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

# 跨链 Composer 模式

> 了解如何组合跨链 DeFi 操作：使用 LI.FI Composer 在单个用户流程中实现跨链 + 兑换 + 存款。

跨链 Composer 让用户将资产存入与他们的资产所在链不同的协议中，全部在单个流程中完成。本指南涵盖跨链 Composer 操作的模式、示例和注意事项。

***

## 跨链 Composer 工作原理

当 `fromChain` 和 `toChain` 不同时，LI.FI 的路由引擎自动组合：

1. **源链操作** — 如果需要则兑换代币
2. **跨链桥** — 将资产转移到目标链
3. **目标链操作** — 兑换到所需代币并通过 Composer 存入目标协议

从开发者的角度来看，API 调用与同链 Composer 完全相同。您只需使用不同的链 ID。LI.FI 处理跨链桥选择、中间兑换和最终的 Composer 存款。

<Note>
  下面的模式说明了**可能的**执行路径。您不控制路由引擎选择哪种模式。它会自动优化成本、速度和流动性。只有在收到路由响应时您才会知道确切的执行路径。
</Note>

```
源链（例如 Ethereum）          目标链（例如 Base）
┌──────────────────────────┐          ┌──────────────────────────┐
│  1. 兑换 ETH → USDC      │          │  4. 接收跨链 USDC  │
│     (如果需要)           │          │  5. 将 USDC 存入     │
│  2. 授权跨链桥        │─── 跨链桥 ──▶│     Morpho 金库       │
│  3. 发送到跨链桥        │          │  6. 返还金库代币   │
└──────────────────────────┘          └──────────────────────────┘
```

***

## 常见跨链模式

这些模式描述路由引擎可能满足跨链 Composer 请求的典型方式。实际路径在报价时根据可用流动性、跨链桥选项和 gas 成本确定。

### 跨链桥 + 存款

用户在错误的链上有正确的代币。

**示例：** Arbitrum 上的 USDC → Base 上的 Morpho 金库

<CodeGroup>
  ```bash curl theme={"system"}
  curl -X GET 'https://li.quest/v1/quote?fromChain=42161&toChain=8453&fromToken=0xaf88d065e77c8cC2239327C5EDb3A432268e5831&toToken=0x7BfA7C4f149E7415b73bdeDfe609237e29CBF34A&fromAddress=0xYOUR_WALLET_ADDRESS&toAddress=0xYOUR_WALLET_ADDRESS&fromAmount=10000000'
  ```

  ```ts TypeScript theme={"system"}
  const quote = await getQuote({
    fromChain: 42161,                                             // Arbitrum
    toChain: 8453,                                                // Base
    fromToken: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',     // Arbitrum 上的 USDC
    toToken: '0x7BfA7C4f149E7415b73bdeDfe609237e29CBF34A',       // Base 上的 Morpho 金库代币
    fromAmount: '10000000',                                       // 10 USDC
    fromAddress: '0xYOUR_WALLET_ADDRESS',
  });
  ```
</CodeGroup>

**可能发生的情况：**

1. 将 USDC 从 Arbitrum 跨链到 Base
2. 将 USDC 存入 Base 上的 Morpho 金库
3. 用户收到金库代币

确切的步骤取决于 API 返回的路由。如果产生更好的结果，路由引擎可能会选择不同的跨链桥或插入中间兑换。

### 兑换 + 跨链桥 + 存款

用户在不同链上有不同的代币。

**示例：** Ethereum 上的 ETH → Optimism 上的 Aave USDC 借贷

<CodeGroup>
  ```bash curl theme={"system"}
  curl -X GET 'https://li.quest/v1/quote?fromChain=1&toChain=10&fromToken=0x0000000000000000000000000000000000000000&toToken=AAVE_AUSDC_TOKEN_ADDRESS_ON_OPTIMISM&fromAddress=0xYOUR_WALLET_ADDRESS&toAddress=0xYOUR_WALLET_ADDRESS&fromAmount=100000000000000000'
  ```

  ```ts TypeScript theme={"system"}
  const quote = await getQuote({
    fromChain: 1,                                                 // Ethereum
    toChain: 10,                                                  // Optimism
    fromToken: '0x0000000000000000000000000000000000000000',       // ETH (原生)
    toToken: 'AAVE_AUSDC_TOKEN_ADDRESS_ON_OPTIMISM',             // Optimism 上的 Aave aUSDC
    fromAmount: '100000000000000000',                             // 0.1 ETH
    fromAddress: '0xYOUR_WALLET_ADDRESS',
  });
  ```
