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

# Cross-Chain Composer

> Deposit into any protocol on any EVM chain, starting from wherever your assets are. LI.FI handles the bridge, swaps, and final deposit in one flow.

Composer 支持跨 EVM 链的跨链存入。Ethereum 上的用户可以存入 Base 上的 Morpho vault，或将 Arbitrum 上的 USDC 存入 Base 上任意受支持的协议。LI.FI 会自动处理桥接选择、中间交换以及最终存入。

从开发者的角度看，集成与同链完全相同：只需将 `fromChain` 与 `toChain` 设为不同的值。

<Note>
  跨链 Composer 目前可在 EVM 链之间工作。非 EVM 链（Solana
  等）尚不受支持。
</Note>

***

## How It Works

跨链 Composer 结合了 LI.FI 的两项能力：

1. **桥接路由：** LI.FI 选择最优桥接，将资产从源链移动到目标链。
2. **Composer 执行：** 在目标链上，Composer 原子地存入目标协议。

从用户的角度看，这是一个单一 flow，在源链上只需一次签名。

***

## Cross-Chain vs. Same-Chain

|                 | Same-chain              | Cross-chain             |
| --------------- | ----------------------- | ----------------------- |
| Transactions    | 1                       | 2（源链 + 目标链）             |
| Atomicity       | 完全原子                    | 每链原子；整体上最终一致            |
| Status tracking | 无需                      | 轮询 `/status` 直到完成       |
| Integration     | `fromChain === toChain` | `fromChain !== toChain` |

***

## Example 1: ETH (Ethereum) → Morpho Vault (Base)

将 Ethereum 上的 ETH 存入 Base 上由 Spark 策展的 Morpho USDC vault。LI.FI 桥接 ETH，在 Base 上交换为 USDC，并存入 vault。

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

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

  const { data: quote } = await axios.get("https://li.quest/v1/quote", {
    params: {
      fromChain: 1, // Ethereum
      toChain: 8453, // Base
      fromToken: "0x0000000000000000000000000000000000000000", // ETH (native)
      toToken: "0x7BfA7C4f149E7415b73bdeDfe609237e29CBF34A", // Morpho vault on Base
      fromAddress: "0xYOUR_WALLET_ADDRESS",
      toAddress: "0xYOUR_WALLET_ADDRESS",
      fromAmount: "100000000000000000", // 0.1 ETH
      slippage: 0.01, // 1% for cross-chain
    },
  });

  // No approval needed for native ETH; submit directly
  const tx = await signer.sendTransaction(quote.transactionRequest);
  await tx.wait();
  console.log("Source chain tx confirmed:", tx.hash);

  // Poll status until the cross-chain transfer completes
  let status;
  do {
    const { data } = await axios.get("https://li.quest/v1/status", {
      params: {
        txHash: tx.hash,
        fromChain: quote.action.fromChainId,
        toChain: quote.action.toChainId,
      },
    });
    status = data;
    console.log(`Status: ${status.status} ${status.substatus || ""}`);

    if (status.status !== "DONE" && status.status !== "FAILED") {
      await new Promise((r) => setTimeout(r, 5000));
    }
  } while (status.status !== "DONE" && status.status !== "FAILED");

  console.log("Final status:", status.status);
  // User now holds Morpho vault tokens on Base
  ```
</CodeGroup>

***

## Example 2: USDC (Arbitrum) → Morpho Vault (Base)

在单一 flow 中将 Arbitrum 上的 USDC 桥接并存入 Base 上由 Spark 策展的 Morpho vault。

<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 { data: quote } = await axios.get("https://li.quest/v1/quote", {
    params: {
      fromChain: 42161, // Arbitrum
      toChain: 8453, // Base
      fromToken: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831", // USDC on Arbitrum
      toToken: "0x7BfA7C4f149E7415b73bdeDfe609237e29CBF34A", // Morpho vault on Base
      fromAddress: "0xYOUR_WALLET_ADDRESS",
      toAddress: "0xYOUR_WALLET_ADDRESS",
      fromAmount: "1000000000", // 1000 USDC (6 decimals)
      slippage: 0.01,
    },
  });

  // Approve USDC, send tx, and poll status (same pattern as above)
  ```
