Skip to main content
Sign a message using Ethereum personal_sign (EIP-191) format
import { Secp256k1 } from '@tevm/voltaire/Secp256k1';
import { Keccak256 } from '@tevm/voltaire/Keccak256';
import { Hex } from '@tevm/voltaire/Hex';

// Create a private key (32 bytes)
const privateKey = Hex.toBytes('0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80');

// Message to sign
const message = 'Hello, Ethereum!';

// Personal sign format: "\x19Ethereum Signed Message:\n" + len(message) + message
const prefix = '\x19Ethereum Signed Message:\n';
const messageBytes = new TextEncoder().encode(message);
const prefixedMessage = new TextEncoder().encode(prefix + messageBytes.length + message);

// Hash the prefixed message
const messageHash = Keccak256.hash(prefixedMessage);

// Sign the hash
const signature = Secp256k1.sign(messageHash, privateKey);
console.log('Signature (r):', Hex(signature.r));
console.log('Signature (s):', Hex(signature.s));
console.log('Signature (v):', signature.v);
This is a fully executable example. View the complete source with test assertions at examples/signing/personal-sign.ts.