diff --git a/packages/utils/__tests__/asset-list-util.test.js b/packages/utils/__tests__/asset-list-util.test.js index c1c94cee3..a4940ebc9 100644 --- a/packages/utils/__tests__/asset-list-util.test.js +++ b/packages/utils/__tests__/asset-list-util.test.js @@ -15,39 +15,44 @@ import { } from '../src'; describe('tests for asset-list-util', () => { - let testAssets = []; - - beforeAll(() => { - testAssets = assets.find((it) => it.chain_name === 'osmosis')?.assets || []; - }); - - it('get osmosis asset by denom', () => { - const asset = getAssetByDenom(testAssets, 'uosmo'); - expect(asset.name).toEqual('Osmosis'); + const osmosisAssetList = assets.filter( + ({ chain_name }) => chain_name === 'osmosis' + ); + + it('getAssetByDenom', () => { + expect(() => getAssetByDenom(assets, 'uosmo')).toThrowError(); + const asset = getAssetByDenom(assets, 'uosmo', 'osmosis'); + expect(asset.base).toEqual('uosmo'); }); - it('get osmosis denom by geckoId', () => { - const denom = getDenomByCoinGeckoId(testAssets, 'osmosis'); - expect(denom).toEqual('uosmo'); + it('getDenomByCoinGeckoId', () => { + const denom1 = getDenomByCoinGeckoId(assets, 'jackal'); + expect(denom1).toEqual('ujkl'); + const denom2 = getDenomByCoinGeckoId(assets, 'stargaze', 'stargaze'); + expect(denom2).toEqual('ustars'); }); - it('get osmosis symbol by denom', () => { - const token = getSymbolByChainDenom(testAssets, 'uosmo'); - expect(token).toEqual('OSMO'); + it('getSymbolByChainDenom', () => { + const denom1 = getSymbolByChainDenom(assets, 'swth'); + expect(denom1).toEqual('SWTH'); + const denom2 = getSymbolByChainDenom(assets, 'uusdc', 'axelar'); + expect(denom2).toEqual('USDC'); }); - it('get osmosis denom by symbol', () => { - const denom = getChainDenomBySymbol(testAssets, 'OSMO'); - expect(denom).toEqual('uosmo'); + it('getChainDenomBySymbol', () => { + const denom1 = getChainDenomBySymbol(assets, 'OCTA'); + expect(denom1).toEqual('uocta'); + const denom2 = getChainDenomBySymbol(assets, 'NOM', 'nomic'); + expect(denom2).toEqual('unom'); }); - it('get osmosis exponent by denom', () => { - const exponent = getExponentByDenom(testAssets, 'uosmo'); + it('getExponentByDenom', () => { + const exponent = getExponentByDenom(assets, 'uosmo', 'osmosis'); expect(exponent).toEqual(6); }); - it('convert osmosis gecko price to denom price map', () => { - const priceMap = convertCoinGeckoPricesToDenomPriceMap(testAssets, { + it('convertCoinGeckoPricesToDenomPriceMap', () => { + const priceMap = convertCoinGeckoPricesToDenomPriceMap(osmosisAssetList, { osmosis: { usd: 0.498124 } @@ -55,36 +60,36 @@ describe('tests for asset-list-util', () => { expect(priceMap.uosmo).toEqual(0.498124); }); - it('convert number no decimals', () => { + it('noDecimals', () => { const re1 = noDecimals(1.12); expect(re1).toEqual('1'); const re2 = noDecimals(1.67); expect(re2).toEqual('1'); }); - it('convert osmosis base units to dollar value', () => { - const re = convertBaseUnitsToDollarValue( - testAssets, + it('convertBaseUnitsToDollarValue', () => { + const value = convertBaseUnitsToDollarValue( + osmosisAssetList, { uosmo: 1 }, 'OSMO', 5 ); - expect(re).toEqual('0.000005'); + expect(value).toEqual('0.000005'); }); - it('convert doller value to osmosis denom units', () => { - const re = convertDollarValueToDenomUnits( - testAssets, + it('convertDollarValueToDenomUnits', () => { + const value = convertDollarValueToDenomUnits( + osmosisAssetList, { uosmo: 1 }, 'OSMO', 0.00001 ); - expect(re).toEqual('10'); + expect(value).toEqual('10'); }); - it('convert osmosis base units to display units', () => { - const re = convertBaseUnitsToDisplayUnits(testAssets, 'OSMO', 99); - expect(re).toEqual('0.000099'); + it('convertBaseUnitsToDisplayUnits', () => { + const value = convertBaseUnitsToDisplayUnits(osmosisAssetList, 'OSMO', 99); + expect(value).toEqual('0.000099'); }); }); diff --git a/packages/utils/src/asset-list-util.ts b/packages/utils/src/asset-list-util.ts index cb18995c3..8c518e259 100644 --- a/packages/utils/src/asset-list-util.ts +++ b/packages/utils/src/asset-list-util.ts @@ -13,19 +13,46 @@ export interface PriceHash { [key: CoinDenom]: number; } -export function getAssetByDenom(assets: Asset[], denom: CoinDenom): Asset { - const asset = assets.find((asset) => asset.base === denom); - if (!asset) { - throw new Error(`Asset not found: ${denom}`); +function getAssetByKeyValue( + assets: AssetList[], + key: keyof Asset, + value: string, + chainName?: string +): Asset { + const filteredAssets = assets + .filter(({ chain_name }) => !chainName || chain_name === chainName) + .flatMap(({ assets }) => assets); + + const matchingAssets = filteredAssets.filter((asset) => asset[key] === value); + + if (matchingAssets.length === 0) { + throw new Error(`No asset found for ${key} '${value}'`); + } + + if (matchingAssets.length > 1) { + throw new Error( + `Ambiguity: ${matchingAssets.length} assets found for ${key} '${value}'` + ); } - return asset; + + return matchingAssets[0]; +} + +export function getAssetByDenom( + assets: AssetList[], + denom: CoinDenom, + chainName?: string +): Asset { + return getAssetByKeyValue(assets, 'base', denom, chainName); } export function getDenomByCoinGeckoId( - assets: Asset[], - coinGeckoId: string + assets: AssetList[], + coinGeckoId: string, + chainName?: string ): CoinDenom { - return assets.find((asset) => asset.coingecko_id === coinGeckoId).base; + return getAssetByKeyValue(assets, 'coingecko_id', coinGeckoId, chainName) + .base; } type GetCoinGeckoIdByDenomOptions = { @@ -61,44 +88,36 @@ export function getCoinGeckoIdByDenom( } export function getSymbolByChainDenom( - assets: Asset[], - denom: CoinDenom + assets: AssetList[], + denom: CoinDenom, + chainName?: string ): string { - const asset = getAssetByDenom(assets, denom); - const symbol = asset.symbol; - if (!symbol) { - return denom; - } - return symbol; + return getAssetByDenom(assets, denom, chainName).symbol; } export function getChainDenomBySymbol( - assets: Asset[], - token: string + assets: AssetList[], + symbol: string, + chainName?: string ): CoinDenom { - const asset = assets.find(({ symbol }) => symbol === token); - const base = asset?.base; - if (!base) { - console.log(`cannot find base for token ${token}`); - return null; - } - return base; + return getAssetByKeyValue(assets, 'symbol', symbol, chainName).base; } export function getExponentByDenom( - assets: Asset[], - denom: CoinDenom + assets: AssetList[], + denom: CoinDenom, + chainName?: string ): Exponent { - const asset = getAssetByDenom(assets, denom); + const asset = getAssetByDenom(assets, denom, chainName); const unit = asset.denom_units.find(({ denom }) => denom === asset.display); - return unit?.exponent || 0; + return unit?.exponent ?? 0; } export function convertCoinGeckoPricesToDenomPriceMap( - assets: Asset[], + assets: AssetList[], prices: Record ): PriceHash { - return Object.keys(prices).reduce((res, geckoId) => { + return Object.keys(prices).reduce((res: PriceHash, geckoId) => { const denom = getDenomByCoinGeckoId(assets, geckoId); res[denom] = prices[geckoId].usd; return res; @@ -110,7 +129,7 @@ export function noDecimals(num: number | string): string { } export function convertBaseUnitsToDollarValue( - assets: Asset[], + assets: AssetList[], prices: PriceHash, symbol: string, amount: string | number @@ -123,7 +142,7 @@ export function convertBaseUnitsToDollarValue( } export function convertDollarValueToDenomUnits( - assets: Asset[], + assets: AssetList[], prices: PriceHash, symbol: string, value: string | number @@ -136,7 +155,7 @@ export function convertDollarValueToDenomUnits( } export function convertBaseUnitsToDisplayUnits( - assets: Asset[], + assets: AssetList[], symbol: string, amount: string | number ): string {