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:
- 1Set up and install necessary packages.
- 2Connect to a user's wallet.
- 3Sign messages.
- 4Verify signatures.
Setup and installation
Using your preferred package manager, install the following packages:
$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!');}}