Prerequisites
Before this page: the user has connected a Kraken or Coinbase account through Dynamic’s exchange connection flow, and the exchange is enabled for your environment in the dashboard.
What you’ll build
An exchange transfer flow lets a user move funds from a connected exchange account to an external wallet address. The transfer form is the same shape for every exchange: pick an account, a currency, an amount, and a destination.
Coinbase transfers can bounce back twice before they complete, each needing its own prompt:
- Two-step verification. Coinbase sends the account holder a one-time code and asks for it.
- Travel Rule information. For some transfers, Coinbase is legally required to collect basic recipient identity details.
Kraken only surfaces the first of these to createKrakenExchangeTransfer (as an optional mfaCode parameter). Kraken also has Travel Rule requirements in some regions, but it collects that information when the user adds a withdrawal address in Kraken’s own UI, not when a transfer is submitted; Kraken’s withdraw API only ever accepts a pre-approved address, never an arbitrary one. So the Kraken form is the same pattern as below with the Travel Rule step removed.
Load the user’s accounts, then collect a currency, amount, and destination address for the selected account.
If you already know the recipient (a saved address, for example), collect Travel Rule fields on this same form and send them on the first submission. Coinbase checks two-step verification before Travel Rule on every request, so sending Travel Rule data late means the user goes through two-step verification twice instead of once. See createCoinbaseExchangeTransfer for the full field list.
Handling two-step verification
The first createCoinbaseExchangeTransfer call for a transfer makes Coinbase send the account holder a one-time code, and the call throws CoinbaseTransferMfaRequiredError. Show a code input, then retry the same transfer with mfaCode set. A wrong or expired code throws CoinbaseTransferMfaFailedError; retry without mfaCode to get a fresh one.
Handling the Travel Rule step
If a transfer needs recipient information that wasn’t sent upfront, the call throws CoinbaseTravelRuleRequiredError with a missingFields array: each entry has a name (for example BENEFICIARY_NAME) and a description you can show directly to the user. Collect those fields and retry.
Adding travelRuleData on a retry changes the request body, which invalidates any mfaCode already collected for it. Drop mfaCode from the params before this retry so the next attempt gets a fresh two-step code if one is still needed, instead of failing with CoinbaseTransferMfaFailedError.
Putting it together
Combine both handlers into a single retry loop. In practice this resolves in one attempt for most transfers, since the earlier tip has you sending known recipient info upfront.
Handling errors
See also