Skip to content

Commit 25821c0

Browse files
author
jagdeep sidhu
committed
feat: update contract addresses and fix SSR hydration issues
- Update relay and ERC20 manager contract addresses to latest versions - Add SSR-safe checks to prevent hydration mismatches in providers - Fix chain ID bug (0x69 -> 0x39) in Pali v2 provider - Add loading states for wallet components during SSR - Replace hardcoded URLs with environment variables - Improve wallet connection reliability and UI consistency
1 parent 8de7f62 commit 25821c0

File tree

9 files changed

+164
-26
lines changed

9 files changed

+164
-26
lines changed

components/Bridge/hooks/useErc20ManagerContract.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export const useErc20ManagerContract = () => {
1414
SyscoinERC20ManagerABI,
1515
flags.isEnabled("isSys5Enabled")
1616
? constants?.contracts.ecr20ManagerContract.address
17-
: "0xA738a563F9ecb55e0b2245D1e9E380f0fE455ea1"
17+
: "0x7904299b3D3dC1b03d1DdEb45E9fDF3576aCBd5f"
1818
),
1919
[web3, flags, constants?.contracts.ecr20ManagerContract.address]
2020
);

components/WalletList/MetaMask.tsx

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,41 @@ import { Button, Box, Typography, Link } from "@mui/material";
22
import Image from "next/image";
33
import { useConnectedWallet } from "../../contexts/ConnectedWallet/useConnectedWallet";
44
import { Launch } from "@mui/icons-material";
5+
import { useMetamask } from "@contexts/Metamask/Provider";
6+
import { useState, useEffect } from "react";
57

