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

# 发现与存入

> 端到端配方：使用 Earn Data API 为某个代币找到最佳收益金库，然后通过 Composer 在单笔交易中存入。

本配方将带你完成一次完整的 LI.FI Earn 集成：使用 Earn Data API 为特定代币找到收益最高的金库，将它们展示给用户，然后通过 Composer 执行存入。

<Note>
  \*\*两个层次，一个流程。\*\*本配方使用 **Earn Data API** 进行发现，使用 **Composer** 进行执行。Earn Data API 告诉你\_在哪里\_存入。Composer 负责\_如何\_存入。
</Note>

***

## 步骤 1：找到 Base 上最佳的 USDC 金库

向 Earn Data API 查询 Base 上按 APY 排序的 USDC 金库：

<CodeGroup>
  ```bash curl theme={"system"}
  curl -X GET 'https://earn.li.fi/v1/vaults?chainId=8453&asset=USDC&sortBy=apy&minTvlUsd=100000&limit=5'
  ```

  ```ts TypeScript theme={"system"}
  const discoverVaults = async (chainId: number, asset: string) => {
    const params = new URLSearchParams({
      chainId: String(chainId),
      asset,
      sortBy: 'apy',
      minTvlUsd: '100000', // Only vaults with $100k+ TVL
      limit: '5',
    });

    const response = await fetch(`https://earn.li.fi/v1/vaults?${params}`);
    const { data } = await response.json();
    return data;
  };

  const vaults = await discoverVaults(8453, 'USDC');
  ```
</CodeGroup>

***

## 步骤 2：筛选可存入的金库

并非所有金库都支持通过 Composer 存入。使用 `isTransactional` 标志进行筛选：

```ts TypeScript theme={"system"}
const depositableVaults = vaults.filter((vault) => vault.isTransactional);

// Display to user
depositableVaults.forEach((vault) => {
  console.log(`${vault.name} (${vault.protocol.name})`);
  console.log(`  APY: ${(vault.analytics.apy.total * 100).toFixed(2)}%`);
  console.log(`  TVL: $${Number(vault.analytics.tvl.usd).toLocaleString()}`);
  console.log(`  30d avg APY: ${(vault.analytics.apy30d * 100).toFixed(2)}%`);
  console.log(`  Deposit token: ${vault.address}`);
});
```

<Tip>
  将 `apy30d` 与 `apy.total` 结合使用，让用户了解收益的稳定性。一个当前 APY 很高但 30 天平均值较低的金库，可能正处于暂时的飙升期。
</Tip>

***

## 步骤 3：获取 Composer 报价

当用户选定一个金库时，将其合约地址用作 Composer 报价请求中的 `toToken`。这是从 Earn 到 Composer 的交接。

<CodeGroup>
  ```bash curl theme={"system"}
  # User selected the first vault, deposit 100 USDC
  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=100000000'
  ```

  ```ts TypeScript theme={"system"}
  const depositIntoVault = async (
    vault: any,
    fromToken: string,
    fromAmount: string,
    userAddress: string
  ) => {
    const params = new URLSearchParams({
      fromChain: String(vault.chainId),
      toChain: String(vault.chainId),
      fromToken,
      toToken: vault.address, // Vault contract address triggers Composer deposit
      fromAddress: userAddress,
      toAddress: userAddress,
      fromAmount,
    });

    const response = await fetch(`https://li.quest/v1/quote?${params}`);
    return response.json();
  };

  // Deposit 100 USDC into the top vault
  const selectedVault = depositableVaults[0];
  const quote = await depositIntoVault(
    selectedVault,
    '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', // USDC on Base
    '100000000', // 100 USDC (6 decimals)
    '0xYOUR_WALLET_ADDRESS'
  );

  console.log('Estimated output:', quote.estimate);
  console.log('Transaction to sign:', quote.transactionRequest);
  ```
</CodeGroup>

<Note>
  Composer 报价端点为 `https://li.quest/v1/quote`。这是 LI.FI Earn 的 Composer 层，而非 Earn Data API。有关参数、代币授权和交易提交的完整详情，请参阅 [Composer API 集成指南](/composer/guides/api-integration)。
</Note>

***

## 步骤 4：执行交易

