diff --git a/src/adaptors/lagoon/index.js b/src/adaptors/lagoon/index.js new file mode 100644 index 0000000000..5ff8713349 --- /dev/null +++ b/src/adaptors/lagoon/index.js @@ -0,0 +1,96 @@ +import { request, gql } from 'graphql-request'; + +const GRAPH_URL = 'https://api.lagoon.finance/query'; +const CHAINS = { + ethereum: 1, + base: 8453, + tac: 239, + arbitrum: 42161, + linea: 59144, + plasma: 9745, + avalanche: 43114, +}; + +const gqlQueries = { + vaultsData: gql` + query GetVaultsData($chainId: Int!, $skip: Int!) { + vaults( + first: 100 + skip: $skip + where: { chainId_in: [$chainId], isVisible_eq: true } + ) { + pageInfo { + hasNextPage + } + items { + id + address + chain { + id + } + symbol + asset { + address + decimals + priceUsd + symbol + } + state { + totalAssetsUsd + weeklyApr { + linearNetAprWithoutExtraYields + incentives { + apr + } + } + } + } + } + } + `, +}; + +const apy = async () => { + let pools = []; + + for (const [chain, chainId] of Object.entries(CHAINS)) { + // Fetch vaults data with pagination + let allVaults = []; + let skip = 0; + while (true) { + const { vaults } = await request(GRAPH_URL, gqlQueries.vaultsData, { + chainId, + skip, + }); + + allVaults = allVaults.concat(vaults.items); + if (!vaults.pageInfo.hasNextPage) break; + skip += 100; + } + const _pools = allVaults.map((vault) => { + const apyReward = + vault.state.weeklyApr.incentives.reduce( + (acc, curr) => acc + curr.apr, + 0 + ) || 0; + return { + pool: `lagoon-${vault.address}-${chain}`, + chain, + project: 'lagoon', + symbol: vault.symbol, + apyBase: vault.state.weeklyApr.linearNetAprWithoutExtraYields, + tvlUsd: vault.state.totalAssetsUsd || 0, + underlyingTokens: [vault.asset.address], + url: `https://app.lagoon.finance/vault/${vault.chain.id}/${vault.address}`, + apyReward, + }; + }); + pools = pools.concat(_pools); + } + + return pools; +}; + +module.exports = { + apy, +};