Skip to main content
This is an enterprise-only feature. Please contact us to enable.
Connections can also move funds out of a user’s exchange account. Open the hosted page with ?intent=fundFromExchange and it signs the user in to the exchange over OAuth, reads their balances, and (in the default mode) asks the exchange to withdraw to an address you name. Coinbase is the only exchange wired today. This is not a wallet operation. No wallet is connected, nothing is signed on device, and the exchange itself broadcasts the withdrawal. The intent has two modes:

transfer (default)

Link, pick a balance, confirm, and the exchange sends the funds. Returns the exchange’s transfer id.

balances

Link and read only. Returns the balance list after the user agrees to share it. Nothing moves.
There is no headless path for either mode. OAuth has nowhere to run inside the hidden web view used by headless Connections: a popup has no surface, and a cross-origin redirect is refused by its navigation delegate. Both modes run in the system browser (ASWebAuthenticationSession on iOS, Chrome Custom Tabs on Android).

What you need

  • The exchange enabled for your Dynamic environment in the dashboard funding settings. Without it, the flow returns an error at the link step.
  • A redirect_uri you control: your app’s custom scheme for native callers, or an allow-listed http(s) host (see Securing the redirect).
  • For mode=balances with an http(s) redirect, a configured redirect host allow-list. The page refuses the request otherwise.
The flow is never silent. Expect the browser to open, an exchange sign-in, and one or two further prompts on the page: two-step verification if the account has it on, and recipient details when the jurisdictions involved require them.

Request parameters

Add these to your hosted Connections page URL, alongside the redirect_uri, nonce, and environmentId parameters that every Connections request takes.

Result parameters

The page redirects back to your redirect_uri with the result as query parameters, and always echoes nonce so a caller with several requests in flight can tell them apart. Compare it against the value you sent and drop the result if it differs. A transfer success: A balances success: A failure in either mode: If the user dismisses the browser instead of finishing, no redirect fires at all. Treat that as a cancel, not an error.

Read balances instead

mode=balances runs the same OAuth link step, then stops. It never asks the exchange for a transfer, and it needs no to, amount, or network. Use it to show the user what they hold before you ask them to fund anything. The page returns only after the user taps through a screen naming who receives the list. A failed read returns on its own, since it carries nothing sensitive.
Flutter is the only native wrapper for mode=balances today. In Swift and Kotlin, open the hosted page with mode=balances through the same session API the transfer flow uses and parse the accounts parameter off the callback.

Add it to your app

The fund methods ship inside the same copy-paste sources the platform guides publish for basic connect, so there is nothing new to add and nothing new in your dependency list. If you already followed your platform’s Connections guide, refresh your copy of its harness file and reuse the callback scheme you registered there.
1. Use the harness file. The fireblocks_connect.dart on Connections on Flutter already includes FireblocksConnect.fundFromExchange and FireblocksConnect.getExchangeBalances, and its models.dart carries the ExchangeTransferResult and ExchangeBalancesResult types. Re-copy the files from that guide, or pull just those additions into your copy.2. Reuse your callback scheme. Both methods redirect to <scheme>://wallet-callback, the same target basic connect uses, so the Info.plist entry and the AndroidManifest.xml intent filter from the Flutter guide already cover this flow. flutter_web_auth_2 is the only dependency involved.3. Fund an address.
fund_button.dart
4. Or read balances only.
balances_button.dart

Security

mode=balances with an http(s) redirect_uri requires a configured redirect host allow-list. The page refuses the request when the allow-list is unset, because an attacker-chosen host would otherwise receive a linked user’s whole balance list. Custom app schemes are never host-filtered and are unaffected. See Securing the redirect.
  • The user always confirms. A transfer takes an explicit confirm step, and a balance read takes an explicit share step that names the receiving host or scheme. Neither mode returns data without a tap.
  • Restrict environmentId in production. Every value the OAuth request is built from comes from that environment’s own project settings, so an unrestricted ?environmentId= lets a caller run the exchange consent screen under an environment you do not own. Allow-list the environment IDs your deployment accepts.
  • Balances carry no account identifier. The result reports account names and amounts only, so the callback URL holds nothing that addresses a specific exchange account. Custom-scheme callbacks can land in operating system navigation logs.
  • Verification attempts are capped. Three rejected codes end the flow with mfa_attempts_exhausted instead of letting the exchange lock the account out.

Common pitfalls

  • transferId is not a transaction hash. Do not paste it into a block explorer. Poll the exchange or the destination address for settlement.
  • The exchange owns the network choice. A wrong network slug can land funds on a chain your user did not expect, or be refused outright. Send the slug the exchange uses.
  • The exchange must be enabled for the environment. If the link step fails immediately, check the funding settings for that environment in the dashboard before debugging the client.
  • amount is a prefill, not a commitment. The exchange can round it, and the returned amount is the one that was accepted.
Last modified on November 2, 2026