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

# Widget configuration

> Configure deposit destinations, funding methods, routing, display, and shared widget props.

`DepositModal` handles funding method selection, source chain and token selection, amount input, and cross-chain routing. Complete the [widget quickstart](/deposits/overview/widget/quickstart) and [backend setup](/deposits/overview/widget/backend-setup) before configuring optional behavior.

## Destination

`recipient` is the address that receives funds on the target chain. The service-managed deposit account is derived from `(recipient, targetChain, targetToken)`, so it does not depend on the payment wallet. Changing the target changes the deposit address.

For a checkout, pass [an order-specific account salt](#checkout-payments) instead. Each order then has its own deposit address.

| Prop               | Type                                              | Required | Description                                                                                                                                   |
| ------------------ | ------------------------------------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| `targetChain`      | `Chain \| number \| "solana" \| "hypercore:spot"` | Yes      | Destination chain as a viem `Chain`, chain ID, or non-EVM identifier                                                                          |
| `targetToken`      | `Address \| string`                               | Yes      | Token on the destination chain; use a base58 mint for Solana                                                                                  |
| `recipient`        | `Address \| string`                               | Yes      | Address receiving funds; use a base58 address for Solana                                                                                      |
| `defaultAmount`    | `string`                                          | No       | Pre-filled USD amount, or `"max"` for the full available balance                                                                              |
| `payment`          | `PaymentConfig`                                   | —        | Checkout for one order: `{ salt: Hex, amount: string }`. Amount is destination token base units; salt is the order's registered account salt. |
| `sourceChain`      | `Chain \| number`                                 | No       | Pre-selected source chain                                                                                                                     |
| `sourceToken`      | `Address`                                         | No       | Pre-selected source token                                                                                                                     |
| `outputTokenRules` | `OutputTokenRule[]`                               | No       | Route deposits to different final tokens based on the source deposit                                                                          |
| `rejectUnmapped`   | `boolean`                                         | No       | Reject an unmatched routing input instead of using `targetToken`                                                                              |
| `appBalanceUsd`    | `number`                                          | No       | Current in-app USD balance; shows the balance after deposit                                                                                   |

For supported destinations and assets, see [supported chains and tokens](/deposits/overview/resources/supported-chains-and-tokens).

## Checkout payments

Register a managed account for each order on your server with a unique 32-byte salt. Store the returned `evmDepositAddress` with the order, then pass the same salt and the required destination amount to the modal:

```tsx theme={null}
<DepositModal
  // ...required props, including the order's target and recipient
  payment={{ salt: order.salt, amount: order.amountBaseUnits }}
/>
```

`payment.amount` is an integer string in **destination token base units**. It is not a USD amount. The salt replaces the modal's normal `(recipient, targetChain, targetToken)` account derivation, so it must match the salt used in [managed account registration](/deposits/headless/setup/account-registration#register-an-account). The modal displays a fixed order amount and withholds the recipient's deposit history from the payer.

On the EVM wallet path, the modal asks `POST /quotes/preview` for an `exactOut` quote and uses its `input.amount` as the source amount to send. The proxy must forward that route to a processor that supports `exactOut`; an older processor cannot price the checkout. The quote is indicative, and a QR, exchange, or card payer can send a different amount.

Reconcile deposits against the order's account using [processor webhooks](/deposits/headless/processing-and-tracking/webhooks) or `GET /deposits?account=<orderAccount>`. Compare the delivered destination amount with the order amount before marking it paid. The modal's `complete` lifecycle event also carries `destinationAmount` in destination token base units when available.

## Account setup

The widget uses service-managed accounts. Rhinestone owns the deposit account and settles to your `recipient`, so there is no session key to configure and the user is not asked to sign during setup.

| Prop            | Type      | Default | Description                                                                  |
| --------------- | --------- | ------- | ---------------------------------------------------------------------------- |
| `forceRegister` | `boolean` | `false` | Re-register even when the account is cached. Registration remains idempotent |

### Restrict accepted sources

Your project's deposit whitelist controls the chains and tokens the processor accepts. Configure it through project setup rather than filtering the widget's source picker.

<Warning>
  A client-side filter can drift from the processor configuration and offer a source the processor rejects. The project whitelist is the enforced source of truth.
</Warning>

## Funding methods

Each enabled method appears on the widget home screen. When exactly one is enabled, the widget skips the chooser and opens that flow directly.

| Prop                    | Type                          | Default  | Guide                                                                                  |
| ----------------------- | ----------------------------- | -------- | -------------------------------------------------------------------------------------- |
| `enableWallet`          | `boolean`                     | `true`   | [Deposit from a wallet](/deposits/crypto/deposit-from-a-wallet)                        |
| `enableQrTransfer`      | `boolean`                     | `true`   | [Deposit addresses and QR codes](/deposits/crypto/deposit-addresses-and-qr-codes)      |
| `enableFiatOnramp`      | `boolean`                     | `false`  | [Accept fiat payments](/deposits/onramps/accept-fiat-payments)                         |
| `fiatMethods`           | `FiatMethodsConfig`           | Regional | [Payment methods and availability](/deposits/onramps/payment-methods-and-availability) |
| `enableExchangeConnect` | `boolean`                     | `false`  | [Connect an exchange](/deposits/exchanges/connect-an-exchange)                         |
| `assetMigrations`       | `AssetMigrationsConfig`       | None     | [Asset migrations](/deposits/crypto/asset-migrations)                                  |
| `initialAssetMigration` | `keyof AssetMigrationsConfig` | —        | Open directly into an enabled migration provider                                       |

Fiat onramps and exchange connect require Swapped routes and credentials on your [backend proxy](/deposits/overview/widget/backend-setup).

## Output token routing

Pass `outputTokenRules` to choose the final token based on the source deposit. Rules can match chain, token address, or symbol. Unmatched deposits use `targetToken` unless `rejectUnmapped` is `true`.

```tsx theme={null}
<DepositModal
  // ...required props
  targetToken="0xFALLBACK_TOKEN_ADDRESS"
  outputTokenRules={[
    {
      match: { symbol: "USDC" },
      outputToken: "0x7f5c764cbc14f9669b88837ca1490cca17c31607",
    },
    {
      match: { symbol: "ETH" },
      outputToken: "0x4200000000000000000000000000000000000006",
    },
  ]}
/>
```

When several rules match, the most specific wins: `chain + token`, then `chain + symbol`, `token`, `symbol`, and `chain`. See [token routing](/deposits/headless/setup/token-routing) for full semantics and examples.

## Non-EVM destinations

### Solana

Use `targetChain="solana"`, a base58 mint as `targetToken`, and a base58 `recipient`. `rpcUrls` accepts a literal `solana` key when you need to override the default connection.

### HyperCore destinations

Use `targetChain="hypercore:spot"`, exported as `HYPERCORE_SPOT_CAIP2`. HyperCore accepts USDC only. `recipient` can be an EOA or smart account: delivery calls the MulticallHandler's `depositFor(recipient)`, which funds either address type without executing on the recipient.

A HyperCore destination names the venue it credits. Spot and perp margin are separate balances; deposits support spot only because the deposit account cannot produce the signature required to move funds back out of perp margin.

<Note>
  `targetChain: 1337`, exported as `HYPERCORE_CHAIN_ID`, is the older spelling and still resolves to the same venue and deposit address. Migrating to `HYPERCORE_SPOT_CAIP2` does not move user accounts.
</Note>

<Note>
  Earlier versions pre-screened recipient bytecode and could emit `HYPERCORE_RECIPIENT_NOT_EOA`. That check did not match orchestrator behavior and was removed in v0.9.0.
</Note>

HyperCore is also available as a transfer source. The address and QR flow uses the account's EVM address as the deposit address; a native Hyperliquid L1 spot transfer lands there.

## Display modes

The widget renders as a centered overlay by default. Set `inline={true}` to place it in your page layout without a backdrop.

```tsx theme={null}
<DepositModal
  isOpen
  onClose={() => {}}
  inline
  // ...other props
/>
```

Backdrop closing is opt-in with `closeOnOverlayClick={true}`. Configure visual appearance in [theming and customization](/deposits/overview/widget/theming-and-customization).

## Package entry points

Everything is exported from the root. Subpaths let you bundle only what you use.

| Import                                 | Contains                                                                                     |
| -------------------------------------- | -------------------------------------------------------------------------------------------- |
| `@rhinestone/deposit-modal`            | Both modals, types, chain helpers, and token helpers                                         |
| `@rhinestone/deposit-modal/deposit`    | `DepositModal` and its types                                                                 |
| `@rhinestone/deposit-modal/withdraw`   | `WithdrawModal` and its types                                                                |
| `@rhinestone/deposit-modal/server`     | `createRefundHandler`; server-only because it holds your API key                             |
| `@rhinestone/deposit-modal/constants`  | `MODAL_VERSION`, chain registry, token helpers, and explorer helpers                         |
| `@rhinestone/deposit-modal/polymarket` | Headless [`getPolymarketAccount`](/deposits/crypto/asset-migrations#headless-account-lookup) |
| `@rhinestone/deposit-modal/styles.css` | Required stylesheet                                                                          |

## Props reference

### Required

| Prop          | Type                                              | Description                                                   |
| ------------- | ------------------------------------------------- | ------------------------------------------------------------- |
| `isOpen`      | `boolean`                                         | Controls widget visibility                                    |
| `onClose`     | `() => void`                                      | Called when the user closes the widget                        |
| `targetChain` | `Chain \| number \| "solana" \| "hypercore:spot"` | Destination chain                                             |
| `targetToken` | `Address \| string`                               | Destination token                                             |
| `recipient`   | `Address \| string`                               | Address receiving funds on the destination                    |
| `backendUrl`  | `string`                                          | Your [backend proxy](/deposits/overview/widget/backend-setup) |

### Wallet

| Prop               | Type                   | Default | Description                                                           |
| ------------------ | ---------------------- | ------- | --------------------------------------------------------------------- |
| `reownAppId`       | `string`               | —       | Reown project ID; lets the widget connect a wallet                    |
| `walletClient`     | `WalletClient \| null` | —       | Wallet your app already connected; the widget reads `.account`        |
| `publicClient`     | `PublicClient \| null` | —       | Read client paired with `walletClient`; defaults to the widget client |
| `enableWallet`     | `boolean`              | `true`  | Offer wallet funding                                                  |
| `onRequestConnect` | `() => void`           | —       | Called when the widget needs your app to connect a wallet             |

See [deposit from a wallet](/deposits/crypto/deposit-from-a-wallet) for widget-managed, app-supplied, and loading-state behavior.

### Transfer

| Prop               | Type                | Default | Description                                                                                                                                   |
| ------------------ | ------------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| `defaultAmount`    | `string`            | —       | Pre-filled USD amount or `"max"`                                                                                                              |
| `payment`          | `PaymentConfig`     | —       | Checkout for one order: `{ salt: Hex, amount: string }`. Amount is destination token base units; salt is the order's registered account salt. |
| `sourceChain`      | `Chain \| number`   | —       | Pre-selected source chain                                                                                                                     |
| `sourceToken`      | `Address`           | —       | Pre-selected source token                                                                                                                     |
| `appBalanceUsd`    | `number`            | —       | In-app USD balance used for the balance-after-deposit row                                                                                     |
| `outputTokenRules` | `OutputTokenRule[]` | —       | Per-deposit output token rules                                                                                                                |
| `rejectUnmapped`   | `boolean`           | `false` | Reject deposits that match no output rule                                                                                                     |

### Funding

| Prop                    | Type                          | Default  | Description                                                                     |
| ----------------------- | ----------------------------- | -------- | ------------------------------------------------------------------------------- |
| `enableWallet`          | `boolean`                     | `true`   | Offer a connected wallet as a source                                            |
| `enableQrTransfer`      | `boolean`                     | `true`   | Offer the address and QR transfer flow                                          |
| `enableFiatOnramp`      | `boolean`                     | `false`  | Offer fiat payment through Swapped                                              |
| `fiatMethods`           | `FiatMethodsConfig`           | Regional | Restrict to `{ creditcard?, "bank-transfer"?, "apple-pay"? }`; empty means none |
| `enableExchangeConnect` | `boolean`                     | `false`  | Offer Connect exchange through Swapped                                          |
| `assetMigrations`       | `AssetMigrationsConfig`       | —        | Enable supported migration providers                                            |
| `initialAssetMigration` | `keyof AssetMigrationsConfig` | —        | Open directly into an enabled migration provider                                |

### Account

| Prop            | Type      | Default | Description                                 |
| --------------- | --------- | ------- | ------------------------------------------- |
| `forceRegister` | `boolean` | `false` | Re-register even when the account is cached |

### Backend

| Prop      | Type        | Default        | Description                                                                                                      |
| --------- | ----------- | -------------- | ---------------------------------------------------------------------------------------------------------------- |
| `rpcUrls` | `RpcUrlMap` | Chain defaults | RPC overrides keyed by EVM chain ID or `solana`; applies to EVM clients, connected wallets, HyperEVM, and Solana |

### Display

| Prop                  | Type                   | Default | Description                                                                              |
| --------------------- | ---------------------- | ------- | ---------------------------------------------------------------------------------------- |
| `inline`              | `boolean`              | `false` | Render without the overlay                                                               |
| `closeOnOverlayClick` | `boolean`              | `false` | Close when the backdrop is clicked                                                       |
| `className`           | `string`               | —       | CSS class for the widget container                                                       |
| `theme`               | `DepositModalTheme`    | —       | [Theme configuration](/deposits/overview/widget/theming-and-customization#theme)         |
| `uiConfig`            | `DepositModalUIConfig` | —       | [UI configuration](/deposits/overview/widget/theming-and-customization#ui-configuration) |
| `debug`               | `boolean`              | `false` | Enable debug logging                                                                     |

### Recovery

| Prop           | Type           | Default | Description                                                                                                                        |
| -------------- | -------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| `signRecovery` | `SignRecovery` | —       | Enable signed recovery from [history](/deposits/overview/widget/history-and-recovery#signing-contract); omit for read-only history |

### Callbacks

| Prop          | Type                                                                                           | Description                                                                                                                       |
| ------------- | ---------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `onReady`     | `() => void`                                                                                   | Widget initialized                                                                                                                |
| `onLifecycle` | `(event: DepositLifecycleEvent) => void`                                                       | Deposit state transitions; see [callbacks and error handling](/deposits/overview/widget/callbacks-and-error-handling#onlifecycle) |
| `onError`     | `(data: ErrorEventData) => void`                                                               | Error at any stage                                                                                                                |
| `onEvent`     | `(event: DepositAnalyticsEvent \| ClaimAnalyticsEvent \| AnalyticsIngestFailureEvent) => void` | Funnel events and ingest diagnostics; see [analytics](/deposits/overview/widget/analytics)                                        |

### Analytics

| Prop                    | Type      | Default | Description                                                                                  |
| ----------------------- | --------- | ------- | -------------------------------------------------------------------------------------------- |
| `enableAnalyticsIngest` | `boolean` | `true`  | Send session analytics to Rhinestone. `false` disables collection without changing `onEvent` |

## Content security policy

The widget loads chain, token, and exchange logos from Rhinestone's asset CDN. Apps with an explicit `img-src` must allow it:

```text theme={null}
img-src 'self' data: https://s3.rhinestone.dev;
```

A blocked image fails silently and renders blank. Apps without an explicit `img-src`, or with `img-src *`, need no change.

Fiat onramps and Connect exchange embed Swapped in an iframe, so those flows also need:

```text theme={null}
frame-src https://widget.swapped.com https://sandbox.swapped.com https://connect.swapped.com;
```

Deposit and withdraw sessions send analytics from the browser. An explicit `connect-src` must include Rhinestone, your proxy, and every RPC override:

```text theme={null}
connect-src 'self' https://v1.orchestrator.rhinestone.dev https://your-proxy.example.com;
```

That directive controls every widget request, not only analytics. A blocked ingest origin does not interrupt deposits, but it drops analytics and reports an `analytics_ingest_failure` event with `reason: "network"`; see [analytics](/deposits/overview/widget/analytics#ingest-failures).
