Skip to main content

Overview

Confirms and submits a signed liquidity withdrawal transaction to the Solana blockchain. This endpoint validates the transaction structure comprehensively and broadcasts it to the network. The transaction removes liquidity from a Meteora DAMM v2 pool and transfers all withdrawn tokens to the manager wallet.
Concurrent request handling: Only one withdrawal operation can be processed at a time for each pool. Additional requests will wait in queue until the current operation completes.
curl -X POST https://api.zcombinator.io/damm/withdraw/confirm \
  -H "Content-Type: application/json" \
  -d '{
    "signedTransaction": "4MzR7dxJNJRVP1Q6k7Y3j8X...",
    "requestId": "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6"
  }'

Request Parameters

signedTransaction
string
required
Base58 encoded signed transaction from the manager wallet (must match the transaction from /damm/withdraw/build)
requestId
string
required
Unique identifier returned from the /damm/withdraw/build endpoint

Response

success
boolean
Indicates if the transaction was submitted successfully
signature
string
Transaction signature (transaction ID) on Solana
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
withdrawalPercentage
number
Percentage of liquidity that was withdrawn
estimatedAmounts
object
Object containing the withdrawn amounts:
  • tokenA (string): Token A amount withdrawn
  • tokenB (string): Token B amount withdrawn
  • liquidityDelta (string): Liquidity amount removed
message
string
Success message

Success Response

{
  "success": true,
  "signature": "5J8Z9xKqH4nL2pR7vT3mB1cW6dF8yG4aS9jK2xM5nP8hQ3rV7wE1",
  "poolAddress": "CPMMoo8L3F4NbTegBCKVNunggL7H1ZpdTHKxQB5qKP1C",
  "tokenAMint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
  "tokenBMint": "So11111111111111111111111111111111111111112",
  "withdrawalPercentage": 50,
  "estimatedAmounts": {
    "tokenA": "5000000",
    "tokenB": "2500000000",
    "liquidityDelta": "1000000"
  },
  "message": "Withdrawal transaction submitted successfully"
}

Error Responses

{
  "error": "Missing required fields: signedTransaction and requestId"
}
{
  "error": "Withdrawal request not found or expired. Please call /damm/withdraw/build first."
}
The requestId is invalid, expired, or already used.
{
  "error": "Withdrawal request expired. Please create a new request."
}
More than 10 minutes have passed since the withdrawal request was created.
{
  "error": "Failed to deserialize transaction: Invalid transaction format"
}
The provided signedTransaction cannot be decoded.
{
  "error": "Invalid transaction: missing blockhash"
}
{
  "error": "Invalid transaction: blockhash is expired. Please create a new transaction."
}
The transaction’s blockhash is older than 150 slots (~60 seconds).
{
  "error": "Transaction fee payer must be manager wallet"
}
The transaction’s fee payer doesn’t match the configured manager wallet.
{
  "error": "Transaction verification failed: Manager wallet has not signed"
}
The manager wallet’s signature is missing from the transaction.
{
  "error": "Transaction verification failed: Invalid manager wallet signature"
}
The manager wallet’s signature is invalid or doesn’t match.
{
  "error": "Invalid transaction: unauthorized program instruction detected",
  "details": "Instruction 3 uses unauthorized program: 11111111111111111111111111111112"
}
The transaction contains instructions from programs that aren’t allowed.
{
  "error": "Invalid transaction: unauthorized token instruction detected",
  "details": "Instruction 2 has invalid opcode: 7"
}
Token program instructions must be Transfer (3), InitializeAccount (9), TransferChecked (12), or SyncNative (17) only. SyncNative is required for wrapping SOL to WSOL.
{
  "error": "Invalid transaction: transfer authority must be LP owner",
  "details": "Instruction 5 authority mismatch"
}
Token transfers must be signed by the LP owner.
{
  "error": "Invalid transaction: transfer destination not authorized",
  "details": "Instruction 6 invalid destination"
}
Transfers can only go to the manager wallet’s token accounts or LP owner’s token accounts.
{
  "error": "Invalid transaction: Token A transfer amount exceeds expected",
  "details": "Instruction 7 amount too large"
}
Transfer amounts cannot exceed the calculated withdrawal amounts.
{
  "error": "Invalid transaction: system transfer destination must be manager wallet",
  "details": "Instruction 8 to mismatch"
}
Native SOL transfers must go to the manager wallet.
{
  "error": "Server configuration incomplete"
}
Required environment variables are not configured.
{
  "error": "Failed to confirm withdrawal"
}

Process Flow

