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.
- Dashboard — configure the migration backend base URL and environment (
sandbox/production) in your environment settings. - Backend — expose
POST /api/devices/{deviceId}/rpcthat relays NCW messages to Fireblocks, and enable CORS for the Dynamic iframe originhttps://app.dynamicauth.com.

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 (everyNCW-*key), verbatim — the encrypted values exactly as stored. See Building thestoragemap.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.
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.
Result
On success the call resolves to aMigrateFromFireblocksResponse:
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:
errorCode | Meaning |
|---|---|
MIGRATION_UNSUPPORTED_CHAIN | The chain can’t be migrated from a Fireblocks NCW wallet (e.g. Aleo, Midnight). |
MIGRATION_UNVERIFIED_CHAIN | The chain isn’t supported for migration yet. |
MIGRATION_NO_KEY_FOR_ALGO | The device has no key for that chain’s signing algorithm. |
MIGRATION_IMPORT_* | The key import into Dynamic failed (transient backend or address-check issue). Safe to retry. |
ok: false as a failure to surface and retry.