Universal Connector to use WalletConnect QR Code
Reown AppKit has launched a new package for easy use of WalletConnect QR.

code, arts and earth keeper
If you are planning to build a dApp that connects client wallets using WalletConnect QR in a chain-agnostic environment, the best way is to use our Universal Connector, which simplifies the integration process, provides flexibility across multiple networks, and ensures a consistent user experience.
In this guide, you will learn how to:
Use Universal Connector to connect a wallet using WalletConnect QR Code
Configure supported networks for your dApp
Manage session state for connected wallets

Prerequisites
A fundamental understanding of JavaScript and React.
Obtain a new project Id on Reown Dashboard at https://dashboard.reown.com
Final project
Download the full project to try it directly on your computer using Universal Connector.
https://github.com/reown-com/appkit-web-examples/tree/main/react/react-core-universal-connector
Also you can try the demo online : https://react-core-universal-connector.vercel.app/
Final project
In order to set up the project, you need to install the following packages:
pnpm add @reown/appkit @reown/appkit-universal-connector @reown/appkit-common
or
npm install @reown/appkit @reown/appkit-universal-connector @reown/appkit-common
Start building with Universal Connector
You can configure with the networks you want to support. For more information, please visit RPC Reference section from our docs. We recommend creating a config file to establish a singleton instance for the Universal Connector.
import type { AppKitNetwork } from '@reown/appkit/networks'
import type { CustomCaipNetwork } from '@reown/appkit-common'
import { UniversalConnector } from '@reown/appkit-universal-connector'
// Get projectId from https://dashboard.reown.com
export const projectId = import.meta.env.VITE_PROJECT_ID || "b56e18d47c72ab683b10814fe9495694" // this is a public projectId only to use on localhost
if (!projectId) {
throw new Error('Project ID is not defined')
}
// Example: configure Sui mainnet
const suiMainnet: CustomCaipNetwork<'sui'> = {
id: 784,
chainNamespace: 'sui' as const,
caipNetworkId: 'sui:mainnet',
name: 'Sui',
nativeCurrency: { name: 'SUI', symbol: 'SUI', decimals: 9 },
rpcUrls: { default: { http: ['https://fullnode.mainnet.sui.io:443'] } }
}
export async function getUniversalConnector() {
const universalConnector = await UniversalConnector.init({
projectId,
metadata: {
name: 'Universal Connector',
description: 'Universal Connector',
url: 'https://appkit.reown.com',
icons: ['https://appkit.reown.com/icon.png']
},
networks: [
{
methods: ['sui_signPersonalMessage'],
chains: [suiMainnet as CustomCaipNetwork],
events: [],
namespace: 'sui'
}
]
})
return universalConnector
}
As you can see, we are importing the UniversalConnector class from the @reown/appkit-universal-connector package. Then you can use the projectId that you can get from the Reown Dashboard.
After that you can configure the networks you want to support. The method init receives the projectId, the metadata and the networks you want to support.
In the App.tsx file you can add :
import { useState, useEffect } from 'react'
import { getUniversalConnector } from './config' // previous config file
import { UniversalConnector } from '@reown/appkit-universal-connector'
export function App() {
const [universalConnector, setUniversalConnector] = useState<UniversalConnector>()
const [session, setSession] = useState<any>()
// Initialize the Universal Connector on component mount
useEffect(() => {
getUniversalConnector().then(setUniversalConnector)
}, [])
// Set the session state in case it changes
useEffect(() => {
setSession(universalConnector?.provider.session)
}, [universalConnector?.provider.session])
This ensures the Universal Connector is initialized when the component mounts. The session state updates whenever the connected wallet session changes. With this setup, you’re now ready to build wallet connections in a chain-agnostic way using WalletConnect QR codes.
Connect a Wallet
The following function initializes the connection and stores the session:
const handleConnect = async () => {
if (!universalConnector) {
return
}
const { session: providerSession } = await universalConnector.connect();
setSession(providerSession);
};
Once the wallet is connected, the session information (such as accounts and namespaces) will be available in your app. You can then use this session to perform actions like signing messages or sending transactions.
Sign a Message
Once your wallet is connected, you can also use the Universal Connector to sign messages. This is useful for authentication or verifying ownership of an address.
Here’s an example of how to sign a personal message on Sui:
// Function to sign a message on Sui
const handleSignSUIMsg = async () => {
if (!universalConnector) {
return
}
const message = "Hello Reown AppKit!" // message to sign
try {
const account = session?.namespaces['sui']?.accounts[0]
if (!account) {
throw new Error('No account found')
}
const result = await universalConnector.request(
{
method: 'sui_signPersonalMessage',
params: [message]
},
'sui:mainnet'
)
// eslint-disable-next-line no-console
console.log('>> Sui Sign Message result', result)
} catch (error) {
// eslint-disable-next-line no-console
console.error('>> Sui Sign Message error', error)
}
}
You can trigger this function with a simple button:
<button onClick={handleSignSUIMsg}>
Sign Message
</button>
This will prompt the connected wallet to sign the message “Hello Reown AppKit!” and log the result in the console.
Disconnect a Wallet
It’s important to give users the option to disconnect their wallet from your dApp. This clears the active session and ensures the wallet is no longer linked until the user chooses to reconnect.
Here’s a simple function to handle disconnection:
const handleDisconnect = async () => {
if (!universalConnector) {
return
}
await universalConnector.disconnect()
setSession(null)
}
When called, this will terminate the session and reset the state in your app. You can bind it to a “Disconnect” button in your UI to make it accessible to users.



