@reinconsole/mock-rails 0.2.0 → 0.3.0-rc.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/dist/index.js CHANGED
@@ -2,11 +2,70 @@
2
2
  import { EventEmitter } from "events";
3
3
  import { randomBytes } from "crypto";
4
4
 
5
- // ../../packages/core/dist/index.js
5
+ // ../../packages/core/dist/chunk-6H2LDEB7.js
6
6
  import { z } from "zod";
7
- var Chain = z.enum(["base", "solana", "polygon", "bnb"]);
8
- var Asset = z.enum(["USDC", "USDT", "EURC"]);
9
- var DecimalString = z.string().regex(/^\d+(\.\d+)?$/, 'must be a non-negative decimal string, e.g. "5.00"');
7
+ var ULID_BODY = "[0-9A-HJKMNP-TV-Z]{26}";
8
+ function prefixedId(prefix) {
9
+ return z.string().regex(new RegExp(`^${prefix}_${ULID_BODY}$`), `expected a "${prefix}_" prefixed id`);
10
+ }
11
+ var OrgId = prefixedId("org");
12
+ var AgentId = prefixedId("agt");
13
+ var PolicyId = prefixedId("pol");
14
+ var IntentId = prefixedId("int");
15
+ var DecisionId = prefixedId("dec");
16
+ var ReceiptId = prefixedId("rcp");
17
+ var SessionId = prefixedId("ses");
18
+ var GateReceiptId = prefixedId("grc");
19
+ var ApiKeyId = prefixedId("key");
20
+ var ApproverKeyId = prefixedId("apk");
21
+ var ApiKeyScope = z.enum(["read", "evaluate", "approve", "report", "admin"]);
22
+ var ApiKey = z.object({
23
+ id: ApiKeyId,
24
+ name: z.string().min(1).max(200),
25
+ scopes: z.array(ApiKeyScope).min(1),
26
+ /**
27
+ * The org this key acts inside. ABSENT means unscoped — an operator key that
28
+ * reads and writes across every org, which is what a self-hosted single-org
29
+ * deployment and every env-seeded boot secret have always been. That is the
30
+ * compatibility rule the whole tenancy design rests on: adding tenancy
31
+ * changed no existing key's behaviour, because no existing key has this
32
+ * field.
33
+ *
34
+ * Present, it is a hard confinement, not a default: the key cannot read,
35
+ * spend, approve or govern outside the org, and a write it submits is
36
+ * stamped with this org rather than the one the body asked for.
37
+ */
38
+ orgId: OrgId.optional(),
39
+ /**
40
+ * Narrow an org-scoped key further, to specific agents — what an agent
41
+ * runtime should carry, so a stolen key spends one agent's budget rather
42
+ * than the org's. Only meaningful alongside {@link ApiKey.orgId}: agent
43
+ * narrowing without an org is refused at issuance, because the scope it
44
+ * would describe has no org to resolve policies and approvers in.
45
+ *
46
+ * Capped at 64: a list long enough to need more is a fleet, and a fleet is
47
+ * what the org scope is for.
48
+ */
49
+ agentIds: z.array(AgentId).max(64).optional(),
50
+ createdAt: z.coerce.date(),
51
+ /** Last successful authentication, for spotting keys that can be retired. */
52
+ lastUsedAt: z.coerce.date().optional(),
53
+ /** Set by revoke(); a revoked key never authenticates again. */
54
+ revokedAt: z.coerce.date().optional(),
55
+ /** Set by rotate(); with `previousSecretExpiresAt` it dates the overlap. */
56
+ rotatedAt: z.coerce.date().optional()
57
+ });
58
+ var ApiKeyRecord = ApiKey.extend({
59
+ secretHash: z.string(),
60
+ previousSecretHash: z.string().optional(),
61
+ previousSecretExpiresAt: z.coerce.date().optional()
62
+ });
63
+
64
+ // ../../packages/core/dist/index.js
65
+ import { z as z2 } from "zod";
66
+ var Chain = z2.enum(["base", "solana", "polygon", "bnb"]);
67
+ var Asset = z2.enum(["USDC", "USDT", "EURC"]);
68
+ var DecimalString = z2.string().regex(/^\d+(\.\d+)?$/, 'must be a non-negative decimal string, e.g. "5.00"');
10
69
  var DECIMAL_RE = /^\d+(\.\d+)?$/;
