BigBlocks Docs
Components/Backup & Recovery

BackupDownload

Component for downloading encrypted wallet backups with security features

BitcoinAuthProvider
backup-recoverysecuritywallet

BackupDownload combines the Radix Button primitive with Bitcoin backup generation, providing secure encrypted wallet backup downloads with user guidance and safety instructions.

Basic Download

Encrypted Backup
Download your encrypted backup file. You'll need your password to restore it.

Required Download

Encrypted Backup
Download your encrypted backup file. You'll need your password to restore it.You must download your backup before continuing

Demo Note: This is a demonstration using test mnemonic data. In a real application, the backup would contain your actual encrypted wallet data.

Installation

npx bigblocks add backup-download

Import

import { BackupDownload } from 'bigblocks';

This component extends the Button primitive and inherits all its props.

Props

PropTypeRequiredDefaultDescription
backupBapMasterBackupYes-The backup data to download
passwordstringNo-Password for encryption (if not already encrypted)
onDownloaded() => voidNo-Callback when download is complete
requireDownloadbooleanNofalseWhether download is required before proceeding
classNamestringNo-Additional CSS classes

Basic Usage

import { BackupDownload } from 'bigblocks';

export default function BackupExample() {
  const backup = {
    // BapMasterBackup data
    idKey: 'L1...',
    derivationScheme: 'master',
    profiles: [],
    bitcoin: {}
  };

  return (
    <BackupDownload
      backup={backup}
      password="user-password"
      onDownloaded={() => {
        console.log('Backup downloaded successfully');
      }}
    />
  );
}

Advanced Usage

Required Download

import { BackupDownload } from 'bigblocks';
import { useState } from 'react';

export default function RequiredBackupFlow() {
  const [downloadComplete, setDownloadComplete] = useState(false);
  const backup = generateBackup(); // Your backup generation logic

  return (
    <div>
      <h2>Step 2: Download Your Backup</h2>
      <p>You must download your backup before continuing.</p>
      
      <BackupDownload
        backup={backup}
        password="secure-password"
        requireDownload={true}
        onDownloaded={() => {
          setDownloadComplete(true);
        }}
      />
      
      <button 
        disabled={!downloadComplete}
        onClick={() => navigateToNextStep()}
      >
        Continue
      </button>
    </div>
  );
}

With Custom Styling

import { BackupDownload } from 'bigblocks';

export default function StyledBackupDownload() {
  const backup = getUserBackup();

  return (
    <BackupDownload
      backup={backup}
      password="user-password"
      className="bg-orange-50 border-orange-200 rounded-lg p-4"
      onDownloaded={() => {
        toast.success('Backup saved successfully!');
      }}
    />
  );
}

In Registration Flow

import { BackupDownload } from 'bigblocks';
import { useAuth } from '@/hooks/useAuth';

export default function RegistrationBackupStep() {
  const { backup, password } = useAuth();
  const [downloaded, setDownloaded] = useState(false);

  return (
    <div className="max-w-md mx-auto">
      <div className="mb-6">
        <h2 className="text-2xl font-bold">Save Your Backup</h2>
        <p className="text-gray-600">
          This backup file is the only way to recover your account. 
          Download and store it safely.
        </p>
      </div>

      <BackupDownload
        backup={backup}
        password={password}
        requireDownload={true}
        onDownloaded={() => {
          setDownloaded(true);
          analytics.track('backup_downloaded');
        }}
      />

      {downloaded && (
        <div className="mt-4 p-3 bg-green-100 text-green-800 rounded">
          ✓ Backup downloaded successfully
        </div>
      )}

      <div className="mt-6">
        <button
          className="w-full btn-primary"
          disabled={!downloaded}
          onClick={() => router.push('/dashboard')}
        >
          Complete Registration
        </button>
      </div>
    </div>
  );
}

Common Patterns

Backup Settings Page

import { BackupDownload } from 'bigblocks';
import { useWallet } from '@/hooks/useWallet';

export function BackupSettings() {
  const { backup } = useWallet();
  const [password, setPassword] = useState('');
  const [showBackup, setShowBackup] = useState(false);

  const handlePasswordSubmit = (e) => {
    e.preventDefault();
    // Validate password
    setShowBackup(true);
  };

  return (
    <div className="space-y-6">
      <h3>Download Backup</h3>
      
      {!showBackup ? (
        <form onSubmit={handlePasswordSubmit}>
          <input
            type="password"
            placeholder="Enter your password"
            value={password}
            onChange={(e) => setPassword(e.target.value)}
            required
          />
          <button type="submit">Continue</button>
        </form>
      ) : (
        <BackupDownload
          backup={backup}
          password={password}
          onDownloaded={() => {
            console.log('New backup downloaded');
            setShowBackup(false);
            setPassword('');
          }}
        />
      )}
    </div>
  );
}