This endpoint performs extensive validation before submitting the transaction:
1

Validate Parameters

Ensures signedTransaction and requestId are provided
2

Retrieve Request Data

Looks up the withdrawal request data using the requestId
3

Queue Request

Ensures only one operation processes at a time for this pool (additional requests wait in queue)
4

Check Request Expiry

Verifies the request is not older than 10 minutes
5

Deserialize Transaction

Decodes the Base58 encoded transaction
6

Validate Blockhash

Checks that the transaction’s blockhash is recent and valid (within last 150 slots)
7

Verify Manager Wallet

Ensures the fee payer is the manager wallet and has signed the transaction
8

Verify Manager Signature

Cryptographically validates the manager wallet’s signature using nacl
9

Validate Transaction Structure

Comprehensive security validation (see Security Validations section below)
10

Complete Transaction

Adds the required signatures to finalize the transaction
11

Submit Transaction

Broadcasts the fully-signed transaction to Solana with preflight checks
12

Wait for Confirmation

Attempts to wait for transaction confirmation (continues if timeout)
13

Cleanup

Removes the request data from memory and releases the pool lock

Security Validations

This endpoint implements comprehensive transaction validation to prevent attacks:
Only one liquidity operation can be processed per pool at a time. Concurrent requests are automatically queued and processed sequentially.
Prevents replay attacks by verifying the blockhash is recent (within last 150 slots / ~60 seconds).
Only the configured manager wallet can submit withdrawal transactions. Both fee payer and signature are verified.
Only permits instructions from:
  • Token Program (TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA)
  • Associated Token Program (ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL)
  • Compute Budget Program
  • Lighthouse Program (for optimization)
  • Meteora CP-AMM Program (CPMMoo8L3F4NbTegBCKVNunggL7H1ZpdTHKxQB5qKP1C)
  • Meteora DAMM v2 Program (cpamdpZCGKy5JxQXB4dcpGPiikHawvSWAd6mEn1sGG)
  • System Program (for native SOL transfers)
  • Only Transfer (opcode 3), InitializeAccount (opcode 9), TransferChecked (opcode 12), and SyncNative (opcode 17) are allowed
  • SyncNative is required for wrapping SOL to WSOL in native SOL withdrawals
  • All transfers must be signed by the LP owner
  • Transfer amounts cannot exceed calculated withdrawal amounts
Transfers can ONLY go to:
  • Manager wallet token accounts (withdrawal recipients)
  • LP owner token accounts (intermediate recipients before transfer) Any other destination is rejected.
For native SOL transfers (when Token B is wSOL):
  • Only SystemProgram.transfer (instruction type 2) allowed
  • Must be from LP owner to manager wallet
  • Amount cannot exceed Token B withdrawal amount
Only CreateAssociatedTokenAccountIdempotent (opcode 1) is allowed for ATA program.
All transfer amounts are compared against stored expected withdrawal amounts to prevent over-withdrawal.
Manager authorization required: Unlike fee claims, withdrawals require manager wallet authorization. Only the configured manager wallet can execute withdrawals, preventing unauthorized access to pool liquidity.

Rate Limiting

This endpoint is subject to rate limiting:
  • 10 requests per 5-minute window per IP
  • Returns HTTP 429 when limit exceeded

Transaction Confirmation

The API attempts to wait for transaction confirmation but continues even if confirmation times out:
  • Confirmation Commitment: confirmed
  • Timeout Handling: Logs warning but returns success
  • User Responsibility: Check transaction status on Solana explorer
You can view the transaction on Solscan: https://solscan.io/tx/{signature}

Concurrent Request Handling

Request queueing:When a liquidity operation is being processed for a pool, subsequent requests for the same pool will wait in queue. This prevents:
  • Concurrent withdrawal conflicts
  • Transaction race conditions
  • Double-processing
Requests are automatically processed in order when the current operation completes.

One-Time Use

After successful submission:
  • The requestId cannot be reused
  • You must create a new request for additional operations

Best Practices

1

Check Blockhash Age

Submit the signed transaction quickly after receiving it from /damm/withdraw/build. Blockhashes expire after ~60 seconds.
2

Handle Expiry

If more than 10 minutes pass, create a new withdrawal request instead of retrying with the old requestId.
3

Monitor Transaction

Use the returned signature to check transaction status on Solana explorers or via RPC.
4

Handle Queueing

If you receive a timeout or slow response, another request may be processing. Wait and retry.
5

Manage Withdrawals Carefully

Withdrawals remove liquidity from the pool. Ensure you’re withdrawing the correct percentage.