Skip to content
ecdsa.com

Sign-In with Ethereum Verifier

A SIWE message is plain text a wallet signs with personal_sign. Paste it with its signature and, optionally, what your server expects: the verifier reports each format problem with its line, tells you who signed, and fails the sign-in for the reasons EIP-4361 lists — a message for another site, a replayed nonce, the wrong chain, an expired window.

The message and the signature are checked in this browser. Only when you press “Check on chain” are the address, the EIP-191 digest and the signature sent to a public RPC node of the message’s chain (named next to the button).

What your server expects (optional)

Fill in what the relying party knows; every field you fill becomes a check.

A sign-in is a signed text

Sign-In with Ethereum (EIP-4361) replaces a password with a signature. The site builds a short text, the wallet shows it and signs it with personal_sign (EIP-191), and the server checks the signature. Because the text is what the user reads, its format is fixed down to the line breaks:

  • the first line names the site: example.com wants you to sign in with your Ethereum account:, optionally with a scheme and a port;
  • the second line is the account, written with its EIP-55 mixed-case checksum;
  • an optional one-line statement, between empty lines;
  • then the fields, in this order: URI, Version (always 1), Chain ID, Nonce (at least eight letters or digits), Issued At, and optionally Expiration Time, Not Before, Request ID and a list of Resources.

Times are RFC 3339 date-times; the domain, the URI and the resources follow RFC 3986. The signed bytes are the text itself: a trailing newline, Windows line endings or a re-cased address make a different message and a different signature.

The verifier parses the message against the specification's grammar and reports every problem with its line — a field out of order, a short nonce, a date such as 31 February that does not exist, a statement with characters the grammar does not allow. Strict libraries such as spruceid's siwe reject a non-conforming message even when its signature is valid, so this is the first thing to fix.

What the server must check

A valid signature only proves that the account signed some sign-in. EIP-4361 lists what the relying party must check before it opens a session, and each check is a separate line in the verifier's report when you fill in what your server expects:

  • Domain — the message must name your site. A message for another domain is the signature of a phishing site that asked the user to "sign in" there, and must be rejected.
  • Request origin — wallets compare the domain with the page that asked for the signature: scheme, host and port. The verifier runs the same algorithm and, as the specification allows, only warns for local development addresses.
  • Nonce — it must be the one your server issued for this session, and only once. A different nonce means a replayed or foreign message.
  • Chain, address and URI — the ones your application expects.
  • Validity window — Expiration Time must not have passed and Not Before must have; an Issued At in the future means a wrong clock or a message prepared in advance. A message without an expiration stays usable until the server retires its nonce.

When the signature does not match, the verifier tries the usual accidents — a copy with different line endings, an added or removed trailing newline — and names the one that reproduces the signer. The Ethereum signature verifier covers personal_sign messages in general.

Smart-contract wallets

A Safe, an Argent wallet or a passkey account cannot sign with ecrecover. Its sign-in is checked by the wallet contract through ERC-1271, or, for a wallet that is not deployed yet, through the deployless validator of ERC-6492. EIP-4361 requires that check to run on the chain the message names, so the verifier asks a public node of that chain and refuses an endpoint that serves another one. The report says which method decided.

What stays in your browser

Parsing, hashing, recovery and every relying-party check run in this page. Seed phrases and private keys are refused before anything is read. The only request the page can make is the smart-wallet check, when you press its button: it sends the address, the 32-byte EIP-191 digest and the signature — never the message — to a public RPC node of the message's chain, named next to the button.