11
70
  function isValidDecimal(value) {
12
71
  return DECIMAL_RE.test(value);
@@ -35,39 +94,25 @@ function compareDecimal(a, b) {
35
94
  const bv = toScaled(b, scale);
36
95
  return av < bv ? -1 : av > bv ? 1 : 0;
37
96
  }
38
- var ULID_BODY = "[0-9A-HJKMNP-TV-Z]{26}";
39
- function prefixedId(prefix) {
40
- return z.string().regex(new RegExp(`^${prefix}_${ULID_BODY}$`), `expected a "${prefix}_" prefixed id`);
41
- }
42
- var OrgId = prefixedId("org");
43
- var AgentId = prefixedId("agt");
44
- var PolicyId = prefixedId("pol");
45
- var IntentId = prefixedId("int");
46
- var DecisionId = prefixedId("dec");
47
- var ReceiptId = prefixedId("rcp");
48
- var SessionId = prefixedId("ses");
49
- var GateReceiptId = prefixedId("grc");
50
- var ApiKeyId = prefixedId("key");
51
- var ApproverKeyId = prefixedId("apk");
52
- var EnforcementMode = z.enum(["observed", "sdk", "session-key"]);
53
- var AgentWallet = z.object({
97
+ var EnforcementMode = z2.enum(["observed", "sdk", "session-key"]);
98
+ var AgentWallet = z2.object({
54
99
  chain: Chain,
55
- address: z.string().min(1),
100
+ address: z2.string().min(1),
56
101
  mode: EnforcementMode
57
102
  });
58
- var AgentStatus = z.enum(["active", "frozen"]);
59
- var AgentLabel = z.string().max(40).regex(/^[a-z0-9][a-z0-9-]*$/, 'label must be a lowercase slug like "research" or "prod-trading"');
60
- var Agent = z.object({
103
+ var AgentStatus = z2.enum(["active", "frozen"]);
104
+ var AgentLabel = z2.string().max(40).regex(/^[a-z0-9][a-z0-9-]*$/, 'label must be a lowercase slug like "research" or "prod-trading"');
105
+ var Agent = z2.object({
61
106
  id: AgentId,
62
107
  orgId: OrgId,
63
- name: z.string().min(1).max(200),
108
+ name: z2.string().min(1).max(200),
64
109
  /** On-chain ERC-8004 identity, if the agent is registered. */
65
- erc8004Id: z.string().optional(),
110
+ erc8004Id: z2.string().optional(),
66
111
  /** Semantic grouping labels — the targets of policy `appliesTo.labels`. */
67
- labels: z.array(AgentLabel).max(16).refine((ls) => new Set(ls).size === ls.length, { message: "labels must be unique" }).default([]),
68
- wallets: z.array(AgentWallet).default([]),
112
+ labels: z2.array(AgentLabel).max(16).refine((ls) => new Set(ls).size === ls.length, { message: "labels must be unique" }).default([]),
113
+ wallets: z2.array(AgentWallet).default([]),
69
114
  status: AgentStatus.default("active"),
70
- createdAt: z.coerce.date()
115
+ createdAt: z2.coerce.date()
71
116
  });
72
117
  var ID_PATTERN = /^eip155:(\d+):(0x[0-9a-fA-F]{40})\/(\d+)$/;
73
118
  function parseErc8004Id(value) {
@@ -81,33 +126,33 @@ function parseErc8004Id(value) {
81
126
  tokenId: BigInt(match[3])
82
127
  };
83
128
  }
84
- var Erc8004Id = z.string().refine((value) => parseErc8004Id(value) !== void 0, {
129
+ var Erc8004Id = z2.string().refine((value) => parseErc8004Id(value) !== void 0, {
85
130
  message: 'expected "eip155:{chainId}:{registry}/{tokenId}"'
86
131
  });
87
- var Vendor = z.object({
88
- host: z.string().min(1),
89
- address: z.string().min(1),
90
- erc8004Id: z.string().optional()
132
+ var Vendor = z2.object({
133
+ host: z2.string().min(1),
134
+ address: z2.string().min(1),
135
+ erc8004Id: z2.string().optional()
91
136
  });
92
- var TaskContext = z.object({
93
- taskId: z.string().optional(),
94
- parentRunId: z.string().optional(),
95
- purpose: z.string().max(500).optional()
137
+ var TaskContext = z2.object({
138
+ taskId: z2.string().optional(),
139
+ parentRunId: z2.string().optional(),
140
+ purpose: z2.string().max(500).optional()
96
141
  });
97
- var PaymentIntent = z.object({
142
+ var PaymentIntent = z2.object({
98
143
  id: IntentId,
99
144
  agentId: AgentId,
100
145
  vendor: Vendor,
101
- resource: z.string(),
146
+ resource: z2.string(),
102
147
  amount: DecimalString,
103
148
  asset: Asset,
104
149
  chain: Chain,
105
150
  taskContext: TaskContext.default({}),
106
- nonce: z.string().min(1),
107
- createdAt: z.coerce.date()
151
+ nonce: z2.string().min(1),
152
+ createdAt: z2.coerce.date()
108
153
  });
109
- var DecisionOutcome = z.enum(["allow", "deny", "escalate"]);
110
- var Decision = z.object({
154
+ var DecisionOutcome = z2.enum(["allow", "deny", "escalate"]);
155
+ var Decision = z2.object({
111
156
  id: DecisionId,
112
157
  intentId: IntentId,
113
158
  /**
@@ -116,114 +161,115 @@ var Decision = z.object({
116
161
  * chain — so a signer can verify an {intent, decision} pair offline as a
117
162
  * self-contained spend voucher, not just a reference by id.
118
163
  */
119
- intentHash: z.string(),
164
+ intentHash: z2.string(),
120
165
  outcome: DecisionOutcome,
121
166
  /** Ids of the rules that fired, for explainability. */
122
- matchedRules: z.array(z.string()).default([]),
167
+ matchedRules: z2.array(z2.string()).default([]),
123
168
  /** Human-readable explanation surfaced in the dashboard. */
124
- reason: z.string().optional(),
125
- policyId: z.string(),
126
- policyVersion: z.string(),
169
+ reason: z2.string().optional(),
170
+ policyId: z2.string(),
171
+ policyVersion: z2.string(),
127
172
  /** Hash of the previous decision in the chain (tamper-evident log). */
128
- prevHash: z.string(),
173
+ prevHash: z2.string(),
129
174
  /** Hash of this decision's canonical content. */
130
- hash: z.string(),
175
+ hash: z2.string(),
131
176
  /** Service signing-key signature over `hash`. */
132
- signature: z.string(),
133
- latencyMs: z.number().nonnegative(),
134
- decidedAt: z.coerce.date()
177
+ signature: z2.string(),
178
+ latencyMs: z2.number().nonnegative(),
179
+ decidedAt: z2.coerce.date()
135
180
  });
136
- var Session = z.object({
181
+ var AttributedDecision = Decision.extend({ agentId: AgentId.optional() });
182
+ var Session = z2.object({
137
183
  id: SessionId,
138
184
  agentId: AgentId,
139
185
  /** sha256 hex of the bearer token. */
140
- tokenHash: z.string(),
186
+ tokenHash: z2.string(),
141
187
  /** Cumulative ceiling across the session's lifetime. Absent = uncapped. */
142
188
  capAmount: DecimalString.optional(),
143
189
  /** Ceiling per individual signature. Absent = uncapped. */
144
190
  maxPerPayment: DecimalString.optional(),
145
- expiresAt: z.coerce.date(),
146
- createdAt: z.coerce.date(),
147
- revokedAt: z.coerce.date().optional()
191
+ expiresAt: z2.coerce.date(),
192
+ createdAt: z2.coerce.date(),
193
+ revokedAt: z2.coerce.date().optional()
148
194
  });
149
- var SettledPayment = z.object({
195
+ var SettledPayment = z2.object({
150
196
  intentId: IntentId,
151
- txHash: z.string(),
197
+ txHash: z2.string(),
152
198
  chain: Chain,
153
- blockNumber: z.coerce.bigint(),
154
- facilitator: z.string().optional(),
199
+ blockNumber: z2.coerce.bigint(),
200
+ facilitator: z2.string().optional(),
155
201
  feePaid: DecimalString.optional(),
156
- confirmedAt: z.coerce.date()
202
+ confirmedAt: z2.coerce.date()
157
203
  });
158
- var SettlementReport = z.object({
204
+ var SettlementReport = z2.object({
159
205
  intentId: IntentId,
160
206
  /** The settling transaction, when the observer saw one. */
161
- txHash: z.string().optional(),
207
+ txHash: z2.string().optional(),
162
208
  chain: Chain.optional(),
163
209
  /** The amount as SETTLED, when known — may differ from the amount allowed. */
164
210
  amount: DecimalString.optional(),
165
211
  /** Free-form observer tag, e.g. "indexer", "guard", "facilitator". */
166
- source: z.string().min(1).max(64).optional(),
167
- confirmedAt: z.coerce.date()
212
+ source: z2.string().min(1).max(64).optional(),
213
+ confirmedAt: z2.coerce.date()
168
214
  });
169
- var ReceiptSettlement = z.object({
170
- txHash: z.string().optional(),
171
- networkId: z.string().optional(),
215
+ var ReceiptSettlement = z2.object({
216
+ txHash: z2.string().optional(),
217
+ networkId: z2.string().optional(),
172
218
  /** Raw header payload, kept for forensics until the indexer confirms. */
173
- raw: z.string().optional()
219
+ raw: z2.string().optional()
174
220
  });
175
- var Receipt = z.object({
221
+ var Receipt = z2.object({
176
222
  id: ReceiptId,
177
223
  agentId: AgentId,
178
224
  intentId: IntentId,
179
225
  decisionId: DecisionId,
180
226
  outcome: DecisionOutcome,
181
227
  /** The URL the agent actually fetched (the paywalled resource). */
182
- url: z.string(),
183
- method: z.string().default("GET"),
184
- vendorHost: z.string(),
228
+ url: z2.string(),
229
+ method: z2.string().default("GET"),
230
+ vendorHost: z2.string(),
185
231
  amount: DecimalString,
186
232
  asset: Asset,
187
233
  chain: Chain,
188
234
  taskContext: TaskContext.default({}),
189
235
  /** Human-readable explanation copied from the decision. */
190
- reason: z.string().optional(),
236
+ reason: z2.string().optional(),
191
237
  /** Present only once a payment was made and the vendor confirmed it. */
192
238
  settlement: ReceiptSettlement.optional(),
193
- createdAt: z.coerce.date()
239
+ createdAt: z2.coerce.date()
194
240
  });
195
- var GateReceipt = z.object({
241
+ var GateReceipt = z2.object({
196
242
  id: GateReceiptId,
197
- at: z.coerce.date(),
243
+ at: z2.coerce.date(),
198
244
  /** The route pattern that priced this request, e.g. "/api/reports/*". */
199
- route: z.string().min(1),
245
+ route: z2.string().min(1),
200
246
  /** The concrete resource paid for (URL path actually requested). */
201
- resource: z.string().min(1),
202
- method: z.string().min(1),
247
+ resource: z2.string().min(1),
248
+ method: z2.string().min(1),
203
249
  /** The paying wallet address, as asserted by the settled payment. */
204
- payer: z.string().min(1),
205
- payTo: z.string().min(1),
250
+ payer: z2.string().min(1),
251
+ payTo: z2.string().min(1),
206
252
  /** Human-unit decimal amount, e.g. "0.05". */
207
253
  amount: DecimalString,
208
254
  /** The same amount in the asset's atomic units, e.g. "50000". */
209
- amountAtomic: z.string().regex(/^\d+$/, "atomic amount must be an integer string"),
255
+ amountAtomic: z2.string().regex(/^\d+$/, "atomic amount must be an integer string"),
210
256
  /** Token symbol or contract address, exactly as quoted in the requirement. */
211
- asset: z.string().min(1),
212
- network: z.string().min(1),
257
+ asset: z2.string().min(1),
258
+ network: z2.string().min(1),
213
259
  /** Settlement transaction hash (mock ledger or on-chain). */
214
- transaction: z.string().min(1)
260
+ transaction: z2.string().min(1)
215
261
  });
216
- var Window = z.string().regex(/^\d+[smhd]$/, 'window must be like "30s", "15m", "1h", or "7d"');
217
- var Multiplier = z.string().regex(/^\d+(\.\d+)?x$/, 'multiplier must be like "3x"');
218
- var Condition = z.object({
262
+ var Window = z2.string().regex(/^\d+[smhd]$/, 'window must be like "30s", "15m", "1h", or "7d"');
263
+ var Multiplier = z2.string().regex(/^\d+(\.\d+)?x$/, 'multiplier must be like "3x"');
264
+ var Condition = z2.object({
219
265
  /** Per-transaction amount exceeds this value. */
220
266
  amountGt: DecimalString.optional(),
221
267
  /** Sum of spend in a rolling window exceeds `gt`. */
222
- rollingSum: z.object({ window: Window, gt: DecimalString }).optional(),
268
+ rollingSum: z2.object({ window: Window, gt: DecimalString }).optional(),
223
269
  /** Transaction count in a rolling window exceeds `gt`. */
224
- txCount: z.object({ window: Window, gt: z.number().int().nonnegative() }).optional(),
270
+ txCount: z2.object({ window: Window, gt: z2.number().int().nonnegative() }).optional(),
225
271
  /** Vendor host matches one of these patterns (supports `*` globs). */
226
- vendorHostIn: z.array(z.string()).optional(),
272
+ vendorHostIn: z2.array(z2.string()).optional(),
227
273
  /**
228
274
  * Resource PATH matches one of these patterns (supports `*` globs, e.g.
229
275
  * "/v1/reports/*"). A full-URL resource is reduced to its pathname before
@@ -231,13 +277,13 @@ var Condition = z.object({
231
277
  * vendor declares "https://api.x.com/v1/answer" or "/v1/answer". Pair
232
278
  * with `vendorHostIn` to scope a path rule to specific vendors.
233
279
  */
234
- resourceIn: z.array(z.string()).optional(),
280
+ resourceIn: z2.array(z2.string()).optional(),
235
281
  /** First time Rein has seen this vendor for the agent. */
236
- vendorFirstSeen: z.boolean().optional(),
282
+ vendorFirstSeen: z2.boolean().optional(),
237
283
  /** Vendor reputation score is below this threshold (Phase 3 hook). */
238
- vendorReputationLt: z.number().min(0).max(100).optional(),
284
+ vendorReputationLt: z2.number().min(0).max(100).optional(),
239
285
  /** Amount is more than `gt`-times the observed median for this resource. */
240
- amountVsResourceMedian: z.object({ gt: Multiplier }).optional(),
286
+ amountVsResourceMedian: z2.object({ gt: Multiplier }).optional(),
241
287
  /**
242
288
  * Cumulative spend attributed to THIS intent's `taskContext.taskId`
243
289
  * (prior spend on the task plus this payment) exceeds `gt`. Scopes a
@@ -250,21 +296,21 @@ var Condition = z.object({
250
296
  * a budget — otherwise every untagged probe payment would trip every
251
297
  * task budget in the policy.
252
298
  */
253
- taskBudget: z.object({ gt: DecimalString }).optional(),
299
+ taskBudget: z2.object({ gt: DecimalString }).optional(),
254
300
  /** The intent carries no `taskContext.taskId` (or an empty one). */
255
- taskIdMissing: z.boolean().optional()
301
+ taskIdMissing: z2.boolean().optional()
256
302
  }).refine((c) => Object.values(c).some((v) => v !== void 0), {
257
303
  message: "a condition must specify at least one predicate"
258
304
  });
259
- var Breaker = z.object({
260
- id: z.string().min(1),
305
+ var Breaker = z2.object({
306
+ id: z2.string().min(1),
261
307
  /** The trailing span the tripwires measure over. */
262
308
  window: Window,
263
309
  /**
264
310
  * Trip when the window would hold MORE than this many transactions.
265
311
  * `10` permits ten in the window and escalates the eleventh.
266
312
  */
267
- txCount: z.number().int().positive().optional(),
313
+ txCount: z2.number().int().positive().optional(),
268
314
  /**
269
315
  * Trip when the window's spend would exceed this total. `"50.00"` permits
270
316
  * a window totalling exactly 50.00 and escalates the payment that would
@@ -276,120 +322,122 @@ var Breaker = z.object({
276
322
  }).refine((b) => b.txCount !== void 0 || b.valueCap !== void 0, {
277
323
  message: "a breaker must specify at least one of txCount / valueCap"
278
324
  });
279
- var Rule = z.object({
280
- id: z.string().min(1),
325
+ var Rule = z2.object({
326
+ id: z2.string().min(1),
281
327
  allow: Condition.optional(),
282
328
  deny: Condition.optional(),
283
329
  escalate: Condition.optional()
284
330
  }).refine((r) => [r.allow, r.deny, r.escalate].filter((v) => v !== void 0).length === 1, {
285
331
  message: "a rule must specify exactly one of allow / deny / escalate"
286
332
  });
287
- var PolicyDefault = z.enum(["allow", "deny"]);
288
- var AppliesTo = z.object({
333
+ var PolicyDefault = z2.enum(["allow", "deny"]);
334
+ var AppliesTo = z2.object({
289
335
  /** Agent id patterns (supports `*` globs, e.g. "agt_research_*"). */
290
- agents: z.array(z.string()).optional(),
336
+ agents: z2.array(z2.string()).optional(),
291
337
  /**
292
338
  * Agent label patterns (supports `*` globs) — semantic targeting. Matches
293
339
  * when the agent carries at least one label matching any pattern. Requires
294
340
  * the agent DOCUMENT: an intent from an unregistered agent never matches a
295
341
  * labels-targeted policy (and so fails closed when no other policy applies).
296
342
  */
297
- labels: z.array(z.string()).optional(),
298
- chains: z.array(Chain).optional()
343
+ labels: z2.array(z2.string()).optional(),
344
+ chains: z2.array(Chain).optional()
299
345
  });
300
- var Escalation = z.object({
301
- approvers: z.array(z.string()).default([]),
346
+ var Escalation = z2.object({
347
+ approvers: z2.array(z2.string()).default([]),
302
348
  timeoutAction: PolicyDefault.default("deny"),
303
- timeoutMin: z.number().int().positive().default(15)
349
+ timeoutMin: z2.number().int().positive().default(15)
304
350
  });
305
- var Policy = z.object({
306
- policyId: z.string().min(1),
307
- version: z.string().default("1"),
351
+ var Policy = z2.object({
352
+ policyId: z2.string().min(1),
353
+ version: z2.string().default("1"),
354
+ /**
355
+ * The org this policy governs. ABSENT means GLOBAL — it is considered for
356
+ * every agent, which is what every policy written before tenancy existed is
357
+ * and stays.
358
+ *
359
+ * This is separate from {@link AppliesTo} on purpose, and it has to be:
360
+ * `appliesTo: {}` matches every agent, so a tenant's policy carrying the
361
+ * default targeting would otherwise govern other tenants' agents the moment
362
+ * it was written. Org scoping is applied BEFORE targeting — a policy whose
363
+ * `orgId` is not the agent's org is not a candidate at all.
364
+ */
365
+ orgId: OrgId.optional(),
308
366
  appliesTo: AppliesTo.default({}),
309
- rules: z.array(Rule).default([]),
367
+ rules: z2.array(Rule).default([]),
310
368
  /**
311
369
  * Behavioral breakers evaluated alongside the rules. A tripped breaker
312
370
  * escalates at the same precedence as an `escalate` rule — so an explicit
313
371
  * DENY still wins, and an ALLOW rule cannot wave past a tripped breaker.
314
372
  */
315
- breakers: z.array(Breaker).default([]),
373
+ breakers: z2.array(Breaker).default([]),
316
374
  default: PolicyDefault.default("deny"),
317
375
  /** Below this amount, fail-open is permitted during a policy-service outage. */
318
376
  denyFloor: DecimalString.default("0.05"),
319
377
  escalation: Escalation.optional()
320
378
  });
321
- var LivenessSource = z.enum([
379
+ var LivenessSource = z2.enum([
322
380
  /** It submitted an intent — ANY outcome, including a denial. */
323
381
  "intent",
324
382
  /** It reported in explicitly, having nothing to buy. */
325
383
  "heartbeat"
326
384
  ]);
327
385
  var DEFAULT_LIVENESS_GRACE_MS = 6e4;
328
- var LivenessExpectation = z.object({
386
+ var LivenessExpectation = z2.object({
329
387
  agentId: AgentId,
330
388
  /** Longest silence still considered normal, e.g. '15m'. */
331
389
  interval: Window,
332
390
  /** Extra slack past `interval` before the silence is an alarm. */
333
- graceMs: z.number().int().nonnegative().default(DEFAULT_LIVENESS_GRACE_MS),
391
+ graceMs: z2.number().int().nonnegative().default(DEFAULT_LIVENESS_GRACE_MS),
334
392
  /**
335
393
  * When watching began. An agent that has NEVER been seen is measured from
336
394
  * here, so a watch on an agent that never starts does raise an alarm — a
337
395
  * detector that never came up is exactly as dead as one that stopped.
338
396
  */
339
- since: z.coerce.date(),
397
+ since: z2.coerce.date(),
340
398
  /** What this agent is supposed to be doing, shown beside the alarm. */
341
- note: z.string().max(200).optional()
399
+ note: z2.string().max(200).optional()
342
400
  });
343
401
  var LivenessWatchInput = LivenessExpectation.omit({ since: true }).extend({
344
- graceMs: z.number().int().nonnegative().optional()
402
+ graceMs: z2.number().int().nonnegative().optional()
345
403
  });
346
- var Heartbeat = z.object({
404
+ var Heartbeat = z2.object({
347
405
  agentId: AgentId,
348
406
  /** When the agent was alive. Defaults to arrival time. */
349
- at: z.coerce.date().optional(),
407
+ at: z2.coerce.date().optional(),
350
408
  /** Free-form note from the reporter, e.g. "poll cycle 41 ok". */
351
- note: z.string().max(200).optional()
409
+ note: z2.string().max(200).optional()
352
410
  });
353
- var LivenessStatus = z.enum(["alive", "late", "missing", "unknown"]);
354
- var ApiKeyScope = z.enum(["read", "evaluate", "approve", "admin"]);
355
- var ApiKey = z.object({
356
- id: ApiKeyId,
357
- name: z.string().min(1).max(200),
358
- scopes: z.array(ApiKeyScope).min(1),
359
- createdAt: z.coerce.date(),
360
- /** Last successful authentication, for spotting keys that can be retired. */
361
- lastUsedAt: z.coerce.date().optional(),
362
- /** Set by revoke(); a revoked key never authenticates again. */
363
- revokedAt: z.coerce.date().optional(),
364
- /** Set by rotate(); with `previousSecretExpiresAt` it dates the overlap. */
365
- rotatedAt: z.coerce.date().optional()
366
- });
367
- var ApiKeyRecord = ApiKey.extend({
368
- secretHash: z.string(),
369
- previousSecretHash: z.string().optional(),
370
- previousSecretExpiresAt: z.coerce.date().optional()
371
- });
372
- var ApprovalVerdict = z.enum(["approve", "reject"]);
373
- var ApprovalStatus = z.enum(["pending", "approved", "rejected", "expired"]);
374
- var ApproverKey = z.object({
411
+ var LivenessStatus = z2.enum(["alive", "late", "missing", "unknown"]);
412
+ var ApprovalVerdict = z2.enum(["approve", "reject"]);
413
+ var ApprovalStatus = z2.enum(["pending", "approved", "rejected", "expired"]);
414
+ var ApproverKey = z2.object({
375
415
  id: ApproverKeyId,
376
416
  orgId: OrgId,
377
- name: z.string().min(1).max(200),
417
+ name: z2.string().min(1).max(200),
378
418
  /** ed25519 public key, SPKI PEM — the same encoding as the decision log's. */
379
- publicKey: z.string().min(1),
380
- algorithm: z.literal("ed25519").default("ed25519"),
381
- createdAt: z.coerce.date(),
382
- revokedAt: z.coerce.date().optional()
419
+ publicKey: z2.string().min(1),
420
+ algorithm: z2.literal("ed25519").default("ed25519"),
421
+ createdAt: z2.coerce.date(),
422
+ revokedAt: z2.coerce.date().optional()
383
423
  });
384
- var ApprovalRequest = z.object({
424
+ var ApprovalRequest = z2.object({
385
425
  /** The `escalate` decision this request answers (primary key). */
386
426
  decisionId: DecisionId,
387
427
  intentId: IntentId,
388
428
  /** Binds the approval to the exact transfer — the signed bytes commit to it. */
389
- intentHash: z.string(),
429
+ intentHash: z2.string(),
390
430
  agentId: AgentId,
391
- vendorHost: z.string(),
392
- resource: z.string(),
431
+ /**
432
+ * The org the escalating agent belongs to, stamped when the request is
433
+ * parked. ABSENT means the agent was never registered (or the request
434
+ * predates tenancy), and such a request is answerable only by an unscoped
435
+ * operator — there is no org to check an approver against, and guessing one
436
+ * is how a cross-tenant approval happens.
437
+ */
438
+ orgId: OrgId.optional(),
439
+ vendorHost: z2.string(),
440
+ resource: z2.string(),
393
441
  amount: DecimalString,
394
442
  asset: Asset,
395
443
  chain: Chain,
@@ -399,9 +447,9 @@ var ApprovalRequest = z.object({
399
447
  * id on the way through would make the budget silently under-count exactly
400
448
  * the payments a human had to look at.
401
449
  */
402
- taskId: z.string().optional(),
450
+ taskId: z2.string().optional(),
403
451
  /** Why policy escalated, verbatim from the decision. */
404
- reason: z.string(),
452
+ reason: z2.string(),
405
453
  /**
406
454
  * Breaker ids whose trip contributed to this escalation. An approval of
407
455
  * this request resets exactly these — moving their counting floor to the
@@ -409,12 +457,12 @@ var ApprovalRequest = z.object({
409
457
  * behavior that stopped it, rather than being asked again immediately.
410
458
  * Empty when ordinary rules did the escalating.
411
459
  */
412
- breakers: z.array(z.string()).default([]),
460
+ breakers: z2.array(z2.string()).default([]),
413
461
  status: ApprovalStatus,
414
- createdAt: z.coerce.date(),
462
+ createdAt: z2.coerce.date(),
415
463
  /** Past this instant the request denies, whatever arrives afterwards. */
416
- expiresAt: z.coerce.date(),
417
- resolvedAt: z.coerce.date().optional(),
464
+ expiresAt: z2.coerce.date(),
465
+ resolvedAt: z2.coerce.date().optional(),
418
466
  /** Which registered key signed — absent when the TTL lapsed instead. */
419
467
  approverKeyId: ApproverKeyId.optional(),
420
468
  /**
@@ -424,117 +472,117 @@ var ApprovalRequest = z.object({
424
472
  */
425
473
  finalDecisionId: DecisionId.optional()
426
474
  });
427
- var ApprovalChallenges = z.object({
428
- approve: z.string(),
429
- reject: z.string()
475
+ var ApprovalChallenges = z2.object({
476
+ approve: z2.string(),
477
+ reject: z2.string()
430
478
  });
431
- var ApprovalGrant = z.object({
479
+ var ApprovalGrant = z2.object({
432
480
  decisionId: DecisionId,
433
- intentHash: z.string(),
481
+ intentHash: z2.string(),
434
482
  verdict: ApprovalVerdict,
435
483
  approverKeyId: ApproverKeyId,
436
- signature: z.string().min(1)
484
+ signature: z2.string().min(1)
437
485
  });
438
- var ReputationSubject = z.object({
439
- kind: z.enum(["agent", "vendor"]),
440
- id: z.string()
486
+ var ReputationSubject = z2.object({
487
+ kind: z2.enum(["agent", "vendor"]),
488
+ id: z2.string()
441
489
  });
442
- var ReputationComponents = z.object({
443
- volume: z.number(),
444
- longevity: z.number(),
445
- disputeRate: z.number(),
446
- counterpartyQuality: z.number(),
447
- settlementReliability: z.number()
490
+ var ReputationComponents = z2.object({
491
+ volume: z2.number(),
492
+ longevity: z2.number(),
493
+ disputeRate: z2.number(),
494
+ counterpartyQuality: z2.number(),
495
+ settlementReliability: z2.number()
448
496
  });
449
- var ReputationScore = z.object({
497
+ var ReputationScore = z2.object({
450
498
  subject: ReputationSubject,
451
- score: z.number().min(0).max(100),
499
+ score: z2.number().min(0).max(100),
452
500
  components: ReputationComponents,
453
- confidence: z.number().min(0).max(1),
454
- asOf: z.coerce.date(),
501
+ confidence: z2.number().min(0).max(1),
502
+ asOf: z2.coerce.date(),
455
503
  /** Hash-anchored attestation, optionally published on-chain (ERC-8004). */
456
- evidenceUri: z.string().optional()
504
+ evidenceUri: z2.string().optional()
457
505
  });
458
- var ReinEvent = z.discriminatedUnion("type", [
459
- z.object({ type: z.literal("intent.created"), at: z.coerce.date(), intent: PaymentIntent }),
460
- z.object({ type: z.literal("decision.made"), at: z.coerce.date(), decision: Decision }),
461
- z.object({ type: z.literal("payment.settled"), at: z.coerce.date(), payment: SettledPayment }),
462
- z.object({
463
- type: z.literal("shadow.spend"),
464
- at: z.coerce.date(),
506
+ var ReinEvent = z2.discriminatedUnion("type", [
507
+ z2.object({ type: z2.literal("intent.created"), at: z2.coerce.date(), intent: PaymentIntent }),
508
+ z2.object({ type: z2.literal("decision.made"), at: z2.coerce.date(), decision: Decision }),
509
+ z2.object({ type: z2.literal("payment.settled"), at: z2.coerce.date(), payment: SettledPayment }),
510
+ z2.object({
511
+ type: z2.literal("shadow.spend"),
512
+ at: z2.coerce.date(),
465
513
  agentId: AgentId,
466
- txHash: z.string(),
514
+ txHash: z2.string(),
467
515
  chain: Chain,
468
516
  amount: DecimalString
469
517
  }),
470
- z.object({
471
- type: z.literal("signature.released"),
472
- at: z.coerce.date(),
518
+ z2.object({
519
+ type: z2.literal("signature.released"),
520
+ at: z2.coerce.date(),
473
521
  sessionId: SessionId,
474
522
  agentId: AgentId,
475
523
  intentId: IntentId,
476
524
  decisionId: DecisionId,
477
525
  amount: DecimalString
478
526
  }),
479
- z.object({
480
- type: z.literal("signature.refused"),
481
- at: z.coerce.date(),
527
+ z2.object({
528
+ type: z2.literal("signature.refused"),
529
+ at: z2.coerce.date(),
482
530
  /** Refusal code, e.g. "decision_replayed" (see @reinconsole/signer). */
483
- code: z.string(),
484
- reason: z.string(),
531
+ code: z2.string(),
532
+ reason: z2.string(),
485
533
  sessionId: SessionId.optional(),
486
534
  agentId: AgentId.optional(),
487
535
  intentId: IntentId.optional()
488
536
  }),
489
- z.object({
490
- type: z.literal("gate.quoted"),
491
- at: z.coerce.date(),
492
- resource: z.string(),
493
- method: z.string(),
537
+ z2.object({
538
+ type: z2.literal("gate.quoted"),
539
+ at: z2.coerce.date(),
540
+ resource: z2.string(),
541
+ method: z2.string(),
494
542
  amount: DecimalString,
495
- asset: z.string(),
496
- network: z.string()
543
+ asset: z2.string(),
544
+ network: z2.string()
497
545
  }),
498
- z.object({ type: z.literal("gate.settled"), at: z.coerce.date(), receipt: GateReceipt }),
499
- z.object({
500
- type: z.literal("approval.requested"),
501
- at: z.coerce.date(),
546
+ z2.object({ type: z2.literal("gate.settled"), at: z2.coerce.date(), receipt: GateReceipt }),
547
+ z2.object({
548
+ type: z2.literal("approval.requested"),
549
+ at: z2.coerce.date(),
502
550
  request: ApprovalRequest
503
551
  }),
504
- z.object({
505
- type: z.literal("approval.resolved"),
506
- at: z.coerce.date(),
552
+ z2.object({
553
+ type: z2.literal("approval.resolved"),
554
+ at: z2.coerce.date(),
507
555
  request: ApprovalRequest,
508
556
  /** The follow-up allow/deny decision this resolution appended. */
509
557
  decision: Decision
510
558
  }),
511
- z.object({
512
- type: z.literal("liveness.missing"),
513
- at: z.coerce.date(),
559
+ z2.object({
560
+ type: z2.literal("liveness.missing"),
561
+ at: z2.coerce.date(),
514
562
  agentId: AgentId,
515
563
  expectation: LivenessExpectation,
516
564
  /** How long the agent has been silent when the alarm was raised. */
517
- silentMs: z.number().int().nonnegative(),
565
+ silentMs: z2.number().int().nonnegative(),
518
566
  /** Last sighting, absent when the agent was never seen at all. */
519
- lastSeenAt: z.coerce.date().optional()
567
+ lastSeenAt: z2.coerce.date().optional()
520
568
  }),
521
- z.object({
522
- type: z.literal("liveness.recovered"),
523
- at: z.coerce.date(),
569
+ z2.object({
570
+ type: z2.literal("liveness.recovered"),
571
+ at: z2.coerce.date(),
524
572
  agentId: AgentId,
525
573
  /** How long the silence lasted, measured to this sighting. */
526
- silentMs: z.number().int().nonnegative(),
574
+ silentMs: z2.number().int().nonnegative(),
527
575
  source: LivenessSource
528
576
  }),
529
- z.object({
530
- type: z.literal("gate.refused"),
531
- at: z.coerce.date(),
577
+ z2.object({
578
+ type: z2.literal("gate.refused"),
579
+ at: z2.coerce.date(),
532
580
  /** Refusal code, e.g. "payment_replayed" (see @reinconsole/gate). */
533
- code: z.string(),
534
- reason: z.string(),
535
- resource: z.string(),
581
+ code: z2.string(),
582
+ reason: z2.string(),
583
+ resource: z2.string(),
536
584
  /** Known only when the payment header decoded far enough to name a payer. */
537
- payer: z.string().optional()
585
+ payer: z2.string().optional()
538
586
  })
539
587
  ]);
540
588
 
@@ -569,98 +617,103 @@ var MockLedger = class {
569
617
  };
570
618
 
571
619
  // ../../packages/sdk/dist/index.js
572
- import { z as z2 } from "zod";
573
- var BreakerState = z2.object({
620
+ import { z as z3 } from "zod";
621
+ var BreakerState = z3.object({
574
622
  breaker: Breaker,
575
- policyId: z2.string(),
576
- txCount: z2.number(),
577
- sum: z2.string(),
578
- countingFrom: z2.number(),
579
- resetAt: z2.number().optional(),
580
- tripped: z2.boolean(),
581
- reason: z2.string().optional()
623
+ policyId: z3.string(),
624
+ txCount: z3.number(),
625
+ sum: z3.string(),
626
+ countingFrom: z3.number(),
627
+ resetAt: z3.number().optional(),
628
+ tripped: z3.boolean(),
629
+ reason: z3.string().optional()
582
630
  });
583
- var LivenessState = z2.object({
584
- agentId: z2.string(),
631
+ var LivenessState = z3.object({
632
+ agentId: z3.string(),
585
633
  expectation: LivenessExpectation,
586
- lastSeenAt: z2.number().optional(),
634
+ lastSeenAt: z3.number().optional(),
587
635
  lastSource: LivenessSource.optional(),
588
- silentSince: z2.number(),
589
- silentMs: z2.number(),
590
- dueAt: z2.number(),
591
- overdueAt: z2.number(),
636
+ silentSince: z3.number(),
637
+ silentMs: z3.number(),
638
+ dueAt: z3.number(),
639
+ overdueAt: z3.number(),
592
640
  status: LivenessStatus,
593
- alertedAt: z2.number().optional()
641
+ alertedAt: z3.number().optional()
594
642
  });
595
- var Health = z2.object({
596
- status: z2.string(),
597
- publicKey: z2.string(),
643
+ var Health = z3.object({
644
+ status: z3.string(),
645
+ publicKey: z3.string(),
598
646
  /** "api-key" once the engine demands a credential; "none" while it does not. */
599
- auth: z2.string().optional(),
600
- approvals: z2.string().optional()
647
+ auth: z3.string().optional(),
648
+ approvals: z3.string().optional()
601
649
  });
602
- var EvaluateResponse = z2.object({
650
+ var EvaluateResponse = z3.object({
603
651
  intent: PaymentIntent,
604
652
  decision: Decision,
605
653
  /** Present when an escalation was parked for a signed verdict. */
606
654
  approval: ApprovalRequest.optional()
607
655
  });
608
- var ApprovalView = z2.object({
656
+ var ApprovalView = z3.object({
609
657
  request: ApprovalRequest,
610
658
  challenges: ApprovalChallenges,
611
659
  /** The follow-up allow/deny decision, once the request has resolved. */
612
660
  decision: Decision.optional()
613
661
  });
614
- var ResolveResponse = z2.object({ request: ApprovalRequest, decision: Decision });
615
- var AllowanceGap = z2.object({
616
- intentId: z2.string(),
617
- decisionId: z2.string().optional(),
618
- agentId: z2.string(),
619
- host: z2.string(),
620
- resource: z2.string(),
621
- amount: z2.string(),
622
- taskId: z2.string().optional(),
623
- allowedAt: z2.number(),
624
- ageMs: z2.number(),
625
- state: z2.enum(["in-flight", "unsettled"])
662
+ var ResolveResponse = z3.object({ request: ApprovalRequest, decision: Decision });
663
+ var AllowanceGap = z3.object({
664
+ intentId: z3.string(),
665
+ decisionId: z3.string().optional(),
666
+ agentId: z3.string(),
667
+ host: z3.string(),
668
+ resource: z3.string(),
669
+ amount: z3.string(),
670
+ settledAmount: z3.string().optional(),
671
+ taskId: z3.string().optional(),
672
+ allowedAt: z3.number(),
673
+ ageMs: z3.number(),
674
+ state: z3.enum(["in-flight", "unsettled", "overspent"])
626
675
  });
627
- var ReconciliationReport = z2.object({
628
- from: z2.number(),
629
- to: z2.number(),
630
- window: z2.string(),
631
- graceMs: z2.number(),
632
- allowed: z2.number(),
633
- allowedValue: z2.string(),
634
- settled: z2.number(),
635
- settledValue: z2.string(),
636
- inFlight: z2.number(),
637
- inFlightValue: z2.string(),
638
- unsettled: z2.number(),
639
- unsettledValue: z2.string(),
640
- unattributed: z2.number(),
641
- settlementsSeen: z2.number(),
642
- gaps: z2.array(AllowanceGap),
643
- truncated: z2.boolean()
676
+ var ReconciliationReport = z3.object({
677
+ from: z3.number(),
678
+ to: z3.number(),
679
+ window: z3.string(),
680
+ graceMs: z3.number(),
681
+ allowed: z3.number(),
682
+ allowedValue: z3.string(),
683
+ settled: z3.number(),
684
+ settledValue: z3.string(),
685
+ inFlight: z3.number(),
686
+ inFlightValue: z3.string(),
687
+ unsettled: z3.number(),
688
+ unsettledValue: z3.string(),
689
+ // Optional on the wire so a 0.2.0 engine still validates; absent means the
690
+ // engine predates the check, not that nothing was overspent.
691
+ overspent: z3.number().optional(),
692
+ overspentValue: z3.string().optional(),
693
+ unattributed: z3.number(),
694
+ settlementsSeen: z3.number(),
695
+ gaps: z3.array(AllowanceGap),
696
+ truncated: z3.boolean()
644
697
  });
645
- var IssuedApiKey = z2.object({ key: ApiKey, secret: z2.string() });
646
- var PaymentRequirement = z2.object({
647
- scheme: z2.string(),
648
- network: z2.string(),
698
+ var IssuedApiKey = z3.object({ key: ApiKey, secret: z3.string() });
699
+ var PaymentRequirement = z3.object({
700
+ scheme: z3.string(),
701
+ network: z3.string(),
649
702
  /** Amount in the asset's atomic units (e.g. "10000" = 0.01 USDC at 6 decimals). */
650
- maxAmountRequired: z2.string().regex(/^\d+$/, "atomic amount must be an integer string"),
651
- resource: z2.string().optional(),
652
- description: z2.string().optional(),
653
- mimeType: z2.string().optional(),
654
- payTo: z2.string().min(1),
655
- maxTimeoutSeconds: z2.number().optional(),
703
+ maxAmountRequired: z3.string().regex(/^\d+$/, "atomic amount must be an integer string"),
704
+ resource: z3.string().optional(),
705
+ description: z3.string().optional(),
706
+ mimeType: z3.string().optional(),
707
+ payTo: z3.string().min(1),
708
+ maxTimeoutSeconds: z3.number().optional(),
656
709
  /** Token contract address — or, mock-first, a plain symbol like "USDC". */
657
- asset: z2.string().min(1),
658
- extra: z2.record(z2.unknown()).optional()
710
+ asset: z3.string().min(1),
711
+ extra: z3.record(z3.unknown()).optional()
659
712
  });
660
- var PaymentRequired = z2.object({
661
- x402Version: z2.number(),
662
- accepts: z2.array(PaymentRequirement).min(1),
663
- error: z2.string().optional()
713
+ var PaymentRequired = z3.object({
714
+ x402Version: z3.number(),
715
+ accepts: z3.array(PaymentRequirement).min(1),
716
+ error: z3.string().optional()
664
717
  });
665
718
  var NETWORK_TO_CHAIN = {
666
719
  base: "base",
@@ -674,6 +727,8 @@ var NETWORK_TO_CHAIN = {
674
727
  bnb: "bnb",
675
728
  bsc: "bnb"
676
729
  };
730
+ var ASSET_DECIMALS = { USDC: 6, USDT: 6, EURC: 6 };
731
+ var EVM_ADDRESS = /^0x[0-9a-fA-F]{40}$/;
677
732
  var KNOWN_ASSET_ADDRESSES = {
678
733
  "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913": "USDC",
679
734
  // USDC on Base
@@ -682,18 +737,38 @@ var KNOWN_ASSET_ADDRESSES = {
682
737
  EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v: "USDC"
683
738
  // USDC on Solana
684
739
  };
740
+ var CAIP2_ALIASES = {
741
+ base: "eip155:8453",
742
+ "base-sepolia": "eip155:84532",
743
+ polygon: "eip155:137",
744
+ "polygon-amoy": "eip155:80002",
745
+ bnb: "eip155:56",
746
+ bsc: "eip155:56",
747
+ solana: "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",
748
+ "solana-devnet": "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1"
749
+ };
750
+ function caip2Of(network) {
751
+ const key = network.toLowerCase();
752
+ return CAIP2_ALIASES[key] ?? key;
753
+ }
754
+ function sameNetwork(a, b) {
755
+ return caip2Of(a) === caip2Of(b);
756
+ }
685
757
  function networkToChain(network) {
686
758
  return NETWORK_TO_CHAIN[network.toLowerCase()];
687
759
  }
688
760
  function resolveAsset(requirement, extraAddresses = {}) {
689
761
  const direct = Asset.safeParse(requirement.asset.toUpperCase());
690
762
  if (direct.success) return direct.data;
763
+ const known = extraAddresses[requirement.asset] ?? extraAddresses[requirement.asset.toLowerCase()] ?? KNOWN_ASSET_ADDRESSES[requirement.asset] ?? KNOWN_ASSET_ADDRESSES[requirement.asset.toLowerCase()];
764
+ if (known) return known;
765
+ if (EVM_ADDRESS.test(requirement.asset)) return void 0;
691
766
  const symbol = requirement.extra?.["symbol"];
692
767
  if (typeof symbol === "string") {
693
768
  const fromExtra = Asset.safeParse(symbol.toUpperCase());
694
769
  if (fromExtra.success) return fromExtra.data;
695
770
  }
696
- return extraAddresses[requirement.asset] ?? extraAddresses[requirement.asset.toLowerCase()] ?? KNOWN_ASSET_ADDRESSES[requirement.asset] ?? KNOWN_ASSET_ADDRESSES[requirement.asset.toLowerCase()];
771
+ return void 0;
697
772
  }
698
773
  function atomicToDecimal(atomic, decimals) {
699
774
  if (!/^\d+$/.test(atomic)) throw new TypeError(`invalid atomic amount: ${atomic}`);
@@ -703,49 +778,33 @@ function atomicToDecimal(atomic, decimals) {
703
778
  const fracPart = digits.slice(digits.length - decimals).replace(/0+$/, "");
704
779
  return fracPart.length > 0 ? `${intPart}.${fracPart}` : intPart;
705
780
  }
706
- function requirementDecimals(requirement) {
781
+ function requirementDecimals(requirement, asset) {
782
+ if (asset) return ASSET_DECIMALS[asset];
707
783
  const decimals = requirement.extra?.["decimals"];
708
784
  return typeof decimals === "number" && Number.isInteger(decimals) && decimals >= 0 ? decimals : 6;
709
785
  }
710
- var CAIP2_ALIASES = {
711
- base: "eip155:8453",
712
- "base-sepolia": "eip155:84532",
713
- polygon: "eip155:137",
714
- "polygon-amoy": "eip155:80002",
715
- bnb: "eip155:56",
716
- bsc: "eip155:56",
717
- solana: "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",
718
- "solana-devnet": "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1"
719
- };
720
- function caip2Of(network) {
721
- const key = network.toLowerCase();
722
- return CAIP2_ALIASES[key] ?? key;
723
- }
724
- function sameNetwork(a, b) {
725
- return caip2Of(a) === caip2Of(b);
726
- }
727
- var PaymentRequirementsV2 = z2.object({
728
- scheme: z2.string(),
786
+ var PaymentRequirementsV2 = z3.object({
787
+ scheme: z3.string(),
729
788
  /** CAIP-2, e.g. "eip155:84532". */
730
- network: z2.string(),
789
+ network: z3.string(),
731
790
  /** Atomic units — v2's rename of v1's maxAmountRequired. */
732
- amount: z2.string().regex(/^\d+$/, "atomic amount must be an integer string"),
733
- asset: z2.string().min(1),
734
- payTo: z2.string().min(1),
735
- maxTimeoutSeconds: z2.number().optional(),
736
- extra: z2.record(z2.unknown()).optional()
791
+ amount: z3.string().regex(/^\d+$/, "atomic amount must be an integer string"),
792
+ asset: z3.string().min(1),
793
+ payTo: z3.string().min(1),
794
+ maxTimeoutSeconds: z3.number().optional(),
795
+ extra: z3.record(z3.unknown()).optional()
737
796
  });
738
- var ResourceInfoV2 = z2.object({
739
- url: z2.string(),
740
- description: z2.string().optional(),
741
- mimeType: z2.string().optional()
797
+ var ResourceInfoV2 = z3.object({
798
+ url: z3.string(),
799
+ description: z3.string().optional(),
800
+ mimeType: z3.string().optional()
742
801
  });
743
- var PaymentRequiredV2 = z2.object({
744
- x402Version: z2.literal(2),
745
- error: z2.string().optional(),
802
+ var PaymentRequiredV2 = z3.object({
803
+ x402Version: z3.literal(2),
804
+ error: z3.string().optional(),
746
805
  resource: ResourceInfoV2.optional(),
747
- accepts: z2.array(PaymentRequirementsV2).min(1),
748
- extensions: z2.record(z2.unknown()).optional()
806
+ accepts: z3.array(PaymentRequirementsV2).min(1),
807
+ extensions: z3.record(z3.unknown()).optional()
749
808
  });
750
809
  function v2Requirements(requirement) {
751
810
  return {
@@ -758,7 +817,7 @@ function v2Requirements(requirement) {
758
817
  ...requirement.extra ? { extra: requirement.extra } : {}
759
818
  };
760
819
  }
761
- function buildPaymentRequiredV2(requirement, error) {
820
+ function buildPaymentRequiredV2(requirement, error, extensions = {}) {
762
821
  return {
763
822
  x402Version: 2,
764
823
  error,
@@ -770,17 +829,17 @@ function buildPaymentRequiredV2(requirement, error) {
770
829
  }
771
830
  } : {},
772
831
  accepts: [v2Requirements(requirement)],
773
- extensions: {}
832
+ extensions
774
833
  };
775
834
  }
776
835
  function encodeBase64Json(value) {
777
836
  return Buffer.from(JSON.stringify(value)).toString("base64");
778
837
  }
779
- var V1Envelope = z2.object({
780
- x402Version: z2.literal(1),
781
- scheme: z2.string(),
782
- network: z2.string(),
783
- payload: z2.record(z2.unknown())
838
+ var V1Envelope = z3.object({
839
+ x402Version: z3.literal(1),
840
+ scheme: z3.string(),
841
+ network: z3.string(),
842
+ payload: z3.record(z3.unknown())
784
843
  });
785
844
 
786
845
  // src/errors.ts
@@ -794,35 +853,35 @@ var FacilitatorError = class extends Error {
794
853
  };
795
854
 
796
855
  // src/payload.ts
797
- import { z as z3 } from "zod";
798
- var MockExactPayload = z3.object({
799
- from: z3.string().min(1),
800
- to: z3.string().min(1),
856
+ import { z as z4 } from "zod";
857
+ var MockExactPayload = z4.object({
858
+ from: z4.string().min(1),
859
+ to: z4.string().min(1),
801
860
  /** Atomic-unit amount, mirroring the requirement's maxAmountRequired. */
802
- value: z3.string().regex(/^\d+$/, "atomic amount must be an integer string"),
803
- asset: z3.string().min(1),
861
+ value: z4.string().regex(/^\d+$/, "atomic amount must be an integer string"),
862
+ asset: z4.string().min(1),
804
863
  /**
805
864
  * Rein linkage: the guard's payer stamps the intent id here, the facilitator
806
865
  * memos it onto the ledger entry, and the indexer reconciles exactly. A real
807
866
  * x402 transfer authorization carries a nonce that serves the same role.
808
867
  */
809
- intentId: z3.string().optional(),
810
- nonce: z3.string().optional()
868
+ intentId: z4.string().optional(),
869
+ nonce: z4.string().optional()
811
870
  });
812
- var MockPaymentHeader = z3.object({
813
- x402Version: z3.literal(1),
814
- scheme: z3.string(),
815
- network: z3.string(),
871
+ var MockPaymentHeader = z4.object({
872
+ x402Version: z4.literal(1),
873
+ scheme: z4.string(),
874
+ network: z4.string(),
816
875
  payload: MockExactPayload
817
876
  });
818
- var MockPaymentHeaderV2 = z3.object({
819
- x402Version: z3.literal(2),
820
- accepted: z3.object({
821
- scheme: z3.string(),
822
- network: z3.string(),
823
- amount: z3.string().regex(/^\d+$/, "atomic amount must be an integer string"),
824
- asset: z3.string().min(1),
825
- payTo: z3.string().min(1)
877
+ var MockPaymentHeaderV2 = z4.object({
878
+ x402Version: z4.literal(2),
879
+ accepted: z4.object({
880
+ scheme: z4.string(),
881
+ network: z4.string(),
882
+ amount: z4.string().regex(/^\d+$/, "atomic amount must be an integer string"),
883
+ asset: z4.string().min(1),
884
+ payTo: z4.string().min(1)
826
885
  }).passthrough(),
827
886
  payload: MockExactPayload
828
887
  }).passthrough();
@@ -868,12 +927,12 @@ function decodePaymentHeader(raw) {
868
927
  payload: parsed.data.payload
869
928
  };
870
929
  }
871
- var SettlementResponse = z3.object({
872
- success: z3.boolean(),
930
+ var SettlementResponse = z4.object({
931
+ success: z4.boolean(),
873
932
  /** The tx hash on the mock ledger (the guard surfaces this on the receipt). */
874
- transaction: z3.string(),
875
- network: z3.string(),
876
- payer: z3.string().optional()
933
+ transaction: z4.string(),
934
+ network: z4.string(),
935
+ payer: z4.string().optional()
877
936
  });
878
937
  function encodeSettlementHeader(response) {
879
938
  return Buffer.from(JSON.stringify(response)).toString("base64");