Using the MultiversX SDK for JavaScript (TypeScript), how to sign (and verify) an arbitrary message?

113 Views Asked by At

How to sign an arbitrary message (arbitrary sequence of bytes) using the MultiversX SDK for JavaScript / TypeScript?

Then, how to verify the signature?

1

There are 1 best solutions below

0
On

The code below is relying on the libraries @multiversx/sdk-wallet (v4) and @multiversx/sdk-core (v12).

Signing the message:

import { SignableMessage } from "@multiversx/sdk-core";
import { UserSigner } from "@multiversx/sdk-wallet";
import { promises } from "fs";

// First, load a wallet and create a UserSigner object:
const fileContent = await promises.readFile("alice.json", { encoding: "utf8" });
const walletObject = JSON.parse(fileContent);
const signer = UserSigner.fromWallet(walletObject, "password");

// Then, prepare and sign the message:
const message = new SignableMessage({ message: Buffer.from("hello") });
const serializedMessage = message.serializeForSigning();
const messageSignature = await signer.sign(serializedMessage);

// Output should be:
// Address of signer: erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th
// Signature: 561bc58f1dc6b10de208b2d2c22c9a474ea5e8cabb59c3d3ce06bbda21cc46454aa71a85d5a60442bd7784effa2e062fcb8fb421c521f898abf7f5ec165e5d0f
console.log("Address of signer:", signer.getAddress().bech32());
console.log("Signature:", messageSignature.toString("hex"));

The example above uses Alice's test wallet (generally used for examples on MultiversX). The address (public key) of this wallet is erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th.

Verifying the message signature:

import { Address, SignableMessage } from "@multiversx/sdk-core";
import { UserVerifier } from "@multiversx/sdk-wallet";

const verifier = UserVerifier.fromAddress(Address.fromBech32("erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th"));
const message = new SignableMessage({ message: Buffer.from("hello") });
const serializedMessage = message.serializeForSigning();
const messageSignature = Buffer.from("561bc58f1dc6b10de208b2d2c22c9a474ea5e8cabb59c3d3ce06bbda21cc46454aa71a85d5a60442bd7784effa2e062fcb8fb421c521f898abf7f5ec165e5d0f", "hex");

// Output should be:
// Is signature correct? true
// Is signature correct? false
console.log("Is signature correct?", verifier.verify(serializedMessage, messageSignature));
console.log("Is signature correct?", verifier.verify(serializedMessage, Buffer.from(Array(64).fill(0))));

Extra notes and references: