LI.FI SDK v4 引入了基于客户端的架构,提供更好的类型安全、更高的模块化程度和更清晰的关注点分离。SDK 现在使用客户端实例模式而非全局配置,使管理多个 SDK 实例更加容易,并提高了可测试性。
首先,安装最新版本的 LI.FI SDK。
v4 中最重要的变化是从全局配置模式转向基于客户端的架构。您不再调用 createConfig() 并使用全局函数,而是创建一个客户端实例并将其传递给所有 SDK 函数。
之前(v3)
// SDK v3
import { createConfig, getQuote, ChainId } from '@lifi/sdk';
createConfig({
integrator: 'Your dApp/company name',
});
const quote = await getQuote({
fromAddress: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045',
fromChain: ChainId.ARB,
toChain: ChainId.OPT,
fromToken: '0x0000000000000000000000000000000000000000',
toToken: '0x0000000000000000000000000000000000000000',
fromAmount: '1000000000000000000',
});
之后(v4)
// SDK v4
import { createClient, getQuote, ChainId } from '@lifi/sdk';
const client = createClient({
integrator: 'Your dApp/company name',
});
const quote = await getQuote(client, {
fromAddress: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045',
fromChain: ChainId.ARB,
toChain: ChainId.OPT,
fromToken: '0x0000000000000000000000000000000000000000',
toToken: '0x0000000000000000000000000000000000000000',
fromAmount: '1000000000000000000',
});
函数签名
所有 SDK 操作函数现在都要求将客户端作为第一个参数。包括:
getRoutes(client, {...})
getQuote(client, {...})
getContractCallsQuote(client, {...})
getChains(client, {...})
getTools(client, {...})
getConnections(client, {...})
getTokens(client, {...})
getToken(client, chain, token)
getTokenBalance(client, walletAddress, token)
getTokenBalances(client, walletAddress, tokens)
getTokenBalancesByChain(client, walletAddress, tokensByChain)
getWalletBalances(client, walletAddress)
getStatus(client, {...})
getStepTransaction(client, step)
executeRoute(client, route, options)
resumeRoute(client, route, options)
getGasRecommendation(client, {...})
getTransactionHistory(client, {...})
getNameServiceAddress(client, name, chainType?)
getRelayerQuote(client, {...})
relayTransaction(client, {...})
getRelayedTransactionStatus(client, {...})
patchContractCalls(client, {...})
迁移示例
之前(v3)
// SDK v3
import { getRoutes, executeRoute } from '@lifi/sdk';
const result = await getRoutes({
fromChainId: 42161,
toChainId: 10,
fromTokenAddress: '0x...',
toTokenAddress: '0x...',
fromAmount: '10000000',
});
const executedRoute = await executeRoute(result.routes[0], {
updateRouteHook(route) {
console.log(route);
},
});
之后(v4)
// SDK v4
import { createClient, getRoutes, executeRoute } from '@lifi/sdk';
const client = createClient({
integrator: 'Your dApp/company name',
});
const result = await getRoutes(client, {
fromChainId: 42161,
toChainId: 10,
fromTokenAddress: '0x...',
toTokenAddress: '0x...',
fromAmount: '10000000',
});
const executedRoute = await executeRoute(client, result.routes[0], {
updateRouteHook(route) {
console.log(route);
},
});
提供者包
在 v4 中,生态系统提供者已移至独立的包中,以实现更好的模块化和 tree-shaking。您需要单独安装提供者包,并从各自的包中导入提供者。
安装提供者包
yarn add @lifi/sdk-provider-ethereum @lifi/sdk-provider-solana @lifi/sdk-provider-bitcoin @lifi/sdk-provider-sui @lifi/sdk-provider-tron
只需安装您所需生态系统的提供者包。例如,如果您只支持 EVM 链,则只需要 @lifi/sdk-provider-ethereum。
提供者配置
之前(v3)
// SDK v3
import { createConfig, EVM, Solana } from '@lifi/sdk';
createConfig({
integrator: 'Your dApp/company name',
providers: [
EVM({
getWalletClient: () => Promise.resolve(walletClient),
}),
Solana({
getWalletAdapter: () => Promise.resolve(walletAdapter),
}),
],
});
之后(v4)
// SDK v4
import { createClient } from '@lifi/sdk';
import { EthereumProvider } from '@lifi/sdk-provider-ethereum';
import { SolanaProvider } from '@lifi/sdk-provider-solana';
const client = createClient({
integrator: 'Your dApp/company name',
});
client.setProviders([
EthereumProvider({
getWalletClient: () => Promise.resolve(walletClient),
}),
SolanaProvider({
getWallet: () => Promise.resolve(wallet), // wallet-standard Wallet
}),
]);
提供者名称
提供者工厂名称已更新为更具描述性的名称:
EVM → EthereumProvider(来自 @lifi/sdk-provider-ethereum)
Solana → SolanaProvider(来自 @lifi/sdk-provider-solana)
UTXO → BitcoinProvider(来自 @lifi/sdk-provider-bitcoin)
Sui → SuiProvider(来自 @lifi/sdk-provider-sui)
- 新增:
TronProvider(来自 @lifi/sdk-provider-tron),新增 Tron 生态系统支持
Solana 提供者:getWalletAdapter → getWallet
Solana 提供者现在使用 @solana/kit 和 Wallet Standard,而非 @solana/web3.js 和旧版钱包适配器。
之前(v3)
// SDK v3
import { Solana } from '@lifi/sdk';
Solana({
getWalletAdapter: () => Promise.resolve(walletAdapter),
});
之后(v4)
// SDK v4
import { SolanaProvider } from '@lifi/sdk-provider-solana';
SolanaProvider({
getWallet: () => Promise.resolve(wallet), // wallet-standard Wallet
});
Sui 提供者:getWallet → getClient + getSigner
Sui 提供者现在使用 @mysten/sui v2,需要 ClientWithCoreApi 和 Signer,而非钱包对象。
之前(v3)
// SDK v3
import { Sui } from '@lifi/sdk';
Sui({
getWallet: () => Promise.resolve(wallet),
});
之后(v4)
// SDK v4
import { SuiProvider } from '@lifi/sdk-provider-sui';
SuiProvider({
getClient: () => Promise.resolve(suiClient),
getSigner: () => Promise.resolve(signer),
});
配置管理
之前(v3)
// SDK v3
import { config } from '@lifi/sdk';
// 更新配置
config.set({
integrator: 'Updated name',
});
// 设置提供者
config.setProviders([...]);
// 获取链
const chains = await config.getChains();
之后(v4)
// SDK v4
import { createClient } from '@lifi/sdk';
const client = createClient({
integrator: 'Your dApp/company name',
});
// 访问配置(只读)
console.log(client.config.integrator);
// 设置提供者
client.setProviders([...]);
// 获取链
const chains = await client.getChains();
// 获取指定链
const chain = await client.getChainById(1);
// 获取 RPC URL
const rpcUrls = await client.getRpcUrls();
执行模型:Process → Action
执行追踪模型已重命名以使其更清晰。之前称为 “process” 的概念现在称为 “action”。
类型和字段重命名
Execution.process → Execution.actions
Process → ExecutionAction
ProcessType → ExecutionActionType
getProcessMessage() → getActionMessage() + getSubstatusMessage()
新的操作类型
TOKEN_ALLOWANCE 流程类型已拆分为更细粒度的操作类型:
CHECK_ALLOWANCE:检查代币授权额度
RESET_ALLOWANCE:重置代币授权额度
SET_ALLOWANCE:设置代币授权额度
此外,还新增了 NATIVE_PERMIT 操作类型。
之前(v3)
// SDK v3
step.execution?.process.forEach((process) => {
if (process.txHash) {
console.log(process.type, process.txHash);
}
});
之后(v4)
// SDK v4
import { getActionMessage } from '@lifi/sdk';
step.execution?.actions.forEach((action) => {
if (action.txHash) {
console.log(action.type, action.txHash);
}
const message = getActionMessage(action.type, action.status);
console.log(message);
});
ExecutionOptions 变更
switchChainHook 和 disableMessageSigning 选项已从 ExecutionOptions 中移除,并移至 EthereumProviderOptions,在设置 EVM 提供者时配置。请注意,switchChainHook 在提供者上已重命名为 switchChain(如下例所示)。
之前(v3)
// SDK v3
executeRoute(route, {
switchChainHook: async (chainId) => { ... },
disableMessageSigning: true,
});
之后(v4)
// SDK v4
import { EthereumProvider } from '@lifi/sdk-provider-ethereum';
client.setProviders([
EthereumProvider({
getWalletClient: () => Promise.resolve(walletClient),
switchChain: async (chainId) => { ... },
disableMessageSigning: true,
}),
]);
executeRoute(client, route, {
// switchChainHook 和 disableMessageSigning 不再在这里
});
代币授权函数
代币授权函数现在从 Ethereum 提供者包导出,而非主 SDK 包。
之前(v3)
// SDK v3
import { getTokenAllowance, setTokenAllowance } from '@lifi/sdk';
const allowance = await getTokenAllowance(token, ownerAddress, spenderAddress);
const txHash = await setTokenAllowance(approvalRequest);
之后(v4)
// SDK v4
import { createClient } from '@lifi/sdk';
import { getTokenAllowance, setTokenAllowance } from '@lifi/sdk-provider-ethereum';
const client = createClient({
integrator: 'Your dApp/company name',
});
const allowance = await getTokenAllowance(client, token, ownerAddress, spenderAddress);
const txHash = await setTokenAllowance(client, approvalRequest);
actions() 辅助函数
如果您不希望每次调用 SDK 函数时都将客户端作为第一个参数传入,可以使用 actions() 辅助函数。它返回一个对象,其中包含所有已预先绑定到客户端的 SDK 操作函数。
// SDK v4
import { createClient, actions } from '@lifi/sdk';
const client = createClient({
integrator: 'Your dApp/company name',
});
const api = actions(client);
// 无需将 client 作为第一个参数传入
const quote = await api.getQuote({
fromChain: 42161,
toChain: 10,
fromToken: '0x...',
toToken: '0x...',
fromAmount: '10000000',
fromAddress: '0x...',
});
新增工具函数
v4 从 @lifi/sdk 导出常用工具函数,因此您不再需要 viem 或其他库来进行基本的格式化:
import { formatUnits, parseUnits } from '@lifi/sdk';
// 格式化代币数量以供显示
const formatted = formatUnits(1000000n, 6); // "1"
// 将用户输入解析为代币数量
const amount = parseUnits("1", 6); // 1000000n
移除的参数
部分配置参数已被移除或更改:
chains:不再传递给 createClient。链会自动从 API 获取。
客户端实例模式
客户端实例模式允许您:
- 创建多个客户端,使用不同的配置
- 更好的可测试性:更容易模拟和测试
- 类型安全:更好的 TypeScript 支持
- 显式依赖:清楚函数依赖什么
示例:多个客户端
// SDK v4 - 多个客户端
import { createClient } from '@lifi/sdk';
const mainnetClient = createClient({
integrator: 'MyApp',
apiUrl: 'https://li.quest/v1',
});
const testnetClient = createClient({
integrator: 'MyApp',
apiUrl: 'https://staging.li.quest/v1',
});
// 为不同环境使用不同的客户端
const mainnetRoutes = await getRoutes(mainnetClient, {...});
const testnetRoutes = await getRoutes(testnetClient, {...});
迁移清单
- 更新包安装,包含所需的提供者包
- 将
createConfig() 替换为 createClient() 并保存客户端实例
- 更新所有函数调用,将
client 作为第一个参数(或使用 actions() 辅助函数)
- 更新提供者导入,使用独立的提供者包
- 更新提供者工厂名称(
EVM → EthereumProvider 等)
- Solana:将
getWalletAdapter 替换为 getWallet(返回 wallet-standard Wallet)
- Sui:将
getWallet 替换为 getClient + getSigner
- 将
switchChainHook(重命名为 switchChain)和 disableMessageSigning 从 ExecutionOptions 移至 EthereumProviderOptions
- 更新执行监控代码:
execution.process → execution.actions
- 将
getProcessMessage() 替换为 getActionMessage() 和 getSubstatusMessage()
- 更新代币授权函数的导入为
@lifi/sdk-provider-ethereum
- 更新代币授权函数调用,加入
client 参数
- 将
config.set() 和 config.getChains() 替换为客户端方法
- 移除对全局
config 对象的任何引用
- 如有需要,将
viem 的 formatUnits/parseUnits 替换为 @lifi/sdk 的导出
请查看 SDK 仓库中的完整示例,如果遇到任何问题,欢迎提交 issue。
更新日志
有关所有变更的详细信息,请参阅 CHANGELOG。