@aztec/foundation 0.66.0 → 0.67.1-devnet

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 (127) hide show
  1. package/dest/abi/abi.d.ts +18 -18
  2. package/dest/abi/abi.d.ts.map +1 -1
  3. package/dest/abi/abi.js +25 -10
  4. package/dest/abi/encoder.js +3 -3
  5. package/dest/abi/event_selector.js +2 -2
  6. package/dest/abi/function_selector.js +2 -2
  7. package/dest/blob/index.d.ts +41 -0
  8. package/dest/blob/index.d.ts.map +1 -0
  9. package/dest/blob/index.js +118 -0
  10. package/dest/collection/array.d.ts +2 -0
  11. package/dest/collection/array.d.ts.map +1 -1
  12. package/dest/collection/array.js +10 -1
  13. package/dest/collection/object.d.ts +6 -0
  14. package/dest/collection/object.d.ts.map +1 -1
  15. package/dest/collection/object.js +15 -1
  16. package/dest/config/env_var.d.ts +1 -1
  17. package/dest/config/env_var.d.ts.map +1 -1
  18. package/dest/crypto/random/randomness_singleton.js +3 -3
  19. package/dest/fields/fields.d.ts +20 -2
  20. package/dest/fields/fields.d.ts.map +1 -1
  21. package/dest/fields/fields.js +37 -3
  22. package/dest/fs/run_in_dir.js +2 -2
  23. package/dest/index.d.ts +1 -0
  24. package/dest/index.d.ts.map +1 -1
  25. package/dest/index.js +2 -1
  26. package/dest/iterable/index.d.ts +1 -0
  27. package/dest/iterable/index.d.ts.map +1 -1
  28. package/dest/iterable/index.js +2 -1
  29. package/dest/iterable/toArray.d.ts +2 -0
  30. package/dest/iterable/toArray.d.ts.map +1 -0
  31. package/dest/iterable/toArray.js +8 -0
  32. package/dest/json-rpc/client/fetch.d.ts +2 -2
  33. package/dest/json-rpc/client/fetch.d.ts.map +1 -1
  34. package/dest/json-rpc/client/fetch.js +3 -3
  35. package/dest/json-rpc/client/safe_json_rpc_client.d.ts.map +1 -1
  36. package/dest/json-rpc/client/safe_json_rpc_client.js +7 -12
  37. package/dest/json-rpc/server/safe_json_rpc_server.d.ts +3 -2
  38. package/dest/json-rpc/server/safe_json_rpc_server.d.ts.map +1 -1
  39. package/dest/json-rpc/server/safe_json_rpc_server.js +5 -5
  40. package/dest/log/log-filters.d.ts.map +1 -1
  41. package/dest/log/log-filters.js +8 -2
  42. package/dest/log/log_fn.d.ts +1 -1
  43. package/dest/log/pino-logger.d.ts +18 -7
  44. package/dest/log/pino-logger.d.ts.map +1 -1
  45. package/dest/log/pino-logger.js +67 -18
  46. package/dest/noir/noir_package_config.d.ts +4 -4
  47. package/dest/promise/running-promise.d.ts +2 -1
  48. package/dest/promise/running-promise.d.ts.map +1 -1
  49. package/dest/promise/running-promise.js +10 -3
  50. package/dest/queue/base_memory_queue.d.ts.map +1 -1
  51. package/dest/queue/base_memory_queue.js +3 -3
  52. package/dest/queue/bounded_serial_queue.d.ts.map +1 -1
  53. package/dest/queue/bounded_serial_queue.js +3 -3
  54. package/dest/queue/fifo_memory_queue.d.ts +2 -2
  55. package/dest/queue/fifo_memory_queue.d.ts.map +1 -1
  56. package/dest/queue/fifo_memory_queue.js +1 -1
  57. package/dest/retry/index.d.ts.map +1 -1
  58. package/dest/retry/index.js +4 -4
  59. package/dest/schemas/utils.d.ts +3 -1
  60. package/dest/schemas/utils.d.ts.map +1 -1
  61. package/dest/schemas/utils.js +8 -3
  62. package/dest/serialize/field_reader.d.ts +5 -0
  63. package/dest/serialize/field_reader.d.ts.map +1 -1
  64. package/dest/serialize/field_reader.js +8 -1
  65. package/dest/string/index.d.ts +1 -0
  66. package/dest/string/index.d.ts.map +1 -1
  67. package/dest/string/index.js +4 -1
  68. package/dest/testing/files/index.d.ts +23 -0
  69. package/dest/testing/files/index.d.ts.map +1 -0
  70. package/dest/testing/files/index.js +68 -0
  71. package/dest/testing/index.d.ts +1 -1
  72. package/dest/testing/index.d.ts.map +1 -1
  73. package/dest/testing/index.js +2 -2
  74. package/dest/testing/test_data.d.ts +0 -11
  75. package/dest/testing/test_data.d.ts.map +1 -1
  76. package/dest/testing/test_data.js +1 -44
  77. package/dest/timer/date.d.ts +13 -0
  78. package/dest/timer/date.d.ts.map +1 -0
  79. package/dest/timer/date.js +22 -0
  80. package/dest/timer/index.d.ts +1 -0
  81. package/dest/timer/index.d.ts.map +1 -1
  82. package/dest/timer/index.js +2 -1
  83. package/dest/transport/dispatch/create_dispatch_fn.d.ts.map +1 -1
  84. package/dest/transport/dispatch/create_dispatch_fn.js +3 -3
  85. package/dest/transport/transport_client.js +3 -3
  86. package/dest/wasm/wasm_module.d.ts.map +1 -1
  87. package/dest/wasm/wasm_module.js +2 -2
  88. package/dest/worker/worker_pool.js +3 -3
  89. package/package.json +12 -3
  90. package/src/abi/abi.ts +30 -11
  91. package/src/abi/encoder.ts +2 -2
  92. package/src/abi/event_selector.ts +1 -1
  93. package/src/abi/function_selector.ts +1 -1
  94. package/src/blob/index.ts +152 -0
  95. package/src/collection/array.ts +10 -0
  96. package/src/collection/object.ts +22 -0
  97. package/src/config/env_var.ts +11 -6
  98. package/src/crypto/random/randomness_singleton.ts +2 -2
  99. package/src/fields/fields.ts +40 -2
  100. package/src/fs/run_in_dir.ts +1 -1
  101. package/src/index.ts +1 -0
  102. package/src/iterable/index.ts +1 -0
  103. package/src/iterable/toArray.ts +7 -0
  104. package/src/jest/setup.mjs +9 -0
  105. package/src/json-rpc/client/fetch.ts +3 -3
  106. package/src/json-rpc/client/safe_json_rpc_client.ts +7 -15
  107. package/src/json-rpc/server/safe_json_rpc_server.ts +5 -5
  108. package/src/log/log-filters.ts +7 -1
  109. package/src/log/log_fn.ts +1 -1
  110. package/src/log/pino-logger.ts +87 -41
  111. package/src/promise/running-promise.ts +11 -2
  112. package/src/queue/base_memory_queue.ts +2 -2
  113. package/src/queue/bounded_serial_queue.ts +2 -2
  114. package/src/queue/fifo_memory_queue.ts +2 -2
  115. package/src/retry/index.ts +3 -3
  116. package/src/schemas/utils.ts +10 -2
  117. package/src/serialize/field_reader.ts +8 -0
  118. package/src/string/index.ts +4 -0
  119. package/src/testing/files/index.ts +76 -0
  120. package/src/testing/index.ts +1 -1
  121. package/src/testing/test_data.ts +0 -50
  122. package/src/timer/date.ts +24 -0
  123. package/src/timer/index.ts +1 -0
  124. package/src/transport/dispatch/create_dispatch_fn.ts +2 -2
  125. package/src/transport/transport_client.ts +2 -2
  126. package/src/wasm/wasm_module.ts +1 -1
  127. package/src/worker/worker_pool.ts +2 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/foundation",
