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

# Offline Recovery

> Hold an encrypted recovery share so users can reconstruct their embedded wallet when Dynamic is offline.

## How does it work?

Offline recovery creates two additional encrypted key shares (a 2-of-2 pair), separate from the wallet's primary key shares:

* **Share 1.** Encrypted and stored in the user's Google Drive.
* **Share 2.** Encrypted and delivered to your configured webhook when you run an offline recovery reshare.

Share 1 and Share 2 can be combined for offline recovery.

## Configure offline recovery

To enable the feature follow the following steps:

1. Configure [Google Drive](/docs/overview/wallets/embedded-wallets/mpc/google-drive-backup) for your environment.
2. In the developer dashboard, go to **Wallets > Embedded Wallets > Backup & Recovery**.
3. Turn on **Developer Recovery Share**.
4. Configure the **Share Delivery** webhook URL and the RSA public key used to encrypt shares.

When offline recovery is enabled, users cannot use Google Drive as a regular cloud backup.

<Note>
  If [delegated access](/docs/overview/wallets/embedded-wallets/mpc/delegated-access/overview) is enabled, offline recovery uses the same share-delivery webhook URL and encryption key.
</Note>

## Request a recovery share

Run an offline recovery reshare from the SDK for the user:

```typescript theme={"system"}
import { createWaasOfflineRecoveryShares } from '@dynamic-labs-sdk/client/waas';

// walletAccount: WalletAccount from the Dynamic client
await createWaasOfflineRecoveryShares({
  walletAccount,
});
```

This creates the recovery shares: Share 1 goes to Google Drive, and Share 2 is delivered to your webhook.

Step-up authentication is not required, but we strongly recommend requiring it before a recovery share is generated. Complete MFA, then pass the resulting `mfaToken`:

```typescript theme={"system"}
import { authenticateTotpMfaDevice } from '@dynamic-labs-sdk/client';
import { createWaasOfflineRecoveryShares } from '@dynamic-labs-sdk/client/waas';

// code: 6-digit TOTP from the user's authenticator app
const { mfaToken } = await authenticateTotpMfaDevice({
  code,
  createMfaTokenOptions: { singleUse: true },
});

await createWaasOfflineRecoveryShares({
  walletAccount,
  mfaToken,
});
```

For other verification methods (passkey, email OTP, and more), see [Step-up authentication](/docs/overview/authentication/step-up-auth).

Your webhook receives a `wallet.offlineRecovery.created` event containing the encrypted Share 2. Store Share 2 securely.

## Recovery

To recover, the user needs both recovery shares:

1. **Share 2** from your webhook.
2. **Share 1** from their Google Drive.

With both shares, recovery is a local cryptographic operation. Dynamic is not involved.

Install the browser wallet package, then call `offlineExportKey` with the two decrypted shares:

```bash theme={"system"}
npm install @dynamic-labs-wallet/browser
```

```typescript theme={"system"}
import { DynamicWalletClient } from '@dynamic-labs-wallet/browser';

// environmentId: your Dynamic environment ID
// share1, share2: decrypted key shares ({ pubkey, secretShare })
const client = new DynamicWalletClient({ environmentId });

const { derivedPrivateKey } = await client.offlineExportKey({
  chainName: 'EVM',
  keyShares: [share1, share2],
});
```

For a full implementation, including decrypting Share 1 and Share 2, see the [example recovery tool](https://github.com/dynamic-labs-oss/offline-recovery).
