{"_id":"@autyon/x402","name":"@autyon/x402","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@autyon/x402","version":"0.1.0","description":"x402 pay-to-call gateway for Autyon service agents — charge AUT per API call, verified on-chain.","type":"module","main":"./paywall.js","exports":{".":"./paywall.js"},"engines":{"node":">=18"},"keywords":["autyon","x402","agent","payments","api","monetization"],"homepage":"https://autyon.io","repository":{"type":"git","url":"git+https://github.com/autyon/autyon.git","directory":"x402"},"license":"MIT","author":{"name":"Autyon"},"publishConfig":{"access":"public"},"dependencies":{"ethers":"^6.13.4"},"peerDependencies":{"express":"^4 || ^5"},"_id":"@autyon/x402@0.1.0","gitHead":"98f2a87ec48025029db7b85c389dc86ce59451e3","bugs":{"url":"https://github.com/autyon/autyon/issues"},"_nodeVersion":"22.22.2","_npmVersion":"10.9.7","dist":{"integrity":"sha512-7ucCuQ3lCipv+hpssRcfeD0ntr98V9H7tIkNvWLY33hFFBdACDmHzPcyzcz8ALNBBP2c3MZ+faF4HRUx5WKvFQ==","shasum":"6eb0fb52a72c8f1eb3a90dbd4c646de93362320f","tarball":"https://registry.npmjs.org/@autyon/x402/-/x402-0.1.0.tgz","fileCount":4,"unpackedSize":14120,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQD0JlbDDfi9ksEYUbx95jjbRL+UsCMTuf4gXdjTF+cqUwIgNIxxVdbfp4QvfSfU3CtmMdpNsVHDSD19QRd3zFmLQqc="}]},"_npmUser":{"name":"autyon","email":"autyonchain@gmail.com"},"directories":{},"maintainers":[{"name":"autyon","email":"autyonchain@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/x402_0.1.0_1787806593065_0.13373141539560374"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-27T04:56:32.897Z","0.1.0":"2026-08-27T04:56:33.210Z","modified":"2026-08-27T04:56:33.376Z"},"maintainers":[{"name":"autyon","email":"autyonchain@gmail.com"}],"description":"x402 pay-to-call gateway for Autyon service agents — charge AUT per API call, verified on-chain.","homepage":"https://autyon.io","keywords":["autyon","x402","agent","payments","api","monetization"],"repository":{"type":"git","url":"git+https://github.com/autyon/autyon.git","directory":"x402"},"author":{"name":"Autyon"},"bugs":{"url":"https://github.com/autyon/autyon/issues"},"license":"MIT","readme":"# @autyon/x402\n\n**Charge AUT per API call, verified on-chain.** An [x402](https://autyon.io/docs)-style \"pay to call\" gateway for Autyon service agents: wrap any Express route in a paywall, and it only runs after the caller has paid your agent on-chain.\n\nAutyon already has the payment rail (`ServicePayment.payAgent`) and receipts (`ServicePaid`). This package adds the missing HTTP layer.\n\n## How it works\n\n```\nClient                         Gateway                         Autyon chain\n  │   GET /premium                 │                                │\n  │ ─────────────────────────────▶│                                │\n  │   402 { agentId, priceWei,     │                                │\n  │        requestId, payTo }      │                                │\n  │ ◀─────────────────────────────│                                │\n  │   payAgent(agentId,[0,0,0],requestId) value≥price ────────────▶│  ServicePaid\n  │ ◀──────────── txHash ──────────────────────────────────────────│\n  │   sign(requestId) with paying key                               │\n  │   GET /premium                 │                                │\n  │   X-Autyon-RequestId, -Tx, -Sig│  verify receipt: agentId +     │\n  │ ──────────────────────────────▶│  requestId match, gross≥price, │\n  │                                │  sig==payer, single-use ──────▶│ (read)\n  │   200 { your data }            │                                │\n  │ ◀─────────────────────────────│                                │\n```\n\n## Server\n\n```js\nimport express from \"express\";\nimport { autyonPaywall } from \"@autyon/x402\";\n\nconst app = express();\n\napp.get(\"/premium\",\n  autyonPaywall({ agentId: 1, priceAUT: \"0.1\" }),  // agentId from `autyon go-pro`\n  (req, res) => res.json({ answer: 42, paidWith: req.autyonPayment })\n);\n\napp.listen(8402);\n```\n\nThe route body runs only on a verified, unused payment. `req.autyonPayment` holds `{ requestId, txHash, agentId }`.\n\n### Options\n\n| Option | Default | Meaning |\n|---|---|---|\n| `agentId` | — | your service agent's AgentRegistry id (required) |\n| `priceAUT` | — | price per call in AUT, e.g. `\"0.1\"` (required) |\n| `rpc` | `https://rpc.autyon.io` | RPC endpoint |\n| `ttlMs` | `600000` | how long a challenge stays payable |\n| `store` | in-memory | `{ put, get, consume }` — use Redis for multi-instance |\n\n> The default store is in-memory. For multiple gateway instances (or restarts), pass a shared/persistent `store`, otherwise a paid `requestId` issued by one instance can't be verified by another.\n\n## Client\n\nThe [`@autyon/sdk`](../sdk) does the 402 → pay → sign → retry automatically. Because the\nserver dictates the price, cap it:\n\n```js\nimport { AutyonClient, ADDR } from \"@autyon/sdk\";\nimport { parseEther } from \"ethers\";\nconst autyon = new AutyonClient({ privateKey: process.env.AGENT_KEY });\n\nconst res = await autyon.x402Fetch(\"https://api.example.com/premium\", {}, {\n  maxPriceWei: parseEther(\"1\"),   // never pay more than 1 AUT for a call\n  allowAgentIds: [1],             // (optional) only pay these agents\n});\nconsole.log(await res.json());\n```\n\n## Security\n\n- **Issued-id only.** The `requestId` must be one the gateway issued (random 32 bytes) and unexpired — a caller can't forge or pre-pay a made-up id.\n- **On-chain proof.** The proof tx must be mined, emitted by the real `ServicePayment` contract, and carry a `ServicePaid` log whose `agentId` + `requestId` match and whose `grossAmount` ≥ the price.\n- **Payer-bound.** `requestId` and the tx hash are public on-chain, so possession alone must not grant access. Redemption requires an `X-Autyon-Sig` signature of the `requestId` by the paying key; the gateway checks it against the `ServicePaid.payer`. A front-runner who only read the chain cannot sign it.\n- **Single-use, path-bound.** Each `requestId` is consumed atomically (compare-and-set) and bound to the request path — no replay under concurrency, and a payment for one resource can't unlock another.\n- **Client price cap.** `x402Fetch` refuses to pay above `maxPriceWei` / outside `allowAgentIds`, so a malicious server can't drain the caller.\n\n### Known limitations (before value-bearing use)\n- Default `store` is in-memory (evicts expired, capped). For multiple instances or restarts, pass a shared/atomic store (Redis with `SET NX` + TTL), or a paid `requestId` from one instance can't be verified by another.\n- If a caller pays **after** the challenge TTL (default 10 min) expires, that payment is unrecoverable — redeem promptly.\n- No confirmation-depth / reorg protection: a tx that confirms then reorgs out was already served. Require N confirmations for real value.\n\nTestnet, chainId 77077. Testnet AUT has no monetary value.\n\nMIT © Autyon\n","readmeFilename":"README.md","_rev":"1-b101bf45b891e2732bc898f42fdd7c4b"}