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

# Strategy Deposit

> Complete example of depositing funds into a DeFi yield strategy

This example demonstrates how to deposit funds into a DeFi yield strategy (e.g., Aave lending) using the Pods API with JavaScript/TypeScript.

## Overview

This example covers:

* Fetching available strategies
* Getting strategy details
* Requesting a quote
* Generating transaction bytecode
* Executing transactions
* Verifying the deposit

## Prerequisites

* Node.js 18+
* Pods API key
* Ethereum wallet with USDC balance
* Basic understanding of async/await

## Installation

<Tabs>
  <Tab title="ethers.js">
    ```bash theme={null}
    npm install axios ethers
    ```
  </Tab>

  <Tab title="viem">
    ```bash theme={null}
    npm install axios viem
    ```
  </Tab>
</Tabs>

## Environment Variables

Create a `.env` file:

```bash theme={null}
PODS_API_KEY=your-api-key
WALLET_ADDRESS=0x...
PRIVATE_KEY=0x...
ETHEREUM_RPC_URL=https://eth-mainnet.g.alchemy.com/v2/your-key
POLYGON_RPC_URL=https://polygon-mainnet.g.alchemy.com/v2/your-key
```

<Warning>
  Never commit your `.env` file to version control. Add it to `.gitignore`.
</Warning>

## Step-by-Step Walkthrough

### 1. Initialize API Client

```javascript theme={null}
import axios from 'axios'

const pods = axios.create({
  baseURL: 'https://api.pods.finance',
  headers: {
    'x-api-key': process.env.PODS_API_KEY,
    'Content-Type': 'application/json'
  }
})
```

### 2. Fetch Available Strategies

```javascript theme={null}
const { data: strategies } = await pods.get('/strategies', {
  params: { page: '1', limit: '10' }
})

console.log('Available strategies:')
strategies.data.forEach(strategy => {
  console.log(`- ${strategy.id} (${strategy.protocol})`)
  console.log(`  APY: ${(strategy.apy * 100).toFixed(2)}%`)
})
```

### 3. Get Strategy Details

```javascript theme={null}
const strategyId = 'aave-usdc-polygon'
const { data: strategy } = await pods.get(`/strategies/${strategyId}`)

console.log('Strategy:', strategy.id)
console.log('Protocol:', strategy.protocol)
console.log('Network:', strategy.network)
console.log('Asset:', strategy.assetName)
console.log('APY:', (strategy.apy * 100).toFixed(2) + '%')
console.log('Status:', strategy.paused ? 'Paused' : 'Active')
```

### 4. Generate Bytecode

```javascript theme={null}
const { data: result } = await pods.get('/strategies/aave-usdc-polygon/bytecode', {
  params: {
    action: 'lend',
    amount: '1000000000',
    wallet: walletAddress
  }
})

console.log('ID:', result.id)
console.log('Transactions to execute:', result.bytecode.length)
```

#### Same-Chain Swap + Deposit

If you hold a different token (e.g., WETH) and want to deposit into a USDC strategy, pass the `fromTokenAddress` parameter. The API will return swap transaction(s) followed by the deposit bytecode:

```javascript theme={null}
const { data: result } = await pods.get('/strategies/aave-usdc-polygon/bytecode', {
  params: {
    action: 'lend',
    amount: '1000000000000000000', // 1 WETH (amount is in fromTokenAddress units)
    wallet: walletAddress,
    fromChainId: 137,
    fromTokenAddress: '0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619' // WETH on Polygon
  }
})

console.log('Cross-chain:', result.crossChain.isCrossChain) // false
console.log('Transactions to execute:', result.bytecode.length) // e.g. 2 (swap + deposit)
```

<Note>
  When `fromTokenAddress` is provided, include `fromChainId` or `chainIdIn`. For same-chain swap + deposit, use the strategy chain. The `amount` parameter refers to the amount of that token to swap, not the strategy's underlying asset.
</Note>

#### Cross-Chain Deposit

If the funds start on a different chain, pass `fromChainId` or `chainIdIn` plus `fromTokenAddress`. Store `result.id`; it is used for asynchronous tracking.

