Skip to main content

Usage

This section provides instructions on how to initialize the WalletKit client, approve sessions with supported namespaces, and respond to session requests, enabling easy integration of Web3 wallets with dapps through a simple and intuitive interface.

Cloud Configuration

Create a new project on Reown Cloud at https://cloud.reown.com and obtain a new project ID.

Don't have a project ID?

Head over to Reown Cloud and create a new project now!

Get startedcloud illustration

Initialization

Note

@walletconnect/react-native-compat must be installed and imported before any @reown/* dependencies for proper React Native polyfills.

import '@walletconnect/react-native-compat'
// Other imports

Create a new instance from Core and initialize it with your projectId. Next, create a WalletKit instance by calling init on WalletKit. Passing in the options object containing metadata about the app.

The pair function will help us pair between the dapp and wallet and will be used shortly.

import { Core } from '@walletconnect/core'
import { WalletKit } from '@reown/walletkit'

const core = new Core({
projectId: process.env.PROJECT_ID
})

const walletKit = await WalletKit.init({
core, // <- pass the shared `core` instance
metadata: {
name: 'Demo React Native Wallet',
description: 'Demo RN Wallet to interface with Dapps',
url: 'www.walletconnect.com',
icons: ['https://your_wallet_icon.png'],
redirect: {
native: 'yourwalletscheme://'
}
}
})

Session

A session is a connection between a dapp and a wallet. It is established when a user approves a session proposal from a dapp. A session is active until the user disconnects from the dapp or the session expires.

Namespace Builder

With WalletKit (and @walletconnect/utils) we've published a helper utility that greatly reduces the complexity of parsing the required and optional namespaces. It accepts as parameters a session proposal along with your user's chains/methods/events/accounts and returns ready-to-use namespaces object.

// util params
{
proposal: ProposalTypes.Struct; // the proposal received by `.on("session_proposal")`
supportedNamespaces: Record< // your Wallet's supported namespaces
string, // the supported namespace key e.g. eip155
{
chains: string[]; // your supported chains in CAIP-2 format e.g. ["eip155:1", "eip155:2", ...]
methods: string[]; // your supported methods e.g. ["personal_sign", "eth_sendTransaction"]
events: string[]; // your supported events e.g. ["chainChanged", "accountsChanged"]
accounts: string[] // your user's accounts in CAIP-10 format e.g. ["eip155:1:0x453d506b1543dcA64f57Ce6e7Bb048466e85e228"]
}
>;
};

Example usage

// import the builder util
import { WalletKit, WalletKitTypes } from '@reown/walletkit'
import { buildApprovedNamespaces, getSdkError } from '@walletconnect/utils'

async function onSessionProposal({ id, params }: WalletKitTypes.SessionProposal){
try{
// ------- namespaces builder util ------------ //
const approvedNamespaces = buildApprovedNamespaces({
proposal: params,
supportedNamespaces: {
eip155: {
chains: ['eip155:1', 'eip155:137'],
methods: ['eth_sendTransaction', 'personal_sign'],
events: ['accountsChanged', 'chainChanged'],
accounts: [
'eip155:1:0xab16a96d359ec26a11e2c2b3d8f8b8942d5bfcdb',
'eip155:137:0xab16a96d359ec26a11e2c2b3d8f8b8942d5bfcdb'
]
}
}
})
// ------- end namespaces builder util ------------ //

const session = await walletKit.approveSession({
id,
namespaces: approvedNamespaces
})
}catch(error){
// use the error.message to show toast/info-box letting the user know that the connection attempt was unsuccessful
....

await walletKit.rejectSession({
id: proposal.id,
reason: getSdkError("USER_REJECTED")
})
}
}


walletKit.on('session_proposal', onSessionProposal)

If your wallet supports multiple namespaces e.g. eip155,cosmos & near Your supportedNamespaces should look like the following example.

// ------- namespaces builder util ------------ //
const approvedNamespaces = buildApprovedNamespaces({
proposal: params,
supportedNamespaces: {
eip155: {...},
cosmos: {...},
near: {...}
},
});
// ------- end namespaces builder util ------------ //

Get Active Sessions

You can get the wallet active sessions using the getActiveSessions function.

const activeSessions = walletKit.getActiveSessions()

EVM methods & events

In @walletconnect/ethereum-provider, (our abstracted EVM SDK for apps) we support by default the following Ethereum methods and events:

{
//...
methods: [
"eth_accounts",
"eth_requestAccounts",
"eth_sendRawTransaction",
"eth_sign",
"eth_signTransaction",
"eth_signTypedData",
"eth_signTypedData_v3",
"eth_signTypedData_v4",
"eth_sendTransaction",
"personal_sign",
"wallet_switchEthereumChain",
"wallet_addEthereumChain",
"wallet_getPermissions",
"wallet_requestPermissions",
"wallet_registerOnboarding",
"wallet_watchAsset",
"wallet_scanQRCode",
"wallet_sendCalls",
"wallet_getCallsStatus",
"wallet_showCallsStatus",
"wallet_getCapabilities",
],
events: [
"chainChanged",
"accountsChanged",
"message",
"disconnect",
"connect",
]
}

Session Approval

In order to connect with a dapp, you will need to receive a WalletConnect URI (WCURI) and this will talk to our protocol to facilitate a pairing session. Therefore, you will need a test dapp in order to communicate with the wallet. We recommend testing with our React V2 Dapp as this is the most up-to-date development site.

In order to capture the WCURI, recommend having some sort of state management you will pass through a TextInput or QRcode instance.

The session_proposal event is emitted when a dapp initiates a new session with a user's wallet. The event will include a proposal object with information about the dapp and requested permissions. The wallet should display a prompt for the user to approve or reject the session. If approved, call approveSession and pass in the proposal.id and requested namespaces.

The pair method initiates a WalletConnect pairing process with a dapp using the given uri (QR code from the dapps). To learn more about pairing, checkout out the docs.

import { getSdkError } from '@walletconnect/utils'

// Approval: Using this listener for sessionProposal, you can accept the session
walletKit.on('session_proposal', async proposal => {
const session = await walletKit.approveSession({
id: proposal.id,
namespaces
})
})

// Call this after WCURI is received
await walletKit.pair({ wcuri })

Session Rejection

You can use the getSDKError function, which is available in the @walletconnect/utils for the rejection function library.

import { getSdkError } from '@walletconnect/utils'

// Reject: Using this listener for sessionProposal, you can reject the session
walletKit.on('session_proposal', async proposal => {
await walletKit.rejectSession({
id: proposal.id,
reason: getSdkError('USER_REJECTED_METHODS')
})
})

// Call this after WCURI is received
await walletKit.core.pairing.pair({ wcuri })

Responding to Session requests

session-request-example

The session_request event is triggered by a dapp when it needs the wallet to perform a specific action, such as signing a transaction. The event contains a topic and a request object, which will vary depending on the action requested.

To respond to the request, the wallet can access the topic and request object by destructuring them from the event payload. To see a list of possible request and response objects, refer to the relevant JSON-RPC Methods for Ethereum, Solana, Cosmos, or Stellar.

As an example, if the dapp requests a personal_sign method, the wallet can extract the params array from the request object. The first item in the array is the hex version of the message to be signed, which can be converted to UTF-8 and assigned to a message variable. The second item in params is the user's wallet address.

To sign the message, the wallet can use the wallet.signMessage method and pass in the message. The signed message, along with the id from the event payload, can then be used to create a response object, which can be passed into respondSessionRequest.

The wallet then signs the message. signedMessage, along with the id from the event payload, can then be used to create a response object, which can be passed into respondSessionRequest.

walletKit.on('session_request', async event => {
const { topic, params, id } = event
const { request } = params
const requestParamsMessage = request.params[0]

// convert `requestParamsMessage` by using a method like hexToUtf8
const message = hexToUtf8(requestParamsMessage)

// sign the message
const signedMessage = await wallet.signMessage(message)

const response = { id, result: signedMessage, jsonrpc: '2.0' }

await walletKit.respondSessionRequest({ topic, response })
})

To reject a session request, the response should be similar to this.

const response = {
id,
jsonrpc: '2.0',
error: {
code: 5000,
message: 'User rejected.'
}
}

Updating a Session

The session_update event is emitted from the wallet when the session is updated by calling updateSession. To update a session, pass in the topic and the new namespace.

await walletKit.updateSession({ topic, namespaces: newNs })

Extending a Session

To extend the session, call the extendSession method and pass in the new topic. The session_update event will be emitted from the wallet.

await walletKit.extendSession({ topic })

Session Disconnect

When either the dapp or the wallet disconnects from a session, a session_delete event will be emitted. It's important to subscribe to this event so you could keep your state up-to-date.

To initiate a session disconnect, call the disconnectSession method and pass in the topic and reason. You can use the getSDKError utility function, which is available in the @walletconnect/utils library.

await walletKit.disconnectSession({
topic,
reason: getSdkError('USER_DISCONNECTED')
})

Emitting Session Events

To emit session events, call the emitSessionEvent and pass in the params. If you wish to switch to chain/account that is not approved (missing from session.namespaces) you will have to update the session first. In the following example, the wallet will emit session_event that will instruct the dapp to switch the active accounts.

await walletKit.emitSessionEvent({
topic,
event: {
name: 'accountsChanged',
data: ['0xab16a96D359eC26a11e2C2b3d8f8B8942d5Bfcdb']
},
chainId: 'eip155:1'
})

In the following example, the wallet will emit session_event when the wallet switches chains.

await walletKit.emitSessionEvent({
topic,
event: {
name: 'chainChanged',
data: 1
},
chainId: 'eip155:1'
})