@reinconsole/sdk 0.1.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Rein contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,46 @@
1
+ # @reinconsole/sdk
2
+
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
+
5
+ > **Status: v0.1 — early open-source infrastructure, live on testnet.** APIs may change before 1.0. See it running: [Rein console](https://reinconsole-production.up.railway.app/).
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install @reinconsole/sdk
11
+ # and something to point it at:
12
+ npx -p @reinconsole/policy-engine rein-policy-engine # the rule engine on :8787
13
+ ```
14
+
15
+ ## Quickstart
16
+
17
+ ```ts
18
+ import { createGuard } from '@reinconsole/sdk';
19
+
20
+ const guard = createGuard({
21
+ engineUrl: 'http://localhost:8787', // @reinconsole/policy-engine (or the durable variant)
22
+ agentId, // registered with the engine
23
+ });
24
+
25
+ const fetch = guard.wrap();
26
+
27
+ // Use it exactly like fetch. When a vendor answers 402:
28
+ // - the guard turns the x402 requirement into a PaymentIntent,
29
+ // - the policy engine evaluates it (budgets, tx caps, allow/deny lists, kill switch),
30
+ // - a signed decision comes back — deny blocks BEFORE any payment exists,
31
+ // - either way you get a Receipt.
32
+ const res = await fetch('https://api.vendor.example/answer');
33
+ ```
34
+
35
+ ## How it behaves
36
+
37
+ - **402 intercept.** The guard wraps the *base* fetch, underneath any x402 payment library. A blocked paywall never reaches the payment layer; an allowed one flows through, and the payment layer's `X-PAYMENT` retry is attached to the same receipt.
38
+ - **Or let it pay.** Pass a `payer` (e.g. the EIP-3009 payer from [`@reinconsole/x402-rails`](https://www.npmjs.com/package/@reinconsole/x402-rails)) and the guard settles allowed payments itself — evaluate → pay → retry, one call.
39
+ - **Blocked, your way.** `onBlocked: 'throw'` (default) raises `PaymentBlockedError`; `'respond'` returns a synthetic 402 JSON response for agent loops that inspect instead of catch.
40
+ - **Task context.** Attach `taskContext` (or scope it per call with `withTask()`) so every decision and receipt says *why* the agent was spending.
41
+ - **Receipts either way.** Every paywall encounter — allowed, denied, settled — becomes a `Receipt`; stream them out with `onReceipt`.
42
+ - **x402 v1 wire + CAIP-2 ids.** Speaks the hosted-facilitator dialect that [x402.org](https://www.x402.org) still fully supports; network ids accept CAIP-2 forms.
43
+
44
+ SDK-mode is advisory + observability: an agent that holds its own key can bypass it — and the indexer flags that as **shadow spend**. The session-key signer tier (keys the agent never holds) is the GA enforcement architecture and lives in the [monorepo](https://github.com/bugiiiii11/rein).
45
+
46
+ MIT © Rein contributors · [Repository](https://github.com/bugiiiii11/rein) · [Issues](https://github.com/bugiiiii11/rein/issues)
package/dist/index.cjs ADDED
@@ -0,0 +1,368 @@
1
+ 'use strict';
2
+
3
+ var async_hooks = require('async_hooks');
4
+ var core = require('@reinconsole/core');
5
+ var zod = require('zod');
6
+
7
+ // src/guard.ts
8
+
9
+ // src/errors.ts
10
+ var ReinError = class extends Error {
11
+ constructor(message) {
12
+ super(message);
13
+ this.name = new.target.name;
14
+ }
15
+ };
16
+ var EngineError = class extends ReinError {
17
+ constructor(status, body, message = `policy engine responded ${status}`) {
18
+ super(message);
19
+ this.status = status;
20
+ this.body = body;
21
+ }
22
+ status;
23
+ body;
24
+ };
25
+ var PaymentBlockedError = class extends ReinError {
26
+ constructor(intent, decision, receipt) {
27
+ super(
28
+ `rein blocked payment of ${intent.amount} ${intent.asset} to ${intent.vendor.host}: ${decision.outcome}${decision.reason ? ` (${decision.reason})` : ""}`
29
+ );
30
+ this.intent = intent;
31
+ this.decision = decision;
32
+ this.receipt = receipt;
33
+ }
34
+ intent;
35
+ decision;
36
+ receipt;
37
+ };
38
+ var UnsupportedRequirementError = class extends ReinError {
39
+ constructor(url) {
40
+ super(`no supported x402 payment requirement in 402 from ${url}; failing closed`);
41
+ this.url = url;
42
+ }
43
+ url;
44
+ };
45
+
46
+ // src/client.ts
47
+ var Health = zod.z.object({ status: zod.z.string(), publicKey: zod.z.string() });
48
+ var EvaluateResponse = zod.z.object({ intent: core.PaymentIntent, decision: core.Decision });
49
+ var EngineClient = class {
50
+ baseUrl;
51
+ fetchImpl;
52
+ constructor(options) {
53
+ this.baseUrl = options.baseUrl.replace(/\/+$/, "");
54
+ const f = options.fetch ?? globalThis.fetch;
55
+ this.fetchImpl = (input, init) => f(input, init);
56
+ }
57
+ async request(method, path, schema, body) {
58
+ const res = await this.fetchImpl(`${this.baseUrl}${path}`, {
59
+ method,
60
+ headers: body === void 0 ? void 0 : { "content-type": "application/json" },
61
+ body: body === void 0 ? void 0 : JSON.stringify(body)
62
+ });
63
+ if (!res.ok) {
64
+ const payload = await res.clone().json().catch(() => res.text().catch(() => void 0));
65
+ throw new EngineError(res.status, payload);
66
+ }
67
+ if (res.status === 204) return schema.parse(void 0);
68
+ return schema.parse(await res.json());
69
+ }
70
+ health() {
71
+ return this.request("GET", "/health", Health);
72
+ }
73
+ registerAgent(input) {
74
+ return this.request("POST", "/v1/agents", core.Agent, input);
75
+ }
76
+ listAgents() {
77
+ return this.request("GET", "/v1/agents", zod.z.array(core.Agent));
78
+ }
79
+ freeze(agentId) {
80
+ return this.request("POST", `/v1/agents/${agentId}/freeze`, zod.z.void());
81
+ }
82
+ unfreeze(agentId) {
83
+ return this.request("POST", `/v1/agents/${agentId}/unfreeze`, zod.z.void());
84
+ }
85
+ addPolicy(policy) {
86
+ return this.request("POST", "/v1/policies", core.Policy, policy);
87
+ }
88
+ listPolicies() {
89
+ return this.request("GET", "/v1/policies", zod.z.array(core.Policy));
90
+ }
91
+ /** The hot path: submit an intent, get the normalized intent + signed decision. */
92
+ evaluate(submission) {
93
+ return this.request("POST", "/v1/evaluate", EvaluateResponse, submission);
94
+ }
95
+ decisions() {
96
+ return this.request("GET", "/v1/decisions", zod.z.array(core.Decision));
97
+ }
98
+ };
99
+ var PaymentRequirement = zod.z.object({
100
+ scheme: zod.z.string(),
101
+ network: zod.z.string(),
102
+ /** Amount in the asset's atomic units (e.g. "10000" = 0.01 USDC at 6 decimals). */
103
+ maxAmountRequired: zod.z.string().regex(/^\d+$/, "atomic amount must be an integer string"),
104
+ resource: zod.z.string().optional(),
105
+ description: zod.z.string().optional(),
106
+ mimeType: zod.z.string().optional(),
107
+ payTo: zod.z.string().min(1),
108
+ maxTimeoutSeconds: zod.z.number().optional(),
109
+ /** Token contract address — or, mock-first, a plain symbol like "USDC". */
110
+ asset: zod.z.string().min(1),
111
+ extra: zod.z.record(zod.z.unknown()).optional()
112
+ });
113
+ var PaymentRequired = zod.z.object({
114
+ x402Version: zod.z.number(),
115
+ accepts: zod.z.array(PaymentRequirement).min(1),
116
+ error: zod.z.string().optional()
117
+ });
118
+ var NETWORK_TO_CHAIN = {
119
+ base: "base",
120
+ "base-sepolia": "base",
121
+ "eip155:8453": "base",
122
+ "eip155:84532": "base",
123
+ solana: "solana",
124
+ "solana-devnet": "solana",
125
+ polygon: "polygon",
126
+ "polygon-amoy": "polygon",
127
+ bnb: "bnb",
128
+ bsc: "bnb"
129
+ };
130
+ var KNOWN_ASSET_ADDRESSES = {
131
+ "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913": "USDC",
132
+ // USDC on Base
133
+ "0x036cbd53842c5426634e7929541ec2318f3dcf7e": "USDC",
134
+ // USDC on Base Sepolia
135
+ EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v: "USDC"
136
+ // USDC on Solana
137
+ };
138
+ function networkToChain(network) {
139
+ return NETWORK_TO_CHAIN[network.toLowerCase()];
140
+ }
141
+ function resolveAsset(requirement, extraAddresses = {}) {
142
+ const direct = core.Asset.safeParse(requirement.asset.toUpperCase());
143
+ if (direct.success) return direct.data;
144
+ const symbol = requirement.extra?.["symbol"];
145
+ if (typeof symbol === "string") {
146
+ const fromExtra = core.Asset.safeParse(symbol.toUpperCase());
147
+ if (fromExtra.success) return fromExtra.data;
148
+ }
149
+ return extraAddresses[requirement.asset] ?? extraAddresses[requirement.asset.toLowerCase()] ?? KNOWN_ASSET_ADDRESSES[requirement.asset] ?? KNOWN_ASSET_ADDRESSES[requirement.asset.toLowerCase()];
150
+ }
151
+ function atomicToDecimal(atomic, decimals) {
152
+ if (!/^\d+$/.test(atomic)) throw new TypeError(`invalid atomic amount: ${atomic}`);
153
+ if (decimals === 0) return atomic.replace(/^0+(?=\d)/, "");
154
+ const digits = atomic.padStart(decimals + 1, "0");
155
+ const intPart = digits.slice(0, digits.length - decimals).replace(/^0+(?=\d)/, "");
156
+ const fracPart = digits.slice(digits.length - decimals).replace(/0+$/, "");
157
+ return fracPart.length > 0 ? `${intPart}.${fracPart}` : intPart;
158
+ }
159
+ function decimalToAtomic(decimal, decimals) {
160
+ if (!/^\d+(\.\d+)?$/.test(decimal)) throw new TypeError(`invalid decimal amount: ${decimal}`);
161
+ const dot = decimal.indexOf(".");
162
+ const intPart = dot === -1 ? decimal : decimal.slice(0, dot);
163
+ const fracPart = dot === -1 ? "" : decimal.slice(dot + 1);
164
+ if (fracPart.length > decimals) {
165
+ throw new TypeError(`amount ${decimal} has more than ${decimals} fraction digits`);
166
+ }
167
+ const atomic = intPart + fracPart.padEnd(decimals, "0");
168
+ return atomic.replace(/^0+(?=\d)/, "");
169
+ }
170
+ function requirementDecimals(requirement) {
171
+ const decimals = requirement.extra?.["decimals"];
172
+ return typeof decimals === "number" && Number.isInteger(decimals) && decimals >= 0 ? decimals : 6;
173
+ }
174
+ function selectRequirement(accepts, extraAddresses = {}) {
175
+ for (const requirement of accepts) {
176
+ if (requirement.scheme.toLowerCase() !== "exact") continue;
177
+ const chain = networkToChain(requirement.network);
178
+ if (!chain) continue;
179
+ const asset = resolveAsset(requirement, extraAddresses);
180
+ if (!asset) continue;
181
+ const amount = atomicToDecimal(requirement.maxAmountRequired, requirementDecimals(requirement));
182
+ return { requirement, chain, asset, amount };
183
+ }
184
+ return void 0;
185
+ }
186
+ function toIntentSubmission(resolved, url, agentId, taskContext) {
187
+ const parsed = new URL(url);
188
+ return {
189
+ agentId,
190
+ vendor: {
191
+ host: parsed.host,
192
+ address: resolved.requirement.payTo
193
+ },
194
+ resource: resolved.requirement.resource ?? parsed.pathname,
195
+ amount: resolved.amount,
196
+ asset: resolved.asset,
197
+ chain: resolved.chain,
198
+ taskContext
199
+ };
200
+ }
201
+
202
+ // src/guard.ts
203
+ var Guard = class {
204
+ client;
205
+ options;
206
+ baseFetch;
207
+ task = new async_hooks.AsyncLocalStorage();
208
+ log = [];
209
+ /** Allowed-but-unsettled receipts awaiting the payment layer's retry, by URL. */
210
+ pendingByUrl = /* @__PURE__ */ new Map();
211
+ constructor(options) {
212
+ core.AgentId.parse(options.agentId);
213
+ this.options = options;
214
+ const f = options.fetch ?? globalThis.fetch;
215
+ this.baseFetch = (input, init) => f(input, init);
216
+ this.client = new EngineClient({ baseUrl: options.engineUrl, fetch: options.engineFetch });
217
+ }
218
+ /** Every receipt this guard has recorded, oldest first. */
219
+ receipts() {
220
+ return this.log;
221
+ }
222
+ /** Run `fn` with a task context attached to every intent submitted inside it. */
223
+ withTask(context, fn) {
224
+ return this.task.run({ ...this.options.taskContext, ...context }, fn);
225
+ }
226
+ /**
227
+ * The one-liner: returns a fetch-compatible function that enforces policy on
228
+ * every x402 paywall. Wraps the guard's base fetch unless one is passed.
229
+ */
230
+ wrap(fetchImpl) {
231
+ const inner = fetchImpl ? (input, init) => fetchImpl(input, init) : this.baseFetch;
232
+ return async (input, init) => {
233
+ const url = requestUrl(input);
234
+ if (readHeader(input, init, "X-PAYMENT") !== null) {
235
+ const res2 = await inner(input, init);
236
+ this.settlePending(url, res2);
237
+ return res2;
238
+ }
239
+ const res = await inner(input, init);
240
+ if (res.status !== 402) return res;
241
+ const body = await res.clone().json().catch(() => void 0);
242
+ const parsed = PaymentRequired.safeParse(body);
243
+ if (!parsed.success) return res;
244
+ const resolved = selectRequirement(parsed.data.accepts, this.options.assetAddresses);
245
+ if (!resolved) throw new UnsupportedRequirementError(url);
246
+ const taskContext = this.task.getStore() ?? this.options.taskContext;
247
+ const submission = toIntentSubmission(resolved, url, this.options.agentId, taskContext);
248
+ const { intent, decision } = await this.client.evaluate(submission);
249
+ if (decision.outcome !== "allow") {
250
+ const receipt = this.record(intent, decision, url, init);
251
+ if (this.options.onBlocked === "respond") return blockedResponse(receipt);
252
+ throw new PaymentBlockedError(intent, decision, receipt);
253
+ }
254
+ if (!this.options.payer) {
255
+ const receipt = this.record(intent, decision, url, init);
256
+ this.pendingByUrl.set(url, receipt);
257
+ return res;
258
+ }
259
+ const paymentHeader = await this.options.payer(resolved.requirement, intent, decision);
260
+ const retry = await inner(input, withHeader(input, init, "X-PAYMENT", paymentHeader));
261
+ this.record(intent, decision, url, init, parseSettlement(retry));
262
+ return retry;
263
+ };
264
+ }
265
+ record(intent, decision, url, init, settlement) {
266
+ const receipt = core.Receipt.parse({
267
+ id: core.newId("rcp"),
268
+ agentId: intent.agentId,
269
+ intentId: intent.id,
270
+ decisionId: decision.id,
271
+ outcome: decision.outcome,
272
+ url,
273
+ method: init?.method ?? "GET",
274
+ vendorHost: intent.vendor.host,
275
+ amount: intent.amount,
276
+ asset: intent.asset,
277
+ chain: intent.chain,
278
+ taskContext: intent.taskContext,
279
+ reason: decision.reason,
280
+ settlement,
281
+ createdAt: /* @__PURE__ */ new Date()
282
+ });
283
+ this.log.push(receipt);
284
+ this.options.onReceipt?.(receipt);
285
+ return receipt;
286
+ }
287
+ settlePending(url, res) {
288
+ const receipt = this.pendingByUrl.get(url);
289
+ if (!receipt || !res.ok) return;
290
+ const settlement = parseSettlement(res);
291
+ if (settlement) receipt.settlement = settlement;
292
+ this.pendingByUrl.delete(url);
293
+ }
294
+ };
295
+ function createGuard(options) {
296
+ return new Guard(options);
297
+ }
298
+ function requestUrl(input) {
299
+ if (typeof input === "string") return input;
300
+ if (input instanceof URL) return input.toString();
301
+ return input.url;
302
+ }
303
+ function readHeader(input, init, name) {
304
+ const source = init?.headers ?? (input instanceof Request ? input.headers : void 0);
305
+ return source === void 0 ? null : new Headers(source).get(name);
306
+ }
307
+ function withHeader(input, init, name, value) {
308
+ const headers = new Headers(
309
+ init?.headers ?? (input instanceof Request ? input.headers : void 0)
310
+ );
311
+ headers.set(name, value);
312
+ return { ...init, headers };
313
+ }
314
+ function parseSettlement(res) {
315
+ const raw = res.headers.get("X-PAYMENT-RESPONSE");
316
+ if (raw === null) return void 0;
317
+ let payload;
318
+ try {
319
+ payload = JSON.parse(raw);
320
+ } catch {
321
+ try {
322
+ payload = JSON.parse(Buffer.from(raw, "base64").toString("utf8"));
323
+ } catch {
324
+ return { raw };
325
+ }
326
+ }
327
+ const record = typeof payload === "object" && payload !== null ? payload : {};
328
+ return {
329
+ txHash: typeof record["transaction"] === "string" ? record["transaction"] : void 0,
330
+ networkId: typeof record["network"] === "string" ? record["network"] : void 0,
331
+ raw
332
+ };
333
+ }
334
+ function blockedResponse(receipt) {
335
+ return new Response(
336
+ JSON.stringify({
337
+ error: "payment_blocked_by_rein",
338
+ outcome: receipt.outcome,
339
+ reason: receipt.reason,
340
+ intentId: receipt.intentId,
341
+ decisionId: receipt.decisionId,
342
+ receiptId: receipt.id
343
+ }),
344
+ {
345
+ status: 402,
346
+ headers: { "content-type": "application/json", "x-rein-outcome": receipt.outcome }
347
+ }
348
+ );
349
+ }
350
+
351
+ exports.EngineClient = EngineClient;
352
+ exports.EngineError = EngineError;
353
+ exports.Guard = Guard;
354
+ exports.PaymentBlockedError = PaymentBlockedError;
355
+ exports.PaymentRequired = PaymentRequired;
356
+ exports.PaymentRequirement = PaymentRequirement;
357
+ exports.ReinError = ReinError;
358
+ exports.UnsupportedRequirementError = UnsupportedRequirementError;
359
+ exports.atomicToDecimal = atomicToDecimal;
360
+ exports.createGuard = createGuard;
361
+ exports.decimalToAtomic = decimalToAtomic;
362
+ exports.networkToChain = networkToChain;
363
+ exports.requirementDecimals = requirementDecimals;
364
+ exports.resolveAsset = resolveAsset;
365
+ exports.selectRequirement = selectRequirement;
366
+ exports.toIntentSubmission = toIntentSubmission;
367
+ //# sourceMappingURL=index.cjs.map
368
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +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":";;;;;;;;;AAGO,IAAM,SAAA,GAAN,cAAwB,KAAA,CAAM;AAAA,EACnC,YAAY,OAAA,EAAiB;AAC3B,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,OAAO,GAAA,CAAA,MAAA,CAAW,IAAA;AAAA,EACzB;AACF;AAGO,IAAM,WAAA,GAAN,cAA0B,SAAA,CAAU;AAAA,EACzC,YACW,MAAA,EACA,IAAA,EACT,OAAA,GAAU,CAAA,wBAAA,EAA2B,MAAM,CAAA,CAAA,EAC3C;AACA,IAAA,KAAA,CAAM,OAAO,CAAA;AAJJ,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AACA,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AAAA,EAIX;AAAA,EALW,MAAA;AAAA,EACA,IAAA;AAKb;AAOO,IAAM,mBAAA,GAAN,cAAkC,SAAA,CAAU;AAAA,EACjD,WAAA,CACW,MAAA,EACA,QAAA,EACA,OAAA,EACT;AACA,IAAA,KAAA;AAAA,MACE,CAAA,wBAAA,EAA2B,OAAO,MAAM,CAAA,CAAA,EAAI,OAAO,KAAK,CAAA,IAAA,EAAO,OAAO,MAAA,CAAO,IAAI,KAC5E,QAAA,CAAS,OAAO,GAAG,QAAA,CAAS,MAAA,GAAS,KAAK,QAAA,CAAS,MAAM,MAAM,EAAE,CAAA;AAAA,KACxE;AAPS,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AACA,IAAA,IAAA,CAAA,QAAA,GAAA,QAAA;AACA,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA;AAAA,EAMX;AAAA,EARW,MAAA;AAAA,EACA,QAAA;AAAA,EACA,OAAA;AAOb;AAOO,IAAM,2BAAA,GAAN,cAA0C,SAAA,CAAU;AAAA,EACzD,YAAqB,GAAA,EAAa;AAChC,IAAA,KAAA,CAAM,CAAA,kDAAA,EAAqD,GAAG,CAAA,gBAAA,CAAkB,CAAA;AAD7D,IAAA,IAAA,CAAA,GAAA,GAAA,GAAA;AAAA,EAErB;AAAA,EAFqB,GAAA;AAGvB;;;ACxCA,IAAM,MAAA,GAASA,KAAA,CAAE,MAAA,CAAO,EAAE,MAAA,EAAQA,KAAA,CAAE,MAAA,EAAO,EAAG,SAAA,EAAWA,KAAA,CAAE,MAAA,EAAO,EAAG,CAAA;AACrE,IAAM,gBAAA,GAAmBA,MAAE,MAAA,CAAO,EAAE,QAAQC,kBAAA,EAAe,QAAA,EAAUC,eAAU,CAAA;AAcxE,IAAM,eAAN,MAAmB;AAAA,EACP,OAAA;AAAA,EACA,SAAA;AAAA,EAEjB,YAAY,OAAA,EAA8B;AACxC,IAAA,IAAA,CAAK,OAAA,GAAU,OAAA,CAAQ,OAAA,CAAQ,OAAA,CAAQ,QAAQ,EAAE,CAAA;AACjD,IAAA,MAAM,CAAA,GAAI,OAAA,CAAQ,KAAA,IAAS,UAAA,CAAW,KAAA;AACtC,IAAA,IAAA,CAAK,YAAY,CAAC,KAAA,EAAO,IAAA,KAAS,CAAA,CAAE,OAAO,IAAI,CAAA;AAAA,EACjD;AAAA,EAEA,MAAc,OAAA,CACZ,MAAA,EACA,IAAA,EACA,QACA,IAAA,EACY;AACZ,IAAA,MAAM,GAAA,GAAM,MAAM,IAAA,CAAK,SAAA,CAAU,GAAG,IAAA,CAAK,OAAO,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI;AAAA,MACzD,MAAA;AAAA,MACA,SAAS,IAAA,KAAS,MAAA,GAAY,MAAA,GAAY,EAAE,gBAAgB,kBAAA,EAAmB;AAAA,MAC/E,MAAM,IAAA,KAAS,MAAA,GAAY,MAAA,GAAY,IAAA,CAAK,UAAU,IAAI;AAAA,KAC3D,CAAA;AACD,IAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,MAAA,MAAM,OAAA,GAAU,MAAM,GAAA,CACnB,KAAA,GACA,IAAA,EAAK,CACL,KAAA,CAAM,MAAM,IAAI,IAAA,EAAK,CAAE,KAAA,CAAM,MAAM,MAAS,CAAC,CAAA;AAChD,MAAA,MAAM,IAAI,WAAA,CAAY,GAAA,CAAI,MAAA,EAAQ,OAAO,CAAA;AAAA,IAC3C;AACA,IAAA,IAAI,IAAI,MAAA,KAAW,GAAA,EAAK,OAAO,MAAA,CAAO,MAAM,MAAS,CAAA;AACrD,IAAA,OAAO,MAAA,CAAO,KAAA,CAAM,MAAM,GAAA,CAAI,MAAM,CAAA;AAAA,EACtC;AAAA,EAEA,MAAA,GAA0C;AACxC,IAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,KAAA,EAAO,SAAA,EAAW,MAAM,CAAA;AAAA,EAC9C;AAAA,EAEA,cAAc,KAAA,EAKK;AACjB,IAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,MAAA,EAAQ,YAAA,EAAcC,YAAO,KAAK,CAAA;AAAA,EACxD;AAAA,EAEA,UAAA,GAA+B;AAC7B,IAAA,OAAO,KAAK,OAAA,CAAQ,KAAA,EAAO,cAAcH,KAAA,CAAE,KAAA,CAAMG,UAAK,CAAC,CAAA;AAAA,EACzD;AAAA,EAEA,OAAO,OAAA,EAAgC;AACrC,IAAA,OAAO,IAAA,CAAK,QAAQ,MAAA,EAAQ,CAAA,WAAA,EAAc,OAAO,CAAA,OAAA,CAAA,EAAWH,KAAA,CAAE,MAAM,CAAA;AAAA,EACtE;AAAA,EAEA,SAAS,OAAA,EAAgC;AACvC,IAAA,OAAO,IAAA,CAAK,QAAQ,MAAA,EAAQ,CAAA,WAAA,EAAc,OAAO,CAAA,SAAA,CAAA,EAAaA,KAAA,CAAE,MAAM,CAAA;AAAA,EACxE;AAAA,EAEA,UAAU,MAAA,EAAiD;AACzD,IAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,MAAA,EAAQ,cAAA,EAAgBI,aAAQ,MAAM,CAAA;AAAA,EAC5D;AAAA,EAEA,YAAA,GAAkC;AAChC,IAAA,OAAO,KAAK,OAAA,CAAQ,KAAA,EAAO,gBAAgBJ,KAAA,CAAE,KAAA,CAAMI,WAAM,CAAC,CAAA;AAAA,EAC5D;AAAA;AAAA,EAGA,SAAS,UAAA,EAAyD;AAChE,IAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,MAAA,EAAQ,cAAA,EAAgB,kBAAkB,UAAU,CAAA;AAAA,EAC1E;AAAA,EAEA,SAAA,GAAiC;AAC/B,IAAA,OAAO,KAAK,OAAA,CAAQ,KAAA,EAAO,iBAAiBJ,KAAA,CAAE,KAAA,CAAME,aAAQ,CAAC,CAAA;AAAA,EAC/D;AACF;ACtFO,IAAM,kBAAA,GAAqBF,MAAE,MAAA,CAAO;AAAA,EACzC,MAAA,EAAQA,MAAE,MAAA,EAAO;AAAA,EACjB,OAAA,EAASA,MAAE,MAAA,EAAO;AAAA;AAAA,EAElB,mBAAmBA,KAAAA,CAAE,MAAA,EAAO,CAAE,KAAA,CAAM,SAAS,yCAAyC,CAAA;AAAA,EACtF,QAAA,EAAUA,KAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,EAC9B,WAAA,EAAaA,KAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,EACjC,QAAA,EAAUA,KAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,EAC9B,KAAA,EAAOA,KAAAA,CAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA;AAAA,EACvB,iBAAA,EAAmBA,KAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA;AAAA,EAEvC,KAAA,EAAOA,KAAAA,CAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA;AAAA,EACvB,OAAOA,KAAAA,CAAE,MAAA,CAAOA,MAAE,OAAA,EAAS,EAAE,QAAA;AAC/B,CAAC;AAIM,IAAM,eAAA,GAAkBA,MAAE,MAAA,CAAO;AAAA,EACtC,WAAA,EAAaA,MAAE,MAAA,EAAO;AAAA,EACtB,SAASA,KAAAA,CAAE,KAAA,CAAM,kBAAkB,CAAA,CAAE,IAAI,CAAC,CAAA;AAAA,EAC1C,KAAA,EAAOA,KAAAA,CAAE,MAAA,EAAO,CAAE,QAAA;AACpB,CAAC;AAQD,IAAM,gBAAA,GAA0C;AAAA,EAC9C,IAAA,EAAM,MAAA;AAAA,EACN,cAAA,EAAgB,MAAA;AAAA,EAChB,aAAA,EAAe,MAAA;AAAA,EACf,cAAA,EAAgB,MAAA;AAAA,EAChB,MAAA,EAAQ,QAAA;AAAA,EACR,eAAA,EAAiB,QAAA;AAAA,EACjB,OAAA,EAAS,SAAA;AAAA,EACT,cAAA,EAAgB,SAAA;AAAA,EAChB,GAAA,EAAK,KAAA;AAAA,EACL,GAAA,EAAK;AACP,CAAA;AAGA,IAAM,qBAAA,GAA+C;AAAA,EACnD,4CAAA,EAA8C,MAAA;AAAA;AAAA,EAC9C,4CAAA,EAA8C,MAAA;AAAA;AAAA,EAC9C,4CAAA,EAA8C;AAAA;AAChD,CAAA;AAEO,SAAS,eAAe,OAAA,EAAoC;AACjE,EAAA,OAAO,gBAAA,CAAiB,OAAA,CAAQ,WAAA,EAAa,CAAA;AAC/C;AAQO,SAAS,YAAA,CACd,WAAA,EACA,cAAA,GAAwC,EAAC,EACtB;AACnB,EAAA,MAAM,SAASK,UAAA,CAAM,SAAA,CAAU,WAAA,CAAY,KAAA,CAAM,aAAa,CAAA;AAC9D,EAAA,IAAI,MAAA,CAAO,OAAA,EAAS,OAAO,MAAA,CAAO,IAAA;AAElC,EAAA,MAAM,MAAA,GAAS,WAAA,CAAY,KAAA,GAAQ,QAAQ,CAAA;AAC3C,EAAA,IAAI,OAAO,WAAW,QAAA,EAAU;AAC9B,IAAA,MAAM,SAAA,GAAYA,UAAA,CAAM,SAAA,CAAU,MAAA,CAAO,aAAa,CAAA;AACtD,IAAA,IAAI,SAAA,CAAU,OAAA,EAAS,OAAO,SAAA,CAAU,IAAA;AAAA,EAC1C;AAEA,EAAA,OACE,eAAe,WAAA,CAAY,KAAK,KAChC,cAAA,CAAe,WAAA,CAAY,MAAM,WAAA,EAAa,CAAA,IAC9C,qBAAA,CAAsB,YAAY,KAAK,CAAA,IACvC,sBAAsB,WAAA,CAAY,KAAA,CAAM,aAAa,CAAA;AAEzD;AAOO,SAAS,eAAA,CAAgB,QAAgB,QAAA,EAA0B;AACxE,EAAA,IAAI,CAAC,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAA,QAAS,IAAI,SAAA,CAAU,CAAA,uBAAA,EAA0B,MAAM,CAAA,CAAE,CAAA;AACjF,EAAA,IAAI,aAAa,CAAA,EAAG,OAAO,MAAA,CAAO,OAAA,CAAQ,aAAa,EAAE,CAAA;AACzD,EAAA,MAAM,MAAA,GAAS,MAAA,CAAO,QAAA,CAAS,QAAA,GAAW,GAAG,GAAG,CAAA;AAChD,EAAA,MAAM,OAAA,GAAU,MAAA,CAAO,KAAA,CAAM,CAAA,EAAG,MAAA,CAAO,SAAS,QAAQ,CAAA,CAAE,OAAA,CAAQ,WAAA,EAAa,EAAE,CAAA;AACjF,EAAA,MAAM,QAAA,GAAW,OAAO,KAAA,CAAM,MAAA,CAAO,SAAS,QAAQ,CAAA,CAAE,OAAA,CAAQ,KAAA,EAAO,EAAE,CAAA;AACzE,EAAA,OAAO,SAAS,MAAA,GAAS,CAAA,GAAI,GAAG,OAAO,CAAA,CAAA,EAAI,QAAQ,CAAA,CAAA,GAAK,OAAA;AAC1D;AAQO,SAAS,eAAA,CAAgB,SAAiB,QAAA,EAA0B;AACzE,EAAA,IAAI,CAAC,eAAA,CAAgB,IAAA,CAAK,OAAO,CAAA,QAAS,IAAI,SAAA,CAAU,CAAA,wBAAA,EAA2B,OAAO,CAAA,CAAE,CAAA;AAC5F,EAAA,MAAM,GAAA,GAAM,OAAA,CAAQ,OAAA,CAAQ,GAAG,CAAA;AAC/B,EAAA,MAAM,UAAU,GAAA,KAAQ,EAAA,GAAK,UAAU,OAAA,CAAQ,KAAA,CAAM,GAAG,GAAG,CAAA;AAC3D,EAAA,MAAM,WAAW,GAAA,KAAQ,EAAA,GAAK,KAAK,OAAA,CAAQ,KAAA,CAAM,MAAM,CAAC,CAAA;AACxD,EAAA,IAAI,QAAA,CAAS,SAAS,QAAA,EAAU;AAC9B,IAAA,MAAM,IAAI,SAAA,CAAU,CAAA,OAAA,EAAU,OAAO,CAAA,eAAA,EAAkB,QAAQ,CAAA,gBAAA,CAAkB,CAAA;AAAA,EACnF;AACA,EAAA,MAAM,MAAA,GAAS,OAAA,GAAU,QAAA,CAAS,MAAA,CAAO,UAAU,GAAG,CAAA;AACtD,EAAA,OAAO,MAAA,CAAO,OAAA,CAAQ,WAAA,EAAa,EAAE,CAAA;AACvC;AAEO,SAAS,oBAAoB,WAAA,EAAyC;AAC3E,EAAA,MAAM,QAAA,GAAW,WAAA,CAAY,KAAA,GAAQ,UAAU,CAAA;AAC/C,EAAA,OAAO,OAAO,aAAa,QAAA,IAAY,MAAA,CAAO,UAAU,QAAQ,CAAA,IAAK,QAAA,IAAY,CAAA,GAAI,QAAA,GAAW,CAAA;AAClG;AAgBO,SAAS,iBAAA,CACd,OAAA,EACA,cAAA,GAAwC,EAAC,EACR;AACjC,EAAA,KAAA,MAAW,eAAe,OAAA,EAAS;AACjC,IAAA,IAAI,WAAA,CAAY,MAAA,CAAO,WAAA,EAAY,KAAM,OAAA,EAAS;AAClD,IAAA,MAAM,KAAA,GAAQ,cAAA,CAAe,WAAA,CAAY,OAAO,CAAA;AAChD,IAAA,IAAI,CAAC,KAAA,EAAO;AACZ,IAAA,MAAM,KAAA,GAAQ,YAAA,CAAa,WAAA,EAAa,cAAc,CAAA;AACtD,IAAA,IAAI,CAAC,KAAA,EAAO;AACZ,IAAA,MAAM,SAAS,eAAA,CAAgB,WAAA,CAAY,iBAAA,EAAmB,mBAAA,CAAoB,WAAW,CAAC,CAAA;AAC9F,IAAA,OAAO,EAAE,WAAA,EAAa,KAAA,EAAO,KAAA,EAAO,MAAA,EAAO;AAAA,EAC7C;AACA,EAAA,OAAO,MAAA;AACT;AAcO,SAAS,kBAAA,CACd,QAAA,EACA,GAAA,EACA,OAAA,EACA,WAAA,EACkB;AAClB,EAAA,MAAM,MAAA,GAAS,IAAI,GAAA,CAAI,GAAG,CAAA;AAC1B,EAAA,OAAO;AAAA,IACL,OAAA;AAAA,IACA,MAAA,EAAQ;AAAA,MACN,MAAM,MAAA,CAAO,IAAA;AAAA,MACb,OAAA,EAAS,SAAS,WAAA,CAAY;AAAA,KAChC;AAAA,IACA,QAAA,EAAU,QAAA,CAAS,WAAA,CAAY,QAAA,IAAY,MAAA,CAAO,QAAA;AAAA,IAClD,QAAQ,QAAA,CAAS,MAAA;AAAA,IACjB,OAAO,QAAA,CAAS,KAAA;AAAA,IAChB,OAAO,QAAA,CAAS,KAAA;AAAA,IAChB;AAAA,GACF;AACF;;;ACxHO,IAAM,QAAN,MAAY;AAAA,EACR,MAAA;AAAA,EACQ,OAAA;AAAA,EACA,SAAA;AAAA,EACA,IAAA,GAAO,IAAIC,6BAAA,EAA+B;AAAA,EAC1C,MAAiB,EAAC;AAAA;AAAA,EAElB,YAAA,uBAAmB,GAAA,EAAqB;AAAA,EAEzD,YAAY,OAAA,EAAuB;AACjC,IAAAC,YAAA,CAAQ,KAAA,CAAM,QAAQ,OAAO,CAAA;AAC7B,IAAA,IAAA,CAAK,OAAA,GAAU,OAAA;AACf,IAAA,MAAM,CAAA,GAAI,OAAA,CAAQ,KAAA,IAAS,UAAA,CAAW,KAAA;AACtC,IAAA,IAAA,CAAK,YAAY,CAAC,KAAA,EAAO,IAAA,KAAS,CAAA,CAAE,OAAO,IAAI,CAAA;AAC/C,IAAA,IAAA,CAAK,MAAA,GAAS,IAAI,YAAA,CAAa,EAAE,OAAA,EAAS,QAAQ,SAAA,EAAW,KAAA,EAAO,OAAA,CAAQ,WAAA,EAAa,CAAA;AAAA,EAC3F;AAAA;AAAA,EAGA,QAAA,GAA+B;AAC7B,IAAA,OAAO,IAAA,CAAK,GAAA;AAAA,EACd;AAAA;AAAA,EAGA,QAAA,CAAY,SAAsB,EAAA,EAAgB;AAChD,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,GAAA,CAAI,EAAE,GAAG,IAAA,CAAK,OAAA,CAAQ,WAAA,EAAa,GAAG,OAAA,EAAQ,EAAG,EAAE,CAAA;AAAA,EACtE;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,KAAK,SAAA,EAAkC;AACrC,IAAA,MAAM,KAAA,GAAmB,YAAY,CAAC,KAAA,EAAO,SAAS,SAAA,CAAU,KAAA,EAAO,IAAI,CAAA,GAAI,IAAA,CAAK,SAAA;AAEpF,IAAA,OAAO,OAAO,OAAO,IAAA,KAAS;AAC5B,MAAA,MAAM,GAAA,GAAM,WAAW,KAAK,CAAA;AAG5B,MAAA,IAAI,UAAA,CAAW,KAAA,EAAO,IAAA,EAAM,WAAW,MAAM,IAAA,EAAM;AACjD,QAAA,MAAMC,IAAAA,GAAM,MAAM,KAAA,CAAM,KAAA,EAAO,IAAI,CAAA;AACnC,QAAA,IAAA,CAAK,aAAA,CAAc,KAAKA,IAAG,CAAA;AAC3B,QAAA,OAAOA,IAAAA;AAAA,MACT;AAEA,MAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,KAAA,EAAO,IAAI,CAAA;AACnC,MAAA,IAAI,GAAA,CAAI,MAAA,KAAW,GAAA,EAAK,OAAO,GAAA;AAE/B,MAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAChB,KAAA,GACA,IAAA,EAAK,CACL,KAAA,CAAM,MAAM,MAAS,CAAA;AACxB,MAAA,MAAM,MAAA,GAAS,eAAA,CAAgB,SAAA,CAAU,IAAI,CAAA;AAE7C,MAAA,IAAI,CAAC,MAAA,CAAO,OAAA,EAAS,OAAO,GAAA;AAE5B,MAAA,MAAM,WAAW,iBAAA,CAAkB,MAAA,CAAO,KAAK,OAAA,EAAS,IAAA,CAAK,QAAQ,cAAc,CAAA;AACnF,MAAA,IAAI,CAAC,QAAA,EAAU,MAAM,IAAI,4BAA4B,GAAG,CAAA;AAExD,MAAA,MAAM,cAAc,IAAA,CAAK,IAAA,CAAK,QAAA,EAAS,IAAK,KAAK,OAAA,CAAQ,WAAA;AACzD,MAAA,MAAM,aAAa,kBAAA,CAAmB,QAAA,EAAU,KAAK,IAAA,CAAK,OAAA,CAAQ,SAAS,WAAW,CAAA;AACtF,MAAA,MAAM,EAAE,QAAQ,QAAA,EAAS,GAAI,MAAM,IAAA,CAAK,MAAA,CAAO,SAAS,UAAU,CAAA;AAElE,MAAA,IAAI,QAAA,CAAS,YAAY,OAAA,EAAS;AAChC,QAAA,MAAM,UAAU,IAAA,CAAK,MAAA,CAAO,MAAA,EAAQ,QAAA,EAAU,KAAK,IAAI,CAAA;AACvD,QAAA,IAAI,KAAK,OAAA,CAAQ,SAAA,KAAc,SAAA,EAAW,OAAO,gBAAgB,OAAO,CAAA;AACxE,QAAA,MAAM,IAAI,mBAAA,CAAoB,MAAA,EAAQ,QAAA,EAAU,OAAO,CAAA;AAAA,MACzD;AAEA,MAAA,IAAI,CAAC,IAAA,CAAK,OAAA,CAAQ,KAAA,EAAO;AAGvB,QAAA,MAAM,UAAU,IAAA,CAAK,MAAA,CAAO,MAAA,EAAQ,QAAA,EAAU,KAAK,IAAI,CAAA;AACvD,QAAA,IAAA,CAAK,YAAA,CAAa,GAAA,CAAI,GAAA,EAAK,OAAO,CAAA;AAClC,QAAA,OAAO,GAAA;AAAA,MACT;AAEA,MAAA,MAAM,aAAA,GAAgB,MAAM,IAAA,CAAK,OAAA,CAAQ,MAAM,QAAA,CAAS,WAAA,EAAa,QAAQ,QAAQ,CAAA;AACrF,MAAA,MAAM,KAAA,GAAQ,MAAM,KAAA,CAAM,KAAA,EAAO,WAAW,KAAA,EAAO,IAAA,EAAM,WAAA,EAAa,aAAa,CAAC,CAAA;AACpF,MAAA,IAAA,CAAK,OAAO,MAAA,EAAQ,QAAA,EAAU,KAAK,IAAA,EAAM,eAAA,CAAgB,KAAK,CAAC,CAAA;AAC/D,MAAA,OAAO,KAAA;AAAA,IACT,CAAA;AAAA,EACF;AAAA,EAEQ,MAAA,CACN,MAAA,EACA,QAAA,EACA,GAAA,EACA,MACA,UAAA,EACS;AACT,IAAA,MAAM,OAAA,GAAUC,aAAQ,KAAA,CAAM;AAAA,MAC5B,EAAA,EAAIC,WAAM,KAAK,CAAA;AAAA,MACf,SAAS,MAAA,CAAO,OAAA;AAAA,MAChB,UAAU,MAAA,CAAO,EAAA;AAAA,MACjB,YAAY,QAAA,CAAS,EAAA;AAAA,MACrB,SAAS,QAAA,CAAS,OAAA;AAAA,MAClB,GAAA;AAAA,MACA,MAAA,EAAQ,MAAM,MAAA,IAAU,KAAA;AAAA,MACxB,UAAA,EAAY,OAAO,MAAA,CAAO,IAAA;AAAA,MAC1B,QAAQ,MAAA,CAAO,MAAA;AAAA,MACf,OAAO,MAAA,CAAO,KAAA;AAAA,MACd,OAAO,MAAA,CAAO,KAAA;AAAA,MACd,aAAa,MAAA,CAAO,WAAA;AAAA,MACpB,QAAQ,QAAA,CAAS,MAAA;AAAA,MACjB,UAAA;AAAA,MACA,SAAA,sBAAe,IAAA;AAAK,KACrB,CAAA;AACD,IAAA,IAAA,CAAK,GAAA,CAAI,KAAK,OAAO,CAAA;AACrB,IAAA,IAAA,CAAK,OAAA,CAAQ,YAAY,OAAO,CAAA;AAChC,IAAA,OAAO,OAAA;AAAA,EACT;AAAA,EAEQ,aAAA,CAAc,KAAa,GAAA,EAAqB;AACtD,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,YAAA,CAAa,GAAA,CAAI,GAAG,CAAA;AACzC,IAAA,IAAI,CAAC,OAAA,IAAW,CAAC,GAAA,CAAI,EAAA,EAAI;AACzB,IAAA,MAAM,UAAA,GAAa,gBAAgB,GAAG,CAAA;AACtC,IAAA,IAAI,UAAA,UAAoB,UAAA,GAAa,UAAA;AACrC,IAAA,IAAA,CAAK,YAAA,CAAa,OAAO,GAAG,CAAA;AAAA,EAC9B;AACF;AAGO,SAAS,YAAY,OAAA,EAA8B;AACxD,EAAA,OAAO,IAAI,MAAM,OAAO,CAAA;AAC1B;AAEA,SAAS,WAAW,KAAA,EAAuC;AACzD,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,EAAU,OAAO,KAAA;AACtC,EAAA,IAAI,KAAA,YAAiB,GAAA,EAAK,OAAO,KAAA,CAAM,QAAA,EAAS;AAChD,EAAA,OAAO,KAAA,CAAM,GAAA;AACf;AAEA,SAAS,UAAA,CACP,KAAA,EACA,IAAA,EACA,IAAA,EACe;AACf,EAAA,MAAM,SAAS,IAAA,EAAM,OAAA,KAAY,KAAA,YAAiB,OAAA,GAAU,MAAM,OAAA,GAAU,MAAA,CAAA;AAC5E,EAAA,OAAO,MAAA,KAAW,SAAY,IAAA,GAAO,IAAI,QAAQ,MAAM,CAAA,CAAE,IAAI,IAAI,CAAA;AACnE;AAEA,SAAS,UAAA,CACP,KAAA,EACA,IAAA,EACA,IAAA,EACA,KAAA,EACa;AACb,EAAA,MAAM,UAAU,IAAI,OAAA;AAAA,IAClB,IAAA,EAAM,OAAA,KAAY,KAAA,YAAiB,OAAA,GAAU,MAAM,OAAA,GAAU,MAAA;AAAA,GAC/D;AACA,EAAA,OAAA,CAAQ,GAAA,CAAI,MAAM,KAAK,CAAA;AACvB,EAAA,OAAO,EAAE,GAAG,IAAA,EAAM,OAAA,EAAQ;AAC5B;AAMA,SAAS,gBAAgB,GAAA,EAA8C;AACrE,EAAA,MAAM,GAAA,GAAM,GAAA,CAAI,OAAA,CAAQ,GAAA,CAAI,oBAAoB,CAAA;AAChD,EAAA,IAAI,GAAA,KAAQ,MAAM,OAAO,MAAA;AACzB,EAAA,IAAI,OAAA;AACJ,EAAA,IAAI;AACF,IAAA,OAAA,GAAU,IAAA,CAAK,MAAM,GAAG,CAAA;AAAA,EAC1B,CAAA,CAAA,MAAQ;AACN,IAAA,IAAI;AACF,MAAA,OAAA,GAAU,IAAA,CAAK,MAAM,MAAA,CAAO,IAAA,CAAK,KAAK,QAAQ,CAAA,CAAE,QAAA,CAAS,MAAM,CAAC,CAAA;AAAA,IAClE,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,EAAE,GAAA,EAAI;AAAA,IACf;AAAA,EACF;AACA,EAAA,MAAM,SACJ,OAAO,OAAA,KAAY,YAAY,OAAA,KAAY,IAAA,GAAQ,UAAsC,EAAC;AAC5F,EAAA,OAAO;AAAA,IACL,MAAA,EAAQ,OAAO,MAAA,CAAO,aAAa,MAAM,QAAA,GAAW,MAAA,CAAO,aAAa,CAAA,GAAI,MAAA;AAAA,IAC5E,SAAA,EAAW,OAAO,MAAA,CAAO,SAAS,MAAM,QAAA,GAAW,MAAA,CAAO,SAAS,CAAA,GAAI,MAAA;AAAA,IACvE;AAAA,GACF;AACF;AAEA,SAAS,gBAAgB,OAAA,EAA4B;AACnD,EAAA,OAAO,IAAI,QAAA;AAAA,IACT,KAAK,SAAA,CAAU;AAAA,MACb,KAAA,EAAO,yBAAA;AAAA,MACP,SAAS,OAAA,CAAQ,OAAA;AAAA,MACjB,QAAQ,OAAA,CAAQ,MAAA;AAAA,MAChB,UAAU,OAAA,CAAQ,QAAA;AAAA,MAClB,YAAY,OAAA,CAAQ,UAAA;AAAA,MACpB,WAAW,OAAA,CAAQ;AAAA,KACpB,CAAA;AAAA,IACD;AAAA,MACE,MAAA,EAAQ,GAAA;AAAA,MACR,SAAS,EAAE,cAAA,EAAgB,kBAAA,EAAoB,gBAAA,EAAkB,QAAQ,OAAA;AAAQ;AACnF,GACF;AACF","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"]}