Skip to content
SIGNET
[ Receipt format ]

Ten fields, all of them computable.

There is no field for a prompt, a completion, a file or a token count, because Signet never receives any of those and refuses to sign a statement about data it has not seen. What is here is what a page can compute or a key can prove.

a receipt, decoded
{
  "v": 3,
  "kind": "notary",
  "fingerprint": "sha256:9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
  "bytes": 4,
  "issued_at": "2026-09-15T12:39:26Z",
  "issuer": "0x4ee49287668b4961b46d6d24e35c46fde45bea08",
  "chain_id": 4663,
  "prev": null,
  "label": "the four bytes test",
  "anchor": null
}
A field of hexadecimal characters fading in and out of the spectrum.64 hex characters, and nothing else
[ Fields ]

What each one is for.

vnumberFormat version. A verifier that does not know a version refuses the receipt instead of guessing at it.
kindseal | run | notaryWho signed and why. seal means a wallet, notary means the server key, run marks a head written for a whole session.
fingerprintstringsha256: followed by 64 lowercase hex characters, computed over the exact bytes that were sealed.
bytesnumberLength of those bytes. It costs nothing and it catches a whole class of mix-ups before anyone reads a hash.
issued_atstringRFC 3339, second precision, always UTC. The issuer's clock, with nothing vouching for it until an anchor exists.
issueraddressThe address that signed, lowercased. This is the value a verifier compares its recovery against.
chain_idnumberThe chain the issuer's key belongs to. 4663 here. A signature itself touches no chain.
prevstring | nullHead of the previous receipt in the same run, or null when this receipt starts one.
labelstringUp to 64 characters the issuer chose. Never interpreted, never trusted, shown as written.
anchorstring | nullTransaction hash of a published head. It is null on every receipt this site produces, and null means not published.
[ Encoding ]

One line, byte for byte.

Key order is fixed by the spec rather than by whatever order an object was built in, so two runs over equal data produce identical bytes. The canonical JSON is base64url encoded, and that string is the payload.

Never re-serialize before checking a signature. Parsing and stringifying a receipt changes whitespace, key order or unicode escaping, and the signature then fails over a difference that has nothing to do with the signer.

envelope
sgn3.<base64url of the canonical JSON>.<0x signature, 65 bytes>
what the wallet shows
Signet receipt v3
trysignet.xyz

fingerprint sha256:9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08
issued      2026-09-15T12:39:26Z
chain       4663
follows     nothing, this starts a run

Signing this proves the key above saw this fingerprint.
It says nothing about whether the work behind it was any good.

<payload>
[ Signing ]

Raw bytes, every time.

The signature is EIP-191 personal_sign, and the signed bytes are the UTF-8 of a readable message: the product name, the site, the fingerprint, the timestamp, the chain, and the payload on the last line. A wallet shows the signer that text. An earlier draft signed the bare base64 payload, which put an unreadable blob in front of the signer and taught the exact habit that gets people drained.

Some signers emit v as 0 or 1 rather than 27 or 28. Normalize before recovery, or you will report a valid signature as a forgery.

A smart-contract wallet produces nothing recoverable. When recovery disagrees with the issuer, ask the contract through EIP-1271 before calling it a failure, and label the result differently: that answer needs the network and cannot be repeated offline.

[ Runs ]

How a head is computed.

A run is a list of receipts and a single hash. Rewriting any receipt in the middle leaves every head after it wrong, and the verifier names the first one that stops matching.

chaining
head(0) = sha256("" + "\n" + payload_0)
head(n) = sha256(head(n-1) + "\n" + payload_n)

A chain proves internal order and nothing about wall-clock time. Without a published anchor, every timestamp in a run is the issuer's own claim. Signet publishes no anchors today, which is why every receipt carries anchor: null. See the trust page.