> ## 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.

# Confirm Fee Claim Transaction

> POST /fee-claim/confirm - Submit signed fee claim transaction to the blockchain

## Overview

Confirms and submits a signed fee claim transaction to the Solana blockchain. This endpoint validates the transaction structure, adds the LP owner's signature, and broadcasts it to the network. The transaction claims fees from a Meteora DAMM v2 pool and transfers 70% to the configured destination address.

<Warning>
  **Pool locking mechanism**: This endpoint uses a mutex lock system to prevent concurrent fee claims for the same pool, ensuring transaction integrity.
</Warning>

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST https://api.zcombinator.io/fee-claim/confirm \
    -H "Content-Type: application/json" \
    -d '{
      "signedTransaction": "4MzR7dxJNJRVP1Q6k7Y3j8X...",
      "requestId": "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6"
    }'
  ```

  ```javascript fetch theme={null}
  const response = await fetch('https://api.zcombinator.io/fee-claim/confirm', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      signedTransaction: "4MzR7dxJNJRVP1Q6k7Y3j8X...",
      requestId: "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6"
    })
  });

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

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

  data = {
      "signedTransaction": "4MzR7dxJNJRVP1Q6k7Y3j8X...",
      "requestId": "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6"
  }

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

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

## Request Parameters

<ParamField body="signedTransaction" type="string" required>
  Base58 encoded signed transaction from the user (must match the transaction from `/fee-claim/claim`)
</ParamField>

<ParamField body="requestId" type="string" required>
  Unique identifier returned from the `/fee-claim/claim` endpoint
</ParamField>

## Response

<ResponseField name="success" type="boolean">
  Indicates if the transaction was submitted successfully
</ResponseField>

<ResponseField name="signature" type="string">
  Transaction signature (transaction ID) on Solana
</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="destinationAddress" type="string">
  Address that received 70% of the claimed fees
</ResponseField>

<ResponseField name="positionsCount" type="number">
  Number of positions claimed from (always 1)
</ResponseField>

<ResponseField name="estimatedFees" type="object">
  Object containing the claimed fee amounts:

  * `tokenA` (string): Total Token A fees claimed
  * `tokenB` (string): Total Token B fees claimed
</ResponseField>

<ResponseField name="message" type="string">
  Success message
</ResponseField>

### Success Response

```json theme={null}
{
  "success": true,
  "signature": "5J8Z9xKqH4nL2pR7vT3mB1cW6dF8yG4aS9jK2xM5nP8hQ3rV7wE1",
  "poolAddress": "CPMMoo8L3F4NbTegBCKVNunggL7H1ZpdTHKxQB5qKP1C",
  "tokenAMint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
  "tokenBMint": "So11111111111111111111111111111111111111112",
  "destinationAddress": "FeeDestinationWalletAddress123456789",
  "positionsCount": 1,
  "estimatedFees": {
    "tokenA": "1000000",
    "tokenB": "500000000"
  },
  "message": "Fee claim transaction submitted successfully"
}
```

