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

# Google Drive backup setup

> Configure Google Drive as a backup option for embedded wallet recovery

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

To enable Google Drive backup for your users, you need to complete two configuration steps:

## 1. Enable in Dynamic dashboard

Navigate to your [Dynamic Dashboard](https://app.dynamic.xyz/dashboard) and enable Google Drive as a backup option in your embedded wallet settings.

## 2. Enable Google Drive API in Google Cloud Console

You must enable the Google Drive API in your Google Cloud project. If the API is not enabled, users will see an error like:

> Google Drive API has not been used in project before or it is disabled. Enable it by visiting [https://console.developers.google.com/apis/api/drive.googleapis.com/overview](https://console.developers.google.com/apis/api/drive.googleapis.com/overview) then retry.

To enable the API:

1. Go to the [Google Cloud Console](https://console.developers.google.com/)
2. Select your project
3. Navigate to **APIs & Services** > **Library**
4. Search for "Google Drive API"
5. Click **Enable**

<Note>
  If you recently enabled the API, wait a few minutes for the changes to propagate before retrying.
</Note>

## Required OAuth scopes

When users authenticate with Google Drive, the following scopes are requested:

| Scope                                           | Purpose                                                                                                                                           |
| ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `https://www.googleapis.com/auth/drive.appdata` | Allows storage in the app-specific hidden folder. This data is only accessible by your application and is not visible to the user in their Drive. |
| `https://www.googleapis.com/auth/drive.file`    | Allows storage in the user's personal Google Drive. This provides a user-accessible backup location.                                              |

<Warning>
  Google presents these scopes on the consent screen as **opt-in checkboxes** that are **unchecked by default** — see the "Select what *your-app* can access" panel below. If the user clicks **Continue** without ticking both boxes (or only ticks one), the Google account will be linked but the Drive upload will fail.

  Surface a clear instruction near the "Backup to Google Drive" CTA — for example: *"On the Google consent screen, please check **both** Google Drive permissions so we can save your backup."* This is also why we recommend the [pre-flight readiness check](#pre-flight-readiness-check) below: it lets you detect and recover from the partially-granted scope case before triggering the MPC reshare ceremony.
</Warning>

<img src="https://mintcdn.com/dynamic-docs/jVr-lVqEGAFM7Eax/images/mpc/google-drive-consent-scopes.png?fit=max&auto=format&n=jVr-lVqEGAFM7Eax&q=85&s=ca31d2e17f85b88d193d88a1d8d6a785" alt="Google consent screen showing Drive scopes as unchecked opt-in boxes" width="2402" height="2030" data-path="images/mpc/google-drive-consent-scopes.png" />

## Dual storage locations

The User Share is stored in two locations for redundancy:

1. **App Data folder** - A hidden, application-specific storage area in Google Drive. Only your application can access this data, providing secure storage that users cannot accidentally delete.

2. **Personal Google Drive** - A user-visible backup in the user's Drive. This ensures users have direct access to their backup if needed.

This dual storage approach ensures maximum reliability for wallet recovery while maintaining security.

<Note>
  Even though developers can obtain OAuth access tokens for users who authenticate with Google, this does **not** grant access to the user's wallet. The key share stored in Google Drive cannot be used by the developer or backend to reconstruct the wallet, and it remains inaccessible without the user's participation.
</Note>

## Key share encryption

For meaningful protection, we recommend setting a [password for the key share](/overview/wallets/embedded-wallets/mpc/configuration-guide#password) during wallet creation or update. This is the security boundary that prevents anyone (including developers) from decrypting the backup.

If no password is provided, the key share is still stored in an encrypted format ensuring the key share cannot be used outside the project context.

## Linking Google account

Users don't need to sign in with Google to enable this feature. They can link their Google account at any point after wallet creation to enable Google Drive backup. See [social linking](/react/users/social-linking) for more details on how users can connect their Google account.

## How key share backup works

The share that gets backed up to Google Drive depends on whether delegation is enabled for your project.

### Google Drive only (2-of-3)

When a user backs up to Google Drive without delegation, a reshare operation creates new key shares:

* The client keeps **Share B** (stored at both Dynamic backend and locally)
* A new **Share C** is created and uploaded exclusively to Google Drive

This means Google Drive holds a different share than the client's local/Dynamic share.

### Delegation + Google Drive (2-of-3)

When delegation is enabled (either before or after Google Drive), the share distribution changes:

* The client's **Share B** is backed up to both Dynamic and Google Drive (same share in both locations)
* A new **Share C** (the delegated share) is sent to the project's webhook

In this scenario, Google Drive acts as a redundant backup of the client's share rather than holding a unique share. This design ensures the delegated share remains exclusively on the webhook server, maintaining the security model where the project environment controls access to the delegated share.

## Programmatic backup management

You can programmatically manage Google Drive backups using the [`useWalletBackup`](/react/reference/hooks/embedded-wallets/usewalletbackup) hook. This hook allows you to:

* Trigger backup flows programmatically
* Check backup status
* Manage backup configurations

See the [useWalletBackup documentation](/react/reference/hooks/embedded-wallets/usewalletbackup) for implementation details.

## Pre-flight readiness check

Backup uploads to Google Drive can fail if the user's linked Google account is missing one of the required OAuth scopes (for example, the user previously linked Google for sign-in only and never granted Drive access). Without a pre-flight check, the SDK would still kick off an MPC reshare ceremony before discovering the upload can't succeed.

The [`useGoogleDriveBackupReadiness`](/react/reference/hooks/embedded-wallets/usegoogledrivebackupreadiness) hook lets you detect — and recover from — these situations *before* triggering the ceremony. It pairs with `useWalletBackup` as a two-layer defense:

* **Layer 1 — pre-flight readiness:** call `check()` when the user opens the backup CTA. If `status` is `'needs-access'`, call `requestAccess()` to re-prompt the Google consent screen, then proceed with `backupWallet(...)`.
* **Layer 2 — post-flight recovery:** for legacy users where the stored OAuth scopes weren't recorded, pre-flight cannot tell whether the upload will succeed. Pass `{ throwOnError: true }` to `useWalletBackup` and wrap `backupWallet(...)` in `try/catch` — when `isInsufficientGoogleDriveScopesError` matches in the catch, call `requestAccess()` and retry.

See the [`useGoogleDriveBackupReadiness` reference](/react/reference/hooks/embedded-wallets/usegoogledrivebackupreadiness) for a full code example.

## Provide your own Google Drive access token

By default the SDK resolves the Drive access token from the user's Google account linked in Dynamic. If you manage Google authentication yourself — for example with **external auth**, where the user's Google account isn't linked in Dynamic — you can pass your own Drive-scoped access token to `backupToCloudProvider`. When provided, the SDK uses it directly and skips the stored-token lookup, avoiding a second Google consent prompt.

The token must already be granted the required Drive scopes (`drive.appdata` and `drive.file`).

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

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

await backupToCloudProvider(
  {
    provider: CloudBackupProvider.GoogleDrive,
    accountAddress: wallet.address,
    // Optional: a Drive-scoped OAuth access token you obtained yourself.
    // When omitted, the SDK falls back to the user's linked Google account.
    googleDriveAccessToken,
  },
  wallet,
);
```

See the [`backupToCloudProvider` reference](/react/reference/hooks/embedded-wallets/usewalletbackup#backuptocloudprovider) for the full option list.

## Webhook event

When a user successfully backs up their key shares to Google Drive, 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](/overview/developer-dashboard/webhooks/events) for more details.
