Skip to main content

Overview

This guide shows you how to sign messages with your EVM wallet. Message signing is commonly used for authentication, nonce verification, and data integrity checks.

Prerequisites

Basic Message Signing

import { authenticatedEvmClient } from './client';

const evmClient = await authenticatedEvmClient();

const signature = await evmClient.signMessage({
  message: 'Hello, World!',
  accountAddress: '0xYourWalletAddress',
});

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

Simple Message Signing

Whether you need to provide externalServerKeyShares depends on how you created your wallet: If you created your wallet with backUpToClientShareService: true, you don’t need to provide external key shares:
// ✅ Simple signing - no externalServerKeyShares needed
const signature = await evmClient.signMessage({
  message: 'Hello, World!',
  accountAddress: '0xYourWalletAddress',
  password: 'your-password', // Only if wallet was created with password
});

console.log('Message signed:', 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('0xYourWalletAddress');

// ❌ Must provide externalServerKeyShares
const signature = await evmClient.signMessage({
  message: 'Hello, World!',
  accountAddress: '0xYourWalletAddress',
  externalServerKeyShares: keyShares, // Required for manual backup!
  password: 'your-password', // Only if wallet was created with password
});

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

Advanced: Providing External Key Shares

For advanced scenarios or manual backup, you can provide external server key shares:
// Example with actual key share structure
const signature = await evmClient.signMessage({
  message: 'Hello, World!',
  accountAddress: '0xYourWalletAddress',
  externalServerKeyShares: [
    {
      pubkey: {
        pubkey: {
          0: 43, 1: 36, 2: 191, 3: 69, 4: 124, 5: 68, 6: 247, 7: 127,
          8: 7, 9: 179, 10: 160, 11: 224, 12: 205, 13: 194, 14: 132, 15: 159,
          // ... continues for 64 bytes total
        }
      },
      secretShare: "020000009ca5a66e79a2ddf631838d5cc5ba6a0cedb15a372e4176e479e0e63abff8cc3d..."
    }
  ],
  password: 'your-password', // Only if wallet was created with password
});

console.log('Message signed:', 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

Common Use Cases

Authentication

const nonce = Date.now().toString();
const message = `Sign this message to authenticate: ${nonce}`;
const signature = await evmClient.signMessage({
  message,
  accountAddress: '0xYourWalletAddress',
});

Data Integrity

const data = { userId: 123, action: 'transfer', amount: '100' };
const message = JSON.stringify(data);
const signature = await evmClient.signMessage({
  message,
  accountAddress: '0xYourWalletAddress',
});

Next Steps

I