diff --git a/src/adaptors/beets-dex/index.js b/src/adaptors/beets-dex/index.js deleted file mode 100644 index ff3907031e..0000000000 --- a/src/adaptors/beets-dex/index.js +++ /dev/null @@ -1,76 +0,0 @@ -const utils = require('../utils'); - -const buildQuery = (chain) => { - return { - operationName: 'GetPools', - variables: { - first: 100, - skip: 0, - orderBy: 'totalLiquidity', - orderDirection: 'desc', - where: { - categoryIn: ['INCENTIVIZED'], - poolTypeIn: ['WEIGHTED', 'STABLE', 'PHANTOM_STABLE', 'META_STABLE'], - chainIn: [chain], - }, - textSearch: '', - }, - query: - 'query GetPools($first: Int, $skip: Int, $orderBy: GqlPoolOrderBy, $orderDirection: GqlPoolOrderDirection, $where: GqlPoolFilter, $textSearch: String) {\n poolGetPools(\n first: $first\n skip: $skip\n orderBy: $orderBy\n orderDirection: $orderDirection\n where: $where\n textSearch: $textSearch\n ) {\n ...GqlPoolMinimal\n __typename\n }\n count: poolGetPoolsCount(\n first: $first\n skip: $skip\n orderBy: $orderBy\n orderDirection: $orderDirection\n where: $where\n textSearch: $textSearch\n )\n}\n\nfragment GqlPoolMinimal on GqlPoolMinimal {\n id\n address\n name\n symbol\n createTime\n dynamicData {\n totalLiquidity\n totalShares\n fees24h\n swapFee\n volume24h\n apr {\n hasRewardApr\n thirdPartyApr {\n ... on GqlPoolAprTotal {\n total\n __typename\n }\n ... on GqlPoolAprRange {\n min\n max\n __typename\n }\n __typename\n }\n nativeRewardApr {\n ... on GqlPoolAprTotal {\n total\n __typename\n }\n ... on GqlPoolAprRange {\n min\n max\n __typename\n }\n __typename\n }\n swapApr\n apr {\n ... on GqlPoolAprTotal {\n total\n __typename\n }\n ... on GqlPoolAprRange {\n min\n max\n __typename\n }\n __typename\n }\n items {\n id\n title\n apr {\n ... on GqlPoolAprTotal {\n total\n __typename\n }\n ... on GqlPoolAprRange {\n min\n max\n __typename\n }\n __typename\n }\n subItems {\n id\n title\n apr {\n ... on GqlPoolAprTotal {\n total\n __typename\n }\n ... on GqlPoolAprRange {\n min\n max\n __typename\n }\n __typename\n }\n __typename\n }\n __typename\n }\n __typename\n }\n __typename\n }\n allTokens {\n id\n address\n isNested\n isPhantomBpt\n weight\n symbol\n __typename\n }\n displayTokens {\n id\n address\n name\n weight\n symbol\n nestedTokens {\n id\n address\n name\n weight\n symbol\n __typename\n }\n __typename\n }\n staking {\n id\n type\n address\n farm {\n id\n beetsPerBlock\n rewarders {\n id\n address\n tokenAddress\n rewardPerSecond\n __typename\n }\n __typename\n }\n __typename\n }\n __typename\n}', - }; -}; - -const apy = async () => { - const chains = ['FANTOM', 'OPTIMISM', 'SONIC']; - const pools = await Promise.all( - chains.map(async (chain) => { - const data = ( - await utils.getData( - 'https://backend-v3.beets-ftm-node.com/', - buildQuery(chain) - ) - )?.data.poolGetPools.filter( - (el) => el.dynamicData.totalLiquidity !== '0' - ); - - return data.map((p) => { - const apyBase = p.dynamicData.apr.swapApr * 100; - const apyReward = - (Number(p.dynamicData.apr.thirdPartyApr.total) + - Number(p.dynamicData.apr.nativeRewardApr.total)) * - 100; - - const symbol = p.allTokens.map((t) => t.symbol).join('-'); - - return { - pool: - chain === 'FANTOM' ? p.id : `${p.address}-${chain.toLowerCase()}`, - chain: utils.formatChain(chain.toLowerCase()), - project: 'beets-dex', - symbol: - p.address === '0x43da214fab3315aa6c02e0b8f2bfb7ef2e3c60a5' - ? 'USDC-DAI' - : p.address === '0x23ca0306b21ea71552b148cf3c4db4fc85ae1929' - ? 'DAI-USDT-USDC' - : p.address === '0x098f32d98d0d64dba199fc1923d3bf4192e78719' - ? 'WBTC-WSTEH-USDC' - : symbol, - tvlUsd: parseFloat(p.dynamicData.totalLiquidity), - apyBase, - apyReward, - url: `https://op.beets.fi/pool/${p.id}`, - underlyingTokens: p.allTokens.map((t) => t.address), - rewardTokens: - apyReward > 0 - ? ['0xf24bcf4d1e507740041c9cfd2dddb29585adce1e'] - : null, - }; - }); - }) - ); - return pools.flat(); -}; - -module.exports = { - apy, -}; diff --git a/src/adaptors/beets-dex/index.ts b/src/adaptors/beets-dex/index.ts new file mode 100644 index 0000000000..2e1c1d48aa --- /dev/null +++ b/src/adaptors/beets-dex/index.ts @@ -0,0 +1,13 @@ +import { getPools } from './utils'; + +const poolsFunction = async () => { + const [sonicPoolsV2] = await Promise.all([getPools('SONIC', 'sonic', 2)]); + + return [...sonicPoolsV2]; +}; + +module.exports = { + timetravel: false, + apy: poolsFunction, + url: 'https://beets.fi/pools', +}; diff --git a/src/adaptors/beets-dex/utils.ts b/src/adaptors/beets-dex/utils.ts new file mode 100644 index 0000000000..fcf1b7c2f7 --- /dev/null +++ b/src/adaptors/beets-dex/utils.ts @@ -0,0 +1,90 @@ +const { gql, request } = require('graphql-request'); +const utils = require('../utils'); + +const query = gql` + query GetPools($chain: GqlChain!, $version: Int!) { + poolGetPools( + first: 1000 + where: { chainIn: [$chain], protocolVersionIn: [$version], minTvl: 10000 } + ) { + id + chain + symbol + address + poolTokens { + address + symbol + } + dynamicData { + totalLiquidity + aprItems { + type + apr + rewardTokenAddress + } + } + } + } +`; + +export const getPools = async (backendChain, chainString, version) => { + try { + const { poolGetPools } = await request( + 'https://backend-v3.beets-ftm-node.com/graphql', + query, + { chain: backendChain, version: version } + ); + + return poolGetPools.map((pool) => { + const aprItems = pool.dynamicData.aprItems || []; + + const baseApr = aprItems + .filter( + (item) => item.type === 'SWAP_FEE_24H' || item.type === 'IB_YIELD' + ) + .reduce((sum, item) => sum + Number(item.apr), 0); + + const stakingApr = aprItems + .filter( + (item) => + item.type === 'STAKING' || + item.type === 'MABEETS_EMISSIONS' || + item.type === 'STAKING_BOOST' + ) + .reduce((sum, item) => sum + Number(item.apr), 0); + + const rewardTokens = aprItems + .filter( + (item) => + (item.type === 'STAKING' || + item.type === 'MABEETS_EMISSIONS' || + item.type === 'STAKING_BOOST') && + item.rewardTokenAddress + ) + .map((item) => item.rewardTokenAddress); + + const underlyingTokens = pool.poolTokens + .map((token) => token.address) + .filter(Boolean); + + return { + pool: pool.address, + chain: utils.formatChain(chainString), + project: version === 3 ? 'beets-dex-v3' : 'beets-dex', + symbol: utils.formatSymbol(pool.symbol), + tvlUsd: Number(pool.dynamicData.totalLiquidity), + apyBase: baseApr * 100, + apyReward: stakingApr * 100, + rewardTokens: rewardTokens, + underlyingTokens: underlyingTokens, + url: `https://beets.fi/pools/${chainString}/v${version}/${pool.id}`, + }; + }); + } catch (error) { + console.error( + `Error fetching Beets V${version} pools for ${chainString}:`, + error + ); + return []; + } +};