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

# 快速入门

> 在 5 分钟内执行您的第一笔 Composer 交易。使用单次 API 调用将 USDC 存入 Base 上的 Morpho 金库。

本快速入门将带您完成一个同链 Composer 交易：将 USDC 存入 Base 上的 Morpho 金库。完成后，您将了解完整的 Composer 流程：报价、授权、执行、跟踪。

## 先决条件

* 一个在 Base 上有 USDC 的钱包地址（即使是像 1 USDC 这样的少量金额也可以）
* Node.js 18+（用于 TypeScript 示例）或 `curl`

***

<Steps>
  <Step title="获取 Composer 报价">
    请求报价，将 `toToken` 设置为金库代币地址：

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

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

      const API_URL = 'https://li.quest/v1';

      const getQuote = async (
        fromChain: number,
        toChain: number,
        fromToken: string,
        toToken: string,
        fromAmount: string,
        fromAddress: string
      ) => {
        const result = await axios.get(`${API_URL}/quote`, {
          params: {
            fromChain,
            toChain,
            fromToken,
            toToken,
            fromAmount,
            fromAddress,
            toAddress: fromAddress,
          },
        });
        return result.data;
      };

      const quote = await getQuote(
        8453,                                              // Base
        8453,                                              // Base (同链)
        '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',     // Base 上的 USDC
        '0x7BfA7C4f149E7415b73bdeDfe609237e29CBF34A',     // Morpho 金库代币
        '1000000',                                         // 1 USDC (6 位小数)
        '0xYOUR_WALLET_ADDRESS'
      );

      console.log(quote);
      ```
    </CodeGroup>

    **关键参数：**

    | 参数           | 值               | 描述             |
    | ------------ | --------------- | -------------- |
    | `fromChain`  | `8453`          | Base 链 ID      |
    | `toChain`    | `8453`          | Base (同链存款)    |
    | `fromToken`  | `0x8335...2913` | Base 上的 USDC   |
    | `toToken`    | `0x7BfA...34A`  | Morpho 金库代币地址  |
    | `fromAmount` | `1000000`       | 1 USDC (6 位小数) |

    <Tip>
      `toToken` 始终是目标协议的**金库代币地址**。您可以在协议自己的应用或文档中找到金库代币地址。
    </Tip>

    响应包括 `transactionRequest`，一个准备签署的 EVM 交易，以及估计的输出金额和使用的工具。
  </Step>

  <Step title="设置代币授权">
    在执行之前，确保 LI.FI 合约被授权使用您的代币。授权地址在报价响应的 `quote.estimate.approvalAddress` 中返回。

    <Note>
      如果您发送原生代币（例如 ETH），请跳过此步骤。原生代币不需要授权。
    </Note>

    <CodeGroup>
      ```ts TypeScript theme={"system"}
      import { ethers } from 'ethers';

      const ERC20_ABI = [
        'function approve(address spender, uint256 amount) returns (bool)',
        'function allowance(address owner, address spender) view returns (uint256)',
      ];

      const checkAndSetAllowance = async (
        signer: ethers.Signer,
        tokenAddress: string,
        approvalAddress: string,
        amount: string
      ) => {
        const erc20 = new ethers.Contract(tokenAddress, ERC20_ABI, signer);
        const signerAddress = await signer.getAddress();
        const allowance = await erc20.allowance(signerAddress, approvalAddress);

        if (allowance.lt(amount)) {
          const tx = await erc20.approve(approvalAddress, amount);
          await tx.wait();
          console.log('授权已设置。');
        } else {
          console.log('授权已足够。');
        }
      };

      await checkAndSetAllowance(
        signer,
        quote.action.fromToken.address,
        quote.estimate.approvalAddress,
        quote.action.fromAmount
      );
      ```
    </CodeGroup>
  </Step>

  <Step title="执行交易">
    使用报价响应中的 `transactionRequest` 对象发送交易。

    <CodeGroup>
      ```ts TypeScript theme={"system"}
      const tx = await signer.sendTransaction(quote.transactionRequest);
      console.log('交易已发送：', tx.hash);

      const receipt = await tx.wait();
      console.log('交易已确认：', receipt.transactionHash);
      ```
    </CodeGroup>

    就这样。Composer 在单笔原子交易中处理兑换和存款。
  </Step>

  <Step title="跟踪状态">
    对于同链交易，一旦确认交易就完成了。对于跨链 Composer 流程，轮询 `/status` 端点：

    <CodeGroup>
      ```ts TypeScript theme={"system"}
      const getStatus = async (txHash: string, fromChain: number, toChain: number) => {
        const result = await axios.get(`${API_URL}/status`, {
          params: { txHash, fromChain, toChain },
        });
        return result.data;
      };

      // 对于跨链转账，轮询直到完成
      if (quote.action.fromChainId !== quote.action.toChainId) {
        let status;
        do {
          status = await getStatus(tx.hash, quote.action.fromChainId, quote.action.toChainId);
          console.log('状态：', status.status, status.substatus);

          if (status.status !== 'DONE' && status.status !== 'FAILED') {
            await new Promise((resolve) => setTimeout(resolve, 5000)); // 等待 5 秒
          }
        } while (status.status !== 'DONE' && status.status !== 'FAILED');

        console.log('最终状态：', status.status);
      }
      ```
    </CodeGroup>

    | 状态          | 含义         |
    | ----------- | ---------- |
    | `NOT_FOUND` | 交易不存在或尚未挖矿 |
    | `INVALID`   | 哈希与请求的工具无关 |
    | `PENDING`   | 交易进行中      |
    | `DONE`      | 成功完成       |
    | `FAILED`    | 交易失败       |

    完整状态参考，请参见[交易状态跟踪](/introduction/user-flows-and-examples/status-tracking)。
  </Step>
</Steps>

***

## 完整工作示例

复制粘贴此完整示例来运行您的第一笔 Composer 交易：

<CodeGroup>
  ```ts TypeScript theme={"system"}
  import { ethers } from 'ethers';
  import axios from 'axios';

  const API_URL = 'https://li.quest/v1';

  // --- 配置 ---
  const PRIVATE_KEY = 'YOUR_PRIVATE_KEY';
  const RPC_URL = 'https://mainnet.base.org';
  const FROM_CHAIN = 8453;                                              // Base
  const FROM_TOKEN = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913';     // Base 上的 USDC
  const TO_TOKEN = '0x7BfA7C4f149E7415b73bdeDfe609237e29CBF34A';       // Morpho 金库代币
  const FROM_AMOUNT = '1000000';                                        // 1 USDC

  // --- 设置 ---
  const provider = new ethers.JsonRpcProvider(RPC_URL);
  const signer = new ethers.Wallet(PRIVATE_KEY, provider);

  // --- 辅助函数 ---
  const getQuote = async (fromAddress: string) => {
    const result = await axios.get(`${API_URL}/quote`, {
      params: {
        fromChain: FROM_CHAIN,
        toChain: FROM_CHAIN,
        fromToken: FROM_TOKEN,
        toToken: TO_TOKEN,
        fromAmount: FROM_AMOUNT,
        fromAddress,
        toAddress: fromAddress,
      },
    });
    return result.data;
  };

  const ERC20_ABI = [
    'function approve(address spender, uint256 amount) returns (bool)',
    'function allowance(address owner, address spender) view returns (uint256)',
  ];

  const ensureAllowance = async (
    tokenAddress: string,
    approvalAddress: string,
    amount: string
  ) => {
    const erc20 = new ethers.Contract(tokenAddress, ERC20_ABI, signer);
    const address = await signer.getAddress();
    const allowance = await erc20.allowance(address, approvalAddress);

    if (allowance < BigInt(amount)) {
      console.log('设置授权...');
      const tx = await erc20.approve(approvalAddress, amount);
      await tx.wait();
      console.log('授权已设置。');
    }
  };

  // --- 主函数 ---
  const run = async () => {
    const address = await signer.getAddress();
    console.log('钱包：', address);

    // 1. 获取报价
    console.log('请求 Composer 报价...');
    const quote = await getQuote(address);
    console.log('收到报价。工具：', quote.tool);
    console.log('估计输出：', quote.estimate.toAmount);

    // 2. 授权
    await ensureAllowance(
      quote.action.fromToken.address,
      quote.estimate.approvalAddress,
      quote.action.fromAmount
    );

    // 3. 执行
    console.log('发送交易...');
    const tx = await signer.sendTransaction(quote.transactionRequest);
    console.log('交易哈希：', tx.hash);

    const receipt = await tx.wait();
    console.log('在区块中确认：', receipt.blockNumber);
    console.log('完成！USDC 已存入 Morpho 金库。');
  };

  run().catch(console.error);
  ```
</CodeGroup>

***

## 刚才发生了什么？

在幕后，Composer：

1. **识别最优路径** — LI.FI 的路由引擎确定了将 USDC 转换为 Morpho 金库代币的最佳方式
2. **编译 eDSL 指令** — Composer 编译器为链上 VM 生成了字节码
3. **模拟执行** — 完整路径在返回报价之前被模拟，确保它会成功
4. **原子执行** — 您的单笔交易在一笔原子操作中兑换了 USDC 并存入了 Morpho

***

## 下一步

<CardGroup cols={3}>
  <Card title="跨链 Composer" icon="bridge" href="/composer/guides/cross-chain-compose">
    在单个流程中存入其他链上的协议
  </Card>

  <Card title="SDK 集成" icon="cube" href="/composer/guides/sdk-integration">
    使用 LI.FI SDK 进行托管执行，包含钩子和事件
  </Card>

  <Card title="金库存款配方" icon="book" href="/composer/recipes/vault-deposits">
    Morpho、Aave、Euler 等的复制粘贴配方
  </Card>
</CardGroup>
