Sign messages

Prompt users to sign a message to prove they control an address or authorize an in-app action.


With Stacks Connect, users can sign a cryptographic message to prove ownership of a particular address. This is helpful for a wide range of use cases. For example, you can use message signing to create token-gated features (a user signs a message to prove they control an address holding the corresponding token requirements) or to prove the user agreed to your terms of service.

In this guide, you will learn how to:

  1. 1Set up and install necessary packages.
  2. 2Connect to a user's wallet.
  3. 3Sign messages.
  4. 4Verify signatures.

Setup and installation

Using your preferred package manager, install the following packages:

Terminal
$
npm install @stacks/connect @stacks/encryption

Connect to a user's wallet

Before signing messages, users need to connect their wallet to your application. Use the connect function to initiate a wallet connection:

import { connect, isConnected } from '@stacks/connect';
async function connectWallet() {
if (!isConnected()) {
const response = await connect();
console.log('Connected with addresses:', response);
}
}

For more details on wallet connection, see the authentication guide.

Sign messages

To request a message signature, use the request method with stx_signMessage:

import { request } from '@stacks/connect';
async function signMessage() {
const message = 'Hello World';
const response = await request('stx_signMessage', {
message,
});
console.log('Signature:', response.signature);
console.log('Public key:', response.publicKey);
}

For structured messages, you can use stx_signStructuredMessage:

import { request } from '@stacks/connect';
import { Cl } from '@stacks/transactions';
async function signStructuredMessage() {
const message = Cl.tuple({
structured: Cl.stringAscii('message'),
num: Cl.uint(3)
});
const domain = Cl.tuple({
name: Cl.stringAscii('My App'),
version: Cl.stringAscii('1.0.0'),
'chain-id': Cl.uint(1)
});
const response = await request('stx_signStructuredMessage', {
message,
domain
});
console.log('Signature:', response.signature);
console.log('Public key:', response.publicKey);
}

Verify signatures

To verify a signature, use the verifyMessageSignatureRsv function from the @stacks/encryption package:

import { verifyMessageSignatureRsv } from '@stacks/encryption';
async function verifySignature() {
const message = 'Hello World';
const response = await request('stx_signMessage', {
message
});
const { signature, publicKey } = response;
const verified = verifyMessageSignatureRsv({
message,
signature,
publicKey
});
if (verified) {
console.log('Signature verified!');
}
}

Next steps