</CodeGroup>

**可能发生的情况：**

1. 在 Ethereum 上将 ETH 兑换为 USDC
2. 将 USDC 从 Ethereum 跨链到 Optimism
3. 将 USDC 存入 Optimism 上的 Aave
4. 用户收到 aUSDC 代币

### 多跳跨链

当没有直接的跨链桥可用时，路由引擎可能使用多跳路径。

**示例：** Polygon 上的 MATIC → Avalanche 上的 Yield Yak 金库

<CodeGroup>
  ```ts TypeScript theme={"system"}
  const quote = await getQuote({
    fromChain: 137,                                                // Polygon
    toChain: 43114,                                               // Avalanche
    fromToken: '0x0000000000000000000000000000000000001010',     // MATIC
    toToken: 'YIELD_YAK_VAULT_ADDRESS_ON_AVALANCHE',             // Avalanche 上的 Yield Yak 金库
    fromAmount: '1000000000000000000',                            // 1 MATIC
    fromAddress: '0xYOUR_WALLET_ADDRESS',
  });
  ```
</CodeGroup>

**可能发生的情况：**

1. 在 Polygon 上将 MATIC 兑换为桥接代币
2. 跨链到中间链（如 Ethereum）
3. 从中间链跨链到 Avalanche
4. 在 Avalanche 上兑换为目标代币
5. 存入 Yield Yak 金库

***

## 执行跨链 Composer

### API 集成

```ts theme={"system"}
import axios from 'axios';

const executeCrossChainComposer = async () => {
  // 1. 获取跨链 Composer 报价
  const quote = await axios.get('https://li.quest/v1/quote', {
    params: {
      fromChain: 1,                                                 // Ethereum
      toChain: 8453,                                                // Base
      fromToken: '0x0000000000000000000000000000000000000000',       // ETH
      toToken: '0x7BfA7C4f149E7415b73bdeDfe609237e29CBF34A',       // Morpho 金库
      fromAmount: '100000000000000000',                             // 0.1 ETH
      fromAddress: '0xYOUR_WALLET_ADDRESS',
      toAddress: '0xYOUR_WALLET_ADDRESS',
    },
  });

  const quoteData = quote.data;
  
  // 2. 设置授权（如果需要）
  if (quoteData.estimate.approvalAddress) {
    // 授权逻辑...
  }

  // 3. 执行源链交易
  const tx = await signer.sendTransaction(quoteData.transactionRequest);
  console.log('源链交易：', tx.hash);

  // 4. 跟踪跨链状态
  const trackStatus = async () => {
    const status = await axios.get('https://li.quest/v1/status', {
      params: {
        txHash: tx.hash,
        fromChain: 1,
        toChain: 8453,
      },
    });

    const statusData = status.data;
    console.log('状态：', statusData.status, statusData.substatus);

    if (statusData.status !== 'DONE' && statusData.status !== 'FAILED') {
      setTimeout(trackStatus, 5000); // 5 秒后重试
    } else {
      console.log('跨链 Composer 完成！');
    }
  };

  trackStatus();
};
```

### SDK 集成

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