## Error Responses

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

  <Accordion title="400 - Request Not Found">
    ```json theme={null}
    {
      "error": "Fee claim request not found or expired. Please call /fee-claim/claim first."
    }
    ```

    The requestId is invalid, expired, or already used.
  </Accordion>

  <Accordion title="400 - Request Expired">
    ```json theme={null}
    {
      "error": "Fee claim request expired. Please create a new request."
    }
    ```

    More than 10 minutes have passed since the claim request was created.
  </Accordion>

  <Accordion title="400 - Transaction Deserialization Failed">
    ```json theme={null}
    {
      "error": "Failed to deserialize transaction: Invalid transaction format"
    }
    ```

    The provided signedTransaction cannot be decoded.
  </Accordion>

  <Accordion title="400 - Missing Blockhash">
    ```json theme={null}
    {
      "error": "Invalid transaction: missing blockhash"
    }
    ```
  </Accordion>

  <Accordion title="400 - Expired Blockhash">
    ```json theme={null}
    {
      "error": "Invalid transaction: blockhash is expired. Please create a new transaction."
    }
    ```

    The transaction's blockhash is older than 150 slots (\~60 seconds).
  </Accordion>

  <Accordion title="400 - Fee Payer Mismatch">
    ```json theme={null}
    {
      "error": "Transaction fee payer mismatch"
    }
    ```

    The transaction's fee payer doesn't match the expected payer from the claim request.
  </Accordion>

  <Accordion title="400 - LP Owner Not Required">
    ```json theme={null}
    {
      "error": "Transaction verification failed: LP owner signature not required"
    }
    ```

    Security validation failed - LP owner must be a required signer.
  </Accordion>

  <Accordion title="400 - Fee Payer Not Signed">
    ```json theme={null}
    {
      "error": "Transaction verification failed: Fee payer has not signed"
    }
    ```

    The fee payer's signature is missing from the transaction.
  </Accordion>

  <Accordion title="400 - Invalid Fee Payer Signature">
    ```json theme={null}
    {
      "error": "Transaction verification failed: Invalid fee payer signature"
    }
    ```

    The fee payer's signature is invalid or doesn't match.
  </Accordion>

  <Accordion title="400 - Unauthorized Program">
    ```json theme={null}
    {
      "error": "Invalid transaction: unauthorized program instruction detected",
      "details": "Instruction 3 uses unauthorized program: 11111111111111111111111111111112"
    }
    ```

    The transaction contains instructions from programs that aren't allowed.
  </Accordion>

  <Accordion title="400 - Unauthorized Token Instruction">
    ```json theme={null}
    {
      "error": "Invalid transaction: unauthorized token instruction detected",
      "details": "Instruction 2 has invalid opcode: 7. Only Transfer (3) and TransferChecked (12) allowed."
    }
    ```

    Token program instructions must be Transfer or TransferChecked only.
  </Accordion>

  <Accordion title="400 - Invalid Transfer Authority">
    ```json theme={null}
    {
      "error": "Invalid transaction: transfer authority must be LP owner",
      "details": "Instruction 5 authority does not match LP owner"
    }
    ```

    Transfers must be signed by the LP owner.
  </Accordion>

  <Accordion title="400 - Unauthorized Destination">
    ```json theme={null}
    {
      "error": "Invalid transaction: transfer destination not authorized",
      "details": "Instruction 6 destination is not in allowed list"
    }
    ```

    Transfers can only go to the configured destination address or LP owner's token accounts.
  </Accordion>

  <Accordion title="400 - Amount Exceeds Expected">
    ```json theme={null}
    {
      "error": "Invalid transaction: Token A transfer amount exceeds expected fees",
      "details": "Instruction 7 amount 2000000 exceeds Token A fees 1000000"
    }
    ```

    Transfer amounts cannot exceed the calculated claimable fees.
  </Accordion>

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

    Required environment variables are not configured.
  </Accordion>

  <Accordion title="500 - Transaction Submission Failed">
    ```json theme={null}
    {
      "error": "Failed to confirm fee claim"
    }
    ```
  </Accordion>
</AccordionGroup>

## Process Flow

This endpoint performs extensive validation before submitting the transaction:

<Steps>
  <Step title="Validate Parameters">
    Ensures signedTransaction and requestId are provided
  </Step>

  <Step title="Retrieve Request Data">
    Looks up the fee claim request data using the requestId
  </Step>

  <Step title="Acquire Pool Lock">
    Obtains a mutex lock for the pool to prevent concurrent claims
  </Step>

  <Step title="Check Request Expiry">
    Verifies the request is not older than 10 minutes
  </Step>

  <Step title="Deserialize Transaction">
    Decodes the Base58 encoded transaction
  </Step>

  <Step title="Validate Blockhash">
    Checks that the transaction's blockhash is recent and valid (within last 150 slots)
  </Step>

  <Step title="Verify Fee Payer">
    Ensures the fee payer matches the expected payer and has signed
  </Step>

  <Step title="Verify Fee Payer Signature">
    Cryptographically validates the fee payer's signature using nacl
  </Step>

  <Step title="Validate Transaction Structure">
    Comprehensive security validation (see Security Validations section below)
  </Step>

  <Step title="Add LP Owner Signature">
    Protocol signs the transaction with the LP owner keypair
  </Step>

  <Step title="Submit Transaction">
    Broadcasts the fully-signed transaction to Solana with preflight checks
  </Step>

  <Step title="Wait for Confirmation">
    Attempts to wait for transaction confirmation (continues if timeout)
  </Step>

  <Step title="Cleanup">
    Removes the request data from memory and releases the pool lock
  </Step>