3
- "version": "0.66.0",
3
+ "version": "0.67.1-devnet",
4
4
  "packageManager": "yarn@3.4.1",
5
5
  "type": "module",
6
6
  "main": "./dest/index.js",
@@ -41,12 +41,14 @@
41
41
  "./wasm": "./dest/wasm/index.js",
42
42
  "./worker": "./dest/worker/index.js",
43
43
  "./bigint-buffer": "./dest/bigint-buffer/index.js",
44
+ "./blob": "./dest/blob/index.js",
44
45
  "./types": "./dest/types/index.js",
45
46
  "./schemas": "./dest/schemas/index.js",
46
47
  "./url": "./dest/url/index.js",
47
48
  "./committable": "./dest/committable/index.js",
48
49
  "./noir": "./dest/noir/index.js",
49
50
  "./testing": "./dest/testing/index.js",
51
+ "./testing/files": "./dest/testing/files/index.js",
50
52
  "./array": "./dest/array/index.js",
51
53
  "./validation": "./dest/validation/index.js",
52
54
  "./promise": "./dest/promise/index.js",
@@ -96,13 +98,21 @@
96
98
  "summaryThreshold": 9999
97
99
  }
98
100
  ]
101
+ ],
102
+ "testTimeout": 30000,
103
+ "setupFilesAfterEnv": [
104
+ "../../foundation/src/jest/setup.mjs"
105
+ ],
106
+ "setupFiles": [
107
+ "../../foundation/src/jest/setup.mjs"
99
108
  ]
100
109
  },
