赞
踩
1、创建utils文件夹在这个文件夹下创建web3.ts文件:
- import { ethers } from 'ethers'
- import { ExternalProvider, JsonRpcFetchFunc } from '@ethersproject/providers';
- import { InjectedConnector } from '@web3-react/injected-connector'
-
-
- // 提供一个provider转成web3provider
-
- export const getLibray = (provider: ExternalProvider | JsonRpcFetchFunc) => {
- const web3Provider = new ethers.providers.Web3Provider(provider)
- return web3Provider
- }
-
- export const InjectConnector = new InjectedConnector({ supportedChainIds: [56] })
2、创建chain文件夹,在这个文件夹下创建一个index.ts文件:
- // 支持的链
- export const SuportChain = {
- eth: {
- chanId: 1,
- name: 'eth'
- },
- bsc: {
- chainId: 56,
- name: 'bsc'
- },
- polygon: {
- chainId: 56,
- name: 'polygon'
- }
- }
-
- // 链id 网络id
- export enum NetworkID {
- // 主网
- Mainnet = 56,
- // 测试网
- Testnet = 97
- }
-
- export enum SUPPORT_CHAIN {
- BSC = 56,
- BSCTEST = 97
- }
-
- // 当前链ID
- export const CURRENT_CHAIN = 56
-
- // MetaMask 中 request 请求中的 methods 方法
- export enum MetaMaskRequestMethods {
- // 添加在metamask中不存在的链
- addEthereumChain = "wallet_addEthereumChain",
- // 吧Token代币添加到钱包中
- watchAsset = 'wallet_watchAsset',
- // 获取当前链接的网络Id
- chainId = 'eth_chainId',
- // eth_requestAccunts 获取账号(可以理解为链接钱包)
- requestAccount = 'eth_requestAccounts',
- // 获取账户地址
- accounts = 'eth_accounts',
- // 获取最新区块编号
- blockNumber = 'eth_blockNumber'
- }
- // 添加一条链到metamask上时请求网络参数
- export const AddEthereumChainParams: { [key: number]: any } = {
- 8: {
- chainId: '0x8',
- chainName: 'Ubiq',
- chativeCurrency: {
- name: 'Ubiq Ether',
- symbol: 'BUQ',
- decimals: 18,
- },
- rpcUrl: ['https://rpc.octano.dev/'],
- blockExplorerUrls: ['https://ubiqscan.io/']
- },
- 56: {
- chainId: '0x38',
- chainName: 'Binance Smart Chain Mainnet',
- nativeCurrency: {
- name: 'BNB',
- symbol: 'bnb',
- decimals: 18
- },
- rpcUrls: ['https://bsc-dataseed1.ninicoin.io', 'https://bsc-dataseed1.defibit.io', 'https://bsc-dataseed.binance.org'],
- blockExplorerUrls: ['https://bscscan.com/'],
- }
- }
-
3、在react-app-env.d.ts内添加:
- /// <reference types="react-scripts" />
- interface Window {
- ethereum?:{
- isMetaMask?:true
- request?:(...args:any[])=>Promise<void>
- }
- BinanceChain?:{
- bnbSign?:(address:string,message:string) => Promise<{publicKey:string;signature:string}>
- }
- web3:any
- }
4、创建types文件夹,在这个文件夹中创建ethereum.tsx文件:
- type EthereumProviderEip1193 = {
- request: (args: {
- method: string
- params?: unknown[] | object
- }) => Promise<unknown>
- }
-
- type EthereumProviderSend = {
- send: (method: string, params: string[]) => Promise<unknown>
- }
-
- type EthereumProviderSendAsync = {
- sendAsync: (
- params: {
- method: string
- params: string[]
- from: string
- jsonrpc: '2.0'
- id: number
- },
- callback: (err: Error, result: unknown) => void
- ) => void
- selectedAddress: string
- }
-
- /**
- * window.ethereum 类型
- * Eip-1193 规范
- */
- export type EthereumProvider = EthereumProviderEip1193 &
- EthereumProviderSend &
- EthereumProviderSendAsync
5、再到utils文件夹中创建ethereum.ts文件:
- import { AddEthereumChainParams, MetaMaskRequestMethods } from "chain";
- import { EthereumProvider } from "types/ethereum";
-
- function isUnwrappedRpcResult(response: unknown): response is {
- error?: string
- result?: unknown
- } {
- return (
- typeof response === 'object' && response !== null && 'jsonrpc' in response
- )
- }
- /**
- * 防止有的客户端没有包裹response
- */
- export function rpcResult(response: unknown): unknown | null {
- // Some providers don’t wrap the response
- if (isUnwrappedRpcResult(response)) {
- if (response.error) {
- throw new Error(response.error)
- }
- return response.result || null
- }
-
- return response || null
- }
- /**
- * metamask request 方法封装
- * @param ethereum provider, 浏览器中使用window.ethereum
- * @param method 请求方法
- * @param params 参数
- * @returns
- */
- export async function ethereumRequest(
- ethereum: EthereumProvider,
- method: string,
- params: string[]
- ): Promise<any> {
- // If ethereum.request() exists, the provider is probably EIP-1193 compliant.
- if (ethereum.request) {
- return ethereum.request({ method, params }).then(rpcResult)
- }
- // This is specific to some older versions of MetaMask combined with Web3.js.
- if (ethereum.sendAsync && ethereum.selectedAddress) {
- return new Promise((resolve, reject) => {
- ethereum.sendAsync(
- {
- method,
- params,
- from: ethereum.selectedAddress,
- jsonrpc: '2.0',
- id: 0,
- },
- (err: Error, result: any) => {
- if (err) {
- reject(err)
- } else {
- resolve(result)
- }
- }
- )
- }).then(rpcResult)
- }
- // If none of the previous two exist, we assume the provider is pre EIP-1193,
- // using .send() rather than .request().
- if (ethereum.send) {
- return ethereum.send(method, params).then(rpcResult)
- }
- throw new Error(
- 'The Ethereum provider doesn’t seem to provide a request method.'
- )
- }
-
- /**
- * 获取区块编码
- * @param ethereum provider, 默认使用window.ethereum
- * @returns
- */
- export async function getBlockNumber(ethereum?: EthereumProvider) {
- ethereum = ethereum ?? window.ethereum as any
- return ethereumRequest(ethereum!, MetaMaskRequestMethods.blockNumber, [])
- }
- /**
- * 添加链到metamask 上
- */
- export async function addChainToBlock(id: number, ethereum?: EthereumProvider) {
- ethereum = ethereum ?? window.ethereum as any
- const params = AddEthereumChainParams[id]
- // ! 确保ethereum 部位null
- return ethereumRequest(ethereum!, MetaMaskRequestMethods.addEthereumChain, [params])
- }
6、在创建hooks文件夹,在这个文件夹里创建useAuth.ts:
- import { UnsupportedChainIdError, useWeb3React } from '@web3-react/core'
- import { InjectConnector } from '../utils/web3'
- import { addChainToBlock } from 'utils/ethereum'
-
- export const useAuth = () => {
- const { activate } = useWeb3React()
- const Login = () => {
- if (InjectConnector) {
- activate(InjectConnector, async (error: Error) => {
- if (error instanceof UnsupportedChainIdError) {
- const hasSetup = await addChainToBlock(56)
- if (hasSetup) {
- activate(InjectConnector)
- }
- }
- })
- }
- }
- return Login
- }
然后再src目录下的index.tsx文件下这么写:
- import React from "react";
- import ReactDOM from "react-dom";
- import "./index.css";
- import App from "./App";
- import reportWebVitals from "./reportWebVitals";
- // 这下边的两个是添加的引入文件
- import { getLibray } from "./utils/web3";
- import { Web3ReactProvider } from "@web3-react/core";
-
- ReactDOM.render(
- <React.StrictMode>
-
- {/* 在这里用 Web3ReactProvider 包裹 app 文件 */}
- <Web3ReactProvider getLibrary={getLibray}>
- <App />
- </Web3ReactProvider>
-
- </React.StrictMode>,
- document.getElementById("root")
- );
-
- // If you want to start measuring performance in your app, pass a function
- // to log results (for example: reportWebVitals(console.log))
- // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
- reportWebVitals();
在然后再你需要获取MetaMask小狐狸地址的地方这么写:
- import React, { useEffect } from "react";
- import "./App.css";
- import { useWeb3React } from "@web3-react/core";
- import { useAuth } from "hooks/useAuth";
-
- function App() {
- const Login = useAuth();
- const { account, library, chainId } = useWeb3React();
- console.log("地址1", account);
-
- const GetClick = () => {
- Login();
- console.log("地址2", account);
- };
-
- useEffect(() => {
- Login();
- }, []);
-
- return (
- <div className="App">
- <button onClick={GetClick}>获取钱包地址</button>
- </div>
- );
- }
-
- export default App;
你只需要按我说的创建文件夹步骤复制代码,就可以链接到你的小狐狸了,记得要在tsconfig.json文件中添加"baseUrl": "src",
希望我能帮到你。我技术有限,有不对的地方请在评论区指教;
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。