```javascript theme={null}
const { data: result } = await pods.get('/strategies/aave-usdc-arbitrum/bytecode', {
  params: {
    action: 'lend',
    amount: '1000000',
    wallet: walletAddress,
    fromChainId: 8453,
    fromTokenAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913' // USDC on Base
  }
})

console.log('ID:', result.id)
console.log('Bridge:', result.quote.bridge)
console.log('Source chain:', result.chainIdIn)
console.log('Destination chain:', result.chainIdOut)
```

### 5. Execute Transactions (atomic batch)

<Warning>
  **Do not loop `sendTransaction` over `result.bytecode`.** Batch all same-chain legs into one
  transaction. See [Executing Bytecode](/getting-started/executing-bytecode).
</Warning>

**EOA (recommended):** use [EIP-7702 `executeBatch`](/examples/javascript/using-eip7702) or run
[`strategy-deposit-eip7702.js`](/examples/javascript/strategy-deposit-eip7702.js) /
[`eip7702-batch.js`](/examples/javascript/eip7702-batch.js).

**Smart account:** add `output=userOperation` and submit via your bundler —
[Smart Account Deposit](/examples/javascript/smart-account-deposit).

```javascript theme={null}
import { http, createWalletClient, publicActions } from 'viem'
import { polygon } from 'viem/chains'
import { privateKeyToAccount } from 'viem/accounts'
import { executeLegsViaEip7702 } from './eip7702-batch.js'

const account = privateKeyToAccount(process.env.PRIVATE_KEY)
const walletClient = createWalletClient({
  account,
  chain: polygon,
  transport: http(process.env.POLYGON_RPC_URL)
}).extend(publicActions)

const receipt = await executeLegsViaEip7702(walletClient, result.bytecode)
console.log('Confirmed in block:', receipt.blockNumber)
```

### 6. Verify Deposit

```javascript theme={null}
// Wait for indexing
await new Promise(resolve => setTimeout(resolve, 5000))

const { data: walletData } = await pods.get(`/wallets/${walletAddress}`)

console.log('Wallet positions:')
walletData.positions.forEach(position => {
  console.log(`${position.strategy.id}:`)
  console.log(`  Balance: ${position.spotPosition.currentPosition.humanized} ${position.spotPosition.currentPosition.symbol}`)
  console.log(`  Value: $${position.spotPosition.underlyingBalanceUSD}`)
  console.log(`  APY: ${(position.spotPosition.apy * 100).toFixed(2)}%`)
})

console.log('Total portfolio value: $' + walletData.summary.totalUnderlyingBalanceUSD)
```

### 7. Track Cross-Chain Deposit Status (Cross-Chain Only)

If you made a cross-chain deposit, the bridge and the destination-chain deposit happen in separate transactions and complete asynchronously. Use the `id` returned in the bytecode response to poll `/actions/:id` until the status reaches a terminal state.

```javascript theme={null}
const id = result.id // returned from /strategies/:id/bytecode

// (Optional) preview the bridge & expected output before signing
if (result.crossChain.isCrossChain) {
  console.log(`Bridging via ${result.quote.bridge}`)
  console.log(`Expected out: ${result.quote.outputAmount.humanized} ${result.quote.outputAmount.symbol}`)
  console.log(`Min out:      ${result.quote.minimumOutputAmount.humanized} ${result.quote.minimumOutputAmount.symbol}`)
}

async function waitForDeposit (id) {
  const TERMINAL = ['SUCCESS', 'FAILED', 'REFUNDED', 'EXPIRED']

  while (true) {
    const { data: statusRecord } = await pods.get(`/actions/${id}`)
    console.log(`Status: ${statusRecord.status} (${statusRecord.transactions.length} tx)`)

    if (TERMINAL.includes(statusRecord.status)) return statusRecord

    await new Promise(resolve => setTimeout(resolve, 5000))
  }
}

const finalStatus = await waitForDeposit(id)
console.log('Final transactions:')
finalStatus.transactions.forEach(tx => {
  console.log(`  ${tx.chain}: ${tx.txHash} (${tx.status})`)
})
```

### 8. Track Cross-Chain Deposit Status (Cross-Chain Only)

If you made a cross-chain deposit (you passed `fromChainId` in Step 5), the bridge and the destination-chain deposit happen in separate transactions and complete asynchronously. Use the `id` returned in the bytecode response to poll `/actions/:id` until the action reaches a terminal state.

