# Get All Fees Claimed by a User

Along with percentage of ownership, <mark style="color:yellow;">positions</mark> also <mark style="color:yellow;">determine</mark> the rewards and <mark style="color:yellow;">fees earned</mark> by the liquidity providers for their participation. We can also find out the fees claimed by the liquidity provider. This again involves two simple steps:

1. We fetch all the position address for the liquidity provider (or the user)
2. Once we have the position address, we can fetch all transactions for each position address, and look for transactions of the 'CLAIMFEE' type. The actions array in each of these parsed (by SHYFT) 'CLAIMFEE' transactions will contain the details of the fees claimed.

You can directly copy paste this code on <mark style="color:yellow;">replit</mark> and see it in action.

{% tabs %}
{% tab title="Code Snippet" %}
{% code overflow="wrap" %}

```typescript
import { ShyftSdk,Network } from "@shyft-to/js";

const SHYFT_API_KEY = "YOUR_SHYFT_API_KEY";

const shyft = new ShyftSdk({ apiKey: SHYFT_API_KEY, network: Network.Mainnet });

async function getClaimfeeDetails(positionAddress: string) {

    let genesisTxnReached = false;
    let claimFeeTxns:any[] = [];
    let lastSignature = undefined;

    while (!genesisTxnReached) {
        const transactions:any = await shyft.transaction.history({
            account: positionAddress,
            network: Network.Mainnet,
            txNum: 10,
            beforeTxSignature: lastSignature
        });
        transactions.map((txn:any) => {
            if(txn.type === "CLAIMFEE")
                claimFeeTxns.push(txn);
        });

        if(transactions.length < 10){
            genesisTxnReached = true;
            break;
        }
        lastSignature = transactions[transactions.length - 1].signatures[0];
    }
    const amountClaimedDetails:any = [];
    claimFeeTxns.map((claimFeeTxn) => {
        const tokenX = claimFeeTxn.actions[0].info.tokenXMint;
        const tokenY = claimFeeTxn.actions[0].info.tokenYMint;

        let eachAddedTxn:any = {
            "txn_id":claimFeeTxn.signatures[0],
            "onchain_timestamp": claimFeeTxn.timestamp,
        };
        claimFeeTxn.actions.map((action:any) => {
            
            if(action.type === "TOKEN_TRANSFER"){
                if(action.info.token_address === tokenX){
                    eachAddedTxn = {
                        ...eachAddedTxn,
                        "tokenX_amount":action.info.amount_raw,
                        "tokenX_address":action.info.token_address
                    }
                }
                if(action.info.token_address === tokenY){
                    eachAddedTxn = {
                        ...eachAddedTxn,
                        "tokenY_amount":action.info.amount_raw,
                        "tokenY_address":action.info.token_address
                    }
                }
                if(eachAddedTxn.tokenX_amount && eachAddedTxn.tokenY_amount)
                    amountClaimedDetails.push(eachAddedTxn);
            }
        })
    })
    console.log(amountClaimedDetails);

}
// getClaimfeeDetails("CFUjqVgyzNfW88FxR3npGBNoPsyceec8CU3778rJ4F8b")


async function getPositionLiquidityDetails(ownerAddress:string) {
	//querying both position and positionV2 for the owner, or user wallet
    const operationsDoc = `
        query MyQuery {
          meteora_dlmm_PositionV2(
            where: {owner: {_eq: ${JSON.stringify(ownerAddress)}}}
          ) {
                lbPair
                owner
                pubkey
            }
          meteora_dlmm_Position(
            where: {owner: {_eq: ${JSON.stringify(ownerAddress)}}}
          ) {
                lbPair
                owner
                pubkey
            }
        }
    `; //you can cherrypick the fields as per your requirement
      const result = await fetch(
        `https://programs.shyft.to/v0/graphql/accounts?api_key=${SHYFT_API_KEY}&network=mainnet-beta`, //SHYFT's GQL endpoint
        {
          method: "POST",
          body: JSON.stringify({
            query: operationsDoc,
            variables: {},
            operationName: "MyQuery",
          }),
        }
      );
    
      const { errors, data } = await result.json();
    
      //adding a delay of 2 seconds to avoid rate limiting, only for free API Keys.
      await new Promise((resolve) => setTimeout(resolve, 2000));
    
      if (data.meteora_dlmm_Position.length > 0) {
        for (let index = 0; index < data.meteora_dlmm_Position.length; index++) {
          const position = data.meteora_dlmm_Position[index];

          //get fee claims for each position
          await getClaimfeeDetails(position.pubkey)
        }
      }
    
      //adding a delay of 2 seconds to avoid rate limiting, only for free API Keys.
      await new Promise((resolve) => setTimeout(resolve, 2000));
    
      if (data.meteora_dlmm_PositionV2.length > 0) {
        for (let index = 0; index < data.meteora_dlmm_PositionV2.length; index++) {
          const position = data.meteora_dlmm_PositionV2[index];
        
          //get fee claims for each positionV2
          await getClaimfeeDetails(position.pubkey)
        }
     }
}

getPositionLiquidityDetails("5sJKcYqCWNPJ25PriinfeH7PbFsHxzQhe8kspg2UFexK")

```

{% endcode %}
{% endtab %}

{% tab title="Response" %}

```json
[
  {
    "txn_id": "ckavTmfvkCTjzLRgt6bsPgexgHcRU1WxXub82u8FrYnnaf37PiTtsHEx54CGhtGhocrUDtAz9LLGX3Hy7VyLBPg",
    "onchain_timestamp": "2024-05-10T18:30:51.000Z",
    "tokenX_amount": 3326268,
    "tokenY_address": "So11111111111111111111111111111111111111112",
    "tokenY_amount": 68527528,
    "tokenY_address": "So11111111111111111111111111111111111111112"
  },
  {
    "txn_id": "2j6iT9yUQyq94xsvZJE3zftZUJfb8LvLcxvRFNDPtzKzHrjsLVsuMU17xiNEcWzNe1dnJJaoyZMoCySqecMn7qSR",
    "onchain_timestamp": "2024-05-08T09:30:47.000Z",
    "tokenX_amount": 4023164.0000000005,
    "tokenY_address": "So11111111111111111111111111111111111111112",
    "tokenY_amount": 71484212,
    "tokenY_address": "So11111111111111111111111111111111111111112"
  }
] //sample response, shortened
```

{% endtab %}
{% endtabs %}

The above function `getClaimfeeDetails` can also be used to fetch all claim rewards when only the position address in known.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.shyft.to/solana-indexers/case-studies/meteora/get-all-fees-claimed-by-a-user.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
