Swap Widget
The Swap widget provides a cross-chain token swap interface. Users select source and destination tokens, enter an amount, and execute the swap.
Imperative API
Section titled “Imperative API”import { TokenFlightSwap } from '@tokenflight/swap';
const swap = new TokenFlightSwap({ container: '#swap-widget', config: { theme: 'dark', locale: 'en-US', slippage: 50, }, callbacks: { onSwapSuccess: (data) => console.log('Success:', data), onSwapError: (data) => console.log('Error:', data), onQuoteReceived: (data) => console.log('Quote:', data), onAmountChanged: (data) => console.log('Amount:', data), },});
swap.initialize();Declarative (HTML)
Section titled “Declarative (HTML)”<tokenflight-swap theme="dark" locale="en-US" default-slippage="50" from-token="eip155:1:0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" to-token="eip155:8453:0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"></tokenflight-swap>HTML Attributes
Section titled “HTML Attributes”| Attribute | Default | Description |
|---|---|---|
theme | 'light' | 'light', 'dark', or 'auto' |
locale | 'en-US' | Display locale |
default-slippage | '50' | Slippage tolerance in basis points (50 = 0.5%) |
from-token | — | Source token in CAIP-10 format (e.g. eip155:1:0x...) |
to-token | — | Destination token in CAIP-10 format |
recipient | — | Custom recipient address for cross-chain swaps (optional) |
api-endpoint | — | Custom API endpoint URL |
csp-nonce | — | Nonce for CSP-restricted environments |
Imperative Configuration
Section titled “Imperative Configuration”| Property | Type | Default | Description |
|---|---|---|---|
theme | 'dark' | 'light' | 'auto' | 'light' | Widget color theme |
locale | string | 'en-US' | Display locale |
slippage | number | 50 | Slippage tolerance in basis points (50 = 0.5%) |
fromToken | TokenIdentifier | — | Source token ({ chainId, address } or CAIP-10 string) |
toToken | TokenIdentifier | — | Destination token |
recipient | string | — | Custom recipient address for cross-chain swaps (optional) |
apiEndpoint | string | — | Custom API endpoint URL |
customColors | Record<string, string> | — | CSS color variable overrides |
Cross-Chain Swaps (EVM ↔ Solana)
Section titled “Cross-Chain Swaps (EVM ↔ Solana)”The Swap widget supports cross-chain swaps between EVM chains and Solana. When swapping to a different chain type than your connected wallet, you must provide a recipient address:
| Scenario | Connected Wallet | Target Chain | Recipient Required |
|---|---|---|---|
| EVM → EVM | MetaMask | Base, Arbitrum, etc. | Optional (defaults to connected address) |
| EVM → Solana | MetaMask | Solana | Required |
| Solana → EVM | Phantom | Ethereum, Base, etc. | Required |
| Solana → Solana | Phantom | Solana | Optional (defaults to connected address) |
Why recipient is required for cross-chain swaps:
When you’re connected with an EVM wallet (e.g., MetaMask) and swapping to Solana, the widget cannot access your Solana address. Therefore, you must manually enter a Solana recipient address. The same applies when swapping from Solana to EVM with a Solana wallet connected.
Example: EVM → Solana
import { TokenFlightSwap } from '@tokenflight/swap';
const swap = new TokenFlightSwap({ container: '#swap-widget', config: { theme: 'dark', // From: Ethereum USDC fromToken: 'eip155:1:0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // To: Solana USDC (use solana namespace for Solana tokens) toToken: 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp:EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', // Required when swapping to a different chain type // (e.g., EVM wallet → Solana, or Solana wallet → EVM) recipient: 'HN7cABqLq46Es1jh92dQQisAq662SmxELLLsHHe4YWrH', }, callbacks: { onWalletConnected: ({ address, chainType }) => { console.log(`Connected: ${address} (${chainType})`); // chainType is 'evm' or 'solana' }, },});
swap.initialize();HTML usage:
<tokenflight-swap theme="dark" from-token="eip155:1:0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" to-token="solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp:EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" recipient="HN7cABqLq46Es1jh92dQQisAq662SmxELLLsHHe4YWrH"></tokenflight-swap>Programmatically Detecting Cross-Chain Requirements
Section titled “Programmatically Detecting Cross-Chain Requirements”You can use the exported utilities to detect if a swap will require a recipient address:
import { getChainType, isCrossChainSwap, SOLANA_CHAIN_ID } from '@tokenflight/swap';
const fromChainId = 1; // Ethereumconst toChainId = SOLANA_CHAIN_ID; // Solana
// Check if chains are different typesconst isCrossChain = isCrossChainSwap(fromChainId, toChainId);console.log('Cross-chain swap:', isCrossChain); // true
// Get chain typesconsole.log('From chain type:', getChainType(fromChainId)); // 'evm'console.log('To chain type:', getChainType(toChainId)); // 'solana'User Experience
Section titled “User Experience”When a cross-chain recipient is required, the widget will:
- Display a “Recipient” input field below the “You receive” panel
- Show a “Required” label to indicate the field must be filled
- Prevent the swap from proceeding until a valid address is entered
- Validate the address format based on the target chain
Callbacks
Section titled “Callbacks”| Callback | Payload | Description |
|---|---|---|
onSwapSuccess | SwapSuccessData | Fired after a successful swap transaction |
onSwapError | SwapErrorData | Fired when a swap fails |
onQuoteReceived | QuoteResponse | Fired when a new price quote is fetched |
onAmountChanged | AmountChangedData | Fired when the user changes the input amount |
onWalletConnected | WalletConnectedData | Fired when a wallet connects |
Runtime Methods
Section titled “Runtime Methods”// Update theme without re-initializationswap.setTheme('light'); // 'light' | 'dark' | 'auto'
// Apply custom color overridesswap.setCustomColors({ primary: '#ff6600', background: '#1a1a2e' });
// Clean up the widgetswap.destroy();