toToken 设置为协议的代币地址,LI.FI 就会处理交换、桥接以及最终的存入。
下面的每个 recipe 都是端到端的:请求报价、授权代币、签署交易、确认存入。
所有示例均使用
GET /quote。相同的 toToken 地址也适用于 POST /advanced/routes 和 LI.FI SDK。完整的集成指南请参阅 API
Integration 或 SDK
Integration。同链:USDC → Morpho Vault(Base)
将 1 USDC 存入 Base 上由 Spark 策划的 Morpho USDC vault。curl -X GET 'https://li.quest/v1/quote?fromChain=8453&toChain=8453&fromToken=0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913&toToken=0x7BfA7C4f149E7415b73bdeDfe609237e29CBF34A&fromAddress=0xYOUR_WALLET_ADDRESS&toAddress=0xYOUR_WALLET_ADDRESS&fromAmount=1000000'
import axios from "axios";
import { erc20Abi, type Address, type Hex } from "viem";
const API_URL = "https://li.quest/v1";
// Assumes publicClient and walletClient are configured (see the API Integration guide)
const [account] = await walletClient.getAddresses();
// 1. Get a Composer quote
const { data: quote } = await axios.get(`${API_URL}/quote`, {
params: {
fromChain: 8453,
toChain: 8453,
fromToken: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", // USDC on Base
toToken: "0x7BfA7C4f149E7415b73bdeDfe609237e29CBF34A", // Morpho vault token (sparkUSDC)
fromAddress: account,
toAddress: account,
fromAmount: "1000000", // 1 USDC (6 decimals)
slippage: 0.005,
},
});
console.log("Tool:", quote.tool); // "composer"
console.log("Estimated output:", quote.estimate.toAmount);
console.log("Approval target:", quote.estimate.approvalAddress);
// 2. Approve the LI.FI Diamond to spend your tokens
const allowance = await publicClient.readContract({
address: quote.action.fromToken.address as Address,
abi: erc20Abi,
functionName: "allowance",
args: [account, quote.estimate.approvalAddress as Address],
});
if (allowance < BigInt(quote.action.fromAmount)) {
const approveHash = await walletClient.writeContract({
address: quote.action.fromToken.address as Address,
abi: erc20Abi,
functionName: "approve",
args: [
quote.estimate.approvalAddress as Address,
BigInt(quote.action.fromAmount),
],
account,
chain: walletClient.chain,
});
await publicClient.waitForTransactionReceipt({ hash: approveHash });
console.log("Approval confirmed.");
}
// 3. Sign and send the transaction
const hash = await walletClient.sendTransaction({
account,
to: quote.transactionRequest.to as Address,
data: quote.transactionRequest.data as Hex,
value: BigInt(quote.transactionRequest.value),
gas: BigInt(quote.transactionRequest.gasLimit),
gasPrice: BigInt(quote.transactionRequest.gasPrice),
chain: walletClient.chain,
});
console.log("Tx hash:", hash);
const receipt = await publicClient.waitForTransactionReceipt({ hash });
console.log("Confirmed in block:", receipt.blockNumber);
toToken 替换为支持的协议参考文档中列出的任意地址即可。其他一切保持不变。
同链:USDC → Aave(Ethereum)
将 1000 USDC 存入 Ethereum 上的 Aave V3,并收到 aUSDC。curl -X GET 'https://li.quest/v1/quote?\
fromChain=1&\
toChain=1&\
fromToken=0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48&\
toToken=0x98C23E9d8f34FEFb1B7BD6a91B7FF122F4e16F5c&\
fromAddress=0xYOUR_WALLET_ADDRESS&\
toAddress=0xYOUR_WALLET_ADDRESS&\
fromAmount=1000000000&\
slippage=0.005'
const { data: quote } = await axios.get(`${API_URL}/quote`, {
params: {
fromChain: 1, // Ethereum
toChain: 1, // Ethereum
fromToken: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC on Ethereum
toToken: "0x98C23E9d8f34FEFb1B7BD6a91B7FF122F4e16F5c", // aEthUSDC (Aave V3)
fromAddress: account,
toAddress: account,
fromAmount: "1000000000", // 1000 USDC (6 decimals)
slippage: 0.005,
},
});
// Approve + send (same pattern as the Morpho example above)
const allowance = await publicClient.readContract({
address: quote.action.fromToken.address as Address,
abi: erc20Abi,
functionName: "allowance",
args: [account, quote.estimate.approvalAddress as Address],
});
if (allowance < BigInt(quote.action.fromAmount)) {
const approveHash = await walletClient.writeContract({
address: quote.action.fromToken.address as Address,
abi: erc20Abi,
functionName: "approve",
args: [
quote.estimate.approvalAddress as Address,
BigInt(quote.action.fromAmount),
],
account,
chain: walletClient.chain,
});
await publicClient.waitForTransactionReceipt({ hash: approveHash });
}
const hash = await walletClient.sendTransaction({
account,
to: quote.transactionRequest.to as Address,
data: quote.transactionRequest.data as Hex,
value: BigInt(quote.transactionRequest.value),
gas: BigInt(quote.transactionRequest.gasLimit),
gasPrice: BigInt(quote.transactionRequest.gasPrice),
chain: walletClient.chain,
});
const receipt = await publicClient.waitForTransactionReceipt({ hash });
console.log("aEthUSDC received. Tx:", receipt.transactionHash);
同链:USDe → Ethena 上的 sUSDe(Ethereum)
将 USDe 存入 Ethena 的质押版 USDe(sUSDe)以获取收益。curl -X GET 'https://li.quest/v1/quote?\
fromChain=1&\
toChain=1&\
fromToken=0x4c9EDD5852cd905f086C759E8383e09bff1E68B3&\
toToken=0x9D39A5DE30e57443BfF2A8307A4256c8797A3497&\
fromAddress=0xYOUR_WALLET_ADDRESS&\
toAddress=0xYOUR_WALLET_ADDRESS&\
fromAmount=1000000000000000000000&\
slippage=0.005'
const { data: quote } = await axios.get(`${API_URL}/quote`, {
params: {
fromChain: 1,
toChain: 1,
fromToken: "0x4c9EDD5852cd905f086C759E8383e09bff1E68B3", // USDe
toToken: "0x9D39A5DE30e57443BfF2A8307A4256c8797A3497", // sUSDe (Ethena)
fromAddress: account,
toAddress: account,
fromAmount: "1000000000000000000000", // 1000 USDe (18 decimals)
slippage: 0.005,
},
});
// Approve + send (same pattern as the Morpho example above)
同链:USDC → Euler eUSDC-2(Ethereum)
将 USDC 存入 Ethereum 上 Euler V2 的 USDC 借贷 vault,并收到 eUSDC-2。curl -X GET 'https://li.quest/v1/quote?\
fromChain=1&\
toChain=1&\
fromToken=0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48&\
toToken=0x797DD80692c3b2dAdabCe8e30C07fDE5307D48a9&\
fromAddress=0xYOUR_WALLET_ADDRESS&\
toAddress=0xYOUR_WALLET_ADDRESS&\
fromAmount=1000000000&\
slippage=0.005'
const { data: quote } = await axios.get(`${API_URL}/quote`, {
params: {
fromChain: 1, // Ethereum
toChain: 1, // Ethereum
fromToken: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC on Ethereum
toToken: "0x797DD80692c3b2dAdabCe8e30C07fDE5307D48a9", // eUSDC-2 (Euler V2)
fromAddress: account,
toAddress: account,
fromAmount: "1000000000", // 1000 USDC (6 decimals)
slippage: 0.005,
},
});
// Approve + send (same pattern as the Morpho example above)
同链:USDC → Maple 上的 syrupUSDC(Ethereum)
将 USDC 存入 Ethereum 上 Maple Finance 的 Syrup USDC 资金池,并收到 syrupUSDC。curl -X GET 'https://li.quest/v1/quote?\
fromChain=1&\
toChain=1&\
fromToken=0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48&\
toToken=0x80ac24aA929eaF5013f6436cdA2a7ba190f5Cc0b&\
fromAddress=0xYOUR_WALLET_ADDRESS&\
toAddress=0xYOUR_WALLET_ADDRESS&\
fromAmount=1000000000&\
slippage=0.005'
const { data: quote } = await axios.get(`${API_URL}/quote`, {
params: {
fromChain: 1, // Ethereum
toChain: 1, // Ethereum
fromToken: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC on Ethereum
toToken: "0x80ac24aA929eaF5013f6436cdA2a7ba190f5Cc0b", // syrupUSDC (Maple)
fromAddress: account,
toAddress: account,
fromAmount: "1000000000", // 1000 USDC (6 decimals)
slippage: 0.005,
},
});
// Approve + send (same pattern as the Morpho example above)
跨链:ETH(Ethereum)→ Morpho Vault(Base)
将 ETH 从 Ethereum 存入 Base 上的 Morpho vault。LI.FI 会处理桥接、中间交换和存入。curl -X GET 'https://li.quest/v1/quote?fromChain=1&toChain=8453&fromToken=0x0000000000000000000000000000000000000000&toToken=0x7BfA7C4f149E7415b73bdeDfe609237e29CBF34A&fromAddress=0xYOUR_WALLET_ADDRESS&toAddress=0xYOUR_WALLET_ADDRESS&fromAmount=100000000000000000'
// 1. Get cross-chain quote
const { data: quote } = await axios.get(`${API_URL}/quote`, {
params: {
fromChain: 1, // Ethereum
toChain: 8453, // Base
fromToken: "0x0000000000000000000000000000000000000000", // ETH
toToken: "0x7BfA7C4f149E7415b73bdeDfe609237e29CBF34A", // Morpho vault on Base
fromAddress: account,
toAddress: account,
fromAmount: "100000000000000000", // 0.1 ETH
slippage: 0.01, // 1% for cross-chain
},
});
// 2. No approval needed for native ETH
// 3. Send the source chain transaction
const hash = await walletClient.sendTransaction({
account,
to: quote.transactionRequest.to as Address,
data: quote.transactionRequest.data as Hex,
value: BigInt(quote.transactionRequest.value),
gas: BigInt(quote.transactionRequest.gasLimit),
gasPrice: BigInt(quote.transactionRequest.gasPrice),
chain: walletClient.chain,
});
await publicClient.waitForTransactionReceipt({ hash });
console.log("Source tx confirmed:", hash);
// 4. Poll status until the cross-chain transfer completes
let status;
do {
const { data } = await axios.get(`${API_URL}/status`, {
params: {
txHash: hash,
fromChain: quote.action.fromChainId,
toChain: quote.action.toChainId,
},
});
status = data;
console.log(`Status: ${status.status} ${status.substatus || ""}`);
if (status.status !== "DONE" && status.status !== "FAILED") {
await new Promise((r) => setTimeout(r, 5000));
}
} while (status.status !== "DONE" && status.status !== "FAILED");
console.log("Final:", status.status);
跨链转账需要通过
GET /status 进行状态轮询。有关完整的执行 flow 和部分失败处理,请参阅
跨链 Composer 模式。跨链:USDC(Ethereum)→ Morpho Vault(Base)
将 USDC 从 Ethereum 桥接过来并存入 Base 上由 Spark 策划的 Morpho vault。LI.FI 在单个 flow 中处理桥接和最终存入。curl -X GET 'https://li.quest/v1/quote?fromChain=1&toChain=8453&fromToken=0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48&toToken=0x7BfA7C4f149E7415b73bdeDfe609237e29CBF34A&fromAddress=0xYOUR_WALLET_ADDRESS&toAddress=0xYOUR_WALLET_ADDRESS&fromAmount=1000000000'
const { data: quote } = await axios.get(`${API_URL}/quote`, {
params: {
fromChain: 1, // Ethereum
toChain: 8453, // Base
fromToken: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC on Ethereum
toToken: "0x7BfA7C4f149E7415b73bdeDfe609237e29CBF34A", // Morpho vault on Base
fromAddress: account,
toAddress: account,
fromAmount: "1000000000", // 1000 USDC (6 decimals)
slippage: 0.01,
},
});
// Approve USDC on Ethereum
const allowance = await publicClient.readContract({
address: quote.action.fromToken.address as Address,
abi: erc20Abi,
functionName: "allowance",
args: [account, quote.estimate.approvalAddress as Address],
});
if (allowance < BigInt(quote.action.fromAmount)) {
const approveHash = await walletClient.writeContract({
address: quote.action.fromToken.address as Address,
abi: erc20Abi,
functionName: "approve",
args: [
quote.estimate.approvalAddress as Address,
BigInt(quote.action.fromAmount),
],
account,
chain: walletClient.chain,
});
await publicClient.waitForTransactionReceipt({ hash: approveHash });
}
// Send source chain transaction
const hash = await walletClient.sendTransaction({
account,
to: quote.transactionRequest.to as Address,
data: quote.transactionRequest.data as Hex,
value: BigInt(quote.transactionRequest.value),
gas: BigInt(quote.transactionRequest.gasLimit),
gasPrice: BigInt(quote.transactionRequest.gasPrice),
chain: walletClient.chain,
});
await publicClient.waitForTransactionReceipt({ hash });
console.log("Source tx confirmed:", hash);
// Poll until cross-chain transfer completes
let status;
do {
const { data } = await axios.get(`${API_URL}/status`, {
params: { txHash: hash, fromChain: 1, toChain: 8453 },
});
status = data;
if (status.status !== "DONE" && status.status !== "FAILED") {
await new Promise((r) => setTimeout(r, 5000));
}
} while (status.status !== "DONE" && status.status !== "FAILED");
console.log("Final status:", status.status);
Felix Vanilla Vaults
Felix Vanilla vault 支持存入和提款。同链:存入 Felix Vanilla Vault
curl -X GET 'https://li.quest/v1/quote?fromChain=CHAIN_ID&toChain=CHAIN_ID&fromToken=SOURCE_TOKEN_ADDRESS&toToken=FELIX_VAULT_TOKEN_ADDRESS&fromAddress=0xYOUR_WALLET_ADDRESS&toAddress=0xYOUR_WALLET_ADDRESS&fromAmount=AMOUNT_IN_SMALLEST_UNIT'
const quote = await axios.get("https://li.quest/v1/quote", {
params: {
fromChain: CHAIN_ID,
toChain: CHAIN_ID,
fromToken: "SOURCE_TOKEN_ADDRESS",
toToken: "FELIX_VAULT_TOKEN_ADDRESS", // Felix Vanilla vault token
fromAddress: "0xYOUR_WALLET_ADDRESS",
toAddress: "0xYOUR_WALLET_ADDRESS",
fromAmount: "AMOUNT_IN_SMALLEST_UNIT",
},
});
Neverland Vaults
Neverland vault 支持存入和提款。同链:存入 Neverland Vault
curl -X GET 'https://li.quest/v1/quote?fromChain=CHAIN_ID&toChain=CHAIN_ID&fromToken=SOURCE_TOKEN_ADDRESS&toToken=NEVERLAND_VAULT_TOKEN_ADDRESS&fromAddress=0xYOUR_WALLET_ADDRESS&toAddress=0xYOUR_WALLET_ADDRESS&fromAmount=AMOUNT_IN_SMALLEST_UNIT'
const quote = await axios.get("https://li.quest/v1/quote", {
params: {
fromChain: CHAIN_ID,
toChain: CHAIN_ID,
fromToken: "SOURCE_TOKEN_ADDRESS",
toToken: "NEVERLAND_VAULT_TOKEN_ADDRESS",
fromAddress: "0xYOUR_WALLET_ADDRESS",
toAddress: "0xYOUR_WALLET_ADDRESS",
fromAmount: "AMOUNT_IN_SMALLEST_UNIT",
},
});
代表另一个地址存入
某些协议(例如带有onBehalfOf 的 Aave)支持代表另一个钱包存入。要使用此模式,请将 toAddress 设置为接收方的地址:
TypeScript
const { data: quote } = await axios.get(`${API_URL}/quote`, {
params: {
fromChain: 8453,
toChain: 8453,
fromToken: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
toToken: "0x7BfA7C4f149E7415b73bdeDfe609237e29CBF34A",
fromAddress: "0xSENDER_ADDRESS",
toAddress: "0xRECIPIENT_ADDRESS", // Vault tokens go to this address
fromAmount: "1000000",
slippage: 0.005,
},
});
并非所有协议都支持代表他人存入。如果目标协议不
支持,API 将返回错误或忽略
toAddress
的区别。在依赖此模式之前,请先用你的目标协议进行测试。Pendle 收益代币
Pendle 支持收益代币化。Composer 支持存入和提款。同链:存入 Pendle
curl -X GET 'https://li.quest/v1/quote?fromChain=CHAIN_ID&toChain=CHAIN_ID&fromToken=SOURCE_TOKEN_ADDRESS&toToken=PENDLE_TOKEN_ADDRESS&fromAddress=0xYOUR_WALLET_ADDRESS&toAddress=0xYOUR_WALLET_ADDRESS&fromAmount=AMOUNT_IN_SMALLEST_UNIT'
const quote = await axios.get("https://li.quest/v1/quote", {
params: {
fromChain: CHAIN_ID,
toChain: CHAIN_ID,
fromToken: "SOURCE_TOKEN_ADDRESS",
toToken: "PENDLE_TOKEN_ADDRESS", // Pendle yield token
fromAddress: "0xYOUR_WALLET_ADDRESS",
toAddress: "0xYOUR_WALLET_ADDRESS",
fromAmount: "AMOUNT_IN_SMALLEST_UNIT",
},
});
仅支持存入的协议
以下协议通过 Composer 仅支持存入(无法通过 Composer 提款): 对于这些协议,使用相同的GET /quote 模式,将协议的 vault/质押代币作为 toToken。
通用模式
每个 vault 存入 recipe 都遵循相同的模式:GET /quote
fromChain = source chain ID
toChain = destination chain ID (same or different)
fromToken = token you're starting with
toToken = VAULT TOKEN ADDRESS (this triggers Composer)
fromAmount = amount in smallest unit
fromAddress = your wallet
toAddress = your wallet (receives vault tokens)
toToken 必须是来自受支持协议的 vault 代币地址。其他一切都与标准的 LI.FI 交换或桥接请求完全相同。
后续步骤
Withdrawals
通过 Composer 从协议头寸提款
Cross-Chain Patterns
桥接 + 存入模式、状态轮询和部分失败处理
Supported Protocols
完整的协议列表及示例代币地址
API Integration
分步 REST API 集成演练

