refactor: cache erc20 token decimals

This commit is contained in:
c4605
2025-08-02 15:40:38 +02:00
parent 2972100f47
commit 510dc29c35
4 changed files with 55 additions and 16 deletions

View File

@@ -316,6 +316,9 @@ export class BroSDK {
evm: {
routesConfigCache: new Map(),
feeRateCache: new Map(),
tokenInfoCaches: {
decimals: new Map(),
},
onChainConfigCache,
viemClients: {
...defaultEvmClients,

View File

@@ -11,6 +11,8 @@ import { nativeCurrencyAddress } from "./addressHelpers"
import { getEVMOnChainConfig } from "./apiHelpers/getEVMOnChainConfig"
import { getEVMSupportedRoutes } from "./apiHelpers/getEVMSupportedRoutes"
import { EVMEndpointContract } from "./evmContractAddresses"
import { readContract } from "viem/actions"
import { ERC20Abi } from "./contractAbi/ERC20Abi"
const CONTRACT_COMMON_NUMBER_SCALE = 18
export const numberFromSolidityContractNumber = (
@@ -113,3 +115,35 @@ export async function getEVMToken(
r => r.evmTokenAddress.toLowerCase() === tokenAddress.toLowerCase(),
)?.evmToken
}
export function getERC20TokenDecimals(
sdkContext: SDKGlobalContext,
chainId: KnownChainId.EVMChain,
tokenAddress: EVMAddress,
): Promise<undefined | number> {
const cacheKey = `${chainId}:${tokenAddress}`
const tokenInfoCache = sdkContext.evm.tokenInfoCaches.decimals.get(cacheKey)
if (tokenInfoCache != null) return tokenInfoCache
const client = sdkContext.evm.viemClients[chainId]
if (client == null) return Promise.resolve(undefined)
const resPromise = readContract(client, {
abi: ERC20Abi,
address: tokenAddress,
functionName: "decimals",
}).catch(err => {
queueMicrotask(() => {
if (
sdkContext.evm.tokenInfoCaches.decimals.get(cacheKey) === resPromise
) {
sdkContext.evm.tokenInfoCaches.decimals.delete(cacheKey)
}
})
throw err
})
sdkContext.evm.tokenInfoCaches.decimals.set(cacheKey, resPromise)
return resPromise
}

View File

@@ -83,6 +83,9 @@ export interface SDKGlobalContext {
string,
Promise<undefined | TransferProphet>
>
tokenInfoCaches: {
decimals: SDKGlobalContextCache<string, Promise<undefined | number>>
}
routesConfigCache?: SDKGlobalContextCache<
"mainnet" | "testnet",
Promise<EVMSupportedRoute[]>

View File

@@ -1,6 +1,9 @@
import { readContract } from "viem/actions"
import { ERC20Abi } from "../../../evmUtils/contractAbi/ERC20Abi"
import { getEVMTokenContractInfo } from "../../../evmUtils/contractHelpers"
import {
getERC20TokenDecimals,
getEVMTokenContractInfo,
} from "../../../evmUtils/contractHelpers"
import { evmChainIdFromKnownChainId } from "../../../evmUtils/evmClients"
import {
EVMAddress,
@@ -68,23 +71,19 @@ export async function getQueryableRoutes(
return
}
const client = Object.values(sdkContext.evm.viemClients).find(
c => c.chain?.id === Number(chainId),
)
if (client == null) return
const [fromTokenDecimals, toTokenDecimals] = await Promise.all([
readContract(client, {
abi: ERC20Abi,
address: fromEVMToken.tokenContractAddress,
functionName: "decimals",
}),
readContract(client, {
abi: ERC20Abi,
address: toEVMToken.tokenContractAddress,
functionName: "decimals",
}),
getERC20TokenDecimals(
sdkContext,
info.evmChain,
fromEVMToken.tokenContractAddress,
),
getERC20TokenDecimals(
sdkContext,
info.evmChain,
toEVMToken.tokenContractAddress,
),
])
if (fromTokenDecimals == null || toTokenDecimals == null) return
return {
chain: {