簡體   English   中英

MetaMask Web3:有什么方法可以確保網站用戶連接到特定的網絡?

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

我正在開發一個在 MATIC.network 上使用 MATIC 令牌的應用程序。 我想確保用戶使用 MetaMask 連接到 this.network,這可能嗎?

現在,在我的 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();

問題是,如果用戶試圖與網站的其他功能進行交互,他們可能會嘗試使用 ETH,這可能會使他們失去令牌,並且無法使用該功能。 所以我想提示他們進入 MATIC.network。

有沒有辦法讓他們自動進入 this.network,而不需要他們手動將其放入 MetaMask? 有助於減少摩擦。 在此處輸入圖像描述

這是我一直在我的后端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.");
} 

您可以使用您的 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
});

為了以編程方式添加網絡( 元掩碼文檔):

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'))

如果您想以編程方式設置 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')
    }
})

您還可以在 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
})

為 metamask.networks 寫一個映射。 你可以在這里找到所有鏈: 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",
};

設置你的 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];
    }
  );

寫邏輯

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

如果supported=true你連接到 right.network

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM