From e03c627f0b84eb3f37c8fa6dfb1282e400c5918b Mon Sep 17 00:00:00 2001 From: Dima Date: Sat, 11 May 2024 19:44:51 +0300 Subject: [PATCH] Feat/hub (#1154) Co-authored-by: dasein --- src/components/Dot/Dot.module.scss | 70 ++++++++ src/components/Dot/Dot.stories.tsx | 23 +++ src/components/Dot/Dot.tsx | 39 +++++ src/components/Row/Row.module.scss | 7 +- src/components/actionBar/index.tsx | 2 +- src/components/index.js | 8 + .../search/Spark/LeftMeta/Creator/Creator.tsx | 4 +- src/components/search/Spark/Spark.tsx | 18 +- src/components/valueImg/imgDenom.tsx | 4 +- src/constants/config.ts | 2 + src/constants/hubContracts.ts | 6 + .../Validators/components/{ui.jsx => ui.tsx} | 63 +++---- .../Header/SwitchAccount/SwitchAccount.tsx | 4 +- src/containers/temple/hooks/getTotalCap.ts | 7 +- src/containers/validator/validatorInfo.tsx | 5 +- src/containers/warp/Warp.tsx | 69 +++++--- src/containers/warp/pool/PoolCard.tsx | 38 ++-- src/containers/warp/utils.ts | 119 +++++-------- src/contexts/hub.tsx | 47 +++++ src/contexts/ibcDenom.tsx | 56 +++--- src/features/ipfs/ipfsSettings/index.tsx | 10 +- src/hooks/useGetMarketData.ts | 3 +- src/hooks/useGetTotalSupply.ts | 33 +--- src/hooks/useHub.ts | 59 ++++--- src/index.tsx | 39 +++-- src/layouts/variables.module.scss | 2 +- src/pages/Hub/Layout/Layout.module.scss | 5 + src/pages/Hub/Layout/Layout.tsx | 12 ++ .../DisplayHub/DisplayHub.module.scss | 9 + .../Hub/components/DisplayHub/DisplayHub.tsx | 39 +++++ .../Hub/containers/Channels/Channels.tsx | 26 +++ src/pages/Hub/containers/Channels/map.tsx | 34 ++++ .../Hub/containers/Networks/Networks.tsx | 24 +++ src/pages/Hub/containers/Networks/map.tsx | 42 +++++ src/pages/Hub/containers/Tokens/Tokens.tsx | 24 +++ src/pages/Hub/containers/Tokens/map.tsx | 44 +++++ src/pages/Hub/hub.tsx | 19 ++ src/pages/Hub/redux/hub.ts | 61 +++++++ src/pages/Keys/KeyItem/KeyItem.module.scss | 8 +- src/pages/Keys/KeyItem/KeyItem.tsx | 147 ++++++++-------- src/pages/Keys/Keys.module.scss | 12 +- src/pages/Keys/Keys.tsx | 42 ++--- src/pages/Settings/Layout/Layout.module.scss | 30 ++++ src/pages/Settings/Layout/Layout.tsx | 20 +++ .../SettingsMenu/SettingsMenu.module.scss | 26 +++ .../Layout/SettingsMenu/SettingsMenu.tsx | 85 +++++++++ src/pages/Settings/Settings.tsx | 20 +++ .../_refactor/account/tabs/feeds.module.scss | 4 + .../robot/_refactor/account/tabs/feeds.tsx | 27 +-- src/redux/reducers/index.ts | 2 + src/router.tsx | 3 + src/routes.ts | 12 +- src/services/soft.js/api/msgs.ts | 4 +- src/types/hub.d.ts | 8 + src/utils/configToken.ts | 165 ------------------ src/utils/tokenList.js | 111 ------------ src/utils/utils.ts | 14 -- 57 files changed, 1122 insertions(+), 694 deletions(-) create mode 100644 src/components/Dot/Dot.module.scss create mode 100644 src/components/Dot/Dot.stories.tsx create mode 100644 src/components/Dot/Dot.tsx rename src/containers/Validators/components/{ui.jsx => ui.tsx} (61%) create mode 100644 src/contexts/hub.tsx create mode 100644 src/pages/Hub/Layout/Layout.module.scss create mode 100644 src/pages/Hub/Layout/Layout.tsx create mode 100644 src/pages/Hub/components/DisplayHub/DisplayHub.module.scss create mode 100644 src/pages/Hub/components/DisplayHub/DisplayHub.tsx create mode 100644 src/pages/Hub/containers/Channels/Channels.tsx create mode 100644 src/pages/Hub/containers/Channels/map.tsx create mode 100644 src/pages/Hub/containers/Networks/Networks.tsx create mode 100644 src/pages/Hub/containers/Networks/map.tsx create mode 100644 src/pages/Hub/containers/Tokens/Tokens.tsx create mode 100644 src/pages/Hub/containers/Tokens/map.tsx create mode 100644 src/pages/Hub/hub.tsx create mode 100644 src/pages/Hub/redux/hub.ts create mode 100644 src/pages/Settings/Layout/Layout.module.scss create mode 100644 src/pages/Settings/Layout/Layout.tsx create mode 100644 src/pages/Settings/Layout/SettingsMenu/SettingsMenu.module.scss create mode 100644 src/pages/Settings/Layout/SettingsMenu/SettingsMenu.tsx create mode 100644 src/pages/Settings/Settings.tsx create mode 100644 src/pages/robot/_refactor/account/tabs/feeds.module.scss delete mode 100644 src/utils/configToken.ts delete mode 100644 src/utils/tokenList.js diff --git a/src/components/Dot/Dot.module.scss b/src/components/Dot/Dot.module.scss new file mode 100644 index 000000000..b003e8805 --- /dev/null +++ b/src/components/Dot/Dot.module.scss @@ -0,0 +1,70 @@ +$animation-time: 2.3s; + +.dot { + --size: 4px; + + display: inline-block; + border-radius: 50%; + opacity: 1; + position: relative; + + width: var(--size); + height: var(--size); + + --color-r: 0; + --color-b: 0; + --color-g: 0; + + &.color_ { + &blue { + --color-r: 31; + --color-b: 203; + --color-g: 225; + } + + &red { + --color-r: 255; + --color-b: 92; + --color-g: 0; + } + + &green { + --color-r: 122; + --color-b: 250; + --color-g: 161; + } + + &purple { + --color-r: 246; + --color-b: 43; + --color-g: 253; + } + + &yellow { + --color-r: 255; + --color-g: 0; + --color-b: 217; + } + } + + background-color: rgb(var(--color-r), var(--color-b), var(--color-g)); +} + +.animation { + transition: all 1s; + + animation: pulse $animation-time infinite alternate; +} + +@keyframes pulse { + 0% { + box-shadow: 0px 0px 0px 0px rgb(var(--color-r), + var(--color-b), + var(--color-g)); + opacity: 0.2; + } + + 100% { + box-shadow: 0px 0px 10px 2px rgb(var(--color-r), var(--color-b), var(--color-g)); + } +} \ No newline at end of file diff --git a/src/components/Dot/Dot.stories.tsx b/src/components/Dot/Dot.stories.tsx new file mode 100644 index 000000000..574f7fd29 --- /dev/null +++ b/src/components/Dot/Dot.stories.tsx @@ -0,0 +1,23 @@ +import { Meta, StoryObj } from '@storybook/react'; +import Dot from './Dot'; + +const meta: Meta = { + component: Dot, + title: 'atoms/Dot', + parameters: { + design: { + type: 'figma', + url: '', + }, + }, +}; +export default meta; + +type Story = StoryObj; + +export const Main: Story = { + args: { + color: 'green', + animation: true, + }, +}; diff --git a/src/components/Dot/Dot.tsx b/src/components/Dot/Dot.tsx new file mode 100644 index 000000000..8689fe80c --- /dev/null +++ b/src/components/Dot/Dot.tsx @@ -0,0 +1,39 @@ +import cx from 'classnames'; +import { useEffect, useRef } from 'react'; +import styles from './Dot.module.scss'; + +export enum DotColors { + blue = 'blue', + green = 'green', + red = 'red', + purple = 'purple', + yellow = 'yellow', +} + +type Props = { + color: DotColors | keyof typeof DotColors; + className?: string; + animation?: boolean; + size?: number; +}; + +function Dot({ color, className, animation, size = 4 }: Props) { + const ref = useRef(null); + + useEffect(() => { + if (ref.current) { + ref.current.style.setProperty('--size', `${size}px`); + } + }, [ref, size]); + + return ( + + ); +} + +export default Dot; diff --git a/src/components/Row/Row.module.scss b/src/components/Row/Row.module.scss index 01d17fa11..d5d8ecc1d 100644 --- a/src/components/Row/Row.module.scss +++ b/src/components/Row/Row.module.scss @@ -1,15 +1,16 @@ .container { display: grid; grid-template-columns: 240px 1fr; - align-items: center; + align-items: baseline; line-height: 20px; font-size: 16px; .value { text-transform: none !important; display: flex; - align-items: center; - justify-content: flex-start; + justify-content: center; + align-items: flex-start; + flex-direction: column; } } diff --git a/src/components/actionBar/index.tsx b/src/components/actionBar/index.tsx index 78b7f9567..874ff9f7d 100644 --- a/src/components/actionBar/index.tsx +++ b/src/components/actionBar/index.tsx @@ -62,7 +62,7 @@ function ActionBar({ children, text, onClickBack, button }: Props) { const noPassport = CHAIN_ID === Networks.BOSTROM && !passport; const exception = - (location.pathname !== routes.keys.path && + (!location.pathname.includes('/keys') && !location.pathname.includes('/drive') && // !location.pathname.includes('/oracle') && location.pathname !== '/') || diff --git a/src/components/index.js b/src/components/index.js index ec10dd66e..4368ea0b8 100644 --- a/src/components/index.js +++ b/src/components/index.js @@ -55,6 +55,10 @@ import Slider from './Slider/Slider'; import CreatedAt from './CreatedAt/CreatedAt'; import Tabs from './Tabs/Tabs'; import Row, { RowsContainer } from './Row/Row'; +import Display from './containerGradient/Display/Display'; +import DisplayTitle from './containerGradient/DisplayTitle/DisplayTitle'; +import { Color } from './LinearGradientContainer/LinearGradientContainer'; +import Dot from './Dot/Dot'; const BtnGrd = Button; @@ -108,6 +112,10 @@ export { Tabs, Row, RowsContainer, + Display, + DisplayTitle, + Color, + Dot, }; export { Dots } from './ui/Dots'; diff --git a/src/components/search/Spark/LeftMeta/Creator/Creator.tsx b/src/components/search/Spark/LeftMeta/Creator/Creator.tsx index d6b9c9d83..f58ef919d 100644 --- a/src/components/search/Spark/LeftMeta/Creator/Creator.tsx +++ b/src/components/search/Spark/LeftMeta/Creator/Creator.tsx @@ -6,7 +6,7 @@ import Account from 'src/components/account/account'; import { timeSince } from 'src/utils/utils'; import styles from './Creator.module.scss'; -function Creator({ cid }: { cid: string }) { +function Creator({ cid, onlyTime }: { cid: string; onlyTime?: boolean }) { const { creator } = useGetCreator(cid); if (!creator) { @@ -24,7 +24,7 @@ function Creator({ cid }: { cid: string }) { - + {!onlyTime && } ); } diff --git a/src/components/search/Spark/Spark.tsx b/src/components/search/Spark/Spark.tsx index a0be205ee..a00ab0949 100644 --- a/src/components/search/Spark/Spark.tsx +++ b/src/components/search/Spark/Spark.tsx @@ -14,10 +14,11 @@ import RankButton from './LeftMeta/RankButton/RankButton'; type Props = { cid: string; handleContentType: (type: IpfsContentType) => void; - handleRankClick: (cid: string) => void; + handleRankClick?: (cid: string) => void; itemData: {}; query: string; linkType: LinksType; + selfLinks?: boolean; }; function Spark({ @@ -28,6 +29,7 @@ function Spark({ rankSelected, handleContentType, handleRankClick, + selfLinks, }: Props) { const { isMobile } = useDevice(); const [ref, hovering] = useHover(); @@ -37,12 +39,14 @@ function Spark({ {!isMobile && hovering && ( <>
- - + + {handleRankClick && ( + + )}
{/* TODO: refact. meta should be moved inside contentItem and exclude fetchParticle from that */} diff --git a/src/components/valueImg/imgDenom.tsx b/src/components/valueImg/imgDenom.tsx index 04da97246..cc121d3de 100644 --- a/src/components/valueImg/imgDenom.tsx +++ b/src/components/valueImg/imgDenom.tsx @@ -101,9 +101,9 @@ function ImgDenom({ setTooltipText(path); } } else { - setImgDenom(defaultImg); + setImgDenom(getNativeImg(coinDenom)); } - }, [coinDenom, infoDenom, fetchWithDetails]); + }, [coinDenom, infoDenom, fetchWithDetails, getImgFromIpfsByCid]); const img = ( {children} @@ -26,47 +28,46 @@ export function TextTable({ children, fontSize, color, display, ...props }) { ); } -export function StatusTooltip({ status }) { - let statusColor; +export function StatusTooltip({ + status, + size, + animation, +}: { + status: keyof typeof statusHeroes | number; + size?: number; + animation?: boolean; +}) { + let statusColor: DotColors; + let textTooltip: string; - switch (statusHeroes[status]) { + const switchValue = + typeof status === 'number' ? status : statusHeroes[status]; + + switch (switchValue) { case 1: - statusColor = 'red'; + statusColor = DotColors.red; + textTooltip = 'UNBONDED'; break; case 2: - statusColor = 'yellow'; + statusColor = DotColors.yellow; + textTooltip = 'UNBONDING'; + break; case 3: - statusColor = 'green'; + statusColor = DotColors.green; + textTooltip = 'BONDED'; + break; default: - statusColor = 'neutral'; + statusColor = DotColors.purple; + textTooltip = 'UNSPECIFIED'; break; } return ( - - - Validator status:  - {statusHeroes[status] === 1 && 'unbonded'} - {statusHeroes[status] === 2 && 'unbonding'} - {statusHeroes[status] === 3 && 'bonded'} - - } - > - + + + ); diff --git a/src/containers/application/Header/SwitchAccount/SwitchAccount.tsx b/src/containers/application/Header/SwitchAccount/SwitchAccount.tsx index 48b10007c..914469c27 100644 --- a/src/containers/application/Header/SwitchAccount/SwitchAccount.tsx +++ b/src/containers/application/Header/SwitchAccount/SwitchAccount.tsx @@ -234,9 +234,9 @@ function SwitchAccount() { image={require('../../../../image/sigma.png')} /> diff --git a/src/containers/temple/hooks/getTotalCap.ts b/src/containers/temple/hooks/getTotalCap.ts index 83a147bda..48fedcb7b 100644 --- a/src/containers/temple/hooks/getTotalCap.ts +++ b/src/containers/temple/hooks/getTotalCap.ts @@ -3,11 +3,11 @@ import { useEffect, useState } from 'react'; import { useIbcDenom } from 'src/contexts/ibcDenom'; import { useAppData } from 'src/contexts/appData'; import { - findDenomInTokenList, - getDenomHash, getDisplayAmount, } from '../../../utils/utils'; import { BASE_DENOM } from 'src/constants/config'; +import { ibcDenomAtom } from 'src/pages/teleport/bridge/bridge'; + function useGetTotalCap() { const { marketData, dataTotalSupply } = useAppData(); @@ -85,9 +85,6 @@ function useGetTotalCap() { useEffect(() => { if (Object.keys(marketData).length > 0) { - const denomInfo = findDenomInTokenList('uatom'); - const path = `transfer/${denomInfo.destChannelId}`; - const ibcDenomAtom = getDenomHash(path, denomInfo.coinMinimalDenom); if ( Object.prototype.hasOwnProperty.call(marketData, ibcDenomAtom) && Object.prototype.hasOwnProperty.call(marketData, BASE_DENOM) diff --git a/src/containers/validator/validatorInfo.tsx b/src/containers/validator/validatorInfo.tsx index 0722e4410..e9d3c49ff 100644 --- a/src/containers/validator/validatorInfo.tsx +++ b/src/containers/validator/validatorInfo.tsx @@ -1,9 +1,10 @@ import { Pane } from '@cybercongress/gravity'; -import { Card, StatusTooltip } from '../../components'; +import { Card } from '../../components'; import { formatNumber } from '../../utils/utils'; import KeybaseAvatar from './keybaseAvatar'; import UptimeHook from './UptimeHook'; import Display from 'src/components/containerGradient/Display/Display'; +import { StatusTooltip } from '../Validators/components'; // function Row({ value, title, marginBottom }) { // return ( @@ -75,7 +76,7 @@ function ValidatorInfo({ data }) { - + {website !== undefined ? {moniker} : moniker} diff --git a/src/containers/warp/Warp.tsx b/src/containers/warp/Warp.tsx index a64b19909..29d630b32 100644 --- a/src/containers/warp/Warp.tsx +++ b/src/containers/warp/Warp.tsx @@ -55,6 +55,8 @@ function Warp() { const [tokenBAmount, setTokenBAmount] = useState(''); const [tokenAPoolAmount, setTokenAPoolAmount] = useState(0); const [tokenBPoolAmount, setTokenBPoolAmount] = useState(0); + const [tokenACoinDecimals, setTokenACoinDecimals] = useState(0); + const [tokenBCoinDecimals, setTokenBCoinDecimals] = useState(0); const [selectedPool, setSelectedPool] = useState(undefined); const [isExceeded, setIsExceeded] = useState(false); const [isEmptyPool, setIsEmptyPool] = useState(false); @@ -100,6 +102,16 @@ function Warp() { setAdviser(text); }, [setAdviser, tab]); + useEffect(() => { + const [{ coinDecimals }] = traseDenom(tokenA); + setTokenACoinDecimals(coinDecimals); + }, [traseDenom, tokenA]); + + useEffect(() => { + const [{ coinDecimals }] = traseDenom(tokenB); + setTokenBCoinDecimals(coinDecimals); + }, [traseDenom, tokenB]); + useEffect(() => { if (firstEffectOccured.current) { // eslint-disable-next-line react-hooks/exhaustive-deps @@ -189,9 +201,6 @@ function Warp() { const myATokenBalanceB = getMyTokenBalanceNumber(tokenB, accountBalances); if (accountBalances !== null) { - const [{ coinDecimals: coinDecimalsA }] = tracesDenom(tokenA); - const [{ coinDecimals: coinDecimalsB }] = tracesDenom(tokenB); - const validTokensAB = Object.prototype.hasOwnProperty.call(accountBalances, tokenA) && Object.prototype.hasOwnProperty.call(accountBalances, tokenB) && @@ -199,10 +208,10 @@ function Warp() { accountBalances[tokenB] > 0; const validTokenAmountAB = - parseFloat(getDisplayAmountReverce(tokenAAmount, coinDecimalsA)) <= + parseFloat(getDisplayAmountReverce(tokenAAmount, tokenACoinDecimals)) <= myATokenBalance && Number(tokenAAmount) > 0 && - parseFloat(getDisplayAmountReverce(tokenBAmount, coinDecimalsB)) <= + parseFloat(getDisplayAmountReverce(tokenBAmount, tokenBCoinDecimals)) <= myATokenBalanceB && Number(tokenBAmount) > 0; @@ -231,7 +240,6 @@ function Warp() { } } setIsExceeded(exceeded); - // eslint-disable-next-line react-hooks/exhaustive-deps }, [ accountBalances, tokenA, @@ -240,32 +248,51 @@ function Warp() { tokenAAmount, tokenBAmount, swapPrice, + tokenACoinDecimals, + tokenBCoinDecimals, + isEmptyPool, ]); const amountChangeHandler = useCallback( - (values: string, e: React.ChangeEvent) => { - const inputAmount = values; - + (inputAmount: string, e: React.ChangeEvent) => { + let counterPairValue = new BigNumber(0); const isReverse = e.target.id !== 'tokenAAmount'; - const state = { tokenAPoolAmount, tokenBPoolAmount, tokenB, tokenA }; - let { counterPairAmount } = calculateCounterPairAmount( - inputAmount, - e, - state - ); - counterPairAmount = Math.abs( - parseFloat(Number(counterPairAmount).toFixed(4)) - ); + if (Number(inputAmount) > 0 && tokenAPoolAmount && tokenBPoolAmount) { + const state = { + tokenAPoolAmount, + tokenBPoolAmount, + tokenA, + tokenB, + tokenACoinDecimals, + tokenBCoinDecimals, + isReverse, + }; + + const { counterPairAmount } = calculateCounterPairAmount( + inputAmount, + state + ); + + counterPairValue = counterPairAmount; + } + if (isReverse) { setTokenBAmount(new BigNumber(inputAmount).toNumber()); - setTokenAAmount(counterPairAmount); + setTokenAAmount(counterPairValue.toString(10)); } else { setTokenAAmount(new BigNumber(inputAmount).toNumber()); - setTokenBAmount(counterPairAmount); + setTokenBAmount(counterPairValue.toString(10)); } }, - [tokenAPoolAmount, tokenBPoolAmount, tokenB, tokenA] + [ + tokenAPoolAmount, + tokenBPoolAmount, + tokenB, + tokenA, + tokenACoinDecimals, + tokenBCoinDecimals, + ] ); const amountChangeHandlerCreatePool = useCallback( diff --git a/src/containers/warp/pool/PoolCard.tsx b/src/containers/warp/pool/PoolCard.tsx index 63afd64ec..ed22e6ec0 100644 --- a/src/containers/warp/pool/PoolCard.tsx +++ b/src/containers/warp/pool/PoolCard.tsx @@ -2,10 +2,9 @@ import { useMemo, useState, useEffect } from 'react'; import { v4 as uuidv4 } from 'uuid'; import { Option } from 'src/types'; import { ObjKeyValue } from 'src/types/data'; -import { useIbcDenom } from 'src/contexts/ibcDenom'; import { Coin } from '@cosmjs/launchpad'; -import { ContainerGradient, FormatNumberTokens } from 'src/components'; -import tokenList from '../../../utils/tokenList'; +import { Display, DisplayTitle, FormatNumberTokens } from 'src/components'; +import { useHub } from 'src/contexts/hub'; import { exponentialToDecimal } from '../../../utils/utils'; import PoolItemsList from './pollItems'; import TitlePool from './TitlePoolCard'; @@ -25,7 +24,7 @@ function PoolCard({ accountBalances, vol24, }: PoolCardProps) { - const { tracesDenom } = useIbcDenom(); + const { tokens } = useHub(); const [sharesToken, setSharesToken] = useState(null); @@ -55,17 +54,7 @@ function PoolCard({ if (reserveCoinDenoms && Object.keys(reserveCoinDenoms).length > 0) { reserveCoinDenoms.forEach((itemCoin) => { if (itemCoin.includes('ibc')) { - const [{ denom, path }] = tracesDenom(itemCoin); - const result = tokenList.find((item) => item.denom === denom); - if (result !== undefined) { - const { counterpartyChainId, destChannelId } = result; - const pathFromList = `${counterpartyChainId}/${destChannelId}`; - if (pathFromList !== path) { - status = true; - } - } else { - status = true; - } + status = !Boolean(tokens && tokens[itemCoin]); } }); } @@ -75,15 +64,20 @@ function PoolCard({ console.log('error', error); return false; } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [pool]); + }, [pool, tokens]); return ( - + + } + /> } >
@@ -113,7 +107,7 @@ function PoolCard({
)} -
+ ); } diff --git a/src/containers/warp/utils.ts b/src/containers/warp/utils.ts index c2023bb43..7fb8720b4 100644 --- a/src/containers/warp/utils.ts +++ b/src/containers/warp/utils.ts @@ -2,7 +2,6 @@ import { Pool } from '@cybercongress/cyber-js/build/codec/tendermint/liquidity/v import { ObjKeyValue } from 'src/types/data'; import BigNumber from 'bignumber.js'; import { MyPoolsT } from './type'; -import coinDecimalsConfig from '../../utils/configToken'; const reduceTextCoin = (text: string) => { switch (text) { @@ -60,89 +59,63 @@ export function getMyTokenBalanceNumber(denom: string, indexer) { return Number(getMyTokenBalance(denom, indexer)); } -function pow(a) { - let result = 1; - for (let i = 0; i < a; i++) { - result *= 10; - } - return result; +function pow(coinDecimals) { + return new BigNumber(1).multipliedBy(new BigNumber(10).pow(coinDecimals)); } -const getCoinDecimals = (amount, token: string) => { - let amountReduce = amount; +export function calculateCounterPairAmount(values, state) { + const inputAmount = values; - if (coinDecimalsConfig[token]) { - const { coinDecimals } = coinDecimalsConfig[token]; - if (coinDecimals) { - amountReduce = parseFloat(amount) / pow(coinDecimals); - } - } - return amountReduce; -}; + let counterPairAmount = new BigNumber(0); + let swapPrice = new BigNumber(0); -const getDecimals = (denom) => { - let decimals = 0; - if (coinDecimalsConfig[denom]) { - decimals = coinDecimalsConfig[denom].coinDecimals; - } - return decimals; -}; + const { + tokenAPoolAmount, + tokenBPoolAmount, + tokenA, + tokenB, + tokenACoinDecimals, + tokenBCoinDecimals, + isReverse, + } = state; -const getCounterPairAmount = (amount, decimals, swapPrice) => { - const inputAmountBN = new BigNumber(amount); - return inputAmountBN - .dividedBy(swapPrice) - .dp(decimals, BigNumber.ROUND_FLOOR) - .toNumber(); -}; + const poolAmountA = new BigNumber(tokenAPoolAmount); + const poolAmountB = new BigNumber(tokenBPoolAmount); -export function calculateCounterPairAmount(values, e, state) { - const inputAmount = values; + const amount = new BigNumber(inputAmount).multipliedBy( + pow(isReverse ? tokenBCoinDecimals : tokenACoinDecimals) + ); - let counterPairAmount = 0; + const isPoolPair = [tokenA, tokenB].sort()[0] === tokenA; - const { tokenAPoolAmount, tokenA, tokenBPoolAmount, tokenB } = state; + let poolCoins: BigNumber[] = []; - const poolAmountA = new BigNumber( - getCoinDecimals(Number(tokenAPoolAmount), tokenA) - ); - const poolAmountB = new BigNumber( - getCoinDecimals(Number(tokenBPoolAmount), tokenB) - ); + if (isPoolPair) { + poolCoins = [poolAmountA, poolAmountB]; + } else { + poolCoins = [poolAmountB, poolAmountA]; + } - if ( - inputAmount.length > 0 && - poolAmountA.comparedTo(0) > 0 && - poolAmountB.comparedTo(0) > 0 - ) { - let swapPrice = null; - let decimals = 0; - - if (e.target.id === 'tokenAAmount') { - swapPrice = poolAmountA.dividedBy(poolAmountB); - swapPrice = swapPrice.multipliedBy(1.03).toNumber(); - if (tokenB.length > 0) { - decimals = getDecimals(tokenB); - } - counterPairAmount = getCounterPairAmount( - inputAmount, - decimals, - swapPrice - ); - } else { - swapPrice = poolAmountB.dividedBy(poolAmountA); - swapPrice = swapPrice.multipliedBy(0.97).toNumber(); - - if (tokenA.length > 0) { - decimals = getDecimals(tokenA); - } - counterPairAmount = getCounterPairAmount( - inputAmount, - decimals, - swapPrice - ); - } + if ((isPoolPair && !isReverse) || (!isPoolPair && isReverse)) { + swapPrice = poolCoins[1].dividedBy(poolCoins[0]); } + + if ((isPoolPair && isReverse) || (!isPoolPair && !isReverse)) { + swapPrice = poolCoins[0].dividedBy(poolCoins[1]); + } + + if (isReverse) { + counterPairAmount = amount + .multipliedBy(swapPrice.multipliedBy(new BigNumber(1))) + .dividedBy(pow(tokenACoinDecimals)) + .dp(tokenACoinDecimals, BigNumber.ROUND_FLOOR); + } else { + counterPairAmount = amount + .multipliedBy(swapPrice) + .dividedBy(pow(tokenBCoinDecimals)) + .dp(tokenBCoinDecimals, BigNumber.ROUND_FLOOR); + } + return { counterPairAmount, }; diff --git a/src/contexts/hub.tsx b/src/contexts/hub.tsx new file mode 100644 index 000000000..af1794847 --- /dev/null +++ b/src/contexts/hub.tsx @@ -0,0 +1,47 @@ +import React, { useContext, useMemo } from 'react'; +import { useChannels, useNetworks, useTokens } from 'src/hooks/useHub'; +import { Option } from 'src/types'; +import { ObjectKey } from 'src/types/data'; +import { Channel, Network, Token } from 'src/types/hub'; + +type HubProviderContextType = { + channels: Option>; + tokens: Option>; + networks: Option>; +}; + +const valueContext = { + channels: undefined, + tokens: undefined, + networks: undefined, +}; + +const HubProviderContext = + React.createContext(valueContext); + +export function useHub() { + return useContext(HubProviderContext); +} + +function HubProvider({ children }: { children: React.ReactNode }) { + const { networks } = useNetworks(); + const { tokens } = useTokens(); + const { channels } = useChannels(); + + const valueMemo = useMemo( + () => ({ + networks, + tokens, + channels, + }), + [networks, tokens, channels] + ); + + return ( + + {children} + + ); +} + +export default HubProvider; diff --git a/src/contexts/ibcDenom.tsx b/src/contexts/ibcDenom.tsx index 12d9a1334..97500c3a6 100644 --- a/src/contexts/ibcDenom.tsx +++ b/src/contexts/ibcDenom.tsx @@ -6,14 +6,9 @@ import { TracesDenomFuncResponse, TracesDenomFuncType, } from 'src/types/ibc'; -import { - findDenomInTokenList, - findPoolDenomInArr, - isNative, -} from 'src/utils/utils'; -import coinDecimalsConfig from 'src/utils/configToken'; +import { findPoolDenomInArr, isNative } from 'src/utils/utils'; import useAllDenomTraces from 'src/hooks/useAllDenomTraces'; -// import { useTokens } from 'src/hooks/useHub'; +import { useHub } from './hub'; type IbcDenomContextContextType = { ibcDenoms: Option; @@ -35,7 +30,7 @@ export function useIbcDenom() { function IbcDenomProvider({ children }: { children: React.ReactNode }) { const poolsData = usePoolListInterval(); const allDenomTraces = useAllDenomTraces(); - // const { tokens } = useTokens(); + const { tokens } = useHub(); const tracesDenom = useCallback( (denomTraces: string): TracesDenomFuncResponse[] => { @@ -47,6 +42,7 @@ function IbcDenomProvider({ children }: { children: React.ReactNode }) { native: true, }; + // pool token is array [denom1, denom2] if (denomTraces.includes('pool') && poolsData) { const findPool = findPoolDenomInArr(denomTraces, poolsData); if (findPool) { @@ -57,15 +53,22 @@ function IbcDenomProvider({ children }: { children: React.ReactNode }) { } } - if (!denomTraces.includes('pool') && coinDecimalsConfig[denomTraces]) { - const { denom, coinDecimals } = coinDecimalsConfig[denomTraces]; - infoDenomTemp.denom = denom; - infoDenomTemp.coinDecimals = coinDecimals || 0; - } else { - infoDenomTemp.denom = denomTraces.toUpperCase(); - } + // check hub contracts + if (tokens && tokens[denomTraces]) { + const { + decimals, + ticker, + logo, + channel_id: channelId, + contract, + } = tokens[denomTraces]; - if ( + infoDenomTemp.denom = ticker; + infoDenomTemp.coinDecimals = parseFloat(decimals); + infoDenomTemp.coinImageCid = contract.includes('ibc') ? logo : ''; + infoDenomTemp.path = channelId; + } else if ( + // response lcd all denom traces !isNative(denomTraces) && allDenomTraces && allDenomTraces[denomTraces] @@ -73,25 +76,16 @@ function IbcDenomProvider({ children }: { children: React.ReactNode }) { const { baseDenom, sourceChannelId: sourceChannelIFromPath } = allDenomTraces[denomTraces]; infoDenomTemp.native = false; - - const denomInfoFromList = findDenomInTokenList(baseDenom); - if (denomInfoFromList) { - const { denom, coinDecimals, coinImageCid, counterpartyChainId } = - denomInfoFromList; - infoDenomTemp.denom = denom; - infoDenomTemp.coinDecimals = coinDecimals; - infoDenomTemp.coinImageCid = coinImageCid || ''; - infoDenomTemp.path = `${counterpartyChainId}/${sourceChannelIFromPath}`; - } else { - infoDenomTemp.denom = baseDenom; - infoDenomTemp.path = sourceChannelIFromPath; - } + infoDenomTemp.denom = baseDenom; + infoDenomTemp.path = sourceChannelIFromPath; + } else { + infoDenomTemp.denom = denomTraces.toUpperCase(); } return [{ ...infoDenomTemp }]; }, - // eslint-disable-next-line react-hooks/exhaustive-deps - [allDenomTraces, poolsData] + + [allDenomTraces, poolsData, tokens] ); const value = useMemo( diff --git a/src/features/ipfs/ipfsSettings/index.tsx b/src/features/ipfs/ipfsSettings/index.tsx index 1e037dbf4..4afcc1341 100644 --- a/src/features/ipfs/ipfsSettings/index.tsx +++ b/src/features/ipfs/ipfsSettings/index.tsx @@ -1,14 +1,15 @@ import { useCallback, useEffect, useState } from 'react'; import { - ContainerGradientText, Input, - ActionBar, Button, + Display, + DisplayTitle, } from 'src/components'; import { Pane } from '@cybercongress/gravity'; import { useAdviser } from 'src/features/adviser/context'; import Select from 'src/containers/warp/components/Select'; +import { AdviserColors } from 'src/features/adviser/Adviser/Adviser'; import BtnPassport from '../../../containers/portal/pasport/btnPasport'; import { updateIpfsStateUrl, @@ -23,7 +24,6 @@ import ComponentLoader from './ipfsComponents/ipfsLoader'; import Drive from '../Drive'; import { useBackend } from 'src/contexts/backend/backend'; import { IPFSNodes } from 'src/services/ipfs/types'; -import { AdviserColors } from 'src/features/adviser/Adviser/Adviser'; const dataOpts = [IPFSNodes.EXTERNAL, IPFSNodes.EMBEDDED, IPFSNodes.HELIA]; @@ -99,7 +99,7 @@ function IpfsSettings() { } return ( - + }>
@@ -198,7 +198,7 @@ function IpfsSettings() { */}
- + ); } diff --git a/src/hooks/useGetMarketData.ts b/src/hooks/useGetMarketData.ts index 3196c7366..383fef612 100644 --- a/src/hooks/useGetMarketData.ts +++ b/src/hooks/useGetMarketData.ts @@ -86,7 +86,8 @@ function useGetMarketData() { const { totalSupplyAll: dataTotalSupply } = useGetTotalSupply({ refetchInterval: 1000 * 60 * 3, }); - const dataPools = usePoolListInterval({ refetchInterval: 1000 * 60 * 3 }); + const dataPools = usePoolListInterval(); + // const dataPools = usePoolListInterval({ refetchInterval: 1000 * 60 * 3 }); useEffect(() => { const marketDataLS = localStorage.getItem('marketData'); diff --git a/src/hooks/useGetTotalSupply.ts b/src/hooks/useGetTotalSupply.ts index 0cd16bf39..cae520cea 100644 --- a/src/hooks/useGetTotalSupply.ts +++ b/src/hooks/useGetTotalSupply.ts @@ -1,16 +1,12 @@ import { useQuery } from '@tanstack/react-query'; import { useEffect, useState } from 'react'; -import { - findDenomInTokenList, - reduceBalances, - isNative, -} from 'src/utils/utils'; +import { reduceBalances, isNative } from 'src/utils/utils'; import { Option } from 'src/types'; import { ObjKeyValue } from 'src/types/data'; import { CyberClient } from '@cybercongress/cyber-js'; import { useQueryClient } from 'src/contexts/queryClient'; -import { useIbcDenom } from 'src/contexts/ibcDenom'; import { BASE_DENOM, DENOM_LIQUID } from 'src/constants/config'; +import { useHub } from 'src/contexts/hub'; type OptionInterval = { refetchInterval?: number | false; @@ -36,7 +32,7 @@ function useGetTotalSupply( option: OptionInterval = { refetchInterval: false } ) { const queryClient = useQueryClient(); - const { ibcDenoms: ibcDataDenom } = useIbcDenom(); + const { tokens } = useHub(); const [totalSupplyAll, setTotalSupplyAll] = useState>(undefined); const [totalSupplyProofList, setTotalSupplyProofList] = @@ -61,27 +57,12 @@ function useGetTotalSupply( const reduceData = {}; - if (ibcDataDenom) { + if (tokens) { Object.keys(datareduceTotalSupply).forEach((key) => { const value = datareduceTotalSupply[key]; if (!isNative(key)) { - if (Object.prototype.hasOwnProperty.call(ibcDataDenom, key)) { - const { baseDenom, sourceChannelId: sourceChannelIFromPath } = - ibcDataDenom[key]; - const denomInfoFromList = findDenomInTokenList(baseDenom); - if (denomInfoFromList) { - if ( - Object.prototype.hasOwnProperty.call( - denomInfoFromList, - 'destChannelId' - ) - ) { - const { destChannelId } = denomInfoFromList; - if (destChannelId === sourceChannelIFromPath) { - reduceData[key] = value; - } - } - } + if (tokens[key]) { + reduceData[key] = value; } } else if (key.indexOf('pool') !== 0) { reduceData[key] = value; @@ -101,7 +82,7 @@ function useGetTotalSupply( }; getTotalSupply(); - }, [ibcDataDenom, dataGetTotalSupply]); + }, [tokens, dataGetTotalSupply]); return { totalSupplyProofList, totalSupplyAll }; } diff --git a/src/hooks/useHub.ts b/src/hooks/useHub.ts index fdce0b780..17a271119 100644 --- a/src/hooks/useHub.ts +++ b/src/hooks/useHub.ts @@ -8,12 +8,17 @@ import { HUB_TOKENS, } from 'src/constants/hubContracts'; import { useQueryClient } from 'src/contexts/queryClient'; +import { setChannels, setNetworks, setTokens } from 'src/pages/Hub/redux/hub'; +import { useAppDispatch, useAppSelector } from 'src/redux/hooks'; import { Option } from 'src/types'; -import { Channel, Network, Token } from 'src/types/hub'; - -type ObjectKey = { - [key: string]: T; -}; +import { + Channel, + ChannelList, + Network, + NetworkList, + Token, + TokenList, +} from 'src/types/hub'; const enum TypeFetcher { NETWORKS = HUB_NETWORKS, @@ -34,9 +39,11 @@ const fetcher = (client: Option, type: TypeFetcher) => { }; export function useNetworks() { + const dispatch = useAppDispatch(); + const { networks: networksStorage } = useAppSelector((state) => state.hub); const queryClient = useQueryClient(); - const [networks, setNetworks] = - useState>>(undefined); + const [networksData, setNetworksData] = + useState>(networksStorage); const { data } = useQuery( ['hub-networks'], () => fetcher(queryClient, TypeFetcher.NETWORKS), @@ -46,23 +53,27 @@ export function useNetworks() { ); useEffect(() => { - const objectMappedResult: ObjectKey = {}; + const objectMappedResult: NetworkList = {}; if (data) { data.entries.forEach((row: Network) => { objectMappedResult[row.chain_id] = row; }); } if (Object.keys(objectMappedResult).length > 0) { - setNetworks(objectMappedResult); + setNetworksData(objectMappedResult); + dispatch(setNetworks(objectMappedResult)); } - }, [data]); + }, [data, dispatch]); - return { networks }; + return { networks: networksData }; } export function useTokens() { + const dispatch = useAppDispatch(); + const { tokens: tokensStorage } = useAppSelector((state) => state.hub); const queryClient = useQueryClient(); - const [tokens, setTokens] = useState>>(undefined); + const [tokensData, setTokensData] = + useState>(tokensStorage); const { data } = useQuery( ['hub-tokens'], () => fetcher(queryClient, TypeFetcher.TOKENS), @@ -72,7 +83,7 @@ export function useTokens() { ); useEffect(() => { - const objectMappedResult: ObjectKey = {}; + const objectMappedResult: TokenList = {}; if (data) { data.entries.forEach((row: Token) => { if (row.chain_id === CHAIN_ID) { @@ -86,18 +97,21 @@ export function useTokens() { }); if (Object.keys(objectMappedResult).length > 0) { - setTokens(objectMappedResult); + setTokensData(objectMappedResult); + dispatch(setTokens(objectMappedResult)); } } - }, [data]); + }, [data, dispatch]); - return { tokens }; + return { tokens: tokensData }; } export function useChannels() { + const dispatch = useAppDispatch(); + const { channels: channelsStorage } = useAppSelector((state) => state.hub); const queryClient = useQueryClient(); - const [channels, setChannels] = - useState>>(undefined); + const [channelsData, setChannelsData] = + useState>(channelsStorage); const { data } = useQuery( ['hub-channels'], () => fetcher(queryClient, TypeFetcher.CHANNELS), @@ -107,7 +121,7 @@ export function useChannels() { ); useEffect(() => { - const objectMappedResult: ObjectKey = {}; + const objectMappedResult: ChannelList = {}; if (data) { data.entries.forEach((row: Channel) => { if (row.active === 'true') { @@ -116,10 +130,11 @@ export function useChannels() { }); if (Object.keys(objectMappedResult).length > 0) { - setChannels(objectMappedResult); + setChannelsData(objectMappedResult); + dispatch(setChannels(objectMappedResult)); } } - }, [data]); + }, [data, dispatch]); - return { channels }; + return { channels: channelsData }; } diff --git a/src/index.tsx b/src/index.tsx index e420ec700..f4c6f9dd9 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -20,6 +20,7 @@ import { getMainDefinition } from '@apollo/client/utilities'; import { QueryClientProvider, QueryClient } from '@tanstack/react-query'; import { ReactQueryDevtools } from '@tanstack/react-query-devtools'; import { Provider } from 'react-redux'; +import { Helmet } from 'react-helmet'; import AppRouter from './router'; import store from './redux/store'; @@ -39,9 +40,9 @@ import DeviceProvider from './contexts/device'; import IbcDenomProvider from './contexts/ibcDenom'; import NetworksProvider from './contexts/networks'; import BackendProvider from './contexts/backend/backend'; - -import { Helmet } from 'react-helmet'; import AdviserProvider from './features/adviser/context'; +import HubProvider from './contexts/hub'; + import { INDEX_HTTPS, INDEX_WEBSOCKET } from './constants/config'; const httpLink = new HttpLink({ @@ -104,22 +105,24 @@ export function Providers({ children }: { children: React.ReactNode }) { - - - - - - - - {/* {children} */} - {children} - - - - - - - + + + + + + + + + {/* {children} */} + {children} + + + + + + + + diff --git a/src/layouts/variables.module.scss b/src/layouts/variables.module.scss index 36ef513a4..567a84833 100644 --- a/src/layouts/variables.module.scss +++ b/src/layouts/variables.module.scss @@ -5,4 +5,4 @@ $adviserOffset: 15px; $reservedTopHeight: $headerHeight + $adviserHeight - $adviserOffset; -$actionBarHeight: 72px; +$actionBarHeight: 102px; diff --git a/src/pages/Hub/Layout/Layout.module.scss b/src/pages/Hub/Layout/Layout.module.scss new file mode 100644 index 000000000..13d9d4b92 --- /dev/null +++ b/src/pages/Hub/Layout/Layout.module.scss @@ -0,0 +1,5 @@ +.container { + & * { + text-transform: none !important; + } +} \ No newline at end of file diff --git a/src/pages/Hub/Layout/Layout.tsx b/src/pages/Hub/Layout/Layout.tsx new file mode 100644 index 000000000..c03fa6a6a --- /dev/null +++ b/src/pages/Hub/Layout/Layout.tsx @@ -0,0 +1,12 @@ +import { Outlet } from 'react-router-dom'; +import styles from './Layout.module.scss'; + +function Layout() { + return ( +
+ +
+ ); +} + +export default Layout; diff --git a/src/pages/Hub/components/DisplayHub/DisplayHub.module.scss b/src/pages/Hub/components/DisplayHub/DisplayHub.module.scss new file mode 100644 index 000000000..b57cb852f --- /dev/null +++ b/src/pages/Hub/components/DisplayHub/DisplayHub.module.scss @@ -0,0 +1,9 @@ +@import '../../../../style/mixins.scss'; + +.link { + span { + width: 20px; + height: 20px; + @include withShareIcon; + } +} \ No newline at end of file diff --git a/src/pages/Hub/components/DisplayHub/DisplayHub.tsx b/src/pages/Hub/components/DisplayHub/DisplayHub.tsx new file mode 100644 index 000000000..d4e81559e --- /dev/null +++ b/src/pages/Hub/components/DisplayHub/DisplayHub.tsx @@ -0,0 +1,39 @@ +import { ReactNode } from 'react'; +import { Link } from 'react-router-dom'; +import { Display, DisplayTitle } from 'src/components'; +import { HUB_CONTRACTS } from 'src/constants/hubContracts'; +import { routes } from 'src/routes'; +import styles from './DisplayHub.module.scss'; + +type Hub = 'networks' | 'channels' | 'tokens'; + +function DisplayHub({ + title, + children, + type, +}: { + children: ReactNode; + title: Hub; + type: keyof typeof HUB_CONTRACTS; +}) { + return ( + + hub {title} + + } + /> + } + > + {children} + + ); +} + +export default DisplayHub; diff --git a/src/pages/Hub/containers/Channels/Channels.tsx b/src/pages/Hub/containers/Channels/Channels.tsx new file mode 100644 index 000000000..4afb0b1e2 --- /dev/null +++ b/src/pages/Hub/containers/Channels/Channels.tsx @@ -0,0 +1,26 @@ +import { useHub } from 'src/contexts/hub'; +import { entityToDto } from 'src/utils/dto'; +import Table from 'src/components/Table/Table'; +import { useMemo } from 'react'; +import DisplayHub from '../../components/DisplayHub/DisplayHub'; +import renderColumnsData from './map'; + +function Channels() { + const { channels } = useHub(); + + const dataRow = channels + ? Object.keys(channels).map((key) => entityToDto(channels[key])) + : []; + + const columnsData = useMemo(() => { + return renderColumnsData(); + }, []); + + return ( + + + + ); +} + +export default Channels; diff --git a/src/pages/Hub/containers/Channels/map.tsx b/src/pages/Hub/containers/Channels/map.tsx new file mode 100644 index 000000000..cc016f4ae --- /dev/null +++ b/src/pages/Hub/containers/Channels/map.tsx @@ -0,0 +1,34 @@ +import { createColumnHelper } from '@tanstack/react-table'; +import { Dot } from 'src/components'; +import { EntityToDto } from 'src/types/dto'; +import { Channel } from 'src/types/hub'; + +const columnHelper = createColumnHelper>(); + +const renderColumnsData = () => { + return [ + columnHelper.accessor('id', { + header: 'id', + }), + columnHelper.accessor('active', { + header: 'active', + cell: (info) => ( + + ), + }), + columnHelper.accessor('destinationChainId', { + header: 'destination chain id', + }), + columnHelper.accessor('destinationChannelId', { + header: 'destination channel id', + }), + columnHelper.accessor('sourceChainId', { + header: 'source chain id', + }), + columnHelper.accessor('sourceChannelId', { + header: 'source channel id', + }), + ]; +}; + +export default renderColumnsData; diff --git a/src/pages/Hub/containers/Networks/Networks.tsx b/src/pages/Hub/containers/Networks/Networks.tsx new file mode 100644 index 000000000..05679545a --- /dev/null +++ b/src/pages/Hub/containers/Networks/Networks.tsx @@ -0,0 +1,24 @@ +import { useHub } from 'src/contexts/hub'; +import Table from 'src/components/Table/Table'; +import { useMemo } from 'react'; +import { entityToDto } from 'src/utils/dto'; +import DisplayHub from '../../components/DisplayHub/DisplayHub'; +import renderColumnsData from './map'; + +function Networks() { + const { networks } = useHub(); + + const dataRow = networks + ? Object.keys(networks).map((key) => entityToDto(networks[key])) + : []; + + const columnsData = useMemo(() => renderColumnsData(), []); + + return ( + +
+ + ); +} + +export default Networks; diff --git a/src/pages/Hub/containers/Networks/map.tsx b/src/pages/Hub/containers/Networks/map.tsx new file mode 100644 index 000000000..1e512f7bd --- /dev/null +++ b/src/pages/Hub/containers/Networks/map.tsx @@ -0,0 +1,42 @@ +import { createColumnHelper } from '@tanstack/react-table'; +import { Cid } from 'src/components'; +import ImgDenom from 'src/components/valueImg/imgDenom'; +import { EntityToDto } from 'src/types/dto'; +import { Network } from 'src/types/hub'; +import { trimString } from 'src/utils/utils'; + +const columnHelper = createColumnHelper>(); + +const renderColumnsData = () => [ + columnHelper.accessor('id', { + header: 'id', + }), + columnHelper.accessor('chainId', { + header: 'chainId', + }), + columnHelper.accessor('name', { + header: 'name', + }), + columnHelper.accessor('logo', { + header: 'logo', + cell: (logo) => ( + + ), + }), + columnHelper.accessor('genesisHash', { + header: 'genesis hash', + cell: (value) => { + const cid = value.getValue(); + return {trimString(cid, 6, 6)}; + }, + }), + columnHelper.accessor('prefix', { + header: 'prefix', + }), +]; + +export default renderColumnsData; diff --git a/src/pages/Hub/containers/Tokens/Tokens.tsx b/src/pages/Hub/containers/Tokens/Tokens.tsx new file mode 100644 index 000000000..74472c6de --- /dev/null +++ b/src/pages/Hub/containers/Tokens/Tokens.tsx @@ -0,0 +1,24 @@ +import { useMemo } from 'react'; +import Table from 'src/components/Table/Table'; +import { useHub } from 'src/contexts/hub'; +import { entityToDto } from 'src/utils/dto'; +import DisplayHub from '../../components/DisplayHub/DisplayHub'; +import renderColumns from './map'; + +function Tokens() { + const { tokens } = useHub(); + + const dataRow = tokens + ? Object.keys(tokens).map((key) => entityToDto(tokens[key])) + : []; + + const columnsData = useMemo(() => renderColumns(), []); + + return ( + +
+ + ); +} + +export default Tokens; diff --git a/src/pages/Hub/containers/Tokens/map.tsx b/src/pages/Hub/containers/Tokens/map.tsx new file mode 100644 index 000000000..35b2cb778 --- /dev/null +++ b/src/pages/Hub/containers/Tokens/map.tsx @@ -0,0 +1,44 @@ +import { createColumnHelper } from '@tanstack/react-table'; +import ImgDenom from 'src/components/valueImg/imgDenom'; +import { EntityToDto } from 'src/types/dto'; +import { Token } from 'src/types/hub'; +import { trimString } from 'src/utils/utils'; + +const columnHelper = createColumnHelper>(); + +const renderColumns = () => [ + columnHelper.accessor('id', { + header: 'id', + }), + columnHelper.accessor('contract', { + header: 'contract', + cell: (info) => { + const denom = info.getValue(); + return denom.includes('ibc') ? trimString(denom, 9, 6) : denom; + }, + }), + columnHelper.accessor('channelId', { + header: 'channel id', + }), + columnHelper.accessor('ticker', { + header: 'ticker', + }), + columnHelper.accessor('logo', { + header: 'logo', + cell: (logo) => ( + + ), + }), + columnHelper.accessor('decimals', { + header: 'decimals', + }), + columnHelper.accessor('chainId', { + header: 'chain id', + }), +]; + +export default renderColumns; diff --git a/src/pages/Hub/hub.tsx b/src/pages/Hub/hub.tsx new file mode 100644 index 000000000..462ecb254 --- /dev/null +++ b/src/pages/Hub/hub.tsx @@ -0,0 +1,19 @@ +import { Route, Routes } from 'react-router-dom'; +import Tokens from './containers/Tokens/Tokens'; +import Layout from './Layout/Layout'; +import Networks from './containers/Networks/Networks'; +import Channels from './containers/Channels/Channels'; + +function Hub() { + return ( + + }> + } /> + } /> + } /> + + + ); +} + +export default Hub; diff --git a/src/pages/Hub/redux/hub.ts b/src/pages/Hub/redux/hub.ts new file mode 100644 index 000000000..b80c90095 --- /dev/null +++ b/src/pages/Hub/redux/hub.ts @@ -0,0 +1,61 @@ +import { PayloadAction, createSlice } from '@reduxjs/toolkit'; +import { Option } from 'src/types'; +import { NetworkList, ChannelList, TokenList } from 'src/types/hub'; + +const enum Hub { + channels = 'channels', + tokens = 'tokens', + networks = 'networks', +} + +type SliceState = { + [Hub.channels]: Option; + [Hub.tokens]: Option; + [Hub.networks]: Option; +}; + +const keyLS = (key: Hub) => `hub-${key}`; + +function getItem(key: Hub) { + const poolsGetItem = localStorage.getItem(keyLS(key)); + + return poolsGetItem ? JSON.parse(poolsGetItem) : undefined; +} + +function saveToLocalStorage(key: Hub, state: SliceState) { + const data = state[key]; + + localStorage.setItem(keyLS(key), JSON.stringify(data)); +} + +const initialState: SliceState = { + [Hub.channels]: getItem(Hub.channels), + [Hub.tokens]: getItem(Hub.tokens), + [Hub.networks]: getItem(Hub.networks), +}; + +const slice = createSlice({ + name: 'hub', + initialState, + reducers: { + setTokens: (state, { payload }: PayloadAction) => { + state[Hub.tokens] = payload; + + saveToLocalStorage(Hub.tokens, state); + }, + setNetworks: (state, { payload }: PayloadAction) => { + state[Hub.networks] = payload; + + saveToLocalStorage(Hub.networks, state); + }, + setChannels: (state, { payload }: PayloadAction) => { + state[Hub.channels] = payload; + + saveToLocalStorage(Hub.channels, state); + }, + }, +}); + +export const { setTokens, setNetworks, setChannels } = slice.actions; + +export default slice.reducer; diff --git a/src/pages/Keys/KeyItem/KeyItem.module.scss b/src/pages/Keys/KeyItem/KeyItem.module.scss index 439d30f0b..2ccb17192 100644 --- a/src/pages/Keys/KeyItem/KeyItem.module.scss +++ b/src/pages/Keys/KeyItem/KeyItem.module.scss @@ -5,8 +5,10 @@ gap: 0 28px; overflow-x: auto; align-items: center; + position: relative; + min-height: 230px; - > img { + >img { height: auto; } @@ -23,7 +25,7 @@ .content { line-height: 30px; - > * { + >* { line-height: initial; } @@ -68,4 +70,4 @@ .passportMain { color: var(--green-light); } -} +} \ No newline at end of file diff --git a/src/pages/Keys/KeyItem/KeyItem.tsx b/src/pages/Keys/KeyItem/KeyItem.tsx index 0dbd8d19b..d7db3693b 100644 --- a/src/pages/Keys/KeyItem/KeyItem.tsx +++ b/src/pages/Keys/KeyItem/KeyItem.tsx @@ -90,83 +90,78 @@ function KeyItem({ account, selected, selectKey }: Props) { } return ( - -
selectKey(bech32)} - > -
- - - {isActive && ( - - )} -
- -
- key
- {['keplr'].includes(keys) && ( - <> - signed by {' '} - - )} - {isHardware && ( - <> - stored in - - )}{' '} - {path && ( - <> - and located at the path
- - )} - from neuron } />
- gives{' '} - {' '} - access - {(passportsLoading || - passportIds.data?.tokens.length || - activePassport.data) && ( - <> - {' '} - to avatars:
- - )} - {passportsLoading && } - {(activePassport.data || !!passportIds.data?.tokens?.length) && ( -
- {activePassport.data && - renderPassportPill(activePassport.data, true)} - {passportIds.data?.tokens?.map((tokenId) => { - return ( - { - if ( - activePassport.data && - equals( - activePassport.data.extension, - passport.extension - ) - ) { - return null; - } - return renderPassportPill(passport); - }} - /> - ); - })} -
- )} -
+
selectKey(bech32)} + > +
+ + + {isActive && ( + + )} +
+ +
+ key
+ {['keplr'].includes(keys) && ( + <> + signed by {' '} + + )} + {isHardware && ( + <> + stored in + + )}{' '} + {path && ( + <> + and located at the path
+ + )} + from neuron } />
+ gives{' '} + {' '} + access + {(passportsLoading || + passportIds.data?.tokens.length || + activePassport.data) && ( + <> + {' '} + to avatars:
+ + )} + {passportsLoading && } + {(activePassport.data || !!passportIds.data?.tokens?.length) && ( +
+ {activePassport.data && + renderPassportPill(activePassport.data, true)} + {passportIds.data?.tokens?.map((tokenId) => { + return ( + { + if ( + activePassport.data && + equals(activePassport.data.extension, passport.extension) + ) { + return null; + } + return renderPassportPill(passport); + }} + /> + ); + })} +
+ )}
- +
); } diff --git a/src/pages/Keys/Keys.module.scss b/src/pages/Keys/Keys.module.scss index 664eede17..d1a72df87 100644 --- a/src/pages/Keys/Keys.module.scss +++ b/src/pages/Keys/Keys.module.scss @@ -1,17 +1,15 @@ .wrapper { - display: flex; - flex-direction: column; - width: 62%; - margin: 0 auto; - padding-bottom: 130px; + display: grid; + align-content: flex-start; + width: 100%; gap: 20px; min-height: 70vh; - > p { + >p { margin: auto; position: relative; top: 65px; text-align: center; line-height: 26px; } -} +} \ No newline at end of file diff --git a/src/pages/Keys/Keys.tsx b/src/pages/Keys/Keys.tsx index 9f4a35cf7..21a31cb39 100644 --- a/src/pages/Keys/Keys.tsx +++ b/src/pages/Keys/Keys.tsx @@ -1,7 +1,7 @@ import { useDispatch, useSelector } from 'react-redux'; import { RootState } from 'src/redux/store'; import KeyItem from './KeyItem/KeyItem'; -import { MainContainer } from 'src/components'; +import { Display, DisplayTitle, MainContainer } from 'src/components'; import ActionBar from 'src/pages/Keys/ActionBar/actionBar'; import { initPocket } from 'src/redux/features/pocket'; import styles from './Keys.module.scss'; @@ -23,25 +23,27 @@ function Keys() { return ( <> -
- {bostromAccounts && bostromAccounts.length > 0 ? ( - bostromAccounts.map(({ cyber: account }) => { - return ( - - ); - }) - ) : ( -

- you have no keys added yet
- add your first key by connecting your wallet -

- )} -
+ }> +
+ {bostromAccounts && bostromAccounts.length > 0 ? ( + bostromAccounts.map(({ cyber: account }) => { + return ( + + ); + }) + ) : ( +

+ you have no keys added yet
+ add your first key by connecting your wallet +

+ )} +
+
div>div { + height: 100%; + } + + > :first-child { + >div { + // don't understand this scroll + overflow-x: hidden; + } + } + + > :nth-child(2) { + left: -2px; + position: relative; + overflow-x: auto; + } + +} \ No newline at end of file diff --git a/src/pages/Settings/Layout/Layout.tsx b/src/pages/Settings/Layout/Layout.tsx new file mode 100644 index 000000000..a333f150d --- /dev/null +++ b/src/pages/Settings/Layout/Layout.tsx @@ -0,0 +1,20 @@ +import { Outlet } from 'react-router-dom'; +import { Helmet } from 'react-helmet'; +import SettingsMenu from './SettingsMenu/SettingsMenu'; +import styles from './Layout.module.scss'; + +function Layout() { + return ( +
+ + setting | cyb + + + + + +
+ ); +} + +export default Layout; diff --git a/src/pages/Settings/Layout/SettingsMenu/SettingsMenu.module.scss b/src/pages/Settings/Layout/SettingsMenu/SettingsMenu.module.scss new file mode 100644 index 000000000..a45eafbae --- /dev/null +++ b/src/pages/Settings/Layout/SettingsMenu/SettingsMenu.module.scss @@ -0,0 +1,26 @@ +.wrapper { + width: 200px; + + .links { + display: grid; + gap: 25px; + } + + a { + display: flex; + gap: 15px; + line-height: 32px; + + .text { + color: var(--grayscale-primary); + } + + &:hover, + &.active { + .text { + color: var(--primary-color); + } + + } + } +} \ No newline at end of file diff --git a/src/pages/Settings/Layout/SettingsMenu/SettingsMenu.tsx b/src/pages/Settings/Layout/SettingsMenu/SettingsMenu.tsx new file mode 100644 index 000000000..bdbb69cb9 --- /dev/null +++ b/src/pages/Settings/Layout/SettingsMenu/SettingsMenu.tsx @@ -0,0 +1,85 @@ +import { NavLink } from 'react-router-dom'; +import cx from 'classnames'; +import styles from './SettingsMenu.module.scss'; +import { Display } from 'src/components'; + +type MenuItem = { + text: string; + link: string; + icon: string; +}; + +const links: Array = [ + [ + { + text: 'Drive', + link: '.', + icon: '🟥', + }, + ], + [ + { + text: 'Keys', + link: './keys', + icon: '🗝', + }, + ], + [ + { + text: 'Tokens', + link: './tokens', + icon: '🟢', + }, + { + text: 'Networks', + link: './networks', + icon: '🌐', + }, + { + text: 'Channels', + link: './channels', + icon: '📡', + }, + ], +]; + +function SettingsMenu() { + const renderLinks = (links: Array) => { + return ( +
+ {links.map((link, indexUl) => { + return ( +
    + {link.map((item, index) => { + return ( +
  • + { + return cx({ + [styles.active]: isActive, + }); + }} + to={item.link} + end + > + {item.icon} + {item.text} + +
  • + ); + })} +
+ ); + })} +
+ ); + }; + + return ( +
+ {renderLinks(links)} +
+ ); +} + +export default SettingsMenu; diff --git a/src/pages/Settings/Settings.tsx b/src/pages/Settings/Settings.tsx new file mode 100644 index 000000000..f1530282f --- /dev/null +++ b/src/pages/Settings/Settings.tsx @@ -0,0 +1,20 @@ +import { Route, Routes } from 'react-router-dom'; +import IpfsSettings from 'src/features/ipfs/ipfsSettings'; +import Layout from './Layout/Layout'; +import Keys from '../Keys/Keys'; +import Hub from '../Hub/hub'; + +function Settings() { + return ( + + }> + } /> + } /> + + } /> + + + ); +} + +export default Settings; diff --git a/src/pages/robot/_refactor/account/tabs/feeds.module.scss b/src/pages/robot/_refactor/account/tabs/feeds.module.scss new file mode 100644 index 000000000..16973a21d --- /dev/null +++ b/src/pages/robot/_refactor/account/tabs/feeds.module.scss @@ -0,0 +1,4 @@ +.containerLogRows { + display: grid; + justify-content: center; +} \ No newline at end of file diff --git a/src/pages/robot/_refactor/account/tabs/feeds.tsx b/src/pages/robot/_refactor/account/tabs/feeds.tsx index b72d0c69d..0c8c4c1c8 100644 --- a/src/pages/robot/_refactor/account/tabs/feeds.tsx +++ b/src/pages/robot/_refactor/account/tabs/feeds.tsx @@ -1,12 +1,13 @@ import { useEffect, useMemo } from 'react'; -import { ContainerGradientText } from 'src/components/containerGradient/ContainerGradient'; import { useRobotContext } from 'src/pages/robot/robot.context'; import { useAdviser } from 'src/features/adviser/context'; import Loader2 from 'src/components/ui/Loader2'; import InfiniteScroll from 'react-infinite-scroll-component'; -import { Dots, NoItems, SearchSnippet } from '../../../../../components'; -import useGetLog from '../hooks/useGetLog'; +import Spark from 'src/components/search/Spark/Spark'; import { RegistryTypes } from 'src/services/soft.js/types'; +import { Display, NoItems } from '../../../../../components'; +import useGetLog from '../hooks/useGetLog'; +import styles from './feeds.module.scss'; function FeedsTab() { const { address, addRefetch } = useRobotContext(); @@ -32,8 +33,6 @@ function FeedsTab() { }; }, [setAdviser, error]); - const onClickRank = () => {}; - const logRows = useMemo(() => { return data.map((item, i) => { // add txs types @@ -53,14 +52,7 @@ function FeedsTab() { return null; } - return ( - - ); + return ; }); }, [data]); @@ -82,6 +74,7 @@ function FeedsTab() { hasMore={Boolean(hasNextPage)} next={fetchNextPage} loader={} + className={styles.containerLogRows} > {logRows} @@ -90,13 +83,7 @@ function FeedsTab() { content = ; } - return ( - -
- {content} -
-
- ); + return {content}; } export default FeedsTab; diff --git a/src/redux/reducers/index.ts b/src/redux/reducers/index.ts index 86b6aa97a..260dc108c 100644 --- a/src/redux/reducers/index.ts +++ b/src/redux/reducers/index.ts @@ -10,6 +10,7 @@ import backendReducer from './backend'; import senseReducer from '../../features/sense/redux/sense.redux'; import warpReducer from '../features/warp'; import ibcDenomReducer from '../features/ibcDenom'; +import hubReducer from '../../pages/Hub/redux/hub'; const rootReducer = { gol: golReducer, @@ -22,6 +23,7 @@ const rootReducer = { sense: senseReducer, warp: warpReducer, ibcDenom: ibcDenomReducer, + hub: hubReducer, }; export default rootReducer; diff --git a/src/router.tsx b/src/router.tsx index 5e15a634e..2f035169e 100644 --- a/src/router.tsx +++ b/src/router.tsx @@ -55,6 +55,7 @@ import Learn from './pages/oracle/Learn/Learn'; import ToOracleAsk from './pages/redirects/ToOracleAsk'; import Social from './pages/Social/Social'; import Brain from './pages/Brain/Brain'; +import Settings from './pages/Settings/Settings'; type WrappedRouterProps = { children: React.ReactNode; @@ -212,6 +213,8 @@ function AppRouter() { } /> + } /> + } /> {/* works as 404 also */} diff --git a/src/routes.ts b/src/routes.ts index aef761687..c9fd9ec01 100644 --- a/src/routes.ts +++ b/src/routes.ts @@ -68,7 +68,7 @@ export const routes = { }, }, keys: { - path: '/keys', + path: '/settings/keys', }, sigma: { path: '/sigma', @@ -97,6 +97,13 @@ export const routes = { path: '/tx/:hash', getLink: (hash: string) => `/network/bostrom/tx/${hash}`, }, + contracts: { + path: '/contracts', + byAddress: { + path: '/contracts/:contractAddress', + getLink: (contractAddress: string) => `/contracts/${contractAddress}`, + }, + }, blocks: { path: '/blocks', getLink: () => `/network/bostrom/blocks`, @@ -105,4 +112,7 @@ export const routes = { getLink: (idBlock: string) => `/network/bostrom/blocks/${idBlock}`, }, }, + settings: { + path: '/settings', + }, }; diff --git a/src/services/soft.js/api/msgs.ts b/src/services/soft.js/api/msgs.ts index c9e913b0b..6f44eba88 100644 --- a/src/services/soft.js/api/msgs.ts +++ b/src/services/soft.js/api/msgs.ts @@ -10,10 +10,10 @@ import { DEFAULT_GAS_LIMITS, BASE_DENOM, DENOM_LIQUID, + COIN_DECIMALS_RESOURCE, } from 'src/constants/config'; import { calculatePairAmount } from 'src/pages/teleport/swap/utils'; import { ObjKeyValue } from 'src/types/data'; -import coinDecimalsConfig from 'src/utils/configToken'; import { authAccounts } from 'src/utils/search/utils'; import { reduceBalances } from 'src/utils/utils'; @@ -23,7 +23,7 @@ const coinFunc = (amount: number, denom: string): Coin => { const checkDenom = (denom: string) => { if (denom === 'millivolt' || denom === 'milliampere') { - return coinDecimalsConfig[denom].coinDecimals; + return COIN_DECIMALS_RESOURCE; } return 0; diff --git a/src/types/hub.d.ts b/src/types/hub.d.ts index c66f803d0..dc61b289b 100644 --- a/src/types/hub.d.ts +++ b/src/types/hub.d.ts @@ -1,3 +1,5 @@ +import { ObjectKey } from './data'; + export type Channel = { id: number; active: 'true' | 'false'; @@ -31,3 +33,9 @@ export type Network = { logo: string; particle: string; }; + +export type TokenList = ObjectKey; + +export type NetworkList = ObjectKey; + +export type ChannelList = ObjectKey; diff --git a/src/utils/configToken.ts b/src/utils/configToken.ts deleted file mode 100644 index c26cdaf59..000000000 --- a/src/utils/configToken.ts +++ /dev/null @@ -1,165 +0,0 @@ -const coinDecimalsConfig: { [key: string]: { denom: string; coinDecimals?: number } } = { - 'ibc/13B2C536BB057AC79D5616B8EA1B9540EC1F2170718CAFF6F0083C966FFFED0B': { - chainId: 'osmosis-1', - coinDecimals: 6, - denom: 'OSMO', - coinMinimalDenom: 'uosmo', - rpc: 'https://rpc.osmosis-1.bronbro.io', - prefix: 'osmo', - sourceChannelId: 'channel-95', - destChannelId: 'channel-2', - }, - 'ibc/15E9C5CF5969080539DB395FA7D9C0868265217EFC528433671AAF9B1912D159': { - chainId: 'cosmoshub-4', - coinDecimals: 6, - denom: 'ATOM', - coinMinimalDenom: 'uatom', - rpc: 'https://rpc.cosmoshub-4.cybernode.ai/', - prefix: 'cosmos', - sourceChannelId: 'channel-341', - destChannelId: 'channel-8', - }, - 'ibc/43DB7553C43D81CB01E9A2644B49A241314B482C2E56F86E85A6539C60383151': { - chainId: 'space-pussy', - coinDecimals: 0, - denom: 'PUSSY', - coinMinimalDenom: 'pussy', - rpc: 'https://rpc.space-pussy.cybernode.ai/', - prefix: 'pussy', - sourceChannelId: 'channel-0', - destChannelId: 'channel-11', - }, - 'ibc/32C4CC556FB73E889DF1A7836A29951F1087525240FF9EEF6AEB616A83C6C9AC': { - chainId: 'chihuahua-1', - coinDecimals: 6, - denom: 'HUAHUA', - coinMinimalDenom: 'uhuahua', - rpc: 'https://rpc.chihuahua.wtf', - sourceChannelId: 'channel-0', - destChannelId: 'channel-11', - }, - 'ibc/8D9262E35CAE362FA74AE05E430550757CF8D842EC1B241F645D3CB7179AFD10': { - chainId: 'juno-1', - coinDecimals: 6, - denom: 'JUNO', - coinMinimalDenom: 'ujuno', - rpc: 'https://rpc-juno.itastakers.com', - sourceChannelId: 'channel-93', - destChannelId: 'channel-10', - }, - 'ibc/C23D820C5B6009E544AFC8AF5A2FEC288108AEDBFAEFDBBDD6BE54CC23069559': { - chainId: 'gravity-bridge-3', - coinDecimals: 6, - denom: 'GRAV', - coinMinimalDenom: 'ugraviton', - rpc: 'https://gravitychain.io:26657', - sourceChannelId: 'channel-103', - destChannelId: 'channel-12', - }, - 'ibc/B6CAD3F7469F3FAD18ED2230A6C7B15E654AB2E1B66E1C70879C04FEF874A863': { - chainId: 'gravity-bridge-3', - coinDecimals: 18, - denom: 'gravETH', - coinMinimalDenom: 'gravity0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', - rpc: 'https://gravitychain.io:26657', - sourceChannelId: 'channel-103', - destChannelId: 'channel-12', - }, - 'ibc/4B322204B4F59D770680FE4D7A565DDC3F37BFF035474B717476C66A4F83DD72': { - chainId: 'evmos_9001-2', - coinDecimals: 18, - denom: 'EVMOS', - coinMinimalDenom: 'aevmos', - rpc: 'https://rpc.evmos-9001-2.bronbro.io', - sourceChannelId: 'channel-19', - destChannelId: 'channel-9', - }, - pool70D7610CBA8E94B27BAD7806EBD826F5626C486BBF5C490D1463D72314353C66: { - denom: ['boot', 'hydrogen'], - }, - pool27BBCA67F42ED27DFFB6A450966C7EA206ADAA42BA0A1871FADC6C59569F6E8D: { - denom: ['boot', 'milliampere'], - }, - pool5D83035BE0E7AB904379161D3C52FB4C1C392265AC19CE39A864146198610628: { - denom: ['boot', 'tocyb'], - }, - poolB02CE42B202A71419D2F9EB4996B36C52F1B5B60DAF7D7B1474660A95656C126: { - denom: ['hydrogen', 'tocyb'], - }, - pool79B9E8E233B61B84EA5AE564AB080FC492B4C953A9D8B409F300D9E29716459F: { - denom: ['hydrogen', 'milliampere'], - }, - poolE479A51F998E2979F89DA9AB897ED45A9AFE4E7DE32BE3D30FB456E58F80D4E9: { - denom: ['hydrogen', 'millivolt'], - }, - pool98692450C039BDD30563475A7699A7805075F592A36837A04357F20B0D59C90F: { - denom: [ - 'hydrogen', - 'ibc/13B2C536BB057AC79D5616B8EA1B9540EC1F2170718CAFF6F0083C966FFFED0B', - ], - }, - poolDA191D1EBA3F4074C2CAB12777FC388216EED222F570548DC3C7D3848D5BE37E: { - denom: [ - 'hydrogen', - 'ibc/BA313C4A19DFBF943586C0387E6B11286F9E416B4DD27574E6909CABE0E342FA', - ], - }, - pool590D4E176871842968705C246DA60E0A57EA41F9257CC7125C8C137C157CC5FA: { - denom: [ - 'ibc/13B2C536BB057AC79D5616B8EA1B9540EC1F2170718CAFF6F0083C966FFFED0B', - 'ibc/BA313C4A19DFBF943586C0387E6B11286F9E416B4DD27574E6909CABE0E342FA', - ], - }, - pool906F3CC4C0F4634031990DB81761BD390890F8A8A80460EBDC6B151254DE7D1D: { - denom: ['milliampere', 'millivolt'], - }, - pool1A492174015ABA47066C8569AFF7582C551980840AAE7EBAEFB667347EDDB601: { - denom: ['boot', 'millivolt'], - }, - pool5D5734E54F485FBAF21DF886EC396F2CBC72203BF050BDE0F99EB94EA37D39E8: { - denom: [ - 'hydrogen', - 'ibc/15E9C5CF5969080539DB395FA7D9C0868265217EFC528433671AAF9B1912D159', - ], - }, - milliampere: { - coinDecimals: 3, - denom: 'A', - coinMinimalDenom: 'milliampere', - }, - hydrogen: { - coinDecimals: 0, - denom: 'H', - coinMinimalDenom: 'hydrogen', - }, - liquidpussy: { - coinDecimals: 0, - denom: 'LP', - coinMinimalDenom: 'liquidpussy', - }, - millivolt: { - coinDecimals: 3, - denom: 'V', - coinMinimalDenom: 'millivolt', - }, - uosmo: { - coinDecimals: 6, - }, - uatom: { - coinDecimals: 6, - }, - ugraviton: { - coinDecimals: 6, - }, - ujuno: { - coinDecimals: 6, - }, - uhuahua: { - coinDecimals: 6, - }, - aevmos: { - coinDecimals: 18, - }, -}; - -export default coinDecimalsConfig; diff --git a/src/utils/tokenList.js b/src/utils/tokenList.js deleted file mode 100644 index 9bae50c51..000000000 --- a/src/utils/tokenList.js +++ /dev/null @@ -1,111 +0,0 @@ -const tokenList = [ - { - coinMinimalDenom: 'uatom', - counterpartyChainId: 'cosmoshub-4', - sourceChannelId: 'channel-341', - destChannelId: 'channel-8', - coinDecimals: 6, - denom: 'ATOM', - coinImageCid: 'Qme1ZkS181jykkBYfvyNqUtRGEm7oCv96n6uo9wrFrMrwN', - }, - { - coinMinimalDenom: 'ujuno', - counterpartyChainId: 'juno-1', - sourceChannelId: 'channel-93', - destChannelId: 'channel-10', - coinDecimals: 6, - denom: 'JUNO', - coinImageCid: 'QmW3ePrLoTFQd7SqbKSZyiV429VBrXpvAYS5Xa4Nt1kVYe', - }, - { - coinMinimalDenom: 'ugraviton', - counterpartyChainId: 'gravity-bridge-3', - sourceChannelId: 'channel-103', - destChannelId: 'channel-12', - coinDecimals: 6, - denom: 'GRAV', - coinImageCid: 'QmQdHDccKswnYjBUML5j3m78NdZWmJ2BTPwMqrGeD73cRQ', - }, - { - coinMinimalDenom: 'gravity0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', - counterpartyChainId: 'gravity-bridge-3', - sourceChannelId: 'channel-103', - destChannelId: 'channel-12', - coinDecimals: 18, - denom: 'grav.ETH', - coinImageCid: 'Qmf4ByG3Z6ptN7EMDEVNukzXNAEZLwzyo4FM6WNJ1rciYA', - }, - { - coinMinimalDenom: 'pussy', - counterpartyChainId: 'space-pussy', - sourceChannelId: 'channel-0', - destChannelId: 'channel-11', - coinDecimals: 0, - denom: 'PUSSY', - coinImageCid: 'QmSdVMzpY9nuHZXZpvZdFbhhMf3nBGAe4JZ7e2Xdh6LMLr', - }, - { - coinMinimalDenom: 'uosmo', - counterpartyChainId: 'osmosis-1', - sourceChannelId: 'channel-95', - destChannelId: 'channel-2', - coinDecimals: 6, - denom: 'OSMO', - coinImageCid: 'QmbS1fKYo9Kxx6g2NwfqABbjKSVcNiRE4wAPYjvak2AZbN', - }, - { - coinMinimalDenom: 'udsm', - counterpartyChainId: 'desmos-mainnet', - sourceChannelId: 'channel-6', - destChannelId: 'channel-13', - coinDecimals: 6, - denom: 'DSM', - coinImageCid: 'QmUmhmyiQfYgJFWjMQF6W8GGvtjAF9YwcTLwnjijDFhmVP', - }, - { - coinMinimalDenom: 'uhuahua', - counterpartyChainId: 'chihuahua-1', - sourceChannelId: 'channel-95', - destChannelId: 'channel-12', - coinDecimals: 6, - denom: 'HUAHUA', - coinImageCid: 'QmdmPzgP3sps9Qbc23VsoaBjBR9cVegonHapTBpN96tjmh', - }, - { - coinMinimalDenom: 'aevmos', - counterpartyChainId: 'evmos_9001-2', - sourceChannelId: 'channel-19', - destChannelId: 'channel-9', - coinDecimals: 18, - denom: 'EVMOS', - coinImageCid: 'QmXhPaHEpLakqEvhY36bzt3ffi9HheF8haPNdbf8RKJbko', - }, - { - coinDecimals: 3, - denom: 'A', - coinMinimalDenom: 'milliampere', - counterpartyChainId: 'bostrom', - }, - { - coinDecimals: 0, - denom: 'H', - coinMinimalDenom: 'hydrogen', - counterpartyChainId: 'bostrom', - }, - { - coinDecimals: 0, - denom: 'LP', - coinMinimalDenom: 'liquidpussy', - counterpartyChainId: 'space-pussy', - sourceChannelId: 'channel-0', - destChannelId: 'channel-11', - }, - { - coinDecimals: 3, - denom: 'V', - coinMinimalDenom: 'millivolt', - counterpartyChainId: 'bostrom', - }, -]; - -export default tokenList; diff --git a/src/utils/utils.ts b/src/utils/utils.ts index f16b63917..8efd610af 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -10,7 +10,6 @@ import { Key } from '@keplr-wallet/types'; import { AccountValue } from 'src/types/defaultAccount'; import { BECH32_PREFIX, BECH32_PREFIX_VAL_CONS } from 'src/constants/config'; import { LEDGER } from './config'; -import tokenList from './tokenList'; import cyberSpace from '../image/large-purple-circle.png'; import customNetwork from '../image/large-orange-circle.png'; @@ -376,18 +375,6 @@ function isNative(denom) { return true; } -const findDenomInTokenList = (baseDenom) => { - let demonInfo; - - const findObj = tokenList.find((item) => item.coinMinimalDenom === baseDenom); - - if (findObj) { - demonInfo = { ...findObj }; - } - - return demonInfo; -}; - const findPoolDenomInArr = ( baseDenom: string, dataPools: Pool[] @@ -449,7 +436,6 @@ export { getDisplayAmountReverce, convertAmount, convertAmountReverce, - findDenomInTokenList, isNative, findPoolDenomInArr, getNowUtcTime,