@metamask-previews/seedless-onboarding-controller 3.0.0-preview-e821953d → 3.0.0-preview-e43ca14

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.
@@ -9,11 +9,11 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
9
9
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
10
10
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
11
  };
12
- var _SeedlessOnboardingController_instances, _SeedlessOnboardingController_vaultEncryptor, _SeedlessOnboardingController_controllerOperationMutex, _SeedlessOnboardingController_vaultOperationMutex, _SeedlessOnboardingController_refreshJWTToken, _SeedlessOnboardingController_revokeRefreshToken, _SeedlessOnboardingController_isUnlocked, _SeedlessOnboardingController_passwordOutdatedCacheTTL, _SeedlessOnboardingController_submitGlobalPassword, _SeedlessOnboardingController_getAccessToken, _SeedlessOnboardingController_setUnlocked, _SeedlessOnboardingController_persistOprfKey, _SeedlessOnboardingController_persistAuthPubKey, _SeedlessOnboardingController_storeKeyringEncryptionKey, _SeedlessOnboardingController_loadKeyringEncryptionKey, _SeedlessOnboardingController_loadSeedlessEncryptionKey, _SeedlessOnboardingController_recoverAuthPubKey, _SeedlessOnboardingController_recoverEncKey, _SeedlessOnboardingController_fetchAllSecretDataFromMetadataStore, _SeedlessOnboardingController_changeEncryptionKey, _SeedlessOnboardingController_encryptAndStoreSecretData, _SeedlessOnboardingController_unlockVaultAndGetVaultData, _SeedlessOnboardingController_decryptAndParseVaultData, _SeedlessOnboardingController_withPersistedSecretMetadataBackupsState, _SeedlessOnboardingController_filterDupesAndUpdateSocialBackupsMetadata, _SeedlessOnboardingController_createNewVaultWithAuthData, _SeedlessOnboardingController_updateVault, _SeedlessOnboardingController_withControllerLock, _SeedlessOnboardingController_withVaultLock, _SeedlessOnboardingController_serializeKeyData, _SeedlessOnboardingController_parseVaultData, _SeedlessOnboardingController_assertIsUnlocked, _SeedlessOnboardingController_assertIsAuthenticatedUser, _SeedlessOnboardingController_assertIsSRPBackedUpUser, _SeedlessOnboardingController_assertPasswordInSync, _SeedlessOnboardingController_resetPasswordOutdatedCache, _SeedlessOnboardingController_isTokenExpiredError, _SeedlessOnboardingController_isMaxKeyChainLengthError, _SeedlessOnboardingController_executeWithTokenRefresh;
12
+ var _SeedlessOnboardingController_instances, _SeedlessOnboardingController_vaultEncryptor, _SeedlessOnboardingController_controllerOperationMutex, _SeedlessOnboardingController_vaultOperationMutex, _SeedlessOnboardingController_refreshJWTToken, _SeedlessOnboardingController_revokeRefreshToken, _SeedlessOnboardingController_passwordOutdatedCacheTTL, _SeedlessOnboardingController_isUnlocked, _SeedlessOnboardingController_cachedDecryptedVaultData, _SeedlessOnboardingController_submitGlobalPassword, _SeedlessOnboardingController_getAccessToken, _SeedlessOnboardingController_setUnlocked, _SeedlessOnboardingController_persistOprfKey, _SeedlessOnboardingController_persistAuthPubKey, _SeedlessOnboardingController_storeKeyringEncryptionKey, _SeedlessOnboardingController_loadKeyringEncryptionKey, _SeedlessOnboardingController_loadSeedlessEncryptionKey, _SeedlessOnboardingController_recoverAuthPubKey, _SeedlessOnboardingController_recoverEncKey, _SeedlessOnboardingController_fetchAllSecretDataFromMetadataStore, _SeedlessOnboardingController_changeEncryptionKey, _SeedlessOnboardingController_encryptAndStoreSecretData, _SeedlessOnboardingController_unlockVaultAndGetVaultData, _SeedlessOnboardingController_decryptAndParseVaultData, _SeedlessOnboardingController_withPersistedSecretMetadataBackupsState, _SeedlessOnboardingController_filterDupesAndUpdateSocialBackupsMetadata, _SeedlessOnboardingController_createNewVaultWithAuthData, _SeedlessOnboardingController_updateVault, _SeedlessOnboardingController_withControllerLock, _SeedlessOnboardingController_withVaultLock, _SeedlessOnboardingController_parseVaultData, _SeedlessOnboardingController_assertIsUnlocked, _SeedlessOnboardingController_assertIsAuthenticatedUser, _SeedlessOnboardingController_assertIsSRPBackedUpUser, _SeedlessOnboardingController_assertPasswordInSync, _SeedlessOnboardingController_resetPasswordOutdatedCache, _SeedlessOnboardingController_isTokenExpiredError, _SeedlessOnboardingController_isMaxKeyChainLengthError, _SeedlessOnboardingController_executeWithTokenRefresh;
13
13
  import { keccak256AndHexify } from "@metamask/auth-network-utils";
