简体   繁体   English

MetaMask Web3:有什么方法可以确保网站用户连接到特定的网络?

[英]MetaMask Web3: is there any way to make sure website user is connected to a particular network?

I am developing an application that uses the MATIC token on the MATIC.network.我正在开发一个在 MATIC.network 上使用 MATIC 令牌的应用程序。 I want to make sure the user is connected to this.network with MetaMask, is this possible?我想确保用户使用 MetaMask 连接到 this.network,这可能吗?

Right now in my client.js attached to my html page, I just have the following:现在,在我的 html 页面所附的client.js中,我只有以下内容:

let accounts, web3, contract;

if (typeof window.ethereum !== 'undefined') {
  console.log('MetaMask is installed!');
} else {
    alert("Hello! Consider adding an ethereum wallet such as MetaMask to fully use this website.");
}
accounts = ethereum.request({ method: 'eth_requestAccounts' });
web3 = new Web3();

The issue is that if the user tries to interact with other features of the website, they could attempt to use ETH, which could make them lose their token and just not have the feature work.问题是,如果用户试图与网站的其他功能进行交互,他们可能会尝试使用 ETH,这可能会使他们失去令牌,并且无法使用该功能。 So I want to prompt them to get onto the MATIC.network.所以我想提示他们进入 MATIC.network。

Is there any way to get them onto this.network automatically, without having them need to put it into MetaMask manually?有没有办法让他们自动进入 this.network,而不需要他们手动将其放入 MetaMask? Would help reduce friction.有助于减少摩擦。 在此处输入图像描述

This is the MATIC.network I've been using on my backend server.js for this application:这是我一直在我的后端server.js上为此应用程序使用的 MATIC.network:

const WEB3_PROVIDER = "https://polygon-rpc.com" 
// https://blog.polygon.technology/polygon-rpc-gateway-will-provide-a-free-high-performance-connection-to-the-polygon-pos-blockchain/

if (typeof web3 !== 'undefined') {
    web3 = new Web3(web3.currentProvider);
    console.log("web3 already initialized.");
} else {
    // set the provider you want from Web3.providers
    web3 = new Web3(new Web3.providers.HttpProvider(WEB3_PROVIDER));
    console.log("New web3 object initialized.");
} 

you can check user network like this using your web3 instance ( web3 document ):您可以使用您的 web3 实例( web3 文档)像这样检查用户网络:

const yourNetworkId = '137'
web3.eth.net.getId()
.then((networkId) => {
  if (networkId != yourNetworkId) {
    // MetaMask network is wrong
  }
})
.catch((err) => {
  // unable to retrieve network id
});

in order to add network programmatically ( metamask document ):为了以编程方式添加网络( 元掩码文档):

ethereum.request({
    method: 'wallet_addEthereumChain',
    params: [{ 
        chainId: web3.utils.toHex('137'),
        chainName: 'Polygon',
        nativeCurrency: {
            name: 'MATIC',
            symbol: 'MATIC',
            decimals: 18
        },
        rpcUrls: ['https://polygon-rpc.com'],
        blockExplorerUrls: ['https://www.polygonscan.com']
    }],
})
.then(() => console.log('network added'))
.catch(() => console.log('could not add network'))

and if you want to set Metamask network programmatically ( Metamask document ):如果您想以编程方式设置 Metamask 网络( Metamask 文档):

ethereum.request({
    method: 'wallet_switchEthereumChain',
    params: [{ chainId: web3.utils.toHex('137') }],
})
.then(() => console.log('network has been set'))
.catch((e) => {
    if (e.code === 4902) {
       console.log('network is not available, add it')
    } else {
       console.log('could not set network')
    }
})

also you can listen chainChanged event on Metamask to detect when user changes Metamask network ( metamask document ):您还可以在 Metamask 上侦听chainChanged事件以检测用户何时更改 Metamask 网络( 元掩码文档):

ethereum.on("chainChanged", () => {
    // if network was wrong, you can open a modal to disable activity and ask
    // user to change network back to Polygon or even change it yourself on 
    // user clicking a button, but i don't suggest setting network by yourself
    // without users permission because users may using other dApps on other
    // networks at the same time which changing network immediately on chainChanged
    // would be a bad UX
})

write a mapping for metamask.networks.为 metamask.networks 写一个映射。 You can find all the chains here: https://chainlist.org/你可以在这里找到所有链: https://chainlist.org/

const NETWORKS = {
  1: "Ethereum Main Network",
  3: "Ropsten Test Network",
  5: "Goerli Test Network",
  42: "Kovan Test Network",
  56: "Binance Smart Chain",
  137: "Polygon Mainnet",
  1337: "Ganache",
};

set your target.networK设置你的 target.network

// matic chain 137
const targetNetwork = NETWORKS[process.env.TARGET_CHAIN_ID];


const getNetwork= async () => {
      const chainId = await web3.eth.getChainId();
      // handle the error here
      if (!chainId) {
        throw new Error(
          "Cannot retrieve an account. Please refresh the browser"
        );
      }
      return NETWORKS[chainId];
    }
  );

write the logic写逻辑

const connectedNetwork=getNetwork()
const supported=targetNetwork===connectedNetwork

if supported=true you are connected to the right.network如果supported=true你连接到 right.network

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM