> ## 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.

# 执行路由/报价

> 我们允许您执行任何同链或跨链交换和桥接转账以及两者的组合。

LI.FI SDK 提供执行路由和报价的功能。在本指南中，您将学习如何利用 SDK 的功能来处理复杂的跨链转账、管理执行设置和控制交易流程。

## 执行路由

假设您已经获得了路由。有关更多详细信息，请参阅[请求路由/报价](/zh-Hans/sdk/request-routes)。

请确保您已使用 EVM/Solana 提供程序配置了 SDK。有关更多详细信息，请参阅[配置 SDK 提供程序](/zh-Hans/sdk/configure-sdk-providers)。

现在，要执行路由，我们可以使用 `executeRoute` 函数。这里是如何使用它的简化示例：

```typescript theme={"system"}
import { executeRoute, getRoutes } from '@lifi/sdk'

const result = await getRoutes({
  fromChainId: 42161, // Arbitrum
  toChainId: 10, // Optimism
  fromTokenAddress: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831', // USDC on Arbitrum
  toTokenAddress: '0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1', // DAI on Optimism
  fromAmount: '10000000', // 10 USDC
  // 正在转移代币的地址。
  fromAddress: '0x552008c0f6870c2f77e5cC1d2eb9bdff03e30Ea0', 
})

const route = result.routes[0]

const executedRoute = await executeRoute(route, {
  // 一旦路由对象获得新更新就会被调用
  updateRouteHook(route) {
    console.log(route)
  },
})
```

`executeRoute` 函数在内部管理授权和余额检查、链切换、交易数据检索、交易提交和交易状态跟踪。

* **参数：**

  * `route` (`Route`): 要执行的路由。

  * `executionOptions` (`ExecutionOptions`, 可选): 包含执行设置和回调的对象。

* **返回：**

  * `Promise<RouteExtended>`: 在执行完成或停止时解析，在失败时拒绝。

### 执行选项

所有执行选项都是可选的，但我们建议查看其描述以确定哪些选项可能对您的用例有益。

