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 and provider widget URL is ready{ 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