Skip to main content

Wallet Usage

Sign API establishes a session between a wallet and a dapp in order to expose a set of blockchain accounts that can sign transactions or messages using a secure remote JSON-RPC transport with methods and events. This library is compatible with NodeJS, browsers and React-Native applications (NodeJS modules require polyfills for React-Native).

info

For an example implementation, please refer to our react-wallet-v2 example.

Migrating from v1.x​

We recommend you install v1 and v2 together for maximum compatibility. If your wallet already uses @walletconnect/client@1.x.x, you should be able to add @walletconnect/sign-client@2.x.x without any issues.

If you experience dependency clashes or you require both @walletconnect/types@1.x.x and @walletconnect/types@2.x.x in parallel in your wallet's top-level dependencies, please refer to the legacy packages which were published explicitly for this purpose.

In the above scenario, you would replace @walletconnect/types@1.x.x with @walletconnect/legacy-types and then install @walletconnect/types@2.x.x.

For more information check our migration guide and the repository for legacy packages.

Integrating Auth​

We strongly encourage wallets to also integrate the Auth API so that dapps using only Auth can still participate in the same ecosystem.

Initializing the client​

Initialize client as a controller using your Project ID.

const signClient = await SignClient.init({
projectId: "<YOUR PROJECT ID>",
// optional parameters
relayUrl: "<YOUR RELAY URL>",
metadata: {
name: "Wallet name",
description: "A short description for your wallet",
url: "<YOUR WALLET'S URL>",
icons: ["<URL TO WALLET'S LOGO/ICON>"],
},
});

Setting up event listeners​

WalletConnect v2.0 emits events related to the current session. The listeners listed in the following code snippet represent typical events in a session's lifecycle that you can listen for to synchronise your application accordingly.

Example: when a session_delete event is emitted, it makes sense to change the UI from an active session state to an inactive/disconnected state.

1. Add listeners for desired SignClient events.

info

To listen to pairing-related events, please follow the guidance for Pairing API event listeners.

signClient.on("session_proposal", (event) => {
// Show session proposal data to the user i.e. in a modal with options to approve / reject it

interface Event {
id: number;
params: {
id: number;
expiry: number;
relays: Array<{
protocol: string;
data?: string;
}>;
proposer: {
publicKey: string;
metadata: {
name: string;
description: string;
url: string;
icons: string[];
};
};
requiredNamespaces: Record<
string,
{
chains: string[];
methods: string[];
events: string[];
}
>;
pairingTopic?: string;
};
}
});

signClient.on("session_event", (event) => {
// Handle session events, such as "chainChanged", "accountsChanged", etc.

interface Event {
id: number;
topic: string;
params: {
event: {
name: string;
data: any;
};
chainId: string;
};
}
});

signClient.on("session_request", (event) => {
// Handle session method requests, such as "eth_sign", "eth_sendTransaction", etc.

interface Event {
id: number;
topic: string;
params: {
request: {
method: string;
params: any;
};
chainId: string;
};
}
});

signClient.on("session_ping", (event) => {
// React to session ping event

interface Event {
id: number;
topic: string;
}
});

signClient.on("session_delete", (event) => {
// React to session delete event

interface Event {
id: number;
topic: string;
}
});

Pairing and session permissions​

URI​

The pairing proposal between a wallet and a dapp is made using an URI. In WalletConnect v2.0 the session and pairing are decoupled from each other. This means that a URI is shared to construct a pairing proposal, and only after settling the pairing the dapp can propose a session using that pairing. In simpler words, the dapp generates an URI that can be used by the wallet for pairing.

Namespaces​

The namespaces parameter is used to specify the namespaces and chains that are intended to be used in the session. The following is an example:

namespaces: {
eip155: {
accounts: ["eip155:1:0x0000000000..., eip155:2:0x0000000000..."],
methods: ["personal_sign", "eth_sendTransaction"],
events: ["accountsChanged"]
},
};

Pairing with uri​

To create a pairing proposal, simply pass the uri received from the dapp into the signClient.core.pairing.pair() function.

caution

As of 2.0.0 (stable), calling pairing-specific methods (such as signClient.pair()) directly on signClient will continue to work, but is considered deprecated and will be removed in a future major version.

It is recommended to instead call these methods directly via the Pairing API, e.g.: signClient.core.pairing.pair().

// This will trigger the `session_proposal` event
await signClient.core.pairing.pair({ uri });

// Approve session proposal, use id from session proposal event and respond with namespace(s) that satisfy dapps request and contain approved accounts
const { topic, acknowledged } = await signClient.approve({
id: 123,
namespaces: {
eip155: {
accounts: ["eip155:1:0x0000000000..."],
methods: ["personal_sign", "eth_sendTransaction"],
events: ["accountsChanged"],
},
},
});

// Optionally await acknowledgement from dapp
const session = await acknowledged();

// Or reject session proposal
await signClient.reject({
id: 123,
reason: {
code: 1,
message: "rejected",
},
});

Pairing with QR Codes​

To facilitate better user experience, it is possible to pair wallets with dapps by scanning QR codes. This can be implemented by using any QR code scanning library (example, react-qr-reader). After scanning the QR code, pass the obtained uri into the signClient.pair() function. A useful reference for implementing QR codes for pairing is the react wallet example.