DaimoWithdrawal is a pre-built React flow for sending USDC or USDT to a
recipient. It collects the recipient and destination first, asks your server to
create an open-amount session, then funds that session from an injected wallet
or a host-controlled wallet.
The component provides:
- EVM addresses, Solana addresses, and ENS recipients
- saved recipient routes scoped to the authenticated user
- supported stablecoin and destination-network selection
- wallet token/balance selection and amount entry
- session polling and started/completed lifecycle callbacks
Install and provide the client
Server callback
ENS resolution is built in. The only required backend callback iscreateSession, which runs from browser code and must call your authenticated
backend. Keep your Daimo API key on the server.
ENS resolution
DaimoWithdrawal trims and ENSIP-15-normalizes ENS names, then resolves them
through the Daimo API URL configured on DaimoSDKProvider. Resolution always
uses Ethereum mainnet, regardless of the selected destination network. Saved
ENS recipients are resolved again before reuse so session creation receives the
same concrete address the user reviewed.
Most integrations should use this zero-configuration default. If your
integration intentionally needs a different resolver, pass resolveEns:
isDaimoWithdrawalDestination, then call POST /v1/sessions with that
destination and no amountUnits. Set display.paymentOptions to
["AutoconnectInjectedWallets"] for injected-wallet funding or
["AllAddresses"] for manual funding. Return only sessionId and
clientSecret to the component.
Embedded or modal presentation
DaimoWithdrawal renders inline by default. Set embedded={false} and mount it
only while open to use the SDK’s floating modal instead of building another
drawer around the embedded component:
Injected-wallet funding
The SDK discovers a browser wallet, shows its token balances, and submits the selected EVM or Solana transaction. If your app already owns an EVM provider, pass both the connected address and that scoped provider.connectToAddress and evmProvider to let the SDK discover and connect a
wallet. The default walletSource="all" includes EVM and Solana funding;
walletSource="evm" excludes Solana-only providers.
Manual funding
Manual funding is for embedded, smart-account, custodial, or sponsored wallets whose transaction lifecycle belongs to your application. The SDK never callseth_sendTransaction or any other provider transaction method in manual mode.
It invokes sendManualTransaction and waits for your promise instead.
There are three amount variants.
Fixed amount
Pass a positive decimalamountUnits. After destination review, the SDK creates
the open-amount session and immediately invokes the adapter. Fixed amount and
connectToAddress are mutually exclusive.
Generic amount entry
Omit bothamountUnits and connectToAddress. The SDK shows a plain USD input
that accepts $0.01+ with up to two decimal places. It deliberately shows no
token artwork, balance, or Max action. Your adapter owns source network, token,
and decimal-to-raw conversion.
Address-aware token and balance selection
OmitamountUnits and pass the embedded wallet’s EVM address. The SDK uses the
address only to fetch wallet options, shows supported tokens and balances, and
always shows Max on the wallet amount page. It does not connect to the wallet.
sourceTokenFilter removes unsupported balances before the selector renders.
Use it when the host wallet supports only particular chains or token-transfer
commands; do not hide rows with CSS. The adapter must still validate source
before submitting because the predicate is a UI constraint, not authorization.
evmProvider is not accepted by any manual variant.
World Mini Apps should map every supported World Chain payment token (for
example USDC, WLD, EURC, WARS, WCOP, WMXN, WBRL, WPEN, and WCLP) to the
corresponding MiniKit
Tokens value and call MiniKit.pay. A direct ERC-20
call through sendTransaction requires that contract to be allowlisted and
otherwise fails with invalid_contract. Filter out non-World-Chain and
non-MiniKit tokens with sourceTokenFilter.Manual adapter contract
amountUnits is the exact fixed or user-entered decimal string. In the
address-aware variant, source is always present: source.address is the
address you supplied, source.token contains the selected chain, token
address, symbol, and decimals, and source.amount is the exact raw,
balance-capped token amount. In the other variants, source is omitted.
Resolve the adapter only after the transaction has been submitted or durably
handed off. Return txHash when available so polling can detect it sooner.
Reject only when repeating the same transfer is safe: the retry action invokes
the adapter again for the same session and hidden receiver. Concurrent calls
and calls after a successful adapter result are deduplicated.
Recipient and session lifecycle
The flow is recipient-first:- The user enters an EVM address, Solana address, or ENS name, or selects a saved recipient.
- The user chooses USDC or USDT and a compatible destination network.
- The SDK asks your server to create an open-amount session.
- The injected wallet or manual adapter submits funds to the hidden receiver.
- The SDK polls until the session succeeds, bounces, or expires.
onPaymentStarted once after submission and
onPaymentCompleted once when the session reaches succeeded.
Typical session progression is waiting_payment → processing → succeeded.
bounced means delivery failed and funds were returned; expired means no
transfer was detected before the session deadline. Amount choice does not alter
the session contract: all withdrawal sessions remain open-amount.