Components/Authentication
createAuthManager
Factory function for creating pre-configured AuthManager instances
A factory function that creates and configures AuthManager instances for Bitcoin authentication. Provides a comprehensive API for managing authentication state, sessions, and wallet operations.
Installation
npx bigblocks add create-auth-managerImport
import { createAuthManager } from 'bigblocks';Basic Usage
import { createAuthManager } from 'bigblocks';
// Create auth manager instance
const authManager = createAuthManager({
apiUrl: '/api'
});
// Use in your application
async function handleSignIn(password: string) {
try {
await authManager.signIn(password);
console.log('Signed in successfully');
} catch (error) {
console.error('Sign in failed:', error);
}
}Configuration
interface BitcoinAuthConfig {
apiUrl: string; // API endpoint URL
debug?: boolean; // Enable debug logging
backupTypes?: string[]; // Supported backup types
}API Methods
The AuthManager instance provides these methods:
Authentication
// Sign in with password
await authManager.signIn(password: string);
// Sign up with new account
await authManager.signUp(password: string);
// Sign out
await authManager.signOut();
// Validate password
const isValid = await authManager.validatePassword(password: string);State Management
// Get current state
const state = authManager.getState();
// Returns: { isAuthenticated, isLoading, user, error }
// Subscribe to state changes
const unsubscribe = authManager.subscribe((event) => {
console.log('Auth event:', event.type, event.data);
});
// Cleanup
unsubscribe();Backup Operations
// Generate backup
const backup = authManager.generateBackup();
// Import backup from file
await authManager.importBackup(file: File);OAuth Integration
// Link OAuth provider
await authManager.linkOAuth('google');
// Handle OAuth callback
await authManager.handleOAuthCallback('google', true);Wallet Features
// Get wallet extension (if user has wallet capabilities)
const walletExt = await authManager.getWalletExtension();Actions Helper
// Get all actions as a convenient object
const actions = authManager.getActions();
// Includes: signIn, signUp, signOut, importBackup, linkOAuth, etc.Advanced Usage
With React Hook
import { createAuthManager } from 'bigblocks';
import { useState, useEffect, useCallback } from 'react';
function useAuthManager(config) {
const [authManager] = useState(() => createAuthManager(config));
const [state, setState] = useState(authManager.getState());
useEffect(() => {
const unsubscribe = authManager.subscribe((event) => {
setState(authManager.getState());
});
return unsubscribe;
}, [authManager]);
const signIn = useCallback(async (password) => {
await authManager.signIn(password);
}, [authManager]);
const signOut = useCallback(async () => {
await authManager.signOut();
}, [authManager]);
return {
...state,
signIn,
signOut,
authManager
};
}
// Usage
function LoginComponent() {
const { isAuthenticated, user, signIn, signOut } = useAuthManager({
apiUrl: '/api'
});
if (isAuthenticated) {
return (
<div>
<p>Welcome, {user.name}!</p>
<button onClick={signOut}>Sign Out</button>
</div>
);
}
return (
<form onSubmit={async (e) => {
e.preventDefault();
const password = e.target.password.value;
await signIn(password);
}}>
<input type="password" name="password" required />
<button type="submit">Sign In</button>
</form>
);
}With Error Handling
import { createAuthManager } from 'bigblocks';
const authManager = createAuthManager({
apiUrl: '/api',
debug: true
});
// Subscribe to all events
authManager.subscribe((event) => {
switch (event.type) {
case 'AUTH_ERROR':
console.error('Auth error:', event.data.error);
showErrorNotification(event.data.error.message);
break;
case 'STATE_CHANGE':
console.log('State changed:', event.data);
break;
case 'SESSION_CREATED':
console.log('Session created for:', event.data.user.name);
trackLogin(event.data.user);
break;
case 'SESSION_DESTROYED':
console.log('Session destroyed');
trackLogout();
break;
}
});With Backup Management
import { createAuthManager } from 'bigblocks';
const authManager = createAuthManager({
apiUrl: '/api',
backupTypes: ['BapMasterBackup', 'OneSatBackup', 'WifBackup']
});
// Export backup
function exportBackup() {
const backup = authManager.generateBackup();
const blob = new Blob([JSON.stringify(backup)], {
type: 'application/json'
});
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'bitcoin-wallet-backup.json';
a.click();
}
// Import backup
async function importBackup(file) {
try {
await authManager.importBackup(file);
console.log('Backup imported successfully');
} catch (error) {
console.error('Import failed:', error);
}
}With OAuth Flow
import { createAuthManager } from 'bigblocks';
const authManager = createAuthManager({
apiUrl: '/api'
});
// OAuth link button
function OAuthLinkButton({ provider }) {
const handleLink = async () => {
try {
await authManager.linkOAuth(provider);
// This will redirect to OAuth provider
} catch (error) {
console.error('OAuth link failed:', error);
}
};
return (
<button onClick={handleLink}>
Link {provider}
</button>
);
}
// OAuth callback handler
async function handleOAuthReturn() {
const params = new URLSearchParams(window.location.search);
const provider = params.get('provider');
const success = params.get('success') === 'true';
if (provider) {
await authManager.handleOAuthCallback(provider, success);
}
}Event Types
The AuthManager emits these events:
type AuthEvent =
| { type: 'STATE_CHANGE'; data: AuthState }
| { type: 'AUTH_ERROR'; data: { error: Error } }
| { type: 'SESSION_CREATED'; data: { user: AuthUser } }
| { type: 'SESSION_DESTROYED'; data: null }
| { type: 'BACKUP_IMPORTED'; data: { type: string } }
| { type: 'OAUTH_LINKED'; data: { provider: string } };State Structure
interface AuthState {
isAuthenticated: boolean;
isLoading: boolean;
user: AuthUser | null;
error: Error | null;
}
interface AuthUser {
bapId: string;
name?: string;
address?: string;
hasWalletCapabilities?: boolean;
createdAt?: Date;
// ... other user properties
}Common Patterns
Protected Routes
function ProtectedRoute({ children }) {
const authManager = createAuthManager({ apiUrl: '/api' });
const [state, setState] = useState(authManager.getState());
useEffect(() => {
const unsubscribe = authManager.subscribe(() => {
setState(authManager.getState());
});
return unsubscribe;
}, []);
if (!state.isAuthenticated) {
return <Navigate to="/signin" />;
}
return children;
}Session Persistence
function PersistentAuth() {
const authManager = createAuthManager({ apiUrl: '/api' });
useEffect(() => {
// Check for existing session on mount
const checkSession = async () => {
const encryptedBackup = localStorage.getItem('encryptedBackup');
if (encryptedBackup) {
// Session exists, validate it
const state = authManager.getState();
if (!state.isAuthenticated) {
// Re-authenticate if needed
console.log('Session expired, please sign in again');
}
}
};
checkSession();
}, []);
}Multi-Provider Support
function MultiProviderAuth() {
const authManager = createAuthManager({
apiUrl: '/api',
backupTypes: ['BapMasterBackup', 'OneSatBackup', 'WifBackup']
});
const handleImport = async (file) => {
try {
await authManager.importBackup(file);
// Check which type was imported
const state = authManager.getState();
console.log('Imported user:', state.user);
} catch (error) {
if (error.message.includes('password')) {
// Prompt for password
const password = prompt('Enter backup password:');
// Retry import with password
}
}
};
}Error Handling
authManager.subscribe((event) => {
if (event.type === 'AUTH_ERROR') {
const error = event.data.error;
switch (error.code) {
case 'INVALID_PASSWORD':
showError('Invalid password');
break;
case 'NETWORK_ERROR':
showError('Network connection failed');
break;
case 'SESSION_EXPIRED':
showError('Session expired, please sign in again');
break;
case 'BACKUP_CORRUPTED':
showError('Backup file is corrupted');
break;
default:
showError('Authentication failed');
}
}
});Best Practices
- Single Instance: Create one AuthManager instance per app
- Error Handling: Always handle authentication errors
- State Subscription: Subscribe to state changes for reactive UI
- Cleanup: Unsubscribe from events when components unmount
- Security: Never log sensitive data like passwords or private keys
Troubleshooting
State Not Updating
// Ensure you're subscribing to changes
const unsubscribe = authManager.subscribe((event) => {
// Update your UI state here
updateUIState(authManager.getState());
});
// Don't forget to cleanup
return () => unsubscribe();Import Failing
// Check supported backup types
console.log('Supported types:', authManager.options?.backupTypes);
// Validate file before import
if (!file.type.match(/json|text/)) {
throw new Error('Invalid file type');
}Related Components
- BitcoinAuthProvider - React provider wrapper
- createBigBlocksAuth - Lower-level auth core
- LoginForm - Pre-built login UI
- SignupFlow - Complete signup flow
API Reference
AuthManager Class
The AuthManager provides a complete authentication system with:
- Password-based authentication
- Backup import/export
- OAuth provider linking
- Session management
- Event-driven state updates
- Wallet integration support
All methods are async and return promises for easy integration with modern JavaScript applications.