Skip to main content
Pass an events object to subscribe to widget lifecycle events. Every callback receives { event, state } where state is a snapshot of the full widget state and event is a discriminated union of named sub-events.
<Widget
  events={{
    onSwap: ({ event, state }) => {
      if (event.name === "Swap:confirmed") {
        analytics.track("swap_confirmed", { txHash: event.params.txHash });
      }
    },
  }}
/>
All callbacks are optional. Subscribe only to what you need.

Callback summary

CallbackFires when
onConnectWalletA wallet connects (or the Connect button is clicked).
onConnectWalletClickThe Connect Wallet button is clicked (dApp-mode hook).
onAllowTokenToken approval / permit lifecycle.
onWrapETHETH → WETH wrap lifecycle (Delta pre-step).
onSwapMarket or Delta Swap lifecycle.
onTwapOrderTWAP order lifecycle.
onLimitOrderDelta limit-order lifecycle.
onOTCOrderOTC order lifecycle.
onCancelTxUser cancels a pending swap tx (replacement).
onCancelOrderUser cancels a Delta or OTC order.
onFillOTCOrderUser fills an existing OTC order.
onSettingsChangeUser changes widget settings (slippage, gas, bridges).
onFormInputChangeAny input in any trading form changes.
onPriceChangePrice quote refreshes or query state changes.

onConnectWallet

Fires when a wallet connects to the widget, and on the click that initiates connection. Sub-events:
  • ConnectWallet:click — Connect Wallet button clicked. Params: {}.
  • ConnectWallet:connect — A wallet actually connected (explicit click, eager auto-reconnect, or embedded provider).
ConnectWallet:connect params:
ParamTypeDescription
connectorTypestringType of connector used.
connectorNamestringWallet name (from WalletConnect or EIP-6963).
connectorAction"Click" | "Eager" | "Embedded" | "External"How the connection happened.
providerEIP1193ProviderLaxThe underlying provider.
accountAddressConnected account address.
walletNamestring | nullWallet display name.
walletIconstring | nullWallet icon URL.
chainIdnumberChain the wallet is connected to.
<Widget
  events={{
    onConnectWallet: ({ event }) => {
      if (event.name === "ConnectWallet:connect") {
        analytics.track("wallet_connected", {
          connector: event.params.connectorType,
          action: event.params.connectorAction,
          account: event.params.account,
        });
      }
    },
  }}
/>
ConnectWallet:click carries no params. Check event.name before reading connect-specific fields.

onConnectWalletClick

Fires when the Connect Wallet button is clicked. Same payload type as onConnectWallet, but only emits ConnectWallet:click.
<Widget
  config={{ widgetMode: "dapp" }}
  events={{
    onConnectWalletClick: () => {
      openHostAppWalletModal();
    },
  }}
/>

onAllowToken

Token approval (approve) or signed-permit (permit1 / permit2) lifecycle. Sub-events:
  • AllowToken:request — Approval or permit initiated.
  • AllowToken:sent — Transaction signed and broadcast.
  • AllowToken:confirmed — Transaction confirmed on-chain, or permit signed.
  • AllowToken:failed — Transaction failed or permit rejected.
Common params:
ParamDescription
tokenToken being approved.
amountWeiApproval amount, in wei.
spenderAddressThe contract receiving the allowance.
chainIdChain ID.
tradeMode"swap" | "limit" | "otc" | "twap".
type"approve" | "permit".
permitType(if permit) "permit1" | "permit2".
txHash(if sent / confirmed / failed) Transaction hash.
txReceipt(if confirmed / failed) Transaction receipt.
error(if failed) Error object.
<Widget
  events={{
    onAllowToken: ({ event }) => {
      if (event.name === "AllowToken:confirmed") {
        console.log("Approved", event.params.token.symbol);
      } else if (event.name === "AllowToken:failed") {
        console.error("Approval failed", event.params.error);
      }
    },
  }}
/>

onWrapETH

Fires during ETH → WETH wrapping. Used as a pre-step for Delta Swaps that start from native ETH. Sub-events: WrapETH:click, WrapETH:request, WrapETH:sent, WrapETH:confirmed, WrapETH:failed. Params: ethAmountWei, wethAddress, chainId, tradeMode, txHash (if sent+), txReceipt (if confirmed/failed), error (if failed).
<Widget
  events={{
    onWrapETH: ({ event }) => {
      if (event.name === "WrapETH:confirmed") {
        console.log("ETH wrapped", event.params.txHash);
      }
    },
  }}
/>

onSwap

The most common callback. Fires for both Delta and Market Swap lifecycles. Sub-events:
  • Swap:click — Confirmation drawer opened.
  • Swap:request — Swap initiated.
  • Swap:sent — Tx signed and broadcast (market), or Delta order submitted.
  • Swap:confirmed — Tx confirmed (market), or Delta order filled.
  • Swap:failed — Tx failed or Delta order failed.
  • Swap:cancelled — User replaced / cancelled the pending tx, or the Delta order was cancelled.
