walletconnect-monorepo
walletconnect-monorepo copied to clipboard
QR code modal doesnt open after closing once
Same as #243 after provider.enable() if user clicks on the x and closes the modal it doesnt open again, someone claims to hv fixed it in the above issue and closed it but it still persists and no one has bothered to look at the replies and open it again, please fix this it's terrible UX there are more issues opened with same problem #538
Even a site such as OpenSea faces the same issue, here im attaching a screenshot
Same problem here
I posted a workaround for the @walletconnect/core
and @walletconnect/qrcode-modal
packages but could likely be applied to the provider if you can find a reference to _qrcodeModal
from core on the provider instance.
https://github.com/WalletConnect/walletconnect-monorepo/issues/538#issuecomment-1068628023
+1
+2
+3
@anoushk1234 @swaxtic @Loque18 @jamesonnuss I came up with a workaround for this that uses import WalletConnectProvider from '@walletconnect/web3-provider'
There are a few parts to this...
First I made a small getter for the provider so I could reference the instance throughout my app(the modal_closed
event listener is important here):
import WalletConnectProvider from '@walletconnect/web3-provider'
// Get the WalletConnectProvider instance if already instantiated, otherwise instantiate it and return it
let walletConnectProvider: WalletConnectProvider
export let shouldForceModalOpen: boolean = false
export const getWalletConnectProvider: () => WalletConnectProvider = () => {
if (!walletConnectProvider) {
walletConnectProvider = new WalletConnectProvider({
infuraId: `YOUR INFURA ID`,
})
// Listen for the QR Code Modal's 'modal_closed' event (I found it when looking here: https://github.com/WalletConnect/walletconnect-monorepo/blob/7573fa9e1d91588d4af3409159b4fd2f9448a0e2/packages/providers/web3-provider/src/index.ts#L222)
walletConnectProvider.wc.on('modal_closed', () => {
shouldForceModalOpen = true
console.log('QR Code Modal closed')
})
}
return walletConnectProvider
}
Then I added this to the top level of my app to check if the user is already connected so I can persist their session across page refreshes(if they're not connected, they'll need to click a 'Connect Wallet Client' button I added to the header):
const provider = await getWalletConnectProvider()
if (provider.connector._connected) {
// Load account data and populate wallet/evm stores
await loadAccountData()
}
This is the callback for the Connect Wallet Client
button that's shown in the header if the user is not already connected:
import { shouldForceModalOpen, getWalletConnectProvider, loadAccountData } from '$lib/wallet/utils'
const handleConnectWalletClient: () => Promise<void> = async () => {
if (shouldForceModalOpen) {
const provider = getWalletConnectProvider()
// This is the code to manually re-open the QR Code Modal if it has already been closed
provider.qrcodeModal.open(provider.connector.uri, { bridge: provider.bridge })
}
// Load account data and populate wallet/evm stores
await loadAccountData()
}
Lastly, this is a bit of code where you can call provider.enable() and populate any stores or anything you need to:
export const loadAccountData: () => Promise<void> = async () => {
try {
// Get WalletConnectProvider
const walletConnectProvider = getWalletConnectProvider()
await walletConnectProvider.enable()
// I'm using ethers in my app, but I put the web3js code here to be consistent with the WalletConnect docs
const web3Provider = new providers.Web3Provider(walletConnectProvider);
// Do anything else you need to, such as populating stores, etc...
} catch (error) {
console.error(error)
}
}
I came across this issue while I was implementing WalletConnect today and couldn't find any workarounds for it online, so hopefully this helps other people who are also dealing with it 👌🏼
@avivash being annoyed with this for some time! now it works!
thanks!
version => @walletconnect/[email protected]
+4
Hi there,I have a pretty simple workround,just need css and jquery(or js),here is my workround:
I use Vue3 in my project,code screenshot:
There is a sign in button in my page,when I click sign in button,signInflag is set to true,and then trigger this watch function:
- It must be delayed,settimeout is important, 500ms is enough, otherwise walletconnect-wrapper will not be added to the dom
walletconnect-wrapper is :
- create a closeBtn,the style of it is from original walletconnect close button
- and appent to header,override the original close button
- bind a click event to closeBtn,because of closeBtn is a dynamic element,you must to use $().on('click',()=>{})
- and then set signInFlag to false,in order to trigger watch function next time.
Full code is here:
watch(() => signInflag.value, (newValue) => {
if (newValue) {
setTimeout(() => {
$('#walletconnect-wrapper').css({ 'z-index': '99999999999999', 'opacity': '1' })
let closeBtn = '<div id="closeQrcodeModalBtn" style="opacity:0;z-index:999999;position: absolute;top: 0px;right: 0px;background: white;border-radius: 26px;padding: 6px;box-sizing: border-box;width: 26px;height: 26px;cursor: pointer; "></div>'
$('.walletconnect-modal__header').append(closeBtn)
$('#closeQrcodeModalBtn').on('click', () => {
$('#walletconnect-wrapper').css({ 'z-index': '-1', 'opacity': '0' })
signInflag.value = false;
})
}, 500);
}
})
There is no problem with my use, it can be solved perfectly, no complicated js is needed at all, although it is a bad hack, but until the official solution of walletconnect, it can be regarded as a feasible solution, I hope it can help friends who encounter the same problem .
Just recreate WalletConnect instance with catch
private createWalletConnect() {
const walletConnect = new WalletConnect({
bridge: 'https://bridge.walletconnect.org',
qrcodeModal: QRCodeModal,
});
walletConnect.on('connect', this.onConnect);
walletConnect.on('disconnect', this.onDisconnect);
walletConnect.on('session_update', (_, payload) => this.onSessionUpdate(payload));
return walletConnect;
}
connect() {
if (this.wallet) {
throw new Error('Wallet is already connected');
}
this.walletConnect
.connect()
// Reopening WalletConnect modal doesn't work
// Workaround: https://github.com/Uniswap/web3-react/issues/124#issuecomment-817631654
.catch(() => { this.walletConnect = this.createWalletConnect(); });
}
Seems like combining these two is a better fix:
- https://github.com/Uniswap/web3-react/issues/124#issuecomment-817631654
- https://github.com/Uniswap/web3-react/issues/124#issuecomment-984882534
@anoushk1234 is this still an issue after trying @goncharov-vlad solution?
@anoushk1234 is this still an issue after trying @goncharov-vlad solution?
havent tried it out but it if it's working then that's great
const isRequestActive: Ref<UnwrapRef
console.log('if AFTER', );
try {
// Example: Requesting account access
const accounts = await (window.ethereum as any)?.request({ method: 'eth_requestAccounts' }).then((account) => console.log('account', account)).catch((error: unknown) => console.error('error', error)).finally(() => console.log('finally', ));
// Proceed with additional actions like showing balance, switching chains, etc.
console.log('NEW accounts', accounts);
isRequestActive.value = true;
} catch (error) {
console.error("NEW Error interacting with MetaMask:", error);
// Handle error appropriately
isRequestActive.value = false;
} finally {
console.log('NEW finally isRequestActive.value', isRequestActive.value);
isRequestActive.value = false;
}
console.log('metaMaskCall end', );
For catching error here the magic is done in this line of code above:
const accounts = await (window.ethereum as any)?.request({ method: 'eth_requestAccounts' }).then((account) => console.log('account', account)).catch((error: unknown) => console.error('error', error)).finally(() => console.log('finally', ));
We caught this error in .catch method of request.
this code is for Vue 3 with typescript