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.
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.
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).
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.
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.
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’).
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.
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.
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;
}