@aztec/foundation 0.0.1-commit.aada20e3 → 0.0.1-commit.b33fc05d0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/dest/array/sorted_array.d.ts +6 -1
  2. package/dest/array/sorted_array.d.ts.map +1 -1
  3. package/dest/array/sorted_array.js +18 -15
  4. package/dest/config/env_var.d.ts +2 -2
  5. package/dest/config/env_var.d.ts.map +1 -1
  6. package/dest/config/index.d.ts +1 -1
  7. package/dest/config/index.d.ts.map +1 -1
  8. package/dest/config/index.js +15 -0
  9. package/dest/config/network_config.d.ts +13 -1
  10. package/dest/config/network_config.d.ts.map +1 -1
  11. package/dest/config/network_config.js +3 -1
  12. package/dest/config/network_name.d.ts +2 -2
  13. package/dest/config/network_name.d.ts.map +1 -1
  14. package/dest/config/network_name.js +2 -0
  15. package/dest/crypto/poseidon/index.js +13 -13
  16. package/dest/crypto/secp256k1-signer/utils.d.ts +12 -1
  17. package/dest/crypto/secp256k1-signer/utils.d.ts.map +1 -1
  18. package/dest/crypto/secp256k1-signer/utils.js +26 -0
  19. package/dest/curves/bn254/field.d.ts +2 -1
  20. package/dest/curves/bn254/field.d.ts.map +1 -1
  21. package/dest/curves/bn254/field.js +5 -2
  22. package/dest/eth-signature/eth_signature.d.ts +2 -1
  23. package/dest/eth-signature/eth_signature.d.ts.map +1 -1
  24. package/dest/eth-signature/eth_signature.js +7 -2
  25. package/dest/jest/setup.js +24 -0
  26. package/dest/json-rpc/client/safe_json_rpc_client.d.ts +2 -1
  27. package/dest/json-rpc/client/safe_json_rpc_client.d.ts.map +1 -1
  28. package/dest/json-rpc/client/safe_json_rpc_client.js +1 -1
  29. package/dest/json-rpc/server/api_key_auth.d.ts +19 -0
  30. package/dest/json-rpc/server/api_key_auth.d.ts.map +1 -0
  31. package/dest/json-rpc/server/api_key_auth.js +57 -0
  32. package/dest/json-rpc/server/index.d.ts +2 -1
  33. package/dest/json-rpc/server/index.d.ts.map +1 -1
  34. package/dest/json-rpc/server/index.js +1 -0
  35. package/dest/log/bigint-utils.d.ts +5 -0
  36. package/dest/log/bigint-utils.d.ts.map +1 -0
  37. package/dest/log/bigint-utils.js +21 -0
  38. package/dest/log/gcloud-logger-config.d.ts +1 -1
  39. package/dest/log/gcloud-logger-config.d.ts.map +1 -1
  40. package/dest/log/gcloud-logger-config.js +3 -0
  41. package/dest/log/log-filters.d.ts +17 -4
  42. package/dest/log/log-filters.d.ts.map +1 -1
  43. package/dest/log/log-filters.js +26 -12
  44. package/dest/log/pino-logger.d.ts +1 -1
  45. package/dest/log/pino-logger.d.ts.map +1 -1
  46. package/dest/log/pino-logger.js +6 -2
  47. package/dest/queue/base_memory_queue.d.ts +2 -2
  48. package/dest/queue/base_memory_queue.d.ts.map +1 -1
  49. package/dest/serialize/buffer_reader.d.ts +8 -1
  50. package/dest/serialize/buffer_reader.d.ts.map +1 -1
  51. package/dest/serialize/buffer_reader.js +13 -0
  52. package/dest/serialize/serialize.d.ts +19 -1
  53. package/dest/serialize/serialize.d.ts.map +1 -1
  54. package/dest/serialize/serialize.js +31 -0
  55. package/dest/sleep/index.d.ts +2 -1
  56. package/dest/sleep/index.d.ts.map +1 -1
  57. package/dest/sleep/index.js +10 -1
  58. package/dest/timer/date.d.ts +3 -1
  59. package/dest/timer/date.d.ts.map +1 -1
  60. package/dest/timer/date.js +4 -0
  61. package/dest/transport/transport_client.js +2 -2
  62. package/package.json +22 -2
  63. package/src/array/sorted_array.ts +22 -17
  64. package/src/config/env_var.ts +37 -7
  65. package/src/config/index.ts +15 -0
  66. package/src/config/network_config.ts +2 -0
  67. package/src/config/network_name.ts +4 -1
  68. package/src/crypto/poseidon/index.ts +13 -13
  69. package/src/crypto/secp256k1-signer/utils.ts +32 -0
  70. package/src/curves/bn254/field.ts +6 -2
  71. package/src/eth-signature/eth_signature.ts +7 -1
  72. package/src/jest/setup.mjs +27 -0
  73. package/src/json-rpc/client/safe_json_rpc_client.ts +2 -0
  74. package/src/json-rpc/server/api_key_auth.ts +63 -0
  75. package/src/json-rpc/server/index.ts +1 -0
  76. package/src/log/bigint-utils.ts +25 -0
  77. package/src/log/gcloud-logger-config.ts +5 -0
  78. package/src/log/log-filters.ts +29 -11
  79. package/src/log/pino-logger.ts +6 -2
  80. package/src/queue/base_memory_queue.ts +1 -1
  81. package/src/serialize/buffer_reader.ts +15 -0
  82. package/src/serialize/serialize.ts +32 -0
  83. package/src/sleep/index.ts +10 -1
  84. package/src/timer/date.ts +6 -0
  85. package/src/transport/transport_client.ts +2 -2
@@ -176,6 +176,20 @@ import { numToUInt32BE } from './free_funcs.js';
176
176
  */ export function serializeBigInt(n, width = 32) {
177
177
  return toBufferBE(n, width);
178
178
  }
