当前位置:   article > 正文

如何配置web3.js和连接MetaMask_web3.js metamask

web3.js metamask

1、创建utils文件夹在这个文件夹下创建web3.ts文件:

  1. import { ethers } from 'ethers'
  2. import { ExternalProvider, JsonRpcFetchFunc } from '@ethersproject/providers';
  3. import { InjectedConnector } from '@web3-react/injected-connector'
  4. // 提供一个provider转成web3provider
  5. export const getLibray = (provider: ExternalProvider | JsonRpcFetchFunc) => {
  6. const web3Provider = new ethers.providers.Web3Provider(provider)
  7. return web3Provider
  8. }
  9. export const InjectConnector = new InjectedConnector({ supportedChainIds: [56] })

2、创建chain文件夹,在这个文件夹下创建一个index.ts文件:

  1. // 支持的链
  2. export const SuportChain = {
  3. eth: {
  4. chanId: 1,
  5. name: 'eth'
  6. },
  7. bsc: {
  8. chainId: 56,
  9. name: 'bsc'
  10. },
  11. polygon: {
  12. chainId: 56,
  13. name: 'polygon'
  14. }
  15. }
  16. // 链id 网络id
  17. export enum NetworkID {
  18. // 主网
  19. Mainnet = 56,
  20. // 测试网
  21. Testnet = 97
  22. }
  23. export enum SUPPORT_CHAIN {
  24. BSC = 56,
  25. BSCTEST = 97
  26. }
  27. // 当前链ID
  28. export const CURRENT_CHAIN = 56
  29. // MetaMask 中 request 请求中的 methods 方法
  30. export enum MetaMaskRequestMethods {
  31. // 添加在metamask中不存在的链
  32. addEthereumChain = "wallet_addEthereumChain",
  33. // 吧Token代币添加到钱包中
  34. watchAsset = 'wallet_watchAsset',
  35. // 获取当前链接的网络Id
  36. chainId = 'eth_chainId',
  37. // eth_requestAccunts 获取账号(可以理解为链接钱包)
  38. requestAccount = 'eth_requestAccounts',
  39. // 获取账户地址
  40. accounts = 'eth_accounts',
  41. // 获取最新区块编号
  42. blockNumber = 'eth_blockNumber'
  43. }
  44. // 添加一条链到metamask上时请求网络参数
  45. export const AddEthereumChainParams: { [key: number]: any } = {
  46. 8: {
  47. chainId: '0x8',
  48. chainName: 'Ubiq',
  49. chativeCurrency: {
  50. name: 'Ubiq Ether',
  51. symbol: 'BUQ',
  52. decimals: 18,
  53. },
  54. rpcUrl: ['https://rpc.octano.dev/'],
  55. blockExplorerUrls: ['https://ubiqscan.io/']
  56. },
  57. 56: {
  58. chainId: '0x38',
  59. chainName: 'Binance Smart Chain Mainnet',
  60. nativeCurrency: {
  61. name: 'BNB',
  62. symbol: 'bnb',
  63. decimals: 18
  64. },
  65. rpcUrls: ['https://bsc-dataseed1.ninicoin.io', 'https://bsc-dataseed1.defibit.io', 'https://bsc-dataseed.binance.org'],
  66. blockExplorerUrls: ['https://bscscan.com/'],
  67. }
  68. }

3、在react-app-env.d.ts内添加:

  1. /// <reference types="react-scripts" />
  2. interface Window {
  3. ethereum?:{
  4. isMetaMask?:true
  5. request?:(...args:any[])=>Promise<void>
  6. }
  7. BinanceChain?:{
  8. bnbSign?:(address:string,message:string) => Promise<{publicKey:string;signature:string}>
  9. }
  10. web3:any
  11. }

4、创建types文件夹,在这个文件夹中创建ethereum.tsx文件:

  1. type EthereumProviderEip1193 = {
  2. request: (args: {
  3. method: string
  4. params?: unknown[] | object
  5. }) => Promise<unknown>
  6. }
  7. type EthereumProviderSend = {
  8. send: (method: string, params: string[]) => Promise<unknown>
  9. }
  10. type EthereumProviderSendAsync = {
  11. sendAsync: (
  12. params: {
  13. method: string
  14. params: string[]
  15. from: string
  16. jsonrpc: '2.0'
  17. id: number
  18. },
  19. callback: (err: Error, result: unknown) => void
  20. ) => void
  21. selectedAddress: string
  22. }
  23. /**
  24. * window.ethereum 类型
  25. * Eip-1193 规范
  26. */
  27. export type EthereumProvider = EthereumProviderEip1193 &
  28. EthereumProviderSend &
  29. EthereumProviderSendAsync

