> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dynamic.xyz/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# useWalletBackup

<Card title="Recommended: JavaScript SDK with React Hooks" icon="react" color="#4779FE">
  For new React apps, we recommend the JavaScript SDK with React Hooks (`@dynamic-labs-sdk/react-hooks`) instead of the legacy React SDK documented here. The JS SDK comes with many benefits such as a much smaller bundle size and other optimizations. Use the [React quickstart (JavaScript SDK)](/javascript/reference/react-quickstart) to get started.
</Card>

<Warning>
  Only available from v4.52.3 onwards.
</Warning>

### 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 Google Drive.

For more information on wallet backup, see the [Google Drive backup documentation](/react/wallets/embedded-wallets/mpc/google-drive-backup).

The hook needs to be initialized within a child of [DynamicContextProvider](/react/reference/providers/dynamiccontextprovider).

### Hook options

`useWalletBackup` accepts an optional options object:

```typescript theme={"system"}
useWalletBackup(options?: { throwOnError?: boolean });
```

#### `throwOnError`

When `true`, `backupWallet`, `backupToCloudProvider`, and `backupAllWallets` throw on failure instead of catching internally, populating `lastBackupError`, and returning `false`. Defaults to `false` to preserve the legacy surface.

New consumers should set `throwOnError: true` and use `try/catch` — `lastBackupError` and `clearBackupError` are deprecated and will be removed in the next major version.

```typescript theme={"system"}
const { backupWallet } = useWalletBackup({ throwOnError: true });

try {
  await backupWallet(wallet);
} catch (err) {
  // handle the error directly
}
```

**Type:** `boolean` (default `false`)

### Functions

#### `initBackupProcess`

Initiates the wallet backup flow by opening the Dynamic modal and displaying the backup progress view to the user.

<Note>This method uses Dynamic's UI.</Note>

**Returns:** `void`

**Errors:**

* Throws `"user_not_logged_in"` if the user is not authenticated

**Example:**

```typescript theme={"system"}
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.

<Note>This method uses Dynamic's UI.</Note>

**Returns:** `Promise<boolean>` - `true` if Google account is linked (or successfully linked), `false` if linking failed.

**Example:**

```typescript theme={"system"}
const { ensureGoogleLinked } = useWalletBackup();

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

#### `backupWallet`

Backs up a single wallet's key shares to Google Drive.

**Parameters:**

* `walletToBackup`: Object containing wallet information
  * `address`: string - The wallet address
  * `chain`: ChainEnum - The chain the wallet is associated with

**Returns:**

