1+ const provider = window . ethereum ;
2+ const supportedNetworks = {
3+ westendAssetHub : {
4+ name : 'Asset-Hub Westend Testnet' ,
5+ chainId : '0x190F1B45' , //Hex value of "420420421"
6+ chainName : 'Asset-Hub Westend Testnet' ,
7+ rpcUrls : [ 'https://westend-asset-hub-eth-rpc.polkadot.io' ] ,
8+ blockExplorerUrls : [ 'https://westend-asset-hub-eth-explorer.parity.io' ] ,
9+ nativeCurrency : {
10+ name : 'Westend Token' ,
11+ symbol : 'WND' ,
12+ decimals : 18 ,
13+ } ,
14+ } ,
15+ } ;
16+
17+ /*
18+ Add or switch to the specified network, then request accounts
19+ NOTE: This calls "eth_requestAccounts" at the end, which prompts for wallet connection
20+ */
21+ const connectNetwork = async ( network ) => {
22+ try {
23+ const targetNetwork = { ...supportedNetworks [ network ] } ;
24+ delete targetNetwork . name ; // remove 'name' property if needed
25+
26+ await provider . request ( {
27+ method : 'wallet_addEthereumChain' ,
28+ params : [ targetNetwork ] ,
29+ } ) ;
30+ // This line requests user accounts, which triggers a "connect" prompt if not already connected:
31+ await provider . request ( { method : 'eth_requestAccounts' } ) ;
32+ } catch ( e ) {
33+ // 4001: user rejected, -32002: request already pending
34+ if ( e . code !== 4001 && e . code !== - 32002 ) {
35+ handleError ( e . message ) ;
36+ }
37+ }
38+ } ;
39+
40+ // Get the network that the user is currently connected to
41+ const getConnectedNetwork = async ( ) => {
42+ const chainId = await provider . request ( { method : 'eth_chainId' } ) ;
43+ const connectedHubNetwork = Object . values ( supportedNetworks ) . find (
44+ ( network ) => network . chainId === chainId
45+ ) ;
46+ if ( connectedNetwork ) {
47+ const connectedNetworkButton = document . querySelector (
48+ `.connect-network[data-value="${ connectedNetwork . name } "]`
49+ ) ;
50+ return { connectedNetwork, connectedNetworkButton } ;
51+ } else {
52+ return {
53+ connectedNetwork : null ,
54+ connectedNetworkButton : null ,
55+ } ;
56+ }
57+ } ;
58+
59+ /* Updates the button to show the connected network. */
60+ const displayConnectedAccount = async ( connectedNetwork , networkButton ) => {
61+ const accounts = await provider . request ( { method : 'eth_requestAccounts' } ) ;
62+ if ( ! accounts || accounts . length === 0 ) return ;
63+
64+ const shortenedAccount = `${ accounts [ 0 ] . slice ( 0 , 6 ) } ...${ accounts [ 0 ] . slice (
65+ - 4
66+ ) } `;
67+ networkButton . innerHTML = `Connected to ${ connectedNetwork . chainName } : ${ shortenedAccount } ` ;
68+ networkButton . className += ' disabled-button' ;
69+ } ;
70+
71+ // Displays an error message to the user
72+ const handleError = ( message ) => {
73+ const errorModalContainer = document . querySelector ( '.error-modal-container' ) ;
74+ const errorMessage = document . querySelector ( '.error-message' ) ;
75+ errorModalContainer . style . display = 'block' ;
76+ errorMessage . innerHTML = message ;
77+ } ;
78+
79+ /*
80+ Handles the logic for the buttons inside of content pages.
81+ Directly connect to the network specified in 'value'
82+ */
83+ const connectMetaMaskBodyButtons =
84+ document . querySelectorAll ( '.connectMetaMask' ) ;
85+ connectMetaMaskBodyButtons . forEach ( ( btn ) => {
86+ btn . addEventListener ( 'click' , async ( e ) => {
87+ e . preventDefault ( ) ;
88+
89+ if ( ! provider ) {
90+ handleError (
91+ `No EVM-compatible wallet found. Please install MetaMask.`
92+ ) ;
93+ return ;
94+ }
95+
96+ const network = btn . getAttribute ( 'value' ) ;
97+ if ( ! network || ! supportedNetworks [ network ] ) {
98+ handleError ( `The network "${ network } " is not supported or not defined.` ) ;
99+ return ;
100+ }
101+
102+ await connectNetwork ( network ) ;
103+ //Update the button to reflect the "connected" state
104+ btn . textContent = 'Connected to ' + supportedNetworks [ network ] [ 'name' ] ;
105+ btn . classList . add ( 'disabled-button' ) ;
106+ } ) ;
107+ } ) ;
108+
109+ if ( provider ) {
110+ provider . on ( 'chainChanged' , ( ) => {
111+ window . location . reload ( ) ;
112+ } ) ;
113+ provider . on ( 'accountsChanged' , async ( accounts ) => {
114+ if ( accounts . length > 0 ) {
115+ const { connectedNetwork, connectedNetworkButton } =
116+ await getConnectedNetwork ( ) ;
117+ if ( connectedNetwork ) {
118+ await displayConnectedAccount (
119+ connectedNetwork ,
120+ connectedNetworkButton
121+ ) ;
122+ }
123+ } else {
124+ window . location . reload ( ) ;
125+ }
126+ } ) ;
127+ }
0 commit comments