5、再到utils文件夹中创建ethereum.ts文件:

  1. import { AddEthereumChainParams, MetaMaskRequestMethods } from "chain";
  2. import { EthereumProvider } from "types/ethereum";
  3. function isUnwrappedRpcResult(response: unknown): response is {
  4. error?: string
  5. result?: unknown
  6. } {
  7. return (
  8. typeof response === 'object' && response !== null && 'jsonrpc' in response
  9. )
  10. }
  11. /**
  12. * 防止有的客户端没有包裹response
  13. */
  14. export function rpcResult(response: unknown): unknown | null {
  15. // Some providers don’t wrap the response
  16. if (isUnwrappedRpcResult(response)) {
  17. if (response.error) {
  18. throw new Error(response.error)
  19. }
  20. return response.result || null
  21. }
  22. return response || null
  23. }
  24. /**
  25. * metamask request 方法封装
  26. * @param ethereum provider, 浏览器中使用window.ethereum
  27. * @param method 请求方法
  28. * @param params 参数
  29. * @returns
  30. */
  31. export async function ethereumRequest(
  32. ethereum: EthereumProvider,
  33. method: string,
  34. params: string[]
  35. ): Promise<any> {
  36. // If ethereum.request() exists, the provider is probably EIP-1193 compliant.
  37. if (ethereum.request) {
  38. return ethereum.request({ method, params }).then(rpcResult)
  39. }
  40. // This is specific to some older versions of MetaMask combined with Web3.js.
  41. if (ethereum.sendAsync && ethereum.selectedAddress) {
  42. return new Promise((resolve, reject) => {
  43. ethereum.sendAsync(
  44. {
  45. method,
  46. params,
  47. from: ethereum.selectedAddress,
  48. jsonrpc: '2.0',
  49. id: 0,
  50. },
  51. (err: Error, result: any) => {
  52. if (err) {
  53. reject(err)
  54. } else {
  55. resolve(result)
  56. }
  57. }
  58. )
  59. }).then(rpcResult)
  60. }
  61. // If none of the previous two exist, we assume the provider is pre EIP-1193,
  62. // using .send() rather than .request().
  63. if (ethereum.send) {
  64. return ethereum.send(method, params).then(rpcResult)
  65. }
  66. throw new Error(
  67. 'The Ethereum provider doesn’t seem to provide a request method.'
  68. )
  69. }
  70. /**
  71. * 获取区块编码
  72. * @param ethereum provider, 默认使用window.ethereum
  73. * @returns
  74. */
  75. export async function getBlockNumber(ethereum?: EthereumProvider) {
  76. ethereum = ethereum ?? window.ethereum as any
  77. return ethereumRequest(ethereum!, MetaMaskRequestMethods.blockNumber, [])
  78. }
  79. /**
  80. * 添加链到metamask 上
  81. */
  82. export async function addChainToBlock(id: number, ethereum?: EthereumProvider) {
  83. ethereum = ethereum ?? window.ethereum as any
  84. const params = AddEthereumChainParams[id]
  85. // ! 确保ethereum 部位null
  86. return ethereumRequest(ethereum!, MetaMaskRequestMethods.addEthereumChain, [params])
  87. }

6、在创建hooks文件夹,在这个文件夹里创建useAuth.ts:

  1. import { UnsupportedChainIdError, useWeb3React } from '@web3-react/core'
  2. import { InjectConnector } from '../utils/web3'
  3. import { addChainToBlock } from 'utils/ethereum'
  4. export const useAuth = () => {
  5. const { activate } = useWeb3React()
  6. const Login = () => {
  7. if (InjectConnector) {
  8. activate(InjectConnector, async (error: Error) => {
  9. if (error instanceof UnsupportedChainIdError) {
  10. const hasSetup = await addChainToBlock(56)
  11. if (hasSetup) {
  12. activate(InjectConnector)
  13. }
  14. }
  15. })
  16. }
  17. }
  18. return Login
  19. }

然后再src目录下的index.tsx文件下这么写:

  1. import React from "react";
  2. import ReactDOM from "react-dom";
  3. import "./index.css";
  4. import App from "./App";
  5. import reportWebVitals from "./reportWebVitals";
  6. // 这下边的两个是添加的引入文件
  7. import { getLibray } from "./utils/web3";
  8. import { Web3ReactProvider } from "@web3-react/core";
  9. ReactDOM.render(
  10. <React.StrictMode>
  11. {/* 在这里用 Web3ReactProvider 包裹 app 文件 */}
  12. <Web3ReactProvider getLibrary={getLibray}>
  13. <App />
  14. </Web3ReactProvider>
  15. </React.StrictMode>,
  16. document.getElementById("root")
  17. );
  18. // If you want to start measuring performance in your app, pass a function
  19. // to log results (for example: reportWebVitals(console.log))
  20. // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
  21. reportWebVitals();

在然后再你需要获取MetaMask小狐狸地址的地方这么写:

  1. import React, { useEffect } from "react";
  2. import "./App.css";
  3. import { useWeb3React } from "@web3-react/core";
  4. import { useAuth } from "hooks/useAuth";
  5. function App() {
  6. const Login = useAuth();
  7. const { account, library, chainId } = useWeb3React();
  8. console.log("地址1", account);
  9. const GetClick = () => {
  10. Login();
  11. console.log("地址2", account);
  12. };
  13. useEffect(() => {
  14. Login();
  15. }, []);
  16. return (
  17. <div className="App">
  18. <button onClick={GetClick}>获取钱包地址</button>
  19. </div>
  20. );
  21. }
  22. export default App;

你只需要按我说的创建文件夹步骤复制代码,就可以链接到你的小狐狸了,记得要在tsconfig.json文件中添加"baseUrl": "src",

希望我能帮到你。我技术有限,有不对的地方请在评论区指教;

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/寸_铁/article/detail/861504
推荐阅读
相关标签
  

闽ICP备14008679号