101
110
  "dependencies": {
102
- "@aztec/bb.js": "0.66.0",
111
+ "@aztec/bb.js": "0.67.1-devnet",
103
112
  "@koa/cors": "^5.0.0",
104
113
  "@noble/curves": "^1.2.0",
105
114
  "bn.js": "^5.2.1",
115
+ "c-kzg": "4.0.0-alpha.1",
106
116
  "colorette": "^2.0.20",
107
117
  "debug": "^4.3.4",
108
118
  "detect-node": "^2.1.0",
@@ -133,7 +143,6 @@
133
143
  "@types/koa": "^2.13.5",
134
144
  "@types/koa-bodyparser": "^4.3.10",
135
145
  "@types/koa-compress": "^4.0.3",
136
- "@types/koa-cors": "^0.0.2",
137
146
  "@types/koa-router": "^7.4.4",
138
147
  "@types/koa__cors": "^4.0.0",
139
148
  "@types/leveldown": "^4.0.3",
package/src/abi/abi.ts CHANGED
@@ -3,6 +3,7 @@ import { inflate } from 'pako';
3
3
  import { z } from 'zod';
4
4
 
5
5
  import { type Fr } from '../fields/fields.js';
6
+ import { createLogger } from '../log/index.js';
6
7
  import { schemas } from '../schemas/schemas.js';
7
8
  import { type ZodFor } from '../schemas/types.js';
8
9
  import { type FunctionSelector } from './function_selector.js';
@@ -15,6 +16,8 @@ export interface BasicValue<T extends string, V> {
15
16
  value: V;
16
17
  }
17
18
 
19
+ const logger = createLogger('aztec:foundation:abi');
20
+
18
21
  /** An exported value. */
19
22
  export type AbiValue =
20
23
  | BasicValue<'boolean', boolean>
@@ -390,7 +393,9 @@ export function getFunctionArtifact(
390
393
  if (!functionArtifact) {
391
394
  throw new Error(`Unknown function ${functionNameOrSelector}`);
392
395
  }
396
+
393
397
  const debugMetadata = getFunctionDebugMetadata(artifact, functionArtifact);
398
+
394
399
  return { ...functionArtifact, debug: debugMetadata };
395
400
  }
396
401
 
@@ -404,18 +409,32 @@ export function getFunctionDebugMetadata(
404
409
  contractArtifact: ContractArtifact,
405
410
  functionArtifact: FunctionArtifact,
406
411
  ): FunctionDebugMetadata | undefined {
407
- if (functionArtifact.debugSymbols && contractArtifact.fileMap) {
408
- const programDebugSymbols = JSON.parse(
409
- inflate(Buffer.from(functionArtifact.debugSymbols, 'base64'), { to: 'string', raw: true }),
410
- );
411
- // TODO(https://github.com/AztecProtocol/aztec-packages/issues/5813)
412
- // We only support handling debug info for the contract function entry point.
413
- // So for now we simply index into the first debug info.
414
- return {
415
- debugSymbols: programDebugSymbols.debug_infos[0],
416
- files: contractArtifact.fileMap,
417
- };
412
+ try {
413
+ if (functionArtifact.debugSymbols && contractArtifact.fileMap) {
414
+ // TODO(https://github.com/AztecProtocol/aztec-packages/issues/10546) investigate why debugMetadata is so big for some tests.
415
+ const programDebugSymbols = JSON.parse(
416
+ inflate(Buffer.from(functionArtifact.debugSymbols, 'base64'), { to: 'string', raw: true }),
417
+ );
418
+ // TODO(https://github.com/AztecProtocol/aztec-packages/issues/5813)
419
+ // We only support handling debug info for the contract function entry point.
420
+ // So for now we simply index into the first debug info.
421
+ return {
422
+ debugSymbols: programDebugSymbols.debug_infos[0],
423
+ files: contractArtifact.fileMap,
424
+ };
425
+ }
426
+ } catch (err: any) {
427
+ if (err instanceof RangeError && err.message.includes('Invalid string length')) {
428
+ logger.warn(
429
+ `Caught RangeError: Invalid string length. This suggests the debug_symbols field of the contract ${contractArtifact.name} and function ${functionArtifact.name} is huge; too big to parse. We'll skip returning this info until this issue is resolved. Here's the error:\n${err.message}`,
430
+ );
431
+ // We'll return undefined.
432
+ } else {
433
+ // Rethrow unexpected errors
434
+ throw err;
435
+ }
418
436
  }
437
+
419
438
  return undefined;
420
439
  }
421
440
 
@@ -49,7 +49,7 @@ class ArgumentEncoder {
49
49
  } else if (typeof arg === 'bigint') {
50
50
  this.flattened.push(new Fr(arg));
51
51
  } else if (typeof arg === 'string') {
52
- this.flattened.push(Fr.fromString(arg));
52
+ this.flattened.push(Fr.fromHexString(arg));
53
53
  } else if (typeof arg === 'boolean') {
54
54
  this.flattened.push(new Fr(arg ? 1n : 0n));
55
55
  } else if (typeof arg === 'object') {
@@ -58,7 +58,7 @@ class ArgumentEncoder {
58
58
  } else if (typeof arg.toField === 'function') {
59
59
  this.flattened.push(arg.toField());
60
60
  } else if (typeof arg.value === 'string') {
61
- this.flattened.push(Fr.fromString(arg.value));
61
+ this.flattened.push(Fr.fromHexString(arg.value));
62
62
  } else {
63
63
  throw new Error(`Argument for ${name} cannot be serialized to a field`);
64
64
  }
@@ -62,7 +62,7 @@ export class EventSelector extends Selector {
62
62
  static fromString(selector: string) {
63
63
  const buf = fromHex(selector);
64
64
  if (buf.length !== Selector.SIZE) {
65
- throw new Error(`Invalid Selector length ${buf.length} (expected ${Selector.SIZE}).`);
65
+ throw new Error(`Invalid EventSelector length ${buf.length} (expected ${Selector.SIZE}).`);
66
66
  }
67
67
  return EventSelector.fromBuffer(buf);
68
68
  }
@@ -91,7 +91,7 @@ export class FunctionSelector extends Selector {
91
91
  static fromString(selector: string) {
92
92
  const buf = fromHex(selector);
93
93
  if (buf.length !== Selector.SIZE) {
94
- throw new Error(`Invalid Selector length ${buf.length} (expected ${Selector.SIZE}).`);
94
+ throw new Error(`Invalid FunctionSelector length ${buf.length} (expected ${Selector.SIZE}).`);
95
95
  }
96
96
  return FunctionSelector.fromBuffer(buf);
97
97
  }
@@ -0,0 +1,152 @@
1
+ import cKzg from 'c-kzg';
2
+ import type { Blob as BlobBuffer } from 'c-kzg';
3
+
4
+ import { poseidon2Hash, sha256 } from '../crypto/index.js';
5
+ import { Fr } from '../fields/index.js';
6
+ import { serializeToBuffer } from '../serialize/index.js';
7
+
8
+ // Importing directly from 'c-kzg' does not work, ignoring import/no-named-as-default-member err:
9
+ /* eslint-disable import/no-named-as-default-member */
10
+
11
+ const {
12
+ BYTES_PER_BLOB,
13
+ FIELD_ELEMENTS_PER_BLOB,
14
+ blobToKzgCommitment,
15
+ computeKzgProof,
16
+ loadTrustedSetup,
17
+ verifyKzgProof,
18
+ } = cKzg;
19
+
20
+ try {
21
+ loadTrustedSetup();
22
+ } catch (error: any) {
23
+ if (error.message.includes('trusted setup is already loaded')) {
24
+ // NB: The c-kzg lib has no way of checking whether the setup is loaded or not,
25
+ // and it throws an error if it's already loaded, even though nothing is wrong.
26
+ // This is a rudimentary way of ensuring we load the trusted setup if we need it.
27
+ } else {
28
+ throw new Error(error);
29
+ }
30
+ }
31
+
32
+ // The prefix to the EVM blobHash, defined here: https://eips.ethereum.org/EIPS/eip-4844#specification
33
+ export const VERSIONED_HASH_VERSION_KZG = 0x01;
34
+
35
+ /**
36
+ * A class to create, manage, and prove EVM blobs.
37
+ */
38
+ export class Blob {
39
+ /** The blob to be broadcast on L1 in bytes form. */
40
+ public readonly data: BlobBuffer;
41
+ /** The hash of all tx effects inside the blob. Used in generating the challenge z and proving that we have included all required effects. */
42
+ public readonly fieldsHash: Fr;
43
+ /** Challenge point z (= H(H(tx_effects), kzgCommmitment). Used such that p(z) = y. */
44
+ public readonly challengeZ: Fr;
45
+ /** Evaluation y = p(z), where p() is the blob polynomial. BLS12 field element, rep. as BigNum in nr, bigint in ts. */
46
+ public readonly evaluationY: Buffer;
47
+ /** Commitment to the blob C. Used in compressed BLS12 point format (48 bytes). */
48
+ public readonly commitment: Buffer;
49
+ /** KZG opening proof for y = p(z). The commitment to quotient polynomial Q, used in compressed BLS12 point format (48 bytes). */
50
+ public readonly proof: Buffer;
51
+
52
+ constructor(
53
+ /** All fields to be broadcast in the blob. */
54
+ fields: Fr[],
55
+ /** If we want to broadcast more fields than fit into a blob, we hash those and used it as the fieldsHash across all blobs.
56
+ * This is much simpler and cheaper in the circuit to do, but MUST BE CHECKED before injecting here.
57
+ */
58
+ multiBlobFieldsHash?: Fr,
59
+ ) {
60
+ if (fields.length > FIELD_ELEMENTS_PER_BLOB) {
61
+ throw new Error(
62
+ `Attempted to overfill blob with ${fields.length} elements. The maximum is ${FIELD_ELEMENTS_PER_BLOB}`,
63
+ );
64
+ }
65
+ this.data = Buffer.concat([serializeToBuffer(fields)], BYTES_PER_BLOB);
66
+ // This matches the output of SpongeBlob.squeeze() in the blob circuit
67
+ this.fieldsHash = multiBlobFieldsHash ? multiBlobFieldsHash : poseidon2Hash(fields);
68
+ this.commitment = Buffer.from(blobToKzgCommitment(this.data));
69
+ this.challengeZ = poseidon2Hash([this.fieldsHash, ...this.commitmentToFields()]);
70
+ const res = computeKzgProof(this.data, this.challengeZ.toBuffer());
71
+ if (!verifyKzgProof(this.commitment, this.challengeZ.toBuffer(), res[1], res[0])) {
72
+ throw new Error(`KZG proof did not verify.`);
73
+ }
74
+ this.proof = Buffer.from(res[0]);
75
+ this.evaluationY = Buffer.from(res[1]);
76
+ }
77
+
78
+ // 48 bytes encoded in fields as [Fr, Fr] = [0->31, 31->48]
79
+ commitmentToFields(): [Fr, Fr] {
80
+ return [new Fr(this.commitment.subarray(0, 31)), new Fr(this.commitment.subarray(31, 48))];
81
+ }
82
+
83
+ // Returns ethereum's versioned blob hash, following kzg_to_versioned_hash: https://eips.ethereum.org/EIPS/eip-4844#helpers
84
+ getEthVersionedBlobHash(): Buffer {
85
+ const hash = sha256(this.commitment);
86
+ hash[0] = VERSIONED_HASH_VERSION_KZG;
87
+ return hash;
88
+ }
89
+
90
+ static getEthVersionedBlobHash(commitment: Buffer): Buffer {
91
+ const hash = sha256(commitment);
92
+ hash[0] = VERSIONED_HASH_VERSION_KZG;
93
+ return hash;
94
+ }
95
+
96
+ // Returns a proof of opening of the blob to verify on L1 using the point evaluation precompile:
97
+ // * input[:32] - versioned_hash
98
+ // * input[32:64] - z
99
+ // * input[64:96] - y
100
+ // * input[96:144] - commitment C
101
+ // * input[144:192] - proof (a commitment to the quotient polynomial q(X))
102
+ // See https://eips.ethereum.org/EIPS/eip-4844#point-evaluation-precompile
103
+ getEthBlobEvaluationInputs(): `0x${string}` {
104
+ const buf = Buffer.concat([
105
+ this.getEthVersionedBlobHash(),
106
+ this.challengeZ.toBuffer(),
107
+ this.evaluationY,
108
+ this.commitment,
109
+ this.proof,
110
+ ]);
111
+ return `0x${buf.toString('hex')}`;
112
+ }
113
+
114
+ static getEthBlobEvaluationInputs(blobs: Blob[]): `0x${string}` {
115
+ let buf = Buffer.alloc(0);
116
+ blobs.forEach(blob => {
117
+ buf = Buffer.concat([
118
+ buf,
119
+ blob.getEthVersionedBlobHash(),
120
+ blob.challengeZ.toBuffer(),
121
+ blob.evaluationY,
122
+ blob.commitment,
123
+ blob.proof,
124
+ ]);
125
+ });
126
+ // For multiple blobs, we prefix the number of blobs:
127
+ const lenBuf = Buffer.alloc(1);
128
+ lenBuf.writeUint8(blobs.length);
129
+ buf = Buffer.concat([lenBuf, buf]);
130
+ return `0x${buf.toString('hex')}`;
131
+ }
132
+
133
+ static getViemKzgInstance() {
134
+ return {
135
+ blobToKzgCommitment: cKzg.blobToKzgCommitment,
136
+ computeBlobKzgProof: cKzg.computeBlobKzgProof,
137
+ };
138
+ }
139
+
140
+ // Returns as many blobs as we require to broadcast the given fields
141
+ // Assumes we share the fields hash between all blobs
142
+ static getBlobs(fields: Fr[]): Blob[] {
143
+ const numBlobs = Math.max(Math.ceil(fields.length / FIELD_ELEMENTS_PER_BLOB), 1);
144
+ const multiBlobFieldsHash = poseidon2Hash(fields);
145
+ const res = [];
146
+ for (let i = 0; i < numBlobs; i++) {
147
+ const end = fields.length < (i + 1) * FIELD_ELEMENTS_PER_BLOB ? fields.length : (i + 1) * FIELD_ELEMENTS_PER_BLOB;
148
+ res.push(new Blob(fields.slice(i * FIELD_ELEMENTS_PER_BLOB, end), multiBlobFieldsHash));
149
+ }
150
+ return res;
151
+ }
152
+ }
@@ -145,3 +145,13 @@ export function areArraysEqual<T>(a: T[], b: T[], eq: (a: T, b: T) => boolean =
145
145
  export function maxBy<T>(arr: T[], fn: (x: T) => number): T | undefined {
146
146
  return arr.reduce((max, x) => (fn(x) > fn(max) ? x : max), arr[0]);
147
147
  }
148
+
149
+ /** Computes the median of a numeric array. Returns undefined if array is empty. */
150
+ export function median(arr: number[]) {
151
+ if (arr.length === 0) {
152
+ return undefined;
153
+ }
154
+ const sorted = [...arr].sort((a, b) => a - b);
155
+ const mid = Math.floor(sorted.length / 2);
156
+ return sorted.length % 2 !== 0 ? sorted[mid] : (sorted[mid - 1] + sorted[mid]) / 2;
157
+ }
@@ -28,3 +28,25 @@ export function compact<T extends object>(obj: T): { [P in keyof T]+?: Exclude<T
28
28
  }
29
29
  return result;
30
30
  }
31
+
32
+ /** Returns a new object by picking the given keys. */
33
+ export function pick<T extends object, U extends keyof T>(object: T, ...props: U[]): Pick<T, U>;
34
+ export function pick<T extends object>(object: T, ...props: string[]): Partial<T>;
35
+ export function pick<T extends object>(object: T, ...props: string[]): Partial<T> {
36
+ const obj: any = {};
37
+ for (const prop of props) {
38
+ obj[prop] = (object as any)[prop];
39
+ }
40
+ return obj;
41
+ }
42
+
43
+ /** Returns a new object by omitting the given keys. */
44
+ export function omit<T extends object, K extends keyof T>(object: T, ...props: K[]): Omit<T, K>;
45
+ export function omit<T extends object>(object: T, ...props: string[]): Partial<T>;
46
+ export function omit<T extends object>(object: T, ...props: string[]): Partial<T> {
47
+ const obj: any = { ...object };
48
+ for (const prop of props) {
49
+ delete obj[prop];
50
+ }
51
+ return obj;
52
+ }
@@ -52,14 +52,17 @@ export type EnvVar =
52
52
  | 'GOVERNANCE_PROPOSER_PAYLOAD_ADDRESS'
53
53
  | 'INBOX_CONTRACT_ADDRESS'
54
54
  | 'L1_CHAIN_ID'
55
+ | 'L1_CONSENSUS_CLIENT_URL'
55
56
  | 'L1_PRIVATE_KEY'
56
57
  | 'L2_QUEUE_SIZE'
57
58
  | 'LOG_ELAPSED_TIME'
58
59
  | 'LOG_JSON'
60
+ | 'LOG_MULTILINE'
59
61
  | 'LOG_LEVEL'
60
62
  | 'MNEMONIC'
61
63
  | 'NETWORK_NAME'
62
64
  | 'NETWORK'
65
+ | 'NO_PXE'
63
66
  | 'COIN_ISSUER_CONTRACT_ADDRESS'
64
67
  | 'OTEL_EXPORTER_OTLP_METRICS_ENDPOINT'
65
68
  | 'OTEL_EXPORTER_OTLP_TRACES_ENDPOINT'
@@ -123,8 +126,6 @@ export type EnvVar =
123
126
  | 'PROVER_REAL_PROOFS'
124
127
  | 'PROVER_REQUIRED_CONFIRMATIONS'
125
128
  | 'PROVER_TEST_DELAY_MS'
126
- | 'PROVER_CACHE_DIR'
127
- | 'PXE_BLOCK_POLLING_INTERVAL_MS'
128
129
  | 'PXE_L2_STARTING_BLOCK'
129
130
  | 'PXE_PROVER_ENABLED'
130
131
  | 'QUOTE_PROVIDER_BASIS_POINT_FEE'
@@ -135,11 +136,8 @@ export type EnvVar =
135
136
  | 'REGISTRY_CONTRACT_ADDRESS'
136
137
  | 'ROLLUP_CONTRACT_ADDRESS'
137
138
  | 'SEQ_ALLOWED_SETUP_FN'
138
- | 'SEQ_ALLOWED_TEARDOWN_FN'
139
139
  | 'SEQ_MAX_BLOCK_SIZE_IN_BYTES'
140
- | 'SEQ_MAX_SECONDS_BETWEEN_BLOCKS'
141
140
  | 'SEQ_MAX_TX_PER_BLOCK'
142
- | 'SEQ_MIN_SECONDS_BETWEEN_BLOCKS'
143
141
  | 'SEQ_MIN_TX_PER_BLOCK'
144
142
  | 'SEQ_PUBLISH_RETRY_INTERVAL_MS'
145
143
  | 'SEQ_PUBLISHER_PRIVATE_KEY'
@@ -182,4 +180,11 @@ export type EnvVar =
182
180
  | 'L1_TX_MONITOR_MAX_ATTEMPTS'
183
181
  | 'L1_TX_MONITOR_CHECK_INTERVAL_MS'
184
182
  | 'L1_TX_MONITOR_STALL_TIME_MS'
185
- | 'L1_TX_MONITOR_TX_TIMEOUT_MS';
183
+ | 'L1_TX_MONITOR_TX_TIMEOUT_MS'
184
+ | 'L1_TX_PROPAGATION_MAX_QUERY_ATTEMPTS'
185
+ | 'FAUCET_MNEMONIC_ACCOUNT_INDEX'
186
+ | 'FAUCET_ETH_AMOUNT'
187
+ | 'FAUCET_INTERVAL_MS'
188
+ | 'FAUCET_L1_ASSETS'
189
+ | 'K8S_POD_NAME'
190
+ | 'K8S_POD_UID';
@@ -1,4 +1,4 @@
1
- import { createDebugLogger } from '../../log/pino-logger.js';
1
+ import { createLogger } from '../../log/pino-logger.js';
2
2
 
3
3
  /**
4
4
  * A number generator which is used as a source of randomness in the system. If the SEED env variable is set, the
@@ -15,7 +15,7 @@ export class RandomnessSingleton {
15
15
 
16
16
  private constructor(
17
17
  private readonly seed?: number,
18
- private readonly log = createDebugLogger('aztec:randomness_singleton'),
18
+ private readonly log = createLogger('foundation:randomness_singleton'),
19
19
  ) {
20
20
  if (seed !== undefined) {
21
21
  this.log.debug(`Using pseudo-randomness with seed: ${seed}`);
@@ -232,12 +232,31 @@ export class Fr extends BaseField {
232
232
  return fromBufferReduce(buffer, Fr);
233
233
  }
234
234
 
235
+ /**
236
+ * Creates a Fr instance from a string.
237
+ * @param buf - the string to create a Fr from.
238
+ * @returns the Fr instance
239
+ * @remarks if the string only consists of numbers, we assume we are parsing a bigint,
240
+ * otherwise we require the hex string to be prepended with "0x", to ensure there is no misunderstanding
241
+ * as to what is being parsed.
242
+ */
243
+ static fromString(buf: string) {
244
+ if (buf.match(/^\d+$/) !== null) {
245
+ return new Fr(toBufferBE(BigInt(buf), 32));
246
+ }
247
+ if (buf.match(/^0x/i) !== null) {
248
+ return fromHexString(buf, Fr);
249
+ }
250
+
251
+ throw new Error('Tried to create a Fr from an invalid string');
252
+ }
253
+
235
254
  /**
236
255
  * Creates a Fr instance from a hex string.
237
256
  * @param buf - a hex encoded string.
238
257
  * @returns the Fr instance
239
258
  */
240
- static fromString(buf: string) {
259
+ static fromHexString(buf: string) {
241
260
  return fromHexString(buf, Fr);
242
261
  }
243
262
 
@@ -368,12 +387,31 @@ export class Fq extends BaseField {
368
387
  return fromBufferReduce(buffer, Fq);
369
388
  }
370
389
 
390
+ /**
391
+ * Creates a Fq instance from a string.
392
+ * @param buf - the string to create a Fq from.
393
+ * @returns the Fq instance
394
+ * @remarks if the string only consists of numbers, we assume we are parsing a bigint,
395
+ * otherwise we require the hex string to be prepended with "0x", to ensure there is no misunderstanding
396
+ * as to what is being parsed.
397
+ */
398
+ static fromString(buf: string) {
399
+ if (buf.match(/^\d+$/) !== null) {
400
+ return new Fq(toBufferBE(BigInt(buf), 32));
401
+ }
402
+ if (buf.match(/^0x/i) !== null) {
403
+ return fromHexString(buf, Fq);
404
+ }
405
+
406
+ throw new Error('Tried to create a Fq from an invalid string');
407
+ }
408
+
371
409
  /**
372
410
  * Creates a Fq instance from a hex string.
373
411
  * @param buf - a hex encoded string.
374
412
  * @returns the Fq instance
375
413
  */
376
- static fromString(buf: string) {
414
+ static fromHexString(buf: string) {
377
415
  return fromHexString(buf, Fq);
378
416
  }
379
417
 
@@ -1,4 +1,4 @@
1
- import * as fs from 'fs/promises';
1
+ import { promises as fs } from 'fs';
2
2
  import * as path from 'path';
3
3
 
4
4
  // Create a random directory underneath a 'base' directory
package/src/index.ts CHANGED
@@ -3,6 +3,7 @@ export * as abi from './abi/index.js';
3
3
  export * as asyncMap from './async-map/index.js';
4
4
  export * as aztecAddress from './aztec-address/index.js';
5
5
  export * as bigintBuffer from './bigint-buffer/index.js';
6
+ export * as blob from './blob/index.js';
6
7
  export * as collection from './collection/index.js';
7
8
  export * as committable from './committable/index.js';
8
9
  export * as crypto from './crypto/index.js';
@@ -4,3 +4,4 @@ export * from './sort.js';
4
4
  export * from './take.js';
5
5
  export * from './all.js';
6
6
  export * from './peek.js';
7
+ export * from './toArray.js';
@@ -0,0 +1,7 @@
1
+ export async function toArray<T>(iterator: AsyncIterableIterator<T> | IterableIterator<T>): Promise<T[]> {
2
+ const arr = [];
3
+ for await (const i of iterator) {
4
+ arr.push(i);
5
+ }
6
+ return arr;
7
+ }
@@ -0,0 +1,9 @@
1
+ import { overwriteLoggingStream, pinoPrettyOpts } from '@aztec/foundation/log';
2
+
3
+ import pretty from 'pino-pretty';
4
+
5
+ // Overwrite logging stream with pino-pretty. We define this as a separate
6
+ // file so we don't mess up with dependencies in non-testing environments,
7
+ // since pino-pretty messes up with browser bundles.
8
+ // See also https://www.npmjs.com/package/pino-pretty?activeTab=readme#user-content-usage-with-jest
9
+ overwriteLoggingStream(pretty(pinoPrettyOpts));
@@ -1,10 +1,10 @@
1
1
  import { format, inspect } from 'util';
2
2
 
3
- import { type DebugLogger, createDebugLogger } from '../../log/index.js';
3
+ import { type Logger, createLogger } from '../../log/index.js';
4
4
  import { NoRetryError, makeBackoff, retry } from '../../retry/index.js';
5
5
  import { jsonStringify } from '../convert.js';
6
6
 
7
- const log = createDebugLogger('json-rpc:json_rpc_client');
7
+ const log = createLogger('json-rpc:json_rpc_client');
8
8
 
9
9
  /**
10
10
  * A normal fetch function that does not retry.
@@ -73,7 +73,7 @@ export async function defaultFetch(
73
73
  * @param log - Optional logger for logging attempts.
74
74
  * @returns A fetch function.
75
75
  */
76
- export function makeFetch(retries: number[], defaultNoRetry: boolean, log?: DebugLogger) {
76
+ export function makeFetch(retries: number[], defaultNoRetry: boolean, log?: Logger) {
77
77
  return async (host: string, rpcMethod: string, body: any, useApiEndpoints: boolean, noRetry?: boolean) => {
78
78
  return await retry(
79
79
  () => defaultFetch(host, rpcMethod, body, useApiEndpoints, noRetry ?? defaultNoRetry),
@@ -1,6 +1,6 @@
1
1
  import { format } from 'util';
2
2
 
3
- import { createDebugLogger } from '../../log/pino-logger.js';
3
+ import { createLogger } from '../../log/pino-logger.js';
4
4
  import { type ApiSchema, type ApiSchemaFor, schemaHasMethod } from '../../schemas/api.js';
5
5
  import { defaultFetch } from './fetch.js';
6
6
 
@@ -19,7 +19,7 @@ export function createSafeJsonRpcClient<T extends object>(
19
19
  useApiEndpoints: boolean = false,
20
20
  namespaceMethods?: string | false,
21
21
  fetch = defaultFetch,
22
- log = createDebugLogger('json-rpc:client'),
22
+ log = createLogger('json-rpc:client'),
23
23
  ): T {
24
24
  let id = 0;
25
25
  const request = async (methodName: string, params: any[]): Promise<any> => {
@@ -44,18 +44,10 @@ export function createSafeJsonRpcClient<T extends object>(
44
44
  return (schema as ApiSchema)[methodName].returnType().parse(res.result);
45
45
  };
46
46
 
47
- // Intercept any RPC methods with a proxy
48
- const proxy = new Proxy(
49
- {},
50
- {
51
- get: (target, method: string) => {
52
- if (['then', 'catch'].includes(method)) {
53
- return Reflect.get(target, method);
54
- }
55
- return (...params: any[]) => request(method, params);
56
- },
57
- },
58
- ) as T;
47
+ const proxy: any = {};
48
+ for (const method of Object.keys(schema)) {
49
+ proxy[method] = (...params: any[]) => request(method, params);
50
+ }
59
51
 
60
- return proxy;
52
+ return proxy as T;
61
53
  }
@@ -8,7 +8,7 @@ import { type AddressInfo } from 'net';
8
8
  import { format, inspect } from 'util';
9
9
  import { ZodError } from 'zod';
10
10
 
11
- import { type DebugLogger, createDebugLogger } from '../../log/index.js';
11
+ import { type Logger, createLogger } from '../../log/index.js';
12
12
  import { promiseWithResolvers } from '../../promise/utils.js';
13
13
  import { type ApiSchema, type ApiSchemaFor, parseWithOptionals, schemaHasMethod } from '../../schemas/index.js';
14
14
  import { jsonStringify } from '../convert.js';
@@ -27,7 +27,7 @@ export class SafeJsonRpcServer {
27
27
  /** Health check function */
28
28
  private readonly healthCheck: StatusCheckFn = () => true,
29
29
  /** Logger */
30
- private log = createDebugLogger('json-rpc:server'),
30
+ private log = createLogger('json-rpc:server'),
31
31
  ) {}
32
32
 
33
33
  public isHealthy(): boolean | Promise<boolean> {
@@ -170,7 +170,7 @@ interface Proxy {
170
170
  * before forwarding calls, and then converts outputs into JSON using default conversions.
171
171
  */
172
172
  export class SafeJsonProxy<T extends object = any> implements Proxy {
173
- private log = createDebugLogger('json-rpc:proxy');
173
+ private log = createLogger('json-rpc:proxy');
174
174
  private schema: ApiSchema;
175
175
 
176
176
  constructor(private handler: T, schema: ApiSchemaFor<T>) {
@@ -233,7 +233,7 @@ export function makeHandler<T extends object>(handler: T, schema: ApiSchemaFor<T
233
233
  return [handler, schema];
234
234
  }
235
235
 
236
- function makeAggregateHealthcheck(namedHandlers: NamespacedApiHandlers, log?: DebugLogger): StatusCheckFn {
236
+ function makeAggregateHealthcheck(namedHandlers: NamespacedApiHandlers, log?: Logger): StatusCheckFn {
237
237
  return async () => {
238
238
  try {
239
239
  const results = await Promise.all(
@@ -259,7 +259,7 @@ function makeAggregateHealthcheck(namedHandlers: NamespacedApiHandlers, log?: De
259
259
  */
260
260
  export function createNamespacedSafeJsonRpcServer(
261
261
  handlers: NamespacedApiHandlers,
262
- log = createDebugLogger('json-rpc:server'),
262
+ log = createLogger('json-rpc:server'),
263
263
  ): SafeJsonRpcServer {
264
264
  const proxy = new NamespacedSafeJsonProxy(handlers);
265
265
  const healthCheck = makeAggregateHealthcheck(handlers, log);
@@ -42,7 +42,13 @@ export function parseFilters(definition: string | undefined): LogFilters {
42
42
  const sanitizedLevel = level.trim().toLowerCase();
43
43
  assertLogLevel(sanitizedLevel);
44
44
  for (const module of modules.split(',')) {
45
- filters.push([module.trim().toLowerCase(), sanitizedLevel as LogLevel | 'silent']);
45
+ filters.push([
46
+ module
47
+ .trim()
48
+ .toLowerCase()
49
+ .replace(/^aztec:/, ''),
50
+ sanitizedLevel as LogLevel | 'silent',
51
+ ]);
46
52
  }
47
53
  }
48
54
  return filters.reverse();
package/src/log/log_fn.ts CHANGED
@@ -2,4 +2,4 @@
2
2
  export type LogData = Record<string, string | number | bigint | boolean | { toString(): string } | undefined>;
3
3
 
4
4
  /** A callable logger instance. */
5
- export type LogFn = (msg: string, data?: LogData) => void;
5
+ export type LogFn = (msg: string, data?: unknown) => void;