@callcium/sdk 0.11.1 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,3 +1,295 @@
1
+ //#region src/constants.d.ts
2
+ /**
3
+ * Extract a `{ KEY: code }` map from a table with `key` and `code` fields.
4
+ * @internal
5
+ */
6
+ type CodeMap<T extends readonly {
7
+ readonly key: string;
8
+ readonly code: number;
9
+ }[]> = { readonly [E in T[number] as E["key"]]: E["code"]; };
10
+ /** ABI type code ranges and sentinel values for the descriptor format. */
11
+ export declare const TypeCode: {
12
+ readonly UINT_MIN: 1;
13
+ readonly UINT_MAX: 32;
14
+ readonly INT_MIN: 33;
15
+ readonly INT_MAX: 64;
16
+ readonly ADDRESS: 65;
17
+ readonly BOOL: 66;
18
+ readonly FUNCTION: 67;
19
+ readonly FIXED_BYTES_MIN: 80;
20
+ readonly FIXED_BYTES_MAX: 111;
21
+ readonly BYTES: 112;
22
+ readonly STRING: 113;
23
+ readonly STATIC_ARRAY: 128;
24
+ readonly DYNAMIC_ARRAY: 129;
25
+ readonly TUPLE: 144;
26
+ };
27
+ /** Well-known context property IDs for context-scope rules. */
28
+ export declare const ContextProperty: CodeMap<readonly [{
29
+ readonly key: "MSG_SENDER";
30
+ readonly code: 0;
31
+ readonly label: "msg.sender";
32
+ readonly contextKey: "msgSender";
33
+ readonly typeCode: 65;
34
+ }, {
35
+ readonly key: "MSG_VALUE";
36
+ readonly code: 1;
37
+ readonly label: "msg.value";
38
+ readonly contextKey: "msgValue";
39
+ readonly typeCode: 32;
40
+ }, {
41
+ readonly key: "BLOCK_TIMESTAMP";
42
+ readonly code: 2;
43
+ readonly label: "block.timestamp";
44
+ readonly contextKey: "blockTimestamp";
45
+ readonly typeCode: 32;
46
+ }, {
47
+ readonly key: "BLOCK_NUMBER";
48
+ readonly code: 3;
49
+ readonly label: "block.number";
50
+ readonly contextKey: "blockNumber";
51
+ readonly typeCode: 32;
52
+ }, {
53
+ readonly key: "CHAIN_ID";
54
+ readonly code: 4;
55
+ readonly label: "block.chainid";
56
+ readonly contextKey: "chainId";
57
+ readonly typeCode: 32;
58
+ }, {
59
+ readonly key: "TX_ORIGIN";
60
+ readonly code: 5;
61
+ readonly label: "tx.origin";
62
+ readonly contextKey: "txOrigin";
63
+ readonly typeCode: 65;
64
+ }, {
65
+ readonly key: "BASE_FEE";
66
+ readonly code: 6;
67
+ readonly label: "block.basefee";
68
+ readonly contextKey: "baseFee";
69
+ readonly typeCode: 32;
70
+ }, {
71
+ readonly key: "GAS_PRICE";
72
+ readonly code: 7;
73
+ readonly label: "tx.gasprice";
74
+ readonly contextKey: "gasPrice";
75
+ readonly typeCode: 32;
76
+ }]>;
77
+ /** Display metadata for a context property code. */
78
+ type ContextPropertyInfo = {
79
+ label: string;
80
+ contextKey: keyof Context;
81
+ typeCode: number;
82
+ };
83
+ /**
84
+ * Map a context property code to its display label and ABI type code.
85
+ * @param code - Context property ID.
86
+ * @returns Display metadata including the ABI type code for the property value.
87
+ * @throws {CallciumError} If the code is not a recognised context property.
88
+ */
89
+ export declare function lookupContextProperty(code: number): ContextPropertyInfo;
90
+ declare const SCOPE_TABLE: readonly [{
91
+ readonly key: "CONTEXT";
92
+ readonly code: 0;
93
+ readonly label: "context";
94
+ }, {
95
+ readonly key: "CALLDATA";
96
+ readonly code: 1;
97
+ readonly label: "calldata";
98
+ }, {
99
+ readonly key: "LOOP";
100
+ readonly code: 2;
101
+ readonly label: "loop";
102
+ }];
103
+ /** Rule scope discriminant: context (EVM environment), calldata (ABI payload) or loop (array elements). */
104
+ export declare const Scope: CodeMap<readonly [{
105
+ readonly key: "CONTEXT";
106
+ readonly code: 0;
107
+ readonly label: "context";
108
+ }, {
109
+ readonly key: "CALLDATA";
110
+ readonly code: 1;
111
+ readonly label: "calldata";
112
+ }, {
113
+ readonly key: "LOOP";
114
+ readonly code: 2;
115
+ readonly label: "loop";
116
+ }]>;
117
+ /** A defined scope code. */
118
+ type ScopeCode = (typeof SCOPE_TABLE)[number]["code"];
119
+ /** Display metadata for a scope code. */
120
+ type ScopeInfo = {
121
+ label: string;
122
+ };
123
+ /**
124
+ * Map a scope code to its display label.
125
+ * @param code - Scope byte value.
126
+ * @returns Display metadata for the scope.
127
+ * @throws {CallciumError} If the code is not a recognised scope.
128
+ */
129
+ export declare function lookupScope(code: number): ScopeInfo;
130
+ declare const QUANTIFIER_TABLE: readonly [{
131
+ readonly key: "ALL";
132
+ readonly code: 1;
133
+ readonly label: "all";
134
+ }, {
135
+ readonly key: "ANY";
136
+ readonly code: 2;
137
+ readonly label: "any";
138
+ }];
139
+ /** Loop quantifier: the body holds for every element (`ALL`) or for some element (`ANY`). */
140
+ export declare const LoopQuantifier: CodeMap<readonly [{
141
+ readonly key: "ALL";
142
+ readonly code: 1;
143
+ readonly label: "all";
144
+ }, {
145
+ readonly key: "ANY";
146
+ readonly code: 2;
147
+ readonly label: "any";
148
+ }]>;
149
+ /** A defined loop quantifier code. */
150
+ type QuantifierCode = (typeof QUANTIFIER_TABLE)[number]["code"];
151
+ /** Display metadata for a loop quantifier code. */
152
+ type QuantifierInfo = {
153
+ label: string;
154
+ };
155
+ /**
156
+ * Map a loop quantifier code to its display label.
157
+ * @param code - Quantifier byte value.
158
+ * @returns Display metadata for the quantifier.
159
+ * @throws {CallciumError} If the code is not a recognised quantifier.
160
+ */
161
+ export declare function lookupQuantifier(code: number): QuantifierInfo;
162
+ /** Operand count category of an operator. */
163
+ type Operands = "single" | "range" | "variadic";
164
+ /** @internal */
165
+ declare const OP_TABLE: readonly [{
166
+ readonly key: "EQ";
167
+ readonly code: 1;
168
+ readonly label: "==";
169
+ readonly operands: "single";
170
+ }, {
171
+ readonly key: "GT";
172
+ readonly code: 2;
173
+ readonly label: ">";
174
+ readonly operands: "single";
175
+ }, {
176
+ readonly key: "LT";
177
+ readonly code: 3;
178
+ readonly label: "<";
179
+ readonly operands: "single";
180
+ }, {
181
+ readonly key: "GTE";
182
+ readonly code: 4;
183
+ readonly label: ">=";
184
+ readonly operands: "single";
185
+ }, {
186
+ readonly key: "LTE";
187
+ readonly code: 5;
188
+ readonly label: "<=";
189
+ readonly operands: "single";
190
+ }, {
191
+ readonly key: "BETWEEN";
192
+ readonly code: 6;
193
+ readonly label: "between";
194
+ readonly operands: "range";
195
+ }, {
196
+ readonly key: "IN";
197
+ readonly code: 7;
198
+ readonly label: "in";
199
+ readonly operands: "variadic";
200
+ }, {
201
+ readonly key: "BITMASK_ALL";
202
+ readonly code: 16;
203
+ readonly label: "bitmask all";
204
+ readonly operands: "single";
205
+ }, {
206
+ readonly key: "BITMASK_ANY";
207
+ readonly code: 17;
208
+ readonly label: "bitmask any";
209
+ readonly operands: "single";
210
+ }, {
211
+ readonly key: "BITMASK_NONE";
212
+ readonly code: 18;
213
+ readonly label: "bitmask none";
214
+ readonly operands: "single";
215
+ }, {
216
+ readonly key: "LENGTH_EQ";
217
+ readonly code: 24;
218
+ readonly label: "length ==";
219
+ readonly operands: "single";
220
+ }, {
221
+ readonly key: "LENGTH_GT";
222
+ readonly code: 25;
223
+ readonly label: "length >";
224
+ readonly operands: "single";
225
+ }, {
226
+ readonly key: "LENGTH_LT";
227
+ readonly code: 26;
228
+ readonly label: "length <";
229
+ readonly operands: "single";
230
+ }, {
231
+ readonly key: "LENGTH_GTE";
232
+ readonly code: 27;
233
+ readonly label: "length >=";
234
+ readonly operands: "single";
235
+ }, {
236
+ readonly key: "LENGTH_LTE";
237
+ readonly code: 28;
238
+ readonly label: "length <=";
239
+ readonly operands: "single";
240
+ }, {
241
+ readonly key: "LENGTH_BETWEEN";
242
+ readonly code: 29;
243
+ readonly label: "length between";
244
+ readonly operands: "range";
245
+ }];
246
+ /** Callcium policy operator codes, with the NOT flag and the operand source fields. */
247
+ export declare const Op: {
248
+ readonly NOT: 128;
249
+ readonly SOURCE_SHIFT: 5;
250
+ readonly COMPARISON_MASK: 31;
251
+ readonly BETWEEN: 6;
252
+ readonly BITMASK_ALL: 16;
253
+ readonly BITMASK_ANY: 17;
254
+ readonly BITMASK_NONE: 18;
255
+ readonly EQ: 1;
256
+ readonly GT: 2;
257
+ readonly GTE: 4;
258
+ readonly IN: 7;
259
+ readonly LENGTH_BETWEEN: 29;
260
+ readonly LENGTH_EQ: 24;
261
+ readonly LENGTH_GT: 25;
262
+ readonly LENGTH_GTE: 27;
263
+ readonly LENGTH_LT: 26;
264
+ readonly LENGTH_LTE: 28;
265
+ readonly LT: 3;
266
+ readonly LTE: 5;
267
+ };
268
+ /** A defined comparison code. */
269
+ type ComparisonCode = (typeof OP_TABLE)[number]["code"];
270
+ /** Operand source: constant values, or a context property. */
271
+ export declare const Source: CodeMap<readonly [{
272
+ readonly key: "CONSTANT";
273
+ readonly code: 0;
274
+ readonly labelSuffix: "";
275
+ }, {
276
+ readonly key: "CONTEXT";
277
+ readonly code: 1;
278
+ readonly labelSuffix: " ctx";
279
+ }]>;
280
+ /** Display metadata for an operator code. */
281
+ type OpInfo = {
282
+ label: string;
283
+ operands: Operands;
284
+ };
285
+ /**
286
+ * Map an operator code to its display label. Strips the NOT flag automatically. A context source adds ` ctx`.
287
+ * @param code - Operator byte value (can include the NOT flag).
288
+ * @returns Display metadata for the base operator.
289
+ * @throws {CallciumError} If the base code is not a recognised operator.
290
+ */
291
+ export declare function lookupOp(code: number): OpInfo;
292
+ //#endregion
1
293
  //#region src/types.d.ts
