From 05c67684742a126504dcff5aeec1080b30e4fdd3 Mon Sep 17 00:00:00 2001 From: Yana Date: Wed, 18 Jun 2025 19:57:13 +0300 Subject: [PATCH] Add Sandbox to wallet, staking, replace SpectreDao balances --- explorer-v2/src/app/api/index.tsx | 60 ++++++++++++++----- explorer-v2/src/app/api/types.ts | 18 ------ explorer-v2/src/app/api/urls.ts | 5 +- .../src/components/nodeTable/NodeTable.tsx | 5 +- .../nymNodePageComponents/NodeProfileCard.tsx | 5 +- .../components/staking/OriginalStakeCard.tsx | 4 +- .../src/components/staking/StakeTable.tsx | 44 +++++++------- .../staking/SubHeaderRowActions.tsx | 47 +++++++++------ .../components/staking/TotalRewardsCard.tsx | 4 +- .../src/components/staking/TotalStakeCard.tsx | 4 +- .../src/components/wallet/ConnectWallet.tsx | 7 ++- .../src/components/wallet/WalletBalance.tsx | 6 +- explorer-v2/src/config/index.ts | 6 +- explorer-v2/src/hooks/useGetWalletBalance.tsx | 6 +- explorer-v2/src/hooks/useNymClient.ts | 19 ++++-- 15 files changed, 145 insertions(+), 95 deletions(-) diff --git a/explorer-v2/src/app/api/index.tsx b/explorer-v2/src/app/api/index.tsx index 7a50d412d9..3234cd21e8 100644 --- a/explorer-v2/src/app/api/index.tsx +++ b/explorer-v2/src/app/api/index.tsx @@ -12,12 +12,10 @@ import type { NS_NODE, NodeRewardDetails, NymTokenomics, - ObservatoryBalance, } from "./types"; import { CURRENT_EPOCH, CURRENT_EPOCH_REWARDS, - DATA_OBSERVATORY_BALANCES_URL, NS_API_MIXNODES_STATS, NS_API_NODES, NYM_ACCOUNT_ADDRESS, @@ -29,6 +27,7 @@ import { SANDBOX_NS_API_NODES, SANDBOX_NYM_ACCOUNT_ADDRESS, } from "./urls"; +import { Delegation } from "@nymproject/contract-clients/Mixnet.types"; // Fetch function for epoch rewards export const fetchEpochRewards = async ( @@ -123,8 +122,15 @@ export const fetchCurrentEpoch = async (environment: Environment) => { }; // Fetch balances based on the address -export const fetchBalances = async (address: string): Promise => { - const response = await fetch(`${DATA_OBSERVATORY_BALANCES_URL}/${address}`, { +export const fetchBalances = async ( + address: string, + environment: Environment +): Promise => { + const baseUrl = + environment === "sandbox" + ? SANDBOX_NYM_ACCOUNT_ADDRESS + : NYM_ACCOUNT_ADDRESS; + const response = await fetch(`${baseUrl}/${address}`, { headers: { Accept: "application/json", "Content-Type": "application/json; charset=utf-8", @@ -135,20 +141,26 @@ export const fetchBalances = async (address: string): Promise => { throw new Error("Failed to fetch balances"); } - const balances: ObservatoryBalance = await response.json(); + const balances: IAccountBalancesInfo = await response.json(); // Calculate total stake return ( - Number(balances.rewards.staking_rewards.amount) + - Number(balances.delegated.amount) + Number(balances.claimable_rewards.amount) + + Number(balances.total_delegations.amount) ); }; // Fetch function to get total staker rewards export const fetchTotalStakerRewards = async ( - address: string + address: string, + environment: Environment ): Promise => { - const response = await fetch(`${DATA_OBSERVATORY_BALANCES_URL}/${address}`, { + const baseUrl = + environment === "sandbox" + ? SANDBOX_NYM_ACCOUNT_ADDRESS + : NYM_ACCOUNT_ADDRESS; + + const response = await fetch(`${baseUrl}/${address}`, { headers: { Accept: "application/json", "Content-Type": "application/json; charset=utf-8", @@ -159,15 +171,22 @@ export const fetchTotalStakerRewards = async ( throw new Error("Failed to fetch balances"); } - const balances: ObservatoryBalance = await response.json(); + const balances: IAccountBalancesInfo = await response.json(); // Return the staking rewards amount - return Number(balances.rewards.staking_rewards.amount); + return Number(balances.claimable_rewards.amount); }; // Fetch function to get the original stake -export const fetchOriginalStake = async (address: string): Promise => { - const response = await fetch(`${DATA_OBSERVATORY_BALANCES_URL}/${address}`, { +export const fetchOriginalStake = async ( + address: string, + environment: Environment +): Promise => { + const baseUrl = + environment === "sandbox" + ? SANDBOX_NYM_ACCOUNT_ADDRESS + : NYM_ACCOUNT_ADDRESS; + const response = await fetch(`${baseUrl}/${address}`, { headers: { Accept: "application/json", "Content-Type": "application/json; charset=utf-8", @@ -178,10 +197,10 @@ export const fetchOriginalStake = async (address: string): Promise => { throw new Error("Failed to fetch balances"); } - const balances: ObservatoryBalance = await response.json(); + const balances: IAccountBalancesInfo = await response.json(); // Return the delegated amount - return Number(balances.delegated.amount); + return Number(balances.total_delegations.amount); }; export const fetchNoise = async ( @@ -351,8 +370,17 @@ export const fetchWorldMapCountries = async ( totalCountries: Object.keys(countryCounts).length, uniqueLocations: uniqueCities.size, totalServers: nodes.length, - environment, }; }; +export const fetchDelegations = async ( + address: string, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + nymClient: any +): Promise => { + const data = await nymClient.getDelegatorDelegations({ delegator: address }); + console.log("data", data); + return data.delegations; +}; + diff --git a/explorer-v2/src/app/api/types.ts b/explorer-v2/src/app/api/types.ts index 6ff82a4d86..380c88be60 100644 --- a/explorer-v2/src/app/api/types.ts +++ b/explorer-v2/src/app/api/types.ts @@ -324,24 +324,6 @@ export type GatewayStatus = { }; }; -type BalanceDetails = { - amount: number; - denom: string; -}; - -export type ObservatoryRewards = { - operator_commissions: BalanceDetails; - staking_rewards: BalanceDetails; - unlocked: BalanceDetails; -}; - -export type ObservatoryBalance = { - delegated: BalanceDetails; - locked: BalanceDetails; - rewards: ObservatoryRewards; - self_bonded: BalanceDetails; - spendable: BalanceDetails; -}; export type Quote = { ath_date: string; diff --git a/explorer-v2/src/app/api/urls.ts b/explorer-v2/src/app/api/urls.ts index f1392a8710..6c8f9cc80c 100644 --- a/explorer-v2/src/app/api/urls.ts +++ b/explorer-v2/src/app/api/urls.ts @@ -11,7 +11,7 @@ export const SANDBOX_CURRENT_EPOCH_REWARDS = export const NYM_ACCOUNT_ADDRESS = "https://validator.nymtech.net/api/v1/unstable/account"; export const SANDBOX_NYM_ACCOUNT_ADDRESS = - "https://sandbox-nym-api1.nymtech.net/api/v1/unstable/account/"; + "https://sandbox-nym-api1.nymtech.net/api/v1/unstable/account"; export const NYM_PRICES_API = "https://api.nym.spectredao.net/api/v1/nym-price"; @@ -19,9 +19,6 @@ export const VALIDATOR_BASE_URL = process.env.NEXT_PUBLIC_VALIDATOR_URL || "https://rpc.nymtech.net"; export const SANDBOX_VALIDATOR_BASE_URL = "https://rpc.sandbox.nymtech.net"; -export const DATA_OBSERVATORY_BALANCES_URL = - "https://api.nym.spectredao.net/api/v1/balances"; - export const OBSERVATORY_GATEWAYS_URL = "https://mainnet-node-status-api.nymtech.cc/v2/gateways"; diff --git a/explorer-v2/src/components/nodeTable/NodeTable.tsx b/explorer-v2/src/components/nodeTable/NodeTable.tsx index 78223a8be0..abd125147f 100644 --- a/explorer-v2/src/components/nodeTable/NodeTable.tsx +++ b/explorer-v2/src/components/nodeTable/NodeTable.tsx @@ -31,6 +31,7 @@ import { fee } from "../staking/schemas"; import ConnectWallet from "../wallet/ConnectWallet"; import type { MappedNymNode, MappedNymNodes } from "./NodeTableWithAction"; import CopyToClipboard from "../copyToClipboard/CopyToClipboard"; +import { useEnvironment } from "@/providers/EnvironmentProvider"; const ColumnHeading = ({ children, @@ -84,7 +85,9 @@ const NodeTable = ({ nodes }: { nodes: MappedNymNodes }) => { identityKey: string; }>(); const [favorites] = useLocalStorage("nym-node-favorites", []); - const { isWalletConnected } = useChain(COSMOS_KIT_USE_CHAIN); + const { environment } = useEnvironment(); + const chain = environment === "mainnet" ? COSMOS_KIT_USE_CHAIN : "sandbox"; + const { isWalletConnected } = useChain(chain); const handleRefetch = useCallback(async () => { await queryClient.invalidateQueries(); diff --git a/explorer-v2/src/components/nymNodePageComponents/NodeProfileCard.tsx b/explorer-v2/src/components/nymNodePageComponents/NodeProfileCard.tsx index ff7d9bab94..c3790bfc9b 100644 --- a/explorer-v2/src/components/nymNodePageComponents/NodeProfileCard.tsx +++ b/explorer-v2/src/components/nymNodePageComponents/NodeProfileCard.tsx @@ -34,8 +34,10 @@ type Props = { export const NodeProfileCard = ({ paramId }: Props) => { let nodeInfo: NS_NODE | undefined; const theme = useTheme(); + const { environment } = useEnvironment(); + const chain = environment === "mainnet" ? COSMOS_KIT_USE_CHAIN : "sandbox"; - const { isWalletConnected } = useChain(COSMOS_KIT_USE_CHAIN); + const { isWalletConnected } = useChain(chain); const { nymClient } = useNymClient(); const [infoModalProps, setInfoModalProps] = useState({ open: false, @@ -45,7 +47,6 @@ export const NodeProfileCard = ({ paramId }: Props) => { nodeId: number; identityKey: string; }>(); - const { environment } = useEnvironment(); // Fetch node info const { diff --git a/explorer-v2/src/components/staking/OriginalStakeCard.tsx b/explorer-v2/src/components/staking/OriginalStakeCard.tsx index 62a9785d4b..8294c5456d 100644 --- a/explorer-v2/src/components/staking/OriginalStakeCard.tsx +++ b/explorer-v2/src/components/staking/OriginalStakeCard.tsx @@ -6,11 +6,13 @@ import { fetchOriginalStake } from "../../app/api"; import { useNymClient } from "../../hooks/useNymClient"; import { formatBigNum } from "../../utils/formatBigNumbers"; import ExplorerCard from "../cards/ExplorerCard"; +import { useEnvironment } from "@/providers/EnvironmentProvider"; const OriginalStakeCard = () => { const { address } = useNymClient(); const theme = useTheme(); const isDarkMode = theme.palette.mode === "dark"; + const { environment } = useEnvironment(); // Use React Query to fetch original stake const { @@ -19,7 +21,7 @@ const OriginalStakeCard = () => { isError, } = useQuery({ queryKey: ["originalStake", address], - queryFn: () => fetchOriginalStake(address || ""), + queryFn: () => fetchOriginalStake(address || "", environment), enabled: !!address, // Only fetch if address exists staleTime: 10 * 60 * 1000, // 10 minutes refetchOnWindowFocus: false, // Prevents unnecessary refetching diff --git a/explorer-v2/src/components/staking/StakeTable.tsx b/explorer-v2/src/components/staking/StakeTable.tsx index 039487c381..e8d923ff5e 100644 --- a/explorer-v2/src/components/staking/StakeTable.tsx +++ b/explorer-v2/src/components/staking/StakeTable.tsx @@ -37,7 +37,7 @@ import StakeActions from "./StakeActions"; import StakeModal from "./StakeModal"; import type { MappedNymNode, MappedNymNodes } from "./StakeTableWithAction"; import { fee } from "./schemas"; - +import { useEnvironment } from "@/providers/EnvironmentProvider"; type DelegationWithNodeDetails = { node: MappedNymNode | undefined; @@ -83,7 +83,7 @@ const ColumnHeading = ({ const StakeTable = ({ nodes }: { nodes: MappedNymNodes }) => { const { nymClient, address, nymQueryClient } = useNymClient(); const [delegations, setDelegations] = useState( - [], + [] ); const [isDataLoading, setIsLoading] = useState(false); const [infoModalProps, setInfoModalProps] = useState({ @@ -94,7 +94,9 @@ const StakeTable = ({ nodes }: { nodes: MappedNymNodes }) => { identityKey: string; }>(); const [favorites] = useLocalStorage("nym-node-favorites", []); - const { isWalletConnected } = useChain(COSMOS_KIT_USE_CHAIN); + const { environment } = useEnvironment(); + const chain = environment === "mainnet" ? COSMOS_KIT_USE_CHAIN : "sandbox"; + const { isWalletConnected } = useChain(chain); const { data: pendingEvents } = usePendingEvents(nymQueryClient, address); const theme = useTheme(); @@ -122,13 +124,13 @@ const StakeTable = ({ nodes }: { nodes: MappedNymNodes }) => { const combineDelegationsWithNodeAndPendingEvents = ( delegations: Delegation[], nodes: MappedNymNode[], - pendingEvents: PendingEvent[] | undefined, + pendingEvents: PendingEvent[] | undefined ) => { // Combine delegations with node details const delegationsWithNodeDetails = delegations.map((delegation) => { const node = nodes.find((node) => node.nodeId === delegation.node_id); const pendingEvent = pendingEvents?.find( - (event) => event?.mixId === delegation.node_id, + (event) => event?.mixId === delegation.node_id ); return { @@ -146,7 +148,7 @@ const StakeTable = ({ nodes }: { nodes: MappedNymNodes }) => { !delegationsWithNodeDetails.find( (item) => item.node?.nodeId === e.mixId || - item.delegation.node_id === e.mixId, + item.delegation.node_id === e.mixId ) ) { delegationsWithNodeDetails.push({ @@ -186,7 +188,7 @@ const StakeTable = ({ nodes }: { nodes: MappedNymNodes }) => { combineDelegationsWithNodeAndPendingEvents( delegations, nodes, - pendingEvents, + pendingEvents ); setDelegations(delegationsWithNodeDetails); @@ -207,7 +209,7 @@ const StakeTable = ({ nodes }: { nodes: MappedNymNodes }) => { { nodeId }, fee, "Delegation from Nym Explorer V2", - uNymFunds, + uNymFunds ); setSelectedNodeForStaking(undefined); @@ -236,7 +238,7 @@ const StakeTable = ({ nodes }: { nodes: MappedNymNodes }) => { } setIsLoading(false); }, - [nymClient, handleRefetch], + [nymClient, handleRefetch] ); const handleOnSelectStake = useCallback( @@ -267,7 +269,7 @@ const StakeTable = ({ nodes }: { nodes: MappedNymNodes }) => { }); } }, - [isWalletConnected], + [isWalletConnected] ); const handleUnstake = useCallback( @@ -282,7 +284,7 @@ const StakeTable = ({ nodes }: { nodes: MappedNymNodes }) => { nodeId, }, fee, - `Explorer V2: Unstaking node ${nodeId}`, + `Explorer V2: Unstaking node ${nodeId}` ); setIsLoading(false); await handleRefetch(); @@ -307,7 +309,7 @@ const StakeTable = ({ nodes }: { nodes: MappedNymNodes }) => { setIsLoading(false); } }, - [address, nymClient, handleRefetch], + [address, nymClient, handleRefetch] ); const handleActionSelect = useCallback( @@ -323,7 +325,7 @@ const StakeTable = ({ nodes }: { nodes: MappedNymNodes }) => { break; } }, - [handleUnstake, handleOnSelectStake], + [handleUnstake, handleOnSelectStake] ); const getTooltipTitle = useCallback( @@ -334,13 +336,13 @@ const StakeTable = ({ nodes }: { nodes: MappedNymNodes }) => { if (pending?.kind === "delegate") { return `You have a delegation pending worth ${formatBigNum( - +pending.amount.amount / 1_000_000, + +pending.amount.amount / 1_000_000 )} NYM`; } return undefined; }, - [], // Add dependencies if necessary + [] // Add dependencies if necessary ); const columns: MRT_ColumnDef[] = useMemo( @@ -419,10 +421,10 @@ const StakeTable = ({ nodes }: { nodes: MappedNymNodes }) => { sortingFn: (rowA, rowB) => { const stakeA = Number.parseFloat( - rowA.original.delegation.amount.amount, + rowA.original.delegation.amount.amount ); const stakeB = Number.parseFloat( - rowB.original.delegation.amount.amount, + rowB.original.delegation.amount.amount ); return stakeA - stakeB; }, @@ -467,10 +469,10 @@ const StakeTable = ({ nodes }: { nodes: MappedNymNodes }) => { ), sortingFn: (rowA, rowB) => { const isFavoriteA = favorites.includes( - rowA.original.node?.owner || "-", + rowA.original.node?.owner || "-" ); const isFavoriteB = favorites.includes( - rowB.original.node?.owner || "-", + rowB.original.node?.owner || "-" ); // Sort favorites first @@ -510,7 +512,7 @@ const StakeTable = ({ nodes }: { nodes: MappedNymNodes }) => { handleActionSelect( action, row.original.delegation?.node_id, - row.original.node?.identity_key || undefined, + row.original.node?.identity_key || undefined ); }} /> @@ -520,7 +522,7 @@ const StakeTable = ({ nodes }: { nodes: MappedNymNodes }) => { }, }, ], - [handleActionSelect, favorites, getTooltipTitle], + [handleActionSelect, favorites, getTooltipTitle] ); const table = useMaterialReactTable({ diff --git a/explorer-v2/src/components/staking/SubHeaderRowActions.tsx b/explorer-v2/src/components/staking/SubHeaderRowActions.tsx index a8335ae1bc..4aac9c6cb1 100644 --- a/explorer-v2/src/components/staking/SubHeaderRowActions.tsx +++ b/explorer-v2/src/components/staking/SubHeaderRowActions.tsx @@ -7,22 +7,19 @@ import { Button, Stack } from "@mui/material"; import type { Delegation } from "@nymproject/contract-clients/Mixnet.types"; import { useQuery, useQueryClient } from "@tanstack/react-query"; import { useCallback, useState } from "react"; -import { fetchTotalStakerRewards } from "../../app/api"; -import { COSMOS_KIT_USE_CHAIN, NYM_MIXNET_CONTRACT } from "../../config"; +import { fetchDelegations, fetchTotalStakerRewards } from "../../app/api"; +import { + COSMOS_KIT_USE_CHAIN, + NYM_MIXNET_CONTRACT, + SANDBOX_MIXNET_CONTRACT_ADDRESS, +} from "../../config"; import { useNymClient } from "../../hooks/useNymClient"; import Loading from "../loading"; import InfoModal, { type InfoModalProps } from "../modal/InfoModal"; import RedeemRewardsModal from "../redeemRewards/RedeemRewardsModal"; - +import { useEnvironment } from "@/providers/EnvironmentProvider"; +import { SANDBOX_VALIDATOR_BASE_URL, VALIDATOR_BASE_URL } from "@/app/api/urls"; // Fetch delegations -const fetchDelegations = async ( - address: string, - // eslint-disable-next-line @typescript-eslint/no-explicit-any - nymClient: any -): Promise => { - const data = await nymClient.getDelegatorDelegations({ delegator: address }); - return data.delegations; -}; const SubHeaderRowActions = () => { const [openRedeemRewardsModal, setOpenRedeemRewardsModal] = @@ -31,9 +28,18 @@ const SubHeaderRowActions = () => { const [infoModalProps, setInfoModalProps] = useState({ open: false, }); + const { environment } = useEnvironment(); + const chain = environment === "mainnet" ? COSMOS_KIT_USE_CHAIN : "sandbox"; + const mixnetContractAddress = + environment === "mainnet" + ? NYM_MIXNET_CONTRACT + : SANDBOX_MIXNET_CONTRACT_ADDRESS; + + const rpcAddress = + environment === "mainnet" ? VALIDATOR_BASE_URL : SANDBOX_VALIDATOR_BASE_URL; const { address, nymClient } = useNymClient(); - const { getOfflineSigner } = useChain(COSMOS_KIT_USE_CHAIN); + const { getOfflineSigner } = useChain(chain); const queryClient = useQueryClient(); @@ -56,7 +62,7 @@ const SubHeaderRowActions = () => { refetch, } = useQuery({ queryKey: ["totalStakerRewards", address], - queryFn: () => fetchTotalStakerRewards(address || ""), + queryFn: () => fetchTotalStakerRewards(address || "", environment), enabled: !!address, // Only fetch if address is available staleTime: 10 * 60 * 1000, // 10 minutes refetchOnWindowFocus: false, // Prevents unnecessary refetching @@ -64,8 +70,8 @@ const SubHeaderRowActions = () => { }); const handleRefetch = useCallback(async () => { - refetch(); - queryClient.invalidateQueries(); // This will refetch ALL active queries + await refetch(); + await queryClient.invalidateQueries(); // This will refetch ALL active queries }, [queryClient, refetch]); const handleRedeemRewards = useCallback(async () => { @@ -81,13 +87,13 @@ const SubHeaderRowActions = () => { const gasPrice = GasPrice.fromString("0.025unym"); const client = await SigningCosmWasmClient.connectWithSigner( - "https://rpc.nymtech.net/", + rpcAddress, signer, { gasPrice } ); const messages = delegations.map((delegation: Delegation) => ({ - contractAddress: NYM_MIXNET_CONTRACT, + contractAddress: mixnetContractAddress, funds: [], msg: { withdraw_delegator_reward: { @@ -111,8 +117,11 @@ const SubHeaderRowActions = () => { tx: result?.transactionHash, onClose: async () => { - await handleRefetch(); - setInfoModalProps({ open: false }); + try { + await handleRefetch(); + } finally { + setInfoModalProps({ open: false }); + } }, }); } catch (error) { diff --git a/explorer-v2/src/components/staking/TotalRewardsCard.tsx b/explorer-v2/src/components/staking/TotalRewardsCard.tsx index cc9a4ac67e..fe7910f534 100644 --- a/explorer-v2/src/components/staking/TotalRewardsCard.tsx +++ b/explorer-v2/src/components/staking/TotalRewardsCard.tsx @@ -6,11 +6,13 @@ import { fetchTotalStakerRewards } from "../../app/api"; import { useNymClient } from "../../hooks/useNymClient"; import { formatBigNum } from "../../utils/formatBigNumbers"; import ExplorerCard from "../cards/ExplorerCard"; +import { useEnvironment } from "@/providers/EnvironmentProvider"; const TotalRewardsCard = () => { const { address } = useNymClient(); const theme = useTheme(); const isDarkMode = theme.palette.mode === "dark"; + const { environment } = useEnvironment(); // Use React Query to fetch total rewards const { @@ -19,7 +21,7 @@ const TotalRewardsCard = () => { isError, } = useQuery({ queryKey: ["totalStakerRewards", address], - queryFn: () => fetchTotalStakerRewards(address || ""), + queryFn: () => fetchTotalStakerRewards(address || "", environment), enabled: !!address, // Only fetch if address exists staleTime: 10 * 60 * 1000, // 10 minutes refetchOnWindowFocus: false, // Prevents unnecessary refetching diff --git a/explorer-v2/src/components/staking/TotalStakeCard.tsx b/explorer-v2/src/components/staking/TotalStakeCard.tsx index 7ec1982fb3..88196fb7cc 100644 --- a/explorer-v2/src/components/staking/TotalStakeCard.tsx +++ b/explorer-v2/src/components/staking/TotalStakeCard.tsx @@ -6,11 +6,13 @@ import { fetchBalances } from "../../app/api"; import { useNymClient } from "../../hooks/useNymClient"; import { formatBigNum } from "../../utils/formatBigNumbers"; import ExplorerCard from "../cards/ExplorerCard"; +import { useEnvironment } from "@/providers/EnvironmentProvider"; const TotalStakeCard = () => { const { address } = useNymClient(); const theme = useTheme(); const isDarkMode = theme.palette.mode === "dark"; + const { environment } = useEnvironment(); // Use React Query to fetch total stake const { @@ -19,7 +21,7 @@ const TotalStakeCard = () => { isError, } = useQuery({ queryKey: ["totalStake", address], - queryFn: () => fetchBalances(address || ""), + queryFn: () => fetchBalances(address || "", environment), enabled: !!address, // Only fetch if address exists staleTime: 10 * 60 * 1000, // 10 minutes refetchOnWindowFocus: false, // Prevents unnecessary refetching diff --git a/explorer-v2/src/components/wallet/ConnectWallet.tsx b/explorer-v2/src/components/wallet/ConnectWallet.tsx index 387927706c..c6c215a19c 100644 --- a/explorer-v2/src/components/wallet/ConnectWallet.tsx +++ b/explorer-v2/src/components/wallet/ConnectWallet.tsx @@ -14,15 +14,16 @@ import Cross from "../icons/Cross"; import CrossDark from "../icons/CrossDark"; import { WalletAddress } from "./WalletAddress"; import { WalletBalance } from "./WalletBalance"; - +import { useEnvironment } from "@/providers/EnvironmentProvider"; interface ButtonPropsWithOnClick extends ButtonProps { hideAddressAndBalance?: boolean; onClick?: () => void; } const ConnectWallet = ({ ...buttonProps }: ButtonPropsWithOnClick) => { - const { connect, disconnect, address, isWalletConnected } = - useChain(COSMOS_KIT_USE_CHAIN); + const { environment } = useEnvironment(); + const chain = environment === "mainnet" ? COSMOS_KIT_USE_CHAIN : "sandbox"; + const { connect, disconnect, address, isWalletConnected } = useChain(chain); const theme = useTheme(); const handleConnectWallet = async () => { diff --git a/explorer-v2/src/components/wallet/WalletBalance.tsx b/explorer-v2/src/components/wallet/WalletBalance.tsx index ac9841051b..417b1a2a19 100644 --- a/explorer-v2/src/components/wallet/WalletBalance.tsx +++ b/explorer-v2/src/components/wallet/WalletBalance.tsx @@ -6,9 +6,11 @@ import React from "react"; import { Token } from "../../components/icons/Token"; import { TokenDark } from "../../components/icons/TokenDark"; import useGetWalletBalance from "../../hooks/useGetWalletBalance"; - +import { useEnvironment } from "@/providers/EnvironmentProvider"; export const WalletBalance = () => { - const { isWalletConnected } = useChain(COSMOS_KIT_USE_CHAIN); + const { environment } = useEnvironment(); + const chain = environment === "mainnet" ? COSMOS_KIT_USE_CHAIN : "sandbox"; + const { isWalletConnected } = useChain(chain); const { formattedBalance, isLoading, isError, refetch } = useGetWalletBalance(); const theme = useTheme(); diff --git a/explorer-v2/src/config/index.ts b/explorer-v2/src/config/index.ts index 6ee864de33..b9024b356b 100644 --- a/explorer-v2/src/config/index.ts +++ b/explorer-v2/src/config/index.ts @@ -1,6 +1,10 @@ export const COSMOS_KIT_USE_CHAIN = - process.env.NEXT_PUBLIC_COSMOS_KIT_USE_CHAIN || "nyx"; + process.env.NEXT_PUBLIC_COSMOS_KIT_USE_CHAIN || "sandbox"; export const NYM_MIXNET_CONTRACT = process.env.NYM_MIXNET_CONTRACT || "n17srjznxl9dvzdkpwpw24gg668wc73val88a6m5ajg6ankwvz9wtst0cznr"; + +export const SANDBOX_MIXNET_CONTRACT_ADDRESS = + "n1xr3rq8yvd7qplsw5yx90ftsr2zdhg4e9z60h5duusgxpv72hud3sjkxkav"; + diff --git a/explorer-v2/src/hooks/useGetWalletBalance.tsx b/explorer-v2/src/hooks/useGetWalletBalance.tsx index 195937be0f..99aeb60582 100644 --- a/explorer-v2/src/hooks/useGetWalletBalance.tsx +++ b/explorer-v2/src/hooks/useGetWalletBalance.tsx @@ -2,6 +2,7 @@ import { useChain } from "@cosmos-kit/react"; import { useQuery } from "@tanstack/react-query"; import { COSMOS_KIT_USE_CHAIN } from "../config"; import { unymToNym } from "../utils/currency"; +import { useEnvironment } from "@/providers/EnvironmentProvider"; // eslint-disable-next-line @typescript-eslint/no-explicit-any const fetchNYMBalance = async (address: string, getCosmWasmClient: any) => { @@ -17,7 +18,10 @@ const fetchNYMBalance = async (address: string, getCosmWasmClient: any) => { }; const useGetWalletBalance = () => { - const { getCosmWasmClient, address } = useChain(COSMOS_KIT_USE_CHAIN); + const { environment } = useEnvironment(); + const chain = environment === "mainnet" ? COSMOS_KIT_USE_CHAIN : "sandbox"; + + const { getCosmWasmClient, address } = useChain(chain); const { data = { NYMBalance: "0", formattedBalance: "-" }, diff --git a/explorer-v2/src/hooks/useNymClient.ts b/explorer-v2/src/hooks/useNymClient.ts index 5224190e3f..ed39fdd433 100644 --- a/explorer-v2/src/hooks/useNymClient.ts +++ b/explorer-v2/src/hooks/useNymClient.ts @@ -7,14 +7,25 @@ import type { MixnetQueryClient, } from "@nymproject/contract-clients/Mixnet.client"; import { useEffect, useState } from "react"; -import { COSMOS_KIT_USE_CHAIN, NYM_MIXNET_CONTRACT } from "../config"; +import { + COSMOS_KIT_USE_CHAIN, + NYM_MIXNET_CONTRACT, + SANDBOX_MIXNET_CONTRACT_ADDRESS, +} from "../config"; +import { useEnvironment } from "@/providers/EnvironmentProvider"; export const useNymClient = () => { const [nymClient, setNymClient] = useState(); const [nymQueryClient, setNymQueryClient] = useState(); + const { environment } = useEnvironment(); + const chain = environment === "mainnet" ? COSMOS_KIT_USE_CHAIN : "sandbox"; + const mixnetContractAddress = + environment === "mainnet" + ? NYM_MIXNET_CONTRACT + : SANDBOX_MIXNET_CONTRACT_ADDRESS; const { address, getCosmWasmClient, getSigningCosmWasmClient } = - useChain(COSMOS_KIT_USE_CHAIN); + useChain(chain); useEffect(() => { if (address) { @@ -26,13 +37,13 @@ export const useNymClient = () => { // eslint-disable-next-line @typescript-eslint/no-explicit-any cosmWasmSigningClient as any, address, - NYM_MIXNET_CONTRACT, + mixnetContractAddress ); const queryClient = new contracts.Mixnet.MixnetQueryClient( // eslint-disable-next-line @typescript-eslint/no-explicit-any cosmWasmClient as any, - NYM_MIXNET_CONTRACT, + NYM_MIXNET_CONTRACT ); setNymClient(client);