Skip to content

AppKit ​

Use AppKit when you want WalletConnect UX plus optional multi-chain providers in one modal.

Live projectOpen in StackBlitz

This page shows the TokenFlight helper that creates AppKit, registers EVM support, and passes Solana signing support when you include Solana networks.

The embedded project is a runnable demo. The React example below is the canonical setup pattern for apps that create and clean up TokenFlightWidget from a client component.

Install ​

bash
npm install @tokenflight/swap @tokenflight/adapter-appkit @reown/appkit @reown/appkit-adapter-wagmi @reown/appkit-adapter-solana @solana/web3.js wagmi viem
bash
pnpm add @tokenflight/swap @tokenflight/adapter-appkit @reown/appkit @reown/appkit-adapter-wagmi @reown/appkit-adapter-solana @solana/web3.js wagmi viem
bash
yarn add @tokenflight/swap @tokenflight/adapter-appkit @reown/appkit @reown/appkit-adapter-wagmi @reown/appkit-adapter-solana @solana/web3.js wagmi viem
bash
bun add @tokenflight/swap @tokenflight/adapter-appkit @reown/appkit @reown/appkit-adapter-wagmi @reown/appkit-adapter-solana @solana/web3.js wagmi viem

Example ​

tsx
import { mainnet, base } from '@reown/appkit/networks';
import { TokenFlightWidget } from '@tokenflight/swap';
import { createAppKitAdapter } from '@tokenflight/adapter-appkit';
import { VersionedTransaction } from '@solana/web3.js';
import { useEffect, useRef } from 'react';

// Get your project ID from https://cloud.reown.com
const projectId = import.meta.env.VITE_REOWN_PROJECT_ID;
const networks = [mainnet, base] as const;

export default function App() {
  const containerRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    let cancelled = false;
    let widget: TokenFlightWidget | undefined;
    let walletAdapter: Awaited<ReturnType<typeof createAppKitAdapter>>['adapter'] | undefined;

    async function mountWidget() {
      if (!containerRef.current) return;

      const result = await createAppKitAdapter({
        projectId,
        networks,
        solana: { VersionedTransaction },
        metadata: {
          name: 'TokenFlight Example',
          description: 'TokenFlight + AppKit',
          url: window.location.origin,
          icons: [],
        },
      });
      walletAdapter = result.adapter;

      if (cancelled) {
        walletAdapter.destroy?.();
        return;
      }

      widget = new TokenFlightWidget({
        container: containerRef.current,
        config: {
          toToken: { chainId: 8453, address: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913' },
          amount: '100',
          tradeType: 'EXACT_OUTPUT',
          theme: 'light',
        },
        walletAdapter,
      });
      widget.initialize();
    }

    void mountWidget();

    return () => {
      cancelled = true;
      widget?.destroy();
      walletAdapter?.destroy?.();
    };
  }, []);

  return <div ref={containerRef} style={{ minHeight: 560 }} />;
}

Set VITE_REOWN_PROJECT_ID in your .env file. Get a project ID from cloud.reown.com.

If your app is EVM-only, keep EVM networks in networks. If you add Solana networks to AppKit, keep the solana: { VersionedTransaction } option so the adapter can sign Solana transactions.

Bitcoin and Tron ​

To let users pay from a Bitcoin or Tron wallet, install the matching Reown adapters, add their networks to networks, and pass the adapters in adapters. createAppKitAdapter() never imports these packages itself, so an app without Bitcoin or Tron networks doesn't need them installed to build.

bash
npm install @reown/appkit-adapter-bitcoin @reown/appkit-adapter-tron @tronweb3/tronwallet-adapter-tronlink
ts
import { mainnet, base, bitcoin, tronMainnet } from '@reown/appkit/networks';
import { BitcoinAdapter } from '@reown/appkit-adapter-bitcoin';
import { TronAdapter } from '@reown/appkit-adapter-tron';
import { TronLinkAdapter } from '@tronweb3/tronwallet-adapter-tronlink';
import { createAppKitAdapter } from '@tokenflight/adapter-appkit';

const { adapter } = await createAppKitAdapter({
  projectId: 'YOUR_REOWN_PROJECT_ID',
  networks: [mainnet, base, bitcoin, tronMainnet],
  adapters: [
    new BitcoinAdapter(),
    new TronAdapter({
      walletAdapters: [new TronLinkAdapter({ openUrlWhenWalletNotFound: false })],
    }),
  ],
  // Optional: the Tron HTTP API used to build and broadcast TRX and TRC-20 transfers.
  // Defaults to https://api.trongrid.io.
  tron: { headers: { 'TRON-PRO-API-KEY': 'YOUR_TRONGRID_KEY' } },
});

createAppKitAdapter() throws if networks includes a Bitcoin or Tron network without its adapter in adapters.

Reown's Tron adapter only lists the Tron browser wallets you give it in walletAdapters; with none, users can only connect over WalletConnect. To offer more wallets, add their @tronweb3/tronwallet-adapter-* adapters:

bash
npm install @tronweb3/tronwallet-adapter-okxwallet
ts
import { mainnet, base, tronMainnet } from '@reown/appkit/networks';
import { TronAdapter } from '@reown/appkit-adapter-tron';
import { TronLinkAdapter } from '@tronweb3/tronwallet-adapter-tronlink';
import { OkxWalletAdapter } from '@tronweb3/tronwallet-adapter-okxwallet';
import { createAppKitAdapter } from '@tokenflight/adapter-appkit';

const { adapter } = await createAppKitAdapter({
  projectId: 'YOUR_REOWN_PROJECT_ID',
  networks: [mainnet, base, tronMainnet],
  adapters: [
    new TronAdapter({
      walletAdapters: [
        new TronLinkAdapter({ openUrlWhenWalletNotFound: false }),
        new OkxWalletAdapter(),
      ],
    }),
  ],
});

Bitcoin and Tron payments use the widget's transfer rail, so the widget must be configured with transfer enabled. TRX and TRC-20 transfers from a browser-extension wallet are built and broadcast through the Tron HTTP API from the browser — add its origin to connect-src if you use a Content Security Policy. TRC-20 transfers over a WalletConnect session are not supported; those users transfer manually and paste the transaction hash. Bitcoin wallets without a transfer call (Wallet Standard wallets) fall back to the same manual transfer.

⚠️ Coming soon: Zcash wallets are not supported yet.

How It Works ​

  1. Create the AppKit adapter — createAppKitAdapter() creates the AppKit instance, EVM wallet adapter, Solana adapter, and TokenFlight walletAdapter.

  2. Pass the TokenFlight adapter — the returned adapter implements the IWalletAdapter interface that TokenFlight widgets expect. Chain IDs are auto-derived from AppKit networks.

  3. Initialize with useEffect — mount the widget in a React effect to ensure the DOM container exists. Clean up both widget.destroy() and walletAdapter.destroy?.() when the component unmounts.

  4. Keep adapter identity stable — create the adapter in a client-only lifecycle or memoize it in your app, so wallet state does not reset on every render.

Adding Callbacks ​

tsx
const widget = new TokenFlightWidget({
  container: '#widget',
  config: {
    toToken: { chainId: 8453, address: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913' },
    amount: '100',
    tradeType: 'EXACT_OUTPUT',
    theme: 'light',
  },
  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})`);
    },
  },
});

See Events & Callbacks for all available callbacks.