@aztec/key-store 0.0.1-commit.e558bd1c → 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.
@@ -30,6 +30,8 @@ export declare class KeyStore {
30
30
  * @returns A Promise that resolves to an array of account addresses.
31
31
  */
32
32
  getAccounts(): Promise<AztecAddress[]>;
33
+ /** Checks whether an account is registered in the key store. */
34
+ hasAccount(account: AztecAddress): Promise<boolean>;
33
35
  /**
34
36
  * Gets the key validation request for a given master public key hash and contract address.
35
37
  * @throws If the account corresponding to the master public key hash does not exist in the key store.
@@ -89,6 +91,13 @@ export declare class KeyStore {
89
91
  * @dev Used when feeding the sk_m to the kernel circuit for keys verification.
90
92
  */
91
93
  getMasterSecretKey(pkM: PublicKey): Promise<GrumpkinScalar>;
94
+ /**
95
+ * Checks whether a given account has a key matching the provided master public key hash.
96
+ * @param account - The account address to check.
97
+ * @param pkMHash - The master public key hash to look for.
98
+ * @returns True if the account has a key with the given hash.
99
+ */
100
+ accountHasKey(account: AztecAddress, pkMHash: Fr): Promise<boolean>;
92
101
  /**
93
102
  * Gets the key prefix and account address for a given value.
94
103
  * @returns A tuple containing the key prefix and account address.
@@ -97,4 +106,4 @@ export declare class KeyStore {
97
106
  */
98
107
  getKeyPrefixAndAccount(value: Bufferable): Promise<[KeyPrefix, AztecAddress]>;
99
108
  }
