li-fi-sdk
npx skills add https://github.com/lifinance/lifi-agent-skills --skill li-fi-sdk
Agent 安装分布
Skill 文档
LI.FI SDK Integration
The LI.FI SDK (@lifi/sdk) is a TypeScript/JavaScript toolkit for cross-chain and on-chain swaps and bridging. It provides complete functionality from obtaining routes/quotes to executing transactions across 30+ blockchain networks.
Installation
# Using yarn
yarn add @lifi/sdk
# Using npm
npm install @lifi/sdk
# Using pnpm
pnpm add @lifi/sdk
# Using bun
bun add @lifi/sdk
Quick Start
1. Configure the SDK
import { createConfig } from '@lifi/sdk';
createConfig({
integrator: 'YourAppName', // Required: identifies your application
});
2. Request a Quote
import { getQuote } from '@lifi/sdk';
const quote = await getQuote({
fromChain: 42161, // Arbitrum
toChain: 10, // Optimism
fromToken: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831', // USDC on Arbitrum
toToken: '0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1', // DAI on Optimism
fromAmount: '10000000', // 10 USDC (6 decimals)
fromAddress: '0xYourWalletAddress',
});
3. Execute the Transfer
import { executeRoute, convertQuoteToRoute } from '@lifi/sdk';
const route = convertQuoteToRoute(quote);
const executedRoute = await executeRoute(route, {
updateRouteHook(updatedRoute) {
console.log('Route updated:', updatedRoute);
},
});
Core Concepts
Routes vs Quotes
getQuote(): Returns single best option with transaction data ready. Use for simple transfers.getRoutes(): Returns multiple options for comparison. Use when presenting choices to users.
See references/REFERENCE.md for chain IDs, token addresses, and parameter tables.
SDK Configuration
Basic Configuration
import { createConfig } from '@lifi/sdk';
createConfig({
integrator: 'YourAppName',
apiKey: 'your-api-key', // Optional: for higher rate limits
});
Advanced Configuration
import { createConfig, ChainType } from '@lifi/sdk';
createConfig({
integrator: 'YourAppName',
apiKey: 'your-api-key',
rpcUrls: {
1: ['https://your-ethereum-rpc.com'],
137: ['https://your-polygon-rpc.com'],
},
chains: {
allow: [1, 10, 137, 42161], // Only allow specific chains
},
preloadChains: true, // Preload chain data for faster initial requests
});
Requesting Routes and Quotes
Get Multiple Routes
import { getRoutes, RoutesRequest } from '@lifi/sdk';
const routesRequest: RoutesRequest = {
fromChainId: 42161,
toChainId: 10,
fromTokenAddress: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',
toTokenAddress: '0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1',
fromAmount: '10000000',
fromAddress: '0xYourAddress', // Optional for routes
options: {
slippage: 0.005, // 0.5% slippage
order: 'CHEAPEST', // or 'FASTEST'
},
};
const result = await getRoutes(routesRequest);
const routes = result.routes;
Get Single Best Quote
import { getQuote, QuoteRequest } from '@lifi/sdk';
const quoteRequest: QuoteRequest = {
fromChain: 42161,
toChain: 10,
fromToken: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',
toToken: '0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1',
fromAmount: '10000000',
fromAddress: '0xYourAddress', // Required for quotes
slippage: 0.005,
};
const quote = await getQuote(quoteRequest);
Route Options
const options = {
slippage: 0.005, // 0.5% slippage tolerance
order: 'CHEAPEST', // 'CHEAPEST' or 'FASTEST'
maxPriceImpact: 0.3, // Hide routes with >30% price impact
allowSwitchChain: true, // Allow 2-step routes
integrator: 'YourApp',
fee: 0.03, // 3% integrator fee (requires verification)
// Bridge/exchange preferences
bridges: {
allow: ['stargate', 'hop'], // Only use these bridges
deny: ['multichain'], // Never use these bridges
prefer: ['stargate'], // Prefer if available
},
exchanges: {
allow: ['1inch', 'uniswap'],
deny: ['sushiswap'],
},
};
Executing Transactions
Basic Execution
import { executeRoute } from '@lifi/sdk';
const executedRoute = await executeRoute(route, {
updateRouteHook(updatedRoute) {
// Called on every route state change
console.log('Status:', updatedRoute.steps[0]?.execution?.status);
},
});
Execution with All Hooks
import { executeRoute } from '@lifi/sdk';
const executedRoute = await executeRoute(route, {
// Track route updates
updateRouteHook(updatedRoute) {
const step = updatedRoute.steps[0];
const process = step?.execution?.process;
const latestProcess = process?.[process.length - 1];
console.log('Status:', latestProcess?.status);
console.log('TX Hash:', latestProcess?.txHash);
},
// Handle exchange rate changes (important!)
acceptExchangeRateUpdateHook(toToken, oldAmount, newAmount) {
const oldValue = parseFloat(oldAmount);
const newValue = parseFloat(newAmount);
const percentChange = ((newValue - oldValue) / oldValue) * 100;
// Accept if change is less than 2%
if (Math.abs(percentChange) < 2) {
return Promise.resolve(true);
}
// Prompt user for larger changes
return promptUserToAccept(percentChange);
},
// Handle chain switching (for 2-step routes)
async switchChainHook(chainId) {
await walletClient.switchChain({ id: chainId });
return walletClient;
},
// Modify transaction before sending (advanced)
async updateTransactionRequestHook(txRequest) {
return {
...txRequest,
gas: txRequest.gas ? BigInt(txRequest.gas) * 120n / 100n : undefined,
};
},
});
Execute a Quote
import { getQuote, convertQuoteToRoute, executeRoute } from '@lifi/sdk';
// Get quote
const quote = await getQuote(quoteRequest);
// Convert to route for execution
const route = convertQuoteToRoute(quote);
// Execute
const result = await executeRoute(route);
Managing Execution Lifecycle
Resume Interrupted Execution
import { resumeRoute } from '@lifi/sdk';
// Resume from the last saved route state
const resumedRoute = await resumeRoute(savedRoute, {
updateRouteHook(route) {
console.log('Resumed execution:', route);
},
});
Background Execution
import { executeRoute, updateRouteExecution } from '@lifi/sdk';
// Start execution
const routePromise = executeRoute(route, {
updateRouteHook(route) {
saveRouteState(route); // Persist state
},
});
// Move to background (e.g., user navigates away)
updateRouteExecution(route, { executeInBackground: true });
// Later: resume in foreground
const resumedRoute = await resumeRoute(savedRoute, {
executeInBackground: false,
});
Stop Execution
import { stopRouteExecution } from '@lifi/sdk';
// Stop execution (already-sent transactions will complete on-chain)
const stoppedRoute = stopRouteExecution(route);
Get Active Routes
import { getActiveRoutes, getActiveRoute } from '@lifi/sdk';
// Get all active routes
const activeRoutes = getActiveRoutes();
// Get specific active route
const activeRoute = getActiveRoute(routeId);
Chain and Token Discovery
Get Available Chains
import { getChains, ChainType } from '@lifi/sdk';
// Get all chains
const allChains = await getChains();
// Get only EVM chains
const evmChains = await getChains({ chainTypes: [ChainType.EVM] });
Get Available Tokens
import { getTokens, getToken } from '@lifi/sdk';
// Get all tokens for a chain
const tokens = await getTokens({ chains: [1, 137] });
// Get specific token
const usdc = await getToken(1, '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48');
Get Available Tools (Bridges/DEXs)
import { getTools } from '@lifi/sdk';
const tools = await getTools();
console.log('Bridges:', tools.bridges);
console.log('Exchanges:', tools.exchanges);
Get Connections
import { getConnections } from '@lifi/sdk';
// Find all possible routes from ETH on Ethereum
const connections = await getConnections({
fromChain: 1,
fromToken: '0x0000000000000000000000000000000000000000', // Native ETH
});
Multi-VM Provider Setup
EVM Provider (Viem)
import { createConfig, EVM } from '@lifi/sdk';
import { createWalletClient, http } from 'viem';
import { mainnet } from 'viem/chains';
const walletClient = createWalletClient({
chain: mainnet,
transport: http(),
});
createConfig({
integrator: 'YourApp',
providers: [
EVM({ getWalletClient: () => Promise.resolve(walletClient) }),
],
});
Solana Provider
import { createConfig, Solana } from '@lifi/sdk';
createConfig({
integrator: 'YourApp',
providers: [
Solana({ getWalletAdapter: () => Promise.resolve(walletAdapter) }),
],
});
Contract Calls (Composer)
Execute contract calls on the destination chain after bridging:
import { getContractCallsQuote } from '@lifi/sdk';
const contractCallQuote = await getContractCallsQuote({
fromAddress: '0xYourAddress',
fromChain: 10, // Optimism
fromToken: '0x0000000000000000000000000000000000000000',
toAmount: '8500000000000',
toChain: 8453, // Base
toToken: '0x0000000000000000000000000000000000000000',
contractCalls: [{
fromAmount: '8500000000000',
fromTokenAddress: '0x0000000000000000000000000000000000000000',
toContractAddress: '0xTargetContract',
toContractCallData: '0x...', // Encoded function call
toContractGasLimit: '210000',
}],
});
Error Handling
import { executeRoute } from '@lifi/sdk';
try {
const result = await executeRoute(route, {
acceptExchangeRateUpdateHook: () => Promise.resolve(true),
});
} catch (error) {
if (error.message.includes('Exchange rate has changed')) {
// Handle rate change rejection
} else if (error.message.includes('insufficient funds')) {
// Handle balance issues
} else if (error.message.includes('user rejected')) {
// Handle user cancellation
} else {
// Handle other errors
console.error('Execution failed:', error);
}
}
Best Practices
-
Always implement
acceptExchangeRateUpdateHook– Exchange rates can change during execution. Without this hook, execution fails on rate changes. -
Persist route state – Use
updateRouteHookto save route state for recovery after page refreshes or app restarts. -
Handle chain switching – For cross-chain routes, implement
switchChainHookto handle wallet chain switches. -
Use appropriate slippage – Default 0.5% (0.005) works for most cases. Increase for volatile tokens or low-liquidity pairs.
-
Set integrator name – Always configure
integratorfor analytics and potential monetization. -
Check token allowances – The SDK handles allowances automatically, but you may want to show approval UI to users.
-
Monitor gas prices – Use
updateTransactionRequestHookto adjust gas if needed.
See references/REFERENCE.md for detailed parameter tables and TypeScript interfaces.