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

# Exporting a wallet

> Let a customer take the seed of their Global Account off Grid

Exporting a wallet returns the wallet's mnemonic seed, encrypted to the client's public key. The customer decrypts it on their device and can then import the wallet into any compatible self-custody client. Grid never sees the plaintext seed leaving the system.

Export uses the same [signed-retry pattern](https://agents-docs.lightspark.com/global-p2p/global-accounts/authentication.md#the-signed-retry-pattern) as credential and session revocation — the initial `POST` returns a `payloadToSign`, and the signed retry returns the encrypted seed.

Generate a fresh P-256 key agreement key pair specifically for the export (see [Wallet export key pair](https://agents-docs.lightspark.com/global-p2p/global-accounts/client-keys.md#wallet-export-key-pair)). Send its public key as `clientPublicKey` on both export requests, as an uncompressed key in lowercase hex (130 characters, `04` prefix), then decrypt `encryptedWalletCredentials` with the matching private key after the signed retry succeeds.

```mermaid theme={null}
sequenceDiagram
  participant C as Client
  participant IB as Integrator backend
  participant G as Grid

  IB->>G: POST /internal-accounts/{id}/export { clientPublicKey }
  G-->>IB: 202 { payloadToSign, requestId, expiresAt }
  IB-->>C: { payloadToSign, requestId }
  C->>C: stamp(payloadToSign, sessionPrivateKey)
  C->>IB: { stamp }
  IB->>G: POST /internal-accounts/{id}/export { same clientPublicKey }<br/>Grid-Wallet-Signature<br/>Request-Id
  alt still settling at the wallet provider
    G-->>IB: 200 { status: "PROCESSING" }
    IB->>G: Re-send the identical signed request
  end
  G-->>IB: 200 { id, encryptedWalletCredentials }
  IB-->>C: { encryptedWalletCredentials }
  C->>C: decrypt with client private key<br/>→ mnemonic
```

**1. First call — receive the challenge**

```bash theme={null}
curl -X POST "$GRID_BASE_URL/internal-accounts/InternalAccount:019542f5-b3e7-1d02-0000-000000000002/export" \
  -u "$GRID_CLIENT_ID:$GRID_CLIENT_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "clientPublicKey": "04f45f2a22c908b9ce09a7150e514afd24627c401c38a4afc164e1ea783adaaa31d4245acfb88c2ebd42b47628d63ecabf345484f0a9f665b63c54c897d5578be2"
  }'
```

**Response (202):**

```json theme={null}
{
  "payloadToSign": "{\"organizationId\":\"org_2m9F...\",\"parameters\":{\"targetPublicKey\":\"04f45f2a22c908b9ce09a7150e514afd24627c401c38a4afc164e1ea783adaaa31d4245acfb88c2ebd42b47628d63ecabf345484f0a9f665b63c54c897d5578be2\",\"walletId\":\"wallet_2m9F...\"},\"timestampMs\":\"1775681700000\",\"type\":\"ACTIVITY_TYPE_EXPORT_WALLET\"}",
  "requestId": "Request:c3f8a614-47e2-4a19-9f5d-2b0a91d47e08",
  "expiresAt": "2026-04-19T12:10:00Z"
}
```

**2. Client stamps the payload**

Build a Grid wallet signature over `payloadToSign` with an active session signing key on the account. Keep the export private key on the client; Grid will use the matching `clientPublicKey` from step 1 to seal the wallet credentials.

**3. Signed retry — receive the encrypted seed**

```bash theme={null}
curl -X POST "$GRID_BASE_URL/internal-accounts/InternalAccount:019542f5-b3e7-1d02-0000-000000000002/export" \
  -u "$GRID_CLIENT_ID:$GRID_CLIENT_SECRET" \
  -H "Content-Type: application/json" \
  -H "Grid-Wallet-Signature: eyJwdWJsaWNLZXkiOiIwMmExYjIuLi4iLCJzY2hlbWUiOiJTSUdOQVRVUkVfU0NIRU1FX1RLX0FQSV9QMjU2Iiwic2lnbmF0dXJlIjoiMzA0NTAyMjEwMC4uLiJ9" \
  -H "Request-Id: Request:c3f8a614-47e2-4a19-9f5d-2b0a91d47e08" \
  -d '{
    "clientPublicKey": "04f45f2a22c908b9ce09a7150e514afd24627c401c38a4afc164e1ea783adaaa31d4245acfb88c2ebd42b47628d63ecabf345484f0a9f665b63c54c897d5578be2"
  }'
```

**Response (200):**

```json theme={null}
{
  "id": "InternalAccount:019542f5-b3e7-1d02-0000-000000000002",
  "encryptedWalletCredentials": "{\"version\":\"v1.0.0\",\"data\":\"7b22656e6361707065645075626c6963223a2230346634356632612e2e2e222c2263697068657274657874223a22316661313032333339302e2e2e222c226f7267616e697a6174696f6e4964223a226f72675f326d39462e2e2e227d\",\"dataSignature\":\"3045022100...\",\"enclaveQuorumPublic\":\"04a1b2c3...\"}"
}
```

Export shares its terminal status code with the still-processing response: a `200` here is only the encrypted seed if the body isn't `{ "status": "PROCESSING" }`. See [handling a still-processing response](https://agents-docs.lightspark.com/global-p2p/global-accounts/authentication.md#handling-a-still-processing-response) — if you get `PROCESSING`, re-send the identical signed retry (same `clientPublicKey`, `Grid-Wallet-Signature`, and `Request-Id`) until you get the credentials. Because Grid never stores them, the re-send is the only way to receive them; subscribe to `wallet_operation.completed` to know when it will succeed. The `Request-Id` challenge is consumed only by the attempt that actually returns credentials, so a `PROCESSING` response leaves it usable.

**4. Decrypt on the client**

`encryptedWalletCredentials` is a signed wallet export envelope. Parse the envelope, verify `dataSignature` against `enclaveQuorumPublic`, decode the hex `data` JSON to get `encappedPublic` and `ciphertext`, then decrypt with the export private key that matches the `clientPublicKey` you sent on both export requests.

The plaintext is a BIP-39 mnemonic (the wallet's master seed).

> [!WARNING]
>
> The exported mnemonic is the master key of the self-custody wallet. After decryption the customer is the only custodian — if the mnemonic is lost, the funds are lost. Surface appropriate warnings in your UI before running an export.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.