@aztec/foundation 0.65.0 → 0.65.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dest/abi/abi.d.ts +9 -9
- package/dest/abi/abi.js +2 -2
- package/dest/abi/event_selector.d.ts +2 -4
- package/dest/abi/event_selector.d.ts.map +1 -1
- package/dest/abi/event_selector.js +6 -5
- package/dest/abi/function_selector.d.ts +2 -4
- package/dest/abi/function_selector.d.ts.map +1 -1
- package/dest/abi/function_selector.js +6 -5
- package/dest/abi/note_selector.d.ts +2 -5
- package/dest/abi/note_selector.d.ts.map +1 -1
- package/dest/abi/note_selector.js +5 -7
- package/dest/abi/selector.d.ts.map +1 -1
- package/dest/abi/selector.js +3 -2
- package/dest/aztec-address/index.d.ts +2 -4
- package/dest/aztec-address/index.d.ts.map +1 -1
- package/dest/aztec-address/index.js +6 -5
- package/dest/buffer/buffer32.d.ts +2 -12
- package/dest/buffer/buffer32.d.ts.map +1 -1
- package/dest/buffer/buffer32.js +3 -16
- package/dest/config/env_var.d.ts +1 -1
- package/dest/config/env_var.d.ts.map +1 -1
- package/dest/crypto/poseidon/index.d.ts +1 -0
- package/dest/crypto/poseidon/index.d.ts.map +1 -1
- package/dest/crypto/poseidon/index.js +7 -1
- package/dest/eth-address/index.d.ts +2 -9
- package/dest/eth-address/index.d.ts.map +1 -1
- package/dest/eth-address/index.js +7 -12
- package/dest/eth-signature/eth_signature.d.ts +5 -3
- package/dest/eth-signature/eth_signature.d.ts.map +1 -1
- package/dest/eth-signature/eth_signature.js +18 -9
- package/dest/fields/fields.d.ts +4 -8
- package/dest/fields/fields.d.ts.map +1 -1
- package/dest/fields/fields.js +10 -10
- package/dest/fields/point.d.ts +6 -4
- package/dest/fields/point.d.ts.map +1 -1
- package/dest/fields/point.js +14 -6
- package/dest/json-rpc/client/fetch.d.ts.map +1 -1
- package/dest/json-rpc/client/fetch.js +20 -14
- package/dest/json-rpc/convert.d.ts.map +1 -1
- package/dest/json-rpc/convert.js +5 -2
- package/dest/json-rpc/index.d.ts +1 -1
- package/dest/json-rpc/index.d.ts.map +1 -1
- package/dest/json-rpc/index.js +2 -2
- package/dest/noir/noir_package_config.d.ts +2 -2
- package/dest/schemas/schemas.d.ts +24 -43
- package/dest/schemas/schemas.d.ts.map +1 -1
- package/dest/schemas/schemas.js +29 -48
- package/dest/schemas/utils.d.ts +18 -7
- package/dest/schemas/utils.d.ts.map +1 -1
- package/dest/schemas/utils.js +20 -8
- package/dest/serialize/type_registry.d.ts.map +1 -1
- package/dest/serialize/type_registry.js +29 -2
- package/dest/string/index.d.ts +1 -0
- package/dest/string/index.d.ts.map +1 -1
- package/dest/string/index.js +4 -1
- package/dest/testing/test_data.js +2 -2
- package/package.json +2 -2
- package/src/abi/abi.ts +1 -1
- package/src/abi/event_selector.ts +6 -4
- package/src/abi/function_selector.ts +6 -4
- package/src/abi/note_selector.ts +4 -6
- package/src/abi/selector.ts +2 -1
- package/src/aztec-address/index.ts +6 -4
- package/src/buffer/buffer32.ts +3 -17
- package/src/config/env_var.ts +1 -0
- package/src/crypto/poseidon/index.ts +11 -0
- package/src/eth-address/index.ts +6 -11
- package/src/eth-signature/eth_signature.ts +20 -9
- package/src/fields/fields.ts +11 -9
- package/src/fields/point.ts +15 -5
- package/src/json-rpc/client/fetch.ts +18 -13
- package/src/json-rpc/convert.ts +3 -1
- package/src/json-rpc/index.ts +1 -1
- package/src/schemas/schemas.ts +28 -51
- package/src/schemas/utils.ts +29 -10
- package/src/serialize/type_registry.ts +33 -1
- package/src/string/index.ts +4 -0
- package/src/testing/test_data.ts +1 -1
package/src/abi/selector.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { inspect } from 'util';
|
|
|
2
2
|
|
|
3
3
|
import { toBufferBE } from '../bigint-buffer/index.js';
|
|
4
4
|
import { Fr } from '../fields/index.js';
|
|
5
|
+
import { bufferToHex } from '../string/index.js';
|
|
5
6
|
|
|
6
7
|
/** A selector is the first 4 bytes of the hash of a signature. */
|
|
7
8
|
export abstract class Selector {
|
|
@@ -36,7 +37,7 @@ export abstract class Selector {
|
|
|
36
37
|
* @returns The string.
|
|
37
38
|
*/
|
|
38
39
|
toString(): string {
|
|
39
|
-
return
|
|
40
|
+
return bufferToHex(this.toBuffer());
|
|
40
41
|
}
|
|
41
42
|
|
|
42
43
|
[inspect.custom]() {
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { inspect } from 'util';
|
|
3
3
|
|
|
4
4
|
import { Fr, Point, fromBuffer } from '../fields/index.js';
|
|
5
|
+
import { hexSchemaFor } from '../schemas/utils.js';
|
|
5
6
|
import { type BufferReader, FieldReader } from '../serialize/index.js';
|
|
6
7
|
import { TypeRegistry } from '../serialize/type_registry.js';
|
|
7
8
|
import { hexToBuffer } from '../string/index.js';
|
|
@@ -133,10 +134,11 @@ export class AztecAddress {
|
|
|
133
134
|
}
|
|
134
135
|
|
|
135
136
|
toJSON() {
|
|
136
|
-
return
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
137
|
+
return this.toString();
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
static get schema() {
|
|
141
|
+
return hexSchemaFor(AztecAddress, AztecAddress.isAddress);
|
|
140
142
|
}
|
|
141
143
|
}
|
|
142
144
|
|
package/src/buffer/buffer32.ts
CHANGED
|
@@ -2,6 +2,8 @@ import { randomBytes } from '@aztec/foundation/crypto';
|
|
|
2
2
|
import { type Fr } from '@aztec/foundation/fields';
|
|
3
3
|
import { BufferReader, deserializeBigInt, serializeBigInt } from '@aztec/foundation/serialize';
|
|
4
4
|
|
|
5
|
+
import { bufferToHex } from '../string/index.js';
|
|
6
|
+
|
|
5
7
|
/**
|
|
6
8
|
* A class representing a 32 byte Buffer.
|
|
7
9
|
*/
|
|
@@ -67,17 +69,13 @@ export class Buffer32 {
|
|
|
67
69
|
* @returns The hex string.
|
|
68
70
|
*/
|
|
69
71
|
public toString() {
|
|
70
|
-
return this.buffer
|
|
72
|
+
return bufferToHex(this.buffer);
|
|
71
73
|
}
|
|
72
74
|
|
|
73
75
|
toJSON() {
|
|
74
76
|
return this.toString();
|
|
75
77
|
}
|
|
76
78
|
|
|
77
|
-
public to0xString(): `0x${string}` {
|
|
78
|
-
return `0x${this.buffer.toString('hex')}`;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
79
|
/**
|
|
82
80
|
* Convert this hash to a big int.
|
|
83
81
|
* @returns The big int.
|
|
@@ -117,18 +115,6 @@ export class Buffer32 {
|
|
|
117
115
|
* @param str - The TX hash in string format.
|
|
118
116
|
* @returns A new Buffer32 object.
|
|
119
117
|
*/
|
|
120
|
-
public static fromStringUnchecked(str: string): Buffer32 {
|
|
121
|
-
return new Buffer32(Buffer.from(str, 'hex'));
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* Converts a string into a Buffer32 object.
|
|
126
|
-
* NOTE: this method includes checks for the 0x prefix and the length of the string.
|
|
127
|
-
* if you dont need this checks, use fromStringUnchecked instead.
|
|
128
|
-
*
|
|
129
|
-
* @param str - The TX hash in string format.
|
|
130
|
-
* @returns A new Buffer32 object.
|
|
131
|
-
*/
|
|
132
118
|
public static fromString(str: string): Buffer32 {
|
|
133
119
|
if (str.startsWith('0x')) {
|
|
134
120
|
str = str.slice(2);
|
package/src/config/env_var.ts
CHANGED
|
@@ -41,6 +41,17 @@ export function poseidon2HashWithSeparator(input: Fieldable[], separator: number
|
|
|
41
41
|
);
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
+
export function poseidon2HashAccumulate(input: Fieldable[]): Fr {
|
|
45
|
+
const inputFields = serializeToFields(input);
|
|
46
|
+
return Fr.fromBuffer(
|
|
47
|
+
Buffer.from(
|
|
48
|
+
BarretenbergSync.getSingleton()
|
|
49
|
+
.poseidon2HashAccumulate(inputFields.map(i => new FrBarretenberg(i.toBuffer())))
|
|
50
|
+
.toBuffer(),
|
|
51
|
+
),
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
44
55
|
/**
|
|
45
56
|
* Runs a Poseidon2 permutation.
|
|
46
57
|
* @param input the input state. Expected to be of size 4.
|
package/src/eth-address/index.ts
CHANGED
|
@@ -3,8 +3,10 @@ import { inspect } from 'util';
|
|
|
3
3
|
import { keccak256String } from '../crypto/keccak/index.js';
|
|
4
4
|
import { randomBytes } from '../crypto/random/index.js';
|
|
5
5
|
import { Fr } from '../fields/index.js';
|
|
6
|
+
import { hexSchemaFor } from '../schemas/utils.js';
|
|
6
7
|
import { BufferReader, FieldReader } from '../serialize/index.js';
|
|
7
8
|
import { TypeRegistry } from '../serialize/type_registry.js';
|
|
9
|
+
import { bufferToHex } from '../string/index.js';
|
|
8
10
|
|
|
9
11
|
/**
|
|
10
12
|
* Represents an Ethereum address as a 20-byte buffer and provides various utility methods
|
|
@@ -154,7 +156,7 @@ export class EthAddress {
|
|
|
154
156
|
* @returns A hex-encoded string representation of the Ethereum address.
|
|
155
157
|
*/
|
|
156
158
|
public toString() {
|
|
157
|
-
return
|
|
159
|
+
return bufferToHex(this.buffer);
|
|
158
160
|
}
|
|
159
161
|
|
|
160
162
|
[inspect.custom]() {
|
|
@@ -226,19 +228,12 @@ export class EthAddress {
|
|
|
226
228
|
return new EthAddress(reader.readBytes(EthAddress.SIZE_IN_BYTES));
|
|
227
229
|
}
|
|
228
230
|
|
|
229
|
-
|
|
230
|
-
* Friendly representation for debugging purposes.
|
|
231
|
-
* @returns A hex string representing the address.
|
|
232
|
-
*/
|
|
233
|
-
toFriendlyJSON() {
|
|
231
|
+
toJSON() {
|
|
234
232
|
return this.toString();
|
|
235
233
|
}
|
|
236
234
|
|
|
237
|
-
|
|
238
|
-
return
|
|
239
|
-
type: 'EthAddress',
|
|
240
|
-
value: this.toString(),
|
|
241
|
-
};
|
|
235
|
+
static get schema() {
|
|
236
|
+
return hexSchemaFor(EthAddress, EthAddress.isAddress);
|
|
242
237
|
}
|
|
243
238
|
}
|
|
244
239
|
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { Buffer32 } from '@aztec/foundation/buffer';
|
|
2
2
|
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
|
|
3
3
|
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
|
|
6
|
+
import { hasHexPrefix, hexToBuffer } from '../string/index.js';
|
|
7
|
+
|
|
4
8
|
/**Viem Signature
|
|
5
9
|
*
|
|
6
10
|
* A version of the Signature class that uses `0x${string}` values for r and s rather than
|
|
@@ -45,7 +49,7 @@ export class Signature {
|
|
|
45
49
|
return new Signature(r, s, v, isEmpty);
|
|
46
50
|
}
|
|
47
51
|
|
|
48
|
-
static
|
|
52
|
+
static isValidString(sig: `0x${string}`): boolean {
|
|
49
53
|
return /^0x[0-9a-f]{129,}$/i.test(sig);
|
|
50
54
|
}
|
|
51
55
|
|
|
@@ -54,10 +58,9 @@ export class Signature {
|
|
|
54
58
|
* parsing from viem, we can expect the v value to be a u8, rather than our
|
|
55
59
|
* default serialization of u32
|
|
56
60
|
*/
|
|
57
|
-
static
|
|
58
|
-
const buf =
|
|
61
|
+
static fromString(sig: `0x${string}`): Signature {
|
|
62
|
+
const buf = hexToBuffer(sig);
|
|
59
63
|
const reader = BufferReader.asReader(buf);
|
|
60
|
-
|
|
61
64
|
const r = reader.readObject(Buffer32);
|
|
62
65
|
const s = reader.readObject(Buffer32);
|
|
63
66
|
const v = parseInt(sig.slice(2 + 64 * 2), 16);
|
|
@@ -95,8 +98,8 @@ export class Signature {
|
|
|
95
98
|
return this.size;
|
|
96
99
|
}
|
|
97
100
|
|
|
98
|
-
|
|
99
|
-
return `0x${this.r.toString()}${this.s.toString()}${this.v.toString(16)}`;
|
|
101
|
+
toString(): `0x${string}` {
|
|
102
|
+
return `0x${this.r.buffer.toString('hex')}${this.s.buffer.toString('hex')}${this.v.toString(16)}`;
|
|
100
103
|
}
|
|
101
104
|
|
|
102
105
|
/**
|
|
@@ -104,14 +107,22 @@ export class Signature {
|
|
|
104
107
|
*/
|
|
105
108
|
toViemSignature(): ViemSignature {
|
|
106
109
|
return {
|
|
107
|
-
r: this.r.
|
|
108
|
-
s: this.s.
|
|
110
|
+
r: this.r.toString(),
|
|
111
|
+
s: this.s.toString(),
|
|
109
112
|
v: this.v,
|
|
110
113
|
isEmpty: this.isEmpty,
|
|
111
114
|
};
|
|
112
115
|
}
|
|
113
116
|
|
|
114
117
|
toJSON() {
|
|
115
|
-
return this.
|
|
118
|
+
return this.toString();
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
static get schema() {
|
|
122
|
+
return z
|
|
123
|
+
.string()
|
|
124
|
+
.refine(hasHexPrefix, 'No hex prefix')
|
|
125
|
+
.refine(Signature.isValidString, 'Not a valid Ethereum signature')
|
|
126
|
+
.transform(Signature.fromString);
|
|
116
127
|
}
|
|
117
128
|
}
|
package/src/fields/fields.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { inspect } from 'util';
|
|
|
4
4
|
|
|
5
5
|
import { toBigIntBE, toBufferBE } from '../bigint-buffer/index.js';
|
|
6
6
|
import { randomBytes } from '../crypto/random/index.js';
|
|
7
|
+
import { hexSchemaFor } from '../schemas/utils.js';
|
|
7
8
|
import { BufferReader } from '../serialize/buffer_reader.js';
|
|
8
9
|
import { TypeRegistry } from '../serialize/type_registry.js';
|
|
9
10
|
|
|
@@ -300,12 +301,12 @@ export class Fr extends BaseField {
|
|
|
300
301
|
return Fr.fromBuffer(rootBuf);
|
|
301
302
|
}
|
|
302
303
|
|
|
303
|
-
// TODO(palla/schemas): Use toString instead of structured type
|
|
304
304
|
toJSON() {
|
|
305
|
-
return
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
305
|
+
return this.toString();
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
static get schema() {
|
|
309
|
+
return hexSchemaFor(Fr);
|
|
309
310
|
}
|
|
310
311
|
}
|
|
311
312
|
|
|
@@ -385,10 +386,11 @@ export class Fq extends BaseField {
|
|
|
385
386
|
}
|
|
386
387
|
|
|
387
388
|
toJSON() {
|
|
388
|
-
return
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
389
|
+
return this.toString();
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
static get schema() {
|
|
393
|
+
return hexSchemaFor(Fq);
|
|
392
394
|
}
|
|
393
395
|
}
|
|
394
396
|
|
package/src/fields/point.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { toBigIntBE } from '../bigint-buffer/index.js';
|
|
2
2
|
import { poseidon2Hash } from '../crypto/poseidon/index.js';
|
|
3
3
|
import { randomBoolean } from '../crypto/random/index.js';
|
|
4
|
+
import { hexSchemaFor } from '../schemas/utils.js';
|
|
4
5
|
import { BufferReader, FieldReader, serializeToBuffer } from '../serialize/index.js';
|
|
6
|
+
import { bufferToHex, hexToBuffer } from '../string/index.js';
|
|
5
7
|
import { Fr } from './fields.js';
|
|
6
8
|
|
|
7
9
|
/**
|
|
@@ -34,6 +36,14 @@ export class Point {
|
|
|
34
36
|
// TODO(#7386): check if on curve
|
|
35
37
|
}
|
|
36
38
|
|
|
39
|
+
toJSON() {
|
|
40
|
+
return this.toString();
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
static get schema() {
|
|
44
|
+
return hexSchemaFor(Point);
|
|
45
|
+
}
|
|
46
|
+
|
|
37
47
|
/**
|
|
38
48
|
* Generate a random Point instance.
|
|
39
49
|
*
|
|
@@ -84,14 +94,14 @@ export class Point {
|
|
|
84
94
|
|
|
85
95
|
/**
|
|
86
96
|
* Create a Point instance from a hex-encoded string.
|
|
87
|
-
* The input
|
|
97
|
+
* The input should be prefixed with '0x' or not, and have exactly 128 hex characters representing the x and y coordinates.
|
|
88
98
|
* Throws an error if the input length is invalid or coordinate values are out of range.
|
|
89
99
|
*
|
|
90
|
-
* @param
|
|
100
|
+
* @param str - The hex-encoded string representing the Point coordinates.
|
|
91
101
|
* @returns A Point instance.
|
|
92
102
|
*/
|
|
93
|
-
static fromString(
|
|
94
|
-
return this.fromBuffer(
|
|
103
|
+
static fromString(str: string) {
|
|
104
|
+
return this.fromBuffer(hexToBuffer(str));
|
|
95
105
|
}
|
|
96
106
|
|
|
97
107
|
/**
|
|
@@ -211,7 +221,7 @@ export class Point {
|
|
|
211
221
|
* @returns A hex-encoded string representing the Point instance.
|
|
212
222
|
*/
|
|
213
223
|
toString() {
|
|
214
|
-
return
|
|
224
|
+
return bufferToHex(this.toBuffer());
|
|
215
225
|
}
|
|
216
226
|
|
|
217
227
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { format } from 'util';
|
|
1
|
+
import { format, inspect } from 'util';
|
|
2
2
|
|
|
3
3
|
import { type DebugLogger, createDebugLogger } from '../../log/index.js';
|
|
4
4
|
import { NoRetryError, makeBackoff, retry } from '../../retry/index.js';
|
|
@@ -25,18 +25,23 @@ export async function defaultFetch(
|
|
|
25
25
|
) {
|
|
26
26
|
log.debug(format(`JsonRpcClient.fetch`, host, rpcMethod, '->', body));
|
|
27
27
|
let resp: Response;
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
28
|
+
try {
|
|
29
|
+
if (useApiEndpoints) {
|
|
30
|
+
resp = await fetch(`${host}/${rpcMethod}`, {
|
|
31
|
+
method: 'POST',
|
|
32
|
+
body: jsonStringify(body),
|
|
33
|
+
headers: { 'content-type': 'application/json' },
|
|
34
|
+
});
|
|
35
|
+
} else {
|
|
36
|
+
resp = await fetch(host, {
|
|
37
|
+
method: 'POST',
|
|
38
|
+
body: jsonStringify({ ...body, method: rpcMethod }),
|
|
39
|
+
headers: { 'content-type': 'application/json' },
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
} catch (err) {
|
|
43
|
+
const errorMessage = `Error fetching from host ${host} with method ${rpcMethod}: ${inspect(err)}`;
|
|
44
|
+
throw new Error(errorMessage);
|
|
40
45
|
}
|
|
41
46
|
|
|
42
47
|
let responseJson;
|
package/src/json-rpc/convert.ts
CHANGED
|
@@ -23,7 +23,9 @@ export function jsonStringify(obj: object, prettify?: boolean): string {
|
|
|
23
23
|
(_key, value) => {
|
|
24
24
|
if (typeof value === 'bigint') {
|
|
25
25
|
return value.toString();
|
|
26
|
-
} else if (typeof value === 'object' && Buffer.
|
|
26
|
+
} else if (typeof value === 'object' && value && value.type === 'Buffer' && Array.isArray(value.data)) {
|
|
27
|
+
return Buffer.from(value.data).toString('base64');
|
|
28
|
+
} else if (typeof value === 'object' && value && Buffer.isBuffer(value)) {
|
|
27
29
|
return value.toString('base64');
|
|
28
30
|
} else if (typeof value === 'object' && value instanceof Map) {
|
|
29
31
|
return Array.from(value.entries());
|
package/src/json-rpc/index.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { jsonStringify } from './convert.js';
|
|
1
|
+
export { jsonStringify, jsonParseWithSchema, tryJsonStringify } from './convert.js';
|
package/src/schemas/schemas.ts
CHANGED
|
@@ -7,65 +7,45 @@ import { NoteSelector } from '../abi/note_selector.js';
|
|
|
7
7
|
import { AztecAddress } from '../aztec-address/index.js';
|
|
8
8
|
import { Buffer32 } from '../buffer/buffer32.js';
|
|
9
9
|
import { EthAddress } from '../eth-address/index.js';
|
|
10
|
-
import { Signature } from '../eth-signature/eth_signature.js';
|
|
11
10
|
import { Fq, Fr } from '../fields/fields.js';
|
|
12
11
|
import { Point } from '../fields/point.js';
|
|
13
|
-
import {
|
|
12
|
+
import { isHex, withoutHexPrefix } from '../string/index.js';
|
|
14
13
|
import { type ZodFor } from './types.js';
|
|
15
|
-
import {
|
|
16
|
-
|
|
17
|
-
const FrSchema = maybeStructuredStringSchemaFor('Fr', Fr, isHex);
|
|
18
|
-
const FqSchema = maybeStructuredStringSchemaFor('Fq', Fq, isHex);
|
|
14
|
+
import { bufferSchema, hexSchema } from './utils.js';
|
|
19
15
|
|
|
20
16
|
/** Validation schemas for common types. Every schema must match its toJSON. */
|
|
21
17
|
export const schemas = {
|
|
22
|
-
/** Accepts
|
|
23
|
-
EthAddress:
|
|
24
|
-
|
|
25
|
-
/** Accepts both a 0x string and a structured `{ type: AztecAddress, value: '0x...' }` */
|
|
26
|
-
AztecAddress: maybeStructuredStringSchemaFor('AztecAddress', AztecAddress, AztecAddress.isAddress),
|
|
18
|
+
/** Accepts a hex string. */
|
|
19
|
+
EthAddress: EthAddress.schema,
|
|
27
20
|
|
|
28
|
-
/** Accepts
|
|
29
|
-
|
|
21
|
+
/** Accepts a hex string. */
|
|
22
|
+
AztecAddress: AztecAddress.schema,
|
|
30
23
|
|
|
31
|
-
/** Accepts
|
|
32
|
-
|
|
24
|
+
/** Accepts a hex string. */
|
|
25
|
+
FunctionSelector: FunctionSelector.schema,
|
|
33
26
|
|
|
34
|
-
/** Accepts
|
|
35
|
-
|
|
27
|
+
/** Accepts a hex string. */
|
|
28
|
+
NoteSelector: NoteSelector.schema,
|
|
36
29
|
|
|
37
|
-
/**
|
|
38
|
-
|
|
30
|
+
/** Accepts a hex string. */
|
|
31
|
+
EventSelector: EventSelector.schema,
|
|
39
32
|
|
|
40
|
-
/**
|
|
41
|
-
|
|
33
|
+
/** Accepts a hex string. */
|
|
34
|
+
Fr: Fr.schema,
|
|
42
35
|
|
|
43
|
-
/**
|
|
44
|
-
|
|
45
|
-
.object({
|
|
46
|
-
x: FrSchema,
|
|
47
|
-
y: FrSchema,
|
|
48
|
-
isInfinite: z.boolean().optional(),
|
|
49
|
-
})
|
|
50
|
-
.or(hexSchema)
|
|
51
|
-
.transform(value =>
|
|
52
|
-
typeof value === 'string' ? Point.fromString(value) : new Point(value.x, value.y, value.isInfinite ?? false),
|
|
53
|
-
),
|
|
36
|
+
/** Accepts a hex string. */
|
|
37
|
+
Fq: Fq.schema,
|
|
54
38
|
|
|
55
|
-
/**
|
|
56
|
-
|
|
57
|
-
.string()
|
|
58
|
-
.refine(hasHexPrefix, 'No hex prefix')
|
|
59
|
-
.refine(Signature.isValid0xString, 'Not a valid Ethereum signature')
|
|
60
|
-
.transform(Signature.from0xString),
|
|
39
|
+
/** Point. Serialized as a hex string. */
|
|
40
|
+
Point: Point.schema,
|
|
61
41
|
|
|
62
|
-
/** Coerces any input to bigint */
|
|
42
|
+
/** Coerces any input to bigint. */
|
|
63
43
|
BigInt: z.union([z.bigint(), z.number(), z.string()]).pipe(z.coerce.bigint()),
|
|
64
44
|
|
|
65
|
-
/** Coerces any input to integer number */
|
|
45
|
+
/** Coerces any input to integer number. */
|
|
66
46
|
Integer: z.union([z.bigint(), z.number(), z.string()]).pipe(z.coerce.number().int()),
|
|
67
47
|
|
|
68
|
-
/** Coerces input to UInt32 */
|
|
48
|
+
/** Coerces input to UInt32. */
|
|
69
49
|
UInt32: z.union([z.bigint(), z.number(), z.string()]).pipe(
|
|
70
50
|
z.coerce
|
|
71
51
|
.number()
|
|
@@ -74,31 +54,28 @@ export const schemas = {
|
|
|
74
54
|
.max(2 ** 32 - 1),
|
|
75
55
|
),
|
|
76
56
|
|
|
77
|
-
/** Accepts a hex string as a Buffer32 type */
|
|
57
|
+
/** Accepts a hex string as a Buffer32 type. */
|
|
78
58
|
Buffer32: z.string().refine(isHex, 'Not a valid hex string').transform(Buffer32.fromString),
|
|
79
59
|
|
|
80
|
-
/** Accepts a base64 string or
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
.string()
|
|
84
|
-
.base64()
|
|
85
|
-
.transform(data => Buffer.from(data, 'base64')),
|
|
60
|
+
/** Accepts a base64 string or an object `{ type: 'Buffer', data: [byte, byte...] }` as a buffer. */
|
|
61
|
+
Buffer: z.union([
|
|
62
|
+
bufferSchema,
|
|
86
63
|
z
|
|
87
64
|
.object({
|
|
88
65
|
type: z.literal('Buffer'),
|
|
89
|
-
data: z.array(z.number().int().max(255)),
|
|
66
|
+
data: z.array(z.number().int().min(0).max(255)),
|
|
90
67
|
})
|
|
91
68
|
.transform(({ data }) => Buffer.from(data)),
|
|
92
69
|
]),
|
|
93
70
|
|
|
94
|
-
/** Accepts a hex string
|
|
71
|
+
/** Accepts a hex string as a buffer. */
|
|
95
72
|
BufferHex: z
|
|
96
73
|
.string()
|
|
97
74
|
.refine(isHex, 'Not a valid hex string')
|
|
98
75
|
.transform(withoutHexPrefix)
|
|
99
76
|
.transform(data => Buffer.from(data, 'hex')),
|
|
100
77
|
|
|
101
|
-
/** Hex string with an optional 0x prefix
|
|
78
|
+
/** Hex string with an optional 0x prefix which gets removed as part of the parsing. */
|
|
102
79
|
HexString: hexSchema,
|
|
103
80
|
};
|
|
104
81
|
|
package/src/schemas/utils.ts
CHANGED
|
@@ -15,6 +15,17 @@ import { type ZodFor } from './types.js';
|
|
|
15
15
|
|
|
16
16
|
export const hexSchema = z.string().refine(isHex, 'Not a valid hex string').transform(withoutHexPrefix);
|
|
17
17
|
|
|
18
|
+
// Copied from zod internals, which was copied from https://stackoverflow.com/questions/7860392/determine-if-string-is-in-base64-using-javascript
|
|
19
|
+
const base64Regex = /^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/;
|
|
20
|
+
|
|
21
|
+
/** Schema for a buffer represented as a base64 string. */
|
|
22
|
+
export const bufferSchema = z
|
|
23
|
+
.string()
|
|
24
|
+
// We only test the str for base64 if it's shorter than 1024 bytes, otherwise we've run into maximum
|
|
25
|
+
// stack size exceeded errors when trying to validate excessively long strings (such as contract bytecode).
|
|
26
|
+
.refine(str => str.length > 1024 || base64Regex.test(str), 'Not a valid base64 string')
|
|
27
|
+
.transform(data => Buffer.from(data, 'base64'));
|
|
28
|
+
|
|
18
29
|
export class ZodNullableOptional<T extends ZodTypeAny> extends ZodOptional<T> {
|
|
19
30
|
_isNullableOptional = true;
|
|
20
31
|
|
|
@@ -43,6 +54,8 @@ export function optional<T extends ZodTypeAny>(schema: T) {
|
|
|
43
54
|
return ZodNullableOptional.create(schema);
|
|
44
55
|
}
|
|
45
56
|
|
|
57
|
+
type ToJsonIs<T, TRet> = T extends { toJSON(): TRet } ? T : never;
|
|
58
|
+
|
|
46
59
|
/**
|
|
47
60
|
* Creates a schema that accepts a hex string and uses it to hydrate an instance.
|
|
48
61
|
* @param klazz - Class that implements either fromString or fromBuffer.
|
|
@@ -50,28 +63,34 @@ export function optional<T extends ZodTypeAny>(schema: T) {
|
|
|
50
63
|
*/
|
|
51
64
|
export function hexSchemaFor<TClass extends { fromString(str: string): any } | { fromBuffer(buf: Buffer): any }>(
|
|
52
65
|
klazz: TClass,
|
|
66
|
+
refinement?: (input: string) => boolean,
|
|
53
67
|
): ZodType<
|
|
54
68
|
TClass extends { fromString(str: string): infer TInstance } | { fromBuffer(buf: Buffer): infer TInstance }
|
|
55
|
-
? TInstance
|
|
69
|
+
? ToJsonIs<TInstance, string>
|
|
56
70
|
: never,
|
|
57
71
|
any,
|
|
58
72
|
string
|
|
59
73
|
> {
|
|
74
|
+
const stringSchema = refinement ? z.string().refine(refinement, `Not a valid instance`) : z.string();
|
|
75
|
+
const hexSchema = stringSchema.refine(isHex, 'Not a valid hex string').transform(withoutHexPrefix);
|
|
60
76
|
return 'fromString' in klazz
|
|
61
77
|
? hexSchema.transform(klazz.fromString.bind(klazz))
|
|
62
78
|
: hexSchema.transform(str => Buffer.from(str, 'hex')).transform(klazz.fromBuffer.bind(klazz));
|
|
63
79
|
}
|
|
64
80
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
81
|
+
/**
|
|
82
|
+
* Creates a schema that accepts a base64 string and uses it to hydrate an instance.
|
|
83
|
+
* @param klazz - Class that implements fromBuffer.
|
|
84
|
+
* @returns A schema for the class.
|
|
85
|
+
*/
|
|
86
|
+
export function bufferSchemaFor<TClass extends { fromBuffer(buf: Buffer): any }>(
|
|
68
87
|
klazz: TClass,
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
88
|
+
): ZodType<
|
|
89
|
+
TClass extends { fromBuffer(buf: Buffer): infer TInstance } ? ToJsonIs<TInstance, Buffer> : never,
|
|
90
|
+
any,
|
|
91
|
+
string
|
|
92
|
+
> {
|
|
93
|
+
return bufferSchema.transform(klazz.fromBuffer.bind(klazz));
|
|
75
94
|
}
|
|
76
95
|
|
|
77
96
|
/** Creates a schema for a js Map type that matches the serialization used in jsonStringify. */
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { mapValues } from '../collection/object.js';
|
|
2
|
+
|
|
1
3
|
type Deserializable = { fromString(str: string): object };
|
|
2
4
|
|
|
3
5
|
/**
|
|
@@ -23,9 +25,39 @@ export class TypeRegistry {
|
|
|
23
25
|
}
|
|
24
26
|
}
|
|
25
27
|
|
|
28
|
+
function replace<T>(value: T) {
|
|
29
|
+
if (
|
|
30
|
+
value &&
|
|
31
|
+
typeof value === 'object' &&
|
|
32
|
+
'toString' in value &&
|
|
33
|
+
TypeRegistry.getConstructor(value.constructor.name)
|
|
34
|
+
) {
|
|
35
|
+
return {
|
|
36
|
+
type: value.constructor.name,
|
|
37
|
+
value: value.toString(),
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return value;
|
|
42
|
+
}
|
|
43
|
+
|
|
26
44
|
// Resolver function that enables JSON serialization of BigInts.
|
|
27
45
|
export function resolver(_: any, value: any) {
|
|
28
|
-
|
|
46
|
+
if (typeof value === 'bigint') {
|
|
47
|
+
return value.toString() + 'n';
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (typeof value === 'object' && value) {
|
|
51
|
+
if (Array.isArray(value)) {
|
|
52
|
+
return value.map(replace);
|
|
53
|
+
} else if (Buffer.isBuffer(value)) {
|
|
54
|
+
return { type: 'buffer', value: value.toString('hex') };
|
|
55
|
+
} else {
|
|
56
|
+
return mapValues(value, replace);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return value;
|
|
29
61
|
}
|
|
30
62
|
|
|
31
63
|
// Reviver function that uses TypeRegistry to instantiate objects.
|
package/src/string/index.ts
CHANGED
|
@@ -14,6 +14,10 @@ export function hexToBuffer(str: string): Buffer {
|
|
|
14
14
|
return Buffer.from(withoutHexPrefix(str), 'hex');
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
+
export function bufferToHex(buffer: Buffer): `0x${string}` {
|
|
18
|
+
return `0x${buffer.toString('hex')}`;
|
|
19
|
+
}
|
|
20
|
+
|
|
17
21
|
export function pluralize(str: string, count: number | bigint, plural?: string): string {
|
|
18
22
|
return count === 1 || count === 1n ? str : plural ?? `${str}s`;
|
|
19
23
|
}
|
package/src/testing/test_data.ts
CHANGED
|
@@ -66,7 +66,7 @@ export function updateInlineTestData(targetFileFromRepoRoot: string, itemName: s
|
|
|
66
66
|
const logger = createConsoleLogger('aztec:testing:test_data');
|
|
67
67
|
const targetFile = getPathToFile(targetFileFromRepoRoot);
|
|
68
68
|
const contents = readFileSync(targetFile, 'utf8').toString();
|
|
69
|
-
const regex = new RegExp(`let ${itemName} =
|
|
69
|
+
const regex = new RegExp(`let ${itemName} =[\\s\\S]*?;`, 'g');
|
|
70
70
|
if (!regex.exec(contents)) {
|
|
71
71
|
throw new Error(`Test data marker for ${itemName} not found in ${targetFile}`);
|
|
72
72
|
}
|