Customization
Better Auth Foundation
Sigma Auth is built on top of Better Auth, a modern authentication framework that provides:
- Type-Safe: Full TypeScript support with type inference
- Framework Agnostic: Works with any web framework or platform
- Plugin Architecture: Extensible through custom plugins
- OAuth 2.0 Compatible: Standard OAuth flows with custom providers
Architecture Overview
Sigma Auth implements a custom Better Auth plugin called sigma
that adds Bitcoin authentication support. The architecture consists of:
- Client Plugin (
sigma-client-plugin.ts
) - Handles OAuth flow initiation - Server Plugin (in auth server) - Manages Bitcoin signature verification
- OAuth Bridge - Standard OAuth 2.0 authorization code flow
Authentication Flow
Here's how the Bitcoin authentication flow works with Better Auth:
Client Configuration
The Sigma Auth client uses Better Auth with a custom sigma plugin:
import { createAuthClient } from 'better-auth/react';
import { sigmaClient } from './sigma-client-plugin';
export const authClient = createAuthClient({
baseURL: 'https://auth.sigmaidentity.com',
plugins: [sigmaClient()],
});
// Export React hooks
export const { useSession } = authClient;
Sigma Client Plugin
The client plugin handles OAuth flow initiation:
import type { BetterAuthClientPlugin } from 'better-auth/client';
export const sigmaClient = () => {
return {
id: 'sigma',
getActions: ($fetch) => {
return {
signIn: {
sigma: async (options?: {
provider?: string; // 'github' | 'google' | 'bitcoin'
}) => {
// Generate CSRF state
const state = Math.random().toString(36).substring(7);
sessionStorage.setItem('oauth_state', state);
// Build OAuth authorization URL
const params = new URLSearchParams({
client_id: 'sigma',
redirect_uri: `${window.location.origin}/callback`,
response_type: 'code',
state,
scope: 'read',
});
if (options?.provider) {
params.append('provider', options.provider);
}
// Redirect to auth server
window.location.href =
`https://auth.sigmaidentity.com/api/oauth/authorize?${params}`;
},
},
};
},
} satisfies BetterAuthClientPlugin;
};
Usage in Components
Sign In
import { authClient } from '@/lib/auth-client';
export function SignInButton() {
const handleSignIn = async () => {
// Bitcoin authentication (default)
await authClient.signIn.sigma();
// OAuth provider authentication
await authClient.signIn.sigma({ provider: 'github' });
await authClient.signIn.sigma({ provider: 'google' });
};
return <button onClick={handleSignIn}>Sign In</button>;
}
Session Management
import { useSession } from '@/lib/auth-client';
export function UserProfile() {
const { data: session, isPending } = useSession();
if (isPending) return <div>Loading...</div>;
if (!session) return <div>Not signed in</div>;
return (
<div>
<p>Welcome, {session.user.profile?.name || session.user.pubkey}</p>
<p>Bitcoin Address: {session.user.address}</p>
</div>
);
}
OAuth Callback
The callback page handles the OAuth authorization code exchange:
export default function CallbackPage() {
useEffect(() => {
const params = new URLSearchParams(window.location.search);
const code = params.get('code');
const state = params.get('state');
if (code && state) {
// Exchange code for token via API route
fetch('/api/auth/callback', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ code, state })
}).then(response => {
if (response.ok) {
window.location.href = '/dashboard';
}
});
}
}, []);
return <div>Processing authentication...</div>;
}
Server Plugin (Auth Server)
The server-side sigma plugin handles Bitcoin authentication:
import { createAuthPlugin } from 'better-auth/plugins';
import { verifyAuthToken } from 'bitcoin-auth';
export const sigmaServer = createAuthPlugin({
id: 'sigma',
endpoints: {
signInSigma: {
method: 'POST',
path: '/sigma/sign-in',
handler: async ({ body, context }) => {
const { authToken } = body;
// Verify Bitcoin signature
const isValid = verifyAuthToken(authToken);
if (!isValid) {
throw new Error('Invalid signature');
}
// Parse token to get user info
const { pubkey, address } = parseAuthToken(authToken);
// Create or update user
const user = await context.adapter.findOrCreateUser({
pubkey,
address,
});
// Create session
const session = await context.adapter.createSession({
userId: user.id,
});
return {
user,
session,
};
},
},
},
});
Benefits of Better Auth
Type Safety
- Full TypeScript support with automatic type inference
- Type-safe plugin development
- No manual type definitions needed
Modern Architecture
- Plugin-based extensibility
- React Query integration
- Optimistic updates
Developer Experience
- Simple API with powerful features
- Excellent documentation
- Active community support
Migration from OpenAuth
If you were using OpenAuth, here's how to migrate:
Client Changes
// Before (OpenAuth)
import { createClient } from '@openauthjs/openauth';
const client = createClient({
clientID: 'sigma',
issuer: 'https://auth.sigmaidentity.com',
});
await client.authorize({ provider: 'bitcoin' });
// After (Better Auth)
import { authClient } from '@/lib/auth-client';
await authClient.signIn.sigma();
Server Changes
// Before (OpenAuth)
import { createOpenAuth } from '@openauthjs/openauth';
export const auth = createOpenAuth({
providers: {
bitcoin: BitcoinProvider,
}
});
// After (Better Auth)
import { betterAuth } from 'better-auth';
import { sigmaServer } from './sigma-server-plugin';
export const auth = betterAuth({
plugins: [sigmaServer()],
});
Learn More
For Bitcoin-specific features and implementation details, see our Bitcoin Authentication Guide.