Skip to content

Commit

Permalink
add birdeye support fro fetching token prices
Browse files Browse the repository at this point in the history
  • Loading branch information
Nagaprasadvr committed Feb 28, 2024
1 parent 72def01 commit c2cfca6
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 20 deletions.
52 changes: 33 additions & 19 deletions packages/cli/src/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,13 @@ import {
} from '@convergence-rfq/sdk';

import { createCvg, Opts } from './cvg';
import { getInstrumentType, getSigConfirmation, getSize } from './helpers';
import {
fetchBirdeyeTokenPrice,
fetchCoinGeckoTokenPrice,
getInstrumentType,
getSigConfirmation,
getSize,
} from './helpers';
import {
logPk,
logResponse,
Expand All @@ -30,7 +36,7 @@ import {
logToken,
logMint,
} from './logger';
import { CoinGeckoResponse, JupTokenList } from './types';
import { JupTokenList } from './types';

export const createMint = async (opts: Opts) => {
const cvg = await createCvg(opts);
Expand Down Expand Up @@ -502,18 +508,23 @@ export const airdropDevnetTokens = async (opts: Opts) => {
export const addBaseAssetsFromJupiter = async (opts: Opts) => {
try {
const cvg = await createCvg(opts);

const { birdeyeApiKey, coinGeckoApiKey } = opts;
const baseAssets = await cvg.protocol().getBaseAssets();
const registerMints = await cvg.protocol().getRegisteredMints();
// eslint-disable-next-line no-console
console.log('Base assets:', baseAssets);
const baseAssetsSymbols = baseAssets.map((b) => b.ticker);
const registerMintAddresses = registerMints.map((r) =>
r.mintAddress.toBase58()
);
const baseAssetAddresses = baseAssets.map((b) => b.address.toBase58());
const res = await fetch('https://token.jup.ag/all');
const jupTokens: JupTokenList[] = await res.json();
const jupTokensToAdd = jupTokens.filter(
(t) =>
!baseAssetsSymbols.includes(t.symbol) &&
!baseAssetAddresses.includes(t.address)
!baseAssetAddresses.includes(t.address) &&
!registerMintAddresses.includes(t.address.toString())
);

let baseAssetIndexToStart = Math.max(...baseAssets.map((b) => b.index)) + 1;
Expand All @@ -522,23 +533,26 @@ export const addBaseAssetsFromJupiter = async (opts: Opts) => {
for (const token of jupTokensToAdd) {
try {
const coingeckoId = token?.extensions?.coingeckoId;
if (!coingeckoId || coingeckoId === '') {
// eslint-disable-next-line no-console
console.log(
'skipping token: because missing coingecko id',
token.symbol
let tokenPrice: number | undefined = undefined;
if (coingeckoId && coingeckoId !== '') {
tokenPrice = await fetchCoinGeckoTokenPrice(
coinGeckoApiKey,
coingeckoId
);
if (!tokenPrice) {
tokenPrice = await fetchBirdeyeTokenPrice(
opts.birdeyeAPIKey,
token.address
);
}
} else {
tokenPrice = await fetchBirdeyeTokenPrice(
birdeyeApiKey,
token.address
);
continue;
}
const coinGeckoAPIKey = opts.coinGeckoApiKey;
const tokenPriceResponse = await fetch(
`https://pro-api.coingecko.com/api/v3/simple/price?ids=${coingeckoId}&vs_currencies=usd&x_cg_pro_api_key=${coinGeckoAPIKey}`
);
const tokenPriceJson: CoinGeckoResponse =
await tokenPriceResponse.json();

const tokenPrice = tokenPriceJson[coingeckoId]?.usd;
if (!tokenPrice) {
if (tokenPrice === undefined) {
// eslint-disable-next-line no-console
console.log(
'skipping token: because missing price',
Expand All @@ -564,7 +578,7 @@ export const addBaseAssetsFromJupiter = async (opts: Opts) => {
// eslint-disable-next-line no-console
console.log('Adding base asset:', token.symbol);
// eslint-disable-next-line no-console
console.log(' current baseAssetIndex:', baseAssetIndexToStart);
console.log('current baseAssetIndex:', baseAssetIndexToStart);
const registerMintTxBuilder = await registerMintBuilder(cvg, {
mint: new PublicKey(token.address),
baseAssetIndex: baseAssetIndexToStart,
Expand Down
4 changes: 4 additions & 0 deletions packages/cli/src/groups/protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,10 @@ const addBaseAssetsFromJupiterCmd = (c: Command) =>
flags: '--coin-gecko-api-key <string>',
description: 'coin gecko api key',
},
{
flags: '--birdeye-api-key <string>',
description: 'birdeye api key',
},
]
);

Expand Down
37 changes: 36 additions & 1 deletion packages/cli/src/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
import { Command } from 'commander';

import { Connection } from '@solana/web3.js';
import { Instrument } from './types';
import { CoinGeckoResponse, Instrument } from './types';
import { DEFAULT_KEYPAIR_FILE, DEFAULT_RPC_ENDPOINT } from './constants';

export const getInstrumentType = (type: string): InstrumentType => {
Expand Down Expand Up @@ -108,3 +108,38 @@ export const getSigConfirmation = async (
});
return result?.value?.confirmationStatus;
};

export const fetchCoinGeckoTokenPrice = async (
coinGeckoApiKey: string,
coingeckoId: string
) => {
const tokenPriceResponse = await fetch(
`https://pro-api.coingecko.com/api/v3/simple/price?ids=${coingeckoId}&vs_currencies=usd&x_cg_pro_api_key=${coinGeckoApiKey}`
);
const tokenPriceJson: CoinGeckoResponse = await tokenPriceResponse.json();

if (tokenPriceJson[coingeckoId]?.usd) {
return Number(tokenPriceJson[coingeckoId]?.usd);
}
return undefined;
};

export const fetchBirdeyeTokenPrice = async (
birdeyeApiKey: string,
tokenAddress: string
) => {
const options = {
method: 'GET',
headers: { 'X-API-KEY': birdeyeApiKey },
};

const tokenPriceResponse = await fetch(
`https://public-api.birdeye.so/defi/price?address=${tokenAddress}`,
options
);
const tokenPriceJson: any = await tokenPriceResponse.json();
if (tokenPriceJson?.success === true) {
return Number(tokenPriceJson?.data?.value);
}
return undefined;
};

0 comments on commit c2cfca6

Please sign in to comment.