设法在我的网站上连接到 Metamask,但我无法显示余额
Managed to connect with Metamask in my website but I can't show the balance
我使用以下代码通过我的应用程序成功连接到 MetaMask:
import React, { useEffect, useState } from "react";
import Web3 from "web3";
import styles from "./MetamaskAuthStyle.css";
function isMobileDevice() {
return "ontouchstart" in window || "onmsgesturechange" in window;
}
async function connect(onConnected) {
if (!window.ethereum) {
alert("Get MetaMask!");
return;
}
const accounts = await window.ethereum.request({
method: "eth_requestAccounts",
});
onConnected(accounts[0]);
}
async function checkIfWalletIsConnected(onConnected) {
if (window.ethereum) {
const accounts = await window.ethereum.request({
method: "eth_accounts",
});
if (accounts.length > 0) {
const account = accounts[0];
onConnected(account);
return;
}
if (isMobileDevice()) {
await connect(onConnected);
}
}
}
// async function getBalance(userAddress) {
// console.log(web3.eth.getBalance(userAddress));
// return web3.eth.getBalance(userAddress);
// }
export default function MetaMaskAuth({ onAddressChanged }) {
const [userAddress, setUserAddress] = useState("");
let web3: Web3 = new Web3();
useEffect(() => {
checkIfWalletIsConnected(setUserAddress);
}, []);
useEffect(() => {
console.log(web3.eth.getBalance(userAddress));
onAddressChanged(userAddress);
}, [userAddress]);
return userAddress ? (
<div>
Connected with <Address userAddress={userAddress} />
<p>Balance: </p>
</div>
) : (
<Connect setUserAddress={setUserAddress} />
);
}
function Connect({ setUserAddress }) {
if (isMobileDevice()) {
const dappUrl = "metamask-auth.ilamanov.repl.co"; // TODO enter your dapp URL. For example: https://uniswap.exchange. (don't enter the "https://")
const metamaskAppDeepLink = "https://metamask.app.link/dapp/" + dappUrl;
return (
<a href={metamaskAppDeepLink}>
<button className={styles.button}>Connect to MetaMask</button>
</a>
);
}
return (
<button className={styles.button} onClick={() => connect(setUserAddress)}>
Connect to MetaMask
</button>
);
}
function Address({ userAddress }) {
return (
<span className={styles.address}>
{userAddress.substring(0, 5)}…
{userAddress.substring(userAddress.length - 4)}
</span>
);
}
我是这个领域的新手,我想了解如何显示已登录用户的余额并显示断开连接按钮,以便用户可以注销。我已经尝试制作 getBalance 函数,但出现以下错误:
Error: Provided address is invalid, the capitalization checksum test
failed, or it's an indirect IBAN address which can't be converted
将默认的 dappUrl 更新为您的项目 URL:
const dappUrl = "metamask-auth.ilamanov.repl.co"
这里是关于如何通过 Web3.js 将 React 应用程序连接到 Metamask 的方法。
主要思想是使用 React 钩子来环绕预期的 web3.js 函数。
下图均显示
(1) 如何获取当前账户的余额和
(2) 任意指定账户的余额。
首先让我们在一个单独的文件中创建一个自定义 React 钩子 useWeb3.js
并将所有 Metamask/web3 连接逻辑放在那里。这个钩子如下:
import { useState } from 'react';
import Web3 from 'web3';
function useWeb3(setIsLoading, setErrorMessage) {
// web3 instance
const [provider, setProvider] = useState(null);
// active account
const [account, setAccount] = useState('');
// connect this function to a button click event
const connect = async () => {
try {
setIsLoading(true);
setErrorMessage('');
// ensure Metamask is installed
if (!window.ethereum) throw new Error('You should enable Metamask');
// show Metamask prompt
await window.ethereum.request({ method: 'eth_requestAccounts' });
// connect Metamask to web3.js and get a web3 provider instance
const web3 = new Web3(window.ethereum);
setProvider(web3);
// refresh account on change
window.ethereum.on('accountsChanged', (accounts) =>
setAccount(accounts[0]),
);
// retrieve Metamask accounts from web3
const accounts = await web3.eth.getAccounts();
setAccount(accounts[0]);
} catch (error) {
setErrorMessage(error.message);
} finally {
setIsLoading(false);
}
};
// connect this function to a disconnect button
const disconnect = () => {
setProvider(null);
setAccount('');
};
return { connect, disconnect, provider, account };
}
export default useWeb3;
请注意,将 metamask/web3 连接代码移动到它自己的自定义挂钩中很方便,
以便在应用的多个组件或部分中重复使用。
要动态观察余额信息,我们可以创建一个useBalance()
钩子。这是一个使用上述 useWeb3()
钩子的示例实现:
import { useEffect, useState } from 'react';
function useBalance(web3, account, setLoading, setErrorMessage) {
const [balance, setBalance] = useState('?');
useEffect(() => {
if (web3 && account) {
(async () => {
try {
setLoading(true);
setErrorMessage('');
// Will convert an upper or lowercase Ethereum address to a checksum address.
// https://web3js.readthedocs.io/en/v1.2.11/web3-utils.html#tochecksumaddress
const correctedAccount = web3.utils.toChecksumAddress(account);
const balanceInWei = await web3.eth.getBalance(correctedAccount);
setBalance(
// convert balance from wei to ether
Number(web3.utils.fromWei(balanceInWei, 'ether')).toFixed(2),
);
} catch (error) {
setErrorMessage(error.message);
setBalance('?');
} finally {
setLoading(false);
}
})();
}
}, [web3, account, setLoading, setErrorMessage]);
return balance;
}
export default useBalance;
然后我们可以连接到真实的区块链,看看是否一切正常。
要向 RSK 网络添加连接,
按照 here.
中的描述使用 Metamask 中的配置
现在 App.js
我们可以将所有挂钩放在一起来检索余额。
奖金示例
这是另一个包含
用户可以粘贴的文本字段
来自 RSK explorer 的任何地址
并查看其余额。
它还利用了上面的 useWeb3()
钩子。
import { useState } from 'react';
import useWeb3 from './hooks/useWeb3';
import useBalance from './hooks/useBalance';
import './App.css';
function App() {
// loading status
const [isLoading, setIsLoading] = useState(false);
// error messages
const [errorMessage, setErrorMessage] = useState('');
// get active account and balance data from useWeb3 hook
const {
connect,
disconnect,
provider,
account: activeAccount,
} = useWeb3(setIsLoading, setErrorMessage);
// get active account balance from useBalance hook
const activeBalance = useBalance(
provider,
activeAccount,
setIsLoading,
setErrorMessage,
);
// random non-empty account from RSK explorer https://explorer.rsk.co/
const [customAcount, setCustomAccount] = useState(
'0xC2a41f76CaCFa933c3496977f2160944EF8c2de3',
);
// get balance of the custom account
const customBalance = useBalance(
provider,
customAcount,
setIsLoading,
setErrorMessage,
);
return (
<div className="App">
{/* instantiate web3 only after a user clicks the button */}
{/* avoid doing it automatically */}
{!provider ? (
<button onClick={connect}>Connect to MetaMask</button>
) : (
<>
<p>Connected with {activeAccount}</p>
<p>My balance: {activeBalance} RBTC</p>
{/* let a user enter any address and see its balance */}
<p>Check RSK account:</p>
<input
type="text"
value={customAcount}
onChange={(e) => setCustomAccount(e.target.value)}
style={{ width: '25rem' }}
/>
<p>
<a href={`https://explorer.rsk.co/address/${customAcount}`}>
RSK account
</a>
{' balance:'}
{customBalance} RBTC
</p>
<button onClick={disconnect}>Disconnect</button>
</>
)}
{/* show loading and error statuses */}
{isLoading && <p>Loading...</p>}
{errorMessage && <p>{errorMessage}</p>}
</div>
);
}
export default App;
Connected with 0x1926617E081D3a670b3553FB0ba75180Bc01b215
My balance: 0.00 RBTC
Check RSK account:
0xC2a41f76CaCFa933c3496977f2160944EF8c2de3
RSK account balance:10.53 RBTC
[Disconnect]
如果您想尝试一个工作示例,请查看
demo-code-snippets/web3-react-show-balance
.
我使用以下代码通过我的应用程序成功连接到 MetaMask:
import React, { useEffect, useState } from "react";
import Web3 from "web3";
import styles from "./MetamaskAuthStyle.css";
function isMobileDevice() {
return "ontouchstart" in window || "onmsgesturechange" in window;
}
async function connect(onConnected) {
if (!window.ethereum) {
alert("Get MetaMask!");
return;
}
const accounts = await window.ethereum.request({
method: "eth_requestAccounts",
});
onConnected(accounts[0]);
}
async function checkIfWalletIsConnected(onConnected) {
if (window.ethereum) {
const accounts = await window.ethereum.request({
method: "eth_accounts",
});
if (accounts.length > 0) {
const account = accounts[0];
onConnected(account);
return;
}
if (isMobileDevice()) {
await connect(onConnected);
}
}
}
// async function getBalance(userAddress) {
// console.log(web3.eth.getBalance(userAddress));
// return web3.eth.getBalance(userAddress);
// }
export default function MetaMaskAuth({ onAddressChanged }) {
const [userAddress, setUserAddress] = useState("");
let web3: Web3 = new Web3();
useEffect(() => {
checkIfWalletIsConnected(setUserAddress);
}, []);
useEffect(() => {
console.log(web3.eth.getBalance(userAddress));
onAddressChanged(userAddress);
}, [userAddress]);
return userAddress ? (
<div>
Connected with <Address userAddress={userAddress} />
<p>Balance: </p>
</div>
) : (
<Connect setUserAddress={setUserAddress} />
);
}
function Connect({ setUserAddress }) {
if (isMobileDevice()) {
const dappUrl = "metamask-auth.ilamanov.repl.co"; // TODO enter your dapp URL. For example: https://uniswap.exchange. (don't enter the "https://")
const metamaskAppDeepLink = "https://metamask.app.link/dapp/" + dappUrl;
return (
<a href={metamaskAppDeepLink}>
<button className={styles.button}>Connect to MetaMask</button>
</a>
);
}
return (
<button className={styles.button} onClick={() => connect(setUserAddress)}>
Connect to MetaMask
</button>
);
}
function Address({ userAddress }) {
return (
<span className={styles.address}>
{userAddress.substring(0, 5)}…
{userAddress.substring(userAddress.length - 4)}
</span>
);
}
我是这个领域的新手,我想了解如何显示已登录用户的余额并显示断开连接按钮,以便用户可以注销。我已经尝试制作 getBalance 函数,但出现以下错误:
Error: Provided address is invalid, the capitalization checksum test failed, or it's an indirect IBAN address which can't be converted
将默认的 dappUrl 更新为您的项目 URL:
const dappUrl = "metamask-auth.ilamanov.repl.co"
这里是关于如何通过 Web3.js 将 React 应用程序连接到 Metamask 的方法。 主要思想是使用 React 钩子来环绕预期的 web3.js 函数。 下图均显示 (1) 如何获取当前账户的余额和 (2) 任意指定账户的余额。
首先让我们在一个单独的文件中创建一个自定义 React 钩子 useWeb3.js
并将所有 Metamask/web3 连接逻辑放在那里。这个钩子如下:
import { useState } from 'react';
import Web3 from 'web3';
function useWeb3(setIsLoading, setErrorMessage) {
// web3 instance
const [provider, setProvider] = useState(null);
// active account
const [account, setAccount] = useState('');
// connect this function to a button click event
const connect = async () => {
try {
setIsLoading(true);
setErrorMessage('');
// ensure Metamask is installed
if (!window.ethereum) throw new Error('You should enable Metamask');
// show Metamask prompt
await window.ethereum.request({ method: 'eth_requestAccounts' });
// connect Metamask to web3.js and get a web3 provider instance
const web3 = new Web3(window.ethereum);
setProvider(web3);
// refresh account on change
window.ethereum.on('accountsChanged', (accounts) =>
setAccount(accounts[0]),
);
// retrieve Metamask accounts from web3
const accounts = await web3.eth.getAccounts();
setAccount(accounts[0]);
} catch (error) {
setErrorMessage(error.message);
} finally {
setIsLoading(false);
}
};
// connect this function to a disconnect button
const disconnect = () => {
setProvider(null);
setAccount('');
};
return { connect, disconnect, provider, account };
}
export default useWeb3;
请注意,将 metamask/web3 连接代码移动到它自己的自定义挂钩中很方便, 以便在应用的多个组件或部分中重复使用。
要动态观察余额信息,我们可以创建一个useBalance()
钩子。这是一个使用上述 useWeb3()
钩子的示例实现:
import { useEffect, useState } from 'react';
function useBalance(web3, account, setLoading, setErrorMessage) {
const [balance, setBalance] = useState('?');
useEffect(() => {
if (web3 && account) {
(async () => {
try {
setLoading(true);
setErrorMessage('');
// Will convert an upper or lowercase Ethereum address to a checksum address.
// https://web3js.readthedocs.io/en/v1.2.11/web3-utils.html#tochecksumaddress
const correctedAccount = web3.utils.toChecksumAddress(account);
const balanceInWei = await web3.eth.getBalance(correctedAccount);
setBalance(
// convert balance from wei to ether
Number(web3.utils.fromWei(balanceInWei, 'ether')).toFixed(2),
);
} catch (error) {
setErrorMessage(error.message);
setBalance('?');
} finally {
setLoading(false);
}
})();
}
}, [web3, account, setLoading, setErrorMessage]);
return balance;
}
export default useBalance;
然后我们可以连接到真实的区块链,看看是否一切正常。 要向 RSK 网络添加连接, 按照 here.
中的描述使用 Metamask 中的配置现在 App.js
我们可以将所有挂钩放在一起来检索余额。
奖金示例
这是另一个包含
用户可以粘贴的文本字段
来自 RSK explorer 的任何地址
并查看其余额。
它还利用了上面的 useWeb3()
钩子。
import { useState } from 'react';
import useWeb3 from './hooks/useWeb3';
import useBalance from './hooks/useBalance';
import './App.css';
function App() {
// loading status
const [isLoading, setIsLoading] = useState(false);
// error messages
const [errorMessage, setErrorMessage] = useState('');
// get active account and balance data from useWeb3 hook
const {
connect,
disconnect,
provider,
account: activeAccount,
} = useWeb3(setIsLoading, setErrorMessage);
// get active account balance from useBalance hook
const activeBalance = useBalance(
provider,
activeAccount,
setIsLoading,
setErrorMessage,
);
// random non-empty account from RSK explorer https://explorer.rsk.co/
const [customAcount, setCustomAccount] = useState(
'0xC2a41f76CaCFa933c3496977f2160944EF8c2de3',
);
// get balance of the custom account
const customBalance = useBalance(
provider,
customAcount,
setIsLoading,
setErrorMessage,
);
return (
<div className="App">
{/* instantiate web3 only after a user clicks the button */}
{/* avoid doing it automatically */}
{!provider ? (
<button onClick={connect}>Connect to MetaMask</button>
) : (
<>
<p>Connected with {activeAccount}</p>
<p>My balance: {activeBalance} RBTC</p>
{/* let a user enter any address and see its balance */}
<p>Check RSK account:</p>
<input
type="text"
value={customAcount}
onChange={(e) => setCustomAccount(e.target.value)}
style={{ width: '25rem' }}
/>
<p>
<a href={`https://explorer.rsk.co/address/${customAcount}`}>
RSK account
</a>
{' balance:'}
{customBalance} RBTC
</p>
<button onClick={disconnect}>Disconnect</button>
</>
)}
{/* show loading and error statuses */}
{isLoading && <p>Loading...</p>}
{errorMessage && <p>{errorMessage}</p>}
</div>
);
}
export default App;
Connected with 0x1926617E081D3a670b3553FB0ba75180Bc01b215
My balance: 0.00 RBTC
Check RSK account:
0xC2a41f76CaCFa933c3496977f2160944EF8c2de3
RSK account balance:10.53 RBTC
[Disconnect]
如果您想尝试一个工作示例,请查看
demo-code-snippets/web3-react-show-balance
.