Skip to main content
This is an enterprise-only feature. Please contact us to enable.
On Android the Connections contract is the same as every other platform. The result comes back on a custom URL scheme, caught by a small return activity. You have two options:
  • Basic — present the hosted page in a Chrome Custom Tab. One Kotlin file to copy.
  • Headless — render your own native wallet list, driven by a hidden WebView. Your app links no wallet SDK.
The basic flow is the recommended default. Use headless only when you need a fully native front end.

Basic

The integration is one Kotlin file, FireblocksConnect.kt — the Android analog of iOS’s FireblocksConnectFlow. It includes FireblocksRedirectActivity, the activity that catches the return.
Present with a Chrome Custom Tab — Android’s secure, sandboxed in-app browser, the analog of iOS’s ASWebAuthenticationSession. The page returns to <scheme>://wallet-callback, caught by FireblocksRedirectActivity.

1. Add the dependency and return activity

Add Chrome Custom Tabs to your Gradle build.
build.gradle.kts
Register FireblocksRedirectActivity in AndroidManifest.xml (replace myapp with your scheme) so the OS routes the return to your app. singleTask lets the return dismiss the Custom Tab.
AndroidManifest.xml

2. Present the flow

Call FireblocksConnect.present. It appends redirect_uri, a random nonce, and embedded=1, verifies the returned nonce, and parses the result into WalletConnection.
MainActivity.kt
WalletConnection carries address, chain (evm or solana), walletName, and walletImage. Render walletImage in a WebView <img> — it’s an SVG sprite that ImageView can’t draw.

Headless

Render your own native list with no visible web. FireblocksHeadlessConnect runs the connect logic in a hidden WebView and talks to it over a bridge — the same architecture as iOS.
No SDK in your app. Your app links no wallet SDK. It needs a hidden WebView pointed at the hosted engine page (https://your-connect-page.example/headless.html, set as ENGINE_URL in FireblocksHeadlessConnect) and your URL scheme. All the WalletConnect / MetaMask / Phantom logic — and the wallet list — comes from that hosted view.
Copy FireblocksHeadlessConnect.kt in addition to FireblocksConnect.kt (the visible fallback).

1. Get the wallet menu

The engine derives the list live from the Dynamic catalog and pushes it over the bridge (a wallets message) — set FireblocksHeadlessConnect.onWallets. Each entry carries key, name, icon, chains (evm / solana), mode (headless | fallback), and featured.

2. Drop in FireblocksHeadlessConnect

It owns a hidden WebView, bridges to it (addJavascriptInterface + evaluateJavascript), opens the wallet deeplink it returns, and calls you back. Pre-warm it at launch.
MainActivity.kt
Auto-fallback is built in: wallets that can’t go headless (Base Account passkey, and similar) return FallbackRequired, and you open the visible FireblocksConnect for that same wallet.

3. Sign a message and transaction

After a successful connect, call sign() with any string, or signTransaction() with a serialized transaction (signing only — no broadcast).
MainActivity.kt
For EVM, pass a JSON transaction 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.

4. Wire the manifest and redirect

Headless needs two manifest additions beyond the basic flow: a phantom-headless host on the same FireblocksRedirectActivity intent-filter, and a <queries> block so the app can open wallet deeplinks on Android 11+.
AndroidManifest.xml
Route the return activity to the engine first (for Phantom’s redirect), then fall through to the visible flow.
FireblocksRedirectActivity

Common pitfalls

  • Don’t call webView.onPause() on the hidden WebView. That suspends its relay socket. It stays alive for a normal app-switch; for long approvals a foreground service is the robust option.
  • Cancellation isn’t auto-detected by Custom Tabs. Treat “resumed with no result” as cancelled, or hold the pending flow in a ViewModel.
  • Test on a device with a wallet installed — not a bare emulator.
  • Serve over HTTPS. The flow mints WalletConnect URIs via WebCrypto, which needs a secure context.
Last modified on August 7, 2026