Skip to main content
Dynamic also supports Google Drive backup as an alternative cloud storage option. See the Google Drive backup documentation for setup instructions.
iCloud backup allows users to securely store their wallet key shares in Apple’s iCloud storage. Unlike Google Drive, iCloud backup requires an iframe-based authentication flow. iCloud recovery uses CloudKit to securely store a client key share in the user’s iCloud account. This flow is completely separate from Apple Sign In or any social authentication mechanism and does not share configuration with Apple authentication.

CloudKit setup and configuration

To enable iCloud recovery, your application must be connected to a CloudKit container associated with its bundle identifier. If you do not already have a container, you can create and attach one through the Apple Developer Portal. Existing containers may be reused. Refer to Apple’s CloudKit documentation for detailed guidance. Once the container is available, configure the CloudKit schema used to store recovery data. Dynamic relies on a dedicated private CloudKit schema for user client key shares. The schema uses a record type named Backup with a single field named backupData (type: string). This schema must be imported using the Import Schema option in the CloudKit dashboard. After importing, deploy the schema to the Production environment. All iCloud recovery operations should use the production deployment going forward. Next, create API tokens in the production CloudKit environment to allow the Dynamic SDK to interact with your CloudKit container. For web integrations, use a descriptive token name, set the Sign In Callback to Post Message, and keep all other settings at their default values. After CloudKit is fully configured, open the Dynamic Dashboard and navigate to Embedded Wallets > Advanced Settings > Backup & Recovery > Apple iCloud. In the Recovery section, enable iCloud as a user-managed recovery option and provide your CloudKit container ID along with the appropriate API token(s).

Enable in Dynamic dashboard

Navigate to your Dynamic Dashboard and enable iCloud as a backup option in your embedded wallet settings.

How iCloud backup works

iCloud backup uses a secure, sandboxed, cross-origin iframe for authentication. This iframe:
  • Renders the iCloud authentication UI
  • Cannot be accessed or manipulated by your application
  • Handles all sensitive authentication operations securely

Implementation

To implement iCloud backup, you need to provide an iframe container element. The useWalletBackup hook provides methods specifically for iCloud:

Basic iCloud backup flow

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
  } = useWalletBackup();

  const handleICloudBackup = async () => {
    if (!containerRef.current) {
      console.error('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>
  );
};

iCloud-specific methods

MethodDescription
showICloudAuth(container, chain)Displays the iCloud authentication UI in the provided container
checkICloudAuth(chain)Checks if the user is authenticated with iCloud
hideICloudAuth(chain)Hides the iCloud authentication UI

Backing up all wallets to iCloud

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

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

// Back up all wallets to iCloud
await backupAllWallets(
  undefined, // backs up all pending wallets
  CloudBackupProvider.ICloud,
  containerRef.current
);

Key differences from Google Drive

FeatureGoogle DriveiCloud
OAuth requiredYesNo
Iframe requiredNoYes
Account linkingRequired before backupNot required
AuthenticationGoogle OAuth flowIframe-based auth

Access and authentication considerations

Only end users can access their client key shares. Although the CloudKit database is owned by your application, data access is restricted to the authenticated iCloud user. Apple authentication is not required for iCloud recovery.

Important notes

  • The iframe container must be mounted and visible when performing iCloud operations
  • iCloud authentication runs in a secure, sandboxed environment that you cannot access
  • The displayContainer parameter is required for all iCloud backup operations
  • Users do not need to link an iCloud account beforehand—authentication happens during the backup flow

Programmatic backup management

For complete API documentation, see the useWalletBackup hook reference, which covers all backup methods including:
  • backupWallet - Back up a single wallet
  • backupAllWallets - Back up multiple wallets
  • startBackup - Start backup with progress tracking
  • getSupportedProviders - Get available backup providers

Webhook event

When a user successfully backs up their key shares to iCloud, Dynamic fires the wallet.keyShares.backedUpToExternal webhook event. You can use this to track backup status or trigger follow-up actions in your application. See webhook events for more details.