{"_id":"@axiru/x402-receipt-verifier","_rev":"2-a26e796976792f7d363bb3c9fcab7eb0","name":"@axiru/x402-receipt-verifier","dist-tags":{"latest":"0.1.1"},"versions":{"0.1.0":{"name":"@axiru/x402-receipt-verifier","version":"0.1.0","keywords":["x402","receipts","offer-receipt","jws","eip-712","did-web","agentic-payments","evidence","verification","axiru"],"author":{"name":"Axiru"},"license":"Apache-2.0","_id":"@axiru/x402-receipt-verifier@0.1.0","maintainers":[{"name":"axiru","email":"marcos@axiru.com"}],"homepage":"https://github.com/AxiruAI/axiru-oss/tree/main/packages/x402-receipt-verifier#readme","bugs":{"url":"https://github.com/AxiruAI/axiru-oss/issues"},"dist":{"shasum":"e1ff6a277c239468ec972ca6bf5b179d39537efc","tarball":"https://registry.npmjs.org/@axiru/x402-receipt-verifier/-/x402-receipt-verifier-0.1.0.tgz","fileCount":18,"integrity":"sha512-u6r2nBJIdpYaZqUiQWbA+UwjGZSI4e5MZId5b2SSA3yiLZZ7wo+6/jN6v5LZS3FN78n0010TZUMw8ddwGcyQmw==","signatures":[{"sig":"MEUCIQDVbJjbn1TJrVdrQNqxHMKom9+/oT+ogcjji3Gk4P1JXAIgBcw+voBKN8FuPQOQ0koLKHPPSSCF0e/bHjmmIZ/i2GE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":59375},"main":"dist/x402-receipt-verifier/src/index.js","type":"module","types":"dist/x402-receipt-verifier/src/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/x402-receipt-verifier/src/index.d.ts","import":"./dist/x402-receipt-verifier/src/index.js"}},"gitHead":"9601ad2c5bda7c27bbf866b78f390fc0f3ee8ee7","private":false,"scripts":{"lint":"tsc --noEmit","test":"pnpm --filter @axiru/spec build && tsc -p tsconfig.json && node dist/x402-receipt-verifier/src/jws-verifier.test.js && node dist/x402-receipt-verifier/src/eip712-verifier.test.js && node dist/x402-receipt-verifier/src/verify-evidence.test.js","build":"tsc -p tsconfig.json","prepack":"pnpm run build","typecheck":"tsc --noEmit"},"_npmUser":{"name":"axiru","email":"marcos@axiru.com"},"repository":{"url":"git+https://github.com/AxiruAI/axiru-oss.git","type":"git","directory":"packages/x402-receipt-verifier"},"_npmVersion":"11.8.0","description":"Verify x402 SignedOffers and SignedReceipts (JWS and EIP-712) independently of the party that issued them. Zero runtime dependencies beyond the Axiru spec types.","directories":{},"_nodeVersion":"24.13.1","dependencies":{"@axiru/spec":"workspace:*"},"publishConfig":{"access":"public","provenance":true},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.3","@types/node":"^25.9.1"},"_npmOperationalInternal":{"tmp":"tmp/x402-receipt-verifier_0.1.0_1785886223739_0.4728417728031664","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@axiru/x402-receipt-verifier","version":"0.1.1","description":"Verify x402 SignedOffers and SignedReceipts (JWS and EIP-712) independently of the party that issued them. Zero runtime dependencies beyond the Axiru spec types.","license":"Apache-2.0","private":false,"author":{"name":"Axiru"},"homepage":"https://github.com/AxiruAI/axiru-oss/tree/main/packages/x402-receipt-verifier#readme","repository":{"type":"git","url":"git+https://github.com/AxiruAI/axiru-oss.git","directory":"packages/x402-receipt-verifier"},"bugs":{"url":"https://github.com/AxiruAI/axiru-oss/issues"},"keywords":["x402","receipts","offer-receipt","jws","eip-712","did-web","agentic-payments","evidence","verification","axiru"],"type":"module","main":"dist/x402-receipt-verifier/src/index.js","types":"dist/x402-receipt-verifier/src/index.d.ts","exports":{".":{"types":"./dist/x402-receipt-verifier/src/index.d.ts","import":"./dist/x402-receipt-verifier/src/index.js"}},"engines":{"node":">=18"},"scripts":{"build":"tsc -p tsconfig.json","lint":"tsc --noEmit","typecheck":"tsc --noEmit","test":"pnpm --filter @axiru/spec build && tsc -p tsconfig.json && node dist/x402-receipt-verifier/src/jws-verifier.test.js && node dist/x402-receipt-verifier/src/eip712-verifier.test.js && node dist/x402-receipt-verifier/src/verify-evidence.test.js","prepack":"pnpm run build"},"publishConfig":{"access":"public","provenance":true},"dependencies":{"@axiru/spec":"^0.1.0"},"devDependencies":{"@types/node":"^25.9.1","typescript":"^5.6.3"},"gitHead":"a231ab3f691b1d3e0b18ff6f22a5d14ecaaf5cf3","_id":"@axiru/x402-receipt-verifier@0.1.1","_nodeVersion":"24.13.1","_npmVersion":"11.8.0","dist":{"integrity":"sha512-S8sy2oPtdh5BLKihTV7bL0hnaREjfi9TmWXQ9WH5aHV8ciUn07Pwvrv5dDfceU+tlNuPkxqX2scNr/GDNg0gDw==","shasum":"7871a941b854a2837d1dafd6818b2d78f7b7fc9a","tarball":"https://registry.npmjs.org/@axiru/x402-receipt-verifier/-/x402-receipt-verifier-0.1.1.tgz","fileCount":18,"unpackedSize":59370,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCICFS4UfNQ5pV/9FNGZOFWkAGZO6k+AIgDZl1s/T8+I3KAiAO74TvPgl3WJKrnOFfQ5UZHGQL8u6bopROJ8bfurP4cw=="}]},"_npmUser":{"name":"axiru","email":"marcos@axiru.com"},"directories":{},"maintainers":[{"name":"axiru","email":"marcos@axiru.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/x402-receipt-verifier_0.1.1_1786468597119_0.8990736804429778"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-04T23:30:23.591Z","modified":"2026-08-11T17:16:37.437Z","0.1.0":"2026-08-04T23:30:23.892Z","0.1.1":"2026-08-11T17:16:37.274Z"},"bugs":{"url":"https://github.com/AxiruAI/axiru-oss/issues"},"author":{"name":"Axiru"},"license":"Apache-2.0","homepage":"https://github.com/AxiruAI/axiru-oss/tree/main/packages/x402-receipt-verifier#readme","keywords":["x402","receipts","offer-receipt","jws","eip-712","did-web","agentic-payments","evidence","verification","axiru"],"repository":{"type":"git","url":"git+https://github.com/AxiruAI/axiru-oss.git","directory":"packages/x402-receipt-verifier"},"description":"Verify x402 SignedOffers and SignedReceipts (JWS and EIP-712) independently of the party that issued them. Zero runtime dependencies beyond the Axiru spec types.","maintainers":[{"name":"axiru","email":"marcos@axiru.com"}],"readme":"# @axiru/x402-receipt-verifier\n\nIndependent verification of x402 **Signed Offers** and **Signed Receipts**, the evidence records defined by the upstream [x402 offer and receipt extension](https://docs.x402.org/extensions/offer-receipt).\n\n**Apache-2.0. Zero runtime dependencies beyond [`@axiru/spec`](https://www.npmjs.com/package/@axiru/spec).**\n\n## Why this exists\n\nA payment receipt that only the payer can verify is not evidence. It is a claim.\n\nx402 settlement produces two signed artifacts: an offer from the resource server describing what is being sold and for how much, and a receipt confirming that settlement happened. If your auditor, your counterparty, or a regulator has to take your word for the contents of those artifacts, the audit trail is worth very little. This package lets anyone with the envelopes and a network connection check both signatures and confirm that the receipt actually settles the offer it claims to settle. No Axiru account, no API key, no hosted service.\n\nThat is the point. A format becomes a standard when third parties can verify it without asking the issuer for permission.\n\n## Install\n\n```bash\nnpm install @axiru/x402-receipt-verifier\n```\n\nNode 18 or later. Works in Edge and Workers runtimes when you inject `fetchDidDocument`.\n\n## What it verifies\n\nTwo wire formats:\n\n| Format      | Identity                                  | Signature check                                              |\n| ----------- | ----------------------------------------- | ------------------------------------------------------------ |\n| **JWS**     | `did:web:<host>`                          | Resolved from `https://<host>/.well-known/did.json`. ES256 (P-256), EdDSA (Ed25519), and ES256K (secp256k1). |\n| **EIP-712** | `did:pkh:eip155:<chainId>:<address>`      | Recovered from the secp256k1 signature. Injected verifier, see below. |\n\nThe JWS path is fully self-contained and uses only the Node `crypto` and `fetch` globals. The EIP-712 path requires you to inject an `Eip712Verifier`, because this package deliberately carries no keccak or secp256k1 dependency; a zero-dependency verifier is easier to audit and easier to trust.\n\n## Quickstart\n\n```ts\nimport {\n  verifySignedOffer,\n  verifySignedReceipt,\n  verifyEvidenceChain\n} from \"@axiru/x402-receipt-verifier\";\n\n// Verify one artifact.\nconst offer = await verifySignedOffer(signedOffer);\nif (!offer.ok) {\n  console.error(\"offer rejected:\", offer.reason, offer.detail);\n} else {\n  console.log(\"signed by\", offer.value.signerDid, offer.value.payload);\n}\n\n// Or verify the whole chain in one call: both signatures, plus the\n// receipt-matches-offer check, plus the payer allowlist.\nconst chain = await verifyEvidenceChain(\n  signedOffer,\n  signedReceipt,\n  [\"did:pkh:eip155:8453:0xAgentWalletAddress\"], // authorized payers\n);\n\nif (!chain.ok) {\n  // `stage` tells you exactly where it failed: \"offer\" | \"receipt\" | \"match\".\n  console.error(`rejected at ${chain.stage}: ${chain.reason}`);\n}\n```\n\nNothing throws on adversarial input. Every public function returns a `Result`-shaped union, because this code sits on an ingestion path where an unhandled exception turns a hostile payload into a 5xx.\n\n## Failure reasons\n\n`structural_invalid`, `unsupported_algorithm`, `unsupported_format`, `did_resolution_failed`, `did_key_not_found`, `signature_invalid`, `kid_did_mismatch`, `eip712_not_implemented`, `internal`.\n\nThese are stable identifiers. Log them, alert on them, and assert on them in tests.\n\n## Binding evidence to an authorization\n\nVerifying that an offer and receipt are well formed and correctly signed is necessary but not sufficient. A valid receipt for the wrong amount is still the wrong payment. Pass an expected settlement to bind the evidence to what you actually authorized:\n\n```ts\nconst chain = await verifyEvidenceChain(signedOffer, signedReceipt, authorizedPayers, deps, {\n  amount_minor_units: \"12000000\",\n  asset: \"USDC\",\n  pay_to: \"0xMerchantAddress\"\n});\n```\n\nWithout that argument the chain check confirms internal consistency only. With it, the chain check confirms that the settled value is the value your policy allowed.\n\n## Injecting dependencies\n\n```ts\nconst deps = {\n  // Cache did:web documents however your host caches things.\n  fetchDidDocument: async (did: string) => myCache.getOrFetch(did),\n  // Bring your own keccak/secp256k1 for EIP-712 envelopes.\n  verifyEip712: async (typedData, signature) => recoverAddress(typedData, signature),\n  // Deterministic clock for tests and replay.\n  now: () => 1_760_000_000\n};\n```\n\nThere is no default singleton. `did:web` caching strategy is host specific and a bad default here would quietly shadow yours.\n\n## Related packages\n\n- [`@axiru/spec`](https://www.npmjs.com/package/@axiru/spec) defines the offer, receipt, and verification result types this package consumes.\n- [`@axiru/x402-policy-middleware`](https://www.npmjs.com/package/@axiru/x402-policy-middleware) is the pre-authorization half of the same loop: decide before you pay, verify after you paid.\n- [`@axiru/agent-spend-guardrails`](https://www.npmjs.com/package/@axiru/agent-spend-guardrails) evaluates spend policy in process.\n\n## License\n\nApache-2.0. Copyright 2026 Axiru. See [LICENSE](./LICENSE).\n","readmeFilename":"README.md"}