From d33e819cf0c40490de7056dab0176797816d1d69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Carvitaly=E2=80=9D?= <“arvitaly@list.ru”> Date: Mon, 14 Aug 2023 08:25:19 +0700 Subject: [PATCH] added new chains, added select for token type --- .../CreatePage/CreatePage.module.css | 31 ++++++++ src/components/CreatePage/CreatePage.tsx | 57 ++++++++++---- src/components/PoolWindow/Deposit/Deposit.tsx | 14 +++- src/components/PoolWindow/PoolWindow.tsx | 1 + src/components/Pools/AllPools.tsx | 2 + src/components/Pools/Pools.tsx | 1 + src/config/chains.ts | 17 +++- src/config/chains/archway.ts | 55 +++++++++++++ src/config/chains/desmos.ts | 53 +++++++++++++ src/config/chains/neutron.ts | 78 +++++++++++++++++++ src/config/cosmwasm.ts | 28 +++++-- src/mutations/pool.ts | 2 + src/queries/native.ts | 4 +- src/stories/CreatePage/Form.module.css | 6 +- src/stories/CreatePage/TokenForm.tsx | 14 +++- src/utils/tokens.ts | 2 +- 16 files changed, 334 insertions(+), 31 deletions(-) create mode 100644 src/config/chains/archway.ts create mode 100644 src/config/chains/desmos.ts create mode 100644 src/config/chains/neutron.ts diff --git a/src/components/CreatePage/CreatePage.module.css b/src/components/CreatePage/CreatePage.module.css index d4466e3..e7ad909 100644 --- a/src/components/CreatePage/CreatePage.module.css +++ b/src/components/CreatePage/CreatePage.module.css @@ -38,4 +38,35 @@ font-size: 95px; color: rgba(115, 237, 201, 0.07); transform: rotate(-90deg); +} + +.tokenTypeSelect { + display: flex; + color: white; + gap: 20px; + margin-bottom: 15px; +} +.tokenTypeSelect label span { + font-weight: 400; + font-size: 14px; + line-height: 18px; + color: rgba(246, 248, 254, 0.8); +} +.tokenTypeSelect label { + display: flex; + gap: 7px; +} +.tokenTypeSelect input { + margin: 0; + padding: 0; + padding-top: 3px; +} + +.tabBox { + background: #12262d; + border: solid 1px rgba(115, 237, 201, 0.1); + border-radius: 0px 16px 16px; + backdrop-filter: blur(10px); + width: 100%; + padding: 35px 45px 35px 45px; } \ No newline at end of file diff --git a/src/components/CreatePage/CreatePage.tsx b/src/components/CreatePage/CreatePage.tsx index e65103e..ebd7d75 100644 --- a/src/components/CreatePage/CreatePage.tsx +++ b/src/components/CreatePage/CreatePage.tsx @@ -1,6 +1,6 @@ /* eslint-disable no-await-in-loop */ /* eslint-disable no-restricted-syntax */ -import { useRef, useState } from "react"; +import { useMemo, useRef, useState } from "react"; import { Tabs, Tab } from "ui/CreatePage/Tabs"; import NTT from "ui/CreatePage/NTT"; import NFT from "ui/CreatePage/NFT"; @@ -23,6 +23,7 @@ const CreatePage = () => { const chain = useChain(); const [creating, setCreating] = useState(false); const { account, connect, isConnected } = useAccount(); + const [tokenType, setTokenType] = useState("cw20"); const { addCw20Token, @@ -196,22 +197,31 @@ const CreatePage = () => { } form.current?.reset(); } catch (error) { - toast.error(error as string, { + toast(`${error}`, { type: "error", }); - console.error("error when create token", error); + console.error("error when create token"); + console.log(error); } finally { setCreating(false); } }; const onCreateToken = (values: CreateFormValues) => { - if (chain.config.features?.includes("tokenfactory")) { - return onCreateFactoryToken(values); + if (tokenType === "cw20") { + return onCreateCw20Token(values); } - return onCreateCw20Token(values); + return onCreateFactoryToken(values); }; + const tokenTypes = useMemo(() => [{ + key: "cw20", + label: "CW20", + }].concat(chain.config.features?.includes("tokenfactory") ? [{ + key: "tokenfactory", + label: "Tokenfactory", + }] : []), [chain]); + return (
@@ -224,13 +234,34 @@ const CreatePage = () => {
{selectedTabId === "token" && ( - +
+ {tokenTypes.length > 1 && ( +
+ {tokenTypes.map((tt) => ( + + ))} +
+ )} + +
)} {selectedTabId === "nft" && } {selectedTabId === "ntt" && } diff --git a/src/components/PoolWindow/Deposit/Deposit.tsx b/src/components/PoolWindow/Deposit/Deposit.tsx index 0c1d1fe..6374a44 100644 --- a/src/components/PoolWindow/Deposit/Deposit.tsx +++ b/src/components/PoolWindow/Deposit/Deposit.tsx @@ -88,7 +88,7 @@ const Deposit = ({ // No allowance for this account console.log("Error when deposit to pool", pool); console.log(e); - toast.error("Unknown error"); + toast.error(`${e}`); }).finally(() => setProcessing(false)); }; return ( @@ -119,7 +119,11 @@ const Deposit = ({
-
$0.00
+
+ {tokenAmountToFloat(reserve1, token1.decimals)} + {" "} + {token1.symbol} +
Balance: {" "} @@ -153,7 +157,11 @@ const Deposit = ({
-
$0.00
+
+ {tokenAmountToFloat(reserve2, token2.decimals)} + {" "} + {token2.symbol} +
Balance: {" "} diff --git a/src/components/PoolWindow/PoolWindow.tsx b/src/components/PoolWindow/PoolWindow.tsx index 18e739c..40ed300 100644 --- a/src/components/PoolWindow/PoolWindow.tsx +++ b/src/components/PoolWindow/PoolWindow.tsx @@ -27,6 +27,7 @@ const fetch = async (chain: Chain, account: Account, pool: PoolDetails) => { chain.query(USER_TOKEN_DETAILS(pool.token1, account.address)), chain.query(USER_TOKEN_DETAILS(pool.token2, account.address)), ]); + console.log("poolInfo", poolInfo); return { poolInfo, tokens, diff --git a/src/components/Pools/AllPools.tsx b/src/components/Pools/AllPools.tsx index 9c56d1d..2a6d614 100644 --- a/src/components/Pools/AllPools.tsx +++ b/src/components/Pools/AllPools.tsx @@ -27,6 +27,7 @@ const AllPools = ({ const [filter, setFilter] = useState(""); const [page, setPage] = useState(1); const [poolForDeposit, setPoolForDeposit] = useState(null); + const [modal, setModal] = useState(false); const pools = ( filter @@ -36,6 +37,7 @@ const AllPools = ({ ) : nonFilteredPools ); + const pagesCount = Math.ceil(pools.length / PAGE_SIZE); const toggleModal = () => { diff --git a/src/components/Pools/Pools.tsx b/src/components/Pools/Pools.tsx index 258e15e..6a6f61f 100644 --- a/src/components/Pools/Pools.tsx +++ b/src/components/Pools/Pools.tsx @@ -36,6 +36,7 @@ const fetchData = async ( const token2Denom = (poolInfo.token2_denom as unknown as PoolDenom); const token1 = await chain.query(POOL_TOKEN_DETAILS(token1Denom)); const token2 = await chain.query(POOL_TOKEN_DETAILS(token2Denom)); + console.log("token1", token1, "token2", token2); return { address: poolAddress, index, diff --git a/src/config/chains.ts b/src/config/chains.ts index cab0059..be92f6a 100644 --- a/src/config/chains.ts +++ b/src/config/chains.ts @@ -3,8 +3,11 @@ import { juno } from "./chains/juno"; import osmoTest from "./chains/osmo-test"; import JunoTest from "./chains/juno-test"; import Bostrom from "./chains/bostrom"; +import { DesmosMainnet } from "./chains/desmos"; +import { NeutronMainnet } from "./chains/neutron"; +import { ArchwayMainnet } from "./chains/archway"; -export type ChainId = "juno-1" | "uni-6" | "bostrom" | "osmo-test-5"; +export type ChainId = "juno-1" | "uni-6" | "bostrom" | "osmo-test-5" | "desmos-mainnet" | "neutron-1" | "archway-1"; export type ChainConfig = Omit & { chainId: ChainId; @@ -18,7 +21,7 @@ export const Chains: Record = { isTestNet: true, } as ChainConfig, "juno-1": { ...juno, features: ["tokenfactory"] } as ChainConfig, - // "archway-1": { ...mainnetChains.archway } as ChainConfig, + "archway-1": { ...ArchwayMainnet } as ChainConfig, "uni-6": { ...JunoTest, chainId: "uni-6", @@ -28,4 +31,14 @@ export const Chains: Record = { ...Bostrom, chainId: "bostrom", }, + "desmos-mainnet": { + ...DesmosMainnet, + chainId: "desmos-mainnet", + features: ["cosmwasm"], + }, + "neutron-1": { + ...NeutronMainnet, + chainId: "neutron-1", + features: [], + }, }; diff --git a/src/config/chains/archway.ts b/src/config/chains/archway.ts new file mode 100644 index 0000000..20a370f --- /dev/null +++ b/src/config/chains/archway.ts @@ -0,0 +1,55 @@ +export const ArchwayMainnet = { + bech32Config: { + bech32PrefixAccAddr: "archway", + bech32PrefixAccPub: "archwaypub", + bech32PrefixConsAddr: "archwayvalcons", + bech32PrefixConsPub: "archwayvalconspub", + bech32PrefixValAddr: "archwayvaloper", + bech32PrefixValPub: "archwayvaloperpub", + }, + bip44: { + coinType: 118, + }, + chainId: "archway-1", + chainName: "Archway", + chainSymbolImageUrl: "https://raw.githubusercontent.com/chainapsis/keplr-chain-registry/main/images/archway/chain.png", + currencies: [ + { + coinDecimals: 18, + coinDenom: "ARCH", + coinGeckoId: "archway", + coinMinimalDenom: "aarch", + coinImageUrl: "https://raw.githubusercontent.com/chainapsis/keplr-chain-registry/main/images/archway/aarch.png", + }, + ], + features: ["cosmwasm"], + feeCurrencies: [ + { + coinDecimals: 18, + coinDenom: "ARCH", + coinGeckoId: "archway", + coinMinimalDenom: "aarch", + gasPriceStep: { + low: 1000000000000, + average: 1500000000000, + high: 2000000000000, + }, + coinImageUrl: "https://raw.githubusercontent.com/chainapsis/keplr-chain-registry/main/images/archway/aarch.png", + }, + ], + rest: "https://api.mainnet.archway.io", + rpc: "https://rpc.mainnet.archway.io", + stakeCurrency: { + coinDecimals: 18, + coinDenom: "ARCH", + coinGeckoId: "archway", + coinMinimalDenom: "aarch", + coinImageUrl: "https://raw.githubusercontent.com/chainapsis/keplr-chain-registry/main/images/archway/aarch.png", + }, + nodeProvider: { + name: "Phi Labs", + email: "support@philabs.xyz", + website: "https://philabs.xyz", + }, + walletUrlForStaking: "https://wallet.keplr.app/chains/archway", +}; diff --git a/src/config/chains/desmos.ts b/src/config/chains/desmos.ts new file mode 100644 index 0000000..cc2ea3c --- /dev/null +++ b/src/config/chains/desmos.ts @@ -0,0 +1,53 @@ +import { ChainInfo } from "@keplr-wallet/types"; +import { chains } from "chain-registry"; + +const chain = chains.find(({ chain_name }) => chain_name === "desmos"); +if (!chain) { + throw new Error(`Not found chain ${"desmos-mainnet"} in registry`); +} +export const DesmosMainnet: ChainInfo = { + chainId: "desmos-mainnet", + chainName: "Desmos", + chainSymbolImageUrl: "https://raw.githubusercontent.com/chainapsis/keplr-chain-registry/main/images/desmos-mainnet/chain.png", + rpc: "https://rpc.mainnet.desmos.network", + rest: "https://api.mainnet.desmos.network", + bip44: { + coinType: 852, + }, + bech32Config: { + bech32PrefixAccAddr: "desmos", + bech32PrefixAccPub: "desmospub", + bech32PrefixValAddr: "desmosvaloper", + bech32PrefixValPub: "desmosvaloperpub", + bech32PrefixConsAddr: "desmosvalcons", + bech32PrefixConsPub: "desmosvalconspub", + }, + currencies: [ + { + coinDenom: "DSM", + coinMinimalDenom: "udsm", + coinDecimals: 6, + coinGeckoId: "desmos", + }, + ], + feeCurrencies: [ + { + coinDenom: "DSM", + coinMinimalDenom: "udsm", + coinDecimals: 6, + coinGeckoId: "desmos", + gasPriceStep: { + low: 0.01, + average: 0.03, + high: 0.05, + }, + }, + ], + stakeCurrency: { + coinDenom: "DSM", + coinMinimalDenom: "udsm", + coinDecimals: 6, + coinGeckoId: "desmos", + }, + features: [], +}; diff --git a/src/config/chains/neutron.ts b/src/config/chains/neutron.ts new file mode 100644 index 0000000..78dbd81 --- /dev/null +++ b/src/config/chains/neutron.ts @@ -0,0 +1,78 @@ +import { ChainInfo } from "@keplr-wallet/types"; +import { chains } from "chain-registry"; + +const chainName = "neutron-1"; + +const chain = chains.find(({ chain_id }) => chain_id === chainName); +if (!chain) { + throw new Error(`Not found chain ${"desmos-mainnet"} in registry`); +} +export const NeutronMainnet: ChainInfo = { + rpc: (chain.apis?.rpc || [])[0].address || "https://rpc-neutron.keplr.app", + rest: (chain.apis?.rest || [])[0].address || "https://rest-kralum.neutron-1.neutron.org", + chainId: "neutron-1", + chainName: "Neutron", + chainSymbolImageUrl: "https://raw.githubusercontent.com/chainapsis/keplr-chain-registry/main/images/neutron/chain.png", + stakeCurrency: { + coinDenom: "STAKE", + coinMinimalDenom: "ustake", + coinDecimals: 6, + }, + bip44: { + coinType: 118, + }, + bech32Config: { + bech32PrefixAccAddr: "neutron", + bech32PrefixAccPub: "neutronpub", + bech32PrefixValAddr: "neutronvaloper", + bech32PrefixValPub: "neutronvaloperpub", + bech32PrefixConsAddr: "neutronvalcons", + bech32PrefixConsPub: "neutronvalconspub", + }, + currencies: [ + { + coinDenom: "NTRN", + coinMinimalDenom: "untrn", + coinDecimals: 6, + coinImageUrl: "https://raw.githubusercontent.com/chainapsis/keplr-chain-registry/main/images/neutron/untrn.png", + }, + { + coinDenom: "STAKE", + coinMinimalDenom: "ustake", + coinDecimals: 6, + }, + ], + feeCurrencies: [ + { + coinDenom: "NTRN", + coinMinimalDenom: "untrn", + coinDecimals: 6, + gasPriceStep: { + low: 0.01, + average: 0.01, + high: 0.01, + }, + }, + { + coinDenom: "ATOM", + coinMinimalDenom: "ibc/C4CFF46FD6DE35CA4CF4CE031E643C8FDC9BA4B99AE598E9B0ED98FE3A2319F9", + coinDecimals: 6, + gasPriceStep: { + low: 0.005, + average: 0.005, + high: 0.005, + }, + }, + { + coinDenom: "USDC", + coinMinimalDenom: "ibc/F082B65C88E4B6D5EF1DB243CDA1D331D002759E938A0F5CD3FFDC5D53B3E349", + coinDecimals: 6, + gasPriceStep: { + low: 0.05, + average: 0.05, + high: 0.05, + }, + }, + ], + features: ["cosmwasm"], +}; diff --git a/src/config/cosmwasm.ts b/src/config/cosmwasm.ts index 84ba708..b746798 100644 --- a/src/config/cosmwasm.ts +++ b/src/config/cosmwasm.ts @@ -24,10 +24,10 @@ export type ChainCosmwasmConfig = { }; const gasLimits = { - [GasLimit.Cw20IncreaseAllowance]: 160000, + [GasLimit.Cw20IncreaseAllowance]: 200000, [GasLimit.PoolAddLiquidity]: 500000, - [GasLimit.PoolRemoveLiquidity]: 500000, - [GasLimit.PoolFactoryCreatePool]: 600000, + [GasLimit.PoolRemoveLiquidity]: 600000, + [GasLimit.PoolFactoryCreatePool]: 700000, [GasLimit.Cw20Instantiate]: 250000, [GasLimit.Cw20Send]: 150000, [GasLimit.NativeSendTokens]: 100000, @@ -58,14 +58,28 @@ export const chainCosmwasmConfigs: Record = { cw20ContractCodeId: 1, gasLimits, }, - // "archway-1": { - // cw20ContractCodeId: 21, - // gasLimits, - // }, + "archway-1": { + factoryAddress: "archway1tmm7nszsxtnmhtvc03ganqn8nn3sdttyxzqf62pxnzmxter528uqsszspl", + swapPoolContractCodeId: "77", + cw20ContractCodeId: 88, + gasLimits, + }, "osmo-test-5": { factoryAddress: "osmo1h4a3wk756pwy6ank2dmeaqpz50tjx8jcvzp3r3499q2tj6yqtjqqucjf7s", cw20ContractCodeId: 2265, swapPoolContractCodeId: "2263", gasLimits, }, + "desmos-mainnet": { + factoryAddress: "desmos17r3faruez552kdxy0lsjydmj0nu22mxax33azx326039hfe7pnhqwjsldn", + cw20ContractCodeId: 6, + swapPoolContractCodeId: "8", + gasLimits, + }, + "neutron-1": { + factoryAddress: "neutron19l5xwvd04c5aa6h6zgqjlu7l58gg0k7cjn3duqq3rtsvjwhhzakqyhzgag", + cw20ContractCodeId: 125, + swapPoolContractCodeId: "126", + gasLimits, + }, }; diff --git a/src/mutations/pool.ts b/src/mutations/pool.ts index 48d86c5..f2daec7 100644 --- a/src/mutations/pool.ts +++ b/src/mutations/pool.ts @@ -7,6 +7,7 @@ import { Coin } from "@cosmjs/amino"; import { SwapPoolClient } from "generated/SwapPool.client"; import { Account } from "classes/Account"; import { SwapPoolFactoryClient } from "generated/SwapPoolFactory.client"; +import { SWAP_POOL_INFO } from "queries/pool"; import { USER_TOKEN_DETAILS } from "../queries/tokens"; export const CREATE_POOL = async ( @@ -122,6 +123,7 @@ export const ADD_LIQUIDITY = async ( minLiquidity: "0", }, chain.calculateFee(GasLimit.PoolAddLiquidity), undefined, funds); try { + chain.invalidate(SWAP_POOL_INFO(poolAddress)); chain.invalidate(USER_TOKEN_DETAILS(token1, address)); chain.invalidate(USER_TOKEN_DETAILS(token2, address)); } catch (e) { diff --git a/src/queries/native.ts b/src/queries/native.ts index 50e7b3f..5f77514 100644 --- a/src/queries/native.ts +++ b/src/queries/native.ts @@ -2,6 +2,7 @@ import { Chain } from "classes/Chain"; import { NativeTokenDetails } from "types/tokens"; export const NATIVE_TOKEN_DETAILS = (denom: string) => ({ + cacheTime: 1, queryKey: `v0.01/native/${denom}/details`, queryFn: async ({ chain }: { chain: Chain @@ -24,7 +25,8 @@ export const NATIVE_TOKEN_DETAILS = (denom: string) => ({ } const native = chain.config.currencies.find( - (currency) => currency.coinMinimalDenom === denom, + (currency) => currency.coinMinimalDenom.toLowerCase() === denom.toLowerCase() + || currency.coinDenom.toLowerCase() === denom.toLowerCase(), ); if (native) { diff --git a/src/stories/CreatePage/Form.module.css b/src/stories/CreatePage/Form.module.css index 99d91c3..c49dce9 100644 --- a/src/stories/CreatePage/Form.module.css +++ b/src/stories/CreatePage/Form.module.css @@ -5,15 +5,15 @@ position: relative; width: 100%; height: 100%; - background: #12262d; + /* background: #12262d; border: solid 1px rgba(115, 237, 201, 0.1); border-radius: 0px 16px 16px; - backdrop-filter: blur(10px); + backdrop-filter: blur(10px); */ } .formContent { display: inline; - padding: 35px 45px 0px 45px; + /* padding: 35px 45px 0px 45px; */ } .formheader { diff --git a/src/stories/CreatePage/TokenForm.tsx b/src/stories/CreatePage/TokenForm.tsx index 6835fe4..35f567c 100644 --- a/src/stories/CreatePage/TokenForm.tsx +++ b/src/stories/CreatePage/TokenForm.tsx @@ -28,6 +28,7 @@ export type TokenFormProps = { connect: () => void; creating: boolean; onCreate: (values: CreateFormValues) => void; + isLogoEnabled: boolean; }; const TokenForm = ({ @@ -35,6 +36,7 @@ const TokenForm = ({ isConnected, connect, onCreate, + isLogoEnabled, }: TokenFormProps, ref: ForwardedRef) => { const [balances, setBalances] = useState([ defaultBalance, @@ -91,7 +93,7 @@ const TokenForm = ({ tokenName: token.value, tokenSymbol: symbol.value, quantity: quantity.value, - logo: logo.value, + logo: logo ? logo.value : "", description, }); }; @@ -103,6 +105,14 @@ const TokenForm = ({ ref={ref} >
+
+ {isLogoEnabled && ( + )}
diff --git a/src/utils/tokens.ts b/src/utils/tokens.ts index 9cb6ad3..f3c14f4 100644 --- a/src/utils/tokens.ts +++ b/src/utils/tokens.ts @@ -75,7 +75,7 @@ export const denomMetaDataToTokenDetails = (metadata: Metadata): NativeTokenDeta export const tokenToPoolDenom = (token: TokenDetails): PoolDenom => (token.type === "cw20" ? { cw20: token.address, } : { - native: token.denom, + native: token.minimalDenom || token.denom, }); export const searchInToken = (token: TokenDetails, q: string) => {