web3-react常用功能方法封装

web3-react常用功能封装分享

使用web3-react

import {
    
    Web3ReactProvider} from '@web3-react/core'

function getLibrary(provider) {
    
    
  const library = new Web3Provider(provider)
  library.pollingInterval = 8000
  return library
}

// render

<Web3ReactProvider getLibrary={
    
    getLibrary}>
	<App/>
</Web3ReactProvider>

获取library(provider)

获取web3实例的library

export function getLibrary(provider) {
    
    
  const library = new Web3Provider(provider)
  library.pollingInterval = 8000
  return library
}

作用:在根部Web3ReactProvider实例化的时候使用

获取指定链的library

const library = new JsonRpcProvider(RPC_URL, chainId)
// 例:获取币安链的library
const library = new JsonRpcProvider(https://bsc-dataseed.binance.org/, 56)

作用:可以当作ethers-multicall-x实例化的library参数

import {
    
     Contract, Provider} from 'ethers-multicall-x';
const multiCallProvider = new Provider(library, chainId);

获取当前连接的library

import {
    
    useWeb3React} from '@web3-react/core'
const {
    
    library} = useWeb3React()

获取当前的连接属性

import {
    
    useWeb3React} from '@web3-react/core'
const {
    
    library, deactivate, chainId, account, active} = useWeb3React()
属性 描述
library 当前连接的library
deactivate 断开连接的方法
chainId 当前连接的链id
account 当前连接的钱包账户地址
active 当前连接的状态,是否连接

以上是列举常用的属性,需要更详细的请查阅文档
https://github.com/NoahZinsmeister/web3-react/tree/v6/docs#web3reactprovider

获取web3实例

获取当前的实例

import Web3 from 'web3'
export const getWeb3 = library => new Web3(library.provider)

获取指定实例

export const getRpcUrl = chainId => {
    
    
  const RPC_URLS = {
    
    
    [ChainId.HECO]: 'https://http-mainnet-node.huobichain.com',
    [ChainId.BSC]: 'https://bsc-dataseed.binance.org/',
    [ChainId.MATIC]: 'https://rpc-mainnet.maticvigil.com'
  }
  return RPC_URLS[chainId]
}

export const getHttpWeb3 = chainId => new Web3(new Web3.providers.HttpProvider(getRpcUrl(chainId)))

获取合约账户余额

import {
    
    useWeb3React} from '@web3-react/core'

export const getContract = (library, abi, address) => {
    
    
  const web3 = new Web3(library.provider)
  return new web3.eth.Contract(abi, address)
}

const contract = getContract(library, abi, address)
      contract.methods
        .balanceOf(account).call()
        .then(balance_ => {
    
    
          console.log('balance_', balance_)
          setBalance(balance_.toString())
        })

library可以是当前的,也可以是上面自己构造的
abi 合约abi 你要取账户在哪个合约的余额呢 一般ERC20是通用的
address 合约地址

获取区块链块的高度

获取块高度-监听

export function useBlockHeight() {
    
    
  const {
    
     account, active, library } = useActiveWeb3React()
  const [blockNumber, setBlockNumber] = useState(0)
  const {
    
     dispatch, state } = useContext(mainContext)

  const updateBlockNumber = (blockNumber) => {
    
    
    setBlockNumber(blockNumber)
  }
  useEffect(() => {
    
    
    library && library.once('block', updateBlockNumber)
    return () => {
    
    
      library && library.off('block', updateBlockNumber)
    }
  }, [blockNumber, library, state.randomNumber])

  return blockNumber
}

获取块高度-定时器

const {
    
    library} = useWeb3React()
  // 块高度
  const [blockHeight, setBlockHeight] = useState(0)
 const getBlockHeight = () => {
    
    
    const web3 = getWeb3(library) // getHttpWeb3(56)
    return web3.eth.getBlockNumber().then(height => {
    
    
      console.log('height', height)
      setBlockHeight(height)
      return height
    })
  }
  const timeOutGetBlockHeight = () => {
    
    
    getBlockHeight().then(() => {
    
    
      setTimeout(timeOutGetBlockHeight, 15000)
    })
  }

链切换

const SCAN_ADDRESS = {
    
    
  [ChainId.BSC]: 'https://bscscan.com',
  [ChainId.HECO]: 'https://hecoinfo.com',
  [ChainId.MATIC]: 'https://polygonscan.com/',
}
const networkConf = {
    
    
  [ChainId.HECO]: {
    
    
    chainId: '0x80',
    chainName: 'HECO',
    nativeCurrency: {
    
    
      name: 'HT',
      symbol: 'HT',
      decimals: 18,
    },
    rpcUrls: [
      'https://http-mainnet-node.huobichain.com',
    ],
    blockExplorerUrls: [SCAN_ADDRESS[ChainId.HECO]],
  },
  [ChainId.BSC]: {
    
    
    chainId: '0x38',
    chainName: 'BSC',
    nativeCurrency: {
    
    
      name: 'BNB',
      symbol: 'BNB',
      decimals: 18,
    },
    rpcUrls: ['https://bsc-dataseed.binance.org/'],
    blockExplorerUrls: [SCAN_ADDRESS[ChainId.BSC]],
  },
  [ChainId.MATIC]: {
    
    
    chainId: '0x89',
    chainName: 'MATIC',
    nativeCurrency: {
    
    
      name: 'MATIC',
      symbol: 'MATIC',
      decimals: 18,
    },
    rpcUrls: ['https://rpc-mainnet.maticvigil.com'],
    blockExplorerUrls: [SCAN_ADDRESS[ChainId.MATIC]],
  }
}

export const changeNetwork = chainId => {
    
    
  return new Promise(reslove => {
    
    
    const {
    
    ethereum} = window
    if (ethereum && ethereum.isMetaMask && networkConf[chainId]) {
    
    
      ethereum.request({
    
    
        method: 'wallet_addEthereumChain',
        params: [
          {
    
    
            ...networkConf[chainId]
          }
        ],
      }).then(() => {
    
    
        setTimeout(reslove, 500)
      })
    } else {
    
    
      reslove()
    }
  })
}

连接钱包、支持MetaMask和扫码连接

变量声明

export const ChainId = {
    
    
  BSC: 56,
  HECO: 128,
  MATIC: 137
}

// react-web3允许连接的链
export const injected = new InjectedConnector({
    
    
  supportedChainIds: [ChainId.MATIC, ChainId.BSC, ChainId.HECO],
})

// 扫码连接配置
export const POLLING_INTERVAL = 12000

const bscWalletConnector = new WalletConnectConnector({
    
    
  rpc: {
    
     56: 'https://bsc-dataseed.binance.org/' },
  bridge: 'https://bridge.walletconnect.org',
  qrcode: true,
  pollingInterval: POLLING_INTERVAL,
})

const hecoWalletConnector = new WalletConnectConnector({
    
    
  rpc: {
    
     128: 'https://http-mainnet-node.huobichain.com' },
  bridge: 'https://bridge.walletconnect.org',
  qrcode: true,
  pollingInterval: POLLING_INTERVAL,
})

const maticWalletConnector = new WalletConnectConnector({
    
    
  rpc: {
    
     137: 'https://rpc-mainnet.maticvigil.com' },
  bridge: 'https://bridge.walletconnect.org',
  qrcode: true,
  pollingInterval: POLLING_INTERVAL,
})

export const walletConnector = {
    
    
  [ChainId.HECO]: hecoWalletConnector,
  [ChainId.BSC]: bscWalletConnector,
  [ChainId.MATIC]: maticWalletConnector
}

方法

import {
    
     InjectedConnector,
  NoEthereumProviderError,
  UserRejectedRequestError} from '@web3-react/injected-connector'
import {
    
     UnsupportedChainIdError, useWeb3React } from '@web3-react/core'

export const useConnectWallet = () => {
    
    
  const {
    
    activate, deactivate, active} = useWeb3React()
  const connectWallet = useCallback((connector, chainId) => {
    
    
    return changeNetwork(chainId).then(() => {
    
    
        return activate(connector, undefined, true)
          .then((e) => {
    
    
            if ( window.ethereum && window.ethereum.on) {
    
    
              // 监听钱包事件
              console.log('注册事件')
              // const { ethereum } = window
              window.ethereum.on('accountsChanged', (accounts) => {
    
    
                if (accounts.length === 0) {
    
    
                  // 无账号,则代表锁定了,主动断开
                  deactivate()
                }
                // 账号改了,刷新网页
                // window.location.reload()
              })

              window.ethereum.on('disconnect', () => {
    
    
                // 断开连接
                deactivate()
              })

              window.ethereum.on('close', () => {
    
    
                // 断开连接
                deactivate()
              })

              window.ethereum.on('message', message => {
    
    
                console.log('message', message)
              })

            }
            reslove(e)
          })
          .catch((error) => {
    
    
            switch (true) {
    
    
              case error instanceof UnsupportedChainIdError:
                console.log('链错了')
                break
              case error instanceof NoEthereumProviderError:
                console.log('不是钱包环境')
                break
              case error instanceof UserRejectedRequestError:
                console.log('用户拒绝连接钱包')
                break
              default:
                console.log(error)
            }
            reject(error)
          })
      })
    })
  }

  useMemo(() => {
    
    
  // 首次尝试连接
    !active && connectWallet(injected)
    window.ethereum && window.ethereum.on('networkChanged', () => {
    
    
      // 切换网络后,尝试连接
      !active && connectWallet(injected)
    })
  }, [])
  return connectWallet
}

调用连接MetaMask

connectWallet(injected, ChainId.BSC).then()

调用扫码连接

connectWallet(walletConnector[ChainId.BSC]).then()

发送请求

export function getContract(library, abi, address) {
    
    
  const web3 = new Web3(library.provider)
  return new web3.eth.Contract(abi, address)
}

const contract = getContract(library, abi, address)
contract.methods
  .exit()
  .send({
    
    
	from: account,
  })
  .on('transactionHash', (hash) => {
    
    
	
  })
  

exit 合约的方法名
send 表示发送请求 通常为涉及敏感操作的如发送交易 授权等, call发送请求通常为查询操作
on 监听transactionHash回调

猜你喜欢

转载自blog.csdn.net/weixin_43840202/article/details/118907658