Skip to main content
The WithdrawModal component handles outbound transfers. The user selects a destination chain and token, enters a recipient and an amount, and the modal registers the account that routes the funds — then asks your app to perform one transfer. The modal never holds a key and never moves funds itself, so it works with any account model: an EOA, a smart account, an embedded or in-app wallet, or a relayer.

Basic usage

accountAddress is the account holding the funds. The modal reads its balance and stops the user sending to themselves; it never transacts from it.

Executing the transfer

onSendTransaction is required. The modal calls it once, when the user confirms on the review screen, with everything needed for a single transfer:
Two rules, both silent-failure modes if missed:
Send to to, and nothing else. It is the Rhinestone account that receives the funds and bridges them on to the recipient — except on a same-route withdrawal (source chain and token identical to the target), where the modal skips the bridge and to is the recipient directly. Substituting an address of your own either bypasses the bridge or strands the funds.Return the on-chain transaction hash. Progress is tracked by looking the deposit up by that hash. An ERC-4337 wallet must await the receipt and return the bundled transaction hash, not the userOp hash — returning the wrong one leaves the modal waiting on a withdrawal that already succeeded.
Reject the promise to surface a failure in the modal. The user can retry from the review screen.

If your funds are in a Safe

A 1/1 Safe signs with personal_sign over the SafeTx hash, relayed by whoever pays the gas. Build the EIP-712 SafeTx, sign it, and submit execTransaction:
Safe’s eth_sign path requires adding 4 to the v value of a personal_sign signature. This adjustment is specific to Safe’s signature verification — see the Safe docs for details.
To keep gas sponsored, relay the signed transaction through POST /safe/withdraw on your proxy rather than submitting execTransaction from the user’s wallet. Note that a relayed transaction cannot use Safe’s pre-validated (v = 1) signature shortcut: that only validates when msg.sender is the owner, and for a relayed call the sender is the relayer.

Props reference

Required

Transfer

targetChain and targetToken are optional — they seed the form, and the user can pick any supported destination. Omit them to open on a same-chain, same-token withdrawal.

Account

Backend

Display

Callbacks

Withdraw sessions send analytics to Rhinestone from the browser too, so the same content security policy applies. WithdrawLifecycleEvent has no balance-changed or smart-account-changed variants, and its payload types differ from the deposit union: txHash is Hex, sourceChain is always a number, sourceToken / targetToken are Address, and "submitted" carries an accountAddress.

Analytics