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

# Export keys from DFNS

> Step-by-step procedure to export a wallet key from DFNS and use it independently, whether to migrate to another provider or to hold a backup, including an offline signing test.

export const SupportLink = ({children}) => {
  const url = "https://support.dfns.co";
  return <a href={url} target="_blank">{children || url}</a>;
};

This guide walks through exporting a wallet's private key out of DFNS and confirming it works. The ceremony is the same whichever goal you have:

* **Migrate to another provider** — move a key to a different custody solution. See also [importing keys](/guides/developers/import-keys) for the reverse direction.
* **Disaster recovery backup** — hold an independent, point-in-time copy so you can keep operating if DFNS is unavailable. See [manual key backup](/advanced/deployment-models/disaster-recovery#manual-key-backup-key-export) for how this compares to Layer 4.

For how export works under the hood, see [Key import and export](/advanced/key-import-and-export#export). Export is not enabled by default — contact our <SupportLink>Support Team</SupportLink> to activate it for your organization.

<Warning>
  The ceremony reconstitutes the full wallet private key — a single point of failure — on the machine that runs it. Run it on a trusted, isolated machine, and from the moment the key exists, treat it as break-glass: keep it offline, encrypt it at rest, restrict access, and securely erase every intermediate copy once you are done.
</Warning>

## Export a key

The export ceremony needs connectivity to the DFNS API — it is the one unavoidable online step. Everything you do with the key afterwards should stay offline.

**Requirements:**

* Export activated for your organization (contact our <SupportLink>Support Team</SupportLink>).
* A service account or user with the `Keys:Export` permission, and its [signing key pair](/guides/developers/generate-a-key-pair). Export requires a user action signature, which the SDK produces with this key.
* The `keyId` of the key to export (find it on the wallet in the dashboard or via [List Wallets](/api-reference/wallets/list-wallets)).
* A trusted, isolated machine with Node.js and the [export SDK example](https://github.com/dfns/dfns-sdk-ts/tree/m/examples/sdk/export-wallet), which uses `@dfns/sdk-keyexport-utils-nodejs`.

<Steps>
  <Step title="Run the export ceremony">
    The SDK generates an ephemeral encryption key pair, calls [Export Key](/api-reference/keys/export-key), and reconstitutes the private key locally — DFNS never handles a plaintext key ([details](/advanced/key-import-and-export#export)).

    ```ts theme={null}
    const ctx = newWalletExportContext()
    const exported = await dfnsApi.keys.exportKey({ keyId: KEY_ID, body: ctx.getConf() })
    const privateKey = ctx.recoverSecretKey(exported) // full wallet private key, in memory
    ```

    See the [export SDK example](https://github.com/dfns/dfns-sdk-ts/tree/m/examples/sdk/export-wallet) for the complete, runnable program.
  </Step>

  <Step title="Secure the recovered key">
    Disconnect the machine from the network. Move the key to encrypted, offline storage — cold storage, an HSM, or a hardware-encrypted medium — with tightly restricted access, then securely erase every plaintext copy from the ceremony machine.

    Exporting does not affect the wallet in DFNS: it keeps signing normally and is flagged as exported. Nothing changes on-chain, and no funds move until you sign with the exported key.
  </Step>
</Steps>

## \[Optional] Verify the exported key

Confirm the exported key controls the wallet by signing with it — the same operation you would perform to use the key elsewhere. Signing stays on the offline machine; only the signed transaction crosses to an online machine to broadcast, so the private key never goes online.

<Warning>
  A recovered key is live and controls the same address on every chain. Test on a testnet (Sepolia) so no real assets move.
</Warning>

**Requirements:**

* Offline machine holding the exported key.
* Online machine to broadcast the signed transaction.
* Removable media (e.g. an SD card or a USB drive) to move files between the two.
* Foundry's [`cast`](https://getfoundry.sh/cast/overview) on both machines. Copy the binary to the offline machine from a verified download rather than installing over the network.

<Steps>
  <Step title="Collect transaction parameters (online)">
    On the online machine, note the values the offline signer needs: the address's current nonce, a gas price, and the chain ID (Sepolia is `11155111`). Fund the address with a little Sepolia test ETH from a public faucet — a zero-value transaction still needs gas. Carry these values to the offline machine.
  </Step>

  <Step title="Derive the address and sign (offline)">
    On the offline machine, take the exported key's hex value for the secp256k1 curve (an Ethereum key) and prefix it with `0x`.

    Derive the address and confirm it matches the one you funded:

    ```bash theme={null}
    cast wallet address --private-key 0x<private_key>
    ```

    Build and sign the transaction offline. This prints a signed raw transaction hex and broadcasts nothing:

    ```bash theme={null}
    cast mktx <address> \
      --value 0 \
      --nonce <nonce> \
      --gas-limit 21000 \
      --gas-price <gas_price> \
      --chain 11155111 \
      --legacy \
      --private-key 0x<private_key>
    ```

    Copy the signed raw transaction hex onto removable media. It contains no private key, so it is safe to move to an online machine.
  </Step>

  <Step title="Broadcast the signed transaction (online)">
    On the online machine, broadcast the signed transaction from Etherscan's [Broadcast Transaction](https://sepolia.etherscan.io/pushTx) page, or from any machine with an RPC endpoint:

    ```bash theme={null}
    cast publish <signed_raw_tx> --rpc-url https://rpc.sepolia.org
    ```

    A returned transaction hash confirms the exported key signs correctly.
  </Step>
</Steps>
