From f19b85af9e163035b2dd9b218de92405f57c20ad Mon Sep 17 00:00:00 2001 From: Sen Com <86837735+Sen-Com@users.noreply.github.com> Date: Fri, 20 Jan 2023 17:21:44 +0100 Subject: [PATCH] Release (#148) * fix: lp asset issue on new position form * fix: wrong pool_id handing on manage_liquidity page * fix: lint issue * fix: style issue * fix: style issue * feat: add chain info in url * fix: useQueriesDataSelector hooks * feat: load pools without wallet connection * fix: update logic of onChainChange function * fix: remove duplicated coinhall api call * fix: infinite loop issue on pools page * fix: typo issue of error * fix: update onChainChange function for wallet connect * docs: replace secuirty email contacts * fix: lp asset issue on new position form (#131) * fix: lp asset issue on new position form * fix: wrong pool_id handing on manage_liquidity page * fix: lint issue * fix: style issue * fix: style issue * fix: loading issue on vaults (#128) * feat:add chain info on add_liquidity/manage_liquidity features (#134) * feat: add chain info on manage_liquidity url * feat: add chain info on new_position url * feat: add chain info on new_position url * feat: enhance pool routing with chain info * feat: enhance new_position url with chain info * fix: replace currentChainId with currentChainName * feat: implement swap default tokens * fix: minor lint and style issue * fix: lint and style issue * fix: swapform alignment issue (#135) * fix:flashloan misalignment issue (#136) * fix: misalignment issue of flashloan json editor form * fix: vertical alignment issue * feat: wallet auto connect (#142) * feat: injective integration; Test and mainnet (#121) * feat(inj): Start on inj integration * feat: Add injective testnet chain_info and pools * feat: Injective integration chain and pool; swaps not working yet * fix: Update testnet rpc for now with one that has cors issues * feat: Add other vaults and pools * working simulation on injective * feat: updates for injective client integration; also run prettier * feat:injective poc, frontend not working yet but a tx was done * injective added * fix:inj to cw20 direct * fix: Inj to cw20 direct, cw20 to inj and router txes * fix: fix: multiple messages in post, cw20 swap * feat: Prep for injective mainnet * feat: Injective Mainnet info; swaps working, withdraw lp, balances * fix: Provide and withdraw LP now working * fix: Update DEFAULT_GAS to 2million * fix: Remove injective poc stuff * fix: reduce gas limit * fixed swp rate message and injective catch error * fix few issues listed in slack * fix: Update decimal conversion on provide lp * fix funds issue on LP * clean console and fix banner and loading state * fix depost message on vault * coming soon, coinhall and atom price off fix * fix mange lp cta cutting off * fix flashloan on injective * fix: Update codeowners, there needs to be two * fix: Run prettier to fixup code Co-authored-by: Vinod Hum * feat: add mobile not support modal on mobile devices (#140) * feat: add price field on injective pools (#141) * feat: add price field on injective pools * feat: add dollar sign * feat: load pools without wallet connection * fix: remove duplicated coinhall api call * fix: infinite loop issue on pools page * fix: minor issue * chore: fix codeowners * fix: lp asset issue on new position form (#131) * fix: lp asset issue on new position form * fix: wrong pool_id handing on manage_liquidity page * fix: lint issue * fix: style issue * fix: style issue * feat: add chain info on flash loan page * feat: add chain info on flashloan page * feat: add routes with chain info for swap and flashloan pages * feat: add chain info on vault new_position and manage_position routes * feat: fix lint and style issues * chore: fix lint and style issue * fix: implement dynamic routing from chain change * fix: route redirection issue on vault depositForm * chore: add / in vault routes * fix: vault route redirection issue with chain info * fix: routing issue on vaults/new_position and vaults/manage_position routes * fix: swap routing issue * fix: issue on pools/manage_liquidity route * fix: routing issue * feat: implement automatic wallet connect feature * feat: improve chain auto change feature * fix: routing issue on flashloan page * fix: routing issue * fix: update getPathName function * fix: update pool routing * fix: remove unused code * fix: lint issue * fix: new_position routing issue * fix: vault/new_position routing issue * fix: used code * fix: vaults/manage_position issue * fix: /vaults routing issue * fix: routing issue on pools/manage_liquidity * fix: update wallet auto connect feature * fix: lint issue * fix: default routing issue * fix: add initial disconnect feature * fix: remove unused code * fix: rename inj to injective * fix: update disconnect logic * fix: pool loading issue * fix: swap default token issue on testnet * fix: error for chihuahua testnet * fix: default token issue of new_position feature on testnet * fix: update defaultToknes for new_position * fix: lint issue * fix: cosmwasm client init issue Co-authored-by: 0xFable <86927513+0xFable@users.noreply.github.com> Co-authored-by: Vinod Hum Co-authored-by: sencom * leap integration (#147) * leap integration * fix multiple connect * fix: logic of resetWalletConnection function * fix: conflict and lint issues * fix: price value issue on comdex pools * fix: wallet reconnect issue * fix: error message * fix: wallet connect issue from page reload * fix: redirect issue * fix: remove dollar sign from comdex atom pool * removed pools requted (#153) * fix: leap wallet logo issue * fix: leap wallet logo issue * fix: typo issue on juno-axlUSDC pool * fix: manage_liquidity routing issue * fix: lint issue * fix: add comdex default tokens * fix: remove unused param Co-authored-by: daiki saito Co-authored-by: optisman <42278459+daisai3@users.noreply.github.com> Co-authored-by: 0xFable <86927513+0xFable@users.noreply.github.com> Co-authored-by: Vinod Hum Co-authored-by: Chandra --- components/Layout/RadialGradient.tsx | 4 +- components/Navbar/Navbar.tsx | 72 +++++---- components/Pages/Flashloan/Editor.tsx | 124 +++++++-------- components/Pages/Flashloan/Flashloan.tsx | 17 ++- components/Pages/Flashloan/FlashloanForm.tsx | 22 ++- .../Pages/ManageLiquidity/DepositForm.tsx | 2 +- .../Pages/ManageLiquidity/ManageLiquidity.tsx | 90 ++++++----- components/Pages/NewPosition/NewPosition.tsx | 119 ++++++++++----- .../Pages/NewPosition/NewPositionForm.tsx | 20 +-- .../Pages/NewPosition/defaultTokens.json | 104 ++++++++++--- components/Pages/Pools/AllPoolsTable.tsx | 6 +- components/Pages/Pools/MobilePools.tsx | 85 ++++++----- components/Pages/Pools/MyPoolsTable.tsx | 11 +- components/Pages/Pools/Pools.tsx | 98 +++++++----- .../Pages/Pools/hooks/useIgnoreCoinhall.tsx | 1 + components/Pages/Pools/types/index.ts | 2 +- components/Pages/Swap/Swap.tsx | 101 ++++++++---- components/Pages/Swap/SwapForm.tsx | 11 +- components/Pages/Swap/defaultTokens.json | 144 ++++++++++++------ components/Vaults/AllVaultsTable.tsx | 10 +- .../Vaults/ManagePoistion/DepositForm.tsx | 9 +- .../Vaults/ManagePoistion/ManagePosition.tsx | 23 ++- components/Vaults/MyVaultsTable.tsx | 10 +- components/Vaults/NewPosition.tsx | 34 +++-- components/Vaults/Vaults.tsx | 42 ++--- .../ConnectedWallet/ConnectedWalletIcon.tsx | 9 +- components/Wallet/Modal/LeapConnectButton.tsx | 29 ++++ components/Wallet/Modal/Modal.tsx | 9 +- components/Wallet/Wallet.tsx | 99 +++++++++++- docs/SECURITY | 2 +- .../components/LiquidityBreakdown.tsx | 3 +- .../ManagePoolDialog/ManagePoolDialog.tsx | 3 +- .../UnbondingLiquidityStatusList.tsx | 5 +- features/swap/components/TokenSwapModule.tsx | 3 +- .../swap/components/TransactionAction.tsx | 3 +- features/swap/components/TransactionTips.tsx | 3 +- features/swap/hooks/useTokenSwap.tsx | 7 +- hooks/useBondTokens.ts | 1 + hooks/useChainInfo.ts | 19 ++- hooks/useConnectIBCWallet.ts | 3 +- hooks/useConnectKeplr.tsx | 16 +- hooks/useConnectLeap.tsx | 74 +++++++++ hooks/useCosmwasmClient.ts | 27 ++++ hooks/useDebounceValue.ts | 2 +- hooks/useIBCTokenBalance.tsx | 8 +- hooks/useQueriesDataSelector.ts | 12 +- hooks/useRewardsQueries.ts | 39 ++--- hooks/useSwapInfo.ts | 1 + hooks/useTerraModalOrConnectKeplr.tsx | 10 +- hooks/useTerraStation.tsx | 9 +- hooks/useTokenBalance.tsx | 13 +- hooks/useTokenDollarValue.tsx | 69 ++++----- hooks/useTokenList.ts | 1 + pages/[chainId]/flashloan.tsx | 5 + pages/[chainId]/pools/index.tsx | 5 + pages/[chainId]/pools/manage_liquidity.tsx | 5 + pages/[chainId]/pools/new_position.tsx | 5 + pages/[chainId]/swap.tsx | 14 ++ pages/[chainId]/vaults/index.tsx | 5 + pages/[chainId]/vaults/manage_position.tsx | 5 + pages/[chainId]/vaults/new_position.tsx | 5 + pages/index.tsx | 9 +- public/img/leap-wallet.svg | 17 +++ public/mainnet/chain_info.json | 8 +- public/mainnet/injective-1/pools_list.json | 4 +- public/mainnet/juno-1/pools_list.json | 127 ++------------- public/mainnet/phoenix-1/pools_list.json | 133 ++-------------- public/testnet/chain_info.json | 8 +- queries/querySwapInfo.ts | 1 + queries/useGetTokenDollarValueQuery.ts | 5 +- queries/useQueryPools.ts | 34 +++-- services/injective.ts | 58 ++++--- services/queryClient.ts | 1 + state/atoms/walletAtoms.ts | 5 +- types/window.d.ts | 5 +- util/chain.ts | 15 ++ util/coinhall.ts | 2 +- util/route.ts | 12 ++ util/wallet-adapters/offlineSigningWallet.ts | 34 ++--- 79 files changed, 1302 insertions(+), 865 deletions(-) create mode 100644 components/Wallet/Modal/LeapConnectButton.tsx create mode 100644 hooks/useConnectLeap.tsx create mode 100644 hooks/useCosmwasmClient.ts create mode 100644 pages/[chainId]/flashloan.tsx create mode 100644 pages/[chainId]/pools/index.tsx create mode 100644 pages/[chainId]/pools/manage_liquidity.tsx create mode 100644 pages/[chainId]/pools/new_position.tsx create mode 100644 pages/[chainId]/swap.tsx create mode 100644 pages/[chainId]/vaults/index.tsx create mode 100644 pages/[chainId]/vaults/manage_position.tsx create mode 100644 pages/[chainId]/vaults/new_position.tsx create mode 100644 public/img/leap-wallet.svg create mode 100644 util/chain.ts create mode 100644 util/route.ts diff --git a/components/Layout/RadialGradient.tsx b/components/Layout/RadialGradient.tsx index 948dd626..2ba04c2d 100644 --- a/components/Layout/RadialGradient.tsx +++ b/components/Layout/RadialGradient.tsx @@ -22,9 +22,9 @@ const backgrounds = { 'injective-888': 'linear-gradient(90deg, rgba(60, 205, 100, 0.25) 2.83%, rgba(82, 206, 252, 0.50) 97.47%)', 'comdex-1': - 'linear-gradient(90deg, rgba(60, 205, 100, 0.25) 2.83%, rgba(250, 64, 74, 0.50) 97.47%)', + 'linear-gradient(90deg, rgba(60, 205, 100, 0.25) 2.83%, rgba(250, 64, 74, 0.50) 97.47%)', 'comdex-test2': - 'linear-gradient(90deg, rgba(60, 205, 100, 0.25) 2.83%, rgba(250, 64, 74, 0.50) 97.47%)', + 'linear-gradient(90deg, rgba(60, 205, 100, 0.25) 2.83%, rgba(250, 64, 74, 0.50) 97.47%)', } const RadialGradient: FC = () => { diff --git a/components/Navbar/Navbar.tsx b/components/Navbar/Navbar.tsx index 8471f279..078942cd 100644 --- a/components/Navbar/Navbar.tsx +++ b/components/Navbar/Navbar.tsx @@ -15,6 +15,7 @@ import { } from '@chakra-ui/react' import { useWallet } from '@terra-money/wallet-provider' import BurgerIcon from 'components/icons/BurgerIcon' +import { useChains } from 'hooks/useChainInfo' import { useRecoilState } from 'recoil' import { walletState, WalletStatusType } from 'state/atoms/walletAtoms' @@ -25,10 +26,34 @@ import DrawerLink from './DrawerLink' import Logo from './Logo' import NavbarLink from './NavbarLink' +const links = [ + { + lable: 'Swap', + link: '/swap', + }, + { + lable: 'Pools', + link: '/pools', + }, + { + lable: 'Flashloan', + link: '/flashloan', + }, + { + lable: 'Vaults', + link: '/vaults', + }, + // { + // lable: "Chart", + // link: "/chart" + // }, +] + const Navbar = ({}) => { const { disconnect } = useWallet() const [{ key, chainId, network, activeWallet }, setWalletState] = useRecoilState(walletState) + const chains = useChains() const { isOpen: isOpenModal, onOpen: onOpenModal, @@ -36,40 +61,21 @@ const Navbar = ({}) => { } = useDisclosure() const { isOpen, onOpen, onClose } = useDisclosure() - function resetWalletConnection() { + const resetWalletConnection = () => { setWalletState({ status: WalletStatusType.idle, address: '', key: null, client: null, - network: network, - chainId: chainId, - activeWallet: 'keplr', + network, + chainId, + activeWallet: activeWallet || 'keplr', }) disconnect() } - const links = [ - { - lable: 'Swap', - link: '/swap', - }, - { - lable: 'Pools', - link: '/pools', - }, - { - lable: 'Flashloan', - link: '/flashloan', - }, - { - lable: 'Vaults', - link: '/vaults', - }, - // { - // lable: "Chart", - // link: "/chart" - // }, - ] + + const currenChain = chains.find((row) => row.chainId === chainId) + const currentChainName = currenChain?.label.toLowerCase() return ( @@ -85,10 +91,14 @@ const Navbar = ({}) => { {links.map(({ lable, link }) => ( - + ))} - + { onOpenModal={onOpenModal} onCloseModal={onCloseModal} /> - + { +const Flashloan: FC = () => { + const { chainId } = useRecoilValue(walletState) + const router = useRouter() + const chains = useChains() + const chainIdParam = router.query.chainId as string + const currenChain = chains.find((row) => row.chainId === chainId) + + if (!currenChain || currenChain.label.toLowerCase() !== chainIdParam) + return null + return ( diff --git a/components/Pages/Flashloan/FlashloanForm.tsx b/components/Pages/Flashloan/FlashloanForm.tsx index 437674ca..8fce8807 100644 --- a/components/Pages/Flashloan/FlashloanForm.tsx +++ b/components/Pages/Flashloan/FlashloanForm.tsx @@ -1,4 +1,4 @@ -import { useEffect, useRef, useState, useMemo } from 'react' +import { useEffect, useMemo, useRef, useState } from 'react' import { MdOutlineFormatIndentDecrease } from 'react-icons/md' import { Box, Button, Flex, HStack, Text, VStack } from '@chakra-ui/react' @@ -134,13 +134,11 @@ function FlashloanForm({}: Props) { alignItems="center" > - JSON to execute the trade + JSON to execute the trade {/* */} - - */} + variant="outline" + isLoading={tx?.txStep == TxStep.Estimating} + disabled={!!error} + onClick={() => tx?.simulate()} + > + {tx?.buttonLabel || 'Simulate'} + */} - - ))} + + + ))} ) } diff --git a/components/Pages/Pools/MyPoolsTable.tsx b/components/Pages/Pools/MyPoolsTable.tsx index fa618f51..58f0dea4 100644 --- a/components/Pages/Pools/MyPoolsTable.tsx +++ b/components/Pages/Pools/MyPoolsTable.tsx @@ -18,14 +18,11 @@ import { getCoreRowModel, useReactTable, } from '@tanstack/react-table' -import { CHIHUAHUA_MAINNET_CHAIN_ID } from 'constants/chain' import { formatPrice } from 'libs/num' -import { useRecoilValue } from 'recoil' -import { walletState } from 'state/atoms/walletAtoms' -import useIgnoreCoinhall from './hooks/useIgnoreCoinhall' import Loader from '../../Loader' import PoolName from './components/PoolName' +import useIgnoreCoinhall from './hooks/useIgnoreCoinhall' import { Pool } from './types' const columnHelper = createColumnHelper() @@ -102,7 +99,7 @@ const columns = [ ] const PoolsTable = ({ - pools = [], + pools, isLoading, }: { pools: Pool[] @@ -116,7 +113,7 @@ const PoolsTable = ({ getCoreRowModel: getCoreRowModel(), }) - if (isLoading) { + if (isLoading || !pools) { return ( = () => { const [allPools, setAllPools] = useState([]) const [isInitLoading, setInitLoading] = useState(true) + const { address, chainId } = useRecoilValue(walletState) + const client = useCosmwasmClient(chainId) const router = useRouter() + const chains = useChains() + const chainIdParam = router.query.chainId as string const { data: poolList } = usePoolsListQuery() - const { chainId } = useRecoilValue(walletState) - - const showCommingSoon = useMemo( - () => commingSoonNetworks.includes(chainId?.split('-')?.[0]), - [chainId] - ) - const [pools, isLoading] = useQueriesDataSelector( useQueryMultiplePoolsLiquidity({ - refetchInBackground: false, + refetchInBackground: true, pools: poolList?.pools, + client, }) ) + const showCommingSoon = useMemo( + () => commingSoonNetworks.includes(chainId?.split('-')?.[0]), + [chainId] + ) + const initPools = useCallback(async () => { - if (!pools || pools.length === 0) return - if (allPools.length > 0) return + if (!pools) return + if (allPools.length > 0) { + return + } setInitLoading(true) @@ -63,10 +70,10 @@ const Pools: FC = () => { const _allPools = await Promise.all( _pools.map(async (pool) => { let price = 0 - if ((pool.isUSDCPool || pool.isLunaxPool) && pool.asset0Price > 0) { + if ((pool.isUSDPool || pool.isLunaxPool) && pool.asset0Price > 0) { price = pool.asset0Price / pool.asset1Price } - if (!pool.isUSDCPool && pool.asset1Price > 0) { + if (!pool.isUSDPool && pool.asset1Price > 0) { price = pool.asset1Price / pool.asset0Price } @@ -77,6 +84,11 @@ const Pools: FC = () => { ? await getTokenPrice(pool?.pool_assets[1].token_address, Date.now()) : 1 + const isUSDPool = + pool?.isUSDPool || + pool?.pool_assets[0].symbol.includes('CMST') || + pool?.pool_assets[1].symbol.includes('CMST') + return { contract: pool?.swap_address, pool: pool?.displayName, @@ -89,44 +101,62 @@ const Pools: FC = () => { volume24hr: showCommingSoon ? COMING_SOON : `$${formatPrice(pool.usdVolume24h)}`, - totalLiq: pool.liquidity.available.total.dollarValue, + totalLiq: pool.liquidity?.available?.total?.dollarValue, liquidity: pool.liquidity, price: showCommingSoon - ? `$${(asset0Price / asset1Price)?.toFixed(2)}` - : `${pool?.isUSDCPool ? '$' : ''}${Number(price).toFixed(3)}`, - isUSDCPool: pool?.isUSDCPool, + ? `${isUSDPool ? '$' : ''}${(asset0Price / asset1Price)?.toFixed( + 2 + )}` + : `${isUSDPool ? '$' : ''}${Number(price).toFixed(3)}`, + isUSDPool: isUSDPool, cta: () => router.push( - `/pools/new_position?from=${pool.pool_assets?.[0].symbol}&to=${pool.pool_assets?.[1].symbol}` + `/${chainIdParam}/pools/new_position?from=${pool.pool_assets?.[0].symbol}&to=${pool.pool_assets?.[1].symbol}` ), } }) ) setAllPools(_allPools) - setInitLoading(false) + setTimeout(() => { + setInitLoading(false) + }, 500) + // eslint-disable-next-line react-hooks/exhaustive-deps - }, [pools, router]) + }, [pools]) useEffect(() => { - initPools() + if (chainId) { + const currenChain = chains.find((row) => row.chainId === chainId) + if (currenChain && currenChain.label.toLowerCase() === chainIdParam) { + initPools() + } + } // eslint-disable-next-line react-hooks/exhaustive-deps - }, [pools]) + }, [chainId, address, chains, pools]) // get a list of my pools - const myPools = allPools - .filter(({ liquidity }) => liquidity?.providedTotal?.tokenAmount > 0) - .map((item) => ({ - ...item, - myPosition: formatPrice(item?.liquidity?.providedTotal?.dollarValue), - cta: () => router.push(`/pools/manage_liquidity?poolId=${item.poolId}`), - })) + const myPools = useMemo(() => { + return ( + allPools && + allPools + .filter(({ liquidity }) => liquidity?.providedTotal?.tokenAmount > 0) + .map((item) => ({ + ...item, + myPosition: formatPrice(item?.liquidity?.providedTotal?.dollarValue), + cta: () => + router.push( + `/${chainIdParam}/pools/manage_liquidity?poolId=${item.poolId}` + ), + })) + ) + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [allPools]) // get a list of all pools excepting myPools - const myPoolsId = myPools.map(({ pool }) => pool) - const allPoolsForShown = allPools.filter( - (item) => !myPoolsId.includes(item.pool) - ) + const myPoolsId = myPools && myPools.map(({ pool }) => pool) + const allPoolsForShown = + allPools && allPools.filter((item) => !myPoolsId.includes(item.pool)) return ( = () => { alignItems="center" margin="auto" > - + My Pools @@ -142,7 +172,7 @@ const Pools: FC = () => { diff --git a/components/Pages/Pools/hooks/useIgnoreCoinhall.tsx b/components/Pages/Pools/hooks/useIgnoreCoinhall.tsx index 2f0a3a9b..d5a4b43a 100644 --- a/components/Pages/Pools/hooks/useIgnoreCoinhall.tsx +++ b/components/Pages/Pools/hooks/useIgnoreCoinhall.tsx @@ -1,4 +1,5 @@ import { useMemo } from 'react' + import { useRecoilValue } from 'recoil' import { walletState } from 'state/atoms/walletAtoms' diff --git a/components/Pages/Pools/types/index.ts b/components/Pages/Pools/types/index.ts index 0afcb541..ffd7df38 100644 --- a/components/Pages/Pools/types/index.ts +++ b/components/Pages/Pools/types/index.ts @@ -8,6 +8,6 @@ export type Pool = { volume24hr: number | string totalLiq: number | string price?: number - isUSDCPool?: boolean + isUSDPool?: boolean cta?: () => void } diff --git a/components/Pages/Swap/Swap.tsx b/components/Pages/Swap/Swap.tsx index b61fec23..5e3b6553 100644 --- a/components/Pages/Swap/Swap.tsx +++ b/components/Pages/Swap/Swap.tsx @@ -1,10 +1,11 @@ -import { FC, useEffect, useState } from 'react' +import { FC, useEffect, useMemo, useState } from 'react' import { HStack, Text, VStack } from '@chakra-ui/react' +import { useChains } from 'hooks/useChainInfo' import { TxStep } from 'hooks/useTransaction' -import getChainName from 'libs/getChainName' import { fromChainAmount } from 'libs/num' import { useRouter } from 'next/router' +import { usePoolsListQuery } from 'queries/usePoolsListQuery' import { useRecoilState, useRecoilValue } from 'recoil' import { walletState } from 'state/atoms/walletAtoms' @@ -23,41 +24,93 @@ const Swap: FC = ({}) => { const [[tokenA, tokenB], setTokenSwapState] = useRecoilState(tokenSwapAtom) const [reverse, setReverse] = useState(false) - const { chainId, address, key, status } = useRecoilValue(walletState) const [resetForm, setResetForm] = useState(false) + + const { chainId, address, network, status } = useRecoilValue(walletState) + const chains = useChains() + const { tx, simulated, state, path, minReceive } = useSwap({ reverse }) + const { data: poolList } = usePoolsListQuery() const router = useRouter() + const currenChain = chains.find((row) => row.chainId === chainId) + const currentChainId = currenChain?.label.toLowerCase() + + const tokenList = useMemo(() => { + let listObj = {} + const { pools = [] } = poolList || {} + pools + .map(({ pool_assets }) => pool_assets) + .map(([a, b]) => { + listObj = { ...listObj, [a.symbol]: a, [b.symbol]: b } + }) + + return Object.keys(listObj).map((row) => { + return { + symbol: listObj[row].symbol, + decimals: listObj[row].decimals, + amount: 0, + } + }) + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [poolList, chainId]) useEffect(() => { + if (!currentChainId) return const { from, to } = router.query - - if (!from && !to) { - if (address) { - const [defaultFrom, defaultTo] = defaultTokens[getChainName(address)] - const params = `?from=${defaultFrom?.tokenSymbol}&to=${defaultTo?.tokenSymbol}` - - setTokenSwapState([defaultFrom, defaultTo]) - router.replace(params) - setResetForm(true) - } + const [defaultFrom, defaultTo] = defaultTokens[network][currentChainId] + + let newState: TokenItemState[] = [ + { + tokenSymbol: String(from), + amount: 0, + decimals: 6, + }, + { + tokenSymbol: String(to), + amount: 0, + decimals: 6, + }, + ] + + if ( + tokenList.find((row) => row.symbol === from) && + tokenList.find((row) => row.symbol === to) + ) { + return } else { - const newState: TokenItemState[] = [ + newState = [ { - tokenSymbol: String(from), + tokenSymbol: String(defaultFrom.tokenSymbol), amount: 0, decimals: 6, }, { - tokenSymbol: String(to), + tokenSymbol: String(defaultTo.tokenSymbol), amount: 0, decimals: 6, }, ] - setTokenSwapState(newState) + setResetForm(true) } + + setTokenSwapState(newState) + // eslint-disable-next-line react-hooks/exhaustive-deps - }, [address, chainId]) + }, [address, currentChainId, tokenList]) - const { tx, simulated, state, path, minReceive } = useSwap({ reverse }) + useEffect(() => { + if (!currentChainId) return + + if (tokenA?.tokenSymbol !== null && tokenB?.tokenSymbol !== null) { + if ( + tokenList.find((row) => row.symbol === tokenA?.tokenSymbol) && + tokenList.find((row) => row.symbol === tokenB?.tokenSymbol) + ) { + const url = `/${currentChainId}/swap?from=${tokenA?.tokenSymbol}&to=${tokenB?.tokenSymbol}` + router.push(url) + } + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [tokenA, tokenB]) const clearForm = (reset) => { setTokenSwapState([ @@ -93,20 +146,12 @@ const Swap: FC = ({}) => { setTokenSwapState([A, B]) } - useEffect(() => { - if (tokenA?.tokenSymbol !== null && tokenB?.tokenSymbol !== null) { - const params = `?from=${tokenA?.tokenSymbol}&to=${tokenB?.tokenSymbol}` - router.replace(params, undefined, { shallow: true }) - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [tokenA, tokenB]) - return ( = ({ setValue('tokenB', { ...tokenB, amount: 0 }) setResetForm(false) } + // eslint-disable-next-line react-hooks/exhaustive-deps }, [resetForm, tx?.txStep]) // const [[_, tokenBBalance] = [], isLoading] = useMultipleTokenBalance([tokenA?.tokenSymbol, tokenB?.tokenSymbol]) @@ -101,6 +102,7 @@ const SwapForm: FC = ({ else if (!!!amountA?.amount) return 'Enter Amount' else if (tx?.buttonLabel) return tx?.buttonLabel else return 'Swap' + // eslint-disable-next-line react-hooks/exhaustive-deps }, [tx?.buttonLabel, tokenB.tokenSymbol, connected, amountA, state?.error]) const onReverse = () => { @@ -144,6 +146,7 @@ const SwapForm: FC = ({ const e = num(tokenA.amount).times(Math.pow(10, tokenBInfo.decimals)) return num(simulated?.amount).div(e).toFixed(6) + // eslint-disable-next-line react-hooks/exhaustive-deps }, [simulated, tokenA.amount]) useEffect(() => { @@ -194,6 +197,7 @@ const SwapForm: FC = ({ } } } + // eslint-disable-next-line react-hooks/exhaustive-deps }, [simulated]) const isInputDisabled = tx?.txStep == TxStep.Posting @@ -290,7 +294,6 @@ const SwapForm: FC = ({ )} /> - = ({ onClick={onReverse} /> - = ({ )} /> - - {amountB.amount && ( <> @@ -524,7 +524,6 @@ const SwapForm: FC = ({ )} - {/* { (tx?.error && !!!tx.buttonLabel) && ( {tx?.error} ) } */} diff --git a/components/Pages/Swap/defaultTokens.json b/components/Pages/Swap/defaultTokens.json index 370b78fa..1239d082 100644 --- a/components/Pages/Swap/defaultTokens.json +++ b/components/Pages/Swap/defaultTokens.json @@ -1,52 +1,96 @@ { - "juno": [ - { - "tokenSymbol": "JUNO", - "amount": 0 - }, - { - "tokenSymbol": "ATOM", - "amount": 0 - } - ], - "terra": [ - { - "tokenSymbol": "LUNA", - "amount": 0 - }, - { - "tokenSymbol": "ATOM", - "amount": 0 - } - ], - "chihuahua": [ - { - "tokenSymbol": "HUAHUA", - "amount": 0 - }, - { - "tokenSymbol": "PUPPY", - "amount": 0 - } - ], - "inj": [ - { - "tokenSymbol": "INJ", - "amount": 0 - }, - { - "tokenSymbol": "USDT", - "amount": 0 - } - ], - "comdex": [ - { - "tokenSymbol": "CMDX", - "amount": 0 - }, - { - "tokenSymbol": "ATOM", - "amount": 0 - } - ] + "mainnet": { + "juno": [ + { + "tokenSymbol": "JUNO", + "amount": 0 + }, + { + "tokenSymbol": "ATOM", + "amount": 0 + } + ], + "terra": [ + { + "tokenSymbol": "LUNA", + "amount": 0 + }, + { + "tokenSymbol": "ATOM", + "amount": 0 + } + ], + "chihuahua": [ + { + "tokenSymbol": "HUAHUA", + "amount": 0 + }, + { + "tokenSymbol": "PUPPY", + "amount": 0 + } + ], + "injective": [ + { + "tokenSymbol": "INJ", + "amount": 0 + }, + { + "tokenSymbol": "USDT", + "amount": 0 + } + ], + "comdex": [ + { + "tokenSymbol": "CMDX", + "amount": 0 + }, + { + "tokenSymbol": "ATOM", + "amount": 0 + } + ] + }, + "testnet": { + "juno": [ + { + "tokenSymbol": "JUNO", + "amount": 0 + }, + { + "tokenSymbol": "JUNOONE", + "amount": 0 + } + ], + "terra": [ + { + "tokenSymbol": "LUNA", + "amount": 0 + }, + { + "tokenSymbol": "LUNAONE", + "amount": 0 + } + ], + "injective": [ + { + "tokenSymbol": "INJ", + "amount": 0 + }, + { + "tokenSymbol": "USDT", + "amount": 0 + } + ], + "comdex": [ + { + "tokenSymbol": "CMDX", + "amount": 0 + }, + { + "tokenSymbol": "ATOM", + "amount": 0 + } + ] + } } diff --git a/components/Vaults/AllVaultsTable.tsx b/components/Vaults/AllVaultsTable.tsx index fe88e43b..6ad95c20 100644 --- a/components/Vaults/AllVaultsTable.tsx +++ b/components/Vaults/AllVaultsTable.tsx @@ -1,5 +1,3 @@ -import { useEffect, useState } from 'react' - import { Button, Flex, @@ -96,14 +94,8 @@ const AllVaultsTable = ({ vaults: Vault[] isLoading?: boolean }) => { - const [data, setData] = useState(() => [...vaults]) - - useEffect(() => { - setData(vaults) - }, [vaults]) - const table = useReactTable({ - data, + data: vaults, columns, getCoreRowModel: getCoreRowModel(), }) diff --git a/components/Vaults/ManagePoistion/DepositForm.tsx b/components/Vaults/ManagePoistion/DepositForm.tsx index 3687409e..152d13eb 100644 --- a/components/Vaults/ManagePoistion/DepositForm.tsx +++ b/components/Vaults/ManagePoistion/DepositForm.tsx @@ -43,7 +43,6 @@ const DepositForm = ({ vaultAddress, refetch, }: Props) => { - const router = useRouter() const baseToken = useBaseTokenInfo() const [token, setToken] = useState({ @@ -52,6 +51,7 @@ const DepositForm = ({ }) const toast = useToast() const { chainId } = useRecoilValue(walletState) + const onSuccess = useCallback( (txHash) => { refetch?.() @@ -68,14 +68,10 @@ const DepositForm = ({ isClosable: true, }) }, + // eslint-disable-next-line react-hooks/exhaustive-deps [token] ) - useEffect(() => { - const params = `?vault=${token?.tokenSymbol}` - router.replace(params, undefined, { shallow: true }) - }, [token.tokenSymbol]) - const { tx } = useDepost({ vaultAddress, token, onSuccess }) const buttonLabel = useMemo(() => { @@ -98,6 +94,7 @@ const DepositForm = ({ setToken({ ...token, amount: 0 }) tx?.reset() } + // eslint-disable-next-line react-hooks/exhaustive-deps }, [tx.txStep]) return ( diff --git a/components/Vaults/ManagePoistion/ManagePosition.tsx b/components/Vaults/ManagePoistion/ManagePosition.tsx index 13187af4..4eba5f7d 100644 --- a/components/Vaults/ManagePoistion/ManagePosition.tsx +++ b/components/Vaults/ManagePoistion/ManagePosition.tsx @@ -1,4 +1,4 @@ -import { useMemo } from 'react' +import { useEffect, useMemo } from 'react' import { ArrowBackIcon } from '@chakra-ui/icons' import { @@ -13,9 +13,10 @@ import { Text, VStack, } from '@chakra-ui/react' +import { useChains } from 'hooks/useChainInfo' import { useTokenBalance } from 'hooks/useTokenBalance' import { NextRouter, useRouter } from 'next/router' -import { useRecoilState, useRecoilValue } from 'recoil' +import { useRecoilValue } from 'recoil' import { walletState } from 'state/atoms/walletAtoms' import useVault, { useVaultDepost } from '../hooks/useVaults' @@ -25,6 +26,7 @@ import WithdrawForm from './WithdrawForm' const ManagePosition = () => { const router: NextRouter = useRouter() const { vaults, isLoading, refetch: vaultsRefetch } = useVault() + const chains = useChains() const params = new URLSearchParams(location.search) const { chainId, key, address, status } = useRecoilValue(walletState) const vaultId = params.get('vault') || 'JUNO' @@ -33,6 +35,23 @@ const ManagePosition = () => { () => vaults?.vaults.find((v) => v.vault_assets?.symbol === vaultId), [vaults, vaultId] ) + + useEffect(() => { + if (chainId) { + const currenChain = chains.find((row) => row.chainId === chainId) + if (currenChain) { + if (!vault) { + router.push(`/${currenChain.label.toLocaleLowerCase()}/vaults`) + } else { + router.push( + `/${currenChain.label.toLowerCase()}/vaults/manage_position?vault=${vaultId}` + ) + } + } + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [chainId, address, chains, vault]) + const { balance: lpTokenBalance, isLoading: lpTokenBalanceLoading, diff --git a/components/Vaults/MyVaultsTable.tsx b/components/Vaults/MyVaultsTable.tsx index 004179d6..0c798609 100644 --- a/components/Vaults/MyVaultsTable.tsx +++ b/components/Vaults/MyVaultsTable.tsx @@ -1,5 +1,3 @@ -import { useEffect, useState } from 'react' - import { Button, Flex, @@ -87,14 +85,8 @@ const MyVaultsTable = ({ vaults: Vault[] isLoading?: boolean }) => { - const [data, setData] = useState(() => [...vaults]) - - useEffect(() => { - setData(vaults) - }, [vaults]) - const table = useReactTable({ - data, + data: vaults, columns, getCoreRowModel: getCoreRowModel(), }) diff --git a/components/Vaults/NewPosition.tsx b/components/Vaults/NewPosition.tsx index e298d3c8..d80871d1 100644 --- a/components/Vaults/NewPosition.tsx +++ b/components/Vaults/NewPosition.tsx @@ -1,4 +1,4 @@ -import { useMemo } from 'react' +import { useEffect, useMemo } from 'react' import { ArrowBackIcon } from '@chakra-ui/icons' import { @@ -13,9 +13,10 @@ import { Text, VStack, } from '@chakra-ui/react' +import { useChains } from 'hooks/useChainInfo' import { useTokenBalance } from 'hooks/useTokenBalance' import { NextRouter, useRouter } from 'next/router' -import { useRecoilState, useRecoilValue } from 'recoil' +import { useRecoilValue } from 'recoil' import { walletState } from 'state/atoms/walletAtoms' import useVault, { useVaultDepost } from './hooks/useVaults' @@ -25,12 +26,31 @@ const NewPosition = () => { const router: NextRouter = useRouter() const { vaults, isLoading, refetch: vaultsRefetch } = useVault() const params = new URLSearchParams(location.search) + const chains = useChains() const { chainId, key, address, status } = useRecoilValue(walletState) const vaultId = params.get('vault') || 'JUNOX' + const vault = useMemo( () => vaults?.vaults.find((v) => v.vault_assets?.symbol === vaultId), [vaults, vaultId] ) + + useEffect(() => { + if (chainId) { + const currenChain = chains.find((row) => row.chainId === chainId) + if (currenChain) { + if (!vault) { + router.push(`/${currenChain.label.toLocaleLowerCase()}/vaults`) + } else { + router.push( + `/${currenChain.label.toLowerCase()}/vaults/new_position?vault=${vaultId}` + ) + } + } + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [chainId, address, chains, vault]) + const edgeTokenList = useMemo( () => vaults?.vaults.map(({ vault_assets }) => vault_assets?.symbol), [vaults] @@ -77,7 +97,6 @@ const NewPosition = () => { New Position - { borderRadius="30px" width={['full']} > - + {vault?.vault_assets?.symbol && ( { +const Vaults: FC = () => { + const [isAllVaultsInited, setAllVaultsInited] = useState(true) + const [isMyVaultsInited, setMyVaultsInited] = useState(true) const { vaults, isLoading } = useVault() const router = useRouter() + const chainIdParam = router.query.chainId as string const myVaults = useMemo(() => { if (!vaults) return [] + setMyVaultsInited(false) return vaults.vaults .filter((vault) => !!Number(vault?.deposits?.lpBalance)) @@ -35,21 +30,24 @@ const Vaults = (props: Props) => { apr: 'coming soon', cta: () => router.push( - `/vaults/manage_position?vault=${vault.vault_assets?.symbol}` + `/${chainIdParam}/vaults/manage_position?vault=${vault.vault_assets?.symbol}` ), })) - }, [vaults]) + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [vaults, isMyVaultsInited]) const allVaults = useMemo(() => { if (!vaults) return [] + setAllVaultsInited(false) + return ( vaults.vaults // .filter(vault => !!!Number(vault.deposits.lptoken)) .map((vault) => { const ctaLabel = vault?.hasDepost ? 'Manage Position' : 'New Position' - const url = `/vaults/${ - vault?.hasDepost ? 'manage' : 'new' - }_position?vault=${vault.vault_assets?.symbol}` + const url = `/${chainIdParam}/vaults/${ + vault?.hasDepost ? 'manage_position' : 'new_position' + }?vault=${vault.vault_assets?.symbol}` return { vaultId: vault?.pool_id, tokenImage: vault.vault_assets?.logoURI, @@ -61,7 +59,8 @@ const Vaults = (props: Props) => { } }) ) - }, [vaults]) + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [vaults, isAllVaultsInited]) return ( { Vaults - + ) diff --git a/components/Wallet/ConnectedWalletWithDisconnect/ConnectedWallet/ConnectedWalletIcon.tsx b/components/Wallet/ConnectedWalletWithDisconnect/ConnectedWallet/ConnectedWalletIcon.tsx index d581e3bf..7afd99e6 100644 --- a/components/Wallet/ConnectedWalletWithDisconnect/ConnectedWallet/ConnectedWalletIcon.tsx +++ b/components/Wallet/ConnectedWalletWithDisconnect/ConnectedWallet/ConnectedWalletIcon.tsx @@ -3,14 +3,21 @@ import React from 'react' import { Box, Img } from '@chakra-ui/react' import { useConnectedWallet } from '@terra-money/wallet-provider' import KeplrWalletIcon from 'components/icons/KeplrWalletIcon' +import { useRecoilValue } from 'recoil' +import { walletState } from 'state/atoms/walletAtoms' function ConnectedWalletIcon({ connected }) { const connectedWallet = useConnectedWallet() + const { activeWallet } = useRecoilValue(walletState) return ( <> {connected ? ( - + {activeWallet === 'leap' ? ( + + ) : ( + + )} ) : ( diff --git a/components/Wallet/Modal/LeapConnectButton.tsx b/components/Wallet/Modal/LeapConnectButton.tsx new file mode 100644 index 00000000..232d6d00 --- /dev/null +++ b/components/Wallet/Modal/LeapConnectButton.tsx @@ -0,0 +1,29 @@ +import React, { useCallback } from 'react' + +import { Button, HStack, Text } from '@chakra-ui/react' +import useConnectLeap from 'hooks/useConnectLeap' + +function LeapConnectButton({ onCloseModal }) { + const { setLeapAndConnect } = useConnectLeap() + + const setLeapMemo = useCallback(() => { + setLeapAndConnect() + onCloseModal() + }, [onCloseModal, setLeapAndConnect]) + + return ( + + ) +} + +export default LeapConnectButton diff --git a/components/Wallet/Modal/Modal.tsx b/components/Wallet/Modal/Modal.tsx index a243f04e..47c4f268 100644 --- a/components/Wallet/Modal/Modal.tsx +++ b/components/Wallet/Modal/Modal.tsx @@ -12,7 +12,9 @@ import { import KeplrConnectButton from 'components/Wallet/Modal/KeplrConnectButton' import TerraStationConnectButton from 'components/Wallet/Modal/TerraStationConnectButton' -function WalletModal({ isOpenModal, onCloseModal }) { +import LeapConnectButton from './LeapConnectButton' + +function WalletModal({ isOpenModal, onCloseModal, chainId }) { return ( @@ -21,8 +23,11 @@ function WalletModal({ isOpenModal, onCloseModal }) { - + {chainId === 'phoenix-1' && ( + + )} + diff --git a/components/Wallet/Wallet.tsx b/components/Wallet/Wallet.tsx index f62a4363..bbe75b00 100644 --- a/components/Wallet/Wallet.tsx +++ b/components/Wallet/Wallet.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useMemo } from 'react' +import React, { useCallback, useEffect, useMemo } from 'react' import { Box, Button, Divider } from '@chakra-ui/react' import { useConnectedWallet } from '@terra-money/wallet-provider' @@ -7,24 +7,88 @@ import WalletIcon from 'components/icons/WalletIcon' import Select from 'components/Wallet/ChainSelect/Select' import ChainSelectWithBalance from 'components/Wallet/ChainSelectWithBalance/ChainSelectWithBalance' import ConnectedWalletWithDisconnect from 'components/Wallet/ConnectedWalletWithDisconnect/ConnectedWalletWithDisconnect' -import { useChainInfo } from 'hooks/useChainInfo' -import useTerraModalOrConnectKeplr from 'hooks/useTerraModalOrConnectKeplr' +import { useChainInfo, useChains } from 'hooks/useChainInfo' +import useConnectKeplr from 'hooks/useConnectKeplr' +import { useRouter } from 'next/router' import { useRecoilState } from 'recoil' import { walletState } from 'state/atoms/walletAtoms' +import { validChains } from 'util/chain' +import { getPathName } from 'util/route' + +import useConnectLeap from '../../hooks/useConnectLeap' const Wallet: any = ({ connected, onDisconnect, onOpenModal }) => { const [currentWalletState, setCurrentWalletState] = useRecoilState(walletState) + const chains = useChains() + const router = useRouter() + const chainIdParam = router.query.chainId as string + const connectedWallet = useConnectedWallet() const [chainInfo] = useChainInfo(currentWalletState.chainId) - const { showTerraModalOrConnectKeplr } = - useTerraModalOrConnectKeplr(onOpenModal) + + const { connectKeplr } = useConnectKeplr() + const { connectLeap } = useConnectLeap() + + useEffect(() => { + onDisconnect() + + if (router.pathname === '/') return + + const defaultChainId = + currentWalletState.network === 'mainnet' ? 'juno-1' : 'uni-3' + + if ( + validChains[currentWalletState.network][chainIdParam] !== + currentWalletState.chainId + ) { + setCurrentWalletState({ + ...currentWalletState, + chainId: validChains[currentWalletState.network][chainIdParam], + }) + } + + if (!validChains[currentWalletState.network][chainIdParam]) { + setCurrentWalletState({ + ...currentWalletState, + chainId: defaultChainId, + }) + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []) + + // useEffect(() => { + // if (router.pathname === '/') return + + // const defaultChain = + // currentWalletState.network === 'mainnet' + // ? chains.find((row) => row.chainId === 'juno-1') + // : chains.find((row) => row.chainId === 'uni-3') + // const targetChain = chains.find( + // (row) => row.label.toLowerCase() === chainIdParam + // ) + // if (targetChain && targetChain.chainId !== currentWalletState.chainId) { + // setCurrentWalletState({ + // ...currentWalletState, + // chainId: targetChain.chainId, + // }) + // } + // if (chains && chains.length > 0 && !targetChain) { + // setCurrentWalletState({ + // ...currentWalletState, + // chainId: defaultChain.chainId, + // }) + // } + + // // eslint-disable-next-line react-hooks/exhaustive-deps + // }, [chainIdParam, chains]) const denom = useMemo(() => { if (!chainInfo) return const [coinDenom] = (chainInfo as any)?.currencies || [] return coinDenom + // eslint-disable-next-line react-hooks/exhaustive-deps }, [ chainInfo, currentWalletState.chainId, @@ -38,9 +102,30 @@ const Wallet: any = ({ connected, onDisconnect, onOpenModal }) => { onDisconnect() setCurrentWalletState({ ...currentWalletState, chainId: chain.chainId }) }, - [currentWalletState.chainId, chainInfo] + // eslint-disable-next-line react-hooks/exhaustive-deps + [currentWalletState.chainId, chains, router] ) + useEffect(() => { + if (!currentWalletState.chainId) return + if (!chains) return + + if (currentWalletState.activeWallet === 'leap') { + connectLeap() + } else if (currentWalletState.activeWallet === 'keplr') { + connectKeplr() + } + + // update route + const sourceChain = chains.find( + (row) => row.chainId.toLowerCase() === currentWalletState.chainId + ) + if (sourceChain) { + router.push(getPathName(router, sourceChain.label)) + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [currentWalletState.chainId, currentWalletState.activeWallet, chains]) + if (!connected && !connectedWallet) { return ( <> @@ -57,7 +142,7 @@ const Wallet: any = ({ connected, onDisconnect, onOpenModal }) => { color="white" borderColor="whiteAlpha.400" borderRadius="full" - onClick={showTerraModalOrConnectKeplr} + onClick={onOpenModal} > Connect wallet diff --git a/docs/SECURITY b/docs/SECURITY index 9f476684..0d87c028 100644 --- a/docs/SECURITY +++ b/docs/SECURITY @@ -7,7 +7,7 @@ This document outlines security procedures and general policies for the `migaloo ## Reporting a Bug Security is something we take seriously at White Whale. Thanks for taking the time to improve the security of `migaloo-frontend`. We appreciate your efforts and responsible disclosure and will make every effort to acknowledge your contributions. -Please report security bugs by emailing White Whale's CTO at sencommunis@protonmail.com or the repository administrator at 0xfable@protonmail.com. Do not report it publicly on the GitHub issues tracker. Your report should detail the necessary steps to reproduce the security issue. We will acknowledge your email within 48 hours and send a detailed response indicating the next steps. After the initial reply to your report, we will keep you informed of the progress towards a fix and full announcement and may ask for additional information or guidance. +Please report security bugs by emailing White Whale at security@whitewhale.money. Do not report it publicly on the GitHub issues tracker. Your report should detail the necessary steps to reproduce the security issue. We will acknowledge your email within 48 hours and send a detailed response indicating the next steps. After the initial reply to your report, we will keep you informed of the progress towards a fix and full announcement and may ask for additional information or guidance. Report security bugs in third-party modules to the person or team maintaining the module. diff --git a/features/liquidity/components/LiquidityBreakdown.tsx b/features/liquidity/components/LiquidityBreakdown.tsx index 53d63d0c..03868fd2 100644 --- a/features/liquidity/components/LiquidityBreakdown.tsx +++ b/features/liquidity/components/LiquidityBreakdown.tsx @@ -1,3 +1,5 @@ +import React from 'react' + import { useTokenToTokenPrice } from 'features/swap' import { Button, @@ -12,7 +14,6 @@ import { Text, Tooltip, } from 'junoblocks' -import React from 'react' import { __POOL_REWARDS_ENABLED__, __POOL_STAKING_ENABLED__, diff --git a/features/liquidity/components/ManagePoolDialog/ManagePoolDialog.tsx b/features/liquidity/components/ManagePoolDialog/ManagePoolDialog.tsx index b0f3f17f..076b3765 100644 --- a/features/liquidity/components/ManagePoolDialog/ManagePoolDialog.tsx +++ b/features/liquidity/components/ManagePoolDialog/ManagePoolDialog.tsx @@ -1,3 +1,5 @@ +import { useEffect, useRef, useState } from 'react' + import { usePrevious } from '@reach/utils' import { LiquidityInput } from 'components' import { useTokenDollarValue } from 'hooks/useTokenDollarValue' @@ -20,7 +22,6 @@ import { Text, } from 'junoblocks' import { useQueryPoolLiquidity } from 'queries/useQueryPools' -import { useEffect, useRef, useState } from 'react' import { LiquidityInputSelector } from '../LiquidityInputSelector' import { PercentageSelection } from '../PercentageSelection' diff --git a/features/liquidity/components/UnbondingLiquidityStatusList.tsx b/features/liquidity/components/UnbondingLiquidityStatusList.tsx index cbc214a3..6ba18ae7 100644 --- a/features/liquidity/components/UnbondingLiquidityStatusList.tsx +++ b/features/liquidity/components/UnbondingLiquidityStatusList.tsx @@ -1,3 +1,6 @@ +import React, { useMemo } from 'react' +import { toast } from 'react-hot-toast' + import { useClaimTokens, usePoolPairTokenAmount, @@ -20,8 +23,6 @@ import { UpRightArrow, Valid, } from 'junoblocks' -import React, { useMemo } from 'react' -import { toast } from 'react-hot-toast' import { TokenInfo } from '../../../queries/usePoolsListQuery' import { UnbondingLiquidityCard } from './UnbondingLiquidityCard' diff --git a/features/swap/components/TokenSwapModule.tsx b/features/swap/components/TokenSwapModule.tsx index bdd9cf5b..bc8d1019 100644 --- a/features/swap/components/TokenSwapModule.tsx +++ b/features/swap/components/TokenSwapModule.tsx @@ -1,6 +1,7 @@ +import { useEffect, useRef } from 'react' + import { useTokenList } from 'hooks/useTokenList' import { styled, useMedia, usePersistance } from 'junoblocks' -import { useEffect, useRef } from 'react' import { useRecoilState, useRecoilValue } from 'recoil' import { TransactionStatus, diff --git a/features/swap/components/TransactionAction.tsx b/features/swap/components/TransactionAction.tsx index 6a7cb509..2e6cadef 100644 --- a/features/swap/components/TransactionAction.tsx +++ b/features/swap/components/TransactionAction.tsx @@ -1,6 +1,7 @@ +import React, { useEffect, useState } from 'react' + import { useTokenBalance } from 'hooks/useTokenBalance' import { Button, Inline, Spinner, styled, Text } from 'junoblocks' -import React, { useEffect, useState } from 'react' import { useRecoilState, useRecoilValue } from 'recoil' import { walletState, WalletStatusType } from 'state/atoms/walletAtoms' import { NETWORK_FEE } from 'util/constants' diff --git a/features/swap/components/TransactionTips.tsx b/features/swap/components/TransactionTips.tsx index 98992511..8af26e10 100644 --- a/features/swap/components/TransactionTips.tsx +++ b/features/swap/components/TransactionTips.tsx @@ -1,3 +1,5 @@ +import React, { useState } from 'react' + import { Button, Column, @@ -9,7 +11,6 @@ import { styled, Text, } from 'junoblocks' -import React, { useState } from 'react' import { useRecoilValue } from 'recoil' import { useTxRates } from '../hooks' diff --git a/features/swap/hooks/useTokenSwap.tsx b/features/swap/hooks/useTokenSwap.tsx index 1cc62295..96c9ee68 100644 --- a/features/swap/hooks/useTokenSwap.tsx +++ b/features/swap/hooks/useTokenSwap.tsx @@ -1,3 +1,6 @@ +import { toast } from 'react-hot-toast' +import { useMutation } from 'react-query' + import { useTokenInfo } from 'hooks/useTokenInfo' import { Button, @@ -7,8 +10,6 @@ import { UpRightArrow, Valid, } from 'junoblocks' -import { toast } from 'react-hot-toast' -import { useMutation } from 'react-query' import { useRecoilValue, useSetRecoilState } from 'recoil' import { directTokenSwap, passThroughTokenSwap } from 'services/swap' import { @@ -88,7 +89,7 @@ export const useTokenSwap = ({ // }) } - return await passThroughTokenSwap({ + return passThroughTokenSwap({ tokenAmount, price, slippage, diff --git a/hooks/useBondTokens.ts b/hooks/useBondTokens.ts index b3890e7c..01c7d262 100644 --- a/hooks/useBondTokens.ts +++ b/hooks/useBondTokens.ts @@ -1,4 +1,5 @@ import { useMutation } from 'react-query' + import { useRecoilValue } from 'recoil' import { usePoolFromListQueryById } from '../queries/usePoolsListQuery' diff --git a/hooks/useChainInfo.ts b/hooks/useChainInfo.ts index 53bc543e..4dfe87d2 100644 --- a/hooks/useChainInfo.ts +++ b/hooks/useChainInfo.ts @@ -1,14 +1,18 @@ -import { ChainInfo } from '@keplr-wallet/types' -import { useQuery } from 'react-query' - -import { queryClient } from '../services/queryClient' - const chainInfoQueryKey = '@chain-info' // import chainInfo from "components/Wallet/chainInfo.json" import { useMemo } from 'react' +import { useQuery } from 'react-query' + +import { ChainInfo } from '@keplr-wallet/types' import { useRecoilValue } from 'recoil' import { walletState } from 'state/atoms/walletAtoms' +import { queryClient } from '../services/queryClient' + +interface CustomChainType extends ChainInfo { + label: string +} + export const unsafelyReadChainInfoCache = () => queryClient.getQueryCache().find(chainInfoQueryKey)?.state?.data as | ChainInfo @@ -17,12 +21,13 @@ export const unsafelyReadChainInfoCache = () => export const useChains = () => { const currentWalletState = useRecoilValue(walletState) - const { data = [], isLoading } = useQuery( + const { data = [], isLoading } = useQuery( ['chainInfo', currentWalletState.network], async () => { const url = `/${currentWalletState.network}${process.env.NEXT_PUBLIC_CHAIN_INFO_URL}` const response = await fetch(url) - return await response.json() + + return response.json() }, { enabled: !!currentWalletState.network, diff --git a/hooks/useConnectIBCWallet.ts b/hooks/useConnectIBCWallet.ts index 5d0b647a..86679218 100644 --- a/hooks/useConnectIBCWallet.ts +++ b/hooks/useConnectIBCWallet.ts @@ -1,6 +1,7 @@ -import { GasPrice, SigningStargateClient } from '@cosmjs/stargate' import { useEffect } from 'react' import { useMutation } from 'react-query' + +import { GasPrice, SigningStargateClient } from '@cosmjs/stargate' import { useRecoilState } from 'recoil' import { ibcWalletState, WalletStatusType } from '../state/atoms/walletAtoms' diff --git a/hooks/useConnectKeplr.tsx b/hooks/useConnectKeplr.tsx index e79e6656..09146142 100644 --- a/hooks/useConnectKeplr.tsx +++ b/hooks/useConnectKeplr.tsx @@ -1,17 +1,14 @@ import { GasPrice } from '@cosmjs/stargate' -import { useRecoilState } from 'recoil' import { useConnectedWallet, useWallet } from '@terra-money/wallet-provider' - +import { useChainInfo } from 'hooks/useChainInfo' +import { useRecoilState } from 'recoil' import { walletState, WalletStatusType } from 'state/atoms/walletAtoms' import { OfflineSigningWallet } from 'util/wallet-adapters' -import { useChainInfo } from 'hooks/useChainInfo' -import getChainName from '../libs/getChainName' -import { getSigningInjectiveClient } from 'injectivejs' export default function useConnectKeplr() { const [currentWalletState, setCurrentWalletState] = useRecoilState(walletState) - let [chainInfo] = useChainInfo(currentWalletState.chainId) + const [chainInfo] = useChainInfo(currentWalletState.chainId) const connectedWallet = useConnectedWallet() const { disconnect } = useWallet() @@ -31,7 +28,9 @@ export default function useConnectKeplr() { const offlineSigner = await window.getOfflineSigner( currentWalletState.chainId ) - console.log(`${chainInfo?.gasPriceStep?.low}${chainInfo?.feeCurrencies?.[0].coinMinimalDenom}`) + console.log( + `${chainInfo?.gasPriceStep?.low}${chainInfo?.feeCurrencies?.[0].coinMinimalDenom}` + ) const wasmChainClient = await OfflineSigningWallet.connectWithSigner( currentWalletState.chainId, chainInfo.rpc, @@ -41,7 +40,8 @@ export default function useConnectKeplr() { gasPrice: GasPrice.fromString( `${chainInfo?.gasPriceStep?.low}${chainInfo?.feeCurrencies?.[0].coinMinimalDenom}` ), - } + }, + 'keplr' ) const [{ address }] = await offlineSigner.getAccounts() const key = await window.keplr.getKey(currentWalletState.chainId) diff --git a/hooks/useConnectLeap.tsx b/hooks/useConnectLeap.tsx new file mode 100644 index 00000000..38b695a0 --- /dev/null +++ b/hooks/useConnectLeap.tsx @@ -0,0 +1,74 @@ +import { GasPrice } from '@cosmjs/stargate' +import { useConnectedWallet, useWallet } from '@terra-money/wallet-provider' +import { useChainInfo } from 'hooks/useChainInfo' +import { useRecoilState } from 'recoil' +import { walletState, WalletStatusType } from 'state/atoms/walletAtoms' +import { OfflineSigningWallet } from 'util/wallet-adapters' + +let isConnecting = false + +export default function useConnectLeap() { + const [currentWalletState, setCurrentWalletState] = + useRecoilState(walletState) + const [chainInfo] = useChainInfo(currentWalletState.chainId) + const connectedWallet = useConnectedWallet() + const { disconnect } = useWallet() + + const connectLeap = async () => { + if (isConnecting) return + + if (connectedWallet) { + disconnect() + } + if (window && !window?.leap) { + alert('Please install Leap extension and refresh the page.') + return + } + try { + if (chainInfo !== undefined) { + isConnecting = true + await window.leap.experimentalSuggestChain(chainInfo) + await window.leap.enable(currentWalletState.chainId) + const offlineSigner = await window.leap.getOfflineSigner( + currentWalletState.chainId + ) + const wasmChainClient = await OfflineSigningWallet.connectWithSigner( + currentWalletState.chainId, + chainInfo.rpc, + offlineSigner, + currentWalletState.network, + { + gasPrice: GasPrice.fromString( + `${chainInfo?.gasPriceStep?.low}${chainInfo?.feeCurrencies?.[0].coinMinimalDenom}` + ), + }, + 'leap' + ) + const [{ address }] = await offlineSigner.getAccounts() + const key = await window.leap.getKey(currentWalletState.chainId) + /* successfully update the wallet state */ + setCurrentWalletState({ + key, + address: address, + client: wasmChainClient, + chainId: currentWalletState.chainId, + network: currentWalletState.network, + status: WalletStatusType.connected, + activeWallet: 'leap', + }) + } + } catch (e) { + throw e + } finally { + isConnecting = false + } + } + + const setLeapAndConnect = () => { + setCurrentWalletState({ ...currentWalletState, activeWallet: 'leap' }) + localStorage.removeItem('__terra_extension_router_session__') + connectLeap() + } + + return { connectLeap, setLeapAndConnect } +} diff --git a/hooks/useCosmwasmClient.ts b/hooks/useCosmwasmClient.ts new file mode 100644 index 00000000..de415fdf --- /dev/null +++ b/hooks/useCosmwasmClient.ts @@ -0,0 +1,27 @@ +import { useEffect, useState } from 'react' + +import { CosmWasmClient } from '@cosmjs/cosmwasm-stargate' +import { useChains } from 'hooks/useChainInfo' + +export const useCosmwasmClient = (chainId?: string) => { + const chainInfo = useChains() + const [clients, setClients] = useState({}) + + const getClients = async () => { + const clientList = {} + await Promise.all( + chainInfo.map(async (row) => { + clientList[row.chainId] = await CosmWasmClient.connect(row.rpc) + }) + ) + + if (Object.keys(clientList).length > 0) setClients(clientList) + } + + useEffect(() => { + getClients() + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [chainInfo]) + + return clients[chainId] +} diff --git a/hooks/useDebounceValue.ts b/hooks/useDebounceValue.ts index a5c24c84..3ed64dfc 100644 --- a/hooks/useDebounceValue.ts +++ b/hooks/useDebounceValue.ts @@ -1,4 +1,4 @@ -import { useState, useEffect } from 'react' +import { useEffect, useState } from 'react' const useDebounceValue = (value: T, delay: number) => { // State and setters for debounced value diff --git a/hooks/useIBCTokenBalance.tsx b/hooks/useIBCTokenBalance.tsx index 4baa9dfb..8cabad63 100644 --- a/hooks/useIBCTokenBalance.tsx +++ b/hooks/useIBCTokenBalance.tsx @@ -1,5 +1,6 @@ -import { SigningStargateClient } from '@cosmjs/stargate' import { useQuery } from 'react-query' + +import { SigningStargateClient } from '@cosmjs/stargate' import { useRecoilValue } from 'recoil' import { convertMicroDenomToDenom } from 'util/conversion' @@ -8,14 +9,15 @@ import { DEFAULT_TOKEN_BALANCE_REFETCH_INTERVAL } from '../util/constants' import { useIBCAssetInfo } from './useIBCAssetInfo' export const useIBCTokenBalance = (tokenSymbol) => { - const { address: nativeWalletAddress } = useRecoilValue(walletState) + const { address: nativeWalletAddress, activeWallet } = + useRecoilValue(walletState) const ibcAsset = useIBCAssetInfo(tokenSymbol) const { data: balance = 0, isLoading } = useQuery( [`ibcTokenBalance/${tokenSymbol}`, nativeWalletAddress], async () => { const { denom, decimals, chain_id, rpc } = ibcAsset - await window.keplr.enable(chain_id) + await window[activeWallet].enable(chain_id) const offlineSigner = await window.getOfflineSigner(chain_id) const wasmChainClient = await SigningStargateClient.connectWithSigner( diff --git a/hooks/useQueriesDataSelector.ts b/hooks/useQueriesDataSelector.ts index 5ccc43fa..3a11d40c 100644 --- a/hooks/useQueriesDataSelector.ts +++ b/hooks/useQueriesDataSelector.ts @@ -1,4 +1,3 @@ -import { usePersistance } from 'junoblocks' import { useMemo } from 'react' import { useQueries } from 'react-query' @@ -7,15 +6,12 @@ export function useQueriesDataSelector< >(queriesResult: TQueries) { const [data, isLoading, isError] = useMemo(() => { const loading = queriesResult.some( - ({ isLoading, data }) => isLoading && !data + ({ isLoading: _isLoading, data: _data }) => _isLoading && !_data ) - const error = queriesResult.some(({ isError }) => isError) - + const error = queriesResult.some(({ isError: _isError }) => _isError) const queriesData: Array = queriesResult?.map( - ({ data }) => data + ({ data: _data }) => _data ) - - // const didFetchEveryQuery = !queriesData.includes(undefined) const didFetchEveryQuery = !queriesData.includes(undefined) return [ @@ -25,7 +21,5 @@ export function useQueriesDataSelector< ] as const }, [queriesResult]) - // const persistData = usePersistance(data?.[0] ? data : undefined) - return [data, isLoading, isError] as const } diff --git a/hooks/useRewardsQueries.ts b/hooks/useRewardsQueries.ts index 0500c397..f5656a50 100644 --- a/hooks/useRewardsQueries.ts +++ b/hooks/useRewardsQueries.ts @@ -1,4 +1,5 @@ import { useMutation, useQuery } from 'react-query' + import { useRecoilValue } from 'recoil' import { claimRewards, getPendingRewards } from 'services/rewards' import { walletState, WalletStatusType } from 'state/atoms/walletAtoms' @@ -16,6 +17,23 @@ type UsePendingRewardsArgs = { pool: PoolEntityTypeWithLiquidity } +const useGetTokenInfoByDenom = () => { + const [tokenList] = useTokenList() + return [ + function getTokenInfoByDenom({ denom: tokenDenom }) { + return tokenList.tokens.find(({ denom, token_address }) => { + if ('native' in tokenDenom) { + return tokenDenom.native === denom + } + if ('cw20' in tokenDenom) { + return tokenDenom.cw20 === token_address + } + }) + }, + Boolean(tokenList?.tokens), + ] as const +} + export const usePendingRewards = ({ pool }: UsePendingRewardsArgs) => { const { address, status, client } = useRecoilValue(walletState) @@ -31,7 +49,7 @@ export const usePendingRewards = ({ pool }: UsePendingRewardsArgs) => { `pendingRewards/${pool?.pool_id}/${address}/${shouldQueryRewards}`, async () => { if (shouldQueryRewards) { - return await Promise.all( + return Promise.all( pool.rewards_tokens.map(async ({ rewards_address, decimals }) => { const { pending_rewards, denom } = await getPendingRewards( address, @@ -108,26 +126,9 @@ export const useClaimRewards = ({ pool, ...options }: UseClaimRewardsArgs) => { }) .map(({ rewards_address }) => rewards_address) - return await claimRewards(address, rewardsAddresses, client) + return claimRewards(address, rewardsAddresses, client) } }, options ) } - -const useGetTokenInfoByDenom = () => { - const [tokenList] = useTokenList() - return [ - function getTokenInfoByDenom({ denom: tokenDenom }) { - return tokenList.tokens.find(({ denom, token_address }) => { - if ('native' in tokenDenom) { - return tokenDenom.native === denom - } - if ('cw20' in tokenDenom) { - return tokenDenom.cw20 === token_address - } - }) - }, - Boolean(tokenList?.tokens), - ] as const -} diff --git a/hooks/useSwapInfo.ts b/hooks/useSwapInfo.ts index ae7097a6..9df4471a 100644 --- a/hooks/useSwapInfo.ts +++ b/hooks/useSwapInfo.ts @@ -1,4 +1,5 @@ import { useQuery } from 'react-query' + import { useRecoilValue } from 'recoil' import { usePoolsListQuery } from '../queries/usePoolsListQuery' diff --git a/hooks/useTerraModalOrConnectKeplr.tsx b/hooks/useTerraModalOrConnectKeplr.tsx index d183a76e..7cb66faa 100644 --- a/hooks/useTerraModalOrConnectKeplr.tsx +++ b/hooks/useTerraModalOrConnectKeplr.tsx @@ -1,16 +1,16 @@ -import { useRecoilValue } from 'recoil' - -import { walletState } from 'state/atoms/walletAtoms' import { useChainInfo } from 'hooks/useChainInfo' import useConnectKeplr from 'hooks/useConnectKeplr' +import { useRecoilValue } from 'recoil' +import { walletState } from 'state/atoms/walletAtoms' export default function useTerraModalOrConnectKeplr(onOpenModal) { const { chainId } = useRecoilValue(walletState) - let [chainInfo] = useChainInfo(chainId) + const [chainInfo] = useChainInfo(chainId) const { setKeplrAndConnect } = useConnectKeplr() const showTerraModalOrConnectKeplr = () => { - chainInfo.label === 'Terra' ? onOpenModal() : setKeplrAndConnect() + if (chainInfo?.label === 'Terra') onOpenModal() + else setKeplrAndConnect() } return { showTerraModalOrConnectKeplr } diff --git a/hooks/useTerraStation.tsx b/hooks/useTerraStation.tsx index 8e09bb4c..eebbcb11 100644 --- a/hooks/useTerraStation.tsx +++ b/hooks/useTerraStation.tsx @@ -1,15 +1,15 @@ import { useEffect } from 'react' -import { useRecoilState } from 'recoil' + +import { LCDClient } from '@terra-money/terra.js' import { Connection, ConnectType, useConnectedWallet, useWallet, } from '@terra-money/wallet-provider' -import { LCDClient } from '@terra-money/terra.js' - -import { TerraStationWallet } from 'util/wallet-adapters/terraStationWallet' +import { useRecoilState } from 'recoil' import { walletState, WalletStatusType } from 'state/atoms/walletAtoms' +import { TerraStationWallet } from 'util/wallet-adapters/terraStationWallet' export const useTerraStation = (onCloseModal) => { const { connect } = useWallet() @@ -53,6 +53,7 @@ export const useTerraStation = (onCloseModal) => { client: wasmChainClient, activeWallet: 'station', }) + // eslint-disable-next-line react-hooks/exhaustive-deps }, [connectedWallet, currentWalletState.network]) return { connectTerraAndCloseModal, filterForStation } diff --git a/hooks/useTokenBalance.tsx b/hooks/useTokenBalance.tsx index af03e022..17c6c8e4 100644 --- a/hooks/useTokenBalance.tsx +++ b/hooks/useTokenBalance.tsx @@ -1,5 +1,7 @@ import { useMemo } from 'react' import { useQuery } from 'react-query' + +import useConnectKeplr from 'hooks/useConnectKeplr' import { useRecoilValue } from 'recoil' import { convertMicroDenomToDenom } from 'util/conversion' @@ -7,11 +9,11 @@ import { CW20 } from '../services/cw20' import { walletState, WalletStatusType } from '../state/atoms/walletAtoms' import { DEFAULT_TOKEN_BALANCE_REFETCH_INTERVAL } from '../util/constants' import { Wallet } from '../util/wallet-adapters' +import useConnectLeap from './useConnectLeap' import { getIBCAssetInfoFromList, useIBCAssetInfo } from './useIBCAssetInfo' import { IBCAssetInfo, useIBCAssetList } from './useIbcAssetList' import { getTokenInfoFromTokenList, useTokenInfo } from './useTokenInfo' import { useTokenList } from './useTokenList' -import useConnectKeplr from 'hooks/useConnectKeplr' async function fetchTokenBalance({ client, @@ -79,8 +81,13 @@ export const useTokenBalance = (tokenSymbol: string) => { useRecoilValue(walletState) // TODO: Adding this fixes the issue where refresh means no client const { connectKeplr } = useConnectKeplr() + const { connectLeap } = useConnectLeap() if (!client && status == '@wallet-state/restored') { - connectKeplr() + if (activeWallet === 'leap') { + connectLeap() + } else { + connectKeplr() + } } const tokenInfo = useTokenInfo(tokenSymbol) const ibcAssetInfo = useIBCAssetInfo(tokenSymbol) @@ -92,7 +99,7 @@ export const useTokenBalance = (tokenSymbol: string) => { ['tokenBalance', tokenSymbol, address, network], async ({ queryKey: [, symbol] }) => { // if (tokenSymbol && client && (tokenInfo || ibcAssetInfo)) { - return await fetchTokenBalance({ + return fetchTokenBalance({ client, address, token: tokenInfo || ibcAssetInfo, diff --git a/hooks/useTokenDollarValue.tsx b/hooks/useTokenDollarValue.tsx index b567293f..53e8b422 100644 --- a/hooks/useTokenDollarValue.tsx +++ b/hooks/useTokenDollarValue.tsx @@ -1,6 +1,7 @@ -import { usePriceForOneToken } from 'features/swap' import { useQuery } from 'react-query' +import { usePriceForOneToken } from 'features/swap' + import { tokenDollarValueQuery } from '../queries/tokenDollarValueQuery' import { DEFAULT_TOKEN_BALANCE_REFETCH_INTERVAL } from '../util/constants' import { useGetMultipleIBCAssetInfo } from './useIBCAssetInfo' @@ -10,6 +11,39 @@ import { useTokenInfo, } from './useTokenInfo' +export const useTokenDollarValueQuery = ( + tokenSymbols?: Array, + chainId?: string +) => { + const getMultipleTokenInfo = useGetMultipleTokenInfo() + const getMultipleIBCAssetInfo = useGetMultipleIBCAssetInfo() + + const { data, isLoading } = useQuery( + `tokenDollarValue/${tokenSymbols?.join('/')}`, + async (): Promise> => { + const tokenIds = tokenSymbols?.map( + (tokenSymbol) => + ( + getMultipleTokenInfo([tokenSymbol])?.[0] || + getMultipleIBCAssetInfo([tokenSymbol])?.[0] + )?.id + ) + + if (tokenIds) { + return tokenDollarValueQuery(tokenIds) + } + }, + { + enabled: Boolean(tokenSymbols?.length), + refetchOnMount: 'always', + refetchInterval: DEFAULT_TOKEN_BALANCE_REFETCH_INTERVAL, + refetchIntervalInBackground: true, + } + ) + + return [data || [], isLoading] as const +} + export const useTokenDollarValue = (tokenSymbol?: string) => { const { symbol: baseTokenSymbol } = useBaseTokenInfo() || {} const tokenInfo = useTokenInfo(tokenSymbol) @@ -46,36 +80,3 @@ export const useTokenDollarValue = (tokenSymbol?: string) => { fetchingTokenDollarPrice || fetchingTokenToTokenPrice, ] as const } - -export const useTokenDollarValueQuery = ( - tokenSymbols?: Array, - chainId?: string -) => { - const getMultipleTokenInfo = useGetMultipleTokenInfo() - const getMultipleIBCAssetInfo = useGetMultipleIBCAssetInfo() - - const { data, isLoading } = useQuery( - `tokenDollarValue/${tokenSymbols?.join('/')}`, - async (): Promise> => { - const tokenIds = tokenSymbols?.map( - (tokenSymbol) => - ( - getMultipleTokenInfo([tokenSymbol])?.[0] || - getMultipleIBCAssetInfo([tokenSymbol])?.[0] - )?.id - ) - - if (tokenIds) { - return tokenDollarValueQuery(tokenIds, chainId) - } - }, - { - enabled: Boolean(tokenSymbols?.length), - refetchOnMount: 'always', - refetchInterval: DEFAULT_TOKEN_BALANCE_REFETCH_INTERVAL, - refetchIntervalInBackground: true, - } - ) - - return [data || [], isLoading] as const -} diff --git a/hooks/useTokenList.ts b/hooks/useTokenList.ts index 84f78be0..ace8a508 100644 --- a/hooks/useTokenList.ts +++ b/hooks/useTokenList.ts @@ -1,4 +1,5 @@ import { useQuery } from 'react-query' + import { useRecoilValue } from 'recoil' import { walletState } from 'state/atoms/walletAtoms' diff --git a/pages/[chainId]/flashloan.tsx b/pages/[chainId]/flashloan.tsx new file mode 100644 index 00000000..623b75aa --- /dev/null +++ b/pages/[chainId]/flashloan.tsx @@ -0,0 +1,5 @@ +import Flashloan from 'components/Pages/Flashloan' + +const FlashloanPage = () => + +export default FlashloanPage diff --git a/pages/[chainId]/pools/index.tsx b/pages/[chainId]/pools/index.tsx new file mode 100644 index 00000000..2da99ccc --- /dev/null +++ b/pages/[chainId]/pools/index.tsx @@ -0,0 +1,5 @@ +import Pools from 'components/Pages/Pools' + +const PoolsPage = () => + +export default PoolsPage diff --git a/pages/[chainId]/pools/manage_liquidity.tsx b/pages/[chainId]/pools/manage_liquidity.tsx new file mode 100644 index 00000000..abfcb125 --- /dev/null +++ b/pages/[chainId]/pools/manage_liquidity.tsx @@ -0,0 +1,5 @@ +import ManageLiquidity from 'components/Pages/ManageLiquidity' + +const ManageLiquidityPage = () => + +export default ManageLiquidityPage diff --git a/pages/[chainId]/pools/new_position.tsx b/pages/[chainId]/pools/new_position.tsx new file mode 100644 index 00000000..1e39f512 --- /dev/null +++ b/pages/[chainId]/pools/new_position.tsx @@ -0,0 +1,5 @@ +import NewPosition from 'components/Pages/NewPosition' + +const NewPositionPage = () => + +export default NewPositionPage diff --git a/pages/[chainId]/swap.tsx b/pages/[chainId]/swap.tsx new file mode 100644 index 00000000..0faf3087 --- /dev/null +++ b/pages/[chainId]/swap.tsx @@ -0,0 +1,14 @@ +import Swap from 'components/Pages/Swap' + +function getInitialTokenPairFromSearchParams() { + const params = new URLSearchParams(location.search) + const from = params.get('from')?.toUpperCase() + const to = params.get('to')?.toUpperCase() + return from || to ? ([from, to] as const) : undefined +} + +const SwapPage = () => ( + +) + +export default SwapPage diff --git a/pages/[chainId]/vaults/index.tsx b/pages/[chainId]/vaults/index.tsx new file mode 100644 index 00000000..9a1056eb --- /dev/null +++ b/pages/[chainId]/vaults/index.tsx @@ -0,0 +1,5 @@ +import Vaults from 'components/Vaults' + +const VaultsPage = () => + +export default VaultsPage diff --git a/pages/[chainId]/vaults/manage_position.tsx b/pages/[chainId]/vaults/manage_position.tsx new file mode 100644 index 00000000..255451cf --- /dev/null +++ b/pages/[chainId]/vaults/manage_position.tsx @@ -0,0 +1,5 @@ +import ManagePoistion from 'components/Vaults/ManagePoistion' + +const ManagePositionPage = () => + +export default ManagePositionPage diff --git a/pages/[chainId]/vaults/new_position.tsx b/pages/[chainId]/vaults/new_position.tsx new file mode 100644 index 00000000..ef415352 --- /dev/null +++ b/pages/[chainId]/vaults/new_position.tsx @@ -0,0 +1,5 @@ +import NewPoistion from 'components/Vaults/NewPosition' + +const NewPositionPage = () => + +export default NewPositionPage diff --git a/pages/index.tsx b/pages/index.tsx index 7edd25ea..f513f0eb 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -1,15 +1,16 @@ import { useEffect } from 'react' -import { useRouter } from 'next/router' +import { NextRouter, useRouter } from 'next/router' -const index = () => { - const router = useRouter() +const Index = () => { + const router: NextRouter = useRouter() useEffect(() => { router.replace('/swap') + // eslint-disable-next-line react-hooks/exhaustive-deps }, []) return
} -export default index +export default Index diff --git a/public/img/leap-wallet.svg b/public/img/leap-wallet.svg new file mode 100644 index 00000000..a12191a6 --- /dev/null +++ b/public/img/leap-wallet.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/public/mainnet/chain_info.json b/public/mainnet/chain_info.json index 0c178551..9a569b15 100644 --- a/public/mainnet/chain_info.json +++ b/public/mainnet/chain_info.json @@ -236,15 +236,15 @@ "coinGeckoId": "comdex", "gasPriceStep": { "low": 0.25, - "average": 0.50, - "high": 1.00 + "average": 0.5, + "high": 1.0 } } ], "gasPriceStep": { "low": 0.25, - "average": 0.50, - "high": 1.00 + "average": 0.5, + "high": 1.0 }, "coinType": 60, "features": ["ibc-transfer", "ibc-go"], diff --git a/public/mainnet/injective-1/pools_list.json b/public/mainnet/injective-1/pools_list.json index 21eee31a..5eb030eb 100644 --- a/public/mainnet/injective-1/pools_list.json +++ b/public/mainnet/injective-1/pools_list.json @@ -28,7 +28,7 @@ "lpOrder": ["INJ", "USDT"], "displayName": "INJ-USDT", "displayLogo1": "/logos/injective.png", - "displayLogo2": "/logos/usdt.png", + "displayLogo2": "/logos/usdt.png", "pool_assets": [ { "chain_id": "injective-1", @@ -64,7 +64,7 @@ "lpOrder": ["ATOM", "USDT"], "displayName": "ATOM-USDT", "displayLogo1": "/logos/atom.png", - "displayLogo2": "/logos/usdt.png", + "displayLogo2": "/logos/usdt.png", "pool_assets": [ { "chain_id": "injective-1", diff --git a/public/mainnet/juno-1/pools_list.json b/public/mainnet/juno-1/pools_list.json index 2c29b39a..0bf26919 100644 --- a/public/mainnet/juno-1/pools_list.json +++ b/public/mainnet/juno-1/pools_list.json @@ -23,48 +23,12 @@ }, "routerAddress": "juno128lewlw6kv223uw4yzdffl8rnh3k9qs8vrf6kef28579w8ygccyq7m90n2", "pools": [ - { - "pool_id": "ATOM-LUNA", - "lpOrder": ["LUNA", "ATOM"], - "displayName" : "LUNA-ATOM", - "displayLogo1" : "/logos/luna.svg", - "displayLogo2" : "/logos/atom.png", - "pool_assets": [ - { - "id": "cosmos", - "chain_id": "juno-1", - "token_address": "ibc/C4CFF46FD6DE35CA4CF4CE031E643C8FDC9BA4B99AE598E9B0ED98FE3A2319F9", - "symbol": "ATOM", - "name": "Atom", - "decimals": 6, - "logoURI": "/logos/atom.png", - "tags": ["native"], - "native": true, - "denom": "ibc/C4CFF46FD6DE35CA4CF4CE031E643C8FDC9BA4B99AE598E9B0ED98FE3A2319F9" - }, - { - "chain_id": "juno-1", - "token_address": "ibc/107D152BB3176FAEBF4C2A84C5FFDEEA7C7CB4FE1BBDAB710F1FD25BCD055CBF", - "symbol": "LUNA", - "name": "Luna", - "decimals": 6, - "logoURI": "/logos/luna.svg", - "tags": ["native"], - "native": true, - "denom": "ibc/107D152BB3176FAEBF4C2A84C5FFDEEA7C7CB4FE1BBDAB710F1FD25BCD055CBF" - } - ], - "lp_token": "juno1fkejwm7alyfnjngtpgtxvreqfcz8uwer2jgwjn40suvgq20tm8ss73cj05", - "swap_address": "juno1k9cw9yghf04cqlu290n4zlveker5cev5ahweqkh07y7zc3xq9hrshjruk8", - "staking_address": "", - "rewards_tokens": [] - }, { "pool_id": "ATOM-JUNO", "lpOrder": ["ATOM", "JUNO"], - "displayName" : "JUNO-ATOM", - "displayLogo1" : "/logos/juno.svg", - "displayLogo2" : "/logos/atom.png", + "displayName": "JUNO-ATOM", + "displayLogo1": "/logos/juno.svg", + "displayLogo2": "/logos/atom.png", "pool_assets": [ { "id": "cosmos", @@ -99,9 +63,9 @@ { "pool_id": "ATOM-axlUSDC", "lpOrder": ["ATOM", "axlUSDC"], - "displayName" : "ATOM-axlUSDC", - "displayLogo1" : "/logos/atom.png", - "displayLogo2" : "/logos/axlUSDC.png", + "displayName": "ATOM-axlUSDC", + "displayLogo1": "/logos/atom.png", + "displayLogo2": "/logos/axlUSDC.png", "pool_assets": [ { "id": "cosmos", @@ -132,83 +96,12 @@ "staking_address": "", "rewards_tokens": [] }, - { - "pool_id": "JUNO-RAW", - "lpOrder": ["JUNO", "RAW"], - "displayName" : "RAW-JUNO", - "displayLogo1" : "/logos/raw.png", - "displayLogo2" : "/logos/juno.svg", - "pool_assets": [ - { - "id": "juno-network", - "chain_id": "juno-1", - "token_address": "ujuno", - "symbol": "JUNO", - "name": "Juno", - "decimals": 6, - "logoURI": "/logos/juno.svg", - "tags": ["native"], - "native": true, - "denom": "ujuno" - }, - { - "chain_id": "juno-1", - "token_address": "juno15u3dt79t6sxxa3x3kpkhzsy56edaa5a66wvt3kxmukqjz2sx0hes5sn38g", - "symbol": "RAW", - "name": "Raw", - "decimals": 6, - "logoURI": "/logos/raw.png", - "tags": [], - "native": false, - "denom": "juno15u3dt79t6sxxa3x3kpkhzsy56edaa5a66wvt3kxmukqjz2sx0hes5sn38g" - } - ], - "lp_token": "juno1zetjfu8j0ndt4d3mgewhatgpfrj8pwhev2tdp3sa9dwwmqlgdxws4257we", - "swap_address": "juno1xpt9mkncxadadn5t8s4t74nmw5zlarghmpme26857s07xz388d6sukvtnz", - "staking_address": "", - "rewards_tokens": [] - }, - { - "pool_id": "JUNO-LOOP", - "displayName" : "LOOP-JUNO", - "displayLogo1" : "/logos/loop.png", - "displayLogo2" : "/logos/juno.svg", - "pool_assets": [ - { - "id": "juno-network", - "chain_id": "juno-1", - "token_address": "ujuno", - "symbol": "JUNO", - "name": "Juno", - "decimals": 6, - "logoURI": "/logos/juno.svg", - "tags": ["native"], - "native": true, - "denom": "ujuno" - }, - { - "chain_id": "juno-1", - "token_address": "juno1qsrercqegvs4ye0yqg93knv73ye5dc3prqwd6jcdcuj8ggp6w0us66deup", - "symbol": "LOOP", - "name": "Loop", - "decimals": 6, - "logoURI": "/logos/loop.png", - "tags": [], - "native": false, - "denom": "juno1qsrercqegvs4ye0yqg93knv73ye5dc3prqwd6jcdcuj8ggp6w0us66deup" - } - ], - "lp_token": "juno1zmsgdpdej4g4m4fc5y5p6wr8gn6peh9vx5dk5vf7v7w32jjmcetshl0yw4", - "swap_address": "juno158mcxa5ajpjfxgy60asrg3m0823m2el5n333xdypcw8h5uwhuvyqkyc4a7", - "staking_address": "", - "rewards_tokens": [] - }, { "pool_id": "JUNO-axlUSDC", - "lpOrder": ["JUNO", "axlUSDC"], - "displayName" : "JUNO-axlUSDC", - "displayLogo1" : "/logos/juno.svg", - "displayLogo2" : "/logos/axlUSDC.png", + "lpOrder": ["axlUSDC", "JUNO"], + "displayName": "JUNO-axlUSDC", + "displayLogo1": "/logos/juno.svg", + "displayLogo2": "/logos/axlUSDC.png", "pool_assets": [ { "id": "juno-network", diff --git a/public/mainnet/phoenix-1/pools_list.json b/public/mainnet/phoenix-1/pools_list.json index 099716ba..aa96c81a 100644 --- a/public/mainnet/phoenix-1/pools_list.json +++ b/public/mainnet/phoenix-1/pools_list.json @@ -1,9 +1,7 @@ { "name": "Pools list on mainnet", "logoURI": "/img/logo.svg", - "keywords": [ - "special tokens" - ], + "keywords": ["special tokens"], "tags": { "ProjectName": { "name": "White Whale", @@ -19,9 +17,7 @@ "name": "Luna", "decimals": 6, "logoURI": "/logos/luna.svg", - "tags": [ - "native" - ], + "tags": ["native"], "native": true, "denom": "uluna" }, @@ -29,10 +25,7 @@ "pools": [ { "pool_id": "ATOM-LUNA", - "lpOrder": [ - "ATOM", - "LUNA" - ], + "lpOrder": ["ATOM", "LUNA"], "displayName": "LUNA-ATOM", "displayLogo1": "/logos/luna.svg", "displayLogo2": "/logos/atom.png", @@ -45,9 +38,7 @@ "name": "Atom", "decimals": 6, "logoURI": "/logos/atom.png", - "tags": [ - "native" - ], + "tags": ["native"], "native": true, "denom": "ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2" }, @@ -59,9 +50,7 @@ "name": "Luna", "decimals": 6, "logoURI": "/logos/luna.svg", - "tags": [ - "native" - ], + "tags": ["native"], "native": true, "denom": "uluna" } @@ -71,55 +60,9 @@ "staking_address": "", "rewards_tokens": [] }, - { - "pool_id": "ATOM-JUNO", - "lpOrder": [ - "ATOM", - "JUNO" - ], - "displayName": "JUNO-ATOM", - "displayLogo1": "/logos/juno.svg", - "displayLogo2": "/logos/atom.png", - "pool_assets": [ - { - "id": "cosmos", - "chain_id": "phoenix-1", - "token_address": "ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2", - "symbol": "ATOM", - "name": "Atom", - "decimals": 6, - "logoURI": "/logos/atom.png", - "tags": [ - "native" - ], - "native": true, - "denom": "ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2" - }, - { - "chain_id": "phoenix-1", - "token_address": "ibc/4CD525F166D32B0132C095F353F4C6F033B0FF5C49141470D1EFDA1D63303D04", - "symbol": "JUNO", - "name": "Juno", - "decimals": 6, - "logoURI": "/logos/juno.svg", - "tags": [ - "native" - ], - "native": true, - "denom": "ibc/4CD525F166D32B0132C095F353F4C6F033B0FF5C49141470D1EFDA1D63303D04" - } - ], - "lp_token": "terra1avfsch3ee82wyrpwlawecyz6zktr9jln0zaxp58xuvmxyl5g305q3rwuj3", - "swap_address": "terra1p2xgcr2ewnetug8ahqms5y3k6rxyh2xglnzzx500ylh4420h9ucqz8w7x5", - "staking_address": "", - "rewards_tokens": [] - }, { "pool_id": "ATOM-axlUSDC", - "lpOrder": [ - "ATOM", - "axlUSDC" - ], + "lpOrder": ["ATOM", "axlUSDC"], "displayName": "ATOM-axlUSDC", "displayLogo1": "/logos/atom.png", "displayLogo2": "/logos/axlUSDC.png", @@ -132,9 +75,7 @@ "name": "Atom", "decimals": 6, "logoURI": "/logos/atom.png", - "tags": [ - "native" - ], + "tags": ["native"], "native": true, "denom": "ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2" }, @@ -145,9 +86,7 @@ "name": "axlUSDC", "decimals": 6, "logoURI": "/logos/axlUSDC.png", - "tags": [ - "native" - ], + "tags": ["native"], "native": true, "denom": "ibc/B3504E092456BA618CC28AC671A71FB08C6CA0FD0BE7C8A5B5A3E2DD933CC9E4" } @@ -157,43 +96,6 @@ "staking_address": "", "rewards_tokens": [] }, - { - "pool_id": "LUNA-LUNAX", - "displayName": "LUNAX-LUNA", - "displayLogo1": "/logos/lunax.png", - "displayLogo2": "/logos/luna.svg", - "pool_assets": [ - { - "id": "terra-luna-2", - "chain_id": "phoenix-1", - "token_address": "uluna", - "symbol": "LUNA", - "name": "Luna", - "decimals": 6, - "logoURI": "/logos/luna.svg", - "tags": [ - "native" - ], - "native": true, - "denom": "uluna" - }, - { - "chain_id": "phoenix-1", - "token_address": "terra14xsm2wzvu7xaf567r693vgfkhmvfs08l68h4tjj5wjgyn5ky8e2qvzyanh", - "symbol": "LUNAX", - "name": "LunaX", - "decimals": 6, - "logoURI": "/logos/lunax.png", - "tags": [], - "native": false, - "denom": "terra14xsm2wzvu7xaf567r693vgfkhmvfs08l68h4tjj5wjgyn5ky8e2qvzyanh" - } - ], - "lp_token": "terra1lt586fhwyuccktk58v8k96ugzp9szurhqvmlnjxhyn6yapa6v2jsmc468d", - "swap_address": "terra1qzux5j9he9nv95kq3unkuzy0hddf080um2t243raatg3f6requwsaahpqp", - "staking_address": "", - "rewards_tokens": [] - }, { "pool_id": "LUNA-ASTRO", "displayName": "ASTRO-LUNA", @@ -208,9 +110,7 @@ "name": "Luna", "decimals": 6, "logoURI": "/logos/luna.svg", - "tags": [ - "native" - ], + "tags": ["native"], "native": true, "denom": "uluna" }, @@ -233,10 +133,7 @@ }, { "pool_id": "LUNA-axlUSDC", - "lpOrder": [ - "axlUSDC", - "LUNA" - ], + "lpOrder": ["axlUSDC", "LUNA"], "displayName": "LUNA-axlUSDC", "displayLogo1": "/logos/luna.svg", "displayLogo2": "/logos/axlUSDC.png", @@ -249,9 +146,7 @@ "name": "Luna", "decimals": 6, "logoURI": "/logos/luna.svg", - "tags": [ - "native" - ], + "tags": ["native"], "native": true, "denom": "uluna" }, @@ -262,9 +157,7 @@ "name": "axlUSDC", "decimals": 6, "logoURI": "/logos/axlUSDC.png", - "tags": [ - "native" - ], + "tags": ["native"], "native": true, "denom": "ibc/B3504E092456BA618CC28AC671A71FB08C6CA0FD0BE7C8A5B5A3E2DD933CC9E4" } @@ -280,4 +173,4 @@ "minor": 1, "patch": 0 } -} \ No newline at end of file +} diff --git a/public/testnet/chain_info.json b/public/testnet/chain_info.json index 1f96603e..2af3410b 100644 --- a/public/testnet/chain_info.json +++ b/public/testnet/chain_info.json @@ -186,15 +186,15 @@ "coinDecimals": 6, "gasPriceStep": { "low": 0.25, - "average": 0.50, - "high": 1.00 + "average": 0.5, + "high": 1.0 } } ], "gasPriceStep": { "low": 0.25, - "average": 0.50, - "high": 1.00 + "average": 0.5, + "high": 1.0 }, "coinType": 118, "beta": true diff --git a/queries/querySwapInfo.ts b/queries/querySwapInfo.ts index 07860e5d..805753e7 100644 --- a/queries/querySwapInfo.ts +++ b/queries/querySwapInfo.ts @@ -3,6 +3,7 @@ import { getSwapInfo } from '../services/swap' export async function querySwapInfo({ context: { client }, swap_address }) { const swap = await getSwapInfo(swap_address, client) const [asset1, asset2] = swap?.assets || [] + return { ...swap, swap_address, diff --git a/queries/useGetTokenDollarValueQuery.ts b/queries/useGetTokenDollarValueQuery.ts index 3445af2e..e71e7990 100644 --- a/queries/useGetTokenDollarValueQuery.ts +++ b/queries/useGetTokenDollarValueQuery.ts @@ -2,6 +2,7 @@ * takes base token price, fetches the ratio of the token provided vs the base token * and calculates the dollar value of the provided token * */ +import { useCosmwasmClient } from 'hooks/useCosmwasmClient' import { useRecoilValue } from 'recoil' import { useTokenDollarValue } from '../hooks/useTokenDollarValue' @@ -12,7 +13,9 @@ import { useGetQueryMatchingPoolForSwap } from './useQueryMatchingPoolForSwap' export const useGetTokenDollarValueQuery = () => { const tokenA = useBaseTokenInfo() - const { client } = useRecoilValue(walletState) + const { chainId } = useRecoilValue(walletState) + const client = useCosmwasmClient(chainId) + const [tokenADollarPrice, fetchingDollarPrice] = useTokenDollarValue( tokenA?.symbol ) diff --git a/queries/useQueryPools.ts b/queries/useQueryPools.ts index 114b1864..02fe52b6 100644 --- a/queries/useQueryPools.ts +++ b/queries/useQueryPools.ts @@ -1,6 +1,8 @@ -import { protectAgainstNaN, usePersistance } from 'junoblocks' import { useMemo } from 'react' import { useQueries } from 'react-query' + +import { useCosmwasmClient } from 'hooks/useCosmwasmClient' +import { protectAgainstNaN, usePersistance } from 'junoblocks' import { useRecoilValue } from 'recoil' import { walletState } from '../state/atoms/walletAtoms' @@ -52,37 +54,36 @@ export type PoolLiquidityState = { } export type PoolEntityTypeWithLiquidity = PoolEntityType & { - liquidity: PoolLiquidityState + liquidity?: PoolLiquidityState } type QueryMultiplePoolsArgs = { pools: Array refetchInBackground?: boolean + client: any } export const useQueryMultiplePoolsLiquidity = ({ pools, refetchInBackground = false, + client, }: QueryMultiplePoolsArgs) => { const [getTokenDollarValue, enabledGetTokenDollarValue] = useGetTokenDollarValueQuery() - - const { - address, - client: signingClient, - chainId, - } = useRecoilValue(walletState) - // const client = useCosmWasmClient() + const { address } = useRecoilValue(walletState) const context = { - client: signingClient, - signingClient, + // client: signingClient, + client, + signingClient: client, getTokenDollarValue, } async function queryPoolLiquidity( pool: PoolEntityType ): Promise { + if (!client) return pool + const [tokenA] = pool.pool_assets const swap = await querySwapInfo({ @@ -201,10 +202,7 @@ export const useQueryMultiplePoolsLiquidity = ({ return useQueries( (pools ?? []).map((pool) => ({ queryKey: `@pool-liquidity/${pool.pool_id}/${address}`, - enabled: Boolean( - !!signingClient && pool.pool_id && enabledGetTokenDollarValue - ), - + enabled: Boolean(!!client && pool.pool_id && enabledGetTokenDollarValue), refetchOnMount: false as const, refetchInterval: refetchInBackground ? DEFAULT_TOKEN_BALANCE_REFETCH_INTERVAL @@ -212,7 +210,8 @@ export const useQueryMultiplePoolsLiquidity = ({ refetchIntervalInBackground: refetchInBackground, async queryFn() { - return await queryPoolLiquidity(pool) + if (!client) return pool + return queryPoolLiquidity(pool) }, })) ) @@ -221,6 +220,8 @@ export const useQueryMultiplePoolsLiquidity = ({ export const useQueryPoolLiquidity = ({ poolId }) => { const { data: poolsListResponse, isLoading: loadingPoolsList } = usePoolsListQuery() + const { chainId } = useRecoilValue(walletState) + const client = useCosmwasmClient(chainId) const poolToFetch = useMemo(() => { const pool = poolsListResponse?.poolsById[poolId] @@ -230,6 +231,7 @@ export const useQueryPoolLiquidity = ({ poolId }) => { const [poolResponse] = useQueryMultiplePoolsLiquidity({ pools: poolToFetch, refetchInBackground: true, + client, }) // const persistedData = usePersistance(poolResponse?.data) diff --git a/services/injective.ts b/services/injective.ts index 0958e3dd..83bac9db 100644 --- a/services/injective.ts +++ b/services/injective.ts @@ -1,32 +1,33 @@ import { + Coin, + EncodeObject, + OfflineDirectSigner, + OfflineSigner, +} from '@cosmjs/proto-signing' +import { StdFee } from '@cosmjs/stargate' +import { getNetworkEndpoints, Network } from '@injectivelabs/networks' +import { + BaseAccount, ChainGrpcWasmApi, - TxRestClient, - ChainRestBankApi, - createTransaction, ChainRestAuthApi, + ChainRestBankApi, ChainRestTendermintApi, - BaseAccount, - createTxRawFromSigResponse, createCosmosSignDocFromTransaction, + createTransaction, + createTxRawFromSigResponse, TxRaw, + TxRestClient, } from '@injectivelabs/sdk-ts' +import { MsgExecuteContract, MsgSend } from '@injectivelabs/sdk-ts' +import { AccountDetails } from '@injectivelabs/sdk-ts/dist/types/auth' +import { ChainId } from '@injectivelabs/ts-types' import { - DEFAULT_STD_FEE, - DEFAULT_BLOCK_TIMEOUT_HEIGHT, BigNumberInBase, + DEFAULT_BLOCK_TIMEOUT_HEIGHT, + DEFAULT_STD_FEE, } from '@injectivelabs/utils' -import { ChainId } from '@injectivelabs/ts-types' -import { Network, getNetworkEndpoints } from '@injectivelabs/networks' -import { MsgExecuteContract, MsgSend } from '@injectivelabs/sdk-ts' -import { - Coin, - EncodeObject, - OfflineDirectSigner, - OfflineSigner, -} from '@cosmjs/proto-signing' -import { AccountDetails } from '@injectivelabs/sdk-ts/dist/types/auth' + import { base64ToJson } from '../util/base64' -import { StdFee } from '@cosmjs/stargate' const HIGHER_DEFAULT_GAS_LIMIT = '2000000' @@ -50,19 +51,31 @@ type SimulateResponse = { class Injective { txClient: TxRestClient + wasmApi: ChainGrpcWasmApi + bankApi: ChainRestBankApi + offlineSigner: OfflineSigner & OfflineDirectSigner + pubKey: string + baseAccount: BaseAccount + account: AccountDetails + chainId: ChainId + txRaw: TxRaw + network: Network + activeWallet: string + constructor( offlineSigner: OfflineSigner & OfflineDirectSigner, - network: Network = Network.TestnetK8s + network: Network = Network.TestnetK8s, + activeWallet: string ) { const endpoints = getNetworkEndpoints(network) @@ -73,11 +86,12 @@ class Injective { this.chainId = network === Network.TestnetK8s ? ChainId.Testnet : ChainId.Mainnet this.network = network + this.activeWallet = activeWallet this.init() } async init() { - const key = await window.keplr.getKey(this.chainId) + const key = await window[this.activeWallet].getKey(this.chainId) this.pubKey = Buffer.from(key.pubKey).toString('base64') const restEndpoint = getNetworkEndpoints(this.network).rest const chainRestAuthApi = new ChainRestAuthApi(restEndpoint) @@ -144,7 +158,7 @@ class Injective { } } - async prepair(messages: EncodeObject[], send: boolean = true) { + async prepair(messages: EncodeObject[], send = true) { try { await this.init() const restEndpoint = getNetworkEndpoints(this.network).rest @@ -320,7 +334,7 @@ class Injective { ) const signTxRaw = createTxRawFromSigResponse(directSignResponse) this.txRaw = null - return this.txClient.broadcast(signTxRaw).then((result) => { + return await this.txClient.broadcast(signTxRaw).then((result) => { console.log({ result }) if (!!result.code) { throw new Error( diff --git a/services/queryClient.ts b/services/queryClient.ts index f0c5ff1b..24770009 100644 --- a/services/queryClient.ts +++ b/services/queryClient.ts @@ -1,4 +1,5 @@ import { QueryClient } from 'react-query' + import { DEFAULT_REFETCH_ON_WINDOW_FOCUS_STALE_TIME } from '../util/constants' export const queryClient = new QueryClient({ diff --git a/state/atoms/walletAtoms.ts b/state/atoms/walletAtoms.ts index de94a844..e7c5da8f 100644 --- a/state/atoms/walletAtoms.ts +++ b/state/atoms/walletAtoms.ts @@ -42,10 +42,11 @@ function createWalletState({ default: { status: WalletStatusType.idle, client: null, - chainId: 'juno-1', + // chainId: 'juno-1', + chainId: null, address: '', network: 'mainnet', - activeWallet: 'keplr', + activeWallet: '', ...defaultState, }, dangerouslyAllowMutability: true, diff --git a/types/window.d.ts b/types/window.d.ts index 6f40f80f..36ddf690 100644 --- a/types/window.d.ts +++ b/types/window.d.ts @@ -1,5 +1,6 @@ import { Window as KeplrWindow } from '@keplr-wallet/types' declare global { - // eslint-disable-next-line - interface Window extends KeplrWindow {} + interface Window extends KeplrWindow { + leap: Keplr + } } diff --git a/util/chain.ts b/util/chain.ts new file mode 100644 index 00000000..5b991606 --- /dev/null +++ b/util/chain.ts @@ -0,0 +1,15 @@ +export const validChains = { + mainnet: { + juno: 'juno-1', + terra: 'phoenix-1', + chihuahua: 'chihuahua-1', + injective: 'injective-1', + comdex: 'comdex-1', + }, + testnet: { + juno: 'uni-3', + terra: 'pisco-1', + injective: 'injective-888', + comdex: 'comdex-test2', + }, +} diff --git a/util/coinhall.ts b/util/coinhall.ts index f4896f7e..bbc2bd9d 100644 --- a/util/coinhall.ts +++ b/util/coinhall.ts @@ -31,7 +31,7 @@ export const getPairApryAnd24HrVolume = async (pairs: string[]) => { apr7d: pairInfo?.apr7d || 0, asset0Price: pairInfo?.asset0.usdPrice, asset1Price: pairInfo?.asset1.usdPrice, - isUSDCPool: + isUSDPool: pairInfo?.asset0.symbol.includes('USDC') || pairInfo?.asset1.symbol.includes('USDC'), isLunaxPool: diff --git a/util/route.ts b/util/route.ts new file mode 100644 index 00000000..ca72504c --- /dev/null +++ b/util/route.ts @@ -0,0 +1,12 @@ +export const getPathName = (router, newChainLabel) => { + const pathname = router.pathname + + return pathname.includes('[chainId') + ? pathname.replace('[chainId]', newChainLabel.toLowerCase()) + : `/${newChainLabel.toLowerCase()}/${pathname}` + + // const paths = router.asPath.split('/') + // return !paths[2] + // ? `/${newChainLabel.toLowerCase()}/${paths[1]}` + // : `/${newChainLabel.toLowerCase()}/${paths[2]}` +} diff --git a/util/wallet-adapters/offlineSigningWallet.ts b/util/wallet-adapters/offlineSigningWallet.ts index d94d91c7..e5703ea5 100644 --- a/util/wallet-adapters/offlineSigningWallet.ts +++ b/util/wallet-adapters/offlineSigningWallet.ts @@ -9,37 +9,33 @@ import { OfflineDirectSigner, OfflineSigner, } from '@cosmjs/proto-signing' -import { - SigningStargateClient, - SigningStargateClientOptions, -} from '@cosmjs/stargate/build/signingstargateclient' +import { SigningStargateClientOptions } from '@cosmjs/stargate/build/signingstargateclient' +import { Network } from '@injectivelabs/networks' import { AuthInfo, - Coin as StationCoin, Fee, ModeInfo, SignerInfo, SimplePublicKey, + Coin as StationCoin, Tx, TxBody, TxInfo, } from '@terra-money/terra.js' import { GetTxResponse } from 'cosmjs-types/cosmos/tx/v1beta1/service' -import { Network, getNetworkEndpoints } from '@injectivelabs/networks' -import { TxResponse, Wallet } from './wallet' -import { cosmwasmAminoConverters, getSigningCosmwasmClient } from 'injectivejs' -// import {SigningStargateClient} from 'injectivejs/node_modules/@cosmjs/stargate/node_modules/@cosmjs/signingstargateclient'; -import getChainName from '../../libs/getChainName' -import { AminoTypes } from '@cosmjs/stargate' - -import { chain } from 'lodash' import Injective from '../../services/injective' +import { TxResponse, Wallet } from './wallet' export class OfflineSigningWallet implements Wallet { client: SigningCosmWasmClient | Injective + network: string - constructor(client: SigningCosmWasmClient | Injective, network?: string) { + constructor( + client: SigningCosmWasmClient | Injective, + network?: string, + activeWallet?: string + ) { this.client = client this.network = network } @@ -49,12 +45,14 @@ export class OfflineSigningWallet implements Wallet { endpoint: string, signer: OfflineSigner & OfflineDirectSigner, network: string, - options?: SigningStargateClientOptions + options?: SigningStargateClientOptions, + activeWallet?: string ): Promise { if (chainId.includes('injective')) { const injectiveClient = new Injective( signer, - chainId === 'injective-1' ? Network.MainnetK8s : Network.TestnetK8s + chainId === 'injective-1' ? Network.MainnetK8s : Network.TestnetK8s, + activeWallet ) return new Promise((resolve, reject) => { resolve(new OfflineSigningWallet(injectiveClient, network)) @@ -107,11 +105,11 @@ export class OfflineSigningWallet implements Wallet { return this.client.simulate(signerAddress, messages, memo) } - getChainId(): Promise { + getChainId(): Promise { return this.client.getChainId() } - getNetwork(): Promise { + getNetwork(): Promise { return Promise.resolve(this.network) }