某些选项，例如 [acceptExchangeRateUpdateHook](#acceptexchangerateupdatehook)，如果在过程中汇率发生变化，对于成功完成转账可能至关重要。

#### `updateRouteHook`

当路由对象在执行期间发生更改时调用该函数。此函数允许您处理路由更新、跟踪执行状态、交易哈希等。有关更多详细信息，请参阅[监控路由执行](#监控路由执行)部分。

* **参数**:

  * `updatedRoute` (`RouteExtended`): 更新的路由对象。

#### `updateTransactionRequestHook`

该函数用于高级用法，它允许您在发送交换/桥接交易请求或代币批准请求之前对其进行修改，例如更新 gas 信息。

* **参数**:

  * `updatedTxRequest` (`TransactionRequestParameters`): 需要更新的交易请求参数。

* **返回**: `Promise<TransactionParameters>`: 修改后的交易参数。

#### `acceptExchangeRateUpdateHook`

每当在交换或桥接操作期间汇率发生变化时，就会调用此函数。它为您提供旧的和新的金额值。要继续执行，您应该返回 `true`。如果未提供此钩子或返回 `false`，SDK 将抛出错误。此钩子是提示用户接受新汇率的理想位置。

* **参数**:

  * `toToken` (`Token`): 目标代币。

  * `oldToAmount` (`string`): 目标代币的先前金额。

  * `newToAmount` (`string`): 目标代币的新金额。

* **返回**: `Promise<boolean | undefined>`: 更新是否被接受。

* **抛出:** `TransactionError: Exchange rate has changed!`

#### `switchChainHook`

* **参数**:

  * `chainId` (`number`): 要切换到的链的 ID。

* **返回**: `Promise<WalletClient | undefined>`: 切换链后的新钱包客户端。

#### `executeInBackground`

一个布尔标志，指示路由执行是否应在后台继续而不需要用户交互。有关如何利用此选项的详细信息，请参阅[更新路由执行](#更新路由执行)和[恢复路由执行](#恢复路由执行)部分。

* **类型**: `boolean`

* **默认值**: `false`

#### `disableMessageSigning`

一个布尔标志，指示是否在执行期间禁用消息签名。某些操作需要签名 EIP-712 消息，包括 Permit 批准（ERC-2612）和无 gas 交易。此功能可能与所有智能账户或钱包不兼容，在这种情况下，应将此标志设置为 true 以禁用消息签名。

* **类型**: `boolean`

* **默认值**: `false`

## 管理路由执行

开始路由执行后，可能存在需要调整执行设置、停止执行并稍后返回或将执行移至后台的用例。我们提供了几个函数来实现这一点。

### 更新路由执行

`updateRouteExecution` 函数用于更新正在进行的路由执行的设置。

一个常见的用例是将执行推到后台，例如，当用户在您的 dApp 中离开执行页面时。调用此函数时，执行将继续，直到需要用户交互（例如，签署交易或切换链）。在那时，执行将停止，并且 `executeRoute` promise 将被解析。

要将执行移回前台并使其再次处于活动状态，您可以使用相同的路由对象调用 `resumeRoute`。然后执行将从停止的地方恢复。

```typescript theme={"system"}
import { updateRouteExecution } from '@lifi/sdk'

updateRouteExecution(route, { executeInBackground: true });
```

* **参数：**

  * `route` (`Route`): 要更新的活动路由。

  * `executionOptions` (`ExecutionOptions`, **必需**): 包含执行设置和回调的对象。

### 恢复路由执行

`resumeRoute` 函数用于从停止的地方恢复已停止、中止或失败的路由执行。使用从 `executeRoute` 函数返回的最新活动路由对象或来自 `updateRouteHook` 的最新版本的更新路由对象调用 `resumeRoute` 至关重要。

#### 常见用例

* **将执行移至前台**：当用户导航回 dApp 中的执行页面时，您可以调用此函数将执行移回前台。执行将从停止的地方恢复。

* **页面刷新**：如果用户在执行过程中刷新页面，调用此函数将尝试恢复执行。

* **用户交互错误**：如果用户拒绝链切换、拒绝签署交易或遇到任何其他错误，您可以调用此函数尝试恢复执行。

```typescript theme={"system"}
import { resumeRoute } from '@lifi/sdk'

const route = await resumeRoute(route, { executeInBackground: false });
```

* **参数：**

  * `route` (`Route`): 要恢复执行的路由。

  * `executionOptions` (`ExecutionOptions`, 可选): 包含执行设置和回调的对象。

* **返回：**

  * `Promise<RouteExtended>`: 在执行完成或停止时解析，在失败时拒绝。

### 停止路由执行

`stopRouteExecution` 函数用于停止活动路由的正在进行的执行。它停止正在进行的执行中的任何剩余用户交互，并从执行队列中删除路由。但是，如果交易已经由用户签署并发送，它将在链上执行。

```typescript theme={"system"}
import { stopRouteExecution } from '@lifi/sdk'

const stoppedRoute = stopRouteExecution(route);
```

* **参数：**

  * `route` (`Route`): 当前正在执行并需要停止的路由。

* **返回：**

  * `Route`: 已停止的路由对象。

## 监控路由执行

监控路由执行很重要，我们提供了跟踪进度、接收数据更新、访问交易哈希和浏览器链接的工具。

### 步骤的简要描述

`route` 对象包括多个 `step` 对象，每个对象代表应按指定顺序完成的一组交易。每个步骤可以包括需要签名的多个交易，例如授权交易后跟主交换或桥接交易。阅读更多 [LI.FI 术语](/zh-Hans/introduction/introduction)。

### 理解 `execution` 对象

`route` 中的每个 `step` 都有一个 `execution` 对象。此对象包含跟踪该步骤执行进度所需的所有必要信息。`execution` 对象有一个 `process` 数组，其中每个条目代表执行中的一个顺序阶段。最新的进程条目包含有关执行阶段的最新信息。

### 进程数组

`execution` 对象中的 `process` 数组详细说明了每个步骤的进展。每个 `process` 对象都有一个类型和状态，并且在用户签署交易后可能还包括交易哈希和区块链浏览器的链接。

### 跟踪进度

要监控执行进度，您可以利用 `updateRouteHook` 回调并遍历路由步骤，检查它们的 `execution` 对象。查看 `process` 数组以获取有关执行阶段的最新信息。`process` 数组中的最新条目将包含最新的交易哈希、状态和其他相关详细信息。

### 访问交易哈希的示例

```typescript theme={"system"}
const getTransactionLinks = (route: RouteExtended) => {
  route.steps.forEach((step, index) => {
    step.execution?.process.forEach((process) => {
      if (process.txHash) {
        console.log(
          `Transaction Hash for Step ${index + 1}, Process ${process.type}:`,
          process.txHash
        )
      }
    })
  })
}

const executedRoute = await executeRoute(route, {
  updateRouteHook(route) {
    getTransactionLinks(route)
  },
})
```

### 获取活动路由

要获取当前正在执行的路由（活动），您可以使用 `getActiveRoutes` 和 `getActiveRoute` 函数。

```typescript theme={"system"}
import { getActiveRoute, getActiveRoutes, RouteExtended } from '@lifi/sdk'

const activeRoutes: RouteExtended[] = getActiveRoutes();

const routeId = activeRoutes[0].routeId;

const activeRoute = getActiveRoute(routeId);
```

## 执行报价

要使用 `executeRoute` 执行报价，您需要首先将其转换为路由对象。我们提供 `convertQuoteToRoute` 辅助函数来将报价对象转换为路由对象。这适用于标准和合约调用报价。

```typescript theme={"system"}
import { convertQuoteToRoute, executeRoute, getQuote } from '@lifi/sdk';

const quoteRequest: QuoteRequest = {
  fromChain: 42161, // Arbitrum
  toChain: 10, // Optimism
  fromToken: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831', // USDC on Arbitrum
  toToken: '0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1', // DAI on Optimism
  fromAmount: '10000000', // 10 USDC
  // 正在转移代币的地址。
  fromAddress: '0x552008c0f6870c2f77e5cC1d2eb9bdff03e30Ea0', 
};

const quote = await getQuote(quoteRequest);

const route = convertQuoteToRoute(quote)

const executedRoute = await executeRoute(route, {
  // 一旦路由对象获得新更新就会被调用
  updateRouteHook(route) {
    console.log(route)
  },
})
```

## 手动路由执行

除了使用 `executeRoute` 函数外，您还可以手动执行路由和报价。此方法要求开发人员独立处理获取交易数据、切换链、发送交易和跟踪交易状态的逻辑。

最初，当请求路由对象时，它们不包括交易数据。这是因为提供了多个路由选项，并且为所有选项生成交易数据将大大延迟响应。每个路由由多个步骤组成，一旦用户选择了路由，应使用 `getStepTransaction` 函数单独请求每个步骤的交易数据（见下面的示例）。每个步骤应按顺序执行，因为每个步骤都依赖于前一个步骤的结果。

另一方面，报价对象返回时包含交易数据，因此不需要 `getStepTransaction` 调用，并且可以立即执行。

使用获得的交易数据发送交易后，您可以使用 `getStatus` 函数跟踪交易的状态。此函数帮助您监控每个交易的进度和完成情况。阅读更多[交易状态](/zh-Hans/introduction/user-flows-and-examples/status-tracking)。

这是一个简化的示例。为简单起见，此示例省略了余额检查、交易替换、错误处理、链切换等。但是，在实际实现中，您应该包括这些附加功能以拥有强大的解决方案并确保可靠性。

```typescript theme={"system"}
import { getStepTransaction, getStatus } from '@lifi/sdk';

// 简化的示例函数，用于按顺序执行路由的每个步骤
async function executeRouteSteps(route) {
  for (const step of route.steps) {
    // 请求当前步骤的交易数据
    const step = await getStepTransaction(step);
    
    // 发送交易（例如使用 Viem）
    const transactionHash = await sendTransaction(step.transactionRequest);
    
    // 监控交易状态
    let status;
    do {
      const result = await getStatus({
        txHash: transactionHash,
        fromChain: step.action.fromChainId,
        toChain: step.action.toChainId,
        bridge: step.tool,
      })
      status = result.status
      
      console.log(`Transaction status for ${transactionHash}:`, status);
      
      // 在再次检查状态之前等待一小段时间
      await new Promise(resolve => setTimeout(resolve, 5000));
      
    } while (status !== 'DONE' && status !== 'FAILED');
    
    if (status === 'FAILED') {
      console.error(`Transaction ${transactionHash} failed`);
      return;
    }
  }
  
  console.log('All steps executed successfully');
}
```

#### `getStepTransaction`

* **参数：**

  * `step` (`LiFiStep`): 我们需要获取交易数据的步骤对象。

  * `options` (`RequestOptions`, 可选): 包含请求选项的对象，例如 `AbortSignal`，可用于在必要时取消请求。

* **返回：**

  * `Promise<LiFiStep>`: 解析为包含交易数据的步骤对象的 promise。

#### `getStatus`

* **参数：**

  * `params` (`GetStatusRequest`): 用于检查状态的参数包括交易哈希、源链和目标链 ID 以及 DEX 或桥接器名称。

  * `options` (`RequestOptions`, 可选): 包含请求选项的对象，例如 `AbortSignal`，可用于在必要时取消请求。

* **返回：**

  * `Promise<StatusResponse>`: 解析为包含有关转账的所有相关信息的状态响应的 promise。