14
14
  import { BaseController } from "@metamask/base-controller";
15
15
  import { ToprfSecureBackup, TOPRFErrorCode, TOPRFError } from "@metamask/toprf-secure-backup";
16
- import { base64ToBytes, bytesToBase64, bigIntToHex } from "@metamask/utils";
16
+ import { base64ToBytes, bytesToBase64 } from "@metamask/utils";
17
17
  import { gcm } from "@noble/ciphers/aes";
18
18
  import { bytesToUtf8, utf8ToBytes } from "@noble/ciphers/utils";
19
19
  import { managedNonce } from "@noble/ciphers/webcrypto";
@@ -24,7 +24,7 @@ import { controllerName, PASSWORD_OUTDATED_CACHE_TTL_MS, SecretType, SeedlessOnb
24
24
  import { PasswordSyncError, RecoveryError } from "./errors.mjs";
25
25
  import { projectLogger, createModuleLogger } from "./logger.mjs";
26
26
  import { SecretMetadata } from "./SecretMetadata.mjs";
27
- import { decodeJWTToken, decodeNodeAuthToken } from "./utils.mjs";
27
+ import { decodeJWTToken, decodeNodeAuthToken, deserializeVaultData, serializeVaultData } from "./utils.mjs";
28
28
  const log = createModuleLogger(projectLogger, controllerName);
29
29
  /**
30
30
  * Get the initial state for the Seedless Onboarding Controller with defaults.
@@ -163,6 +163,10 @@ export class SeedlessOnboardingController extends BaseController {
163
163
  _SeedlessOnboardingController_vaultOperationMutex.set(this, new Mutex());
164
164
  _SeedlessOnboardingController_refreshJWTToken.set(this, void 0);
165
165
  _SeedlessOnboardingController_revokeRefreshToken.set(this, void 0);
166
+ /**
167
+ * The TTL of the password outdated cache in milliseconds.
168
+ */
169
+ _SeedlessOnboardingController_passwordOutdatedCacheTTL.set(this, void 0);
166
170
  /**
167
171
  * Controller lock state.
168
172
  *
@@ -170,9 +174,11 @@ export class SeedlessOnboardingController extends BaseController {
170
174
  */
171
175
  _SeedlessOnboardingController_isUnlocked.set(this, false);
172
176
  /**
173
- * The TTL of the password outdated cache in milliseconds.
177
+ * Cached decrypted vault data.
178
+ *
179
+ * This is used to cache the decrypted vault data to avoid decrypting the vault data multiple times.
174
180
  */
175
- _SeedlessOnboardingController_passwordOutdatedCacheTTL.set(this, void 0);
181
+ _SeedlessOnboardingController_cachedDecryptedVaultData.set(this, void 0);
176
182
  assertIsPasswordOutdatedCacheValid(passwordOutdatedCacheTTL);
177
183
  __classPrivateFieldSet(this, _SeedlessOnboardingController_passwordOutdatedCacheTTL, passwordOutdatedCacheTTL, "f");
178
184
  __classPrivateFieldSet(this, _SeedlessOnboardingController_vaultEncryptor, encryptor, "f");
@@ -183,14 +189,6 @@ export class SeedlessOnboardingController extends BaseController {
183
189
  });
