Signing provider for dApps: WalletConnect.
Documentation is available on docs.multiversx.com, while an integration example can be found here.
Note that we recommend using sdk-dapp instead of integrating the signing provider on your own.
You can check out the integration with sdk-dapp
in the Template dApp repository with a live example here.
sdk-wallet-connect-provider
is delivered via npm, therefore it can be installed as follows:
npm install @multiversx/sdk-wallet-connect-provider
In order to compile the library, run the following:
npm install
npm run compile
The WalletConnect 2.0 Signing Provider can use the WalletConnect Cloud Relay default address: wss://relay.walletconnect.com
, in order to be able to access the Cloud Relay you will need to generate a Project ID
The Project ID can be generated for free here: https://cloud.walletconnect.com/sign-in
The WalletConnect Project ID grants you access to the WalletConnect Cloud Relay that securely manages communication between the device and the dApp.
For this example we will use the WalletConnect 2.0 provider since 1.0 is deprecated
First, let's see a (simple) way to build a QR dialog using qrcode
(and bootstrap):
import QRCode from "qrcode";
async function openModal(connectorUri) {
const svg = await QRCode.toString(connectorUri, { type: "svg" });
// The referenced elements must be added to your page, in advance
$("#MyWalletConnectQRContainer").html(svg);
$("#MyWalletConnectModal").modal("show");
}
function closeModal() {
$("#MyWalletConnectModal").modal("hide");
}
In order to create an instance of the provider, do as follows:
import { WalletConnectV2Provider } from "@multiversx/sdk-wallet-connect-provider";
// Generate your own WalletConnect 2 ProjectId here:
// https://cloud.walletconnect.com/app
const projectId = "9b1a9564f91cb6...";
// The default WalletConnect V2 Cloud Relay
const relayUrl = "wss://relay.walletconnect.com";
// T for Testnet, D for Devnet and 1 for Mainnet
const chainId = "T";
const callbacks = {
onClientLogin: async function () {
// closeModal() is defined above
closeModal();
const address = await provider.getAddress();
console.log("Address:", address);
},
onClientLogout: async function () {
console.log("onClientLogout()");
},
onClientEvent: async function (event) {
console.log("onClientEvent()", event);
},
};
const provider = new WalletConnectProvider(
callbacks,
chainId,
relayUrl,
projectId
);
You can customize the Core WalletConnect functionality by passing
WalletConnectProvider
an optional 5th parameter:options
For examplemetadata
andstorage
for React Native or{ logger: 'debug' }
for a detailed under the hood logging
Before performing any operation, make sure to initialize the provider:
await provider.init();
Then, ask the user to login using xPortal on her phone:
const { uri, approval } = await provider.connect();
// connect will provide the uri required for the qr code display
// and an approval Promise that will return the connection session
// once the user confirms the login
// openModal() is defined above
openModal(uri);
// pass the approval Promise
await provider.login({ approval });
The login()
method supports the token
parameter (similar to other providers):
// A custom identity token (opaque to the signing provider)
const authToken = "aaaabbbbaaaabbbb";
await provider.login({ approval, token: authToken });
console.log("Address:", provider.address);
console.log("Token signature:", provider.signature);
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.
Once the user confirms the login, the onClientLogin()
callback (declared above) is executed.
In order to log out, do as follows:
await provider.logout();
Transactions can be signed as follows:
import { Transaction } from "@multiversx/sdk-core";
const firstTransaction = new Transaction({ ... });
const secondTransaction = new Transaction({ ... });
await provider.signTransactions([firstTransaction, secondTransaction]);
// "firstTransaction" and "secondTransaction" can now be broadcasted.
Alternatively, one can sign a single transaction using the method signTransaction()
.
Arbitrary messages can be signed as follows:
import { SignableMessage } from "@multiversx/sdk-core";
const message = new SignableMessage({
message: Buffer.from("hello"),
});
await provider.signMessage(message);
console.log(message.toJSON());
MultiversX Namespace: mvx
Reference: 1
for Mainnet
, T
for Testnet
, D
for Devnet
( same as the MultiversX chainID )
The MultiversX namespaces respect the CAIP Standards.
{
"requiredNamespaces": {
"mvx": {
"chains": ["mvx:D"],
"methods": [
"mvx_signTransaction",
"mvx_signTransactions",
"mvx_signMessage"
],
"events": []
}
}
}
If the wallet (or the user) does NOT approve the session, then it is rejected. Otherwise, the wallet responds with a slightly different namespace schema: Session Namespace.
{
"sessionNamespaces": {
"mvx": {
"chains": ["mvx:D"],
"methods": [
"mvx_signTransaction",
"mvx_signTransactions",
"mvx_signMessage"
],
"events": [],
"accounts": [
"mvx:D:erd1p47hljmqsetgzc4yqp700z6443r655zfkkg9lfkh0tx2wzyxl8sa5jdjq"
]
}
}
}
The default methods are mvx_signTransaction
, mvx_signTransactions
and mvx_signMessage
.
A detailed documentation for the default methods is available here.
Any additional methods must be passed in the .connect
step
const { uri, approval } = await provider.connect({
methods: ["mvx_signNativeAuthToken", "mvx_cancelAction"],
});
mvx_signLoginToken
- Included by default for now for compatibility reasons. Subject to change as it will be replaced by themvx_signNativeAuthToken
method soon.mvx_signNativeAuthToken
- Used while logging in with a nativeAuth token, this will offer a special UI based on that format.mvx_cancelAction
- The dApp can trigger asendCustomRequest
event that will cancel the current signing flow on the device.
The available MultiversX JSON-RPC Methods and the structure can be checked on WalletConnect's Specs and on MultiversX Docs.