Skip to main content
Prerequisites: Create and initialize a Dynamic client and add the extension(s) for your chain(s): EVM and/or Solana. The SDK supports WalletConnect for EVM and Solana only. What is WalletConnect? Users connect a wallet from another device (e.g. mobile) by scanning a QR code or opening a deep link. Use it for cross-device or mobile-to-web flows. You build the UI yourself; there is no built-in picker.

1. Add the extension(s)

Add the WalletConnect extension for each chain you support, once at app setup. Client is optional when using a single Dynamic client.

2. Get the wallet list

Use getWalletConnectCatalog() for names, icons, and deep links (e.g. for a picker or “Open in MetaMask”). To look up one wallet by provider key after a wallet is connected, see When the user must act.
Wallet entry: name, chain (EVM/SOL/BTC), spriteUrl, primaryColor, deeplinks.native, deeplinks.universal, downloadLinks.androidUrl, downloadLinks.iosUrl.

3. Connect a wallet

Every connect flow returns { uri, approval }. You show the URI as a QR code (desktop) or pass it into a deep link (mobile via appendWalletConnectUriToDeepLink); the user approves in their wallet app; then approval() resolves with { walletAccounts }. Connect:
Connect and verify: For connect and verify, call connectAndVerifyWithWalletConnectEvm() or connectAndVerifyWithWalletConnectSolana() instead; same uri / approval pattern.
Solana has no single-step WalletConnect authenticate method (only EIP-155 chains support it), so connectAndVerifyWithWalletConnectSolana performs connect then verify in sequence internally.

4. When the user must act in their wallet

After a request (e.g. sign, switch network), the user approves in their wallet app. Listen for walletConnectUserActionRequested and either open the wallet app (mobile) or show a prompt (desktop). Use getWalletConnectCatalogWalletByWalletProviderKey({ walletProviderKey }) to get the wallet’s deep link when you have a connected wallet or the event’s walletProviderKey.

5. Account and network changes

Use wallet provider events with onWalletProviderEvent:

6. Full flow example

End-to-end: setup, connect (QR on desktop, deep link on mobile), handle user actions, listen to events.

7. Error handling

Use instanceof with the exported error classes. The following errors can be thrown by the connect functions or by approval():
For recurring connection or signing issues, see Troubleshooting and WalletConnect unsupported chain.
If the client or project is misconfigured, getSignClient can throw ValueMustBeDefinedError when: the app name (display name) is not set in the dashboard, or the WalletConnect project ID is not set in the dashboard.

React

The core WalletConnect functions are identical in React. The main differences are:
  1. Extensions — add them in your dynamicClient.ts module alongside initializeClient, not inside a component.
  2. QR code display — store the uri in state and render it in a component.
  3. walletConnectUserActionRequested — register the listener once in a top-level useEffect.

React Native

The core WalletConnect functions are identical on React Native. The differences are how you send the user to their wallet app and that there is no QR code — on mobile the user always deep links straight to the wallet app:
  1. Open the wallet — use Linking.openURL instead of window.open / window.location.href. The only difference between Expo and bare React Native is where Linking comes from: expo-linking on Expo, react-native on bare.
  2. No QR code — skip the qrcode rendering; mobile connects by deep link only.
  3. Deep links — set metadata.nativeLink and metadata.universalLink when creating the client so the wallet can redirect back to your app. See React Native Setup.

Install the WalletConnect dependency

WalletConnect needs a native shim that the base React Native Setup does not install. Add it before wiring up the code below.
Then import the shim as the first line of your polyfills.ts, before the crypto shims, so it loads before anything WalletConnect-related:
polyfills.ts
walletConnectUserActionRequested fires whenever the connected wallet needs the user to act (sign a message, switch network). The listener is where you decide how to route the user to their wallet — you are not required to deep link immediately.
Opening the wallet the instant the event fires (shown below) is the simplest option, but an abrupt app switch can confuse users. Many apps instead surface their own UI first — a modal or banner such as “Continue in your wallet to approve” with an Open wallet button — and only call Linking.openURL when the user taps it. See Prompt the user before opening the wallet.
The simplest approach registers the listener once at app setup and opens the wallet directly:

Prompt the user before opening the wallet

Instead of deep linking the moment walletConnectUserActionRequested fires, store the pending deep link and show your own UI first, then open the wallet when the user taps a button. The user knows the app is about to switch, and you control the messaging. Register the listener with useOnEvent and keep the pending deep link in component state. Only the Linking import differs between Expo and bare React Native.
Connection result: { approval: () => Promise<{ walletAccounts }>, uri: string } (same for EVM and Solana).

API reference

Related
Last modified on July 22, 2026