> ## Documentation Index
> Fetch the complete documentation index at: https://docs.compasslabs.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Earn

> Earn lets your users generate yield on stablecoins and crypto assets by depositing into DeFi venues.

export const GithubCodeBlock = ({typescript, python}) => {
  const [typescriptCode, setTypescriptCode] = useState("");
  const [pythonCode, setPythonCode] = useState("");
  function removeWhitespace(strings, x) {
    return strings.map(str => {
      let count = 0;
      let i = 0;
      while (i < str.length && count < x && str[i] === " ") {
        count++;
        i++;
      }
      return str.slice(i);
    });
  }
  function cropToSnippet({text, from, to}) {
    const lines = text.split("\n");
    let result = [];
    let isCollecting = false;
    for (const line of lines) {
      if (line.trim() === from) {
        isCollecting = true;
        continue;
      }
      if (line.trim() === to) {
        break;
      }
      if (isCollecting) {
        result.push(line);
      }
    }
    const whitespaceToDelete = result[0].length - result[0].trimStart().length;
    result = removeWhitespace(result, whitespaceToDelete);
    return result.join("\n");
  }
  function removeSnippetComments(code) {
    return code.replace(/(\/\/|#) SNIPPET (START|END) \d+(\n|$)/g, "");
  }
  useEffect(() => {
    if (!typescript) return;
    fetch(typescript.url).then(response => response.text()).then(text => {
      let code = text;
      if (typescript.snippetNumber) {
        code = cropToSnippet({
          text,
          from: `// SNIPPET START ${typescript.snippetNumber}`,
          to: `// SNIPPET END ${typescript.snippetNumber}`
        });
      } else {
        code = removeSnippetComments(code);
      }
      setTypescriptCode(code);
    }).catch(error => {
      console.error("Error loading file:", error);
    });
  }, [typescript]);
  useEffect(() => {
    if (!python) return;
    fetch(python.url).then(response => response.text()).then(text => {
      let code = text;
      if (python.snippetNumber) {
        code = cropToSnippet({
          text,
          from: `# SNIPPET START ${python.snippetNumber}`,
          to: `# SNIPPET END ${python.snippetNumber}`
        });
      } else {
        code = removeSnippetComments(code);
      }
      setPythonCode(code);
    }).catch(error => {
      console.error("Error loading file:", error);
    });
  }, [python]);
  if (!python && !typescript) return null;
  if (!python) {
    return <CodeBlock language="typescript" filename={typescript.name} expandable={typescript?.numOfLinesExpandable ? "true" : null} lines="true" icon="https://upload.wikimedia.org/wikipedia/commons/f/f5/Typescript.svg" code={typescriptCode} children={typescriptCode || !typescript?.numOfLinesExpandable || <div style={{
      whiteSpace: "pre-wrap"
    }}>
        {Array(typescript?.numOfLinesExpandable).fill("-").map(x => x).join("\n")}
      </div>} />;
  }
  if (!typescript) {
    return <CodeBlock language="python" filename={python.name} expandable={python?.numOfLinesExpandable ? "true" : null} lines="true" icon="https://upload.wikimedia.org/wikipedia/commons/c/c3/Python-logo-notext.svg" code={pythonCode} children={pythonCode || !python?.numOfLinesExpandable || <div style={{
      whiteSpace: "pre-wrap"
    }}>
        {Array(python?.numOfLinesExpandable).fill("-").map(x => x).join("\n")}
      </div>} />;
  }
  return <CodeGroup>
  <CodeBlock language="typescript" filename={typescript.name} expandable={typescript?.numOfLinesExpandable ? "true" : null} lines="true" icon="https://upload.wikimedia.org/wikipedia/commons/f/f5/Typescript.svg" code={typescriptCode} children={typescriptCode || !typescript?.numOfLinesExpandable || <div style={{
    whiteSpace: "pre-wrap"
  }}>
          {Array(typescript?.numOfLinesExpandable).fill("-").map(x => x).join("\n")}
        </div>} />
  <CodeBlock language="python" filename={python.name} expandable={python?.numOfLinesExpandable ? "true" : null} lines="true" icon="https://upload.wikimedia.org/wikipedia/commons/c/c3/Python-logo-notext.svg" code={pythonCode} children={pythonCode || !python?.numOfLinesExpandable || <div style={{
    whiteSpace: "pre-wrap"
  }}>
          {Array(python?.numOfLinesExpandable).fill("-").map(x => x).join("\n")}
        </div>} />
</CodeGroup>;
};

## Why This Matters

Building yield products from scratch means months of work across DeFi protocols, managing smart contract interactions, tracking positions across chains, and ongoing maintenance. We've done that - you get one API that covers everything to get your yield product live in days.

## What It Does

Let users deposit stablecoins and crypto assets into DeFi yield venues (lending protocols and yield vaults) and track positions. Build products that aggregate yield across multiple protocols, automatically rebalance for optimal returns, or manage treasury operations for businesses.

You call our API, we return a transaction payload. You or your users sign and broadcast. Users earn yield, you capture fees.

**Important:** Users must first create an [Earn Account](/v2/Products/Accounts) (the API-level account that holds your Earn positions) before depositing into yield venues.

## Supported Venues

A venue is a DeFi market or vault where users can deploy funds to generate yield.

| Protocol            | Type                | What it does                                                                                      |
| ------------------- | ------------------- | ------------------------------------------------------------------------------------------------- |
| **Aave V3**         | Lending market      | Deposit assets, earn variable rate from borrowers                                                 |
| **Morpho**          | Vaults + Markets    | Optimized lending with curated risk management, and markets to earn variable rates from borrowers |
| **ERC-4626 Vaults** | Standardized vaults | Yield from various strategies                                                                     |

For fixed yield, use [Fixed Earn](/v2/Products/Fixed-Earn) with Pendle to lock in rates for 30, 90, or 180 days.

We support dozens of yield venues across multiple chains. If you need a specific venue, we can add it.

## Venue Data & Analytics

### Vaults

For each ERC-4626 vault, we return the address, chain, underlying asset, TVL, and APY over 7, 30, and 90 days. Filter by chain or asset symbol, sort by TVL or APY.

### Aave Markets

For each Aave market, we return supply and borrow APY by chain. We also surface which chain has the highest supply rate for each token, useful if you want to route deposits to the best opportunity automatically.

### Positions

For each user position, we return the current balance, vault name, and full PnL breakdown: total deposited, total withdrawn, cost basis, realized and unrealized PnL, total yield earned, and fees paid. Every deposit and withdrawal is logged with block number and transaction hash, enough detail for tax reporting or building a transaction history UI.

### Example: Get Top Vault by 30-Day Net Annualized Return

Fetch the top vault sorted by 30-day net annualized return (after fees) to help users find the best performing opportunities:

<GithubCodeBlock
  typescript={{
name: "index.ts",
url: "https://raw.githubusercontent.com/CompassLabs/api_usecases/main/v2/earn_vault_data/typescript/src/index.ts",
snippetNumber: 2,
}}
  python={{
name: "main.py",
url: "https://raw.githubusercontent.com/CompassLabs/api_usecases/main/v2/earn_vault_data/python/main.py",
snippetNumber: 2,
}}
/>

## Manage Earn Positions

Deposit into yield vaults and manage positions with just a few lines of code.

### Deposit into a Vault

Deposit into the Steakhouse USDC vault on Morpho. This walk-through sends 0.5 USDC from the owner's Earn Account into the vault, without embedding a fee and without gas sponsorship. If you want to monetize flows or cover gas for users, set the `fee` and `gasSponsorship` fields accordingly; the SDK call stays the same.

<GithubCodeBlock
  typescript={{
name: "index.ts",
url: "https://raw.githubusercontent.com/CompassLabs/api_usecases/main/v2/manage_earn_position/typescript/src/index.ts",
snippetNumber: 3,
}}
  python={{
name: "main.py",
url: "https://raw.githubusercontent.com/CompassLabs/api_usecases/main/v2/manage_earn_position/python/main.py",
snippetNumber: 3,
}}
/>

Sign and broadcast the transaction:

<GithubCodeBlock
  typescript={{
name: "index.ts",
url: "https://raw.githubusercontent.com/CompassLabs/api_usecases/main/v2/manage_earn_position/typescript/src/index.ts",
snippetNumber: 4,
}}
  python={{
name: "main.py",
url: "https://raw.githubusercontent.com/CompassLabs/api_usecases/main/v2/manage_earn_position/python/main.py",
snippetNumber: 4,
}}
/>

### Check Your Positions

<GithubCodeBlock
  typescript={{
name: "index.ts",
url: "https://raw.githubusercontent.com/CompassLabs/api_usecases/main/v2/manage_earn_position/typescript/src/index.ts",
snippetNumber: 5,
}}
  python={{
name: "main.py",
url: "https://raw.githubusercontent.com/CompassLabs/api_usecases/main/v2/manage_earn_position/python/main.py",
snippetNumber: 5,
}}
/>

## Use Cases

**Consumer:** Build a yield savings product that deposits across Aave, Morpho simultaneously. Show users one aggregated APY while spreading risk across protocols.

*Example: User deposits \$10,000 split between Aave (5.2% APY) and Morpho (6.1% APY). App shows combined 5.65% APY. After one year, user earns \$565 in yield.* You embed a 10% fee on earned yield.

**Automated Rebalancing:** Monitor rates across protocols and automatically rebalance user funds to maximize yield. When Morpho offers 6.2% but Aave drops to 4.8%, rebalance atomically.

*Example: \$50,000 in Aave earning 4.8% (\$2,400/year). Rebalance to Morpho at 6.2% (\$3,100/year). Net gain: \$700 additional yield annually.*

**Treasury Management**: Let businesses earn on idle capital. Deposit stablecoin balances into yield vaults, track performance for CFO dashboards, and maintain liquidity for operations.

*Example: Company with \$1M average idle stablecoin balance earns 5.5% APY (\$55,000/year) while maintaining full liquidity.*

## Next Steps

<CardGroup cols={3}>
  <Card title="Product Accounts" icon="wallet" href="/v2/Products/Accounts">
    Create isolated accounts for managing DeFi positions.
  </Card>

  <Card title="Embedded Fees" icon="coins" href="/v2/Products/Embedded-fees">
    Monetize your yield product by embedding fees into transactions.
  </Card>

  <Card title="Gas Sponsorship" icon="gas-pump" href="/v2/Products/gas-sponsorship">
    Sponsor gas for your users so they never need ETH.
  </Card>
</CardGroup>
