@aztec/foundation 0.0.1-commit.e588bc7e5 → 0.0.1-commit.e5a3663dd

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 (80) hide show
  1. package/dest/branded-types/buffer32_hash.d.ts +24 -0
  2. package/dest/branded-types/buffer32_hash.d.ts.map +1 -0
  3. package/dest/branded-types/buffer32_hash.js +19 -0
  4. package/dest/branded-types/checkpoint_number.d.ts +4 -1
  5. package/dest/branded-types/checkpoint_number.d.ts.map +1 -1
  6. package/dest/branded-types/checkpoint_number.js +3 -0
  7. package/dest/branded-types/index.d.ts +2 -1
  8. package/dest/branded-types/index.d.ts.map +1 -1
  9. package/dest/branded-types/index.js +1 -0
  10. package/dest/buffer/buffer16.d.ts +3 -3
  11. package/dest/buffer/buffer16.d.ts.map +1 -1
  12. package/dest/buffer/buffer32.d.ts +28 -63
  13. package/dest/buffer/buffer32.d.ts.map +1 -1
  14. package/dest/buffer/buffer32.js +26 -60
  15. package/dest/config/env_var.d.ts +2 -2
  16. package/dest/config/env_var.d.ts.map +1 -1
  17. package/dest/config/index.d.ts +48 -30
  18. package/dest/config/index.d.ts.map +1 -1
  19. package/dest/config/index.js +21 -30
  20. package/dest/curves/bls12/field.d.ts +1 -1
  21. package/dest/curves/bls12/field.d.ts.map +1 -1
  22. package/dest/curves/bls12/field.js +0 -5
  23. package/dest/curves/bn254/field.d.ts +17 -16
  24. package/dest/curves/bn254/field.d.ts.map +1 -1
  25. package/dest/curves/bn254/field.js +18 -13
  26. package/dest/curves/grumpkin/point.d.ts +3 -3
  27. package/dest/curves/grumpkin/point.d.ts.map +1 -1
  28. package/dest/curves/grumpkin/point.js +6 -3
  29. package/dest/eth-address/index.d.ts +1 -1
  30. package/dest/eth-address/index.d.ts.map +1 -1
  31. package/dest/eth-address/index.js +0 -3
  32. package/dest/json-rpc/client/fetch.js +1 -1
  33. package/dest/json-rpc/client/undici.d.ts +1 -1
  34. package/dest/json-rpc/client/undici.d.ts.map +1 -1
  35. package/dest/json-rpc/client/undici.js +5 -3
  36. package/dest/log/pino-logger.js +15 -1
  37. package/dest/queue/batch_queue.d.ts +1 -1
  38. package/dest/queue/batch_queue.d.ts.map +1 -1
  39. package/dest/queue/batch_queue.js +1 -0
  40. package/dest/string/index.js +1 -1
  41. package/dest/trees/balanced_merkle_tree_root.d.ts +2 -3
  42. package/dest/trees/balanced_merkle_tree_root.d.ts.map +1 -1
  43. package/dest/trees/balanced_merkle_tree_root.js +2 -3
  44. package/dest/trees/hasher.d.ts +3 -2
  45. package/dest/trees/hasher.d.ts.map +1 -1
  46. package/dest/trees/hasher.js +5 -5
  47. package/dest/trees/merkle_tree_calculator.d.ts +4 -2
  48. package/dest/trees/merkle_tree_calculator.d.ts.map +1 -1
  49. package/dest/trees/merkle_tree_calculator.js +1 -5
  50. package/dest/trees/sibling_path.d.ts +2 -2
  51. package/dest/trees/sibling_path.d.ts.map +1 -1
  52. package/dest/trees/sibling_path.js +1 -5
  53. package/dest/trees/unbalanced_merkle_tree_root.d.ts +2 -3
  54. package/dest/trees/unbalanced_merkle_tree_root.d.ts.map +1 -1
  55. package/dest/trees/unbalanced_merkle_tree_root.js +2 -3
  56. package/dest/types/index.d.ts +9 -1
  57. package/dest/types/index.d.ts.map +1 -1
  58. package/package.json +2 -2
  59. package/src/branded-types/buffer32_hash.ts +42 -0
  60. package/src/branded-types/checkpoint_number.ts +5 -0
  61. package/src/branded-types/index.ts +1 -0
  62. package/src/buffer/buffer16.ts +2 -2
  63. package/src/buffer/buffer32.ts +36 -68
  64. package/src/config/env_var.ts +5 -5
  65. package/src/config/index.ts +96 -84
  66. package/src/curves/bls12/field.ts +0 -7
  67. package/src/curves/bn254/field.ts +25 -31
  68. package/src/curves/grumpkin/point.ts +5 -2
  69. package/src/eth-address/index.ts +0 -4
  70. package/src/json-rpc/client/fetch.ts +1 -1
  71. package/src/json-rpc/client/undici.ts +5 -3
  72. package/src/log/pino-logger.ts +16 -1
  73. package/src/queue/batch_queue.ts +1 -0
  74. package/src/string/index.ts +1 -1
  75. package/src/trees/balanced_merkle_tree_root.ts +2 -5
  76. package/src/trees/hasher.ts +6 -3
  77. package/src/trees/merkle_tree_calculator.ts +4 -10
  78. package/src/trees/sibling_path.ts +1 -2
  79. package/src/trees/unbalanced_merkle_tree_root.ts +2 -5
  80. package/src/types/index.ts +14 -0
