@correntelabs/beeai-ashlar-bridge 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/README.md +75 -0
  2. package/STRESS_REPORT.md +71 -0
  3. package/dist/packages/beeai-ashlar-bridge/src/ashlar-tool.d.ts +84 -0
  4. package/dist/packages/beeai-ashlar-bridge/src/ashlar-tool.js +202 -0
  5. package/dist/packages/beeai-ashlar-bridge/src/beehive-swarm.d.ts +1 -0
  6. package/dist/packages/beeai-ashlar-bridge/src/beehive-swarm.js +157 -0
  7. package/dist/packages/beeai-ashlar-bridge/src/catalog-tool.d.ts +28 -0
  8. package/dist/packages/beeai-ashlar-bridge/src/catalog-tool.js +64 -0
  9. package/dist/packages/beeai-ashlar-bridge/src/compliance-tool.d.ts +34 -0
  10. package/dist/packages/beeai-ashlar-bridge/src/compliance-tool.js +73 -0
  11. package/dist/packages/beeai-ashlar-bridge/src/demo-agent.d.ts +1 -0
  12. package/dist/packages/beeai-ashlar-bridge/src/demo-agent.js +149 -0
  13. package/dist/packages/beeai-ashlar-bridge/src/index.d.ts +3 -0
  14. package/dist/packages/beeai-ashlar-bridge/src/index.js +3 -0
  15. package/dist/packages/beeai-ashlar-bridge/src/large-swarm-stress.d.ts +1 -0
  16. package/dist/packages/beeai-ashlar-bridge/src/large-swarm-stress.js +152 -0
  17. package/dist/src/x402/mandate.d.ts +449 -0
  18. package/dist/src/x402/mandate.js +1234 -0
  19. package/dist/src/x402/manifest-sig.d.ts +163 -0
  20. package/dist/src/x402/manifest-sig.js +259 -0
  21. package/dist/src/x402/merkle-transcript.d.ts +73 -0
  22. package/dist/src/x402/merkle-transcript.js +159 -0
  23. package/package.json +37 -0
  24. package/src/ashlar-tool.ts +277 -0
  25. package/src/beehive-swarm.ts +172 -0
  26. package/src/catalog-tool.ts +80 -0
  27. package/src/compliance-tool.ts +89 -0
  28. package/src/demo-agent.ts +163 -0
  29. package/src/index.ts +3 -0
  30. package/src/large-swarm-stress.ts +180 -0
  31. package/tsconfig.json +21 -0
