From 9be0e9fe7c7e7379ed3f9351c1afa5e677d47118 Mon Sep 17 00:00:00 2001 From: Jon Ator Date: Tue, 4 Jun 2024 11:44:53 -0500 Subject: [PATCH] reduce excess CL position queries --- .../complex/concentrated-liquidity/index.ts | 80 ++++++++++--------- packages/trpc/src/concentrated-liquidity.ts | 71 ++++++++++++---- .../components/cards/my-position/index.tsx | 21 +++-- 3 files changed, 109 insertions(+), 63 deletions(-) diff --git a/packages/server/src/queries/complex/concentrated-liquidity/index.ts b/packages/server/src/queries/complex/concentrated-liquidity/index.ts index 06e601e835..517a96d72b 100644 --- a/packages/server/src/queries/complex/concentrated-liquidity/index.ts +++ b/packages/server/src/queries/complex/concentrated-liquidity/index.ts @@ -255,10 +255,6 @@ export async function mapGetUserPositionDetails({ ...params, bech32Address: userOsmoAddress, }); - const stakeCurrencyPromise = getAsset({ - ...params, - anyDenom: params.chainList[0].staking.staking_tokens[0].denom, - }); const superfluidPoolIdsPromise = getSuperfluidPoolIds(params); const [ @@ -266,17 +262,20 @@ export async function mapGetUserPositionDetails({ userUnbondingPositions, delegatedPositions, undelegatingPositions, - stakeCurrency, superfluidPoolIds, ] = await Promise.all([ positionsPromise, userUnbondingPositionsPromise, delegatedPositionsPromise, undelegatingPositionsPromise, - stakeCurrencyPromise, superfluidPoolIdsPromise, ]); + const stakeCurrency = getAsset({ + ...params, + anyDenom: params.chainList[0].staking.staking_tokens[0].denom, + }); + const lockableDurations = getLockableDurations(); const longestLockDuration = lockableDurations[lockableDurations.length - 1]; @@ -585,23 +584,28 @@ export type PositionHistoricalPerformance = Awaited< /** Gets a breakdown of current and reward coins, with fiat values, for a single CL position. */ export async function getPositionHistoricalPerformance({ - positionId, + position: givenPosition, ...params }: { assetLists: AssetList[]; chainList: Chain[]; - positionId: string; + /** Position by ID or the returned position object. */ + position: string | LiquidityPosition; }) { - const [{ position }, performance] = await Promise.all([ - queryPositionById({ ...params, id: positionId }), - queryPositionPerformance({ - positionId, - }), - ]); + const { position } = + typeof givenPosition === "string" + ? await queryPositionById({ ...params, id: givenPosition }) + : { position: givenPosition }; + + const performance = await queryPositionPerformance({ + positionId: position.position.position_id, + }); // There is no performance data for this position if (performance.message) { - console.error(`No performance data for position ${positionId}`); + console.error( + `No performance data for position ${position.position.position_id}` + ); } // get all user CL coins, including claimable rewards @@ -651,31 +655,33 @@ export async function getPositionHistoricalPerformance({ // calculate fiat values - const currentValue = new PricePretty( - DEFAULT_VS_CURRENCY, - await calcSumCoinsValue({ ...params, coins: currentCoins }).catch((e) => - captureErrorAndReturn(e, new Dec(0)) - ) - ); - const currentCoinsValues = ( - await Promise.all( + const [ + currentValue, + currentCoinsValues, + principalValue, + claimableRewardsValue, + totalEarnedValue, + ] = await Promise.all([ + calcSumCoinsValue({ ...params, coins: currentCoins }) + .then((value) => new PricePretty(DEFAULT_VS_CURRENCY, value)) + .catch(() => new PricePretty(DEFAULT_VS_CURRENCY, new Dec(0))), + Promise.all( currentCoins .map((coin) => calcCoinValue({ ...params, coin })) .map((p) => p.catch((e) => captureErrorAndReturn(e, 0))) - ) - ).map((p) => new PricePretty(DEFAULT_VS_CURRENCY, p)); - const principalValue = new PricePretty( - DEFAULT_VS_CURRENCY, - await calcSumCoinsValue({ ...params, coins: principalCoins }) - ); - const claimableRewardsValue = new PricePretty( - DEFAULT_VS_CURRENCY, - await calcSumCoinsValue({ ...params, coins: claimableRewardCoins }) - ); - const totalEarnedValue = new PricePretty( - DEFAULT_VS_CURRENCY, - await calcSumCoinsValue({ ...params, coins: totalRewardCoins }) - ); + ).then((values) => + values.map((p) => new PricePretty(DEFAULT_VS_CURRENCY, p)) + ), + calcSumCoinsValue({ ...params, coins: principalCoins }).then( + (value) => new PricePretty(DEFAULT_VS_CURRENCY, value) + ), + calcSumCoinsValue({ ...params, coins: claimableRewardCoins }).then( + (value) => new PricePretty(DEFAULT_VS_CURRENCY, value) + ), + calcSumCoinsValue({ ...params, coins: totalRewardCoins }).then( + (value) => new PricePretty(DEFAULT_VS_CURRENCY, value) + ), + ]); const principalValueDec = principalValue.toDec(); diff --git a/packages/trpc/src/concentrated-liquidity.ts b/packages/trpc/src/concentrated-liquidity.ts index 26a9d425ed..2de64f504e 100644 --- a/packages/trpc/src/concentrated-liquidity.ts +++ b/packages/trpc/src/concentrated-liquidity.ts @@ -10,6 +10,44 @@ import { z } from "zod"; import { createTRPCRouter, publicProcedure } from "./api"; import { UserOsmoAddressSchema } from "./parameter-types"; +const LiquidityPositionSchema = z.object({ + position: z.object({ + position_id: z.string(), + address: z.string(), + join_time: z.string(), + liquidity: z.string(), + lower_tick: z.string(), + pool_id: z.string(), + upper_tick: z.string(), + }), + asset0: z.object({ + amount: z.string(), + denom: z.string(), + }), + asset1: z.object({ + amount: z.string(), + denom: z.string(), + }), + claimable_spread_rewards: z.array( + z.object({ + denom: z.string(), + amount: z.string(), + }) + ), + claimable_incentives: z.array( + z.object({ + denom: z.string(), + amount: z.string(), + }) + ), + forfeited_incentives: z.array( + z.object({ + denom: z.string(), + amount: z.string(), + }) + ), +}); + export const concentratedLiquidityRouter = createTRPCRouter({ getUserPositions: publicProcedure .input( @@ -31,28 +69,33 @@ export const concentratedLiquidityRouter = createTRPCRouter({ .input( z .object({ - positionId: z.string(), + position: z.union([z.string(), LiquidityPositionSchema]), }) .merge(UserOsmoAddressSchema.required()) ) - .query(async ({ input: { positionId, userOsmoAddress }, ctx }) => { - const { position } = await queryPositionById({ ...ctx, id: positionId }); + .query( + async ({ input: { position: givenPosition, userOsmoAddress }, ctx }) => { + const { position } = + typeof givenPosition === "string" + ? await queryPositionById({ ...ctx, id: givenPosition }) + : { position: givenPosition }; - return ( - await mapGetUserPositionDetails({ - ...ctx, - positions: [position], - userOsmoAddress, - }) - )[0]; - }), + return ( + await mapGetUserPositionDetails({ + ...ctx, + positions: [position], + userOsmoAddress, + }) + )[0]; + } + ), getPositionHistoricalPerformance: publicProcedure .input( z.object({ - positionId: z.string(), + position: z.union([z.string(), LiquidityPositionSchema]), }) ) - .query(({ input: { positionId }, ctx }) => - getPositionHistoricalPerformance({ ...ctx, positionId }) + .query(({ input: { position }, ctx }) => + getPositionHistoricalPerformance({ ...ctx, position }) ), }); diff --git a/packages/web/components/cards/my-position/index.tsx b/packages/web/components/cards/my-position/index.tsx index 074c6db4ec..cf309a3251 100644 --- a/packages/web/components/cards/my-position/index.tsx +++ b/packages/web/components/cards/my-position/index.tsx @@ -23,17 +23,14 @@ export const MyPositionCard: FunctionComponent<{ const { accountStore, chainStore } = useStore(); const { chainId } = chainStore.osmosis; const account = accountStore.getWallet(chainId); + const { showLinkToPool = false, position } = props; const { - showLinkToPool = false, - position: { - id, - poolId, - currentCoins, - currentValue, - priceRange: [lowerPrice, upperPrice], - isFullRange, - }, - } = props; + poolId, + currentCoins, + currentValue, + priceRange: [lowerPrice, upperPrice], + isFullRange, + } = position; const { t } = useTranslation(); const [collapsed, setCollapsed] = useState(true); const featureFlags = useFeatureFlags(); @@ -41,7 +38,7 @@ export const MyPositionCard: FunctionComponent<{ const { data: positionPerformance } = api.local.concentratedLiquidity.getPositionHistoricalPerformance.useQuery( { - positionId: id, + position: position.position, }, { trpc: { @@ -55,7 +52,7 @@ export const MyPositionCard: FunctionComponent<{ const { data: positionDetails, isLoading: isLoadingPositionDetails } = api.local.concentratedLiquidity.getPositionDetails.useQuery( { - positionId: id, + position: position.position, userOsmoAddress: account?.address ?? "", }, {