> ## Documentation Index
> Fetch the complete documentation index at: https://www.dynamic.xyz/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Sign BTC Messages

> Learn how to sign messages using Dynamic's Node SDK for Bitcoin

## Overview

This guide shows you how to sign messages with your Bitcoin wallet. Message signing uses the **BIP-322** standard, which provides a unified way to sign messages across all Bitcoin address types. The signature is returned as a **base64** string.

## Prerequisites

* [Created a Bitcoin wallet](/node/btc/create-wallet)

## Basic Message Signing

```typescript theme={"system"}
import { authenticatedBtcClient } from './client';
import { BitcoinNetwork } from '@dynamic-labs-wallet/core';

const btcClient = await authenticatedBtcClient();

const signature = await btcClient.signMessage({
  message: 'Hello, Bitcoin!',
  walletMetadata,
  network: BitcoinNetwork.MAINNET,
});

console.log('Message signed (base64):', signature);
```

## Simple Message Signing

Whether you need to provide `externalServerKeyShares` depends on how you created your wallet:

### With Automatic Backup (Recommended)

If you created your wallet with `backUpToDynamic: true`, you don't need to provide external key shares:

```typescript theme={"system"}
import { BitcoinNetwork } from '@dynamic-labs-wallet/core';

// Simple signing - no externalServerKeyShares needed
const signature = await btcClient.signMessage({
  message: 'Hello, Bitcoin!',
  walletMetadata,
  network: BitcoinNetwork.MAINNET,
});

console.log('Message signed (base64):', signature);
```

### With Manual Backup

If you created your wallet with `backUpToDynamic: false`, you must provide external key shares:

```typescript theme={"system"}
// First, retrieve your stored key shares
const keyShares = await retrieveStoredKeyShares('bc1q...your-wallet-address');

// Must provide externalServerKeyShares
const signature = await btcClient.signMessage({
  message: 'Hello, Bitcoin!',
  walletMetadata,
  network: BitcoinNetwork.MAINNET,
  externalServerKeyShares: keyShares, // Required for manual backup!
  password: 'your-password', // Only if wallet was created with password
});

console.log('Message signed (base64):', signature);
```

**Password Handling Notes:**

* If your wallet was created **without a password**, omit the `password` parameter
* If your wallet was created **with a password**, you must provide it for all operations
* The password parameter is always optional in the API, but required if the wallet is password-protected

## BIP-322 Message Signing

The SDK automatically uses BIP-322 for message signing, which works with both Native SegWit and Taproot addresses:

### Native SegWit (P2WPKH)

```typescript theme={"system"}
// Native SegWit wallet — walletMetadata.addressType is 'native_segwit'
const signature = await btcClient.signMessage({
  message: 'Verify my ownership',
  walletMetadata,
  network: BitcoinNetwork.MAINNET,
});
// Returns BIP-322 signature in base64 format
```

### Taproot (P2TR)

```typescript theme={"system"}
// Taproot wallet — walletMetadata.addressType is 'taproot'
const signature = await btcClient.signMessage({
  message: 'Verify my ownership',
  walletMetadata,
  network: BitcoinNetwork.MAINNET,
});
// Returns BIP-322 signature with Schnorr (BIP-340) in base64 format
```

## Common Use Cases

### Authentication

```typescript theme={"system"}
const nonce = Date.now().toString();
const message = `Sign this message to authenticate: ${nonce}`;
const signature = await btcClient.signMessage({
  message,
  walletMetadata,
  network: BitcoinNetwork.MAINNET,
});
// signature is a BIP-322 encoded signature in base64
```

### Data Integrity

```typescript theme={"system"}
const data = { userId: 123, action: 'transfer', amount: '100000' };
const message = JSON.stringify(data);
const signature = await btcClient.signMessage({
  message,
  walletMetadata,
  network: BitcoinNetwork.MAINNET,
});
```

### Proof of Ownership

```typescript theme={"system"}
const proofMessage = `I own this Bitcoin address: ${walletAddress}`;
const signature = await btcClient.signMessage({
  message: proofMessage,
  accountAddress: walletAddress,
  network: BitcoinNetwork.MAINNET,
});
```

## Understanding BIP-322

BIP-322 (Generic Signed Message Format) provides a standardized way to sign and verify messages for all Bitcoin address types:

* **Native SegWit (P2WPKH)**: Uses ECDSA signatures
* **Taproot (P2TR)**: Uses Schnorr signatures (BIP-340)

The signature format encodes the signed message in a way that can be verified by any BIP-322 compatible verifier.

## Error Handling

```typescript theme={"system"}
try {
  const signature = await btcClient.signMessage({
    message: 'Test message',
    accountAddress: walletAddress,
    network: BitcoinNetwork.MAINNET,
  });
  console.log('Signature:', signature);
} catch (error) {
  console.error('Message signing failed:', error.message);
}
```

## Next Steps

* [Sign Bitcoin transactions](/node/btc/sign-transactions)