</Steps>

## Security Validations

This endpoint implements comprehensive transaction validation to prevent attacks:

<AccordionGroup>
  <Accordion title="1. Lock System">
    Prevents race conditions by ensuring only one fee claim can be processed per pool at a time using mutex locks.
  </Accordion>

  <Accordion title="2. Blockhash Validation">
    Prevents replay attacks by verifying the blockhash is recent (within last 150 slots / \~60 seconds).
  </Accordion>

  <Accordion title="3. Allowed Programs">
    Only permits instructions from:

    * Token Program (TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA)
    * Associated Token Program (ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL)
    * Compute Budget Program
    * Lighthouse Program (for optimization)
    * Meteora CP-AMM Program (CPMMoo8L3F4NbTegBCKVNunggL7H1ZpdTHKxQB5qKP1C)
    * System Program (for native SOL transfers)
  </Accordion>

  <Accordion title="4. Token Instruction Validation">
    * Only Transfer (opcode 3) and TransferChecked (opcode 12) are allowed
    * All transfers must be signed by the LP owner
    * Transfer amounts cannot exceed calculated fees
  </Accordion>

  <Accordion title="5. Destination Validation">
    Transfers can ONLY go to:

    * Configured destination address token accounts (70% recipient)
    * LP owner token accounts (30% remainder)
      Any other destination is rejected.
  </Accordion>

  <Accordion title="6. System Transfer Validation">
    For native SOL transfers (when Token B is wSOL):

    * Only SystemProgram.transfer (instruction type 2) allowed
    * Must be from LP owner to configured destination address
    * Amount cannot exceed Token B fees
  </Accordion>

  <Accordion title="7. ATA Instruction Validation">
    Only CreateAssociatedTokenAccountIdempotent (opcode 1) is allowed for ATA program.
  </Accordion>

  <Accordion title="8. Amount Validation">
    All transfer amounts are compared against stored expected fees to prevent over-claiming.
  </Accordion>
</AccordionGroup>

<Info>
  **No authorization required**: Since fee destinations are hardcoded and validated, anyone can trigger fee claims. The fee payer only covers transaction costs and cannot redirect funds.
</Info>

## 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}`

## Pool Lock System

<Warning>
  **Mutex locks prevent concurrent processing**:

  When a fee claim is being processed for a pool, subsequent requests for the same pool will wait for the lock to be released. This prevents:

  * Double-claiming fees
  * Transaction conflicts
  * Race conditions

  The lock is automatically released when processing completes (success or error).
</Warning>

## Request Cleanup

After successful submission:

* Request data is immediately removed from memory
* Pool lock is released
* requestId cannot be reused

## Logging

The endpoint logs comprehensive information for monitoring:

* Pool address
* Token mints and fee amounts
* Destination address
* Transaction signature
* Solscan link for easy verification

## Best Practices

<Steps>
  <Step title="Check Blockhash Age">
    Submit the signed transaction quickly after receiving it from `/fee-claim/claim`. Blockhashes expire after \~60 seconds.
  </Step>

  <Step title="Handle Expiry">
    If more than 10 minutes pass, create a new claim request instead of retrying with the old requestId.
  </Step>

  <Step title="Monitor Transaction">
    Use the returned signature to check transaction status on Solana explorers or via RPC.
  </Step>

  <Step title="Wait for Lock">
    If you receive a timeout or slow response, the pool may be locked by another concurrent request. Wait and retry.
  </Step>
</Steps>

## Environment Variables

Required server configuration:

* `RPC_URL`: Solana RPC endpoint
* `DAMM_POOL_ADDRESS`: Meteora DAMM v2 pool address
* `PROTOCOL_PRIVATE_KEY`: LP owner's private key (Base58)
* `FEE_DESTINATION_ADDRESS`: Address to receive 70% of claimed fees

## Related Endpoints

* [`/fee-claim/claim`](/api-reference/fee-claim/claim) - Create the unsigned fee claim transaction
