> ## Documentation Index
> Fetch the complete documentation index at: https://docs.li.fi/llms.txt
> Use this file to discover all available pages before exploring further.

# 从 v3 迁移到 v4

> LI.FI SDK v3 升级到 v4 的迁移指南

## 概述

**LI.FI SDK v4** 引入了基于客户端的架构，提供更好的类型安全、更高的模块化程度和更清晰的关注点分离。SDK 现在使用客户端实例模式而非全局配置，使管理多个 SDK 实例更加容易，并提高了可测试性。

首先，安装最新版本的 LI.FI SDK。

<CodeGroup>
  ```typescript yarn theme={"system"}
  yarn add @lifi/sdk
  ```

  ```typescript pnpm theme={"system"}
  pnpm add @lifi/sdk
  ```

  ```typescript bun theme={"system"}
  bun add @lifi/sdk
  ```

  ```typescript npm theme={"system"}
  npm install @lifi/sdk
  ```
</CodeGroup>

## 配置

v4 中最重要的变化是从全局配置模式转向基于客户端的架构。您不再调用 `createConfig()` 并使用全局函数，而是创建一个客户端实例并将其传递给所有 SDK 函数。

### 之前（v3）

```typescript theme={"system"}
// 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）

```typescript theme={"system"}
// 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）

```typescript theme={"system"}
// 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）

```typescript theme={"system"}
// 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。您需要单独安装提供者包，并从各自的包中导入提供者。

### 安装提供者包

<CodeGroup>
  ```typescript yarn theme={"system"}
  yarn add @lifi/sdk-provider-ethereum @lifi/sdk-provider-solana @lifi/sdk-provider-bitcoin @lifi/sdk-provider-sui @lifi/sdk-provider-tron
  ```

  ```typescript pnpm theme={"system"}
  pnpm add @lifi/sdk-provider-ethereum @lifi/sdk-provider-solana @lifi/sdk-provider-bitcoin @lifi/sdk-provider-sui @lifi/sdk-provider-tron
  ```

  ```typescript npm theme={"system"}
  npm install @lifi/sdk-provider-ethereum @lifi/sdk-provider-solana @lifi/sdk-provider-bitcoin @lifi/sdk-provider-sui @lifi/sdk-provider-tron
  ```

  ```typescript bun theme={"system"}
  bun add @lifi/sdk-provider-ethereum @lifi/sdk-provider-solana @lifi/sdk-provider-bitcoin @lifi/sdk-provider-sui @lifi/sdk-provider-tron
  ```
</CodeGroup>

<Note>
  只需安装您所需生态系统的提供者包。例如，如果您只支持 EVM 链，则只需要 `@lifi/sdk-provider-ethereum`。
</Note>

### 提供者配置

### 之前（v3）

```typescript theme={"system"}
// 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）

```typescript theme={"system"}
// 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`](https://github.com/solana-labs/solana-web3.js) 和 [Wallet Standard](https://github.com/wallet-standard/wallet-standard)，而非 `@solana/web3.js` 和旧版钱包适配器。

### 之前（v3）

```typescript theme={"system"}
// SDK v3
import { Solana } from '@lifi/sdk';

Solana({
  getWalletAdapter: () => Promise.resolve(walletAdapter),
});
```

### 之后（v4）

```typescript theme={"system"}
// 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）

```typescript theme={"system"}
// SDK v3
import { Sui } from '@lifi/sdk';

Sui({
  getWallet: () => Promise.resolve(wallet),
});
```

### 之后（v4）

```typescript theme={"system"}
// SDK v4
import { SuiProvider } from '@lifi/sdk-provider-sui';

SuiProvider({
  getClient: () => Promise.resolve(suiClient),
  getSigner: () => Promise.resolve(signer),
});
```

## 配置管理

### 之前（v3）

```typescript theme={"system"}
// SDK v3
import { config } from '@lifi/sdk';

// 更新配置
config.set({
  integrator: 'Updated name',
});

// 设置提供者
config.setProviders([...]);

// 获取链
const chains = await config.getChains();
```

### 之后（v4）

```typescript theme={"system"}
// 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）

```typescript theme={"system"}
// SDK v3
step.execution?.process.forEach((process) => {
  if (process.txHash) {
    console.log(process.type, process.txHash);
  }
});
```

### 之后（v4）

```typescript theme={"system"}
// 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）

```typescript theme={"system"}
// SDK v3
executeRoute(route, {
  switchChainHook: async (chainId) => { ... },
  disableMessageSigning: true,
});
```

### 之后（v4）

```typescript theme={"system"}
// 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）

```typescript theme={"system"}
// SDK v3
import { getTokenAllowance, setTokenAllowance } from '@lifi/sdk';

const allowance = await getTokenAllowance(token, ownerAddress, spenderAddress);
const txHash = await setTokenAllowance(approvalRequest);
```

### 之后（v4）

```typescript theme={"system"}
// 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 操作函数。

```typescript theme={"system"}
// 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` 或其他库来进行基本的格式化：

```typescript theme={"system"}
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. **显式依赖**：清楚函数依赖什么

### 示例：多个客户端

```typescript theme={"system"}
// 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 仓库](https://github.com/lifinance/sdk/tree/main/examples)中的完整示例，如果遇到任何问题，欢迎[提交 issue](https://github.com/lifinance/sdk/issues)。

## 更新日志

有关所有变更的详细信息，请参阅 [CHANGELOG](https://github.com/lifinance/sdk/blob/main/CHANGELOG.md)。