68
const WalletListMetamask = () => {
79
const { nevm, connectNEVM, availableWallets } = useConnectedWallet();
10+
const { isEnabled } = useMetamask();
11+
const [mounted, setMounted] = useState(false);
12+
13+
useEffect(() => {
14+
setMounted(true);
15+
}, []);
16+
17+
if (!mounted) {
18+
// Show consistent loading state during SSR
19+
return (
20+
<Box sx={{ display: "flex", alignItems: "center", mb: 2 }}>
21+
<Image
22+
src="/metamask-logo.svg"
23+
height={32}
24+
width={32}
25+
alt="Metamask logo"
26+
/>
27+
<Typography variant="body1">MetaMask</Typography>
28+
<Button sx={{ ml: "auto" }} variant="contained" disabled>
29+
Loading...
30+
</Button>
31+
</Box>
32+
);
33+
}
34+
35+
// Skip rendering if this isn't the MetaMask connection type
836
if (nevm.type !== "metamask") {
937
return null;
1038
}
39+
1140
return (
1241
<Box sx={{ display: "flex", alignItems: "center", mb: 2 }}>
1342
<Image
@@ -19,7 +48,7 @@ const WalletListMetamask = () => {
1948

2049
{nevm.type === "metamask" && nevm.account ? (
2150
<>
22-
<Typography variant="body1" color="secondary">
51+
<Typography variant="body1" color="secondary" noWrap maxWidth={"70%"}>
2352
{nevm.account}
2453
</Typography>
2554
<Typography variant="body1" color="success.main" sx={{ ml: "auto" }}>
@@ -28,8 +57,8 @@ const WalletListMetamask = () => {
2857
</>
2958
) : (
3059
<>
31-
<Typography variant="body1">Metamask</Typography>
32-
{availableWallets.metamask ? (
60+
<Typography variant="body1">MetaMask</Typography>
61+
{availableWallets.metamask && isEnabled ? (
3362
<Button
3463
sx={{ ml: "auto" }}
3564
variant="contained"
@@ -40,7 +69,7 @@ const WalletListMetamask = () => {
4069
) : (
4170
<Link
4271
href="https://metamask.io/"
43-
title="Go to Metamask"
72+
title="Go to MetaMask"
4473
sx={{ ml: "auto" }}
4574
target="_blank"
4675
>

components/WalletList/PaliWallet.tsx

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,34 @@ import {
77
usePaliWalletV2,
88
} from "@contexts/PaliWallet/usePaliWallet";
99
import Web3 from "web3";
10+
import { useState, useEffect } from "react";
1011

1112
const InstallPaliWallet = () => {
1213
const { connectWallet, isInstalled } = usePaliWallet();
14+
const [mounted, setMounted] = useState(false);
15+
16+
useEffect(() => {
17+
setMounted(true);
18+
}, []);
19+
20+
if (!mounted) {
21+
// Show loading state during SSR
22+
return (
23+
<Box sx={{ display: "flex", alignItems: "center", mb: 2 }}>
24+
<Image
25+
src="/pali-wallet-logo.svg"
26+
height={32}
27+
width={32}
28+
alt="PaliWallet logo"
29+
/>
30+
<Typography variant="body1">Pali Wallet</Typography>
31+
<Button sx={{ ml: "auto" }} variant="contained" disabled>
32+
Loading...
33+
</Button>
34+
</Box>
35+
);
36+
}
37+
1338
return (
1439
<Box sx={{ display: "flex", alignItems: "center", mb: 2 }}>
1540
<Image
@@ -43,9 +68,32 @@ const PaliWalletV2 = () => {
4368
const { utxo, nevm } = useConnectedWallet();
4469
const { isBitcoinBased, switchTo, isInstalled, isEVMInjected } =
4570
usePaliWalletV2();
71+
const [mounted, setMounted] = useState(false);
72+
73+
useEffect(() => {
74+
setMounted(true);
75+
}, []);
76+
4677
const connectedAccount = isBitcoinBased ? utxo.account : nevm.account;
4778
const isConnected = Boolean(connectedAccount);
4879

80+
if (!mounted) {
81+
// Show loading state during SSR
82+
return (
83+
<Box sx={{ mb: 2 }}>
84+
<Box sx={{ display: "flex", alignItems: "center" }}>
85+
<Image
86+
src="/pali-wallet-logo.svg"
87+
height={32}
88+
width={32}
89+
alt="PaliWallet logo"
90+
/>
91+
<Typography variant="body1">Loading...</Typography>
92+
</Box>
93+
</Box>
94+
);
95+
}
96+
4997
if (utxo.type !== "pali-wallet" || !isInstalled || !isConnected) {
5098
return <InstallPaliWallet />;
5199
}
@@ -106,6 +154,29 @@ const PaliWalletV2 = () => {
106154
const WalletListPaliWallet = () => {
107155
const { utxo } = useConnectedWallet();
108156
const { version, isInstalled } = usePaliWallet();
157+
const [mounted, setMounted] = useState(false);
158+
159+
useEffect(() => {
160+
setMounted(true);
161+
}, []);
162+
163+
if (!mounted) {
164+
// Show consistent loading state during SSR
165+
return (
166+
<Box sx={{ display: "flex", alignItems: "center", mb: 2 }}>
167+
<Image
168+
src="/pali-wallet-logo.svg"
169+
height={32}
170+
width={32}
171+
alt="PaliWallet logo"
172+
/>
173+
<Typography variant="body1">Pali Wallet</Typography>
174+
<Button sx={{ ml: "auto" }} variant="contained" disabled>
175+
Loading...
176+
</Button>
177+
</Box>
178+
);
179+
}
109180

110181
if (version === "v2") {
111182
return <PaliWalletV2 />;

constants.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ export const DEFAULT_GAS_LIMIT = 120_000;
44
export const RELAY_CONTRACT_ADDRESS =
55
process.env.SYS5_ENABLED === "true"
66
? process.env.RELAY_CONTRACT_ADDRESS
7-
: "0xD822557aC2F2b77A1988617308e4A29A89Cb95A6";
7+
: "0xd714E7915362FF89388025F584726E6dF26D20f9";
88

99
export const ERC20_MANAGER_CONTRACT_ADDRESS =
1010
process.env.SYS5_ENABLED === "true"
1111
? process.env.ERC20_MANAGER_CONTRACT_ADDRESS
12-
: "0xA738a563F9ecb55e0b2245D1e9E380f0fE455ea1";
12+
: "0x7904299b3D3dC1b03d1DdEb45E9fDF3576aCBd5f";
1313

1414
export const ADMIN_LOGIN_MESSAGE = "Login to Syscoin Bridge Admin";

contexts/ConnectedWallet/Provider.tsx

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,18 @@ const ConnectedWalletProvider: React.FC<{ children: ReactNode }> = ({
6060
const metamask = useMetamask();
6161
const [utxoWalletType, setUtxoWalletType] =
6262
useState<UTXOWallet>("pali-wallet");
63-
const [nevmWalletType, setNevmWalletType] = useState<NEVMWallet>(
64-
paliWallet.version === "v2" && paliWalletV2.isEVMInjected
65-
? "pali-wallet"
66-
: "metamask"
67-
);
63+
const [nevmWalletType, setNevmWalletType] = useState<NEVMWallet>(() => {
64+
// Check if Pali v2 with EVM injection is available
65+
if (paliWallet.version === "v2" && paliWalletV2.isEVMInjected) {
66+
return "pali-wallet";
67+
}
68+
// Check if window.ethereum is Pali v2
69+
if (typeof window !== "undefined" && window.ethereum?.wallet === "pali-v2") {
70+
return "pali-wallet";
71+
}
72+
// Default to MetaMask
73+
return "metamask";
74+
});
6875
const nevm = useNEVM();
6976

7077
const utxoAccount = paliWallet.connectedAccount;
@@ -80,6 +87,14 @@ const ConnectedWalletProvider: React.FC<{ children: ReactNode }> = ({
8087
const connectNEVM = (type: NEVMWallet) => {
8188
if (type === "metamask") {
8289
nevm.connect();
90+
} else if (type === "pali-wallet") {
91+
// Handle Pali wallet EVM connection
92+
if (window.ethereum && window.ethereum.wallet === "pali-v2") {
93+
window.ethereum.request({ method: 'eth_requestAccounts' })
94+
.catch((error) => {
95+
console.error('Failed to connect Pali EVM provider:', error);
96+
});
97+
}
8398
}
8499
setNevmWalletType(
85100
window.ethereum.wallet === "pali-v2" ? "pali-wallet" : "metamask"
@@ -189,10 +204,21 @@ const ConnectedWalletProvider: React.FC<{ children: ReactNode }> = ({
189204
if (!window.ethereum) {
190205
return;
191206
}
192-
setNevmWalletType(
193-
window.ethereum.wallet === "pali-v2" ? "pali-wallet" : "metamask"
194-
);
195-
}, [paliWalletV2.isEVMInjected, setNevmWalletType]);
207+
208+
// Determine the correct NEVM wallet type based on current state
209+
let correctWalletType: NEVMWallet = "metamask";
210+
211+
if (window.ethereum.wallet === "pali-v2") {
212+
correctWalletType = "pali-wallet";
213+
} else if (paliWallet.version === "v2" && paliWalletV2.isEVMInjected) {
214+
correctWalletType = "pali-wallet";
215+
}
216+
217+
// Only update if the wallet type has actually changed
218+
if (nevmWalletType !== correctWalletType) {
219+
setNevmWalletType(correctWalletType);
220+
}
221+
}, [paliWalletV2.isEVMInjected, paliWallet.version, nevmWalletType]);
196222

197223
return (
198224
<ConnectedWalletContext.Provider

contexts/Metamask/Provider.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,12 @@ const MetamaskProvider: React.FC<{ children: React.ReactNode }> = ({
3232
}) => {
3333
const { data: isEnabled } = useQuery(["metamask", "enabled"], {
3434
queryFn: () => {
35+
if (typeof window === "undefined") return false;
3536
return (
3637
typeof window.ethereum !== "undefined" && window.ethereum.isMetaMask
3738
);
3839
},
40+
enabled: typeof window !== "undefined",
3941
});
4042

4143
return (

contexts/PaliWallet/V2Provider.tsx

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -81,36 +81,46 @@ export const PaliWalletV2Provider: React.FC<{
8181
const { constants } = useConstants();
8282
const installed = useQuery(["pali", "is-installed"], {
8383
queryFn: () => {
84+
if (typeof window === "undefined") return false;
8485
return Boolean(window.pali) && window.pali.wallet === "pali-v2";
8586
},
8687
refetchInterval: 1000,
88+
enabled: typeof window !== "undefined",
8789
});
8890

8991
const isEVMInjected = useQuery(["pali", "is-ethereum-injected"], {
9092
queryFn: () => {
93+
if (typeof window === "undefined") return false;
9194
return Boolean(window.ethereum) && window.ethereum.wallet === "pali-v2";
9295
},
9396
refetchInterval: 1000,
97+
enabled: typeof window !== "undefined",
9498
});
9599

96100
const isInstalled = installed.isFetched && installed.data;
97101

98102
const isBitcoinBased = useQuery(["pali", "isBitcoinBased"], {
99103
queryFn: () => {
104+
if (typeof window === "undefined" || !window.pali) return false;
100105
const bitcoinBased = window.pali.isBitcoinBased();
101106
return Boolean(bitcoinBased);
102107
},
103-
enabled: isInstalled,
108+
enabled: isInstalled && typeof window !== "undefined",
104109
refetchInterval: 1000,
105110
});
106111

107-
const providerState = useQuery<ProviderState>(["pali", "provider-state"], {
108-
queryFn: () => {
109-
return window.pali.request({
110-
method: "wallet_getProviderState",
111-
});
112+
const providerState = useQuery<ProviderState | null>(["pali", "provider-state"], {
113+
queryFn: async (): Promise<ProviderState | null> => {
114+
if (typeof window === "undefined" || !window.pali) return null;
115+
try {
116+
return await window.pali.request({
117+
method: "wallet_getProviderState",
118+
});
119+
} catch (error) {
120+
return null;
121+
}
112122
},
113-
enabled: isInstalled,
123+
enabled: isInstalled && typeof window !== "undefined",
114124
});
115125

116126
const requestAccounts = () => {
@@ -225,7 +235,7 @@ export const PaliWalletV2Provider: React.FC<{
225235
return Promise.reject("Pali Wallet is not installed");
226236
}
227237

228-
const chainId = parseInt(constants?.chain_id ?? "0x69", 16);
238+
const chainId = parseInt(constants?.chain_id ?? "0x39", 16);
229239

230240
if (networkType === "bitcoin") {
231241
return window.pali

contexts/Transfer/constants.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@ export const NEVMNetwork = {
99
decimals: 18,
1010
},
1111
rpcUrls: [process.env.NEVM_RPC_URL!],
12-
blockExplorerUrls: ["https://explorer.syscoin.org/"],
12+
blockExplorerUrls: [process.env.NEXT_PUBLIC_NEVM_EXPLORER || "https://explorer.syscoin.org/"],
1313
};

contexts/Transfer/functions/nevmToSys.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ const mintSysx = async (
114114
const txOpts = { rbf: true };
115115
// web3 URL + ID and nevm burn txid
116116
const assetOpts = {
117-
web3url: "https://rpc.syscoin.org",
117+
web3url: process.env.NEXT_PUBLIC_NEVM_RPC_URL || "https://rpc.syscoin.org",
118118
ethtxid: receipt.transactionHash,
119119
};
120120
// will be auto filled based on ethtxid eth-proof

0 commit comments

Comments
 (0)