179
+ /**
180
+ * Serialize a signed BigInt value into a Buffer of specified width using two's complement.
181
+ * @param n - The signed BigInt value to be serialized.
182
+ * @param width - The width (in bytes) of the output Buffer, optional with default value 32.
183
+ * @returns A Buffer containing the serialized signed BigInt value in big-endian format.
184
+ */ export function serializeSignedBigInt(n, width = 32) {
185
+ const widthBits = BigInt(width * 8);
186
+ const max = 1n << widthBits - 1n;
187
+ if (n < -max || n >= max) {
188
+ throw new Error(`Signed BigInt ${n.toString()} does not fit into ${width} bytes`);
189
+ }
190
+ const unsigned = n < 0n ? (1n << widthBits) + n : n;
191
+ return toBufferBE(unsigned, width);
192
+ }
179
193
  /**
180
194
  * Deserialize a big integer from a buffer, given an offset and width.
181
195
  * Reads the specified number of bytes from the buffer starting at the offset, converts it to a big integer, and returns the deserialized result along with the number of bytes read (advanced).
@@ -190,6 +204,23 @@ import { numToUInt32BE } from './free_funcs.js';
190
204
  adv: width
191
205
  };
192
206
  }
207
+ /**
208
+ * Deserialize a signed BigInt from a buffer (two's complement).
209
+ * @param buf - The buffer containing the signed big integer to be deserialized.
210
+ * @param offset - The position in the buffer where the integer starts. Defaults to 0.
211
+ * @param width - The number of bytes to read from the buffer for the integer. Defaults to 32.
212
+ * @returns An object containing the deserialized signed bigint value ('elem') and bytes advanced ('adv').
213
+ */ export function deserializeSignedBigInt(buf, offset = 0, width = 32) {
214
+ const { elem, adv } = deserializeBigInt(buf, offset, width);
215
+ const widthBits = BigInt(width * 8);
216
+ const signBit = 1n << widthBits - 1n;
217
+ const fullRange = 1n << widthBits;
218
+ const signed = elem >= signBit ? elem - fullRange : elem;
219
+ return {
220
+ elem: signed,
221
+ adv
222
+ };
223
+ }
193
224
  /**
194
225
  * Serializes a Date object into a Buffer containing its timestamp as a big integer value.
195
226
  * The resulting Buffer has a fixed width of 8 bytes, representing a 64-bit big-endian integer.
@@ -20,6 +20,7 @@
20
20
  */
21
21
  export declare class InterruptibleSleep {
22
22
  private interrupts;
23
+ private timeoutIds;
23
24
  /**
24
25
  * Sleep for a specified amount of time in milliseconds.
25
26
  * The sleep function will pause the execution of the current async function
@@ -50,4 +51,4 @@ export declare class InterruptibleSleep {
50
51
  export declare function sleep<T>(ms: number, returnValue?: T): Promise<T>;
51
52
  /** Sleeps until the target date */
52
53
  export declare function sleepUntil<T>(target: Date, now: Date, returnValue?: T): Promise<T>;
53
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zbGVlcC9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQTs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW1CRztBQUNILHFCQUFhLGtCQUFrQjtJQUM3QixPQUFPLENBQUMsVUFBVSxDQUE2QztJQUUvRDs7Ozs7OztPQU9HO0lBQ1UsS0FBSyxDQUFDLEVBQUUsRUFBRSxNQUFNLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxDQWU1QztJQUVEOzs7Ozs7T0FNRztJQUNJLFNBQVMsQ0FBQyxnQkFBZ0IsVUFBUSxHQUFHLElBQUksQ0FHL0M7Q0FDRjtBQUVEOzs7Ozs7OztHQVFHO0FBQ0gsd0JBQWdCLEtBQUssQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLE1BQU0sRUFBRSxXQUFXLENBQUMsRUFBRSxDQUFDLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUVoRTtBQUVELG1DQUFtQztBQUNuQyx3QkFBZ0IsVUFBVSxDQUFDLENBQUMsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsV0FBVyxDQUFDLEVBQUUsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FHbEYifQ==
54
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zbGVlcC9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQTs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW1CRztBQUNILHFCQUFhLGtCQUFrQjtJQUM3QixPQUFPLENBQUMsVUFBVSxDQUE2QztJQUMvRCxPQUFPLENBQUMsVUFBVSxDQUF3QjtJQUUxQzs7Ozs7OztPQU9HO0lBQ1UsS0FBSyxDQUFDLEVBQUUsRUFBRSxNQUFNLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxDQXFCNUM7SUFFRDs7Ozs7O09BTUc7SUFDSSxTQUFTLENBQUMsZ0JBQWdCLFVBQVEsR0FBRyxJQUFJLENBSy9DO0NBQ0Y7QUFFRDs7Ozs7Ozs7R0FRRztBQUNILHdCQUFnQixLQUFLLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxNQUFNLEVBQUUsV0FBVyxDQUFDLEVBQUUsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FFaEU7QUFFRCxtQ0FBbUM7QUFDbkMsd0JBQWdCLFVBQVUsQ0FBQyxDQUFDLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLFdBQVcsQ0FBQyxFQUFFLENBQUMsR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBR2xGIn0=
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sleep/index.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,UAAU,CAA6C;IAE/D;;;;;;;OAOG;IACU,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAe5C;IAED;;;;;;OAMG;IACI,SAAS,CAAC,gBAAgB,UAAQ,GAAG,IAAI,CAG/C;CACF;AAED;;;;;;;;GAQG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAEhE;AAED,mCAAmC;AACnC,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,WAAW,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAGlF"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sleep/index.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,UAAU,CAA6C;IAC/D,OAAO,CAAC,UAAU,CAAwB;IAE1C;;;;;;;OAOG;IACU,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAqB5C;IAED;;;;;;OAMG;IACI,SAAS,CAAC,gBAAgB,UAAQ,GAAG,IAAI,CAK/C;CACF;AAED;;;;;;;;GAQG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAEhE;AAED,mCAAmC;AACnC,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,WAAW,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAGlF"}
@@ -20,6 +20,7 @@ import { InterruptError } from '../error/index.js';
20
20
  * setTimeout(() =\> sleeper.interrupt(true), 1500); // Interrupt the sleep after 1.5 seconds
21
21
  */ export class InterruptibleSleep {
22
22
  interrupts = [];
23
+ timeoutIds = [];
23
24
  /**
24
25
  * Sleep for a specified amount of time in milliseconds.
25
26
  * The sleep function will pause the execution of the current async function
@@ -33,11 +34,17 @@ import { InterruptError } from '../error/index.js';
33
34
  interruptResolve = resolve;
34
35
  this.interrupts.push(resolve);
35
36
  });
36
- const timeoutPromise = new Promise((resolve)=>setTimeout(()=>resolve(false), ms));
37
+ let timeoutId;
38
+ const timeoutPromise = new Promise((resolve)=>{
39
+ timeoutId = setTimeout(()=>resolve(false), ms);
40
+ this.timeoutIds.push(timeoutId);
41
+ });
37
42
  const shouldThrow = await Promise.race([
38
43
  interruptPromise,
39
44
  timeoutPromise
40
45
  ]);
46
+ clearTimeout(timeoutId);
47
+ this.timeoutIds = this.timeoutIds.filter((id)=>id !== timeoutId);
41
48
  this.interrupts = this.interrupts.filter((res)=>res !== interruptResolve);
42
49
  if (shouldThrow) {
43
50
  throw new InterruptError('Interrupted.');
@@ -52,6 +59,8 @@ import { InterruptError } from '../error/index.js';
52
59
  */ interrupt(sleepShouldThrow = false) {
53
60
  this.interrupts.forEach((resolve)=>resolve(sleepShouldThrow));
54
61
  this.interrupts = [];
62
+ this.timeoutIds.forEach((id)=>clearTimeout(id));
63
+ this.timeoutIds = [];
55
64
  }
56
65
  }
