@reinconsole/sdk 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/index.cjs +163 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +161 -1
- package/dist/index.d.ts +161 -1
- package/dist/index.js +153 -9
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
The demand-side guard of **[Rein](https://github.com/bugiiiii11/rein)** — the control plane for AI agent payments. Wrap your agent's `fetch` once and every [x402](https://www.x402.org) payment is policy-checked, receipted, and observable **before a cent moves**. Non-custodial: Rein governs the authority to spend, never the funds.
|
|
4
4
|
|
|
5
|
-
> **Status: v0.1 — early open-source infrastructure, live on testnet.** APIs may change before 1.0. See it running: [Rein console](https://reinconsole
|
|
5
|
+
> **Status: v0.1 — early open-source infrastructure, live on testnet.** APIs may change before 1.0. See it running: [Rein console](https://app.reinconsole.com).
|
|
6
6
|
|
|
7
7
|
## Install
|
|
8
8
|
|
package/dist/index.cjs
CHANGED
|
@@ -198,6 +198,124 @@ function toIntentSubmission(resolved, url, agentId, taskContext) {
|
|
|
198
198
|
taskContext
|
|
199
199
|
};
|
|
200
200
|
}
|
|
201
|
+
var CAIP2_ALIASES = {
|
|
202
|
+
base: "eip155:8453",
|
|
203
|
+
"base-sepolia": "eip155:84532",
|
|
204
|
+
polygon: "eip155:137",
|
|
205
|
+
"polygon-amoy": "eip155:80002",
|
|
206
|
+
bnb: "eip155:56",
|
|
207
|
+
bsc: "eip155:56",
|
|
208
|
+
solana: "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",
|
|
209
|
+
"solana-devnet": "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1"
|
|
210
|
+
};
|
|
211
|
+
function caip2Of(network) {
|
|
212
|
+
const key = network.toLowerCase();
|
|
213
|
+
return CAIP2_ALIASES[key] ?? key;
|
|
214
|
+
}
|
|
215
|
+
function sameNetwork(a, b) {
|
|
216
|
+
return caip2Of(a) === caip2Of(b);
|
|
217
|
+
}
|
|
218
|
+
var PaymentRequirementsV2 = zod.z.object({
|
|
219
|
+
scheme: zod.z.string(),
|
|
220
|
+
/** CAIP-2, e.g. "eip155:84532". */
|
|
221
|
+
network: zod.z.string(),
|
|
222
|
+
/** Atomic units — v2's rename of v1's maxAmountRequired. */
|
|
223
|
+
amount: zod.z.string().regex(/^\d+$/, "atomic amount must be an integer string"),
|
|
224
|
+
asset: zod.z.string().min(1),
|
|
225
|
+
payTo: zod.z.string().min(1),
|
|
226
|
+
maxTimeoutSeconds: zod.z.number().optional(),
|
|
227
|
+
extra: zod.z.record(zod.z.unknown()).optional()
|
|
228
|
+
});
|
|
229
|
+
var ResourceInfoV2 = zod.z.object({
|
|
230
|
+
url: zod.z.string(),
|
|
231
|
+
description: zod.z.string().optional(),
|
|
232
|
+
mimeType: zod.z.string().optional()
|
|
233
|
+
});
|
|
234
|
+
var PaymentRequiredV2 = zod.z.object({
|
|
235
|
+
x402Version: zod.z.literal(2),
|
|
236
|
+
error: zod.z.string().optional(),
|
|
237
|
+
resource: ResourceInfoV2.optional(),
|
|
238
|
+
accepts: zod.z.array(PaymentRequirementsV2).min(1),
|
|
239
|
+
extensions: zod.z.record(zod.z.unknown()).optional()
|
|
240
|
+
});
|
|
241
|
+
function v2Requirements(requirement) {
|
|
242
|
+
return {
|
|
243
|
+
scheme: requirement.scheme,
|
|
244
|
+
network: caip2Of(requirement.network),
|
|
245
|
+
amount: requirement.maxAmountRequired,
|
|
246
|
+
asset: requirement.asset,
|
|
247
|
+
payTo: requirement.payTo,
|
|
248
|
+
...requirement.maxTimeoutSeconds !== void 0 ? { maxTimeoutSeconds: requirement.maxTimeoutSeconds } : {},
|
|
249
|
+
...requirement.extra ? { extra: requirement.extra } : {}
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
function requirementFromV2(offer, resource) {
|
|
253
|
+
return PaymentRequirement.parse({
|
|
254
|
+
scheme: offer.scheme,
|
|
255
|
+
network: offer.network,
|
|
256
|
+
maxAmountRequired: offer.amount,
|
|
257
|
+
payTo: offer.payTo,
|
|
258
|
+
asset: offer.asset,
|
|
259
|
+
...resource !== void 0 ? { resource: resource.url } : {},
|
|
260
|
+
...resource?.description !== void 0 ? { description: resource.description } : {},
|
|
261
|
+
...resource?.mimeType !== void 0 ? { mimeType: resource.mimeType } : {},
|
|
262
|
+
...offer.maxTimeoutSeconds !== void 0 ? { maxTimeoutSeconds: offer.maxTimeoutSeconds } : {},
|
|
263
|
+
...offer.extra ? { extra: offer.extra } : {}
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
function buildPaymentRequiredV2(requirement, error) {
|
|
267
|
+
return {
|
|
268
|
+
x402Version: 2,
|
|
269
|
+
error,
|
|
270
|
+
...requirement.resource ? {
|
|
271
|
+
resource: {
|
|
272
|
+
url: requirement.resource,
|
|
273
|
+
...requirement.description ? { description: requirement.description } : {},
|
|
274
|
+
...requirement.mimeType ? { mimeType: requirement.mimeType } : {}
|
|
275
|
+
}
|
|
276
|
+
} : {},
|
|
277
|
+
accepts: [v2Requirements(requirement)],
|
|
278
|
+
extensions: {}
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
function encodeBase64Json(value) {
|
|
282
|
+
return Buffer.from(JSON.stringify(value)).toString("base64");
|
|
283
|
+
}
|
|
284
|
+
function decodeBase64Json(raw) {
|
|
285
|
+
try {
|
|
286
|
+
return JSON.parse(Buffer.from(raw, "base64").toString("utf8"));
|
|
287
|
+
} catch {
|
|
288
|
+
return void 0;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
function parsePaymentRequiredHeader(raw) {
|
|
292
|
+
if (raw === null) return void 0;
|
|
293
|
+
const parsed = PaymentRequiredV2.safeParse(decodeBase64Json(raw));
|
|
294
|
+
return parsed.success ? parsed.data : void 0;
|
|
295
|
+
}
|
|
296
|
+
var V1Envelope = zod.z.object({
|
|
297
|
+
x402Version: zod.z.literal(1),
|
|
298
|
+
scheme: zod.z.string(),
|
|
299
|
+
network: zod.z.string(),
|
|
300
|
+
payload: zod.z.record(zod.z.unknown())
|
|
301
|
+
});
|
|
302
|
+
function wrapPaymentV2(paymentHeader, requirement, resource) {
|
|
303
|
+
const decoded = decodeBase64Json(paymentHeader);
|
|
304
|
+
if (decoded?.x402Version === 2) {
|
|
305
|
+
return paymentHeader;
|
|
306
|
+
}
|
|
307
|
+
const v1 = V1Envelope.safeParse(decoded);
|
|
308
|
+
if (!v1.success) {
|
|
309
|
+
throw new TypeError(`cannot rewrap payment header as x402 v2: ${v1.error.message}`);
|
|
310
|
+
}
|
|
311
|
+
return encodeBase64Json({
|
|
312
|
+
x402Version: 2,
|
|
313
|
+
...resource !== void 0 ? { resource } : {},
|
|
314
|
+
accepted: v2Requirements(requirement),
|
|
315
|
+
payload: v1.data.payload,
|
|
316
|
+
extensions: {}
|
|
317
|
+
});
|
|
318
|
+
}
|
|
201
319
|
|
|
202
320
|
// src/guard.ts
|
|
203
321
|
var Guard = class {
|
|
@@ -231,17 +349,16 @@ var Guard = class {
|
|
|
231
349
|
const inner = fetchImpl ? (input, init) => fetchImpl(input, init) : this.baseFetch;
|
|
232
350
|
return async (input, init) => {
|
|
233
351
|
const url = requestUrl(input);
|
|
234
|
-
if (readHeader(input, init, "X-PAYMENT") !== null) {
|
|
352
|
+
if (readHeader(input, init, "X-PAYMENT") !== null || readHeader(input, init, "PAYMENT-SIGNATURE") !== null) {
|
|
235
353
|
const res2 = await inner(input, init);
|
|
236
354
|
this.settlePending(url, res2);
|
|
237
355
|
return res2;
|
|
238
356
|
}
|
|
239
357
|
const res = await inner(input, init);
|
|
240
358
|
if (res.status !== 402) return res;
|
|
241
|
-
const
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
const resolved = selectRequirement(parsed.data.accepts, this.options.assetAddresses);
|
|
359
|
+
const paywall = await parse402(res, this.options.assetAddresses);
|
|
360
|
+
if (!paywall) return res;
|
|
361
|
+
const { resolved, wire, resource } = paywall;
|
|
245
362
|
if (!resolved) throw new UnsupportedRequirementError(url);
|
|
246
363
|
const taskContext = this.task.getStore() ?? this.options.taskContext;
|
|
247
364
|
const submission = toIntentSubmission(resolved, url, this.options.agentId, taskContext);
|
|
@@ -257,7 +374,15 @@ var Guard = class {
|
|
|
257
374
|
return res;
|
|
258
375
|
}
|
|
259
376
|
const paymentHeader = await this.options.payer(resolved.requirement, intent, decision);
|
|
260
|
-
const retry = await inner(
|
|
377
|
+
const retry = await inner(
|
|
378
|
+
input,
|
|
379
|
+
wire === 2 ? withHeader(
|
|
380
|
+
input,
|
|
381
|
+
init,
|
|
382
|
+
"PAYMENT-SIGNATURE",
|
|
383
|
+
wrapPaymentV2(paymentHeader, resolved.requirement, resource)
|
|
384
|
+
) : withHeader(input, init, "X-PAYMENT", paymentHeader)
|
|
385
|
+
);
|
|
261
386
|
this.record(intent, decision, url, init, parseSettlement(retry));
|
|
262
387
|
return retry;
|
|
263
388
|
};
|
|
@@ -295,6 +420,24 @@ var Guard = class {
|
|
|
295
420
|
function createGuard(options) {
|
|
296
421
|
return new Guard(options);
|
|
297
422
|
}
|
|
423
|
+
async function parse402(res, assetAddresses) {
|
|
424
|
+
const v2 = parsePaymentRequiredHeader(res.headers.get("PAYMENT-REQUIRED"));
|
|
425
|
+
if (v2) {
|
|
426
|
+
const resolved = selectRequirement(
|
|
427
|
+
v2.accepts.map((offer) => requirementFromV2(offer, v2.resource)),
|
|
428
|
+
assetAddresses
|
|
429
|
+
);
|
|
430
|
+
if (resolved) {
|
|
431
|
+
return v2.resource !== void 0 ? { resolved, wire: 2, resource: v2.resource } : { resolved, wire: 2 };
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
const body = await res.clone().json().catch(() => void 0);
|
|
435
|
+
const parsed = PaymentRequired.safeParse(body);
|
|
436
|
+
if (parsed.success) {
|
|
437
|
+
return { resolved: selectRequirement(parsed.data.accepts, assetAddresses), wire: 1 };
|
|
438
|
+
}
|
|
439
|
+
return v2 ? { resolved: void 0, wire: 2 } : void 0;
|
|
440
|
+
}
|
|
298
441
|
function requestUrl(input) {
|
|
299
442
|
if (typeof input === "string") return input;
|
|
300
443
|
if (input instanceof URL) return input.toString();
|
|
@@ -312,7 +455,7 @@ function withHeader(input, init, name, value) {
|
|
|
312
455
|
return { ...init, headers };
|
|
313
456
|
}
|
|
314
457
|
function parseSettlement(res) {
|
|
315
|
-
const raw = res.headers.get("X-PAYMENT-RESPONSE");
|
|
458
|
+
const raw = res.headers.get("X-PAYMENT-RESPONSE") ?? res.headers.get("PAYMENT-RESPONSE");
|
|
316
459
|
if (raw === null) return void 0;
|
|
317
460
|
let payload;
|
|
318
461
|
try {
|
|
@@ -326,7 +469,8 @@ function parseSettlement(res) {
|
|
|
326
469
|
}
|
|
327
470
|
const record = typeof payload === "object" && payload !== null ? payload : {};
|
|
328
471
|
return {
|
|
329
|
-
|
|
472
|
+
// A failed v2 settle carries transaction: "" — no tx is no txHash.
|
|
473
|
+
txHash: typeof record["transaction"] === "string" && record["transaction"] !== "" ? record["transaction"] : void 0,
|
|
330
474
|
networkId: typeof record["network"] === "string" ? record["network"] : void 0,
|
|
331
475
|
raw
|
|
332
476
|
};
|
|
@@ -353,16 +497,27 @@ exports.EngineError = EngineError;
|
|
|
353
497
|
exports.Guard = Guard;
|
|
354
498
|
exports.PaymentBlockedError = PaymentBlockedError;
|
|
355
499
|
exports.PaymentRequired = PaymentRequired;
|
|
500
|
+
exports.PaymentRequiredV2 = PaymentRequiredV2;
|
|
356
501
|
exports.PaymentRequirement = PaymentRequirement;
|
|
502
|
+
exports.PaymentRequirementsV2 = PaymentRequirementsV2;
|
|
357
503
|
exports.ReinError = ReinError;
|
|
504
|
+
exports.ResourceInfoV2 = ResourceInfoV2;
|
|
358
505
|
exports.UnsupportedRequirementError = UnsupportedRequirementError;
|
|
359
506
|
exports.atomicToDecimal = atomicToDecimal;
|
|
507
|
+
exports.buildPaymentRequiredV2 = buildPaymentRequiredV2;
|
|
508
|
+
exports.caip2Of = caip2Of;
|
|
360
509
|
exports.createGuard = createGuard;
|
|
361
510
|
exports.decimalToAtomic = decimalToAtomic;
|
|
511
|
+
exports.encodeBase64Json = encodeBase64Json;
|
|
362
512
|
exports.networkToChain = networkToChain;
|
|
513
|
+
exports.parsePaymentRequiredHeader = parsePaymentRequiredHeader;
|
|
363
514
|
exports.requirementDecimals = requirementDecimals;
|
|
515
|
+
exports.requirementFromV2 = requirementFromV2;
|
|
364
516
|
exports.resolveAsset = resolveAsset;
|
|
517
|
+
exports.sameNetwork = sameNetwork;
|
|
365
518
|
exports.selectRequirement = selectRequirement;
|
|
366
519
|
exports.toIntentSubmission = toIntentSubmission;
|
|
520
|
+
exports.v2Requirements = v2Requirements;
|
|
521
|
+
exports.wrapPaymentV2 = wrapPaymentV2;
|
|
367
522
|
//# sourceMappingURL=index.cjs.map
|
|
368
523
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors.ts","../src/client.ts","../src/x402.ts","../src/guard.ts"],"names":["z","PaymentIntent","Decision","Agent","Policy","Asset","AsyncLocalStorage","AgentId","res","Receipt","newId"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { Decision, PaymentIntent, Receipt } from '@reinconsole/core';\n\n/** Base class for everything the SDK throws, so callers can catch broadly. */\nexport class ReinError extends Error {\n constructor(message: string) {\n super(message);\n this.name = new.target.name;\n }\n}\n\n/** The policy engine answered with a non-2xx status. */\nexport class EngineError extends ReinError {\n constructor(\n readonly status: number,\n readonly body: unknown,\n message = `policy engine responded ${status}`,\n ) {\n super(message);\n }\n}\n\n/**\n * The engine evaluated the intent and did NOT allow it (deny or escalate —\n * v0.1 blocks both; escalation approval flows land later). The payment was\n * never constructed, so no funds moved. Carries the full evidence trail.\n */\nexport class PaymentBlockedError extends ReinError {\n constructor(\n readonly intent: PaymentIntent,\n readonly decision: Decision,\n readonly receipt: Receipt,\n ) {\n super(\n `rein blocked payment of ${intent.amount} ${intent.asset} to ${intent.vendor.host}: ` +\n `${decision.outcome}${decision.reason ? ` (${decision.reason})` : ''}`,\n );\n }\n}\n\n/**\n * The vendor's 402 was x402-shaped but offered no requirement the guard can\n * govern (unknown scheme/network/asset). The guard fails closed rather than\n * letting an ungoverned payment through.\n */\nexport class UnsupportedRequirementError extends ReinError {\n constructor(readonly url: string) {\n super(`no supported x402 payment requirement in 402 from ${url}; failing closed`);\n }\n}\n","import { z } from 'zod';\nimport { Agent, Decision, PaymentIntent, Policy } from '@reinconsole/core';\nimport { EngineError } from './errors.js';\nimport type { IntentSubmission } from './x402.js';\n\n/** Any fetch-compatible function (global fetch, undici, or a test double). */\nexport type FetchLike = (input: string | URL | Request, init?: RequestInit) => Promise<Response>;\n\nconst Health = z.object({ status: z.string(), publicKey: z.string() });\nconst EvaluateResponse = z.object({ intent: PaymentIntent, decision: Decision });\nexport type EvaluateResponse = z.infer<typeof EvaluateResponse>;\n\nexport interface EngineClientOptions {\n /** Base URL of the policy engine, e.g. \"http://localhost:8787\". */\n baseUrl: string;\n /** Override the transport (tests, custom agents). Defaults to global fetch. */\n fetch?: FetchLike;\n}\n\n/**\n * Thin typed client for the policy-engine HTTP API. Every response is parsed\n * through the @reinconsole/core schemas, so wire drift fails loudly at the boundary.\n */\nexport class EngineClient {\n private readonly baseUrl: string;\n private readonly fetchImpl: FetchLike;\n\n constructor(options: EngineClientOptions) {\n this.baseUrl = options.baseUrl.replace(/\\/+$/, '');\n const f = options.fetch ?? globalThis.fetch;\n this.fetchImpl = (input, init) => f(input, init);\n }\n\n private async request<T>(\n method: string,\n path: string,\n schema: z.ZodType<T, z.ZodTypeDef, unknown>,\n body?: unknown,\n ): Promise<T> {\n const res = await this.fetchImpl(`${this.baseUrl}${path}`, {\n method,\n headers: body === undefined ? undefined : { 'content-type': 'application/json' },\n body: body === undefined ? undefined : JSON.stringify(body),\n });\n if (!res.ok) {\n const payload = await res\n .clone()\n .json()\n .catch(() => res.text().catch(() => undefined));\n throw new EngineError(res.status, payload);\n }\n if (res.status === 204) return schema.parse(undefined);\n return schema.parse(await res.json());\n }\n\n health(): Promise<z.infer<typeof Health>> {\n return this.request('GET', '/health', Health);\n }\n\n registerAgent(input: {\n orgId: string;\n name: string;\n erc8004Id?: string;\n wallets?: Agent['wallets'];\n }): Promise<Agent> {\n return this.request('POST', '/v1/agents', Agent, input);\n }\n\n listAgents(): Promise<Agent[]> {\n return this.request('GET', '/v1/agents', z.array(Agent));\n }\n\n freeze(agentId: string): Promise<void> {\n return this.request('POST', `/v1/agents/${agentId}/freeze`, z.void());\n }\n\n unfreeze(agentId: string): Promise<void> {\n return this.request('POST', `/v1/agents/${agentId}/unfreeze`, z.void());\n }\n\n addPolicy(policy: z.input<typeof Policy>): Promise<Policy> {\n return this.request('POST', '/v1/policies', Policy, policy);\n }\n\n listPolicies(): Promise<Policy[]> {\n return this.request('GET', '/v1/policies', z.array(Policy));\n }\n\n /** The hot path: submit an intent, get the normalized intent + signed decision. */\n evaluate(submission: IntentSubmission): Promise<EvaluateResponse> {\n return this.request('POST', '/v1/evaluate', EvaluateResponse, submission);\n }\n\n decisions(): Promise<Decision[]> {\n return this.request('GET', '/v1/decisions', z.array(Decision));\n }\n}\n","import { z } from 'zod';\nimport { Chain, Asset, type TaskContext, type Vendor } from '@reinconsole/core';\n\n/**\n * x402 wire shapes (spec v1), mock-first: these schemas are what Rein's mock\n * facilitator and tests speak today, and they track the published x402 spec so\n * real vendors parse identically when the live integration lands.\n */\n\n/** One way to pay, as offered inside a 402 response body. */\nexport const PaymentRequirement = z.object({\n scheme: z.string(),\n network: z.string(),\n /** Amount in the asset's atomic units (e.g. \"10000\" = 0.01 USDC at 6 decimals). */\n maxAmountRequired: z.string().regex(/^\\d+$/, 'atomic amount must be an integer string'),\n resource: z.string().optional(),\n description: z.string().optional(),\n mimeType: z.string().optional(),\n payTo: z.string().min(1),\n maxTimeoutSeconds: z.number().optional(),\n /** Token contract address — or, mock-first, a plain symbol like \"USDC\". */\n asset: z.string().min(1),\n extra: z.record(z.unknown()).optional(),\n});\nexport type PaymentRequirement = z.infer<typeof PaymentRequirement>;\n\n/** The full 402 body a paywalled vendor returns. */\nexport const PaymentRequired = z.object({\n x402Version: z.number(),\n accepts: z.array(PaymentRequirement).min(1),\n error: z.string().optional(),\n});\nexport type PaymentRequired = z.infer<typeof PaymentRequired>;\n\n/**\n * x402 network ids → the chains Rein governs. Testnets map to their mainnet.\n * Both v1 names (\"base-sepolia\") and v2 CAIP-2 ids (\"eip155:84532\") appear in\n * the wild, so the guard accepts either.\n */\nconst NETWORK_TO_CHAIN: Record<string, Chain> = {\n base: 'base',\n 'base-sepolia': 'base',\n 'eip155:8453': 'base',\n 'eip155:84532': 'base',\n solana: 'solana',\n 'solana-devnet': 'solana',\n polygon: 'polygon',\n 'polygon-amoy': 'polygon',\n bnb: 'bnb',\n bsc: 'bnb',\n};\n\n/** Canonical stablecoin contract addresses (EVM keys lowercased). */\nconst KNOWN_ASSET_ADDRESSES: Record<string, Asset> = {\n '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913': 'USDC', // USDC on Base\n '0x036cbd53842c5426634e7929541ec2318f3dcf7e': 'USDC', // USDC on Base Sepolia\n EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v: 'USDC', // USDC on Solana\n};\n\nexport function networkToChain(network: string): Chain | undefined {\n return NETWORK_TO_CHAIN[network.toLowerCase()];\n}\n\n/**\n * Resolve a requirement's asset to a symbol Rein knows. Tries, in order: the\n * asset field as a literal symbol (mock-first), `extra.symbol`, then known\n * contract addresses (exact case for Solana, lowercased for EVM), then any\n * caller-supplied address map.\n */\nexport function resolveAsset(\n requirement: PaymentRequirement,\n extraAddresses: Record<string, Asset> = {},\n): Asset | undefined {\n const direct = Asset.safeParse(requirement.asset.toUpperCase());\n if (direct.success) return direct.data;\n\n const symbol = requirement.extra?.['symbol'];\n if (typeof symbol === 'string') {\n const fromExtra = Asset.safeParse(symbol.toUpperCase());\n if (fromExtra.success) return fromExtra.data;\n }\n\n return (\n extraAddresses[requirement.asset] ??\n extraAddresses[requirement.asset.toLowerCase()] ??\n KNOWN_ASSET_ADDRESSES[requirement.asset] ??\n KNOWN_ASSET_ADDRESSES[requirement.asset.toLowerCase()]\n );\n}\n\n/**\n * Convert an atomic-unit amount to a normalized decimal string without floats,\n * e.g. (\"10000\", 6) -> \"0.01\". Stablecoins Rein supports all use 6 decimals;\n * a requirement can override via `extra.decimals`.\n */\nexport function atomicToDecimal(atomic: string, decimals: number): string {\n if (!/^\\d+$/.test(atomic)) throw new TypeError(`invalid atomic amount: ${atomic}`);\n if (decimals === 0) return atomic.replace(/^0+(?=\\d)/, '');\n const digits = atomic.padStart(decimals + 1, '0');\n const intPart = digits.slice(0, digits.length - decimals).replace(/^0+(?=\\d)/, '');\n const fracPart = digits.slice(digits.length - decimals).replace(/0+$/, '');\n return fracPart.length > 0 ? `${intPart}.${fracPart}` : intPart;\n}\n\n/**\n * The inverse of {@link atomicToDecimal}: a human-unit decimal string to atomic\n * units without floats, e.g. (\"0.05\", 6) -> \"50000\". Throws if the value has\n * more fraction digits than the asset carries (sub-atomic precision is a\n * pricing bug, not something to round silently).\n */\nexport function decimalToAtomic(decimal: string, decimals: number): string {\n if (!/^\\d+(\\.\\d+)?$/.test(decimal)) throw new TypeError(`invalid decimal amount: ${decimal}`);\n const dot = decimal.indexOf('.');\n const intPart = dot === -1 ? decimal : decimal.slice(0, dot);\n const fracPart = dot === -1 ? '' : decimal.slice(dot + 1);\n if (fracPart.length > decimals) {\n throw new TypeError(`amount ${decimal} has more than ${decimals} fraction digits`);\n }\n const atomic = intPart + fracPart.padEnd(decimals, '0');\n return atomic.replace(/^0+(?=\\d)/, '');\n}\n\nexport function requirementDecimals(requirement: PaymentRequirement): number {\n const decimals = requirement.extra?.['decimals'];\n return typeof decimals === 'number' && Number.isInteger(decimals) && decimals >= 0 ? decimals : 6;\n}\n\n/** A requirement the guard fully understood, mapped into Rein's domain. */\nexport interface ResolvedRequirement {\n requirement: PaymentRequirement;\n chain: Chain;\n asset: Asset;\n /** Human-unit decimal amount, e.g. \"0.01\". */\n amount: string;\n}\n\n/**\n * Pick the first offer the guard can govern: scheme `exact`, a network that\n * maps to a supported chain, and a resolvable asset. Returns undefined when\n * no offer qualifies — callers must treat that as fail-closed.\n */\nexport function selectRequirement(\n accepts: readonly PaymentRequirement[],\n extraAddresses: Record<string, Asset> = {},\n): ResolvedRequirement | undefined {\n for (const requirement of accepts) {\n if (requirement.scheme.toLowerCase() !== 'exact') continue;\n const chain = networkToChain(requirement.network);\n if (!chain) continue;\n const asset = resolveAsset(requirement, extraAddresses);\n if (!asset) continue;\n const amount = atomicToDecimal(requirement.maxAmountRequired, requirementDecimals(requirement));\n return { requirement, chain, asset, amount };\n }\n return undefined;\n}\n\n/** What the guard submits to the policy engine (the `/v1/evaluate` shape). */\nexport interface IntentSubmission {\n agentId: string;\n vendor: Vendor;\n resource: string;\n amount: string;\n asset: Asset;\n chain: Chain;\n taskContext?: TaskContext;\n}\n\n/** Build the evaluate payload for a resolved offer on a given request URL. */\nexport function toIntentSubmission(\n resolved: ResolvedRequirement,\n url: string,\n agentId: string,\n taskContext: TaskContext | undefined,\n): IntentSubmission {\n const parsed = new URL(url);\n return {\n agentId,\n vendor: {\n host: parsed.host,\n address: resolved.requirement.payTo,\n },\n resource: resolved.requirement.resource ?? parsed.pathname,\n amount: resolved.amount,\n asset: resolved.asset,\n chain: resolved.chain,\n taskContext,\n };\n}\n","import { AsyncLocalStorage } from 'node:async_hooks';\nimport {\n AgentId,\n Receipt,\n newId,\n type Asset,\n type Decision,\n type PaymentIntent,\n type ReceiptSettlement,\n type TaskContext,\n} from '@reinconsole/core';\nimport { EngineClient, type FetchLike } from './client.js';\nimport { PaymentBlockedError, UnsupportedRequirementError } from './errors.js';\nimport {\n PaymentRequired,\n selectRequirement,\n toIntentSubmission,\n type PaymentRequirement,\n} from './x402.js';\n\n/**\n * Builds the `X-PAYMENT` header for an allowed intent. Mock payers and the\n * local EIP-3009 payer ignore the decision; the session-key signer tier\n * requires it — the {intent, decision} pair is the engine-signed voucher the\n * signer verifies before any key is put to work.\n */\nexport type Payer = (\n requirement: PaymentRequirement,\n intent: PaymentIntent,\n decision: Decision,\n) => string | Promise<string>;\n\nexport interface GuardOptions {\n /** Policy engine base URL, e.g. \"http://localhost:8787\". */\n engineUrl: string;\n /** The agent this guard speaks for (must be registered with the engine). */\n agentId: string;\n /** Base fetch the guard wraps by default (vendor-facing). Defaults to global fetch. */\n fetch?: FetchLike;\n /** Transport for talking to the policy engine. Defaults to global fetch. */\n engineFetch?: FetchLike;\n /** Task context attached to every intent unless overridden via withTask(). */\n taskContext?: TaskContext;\n /**\n * What a blocked payment looks like to the caller: 'throw' (default) raises\n * PaymentBlockedError; 'respond' returns a synthetic 402 JSON response, for\n * agent loops that prefer inspecting responses over catching.\n */\n onBlocked?: 'throw' | 'respond';\n /** If set, the guard settles allowed payments itself (pay + retry). */\n payer?: Payer;\n /** Extra token-address -> symbol mappings for asset resolution. */\n assetAddresses?: Record<string, Asset>;\n /** Called once per receipt, as it is recorded. */\n onReceipt?: (receipt: Receipt) => void;\n}\n\n/**\n * The Rein guard: wrap an agent's fetch once, and every x402 paywall it hits\n * is policy-checked before any payment exists, with a receipt either way.\n *\n * Layering: the guard wraps the BASE fetch, underneath any x402 payment\n * library. The first (unpaid) request surfaces the 402; the guard evaluates\n * it and either blocks — so the payment layer never sees the paywall — or\n * releases the 402 upward. The payment layer's `X-PAYMENT` retry then flows\n * back through the guard, which attaches the settlement to the receipt.\n * Alternatively, pass a `payer` and the guard completes the payment itself.\n */\nexport class Guard {\n readonly client: EngineClient;\n private readonly options: GuardOptions;\n private readonly baseFetch: FetchLike;\n private readonly task = new AsyncLocalStorage<TaskContext>();\n private readonly log: Receipt[] = [];\n /** Allowed-but-unsettled receipts awaiting the payment layer's retry, by URL. */\n private readonly pendingByUrl = new Map<string, Receipt>();\n\n constructor(options: GuardOptions) {\n AgentId.parse(options.agentId);\n this.options = options;\n const f = options.fetch ?? globalThis.fetch;\n this.baseFetch = (input, init) => f(input, init);\n this.client = new EngineClient({ baseUrl: options.engineUrl, fetch: options.engineFetch });\n }\n\n /** Every receipt this guard has recorded, oldest first. */\n receipts(): readonly Receipt[] {\n return this.log;\n }\n\n /** Run `fn` with a task context attached to every intent submitted inside it. */\n withTask<T>(context: TaskContext, fn: () => T): T {\n return this.task.run({ ...this.options.taskContext, ...context }, fn);\n }\n\n /**\n * The one-liner: returns a fetch-compatible function that enforces policy on\n * every x402 paywall. Wraps the guard's base fetch unless one is passed.\n */\n wrap(fetchImpl?: FetchLike): FetchLike {\n const inner: FetchLike = fetchImpl ? (input, init) => fetchImpl(input, init) : this.baseFetch;\n\n return async (input, init) => {\n const url = requestUrl(input);\n // A request that already carries a payment is the release leg of an\n // intent this guard allowed — pass it through and capture settlement.\n if (readHeader(input, init, 'X-PAYMENT') !== null) {\n const res = await inner(input, init);\n this.settlePending(url, res);\n return res;\n }\n\n const res = await inner(input, init);\n if (res.status !== 402) return res;\n\n const body = await res\n .clone()\n .json()\n .catch(() => undefined);\n const parsed = PaymentRequired.safeParse(body);\n // Not an x402 paywall — nothing to govern, hand it back untouched.\n if (!parsed.success) return res;\n\n const resolved = selectRequirement(parsed.data.accepts, this.options.assetAddresses);\n if (!resolved) throw new UnsupportedRequirementError(url);\n\n const taskContext = this.task.getStore() ?? this.options.taskContext;\n const submission = toIntentSubmission(resolved, url, this.options.agentId, taskContext);\n const { intent, decision } = await this.client.evaluate(submission);\n\n if (decision.outcome !== 'allow') {\n const receipt = this.record(intent, decision, url, init);\n if (this.options.onBlocked === 'respond') return blockedResponse(receipt);\n throw new PaymentBlockedError(intent, decision, receipt);\n }\n\n if (!this.options.payer) {\n // Advisory mode: release the 402 to the payment layer above us; its\n // X-PAYMENT retry will come back through and settle the receipt.\n const receipt = this.record(intent, decision, url, init);\n this.pendingByUrl.set(url, receipt);\n return res;\n }\n\n const paymentHeader = await this.options.payer(resolved.requirement, intent, decision);\n const retry = await inner(input, withHeader(input, init, 'X-PAYMENT', paymentHeader));\n this.record(intent, decision, url, init, parseSettlement(retry));\n return retry;\n };\n }\n\n private record(\n intent: PaymentIntent,\n decision: Decision,\n url: string,\n init: RequestInit | undefined,\n settlement?: ReceiptSettlement,\n ): Receipt {\n const receipt = Receipt.parse({\n id: newId('rcp'),\n agentId: intent.agentId,\n intentId: intent.id,\n decisionId: decision.id,\n outcome: decision.outcome,\n url,\n method: init?.method ?? 'GET',\n vendorHost: intent.vendor.host,\n amount: intent.amount,\n asset: intent.asset,\n chain: intent.chain,\n taskContext: intent.taskContext,\n reason: decision.reason,\n settlement,\n createdAt: new Date(),\n });\n this.log.push(receipt);\n this.options.onReceipt?.(receipt);\n return receipt;\n }\n\n private settlePending(url: string, res: Response): void {\n const receipt = this.pendingByUrl.get(url);\n if (!receipt || !res.ok) return;\n const settlement = parseSettlement(res);\n if (settlement) receipt.settlement = settlement;\n this.pendingByUrl.delete(url);\n }\n}\n\n/** Convenience factory mirroring the docs: `const guard = createGuard({...})`. */\nexport function createGuard(options: GuardOptions): Guard {\n return new Guard(options);\n}\n\nfunction requestUrl(input: string | URL | Request): string {\n if (typeof input === 'string') return input;\n if (input instanceof URL) return input.toString();\n return input.url;\n}\n\nfunction readHeader(\n input: string | URL | Request,\n init: RequestInit | undefined,\n name: string,\n): string | null {\n const source = init?.headers ?? (input instanceof Request ? input.headers : undefined);\n return source === undefined ? null : new Headers(source).get(name);\n}\n\nfunction withHeader(\n input: string | URL | Request,\n init: RequestInit | undefined,\n name: string,\n value: string,\n): RequestInit {\n const headers = new Headers(\n init?.headers ?? (input instanceof Request ? input.headers : undefined),\n );\n headers.set(name, value);\n return { ...init, headers };\n}\n\n/**\n * Decode the vendor's `X-PAYMENT-RESPONSE` header (base64 JSON per the x402\n * spec; plain JSON tolerated mock-first). Absent or undecodable -> undefined.\n */\nfunction parseSettlement(res: Response): ReceiptSettlement | undefined {\n const raw = res.headers.get('X-PAYMENT-RESPONSE');\n if (raw === null) return undefined;\n let payload: unknown;\n try {\n payload = JSON.parse(raw);\n } catch {\n try {\n payload = JSON.parse(Buffer.from(raw, 'base64').toString('utf8'));\n } catch {\n return { raw };\n }\n }\n const record =\n typeof payload === 'object' && payload !== null ? (payload as Record<string, unknown>) : {};\n return {\n txHash: typeof record['transaction'] === 'string' ? record['transaction'] : undefined,\n networkId: typeof record['network'] === 'string' ? record['network'] : undefined,\n raw,\n };\n}\n\nfunction blockedResponse(receipt: Receipt): Response {\n return new Response(\n JSON.stringify({\n error: 'payment_blocked_by_rein',\n outcome: receipt.outcome,\n reason: receipt.reason,\n intentId: receipt.intentId,\n decisionId: receipt.decisionId,\n receiptId: receipt.id,\n }),\n {\n status: 402,\n headers: { 'content-type': 'application/json', 'x-rein-outcome': receipt.outcome },\n },\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/client.ts","../src/x402.ts","../src/x402v2.ts","../src/guard.ts"],"names":["z","PaymentIntent","Decision","Agent","Policy","Asset","AsyncLocalStorage","AgentId","res","Receipt","newId"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { Decision, PaymentIntent, Receipt } from '@reinconsole/core';\n\n/** Base class for everything the SDK throws, so callers can catch broadly. */\nexport class ReinError extends Error {\n constructor(message: string) {\n super(message);\n this.name = new.target.name;\n }\n}\n\n/** The policy engine answered with a non-2xx status. */\nexport class EngineError extends ReinError {\n constructor(\n readonly status: number,\n readonly body: unknown,\n message = `policy engine responded ${status}`,\n ) {\n super(message);\n }\n}\n\n/**\n * The engine evaluated the intent and did NOT allow it (deny or escalate —\n * v0.1 blocks both; escalation approval flows land later). The payment was\n * never constructed, so no funds moved. Carries the full evidence trail.\n */\nexport class PaymentBlockedError extends ReinError {\n constructor(\n readonly intent: PaymentIntent,\n readonly decision: Decision,\n readonly receipt: Receipt,\n ) {\n super(\n `rein blocked payment of ${intent.amount} ${intent.asset} to ${intent.vendor.host}: ` +\n `${decision.outcome}${decision.reason ? ` (${decision.reason})` : ''}`,\n );\n }\n}\n\n/**\n * The vendor's 402 was x402-shaped but offered no requirement the guard can\n * govern (unknown scheme/network/asset). The guard fails closed rather than\n * letting an ungoverned payment through.\n */\nexport class UnsupportedRequirementError extends ReinError {\n constructor(readonly url: string) {\n super(`no supported x402 payment requirement in 402 from ${url}; failing closed`);\n }\n}\n","import { z } from 'zod';\nimport { Agent, Decision, PaymentIntent, Policy } from '@reinconsole/core';\nimport { EngineError } from './errors.js';\nimport type { IntentSubmission } from './x402.js';\n\n/** Any fetch-compatible function (global fetch, undici, or a test double). */\nexport type FetchLike = (input: string | URL | Request, init?: RequestInit) => Promise<Response>;\n\nconst Health = z.object({ status: z.string(), publicKey: z.string() });\nconst EvaluateResponse = z.object({ intent: PaymentIntent, decision: Decision });\nexport type EvaluateResponse = z.infer<typeof EvaluateResponse>;\n\nexport interface EngineClientOptions {\n /** Base URL of the policy engine, e.g. \"http://localhost:8787\". */\n baseUrl: string;\n /** Override the transport (tests, custom agents). Defaults to global fetch. */\n fetch?: FetchLike;\n}\n\n/**\n * Thin typed client for the policy-engine HTTP API. Every response is parsed\n * through the @reinconsole/core schemas, so wire drift fails loudly at the boundary.\n */\nexport class EngineClient {\n private readonly baseUrl: string;\n private readonly fetchImpl: FetchLike;\n\n constructor(options: EngineClientOptions) {\n this.baseUrl = options.baseUrl.replace(/\\/+$/, '');\n const f = options.fetch ?? globalThis.fetch;\n this.fetchImpl = (input, init) => f(input, init);\n }\n\n private async request<T>(\n method: string,\n path: string,\n schema: z.ZodType<T, z.ZodTypeDef, unknown>,\n body?: unknown,\n ): Promise<T> {\n const res = await this.fetchImpl(`${this.baseUrl}${path}`, {\n method,\n headers: body === undefined ? undefined : { 'content-type': 'application/json' },\n body: body === undefined ? undefined : JSON.stringify(body),\n });\n if (!res.ok) {\n const payload = await res\n .clone()\n .json()\n .catch(() => res.text().catch(() => undefined));\n throw new EngineError(res.status, payload);\n }\n if (res.status === 204) return schema.parse(undefined);\n return schema.parse(await res.json());\n }\n\n health(): Promise<z.infer<typeof Health>> {\n return this.request('GET', '/health', Health);\n }\n\n registerAgent(input: {\n orgId: string;\n name: string;\n erc8004Id?: string;\n wallets?: Agent['wallets'];\n }): Promise<Agent> {\n return this.request('POST', '/v1/agents', Agent, input);\n }\n\n listAgents(): Promise<Agent[]> {\n return this.request('GET', '/v1/agents', z.array(Agent));\n }\n\n freeze(agentId: string): Promise<void> {\n return this.request('POST', `/v1/agents/${agentId}/freeze`, z.void());\n }\n\n unfreeze(agentId: string): Promise<void> {\n return this.request('POST', `/v1/agents/${agentId}/unfreeze`, z.void());\n }\n\n addPolicy(policy: z.input<typeof Policy>): Promise<Policy> {\n return this.request('POST', '/v1/policies', Policy, policy);\n }\n\n listPolicies(): Promise<Policy[]> {\n return this.request('GET', '/v1/policies', z.array(Policy));\n }\n\n /** The hot path: submit an intent, get the normalized intent + signed decision. */\n evaluate(submission: IntentSubmission): Promise<EvaluateResponse> {\n return this.request('POST', '/v1/evaluate', EvaluateResponse, submission);\n }\n\n decisions(): Promise<Decision[]> {\n return this.request('GET', '/v1/decisions', z.array(Decision));\n }\n}\n","import { z } from 'zod';\nimport { Chain, Asset, type TaskContext, type Vendor } from '@reinconsole/core';\n\n/**\n * x402 wire shapes (spec v1), mock-first: these schemas are what Rein's mock\n * facilitator and tests speak today, and they track the published x402 spec so\n * real vendors parse identically when the live integration lands.\n */\n\n/** One way to pay, as offered inside a 402 response body. */\nexport const PaymentRequirement = z.object({\n scheme: z.string(),\n network: z.string(),\n /** Amount in the asset's atomic units (e.g. \"10000\" = 0.01 USDC at 6 decimals). */\n maxAmountRequired: z.string().regex(/^\\d+$/, 'atomic amount must be an integer string'),\n resource: z.string().optional(),\n description: z.string().optional(),\n mimeType: z.string().optional(),\n payTo: z.string().min(1),\n maxTimeoutSeconds: z.number().optional(),\n /** Token contract address — or, mock-first, a plain symbol like \"USDC\". */\n asset: z.string().min(1),\n extra: z.record(z.unknown()).optional(),\n});\nexport type PaymentRequirement = z.infer<typeof PaymentRequirement>;\n\n/** The full 402 body a paywalled vendor returns. */\nexport const PaymentRequired = z.object({\n x402Version: z.number(),\n accepts: z.array(PaymentRequirement).min(1),\n error: z.string().optional(),\n});\nexport type PaymentRequired = z.infer<typeof PaymentRequired>;\n\n/**\n * x402 network ids → the chains Rein governs. Testnets map to their mainnet.\n * Both v1 names (\"base-sepolia\") and v2 CAIP-2 ids (\"eip155:84532\") appear in\n * the wild, so the guard accepts either.\n */\nconst NETWORK_TO_CHAIN: Record<string, Chain> = {\n base: 'base',\n 'base-sepolia': 'base',\n 'eip155:8453': 'base',\n 'eip155:84532': 'base',\n solana: 'solana',\n 'solana-devnet': 'solana',\n polygon: 'polygon',\n 'polygon-amoy': 'polygon',\n bnb: 'bnb',\n bsc: 'bnb',\n};\n\n/** Canonical stablecoin contract addresses (EVM keys lowercased). */\nconst KNOWN_ASSET_ADDRESSES: Record<string, Asset> = {\n '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913': 'USDC', // USDC on Base\n '0x036cbd53842c5426634e7929541ec2318f3dcf7e': 'USDC', // USDC on Base Sepolia\n EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v: 'USDC', // USDC on Solana\n};\n\nexport function networkToChain(network: string): Chain | undefined {\n return NETWORK_TO_CHAIN[network.toLowerCase()];\n}\n\n/**\n * Resolve a requirement's asset to a symbol Rein knows. Tries, in order: the\n * asset field as a literal symbol (mock-first), `extra.symbol`, then known\n * contract addresses (exact case for Solana, lowercased for EVM), then any\n * caller-supplied address map.\n */\nexport function resolveAsset(\n requirement: PaymentRequirement,\n extraAddresses: Record<string, Asset> = {},\n): Asset | undefined {\n const direct = Asset.safeParse(requirement.asset.toUpperCase());\n if (direct.success) return direct.data;\n\n const symbol = requirement.extra?.['symbol'];\n if (typeof symbol === 'string') {\n const fromExtra = Asset.safeParse(symbol.toUpperCase());\n if (fromExtra.success) return fromExtra.data;\n }\n\n return (\n extraAddresses[requirement.asset] ??\n extraAddresses[requirement.asset.toLowerCase()] ??\n KNOWN_ASSET_ADDRESSES[requirement.asset] ??\n KNOWN_ASSET_ADDRESSES[requirement.asset.toLowerCase()]\n );\n}\n\n/**\n * Convert an atomic-unit amount to a normalized decimal string without floats,\n * e.g. (\"10000\", 6) -> \"0.01\". Stablecoins Rein supports all use 6 decimals;\n * a requirement can override via `extra.decimals`.\n */\nexport function atomicToDecimal(atomic: string, decimals: number): string {\n if (!/^\\d+$/.test(atomic)) throw new TypeError(`invalid atomic amount: ${atomic}`);\n if (decimals === 0) return atomic.replace(/^0+(?=\\d)/, '');\n const digits = atomic.padStart(decimals + 1, '0');\n const intPart = digits.slice(0, digits.length - decimals).replace(/^0+(?=\\d)/, '');\n const fracPart = digits.slice(digits.length - decimals).replace(/0+$/, '');\n return fracPart.length > 0 ? `${intPart}.${fracPart}` : intPart;\n}\n\n/**\n * The inverse of {@link atomicToDecimal}: a human-unit decimal string to atomic\n * units without floats, e.g. (\"0.05\", 6) -> \"50000\". Throws if the value has\n * more fraction digits than the asset carries (sub-atomic precision is a\n * pricing bug, not something to round silently).\n */\nexport function decimalToAtomic(decimal: string, decimals: number): string {\n if (!/^\\d+(\\.\\d+)?$/.test(decimal)) throw new TypeError(`invalid decimal amount: ${decimal}`);\n const dot = decimal.indexOf('.');\n const intPart = dot === -1 ? decimal : decimal.slice(0, dot);\n const fracPart = dot === -1 ? '' : decimal.slice(dot + 1);\n if (fracPart.length > decimals) {\n throw new TypeError(`amount ${decimal} has more than ${decimals} fraction digits`);\n }\n const atomic = intPart + fracPart.padEnd(decimals, '0');\n return atomic.replace(/^0+(?=\\d)/, '');\n}\n\nexport function requirementDecimals(requirement: PaymentRequirement): number {\n const decimals = requirement.extra?.['decimals'];\n return typeof decimals === 'number' && Number.isInteger(decimals) && decimals >= 0 ? decimals : 6;\n}\n\n/** A requirement the guard fully understood, mapped into Rein's domain. */\nexport interface ResolvedRequirement {\n requirement: PaymentRequirement;\n chain: Chain;\n asset: Asset;\n /** Human-unit decimal amount, e.g. \"0.01\". */\n amount: string;\n}\n\n/**\n * Pick the first offer the guard can govern: scheme `exact`, a network that\n * maps to a supported chain, and a resolvable asset. Returns undefined when\n * no offer qualifies — callers must treat that as fail-closed.\n */\nexport function selectRequirement(\n accepts: readonly PaymentRequirement[],\n extraAddresses: Record<string, Asset> = {},\n): ResolvedRequirement | undefined {\n for (const requirement of accepts) {\n if (requirement.scheme.toLowerCase() !== 'exact') continue;\n const chain = networkToChain(requirement.network);\n if (!chain) continue;\n const asset = resolveAsset(requirement, extraAddresses);\n if (!asset) continue;\n const amount = atomicToDecimal(requirement.maxAmountRequired, requirementDecimals(requirement));\n return { requirement, chain, asset, amount };\n }\n return undefined;\n}\n\n/** What the guard submits to the policy engine (the `/v1/evaluate` shape). */\nexport interface IntentSubmission {\n agentId: string;\n vendor: Vendor;\n resource: string;\n amount: string;\n asset: Asset;\n chain: Chain;\n taskContext?: TaskContext;\n}\n\n/** Build the evaluate payload for a resolved offer on a given request URL. */\nexport function toIntentSubmission(\n resolved: ResolvedRequirement,\n url: string,\n agentId: string,\n taskContext: TaskContext | undefined,\n): IntentSubmission {\n const parsed = new URL(url);\n return {\n agentId,\n vendor: {\n host: parsed.host,\n address: resolved.requirement.payTo,\n },\n resource: resolved.requirement.resource ?? parsed.pathname,\n amount: resolved.amount,\n asset: resolved.asset,\n chain: resolved.chain,\n taskContext,\n };\n}\n","import { z } from 'zod';\nimport { PaymentRequirement } from './x402.js';\n\n/**\n * x402 v2 wire dialect — CAIP-2 network ids, `PAYMENT-REQUIRED` /\n * `PAYMENT-SIGNATURE` / `PAYMENT-RESPONSE` headers, base64-JSON payloads.\n * Verified against the published spec (coinbase/x402\n * specs/x402-specification-v2.md + transports-v2/http.md, re-checked 2026-07)\n * and the live facilitator's /supported.\n *\n * Rein's internal requirement shape stays v1 (the zod contract in x402.ts);\n * v2 is a WIRE dialect converted at the edges. Inbound, the guard converts a\n * PAYMENT-REQUIRED quote into internal requirements. Outbound, it REWRAPS the\n * payer's v1 X-PAYMENT envelope into the v2 PaymentPayload: the scheme payload\n * (e.g. the signed EIP-3009 authorization) is byte-identical in both dialects,\n * so every Payer — mock, EIP-3009, session-signer — is v2-capable without\n * knowing v2 exists. The vendor side (@reinconsole/gate) re-exports these\n * helpers rather than owning its own copies.\n */\n\n/**\n * Known v1 network names → CAIP-2. EVM entries are chain-id math; the Solana\n * ids are what the live facilitator advertises. Unknown names pass through\n * lowercased, so two spellings of an UNKNOWN network still compare equal.\n */\nconst CAIP2_ALIASES: Record<string, string> = {\n base: 'eip155:8453',\n 'base-sepolia': 'eip155:84532',\n polygon: 'eip155:137',\n 'polygon-amoy': 'eip155:80002',\n bnb: 'eip155:56',\n bsc: 'eip155:56',\n solana: 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp',\n 'solana-devnet': 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1',\n};\n\n/** The CAIP-2 id for a network name, or the lowercased name when unknown. */\nexport function caip2Of(network: string): string {\n const key = network.toLowerCase();\n return CAIP2_ALIASES[key] ?? key;\n}\n\n/** Do two network ids name the same chain, across the v1/CAIP-2 divide? */\nexport function sameNetwork(a: string, b: string): boolean {\n return caip2Of(a) === caip2Of(b);\n}\n\n/** x402 v2 PaymentRequirements (one entry of a 402's `accepts`). */\nexport const PaymentRequirementsV2 = z.object({\n scheme: z.string(),\n /** CAIP-2, e.g. \"eip155:84532\". */\n network: z.string(),\n /** Atomic units — v2's rename of v1's maxAmountRequired. */\n amount: z.string().regex(/^\\d+$/, 'atomic amount must be an integer string'),\n asset: z.string().min(1),\n payTo: z.string().min(1),\n maxTimeoutSeconds: z.number().optional(),\n extra: z.record(z.unknown()).optional(),\n});\nexport type PaymentRequirementsV2 = z.infer<typeof PaymentRequirementsV2>;\n\n/** v2 ResourceInfo — resource facts move out of the requirement in v2. */\nexport const ResourceInfoV2 = z.object({\n url: z.string(),\n description: z.string().optional(),\n mimeType: z.string().optional(),\n});\nexport type ResourceInfoV2 = z.infer<typeof ResourceInfoV2>;\n\n/** v2 PaymentRequired — the decoded PAYMENT-REQUIRED header. */\nexport const PaymentRequiredV2 = z.object({\n x402Version: z.literal(2),\n error: z.string().optional(),\n resource: ResourceInfoV2.optional(),\n accepts: z.array(PaymentRequirementsV2).min(1),\n extensions: z.record(z.unknown()).optional(),\n});\nexport type PaymentRequiredV2 = z.infer<typeof PaymentRequiredV2>;\n\n/** Convert Rein's internal (v1-shaped) requirement to the v2 wire shape. */\nexport function v2Requirements(requirement: PaymentRequirement): PaymentRequirementsV2 {\n return {\n scheme: requirement.scheme,\n network: caip2Of(requirement.network),\n amount: requirement.maxAmountRequired,\n asset: requirement.asset,\n payTo: requirement.payTo,\n ...(requirement.maxTimeoutSeconds !== undefined\n ? { maxTimeoutSeconds: requirement.maxTimeoutSeconds }\n : {}),\n ...(requirement.extra ? { extra: requirement.extra } : {}),\n };\n}\n\n/**\n * The inverse: a v2 offer (plus the 402's shared ResourceInfo) as an internal\n * requirement. The CAIP-2 network id is kept verbatim — networkToChain and\n * chainIdForNetwork resolve both dialects, and sameNetwork compares across\n * them, so nothing downstream needs the v1 spelling back.\n */\nexport function requirementFromV2(\n offer: PaymentRequirementsV2,\n resource?: ResourceInfoV2,\n): PaymentRequirement {\n return PaymentRequirement.parse({\n scheme: offer.scheme,\n network: offer.network,\n maxAmountRequired: offer.amount,\n payTo: offer.payTo,\n asset: offer.asset,\n ...(resource !== undefined ? { resource: resource.url } : {}),\n ...(resource?.description !== undefined ? { description: resource.description } : {}),\n ...(resource?.mimeType !== undefined ? { mimeType: resource.mimeType } : {}),\n ...(offer.maxTimeoutSeconds !== undefined\n ? { maxTimeoutSeconds: offer.maxTimeoutSeconds }\n : {}),\n ...(offer.extra ? { extra: offer.extra } : {}),\n });\n}\n\n/** The full v2 PaymentRequired for one quoted requirement. */\nexport function buildPaymentRequiredV2(\n requirement: PaymentRequirement,\n error: string,\n): PaymentRequiredV2 {\n return {\n x402Version: 2,\n error,\n ...(requirement.resource\n ? {\n resource: {\n url: requirement.resource,\n ...(requirement.description ? { description: requirement.description } : {}),\n ...(requirement.mimeType ? { mimeType: requirement.mimeType } : {}),\n },\n }\n : {}),\n accepts: [v2Requirements(requirement)],\n extensions: {},\n };\n}\n\n/** The one codec every x402 header uses: base64 of compact JSON. */\nexport function encodeBase64Json(value: unknown): string {\n return Buffer.from(JSON.stringify(value)).toString('base64');\n}\n\n/** Base64 JSON → value, or undefined when the header is not decodable. */\nfunction decodeBase64Json(raw: string): unknown {\n try {\n return JSON.parse(Buffer.from(raw, 'base64').toString('utf8'));\n } catch {\n return undefined;\n }\n}\n\n/**\n * Decode a PAYMENT-REQUIRED response header. Lenient by design: a missing,\n * undecodable, or non-v2 header returns undefined so callers fall back to the\n * v1 body — a garbled v2 advertisement must not break a dual-stack 402.\n */\nexport function parsePaymentRequiredHeader(raw: string | null): PaymentRequiredV2 | undefined {\n if (raw === null) return undefined;\n const parsed = PaymentRequiredV2.safeParse(decodeBase64Json(raw));\n return parsed.success ? parsed.data : undefined;\n}\n\n/** The v1 X-PAYMENT envelope, as far as the v2 rewrap needs to see it. */\nconst V1Envelope = z.object({\n x402Version: z.literal(1),\n scheme: z.string(),\n network: z.string(),\n payload: z.record(z.unknown()),\n});\n\n/**\n * Rewrap a payer's v1 X-PAYMENT header as a v2 PaymentPayload for the\n * PAYMENT-SIGNATURE header. The scheme payload transfers verbatim (what the\n * payer signed is envelope-independent); the chosen requirement rides along\n * as `accepted` per the v2 spec. A header that is already a v2 envelope\n * passes through unchanged. Throws TypeError on anything else — a payer\n * returning an unrecognizable header is a programming error, not wire input.\n */\nexport function wrapPaymentV2(\n paymentHeader: string,\n requirement: PaymentRequirement,\n resource?: ResourceInfoV2,\n): string {\n const decoded = decodeBase64Json(paymentHeader);\n if ((decoded as { x402Version?: unknown } | undefined)?.x402Version === 2) {\n return paymentHeader;\n }\n const v1 = V1Envelope.safeParse(decoded);\n if (!v1.success) {\n throw new TypeError(`cannot rewrap payment header as x402 v2: ${v1.error.message}`);\n }\n return encodeBase64Json({\n x402Version: 2,\n ...(resource !== undefined ? { resource } : {}),\n accepted: v2Requirements(requirement),\n payload: v1.data.payload,\n extensions: {},\n });\n}\n","import { AsyncLocalStorage } from 'node:async_hooks';\nimport {\n AgentId,\n Receipt,\n newId,\n type Asset,\n type Decision,\n type PaymentIntent,\n type ReceiptSettlement,\n type TaskContext,\n} from '@reinconsole/core';\nimport { EngineClient, type FetchLike } from './client.js';\nimport { PaymentBlockedError, UnsupportedRequirementError } from './errors.js';\nimport {\n PaymentRequired,\n selectRequirement,\n toIntentSubmission,\n type PaymentRequirement,\n type ResolvedRequirement,\n} from './x402.js';\nimport {\n parsePaymentRequiredHeader,\n requirementFromV2,\n wrapPaymentV2,\n type ResourceInfoV2,\n} from './x402v2.js';\n\n/**\n * Builds the `X-PAYMENT` header for an allowed intent. Mock payers and the\n * local EIP-3009 payer ignore the decision; the session-key signer tier\n * requires it — the {intent, decision} pair is the engine-signed voucher the\n * signer verifies before any key is put to work.\n */\nexport type Payer = (\n requirement: PaymentRequirement,\n intent: PaymentIntent,\n decision: Decision,\n) => string | Promise<string>;\n\nexport interface GuardOptions {\n /** Policy engine base URL, e.g. \"http://localhost:8787\". */\n engineUrl: string;\n /** The agent this guard speaks for (must be registered with the engine). */\n agentId: string;\n /** Base fetch the guard wraps by default (vendor-facing). Defaults to global fetch. */\n fetch?: FetchLike;\n /** Transport for talking to the policy engine. Defaults to global fetch. */\n engineFetch?: FetchLike;\n /** Task context attached to every intent unless overridden via withTask(). */\n taskContext?: TaskContext;\n /**\n * What a blocked payment looks like to the caller: 'throw' (default) raises\n * PaymentBlockedError; 'respond' returns a synthetic 402 JSON response, for\n * agent loops that prefer inspecting responses over catching.\n */\n onBlocked?: 'throw' | 'respond';\n /** If set, the guard settles allowed payments itself (pay + retry). */\n payer?: Payer;\n /** Extra token-address -> symbol mappings for asset resolution. */\n assetAddresses?: Record<string, Asset>;\n /** Called once per receipt, as it is recorded. */\n onReceipt?: (receipt: Receipt) => void;\n}\n\n/**\n * The Rein guard: wrap an agent's fetch once, and every x402 paywall it hits\n * is policy-checked before any payment exists, with a receipt either way.\n *\n * Layering: the guard wraps the BASE fetch, underneath any x402 payment\n * library. The first (unpaid) request surfaces the 402; the guard evaluates\n * it and either blocks — so the payment layer never sees the paywall — or\n * releases the 402 upward. The payment layer's `X-PAYMENT` retry then flows\n * back through the guard, which attaches the settlement to the receipt.\n * Alternatively, pass a `payer` and the guard completes the payment itself.\n */\nexport class Guard {\n readonly client: EngineClient;\n private readonly options: GuardOptions;\n private readonly baseFetch: FetchLike;\n private readonly task = new AsyncLocalStorage<TaskContext>();\n private readonly log: Receipt[] = [];\n /** Allowed-but-unsettled receipts awaiting the payment layer's retry, by URL. */\n private readonly pendingByUrl = new Map<string, Receipt>();\n\n constructor(options: GuardOptions) {\n AgentId.parse(options.agentId);\n this.options = options;\n const f = options.fetch ?? globalThis.fetch;\n this.baseFetch = (input, init) => f(input, init);\n this.client = new EngineClient({ baseUrl: options.engineUrl, fetch: options.engineFetch });\n }\n\n /** Every receipt this guard has recorded, oldest first. */\n receipts(): readonly Receipt[] {\n return this.log;\n }\n\n /** Run `fn` with a task context attached to every intent submitted inside it. */\n withTask<T>(context: TaskContext, fn: () => T): T {\n return this.task.run({ ...this.options.taskContext, ...context }, fn);\n }\n\n /**\n * The one-liner: returns a fetch-compatible function that enforces policy on\n * every x402 paywall. Wraps the guard's base fetch unless one is passed.\n */\n wrap(fetchImpl?: FetchLike): FetchLike {\n const inner: FetchLike = fetchImpl ? (input, init) => fetchImpl(input, init) : this.baseFetch;\n\n return async (input, init) => {\n const url = requestUrl(input);\n // A request that already carries a payment (either dialect's header) is\n // the release leg of an intent this guard allowed — pass it through and\n // capture settlement.\n if (\n readHeader(input, init, 'X-PAYMENT') !== null ||\n readHeader(input, init, 'PAYMENT-SIGNATURE') !== null\n ) {\n const res = await inner(input, init);\n this.settlePending(url, res);\n return res;\n }\n\n const res = await inner(input, init);\n if (res.status !== 402) return res;\n\n const paywall = await parse402(res, this.options.assetAddresses);\n // Not an x402 paywall — nothing to govern, hand it back untouched.\n if (!paywall) return res;\n\n const { resolved, wire, resource } = paywall;\n if (!resolved) throw new UnsupportedRequirementError(url);\n\n const taskContext = this.task.getStore() ?? this.options.taskContext;\n const submission = toIntentSubmission(resolved, url, this.options.agentId, taskContext);\n const { intent, decision } = await this.client.evaluate(submission);\n\n if (decision.outcome !== 'allow') {\n const receipt = this.record(intent, decision, url, init);\n if (this.options.onBlocked === 'respond') return blockedResponse(receipt);\n throw new PaymentBlockedError(intent, decision, receipt);\n }\n\n if (!this.options.payer) {\n // Advisory mode: release the 402 to the payment layer above us; its\n // X-PAYMENT retry will come back through and settle the receipt.\n const receipt = this.record(intent, decision, url, init);\n this.pendingByUrl.set(url, receipt);\n return res;\n }\n\n // The payer always produces the v1 envelope it knows; on a v2 paywall\n // the guard rewraps it (same signed payload, v2 PaymentPayload around\n // it) and pays on the v2 header. Every payer is v2-capable this way.\n const paymentHeader = await this.options.payer(resolved.requirement, intent, decision);\n const retry = await inner(\n input,\n wire === 2\n ? withHeader(\n input,\n init,\n 'PAYMENT-SIGNATURE',\n wrapPaymentV2(paymentHeader, resolved.requirement, resource),\n )\n : withHeader(input, init, 'X-PAYMENT', paymentHeader),\n );\n this.record(intent, decision, url, init, parseSettlement(retry));\n return retry;\n };\n }\n\n private record(\n intent: PaymentIntent,\n decision: Decision,\n url: string,\n init: RequestInit | undefined,\n settlement?: ReceiptSettlement,\n ): Receipt {\n const receipt = Receipt.parse({\n id: newId('rcp'),\n agentId: intent.agentId,\n intentId: intent.id,\n decisionId: decision.id,\n outcome: decision.outcome,\n url,\n method: init?.method ?? 'GET',\n vendorHost: intent.vendor.host,\n amount: intent.amount,\n asset: intent.asset,\n chain: intent.chain,\n taskContext: intent.taskContext,\n reason: decision.reason,\n settlement,\n createdAt: new Date(),\n });\n this.log.push(receipt);\n this.options.onReceipt?.(receipt);\n return receipt;\n }\n\n private settlePending(url: string, res: Response): void {\n const receipt = this.pendingByUrl.get(url);\n if (!receipt || !res.ok) return;\n const settlement = parseSettlement(res);\n if (settlement) receipt.settlement = settlement;\n this.pendingByUrl.delete(url);\n }\n}\n\n/** Convenience factory mirroring the docs: `const guard = createGuard({...})`. */\nexport function createGuard(options: GuardOptions): Guard {\n return new Guard(options);\n}\n\n/** What a 402 offered, in whichever dialect the guard could govern. */\ninterface ParsedPaywall {\n /** The offer the guard selected, or undefined when none qualifies. */\n resolved: ResolvedRequirement | undefined;\n /** Which wire dialect to pay on: 2 = PAYMENT-SIGNATURE, 1 = X-PAYMENT. */\n wire: 1 | 2;\n /** The v2 402's shared resource info, echoed into the payment envelope. */\n resource?: ResourceInfoV2;\n}\n\n/**\n * Read a 402 in both dialects. v2 (the PAYMENT-REQUIRED header) is preferred\n * when it carries an offer the guard can govern; otherwise the v1 body gets\n * its chance — a dual-stack vendor is served on whichever channel works.\n * Returns undefined when neither channel is x402 at all (not a paywall).\n */\nasync function parse402(\n res: Response,\n assetAddresses: Record<string, Asset> | undefined,\n): Promise<ParsedPaywall | undefined> {\n const v2 = parsePaymentRequiredHeader(res.headers.get('PAYMENT-REQUIRED'));\n if (v2) {\n const resolved = selectRequirement(\n v2.accepts.map((offer) => requirementFromV2(offer, v2.resource)),\n assetAddresses,\n );\n if (resolved) {\n return v2.resource !== undefined\n ? { resolved, wire: 2, resource: v2.resource }\n : { resolved, wire: 2 };\n }\n }\n\n const body = await res\n .clone()\n .json()\n .catch(() => undefined);\n const parsed = PaymentRequired.safeParse(body);\n if (parsed.success) {\n return { resolved: selectRequirement(parsed.data.accepts, assetAddresses), wire: 1 };\n }\n // A v2 header alone still marks this as a paywall — one the guard must\n // fail closed on if nothing in it was governable.\n return v2 ? { resolved: undefined, wire: 2 } : undefined;\n}\n\nfunction requestUrl(input: string | URL | Request): string {\n if (typeof input === 'string') return input;\n if (input instanceof URL) return input.toString();\n return input.url;\n}\n\nfunction readHeader(\n input: string | URL | Request,\n init: RequestInit | undefined,\n name: string,\n): string | null {\n const source = init?.headers ?? (input instanceof Request ? input.headers : undefined);\n return source === undefined ? null : new Headers(source).get(name);\n}\n\nfunction withHeader(\n input: string | URL | Request,\n init: RequestInit | undefined,\n name: string,\n value: string,\n): RequestInit {\n const headers = new Headers(\n init?.headers ?? (input instanceof Request ? input.headers : undefined),\n );\n headers.set(name, value);\n return { ...init, headers };\n}\n\n/**\n * Decode the vendor's settlement header — `X-PAYMENT-RESPONSE` (v1) or\n * `PAYMENT-RESPONSE` (v2); base64 JSON per the x402 spec, plain JSON\n * tolerated mock-first. Absent or undecodable -> undefined.\n */\nfunction parseSettlement(res: Response): ReceiptSettlement | undefined {\n const raw = res.headers.get('X-PAYMENT-RESPONSE') ?? res.headers.get('PAYMENT-RESPONSE');\n if (raw === null) return undefined;\n let payload: unknown;\n try {\n payload = JSON.parse(raw);\n } catch {\n try {\n payload = JSON.parse(Buffer.from(raw, 'base64').toString('utf8'));\n } catch {\n return { raw };\n }\n }\n const record =\n typeof payload === 'object' && payload !== null ? (payload as Record<string, unknown>) : {};\n return {\n // A failed v2 settle carries transaction: \"\" — no tx is no txHash.\n txHash:\n typeof record['transaction'] === 'string' && record['transaction'] !== ''\n ? record['transaction']\n : undefined,\n networkId: typeof record['network'] === 'string' ? record['network'] : undefined,\n raw,\n };\n}\n\nfunction blockedResponse(receipt: Receipt): Response {\n return new Response(\n JSON.stringify({\n error: 'payment_blocked_by_rein',\n outcome: receipt.outcome,\n reason: receipt.reason,\n intentId: receipt.intentId,\n decisionId: receipt.decisionId,\n receiptId: receipt.id,\n }),\n {\n status: 402,\n headers: { 'content-type': 'application/json', 'x-rein-outcome': receipt.outcome },\n },\n );\n}\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -468,6 +468,166 @@ declare class Guard {
|
|
|
468
468
|
/** Convenience factory mirroring the docs: `const guard = createGuard({...})`. */
|
|
469
469
|
declare function createGuard(options: GuardOptions): Guard;
|
|
470
470
|
|
|
471
|
+
/** The CAIP-2 id for a network name, or the lowercased name when unknown. */
|
|
472
|
+
declare function caip2Of(network: string): string;
|
|
473
|
+
/** Do two network ids name the same chain, across the v1/CAIP-2 divide? */
|
|
474
|
+
declare function sameNetwork(a: string, b: string): boolean;
|
|
475
|
+
/** x402 v2 PaymentRequirements (one entry of a 402's `accepts`). */
|
|
476
|
+
declare const PaymentRequirementsV2: z.ZodObject<{
|
|
477
|
+
scheme: z.ZodString;
|
|
478
|
+
/** CAIP-2, e.g. "eip155:84532". */
|
|
479
|
+
network: z.ZodString;
|
|
480
|
+
/** Atomic units — v2's rename of v1's maxAmountRequired. */
|
|
481
|
+
amount: z.ZodString;
|
|
482
|
+
asset: z.ZodString;
|
|
483
|
+
payTo: z.ZodString;
|
|
484
|
+
maxTimeoutSeconds: z.ZodOptional<z.ZodNumber>;
|
|
485
|
+
extra: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
486
|
+
}, "strip", z.ZodTypeAny, {
|
|
487
|
+
scheme: string;
|
|
488
|
+
network: string;
|
|
489
|
+
payTo: string;
|
|
490
|
+
asset: string;
|
|
491
|
+
amount: string;
|
|
492
|
+
maxTimeoutSeconds?: number | undefined;
|
|
493
|
+
extra?: Record<string, unknown> | undefined;
|
|
494
|
+
}, {
|
|
495
|
+
scheme: string;
|
|
496
|
+
network: string;
|
|
497
|
+
payTo: string;
|
|
498
|
+
asset: string;
|
|
499
|
+
amount: string;
|
|
500
|
+
maxTimeoutSeconds?: number | undefined;
|
|
501
|
+
extra?: Record<string, unknown> | undefined;
|
|
502
|
+
}>;
|
|
503
|
+
type PaymentRequirementsV2 = z.infer<typeof PaymentRequirementsV2>;
|
|
504
|
+
/** v2 ResourceInfo — resource facts move out of the requirement in v2. */
|
|
505
|
+
declare const ResourceInfoV2: z.ZodObject<{
|
|
506
|
+
url: z.ZodString;
|
|
507
|
+
description: z.ZodOptional<z.ZodString>;
|
|
508
|
+
mimeType: z.ZodOptional<z.ZodString>;
|
|
509
|
+
}, "strip", z.ZodTypeAny, {
|
|
510
|
+
url: string;
|
|
511
|
+
description?: string | undefined;
|
|
512
|
+
mimeType?: string | undefined;
|
|
513
|
+
}, {
|
|
514
|
+
url: string;
|
|
515
|
+
description?: string | undefined;
|
|
516
|
+
mimeType?: string | undefined;
|
|
517
|
+
}>;
|
|
518
|
+
type ResourceInfoV2 = z.infer<typeof ResourceInfoV2>;
|
|
519
|
+
/** v2 PaymentRequired — the decoded PAYMENT-REQUIRED header. */
|
|
520
|
+
declare const PaymentRequiredV2: z.ZodObject<{
|
|
521
|
+
x402Version: z.ZodLiteral<2>;
|
|
522
|
+
error: z.ZodOptional<z.ZodString>;
|
|
523
|
+
resource: z.ZodOptional<z.ZodObject<{
|
|
524
|
+
url: z.ZodString;
|
|
525
|
+
description: z.ZodOptional<z.ZodString>;
|
|
526
|
+
mimeType: z.ZodOptional<z.ZodString>;
|
|
527
|
+
}, "strip", z.ZodTypeAny, {
|
|
528
|
+
url: string;
|
|
529
|
+
description?: string | undefined;
|
|
530
|
+
mimeType?: string | undefined;
|
|
531
|
+
}, {
|
|
532
|
+
url: string;
|
|
533
|
+
description?: string | undefined;
|
|
534
|
+
mimeType?: string | undefined;
|
|
535
|
+
}>>;
|
|
536
|
+
accepts: z.ZodArray<z.ZodObject<{
|
|
537
|
+
scheme: z.ZodString;
|
|
538
|
+
/** CAIP-2, e.g. "eip155:84532". */
|
|
539
|
+
network: z.ZodString;
|
|
540
|
+
/** Atomic units — v2's rename of v1's maxAmountRequired. */
|
|
541
|
+
amount: z.ZodString;
|
|
542
|
+
asset: z.ZodString;
|
|
543
|
+
payTo: z.ZodString;
|
|
544
|
+
maxTimeoutSeconds: z.ZodOptional<z.ZodNumber>;
|
|
545
|
+
extra: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
546
|
+
}, "strip", z.ZodTypeAny, {
|
|
547
|
+
scheme: string;
|
|
548
|
+
network: string;
|
|
549
|
+
payTo: string;
|
|
550
|
+
asset: string;
|
|
551
|
+
amount: string;
|
|
552
|
+
maxTimeoutSeconds?: number | undefined;
|
|
553
|
+
extra?: Record<string, unknown> | undefined;
|
|
554
|
+
}, {
|
|
555
|
+
scheme: string;
|
|
556
|
+
network: string;
|
|
557
|
+
payTo: string;
|
|
558
|
+
asset: string;
|
|
559
|
+
amount: string;
|
|
560
|
+
maxTimeoutSeconds?: number | undefined;
|
|
561
|
+
extra?: Record<string, unknown> | undefined;
|
|
562
|
+
}>, "many">;
|
|
563
|
+
extensions: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
564
|
+
}, "strip", z.ZodTypeAny, {
|
|
565
|
+
x402Version: 2;
|
|
566
|
+
accepts: {
|
|
567
|
+
scheme: string;
|
|
568
|
+
network: string;
|
|
569
|
+
payTo: string;
|
|
570
|
+
asset: string;
|
|
571
|
+
amount: string;
|
|
572
|
+
maxTimeoutSeconds?: number | undefined;
|
|
573
|
+
extra?: Record<string, unknown> | undefined;
|
|
574
|
+
}[];
|
|
575
|
+
resource?: {
|
|
576
|
+
url: string;
|
|
577
|
+
description?: string | undefined;
|
|
578
|
+
mimeType?: string | undefined;
|
|
579
|
+
} | undefined;
|
|
580
|
+
error?: string | undefined;
|
|
581
|
+
extensions?: Record<string, unknown> | undefined;
|
|
582
|
+
}, {
|
|
583
|
+
x402Version: 2;
|
|
584
|
+
accepts: {
|
|
585
|
+
scheme: string;
|
|
586
|
+
network: string;
|
|
587
|
+
payTo: string;
|
|
588
|
+
asset: string;
|
|
589
|
+
amount: string;
|
|
590
|
+
maxTimeoutSeconds?: number | undefined;
|
|
591
|
+
extra?: Record<string, unknown> | undefined;
|
|
592
|
+
}[];
|
|
593
|
+
resource?: {
|
|
594
|
+
url: string;
|
|
595
|
+
description?: string | undefined;
|
|
596
|
+
mimeType?: string | undefined;
|
|
597
|
+
} | undefined;
|
|
598
|
+
error?: string | undefined;
|
|
599
|
+
extensions?: Record<string, unknown> | undefined;
|
|
600
|
+
}>;
|
|
601
|
+
type PaymentRequiredV2 = z.infer<typeof PaymentRequiredV2>;
|
|
602
|
+
/** Convert Rein's internal (v1-shaped) requirement to the v2 wire shape. */
|
|
603
|
+
declare function v2Requirements(requirement: PaymentRequirement): PaymentRequirementsV2;
|
|
604
|
+
/**
|
|
605
|
+
* The inverse: a v2 offer (plus the 402's shared ResourceInfo) as an internal
|
|
606
|
+
* requirement. The CAIP-2 network id is kept verbatim — networkToChain and
|
|
607
|
+
* chainIdForNetwork resolve both dialects, and sameNetwork compares across
|
|
608
|
+
* them, so nothing downstream needs the v1 spelling back.
|
|
609
|
+
*/
|
|
610
|
+
declare function requirementFromV2(offer: PaymentRequirementsV2, resource?: ResourceInfoV2): PaymentRequirement;
|
|
611
|
+
/** The full v2 PaymentRequired for one quoted requirement. */
|
|
612
|
+
declare function buildPaymentRequiredV2(requirement: PaymentRequirement, error: string): PaymentRequiredV2;
|
|
613
|
+
/** The one codec every x402 header uses: base64 of compact JSON. */
|
|
614
|
+
declare function encodeBase64Json(value: unknown): string;
|
|
615
|
+
/**
|
|
616
|
+
* Decode a PAYMENT-REQUIRED response header. Lenient by design: a missing,
|
|
617
|
+
* undecodable, or non-v2 header returns undefined so callers fall back to the
|
|
618
|
+
* v1 body — a garbled v2 advertisement must not break a dual-stack 402.
|
|
619
|
+
*/
|
|
620
|
+
declare function parsePaymentRequiredHeader(raw: string | null): PaymentRequiredV2 | undefined;
|
|
621
|
+
/**
|
|
622
|
+
* Rewrap a payer's v1 X-PAYMENT header as a v2 PaymentPayload for the
|
|
623
|
+
* PAYMENT-SIGNATURE header. The scheme payload transfers verbatim (what the
|
|
624
|
+
* payer signed is envelope-independent); the chosen requirement rides along
|
|
625
|
+
* as `accepted` per the v2 spec. A header that is already a v2 envelope
|
|
626
|
+
* passes through unchanged. Throws TypeError on anything else — a payer
|
|
627
|
+
* returning an unrecognizable header is a programming error, not wire input.
|
|
628
|
+
*/
|
|
629
|
+
declare function wrapPaymentV2(paymentHeader: string, requirement: PaymentRequirement, resource?: ResourceInfoV2): string;
|
|
630
|
+
|
|
471
631
|
/** Base class for everything the SDK throws, so callers can catch broadly. */
|
|
472
632
|
declare class ReinError extends Error {
|
|
473
633
|
constructor(message: string);
|
|
@@ -499,4 +659,4 @@ declare class UnsupportedRequirementError extends ReinError {
|
|
|
499
659
|
constructor(url: string);
|
|
500
660
|
}
|
|
501
661
|
|
|
502
|
-
export { EngineClient, type EngineClientOptions, EngineError, EvaluateResponse, type FetchLike, Guard, type GuardOptions, type IntentSubmission, type Payer, PaymentBlockedError, PaymentRequired, PaymentRequirement, ReinError, type ResolvedRequirement, UnsupportedRequirementError, atomicToDecimal, createGuard, decimalToAtomic, networkToChain, requirementDecimals, resolveAsset, selectRequirement, toIntentSubmission };
|
|
662
|
+
export { EngineClient, type EngineClientOptions, EngineError, EvaluateResponse, type FetchLike, Guard, type GuardOptions, type IntentSubmission, type Payer, PaymentBlockedError, PaymentRequired, PaymentRequiredV2, PaymentRequirement, PaymentRequirementsV2, ReinError, type ResolvedRequirement, ResourceInfoV2, UnsupportedRequirementError, atomicToDecimal, buildPaymentRequiredV2, caip2Of, createGuard, decimalToAtomic, encodeBase64Json, networkToChain, parsePaymentRequiredHeader, requirementDecimals, requirementFromV2, resolveAsset, sameNetwork, selectRequirement, toIntentSubmission, v2Requirements, wrapPaymentV2 };
|
package/dist/index.d.ts
CHANGED
|
@@ -468,6 +468,166 @@ declare class Guard {
|
|
|
468
468
|
/** Convenience factory mirroring the docs: `const guard = createGuard({...})`. */
|
|
469
469
|
declare function createGuard(options: GuardOptions): Guard;
|
|
470
470
|
|
|
471
|
+
/** The CAIP-2 id for a network name, or the lowercased name when unknown. */
|
|
472
|
+
declare function caip2Of(network: string): string;
|
|
473
|
+
/** Do two network ids name the same chain, across the v1/CAIP-2 divide? */
|
|
474
|
+
declare function sameNetwork(a: string, b: string): boolean;
|
|
475
|
+
/** x402 v2 PaymentRequirements (one entry of a 402's `accepts`). */
|
|
476
|
+
declare const PaymentRequirementsV2: z.ZodObject<{
|
|
477
|
+
scheme: z.ZodString;
|
|
478
|
+
/** CAIP-2, e.g. "eip155:84532". */
|
|
479
|
+
network: z.ZodString;
|
|
480
|
+
/** Atomic units — v2's rename of v1's maxAmountRequired. */
|
|
481
|
+
amount: z.ZodString;
|
|
482
|
+
asset: z.ZodString;
|
|
483
|
+
payTo: z.ZodString;
|
|
484
|
+
maxTimeoutSeconds: z.ZodOptional<z.ZodNumber>;
|
|
485
|
+
extra: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
486
|
+
}, "strip", z.ZodTypeAny, {
|
|
487
|
+
scheme: string;
|
|
488
|
+
network: string;
|
|
489
|
+
payTo: string;
|
|
490
|
+
asset: string;
|
|
491
|
+
amount: string;
|
|
492
|
+
maxTimeoutSeconds?: number | undefined;
|
|
493
|
+
extra?: Record<string, unknown> | undefined;
|
|
494
|
+
}, {
|
|
495
|
+
scheme: string;
|
|
496
|
+
network: string;
|
|
497
|
+
payTo: string;
|
|
498
|
+
asset: string;
|
|
499
|
+
amount: string;
|
|
500
|
+
maxTimeoutSeconds?: number | undefined;
|
|
501
|
+
extra?: Record<string, unknown> | undefined;
|
|
502
|
+
}>;
|
|
503
|
+
type PaymentRequirementsV2 = z.infer<typeof PaymentRequirementsV2>;
|
|
504
|
+
/** v2 ResourceInfo — resource facts move out of the requirement in v2. */
|
|
505
|
+
declare const ResourceInfoV2: z.ZodObject<{
|
|
506
|
+
url: z.ZodString;
|
|
507
|
+
description: z.ZodOptional<z.ZodString>;
|
|
508
|
+
mimeType: z.ZodOptional<z.ZodString>;
|
|
509
|
+
}, "strip", z.ZodTypeAny, {
|
|
510
|
+
url: string;
|
|
511
|
+
description?: string | undefined;
|
|
512
|
+
mimeType?: string | undefined;
|
|
513
|
+
}, {
|
|
514
|
+
url: string;
|
|
515
|
+
description?: string | undefined;
|
|
516
|
+
mimeType?: string | undefined;
|
|
517
|
+
}>;
|
|
518
|
+
type ResourceInfoV2 = z.infer<typeof ResourceInfoV2>;
|
|
519
|
+
/** v2 PaymentRequired — the decoded PAYMENT-REQUIRED header. */
|
|
520
|
+
declare const PaymentRequiredV2: z.ZodObject<{
|
|
521
|
+
x402Version: z.ZodLiteral<2>;
|
|
522
|
+
error: z.ZodOptional<z.ZodString>;
|
|
523
|
+
resource: z.ZodOptional<z.ZodObject<{
|
|
524
|
+
url: z.ZodString;
|
|
525
|
+
description: z.ZodOptional<z.ZodString>;
|
|
526
|
+
mimeType: z.ZodOptional<z.ZodString>;
|
|
527
|
+
}, "strip", z.ZodTypeAny, {
|
|
528
|
+
url: string;
|
|
529
|
+
description?: string | undefined;
|
|
530
|
+
mimeType?: string | undefined;
|
|
531
|
+
}, {
|
|
532
|
+
url: string;
|
|
533
|
+
description?: string | undefined;
|
|
534
|
+
mimeType?: string | undefined;
|
|
535
|
+
}>>;
|
|
536
|
+
accepts: z.ZodArray<z.ZodObject<{
|
|
537
|
+
scheme: z.ZodString;
|
|
538
|
+
/** CAIP-2, e.g. "eip155:84532". */
|
|
539
|
+
network: z.ZodString;
|
|
540
|
+
/** Atomic units — v2's rename of v1's maxAmountRequired. */
|
|
541
|
+
amount: z.ZodString;
|
|
542
|
+
asset: z.ZodString;
|
|
543
|
+
payTo: z.ZodString;
|
|
544
|
+
maxTimeoutSeconds: z.ZodOptional<z.ZodNumber>;
|
|
545
|
+
extra: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
546
|
+
}, "strip", z.ZodTypeAny, {
|
|
547
|
+
scheme: string;
|
|
548
|
+
network: string;
|
|
549
|
+
payTo: string;
|
|
550
|
+
asset: string;
|
|
551
|
+
amount: string;
|
|
552
|
+
maxTimeoutSeconds?: number | undefined;
|
|
553
|
+
extra?: Record<string, unknown> | undefined;
|
|
554
|
+
}, {
|
|
555
|
+
scheme: string;
|
|
556
|
+
network: string;
|
|
557
|
+
payTo: string;
|
|
558
|
+
asset: string;
|
|
559
|
+
amount: string;
|
|
560
|
+
maxTimeoutSeconds?: number | undefined;
|
|
561
|
+
extra?: Record<string, unknown> | undefined;
|
|
562
|
+
}>, "many">;
|
|
563
|
+
extensions: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
564
|
+
}, "strip", z.ZodTypeAny, {
|
|
565
|
+
x402Version: 2;
|
|
566
|
+
accepts: {
|
|
567
|
+
scheme: string;
|
|
568
|
+
network: string;
|
|
569
|
+
payTo: string;
|
|
570
|
+
asset: string;
|
|
571
|
+
amount: string;
|
|
572
|
+
maxTimeoutSeconds?: number | undefined;
|
|
573
|
+
extra?: Record<string, unknown> | undefined;
|
|
574
|
+
}[];
|
|
575
|
+
resource?: {
|
|
576
|
+
url: string;
|
|
577
|
+
description?: string | undefined;
|
|
578
|
+
mimeType?: string | undefined;
|
|
579
|
+
} | undefined;
|
|
580
|
+
error?: string | undefined;
|
|
581
|
+
extensions?: Record<string, unknown> | undefined;
|
|
582
|
+
}, {
|
|
583
|
+
x402Version: 2;
|
|
584
|
+
accepts: {
|
|
585
|
+
scheme: string;
|
|
586
|
+
network: string;
|
|
587
|
+
payTo: string;
|
|
588
|
+
asset: string;
|
|
589
|
+
amount: string;
|
|
590
|
+
maxTimeoutSeconds?: number | undefined;
|
|
591
|
+
extra?: Record<string, unknown> | undefined;
|
|
592
|
+
}[];
|
|
593
|
+
resource?: {
|
|
594
|
+
url: string;
|
|
595
|
+
description?: string | undefined;
|
|
596
|
+
mimeType?: string | undefined;
|
|
597
|
+
} | undefined;
|
|
598
|
+
error?: string | undefined;
|
|
599
|
+
extensions?: Record<string, unknown> | undefined;
|
|
600
|
+
}>;
|
|
601
|
+
type PaymentRequiredV2 = z.infer<typeof PaymentRequiredV2>;
|
|
602
|
+
/** Convert Rein's internal (v1-shaped) requirement to the v2 wire shape. */
|
|
603
|
+
declare function v2Requirements(requirement: PaymentRequirement): PaymentRequirementsV2;
|
|
604
|
+
/**
|
|
605
|
+
* The inverse: a v2 offer (plus the 402's shared ResourceInfo) as an internal
|
|
606
|
+
* requirement. The CAIP-2 network id is kept verbatim — networkToChain and
|
|
607
|
+
* chainIdForNetwork resolve both dialects, and sameNetwork compares across
|
|
608
|
+
* them, so nothing downstream needs the v1 spelling back.
|
|
609
|
+
*/
|
|
610
|
+
declare function requirementFromV2(offer: PaymentRequirementsV2, resource?: ResourceInfoV2): PaymentRequirement;
|
|
611
|
+
/** The full v2 PaymentRequired for one quoted requirement. */
|
|
612
|
+
declare function buildPaymentRequiredV2(requirement: PaymentRequirement, error: string): PaymentRequiredV2;
|
|
613
|
+
/** The one codec every x402 header uses: base64 of compact JSON. */
|
|
614
|
+
declare function encodeBase64Json(value: unknown): string;
|
|
615
|
+
/**
|
|
616
|
+
* Decode a PAYMENT-REQUIRED response header. Lenient by design: a missing,
|
|
617
|
+
* undecodable, or non-v2 header returns undefined so callers fall back to the
|
|
618
|
+
* v1 body — a garbled v2 advertisement must not break a dual-stack 402.
|
|
619
|
+
*/
|
|
620
|
+
declare function parsePaymentRequiredHeader(raw: string | null): PaymentRequiredV2 | undefined;
|
|
621
|
+
/**
|
|
622
|
+
* Rewrap a payer's v1 X-PAYMENT header as a v2 PaymentPayload for the
|
|
623
|
+
* PAYMENT-SIGNATURE header. The scheme payload transfers verbatim (what the
|
|
624
|
+
* payer signed is envelope-independent); the chosen requirement rides along
|
|
625
|
+
* as `accepted` per the v2 spec. A header that is already a v2 envelope
|
|
626
|
+
* passes through unchanged. Throws TypeError on anything else — a payer
|
|
627
|
+
* returning an unrecognizable header is a programming error, not wire input.
|
|
628
|
+
*/
|
|
629
|
+
declare function wrapPaymentV2(paymentHeader: string, requirement: PaymentRequirement, resource?: ResourceInfoV2): string;
|
|
630
|
+
|
|
471
631
|
/** Base class for everything the SDK throws, so callers can catch broadly. */
|
|
472
632
|
declare class ReinError extends Error {
|
|
473
633
|
constructor(message: string);
|
|
@@ -499,4 +659,4 @@ declare class UnsupportedRequirementError extends ReinError {
|
|
|
499
659
|
constructor(url: string);
|
|
500
660
|
}
|
|
501
661
|
|
|
502
|
-
export { EngineClient, type EngineClientOptions, EngineError, EvaluateResponse, type FetchLike, Guard, type GuardOptions, type IntentSubmission, type Payer, PaymentBlockedError, PaymentRequired, PaymentRequirement, ReinError, type ResolvedRequirement, UnsupportedRequirementError, atomicToDecimal, createGuard, decimalToAtomic, networkToChain, requirementDecimals, resolveAsset, selectRequirement, toIntentSubmission };
|
|
662
|
+
export { EngineClient, type EngineClientOptions, EngineError, EvaluateResponse, type FetchLike, Guard, type GuardOptions, type IntentSubmission, type Payer, PaymentBlockedError, PaymentRequired, PaymentRequiredV2, PaymentRequirement, PaymentRequirementsV2, ReinError, type ResolvedRequirement, ResourceInfoV2, UnsupportedRequirementError, atomicToDecimal, buildPaymentRequiredV2, caip2Of, createGuard, decimalToAtomic, encodeBase64Json, networkToChain, parsePaymentRequiredHeader, requirementDecimals, requirementFromV2, resolveAsset, sameNetwork, selectRequirement, toIntentSubmission, v2Requirements, wrapPaymentV2 };
|
package/dist/index.js
CHANGED
|
@@ -196,6 +196,124 @@ function toIntentSubmission(resolved, url, agentId, taskContext) {
|
|
|
196
196
|
taskContext
|
|
197
197
|
};
|
|
198
198
|
}
|
|
199
|
+
var CAIP2_ALIASES = {
|
|
200
|
+
base: "eip155:8453",
|
|
201
|
+
"base-sepolia": "eip155:84532",
|
|
202
|
+
polygon: "eip155:137",
|
|
203
|
+
"polygon-amoy": "eip155:80002",
|
|
204
|
+
bnb: "eip155:56",
|
|
205
|
+
bsc: "eip155:56",
|
|
206
|
+
solana: "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",
|
|
207
|
+
"solana-devnet": "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1"
|
|
208
|
+
};
|
|
209
|
+
function caip2Of(network) {
|
|
210
|
+
const key = network.toLowerCase();
|
|
211
|
+
return CAIP2_ALIASES[key] ?? key;
|
|
212
|
+
}
|
|
213
|
+
function sameNetwork(a, b) {
|
|
214
|
+
return caip2Of(a) === caip2Of(b);
|
|
215
|
+
}
|
|
216
|
+
var PaymentRequirementsV2 = z.object({
|
|
217
|
+
scheme: z.string(),
|
|
218
|
+
/** CAIP-2, e.g. "eip155:84532". */
|
|
219
|
+
network: z.string(),
|
|
220
|
+
/** Atomic units — v2's rename of v1's maxAmountRequired. */
|
|
221
|
+
amount: z.string().regex(/^\d+$/, "atomic amount must be an integer string"),
|
|
222
|
+
asset: z.string().min(1),
|
|
223
|
+
payTo: z.string().min(1),
|
|
224
|
+
maxTimeoutSeconds: z.number().optional(),
|
|
225
|
+
extra: z.record(z.unknown()).optional()
|
|
226
|
+
});
|
|
227
|
+
var ResourceInfoV2 = z.object({
|
|
228
|
+
url: z.string(),
|
|
229
|
+
description: z.string().optional(),
|
|
230
|
+
mimeType: z.string().optional()
|
|
231
|
+
});
|
|
232
|
+
var PaymentRequiredV2 = z.object({
|
|
233
|
+
x402Version: z.literal(2),
|
|
234
|
+
error: z.string().optional(),
|
|
235
|
+
resource: ResourceInfoV2.optional(),
|
|
236
|
+
accepts: z.array(PaymentRequirementsV2).min(1),
|
|
237
|
+
extensions: z.record(z.unknown()).optional()
|
|
238
|
+
});
|
|
239
|
+
function v2Requirements(requirement) {
|
|
240
|
+
return {
|
|
241
|
+
scheme: requirement.scheme,
|
|
242
|
+
network: caip2Of(requirement.network),
|
|
243
|
+
amount: requirement.maxAmountRequired,
|
|
244
|
+
asset: requirement.asset,
|
|
245
|
+
payTo: requirement.payTo,
|
|
246
|
+
...requirement.maxTimeoutSeconds !== void 0 ? { maxTimeoutSeconds: requirement.maxTimeoutSeconds } : {},
|
|
247
|
+
...requirement.extra ? { extra: requirement.extra } : {}
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
function requirementFromV2(offer, resource) {
|
|
251
|
+
return PaymentRequirement.parse({
|
|
252
|
+
scheme: offer.scheme,
|
|
253
|
+
network: offer.network,
|
|
254
|
+
maxAmountRequired: offer.amount,
|
|
255
|
+
payTo: offer.payTo,
|
|
256
|
+
asset: offer.asset,
|
|
257
|
+
...resource !== void 0 ? { resource: resource.url } : {},
|
|
258
|
+
...resource?.description !== void 0 ? { description: resource.description } : {},
|
|
259
|
+
...resource?.mimeType !== void 0 ? { mimeType: resource.mimeType } : {},
|
|
260
|
+
...offer.maxTimeoutSeconds !== void 0 ? { maxTimeoutSeconds: offer.maxTimeoutSeconds } : {},
|
|
261
|
+
...offer.extra ? { extra: offer.extra } : {}
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
function buildPaymentRequiredV2(requirement, error) {
|
|
265
|
+
return {
|
|
266
|
+
x402Version: 2,
|
|
267
|
+
error,
|
|
268
|
+
...requirement.resource ? {
|
|
269
|
+
resource: {
|
|
270
|
+
url: requirement.resource,
|
|
271
|
+
...requirement.description ? { description: requirement.description } : {},
|
|
272
|
+
...requirement.mimeType ? { mimeType: requirement.mimeType } : {}
|
|
273
|
+
}
|
|
274
|
+
} : {},
|
|
275
|
+
accepts: [v2Requirements(requirement)],
|
|
276
|
+
extensions: {}
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
function encodeBase64Json(value) {
|
|
280
|
+
return Buffer.from(JSON.stringify(value)).toString("base64");
|
|
281
|
+
}
|
|
282
|
+
function decodeBase64Json(raw) {
|
|
283
|
+
try {
|
|
284
|
+
return JSON.parse(Buffer.from(raw, "base64").toString("utf8"));
|
|
285
|
+
} catch {
|
|
286
|
+
return void 0;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
function parsePaymentRequiredHeader(raw) {
|
|
290
|
+
if (raw === null) return void 0;
|
|
291
|
+
const parsed = PaymentRequiredV2.safeParse(decodeBase64Json(raw));
|
|
292
|
+
return parsed.success ? parsed.data : void 0;
|
|
293
|
+
}
|
|
294
|
+
var V1Envelope = z.object({
|
|
295
|
+
x402Version: z.literal(1),
|
|
296
|
+
scheme: z.string(),
|
|
297
|
+
network: z.string(),
|
|
298
|
+
payload: z.record(z.unknown())
|
|
299
|
+
});
|
|
300
|
+
function wrapPaymentV2(paymentHeader, requirement, resource) {
|
|
301
|
+
const decoded = decodeBase64Json(paymentHeader);
|
|
302
|
+
if (decoded?.x402Version === 2) {
|
|
303
|
+
return paymentHeader;
|
|
304
|
+
}
|
|
305
|
+
const v1 = V1Envelope.safeParse(decoded);
|
|
306
|
+
if (!v1.success) {
|
|
307
|
+
throw new TypeError(`cannot rewrap payment header as x402 v2: ${v1.error.message}`);
|
|
308
|
+
}
|
|
309
|
+
return encodeBase64Json({
|
|
310
|
+
x402Version: 2,
|
|
311
|
+
...resource !== void 0 ? { resource } : {},
|
|
312
|
+
accepted: v2Requirements(requirement),
|
|
313
|
+
payload: v1.data.payload,
|
|
314
|
+
extensions: {}
|
|
315
|
+
});
|
|
316
|
+
}
|
|
199
317
|
|
|
200
318
|
// src/guard.ts
|
|
201
319
|
var Guard = class {
|
|
@@ -229,17 +347,16 @@ var Guard = class {
|
|
|
229
347
|
const inner = fetchImpl ? (input, init) => fetchImpl(input, init) : this.baseFetch;
|
|
230
348
|
return async (input, init) => {
|
|
231
349
|
const url = requestUrl(input);
|
|
232
|
-
if (readHeader(input, init, "X-PAYMENT") !== null) {
|
|
350
|
+
if (readHeader(input, init, "X-PAYMENT") !== null || readHeader(input, init, "PAYMENT-SIGNATURE") !== null) {
|
|
233
351
|
const res2 = await inner(input, init);
|
|
234
352
|
this.settlePending(url, res2);
|
|
235
353
|
return res2;
|
|
236
354
|
}
|
|
237
355
|
const res = await inner(input, init);
|
|
238
356
|
if (res.status !== 402) return res;
|
|
239
|
-
const
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
const resolved = selectRequirement(parsed.data.accepts, this.options.assetAddresses);
|
|
357
|
+
const paywall = await parse402(res, this.options.assetAddresses);
|
|
358
|
+
if (!paywall) return res;
|
|
359
|
+
const { resolved, wire, resource } = paywall;
|
|
243
360
|
if (!resolved) throw new UnsupportedRequirementError(url);
|
|
244
361
|
const taskContext = this.task.getStore() ?? this.options.taskContext;
|
|
245
362
|
const submission = toIntentSubmission(resolved, url, this.options.agentId, taskContext);
|
|
@@ -255,7 +372,15 @@ var Guard = class {
|
|
|
255
372
|
return res;
|
|
256
373
|
}
|
|
257
374
|
const paymentHeader = await this.options.payer(resolved.requirement, intent, decision);
|
|
258
|
-
const retry = await inner(
|
|
375
|
+
const retry = await inner(
|
|
376
|
+
input,
|
|
377
|
+
wire === 2 ? withHeader(
|
|
378
|
+
input,
|
|
379
|
+
init,
|
|
380
|
+
"PAYMENT-SIGNATURE",
|
|
381
|
+
wrapPaymentV2(paymentHeader, resolved.requirement, resource)
|
|
382
|
+
) : withHeader(input, init, "X-PAYMENT", paymentHeader)
|
|
383
|
+
);
|
|
259
384
|
this.record(intent, decision, url, init, parseSettlement(retry));
|
|
260
385
|
return retry;
|
|
261
386
|
};
|
|
@@ -293,6 +418,24 @@ var Guard = class {
|
|
|
293
418
|
function createGuard(options) {
|
|
294
419
|
return new Guard(options);
|
|
295
420
|
}
|
|
421
|
+
async function parse402(res, assetAddresses) {
|
|
422
|
+
const v2 = parsePaymentRequiredHeader(res.headers.get("PAYMENT-REQUIRED"));
|
|
423
|
+
if (v2) {
|
|
424
|
+
const resolved = selectRequirement(
|
|
425
|
+
v2.accepts.map((offer) => requirementFromV2(offer, v2.resource)),
|
|
426
|
+
assetAddresses
|
|
427
|
+
);
|
|
428
|
+
if (resolved) {
|
|
429
|
+
return v2.resource !== void 0 ? { resolved, wire: 2, resource: v2.resource } : { resolved, wire: 2 };
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
const body = await res.clone().json().catch(() => void 0);
|
|
433
|
+
const parsed = PaymentRequired.safeParse(body);
|
|
434
|
+
if (parsed.success) {
|
|
435
|
+
return { resolved: selectRequirement(parsed.data.accepts, assetAddresses), wire: 1 };
|
|
436
|
+
}
|
|
437
|
+
return v2 ? { resolved: void 0, wire: 2 } : void 0;
|
|
438
|
+
}
|
|
296
439
|
function requestUrl(input) {
|
|
297
440
|
if (typeof input === "string") return input;
|
|
298
441
|
if (input instanceof URL) return input.toString();
|
|
@@ -310,7 +453,7 @@ function withHeader(input, init, name, value) {
|
|
|
310
453
|
return { ...init, headers };
|
|
311
454
|
}
|
|
312
455
|
function parseSettlement(res) {
|
|
313
|
-
const raw = res.headers.get("X-PAYMENT-RESPONSE");
|
|
456
|
+
const raw = res.headers.get("X-PAYMENT-RESPONSE") ?? res.headers.get("PAYMENT-RESPONSE");
|
|
314
457
|
if (raw === null) return void 0;
|
|
315
458
|
let payload;
|
|
316
459
|
try {
|
|
@@ -324,7 +467,8 @@ function parseSettlement(res) {
|
|
|
324
467
|
}
|
|
325
468
|
const record = typeof payload === "object" && payload !== null ? payload : {};
|
|
326
469
|
return {
|
|
327
|
-
|
|
470
|
+
// A failed v2 settle carries transaction: "" — no tx is no txHash.
|
|
471
|
+
txHash: typeof record["transaction"] === "string" && record["transaction"] !== "" ? record["transaction"] : void 0,
|
|
328
472
|
networkId: typeof record["network"] === "string" ? record["network"] : void 0,
|
|
329
473
|
raw
|
|
330
474
|
};
|
|
@@ -346,6 +490,6 @@ function blockedResponse(receipt) {
|
|
|
346
490
|
);
|
|
347
491
|
}
|
|
348
492
|
|
|
349
|
-
export { EngineClient, EngineError, Guard, PaymentBlockedError, PaymentRequired, PaymentRequirement, ReinError, UnsupportedRequirementError, atomicToDecimal, createGuard, decimalToAtomic, networkToChain, requirementDecimals, resolveAsset, selectRequirement, toIntentSubmission };
|
|
493
|
+
export { EngineClient, EngineError, Guard, PaymentBlockedError, PaymentRequired, PaymentRequiredV2, PaymentRequirement, PaymentRequirementsV2, ReinError, ResourceInfoV2, UnsupportedRequirementError, atomicToDecimal, buildPaymentRequiredV2, caip2Of, createGuard, decimalToAtomic, encodeBase64Json, networkToChain, parsePaymentRequiredHeader, requirementDecimals, requirementFromV2, resolveAsset, sameNetwork, selectRequirement, toIntentSubmission, v2Requirements, wrapPaymentV2 };
|
|
350
494
|
//# sourceMappingURL=index.js.map
|
|
351
495
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors.ts","../src/client.ts","../src/x402.ts","../src/guard.ts"],"names":["z","res"],"mappings":"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","file":"index.js","sourcesContent":["import type { Decision, PaymentIntent, Receipt } from '@reinconsole/core';\n\n/** Base class for everything the SDK throws, so callers can catch broadly. */\nexport class ReinError extends Error {\n constructor(message: string) {\n super(message);\n this.name = new.target.name;\n }\n}\n\n/** The policy engine answered with a non-2xx status. */\nexport class EngineError extends ReinError {\n constructor(\n readonly status: number,\n readonly body: unknown,\n message = `policy engine responded ${status}`,\n ) {\n super(message);\n }\n}\n\n/**\n * The engine evaluated the intent and did NOT allow it (deny or escalate —\n * v0.1 blocks both; escalation approval flows land later). The payment was\n * never constructed, so no funds moved. Carries the full evidence trail.\n */\nexport class PaymentBlockedError extends ReinError {\n constructor(\n readonly intent: PaymentIntent,\n readonly decision: Decision,\n readonly receipt: Receipt,\n ) {\n super(\n `rein blocked payment of ${intent.amount} ${intent.asset} to ${intent.vendor.host}: ` +\n `${decision.outcome}${decision.reason ? ` (${decision.reason})` : ''}`,\n );\n }\n}\n\n/**\n * The vendor's 402 was x402-shaped but offered no requirement the guard can\n * govern (unknown scheme/network/asset). The guard fails closed rather than\n * letting an ungoverned payment through.\n */\nexport class UnsupportedRequirementError extends ReinError {\n constructor(readonly url: string) {\n super(`no supported x402 payment requirement in 402 from ${url}; failing closed`);\n }\n}\n","import { z } from 'zod';\nimport { Agent, Decision, PaymentIntent, Policy } from '@reinconsole/core';\nimport { EngineError } from './errors.js';\nimport type { IntentSubmission } from './x402.js';\n\n/** Any fetch-compatible function (global fetch, undici, or a test double). */\nexport type FetchLike = (input: string | URL | Request, init?: RequestInit) => Promise<Response>;\n\nconst Health = z.object({ status: z.string(), publicKey: z.string() });\nconst EvaluateResponse = z.object({ intent: PaymentIntent, decision: Decision });\nexport type EvaluateResponse = z.infer<typeof EvaluateResponse>;\n\nexport interface EngineClientOptions {\n /** Base URL of the policy engine, e.g. \"http://localhost:8787\". */\n baseUrl: string;\n /** Override the transport (tests, custom agents). Defaults to global fetch. */\n fetch?: FetchLike;\n}\n\n/**\n * Thin typed client for the policy-engine HTTP API. Every response is parsed\n * through the @reinconsole/core schemas, so wire drift fails loudly at the boundary.\n */\nexport class EngineClient {\n private readonly baseUrl: string;\n private readonly fetchImpl: FetchLike;\n\n constructor(options: EngineClientOptions) {\n this.baseUrl = options.baseUrl.replace(/\\/+$/, '');\n const f = options.fetch ?? globalThis.fetch;\n this.fetchImpl = (input, init) => f(input, init);\n }\n\n private async request<T>(\n method: string,\n path: string,\n schema: z.ZodType<T, z.ZodTypeDef, unknown>,\n body?: unknown,\n ): Promise<T> {\n const res = await this.fetchImpl(`${this.baseUrl}${path}`, {\n method,\n headers: body === undefined ? undefined : { 'content-type': 'application/json' },\n body: body === undefined ? undefined : JSON.stringify(body),\n });\n if (!res.ok) {\n const payload = await res\n .clone()\n .json()\n .catch(() => res.text().catch(() => undefined));\n throw new EngineError(res.status, payload);\n }\n if (res.status === 204) return schema.parse(undefined);\n return schema.parse(await res.json());\n }\n\n health(): Promise<z.infer<typeof Health>> {\n return this.request('GET', '/health', Health);\n }\n\n registerAgent(input: {\n orgId: string;\n name: string;\n erc8004Id?: string;\n wallets?: Agent['wallets'];\n }): Promise<Agent> {\n return this.request('POST', '/v1/agents', Agent, input);\n }\n\n listAgents(): Promise<Agent[]> {\n return this.request('GET', '/v1/agents', z.array(Agent));\n }\n\n freeze(agentId: string): Promise<void> {\n return this.request('POST', `/v1/agents/${agentId}/freeze`, z.void());\n }\n\n unfreeze(agentId: string): Promise<void> {\n return this.request('POST', `/v1/agents/${agentId}/unfreeze`, z.void());\n }\n\n addPolicy(policy: z.input<typeof Policy>): Promise<Policy> {\n return this.request('POST', '/v1/policies', Policy, policy);\n }\n\n listPolicies(): Promise<Policy[]> {\n return this.request('GET', '/v1/policies', z.array(Policy));\n }\n\n /** The hot path: submit an intent, get the normalized intent + signed decision. */\n evaluate(submission: IntentSubmission): Promise<EvaluateResponse> {\n return this.request('POST', '/v1/evaluate', EvaluateResponse, submission);\n }\n\n decisions(): Promise<Decision[]> {\n return this.request('GET', '/v1/decisions', z.array(Decision));\n }\n}\n","import { z } from 'zod';\nimport { Chain, Asset, type TaskContext, type Vendor } from '@reinconsole/core';\n\n/**\n * x402 wire shapes (spec v1), mock-first: these schemas are what Rein's mock\n * facilitator and tests speak today, and they track the published x402 spec so\n * real vendors parse identically when the live integration lands.\n */\n\n/** One way to pay, as offered inside a 402 response body. */\nexport const PaymentRequirement = z.object({\n scheme: z.string(),\n network: z.string(),\n /** Amount in the asset's atomic units (e.g. \"10000\" = 0.01 USDC at 6 decimals). */\n maxAmountRequired: z.string().regex(/^\\d+$/, 'atomic amount must be an integer string'),\n resource: z.string().optional(),\n description: z.string().optional(),\n mimeType: z.string().optional(),\n payTo: z.string().min(1),\n maxTimeoutSeconds: z.number().optional(),\n /** Token contract address — or, mock-first, a plain symbol like \"USDC\". */\n asset: z.string().min(1),\n extra: z.record(z.unknown()).optional(),\n});\nexport type PaymentRequirement = z.infer<typeof PaymentRequirement>;\n\n/** The full 402 body a paywalled vendor returns. */\nexport const PaymentRequired = z.object({\n x402Version: z.number(),\n accepts: z.array(PaymentRequirement).min(1),\n error: z.string().optional(),\n});\nexport type PaymentRequired = z.infer<typeof PaymentRequired>;\n\n/**\n * x402 network ids → the chains Rein governs. Testnets map to their mainnet.\n * Both v1 names (\"base-sepolia\") and v2 CAIP-2 ids (\"eip155:84532\") appear in\n * the wild, so the guard accepts either.\n */\nconst NETWORK_TO_CHAIN: Record<string, Chain> = {\n base: 'base',\n 'base-sepolia': 'base',\n 'eip155:8453': 'base',\n 'eip155:84532': 'base',\n solana: 'solana',\n 'solana-devnet': 'solana',\n polygon: 'polygon',\n 'polygon-amoy': 'polygon',\n bnb: 'bnb',\n bsc: 'bnb',\n};\n\n/** Canonical stablecoin contract addresses (EVM keys lowercased). */\nconst KNOWN_ASSET_ADDRESSES: Record<string, Asset> = {\n '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913': 'USDC', // USDC on Base\n '0x036cbd53842c5426634e7929541ec2318f3dcf7e': 'USDC', // USDC on Base Sepolia\n EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v: 'USDC', // USDC on Solana\n};\n\nexport function networkToChain(network: string): Chain | undefined {\n return NETWORK_TO_CHAIN[network.toLowerCase()];\n}\n\n/**\n * Resolve a requirement's asset to a symbol Rein knows. Tries, in order: the\n * asset field as a literal symbol (mock-first), `extra.symbol`, then known\n * contract addresses (exact case for Solana, lowercased for EVM), then any\n * caller-supplied address map.\n */\nexport function resolveAsset(\n requirement: PaymentRequirement,\n extraAddresses: Record<string, Asset> = {},\n): Asset | undefined {\n const direct = Asset.safeParse(requirement.asset.toUpperCase());\n if (direct.success) return direct.data;\n\n const symbol = requirement.extra?.['symbol'];\n if (typeof symbol === 'string') {\n const fromExtra = Asset.safeParse(symbol.toUpperCase());\n if (fromExtra.success) return fromExtra.data;\n }\n\n return (\n extraAddresses[requirement.asset] ??\n extraAddresses[requirement.asset.toLowerCase()] ??\n KNOWN_ASSET_ADDRESSES[requirement.asset] ??\n KNOWN_ASSET_ADDRESSES[requirement.asset.toLowerCase()]\n );\n}\n\n/**\n * Convert an atomic-unit amount to a normalized decimal string without floats,\n * e.g. (\"10000\", 6) -> \"0.01\". Stablecoins Rein supports all use 6 decimals;\n * a requirement can override via `extra.decimals`.\n */\nexport function atomicToDecimal(atomic: string, decimals: number): string {\n if (!/^\\d+$/.test(atomic)) throw new TypeError(`invalid atomic amount: ${atomic}`);\n if (decimals === 0) return atomic.replace(/^0+(?=\\d)/, '');\n const digits = atomic.padStart(decimals + 1, '0');\n const intPart = digits.slice(0, digits.length - decimals).replace(/^0+(?=\\d)/, '');\n const fracPart = digits.slice(digits.length - decimals).replace(/0+$/, '');\n return fracPart.length > 0 ? `${intPart}.${fracPart}` : intPart;\n}\n\n/**\n * The inverse of {@link atomicToDecimal}: a human-unit decimal string to atomic\n * units without floats, e.g. (\"0.05\", 6) -> \"50000\". Throws if the value has\n * more fraction digits than the asset carries (sub-atomic precision is a\n * pricing bug, not something to round silently).\n */\nexport function decimalToAtomic(decimal: string, decimals: number): string {\n if (!/^\\d+(\\.\\d+)?$/.test(decimal)) throw new TypeError(`invalid decimal amount: ${decimal}`);\n const dot = decimal.indexOf('.');\n const intPart = dot === -1 ? decimal : decimal.slice(0, dot);\n const fracPart = dot === -1 ? '' : decimal.slice(dot + 1);\n if (fracPart.length > decimals) {\n throw new TypeError(`amount ${decimal} has more than ${decimals} fraction digits`);\n }\n const atomic = intPart + fracPart.padEnd(decimals, '0');\n return atomic.replace(/^0+(?=\\d)/, '');\n}\n\nexport function requirementDecimals(requirement: PaymentRequirement): number {\n const decimals = requirement.extra?.['decimals'];\n return typeof decimals === 'number' && Number.isInteger(decimals) && decimals >= 0 ? decimals : 6;\n}\n\n/** A requirement the guard fully understood, mapped into Rein's domain. */\nexport interface ResolvedRequirement {\n requirement: PaymentRequirement;\n chain: Chain;\n asset: Asset;\n /** Human-unit decimal amount, e.g. \"0.01\". */\n amount: string;\n}\n\n/**\n * Pick the first offer the guard can govern: scheme `exact`, a network that\n * maps to a supported chain, and a resolvable asset. Returns undefined when\n * no offer qualifies — callers must treat that as fail-closed.\n */\nexport function selectRequirement(\n accepts: readonly PaymentRequirement[],\n extraAddresses: Record<string, Asset> = {},\n): ResolvedRequirement | undefined {\n for (const requirement of accepts) {\n if (requirement.scheme.toLowerCase() !== 'exact') continue;\n const chain = networkToChain(requirement.network);\n if (!chain) continue;\n const asset = resolveAsset(requirement, extraAddresses);\n if (!asset) continue;\n const amount = atomicToDecimal(requirement.maxAmountRequired, requirementDecimals(requirement));\n return { requirement, chain, asset, amount };\n }\n return undefined;\n}\n\n/** What the guard submits to the policy engine (the `/v1/evaluate` shape). */\nexport interface IntentSubmission {\n agentId: string;\n vendor: Vendor;\n resource: string;\n amount: string;\n asset: Asset;\n chain: Chain;\n taskContext?: TaskContext;\n}\n\n/** Build the evaluate payload for a resolved offer on a given request URL. */\nexport function toIntentSubmission(\n resolved: ResolvedRequirement,\n url: string,\n agentId: string,\n taskContext: TaskContext | undefined,\n): IntentSubmission {\n const parsed = new URL(url);\n return {\n agentId,\n vendor: {\n host: parsed.host,\n address: resolved.requirement.payTo,\n },\n resource: resolved.requirement.resource ?? parsed.pathname,\n amount: resolved.amount,\n asset: resolved.asset,\n chain: resolved.chain,\n taskContext,\n };\n}\n","import { AsyncLocalStorage } from 'node:async_hooks';\nimport {\n AgentId,\n Receipt,\n newId,\n type Asset,\n type Decision,\n type PaymentIntent,\n type ReceiptSettlement,\n type TaskContext,\n} from '@reinconsole/core';\nimport { EngineClient, type FetchLike } from './client.js';\nimport { PaymentBlockedError, UnsupportedRequirementError } from './errors.js';\nimport {\n PaymentRequired,\n selectRequirement,\n toIntentSubmission,\n type PaymentRequirement,\n} from './x402.js';\n\n/**\n * Builds the `X-PAYMENT` header for an allowed intent. Mock payers and the\n * local EIP-3009 payer ignore the decision; the session-key signer tier\n * requires it — the {intent, decision} pair is the engine-signed voucher the\n * signer verifies before any key is put to work.\n */\nexport type Payer = (\n requirement: PaymentRequirement,\n intent: PaymentIntent,\n decision: Decision,\n) => string | Promise<string>;\n\nexport interface GuardOptions {\n /** Policy engine base URL, e.g. \"http://localhost:8787\". */\n engineUrl: string;\n /** The agent this guard speaks for (must be registered with the engine). */\n agentId: string;\n /** Base fetch the guard wraps by default (vendor-facing). Defaults to global fetch. */\n fetch?: FetchLike;\n /** Transport for talking to the policy engine. Defaults to global fetch. */\n engineFetch?: FetchLike;\n /** Task context attached to every intent unless overridden via withTask(). */\n taskContext?: TaskContext;\n /**\n * What a blocked payment looks like to the caller: 'throw' (default) raises\n * PaymentBlockedError; 'respond' returns a synthetic 402 JSON response, for\n * agent loops that prefer inspecting responses over catching.\n */\n onBlocked?: 'throw' | 'respond';\n /** If set, the guard settles allowed payments itself (pay + retry). */\n payer?: Payer;\n /** Extra token-address -> symbol mappings for asset resolution. */\n assetAddresses?: Record<string, Asset>;\n /** Called once per receipt, as it is recorded. */\n onReceipt?: (receipt: Receipt) => void;\n}\n\n/**\n * The Rein guard: wrap an agent's fetch once, and every x402 paywall it hits\n * is policy-checked before any payment exists, with a receipt either way.\n *\n * Layering: the guard wraps the BASE fetch, underneath any x402 payment\n * library. The first (unpaid) request surfaces the 402; the guard evaluates\n * it and either blocks — so the payment layer never sees the paywall — or\n * releases the 402 upward. The payment layer's `X-PAYMENT` retry then flows\n * back through the guard, which attaches the settlement to the receipt.\n * Alternatively, pass a `payer` and the guard completes the payment itself.\n */\nexport class Guard {\n readonly client: EngineClient;\n private readonly options: GuardOptions;\n private readonly baseFetch: FetchLike;\n private readonly task = new AsyncLocalStorage<TaskContext>();\n private readonly log: Receipt[] = [];\n /** Allowed-but-unsettled receipts awaiting the payment layer's retry, by URL. */\n private readonly pendingByUrl = new Map<string, Receipt>();\n\n constructor(options: GuardOptions) {\n AgentId.parse(options.agentId);\n this.options = options;\n const f = options.fetch ?? globalThis.fetch;\n this.baseFetch = (input, init) => f(input, init);\n this.client = new EngineClient({ baseUrl: options.engineUrl, fetch: options.engineFetch });\n }\n\n /** Every receipt this guard has recorded, oldest first. */\n receipts(): readonly Receipt[] {\n return this.log;\n }\n\n /** Run `fn` with a task context attached to every intent submitted inside it. */\n withTask<T>(context: TaskContext, fn: () => T): T {\n return this.task.run({ ...this.options.taskContext, ...context }, fn);\n }\n\n /**\n * The one-liner: returns a fetch-compatible function that enforces policy on\n * every x402 paywall. Wraps the guard's base fetch unless one is passed.\n */\n wrap(fetchImpl?: FetchLike): FetchLike {\n const inner: FetchLike = fetchImpl ? (input, init) => fetchImpl(input, init) : this.baseFetch;\n\n return async (input, init) => {\n const url = requestUrl(input);\n // A request that already carries a payment is the release leg of an\n // intent this guard allowed — pass it through and capture settlement.\n if (readHeader(input, init, 'X-PAYMENT') !== null) {\n const res = await inner(input, init);\n this.settlePending(url, res);\n return res;\n }\n\n const res = await inner(input, init);\n if (res.status !== 402) return res;\n\n const body = await res\n .clone()\n .json()\n .catch(() => undefined);\n const parsed = PaymentRequired.safeParse(body);\n // Not an x402 paywall — nothing to govern, hand it back untouched.\n if (!parsed.success) return res;\n\n const resolved = selectRequirement(parsed.data.accepts, this.options.assetAddresses);\n if (!resolved) throw new UnsupportedRequirementError(url);\n\n const taskContext = this.task.getStore() ?? this.options.taskContext;\n const submission = toIntentSubmission(resolved, url, this.options.agentId, taskContext);\n const { intent, decision } = await this.client.evaluate(submission);\n\n if (decision.outcome !== 'allow') {\n const receipt = this.record(intent, decision, url, init);\n if (this.options.onBlocked === 'respond') return blockedResponse(receipt);\n throw new PaymentBlockedError(intent, decision, receipt);\n }\n\n if (!this.options.payer) {\n // Advisory mode: release the 402 to the payment layer above us; its\n // X-PAYMENT retry will come back through and settle the receipt.\n const receipt = this.record(intent, decision, url, init);\n this.pendingByUrl.set(url, receipt);\n return res;\n }\n\n const paymentHeader = await this.options.payer(resolved.requirement, intent, decision);\n const retry = await inner(input, withHeader(input, init, 'X-PAYMENT', paymentHeader));\n this.record(intent, decision, url, init, parseSettlement(retry));\n return retry;\n };\n }\n\n private record(\n intent: PaymentIntent,\n decision: Decision,\n url: string,\n init: RequestInit | undefined,\n settlement?: ReceiptSettlement,\n ): Receipt {\n const receipt = Receipt.parse({\n id: newId('rcp'),\n agentId: intent.agentId,\n intentId: intent.id,\n decisionId: decision.id,\n outcome: decision.outcome,\n url,\n method: init?.method ?? 'GET',\n vendorHost: intent.vendor.host,\n amount: intent.amount,\n asset: intent.asset,\n chain: intent.chain,\n taskContext: intent.taskContext,\n reason: decision.reason,\n settlement,\n createdAt: new Date(),\n });\n this.log.push(receipt);\n this.options.onReceipt?.(receipt);\n return receipt;\n }\n\n private settlePending(url: string, res: Response): void {\n const receipt = this.pendingByUrl.get(url);\n if (!receipt || !res.ok) return;\n const settlement = parseSettlement(res);\n if (settlement) receipt.settlement = settlement;\n this.pendingByUrl.delete(url);\n }\n}\n\n/** Convenience factory mirroring the docs: `const guard = createGuard({...})`. */\nexport function createGuard(options: GuardOptions): Guard {\n return new Guard(options);\n}\n\nfunction requestUrl(input: string | URL | Request): string {\n if (typeof input === 'string') return input;\n if (input instanceof URL) return input.toString();\n return input.url;\n}\n\nfunction readHeader(\n input: string | URL | Request,\n init: RequestInit | undefined,\n name: string,\n): string | null {\n const source = init?.headers ?? (input instanceof Request ? input.headers : undefined);\n return source === undefined ? null : new Headers(source).get(name);\n}\n\nfunction withHeader(\n input: string | URL | Request,\n init: RequestInit | undefined,\n name: string,\n value: string,\n): RequestInit {\n const headers = new Headers(\n init?.headers ?? (input instanceof Request ? input.headers : undefined),\n );\n headers.set(name, value);\n return { ...init, headers };\n}\n\n/**\n * Decode the vendor's `X-PAYMENT-RESPONSE` header (base64 JSON per the x402\n * spec; plain JSON tolerated mock-first). Absent or undecodable -> undefined.\n */\nfunction parseSettlement(res: Response): ReceiptSettlement | undefined {\n const raw = res.headers.get('X-PAYMENT-RESPONSE');\n if (raw === null) return undefined;\n let payload: unknown;\n try {\n payload = JSON.parse(raw);\n } catch {\n try {\n payload = JSON.parse(Buffer.from(raw, 'base64').toString('utf8'));\n } catch {\n return { raw };\n }\n }\n const record =\n typeof payload === 'object' && payload !== null ? (payload as Record<string, unknown>) : {};\n return {\n txHash: typeof record['transaction'] === 'string' ? record['transaction'] : undefined,\n networkId: typeof record['network'] === 'string' ? record['network'] : undefined,\n raw,\n };\n}\n\nfunction blockedResponse(receipt: Receipt): Response {\n return new Response(\n JSON.stringify({\n error: 'payment_blocked_by_rein',\n outcome: receipt.outcome,\n reason: receipt.reason,\n intentId: receipt.intentId,\n decisionId: receipt.decisionId,\n receiptId: receipt.id,\n }),\n {\n status: 402,\n headers: { 'content-type': 'application/json', 'x-rein-outcome': receipt.outcome },\n },\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/client.ts","../src/x402.ts","../src/x402v2.ts","../src/guard.ts"],"names":["z","res"],"mappings":"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","file":"index.js","sourcesContent":["import type { Decision, PaymentIntent, Receipt } from '@reinconsole/core';\n\n/** Base class for everything the SDK throws, so callers can catch broadly. */\nexport class ReinError extends Error {\n constructor(message: string) {\n super(message);\n this.name = new.target.name;\n }\n}\n\n/** The policy engine answered with a non-2xx status. */\nexport class EngineError extends ReinError {\n constructor(\n readonly status: number,\n readonly body: unknown,\n message = `policy engine responded ${status}`,\n ) {\n super(message);\n }\n}\n\n/**\n * The engine evaluated the intent and did NOT allow it (deny or escalate —\n * v0.1 blocks both; escalation approval flows land later). The payment was\n * never constructed, so no funds moved. Carries the full evidence trail.\n */\nexport class PaymentBlockedError extends ReinError {\n constructor(\n readonly intent: PaymentIntent,\n readonly decision: Decision,\n readonly receipt: Receipt,\n ) {\n super(\n `rein blocked payment of ${intent.amount} ${intent.asset} to ${intent.vendor.host}: ` +\n `${decision.outcome}${decision.reason ? ` (${decision.reason})` : ''}`,\n );\n }\n}\n\n/**\n * The vendor's 402 was x402-shaped but offered no requirement the guard can\n * govern (unknown scheme/network/asset). The guard fails closed rather than\n * letting an ungoverned payment through.\n */\nexport class UnsupportedRequirementError extends ReinError {\n constructor(readonly url: string) {\n super(`no supported x402 payment requirement in 402 from ${url}; failing closed`);\n }\n}\n","import { z } from 'zod';\nimport { Agent, Decision, PaymentIntent, Policy } from '@reinconsole/core';\nimport { EngineError } from './errors.js';\nimport type { IntentSubmission } from './x402.js';\n\n/** Any fetch-compatible function (global fetch, undici, or a test double). */\nexport type FetchLike = (input: string | URL | Request, init?: RequestInit) => Promise<Response>;\n\nconst Health = z.object({ status: z.string(), publicKey: z.string() });\nconst EvaluateResponse = z.object({ intent: PaymentIntent, decision: Decision });\nexport type EvaluateResponse = z.infer<typeof EvaluateResponse>;\n\nexport interface EngineClientOptions {\n /** Base URL of the policy engine, e.g. \"http://localhost:8787\". */\n baseUrl: string;\n /** Override the transport (tests, custom agents). Defaults to global fetch. */\n fetch?: FetchLike;\n}\n\n/**\n * Thin typed client for the policy-engine HTTP API. Every response is parsed\n * through the @reinconsole/core schemas, so wire drift fails loudly at the boundary.\n */\nexport class EngineClient {\n private readonly baseUrl: string;\n private readonly fetchImpl: FetchLike;\n\n constructor(options: EngineClientOptions) {\n this.baseUrl = options.baseUrl.replace(/\\/+$/, '');\n const f = options.fetch ?? globalThis.fetch;\n this.fetchImpl = (input, init) => f(input, init);\n }\n\n private async request<T>(\n method: string,\n path: string,\n schema: z.ZodType<T, z.ZodTypeDef, unknown>,\n body?: unknown,\n ): Promise<T> {\n const res = await this.fetchImpl(`${this.baseUrl}${path}`, {\n method,\n headers: body === undefined ? undefined : { 'content-type': 'application/json' },\n body: body === undefined ? undefined : JSON.stringify(body),\n });\n if (!res.ok) {\n const payload = await res\n .clone()\n .json()\n .catch(() => res.text().catch(() => undefined));\n throw new EngineError(res.status, payload);\n }\n if (res.status === 204) return schema.parse(undefined);\n return schema.parse(await res.json());\n }\n\n health(): Promise<z.infer<typeof Health>> {\n return this.request('GET', '/health', Health);\n }\n\n registerAgent(input: {\n orgId: string;\n name: string;\n erc8004Id?: string;\n wallets?: Agent['wallets'];\n }): Promise<Agent> {\n return this.request('POST', '/v1/agents', Agent, input);\n }\n\n listAgents(): Promise<Agent[]> {\n return this.request('GET', '/v1/agents', z.array(Agent));\n }\n\n freeze(agentId: string): Promise<void> {\n return this.request('POST', `/v1/agents/${agentId}/freeze`, z.void());\n }\n\n unfreeze(agentId: string): Promise<void> {\n return this.request('POST', `/v1/agents/${agentId}/unfreeze`, z.void());\n }\n\n addPolicy(policy: z.input<typeof Policy>): Promise<Policy> {\n return this.request('POST', '/v1/policies', Policy, policy);\n }\n\n listPolicies(): Promise<Policy[]> {\n return this.request('GET', '/v1/policies', z.array(Policy));\n }\n\n /** The hot path: submit an intent, get the normalized intent + signed decision. */\n evaluate(submission: IntentSubmission): Promise<EvaluateResponse> {\n return this.request('POST', '/v1/evaluate', EvaluateResponse, submission);\n }\n\n decisions(): Promise<Decision[]> {\n return this.request('GET', '/v1/decisions', z.array(Decision));\n }\n}\n","import { z } from 'zod';\nimport { Chain, Asset, type TaskContext, type Vendor } from '@reinconsole/core';\n\n/**\n * x402 wire shapes (spec v1), mock-first: these schemas are what Rein's mock\n * facilitator and tests speak today, and they track the published x402 spec so\n * real vendors parse identically when the live integration lands.\n */\n\n/** One way to pay, as offered inside a 402 response body. */\nexport const PaymentRequirement = z.object({\n scheme: z.string(),\n network: z.string(),\n /** Amount in the asset's atomic units (e.g. \"10000\" = 0.01 USDC at 6 decimals). */\n maxAmountRequired: z.string().regex(/^\\d+$/, 'atomic amount must be an integer string'),\n resource: z.string().optional(),\n description: z.string().optional(),\n mimeType: z.string().optional(),\n payTo: z.string().min(1),\n maxTimeoutSeconds: z.number().optional(),\n /** Token contract address — or, mock-first, a plain symbol like \"USDC\". */\n asset: z.string().min(1),\n extra: z.record(z.unknown()).optional(),\n});\nexport type PaymentRequirement = z.infer<typeof PaymentRequirement>;\n\n/** The full 402 body a paywalled vendor returns. */\nexport const PaymentRequired = z.object({\n x402Version: z.number(),\n accepts: z.array(PaymentRequirement).min(1),\n error: z.string().optional(),\n});\nexport type PaymentRequired = z.infer<typeof PaymentRequired>;\n\n/**\n * x402 network ids → the chains Rein governs. Testnets map to their mainnet.\n * Both v1 names (\"base-sepolia\") and v2 CAIP-2 ids (\"eip155:84532\") appear in\n * the wild, so the guard accepts either.\n */\nconst NETWORK_TO_CHAIN: Record<string, Chain> = {\n base: 'base',\n 'base-sepolia': 'base',\n 'eip155:8453': 'base',\n 'eip155:84532': 'base',\n solana: 'solana',\n 'solana-devnet': 'solana',\n polygon: 'polygon',\n 'polygon-amoy': 'polygon',\n bnb: 'bnb',\n bsc: 'bnb',\n};\n\n/** Canonical stablecoin contract addresses (EVM keys lowercased). */\nconst KNOWN_ASSET_ADDRESSES: Record<string, Asset> = {\n '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913': 'USDC', // USDC on Base\n '0x036cbd53842c5426634e7929541ec2318f3dcf7e': 'USDC', // USDC on Base Sepolia\n EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v: 'USDC', // USDC on Solana\n};\n\nexport function networkToChain(network: string): Chain | undefined {\n return NETWORK_TO_CHAIN[network.toLowerCase()];\n}\n\n/**\n * Resolve a requirement's asset to a symbol Rein knows. Tries, in order: the\n * asset field as a literal symbol (mock-first), `extra.symbol`, then known\n * contract addresses (exact case for Solana, lowercased for EVM), then any\n * caller-supplied address map.\n */\nexport function resolveAsset(\n requirement: PaymentRequirement,\n extraAddresses: Record<string, Asset> = {},\n): Asset | undefined {\n const direct = Asset.safeParse(requirement.asset.toUpperCase());\n if (direct.success) return direct.data;\n\n const symbol = requirement.extra?.['symbol'];\n if (typeof symbol === 'string') {\n const fromExtra = Asset.safeParse(symbol.toUpperCase());\n if (fromExtra.success) return fromExtra.data;\n }\n\n return (\n extraAddresses[requirement.asset] ??\n extraAddresses[requirement.asset.toLowerCase()] ??\n KNOWN_ASSET_ADDRESSES[requirement.asset] ??\n KNOWN_ASSET_ADDRESSES[requirement.asset.toLowerCase()]\n );\n}\n\n/**\n * Convert an atomic-unit amount to a normalized decimal string without floats,\n * e.g. (\"10000\", 6) -> \"0.01\". Stablecoins Rein supports all use 6 decimals;\n * a requirement can override via `extra.decimals`.\n */\nexport function atomicToDecimal(atomic: string, decimals: number): string {\n if (!/^\\d+$/.test(atomic)) throw new TypeError(`invalid atomic amount: ${atomic}`);\n if (decimals === 0) return atomic.replace(/^0+(?=\\d)/, '');\n const digits = atomic.padStart(decimals + 1, '0');\n const intPart = digits.slice(0, digits.length - decimals).replace(/^0+(?=\\d)/, '');\n const fracPart = digits.slice(digits.length - decimals).replace(/0+$/, '');\n return fracPart.length > 0 ? `${intPart}.${fracPart}` : intPart;\n}\n\n/**\n * The inverse of {@link atomicToDecimal}: a human-unit decimal string to atomic\n * units without floats, e.g. (\"0.05\", 6) -> \"50000\". Throws if the value has\n * more fraction digits than the asset carries (sub-atomic precision is a\n * pricing bug, not something to round silently).\n */\nexport function decimalToAtomic(decimal: string, decimals: number): string {\n if (!/^\\d+(\\.\\d+)?$/.test(decimal)) throw new TypeError(`invalid decimal amount: ${decimal}`);\n const dot = decimal.indexOf('.');\n const intPart = dot === -1 ? decimal : decimal.slice(0, dot);\n const fracPart = dot === -1 ? '' : decimal.slice(dot + 1);\n if (fracPart.length > decimals) {\n throw new TypeError(`amount ${decimal} has more than ${decimals} fraction digits`);\n }\n const atomic = intPart + fracPart.padEnd(decimals, '0');\n return atomic.replace(/^0+(?=\\d)/, '');\n}\n\nexport function requirementDecimals(requirement: PaymentRequirement): number {\n const decimals = requirement.extra?.['decimals'];\n return typeof decimals === 'number' && Number.isInteger(decimals) && decimals >= 0 ? decimals : 6;\n}\n\n/** A requirement the guard fully understood, mapped into Rein's domain. */\nexport interface ResolvedRequirement {\n requirement: PaymentRequirement;\n chain: Chain;\n asset: Asset;\n /** Human-unit decimal amount, e.g. \"0.01\". */\n amount: string;\n}\n\n/**\n * Pick the first offer the guard can govern: scheme `exact`, a network that\n * maps to a supported chain, and a resolvable asset. Returns undefined when\n * no offer qualifies — callers must treat that as fail-closed.\n */\nexport function selectRequirement(\n accepts: readonly PaymentRequirement[],\n extraAddresses: Record<string, Asset> = {},\n): ResolvedRequirement | undefined {\n for (const requirement of accepts) {\n if (requirement.scheme.toLowerCase() !== 'exact') continue;\n const chain = networkToChain(requirement.network);\n if (!chain) continue;\n const asset = resolveAsset(requirement, extraAddresses);\n if (!asset) continue;\n const amount = atomicToDecimal(requirement.maxAmountRequired, requirementDecimals(requirement));\n return { requirement, chain, asset, amount };\n }\n return undefined;\n}\n\n/** What the guard submits to the policy engine (the `/v1/evaluate` shape). */\nexport interface IntentSubmission {\n agentId: string;\n vendor: Vendor;\n resource: string;\n amount: string;\n asset: Asset;\n chain: Chain;\n taskContext?: TaskContext;\n}\n\n/** Build the evaluate payload for a resolved offer on a given request URL. */\nexport function toIntentSubmission(\n resolved: ResolvedRequirement,\n url: string,\n agentId: string,\n taskContext: TaskContext | undefined,\n): IntentSubmission {\n const parsed = new URL(url);\n return {\n agentId,\n vendor: {\n host: parsed.host,\n address: resolved.requirement.payTo,\n },\n resource: resolved.requirement.resource ?? parsed.pathname,\n amount: resolved.amount,\n asset: resolved.asset,\n chain: resolved.chain,\n taskContext,\n };\n}\n","import { z } from 'zod';\nimport { PaymentRequirement } from './x402.js';\n\n/**\n * x402 v2 wire dialect — CAIP-2 network ids, `PAYMENT-REQUIRED` /\n * `PAYMENT-SIGNATURE` / `PAYMENT-RESPONSE` headers, base64-JSON payloads.\n * Verified against the published spec (coinbase/x402\n * specs/x402-specification-v2.md + transports-v2/http.md, re-checked 2026-07)\n * and the live facilitator's /supported.\n *\n * Rein's internal requirement shape stays v1 (the zod contract in x402.ts);\n * v2 is a WIRE dialect converted at the edges. Inbound, the guard converts a\n * PAYMENT-REQUIRED quote into internal requirements. Outbound, it REWRAPS the\n * payer's v1 X-PAYMENT envelope into the v2 PaymentPayload: the scheme payload\n * (e.g. the signed EIP-3009 authorization) is byte-identical in both dialects,\n * so every Payer — mock, EIP-3009, session-signer — is v2-capable without\n * knowing v2 exists. The vendor side (@reinconsole/gate) re-exports these\n * helpers rather than owning its own copies.\n */\n\n/**\n * Known v1 network names → CAIP-2. EVM entries are chain-id math; the Solana\n * ids are what the live facilitator advertises. Unknown names pass through\n * lowercased, so two spellings of an UNKNOWN network still compare equal.\n */\nconst CAIP2_ALIASES: Record<string, string> = {\n base: 'eip155:8453',\n 'base-sepolia': 'eip155:84532',\n polygon: 'eip155:137',\n 'polygon-amoy': 'eip155:80002',\n bnb: 'eip155:56',\n bsc: 'eip155:56',\n solana: 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp',\n 'solana-devnet': 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1',\n};\n\n/** The CAIP-2 id for a network name, or the lowercased name when unknown. */\nexport function caip2Of(network: string): string {\n const key = network.toLowerCase();\n return CAIP2_ALIASES[key] ?? key;\n}\n\n/** Do two network ids name the same chain, across the v1/CAIP-2 divide? */\nexport function sameNetwork(a: string, b: string): boolean {\n return caip2Of(a) === caip2Of(b);\n}\n\n/** x402 v2 PaymentRequirements (one entry of a 402's `accepts`). */\nexport const PaymentRequirementsV2 = z.object({\n scheme: z.string(),\n /** CAIP-2, e.g. \"eip155:84532\". */\n network: z.string(),\n /** Atomic units — v2's rename of v1's maxAmountRequired. */\n amount: z.string().regex(/^\\d+$/, 'atomic amount must be an integer string'),\n asset: z.string().min(1),\n payTo: z.string().min(1),\n maxTimeoutSeconds: z.number().optional(),\n extra: z.record(z.unknown()).optional(),\n});\nexport type PaymentRequirementsV2 = z.infer<typeof PaymentRequirementsV2>;\n\n/** v2 ResourceInfo — resource facts move out of the requirement in v2. */\nexport const ResourceInfoV2 = z.object({\n url: z.string(),\n description: z.string().optional(),\n mimeType: z.string().optional(),\n});\nexport type ResourceInfoV2 = z.infer<typeof ResourceInfoV2>;\n\n/** v2 PaymentRequired — the decoded PAYMENT-REQUIRED header. */\nexport const PaymentRequiredV2 = z.object({\n x402Version: z.literal(2),\n error: z.string().optional(),\n resource: ResourceInfoV2.optional(),\n accepts: z.array(PaymentRequirementsV2).min(1),\n extensions: z.record(z.unknown()).optional(),\n});\nexport type PaymentRequiredV2 = z.infer<typeof PaymentRequiredV2>;\n\n/** Convert Rein's internal (v1-shaped) requirement to the v2 wire shape. */\nexport function v2Requirements(requirement: PaymentRequirement): PaymentRequirementsV2 {\n return {\n scheme: requirement.scheme,\n network: caip2Of(requirement.network),\n amount: requirement.maxAmountRequired,\n asset: requirement.asset,\n payTo: requirement.payTo,\n ...(requirement.maxTimeoutSeconds !== undefined\n ? { maxTimeoutSeconds: requirement.maxTimeoutSeconds }\n : {}),\n ...(requirement.extra ? { extra: requirement.extra } : {}),\n };\n}\n\n/**\n * The inverse: a v2 offer (plus the 402's shared ResourceInfo) as an internal\n * requirement. The CAIP-2 network id is kept verbatim — networkToChain and\n * chainIdForNetwork resolve both dialects, and sameNetwork compares across\n * them, so nothing downstream needs the v1 spelling back.\n */\nexport function requirementFromV2(\n offer: PaymentRequirementsV2,\n resource?: ResourceInfoV2,\n): PaymentRequirement {\n return PaymentRequirement.parse({\n scheme: offer.scheme,\n network: offer.network,\n maxAmountRequired: offer.amount,\n payTo: offer.payTo,\n asset: offer.asset,\n ...(resource !== undefined ? { resource: resource.url } : {}),\n ...(resource?.description !== undefined ? { description: resource.description } : {}),\n ...(resource?.mimeType !== undefined ? { mimeType: resource.mimeType } : {}),\n ...(offer.maxTimeoutSeconds !== undefined\n ? { maxTimeoutSeconds: offer.maxTimeoutSeconds }\n : {}),\n ...(offer.extra ? { extra: offer.extra } : {}),\n });\n}\n\n/** The full v2 PaymentRequired for one quoted requirement. */\nexport function buildPaymentRequiredV2(\n requirement: PaymentRequirement,\n error: string,\n): PaymentRequiredV2 {\n return {\n x402Version: 2,\n error,\n ...(requirement.resource\n ? {\n resource: {\n url: requirement.resource,\n ...(requirement.description ? { description: requirement.description } : {}),\n ...(requirement.mimeType ? { mimeType: requirement.mimeType } : {}),\n },\n }\n : {}),\n accepts: [v2Requirements(requirement)],\n extensions: {},\n };\n}\n\n/** The one codec every x402 header uses: base64 of compact JSON. */\nexport function encodeBase64Json(value: unknown): string {\n return Buffer.from(JSON.stringify(value)).toString('base64');\n}\n\n/** Base64 JSON → value, or undefined when the header is not decodable. */\nfunction decodeBase64Json(raw: string): unknown {\n try {\n return JSON.parse(Buffer.from(raw, 'base64').toString('utf8'));\n } catch {\n return undefined;\n }\n}\n\n/**\n * Decode a PAYMENT-REQUIRED response header. Lenient by design: a missing,\n * undecodable, or non-v2 header returns undefined so callers fall back to the\n * v1 body — a garbled v2 advertisement must not break a dual-stack 402.\n */\nexport function parsePaymentRequiredHeader(raw: string | null): PaymentRequiredV2 | undefined {\n if (raw === null) return undefined;\n const parsed = PaymentRequiredV2.safeParse(decodeBase64Json(raw));\n return parsed.success ? parsed.data : undefined;\n}\n\n/** The v1 X-PAYMENT envelope, as far as the v2 rewrap needs to see it. */\nconst V1Envelope = z.object({\n x402Version: z.literal(1),\n scheme: z.string(),\n network: z.string(),\n payload: z.record(z.unknown()),\n});\n\n/**\n * Rewrap a payer's v1 X-PAYMENT header as a v2 PaymentPayload for the\n * PAYMENT-SIGNATURE header. The scheme payload transfers verbatim (what the\n * payer signed is envelope-independent); the chosen requirement rides along\n * as `accepted` per the v2 spec. A header that is already a v2 envelope\n * passes through unchanged. Throws TypeError on anything else — a payer\n * returning an unrecognizable header is a programming error, not wire input.\n */\nexport function wrapPaymentV2(\n paymentHeader: string,\n requirement: PaymentRequirement,\n resource?: ResourceInfoV2,\n): string {\n const decoded = decodeBase64Json(paymentHeader);\n if ((decoded as { x402Version?: unknown } | undefined)?.x402Version === 2) {\n return paymentHeader;\n }\n const v1 = V1Envelope.safeParse(decoded);\n if (!v1.success) {\n throw new TypeError(`cannot rewrap payment header as x402 v2: ${v1.error.message}`);\n }\n return encodeBase64Json({\n x402Version: 2,\n ...(resource !== undefined ? { resource } : {}),\n accepted: v2Requirements(requirement),\n payload: v1.data.payload,\n extensions: {},\n });\n}\n","import { AsyncLocalStorage } from 'node:async_hooks';\nimport {\n AgentId,\n Receipt,\n newId,\n type Asset,\n type Decision,\n type PaymentIntent,\n type ReceiptSettlement,\n type TaskContext,\n} from '@reinconsole/core';\nimport { EngineClient, type FetchLike } from './client.js';\nimport { PaymentBlockedError, UnsupportedRequirementError } from './errors.js';\nimport {\n PaymentRequired,\n selectRequirement,\n toIntentSubmission,\n type PaymentRequirement,\n type ResolvedRequirement,\n} from './x402.js';\nimport {\n parsePaymentRequiredHeader,\n requirementFromV2,\n wrapPaymentV2,\n type ResourceInfoV2,\n} from './x402v2.js';\n\n/**\n * Builds the `X-PAYMENT` header for an allowed intent. Mock payers and the\n * local EIP-3009 payer ignore the decision; the session-key signer tier\n * requires it — the {intent, decision} pair is the engine-signed voucher the\n * signer verifies before any key is put to work.\n */\nexport type Payer = (\n requirement: PaymentRequirement,\n intent: PaymentIntent,\n decision: Decision,\n) => string | Promise<string>;\n\nexport interface GuardOptions {\n /** Policy engine base URL, e.g. \"http://localhost:8787\". */\n engineUrl: string;\n /** The agent this guard speaks for (must be registered with the engine). */\n agentId: string;\n /** Base fetch the guard wraps by default (vendor-facing). Defaults to global fetch. */\n fetch?: FetchLike;\n /** Transport for talking to the policy engine. Defaults to global fetch. */\n engineFetch?: FetchLike;\n /** Task context attached to every intent unless overridden via withTask(). */\n taskContext?: TaskContext;\n /**\n * What a blocked payment looks like to the caller: 'throw' (default) raises\n * PaymentBlockedError; 'respond' returns a synthetic 402 JSON response, for\n * agent loops that prefer inspecting responses over catching.\n */\n onBlocked?: 'throw' | 'respond';\n /** If set, the guard settles allowed payments itself (pay + retry). */\n payer?: Payer;\n /** Extra token-address -> symbol mappings for asset resolution. */\n assetAddresses?: Record<string, Asset>;\n /** Called once per receipt, as it is recorded. */\n onReceipt?: (receipt: Receipt) => void;\n}\n\n/**\n * The Rein guard: wrap an agent's fetch once, and every x402 paywall it hits\n * is policy-checked before any payment exists, with a receipt either way.\n *\n * Layering: the guard wraps the BASE fetch, underneath any x402 payment\n * library. The first (unpaid) request surfaces the 402; the guard evaluates\n * it and either blocks — so the payment layer never sees the paywall — or\n * releases the 402 upward. The payment layer's `X-PAYMENT` retry then flows\n * back through the guard, which attaches the settlement to the receipt.\n * Alternatively, pass a `payer` and the guard completes the payment itself.\n */\nexport class Guard {\n readonly client: EngineClient;\n private readonly options: GuardOptions;\n private readonly baseFetch: FetchLike;\n private readonly task = new AsyncLocalStorage<TaskContext>();\n private readonly log: Receipt[] = [];\n /** Allowed-but-unsettled receipts awaiting the payment layer's retry, by URL. */\n private readonly pendingByUrl = new Map<string, Receipt>();\n\n constructor(options: GuardOptions) {\n AgentId.parse(options.agentId);\n this.options = options;\n const f = options.fetch ?? globalThis.fetch;\n this.baseFetch = (input, init) => f(input, init);\n this.client = new EngineClient({ baseUrl: options.engineUrl, fetch: options.engineFetch });\n }\n\n /** Every receipt this guard has recorded, oldest first. */\n receipts(): readonly Receipt[] {\n return this.log;\n }\n\n /** Run `fn` with a task context attached to every intent submitted inside it. */\n withTask<T>(context: TaskContext, fn: () => T): T {\n return this.task.run({ ...this.options.taskContext, ...context }, fn);\n }\n\n /**\n * The one-liner: returns a fetch-compatible function that enforces policy on\n * every x402 paywall. Wraps the guard's base fetch unless one is passed.\n */\n wrap(fetchImpl?: FetchLike): FetchLike {\n const inner: FetchLike = fetchImpl ? (input, init) => fetchImpl(input, init) : this.baseFetch;\n\n return async (input, init) => {\n const url = requestUrl(input);\n // A request that already carries a payment (either dialect's header) is\n // the release leg of an intent this guard allowed — pass it through and\n // capture settlement.\n if (\n readHeader(input, init, 'X-PAYMENT') !== null ||\n readHeader(input, init, 'PAYMENT-SIGNATURE') !== null\n ) {\n const res = await inner(input, init);\n this.settlePending(url, res);\n return res;\n }\n\n const res = await inner(input, init);\n if (res.status !== 402) return res;\n\n const paywall = await parse402(res, this.options.assetAddresses);\n // Not an x402 paywall — nothing to govern, hand it back untouched.\n if (!paywall) return res;\n\n const { resolved, wire, resource } = paywall;\n if (!resolved) throw new UnsupportedRequirementError(url);\n\n const taskContext = this.task.getStore() ?? this.options.taskContext;\n const submission = toIntentSubmission(resolved, url, this.options.agentId, taskContext);\n const { intent, decision } = await this.client.evaluate(submission);\n\n if (decision.outcome !== 'allow') {\n const receipt = this.record(intent, decision, url, init);\n if (this.options.onBlocked === 'respond') return blockedResponse(receipt);\n throw new PaymentBlockedError(intent, decision, receipt);\n }\n\n if (!this.options.payer) {\n // Advisory mode: release the 402 to the payment layer above us; its\n // X-PAYMENT retry will come back through and settle the receipt.\n const receipt = this.record(intent, decision, url, init);\n this.pendingByUrl.set(url, receipt);\n return res;\n }\n\n // The payer always produces the v1 envelope it knows; on a v2 paywall\n // the guard rewraps it (same signed payload, v2 PaymentPayload around\n // it) and pays on the v2 header. Every payer is v2-capable this way.\n const paymentHeader = await this.options.payer(resolved.requirement, intent, decision);\n const retry = await inner(\n input,\n wire === 2\n ? withHeader(\n input,\n init,\n 'PAYMENT-SIGNATURE',\n wrapPaymentV2(paymentHeader, resolved.requirement, resource),\n )\n : withHeader(input, init, 'X-PAYMENT', paymentHeader),\n );\n this.record(intent, decision, url, init, parseSettlement(retry));\n return retry;\n };\n }\n\n private record(\n intent: PaymentIntent,\n decision: Decision,\n url: string,\n init: RequestInit | undefined,\n settlement?: ReceiptSettlement,\n ): Receipt {\n const receipt = Receipt.parse({\n id: newId('rcp'),\n agentId: intent.agentId,\n intentId: intent.id,\n decisionId: decision.id,\n outcome: decision.outcome,\n url,\n method: init?.method ?? 'GET',\n vendorHost: intent.vendor.host,\n amount: intent.amount,\n asset: intent.asset,\n chain: intent.chain,\n taskContext: intent.taskContext,\n reason: decision.reason,\n settlement,\n createdAt: new Date(),\n });\n this.log.push(receipt);\n this.options.onReceipt?.(receipt);\n return receipt;\n }\n\n private settlePending(url: string, res: Response): void {\n const receipt = this.pendingByUrl.get(url);\n if (!receipt || !res.ok) return;\n const settlement = parseSettlement(res);\n if (settlement) receipt.settlement = settlement;\n this.pendingByUrl.delete(url);\n }\n}\n\n/** Convenience factory mirroring the docs: `const guard = createGuard({...})`. */\nexport function createGuard(options: GuardOptions): Guard {\n return new Guard(options);\n}\n\n/** What a 402 offered, in whichever dialect the guard could govern. */\ninterface ParsedPaywall {\n /** The offer the guard selected, or undefined when none qualifies. */\n resolved: ResolvedRequirement | undefined;\n /** Which wire dialect to pay on: 2 = PAYMENT-SIGNATURE, 1 = X-PAYMENT. */\n wire: 1 | 2;\n /** The v2 402's shared resource info, echoed into the payment envelope. */\n resource?: ResourceInfoV2;\n}\n\n/**\n * Read a 402 in both dialects. v2 (the PAYMENT-REQUIRED header) is preferred\n * when it carries an offer the guard can govern; otherwise the v1 body gets\n * its chance — a dual-stack vendor is served on whichever channel works.\n * Returns undefined when neither channel is x402 at all (not a paywall).\n */\nasync function parse402(\n res: Response,\n assetAddresses: Record<string, Asset> | undefined,\n): Promise<ParsedPaywall | undefined> {\n const v2 = parsePaymentRequiredHeader(res.headers.get('PAYMENT-REQUIRED'));\n if (v2) {\n const resolved = selectRequirement(\n v2.accepts.map((offer) => requirementFromV2(offer, v2.resource)),\n assetAddresses,\n );\n if (resolved) {\n return v2.resource !== undefined\n ? { resolved, wire: 2, resource: v2.resource }\n : { resolved, wire: 2 };\n }\n }\n\n const body = await res\n .clone()\n .json()\n .catch(() => undefined);\n const parsed = PaymentRequired.safeParse(body);\n if (parsed.success) {\n return { resolved: selectRequirement(parsed.data.accepts, assetAddresses), wire: 1 };\n }\n // A v2 header alone still marks this as a paywall — one the guard must\n // fail closed on if nothing in it was governable.\n return v2 ? { resolved: undefined, wire: 2 } : undefined;\n}\n\nfunction requestUrl(input: string | URL | Request): string {\n if (typeof input === 'string') return input;\n if (input instanceof URL) return input.toString();\n return input.url;\n}\n\nfunction readHeader(\n input: string | URL | Request,\n init: RequestInit | undefined,\n name: string,\n): string | null {\n const source = init?.headers ?? (input instanceof Request ? input.headers : undefined);\n return source === undefined ? null : new Headers(source).get(name);\n}\n\nfunction withHeader(\n input: string | URL | Request,\n init: RequestInit | undefined,\n name: string,\n value: string,\n): RequestInit {\n const headers = new Headers(\n init?.headers ?? (input instanceof Request ? input.headers : undefined),\n );\n headers.set(name, value);\n return { ...init, headers };\n}\n\n/**\n * Decode the vendor's settlement header — `X-PAYMENT-RESPONSE` (v1) or\n * `PAYMENT-RESPONSE` (v2); base64 JSON per the x402 spec, plain JSON\n * tolerated mock-first. Absent or undecodable -> undefined.\n */\nfunction parseSettlement(res: Response): ReceiptSettlement | undefined {\n const raw = res.headers.get('X-PAYMENT-RESPONSE') ?? res.headers.get('PAYMENT-RESPONSE');\n if (raw === null) return undefined;\n let payload: unknown;\n try {\n payload = JSON.parse(raw);\n } catch {\n try {\n payload = JSON.parse(Buffer.from(raw, 'base64').toString('utf8'));\n } catch {\n return { raw };\n }\n }\n const record =\n typeof payload === 'object' && payload !== null ? (payload as Record<string, unknown>) : {};\n return {\n // A failed v2 settle carries transaction: \"\" — no tx is no txHash.\n txHash:\n typeof record['transaction'] === 'string' && record['transaction'] !== ''\n ? record['transaction']\n : undefined,\n networkId: typeof record['network'] === 'string' ? record['network'] : undefined,\n raw,\n };\n}\n\nfunction blockedResponse(receipt: Receipt): Response {\n return new Response(\n JSON.stringify({\n error: 'payment_blocked_by_rein',\n outcome: receipt.outcome,\n reason: receipt.reason,\n intentId: receipt.intentId,\n decisionId: receipt.decisionId,\n receiptId: receipt.id,\n }),\n {\n status: 402,\n headers: { 'content-type': 'application/json', 'x-rein-outcome': receipt.outcome },\n },\n );\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reinconsole/sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Rein guard SDK — wrap your agent's fetch once and every x402 payment is policy-checked, receipted, and observable before a cent moves.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://github.com/bugiiiii11/rein#readme",
|
|
@@ -43,14 +43,14 @@
|
|
|
43
43
|
],
|
|
44
44
|
"dependencies": {
|
|
45
45
|
"zod": "^3.24.1",
|
|
46
|
-
"@reinconsole/core": "^0.1.
|
|
46
|
+
"@reinconsole/core": "^0.1.1"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"@types/node": "^22.10.0",
|
|
50
50
|
"tsup": "^8.3.5",
|
|
51
51
|
"typescript": "^5.7.2",
|
|
52
52
|
"vitest": "^2.1.8",
|
|
53
|
-
"@reinconsole/policy-engine": "0.1.
|
|
53
|
+
"@reinconsole/policy-engine": "0.1.1"
|
|
54
54
|
},
|
|
55
55
|
"scripts": {
|
|
56
56
|
"build": "tsup",
|