Skip to content

How to sign a message or typed data

Plain messages, explicit encodings, and EIP-712 typed data.

Updated View as Markdown

Signing needs a token carrying the sign scope. Both routes address a public key directly — you never walk account → wallet → address to sign.

Sign a message

curl -X POST "$API_URL/sign/message" \
  -H "Authorization: Bearer $TOKEN" \
  -H "content-type: application/json" \
  -d '{"address":"0xabc…","message":"hello from tee-docker"}'
{ "address": "0xabc…", "signature": "0x…" }

Choosing an encoding

Omit encoding and the address signs with its VM’s natural default. Name one explicitly when the verifier expects a particular scheme:

encoding Use when
personal_sign The verifier expects the EIP-191 personal-message prefix
raw You are signing pre-hashed or otherwise pre-framed bytes
ed25519 Signing with an ed25519 key

With an explicit encoding the response may also carry messageHash, so you can check what was actually signed:

{ "address": "0xabc…", "signature": "0x…", "messageHash": "0x…" }

Sign typed data (EIP-712)

curl -X POST "$API_URL/sign/typed-data" \
  -H "Authorization: Bearer $TOKEN" \
  -H "content-type: application/json" \
  -d '{
    "address": "0xabc…",
    "typedData": {
      "domain": { "name": "MyDapp", "version": "1", "chainId": 1, "verifyingContract": "0xdef…" },
      "types": { "Order": [ { "name": "maker", "type": "address" }, { "name": "amount", "type": "uint256" } ] },
      "primaryType": "Order",
      "message": { "maker": "0xabc…", "amount": "1000" }
    }
  }'

The response includes both intermediate hashes, so you can verify the domain binding independently:

{
  "address": "0xabc…",
  "signature": "0x…",
  "domainSeparator": "0x…",
  "structHash": "0x…"
}

chainId is never guessed

chainId is optional. When omitted, the signature is bound to the address’s own network, not to a default chain.

Typed-data signing is EVM-only. Calling it with a non-EVM address returns 422 with unsupported_for_kind.

Failures worth handling

Code Status What happened
scope_denied 403 Token lacks sign
account_not_found 404 No such address in this workspace
account_locked 423 The owning account is locked — its own password, an explicit lock, or a lapsed custody window. Unlock it
unsupported_for_kind 422 Typed data on a non-EVM address
invalid_body 400 Malformed request shape

An address that exists but belongs to another tenant returns account_not_found — identical to one that does not exist anywhere.

Navigation

Type to search…

↑↓ navigate↵ selectEsc close