Skip to main content

Overview

Creates an unsigned transaction for withdrawing liquidity from a Meteora DAMM v2 (Dynamic AMM) pool. The API validates available liquidity, builds a combined transaction that removes liquidity and transfers withdrawn tokens to the manager wallet, and returns the transaction ready for manager wallet signing.
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.
curl -X POST https://api.zcombinator.io/damm/withdraw/build \
  -H "Content-Type: application/json" \
  -d '{
    "withdrawalPercentage": 12.5
  }'

Request Parameters

withdrawalPercentage
number
required
Percentage of unlocked liquidity to withdraw (0 < value <= 15). For example, 12.5 withdraws 12.5% of available liquidity. Maximum 15% to prevent excessive liquidity removal.

Response

success
boolean
Indicates if the operation was successful
transaction
string
Base58 encoded unsigned transaction that needs to be signed by the manager wallet
requestId
string
Unique identifier for this withdrawal request (needed for confirmation)
poolAddress
string
Address of the Meteora DAMM v2 pool
tokenAMint
string
Mint address of Token A in the pool
tokenBMint
string
Mint address of Token B in the pool
isTokenBNativeSOL
boolean
Whether Token B is native SOL (handled specially in transfers)
withdrawalPercentage
number
The withdrawal percentage requested
instructionsCount
number
Number of instructions in the transaction
estimatedAmounts
object
Object containing estimated withdrawal amounts:
  • tokenA (string): Estimated Token A amount to be withdrawn
  • tokenB (string): Estimated Token B amount to be withdrawn
  • liquidityDelta (string): Amount of liquidity being removed
message
string
Instructions for the next step in the process

Success Response

{
  "success": true,
  "transaction": "4MzR7dxJNJRVP1Q6k7Y3j8X...",
  "requestId": "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6",
  "poolAddress": "CPMMoo8L3F4NbTegBCKVNunggL7H1ZpdTHKxQB5qKP1C",
  "tokenAMint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
  "tokenBMint": "So11111111111111111111111111111111111111112",
  "isTokenBNativeSOL": true,
  "withdrawalPercentage": 12.5,
  "instructionsCount": 7,
  "estimatedAmounts": {
    "tokenA": "5000000",
    "tokenB": "2500000000",
    "liquidityDelta": "1000000"
  },
  "message": "Sign this transaction with the manager wallet and submit to /damm/withdraw/confirm"
}

Error Responses

{
  "error": "Missing required field: withdrawalPercentage"
}
{
  "error": "withdrawalPercentage must be a number between 0 and 15"
}
The withdrawal percentage must be greater than 0 and not exceed 15. This limit prevents excessive liquidity removal in a single transaction.
{
  "error": "No positions found for the LP owner in this pool"
}
The protocol wallet does not have any LP positions in the configured pool.
{
  "error": "No unlocked liquidity in position"
}
The position has no available liquidity to withdraw (all liquidity may be locked).
{
  "error": "Withdrawal amount too small"
}
The calculated withdrawal amount is too small to process (rounds to zero).
{
  "error": "Server configuration incomplete. Missing required environment variables."
}
The server is not properly configured to process withdrawal requests.
{
  "error": "Failed to create withdrawal transaction"
}

Process Flow

This endpoint performs several steps to build the withdrawal transaction:
1

Validate Parameters

Ensures withdrawalPercentage is provided and is a valid number between 0 and 15 (maximum 15% to prevent excessive liquidity removal)
2

Validate Server Configuration

Checks that the server is properly configured to process withdrawal requests
3

Verify Authorization

Validates that the manager wallet is authorized to perform withdrawals
4

Fetch Pool State

Retrieves the current state of the Meteora DAMM v2 pool
5

Get User Positions

Fetches all LP positions owned by the protocol wallet (uses first position)
6

Calculate Withdrawal Amount

Calculates liquidityDelta based on the withdrawal percentage and available unlocked liquidity
7

Calculate Token Amounts

Calculates the exact token amounts that will be withdrawn based on current pool state
8

Build Transaction

Creates a transaction that:
  • Removes liquidity from the pool position
  • Transfers all withdrawn tokens to the manager wallet
  • Creates any needed token accounts
9

Handle Native SOL

If Token B is native SOL, uses SystemProgram.transfer instead of SPL token transfer
10

Generate Request ID

Creates a unique request ID for tracking this withdrawal request
11

Return Unsigned Transaction

Returns the Base58 encoded transaction for manager wallet signing

Withdrawal Percentage Calculation

The withdrawal amount is calculated as:
liquidityDelta = unlockedLiquidity * (withdrawalPercentage * 1000) / 100000
This calculation ensures precision while working with integer arithmetic.
First position only: This endpoint withdraws from the first position in the pool. If multiple positions exist, you need to call this endpoint multiple times to withdraw from other positions.

Native SOL Handling

Special handling for wrapped SOL (wSOL):When Token B is the native SOL mint (So11111111111111111111111111111111111111112):
  1. Meteora automatically unwraps wSOL to native SOL during withdrawal
  2. No token account is created for Token B for the LP owner
  3. Transfers use SystemProgram.transfer instead of SPL token transfer
  4. Withdrawn SOL is received directly as native SOL in the manager wallet

Request ID

The requestId is essential for the confirmation step:
  • Format: Random 16-byte hex string
  • Expiration: Automatically cleaned up after 15 minutes
  • Required: Must be provided to /damm/withdraw/confirm

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

Manager authorization required:
  • Only the configured manager wallet can sign and confirm withdrawals
  • Withdrawn tokens always go to the manager wallet
  • LP owner’s signature is added automatically by the API
  • This prevents unauthorized liquidity withdrawals

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/withdraw/confirm

Request Expiration

Withdrawal requests expire after a period of time:
  • Validity: You must call /damm/withdraw/confirm within 10 minutes
  • After expiration: You’ll need to create a new withdrawal request