@callcium/sdk 0.9.0 → 0.10.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.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { keccak_256 } from "@noble/hashes/sha3.js";
2
2
  //#region src/errors.ts
3
- var CallciumError = class CallciumError extends Error {
3
+ var CallciumError = class extends Error {
4
4
  code;
5
5
  offset;
6
6
  constructor(code, message, offset) {
@@ -8,25 +8,22 @@ var CallciumError = class CallciumError extends Error {
8
8
  super(`${prefix}${message}`);
9
9
  this.name = "CallciumError";
10
10
  this.code = code;
11
- Object.setPrototypeOf(this, CallciumError.prototype);
12
11
  }
13
12
  };
14
- var ValidationError = class ValidationError extends CallciumError {
13
+ var ValidationError = class extends CallciumError {
15
14
  issues;
16
15
  constructor(issues) {
17
16
  super("VALIDATION_ERROR", issues[0]?.message ?? "Policy validation failed");
18
17
  this.name = "ValidationError";
19
18
  this.issues = issues;
20
- Object.setPrototypeOf(this, ValidationError.prototype);
21
19
  }
22
20
  };
23
- var PolicyViolationError = class PolicyViolationError extends Error {
21
+ var PolicyViolationError = class extends Error {
24
22
  violations;
25
23
  constructor(violations) {
26
24
  super(formatDiagnostic(violations[0]));
27
25
  this.name = "PolicyViolationError";
28
26
  this.violations = violations;
29
- Object.setPrototypeOf(this, PolicyViolationError.prototype);
30
27
  }
31
28
  };
32
29
  function formatDiagnostic(violation) {
@@ -36,29 +33,29 @@ function formatDiagnostic(violation) {
36
33
  }
37
34
  //#endregion
38
35
  //#region src/bytes.ts
39
- const HEX_BODY_RE = /^[0-9a-fA-F]*$/;
36
+ const hexBodyPattern = /^[0-9a-fA-F]*$/;
40
37
  const HEX_DIGITS = "0123456789abcdef";
41
- const NIBBLE = new Int8Array(128).fill(-1);
38
+ const nibble = new Int8Array(128).fill(-1);
42
39
  for (let value = 0; value < 16; value++) {
43
- NIBBLE[HEX_DIGITS.charCodeAt(value)] = value;
44
- NIBBLE[HEX_DIGITS.toUpperCase().charCodeAt(value)] = value;
40
+ nibble[HEX_DIGITS.charCodeAt(value)] = value;
41
+ nibble[HEX_DIGITS.toUpperCase().charCodeAt(value)] = value;
45
42
  }
46
43
  function hexToBytes(hex) {
47
44
  const clean = hex.startsWith("0x") ? hex.slice(2) : hex;
48
45
  if (clean.length % 2 !== 0) throw new CallciumError("INVALID_HEX", "Odd-length hex string");
49
46
  const bytes = new Uint8Array(clean.length / 2);
50
47
  for (let i = 0; i < bytes.length; i++) {
51
- const high = NIBBLE[clean.charCodeAt(i * 2)] ?? -1;
52
- const low = NIBBLE[clean.charCodeAt(i * 2 + 1)] ?? -1;
48
+ const high = nibble[clean.charCodeAt(i * 2)] ?? -1;
49
+ const low = nibble[clean.charCodeAt(i * 2 + 1)] ?? -1;
53
50
  if (high < 0 || low < 0) throw new CallciumError("INVALID_HEX", "Invalid hex characters");
54
51
  bytes[i] = high << 4 | low;
55
52
  }
56
53
  return bytes;
57
54
  }
58
- const HEX_LUT = Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, "0"));
55
+ const hexPairs = Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, "0"));
59
56
  function bytesToHex(bytes) {
60
57
  let body = "";
61
- for (let i = 0; i < bytes.length; i++) body += HEX_LUT[bytes[i]];
58
+ for (let i = 0; i < bytes.length; i++) body += hexPairs[bytes[i]];
62
59
  return `0x${body}`;
63
60
  }
64
61
  function toHex(data, start, end) {
@@ -94,7 +91,7 @@ function bigintToHex(value) {
94
91
  function toAddress(hex) {
95
92
  const body = hex.startsWith("0x") ? hex.slice(2) : hex;
96
93
  if (body.length !== 40) throw new CallciumError("INVALID_HEX", `Invalid address length: expected 40 hex chars, got ${body.length}`);
97
- if (!HEX_BODY_RE.test(body)) throw new CallciumError("INVALID_HEX", "Invalid hex characters in address");
94
+ if (!hexBodyPattern.test(body)) throw new CallciumError("INVALID_HEX", "Invalid hex characters in address");
98
95
  return `0x${body}`;
99
96
  }
100
97
  //#endregion
@@ -117,6 +114,7 @@ const DescriptorFormat = {
117
114
  MAX_PARAMS: 255,
118
115
  MAX_NESTING_DEPTH: 64
119
116
  };
117
+ const RULE_DATALENGTH_SIZE = 2;
120
118
  const PolicyFormat = {
121
119
  VERSION: 2,
122
120
  VERSION_MASK: 15,
@@ -138,7 +136,7 @@ const PolicyFormat = {
138
136
  RULE_PATH_OFFSET: 4,
139
137
  PATH_STEP_SIZE: 2,
140
138
  RULE_OPCODE_SIZE: 1,
141
- RULE_DATALENGTH_SIZE: 2,
139
+ RULE_DATALENGTH_SIZE,
142
140
  RULE_FIXED_OVERHEAD: 7,
143
141
  RULE_MIN_SIZE: 9,
144
142
  HINT_HEADER_SIZE: 1,
@@ -163,7 +161,10 @@ const PolicyFormat = {
163
161
  HINT_META_ELEM_DYNAMIC: 32768,
164
162
  HINT_META_DYNAMIC_ARRAY: 16384,
165
163
  HINT_META_RESERVED_MASK: 12288,
166
- HINT_META_STRIDE_MASK: 4095
164
+ HINT_META_STRIDE_MASK: 4095,
165
+ MAX_PATH_DEPTH: 32,
166
+ MAX_QUANTIFIED_ARRAY_LENGTH: 256,
167
+ MAX_SET_MEMBERS: Math.floor((256 ** RULE_DATALENGTH_SIZE - 1) / 32)
167
168
  };
168
169
  function buildCodeMap(table) {
169
170
  return Object.fromEntries(table.map((e) => [e.key, e.code]));
@@ -200,83 +201,76 @@ const TypeCode = {
200
201
  DYNAMIC_ARRAY: 129,
201
202
  TUPLE: 144
202
203
  };
203
- const CTX_PROP_TABLE = [
204
+ const CTX_PROPERTY_TABLE = [
204
205
  {
205
206
  key: "MSG_SENDER",
206
207
  code: 0,
207
208
  label: "msg.sender",
209
+ contextKey: "msgSender",
208
210
  typeCode: TypeCode.ADDRESS
209
211
  },
210
212
  {
211
213
  key: "MSG_VALUE",
212
214
  code: 1,
213
215
  label: "msg.value",
216
+ contextKey: "msgValue",
214
217
  typeCode: TypeCode.UINT_MAX
215
218
  },
216
219
  {
217
220
  key: "BLOCK_TIMESTAMP",
218
221
  code: 2,
219
222
  label: "block.timestamp",
223
+ contextKey: "blockTimestamp",
220
224
  typeCode: TypeCode.UINT_MAX
221
225
  },
222
226
  {
223
227
  key: "BLOCK_NUMBER",
224
228
  code: 3,
225
229
  label: "block.number",
230
+ contextKey: "blockNumber",
226
231
  typeCode: TypeCode.UINT_MAX
227
232
  },
228
233
  {
229
234
  key: "CHAIN_ID",
230
235
  code: 4,
231
236
  label: "block.chainid",
237
+ contextKey: "chainId",
232
238
  typeCode: TypeCode.UINT_MAX
233
239
  },
234
240
  {
235
241
  key: "TX_ORIGIN",
236
242
  code: 5,
237
243
  label: "tx.origin",
244
+ contextKey: "txOrigin",
238
245
  typeCode: TypeCode.ADDRESS
239
246
  },
240
247
  {
241
248
  key: "BASE_FEE",
242
249
  code: 6,
243
250
  label: "block.basefee",
251
+ contextKey: "baseFee",
244
252
  typeCode: TypeCode.UINT_MAX
245
253
  },
246
254
  {
247
255
  key: "GAS_PRICE",
248
256
  code: 7,
249
257
  label: "tx.gasprice",
258
+ contextKey: "gasPrice",
250
259
  typeCode: TypeCode.UINT_MAX
251
260
  }
252
261
  ];
253
- const ContextProperty = buildCodeMap(CTX_PROP_TABLE);
254
- const MAX_CONTEXT_PROPERTY_ID = Math.max(...CTX_PROP_TABLE.map((e) => e.code));
255
- const CTX_KEY_MAP = {
256
- MSG_SENDER: "msgSender",
257
- MSG_VALUE: "msgValue",
258
- BLOCK_TIMESTAMP: "blockTimestamp",
259
- BLOCK_NUMBER: "blockNumber",
260
- CHAIN_ID: "chainId",
261
- TX_ORIGIN: "txOrigin",
262
- BASE_FEE: "baseFee",
263
- GAS_PRICE: "gasPrice"
264
- };
265
- const ctxPropByCode = new Map(CTX_PROP_TABLE.map((e) => [e.code, {
262
+ const ContextProperty = buildCodeMap(CTX_PROPERTY_TABLE);
263
+ const MAX_CONTEXT_PROPERTY_ID = Math.max(...CTX_PROPERTY_TABLE.map((e) => e.code));
264
+ const ctxPropertyByCode = new Map(CTX_PROPERTY_TABLE.map((e) => [e.code, {
266
265
  label: e.label,
267
- contextKey: CTX_KEY_MAP[e.key],
266
+ contextKey: e.contextKey,
268
267
  typeCode: e.typeCode
269
268
  }]));
270
269
  function lookupContextProperty(code) {
271
- const info = ctxPropByCode.get(code);
270
+ const info = ctxPropertyByCode.get(code);
272
271
  if (!info) throw new CallciumError("UNKNOWN_CONTEXT_PROPERTY", `Unknown context property ${code}`);
273
272
  return info;
274
273
  }
275
- const Limits = {
276
- MAX_PATH_DEPTH: 32,
277
- MAX_QUANTIFIED_ARRAY_LENGTH: 256,
278
- MAX_SET_MEMBERS: Math.floor((256 ** PolicyFormat.RULE_DATALENGTH_SIZE - 1) / 32)
279
- };
280
274
  const OP_TABLE = [
281
275
  {
282
276
  key: "EQ",
@@ -395,13 +389,11 @@ function lookupOp(code) {
395
389
  if (!info) throw new CallciumError("UNKNOWN_OPERATOR", `Unknown operator code 0x${base.toString(16).padStart(2, "0")}`);
396
390
  return info;
397
391
  }
398
- function isValidOperatorData(opBase, dataLength) {
399
- const operands = opByCode.get(opBase)?.operands;
400
- if (operands === "single") return dataLength === 32;
401
- if (operands === "range") return dataLength === 64;
402
- if (operands === "variadic") return dataLength > 0 && dataLength % 32 === 0;
403
- return false;
392
+ function operandsOf(opBase) {
393
+ return opByCode.get(opBase)?.operands;
404
394
  }
395
+ //#endregion
396
+ //#region src/path.ts
405
397
  const QUANTIFIER_TABLE = [{
406
398
  key: "ALL",
407
399
  code: 65535,
@@ -421,71 +413,17 @@ function lookupQuantifier(code) {
421
413
  if (!info) throw new CallciumError("UNKNOWN_QUANTIFIER", `Unknown quantifier step 0x${code.toString(16)}`);
422
414
  return info;
423
415
  }
424
- function unknownTypeCode(code) {
425
- throw new CallciumError("UNKNOWN_TYPE_CODE", `Unknown type code 0x${code.toString(16).padStart(2, "0")}`);
426
- }
427
- const ELEMENTARY = {
428
- typeClass: "elementary",
429
- isDynamic: false
430
- };
431
- const ELEMENTARY_DYN = {
432
- typeClass: "elementary",
433
- isDynamic: true
434
- };
435
- const STATIC_ARR = {
436
- typeClass: "staticArray",
437
- isDynamic: false
438
- };
439
- const DYNAMIC_ARR = {
440
- typeClass: "dynamicArray",
441
- isDynamic: true
442
- };
443
- const TUPLE = {
444
- typeClass: "tuple",
445
- isDynamic: false
446
- };
447
- function classifyTypeCode(code) {
448
- if (code >= TypeCode.UINT_MIN && code <= TypeCode.UINT_MAX) return ELEMENTARY;
449
- if (code >= TypeCode.INT_MIN && code <= TypeCode.INT_MAX) return ELEMENTARY;
450
- if (code === TypeCode.ADDRESS || code === TypeCode.BOOL || code === TypeCode.FUNCTION) return ELEMENTARY;
451
- if (code >= 68 && code <= 79) unknownTypeCode(code);
452
- if (code >= TypeCode.FIXED_BYTES_MIN && code <= TypeCode.FIXED_BYTES_MAX) return ELEMENTARY;
453
- if (code === TypeCode.BYTES || code === TypeCode.STRING) return ELEMENTARY_DYN;
454
- if (code >= 114 && code <= 127) unknownTypeCode(code);
455
- if (code === TypeCode.STATIC_ARRAY) return STATIC_ARR;
456
- if (code === TypeCode.DYNAMIC_ARRAY) return DYNAMIC_ARR;
457
- if (code >= 130 && code <= 143) unknownTypeCode(code);
458
- if (code === TypeCode.TUPLE) return TUPLE;
459
- unknownTypeCode(code);
460
- }
461
- function isAddressableTarget(code) {
462
- let info;
463
- try {
464
- info = classifyTypeCode(code);
465
- } catch {
466
- return false;
467
- }
468
- return info.typeClass === "elementary" || info.typeClass === "dynamicArray";
469
- }
470
- function typeCodeLabel(code) {
471
- if (code >= TypeCode.UINT_MIN && code <= TypeCode.UINT_MAX) return `uint${(code - TypeCode.UINT_MIN + 1) * 8}`;
472
- if (code >= TypeCode.INT_MIN && code <= TypeCode.INT_MAX) return `int${(code - TypeCode.INT_MIN + 1) * 8}`;
473
- if (code === TypeCode.ADDRESS) return "address";
474
- if (code === TypeCode.BOOL) return "bool";
475
- if (code === TypeCode.FUNCTION) return "function";
476
- if (code >= TypeCode.FIXED_BYTES_MIN && code <= TypeCode.FIXED_BYTES_MAX) return `bytes${code - TypeCode.FIXED_BYTES_MIN + 1}`;
477
- if (code === TypeCode.BYTES) return "bytes";
478
- if (code === TypeCode.STRING) return "string";
479
- if (code === TypeCode.STATIC_ARRAY) return "T[k]";
480
- if (code === TypeCode.DYNAMIC_ARRAY) return "T[]";
481
- if (code === TypeCode.TUPLE) return "tuple";
482
- return `0x${code.toString(16).padStart(2, "0")}`;
416
+ function encodePath(steps) {
417
+ const buffer = new Uint8Array(steps.length * 2);
418
+ for (let i = 0; i < steps.length; i++) writeBE16(buffer, i * 2, steps[i]);
419
+ return bytesToHex(buffer);
483
420
  }
484
- function lookupTypeCode(code) {
485
- return {
486
- label: typeCodeLabel(code),
487
- ...classifyTypeCode(code)
488
- };
421
+ function parsePathSteps(path) {
422
+ const bytes = hexToBytes(path);
423
+ if (bytes.length % PolicyFormat.PATH_STEP_SIZE !== 0) throw new CallciumError("MALFORMED_PATH", `Path byte length ${bytes.length} is not a whole number of steps`);
424
+ const steps = [];
425
+ for (let offset = 0; offset < bytes.length; offset += PolicyFormat.PATH_STEP_SIZE) steps.push(readU16(bytes, offset));
426
+ return steps;
489
427
  }
490
428
  //#endregion
491
429
  //#region src/descriptor.ts
@@ -503,7 +441,7 @@ function paramCount(desc) {
503
441
  }
504
442
  function paramOffset(desc, index) {
505
443
  const count = desc[1];
506
- if (index >= count) throw new CallciumError("PARAM_INDEX_OUT_OF_BOUNDS", `Param index ${index} out of range (paramCount=${count}).`);
444
+ if (index >= count) throw new CallciumError("PARAM_INDEX_OUT_OF_BOUNDS", `Param index ${index} out of range (paramCount=${count})`);
507
445
  let cursor = DescriptorFormat.HEADER_SIZE;
508
446
  for (let i = 0; i < index; i++) cursor += nodeLength(desc, cursor);
509
447
  return cursor;
@@ -523,10 +461,10 @@ function typeAt(desc, steps) {
523
461
  return walkPath(desc, steps).typeInfo;
524
462
  }
525
463
  function walkPath(desc, steps) {
526
- if (steps.length === 0) throw new CallciumError("EMPTY_PATH", "Path must have at least one step.");
464
+ if (steps.length === 0) throw new CallciumError("EMPTY_PATH", "Path must have at least one step");
527
465
  const paramIndex = steps[0];
528
466
  const count = desc[1];
529
- if (paramIndex >= count) throw new CallciumError("PARAM_INDEX_OUT_OF_BOUNDS", `Param index ${paramIndex} out of range (paramCount=${count}).`);
467
+ if (paramIndex >= count) throw new CallciumError("PARAM_INDEX_OUT_OF_BOUNDS", `Param index ${paramIndex} out of range (paramCount=${count})`);
530
468
  let cursor = paramOffset(desc, paramIndex);
531
469
  let quantifiedStaticLength = 0;
532
470
  for (let stepIndex = 1; stepIndex < steps.length; stepIndex++) {
@@ -534,16 +472,16 @@ function walkPath(desc, steps) {
534
472
  const step = steps[stepIndex];
535
473
  if (typeCode === TypeCode.TUPLE) {
536
474
  const fields = tupleFieldCount(desc, cursor);
537
- if (step >= fields) throw new CallciumError("TUPLE_FIELD_OUT_OF_BOUNDS", `Tuple field index ${step} out of range (tuple has ${fields} fields).`);
475
+ if (step >= fields) throw new CallciumError("TUPLE_FIELD_OUT_OF_BOUNDS", `Tuple field index ${step} out of range (tuple has ${fields} fields)`);
538
476
  cursor = tupleFieldOffset(desc, cursor, step);
539
477
  } else if (typeCode === TypeCode.STATIC_ARRAY || typeCode === TypeCode.DYNAMIC_ARRAY) {
540
478
  if (typeCode === TypeCode.STATIC_ARRAY) if (isQuantifier(step)) quantifiedStaticLength = staticArrayLength(desc, cursor);
541
479
  else {
542
480
  const length = staticArrayLength(desc, cursor);
543
- if (step >= length) throw new CallciumError("STATIC_ARRAY_INDEX_OUT_OF_BOUNDS", `Array index ${step} out of range (length=${length}).`);
481
+ if (step >= length) throw new CallciumError("STATIC_ARRAY_INDEX_OUT_OF_BOUNDS", `Array index ${step} out of range (length=${length})`);
544
482
  }
545
483
  cursor = arrayElementOffset(cursor);
546
- } else throw new CallciumError("NOT_COMPOSITE", `Cannot descend into elementary type at offset ${cursor}.`);
484
+ } else throw new CallciumError("NOT_COMPOSITE", `Cannot descend into elementary type at offset ${cursor}`);
547
485
  }
548
486
  return {
549
487
  typeInfo: inspect$1(desc, cursor),
@@ -561,7 +499,7 @@ function arrayElementOffset(offset) {
561
499
  return offset + DescriptorFormat.ARRAY_HEADER_SIZE;
562
500
  }
563
501
  function uncompilablePath(stepIndex) {
564
- return new CallciumError("UNCOMPILABLE_PATH", `Path step ${stepIndex} does not resolve to a hop-chain target.`);
502
+ return new CallciumError("UNCOMPILABLE_PATH", `Path step ${stepIndex} does not resolve to a hop-chain target`);
565
503
  }
566
504
  function headSpan(desc, offset, count) {
567
505
  let span = 0;
@@ -668,7 +606,7 @@ function encodeHint(walk, targetMeta, typeCode, depth) {
668
606
  return out;
669
607
  }
670
608
  function compileHint(desc, steps) {
671
- if (steps.length === 0) throw new CallciumError("EMPTY_PATH", "Path must have at least one step.");
609
+ if (steps.length === 0) throw new CallciumError("EMPTY_PATH", "Path must have at least one step");
672
610
  const argIndex = steps[0];
673
611
  if (argIndex >= paramCount(desc)) throw uncompilablePath(0);
674
612
  const arg = headSpan(desc, DescriptorFormat.HEADER_SIZE, argIndex);
@@ -704,6 +642,199 @@ const Descriptor = {
704
642
  compileHint
705
643
  };
706
644
  //#endregion
645
+ //#region src/operators.ts
646
+ function toBigInt(bytes, offset = 0) {
647
+ const view = new DataView(bytes.buffer, bytes.byteOffset + offset, 32);
648
+ return view.getBigUint64(0, false) << 192n | view.getBigUint64(8, false) << 128n | view.getBigUint64(16, false) << 64n | view.getBigUint64(24, false);
649
+ }
650
+ function isSigned(typeCode) {
651
+ return typeCode >= TypeCode.INT_MIN && typeCode <= TypeCode.INT_MAX;
652
+ }
653
+ function isLeftAligned(typeCode) {
654
+ return typeCode >= TypeCode.FIXED_BYTES_MIN && typeCode <= TypeCode.FIXED_BYTES_MAX || typeCode === TypeCode.FUNCTION;
655
+ }
656
+ function canonicalize(value, typeCode) {
657
+ if (typeCode >= TypeCode.UINT_MIN && typeCode <= TypeCode.UINT_MAX) {
658
+ const bits = BigInt(typeCode * 8);
659
+ return bits === 256n ? value : value & (1n << bits) - 1n;
660
+ }
661
+ if (typeCode >= TypeCode.INT_MIN && typeCode <= TypeCode.INT_MAX) {
662
+ const bits = (typeCode - TypeCode.INT_MIN + 1) * 8;
663
+ return bits === 256 ? value : BigInt.asUintN(256, BigInt.asIntN(bits, value));
664
+ }
665
+ if (typeCode === TypeCode.ADDRESS) return value & (1n << 160n) - 1n;
666
+ if (typeCode === TypeCode.BOOL) return value & 1n;
667
+ if (typeCode === TypeCode.FUNCTION) return value >> 64n << 64n;
668
+ if (typeCode >= TypeCode.FIXED_BYTES_MIN && typeCode <= TypeCode.FIXED_BYTES_MAX) {
669
+ const n = typeCode - TypeCode.FIXED_BYTES_MIN + 1;
670
+ if (n === 32) return value;
671
+ const padBits = BigInt((32 - n) * 8);
672
+ return value >> padBits << padBits;
673
+ }
674
+ return value;
675
+ }
676
+ function isLengthOp(opCode) {
677
+ const base = opCode & ~Op.NOT;
678
+ return base >= Op.LENGTH_EQ && base <= Op.LENGTH_BETWEEN;
679
+ }
680
+ function lengthToValueOp(base) {
681
+ if (base === Op.LENGTH_EQ) return Op.EQ;
682
+ if (base === Op.LENGTH_GT) return Op.GT;
683
+ if (base === Op.LENGTH_LT) return Op.LT;
684
+ if (base === Op.LENGTH_GTE) return Op.GTE;
685
+ if (base === Op.LENGTH_LTE) return Op.LTE;
686
+ return Op.BETWEEN;
687
+ }
688
+ function isLengthValidType(typeCode) {
689
+ return typeCode === TypeCode.BYTES || typeCode === TypeCode.STRING || typeCode === TypeCode.DYNAMIC_ARRAY;
690
+ }
691
+ function compareTyped(a, b, typeCode) {
692
+ if (isSigned(typeCode)) {
693
+ const sa = BigInt.asIntN(256, a);
694
+ const sb = BigInt.asIntN(256, b);
695
+ return sa < sb ? -1 : sa > sb ? 1 : 0;
696
+ }
697
+ return a < b ? -1 : a > b ? 1 : 0;
698
+ }
699
+ function isIn(value, data) {
700
+ const count = data.length / 32;
701
+ let low = 0;
702
+ let high = count - 1;
703
+ while (low <= high) {
704
+ const mid = low + high >>> 1;
705
+ const elem = toBigInt(data, mid * 32);
706
+ if (value === elem) return true;
707
+ if (value < elem) high = mid - 1;
708
+ else low = mid + 1;
709
+ }
710
+ return false;
711
+ }
712
+ function applyOperator(opCode, value, valueLength, operandData, typeCode) {
713
+ let base = opCode & ~Op.NOT;
714
+ if (isLengthOp(base)) {
715
+ value = BigInt(valueLength);
716
+ typeCode = TypeCode.UINT_MAX;
717
+ base = lengthToValueOp(base);
718
+ }
719
+ let result;
720
+ switch (base) {
721
+ case Op.EQ:
722
+ result = value === toBigInt(operandData, 0);
723
+ break;
724
+ case Op.GT:
725
+ result = compareTyped(value, toBigInt(operandData, 0), typeCode) > 0;
726
+ break;
727
+ case Op.LT:
728
+ result = compareTyped(value, toBigInt(operandData, 0), typeCode) < 0;
729
+ break;
730
+ case Op.GTE:
731
+ result = compareTyped(value, toBigInt(operandData, 0), typeCode) >= 0;
732
+ break;
733
+ case Op.LTE:
734
+ result = compareTyped(value, toBigInt(operandData, 0), typeCode) <= 0;
735
+ break;
736
+ case Op.BETWEEN: {
737
+ const min = toBigInt(operandData, 0);
738
+ const max = toBigInt(operandData, 32);
739
+ result = compareTyped(value, min, typeCode) >= 0 && compareTyped(value, max, typeCode) <= 0;
740
+ break;
741
+ }
742
+ case Op.IN:
743
+ result = isIn(value, operandData);
744
+ break;
745
+ case Op.BITMASK_ALL: {
746
+ const mask = toBigInt(operandData, 0);
747
+ result = (value & mask) === mask;
748
+ break;
749
+ }
750
+ case Op.BITMASK_ANY: {
751
+ const mask = toBigInt(operandData, 0);
752
+ result = (value & mask) !== 0n;
753
+ break;
754
+ }
755
+ case Op.BITMASK_NONE: {
756
+ const mask = toBigInt(operandData, 0);
757
+ result = (value & mask) === 0n;
758
+ break;
759
+ }
760
+ default: throw new CallciumError("UNKNOWN_OPERATOR", `Unknown operator code 0x${base.toString(16).padStart(2, "0")}`);
761
+ }
762
+ return (opCode & Op.NOT) !== 0 ? !result : result;
763
+ }
764
+ function isValidOperatorData(opBase, dataLength) {
765
+ const operands = operandsOf(opBase);
766
+ if (operands === "single") return dataLength === 32;
767
+ if (operands === "range") return dataLength === 64;
768
+ if (operands === "variadic") return dataLength > 0 && dataLength % 32 === 0;
769
+ return false;
770
+ }
771
+ function unknownTypeCode(code) {
772
+ throw new CallciumError("UNKNOWN_TYPE_CODE", `Unknown type code 0x${code.toString(16).padStart(2, "0")}`);
773
+ }
774
+ const ELEMENTARY = {
775
+ typeClass: "elementary",
776
+ isDynamic: false
777
+ };
778
+ const ELEMENTARY_DYNAMIC = {
779
+ typeClass: "elementary",
780
+ isDynamic: true
781
+ };
782
+ const STATIC_ARR = {
783
+ typeClass: "staticArray",
784
+ isDynamic: false
785
+ };
786
+ const DYNAMIC_ARR = {
787
+ typeClass: "dynamicArray",
788
+ isDynamic: true
789
+ };
790
+ const TUPLE = {
791
+ typeClass: "tuple",
792
+ isDynamic: false
793
+ };
794
+ function classifyTypeCode(code) {
795
+ if (code >= TypeCode.UINT_MIN && code <= TypeCode.UINT_MAX) return ELEMENTARY;
796
+ if (code >= TypeCode.INT_MIN && code <= TypeCode.INT_MAX) return ELEMENTARY;
797
+ if (code === TypeCode.ADDRESS || code === TypeCode.BOOL || code === TypeCode.FUNCTION) return ELEMENTARY;
798
+ if (code >= 68 && code <= 79) unknownTypeCode(code);
799
+ if (code >= TypeCode.FIXED_BYTES_MIN && code <= TypeCode.FIXED_BYTES_MAX) return ELEMENTARY;
800
+ if (code === TypeCode.BYTES || code === TypeCode.STRING) return ELEMENTARY_DYNAMIC;
801
+ if (code >= 114 && code <= 127) unknownTypeCode(code);
802
+ if (code === TypeCode.STATIC_ARRAY) return STATIC_ARR;
803
+ if (code === TypeCode.DYNAMIC_ARRAY) return DYNAMIC_ARR;
804
+ if (code >= 130 && code <= 143) unknownTypeCode(code);
805
+ if (code === TypeCode.TUPLE) return TUPLE;
806
+ unknownTypeCode(code);
807
+ }
808
+ function isAddressableTarget(code) {
809
+ let info;
810
+ try {
811
+ info = classifyTypeCode(code);
812
+ } catch {
813
+ return false;
814
+ }
815
+ return info.typeClass === "elementary" || info.typeClass === "dynamicArray";
816
+ }
817
+ function typeCodeLabel(code) {
818
+ if (code >= TypeCode.UINT_MIN && code <= TypeCode.UINT_MAX) return `uint${(code - TypeCode.UINT_MIN + 1) * 8}`;
819
+ if (code >= TypeCode.INT_MIN && code <= TypeCode.INT_MAX) return `int${(code - TypeCode.INT_MIN + 1) * 8}`;
820
+ if (code === TypeCode.ADDRESS) return "address";
821
+ if (code === TypeCode.BOOL) return "bool";
822
+ if (code === TypeCode.FUNCTION) return "function";
823
+ if (code >= TypeCode.FIXED_BYTES_MIN && code <= TypeCode.FIXED_BYTES_MAX) return `bytes${code - TypeCode.FIXED_BYTES_MIN + 1}`;
824
+ if (code === TypeCode.BYTES) return "bytes";
825
+ if (code === TypeCode.STRING) return "string";
826
+ if (code === TypeCode.STATIC_ARRAY) return "T[k]";
827
+ if (code === TypeCode.DYNAMIC_ARRAY) return "T[]";
828
+ if (code === TypeCode.TUPLE) return "tuple";
829
+ return `0x${code.toString(16).padStart(2, "0")}`;
830
+ }
831
+ function lookupTypeCode(code) {
832
+ return {
833
+ label: typeCodeLabel(code),
834
+ ...classifyTypeCode(code)
835
+ };
836
+ }
837
+ //#endregion
707
838
  //#region src/type-desc.ts
708
839
  function extractStaticWords(desc) {
709
840
  const typeCode = desc[0];
@@ -720,11 +851,11 @@ function function_() {
720
851
  return new Uint8Array([TypeCode.FUNCTION]);
721
852
  }
722
853
  function uintN(bits) {
723
- if (bits < 8 || bits > 256 || bits % 8 !== 0) throw new CallciumError("UNKNOWN_TYPE", `Invalid uintN bits: ${bits}. Must be 8–256 in steps of 8.`);
854
+ if (bits < 8 || bits > 256 || bits % 8 !== 0) throw new CallciumError("UNKNOWN_TYPE", `Invalid uintN bits: ${bits}. Must be 8–256 in steps of 8`);
724
855
  return new Uint8Array([TypeCode.UINT_MIN + (bits / 8 - 1)]);
725
856
  }
726
857
  function intN(bits) {
727
- if (bits < 8 || bits > 256 || bits % 8 !== 0) throw new CallciumError("UNKNOWN_TYPE", `Invalid intN bits: ${bits}. Must be 8–256 in steps of 8.`);
858
+ if (bits < 8 || bits > 256 || bits % 8 !== 0) throw new CallciumError("UNKNOWN_TYPE", `Invalid intN bits: ${bits}. Must be 8–256 in steps of 8`);
728
859
  return new Uint8Array([TypeCode.INT_MIN + (bits / 8 - 1)]);
729
860
  }
730
861
  function bytes() {
@@ -734,13 +865,13 @@ function string_() {
734
865
  return new Uint8Array([TypeCode.STRING]);
735
866
  }
736
867
  function bytesN(n) {
737
- if (n < 1 || n > 32) throw new CallciumError("UNKNOWN_TYPE", `Invalid bytesN size: ${n}. Must be 1–32.`);
868
+ if (n < 1 || n > 32) throw new CallciumError("UNKNOWN_TYPE", `Invalid bytesN size: ${n}. Must be 1–32`);
738
869
  return new Uint8Array([TypeCode.FIXED_BYTES_MIN + (n - 1)]);
739
870
  }
740
871
  function array(elemDesc, length) {
741
872
  if (length === void 0) {
742
873
  const nodeLength = DescriptorFormat.ARRAY_HEADER_SIZE + elemDesc.length;
743
- if (nodeLength > DescriptorFormat.MAX_NODE_LENGTH) throw new CallciumError("NODE_LENGTH_TOO_LARGE", `Dynamic array node length ${nodeLength} exceeds maximum ${DescriptorFormat.MAX_NODE_LENGTH}.`);
874
+ if (nodeLength > DescriptorFormat.MAX_NODE_LENGTH) throw new CallciumError("NODE_LENGTH_TOO_LARGE", `Dynamic array node length ${nodeLength} exceeds maximum ${DescriptorFormat.MAX_NODE_LENGTH}`);
744
875
  const meta24 = 0 << DescriptorFormat.META_STATIC_WORDS_SHIFT | nodeLength;
745
876
  const buf = new Uint8Array(1 + DescriptorFormat.COMPOSITE_META_SIZE + elemDesc.length);
746
877
  buf[0] = TypeCode.DYNAMIC_ARRAY;
@@ -748,12 +879,12 @@ function array(elemDesc, length) {
748
879
  buf.set(elemDesc, 4);
749
880
  return buf;
750
881
  }
751
- if (length <= 0 || length > DescriptorFormat.MAX_STATIC_ARRAY_LENGTH) throw new CallciumError("INVALID_ARRAY_LENGTH", `Static array length ${length} out of range. Must be 1–${DescriptorFormat.MAX_STATIC_ARRAY_LENGTH}.`);
882
+ if (length <= 0 || length > DescriptorFormat.MAX_STATIC_ARRAY_LENGTH) throw new CallciumError("INVALID_ARRAY_LENGTH", `Static array length ${length} out of range. Must be 1–${DescriptorFormat.MAX_STATIC_ARRAY_LENGTH}`);
752
883
  const nodeLength = DescriptorFormat.ARRAY_HEADER_SIZE + elemDesc.length + DescriptorFormat.ARRAY_LENGTH_SIZE;
753
- if (nodeLength > DescriptorFormat.MAX_NODE_LENGTH) throw new CallciumError("NODE_LENGTH_TOO_LARGE", `Static array node length ${nodeLength} exceeds maximum ${DescriptorFormat.MAX_NODE_LENGTH}.`);
884
+ if (nodeLength > DescriptorFormat.MAX_NODE_LENGTH) throw new CallciumError("NODE_LENGTH_TOO_LARGE", `Static array node length ${nodeLength} exceeds maximum ${DescriptorFormat.MAX_NODE_LENGTH}`);
754
885
  const elemStaticWords = extractStaticWords(elemDesc);
755
886
  const staticWords = elemStaticWords === 0 ? 0 : length * elemStaticWords;
756
- if (staticWords > DescriptorFormat.MAX_STATIC_WORDS) throw new CallciumError("STATIC_WORDS_TOO_LARGE", `Static array static words ${staticWords} exceeds maximum ${DescriptorFormat.MAX_STATIC_WORDS}.`);
887
+ if (staticWords > DescriptorFormat.MAX_STATIC_WORDS) throw new CallciumError("STATIC_WORDS_TOO_LARGE", `Static array static words ${staticWords} exceeds maximum ${DescriptorFormat.MAX_STATIC_WORDS}`);
757
888
  const meta24 = staticWords << DescriptorFormat.META_STATIC_WORDS_SHIFT | nodeLength;
758
889
  const buf = new Uint8Array(1 + DescriptorFormat.COMPOSITE_META_SIZE + elemDesc.length + DescriptorFormat.ARRAY_LENGTH_SIZE);
759
890
  buf[0] = TypeCode.STATIC_ARRAY;
@@ -763,10 +894,10 @@ function array(elemDesc, length) {
763
894
  return buf;
764
895
  }
765
896
  function tuple(fieldDescs) {
766
- if (fieldDescs.length === 0 || fieldDescs.length > DescriptorFormat.MAX_TUPLE_FIELDS) throw new CallciumError("INVALID_TUPLE_FIELD_COUNT", `Tuple field count ${fieldDescs.length} out of range. Must be 1–${DescriptorFormat.MAX_TUPLE_FIELDS}.`);
897
+ if (fieldDescs.length === 0 || fieldDescs.length > DescriptorFormat.MAX_TUPLE_FIELDS) throw new CallciumError("INVALID_TUPLE_FIELD_COUNT", `Tuple field count ${fieldDescs.length} out of range. Must be 1–${DescriptorFormat.MAX_TUPLE_FIELDS}`);
767
898
  const totalFieldBytes = fieldDescs.reduce((sum, f) => sum + f.length, 0);
768
899
  const nodeLength = DescriptorFormat.TUPLE_HEADER_SIZE + totalFieldBytes;
769
- if (nodeLength > DescriptorFormat.MAX_NODE_LENGTH) throw new CallciumError("NODE_LENGTH_TOO_LARGE", `Tuple node length ${nodeLength} exceeds maximum ${DescriptorFormat.MAX_NODE_LENGTH}.`);
900
+ if (nodeLength > DescriptorFormat.MAX_NODE_LENGTH) throw new CallciumError("NODE_LENGTH_TOO_LARGE", `Tuple node length ${nodeLength} exceeds maximum ${DescriptorFormat.MAX_NODE_LENGTH}`);
770
901
  let anyDynamic = false;
771
902
  let staticWordsSum = 0;
772
903
  for (const field of fieldDescs) {
@@ -775,7 +906,7 @@ function tuple(fieldDescs) {
775
906
  staticWordsSum += staticWords;
776
907
  }
777
908
  const staticWords = anyDynamic ? 0 : staticWordsSum;
778
- if (staticWords > DescriptorFormat.MAX_STATIC_WORDS) throw new CallciumError("STATIC_WORDS_TOO_LARGE", `Tuple static words ${staticWords} exceeds maximum ${DescriptorFormat.MAX_STATIC_WORDS}.`);
909
+ if (staticWords > DescriptorFormat.MAX_STATIC_WORDS) throw new CallciumError("STATIC_WORDS_TOO_LARGE", `Tuple static words ${staticWords} exceeds maximum ${DescriptorFormat.MAX_STATIC_WORDS}`);
779
910
  const meta24 = staticWords << DescriptorFormat.META_STATIC_WORDS_SHIFT | nodeLength;
780
911
  const buf = new Uint8Array(1 + DescriptorFormat.COMPOSITE_META_SIZE + DescriptorFormat.TUPLE_FIELDCOUNT_SIZE + totalFieldBytes);
781
912
  buf[0] = TypeCode.TUPLE;
@@ -817,19 +948,19 @@ function parseUint(input, start, end) {
817
948
  function parseTuple(input, start, end) {
818
949
  if (input[start] !== "(") throw new CallciumError("MALFORMED_TYPE_STRING", `Expected '(' at position ${start}`);
819
950
  let depth = 0;
820
- let closePos = -1;
951
+ let closeIndex = -1;
821
952
  for (let i = start; i < end; i++) if (input[i] === "(") depth++;
822
953
  else if (input[i] === ")") {
823
954
  depth--;
824
955
  if (depth === 0) {
825
- closePos = i;
956
+ closeIndex = i;
826
957
  break;
827
958
  }
828
959
  }
829
- if (closePos === -1) throw new CallciumError("MALFORMED_TYPE_STRING", `Unmatched '(' at position ${start}`);
830
- if (closePos !== end - 1) throw new CallciumError("MALFORMED_TYPE_STRING", `Unexpected characters after ')' at position ${closePos + 1}`);
960
+ if (closeIndex === -1) throw new CallciumError("MALFORMED_TYPE_STRING", `Unmatched '(' at position ${start}`);
961
+ if (closeIndex !== end - 1) throw new CallciumError("MALFORMED_TYPE_STRING", `Unexpected characters after ')' at position ${closeIndex + 1}`);
831
962
  const innerStart = start + 1;
832
- const innerEnd = closePos;
963
+ const innerEnd = closeIndex;
833
964
  const commas = commaPositions(input, innerStart, innerEnd);
834
965
  const segments = [];
835
966
  let segStart = innerStart;
@@ -859,14 +990,14 @@ function parseType(input, start, end) {
859
990
  const suffixes = [];
860
991
  let baseEnd = end;
861
992
  while (baseEnd > start && input[baseEnd - 1] === "]") {
862
- const closePos = baseEnd - 1;
863
- let openPos = closePos - 1;
864
- while (openPos > start && input[openPos] !== "[") openPos--;
865
- if (input[openPos] !== "[") throw new CallciumError("MALFORMED_TYPE_STRING", `Unmatched ']' at position ${closePos}`);
866
- const innerStart = openPos + 1;
867
- const innerEnd = closePos;
993
+ const closeIndex = baseEnd - 1;
994
+ let openIndex = closeIndex - 1;
995
+ while (openIndex > start && input[openIndex] !== "[") openIndex--;
996
+ if (input[openIndex] !== "[") throw new CallciumError("MALFORMED_TYPE_STRING", `Unmatched ']' at position ${closeIndex}`);
997
+ const innerStart = openIndex + 1;
998
+ const innerEnd = closeIndex;
868
999
  suffixes.unshift(innerStart === innerEnd ? void 0 : parseUint(input, innerStart, innerEnd));
869
- baseEnd = openPos;
1000
+ baseEnd = openIndex;
870
1001
  }
871
1002
  if (input[start] !== "(" && input.slice(start, baseEnd).includes("[")) throw new CallciumError("MALFORMED_TYPE_STRING", `Unmatched '[' in '${input.slice(start, baseEnd)}'`);
872
1003
  let desc = parseBaseType(input, start, baseEnd);
@@ -884,7 +1015,7 @@ function fromTypes(typesCsv) {
884
1015
  }
885
1016
  segments.push([segStart, typesCsv.length]);
886
1017
  const paramDescs = segments.map(([start, end]) => parseType(typesCsv, start, end));
887
- if (paramDescs.length > DescriptorFormat.MAX_PARAMS) throw new CallciumError("TOO_MANY_PARAMS", `Parameter count ${paramDescs.length} exceeds maximum ${DescriptorFormat.MAX_PARAMS}.`);
1018
+ if (paramDescs.length > DescriptorFormat.MAX_PARAMS) throw new CallciumError("TOO_MANY_PARAMS", `Parameter count ${paramDescs.length} exceeds maximum ${DescriptorFormat.MAX_PARAMS}`);
888
1019
  const totalBytes = paramDescs.reduce((sum, d) => sum + d.length, 0);
889
1020
  const result = new Uint8Array(DescriptorFormat.HEADER_SIZE + totalBytes);
890
1021
  result[0] = DescriptorFormat.VERSION;
@@ -1022,134 +1153,7 @@ const DescriptorCoder = {
1022
1153
  toTypes
1023
1154
  };
1024
1155
  //#endregion
1025
- //#region src/operators.ts
1026
- function toBigInt(bytes, offset = 0) {
1027
- const view = new DataView(bytes.buffer, bytes.byteOffset + offset, 32);
1028
- return view.getBigUint64(0, false) << 192n | view.getBigUint64(8, false) << 128n | view.getBigUint64(16, false) << 64n | view.getBigUint64(24, false);
1029
- }
1030
- function isSigned(typeCode) {
1031
- return typeCode >= TypeCode.INT_MIN && typeCode <= TypeCode.INT_MAX;
1032
- }
1033
- function isLeftAligned(typeCode) {
1034
- return typeCode >= TypeCode.FIXED_BYTES_MIN && typeCode <= TypeCode.FIXED_BYTES_MAX || typeCode === TypeCode.FUNCTION;
1035
- }
1036
- function canonicalize(value, typeCode) {
1037
- if (typeCode >= TypeCode.UINT_MIN && typeCode <= TypeCode.UINT_MAX) {
1038
- const bits = BigInt(typeCode * 8);
1039
- return bits === 256n ? value : value & (1n << bits) - 1n;
1040
- }
1041
- if (typeCode >= TypeCode.INT_MIN && typeCode <= TypeCode.INT_MAX) {
1042
- const bits = (typeCode - TypeCode.INT_MIN + 1) * 8;
1043
- return bits === 256 ? value : BigInt.asUintN(256, BigInt.asIntN(bits, value));
1044
- }
1045
- if (typeCode === TypeCode.ADDRESS) return value & (1n << 160n) - 1n;
1046
- if (typeCode === TypeCode.BOOL) return value & 1n;
1047
- if (typeCode === TypeCode.FUNCTION) return value >> 64n << 64n;
1048
- if (typeCode >= TypeCode.FIXED_BYTES_MIN && typeCode <= TypeCode.FIXED_BYTES_MAX) {
1049
- const n = typeCode - TypeCode.FIXED_BYTES_MIN + 1;
1050
- if (n === 32) return value;
1051
- const padBits = BigInt((32 - n) * 8);
1052
- return value >> padBits << padBits;
1053
- }
1054
- return value;
1055
- }
1056
- function isLengthOp(opCode) {
1057
- const base = opCode & ~Op.NOT;
1058
- return base >= Op.LENGTH_EQ && base <= Op.LENGTH_BETWEEN;
1059
- }
1060
- function lengthToValueOp(base) {
1061
- if (base === Op.LENGTH_EQ) return Op.EQ;
1062
- if (base === Op.LENGTH_GT) return Op.GT;
1063
- if (base === Op.LENGTH_LT) return Op.LT;
1064
- if (base === Op.LENGTH_GTE) return Op.GTE;
1065
- if (base === Op.LENGTH_LTE) return Op.LTE;
1066
- return Op.BETWEEN;
1067
- }
1068
- function isLengthValidType(typeCode) {
1069
- return typeCode === TypeCode.BYTES || typeCode === TypeCode.STRING || typeCode === TypeCode.DYNAMIC_ARRAY;
1070
- }
1071
- function compareTyped(a, b, typeCode) {
1072
- if (isSigned(typeCode)) {
1073
- const sa = BigInt.asIntN(256, a);
1074
- const sb = BigInt.asIntN(256, b);
1075
- return sa < sb ? -1 : sa > sb ? 1 : 0;
1076
- }
1077
- return a < b ? -1 : a > b ? 1 : 0;
1078
- }
1079
- function isIn(value, data) {
1080
- const count = data.length / 32;
1081
- let lo = 0;
1082
- let hi = count - 1;
1083
- while (lo <= hi) {
1084
- const mid = lo + hi >>> 1;
1085
- const elem = toBigInt(data, mid * 32);
1086
- if (value === elem) return true;
1087
- if (value < elem) hi = mid - 1;
1088
- else lo = mid + 1;
1089
- }
1090
- return false;
1091
- }
1092
- function applyOperator(opCode, value, valueLength, operandData, typeCode) {
1093
- let base = opCode & ~Op.NOT;
1094
- if (isLengthOp(base)) {
1095
- value = BigInt(valueLength);
1096
- typeCode = TypeCode.UINT_MAX;
1097
- base = lengthToValueOp(base);
1098
- }
1099
- let result;
1100
- switch (base) {
1101
- case Op.EQ:
1102
- result = value === toBigInt(operandData, 0);
1103
- break;
1104
- case Op.GT:
1105
- result = compareTyped(value, toBigInt(operandData, 0), typeCode) > 0;
1106
- break;
1107
- case Op.LT:
1108
- result = compareTyped(value, toBigInt(operandData, 0), typeCode) < 0;
1109
- break;
1110
- case Op.GTE:
1111
- result = compareTyped(value, toBigInt(operandData, 0), typeCode) >= 0;
1112
- break;
1113
- case Op.LTE:
1114
- result = compareTyped(value, toBigInt(operandData, 0), typeCode) <= 0;
1115
- break;
1116
- case Op.BETWEEN: {
1117
- const min = toBigInt(operandData, 0);
1118
- const max = toBigInt(operandData, 32);
1119
- result = compareTyped(value, min, typeCode) >= 0 && compareTyped(value, max, typeCode) <= 0;
1120
- break;
1121
- }
1122
- case Op.IN:
1123
- result = isIn(value, operandData);
1124
- break;
1125
- case Op.BITMASK_ALL: {
1126
- const mask = toBigInt(operandData, 0);
1127
- result = (value & mask) === mask;
1128
- break;
1129
- }
1130
- case Op.BITMASK_ANY: {
1131
- const mask = toBigInt(operandData, 0);
1132
- result = (value & mask) !== 0n;
1133
- break;
1134
- }
1135
- case Op.BITMASK_NONE: {
1136
- const mask = toBigInt(operandData, 0);
1137
- result = (value & mask) === 0n;
1138
- break;
1139
- }
1140
- default: throw new CallciumError("UNKNOWN_OPERATOR", `Unknown operator code 0x${base.toString(16).padStart(2, "0")}.`);
1141
- }
1142
- return (opCode & Op.NOT) !== 0 ? !result : result;
1143
- }
1144
- //#endregion
1145
1156
  //#region src/policy-coder.ts
1146
- function parsePathSteps(path) {
1147
- const bytes = hexToBytes(path);
1148
- if (bytes.length % PolicyFormat.PATH_STEP_SIZE !== 0) throw new CallciumError("MALFORMED_PATH", `Path byte length ${bytes.length} is not a whole number of steps`);
1149
- const steps = [];
1150
- for (let offset = 0; offset < bytes.length; offset += PolicyFormat.PATH_STEP_SIZE) steps.push(readU16(bytes, offset));
1151
- return steps;
1152
- }
1153
1157
  function field(value, start, end) {
1154
1158
  return {
1155
1159
  value,
@@ -1299,7 +1303,7 @@ function decodePolicy(blob) {
1299
1303
  if (toBigInt(data, dataStart) > BigInt(MAX_CONTEXT_PROPERTY_ID)) throw new CallciumError("UNKNOWN_CONTEXT_PROPERTY", "EQ_CTX operand references an undefined context property", ruleOffset);
1300
1304
  }
1301
1305
  if (depthValue === 0) throw new CallciumError("EMPTY_PATH", "Rule path must have at least one step", ruleOffset);
1302
- if (depthValue > Limits.MAX_PATH_DEPTH) throw new CallciumError("PATH_TOO_DEEP", `Path depth ${depthValue} exceeds maximum ${Limits.MAX_PATH_DEPTH}`, ruleOffset);
1306
+ if (depthValue > PolicyFormat.MAX_PATH_DEPTH) throw new CallciumError("PATH_TOO_DEEP", `Path depth ${depthValue} exceeds maximum ${PolicyFormat.MAX_PATH_DEPTH}`, ruleOffset);
1303
1307
  if (scopeValue === Scope.CONTEXT) {
1304
1308
  if (depthValue !== 1) throw new CallciumError("INVALID_CONTEXT_PATH", "Context-scope rules must have exactly one path step", ruleOffset);
1305
1309
  const contextPropertyId = readU16(data, pathStart);
@@ -1366,12 +1370,12 @@ function decodePolicy(blob) {
1366
1370
  }
1367
1371
  function flattenConstraint(constraint, desc) {
1368
1372
  const operators = constraint.operators.map(hexToBytes);
1369
- for (const operator of operators) if (operator.length < 1) throw new CallciumError("INVALID_OPERATOR_BYTES", "Operator must have at least one byte (opcode).");
1373
+ for (const operator of operators) if (operator.length < 1) throw new CallciumError("INVALID_OPERATOR_BYTES", "Operator must have at least one byte (opcode)");
1370
1374
  const path = hexToBytes(constraint.path);
1371
- if (path.length === 0) throw new CallciumError("EMPTY_PATH", "Rule path must have at least one step.");
1372
- if ((path.length & 1) !== 0) throw new CallciumError("MALFORMED_PATH", "Path byte length must be even.");
1375
+ if (path.length === 0) throw new CallciumError("EMPTY_PATH", "Rule path must have at least one step");
1376
+ if ((path.length & 1) !== 0) throw new CallciumError("MALFORMED_PATH", "Path byte length must be even");
1373
1377
  const depth = path.length / 2;
1374
- if (depth > Limits.MAX_PATH_DEPTH) throw new CallciumError("PATH_TOO_DEEP", `Path depth ${depth} exceeds maximum ${Limits.MAX_PATH_DEPTH}.`);
1378
+ if (depth > PolicyFormat.MAX_PATH_DEPTH) throw new CallciumError("PATH_TOO_DEEP", `Path depth ${depth} exceeds maximum ${PolicyFormat.MAX_PATH_DEPTH}`);
1375
1379
  const hint = constraint.scope === Scope.CALLDATA ? Descriptor.compileHint(desc, parsePathSteps(constraint.path)) : new Uint8Array(0);
1376
1380
  return operators.map((operator) => ({
1377
1381
  scope: constraint.scope,
@@ -1398,7 +1402,7 @@ function sortRules(rules) {
1398
1402
  }
1399
1403
  function encodeRule(rule) {
1400
1404
  const depth = rule.path.length / 2;
1401
- if (rule.scope === Scope.CONTEXT && depth !== 1) throw new CallciumError("INVALID_CONTEXT_PATH", "Context-scope rules must have exactly one path step.");
1405
+ if (rule.scope === Scope.CONTEXT && depth !== 1) throw new CallciumError("INVALID_CONTEXT_PATH", "Context-scope rules must have exactly one path step");
1402
1406
  const data = rule.operator.subarray(1);
1403
1407
  const ruleSize = PolicyFormat.RULE_FIXED_OVERHEAD + rule.path.length + rule.hint.length + data.length;
1404
1408
  if (ruleSize > 65535) throw new CallciumError("RULE_SIZE_OVERFLOW", `Rule size ${ruleSize} exceeds maximum 65535`);
@@ -1743,7 +1747,7 @@ function unsortedInSet(groupIndex, constraintIndex) {
1743
1747
  code: "UNSORTED_IN_SET",
1744
1748
  value1: ZERO,
1745
1749
  value2: ZERO,
1746
- message: "isIn/notIn set is not strictly sorted and deduplicated."
1750
+ message: "isIn/notIn set is not strictly sorted and deduplicated"
1747
1751
  };
1748
1752
  }
1749
1753
  function emptyGroup(groupIndex) {
@@ -1755,7 +1759,7 @@ function emptyGroup(groupIndex) {
1755
1759
  code: "EMPTY_GROUP",
1756
1760
  value1: ZERO,
1757
1761
  value2: ZERO,
1758
- message: "Group contains zero constraints."
1762
+ message: "Group contains zero constraints"
1759
1763
  };
1760
1764
  }
1761
1765
  function dominatedBound(isLength, groupIndex, constraintIndex, value) {
@@ -1940,7 +1944,7 @@ function negationUnderAny(groupIndex, constraintIndex, opCode) {
1940
1944
  }
1941
1945
  //#endregion
1942
1946
  //#region src/policy-validator.ts
1943
- const NAVIGABILITY_CODES = new Set([
1947
+ const navigabilityCodes = new Set([
1944
1948
  "EMPTY_PATH",
1945
1949
  "PARAM_INDEX_OUT_OF_BOUNDS",
1946
1950
  "TUPLE_FIELD_OUT_OF_BOUNDS",
@@ -2418,12 +2422,12 @@ function validateGroup(data, descBytes, groupIndex, issues) {
2418
2422
  const steps = parsePathSteps(constraint.path);
2419
2423
  let typeInfo;
2420
2424
  if (constraint.scope === Scope.CALLDATA) {
2421
- if (steps.length > Limits.MAX_PATH_DEPTH) issues.push(pathDepthExceeded(groupIndex, constraintIndex, bigintToHex(BigInt(steps.length)), bigintToHex(BigInt(Limits.MAX_PATH_DEPTH))));
2425
+ if (steps.length > PolicyFormat.MAX_PATH_DEPTH) issues.push(pathDepthExceeded(groupIndex, constraintIndex, bigintToHex(BigInt(steps.length)), bigintToHex(BigInt(PolicyFormat.MAX_PATH_DEPTH))));
2422
2426
  let walk;
2423
2427
  try {
2424
2428
  walk = Descriptor.walkPath(descBytes, steps);
2425
2429
  } catch (error) {
2426
- if (error instanceof CallciumError && NAVIGABILITY_CODES.has(error.code)) {
2430
+ if (error instanceof CallciumError && navigabilityCodes.has(error.code)) {
2427
2431
  issues.push(unnavigablePath(groupIndex, constraintIndex));
2428
2432
  continue;
2429
2433
  }
@@ -2433,7 +2437,7 @@ function validateGroup(data, descBytes, groupIndex, issues) {
2433
2437
  issues.push(nestedQuantifier(groupIndex, constraintIndex));
2434
2438
  continue;
2435
2439
  }
2436
- if (walk.quantifiedStaticLength > Limits.MAX_QUANTIFIED_ARRAY_LENGTH) issues.push(quantifierOverStaticLimit(groupIndex, constraintIndex, bigintToHex(BigInt(walk.quantifiedStaticLength)), bigintToHex(BigInt(Limits.MAX_QUANTIFIED_ARRAY_LENGTH))));
2440
+ if (walk.quantifiedStaticLength > PolicyFormat.MAX_QUANTIFIED_ARRAY_LENGTH) issues.push(quantifierOverStaticLimit(groupIndex, constraintIndex, bigintToHex(BigInt(walk.quantifiedStaticLength)), bigintToHex(BigInt(PolicyFormat.MAX_QUANTIFIED_ARRAY_LENGTH))));
2437
2441
  typeInfo = walk.typeInfo;
2438
2442
  } else {
2439
2443
  const ctxId = steps[0];
@@ -2453,7 +2457,7 @@ function validateGroup(data, descBytes, groupIndex, issues) {
2453
2457
  ctx = initContext(constraint.scope, normalizedPath, steps, typeInfo);
2454
2458
  contexts.push(ctx);
2455
2459
  }
2456
- if (constraint.scope === Scope.CALLDATA && constraint.hint !== void 0 && ctx.steps.length <= Limits.MAX_PATH_DEPTH) {
2460
+ if (constraint.scope === Scope.CALLDATA && constraint.hint !== void 0 && ctx.steps.length <= PolicyFormat.MAX_PATH_DEPTH) {
2457
2461
  if (bytesToHex(Descriptor.compileHint(descBytes, ctx.steps)) !== constraint.hint.toLowerCase()) issues.push(hintMismatch(groupIndex, constraintIndex));
2458
2462
  }
2459
2463
  validateConstraint(ctx, constraint, groupIndex, constraintIndex, issues);
@@ -2510,14 +2514,14 @@ const SignatureParser = { parse };
2510
2514
  //#endregion
2511
2515
  //#region src/policy-builder.ts
2512
2516
  function validateContextPath(steps) {
2513
- if (steps.length !== 1) throw new CallciumError("INVALID_CONTEXT_PATH", "Context-scope path must be exactly one step.");
2517
+ if (steps.length !== 1) throw new CallciumError("INVALID_CONTEXT_PATH", "Context-scope path must be exactly one step");
2514
2518
  const step = steps[0];
2515
- if (step > MAX_CONTEXT_PROPERTY_ID) throw new CallciumError("UNKNOWN_CONTEXT_PROPERTY", `Unknown context property ID 0x${step.toString(16).padStart(4, "0")}.`);
2519
+ if (step > MAX_CONTEXT_PROPERTY_ID) throw new CallciumError("UNKNOWN_CONTEXT_PROPERTY", `Unknown context property ID 0x${step.toString(16).padStart(4, "0")}`);
2516
2520
  }
2517
2521
  function validateCalldataPath(steps, desc) {
2518
2522
  const argIndex = steps[0];
2519
2523
  const paramCount = Descriptor.paramCount(desc);
2520
- if (argIndex >= paramCount) throw new CallciumError("PARAM_INDEX_OUT_OF_BOUNDS", `Param index ${argIndex} out of range (descriptor has ${paramCount} params).`);
2524
+ if (argIndex >= paramCount) throw new CallciumError("PARAM_INDEX_OUT_OF_BOUNDS", `Param index ${argIndex} out of range (descriptor has ${paramCount} params)`);
2521
2525
  let offset = Descriptor.paramOffset(desc, argIndex);
2522
2526
  let hasQuantifier = false;
2523
2527
  for (let i = 1; i < steps.length; i++) {
@@ -2525,21 +2529,21 @@ function validateCalldataPath(steps, desc) {
2525
2529
  const info = Descriptor.inspect(desc, offset);
2526
2530
  const isArray = info.typeCode === TypeCode.STATIC_ARRAY || info.typeCode === TypeCode.DYNAMIC_ARRAY;
2527
2531
  if (isQuantifier(step)) {
2528
- if (!isArray) throw new CallciumError("QUANTIFIER_ON_NON_ARRAY", "Quantifier step is only valid on an array node.");
2529
- if (hasQuantifier) throw new CallciumError("NESTED_QUANTIFIER", "Nested quantifiers are not allowed.");
2532
+ if (!isArray) throw new CallciumError("QUANTIFIER_ON_NON_ARRAY", "Quantifier step is only valid on an array node");
2533
+ if (hasQuantifier) throw new CallciumError("NESTED_QUANTIFIER", "Nested quantifiers are not allowed");
2530
2534
  hasQuantifier = true;
2531
2535
  }
2532
2536
  if (info.typeCode === TypeCode.TUPLE) {
2533
2537
  const fieldCount = Descriptor.tupleFieldCount(desc, offset);
2534
- if (step >= fieldCount) throw new CallciumError("TUPLE_FIELD_OUT_OF_BOUNDS", `Tuple field index ${step} out of range (tuple has ${fieldCount} fields).`);
2538
+ if (step >= fieldCount) throw new CallciumError("TUPLE_FIELD_OUT_OF_BOUNDS", `Tuple field index ${step} out of range (tuple has ${fieldCount} fields)`);
2535
2539
  offset = Descriptor.tupleFieldOffset(desc, offset, step);
2536
2540
  } else if (isArray) {
2537
2541
  if (!isQuantifier(step) && info.typeCode === TypeCode.STATIC_ARRAY) {
2538
2542
  const arrayLength = Descriptor.staticArrayLength(desc, offset);
2539
- if (step >= arrayLength) throw new CallciumError("STATIC_ARRAY_INDEX_OUT_OF_BOUNDS", `Array index ${step} out of range (static array has ${arrayLength} elements).`);
2543
+ if (step >= arrayLength) throw new CallciumError("STATIC_ARRAY_INDEX_OUT_OF_BOUNDS", `Array index ${step} out of range (static array has ${arrayLength} elements)`);
2540
2544
  }
2541
2545
  offset = Descriptor.arrayElementOffset(offset);
2542
- } else throw new CallciumError("NOT_COMPOSITE", "Cannot descend into an elementary type.");
2546
+ } else throw new CallciumError("NOT_COMPOSITE", "Cannot descend into an elementary type");
2543
2547
  }
2544
2548
  }
2545
2549
  var PolicyBuilder = class PolicyBuilder {
@@ -2573,21 +2577,21 @@ var PolicyBuilder = class PolicyBuilder {
2573
2577
  path: constraint.path,
2574
2578
  operators: [...constraint.operators]
2575
2579
  };
2576
- if (c.operators.length === 0) throw new CallciumError("NO_CONSTRAINT_OPERATORS", "Constraint must have at least one operator.");
2580
+ if (c.operators.length === 0) throw new CallciumError("NO_CONSTRAINT_OPERATORS", "Constraint must have at least one operator");
2577
2581
  const steps = parsePathSteps(c.path);
2578
- if (steps.length === 0) throw new CallciumError("EMPTY_PATH", "Path must have at least one step.");
2582
+ if (steps.length === 0) throw new CallciumError("EMPTY_PATH", "Path must have at least one step");
2579
2583
  if (c.scope === Scope.CONTEXT) validateContextPath(steps);
2580
2584
  else if (c.scope === Scope.CALLDATA) validateCalldataPath(steps, this.draft.descriptor);
2581
- else throw new CallciumError("INVALID_SCOPE", `Unknown scope value ${c.scope}.`);
2585
+ else throw new CallciumError("INVALID_SCOPE", `Unknown scope value ${c.scope}`);
2582
2586
  const key = `${c.scope}:${c.path.toLowerCase()}`;
2583
2587
  const currentHashes = this.draft.pathHashes[this.draft.pathHashes.length - 1];
2584
- if (currentHashes.has(key)) throw new CallciumError("DUPLICATE_PATH_IN_GROUP", `Duplicate path ${c.path} in the same group.`);
2588
+ if (currentHashes.has(key)) throw new CallciumError("DUPLICATE_PATH_IN_GROUP", `Duplicate path ${c.path} in the same group`);
2585
2589
  currentHashes.add(key);
2586
2590
  this.draft.groups[this.draft.groups.length - 1].push(c);
2587
2591
  return this;
2588
2592
  }
2589
2593
  or() {
2590
- if (this.draft.groups[this.draft.groups.length - 1].length === 0) throw new CallciumError("EMPTY_GROUP", "Cannot start a new group when the current group is empty.");
2594
+ if (this.draft.groups[this.draft.groups.length - 1].length === 0) throw new CallciumError("EMPTY_GROUP", "Cannot start a new group when the current group is empty");
2591
2595
  this.draft.groups.push([]);
2592
2596
  this.draft.pathHashes.push(/* @__PURE__ */ new Set());
2593
2597
  return this;
@@ -2609,7 +2613,7 @@ var PolicyBuilder = class PolicyBuilder {
2609
2613
  return PolicyValidator.validate(policyData);
2610
2614
  }
2611
2615
  checkGroups() {
2612
- for (let i = 0; i < this.draft.groups.length; i++) if (this.draft.groups[i].length === 0) throw new CallciumError("EMPTY_GROUP", `Group ${i} is empty.`);
2616
+ for (let i = 0; i < this.draft.groups.length; i++) if (this.draft.groups[i].length === 0) throw new CallciumError("EMPTY_GROUP", `Group ${i} is empty`);
2613
2617
  }
2614
2618
  toPolicyData() {
2615
2619
  return {
@@ -2632,8 +2636,7 @@ function encodeWord(value) {
2632
2636
  return word;
2633
2637
  }
2634
2638
  if (typeof value === "string") {
2635
- const body = addressBody(value);
2636
- for (let i = 0; i < 20; i++) word[12 + i] = parseInt(body.substring(i * 2, i * 2 + 2), 16);
2639
+ word.set(hexToBytes(addressBody(value)), 12);
2637
2640
  return word;
2638
2641
  }
2639
2642
  let bigValue = typeof value === "number" ? BigInt(value) : value;
@@ -2661,7 +2664,6 @@ function checkContextPropertyId(contextPropertyId) {
2661
2664
  if (!Number.isInteger(contextPropertyId) || contextPropertyId < 0 || contextPropertyId > MAX_CONTEXT_PROPERTY_ID) throw new CallciumError("UNKNOWN_CONTEXT_PROPERTY", `Unknown context property ID ${contextPropertyId}`);
2662
2665
  return contextPropertyId;
2663
2666
  }
2664
- const MAX_SET_MEMBERS = Limits.MAX_SET_MEMBERS;
2665
2667
  function setOp(opCode, values) {
2666
2668
  const bigs = values.map((v) => {
2667
2669
  if (typeof v === "bigint") return v;
@@ -2669,21 +2671,14 @@ function setOp(opCode, values) {
2669
2671
  if (typeof v === "boolean") return v ? 1n : 0n;
2670
2672
  return BigInt("0x" + addressBody(v));
2671
2673
  });
2672
- bigs.sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
2673
- const deduped = [];
2674
- for (const value of bigs) if (deduped.length === 0 || deduped[deduped.length - 1] !== value) deduped.push(value);
2674
+ const deduped = [...new Set(bigs)].toSorted((a, b) => a < b ? -1 : a > b ? 1 : 0);
2675
2675
  if (deduped.length === 0) throw new CallciumError("EMPTY_SET", "Set must contain at least one value");
2676
- if (deduped.length > MAX_SET_MEMBERS) throw new CallciumError("SET_TOO_LARGE", `Set must contain at most ${MAX_SET_MEMBERS} values`);
2676
+ if (deduped.length > PolicyFormat.MAX_SET_MEMBERS) throw new CallciumError("SET_TOO_LARGE", `Set must contain at most ${PolicyFormat.MAX_SET_MEMBERS} values`);
2677
2677
  const buffer = new Uint8Array(1 + deduped.length * 32);
2678
2678
  buffer[0] = opCode;
2679
2679
  for (let i = 0; i < deduped.length; i++) buffer.set(encodeWord(deduped[i]), 1 + i * 32);
2680
2680
  return bytesToHex(buffer);
2681
2681
  }
2682
- function encodePath(steps) {
2683
- const buffer = new Uint8Array(steps.length * 2);
2684
- for (let i = 0; i < steps.length; i++) writeBE16(buffer, i * 2, steps[i]);
2685
- return bytesToHex(buffer);
2686
- }
2687
2682
  var ConstraintBuilder = class {
2688
2683
  scope;
2689
2684
  path;
@@ -2801,17 +2796,14 @@ function readPointer(callData, head) {
2801
2796
  }
2802
2797
  //#endregion
2803
2798
  //#region src/policy-enforcer.ts
2804
- const ABORT_VIOLATION_CODES = new Set([
2799
+ const abortViolationCodes = new Set([
2805
2800
  "CALLDATA_OUT_OF_BOUNDS",
2806
2801
  "ARRAY_INDEX_OUT_OF_BOUNDS",
2807
2802
  "NON_CANONICAL_VALUE",
2808
2803
  "QUANTIFIER_LIMIT_EXCEEDED"
2809
2804
  ]);
2810
2805
  function addressToBigInt(hex) {
2811
- const bytes = hexToBytes(hex);
2812
- const padded = new Uint8Array(32);
2813
- padded.set(bytes, 32 - bytes.length);
2814
- return toBigInt(padded, 0);
2806
+ return BigInt(toAddress(hex));
2815
2807
  }
2816
2808
  function check(policy, callData, context) {
2817
2809
  const { policy: decoded, data: policyBytes } = decodePolicy(policy);
@@ -2842,7 +2834,7 @@ function check(policy, callData, context) {
2842
2834
  const violation = evaluateRule(rule, policyBytes, callDataBytes, baseOffset, groupIndex, ruleIndex, context);
2843
2835
  if (violation !== null) {
2844
2836
  allViolations.push(violation);
2845
- if (ABORT_VIOLATION_CODES.has(violation.code)) return {
2837
+ if (abortViolationCodes.has(violation.code)) return {
2846
2838
  ok: false,
2847
2839
  violations: allViolations
2848
2840
  };
@@ -2875,9 +2867,9 @@ function evaluateRule(rule, policyBytes, callDataBytes, baseOffset, groupIndex,
2875
2867
  return evaluateCalldataRule(fieldBytes(policyBytes, rule.hint), callDataBytes, baseOffset, opCode, operandData, groupIndex, ruleIndex, rule.path.value, context);
2876
2868
  }
2877
2869
  function resolveContextOperand(operandData, context) {
2878
- const propInfo = lookupContextProperty(Number(toBigInt(operandData, 0)));
2879
- const value = context?.[propInfo.contextKey];
2880
- if (value === void 0) return { ctxTypeCode: propInfo.typeCode };
2870
+ const propertyInfo = lookupContextProperty(Number(toBigInt(operandData, 0)));
2871
+ const value = context?.[propertyInfo.contextKey];
2872
+ if (value === void 0) return { ctxTypeCode: propertyInfo.typeCode };
2881
2873
  return typeof value === "string" ? addressToBigInt(value) : value;
2882
2874
  }
2883
2875
  function readTargetBlock(hint, targetOffset) {
@@ -2922,7 +2914,7 @@ function chainResolve(hint, callData, base, hopsOffset, hopCount) {
2922
2914
  function evalTarget(callData, target, block, opCode, operandData, context) {
2923
2915
  const typeCode = block.typeCode;
2924
2916
  if (isLengthValidType(typeCode)) {
2925
- if (!isLengthOp(opCode)) throw new CallciumError("OPERATOR_TARGET_MISMATCH", "Value operator on a target without a scalar word.");
2917
+ if (!isLengthOp(opCode)) throw new CallciumError("OPERATOR_TARGET_MISMATCH", "Value operator on a target without a scalar word");
2926
2918
  const length = readPointer(callData, target);
2927
2919
  if (typeof length !== "number") return { error: length.code };
2928
2920
  const stride = typeCode === TypeCode.DYNAMIC_ARRAY ? (block.targetMeta & PolicyFormat.HINT_META_STRIDE_MASK) * 32 : 1;
@@ -2933,7 +2925,7 @@ function evalTarget(callData, target, block, opCode, operandData, context) {
2933
2925
  value: BigInt(length)
2934
2926
  };
2935
2927
  }
2936
- if (classifyTypeCode(typeCode).typeClass !== "elementary") throw new CallciumError("OPERATOR_TARGET_MISMATCH", "Operator target does not carry a scalar word.");
2928
+ if (classifyTypeCode(typeCode).typeClass !== "elementary") throw new CallciumError("OPERATOR_TARGET_MISMATCH", "Operator target does not carry a scalar word");
2937
2929
  const word = loadWord(callData, target);
2938
2930
  if (!(word instanceof Uint8Array)) return { error: word.code };
2939
2931
  const value = toBigInt(word, 0);
@@ -3055,7 +3047,7 @@ function evaluateQuantified(hint, callDataBytes, baseOffset, kind, hopsOffset, h
3055
3047
  count = length;
3056
3048
  elems += 32;
3057
3049
  }
3058
- if (count > Limits.MAX_QUANTIFIED_ARRAY_LENGTH) return {
3050
+ if (count > PolicyFormat.MAX_QUANTIFIED_ARRAY_LENGTH) return {
3059
3051
  group: groupIndex,
3060
3052
  rule: ruleIndex,
3061
3053
  code: "QUANTIFIER_LIMIT_EXCEEDED",
@@ -3115,15 +3107,15 @@ function evaluateQuantified(hint, callDataBytes, baseOffset, kind, hopsOffset, h
3115
3107
  function evaluateContextRule(pathBytes, opCode, operandData, groupIndex, ruleIndex, pathHex, context) {
3116
3108
  const propertyId = readU16(pathBytes, 0);
3117
3109
  if (propertyId > MAX_CONTEXT_PROPERTY_ID) throw new CallciumError("UNKNOWN_CONTEXT_PROPERTY", `Unknown context property ID 0x${propertyId.toString(16).padStart(4, "0")}`);
3118
- const propInfo = lookupContextProperty(propertyId);
3119
- const contextValue = context?.[propInfo.contextKey];
3110
+ const propertyInfo = lookupContextProperty(propertyId);
3111
+ const contextValue = context?.[propertyInfo.contextKey];
3120
3112
  if (contextValue === void 0) return {
3121
3113
  group: groupIndex,
3122
3114
  rule: ruleIndex,
3123
3115
  code: "MISSING_CONTEXT",
3124
3116
  scope: Scope.CONTEXT,
3125
3117
  path: pathHex,
3126
- typeCode: propInfo.typeCode
3118
+ typeCode: propertyInfo.typeCode
3127
3119
  };
3128
3120
  let value;
3129
3121
  if (typeof contextValue === "string") value = addressToBigInt(contextValue);
@@ -3144,7 +3136,7 @@ function evaluateContextRule(pathBytes, opCode, operandData, groupIndex, ruleInd
3144
3136
  };
3145
3137
  result = value === operand !== ((opCode & Op.NOT) !== 0);
3146
3138
  ctxOperand = operand;
3147
- } else result = applyOperator(opCode, value, 32, operandData, propInfo.typeCode);
3139
+ } else result = applyOperator(opCode, value, 32, operandData, propertyInfo.typeCode);
3148
3140
  if (!result) return {
3149
3141
  group: groupIndex,
3150
3142
  rule: ruleIndex,
@@ -3153,7 +3145,7 @@ function evaluateContextRule(pathBytes, opCode, operandData, groupIndex, ruleInd
3153
3145
  path: pathHex,
3154
3146
  opCode,
3155
3147
  operandData: bytesToHex(operandData),
3156
- typeCode: propInfo.typeCode,
3148
+ typeCode: propertyInfo.typeCode,
3157
3149
  resolvedValue: bigintToHex(value),
3158
3150
  ...ctxOperand !== void 0 && { resolvedOperand: bigintToHex(ctxOperand) }
3159
3151
  };
@@ -3164,6 +3156,6 @@ const PolicyEnforcer = {
3164
3156
  enforce
3165
3157
  };
3166
3158
  //#endregion
3167
- export { CallciumError, ContextProperty, Descriptor, DescriptorCoder, Limits, MAX_CONTEXT_PROPERTY_ID, Op, PolicyBuilder, PolicyCoder, PolicyEnforcer, PolicyFormat, PolicyValidator, PolicyViolationError, Quantifier, Scope, TypeCode, ValidationError, arg, baseFee, blockNumber, blockTimestamp, bytesToHex, chainId, gasPrice, hexToBytes, isLengthOp, isOpAllowed, isQuantifier, lookupContextProperty, lookupOp, lookupQuantifier, lookupScope, lookupTypeCode, msgSender, msgValue, parsePathSteps, toAddress, txOrigin };
3159
+ export { CallciumError, ContextProperty, Descriptor, DescriptorCoder, MAX_CONTEXT_PROPERTY_ID, Op, PolicyBuilder, PolicyCoder, PolicyEnforcer, PolicyFormat, PolicyValidator, PolicyViolationError, Quantifier, Scope, TypeCode, ValidationError, arg, baseFee, blockNumber, blockTimestamp, bytesToHex, chainId, gasPrice, hexToBytes, isLengthOp, isOpAllowed, isQuantifier, lookupContextProperty, lookupOp, lookupQuantifier, lookupScope, lookupTypeCode, msgSender, msgValue, parsePathSteps, toAddress, txOrigin };
3168
3160
 
3169
3161
  //# sourceMappingURL=index.js.map