Skip to main content

Signing methods

Core supports the message-signing surface that dapps rely on for authentication, off-chain orders, and permits. Every call opens an approval screen that shows the user what they are signing.

personal_sign

The most common signature request — signs an arbitrary message, prefixed per EIP-191 so it can never double as a transaction:

// Hex-encode the message without Node's Buffer, which browsers lack:
const message = new TextEncoder().encode('Sign in to Example');
const hexMessage =
'0x' + [...message].map((b) => b.toString(16).padStart(2, '0')).join('');

const signature = await provider.request({
method: 'personal_sign',
params: [hexMessage, account],
});

Sign-In-with-Ethereum (EIP-4361) flows are personal_sign with a structured message body.

eth_signTypedData_v4

Signs structured data per EIP-712 — the standard behind permits, orders, and most modern signature schemes. Core renders the typed fields on the approval screen so users see the individual values, not a blob:

const signature = await provider.request({
method: 'eth_signTypedData_v4',
params: [
account,
JSON.stringify({
domain: { name: 'Example', version: '1', chainId: 43114 },
message: { contents: 'Hello from Core', from: account },
primaryType: 'Mail',
types: {
EIP712Domain: [
{ name: 'name', type: 'string' },
{ name: 'version', type: 'string' },
{ name: 'chainId', type: 'uint256' },
],
Mail: [
{ name: 'contents', type: 'string' },
{ name: 'from', type: 'address' },
],
},
}),
],
});

The typed-data guide has a complete worked example. Core also accepts the legacy eth_signTypedData, eth_signTypedData_v1, and eth_signTypedData_v3 variants; new code should use v4.

Avalanche message signing

avalanche_signMessage signs a message for X and P-Chain address schemes, where EVM signature formats do not apply. Params are positional: the message, optionally followed by a non-negative account index — [message] or [message, accountIndex]. Returns the signature.

Encryption

Two companion methods let dapps encrypt data that only the wallet owner can read:

  • eth_getEncryptionPublicKey — returns the account's encryption public key after user approval.
  • eth_decrypt — decrypts a payload produced for that key, again behind an approval screen.

Encrypt with a compatible library, for example @metamask/eth-sig-util's encrypt with the x25519-xsalsa20-poly1305 scheme.

What Core does not support

eth_sign — the legacy blind-signing method — is rejected by design. It asks users to sign opaque bytes that could encode anything, including a valid transaction. Use personal_sign or eth_signTypedData_v4 instead.