Skip to content

Vanilla JS Demo

This demo shows the unified widget running with vanilla JavaScript -- no framework required. Use the theme buttons to switch between dark and light mode.

Widget demo without wallet connection
Live projectOpen in StackBlitz

Declarative — Minimal

The simplest way to embed a widget is to register the public custom element and use HTML tags. This renders the UI; add a wallet adapter before users make crypto payments.

html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>TokenFlight – Declarative</title>
</head>
<body>
  <tokenflight-widget
    theme="dark"
    to-token="eip155:8453:0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
    trade-type="EXACT_OUTPUT"
    amount="100"
  ></tokenflight-widget>

  <script type="module">
    import { registerWidgetElement } from '@tokenflight/swap/widget';

    registerWidgetElement();
  </script>
</body>
</html>

Imperative — Full Source

The following snippet embeds the widget from JavaScript. Add walletAdapter before users make crypto payments.

html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>TokenFlight Demo</title>
</head>
<body>
  <div id="widget"></div>

  <script type="module">
    import {
      TokenFlightWidget,
    } from '@tokenflight/swap';

    const widget = new TokenFlightWidget({
      container: '#widget',
      config: {
        toToken: {
          chainId: 8453,
          address: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
        },
        amount: '100',
        tradeType: 'EXACT_OUTPUT',
        theme: 'dark',
        locale: 'en-US',
      },
      callbacks: {
        onDepositSuccess: (data) => console.log('Payment success:', data),
        onDepositError: (data) => console.log('Payment error:', data),
      },
    });
    widget.initialize();

    // Theme switching
    function setTheme(theme) {
      widget.setTheme(theme);
    }
  </script>
</body>
</html>

Declarative — With Wallet Adapter & Callbacks

Declarative HTML tags can have full functionality — wallet connections, transaction signing, and callbacks — by passing options to registerWidgetElement():

html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>TokenFlight – Declarative Full</title>
</head>
<body>
  <tokenflight-widget
    theme="dark"
    to-token="eip155:8453:0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
    trade-type="EXACT_OUTPUT"
    amount="100"
  ></tokenflight-widget>

  <script type="module">
    import { registerWidgetElement } from '@tokenflight/swap/widget';
    import { createAppKitAdapter } from '@tokenflight/adapter-appkit';
    import { mainnet, base } from '@reown/appkit/networks';

    const { adapter: walletAdapter } = await createAppKitAdapter({
      projectId: import.meta.env.VITE_REOWN_PROJECT_ID,
      networks: [mainnet, base],
      metadata: {
        name: 'TokenFlight Vanilla Example',
        description: 'TokenFlight payment flow',
        url: window.location.origin,
        icons: [],
      },
    });

    registerWidgetElement({
      walletAdapter,
      callbacks: {
        onDepositSuccess: (data) => {
          console.log('Payment completed:', data.orderId, data.txHash);
        },
        onDepositError: (error) => {
          console.error(`[${error.code}] ${error.message}`);
        },
        onWalletConnected: ({ address, chainType }) => {
          console.log(`Connected: ${address} (${chainType})`);
        },
      },
    });
  </script>
</body>
</html>

All <tokenflight-widget> tags on the page automatically inherit the wallet adapter and callbacks.

Key Points

  • registerWidgetElement() must be called once before using <tokenflight-widget> as an HTML tag. The imperative API (new TokenFlightWidget(...)) does not require registration.
  • registerWidgetElement() accepts optional walletAdapter and callbacks — all declarative widgets inherit these defaults.
  • container accepts a CSS selector string or an HTMLElement reference (imperative API only).
  • setTheme() updates the widget theme at runtime without re-initialization (imperative API only).
  • Callbacks are optional but useful for reacting to payment lifecycle events.
  • Production wallet setup should follow AppKit, wagmi, ethers, or Custom Wallet Adapter.