@aztec/foundation 0.61.0 → 0.63.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dest/abi/abi.d.ts +708 -228
- package/dest/abi/abi.d.ts.map +1 -1
- package/dest/abi/abi.js +92 -8
- package/dest/abi/decoder.d.ts.map +1 -1
- package/dest/abi/decoder.js +8 -6
- package/dest/abi/encoder.d.ts.map +1 -1
- package/dest/abi/encoder.js +4 -1
- package/dest/abi/event_selector.d.ts +4 -0
- package/dest/abi/event_selector.d.ts.map +1 -1
- package/dest/abi/event_selector.js +7 -1
- package/dest/abi/utils.d.ts +8 -0
- package/dest/abi/utils.d.ts.map +1 -1
- package/dest/abi/utils.js +23 -1
- package/dest/aztec-address/index.d.ts +19 -3
- package/dest/aztec-address/index.d.ts.map +1 -1
- package/dest/aztec-address/index.js +43 -14
- package/dest/buffer/buffer32.d.ts +1 -0
- package/dest/buffer/buffer32.d.ts.map +1 -1
- package/dest/buffer/buffer32.js +4 -1
- package/dest/config/env_var.d.ts +1 -1
- package/dest/config/env_var.d.ts.map +1 -1
- package/dest/crypto/index.d.ts +1 -0
- package/dest/crypto/index.d.ts.map +1 -1
- package/dest/crypto/index.js +2 -1
- package/dest/crypto/keys/index.d.ts +5 -0
- package/dest/crypto/keys/index.d.ts.map +1 -0
- package/dest/crypto/keys/index.js +8 -0
- package/dest/eth-address/index.d.ts +2 -6
- package/dest/eth-address/index.d.ts.map +1 -1
- package/dest/eth-address/index.js +3 -7
- package/dest/eth-signature/eth_signature.d.ts +2 -0
- package/dest/eth-signature/eth_signature.d.ts.map +1 -1
- package/dest/eth-signature/eth_signature.js +7 -1
- package/dest/fields/fields.d.ts +1 -3
- package/dest/fields/fields.d.ts.map +1 -1
- package/dest/fields/fields.js +2 -1
- package/dest/json-rpc/client/fetch.d.ts +21 -0
- package/dest/json-rpc/client/fetch.d.ts.map +1 -0
- package/dest/json-rpc/client/fetch.js +66 -0
- package/dest/json-rpc/client/index.d.ts +2 -1
- package/dest/json-rpc/client/index.d.ts.map +1 -1
- package/dest/json-rpc/client/index.js +3 -2
- package/dest/json-rpc/client/safe_json_rpc_client.d.ts +13 -0
- package/dest/json-rpc/client/safe_json_rpc_client.d.ts.map +1 -0
- package/dest/json-rpc/client/safe_json_rpc_client.js +45 -0
- package/dest/json-rpc/convert.d.ts +11 -19
- package/dest/json-rpc/convert.d.ts.map +1 -1
- package/dest/json-rpc/convert.js +30 -123
- package/dest/json-rpc/fixtures/test_state.d.ts +45 -3
- package/dest/json-rpc/fixtures/test_state.d.ts.map +1 -1
- package/dest/json-rpc/fixtures/test_state.js +58 -2
- package/dest/json-rpc/index.d.ts +1 -2
- package/dest/json-rpc/index.d.ts.map +1 -1
- package/dest/json-rpc/index.js +2 -3
- package/dest/json-rpc/js_utils.d.ts.map +1 -1
- package/dest/json-rpc/js_utils.js +2 -1
- package/dest/json-rpc/server/index.d.ts +1 -2
- package/dest/json-rpc/server/index.d.ts.map +1 -1
- package/dest/json-rpc/server/index.js +2 -3
- package/dest/json-rpc/server/safe_json_rpc_server.d.ts +112 -0
- package/dest/json-rpc/server/safe_json_rpc_server.d.ts.map +1 -0
- package/dest/json-rpc/server/safe_json_rpc_server.js +275 -0
- package/dest/json-rpc/test/index.d.ts +2 -0
- package/dest/json-rpc/test/index.d.ts.map +1 -0
- package/dest/json-rpc/test/index.js +2 -0
- package/dest/json-rpc/test/integration.d.ts +13 -0
- package/dest/json-rpc/test/integration.d.ts.map +1 -0
- package/dest/json-rpc/test/integration.js +12 -0
- package/dest/log/logger.d.ts +10 -2
- package/dest/log/logger.d.ts.map +1 -1
- package/dest/log/logger.js +55 -12
- package/dest/schemas/api.d.ts +21 -0
- package/dest/schemas/api.d.ts.map +1 -0
- package/dest/schemas/api.js +8 -0
- package/dest/schemas/index.d.ts +6 -0
- package/dest/schemas/index.d.ts.map +1 -0
- package/dest/schemas/index.js +6 -0
- package/dest/schemas/parse.d.ts +9 -0
- package/dest/schemas/parse.d.ts.map +1 -0
- package/dest/schemas/parse.js +26 -0
- package/dest/schemas/schemas.d.ts +79 -0
- package/dest/schemas/schemas.d.ts.map +1 -0
- package/dest/schemas/schemas.js +87 -0
- package/dest/schemas/types.d.ts +3 -0
- package/dest/schemas/types.d.ts.map +1 -0
- package/dest/schemas/types.js +2 -0
- package/dest/schemas/utils.d.ts +40 -0
- package/dest/schemas/utils.d.ts.map +1 -0
- package/dest/schemas/utils.js +56 -0
- package/dest/string/index.d.ts +7 -0
- package/dest/string/index.d.ts.map +1 -0
- package/dest/string/index.js +13 -0
- package/dest/types/index.d.ts +2 -0
- package/dest/types/index.d.ts.map +1 -1
- package/dest/validation/index.d.ts +6 -0
- package/dest/validation/index.d.ts.map +1 -1
- package/dest/validation/index.js +11 -1
- package/dest/wasm/wasm_module.js +1 -1
- package/package.json +7 -4
- package/src/abi/abi.ts +203 -233
- package/src/abi/decoder.ts +9 -5
- package/src/abi/encoder.ts +2 -0
- package/src/abi/event_selector.ts +7 -0
- package/src/abi/utils.ts +28 -0
- package/src/aztec-address/index.ts +64 -18
- package/src/buffer/buffer32.ts +5 -0
- package/src/config/env_var.ts +22 -8
- package/src/crypto/index.ts +1 -0
- package/src/crypto/keys/index.ts +9 -0
- package/src/eth-address/index.ts +2 -6
- package/src/eth-signature/eth_signature.ts +8 -0
- package/src/fields/fields.ts +2 -3
- package/src/json-rpc/client/fetch.ts +81 -0
- package/src/json-rpc/client/index.ts +2 -1
- package/src/json-rpc/client/safe_json_rpc_client.ts +61 -0
- package/src/json-rpc/convert.ts +29 -142
- package/src/json-rpc/fixtures/test_state.ts +87 -3
- package/src/json-rpc/index.ts +1 -8
- package/src/json-rpc/js_utils.ts +1 -0
- package/src/json-rpc/server/index.ts +1 -2
- package/src/json-rpc/server/safe_json_rpc_server.ts +336 -0
- package/src/json-rpc/test/index.ts +1 -0
- package/src/json-rpc/test/integration.ts +24 -0
- package/src/log/logger.ts +59 -15
- package/src/schemas/api.ts +47 -0
- package/src/schemas/index.ts +5 -0
- package/src/schemas/parse.ts +29 -0
- package/src/schemas/schemas.ts +111 -0
- package/src/schemas/types.ts +3 -0
- package/src/schemas/utils.ts +85 -0
- package/src/string/index.ts +15 -0
- package/src/types/index.ts +3 -0
- package/src/validation/index.ts +11 -0
- package/src/wasm/wasm_module.ts +1 -1
- package/dest/json-rpc/class_converter.d.ts +0 -144
- package/dest/json-rpc/class_converter.d.ts.map +0 -1
- package/dest/json-rpc/class_converter.js +0 -102
- package/dest/json-rpc/client/json_rpc_client.d.ts +0 -35
- package/dest/json-rpc/client/json_rpc_client.d.ts.map +0 -1
- package/dest/json-rpc/client/json_rpc_client.js +0 -117
- package/dest/json-rpc/server/json_proxy.d.ts +0 -30
- package/dest/json-rpc/server/json_proxy.d.ts.map +0 -1
- package/dest/json-rpc/server/json_proxy.js +0 -46
- package/dest/json-rpc/server/json_rpc_server.d.ts +0 -98
- package/dest/json-rpc/server/json_rpc_server.d.ts.map +0 -1
- package/dest/json-rpc/server/json_rpc_server.js +0 -248
- package/src/json-rpc/class_converter.ts +0 -213
- package/src/json-rpc/client/json_rpc_client.ts +0 -148
- package/src/json-rpc/server/json_proxy.ts +0 -60
- package/src/json-rpc/server/json_rpc_server.ts +0 -300
|
@@ -1,9 +1,16 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-unsafe-declaration-merging */
|
|
1
2
|
import { inspect } from 'util';
|
|
2
3
|
|
|
3
4
|
import { Fr, fromBuffer } from '../fields/index.js';
|
|
4
5
|
import { type BufferReader, FieldReader } from '../serialize/index.js';
|
|
5
6
|
import { TypeRegistry } from '../serialize/type_registry.js';
|
|
7
|
+
import { hexToBuffer } from '../string/index.js';
|
|
6
8
|
|
|
9
|
+
/** Branding to ensure fields are not interchangeable types. */
|
|
10
|
+
export interface AztecAddress {
|
|
11
|
+
/** Brand. */
|
|
12
|
+
_branding: 'AztecAddress';
|
|
13
|
+
}
|
|
7
14
|
/**
|
|
8
15
|
* AztecAddress represents a 32-byte address in the Aztec Protocol.
|
|
9
16
|
* It provides methods to create, manipulate, and compare addresses.
|
|
@@ -11,51 +18,90 @@ import { TypeRegistry } from '../serialize/type_registry.js';
|
|
|
11
18
|
* It should have a value less than or equal to this max value.
|
|
12
19
|
* This class also provides helper functions to convert addresses from strings, buffers, and other formats.
|
|
13
20
|
*/
|
|
14
|
-
export class AztecAddress
|
|
15
|
-
|
|
16
|
-
|
|
21
|
+
export class AztecAddress {
|
|
22
|
+
private value: Fr;
|
|
23
|
+
|
|
24
|
+
constructor(buffer: Buffer | Fr) {
|
|
25
|
+
if ('length' in buffer && buffer.length !== 32) {
|
|
17
26
|
throw new Error(`Invalid AztecAddress length ${buffer.length}.`);
|
|
18
27
|
}
|
|
19
|
-
|
|
28
|
+
this.value = new Fr(buffer);
|
|
20
29
|
}
|
|
21
30
|
|
|
22
31
|
[inspect.custom]() {
|
|
23
32
|
return `AztecAddress<${this.toString()}>`;
|
|
24
33
|
}
|
|
25
34
|
|
|
26
|
-
static
|
|
35
|
+
static isAddress(str: string) {
|
|
36
|
+
return /^(0x)?[a-fA-F0-9]{64}$/.test(str);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
static SIZE_IN_BYTES = Fr.SIZE_IN_BYTES;
|
|
40
|
+
|
|
41
|
+
static ZERO = new AztecAddress(Buffer.alloc(32, 0));
|
|
27
42
|
|
|
28
|
-
static
|
|
43
|
+
static zero(): AztecAddress {
|
|
29
44
|
return AztecAddress.ZERO;
|
|
30
45
|
}
|
|
31
46
|
|
|
32
|
-
static
|
|
33
|
-
return
|
|
47
|
+
static fromField(fr: Fr) {
|
|
48
|
+
return new AztecAddress(fr);
|
|
34
49
|
}
|
|
35
50
|
|
|
36
|
-
static
|
|
37
|
-
return new AztecAddress(
|
|
51
|
+
static fromBuffer(buffer: Buffer | BufferReader) {
|
|
52
|
+
return new AztecAddress(fromBuffer(buffer, Fr));
|
|
38
53
|
}
|
|
39
54
|
|
|
40
55
|
static fromFields(fields: Fr[] | FieldReader) {
|
|
41
56
|
const reader = FieldReader.asReader(fields);
|
|
42
|
-
return AztecAddress
|
|
57
|
+
return new AztecAddress(reader.readField());
|
|
43
58
|
}
|
|
44
59
|
|
|
45
60
|
static fromBigInt(value: bigint) {
|
|
46
|
-
return AztecAddress
|
|
61
|
+
return new AztecAddress(new Fr(value));
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
static fromNumber(value: number) {
|
|
65
|
+
return new AztecAddress(new Fr(value));
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
static fromString(buf: string) {
|
|
69
|
+
return new AztecAddress(hexToBuffer(buf));
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
static random() {
|
|
73
|
+
return new AztecAddress(Fr.random());
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
get size() {
|
|
77
|
+
return this.value.size;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
equals(other: AztecAddress) {
|
|
81
|
+
return this.value.equals(other.value);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
isZero() {
|
|
85
|
+
return this.value.isZero();
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
toBuffer() {
|
|
89
|
+
return this.value.toBuffer();
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
toBigInt() {
|
|
93
|
+
return this.value.toBigInt();
|
|
47
94
|
}
|
|
48
95
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
return new AztecAddress(buffer);
|
|
96
|
+
toField() {
|
|
97
|
+
return this.value;
|
|
52
98
|
}
|
|
53
99
|
|
|
54
|
-
|
|
55
|
-
return
|
|
100
|
+
toString() {
|
|
101
|
+
return this.value.toString();
|
|
56
102
|
}
|
|
57
103
|
|
|
58
|
-
|
|
104
|
+
toJSON() {
|
|
59
105
|
return {
|
|
60
106
|
type: 'AztecAddress',
|
|
61
107
|
value: this.toString(),
|
package/src/buffer/buffer32.ts
CHANGED
|
@@ -70,6 +70,10 @@ export class Buffer32 {
|
|
|
70
70
|
return this.buffer.toString('hex');
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
+
toJSON() {
|
|
74
|
+
return this.toString();
|
|
75
|
+
}
|
|
76
|
+
|
|
73
77
|
public to0xString(): `0x${string}` {
|
|
74
78
|
return `0x${this.buffer.toString('hex')}`;
|
|
75
79
|
}
|
|
@@ -89,6 +93,7 @@ export class Buffer32 {
|
|
|
89
93
|
public static fromBigInt(hash: bigint) {
|
|
90
94
|
return new Buffer32(serializeBigInt(hash, Buffer32.SIZE));
|
|
91
95
|
}
|
|
96
|
+
|
|
92
97
|
public static fromField(hash: Fr) {
|
|
93
98
|
return new Buffer32(serializeBigInt(hash.toBigInt()));
|
|
94
99
|
}
|
package/src/config/env_var.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export type EnvVar =
|
|
2
2
|
| 'ACVM_BINARY_PATH'
|
|
3
3
|
| 'ACVM_WORKING_DIRECTORY'
|
|
4
|
-
| '
|
|
4
|
+
| 'GOVERNANCE_CONTRACT_ADDRESS'
|
|
5
5
|
| 'API_KEY'
|
|
6
6
|
| 'API_PREFIX'
|
|
7
7
|
| 'ARCHIVER_MAX_LOGS'
|
|
@@ -33,8 +33,11 @@ export type EnvVar =
|
|
|
33
33
|
| 'BOT_TOKEN_SALT'
|
|
34
34
|
| 'BOT_TX_INTERVAL_SECONDS'
|
|
35
35
|
| 'BOT_TX_MINED_WAIT_SECONDS'
|
|
36
|
+
| 'BOT_MAX_CONSECUTIVE_ERRORS'
|
|
37
|
+
| 'BOT_STOP_WHEN_UNHEALTHY'
|
|
36
38
|
| 'COINBASE'
|
|
37
39
|
| 'DATA_DIRECTORY'
|
|
40
|
+
| 'DATA_STORE_MAP_SIZE_KB'
|
|
38
41
|
| 'DEBUG'
|
|
39
42
|
| 'DEPLOY_AZTEC_CONTRACTS_SALT'
|
|
40
43
|
| 'DEPLOY_AZTEC_CONTRACTS'
|
|
@@ -44,8 +47,8 @@ export type EnvVar =
|
|
|
44
47
|
| 'FEE_JUICE_CONTRACT_ADDRESS'
|
|
45
48
|
| 'FEE_JUICE_PORTAL_CONTRACT_ADDRESS'
|
|
46
49
|
| 'FEE_RECIPIENT'
|
|
47
|
-
| '
|
|
48
|
-
| '
|
|
50
|
+
| 'GOVERNANCE_PROPOSER_CONTRACT_ADDRESS'
|
|
51
|
+
| 'GOVERNANCE_PROPOSER_PAYLOAD_ADDRESS'
|
|
49
52
|
| 'INBOX_CONTRACT_ADDRESS'
|
|
50
53
|
| 'L1_CHAIN_ID'
|
|
51
54
|
| 'L1_PRIVATE_KEY'
|
|
@@ -55,12 +58,16 @@ export type EnvVar =
|
|
|
55
58
|
| 'MNEMONIC'
|
|
56
59
|
| 'NETWORK_NAME'
|
|
57
60
|
| 'NETWORK'
|
|
58
|
-
| '
|
|
61
|
+
| 'COIN_ISSUER_CONTRACT_ADDRESS'
|
|
59
62
|
| 'OTEL_EXPORTER_OTLP_METRICS_ENDPOINT'
|
|
60
63
|
| 'OTEL_EXPORTER_OTLP_TRACES_ENDPOINT'
|
|
64
|
+
| 'OTEL_EXPORTER_OTLP_LOGS_ENDPOINT'
|
|
61
65
|
| 'OTEL_SERVICE_NAME'
|
|
66
|
+
| 'OTEL_COLLECT_INTERVAL_MS'
|
|
67
|
+
| 'OTEL_EXPORT_TIMEOUT_MS'
|
|
62
68
|
| 'OUTBOX_CONTRACT_ADDRESS'
|
|
63
69
|
| 'P2P_BLOCK_CHECK_INTERVAL_MS'
|
|
70
|
+
| 'P2P_BLOCK_REQUEST_BATCH_SIZE'
|
|
64
71
|
| 'P2P_ENABLED'
|
|
65
72
|
| 'P2P_GOSSIPSUB_D'
|
|
66
73
|
| 'P2P_GOSSIPSUB_DHI'
|
|
@@ -106,7 +113,6 @@ export type EnvVar =
|
|
|
106
113
|
| 'PROVER_REQUIRED_CONFIRMATIONS'
|
|
107
114
|
| 'PROVER_TEST_DELAY_MS'
|
|
108
115
|
| 'PXE_BLOCK_POLLING_INTERVAL_MS'
|
|
109
|
-
| 'PXE_DATA_DIRECTORY'
|
|
110
116
|
| 'PXE_L2_STARTING_BLOCK'
|
|
111
117
|
| 'PXE_PROVER_ENABLED'
|
|
112
118
|
| 'QUOTE_PROVIDER_BASIS_POINT_FEE'
|
|
@@ -127,12 +133,13 @@ export type EnvVar =
|
|
|
127
133
|
| 'SEQ_PUBLISHER_PRIVATE_KEY'
|
|
128
134
|
| 'SEQ_REQUIRED_CONFIRMATIONS'
|
|
129
135
|
| 'SEQ_TX_POLLING_INTERVAL_MS'
|
|
130
|
-
| '
|
|
136
|
+
| 'SEQ_ENFORCE_TIME_TABLE'
|
|
137
|
+
| 'REWARD_DISTRIBUTOR_CONTRACT_ADDRESS'
|
|
131
138
|
| 'TELEMETRY'
|
|
132
139
|
| 'TEST_ACCOUNTS'
|
|
133
140
|
| 'TX_GOSSIP_VERSION'
|
|
134
141
|
| 'TXE_PORT'
|
|
135
|
-
| '
|
|
142
|
+
| 'VALIDATOR_ATTESTATIONS_POLLING_INTERVAL_MS'
|
|
136
143
|
| 'VALIDATOR_ATTESTATIONS_WAIT_TIMEOUT_MS'
|
|
137
144
|
| 'VALIDATOR_DISABLED'
|
|
138
145
|
| 'VALIDATOR_PRIVATE_KEY'
|
|
@@ -143,4 +150,11 @@ export type EnvVar =
|
|
|
143
150
|
| 'VERIFIER_VIEM_POLLING_INTERVAL_MS'
|
|
144
151
|
| 'L1_READER_VIEM_POLLING_INTERVAL_MS'
|
|
145
152
|
| 'PROVER_VIEM_POLLING_INTERVAL_MS'
|
|
146
|
-
| 'SEQ_VIEM_POLLING_INTERVAL_MS'
|
|
153
|
+
| 'SEQ_VIEM_POLLING_INTERVAL_MS'
|
|
154
|
+
| 'WS_DB_MAP_SIZE_KB'
|
|
155
|
+
| 'WS_DATA_DIRECTORY'
|
|
156
|
+
| 'ETHEREUM_SLOT_DURATION'
|
|
157
|
+
| 'AZTEC_SLOT_DURATION'
|
|
158
|
+
| 'AZTEC_EPOCH_DURATION'
|
|
159
|
+
| 'AZTEC_TARGET_COMMITTEE_SIZE'
|
|
160
|
+
| 'AZTEC_EPOCH_PROOF_CLAIM_WINDOW_IN_L2_SLOTS';
|
package/src/crypto/index.ts
CHANGED
|
@@ -7,6 +7,7 @@ export * from './sha512/index.js';
|
|
|
7
7
|
export * from './pedersen/index.js';
|
|
8
8
|
export * from './poseidon/index.js';
|
|
9
9
|
export * from './secp256k1-signer/index.js';
|
|
10
|
+
export * from './keys/index.js';
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* Init the bb singleton. This constructs (if not already) the barretenberg sync api within bb.js itself.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { BarretenbergSync, RawBuffer } from '@aztec/bb.js';
|
|
2
|
+
|
|
3
|
+
import { Fr } from '../../fields/fields.js';
|
|
4
|
+
|
|
5
|
+
export function vkAsFieldsMegaHonk(input: Buffer): Fr[] {
|
|
6
|
+
return BarretenbergSync.getSingleton()
|
|
7
|
+
.acirVkAsFieldsMegaHonk(new RawBuffer(input))
|
|
8
|
+
.map(bbFr => Fr.fromBuffer(Buffer.from(bbFr.toBuffer()))); // TODO(#4189): remove this conversion
|
|
9
|
+
}
|
package/src/eth-address/index.ts
CHANGED
|
@@ -13,13 +13,9 @@ import { TypeRegistry } from '../serialize/type_registry.js';
|
|
|
13
13
|
* and can be serialized/deserialized from a buffer or BufferReader.
|
|
14
14
|
*/
|
|
15
15
|
export class EthAddress {
|
|
16
|
-
/**
|
|
17
|
-
* The size of an Ethereum address in bytes.
|
|
18
|
-
*/
|
|
16
|
+
/** The size of an Ethereum address in bytes. */
|
|
19
17
|
public static SIZE_IN_BYTES = 20;
|
|
20
|
-
/**
|
|
21
|
-
* Represents a zero Ethereum address with 20 bytes filled with zeros.
|
|
22
|
-
*/
|
|
18
|
+
/** Represents a zero Ethereum address with 20 bytes filled with zeros. */
|
|
23
19
|
public static ZERO = new EthAddress(Buffer.alloc(EthAddress.SIZE_IN_BYTES));
|
|
24
20
|
|
|
25
21
|
constructor(private buffer: Buffer) {
|
|
@@ -45,6 +45,10 @@ export class Signature {
|
|
|
45
45
|
return new Signature(r, s, v, isEmpty);
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
+
static isValid0xString(sig: `0x${string}`): boolean {
|
|
49
|
+
return /^0x[0-9a-f]{129,}$/i.test(sig);
|
|
50
|
+
}
|
|
51
|
+
|
|
48
52
|
/**
|
|
49
53
|
* A seperate method exists for this as when signing locally with viem, as when
|
|
50
54
|
* parsing from viem, we can expect the v value to be a u8, rather than our
|
|
@@ -106,4 +110,8 @@ export class Signature {
|
|
|
106
110
|
isEmpty: this.isEmpty,
|
|
107
111
|
};
|
|
108
112
|
}
|
|
113
|
+
|
|
114
|
+
toJSON() {
|
|
115
|
+
return this.to0xString();
|
|
116
|
+
}
|
|
109
117
|
}
|
package/src/fields/fields.ts
CHANGED
|
@@ -182,9 +182,7 @@ function fromHexString<T extends BaseField>(buf: string, f: DerivedField<T>) {
|
|
|
182
182
|
return new f(buffer);
|
|
183
183
|
}
|
|
184
184
|
|
|
185
|
-
/**
|
|
186
|
-
* Branding to ensure fields are not interchangeable types.
|
|
187
|
-
*/
|
|
185
|
+
/** Branding to ensure fields are not interchangeable types. */
|
|
188
186
|
export interface Fr {
|
|
189
187
|
/** Brand. */
|
|
190
188
|
_branding: 'Fr';
|
|
@@ -302,6 +300,7 @@ export class Fr extends BaseField {
|
|
|
302
300
|
return Fr.fromBuffer(rootBuf);
|
|
303
301
|
}
|
|
304
302
|
|
|
303
|
+
// TODO(palla/schemas): Use toString instead of structured type
|
|
305
304
|
toJSON() {
|
|
306
305
|
return {
|
|
307
306
|
type: 'Fr',
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { format } from 'util';
|
|
2
|
+
|
|
3
|
+
import { type DebugLogger, createDebugLogger } from '../../log/index.js';
|
|
4
|
+
import { NoRetryError, makeBackoff, retry } from '../../retry/index.js';
|
|
5
|
+
import { jsonStringify } from '../convert.js';
|
|
6
|
+
|
|
7
|
+
const log = createDebugLogger('json-rpc:json_rpc_client');
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* A normal fetch function that does not retry.
|
|
11
|
+
* Alternatives are a fetch function with retries, or a mocked fetch.
|
|
12
|
+
* @param host - The host URL.
|
|
13
|
+
* @param method - The RPC method name.
|
|
14
|
+
* @param body - The RPC payload.
|
|
15
|
+
* @param noRetry - Whether to throw a `NoRetryError` in case the response is a 5xx error and the body contains an error
|
|
16
|
+
* message (see `retry` function for more details).
|
|
17
|
+
* @returns The parsed JSON response, or throws an error.
|
|
18
|
+
*/
|
|
19
|
+
export async function defaultFetch(
|
|
20
|
+
host: string,
|
|
21
|
+
rpcMethod: string,
|
|
22
|
+
body: any,
|
|
23
|
+
useApiEndpoints: boolean,
|
|
24
|
+
noRetry = false,
|
|
25
|
+
) {
|
|
26
|
+
log.debug(format(`JsonRpcClient.fetch`, host, rpcMethod, '->', body));
|
|
27
|
+
let resp: Response;
|
|
28
|
+
if (useApiEndpoints) {
|
|
29
|
+
resp = await fetch(`${host}/${rpcMethod}`, {
|
|
30
|
+
method: 'POST',
|
|
31
|
+
body: jsonStringify(body),
|
|
32
|
+
headers: { 'content-type': 'application/json' },
|
|
33
|
+
});
|
|
34
|
+
} else {
|
|
35
|
+
resp = await fetch(host, {
|
|
36
|
+
method: 'POST',
|
|
37
|
+
body: jsonStringify({ ...body, method: rpcMethod }),
|
|
38
|
+
headers: { 'content-type': 'application/json' },
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
let responseJson;
|
|
43
|
+
try {
|
|
44
|
+
responseJson = await resp.json();
|
|
45
|
+
} catch (err) {
|
|
46
|
+
if (!resp.ok) {
|
|
47
|
+
throw new Error(resp.statusText);
|
|
48
|
+
}
|
|
49
|
+
throw new Error(`Failed to parse body as JSON: ${resp.text()}`);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (!resp.ok) {
|
|
53
|
+
const errorMessage = `(JSON-RPC PROPAGATED) (host ${host}) (method ${rpcMethod}) (code ${resp.status}) ${responseJson.error.message}`;
|
|
54
|
+
if (noRetry || (resp.status >= 400 && resp.status < 500)) {
|
|
55
|
+
throw new NoRetryError(errorMessage);
|
|
56
|
+
} else {
|
|
57
|
+
throw new Error(errorMessage);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return responseJson;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Makes a fetch function that retries based on the given attempts.
|
|
66
|
+
* @param retries - Sequence of intervals (in seconds) to retry.
|
|
67
|
+
* @param noRetry - Whether to stop retries on server errors.
|
|
68
|
+
* @param log - Optional logger for logging attempts.
|
|
69
|
+
* @returns A fetch function.
|
|
70
|
+
*/
|
|
71
|
+
export function makeFetch(retries: number[], defaultNoRetry: boolean, log?: DebugLogger) {
|
|
72
|
+
return async (host: string, rpcMethod: string, body: any, useApiEndpoints: boolean, noRetry?: boolean) => {
|
|
73
|
+
return await retry(
|
|
74
|
+
() => defaultFetch(host, rpcMethod, body, useApiEndpoints, noRetry ?? defaultNoRetry),
|
|
75
|
+
`JsonRpcClient request ${rpcMethod} to ${host}`,
|
|
76
|
+
makeBackoff(retries),
|
|
77
|
+
log,
|
|
78
|
+
false,
|
|
79
|
+
);
|
|
80
|
+
};
|
|
81
|
+
}
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export
|
|
1
|
+
export * from './safe_json_rpc_client.js';
|
|
2
|
+
export * from './fetch.js';
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { format } from 'util';
|
|
2
|
+
|
|
3
|
+
import { createDebugLogger } from '../../log/logger.js';
|
|
4
|
+
import { type ApiSchema, type ApiSchemaFor, schemaHasMethod } from '../../schemas/api.js';
|
|
5
|
+
import { defaultFetch } from './fetch.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Creates a Proxy object that delegates over RPC and validates outputs against a given schema.
|
|
9
|
+
* The server is expected to be a JsonRpcServer.
|
|
10
|
+
* @param host - The host URL.
|
|
11
|
+
* @param schema - The api schema to validate returned data against.
|
|
12
|
+
* @param useApiEndpoints - Whether to use the API endpoints or the default RPC endpoint.
|
|
13
|
+
* @param namespaceMethods - String value (or false/empty) to namespace all methods sent to the server. e.g. 'getInfo' -\> 'pxe_getInfo'
|
|
14
|
+
* @param fetch - The fetch implementation to use.
|
|
15
|
+
*/
|
|
16
|
+
export function createSafeJsonRpcClient<T extends object>(
|
|
17
|
+
host: string,
|
|
18
|
+
schema: ApiSchemaFor<T>,
|
|
19
|
+
useApiEndpoints: boolean = false,
|
|
20
|
+
namespaceMethods?: string | false,
|
|
21
|
+
fetch = defaultFetch,
|
|
22
|
+
log = createDebugLogger('json-rpc:client'),
|
|
23
|
+
): T {
|
|
24
|
+
let id = 0;
|
|
25
|
+
const request = async (methodName: string, params: any[]): Promise<any> => {
|
|
26
|
+
if (!schemaHasMethod(schema, methodName)) {
|
|
27
|
+
throw new Error(`Unspecified method ${methodName} in client schema`);
|
|
28
|
+
}
|
|
29
|
+
const method = namespaceMethods ? `${namespaceMethods}_${methodName}` : methodName;
|
|
30
|
+
const body = { jsonrpc: '2.0', id: id++, method, params };
|
|
31
|
+
|
|
32
|
+
log.debug(format(`request`, method, params));
|
|
33
|
+
const res = await fetch(host, method, body, useApiEndpoints);
|
|
34
|
+
log.debug(format(`result`, method, res));
|
|
35
|
+
|
|
36
|
+
if (res.error) {
|
|
37
|
+
throw res.error;
|
|
38
|
+
}
|
|
39
|
+
// TODO(palla/schemas): Find a better way to handle null responses (JSON.stringify(null) is string "null").
|
|
40
|
+
if ([null, undefined, 'null', 'undefined'].includes(res.result)) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return (schema as ApiSchema)[methodName].returnType().parse(res.result);
|
|
45
|
+
};
|
|
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;
|
|
59
|
+
|
|
60
|
+
return proxy;
|
|
61
|
+
}
|
package/src/json-rpc/convert.ts
CHANGED
|
@@ -1,163 +1,50 @@
|
|
|
1
1
|
import { Buffer } from 'buffer';
|
|
2
|
-
import cloneDeepWith from 'lodash.clonedeepwith';
|
|
3
2
|
|
|
4
|
-
import { type
|
|
3
|
+
import { type ZodFor } from '../schemas/types.js';
|
|
5
4
|
|
|
6
5
|
/**
|
|
7
|
-
*
|
|
8
|
-
* @param
|
|
9
|
-
* @
|
|
6
|
+
* Parses a json string and then feeds it to a zod schema.
|
|
7
|
+
* @param json - JSON string.
|
|
8
|
+
* @param schema - Zod schema.
|
|
9
|
+
* @returns Result of parsing json with schema.
|
|
10
10
|
*/
|
|
11
|
-
function
|
|
12
|
-
|
|
13
|
-
return false;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
let proto = obj;
|
|
17
|
-
let counter = 0;
|
|
18
|
-
const MAX_PROTOTYPE_CHAIN_LENGTH = 1000; // Adjust as needed
|
|
19
|
-
while (Object.getPrototypeOf(proto) !== null) {
|
|
20
|
-
if (counter >= MAX_PROTOTYPE_CHAIN_LENGTH) {
|
|
21
|
-
// This is a failsafe in case circular prototype chain has been created. It should not be hit
|
|
22
|
-
return false;
|
|
23
|
-
}
|
|
24
|
-
proto = Object.getPrototypeOf(proto);
|
|
25
|
-
counter++;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
return Object.getPrototypeOf(obj) === proto;
|
|
11
|
+
export function jsonParseWithSchema<T>(json: string, schema: ZodFor<T>): T {
|
|
12
|
+
return schema.parse(JSON.parse(json));
|
|
29
13
|
}
|
|
30
14
|
|
|
31
15
|
/**
|
|
32
|
-
*
|
|
33
|
-
* @param obj - The object to convert.
|
|
34
|
-
* @returns The converted object with stringified bigints.
|
|
35
|
-
*/
|
|
36
|
-
export const convertBigintsInObj = (obj: any) => {
|
|
37
|
-
return cloneDeepWith(obj, (value: any) => {
|
|
38
|
-
if (typeof value === 'bigint') {
|
|
39
|
-
return { type: 'bigint', data: value.toString() };
|
|
40
|
-
}
|
|
41
|
-
});
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* JSON.stringify helper that handles bigints.
|
|
16
|
+
* JSON.stringify helper that stringifies bigints, buffers, maps, and sets.
|
|
46
17
|
* @param obj - The object to be stringified.
|
|
47
18
|
* @returns The resulting string.
|
|
48
19
|
*/
|
|
49
|
-
export function
|
|
20
|
+
export function jsonStringify(obj: object, prettify?: boolean): string {
|
|
50
21
|
return JSON.stringify(
|
|
51
22
|
obj,
|
|
52
|
-
(
|
|
53
|
-
typeof value === 'bigint'
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
23
|
+
(_key, value) => {
|
|
24
|
+
if (typeof value === 'bigint') {
|
|
25
|
+
return value.toString();
|
|
26
|
+
} else if (typeof value === 'object' && Buffer.isBuffer(value)) {
|
|
27
|
+
return value.toString('base64');
|
|
28
|
+
} else if (typeof value === 'object' && value instanceof Map) {
|
|
29
|
+
return Array.from(value.entries());
|
|
30
|
+
} else if (typeof value === 'object' && value instanceof Set) {
|
|
31
|
+
return Array.from(value.values());
|
|
32
|
+
} else {
|
|
33
|
+
return value;
|
|
34
|
+
}
|
|
35
|
+
},
|
|
59
36
|
prettify ? 2 : 0,
|
|
60
37
|
);
|
|
61
38
|
}
|
|
62
39
|
|
|
63
40
|
/**
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
* @param obj - The encoded object.
|
|
67
|
-
* @returns The decoded object.
|
|
41
|
+
* Calls jsonStringify but swallows errors.
|
|
42
|
+
* Use for logging, when you don't want to potentially introduce another thing that throws.
|
|
68
43
|
*/
|
|
69
|
-
export function
|
|
70
|
-
|
|
71
|
-
return
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
if (!obj) {
|
|
75
|
-
return obj; // Primitive type
|
|
76
|
-
}
|
|
77
|
-
// Is this a serialized Node buffer?
|
|
78
|
-
if (obj.type === 'Buffer' && typeof obj.data === 'string') {
|
|
79
|
-
return Buffer.from(obj.data, 'base64');
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
if (obj.type === 'bigint' && typeof obj.data === 'string') {
|
|
83
|
-
return BigInt(obj.data);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
// Is this a convertible type?
|
|
87
|
-
if (typeof obj.type === 'string') {
|
|
88
|
-
if (cc.isRegisteredClassName(obj.type)) {
|
|
89
|
-
return cc.toClassObj(obj);
|
|
90
|
-
} else {
|
|
91
|
-
throw new Error(`Object ${obj.type} not registered for serialization FROM JSON`);
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// Is this an array?
|
|
96
|
-
if (Array.isArray(obj)) {
|
|
97
|
-
return obj.map((x: any) => convertFromJsonObj(cc, x));
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
// Is this a dictionary?
|
|
101
|
-
if (typeof obj === 'object') {
|
|
102
|
-
const newObj: any = {};
|
|
103
|
-
for (const key of Object.keys(obj)) {
|
|
104
|
-
newObj[key] = convertFromJsonObj(cc, obj[key]);
|
|
105
|
-
}
|
|
106
|
-
return newObj;
|
|
44
|
+
export function tryJsonStringify(obj: any, prettify?: boolean): string | undefined {
|
|
45
|
+
try {
|
|
46
|
+
return jsonStringify(obj, prettify);
|
|
47
|
+
} catch (e) {
|
|
48
|
+
return undefined;
|
|
107
49
|
}
|
|
108
|
-
|
|
109
|
-
// Leave alone, assume JSON primitive
|
|
110
|
-
return obj;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* Convert objects or classes to a JSON-friendly object.
|
|
115
|
-
* @param cc - The class converter.
|
|
116
|
-
* @param obj - The object.
|
|
117
|
-
* @returns The encoded object.
|
|
118
|
-
*/
|
|
119
|
-
export function convertToJsonObj(cc: ClassConverter, obj: any): any {
|
|
120
|
-
// Bigint is a primitive type that needs special handling since it's not serializable
|
|
121
|
-
if (typeof obj === 'bigint') {
|
|
122
|
-
return {
|
|
123
|
-
type: 'bigint',
|
|
124
|
-
data: obj.toString(),
|
|
125
|
-
};
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
if (!obj) {
|
|
129
|
-
return obj; // Primitive type
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
// Is this a Node buffer?
|
|
133
|
-
if (Buffer.isBuffer(obj)) {
|
|
134
|
-
return { type: 'Buffer', data: obj.toString('base64') };
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
// Is this a convertible type?
|
|
138
|
-
if (cc.isRegisteredClass(obj.constructor)) {
|
|
139
|
-
return cc.toJsonObj(obj);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
// Is this an array?
|
|
143
|
-
if (Array.isArray(obj)) {
|
|
144
|
-
return obj.map((x: any) => convertToJsonObj(cc, x));
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
if (typeof obj === 'object') {
|
|
148
|
-
// Is this a dictionary?
|
|
149
|
-
if (isPlainObject(obj)) {
|
|
150
|
-
const newObj: any = {};
|
|
151
|
-
for (const key of Object.keys(obj)) {
|
|
152
|
-
newObj[key] = convertToJsonObj(cc, obj[key]);
|
|
153
|
-
}
|
|
154
|
-
return newObj;
|
|
155
|
-
} else {
|
|
156
|
-
// Throw if this is a non-primitive class that was not registered
|
|
157
|
-
throw new Error(`Object ${obj.constructor.name} not registered for serialization TO JSON`);
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
// Leave alone, assume JSON primitive
|
|
162
|
-
return obj;
|
|
163
50
|
}
|