英文:
Metamask not returning "code 4001 User rejected the request." when closing login popup in Chrome, but works in Edge
问题
我正在尝试通过在单击按钮时启动登录流程来连接到Chrome上的Metamask扩展。但是,如果用户在单击按钮后关闭登录弹出窗口,Chrome不会抛出代码4001异常,控制台日志完全为空。之后,当我再次单击按钮时,它不再弹出登录弹出窗口,而是抛出“RPC错误:已经在处理eth_requestAccounts,请等待。”
但是,当我在Edge中尝试时,控制台会正常抛出异常(这是预期的结果)。刷新Chrome页面不起作用,必须关闭并重新打开整个浏览器才能重置它。
查看扩展图标时,我注意到在Edge中,每当我关闭登录按钮时,表示挂起交易的蓝色“1”通知将消失。但是在Chrome中,情况并非如此,蓝色“1”通知仍然存在。
以下是按钮的相关代码,如果有帮助的话。非常感谢您的协助:
import { Card, CardContent, Button, Grid } from '@material-ui/core';
import React, { useEffect, useState } from "react";
import MetaMaskOnboarding from '@metamask/onboarding';
function MetaMaskConnectButton(props) {
const forwarderOrigin = 'http://localhost:3000';
const onboarding = new MetaMaskOnboarding({ forwarderOrigin });
const { ethereum } = window;
const [buttonText, setButtonText] = useState('Connect MetaMask');
const [isButtonDisabled, setIsButtonDisabled] = useState(false);
const [mmAccounts, setMmAccounts] = useState('');
useEffect(() => {
if (!isMetaMaskInstalled()) {
setButtonText('Click here to install MetaMask!');
}
}, []);
useEffect(() => {
if (mmAccounts == null || mmAccounts.length === 0)
setIsButtonDisabled(false);
else
setIsButtonDisabled(true);
}, [mmAccounts]);
async function metaMaskClientCheck() {
if (!isMetaMaskInstalled()) {
await metamaskInstall();
setIsButtonDisabled(true);
} else {
await metamaskConnect();
setIsButtonDisabled(false);
}
}
const isMetaMaskInstalled = () => {
return Boolean(ethereum && ethereum.isMetaMask);
}
const metamaskInstall = async () => {
setButtonText('Onboarding in progress...');
setIsButtonDisabled(true);
onboarding.startOnboarding();
}
const metamaskConnect = async () => {
setIsButtonDisabled(true);
setButtonText('Connecting to MetaMask...');
try {
let accounts = await ethereum.request({ method: 'eth_requestAccounts' });
console.log('Ethereum Request over');
let account = accounts[0];
setMmAccounts(account);
setButtonText('MetaMask Connected');
} catch (error) {
console.error(error);
setIsButtonDisabled(false);
setButtonText('Connect MetaMask');
}
};
return (
<Grid container xs={12} sm={12}>
<Grid container xs={6} sm={6} justify='flex-start'>
<Button
disabled={isButtonDisabled}
variant='contained'
color='secondary'
className='button-blue originalText'
onClick={() => {
metaMaskClientCheck()
}}
classes={{ root: 'ng-button-filled-secondary' }}
>
{buttonText}
</Button>
</Grid>
</Grid>
)
}
export default MetaMaskConnectButton;
英文:
I am trying to connect to the Metamask extension on Chrome by having a button that initiates the log in process on click. However in the event the user closes the log in pop up after clicking the button, no code 4001 exception is thrown in Chrome, the console log is completely empty. After that when I click the button again, it will no longer bring up the log in pop up but instead throw "RPC Error: Already processing eth_requestAccounts. Please wait."
But when I tried in Edge, it throws just fine in the console (this is the expected result):
Refreshing the Chrome page does not help, I have to close and reopen the entire browser to reset it.
Looking into the extension icon, I noticed that in Edge, whenever I close the login button, the blue "1" notification which signifies pending transactions will be gone:
However in Chrome that is not the case, the blue "1" notification remains:
Here is the relevant code for the button if it helps. Any assistance is greatly appreciated:
import { Card, CardContent, Button, Grid } from '@material-ui/core'
import React, { useEffect, useState } from "react";
import MetaMaskOnboarding from '@metamask/onboarding';
function MetaMaskConnectButton(props) {   
const forwarderOrigin = 'http://localhost:3000';   
const onboarding = new MetaMaskOnboarding({ forwarderOrigin });   
const { ethereum } = window;   
const [buttonText, setButtonText] = useState('Connect MetaMask')   
const [isButtonDisabled, setIsButtonDisabled] = useState(false)   
const [mmAccounts, setMmAccounts] = useState('')   
useEffect(() => {       
if (!isMetaMaskInstalled()) {           
setButtonText('Click here to install MetaMask!')       
}
}, [])   
useEffect(() => {       
if (mmAccounts == null || mmAccounts.length === 0)
            setIsButtonDisabled(false)      
else           
setIsButtonDisabled(true)   
}, [mmAccounts])   
async function metaMaskClientCheck() {       
if (!isMetaMaskInstalled()) {           
await metamaskInstall()           
setIsButtonDisabled(true)       
}
else {           
await metamaskConnect()           
setIsButtonDisabled(false)       
}   
}   
//Function checks if the MetaMask extension is installed   
const isMetaMaskInstalled = () => {       
//Have to check the ethereum binding on the window object to see if it's installed
        return Boolean(ethereum && ethereum.isMetaMask);   
}   
const metamaskInstall = async () => {       
setButtonText('Onboarding in progress...')       
setIsButtonDisabled(true)       
onboarding.startOnboarding();   
}   
const metamaskConnect = async () => {       
setIsButtonDisabled(true)       
setButtonText('Connecting to MetaMask...')       
try {           
// Will open the MetaMask UI           
let accounts = await ethereum.request({ method: 'eth_requestAccounts' }) 
console.log('Ethereum Request over')           
let account = accounts[0]           
setMmAccounts(account)           
setButtonText('MetaMask Connected')       
} catch (error) {           
console.error(error);           
setIsButtonDisabled(false)           
setButtonText('Connect MetaMask')       
}   
};   
return (       
<Grid container xs={12} sm={12}>
<Grid container xs={6} sm={6} justify='flex-start'>
<Button                   
disabled={isButtonDisabled}                   
variant='contained'                   
color='secondary'
className='button-blue originalText'
                    onClick={() => {
                        metaMaskClientCheck()
                    }}
                    classes={{ root: 'ng-button-filled-secondary' }}
                >
                    {buttonText}
                </Button>
            </Grid>
        </Grid>
    )}
