Skip to main content
Migration takes over the key material from a user’s Fireblocks Non-Custodial Wallet (NCW) and provisions Dynamic embedded wallets for it. It is a single cross-chain operation: one call migrates the device across every supported chain and preserves the wallet addresses the user already had.
Before you start. This is for apps already running a Fireblocks NCW integration. The user must be signed in to Dynamic — migration creates the embedded wallet for the current Dynamic user, and your Fireblocks wallet is left untouched. You supply the existing device’s deviceId, password, and storage from your NCW integration, plus a jwt from your own auth. Migration currently supports EVM and Solana; other chains come back as a per-chain failure (see Result).

Prerequisites

Fireblocks migration is behind a feature flag. Contact support to enable it for your environment.
Before users can migrate, set up the migration backend — see Migrate from Fireblocks for the full setup. In short:
  • Dashboard — configure the migration backend base URL and environment (sandbox / production) in your environment settings.
  • Backend — expose POST /api/devices/{deviceId}/rpc that relays NCW messages to Fireblocks, and enable CORS for the Dynamic iframe origin https://app.dynamicauth.com.
Fireblocks migration settings in the Dynamic dashboard

Migrate a wallet

migrateFromFireblocks(options) is available from the useDynamicWaas hook. Parameters:
  • deviceId: string — The Fireblocks NCW device id being migrated.
  • jwt: string — Your application’s auth token for the user (for example, from social login). It’s forwarded as the bearer token to your backend’s RPC endpoint, which authenticates the request. This is not a Fireblocks credential — your Fireblocks API auth stays on the backend.
  • password: string — The password that encrypted the NCW device storage. Required.
  • storage: Record<string, string> — The device’s persisted Fireblocks NCW entries (every NCW-* key), verbatim — the encrypted values exactly as stored. See Building the storage map.
  • expectedAddresses: Record<string, string> — Required. The wallet address Fireblocks held per chain name (for example, { EVM: "0x…" }). Its keys are the chains migration runs on — only those chains are migrated — and each imported Dynamic address is verified against the value, so a wrong derivation fails loudly instead of producing an unusable wallet.
The call returns once every chain has been processed. It resolves to undefined if no embedded wallet chain is enabled for the environment; otherwise inspect result.wallets for the per-chain outcome (see Result).

Building the storage map

storage must contain the device’s persisted Fireblocks NCW entries (every NCW-* key) verbatim — the encrypted values exactly as stored. The migration iframe re-hydrates this map and decrypts the secure entries itself using the same password and deviceId, so the values must stay as ciphertext. Build it in your application, where your Fireblocks NCW integration persisted the device. The snippet below reads the default browser storage; if you configured a custom NCW storage provider, read the device’s entries from there instead.
Enumerate the base BrowserLocalStorageProvider so secure entries stay encrypted. Do not read entries through a secure-storage provider (ISecureStorageProvider, e.g. PasswordEncryptedLocalStorage) — its get() decrypts to plaintext, which will not round-trip through the takeover.

Result

On success the call resolves to a MigrateFromFireblocksResponse:
Migration is per chain, so inspect wallets to see which chains migrated. account is the created Dynamic embedded wallet account; fireblocksAlgorithm and fireblocksKeyId identify the source Fireblocks key, useful for logging and reconciliation. Re-running migration is safe: a chain already imported on a prior run comes back as { ok: true, alreadyMigrated: true }. A { ok: false } entry means that chain failed while others may have succeeded — surface it and let the user retry. Possible errorCode values: Treat any other ok: false as a failure to surface and retry.
The password must match the password that originally encrypted the Fireblocks NCW device storage. A wrong password fails the takeover; it does not create a usable wallet.
Last modified on June 25, 2026