onLifecycle callback.
You switch on event.type to update your UI, trigger backend processes, or log
analytics. New event variants can be added without changing the prop surface.
These callbacks are browser UI signals, not proof of server-side settlement: they stop when the modal closes. Use webhooks on your server for work that must happen regardless, such as crediting a balance or sending a receipt.
Deposit lifecycle
- The modal initializes and fires
onReady - If the user funds from a wallet,
"connected"fires with the EOAaddressand thesmartAccountthe deposit lands on - The user selects a source chain, token, and amount, then confirms
- The modal submits the transaction on the source chain and emits
"submitted" - The bridge routes funds to the target chain. Once they arrive, the modal
emits
"complete"
"failed" is emitted instead of
"complete".
Arrival estimates
From@rhinestone/deposit-modal v0.17.0, the modal states how long a deposit is
expected to take and changes its framing when the wait runs long.
The estimate is served by the deposit service — with the quote, and again on each
read of an in-flight deposit — and is derived from recent completed deposits on the
same route, falling back to the route’s own indicative estimate. It is an
expectation, never a deadline, guarantee, or SLA. It is resolved per request, so two
reads of the same deposit can return different numbers, and it is omitted whenever no
estimate is available.
Nothing about your integration changes. The estimate rides the existing
POST /quotes/preview and GET /deposits routes your
proxy already forwards — there is no new
prop, proxy route, or host configuration.
While the deposit is processing
The pending screen shows one of three treatments, each replacing the previous one in place rather than accompanying it:
Crossing a threshold drops the expectation instead of restating an estimate the
deposit has already exceeded. The treatments only advance — a phase change or a late
quote never walks the framing back. The estimate itself is latched for the widget
session the first time it is seen, so a quote that resolves late can supply the
numbers for the first time but can never change numbers the user has already been
shown.
Before submission
The review and QR screens state the expected duration end to end rather than the bridging leg alone, using the served estimate and falling back to the route’s fill time when none was served. Sub-minute estimates read in seconds (~7 seconds)
instead of collapsing to “less than a minute”.
In deposit history
An in-flight row in the history panel carries the same three treatments, computed from the deposit’s creation time against the served thresholds. History reads them fromGET /deposits rather than from the
current session, so the expectation survives a reload and is the same on another
device or for a deposit started elsewhere.
When no estimate is served
Estimates are optional and route-dependent, and a read that cannot resolve one simply omits it. In that case the modal shows no expectation and no delay framing, and behaves exactly as it did before v0.17.0. The withdraw modal’s pending screen is served no estimate at all, so it is unchanged. See tracking a deposit through the API for the field on the deposit read, and theGET /deposits reference
for its schema.
onLifecycle
onLifecycle receives a discriminated union — DepositLifecycleEvent on
<DepositModal>, WithdrawLifecycleEvent on <WithdrawModal>. The two are
similar but not identical; see withdraw events for the
differences.
Deposit events
amount is in the source token’s base units — divide by sourceDecimals to display
it. sourceDecimals is omitted when the token isn’t recognised, which happens for a
QR deposit of an unlisted token.
destinationAmount, when present, is the amount delivered in the destination token’s base units. Use it to reconcile a checkout payment; amount is the source amount sent.
amountUsd is the USD value as entered in the modal. It is omitted for flows with no
amount input: QR transfer, fiat on-ramp, and exchange connect.
Withdraw events
WithdrawLifecycleEvent carries the same type values minus "balance-changed"
and "smart-account-changed". Its txHash is Hex, sourceChain is always a
number, sourceToken / targetToken are Address, and "submitted" adds an
accountAddress: Address field. "connected" means the deposit account for the
chosen target is registered and fundable, not that a wallet connected.
onReady
Fires once when the modal is initialized and ready for interaction. No payload.onError
Fires on errors at any stage — wallet connection, transaction signing, bridge setup — that prevent the deposit from being submitted. Distinct from the"failed" lifecycle event, which covers failures after the source transaction
confirms.
Codes
PROCESS_TIMEOUT fires at most once per deposit. From v0.17.0 it fires at the served
escalated threshold, five to ten minutes in practice, and keeps its previous fixed
ten-minute threshold when no estimate is served. It does not fire for same-route
transfers, and the withdraw modal keeps the fixed threshold.
Errors without a code carry only message. For bridge-level codes, see deposit processing error codes.
Error handling
After the source chain transaction confirms, the deposit service may
retry automatically before the
"failed" event fires.