This is an enterprise-only feature. Please contact us to enable.
ASWebAuthenticationSession on iOS.
You have two options:
- Basic — present the hosted page and read the result. One Dart file to copy.
- Headless — render your own native wallet list, driven by a hidden
WebViewWidget. Your app links no wallet SDK.
Basic
The integration isfireblocks_connect.dart.
1. Add dependencies
pubspec.yaml
2. Register your URL scheme
For iOS, add toios/Runner/Info.plist.
Info.plist
<activity> in AndroidManifest.xml.
AndroidManifest.xml
3. Connect and use the result
connect_button.dart
walletImage is usually an SVG-sprite URL — render it in a WebViewWidget rather than Image.network.
Headless
Render your own native list and drive a hiddenWebViewWidget that runs the Dynamic SDK and returns results — including message and transaction signatures — over a JS bridge.
No SDK in your app. Your app links no wallet SDK — no CocoaPods, no native crypto, no Gradle dep. It needs a hidden
WebViewWidget pointed at headless.html and your URL scheme. All the WalletConnect / MetaMask / Phantom logic — and the wallet list itself — comes from that hosted view.fireblocks_headless_connect.dart.
1. Add dependencies
pubspec.yaml
2. Register URL schemes
You need two hosts under your scheme — one for the visible flow callback (wallet-callback) and one for Phantom’s redirect (phantom-headless) — plus LSApplicationQueriesSchemes on iOS for the wallet schemes you open.
3. Mount the engine and connect
Wrap your home screen withFireblocksEngineHost — it keeps the hidden WebViewWidget alive at all times. Prewarm at launch and connect on tap.
main.dart
example_screen.dart
MaterialApp.onGenerateRoute (or your router’s redirect hook) with FireblocksHeadlessConnect.shared.handleReturnUrl(uri).
4. Sign a message and transaction
After a successful connect, callsign() with any string, or signTransaction() with a serialized transaction (signing only — no broadcast).
example_screen.dart
to is required) and receive an RLP-encoded hex string. For Solana, pass a base64-encoded serialized VersionedTransaction and receive base64-encoded signed bytes. Signing is only available for wallets connected through the headless engine.
5. Disconnect
ClearslocalStorage in the hidden WebView and reloads the engine so stale SDK state doesn’t bleed into the next connect.
example_screen.dart
Common pitfalls
- Match the channel name exactly. Flutter bridges over
addJavaScriptChannel('walletNative', …). A mismatch is invisible — the channel just never receives anything. - Test on a physical device. Wallets don’t run in the Simulator or a bare emulator.
- Serve over HTTPS. The flow mints WalletConnect URIs via WebCrypto, which needs a secure context.