Components/Authentication
SignupFlow
Multi-step signup process for creating new Bitcoin wallets
A comprehensive multi-step signup component for creating new Bitcoin wallets with built-in identity generation, password setup, and backup management. It provides a complete onboarding experience with proper error handling and state management.
Installation
npx bigblocks add signup-flowImport
import { SignupFlow } from 'bigblocks';Props
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
| onSuccess | (user: AuthUser) => void | No | - | Callback when signup succeeds |
| onError | (error: AuthError) => void | No | - | Callback for error handling |
| className | string | No | - | Additional CSS classes |
Basic Usage
import { SignupFlow, BitcoinAuthProvider } from 'bigblocks';
import { useRouter } from 'next/navigation';
export default function SignupPage() {
const router = useRouter();
const handleSuccess = (user) => {
console.log('Signup successful:', user);
router.push('/dashboard');
};
const handleError = (error) => {
console.error('Signup failed:', error);
};
return (
<BitcoinAuthProvider config={{ apiUrl: '/api' }}>
<SignupFlow
onSuccess={handleSuccess}
onError={handleError}
/>
</BitcoinAuthProvider>
);
}Advanced Usage
With Custom Error Handling
import { SignupFlow } from 'bigblocks';
import { toast } from 'sonner';
export default function SignupWithErrorHandling() {
return (
<SignupFlow
onSuccess={(user) => {
toast.success('Account created successfully!');
router.push('/onboarding');
}}
onError={(error) => {
// Handle specific error types
switch (error.code) {
case 'USER_EXISTS':
toast.error('An account already exists. Please sign in.');
router.push('/signin');
break;
case 'NETWORK_ERROR':
toast.error('Network error. Please check your connection.');
break;
case 'INVALID_PASSWORD':
toast.error('Password does not meet requirements.');
break;
default:
toast.error(error.message || 'Signup failed. Please try again.');
}
}}
/>
);
}With Analytics Tracking
import { SignupFlow } from 'bigblocks';
import { analytics } from '@/lib/analytics';
export default function TrackedSignup() {
const startTime = Date.now();
return (
<SignupFlow
onSuccess={(user) => {
const duration = Date.now() - startTime;
analytics.track('signup_completed', {
userId: user.id,
duration: duration,
profileCount: user.profiles.length,
hasMultipleProfiles: user.profiles.length > 1
});
// Set user for future analytics
analytics.identify(user.id, {
address: user.address,
createdAt: new Date().toISOString()
});
router.push('/welcome');
}}
onError={(error) => {
analytics.track('signup_failed', {
error: error.code,
duration: Date.now() - startTime
});
}}
/>
);
}With Custom Styling
import { SignupFlow } from 'bigblocks';
export default function StyledSignup() {
return (
<div className="min-h-screen bg-gradient-to-br from-orange-50 to-orange-100">
<div className="flex items-center justify-center p-4">
<SignupFlow
className="max-w-md w-full shadow-xl"
onSuccess={(user) => {
router.push('/dashboard');
}}
/>
</div>
</div>
);
}In Modal
import { SignupFlow } from 'bigblocks';
import { Modal } from '@radix-ui/themes';
export function SignupModal({ isOpen, onClose }) {
return (
<Modal open={isOpen} onOpenChange={onClose}>
<Modal.Content maxWidth="500px">
<Modal.Title>Create Your Bitcoin Wallet</Modal.Title>
<SignupFlow
onSuccess={(user) => {
console.log('Signup completed:', user);
onClose();
router.push('/dashboard');
}}
onError={(error) => {
if (error.code !== 'USER_CANCELLED') {
toast.error('Signup failed');
}
}}
/>
</Modal.Content>
</Modal>
);
}Signup Flow Steps
The SignupFlow component guides users through these steps:
1. Welcome Step
- Introduction to Bitcoin wallet creation
- Terms of service acceptance (if configured)
- Clear value proposition
2. Identity Generation
- Automatic Bitcoin keypair generation
- Visual feedback during generation
- Secure client-side process
3. Password Setup
- Password creation for encryption
- Password strength indicator
- Confirmation field
- Requirements display
4. Backup Creation
- Encrypted backup generation
- Download prompt
- Security instructions
- Verification checkbox
5. Success Confirmation
- Account creation confirmation
- Next steps guidance
- Navigation to dashboard
Common Patterns
Full Page Signup
import { SignupFlow } from 'bigblocks';
export function SignupPage() {
return (
<div className="min-h-screen flex flex-col">
<header className="border-b">
<div className="container mx-auto px-4 py-3">
<h1 className="text-xl font-bold">Create Account</h1>
</div>
</header>
<main className="flex-1 flex items-center justify-center p-4">
<SignupFlow
className="w-full max-w-lg"
onSuccess={(user) => {
router.push('/onboarding');
}}
/>
</main>
</div>
);
}With Navigation Options
import { SignupFlow } from 'bigblocks';
import Link from 'next/link';
export function SignupWithNav() {
return (
<div className="space-y-4">
<SignupFlow
onSuccess={(user) => {
router.push('/dashboard');
}}
/>
<div className="text-center">
<p className="text-sm text-gray-600">
Already have an account?{' '}
<Link href="/signin" className="text-blue-600 hover:underline">
Sign in
</Link>
</p>
</div>
</div>
);
}With Loading Overlay
import { SignupFlow } from 'bigblocks';
import { useState } from 'react';
export function SignupWithLoading() {
const [isProcessing, setIsProcessing] = useState(false);
return (
<>
{isProcessing && (
<div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50">
<div className="bg-white rounded-lg p-6">
<Spinner size="lg" />
<p className="mt-2">Setting up your account...</p>
</div>
</div>
)}
<SignupFlow
onSuccess={async (user) => {
setIsProcessing(true);
try {
// Additional setup
await setupUserProfile(user);
await createDefaultSettings(user.id);
router.push('/welcome');
} finally {
setIsProcessing(false);
}
}}
/>
</>
);
}Security Features
- Client-Side Key Generation: All cryptographic operations happen in the browser
- Password Encryption: Private keys are encrypted before any storage
- No Password Transmission: Passwords never leave the client
- Secure Backup Format: Industry-standard encryption for backups
- Session Management: Secure session creation after signup
Error Types
interface AuthError {
code:
| 'USER_EXISTS' // Account already exists
| 'NETWORK_ERROR' // Network connectivity issues
| 'INVALID_PASSWORD' // Password requirements not met
| 'GENERATION_FAILED' // Key generation failed
| 'BACKUP_FAILED' // Backup creation failed
| 'SESSION_FAILED' // Session creation failed
| 'USER_CANCELLED'; // User cancelled the flow
message: string;
}Styling
The SignupFlow uses Radix Themes and respects the BitcoinThemeProvider:
/* Component structure */
.signup-flow-container {
/* Inherits theme styles */
}
.signup-step {
/* Individual step styling */
}
.signup-navigation {
/* Step navigation buttons */
}State Management
The component internally manages:
- Current step tracking
- Form data across steps
- Loading states
- Error states
- Validation state
- Backup generation status
Best Practices
- Error Handling: Always implement onError to handle failures gracefully
- Success Routing: Navigate users appropriately after signup
- Loading States: Show feedback during async operations
- Backup Emphasis: Ensure users understand backup importance
- Mobile Optimization: Test on mobile devices for touch interactions
Troubleshooting
Component Not Rendering
- Ensure wrapped in
BitcoinAuthProvider - Check that React Query is properly configured
- Verify API endpoints are accessible
Key Generation Failing
- Check browser crypto API support
- Ensure sufficient entropy available
- Verify no browser extensions blocking crypto
Backup Download Issues
- Check browser download permissions
- Ensure popup blockers aren't interfering
- Verify file download API compatibility
Related Components
- LoginForm - Sign in existing users
- AuthFlowOrchestrator - Unified auth flows
- BackupDownload - Backup management
- IdentityGeneration - Key generation
- OAuthProviders - OAuth integration
API Reference
AuthUser Type
interface AuthUser {
id: string; // User's BAP ID
address: string; // Bitcoin address
idKey: string; // Identity key
profiles: ProfileInfo[]; // User profiles
activeProfileId: string; // Current profile
}Internal Flow
- Generate Bitcoin keypair
- Create password
- Encrypt private key
- Generate backup file
- Store encrypted backup
- Create server session
- Return authenticated user
Notes for Improvement
Implementation Differences: The actual component is simpler than the prompt described:
- No
onCancelcallback - No
showBackupSteporshowOAuthStepprops to control flow - No configurable steps
- OAuth linking is not part of the current implementation
- The flow is more streamlined with fewer customization options