@aztec/node-keystore 2.1.0-rc.1 → 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.
@@ -45,6 +45,10 @@ export declare class KeystoreManager {
45
45
  * This is used at construction time to check for obvious duplicates without throwing for invalid inputs.
46
46
  */
47
47
  private extractAddressesWithoutSensitiveOperations;
48
+ /**
49
+ * Extract addresses from EthAccounts without sensitive operations (no decryption/derivation).
50
+ */
51
+ private extractAddressesFromEthAccountsNonSensitive;
48
52
  /**
49
53
  * Create signers for validator attester accounts
50
54
  */
@@ -129,5 +133,7 @@ export declare class KeystoreManager {
129
133
  * Precedence: account-level override > validator-level config > file-level default
130
134
  */
131
135
  getEffectiveRemoteSignerConfig(validatorIndex: number, attesterAddress: EthAddress): EthRemoteSignerConfig | undefined;
136
+ /** Extract ETH accounts from AttesterAccounts */
137
+ private extractEthAccountsFromAttester;
132
138
  }
133
139
  //# sourceMappingURL=keystore_manager.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"keystore_manager.d.ts","sourceRoot":"","sources":["../src/keystore_manager.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAKhE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,MAAM,CAAC;AAKhD,OAAO,KAAK,EAEV,WAAW,EAIX,qBAAqB,EACrB,QAAQ,EACR,cAAc,EACd,iBAAiB,IAAI,uBAAuB,EAC7C,MAAM,YAAY,CAAC;AAEpB;;GAEG;AACH,qBAAa,aAAc,SAAQ,KAAK;IAGpB,KAAK,CAAC,EAAE,KAAK;gBAD7B,OAAO,EAAE,MAAM,EACC,KAAK,CAAC,EAAE,KAAK,YAAA;CAKhC;AAED;;GAEG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAW;IAEpC;;;;OAIG;gBACS,QAAQ,EAAE,QAAQ;IAK9B;;;OAGG;IACG,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IAwEtC;;;;;OAKG;IACH,OAAO,CAAC,+BAA+B;IAkBvC;;;OAGG;IACH,OAAO,CAAC,0CAA0C;IAoDlD;;OAEG;IACH,qBAAqB,CAAC,cAAc,EAAE,MAAM,GAAG,SAAS,EAAE;IAK1D;;OAEG;IACH,sBAAsB,CAAC,cAAc,EAAE,MAAM,GAAG,SAAS,EAAE;IAc3D,kCAAkC,IAAI,SAAS,EAAE;IAWjD;;OAEG;IACH,oBAAoB,IAAI,SAAS,EAAE;IAQnC;;OAEG;IACH,mBAAmB,IAAI;QAAE,EAAE,EAAE,UAAU,GAAG,SAAS,CAAC;QAAC,OAAO,EAAE,SAAS,EAAE,CAAA;KAAE,GAAG,SAAS;IAkCvF;;OAEG;IACH,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,uBAAuB;IAOpD;;OAEG;IACH,iBAAiB,IAAI,MAAM;IAI3B;;OAEG;IACH,kBAAkB,CAAC,cAAc,EAAE,MAAM,GAAG,UAAU;IAgBtD;;OAEG;IACH,eAAe,CAAC,cAAc,EAAE,MAAM,GAAG,YAAY;IAKrD;;;OAGG;IACH,kBAAkB,IAAI,WAAW,GAAG,SAAS;IAI7C;;;OAGG;IACH,eAAe,IAAI,cAAc,GAAG,SAAS;IAI7C;;;OAGG;IACH,uCAAuC,IAAI,IAAI;IAqB/C;;OAEG;IACH,OAAO,CAAC,4BAA4B;IA+BpC;;OAEG;IACH,OAAO,CAAC,0BAA0B;IA2ClC;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAkD9B;;OAEG;IACH,OAAO,CAAC,gCAAgC;IAwBxC;;OAEG;IACH,OAAO,CAAC,yBAAyB;IA8BjC;;OAEG;IACG,WAAW,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,SAAS,CAAC;IAI3E;;OAEG;IACG,aAAa,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,mBAAmB,GAAG,OAAO,CAAC,SAAS,CAAC;IAI1F;;;OAGG;IACH,8BAA8B,CAC5B,cAAc,EAAE,MAAM,EACtB,eAAe,EAAE,UAAU,GAC1B,qBAAqB,GAAG,SAAS;CAkHrC"}
1
+ {"version":3,"file":"keystore_manager.d.ts","sourceRoot":"","sources":["../src/keystore_manager.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAKhE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,MAAM,CAAC;AAKhD,OAAO,KAAK,EAGV,WAAW,EAEX,qBAAqB,EAErB,QAAQ,EAER,cAAc,EACd,iBAAiB,IAAI,uBAAuB,EAC7C,MAAM,YAAY,CAAC;AAEpB;;GAEG;AACH,qBAAa,aAAc,SAAQ,KAAK;IAGpB,KAAK,CAAC,EAAE,KAAK;gBAD7B,OAAO,EAAE,MAAM,EACC,KAAK,CAAC,EAAE,KAAK,YAAA;CAKhC;AAED;;GAEG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAW;IAEpC;;;;OAIG;gBACS,QAAQ,EAAE,QAAQ;IAK9B;;;OAGG;IACG,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IAwEtC;;;;;OAKG;IACH,OAAO,CAAC,+BAA+B;IAkBvC;;;OAGG;IACH,OAAO,CAAC,0CAA0C;IAKlD;;OAEG;IACH,OAAO,CAAC,2CAA2C;IA+CnD;;OAEG;IACH,qBAAqB,CAAC,cAAc,EAAE,MAAM,GAAG,SAAS,EAAE;IAM1D;;OAEG;IACH,sBAAsB,CAAC,cAAc,EAAE,MAAM,GAAG,SAAS,EAAE;IAc3D,kCAAkC,IAAI,SAAS,EAAE;IAWjD;;OAEG;IACH,oBAAoB,IAAI,SAAS,EAAE;IAQnC;;OAEG;IACH,mBAAmB,IAAI;QAAE,EAAE,EAAE,UAAU,GAAG,SAAS,CAAC;QAAC,OAAO,EAAE,SAAS,EAAE,CAAA;KAAE,GAAG,SAAS;IAiCvF;;OAEG;IACH,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,uBAAuB;IAOpD;;OAEG;IACH,iBAAiB,IAAI,MAAM;IAI3B;;OAEG;IACH,kBAAkB,CAAC,cAAc,EAAE,MAAM,GAAG,UAAU;IAgBtD;;OAEG;IACH,eAAe,CAAC,cAAc,EAAE,MAAM,GAAG,YAAY;IAKrD;;;OAGG;IACH,kBAAkB,IAAI,WAAW,GAAG,SAAS;IAI7C;;;OAGG;IACH,eAAe,IAAI,cAAc,GAAG,SAAS;IAI7C;;;OAGG;IACH,uCAAuC,IAAI,IAAI;IAqB/C;;OAEG;IACH,OAAO,CAAC,4BAA4B;IA+BpC;;OAEG;IACH,OAAO,CAAC,0BAA0B;IA2ClC;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAkD9B;;OAEG;IACH,OAAO,CAAC,gCAAgC;IAwBxC;;OAEG;IACH,OAAO,CAAC,yBAAyB;IA8BjC;;OAEG;IACG,WAAW,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,SAAS,CAAC;IAI3E;;OAEG;IACG,aAAa,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,mBAAmB,GAAG,OAAO,CAAC,SAAS,CAAC;IAI1F;;;OAGG;IACH,8BAA8B,CAC5B,cAAc,EAAE,MAAM,EACtB,eAAe,EAAE,UAAU,GAC1B,qBAAqB,GAAG,SAAS;IA0GpC,iDAAiD;IACjD,OAAO,CAAC,8BAA8B;CAyBvC"}
@@ -74,7 +74,7 @@ import { LocalSigner, RemoteSigner } from './signer.js';
74
74
  for(let i = 0; i < validatorCount; i++){
75
75
  const validator = this.getValidator(i);
76
76
  const remoteSigner = validator.remoteSigner || this.keystore.remoteSigner;
77
- collectRemoteSigners(validator.attester, remoteSigner);
77
+ collectRemoteSigners(this.extractEthAccountsFromAttester(validator.attester), remoteSigner);
78
78
  if (validator.publisher) {
79
79
  collectRemoteSigners(validator.publisher, remoteSigner);
80
80
  }
@@ -118,32 +118,31 @@ import { LocalSigner, RemoteSigner } from './signer.js';
118
118
  * Best-effort address extraction that avoids decryption/derivation (no JSON-V3 or mnemonic processing).
119
119
  * This is used at construction time to check for obvious duplicates without throwing for invalid inputs.
120
120
  */ extractAddressesWithoutSensitiveOperations(accounts) {
121
+ const ethAccounts = this.extractEthAccountsFromAttester(accounts);
122
+ return this.extractAddressesFromEthAccountsNonSensitive(ethAccounts);
123
+ }
124
+ /**
125
+ * Extract addresses from EthAccounts without sensitive operations (no decryption/derivation).
126
+ */ extractAddressesFromEthAccountsNonSensitive(accounts) {
121
127
  const results = [];
122
128
  const handleAccount = (account)=>{
123
- // String cases: private key or address or remote signer address
124
129
  if (typeof account === 'string') {
125
130
  if (account.startsWith('0x') && account.length === 66) {
126
- // Private key -> derive address locally without external deps
127
131
  try {
128
132
  const signer = new LocalSigner(Buffer32.fromString(ethPrivateKeySchema.parse(account)));
129
133
  results.push(signer.address);
130
134
  } catch {
131
- // Ignore invalid private key at construction time
135
+ // ignore invalid private key at construction time
132
136
  }
133
- return;
134
137
  }
135
- // Any other string cannot be confidently resolved here
136
138
  return;
137
139
  }
138
- // JSON V3 keystore: skip (requires decryption)
139
140
  if ('path' in account) {
140
141
  return;
141
142
  }
142
- // Mnemonic: skip (requires derivation and may throw on invalid mnemonics)
143
143
  if ('mnemonic' in account) {
144
144
  return;
145
145
  }
146
- // Remote signer account. If it contains 'address' then extract, otherwise it IS the address
147
146
  const remoteSigner = account;
148
147
  if ('address' in remoteSigner) {
149
148
  results.push(remoteSigner.address);
@@ -153,11 +152,13 @@ import { LocalSigner, RemoteSigner } from './signer.js';
153
152
  };
154
153
  if (Array.isArray(accounts)) {
155
154
  for (const account of accounts){
156
- const subResults = this.extractAddressesWithoutSensitiveOperations(account);
157
- results.push(...subResults);
155
+ handleAccount(account);
158
156
  }
159
157
  return results;
160
158
  }
159
+ if (typeof accounts === 'object' && accounts !== null && 'mnemonic' in accounts) {
160
+ return results;
161
+ }
161
162
  handleAccount(accounts);
162
163
  return results;
163
164
  }
@@ -165,7 +166,8 @@ import { LocalSigner, RemoteSigner } from './signer.js';
165
166
  * Create signers for validator attester accounts
166
167
  */ createAttesterSigners(validatorIndex) {
167
168
  const validator = this.getValidator(validatorIndex);
168
- return this.createSignersFromEthAccounts(validator.attester, validator.remoteSigner || this.keystore.remoteSigner);
169
+ const ethAccounts = this.extractEthAccountsFromAttester(validator.attester);
170
+ return this.createSignersFromEthAccounts(ethAccounts, validator.remoteSigner || this.keystore.remoteSigner);
169
171
  }
170
172
  /**
171
173
  * Create signers for validator publisher accounts (falls back to attester if not specified)
@@ -276,7 +278,7 @@ import { LocalSigner, RemoteSigner } from './signer.js';
276
278
  const validatorCount = this.getValidatorCount();
277
279
  for(let validatorIndex = 0; validatorIndex < validatorCount; validatorIndex++){
278
280
  const validator = this.getValidator(validatorIndex);
279
- const signers = this.createSignersFromEthAccounts(validator.attester, validator.remoteSigner || this.keystore.remoteSigner);
281
+ const signers = this.createSignersFromEthAccounts(this.extractEthAccountsFromAttester(validator.attester), validator.remoteSigner || this.keystore.remoteSigner);
280
282
  for (const signer of signers){
281
283
  const address = signer.address.toString().toLowerCase();
282
284
  if (seenAddresses.has(address)) {
@@ -530,34 +532,52 @@ import { LocalSigner, RemoteSigner } from './signer.js';
530
532
  // Just an address, use defaults
531
533
  return validator.remoteSigner || this.keystore.remoteSigner;
532
534
  };
533
- // Check the attester configuration
534
- const { attester } = validator;
535
+ // Normalize attester to EthAccounts and search
536
+ const normalized = this.extractEthAccountsFromAttester(validator.attester);
537
+ const findInEthAccounts = (accs)=>{
538
+ if (typeof accs === 'string') {
539
+ return checkAccount(accs);
540
+ }
541
+ if (Array.isArray(accs)) {
542
+ for (const a of accs){
543
+ const res = checkAccount(a);
544
+ if (res !== undefined) {
545
+ return res;
546
+ }
547
+ }
548
+ return undefined;
549
+ }
550
+ if (typeof accs === 'object' && accs !== null && 'mnemonic' in accs) {
551
+ // mnemonic-derived keys are local signers; no remote signer config
552
+ return undefined;
553
+ }
554
+ return checkAccount(accs);
555
+ };
556
+ return findInEthAccounts(normalized);
557
+ }
558
+ /** Extract ETH accounts from AttesterAccounts */ extractEthAccountsFromAttester(attester) {
535
559
  if (typeof attester === 'string') {
536
- const result = checkAccount(attester);
537
- return result === undefined ? undefined : result;
560
+ return attester;
538
561
  }
539
562
  if (Array.isArray(attester)) {
540
- for (const account of attester){
541
- const result = checkAccount(account);
542
- if (result !== undefined) {
543
- return result;
563
+ const out = [];
564
+ for (const item of attester){
565
+ if (typeof item === 'string') {
566
+ out.push(item);
567
+ } else if ('eth' in item) {
568
+ out.push(item.eth);
569
+ } else if (!('mnemonic' in item)) {
570
+ out.push(item);
544
571
  }
545
572
  }
546
- return undefined;
573
+ return out;
547
574
  }
548
- // Mnemonic configuration
549
575
  if ('mnemonic' in attester) {
550
- try {
551
- const signers = this.createSignersFromMnemonic(attester);
552
- const matches = signers.some((s)=>s.address.equals(attesterAddress));
553
- // Mnemonic-derived keys are local signers
554
- return matches ? undefined : undefined;
555
- } catch {
556
- return undefined;
557
- }
576
+ return attester;
577
+ }
578
+ if ('eth' in attester) {
579
+ return attester.eth;
558
580
  }
559
- // Single account object
560
- const result = checkAccount(attester);
561
- return result === undefined ? undefined : result;
581
+ return attester;
562
582
  }
563
583
  }
package/dest/loader.js CHANGED
@@ -236,19 +236,38 @@ const logger = createLogger('node-keystore:loader');
236
236
  * @param attester The attester configuration in any supported shape.
237
237
  * @returns Array of string keys used to detect duplicates.
238
238
  */ function extractAttesterKeys(attester) {
239
+ // String forms (private key or other) - return as-is for coarse uniqueness
239
240
  if (typeof attester === 'string') {
240
241
  return [
241
242
  attester
242
243
  ];
243
244
  }
245
+ // Arrays of attester items
244
246
  if (Array.isArray(attester)) {
245
- return attester.map((a)=>typeof a === 'string' ? a : JSON.stringify(a));
247
+ const keys = [];
248
+ for (const item of attester){
249
+ keys.push(...extractAttesterKeys(item));
250
+ }
251
+ return keys;
246
252
  }
247
- if (attester && typeof attester === 'object' && 'address' in attester) {
253
+ if (attester && typeof attester === 'object') {
254
+ const obj = attester;
255
+ // New shape: { eth: EthAccount, bls?: BLSAccount }
256
+ if ('eth' in obj) {
257
+ return extractAttesterKeys(obj.eth);
258
+ }
259
+ // Remote signer account object shape: { address, remoteSignerUrl?, ... }
260
+ if ('address' in obj) {
261
+ return [
262
+ String(obj.address)
263
+ ];
264
+ }
265
+ // Mnemonic or other object shapes: stringify
248
266
  return [
249
- attester.address
267
+ JSON.stringify(attester)
250
268
  ];
251
269
  }
270
+ // Fallback stringify for anything else (null/undefined)
252
271
  return [
253
272
  JSON.stringify(attester)
254
273
  ];