Server-side ed25519 receipt verifier
emem_verify_receiptVerify a signed receipt envelope server-side: rebuilds the canonical preimage under the rule the receipt's own preimage_version names, runs ed25519 over the embedded key and signature, and returns {valid, reason, failure_detail, signature_valid, merkle_proof_valid, signer_pubkey_b32, preimage_blake3_hex}. A receipt is BYTE-FOR-BYTE OR NOTHING: v2 binds the inclusion proof, so any reshaping (a dropped field, a re-keyed one, a summary) invalidates the signature by design. For when the in-browser /verify path is unavailable, or for a server-side audit of a third party's receipt.
When to use: Pass the receipt EXACTLY as the read primitive returned it, whole and unmodified. Two omissions produce a false forgery rather than a 400, and they are the only two worth memorising: dropping merkle_proof, and dropping preimage_version (absent deserialises to 0, which silently selects the v0 rule, so the proof still walks while the signature reads as invalid). Signature and pubkey may be byte arrays or sig_b32 / responder_pubkey_b32; no other spelling is tolerated. Reshaping a field this responder can check is reported as reason: receipt_reshaped_after_signing with the field named, never accepted. Optionally set pubkey_b32 to assert a specific signer. A bad signature is 200 with valid: false, never a 4xx. The example arguments are a real receipt this responder signed (key epoch 0) over one weather fact at Trafalgar Square: run it unchanged and valid is true; change any byte and it is not.
Example arguments: 1602 bytes, too long to inline in a listing. Call emem_tools with {"name": "emem_verify_receipt"} for it whole and runnable; it is not shortened here because a truncated example is not one.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| facts | No | The fact value(s) you intend to rely on. Each is content-addressed and checked for membership in the receipt's `fact_cids`, so a genuine receipt presented beside a tampered fact answers `valid:false` / `fact_mismatch`. Omit it and only the signature is checked, which a doctored fact survives. | |
| receipt | Yes | The signed receipt envelope, the object under `receipt` in any read primitive's result. Must carry primitive/served_at/request_id/cells/fact_cids and either `signature` byte[] + `responder_pubkey` byte[] or their b32 string forms. IF ALL YOU HOLD IS AN `emem:fact:` TOKEN, this is not the tool to call first: a token is not a receipt and passing one here is a shape error. Call `emem_memory_token_resolve` on the token, then pass THAT result's `receipt` object here. Resolving proves the token points at the bytes it claims; verifying proves this responder signed them. | |
| pubkey_b32 | No | Optional explicit responder pubkey (base32). When omitted, uses the receipt's embedded pubkey/responder fields. | |
| current_responder_epoch | No | The responder key epoch you currently trust, from `/v1/manifests`. Produces an advisory `key_epoch_advisory` comparison against the receipt's epoch; a mismatch is reported, never rejected. |