提交报价响应中的交易。有关包含代币授权和状态追踪在内的完整执行流程，请参阅 [Composer API 集成指南](/composer/guides/api-integration#send-the-transaction)。

```ts TypeScript theme={"system"}
// Using viem
import { createPublicClient, createWalletClient, custom, http } from 'viem';
import type { Address, Hex } from 'viem';
import { base } from 'viem/chains';

const publicClient = createPublicClient({ chain: base, transport: http() });
const walletClient = createWalletClient({ chain: base, transport: custom(window.ethereum) });
const [account] = await walletClient.getAddresses();

// Send the transaction from the Composer quote
const hash = await walletClient.sendTransaction({
  account,
  to: quote.transactionRequest.to as Address,
  data: quote.transactionRequest.data as Hex,
  value: BigInt(quote.transactionRequest.value),
  gas: BigInt(quote.transactionRequest.gasLimit),
  gasPrice: BigInt(quote.transactionRequest.gasPrice),
});
console.log('Transaction sent:', hash);

const receipt = await publicClient.waitForTransactionReceipt({ hash });
console.log('Confirmed in block:', receipt.blockNumber);
```

***

## 步骤 5：验证持仓

存入确认后，使用 Earn 投资组合端点验证用户的新持仓：

<CodeGroup>
  ```bash curl theme={"system"}
  curl -X GET 'https://earn.li.fi/v1/portfolio/0xYOUR_WALLET_ADDRESS/positions'
  ```

  ```ts TypeScript theme={"system"}
  const response = await fetch(
    `https://earn.li.fi/v1/portfolio/0xYOUR_WALLET_ADDRESS/positions`
  );
  const { positions } = await response.json();

  // Find the position in the vault we just deposited into
  const newPosition = positions.find(
    (pos) => pos.address?.toLowerCase() === selectedVault.address.toLowerCase()
  );

  if (newPosition) {
    const usd = newPosition.balanceUsd ?? 'N/A';
    const protocol = newPosition.protocolName ?? 'unknown';
    console.log(`Position: $${usd} in ${protocol}`);
  }
  ```
</CodeGroup>

***

## 跨链存入

金库是特定于链的，但 Composer 可无缝处理跨链存入。要从不同的链存入，请更改报价请求中的 `fromChain` 和 `fromToken`：

```ts TypeScript theme={"system"}
// Deposit ETH from Ethereum into a USDC vault on Base
// Note: fromChain differs from vault's chain. Composer handles the bridge automatically.
const params = new URLSearchParams({
  fromChain: '1',        // Ethereum (where the user's funds are)
  toChain: '8453',       // Base (where the vault lives)
  fromToken: '0x0000000000000000000000000000000000000000', // ETH (native)
  toToken: selectedVault.address,                           // Vault contract address on Base
  fromAddress: '0xYOUR_WALLET_ADDRESS',
  toAddress: '0xYOUR_WALLET_ADDRESS',
  fromAmount: '100000000000000000', // 0.1 ETH
});

const response = await fetch(`https://li.quest/v1/quote?${params}`);
const crossChainQuote = await response.json();
// Composer routes: bridge ETH to Base, swap to USDC, deposit into vault, all in one transaction
```

Composer 的路由引擎会自动确定最优的桥接和交换路径。详情请参阅[跨链 Compose](/composer/guides/cross-chain-compose)。

***

## 完整示例

以下是单个函数中的完整流程：

```ts TypeScript theme={"system"}
const discoverAndDeposit = async (
  chainId: number,
  asset: string,
  fromToken: string,
  fromAmount: string,
  userAddress: string
) => {
  // 1. Discover vaults
  const vaultParams = new URLSearchParams({
    chainId: String(chainId),
    asset,
    sortBy: 'apy',
    minTvlUsd: '100000',
    limit: '5',
  });
  const { data: vaults } = await fetch(
    `https://earn.li.fi/v1/vaults?${vaultParams}`
  ).then((r) => r.json());

  // 2. Filter for depositable vaults
  const depositable = vaults.filter((v) => v.isTransactional);
  if (depositable.length === 0) throw new Error('No depositable vaults found');

  // 3. Pick the highest-APY vault
  const bestVault = depositable[0];
  console.log(
    `Best vault: ${bestVault.name} at ${(bestVault.analytics.apy.total * 100).toFixed(2)}% APY`
  );

  // 4. Get Composer quote
  const quoteParams = new URLSearchParams({
    fromChain: String(chainId),
    toChain: String(chainId),
    fromToken,
    toToken: bestVault.address,
    fromAddress: userAddress,
    toAddress: userAddress,
    fromAmount,
  });
  const quote = await fetch(
    `https://li.quest/v1/quote?${quoteParams}`
  ).then((r) => r.json());

  return { vault: bestVault, quote };
};

// Usage
const { vault, quote } = await discoverAndDeposit(
  8453,
  'USDC',
  '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
  '100000000', // 100 USDC
  '0xYOUR_WALLET_ADDRESS'
);
```

***

## 相关内容

<CardGroup cols={2}>
  <Card title="Earn API 参考" icon="code" href="/earn/guides/api-integration">
    包含所有参数的完整端点参考
  </Card>

  <Card title="Composer 金库存入" icon="book" href="/composer/recipes/vault-deposits">
    更多包含协议特定示例的金库存入配方
  </Card>

  <Card title="Composer API 指南" icon="code" href="/composer/guides/api-integration">
    完整的 Composer 集成指南，包含授权和状态追踪
  </Card>

  <Card title="跨链 Compose" icon="bridge" href="/composer/guides/cross-chain-compose">
    跨链存入模式和桥接选择
  </Card>
</CardGroup>
