Sigma Auth
Setup

Integrating with Sigma Auth

Sigma Auth is an OAuth 2.0 provider. Here's how to integrate it with your React application.

Simple OAuth Integration

1. Environment Variables

.env
REACT_APP_SIGMA_CLIENT_ID=your-app-name
REACT_APP_SIGMA_ISSUER=https://auth.sigmaidentity.com
REACT_APP_REDIRECT_URI=http://localhost:3000/callback

2. Auth Hook

hooks/useAuth.ts
import { useState, useEffect } from 'react';

interface User {
  id: string;
  address: string;
  name?: string;
  email?: string;
}

export function useAuth() {
  const [user, setUser] = useState<User | null>(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const token = localStorage.getItem('access_token');
    if (token) {
      fetchUser(token);
    } else {
      setLoading(false);
    }
  }, []);

  const fetchUser = async (token: string) => {
    try {
      const response = await fetch('https://auth.sigmaidentity.com/api/auth/oauth2/userinfo', {
        headers: { Authorization: `Bearer ${token}` }
      });
      const userData = await response.json();
      setUser({
        id: userData.sub,
        address: userData.address,
        name: userData.name,
        email: userData.email
      });
    } catch (error) {
      localStorage.removeItem('access_token');
    } finally {
      setLoading(false);
    }
  };

  const signIn = () => {
    const authUrl = 'https://auth.sigmaidentity.com/oauth2/authorize?' +
      new URLSearchParams({
        client_id: process.env.REACT_APP_SIGMA_CLIENT_ID!,
        redirect_uri: process.env.REACT_APP_REDIRECT_URI!,
        response_type: 'code',
        provider: 'sigma'
      });
    window.location.href = authUrl;
  };

  const signOut = () => {
    localStorage.removeItem('access_token');
    setUser(null);
  };

  return { user, loading, signIn, signOut, isAuthenticated: !!user };
}

3. Login Component

components/LoginButton.tsx
import { useAuth } from '../hooks/useAuth';

export function LoginButton() {
  const { signIn, signOut, user, loading } = useAuth();

  if (loading) return <div>Loading...</div>;

  if (user) {
    return (
      <div>
        <span>Welcome, {user.address.slice(0, 8)}...</span>
        <button onClick={signOut}>Sign Out</button>
      </div>
    );
  }

  return (
    <button onClick={signIn}>
      Sign In with Bitcoin
    </button>
  );
}

4. Callback Handler

pages/CallbackPage.tsx
import { useEffect } from 'react';
import { useNavigate } from 'react-router-dom';

export function CallbackPage() {
  const navigate = useNavigate();

  useEffect(() => {
    const handleCallback = async () => {
      const urlParams = new URLSearchParams(window.location.search);
      const code = urlParams.get('code');

      if (!code) {
        navigate('/');
        return;
      }

      try {
        // Exchange code for token
        const response = await fetch('https://auth.sigmaidentity.com/api/auth/oauth2/token', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            grant_type: 'authorization_code',
            code,
            client_id: process.env.REACT_APP_SIGMA_CLIENT_ID!,
            redirect_uri: process.env.REACT_APP_REDIRECT_URI!
          })
        });

        const { access_token } = await response.json();
        localStorage.setItem('access_token', access_token);
        navigate('/dashboard');
      } catch (error) {
        console.error('Auth failed:', error);
        navigate('/');
      }
    };

    handleCallback();
  }, [navigate]);

  return <div>Completing sign in...</div>;
}

5. Protected Route

components/ProtectedRoute.tsx
import { useAuth } from '../hooks/useAuth';

interface ProtectedRouteProps {
  children: React.ReactNode;
}

export function ProtectedRoute({ children }: ProtectedRouteProps) {
  const { user, loading } = useAuth();

  if (loading) return <div>Loading...</div>;
  if (!user) return <div>Please sign in to access this page.</div>;

  return <>{children}</>;
}

Router Setup

App.tsx
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import { LoginButton } from './components/LoginButton';
import { CallbackPage } from './pages/CallbackPage';
import { ProtectedRoute } from './components/ProtectedRoute';

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<LoginButton />} />
        <Route path="/callback" element={<CallbackPage />} />
        <Route 
          path="/dashboard" 
          element={
            <ProtectedRoute>
              <div>Protected Dashboard</div>
            </ProtectedRoute>
          } 
        />
      </Routes>
    </BrowserRouter>
  );
}

export default App;

Using with React Libraries

React Query Integration

hooks/useAuthQuery.ts
import { useQuery } from '@tanstack/react-query';

export function useAuthQuery() {
  return useQuery({
    queryKey: ['auth'],
    queryFn: async () => {
      const token = localStorage.getItem('access_token');
      if (!token) return null;

      const response = await fetch('https://auth.sigmaidentity.com/api/auth/oauth2/userinfo', {
        headers: { Authorization: `Bearer ${token}` }
      });
      return response.json();
    },
    staleTime: 5 * 60 * 1000, // 5 minutes
  });
}

If you're on Next.js or already using Better Auth, use the official plugin — it wraps the OAuth dance (PKCE, state, token exchange) and the BAP-aware signing helpers. See the Next.js setup and plugin reference.

Key Points

  • Sigma Auth is the OAuth provider — your React app is the client.
  • Standard OAuth 2.0 flow — redirect to Sigma Auth, handle callback, exchange code for token.
  • Public key as user ID — users authenticate with Bitcoin signatures instead of passwords.
  • Works with any OAuth library — Auth0, Firebase Auth, etc. For Next.js, the Better Auth plugin is the shortest path.

Next Steps

On this page