With Progress Tracking

import { BackupDownload } from 'bigblocks';

export function BackupWithProgress() {
  const [step, setStep] = useState(1);
  const backup = generateBackup();

  return (
    <div>
      <ProgressIndicator steps={3} current={step} />
      
      {step === 1 && (
        <div>
          <h3>Create Password</h3>
          <PasswordInput onSubmit={() => setStep(2)} />
        </div>
      )}
      
      {step === 2 && (
        <div>
          <h3>Download Backup</h3>
          <BackupDownload
            backup={backup}
            requireDownload={true}
            onDownloaded={() => setStep(3)}
          />
        </div>
      )}
      
      {step === 3 && (
        <div>
          <h3>Backup Complete!</h3>
          <p>Your wallet is now safely backed up.</p>
        </div>
      )}
    </div>
  );
}

Error Handling

import { BackupDownload } from 'bigblocks';

export function BackupWithErrorHandling() {
  const backup = getUserBackup();
  const [error, setError] = useState(null);

  if (!backup) {
    return <div>No backup available</div>;
  }

  return (
    <div>
      {error && (
        <div className="error-message">
          {error}
        </div>
      )}
      
      <BackupDownload
        backup={backup}
        onDownloaded={() => {
          try {
            // Additional validation or tracking
            validateBackupDownload();
            console.log('Backup downloaded successfully');
          } catch (err) {
            setError('Failed to validate backup download');
          }
        }}
      />
    </div>
  );
}

File Format

The downloaded backup file is encrypted and contains:

// Encrypted backup format (after decryption)
interface BapMasterBackup {
  idKey: string;              // Master private key
  derivationScheme: string;   // Key derivation scheme
  profiles: ProfileInfo[];    // User profiles
  bitcoin: {                  // Bitcoin-specific data
    mnemonic?: string;        // Optional seed phrase
    network?: string;         // Bitcoin network
  };
}

The file is saved with a timestamp-based filename:

  • Format: bitcoin-backup-{timestamp}.txt
  • Content: Base64 encoded encrypted data

Security Considerations

  1. Encryption: Backups are encrypted using AES-256-GCM
  2. Password: Never stored, only used for encryption
  3. Client-side: All encryption happens in the browser
  4. No Network: Download doesn't require network requests
  5. User Responsibility: Users must safely store their backups

Styling

The component uses Radix Themes and can be styled with:

/* Custom styling example */
.backup-download-container {
  background: var(--orange-2);
  border: 1px solid var(--orange-6);
  border-radius: var(--radius-3);
  padding: var(--space-4);
}

Best Practices

  1. Password Strength: Encourage strong passwords for encryption
  2. Multiple Copies: Advise users to make multiple backup copies
  3. Offline Storage: Recommend offline storage (USB, paper)
  4. Test Recovery: Suggest testing backup restoration
  5. Regular Updates: Remind users to update backups after profile changes

Troubleshooting

Download Not Working

  • Check that backup data is valid BapMasterBackup format
  • Ensure browser allows file downloads
  • Verify password is provided if encryption is needed

File Not Encrypted

  • Confirm password prop is provided
  • Check that backup isn't already encrypted
  • Verify encryption library is loaded

Callback Not Firing

  • Ensure onDownloaded prop is a valid function
  • Check browser console for errors
  • Verify download completes successfully

API Reference

BapMasterBackup Type

The backup data structure expected by the component:

interface BapMasterBackup {
  idKey: string;
  derivationScheme: string;
  profiles: Array<{
    idKey: string;
    name?: string;
    // ... other profile data
  }>;
  bitcoin: {
    mnemonic?: string;
    network?: string;
  };
}

File Generation

The component handles:

  1. Encryption of backup data (if password provided)
  2. Base64 encoding
  3. File blob creation
  4. Download trigger
  5. Cleanup

Notes for Improvement

Major Discrepancy: The prompt describes a much more feature-rich component than what's actually implemented. The actual component is simpler with:

  • No variant prop (button vs card)
  • No size options
  • No preview functionality
  • No progress tracking
  • No error callback
  • No custom filename support
  • No instruction display options
  • No backend integration

The actual implementation focuses solely on downloading an encrypted backup file with minimal UI.