js连接web3,连接小狐狸metamask钱包,实现链不对后切换网络和创建网络

前言:在今天之前,用metamask检测链不对,并且自动切换网络和创建网络的功能,从来没有真正自己实践一次。

 

核心代码:

 

import { useWeb3React } from "@web3-react/core";
// 从这句看出用的库web3-react,既不是web3js,也不是etherjs


export default function WalletModal({ isOpen, onClose }: UseModalProps) { const { activate } = useWeb3React(); function getOptions() { const option = SUPPORTED_WALLETS["METAMASK"]; return ( <VStack> <Button variant="outline" onClick={async () => { activate(option.connector); onClose(); if (window.ethereum) { try { await (window.ethereum as any).request({ method: 'wallet_switchEthereumChain', params: [{ chainId: "0x41" // 目标链ID }] }) console.log('wallet_switchEthereumChain'); } catch (e) { console.log('(e as any).code', (e as any).code); if ((e as any).code === 4902) { try { console.log('wallet_addEthereumChain'); await (window.ethereum as any).request({ method: 'wallet_addEthereumChain', params: [ { chainId: "0x41", // 目标链ID chainName: 'OKC Testnet', nativeCurrency: { name: 'OKT', symbol: 'OKT', decimals: 18 }, rpcUrls: ['https://exchaintestrpc.okex.org'], // 节点 blockExplorerUrls: ['https://www.oklink.com/zh-cn/okc-test'] } ] }) } catch (ee) { // } } else if ((e as any).code === 4001) return } } }} w="100%" > <HStack w="100%" justifyContent="center"> <Image src={option.iconURL} alt="Metamask Logo" width={25} height={25} borderRadius="3px" /> <Text>Metamask</Text> </HStack> </Button> </VStack> ); } return ( <Modal isOpen={isOpen} onClose={onClose} isCentered> <ModalOverlay /> <ModalContent w="300px"> <ModalHeader>Select Wallet</ModalHeader> <ModalCloseButton _focus={{ boxShadow: "none", }} /> <ModalBody paddingBottom="1.5rem">{getOptions()}</ModalBody> </ModalContent> </Modal> ); }

注意:

配置中的chainId,rpcUrls和blockExplorerUrls三个值,特别注意。

chainId是16进制。

rpcUrls和blockExplorerUrls必须是https。

 

此时会报错:

`Property 'ethereum' does not exist on type 'Window & typeof globalThis'` error in React

分析:window.ethereum不存在。

解决办法:

src/react-app-env.d.ts 添加如下内容

/// <reference types="react-scripts" />
import { ExternalProvider } from "@ethersproject/providers";

declare global {
  interface Window {
    ethereum?: ExternalProvider;
  }
}

 

代码的含义是:

先切换网络到指定chainId,如果chainId存在,则切换成功;如果不存在,则添加新网络。

 

另一种写法:把window.ethereum换为currentProvider。

await (window.ethereum as any).request({}) 改为

currentProvider.send({})

如下所示:

currentProvider.send({
    "method": "wallet_addEthereumChain",
    "params": [
        {
            "chainId": "0x42",
            "chainName": "OKC Main",
            "rpcUrls": ["https://exchainrpc.okex.org/"],
            "nativeCurrency": {
                "name": "OKT",
                "symbol": "OKT",
                "decimals": 18
            },
            "blockExplorerUrls": ["https://www.oklink.com/okc"]
        }
    ]
})

 

 

参考:

https://blog.csdn.net/github_38633141/article/details/124023708

https://codeleading.com/article/10766257519/

https://stackoverflow.com/questions/70961190/property-ethereum-does-not-exist-on-type-window-typeof-globalthis-error

https://okc-docs.readthedocs.io/en/latest/developers/blockchainDetail/rpc.html

 

posted @ 2022-11-11 22:37  走走停停走走  Views(1396)  Comments(0Edit  收藏  举报