Skip to main content
Only available from v4.52.3 onwards.

Summary

The useWalletBackup hook provides methods to manage wallet backup functionality for Dynamic embedded wallets, allowing users to back up their wallet key shares to cloud providers including Google Drive and iCloud. For more information on wallet backup, see the Google Drive backup documentation or the iCloud backup documentation. The hook needs to be initialized within a child of DynamicContextProvider.

Functions

initBackupProcess

Initiates the wallet backup flow by opening the Dynamic modal and displaying the backup progress view to the user.
This method uses Dynamic’s UI.
Returns: void Errors:
  • Throws "user_not_logged_in" if the user is not authenticated
Example:
const { initBackupProcess } = useWalletBackup();

try {
  initBackupProcess();
} catch (error) {
  console.error('Failed to start backup:', error);
}

ensureGoogleLinked

Ensures that the user has linked their Google account. If not already linked, prompts the user to link their Google account via popup.
This method uses Dynamic’s UI.
Returns: Promise<boolean> - true if Google account is linked (or successfully linked), false if linking failed. Example:
const { ensureGoogleLinked } = useWalletBackup();

const isLinked = await ensureGoogleLinked();
if (isLinked) {
  console.log('Google account is linked');
} else {
  console.error('Failed to link Google account');
}

ensureProviderLinked

Ensures that the user has linked the required account for the specified cloud provider. For Google Drive, this links the Google account. For iCloud, no OAuth is required.
This method uses Dynamic’s UI for OAuth providers.
Parameters:
  • provider: CloudBackupProvider - The cloud provider to ensure is linked
Returns: Promise<boolean> - true if provider is linked (or successfully linked), false if linking failed. Example:
import { CloudBackupProvider } from '@dynamic-labs/sdk-react-core';
const { ensureProviderLinked } = useWalletBackup();

const isLinked = await ensureProviderLinked(CloudBackupProvider.GoogleDrive);
if (isLinked) {
  console.log('Provider is linked');
}

showICloudAuth

Displays the iCloud authentication UI in the provided container. This method renders into a secure, sandboxed, cross-origin iframe that you don’t control. You cannot access or manipulate the iframe content.
This method requires an iframe container and is only needed for custom/headless iCloud backup implementations. If you’re using initBackupProcess(), Dynamic’s UI handles this automatically.
Parameters:
  • displayContainer: HTMLElement - The container element to render the iCloud authentication UI
  • walletChain: ChainEnum - The chain of the wallet to authenticate for
Returns: Promise<boolean> - true if authentication UI was displayed successfully, false otherwise. Example:
import { useRef } from 'react';
import { ChainEnum } from '@dynamic-labs/sdk-api-core';

const containerRef = useRef<HTMLDivElement>(null);
const { showICloudAuth } = useWalletBackup();

const handleShowAuth = async () => {
  if (!containerRef.current) {
    console.error('Container is not ready');
    return;
  }

  const success = await showICloudAuth(containerRef.current, ChainEnum.Evm);
  if (success) {
    console.log('iCloud auth UI displayed');
  }
};

return <div ref={containerRef} />;

checkICloudAuth

Checks if the user is authenticated with iCloud for the specified wallet chain.
This method is headless.
Parameters:
  • walletChain: ChainEnum - The chain of the wallet to check authentication for
Returns: Promise<boolean> - true if authenticated with iCloud, false otherwise. Example:
import { ChainEnum } from '@dynamic-labs/sdk-api-core';
const { checkICloudAuth } = useWalletBackup();

const isAuthenticated = await checkICloudAuth(ChainEnum.Evm);
if (isAuthenticated) {
  console.log('User is authenticated with iCloud');
}

hideICloudAuth

Hides the iCloud authentication UI for the specified wallet chain.
This method is headless.
Parameters:
  • walletChain: ChainEnum - The chain of the wallet to hide authentication UI for
Returns: Promise<void> Example:
import { ChainEnum } from '@dynamic-labs/sdk-api-core';
const { hideICloudAuth } = useWalletBackup();

await hideICloudAuth(ChainEnum.Evm);

backupWallet

Backs up a single wallet’s key shares to a cloud provider (Google Drive or iCloud). Parameters:
  • walletToBackup: Object containing wallet information
    • address: string - The wallet address
    • chain: ChainEnum - The chain the wallet is associated with
  • provider (optional): CloudBackupProvider - The cloud provider to use (defaults to GoogleDrive)
  • displayContainer (optional): HTMLElement - The container for iCloud authentication iframe (required for iCloud backups)
Returns: Promise<boolean> - true if backup was successful, false otherwise. Example:
import { ChainEnum } from '@dynamic-labs/sdk-api-core';
import { CloudBackupProvider } from '@dynamic-labs/sdk-react-core';

