From 48a8dfb5be9f1a36a7b6fe88f973224a5d6fa0cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Pr=C3=A9vost?= <998369+prevostc@users.noreply.github.com> Date: Wed, 4 Dec 2024 18:48:52 +0100 Subject: [PATCH] Add camelot config url --- README.md | 3 + src/routes/v1/index.ts | 2 + src/routes/v1/partner/camelot.ts | 78 +++++++++++++++++++ src/routes/v1/partner/index.ts | 10 +++ .../vault/getBeefyVaultConfig.ts | 8 ++ 5 files changed, 101 insertions(+) create mode 100644 src/routes/v1/partner/camelot.ts create mode 100644 src/routes/v1/partner/index.ts diff --git a/README.md b/README.md index 698b6ae..25db6da 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,9 @@ https://balance-api.beefy.finance/api/v1/config/arbitrum/bundles http://localhost:4000/api/v1/config/arbitrum/bundles +https://balance-api.beefy.finance/api/v1/partner/camelot/config/arbitrum/bundles +http://localhost:4000/api/v1/partner/camelot/config/arbitrum/bundles + https://balance-api.beefy.finance/api/v1/vault/base/baseswap-cow-weth-cbbtc/20449610/bundle-holder-share http://localhost:4000/api/v1/vault/base/baseswap-cow-weth-cbbtc/20449610/bundle-holder-share https://balance-api.beefy.finance/api/v1/vault/arbitrum/camelot-order-weth/279181618/bundle-holder-share diff --git a/src/routes/v1/index.ts b/src/routes/v1/index.ts index 336c686..bf4944c 100644 --- a/src/routes/v1/index.ts +++ b/src/routes/v1/index.ts @@ -2,6 +2,7 @@ import type { FastifyInstance, FastifyPluginOptions } from 'fastify'; import config from './config'; import contract from './contract'; import holders from './holders'; +import partner from './partner'; import status from './status'; import vault from './vault'; @@ -15,5 +16,6 @@ export default async function ( instance.register(vault, { prefix: '/vault' }); instance.register(config, { prefix: '/config' }); instance.register(contract, { prefix: '/contract' }); + instance.register(partner, { prefix: '/partner' }); done(); } diff --git a/src/routes/v1/partner/camelot.ts b/src/routes/v1/partner/camelot.ts new file mode 100644 index 0000000..f8fbe38 --- /dev/null +++ b/src/routes/v1/partner/camelot.ts @@ -0,0 +1,78 @@ +import { type Static, Type } from '@sinclair/typebox'; +import type { FastifyInstance, FastifyPluginOptions, FastifySchema } from 'fastify'; +import { chainIdSchema } from '../../../config/chains'; +import { getAsyncCache } from '../../../utils/async-lock'; +import { getBeefyVaultConfig } from '../../../vault-breakdown/vault/getBeefyVaultConfig'; + +export default async function ( + instance: FastifyInstance, + _opts: FastifyPluginOptions, + done: (err?: Error) => void +) { + const asyncCache = getAsyncCache(); + + // all configs with point structure id of some chain + { + const urlParamsSchema = Type.Object({ + chain: chainIdSchema, + }); + type UrlParams = Static; + const responseSchema = Type.Object({ + vaults: Type.Array(Type.Any()), + }); + + const queryParamsSchema = Type.Object({ + include_eol: Type.Optional(Type.Boolean({ default: false })), + }); + type QueryParams = Static; + + const schema: FastifySchema = { + tags: ['camelot'], + params: urlParamsSchema, + querystring: queryParamsSchema, + response: { + 200: responseSchema, + }, + }; + + instance.get<{ Params: UrlParams; Querystring: QueryParams }>( + '/config/:chain/bundles', + { schema }, + async (request, reply) => { + const { chain } = request.params; + const { include_eol } = request.query; + + const result = await asyncCache.wrap(`config:${chain}`, 5 * 60 * 1000, async () => { + const configs = await getBeefyVaultConfig( + chain, + vault => + (include_eol ? true : vault.status === 'active') && + vault.underlyingPlatform === 'camelot' + ); + + // remove clm vault from top levels if a vault exists on top + const clmVaultAddresses = new Set( + configs + .map(vault => + vault.protocol_type === 'beefy_clm_vault' + ? vault.beefy_clm_manager.vault_address + : null + ) + .map(address => address?.toLowerCase()) + .filter(Boolean) + ); + + console.log(clmVaultAddresses); + + const filteredConfigs = configs.filter( + vault => !clmVaultAddresses.has(vault.vault_address.toLowerCase()) + ); + return filteredConfigs; + }); + reply.send(result); + } + ); + } + + done(); +} diff --git a/src/routes/v1/partner/index.ts b/src/routes/v1/partner/index.ts new file mode 100644 index 0000000..008049f --- /dev/null +++ b/src/routes/v1/partner/index.ts @@ -0,0 +1,10 @@ +import type { FastifyInstance, FastifyPluginOptions } from 'fastify'; +import camelot from './camelot'; +export default async function ( + instance: FastifyInstance, + _opts: FastifyPluginOptions, + done: (err?: Error) => void +) { + instance.register(camelot, { prefix: '/camelot' }); + done(); +} diff --git a/src/vault-breakdown/vault/getBeefyVaultConfig.ts b/src/vault-breakdown/vault/getBeefyVaultConfig.ts index 91571c2..a71f788 100644 --- a/src/vault-breakdown/vault/getBeefyVaultConfig.ts +++ b/src/vault-breakdown/vault/getBeefyVaultConfig.ts @@ -24,6 +24,7 @@ export type BeefyVault = { pointStructureIds: string[]; platformId: ApiPlatformId; status: 'active' | 'eol'; + underlyingPlatform: string | null; } & ( | { protocol_type: 'beefy_clm_vault'; @@ -109,6 +110,7 @@ export type ApiClmManager = { earnContractAddress: string; // reward pool address earnedTokenAddress: string; // clm manager address pointStructureIds?: string[]; + tokenProviderId?: string; }; export type ApiClmRewardPool = { @@ -246,6 +248,7 @@ const getAllConfigs = async (chain: ChainId): Promise => { const reward_pools = clmRewardPoolDataPerClmAddress[vault_address] ?? []; const boosts = boostPerUnderlyingAddress[vault_address] ?? []; + const underlyingPlatform = vault.tokenProviderId ?? null; return { id: vault.id, @@ -257,6 +260,7 @@ const getAllConfigs = async (chain: ChainId): Promise => { status: vault.status, strategy_address: vault.strategy.toLocaleLowerCase() as Hex, undelying_lp_address, + underlyingPlatform, reward_pools: reward_pools.map(pool => ({ id: pool.id, clm_address: pool.tokenAddress.toLocaleLowerCase() as Hex, @@ -305,12 +309,16 @@ const getAllConfigs = async (chain: ChainId): Promise => { : { protocol_type, platformId: vault.platformId }; const reward_pools = vaultRewardPoolDataPerVaultAddress[vault_address] ?? []; const boosts = boostPerUnderlyingAddress[vault_address] ?? []; + + const underlyingPlatform = vault.platformId ?? null; + return { id: vault.id, vault_address, chain: vault.chain, vault_token_symbol: vault.earnedToken, ...additionalConfig, + underlyingPlatform, strategy_address: vault.strategy.toLocaleLowerCase() as Hex, undelying_lp_address: underlying_lp_address, status: vault.status,