| name | lifi-dev |
| description | Comprehensive development support for LI.FI DEX aggregator including SDK, Widget, and API integration for cross-chain swaps and bridging. Use when building applications with LI.FI for - (1) Cross-chain token swaps and bridges, (2) Multi-chain liquidity aggregation, (3) Trading widget integration, (4) Custom DEX aggregation UI, (5) Gas subsidy implementation, (6) Revenue monetization with integrator fees, (7) Route optimization across 60+ chains, (8) Intent-based trading systems. Covers SDK usage (TypeScript/JavaScript), Widget customization (React/Vue/Svelte), API integration (REST), and LI.FI-specific features like cross-chain routing, gas subsidies (LI.Fuel), and multi-protocol aggregation across Uniswap, 1inch, Stargate, Across, and 800+ protocols.
|
LI.FI Development Support
Comprehensive toolkit for building cross-chain swap and bridge applications with LI.FI - the leading DEX and bridge aggregation protocol supporting 60+ chains and 800+ protocols.
Quick Start
Product Selection
LI.FI offers three integration methods. Choose based on your use case:
Quick Decision:
- Ready-made UI component โ Widget (5 min integration, highly customizable)
- Full control over UX โ SDK (TypeScript/JavaScript, frontend & backend)
- Direct API access โ REST API (language-agnostic, maximum flexibility)
- Existing widget + custom logic โ Widget + SDK combo (best of both worlds)
Integration Complexity:
- Widget: โญ (Easiest - drop-in component)
- SDK: โญโญ (Moderate - programmatic control)
- API: โญโญโญ (Advanced - full customization)
Common Tasks
1. Add swap widget to your app:
- Review widget_integration.tsx for React integration
- Key points: theme customization, chain filtering, event handling
- Production-ready in under 5 minutes
- See widget-guide.md for advanced customization
2. Execute cross-chain swap programmatically:
- Use sdk_swap_example.ts for SDK implementation
- Key points: route optimization, gas estimation, slippage protection
- See sdk-guide.md for comprehensive SDK patterns
3. Get best swap route via API:
4. Implement gas subsidy (LI.Fuel):
5. Monetize with integrator fees:
Core Workflows
Widget Integration
React/Next.js Integration:
import { LiFiWidget, WidgetConfig } from '@lifi/widget';
const widgetConfig: WidgetConfig = {
integrator: 'your-app-name',
variant: 'expandable',
theme: {
palette: {
primary: { main: '#3f51b5' },
secondary: { main: '#f50057' }
},
shape: { borderRadius: 12 }
},
fromChain: 1,
toChain: 137,
fromToken: '0x...',
fee: 0.03,
slippage: 0.005,
onRouteExecutionStarted: (route) => {
console.log('Swap started:', route);
},
onRouteExecutionCompleted: (route) => {
console.log('Swap completed:', route);
}
};
function App() {
return (
<div style={{ width: '100%', maxWidth: 500 }}>
<LiFiWidget config={widgetConfig} />
</div>
);
}
Vue.js Integration:
<template>
<div class="widget-container">
<lifi-widget :config="widgetConfig" />
</div>
</template>
<script setup>
import { LiFiWidget } from '@lifi/widget';
const widgetConfig = {
integrator: 'your-app-name',
variant: 'wide',
theme: { palette: { primary: { main: '#42b883' } } }
};
</script>
Vanilla JavaScript:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://unpkg.com/@lifi/widget/dist/widget.css">
</head>
<body>
<div id="lifi-widget"></div>
<script src="https://unpkg.com/@lifi/widget"></script>
<script>
window.lifi.createWidget({
container: document.getElementById('lifi-widget'),
config: {
integrator: 'your-app-name',
variant: 'default'
}
});
</script>
</body>
</html>
See widget_integration.tsx for complete examples.
SDK Integration
Installation:
npm install @lifi/sdk
yarn add @lifi/sdk
pnpm add @lifi/sdk
Basic Swap Flow:
import { LIFI } from '@lifi/sdk';
import { createWalletClient, http } from 'viem';
import { mainnet } from 'viem/chains';
const lifi = new LIFI({
integrator: 'your-app-name',
apiKey: process.env.LIFI_API_KEY
});
const chains = await lifi.getChains();
const tokens = await lifi.getTokens({ chains: [1, 137] });
const routeRequest = {
fromChainId: 1,
fromTokenAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
fromAmount: '1000000000',
toChainId: 137,
toTokenAddress: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',
fromAddress: '0x...',
options: {
slippage: 0.005,
order: 'RECOMMENDED',
allowSwitchChain: true
}
};
const routes = await lifi.getRoutes(routeRequest);
const bestRoute = routes.routes[0];
console.log('Estimated time:', bestRoute.steps.reduce((t, s) => t + s.estimate.executionDuration, 0), 'seconds');
console.log('Gas cost:', bestRoute.gasCostUSD);
console.log('Output amount:', bestRoute.toAmountMin);
const wallet = createWalletClient({
chain: mainnet,
transport: http()
});
if (bestRoute.steps[0].action.fromToken.address !== '0x0000000000000000000000000000000000000000') {
const approvalTx = await lifi.approveToken({
walletClient: wallet,
token: bestRoute.steps[0].action.fromToken,
amount: bestRoute.steps[0].action.fromAmount,
spender: bestRoute.steps[0].estimate.approvalAddress
});
await approvalTx.wait();
}
const execution = await lifi.executeRoute({
route: bestRoute,
walletClient: wallet,
updateRouteHook: (updatedRoute) => {
console.log('Route updated:', updatedRoute.status);
},
switchChainHook: async (requiredChainId) => {
await wallet.switchChain({ id: requiredChainId });
},
acceptExchangeRateUpdateHook: (oldRate, newRate) => {
return confirm(`Rate changed from ${oldRate} to ${newRate}. Continue?`);
}
});
console.log('Swap completed!', execution);
Advanced Route Filtering:
const routes = await lifi.getRoutes({
...routeRequest,
options: {
bridges: { allow: ['stargate', 'across', 'hop'] },
exchanges: { allow: ['uniswap', '1inch'] },
integrator: 'your-app',
fee: 0.03
}
});
See sdk_swap_example.ts for production-ready implementation.
API Integration
Base URL: https://li.quest/v1
Authentication (Optional):
curl -H "x-lifi-api-key: YOUR_API_KEY" https://li.quest/v1/...
Get Route Quote:
const response = await fetch(
'https://li.quest/v1/quote?' + new URLSearchParams({
fromChain: '1',
toChain: '137',
fromToken: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
toToken: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',
fromAmount: '1000000000',
fromAddress: '0x...',
integrator: 'your-app-name',
fee: '0.03',
slippage: '0.005',
order: 'RECOMMENDED'
}),
{
headers: {
'x-lifi-api-key': process.env.LIFI_API_KEY
}
}
);
const quote = await response.json();
console.log('Estimated output:', quote.estimate.toAmount);
console.log('Execution time:', quote.estimate.executionDuration, 'seconds');
console.log('Gas cost:', quote.estimate.gasCosts);
Get Multiple Routes:
const response = await fetch(
'https://li.quest/v1/advanced/routes?' + new URLSearchParams({
fromChainId: '1',
toChainId: '137',
fromTokenAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
toTokenAddress: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',
fromAmount: '1000000000',
fromAddress: '0x...'
})
);
const { routes } = await response.json();
routes.forEach((route, i) => {
console.log(`Route ${i + 1}:`);
console.log(' Steps:', route.steps.length);
console.log(' Time:', route.steps.reduce((t, s) => t + s.estimate.executionDuration, 0));
console.log(' Output:', route.toAmount);
});
Get Supported Chains:
const response = await fetch('https://li.quest/v1/chains');
const chains = await response.json();
chains.forEach(chain => {
console.log(`${chain.name} (${chain.id}): ${chain.nativeToken.symbol}`);
});
Get Supported Tokens:
const response = await fetch(
'https://li.quest/v1/tokens?' + new URLSearchParams({
chains: '1,137,42161'
})
);
const { tokens } = await response.json();
Check Route Status:
const response = await fetch(
'https://li.quest/v1/status?' + new URLSearchParams({
txHash: '0x...',
bridge: 'stargate',
fromChain: '1',
toChain: '137'
})
);
const status = await response.json();
console.log('Status:', status.status);
console.log('Destination tx:', status.receiving?.txHash);
See api_routes_example.ts and api-reference.md.
Gas Subsidy Implementation (LI.Fuel)
Problem: Users bridging to a new chain lack native gas tokens.
Solution: LI.Fuel converts a portion of bridged assets to destination chain's native token.
import { LIFI } from '@lifi/sdk';
const lifi = new LIFI({ integrator: 'your-app' });
const routes = await lifi.getRoutes({
fromChainId: 1,
fromTokenAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
fromAmount: '1000000000',
toChainId: 137,
toTokenAddress: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',
fromAddress: userAddress,
fromAmountForGas: '50000000'
});
const route = routes.routes[0];
const gasStep = route.steps.find(step => step.type === 'lifi');
if (gasStep?.includedSteps?.some(s => s.type === 'swap' && s.action.toToken.address === '0x0000000000000000000000000000000000000000')) {
console.log('Gas subsidy enabled: User will receive native tokens');
}
API Version:
const response = await fetch(
'https://li.quest/v1/quote?' + new URLSearchParams({
fromChain: '1',
toChain: '137',
fromToken: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
toToken: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',
fromAmount: '1000000000',
fromAddress: userAddress,
fromAmountForGas: '50000000'
})
);
Limitations:
- โ Not supported with
/contractCalls endpoint
- โ Not supported via Composer (multi-action transactions)
- โ
Supported via
/quote and /routes endpoints
- โ
Works with SDK's
getRoutes() method
See gas_subsidy_example.ts and gas-subsidy-guide.md.
Fee Monetization
Earn revenue by adding integrator fees to swaps:
const routes = await lifi.getRoutes({
...routeRequest,
integrator: 'your-app-name',
fee: 0.03
});
Fee Collection:
const response = await fetch('https://li.quest/v1/integrators/fees', {
headers: {
'Authorization': 'Bearer YOUR_API_TOKEN',
'x-lifi-api-key': 'YOUR_API_KEY'
}
});
const { fees } = await response.json();
console.log('Collected fees:', fees);
await fetch('https://li.quest/v1/integrators/fees/withdraw', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_TOKEN',
'x-lifi-api-key': 'YOUR_API_KEY'
},
body: JSON.stringify({
token: '0x...',
amount: '1000000000'
})
});
Base Fee Structure:
- LI.FI base fee: 0.25% on all transactions
- Your integrator fee: Configurable (typically 0.1% - 1%)
- User pays: LI.FI fee + your fee + protocol fees (DEX/bridge)
Volume Discounts:
- High-volume integrators can negotiate reduced LI.FI base fees
- Contact LI.FI team for enterprise pricing
Important:
- โ ๏ธ Must withdraw fees from the same wallet used during integration
- โ ๏ธ Switching wallets will lock previous fee claims
- โ
Can set up automatic consolidation and conversion to stablecoins
See monetization-guide.md for complete setup guide.
Critical Security Requirements
Never deploy without:
- Slippage Protection: Always set
slippage parameter (default 0.5% = 0.005)
- Amount Validation: Verify
toAmountMin in routes before execution
- Token Approval Limits: Approve exact amounts, not unlimited allowances
- Rate Limiting: Implement client-side rate limiting for API calls
- Error Handling: Handle network errors, route failures, and bridge delays
- Chain Verification: Verify user is on correct chain before execution
- Transaction Monitoring: Track transaction status across chains
- API Key Protection: Never expose API keys in frontend code (use backend proxy)
- User Confirmation: Show final amounts, fees, and execution time before swap
- Bridge Risk Disclosure: Inform users about bridge security and delays
Widget Security:
const widgetConfig = {
integrator: 'your-app',
infiniteApproval: false,
slippage: 0.005,
bridges: { deny: ['bridge-with-issues'] },
onRouteExecutionStarted: (route) => {
analytics.track('swap_started', {
fromChain: route.fromChainId,
toChain: route.toChainId,
amount: route.fromAmount
});
}
};
SDK Security:
await lifi.approveToken({
token: route.steps[0].action.fromToken,
amount: route.steps[0].action.fromAmount,
spender: route.steps[0].estimate.approvalAddress
});
await lifi.approveToken({
token: route.steps[0].action.fromToken,
amount: ethers.MaxUint256,
spender: route.steps[0].estimate.approvalAddress
});
const rateLimit = {
maxRequests: 10,
perSeconds: 60
};
const routePromise = lifi.getRoutes(request);
const timeoutPromise = new Promise((_, reject) =>
setTimeout(() => reject(new Error('Route timeout')), 30000)
);
try {
const routes = await Promise.race([routePromise, timeoutPromise]);
} catch (error) {
}
See security.md for complete security checklist.
Architecture Patterns
LI.FI Aggregation Architecture
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Your Application (dApp) โ
โ โโโโโโโโโโโ โโโโโโโโโโโ โโโโโโโโโโโ โ
โ โ Widget โ โ SDK โ โ API โ โ
โ โโโโโโฌโโโโโ โโโโโโฌโโโโโ โโโโโโฌโโโโโ โ
โโโโโโโโโผโโโโโโโโโโโโผโโโโโโโโโโโโโผโโโโโโโโโโโโ
โ โ โ
โโโโโโโโโโโโโดโโโโโโโโโโโโโ
โ
โโโโโโโโโโโโโผโโโโโโโโโโโโโ
โ LI.FI Smart Router โ
โ (Route Optimization) โ
โโโโโโโโโโโโโฌโโโโโโโโโโโโโ
โ
โโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโ
โ โ โ
โโโโโผโโโโโ โโโโโโผโโโโโโ โโโโโโผโโโโโ
โ Bridgesโ โ DEX Agg โ โ Solvers โ
โ โ โ โ โ โ
โStargateโ โ Uniswap โ โ 1inch โ
โ Across โ โ Sushiswapโ โ 0x โ
โ Hop โ โ Curve โ โ Kyber โ
โConnext โ โ Balancer โ โ ParaSwapโ
โโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโ
โ โ โ
โโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโ
โ
โโโโโโโโโโผโโโโโโโโโโ
โ 60+ Blockchains โ
โ 800+ Protocols โ
โโโโโโโโโโโโโโโโโโโโ
Integration Decision Tree
Start: Need cross-chain swap/bridge functionality
โ
โโ Need UI component?
โ โ
โ โโ Yes โ Use Widget
โ โ โ
โ โ โโ Basic theme customization โ Widget default config
โ โ โโ Advanced customization โ Widget + custom theme
โ โ โโ Need custom logic โ Widget + SDK hooks
โ โ
โ โโ No โ Need programmatic control?
โ โ
โ โโ TypeScript/JavaScript โ Use SDK
โ โ โ
โ โ โโ Frontend โ SDK + wallet provider
โ โ โโ Backend โ SDK + private key signer
โ โ
โ โโ Other language/platform โ Use REST API
โ โ
โ โโ Python/Go/Ruby โ Direct HTTP
โ โโ Mobile native โ HTTP client
Multi-Step Route Flow
User Swap: 1000 USDC (Ethereum) โ USDT (Arbitrum)
โ
โโ Step 1 (SWAP on Ethereum):
โ โโ 1000 USDC โ 1000 USDT via Uniswap V3
โ
โโ Step 2 (BRIDGE):
โ โโ 1000 USDT (Ethereum) โ 998 USDT (Arbitrum) via Stargate
โ (2 USDT bridge fee)
โ
โโ Result: 998 USDT on Arbitrum
Optional: Gas Subsidy (LI.Fuel)
โ
โโ Step 2a (before bridge):
โ โโ 50 USDT โ 0.05 ETH (for gas on Ethereum)
โ
โโ Step 2b (on destination):
โโ Bridge converts 50 USDT โ ~40 ARB native tokens
โโ User receives: 948 USDT + 40 ARB (for gas)
Rate Limiting Architecture
Without API Key (per IP):
โโ /quote, /routes: 10 requests/minute
โโ /chains, /tokens: 20 requests/minute
โโ /status: 30 requests/minute
With API Key (per key):
โโ /quote, /routes: 100 requests/minute
โโ /chains, /tokens: 200 requests/minute
โโ /status: 300 requests/minute
Enterprise (contact LI.FI):
โโ Custom limits + dedicated infrastructure
Development Setup
Dependencies
Widget Installation:
npm install @lifi/widget
npm install @lifi/widget vue
npm install @lifi/widget svelte
SDK Installation:
npm install @lifi/sdk viem
npm install @lifi/sdk ethers
Additional Tools:
npm install axios
npm install wagmi @wagmi/core viem
npm install @web3-react/core ethers
Environment Setup
LIFI_API_KEY=your_api_key_here
INTEGRATOR_NAME=your-app-name
INTEGRATOR_FEE=0.03
PRIVATE_KEY=0x...
RPC_URL_ETHEREUM=https://eth.llamarpc.com
RPC_URL_POLYGON=https://polygon.llamarpc.com
Supported Chains
EVM Chains (40+):
- Ethereum, Arbitrum, Optimism, Base, Polygon, BSC, Avalanche
- Gnosis, Fantom, Moonbeam, Moonriver, Celo, Aurora, Harmony
- zkSync Era, Polygon zkEVM, Linea, Scroll, Mantle
- And many more...
Non-EVM Chains (20+):
- Solana, Bitcoin (experimental), Cosmos ecosystem
- More being added regularly
Testnet Support:
- Sepolia, Goerli, Mumbai, Arbitrum Goerli, Optimism Goerli
- Check api-reference.md for complete list
Key Contract Addresses
LI.FI uses partner protocols (Uniswap, Stargate, etc.) - no proprietary contracts to deploy.
Integration Contracts (for advanced use):
- LI.FI Diamond Proxy:
0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE (multi-chain)
- Receiver Contract: Varies by chain
Token Addresses (commonly used):
- USDC (Ethereum):
0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
- USDC (Polygon):
0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359
- USDC (Arbitrum):
0xaf88d065e77c8cC2239327C5EDb3A432268e5831
- USDC (Optimism):
0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85
- Native tokens: Use
0x0000000000000000000000000000000000000000
See api-reference.md for complete address list.
Testing
Widget Testing (React Testing Library)
import { render, screen, waitFor } from '@testing-library/react';
import { LiFiWidget } from '@lifi/widget';
describe('LiFi Widget Integration', () => {
it('should render widget with custom config', () => {
const config = {
integrator: 'test-app',
variant: 'wide',
fromChain: 1,
toChain: 137
};
render(<LiFiWidget config={config} />);
expect(screen.getByTestId('lifi-widget')).toBeInTheDocument();
});
it('should call onRouteExecutionCompleted', async () => {
const onComplete = jest.fn();
const config = {
integrator: 'test-app',
onRouteExecutionCompleted: onComplete
};
render(<LiFiWidget config={config} />);
await waitFor(() => {
expect(onComplete).toHaveBeenCalled();
});
});
});
SDK Testing (Jest/Vitest)
import { LIFI } from '@lifi/sdk';
import { describe, it, expect, beforeEach } from 'vitest';
describe('LI.FI SDK', () => {
let lifi: LIFI;
beforeEach(() => {
lifi = new LIFI({
integrator: 'test-app'
});
});
it('should fetch available chains', async () => {
const chains = await lifi.getChains();
expect(chains.length).toBeGreaterThan(0);
expect(chains[0]).toHaveProperty('id');
expect(chains[0]).toHaveProperty('name');
});
it('should get routes for valid swap', async () => {
const routes = await lifi.getRoutes({
fromChainId: 1,
fromTokenAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
fromAmount: '1000000000',
toChainId: 137,
toTokenAddress: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',
fromAddress: '0x1234567890123456789012345678901234567890'
});
expect(routes.routes.length).toBeGreaterThan(0);
expect(routes.routes[0]).toHaveProperty('fromAmount');
expect(routes.routes[0]).toHaveProperty('toAmount');
});
it('should handle invalid route request', async () => {
await expect(
lifi.getRoutes({
fromChainId: 1,
fromTokenAddress: '0xinvalid',
fromAmount: '1000000000',
toChainId: 137,
toTokenAddress: '0x...',
fromAddress: '0x...'
})
).rejects.toThrow();
});
});
API Testing (curl)
curl https://li.quest/v1/chains | jq '.[0]'
curl "https://li.quest/v1/quote?fromChain=1&toChain=137&fromToken=0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48&toToken=0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359&fromAmount=1000000000&fromAddress=0x1234567890123456789012345678901234567890" \
-H "x-lifi-api-key: YOUR_API_KEY" | jq '.estimate'
curl "https://li.quest/v1/quote?fromChain=1&toChain=137&fromToken=0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48&toToken=0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359&fromAmount=1000000000&fromAddress=0x...&integrator=test-app&fee=0.03" | jq '.estimate.feeCosts'
E2E Testing (Playwright)
import { test, expect } from '@playwright/test';
test('complete swap flow with widget', async ({ page }) => {
await page.goto('http://localhost:3000');
await page.waitForSelector('#lifi-widget');
await page.fill('input[name="fromAmount"]', '100');
await page.selectOption('select[name="fromChain"]', '1');
await page.selectOption('select[name="toChain"]', '137');
await page.click('button:has-text("Swap")');
await expect(page.locator('.route-summary')).toBeVisible();
await expect(page.locator('.estimated-output')).toContainText('USDC');
});
Common Pitfalls
-
Missing integrator name: Required for analytics and fee collection
const lifi = new LIFI({});
const lifi = new LIFI({ integrator: 'your-app-name' });
-
Ignoring route execution status: Always monitor multi-step routes
await lifi.executeRoute({ route, walletClient });
const execution = await lifi.executeRoute({
route,
walletClient,
updateRouteHook: (route) => {
console.log('Step', route.steps.findIndex(s => s.execution?.status === 'PENDING'));
}
});
-
Not handling chain switches: Cross-chain swaps require chain switching
const execution = await lifi.executeRoute({
route,
walletClient,
switchChainHook: async (chainId) => {
await walletClient.switchChain({ id: chainId });
}
});
-
Unlimited token approvals: Security risk
await token.approve(spender, ethers.MaxUint256);
await lifi.approveToken({
token: route.steps[0].action.fromToken,
amount: route.steps[0].action.fromAmount,
spender: route.steps[0].estimate.approvalAddress
});
-
Exposing API keys in frontend: Use backend proxy
const lifi = new LIFI({
apiKey: 'pk_live_...'
});
const routes = await fetch('/api/lifi/routes', {
method: 'POST',
body: JSON.stringify(routeRequest)
});
const lifi = new LIFI({
apiKey: process.env.LIFI_API_KEY
});
-
Not handling bridge delays: Some bridges take hours
console.log('Estimated time:', route.steps.reduce(
(total, step) => total + step.estimate.executionDuration,
0
), 'seconds');
if (route.steps.some(s => s.estimate.executionDuration > 3600)) {
alert('This route may take over 1 hour. Continue?');
}
-
Wrong fee format: Use decimal, not percentage
fee: 3
fee: 0.03
-
Ignoring rate limits: Will get throttled
const rateLimiter = new RateLimiter({
maxRequests: 10,
perSeconds: 60
});
await rateLimiter.throttle();
const routes = await lifi.getRoutes(request);
-
Not validating user inputs: Can cause API errors
if (!ethers.isAddress(fromAddress)) {
throw new Error('Invalid address');
}
if (BigInt(fromAmount) <= 0) {
throw new Error('Amount must be positive');
}
-
Gas subsidy with contractCalls: Not supported
const routes = await lifi.getRoutes({
...request,
contractCalls: [...],
fromAmountForGas: '50000000'
});
const routes = await lifi.getRoutes({
...request,
fromAmountForGas: '50000000'
});
Resources
Official Documentation
Integration Guides
Tools & Dashboards
Code Examples
Support
Bundled Resources
Scripts
References
Assets
Support Context7 Integration
When the user needs up-to-date documentation or specific implementation details not covered in this skill:
- Use LI.FI official docs as primary source: https://docs.li.fi/
- For SDK-specific questions: Use Context7 with "@lifi/sdk"
- For Widget customization: Use Context7 with "@lifi/widget"
- Combine Context7 results with this skill's security guidelines
Example:
User: "How do I customize the widget theme for dark mode?"
โ Check widget-guide.md for theme basics
โ Use Context7: query-docs with "@lifi/widget" for latest theme options
โ Apply security patterns from security.md for safe integration
Advanced Topics
Multi-Chain Portfolio Management
Track user balances across all chains:
import { LIFI } from '@lifi/sdk';
async function getMultiChainBalances(userAddress: string) {
const lifi = new LIFI({ integrator: 'portfolio-app' });
const chains = await lifi.getChains();
const balances = await Promise.all(
chains.map(async (chain) => {
const tokens = await lifi.getTokenBalances(userAddress, [chain.id]);
return {
chain: chain.name,
tokens: tokens.filter(t => parseFloat(t.amount) > 0)
};
})
);
return balances.filter(b => b.tokens.length > 0);
}
Route Optimization Strategies
const routes = await lifi.getRoutes({
...baseRequest,
options: {
order: 'RECOMMENDED'
}
});
const comparison = routes.routes.map(route => ({
id: route.id,
outputAmount: route.toAmount,
executionTime: route.steps.reduce((t, s) => t + s.estimate.executionDuration, 0),
gasCostUSD: route.gasCostUSD,
steps: route.steps.length
}));
const bestByOutput = [...comparison].sort((a, b) =>
parseFloat(b.outputAmount) - parseFloat(a.outputAmount)
)[0];
const bestByTime = [...comparison].sort((a, b) =>
a.executionTime - b.executionTime
)[0];
Custom Event Tracking
const widgetConfig = {
integrator: 'analytics-app',
onRouteHighValueLoss: (route, loss) => {
analytics.track('high_value_loss_warning', {
expectedOutput: route.toAmount,
actualOutput: route.toAmountMin,
lossAmount: loss
});
},
onRouteExecutionStarted: (route) => {
analytics.track('swap_started', {
fromChain: route.fromChainId,
toChain: route.toChainId,
fromToken: route.fromToken.symbol,
toToken: route.toToken.symbol,
amount: route.fromAmount
});
},
onRouteExecutionCompleted: (route) => {
analytics.track('swap_completed', {
routeId: route.id,
executionTime: Date.now() - route.executionStartedAt,
actualOutput: route.toAmountMin
});
},
onRouteExecutionFailed: (route, error) => {
analytics.track('swap_failed', {
routeId: route.id,
error: error.message,
step: route.steps.findIndex(s => s.execution?.status === 'FAILED')
});
}
};
Webhook Integration (Backend)
import express from 'express';
import { createHmac } from 'crypto';
const app = express();
app.post('/webhooks/lifi', express.json(), (req, res) => {
const signature = req.headers['x-lifi-signature'];
const payload = JSON.stringify(req.body);
const expectedSignature = createHmac('sha256', process.env.LIFI_WEBHOOK_SECRET)
.update(payload)
.digest('hex');
if (signature !== expectedSignature) {
return res.status(401).send('Invalid signature');
}
const { event, data } = req.body;
switch (event) {
case 'route.completed':
console.log('Route completed:', data.routeId);
break;
case 'route.failed':
console.log('Route failed:', data.routeId, data.error);
break;
case 'fee.collected':
console.log('Fee collected:', data.amount, data.token);
break;
}
res.status(200).send('OK');
});
Performance Optimization
Caching Strategies
import { LRUCache } from 'lru-cache';
const chainCache = new LRUCache({
max: 100,
ttl: 1000 * 60 * 60
});
async function getChainsWithCache() {
const cached = chainCache.get('chains');
if (cached) return cached;
const lifi = new LIFI({ integrator: 'your-app' });
const chains = await lifi.getChains();
chainCache.set('chains', chains);
return chains;
}
const routeCache = new LRUCache({
max: 50,
ttl: 1000 * 30
});
async function getRoutesWithCache(request) {
const cacheKey = JSON.stringify(request);
const cached = routeCache.get(cacheKey);
if (cached) return cached;
const lifi = new LIFI({ integrator: 'your-app' });
const routes = await lifi.getRoutes(request);
routeCache.set(cacheKey, routes);
return routes;
}
Parallel Route Fetching
async function getMultipleRoutes(requests) {
const lifi = new LIFI({ integrator: 'your-app' });
const routePromises = requests.map(request =>
lifi.getRoutes(request).catch(err => ({
error: err.message,
request
}))
);
const results = await Promise.all(routePromises);
return results.filter(r => !r.error);
}
const routes = await getMultipleRoutes([
{ fromChainId: 1, toChainId: 137, ... },
{ fromChainId: 1, toChainId: 42161, ... },
{ fromChainId: 137, toChainId: 10, ... }
]);
Widget Performance
import { lazy, Suspense } from 'react';
const LiFiWidget = lazy(() => import('@lifi/widget').then(m => ({ default: m.LiFiWidget })));
function App() {
return (
<Suspense fallback={<div>Loading swap widget...</div>}>
<LiFiWidget config={widgetConfig} />
</Suspense>
);
}
Migration Guides
From 0x API to LI.FI
const response = await fetch(
`https://api.0x.org/swap/v1/quote?` + new URLSearchParams({
sellToken: 'ETH',
buyToken: 'DAI',
sellAmount: '1000000000000000000'
})
);
const lifi = new LIFI({ integrator: 'migrated-from-0x' });
const routes = await lifi.getRoutes({
fromChainId: 1,
fromTokenAddress: '0x0000000000000000000000000000000000000000',
fromAmount: '1000000000000000000',
toChainId: 1,
toTokenAddress: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
fromAddress: userAddress
});
const bestRoute = routes.routes[0];
From 1inch API to LI.FI
const response = await fetch(
`https://api.1inch.dev/swap/v5.2/1/quote?` + new URLSearchParams({
src: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE',
dst: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
amount: '1000000000000000000'
}),
{ headers: { 'Authorization': `Bearer ${API_KEY}` } }
);
const routes = await lifi.getRoutes({
fromChainId: 1,
fromTokenAddress: '0x0000000000000000000000000000000000000000',
fromAmount: '1000000000000000000',
toChainId: 1,
toTokenAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
fromAddress: userAddress,
options: {
exchanges: { allow: ['1inch', 'uniswap', 'sushiswap'] }
}
});
Enterprise Features
For high-volume applications, contact LI.FI for:
- Dedicated Infrastructure: Private RPC nodes and dedicated API instances
- Custom Rate Limits: Higher throughput for enterprise needs
- Volume Discounts: Reduced fees for high transaction volumes
- Priority Support: Dedicated technical support and integration assistance
- Custom Analytics: Advanced reporting and monitoring dashboards
- SLA Guarantees: Uptime and performance guarantees
Contact: partnerships@li.fi