100
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoia2V5X3N0b3JlLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMva2V5X3N0b3JlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBLE9BQU8sRUFBRSxFQUFFLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNwRCxPQUFPLEVBQUUsY0FBYyxFQUFTLE1BQU0sbUNBQW1DLENBQUM7QUFFMUUsT0FBTyxFQUFFLEtBQUssVUFBVSxFQUFxQixNQUFNLDZCQUE2QixDQUFDO0FBQ2pGLE9BQU8sS0FBSyxFQUFFLGlCQUFpQixFQUFpQixNQUFNLGlCQUFpQixDQUFDO0FBQ3hFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsZUFBZSxFQUFFLEtBQUssY0FBYyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDOUUsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDNUQsT0FBTyxFQUVMLEtBQUssU0FBUyxFQUNkLEtBQUssU0FBUyxFQUlmLE1BQU0sb0JBQW9CLENBQUM7QUFPNUI7O0dBRUc7QUFDSCxxQkFBYSxRQUFROztJQUNuQixnQkFBdUIsY0FBYyxLQUFLO0lBSTFDLFlBQVksUUFBUSxFQUFFLGlCQUFpQixFQUd0QztJQUVEOzs7T0FHRztJQUNJLGFBQWEsSUFBSSxPQUFPLENBQUMsZUFBZSxDQUFDLENBSS9DO0lBRUQ7Ozs7O09BS0c7SUFDVSxVQUFVLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxjQUFjLEVBQUUsY0FBYyxHQUFHLE9BQU8sQ0FBQyxlQUFlLENBQUMsQ0F3Q3hGO0lBRUQ7OztPQUdHO0lBQ1UsV0FBVyxJQUFJLE9BQU8sQ0FBQyxZQUFZLEVBQUUsQ0FBQyxDQUtsRDtJQUVEOzs7Ozs7T0FNRztJQUNVLHVCQUF1QixDQUFDLE9BQU8sRUFBRSxFQUFFLEVBQUUsZUFBZSxFQUFFLFlBQVksR0FBRyxPQUFPLENBQUMsb0JBQW9CLENBQUMsQ0FzQzlHO0lBRUQ7Ozs7O09BS0c7SUFDVSwyQkFBMkIsQ0FBQyxPQUFPLEVBQUUsWUFBWSxHQUFHLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FRbEY7SUFFRDs7Ozs7T0FLRztJQUNVLGlDQUFpQyxDQUFDLE9BQU8sRUFBRSxZQUFZLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQVF4RjtJQUVEOzs7OztPQUtHO0lBQ1UsaUNBQWlDLENBQUMsT0FBTyxFQUFFLFlBQVksR0FBRyxPQUFPLENBQUMsU0FBUyxDQUFDLENBUXhGO0lBRUQ7Ozs7O09BS0c7SUFDVSx5QkFBeUIsQ0FBQyxPQUFPLEVBQUUsWUFBWSxHQUFHLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FRaEY7SUFFRDs7Ozs7T0FLRztJQUNVLGlDQUFpQyxDQUFDLE9BQU8sRUFBRSxZQUFZLEdBQUcsT0FBTyxDQUFDLGNBQWMsQ0FBQyxDQVE3RjtJQUVEOzs7Ozs7T0FNRztJQUNVLDhCQUE4QixDQUFDLE9BQU8sRUFBRSxZQUFZLEVBQUUsR0FBRyxFQUFFLFlBQVksR0FBRyxPQUFPLENBQUMsRUFBRSxDQUFDLENBYWpHO0lBRUQ7Ozs7OztPQU1HO0lBQ1Usa0JBQWtCLENBQUMsR0FBRyxFQUFFLFNBQVMsR0FBRyxPQUFPLENBQUMsY0FBYyxDQUFDLENBa0J2RTtJQUVEOzs7OztPQUtHO0lBQ1Usc0JBQXNCLENBQUMsS0FBSyxFQUFFLFVBQVUsR0FBRyxPQUFPLENBQUMsQ0FBQyxTQUFTLEVBQUUsWUFBWSxDQUFDLENBQUMsQ0FjekY7Q0FDRiJ9
109
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoia2V5X3N0b3JlLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMva2V5X3N0b3JlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBLE9BQU8sRUFBRSxFQUFFLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNwRCxPQUFPLEVBQUUsY0FBYyxFQUFTLE1BQU0sbUNBQW1DLENBQUM7QUFFMUUsT0FBTyxFQUFFLEtBQUssVUFBVSxFQUFxQixNQUFNLDZCQUE2QixDQUFDO0FBQ2pGLE9BQU8sS0FBSyxFQUFFLGlCQUFpQixFQUFpQixNQUFNLGlCQUFpQixDQUFDO0FBQ3hFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsZUFBZSxFQUFFLEtBQUssY0FBYyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDOUUsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDNUQsT0FBTyxFQUVMLEtBQUssU0FBUyxFQUNkLEtBQUssU0FBUyxFQUlmLE1BQU0sb0JBQW9CLENBQUM7QUFPNUI7O0dBRUc7QUFDSCxxQkFBYSxRQUFROztJQUNuQixnQkFBdUIsY0FBYyxLQUFLO0lBSTFDLFlBQVksUUFBUSxFQUFFLGlCQUFpQixFQUd0QztJQUVEOzs7T0FHRztJQUNJLGFBQWEsSUFBSSxPQUFPLENBQUMsZUFBZSxDQUFDLENBSS9DO0lBRUQ7Ozs7O09BS0c7SUFDVSxVQUFVLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxjQUFjLEVBQUUsY0FBYyxHQUFHLE9BQU8sQ0FBQyxlQUFlLENBQUMsQ0F3Q3hGO0lBRUQ7OztPQUdHO0lBQ1UsV0FBVyxJQUFJLE9BQU8sQ0FBQyxZQUFZLEVBQUUsQ0FBQyxDQUtsRDtJQUVELGdFQUFnRTtJQUNuRCxVQUFVLENBQUMsT0FBTyxFQUFFLFlBQVksR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLENBRS9EO0lBRUQ7Ozs7OztPQU1HO0lBQ0ksdUJBQXVCLENBQUMsT0FBTyxFQUFFLEVBQUUsRUFBRSxlQUFlLEVBQUUsWUFBWSxHQUFHLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQyxDQXdDeEc7SUFFRDs7Ozs7T0FLRztJQUNVLDJCQUEyQixDQUFDLE9BQU8sRUFBRSxZQUFZLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQVFsRjtJQUVEOzs7OztPQUtHO0lBQ1UsaUNBQWlDLENBQUMsT0FBTyxFQUFFLFlBQVksR0FBRyxPQUFPLENBQUMsU0FBUyxDQUFDLENBUXhGO0lBRUQ7Ozs7O09BS0c7SUFDVSxpQ0FBaUMsQ0FBQyxPQUFPLEVBQUUsWUFBWSxHQUFHLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FReEY7SUFFRDs7Ozs7T0FLRztJQUNVLHlCQUF5QixDQUFDLE9BQU8sRUFBRSxZQUFZLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQVFoRjtJQUVEOzs7OztPQUtHO0lBQ1UsaUNBQWlDLENBQUMsT0FBTyxFQUFFLFlBQVksR0FBRyxPQUFPLENBQUMsY0FBYyxDQUFDLENBUTdGO0lBRUQ7Ozs7OztPQU1HO0lBQ1UsOEJBQThCLENBQUMsT0FBTyxFQUFFLFlBQVksRUFBRSxHQUFHLEVBQUUsWUFBWSxHQUFHLE9BQU8sQ0FBQyxFQUFFLENBQUMsQ0Fhakc7SUFFRDs7Ozs7O09BTUc7SUFDSSxrQkFBa0IsQ0FBQyxHQUFHLEVBQUUsU0FBUyxHQUFHLE9BQU8sQ0FBQyxjQUFjLENBQUMsQ0F3QmpFO0lBRUQ7Ozs7O09BS0c7SUFDSSxhQUFhLENBQUMsT0FBTyxFQUFFLFlBQVksRUFBRSxPQUFPLEVBQUUsRUFBRSxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FXekU7SUFFRDs7Ozs7T0FLRztJQUNVLHNCQUFzQixDQUFDLEtBQUssRUFBRSxVQUFVLEdBQUcsT0FBTyxDQUFDLENBQUMsU0FBUyxFQUFFLFlBQVksQ0FBQyxDQUFDLENBY3pGO0NBQ0YifQ==
@@ -1 +1 @@
1
- {"version":3,"file":"key_store.d.ts","sourceRoot":"","sources":["../src/key_store.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,EAAE,EAAE,MAAM,gCAAgC,CAAC;AACpD,OAAO,EAAE,cAAc,EAAS,MAAM,mCAAmC,CAAC;AAE1E,OAAO,EAAE,KAAK,UAAU,EAAqB,MAAM,6BAA6B,CAAC;AACjF,OAAO,KAAK,EAAE,iBAAiB,EAAiB,MAAM,iBAAiB,CAAC;AACxE,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC9E,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAEL,KAAK,SAAS,EACd,KAAK,SAAS,EAIf,MAAM,oBAAoB,CAAC;AAO5B;;GAEG;AACH,qBAAa,QAAQ;;IACnB,gBAAuB,cAAc,KAAK;IAI1C,YAAY,QAAQ,EAAE,iBAAiB,EAGtC;IAED;;;OAGG;IACI,aAAa,IAAI,OAAO,CAAC,eAAe,CAAC,CAI/C;IAED;;;;;OAKG;IACU,UAAU,CAAC,EAAE,EAAE,EAAE,EAAE,cAAc,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC,CAwCxF;IAED;;;OAGG;IACU,WAAW,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC,CAKlD;IAED;;;;;;OAMG;IACU,uBAAuB,CAAC,OAAO,EAAE,EAAE,EAAE,eAAe,EAAE,YAAY,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAsC9G;IAED;;;;;OAKG;IACU,2BAA2B,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,SAAS,CAAC,CAQlF;IAED;;;;;OAKG;IACU,iCAAiC,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,SAAS,CAAC,CAQxF;IAED;;;;;OAKG;IACU,iCAAiC,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,SAAS,CAAC,CAQxF;IAED;;;;;OAKG;IACU,yBAAyB,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,SAAS,CAAC,CAQhF;IAED;;;;;OAKG;IACU,iCAAiC,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,cAAc,CAAC,CAQ7F;IAED;;;;;;OAMG;IACU,8BAA8B,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,EAAE,CAAC,CAajG;IAED;;;;;;OAMG;IACU,kBAAkB,CAAC,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC,cAAc,CAAC,CAkBvE;IAED;;;;;OAKG;IACU,sBAAsB,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC,CAczF;CACF"}
1
+ {"version":3,"file":"key_store.d.ts","sourceRoot":"","sources":["../src/key_store.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,EAAE,EAAE,MAAM,gCAAgC,CAAC;AACpD,OAAO,EAAE,cAAc,EAAS,MAAM,mCAAmC,CAAC;AAE1E,OAAO,EAAE,KAAK,UAAU,EAAqB,MAAM,6BAA6B,CAAC;AACjF,OAAO,KAAK,EAAE,iBAAiB,EAAiB,MAAM,iBAAiB,CAAC;AACxE,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC9E,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAEL,KAAK,SAAS,EACd,KAAK,SAAS,EAIf,MAAM,oBAAoB,CAAC;AAO5B;;GAEG;AACH,qBAAa,QAAQ;;IACnB,gBAAuB,cAAc,KAAK;IAI1C,YAAY,QAAQ,EAAE,iBAAiB,EAGtC;IAED;;;OAGG;IACI,aAAa,IAAI,OAAO,CAAC,eAAe,CAAC,CAI/C;IAED;;;;;OAKG;IACU,UAAU,CAAC,EAAE,EAAE,EAAE,EAAE,cAAc,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC,CAwCxF;IAED;;;OAGG;IACU,WAAW,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC,CAKlD;IAED,gEAAgE;IACnD,UAAU,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,CAE/D;IAED;;;;;;OAMG;IACI,uBAAuB,CAAC,OAAO,EAAE,EAAE,EAAE,eAAe,EAAE,YAAY,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAwCxG;IAED;;;;;OAKG;IACU,2BAA2B,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,SAAS,CAAC,CAQlF;IAED;;;;;OAKG;IACU,iCAAiC,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,SAAS,CAAC,CAQxF;IAED;;;;;OAKG;IACU,iCAAiC,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,SAAS,CAAC,CAQxF;IAED;;;;;OAKG;IACU,yBAAyB,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,SAAS,CAAC,CAQhF;IAED;;;;;OAKG;IACU,iCAAiC,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,cAAc,CAAC,CAQ7F;IAED;;;;;;OAMG;IACU,8BAA8B,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,EAAE,CAAC,CAajG;IAED;;;;;;OAMG;IACI,kBAAkB,CAAC,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC,cAAc,CAAC,CAwBjE;IAED;;;;;OAKG;IACI,aAAa,CAAC,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAWzE;IAED;;;;;OAKG;IACU,sBAAsB,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC,CAczF;CACF"}
package/dest/key_store.js CHANGED
@@ -1,4 +1,4 @@
1
- import { GeneratorIndex } from '@aztec/constants';
1
+ import { DomainSeparator } from '@aztec/constants';
2
2
  import { poseidon2HashWithSeparator } from '@aztec/foundation/crypto/poseidon';
3
3
  import { Fr } from '@aztec/foundation/curves/bn254';
4
4
  import { GrumpkinScalar, Point } from '@aztec/foundation/curves/grumpkin';
@@ -72,39 +72,43 @@ import { KEY_PREFIXES, computeAppSecretKey, deriveKeys, derivePublicKeyFromSecre
72
72
  const accounts = allMapKeys.filter((key)=>key.endsWith('-ivsk_m')).map((key)=>key.split('-')[0]);
73
73
  return accounts.map((account)=>AztecAddress.fromString(account));
74
74
  }
75
+ /** Checks whether an account is registered in the key store. */ async hasAccount(account) {
76
+ return !!await this.#keys.getAsync(`${account.toString()}-ivsk_m`);
77
+ }
75
78
  /**
76
79
  * Gets the key validation request for a given master public key hash and contract address.
77
80
  * @throws If the account corresponding to the master public key hash does not exist in the key store.
78
81
  * @param pkMHash - The master public key hash.
79
82
  * @param contractAddress - The contract address to silo the secret key in the key validation request with.
80
83
  * @returns The key validation request.
81
- */ async getKeyValidationRequest(pkMHash, contractAddress) {
82
- const [keyPrefix, account] = await this.getKeyPrefixAndAccount(pkMHash);
83
- // Now we find the master public key for the account
84
- const pkMBuffer = await this.#keys.getAsync(`${account.toString()}-${keyPrefix}pk_m`);
85
- if (!pkMBuffer) {
86
- throw new Error(`Could not find ${keyPrefix}pk_m for account ${account.toString()} whose address was successfully obtained with ${keyPrefix}pk_m_hash ${pkMHash.toString()}.`);
87
- }
88
- const pkM = Point.fromBuffer(pkMBuffer);
89
- const computedPkMHash = await pkM.hash();
90
- if (!computedPkMHash.equals(pkMHash)) {
91
- throw new Error(`Could not find ${keyPrefix}pkM for ${keyPrefix}pk_m_hash ${pkMHash.toString()}.`);
92
- }
93
- // Now we find the secret key for the public key
94
- const skStorageSuffix = secretKeyStorageSuffix(keyPrefix);
95
- const skMBuffer = await this.#keys.getAsync(`${account.toString()}-${skStorageSuffix}`);
96
- if (!skMBuffer) {
97
- throw new Error(`Could not find ${skStorageSuffix} for account ${account.toString()} whose address was successfully obtained with ${keyPrefix}pk_m_hash ${pkMHash.toString()}.`);
98
- }
99
- const skM = GrumpkinScalar.fromBuffer(skMBuffer);
100
- // We sanity check that it's possible to derive the public key from the secret key
101
- const derivedPkM = await derivePublicKeyFromSecretKey(skM);
102
- if (!derivedPkM.equals(pkM)) {
103
- throw new Error(`Could not derive ${keyPrefix}pkM from ${keyPrefix}skM.`);
104
- }
105
- // At last we silo the secret key and return the key validation request
106
- const skApp = await computeAppSecretKey(skM, contractAddress, keyPrefix);
107
- return new KeyValidationRequest(pkM, skApp);
84
+ */ getKeyValidationRequest(pkMHash, contractAddress) {
85
+ return this.#db.transactionAsync(async ()=>{
86
+ const [keyPrefix, account] = await this.getKeyPrefixAndAccount(pkMHash);
87
+ // Now we find the master public key for the account
88
+ const pkMBuffer = await this.#keys.getAsync(`${account.toString()}-${keyPrefix}pk_m`);
89
+ if (!pkMBuffer) {
90
+ throw new Error(`Could not find ${keyPrefix}pk_m for account ${account.toString()} whose address was successfully obtained with ${keyPrefix}pk_m_hash ${pkMHash.toString()}.`);
91
+ }
92
+ const pkM = Point.fromBuffer(pkMBuffer);
93
+ // Now we find the secret key for the public key
94
+ const skStorageSuffix = secretKeyStorageSuffix(keyPrefix);
95
+ const skMBuffer = await this.#keys.getAsync(`${account.toString()}-${skStorageSuffix}`);
96
+ if (!skMBuffer) {
97
+ throw new Error(`Could not find ${skStorageSuffix} for account ${account.toString()} whose address was successfully obtained with ${keyPrefix}pk_m_hash ${pkMHash.toString()}.`);
98
+ }
99
+ const skM = GrumpkinScalar.fromBuffer(skMBuffer);
100
+ // The remaining awaits are non-DB computations. They are safe because no further IDB operations follow them.
101
+ const computedPkMHash = await pkM.hash();
102
+ if (!computedPkMHash.equals(pkMHash)) {
103
+ throw new Error(`Could not find ${keyPrefix}pkM for ${keyPrefix}pk_m_hash ${pkMHash.toString()}.`);
104
+ }
105
+ const derivedPkM = await derivePublicKeyFromSecretKey(skM);
106
+ if (!derivedPkM.equals(pkM)) {
107
+ throw new Error(`Could not derive ${keyPrefix}pkM from ${keyPrefix}skM.`);
108
+ }
109
+ const skApp = await computeAppSecretKey(skM, contractAddress, keyPrefix);
110
+ return new KeyValidationRequest(pkM, skApp);
111
+ });
108
112
  }
109
113
  /**
110
114
  * Gets the master nullifier public key for a given account.
@@ -182,7 +186,7 @@ import { KEY_PREFIXES, computeAppSecretKey, deriveKeys, derivePublicKeyFromSecre
182
186
  masterOutgoingViewingSecretKey.hi,
183
187
  masterOutgoingViewingSecretKey.lo,
184
188
  app
185
- ], GeneratorIndex.OVSK_M);
189
+ ], DomainSeparator.OVSK_M);
186
190
  }
187
191
  /**
188
192
  * Retrieves the sk_m corresponding to the pk_m.
@@ -190,19 +194,39 @@ import { KEY_PREFIXES, computeAppSecretKey, deriveKeys, derivePublicKeyFromSecre
190
194
  * @param pkM - The master public key to get secret key for.
191
195
  * @returns A Promise that resolves to sk_m.
192
196
  * @dev Used when feeding the sk_m to the kernel circuit for keys verification.
193
- */ async getMasterSecretKey(pkM) {
194
- const [keyPrefix, account] = await this.getKeyPrefixAndAccount(pkM);
195
- const skStorageSuffix = secretKeyStorageSuffix(keyPrefix);
196
- const secretKeyBuffer = await this.#keys.getAsync(`${account.toString()}-${skStorageSuffix}`);
197
- if (!secretKeyBuffer) {
198
- throw new Error(`Could not find ${skStorageSuffix} for ${keyPrefix}pk_m ${pkM.toString()}. This should not happen.`);
199
- }
200
- const skM = GrumpkinScalar.fromBuffer(secretKeyBuffer);
201
- const derivedpkM = await derivePublicKeyFromSecretKey(skM);
202
- if (!derivedpkM.equals(pkM)) {
203
- throw new Error(`Could not find ${skStorageSuffix} for ${keyPrefix}pkM ${pkM.toString()} in secret keys buffer.`);
204
- }
205
- return Promise.resolve(skM);
197
+ */ getMasterSecretKey(pkM) {
198
+ return this.#db.transactionAsync(async ()=>{
199
+ const [keyPrefix, account] = await this.getKeyPrefixAndAccount(pkM);
200
+ const skStorageSuffix = secretKeyStorageSuffix(keyPrefix);
201
+ const secretKeyBuffer = await this.#keys.getAsync(`${account.toString()}-${skStorageSuffix}`);
202
+ if (!secretKeyBuffer) {
203
+ throw new Error(`Could not find ${skStorageSuffix} for ${keyPrefix}pk_m ${pkM.toString()}. This should not happen.`);
204
+ }
205
+ const skM = GrumpkinScalar.fromBuffer(secretKeyBuffer);
206
+ // Non-DB computation — safe because no further IDB operations follow.
207
+ const derivedpkM = await derivePublicKeyFromSecretKey(skM);
208
+ if (!derivedpkM.equals(pkM)) {
209
+ throw new Error(`Could not find ${skStorageSuffix} for ${keyPrefix}pkM ${pkM.toString()} in secret keys buffer.`);
210
+ }
211
+ return skM;
212
+ });
213
+ }
214
+ /**
215
+ * Checks whether a given account has a key matching the provided master public key hash.
216
+ * @param account - The account address to check.
217
+ * @param pkMHash - The master public key hash to look for.
218
+ * @returns True if the account has a key with the given hash.
219
+ */ accountHasKey(account, pkMHash) {
220
+ return this.#db.transactionAsync(async ()=>{
221
+ const pkMHashBuffer = serializeToBuffer(pkMHash);
222
+ for (const prefix of KEY_PREFIXES){
223
+ const stored = await this.#keys.getAsync(`${account.toString()}-${prefix}pk_m_hash`);
224
+ if (stored && Buffer.from(stored).equals(pkMHashBuffer)) {
225
+ return true;
226
+ }
227
+ }
228
+ return false;
229
+ });
206
230
  }