57
66
  /**
@@ -11,6 +11,8 @@ export declare class TestDateProvider extends DateProvider {
11
11
  constructor(logger?: import("../log/pino-logger.js").Logger);
12
12
  now(): number;
13
13
  setTime(timeMs: number): void;
14
+ /** Resets the time back to real time (offset = 0). */
15
+ reset(): void;
14
16
  /** Advances the time by the given number of seconds. */
15
17
  advanceTime(seconds: number): void;
16
18
  }
@@ -34,4 +36,4 @@ export declare class ManualDateProvider extends DateProvider {
34
36
  /** Advances the time by the given number of milliseconds. */
35
37
  advanceTimeMs(ms: number): void;
36
38
  }
37
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0ZS5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3RpbWVyL2RhdGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsZ0NBQWdDO0FBQ2hDLHFCQUFhLFlBQVk7SUFDaEIsR0FBRyxJQUFJLE1BQU0sQ0FFbkI7SUFFTSxZQUFZLElBQUksTUFBTSxDQUU1QjtJQUVNLFNBQVMsSUFBSSxJQUFJLENBRXZCO0NBQ0Y7QUFFRCwwREFBMEQ7QUFDMUQscUJBQWEsZ0JBQWlCLFNBQVEsWUFBWTtJQUdwQyxPQUFPLENBQUMsUUFBUSxDQUFDLE1BQU07SUFGbkMsT0FBTyxDQUFDLE1BQU0sQ0FBSztJQUVuQixZQUE2QixNQUFNLHlDQUFnRCxFQUVsRjtJQUVlLEdBQUcsSUFBSSxNQUFNLENBRTVCO0lBRU0sT0FBTyxDQUFDLE1BQU0sRUFBRSxNQUFNLFFBRzVCO0lBRUQsd0RBQXdEO0lBQ2pELFdBQVcsQ0FBQyxPQUFPLEVBQUUsTUFBTSxRQUVqQztDQUNGO0FBRUQ7Ozs7O0dBS0c7QUFDSCxxQkFBYSxrQkFBbUIsU0FBUSxZQUFZO0lBQ2xELE9BQU8sQ0FBQyxhQUFhLENBQVM7SUFFOUI7O09BRUc7SUFDSCxZQUFZLGFBQWEsR0FBRSxNQUFzQyxFQUdoRTtJQUVlLEdBQUcsSUFBSSxNQUFNLENBRTVCO0lBRUQsb0VBQW9FO0lBQzdELE9BQU8sQ0FBQyxNQUFNLEVBQUUsTUFBTSxRQUU1QjtJQUVELHdEQUF3RDtJQUNqRCxXQUFXLENBQUMsT0FBTyxFQUFFLE1BQU0sUUFFakM7SUFFRCw2REFBNkQ7SUFDdEQsYUFBYSxDQUFDLEVBQUUsRUFBRSxNQUFNLFFBRTlCO0NBQ0YifQ==
39
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0ZS5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3RpbWVyL2RhdGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsZ0NBQWdDO0FBQ2hDLHFCQUFhLFlBQVk7SUFDaEIsR0FBRyxJQUFJLE1BQU0sQ0FFbkI7SUFFTSxZQUFZLElBQUksTUFBTSxDQUU1QjtJQUVNLFNBQVMsSUFBSSxJQUFJLENBRXZCO0NBQ0Y7QUFFRCwwREFBMEQ7QUFDMUQscUJBQWEsZ0JBQWlCLFNBQVEsWUFBWTtJQUdwQyxPQUFPLENBQUMsUUFBUSxDQUFDLE1BQU07SUFGbkMsT0FBTyxDQUFDLE1BQU0sQ0FBSztJQUVuQixZQUE2QixNQUFNLHlDQUFnRCxFQUVsRjtJQUVlLEdBQUcsSUFBSSxNQUFNLENBRTVCO0lBRU0sT0FBTyxDQUFDLE1BQU0sRUFBRSxNQUFNLFFBRzVCO0lBRUQsc0RBQXNEO0lBQy9DLEtBQUssU0FHWDtJQUVELHdEQUF3RDtJQUNqRCxXQUFXLENBQUMsT0FBTyxFQUFFLE1BQU0sUUFFakM7Q0FDRjtBQUVEOzs7OztHQUtHO0FBQ0gscUJBQWEsa0JBQW1CLFNBQVEsWUFBWTtJQUNsRCxPQUFPLENBQUMsYUFBYSxDQUFTO0lBRTlCOztPQUVHO0lBQ0gsWUFBWSxhQUFhLEdBQUUsTUFBc0MsRUFHaEU7SUFFZSxHQUFHLElBQUksTUFBTSxDQUU1QjtJQUVELG9FQUFvRTtJQUM3RCxPQUFPLENBQUMsTUFBTSxFQUFFLE1BQU0sUUFFNUI7SUFFRCx3REFBd0Q7SUFDakQsV0FBVyxDQUFDLE9BQU8sRUFBRSxNQUFNLFFBRWpDO0lBRUQsNkRBQTZEO0lBQ3RELGFBQWEsQ0FBQyxFQUFFLEVBQUUsTUFBTSxRQUU5QjtDQUNGIn0=
@@ -1 +1 @@
1
- {"version":3,"file":"date.d.ts","sourceRoot":"","sources":["../../src/timer/date.ts"],"names":[],"mappings":"AAEA,gCAAgC;AAChC,qBAAa,YAAY;IAChB,GAAG,IAAI,MAAM,CAEnB;IAEM,YAAY,IAAI,MAAM,CAE5B;IAEM,SAAS,IAAI,IAAI,CAEvB;CACF;AAED,0DAA0D;AAC1D,qBAAa,gBAAiB,SAAQ,YAAY;IAGpC,OAAO,CAAC,QAAQ,CAAC,MAAM;IAFnC,OAAO,CAAC,MAAM,CAAK;IAEnB,YAA6B,MAAM,yCAAgD,EAElF;IAEe,GAAG,IAAI,MAAM,CAE5B;IAEM,OAAO,CAAC,MAAM,EAAE,MAAM,QAG5B;IAED,wDAAwD;IACjD,WAAW,CAAC,OAAO,EAAE,MAAM,QAEjC;CACF;AAED;;;;;GAKG;AACH,qBAAa,kBAAmB,SAAQ,YAAY;IAClD,OAAO,CAAC,aAAa,CAAS;IAE9B;;OAEG;IACH,YAAY,aAAa,GAAE,MAAsC,EAGhE;IAEe,GAAG,IAAI,MAAM,CAE5B;IAED,oEAAoE;IAC7D,OAAO,CAAC,MAAM,EAAE,MAAM,QAE5B;IAED,wDAAwD;IACjD,WAAW,CAAC,OAAO,EAAE,MAAM,QAEjC;IAED,6DAA6D;IACtD,aAAa,CAAC,EAAE,EAAE,MAAM,QAE9B;CACF"}
1
+ {"version":3,"file":"date.d.ts","sourceRoot":"","sources":["../../src/timer/date.ts"],"names":[],"mappings":"AAEA,gCAAgC;AAChC,qBAAa,YAAY;IAChB,GAAG,IAAI,MAAM,CAEnB;IAEM,YAAY,IAAI,MAAM,CAE5B;IAEM,SAAS,IAAI,IAAI,CAEvB;CACF;AAED,0DAA0D;AAC1D,qBAAa,gBAAiB,SAAQ,YAAY;IAGpC,OAAO,CAAC,QAAQ,CAAC,MAAM;IAFnC,OAAO,CAAC,MAAM,CAAK;IAEnB,YAA6B,MAAM,yCAAgD,EAElF;IAEe,GAAG,IAAI,MAAM,CAE5B;IAEM,OAAO,CAAC,MAAM,EAAE,MAAM,QAG5B;IAED,sDAAsD;IAC/C,KAAK,SAGX;IAED,wDAAwD;IACjD,WAAW,CAAC,OAAO,EAAE,MAAM,QAEjC;CACF;AAED;;;;;GAKG;AACH,qBAAa,kBAAmB,SAAQ,YAAY;IAClD,OAAO,CAAC,aAAa,CAAS;IAE9B;;OAEG;IACH,YAAY,aAAa,GAAE,MAAsC,EAGhE;IAEe,GAAG,IAAI,MAAM,CAE5B;IAED,oEAAoE;IAC7D,OAAO,CAAC,MAAM,EAAE,MAAM,QAE5B;IAED,wDAAwD;IACjD,WAAW,CAAC,OAAO,EAAE,MAAM,QAEjC;IAED,6DAA6D;IACtD,aAAa,CAAC,EAAE,EAAE,MAAM,QAE9B;CACF"}
@@ -26,6 +26,10 @@ import { createLogger } from '../log/pino-logger.js';
26
26
  timeMs