* Default mode: `Promise<boolean>` — `true` if backup was successful, `false` otherwise. The underlying error is captured in [`lastBackupError`](#lastbackuperror).
* With `{ throwOnError: true }`: `Promise<boolean>` resolving to `true` on success, or rejecting with the underlying error.

**Example — default (legacy) mode:**

```typescript theme={"system"}
import { ChainEnum } from '@dynamic-labs/sdk-api-core';
const { backupWallet } = useWalletBackup();

const success = await backupWallet({
  address: '0x123...',
  chain: ChainEnum.Evm,
});

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

**Example — opt-in throw mode:**

```typescript theme={"system"}
const { backupWallet } = useWalletBackup({ throwOnError: true });

try {
  await backupWallet({ address: '0x123...', chain: ChainEnum.Evm });
} catch (err) {
  console.error('Backup failed:', err);
}
```

#### `backupToCloudProvider`

Backs up a single wallet's key shares to a specific cloud provider using a per-call options object. Unlike `backupWallet`, this accepts a `CloudProviderBackupOptions` object — which includes an optional consumer-supplied Google Drive access token.

<Note>This method is headless.</Note>

**Parameters:**

* `options`: `CloudProviderBackupOptions`
  * `provider`: `CloudBackupProvider` — `CloudBackupProvider.GoogleDrive` or `CloudBackupProvider.ICloud`.
  * `accountAddress`: string — the wallet address being backed up.
  * `password` (optional): string — password used to encrypt the key share.
  * `googleDriveAccessToken` (optional): string — a consumer-supplied Drive-scoped OAuth access token (`drive.appdata` + `drive.file`). When provided, the SDK uses it directly instead of the stored OAuth token — useful for **external auth** (where the user's Google account isn't linked in Dynamic), and avoids a second Google consent prompt. Only applies to the `GoogleDrive` provider.
* `walletToBackup`: `WalletToBackup` — `{ address, chain }`.

**Returns:**

* Default mode: `Promise<boolean>` — `true` if backup was successful, `false` otherwise (error captured in [`lastBackupError`](#lastbackuperror)).
* With `{ throwOnError: true }`: `Promise<boolean>` resolving to `true` on success, or rejecting with the underlying error.

**Example:**

```typescript theme={"system"}
import { useWalletBackup, CloudBackupProvider } from '@dynamic-labs/sdk-react-core';

const { backupToCloudProvider } = useWalletBackup({ throwOnError: true });

// Uses the user's linked Google account
await backupToCloudProvider(
  { provider: CloudBackupProvider.GoogleDrive, accountAddress: wallet.address },
  wallet,
);

// External auth: supply your own Drive-scoped token
await backupToCloudProvider(
  {
    provider: CloudBackupProvider.GoogleDrive,
    accountAddress: wallet.address,
    googleDriveAccessToken,
  },
  wallet,
);
```

#### `backupAllWallets`

Backs up all wallets (or a specified list of wallets) to Google Drive.

<Note>This method is headless.</Note>

**Parameters:**

* `wallets` (optional): Array of wallet objects to back up. If not provided, backs up all wallets that need backup.

**Returns:** `Promise<void>` — resolves when the loop completes and user data has been refreshed.

**Errors:**

* Default mode: never throws on per-wallet failures. Individual failures are captured via [`lastBackupError`](#lastbackuperror) (which is overwritten by each `backupWallet` call, so it reflects the most recent attempt). `refresh()` always runs at the end.
* With `{ throwOnError: true }`: iterates every wallet, calls `refresh()`, then throws a [`BackupError`](#backuperror) aggregating successful and failed wallets if any failed.

**Example — default (legacy) mode:**

```typescript theme={"system"}
const { backupAllWallets } = useWalletBackup();

// Back up all pending wallets
await backupAllWallets();

// Back up specific wallets
await backupAllWallets([
  { address: '0x123...', chain: ChainEnum.Evm },
  { address: '0x456...', chain: ChainEnum.Evm },
]);
```

**Example — opt-in throw mode with partial-failure handling:**

```typescript theme={"system"}
import { BackupError } from '@dynamic-labs/sdk-react-core';

const { backupAllWallets } = useWalletBackup({ throwOnError: true });

try {
  await backupAllWallets();
} catch (err) {
  if (err instanceof BackupError) {
    console.log(
      `${err.failureCount} of ${err.successCount + err.failureCount} wallets failed`,
    );
    // err.failedWallets is structured for retry logic
  }
}
```

#### `startBackup`

Starts the backup process with progress tracking and error handling. This function backs up wallets sequentially and updates the `backupState` as it progresses.

<Note>This method is headless.</Note>

**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.

**Returns:** `Promise<void>` - Resolves when backup completes or fails.

**Example:**

```typescript theme={"system"}
const { startBackup, backupState } = useWalletBackup();

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

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

#### `getWalletsBackupStatus`

Returns the backup status for all WaaS wallets.

<Note>This method is headless.</Note>

**Returns:** `WalletWithBackupStatus[]` - Array of wallets with their backup status.

**Example:**

```typescript theme={"system"}
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').

<Note>This method is headless.</Note>

**Returns:** `WalletToBackup[]` - Array of wallets that need backup.

**Example:**

```typescript theme={"system"}
const { getWalletsToBackup } = useWalletBackup();

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

### Properties

#### `areAllWalletsBackedUp`

A boolean value indicating whether all WaaS wallets have been backed up to Google Drive.

**Type:** `boolean`

**Example:**

```typescript theme={"system"}
const { areAllWalletsBackedUp } = useWalletBackup();

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

#### `isGoogleLinked`

A boolean value indicating whether the user has linked their Google account.

**Type:** `boolean`

**Example:**

```typescript theme={"system"}
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:**

```typescript theme={"system"}
const { backupState } = useWalletBackup();

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

#### `lastBackupError`

<Warning>
  Deprecated. Pass `{ throwOnError: true }` to `useWalletBackup` and use `try/catch` around `backupWallet` / `backupToCloudProvider` instead. `lastBackupError` and `clearBackupError` will be removed in the next major version.
</Warning>

The error thrown by the most recent `backupWallet` or `backupToCloudProvider` call, or `undefined` if the last attempt succeeded (or no attempt has been made). Updates as React state — components re-render automatically when it changes.

Inspect it during render to drive a post-flight recovery UI for the (rare) case where pre-flight readiness can't predict that a Google Drive upload will fail — for example, legacy users whose stored OAuth scopes weren't recorded. Pair with [`isInsufficientGoogleDriveScopesError`](#scope-helpers-and-error-guards) to detect missing-scope failures and recover by re-prompting consent via [`useGoogleDriveBackupReadiness`](/react/reference/hooks/embedded-wallets/usegoogledrivebackupreadiness).

<Note>
  `lastBackupError` is React state and won't be updated yet immediately after `await backupWallet(...)`. Read it from render, not from the line right after the await.
</Note>

**Type:** `unknown`

**Example:**

```tsx theme={"system"}
import {
  useWalletBackup,
  useGoogleDriveBackupReadiness,
  isInsufficientGoogleDriveScopesError,
  CloudBackupProvider,
} from '@dynamic-labs/sdk-react-core';

function BackupRecovery({ wallet }) {
  const { backupWallet, lastBackupError, clearBackupError } = useWalletBackup();
  const { requestAccess } = useGoogleDriveBackupReadiness();

  const needsScopeRecovery =
    lastBackupError && isInsufficientGoogleDriveScopesError(lastBackupError);

  if (!needsScopeRecovery) return null;

  const onRecover = async () => {
    clearBackupError();
    const r = await requestAccess();
    if (r.status === 'ready') {
      await backupWallet(wallet, CloudBackupProvider.GoogleDrive);
    }
  };

  return (
    <button onClick={onRecover}>Re-grant Drive access and retry</button>
  );
}
```

#### `clearBackupError`

<Warning>
  Deprecated alongside [`lastBackupError`](#lastbackuperror). Prefer `{ throwOnError: true }` and `try/catch`.
</Warning>

Clears `lastBackupError` back to `undefined`. Call this after handling the error so subsequent renders don't re-trigger your fallback logic.

**Returns:** `void`

### `BackupError`

Thrown by `backupAllWallets` (when called with `{ throwOnError: true }`) if one or more per-wallet backups fail. Extends [`AggregateError`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AggregateError), so callers reading the underlying causes via `.errors` keep working; structured fields make it easy to drive partial-failure UI without parsing the message.

**Fields:**

* `operation`: `'backup'` — constant marker.
* `provider`: `CloudBackupProvider` — which cloud provider was being targeted.
* `successfulWallets`: `WalletToBackup[]` — wallets that completed before the error was thrown.
* `failedWallets`: `{ wallet: WalletToBackup; cause: unknown }[]` — wallets that failed and their underlying causes.
* `successCount`: `number` — convenience getter.
* `failureCount`: `number` — convenience getter.
* `message`: `string` — `"Backup failed for X of Y wallet(s): <first underlying cause>"`.

```typescript theme={"system"}
import { BackupError } from '@dynamic-labs/sdk-react-core';

try {
  await backupAllWallets();
} catch (err) {
  if (err instanceof BackupError) {
    // Retry only the wallets that failed
    const retryTargets = err.failedWallets.map((f) => f.wallet);
    await backupAllWallets(retryTargets);
  }
}
```

### Scope helpers and error guards

The same module also exports a few utilities for callers building their own pre-flight or post-flight checks against the Google Drive backup flow.

#### `GOOGLE_DRIVE_BACKUP_REQUIRED_SCOPES`

The readonly tuple of OAuth scopes that must be granted on the user's Google account for the backup upload to succeed.

```typescript theme={"system"}
import { GOOGLE_DRIVE_BACKUP_REQUIRED_SCOPES } from '@dynamic-labs/sdk-react-core';
// [
//   'https://www.googleapis.com/auth/drive.appdata',
//   'https://www.googleapis.com/auth/drive.file',
// ]
```

#### `findMissingGoogleDriveBackupScopes`

Given the scopes the user has granted, returns the subset of required scopes that are still missing.

**Parameters:**

* `grantedScopes`: `readonly string[]`

**Returns:** `string[]`

#### `hasAllGoogleDriveBackupScopes`

Convenience boolean — `true` if `grantedScopes` covers every required scope.

**Parameters:**

* `grantedScopes`: `readonly string[]`

**Returns:** `boolean`

#### `isInsufficientGoogleDriveScopesError`

Type guard for Google Drive backup failures caused by missing or insufficient OAuth scopes. Recover by re-prompting consent (e.g. via `useGoogleDriveBackupReadiness().requestAccess()`) and retrying the backup.

**Parameters:**

* `err`: `unknown`

**Returns:** `err is GoogleDriveBackupAccessError`

```typescript theme={"system"}
import { isInsufficientGoogleDriveScopesError } from '@dynamic-labs/sdk-react-core';

if (isInsufficientGoogleDriveScopesError(lastBackupError)) {
  // Re-prompt Google consent and retry.
}
```

<Tip>For a two-layer (pre-flight + post-flight) integration, see [`useGoogleDriveBackupReadiness`](/react/reference/hooks/embedded-wallets/usegoogledrivebackupreadiness).</Tip>

### Usage

```typescript theme={"system"}
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:

```typescript theme={"system"}
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>
  );
};
```

### Important Notes

* The user must be authenticated to use backup functionality
* Google account linking is required before backing up wallets
* 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`

### Learn More

* [Google Drive Backup Documentation](/react/wallets/embedded-wallets/mpc/google-drive-backup)
* [MPC Embedded Wallets](/overview/wallets/embedded-wallets/mpc/overview)
* [DynamicContextProvider](/react/reference/providers/dynamiccontextprovider)

### Return Value

The hook signature:

```typescript theme={"system"}
useWalletBackup(options?: UseWalletBackupOptions): {
  areAllWalletsBackedUp: boolean;
  backupAllWallets: (wallets?: WalletToBackup[]) => Promise<void>;
  backupState: WalletOperationState;
  backupToCloudProvider: (
    options: CloudProviderBackupOptions,
    walletToBackup: WalletToBackup,
  ) => Promise<boolean>;
  backupWallet: (walletToBackup: WalletToBackup) => Promise<boolean>;
  /** @deprecated use { throwOnError: true } and try/catch */
  clearBackupError: () => void;
  ensureGoogleLinked: () => Promise<boolean>;
  getWalletsBackupStatus: () => WalletWithBackupStatus[];
  getWalletsToBackup: () => WalletToBackup[];
  initBackupProcess: () => void;
  isGoogleLinked: boolean;
  /** @deprecated use { throwOnError: true } and try/catch */
  lastBackupError: unknown;
  startBackup: (onComplete?: () => void, fromIndex?: number) => Promise<void>;
}
```

### Types

```typescript theme={"system"}
interface UseWalletBackupOptions {
  throwOnError?: boolean;
}

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

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

// CloudBackupProvider.GoogleDrive | CloudBackupProvider.ICloud
type CloudProviderBackupOptions = {
  provider: CloudBackupProvider;
  accountAddress: string;
  password?: string;
  googleDriveAccessToken?: string;
};

interface WalletWithBackupStatus extends WalletToBackup {
  status: WalletBackupStatus;
}

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