207
231
  /**
208
232
  * Gets the key prefix and account address for a given value.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/key-store",
3
- "version": "0.0.1-commit.e558bd1c",
3
+ "version": "0.0.1-commit.e5a3663dd",
4
4
  "type": "module",
5
5
  "exports": "./dest/index.js",
6
6
  "typedocOptions": {
@@ -57,10 +57,10 @@
57
57
  ]
58
58
  },
59
59
  "dependencies": {
60
- "@aztec/constants": "0.0.1-commit.e558bd1c",
61
- "@aztec/foundation": "0.0.1-commit.e558bd1c",
62
- "@aztec/kv-store": "0.0.1-commit.e558bd1c",
63
- "@aztec/stdlib": "0.0.1-commit.e558bd1c",
60
+ "@aztec/constants": "0.0.1-commit.e5a3663dd",
61
+ "@aztec/foundation": "0.0.1-commit.e5a3663dd",
62
+ "@aztec/kv-store": "0.0.1-commit.e5a3663dd",
63
+ "@aztec/stdlib": "0.0.1-commit.e5a3663dd",
64
64
  "tslib": "^2.4.0"
65
65
  },
66
66
  "devDependencies": {
package/src/key_store.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { GeneratorIndex } from '@aztec/constants';
1
+ import { DomainSeparator } from '@aztec/constants';
2
2
  import { poseidon2HashWithSeparator } from '@aztec/foundation/crypto/poseidon';
3
3
  import { Fr } from '@aztec/foundation/curves/bn254';
4
4
  import { GrumpkinScalar, Point } from '@aztec/foundation/curves/grumpkin';
@@ -104,6 +104,11 @@ export class KeyStore {
104
104
  return accounts.map(account => AztecAddress.fromString(account));
105
105
  }
106
106
 
107
+ /** Checks whether an account is registered in the key store. */
108
+ public async hasAccount(account: AztecAddress): Promise<boolean> {
109
+ return !!(await this.#keys.getAsync(`${account.toString()}-ivsk_m`));
110
+ }
111
+
107
112
  /**
108
113
  * Gets the key validation request for a given master public key hash and contract address.
109
114
  * @throws If the account corresponding to the master public key hash does not exist in the key store.
@@ -111,44 +116,46 @@ export class KeyStore {
111
116
  * @param contractAddress - The contract address to silo the secret key in the key validation request with.
112
117
  * @returns The key validation request.
113
118
  */
114
- public async getKeyValidationRequest(pkMHash: Fr, contractAddress: AztecAddress): Promise<KeyValidationRequest> {
115
- const [keyPrefix, account] = await this.getKeyPrefixAndAccount(pkMHash);
119
+ public getKeyValidationRequest(pkMHash: Fr, contractAddress: AztecAddress): Promise<KeyValidationRequest> {
120
+ return this.#db.transactionAsync(async () => {
121
+ const [keyPrefix, account] = await this.getKeyPrefixAndAccount(pkMHash);
122
+
123
+ // Now we find the master public key for the account
124
+ const pkMBuffer = await this.#keys.getAsync(`${account.toString()}-${keyPrefix}pk_m`);
125
+ if (!pkMBuffer) {
126
+ throw new Error(
127
+ `Could not find ${keyPrefix}pk_m for account ${account.toString()} whose address was successfully obtained with ${keyPrefix}pk_m_hash ${pkMHash.toString()}.`,
128
+ );
129
+ }
116
130
 
117
- // Now we find the master public key for the account
118
- const pkMBuffer = await this.#keys.getAsync(`${account.toString()}-${keyPrefix}pk_m`);
119
- if (!pkMBuffer) {
120
- throw new Error(
121
- `Could not find ${keyPrefix}pk_m for account ${account.toString()} whose address was successfully obtained with ${keyPrefix}pk_m_hash ${pkMHash.toString()}.`,
122
- );
123
- }
131
+ const pkM = Point.fromBuffer(pkMBuffer);
124
132
 
125
- const pkM = Point.fromBuffer(pkMBuffer);
126
- const computedPkMHash = await pkM.hash();
127
- if (!computedPkMHash.equals(pkMHash)) {
128
- throw new Error(`Could not find ${keyPrefix}pkM for ${keyPrefix}pk_m_hash ${pkMHash.toString()}.`);
129
- }
133
+ // Now we find the secret key for the public key
134
+ const skStorageSuffix = secretKeyStorageSuffix(keyPrefix);
135
+ const skMBuffer = await this.#keys.getAsync(`${account.toString()}-${skStorageSuffix}`);
136
+ if (!skMBuffer) {
137
+ throw new Error(
138
+ `Could not find ${skStorageSuffix} for account ${account.toString()} whose address was successfully obtained with ${keyPrefix}pk_m_hash ${pkMHash.toString()}.`,
139
+ );
140
+ }
130
141
 
131
- // Now we find the secret key for the public key
132
- const skStorageSuffix = secretKeyStorageSuffix(keyPrefix);
133
- const skMBuffer = await this.#keys.getAsync(`${account.toString()}-${skStorageSuffix}`);
134
- if (!skMBuffer) {
135
- throw new Error(
136
- `Could not find ${skStorageSuffix} for account ${account.toString()} whose address was successfully obtained with ${keyPrefix}pk_m_hash ${pkMHash.toString()}.`,
137
- );
138
- }
142
+ const skM = GrumpkinScalar.fromBuffer(skMBuffer);
139
143
 
140
- const skM = GrumpkinScalar.fromBuffer(skMBuffer);
144
+ // The remaining awaits are non-DB computations. They are safe because no further IDB operations follow them.
145
+ const computedPkMHash = await pkM.hash();
146
+ if (!computedPkMHash.equals(pkMHash)) {
147
+ throw new Error(`Could not find ${keyPrefix}pkM for ${keyPrefix}pk_m_hash ${pkMHash.toString()}.`);
148
+ }
141
149
 
142
- // We sanity check that it's possible to derive the public key from the secret key
143
- const derivedPkM = await derivePublicKeyFromSecretKey(skM);
144
- if (!derivedPkM.equals(pkM)) {
145
- throw new Error(`Could not derive ${keyPrefix}pkM from ${keyPrefix}skM.`);
146
- }
150
+ const derivedPkM = await derivePublicKeyFromSecretKey(skM);
151
+ if (!derivedPkM.equals(pkM)) {
152
+ throw new Error(`Could not derive ${keyPrefix}pkM from ${keyPrefix}skM.`);
153
+ }
147
154
 
148
- // At last we silo the secret key and return the key validation request
149
- const skApp = await computeAppSecretKey(skM, contractAddress, keyPrefix!);
155
+ const skApp = await computeAppSecretKey(skM, contractAddress, keyPrefix!);
150
156
 
151
- return new KeyValidationRequest(pkM, skApp);
157
+ return new KeyValidationRequest(pkM, skApp);
158
+ });
152
159
  }