@@ -0,0 +1,449 @@
1
+ import { type Ed25519Signer } from './manifest-sig.js';
2
+ export declare const MANDATE_VERSION = "x402-mandate/1";
3
+ /** Recipient sentinel: an EXPLICIT, signed opt-in to an unconstrained payee set. Must be the SOLE element. */
4
+ export declare const ANY_RECIPIENT = "*";
5
+ /** Accountant sentinel selecting Model B: spend entries are co-signed by their payees; no single accountant key. */
6
+ export declare const PAYEES_ACCOUNTANT = "payees";
7
+ export interface Mandate {
8
+ v: typeof MANDATE_VERSION;
9
+ /** base64url Ed25519 public key of the PRINCIPAL that issued this grant. */
10
+ issuer: string;
11
+ /** The agent payer identity this grant authorizes. Bound to the payment's payer. */
12
+ subject: string;
13
+ /** Asset the cap and amounts are denominated in. */
14
+ asset: string;
15
+ /** Maximum CUMULATIVE spend, integer minor units as a decimal string. */
16
+ cap: string;
17
+ /** Optional maximum for any SINGLE payment, integer minor units. MUST be <= cap. */
18
+ perPayment?: string;
19
+ /**
20
+ * Allowed payees. Under Model B ('payees' accountant) each recipient MUST
21
+ * itself be a base64url Ed25519 key — the identity IS the attesting key.
22
+ * Exactly [ANY_RECIPIENT] is a signed opt-in to any payee; mixing '*' with
23
+ * named recipients is invalid.
24
+ */
25
+ recipients: string[];
26
+ /**
27
+ * THE TRUST ROOT FOR ACCOUNTING: either one base64url Ed25519 key (Model A
28
+ * — this exact key must sign every committed head) or PAYEES_ACCOUNTANT
29
+ * (Model B). A verifier MUST take the accountant from here, never from the
30
+ * presenter.
31
+ */
32
+ accountant: string;
33
+ /** Human-readable purpose, carried verbatim. */
34
+ purpose: string;
35
+ /** Expiry, strict RFC 3339 UTC (must end in 'Z'). */
36
+ notAfter: string;
37
+ /** Uniqueness — distinguishes two otherwise-identical grants. */
38
+ nonce: string;
39
+ /**
40
+ * DELEGATION: the sha256:<hex> digest of the PARENT mandate this grant is
41
+ * carved from. Absent on a root grant. A delegated grant is signed by the
42
+ * parent's SUBJECT and may only NARROW every bound (see
43
+ * issueDelegatedMandate / verifyDelegationChain).
44
+ */
45
+ parent?: string;
46
+ }
47
+ export interface SignedMandate {
48
+ mandate: Mandate;
49
+ alg: 'Ed25519';
50
+ /** base64url Ed25519 signature over DS_TAG || jcsCanonical(mandate). */
51
+ sig: string;
52
+ }
53
+ /**
54
+ * One split leg: an ADDITIONAL recipient paid by the same payment. Mirrors an
55
+ * entry of x402's `PaymentRequirements.extra.splits` (platform fees, revenue
56
+ * share, referral commissions), reduced to the two fields authority cares
57
+ * about. All legs share the payment's `asset`; a scheme that splits ACROSS
58
+ * assets is out of scope here and MUST NOT be modelled with this field.
59
+ */
60
+ export interface PaymentSplit {
61
+ recipient: string;
62
+ amount: string;
63
+ }
64
+ /**
65
+ * One payment presented for authorization against a Mandate.
66
+ *
67
+ * MULTI-PAYEE: `recipient`/`amount` are the primary (`payTo`) leg; `splits`
68
+ * carries any ADDITIONAL legs of the SAME payment, matching x402's model where
69
+ * `extra.splits` is additional to `payTo`. Absent or empty `splits` is exactly
70
+ * today's single-leg behaviour, so nothing existing changes. When splits ARE
71
+ * present, EVERY leg's recipient is scope-checked and the per-payment bound and
72
+ * cap bind the TOTAL across all legs — a payment cannot pay eight strangers, or
73
+ * move more than its cap, by moving the money into legs the check never reads.
74
+ */
75
+ export interface MandatePayment {
76
+ payer: string;
77
+ recipient: string;
78
+ asset: string;
79
+ amount: string;
80
+ /** 'sha256:...' of the mandate this payment was made under — bound into the payment preimage. */
81
+ mandateDigest: string;
82
+ /** When the payment settled, strict RFC 3339 UTC. Advisory only — expiry is judged on the verifier's clock. */
83
+ at?: string;
84
+ /** ADDITIONAL legs beyond `recipient`/`amount`. Absent = single-leg. */
85
+ splits?: PaymentSplit[];
86
+ }
87
+ export interface MandateVerdict {
88
+ ok: boolean;
89
+ reasons: string[];
90
+ warnings: string[];
91
+ }
92
+ /** The digest a payment binds to (domain-separated). */
93
+ export declare function mandateDigest(m: Mandate): string;
94
+ /** Sign a mandate with the principal's key. Rejects malformed grants, perPayment>cap, and a signer that is not the issuer. */
95
+ export declare function issueMandate(m: Mandate, signer: Ed25519Signer): SignedMandate;
96
+ /** Verify the issuer's signature over the (domain-separated) grant, offline. False on any structural or crypto failure. */
97
+ export declare function verifyMandateSignature(sm: SignedMandate): boolean;
98
+ /**
99
+ * The offline authority check for ONE payment against a Mandate. Total —
100
+ * returns a verdict, never throws — and judges expiry on the VERIFIER's clock,
101
+ * not the payer's self-asserted `at`.
102
+ *
103
+ * MULTI-PAYEE (`payment.splits`): a payment may pay several recipients at once
104
+ * (x402 `extra.splits`). EVERY leg is scope-checked, and the per-payment bound
105
+ * and the cap bind the TOTAL across all legs. Without that, a mandate scoped to
106
+ * one merchant would authorize a payment that also pays eight strangers, and a
107
+ * cap would bind only the primary leg while the real outflow exceeded it — the
108
+ * exact failure this object exists to prevent, re-entering through a scheme
109
+ * feature. Absent/empty `splits` is byte-for-byte today's behaviour.
110
+ *
111
+ * HONESTY: this bounds ONE payment's total. The spend LOG still records a
112
+ * single (recipient, amount) per entry, so a multi-leg payment's per-leg
113
+ * breakdown is not represented in the Merkle log — cumulative accounting sees
114
+ * the primary leg only. Log the TOTAL as the entry amount until SpendEntry
115
+ * grows legs, and treat per-leg cumulative attribution as unsolved.
116
+ */
117
+ export declare function checkPayment(sm: SignedMandate, payment: MandatePayment, opts?: {
118
+ now?: () => number;
119
+ }): MandateVerdict;
120
+ /** One committed spend under a mandate. Bound to the mandate + asset, and chained to the prior root (append-only). */
121
+ export interface SpendEntry {
122
+ mandateDigest: string;
123
+ asset: string;
124
+ paymentId: string;
125
+ recipient: string;
126
+ amount: string;
127
+ /** Running total after this payment. Equals previous cumulative + amount. */
128
+ cumulative: string;
129
+ /** Merkle root of the log BEFORE this entry — an edit/reorder/insert breaks the chain. */
130
+ priorRoot: string;
131
+ }
132
+ /** An append-only, mandate-bound, Merkle-committed record of spend under one mandate. */
133
+ export declare class SpendLog {
134
+ private readonly mandateDigestHex;
135
+ private readonly asset;
136
+ private entries;
137
+ private ids;
138
+ constructor(mandateDigestHex: string, asset: string);
139
+ add(paymentId: string, recipient: string, amount: string): this;
140
+ get size(): number;
141
+ all(): SpendEntry[];
142
+ total(): string;
143
+ root(): string;
144
+ prove(index: number): {
145
+ entry: SpendEntry;
146
+ index: number;
147
+ size: number;
148
+ proof: string[];
149
+ };
150
+ /**
151
+ * Produce the committed head over the current (root, total) at a monotonic
152
+ * seq. This is the ONLY blessed committing path: the root and total are
153
+ * derived from the entries the log actually holds, never handed in — an
154
+ * accountant signing a (root, total) it did not derive is signing blind.
155
+ */
156
+ commit(seq: number, accountant: Ed25519Signer, at: string): SignedCommitment;
157
+ }
158
+ /** Verify one spend entry belongs to a committed spend-log root, holding nothing else. */
159
+ export declare function verifySpendEntry(entry: SpendEntry, index: number, size: number, proof: string[], root: string): boolean;
160
+ /**
161
+ * Verify a presented spend history is INTERNALLY sound against a mandate:
162
+ * authenticated grant, every entry bound to THIS mandate + asset, scope and
163
+ * per-payment re-checked, duplicate paymentIds refused, append-only chain
164
+ * verified, running totals gap-free, total within cap.
165
+ *
166
+ * HONESTY: a truncated PREFIX of the true history passes all of this. This
167
+ * function alone is tamper-evidence, not completeness — completeness comes
168
+ * from a committed head (Model A) with a freshness floor.
169
+ */
170
+ export declare function verifySpendWithinCap(sm: SignedMandate, entries: SpendEntry[]): MandateVerdict;
171
+ export declare const COMMIT_VERSION = "x402-mandate-commit/1";
172
+ /** A signed statement that "as of seq, the spend log for this mandate has this root and this total." */
173
+ export interface SpendCommitment {
174
+ v: typeof COMMIT_VERSION;
175
+ mandateDigest: string;
176
+ /** The Ed25519 key that signs this head. MUST equal the mandate's accountant to be acceptable. */
177
+ accountant: string;
178
+ /** Monotonic per mandate — a later head MUST carry a strictly greater seq. */
179
+ seq: number;
180
+ root: string;
181
+ total: string;
182
+ at: string;
183
+ }
184
+ export interface SignedCommitment {
185
+ commitment: SpendCommitment;
186
+ alg: 'Ed25519';
187
+ sig: string;
188
+ }
189
+ /** Sign a committed head. Prefer SpendLog.commit, which derives root/total from real entries. */
190
+ export declare function commitHead(c: SpendCommitment, accountant: Ed25519Signer): SignedCommitment;
191
+ /**
192
+ * Verify a head is SELF-consistent: signed by the key it names as accountant.
193
+ * Self-consistency is not authorization — verifySpendAgainstCommitment also
194
+ * requires that key to equal the MANDATE's accountant (the trust root).
195
+ */
196
+ export declare function verifyCommitment(sc: SignedCommitment): boolean;
197
+ /** LAYER 2: the digest anchored on-chain / in a transparency log. */
198
+ export declare function commitmentAnchorDigest(sc: SignedCommitment): string;
199
+ /**
200
+ * LAYER 2 calldata (the evidence lane's x402note/1 grammar). Carries the
201
+ * mandate + seq so a scanner can find the highest anchored head for a mandate,
202
+ * and `by=<accountant>` so anchors are attributable without fetching the head.
203
+ * Anchoring is permissionless: an anchor proves WHEN, never honesty.
204
+ */
205
+ export declare function commitmentAnchorCalldata(sc: SignedCommitment): string;
206
+ /** Verify an on-chain anchor's calldata commits to exactly THIS head. Pair with the tx's block timestamp for the WHEN. */
207
+ export declare function verifyCommitmentAnchor(sc: SignedCommitment, calldata: string): boolean;
208
+ /**
209
+ * MODEL A cap check against a committed head. The accountant is taken from the
210
+ * MANDATE (the trust root) — a presenter can never name their own. The
211
+ * presented entries must reproduce the committed root AND total.
212
+ *
213
+ * `lastSeq` is REQUIRED: pass the highest seq you have previously accepted for
214
+ * this mandate (from your own state, or the highest anchored seq you read from
215
+ * Layer 2). Passing `null` means you have no freshness floor — the check still
216
+ * runs, but the verdict carries a loud warning: without a floor you get
217
+ * tamper-evidence, NOT completeness, because an old validly-signed head plus
218
+ * its prefix log passes (first-contact truncation).
219
+ */
220
+ export declare function verifySpendAgainstCommitment(sm: SignedMandate, entries: SpendEntry[], sc: SignedCommitment, lastSeq: number | null): MandateVerdict;
221
+ /**
222
+ * The counterparty's POST-SETTLE check (MUST-rule 2): the payment it just
223
+ * accepted is INCLUDED under a NEW committed head strictly newer than the one
224
+ * it saw before settling. This is what forces the head to advance per payment
225
+ * — an authorized payment that is never committed is otherwise invisible.
226
+ */
227
+ export declare function verifyPaymentCommitted(sm: SignedMandate, paymentId: string, proof: {
228
+ entry: SpendEntry;
229
+ index: number;
230
+ size: number;
231
+ proof: string[];
232
+ }, newHead: SignedCommitment, prevSeq: number,
233
+ /** OPTIONAL but STRONGLY RECOMMENDED: the fields decoded from the settled
234
+ * artifact. When supplied, the included entry's recipient/asset/amount MUST
235
+ * equal them — this is what stops an agent committing a truthful-looking
236
+ * head over an amount smaller than what actually settled (see §7/§13). */
237
+ settled?: {
238
+ recipient: string;
239
+ asset: string;
240
+ amount: string;
241
+ }): MandateVerdict;
242
+ export declare const PAYEE_ATT_VERSION = "x402-mandate-payee/1";
243
+ /**
244
+ * A payee's signed acknowledgement that it received a specific payment under a
245
+ * mandate. The payee identity IS its Ed25519 key (enforced by the mandate's
246
+ * shape when accountant='payees'), so there is no prose-level payee↔key
247
+ * binding for an agent to spoof: the signature verifies against the entry's
248
+ * recipient, or it does not verify.
249
+ */
250
+ export interface PayeeAttestation {
251
+ v: typeof PAYEE_ATT_VERSION;
252
+ mandateDigest: string;
253
+ paymentId: string;
254
+ /** The payee — the base64url Ed25519 key that is BOTH the recipient identity and the signer. */
255
+ payee: string;
256
+ asset: string;
257
+ amount: string;
258
+ at: string;
259
+ }
260
+ export interface SignedPayeeAttestation {
261
+ attestation: PayeeAttestation;
262
+ alg: 'Ed25519';
263
+ sig: string;
264
+ }
265
+ /** The payee signs "I received this payment under this mandate." Signer's key must BE the payee identity. */
266
+ export declare function attestPayment(a: PayeeAttestation, payee: Ed25519Signer): SignedPayeeAttestation;
267
+ /** Verify a payee attestation's signature against the payee identity itself, offline. */
268
+ export declare function verifyPayeeAttestation(spa: SignedPayeeAttestation): boolean;
269
+ /**
270
+ * MODEL B check: every presented entry must be backed by an authentic
271
+ * attestation signed by the RECIPIENT ITSELF (identity == key). Requires the
272
+ * mandate's accountant to be 'payees'.
273
+ *
274
+ * WHAT THIS PROVES: no fabricated entries — an agent cannot invent a payment a
275
+ * payee never acknowledged.
276
+ * WHAT IT DOES NOT PROVE: completeness. Dropping an entry AND its attestation
277
+ * passes. Do not present this check alone as omission-proof — completeness in
278
+ * Model B comes from reconcilePayeeEvidence below, run against payee evidence
279
+ * the verifier gathered independently of the agent.
280
+ */
281
+ export declare function verifySpendWithPayeeAttestations(sm: SignedMandate, entries: SpendEntry[], attestations: SignedPayeeAttestation[]): MandateVerdict;
282
+ /** The digest a payee attestation is anchored under. */
283
+ export declare function payeeAttestationAnchorDigest(spa: SignedPayeeAttestation): string;
284
+ /**
285
+ * A payee anchors ITS OWN evidence (the x402note/1 grammar; `@<paymentId>`
286
+ * keeps attestation anchors distinguishable from head anchors' `#<seq>`). This
287
+ * is what makes an omitted payment publicly discoverable: the agent controls
288
+ * its log, but it does not control the payee's anchor.
289
+ */
290
+ export declare function payeeAttestationAnchorCalldata(spa: SignedPayeeAttestation): string;
291
+ /**
292
+ * MODEL B OMISSION-RESISTANCE — the payee-evidence reconciler. `evidence` is
293
+ * the set of payee attestations the VERIFIER gathered INDEPENDENTLY (from the
294
+ * payees, or by scanning their anchors) — never from the agent. Then:
295
+ *
296
+ * 1. the presented entries must all be payee-backed (no fabrication), AND
297
+ * 2. every valid attestation for THIS mandate must appear in the log — an
298
+ * attested payment with no entry is the OMISSION, caught by the party who
299
+ * cannot un-know it was paid, AND
300
+ * 3. the attested floor (sum over all attested payments, whether logged or
301
+ * not) must be within cap — a short log cannot hide over-spend the payees
302
+ * can prove.
303
+ *
304
+ * Hostile-input hygiene: attestations that fail signature verification or
305
+ * belong to other mandates are IGNORED with a warning (a stranger cannot DoS a
306
+ * verdict with junk); two authentic attestations from one payee for one
307
+ * paymentId with different facts = payee equivocation, refused loudly.
308
+ */
309
+ export declare function reconcilePayeeEvidence(sm: SignedMandate, entries: SpendEntry[], evidence: SignedPayeeAttestation[]): MandateVerdict;
310
+ /** The parent's subject carves a narrowed child grant. Refuses any widening. */
311
+ export declare function issueDelegatedMandate(child: Mandate, parentSm: SignedMandate, delegator: Ed25519Signer): SignedMandate;
312
+ /**
313
+ * Walk a delegation chain root→leaf, entirely offline: every link signed,
314
+ * every hop narrowing, the leaf usable exactly like any mandate. Returns the
315
+ * ROOT ISSUER — the human origin, recoverable at any depth.
316
+ */
317
+ export declare function verifyDelegationChain(chain: SignedMandate[]): MandateVerdict & {
318
+ rootIssuer?: string;
319
+ };
320
+ export declare const BINDING_VERSION = "x402-mandate-binding/1";
321
+ /** The bytes32 nonce an EIP-3009 TransferWithAuthorization MUST carry for this (mandate, payment). */
322
+ export declare function eip3009BindingNonce(mandateDigestStr: string, paymentId: string): string;
323
+ /** The uint256 nonce (decimal string) a Permit2 PermitTransferFrom MUST carry. */
324
+ export declare function permit2BindingNonce(mandateDigestStr: string, paymentId: string): string;
325
+ /** The InvoiceID (uppercase 64-hex, XRPL convention) a Payment tx MUST carry. */
326
+ export declare function xrplBindingInvoiceId(mandateDigestStr: string, paymentId: string): string;
327
+ export type BindingScheme = 'eip3009' | 'permit2' | 'xrpl';
328
+ /**
329
+ * Verify the binding FROM THE SETTLED ARTIFACT: pass the value read out of the
330
+ * settled authorization/tx (the EIP-3009 nonce, the Permit2 nonce, the XRPL
331
+ * InvoiceID) and the claimed (mandate, paymentId). True iff the slot commits to
332
+ * exactly this pair. Total — false on anything malformed.
333
+ */
334
+ export declare function verifyPaymentBinding(scheme: BindingScheme, settledValue: string, mandateDigestStr: string, paymentId: string): boolean;
335
+ /** The fields a counterparty MUST decode OUT of the settled artifact (never presented). */
336
+ export interface SettledTransfer {
337
+ scheme: BindingScheme;
338
+ /** The binding slot: EIP-3009 nonce / Permit2 nonce / XRPL InvoiceID, read from the settled tx. */
339
+ slot: string;
340
+ /** from / Account. */
341
+ payer: string;
342
+ /** to / Destination. */
343
+ recipient: string;
344
+ /** token contract / XRPL currency. */
345
+ asset: string;
346
+ /** value / delivered_amount, integer minor units. */
347
+ amount: string;
348
+ /**
349
+ * ADDITIONAL legs decoded from the SAME settled artifact (a multi-payee
350
+ * split: x402 `extra.splits`, one on-chain transfer per leg). A verifier
351
+ * that decodes only the primary transfer of a split settlement under-counts
352
+ * the outflow — decode EVERY transfer the artifact performed, or the cap
353
+ * binds nothing. Absent = single-transfer settlement.
354
+ */
355
+ splits?: PaymentSplit[];
356
+ }
357
+ /**
358
+ * THE ENFORCEMENT the §7 binding alone cannot give: the binding slot commits
359
+ * only to (mandate, paymentId), NOT to amount/recipient/asset. A cap that binds
360
+ * only self-asserted amounts binds nothing on a rail the agent controls. This
361
+ * check reads the ACTUAL transferred fields out of the settled artifact and
362
+ * runs the full §6 authority check on THEM — so an agent that settles 1,000,000
363
+ * cannot log amount='1'. A counterparty deriving cumulative-spend conclusions
364
+ * MUST call this, not verifyPaymentBinding alone. Total — never throws.
365
+ */
366
+ export declare function verifySettledPayment(sm: SignedMandate, settled: SettledTransfer, paymentId: string, opts?: {
367
+ now?: () => number;
368
+ }): MandateVerdict;
369
+ export interface ParsedHeadAnchor {
370
+ anchorDigest: string;
371
+ mandateDigest: string;
372
+ seq: number;
373
+ /** Absent on pre-hardening anchors (the historic 2026-08-19 anchor has no by=). */
374
+ by?: string;
375
+ }
376
+ /**
377
+ * Parse an on-chain head-anchor calldata. Tolerates the historic pre-`by=`
378
+ * grammar so scanners can read every anchor ever made. Returns null on
379
+ * anything that is not a head anchor (payee anchors use `@`, not `#`).
380
+ */
381
+ export declare function parseCommitmentAnchorCalldata(calldata: string): ParsedHeadAnchor | null;
382
+ /**
383
+ * From a batch of decoded anchor calldatas (a scanner's haul), the highest
384
+ * anchored seq for a mandate — the FIRST-CONTACT FRESHNESS FLOOR to pass as
385
+ * lastSeq. When the mandate names a single-key accountant, anchors not
386
+ * carrying that `by=` are ignored (permissionless anchoring means strangers
387
+ * can anchor anything; only the accountant's own anchors set the floor).
388
+ * Returns null when no qualifying anchor exists — which a verifier must treat
389
+ * as "no floor", not "seq 0".
390
+ */
391
+ /** An anchor read off-chain, paired with the head its digest points at. */
392
+ export interface AnchorEvidence {
393
+ /** The `x402note/1` calldata as read from the chain. */
394
+ calldata: string;
395
+ /**
396
+ * The head retrieved out-of-band for this anchor's digest. Absent when the
397
+ * content could not be fetched — such an anchor is NOT floor-eligible.
398
+ */
399
+ head?: SignedCommitment;
400
+ }
401
+ /**
402
+ * RUNG 3, done properly: derive a freshness floor ONLY from anchors whose
403
+ * content has been retrieved and re-verified.
404
+ *
405
+ * WHY THIS EXISTS: anchoring is permissionless and `by=` is unauthenticated
406
+ * plaintext, while the accountant's key is public (it is named in the grant).
407
+ * So `highestAnchoredSeq` — which trusts the seq printed in calldata — is
408
+ * POISONABLE: a stranger anchors `…#999999999;by=<the real accountant>` and
409
+ * every honest head afterwards is refused as a rollback. That failure is not a
410
+ * missed omission, it is an honest record permanently refused.
411
+ *
412
+ * Here an anchored seq is a POINTER, never a fact. For an anchor to move the
413
+ * floor, all of the following must hold: the calldata parses and names THIS
414
+ * mandate; `by=` equals the mandate's accountant; the head was retrieved; the
415
+ * anchor digest recomputes over that head; the head's signature verifies; and
416
+ * the head itself names this mandate, this accountant, and this seq. Anything
417
+ * short of that is ignored with a warning — which can only LOWER the floor
418
+ * toward the tamper-evidence downgrade, never raise it.
419
+ */
420
+ export declare function verifiedAnchoredSeq(sm: SignedMandate, anchors: AnchorEvidence[]): {
421
+ seq: number | null;
422
+ reasons: string[];
423
+ warnings: string[];
424
+ };
425
+ /**
426
+ * ⚠️ UNVERIFIED floor: trusts the seq printed in permissionless calldata and is
427
+ * therefore POISONABLE by any chain writer (see verifiedAnchoredSeq). Retained
428
+ * for scanning/equivocation surveys where a claimed seq is a lead to follow,
429
+ * NOT for deriving the floor a verifier will refuse honest heads against.
430
+ */
431
+ export declare function highestAnchoredSeq(calldatas: string[], mandateDigestStr: string, accountant?: string): number | null;
432
+ /**
433
+ * The accountant-side check the delegation section's honest limit calls for:
434
+ * given a parent grant and the set of children issued under it, every child
435
+ * must be an authentic, correctly-narrowing child of THIS parent, digests
436
+ * distinct, and the SUM of child caps must fit within the parent cap.
437
+ *
438
+ * HONESTY: this binds over the set it is GIVEN. Only the party that registers
439
+ * delegations (the accountant, or the delegator's own ledger) knows the set is
440
+ * complete — a verifier handed a partial set gets a partial answer. That is
441
+ * the same completeness shape as spend, and the same parties close it.
442
+ */
443
+ export declare function verifySiblingBudget(parentSm: SignedMandate, children: SignedMandate[]): MandateVerdict;
444
+ /** Authorize one payment against the LEAF of a verified delegation chain. */
445
+ export declare function checkDelegatedPayment(chain: SignedMandate[], payment: MandatePayment, opts?: {
446
+ now?: () => number;
447
+ }): MandateVerdict & {
448
+ rootIssuer?: string;
449
+ };