```javascript theme={null}
const actionId = result.id // returned from /strategies/:id/bytecode

// (Optional) preview the bridge & expected output before signing
if (result.crossChain.isCrossChain) {
  console.log(`Bridging via ${result.quote.bridge}`)
  console.log(`Expected out: ${result.quote.outputAmount.humanized} ${result.quote.outputAmount.symbol}`)
  console.log(`Min out:      ${result.quote.minimumOutputAmount.humanized} ${result.quote.minimumOutputAmount.symbol}`)
}

async function waitForDeposit (actionId) {
  const TERMINAL = ['SUCCESS', 'FAILED', 'REFUNDED', 'EXPIRED']

  while (true) {
    const { data: action } = await pods.get(`/actions/${actionId}`)
    console.log(`Status: ${action.status} (${action.transactions.length} tx)`)

    if (TERMINAL.includes(action.status)) return action

    await new Promise(resolve => setTimeout(resolve, 5000))
  }
}

const finalAction = await waitForDeposit(actionId)
console.log('Final transactions:')
finalAction.transactions.forEach(tx => {
  console.log(`  ${tx.chain}: ${tx.txHash} (${tx.status})`)
})
```

<Note>
  Same-chain deposits do not require polling — the deposit completes inline with the user's signed transaction. You can still call `GET /actions/:id` with the returned `id` for record-keeping.
</Note>

## Error Handling

The example includes comprehensive error handling:

```javascript theme={null}
try {
  // Your code here
} catch (error) {
  if (error.response?.data?.error) {
    const apiError = error.response.data.error
    console.error('API Error:', apiError.code)
    console.error('Message:', apiError.message)

    // Handle specific errors
    if (apiError.code === 'STRATEGY_NOT_FOUND') {
      console.log('Strategy does not exist or is not available')
    } else if (apiError.code === 'INSUFFICIENT_BALANCE') {
      console.log('Wallet does not have enough tokens')
    }
  } else {
    console.error('Unexpected error:', error.message)
  }
}
```

## Running the Example

```bash theme={null}
# Install dependencies
npm install

# Set environment variables
cp .env.example .env
# Edit .env with your values

# Run the example
node strategy-deposit.js
```

## Expected Output

```
1️⃣  Fetching available strategies...
✅ Available strategies:
   - Aave-USDC-polygon (Aave)
     APY: 4.50%
   - Morpho-BTC-base (Morpho)
     APY: 3.20%

2️⃣  Getting details for Aave-USDC-polygon...
✅ Strategy details:
   Strategy: Aave-USDC-polygon
   Protocol: Aave
   Network: polygon
   Asset: USDC
   APY: 4.50%
   Status: ✅ Active

4️⃣  Generating deposit bytecode...
✅ Bytecode generated:
   ID: 65f3a1c8e9b2d4f8a7c1d2e3
   Transactions: 2

5️⃣  Executing atomic EIP-7702 batch...
   ✅ Confirmed in block 12345678

6️⃣  Verifying deposit...
✅ Wallet positions:
   Aave-USDC-polygon:
      Balance: 1000.00 USDC
      Value: $1000.00
      APY: 4.17%

   Total Portfolio Value: $1000.00

🎉 Strategy deposit completed successfully!
```

## Next Steps

<CardGroup cols={2}>
  <Card title="EIP-7702 Batch Deposit" icon="bolt" href="/examples/javascript/using-eip7702">
    Atomic EOA execution (recommended)
  </Card>

  <Card title="Executing Bytecode" icon="layer-group" href="/getting-started/executing-bytecode">
    Output types and wallet decision tree
  </Card>

  <Card title="Strategy Withdrawal" href="/examples/javascript/strategy-withdraw">
    Withdraw from strategies, including cross-chain withdrawals
  </Card>

  <Card title="Cross-Chain Swap" href="/examples/javascript/cross-chain-swap">
    Execute cross-chain token swaps
  </Card>

  <Card title="Check Positions" href="/guides/yield/check-positions">
    Track wallet positions
  </Card>

  <Card title="API Reference" href="/api-reference/introduction">
    View complete API documentation
  </Card>
</CardGroup>
