Skip to content

Commit

Permalink
fix: fix tanstack query caching with price calculations
Browse files Browse the repository at this point in the history
  • Loading branch information
rkalis committed Jan 26, 2025
1 parent 8f5f351 commit 7131da3
Show file tree
Hide file tree
Showing 9 changed files with 28 additions and 22 deletions.
6 changes: 3 additions & 3 deletions lib/price/AbstractPriceStrategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export abstract class AbstractPriceStrategy implements PriceStrategy {
this.supportedAssets = options.supportedAssets;
}

public async calculateNativeTokenPrice(publicClient: PublicClient): Promise<number | undefined> {
public async calculateNativeTokenPrice(publicClient: PublicClient): Promise<number | null> {
if (!this.nativeAsset) {
throw new Error('Native token type is not supported by this price strategy');
}
Expand All @@ -32,13 +32,13 @@ export abstract class AbstractPriceStrategy implements PriceStrategy {
return tokenPrice;
}

public calculateTokenPrice(tokenContract: TokenContract): Promise<number | undefined> {
public calculateTokenPrice(tokenContract: TokenContract): Promise<number | null> {
if (!strategySupportsToken(this, tokenContract)) {
throw new Error('Token type is not supported by this price strategy');
}

return this.calculateTokenPriceInternal(tokenContract);
}

protected abstract calculateTokenPriceInternal(tokenContract: TokenContract): Promise<number | undefined>;
protected abstract calculateTokenPriceInternal(tokenContract: TokenContract): Promise<number | null>;
}
4 changes: 2 additions & 2 deletions lib/price/AggregatePriceStrategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,12 @@ export class AggregatePriceStrategy implements PriceStrategy {

// Note: we only use the first strategy to calculate the native token price, so we only need to make sure that
// the first strategy is able to calculate the native token price
public async calculateNativeTokenPrice(publicClient: PublicClient): Promise<number | undefined> {
public async calculateNativeTokenPrice(publicClient: PublicClient): Promise<number | null> {
if (this.strategies.length === 0) throw new Error('No strategies provided');
return this.strategies[0].calculateNativeTokenPrice(publicClient);
}

public async calculateTokenPrice(tokenContract: TokenContract): Promise<number | undefined> {
public async calculateTokenPrice(tokenContract: TokenContract): Promise<number | null> {
const supportedStrategies = this.getSupportedStrategies(tokenContract);
if (supportedStrategies.length === 0) throw new Error('No supported strategies provided for this token type');

Expand Down
4 changes: 2 additions & 2 deletions lib/price/PriceStrategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ import type { PublicClient } from 'viem';

export interface PriceStrategy {
supportedAssets: TokenStandard[];
calculateNativeTokenPrice: (publicClient: PublicClient) => Promise<number | undefined>;
calculateTokenPrice: (tokenContract: TokenContract) => Promise<number | undefined>;
calculateNativeTokenPrice: (publicClient: PublicClient) => Promise<number | null>;
calculateTokenPrice: (tokenContract: TokenContract) => Promise<number | null>;
}
2 changes: 1 addition & 1 deletion lib/price/UniswapV2PriceStrategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export class UniswapV2PriceStrategy extends AbstractPriceStrategy implements Pri
this.fee = options.feeParameters?.fee ?? [];
}

protected async calculateTokenPriceInternal(tokenContract: Erc20TokenContract): Promise<number | undefined> {
protected async calculateTokenPriceInternal(tokenContract: Erc20TokenContract): Promise<number | null> {
if (tokenContract.address === this.path.at(-1)) {
return 1;
}
Expand Down
2 changes: 1 addition & 1 deletion lib/price/UniswapV3PriceStrategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export class UniswapV3PriceStrategy extends AbstractPriceStrategy implements Pri
this.decimals = options.decimals ?? 18;
}

protected async calculateTokenPriceInternal(tokenContract: Erc20TokenContract): Promise<number | undefined> {
protected async calculateTokenPriceInternal(tokenContract: Erc20TokenContract): Promise<number | null> {
if (tokenContract.address === this.path.at(-1)) {
// return parseUnits(String(1), this.decimals);

Expand Down
2 changes: 1 addition & 1 deletion lib/price/UniswapV3ReadonlyPriceStrategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export class UniswapV3ReadonlyPriceStrategy extends UniswapV3PriceStrategy {
this.minLiquidity = options.liquidityParameters?.minLiquidity ?? 10n ** 17n;
}

protected async calculateTokenPriceInternal(tokenContract: Erc20TokenContract): Promise<number | undefined> {
protected async calculateTokenPriceInternal(tokenContract: Erc20TokenContract): Promise<number | null> {
if (tokenContract.address === this.path.at(-1)) {
return 1;
}
Expand Down
16 changes: 8 additions & 8 deletions lib/price/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,30 @@ import { type TokenContract, isErc721Contract } from 'lib/utils/tokens';
import { type PublicClient, formatUnits } from 'viem';
import type { PriceStrategy } from './PriceStrategy';

export const calculateTokenPrice = (inversePrice: bigint | null, tokenDecimals: number): number | undefined => {
return isNullish(inversePrice) ? undefined : 1 / Number.parseFloat(formatUnits(inversePrice, tokenDecimals));
export const calculateTokenPrice = (inversePrice: bigint | null, tokenDecimals: number): number | null => {
return isNullish(inversePrice) ? null : 1 / Number.parseFloat(formatUnits(inversePrice, tokenDecimals));
};

export const getNativeTokenPrice = async (chainId: number, publicClient: PublicClient): Promise<number | undefined> => {
export const getNativeTokenPrice = async (chainId: number, publicClient: PublicClient): Promise<number | null> => {
const strategy = getChainPriceStrategy(chainId);

if (!strategy) return undefined;
if (!strategy) return null;

try {
return await strategy.calculateNativeTokenPrice(publicClient);
} catch {
return undefined;
return null;
}
};

export const getTokenPrice = async (chainId: number, tokenContract: TokenContract): Promise<number | undefined> => {
export const getTokenPrice = async (chainId: number, tokenContract: TokenContract): Promise<number | null> => {
const strategy = getChainPriceStrategy(chainId);
if (!strategy || !strategySupportsToken(strategy, tokenContract)) return undefined;
if (!strategy || !strategySupportsToken(strategy, tokenContract)) return null;

try {
return await strategy.calculateTokenPrice(tokenContract);
} catch {
return undefined;
return null;
}
};

Expand Down
10 changes: 8 additions & 2 deletions lib/utils/formatting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,16 @@ export const formatBalance = (symbol: string, balance: TokenBalance, decimals?:
return `${formatFixedPointBigInt(balance, decimals)} ${symbol}`;
};

export const formatFiatBalance = (balance: TokenBalance, price?: number, decimals?: number, fiatSign: string = '$') => {
export const formatFiatBalance = (
balance: TokenBalance,
price?: Nullable<number>,
decimals?: number,
fiatSign: string = '$',
) => {
if (balance === 'ERC1155') return null;
if (isNullish(price)) return null;
return formatFiatAmount(Number(formatUnits(fixedPointMultiply(balance, price, decimals ?? 18), decimals ?? 18)));
const amount = Number(formatUnits(fixedPointMultiply(balance, price, decimals ?? 18), decimals ?? 18));
return formatFiatAmount(amount, decimals, fiatSign);
};

export const formatFiatAmount = (
Expand Down
4 changes: 2 additions & 2 deletions lib/utils/tokens.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ERC20_ABI, ERC721_ABI } from 'lib/abis';
import { DUMMY_ADDRESS, DUMMY_ADDRESS_2, WHOIS_BASE_URL } from 'lib/constants';
import type { Contract } from 'lib/interfaces';
import type { Contract, Nullable } from 'lib/interfaces';
import ky from 'lib/ky';
import { getTokenPrice } from 'lib/price/utils';
import {
Expand Down Expand Up @@ -47,7 +47,7 @@ export interface TokenMetadata {
icon?: string;
decimals?: number;
totalSupply?: bigint;
price?: number;
price?: Nullable<number>;
}

export type TokenBalance = bigint | 'ERC1155';
Expand Down

0 comments on commit 7131da3

Please sign in to comment.