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

# Build Deposit Transaction

> POST /damm/deposit/build - Create unsigned transaction for depositing liquidity into Meteora DAMM v2 pool

## Overview

Creates an unsigned transaction for depositing liquidity into a Meteora DAMM v2 (Dynamic AMM) pool. The API validates the deposit amounts, builds a combined transaction that transfers tokens from the manager wallet to the LP owner and adds liquidity to the pool, and returns the transaction ready for manager wallet signing.

<Warning>
  **Manager-only operation**: This endpoint requires the manager wallet to sign and submit the transaction. The manager wallet must be configured via the `MANAGER_WALLET` environment variable.
</Warning>

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST https://api.zcombinator.io/damm/deposit/build \
    -H "Content-Type: application/json" \
    -d '{
      "tokenAAmount": 1000,
      "tokenBAmount": 0.5
    }'
  ```

  ```javascript fetch theme={null}
  const response = await fetch('https://api.zcombinator.io/damm/deposit/build', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      tokenAAmount: 1000,
      tokenBAmount: 0.5
    })
  });

  const result = await response.json();
  ```

  ```python requests theme={null}
  import requests

  data = {
      "tokenAAmount": 1000,
      "tokenBAmount": 0.5
  }

  response = requests.post(
      'https://api.zcombinator.io/damm/deposit/build',
      json=data,
      headers={'Content-Type': 'application/json'}
  )

  result = response.json()
  ```
</CodeGroup>

## Request Parameters

<ParamField body="tokenAAmount" type="number" required>
  Amount of Token A to deposit (in UI units, e.g., 1000 for 1000 USDC). Must be non-negative.
</ParamField>

<ParamField body="tokenBAmount" type="number" required>
  Amount of Token B to deposit (in UI units, e.g., 0.5 for 0.5 SOL). Must be non-negative.
</ParamField>

<Note>
  **UI units**: Amounts are specified in human-readable units (e.g., 1.5 SOL, not 1500000000 lamports). The API automatically converts to raw token amounts based on token decimals.
</Note>

## Response

<ResponseField name="success" type="boolean">
  Indicates if the operation was successful
</ResponseField>

<ResponseField name="transaction" type="string">
  Base58 encoded unsigned transaction that needs to be signed by the manager wallet
</ResponseField>

<ResponseField name="requestId" type="string">
  Unique identifier for this deposit request (needed for confirmation)
</ResponseField>

<ResponseField name="poolAddress" type="string">
  Address of the Meteora DAMM v2 pool
</ResponseField>

<ResponseField name="tokenAMint" type="string">
  Mint address of Token A in the pool
</ResponseField>

<ResponseField name="tokenBMint" type="string">
  Mint address of Token B in the pool
</ResponseField>

<ResponseField name="isTokenBNativeSOL" type="boolean">
  Whether Token B is native SOL (handled specially in transfers)
</ResponseField>

<ResponseField name="instructionsCount" type="number">
  Number of instructions in the transaction
</ResponseField>

<ResponseField name="amounts" type="object">
  Object containing deposit amounts (in raw token units):

  * `tokenA` (string): Token A amount in raw units
  * `tokenB` (string): Token B amount in raw units
  * `liquidityDelta` (string): Liquidity amount to be added
</ResponseField>

<ResponseField name="message" type="string">
  Instructions for the next step in the process
</ResponseField>

### Success Response

```json theme={null}
{
  "success": true,
  "transaction": "4MzR7dxJNJRVP1Q6k7Y3j8X...",
  "requestId": "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6",
  "poolAddress": "CPMMoo8L3F4NbTegBCKVNunggL7H1ZpdTHKxQB5qKP1C",
  "tokenAMint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
  "tokenBMint": "So11111111111111111111111111111111111111112",
  "isTokenBNativeSOL": true,
  "instructionsCount": 9,
  "amounts": {
    "tokenA": "1000000000",
    "tokenB": "500000000",
    "liquidityDelta": "707106781"
  },
  "message": "Sign this transaction with the manager wallet and submit to /damm/deposit/confirm"
}
```

## Error Responses

<AccordionGroup>
  <Accordion title="400 - Missing Parameters">
    ```json theme={null}
    {
      "error": "Missing required fields: tokenAAmount and tokenBAmount"
    }
    ```
  </Accordion>

  <Accordion title="400 - Invalid Amount Type">
    ```json theme={null}
    {
      "error": "tokenAAmount and tokenBAmount must be numbers"
    }
    ```

    Both amounts must be valid numbers, not strings or other types.
  </Accordion>

  <Accordion title="400 - Negative Amounts">
    ```json theme={null}
    {
      "error": "Token amounts must be non-negative"
    }
    ```

    Deposit amounts cannot be negative.
  </Accordion>

  <Accordion title="404 - No Positions Found">
    ```json theme={null}
    {
      "error": "No positions found for the LP owner. Create a position first."
    }
    ```

    The protocol wallet does not have any LP positions in the configured pool. A position must be created before depositing.
  </Accordion>

  <Accordion title="400 - Deposit Too Small">
    ```json theme={null}
    {
      "error": "Deposit amount too small"
    }
    ```

    The calculated liquidity delta is too small to process (rounds to zero).
  </Accordion>

  <Accordion title="500 - Configuration Error">
    ```json theme={null}
    {
      "error": "Server configuration incomplete. Missing required environment variables."
    }
    ```

    The server is not properly configured to process deposit requests.
  </Accordion>

  <Accordion title="500 - Transaction Creation Failed">
    ```json theme={null}
    {
      "error": "Failed to create deposit transaction"
    }
    ```
  </Accordion>
</AccordionGroup>

## Process Flow

This endpoint performs several steps to build the deposit transaction:

<Steps>
  <Step title="Validate Parameters">
    Ensures tokenAAmount and tokenBAmount are provided, are valid numbers, and are non-negative
  </Step>

  <Step title="Validate Server Configuration">
    Checks that the server is properly configured to process deposit requests
  </Step>

  <Step title="Verify Authorization">
    Validates that the manager wallet is authorized to deposit funds
  </Step>

  <Step title="Fetch Pool State">
    Retrieves the current state of the Meteora DAMM v2 pool
  </Step>

  <Step title="Convert to Raw Amounts">
    Converts UI amounts to raw token amounts based on token decimals (e.g., 1.5 SOL → 1500000000 lamports)
  </Step>

  <Step title="Get User Positions">
    Fetches all LP positions owned by the protocol wallet (uses first position)
  </Step>

  <Step title="Calculate Liquidity Amount">
    Calculates the liquidity amount based on token amounts and current pool state
  </Step>

  <Step title="Build Transaction">
    Creates a transaction that:

    * Transfers tokens from manager wallet
    * Adds liquidity to the pool position
    * Creates any needed token accounts
  </Step>

  <Step title="Handle Native SOL">
    If Token B is native SOL, uses SystemProgram.transfer instead of SPL token transfer
  </Step>

  <Step title="Generate Security Hash">
    Creates a security hash for tamper detection during confirmation
  </Step>

  <Step title="Generate Request ID">
    Creates a unique request ID for tracking this deposit request
  </Step>

  <Step title="Return Unsigned Transaction">
    Returns the Base58 encoded transaction for manager wallet signing
  </Step>
</Steps>

## Liquidity Calculation

The liquidity amount is calculated based on:

* Current pool price
* Pool price range
* Token amounts being deposited
* Token metadata (decimals, transfer fees, etc.)

The calculation ensures optimal liquidity provision based on the current pool state.

<Note>
  **First position only**: This endpoint deposits to the first position in the pool. If multiple positions exist, deposits go to the first position.
</Note>

## Native SOL Handling

<Info>
  **Special handling for wrapped SOL (wSOL)**:

  When Token B is the native SOL mint (So11111111111111111111111111111111111111112):

  1. The manager wallet transfers native SOL to the LP owner
  2. Meteora automatically wraps SOL during the add liquidity operation
  3. No intermediate token account is needed for Token B
  4. The deposit flow uses `SystemProgram.transfer` for the initial transfer
</Info>

## Request ID

The response includes a `requestId`:

* **Format**: Random 16-byte hex string for identifying the request
* **Validity**: Must be used within 10 minutes
* **Required**: Must be provided to [`/damm/deposit/confirm`](/api-reference/damm-liquidity/deposit-confirm)
* **One-time use**: Cannot be reused after confirmation

## Rate Limiting

This endpoint is subject to rate limiting:

* **10 requests** per 5-minute window per IP
* Returns HTTP 429 when limit exceeded with message: "Too many liquidity requests, please wait a moment."

## Security Considerations

<Warning>
  **Manager authorization required**:

  * Only the configured manager wallet can sign and confirm deposits
  * Tokens are transferred from manager wallet to LP owner, then added to pool
  * LP owner's signature is added automatically by the API
  * Transaction hash validation prevents tampering during confirmation
  * This ensures only authorized deposits to the pool
</Warning>

## Next Steps

After receiving the unsigned transaction:

1. **Deserialize** the transaction using `@solana/web3.js`
2. **Sign** the transaction with your manager wallet
3. **Submit** the signed transaction to [`/damm/deposit/confirm`](/api-reference/damm-liquidity/deposit-confirm)

<Warning>
  **Important**: Do not modify the transaction after signing. The confirmation endpoint validates the transaction hash to detect any tampering.
</Warning>

## Request Expiration

Deposit requests expire after a period of time:

* **Validity**: You must call `/damm/deposit/confirm` within 10 minutes
* **After expiration**: You'll need to create a new deposit request

## Token Balance Requirements

<Note>
  **Manager wallet must have sufficient balance**:

  * Token A balance >= tokenAAmount (in UI units)
  * Token B balance >= tokenBAmount (in UI units)
  * SOL balance for transaction fees

  If balances are insufficient, the transaction will fail during submission.
</Note>

## Related Endpoints

* [`/damm/deposit/confirm`](/api-reference/damm-liquidity/deposit-confirm) - Confirm and submit the deposit transaction
* [`/damm/withdraw/build`](/api-reference/damm-liquidity/withdraw-build) - Build withdrawal transaction