153
160
 
154
161
  /**
@@ -249,7 +256,7 @@ export class KeyStore {
249
256
 
250
257
  return poseidon2HashWithSeparator(
251
258
  [masterOutgoingViewingSecretKey.hi, masterOutgoingViewingSecretKey.lo, app],
252
- GeneratorIndex.OVSK_M,
259
+ DomainSeparator.OVSK_M,
253
260
  );
254
261
  }
255
262
 
@@ -260,24 +267,49 @@ export class KeyStore {
260
267
  * @returns A Promise that resolves to sk_m.
261
268
  * @dev Used when feeding the sk_m to the kernel circuit for keys verification.
262
269
  */
263
- public async getMasterSecretKey(pkM: PublicKey): Promise<GrumpkinScalar> {
264
- const [keyPrefix, account] = await this.getKeyPrefixAndAccount(pkM);
270
+ public getMasterSecretKey(pkM: PublicKey): Promise<GrumpkinScalar> {
271
+ return this.#db.transactionAsync(async () => {
272
+ const [keyPrefix, account] = await this.getKeyPrefixAndAccount(pkM);
273
+
274
+ const skStorageSuffix = secretKeyStorageSuffix(keyPrefix);
275
+ const secretKeyBuffer = await this.#keys.getAsync(`${account.toString()}-${skStorageSuffix}`);
276
+ if (!secretKeyBuffer) {
277
+ throw new Error(
278
+ `Could not find ${skStorageSuffix} for ${keyPrefix}pk_m ${pkM.toString()}. This should not happen.`,
279
+ );
280
+ }
265
281
 
266
- const skStorageSuffix = secretKeyStorageSuffix(keyPrefix);
267
- const secretKeyBuffer = await this.#keys.getAsync(`${account.toString()}-${skStorageSuffix}`);
268
- if (!secretKeyBuffer) {
269
- throw new Error(
270
- `Could not find ${skStorageSuffix} for ${keyPrefix}pk_m ${pkM.toString()}. This should not happen.`,
271
- );
272
- }
282
+ const skM = GrumpkinScalar.fromBuffer(secretKeyBuffer);
273
283
 
274
- const skM = GrumpkinScalar.fromBuffer(secretKeyBuffer);
275
- const derivedpkM = await derivePublicKeyFromSecretKey(skM);
276
- if (!derivedpkM.equals(pkM)) {
277
- throw new Error(`Could not find ${skStorageSuffix} for ${keyPrefix}pkM ${pkM.toString()} in secret keys buffer.`);
278
- }
284
+ // Non-DB computation — safe because no further IDB operations follow.
285
+ const derivedpkM = await derivePublicKeyFromSecretKey(skM);
286
+ if (!derivedpkM.equals(pkM)) {
287
+ throw new Error(
288
+ `Could not find ${skStorageSuffix} for ${keyPrefix}pkM ${pkM.toString()} in secret keys buffer.`,
289
+ );
290
+ }
291
+
292
+ return skM;
293
+ });
294
+ }
279
295
 
280
- return Promise.resolve(skM);
296
+ /**
297
+ * Checks whether a given account has a key matching the provided master public key hash.
298
+ * @param account - The account address to check.
299
+ * @param pkMHash - The master public key hash to look for.
300
+ * @returns True if the account has a key with the given hash.
301
+ */
302
+ public accountHasKey(account: AztecAddress, pkMHash: Fr): Promise<boolean> {
303
+ return this.#db.transactionAsync(async () => {
304
+ const pkMHashBuffer = serializeToBuffer(pkMHash);
305
+ for (const prefix of KEY_PREFIXES) {
306
+ const stored = await this.#keys.getAsync(`${account.toString()}-${prefix}pk_m_hash`);
307
+ if (stored && Buffer.from(stored).equals(pkMHashBuffer)) {
308
+ return true;
309
+ }
310
+ }
311
+ return false;
312
+ });
281
313
  }
282
314
 
283
315
  /**