Skip to content

Events & Callbacks ​

TokenFlight communicates with your application through callback functions. There are no DOM CustomEvents.

Should you read this? ​

Read this page when your app needs to update UI, analytics, or backend state after a quote, wallet connection, success, or failure.

If you are still choosing a flow, read Choose your flow first.

Before you start ​

  • onSwapSuccess and onSwapError are for EXACT_INPUT swap flows.
  • onDepositSuccess and onDepositError are for EXACT_OUTPUT receive and deposit flows.
  • Card orders use onFiatOrderCreated and onFiatOrderCompleted for the card lifecycle.
  • Frontend callbacks are not payment proof. Verify important orders from your backend.

Available Callbacks ​

CallbackTriggerPayload
onSwapSuccess(data)EXACT_INPUT order filled successfullySwapSuccessData
onSwapError(data)EXACT_INPUT execution errorSwapErrorData
onWalletConnected(data)Wallet connects or address changesWalletConnectedData
onQuoteReceived(data)New quote arrives from the APIQuoteResponse
onAmountChanged(data)User changes an editable amountAmountChangedData
onConnectWallet()User clicks "Connect Wallet" and no adapter is provided—
onAccountModal()Fallback when the user clicks the wallet address button and the adapter has no openAccountModal()—
onFiatOrderCreated(data)Fiat order created; widgetUrl is present only for URL-bearing payment actions{ orderId, widgetUrl? }
onFiatOrderCompleted(data)Fiat order reaches a terminal status{ orderId, status, txHash? }
onDepositSuccess(data)EXACT_OUTPUT receive or deposit completed successfullySwapSuccessData
onDepositError(data)EXACT_OUTPUT receive or deposit failedSwapErrorData

If your wallet adapter implements openAccountModal(), the widget calls that adapter method instead of onAccountModal().

Callback Payloads ​

ts
interface SwapSuccessData {
  orderId: string;
  fromToken: string;
  toToken: string;
  fromAmount: string;
  toAmount: string;
  txHash: string;
}

interface SwapErrorData {
  code: string;
  message: string;
  details?: unknown;
}

interface WalletConnectedData {
  address: string;
  chainType: string;
}

interface AmountChangedData {
  amount: string;
  direction: "from" | "to";
}

Three Ways to Pass Callbacks ​

Pick based on how many widgets you have and whether callbacks differ per instance:

ApproachUse whenScope
registerWidgetElement({ callbacks })All <tokenflight-widget> tags share the same handlersGlobal default
element.__callbacks = { ... }Different callbacks per declarative instancePer element
new TokenFlightWidget({ callbacks })You're using the imperative API alreadyPer instance

1. registerWidgetElement() Defaults ​

js
import { registerWidgetElement } from '@tokenflight/swap/widget';

registerWidgetElement({
  callbacks: {
    onDepositSuccess: (data) => {
      analytics.track('deposit_success', {
        from: data.fromToken,
        to: data.toToken,
        txHash: data.txHash,
      });
    },
    onDepositError: (error) => {
      console.error(`[${error.code}] ${error.message}`);
    },
    onConnectWallet: () => {
      myWalletModal.open();
    },
  },
});
html
<tokenflight-widget
  to-token="eip155:8453:0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
  trade-type="EXACT_OUTPUT"
  amount="100"
  theme="dark"
></tokenflight-widget>

2. Element __callbacks ​

js
import { registerWidgetElement } from '@tokenflight/swap/widget';

registerWidgetElement();

const widgetEl = document.createElement('tokenflight-widget');
widgetEl.__callbacks = {
  onDepositSuccess: (data) => showConfirmationDialog(data),
};
widgetEl.setAttribute('to-token', 'eip155:8453:0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913');
widgetEl.setAttribute('trade-type', 'EXACT_OUTPUT');
widgetEl.setAttribute('amount', '100');
widgetEl.setAttribute('theme', 'dark');

document.querySelector('#widget').appendChild(widgetEl);

3. Imperative Constructor Callbacks ​

js
import { TokenFlightWidget } from '@tokenflight/swap';

const widget = new TokenFlightWidget({
  container: '#widget',
  config: {
    toToken: { chainId: 8453, address: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913' },
    tradeType: 'EXACT_OUTPUT',
    amount: '100',
    theme: 'dark',
  },
  callbacks: {
    onDepositSuccess: (data) => console.log('Order:', data.orderId),
    onDepositError: (error) => showErrorToast(error.message),
    onWalletConnected: ({ address, chainType }) => {
      console.log(`Connected: ${address} (${chainType})`);
    },
    onAmountChanged: ({ amount, direction }) => {
      console.log(`Amount changed: ${amount} (${direction})`);
    },
    onQuoteReceived: (quote) => console.log('Quote:', quote),
    onConnectWallet: () => myWalletModal.open(),
    onAccountModal: () => myAccountModal.open(),
  },
});

widget.initialize();

Analytics Example ​

js
import { TokenFlightWidget } from '@tokenflight/swap';

const widget = new TokenFlightWidget({
  container: '#widget',
  config: {
    toToken: { chainId: 8453, address: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913' },
    tradeType: 'EXACT_OUTPUT',
    amount: '100',
    theme: 'dark',
  },
  callbacks: {
    onDepositSuccess: (data) => {
      analytics.track('deposit_completed', {
        orderId: data.orderId,
        fromToken: data.fromToken,
        toToken: data.toToken,
        txHash: data.txHash,
      });
    },
    onDepositError: (error) => {
      analytics.track('deposit_error', {
        code: error.code,
        message: error.message,
      });
    },
  },
});

Next step ​