Error: Keys not exchanged when calling await ethereum.request({method: ‘eth_requestAccounts’})
I am trying to connect my React Native app to MetaMask with
MetamaskSDK, but I am getting the error “Error: Keys not exchanged”
when calling await ethereum.request({method: ‘eth_requestAccounts’}).
The connection request gets stuck on the phrase “Connecting to
MetaMask”. This happens before MetaMask shows a connection request
popup with my application data. It is very strange that this error does not
occur on every connection.
Any help would be greatly appreciated.
My code:
const MMSDK = new MetaMaskSDK({
openDeeplink: (link) => {
Linking.openURL(link);
},
timer: BackgroundTimer,
dappMetadata: {
name: 'dapp',
url: 'https://dapp.com',
},
});
export const ethereum = MMSDK.getProvider();
const provider = new ethers.providers.Web3Provider(ethereum);
export const ConnectWallet = () => {
const [walletAddress, setWalletAddress] = useState('');
const [chain, setChain] = useState('');
const [isAuthenticated, setIsAuthenticated] = useState(false);
const [userDetails, setUserDetails] = useState({
token: null,
userId: null,
});
useEffect(() => {
ethereum.on('chainChanged', setChain);
ethereum.on('accountsChanged', handleAccountsChanged);
return () => {
ethereum.removeListener('chainChanged', setChain);
ethereum.removeListener('accountsChanged', handleAccountsChanged);
};
}, []);
const handleAccountsChanged = async (accounts) => {
setWalletAddress(accounts?.[0] || '');
onLogin();
};
const onConnect = async () => {
try {
if (!isAuthenticated && ethereum.isMetaMask) {
const result = await ethereum.request({ method: 'eth_requestAccounts' });
console.log('RESULT', result?.[0]);
setWalletAddress(result?.[0]);
}
else {
console.log("It looks like you don't have the Metamask App installed yet");
}
} catch (error) {
console.error('Error:', error);
}
};
const onLogin = async () => {
try {
const accounts = await ethereum.request({ method: 'eth_accounts' });
const [account] = accounts;
if (!account) {
setIsAuthenticated(false);
return;
}
const createNonce = await fetch(`${url}/nonce/${account}`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
});
const res = await createNonce.json();
if (res) {
const signature = await provider.getSigner().signMessage(res.nonce);
const response = await fetch(`${url}/user/`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
walletAddress: account,
signature: signature,
}),
});
const data = await response.json();
setUserDetails({
token: data.token,
userId: data.id,
});
setIsAuthenticated(true);
}
} catch (error) {
console.error('Error:', error);
}
};
return (
<View>
<Button onPress={onConnect} />
</View>
);
}