> ## Documentation Index
> Fetch the complete documentation index at: https://www.dynamic.xyz/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Hosted wallet connections

> Send users to a connect page for a wallet address, or run it headless on native platforms to also sign messages and transactions.

<Note>
  This is an enterprise-only feature. Please [contact us](https://www.dynamic.xyz/book-a-call) to enable.
</Note>

This is the hosted form factor of [Fireblocks Flow](/docs/flow/overview)'s wallet connector, built on the Dynamic SDK. Instead of building a wallet picker yourself, you send users to a connect page with a catalog of 800+ **external wallets** (for example MetaMask or Phantom), plus manual address entry.

For the choice between this and [native](/docs/external-wallets/native) connection, see [Connections](/docs/flow/connections).

<Tip>
  Dynamic hosts a ready-to-use instance at `https://connect.dynamicauth.com/`. Deploying your own instance on a custom domain is also supported, and is arranged as part of enabling the feature. See the [live demo](https://connections.dynamic.dev/).
</Tip>

## Redirect or headless

<CardGroup cols={2}>
  <Card title="Redirect (basic)" icon="arrow-right">
    Open the connect page with a `redirect_uri`. The user connects a wallet (or pastes an address) and it redirects back with the public address. Address-only: no signature or transaction.
  </Card>

  <Card title="Headless" icon="code">
    iOS, Android, and Flutter. Render your own native wallet list backed by a hidden web view running the Dynamic SDK. After connecting, you can also sign messages and transactions over the same bridge. Your app links no wallet SDK.
  </Card>
</CardGroup>

<Info>
  Already building with the React, React Native, or JavaScript SDK? Use the SDK directly for full wallet state (balances, embedded wallets, signing APIs). See [Wallets](/docs/embedded-wallets/overview).
</Info>

## When to use this

Reach for it when you want a wallet address (and optionally signing) without adding the Dynamic SDK to every client:

* **You want a hosted picker.** Link out to one page instead of building and maintaining a wallet list per platform.
* **You can't add a third-party SDK.** On iOS, Android, and Flutter, **headless** mode runs the wallet list and connection logic behind a hidden web view, so your app links no wallet SDK. After connect, you can also sign messages and transactions through that same bridge.

## How it works

Every platform follows the same redirect contract for the basic flow:

<Steps>
  <Step title="Open the connect page">
    Open it with a `redirect_uri` you control, and an optional `nonce`. The platform guides under **Implement** show the URL assembly for each platform.

    | Parameter       | Required | Description                                                                                                                                                                                                                                            |
    | --------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
    | `redirect_uri`  | Yes      | Where to send the user back after they connect. Either an `http(s)` URL you control, or your app's custom scheme (e.g. `myapp://wallet-callback`) for native integrations. Alias: `redirect_url`.                                                      |
    | `nonce`         | No       | An opaque value echoed back unchanged so you can correlate the response to the request. If you don't send one, none is returned.                                                                                                                       |
    | `environmentId` | No       | Dynamic environment ID to use instead of the page's build-time default. Must be a UUID. Invalid values are ignored with a console warning, and the page falls back to its build-time default. For headless, set this before `prewarm()` / `connect()`. |
  </Step>

  <Step title="The user connects">
    The user searches Dynamic's catalog of 800+ wallets, or pastes an address manually.
  </Step>

  <Step title="Read the result on your redirect">
    It redirects back to your `redirect_uri` with the result appended as query parameters:

    | Parameter     | Description                                                                         |
    | ------------- | ----------------------------------------------------------------------------------- |
    | `address`     | The connected wallet's public address.                                              |
    | `chain`       | The chain family the address belongs to: `evm`, `solana`, or `bitcoin`.             |
    | `walletName`  | Display name of the wallet (e.g. `MetaMask`). Empty for a manually-entered address. |
    | `walletImage` | Icon URL for the wallet. Empty for a manually-entered address.                      |
    | `nonce`       | The exact nonce you passed in, present only if you sent one.                        |
  </Step>
</Steps>

Pick your platform for the full integration guide (including copy-paste harness sources):

<CardGroup cols={2}>
  <Card title="Web" icon="globe" href="/docs/connections/web">
    Link to the hosted page and read the result on your redirect.
  </Card>

  <Card title="iOS (basic)" icon="apple" href="/docs/connections/ios">
    Present it in `ASWebAuthenticationSession`.
  </Card>

  <Card title="iOS (headless)" icon="apple" href="/docs/connections/ios-headless">
    Native list via a hidden web view. Connect and sign over the bridge.
  </Card>

  <Card title="Android (basic)" icon="android" href="/docs/connections/android">
    Present it in a Chrome Custom Tab.
  </Card>

  <Card title="Android (headless)" icon="android" href="/docs/connections/android-headless">
    Native list via a hidden WebView. Connect and sign over the bridge.
  </Card>

  <Card title="React Native" icon="react" href="/docs/connections/react-native">
    Present it with `expo-web-browser`.
  </Card>

  <Card title="Flutter (basic)" icon="flutter" href="/docs/connections/flutter">
    Present it with `flutter_web_auth_2`.
  </Card>

  <Card title="Flutter (headless)" icon="flutter" href="/docs/connections/flutter-headless">
    Native list + message signing and EVM, Solana, and Bitcoin sends, plus Bitcoin PSBT signing, via a hidden WebViewWidget.
  </Card>
</CardGroup>

## Securing the redirect

`redirect_uri` is caller-supplied, so an `http(s)` target is an open-redirect surface. Lock it down before exposing this to untrusted callers.

<Warning>
  Set `NEXT_PUBLIC_CONNECT_ALLOWED_REDIRECT_HOSTS` to the `http(s)` hosts you accept: bare hostnames, comma-separated, no scheme, no path, no wildcards. Left unset, any host is accepted (with a console warning) so existing integrations keep working.
</Warning>

* **Exact hostname match.** `example.com` does not match `sub.example.com`. Port is ignored.
* **Rebuild to apply.** Next.js inlines `NEXT_PUBLIC_*` variables at build time, so changing this needs a rebuild and redeploy. Setting it in a hosting dashboard alone does nothing.
* **Custom app schemes are never host-filtered.** Their "host" is a callback name interpreted by your native app, not a network address.

A handful of schemes that can hand off to another app or a browser-internal page are always refused, even in permissive mode: `javascript:`, `data:`, `intent:`, `android-app:`, `market:`, `content:`, `chrome:`, `ftp:`, and similar. A refused value falls back to the same-origin `/callback` page and logs a warning. If your callback never fires, check the browser console first.
