Skip to main content
The onEvent callback delivers modal funnel events and analytics delivery diagnostics. Funnel events use DepositAnalyticsEvent, WithdrawAnalyticsEvent, or ClaimAnalyticsEvent; diagnostics use AnalyticsIngestFailureEvent. onEvent is browser UI telemetry, not server-side settlement confirmation. It stops when the modal closes; use webhooks on your server for settlement work that must run regardless.
All three funnels use the same event taxonomy where it applies: open, step open and complete, friction, failure, retry, handoff, UI outcome, abandonment, and close. Each modal also has events and fields specific to its flow. Every position-bearing event uses step. Abandonment carries the latest reached step. Close carries that step, or step: null only when the session closes before entering the funnel. A UI outcome reports what the widget observed, not backend or on-chain fulfillment truth.

The session envelope

Every funnel event carries these fields in addition to its event-specific payload: Deposit funnel events also carry top-level funding_method, which is null before method selection. AnalyticsIngestFailureEvent is a delivery diagnostic, not a funnel event, so it has no session_properties. Session properties stay fixed for the session even if props change while the modal is open.

Deposit session properties

The target is the configured deposit destination.

Withdraw session properties

The target is the destination on which the form opened, including the source-chain and source-token fallback when no target was supplied. The prefill flags separately record whether your app supplied each value.

Claim session properties

overlay_close_enabled reports the effective configuration. Backdrop closing is opt-in because closeOnOverlayClick defaults to false.

Target identities

target_chain uses CAIP-2: eip155:<id>, solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp, or hypercore:spot. target_token is the on-chain token identity. EVM addresses and HyperCore hex token IDs are normalized to lowercase, Solana mints preserve case, and the literal native is allowed. Invalid chain and token values are omitted independently, so one invalid value does not remove the other or invalidate the session.

Friction, failure, and retry

  • Friction means progress is blocked without an attempted operation failing. Its payload carries step and reason.
  • Failure means an attempted operation failed or the flow reached a terminal condition. Its payload carries step, reason, and retryable.
  • Retry is a subsequent explicit attempt after a reported reason. Its payload carries step and reason.
retryable means the widget judged another attempt safe or offered that affordance. It appears only on failure events. Reasons used by friction, failure, and retry form bounded vocabularies. Each starts with one declared AnalyticsReasonFamily: account_setup, amount, exchange, lookup, migration, modal, processor, provider, quote, recipient, recovery, refund, regional_methods, registration, route, signature, submission, swapped, transfer, or wallet. Route reasons by matching this declared list longest-prefix first. Do not split at the first underscore: account_setup_* and regional_methods_* are multiword families. Abandonment reasons, close sources, and ingest-delivery reasons are separate vocabularies and do not follow this convention.

Deposit analytics

Funding methods are wallet, transfer, fiat_onramp, exchange_connect, and asset_migration.

Deposit steps

Deposit events

All payloads below also carry the envelope and top-level funding_method. entry_source is user or initial_config. Method-selection identifiers are discriminated by funding_method: A transfer handoff requires correlator: { type: "deposit_address", value } and identifiers: { source_chain, source_token }. Those identities describe the payment source, not the session target. Non-transfer handoffs cannot use deposit_address and have no identifier bag. The transfer picker can show a temporary default while its source options load. The modal waits until the picker settles on the source presented to the user before emitting a handoff, so it never publishes that temporary source. If no source identity resolves, the step events remain but no transfer handoff is emitted. A later selection of a distinct source can emit another handoff. For same-route deposits, the processing step opens before the completed outcome. A transfer emits deposit_modal_step_open at transfer_tracking, followed by deposit_modal_ui_outcome with outcome: "completed" and step: "transfer_tracking". A wallet deposit emits the same events in that order at wallet_processing. These outcomes report what the widget observed, not backend or on-chain fulfillment. Correlator types are deposit_address, transaction_hash, deposit_id, and swapped_external_customer_id. Abandonment reasons are back, modal_close, provider_back, wallet_disconnect, method_replacement, and initial_migration_fallback. Close sources are header_button, escape, overlay, host_controlled, provider_back, native_dismiss_request, success_done, failure_cancel, and new_deposit_reset.

Deposit reasons

Withdraw analytics

Steps are form, review, submit, and processing. submit is the asynchronous boundary opened by the review CTA, not a separate screen. same_route is unknown before submit, pinned on handoff, and repeated on later events. A same-route withdrawal creates no backend bridge row, so its UI outcome remains a client observation. Close sources are header_button, escape, overlay, host_controlled, success_done, and failure_cancel.

Withdraw reasons

History analytics

History navigation stays in the current deposit or withdraw session. It does not open or advance a host funnel step. Each suffix below has both a deposit_modal_history_* and withdraw_modal_history_* event name. For example, deposit history emits deposit_modal_history_open, deposit_modal_history_row_view, deposit_modal_history_load_more, deposit_modal_history_fallback_open, and deposit_modal_history_recovery_start. Withdraw uses the same suffixes after withdraw_modal_. Withdraw history events may also carry the optional same_route classification used by the rest of the withdraw funnel. Deposit history events carry the normal top-level funding_method. Opening the panel creates a history visit. Closing and reopening creates a new history_visit_id. A row emits at most one view event per visit. Opening fallback lookup immediately creates a claim_attempt_id, even if the hash is malformed or resolves to no deposit, so lookup failures remain measurable. history_recovery_start is later: it fires only when an eligible deposit is selected for recovery. Recovery runs as a claim session rather than as host funnel steps. Claim events from history carry entry_source, source_session_id, history_visit_id, and claim_attempt_id; deposit_id joins the selected deposit after lookup. These correlation fields are event payload fields, not session_properties. They link history_fallback_open or history_recovery_start to the claim session. The host modal delivers those ClaimAnalyticsEvent values through onEvent. It does not deliver claim progress through deposit or withdraw onLifecycle.

Claim analytics

Steps are lookup, select, review, and submit. submit is the asynchronous boundary opened by the review CTA, not a separate screen. Every claim event identifies how the attempt started with entry_source: history_row or history_fallback. Both carry the correlation fields described in history analytics. Most events arrive at most once per attempt. claim_modal_lookup_result arrives once per submitted search. The searched hash, refund destination, and deposit amount are not sent. Identities enter the stream only after a lookup matches a backend deposit row. transaction_hash is the deposit’s source transaction hash; refund_transaction_hash is the submitted refund transaction. A missing source hash is null, never an empty string, and deposit_id is the authoritative join key. A claim UI outcome is what the widget observed at submit, not on-chain settlement. Close sources are header_button, escape, overlay, host_controlled, success_done, failure_cancel, and history_back. The last value returns a history-originated claim to its history panel.

Claim reasons

Recovery from history is analytics-only for the host and arrives through onEvent. There is no claim onLifecycle.

Opting out

enableAnalyticsIngest={false} on any modal turns Rhinestone collection off entirely. onEvent receives the same events either way, so your own pipeline is unaffected. Collection and attribution are separate: leaving the POST /analytics/ingest-token route off your proxy leaves sessions unattributed but does not stop collection.

Ingest failures

When delivery to Rhinestone fails, onEvent receives an AnalyticsIngestFailureEvent. It carries type, session_id, modal, widget_version, timestamp, reason, dropped_events, and status when an HTTP response exists. It has no session_properties and is never sent to Rhinestone. It fires at most once per distinct reason per session, with a running dropped_events count.
Analytics never blocks or interrupts a deposit, withdrawal, or claim. Ignoring a delivery diagnostic costs analytics only.