Verify a Spoolis outcome receipt
import { verifyOutcomeReceipt } from '@spoolis/receipt-verifier'
const result = await verifyOutcomeReceipt(receipt, { trustSet })
console.log(result.valid)
console.log(receipt.amounts.earned)
Install
npm install @spoolis/receipt-verifier
No Spoolis account is required to verify a receipt. The package has no runtime dependencies and uses WebCrypto in Node 20 or later, browsers, workers, and agent sandboxes.
Trust material
Spoolis publishes receipt trust material at https://spoolis.com/.well-known/spoolis-keys.json. Pin the receipt entries you accept and pass that array as trustSet for offline verification. fetchTrustSet(url) is an online convenience that fetches and returns all published receipt trust entries. Fetching at verification time is not required or preferred for a pinned deployment.
Offline verification and online status
Signature validity is offline and permanent when a verifier has the receipt and a pinned trust set. Corrected or revoked status is an online check through statusSource. Without a status source, verification includes the status_source_unavailable advisory. A receipt can be cryptographically valid yet superseded.
Reasons
unknown_schema | The receipt schema version is not supported. |
environment_mismatch | The receipt environment does not match the requested environment. |
invalid_evidence_root | The evidence root is not a lowercase SHA-256 digest. |
invalid_run_digest | The verification run digest is malformed. |
invalid_agreement_hash | The agreement hash is malformed. |
receipt_id_mismatch | The content-derived receipt ID does not match the payload. |
earned_amount_mismatch | Per-unit arithmetic does not equal the earned amount. |
aggregation_inconsistent | A recognized aggregation policy does not produce the stated result. |
corrected | The online status source marks this receipt corrected. |
revoked | The online status source marks this receipt revoked. |
untrusted_signing_key | No active or retiring trust entry matches the signing key. |
signing_key_id_mismatch | The trust entry public key does not hash to the signing key ID. |
invalid_signature | The Ed25519 signature does not verify. |
malformed_receipt | A required structure or value is malformed. |
Advisories
unknown_aggregation_policy | The verifier does not know how to recompute this policy. |
past_execute_by | The optional execution deadline has passed. This does not expire the receipt. |
status_source_unavailable | No corrected or revoked status source was supplied. |
key_retiring | The receipt uses a trusted key marked as retiring. |
Security model
A valid result proves that the receipt payload was signed by a key in the supplied trust set. It proves that the content-derived ID matches the signed content. It checks digest formats, recognized aggregation rules, and unit arithmetic. It also enforces the selected production or demo environment. Verification does not prove that referenced evidence is true or available. It does not resolve actor identities. It does not grant payment authority. It does not prove authorization, capture, settlement, or finality on any payment rail. Consumers must enforce their own authorization and consume-once rules before taking economic action. Pin trust material through a trusted channel and review key rotation policy. Use an online status source when corrected or revoked state matters.
Golden vectors
The conformance corpus is maintained at tests/fixtures/receipt-vectors/ in the Spoolis repository. The package test runs every declared vector against the standalone implementation.