@reinconsole/mock-rails 0.1.1 → 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,34 +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 EnforcementMode = z.enum(["observed", "sdk", "session-key"]);
51
- var AgentWallet = z.object({
97
+ var EnforcementMode = z2.enum(["observed", "sdk", "session-key"]);
98
+ var AgentWallet = z2.object({
52
99
  chain: Chain,
53
- address: z.string().min(1),
100
+ address: z2.string().min(1),
54
101
  mode: EnforcementMode
55
102
  });
56
- var AgentStatus = z.enum(["active", "frozen"]);
57
- 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({
58
106
  id: AgentId,
59
107
  orgId: OrgId,
60
- name: z.string().min(1).max(200),
108
+ name: z2.string().min(1).max(200),
61
109
  /** On-chain ERC-8004 identity, if the agent is registered. */
62
- erc8004Id: z.string().optional(),
63
- wallets: z.array(AgentWallet).default([]),
110
+ erc8004Id: z2.string().optional(),
111
+ /** Semantic grouping labels — the targets of policy `appliesTo.labels`. */
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([]),
64
114
  status: AgentStatus.default("active"),
65
- createdAt: z.coerce.date()
115
+ createdAt: z2.coerce.date()
66
116
  });
67
117
  var ID_PATTERN = /^eip155:(\d+):(0x[0-9a-fA-F]{40})\/(\d+)$/;
68
118
  function parseErc8004Id(value) {
@@ -76,33 +126,33 @@ function parseErc8004Id(value) {
76
126
  tokenId: BigInt(match[3])
77
127
  };
78
128
  }
79
- var Erc8004Id = z.string().refine((value) => parseErc8004Id(value) !== void 0, {
129
+ var Erc8004Id = z2.string().refine((value) => parseErc8004Id(value) !== void 0, {
80
130
  message: 'expected "eip155:{chainId}:{registry}/{tokenId}"'
81
131
  });
82
- var Vendor = z.object({
83
- host: z.string().min(1),
84
- address: z.string().min(1),
85
- 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()
86
136
  });
87
- var TaskContext = z.object({
88
- taskId: z.string().optional(),
89
- parentRunId: z.string().optional(),
90
- 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()
91
141
  });
92
- var PaymentIntent = z.object({
142
+ var PaymentIntent = z2.object({
93
143
  id: IntentId,
94
144
  agentId: AgentId,
95
145
  vendor: Vendor,
96
- resource: z.string(),
146
+ resource: z2.string(),
97
147
  amount: DecimalString,
98
148
  asset: Asset,
99
149
  chain: Chain,
100
150
  taskContext: TaskContext.default({}),
101
- nonce: z.string().min(1),
102
- createdAt: z.coerce.date()
151
+ nonce: z2.string().min(1),
152
+ createdAt: z2.coerce.date()
103
153
  });
104
- var DecisionOutcome = z.enum(["allow", "deny", "escalate"]);
105
- var Decision = z.object({
154
+ var DecisionOutcome = z2.enum(["allow", "deny", "escalate"]);
155
+ var Decision = z2.object({
106
156
  id: DecisionId,
107
157
  intentId: IntentId,
108
158
  /**
@@ -111,211 +161,428 @@ var Decision = z.object({
111
161
  * chain — so a signer can verify an {intent, decision} pair offline as a
112
162
  * self-contained spend voucher, not just a reference by id.
113
163
  */
114
- intentHash: z.string(),
164
+ intentHash: z2.string(),
115
165
  outcome: DecisionOutcome,
116
166
  /** Ids of the rules that fired, for explainability. */
117
- matchedRules: z.array(z.string()).default([]),
167
+ matchedRules: z2.array(z2.string()).default([]),
118
168
  /** Human-readable explanation surfaced in the dashboard. */
119
- reason: z.string().optional(),
120
- policyId: z.string(),
121
- policyVersion: z.string(),
169
+ reason: z2.string().optional(),
170
+ policyId: z2.string(),
171
+ policyVersion: z2.string(),
122
172
  /** Hash of the previous decision in the chain (tamper-evident log). */
123
- prevHash: z.string(),
173
+ prevHash: z2.string(),
124
174
  /** Hash of this decision's canonical content. */
125
- hash: z.string(),
175
+ hash: z2.string(),
126
176
  /** Service signing-key signature over `hash`. */
127
- signature: z.string(),
128
- latencyMs: z.number().nonnegative(),
129
- decidedAt: z.coerce.date()
177
+ signature: z2.string(),
178
+ latencyMs: z2.number().nonnegative(),
179
+ decidedAt: z2.coerce.date()
130
180
  });
131
- var Session = z.object({
181
+ var AttributedDecision = Decision.extend({ agentId: AgentId.optional() });
182
+ var Session = z2.object({
132
183
  id: SessionId,
133
184
  agentId: AgentId,
134
185
  /** sha256 hex of the bearer token. */
135
- tokenHash: z.string(),
186
+ tokenHash: z2.string(),
136
187
  /** Cumulative ceiling across the session's lifetime. Absent = uncapped. */
137
188
  capAmount: DecimalString.optional(),
138
189
  /** Ceiling per individual signature. Absent = uncapped. */
139
190
  maxPerPayment: DecimalString.optional(),
140
- expiresAt: z.coerce.date(),
141
- createdAt: z.coerce.date(),
142
- revokedAt: z.coerce.date().optional()
191
+ expiresAt: z2.coerce.date(),
192
+ createdAt: z2.coerce.date(),
193
+ revokedAt: z2.coerce.date().optional()
143
194
  });
144
- var SettledPayment = z.object({
195
+ var SettledPayment = z2.object({
145
196
  intentId: IntentId,
146
- txHash: z.string(),
197
+ txHash: z2.string(),
147
198
  chain: Chain,
148
- blockNumber: z.coerce.bigint(),
149
- facilitator: z.string().optional(),
199
+ blockNumber: z2.coerce.bigint(),
200
+ facilitator: z2.string().optional(),
150
201
  feePaid: DecimalString.optional(),
151
- confirmedAt: z.coerce.date()
202
+ confirmedAt: z2.coerce.date()
203
+ });
204
+ var SettlementReport = z2.object({
205
+ intentId: IntentId,
206
+ /** The settling transaction, when the observer saw one. */
207
+ txHash: z2.string().optional(),
208
+ chain: Chain.optional(),
209
+ /** The amount as SETTLED, when known — may differ from the amount allowed. */
210
+ amount: DecimalString.optional(),
211
+ /** Free-form observer tag, e.g. "indexer", "guard", "facilitator". */
212
+ source: z2.string().min(1).max(64).optional(),
213
+ confirmedAt: z2.coerce.date()
152
214
  });
153
- var ReceiptSettlement = z.object({
154
- txHash: z.string().optional(),
155
- networkId: z.string().optional(),
215
+ var ReceiptSettlement = z2.object({
216
+ txHash: z2.string().optional(),
217
+ networkId: z2.string().optional(),
156
218
  /** Raw header payload, kept for forensics until the indexer confirms. */
157
- raw: z.string().optional()
219
+ raw: z2.string().optional()
158
220
  });
159
- var Receipt = z.object({
221
+ var Receipt = z2.object({
160
222
  id: ReceiptId,
161
223
  agentId: AgentId,
162
224
  intentId: IntentId,
163
225
  decisionId: DecisionId,
164
226
  outcome: DecisionOutcome,
165
227
  /** The URL the agent actually fetched (the paywalled resource). */
166
- url: z.string(),
167
- method: z.string().default("GET"),
168
- vendorHost: z.string(),
228
+ url: z2.string(),
229
+ method: z2.string().default("GET"),
230
+ vendorHost: z2.string(),
169
231
  amount: DecimalString,
170
232
  asset: Asset,
171
233
  chain: Chain,
172
234
  taskContext: TaskContext.default({}),
173
235
  /** Human-readable explanation copied from the decision. */
174
- reason: z.string().optional(),
236
+ reason: z2.string().optional(),
175
237
  /** Present only once a payment was made and the vendor confirmed it. */
176
238
  settlement: ReceiptSettlement.optional(),
177
- createdAt: z.coerce.date()
239
+ createdAt: z2.coerce.date()
178
240
  });
179
- var GateReceipt = z.object({
241
+ var GateReceipt = z2.object({
180
242
  id: GateReceiptId,
181
- at: z.coerce.date(),
243
+ at: z2.coerce.date(),
182
244
  /** The route pattern that priced this request, e.g. "/api/reports/*". */
183
- route: z.string().min(1),
245
+ route: z2.string().min(1),
184
246
  /** The concrete resource paid for (URL path actually requested). */
185
- resource: z.string().min(1),
186
- method: z.string().min(1),
247
+ resource: z2.string().min(1),
248
+ method: z2.string().min(1),
187
249
  /** The paying wallet address, as asserted by the settled payment. */
188
- payer: z.string().min(1),
189
- payTo: z.string().min(1),
250
+ payer: z2.string().min(1),
251
+ payTo: z2.string().min(1),
190
252
  /** Human-unit decimal amount, e.g. "0.05". */
191
253
  amount: DecimalString,
192
254
  /** The same amount in the asset's atomic units, e.g. "50000". */
193
- 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"),
194
256
  /** Token symbol or contract address, exactly as quoted in the requirement. */
195
- asset: z.string().min(1),
196
- network: z.string().min(1),
257
+ asset: z2.string().min(1),
258
+ network: z2.string().min(1),
197
259
  /** Settlement transaction hash (mock ledger or on-chain). */
198
- transaction: z.string().min(1)
260
+ transaction: z2.string().min(1)
199
261
  });
200
- var Window = z.string().regex(/^\d+[smhd]$/, 'window must be like "30s", "15m", "1h", or "7d"');
201
- var Multiplier = z.string().regex(/^\d+(\.\d+)?x$/, 'multiplier must be like "3x"');
202
- 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({
203
265
  /** Per-transaction amount exceeds this value. */
204
266
  amountGt: DecimalString.optional(),
205
267
  /** Sum of spend in a rolling window exceeds `gt`. */
206
- rollingSum: z.object({ window: Window, gt: DecimalString }).optional(),
268
+ rollingSum: z2.object({ window: Window, gt: DecimalString }).optional(),
207
269
  /** Transaction count in a rolling window exceeds `gt`. */
208
- txCount: z.object({ window: Window, gt: z.number().int().nonnegative() }).optional(),
270
+ txCount: z2.object({ window: Window, gt: z2.number().int().nonnegative() }).optional(),
209
271
  /** Vendor host matches one of these patterns (supports `*` globs). */
210
- vendorHostIn: z.array(z.string()).optional(),
272
+ vendorHostIn: z2.array(z2.string()).optional(),
273
+ /**
274
+ * Resource PATH matches one of these patterns (supports `*` globs, e.g.
275
+ * "/v1/reports/*"). A full-URL resource is reduced to its pathname before
276
+ * matching (see `resourcePathOf`), so the same pattern works whether the
277
+ * vendor declares "https://api.x.com/v1/answer" or "/v1/answer". Pair
278
+ * with `vendorHostIn` to scope a path rule to specific vendors.
279
+ */
280
+ resourceIn: z2.array(z2.string()).optional(),
211
281
  /** First time Rein has seen this vendor for the agent. */
212
- vendorFirstSeen: z.boolean().optional(),
282
+ vendorFirstSeen: z2.boolean().optional(),
213
283
  /** Vendor reputation score is below this threshold (Phase 3 hook). */
214
- vendorReputationLt: z.number().min(0).max(100).optional(),
284
+ vendorReputationLt: z2.number().min(0).max(100).optional(),
215
285
  /** Amount is more than `gt`-times the observed median for this resource. */
216
- amountVsResourceMedian: z.object({ gt: Multiplier }).optional()
286
+ amountVsResourceMedian: z2.object({ gt: Multiplier }).optional(),
287
+ /**
288
+ * Cumulative spend attributed to THIS intent's `taskContext.taskId`
289
+ * (prior spend on the task plus this payment) exceeds `gt`. Scopes a
290
+ * budget to one unit of work rather than to a window: a research run that
291
+ * is meant to cost a dollar cannot quietly cost fifty, however slowly.
292
+ *
293
+ * An intent carrying no `taskId` cannot be attributed to a task, so the
294
+ * predicate never triggers for one. Requiring attribution is a separate,
295
+ * deliberate rule (deny on `taskIdMissing`), not a side effect of setting
296
+ * a budget — otherwise every untagged probe payment would trip every
297
+ * task budget in the policy.
298
+ */
299
+ taskBudget: z2.object({ gt: DecimalString }).optional(),
300
+ /** The intent carries no `taskContext.taskId` (or an empty one). */
301
+ taskIdMissing: z2.boolean().optional()
217
302
  }).refine((c) => Object.values(c).some((v) => v !== void 0), {
218
303
  message: "a condition must specify at least one predicate"
219
304
  });
220
- var Rule = z.object({
221
- id: z.string().min(1),
305
+ var Breaker = z2.object({
306
+ id: z2.string().min(1),
307
+ /** The trailing span the tripwires measure over. */
308
+ window: Window,
309
+ /**
310
+ * Trip when the window would hold MORE than this many transactions.
311
+ * `10` permits ten in the window and escalates the eleventh.
312
+ */
313
+ txCount: z2.number().int().positive().optional(),
314
+ /**
315
+ * Trip when the window's spend would exceed this total. `"50.00"` permits
316
+ * a window totalling exactly 50.00 and escalates the payment that would
317
+ * carry it past. Prospective, like every other spend predicate: the
318
+ * payment that would breach the cap is the one that escalates, rather
319
+ * than the innocent one after it.
320
+ */
321
+ valueCap: DecimalString.optional()
322
+ }).refine((b) => b.txCount !== void 0 || b.valueCap !== void 0, {
323
+ message: "a breaker must specify at least one of txCount / valueCap"
324
+ });
325
+ var Rule = z2.object({
326
+ id: z2.string().min(1),
222
327
  allow: Condition.optional(),
223
328
  deny: Condition.optional(),
224
329
  escalate: Condition.optional()
225
330
  }).refine((r) => [r.allow, r.deny, r.escalate].filter((v) => v !== void 0).length === 1, {
226
331
  message: "a rule must specify exactly one of allow / deny / escalate"
227
332
  });
228
- var PolicyDefault = z.enum(["allow", "deny"]);
229
- var AppliesTo = z.object({
333
+ var PolicyDefault = z2.enum(["allow", "deny"]);
334
+ var AppliesTo = z2.object({
230
335
  /** Agent id patterns (supports `*` globs, e.g. "agt_research_*"). */
231
- agents: z.array(z.string()).optional(),
232
- chains: z.array(Chain).optional()
336
+ agents: z2.array(z2.string()).optional(),
337
+ /**
338
+ * Agent label patterns (supports `*` globs) — semantic targeting. Matches
339
+ * when the agent carries at least one label matching any pattern. Requires
340
+ * the agent DOCUMENT: an intent from an unregistered agent never matches a
341
+ * labels-targeted policy (and so fails closed when no other policy applies).
342
+ */
343
+ labels: z2.array(z2.string()).optional(),
344
+ chains: z2.array(Chain).optional()
233
345
  });
234
- var Escalation = z.object({
235
- approvers: z.array(z.string()).default([]),
346
+ var Escalation = z2.object({
347
+ approvers: z2.array(z2.string()).default([]),
236
348
  timeoutAction: PolicyDefault.default("deny"),
237
- timeoutMin: z.number().int().positive().default(15)
349
+ timeoutMin: z2.number().int().positive().default(15)
238
350
  });
239
- var Policy = z.object({
240
- policyId: z.string().min(1),
241
- 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(),
242
366
  appliesTo: AppliesTo.default({}),
243
- rules: z.array(Rule).default([]),
367
+ rules: z2.array(Rule).default([]),
368
+ /**
369
+ * Behavioral breakers evaluated alongside the rules. A tripped breaker
370
+ * escalates at the same precedence as an `escalate` rule — so an explicit
371
+ * DENY still wins, and an ALLOW rule cannot wave past a tripped breaker.
372
+ */
373
+ breakers: z2.array(Breaker).default([]),
244
374
  default: PolicyDefault.default("deny"),
245
375
  /** Below this amount, fail-open is permitted during a policy-service outage. */
246
376
  denyFloor: DecimalString.default("0.05"),
247
377
  escalation: Escalation.optional()
248
378
  });
249
- var ReputationSubject = z.object({
250
- kind: z.enum(["agent", "vendor"]),
251
- id: z.string()
379
+ var LivenessSource = z2.enum([
380
+ /** It submitted an intent — ANY outcome, including a denial. */
381
+ "intent",
382
+ /** It reported in explicitly, having nothing to buy. */
383
+ "heartbeat"
384
+ ]);
385
+ var DEFAULT_LIVENESS_GRACE_MS = 6e4;
386
+ var LivenessExpectation = z2.object({
387
+ agentId: AgentId,
388
+ /** Longest silence still considered normal, e.g. '15m'. */
389
+ interval: Window,
390
+ /** Extra slack past `interval` before the silence is an alarm. */
391
+ graceMs: z2.number().int().nonnegative().default(DEFAULT_LIVENESS_GRACE_MS),
392
+ /**
393
+ * When watching began. An agent that has NEVER been seen is measured from
394
+ * here, so a watch on an agent that never starts does raise an alarm — a
395
+ * detector that never came up is exactly as dead as one that stopped.
396
+ */
397
+ since: z2.coerce.date(),
398
+ /** What this agent is supposed to be doing, shown beside the alarm. */
399
+ note: z2.string().max(200).optional()
400
+ });
401
+ var LivenessWatchInput = LivenessExpectation.omit({ since: true }).extend({
402
+ graceMs: z2.number().int().nonnegative().optional()
403
+ });
404
+ var Heartbeat = z2.object({
405
+ agentId: AgentId,
406
+ /** When the agent was alive. Defaults to arrival time. */
407
+ at: z2.coerce.date().optional(),
408
+ /** Free-form note from the reporter, e.g. "poll cycle 41 ok". */
409
+ note: z2.string().max(200).optional()
410
+ });
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({
415
+ id: ApproverKeyId,
416
+ orgId: OrgId,
417
+ name: z2.string().min(1).max(200),
418
+ /** ed25519 public key, SPKI PEM — the same encoding as the decision log's. */
419
+ publicKey: z2.string().min(1),
420
+ algorithm: z2.literal("ed25519").default("ed25519"),
421
+ createdAt: z2.coerce.date(),
422
+ revokedAt: z2.coerce.date().optional()
423
+ });
424
+ var ApprovalRequest = z2.object({
425
+ /** The `escalate` decision this request answers (primary key). */
426
+ decisionId: DecisionId,
427
+ intentId: IntentId,
428
+ /** Binds the approval to the exact transfer — the signed bytes commit to it. */
429
+ intentHash: z2.string(),
430
+ agentId: AgentId,
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(),
441
+ amount: DecimalString,
442
+ asset: Asset,
443
+ chain: Chain,
444
+ /**
445
+ * Task attribution copied from the intent. Carried so an approved payment
446
+ * still counts against its `taskBudget` — an escalation that lost its task
447
+ * id on the way through would make the budget silently under-count exactly
448
+ * the payments a human had to look at.
449
+ */
450
+ taskId: z2.string().optional(),
451
+ /** Why policy escalated, verbatim from the decision. */
452
+ reason: z2.string(),
453
+ /**
454
+ * Breaker ids whose trip contributed to this escalation. An approval of
455
+ * this request resets exactly these — moving their counting floor to the
456
+ * approval instant — so a human waving one payment through also clears the
457
+ * behavior that stopped it, rather than being asked again immediately.
458
+ * Empty when ordinary rules did the escalating.
459
+ */
460
+ breakers: z2.array(z2.string()).default([]),
461
+ status: ApprovalStatus,
462
+ createdAt: z2.coerce.date(),
463
+ /** Past this instant the request denies, whatever arrives afterwards. */
464
+ expiresAt: z2.coerce.date(),
465
+ resolvedAt: z2.coerce.date().optional(),
466
+ /** Which registered key signed — absent when the TTL lapsed instead. */
467
+ approverKeyId: ApproverKeyId.optional(),
468
+ /**
469
+ * The follow-up decision appended to the chain when this resolved. That
470
+ * decision, not this record, is the voucher a signer verifies: the original
471
+ * `escalate` decision is never rewritten.
472
+ */
473
+ finalDecisionId: DecisionId.optional()
474
+ });
475
+ var ApprovalChallenges = z2.object({
476
+ approve: z2.string(),
477
+ reject: z2.string()
478
+ });
479
+ var ApprovalGrant = z2.object({
480
+ decisionId: DecisionId,
481
+ intentHash: z2.string(),
482
+ verdict: ApprovalVerdict,
483
+ approverKeyId: ApproverKeyId,
484
+ signature: z2.string().min(1)
485
+ });
486
+ var ReputationSubject = z2.object({
487
+ kind: z2.enum(["agent", "vendor"]),
488
+ id: z2.string()
252
489
  });
253
- var ReputationComponents = z.object({
254
- volume: z.number(),
255
- longevity: z.number(),
256
- disputeRate: z.number(),
257
- counterpartyQuality: z.number(),
258
- 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()
259
496
  });
260
- var ReputationScore = z.object({
497
+ var ReputationScore = z2.object({
261
498
  subject: ReputationSubject,
262
- score: z.number().min(0).max(100),
499
+ score: z2.number().min(0).max(100),
263
500
  components: ReputationComponents,
264
- confidence: z.number().min(0).max(1),
265
- asOf: z.coerce.date(),
501
+ confidence: z2.number().min(0).max(1),
502
+ asOf: z2.coerce.date(),
266
503
  /** Hash-anchored attestation, optionally published on-chain (ERC-8004). */
267
- evidenceUri: z.string().optional()
268
- });
269
- var ReinEvent = z.discriminatedUnion("type", [
270
- z.object({ type: z.literal("intent.created"), at: z.coerce.date(), intent: PaymentIntent }),
271
- z.object({ type: z.literal("decision.made"), at: z.coerce.date(), decision: Decision }),
272
- z.object({ type: z.literal("payment.settled"), at: z.coerce.date(), payment: SettledPayment }),
273
- z.object({
274
- type: z.literal("shadow.spend"),
275
- at: z.coerce.date(),
504
+ evidenceUri: z2.string().optional()
505
+ });
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(),
276
513
  agentId: AgentId,
277
- txHash: z.string(),
514
+ txHash: z2.string(),
278
515
  chain: Chain,
279
516
  amount: DecimalString
280
517
  }),
281
- z.object({
282
- type: z.literal("signature.released"),
283
- at: z.coerce.date(),
518
+ z2.object({
519
+ type: z2.literal("signature.released"),
520
+ at: z2.coerce.date(),
284
521
  sessionId: SessionId,
285
522
  agentId: AgentId,
286
523
  intentId: IntentId,
287
524
  decisionId: DecisionId,
288
525
  amount: DecimalString
289
526
  }),
290
- z.object({
291
- type: z.literal("signature.refused"),
292
- at: z.coerce.date(),
527
+ z2.object({
528
+ type: z2.literal("signature.refused"),
529
+ at: z2.coerce.date(),
293
530
  /** Refusal code, e.g. "decision_replayed" (see @reinconsole/signer). */
294
- code: z.string(),
295
- reason: z.string(),
531
+ code: z2.string(),
532
+ reason: z2.string(),
296
533
  sessionId: SessionId.optional(),
297
534
  agentId: AgentId.optional(),
298
535
  intentId: IntentId.optional()
299
536
  }),
300
- z.object({
301
- type: z.literal("gate.quoted"),
302
- at: z.coerce.date(),
303
- resource: z.string(),
304
- 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(),
305
542
  amount: DecimalString,
306
- asset: z.string(),
307
- network: z.string()
543
+ asset: z2.string(),
544
+ network: z2.string()
545
+ }),
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(),
550
+ request: ApprovalRequest
551
+ }),
552
+ z2.object({
553
+ type: z2.literal("approval.resolved"),
554
+ at: z2.coerce.date(),
555
+ request: ApprovalRequest,
556
+ /** The follow-up allow/deny decision this resolution appended. */
557
+ decision: Decision
308
558
  }),
309
- z.object({ type: z.literal("gate.settled"), at: z.coerce.date(), receipt: GateReceipt }),
310
- z.object({
311
- type: z.literal("gate.refused"),
312
- at: z.coerce.date(),
559
+ z2.object({
560
+ type: z2.literal("liveness.missing"),
561
+ at: z2.coerce.date(),
562
+ agentId: AgentId,
563
+ expectation: LivenessExpectation,
564
+ /** How long the agent has been silent when the alarm was raised. */
565
+ silentMs: z2.number().int().nonnegative(),
566
+ /** Last sighting, absent when the agent was never seen at all. */
567
+ lastSeenAt: z2.coerce.date().optional()
568
+ }),
569
+ z2.object({
570
+ type: z2.literal("liveness.recovered"),
571
+ at: z2.coerce.date(),
572
+ agentId: AgentId,
573
+ /** How long the silence lasted, measured to this sighting. */
574
+ silentMs: z2.number().int().nonnegative(),
575
+ source: LivenessSource
576
+ }),
577
+ z2.object({
578
+ type: z2.literal("gate.refused"),
579
+ at: z2.coerce.date(),
313
580
  /** Refusal code, e.g. "payment_replayed" (see @reinconsole/gate). */
314
- code: z.string(),
315
- reason: z.string(),
316
- resource: z.string(),
581
+ code: z2.string(),
582
+ reason: z2.string(),
583
+ resource: z2.string(),
317
584
  /** Known only when the payment header decoded far enough to name a payer. */
318
- payer: z.string().optional()
585
+ payer: z2.string().optional()
319
586
  })
320
587
  ]);
321
588
 
@@ -350,27 +617,103 @@ var MockLedger = class {
350
617
  };
351
618
 
352
619
  // ../../packages/sdk/dist/index.js
353
- import { z as z2 } from "zod";
354
- var Health = z2.object({ status: z2.string(), publicKey: z2.string() });
355
- var EvaluateResponse = z2.object({ intent: PaymentIntent, decision: Decision });
356
- var PaymentRequirement = z2.object({
357
- scheme: z2.string(),
358
- network: z2.string(),
620
+ import { z as z3 } from "zod";
621
+ var BreakerState = z3.object({
622
+ breaker: Breaker,
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()
630
+ });
631
+ var LivenessState = z3.object({
632
+ agentId: z3.string(),
633
+ expectation: LivenessExpectation,
634
+ lastSeenAt: z3.number().optional(),
635
+ lastSource: LivenessSource.optional(),
636
+ silentSince: z3.number(),
637
+ silentMs: z3.number(),
638
+ dueAt: z3.number(),
639
+ overdueAt: z3.number(),
640
+ status: LivenessStatus,
641
+ alertedAt: z3.number().optional()
642
+ });
643
+ var Health = z3.object({
644
+ status: z3.string(),
645
+ publicKey: z3.string(),
646
+ /** "api-key" once the engine demands a credential; "none" while it does not. */
647
+ auth: z3.string().optional(),
648
+ approvals: z3.string().optional()
649
+ });
650
+ var EvaluateResponse = z3.object({
651
+ intent: PaymentIntent,
652
+ decision: Decision,
653
+ /** Present when an escalation was parked for a signed verdict. */
654
+ approval: ApprovalRequest.optional()
655
+ });
656
+ var ApprovalView = z3.object({
657
+ request: ApprovalRequest,
658
+ challenges: ApprovalChallenges,
659
+ /** The follow-up allow/deny decision, once the request has resolved. */
660
+ decision: Decision.optional()
661
+ });
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"])
675
+ });
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()
697
+ });
698
+ var IssuedApiKey = z3.object({ key: ApiKey, secret: z3.string() });
699
+ var PaymentRequirement = z3.object({
700
+ scheme: z3.string(),
701
+ network: z3.string(),
359
702
  /** Amount in the asset's atomic units (e.g. "10000" = 0.01 USDC at 6 decimals). */
360
- maxAmountRequired: z2.string().regex(/^\d+$/, "atomic amount must be an integer string"),
361
- resource: z2.string().optional(),
362
- description: z2.string().optional(),
363
- mimeType: z2.string().optional(),
364
- payTo: z2.string().min(1),
365
- 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(),
366
709
  /** Token contract address — or, mock-first, a plain symbol like "USDC". */
367
- asset: z2.string().min(1),
368
- extra: z2.record(z2.unknown()).optional()
710
+ asset: z3.string().min(1),
711
+ extra: z3.record(z3.unknown()).optional()
369
712
  });
370
- var PaymentRequired = z2.object({
371
- x402Version: z2.number(),
372
- accepts: z2.array(PaymentRequirement).min(1),
373
- 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()
374
717
  });
375
718
  var NETWORK_TO_CHAIN = {
376
719
  base: "base",
@@ -384,6 +727,8 @@ var NETWORK_TO_CHAIN = {
384
727
  bnb: "bnb",
385
728
  bsc: "bnb"
386
729
  };
730
+ var ASSET_DECIMALS = { USDC: 6, USDT: 6, EURC: 6 };
731
+ var EVM_ADDRESS = /^0x[0-9a-fA-F]{40}$/;
387
732
  var KNOWN_ASSET_ADDRESSES = {
388
733
  "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913": "USDC",
389
734
  // USDC on Base
@@ -392,18 +737,38 @@ var KNOWN_ASSET_ADDRESSES = {
392
737
  EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v: "USDC"
393
738
  // USDC on Solana
394
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
+ }
395
757
  function networkToChain(network) {
396
758
  return NETWORK_TO_CHAIN[network.toLowerCase()];
397
759
  }
398
760
  function resolveAsset(requirement, extraAddresses = {}) {
399
761
  const direct = Asset.safeParse(requirement.asset.toUpperCase());
400
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;
401
766
  const symbol = requirement.extra?.["symbol"];
402
767
  if (typeof symbol === "string") {
403
768
  const fromExtra = Asset.safeParse(symbol.toUpperCase());
404
769
  if (fromExtra.success) return fromExtra.data;
405
770
  }
406
- return extraAddresses[requirement.asset] ?? extraAddresses[requirement.asset.toLowerCase()] ?? KNOWN_ASSET_ADDRESSES[requirement.asset] ?? KNOWN_ASSET_ADDRESSES[requirement.asset.toLowerCase()];
771
+ return void 0;
407
772
  }
408
773
  function atomicToDecimal(atomic, decimals) {
409
774
  if (!/^\d+$/.test(atomic)) throw new TypeError(`invalid atomic amount: ${atomic}`);
@@ -413,49 +778,33 @@ function atomicToDecimal(atomic, decimals) {
413
778
  const fracPart = digits.slice(digits.length - decimals).replace(/0+$/, "");
414
779
  return fracPart.length > 0 ? `${intPart}.${fracPart}` : intPart;
415
780
  }
416
- function requirementDecimals(requirement) {
781
+ function requirementDecimals(requirement, asset) {
782
+ if (asset) return ASSET_DECIMALS[asset];
417
783
  const decimals = requirement.extra?.["decimals"];
418
784
  return typeof decimals === "number" && Number.isInteger(decimals) && decimals >= 0 ? decimals : 6;
419
785
  }
420
- var CAIP2_ALIASES = {
421
- base: "eip155:8453",
422
- "base-sepolia": "eip155:84532",
423
- polygon: "eip155:137",
424
- "polygon-amoy": "eip155:80002",
425
- bnb: "eip155:56",
426
- bsc: "eip155:56",
427
- solana: "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",
428
- "solana-devnet": "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1"
429
- };
430
- function caip2Of(network) {
431
- const key = network.toLowerCase();
432
- return CAIP2_ALIASES[key] ?? key;
433
- }
434
- function sameNetwork(a, b) {
435
- return caip2Of(a) === caip2Of(b);
436
- }
437
- var PaymentRequirementsV2 = z2.object({
438
- scheme: z2.string(),
786
+ var PaymentRequirementsV2 = z3.object({
787
+ scheme: z3.string(),
439
788
  /** CAIP-2, e.g. "eip155:84532". */
440
- network: z2.string(),
789
+ network: z3.string(),
441
790
  /** Atomic units — v2's rename of v1's maxAmountRequired. */
442
- amount: z2.string().regex(/^\d+$/, "atomic amount must be an integer string"),
443
- asset: z2.string().min(1),
444
- payTo: z2.string().min(1),
445
- maxTimeoutSeconds: z2.number().optional(),
446
- 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()
447
796
  });
448
- var ResourceInfoV2 = z2.object({
449
- url: z2.string(),
450
- description: z2.string().optional(),
451
- mimeType: z2.string().optional()
797
+ var ResourceInfoV2 = z3.object({
798
+ url: z3.string(),
799
+ description: z3.string().optional(),
800
+ mimeType: z3.string().optional()
452
801
  });
453
- var PaymentRequiredV2 = z2.object({
454
- x402Version: z2.literal(2),
455
- error: z2.string().optional(),
802
+ var PaymentRequiredV2 = z3.object({
803
+ x402Version: z3.literal(2),
804
+ error: z3.string().optional(),
456
805
  resource: ResourceInfoV2.optional(),
457
- accepts: z2.array(PaymentRequirementsV2).min(1),
458
- extensions: z2.record(z2.unknown()).optional()
806
+ accepts: z3.array(PaymentRequirementsV2).min(1),
807
+ extensions: z3.record(z3.unknown()).optional()
459
808
  });
460
809
  function v2Requirements(requirement) {
461
810
  return {
@@ -468,7 +817,7 @@ function v2Requirements(requirement) {
468
817
  ...requirement.extra ? { extra: requirement.extra } : {}
469
818
  };
470
819
  }
471
- function buildPaymentRequiredV2(requirement, error) {
820
+ function buildPaymentRequiredV2(requirement, error, extensions = {}) {
472
821
  return {
473
822
  x402Version: 2,
474
823
  error,
@@ -480,17 +829,17 @@ function buildPaymentRequiredV2(requirement, error) {
480
829
  }
481
830
  } : {},
482
831
  accepts: [v2Requirements(requirement)],
483
- extensions: {}
832
+ extensions
484
833
  };
485
834
  }
486
835
  function encodeBase64Json(value) {
487
836
  return Buffer.from(JSON.stringify(value)).toString("base64");
488
837
  }
489
- var V1Envelope = z2.object({
490
- x402Version: z2.literal(1),
491
- scheme: z2.string(),
492
- network: z2.string(),
493
- 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())
494
843
  });
495
844
 
496
845
  // src/errors.ts
@@ -504,35 +853,35 @@ var FacilitatorError = class extends Error {
504
853
  };
505
854
 
506
855
  // src/payload.ts
507
- import { z as z3 } from "zod";
508
- var MockExactPayload = z3.object({
509
- from: z3.string().min(1),
510
- 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),
511
860
  /** Atomic-unit amount, mirroring the requirement's maxAmountRequired. */
512
- value: z3.string().regex(/^\d+$/, "atomic amount must be an integer string"),
513
- asset: z3.string().min(1),
861
+ value: z4.string().regex(/^\d+$/, "atomic amount must be an integer string"),
862
+ asset: z4.string().min(1),
514
863
  /**
515
864
  * Rein linkage: the guard's payer stamps the intent id here, the facilitator
516
865
  * memos it onto the ledger entry, and the indexer reconciles exactly. A real
517
866
  * x402 transfer authorization carries a nonce that serves the same role.
518
867
  */
519
- intentId: z3.string().optional(),
520
- nonce: z3.string().optional()
868
+ intentId: z4.string().optional(),
869
+ nonce: z4.string().optional()
521
870
  });
522
- var MockPaymentHeader = z3.object({
523
- x402Version: z3.literal(1),
524
- scheme: z3.string(),
525
- network: z3.string(),
871
+ var MockPaymentHeader = z4.object({
872
+ x402Version: z4.literal(1),
873
+ scheme: z4.string(),
874
+ network: z4.string(),
526
875
  payload: MockExactPayload
527
876
  });
528
- var MockPaymentHeaderV2 = z3.object({
529
- x402Version: z3.literal(2),
530
- accepted: z3.object({
531
- scheme: z3.string(),
532
- network: z3.string(),
533
- amount: z3.string().regex(/^\d+$/, "atomic amount must be an integer string"),
534
- asset: z3.string().min(1),
535
- 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)
536
885
  }).passthrough(),
537
886
  payload: MockExactPayload
538
887
  }).passthrough();
@@ -578,12 +927,12 @@ function decodePaymentHeader(raw) {
578
927
  payload: parsed.data.payload
579
928
  };
580
929
  }
581
- var SettlementResponse = z3.object({
582
- success: z3.boolean(),
930
+ var SettlementResponse = z4.object({
931
+ success: z4.boolean(),
583
932
  /** The tx hash on the mock ledger (the guard surfaces this on the receipt). */
584
- transaction: z3.string(),
585
- network: z3.string(),
586
- payer: z3.string().optional()
933
+ transaction: z4.string(),
934
+ network: z4.string(),
935
+ payer: z4.string().optional()
587
936
  });
588
937
  function encodeSettlementHeader(response) {
589
938
  return Buffer.from(JSON.stringify(response)).toString("base64");