web3modal-react-native
web3modal-react-native copied to clipboard
Excessive 'MyApp wants to open ...' dialogs displayed during wallet selection (iOS)
Describe the bug During wallet selection, sometimes 'MyApp wants to open ...' dialog shown excessive times. This doesn't happen always.
SDK Version (if relevant)
"@tanstack/react-query": "^5.52.2",
"@walletconnect/react-native-compat": "2.15.1",
"@web3modal/wagmi-react-native": "^2.0.2",
"wagmi": "^2.12.7",
"@react-native-community/netinfo": "6.0.0",
"react-native-get-random-values": "^1.11.0",
To Reproduce Steps to reproduce the behavior:
- Go to 'WalletConnect'
- Click on '....'
- Scroll down to '....'
- See error
Expected behavior It should only show dialog once
Screenshots
Smartphone (please complete the following information):
- Device: iPhone
- OS: 17
Additional context
This problem occurs when we call web3Modal.open({ view: 'Connect' }); method and rest is handled by WalletConnect. Problem can be seen in the video:
https://github.com/user-attachments/assets/9abdcf8a-5503-40d5-9793-aacfbe06ae32
WalletConnectProvider.tsx:
import { WagmiProvider } from 'wagmi';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { createWeb3Modal, defaultWagmiConfig, Web3Modal } from '@web3modal/wagmi-react-native';
import React, { ReactNode } from 'react';
import { WALLET_CONNECT_PROJECT_ID } from '~/shared/environment';
import { mainnet, polygon, bsc, avalanche } from '@wagmi/core/chains';
const SUPPORTED_CHAIN_CONFIGS = [mainnet, polygon, bsc, avalanche] as const;
export const WALLET_CONNECT_METADATA: ConfigOptions['metadata'] = {
name: 'Bitvavo',
description: 'Connect your wallet',
url: 'https://bitvavo.com/',
icons: ['https://bitvavo.com/press/blue/bitvavo-mark/bitvavo-mark-blue.png'],
redirect: {
native: `${NAVIGATION_SCHEMA}://`
}
};
const queryClient = new QueryClient();
const wagmiConfig = defaultWagmiConfig({
chains: SUPPORTED_CHAIN_CONFIGS,
projectId: WALLET_CONNECT_PROJECT_ID,
metadata: WALLET_CONNECT_METADATA
});
createWeb3Modal({
projectId: WALLET_CONNECT_PROJECT_ID,
wagmiConfig,
enableAnalytics: false
});
export const WalletConnectProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
return (
<WagmiProvider config={wagmiConfig}>
<QueryClientProvider client={queryClient}>
{children}
<Web3Modal />
</QueryClientProvider>
</WagmiProvider>
);
};
WalletConnect.tsx;
import React from 'react';
import { Web3Modal } from '@web3modal/wagmi-react-native';
import { Steps } from '../ui/Steps';
import { WalletConnectProvider } from './WalletConnectProvider';
import { useWalletConnectConnectionManager } from './useWalletConnectConnectionManager';
const WalletConnectInner = () => {
const {
open,
isConnected,
disconnect: wcDisconnect,
sign: wcSign,
address,
loading
} = useWalletConnectConnectionManager();
const sign = async () => {
if (!address) return;
const signature = await wcSign();
if (!signature) return;
// omitted
};
const disconnect = () => {
wcDisconnect();
};
const getContent = () => {
if (loading) {
return <Steps.Loading />;
}
if (isConnected) {
return <Steps.Connected onPressOpenWallet={sign} onPressDisconnect={disconnect} />;
}
return <Steps.NotConnected onPressOpenWallet={open} />;
};
return (
<WalletConnectProvider>
{getContent()}
<Web3Modal />
</WalletConnectProvider>
);
};
export const WalletConnect = () => {
return (
<WalletConnectProvider>
<WalletConnectInner />
</WalletConnectProvider>
);
};
useWalletConnectConnectionManager.ts:
import { useWeb3Modal } from '@web3modal/wagmi-react-native';
import { useDisconnect, useAccount, useSignMessage } from 'wagmi';
export const useWalletConnectConnectionManager = () => {
const web3Modal = useWeb3Modal();
const mDisconnect = useDisconnect();
const account = useAccount();
const { signMessageAsync } = useSignMessage();
const { isConnected } = account;
const selectedChain = account.chain;
const open = () => {
web3Modal.open({ view: 'Connect' });
};
const disconnect = () => {
mDisconnect.disconnect();
};
const sign = async () => {
try {
const sig = await signMessageAsync({ message: 'Test' });
return sig;
// eslint-disable-next-line no-empty
} catch (e) {
return null;
}
};
return {
isConnected,
loading: account.isConnecting || account.isReconnecting,
selectedChain,
address: account.address,
open,
disconnect,
sign
};
};
Some logs appearing in case it helps:
Warning: Encountered two children with the same key, `f2436c67184f158d1beda5df53298ee84abfc367581e4505134b5bcf5f46697d:e9ff15be73584489ca4a66f64d32c4537711797e30b6660dbcb71ea72a42b1f4:bc949c5d968ae81310268bf9193f9c9fb7bb4e1283e1284af8f2bd4992535fd6:ef333840daf915aafdc4a004525502d6d49d77bd9c65e0642dbaefb3c2893bef`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.
Warning: Encountered two children with the same key, `9414d5a85c8f4eabc1b5b15ebe0cd399e1a2a9d35643ab0ad22a6e4a32f596f0:84b43e8ddfcd18e5fcb5d21e7277733f9cccef76f7d92c836d0e481db0c70c04:18450873727504ae9315a084fa7624b5297d2fe5880f0982979c17345a138277:fd20dc426fb37566d803205b19bbc1d4096b248ac04548e3cfb6b3a38bd033aa`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.
Task orphaned for request <NSMutableURLRequest: 0x305be9d80> { URL: data:image/webp;base64,UklGRsgQAABXRUJQVlA4ILwQAABQcgCdASqQAZABPkkkjkUioiEUKXx8KASEs7d4BNpW9CZkpB8Z9W19e3P8zgHpdMFzoj0P+ ... AAAAAAA= }
Task orphaned for request <NSMutableURLRequest: 0x305be9bc0> { URL: data:image/webp;base64,UklGRlQUAABXRUJQVlA4IEgUAABwdgCdASqQAZABPkkkkUWioiITC0QoKASEsrdz2QUiPEDmJQwum5L8xoKMRfc6pY9h+YHv+ ... F7AAAA== }
Task orphaned for request <NSMutableURLRequest: 0x305be9bb0> { URL: data:image/webp;base64,UklGRiIIAABXRUJQVlA4WAoAAAAQAAAAjwEAjwEAQUxQSMEEAAABoATb2uI2+lrdGZLkckvtMCdaucIsexVTOHGytIMqr1OcK ... AAAAAAA= }
Task orphaned for request <NSMutableURLRequest: 0x305be9b80> { URL: data:image/webp;base64,UklGRjYRAABXRUJQVlA4ICoRAAAQYgCdASqQAZABPkkkkUWioiGSKjQ0KASEsrd+M/y3Yz9adfKhid/4j+4/tn4jlJO2f2T9r ... AAAAAA== }
[MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 disconnect listeners added. Use emitter.setMaxListeners() to increase limit]
hey @ozgurrgul 👋 can you check if upgrading this solves the issue?
"@walletconnect/react-native-compat": "2.16.1",
"@web3modal/wagmi-react-native": "2.0.4",
"wagmi": "2.12.11",
I bumped the versions as instructed but unfortunately the same issue still persists when I test.
@ozgurrgul Okey, can you check having just one Web3Modal component? If you want to use the modal in two or more views, you should put it in the root view of your app.
I see you use Web3Modal component in WalletConnectProvider.tsx and in WalletConnect.tsx.
Removing it from WalletConnect should be enough
any news @ozgurrgul ?
hi @ignaciosantise, good catch I didn't notice WalletConnectProvider was used in 2 place
I moved WalletConnectProvider to our root, this issue still continues.
I also tried using W3mButton only to see if it solves, but still same.
Interesting things is this issue only happen on our prod build and not locally. I am not able to replicate the issue on our developer build in the same phone.
Also, this issue doesn't happen for every wallet. For example for Trust Wallet/Metamask I don't see this issue but for Rainbow/OKX it happens every time.
okey, it's really weird. I cannot reproduce on our sample apps from Testflight. Does it also happen on Android? Which version of react native are you using?
We are using RN 0.72.13. (Unfortunately I am not able to test on Android since I don't have a test device currently, but I will try to test tomorrow and let you know)
I am not able to reproduce this issue on Android (at least for Rainbow wallet case).
@ozgurrgul could you create a minimal reproducible example? So i can try to reproduce it locally.
Can you also add a log here? That code should be executed once, but it seems it's entering in a loop 🤔
hey @ozgurrgul 👋 can you provide a minimal reproducible example?
HI @ignaciosantise, sorry I was AFK due to to personal reasons.
could you create a minimal reproducible example? So i can try to reproduce it locally. I have tried to create a reproducible example and I wasn't able to repro the issue
Can you also add a log here?
I might be able to, but it's just we build our app on CI, so I will need to build locally which I don't have access to signing certificates, but I will give it a try. Since this issue is only happening on our prod build it's hard to debug.
Apart from that there is another issue that is preventing me to debug above.
We noticed that, recently when a user selects Trust wallet or any other wallet from the list, the wallet doesn't open to initiate a connection. Or when you open the wallet manually, it doesn't have any indication of WC connection too, so it gets stuck on ConnectingView. Try again button doesn't work as well.
I put a log here since I am able to repro locally:
So it seems await ConnectionController.state.wcPromise; waits indefinitely? and console.log("initializeConnection 3") doesn't get called into logs hence it doesn't continue to execute in the codeblock.
Is it possible to check this too? If you want, I can also create separate bug ticket.
"wagmi": "2.12.11",
"@walletconnect/react-native-compat": "2.17.1",
"@reown/appkit-wagmi-react-native": "1.0.2",
Video:
https://github.com/user-attachments/assets/2c3073c7-61af-491c-b7c7-45e94f9a0346
import { WagmiProvider } from 'wagmi';
import { mainnet } from '@wagmi/core/chains';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { createAppKit, defaultWagmiConfig, AppKit, AppKitButton } from '@reown/appkit-wagmi-react-native';
import { ReactNode } from 'react';
import { WALLET_CONNECT_PROJECT_ID } from '~/shared/environment';
import { WALLET_CONNECT_METADATA } from '~/store/addressBook/web3/AddressBookWeb3Constants';
const queryClient = new QueryClient();
const chains = [mainnet] as const;
const wagmiConfig = defaultWagmiConfig({
chains,
projectId: WALLET_CONNECT_PROJECT_ID,
metadata: WALLET_CONNECT_METADATA
});
createAppKit({
projectId: WALLET_CONNECT_PROJECT_ID,
wagmiConfig,
enableAnalytics: false
});
export const WalletConnectProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
return (
<WagmiProvider config={wagmiConfig}>
<QueryClientProvider client={queryClient}>
{children}
<AppKit />
<AppKitButton />
</QueryClientProvider>
</WagmiProvider>
);
};
hey @ozgurrgul 👋 sorry for the delay. Can you check if the QR code is generated? Open the modal -> All Wallets -> QR Code button at top right. Because i think you have an issue when trying to generate the connection uri
Some questions:
- Does
WALLET_CONNECT_PROJECT_IDcontain the project id? can you check that is not null? - Did you add any bundle_id in your Cloud dashboard?
Does WALLET_CONNECT_PROJECT_ID contain the project id? can you check that is not null?
It contains the correct project id (otherwise, WC doesn't show any wallets).
Did you add any bundle_id in your Cloud dashboard?
Yes, we have 3 bundle ids added in the Reown dashboard (for prod, staging, dev).
@ozgurrgul if you go to the QR view, does the code load?
@ignaciosantise It's hanging on loading/blinking state and QR code doesn't load
@ozgurrgul okey, then the issue is when trying to connect to the socket.
- Do you see any error related to sockets?
- Are you using a VPN? if so, can you check turning it off?
- Can you create a new project id and test? (without setting bundle ids)
-
No I don't see any socket issues (at least not visible in console or screen)
-
No VPN
-
Oh wow It actually works with a brand new project id! what could be the issue here?
- Trustwallet opens (buttons working)
okey good, it might be related to the bundleIds validation. Can you go to your original Cloud project and add the bundleIds in the allowed domains list?
Adding bundle ids to domain list like this? Yes it worked for the original project
@ozgurrgul Amazing! The Cloud team is already aware of this issue, i'll ping them again. But this workaround will make your project work 🤝
Guess we can close the issue?
Guess we can close the issue?
Unfortunately we can't yet, it seems.
So there are 2 different issues:
- Excessive amount of redirections to
TrustWalletetc (the original issue) - When a user selects
TrustWalletetc from the list, the app doesn't respond
The above domain workaround only fixed second item (and the original issue is now visible and still persists). The fix also introduces another issue for our prod builds, which walletConnect list is empty:
So, to summary, when we add the domain from dashboard, the the issue:
- We can click on the
TrustWalletor any other wallet and it works - I was able to interact with
TrustWalletand it still tried to open it too many times
Now:w
- After the dashboard fix, wallet list is empty in our prod build or local development which there is no wallet to click. There was initially wallets visible, but now I can't see any wallet item anymore
Relevant log:
@ozgurrgul the wallet list should be solved now, we had an issue yesterday -> https://status.reown.com/incidents/n059gtnp0jvs
I was able to interact with TrustWallet and it still tried to open it too many times
So this issue keeps happening?
Ah I see, that timing of the incident was very coincident.
So this issue keeps happening?
I checked our build and the issue seem to be disappeared. Thanks for all the help!
Amazing 🎉 I'm closing the issue then 🤝