Positions in liquidity pool refers to an users indirect ownership through Liquidity Pool Tokens. These tokens reflect your share of the pool, and you get rewarded based on your stake (LP tokens) when you withdraw.
You can get a user positions and their LB Pair details for Meteora DLMM using graphQL APIs. The process involves two precise steps.
SHYFT's GraphQL APIs allow you to add filters to your queries on specific accounts for Meteora DLMM. Firstly we fetch all the position details for a particular wallet address by applying the _eq filter on the owner field of meteora_dlmm_Position account.
The response received in the previous step contains the lbPair field. We use this value to query the meteora_dlmm_LbPair account, to get all the Pool related details.
You can directly copy paste this code on replit and see it in action.
asyncfunctiongetAllLbPairPositionForOwner(ownerAddress) {constSHYFT_API_KEY="YOUR_SHYFT_API_KEY";//get all Position and LB Pair address for a particular owner (wallet address)constoperationsDoc=` query MyQuery { meteora_dlmm_PositionV2( where: {owner: {_eq: ${JSON.stringify(ownerAddress)}}} ) { upperBinId lowerBinId totalClaimedFeeYAmount totalClaimedFeeXAmount lastUpdatedAt lbPair owner } meteora_dlmm_Position( where: {owner: {_eq: ${JSON.stringify(ownerAddress)}}} ) { lastUpdatedAt lbPair lowerBinId upperBinId totalClaimedFeeYAmount totalClaimedFeeXAmount owner } }`; //you can cherrypick the fields as per your requirementconstresult=awaitfetch( `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 } =awaitresult.json();if (data.meteora_dlmm_Position.length>0) {for (let index =0; index <data.meteora_dlmm_Position.length; index++) {constposition=data.meteora_dlmm_Position[index];//get all Lb pair details for the positionconstLbPairDetails=awaitfetch( `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:` query MyQuery { meteora_dlmm_LbPair(where: {pubkey: {_eq: ${JSON.stringify(position.lbPair)}}} ) { pubkey oracle pairType reserveX reserveY status tokenXMint tokenYMint } }`,//querying the LB pair details variables: {}, operationName:"MyQuery", }), } );constLBPairResponse=awaitLbPairDetails.json();console.log({ owner:position.owner, lbPair:position.lbPair, lowerBindId:position.lowerBinId, upperBinId:position.upperBinId, lbPairDetails:LBPairResponse.data.meteora_dlmm_LbPair[0], });//adding a delay of 2 seconds to avoid rate limiting, only for free API Keys.awaitnewPromise((resolve) =>setTimeout(resolve,2000)); } }if (data.meteora_dlmm_PositionV2.length>0) {for (let index =0; index <data.meteora_dlmm_PositionV2.length; index++) {constposition=data.meteora_dlmm_PositionV2[index];//get all Lb pair details for the positionV2constLbPairDetails=awaitfetch( `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:` query MyQuery { meteora_dlmm_LbPair( where: {pubkey: {_eq: ${JSON.stringify(position.lbPair)}}} ) { pubkey oracle pairType reserveX reserveY status tokenXMint tokenYMint } } `,//querying the LB pair details variables: {}, operationName:"MyQuery", }), } );constLBPairResponse=awaitLbPairDetails.json();console.log({ owner:position.owner, lbPair:position.lbPair, lowerBindId:position.lowerBinId, upperBinId:position.upperBinId, lbPairDetails:LBPairResponse.data.meteora_dlmm_LbPair[0], });//adding a delay of 2 seconds to avoid rate limiting, only for free API Keys.//await new Promise((resolve) => setTimeout(resolve, 2000)); } }}getAllLbPairPositionForOwner("2rJeSN4HJTvkG5VqwHxYeLHo6up9WBScPKgJ2kQbiSr4")//owner address for which we are fetching the positions