</CodeGroup>

**底层可能发生的事：**

1. 将 USDC 从 Arbitrum 桥接到 Base
2. 在 Base 上将 USDC 存入 Morpho vault
3. 用户收到 vault 代币

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

### Swap + Bridge + Deposit

用户在另一条链上持有另一种代币。

**示例：** 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 (native)
    toToken: "AAVE_AUSDC_TOKEN_ADDRESS_ON_OPTIMISM", // Aave aUSDC on Optimism
    fromAmount: "100000000000000000", // 0.1 ETH
    fromAddress: "0xYOUR_WALLET_ADDRESS",
  });
  ```
</CodeGroup>

**底层可能发生的事：**

1. 在 Ethereum 上将 ETH → USDC 交换，然后将 USDC 桥接到 Optimism；或直接桥接 ETH 并在目标链上交换
2. 在 Optimism 上将 USDC 存入 Aave
3. 用户收到 aUSDC 代币

路由引擎决定最优序列。你会在路由响应中看到所选路径。

### Bridge + Swap + Stake

用户想在另一条链上质押。

**示例：** Arbitrum 上的 USDC → Ethereum 上的 wstETH（Lido）

<CodeGroup>
  ```ts TypeScript theme={"system"}
  const quote = await getQuote({
    fromChain: 42161,                                             // Arbitrum
    toChain: 1,                                                   // Ethereum
    fromToken: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',     // USDC on Arbitrum
    toToken: '0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0',       // wstETH on Ethereum
    fromAmount: '1000000000',                                     // 1000 USDC
    fromAddress: '0xYOUR_WALLET_ADDRESS',
  });
  ```
</CodeGroup>

**底层可能发生的事：**

1. 将 USDC 从 Arbitrum 桥接到 Ethereum
2. 在 Ethereum 上将 USDC → ETH 交换
3. 通过 Lido 质押 ETH，包装为 wstETH
4. 用户收到 wstETH

如果找到更优路径，路由引擎可能选择不同的序列（例如先在 Arbitrum 上交换，再桥接 ETH）。

## Status Tracking

跨链转移需要状态轮询。源链交易确认后，轮询 `GET /v1/status` 直到转移达到 `DONE` 或 `FAILED`。

```ts TypeScript theme={"system"}
const pollStatus = async (
  txHash: string,
  fromChain: number,
  toChain: number,
) => {
  let status;
  do {
    const { data } = await axios.get("https://li.quest/v1/status", {
      params: { txHash, fromChain, toChain },
    });
    status = data;
    console.log(`Status: ${status.status} (${status.substatus || ""})`);

    if (status.status !== "DONE" && status.status !== "FAILED") {
      await new Promise((r) => setTimeout(r, 5000));
    }
  } while (status.status !== "DONE" && status.status !== "FAILED");

  return status;
};
```

如需完整的 status 与 substatus 参考，参见 [Transaction Status Tracking](/introduction/user-flows-and-examples/status-tracking)。

***

## Partial Failure Handling

跨链 flow 是最终一致的。在极少数情况下，桥接步骤成功但目标存入失败。发生这种情况时：

* 用户在目标链上收到桥接后的代币，而非 vault 代币
* 源链代币不受风险影响
* gas 费用被消耗

请构建你的 UI 以处理 `FAILED` 状态，并在跨链转移未完成时提示用户检查其目标链余额。

***

## Next Steps

<CardGroup cols={2}>
  <Card title="API Integration" icon="code" href="/composer/lifi-api/guides/api-integration">
    含同链与跨链示例的完整 API 集成指南
  </Card>

  <Card title="SDK Integration" icon="cube" href="/composer/lifi-api/guides/sdk-integration">
    使用 LI.FI TypeScript SDK 的托管式跨链执行
  </Card>

  <Card title="Deposit Recipes" icon="book" href="/composer/lifi-api/recipes/vault-deposits">
    常见协议与链的可复制粘贴 recipe
  </Card>

  <Card title="Supported Protocols" icon="list" href="/composer/protocols-and-chains">
    可用于跨链存入的协议
  </Card>
</CardGroup>
