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

执行路由

假设您已经获得了路由。有关更多详细信息,请参阅请求路由/报价 请确保您已使用 EVM/Solana 提供程序配置了 SDK。有关更多详细信息,请参阅配置 SDK 提供程序 现在,要执行路由,我们可以使用 executeRoute 函数。这里是如何使用它的简化示例:
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,如果在过程中汇率发生变化,对于成功完成转账可能至关重要。

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。然后执行将从停止的地方恢复。
import { updateRouteExecution } from '@lifi/sdk'

updateRouteExecution(route, { executeInBackground: true });
  • 参数:
    • route (Route): 要更新的活动路由。
    • executionOptions (ExecutionOptions, 必需): 包含执行设置和回调的对象。

恢复路由执行

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

常见用例

  • 将执行移至前台:当用户导航回 dApp 中的执行页面时,您可以调用此函数将执行移回前台。执行将从停止的地方恢复。
  • 页面刷新:如果用户在执行过程中刷新页面,调用此函数将尝试恢复执行。
  • 用户交互错误:如果用户拒绝链切换、拒绝签署交易或遇到任何其他错误,您可以调用此函数尝试恢复执行。
import { resumeRoute } from '@lifi/sdk'

const route = await resumeRoute(route, { executeInBackground: false });
  • 参数:
    • route (Route): 要恢复执行的路由。
    • executionOptions (ExecutionOptions, 可选): 包含执行设置和回调的对象。
  • 返回:
    • Promise<RouteExtended>: 在执行完成或停止时解析,在失败时拒绝。

停止路由执行

stopRouteExecution 函数用于停止活动路由的正在进行的执行。它停止正在进行的执行中的任何剩余用户交互,并从执行队列中删除路由。但是,如果交易已经由用户签署并发送,它将在链上执行。
import { stopRouteExecution } from '@lifi/sdk'

const stoppedRoute = stopRouteExecution(route);
  • 参数:
    • route (Route): 当前正在执行并需要停止的路由。
  • 返回:
    • Route: 已停止的路由对象。

监控路由执行

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

步骤的简要描述

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

理解 execution 对象

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

进程数组

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

跟踪进度

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

访问交易哈希的示例

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)
  },
})

获取活动路由

要获取当前正在执行的路由(活动),您可以使用 getActiveRoutesgetActiveRoute 函数。
import { getActiveRoute, getActiveRoutes, RouteExtended } from '@lifi/sdk'

const activeRoutes: RouteExtended[] = getActiveRoutes();

const routeId = activeRoutes[0].routeId;

const activeRoute = getActiveRoute(routeId);

执行报价

要使用 executeRoute 执行报价,您需要首先将其转换为路由对象。我们提供 convertQuoteToRoute 辅助函数来将报价对象转换为路由对象。这适用于标准和合约调用报价。
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 函数跟踪交易的状态。此函数帮助您监控每个交易的进度和完成情况。阅读更多交易状态 这是一个简化的示例。为简单起见,此示例省略了余额检查、交易替换、错误处理、链切换等。但是,在实际实现中,您应该包括这些附加功能以拥有强大的解决方案并确保可靠性。
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。
I