@@ -7,72 +7,39 @@ import { inspect } from 'util';
7
7
  import { bufferToHex } from '../string/index.js';
8
8
 
9
9
  /**
10
- * A class representing a 32 byte Buffer.
10
+ * Abstract unbranded base class for 32-byte buffers.
11
+ * Extend this instead of Buffer32 when defining a branded subtype
12
+ * to avoid inheriting Buffer32's `_branding`.
11
13
  */
12
- export class Buffer32 {
13
- /** Branding to prevent structural compatibility with Buffer16. */
14
- declare readonly __brand: 'Buffer32';
15
-
16
- /**
17
- * The size of the hash in bytes.
18
- */
14
+ export abstract class BaseBuffer32 {
15
+ /** The size of the buffer in bytes. */
19
16
  public static SIZE = 32;
20
17
 
21
- /**
22
- * Buffer32 with value zero.
23
- */
24
- public static ZERO = new Buffer32(Buffer.alloc(Buffer32.SIZE));
25
-
26
18
  constructor(
27
- /**
28
- * The buffer containing the hash.
29
- */
19
+ /** The buffer containing the data. */
30
20
  public buffer: Buffer,
31
21
  ) {
32
- if (buffer.length !== Buffer32.SIZE) {
33
- throw new Error(`Expected buffer to have length ${Buffer32.SIZE} but was ${buffer.length}`);
22
+ if (buffer.length !== BaseBuffer32.SIZE) {
23
+ throw new Error(`Expected buffer to have length ${BaseBuffer32.SIZE} but was ${buffer.length}`);
34
24
  }
35
25
  }
36
26
 
37
- /**
38
- * Returns the raw buffer of the hash.
39
- * @returns The buffer containing the hash.
40
- */
27
+ /** Returns the raw buffer. */
41
28
  public toBuffer() {
42
29
  return this.buffer;
43
30
  }
44
31
 
45
- /**
46
- * Creates a Buffer32 from a buffer.
47
- * @param buffer - The buffer to create from.
48
- * @returns A new Buffer32 object.
49
- */
50
- public static fromBuffer(buffer: Buffer | BufferReader) {
51
- const reader = BufferReader.asReader(buffer);
52
- return new Buffer32(reader.readBytes(Buffer32.SIZE));
53
- }
54
-
55
- /**
56
- * Checks if this hash and another hash are equal.
57
- * @param hash - A hash to compare with.
58
- * @returns True if the hashes are equal, false otherwise.
59
- */
60
- public equals(hash: Buffer32): boolean {
32
+ /** Checks if this and another buffer are equal. */
33
+ public equals(hash: BaseBuffer32): boolean {
61
34
  return this.buffer.equals(hash.buffer);
62
35
  }
63
36
 
64
- /**
65
- * Returns true if this hash is zero.
66
- * @returns True if this hash is zero.
67
- */
37
+ /** Returns true if all bytes are zero. */
68
38
  public isZero(): boolean {
69
39
  return this.buffer.equals(Buffer.alloc(32, 0));
70
40
  }
71
41
 
72
- /**
73
- * Convert this hash to a hex string.
74
- * @returns The hex string.
75
- */
42
+ /** Convert to a hex string. */
76
43
  public toString() {
77
44
  return bufferToHex(this.buffer);
78
45
  }
@@ -85,16 +52,27 @@ export class Buffer32 {
85
52
  return this.toString();
86
53
  }
87
54
 
88
- /**
89
- * Convert this hash to a big int.
90
- * @returns The big int.
91
- */
55
+ /** Convert to a big int. */
92
56
  public toBigInt() {
93
- return deserializeBigInt(this.buffer, 0, Buffer32.SIZE).elem;
57
+ return deserializeBigInt(this.buffer, 0, BaseBuffer32.SIZE).elem;
94
58
  }
95
- /**
96
- * Creates a Buffer32 from a bigint.
97
- */
59
+ }
60
+
61
+ /** A branded 32-byte buffer. */
62
+ export class Buffer32 extends BaseBuffer32 {
63
+ /** Branding for nominal typing. */
64
+ declare private readonly _branding: 'Buffer32';
65
+
66
+ /** Buffer32 with value zero. */
67
+ public static ZERO = new Buffer32(Buffer.alloc(Buffer32.SIZE));
68
+
69
+ /** Creates a Buffer32 from a buffer. */
70
+ public static fromBuffer(buffer: Buffer | BufferReader) {
71
+ const reader = BufferReader.asReader(buffer);
72
+ return new Buffer32(reader.readBytes(Buffer32.SIZE));
73
+ }
74
+
75
+ /** Creates a Buffer32 from a bigint. */
98
76
  public static fromBigInt(hash: bigint) {
99
77
  return new Buffer32(serializeBigInt(hash, Buffer32.SIZE));
100
78
  }
@@ -104,8 +82,7 @@ export class Buffer32 {
104
82
  }
105
83
 
106
84
  /**
107
- * Converts this hash from a buffer of 28 bytes.
108
- * Verifies the input is 28 bytes.
85
+ * Converts from a buffer of 28 bytes.
109
86
  * @param buffer - The 28 byte buffer to construct from.
110
87
  * @returns A Buffer32 created from the input buffer with 4 bytes 0 padding at the front.
111
88
  */
@@ -117,9 +94,7 @@ export class Buffer32 {
117
94
  return new Buffer32(padded);
118
95
  }
119
96
 
120
- /**
121
- * Converts a string into a Buffer32 object.
122
- */
97
+ /** Converts a string into a Buffer32 object. */
123
98
  public static fromString(str: string): Buffer32 {
124
99
  if (str.startsWith('0x')) {
125
100
  str = str.slice(2);
@@ -130,19 +105,12 @@ export class Buffer32 {
130
105
  return new Buffer32(Buffer.from(str, 'hex'));
131
106
  }
132
107
 
133
- /**
134
- * Converts a number into a Buffer32 object.
135
- * @param num - The number to convert.
136
- * @returns A new Buffer32 object.
137
- */
108
+ /** Converts a number into a Buffer32 object. */
138
109
  public static fromNumber(num: number): Buffer32 {
139
110
  return new Buffer32(serializeBigInt(BigInt(num), Buffer32.SIZE));
140
111
  }
141
112
 
142
- /**
143
- * Generates a random Buffer32.
144
- * @returns A new Buffer32 object.
145
- */
113
+ /** Generates a random Buffer32. */
146
114
  public static random(): Buffer32 {
147
115
  return new Buffer32(Buffer.from(randomBytes(Buffer32.SIZE)));
148
116
  }
@@ -1,17 +1,18 @@
1
1
  export type EnvVar =
2
2
  | 'REGISTRY_CONTRACT_ADDRESS'
3
3
  | 'FEE_ASSET_HANDLER_CONTRACT_ADDRESS'
4
- | 'SLASH_FACTORY_CONTRACT_ADDRESS'
5
4
  | 'ACVM_BINARY_PATH'
6
5
  | 'ACVM_WORKING_DIRECTORY'
7
6
  | 'API_KEY'
8
7
  | 'API_PREFIX'
9
8
  | 'ARCHIVER_MAX_LOGS'
10
9
  | 'ARCHIVER_POLLING_INTERVAL_MS'
10
+ | 'ARCHIVER_SKIP_HISTORICAL_LOGS_CHECK'
11
11
  | 'ARCHIVER_URL'
12
12
  | 'ARCHIVER_VIEM_POLLING_INTERVAL_MS'
13
13
  | 'ARCHIVER_BATCH_SIZE'
14
14
  | 'AZTEC_ADMIN_PORT'
15
+ | 'AZTEC_NODE_DEBUG'
15
16
  | 'AZTEC_ADMIN_API_KEY_HASH'
16
17
  | 'AZTEC_DISABLE_ADMIN_API_KEY'
17
18
  | 'AZTEC_RESET_ADMIN_API_KEY'
@@ -94,7 +95,6 @@ export type EnvVar =
94
95
  | 'MNEMONIC'
95
96
  | 'NETWORK'
96
97
  | 'NETWORK_CONFIG_LOCATION'
97
- | 'NO_PXE'
98
98
  | 'USE_GCLOUD_LOGGING'
99
99
  | 'OTEL_EXPORTER_OTLP_METRICS_ENDPOINT'
100
100
  | 'OTEL_EXPORTER_OTLP_TRACES_ENDPOINT'
@@ -228,13 +228,12 @@ export type EnvVar =
228
228
  | 'SEQ_L1_PUBLISHING_TIME_ALLOWANCE_IN_SLOT'
229
229
  | 'SEQ_ATTESTATION_PROPAGATION_TIME'
230
230
  | 'SEQ_BLOCK_DURATION_MS'
231
+ | 'SEQ_LAST_BLOCK_DURATION_MS'
231
232
  | 'SEQ_EXPECTED_BLOCK_PROPOSALS_PER_SLOT'
232
233
  | 'SEQ_BUILD_CHECKPOINT_IF_EMPTY'
233
234
  | 'SEQ_SECONDS_BEFORE_INVALIDATING_BLOCK_AS_COMMITTEE_MEMBER'
234
235
  | 'SEQ_SECONDS_BEFORE_INVALIDATING_BLOCK_AS_NON_COMMITTEE_MEMBER'
235
236
  | 'SEQ_SKIP_CHECKPOINT_PUBLISH_PERCENT'
236
- | 'SLASH_MIN_PENALTY_PERCENTAGE'
237
- | 'SLASH_MAX_PENALTY_PERCENTAGE'
238
237
  | 'SLASH_VALIDATORS_ALWAYS'
239
238
  | 'SLASH_VALIDATORS_NEVER'
240
239
  | 'SLASH_PRUNE_PENALTY'
@@ -327,7 +326,7 @@ export type EnvVar =
327
326
  | 'AZTEC_SLASH_AMOUNT_SMALL'
328
327
  | 'AZTEC_SLASH_AMOUNT_MEDIUM'
329
328
  | 'AZTEC_SLASH_AMOUNT_LARGE'
330
- | 'AZTEC_SLASHER_FLAVOR'
329
+ | 'AZTEC_SLASHER_ENABLED'
331
330
  | 'AZTEC_GOVERNANCE_PROPOSER_QUORUM'
332
331
  | 'AZTEC_GOVERNANCE_PROPOSER_ROUND_SIZE'
333
332
  | 'AZTEC_GOVERNANCE_VOTING_DURATION'
@@ -364,6 +363,7 @@ export type EnvVar =
364
363
  | 'BLOB_FILE_STORE_TIMEOUT_MS'
365
364
  | 'FISHERMAN_MODE'
366
365
  | 'MAX_ALLOWED_ETH_CLIENT_DRIFT_SECONDS'
366
+ | 'MAX_BLOCKS_PER_CHECKPOINT'
367
367
  | 'LEGACY_BLS_CLI'
368
368
  | 'DEBUG_FORCE_TX_PROOF_VERIFICATION'
369
369
  | 'VALIDATOR_HA_SIGNING_ENABLED'
@@ -10,14 +10,15 @@ export type { EnvVar, NetworkNames };
10
10
  export type { NetworkConfig, NetworkConfigMap } from './network_config.js';
11
11
  export { NetworkConfigMapSchema, NetworkConfigSchema } from './network_config.js';
12
12
 
13
- export interface ConfigMapping {
13
+ export interface ConfigMapping<T> {
14
14
  env?: EnvVar;
15
- parseEnv?: (val: string) => any;
16
- defaultValue?: any;
15
+ /** Parse an env-var string into `T`. Throws on invalid input. */
16
+ parseEnv?: (val: string) => T;
17
+ defaultValue?: T;
17
18
  printDefault?: (val: any) => string;
18
19
  description: string;
19
20
  isBoolean?: boolean;
20
- nested?: Record<string, ConfigMapping>;
21
+ nested?: Record<string, ConfigMapping<any>>;
21
22
  fallback?: EnvVar[];
22
23
  /**
23
24
  * List of deprecated env vars that are still supported but will log a warning.
@@ -30,7 +31,9 @@ export function isBooleanConfigValue<T>(obj: T, key: keyof T): boolean {
30
31
  return typeof obj[key] === 'boolean';
31
32
  }
32
33
 
33
- export type ConfigMappingsType<T> = Record<keyof T, ConfigMapping>;
34
+ export type ConfigMappingsType<T> = {
35
+ [K in keyof T]-?: ConfigMapping<Required<T>[K]>;
36
+ };
34
37
 
35
38
  /**
36
39
  * Shared utility function to get a value from environment variables with fallback support.
@@ -66,8 +69,8 @@ export function getValueFromEnvWithFallback<T>(
66
69
  }
67
70
  }
68
71
 
69
- // Parse the value if needed
70
- if (value !== undefined) {
72
+ // Parse the value if needed. Empty strings are treated as "not set".
73
+ if (value !== undefined && value !== '') {
71
74
  return parseFunc ? parseFunc(value) : (value as unknown as T);
72
75
  }
73
76
 
@@ -84,7 +87,11 @@ export function getConfigFromMappings<T>(configMappings: ConfigMappingsType<T>):
84
87
  (config as any)[key] = getConfigFromMappings(nested);
85
88
  } else {
86
89
  // Use the shared utility function
87
- (config as any)[key] = getValueFromEnvWithFallback(env, parseEnv, defaultValue, fallback);
90
+ try {
91
+ (config as any)[key] = getValueFromEnvWithFallback(env, parseEnv, defaultValue, fallback);
92
+ } catch (e: any) {
93
+ throw new Error(`Failed to parse config '${key}' (env: ${env ?? 'none'}): ${e.message}`);
94
+ }
88
95
 
89
96
  // Check for deprecated env vars and warn if logger is set
90
97
  if (deprecatedFallback?.length) {
@@ -123,7 +130,7 @@ export function omitConfigMappings<T, K extends keyof T>(
123
130
  * @param defaultVal - The default numerical value to use if the environment variable is not set or is invalid
124
131
  * @returns Object with parseEnv and default values for a numerical config value
125
132
  */
126
- export function numberConfigHelper(defaultVal: number): Pick<ConfigMapping, 'parseEnv' | 'defaultValue'> {
133
+ export function numberConfigHelper(defaultVal: number): Pick<ConfigMapping<number>, 'parseEnv' | 'defaultValue'> {
127
134
  return {
128
135
  parseEnv: (val: string) => safeParseNumber(val, defaultVal),
129
136
  defaultValue: defaultVal,
@@ -138,7 +145,7 @@ export function numberConfigHelper(defaultVal: number): Pick<ConfigMapping, 'par
138
145
  export function floatConfigHelper(
139
146
  defaultVal: number,
140
147
  validationFn?: (val: number) => void,
141
- ): Pick<ConfigMapping, 'parseEnv' | 'defaultValue'> {
148
+ ): Pick<ConfigMapping<number>, 'parseEnv' | 'defaultValue'> {
142
149
  return {
143
150
  parseEnv: (val: string): number => {
144
151
  const parsed = safeParseFloat(val, defaultVal);
@@ -152,7 +159,7 @@ export function floatConfigHelper(
152
159
  /**
153
160
  * Parses an environment variable to a 0-1 percentage value
154
161
  */
155
- export function percentageConfigHelper(defaultVal: number): Pick<ConfigMapping, 'parseEnv' | 'defaultValue'> {
162
+ export function percentageConfigHelper(defaultVal: number): Pick<ConfigMapping<number>, 'parseEnv' | 'defaultValue'> {
156
163
  return {
157
164
  parseEnv: (val: string): number => {
158
165
  const parsed = safeParseFloat(val, defaultVal);
@@ -171,12 +178,13 @@ export function percentageConfigHelper(defaultVal: number): Pick<ConfigMapping,
171
178
  * @param defaultVal - The default numerical value to use if the environment variable is not set or is invalid
172
179
  * @returns Object with parseEnv and default values for a numerical config value
173
180
  */
174
- export function bigintConfigHelper(defaultVal?: bigint): Pick<ConfigMapping, 'parseEnv' | 'defaultValue'> {
181
+ export function bigintConfigHelper(defaultVal: bigint): Pick<ConfigMapping<bigint>, 'parseEnv' | 'defaultValue'>;
182
+ export function bigintConfigHelper(): Pick<ConfigMapping<bigint | undefined>, 'parseEnv' | 'defaultValue'>;
183
+ export function bigintConfigHelper(
184
+ defaultVal?: bigint,
185
+ ): Pick<ConfigMapping<bigint | undefined>, 'parseEnv' | 'defaultValue'> {
175
186
  return {
176
187
  parseEnv: (val: string) => {
177
- if (val === '') {
178
- return defaultVal;
179
- }
180
188
  // Handle scientific notation (e.g. "1e+23", "2E23") which BigInt() doesn't accept directly.
181
189
  // We parse it losslessly using bigint arithmetic instead of going through float64.
182
190
  if (/[eE]/.test(val)) {
@@ -200,32 +208,37 @@ export function bigintConfigHelper(defaultVal?: bigint): Pick<ConfigMapping, 'pa
200
208
 
201
209
  /**
202
210
  * Generates parseEnv for an optional numerical config value.
211
+ * Empty strings are already handled by getValueFromEnvWithFallback.
203
212
  */
204
- export function optionalNumberConfigHelper(): Pick<ConfigMapping, 'parseEnv'> {
213
+ export function optionalNumberConfigHelper(): Pick<ConfigMapping<number>, 'parseEnv'> {
205
214
  return {
206
- parseEnv: (val: string | undefined) => {
207
- if (val !== undefined && val.length > 0) {
208
- const parsedValue = parseInt(val);
209
- return Number.isSafeInteger(parsedValue) ? parsedValue : undefined;
215
+ parseEnv: (val: string) => {
216
+ const parsedValue = parseInt(val);
217
+ if (!Number.isSafeInteger(parsedValue)) {
218
+ throw new Error(`Invalid number: ${val}`);
210
219
  }
211
- return undefined;
220
+ return parsedValue;
212
221
  },
213
222
  };
214
223
  }
215
224
 
216
225
  /** Generates parseEnv for an enum-like config value. */
226
+ export function enumConfigHelper<T extends string>(
227
+ values: T[],
228
+ defaultValue: NoInfer<T>,
229
+ ): Pick<ConfigMapping<T>, 'parseEnv' | 'defaultValue'>;
230
+ export function enumConfigHelper<T extends string>(
231
+ values: T[],
232
+ ): Pick<ConfigMapping<T | undefined>, 'parseEnv' | 'defaultValue'>;
217
233
  export function enumConfigHelper<T extends string>(
218
234
  values: T[],
219
235
  defaultValue?: NoInfer<T>,
220
- ): Pick<ConfigMapping, 'parseEnv' | 'defaultValue'> {
236
+ ): Pick<ConfigMapping<T | undefined>, 'parseEnv' | 'defaultValue'> {
221
237
  return {
222
238
  parseEnv: (val: string) => {
223
- const sanitizedVal = (val ?? '').trim().toLowerCase();
224
- if (values.includes(sanitizedVal as T)) {
225
- return sanitizedVal as T;
226
- }
227
- if (!val && defaultValue) {
228
- return defaultValue;
239
+ const sanitizedVal = val.trim().toLowerCase();
240
+ if (values.some(v => v.toLowerCase() === sanitizedVal)) {
241
+ return values.find(v => v.toLowerCase() === sanitizedVal)!;
229
242
  }
230
243
  throw new Error(`Invalid config value '${val}' (must be one of ${values.join(', ')})`);
231
244
  },
@@ -240,7 +253,9 @@ export function enumConfigHelper<T extends string>(
240
253
  */
241
254
  export function booleanConfigHelper(
242
255
  defaultVal = false,
243
- ): Required<Pick<ConfigMapping, 'parseEnv' | 'defaultValue' | 'isBoolean'> & { parseVal: (val: string) => boolean }> {
256
+ ): Required<
257
+ Pick<ConfigMapping<boolean>, 'parseEnv' | 'defaultValue' | 'isBoolean'> & { parseVal: (val: string) => boolean }
258
+ > {
244
259
  const parse = (val: string | boolean) => (typeof val === 'boolean' ? val : parseBooleanEnv(val));
245
260
  return {
246
261
  parseEnv: parse,
@@ -250,91 +265,88 @@ export function booleanConfigHelper(
250
265
  };
251
266
  }
252
267
 
253
- export function secretValueConfigHelper<T>(parse: (val: string | undefined) => T): Required<
254
- Pick<ConfigMapping, 'parseEnv' | 'defaultValue' | 'isBoolean'> & {
255
- parseVal: (val: string) => SecretValue<T>;
256
- }
257
- > {
268
+ export function secretValueConfigHelper<T>(parse: (val: string | undefined) => T): Pick<
269
+ ConfigMapping<SecretValue<T>>,
270
+ 'parseEnv' | 'defaultValue'
271
+ > & {
272
+ parseVal: (val: string) => SecretValue<T>;
273
+ } {
258
274
  const wrap = (val: string) => new SecretValue(parse(val));
259
275
  return {
260
276
  parseEnv: wrap,
261
277
  parseVal: wrap,
262
278
  defaultValue: new SecretValue(parse(undefined)),
263
- isBoolean: true,
264
279
  };
265
280
  }
266
281
 
267
282
  export { parseBooleanEnv } from './parse-env.js';
268
283
 
269
- export function secretStringConfigHelper(): Required<
270
- Pick<ConfigMapping, 'parseEnv' | 'defaultValue' | 'isBoolean'> & {
271
- parseVal: (val: string) => SecretValue<string | undefined>;
272
- }
273
- >;
274
- export function secretStringConfigHelper(defaultValue: string): Required<
275
- Pick<ConfigMapping, 'parseEnv' | 'defaultValue' | 'isBoolean'> & {
276
- parseVal: (val: string) => SecretValue<string>;
277
- }
278
- >;
279
- export function secretStringConfigHelper(defaultValue?: string): Required<
280
- Pick<ConfigMapping, 'parseEnv' | 'defaultValue' | 'isBoolean'> & {
281
- parseVal: (val: string) => SecretValue<string | typeof defaultValue>;
282
- }
283
- > {
284
+ export function secretStringConfigHelper(): {
285
+ parseEnv: (val: string) => SecretValue<string>;
286
+ parseVal: (val: string) => SecretValue<string>;
287
+ defaultValue: undefined;
288
+ };
289
+ export function secretStringConfigHelper(defaultValue: string): {
290
+ parseEnv: (val: string) => SecretValue<string>;
291
+ parseVal: (val: string) => SecretValue<string>;
292
+ defaultValue: SecretValue<string>;
293
+ };
294
+ export function secretStringConfigHelper(defaultValue?: string): {
295
+ parseEnv: (val: string) => SecretValue<string>;
296
+ parseVal: (val: string) => SecretValue<string>;
297
+ defaultValue: SecretValue<string> | undefined;
298
+ } {
284
299
  const parse = (val: string) => new SecretValue(val);
285
300
  return {
286
301
  parseEnv: parse,
287
302
  parseVal: parse,
288
303
  defaultValue: defaultValue !== undefined ? new SecretValue(defaultValue) : undefined,
289
- isBoolean: true,
290
304
  };
291
305
  }
292
306
 
293
- export function secretFrConfigHelper(): Required<
294
- Pick<ConfigMapping, 'parseEnv' | 'defaultValue' | 'isBoolean'> & {
295
- parseVal: (val: string) => SecretValue<Fr | undefined>;
296
- }
297
- >;
298
- export function secretFrConfigHelper(defaultValue: Fr): Required<
299
- Pick<ConfigMapping, 'parseEnv' | 'defaultValue' | 'isBoolean'> & {
300
- parseVal: (val: string) => SecretValue<Fr>;
301
- }
302
- >;
303
- export function secretFrConfigHelper(defaultValue?: Fr): Required<
304
- Pick<ConfigMapping, 'parseEnv' | 'defaultValue' | 'isBoolean'> & {
305
- parseVal: (val: string) => SecretValue<Fr | typeof defaultValue>;
306
- }
307
- > {
307
+ export function secretFrConfigHelper(): {
308
+ parseEnv: (val: string) => SecretValue<Fr>;
309
+ parseVal: (val: string) => SecretValue<Fr>;
310
+ defaultValue: undefined;
311
+ };
312
+ export function secretFrConfigHelper(defaultValue: Fr): {
313
+ parseEnv: (val: string) => SecretValue<Fr>;
314
+ parseVal: (val: string) => SecretValue<Fr>;
315
+ defaultValue: SecretValue<Fr>;
316
+ };
317
+ export function secretFrConfigHelper(defaultValue?: Fr): {
318
+ parseEnv: (val: string) => SecretValue<Fr>;
319
+ parseVal: (val: string) => SecretValue<Fr>;
320
+ defaultValue: SecretValue<Fr> | undefined;
321
+ } {
308
322
  const parse = (val: string) => new SecretValue(Fr.fromHexString(val));
309
323
  return {
310
324
  parseEnv: parse,
311
325
  parseVal: parse,
312
326
  defaultValue: defaultValue !== undefined ? new SecretValue(defaultValue) : undefined,
313
- isBoolean: true,
314
327
  };
315
328
  }
316
329
 
317
- export function secretFqConfigHelper(defaultValue: Fq): Required<
318
- Pick<ConfigMapping, 'parseEnv' | 'defaultValue' | 'isBoolean'> & {
319
- parseVal: (val: string) => SecretValue<Fq>;
320
- }
321
- >;
322
- export function secretFqConfigHelper(): Required<
323
- Pick<ConfigMapping, 'parseEnv' | 'defaultValue' | 'isBoolean'> & {
324
- parseVal: (val: string) => SecretValue<Fq | undefined>;
325
- }
326
- >;
327
- export function secretFqConfigHelper(defaultValue?: Fq): Required<
328
- Pick<ConfigMapping, 'parseEnv' | 'defaultValue' | 'isBoolean'> & {
329
- parseVal: (val: string) => SecretValue<Fq | typeof defaultValue>;
330
- }
331
- > {
330
+ export function secretFqConfigHelper(): {
331
+ parseEnv: (val: string) => SecretValue<Fq>;
332
+ parseVal: (val: string) => SecretValue<Fq>;
333
+ defaultValue: undefined;
334
+ };
335
+ export function secretFqConfigHelper(defaultValue: Fq): {
336
+ parseEnv: (val: string) => SecretValue<Fq>;
337
+ parseVal: (val: string) => SecretValue<Fq>;
338
+ defaultValue: SecretValue<Fq>;
339
+ };
340
+ export function secretFqConfigHelper(defaultValue?: Fq): {
341
+ parseEnv: (val: string) => SecretValue<Fq>;
342
+ parseVal: (val: string) => SecretValue<Fq>;
343
+ defaultValue: SecretValue<Fq> | undefined;
344
+ } {
332
345
  const parse = (val: string) => new SecretValue(Fq.fromHexString(val));
333
346
  return {
334
347
  parseEnv: parse,
335
348
  parseVal: parse,
336
- defaultValue: typeof defaultValue !== 'undefined' ? new SecretValue(defaultValue) : undefined,
337
- isBoolean: true,
349
+ defaultValue: defaultValue !== undefined ? new SecretValue(defaultValue) : undefined,
338
350
  };
339
351
  }
340
352
 
@@ -6,7 +6,6 @@ import { toBigIntBE, toBufferBE } from '../../bigint-buffer/index.js';
6
6
  import { randomBytes } from '../../crypto/random/index.js';
7
7
  import { hexSchemaFor } from '../../schemas/utils.js';
8
8
  import { BufferReader } from '../../serialize/buffer_reader.js';
9
- import { TypeRegistry } from '../../serialize/type_registry.js';
10
9
  import { Fr } from '../bn254/field.js';
11
10
 
12
11
  /**
@@ -323,9 +322,6 @@ export class BLS12Fr extends BLS12Field {
323
322
  }
324
323
  }
325
324
 
326
- // For deserializing JSON.
327
- TypeRegistry.register('BLS12Fr', BLS12Fr);
328
-
329
325
  /**
330
326
  * Fq field class.
331
327
  * @dev This class is used to represent elements of BLS12-381 base field.
@@ -458,6 +454,3 @@ export class BLS12Fq extends BLS12Field {
458
454
  return hexSchemaFor(BLS12Fq);
459
455
  }
460
456
  }
461
-
462
- // For deserializing JSON.
463
- TypeRegistry.register('BLS12Fq', BLS12Fq);
@@ -6,9 +6,6 @@ import { toBigIntBE, toBufferBE } from '../../bigint-buffer/index.js';
6
6
  import { randomBytes } from '../../crypto/random/index.js';
7
7
  import { hexSchemaFor } from '../../schemas/utils.js';
8
8
  import { BufferReader } from '../../serialize/buffer_reader.js';
9
- import { TypeRegistry } from '../../serialize/type_registry.js';
10
-
11
- /* eslint-disable @typescript-eslint/no-unsafe-declaration-merging */
12
9
 
13
10
  /**
14
11
  * Represents a field derived from BaseField.
@@ -187,10 +184,25 @@ function fromHexString<T extends BaseField>(buf: string, f: DerivedField<T>) {
187
184
  return new f(toBigIntBE(buffer));
188
185
  }
189
186
 
190
- /** Branding to ensure fields are not interchangeable types. */
191
- export interface Fr {
192
- /** Brand. */
193
- _branding: 'Fr';
187
+ /**
188
+ * Abstract unbranded base class for BN254 scalar field elements.
189
+ * Extend this instead of Fr when defining a branded subtype (e.g. BlockHash)
190
+ * to avoid inheriting Fr's `_branding`.
191
+ */
192
+ export abstract class BaseFr extends BaseField {
193
+ static MODULUS = 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001n;
194
+
195
+ constructor(value: number | bigint | boolean | BaseField | Buffer) {
196
+ super(value);
197
+ }
198
+
199
+ protected modulus() {
200
+ return BaseFr.MODULUS;
201
+ }
202
+
203
+ toJSON() {
204
+ return this.toString();
205
+ }
194
206
  }
195
207
 
196
208
  /**
@@ -198,10 +210,12 @@ export interface Fr {
198
210
  * @dev This class is used to represent elements of BN254 scalar field or elements in the base field of Grumpkin.
199
211
  * (Grumpkin's scalar field corresponds to BN254's base field and vice versa.)
200
212
  */
201
- export class Fr extends BaseField {
213
+ export class Fr extends BaseFr {
214
+ /** Branding for nominal typing. */
215
+ declare private readonly _branding: 'Fr';
216
+ static override MODULUS = 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001n;
202
217
  static ZERO = new Fr(0n);
203
218
  static ONE = new Fr(1n);
204
- static MODULUS = 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001n;
205
219
  static MAX_FIELD_VALUE = new Fr(this.MODULUS - 1n);
206
220
 
207
221
  constructor(value: number | bigint | boolean | Fr | Buffer) {
@@ -212,10 +226,6 @@ export class Fr extends BaseField {
212
226
  return `Fr<${this.toString()}>`;
213
227
  }
214
228
 
215
- protected modulus() {
216
- return Fr.MODULUS;
217
- }
218
-
219
229
  static random() {
220
230
  return random(Fr);
221
231
  }
@@ -320,10 +330,6 @@ export class Fr extends BaseField {
320
330
  return Fr.fromBuffer(Buffer.from(response.value));
321
331
  }
322
332
 
323
- toJSON() {
324
- return this.toString();
325
- }
326
-
327
333
  /**
328
334
  * Creates an Fr instance from a plain object without Zod validation.
329
335
  * This method is optimized for performance and skips validation, making it suitable
@@ -345,23 +351,14 @@ export class Fr extends BaseField {
345
351
  }
346
352
  }
347
353
 
348
- // For deserializing JSON.
349
- TypeRegistry.register('Fr', Fr);
350
-
351
- /**
352
- * Branding to ensure fields are not interchangeable types.
353
- */
354
- export interface Fq {
355
- /** Brand. */
356
- _branding: 'Fq';
357
- }
358
-
359
354
  /**
360
355
  * Fq field class.
361
356
  * @dev This class is used to represent elements of BN254 base field or elements in the scalar field of Grumpkin.
362
357
  * (Grumpkin's scalar field corresponds to BN254's base field and vice versa.)
363
358
  */
364
359
  export class Fq extends BaseField {
360
+ /** Branding for nominal typing. */
361
+ declare private readonly _branding: 'Fq';
365
362
  static ZERO = new Fq(0n);
366
363
  static MODULUS = 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47n;
367
364
  private static HIGH_SHIFT = BigInt((BaseField.SIZE_IN_BYTES / 2) * 8);
@@ -470,9 +467,6 @@ export class Fq extends BaseField {
470
467
  }
471
468
  }
472
469
 
473
- // For deserializing JSON.
474
- TypeRegistry.register('Fq', Fq);
475
-
476
470
  // Beware: Performance bottleneck below
477
471
 
478
472
  /**