Skip to content

Commit

Permalink
reduce excess CL position queries
Browse files Browse the repository at this point in the history
  • Loading branch information
jonator committed Jun 4, 2024
1 parent 10725b2 commit 9be0e9f
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 63 deletions.
80 changes: 43 additions & 37 deletions packages/server/src/queries/complex/concentrated-liquidity/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -255,28 +255,27 @@ 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 [
positions,
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];

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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();

Expand Down
71 changes: 57 additions & 14 deletions packages/trpc/src/concentrated-liquidity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -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 })
),
});
21 changes: 9 additions & 12 deletions packages/web/components/cards/my-position/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,25 +23,22 @@ 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();

const { data: positionPerformance } =
api.local.concentratedLiquidity.getPositionHistoricalPerformance.useQuery(
{
positionId: id,
position: position.position,
},
{
trpc: {
Expand All @@ -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 ?? "",
},
{
Expand Down

0 comments on commit 9be0e9f

Please sign in to comment.