184
190
  __classPrivateFieldSet(this, _SeedlessOnboardingController_refreshJWTToken, refreshJWTToken, "f");
185
191
  __classPrivateFieldSet(this, _SeedlessOnboardingController_revokeRefreshToken, revokeRefreshToken, "f");
186
- // setup subscriptions to the keyring lock event
187
- // when the keyring is locked (wallet is locked), the controller will be cleared of its credentials
188
- this.messagingSystem.subscribe('KeyringController:lock', () => {
189
- this.setLocked();
190
- });
191
- this.messagingSystem.subscribe('KeyringController:unlock', () => {
192
- __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_setUnlocked).call(this);
193
- });
194
192
  }
195
193
  async fetchMetadataAccessCreds() {
196
194
  const { metadataAccessToken } = this.state;
@@ -502,7 +500,7 @@ export class SeedlessOnboardingController extends BaseController {
502
500
  */
503
501
  async submitPassword(password) {
504
502
  return await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_withControllerLock).call(this, async () => {
505
- await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_unlockVaultAndGetVaultData).call(this, password);
503
+ await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_unlockVaultAndGetVaultData).call(this, { password });
506
504
  __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_setUnlocked).call(this);
507
505
  });
508
506
  }
@@ -510,15 +508,20 @@ export class SeedlessOnboardingController extends BaseController {
510
508
  * Set the controller to locked state, and deallocate the secrets (vault encryption key and salt).
511
509
  *
512
510
  * When the controller is locked, the user will not be able to perform any operations on the controller/vault.
511
+ *
512
+ * @returns A promise that resolves to the success of the operation.
513
513
  */
514
- setLocked() {
515
- this.update((state) => {
516
- delete state.vaultEncryptionKey;
517
- delete state.vaultEncryptionSalt;
518
- delete state.revokeToken;
519
- delete state.accessToken;
514
+ async setLocked() {
515
+ return await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_withControllerLock).call(this, async () => {
516
+ this.update((state) => {
517
+ delete state.vaultEncryptionKey;
518
+ delete state.vaultEncryptionSalt;
519
+ delete state.revokeToken;
520
+ delete state.accessToken;
521
+ });
522
+ __classPrivateFieldSet(this, _SeedlessOnboardingController_cachedDecryptedVaultData, undefined, "f");
523
+ __classPrivateFieldSet(this, _SeedlessOnboardingController_isUnlocked, false, "f");
520
524
  });
521
- __classPrivateFieldSet(this, _SeedlessOnboardingController_isUnlocked, false, "f");
522
525
  }
523
526
  /**
524
527
  * Sync the latest global password to the controller.
@@ -696,7 +699,10 @@ export class SeedlessOnboardingController extends BaseController {
696
699
  return await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_withControllerLock).call(this, async () => {
697
700
  __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_assertIsAuthenticatedUser).call(this, this.state);
698
701
  const { vaultEncryptionKey } = this.state;
699
- const { toprfEncryptionKey: rawToprfEncryptionKey, toprfPwEncryptionKey: rawToprfPwEncryptionKey, toprfAuthKeyPair: rawToprfAuthKeyPair, revokeToken, } = await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_unlockVaultAndGetVaultData).call(this, password, vaultEncryptionKey);
702
+ const { toprfEncryptionKey: rawToprfEncryptionKey, toprfPwEncryptionKey: rawToprfPwEncryptionKey, toprfAuthKeyPair: rawToprfAuthKeyPair, revokeToken, } = await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_unlockVaultAndGetVaultData).call(this, {
703
+ password,
704
+ encryptionKey: vaultEncryptionKey,
705
+ });
700
706
  if (!revokeToken) {
701
707
  throw new Error(SeedlessOnboardingControllerErrorMessage.InvalidRevokeToken);
702
708
  }
@@ -773,7 +779,7 @@ export class SeedlessOnboardingController extends BaseController {
773
779
  }
774
780
  }
775
781
  }
776
- _SeedlessOnboardingController_vaultEncryptor = new WeakMap(), _SeedlessOnboardingController_controllerOperationMutex = new WeakMap(), _SeedlessOnboardingController_vaultOperationMutex = new WeakMap(), _SeedlessOnboardingController_refreshJWTToken = new WeakMap(), _SeedlessOnboardingController_revokeRefreshToken = new WeakMap(), _SeedlessOnboardingController_isUnlocked = new WeakMap(), _SeedlessOnboardingController_passwordOutdatedCacheTTL = new WeakMap(), _SeedlessOnboardingController_instances = new WeakSet(), _SeedlessOnboardingController_submitGlobalPassword =
782
+ _SeedlessOnboardingController_vaultEncryptor = new WeakMap(), _SeedlessOnboardingController_controllerOperationMutex = new WeakMap(), _SeedlessOnboardingController_vaultOperationMutex = new WeakMap(), _SeedlessOnboardingController_refreshJWTToken = new WeakMap(), _SeedlessOnboardingController_revokeRefreshToken = new WeakMap(), _SeedlessOnboardingController_passwordOutdatedCacheTTL = new WeakMap(), _SeedlessOnboardingController_isUnlocked = new WeakMap(), _SeedlessOnboardingController_cachedDecryptedVaultData = new WeakMap(), _SeedlessOnboardingController_instances = new WeakSet(), _SeedlessOnboardingController_submitGlobalPassword =
777
783
  /**
778
784
  * @description Submit the global password to the controller, verify the
779
785
  * password validity and unlock the controller.
@@ -799,7 +805,9 @@ async function _SeedlessOnboardingController_submitGlobalPassword({ targetAuthPu
799
805
  const { pwEncKey } = res;
800
806
  const vaultKey = await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_loadSeedlessEncryptionKey).call(this, pwEncKey);
801
807
  // Unlock the controller
802
- await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_unlockVaultAndGetVaultData).call(this, undefined, vaultKey);
808
+ await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_unlockVaultAndGetVaultData).call(this, {
809
+ encryptionKey: vaultKey,
810
+ });
803
811
  __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_setUnlocked).call(this);
804
812
  }
805
813
  catch (error) {
@@ -831,8 +839,10 @@ async function _SeedlessOnboardingController_getAccessToken(password) {
831
839
  if (!vault) {
832
840
  throw new Error(SeedlessOnboardingControllerErrorMessage.InvalidAccessToken);
833
841
  }
834
- const { parsedVaultData } = await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_decryptAndParseVaultData).call(this, password);
835
- return parsedVaultData.accessToken;
842
+ const { vaultData } = await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_decryptAndParseVaultData).call(this, {
843
+ password,
844
+ });
845
+ return vaultData.accessToken;
836
846
  }, _SeedlessOnboardingController_setUnlocked = function _SeedlessOnboardingController_setUnlocked() {
837
847
  __classPrivateFieldSet(this, _SeedlessOnboardingController_isUnlocked, true, "f");
838
848
  }, _SeedlessOnboardingController_persistOprfKey =
@@ -997,7 +1007,7 @@ async function _SeedlessOnboardingController_changeEncryptionKey({ oldPassword,
997
1007
  toprfEncryptionKey: encKey,
998
1008
  toprfPwEncryptionKey: pwEncKey,
999
1009
  toprfAuthKeyPair: authKeyPair,
1000
- } = await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_unlockVaultAndGetVaultData).call(this, oldPassword));
1010
+ } = await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_unlockVaultAndGetVaultData).call(this, { password: oldPassword }));
1001
1011
  }
1002
1012
  const result = await this.toprfClient.changeEncKey({
1003
1013
  nodeAuthTokens: this.state.nodeAuthTokens,
@@ -1066,8 +1076,9 @@ async function _SeedlessOnboardingController_encryptAndStoreSecretData(params) {
1066
1076
  * Unlocks the encrypted vault using the provided password and returns the decrypted vault data.
1067
1077
  * This method ensures thread-safety by using a mutex lock when accessing the vault.
1068
1078
  *
1069
- * @param password - The optional password to unlock the vault.
1070
- * @param encryptionKey - The optional encryption key to unlock the vault.
1079
+ * @param params - The parameters for unlocking the vault.
1080
+ * @param params.password - The optional password to unlock the vault.
1081
+ * @param params.encryptionKey - The optional encryption key to unlock the vault.
1071
1082
  * @returns A promise that resolves to an object containing:
1072
1083
  * - toprfEncryptionKey: The decrypted TOPRF encryption key
1073
1084
  * - toprfAuthKeyPair: The decrypted TOPRF authentication key pair
@@ -1079,54 +1090,43 @@ async function _SeedlessOnboardingController_encryptAndStoreSecretData(params) {
1079
1090
  * - The password is incorrect (from encryptor.decrypt)
1080
1091
  * - The decrypted vault data is malformed
1081
1092
  */
1082
- async function _SeedlessOnboardingController_unlockVaultAndGetVaultData(password, encryptionKey) {
1093
+ async function _SeedlessOnboardingController_unlockVaultAndGetVaultData(params) {
1083
1094
  return __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_withVaultLock).call(this, async () => {
1084
- const { parsedVaultData, vaultEncryptionKey, vaultEncryptionSalt } = await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_decryptAndParseVaultData).call(this, password, encryptionKey);
1085
- const { toprfEncryptionKey, toprfPwEncryptionKey, toprfAuthKeyPair, revokeToken, accessToken, } = parsedVaultData;
1095
+ if (__classPrivateFieldGet(this, _SeedlessOnboardingController_cachedDecryptedVaultData, "f")) {
1096
+ return __classPrivateFieldGet(this, _SeedlessOnboardingController_cachedDecryptedVaultData, "f");
1097
+ }
1098
+ const { vaultData, vaultEncryptionKey, vaultEncryptionSalt } = await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_decryptAndParseVaultData).call(this, params);
1086
1099
  this.update((state) => {
1087
1100
  state.vaultEncryptionKey = vaultEncryptionKey;
1088
1101
  state.vaultEncryptionSalt = vaultEncryptionSalt;
1089
- state.revokeToken = revokeToken;
1090
- state.accessToken = accessToken;
1102
+ state.revokeToken = vaultData.revokeToken;
1103
+ state.accessToken = vaultData.accessToken;
1091
1104
  });
1092
- return {
1093
- toprfEncryptionKey,
1094
- toprfPwEncryptionKey,
1095
- toprfAuthKeyPair,
1096
- revokeToken,
1097
- accessToken,
1098
- };
1105
+ const deserializedVaultData = deserializeVaultData(vaultData);
1106
+ __classPrivateFieldSet(this, _SeedlessOnboardingController_cachedDecryptedVaultData, deserializedVaultData, "f");
1107
+ return deserializedVaultData;
1099
1108
  });
1100
1109
  }, _SeedlessOnboardingController_decryptAndParseVaultData =
1101
1110
  /**
1102
1111
  * Decrypts the vault data and parses it into a usable format.
1103
1112
  *
1104
- * @param password - The optional password to decrypt the vault.
1105
- * @param encryptionKey - The optional encryption key to decrypt the vault.
1113
+ * @param params - The parameters for decrypting the vault.
1114
+ * @param params.password - The optional password to decrypt the vault.
1115
+ * @param params.encryptionKey - The optional encryption key to decrypt the vault.
1106
1116
  * @returns A promise that resolves to an object containing:
1107
1117
  */
1108
- async function _SeedlessOnboardingController_decryptAndParseVaultData(password, encryptionKey) {
1118
+ async function _SeedlessOnboardingController_decryptAndParseVaultData(params) {
1109
1119
  let { vaultEncryptionKey, vaultEncryptionSalt } = this.state;
1110
1120
  const { vault: encryptedVault } = this.state;
1111
1121
  if (!encryptedVault) {
1112
1122
  throw new Error(SeedlessOnboardingControllerErrorMessage.VaultError);
1113
1123
  }
1114
- if (encryptionKey) {
1115
- vaultEncryptionKey = encryptionKey;
1124
+ if (params?.encryptionKey) {
1125
+ vaultEncryptionKey = params.encryptionKey;
1116
1126
  }
1117
1127
  let decryptedVaultData;
1118
- if (password) {
1119
- assertIsValidPassword(password);
1120
- // Note that vault decryption using the password is a very costly operation as it involves deriving the encryption key
1121
- // from the password using an intentionally slow key derivation function.
1122
- // We should make sure that we only call it very intentionally.
1123
- const result = await __classPrivateFieldGet(this, _SeedlessOnboardingController_vaultEncryptor, "f").decryptWithDetail(password, encryptedVault);
1124
- decryptedVaultData = result.vault;
1125
- vaultEncryptionKey = result.exportedKeyString;
1126
- vaultEncryptionSalt = result.salt;
1127
- }
1128
- else {
1129
- assertIsVaultEncryptionKeyDefined(vaultEncryptionKey);
1128
+ // if the encryption key is available, we will use it to decrypt the vault
1129
+ if (vaultEncryptionKey) {
1130
1130
  const parsedEncryptedVault = JSON.parse(encryptedVault);
1131
1131
  if (vaultEncryptionSalt &&
1132
1132
  vaultEncryptionSalt !== parsedEncryptedVault.salt) {
@@ -1135,9 +1135,20 @@ async function _SeedlessOnboardingController_decryptAndParseVaultData(password,
1135
1135
  const key = await __classPrivateFieldGet(this, _SeedlessOnboardingController_vaultEncryptor, "f").importKey(vaultEncryptionKey);
1136
1136
  decryptedVaultData = await __classPrivateFieldGet(this, _SeedlessOnboardingController_vaultEncryptor, "f").decryptWithKey(key, parsedEncryptedVault);
1137
1137
  }
1138
- const parsedVaultData = __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_parseVaultData).call(this, decryptedVaultData);
1138
+ else {
1139
+ // if the encryption key is not available, we will use the password to decrypt the vault
1140
+ assertIsValidPassword(params?.password);
1141
+ // Note that vault decryption using the password is a very costly operation as it involves deriving the encryption key
1142
+ // from the password using an intentionally slow key derivation function.
1143
+ // We should make sure that we only call it very intentionally.
1144
+ const result = await __classPrivateFieldGet(this, _SeedlessOnboardingController_vaultEncryptor, "f").decryptWithDetail(params.password, encryptedVault);
1145
+ decryptedVaultData = result.vault;
1146
+ vaultEncryptionKey = result.exportedKeyString;
1147
+ vaultEncryptionSalt = result.salt;
1148
+ }
1149
+ const vaultData = __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_parseVaultData).call(this, decryptedVaultData);
1139
1150
  return {
1140
- parsedVaultData,
1151
+ vaultData,
1141
1152
  vaultEncryptionKey,
1142
1153
  vaultEncryptionSalt,
1143
1154
  };
@@ -1213,17 +1224,16 @@ async function _SeedlessOnboardingController_createNewVaultWithAuthData({ passwo
1213
1224
  __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_assertIsAuthenticatedUser).call(this, this.state);
1214
1225
  const { revokeToken } = this.state;
1215
1226
  const accessToken = await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_getAccessToken).call(this, password);
1216
- const { toprfEncryptionKey, toprfPwEncryptionKey, toprfAuthKeyPair } = __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_serializeKeyData).call(this, rawToprfEncryptionKey, rawToprfPwEncryptionKey, rawToprfAuthKeyPair);
1217
- const serializedVaultData = JSON.stringify({
1218
- toprfEncryptionKey,
1219
- toprfPwEncryptionKey,
1220
- toprfAuthKeyPair,
1227
+ const vaultData = {
1228
+ toprfAuthKeyPair: rawToprfAuthKeyPair,
1229
+ toprfEncryptionKey: rawToprfEncryptionKey,
1230
+ toprfPwEncryptionKey: rawToprfPwEncryptionKey,
1221
1231
  revokeToken,
1222
1232
  accessToken,
1223
- });
1233
+ };
1224
1234
  await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_updateVault).call(this, {
1225
1235
  password,
1226
- serializedVaultData,
1236
+ vaultData,
1227
1237
  pwEncKey: rawToprfPwEncryptionKey,
1228
1238
  });
1229
1239
  // update the authPubKey in the state
@@ -1237,13 +1247,16 @@ async function _SeedlessOnboardingController_createNewVaultWithAuthData({ passwo
1237
1247
  *
1238
1248
  * @param params - The parameters for updating the vault.
1239
1249
  * @param params.password - The password to encrypt the vault.
1240
- * @param params.serializedVaultData - The serialized authentication data to update the vault with.
1250
+ * @param params.vaultData - The raw vault data to update the vault with.
1241
1251
  * @param params.pwEncKey - The global password encryption key.
1242
1252
  * @returns A promise that resolves to the updated vault.
1243
1253
  */
1244
- async function _SeedlessOnboardingController_updateVault({ password, serializedVaultData, pwEncKey, }) {
1254
+ async function _SeedlessOnboardingController_updateVault({ password, vaultData, pwEncKey, }) {
1245
1255
  await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_withVaultLock).call(this, async () => {
1246
1256
  assertIsValidPassword(password);
1257
+ // cache the vault data to avoid decrypting the vault data multiple times
1258
+ __classPrivateFieldSet(this, _SeedlessOnboardingController_cachedDecryptedVaultData, vaultData, "f");
1259
+ const serializedVaultData = serializeVaultData(vaultData);
1247
1260
  // Note that vault encryption using the password is a very costly operation as it involves deriving the encryption key
1248
1261
  // from the password using an intentionally slow key derivation function.
1249
1262
  // We should make sure that we only call it very intentionally.
@@ -1287,44 +1300,19 @@ async function _SeedlessOnboardingController_withControllerLock(callback) {
1287
1300
  */
1288
1301
  async function _SeedlessOnboardingController_withVaultLock(callback) {
1289
1302
  return await withLock(__classPrivateFieldGet(this, _SeedlessOnboardingController_vaultOperationMutex, "f"), callback);
1290
- }, _SeedlessOnboardingController_serializeKeyData = function _SeedlessOnboardingController_serializeKeyData(encKey, pwEncKey, authKeyPair) {
1291
- const b64EncodedEncKey = bytesToBase64(encKey);
1292
- const b64EncodedPwEncKey = bytesToBase64(pwEncKey);
1293
- const b64EncodedAuthKeyPair = JSON.stringify({
1294
- sk: bigIntToHex(authKeyPair.sk),
1295
- pk: bytesToBase64(authKeyPair.pk),
1296
- });
1297
- return {
1298
- toprfEncryptionKey: b64EncodedEncKey,
1299
- toprfPwEncryptionKey: b64EncodedPwEncKey,
1300
- toprfAuthKeyPair: b64EncodedAuthKeyPair,
1301
- };
1302
1303
  }, _SeedlessOnboardingController_parseVaultData = function _SeedlessOnboardingController_parseVaultData(data) {
1303
1304
  if (typeof data !== 'string') {
1304
- throw new Error(SeedlessOnboardingControllerErrorMessage.InvalidVaultData);
1305
+ throw new Error(SeedlessOnboardingControllerErrorMessage.VaultDataError);
1305
1306
  }
1306
1307
  let parsedVaultData;
1307
1308
  try {
1308
1309
  parsedVaultData = JSON.parse(data);
1309
1310
  }
1310
1311
  catch {
1311
- throw new Error(SeedlessOnboardingControllerErrorMessage.InvalidVaultData);
1312
+ throw new Error(SeedlessOnboardingControllerErrorMessage.VaultDataError);
1312
1313
  }
1313
1314
  assertIsValidVaultData(parsedVaultData);
1314
- const rawToprfEncryptionKey = base64ToBytes(parsedVaultData.toprfEncryptionKey);
1315
- const rawToprfPwEncryptionKey = base64ToBytes(parsedVaultData.toprfPwEncryptionKey);
1316
- const parsedToprfAuthKeyPair = JSON.parse(parsedVaultData.toprfAuthKeyPair);
1317
- const rawToprfAuthKeyPair = {
1318
- sk: BigInt(parsedToprfAuthKeyPair.sk),
1319
- pk: base64ToBytes(parsedToprfAuthKeyPair.pk),
1320
- };
1321
- return {
1322
- toprfEncryptionKey: rawToprfEncryptionKey,
1323
- toprfPwEncryptionKey: rawToprfPwEncryptionKey,
1324
- toprfAuthKeyPair: rawToprfAuthKeyPair,
1325
- revokeToken: parsedVaultData.revokeToken,
1326
- accessToken: parsedVaultData.accessToken,
1327
- };
1315
+ return parsedVaultData;
1328
1316
  }, _SeedlessOnboardingController_assertIsUnlocked = function _SeedlessOnboardingController_assertIsUnlocked() {
1329
1317
  if (!__classPrivateFieldGet(this, _SeedlessOnboardingController_isUnlocked, "f")) {
1330
1318
  throw new Error(SeedlessOnboardingControllerErrorMessage.ControllerLocked);
@@ -1354,10 +1342,8 @@ async function _SeedlessOnboardingController_withVaultLock(callback) {
1354
1342
  * @throws If the password is outdated.
1355
1343
  */
1356
1344
  async function _SeedlessOnboardingController_assertPasswordInSync(options) {
1345
+ __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_assertIsAuthenticatedUser).call(this, this.state);
1357
1346
  const { nodeAuthTokens, authConnectionId, groupedAuthConnectionId, userId, } = this.state;
1358
- if (!nodeAuthTokens || !authConnectionId || !userId) {
1359
- throw new Error(SeedlessOnboardingControllerErrorMessage.MissingAuthUserInfo);
1360
- }
1361
1347
  const { authPubKey, keyIndex: latestKeyIndex } = await this.toprfClient
1362
1348
  .fetchAuthPubKey({
1363
1349
  nodeAuthTokens,
@@ -1500,15 +1486,4 @@ function assertIsEncryptedSeedlessEncryptionKeySet(encryptedSeedlessEncryptionKe
1500
1486
  throw new Error(SeedlessOnboardingControllerErrorMessage.EncryptedSeedlessEncryptionKeyNotSet);
1501
1487
  }
1502
1488
  }
1503
- /**
1504
- * Assert that the provided vault encryption key is a valid non-empty string.
1505
- *
1506
- * @param vaultEncryptionKey - The vault encryption key to check.
1507
- * @throws If the vault encryption key is not a valid string.
1508
- */
1509
- function assertIsVaultEncryptionKeyDefined(vaultEncryptionKey) {
1510
- if (!vaultEncryptionKey) {
1511
- throw new Error(SeedlessOnboardingControllerErrorMessage.VaultEncryptionKeyUndefined);
1512
- }
1513
- }
1514
1489
  //# sourceMappingURL=SeedlessOnboardingController.mjs.map