27
27
  });
28
28
  }
29
+ /** Resets the time back to real time (offset = 0). */ reset() {
30
+ this.offset = 0;
31
+ this.logger.warn('Time reset to real time');
32
+ }
29
33
  /** Advances the time by the given number of seconds. */ advanceTime(seconds) {
30
34
  this.offset += seconds * 1000;
31
35
  }
@@ -55,7 +55,7 @@ const log = createLogger('foundation:transport_client');
55
55
  msgId,
56
56
  payload
57
57
  };
58
- log.debug(format(`->`, msg));
58
+ log.trace(format(`->`, msg));
59
59
  return new Promise((resolve, reject)=>{
60
60
  this.pendingRequests.push({
61
61
  resolve,
@@ -77,7 +77,7 @@ const log = createLogger('foundation:transport_client');
77
77
  this.close();
78
78
  return;
79
79
  }
80
- log.debug(format(`<-`, msg));
80
+ log.trace(format(`<-`, msg));
81
81
  if (isEventMessage(msg)) {
82
82
  this.emit('event_msg', msg.payload);
83
83
  return;
package/package.json CHANGED
@@ -1,9 +1,29 @@
1
1
  {
2
2
  "name": "@aztec/foundation",
3
- "version": "0.0.1-commit.aada20e3",
3
+ "version": "0.0.1-commit.b33fc05d0",
4
4
  "type": "module",
5
5
  "main": "./dest/index.js",
6
6
  "types": "./dest/index.d.ts",
7
+ "typedocOptions": {
8
+ "entryPoints": [
9
+ "./src/buffer/index.ts",
10
+ "./src/collection/index.ts",
11
+ "./src/config/index.ts",
12
+ "./src/crypto/random/index.ts",
13
+ "./src/error/index.ts",
14
+ "./src/eth-address/index.ts",
15
+ "./src/json-rpc/index.ts",
16
+ "./src/log/index.ts",
17
+ "./src/retry/index.ts",
18
+ "./src/schemas/index.ts",
19
+ "./src/serialize/index.ts",
20
+ "./src/sleep/index.ts",
21
+ "./src/timer/index.ts",
22
+ "./src/types/index.ts"
23
+ ],
24
+ "name": "Foundation",
25
+ "tsconfig": "./tsconfig.json"
26
+ },
7
27
  "exports": {
8
28
  "./eslint": "./eslint.config.js",
9
29
  "./eslint.docs": "./eslint.config.docs.js",
@@ -124,7 +144,7 @@
124
144
  "testEnvironment": "../../foundation/src/jest/env.mjs"
125
145
  },
126
146
  "dependencies": {
127
- "@aztec/bb.js": "0.0.1-commit.aada20e3",
147
+ "@aztec/bb.js": "0.0.1-commit.b33fc05d0",
128
148
  "@koa/cors": "^5.0.0",
129
149
  "@noble/curves": "=1.7.0",
130
150
  "@noble/hashes": "^1.6.1",
@@ -21,34 +21,39 @@ export function dedupeSortedArray<T>(arr: T[], cmp: Cmp<T>): void {
21
21
  }
22
22
 
23
23
  export function insertIntoSortedArray<T>(arr: T[], item: T, cmp: Cmp<T>, allowDuplicates = true): boolean {
24
+ const index = findInsertionIndexInSortedArray(arr, item, cmp);
25
+
26
+ if (!allowDuplicates) {
27
+ // Check element before insertion point (upper bound returns index after equal elements)
28
+ if (index > 0 && cmp(arr[index - 1], item) === 0) {
29
+ return false;
30
+ }
31
+ }
32
+
33
+ arr.splice(index, 0, item);
34
+ return true;
35
+ }
36
+
37
+ /**
38
+ * Finds the index where needle would be inserted to maintain sorted order.
39
+ * Returns the count of elements less than or equal to needle.
40
+ */
41
+ export function findInsertionIndexInSortedArray<T, N>(values: T[], needle: N, cmp: (a: T, b: N) => number): number {
24
42
  let start = 0;
25
- let end = arr.length;
43
+ let end = values.length;
26
44
 
27
45
  while (start < end) {
28
46
  const mid = start + (((end - start) / 2) | 0);
29
- const comparison = cmp(arr[mid], item);
47
+ const comparison = cmp(values[mid], needle);
30
48
 
31
- if (comparison < 0) {
49
+ if (comparison <= 0) {
32
50
  start = mid + 1;
33
51
  } else {
34
52
  end = mid;
35
53
  }
36
54
  }
37
55
 
38
- if (!allowDuplicates) {
39
- // Check element at insertion point
40
- if (start < arr.length && cmp(arr[start], item) === 0) {
41
- return false;
42
- }
43
-
44
- // Check element before insertion point (in case we landed after duplicates)
45
- if (start > 0 && cmp(arr[start - 1], item) === 0) {
46
- return false;
47
- }
48
- }
49
-
50
- arr.splice(start, 0, item);
51
- return true;
56
+ return start;
52
57
  }
53
58
 
54
59
  export function findIndexInSortedArray<T, N>(values: T[], needle: N, cmp: (a: T, b: N) => number): number {
@@ -12,6 +12,9 @@ export type EnvVar =
12
12
  | 'ARCHIVER_VIEM_POLLING_INTERVAL_MS'
13
13
  | 'ARCHIVER_BATCH_SIZE'
14
14
  | 'AZTEC_ADMIN_PORT'
15
+ | 'AZTEC_ADMIN_API_KEY_HASH'
16
+ | 'AZTEC_DISABLE_ADMIN_API_KEY'
17
+ | 'AZTEC_RESET_ADMIN_API_KEY'
15
18
  | 'AZTEC_NODE_ADMIN_URL'
16
19
  | 'AZTEC_NODE_URL'
17
20
  | 'AZTEC_PORT'
@@ -47,7 +50,10 @@ export type EnvVar =
47
50
  | 'BOT_TX_MINED_WAIT_SECONDS'
48
51
  | 'BOT_MAX_CONSECUTIVE_ERRORS'
49
52
  | 'BOT_STOP_WHEN_UNHEALTHY'
50
- | 'BOT_AMM_TXS'
53
+ | 'BOT_MODE'
54
+ | 'BOT_L2_TO_L1_MESSAGES_PER_TX'
55
+ | 'BOT_L1_TO_L2_SEED_COUNT'
56
+ | 'BOT_L1_TO_L2_SEED_INTERVAL'
51
57
  | 'COINBASE'
52
58
  | 'CRS_PATH'
53
59
  | 'DATA_DIRECTORY'
@@ -56,6 +62,7 @@ export type EnvVar =
56
62
  | 'BLOB_SINK_MAP_SIZE_KB'
57
63
  | 'P2P_STORE_MAP_SIZE_KB'
58
64
  | 'PROVER_BROKER_STORE_MAP_SIZE_KB'
65
+ | 'SIGNING_PROTECTION_MAP_SIZE_KB'
59
66
  | 'WS_DB_MAP_SIZE_KB'
60
67
  | 'ARCHIVE_TREE_MAP_SIZE_KB'
61
68
  | 'NULLIFIER_TREE_MAP_SIZE_KB'
@@ -64,6 +71,7 @@ export type EnvVar =
64
71
  | 'PUBLIC_DATA_TREE_MAP_SIZE_KB'
65
72
  | 'DEBUG'
66
73
  | 'DEBUG_P2P_DISABLE_COLOCATION_PENALTY'
74
+ | 'ENABLE_PROVER_NODE'
67
75
  | 'ETHEREUM_HOSTS'
68
76
  | 'ETHEREUM_DEBUG_HOSTS'
69
77
  | 'ETHEREUM_ALLOW_NO_DEBUG_HOSTS'
@@ -75,6 +83,7 @@ export type EnvVar =
75
83
  | 'L1_CONSENSUS_HOST_URLS'
76
84
  | 'L1_CONSENSUS_HOST_API_KEYS'
77
85
  | 'L1_CONSENSUS_HOST_API_KEY_HEADERS'
86
+ | 'L1_TX_FAILED_STORE'
78
87
  | 'LOG_JSON'
79
88
  | 'LOG_MULTILINE'
80
89
  | 'LOG_NO_COLOR_PER_ACTOR'
@@ -100,6 +109,7 @@ export type EnvVar =
100
109
  | 'P2P_BATCH_TX_REQUESTER_TX_BATCH_SIZE'
101
110
  | 'P2P_BATCH_TX_REQUESTER_BAD_PEER_THRESHOLD'
102
111
  | 'P2P_BLOCK_CHECK_INTERVAL_MS'
112
+ | 'P2P_SLOT_CHECK_INTERVAL_MS'
103
113
  | 'P2P_BLOCK_REQUEST_BATCH_SIZE'
104
114
  | 'P2P_BOOTSTRAP_NODE_ENR_VERSION_CHECK'
105
115
  | 'P2P_BOOTSTRAP_NODES_AS_FULL_PEERS'
@@ -140,9 +150,10 @@ export type EnvVar =
140
150
  | 'P2P_PREFERRED_PEERS'
141
151
  | 'P2P_MAX_PENDING_TX_COUNT'
142
152
  | 'P2P_SEEN_MSG_CACHE_SIZE'
143
- | 'P2P_DROP_TX'
144
153
  | 'P2P_DROP_TX_CHANCE'
145
154
  | 'P2P_TX_POOL_DELETE_TXS_AFTER_REORG'
155
+ | 'P2P_MIN_TX_POOL_AGE_MS'
156
+ | 'P2P_RPC_PRICE_BUMP_PERCENTAGE'
146
157
  | 'DEBUG_P2P_INSTRUMENT_MESSAGES'
147
158
  | 'PEER_ID_PRIVATE_KEY'
148
159
  | 'PEER_ID_PRIVATE_KEY_PATH'
@@ -158,6 +169,7 @@ export type EnvVar =
158
169
  | 'PROVER_BROKER_MAX_EPOCHS_TO_KEEP_RESULTS_FOR'
159
170
  | 'PROVER_BROKER_DEBUG_REPLAY_ENABLED'
160
171
  | 'PROVER_CANCEL_JOBS_ON_STOP'
172
+ | 'PROVER_ENQUEUE_CONCURRENCY'
161
173
  | 'PROVER_COORDINATION_NODE_URLS'
162
174
  | 'PROVER_PROOF_STORE'
163
175
  | 'PROVER_FAILED_PROOF_STORE'
@@ -191,12 +203,13 @@ export type EnvVar =
191
203
  | 'SENTINEL_ENABLED'
192
204
  | 'SENTINEL_HISTORY_LENGTH_IN_EPOCHS'
193
205
  | 'SENTINEL_HISTORIC_PROVEN_PERFORMANCE_LENGTH_IN_EPOCHS'
194
- | 'SEQ_MAX_BLOCK_SIZE_IN_BYTES'
195
206
  | 'SEQ_MAX_TX_PER_BLOCK'
207
+ | 'SEQ_MAX_TX_PER_CHECKPOINT'
196
208
  | 'SEQ_MIN_TX_PER_BLOCK'
197
209
  | 'SEQ_PUBLISH_TXS_WITH_PROPOSALS'
198
210
  | 'SEQ_MAX_DA_BLOCK_GAS'
199
211
  | 'SEQ_MAX_L2_BLOCK_GAS'
212
+ | 'SEQ_PER_BLOCK_ALLOCATION_MULTIPLIER'
200
213
  | 'SEQ_PUBLISHER_PRIVATE_KEY'
201
214
  | 'SEQ_PUBLISHER_PRIVATE_KEYS'
202
215
  | 'SEQ_PUBLISHER_ADDRESSES'
@@ -207,9 +220,11 @@ export type EnvVar =
207
220
  | 'SEQ_L1_PUBLISHING_TIME_ALLOWANCE_IN_SLOT'
208
221
  | 'SEQ_ATTESTATION_PROPAGATION_TIME'
209
222
  | 'SEQ_BLOCK_DURATION_MS'
223
+ | 'SEQ_EXPECTED_BLOCK_PROPOSALS_PER_SLOT'
210
224
  | 'SEQ_BUILD_CHECKPOINT_IF_EMPTY'
211
225
  | 'SEQ_SECONDS_BEFORE_INVALIDATING_BLOCK_AS_COMMITTEE_MEMBER'
212
226
  | 'SEQ_SECONDS_BEFORE_INVALIDATING_BLOCK_AS_NON_COMMITTEE_MEMBER'
227
+ | 'SEQ_SKIP_CHECKPOINT_PUBLISH_PERCENT'
213
228
  | 'SLASH_MIN_PENALTY_PERCENTAGE'
214
229
  | 'SLASH_MAX_PENALTY_PERCENTAGE'
215
230
  | 'SLASH_VALIDATORS_ALWAYS'
@@ -220,6 +235,8 @@ export type EnvVar =
220
235
  | 'SLASH_INACTIVITY_TARGET_PERCENTAGE'
221
236
  | 'SLASH_INACTIVITY_CONSECUTIVE_EPOCH_THRESHOLD'
222
237
  | 'SLASH_INVALID_BLOCK_PENALTY'
238
+ | 'SLASH_DUPLICATE_PROPOSAL_PENALTY'
239
+ | 'SLASH_DUPLICATE_ATTESTATION_PENALTY'
223
240
  | 'SLASH_OVERRIDE_PAYLOAD'
224
241
  | 'SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY'
225
242
  | 'SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY'
@@ -234,6 +251,7 @@ export type EnvVar =
234
251
  | 'TELEMETRY'
235
252
  | 'TEST_ACCOUNTS'
236
253
  | 'SPONSORED_FPC'
254
+ | 'PREFUND_ADDRESSES'
237
255
  | 'TX_COLLECTION_FAST_NODES_TIMEOUT_BEFORE_REQ_RESP_MS'
238
256
  | 'TX_COLLECTION_SLOW_NODES_INTERVAL_MS'
239
257
  | 'TX_COLLECTION_SLOW_REQ_RESP_INTERVAL_MS'
@@ -244,9 +262,17 @@ export type EnvVar =
244
262
  | 'TX_COLLECTION_FAST_MAX_PARALLEL_REQUESTS_PER_NODE'
245
263
  | 'TX_COLLECTION_NODE_RPC_MAX_BATCH_SIZE'
246
264
  | 'TX_COLLECTION_NODE_RPC_URLS'
247
- | 'TX_COLLECTION_PROPOSAL_TX_COLLECTOR_TYPE'
265
+ | 'TX_COLLECTION_MISSING_TXS_COLLECTOR_TYPE'
266
+ | 'TX_COLLECTION_FILE_STORE_URLS'
267
+ | 'TX_COLLECTION_FILE_STORE_SLOW_DELAY_MS'
268
+ | 'TX_COLLECTION_FILE_STORE_FAST_DELAY_MS'
269
+ | 'TX_COLLECTION_FILE_STORE_FAST_WORKER_COUNT'
270
+ | 'TX_COLLECTION_FILE_STORE_SLOW_WORKER_COUNT'
271
+ | 'TX_COLLECTION_FILE_STORE_FAST_BACKOFF_BASE_MS'
272
+ | 'TX_COLLECTION_FILE_STORE_SLOW_BACKOFF_BASE_MS'
273
+ | 'TX_COLLECTION_FILE_STORE_FAST_BACKOFF_MAX_MS'
274
+ | 'TX_COLLECTION_FILE_STORE_SLOW_BACKOFF_MAX_MS'
248
275
  | 'TX_FILE_STORE_URL'
249
- | 'TX_FILE_STORE_DOWNLOAD_URL'
250
276
  | 'TX_FILE_STORE_UPLOAD_CONCURRENCY'
251
277
  | 'TX_FILE_STORE_MAX_QUEUE_SIZE'
252
278
  | 'TX_FILE_STORE_ENABLED'
@@ -255,6 +281,10 @@ export type EnvVar =
255
281
  | 'TRANSACTIONS_DISABLED'
256
282
  | 'VALIDATOR_ATTESTATIONS_POLLING_INTERVAL_MS'
257
283
  | 'VALIDATOR_DISABLED'
284
+ | 'VALIDATOR_MAX_DA_BLOCK_GAS'
285
+ | 'VALIDATOR_MAX_L2_BLOCK_GAS'
286
+ | 'VALIDATOR_MAX_TX_PER_BLOCK'
287
+ | 'VALIDATOR_MAX_TX_PER_CHECKPOINT'
258
288
  | 'VALIDATOR_PRIVATE_KEYS'
259
289
  | 'VALIDATOR_PRIVATE_KEY'
260
290
  | 'VALIDATOR_REEXECUTE'
@@ -264,6 +294,7 @@ export type EnvVar =
264
294
  | 'WS_BLOCK_REQUEST_BATCH_SIZE'
265
295
  | 'L1_READER_VIEM_POLLING_INTERVAL_MS'
266
296
  | 'WS_DATA_DIRECTORY'
297
+ | 'WS_NUM_HISTORIC_CHECKPOINTS'
267
298
  | 'WS_NUM_HISTORIC_BLOCKS'
268
299
  | 'ETHEREUM_SLOT_DURATION'
269
300
  | 'AZTEC_SLOT_DURATION'
@@ -318,9 +349,8 @@ export type EnvVar =
318
349
  | 'K8S_POD_NAME'
319
350
  | 'K8S_POD_UID'
320
351
  | 'K8S_NAMESPACE_NAME'
352
+ | 'ENABLE_VERSION_CHECK'
321
353
  | 'VALIDATOR_REEXECUTE_DEADLINE_MS'
322
- | 'AUTO_UPDATE'
323
- | 'AUTO_UPDATE_URL'
324
354
  | 'WEB3_SIGNER_URL'
325
355
  | 'SKIP_ARCHIVER_INITIAL_SYNC'
326
356
  | 'BLOB_ALLOW_EMPTY_SOURCES'
@@ -177,6 +177,21 @@ export function bigintConfigHelper(defaultVal?: bigint): Pick<ConfigMapping, 'pa
177
177
  if (val === '') {
178
178
  return defaultVal;
179
179
  }
180
+ // Handle scientific notation (e.g. "1e+23", "2E23") which BigInt() doesn't accept directly.
181
+ // We parse it losslessly using bigint arithmetic instead of going through float64.
182
+ if (/[eE]/.test(val)) {
183
+ const match = val.match(/^(-?\d+(?:\.(\d+))?)[eE]([+-]?\d+)$/);
184
+ if (!match) {
185
+ throw new Error(`Cannot convert '${val}' to a BigInt`);
186
+ }
187
+ const digits = match[1].replace('.', '');
188
+ const decimalPlaces = match[2]?.length ?? 0;
189
+ const exponent = parseInt(match[3], 10) - decimalPlaces;
190
+ if (exponent < 0) {
191
+ throw new Error(`Cannot convert '${val}' to a BigInt: result is not an integer`);
192
+ }
193
+ return BigInt(digits) * 10n ** BigInt(exponent);
194
+ }
180
195
  return BigInt(val);
181
196
  },
182
197
  defaultValue: defaultVal,
@@ -9,6 +9,8 @@ export const NetworkConfigSchema = z
9
9
  feeAssetHandlerAddress: z.string().optional(),
10
10
  l1ChainId: z.number(),
11
11
  blockDurationMs: z.number().positive().optional(),
12
+ txPublicSetupAllowListExtend: z.string().optional(),
13
+ nodeVersion: z.string().optional(),
12
14
  })
13
15
  .passthrough(); // Allow additional unknown fields to pass through
14
16
 
@@ -5,7 +5,8 @@ export type NetworkNames =
5
5
  | 'testnet'
6
6
  | 'mainnet'
7
7
  | 'next-net'
8
- | 'devnet';
8
+ | 'devnet'
9
+ | `v${number}-devnet-${number}`;
9
10
 
10
11
  export function getActiveNetworkName(name?: string): NetworkNames {
11
12
  const network = name || process.env.NETWORK;
@@ -23,6 +24,8 @@ export function getActiveNetworkName(name?: string): NetworkNames {
23
24
  return 'next-net';
24
25
  } else if (network === 'devnet') {
25
26
  return 'devnet';
27
+ } else if (/^v\d+-devnet-\d+$/.test(network)) {
28
+ return network as `v${number}-devnet-${number}`;
26
29
  }
27
30
  throw new Error(`Unknown network: ${network}`);
28
31
  }
@@ -1,4 +1,4 @@
1
- import { BarretenbergSync } from '@aztec/bb.js';
1
+ import { Barretenberg } from '@aztec/bb.js';
2
2
 
3
3
  import { Fr } from '../../curves/bn254/field.js';
4
4
  import { type Fieldable, serializeToFields } from '../../serialize/serialize.js';
@@ -10,9 +10,9 @@ import { type Fieldable, serializeToFields } from '../../serialize/serialize.js'
10
10
  */
11
11
  export async function poseidon2Hash(input: Fieldable[]): Promise<Fr> {
12
12
  const inputFields = serializeToFields(input);
13
- await BarretenbergSync.initSingleton();
14
- const api = BarretenbergSync.getSingleton();
15
- const response = api.poseidon2Hash({
13
+ await Barretenberg.initSingleton();
14
+ const api = Barretenberg.getSingleton();
15
+ const response = await api.poseidon2Hash({
16
16
  inputs: inputFields.map(i => i.toBuffer()),
17
17
  });
18
18
  return Fr.fromBuffer(Buffer.from(response.hash));
@@ -27,9 +27,9 @@ export async function poseidon2Hash(input: Fieldable[]): Promise<Fr> {
27
27
  export async function poseidon2HashWithSeparator(input: Fieldable[], separator: number): Promise<Fr> {
28
28
  const inputFields = serializeToFields(input);
29
29
  inputFields.unshift(new Fr(separator));
30
- await BarretenbergSync.initSingleton();
31
- const api = BarretenbergSync.getSingleton();
32
- const response = api.poseidon2Hash({
30
+ await Barretenberg.initSingleton();
31
+ const api = Barretenberg.getSingleton();
32
+ const response = await api.poseidon2Hash({
33
33
  inputs: inputFields.map(i => i.toBuffer()),
34
34
  });
35
35
  return Fr.fromBuffer(Buffer.from(response.hash));
@@ -44,9 +44,9 @@ export async function poseidon2Permutation(input: Fieldable[]): Promise<Fr[]> {
44
44
  const inputFields = serializeToFields(input);
45
45
  // We'd like this assertion but it's not possible to use it in the browser.
46
46
  // assert(input.length === 4, 'Input state must be of size 4');
47
- await BarretenbergSync.initSingleton();
48
- const api = BarretenbergSync.getSingleton();
49
- const response = api.poseidon2Permutation({
47
+ await Barretenberg.initSingleton();
48
+ const api = Barretenberg.getSingleton();
49
+ const response = await api.poseidon2Permutation({
50
50
  inputs: inputFields.map(i => i.toBuffer()),
51
51
  });
52
52
  // We'd like this assertion but it's not possible to use it in the browser.
@@ -65,9 +65,9 @@ export async function poseidon2HashBytes(input: Buffer): Promise<Fr> {
65
65
  inputFields.push(Fr.fromBuffer(fieldBytes));
66
66
  }
67
67
 
68
- await BarretenbergSync.initSingleton();
69
- const api = BarretenbergSync.getSingleton();
70
- const response = api.poseidon2Hash({
68
+ await Barretenberg.initSingleton();
69
+ const api = Barretenberg.getSingleton();
70
+ const response = await api.poseidon2Hash({
71
71
  inputs: inputFields.map(i => i.toBuffer()),
72
72
  });
73
73
 
@@ -210,3 +210,35 @@ export function recoverPublicKey(hash: Buffer32, signature: Signature, opts: Rec
210
210
  const publicKey = sig.recoverPublicKey(hash.buffer).toHex(false);
211
211
  return Buffer.from(publicKey, 'hex');
212
212
  }
213
+
214
+ /** Arbitrary hash used for testing signature recoverability. */
215
+ const PROBE_HASH = Buffer32.fromBuffer(keccak256(Buffer.from('signature-recoverability-probe')));
216
+
217
+ /**
218
+ * Generates a random valid ECDSA signature that is recoverable to some address.
219
+ * Since Signature.random() produces real signatures via secp256k1 signing, the result is always
220
+ * recoverable, but we verify defensively by checking tryRecoverAddress.
221
+ */
222
+ export function generateRecoverableSignature(): Signature {
223
+ for (let i = 0; i < 100; i++) {
224
+ const sig = Signature.random();
225
+ if (tryRecoverAddress(PROBE_HASH, sig) !== undefined) {
226
+ return sig;
227
+ }
228
+ }
229
+ throw new Secp256k1Error('Failed to generate a recoverable signature after 100 attempts');
230
+ }
231
+
232
+ /**
233
+ * Generates a random signature where ECDSA address recovery fails.
234
+ * Uses random r/s values (not from real signing) so that r is unlikely to be a valid secp256k1 x-coordinate.
235
+ */
236
+ export function generateUnrecoverableSignature(): Signature {
237
+ for (let i = 0; i < 100; i++) {
238
+ const sig = new Signature(Buffer32.random(), Buffer32.random(), 27);
239
+ if (tryRecoverAddress(PROBE_HASH, sig) === undefined) {
240
+ return sig;
241
+ }
242
+ }
243
+ throw new Secp256k1Error('Failed to generate an unrecoverable signature after 100 attempts');
244
+ }
@@ -118,14 +118,18 @@ abstract class BaseField {
118
118
  }
119
119
 
120
120
  cmp(rhs: BaseField): -1 | 0 | 1 {
121
- const rhsBigInt = rhs.asBigInt;
122
- return this.asBigInt === rhsBigInt ? 0 : this.asBigInt < rhsBigInt ? -1 : 1;
121
+ return BaseField.cmpAsBigInt(this.asBigInt, rhs.asBigInt);
123
122
  }
124
123
 
125
124
  static cmp(lhs: BaseField, rhs: BaseField): -1 | 0 | 1 {
126
125
  return lhs.cmp(rhs);
127
126
  }
128
127
 
128
+ // Actual bigint comparison. Arguments must have been validated previously.
129
+ static cmpAsBigInt(lhs: bigint, rhs: bigint): -1 | 0 | 1 {
130
+ return lhs === rhs ? 0 : lhs < rhs ? -1 : 1;
131
+ }
132
+
129
133
  isZero(): boolean {
130
134
  return this.asBigInt === 0n;
131
135
  }
@@ -1,8 +1,10 @@
1
1
  import { Buffer32 } from '@aztec/foundation/buffer';
2
2
  import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
3
3
 
4
+ import { secp256k1 } from '@noble/curves/secp256k1';
4
5
  import { z } from 'zod';
5
6
 
7
+ import { randomBytes } from '../crypto/random/index.js';
6
8
  import { hasHexPrefix, hexToBuffer } from '../string/index.js';
7
9
 
8
10
  /**
@@ -77,8 +79,12 @@ export class Signature {
77
79
  return new Signature(Buffer32.fromBuffer(hexToBuffer(sig.r)), Buffer32.fromBuffer(hexToBuffer(sig.s)), sig.yParity);
78
80
  }
79
81
 
82
+ /** Generates a random valid ECDSA signature with a low s-value by signing a random message with a random key. */
80
83
  static random(): Signature {
81
- return new Signature(Buffer32.random(), Buffer32.random(), 1);
84
+ const privateKey = randomBytes(32);
85
+ const message = randomBytes(32);
86
+ const { r, s, recovery } = secp256k1.sign(message, privateKey);
87
+ return new Signature(Buffer32.fromBigInt(r), Buffer32.fromBigInt(s), recovery ? 28 : 27);
82
88
  }
83
89
 
84
90
  static empty(): Signature {
@@ -10,3 +10,30 @@ import pretty from 'pino-pretty';
10
10
  if (!parseBooleanEnv(process.env.LOG_JSON)) {
11
11
  overwriteLoggingStream(pretty(pinoPrettyOpts));
12
12
  }
13
+
14
+ // Prevent timers from keeping the process alive after tests complete.
15
+ // Libraries like viem create internal polling loops (via setTimeout) that
16
+ // reschedule themselves indefinitely. In test environments we never want a
17
+ // timer to be the reason the process can't exit. We also unref stdout/stderr
18
+ // which, when they are pipes (as in Jest workers), remain ref'd by default.
19
+ {
20
+ const origSetTimeout = globalThis.setTimeout;
21
+ const origSetInterval = globalThis.setInterval;
22
+ globalThis.setTimeout = function unrefSetTimeout(...args) {
23
+ const id = origSetTimeout.apply(this, args);
24
+ id?.unref?.();
25
+ return id;
26
+ };
27
+ // Preserve .unref, .__promisify__ etc. that may exist on the original
28
+ Object.setPrototypeOf(globalThis.setTimeout, origSetTimeout);
29
+
30
+ globalThis.setInterval = function unrefSetInterval(...args) {
31
+ const id = origSetInterval.apply(this, args);
32
+ id?.unref?.();
33
+ return id;
34
+ };
35
+ Object.setPrototypeOf(globalThis.setInterval, origSetInterval);
36
+
37
+ if (process.stdout?._handle?.unref) process.stdout._handle.unref();
38
+ if (process.stderr?._handle?.unref) process.stderr._handle.unref();
39
+ }
@@ -24,6 +24,7 @@ export type SafeJsonRpcClientOptions = {
24
24
  batchWindowMS?: number;
25
25
  maxBatchSize?: number;
26
26
  maxRequestBodySize?: number;
27
+ extraHeaders?: Record<string, string>;
27
28
  onResponse?: (res: {
28
29
  response: any;
29
30
  headers: { get: (header: string) => string | null | undefined };
@@ -129,6 +130,7 @@ export function createSafeJsonRpcClient<T extends object>(
129
130
  const { response, headers } = await fetch(
130
131
  host,
131
132
  rpcCalls.map(({ request }) => request),
133
+ config.extraHeaders,
132
134
  );
133
135
 
134
136
  if (config.onResponse) {