const { backupWallet } = useWalletBackup();

// Google Drive backup
const success = await backupWallet({
  address: '0x123...',
  chain: ChainEnum.Evm,
}, CloudBackupProvider.GoogleDrive);

// iCloud backup (requires iframe container)
const containerRef = useRef<HTMLDivElement>(null);
const successICloud = await backupWallet({
  address: '0x123...',
  chain: ChainEnum.Evm,
}, CloudBackupProvider.ICloud, containerRef.current);

if (success) {
  console.log('Wallet backed up successfully');
}

backupAllWallets

Backs up all wallets (or a specified list of wallets) to a cloud provider (Google Drive or iCloud).
This method is headless.
Parameters:
  • wallets (optional): Array of wallet objects to back up. If not provided, backs up all wallets that need backup.
  • provider (optional): CloudBackupProvider - The cloud provider to use (defaults to GoogleDrive)
  • displayContainer (optional): HTMLElement - The container for iCloud authentication iframe (required for iCloud backups)
Returns: Promise<void> - Resolves when all backups complete. Automatically refreshes user data after completion. Example:
import { CloudBackupProvider } from '@dynamic-labs/sdk-react-core';
const { backupAllWallets } = useWalletBackup();

// Back up all pending wallets to Google Drive
await backupAllWallets();

// Back up specific wallets to iCloud (requires iframe container)
const containerRef = useRef<HTMLDivElement>(null);
await backupAllWallets(
  [
    { address: '0x123...', chain: ChainEnum.Evm },
    { address: '0x456...', chain: ChainEnum.Evm },
  ],
  CloudBackupProvider.ICloud,
  containerRef.current
);

startBackup

Starts the backup process with progress tracking and error handling. This function backs up wallets sequentially and updates the backupState as it progresses.
This method is headless.
Parameters:
  • onComplete (optional): Callback function to execute when backup completes successfully
  • fromIndex (optional): Index to start backup from (useful for retrying after failure). Default is 0.
  • provider (optional): CloudBackupProvider - The cloud provider to use (defaults to GoogleDrive)
  • displayContainer (optional): HTMLElement - The container for iCloud authentication iframe (required for iCloud backups)
Returns: Promise<void> - Resolves when backup completes or fails. Example:
import { CloudBackupProvider } from '@dynamic-labs/sdk-react-core';
const { startBackup, backupState } = useWalletBackup();

// Google Drive backup
await startBackup(() => {
  console.log('All wallets backed up!');
});

// iCloud backup (requires iframe container)
const containerRef = useRef<HTMLDivElement>(null);
await startBackup(
  () => console.log('iCloud backup complete!'),
  0,
  CloudBackupProvider.ICloud,
  containerRef.current
);

// Retry from failed index
if (backupState.hasError && backupState.failedIndex !== null) {
  await startBackup(undefined, backupState.failedIndex);
}

getWalletsBackupStatus

Returns the backup status for all WaaS wallets.
This method is headless.
Returns: WalletWithBackupStatus[] - Array of wallets with their backup status. Example:
const { getWalletsBackupStatus } = useWalletBackup();

const wallets = getWalletsBackupStatus();
wallets.forEach(wallet => {
  console.log(`${wallet.address}: ${wallet.status}`);
});

getWalletsToBackup

Returns only the wallets that still need to be backed up (status is ‘pending’).
This method is headless.
Returns: WalletToBackup[] - Array of wallets that need backup. Example:
const { getWalletsToBackup } = useWalletBackup();

const pendingWallets = getWalletsToBackup();
console.log(`${pendingWallets.length} wallets need backup`);

getSupportedProviders

Returns the list of supported cloud backup providers based on project settings.
This method is headless.
Returns: CloudProviderConfigWithIcon[] - Array of supported cloud providers with their configuration. Example:
const { getSupportedProviders } = useWalletBackup();

const providers = getSupportedProviders();
providers.forEach(provider => {
  console.log(`${provider.name}: ${provider.id}`);
  console.log(`Requires OAuth: ${provider.requiresOAuth}`);
  console.log(`Requires iframe: ${provider.requiresIframe}`);
});

backupToCloudProvider

Backs up a wallet to a specified cloud provider with optional password protection.
This method is headless.
Parameters:
  • options: CloudProviderBackupOptions
    • provider: CloudBackupProvider - The cloud provider to use
    • accountAddress: string - The wallet address to back up
    • password (optional): string - Password for encrypting the backup
  • walletToBackup: WalletToBackup - The wallet to back up
