Skip to content

multiversx/mx-sdk-js-wallet-connect-provider

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

mx-sdk-js-wallet-connect-provider

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.

Distribution

npm

Installation

sdk-wallet-connect-provider is delivered via npm, therefore it can be installed as follows:

npm install @multiversx/sdk-wallet-connect-provider

Building the library

In order to compile the library, run the following:

npm install
npm run compile

Project ID

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.

Usage Examples

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 example metadata and storage 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();

Login and logout

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();

Signing transactions

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().

Signing messages

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());

Namespaces

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.

Example of a MultiversX WalletConnect Proposal Namespace

{
  "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.

Example of a MultiversX WalletConnect Session Namespace

{
  "sessionNamespaces": {
    "mvx": {
      "chains": ["mvx:D"],
      "methods": [
        "mvx_signTransaction",
        "mvx_signTransactions",
        "mvx_signMessage"
      ],
      "events": [],
      "accounts": [
        "mvx:D:erd1p47hljmqsetgzc4yqp700z6443r655zfkkg9lfkh0tx2wzyxl8sa5jdjq"
      ]
    }
  }
}

Optional Methods

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 the mvx_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 a sendCustomRequest event that will cancel the current signing flow on the device.

WalletConnect JSON-RPC Methods

The available MultiversX JSON-RPC Methods and the structure can be checked on WalletConnect's Specs and on MultiversX Docs.