Params common to all sub-events:
ParamDescription
swapMode"market" | "delta".
priceQuote info (shape varies by swapMode).
tokenFrom, tokenToTokens involved.
sendAmount, receiveAmountAmounts.
receiverAddressDestination address.
srcChainId, destChainIdChains involved.
connectedAccountConnected wallet address.
side"BUY" | "SELL".
Sub-event-specific: txHash, callsId, order (Delta), txReceipt, callsReceipt, error, cancelTxDetails.
<Widget
  events={{
    onSwap: ({ event }) => {
      if (event.name === "Swap:confirmed") {
        if (event.params.swapMode === "market") {
          console.log("Market Swap confirmed", event.params.txHash);
        } else {
          console.log("Delta order filled", event.params.order);
        }
      } else if (event.name === "Swap:failed") {
        console.error("Swap failed", event.params.error);
      }
    },
  }}
/>

onTwapOrder

TWAP (Time-Weighted Average Price) order lifecycle. TWAP splits a large trade into smaller slices executed over a duration. Sub-events: TwapOrder:click, TwapOrder:request, TwapOrder:sent, TwapOrder:confirmed, TwapOrder:failed. Params: Delta or bridge price, order (if sent+), error (if failed), plus form-state fields (tokenFrom, tokenTo, sendAmount, receiveAmount, receiverAddress, srcChainId, destChainId, connectedAccount, side).
<Widget
  events={{
    onTwapOrder: ({ event }) => {
      if (event.name === "TwapOrder:sent") {
        toast.success("TWAP order placed");
      }
    },
  }}
/>

onLimitOrder

Delta limit-order lifecycle. Sub-events: LimitOrder:click, LimitOrder:request, LimitOrder:sent, LimitOrder:confirmed (rare; orders typically fill later), LimitOrder:failed. Params: Delta price, order, error (if failed), plus form-state fields including limitPrice and orderDeadline.
<Widget
  events={{
    onLimitOrder: ({ event }) => {
      if (event.name === "LimitOrder:sent") {
        toast.success("Limit order placed");
      }
    },
  }}
/>

onOTCOrder

OTC (Over-The-Counter) order lifecycle. Similar to limit orders but for OTC trades. Sub-events: OTCOrder:click, OTCOrder:request, OTCOrder:sent, OTCOrder:confirmed (rare), OTCOrder:failed. Params: OTC price, order (if not failed), error (if failed), plus form-state fields including otcPrice and orderDeadline.
<Widget
  events={{
    onOTCOrder: ({ event }) => {
      if (event.name === "OTCOrder:sent") {
        console.log("OTC order submitted", event.params.order);
      }
    },
  }}
/>

onCancelTx

Fires when the user replaces a pending swap tx with a “cancel” tx (same nonce, zero value) to drop it. Sub-events: CancelTx:request, CancelTx:sent, CancelTx:confirmed, CancelTx:failed. Params:
ParamDescription
txType"SWAP" (only swap tx cancellations are supported today).
originalTxHashHash of the tx being cancelled.
chainIdChain.
originalTx(if sent+) The original tx response.
replacementRequest(if sent+) The replacement (cancel) tx request.
replacementTxHash(if sent+) Hash of the cancel tx.
replacementTxReceipt(if confirmed) Receipt of the mined cancel tx.
error(if failed) Error object.

onCancelOrder

Fires when the user cancels a Delta or OTC order. Sub-events:
  • CancelOrder:request — Cancel initiated (tx or typed-data signing).
  • CancelOrder:sentTx — Cancel tx signed and broadcast. Fires for OTC orders and for ETH Delta orders cancelled via withdrawAndCancel. Non-ETH Delta orders skip this stage (they cancel via signed typed-data).
  • CancelOrder:confirmed — Cancel tx mined, or typed-data posted.
  • CancelOrder:failed — Cancel failed.
Params:
ParamDescription
orderType"DELTA" | "OTC".
orderSubTypeSubtype (varies by order type).
orderIds(Delta) Array of order IDs to cancel.
orderHash(OTC) Hash of the order.
txHash, chainId, txReceipt(if sent/confirmed) Required for OTC; optional for Delta (only ETH Delta orders have a tx).
error(if failed) Error object.
<Widget
  events={{
    onCancelOrder: ({ event }) => {
      if (event.name === "CancelOrder:confirmed") {
        if (event.params.orderType === "DELTA") {
          console.log("Delta orders cancelled", event.params.orderIds);
        } else {
          console.log("OTC order cancelled", event.params.orderHash);
        }
      }
    },
  }}
