diff --git a/packages/plugins/src/plugins/adrena/alpPriceJob.ts b/packages/plugins/src/plugins/adrena/alpPriceJob.ts new file mode 100644 index 00000000..8898c352 --- /dev/null +++ b/packages/plugins/src/plugins/adrena/alpPriceJob.ts @@ -0,0 +1,44 @@ +import { NetworkId, walletTokensPlatformId } from '@sonarwatch/portfolio-core'; +import { PublicKey } from '@solana/web3.js'; +import { Cache } from '../../Cache'; +import { Job, JobExecutor } from '../../Job'; +import { alpMint, platformId } from './constants'; +import { getClientSolana } from '../../utils/clients'; +import { poolStruct } from './structs'; +import { getSupply } from '../../utils/solana/getSupply'; +import { alpDecimals } from '../abex/constants'; +import { getParsedAccountInfo } from '../../utils/solana/getParsedAccountInfo'; + +const executor: JobExecutor = async (cache: Cache) => { + const client = getClientSolana(); + + const alpSupply = await getSupply(client, new PublicKey(alpMint)); + if (!alpSupply) throw new Error('Cannot get ALP supply'); + + const poolAccount = await getParsedAccountInfo( + client, + poolStruct, + new PublicKey('4bQRutgDJs6vuh6ZcWaPVXiQaBzbHketjbCDjL4oRN34') + ); + if (!poolAccount) throw new Error('Cannot get ALP pool'); + const aumUsd = poolAccount.aumUsdLow.div(10 ** 6); + if (aumUsd.isZero()) throw new Error('Adrena aumUsd is 0'); + + const price = aumUsd.div(alpSupply).toNumber(); + await cache.setTokenPriceSource({ + address: alpMint, + decimals: alpDecimals, + id: 'adrena', + networkId: NetworkId.solana, + platformId: walletTokensPlatformId, + price, + timestamp: Date.now(), + weight: 1, + }); +}; +const job: Job = { + id: `${platformId}-alp-price`, + executor, + label: 'realtime', +}; +export default job; diff --git a/packages/plugins/src/plugins/adrena/index.ts b/packages/plugins/src/plugins/adrena/index.ts index 3e09e4ad..2c35cddf 100644 --- a/packages/plugins/src/plugins/adrena/index.ts +++ b/packages/plugins/src/plugins/adrena/index.ts @@ -3,9 +3,10 @@ import { Fetcher } from '../../Fetcher'; import { Job } from '../../Job'; import { platform } from './constants'; import custodiesJob from './custodiesJob'; +import alpPriceJob from './alpPriceJob'; import positionsFetcher from './positionsFetcher'; import stakingFetcher from './stakingFetcher'; export const platforms: Platform[] = [platform]; -export const jobs: Job[] = [custodiesJob]; +export const jobs: Job[] = [custodiesJob, alpPriceJob]; export const fetchers: Fetcher[] = [positionsFetcher, stakingFetcher]; diff --git a/packages/plugins/src/plugins/adrena/structs.ts b/packages/plugins/src/plugins/adrena/structs.ts index c2719a67..a2310fef 100644 --- a/packages/plugins/src/plugins/adrena/structs.ts +++ b/packages/plugins/src/plugins/adrena/structs.ts @@ -407,6 +407,51 @@ export const liquidStakeStruct = new BeetStruct( (args) => args as LiquidStake ); +export type Pool = { + buffer: number; + padding: Buffer; + bump: number; + lpTokenBump: number; + nbStableCustody: number; + initialized: number; + allowTrade: number; + allowSwap: number; + liquidityState: number; + registeredCustodyCount: number; + name: Buffer; + custodies: PublicKey[]; + padding1: number[]; + whitelistedSwapper: PublicKey; + ratios: Buffer; + padding2: number[]; + aumUsdHigh: BigNumber; + aumUsdLow: BigNumber; +}; + +export const poolStruct = new FixableBeetStruct( + [ + // ['padding', blob(8 + 8 + 32 + 32 * 8 + 32 + 32 + 32 + 8 * 8 + 16 + 8)], + ['buffer', blob(8)], + ['bump', u8], + ['lpTokenBump', u8], + ['nbStableCustody', u8], + ['initialized', u8], + ['allowTrade', u8], + ['allowSwap', u8], + ['liquidityState', u8], + ['registeredCustodyCount', u8], + ['name', blob(32)], + ['custodies', uniformFixedSizeArray(publicKey, 8)], + ['padding1', uniformFixedSizeArray(u8, 32)], + ['whitelistedSwapper', publicKey], + ['ratios', blob(64)], + ['padding2', uniformFixedSizeArray(u8, 16)], + ['aumUsdHigh', u64], + ['aumUsdLow', u64], + ], + (args) => args as Pool +); + export type UserStaking = { bump: number; threadAuthorityBump: number;