2
294
  /** Hex-encoded byte string, 0x-prefixed. */
3
295
  type Hex = `0x${string}`;
@@ -8,10 +300,14 @@ type Span = {
8
300
  start: number;
9
301
  end: number;
10
302
  };
303
+ /** A decoded value with its byte position in the source blob. */
304
+ type Field<T> = {
305
+ value: T;
306
+ span: Span;
307
+ };
11
308
  /**
12
- * Execution context for context-scoped rules.
13
- * Each property maps to a well-known EVM execution environment value.
14
- * Only the properties referenced by the policy need to be supplied.
309
+ * Execution context for context-scoped rules. Each property maps to a well-known EVM execution environment value. Only
310
+ * the properties referenced by the policy need to be supplied.
15
311
  */
16
312
  type Context = {
17
313
  msgSender?: Address;
@@ -39,51 +335,60 @@ type MissingSelectorViolation = {
39
335
  };
40
336
  /** Calldata selector does not match the policy's expected selector. */
41
337
  type SelectorMismatchViolation = {
42
- code: "SELECTOR_MISMATCH"; /** Selector declared by the policy. */
43
- expectedValue: Hex; /** Selector observed in the calldata. */
338
+ code: "SELECTOR_MISMATCH";
339
+ /** Selector declared by the policy. */
340
+ expectedValue: Hex;
341
+ /** Selector observed in the calldata. */
44
342
  resolvedValue: Hex;
45
343
  };
46
344
  /**
47
- * A rule referenced a context property not supplied in the execution context — a context-scoped
48
- * subject, or an `EQ_CTX` operand on either scope.
345
+ * A test read a context property not supplied in the execution context — a context test's subject, or a context
346
+ * operand on either kind of test.
347
+ *
348
+ * `group` and `rule` locate the root rule. A test in a loop body adds `bodyRule` and `elementIndex`.
49
349
  */
50
350
  type MissingContextViolation = {
51
351
  code: "MISSING_CONTEXT";
52
352
  group: number;
53
353
  rule: number;
54
- scope: number;
55
- path: Hex; /** Declared type of the missing context property. */
56
- typeCode: number; /** Operator code with the `Op.NOT` bit intact; absent for a context-scoped subject. */
57
- opCode?: number; /** Operator payload; absent for a context-scoped subject. */
58
- operandData?: Hex;
354
+ scope: ScopeCode;
355
+ /** The test's path: a context test's property ID, or a calldata test's steps (in a loop body, from the element). */
356
+ path: Hex;
357
+ /** Declared type of the missing context property. */
358
+ typeCode: number;
359
+ /** The test's operator, absent for a context test's subject. */
360
+ operator?: DecodedOperator;
361
+ /** Position of the test in the loop body, absent for a root test. */
362
+ bodyRule?: number;
363
+ /** Position of the element the body test read, absent for a root test. */
364
+ elementIndex?: number;
59
365
  };
60
366
  /**
61
- * A rule's operator returned false against the loaded value.
62
- *
63
- * Field combinations:
64
- * - `resolvedValue` present, `elementIndex` absent — scalar leaf or context value that failed the operator.
65
- * - `resolvedValue` present, `elementIndex` present — universal-quantifier per-element failure.
66
- * - `resolvedValue` absent, `elementIndex` absent — existential-aggregate failure (no element satisfied).
67
- * - `resolvedValue` absent, `elementIndex` present — per-element failure where the leaf could not be loaded.
367
+ * A test's operator returned false against the loaded value.
68
368
  *
69
- * For length operations (`isLengthOp(opCode)`), `resolvedValue` is a hex-encoded count
70
- * rather than a 32-byte ABI word.
369
+ * `resolvedValue` is the value the operator compared: a word, or for length operators the length as a 32-byte word.
370
+ * `group` and `rule` locate the root rule. A test in a loop body adds `bodyRule` and `elementIndex`.
71
371
  */
72
372
  type ValueMismatchViolation = {
73
373
  code: "VALUE_MISMATCH";
74
374
  group: number;
75
375
  rule: number;
76
- scope: number;
77
- path: Hex; /** Operator code with the `Op.NOT` bit intact. */
78
- opCode: number; /** Full untruncated operand bytes declared by the rule. */
79
- operandData: Hex; /** Type code of the failing value's leaf. */
376
+ scope: ScopeCode;
377
+ /** The test's path: a context test's property ID, or a calldata test's steps (in a loop body, from the element). */
378
+ path: Hex;
379
+ /** The test's operator. */
380
+ operator: DecodedOperator;
381
+ /** Type code of the failing value. */
80
382
  typeCode: number;
81
- resolvedValue?: Hex;
383
+ resolvedValue: Hex;
82
384
  /**
83
- * Resolved runtime value of a reference operand as a 32-byte word; present when the
84
- * operator's operand names a reference resolved at enforcement, not a literal.
385
+ * Resolved runtime value of a context operand as a 32-byte word, present when the operator's operand names a context
386
+ * property, not a constant.
85
387
  */
86
388
  resolvedOperand?: Hex;
389
+ /** Position of the test in the loop body, absent for a root test. */
390
+ bodyRule?: number;
391
+ /** Position of the element the body test read, absent for a root test. */
87
392
  elementIndex?: number;
88
393
  };
89
394
  /**
@@ -94,29 +399,33 @@ type CalldataNavigationVariant<C extends NavigationViolationCode> = {
94
399
  code: C;
95
400
  group: number;
96
401
  rule: number;
97
- scope: number;
402
+ scope: ScopeCode;
98
403
  path: Hex;
99
- opCode?: number;
100
- operandData?: Hex;
404
+ operator?: DecodedOperator;
101
405
  typeCode?: number;
406
+ bodyRule?: number;
102
407
  elementIndex?: number;
103
408
  };
104
409
  /**
105
- * Calldata structure prevented the rule from being evaluated.
410
+ * Calldata structure prevented a rule from being evaluated.
106
411
  *
107
- * The operator was never applied; `opCode`, `operandData`, `typeCode`, and `elementIndex`
108
- * are diagnostic context describing the failing site, not a constraint claim.
412
+ * The operator was never applied. `operator`, `typeCode`, `bodyRule` and `elementIndex` are diagnostic context
413
+ * describing the failing site, not a constraint claim. A failure resolving a loop's array carries the loop
414
+ * rule's scope and array path and no operator. A failure resolving an element adds `elementIndex`. A failure in a body
415
+ * test adds the test's fields and `bodyRule`.
109
416
  *
110
417
  * A union of per-code variants, narrowable with `Extract<Violation, { code: "..." }>`.
111
418
  */
112
419
  type CalldataNavigationViolation = CalldataNavigationVariant<"CALLDATA_OUT_OF_BOUNDS"> | CalldataNavigationVariant<"ARRAY_INDEX_OUT_OF_BOUNDS">;
113
- /** A quantified array exceeded `PolicyFormat.MAX_QUANTIFIED_ARRAY_LENGTH`. */
420
+ /** A loop's array exceeded `MAX_QUANTIFIED_ARRAY_LENGTH`. */
114
421
  type QuantifierLimitExceededViolation = {
115
422
  code: "QUANTIFIER_LIMIT_EXCEEDED";
116
423
  group: number;
117
424
  rule: number;
118
- scope: number;
119
- path: Hex; /** Hex-encoded element count of the offending array. */
425
+ scope: ScopeCode;
426
+ /** The loop's array path. */
427
+ path: Hex;
428
+ /** Hex-encoded element count of the offending array. */
120
429
  resolvedValue: Hex;
121
430
  };
122
431
  /**
@@ -128,117 +437,238 @@ type NonCanonicalValueViolation = {
128
437
  code: "NON_CANONICAL_VALUE";
129
438
  group: number;
130
439
  rule: number;
131
- scope: number;
132
- path: Hex; /** Type code of the target whose encoding was violated. */
133
- typeCode: number; /** Raw 32-byte word as it appeared in calldata, before any masking. */
440
+ scope: ScopeCode;
441
+ path: Hex;
442
+ /** Type code of the target whose encoding was violated. */
443
+ typeCode: number;
444
+ /** Raw 32-byte word as it appeared in calldata, before any masking. */
134
445
  resolvedValue: Hex;
135
- opCode?: number;
136
- operandData?: Hex;
446
+ /** The test's operator. */
447
+ operator: DecodedOperator;
448
+ /** Position of the test in the loop body, absent for a root test. */
449
+ bodyRule?: number;
450
+ /** Position of the element the body test read, absent for a root test. */
137
451
  elementIndex?: number;
138
452
  };
