Skip to content

Commit

Permalink
Restore sorting feature on All Pools page (#1679)
Browse files Browse the repository at this point in the history
* Make makeQueryKey2, pull keys to shareable structure

* Update hooks to use new makeQueryKey2

* Move getDepositAssets to own file

* Refactor to destructured object params

* Move logic out to own function for re-use in other hooks

* Use fiat price from hook

* Refactor PoolsList fetching to own hook, bring back Sort button

* Add comments

* Fix sorting by variable rate

* Remove dead code
  • Loading branch information
DannyDelott authored Dec 13, 2024
1 parent c3380b3 commit 00d19a5
Show file tree
Hide file tree
Showing 25 changed files with 940 additions and 499 deletions.
54 changes: 54 additions & 0 deletions apps/hyperdrive-trading/src/base/makeQueryKey.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { createSerializableKey } from "@delvtech/drift";
import { QueryKey } from "@tanstack/query-core";
/**
* This is a factory function for generating application-level query keys. By
Expand All @@ -8,6 +9,59 @@ import { QueryKey } from "@tanstack/query-core";
* Recommended use: All app queries should leverage this function for query key
* creation to maintain namespace integrity.
*/
/**
*
* @deprecated use `makeQueryKey2` instead
*/
export function makeQueryKey<T>(queryName: string, options: T): QueryKey {
return ["app", queryName, options];
}

// Intentionally empty, as we want individual queryKeys.ts files to merge
// declarations into this type
export interface QueryKeys {}

export function makeQueryKey2<
QueryNamespace extends keyof QueryKeys,
QueryId extends keyof QueryKeys[QueryNamespace],
>({
namespace,
queryId,
params,
}: {
namespace: QueryNamespace;
queryId: QueryId;
params: QueryKeys[QueryNamespace][QueryId];
}): QueryKey {
return [
...makeNamespaceQueryKey({ namespace, queryId }),
createSerializableKey(params as any),
];
}

/**
* Returns the query key for a given namespace and optional queryId, used for
* partial matching in tanstack query.
*
* Example:
* // matches all token queries
* const queryKey = makeNamespaceQueryKey({ namespace: "tokens" });
*
* // matches all tokenFiatPrice queries
* const queryKey = makeNamespaceQueryKey({ namespace: "tokens", queryId: "tokenFiatPrice" });
*/
export function makeNamespaceQueryKey<
QueryNamespace extends keyof QueryKeys,
QueryId extends keyof QueryKeys[QueryNamespace],
>({
namespace,
queryId,
}: {
namespace: QueryNamespace;
queryId?: QueryId;
}): QueryKey {
if (!queryId) {
return ["app", namespace];
}
return ["app", namespace, queryId];
}
33 changes: 33 additions & 0 deletions apps/hyperdrive-trading/src/hyperdrive/getDepositAssets.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { ZERO_ADDRESS } from "@delvtech/drift";
import {
HyperdriveConfig,
TokenConfig,
appConfig,
getBaseToken,
getToken,
} from "@delvtech/hyperdrive-appconfig";

// TODO: Move this to the appconfig
export function getDepositAssets(hyperdrive: HyperdriveConfig): TokenConfig[] {
const depositAssets: TokenConfig[] = [];
if (hyperdrive.depositOptions.isBaseTokenDepositEnabled) {
const baseToken = getBaseToken({
hyperdriveChainId: hyperdrive.chainId,
hyperdriveAddress: hyperdrive.address,
appConfig,
});
depositAssets.push(baseToken);
}

if (hyperdrive.depositOptions.isShareTokenDepositsEnabled) {
const sharesToken = getToken({
chainId: hyperdrive.chainId,
tokenAddress: hyperdrive.poolConfig.vaultSharesToken,
appConfig,
});
if (sharesToken && sharesToken.address !== ZERO_ADDRESS) {
depositAssets.push(sharesToken);
}
}
return depositAssets;
}
11 changes: 7 additions & 4 deletions apps/hyperdrive-trading/src/hyperdrive/getYieldSourceRate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,13 @@ import { isForkChain } from "src/chains/isForkChain";
import { wagmiConfig } from "src/network/wagmiClient";
import { PublicClient } from "viem";

export async function getYieldSourceRate(
readHyperdrive: ReadHyperdrive,
appConfig: AppConfig,
): Promise<{ rate: bigint; ratePeriodDays: number; netRate: bigint }> {
export async function getYieldSourceRate({
readHyperdrive,
appConfig,
}: {
readHyperdrive: ReadHyperdrive;
appConfig: AppConfig;
}): Promise<{ rate: bigint; ratePeriodDays: number; netRate: bigint }> {
const hyperdriveChainId = await readHyperdrive.drift.getChainId();
const hyperdrive = getHyperdriveConfig({
hyperdriveChainId,
Expand Down
12 changes: 8 additions & 4 deletions apps/hyperdrive-trading/src/ui/hyperdrive/hooks/usePoolInfo.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { PoolInfo } from "@delvtech/hyperdrive-js";
import { useQuery } from "@tanstack/react-query";
import { makeQueryKey } from "src/base/makeQueryKey";
import { makeQueryKey2 } from "src/base/makeQueryKey";
import { useReadHyperdrive } from "src/ui/hyperdrive/hooks/useReadHyperdrive";
import { Address } from "viem";
export function usePoolInfo({
Expand All @@ -20,9 +20,13 @@ export function usePoolInfo({
});
const queryEnabled = !!readHyperdrive && !!enabled;
const { data: poolInfo } = useQuery({
queryKey: makeQueryKey("poolInfo", {
chainId,
hyperdriveAddress,
queryKey: makeQueryKey2({
namespace: "hyperdrive",
queryId: "poolInfo",
params: {
chainId,
hyperdriveAddress,
},
}),
queryFn: queryEnabled ? () => readHyperdrive.getPoolInfo() : undefined,
enabled: queryEnabled,
Expand Down
88 changes: 83 additions & 5 deletions apps/hyperdrive-trading/src/ui/hyperdrive/hooks/usePresentValue.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,19 @@
import { fixed } from "@delvtech/fixed-point-wasm";
import {
appConfig,
getBaseToken,
getHyperdriveConfig,
} from "@delvtech/hyperdrive-appconfig";
import { ReadHyperdrive } from "@delvtech/hyperdrive-js";
import { QueryStatus, useQuery } from "@tanstack/react-query";
import { makeQueryKey } from "src/base/makeQueryKey";
import { getPublicClient } from "@wagmi/core";
import { ZERO_ADDRESS } from "src/base/constants";
import { makeQueryKey2 } from "src/base/makeQueryKey";
import { isTestnetChain } from "src/chains/isTestnetChain";
import { wagmiConfig } from "src/network/wagmiClient";
import { useReadHyperdrive } from "src/ui/hyperdrive/hooks/useReadHyperdrive";
import { Address } from "viem";
import { getTokenFiatPrice } from "src/ui/token/hooks/useTokenFiatPrice";
import { Address, PublicClient } from "viem";

export function usePresentValue({
chainId,
Expand All @@ -10,7 +22,12 @@ export function usePresentValue({
chainId: number;
hyperdriveAddress: Address;
}): {
presentValue: bigint | undefined;
presentValue:
| {
base: bigint;
fiat: bigint | undefined;
}
| undefined;
presentValueStatus: QueryStatus;
} {
const readHyperdrive = useReadHyperdrive({
Expand All @@ -19,8 +36,25 @@ export function usePresentValue({
});
const queryEnabled = !!readHyperdrive;
const { data, status } = useQuery({
queryKey: makeQueryKey("present-value", { chainId, hyperdriveAddress }),
queryFn: queryEnabled ? () => readHyperdrive.getPresentValue() : undefined,
queryKey: makeQueryKey2({
namespace: "hyperdrive",
queryId: "presentValue",
params: { chainId, hyperdriveAddress },
}),
queryFn: queryEnabled
? async () => {
const publicClient = getPublicClient(wagmiConfig as any, {
chainId,
}) as PublicClient;

return getPresentValue({
hyperdriveAddress,
chainId,
publicClient,
readHyperdrive,
});
}
: undefined,
enabled: queryEnabled,
});

Expand All @@ -29,3 +63,47 @@ export function usePresentValue({
presentValueStatus: status,
};
}

export function getPresentValue({
hyperdriveAddress,
chainId,
publicClient,
readHyperdrive,
}: {
publicClient: PublicClient;
hyperdriveAddress: Address;
chainId: number;
readHyperdrive: ReadHyperdrive;
}): Promise<{ base: bigint; fiat: bigint | undefined }> {
const hyperdriveConfig = getHyperdriveConfig({
appConfig,
hyperdriveAddress,
hyperdriveChainId: chainId,
});
const baseToken = getBaseToken({
hyperdriveChainId: chainId,
hyperdriveAddress,
appConfig,
});
const isFiatSupported =
!isTestnetChain(chainId) && baseToken.address !== ZERO_ADDRESS;
const fiatPricePromise = isFiatSupported
? getTokenFiatPrice({
chainId: baseToken.chainId,
publicClient,
tokenAddress: baseToken.address,
})
: Promise.resolve(undefined);
return Promise.all([readHyperdrive.getPresentValue(), fiatPricePromise]).then(
([presentValue, fiatPrice]) => {
const presentValueFiat = fiatPrice
? fixed(presentValue, hyperdriveConfig.decimals).mul(fiatPrice).bigint
: undefined;

return {
base: presentValue,
fiat: presentValueFiat,
};
},
);
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { QueryStatus, useQuery } from "@tanstack/react-query";
import { makeQueryKey } from "src/base/makeQueryKey";
import { makeQueryKey2 } from "src/base/makeQueryKey";
import { useReadHyperdrive } from "src/ui/hyperdrive/hooks/useReadHyperdrive";
import { Address } from "viem";

Expand All @@ -19,9 +19,13 @@ export function useCurrentLongPrice({
});
const queryEnabled = !!readHyperdrive;
const { data, status } = useQuery({
queryKey: makeQueryKey("current-long-price", {
chainId,
hyperdriveAddress: hyperdriveAddress,
queryKey: makeQueryKey2({
namespace: "hyperdrive",
queryId: "currentLongPrice",
params: {
chainId,
hyperdriveAddress: hyperdriveAddress,
},
}),
queryFn: queryEnabled ? () => readHyperdrive.getLongPrice() : undefined,
enabled: queryEnabled,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { getHprFromApr } from "@delvtech/hyperdrive-js";
import { useQuery } from "@tanstack/react-query";

import { formatRate } from "src/base/formatRate";
import { makeQueryKey } from "src/base/makeQueryKey";
import { makeQueryKey2 } from "src/base/makeQueryKey";
import { QueryStatusWithIdle, getStatus } from "src/base/queryStatus";
import { useReadHyperdrive } from "src/ui/hyperdrive/hooks/useReadHyperdrive";
import { Address } from "viem";
Expand Down Expand Up @@ -34,7 +34,11 @@ export function useFixedRate({

const queryEnabled = !!readHyperdrive;
const { data, status, fetchStatus } = useQuery({
queryKey: makeQueryKey("fixedApr", { chainId, address: hyperdriveAddress }),
queryKey: makeQueryKey2({
namespace: "hyperdrive",
queryId: "fixedApr",
params: { chainId, hyperdriveAddress },
}),
queryFn: queryEnabled
? async () => {
const fixedApr = await readHyperdrive.getFixedApr({ block });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ import { ConnectWalletButton } from "src/ui/compliance/ConnectWallet";
import { InvalidTransactionButton } from "src/ui/hyperdrive/InvalidTransactionButton";
import { TransactionView } from "src/ui/hyperdrive/TransactionView";
import { useIsNewPool } from "src/ui/hyperdrive/hooks/useIsNewPool";
import { useLpApy } from "src/ui/hyperdrive/hooks/useLpApy";
import { useMarketState } from "src/ui/hyperdrive/hooks/useMarketState";
import { usePoolInfo } from "src/ui/hyperdrive/hooks/usePoolInfo";
import { useFixedRate } from "src/ui/hyperdrive/longs/hooks/useFixedRate";
import { useAddLiquidity } from "src/ui/hyperdrive/lp/hooks/useAddLiquidity";
import { useLpApy } from "src/ui/hyperdrive/lp/hooks/useLpApy";
import { useLpShares } from "src/ui/hyperdrive/lp/hooks/useLpShares";
import { useLpSharesTotalSupply } from "src/ui/hyperdrive/lp/hooks/useLpSharesTotalSupply";
import { usePreviewAddLiquidity } from "src/ui/hyperdrive/lp/hooks/usePreviewAddLiquidity";
Expand Down Expand Up @@ -167,7 +167,7 @@ export function AddLiquidityForm({
const lpSharePrice = !isBaseActiveToken
? fixed(poolInfo?.lpSharePrice || 0n, baseToken.decimals).div(
poolInfo?.vaultSharePrice || 0n,
baseToken.decimals
baseToken.decimals,
).bigint
: poolInfo?.lpSharePrice || 0n;

Expand Down Expand Up @@ -253,7 +253,7 @@ export function AddLiquidityForm({
balance:
activeTokenPrice && depositAmountAsBigInt
? fixed(depositAmountAsBigInt, activeToken.decimals).mul(
activeTokenPrice
activeTokenPrice,
).bigint
: 0n,
decimals: activeToken.decimals,
Expand Down Expand Up @@ -352,7 +352,7 @@ export function AddLiquidityForm({
disclaimer={(() => {
if (
previewAddLiquidityError?.message.includes(
"Not enough lp shares minted."
"Not enough lp shares minted.",
)
) {
return (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { appConfig, getHyperdriveConfig } from "@delvtech/hyperdrive-appconfig";
import { useQuery } from "@tanstack/react-query";
import { makeQueryKey } from "src/base/makeQueryKey";
import { makeQueryKey2 } from "src/base/makeQueryKey";
import { getLpApy, LpApyResult } from "src/hyperdrive/getLpApy";
import { usePoolInfo } from "src/ui/hyperdrive/hooks/usePoolInfo";
import { useReadHyperdrive } from "src/ui/hyperdrive/hooks/useReadHyperdrive";
import { Address } from "viem";
import { useBlockNumber } from "wagmi";

export function useLpApy({
hyperdriveAddress,
chainId,
Expand Down Expand Up @@ -35,10 +34,14 @@ export function useLpApy({
});
const queryEnabled = !!readHyperdrive && !!blockNumber && !!currentPoolInfo;
const { data, status } = useQuery({
queryKey: makeQueryKey("getLpApy", {
chainId,
blockNumber: blockNumber?.toString(),
hyperdrive: hyperdriveAddress,
queryKey: makeQueryKey2({
namespace: "hyperdrive",
queryId: "lpApy",
params: {
blockNumber,
chainId,
hyperdriveAddress,
},
}),
queryFn: queryEnabled
? async () =>
Expand Down
Loading

0 comments on commit 00d19a5

Please sign in to comment.