diff --git a/examples/asset-list/hooks/useChainUtils.ts b/examples/asset-list/hooks/useChainUtils.ts index 03b102046..0fbfbec64 100644 --- a/examples/asset-list/hooks/useChainUtils.ts +++ b/examples/asset-list/hooks/useChainUtils.ts @@ -1,16 +1,10 @@ -import { useManager } from '@cosmos-kit/react'; import { useMemo } from 'react'; import { Asset, AssetList } from '@chain-registry/types'; import { asset_lists as ibcAssetLists } from '@chain-registry/assets'; -import { assets as chainAssets, ibc } from 'chain-registry'; -import { CoinDenom, CoinSymbol, Exponent, PriceHash } from '../utils/types'; -import BigNumber from 'bignumber.js'; -import { Coin } from '@cosmjs/amino'; +import { assets as chainAssets } from 'chain-registry'; import { PrettyAsset } from '../components'; -import { ChainName } from 'cosmos-kit'; export const useChainUtils = (chainName: string) => { - const { getChainRecord } = useManager(); const filterAssets = (assetList: AssetList[]): Asset[] => { return ( @@ -20,7 +14,7 @@ export const useChainUtils = (chainName: string) => { ); }; - const { nativeAssets, ibcAssets } = useMemo(() => { + const { nativeAssets } = useMemo(() => { // @ts-ignore const nativeAssets = filterAssets(chainAssets); // @ts-ignore @@ -30,131 +24,11 @@ export const useChainUtils = (chainName: string) => { // eslint-disable-next-line react-hooks/exhaustive-deps }, [chainName]); - const allAssets = [...nativeAssets, ...ibcAssets]; - - const getIbcAssetsLength = () => { - return ibcAssets.length; - }; - - const getAssetByDenom = (denom: CoinDenom): Asset => { - return allAssets.find((asset) => asset.base === denom) as Asset; - }; - - const denomToSymbol = (denom: CoinDenom): CoinSymbol => { - const asset = getAssetByDenom(denom); - const symbol = asset?.symbol; - if (!symbol) { - return denom; - } - return symbol; - }; - - const symbolToDenom = (symbol: CoinSymbol): CoinDenom => { - const asset = allAssets.find((asset) => asset.symbol === symbol); - const base = asset?.base; - if (!base) { - return symbol; - } - return base; - }; - - const getExponentByDenom = (denom: CoinDenom): Exponent => { - const asset = getAssetByDenom(denom); - const unit = asset.denom_units.find(({ denom }) => denom === asset.display); - return unit?.exponent || 0; - }; - - const convRawToDispAmount = (symbol: string, amount: string | number) => { - const denom = symbolToDenom(symbol); - return new BigNumber(amount) - .shiftedBy(-getExponentByDenom(denom)) - .toString(); - }; - - const calcCoinDollarValue = (prices: PriceHash, coin: Coin) => { - const { denom, amount } = coin; - return new BigNumber(amount) - .shiftedBy(-getExponentByDenom(denom)) - .multipliedBy(prices[denom]) - .toString(); - }; - - const getChainName = (ibcDenom: CoinDenom) => { - if (nativeAssets.find((asset) => asset.base === ibcDenom)) { - return chainName; - } - const asset = ibcAssets.find((asset) => asset.base === ibcDenom); - const ibcChainName = asset?.traces?.[0].counterparty.chain_name; - if (!ibcChainName) throw Error('chainName not found: ' + ibcDenom); - return ibcChainName; - }; - - const getPrettyChainName = (ibcDenom: CoinDenom) => { - const chainName = getChainName(ibcDenom); - try { - const chainRecord = getChainRecord(chainName); - // @ts-ignore - return chainRecord.chain.pretty_name; - } catch (e) { - return 'CHAIN_INFO_NOT_FOUND' - } - }; - const isNativeAsset = ({ denom }: PrettyAsset) => { return !!nativeAssets.find((asset) => asset.base === denom); }; - const getNativeDenom = (chainName: ChainName) => { - const chainRecord = getChainRecord(chainName); - const denom = chainRecord.assetList?.assets[0].base; - if (!denom) throw Error('denom not found'); - return denom; - }; - - const getIbcInfo = (fromChainName: string, toChainName: string) => { - let flipped = false; - - let ibcInfo = ibc.find( - (i) => - i.chain_1.chain_name === fromChainName && - i.chain_2.chain_name === toChainName - ); - - if (!ibcInfo) { - ibcInfo = ibc.find( - (i) => - i.chain_1.chain_name === toChainName && - i.chain_2.chain_name === fromChainName - ); - flipped = true; - } - - if (!ibcInfo) { - throw new Error('cannot find IBC info'); - } - - const key = flipped ? 'chain_2' : 'chain_1'; - const sourcePort = ibcInfo.channels[0][key].port_id; - const sourceChannel = ibcInfo.channels[0][key].channel_id; - - return { sourcePort, sourceChannel }; - }; - return { - allAssets, - nativeAssets, - ibcAssets, - getAssetByDenom, - denomToSymbol, - symbolToDenom, - convRawToDispAmount, - calcCoinDollarValue, - getIbcAssetsLength, - getChainName, - getPrettyChainName, isNativeAsset, - getNativeDenom, - getIbcInfo, - getExponentByDenom, }; }; diff --git a/examples/asset-list/utils/assets.ts b/examples/asset-list/utils/assets.ts deleted file mode 100644 index 4ce93bf00..000000000 --- a/examples/asset-list/utils/assets.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { asset_list, assets } from "@chain-registry/osmosis"; -import { Asset as OsmosisAsset } from "@chain-registry/types"; - -// @ts-ignore -export const osmosisAssets: OsmosisAsset[] = [ - ...assets.assets, - ...asset_list.assets, -]; diff --git a/examples/asset-list/utils/base.ts b/examples/asset-list/utils/base.ts deleted file mode 100644 index 856413cda..000000000 --- a/examples/asset-list/utils/base.ts +++ /dev/null @@ -1,96 +0,0 @@ -import { osmosisAssets } from './assets'; -import { - CoinGeckoToken, - CoinDenom, - Exponent, - CoinSymbol, - PriceHash, - CoinGeckoUSDResponse, -} from './types'; -import { Asset as OsmosisAsset } from '@chain-registry/types'; -import BigNumber from 'bignumber.js'; - -export const getOsmoAssetByDenom = (denom: CoinDenom): OsmosisAsset => { - return osmosisAssets.find((asset) => asset.base === denom) as OsmosisAsset; -}; - -export const getDenomForCoinGeckoId = ( - coinGeckoId: CoinGeckoToken -): CoinDenom => { - // @ts-ignore - return osmosisAssets.find((asset) => asset.coingecko_id === coinGeckoId).base; -}; - -export const osmoDenomToSymbol = (denom: CoinDenom): CoinSymbol => { - const asset = getOsmoAssetByDenom(denom); - const symbol = asset?.symbol; - if (!symbol) { - return denom; - } - return symbol; -}; - -export const symbolToOsmoDenom = (token: CoinSymbol): CoinDenom => { - const asset = osmosisAssets.find(({ symbol }) => symbol === token); - const base = asset?.base; - if (!base) { - console.log(`cannot find base for token ${token}`); - // @ts-ignore - return null; - } - return base; -}; - -export const getExponentByDenom = (denom: CoinDenom): Exponent => { - const asset = getOsmoAssetByDenom(denom); - const unit = asset.denom_units.find(({ denom }) => denom === asset.display); - // @ts-ignore - return unit.exponent; -}; - -export const convertGeckoPricesToDenomPriceHash = ( - prices: CoinGeckoUSDResponse -): PriceHash => { - return Object.keys(prices).reduce((res, geckoId) => { - const denom = getDenomForCoinGeckoId(geckoId); - // @ts-ignore - res[denom] = prices[geckoId].usd; - return res; - }, {}); -}; - -export const noDecimals = (num: number | string) => { - return new BigNumber(num).decimalPlaces(0, BigNumber.ROUND_DOWN).toString(); -}; - -export const baseUnitsToDollarValue = ( - prices: PriceHash, - symbol: string, - amount: string | number -) => { - const denom = symbolToOsmoDenom(symbol); - return new BigNumber(amount) - .shiftedBy(-getExponentByDenom(denom)) - .multipliedBy(prices[denom]) - .toString(); -}; - -export const dollarValueToDenomUnits = ( - prices: PriceHash, - symbol: string, - value: string | number -) => { - const denom = symbolToOsmoDenom(symbol); - return new BigNumber(value) - .dividedBy(prices[denom]) - .shiftedBy(getExponentByDenom(denom)) - .toString(); -}; - -export const baseUnitsToDisplayUnits = ( - symbol: string, - amount: string | number -) => { - const denom = symbolToOsmoDenom(symbol); - return new BigNumber(amount).shiftedBy(-getExponentByDenom(denom)).toString(); -}; diff --git a/examples/asset-list/utils/index.ts b/examples/asset-list/utils/index.ts index fce1c34ac..16c5b2b50 100644 --- a/examples/asset-list/utils/index.ts +++ b/examples/asset-list/utils/index.ts @@ -1,4 +1 @@ -export * from './pool'; -export * from './base'; -export * from './assets'; export * from './format'; diff --git a/examples/asset-list/utils/pool.ts b/examples/asset-list/utils/pool.ts deleted file mode 100644 index 0d5114402..000000000 --- a/examples/asset-list/utils/pool.ts +++ /dev/null @@ -1,279 +0,0 @@ -import { Pool } from 'osmo-query/dist/codegen/osmosis/gamm/pool-models/balancer/balancerPool'; -import { Coin } from 'osmo-query/dist/codegen/cosmos/base/v1beta1/coin'; -import { - PriceHash, - CoinValue, - PoolPretty, - CoinBalance, - PoolAssetPretty, - PrettyPair, -} from './types'; -import BigNumber from 'bignumber.js'; -import { osmosisAssets } from './assets'; -import { - baseUnitsToDisplayUnits, - baseUnitsToDollarValue, - dollarValueToDenomUnits, - getExponentByDenom, - osmoDenomToSymbol, - noDecimals, - getOsmoAssetByDenom, -} from './base'; - -export const calcPoolLiquidity = (pool: Pool, prices: PriceHash): string => { - return pool.poolAssets - .reduce((res, { token }) => { - const liquidity = new BigNumber(token.amount) - .shiftedBy(-getExponentByDenom(token.denom)) - .multipliedBy(prices[token.denom]); - return res.plus(liquidity); - }, new BigNumber(0)) - .toString(); -}; - -export const getPoolByGammName = (pools: Pool[], gammId: string): Pool => { - return pools.find(({ totalShares: { denom } }) => denom === gammId) as Pool; -}; - -export const convertGammTokenToDollarValue = ( - coin: Coin, - pool: Pool, - prices: PriceHash -): string => { - const { amount } = coin; - const liquidity = calcPoolLiquidity(pool, prices); - - return new BigNumber(liquidity) - .multipliedBy(amount) - .dividedBy(pool.totalShares!.amount) - .toString(); -}; - -export const convertDollarValueToCoins = ( - value: string | number, - pool: Pool, - prices: PriceHash -): CoinValue[] => { - const tokens = pool.poolAssets.map(({ token: { denom }, weight }) => { - const ratio = new BigNumber(weight).dividedBy(pool.totalWeight); - const valueByRatio = new BigNumber(value).multipliedBy(ratio); - const displayAmount = valueByRatio.dividedBy(prices[denom]).toString(); - const amount = new BigNumber(displayAmount) - .shiftedBy(getExponentByDenom(denom)) - .toString(); - const symbol = osmoDenomToSymbol(denom); - - return { - denom, - symbol, - amount, - displayAmount, - value: valueByRatio.toString(), - }; - }); - return tokens; -}; - -export const convertDollarValueToShares = ( - value: string | number, - pool: Pool, - prices: PriceHash -) => { - const liquidity = calcPoolLiquidity(pool, prices); - - return new BigNumber(value) - .multipliedBy(pool.totalShares.amount) - .dividedBy(liquidity) - .shiftedBy(-18) - .toString(); -}; - -const assetHashMap = osmosisAssets.reduce((res, asset) => { - return { ...res, [asset.base]: asset }; -}, {}); - -export const prettyPool = ( - pool: Pool, - { includeDetails = false } = {} -): PoolPretty => { - const totalWeight = new BigNumber(pool.totalWeight); - const tokens = pool.poolAssets.map(({ token, weight }) => { - // @ts-ignore - const asset = assetHashMap?.[token.denom]; - const symbol = asset?.symbol ?? token.denom; - const ratio = new BigNumber(weight).dividedBy(totalWeight).toString(); - const obj = { - symbol, - denom: token.denom, - amount: token.amount, - ratio, - info: undefined, - }; - if (includeDetails) { - obj.info = asset; - } - return obj; - }); - const value = { - nickname: tokens.map((t) => t.symbol).join('/'), - images: undefined, - }; - if (includeDetails) { - // @ts-ignore - value.images = tokens - .map((t) => { - // @ts-ignore - const imgs = t?.info?.logo_URIs; - if (imgs) { - return { - token: t.symbol, - images: imgs, - }; - } - }) - .filter(Boolean); - } - // @ts-ignore - return { - ...value, - ...pool, - poolAssetsPretty: tokens, - }; -}; - -export const calcCoinsNeededForValue = ( - prices: PriceHash, - poolInfo: PoolPretty, - value: string | number -) => { - const val = new BigNumber(value); - const coinsNeeded = poolInfo.poolAssetsPretty.map( - ({ symbol, amount, denom, ratio }) => { - const valueByRatio = val.multipliedBy(ratio).toString(); - const amountNeeded = dollarValueToDenomUnits( - prices, - symbol, - valueByRatio - ); - const unitRatio = new BigNumber(amountNeeded) - .dividedBy(amount) - .toString(); - - return { - denom: denom, - symbol: symbol, - amount: noDecimals(amountNeeded), - shareTotalValue: valueByRatio, - displayAmount: baseUnitsToDisplayUnits(symbol, amountNeeded), - totalDollarValue: baseUnitsToDollarValue(prices, symbol, amount), - unitRatio, - }; - } - ); - return coinsNeeded; -}; - -export const getCoinBalance = ( - prices: PriceHash, - balances: Coin[], - prettyAsset: PoolAssetPretty -): CoinBalance => { - const coinBalance = balances.find((coin) => coin.denom == prettyAsset.denom); - - if (!coinBalance || !coinBalance.amount) { - // console.log({ coinBalance }); - // throw new Error("not enough " + prettyAsset.symbol); - // @ts-ignore - return { ...coinBalance, displayValue: 0 }; - } - - const displayValue = baseUnitsToDollarValue( - prices, - prettyAsset.symbol, - coinBalance.amount - ); - - return { ...coinBalance, displayValue }; -}; - -export const calcMaxCoinsForPool = ( - prices: PriceHash, - poolInfo: PoolPretty, - balances: Coin[] -) => { - const smallestTotalDollarValue = poolInfo.poolAssetsPretty - .map((prettyAsset) => { - const { displayValue } = getCoinBalance(prices, balances, prettyAsset); - return new BigNumber(displayValue).dividedBy(prettyAsset.ratio); - }) - .sort((a, b) => a.minus(b).toNumber())[0] - .toString(); - - const coinsNeeded = poolInfo.poolAssetsPretty.map((asset) => { - const coinValue = new BigNumber(smallestTotalDollarValue) - .multipliedBy(asset.ratio) - .toString(); - const amount = dollarValueToDenomUnits(prices, asset.symbol, coinValue); - - return { - denom: asset.denom, - amount: noDecimals(amount), - }; - }); - - return coinsNeeded; -}; - -export const calcShareOutAmount = ( - poolInfo: Pool, - coinsNeeded: Coin[] -): string => { - return poolInfo.poolAssets - .map(({ token }, i) => { - const tokenInAmount = new BigNumber(coinsNeeded[i].amount); - const totalShare = new BigNumber(poolInfo.totalShares.amount); - const totalShareExp = totalShare.shiftedBy(-18); - const poolAssetAmount = new BigNumber(token.amount); - - return tokenInAmount - .multipliedBy(totalShareExp) - .dividedBy(poolAssetAmount) - .shiftedBy(18) - .decimalPlaces(0, BigNumber.ROUND_HALF_UP) - .toString(); - }) - .sort()[0]; -}; - -export const makePoolPairs = (pools: Pool[]): PrettyPair[] => { - // @ts-ignore - return pools - .filter( - (pool) => - pool.poolAssets.length === 2 && - pool.poolAssets.every(({ token }) => !token.denom.startsWith('gamm')) - ) - .map((pool) => { - const assetA = pool.poolAssets[0].token; - const assetAinfo = getOsmoAssetByDenom(assetA.denom); - const assetB = pool.poolAssets[1].token; - const assetBinfo = getOsmoAssetByDenom(assetB.denom); - - if (!assetAinfo || !assetBinfo) return; - - return { - // TODO fix the fact this is seemingly using long - // TODO or, why do we even have pools here??? - // @ts-ignore - poolId: typeof pool.id === 'string' ? pool.id : pool.id.low.toString(), - poolAddress: pool.address, - baseName: assetAinfo.display, - baseSymbol: assetAinfo.symbol, - baseAddress: assetAinfo.base, - quoteName: assetBinfo.display, - quoteSymbol: assetBinfo.symbol, - quoteAddress: assetBinfo.base, - }; - }) - .filter(Boolean); -}; diff --git a/examples/asset-list/utils/types.ts b/examples/asset-list/utils/types.ts deleted file mode 100644 index e1e13eb1c..000000000 --- a/examples/asset-list/utils/types.ts +++ /dev/null @@ -1,85 +0,0 @@ -import { AssetDenomUnit } from '@chain-registry/types'; -import { Duration } from 'osmo-query/dist/codegen/google/protobuf/duration'; -import { Gauge } from 'osmo-query/dist/codegen/osmosis/incentives/gauge'; -import { SuperfluidAsset } from 'osmo-query/dist/codegen/osmosis/superfluid/superfluid'; -import { Coin } from 'osmo-query/dist/codegen/cosmos/base/v1beta1/coin'; -import { Pool } from 'osmo-query/dist/codegen/osmosis/gamm/pool-models/balancer/balancerPool'; - -export type CoinDenom = AssetDenomUnit['denom']; - -export type Exponent = AssetDenomUnit['exponent']; - -export type CoinSymbol = string; - -export interface PriceHash { - [key: CoinDenom]: number; -} - -export type CoinGeckoToken = string; - -export interface CoinGeckoUSD { - usd: number; -} - -export type CoinGeckoUSDResponse = Record; - -export interface CoinValue { - amount: string; - denom: CoinDenom; - displayAmount: string; - value: string; - symbol: CoinSymbol; -} - -export type CoinBalance = Coin & { displayValue: string | number }; - -export interface PoolAssetPretty { - symbol: any; - denom: string; - amount: string; - ratio: string; - info: any; -} - -export interface PoolTokenImage { - token: CoinSymbol; - images: { - png: string; - svg: string; - }; -} - -export interface PoolPretty extends Pool { - nickname: string; - images: PoolTokenImage[] | null; - poolAssetsPretty: PoolAssetPretty[]; -} - -export interface CalcPoolAprsParams { - activeGauges: Gauge[]; - pool: Pool; - prices: PriceHash; - superfluidPools: SuperfluidAsset[]; - aprSuperfluid: string | number; - lockupDurations: Duration[]; - volume7d: string | number; - swapFee: string | number; - lockup?: string; - includeNonPerpetual?: boolean; -} - -export interface Trade { - sell: Coin; - buy: Coin; -} - -export interface PrettyPair { - poolId: string; - poolAddress: string; - baseName: string; - baseSymbol: string; - baseAddress: string; - quoteName: string; - quoteSymbol: string; - quoteAddress: string; -}