Skip to main content
The DepositModal component handles the full deposit flow: wallet connection, source chain and token selection, amount input, and cross-chain bridging. It supports three wallet integration modes depending on how your app manages wallets.

recipient vs dappAddress

Two props look similar but serve different purposes:
  • recipient (required) — the address that receives the bridged funds on the target chain. This is a pure delivery target.
  • dappAddress (embedded wallet & QR modes) — the address that owns the deposit. The modal uses it to derive the smart account and, by default, as the delivery target. It is the user’s identity in the flow, not a destination.
In external wallet mode, the connected wallet is the owner, so only recipient is needed. In embedded and QR modes, you must pass dappAddress because the modal has no other way to know who owns the deposit.

Integration modes

External wallet

The user connects their own wallet via Reown (WalletConnect). The modal manages the wallet connection UI internally. Use this when your app doesn’t have existing wallet infrastructure. Pass a reownAppId to enable external wallet connection.
import { DepositModal } from "@rhinestone/deposit-modal";
import "@rhinestone/deposit-modal/styles.css";

<DepositModal
  isOpen={isOpen}
  onClose={() => setIsOpen(false)}
  targetChain={8453}
  targetToken="0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
  recipient="0xYOUR_RECIPIENT_ADDRESS"
  reownAppId="YOUR_REOWN_PROJECT_ID"
  onDepositComplete={(data) => console.log(data)}
/>

Embedded wallet

Your app manages the wallet (e.g. via Privy, Dynamic, or Turnkey) and passes the owner address to the modal. The modal skips its own wallet connection UI and uses your app’s wallet context. Pass dappAddress with the wallet owner address, and onRequestConnect to trigger your app’s login flow when the modal needs a connected wallet.
import { DepositModal } from "@rhinestone/deposit-modal";
import "@rhinestone/deposit-modal/styles.css";

<DepositModal
  isOpen={isOpen}
  onClose={() => setIsOpen(false)}
  targetChain={8453}
  targetToken="0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
  recipient="0xYOUR_RECIPIENT_ADDRESS"
  dappAddress={embeddedWalletAddress}
  onRequestConnect={() => login()}
  onDepositComplete={(data) => console.log(data)}
/>

QR code deposit

The modal displays a deposit address and QR code. The user sends funds from any wallet externally — no wallet connection is required inside the modal. Pass dappAddress without onRequestConnect or reownAppId.
import { DepositModal } from "@rhinestone/deposit-modal";
import "@rhinestone/deposit-modal/styles.css";

<DepositModal
  isOpen={isOpen}
  onClose={() => setIsOpen(false)}
  targetChain={8453}
  targetToken="0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
  recipient="0xYOUR_RECIPIENT_ADDRESS"
  dappAddress={ownerAddress}
  onDepositComplete={(data) => console.log(data)}
/>

Transfer configuration

Control the deposit destination and optionally pre-fill source parameters.
PropTypeRequiredDescription
targetChainChain | numberYesDestination chain (viem Chain object or chain ID)
targetTokenAddressYesToken address on the destination chain
recipientAddressYesWhere funds are delivered on the target chain
defaultAmountstringNoPre-filled deposit amount
sourceChainChain | numberNoPre-selected source chain
sourceTokenAddressNoPre-selected source token
allowedRoutesRouteConfigNoRestrict available source chains and tokens
The allowedRoutes prop accepts { sourceChains?: number[], sourceTokens?: string[] } to limit what the user can select. For supported chains and tokens, see supported chains.

Session configuration

Sessions allow the widget to execute bridging on behalf of the user’s smart account. These props control session behavior.
PropTypeDefaultDescription
sessionChainIdsnumber[]All supported chainsRestrict which chains get session keys
forceRegisterbooleanfalseForce session re-creation even if the account is already registered
waitForFinalTxbooleantrueWait for destination chain confirmation before firing onDepositComplete. When false, resolves after the bridge is submitted.

Post-bridge actions

Execute actions on the destination chain after bridging completes. Use this for automated swaps into vault tokens or other DeFi positions.
<DepositModal
  // ...required props
  postBridgeActions={[
    {
      type: "orderbook-swap",
      contract: "0xSWAP_CONTRACT_ADDRESS",
      outputToken: "0xVAULT_TOKEN_ADDRESS",
    },
  ]}
/>
The flow becomes: deposit on source chain → bridge to target chain → swap into the output token → deliver to the recipient.

Display modes

By default, the component renders as a centered modal overlay with a backdrop. Set inline={true} to render it without the overlay, fitting into your page layout.
<DepositModal
  isOpen={true}
  onClose={() => {}}
  inline={true}
  // ...other props
/>
Set closeOnOverlayClick={false} to prevent the modal from closing when the user clicks outside it.

Props reference

Required

PropTypeDescription
isOpenbooleanControls modal visibility
onClose() => voidCalled when the user closes the modal
targetChainChain | numberDestination chain (viem Chain object or chain ID)
targetTokenAddressToken address on the destination chain
recipientAddressWhere funds are delivered on the target chain

Wallet

PropTypeDefaultDescription
reownAppIdstringReown project ID. Enables external wallet connection.
dappAddressAddressOwner address for embedded wallet or QR code flows
dappWalletClientWalletClientHost-provided viem wallet client for signing
dappPublicClientPublicClientHost-provided viem public client
onRequestConnect() => voidCalled when the modal needs the user to connect a wallet
connectButtonLabelstringCustom label for the connect button

Transfer

PropTypeDefaultDescription
defaultAmountstringPre-filled deposit amount
sourceChainChain | numberPre-selected source chain
sourceTokenAddressPre-selected source token
allowedRoutesRouteConfig{ sourceChains?, sourceTokens? } to restrict selection
postBridgeActionsPostBridgeAction[]Actions to execute after bridging

Session

PropTypeDefaultDescription
sessionChainIdsnumber[]All supportedChain IDs for session key creation
forceRegisterbooleanfalseForce session re-creation
waitForFinalTxbooleantrueWait for destination chain confirmation
signerAddressAddressDefault signerSession signer address
rhinestoneApiKeystringAPI key for account setup

Backend

PropTypeDefaultDescription
backendUrlstringRhinestone production URLURL of your deposit-widget-backend instance

Display

PropTypeDefaultDescription
inlinebooleanfalseRender without modal overlay
closeOnOverlayClickbooleantrueClose modal on backdrop click
classNamestringCSS class for the modal container
themeDepositModalThemeTheme configuration
brandingDepositModalBrandingBranding configuration
uiConfigDepositModalUIConfigUI configuration
debugbooleanfalseEnable debug logging

Callbacks

PropTypeDescription
onReady() => voidModal initialized
onConnected(data: ConnectedEventData) => voidSmart account created
onDepositSubmitted(data: DepositSubmittedEventData) => voidDeposit transaction submitted on source chain
onDepositComplete(data: DepositCompleteEventData) => voidTokens arrived on target chain
onDepositFailed(data: DepositFailedEventData) => voidBridge or transfer failed
onError(data: ErrorEventData) => voidError at any stage
onEvent(event: DepositEvent) => voidAnalytics event
See status tracking for callback payload types and the deposit lifecycle.

Solana

PropTypeDefaultDescription
enableSolanabooleantrueEnable Solana wallet support and QR flows
solanaRpcUrlstringSolana mainnetCustom Solana RPC endpoint