Skip to main content

Documentation Index

Fetch the complete documentation index at: https://www.dynamic.xyz/docs/llms.txt

Use this file to discover all available pages before exploring further.

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 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 then retry.
To enable the API:
  1. Go to the Google Cloud Console
  2. Select your project
  3. Navigate to APIs & Services > Library
  4. Search for “Google Drive API”
  5. Click Enable
If you recently enabled the API, wait a few minutes for the changes to propagate before retrying.

Required OAuth scopes

When users authenticate with Google Drive, the following scopes are requested:
ScopePurpose
https://www.googleapis.com/auth/drive.appdataAllows 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.fileAllows storage in the user’s personal Google Drive. This provides a user-accessible backup location.
Google presents these scopes on the consent screen as opt-in checkboxes that are unchecked by default. 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 below: it lets you detect and recover from the partially-granted scope case before triggering the MPC reshare ceremony.
Google consent screen showing Drive scopes as unchecked opt-in boxes

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

Key share encryption

For meaningful protection, we recommend setting a password for the key share 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 authentication for details on how users can connect their Google account via signInWithSocialRedirect.

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.

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 getGoogleDriveBackupReadiness function lets you detect — and recover from — these situations before triggering the ceremony. It pairs with the backup flow as a two-layer defense:
  • Layer 1 — pre-flight readiness: call getGoogleDriveBackupReadiness() when the user opens the backup CTA. If status is 'needs-access', send the user through signInWithSocialRedirect({ provider: 'google' }) to re-prompt the Google consent screen, then call the readiness check again before proceeding with the backup.
  • 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. Wrap the backup call in a try/catch and use isInsufficientGoogleDriveScopesError(error) to detect the scope-denied failure mode; on a match, surface a “Re-grant Drive access” UI that re-links Google and retries the backup.
import {
  getGoogleDriveBackupReadiness,
  isInsufficientGoogleDriveScopesError,
  signInWithSocialRedirect,
} from '@dynamic-labs-sdk/client';

const backupToGoogleDrive = async (walletAccount) => {
  // Layer 1: pre-flight — saves an MPC reshare ceremony when we can already
  // tell the upload will fail.
  let readiness = await getGoogleDriveBackupReadiness();

  if (readiness.status === 'needs-access') {
    await signInWithSocialRedirect({
      provider: 'google',
      redirectUrl: window.location.href,
    });
    // After the redirect resolves, call getGoogleDriveBackupReadiness() again
    // to verify the user granted the required scopes before proceeding.
    return;
  }

  try {
    // ...trigger your Google Drive backup flow here
  } catch (error) {
    // Layer 2: post-flight — catches the legacy "unknown scopes" case where
    // pre-flight returned 'ready' (or 'needs-access' with empty missingScopes)
    // but the upload still failed for scope reasons.
    if (isInsufficientGoogleDriveScopesError(error)) {
      await signInWithSocialRedirect({
        provider: 'google',
        redirectUrl: window.location.href,
      });
      return;
    }
    throw error;
  }
};
See the getGoogleDriveBackupReadiness reference for full status semantics, helper functions, and types.

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 for more details.