Getting Started
TokenFlight Embed is a drop-in payment widget for cross-chain token flows.
Install the SDK, choose a wallet adapter, and render one widget. This page gets a first crypto-capable widget on screen.
Should you read this?
Read this page if you are new to TokenFlight and want the shortest working path.
Skip ahead if you already know your app shape:
- Choose your flow explains swap vs fixed-amount receive vs card payments.
- Why wallet adapters explains how wallet connection works.
- Choose your API explains HTML tag vs JavaScript class.
- Examples has framework projects.
1. Install
These examples use npm package imports, so run them inside a bundler or framework project such as Vite, Next.js, Vue, Astro, or SvelteKit. Do not open the HTML file directly from your filesystem.
npm install @tokenflight/swappnpm add @tokenflight/swapyarn add @tokenflight/swapbun add @tokenflight/swap2. Choose a wallet adapter
Most TokenFlight flows need a wallet adapter. Without one, the widget can render, but users cannot finish crypto wallet actions.
Card-only checkout is the exception. If your flow is only methods='["card"]', you can skip the crypto wallet adapter.
| Your app | Choose | Install |
|---|---|---|
| You are not sure yet, or you want WalletConnect UX | AppKit | @tokenflight/adapter-appkit |
| You already use wagmi or RainbowKit for EVM wallets | wagmi | @tokenflight/adapter-wagmi |
| You use an injected EIP-1193 wallet through ethers | ethers | @tokenflight/adapter-ethers |
| You have your own wallet modal or provider | Custom Wallet Adapter | Your adapter implementation |
If you are choosing for the first time, start with AppKit. It gives users a familiar wallet connection flow.
3. Install the AppKit adapter
This quickstart uses AppKit as the default wallet setup.
npm install @tokenflight/adapter-appkit @reown/appkit @reown/appkit-adapter-wagmi @reown/appkit-adapter-solana @solana/web3.js wagmi viempnpm add @tokenflight/adapter-appkit @reown/appkit @reown/appkit-adapter-wagmi @reown/appkit-adapter-solana @solana/web3.js wagmi viemyarn add @tokenflight/adapter-appkit @reown/appkit @reown/appkit-adapter-wagmi @reown/appkit-adapter-solana @solana/web3.js wagmi viembun add @tokenflight/adapter-appkit @reown/appkit @reown/appkit-adapter-wagmi @reown/appkit-adapter-solana @solana/web3.js wagmi viem4. Render declaratively with the HTML tag
TokenFlight is a Web Component. The shortest path is to place <tokenflight-widget> in your HTML and register it once from JavaScript.
This example renders a fixed-amount receive flow. Your app asks for 100 USDC on Base, and AppKit provides the wallet connection path.
<div id="app">
<tokenflight-widget
theme="dark"
to-token="eip155:8453:0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
trade-type="EXACT_OUTPUT"
amount="100"
></tokenflight-widget>
</div>
<script type="module">
import { registerWidgetElement } from '@tokenflight/swap/widget';
import { createAppKitAdapter } from '@tokenflight/adapter-appkit';
import { mainnet, base } from '@reown/appkit/networks';
const { adapter } = await createAppKitAdapter({
projectId: import.meta.env.VITE_REOWN_PROJECT_ID,
networks: [mainnet, base],
metadata: {
name: 'My TokenFlight App',
description: 'TokenFlight payment flow',
url: window.location.origin,
icons: [],
},
});
registerWidgetElement({ walletAdapter: adapter });
</script>See the AppKit guide for install commands, Solana signing, and Reown project setup.
Use the declarative HTML tag when:
- Your config fits in HTML attributes.
- You want the simplest Web Component embed.
- Your framework handles custom elements cleanly.
- One wallet adapter and callback set can apply to every widget on the page.
5. Render imperatively with JavaScript
The imperative API mounts the same widget from JavaScript. Use it when config comes from runtime state, callbacks, or app objects.
import { TokenFlightWidget } from '@tokenflight/swap';
import { createAppKitAdapter } from '@tokenflight/adapter-appkit';
import { mainnet, base } from '@reown/appkit/networks';
const container = document.querySelector<HTMLElement>('#tokenflight-widget');
if (!container) {
throw new Error('Missing #tokenflight-widget container');
}
const { adapter } = await createAppKitAdapter({
projectId: import.meta.env.VITE_REOWN_PROJECT_ID,
networks: [mainnet, base],
metadata: {
name: 'My TokenFlight App',
description: 'TokenFlight payment flow',
url: window.location.origin,
icons: [],
},
});
const widget = new TokenFlightWidget({
container,
config: {
theme: 'dark',
toToken: {
chainId: 8453,
address: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
},
tradeType: 'EXACT_OUTPUT',
amount: '100',
},
walletAdapter: adapter,
});
widget.initialize();Pair it with a plain container in your page:
<div id="tokenflight-widget"></div>
<script type="module" src="/src/main.ts"></script>Use the imperative JavaScript class when:
- You need per-instance wallet adapters, callbacks, or functions.
- Config comes from a cart, checkout session, URL, or backend response.
- You need to call
widget.destroy()during route changes.
See Choose your API for the full declarative vs imperative comparison.
6. Check that it worked
You should see:
- The widget frame renders in the page, with TokenFlight styling and no blank box.
- The receive flow shows a target amount of
100USDC on Base. - If no wallet adapter is configured yet, the connect button can render but crypto signing cannot finish.
- If an adapter is configured, clicking connect opens your wallet modal or wallet provider.
- After wallet and token inputs are ready, the widget can show quotes, route details, or the next payment step.
- The browser console has no
registerWidgetElement,TokenFlightWidget, or wallet adapter setup error.
If the page is blank, open Troubleshooting.
7. Pick the next page
Most teams need one of these next:
Important words
toToken: the token the user or your app should receive.fromToken: the token the user starts with.EXACT_INPUT: the user chooses the amount they pay.EXACT_OUTPUT: your app chooses the amount that must arrive.walletAdapter: the object that lets the widget talk to a wallet.