Documentation Index
Fetch the complete documentation index at: https://docs.dynamic.xyz/docs/llms.txt
Use this file to discover all available pages before exploring further.
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
Basic Message Signing
import { authenticatedBtcClient } from './client';
import { BitcoinNetwork } from '@dynamic-labs-wallet/core';
const btcClient = await authenticatedBtcClient();
const signature = await btcClient.signMessage({
message: 'Hello, Bitcoin!',
accountAddress: 'bc1q...your-wallet-address',
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 backUpToClientShareService: true, you don’t need to provide external key shares:
import { BitcoinNetwork } from '@dynamic-labs-wallet/core';
// Simple signing - no externalServerKeyShares needed
const signature = await btcClient.signMessage({
message: 'Hello, Bitcoin!',
accountAddress: 'bc1q...your-wallet-address',
network: BitcoinNetwork.MAINNET,
});
console.log('Message signed (base64):', signature);
With Manual Backup
If you created your wallet with backUpToClientShareService: false, you must provide external key shares:
// 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!',
accountAddress: 'bc1q...your-wallet-address',
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)
// Native SegWit address (bc1q...)
const signature = await btcClient.signMessage({
message: 'Verify my ownership',
accountAddress: 'bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh',
network: BitcoinNetwork.MAINNET,
});
// Returns BIP-322 signature in base64 format
Taproot (P2TR)
// Taproot address (bc1p...)
const signature = await btcClient.signMessage({
message: 'Verify my ownership',
accountAddress: 'bc1p5d7rjq7g6rdk2yhzks9smlaqtedr4dekq08ge8ztwac72sfr9rusxg3297',
network: BitcoinNetwork.MAINNET,
});
// Returns BIP-322 signature with Schnorr (BIP-340) in base64 format
Common Use Cases
Authentication
const nonce = Date.now().toString();
const message = `Sign this message to authenticate: ${nonce}`;
const signature = await btcClient.signMessage({
message,
accountAddress: 'bc1q...your-wallet-address',
network: BitcoinNetwork.MAINNET,
});
// signature is a BIP-322 encoded signature in base64
Data Integrity
const data = { userId: 123, action: 'transfer', amount: '100000' };
const message = JSON.stringify(data);
const signature = await btcClient.signMessage({
message,
accountAddress: 'bc1q...your-wallet-address',
network: BitcoinNetwork.MAINNET,
});
Proof of Ownership
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
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