> ## 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.

# Connections

> A hosted, connect-only wallet page you deploy on your own domain and hand off to by redirect — it reads a wallet address, never a signature.

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

Connections is a hosted wallet-connect page built on the Dynamic SDK. Instead of building a wallet picker yourself, you deploy this page on your own domain and send users to it — as a browser link, an iframe, or a native web view. When a user picks or pastes a wallet, Connections redirects back to a URL you control with the wallet's public address.

It supports **external wallets** (e.g. MetaMask, Phantom) across 600+ EVM and Solana wallets, plus manual address entry.

<Note>
  **Connect-only.** Connections never requests a signature or a transaction — it reads only the user's public wallet address and hands it back to you. This proves the user can present an address, not that they control it. For proof of ownership, add your own sign-in step after the connection.
</Note>

## When to use Connections

Reach for Connections when you want a wallet address 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 and Android, a **headless** mode runs the wallet list and connection logic behind a hidden web view, so your app links no wallet SDK at all.

If you're already building with the React, React Native, or JavaScript SDK and want full wallet state (balances, signing, embedded wallets), use the SDK directly instead. See [Wallets](/docs/overview/wallets/overview).

## How it works

Every platform follows the same contract:

<Steps>
  <Step title="Open the connect page">
    Open Connections with a `redirect_uri` you control, and an optional `nonce`.

    ```text theme={"system"}
    https://your-connect-page.example/
      ?redirect_uri=https://your-app.com/wallet/callback
      &nonce=a1b2c3d4e5
    ```

    | 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.                                                                  |
  </Step>

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

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

    ```text theme={"system"}
    https://your-app.com/wallet/callback
      ?address=0x1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b
      &chain=evm
      &walletName=MetaMask
      &walletImage=https://.../metamask.svg
      &nonce=a1b2c3d4e5
    ```

    | Parameter     | Description                                                                         |
    | :------------ | :---------------------------------------------------------------------------------- |
    | `address`     | The connected wallet's public address.                                              |
    | `chain`       | The chain family the address belongs to: `evm` or `solana`.                         |
    | `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 to see the full integration:

<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" icon="apple" href="/docs/connections/ios">
    Present it in `ASWebAuthenticationSession`, or go headless.
  </Card>

  <Card title="Android" icon="android" href="/docs/connections/android">
    Present it in a Chrome Custom Tab, or go headless.
  </Card>

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

  <Card title="Flutter" icon="flutter" href="/docs/connections/flutter">
    Present it with `flutter_web_auth_2`, or go headless.
  </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 Connections to untrusted callers.

<Warning>
  Set `VITE_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>

```bash .env theme={"system"}
VITE_ALLOWED_REDIRECT_HOSTS=app.example.com,checkout.example.com
```

* **Exact hostname match.** `example.com` does not match `sub.example.com`. Port is ignored.
* **Rebuild to apply.** Vite inlines `VITE_*` 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 `VITE_REDIRECT_BASE_URL` and logs a warning — so if your callback never fires, check the browser console first.

## Deploying Connections

Connections ships as an open-source app, [`dynamic-labs-oss/iframe-fb`](https://github.com/dynamic-labs-oss/iframe-fb). To run your own instance:

<Steps>
  <Step title="Set your environment ID">
    Copy `.env.example` to `.env` and set your [Dynamic environment ID](https://app.dynamic.xyz/dashboard/developer/api) in `VITE_DYNAMIC_ENVIRONMENT_ID`.
  </Step>

  <Step title="Enable chains and origins">
    In the Dynamic dashboard, enable the **EVM** and **Solana** chains, and add your domain to **Allowed Origins**.
  </Step>

  <Step title="Serve over HTTPS">
    Connections mints WalletConnect URIs via WebCrypto, which needs a secure context. Serve the page over HTTPS in production.
  </Step>
</Steps>
