跳转到主要内容

概述

LI.FI SDK v4 引入了基于客户端的架构,提供更好的类型安全、更高的模块化程度和更清晰的关注点分离。SDK 现在使用客户端实例模式而非全局配置,使管理多个 SDK 实例更加容易,并提高了可测试性。 首先,安装最新版本的 LI.FI SDK。
yarn add @lifi/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
  }),
]);

提供者名称

提供者工厂名称已更新为更具描述性的名称:
  • EVMEthereumProvider(来自 @lifi/sdk-provider-ethereum
  • SolanaSolanaProvider(来自 @lifi/sdk-provider-solana
  • UTXOBitcoinProvider(来自 @lifi/sdk-provider-bitcoin
  • SuiSuiProvider(来自 @lifi/sdk-provider-sui
  • 新增TronProvider(来自 @lifi/sdk-provider-tron),新增 Tron 生态系统支持

Solana 提供者:getWalletAdaptergetWallet

Solana 提供者现在使用 @solana/kitWallet 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 提供者:getWalletgetClient + getSigner

Sui 提供者现在使用 @mysten/sui v2,需要 ClientWithCoreApiSigner,而非钱包对象。

之前(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.processExecution.actions
  • ProcessExecutionAction
  • ProcessTypeExecutionActionType
  • 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 变更

switchChainHookdisableMessageSigning 选项已从 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 获取。

客户端实例模式

客户端实例模式允许您:
  1. 创建多个客户端,使用不同的配置
  2. 更好的可测试性:更容易模拟和测试
  3. 类型安全:更好的 TypeScript 支持
  4. 显式依赖:清楚函数依赖什么

示例:多个客户端

// 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() 辅助函数)
  • 更新提供者导入,使用独立的提供者包
  • 更新提供者工厂名称(EVMEthereumProvider 等)
  • Solana:将 getWalletAdapter 替换为 getWallet(返回 wallet-standard Wallet
  • Sui:将 getWallet 替换为 getClient + getSigner
  • switchChainHook(重命名为 switchChain)和 disableMessageSigningExecutionOptions 移至 EthereumProviderOptions
  • 更新执行监控代码:execution.processexecution.actions
  • getProcessMessage() 替换为 getActionMessage()getSubstatusMessage()
  • 更新代币授权函数的导入为 @lifi/sdk-provider-ethereum
  • 更新代币授权函数调用,加入 client 参数
  • config.set()config.getChains() 替换为客户端方法
  • 移除对全局 config 对象的任何引用
  • 如有需要,将 viemformatUnits/parseUnits 替换为 @lifi/sdk 的导出

示例

请查看 SDK 仓库中的完整示例,如果遇到任何问题,欢迎提交 issue

更新日志

有关所有变更的详细信息,请参阅 CHANGELOG