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>
export function getLibrary(provider) {
const library = new Web3Provider(provider)
library.pollingInterval = 8000
return library
}
作用:在根部Web3ReactProvider实例化的时候使用
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);
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
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()
}
})
}
变量声明
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回调