139
- /** An `ANY` quantifier was applied to an empty array. */
140
- type QuantifierEmptyArrayViolation = {
141
- code: "QUANTIFIER_EMPTY_ARRAY";
453
+ /** No element satisfied an `ANY` loop's body, the empty array included. No element and no test is to blame. */
454
+ type QuantifierNoMatchViolation = {
455
+ code: "QUANTIFIER_NO_MATCH";
142
456
  group: number;
143
457
  rule: number;
144
- scope: number;
458
+ scope: ScopeCode;
459
+ /** The loop's array path. */
145
460
  path: Hex;
146
461
  };
147
462
  /**
148
463
  * Structured details of a single rule failure during enforcement.
149
464
  *
150
- * Carries semantic data only; no message strings.
151
- * Discriminate on `code` to narrow to the matching variant.
465
+ * Carries semantic data only, with no message strings. Discriminate on `code` to narrow to the matching variant.
152
466
  */
153
- type Violation = MissingSelectorViolation | SelectorMismatchViolation | MissingContextViolation | ValueMismatchViolation | CalldataNavigationViolation | NonCanonicalValueViolation | QuantifierLimitExceededViolation | QuantifierEmptyArrayViolation;
467
+ type Violation = MissingSelectorViolation | SelectorMismatchViolation | MissingContextViolation | ValueMismatchViolation | CalldataNavigationViolation | NonCanonicalValueViolation | QuantifierLimitExceededViolation | QuantifierNoMatchViolation;
154
468
  /** Machine-readable reason code for an enforcement violation. Derived from `Violation` to prevent drift. */
155
469
  type ViolationCode = Violation["code"];
156
- /** Canonical structured representation of a policy. */
470
+ /** A test or a context test of a loop body, or of a group. */
471
+ type BodyRule = {
472
+ scope: typeof Scope.CONTEXT | typeof Scope.CALLDATA;
473
+ /** BE16-encoded path from the starting point. A context test's path is its property ID. */
474
+ path: Hex;
475
+ /** The hint a blob carries for the path, absent for a context test and in data not read from a blob. */
476
+ hint?: Hex;
477
+ /** Encoded operator: opCode(1) || each operand value as a 32-byte word, a context property as its ID. */
478
+ operator: Hex;
479
+ };
480
+ /** A loop: its body over each element of the array at `path`. */
481
+ type LoopRule = {
482
+ scope: typeof Scope.LOOP;
483
+ quantifier: QuantifierCode;
484
+ /** BE16-encoded path from the arguments to the array. */
485
+ path: Hex;
486
+ /** The frame hint a blob carries for the path, absent in data not read from a blob. */
487
+ hint?: Hex;
488
+ body: BodyRule[];
489
+ };
490
+ /** A rule of a group: a test, a context test or a loop. */
491
+ type Rule = BodyRule | LoopRule;
492
+ /** A policy: its selector, its descriptor and its groups of rules. */
157
493
  type PolicyData = {
158
494
  isSelectorless: boolean;
159
495
  selector: Hex;
160
496
  descriptor: Hex;
161
- groups: Constraint[][];
162
- span?: Span;
497
+ groups: Rule[][];
163
498
  };
499
+ /**
500
+ * An operator as a policy stores it: its comparison, its polarity and its operands. Constants are loaded to 32-byte
501
+ * words of `operandType`. A context operand names its property.
502
+ */
503
+ type DecodedOperator = {
504
+ /** Operator code with the `Op.NOT` bit intact. */
505
+ opCode: number;
506
+ /** Comparison bits of `opCode`. */
507
+ comparison: ComparisonCode;
508
+ /** True when `opCode` carries the `Op.NOT` bit. */
509
+ negated: boolean;
510
+ /**
511
+ * Type code of the operands: the target's type, the type a length compares as for a length comparison,
512
+ * or the context property's type.
513
+ */
514
+ operandType: number;
515
+ } & ({
516
+ source: typeof Source.CONSTANT;
517
+ /** Each constant loaded to its 32-byte word. */
518
+ values: Hex[];
519
+ } | {
520
+ source: typeof Source.CONTEXT;
521
+ /** The context property the operand names. */
522
+ contextPropertyId: number;
523
+ });
164
524
  /** A collection of operators targeting a specific value. */
165
525
  type Constraint = {
166
- scope: number;
526
+ scope: typeof Scope.CONTEXT | typeof Scope.CALLDATA;
167
527
  path: Hex;
168
- operators: Hex[]; /** Compiled hint block as carried on the wire; absent when the constraint has no encoding. */
169
- hint?: Hex;
170
- span?: Span;
528
+ operators: Hex[];
171
529
  };
172
- /** A decoded value with its byte position in the source blob. */
173
- type Field<T> = {
174
- value: T;
175
- span: Span;
176
- };
177
- /** Structural representation of a decoded parameter within the descriptor. */
178
- type DecodedParam = {
179
- index: number;
530
+ /** A descriptor node: its type, its head size and the bytes it spans, with its fields or its element. */
531
+ type DecodedNode = {
180
532
  typeCode: number;
181
533
  isDynamic: boolean;
534
+ /** Head size in bytes, zero for a dynamic type. */
182
535
  staticSize: number;
183
- path: Hex;
536
+ span: Span;
537
+ } & ({
538
+ typeClass: "elementary";
539
+ } | {
540
+ typeClass: "tuple";
541
+ fields: DecodedNode[];
542
+ } | {
543
+ typeClass: "staticArray";
544
+ length: number;
545
+ element: DecodedNode;
546
+ } | {
547
+ typeClass: "dynamicArray";
548
+ element: DecodedNode;
549
+ });
550
+ /** A descriptor: its header fields and one node per parameter. */
551
+ type DecodedDescriptor = {
552
+ version: Field<number>;
553
+ paramCount: Field<number>;
554
+ params: DecodedNode[];
555
+ span: Span;
556
+ };
557
+ /** An array's meta word. */
558
+ type ArrayMeta = {
559
+ /** The element type is dynamic. An offset word points to each element. */
560
+ isElementDynamic: boolean;
561
+ /** The array is dynamic. A length word is before the elements. */
562
+ isDynamicArray: boolean;
563
+ /** Element head size in words. */
564
+ strideWords: number;
565
+ };
566
+ /** A hop of a compiled hint: a plain hop enters the node behind an offset word, an element hop selects an element. */
567
+ type DecodedHop = {
568
+ kind: "plain" | "element";
569
+ delta: Field<number>;
570
+ index: Field<number>;
571
+ meta: Field<ArrayMeta>;
572
+ span: Span;
573
+ };
574
+ /** A test hint: its hops, then the target's position, meta word and type code. */
575
+ type DecodedHint = {
576
+ hopCount: Field<number>;
577
+ hops: DecodedHop[];
578
+ targetDelta: Field<number>;
579
+ /** The target's meta word. Every field is false or zero unless the target is a dynamic array. */
580
+ targetMeta: Field<ArrayMeta>;
581
+ typeCode: Field<number>;
582
+ span: Span;
583
+ };
584
+ /** A frame hint: its hops, then the array's position, declared length and meta word. */
585
+ type DecodedFrameHint = {
586
+ hopCount: Field<number>;
587
+ hops: DecodedHop[];
588
+ arrayDelta: Field<number>;
589
+ /** Declared length of a static array, or zero for a dynamic array. */
590
+ count: Field<number>;
591
+ meta: Field<ArrayMeta>;
184
592
  span: Span;
185
593
  };
186
- /** Structural representation of a decoded rule with per-field spans. */
187
- type DecodedRule = {
594
+ /** A test or a context test, each field with the bytes that contain it. */
595
+ type DecodedTest = {
188
596
  ruleSize: Field<number>;
189
- scope: Field<number>;
597
+ scope: Field<typeof Scope.CONTEXT | typeof Scope.CALLDATA>;
190
598
  pathDepth: Field<number>;
191
- path: Field<Hex>; /** Compiled hint block; present for calldata rules only. */
192
- hint?: Field<Hex>;
599
+ /** The path steps, or a context test's property ID. */
600
+ path: Field<Hex>;
601
+ /** The test hint, absent for a context test. */
602
+ hint?: DecodedHint;
603
+ /** Type code of the target: the hint's, or the context property's. */
604
+ targetType: number;
193
605
  opCode: Field<number>;
194
606
  dataLength: Field<number>;
607
+ /** The operands as stored. */
195
608
  data: Field<Hex>;
609
+ operator: DecodedOperator;
610
+ span: Span;
611
+ };
612
+ /** A loop rule, each field with the bytes that contain it. */
613
+ type DecodedLoop = {
614
+ ruleSize: Field<number>;
615
+ scope: Field<typeof Scope.LOOP>;
616
+ quantifier: Field<QuantifierCode>;
617
+ pathDepth: Field<number>;
618
+ /** The array's path. */
619
+ path: Field<Hex>;
620
+ hint: DecodedFrameHint;
621
+ ruleCount: Field<number>;
622
+ body: DecodedTest[];
196
623
  span: Span;
197
624
  };
198
- /** Structural representation of a decoded group with metadata spans. */
625
+ /** A rule of a group: a test, a context test or a loop. */
626
+ type DecodedRule = DecodedTest | DecodedLoop;
627
+ /** A group, each field with the bytes that contain it. */
199
628
  type DecodedGroup = {
200
629
  ruleCount: Field<number>;
201
630
  groupSize: Field<number>;
202
631
  rules: DecodedRule[];
203
632
  span: Span;
204
633
  };
205
- /** Structural representation of a decoded policy with full byte-level spans. */
634
+ /** A policy blob, each field with the bytes that contain it. */
206
635
  type DecodedPolicy = {
207
- header: Field<number>;
636
+ header: Field<{
637
+ major: number;
638
+ minor: number;
639
+ isSelectorless: boolean;
640
+ }>;
641
+ /** The selector slot, zero for a selectorless policy. */
208
642
  selector: Field<Hex>;
209
643
  descLength: Field<number>;
210
- descriptor: {
211
- raw: Hex;
212
- header: Field<{
213
- version: number;
214
- paramCount: number;
215
- }>;
216
- params: DecodedParam[];
217
- span: Span;
218
- };
644
+ descriptor: DecodedDescriptor;
219
645
  groupCount: Field<number>;
220
646
  groups: DecodedGroup[];
221
647
  span: Span;
222
- version: number;
223
- isSelectorless: boolean;
224
648
  };
225
649
  /** Severity of a validation issue. */
226
650
  type IssueSeverity = "info" | "warning" | "error";
227
- /** Category of a validation issue. */
651
+ /** Kind of defect a validation issue reports. */
228
652
  type IssueCategory = "typeMismatch" | "contradiction" | "redundancy" | "vacuity" | "compatibility";
653
+ /** Machine-readable code of a validation issue. */
654
+ type IssueCode = "INVALID_DESCRIPTOR" | "UNNAVIGABLE_PATH" | "QUANTIFIER_ON_NON_ARRAY" | "HINT_MISMATCH" | "NUMERIC_OP_ON_NON_NUMERIC" | "BITMASK_ON_INVALID" | "IN_ON_BOOL" | "CONTEXT_TYPE_MISMATCH" | "OUT_OF_PHYSICAL_BOUNDS" | "CONTRADICTORY_RULE" | "REDUNDANT_RULE" | "DOMINATED_BOUND" | "DOMINATED_LENGTH_BOUND" | "VACUOUS_RULE" | "QUANTIFIER_OVER_STATIC_LIMIT" | "CONTEXT_ONLY_BODY";
229
655
  /**
230
- * Machine-readable code for a policy validation issue.
231
- *
232
- * Each code names one finding of the semantic validator and matches the constant of the same
233
- * name in the Solidity `IssueCode` library.
656
+ * The rule an issue names: its group, its position in the group and, for a test in a loop body, its position in the
657
+ * body. The location also carries the rule's scope, path and operator as decoded.
658
+ * A path in a body starts at the element.
234
659
  */
235
- type IssueCode = "VALUE_OP_ON_DYNAMIC" | "VALUE_OP_ON_COMPOSITE" | "NUMERIC_OP_ON_NON_NUMERIC" | "BITMASK_ON_INVALID" | "IN_ON_BOOL" | "LENGTH_ON_STATIC" | "CONTEXT_TYPE_MISMATCH" | "UNKNOWN_OPERATOR" | "NON_CANONICAL_OPERAND" | "UNNAVIGABLE_PATH" | "NESTED_QUANTIFIER" | "HINT_MISMATCH" | "EQ_NEQ_CONTRADICTION" | "CONFLICTING_EQUALITY" | "OUT_OF_PHYSICAL_BOUNDS" | "IMPOSSIBLE_GT" | "IMPOSSIBLE_LT" | "BOUNDS_EXCLUDE_EQUALITY" | "IMPOSSIBLE_RANGE" | "SET_EXCLUDES_EQUALITY" | "EMPTY_SET_INTERSECTION" | "SET_FULLY_EXCLUDED" | "LENGTH_EQ_NEQ_CONTRADICTION" | "CONFLICTING_LENGTH" | "BOUNDS_EXCLUDE_LENGTH" | "IMPOSSIBLE_LENGTH_RANGE" | "OUT_OF_PHYSICAL_LENGTH_BOUNDS" | "IMPOSSIBLE_LENGTH_GT" | "IMPOSSIBLE_LENGTH_LT" | "BITMASK_CONTRADICTION" | "BITMASK_ANY_IMPOSSIBLE" | "UNSORTED_IN_SET" | "EMPTY_GROUP" | "DOMINATED_BOUND" | "REDUNDANT_BOUND" | "SET_REDUCTION" | "SET_REDUNDANCY" | "SET_PARTIALLY_EXCLUDED" | "DOMINATED_LENGTH_BOUND" | "REDUNDANT_LENGTH_BOUND" | "REDUNDANT_BITMASK" | "DUPLICATE_CONSTRAINT" | "FUSIBLE_RANGE" | "FUSIBLE_LENGTH_RANGE" | "VACUOUS_GTE" | "VACUOUS_LTE" | "VACUOUS_LENGTH_GTE" | "VACUOUS_LENGTH_LTE" | "VACUOUS_NEGATED_RANGE" | "VACUOUS_NEGATED_LENGTH_RANGE" | "PATH_DEPTH_EXCEEDED" | "QUANTIFIER_OVER_STATIC_LIMIT" | "UNKNOWN_CONTEXT_PROPERTY" | "NEGATION_UNDER_ANY";
236
- /** A single validation issue found during policy analysis. */
237
- type Issue = {
660
+ type RuleLocation = {
661
+ groupIndex: number;
662
+ ruleIndex: number;
663
+ bodyRuleIndex?: number;
664
+ scope: ScopeCode;
665
+ path: Hex;
666
+ operator?: Hex;
667
+ };
668
+ /** A validation issue: the rule it names, absent for one about the descriptor, and the values that show the defect. */
669
+ type Issue = Partial<RuleLocation> & {
238
670
  severity: IssueSeverity;
239
671
  category: IssueCategory;
240
- groupIndex: number;
241
- constraintIndex: number;
242
672
  code: IssueCode;
243
673
  value1: Hex;
244
674
  value2: Hex;
@@ -246,233 +676,140 @@ type Issue = {
246
676
  };
247
677
  //#endregion
248
678
  //#region src/policy-builder.d.ts
249
- /** Fluent builder for constructing Callcium policies. */
250
- declare class PolicyBuilder {
679
+ /** Fluent API for drafting policies from constraints. */
680
+ export declare class PolicyBuilder {
251
681
  private draft;
252
682
  private constructor();
253
683
  /**
254
684
  * Create a builder from a function signature.
255
- * @param signature - ABI function signature, e.g. `"transfer(address,uint256)"`.
685
+ * @param signature - The function signature (for example "transfer(address,uint256)").
686
+ * @returns A new builder.
687
+ * @throws {CallciumError} If the signature is malformed.
256
688
  */
257
689
  static create(signature: string): PolicyBuilder;
258
690
  /**
259
- * Create a selectorless builder from a raw type string.
260
- * @param typesCsv - Comma-separated ABI type strings, e.g. `"address,uint256"`.
691
+ * Create a selectorless builder from a comma-separated type list.
692
+ * @param typesCsv - The comma-separated ABI types (for example "uint256,address").
693
+ * @returns A new builder.
694
+ * @throws {CallciumError} If a type is malformed.
261
695
  */
262
696
  static createRaw(typesCsv: string): PolicyBuilder;
263
697
  /**
264
- * Add a constraint to the current group.
265
- * @param constraint - A `Constraint` object or a `ConstraintBuilder` instance.
266
- * @throws {CallciumError} With code `OUT_OF_PHYSICAL_BOUNDS` when a numeric operand lies outside
267
- * the target type's range and encodes as a value inside it. Operands are read as written, so a
268
- * `Constraint` carrying encoded operator bytes is left to {@link validate}.
698
+ * Add a constraint to the active group. A path through `Quantifier.ALL` or `Quantifier.ANY` adds its operators to the
699
+ * body of the group's loop over that array with that quantifier.
700
+ * @param constraint - The constraint to add.
701
+ * @returns This builder.
702
+ * @throws {CallciumError} If the constraint has no operator, or its path does not reach a target in the signature.
703
+ * If a comparison does not apply to its target, or an operand is a value its target's type cannot represent.
269
704
  */
270
705
  add(constraint: Constraint): this;
271
- /** Start a new constraint group (OR branch). */
706
+ /**
707
+ * Start a new constraint group (OR semantics between groups).
708
+ * @returns This builder.
709
+ * @throws {CallciumError} If the current group is empty.
710
+ */
272
711
  or(): this;
273
712
  /**
274
- * Build the policy into an encoded binary blob with strict validation.
275
- * Throws on any issue, regardless of severity. Use {@link validate} to
276
- * inspect issues, or {@link buildUnsafe} to encode without validation.
277
- * @returns The policy as a 0x-prefixed hex string.
278
- * @throws {CallciumError} If any group is empty.
279
- * @throws {ValidationError} If validation finds any issue.
280
- * @throws {CallciumError} With code `RULE_SIZE_OVERFLOW` when a rule's encoded bytes exceed the
281
- * width of the rule size field.
713
+ * Build the policy blob and validate it.
714
+ * @returns The encoded policy.
715
+ * @throws {ValidationError} If validation reports any issue.
716
+ * @throws {CallciumError} If the encoder refuses the policy, or the blob fails storage validation.
282
717
  */
283
718
  build(): Hex;
284
719
  /**
285
- * Build the policy into an encoded binary blob without validation.
286
- * The resulting policy may be invalid. Prefer {@link build}; use this
287
- * only to knowingly bypass a reported issue.
288
- * @returns The policy as a 0x-prefixed hex string.
289
- * @throws {CallciumError} If any group is empty.
720
+ * Validate the policy the builder contains.
721
+ * @returns Every issue validation reports on the encoded policy.
722
+ * @throws {CallciumError} If the encoder refuses the policy, or the blob fails storage validation.
723
+ */
724
+ validate(): Issue[];
725
+ /**
726
+ * Build the policy blob without validation. The resulting policy can be invalid.
727
+ * @returns The encoded policy.
728
+ * @throws {CallciumError} If the encoder refuses the policy.
290
729
  */
291
730
  buildUnsafe(): Hex;
731
+ /** Append a context test per operator of `constraint`, whose path names a context property. */
732
+ private addContextTests;
292
733
  /**
293
- * Validate the policy without encoding.
294
- * @returns All validation issues found.
734
+ * Append a calldata test per operator of `constraint`. If the path of `constraint` passes a quantifier step, append a
735
+ * body test per operator to the group's loop over that array instead.
295
736
  */
296
- validate(): Issue[];
297
- /** Throw if any group is empty. */
298
- private checkGroups;
299
- /** Convert the draft to a PolicyData structure. */
737
+ private addCalldataTests;
738
+ /** The active group. */
739
+ private currentGroup;
740
+ /** The draft as the encoder takes it. */
300
741
  private toPolicyData;
301
742
  }
302
743
  //#endregion
303
744
  //#region src/policy-coder.d.ts
304
745
  /**
305
- * Encode a PolicyData structure into the canonical binary format.
306
- * @param data - The policy data to encode.
307
- * @returns The encoded policy as a 0x-prefixed hex string.
746
+ * Encode the canonical form of a policy: each group normalized, its rules and the groups sorted by their
747
+ * size-free bytes, repeats dropped.
748
+ * @param data - The policy.
749
+ * @returns The policy blob as a 0x-prefixed hex string.
750
+ * @throws {CallciumError} When a field does not have the shape the encoder reads, or a path does not compile.
751
+ * When an operator does not apply to its target, or a constant is not a value of its operand type.
752
+ * When a count or size overflows its field.
308
753
  */
309
754
  declare function encode(data: PolicyData): Hex;
310
755
  /**
311
- * Decode a binary policy blob into a PolicyData structure.
312
- * @param blob - Binary policy as 0x-prefixed hex string.
313
- * @returns The decoded policy data with constraints grouped by scope and path.
314
- * @throws {CallciumError} If the blob is structurally malformed.
756
+ * Decode a policy blob into the policy it states.
757
+ * @param blob - The policy blob.
758
+ * @returns The decoded policy, each operand loaded to its 32-byte word.
759
+ * @throws {CallciumError} When the blob fails storage validation or its descriptor fails DV-1 or DV-2.
315
760
  */
316
761
  declare function decode(blob: Hex): PolicyData;
317
762
  /**
318
- * Inspect a binary policy blob, returning the structural representation with full byte-level spans.
319
- * @param blob - Binary policy as 0x-prefixed hex string.
320
- * @returns The inspected policy with per-field spans for every structural element.
321
- * @throws {CallciumError} If the blob is structurally malformed.
763
+ * Inspect a policy blob: every field it stores with the bytes that contain it. The descriptor is a node tree, the hints
764
+ * are split into their fields and the operators are parsed.
765
+ * @param blob - The policy blob.
766
+ * @returns The inspected policy, each operand loaded to its 32-byte word.
767
+ * @throws {CallciumError} When the blob fails storage validation or its descriptor fails DV-1 or DV-2.
322
768
  */
323
769
  declare function inspect$1(blob: Hex): DecodedPolicy;
324
- /** Encode, decode, and inspect policies in the canonical binary format. */
325
- declare const PolicyCoder: {
770
+ /** Encode policies in canonical form, and decode and inspect policy blobs. */
771
+ export declare const PolicyCoder: {
326
772
  encode: typeof encode;
327
773
  decode: typeof decode;
328
774
  inspect: typeof inspect$1;
329
775
  };
330
776
  //#endregion
331
777
  //#region src/path.d.ts
332
- /** Reserved path step values that trigger quantified evaluation over array elements. */
333
- declare const Quantifier: {
778
+ /** Path steps that quantify over the array before them: `ALL` over every element, `ANY` over some element. */
779
+ export declare const Quantifier: {
334
780
  readonly ALL: 65535;
335
781
  readonly ANY: 65534;
336
782
  };
337
- /** Display metadata for a quantifier step. */
338
- type QuantifierInfo = {
339
- label: string;
340
- };
341
- /** Check whether a path step is a quantifier (ALL or ANY). */
342
- declare function isQuantifier(step: number): boolean;
343
- /**
344
- * Map a quantifier path step to its display label.
345
- * @param code - Quantifier step value.
346
- * @returns Display metadata for the quantifier.
347
- * @throws {CallciumError} If the code is not a recognised quantifier.
348
- */
349
- declare function lookupQuantifier(code: number): QuantifierInfo;
350
783
  /**
351
784
  * Parse a BE16-encoded hex path into an array of step values.
352
785
  * @param path - 0x-prefixed hex string containing BE16-encoded path steps.
353
786
  * @returns Array of numeric step values.
354
787
  */
355
- declare function parsePathSteps(path: Hex): number[];
356
- //#endregion
357
- //#region src/descriptor.d.ts
358
- /** Structural type information extracted from a descriptor node. */
359
- type TypeInfo = {
360
- typeCode: number;
361
- isDynamic: boolean;
362
- staticSize: number;
363
- };
364
- /**
365
- * Return the byte length of the node at `offset`.
366
- * @throws {CallciumError} When the descriptor holds no readable node at `offset`.
367
- */
368
- declare function nodeLength(desc: Uint8Array, offset: number): number;
369
- /**
370
- * Return the byte offset of the `fieldIndex`-th field inside a tuple node.
371
- * Starts at the first field and skips `fieldIndex` nodes using `nodeLength`.
372
- */
373
- declare function tupleFieldOffset(desc: Uint8Array, tupleOffset: number, fieldIndex: number): number;
374
- /**
375
- * Return the declared top-level parameter count.
376
- * @throws {CallciumError} When the descriptor is too short to hold a header.
377
- */
378
- declare function paramCount(desc: Uint8Array): number;
379
- /** Return byte offset of the N-th top-level param (0-indexed). */
380
- declare function paramOffset(desc: Uint8Array, index: number): number;
381
- /**
382
- * Inspect the type node at a given byte offset.
383
- * @param desc - Raw descriptor bytes.
384
- * @param offset - Byte position of the node.
385
- * @returns typeCode, isDynamic, and staticSize in bytes.
386
- * @throws {CallciumError} When the descriptor holds no readable node at `offset`.
387
- */
388
- declare function inspect(desc: Uint8Array, offset: number): TypeInfo;
389
- /**
390
- * Resolve the type at a calldata path (array of step indices).
391
- *
392
- * The first step selects a top-level param. Each subsequent step descends
393
- * into the current node: for tuples it selects a field, for arrays it
394
- * advances to the element descriptor.
395
- *
396
- * @param desc - Raw descriptor bytes.
397
- * @param steps - Path steps, length >= 1.
398
- * @returns TypeInfo for the node at the resolved path.
399
- * @throws {CallciumError} On empty steps, out-of-bounds param or array index, or descent into elementary type.
400
- */
401
- declare function typeAt(desc: Uint8Array, steps: number[]): TypeInfo;
402
- /**
403
- * Resolve the type at the path and the declared length of the static array a
404
- * quantifier step descends into (zero when the path holds no quantifier step
405
- * over a static array).
406
- * @param desc - Raw descriptor bytes.
407
- * @param steps - Path steps, length >= 1.
408
- * @returns TypeInfo at the resolved path and the quantified static array length.
409
- * @throws {CallciumError} On empty steps, out-of-bounds param or array index, or descent into elementary type.
410
- */
411
- declare function walkPath(desc: Uint8Array, steps: number[]): {
412
- typeInfo: TypeInfo;
413
- quantifiedStaticLength: number;
414
- };
415
- /**
416
- * Return tuple field count at a tuple node offset.
417
- * @param desc - Raw descriptor bytes.
418
- * @param offset - Byte position of the tuple node.
419
- */
420
- declare function tupleFieldCount(desc: Uint8Array, offset: number): number;
421
- /**
422
- * Return static array length at a static array node offset.
423
- * @param desc - Raw descriptor bytes.
424
- * @param offset - Byte position of the static array node.
425
- */
426
- declare function staticArrayLength(desc: Uint8Array, offset: number): number;
427
- /**
428
- * Return the byte offset of the array element descriptor.
429
- * @param offset - Byte position of the array node (static or dynamic).
430
- */
431
- declare function arrayElementOffset(offset: number): number;
432
- /**
433
- * Compile a calldata rule path into its wire hint block.
434
- *
435
- * @param desc - Raw descriptor bytes.
436
- * @param steps - Path steps, length >= 1.
437
- * @returns The hint block bytes.
438
- * @throws {CallciumError} When a step leaves the structure the descriptor declares, quantifies over
439
- * a non-array node, or repeats a quantifier.
440
- */
441
- declare function compileHint(desc: Uint8Array, steps: number[]): Uint8Array;
442
- /** Inspect and navigate raw descriptor bytes. */
443
- declare const Descriptor: {
444
- paramCount: typeof paramCount;
445
- paramOffset: typeof paramOffset;
446
- inspect: typeof inspect;
447
- typeAt: typeof typeAt;
448
- tupleFieldOffset: typeof tupleFieldOffset;
449
- tupleFieldCount: typeof tupleFieldCount;
450
- staticArrayLength: typeof staticArrayLength;
451
- nodeLength: typeof nodeLength;
452
- arrayElementOffset: typeof arrayElementOffset;
453
- walkPath: typeof walkPath;
454
- compileHint: typeof compileHint;
455
- };
788
+ export declare function parsePathSteps(path: Hex): number[];
456
789
  //#endregion
457
790
  //#region src/policy-validator.d.ts
458
791
  /**
459
- * True if operator `opCode` is allowed on a target with the given type info.
460
- * Tolerates the NOT flag on `opCode`.
792
+ * Determine whether the compatibility matrix admits an operator on a target type. A context operand is admitted on a
793
+ * target its comparison can pair with a context property. These targets are `uintN` under `EQ`, `GT`, `LT`, `GTE` and
794
+ * `LTE`, and `address` under `EQ`.
795
+ * @param opCode - The operator code, with or without the NOT flag.
796
+ * @param typeCode - The target's type code.
797
+ * @returns True when the operator applies to the target.
461
798
  */
462
- declare function isOpAllowed(opCode: number, typeInfo: TypeInfo): boolean;
799
+ export declare function isOpAllowed(opCode: number, typeCode: number): boolean;
463
800
  /**
464
- * Validate a policy for type mismatches, contradictions, redundancies, and vacuities.
465
- * @param data - The canonical policy data to validate.
466
- * @returns All validation issues found, ordered by group and constraint index.
467
- * @throws {CallciumError} If the descriptor is not well-formed; semantic validation is
468
- * defined only over a well-formed descriptor.
469
- * @throws {CallciumError} With code `EMPTY_PATH` when a constraint carries no path step, and
470
- * `INVALID_HEX` or `INVALID_OPERATOR_BYTES` when an operator is not a readable encoding. Analysis
471
- * is defined over canonical data, so these reject the input rather than report an issue on it.
801
+ * Validate a policy blob (PV-1 to PV-9). Storage validation runs first, since the descriptor check reads the descriptor
802
+ * before anything is decoded. Issues of PV-1 to PV-7 name a rule where the blob stores it. Issues of PV-8 and PV-9 name
803
+ * the group where the blob stores it and the rule's position in the normal form of that group. Only rules that raise no
804
+ * PV-2, PV-3, PV-5 or PV-6 issue and no PV-4 issue on a test enter the normal form. PV-8 skips a loop that lost a body
805
+ * test to such an issue.
806
+ * @param blob - A policy blob that passes storage validation.
807
+ * @returns Every issue found, or one issue alone when the descriptor is not valid.
808
+ * @throws {CallciumError} When the blob fails storage validation, or a group's normal form exceeds a format limit.
472
809
  */
473
- declare function validate(data: PolicyData): Issue[];
474
- /** Semantic validation for policies. */
475
- declare const PolicyValidator: {
810
+ declare function validate(blob: Hex): Issue[];
811
+ /** Build-time validation of policy blobs. */
812
+ export declare const PolicyValidator: {
476
813
  validate: typeof validate;
477
814
  };
478
815
  //#endregion
@@ -480,33 +817,33 @@ declare const PolicyValidator: {
480
817
  /** Accepted scalar value types for operator arguments. */
481
818
  type ScalarValue = bigint | boolean | string;
482
819
  /**
483
- * Extremes of the numeric operands a builder's value operators received, as written. Encoding folds
484
- * a negative operand onto its unsigned alias, so the sign survives nowhere else.
820
+ * Extremes of the numeric operands a builder's equality, comparison and set operators received, as written. Encoding
821
+ * folds a negative operand onto its unsigned alias, so the sign survives nowhere else.
485
822
  */
486
823
  type OperandExtremes = {
487
- /** Most negative operand written, or zero when none was negative. */leastNegative: bigint; /** Greatest operand written, or zero when none exceeded it. */
824
+ /** Most negative operand written, or zero when none was negative. */
825
+ leastNegative: bigint;
826
+ /** Greatest operand written, or zero when none exceeded it. */
488
827
  greatest: bigint;
489
828
  };
490
829
  /**
491
- * Mutable builder that accumulates operators targeting a single path.
492
- * Implements the `Constraint` interface so it can be passed directly to policy builders.
830
+ * Mutable builder that accumulates operators targeting a single path. Implements the `Constraint` interface so it can
831
+ * be passed directly to policy builders.
493
832
  */
494
833
  declare class ConstraintBuilder<Operand extends ScalarValue = ScalarValue> implements Constraint {
495
- readonly scope: number;
834
+ readonly scope: Constraint["scope"];
496
835
  readonly path: Hex;
497
836
  readonly operators: Hex[];
498
837
  /**
499
- * Extremes of the numeric operands the value operators received, as written. Only the extremes
500
- * can offend: an operand folds into a target's range from below it or from above it, and
501
- * whichever reaches furthest arrives first. Read it through {@link readOperandExtremes}.
838
+ * Extremes of the numeric operands the value operators received, as written.
502
839
  * @internal
503
840
  */
504
841
  readonly operandExtremes: OperandExtremes;
505
842
  /** @internal */
506
- constructor(scope: number, path: Hex);
843
+ constructor(scope: Constraint["scope"], path: Hex);
507
844
  /**
508
- * Push a pre-encoded operator hex string and return this for chaining.
509
- * `values` are the operands as written; the numeric ones join the record.
845
+ * Push a pre-encoded operator hex string and return this for chaining. `values` are the operands as written. The
846
+ * numeric ones join the record.
510
847
  */
511
848
  private push;
512
849
  /** Assert the value equals `value`. */
@@ -517,6 +854,14 @@ declare class ConstraintBuilder<Operand extends ScalarValue = ScalarValue> imple
517
854
  eqCtx(contextPropertyId: number): this;
518
855
  /** Assert the value does not equal the context property `contextPropertyId`. */
519
856
  neqCtx(contextPropertyId: number): this;
857
+ /** Assert the value is greater than the context property `contextPropertyId`. */
858
+ gtCtx(contextPropertyId: number): this;
859
+ /** Assert the value is less than the context property `contextPropertyId`. */
860
+ ltCtx(contextPropertyId: number): this;
861
+ /** Assert the value is greater than or equal to the context property `contextPropertyId`. */
862
+ gteCtx(contextPropertyId: number): this;
863
+ /** Assert the value is less than or equal to the context property `contextPropertyId`. */
864
+ lteCtx(contextPropertyId: number): this;
520
865
  /** Assert the value is greater than `bound`. */
521
866
  gt(bound: bigint): this;
522
867
  /** Assert the value is less than `bound`. */
@@ -531,14 +876,13 @@ declare class ConstraintBuilder<Operand extends ScalarValue = ScalarValue> imple
531
876
  */
532
877
  between(min: bigint, max: bigint): this;
533
878
  /**
534
- * Assert the value is a member of the set.
535
- * Values are sorted and deduplicated before encoding.
536
- * @throws {CallciumError} If the set is empty after deduplication.
879
+ * Assert the value is a member of the set. Values are sorted and deduplicated before encoding.
880
+ * @throws {CallciumError} If the set is empty or a value is not encodable as an operand word.
537
881
  */
538
882
  isIn(values: readonly Operand[]): this;
539
883
  /**
540
884
  * Assert the value is not a member of the set.
541
- * @throws {CallciumError} If the set is empty after deduplication.
885
+ * @throws {CallciumError} If the set is empty or a value is not encodable as an operand word.
542
886
  */
543
887
  notIn(values: readonly Operand[]): this;
544
888
  /** Assert all bits in `mask` are set. */
@@ -564,67 +908,68 @@ declare class ConstraintBuilder<Operand extends ScalarValue = ScalarValue> imple
564
908
  lengthBetween(min: bigint, max: bigint): this;
565
909
  }
566
910
  /**
567
- * Target a calldata argument by path.
568
- * Each argument is a big-endian uint16 step; multiple steps navigate into nested types.
911
+ * Target a calldata argument by path. Each argument is a big-endian uint16 step. Further steps navigate nested types.
569
912
  */
570
- declare function arg(p0: number, ...rest: number[]): ConstraintBuilder;
913
+ export declare function arg(p0: number, ...rest: number[]): ConstraintBuilder;
571
914
  /** Target the `msg.sender` context property. */
572
- declare function msgSender(): ConstraintBuilder<Address>;
915
+ export declare function msgSender(): ConstraintBuilder<Address>;
573
916
  /** Target the `msg.value` context property. */
574
- declare function msgValue(): ConstraintBuilder<bigint>;
917
+ export declare function msgValue(): ConstraintBuilder<bigint>;
575
918
  /** Target the `block.timestamp` context property. */
576
- declare function blockTimestamp(): ConstraintBuilder<bigint>;
919
+ export declare function blockTimestamp(): ConstraintBuilder<bigint>;
577
920
  /** Target the `block.number` context property. */
578
- declare function blockNumber(): ConstraintBuilder<bigint>;
921
+ export declare function blockNumber(): ConstraintBuilder<bigint>;
579
922
  /** Target the `block.chainid` context property. */
580
- declare function chainId(): ConstraintBuilder<bigint>;
923
+ export declare function chainId(): ConstraintBuilder<bigint>;
581
924
  /** Target the `tx.origin` context property. */
582
- declare function txOrigin(): ConstraintBuilder<Address>;
925
+ export declare function txOrigin(): ConstraintBuilder<Address>;
583
926
  /** Target the `block.basefee` context property. */
584
- declare function baseFee(): ConstraintBuilder<bigint>;
927
+ export declare function baseFee(): ConstraintBuilder<bigint>;
585
928
  /** Target the `tx.gasprice` context property. */
586
- declare function gasPrice(): ConstraintBuilder<bigint>;
929
+ export declare function gasPrice(): ConstraintBuilder<bigint>;
587
930
  //#endregion
588
931
  //#region src/policy-enforcer.d.ts
589
932
  /**
590
- * Check a policy against ABI-encoded call data without throwing on violations.
933
+ * Check a policy against ABI-encoded call data without throwing on violations. Requires a policy blob that passes
934
+ * storage validation. The outcome on any other blob past its header is undefined.
591
935
  * @param policy - Binary policy blob as 0x-prefixed hex string.
592
936
  * @param callData - ABI-encoded call data as 0x-prefixed hex string.
593
937
  * @param context - Optional execution context for context-scoped rules.
594
938
  * @returns Pass with matched group index, or fail with one violation per evaluated failing group.
595
- * @throws {CallciumError} If the policy blob is structurally malformed, or a context value a rule
596
- * reads is not an address or an integer a 32-byte word represents.
939
+ * @throws {CallciumError} If the policy blob is shorter than its fixed prefix or of an unsupported format version.
940
+ * If the policy or call data is not valid hex.
941
+ * If a context value is not of its property's type or does not fit a 32-byte word.
597
942
  */
598
943
  declare function check(policy: Hex, callData: Hex, context?: Context): EnforceResult;
599
944
  /**
600
- * Enforce a policy against ABI-encoded call data, throwing on violation.
945
+ * Enforce a policy against ABI-encoded call data, throwing on violation. Requires a policy blob that passes storage
946
+ * validation. The outcome on any other blob past its header is undefined.
601
947
  * @param policy - Binary policy blob as 0x-prefixed hex string.
602
948
  * @param callData - ABI-encoded call data as 0x-prefixed hex string.
603
949
  * @param context - Optional execution context for context-scoped rules.
604
950
  * @throws {PolicyViolationError} If the policy rejects the call data.
605
- * @throws {CallciumError} If the policy blob is structurally malformed, or a context value a rule
606
- * reads is not an address or an integer a 32-byte word represents.
951
+ * @throws {CallciumError} If the policy blob is shorter than its fixed prefix or of an unsupported format version.
952
+ * If the policy or call data is not valid hex.
953
+ * If a context value is not of its property's type or does not fit a 32-byte word.
607
954
  */
608
955
  declare function enforce(policy: Hex, callData: Hex, context?: Context): void;
609
956
  /** Check and enforce policies against ABI-encoded call data. */
610
- declare const PolicyEnforcer: {
957
+ export declare const PolicyEnforcer: {
611
958
  check: typeof check;
612
959
  enforce: typeof enforce;
613
960
  };
614
961
  //#endregion
615
962
  //#region src/bytes.d.ts
616
963
  /** Convert a hex string to a byte array, stripping the 0x prefix if present. */
617
- declare function hexToBytes(hex: string): Uint8Array;
964
+ export declare function hexToBytes(hex: string): Uint8Array;
618
965
  /** Convert a byte array to a 0x-prefixed lowercase hex string. */
619
- declare function bytesToHex(bytes: Uint8Array): Hex;
620
- /** Validate and brand a hex string as an address. Throws if the runtime length is not exactly 20 bytes. */
621
- declare function toAddress(hex: string): Address;
966
+ export declare function bytesToHex(bytes: Uint8Array): Hex;
622
967
  //#endregion
623
968
  //#region src/descriptor-coder.d.ts
624
969
  /**
625
970
  * Encode a comma-separated list of ABI type strings into a binary descriptor.
626
971
  *
627
- * @param typesCsv - Comma-separated ABI type strings, e.g. `"address,uint256,(bool,bytes32)[],string"`.
972
+ * @param typesCsv - Comma-separated ABI type strings, for example `"address,uint256,(bool,bytes32)[],string"`.
628
973
  * @returns Binary descriptor bytes starting with the version+paramCount header.
629
974
  * @throws {CallciumError} With code `MALFORMED_TYPE_STRING` for malformed input.
630
975
  * @throws {CallciumError} With code `UNKNOWN_TYPE` for unrecognised type names.
@@ -632,307 +977,28 @@ declare function toAddress(hex: string): Address;
632
977
  */
633
978
  declare function fromTypes(typesCsv: string): Uint8Array;
634
979
  /**
635
- * Reconstruct a comma-separated list of ABI type strings from a binary descriptor.
636
- *
637
- * Inverse of `fromTypes`: `toTypes(fromTypes(s))` returns `s` for any valid input.
638
- *
980
+ * Inspect a binary descriptor: its header fields and its parameters as a tree of nodes, each with the bytes it spans.
981
+ * @param desc - Binary descriptor bytes (with version+paramCount header).
982
+ * @returns The decoded descriptor.
983
+ * @throws {CallciumError} If the descriptor is malformed, or a composite node disagrees with its children.
984
+ */
985
+ declare function inspect(desc: Uint8Array): DecodedDescriptor;
986
+ /**
987
+ * Reconstruct a comma-separated list of ABI type strings from a binary descriptor. `fromTypes(toTypes(desc))` returns
988
+ * `desc` for every descriptor `inspect` accepts.
639
989
  * @param desc - Binary descriptor bytes (with version+paramCount header).
640
- * @returns Comma-separated ABI type strings, e.g. `"address,uint256,(bool,bytes32)[]"`.
641
- * @throws {CallciumError} If the descriptor is malformed.
990
+ * @returns Comma-separated ABI type strings, for example `"address,uint256,(bool,bytes32)[]"`.
991
+ * @throws {CallciumError} If the descriptor is malformed, or a composite node disagrees with its children.
642
992
  */
643
993
  declare function toTypes(desc: Uint8Array): string;
644
- /** Encode and decode descriptors. */
645
- declare const DescriptorCoder: {
994
+ /** Encode descriptors from type strings, inspect them and read their type strings back. */
995
+ export declare const DescriptorCoder: {
646
996
  fromTypes: typeof fromTypes;
997
+ inspect: typeof inspect;
647
998
  toTypes: typeof toTypes;
648
999
  };
649
1000
  //#endregion
650
- //#region src/constants.d.ts
651
- /** Binary layout constants and normative limits for the Callcium policy format. */
652
- declare const PolicyFormat: {
653
- readonly VERSION: 2;
654
- readonly VERSION_MASK: 15;
655
- readonly FLAG_NO_SELECTOR: 16;
656
- readonly RESERVED_MASK: 224;
657
- readonly HEADER_SIZE: 1;
658
- readonly SELECTOR_OFFSET: 1;
659
- readonly SELECTOR_SIZE: 4;
660
- readonly DESC_LENGTH_OFFSET: 5;
661
- readonly DESC_LENGTH_SIZE: 2;
662
- readonly DESC_OFFSET: 7;
663
- readonly GROUP_COUNT_SIZE: 1;
664
- readonly GROUP_RULECOUNT_SIZE: 2;
665
- readonly GROUP_SIZE_SIZE: 4;
666
- readonly GROUP_HEADER_SIZE: 6;
667
- readonly RULE_SIZE_SIZE: 2;
668
- readonly RULE_SCOPE_OFFSET: 2;
669
- readonly RULE_DEPTH_OFFSET: 3;
670
- readonly RULE_PATH_OFFSET: 4;
671
- readonly PATH_STEP_SIZE: 2;
672
- readonly PATH_STEP_MAX: number;
673
- readonly RULE_OPCODE_SIZE: 1;
674
- readonly RULE_DATALENGTH_SIZE: 2;
675
- readonly RULE_FIXED_OVERHEAD: 7;
676
- readonly RULE_MIN_SIZE: number;
677
- readonly HINT_HEADER_SIZE: 1;
678
- readonly HINT_HOP_SIZE: 8;
679
- readonly HINT_HOP_INDEX_OFFSET: 4;
680
- readonly HINT_HOP_META_OFFSET: 6;
681
- readonly HINT_FRAME_PREFIX_SIZE: 8;
682
- readonly HINT_FRAME_COUNT_OFFSET: 4;
683
- readonly HINT_FRAME_META_OFFSET: 6;
684
- readonly HINT_TARGET_SIZE: 7;
685
- readonly HINT_TARGET_META_OFFSET: 4;
686
- readonly HINT_TARGET_TYPECODE_OFFSET: 6;
687
- readonly HINT_KIND_NONE: 0;
688
- readonly HINT_KIND_ALL: 1;
689
- readonly HINT_KIND_ANY: 2;
690
- readonly HINT_KIND_MAX: 2;
691
- readonly HINT_KIND_SHIFT: 6;
692
- readonly HINT_HOP_COUNT_MASK: 63;
693
- readonly HINT_SUFFIX_RESERVED_MASK: 192;
694
- readonly HINT_NO_INDEX: 65535;
695
- readonly HINT_INDEX_RESERVED: 65534;
696
- readonly HINT_META_ELEM_DYNAMIC: 32768;
697
- readonly HINT_META_DYNAMIC_ARRAY: 16384;
698
- readonly HINT_META_RESERVED_MASK: 12288;
699
- readonly HINT_META_STRIDE_MASK: 4095;
700
- readonly MAX_PATH_DEPTH: 32;
701
- readonly MAX_QUANTIFIED_ARRAY_LENGTH: 256;
702
- readonly MAX_SET_MEMBERS: number;
703
- };
704
- /**
705
- * Extract a `{ KEY: code }` map from a table with `key` and `code` fields.
706
- * @internal
707
- */
708
- type CodeMap<T extends readonly {
709
- readonly key: string;
710
- readonly code: number;
711
- }[]> = { readonly [E in T[number] as E["key"]]: E["code"] };
712
- /**
713
- * Render a wire code as fixed-width hex.
714
- * @param code - Code value.
715
- * @param byteWidth - Byte width of the field the code occupies.
716
- * @returns The code as `0x`-prefixed hex, or its decimal form when no such field holds it.
717
- */
718
- /** Rule scope discriminant: context (EVM environment) vs. calldata (ABI payload). */
719
- declare const Scope: CodeMap<readonly [{
720
- readonly key: "CONTEXT";
721
- readonly code: 0;
722
- readonly label: "context";
723
- }, {
724
- readonly key: "CALLDATA";
725
- readonly code: 1;
726
- readonly label: "calldata";
727
- }]>;
728
- /** Display metadata for a scope code. */
729
- type ScopeInfo = {
730
- label: string;
731
- };
732
- /**
733
- * Map a scope code to its display label.
734
- * @param code - Scope byte value.
735
- * @returns Display metadata for the scope.
736
- * @throws {CallciumError} If the code is not a recognised scope.
737
- */
738
- declare function lookupScope(code: number): ScopeInfo;
739
- /** ABI type code ranges and sentinel values for the descriptor format. */
740
- declare const TypeCode: {
741
- readonly UINT_MIN: 1;
742
- readonly UINT_MAX: 32;
743
- readonly INT_MIN: 33;
744
- readonly INT_MAX: 64;
745
- readonly ADDRESS: 65;
746
- readonly BOOL: 66;
747
- readonly FUNCTION: 67;
748
- readonly FIXED_BYTES_MIN: 80;
749
- readonly FIXED_BYTES_MAX: 111;
750
- readonly BYTES: 112;
751
- readonly STRING: 113;
752
- readonly STATIC_ARRAY: 128;
753
- readonly DYNAMIC_ARRAY: 129;
754
- readonly TUPLE: 144;
755
- };
756
- /** Well-known context property IDs for context-scope rules. */
757
- declare const ContextProperty: CodeMap<readonly [{
758
- readonly key: "MSG_SENDER";
759
- readonly code: 0;
760
- readonly label: "msg.sender";
761
- readonly contextKey: "msgSender";
762
- readonly typeCode: 65;
763
- }, {
764
- readonly key: "MSG_VALUE";
765
- readonly code: 1;
766
- readonly label: "msg.value";
767
- readonly contextKey: "msgValue";
768
- readonly typeCode: 32;
769
- }, {
770
- readonly key: "BLOCK_TIMESTAMP";
771
- readonly code: 2;
772
- readonly label: "block.timestamp";
773
- readonly contextKey: "blockTimestamp";
774
- readonly typeCode: 32;
775
- }, {
776
- readonly key: "BLOCK_NUMBER";
777
- readonly code: 3;
778
- readonly label: "block.number";
779
- readonly contextKey: "blockNumber";
780
- readonly typeCode: 32;
781
- }, {
782
- readonly key: "CHAIN_ID";
783
- readonly code: 4;
784
- readonly label: "block.chainid";
785
- readonly contextKey: "chainId";
786
- readonly typeCode: 32;
787
- }, {
788
- readonly key: "TX_ORIGIN";
789
- readonly code: 5;
790
- readonly label: "tx.origin";
791
- readonly contextKey: "txOrigin";
792
- readonly typeCode: 65;
793
- }, {
794
- readonly key: "BASE_FEE";
795
- readonly code: 6;
796
- readonly label: "block.basefee";
797
- readonly contextKey: "baseFee";
798
- readonly typeCode: 32;
799
- }, {
800
- readonly key: "GAS_PRICE";
801
- readonly code: 7;
802
- readonly label: "tx.gasprice";
803
- readonly contextKey: "gasPrice";
804
- readonly typeCode: 32;
805
- }]>;
806
- /** Maximum valid context property ID. */
807
- declare const MAX_CONTEXT_PROPERTY_ID: number;
808
- /** Display metadata for a context property code. */
809
- type ContextPropertyInfo = {
810
- label: string;
811
- contextKey: keyof Context;
812
- typeCode: number;
813
- };
814
- /**
815
- * Look up a context property code in the assigned set.
816
- * @param code - Context property ID.
817
- * @returns Display metadata, or undefined when the ID names no assigned property.
818
- */
819
- declare function findContextProperty(code: number): ContextPropertyInfo | undefined;
820
- /**
821
- * Map a context property code to its display label and ABI type code.
822
- * @param code - Context property ID.
823
- * @returns Display metadata including the ABI type code for the property value.
824
- * @throws {CallciumError} If the code is not a recognised context property.
825
- */
826
- declare function lookupContextProperty(code: number): ContextPropertyInfo;
827
- /** Operand count category for operator data validation. */
828
- type Operands = "single" | "range" | "variadic";
829
- /** @internal */
830
- declare const OP_TABLE: readonly [{
831
- readonly key: "EQ";
832
- readonly code: 1;
833
- readonly label: "==";
834
- readonly operands: "single";
835
- }, {
836
- readonly key: "GT";
837
- readonly code: 2;
838
- readonly label: ">";
839
- readonly operands: "single";
840
- }, {
841
- readonly key: "LT";
842
- readonly code: 3;
843
- readonly label: "<";
844
- readonly operands: "single";
845
- }, {
846
- readonly key: "GTE";
847
- readonly code: 4;
848
- readonly label: ">=";
849
- readonly operands: "single";
850
- }, {
851
- readonly key: "LTE";
852
- readonly code: 5;
853
- readonly label: "<=";
854
- readonly operands: "single";
855
- }, {
856
- readonly key: "BETWEEN";
857
- readonly code: 6;
858
- readonly label: "between";
859
- readonly operands: "range";
860
- }, {
861
- readonly key: "IN";
862
- readonly code: 7;
863
- readonly label: "in";
864
- readonly operands: "variadic";
865
- }, {
866
- readonly key: "EQ_CTX";
867
- readonly code: 8;
868
- readonly label: "== ctx";
869
- readonly operands: "single";
870
- }, {
871
- readonly key: "BITMASK_ALL";
872
- readonly code: 16;
873
- readonly label: "bitmask all";
874
- readonly operands: "single";
875
- }, {
876
- readonly key: "BITMASK_ANY";
877
- readonly code: 17;
878
- readonly label: "bitmask any";
879
- readonly operands: "single";
880
- }, {
881
- readonly key: "BITMASK_NONE";
882
- readonly code: 18;
883
- readonly label: "bitmask none";
884
- readonly operands: "single";
885
- }, {
886
- readonly key: "LENGTH_EQ";
887
- readonly code: 32;
888
- readonly label: "length ==";
889
- readonly operands: "single";
890
- }, {
891
- readonly key: "LENGTH_GT";
892
- readonly code: 33;
893
- readonly label: "length >";
894
- readonly operands: "single";
895
- }, {
896
- readonly key: "LENGTH_LT";
897
- readonly code: 34;
898
- readonly label: "length <";
899
- readonly operands: "single";
900
- }, {
901
- readonly key: "LENGTH_GTE";
902
- readonly code: 35;
903
- readonly label: "length >=";
904
- readonly operands: "single";
905
- }, {
906
- readonly key: "LENGTH_LTE";
907
- readonly code: 36;
908
- readonly label: "length <=";
909
- readonly operands: "single";
910
- }, {
911
- readonly key: "LENGTH_BETWEEN";
912
- readonly code: 37;
913
- readonly label: "length between";
914
- readonly operands: "range";
915
- }];
916
- /** Callcium policy operator codes. */
917
- declare const Op: CodeMap<typeof OP_TABLE> & {
918
- readonly NOT: 0x80;
919
- };
920
- /** Display metadata for an operator code. */
921
- type OpInfo = {
922
- label: string;
923
- operands: Operands;
924
- };
925
- /**
926
- * Map an operator code to its display label. Strips the NOT flag automatically.
927
- * @param code - Operator byte value (may include the NOT flag).
928
- * @returns Display metadata for the base operator.
929
- * @throws {CallciumError} If the base code is not a recognised operator.
930
- */
931
- declare function lookupOp(code: number): OpInfo;
932
- //#endregion
933
1001
  //#region src/operators.d.ts
934
- /** Return true when the operator code (with or without NOT flag) is a LENGTH_* variant. */
935
- declare function isLengthOp(opCode: number): boolean;
936
1002
  /** Structural category for a descriptor type code. */
937
1003
  type TypeClass = "elementary" | "tuple" | "staticArray" | "dynamicArray";
938
1004
  /** Structural classification without label. */
@@ -947,27 +1013,24 @@ type TypeCodeInfo = TypeClassInfo & {
947
1013
  /**
948
1014
  * Map a raw type code byte to its ABI type label, structural category, and dynamism.
949
1015
  * @param code - A single-byte descriptor type code.
950
- * @returns Label, type class, and whether the type is ABI-dynamic.
1016
+ * @returns Label, type class, and whether the code alone implies ABI dynamism (false for tuples and static arrays).
951
1017
  * @throws {CallciumError} If the code is not a recognised type code.
952
1018
  */
953
- declare function lookupTypeCode(code: number): TypeCodeInfo;
1019
+ export declare function lookupTypeCode(code: number): TypeCodeInfo;
954
1020
  //#endregion
955
1021
  //#region src/errors.d.ts
956
1022
  /**
957
1023
  * Machine-readable error code for structural decoding and validation failures.
958
1024
  *
959
- * Each code names one invariant. Where Solidity detects the same invariant, the code is its error
960
- * name transliterated from `PascalCase` to `SCREAMING_SNAKE_CASE`. The codes under "Inputs and
961
- * validation" have no counterpart: they name input a Solidity signature cannot express.
962
- * `OUT_OF_PHYSICAL_BOUNDS` names an invariant Solidity carries twice, as the error
963
- * `PolicyBuilder.OutOfPhysicalBounds` and as an issue code, so the name is shared with `IssueCode`.
1025
+ * Each code names one invariant. Where Solidity detects the same invariant, the code is its error name transliterated
1026
+ * from `PascalCase` to `SCREAMING_SNAKE_CASE`. The codes under "Inputs and validation" have no counterpart: they name
1027
+ * input a Solidity signature cannot express.
964
1028
  */
965
- type CallciumErrorCode = "UNSUPPORTED_VERSION" | "MALFORMED_HEADER" | "UNEXPECTED_END" | "TRAILING_BYTES" | "EMPTY_POLICY" | "EMPTY_GROUP" | "GROUP_TOO_SMALL" | "GROUP_SIZE_MISMATCH" | "GROUP_OVERFLOW" | "RULE_TOO_SMALL" | "RULE_SIZE_MISMATCH" | "RULE_FIELD_OUT_OF_BOUNDS" | "RULE_OVERFLOW" | "EMPTY_PATH" | "MALFORMED_PATH" | "PATH_TOO_DEEP" | "PARAM_INDEX_OUT_OF_BOUNDS" | "TUPLE_FIELD_OUT_OF_BOUNDS" | "STATIC_ARRAY_INDEX_OUT_OF_BOUNDS" | "NOT_COMPOSITE" | "UNCOMPILABLE_PATH" | "QUANTIFIER_ON_NON_ARRAY" | "NESTED_QUANTIFIER" | "INVALID_SCOPE" | "INVALID_CONTEXT_PATH" | "UNKNOWN_CONTEXT_PROPERTY" | "UNKNOWN_OPERATOR" | "INVALID_OPERATOR_BYTES" | "OPERATOR_TARGET_MISMATCH" | "UNSORTED_IN_SET" | "MALFORMED_HINT" | "NO_CONSTRAINT_OPERATORS" | "DUPLICATE_PATH_IN_GROUP" | "EMPTY_SET" | "SET_TOO_LARGE" | "INVALID_RANGE" | "OUT_OF_PHYSICAL_BOUNDS" | "UNKNOWN_TYPE_CODE" | "NODE_LENGTH_TOO_SMALL" | "NODE_LENGTH_TOO_LARGE" | "NODE_OVERFLOW" | "NESTING_TOO_DEEP" | "INVALID_ARRAY_LENGTH" | "INVALID_TUPLE_FIELD_COUNT" | "STATIC_WORDS_TOO_LARGE" | "PARAM_COUNT_MISMATCH" | "TOO_MANY_PARAMS" | "MALFORMED_TYPE_STRING" | "UNKNOWN_TYPE" | "MALFORMED_SIGNATURE" | "SIGNATURE_CONTAINS_WHITESPACE" | "INVALID_FUNCTION_NAME" | "GROUP_COUNT_OVERFLOW" | "RULE_COUNT_OVERFLOW" | "RULE_SIZE_OVERFLOW" | "DESC_LENGTH_OVERFLOW" | "UNKNOWN_QUANTIFIER" | "INVALID_HEX" | "MALFORMED_SELECTOR" | "PATH_STEP_OVERFLOW" | "OPERAND_OVERFLOW" | "CONTEXT_VALUE_OVERFLOW" | "VALIDATION_ERROR";
1029
+ type CallciumErrorCode = "UNSUPPORTED_VERSION" | "UNSUPPORTED_MINOR" | "MINOR_MISMATCH" | "MALFORMED_HEADER" | "UNEXPECTED_END" | "TRAILING_BYTES" | "EMPTY_POLICY" | "EMPTY_GROUP" | "GROUP_SIZE_MISMATCH" | "GROUP_OVERFLOW" | "RULE_TOO_SMALL" | "RULE_SIZE_MISMATCH" | "RULE_OVERFLOW" | "EMPTY_PATH" | "MALFORMED_PATH" | "PATH_TOO_DEEP" | "PARAM_INDEX_OUT_OF_BOUNDS" | "TUPLE_FIELD_OUT_OF_BOUNDS" | "STATIC_ARRAY_INDEX_OUT_OF_BOUNDS" | "NOT_COMPOSITE" | "QUANTIFIER_ON_NON_ARRAY" | "UNKNOWN_PATH_STEP" | "UNKNOWN_QUANTIFIER" | "INVALID_NESTED_LOOP" | "UNKNOWN_SCOPE" | "INVALID_CONTEXT_PATH" | "UNKNOWN_CONTEXT_PROPERTY" | "UNKNOWN_OPERATOR" | "INVALID_OPERATOR_BYTES" | "OPERATOR_TARGET_MISMATCH" | "INVALID_CONTEXT_OPERAND" | "DATA_LENGTH_MISMATCH" | "UNSORTED_IN_SET" | "MALFORMED_HINT" | "NO_CONSTRAINT_OPERATORS" | "EMPTY_SET" | "SET_TOO_LARGE" | "INVALID_RANGE" | "OUT_OF_PHYSICAL_BOUNDS" | "UNKNOWN_TYPE_CODE" | "NODE_LENGTH_TOO_SMALL" | "NODE_LENGTH_TOO_LARGE" | "NODE_OVERFLOW" | "NESTING_TOO_DEEP" | "INVALID_ARRAY_LENGTH" | "INVALID_TUPLE_FIELD_COUNT" | "STATIC_WORDS_TOO_LARGE" | "PARAM_COUNT_MISMATCH" | "TOO_MANY_PARAMS" | "NODE_LENGTH_MISMATCH" | "STATIC_WORDS_MISMATCH" | "INVALID_UINT_BITS" | "INVALID_INT_BITS" | "INVALID_BYTES_LENGTH" | "MALFORMED_TYPE_STRING" | "UNKNOWN_TYPE" | "MALFORMED_SIGNATURE" | "SIGNATURE_CONTAINS_WHITESPACE" | "INVALID_FUNCTION_NAME" | "GROUP_COUNT_OVERFLOW" | "RULE_COUNT_OVERFLOW" | "RULE_SIZE_OVERFLOW" | "DESC_LENGTH_OVERFLOW" | "VALIDATION_ERROR" | "INVALID_HEX" | "MALFORMED_SELECTOR" | "PATH_STEP_OVERFLOW" | "OPERAND_OVERFLOW" | "CONTEXT_VALUE_OVERFLOW" | "MALFORMED_CONTEXT_VALUE" | "MALFORMED_OPERAND";
966
1030
  /**
967
- * Thrown when a policy or descriptor blob is structurally malformed.
968
- * The optional `offset` indicates the byte position in the source blob where the error was detected.
1031
+ * Thrown on malformed or inadmissible SDK input. `offset`, when set, is the error's byte position in the source blob.
969
1032
  */
970
- declare class CallciumError extends Error {
1033
+ export declare class CallciumError extends Error {
971
1034
  readonly code: CallciumErrorCode;
972
1035
  /** Byte position in the source blob where the error was detected, if applicable. */
973
1036
  readonly offset?: number;
@@ -976,27 +1039,25 @@ declare class CallciumError extends Error {
976
1039
  /**
977
1040
  * Thrown by `PolicyBuilder.build` when validation reports any issue.
978
1041
  *
979
- * Carries every issue the validator found. The `Error.message` is the first issue's
980
- * message — a diagnostic summary, not a presentation contract. Consumers rendering
981
- * issues to users should iterate `issues` directly.
1042
+ * Carries every issue the validator found. The `Error.message` is the first issue's message — a diagnostic summary, not
1043
+ * a presentation contract. To render issues to users, iterate `issues` directly.
982
1044
  */
983
- declare class ValidationError extends CallciumError {
1045
+ export declare class ValidationError extends CallciumError {
984
1046
  readonly issues: Issue[];
985
1047
  constructor(issues: Issue[]);
986
1048
  }
987
1049
  /**
988
- * Thrown by `PolicyEnforcer.enforce` when calldata fails policy enforcement.
989
- * Distinct from `ValidationError`, which signals static issues in the policy itself.
1050
+ * Thrown by `PolicyEnforcer.enforce` when calldata fails policy enforcement. Distinct from `ValidationError`, which
1051
+ * signals static issues in the policy itself.
990
1052
  *
991
- * Carries the full list of structured violations (one per failed group). The
992
- * `Error.message` is a minimal non-lossy diagnostic summary built from the
993
- * first violation's structured fields — not a presentation contract. Consumers
994
- * rendering violations to users should iterate `violations` directly.
1053
+ * Carries the full list of structured violations (one per failed group). The `Error.message` is a minimal non-lossy
1054
+ * diagnostic summary built from the first violation's structured fields — not a presentation contract. To render
1055
+ * violations to users, iterate `violations` directly.
995
1056
  */
996
- declare class PolicyViolationError extends Error {
1057
+ export declare class PolicyViolationError extends Error {
997
1058
  readonly violations: Violation[];
998
1059
  constructor(violations: Violation[]);
999
1060
  }
1000
1061
  //#endregion
1001
- export { type Address, CallciumError, type CallciumErrorCode, type CalldataNavigationViolation, type Constraint, type ConstraintBuilder, type Context, ContextProperty, type ContextPropertyInfo, type DecodedGroup, type DecodedParam, type DecodedPolicy, type DecodedRule, Descriptor, DescriptorCoder, type EnforceResult, type Field, type Hex, type Issue, type IssueCategory, type IssueCode, type IssueSeverity, MAX_CONTEXT_PROPERTY_ID, type MissingContextViolation, type MissingSelectorViolation, type NavigationViolationCode, type NonCanonicalValueViolation, Op, type OpInfo, type Operands, PolicyBuilder, PolicyCoder, type PolicyData, PolicyEnforcer, PolicyFormat, PolicyValidator, PolicyViolationError, Quantifier, type QuantifierEmptyArrayViolation, type QuantifierInfo, type QuantifierLimitExceededViolation, type ScalarValue, Scope, type ScopeInfo, type SelectorMismatchViolation, type Span, type TypeClass, type TypeClassInfo, TypeCode, type TypeCodeInfo, type TypeInfo, ValidationError, type ValueMismatchViolation, type Violation, type ViolationCode, arg, baseFee, blockNumber, blockTimestamp, bytesToHex, chainId, findContextProperty, gasPrice, hexToBytes, isLengthOp, isOpAllowed, isQuantifier, lookupContextProperty, lookupOp, lookupQuantifier, lookupScope, lookupTypeCode, msgSender, msgValue, parsePathSteps, toAddress, txOrigin };
1062
+ export type { Address, ArrayMeta, BodyRule, CallciumErrorCode, CalldataNavigationViolation, ComparisonCode, Constraint, ConstraintBuilder, Context, ContextPropertyInfo, DecodedDescriptor, DecodedFrameHint, DecodedGroup, DecodedHint, DecodedHop, DecodedLoop, DecodedNode, DecodedOperator, DecodedPolicy, DecodedRule, DecodedTest, EnforceResult, Field, Hex, Issue, IssueCategory, IssueCode, IssueSeverity, LoopRule, MissingContextViolation, MissingSelectorViolation, NavigationViolationCode, NonCanonicalValueViolation, OpInfo, Operands, PolicyData, QuantifierCode, QuantifierInfo, QuantifierLimitExceededViolation, QuantifierNoMatchViolation, Rule, RuleLocation, ScalarValue, ScopeCode, ScopeInfo, SelectorMismatchViolation, Span, TypeClass, TypeClassInfo, TypeCodeInfo, ValueMismatchViolation, Violation, ViolationCode };
1002
1063
  //# sourceMappingURL=index.d.ts.map