# Message Signing

Learn how to implement message signing in your Stacks application. Message signing allows users to cryptographically prove they control an address without making an on-chain transaction, enabling authentication, authorization, and verifiable statements.

## What you'll learn

* Connect to a user's wallet and request message signatures
* Sign both simple text messages and structured data
* Verify signatures to ensure authenticity

## Prerequisites

* Node.js installed on your machine
* A code editor like VS Code

## Installation

Install the required packages for message signing and verification.

```bash
npm install @stacks/connect @stacks/encryption
```

## Connect to wallet

Before signing messages, establish a connection to the user's wallet. The connection persists across page reloads.

```ts
import { connect, isConnected } from '@stacks/connect';

async function connectWallet() {
  if (!isConnected()) {
    const response = await connect();
    console.log('Connected addresses:', response.addresses);
  }
}
```

Call this function when your app loads or when the user clicks a connect button.

## Sign text messages

Request a signature for a simple text message using the `request` method.

```ts
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);

  return response;
}
```

The wallet will display the message to the user for approval before signing.

## Sign structured data

For more complex data, use structured message signing with Clarity values.

```ts
import { request } from '@stacks/connect';
import { Cl } from '@stacks/transactions';

async function signStructuredMessage() {
  const message = Cl.tuple({
    action: Cl.stringAscii('transfer'),
    amount: Cl.uint(1000),
    recipient: Cl.stringAscii('alice.btc')
  });

  const domain = Cl.tuple({
    name: Cl.stringAscii('My App'),
    version: Cl.stringAscii('1.0.0'),
    'chain-id': Cl.uint(1) // 1 for mainnet
  });

  const response = await request('stx_signStructuredMessage', {
    message,
    domain
  });

  return response;
}
```

Structured messages provide better type safety and are easier to parse on-chain.

## Verify signatures

Validate signatures to ensure they match the expected message and public key.

```ts
import { verifyMessageSignatureRsv } from '@stacks/encryption';

async function verifySignature(
  message: string,
  signature: string,
  publicKey: string
): Promise<boolean> {
  const isValid = verifyMessageSignatureRsv({
    message,
    signature,
    publicKey
  });

  if (isValid) {
    console.log('✓ Signature verified successfully');
  } else {
    console.log('✗ Invalid signature');
  }

  return isValid;
}
```

Always verify signatures before trusting the signed data.

## Complete verification flow

```ts
async function signAndVerify() {
  // Request signature
  const message = 'Authorize login at ' + new Date().toISOString();
  const signResponse = await request('stx_signMessage', { message });

  // Verify immediately
  const isValid = await verifySignature(
    message,
    signResponse.signature,
    signResponse.publicKey
  );

  if (isValid) {
    // Proceed with authenticated action
    console.log('Authentication successful');
  }
}
```

## Try it out

Create a simple authentication system using message signatures.

```ts
// Generate a unique challenge
function generateChallenge(): string {
  const nonce = Math.random().toString(36).substring(7);
  const timestamp = Date.now();
  return `Sign this message to authenticate:\nNonce: ${nonce}\nTime: ${timestamp}`;
}

// Complete auth flow
async function authenticate() {
  const challenge = generateChallenge();

  try {
    const response = await request('stx_signMessage', {
      message: challenge
    });

    const isValid = verifyMessageSignatureRsv({
      message: challenge,
      signature: response.signature,
      publicKey: response.publicKey
    });

    if (isValid) {
      // Store auth token or session
      localStorage.setItem('auth', JSON.stringify({
        publicKey: response.publicKey,
        timestamp: Date.now()
      }));

      return { success: true };
    }
  } catch (error) {
    console.error('Authentication failed:', error);
  }

  return { success: false };
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.stacks.co/stacks-connect/message-signing.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
