@aztec/node-keystore 2.0.3 → 2.1.0-rc.2

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/src/signer.ts CHANGED
@@ -104,6 +104,82 @@ export class RemoteSigner implements EthSigner {
104
104
  private fetch: typeof globalThis.fetch = globalThis.fetch,
105
105
  ) {}
106
106
 
107
+ /**
108
+ * Validates that a web3signer is accessible and that the given addresses are available.
109
+ * @param remoteSignerUrl - The URL of the web3signer (can be string or EthRemoteSignerConfig)
110
+ * @param addresses - The addresses to check for availability
111
+ * @param fetch - Optional fetch implementation for testing
112
+ * @throws Error if the web3signer is not accessible or if any address is not available
113
+ */
114
+ static async validateAccess(
115
+ remoteSignerUrl: EthRemoteSignerConfig,
116
+ addresses: string[],
117
+ fetch: typeof globalThis.fetch = globalThis.fetch,
118
+ ): Promise<void> {
119
+ const url = typeof remoteSignerUrl === 'string' ? remoteSignerUrl : remoteSignerUrl.remoteSignerUrl;
120
+
121
+ try {
122
+ // Check if the web3signer is reachable by calling eth_accounts
123
+ const response = await fetch(url, {
124
+ method: 'POST',
125
+ headers: {
126
+ 'Content-Type': 'application/json',
127
+ },
128
+ body: JSON.stringify({
129
+ jsonrpc: '2.0',
130
+ method: 'eth_accounts',
131
+ params: [],
132
+ id: 1,
133
+ }),
134
+ });
135
+
136
+ if (!response.ok) {
137
+ const errorText = await response.text();
138
+ throw new SignerError(
139
+ `Web3Signer validation failed: ${response.status} ${response.statusText} - ${errorText}`,
140
+ 'eth_accounts',
141
+ url,
142
+ response.status,
143
+ );
144
+ }
145
+
146
+ const result = await response.json();
147
+
148
+ if (result.error) {
149
+ throw new SignerError(
150
+ `Web3Signer JSON-RPC error during validation: ${result.error.code} - ${result.error.message}`,
151
+ 'eth_accounts',
152
+ url,
153
+ 200,
154
+ result.error.code,
155
+ );
156
+ }
157
+
158
+ if (!result.result || !Array.isArray(result.result)) {
159
+ throw new Error('Invalid response from Web3Signer: expected array of accounts');
160
+ }
161
+
162
+ // Normalize addresses to lowercase for comparison
163
+ const availableAccounts: string[] = result.result.map((addr: string) => addr.toLowerCase());
164
+ const requestedAddresses = addresses.map(addr => addr.toLowerCase());
165
+
166
+ // Check if all requested addresses are available
167
+ const missingAddresses = requestedAddresses.filter(addr => !availableAccounts.includes(addr));
168
+
169
+ if (missingAddresses.length > 0) {
170
+ throw new Error(`The following addresses are not available in the web3signer: ${missingAddresses.join(', ')}`);
171
+ }
172
+ } catch (error: any) {
173
+ if (error instanceof SignerError) {
174
+ throw error;
175
+ }
176
+ if (error.code === 'ECONNREFUSED' || error.cause?.code === 'ECONNREFUSED') {
177
+ throw new Error(`Unable to connect to web3signer at ${url}. Please ensure it is running and accessible.`);
178
+ }
179
+ throw error;
180
+ }
181
+ }
182
+
107
183
  /**
108
184
  * Sign a message using eth_sign via remote JSON-RPC.
109
185
  */
package/src/types.ts CHANGED
@@ -12,11 +12,14 @@ import type { AztecAddress } from '@aztec/stdlib/aztec-address';
12
12
  export type Hex<TByteLength extends number> = `0x${string}` & { readonly _length: TByteLength };
13
13
 
14
14
  /** A json keystore config points to a local file with the encrypted private key, and may require a password for decrypting it */
15
- export type EthJsonKeyFileV3Config = { path: string; password?: string };
15
+ export type JsonKeyFileV3Config = { path: string; password?: string };
16
16
 
17
17
  /** A private key is a 32-byte 0x-prefixed hex */
18
18
  export type EthPrivateKey = Hex<32>;
19
19
 
20
+ /** A BLS private key is a 32-byte 0x-prefixed hex */
21
+ export type BLSPrivateKey = Hex<32>;
22
+
20
23
  /** URL type for remote signers */
21
24
  export type Url = string;
22
25
 
@@ -39,16 +42,16 @@ export type EthRemoteSignerAccount =
39
42
  | EthAddress
40
43
  | {
41
44
  address: EthAddress;
42
- remoteSignerUrl?: Url;
45
+ remoteSignerUrl: Url;
43
46
  certPath?: string;
44
47
  certPass?: string;
45
48
  };
46
49
 
47
50
  /** An L1 account is a private key, a remote signer configuration, or a standard json key store file */
48
- export type EthAccount = EthPrivateKey | EthRemoteSignerAccount | EthJsonKeyFileV3Config;
51
+ export type EthAccount = EthPrivateKey | EthRemoteSignerAccount | JsonKeyFileV3Config;
49
52
 
50
53
  /** A mnemonic can be used to define a set of accounts */
51
- export type EthMnemonicConfig = {
54
+ export type MnemonicConfig = {
52
55
  mnemonic: string;
53
56
  addressIndex?: number;
54
57
  accountIndex?: number;
@@ -57,7 +60,7 @@ export type EthMnemonicConfig = {
57
60
  };
58
61
 
59
62
  /** One or more L1 accounts */
60
- export type EthAccounts = EthAccount | EthAccount[] | EthMnemonicConfig;
63
+ export type EthAccounts = EthAccount | EthAccount[] | MnemonicConfig;
61
64
 
62
65
  export type ProverKeyStoreWithId = {
63
66
  /** Address that identifies the prover. This address will receive the rewards. */
@@ -68,12 +71,21 @@ export type ProverKeyStoreWithId = {
68
71
 
69
72
  export type ProverKeyStore = ProverKeyStoreWithId | EthAccount;
70
73
 
74
+ /** A BLS account is either a private key, or a standard json key store file */
75
+ export type BLSAccount = BLSPrivateKey | JsonKeyFileV3Config;
76
+
77
+ /** An AttesterAccount is a combined EthAccount and optional BLSAccount */
78
+ export type AttesterAccount = { eth: EthAccount; bls?: BLSAccount } | EthAccount;
79
+
80
+ /** One or more attester accounts combining ETH and BLS keys */
81
+ export type AttesterAccounts = AttesterAccount | AttesterAccount[] | MnemonicConfig;
82
+
71
83
  export type ValidatorKeyStore = {
72
84
  /**
73
85
  * One or more validator attester keys to handle in this configuration block.
74
86
  * An attester address may only appear once across all configuration blocks across all keystore files.
75
87
  */
76
- attester: EthAccounts;
88
+ attester: AttesterAccounts;
77
89
  /**
78
90
  * Coinbase address to use when proposing an L2 block as any of the validators in this configuration block.
79
91
  * Falls back to the attester address if not set.