Skip to content

Commit

Permalink
feat: optimized state fetching
Browse files Browse the repository at this point in the history
  • Loading branch information
k0beLeenders authored and chambaz committed Nov 29, 2023
1 parent dd10b70 commit 38e56ce
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 13 deletions.
65 changes: 56 additions & 9 deletions packages/marginfi-v2-ui-state/src/lib/mrgnlend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,28 +158,75 @@ export async function fetchBirdeyePrices(mints: PublicKey[], apiKey?: string): P
throw new Error("Failed to fetch price");
}

export async function fetchEmissionsPriceMap(
banks: Bank[],
connection: Connection,
export async function makeExtendedBankEmission(
banks: ExtendedBankInfo[],
extendedBankMetadatas: ExtendedBankMetadata[],
tokenMap: TokenPriceMap,
apiKey?: string
): Promise<TokenPriceMap> {
const banksWithEmissions = banks.filter((bank) => !bank.emissionsMint.equals(PublicKey.default));
const emissionsMints = banksWithEmissions.map((bank) => bank.emissionsMint);

let birdeyePrices = emissionsMints.map((m) => new BigNumber(0));
): Promise<[ExtendedBankInfo[], ExtendedBankMetadata[]]> {
const emissionsMints = Object.keys(tokenMap).map((key) => new PublicKey(key));
let birdeyePrices = emissionsMints.map(() => new BigNumber(0));

try {
birdeyePrices = await fetchBirdeyePrices(emissionsMints, apiKey);
} catch (err) {
console.log("Failed to fetch emissions prices from Birdeye", err);
}

emissionsMints.map((mint, idx) => {
tokenMap[mint.toBase58()] = { ...tokenMap[mint.toBase58()], price: birdeyePrices[idx] };
});

const updatedBanks = banks.map((bank) => {
const rawBank = bank.info.rawBank;
const emissionTokenData = tokenMap[rawBank.emissionsMint.toBase58()];
let emissionsRate: number = 0;
let emissions = Emissions.Inactive;
if ((rawBank.emissionsActiveLending || rawBank.emissionsActiveBorrowing) && emissionTokenData) {
const emissionsRateAmount = new BigNumber(nativeToUi(rawBank.emissionsRate, emissionTokenData.decimals));
const emissionsRateValue = emissionsRateAmount.times(emissionTokenData.price);
const emissionsRateAdditionalyApy = emissionsRateValue.div(bank.info.oraclePrice.price);

emissionsRate = emissionsRateAdditionalyApy.toNumber();

if (rawBank.emissionsActiveBorrowing) {
emissions = Emissions.Borrowing;
} else if (rawBank.emissionsActiveLending) {
emissions = Emissions.Lending;
}

bank.info.state = {
...bank.info.state,
emissionsRate,
emissions,
};
}
return bank;
});

const sortedExtendedBankInfos = updatedBanks.sort(
(a, b) => b.info.state.totalDeposits * b.info.state.price - a.info.state.totalDeposits * a.info.state.price
);

const sortedExtendedBankMetadatas = extendedBankMetadatas.sort((am, bm) => {
const a = sortedExtendedBankInfos.find((a) => a.address.equals(am.address))!;
const b = sortedExtendedBankInfos.find((b) => b.address.equals(bm.address))!;
return b.info.state.totalDeposits * b.info.state.price - a.info.state.totalDeposits * a.info.state.price;
});

return [sortedExtendedBankInfos, sortedExtendedBankMetadatas];
}

export async function makeEmissionsPriceMap(banks: Bank[], connection: Connection): Promise<TokenPriceMap> {
const banksWithEmissions = banks.filter((bank) => !bank.emissionsMint.equals(PublicKey.default));
const emissionsMints = banksWithEmissions.map((bank) => bank.emissionsMint);

const mintAis = await connection.getMultipleAccountsInfo(emissionsMints);

const mint = mintAis.map((ai) => MintLayout.decode(ai!.data));
const emissionsPrices = banksWithEmissions.map((bank, i) => ({
mint: bank.emissionsMint,
price: birdeyePrices[i],
price: new BigNumber(0),
decimals: mint[0].decimals,
}));

Expand Down
27 changes: 23 additions & 4 deletions packages/marginfi-v2-ui-state/src/store/mrgnlendStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { Bank, OraclePrice } from "@mrgnlabs/marginfi-client-v2";
import { Connection, PublicKey } from "@solana/web3.js";
import {
DEFAULT_ACCOUNT_SUMMARY,
fetchEmissionsPriceMap,
makeEmissionsPriceMap,
computeAccountSummary,
fetchTokenAccounts,
makeExtendedBankInfo,
Expand All @@ -21,6 +21,7 @@ import {
TokenAccountMap,
ExtendedBankMetadata,
makeExtendedBankMetadata,
makeExtendedBankEmission,
} from "../lib";
import { getPointsSummary } from "../lib/points";
import { create, StateCreator } from "zustand";
Expand Down Expand Up @@ -131,7 +132,7 @@ const stateCreator: StateCreator<MrgnlendState, [], []> = (set, get) => ({
const banks = [...marginfiClient.banks.values()];

const birdEyeApiKey = args?.birdEyeApiKey ?? get().birdEyeApiKey;
const priceMap = await fetchEmissionsPriceMap(banks, connection, birdEyeApiKey);
const priceMap = await makeEmissionsPriceMap(banks, connection);

let nativeSolBalance: number = 0;
let tokenAccountMap: TokenAccountMap;
Expand Down Expand Up @@ -252,7 +253,7 @@ const stateCreator: StateCreator<MrgnlendState, [], []> = (set, get) => ({
accountSummary = computeAccountSummary(selectedAccount, extendedBankInfos);
}

const pointSummary = await getPointsSummary();
const pointsTotal = get().protocolStats.pointsTotal;

set({
initialized: true,
Expand All @@ -268,13 +269,31 @@ const stateCreator: StateCreator<MrgnlendState, [], []> = (set, get) => ({
deposits,
borrows,
tvl: deposits - borrows,
pointsTotal: pointSummary.points_total,
pointsTotal: pointsTotal,
},
selectedAccount,
nativeSolBalance,
accountSummary,
birdEyeApiKey,
});

const pointSummary = await getPointsSummary();

set({
protocolStats: { deposits, borrows, tvl: deposits - borrows, pointsTotal: pointSummary.points_total },
});

const [sortedExtendedBankEmission, sortedExtendedBankMetadatasEmission] = await makeExtendedBankEmission(
sortedExtendedBankInfos,
sortedExtendedBankMetadatas,
priceMap,
birdEyeApiKey
);

set({
extendedBankInfos: sortedExtendedBankEmission,
extendedBankMetadatas: sortedExtendedBankMetadatasEmission,
});
} catch (err) {
console.error("error refreshing state: ", err);
set({ isRefreshingStore: false });
Expand Down

2 comments on commit 38e56ce

@vercel
Copy link

@vercel vercel bot commented on 38e56ce Nov 29, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

omni – ./apps/omni

omni-mrgn.vercel.app
omni-git-production-mrgn.vercel.app
omni-one.vercel.app
omni.marginfi.com

@vercel
Copy link

@vercel vercel bot commented on 38e56ce Nov 29, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.