web3-react常用功能方法封装

本文详细介绍了如何使用web3-react库进行以太坊相关功能的封装,包括设置provider、获取web3实例、切换链、获取合约余额、监听区块高度等。此外,还展示了如何连接MetaMask钱包和实现链切换功能。内容涵盖web3-react核心组件的使用方法和实战技巧。
摘要由CSDN通过智能技术生成

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回调

Vue-React组件库的实现原理主要是通过将Vue组件转化为React组件,或将React组件转化为Vue组件,从而实现在Vue和React项目中同时使用的目的。 具体来说,Vue-React组件库的实现原理有以下几种方式: 1. 使用Vue-React转换器:Vue-React转换器是一个将Vue组件转换为React组件的工具,可以实现在React项目中使用Vue组件。转换器的实现原理是将Vue组件的模板转换为React组件的JSX语法,再在React项目中引入转换后的React组件。这种方式需要注意Vue组件的语法和React组件的语法差异,以及转换器的兼容性和性能问题。 2. 使用Vue-React组件库:Vue-React组件库是一个同时支持Vue和React的UI组件库,可以直接在Vue和React项目中使用。组件库的实现原理是针对Vue和React两种框架分别提供了组件的实现,通过封装和兼容处理,实现在两种框架中的使用。这种方式需要注意组件的兼容性和性能问题,以及组件库的选择和使用方法。 3. 使用Web Components:Web Components是一种通用的组件规范,可以在各种前端框架中使用。Vue和React都支持Web Components规范,因此可以使用Web Components实现在两种框架中共享组件。这种方式需要注意组件的规范和兼容性问题,以及Web Components的使用方法和浏览器支持情况。 需要注意的是,使用Vue-React组件库的方式相对简单,而且在实现原理上比较清晰,因此在实际开发中比较常用。但是,不同的Vue-React组件库实现方式略有不同,需要根据具体组件库的文档进行使用和配置。同时,也需要注意不同框架之间的差异和兼容性问题,避免出现不可预期的错误。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值