Returns: Promise<boolean> - true if backup was successful, false otherwise. Example:
import { CloudBackupProvider } from '@dynamic-labs/sdk-react-core';
const { backupToCloudProvider } = useWalletBackup();

const success = await backupToCloudProvider(
  {
    provider: CloudBackupProvider.GoogleDrive,
    accountAddress: '0x123...',
    password: 'optional-password'
  },
  {
    address: '0x123...',
    chain: ChainEnum.Evm
  }
);

Properties

areAllWalletsBackedUp

A boolean value indicating whether all WaaS wallets have been backed up to a cloud provider (Google Drive or iCloud). Type: boolean Example:
const { areAllWalletsBackedUp } = useWalletBackup();

if (areAllWalletsBackedUp) {
  console.log('All wallets are safely backed up');
}

isProviderLinked

Checks if the user has linked the required account for the specified cloud provider. Parameters:
  • provider: CloudBackupProvider - The cloud provider to check
Type: (provider: CloudBackupProvider) => boolean Example:
import { CloudBackupProvider } from '@dynamic-labs/sdk-react-core';
const { isProviderLinked } = useWalletBackup();

if (isProviderLinked(CloudBackupProvider.GoogleDrive)) {
  console.log('Google Drive is linked');
}

isGoogleLinked

A boolean value indicating whether the user has linked their Google account. Type: boolean Example:
const { isGoogleLinked } = useWalletBackup();

if (!isGoogleLinked) {
  console.log('User needs to link Google account for backup');
}

backupState

An object containing the current state of the backup operation, including progress and error information. Type: WalletOperationState Example:
const { backupState } = useWalletBackup();

console.log(`Progress: ${backupState.currentIndex}/${backupState.totalWallets}`);
if (backupState.hasError) {
  console.error(`Backup failed at index ${backupState.failedIndex}`);
}

Usage

import { useWalletBackup } from '@dynamic-labs/sdk-react-core';

const MyComponent = () => {
  const { 
    initBackupProcess,
    areAllWalletsBackedUp,
    isGoogleLinked,
    backupState
  } = useWalletBackup();

  const handleBackup = () => {
    initBackupProcess();
  };

  return (
    <div>
      {!areAllWalletsBackedUp && (
        <div>
          <p>Your wallets are not backed up</p>
          {!isGoogleLinked && (
            <p>You'll need to link your Google account</p>
          )}
          <button onClick={handleBackup}>
            Back Up Wallets
          </button>
        </div>
      )}
      
      {backupState.isProcessing && (
        <p>Backing up wallet {backupState.currentIndex} of {backupState.totalWallets}</p>
      )}
      
      {backupState.isComplete && (
        <p>All wallets backed up successfully!</p>
      )}
      
      {backupState.hasError && (
        <p>Backup failed. Please try again.</p>
      )}
    </div>
  );
};

Advanced Usage

Monitor backup progress and handle errors:
import { useWalletBackup } from '@dynamic-labs/sdk-react-core';
import { useEffect } from 'react';

const BackupMonitor = () => {
  const { 
    startBackup,
    backupState,
    getWalletsToBackup
  } = useWalletBackup();

  const handleBackupWithRetry = async () => {
    const walletsToBackup = getWalletsToBackup();
    
    if (walletsToBackup.length === 0) {
      console.log('No wallets need backup');
      return;
    }

    await startBackup(() => {
      console.log('Backup completed successfully');
    });
  };

  const handleRetry = async () => {
    if (backupState.failedIndex !== null) {
      await startBackup(
        () => console.log('Retry successful'),
        backupState.failedIndex
      );
    }
  };

  useEffect(() => {
    if (backupState.hasError) {
      console.error(`Backup failed at wallet ${backupState.failedIndex}`);
    }
  }, [backupState.hasError]);

  return (
    <div>
      <button onClick={handleBackupWithRetry}>
        Start Backup
      </button>
      
      {backupState.hasError && (
        <button onClick={handleRetry}>
          Retry Failed Backup
        </button>
      )}
      
      {backupState.isProcessing && (
        <div>
          <progress 
            value={backupState.currentIndex} 
            max={backupState.totalWallets}
          />
          <p>
            Backing up wallet {backupState.currentIndex} of {backupState.totalWallets}
          </p>
        </div>
      )}
    </div>
  );
};

iCloud Backup with Iframe

Most developers don’t need this. The iframe container is only required if you’re building a custom/headless UI for iCloud backups. If you’re using initBackupProcess(), Dynamic’s UI handles the iframe automatically.
When building a custom UI for iCloud backup, you must provide an iframe container element, similar to exportPrivateKey:
import { useRef } from 'react';
import { useWalletBackup, CloudBackupProvider } from '@dynamic-labs/sdk-react-core';
import { ChainEnum } from '@dynamic-labs/sdk-api-core';