export default MetaMaskConnectButton
答案1
得分: 1
Chrome中的Metamask表现出奇怪的行为。我刚刚在Metamask Chrome上遇到了一个问题,在此处提问。在Mozilla和Brave上运行正常,但在Chrome上却不行。我已经禁用了所有的扩展(你可以尝试这样做),但错误仍然发生。我的主要计算机是Linux,当我在macOS的Chrome上启动相同的应用程序时,它可以正常运行。
你可以在这里阅读详细的讨论。我认为这个问题是与你的Chrome浏览器和设备有关的。
英文:
Chrome metamask behaves funky. I just had an issue with metamask chrome asked here. It was working on mozilla and brave but not on chrome. I disabled all the extensions (you should try this) but error still occurred. My main machine is Linux and when I started the same app on macos chrome, it worked.
You can read a long discussion here. I think the issue is specific to your chrome and device
答案2
得分: 1
你可以在当前代码中添加超时,并像这样抛出错误:
let timeout;
async function metamaskConnect() {
setIsButtonDisabled(true);
setButtonText('连接到 MetaMask...');
try {
let accounts = await ethereum.request({ method: 'eth_requestAccounts' });
console.log('以太坊请求完成');
let account = accounts[0];
setMmAccounts(account);
setButtonText('MetaMask 已连接');
timeout = setTimeout(() => {
setIsButtonDisabled(false);
setButtonText('连接 MetaMask');
}, 5000);
} catch (error) {
console.error(error);
setIsButtonDisabled(false);
setButtonText('连接 MetaMask');
}
}
或者作为另一种选择,也可以使用 Promise.reject
或抛出新的错误。
英文:
You can add a timeout to your current code and thrown an error like this:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
let timeout;
async function metamaskConnect() {
setIsButtonDisabled(true);
setButtonText('Connecting to MetaMask...');
try {
let accounts = await ethereum.request({ method: 'eth_requestAccounts' });
console.log('Ethereum Request over');
let account = accounts[0];
setMmAccounts(account);
setButtonText('MetaMask Connected');
timeout = setTimeout(() => {
setIsButtonDisabled(false);
setButtonText('Connect MetaMask');
}, 5000);
} catch (error) {
console.error(error);
setIsButtonDisabled(false);
setButtonText('Connect MetaMask');
}
}
<!-- end snippet -->
Or maybe use Promise.reject or thrown new Error as another option.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论