{"_id":"@accord-protocol/gateway","_rev":"3-dd9259c265c8ad0c930a9350eedddceb","name":"@accord-protocol/gateway","dist-tags":{"latest":"0.4.2"},"versions":{"0.4.0":{"name":"@accord-protocol/gateway","version":"0.4.0","keywords":["accord-protocol","accord-402","http-402","agent-payments","paid-api","x402-compatible","express-middleware","connect-middleware"],"author":{"name":"bez111"},"license":"MIT","_id":"@accord-protocol/gateway@0.4.0","maintainers":[{"name":"accord-protocol","email":"alexander.bezkrovny@gmail.com"}],"homepage":"https://github.com/accord-protocol/accord-protocol/tree/main/packages/accord-gateway","bugs":{"url":"https://github.com/accord-protocol/accord-protocol/issues"},"dist":{"shasum":"b95655bd4aa8e6229f72ca40c8b85adec9bc5e39","tarball":"https://registry.npmjs.org/@accord-protocol/gateway/-/gateway-0.4.0.tgz","fileCount":6,"integrity":"sha512-bykG+GdSGMYnGwR0jsfKBqJkPvl/F/nKbZKIoatnLzmPDUEbWoV8jYQW2BcWe/Z6omUXkT4GsE84dn/j1GyXEg==","signatures":[{"sig":"MEYCIQCAdoSUwDCUD7zZ2v3VRtDB0s5yPfgbVzTpRLYBVGkfKAIhAIrTf0Aj4X4Nb4+LeiphwipkXQp09PqAUzelNoTDu18s","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":44697},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"3de0b386d2e83302cac87206d198a8a799b6baa8","scripts":{"test":"npx tsx --test src/__tests__/*.test.ts","build":"tsup src/index.ts --format esm,cjs --dts --clean","typecheck":"tsc --noEmit"},"_npmUser":{"name":"accord-protocol","email":"alexander.bezkrovny@gmail.com"},"repository":{"url":"git+https://github.com/accord-protocol/accord-protocol.git","type":"git","directory":"packages/accord-gateway"},"_npmVersion":"10.9.4","description":"Accord/402 HTTP middleware. Express/Connect-compatible. Turn any HTTP endpoint into a paid, verifiable Accord engagement: 402 challenge with agreement template, replay-protected payment verification, structured error envelope. Rail-agnostic. See specs/ACC","directories":{},"_nodeVersion":"22.21.1","dependencies":{"@accord-protocol/core":"^0.4.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.0.0","tsup":"^8.0.0","typescript":"^5.0.0","@types/node":"^20.0.0"},"_npmOperationalInternal":{"tmp":"tmp/gateway_0.4.0_1778775550830_0.5937898978668061","host":"s3://npm-registry-packages-npm-production"}},"0.4.1":{"name":"@accord-protocol/gateway","version":"0.4.1","keywords":["accord-protocol","accord-402","http-402","agent-payments","paid-api","x402-compatible","express-middleware","connect-middleware"],"author":{"name":"bez111"},"license":"MIT","_id":"@accord-protocol/gateway@0.4.1","maintainers":[{"name":"accord-protocol","email":"alexander.bezkrovny@gmail.com"}],"homepage":"https://github.com/accord-protocol/accord-protocol/tree/main/packages/accord-gateway","bugs":{"url":"https://github.com/accord-protocol/accord-protocol/issues"},"dist":{"shasum":"570868886f30a717cd94385c139efbdd187ecab2","tarball":"https://registry.npmjs.org/@accord-protocol/gateway/-/gateway-0.4.1.tgz","fileCount":6,"integrity":"sha512-JMNvKGgNdDKwOABLtxwM0hqwoEXrXs1Klt+z+WafoppmuiVCCZNItLEaOHcY/95LT8i4zXc/0mRjV/0EnQzz+Q==","signatures":[{"sig":"MEUCIGXT4R/qmtBxjr+KSL4c/mQs/KaKhUQcxbRJPHmizXcwAiEAlDZKtByixO1cD1kMztz83DlAitn5bG0jCSgQbxQHcgw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@accord-protocol%2fgateway@0.4.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":44698},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"e42de427235ef205df05351fb51e607b159d23b6","scripts":{"test":"npx tsx --test src/__tests__/*.test.ts","build":"tsup src/index.ts --format esm,cjs --dts --clean","typecheck":"tsc --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:5186f0bb-cb95-42a6-a4e9-7d9c7316ec03"}},"repository":{"url":"git+https://github.com/accord-protocol/accord-protocol.git","type":"git","directory":"packages/accord-gateway"},"_npmVersion":"11.14.1","description":"Accord/402 HTTP middleware. Express/Connect-compatible. Turn any HTTP endpoint into a paid, verifiable Accord engagement: 402 challenge with agreement template, replay-protected payment verification, structured error envelope. Rail-agnostic. See specs/ACC","directories":{},"_nodeVersion":"24.15.0","dependencies":{"@accord-protocol/core":"^0.4.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.0.0","tsup":"^8.0.0","typescript":"^5.0.0","@types/node":"^20.0.0"},"_npmOperationalInternal":{"tmp":"tmp/gateway_0.4.1_1778872876903_0.8685994615461183","host":"s3://npm-registry-packages-npm-production"}},"0.4.2":{"name":"@accord-protocol/gateway","version":"0.4.2","description":"Accord/402 HTTP middleware. Express/Connect-compatible. Turn any HTTP endpoint into a paid, verifiable Accord engagement: 402 challenge with agreement template, replay-protected payment verification, structured error envelope. Rail-agnostic. See specs/ACC","type":"module","main":"./dist/index.cjs","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"scripts":{"build":"tsup src/index.ts --format esm,cjs --dts --clean","typecheck":"tsc --noEmit","test":"npx tsx --test src/__tests__/*.test.ts"},"keywords":["accord-protocol","accord-402","http-402","agent-payments","paid-api","x402-compatible","express-middleware","connect-middleware"],"author":{"name":"bez111"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/accord-protocol/accord-protocol.git","directory":"packages/accord-gateway"},"homepage":"https://accordprotocol.ai/learn/accord-402-flow/","bugs":{"url":"https://github.com/accord-protocol/accord-protocol/issues"},"dependencies":{"@accord-protocol/core":"^0.4.2"},"devDependencies":{"@types/node":"^20.0.0","tsup":"^8.0.0","tsx":"^4.0.0","typescript":"^5.0.0"},"engines":{"node":">=18"},"publishConfig":{"access":"public"},"gitHead":"437febb0a70b3162d4b10b19874f1a0026a59bdf","_id":"@accord-protocol/gateway@0.4.2","_nodeVersion":"24.15.0","_npmVersion":"11.15.0","dist":{"integrity":"sha512-pJWaQuqR4BAJ1JetnC4zuht/QPZ5vknAIOyb9Zo/g/bzrMbE7viDiym+BLxkjpTd9Et3AqsrncZwpjXuAKc0JA==","shasum":"b54328df6029d90ff9997ff4006ae1601c46b5d2","tarball":"https://registry.npmjs.org/@accord-protocol/gateway/-/gateway-0.4.2.tgz","fileCount":6,"unpackedSize":44833,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@accord-protocol%2fgateway@0.4.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIFjibgyB+RjaIYhB9lLgDE2d7WuS0YOwaDbn1NRjPac3AiBY1UimzZNEm7GZeJzlichRAK+mSL1TpSt3zMq7YOLYjA=="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:5186f0bb-cb95-42a6-a4e9-7d9c7316ec03"}},"directories":{},"maintainers":[{"name":"accord-protocol","email":"alexander.bezkrovny@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/gateway_0.4.2_1779582021589_0.9185617773092438"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-14T16:19:10.774Z","modified":"2026-05-24T00:20:22.028Z","0.4.0":"2026-05-14T16:19:10.983Z","0.4.1":"2026-05-15T19:21:17.043Z","0.4.2":"2026-05-24T00:20:21.737Z"},"bugs":{"url":"https://github.com/accord-protocol/accord-protocol/issues"},"author":{"name":"bez111"},"license":"MIT","homepage":"https://accordprotocol.ai/learn/accord-402-flow/","keywords":["accord-protocol","accord-402","http-402","agent-payments","paid-api","x402-compatible","express-middleware","connect-middleware"],"repository":{"type":"git","url":"git+https://github.com/accord-protocol/accord-protocol.git","directory":"packages/accord-gateway"},"description":"Accord/402 HTTP middleware. Express/Connect-compatible. Turn any HTTP endpoint into a paid, verifiable Accord engagement: 402 challenge with agreement template, replay-protected payment verification, structured error envelope. Rail-agnostic. See specs/ACC","maintainers":[{"name":"accord-protocol","email":"alexander.bezkrovny@gmail.com"}],"readme":"# `@accord-protocol/gateway`\n\n**Accord/402 HTTP middleware.** Connect / Express compatible. Turn any HTTP endpoint into a paid, verifiable Accord engagement: 402 challenge with agreement template, replay-protected payment verification, structured error envelope, optional verifier hook, optional settlement.\n\nPublic docs: [Website](https://accordprotocol.ai/) · [Accord/402 guide](https://accordprotocol.ai/learn/accord-402-flow/) · [Status](https://accordprotocol.ai/status/)\n\nRail-agnostic — takes any `AccordRailAdapter`. Reference rail adapters land separately as `@accord-protocol/rails-{ergo,base,x402}`.\n\n## Install\n\n```bash\nnpm install @accord-protocol/gateway @accord-protocol/core\n```\n\n## Quickstart\n\n```ts\nimport express from \"express\";\nimport { accordGateway, type AccordRailAdapter } from \"@accord-protocol/gateway\";\n\nconst app = express();\napp.use(express.json());\n\nconst rail: AccordRailAdapter = {\n  rail: \"ergo\",\n  async verifyPayment({ agreement, payment }) {\n    // …call your real Note verifier here\n    return { ok: true, rail: \"ergo\", payment_id: \"<note-box-id>\" };\n  },\n  async settle({ agreement }) {\n    return { /* AccordSettlementReceipt */ } as never;\n  },\n};\n\napp.post(\"/api/run\", accordGateway({\n  rail,\n  resolveAgreement: async (id) => store.get(id),\n  buildAgreementTemplate: () => ({\n    agreement_template: \"https://provider.example/.well-known/accord/agreement-template\",\n    price: { amount: \"0.05\", currency: \"USDC\", decimals: 6 },\n    accepted_rails: [\"ergo\", \"rosen\", \"base\", \"x402\"],\n    verification_required: false,\n  }),\n  handler: async (req, { agreement, body }) => {\n    return { word_count: String(body?.text ?? \"\").split(/\\s+/).filter(Boolean).length };\n  },\n}));\n\napp.listen(3000);\n```\n\n## Per-request flow\n\n```text\n1. Read X-Accord-* headers\n2. resolveAgreement(id)                       → 402 with template if unknown\n3. validateAgreement(agreement)               → 400 if cross-field problems\n4. JSON.parse(X-Accord-Payment)               → 402 if missing\n5. rail.verifyPayment(...)                    → 402 if rejected, 502 if threw\n6. replayStore.has/put(rail, payment_id)      → 402 if same id replayed\n7. (optional) accord_task_output hash check   → 400 if mismatch\n8. handler(req, { agreement, body })          → 500 if threw\n9. (if required) verifier(...) + validate     → 422 if rejected/invalid\n10. (best-effort) rail.settle(...)            → swallowed, attached to _meta\n11. 200 with { output, _meta } JSON body + Accord headers\n```\n\n## 402 challenge response\n\n```http\nHTTP/1.1 402 Payment Required\nAccord-Version: v0\nAccord-Agreement-Required: true\nAccord-Agreement-Template: https://provider.example/.well-known/accord/agreement-template\nAccord-Accepted-Rails: ergo,rosen,base,x402\nWWW-Authenticate: Accord402\nContent-Type: application/json\n\n{\n  \"error\": \"ACCORD_PAYMENT_REQUIRED\",\n  \"agreement_template\": \"https://provider.example/.well-known/accord/agreement-template\",\n  \"price\": { \"amount\": \"0.05\", \"currency\": \"USDC\", \"decimals\": 6 },\n  \"accepted_rails\": [\"ergo\", \"rosen\", \"base\", \"x402\"],\n  \"verification_required\": false\n}\n```\n\n## Replay protection\n\nDefault: in-process `Map`-backed `InMemoryReplayStore` with a 24h TTL. Suitable for dev / tests / single-process demos. For production, plug in a Redis-backed implementation:\n\n```ts\nimport type { AccordReplayStore } from \"@accord-protocol/gateway\";\n\nconst replayStore: AccordReplayStore = {\n  has: async (rail, id) => (await redis.exists(`replay:${rail}:${id}`)) === 1,\n  put: async (rail, id, expiresAtMs) => {\n    const ttlSec = Math.max(1, Math.floor((expiresAtMs - Date.now()) / 1000));\n    await redis.setex(`replay:${rail}:${id}`, ttlSec, \"1\");\n  },\n};\n```\n\nThe interface is intentionally tiny — two methods.\n\n## Error codes\n\n| Code | HTTP |\n|---|---|\n| `ACCORD_PAYMENT_REQUIRED` | 402 |\n| `UNKNOWN_AGREEMENT` | 402 |\n| `MISSING_PAYMENT` | 402 |\n| `AGREEMENT_INVALID` | 400 |\n| `PAYMENT_VERIFICATION_FAILED` | 402 |\n| `RAIL_UNAVAILABLE` | 502 |\n| `REPLAY_DETECTED` | 402 |\n| `TASK_OUTPUT_HASH_MISMATCH` | 400 |\n| `HANDLER_THREW` | 500 |\n| `VERIFICATION_REQUIRED` | 422 |\n| `VERIFICATION_REJECTED` | 422 |\n\n## What's NOT in this package\n\n- Rail adapter implementations (Ergo / Rosen / Base / x402) → `@accord-protocol/rails-*`\n- x402 compatibility shim — use the rail adapter package for current x402 integrations.\n- A bundled JSON parser — bring your own (`express.json()`, `body-parser`, etc.). The middleware only reads headers and `req.body`.\n- Conformance tests → `@accord-protocol/conformance`\n\n## License\n\nMIT.\n","readmeFilename":"README.md"}