const executeCrossChainComposerWithSDK = async () => {
  // 1. 获取跨链报价
  const quote = await getQuote({
    fromChain: 1,                                                 // Ethereum
    toChain: 8453,                                                // Base
    fromToken: '0x0000000000000000000000000000000000000000',       // ETH
    toToken: '0x7BfA7C4f149E7415b73bdeDfe609237e29CBF34A',       // Morpho 金库
    fromAmount: '100000000000000000',                             // 0.1 ETH
    fromAddress: '0xYOUR_WALLET_ADDRESS',
  });

  // 2. 转换并执行 - SDK 处理所有复杂性
  const route = convertQuoteToRoute(quote);
  const executedRoute = await executeRoute(route, {
    updateRouteHook(updatedRoute) {
      console.log('路由更新：', updatedRoute);
    },
    onChainSwitch(chainId) {
      console.log('切换到链：', chainId);
    },
  });

  console.log('跨链 Composer 完成：', executedRoute);
};
```

***

## 状态跟踪

跨链 Composer 需要状态跟踪来监控两阶段执行：

| 阶段      | 状态        | 描述             |
| ------- | --------- | -------------- |
| **源链**  | `PENDING` | 源链交易进行中        |
| **跨链桥** | `PENDING` | 资产正在跨链         |
| **目标链** | `PENDING` | Composer 执行进行中 |
| **完成**  | `DONE`    | 所有步骤完成         |

```ts theme={"system"}
const trackCrossChainStatus = async (txHash: string, fromChain: number, toChain: number) => {
  const status = await getStatus(txHash, fromChain, toChain);
  
  switch (status.status) {
    case 'PENDING':
      if (status.substatus?.includes('bridge')) {
        console.log('跨链进行中...');
      } else if (status.substatus?.includes('composer')) {
        console.log('Composer 执行进行中...');
      } else {
        console.log('源链交易进行中...');
      }
      break;
      
    case 'DONE':
      console.log('跨链 Composer 完成！');
      break;
      
    case 'FAILED':
      console.error('执行失败：', status.substatus);
      break;
      
    default:
      console.log('状态：', status.status);
  }
};
```

***

## 成本和速度考虑

### 成本因素

* **Gas 费用**：两笔交易（源链 + 目标链）
* **跨链桥费用**：跨链桥收取的费用
* **DEX 费用**：中间兑换的费用
* **Slippage**：跨链和兑换的价格影响

### 速度因素

* **跨链桥时间**：从几秒（LayerZero）到几分钟（传统跨链桥）
* **目标链确认**：取决于目标链的出块时间
* **拥堵**：网络拥堵可能延迟执行

### 优化建议

```ts theme={"system"}
// 在报价请求中包含选项以优化
const quote = await getQuote({
  fromChain: 1,
  toChain: 8453,
  fromToken: '0x0000000000000000000000000000000000000000',
  toToken: '0x7BfA7C4f149E7415b73bdeDfe609237e29CBF34A',
  fromAmount: '100000000000000000',
  fromAddress: '0xYOUR_WALLET_ADDRESS',
  options: {
    slippage: 0.005, // 0.5% slippage
    bridges: {
      allow: ['stargateV2', 'across'], // 偏好快速跨链桥
    },
  },
});
```

***

## 错误处理

常见跨链 Composer 错误：

| 错误                              | 原因              | 解决方案       |
| ------------------------------- | --------------- | ---------- |
| `BRIDGE_NOT_AVAILABLE`          | 没有可用的跨链桥        | 尝试不同的源链或代币 |
| `INSUFFICIENT_BRIDGE_LIQUIDITY` | 跨链桥流动性不足        | 等待或使用较小的金额 |
| `COMPOSER_EXECUTION_FAILED`     | 目标链 Composer 失败 | 检查协议状态，重试  |
| `TIMEOUT`                       | 跨链时间过长          | 检查状态，可能已完成 |

```ts theme={"system"}
try {
  const executedRoute = await executeRoute(route);
} catch (error) {
  if (error.code === 'BRIDGE_NOT_AVAILABLE') {
    console.error('此路径没有可用的跨链桥');
  } else if (error.code === 'COMPOSER_EXECUTION_FAILED') {
    console.error('目标链执行失败，请检查协议状态');
  }
}
```

***

## 最佳实践

1. **显示进度**：向用户显示两阶段执行进度
2. **设置合理超时**：跨链可能需要几分钟
3. **处理部分失败**：源链成功但目标链失败的情况
4. **提供反馈**：清晰的状态更新和错误消息
5. **测试跨链桥**：在主网之前在测试网上测试

```ts theme={"system"}
const executeWithProgress = async (route) => {
  try {
    const executedRoute = await executeRoute(route, {
      updateRouteHook(updatedRoute) {
        // 向用户显示进度
        const currentStep = updatedRoute.steps.find(step => 
          step.execution?.status === 'PENDING'
        );
        
        if (currentStep) {
          updateUI(`正在执行：${currentStep.tool} 在链 ${currentStep.action.toChainId}`);
        }
      },
    });
    
    updateUI('跨链 Composer 完成！');
    return executedRoute;
    
  } catch (error) {
    updateUI(`错误：${error.message}`);
    throw error;
  }
};
```

***

## 下一步

<CardGroup cols={2}>
  <Card title="API 集成" icon="code" href="/composer/guides/api-integration">
    直接 REST API 集成
  </Card>

  <Card title="SDK 集成" icon="cube" href="/composer/guides/sdk-integration">
    使用 LI.FI SDK
  </Card>

  <Card title="状态跟踪" icon="clock" href="/introduction/user-flows-and-examples/status-tracking">
    完整状态跟踪指南
  </Card>

  <Card title="支持的协议" icon="list" href="/composer/reference/supported-protocols">
    查看所有支持的协议
  </Card>
</CardGroup>