const ICloudBackupComponent = () => {
  const containerRef = useRef<HTMLDivElement>(null);
  const { 
    showICloudAuth,
    checkICloudAuth,
    hideICloudAuth,
    backupWallet,
    getSupportedProviders
  } = useWalletBackup();

  const handleICloudBackup = async () => {
    if (!containerRef.current) {
      console.error('Secure container is not ready');
      return;
    }

    // Check if already authenticated
    const isAuthenticated = await checkICloudAuth(ChainEnum.Evm);
    
    if (!isAuthenticated) {
      // Show iCloud authentication UI in iframe
      const authSuccess = await showICloudAuth(containerRef.current, ChainEnum.Evm);
      if (!authSuccess) {
        console.error('Failed to show iCloud auth');
        return;
      }
    }

    // Perform backup
    const success = await backupWallet(
      {
        address: '0x123...',
        chain: ChainEnum.Evm,
      },
      CloudBackupProvider.ICloud,
      containerRef.current
    );

    if (success) {
      console.log('Wallet backed up to iCloud successfully');
      // Hide the iframe after successful backup
      await hideICloudAuth(ChainEnum.Evm);
    }
  };

  return (
    <div>
      <button onClick={handleICloudBackup}>
        Backup to iCloud
      </button>
      {/* Secure iframe container for iCloud authentication */}
      <div ref={containerRef} style={{ width: '100%', height: '400px' }} />
    </div>
  );
};

Important Notes

  • The user must be authenticated to use backup functionality
  • Google Drive backups require Google account linking before backing up wallets
  • iCloud backups with custom UI require an iframe container to be passed to the backup methods (similar to exportPrivateKey). If you’re using initBackupProcess(), Dynamic’s UI handles this automatically.
  • iCloud authentication runs in a secure, sandboxed, cross-origin iframe that you cannot access or manipulate
  • Backup operations are performed sequentially, one wallet at a time
  • The backup modal is part of the Dynamic UI and handles user interactions
  • Failed backups can be retried from the point of failure using the failedIndex
  • Cloud provider support can be configured in your project settings via the waas.backupOptions configuration

Learn More

Return Value

The hook returns an object with the following properties:
{
  areAllWalletsBackedUp: boolean;
  backupAllWallets: (
    wallets?: WalletToBackup[],
    provider?: CloudBackupProvider,
    displayContainer?: HTMLElement
  ) => Promise<void>;
  backupState: WalletOperationState;
  backupToCloudProvider: (
    options: CloudProviderBackupOptions,
    walletToBackup: WalletToBackup
  ) => Promise<boolean>;
  backupWallet: (
    walletToBackup: WalletToBackup,
    provider?: CloudBackupProvider,
    displayContainer?: HTMLElement
  ) => Promise<boolean>;
  checkICloudAuth: (walletChain: ChainEnum) => Promise<boolean>;
  ensureGoogleLinked: () => Promise<boolean>;
  ensureProviderLinked: (provider: CloudBackupProvider) => Promise<boolean>;
  getSupportedProviders: () => CloudProviderConfigWithIcon[];
  getWalletsBackupStatus: () => WalletWithBackupStatus[];
  getWalletsToBackup: () => WalletToBackup[];
  hideICloudAuth: (walletChain: ChainEnum) => Promise<void>;
  initBackupProcess: () => void;
  isGoogleLinked: boolean;
  isProviderLinked: (provider: CloudBackupProvider) => boolean;
  showICloudAuth: (displayContainer: HTMLElement, walletChain: ChainEnum) => Promise<boolean>;
  startBackup: (
    onComplete?: () => void,
    fromIndex?: number,
    provider?: CloudBackupProvider,
    displayContainer?: HTMLElement
  ) => Promise<void>;
}

Types

type WalletBackupStatus = 'backed-up' | 'pending';

interface WalletToBackup {
  address: string;
  chain: ChainEnum;
}

interface WalletWithBackupStatus extends WalletToBackup {
  status: WalletBackupStatus;
}

interface WalletOperationState {
  currentIndex: number;
  failedIndex: number | null;
  hasError: boolean;
  isComplete: boolean;
  isProcessing: boolean;
  totalWallets: number;
}

enum CloudBackupProvider {
  GoogleDrive = 'google_drive',
  ICloud = 'icloud'
}

interface CloudProviderConfig {
  id: CloudBackupProvider;
  name: string;
  requiresOAuth: boolean;
  requiresIframe: boolean;
  oauthProvider?: ProviderEnum;
}

interface CloudProviderBackupOptions {
  provider: CloudBackupProvider;
  accountAddress: string;
  password?: string;
}