From db40ff0b224f477290a51a7e4b05ecc4023e7942 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Harrison=20Mendon=C3=A7a?= Date: Thu, 21 Nov 2024 19:41:59 -0300 Subject: [PATCH] fix: fix token price (#1300) --- apps/namadillo/src/atoms/balance/atoms.ts | 73 +++++++------------ apps/namadillo/src/atoms/balance/functions.ts | 28 +++---- apps/namadillo/src/atoms/balance/services.ts | 10 ++- 3 files changed, 43 insertions(+), 68 deletions(-) diff --git a/apps/namadillo/src/atoms/balance/atoms.ts b/apps/namadillo/src/atoms/balance/atoms.ts index e78d23460..9138caf71 100644 --- a/apps/namadillo/src/atoms/balance/atoms.ts +++ b/apps/namadillo/src/atoms/balance/atoms.ts @@ -1,4 +1,3 @@ -import { Asset } from "@chain-registry/types"; import { accountsAtom, defaultAccountAtom, @@ -10,11 +9,10 @@ import { tokenAddressesAtom, } from "atoms/chain"; import { shouldUpdateBalanceAtom } from "atoms/etc"; -import { availableAssetsAtom } from "atoms/integrations"; import { queryDependentFn } from "atoms/utils"; import BigNumber from "bignumber.js"; +import * as osmosis from "chain-registry/mainnet/osmosis"; import { atomWithQuery } from "jotai-tanstack-query"; -import { namadaAsset } from "registry/namadaAsset"; import { AddressWithAsset } from "types"; import { findAssetByToken, @@ -82,37 +80,11 @@ export const shieldedBalanceAtom = atomWithQuery< }; }); -export const assetByAddressAtom = atomWithQuery((get) => { - const tokenAddressesQuery = get(tokenAddressesAtom); - const namTokenAddressQuery = get(nativeTokenAddressAtom); - const availableAssets = get(availableAssetsAtom); - - return { - queryKey: [ - "asset-by-address", - tokenAddressesQuery.data, - namTokenAddressQuery.data, - ], - queryFn: () => { - const assetByAddress: Record = {}; - if (namTokenAddressQuery.data) { - assetByAddress[namTokenAddressQuery.data] = namadaAsset; - } - tokenAddressesQuery.data?.forEach((token) => { - const asset = findAssetByToken(token, availableAssets); - if (asset) { - assetByAddress[token.address] = asset; - } - }); - return assetByAddress; - }, - }; -}); - export const tokenPricesAtom = atomWithQuery((get) => { const shieldedBalanceQuery = get(shieldedBalanceAtom); const transparentBalanceQuery = get(transparentBalanceAtom); - const assetByAddressQuery = get(assetByAddressAtom); + const namTokenAddressQuery = get(nativeTokenAddressAtom); + const tokenAddressesQuery = get(tokenAddressesAtom); // Get the list of addresses that exists on balances const obj: Record = {}; @@ -123,32 +95,37 @@ export const tokenPricesAtom = atomWithQuery((get) => { obj[address] = true; }); const addresses = Object.keys(obj); + const namAddress = namTokenAddressQuery.data; + const tokens = tokenAddressesQuery.data; return { - queryKey: ["token-prices", addresses, assetByAddressQuery.data], + queryKey: ["token-prices", addresses, tokens, namAddress], queryFn: async () => { - const addressByBase: Record = {}; + const baseMap: Record = {}; addresses.forEach((address) => { - const base = assetByAddressQuery.data?.[address]?.base; - if (base) { - addressByBase[base] = address; + const token = tokens?.find((t) => t.address === address); + if (token) { + const asset = findAssetByToken(token, osmosis.assets); + if (asset) { + baseMap[asset.base] = address; + } } }); - const assetBaseList = Object.keys(addressByBase); - const apiResponse = - assetBaseList.length ? - await fetchCoinPrices(Object.keys(addressByBase)) - : []; - // TODO mock NAM price - // apiResponse[namadaAsset.base] = { - // "ibc/498A0751C798A0D9A389AA3691123DADA57DAA4FE165D5C75894505B876BA6E4": - // "1.000000000000000000000000000000000000", - // }; + const baseList = Object.keys(baseMap); + const apiResponse = await fetchCoinPrices(baseList); + const tokenPrices: Record = {}; Object.entries(apiResponse).forEach(([base, value]) => { - const address = addressByBase[base]; - tokenPrices[address] = new BigNumber(Object.values(value)[0]); + const address = baseMap[base]; + const dollar = Object.values(value)[0]; + if (dollar) { + tokenPrices[address] = new BigNumber(dollar); + } }); + // TODO mock NAM price while it's not available on api + if (namAddress && !tokenPrices[namAddress]) { + tokenPrices[namAddress] = new BigNumber(0); + } return tokenPrices; }, }; diff --git a/apps/namadillo/src/atoms/balance/functions.ts b/apps/namadillo/src/atoms/balance/functions.ts index 81bb30ce1..61d646b68 100644 --- a/apps/namadillo/src/atoms/balance/functions.ts +++ b/apps/namadillo/src/atoms/balance/functions.ts @@ -11,24 +11,20 @@ import { TokenBalance } from "./atoms"; // please refer to `tryCoinToIbcAsset` and how we could combine both export const findAssetByToken = ( token: NativeToken | IbcToken, - chains: AssetList[] + assetList: AssetList ): Asset | undefined => { if ("trace" in token) { - for (let i = 0; i < chains.length; i++) { - for (let j = 0; j < chains[i].assets.length; j++) { - const asset = chains[i].assets[j]; - if (asset.traces) { - for (let k = 0; k < asset.traces.length; k++) { - const trace = asset.traces[k]; - if ( - "chain" in trace && - trace.chain && - "path" in trace.chain && - trace.chain.path === token.trace - ) { - return asset; - } - } + const traceDenom = token.trace.split("/").at(-1); + if (traceDenom) { + for (let i = 0; i < assetList.assets.length; i++) { + const asset = assetList.assets[i]; + if ( + asset.base === traceDenom || + asset.denom_units.find( + (u) => u.denom === traceDenom || u.aliases?.includes(traceDenom) + ) + ) { + return asset; } } } diff --git a/apps/namadillo/src/atoms/balance/services.ts b/apps/namadillo/src/atoms/balance/services.ts index 6c4de90af..3f39abb17 100644 --- a/apps/namadillo/src/atoms/balance/services.ts +++ b/apps/namadillo/src/atoms/balance/services.ts @@ -1,15 +1,17 @@ import { Balance } from "@namada/sdk/web"; import { getSdkInstance } from "utils/sdk"; -const sqsOsmosisApi = "https://sqs.osmosis.zone/"; +const sqsOsmosisApi = "https://sqs.osmosis.zone"; // ref: https://sqs.osmosis.zone/swagger/index.html#/default/get_tokens_prices export const fetchCoinPrices = async ( assetBaseList: string[] ): Promise> => - fetch( - `${sqsOsmosisApi}/tokens/prices?base=${assetBaseList.sort((a, b) => a.localeCompare(b)).join(",")}` - ).then((res) => res.json()); + assetBaseList.length ? + fetch( + `${sqsOsmosisApi}/tokens/prices?base=${assetBaseList.sort((a, b) => a.localeCompare(b)).join(",")}` + ).then((res) => res.json()) + : []; export const fetchShieldedBalance = async ( viewingKey: string,