From 42204234243c22876b6cc3b291f404539b61ddf4 Mon Sep 17 00:00:00 2001 From: jinoosss <112360739+jinoosss@users.noreply.github.com> Date: Wed, 29 May 2024 18:06:43 +0900 Subject: [PATCH] feat: Support multiple environment (#366) * feat: Support multi environment * refactor: Clean env variables --- packages/web/.env | 36 ++++---- packages/web/.env.example | 11 ++- .../transaction-messages/common.ts | 72 --------------- .../transaction-messages/pool.ts | 10 ++- .../transaction-messages/position.ts | 11 ++- .../transaction-messages/staker.ts | 5 +- .../EarnMyPositionNoLiquidity.tsx | 2 +- .../wallet/deposit-modal/DepositModal.tsx | 46 ++-------- .../wallet/withdraw-modal/WithDrawModal.tsx | 20 +---- packages/web/src/constants/common.constant.ts | 14 ++- .../web/src/constants/environment.constant.ts | 55 ++++++++++++ .../AssetListContainer.tsx | 43 --------- .../TokenInfoContentContainer.tsx | 3 +- .../WalletBalanceContainer.tsx | 2 +- .../use-earn-add-liquidity-confirm-modal.tsx | 2 +- .../web/src/hooks/token/use-gnot-wugnot.tsx | 5 +- .../web/src/hooks/token/use-token-image.tsx | 4 +- packages/web/src/hooks/wallet/use-wallet.ts | 24 +++-- .../GnoswapServiceProvider.tsx | 90 +++++++++++-------- .../account/account-repository-impl.ts | 7 +- .../dashboard/dashboard-repository-impl.ts | 21 ++++- .../notification-repository-impl.ts | 24 +++-- .../repositories/pool/pool-repository-impl.ts | 27 ++++-- .../position/position-repository-impl.ts | 21 +++-- .../repositories/swap/swap-repository-impl.ts | 2 +- .../swap/swap-router-repository-impl.ts | 14 +-- .../token/token-repository-impl.ts | 34 +++++-- packages/web/src/resources/chains.json | 6 ++ packages/web/src/utils/common.ts | 2 +- 29 files changed, 318 insertions(+), 295 deletions(-) create mode 100644 packages/web/src/constants/environment.constant.ts diff --git a/packages/web/.env b/packages/web/.env index 0c3853831..5c16a465c 100644 --- a/packages/web/.env +++ b/packages/web/.env @@ -1,15 +1,21 @@ -NEXT_PUBLIC_DEFAULT_CHAIN_ID="dev.gnoswap" -NEXT_PUBLIC_API_URL="https://dev.api.gnoswap.io/v1" -NEXT_PUBLIC_PACKAGE_ROUTER_PATH="gno.land/r/demo/router" -NEXT_PUBLIC_PACKAGE_POOL_PATH="gno.land/r/demo/pool" -NEXT_PUBLIC_PACKAGE_POSITION_PATH="gno.land/r/demo/position" -NEXT_PUBLIC_PACKAGE_STAKER_PATH="gno.land/r/demo/staker" -NEXT_PUBLIC_PACKAGE_NFT_PATH="gno.land/r/demo/gnft" -NEXT_PUBLIC_GOVERNANCE_PATH="gno.land/r/demo/gov" -NEXT_PUBLIC_WRAPPED_GNOT_PATH="gno.land/r/demo/wugnot" -NEXT_PUBLIC_GNOS_PATH="gno.land/r/demo/gns" -NEXT_PUBLIC_PACKAGE_ROUTER_ADDRESS="g1pjtpgjpsn4hjfv2n4mpz8cczdn32jkpsqwxuav" -NEXT_PUBLIC_PACKAGE_POOL_ADDRESS="g15z32w7txv6lw259xzhzzmwtwmcjjc0m6dqzh6f" -NEXT_PUBLIC_PACKAGE_POSITION_ADDRESS="g10wwa53xgu4397kvzz7akxar9370zjdpwux5th9" -NEXT_PUBLIC_PACKAGE_STAKER_ADDRESS="g1puv9dz470prjshjm9qyg25dyfvrgph2kvjph68" -NEXT_PUBLIC_PACKAGE_GOVERNANCE_ADDRESS="g1kmat25auuqf0h5qvd4q7s707r8let5sky4tr76" \ No newline at end of file +NEXT_PUBLIC_CHAINS="" +NEXT_PUBLIC_DEFAULT_CHAIN_ID="" +NEXT_PUBLIC_API_URL="" +NEXT_PUBLIC_ROUTER_API_URL="" +NEXT_PUBLIC_DEV_CHAIN_ID="" +NEXT_PUBLIC_DEV_API_URL="" +NEXT_PUBLIC_DEV_ROUTER_API_URL="" +NEXT_PUBLIC_PACKAGE_GNOSWAP_CONST_PATH="" +NEXT_PUBLIC_PACKAGE_ROUTER_PATH="" +NEXT_PUBLIC_PACKAGE_POOL_PATH="" +NEXT_PUBLIC_PACKAGE_POSITION_PATH="" +NEXT_PUBLIC_PACKAGE_STAKER_PATH="" +NEXT_PUBLIC_PACKAGE_NFT_PATH="" +NEXT_PUBLIC_GOVERNANCE_PATH="" +NEXT_PUBLIC_WRAPPED_GNOT_PATH="" +NEXT_PUBLIC_GNS_TOKEN_PATH="" +NEXT_PUBLIC_PACKAGE_ROUTER_ADDRESS="" +NEXT_PUBLIC_PACKAGE_POOL_ADDRESS="" +NEXT_PUBLIC_PACKAGE_POSITION_ADDRESS="" +NEXT_PUBLIC_PACKAGE_STAKER_ADDRESS="" +NEXT_PUBLIC_PACKAGE_GOVERNANCE_ADDRESS="" \ No newline at end of file diff --git a/packages/web/.env.example b/packages/web/.env.example index 2ccefcbfb..f68b00682 100644 --- a/packages/web/.env.example +++ b/packages/web/.env.example @@ -1,5 +1,10 @@ +NEXT_PUBLIC_CHAINS="dev.gnoswap" NEXT_PUBLIC_DEFAULT_CHAIN_ID="dev.gnoswap" NEXT_PUBLIC_API_URL="https://dev.api.gnoswap.io/v1" +NEXT_PUBLIC_ROUTER_API_URL="https://dev.route.gnoswap.io" +NEXT_PUBLIC_DEV_CHAIN_ID="dev.gnoswap" +NEXT_PUBLIC_DEV_API_URL="https://dev.api.gnoswap.io/v1" +NEXT_PUBLIC_DEV_ROUTER_API_URL="https://dev.route.gnoswap.io" NEXT_PUBLIC_PACKAGE_GNOSWAP_CONST_PATH="gno.land/r/demo/gnoswap/consts" NEXT_PUBLIC_PACKAGE_ROUTER_PATH="gno.land/r/demo/router" NEXT_PUBLIC_PACKAGE_POOL_PATH="gno.land/r/demo/pool" @@ -7,10 +12,10 @@ NEXT_PUBLIC_PACKAGE_POSITION_PATH="gno.land/r/demo/position" NEXT_PUBLIC_PACKAGE_STAKER_PATH="gno.land/r/demo/staker" NEXT_PUBLIC_PACKAGE_NFT_PATH="gno.land/r/demo/gnft" NEXT_PUBLIC_GOVERNANCE_PATH="gno.land/r/demo/gov" +NEXT_PUBLIC_WRAPPED_GNOT_PATH="gno.land/r/demo/wugnot" +NEXT_PUBLIC_GNS_TOKEN_PATH="gno.land/r/demo/gns" NEXT_PUBLIC_PACKAGE_ROUTER_ADDRESS="g1pjtpgjpsn4hjfv2n4mpz8cczdn32jkpsqwxuav" NEXT_PUBLIC_PACKAGE_POOL_ADDRESS="g15z32w7txv6lw259xzhzzmwtwmcjjc0m6dqzh6f" NEXT_PUBLIC_PACKAGE_POSITION_ADDRESS="g10wwa53xgu4397kvzz7akxar9370zjdpwux5th9" NEXT_PUBLIC_PACKAGE_STAKER_ADDRESS="g1puv9dz470prjshjm9qyg25dyfvrgph2kvjph68" -NEXT_PUBLIC_PACKAGE_GOVERNANCE_ADDRESS="g1kmat25auuqf0h5qvd4q7s707r8let5sky4tr76" -NEXT_PUBLIC_WRAPPED_GNOT_PATH="gno.land/r/demo/wugnot" -NEXT_PUBLIC_GNS_TOKEN_PATH="gno.land/r/demo/gns" \ No newline at end of file +NEXT_PUBLIC_PACKAGE_GOVERNANCE_ADDRESS="g1kmat25auuqf0h5qvd4q7s707r8let5sky4tr76" \ No newline at end of file diff --git a/packages/web/src/common/clients/wallet-client/transaction-messages/common.ts b/packages/web/src/common/clients/wallet-client/transaction-messages/common.ts index dc55e5e54..7b03db67f 100644 --- a/packages/web/src/common/clients/wallet-client/transaction-messages/common.ts +++ b/packages/web/src/common/clients/wallet-client/transaction-messages/common.ts @@ -1,77 +1,5 @@ import BigNumber from "bignumber.js"; -export const ENVIRONMENT = process.env.NEXT_PUBLIC_ENVIRONMENT || "preview"; - -const isPreview = ENVIRONMENT === "preview"; - -const PREVIEW_ENV_VARIABLES = { - DEFAULT_CHAIN_ID: "dev.gnoswap", - API_URL: "https://dev.api.gnoswap.io/v1", - ROUTER_API_URL: "https://gnoswap-route-api.in.onbloc.xyz", - PACKAGE_GNOSWAP_CONST_PATH: "gno.land/r/demo/gnoswap/consts", - PACKAGE_ROUTER_PATH: "gno.land/r/demo/router", - PACKAGE_POOL_PATH: "gno.land/r/demo/pool", - PACKAGE_POSITION_PATH: "gno.land/r/demo/position", - PACKAGE_STAKER_PATH: "gno.land/r/demo/staker", - PACKAGE_NFT_PATH: "gno.land/r/demo/gnft", - GOVERNANCE_PATH: "gno.land/r/demo/gov", - PACKAGE_ROUTER_ADDRESS: "g1pjtpgjpsn4hjfv2n4mpz8cczdn32jkpsqwxuav", - PACKAGE_POOL_ADDRESS: "g15z32w7txv6lw259xzhzzmwtwmcjjc0m6dqzh6f", - PACKAGE_POSITION_ADDRESS: "g10wwa53xgu4397kvzz7akxar9370zjdpwux5th9", - PACKAGE_STAKER_ADDRESS: "g1puv9dz470prjshjm9qyg25dyfvrgph2kvjph68", - PACKAGE_GOVERNANCE_ADDRESS: "g1kmat25auuqf0h5qvd4q7s707r8let5sky4tr76", - WRAPPED_GNOT_PATH: "gno.land/r/demo/wugnot", - GNS_TOKEN_PATH: "gno.land/r/demo/gns", -}; - -const ENV_VARIABLES = { - DEFAULT_CHAIN_ID: process.env.NEXT_PUBLIC_DEFAULT_CHAIN_ID || "", - API_URL: process.env.NEXT_PUBLIC_API_URL || "", - ROUTER_API_URL: process.env.NEXT_PUBLIC_ROUTER_API_URL || "", - PACKAGE_GNOSWAP_CONST_PATH: - process.env.NEXT_PUBLIC_PACKAGE_GNOSWAP_CONST_PATH || "", - PACKAGE_ROUTER_PATH: process.env.NEXT_PUBLIC_PACKAGE_ROUTER_PATH || "", - PACKAGE_POOL_PATH: process.env.NEXT_PUBLIC_PACKAGE_POOL_PATH || "", - PACKAGE_POSITION_PATH: process.env.NEXT_PUBLIC_PACKAGE_POSITION_PATH || "", - PACKAGE_STAKER_PATH: process.env.NEXT_PUBLIC_PACKAGE_STAKER_PATH || "", - PACKAGE_NFT_PATH: process.env.NEXT_PUBLIC_PACKAGE_NFT_PATH || "", - GOVERNANCE_PATH: process.env.NEXT_PUBLIC_GOVERNANCE_PATH || "", - WRAPPED_GNOT_PATH: process.env.NEXT_PUBLIC_WRAPPED_GNOT_PATH || "", - PACKAGE_ROUTER_ADDRESS: process.env.NEXT_PUBLIC_PACKAGE_ROUTER_ADDRESS || "", - PACKAGE_POOL_ADDRESS: process.env.NEXT_PUBLIC_PACKAGE_POOL_ADDRESS || "", - PACKAGE_POSITION_ADDRESS: - process.env.NEXT_PUBLIC_PACKAGE_POSITION_ADDRESS || "", - PACKAGE_STAKER_ADDRESS: process.env.NEXT_PUBLIC_PACKAGE_STAKER_ADDRESS || "", - PACKAGE_GOVERNANCE_ADDRESS: - process.env.NEXT_PUBLIC_PACKAGE_GOVERNANCE_ADDRESS || "", - GNS_TOKEN_PATH: process.env.NEXT_PUBLIC_GNS_TOKEN_PATH || "", -}; - -const currentEnvVariables = isPreview ? PREVIEW_ENV_VARIABLES : ENV_VARIABLES; - -export const DEFAULT_CHAIN_ID = currentEnvVariables.DEFAULT_CHAIN_ID; -export const API_URL = currentEnvVariables.API_URL; -export const ROUTER_API_URL = currentEnvVariables.ROUTER_API_URL; -export const PACKAGE_GNOSWAP_CONST_PATH = - currentEnvVariables.PACKAGE_GNOSWAP_CONST_PATH; -export const PACKAGE_ROUTER_PATH = currentEnvVariables.PACKAGE_ROUTER_PATH; -export const PACKAGE_POOL_PATH = currentEnvVariables.PACKAGE_POOL_PATH; -export const PACKAGE_POSITION_PATH = currentEnvVariables.PACKAGE_POSITION_PATH; -export const PACKAGE_STAKER_PATH = currentEnvVariables.PACKAGE_STAKER_PATH; -export const PACKAGE_NFT_PATH = currentEnvVariables.PACKAGE_NFT_PATH; -export const GOVERNANCE_PATH = currentEnvVariables.GOVERNANCE_PATH; -export const WRAPPED_GNOT_PATH = currentEnvVariables.WRAPPED_GNOT_PATH; -export const PACKAGE_ROUTER_ADDRESS = - currentEnvVariables.PACKAGE_ROUTER_ADDRESS; -export const PACKAGE_POOL_ADDRESS = currentEnvVariables.PACKAGE_POOL_ADDRESS; -export const PACKAGE_POSITION_ADDRESS = - currentEnvVariables.PACKAGE_POSITION_ADDRESS; -export const PACKAGE_STAKER_ADDRESS = - currentEnvVariables.PACKAGE_STAKER_ADDRESS; -export const PACKAGE_GOVERNANCE_ADDRESS = - currentEnvVariables.PACKAGE_GOVERNANCE_ADDRESS; -export const GNS_TOKEN_PATH = currentEnvVariables.GNS_TOKEN_PATH; - export interface TransactionBankMessage { from_address: string; to_address: string; diff --git a/packages/web/src/common/clients/wallet-client/transaction-messages/pool.ts b/packages/web/src/common/clients/wallet-client/transaction-messages/pool.ts index 43cd1dd4a..3531d002c 100644 --- a/packages/web/src/common/clients/wallet-client/transaction-messages/pool.ts +++ b/packages/web/src/common/clients/wallet-client/transaction-messages/pool.ts @@ -1,12 +1,14 @@ -import { toNativePath } from "@utils/common"; import { - makeApproveMessage, - makeGNOTSendAmount, - makeTransactionMessage, PACKAGE_POOL_ADDRESS, PACKAGE_ROUTER_ADDRESS, PACKAGE_STAKER_ADDRESS, PACKAGE_STAKER_PATH, +} from "@constants/environment.constant"; +import { toNativePath } from "@utils/common"; +import { + makeApproveMessage, + makeGNOTSendAmount, + makeTransactionMessage, } from "./common"; export function makePoolTokenApproveMessage( diff --git a/packages/web/src/common/clients/wallet-client/transaction-messages/position.ts b/packages/web/src/common/clients/wallet-client/transaction-messages/position.ts index 4077a3083..7bcf1f2ed 100644 --- a/packages/web/src/common/clients/wallet-client/transaction-messages/position.ts +++ b/packages/web/src/common/clients/wallet-client/transaction-messages/position.ts @@ -1,15 +1,14 @@ -import { - makeGNOTSendAmount, - makeTransactionMessage, - PACKAGE_POSITION_PATH, - PACKAGE_STAKER_PATH, -} from "./common"; +import { makeGNOTSendAmount, makeTransactionMessage } from "./common"; import { SwapFeeTierInfoMap, SwapFeeTierType, } from "@constants/option.constant"; import { DEFAULT_TRANSACTION_DEADLINE } from "@common/values"; import BigNumber from "bignumber.js"; +import { + PACKAGE_POSITION_PATH, + PACKAGE_STAKER_PATH, +} from "@constants/environment.constant"; export function makePositionMintMessage( tokenAPath: string, diff --git a/packages/web/src/common/clients/wallet-client/transaction-messages/staker.ts b/packages/web/src/common/clients/wallet-client/transaction-messages/staker.ts index 5ddfd025c..a08c9099e 100644 --- a/packages/web/src/common/clients/wallet-client/transaction-messages/staker.ts +++ b/packages/web/src/common/clients/wallet-client/transaction-messages/staker.ts @@ -1,10 +1,9 @@ import { - makeApproveMessage, - makeTransactionMessage, PACKAGE_NFT_PATH, PACKAGE_STAKER_ADDRESS, PACKAGE_STAKER_PATH, -} from "./common"; +} from "@constants/environment.constant"; +import { makeApproveMessage, makeTransactionMessage } from "./common"; export function makeApporveStakeTokenMessage( lpTokenId: string, diff --git a/packages/web/src/components/earn/earn-my-positions-no-liquidity/EarnMyPositionNoLiquidity.tsx b/packages/web/src/components/earn/earn-my-positions-no-liquidity/EarnMyPositionNoLiquidity.tsx index 1bccab1b8..84448ff8f 100644 --- a/packages/web/src/components/earn/earn-my-positions-no-liquidity/EarnMyPositionNoLiquidity.tsx +++ b/packages/web/src/components/earn/earn-my-positions-no-liquidity/EarnMyPositionNoLiquidity.tsx @@ -1,5 +1,5 @@ -import { WRAPPED_GNOT_PATH } from "@common/clients/wallet-client/transaction-messages"; import IconNoPosition from "@components/common/icons/IconNoPosition"; +import { WRAPPED_GNOT_PATH } from "@constants/environment.constant"; import { useTokenData } from "@hooks/token/use-token-data"; import { AccountModel } from "@models/account/account-model"; import { useGetTokenPrices } from "@query/token"; diff --git a/packages/web/src/components/wallet/deposit-modal/DepositModal.tsx b/packages/web/src/components/wallet/deposit-modal/DepositModal.tsx index 8dbc0adcd..a8b02ec04 100644 --- a/packages/web/src/components/wallet/deposit-modal/DepositModal.tsx +++ b/packages/web/src/components/wallet/deposit-modal/DepositModal.tsx @@ -1,3 +1,4 @@ +import { GNOT_TOKEN } from "@common/values/token-constant"; import Button, { ButtonHierarchy } from "@components/common/button/Button"; import IconClose from "@components/common/icons/IconCancel"; import IconFailed from "@components/common/icons/IconFailed"; @@ -23,45 +24,12 @@ import { DepositTooltipContent, } from "./DepositModal.styles"; -export const DEFAULT_DEPOSIT_GNOT = { - type: "native", - chainId: "dev.gnoswap", - createdAt: "0001-01-01T00:00:00Z", - name: "Gnoland", - path: "gnot", - decimals: 6, - symbol: "GNOT", - logoURI: - "https://raw.githubusercontent.com/onbloc/gno-token-resource/main/gno-native/images/gnot.svg", - priceID: "gnot", - priceId: "gnot", - description: - "Gno.land is a platform to write smart contracts in Gnolang (Gno). Using an interpreted version of the general-purpose programming language Golang (Go), developers can write smart contracts and other blockchain apps without having to learn a language that’s exclusive to a single ecosystem. Web2 developers can easily contribute to web3 and start building a more transparent, accountable world.\n\nThe Gno transaction token, GNOT, and the contributor memberships power the platform, which runs on a variation of Proof of Stake. Proof of Contribution rewards contributors from technical and non-technical backgrounds, fairly and for life with GNOT. This consensus mechanism also achieves higher security with fewer validators, optimizing resources for a greener, more sustainable, and enduring blockchain ecosystem.\n\nAny blockchain using Gnolang achieves succinctness, composability, expressivity, and completeness not found in any other smart contract platform. By observing a minimal structure, the design can endure over time and challenge the regime of information censorship we’re living in today.", - websiteURL: "https://gno.land/", - displayPath: "Native", - wrappedPath: "gno.land/r/demo/wugnot", - balance: 9989743.152257, -} as const; +export const DEFAULT_DEPOSIT_GNOT = GNOT_TOKEN; const DEFAULT_DEPOSIT_GRC20s = { - type: "native", - chainId: "dev.gnoswap", - createdAt: "0001-01-01T00:00:00Z", - name: "Gnoland", - path: "gnot", - decimals: 6, + ...GNOT_TOKEN, symbol: "GRC20s", - logoURI: - "https://raw.githubusercontent.com/onbloc/gno-token-resource/main/gno-native/images/gnot.svg", - priceID: "gnot", - priceId: "gnot", - description: - "Gno.land is a platform to write smart contracts in Gnolang (Gno). Using an interpreted version of the general-purpose programming language Golang (Go), developers can write smart contracts and other blockchain apps without having to learn a language that’s exclusive to a single ecosystem. Web2 developers can easily contribute to web3 and start building a more transparent, accountable world.\n\nThe Gno transaction token, GNOT, and the contributor memberships power the platform, which runs on a variation of Proof of Stake. Proof of Contribution rewards contributors from technical and non-technical backgrounds, fairly and for life with GNOT. This consensus mechanism also achieves higher security with fewer validators, optimizing resources for a greener, more sustainable, and enduring blockchain ecosystem.\n\nAny blockchain using Gnolang achieves succinctness, composability, expressivity, and completeness not found in any other smart contract platform. By observing a minimal structure, the design can endure over time and challenge the regime of information censorship we’re living in today.", - websiteURL: "https://gno.land/", - displayPath: "Native", - wrappedPath: "gno.land/r/demo/wugnot", - balance: 9989743.152257, -} as const; +}; interface Props { close: () => void; @@ -200,7 +168,11 @@ const DepositModal: React.FC = ({ - +

Learn More

diff --git a/packages/web/src/components/wallet/withdraw-modal/WithDrawModal.tsx b/packages/web/src/components/wallet/withdraw-modal/WithDrawModal.tsx index afb5eaaf8..42b2f76c2 100644 --- a/packages/web/src/components/wallet/withdraw-modal/WithDrawModal.tsx +++ b/packages/web/src/components/wallet/withdraw-modal/WithDrawModal.tsx @@ -1,3 +1,4 @@ +import { GNOT_TOKEN } from "@common/values/token-constant"; import Button, { ButtonHierarchy } from "@components/common/button/Button"; import IconClose from "@components/common/icons/IconCancel"; import IconFailed from "@components/common/icons/IconFailed"; @@ -24,24 +25,7 @@ import { WithdrawTooltipContent, } from "./WithDrawModal.styles"; -const DEFAULT_WITHDRAW_GNOT = { - type: "native", - chainId: "dev.gnoswap", - createdAt: "0001-01-01T00:00:00Z", - name: "Gnoland", - path: "gnot", - decimals: 6, - symbol: "GNOT", - logoURI: - "https://raw.githubusercontent.com/onbloc/gno-token-resource/main/gno-native/images/gnot.svg", - priceID: "gnot", - description: - "Gno.land is a platform to write smart contracts in Gnolang (Gno). Using an interpreted version of the general-purpose programming language Golang (Go), developers can write smart contracts and other blockchain apps without having to learn a language that’s exclusive to a single ecosystem. Web2 developers can easily contribute to web3 and start building a more transparent, accountable world.\n\nThe Gno transaction token, GNOT, and the contributor memberships power the platform, which runs on a variation of Proof of Stake. Proof of Contribution rewards contributors from technical and non-technical backgrounds, fairly and for life with GNOT. This consensus mechanism also achieves higher security with fewer validators, optimizing resources for a greener, more sustainable, and enduring blockchain ecosystem.\n\nAny blockchain using Gnolang achieves succinctness, composability, expressivity, and completeness not found in any other smart contract platform. By observing a minimal structure, the design can endure over time and challenge the regime of information censorship we’re living in today.", - websiteURL: "https://gno.land/", - displayPath: "Native", - wrappedPath: "gno.land/r/demo/wugnot", - balance: 9989743.152257, -} as const; +const DEFAULT_WITHDRAW_GNOT = GNOT_TOKEN; interface Props { close: () => void; diff --git a/packages/web/src/constants/common.constant.ts b/packages/web/src/constants/common.constant.ts index eacb02475..c99d07bb5 100644 --- a/packages/web/src/constants/common.constant.ts +++ b/packages/web/src/constants/common.constant.ts @@ -1,6 +1,14 @@ -export const DEFAULT_NETWORK_ID = "dev.gnoswap"; +export const DEFAULT_NETWORK_ID = "portal-loop"; export const PATH = ["/earn"]; // 10SECOND/60SECOND is the specific time for data refetching cycles. `useGetPositionsByAddress` will refetch after these specific time -export const PATH_10SECOND = ["/earn/pool/[pool-path]/remove", "/tokens/[token-path]"]; -export const PATH_60SECOND = ["/wallet", "/earn/pool/[pool-path]/stake", "/earn/pool/[pool-path]/unstake", "/earn/pool/[pool-path]"]; \ No newline at end of file +export const PATH_10SECOND = [ + "/earn/pool/[pool-path]/remove", + "/tokens/[token-path]", +]; +export const PATH_60SECOND = [ + "/wallet", + "/earn/pool/[pool-path]/stake", + "/earn/pool/[pool-path]/unstake", + "/earn/pool/[pool-path]", +]; diff --git a/packages/web/src/constants/environment.constant.ts b/packages/web/src/constants/environment.constant.ts new file mode 100644 index 000000000..881f972e9 --- /dev/null +++ b/packages/web/src/constants/environment.constant.ts @@ -0,0 +1,55 @@ +const ENV_VARIABLES = { + CHAINS: process.env.NEXT_PUBLIC_CHAINS?.split(",") || [], + DEFAULT_CHAIN_ID: process.env.NEXT_PUBLIC_DEFAULT_CHAIN_ID || "", + API_URL: process.env.NEXT_PUBLIC_API_URL || "", + ROUTER_API_URL: process.env.NEXT_PUBLIC_ROUTER_API_URL || "", + DEV_CHAIN_ID: process.env.NEXT_PUBLIC_DEV_CHAIN_ID || "", + DEV_API_URL: process.env.NEXT_PUBLIC_DEV_API_URL || "", + DEV_ROUTER_API_URL: process.env.NEXT_PUBLIC_DEV_ROUTER_API_URL || "", + PACKAGE_GNOSWAP_CONST_PATH: + process.env.NEXT_PUBLIC_PACKAGE_GNOSWAP_CONST_PATH || "", + PACKAGE_ROUTER_PATH: process.env.NEXT_PUBLIC_PACKAGE_ROUTER_PATH || "", + PACKAGE_POOL_PATH: process.env.NEXT_PUBLIC_PACKAGE_POOL_PATH || "", + PACKAGE_POSITION_PATH: process.env.NEXT_PUBLIC_PACKAGE_POSITION_PATH || "", + PACKAGE_STAKER_PATH: process.env.NEXT_PUBLIC_PACKAGE_STAKER_PATH || "", + PACKAGE_NFT_PATH: process.env.NEXT_PUBLIC_PACKAGE_NFT_PATH || "", + GOVERNANCE_PATH: process.env.NEXT_PUBLIC_GOVERNANCE_PATH || "", + WRAPPED_GNOT_PATH: process.env.NEXT_PUBLIC_WRAPPED_GNOT_PATH || "", + GNS_TOKEN_PATH: process.env.NEXT_PUBLIC_GNS_TOKEN_PATH || "", + PACKAGE_ROUTER_ADDRESS: process.env.NEXT_PUBLIC_PACKAGE_ROUTER_ADDRESS || "", + PACKAGE_POOL_ADDRESS: process.env.NEXT_PUBLIC_PACKAGE_POOL_ADDRESS || "", + PACKAGE_POSITION_ADDRESS: + process.env.NEXT_PUBLIC_PACKAGE_POSITION_ADDRESS || "", + PACKAGE_STAKER_ADDRESS: process.env.NEXT_PUBLIC_PACKAGE_STAKER_ADDRESS || "", + PACKAGE_GOVERNANCE_ADDRESS: + process.env.NEXT_PUBLIC_PACKAGE_GOVERNANCE_ADDRESS || "", +}; + +const currentEnvVariables = ENV_VARIABLES; + +export const CHAINS = currentEnvVariables.CHAINS; +export const DEFAULT_CHAIN_ID = currentEnvVariables.DEFAULT_CHAIN_ID; +export const API_URL = currentEnvVariables.API_URL; +export const ROUTER_API_URL = currentEnvVariables.ROUTER_API_URL; +export const DEV_CHAIN_ID = currentEnvVariables.DEV_CHAIN_ID; +export const DEV_API_URL = currentEnvVariables.DEV_API_URL; +export const DEV_ROUTER_API_URL = currentEnvVariables.DEV_ROUTER_API_URL; +export const PACKAGE_GNOSWAP_CONST_PATH = + currentEnvVariables.PACKAGE_GNOSWAP_CONST_PATH; +export const PACKAGE_ROUTER_PATH = currentEnvVariables.PACKAGE_ROUTER_PATH; +export const PACKAGE_POOL_PATH = currentEnvVariables.PACKAGE_POOL_PATH; +export const PACKAGE_POSITION_PATH = currentEnvVariables.PACKAGE_POSITION_PATH; +export const PACKAGE_STAKER_PATH = currentEnvVariables.PACKAGE_STAKER_PATH; +export const PACKAGE_NFT_PATH = currentEnvVariables.PACKAGE_NFT_PATH; +export const GOVERNANCE_PATH = currentEnvVariables.GOVERNANCE_PATH; +export const WRAPPED_GNOT_PATH = currentEnvVariables.WRAPPED_GNOT_PATH; +export const GNS_TOKEN_PATH = currentEnvVariables.GNS_TOKEN_PATH; +export const PACKAGE_ROUTER_ADDRESS = + currentEnvVariables.PACKAGE_ROUTER_ADDRESS; +export const PACKAGE_POOL_ADDRESS = currentEnvVariables.PACKAGE_POOL_ADDRESS; +export const PACKAGE_POSITION_ADDRESS = + currentEnvVariables.PACKAGE_POSITION_ADDRESS; +export const PACKAGE_STAKER_ADDRESS = + currentEnvVariables.PACKAGE_STAKER_ADDRESS; +export const PACKAGE_GOVERNANCE_ADDRESS = + currentEnvVariables.PACKAGE_GOVERNANCE_ADDRESS; diff --git a/packages/web/src/containers/asset-list-container/AssetListContainer.tsx b/packages/web/src/containers/asset-list-container/AssetListContainer.tsx index ddba2c362..1000d2b03 100644 --- a/packages/web/src/containers/asset-list-container/AssetListContainer.tsx +++ b/packages/web/src/containers/asset-list-container/AssetListContainer.tsx @@ -37,12 +37,6 @@ export const ASSET_HEAD = { export type ASSET_HEAD = ValuesType; export interface Asset extends TokenModel { - // id: string; - // logoUri: string; - // type: ASSET_TYPE; - // name: string; - // symbol: string; - // chain: string; balance?: number | string | null; price?: any; } @@ -98,43 +92,6 @@ const DEPOSIT_INFO: TokenModel = { priceID: "gno.land/r/gns", }; -const INIT_GNOT = { - type: "native", - chainId: "dev.gnoswap", - createdAt: "0001-01-01T00:00:00Z", - name: "Gnoland", - path: "gnot", - decimals: 6, - symbol: "GNOT", - logoURI: - "https://raw.githubusercontent.com/onbloc/gno-token-resource/main/gno-native/images/gnot.svg", - priceID: "gnot", - description: - "Gno.land is a platform to write smart contracts in Gnolang (Gno). Using an interpreted version of the general-purpose programming language Golang (Go), developers can write smart contracts and other blockchain apps without having to learn a language that’s exclusive to a single ecosystem. Web2 developers can easily contribute to web3 and start building a more transparent, accountable world.\n\nThe Gno transaction token, GNOT, and the contributor memberships power the platform, which runs on a variation of Proof of Stake. Proof of Contribution rewards contributors from technical and non-technical backgrounds, fairly and for life with GNOT. This consensus mechanism also achieves higher security with fewer validators, optimizing resources for a greener, more sustainable, and enduring blockchain ecosystem.\n\nAny blockchain using Gnolang achieves succinctness, composability, expressivity, and completeness not found in any other smart contract platform. By observing a minimal structure, the design can endure over time and challenge the regime of information censorship we’re living in today.", - websiteURL: "https://gno.land/", - displayPath: "Native", - wrappedPath: "gno.land/r/demo/wugnot", - balance: "0", -} as const; - -const INIT_GNS = { - type: "grc20", - chainId: "dev.gnoswap", - createdAt: "2023-12-16T17:27:10Z", - name: "Gnoswap", - path: "gno.land/r/demo/gns", - decimals: 6, - symbol: "GNS", - logoURI: - "https://raw.githubusercontent.com/onbloc/gno-token-resource/main/grc20/images/gno_land_r_gns.svg", - priceID: "gno.land/r/demo/gns", - description: "GNS is a GRC20 token issued solely for testing purposes.", - websiteURL: "https://beta.gnoswap.io", - displayPath: "gno.land/r/demo/gns", - wrappedPath: "gno.land/r/demo/gns", - balance: "0", -} as const; - interface SortedProps extends TokenModel { balance: string; price?: string; diff --git a/packages/web/src/containers/token-info-content-container/TokenInfoContentContainer.tsx b/packages/web/src/containers/token-info-content-container/TokenInfoContentContainer.tsx index dfcd45d52..b4231c77e 100644 --- a/packages/web/src/containers/token-info-content-container/TokenInfoContentContainer.tsx +++ b/packages/web/src/containers/token-info-content-container/TokenInfoContentContainer.tsx @@ -6,8 +6,7 @@ import useRouter from "@hooks/common/use-custom-router"; import { convertToKMB } from "@utils/stake-position-utils"; import { checkPositivePrice } from "@utils/common"; import { useLoading } from "@hooks/common/use-loading"; -import { WRAPPED_GNOT_PATH as ENV_WRAPPED_GNOT_PATH } from "@common/clients/wallet-client/transaction-messages"; -const WRAPPED_GNOT_PATH = ENV_WRAPPED_GNOT_PATH || ""; +import { WRAPPED_GNOT_PATH } from "@constants/environment.constant"; export const performanceInit = [ { diff --git a/packages/web/src/containers/wallet-balance-container/WalletBalanceContainer.tsx b/packages/web/src/containers/wallet-balance-container/WalletBalanceContainer.tsx index 77b89b1c5..06696ef5b 100644 --- a/packages/web/src/containers/wallet-balance-container/WalletBalanceContainer.tsx +++ b/packages/web/src/containers/wallet-balance-container/WalletBalanceContainer.tsx @@ -21,9 +21,9 @@ import { useGetTokenPrices } from "@query/token"; import BigNumber from "bignumber.js"; import React, { useCallback, useState, useMemo } from "react"; import { useLoading } from "@hooks/common/use-loading"; -import { WRAPPED_GNOT_PATH } from "@common/clients/wallet-client/transaction-messages"; import { isEmptyObject } from "@utils/validation-utils"; import { toUnitFormat } from "@utils/number-utils"; +import { WRAPPED_GNOT_PATH } from "@constants/environment.constant"; export interface BalanceSummaryInfo { amount: string; diff --git a/packages/web/src/hooks/token/use-earn-add-liquidity-confirm-modal.tsx b/packages/web/src/hooks/token/use-earn-add-liquidity-confirm-modal.tsx index b84cfb1e7..6f8cc92ae 100644 --- a/packages/web/src/hooks/token/use-earn-add-liquidity-confirm-modal.tsx +++ b/packages/web/src/hooks/token/use-earn-add-liquidity-confirm-modal.tsx @@ -26,8 +26,8 @@ import { AddLiquidityResponse } from "@repositories/pool/response/add-liquidity- import { convertToKMB } from "@utils/stake-position-utils"; import OneClickStakingModal from "@components/common/one-click-staking-modal/OneClickStakingModal"; import { WalletResponse } from "@common/clients/wallet-client/protocols"; -import { GNS_TOKEN_PATH } from "@common/clients/wallet-client/transaction-messages"; import { useGetPoolCreationFee } from "@query/pools"; +import { GNS_TOKEN_PATH } from "@constants/environment.constant"; export interface EarnAddLiquidityConfirmModalProps { tokenA: TokenModel | null; diff --git a/packages/web/src/hooks/token/use-gnot-wugnot.tsx b/packages/web/src/hooks/token/use-gnot-wugnot.tsx index 2aa3cc6eb..a26659e89 100644 --- a/packages/web/src/hooks/token/use-gnot-wugnot.tsx +++ b/packages/web/src/hooks/token/use-gnot-wugnot.tsx @@ -1,6 +1,7 @@ -import { WRAPPED_GNOT_PATH } from "@common/clients/wallet-client/transaction-messages"; -import { useGetTokenByPath } from "@query/token"; import { useCallback } from "react"; +import { useGetTokenByPath } from "@query/token"; +import { WRAPPED_GNOT_PATH } from "@constants/environment.constant"; + const GNOT_PATH = "gnot"; export const useGnotToGnot = () => { diff --git a/packages/web/src/hooks/token/use-token-image.tsx b/packages/web/src/hooks/token/use-token-image.tsx index fd4b6d0f8..547eac295 100644 --- a/packages/web/src/hooks/token/use-token-image.tsx +++ b/packages/web/src/hooks/token/use-token-image.tsx @@ -1,6 +1,6 @@ -import { WRAPPED_GNOT_PATH } from "@common/clients/wallet-client/transaction-messages"; -import { useGetTokensList } from "@query/token"; import { useCallback } from "react"; +import { useGetTokensList } from "@query/token"; +import { WRAPPED_GNOT_PATH } from "@constants/environment.constant"; export const useTokenImage = () => { const { data: { tokens = [] } = {} } = useGetTokensList(); diff --git a/packages/web/src/hooks/wallet/use-wallet.ts b/packages/web/src/hooks/wallet/use-wallet.ts index c771ce4ae..a178de74a 100644 --- a/packages/web/src/hooks/wallet/use-wallet.ts +++ b/packages/web/src/hooks/wallet/use-wallet.ts @@ -12,8 +12,8 @@ import { GNOSWAP_SESSION_ID_KEY, GNOWSWAP_CONNECTED_KEY, } from "@states/common"; -import { DEFAULT_CHAIN_ID } from "@common/clients/wallet-client/transaction-messages"; import { useQuery, useQueryClient } from "@tanstack/react-query"; +import { CHAINS, DEFAULT_CHAIN_ID } from "@constants/environment.constant"; const CHAIN_ID = DEFAULT_CHAIN_ID; const balanceQueryKey = ["token-balance", "ugnot"]; @@ -35,11 +35,17 @@ export const useWallet = () => { }, [walletAccount]); const balanceQuery = useQuery({ - queryKey: balanceQueryKey, - queryFn: () => rpcProvider?.getBalance(walletAccount?.address || "", "ugnot"), + queryKey: [balanceQueryKey, walletAccount?.chainId || ""], + queryFn: () => + rpcProvider?.getBalance(walletAccount?.address || "", "ugnot"), refetchInterval: 5_000, + enabled: !!walletAccount?.address, }); - const { data: balance, isLoading: isLoadingBalance, isStale: isBalanceStale } = balanceQuery; + const { + data: balance, + isLoading: isLoadingBalance, + isStale: isBalanceStale, + } = balanceQuery; const wallet = useMemo(() => { if (!connected) { @@ -132,8 +138,8 @@ export const useWallet = () => { if (established.code === 0 || established.code === 4001) { const account = await accountRepository.getAccount(); sessionStorage.setItem(ACCOUNT_SESSION_INFO_KEY, JSON.stringify(account)); - const network = account.chainId === CHAIN_ID; - if (!network) { + const availNetwork = CHAINS.includes(account.chainId); + if (!availNetwork) { switchNetwork(); } setWalletAccount(account); @@ -152,17 +158,17 @@ export const useWallet = () => { try { walletClient.addEventChangedAccount(() => { queryClient.invalidateQueries({ - queryKey: balanceQueryKey + queryKey: balanceQueryKey, }); connectAdenaClient(); }); walletClient.addEventChangedNetwork(() => connectAdenaClient()); - } catch { } + } catch {} } const isSwitchNetwork = useMemo(() => { if (!walletAccount) return true; - const network = walletAccount.chainId === CHAIN_ID; + const network = CHAINS.includes(walletAccount.chainId); return network ? false : true; }, [walletAccount]); diff --git a/packages/web/src/providers/gnoswap-service-provider/GnoswapServiceProvider.tsx b/packages/web/src/providers/gnoswap-service-provider/GnoswapServiceProvider.tsx index 2e539a165..bad604827 100644 --- a/packages/web/src/providers/gnoswap-service-provider/GnoswapServiceProvider.tsx +++ b/packages/web/src/providers/gnoswap-service-provider/GnoswapServiceProvider.tsx @@ -49,8 +49,13 @@ import { LeaderboardRepository } from "@repositories/leaderboard/leaderboard-rep import { API_URL, DEFAULT_CHAIN_ID, + DEV_CHAIN_ID, ROUTER_API_URL, -} from "@common/clients/wallet-client/transaction-messages"; + DEV_API_URL, + DEV_ROUTER_API_URL, + CHAINS, +} from "@constants/environment.constant"; +import { NetworkClient } from "@common/clients/network-client"; interface GnoswapContextProps { initialized: boolean; @@ -99,11 +104,15 @@ const GnoswapServiceProvider: React.FC = ({ children, }) => { const [sessionId, setSessionId] = useAtom(CommonState.sessionId); - const [, setWalletAccount] = useAtom(WalletState.account); - const [, setStatus] = useAtom(WalletState.status); + const [walletAccount, setWalletAccount] = useAtom(WalletState.account); + const [status, setStatus] = useAtom(WalletState.status); - const [networkClient] = useState(new AxiosClient(API_URL)); - const [routerAPIClient] = useState(new AxiosClient(ROUTER_API_URL)); + const [networkClient, setNetworkClient] = useState( + null, + ); + const [routerAPIClient, setRouterAPIClient] = useState( + null, + ); const [localStorageClient, setLocalStorageClient] = useState( WebStorageClient.createLocalStorageClient(), @@ -115,21 +124,26 @@ const GnoswapServiceProvider: React.FC = ({ const [walletClient] = useAtom(WalletState.client); - const [network] = useAtom(CommonState.network); - const [rpcProvider, setRPCProvider] = useState(null); const initialized = useMemo(() => { return rpcProvider !== null && window !== undefined; }, [rpcProvider]); + const loadedProviders = useMemo(() => { + if (!networkClient || !routerAPIClient || !rpcProvider) { + return false; + } + return true; + }, [networkClient, routerAPIClient, rpcProvider]); + useEffect(() => { const sessionId = getSessionId(); const accountInfo = getAccountInfo(); const status = getStatus(); setSessionId(sessionId || ""); setWalletAccount(accountInfo); - setStatus(status); + setStatus(status || "init"); }, []); useEffect(() => { @@ -140,15 +154,35 @@ const GnoswapServiceProvider: React.FC = ({ }, [sessionId]); useEffect(() => { - const defaultChainId = DEFAULT_CHAIN_ID || ""; - const currentNetwork = - network || - ChainNetworkInfos.find(info => info.chainId === defaultChainId); - if (currentNetwork) { - const provider = new GnoJSONRPCProvider(currentNetwork.rpcUrl); - setRPCProvider(provider); + if (!status) { + return; + } + + if (status === "connected" && !walletAccount && !loadedProviders) { + return; } - }, [network]); + + const currentChainId = CHAINS.includes(walletAccount?.chainId || "") + ? walletAccount?.chainId + : DEFAULT_CHAIN_ID; + const network = + ChainNetworkInfos.find(info => info.chainId === currentChainId) || + ChainNetworkInfos[0]; + + switch (currentChainId) { + case DEV_CHAIN_ID: + setNetworkClient(new AxiosClient(DEV_API_URL)); + setRouterAPIClient(new AxiosClient(DEV_ROUTER_API_URL)); + setRPCProvider(new GnoJSONRPCProvider(network.rpcUrl || "")); + break; + case DEFAULT_CHAIN_ID: + default: + setNetworkClient(new AxiosClient(API_URL)); + setRouterAPIClient(new AxiosClient(ROUTER_API_URL)); + setRPCProvider(new GnoJSONRPCProvider(network.rpcUrl)); + break; + } + }, [loadedProviders, status, walletAccount, walletAccount?.chainId]); const accountRepository = useMemo(() => { return new AccountRepositoryImpl( @@ -217,24 +251,6 @@ const GnoswapServiceProvider: React.FC = ({ return new LeaderboardRepositoryMock(); }, []); - async function initNetwork() { - const defaultChainId = DEFAULT_CHAIN_ID; - const currentNetwork = - network || - ChainNetworkInfos.find(info => info.chainId === defaultChainId); - if (currentNetwork) { - try { - const provider = new GnoJSONRPCProvider(currentNetwork.rpcUrl); - setRPCProvider(provider); - return true; - } catch (error) { - console.log(error); - } - } - setRPCProvider(null); - return false; - } - useEffect(() => { if (window) { setLocalStorageClient(WebStorageClient.createLocalStorageClient()); @@ -242,10 +258,6 @@ const GnoswapServiceProvider: React.FC = ({ } }, []); - useEffect(() => { - initNetwork(); - }, [network]); - return ( = ({ leaderboardRepository, }} > - {rpcProvider && children} + {loadedProviders && children} ); }; diff --git a/packages/web/src/repositories/account/account-repository-impl.ts b/packages/web/src/repositories/account/account-repository-impl.ts index b25016af3..6ff34d5e3 100644 --- a/packages/web/src/repositories/account/account-repository-impl.ts +++ b/packages/web/src/repositories/account/account-repository-impl.ts @@ -18,14 +18,14 @@ import { GnoProvider } from "@gnolang/gno-js-client"; export class AccountRepositoryImpl implements AccountRepository { private walletClient: WalletClient | null; - private networkClient: NetworkClient; + private networkClient: NetworkClient | null; private rpcProvider: GnoProvider | null; private localStorageClient: StorageClient; private sessionStorageClient: StorageClient; constructor( walletClient: WalletClient | null, - networkClient: NetworkClient, + networkClient: NetworkClient | null, localStorageClient: StorageClient, sessionStorageClient: StorageClient, rpcProvider: GnoProvider | null, @@ -62,6 +62,9 @@ export class AccountRepositoryImpl implements AccountRepository { public getBalances = async ( address: string, ): Promise => { + if (!this.networkClient) { + return []; + } const response = await this.networkClient.get({ url: `/user/${address}/balance`, }); diff --git a/packages/web/src/repositories/dashboard/dashboard-repository-impl.ts b/packages/web/src/repositories/dashboard/dashboard-repository-impl.ts index 68e053ab9..cb7e68cf0 100644 --- a/packages/web/src/repositories/dashboard/dashboard-repository-impl.ts +++ b/packages/web/src/repositories/dashboard/dashboard-repository-impl.ts @@ -11,13 +11,14 @@ import { } from "./request"; import { OnchainActivityResponse } from "./response/onchain-response"; import { IVolumeResponse } from "./response/volume-response"; +import { CommonError } from "@common/errors"; export class DashboardRepositoryImpl implements DashboardRepository { - private networkClient: NetworkClient; + private networkClient: NetworkClient | null; private localStorageClient: StorageClient; constructor( - networkClient: NetworkClient, + networkClient: NetworkClient | null, localStorageClient: StorageClient, ) { this.networkClient = networkClient; @@ -25,6 +26,9 @@ export class DashboardRepositoryImpl implements DashboardRepository { } public getDashboardTvl = async (): Promise => { + if (!this.networkClient) { + throw new CommonError("FAILED_INITIALIZE_PROVIDER"); + } const { data } = await this.networkClient.get<{ data: TvlResponse }>({ url: "/dashboard/tvl", }); @@ -32,12 +36,18 @@ export class DashboardRepositoryImpl implements DashboardRepository { return data.data; }; public getDashboardVolume = async (): Promise => { + if (!this.networkClient) { + throw new CommonError("FAILED_INITIALIZE_PROVIDER"); + } const { data } = await this.networkClient.get<{ data: IVolumeResponse }>({ url: "/dashboard/volume", }); return data.data; }; public getDashboardToken = async (): Promise => { + if (!this.networkClient) { + throw new CommonError("FAILED_INITIALIZE_PROVIDER"); + } const { data } = await this.networkClient.get<{ data: DashboardTokenResponse; }>({ @@ -49,6 +59,10 @@ export class DashboardRepositoryImpl implements DashboardRepository { public getDashboardOnchainActivity = async ( request: OnchainRequest, ): Promise => { + if (!this.networkClient) { + throw new CommonError("FAILED_INITIALIZE_PROVIDER"); + } + // type: "ALL" | "ADD" | "INCREASE" | "DECREASE" | "SWAP" | "STAKE" | "UNSTAKE" | "CLAIM" | "WITHDRAW" | "REMOVE"; const response = await this.networkClient .get<{ data: OnchainActivityResponse }>({ @@ -64,6 +78,9 @@ export class DashboardRepositoryImpl implements DashboardRepository { public getAccountOnchainActivity = async ( request: OnchainAccountRequest, ): Promise => { + if (!this.networkClient) { + throw new CommonError("FAILED_INITIALIZE_PROVIDER"); + } if (!request.address) { console.log(""); } diff --git a/packages/web/src/repositories/notification/notification-repository-impl.ts b/packages/web/src/repositories/notification/notification-repository-impl.ts index 3c0884a0d..f380c724f 100644 --- a/packages/web/src/repositories/notification/notification-repository-impl.ts +++ b/packages/web/src/repositories/notification/notification-repository-impl.ts @@ -9,13 +9,14 @@ import { TransactionModel } from "@models/account/account-history-model"; import dayjs from "dayjs"; import { prettyNumberFloatInteger } from "@utils/number-utils"; import { DeleteAccountActivityRequest } from "./request/delete-account-activity-request"; +import { CommonError } from "@common/errors"; export class NotificationRepositoryImpl implements NotificationRepository { - private networkClient: NetworkClient; + private networkClient: NetworkClient | null; private storage: StorageClient; constructor( - networkClient: NetworkClient, + networkClient: NetworkClient | null, localStorageClient: StorageClient, ) { this.networkClient = networkClient; @@ -108,9 +109,11 @@ export class NotificationRepositoryImpl implements NotificationRepository { case "DEPOSIT": return `Received ${token0Amount} ${token0symbol}`; default: - return `${this.capitalizeFirstLetter(tx.actionType)} ${prettyNumberFloatInteger( - tx.tokenAAmount, - )} ${this.replaceToken(tx.tokenA.symbol ?? tx.tokenB.symbol)}`; + return `${this.capitalizeFirstLetter( + tx.actionType, + )} ${prettyNumberFloatInteger(tx.tokenAAmount)} ${this.replaceToken( + tx.tokenA.symbol ?? tx.tokenB.symbol, + )}`; } }; @@ -202,11 +205,17 @@ export class NotificationRepositoryImpl implements NotificationRepository { public getAccountOnchainActivity = async ( request: AccountActivityRequest, ): Promise => { + if (!this.networkClient) { + return []; + } if (!request?.address) { return []; } try { - const { data } = await this.networkClient.get<{ data: AccountActivity[], error: any }>({ + const { data } = await this.networkClient.get<{ + data: AccountActivity[]; + error: any; + }>({ url: "/users/" + request.address + "/activity", }); @@ -226,6 +235,9 @@ export class NotificationRepositoryImpl implements NotificationRepository { public clearNotification = async ( request: DeleteAccountActivityRequest, ): Promise => { + if (!this.networkClient) { + throw new CommonError("FAILED_INITIALIZE_PROVIDER"); + } await this.networkClient.delete({ url: "/users/" + request.address + "/activity", }); diff --git a/packages/web/src/repositories/pool/pool-repository-impl.ts b/packages/web/src/repositories/pool/pool-repository-impl.ts index 1e83ba231..202196960 100644 --- a/packages/web/src/repositories/pool/pool-repository-impl.ts +++ b/packages/web/src/repositories/pool/pool-repository-impl.ts @@ -48,16 +48,18 @@ import { } from "@common/clients/wallet-client/transaction-messages/position"; import { AddLiquidityResponse } from "./response/add-liquidity-response"; import { CreatePoolResponse } from "./response/create-pool-response"; +import { + makeApproveMessage, + TransactionMessage, +} from "@common/clients/wallet-client/transaction-messages"; import { PACKAGE_POOL_ADDRESS, PACKAGE_POOL_PATH, GNS_TOKEN_PATH, PACKAGE_POSITION_ADDRESS, - makeApproveMessage, WRAPPED_GNOT_PATH, - TransactionMessage, PACKAGE_GNOSWAP_CONST_PATH, -} from "@common/clients/wallet-client/transaction-messages"; +} from "@constants/environment.constant"; import { MAX_UINT64, tickToSqrtPriceX96 } from "@utils/math.utils"; import { PoolBinModel } from "@models/pool/pool-bin-model"; import { @@ -72,12 +74,12 @@ const POOL_PATH = PACKAGE_POOL_PATH || ""; const POOL_ADDRESS = PACKAGE_POOL_ADDRESS || ""; export class PoolRepositoryImpl implements PoolRepository { - private networkClient: NetworkClient; + private networkClient: NetworkClient | null; private rpcProvider: GnoProvider | null; private walletClient: WalletClient | null; constructor( - networkClient: NetworkClient, + networkClient: NetworkClient | null, rpcProvider: GnoProvider | null, walletClient: WalletClient | null, ) { @@ -130,6 +132,9 @@ export class PoolRepositoryImpl implements PoolRepository { }; getPools = async (): Promise => { + if (!this.networkClient) { + return []; + } const response = await this.networkClient.get({ url: "/pools", }); @@ -140,6 +145,9 @@ export class PoolRepositoryImpl implements PoolRepository { }; getIncentivizePools = async (): Promise => { + if (!this.networkClient) { + return []; + } const response = await this.networkClient.get({ url: "/incentivize/pools", }); @@ -153,6 +161,9 @@ export class PoolRepositoryImpl implements PoolRepository { getPoolDetailByPoolPath = async ( poolPath: string, ): Promise => { + if (!this.networkClient) { + throw new CommonError("FAILED_INITIALIZE_PROVIDER"); + } const pool = await this.networkClient .get<{ data: PoolResponse }>({ url: "/pools/" + encodeURIComponent(poolPath), @@ -165,6 +176,9 @@ export class PoolRepositoryImpl implements PoolRepository { poolPath: string, count?: number, ): Promise => { + if (!this.networkClient) { + throw new CommonError("FAILED_INITIALIZE_PROVIDER"); + } return this.networkClient .get<{ data: PoolBinModel[] }>({ url: `/pools/${encodeURIComponent(poolPath)}/bins?bins=${count || 40}`, @@ -482,6 +496,9 @@ export class PoolRepositoryImpl implements PoolRepository { getPoolDetailByPath = async ( poolPath: string, ): Promise => { + if (!this.networkClient) { + throw new CommonError("FAILED_INITIALIZE_PROVIDER"); + } const response = await this.networkClient.get({ url: "/pools/" + poolPath, }); diff --git a/packages/web/src/repositories/position/position-repository-impl.ts b/packages/web/src/repositories/position/position-repository-impl.ts index 322aae185..73530cbba 100644 --- a/packages/web/src/repositories/position/position-repository-impl.ts +++ b/packages/web/src/repositories/position/position-repository-impl.ts @@ -36,12 +36,14 @@ import { IPositionHistoryModel } from "@models/position/position-history-model"; import { PositionHistoryMapper } from "@models/position/mapper/position-history-mapper"; import { IPositionHistoryResponse } from "./response/position-history-response"; import { - PACKAGE_POOL_ADDRESS, - PACKAGE_STAKER_ADDRESS, TransactionMessage, - WRAPPED_GNOT_PATH, makeApproveMessage, } from "@common/clients/wallet-client/transaction-messages"; +import { + PACKAGE_POOL_ADDRESS, + PACKAGE_STAKER_ADDRESS, + WRAPPED_GNOT_PATH, +} from "@constants/environment.constant"; import { MAX_INT64, MAX_UINT64 } from "@utils/math.utils"; import { DecreaseLiquidityRequest, IncreaseLiquidityRequest } from "./request"; import { checkGnotPath, isGNOTPath } from "@utils/common"; @@ -51,12 +53,12 @@ import { PositionBinModel } from "@models/position/position-bin-model"; import { PositionBinMapper } from "@models/position/mapper/position-bin-mapper"; export class PositionRepositoryImpl implements PositionRepository { - private networkClient: NetworkClient; + private networkClient: NetworkClient | null; private rpcProvider: GnoProvider | null; private walletClient: WalletClient | null; constructor( - networkClient: NetworkClient, + networkClient: NetworkClient | null, rpcProvider: GnoProvider | null, walletClient: WalletClient | null, ) { @@ -68,6 +70,9 @@ export class PositionRepositoryImpl implements PositionRepository { getPositionHistory = async ( lpTokenId: string, ): Promise => { + if (!this.networkClient) { + throw new CommonError("FAILED_INITIALIZE_PROVIDER"); + } const response = await this.networkClient.get<{ data: IPositionHistoryResponse[]; }>({ @@ -80,6 +85,9 @@ export class PositionRepositoryImpl implements PositionRepository { lpTokenId: string, count: 20 | 40, ): Promise => { + if (!this.networkClient) { + throw new CommonError("FAILED_INITIALIZE_PROVIDER"); + } const response = await this.networkClient.get<{ data: PositionBinResponse[]; }>({ @@ -92,6 +100,9 @@ export class PositionRepositoryImpl implements PositionRepository { address: string, options?: { isClosed?: boolean }, ): Promise => { + if (!this.networkClient) { + throw new CommonError("FAILED_INITIALIZE_PROVIDER"); + } const response = await this.networkClient.get<{ data: PositionListResponse; }>({ diff --git a/packages/web/src/repositories/swap/swap-repository-impl.ts b/packages/web/src/repositories/swap/swap-repository-impl.ts index 61fd89840..df3c761f9 100644 --- a/packages/web/src/repositories/swap/swap-repository-impl.ts +++ b/packages/web/src/repositories/swap/swap-repository-impl.ts @@ -23,7 +23,7 @@ import { SwapPoolResponse } from "./response/swap-pool-response"; import { makeSwapFeeTier } from "@utils/swap-utils"; import { CommonError } from "@common/errors"; import { SwapError } from "@common/errors/swap"; -import { PACKAGE_POOL_ADDRESS, PACKAGE_POOL_PATH } from "@common/clients/wallet-client/transaction-messages"; +import { PACKAGE_POOL_ADDRESS, PACKAGE_POOL_PATH } from "@constants/environment.constant"; const POOL_ADDRESS = PACKAGE_POOL_ADDRESS || ""; diff --git a/packages/web/src/repositories/swap/swap-router-repository-impl.ts b/packages/web/src/repositories/swap/swap-router-repository-impl.ts index f8e2de4b5..5887a8837 100644 --- a/packages/web/src/repositories/swap/swap-router-repository-impl.ts +++ b/packages/web/src/repositories/swap/swap-router-repository-impl.ts @@ -28,26 +28,24 @@ import { WrapTokenRequest } from "./request/wrap-token-request"; import { TokenError } from "@common/errors/token"; import { UnwrapTokenRequest } from "./request/unwrap-token-request"; import { SwapRouteResponse } from "./response/swap-route-response"; -import { - PACKAGE_ROUTER_PATH, - TransactionMessage, -} from "@common/clients/wallet-client/transaction-messages"; +import { TransactionMessage } from "@common/clients/wallet-client/transaction-messages"; import { checkGnotPath, toNativePath } from "@utils/common"; import { NetworkClient } from "@common/clients/network-client"; import { EstimatedRoute } from "@models/swap/swap-route-info"; +import { PACKAGE_ROUTER_PATH } from "@constants/environment.constant"; const ROUTER_PACKAGE_PATH = PACKAGE_ROUTER_PATH; export class SwapRouterRepositoryImpl implements SwapRouterRepository { private rpcProvider: GnoProvider | null; - private networkClient: NetworkClient; + private networkClient: NetworkClient | null; private walletClient: WalletClient | null; private pools: PoolRPCModel[]; constructor( rpcProvider: GnoProvider | null, walletClient: WalletClient | null, - networkClient: NetworkClient, + networkClient: NetworkClient | null, ) { this.rpcProvider = rpcProvider; this.walletClient = walletClient; @@ -64,6 +62,10 @@ export class SwapRouterRepositoryImpl implements SwapRouterRepository { ): Promise => { const { inputToken, outputToken, exactType, tokenAmount } = request; + if (!this.networkClient) { + throw new CommonError("FAILED_INITIALIZE_PROVIDER"); + } + if (BigNumber(tokenAmount).isNaN()) { throw new SwapError("INVALID_PARAMS"); } diff --git a/packages/web/src/repositories/token/token-repository-impl.ts b/packages/web/src/repositories/token/token-repository-impl.ts index 9ff2a7a63..b037a4bfe 100644 --- a/packages/web/src/repositories/token/token-repository-impl.ts +++ b/packages/web/src/repositories/token/token-repository-impl.ts @@ -16,24 +16,29 @@ import { IBalancesByAddressResponse } from "./response/balance-by-address-respon import { customSort } from "@containers/select-token-container/SelectTokenContainer"; import mockedExchangeRateGraph from "./mock/token-exchange-rate-graph.json"; import { TokenExchangeRateGraphResponse } from "./response/token-exchange-rate-response"; +import { CommonError } from "@common/errors"; export class TokenRepositoryImpl implements TokenRepository { - private networkClient: NetworkClient; + private networkClient: NetworkClient | null; private localStorageClient: StorageClient; constructor( - networkClient: NetworkClient, + networkClient: NetworkClient | null, localStorageClient: StorageClient, ) { this.networkClient = networkClient; this.localStorageClient = localStorageClient; } - public getExchangeRateGraph = async (): Promise => { - return mockedExchangeRateGraph; - }; + public getExchangeRateGraph = + async (): Promise => { + return mockedExchangeRateGraph; + }; public getTokenByPath = async (path: string): Promise => { + if (!this.networkClient) { + throw new CommonError("FAILED_INITIALIZE_PROVIDER"); + } const tempPath = path.replace(/\//g, "%2F"); const response = await this.networkClient.get<{ data: ITokenResponse }>({ url: `/token-metas/${tempPath}`, @@ -42,6 +47,9 @@ export class TokenRepositoryImpl implements TokenRepository { }; public getTokens = async (): Promise => { + if (!this.networkClient) { + throw new CommonError("FAILED_INITIALIZE_PROVIDER"); + } const response = await this.networkClient.get<{ data: ITokenResponse[] }>({ url: "/token-metas", }); @@ -53,6 +61,9 @@ export class TokenRepositoryImpl implements TokenRepository { }; public getTokenPrices = async (): Promise => { + if (!this.networkClient) { + throw new CommonError("FAILED_INITIALIZE_PROVIDER"); + } const response = await this.networkClient.get({ url: "/tokens/prices", }); @@ -62,14 +73,22 @@ export class TokenRepositoryImpl implements TokenRepository { public getTokenDetailByPath = async ( path: string, ): Promise => { + if (!this.networkClient) { + throw new CommonError("FAILED_INITIALIZE_PROVIDER"); + } const tempPath = path.replace(/\//g, "%2F"); - const response = await this.networkClient.get<{ data: ITokenDetailResponse }>({ + const response = await this.networkClient.get<{ + data: ITokenDetailResponse; + }>({ url: `/tokens/${tempPath}/details`, }); return response.data.data; }; public getChain = async (): Promise => { + if (!this.networkClient) { + throw new CommonError("FAILED_INITIALIZE_PROVIDER"); + } const response = await this.networkClient.get<{ data: IChainResponse }>({ url: "/chain", }); @@ -79,6 +98,9 @@ export class TokenRepositoryImpl implements TokenRepository { public getBalancesByAddress = async ( address: string, ): Promise => { + if (!this.networkClient) { + throw new CommonError("FAILED_INITIALIZE_PROVIDER"); + } const response = await this.networkClient.get({ url: `/balances/${address}`, }); diff --git a/packages/web/src/resources/chains.json b/packages/web/src/resources/chains.json index 912bbf692..cc9df720f 100644 --- a/packages/web/src/resources/chains.json +++ b/packages/web/src/resources/chains.json @@ -1,4 +1,10 @@ [ + { + "name": "GNO.LAND", + "chainId": "portal-loop", + "rpcUrl": "https://rpc.gno.land", + "wsUrl": "wss://rpc.gno.land/websocket" + }, { "name": "GNO.LAND", "chainId": "test3", diff --git a/packages/web/src/utils/common.ts b/packages/web/src/utils/common.ts index 3de8bfdd0..691c79551 100644 --- a/packages/web/src/utils/common.ts +++ b/packages/web/src/utils/common.ts @@ -1,6 +1,6 @@ import { MATH_NEGATIVE_TYPE } from "@constants/option.constant"; import { convertToMB } from "./stake-position-utils"; -import { WRAPPED_GNOT_PATH } from "@common/clients/wallet-client/transaction-messages"; +import { WRAPPED_GNOT_PATH } from "@constants/environment.constant"; import { TokenModel } from "@models/token/token-model"; import { formatUsdNumber3Digits } from "./number-utils";