/>

onFillOTCOrder

Fires when the user fills an existing OTC order (acts as the taker). Sub-events: FillOTCOrder:request, FillOTCOrder:sent, FillOTCOrder:confirmed, FillOTCOrder:failed. Params: orderHash, orderType: "OTC", orderSubType, txHash (if sent+), callsId (if sendCalls), txReceipt (if confirmed), callsReceipt, error (if failed).

onSettingsChange

Fires when the user changes widget settings. Sub-events:
  • Settings:switchSwapMode — Switched between Market and Delta. Params: { swapMode: "market" | "delta" }.
  • Settings:saveSettings — User saved settings. Payload is the full SettingsState: slippageTolerance, transactionSpeed ("slow" | "standard" | "fast" | "custom"), swapMode, eip1559Enabled, degenMode, disabledDexes, bridgePreference ("auto" | "fastest" | "bestReturn"), disabledBridges.
  • Settings:changeBridgePreferences — Bridge preferences changed independently (e.g. from Compare Quotes). Params: bridgePreference, disabledBridges.
<Widget
  events={{
    onSettingsChange: ({ event }) => {
      if (event.name === "Settings:saveSettings") {
        console.log("New slippage", event.params.slippageTolerance);
      }
    },
  }}
/>

onFormInputChange

Fires whenever any input changes in any trading form. Sub-event: FormInput:change. Params (discriminated by form): Common to all variants:
ParamDescription
form"swap" | "limit" | "otc" | "twap".
tokenFromMinTradeFlowToken — source token.
tokenToMinTradeFlowToken — destination token (may be absent until selected).
srcChainId, destChainIdChain IDs (destChainId may be absent).
receiverAddressOptional — defaults to connected account.
Variant-specific:
  • form: "swap" — adds side: "SELL" | "BUY". When side === "SELL", payload carries sendAmount (not receiveAmount); when side === "BUY", receiveAmount (not sendAmount).
  • form: "twap" — adds side, orderSplit (slice count), orderInterval (seconds), orderDeadline (Unix seconds), slippage.
  • form: "limit" — adds limitPrice, orderDeadline. Both sendAmount and receiveAmount present.
  • form: "otc" — adds otcPrice, orderDeadline. Both sendAmount and receiveAmount present.
<Widget
  events={{
    onFormInputChange: ({ event }) => {
      console.log("Form changed", {
        form: event.params.form,
        from: event.params.tokenFrom?.symbol,
        to: event.params.tokenTo?.symbol,
      });
    },
  }}
/>

onPriceChange

Fires when price info refreshes or the price-query state changes. Sub-events:
  • PriceUpdate — Price was successfully (re)fetched.
  • PriceQueryUpdate — Price-query state changed (data, isLoading, error).
Params:
ParamDescription
priceMode"delta" | "market".
pricePrice object (DeltaPrice | BridgePrice for Delta, OptimalRate for market).
isLoading(PriceQueryUpdate) First-time fetch in progress.
isFetching(PriceQueryUpdate) Refetching.
isError(PriceQueryUpdate) Whether the query errored.
error(PriceQueryUpdate) Error or null.
<Widget
  events={{
    onPriceChange: ({ event }) => {
      if (event.name === "PriceUpdate") {
        console.log("New price", event.params.priceMode, event.params.price);
      }
    },
  }}
/>

Lifecycle of a successful market swap

For a wallet-connected market swap that requires token approval, events fire in this order:
  1. onConnectWalletConnectWallet:click (user clicks), then ConnectWallet:connect once a wallet attaches.
  2. onFormInputChangeFormInput:change for every field edit.
  3. onPriceChangePriceQueryUpdate (loading / refetching) and PriceUpdate (successful fetch) as quotes refresh.
  4. onAllowTokenAllowToken:requestAllowToken:sentAllowToken:confirmed. Skipped if allowance already covers the trade or the flow uses a permit signature only.
  5. onWrapETH — for Delta Swaps with ETH as tokenFrom, the user is asked to wrap first: WrapETH:clickWrapETH:requestWrapETH:sentWrapETH:confirmed.
  6. onSwapSwap:clickSwap:requestSwap:sentSwap:confirmed. Replace with Swap:failed or Swap:cancelled on the unhappy path.
  7. onCancelTx — only if the user explicitly cancels a pending market swap tx: CancelTx:requestCancelTx:sentCancelTx:confirmed.
Delta Swaps replace step 4/5/6 with a single Delta order submission (Swap:sent with swapMode: "delta" and an order param). The order is filled off-band, so Swap:confirmed may arrive minutes later, or be missed entirely if the user closes the widget. Limit, OTC, and TWAP flows replace step 6 with their respective callbacks (onLimitOrder, onOTCOrder, onTwapOrder).
Last modified on June 14, 2026