@metamask-previews/seedless-onboarding-controller 1.0.0-preview-8e80bb02 → 1.0.0-preview-13f36eb8
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/CHANGELOG.md +4 -0
- package/dist/SeedlessOnboardingController.cjs.map +1 -1
- package/dist/SeedlessOnboardingController.d.cts +2 -2
- package/dist/SeedlessOnboardingController.d.cts.map +1 -1
- package/dist/SeedlessOnboardingController.d.mts +2 -2
- package/dist/SeedlessOnboardingController.d.mts.map +1 -1
- package/dist/SeedlessOnboardingController.mjs.map +1 -1
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +3 -3
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +3 -3
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -16,6 +16,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
16
16
|
- renamed `fetchAllSeedPhrases` method to `fetchAllSecretData` and updated the return value to `Record<SecretType, Uint8Array[]>`.
|
|
17
17
|
- added new error message, `MissingKeyringId` which will throw if no `keyringId` is provided during seed phrase (Mnemonic) backup.
|
|
18
18
|
|
|
19
|
+
### Changed
|
|
20
|
+
|
|
21
|
+
- **BREAKING:** `SeedlessOnboardingController` now requires an additional `SupportedKeyDerivationOptions` type parameter ([#5963](https://github.com/MetaMask/core/pull/5963))
|
|
22
|
+
|
|
19
23
|
## [1.0.0]
|
|
20
24
|
|
|
21
25
|
### Added
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SeedlessOnboardingController.cjs","sourceRoot":"","sources":["../src/SeedlessOnboardingController.ts"],"names":[],"mappings":"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","sourcesContent":["import { keccak256AndHexify } from '@metamask/auth-network-utils';\nimport type { StateMetadata } from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport type {\n KeyPair,\n NodeAuthTokens,\n RecoverEncryptionKeyResult,\n SEC1EncodedPublicKey,\n} from '@metamask/toprf-secure-backup';\nimport { ToprfSecureBackup } from '@metamask/toprf-secure-backup';\nimport { base64ToBytes, bytesToBase64, bigIntToHex } from '@metamask/utils';\nimport { secp256k1 } from '@noble/curves/secp256k1';\nimport { Mutex } from 'async-mutex';\n\nimport {\n type AuthConnection,\n controllerName,\n PASSWORD_OUTDATED_CACHE_TTL_MS,\n SecretType,\n SeedlessOnboardingControllerErrorMessage,\n Web3AuthNetwork,\n} from './constants';\nimport { PasswordSyncError, RecoveryError } from './errors';\nimport { projectLogger, createModuleLogger } from './logger';\nimport { SecretMetadata } from './SecretMetadata';\nimport type {\n MutuallyExclusiveCallback,\n SeedlessOnboardingControllerMessenger,\n SeedlessOnboardingControllerOptions,\n SeedlessOnboardingControllerState,\n VaultData,\n AuthenticatedUserDetails,\n SocialBackupsMetadata,\n SRPBackedUpUserDetails,\n VaultEncryptor,\n} from './types';\n\nconst log = createModuleLogger(projectLogger, controllerName);\n\n/**\n * Get the default state for the Seedless Onboarding Controller.\n *\n * @returns The default state for the Seedless Onboarding Controller.\n */\nexport function getDefaultSeedlessOnboardingControllerState(): SeedlessOnboardingControllerState {\n return {\n socialBackupsMetadata: [],\n };\n}\n\n/**\n * Seedless Onboarding Controller State Metadata.\n *\n * This allows us to choose if fields of the state should be persisted or not\n * using the `persist` flag; and if they can be sent to Sentry or not, using\n * the `anonymous` flag.\n */\nconst seedlessOnboardingMetadata: StateMetadata<SeedlessOnboardingControllerState> =\n {\n vault: {\n persist: true,\n anonymous: false,\n },\n socialBackupsMetadata: {\n persist: true,\n anonymous: true,\n },\n nodeAuthTokens: {\n persist: true,\n anonymous: true,\n },\n authConnection: {\n persist: true,\n anonymous: true,\n },\n authConnectionId: {\n persist: true,\n anonymous: true,\n },\n groupedAuthConnectionId: {\n persist: true,\n anonymous: true,\n },\n userId: {\n persist: true,\n anonymous: true,\n },\n socialLoginEmail: {\n persist: true,\n anonymous: true,\n },\n vaultEncryptionKey: {\n persist: false,\n anonymous: true,\n },\n vaultEncryptionSalt: {\n persist: false,\n anonymous: true,\n },\n authPubKey: {\n persist: true,\n anonymous: true,\n },\n passwordOutdatedCache: {\n persist: true,\n anonymous: true,\n },\n recoveryRatelimitCache: {\n persist: true,\n anonymous: true,\n },\n };\n\nexport class SeedlessOnboardingController<EncryptionKey> extends BaseController<\n typeof controllerName,\n SeedlessOnboardingControllerState,\n SeedlessOnboardingControllerMessenger\n> {\n readonly #vaultEncryptor: VaultEncryptor<EncryptionKey>;\n\n readonly #controllerOperationMutex = new Mutex();\n\n readonly #vaultOperationMutex = new Mutex();\n\n readonly toprfClient: ToprfSecureBackup;\n\n /**\n * Controller lock state.\n *\n * The controller lock is synchronized with the keyring lock.\n */\n #isUnlocked = false;\n\n /**\n * Creates a new SeedlessOnboardingController instance.\n *\n * @param options - The options for the SeedlessOnboardingController.\n * @param options.messenger - A restricted messenger.\n * @param options.state - Initial state to set on this controller.\n * @param options.encryptor - An optional encryptor to use for encrypting and decrypting seedless onboarding vault.\n * @param options.toprfKeyDeriver - An optional key derivation interface for the TOPRF client.\n * @param options.network - The network to be used for the Seedless Onboarding flow.\n */\n constructor({\n messenger,\n state,\n encryptor,\n toprfKeyDeriver,\n network = Web3AuthNetwork.Mainnet,\n }: SeedlessOnboardingControllerOptions<EncryptionKey>) {\n super({\n name: controllerName,\n metadata: seedlessOnboardingMetadata,\n state: {\n ...getDefaultSeedlessOnboardingControllerState(),\n ...state,\n },\n messenger,\n });\n\n this.#vaultEncryptor = encryptor;\n this.toprfClient = new ToprfSecureBackup({\n network,\n keyDeriver: toprfKeyDeriver,\n });\n\n // setup subscriptions to the keyring lock event\n // when the keyring is locked (wallet is locked), the controller will be cleared of its credentials\n this.messagingSystem.subscribe('KeyringController:lock', () => {\n this.setLocked();\n });\n this.messagingSystem.subscribe('KeyringController:unlock', () => {\n this.#setUnlocked();\n });\n }\n\n /**\n * Authenticate OAuth user using the seedless onboarding flow\n * and determine if the user is already registered or not.\n *\n * @param params - The parameters for authenticate OAuth user.\n * @param params.idTokens - The ID token(s) issued by OAuth verification service. Currently this array only contains a single idToken which is verified by all the nodes, in future we are considering to issue a unique idToken for each node.\n * @param params.authConnection - The social login provider.\n * @param params.authConnectionId - OAuth authConnectionId from dashboard\n * @param params.userId - user email or id from Social login\n * @param params.groupedAuthConnectionId - Optional grouped authConnectionId to be used for the authenticate request.\n * @param params.socialLoginEmail - The user email from Social login.\n * You can pass this to use aggregate multiple OAuth connections. Useful when you want user to have same account while using different OAuth connections.\n * @returns A promise that resolves to the authentication result.\n */\n async authenticate(params: {\n idTokens: string[];\n authConnection: AuthConnection;\n authConnectionId: string;\n userId: string;\n groupedAuthConnectionId?: string;\n socialLoginEmail?: string;\n }) {\n return await this.#withControllerLock(async () => {\n try {\n const {\n idTokens,\n authConnectionId,\n groupedAuthConnectionId,\n userId,\n authConnection,\n socialLoginEmail,\n } = params;\n\n const authenticationResult = await this.toprfClient.authenticate({\n authConnectionId,\n userId,\n idTokens,\n groupedAuthConnectionId,\n });\n // update the state with the authenticated user info\n this.update((state) => {\n state.nodeAuthTokens = authenticationResult.nodeAuthTokens;\n state.authConnectionId = authConnectionId;\n state.groupedAuthConnectionId = groupedAuthConnectionId;\n state.userId = userId;\n state.authConnection = authConnection;\n state.socialLoginEmail = socialLoginEmail;\n });\n return authenticationResult;\n } catch (error) {\n log('Error authenticating user', error);\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.AuthenticationError,\n );\n }\n });\n }\n\n /**\n * Create a new TOPRF encryption key using given password and backups the provided seed phrase.\n *\n * @param password - The password used to create new wallet and seedphrase\n * @param seedPhrase - The seed phrase to backup\n * @param keyringId - The keyring id of the backup seed phrase\n * @returns A promise that resolves to the encrypted seed phrase and the encryption key.\n */\n async createToprfKeyAndBackupSeedPhrase(\n password: string,\n seedPhrase: Uint8Array,\n keyringId: string,\n ): Promise<void> {\n // to make sure that fail fast,\n // assert that the user is authenticated before creating the TOPRF key and backing up the seed phrase\n this.#assertIsAuthenticatedUser(this.state);\n\n return await this.#withControllerLock(async () => {\n // locally evaluate the encryption key from the password\n const { encKey, authKeyPair, oprfKey } =\n await this.toprfClient.createLocalKey({\n password,\n });\n\n // encrypt and store the seed phrase backup\n await this.#encryptAndStoreSecretData({\n data: seedPhrase,\n type: SecretType.Mnemonic,\n encKey,\n authKeyPair,\n options: {\n keyringId,\n },\n });\n\n // store/persist the encryption key shares\n // We store the seed phrase metadata in the metadata store first. If this operation fails,\n // we avoid persisting the encryption key shares to prevent a situation where a user appears\n // to have an account but with no associated data.\n await this.#persistOprfKey(oprfKey, authKeyPair.pk);\n // create a new vault with the resulting authentication data\n await this.#createNewVaultWithAuthData({\n password,\n rawToprfEncryptionKey: encKey,\n rawToprfAuthKeyPair: authKeyPair,\n });\n this.#persistAuthPubKey({\n authPubKey: authKeyPair.pk,\n });\n });\n }\n\n /**\n * encrypt and add a new secret data to the metadata store.\n *\n * @param data - The data to add.\n * @param type - The type of the secret data.\n * @param options - Optional options object, which includes optional data to be added to the metadata store.\n * @param options.keyringId - The keyring id of the backup keyring (SRP).\n * @returns A promise that resolves to the success of the operation.\n */\n async addNewSecretData(\n data: Uint8Array,\n type: SecretType,\n options?: {\n keyringId?: string;\n },\n ): Promise<void> {\n return await this.#withControllerLock(async () => {\n this.#assertIsUnlocked();\n\n await this.#assertPasswordInSync({\n skipCache: true,\n skipLock: true, // skip lock since we already have the lock\n });\n\n // verify the password and unlock the vault\n const { toprfEncryptionKey, toprfAuthKeyPair } =\n await this.#unlockVaultAndGetBackupEncKey();\n\n // encrypt and store the seed phrase backup\n await this.#encryptAndStoreSecretData({\n data,\n type,\n encKey: toprfEncryptionKey,\n authKeyPair: toprfAuthKeyPair,\n options,\n });\n });\n }\n\n /**\n * Fetches all encrypted secret data and metadata for user's account from the metadata store.\n *\n * Decrypts the secret data and returns the decrypted secret data using the recovered encryption key from the password.\n *\n * @param password - The optional password used to create new wallet and seedphrase. If not provided, `cached Encryption Key` will be used.\n * @returns A promise that resolves to the secret data.\n */\n async fetchAllSecretData(\n password?: string,\n ): Promise<Record<SecretType, Uint8Array[]>> {\n // assert that the user is authenticated before fetching the seed phrases\n this.#assertIsAuthenticatedUser(this.state);\n\n return await this.#withControllerLock(async () => {\n let encKey: Uint8Array;\n let authKeyPair: KeyPair;\n\n if (password) {\n const recoverEncKeyResult = await this.#recoverEncKey(password);\n encKey = recoverEncKeyResult.encKey;\n authKeyPair = recoverEncKeyResult.authKeyPair;\n } else {\n this.#assertIsUnlocked();\n // verify the password and unlock the vault\n const keysFromVault = await this.#unlockVaultAndGetBackupEncKey();\n encKey = keysFromVault.toprfEncryptionKey;\n authKeyPair = keysFromVault.toprfAuthKeyPair;\n }\n\n try {\n const secretData = await this.toprfClient.fetchAllSecretDataItems({\n decKey: encKey,\n authKeyPair,\n });\n\n if (secretData?.length > 0 && password) {\n // if password is provided, we need to create a new vault with the auth data. (supposedly the user is trying to rehydrate the wallet)\n await this.#createNewVaultWithAuthData({\n password,\n rawToprfEncryptionKey: encKey,\n rawToprfAuthKeyPair: authKeyPair,\n });\n\n this.#persistAuthPubKey({\n authPubKey: authKeyPair.pk,\n });\n }\n\n const result: Record<SecretType, Uint8Array[]> = {\n mnemonic: [],\n privateKey: [],\n };\n const secrets =\n SecretMetadata.parseSecretsFromMetadataStore(secretData);\n\n secrets.forEach((secret) => {\n result[secret.type].push(secret.data);\n });\n\n return result;\n } catch (error) {\n log('Error fetching seed phrase metadata', error);\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.FailedToFetchSeedPhraseMetadata,\n );\n }\n });\n }\n\n /**\n * Update the password of the seedless onboarding flow.\n *\n * Changing password will also update the encryption key, metadata store and the vault with new encrypted values.\n *\n * @param newPassword - The new password to update.\n * @param oldPassword - The old password to verify.\n * @returns A promise that resolves to the success of the operation.\n */\n async changePassword(newPassword: string, oldPassword: string) {\n return await this.#withControllerLock(async () => {\n this.#assertIsUnlocked();\n // verify the old password of the encrypted vault\n await this.verifyVaultPassword(oldPassword, {\n skipLock: true, // skip lock since we already have the lock\n });\n await this.#assertPasswordInSync({\n skipCache: true,\n skipLock: true, // skip lock since we already have the lock\n });\n\n try {\n // update the encryption key with new password and update the Metadata Store\n const { encKey: newEncKey, authKeyPair: newAuthKeyPair } =\n await this.#changeEncryptionKey(newPassword, oldPassword);\n\n // update and encrypt the vault with new password\n await this.#createNewVaultWithAuthData({\n password: newPassword,\n rawToprfEncryptionKey: newEncKey,\n rawToprfAuthKeyPair: newAuthKeyPair,\n });\n\n this.#persistAuthPubKey({\n authPubKey: newAuthKeyPair.pk,\n });\n this.#resetPasswordOutdatedCache();\n } catch (error) {\n log('Error changing password', error);\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.FailedToChangePassword,\n );\n }\n });\n }\n\n /**\n * Update the backup metadata state for the given seed phrase.\n *\n * @param data - The data to backup, can be a single backup or array of backups.\n * @param data.keyringId - The keyring id associated with the backup seed phrase.\n * @param data.seedPhrase - The seed phrase to update the backup metadata state.\n */\n updateBackupMetadataState(\n data:\n | {\n keyringId: string;\n seedPhrase: Uint8Array;\n }\n | {\n keyringId: string;\n seedPhrase: Uint8Array;\n }[],\n ) {\n this.#assertIsUnlocked();\n\n this.#filterDupesAndUpdateSocialBackupsMetadata(data);\n }\n\n /**\n * Verify the password validity by decrypting the vault.\n *\n * @param password - The password to verify.\n * @param options - Optional options object.\n * @param options.skipLock - Whether to skip the lock acquisition.\n * @returns A promise that resolves to the success of the operation.\n * @throws {Error} If the password is invalid or the vault is not initialized.\n */\n async verifyVaultPassword(\n password: string,\n options?: {\n skipLock?: boolean;\n },\n ): Promise<void> {\n const doVerify = async () => {\n if (!this.state.vault) {\n throw new Error(SeedlessOnboardingControllerErrorMessage.VaultError);\n }\n await this.#vaultEncryptor.decrypt(password, this.state.vault);\n };\n return options?.skipLock\n ? await doVerify()\n : await this.#withControllerLock(doVerify);\n }\n\n /**\n * Get the hash of the seed phrase backup for the given seed phrase, from the state.\n *\n * If the given seed phrase is not backed up and not found in the state, it will return `undefined`.\n *\n * @param seedPhrase - The seed phrase to get the hash of.\n * @returns A promise that resolves to the hash of the seed phrase backup.\n */\n getSeedPhraseBackupHash(\n seedPhrase: Uint8Array,\n ): SocialBackupsMetadata | undefined {\n const seedPhraseHash = keccak256AndHexify(seedPhrase);\n return this.state.socialBackupsMetadata.find(\n (backup) => backup.hash === seedPhraseHash,\n );\n }\n\n /**\n * Submit the password to the controller, verify the password validity and unlock the controller.\n *\n * This method will be used especially when user rehydrate/unlock the wallet.\n * The provided password will be verified against the encrypted vault, encryption key will be derived and saved in the controller state.\n *\n * This operation is useful when user performs some actions that requires the user password/encryption key. e.g. add new srp backup\n *\n * @param password - The password to submit.\n * @returns A promise that resolves to the success of the operation.\n */\n async submitPassword(password: string): Promise<void> {\n return await this.#withControllerLock(async () => {\n await this.#unlockVaultAndGetBackupEncKey(password);\n this.#setUnlocked();\n });\n }\n\n /**\n * Set the controller to locked state, and deallocate the secrets (vault encryption key and salt).\n *\n * When the controller is locked, the user will not be able to perform any operations on the controller/vault.\n */\n setLocked() {\n this.update((state) => {\n delete state.vaultEncryptionKey;\n delete state.vaultEncryptionSalt;\n });\n\n this.#isUnlocked = false;\n }\n\n /**\n * Sync the latest global password to the controller.\n * reset vault with latest globalPassword,\n * persist the latest global password authPubKey\n *\n * @param params - The parameters for syncing the latest global password.\n * @param params.oldPassword - The old password to verify.\n * @param params.globalPassword - The latest global password.\n * @returns A promise that resolves to the success of the operation.\n */\n async syncLatestGlobalPassword({\n oldPassword,\n globalPassword,\n }: {\n oldPassword: string;\n globalPassword: string;\n }) {\n return await this.#withControllerLock(async () => {\n // verify correct old password\n await this.verifyVaultPassword(oldPassword, {\n skipLock: true, // skip lock since we already have the lock\n });\n // update vault with latest globalPassword\n const { encKey, authKeyPair } = await this.#recoverEncKey(globalPassword);\n // update and encrypt the vault with new password\n await this.#createNewVaultWithAuthData({\n password: globalPassword,\n rawToprfEncryptionKey: encKey,\n rawToprfAuthKeyPair: authKeyPair,\n });\n // persist the latest global password authPubKey\n this.#persistAuthPubKey({\n authPubKey: authKeyPair.pk,\n });\n this.#resetPasswordOutdatedCache();\n });\n }\n\n /**\n * @description Fetch the password corresponding to the current authPubKey in state (current device password which is already out of sync with the current global password).\n * then we use this recovered old password to unlock the vault and set the password to the new global password.\n *\n * @param params - The parameters for fetching the password.\n * @param params.globalPassword - The latest global password.\n * @returns A promise that resolves to the password corresponding to the current authPubKey in state.\n */\n async recoverCurrentDevicePassword({\n globalPassword,\n }: {\n globalPassword: string;\n }): Promise<{ password: string }> {\n return await this.#withControllerLock(async () => {\n const currentDeviceAuthPubKey = this.#recoverAuthPubKey();\n const { password: currentDevicePassword } = await this.#recoverPassword({\n targetPwPubKey: currentDeviceAuthPubKey,\n globalPassword,\n });\n return {\n password: currentDevicePassword,\n };\n });\n }\n\n /**\n * @description Fetch the password corresponding to the targetPwPubKey.\n *\n * @param params - The parameters for fetching the password.\n * @param params.targetPwPubKey - The target public key of the password to recover.\n * @param params.globalPassword - The latest global password.\n * @returns A promise that resolves to the password corresponding to the current authPubKey in state.\n */\n async #recoverPassword({\n targetPwPubKey,\n globalPassword,\n }: {\n targetPwPubKey: SEC1EncodedPublicKey;\n globalPassword: string;\n }): Promise<{ password: string }> {\n const { encKey: latestPwEncKey, authKeyPair: latestPwAuthKeyPair } =\n await this.#recoverEncKey(globalPassword);\n\n try {\n const res = await this.toprfClient.recoverPassword({\n targetPwPubKey,\n curEncKey: latestPwEncKey,\n curAuthKeyPair: latestPwAuthKeyPair,\n });\n return res;\n } catch (error) {\n throw PasswordSyncError.getInstance(error);\n }\n }\n\n /**\n * @description Check if the current password is outdated compare to the global password.\n *\n * @param options - Optional options object.\n * @param options.skipCache - If true, bypass the cache and force a fresh check.\n * @param options.skipLock - Whether to skip the lock acquisition.\n * @returns A promise that resolves to true if the password is outdated, false otherwise.\n */\n async checkIsPasswordOutdated(options?: {\n skipCache?: boolean;\n skipLock?: boolean;\n }): Promise<boolean> {\n // cache result to reduce load on infra\n // Check cache first unless skipCache is true\n if (!options?.skipCache) {\n const { passwordOutdatedCache } = this.state;\n const now = Date.now();\n const isCacheValid =\n passwordOutdatedCache &&\n now - passwordOutdatedCache.timestamp < PASSWORD_OUTDATED_CACHE_TTL_MS;\n\n if (isCacheValid) {\n return passwordOutdatedCache.isExpiredPwd;\n }\n }\n\n const doCheck = async () => {\n this.#assertIsAuthenticatedUser(this.state);\n const {\n nodeAuthTokens,\n authConnectionId,\n groupedAuthConnectionId,\n userId,\n } = this.state;\n\n const currentDeviceAuthPubKey = this.#recoverAuthPubKey();\n\n const { authPubKey: globalAuthPubKey } =\n await this.toprfClient.fetchAuthPubKey({\n nodeAuthTokens,\n authConnectionId,\n groupedAuthConnectionId,\n userId,\n });\n\n // use noble lib to deserialize and compare curve point\n const isExpiredPwd = !secp256k1.ProjectivePoint.fromHex(\n currentDeviceAuthPubKey,\n ).equals(secp256k1.ProjectivePoint.fromHex(globalAuthPubKey));\n // Cache the result in state\n this.update((state) => {\n state.passwordOutdatedCache = { isExpiredPwd, timestamp: Date.now() };\n });\n return isExpiredPwd;\n };\n\n return options?.skipLock\n ? await doCheck()\n : await this.#withControllerLock(doCheck);\n }\n\n #setUnlocked(): void {\n this.#isUnlocked = true;\n }\n\n /**\n * Clears the current state of the SeedlessOnboardingController.\n */\n clearState() {\n const defaultState = getDefaultSeedlessOnboardingControllerState();\n this.update(() => {\n return defaultState;\n });\n }\n\n /**\n * Persist the encryption key for the seedless onboarding flow.\n *\n * @param oprfKey - The OPRF key to be splited and persisted.\n * @param authPubKey - The authentication public key.\n * @returns A promise that resolves to the success of the operation.\n */\n async #persistOprfKey(oprfKey: bigint, authPubKey: SEC1EncodedPublicKey) {\n this.#assertIsAuthenticatedUser(this.state);\n const { authConnectionId, groupedAuthConnectionId, userId } = this.state;\n\n try {\n await this.toprfClient.persistLocalKey({\n nodeAuthTokens: this.state.nodeAuthTokens,\n authConnectionId,\n groupedAuthConnectionId,\n userId,\n oprfKey,\n authPubKey,\n });\n } catch (error) {\n log('Error persisting local encryption key', error);\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.FailedToPersistOprfKey,\n );\n }\n }\n\n /**\n * Persist the authentication public key for the seedless onboarding flow.\n * convert to suitable format before persisting.\n *\n * @param params - The parameters for persisting the authentication public key.\n * @param params.authPubKey - The authentication public key to be persisted.\n */\n #persistAuthPubKey(params: { authPubKey: SEC1EncodedPublicKey }): void {\n this.update((state) => {\n state.authPubKey = bytesToBase64(params.authPubKey);\n });\n }\n\n /**\n * Recover the authentication public key from the state.\n * convert to pubkey format before recovering.\n *\n * @returns The authentication public key.\n */\n #recoverAuthPubKey(): SEC1EncodedPublicKey {\n this.#assertIsSRPBackedUpUser(this.state);\n const { authPubKey } = this.state;\n\n return base64ToBytes(authPubKey);\n }\n\n /**\n * Recover the encryption key from password.\n *\n * @param password - The password used to derive/recover the encryption key.\n * @returns A promise that resolves to the encryption key and authentication key pair.\n * @throws RecoveryError - If failed to recover the encryption key.\n */\n async #recoverEncKey(password: string) {\n return this.#withRecoveryErrorHandler(async () => {\n this.#assertIsAuthenticatedUser(this.state);\n\n const { authConnectionId, groupedAuthConnectionId, userId } = this.state;\n\n const recoverEncKeyResult = await this.toprfClient.recoverEncKey({\n nodeAuthTokens: this.state.nodeAuthTokens,\n password,\n authConnectionId,\n groupedAuthConnectionId,\n userId,\n });\n return recoverEncKeyResult;\n });\n }\n\n /**\n * Update the encryption key with new password and update the Metadata Store with new encryption key.\n *\n * @param newPassword - The new password to update.\n * @param oldPassword - The old password to verify.\n * @returns A promise that resolves to new encryption key and authentication key pair.\n */\n async #changeEncryptionKey(newPassword: string, oldPassword: string) {\n this.#assertIsAuthenticatedUser(this.state);\n const { authConnectionId, groupedAuthConnectionId, userId } = this.state;\n\n const {\n encKey,\n authKeyPair,\n keyShareIndex: newKeyShareIndex,\n } = await this.#recoverEncKey(oldPassword);\n\n return await this.toprfClient.changeEncKey({\n nodeAuthTokens: this.state.nodeAuthTokens,\n authConnectionId,\n groupedAuthConnectionId,\n userId,\n oldEncKey: encKey,\n oldAuthKeyPair: authKeyPair,\n newKeyShareIndex,\n oldPassword,\n newPassword,\n });\n }\n\n /**\n * Encrypt and store the seed phrase backup in the metadata store.\n *\n * @param params - The parameters for encrypting and storing the seed phrase backup.\n * @param params.data - The seed phrase to store.\n * @param params.type - The type of the secret data.\n * @param params.encKey - The encryption key to store.\n * @param params.authKeyPair - The authentication key pair to store.\n * @param params.options - Optional options object, which includes optional data to be added to the metadata store.\n * @param params.options.keyringId - The keyring id of the backup keyring (SRP).\n *\n * @returns A promise that resolves to the success of the operation.\n */\n async #encryptAndStoreSecretData(params: {\n data: Uint8Array;\n type: SecretType;\n encKey: Uint8Array;\n authKeyPair: KeyPair;\n options?: {\n keyringId?: string;\n };\n }): Promise<void> {\n const { options, data, encKey, authKeyPair, type } = params;\n\n const secretMetadata = new SecretMetadata(data, {\n type,\n });\n const secretData = secretMetadata.toBytes();\n\n const keyringId = options?.keyringId as string;\n if (type === SecretType.Mnemonic && !keyringId) {\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.MissingKeyringId,\n );\n }\n\n try {\n if (type === SecretType.Mnemonic) {\n await this.#withPersistedSeedPhraseBackupsState(async () => {\n await this.toprfClient.addSecretDataItem({\n encKey,\n secretData,\n authKeyPair,\n });\n return {\n keyringId,\n seedPhrase: data,\n };\n });\n return;\n }\n\n await this.toprfClient.addSecretDataItem({\n encKey,\n secretData,\n authKeyPair,\n });\n } catch (error) {\n log('Error encrypting and storing seed phrase backup', error);\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.FailedToEncryptAndStoreSeedPhraseBackup,\n );\n }\n }\n\n /**\n * Unlocks the encrypted vault using the provided password and returns the decrypted vault data.\n * This method ensures thread-safety by using a mutex lock when accessing the vault.\n *\n * @param password - The optional password to unlock the vault.\n * @returns A promise that resolves to an object containing:\n * - nodeAuthTokens: Authentication tokens to communicate with the TOPRF service\n * - toprfEncryptionKey: The decrypted TOPRF encryption key\n * - toprfAuthKeyPair: The decrypted TOPRF authentication key pair\n * @throws {Error} If:\n * - The password is invalid or empty\n * - The vault is not initialized\n * - The password is incorrect (from encryptor.decrypt)\n * - The decrypted vault data is malformed\n */\n async #unlockVaultAndGetBackupEncKey(password?: string): Promise<{\n nodeAuthTokens: NodeAuthTokens;\n toprfEncryptionKey: Uint8Array;\n toprfAuthKeyPair: KeyPair;\n }> {\n return this.#withVaultLock(async () => {\n const {\n vault: encryptedVault,\n vaultEncryptionKey,\n vaultEncryptionSalt,\n } = this.state;\n\n if (!encryptedVault) {\n throw new Error(SeedlessOnboardingControllerErrorMessage.VaultError);\n }\n\n if (!vaultEncryptionKey && !password) {\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.MissingCredentials,\n );\n }\n\n let decryptedVaultData: unknown;\n const updatedState: Partial<SeedlessOnboardingControllerState> = {};\n\n if (password) {\n assertIsValidPassword(password);\n // Note that vault decryption using the password is a very costly operation as it involves deriving the encryption key\n // from the password using an intentionally slow key derivation function.\n // We should make sure that we only call it very intentionally.\n const result = await this.#vaultEncryptor.decryptWithDetail(\n password,\n encryptedVault,\n );\n decryptedVaultData = result.vault;\n updatedState.vaultEncryptionKey = result.exportedKeyString;\n updatedState.vaultEncryptionSalt = result.salt;\n } else {\n const parsedEncryptedVault = JSON.parse(encryptedVault);\n\n if (vaultEncryptionSalt !== parsedEncryptedVault.salt) {\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.ExpiredCredentials,\n );\n }\n\n if (typeof vaultEncryptionKey !== 'string') {\n throw new TypeError(\n SeedlessOnboardingControllerErrorMessage.WrongPasswordType,\n );\n }\n\n const key = await this.#vaultEncryptor.importKey(vaultEncryptionKey);\n decryptedVaultData = await this.#vaultEncryptor.decryptWithKey(\n key,\n parsedEncryptedVault,\n );\n updatedState.vaultEncryptionKey = vaultEncryptionKey;\n updatedState.vaultEncryptionSalt = vaultEncryptionSalt;\n }\n\n const { nodeAuthTokens, toprfEncryptionKey, toprfAuthKeyPair } =\n this.#parseVaultData(decryptedVaultData);\n\n // update the state with the restored nodeAuthTokens\n this.update((state) => {\n state.nodeAuthTokens = nodeAuthTokens;\n state.vaultEncryptionKey = updatedState.vaultEncryptionKey;\n state.vaultEncryptionSalt = updatedState.vaultEncryptionSalt;\n });\n\n return { nodeAuthTokens, toprfEncryptionKey, toprfAuthKeyPair };\n });\n }\n\n /**\n * Executes a callback function that creates or restores seed phrases and persists their hashes in the controller state.\n *\n * This method:\n * 1. Executes the provided callback to create/restore seed phrases\n * 2. Generates keccak256 hashes of the seed phrases\n * 3. Merges new hashes with existing ones in the state, ensuring uniqueness\n * 4. Updates the controller state with the combined hashes\n *\n * This is a wrapper method that should be used around any operation that creates\n * or restores seed phrases to ensure their hashes are properly tracked.\n *\n * @param createSeedPhraseBackupCallback - function that returns either a single seed phrase\n * or an array of seed phrases as Uint8Array(s)\n * @returns The original seed phrase(s) returned by the callback\n * @throws Rethrows any errors from the callback with additional logging\n */\n async #withPersistedSeedPhraseBackupsState(\n createSeedPhraseBackupCallback: () => Promise<{\n keyringId: string;\n seedPhrase: Uint8Array;\n }>,\n ): Promise<{\n keyringId: string;\n seedPhrase: Uint8Array;\n }> {\n try {\n const newBackup = await createSeedPhraseBackupCallback();\n\n this.#filterDupesAndUpdateSocialBackupsMetadata(newBackup);\n\n return newBackup;\n } catch (error) {\n log('Error persisting seed phrase backups', error);\n throw error;\n }\n }\n\n /**\n * Updates the social backups metadata state by adding new unique seed phrase backups.\n * This method ensures no duplicate backups are stored by checking the hash of each seed phrase.\n *\n * @param data - The backup data to add to the state\n * @param data.id - The identifier for the backup\n * @param data.seedPhrase - The seed phrase to backup as a Uint8Array\n */\n #filterDupesAndUpdateSocialBackupsMetadata(\n data:\n | {\n keyringId: string;\n seedPhrase: Uint8Array;\n }\n | {\n keyringId: string;\n seedPhrase: Uint8Array;\n }[],\n ) {\n const currentBackupsMetadata = this.state.socialBackupsMetadata;\n\n const newBackupsMetadata = Array.isArray(data) ? data : [data];\n const filteredNewBackupsMetadata: SocialBackupsMetadata[] = [];\n\n // filter out the backed up metadata that already exists in the state\n // to prevent duplicates\n newBackupsMetadata.forEach((item) => {\n const { keyringId, seedPhrase } = item;\n const backupHash = keccak256AndHexify(seedPhrase);\n\n const backupStateAlreadyExisted = currentBackupsMetadata.some(\n (backup) => backup.hash === backupHash,\n );\n\n if (!backupStateAlreadyExisted) {\n filteredNewBackupsMetadata.push({\n id: keyringId,\n hash: backupHash,\n });\n }\n });\n\n if (filteredNewBackupsMetadata.length > 0) {\n this.update((state) => {\n state.socialBackupsMetadata = [\n ...state.socialBackupsMetadata,\n ...filteredNewBackupsMetadata,\n ];\n });\n }\n }\n\n /**\n * Create a new vault with the given authentication data.\n *\n * Serialize the authentication and key data which will be stored in the vault.\n *\n * @param params - The parameters for creating a new vault.\n * @param params.password - The password to encrypt the vault.\n * @param params.rawToprfEncryptionKey - The encryption key to encrypt the vault.\n * @param params.rawToprfAuthKeyPair - The authentication key pair to encrypt the vault.\n */\n async #createNewVaultWithAuthData({\n password,\n rawToprfEncryptionKey,\n rawToprfAuthKeyPair,\n }: {\n password: string;\n rawToprfEncryptionKey: Uint8Array;\n rawToprfAuthKeyPair: KeyPair;\n }): Promise<void> {\n this.#assertIsAuthenticatedUser(this.state);\n this.#setUnlocked();\n\n const { toprfEncryptionKey, toprfAuthKeyPair } = this.#serializeKeyData(\n rawToprfEncryptionKey,\n rawToprfAuthKeyPair,\n );\n\n const serializedVaultData = JSON.stringify({\n authTokens: this.state.nodeAuthTokens,\n toprfEncryptionKey,\n toprfAuthKeyPair,\n });\n\n await this.#updateVault({\n password,\n serializedVaultData,\n });\n }\n\n /**\n * Encrypt and update the vault with the given authentication data.\n *\n * @param params - The parameters for updating the vault.\n * @param params.password - The password to encrypt the vault.\n * @param params.serializedVaultData - The serialized authentication data to update the vault with.\n * @returns A promise that resolves to the updated vault.\n */\n async #updateVault({\n password,\n serializedVaultData,\n }: {\n password: string;\n serializedVaultData: string;\n }): Promise<void> {\n await this.#withVaultLock(async () => {\n assertIsValidPassword(password);\n\n // Note that vault encryption using the password is a very costly operation as it involves deriving the encryption key\n // from the password using an intentionally slow key derivation function.\n // We should make sure that we only call it very intentionally.\n const { vault, exportedKeyString } =\n await this.#vaultEncryptor.encryptWithDetail(\n password,\n serializedVaultData,\n );\n\n this.update((state) => {\n state.vault = vault;\n state.vaultEncryptionKey = exportedKeyString;\n state.vaultEncryptionSalt = JSON.parse(vault).salt;\n });\n });\n }\n\n /**\n * Lock the controller mutex before executing the given function,\n * and release it after the function is resolved or after an\n * error is thrown.\n *\n * This wrapper ensures that each mutable operation that interacts with the\n * controller and that changes its state is executed in a mutually exclusive way,\n * preventing unsafe concurrent access that could lead to unpredictable behavior.\n *\n * @param callback - The function to execute while the controller mutex is locked.\n * @returns The result of the function.\n */\n async #withControllerLock<Result>(\n callback: MutuallyExclusiveCallback<Result>,\n ): Promise<Result> {\n return await withLock(this.#controllerOperationMutex, callback);\n }\n\n /**\n * Lock the vault mutex before executing the given function,\n * and release it after the function is resolved or after an\n * error is thrown.\n *\n * This ensures that each operation that interacts with the vault\n * is executed in a mutually exclusive way.\n *\n * @param callback - The function to execute while the vault mutex is locked.\n * @returns The result of the function.\n */\n async #withVaultLock<Result>(\n callback: MutuallyExclusiveCallback<Result>,\n ): Promise<Result> {\n return await withLock(this.#vaultOperationMutex, callback);\n }\n\n /**\n * Serialize the encryption key and authentication key pair.\n *\n * @param encKey - The encryption key to serialize.\n * @param authKeyPair - The authentication key pair to serialize.\n * @returns The serialized encryption key and authentication key pair.\n */\n #serializeKeyData(\n encKey: Uint8Array,\n authKeyPair: KeyPair,\n ): {\n toprfEncryptionKey: string;\n toprfAuthKeyPair: string;\n } {\n const b64EncodedEncKey = bytesToBase64(encKey);\n const b64EncodedAuthKeyPair = JSON.stringify({\n sk: bigIntToHex(authKeyPair.sk), // Convert BigInt to hex string\n pk: bytesToBase64(authKeyPair.pk),\n });\n\n return {\n toprfEncryptionKey: b64EncodedEncKey,\n toprfAuthKeyPair: b64EncodedAuthKeyPair,\n };\n }\n\n /**\n * Parse and deserialize the authentication data from the vault.\n *\n * @param data - The decrypted vault data.\n * @returns The parsed authentication data.\n * @throws If the vault data is not valid.\n */\n #parseVaultData(data: unknown): {\n nodeAuthTokens: NodeAuthTokens;\n toprfEncryptionKey: Uint8Array;\n toprfAuthKeyPair: KeyPair;\n } {\n if (typeof data !== 'string') {\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.InvalidVaultData,\n );\n }\n\n let parsedVaultData: unknown;\n try {\n parsedVaultData = JSON.parse(data);\n } catch {\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.InvalidVaultData,\n );\n }\n\n this.#assertIsValidVaultData(parsedVaultData);\n\n const rawToprfEncryptionKey = base64ToBytes(\n parsedVaultData.toprfEncryptionKey,\n );\n const parsedToprfAuthKeyPair = JSON.parse(parsedVaultData.toprfAuthKeyPair);\n const rawToprfAuthKeyPair = {\n sk: BigInt(parsedToprfAuthKeyPair.sk),\n pk: base64ToBytes(parsedToprfAuthKeyPair.pk),\n };\n\n return {\n nodeAuthTokens: parsedVaultData.authTokens,\n toprfEncryptionKey: rawToprfEncryptionKey,\n toprfAuthKeyPair: rawToprfAuthKeyPair,\n };\n }\n\n #assertIsUnlocked(): void {\n if (!this.#isUnlocked) {\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.ControllerLocked,\n );\n }\n }\n\n /**\n * Assert that the provided value contains valid authenticated user information.\n *\n * This method checks that the value is an object containing:\n * - nodeAuthTokens: A non-empty array of authentication tokens\n * - authConnectionId: A string identifier for the OAuth connection\n * - groupedAuthConnectionId: A string identifier for grouped OAuth connections\n * - userId: A string identifier for the authenticated user\n *\n * @param value - The value to validate.\n * @throws {Error} If the value does not contain valid authenticated user information.\n */\n #assertIsAuthenticatedUser(\n value: unknown,\n ): asserts value is AuthenticatedUserDetails {\n if (\n !value ||\n typeof value !== 'object' ||\n !('authConnectionId' in value) ||\n typeof value.authConnectionId !== 'string' ||\n !('userId' in value) ||\n typeof value.userId !== 'string'\n ) {\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.MissingAuthUserInfo,\n );\n }\n\n if (\n !('nodeAuthTokens' in value) ||\n typeof value.nodeAuthTokens !== 'object' ||\n !Array.isArray(value.nodeAuthTokens) ||\n value.nodeAuthTokens.length < 3 // At least 3 auth tokens are required for Threshold OPRF service\n ) {\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.InsufficientAuthToken,\n );\n }\n }\n\n #assertIsSRPBackedUpUser(\n value: unknown,\n ): asserts value is SRPBackedUpUserDetails {\n if (!this.state.authPubKey) {\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.SRPNotBackedUpError,\n );\n }\n }\n\n /**\n * Handle the recovery error and update the recovery error data after executing the given callback.\n *\n * @param recoveryCallback - The callback recovery function to execute.\n * @returns The result of the callback function.\n */\n async #withRecoveryErrorHandler(\n recoveryCallback: () => Promise<RecoverEncryptionKeyResult>,\n ): Promise<RecoverEncryptionKeyResult> {\n const currentRecoveryAttempts =\n this.state.recoveryRatelimitCache?.numberOfAttempts || 0;\n let updatedRecoveryAttempts = currentRecoveryAttempts + 1;\n let updatedRemainingTime =\n this.state.recoveryRatelimitCache?.remainingTime || 0;\n\n try {\n const result = await recoveryCallback();\n\n // reset the ratelimit error data\n updatedRecoveryAttempts = 0;\n updatedRemainingTime = 0;\n\n return result;\n } catch (error) {\n const recoveryError = RecoveryError.getInstance(error, {\n numberOfAttempts: updatedRecoveryAttempts,\n remainingTime: updatedRemainingTime,\n });\n\n if (recoveryError.data?.numberOfAttempts) {\n updatedRecoveryAttempts = recoveryError.data.numberOfAttempts;\n }\n\n if (recoveryError.data?.remainingTime) {\n updatedRemainingTime = recoveryError.data.remainingTime;\n }\n\n throw recoveryError;\n } finally {\n this.update((state) => {\n state.recoveryRatelimitCache = {\n numberOfAttempts: updatedRecoveryAttempts,\n remainingTime: updatedRemainingTime,\n };\n });\n }\n }\n\n /**\n * Assert that the password is in sync with the global password.\n *\n * @param options - The options for asserting the password is in sync.\n * @param options.skipCache - Whether to skip the cache check.\n * @param options.skipLock - Whether to skip the lock acquisition.\n * @throws If the password is outdated.\n */\n async #assertPasswordInSync(options?: {\n skipCache?: boolean;\n skipLock?: boolean;\n }): Promise<void> {\n const isPasswordOutdated = await this.checkIsPasswordOutdated(options);\n if (isPasswordOutdated) {\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.OutdatedPassword,\n );\n }\n }\n\n #resetPasswordOutdatedCache(): void {\n this.update((state) => {\n delete state.passwordOutdatedCache;\n });\n }\n\n /**\n * Check if the provided value is a valid vault data.\n *\n * @param value - The value to check.\n * @throws If the value is not a valid vault data.\n */\n #assertIsValidVaultData(value: unknown): asserts value is VaultData {\n // value is not valid vault data if any of the following conditions are true:\n if (\n !value || // value is not defined\n typeof value !== 'object' || // value is not an object\n !('authTokens' in value) || // authTokens is not defined\n typeof value.authTokens !== 'object' || // authTokens is not an object\n !('toprfEncryptionKey' in value) || // toprfEncryptionKey is not defined\n typeof value.toprfEncryptionKey !== 'string' || // toprfEncryptionKey is not a string\n !('toprfAuthKeyPair' in value) || // toprfAuthKeyPair is not defined\n typeof value.toprfAuthKeyPair !== 'string' // toprfAuthKeyPair is not a string\n ) {\n throw new Error(SeedlessOnboardingControllerErrorMessage.VaultDataError);\n }\n }\n}\n\n/**\n * Assert that the provided password is a valid non-empty string.\n *\n * @param password - The password to check.\n * @throws If the password is not a valid string.\n */\nfunction assertIsValidPassword(password: unknown): asserts password is string {\n if (typeof password !== 'string') {\n throw new Error(SeedlessOnboardingControllerErrorMessage.WrongPasswordType);\n }\n\n if (!password || !password.length) {\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.InvalidEmptyPassword,\n );\n }\n}\n\n/**\n * Lock the given mutex before executing the given function,\n * and release it after the function is resolved or after an\n * error is thrown.\n *\n * @param mutex - The mutex to lock.\n * @param callback - The function to execute while the mutex is locked.\n * @returns The result of the function.\n */\nasync function withLock<Result>(\n mutex: Mutex,\n callback: MutuallyExclusiveCallback<Result>,\n): Promise<Result> {\n const releaseLock = await mutex.acquire();\n\n try {\n return await callback({ releaseLock });\n } finally {\n releaseLock();\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"SeedlessOnboardingController.cjs","sourceRoot":"","sources":["../src/SeedlessOnboardingController.ts"],"names":[],"mappings":"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","sourcesContent":["import { keccak256AndHexify } from '@metamask/auth-network-utils';\nimport type { StateMetadata } from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport type {\n KeyPair,\n NodeAuthTokens,\n RecoverEncryptionKeyResult,\n SEC1EncodedPublicKey,\n} from '@metamask/toprf-secure-backup';\nimport { ToprfSecureBackup } from '@metamask/toprf-secure-backup';\nimport { base64ToBytes, bytesToBase64, bigIntToHex } from '@metamask/utils';\nimport { secp256k1 } from '@noble/curves/secp256k1';\nimport { Mutex } from 'async-mutex';\n\nimport {\n type AuthConnection,\n controllerName,\n PASSWORD_OUTDATED_CACHE_TTL_MS,\n SecretType,\n SeedlessOnboardingControllerErrorMessage,\n Web3AuthNetwork,\n} from './constants';\nimport { PasswordSyncError, RecoveryError } from './errors';\nimport { projectLogger, createModuleLogger } from './logger';\nimport { SecretMetadata } from './SecretMetadata';\nimport type {\n MutuallyExclusiveCallback,\n SeedlessOnboardingControllerMessenger,\n SeedlessOnboardingControllerOptions,\n SeedlessOnboardingControllerState,\n VaultData,\n AuthenticatedUserDetails,\n SocialBackupsMetadata,\n SRPBackedUpUserDetails,\n VaultEncryptor,\n} from './types';\n\nconst log = createModuleLogger(projectLogger, controllerName);\n\n/**\n * Get the default state for the Seedless Onboarding Controller.\n *\n * @returns The default state for the Seedless Onboarding Controller.\n */\nexport function getDefaultSeedlessOnboardingControllerState(): SeedlessOnboardingControllerState {\n return {\n socialBackupsMetadata: [],\n };\n}\n\n/**\n * Seedless Onboarding Controller State Metadata.\n *\n * This allows us to choose if fields of the state should be persisted or not\n * using the `persist` flag; and if they can be sent to Sentry or not, using\n * the `anonymous` flag.\n */\nconst seedlessOnboardingMetadata: StateMetadata<SeedlessOnboardingControllerState> =\n {\n vault: {\n persist: true,\n anonymous: false,\n },\n socialBackupsMetadata: {\n persist: true,\n anonymous: true,\n },\n nodeAuthTokens: {\n persist: true,\n anonymous: true,\n },\n authConnection: {\n persist: true,\n anonymous: true,\n },\n authConnectionId: {\n persist: true,\n anonymous: true,\n },\n groupedAuthConnectionId: {\n persist: true,\n anonymous: true,\n },\n userId: {\n persist: true,\n anonymous: true,\n },\n socialLoginEmail: {\n persist: true,\n anonymous: true,\n },\n vaultEncryptionKey: {\n persist: false,\n anonymous: true,\n },\n vaultEncryptionSalt: {\n persist: false,\n anonymous: true,\n },\n authPubKey: {\n persist: true,\n anonymous: true,\n },\n passwordOutdatedCache: {\n persist: true,\n anonymous: true,\n },\n recoveryRatelimitCache: {\n persist: true,\n anonymous: true,\n },\n };\n\nexport class SeedlessOnboardingController<\n EncryptionKey,\n SupportedKeyDerivationOptions,\n> extends BaseController<\n typeof controllerName,\n SeedlessOnboardingControllerState,\n SeedlessOnboardingControllerMessenger\n> {\n readonly #vaultEncryptor: VaultEncryptor<\n EncryptionKey,\n SupportedKeyDerivationOptions\n >;\n\n readonly #controllerOperationMutex = new Mutex();\n\n readonly #vaultOperationMutex = new Mutex();\n\n readonly toprfClient: ToprfSecureBackup;\n\n /**\n * Controller lock state.\n *\n * The controller lock is synchronized with the keyring lock.\n */\n #isUnlocked = false;\n\n /**\n * Creates a new SeedlessOnboardingController instance.\n *\n * @param options - The options for the SeedlessOnboardingController.\n * @param options.messenger - A restricted messenger.\n * @param options.state - Initial state to set on this controller.\n * @param options.encryptor - An optional encryptor to use for encrypting and decrypting seedless onboarding vault.\n * @param options.toprfKeyDeriver - An optional key derivation interface for the TOPRF client.\n * @param options.network - The network to be used for the Seedless Onboarding flow.\n */\n constructor({\n messenger,\n state,\n encryptor,\n toprfKeyDeriver,\n network = Web3AuthNetwork.Mainnet,\n }: SeedlessOnboardingControllerOptions<\n EncryptionKey,\n SupportedKeyDerivationOptions\n >) {\n super({\n name: controllerName,\n metadata: seedlessOnboardingMetadata,\n state: {\n ...getDefaultSeedlessOnboardingControllerState(),\n ...state,\n },\n messenger,\n });\n\n this.#vaultEncryptor = encryptor;\n this.toprfClient = new ToprfSecureBackup({\n network,\n keyDeriver: toprfKeyDeriver,\n });\n\n // setup subscriptions to the keyring lock event\n // when the keyring is locked (wallet is locked), the controller will be cleared of its credentials\n this.messagingSystem.subscribe('KeyringController:lock', () => {\n this.setLocked();\n });\n this.messagingSystem.subscribe('KeyringController:unlock', () => {\n this.#setUnlocked();\n });\n }\n\n /**\n * Authenticate OAuth user using the seedless onboarding flow\n * and determine if the user is already registered or not.\n *\n * @param params - The parameters for authenticate OAuth user.\n * @param params.idTokens - The ID token(s) issued by OAuth verification service. Currently this array only contains a single idToken which is verified by all the nodes, in future we are considering to issue a unique idToken for each node.\n * @param params.authConnection - The social login provider.\n * @param params.authConnectionId - OAuth authConnectionId from dashboard\n * @param params.userId - user email or id from Social login\n * @param params.groupedAuthConnectionId - Optional grouped authConnectionId to be used for the authenticate request.\n * @param params.socialLoginEmail - The user email from Social login.\n * You can pass this to use aggregate multiple OAuth connections. Useful when you want user to have same account while using different OAuth connections.\n * @returns A promise that resolves to the authentication result.\n */\n async authenticate(params: {\n idTokens: string[];\n authConnection: AuthConnection;\n authConnectionId: string;\n userId: string;\n groupedAuthConnectionId?: string;\n socialLoginEmail?: string;\n }) {\n return await this.#withControllerLock(async () => {\n try {\n const {\n idTokens,\n authConnectionId,\n groupedAuthConnectionId,\n userId,\n authConnection,\n socialLoginEmail,\n } = params;\n\n const authenticationResult = await this.toprfClient.authenticate({\n authConnectionId,\n userId,\n idTokens,\n groupedAuthConnectionId,\n });\n // update the state with the authenticated user info\n this.update((state) => {\n state.nodeAuthTokens = authenticationResult.nodeAuthTokens;\n state.authConnectionId = authConnectionId;\n state.groupedAuthConnectionId = groupedAuthConnectionId;\n state.userId = userId;\n state.authConnection = authConnection;\n state.socialLoginEmail = socialLoginEmail;\n });\n return authenticationResult;\n } catch (error) {\n log('Error authenticating user', error);\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.AuthenticationError,\n );\n }\n });\n }\n\n /**\n * Create a new TOPRF encryption key using given password and backups the provided seed phrase.\n *\n * @param password - The password used to create new wallet and seedphrase\n * @param seedPhrase - The seed phrase to backup\n * @param keyringId - The keyring id of the backup seed phrase\n * @returns A promise that resolves to the encrypted seed phrase and the encryption key.\n */\n async createToprfKeyAndBackupSeedPhrase(\n password: string,\n seedPhrase: Uint8Array,\n keyringId: string,\n ): Promise<void> {\n // to make sure that fail fast,\n // assert that the user is authenticated before creating the TOPRF key and backing up the seed phrase\n this.#assertIsAuthenticatedUser(this.state);\n\n return await this.#withControllerLock(async () => {\n // locally evaluate the encryption key from the password\n const { encKey, authKeyPair, oprfKey } =\n await this.toprfClient.createLocalKey({\n password,\n });\n\n // encrypt and store the seed phrase backup\n await this.#encryptAndStoreSecretData({\n data: seedPhrase,\n type: SecretType.Mnemonic,\n encKey,\n authKeyPair,\n options: {\n keyringId,\n },\n });\n\n // store/persist the encryption key shares\n // We store the seed phrase metadata in the metadata store first. If this operation fails,\n // we avoid persisting the encryption key shares to prevent a situation where a user appears\n // to have an account but with no associated data.\n await this.#persistOprfKey(oprfKey, authKeyPair.pk);\n // create a new vault with the resulting authentication data\n await this.#createNewVaultWithAuthData({\n password,\n rawToprfEncryptionKey: encKey,\n rawToprfAuthKeyPair: authKeyPair,\n });\n this.#persistAuthPubKey({\n authPubKey: authKeyPair.pk,\n });\n });\n }\n\n /**\n * encrypt and add a new secret data to the metadata store.\n *\n * @param data - The data to add.\n * @param type - The type of the secret data.\n * @param options - Optional options object, which includes optional data to be added to the metadata store.\n * @param options.keyringId - The keyring id of the backup keyring (SRP).\n * @returns A promise that resolves to the success of the operation.\n */\n async addNewSecretData(\n data: Uint8Array,\n type: SecretType,\n options?: {\n keyringId?: string;\n },\n ): Promise<void> {\n return await this.#withControllerLock(async () => {\n this.#assertIsUnlocked();\n\n await this.#assertPasswordInSync({\n skipCache: true,\n skipLock: true, // skip lock since we already have the lock\n });\n\n // verify the password and unlock the vault\n const { toprfEncryptionKey, toprfAuthKeyPair } =\n await this.#unlockVaultAndGetBackupEncKey();\n\n // encrypt and store the seed phrase backup\n await this.#encryptAndStoreSecretData({\n data,\n type,\n encKey: toprfEncryptionKey,\n authKeyPair: toprfAuthKeyPair,\n options,\n });\n });\n }\n\n /**\n * Fetches all encrypted secret data and metadata for user's account from the metadata store.\n *\n * Decrypts the secret data and returns the decrypted secret data using the recovered encryption key from the password.\n *\n * @param password - The optional password used to create new wallet and seedphrase. If not provided, `cached Encryption Key` will be used.\n * @returns A promise that resolves to the secret data.\n */\n async fetchAllSecretData(\n password?: string,\n ): Promise<Record<SecretType, Uint8Array[]>> {\n // assert that the user is authenticated before fetching the seed phrases\n this.#assertIsAuthenticatedUser(this.state);\n\n return await this.#withControllerLock(async () => {\n let encKey: Uint8Array;\n let authKeyPair: KeyPair;\n\n if (password) {\n const recoverEncKeyResult = await this.#recoverEncKey(password);\n encKey = recoverEncKeyResult.encKey;\n authKeyPair = recoverEncKeyResult.authKeyPair;\n } else {\n this.#assertIsUnlocked();\n // verify the password and unlock the vault\n const keysFromVault = await this.#unlockVaultAndGetBackupEncKey();\n encKey = keysFromVault.toprfEncryptionKey;\n authKeyPair = keysFromVault.toprfAuthKeyPair;\n }\n\n try {\n const secretData = await this.toprfClient.fetchAllSecretDataItems({\n decKey: encKey,\n authKeyPair,\n });\n\n if (secretData?.length > 0 && password) {\n // if password is provided, we need to create a new vault with the auth data. (supposedly the user is trying to rehydrate the wallet)\n await this.#createNewVaultWithAuthData({\n password,\n rawToprfEncryptionKey: encKey,\n rawToprfAuthKeyPair: authKeyPair,\n });\n\n this.#persistAuthPubKey({\n authPubKey: authKeyPair.pk,\n });\n }\n\n const result: Record<SecretType, Uint8Array[]> = {\n mnemonic: [],\n privateKey: [],\n };\n const secrets =\n SecretMetadata.parseSecretsFromMetadataStore(secretData);\n\n secrets.forEach((secret) => {\n result[secret.type].push(secret.data);\n });\n\n return result;\n } catch (error) {\n log('Error fetching seed phrase metadata', error);\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.FailedToFetchSeedPhraseMetadata,\n );\n }\n });\n }\n\n /**\n * Update the password of the seedless onboarding flow.\n *\n * Changing password will also update the encryption key, metadata store and the vault with new encrypted values.\n *\n * @param newPassword - The new password to update.\n * @param oldPassword - The old password to verify.\n * @returns A promise that resolves to the success of the operation.\n */\n async changePassword(newPassword: string, oldPassword: string) {\n return await this.#withControllerLock(async () => {\n this.#assertIsUnlocked();\n // verify the old password of the encrypted vault\n await this.verifyVaultPassword(oldPassword, {\n skipLock: true, // skip lock since we already have the lock\n });\n await this.#assertPasswordInSync({\n skipCache: true,\n skipLock: true, // skip lock since we already have the lock\n });\n\n try {\n // update the encryption key with new password and update the Metadata Store\n const { encKey: newEncKey, authKeyPair: newAuthKeyPair } =\n await this.#changeEncryptionKey(newPassword, oldPassword);\n\n // update and encrypt the vault with new password\n await this.#createNewVaultWithAuthData({\n password: newPassword,\n rawToprfEncryptionKey: newEncKey,\n rawToprfAuthKeyPair: newAuthKeyPair,\n });\n\n this.#persistAuthPubKey({\n authPubKey: newAuthKeyPair.pk,\n });\n this.#resetPasswordOutdatedCache();\n } catch (error) {\n log('Error changing password', error);\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.FailedToChangePassword,\n );\n }\n });\n }\n\n /**\n * Update the backup metadata state for the given seed phrase.\n *\n * @param data - The data to backup, can be a single backup or array of backups.\n * @param data.keyringId - The keyring id associated with the backup seed phrase.\n * @param data.seedPhrase - The seed phrase to update the backup metadata state.\n */\n updateBackupMetadataState(\n data:\n | {\n keyringId: string;\n seedPhrase: Uint8Array;\n }\n | {\n keyringId: string;\n seedPhrase: Uint8Array;\n }[],\n ) {\n this.#assertIsUnlocked();\n\n this.#filterDupesAndUpdateSocialBackupsMetadata(data);\n }\n\n /**\n * Verify the password validity by decrypting the vault.\n *\n * @param password - The password to verify.\n * @param options - Optional options object.\n * @param options.skipLock - Whether to skip the lock acquisition.\n * @returns A promise that resolves to the success of the operation.\n * @throws {Error} If the password is invalid or the vault is not initialized.\n */\n async verifyVaultPassword(\n password: string,\n options?: {\n skipLock?: boolean;\n },\n ): Promise<void> {\n const doVerify = async () => {\n if (!this.state.vault) {\n throw new Error(SeedlessOnboardingControllerErrorMessage.VaultError);\n }\n await this.#vaultEncryptor.decrypt(password, this.state.vault);\n };\n return options?.skipLock\n ? await doVerify()\n : await this.#withControllerLock(doVerify);\n }\n\n /**\n * Get the hash of the seed phrase backup for the given seed phrase, from the state.\n *\n * If the given seed phrase is not backed up and not found in the state, it will return `undefined`.\n *\n * @param seedPhrase - The seed phrase to get the hash of.\n * @returns A promise that resolves to the hash of the seed phrase backup.\n */\n getSeedPhraseBackupHash(\n seedPhrase: Uint8Array,\n ): SocialBackupsMetadata | undefined {\n const seedPhraseHash = keccak256AndHexify(seedPhrase);\n return this.state.socialBackupsMetadata.find(\n (backup) => backup.hash === seedPhraseHash,\n );\n }\n\n /**\n * Submit the password to the controller, verify the password validity and unlock the controller.\n *\n * This method will be used especially when user rehydrate/unlock the wallet.\n * The provided password will be verified against the encrypted vault, encryption key will be derived and saved in the controller state.\n *\n * This operation is useful when user performs some actions that requires the user password/encryption key. e.g. add new srp backup\n *\n * @param password - The password to submit.\n * @returns A promise that resolves to the success of the operation.\n */\n async submitPassword(password: string): Promise<void> {\n return await this.#withControllerLock(async () => {\n await this.#unlockVaultAndGetBackupEncKey(password);\n this.#setUnlocked();\n });\n }\n\n /**\n * Set the controller to locked state, and deallocate the secrets (vault encryption key and salt).\n *\n * When the controller is locked, the user will not be able to perform any operations on the controller/vault.\n */\n setLocked() {\n this.update((state) => {\n delete state.vaultEncryptionKey;\n delete state.vaultEncryptionSalt;\n });\n\n this.#isUnlocked = false;\n }\n\n /**\n * Sync the latest global password to the controller.\n * reset vault with latest globalPassword,\n * persist the latest global password authPubKey\n *\n * @param params - The parameters for syncing the latest global password.\n * @param params.oldPassword - The old password to verify.\n * @param params.globalPassword - The latest global password.\n * @returns A promise that resolves to the success of the operation.\n */\n async syncLatestGlobalPassword({\n oldPassword,\n globalPassword,\n }: {\n oldPassword: string;\n globalPassword: string;\n }) {\n return await this.#withControllerLock(async () => {\n // verify correct old password\n await this.verifyVaultPassword(oldPassword, {\n skipLock: true, // skip lock since we already have the lock\n });\n // update vault with latest globalPassword\n const { encKey, authKeyPair } = await this.#recoverEncKey(globalPassword);\n // update and encrypt the vault with new password\n await this.#createNewVaultWithAuthData({\n password: globalPassword,\n rawToprfEncryptionKey: encKey,\n rawToprfAuthKeyPair: authKeyPair,\n });\n // persist the latest global password authPubKey\n this.#persistAuthPubKey({\n authPubKey: authKeyPair.pk,\n });\n this.#resetPasswordOutdatedCache();\n });\n }\n\n /**\n * @description Fetch the password corresponding to the current authPubKey in state (current device password which is already out of sync with the current global password).\n * then we use this recovered old password to unlock the vault and set the password to the new global password.\n *\n * @param params - The parameters for fetching the password.\n * @param params.globalPassword - The latest global password.\n * @returns A promise that resolves to the password corresponding to the current authPubKey in state.\n */\n async recoverCurrentDevicePassword({\n globalPassword,\n }: {\n globalPassword: string;\n }): Promise<{ password: string }> {\n return await this.#withControllerLock(async () => {\n const currentDeviceAuthPubKey = this.#recoverAuthPubKey();\n const { password: currentDevicePassword } = await this.#recoverPassword({\n targetPwPubKey: currentDeviceAuthPubKey,\n globalPassword,\n });\n return {\n password: currentDevicePassword,\n };\n });\n }\n\n /**\n * @description Fetch the password corresponding to the targetPwPubKey.\n *\n * @param params - The parameters for fetching the password.\n * @param params.targetPwPubKey - The target public key of the password to recover.\n * @param params.globalPassword - The latest global password.\n * @returns A promise that resolves to the password corresponding to the current authPubKey in state.\n */\n async #recoverPassword({\n targetPwPubKey,\n globalPassword,\n }: {\n targetPwPubKey: SEC1EncodedPublicKey;\n globalPassword: string;\n }): Promise<{ password: string }> {\n const { encKey: latestPwEncKey, authKeyPair: latestPwAuthKeyPair } =\n await this.#recoverEncKey(globalPassword);\n\n try {\n const res = await this.toprfClient.recoverPassword({\n targetPwPubKey,\n curEncKey: latestPwEncKey,\n curAuthKeyPair: latestPwAuthKeyPair,\n });\n return res;\n } catch (error) {\n throw PasswordSyncError.getInstance(error);\n }\n }\n\n /**\n * @description Check if the current password is outdated compare to the global password.\n *\n * @param options - Optional options object.\n * @param options.skipCache - If true, bypass the cache and force a fresh check.\n * @param options.skipLock - Whether to skip the lock acquisition.\n * @returns A promise that resolves to true if the password is outdated, false otherwise.\n */\n async checkIsPasswordOutdated(options?: {\n skipCache?: boolean;\n skipLock?: boolean;\n }): Promise<boolean> {\n // cache result to reduce load on infra\n // Check cache first unless skipCache is true\n if (!options?.skipCache) {\n const { passwordOutdatedCache } = this.state;\n const now = Date.now();\n const isCacheValid =\n passwordOutdatedCache &&\n now - passwordOutdatedCache.timestamp < PASSWORD_OUTDATED_CACHE_TTL_MS;\n\n if (isCacheValid) {\n return passwordOutdatedCache.isExpiredPwd;\n }\n }\n\n const doCheck = async () => {\n this.#assertIsAuthenticatedUser(this.state);\n const {\n nodeAuthTokens,\n authConnectionId,\n groupedAuthConnectionId,\n userId,\n } = this.state;\n\n const currentDeviceAuthPubKey = this.#recoverAuthPubKey();\n\n const { authPubKey: globalAuthPubKey } =\n await this.toprfClient.fetchAuthPubKey({\n nodeAuthTokens,\n authConnectionId,\n groupedAuthConnectionId,\n userId,\n });\n\n // use noble lib to deserialize and compare curve point\n const isExpiredPwd = !secp256k1.ProjectivePoint.fromHex(\n currentDeviceAuthPubKey,\n ).equals(secp256k1.ProjectivePoint.fromHex(globalAuthPubKey));\n // Cache the result in state\n this.update((state) => {\n state.passwordOutdatedCache = { isExpiredPwd, timestamp: Date.now() };\n });\n return isExpiredPwd;\n };\n\n return options?.skipLock\n ? await doCheck()\n : await this.#withControllerLock(doCheck);\n }\n\n #setUnlocked(): void {\n this.#isUnlocked = true;\n }\n\n /**\n * Clears the current state of the SeedlessOnboardingController.\n */\n clearState() {\n const defaultState = getDefaultSeedlessOnboardingControllerState();\n this.update(() => {\n return defaultState;\n });\n }\n\n /**\n * Persist the encryption key for the seedless onboarding flow.\n *\n * @param oprfKey - The OPRF key to be splited and persisted.\n * @param authPubKey - The authentication public key.\n * @returns A promise that resolves to the success of the operation.\n */\n async #persistOprfKey(oprfKey: bigint, authPubKey: SEC1EncodedPublicKey) {\n this.#assertIsAuthenticatedUser(this.state);\n const { authConnectionId, groupedAuthConnectionId, userId } = this.state;\n\n try {\n await this.toprfClient.persistLocalKey({\n nodeAuthTokens: this.state.nodeAuthTokens,\n authConnectionId,\n groupedAuthConnectionId,\n userId,\n oprfKey,\n authPubKey,\n });\n } catch (error) {\n log('Error persisting local encryption key', error);\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.FailedToPersistOprfKey,\n );\n }\n }\n\n /**\n * Persist the authentication public key for the seedless onboarding flow.\n * convert to suitable format before persisting.\n *\n * @param params - The parameters for persisting the authentication public key.\n * @param params.authPubKey - The authentication public key to be persisted.\n */\n #persistAuthPubKey(params: { authPubKey: SEC1EncodedPublicKey }): void {\n this.update((state) => {\n state.authPubKey = bytesToBase64(params.authPubKey);\n });\n }\n\n /**\n * Recover the authentication public key from the state.\n * convert to pubkey format before recovering.\n *\n * @returns The authentication public key.\n */\n #recoverAuthPubKey(): SEC1EncodedPublicKey {\n this.#assertIsSRPBackedUpUser(this.state);\n const { authPubKey } = this.state;\n\n return base64ToBytes(authPubKey);\n }\n\n /**\n * Recover the encryption key from password.\n *\n * @param password - The password used to derive/recover the encryption key.\n * @returns A promise that resolves to the encryption key and authentication key pair.\n * @throws RecoveryError - If failed to recover the encryption key.\n */\n async #recoverEncKey(password: string) {\n return this.#withRecoveryErrorHandler(async () => {\n this.#assertIsAuthenticatedUser(this.state);\n\n const { authConnectionId, groupedAuthConnectionId, userId } = this.state;\n\n const recoverEncKeyResult = await this.toprfClient.recoverEncKey({\n nodeAuthTokens: this.state.nodeAuthTokens,\n password,\n authConnectionId,\n groupedAuthConnectionId,\n userId,\n });\n return recoverEncKeyResult;\n });\n }\n\n /**\n * Update the encryption key with new password and update the Metadata Store with new encryption key.\n *\n * @param newPassword - The new password to update.\n * @param oldPassword - The old password to verify.\n * @returns A promise that resolves to new encryption key and authentication key pair.\n */\n async #changeEncryptionKey(newPassword: string, oldPassword: string) {\n this.#assertIsAuthenticatedUser(this.state);\n const { authConnectionId, groupedAuthConnectionId, userId } = this.state;\n\n const {\n encKey,\n authKeyPair,\n keyShareIndex: newKeyShareIndex,\n } = await this.#recoverEncKey(oldPassword);\n\n return await this.toprfClient.changeEncKey({\n nodeAuthTokens: this.state.nodeAuthTokens,\n authConnectionId,\n groupedAuthConnectionId,\n userId,\n oldEncKey: encKey,\n oldAuthKeyPair: authKeyPair,\n newKeyShareIndex,\n oldPassword,\n newPassword,\n });\n }\n\n /**\n * Encrypt and store the seed phrase backup in the metadata store.\n *\n * @param params - The parameters for encrypting and storing the seed phrase backup.\n * @param params.data - The seed phrase to store.\n * @param params.type - The type of the secret data.\n * @param params.encKey - The encryption key to store.\n * @param params.authKeyPair - The authentication key pair to store.\n * @param params.options - Optional options object, which includes optional data to be added to the metadata store.\n * @param params.options.keyringId - The keyring id of the backup keyring (SRP).\n *\n * @returns A promise that resolves to the success of the operation.\n */\n async #encryptAndStoreSecretData(params: {\n data: Uint8Array;\n type: SecretType;\n encKey: Uint8Array;\n authKeyPair: KeyPair;\n options?: {\n keyringId?: string;\n };\n }): Promise<void> {\n const { options, data, encKey, authKeyPair, type } = params;\n\n const secretMetadata = new SecretMetadata(data, {\n type,\n });\n const secretData = secretMetadata.toBytes();\n\n const keyringId = options?.keyringId as string;\n if (type === SecretType.Mnemonic && !keyringId) {\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.MissingKeyringId,\n );\n }\n\n try {\n if (type === SecretType.Mnemonic) {\n await this.#withPersistedSeedPhraseBackupsState(async () => {\n await this.toprfClient.addSecretDataItem({\n encKey,\n secretData,\n authKeyPair,\n });\n return {\n keyringId,\n seedPhrase: data,\n };\n });\n return;\n }\n\n await this.toprfClient.addSecretDataItem({\n encKey,\n secretData,\n authKeyPair,\n });\n } catch (error) {\n log('Error encrypting and storing seed phrase backup', error);\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.FailedToEncryptAndStoreSeedPhraseBackup,\n );\n }\n }\n\n /**\n * Unlocks the encrypted vault using the provided password and returns the decrypted vault data.\n * This method ensures thread-safety by using a mutex lock when accessing the vault.\n *\n * @param password - The optional password to unlock the vault.\n * @returns A promise that resolves to an object containing:\n * - nodeAuthTokens: Authentication tokens to communicate with the TOPRF service\n * - toprfEncryptionKey: The decrypted TOPRF encryption key\n * - toprfAuthKeyPair: The decrypted TOPRF authentication key pair\n * @throws {Error} If:\n * - The password is invalid or empty\n * - The vault is not initialized\n * - The password is incorrect (from encryptor.decrypt)\n * - The decrypted vault data is malformed\n */\n async #unlockVaultAndGetBackupEncKey(password?: string): Promise<{\n nodeAuthTokens: NodeAuthTokens;\n toprfEncryptionKey: Uint8Array;\n toprfAuthKeyPair: KeyPair;\n }> {\n return this.#withVaultLock(async () => {\n const {\n vault: encryptedVault,\n vaultEncryptionKey,\n vaultEncryptionSalt,\n } = this.state;\n\n if (!encryptedVault) {\n throw new Error(SeedlessOnboardingControllerErrorMessage.VaultError);\n }\n\n if (!vaultEncryptionKey && !password) {\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.MissingCredentials,\n );\n }\n\n let decryptedVaultData: unknown;\n const updatedState: Partial<SeedlessOnboardingControllerState> = {};\n\n if (password) {\n assertIsValidPassword(password);\n // Note that vault decryption using the password is a very costly operation as it involves deriving the encryption key\n // from the password using an intentionally slow key derivation function.\n // We should make sure that we only call it very intentionally.\n const result = await this.#vaultEncryptor.decryptWithDetail(\n password,\n encryptedVault,\n );\n decryptedVaultData = result.vault;\n updatedState.vaultEncryptionKey = result.exportedKeyString;\n updatedState.vaultEncryptionSalt = result.salt;\n } else {\n const parsedEncryptedVault = JSON.parse(encryptedVault);\n\n if (vaultEncryptionSalt !== parsedEncryptedVault.salt) {\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.ExpiredCredentials,\n );\n }\n\n if (typeof vaultEncryptionKey !== 'string') {\n throw new TypeError(\n SeedlessOnboardingControllerErrorMessage.WrongPasswordType,\n );\n }\n\n const key = await this.#vaultEncryptor.importKey(vaultEncryptionKey);\n decryptedVaultData = await this.#vaultEncryptor.decryptWithKey(\n key,\n parsedEncryptedVault,\n );\n updatedState.vaultEncryptionKey = vaultEncryptionKey;\n updatedState.vaultEncryptionSalt = vaultEncryptionSalt;\n }\n\n const { nodeAuthTokens, toprfEncryptionKey, toprfAuthKeyPair } =\n this.#parseVaultData(decryptedVaultData);\n\n // update the state with the restored nodeAuthTokens\n this.update((state) => {\n state.nodeAuthTokens = nodeAuthTokens;\n state.vaultEncryptionKey = updatedState.vaultEncryptionKey;\n state.vaultEncryptionSalt = updatedState.vaultEncryptionSalt;\n });\n\n return { nodeAuthTokens, toprfEncryptionKey, toprfAuthKeyPair };\n });\n }\n\n /**\n * Executes a callback function that creates or restores seed phrases and persists their hashes in the controller state.\n *\n * This method:\n * 1. Executes the provided callback to create/restore seed phrases\n * 2. Generates keccak256 hashes of the seed phrases\n * 3. Merges new hashes with existing ones in the state, ensuring uniqueness\n * 4. Updates the controller state with the combined hashes\n *\n * This is a wrapper method that should be used around any operation that creates\n * or restores seed phrases to ensure their hashes are properly tracked.\n *\n * @param createSeedPhraseBackupCallback - function that returns either a single seed phrase\n * or an array of seed phrases as Uint8Array(s)\n * @returns The original seed phrase(s) returned by the callback\n * @throws Rethrows any errors from the callback with additional logging\n */\n async #withPersistedSeedPhraseBackupsState(\n createSeedPhraseBackupCallback: () => Promise<{\n keyringId: string;\n seedPhrase: Uint8Array;\n }>,\n ): Promise<{\n keyringId: string;\n seedPhrase: Uint8Array;\n }> {\n try {\n const newBackup = await createSeedPhraseBackupCallback();\n\n this.#filterDupesAndUpdateSocialBackupsMetadata(newBackup);\n\n return newBackup;\n } catch (error) {\n log('Error persisting seed phrase backups', error);\n throw error;\n }\n }\n\n /**\n * Updates the social backups metadata state by adding new unique seed phrase backups.\n * This method ensures no duplicate backups are stored by checking the hash of each seed phrase.\n *\n * @param data - The backup data to add to the state\n * @param data.id - The identifier for the backup\n * @param data.seedPhrase - The seed phrase to backup as a Uint8Array\n */\n #filterDupesAndUpdateSocialBackupsMetadata(\n data:\n | {\n keyringId: string;\n seedPhrase: Uint8Array;\n }\n | {\n keyringId: string;\n seedPhrase: Uint8Array;\n }[],\n ) {\n const currentBackupsMetadata = this.state.socialBackupsMetadata;\n\n const newBackupsMetadata = Array.isArray(data) ? data : [data];\n const filteredNewBackupsMetadata: SocialBackupsMetadata[] = [];\n\n // filter out the backed up metadata that already exists in the state\n // to prevent duplicates\n newBackupsMetadata.forEach((item) => {\n const { keyringId, seedPhrase } = item;\n const backupHash = keccak256AndHexify(seedPhrase);\n\n const backupStateAlreadyExisted = currentBackupsMetadata.some(\n (backup) => backup.hash === backupHash,\n );\n\n if (!backupStateAlreadyExisted) {\n filteredNewBackupsMetadata.push({\n id: keyringId,\n hash: backupHash,\n });\n }\n });\n\n if (filteredNewBackupsMetadata.length > 0) {\n this.update((state) => {\n state.socialBackupsMetadata = [\n ...state.socialBackupsMetadata,\n ...filteredNewBackupsMetadata,\n ];\n });\n }\n }\n\n /**\n * Create a new vault with the given authentication data.\n *\n * Serialize the authentication and key data which will be stored in the vault.\n *\n * @param params - The parameters for creating a new vault.\n * @param params.password - The password to encrypt the vault.\n * @param params.rawToprfEncryptionKey - The encryption key to encrypt the vault.\n * @param params.rawToprfAuthKeyPair - The authentication key pair to encrypt the vault.\n */\n async #createNewVaultWithAuthData({\n password,\n rawToprfEncryptionKey,\n rawToprfAuthKeyPair,\n }: {\n password: string;\n rawToprfEncryptionKey: Uint8Array;\n rawToprfAuthKeyPair: KeyPair;\n }): Promise<void> {\n this.#assertIsAuthenticatedUser(this.state);\n this.#setUnlocked();\n\n const { toprfEncryptionKey, toprfAuthKeyPair } = this.#serializeKeyData(\n rawToprfEncryptionKey,\n rawToprfAuthKeyPair,\n );\n\n const serializedVaultData = JSON.stringify({\n authTokens: this.state.nodeAuthTokens,\n toprfEncryptionKey,\n toprfAuthKeyPair,\n });\n\n await this.#updateVault({\n password,\n serializedVaultData,\n });\n }\n\n /**\n * Encrypt and update the vault with the given authentication data.\n *\n * @param params - The parameters for updating the vault.\n * @param params.password - The password to encrypt the vault.\n * @param params.serializedVaultData - The serialized authentication data to update the vault with.\n * @returns A promise that resolves to the updated vault.\n */\n async #updateVault({\n password,\n serializedVaultData,\n }: {\n password: string;\n serializedVaultData: string;\n }): Promise<void> {\n await this.#withVaultLock(async () => {\n assertIsValidPassword(password);\n\n // Note that vault encryption using the password is a very costly operation as it involves deriving the encryption key\n // from the password using an intentionally slow key derivation function.\n // We should make sure that we only call it very intentionally.\n const { vault, exportedKeyString } =\n await this.#vaultEncryptor.encryptWithDetail(\n password,\n serializedVaultData,\n );\n\n this.update((state) => {\n state.vault = vault;\n state.vaultEncryptionKey = exportedKeyString;\n state.vaultEncryptionSalt = JSON.parse(vault).salt;\n });\n });\n }\n\n /**\n * Lock the controller mutex before executing the given function,\n * and release it after the function is resolved or after an\n * error is thrown.\n *\n * This wrapper ensures that each mutable operation that interacts with the\n * controller and that changes its state is executed in a mutually exclusive way,\n * preventing unsafe concurrent access that could lead to unpredictable behavior.\n *\n * @param callback - The function to execute while the controller mutex is locked.\n * @returns The result of the function.\n */\n async #withControllerLock<Result>(\n callback: MutuallyExclusiveCallback<Result>,\n ): Promise<Result> {\n return await withLock(this.#controllerOperationMutex, callback);\n }\n\n /**\n * Lock the vault mutex before executing the given function,\n * and release it after the function is resolved or after an\n * error is thrown.\n *\n * This ensures that each operation that interacts with the vault\n * is executed in a mutually exclusive way.\n *\n * @param callback - The function to execute while the vault mutex is locked.\n * @returns The result of the function.\n */\n async #withVaultLock<Result>(\n callback: MutuallyExclusiveCallback<Result>,\n ): Promise<Result> {\n return await withLock(this.#vaultOperationMutex, callback);\n }\n\n /**\n * Serialize the encryption key and authentication key pair.\n *\n * @param encKey - The encryption key to serialize.\n * @param authKeyPair - The authentication key pair to serialize.\n * @returns The serialized encryption key and authentication key pair.\n */\n #serializeKeyData(\n encKey: Uint8Array,\n authKeyPair: KeyPair,\n ): {\n toprfEncryptionKey: string;\n toprfAuthKeyPair: string;\n } {\n const b64EncodedEncKey = bytesToBase64(encKey);\n const b64EncodedAuthKeyPair = JSON.stringify({\n sk: bigIntToHex(authKeyPair.sk), // Convert BigInt to hex string\n pk: bytesToBase64(authKeyPair.pk),\n });\n\n return {\n toprfEncryptionKey: b64EncodedEncKey,\n toprfAuthKeyPair: b64EncodedAuthKeyPair,\n };\n }\n\n /**\n * Parse and deserialize the authentication data from the vault.\n *\n * @param data - The decrypted vault data.\n * @returns The parsed authentication data.\n * @throws If the vault data is not valid.\n */\n #parseVaultData(data: unknown): {\n nodeAuthTokens: NodeAuthTokens;\n toprfEncryptionKey: Uint8Array;\n toprfAuthKeyPair: KeyPair;\n } {\n if (typeof data !== 'string') {\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.InvalidVaultData,\n );\n }\n\n let parsedVaultData: unknown;\n try {\n parsedVaultData = JSON.parse(data);\n } catch {\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.InvalidVaultData,\n );\n }\n\n this.#assertIsValidVaultData(parsedVaultData);\n\n const rawToprfEncryptionKey = base64ToBytes(\n parsedVaultData.toprfEncryptionKey,\n );\n const parsedToprfAuthKeyPair = JSON.parse(parsedVaultData.toprfAuthKeyPair);\n const rawToprfAuthKeyPair = {\n sk: BigInt(parsedToprfAuthKeyPair.sk),\n pk: base64ToBytes(parsedToprfAuthKeyPair.pk),\n };\n\n return {\n nodeAuthTokens: parsedVaultData.authTokens,\n toprfEncryptionKey: rawToprfEncryptionKey,\n toprfAuthKeyPair: rawToprfAuthKeyPair,\n };\n }\n\n #assertIsUnlocked(): void {\n if (!this.#isUnlocked) {\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.ControllerLocked,\n );\n }\n }\n\n /**\n * Assert that the provided value contains valid authenticated user information.\n *\n * This method checks that the value is an object containing:\n * - nodeAuthTokens: A non-empty array of authentication tokens\n * - authConnectionId: A string identifier for the OAuth connection\n * - groupedAuthConnectionId: A string identifier for grouped OAuth connections\n * - userId: A string identifier for the authenticated user\n *\n * @param value - The value to validate.\n * @throws {Error} If the value does not contain valid authenticated user information.\n */\n #assertIsAuthenticatedUser(\n value: unknown,\n ): asserts value is AuthenticatedUserDetails {\n if (\n !value ||\n typeof value !== 'object' ||\n !('authConnectionId' in value) ||\n typeof value.authConnectionId !== 'string' ||\n !('userId' in value) ||\n typeof value.userId !== 'string'\n ) {\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.MissingAuthUserInfo,\n );\n }\n\n if (\n !('nodeAuthTokens' in value) ||\n typeof value.nodeAuthTokens !== 'object' ||\n !Array.isArray(value.nodeAuthTokens) ||\n value.nodeAuthTokens.length < 3 // At least 3 auth tokens are required for Threshold OPRF service\n ) {\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.InsufficientAuthToken,\n );\n }\n }\n\n #assertIsSRPBackedUpUser(\n value: unknown,\n ): asserts value is SRPBackedUpUserDetails {\n if (!this.state.authPubKey) {\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.SRPNotBackedUpError,\n );\n }\n }\n\n /**\n * Handle the recovery error and update the recovery error data after executing the given callback.\n *\n * @param recoveryCallback - The callback recovery function to execute.\n * @returns The result of the callback function.\n */\n async #withRecoveryErrorHandler(\n recoveryCallback: () => Promise<RecoverEncryptionKeyResult>,\n ): Promise<RecoverEncryptionKeyResult> {\n const currentRecoveryAttempts =\n this.state.recoveryRatelimitCache?.numberOfAttempts || 0;\n let updatedRecoveryAttempts = currentRecoveryAttempts + 1;\n let updatedRemainingTime =\n this.state.recoveryRatelimitCache?.remainingTime || 0;\n\n try {\n const result = await recoveryCallback();\n\n // reset the ratelimit error data\n updatedRecoveryAttempts = 0;\n updatedRemainingTime = 0;\n\n return result;\n } catch (error) {\n const recoveryError = RecoveryError.getInstance(error, {\n numberOfAttempts: updatedRecoveryAttempts,\n remainingTime: updatedRemainingTime,\n });\n\n if (recoveryError.data?.numberOfAttempts) {\n updatedRecoveryAttempts = recoveryError.data.numberOfAttempts;\n }\n\n if (recoveryError.data?.remainingTime) {\n updatedRemainingTime = recoveryError.data.remainingTime;\n }\n\n throw recoveryError;\n } finally {\n this.update((state) => {\n state.recoveryRatelimitCache = {\n numberOfAttempts: updatedRecoveryAttempts,\n remainingTime: updatedRemainingTime,\n };\n });\n }\n }\n\n /**\n * Assert that the password is in sync with the global password.\n *\n * @param options - The options for asserting the password is in sync.\n * @param options.skipCache - Whether to skip the cache check.\n * @param options.skipLock - Whether to skip the lock acquisition.\n * @throws If the password is outdated.\n */\n async #assertPasswordInSync(options?: {\n skipCache?: boolean;\n skipLock?: boolean;\n }): Promise<void> {\n const isPasswordOutdated = await this.checkIsPasswordOutdated(options);\n if (isPasswordOutdated) {\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.OutdatedPassword,\n );\n }\n }\n\n #resetPasswordOutdatedCache(): void {\n this.update((state) => {\n delete state.passwordOutdatedCache;\n });\n }\n\n /**\n * Check if the provided value is a valid vault data.\n *\n * @param value - The value to check.\n * @throws If the value is not a valid vault data.\n */\n #assertIsValidVaultData(value: unknown): asserts value is VaultData {\n // value is not valid vault data if any of the following conditions are true:\n if (\n !value || // value is not defined\n typeof value !== 'object' || // value is not an object\n !('authTokens' in value) || // authTokens is not defined\n typeof value.authTokens !== 'object' || // authTokens is not an object\n !('toprfEncryptionKey' in value) || // toprfEncryptionKey is not defined\n typeof value.toprfEncryptionKey !== 'string' || // toprfEncryptionKey is not a string\n !('toprfAuthKeyPair' in value) || // toprfAuthKeyPair is not defined\n typeof value.toprfAuthKeyPair !== 'string' // toprfAuthKeyPair is not a string\n ) {\n throw new Error(SeedlessOnboardingControllerErrorMessage.VaultDataError);\n }\n }\n}\n\n/**\n * Assert that the provided password is a valid non-empty string.\n *\n * @param password - The password to check.\n * @throws If the password is not a valid string.\n */\nfunction assertIsValidPassword(password: unknown): asserts password is string {\n if (typeof password !== 'string') {\n throw new Error(SeedlessOnboardingControllerErrorMessage.WrongPasswordType);\n }\n\n if (!password || !password.length) {\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.InvalidEmptyPassword,\n );\n }\n}\n\n/**\n * Lock the given mutex before executing the given function,\n * and release it after the function is resolved or after an\n * error is thrown.\n *\n * @param mutex - The mutex to lock.\n * @param callback - The function to execute while the mutex is locked.\n * @returns The result of the function.\n */\nasync function withLock<Result>(\n mutex: Mutex,\n callback: MutuallyExclusiveCallback<Result>,\n): Promise<Result> {\n const releaseLock = await mutex.acquire();\n\n try {\n return await callback({ releaseLock });\n } finally {\n releaseLock();\n }\n}\n"]}
|
|
@@ -8,7 +8,7 @@ import type { SeedlessOnboardingControllerMessenger, SeedlessOnboardingControlle
|
|
|
8
8
|
* @returns The default state for the Seedless Onboarding Controller.
|
|
9
9
|
*/
|
|
10
10
|
export declare function getDefaultSeedlessOnboardingControllerState(): SeedlessOnboardingControllerState;
|
|
11
|
-
export declare class SeedlessOnboardingController<EncryptionKey> extends BaseController<typeof controllerName, SeedlessOnboardingControllerState, SeedlessOnboardingControllerMessenger> {
|
|
11
|
+
export declare class SeedlessOnboardingController<EncryptionKey, SupportedKeyDerivationOptions> extends BaseController<typeof controllerName, SeedlessOnboardingControllerState, SeedlessOnboardingControllerMessenger> {
|
|
12
12
|
#private;
|
|
13
13
|
readonly toprfClient: ToprfSecureBackup;
|
|
14
14
|
/**
|
|
@@ -21,7 +21,7 @@ export declare class SeedlessOnboardingController<EncryptionKey> extends BaseCon
|
|
|
21
21
|
* @param options.toprfKeyDeriver - An optional key derivation interface for the TOPRF client.
|
|
22
22
|
* @param options.network - The network to be used for the Seedless Onboarding flow.
|
|
23
23
|
*/
|
|
24
|
-
constructor({ messenger, state, encryptor, toprfKeyDeriver, network, }: SeedlessOnboardingControllerOptions<EncryptionKey>);
|
|
24
|
+
constructor({ messenger, state, encryptor, toprfKeyDeriver, network, }: SeedlessOnboardingControllerOptions<EncryptionKey, SupportedKeyDerivationOptions>);
|
|
25
25
|
/**
|
|
26
26
|
* Authenticate OAuth user using the seedless onboarding flow
|
|
27
27
|
* and determine if the user is already registered or not.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SeedlessOnboardingController.d.cts","sourceRoot":"","sources":["../src/SeedlessOnboardingController.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAO3D,OAAO,EAAE,iBAAiB,EAAE,sCAAsC;AAKlE,OAAO,EACL,KAAK,cAAc,EACnB,cAAc,EAEd,UAAU,EAGX,wBAAoB;AAIrB,OAAO,KAAK,EAEV,qCAAqC,EACrC,mCAAmC,EACnC,iCAAiC,EAGjC,qBAAqB,EAGtB,oBAAgB;AAIjB;;;;GAIG;AACH,wBAAgB,2CAA2C,IAAI,iCAAiC,CAI/F;AAiED,qBAAa,4BAA4B,
|
|
1
|
+
{"version":3,"file":"SeedlessOnboardingController.d.cts","sourceRoot":"","sources":["../src/SeedlessOnboardingController.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,7 +8,7 @@ import type { SeedlessOnboardingControllerMessenger, SeedlessOnboardingControlle
|
|
|
8
8
|
* @returns The default state for the Seedless Onboarding Controller.
|
|
9
9
|
*/
|
|
10
10
|
export declare function getDefaultSeedlessOnboardingControllerState(): SeedlessOnboardingControllerState;
|
|
11
|
-
export declare class SeedlessOnboardingController<EncryptionKey> extends BaseController<typeof controllerName, SeedlessOnboardingControllerState, SeedlessOnboardingControllerMessenger> {
|
|
11
|
+
export declare class SeedlessOnboardingController<EncryptionKey, SupportedKeyDerivationOptions> extends BaseController<typeof controllerName, SeedlessOnboardingControllerState, SeedlessOnboardingControllerMessenger> {
|
|
12
12
|
#private;
|
|
13
13
|
readonly toprfClient: ToprfSecureBackup;
|
|
14
14
|
/**
|
|
@@ -21,7 +21,7 @@ export declare class SeedlessOnboardingController<EncryptionKey> extends BaseCon
|
|
|
21
21
|
* @param options.toprfKeyDeriver - An optional key derivation interface for the TOPRF client.
|
|
22
22
|
* @param options.network - The network to be used for the Seedless Onboarding flow.
|
|
23
23
|
*/
|
|
24
|
-
constructor({ messenger, state, encryptor, toprfKeyDeriver, network, }: SeedlessOnboardingControllerOptions<EncryptionKey>);
|
|
24
|
+
constructor({ messenger, state, encryptor, toprfKeyDeriver, network, }: SeedlessOnboardingControllerOptions<EncryptionKey, SupportedKeyDerivationOptions>);
|
|
25
25
|
/**
|
|
26
26
|
* Authenticate OAuth user using the seedless onboarding flow
|
|
27
27
|
* and determine if the user is already registered or not.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SeedlessOnboardingController.d.mts","sourceRoot":"","sources":["../src/SeedlessOnboardingController.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAO3D,OAAO,EAAE,iBAAiB,EAAE,sCAAsC;AAKlE,OAAO,EACL,KAAK,cAAc,EACnB,cAAc,EAEd,UAAU,EAGX,wBAAoB;AAIrB,OAAO,KAAK,EAEV,qCAAqC,EACrC,mCAAmC,EACnC,iCAAiC,EAGjC,qBAAqB,EAGtB,oBAAgB;AAIjB;;;;GAIG;AACH,wBAAgB,2CAA2C,IAAI,iCAAiC,CAI/F;AAiED,qBAAa,4BAA4B,
|
|
1
|
+
{"version":3,"file":"SeedlessOnboardingController.d.mts","sourceRoot":"","sources":["../src/SeedlessOnboardingController.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SeedlessOnboardingController.mjs","sourceRoot":"","sources":["../src/SeedlessOnboardingController.ts"],"names":[],"mappings":"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","sourcesContent":["import { keccak256AndHexify } from '@metamask/auth-network-utils';\nimport type { StateMetadata } from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport type {\n KeyPair,\n NodeAuthTokens,\n RecoverEncryptionKeyResult,\n SEC1EncodedPublicKey,\n} from '@metamask/toprf-secure-backup';\nimport { ToprfSecureBackup } from '@metamask/toprf-secure-backup';\nimport { base64ToBytes, bytesToBase64, bigIntToHex } from '@metamask/utils';\nimport { secp256k1 } from '@noble/curves/secp256k1';\nimport { Mutex } from 'async-mutex';\n\nimport {\n type AuthConnection,\n controllerName,\n PASSWORD_OUTDATED_CACHE_TTL_MS,\n SecretType,\n SeedlessOnboardingControllerErrorMessage,\n Web3AuthNetwork,\n} from './constants';\nimport { PasswordSyncError, RecoveryError } from './errors';\nimport { projectLogger, createModuleLogger } from './logger';\nimport { SecretMetadata } from './SecretMetadata';\nimport type {\n MutuallyExclusiveCallback,\n SeedlessOnboardingControllerMessenger,\n SeedlessOnboardingControllerOptions,\n SeedlessOnboardingControllerState,\n VaultData,\n AuthenticatedUserDetails,\n SocialBackupsMetadata,\n SRPBackedUpUserDetails,\n VaultEncryptor,\n} from './types';\n\nconst log = createModuleLogger(projectLogger, controllerName);\n\n/**\n * Get the default state for the Seedless Onboarding Controller.\n *\n * @returns The default state for the Seedless Onboarding Controller.\n */\nexport function getDefaultSeedlessOnboardingControllerState(): SeedlessOnboardingControllerState {\n return {\n socialBackupsMetadata: [],\n };\n}\n\n/**\n * Seedless Onboarding Controller State Metadata.\n *\n * This allows us to choose if fields of the state should be persisted or not\n * using the `persist` flag; and if they can be sent to Sentry or not, using\n * the `anonymous` flag.\n */\nconst seedlessOnboardingMetadata: StateMetadata<SeedlessOnboardingControllerState> =\n {\n vault: {\n persist: true,\n anonymous: false,\n },\n socialBackupsMetadata: {\n persist: true,\n anonymous: true,\n },\n nodeAuthTokens: {\n persist: true,\n anonymous: true,\n },\n authConnection: {\n persist: true,\n anonymous: true,\n },\n authConnectionId: {\n persist: true,\n anonymous: true,\n },\n groupedAuthConnectionId: {\n persist: true,\n anonymous: true,\n },\n userId: {\n persist: true,\n anonymous: true,\n },\n socialLoginEmail: {\n persist: true,\n anonymous: true,\n },\n vaultEncryptionKey: {\n persist: false,\n anonymous: true,\n },\n vaultEncryptionSalt: {\n persist: false,\n anonymous: true,\n },\n authPubKey: {\n persist: true,\n anonymous: true,\n },\n passwordOutdatedCache: {\n persist: true,\n anonymous: true,\n },\n recoveryRatelimitCache: {\n persist: true,\n anonymous: true,\n },\n };\n\nexport class SeedlessOnboardingController<EncryptionKey> extends BaseController<\n typeof controllerName,\n SeedlessOnboardingControllerState,\n SeedlessOnboardingControllerMessenger\n> {\n readonly #vaultEncryptor: VaultEncryptor<EncryptionKey>;\n\n readonly #controllerOperationMutex = new Mutex();\n\n readonly #vaultOperationMutex = new Mutex();\n\n readonly toprfClient: ToprfSecureBackup;\n\n /**\n * Controller lock state.\n *\n * The controller lock is synchronized with the keyring lock.\n */\n #isUnlocked = false;\n\n /**\n * Creates a new SeedlessOnboardingController instance.\n *\n * @param options - The options for the SeedlessOnboardingController.\n * @param options.messenger - A restricted messenger.\n * @param options.state - Initial state to set on this controller.\n * @param options.encryptor - An optional encryptor to use for encrypting and decrypting seedless onboarding vault.\n * @param options.toprfKeyDeriver - An optional key derivation interface for the TOPRF client.\n * @param options.network - The network to be used for the Seedless Onboarding flow.\n */\n constructor({\n messenger,\n state,\n encryptor,\n toprfKeyDeriver,\n network = Web3AuthNetwork.Mainnet,\n }: SeedlessOnboardingControllerOptions<EncryptionKey>) {\n super({\n name: controllerName,\n metadata: seedlessOnboardingMetadata,\n state: {\n ...getDefaultSeedlessOnboardingControllerState(),\n ...state,\n },\n messenger,\n });\n\n this.#vaultEncryptor = encryptor;\n this.toprfClient = new ToprfSecureBackup({\n network,\n keyDeriver: toprfKeyDeriver,\n });\n\n // setup subscriptions to the keyring lock event\n // when the keyring is locked (wallet is locked), the controller will be cleared of its credentials\n this.messagingSystem.subscribe('KeyringController:lock', () => {\n this.setLocked();\n });\n this.messagingSystem.subscribe('KeyringController:unlock', () => {\n this.#setUnlocked();\n });\n }\n\n /**\n * Authenticate OAuth user using the seedless onboarding flow\n * and determine if the user is already registered or not.\n *\n * @param params - The parameters for authenticate OAuth user.\n * @param params.idTokens - The ID token(s) issued by OAuth verification service. Currently this array only contains a single idToken which is verified by all the nodes, in future we are considering to issue a unique idToken for each node.\n * @param params.authConnection - The social login provider.\n * @param params.authConnectionId - OAuth authConnectionId from dashboard\n * @param params.userId - user email or id from Social login\n * @param params.groupedAuthConnectionId - Optional grouped authConnectionId to be used for the authenticate request.\n * @param params.socialLoginEmail - The user email from Social login.\n * You can pass this to use aggregate multiple OAuth connections. Useful when you want user to have same account while using different OAuth connections.\n * @returns A promise that resolves to the authentication result.\n */\n async authenticate(params: {\n idTokens: string[];\n authConnection: AuthConnection;\n authConnectionId: string;\n userId: string;\n groupedAuthConnectionId?: string;\n socialLoginEmail?: string;\n }) {\n return await this.#withControllerLock(async () => {\n try {\n const {\n idTokens,\n authConnectionId,\n groupedAuthConnectionId,\n userId,\n authConnection,\n socialLoginEmail,\n } = params;\n\n const authenticationResult = await this.toprfClient.authenticate({\n authConnectionId,\n userId,\n idTokens,\n groupedAuthConnectionId,\n });\n // update the state with the authenticated user info\n this.update((state) => {\n state.nodeAuthTokens = authenticationResult.nodeAuthTokens;\n state.authConnectionId = authConnectionId;\n state.groupedAuthConnectionId = groupedAuthConnectionId;\n state.userId = userId;\n state.authConnection = authConnection;\n state.socialLoginEmail = socialLoginEmail;\n });\n return authenticationResult;\n } catch (error) {\n log('Error authenticating user', error);\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.AuthenticationError,\n );\n }\n });\n }\n\n /**\n * Create a new TOPRF encryption key using given password and backups the provided seed phrase.\n *\n * @param password - The password used to create new wallet and seedphrase\n * @param seedPhrase - The seed phrase to backup\n * @param keyringId - The keyring id of the backup seed phrase\n * @returns A promise that resolves to the encrypted seed phrase and the encryption key.\n */\n async createToprfKeyAndBackupSeedPhrase(\n password: string,\n seedPhrase: Uint8Array,\n keyringId: string,\n ): Promise<void> {\n // to make sure that fail fast,\n // assert that the user is authenticated before creating the TOPRF key and backing up the seed phrase\n this.#assertIsAuthenticatedUser(this.state);\n\n return await this.#withControllerLock(async () => {\n // locally evaluate the encryption key from the password\n const { encKey, authKeyPair, oprfKey } =\n await this.toprfClient.createLocalKey({\n password,\n });\n\n // encrypt and store the seed phrase backup\n await this.#encryptAndStoreSecretData({\n data: seedPhrase,\n type: SecretType.Mnemonic,\n encKey,\n authKeyPair,\n options: {\n keyringId,\n },\n });\n\n // store/persist the encryption key shares\n // We store the seed phrase metadata in the metadata store first. If this operation fails,\n // we avoid persisting the encryption key shares to prevent a situation where a user appears\n // to have an account but with no associated data.\n await this.#persistOprfKey(oprfKey, authKeyPair.pk);\n // create a new vault with the resulting authentication data\n await this.#createNewVaultWithAuthData({\n password,\n rawToprfEncryptionKey: encKey,\n rawToprfAuthKeyPair: authKeyPair,\n });\n this.#persistAuthPubKey({\n authPubKey: authKeyPair.pk,\n });\n });\n }\n\n /**\n * encrypt and add a new secret data to the metadata store.\n *\n * @param data - The data to add.\n * @param type - The type of the secret data.\n * @param options - Optional options object, which includes optional data to be added to the metadata store.\n * @param options.keyringId - The keyring id of the backup keyring (SRP).\n * @returns A promise that resolves to the success of the operation.\n */\n async addNewSecretData(\n data: Uint8Array,\n type: SecretType,\n options?: {\n keyringId?: string;\n },\n ): Promise<void> {\n return await this.#withControllerLock(async () => {\n this.#assertIsUnlocked();\n\n await this.#assertPasswordInSync({\n skipCache: true,\n skipLock: true, // skip lock since we already have the lock\n });\n\n // verify the password and unlock the vault\n const { toprfEncryptionKey, toprfAuthKeyPair } =\n await this.#unlockVaultAndGetBackupEncKey();\n\n // encrypt and store the seed phrase backup\n await this.#encryptAndStoreSecretData({\n data,\n type,\n encKey: toprfEncryptionKey,\n authKeyPair: toprfAuthKeyPair,\n options,\n });\n });\n }\n\n /**\n * Fetches all encrypted secret data and metadata for user's account from the metadata store.\n *\n * Decrypts the secret data and returns the decrypted secret data using the recovered encryption key from the password.\n *\n * @param password - The optional password used to create new wallet and seedphrase. If not provided, `cached Encryption Key` will be used.\n * @returns A promise that resolves to the secret data.\n */\n async fetchAllSecretData(\n password?: string,\n ): Promise<Record<SecretType, Uint8Array[]>> {\n // assert that the user is authenticated before fetching the seed phrases\n this.#assertIsAuthenticatedUser(this.state);\n\n return await this.#withControllerLock(async () => {\n let encKey: Uint8Array;\n let authKeyPair: KeyPair;\n\n if (password) {\n const recoverEncKeyResult = await this.#recoverEncKey(password);\n encKey = recoverEncKeyResult.encKey;\n authKeyPair = recoverEncKeyResult.authKeyPair;\n } else {\n this.#assertIsUnlocked();\n // verify the password and unlock the vault\n const keysFromVault = await this.#unlockVaultAndGetBackupEncKey();\n encKey = keysFromVault.toprfEncryptionKey;\n authKeyPair = keysFromVault.toprfAuthKeyPair;\n }\n\n try {\n const secretData = await this.toprfClient.fetchAllSecretDataItems({\n decKey: encKey,\n authKeyPair,\n });\n\n if (secretData?.length > 0 && password) {\n // if password is provided, we need to create a new vault with the auth data. (supposedly the user is trying to rehydrate the wallet)\n await this.#createNewVaultWithAuthData({\n password,\n rawToprfEncryptionKey: encKey,\n rawToprfAuthKeyPair: authKeyPair,\n });\n\n this.#persistAuthPubKey({\n authPubKey: authKeyPair.pk,\n });\n }\n\n const result: Record<SecretType, Uint8Array[]> = {\n mnemonic: [],\n privateKey: [],\n };\n const secrets =\n SecretMetadata.parseSecretsFromMetadataStore(secretData);\n\n secrets.forEach((secret) => {\n result[secret.type].push(secret.data);\n });\n\n return result;\n } catch (error) {\n log('Error fetching seed phrase metadata', error);\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.FailedToFetchSeedPhraseMetadata,\n );\n }\n });\n }\n\n /**\n * Update the password of the seedless onboarding flow.\n *\n * Changing password will also update the encryption key, metadata store and the vault with new encrypted values.\n *\n * @param newPassword - The new password to update.\n * @param oldPassword - The old password to verify.\n * @returns A promise that resolves to the success of the operation.\n */\n async changePassword(newPassword: string, oldPassword: string) {\n return await this.#withControllerLock(async () => {\n this.#assertIsUnlocked();\n // verify the old password of the encrypted vault\n await this.verifyVaultPassword(oldPassword, {\n skipLock: true, // skip lock since we already have the lock\n });\n await this.#assertPasswordInSync({\n skipCache: true,\n skipLock: true, // skip lock since we already have the lock\n });\n\n try {\n // update the encryption key with new password and update the Metadata Store\n const { encKey: newEncKey, authKeyPair: newAuthKeyPair } =\n await this.#changeEncryptionKey(newPassword, oldPassword);\n\n // update and encrypt the vault with new password\n await this.#createNewVaultWithAuthData({\n password: newPassword,\n rawToprfEncryptionKey: newEncKey,\n rawToprfAuthKeyPair: newAuthKeyPair,\n });\n\n this.#persistAuthPubKey({\n authPubKey: newAuthKeyPair.pk,\n });\n this.#resetPasswordOutdatedCache();\n } catch (error) {\n log('Error changing password', error);\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.FailedToChangePassword,\n );\n }\n });\n }\n\n /**\n * Update the backup metadata state for the given seed phrase.\n *\n * @param data - The data to backup, can be a single backup or array of backups.\n * @param data.keyringId - The keyring id associated with the backup seed phrase.\n * @param data.seedPhrase - The seed phrase to update the backup metadata state.\n */\n updateBackupMetadataState(\n data:\n | {\n keyringId: string;\n seedPhrase: Uint8Array;\n }\n | {\n keyringId: string;\n seedPhrase: Uint8Array;\n }[],\n ) {\n this.#assertIsUnlocked();\n\n this.#filterDupesAndUpdateSocialBackupsMetadata(data);\n }\n\n /**\n * Verify the password validity by decrypting the vault.\n *\n * @param password - The password to verify.\n * @param options - Optional options object.\n * @param options.skipLock - Whether to skip the lock acquisition.\n * @returns A promise that resolves to the success of the operation.\n * @throws {Error} If the password is invalid or the vault is not initialized.\n */\n async verifyVaultPassword(\n password: string,\n options?: {\n skipLock?: boolean;\n },\n ): Promise<void> {\n const doVerify = async () => {\n if (!this.state.vault) {\n throw new Error(SeedlessOnboardingControllerErrorMessage.VaultError);\n }\n await this.#vaultEncryptor.decrypt(password, this.state.vault);\n };\n return options?.skipLock\n ? await doVerify()\n : await this.#withControllerLock(doVerify);\n }\n\n /**\n * Get the hash of the seed phrase backup for the given seed phrase, from the state.\n *\n * If the given seed phrase is not backed up and not found in the state, it will return `undefined`.\n *\n * @param seedPhrase - The seed phrase to get the hash of.\n * @returns A promise that resolves to the hash of the seed phrase backup.\n */\n getSeedPhraseBackupHash(\n seedPhrase: Uint8Array,\n ): SocialBackupsMetadata | undefined {\n const seedPhraseHash = keccak256AndHexify(seedPhrase);\n return this.state.socialBackupsMetadata.find(\n (backup) => backup.hash === seedPhraseHash,\n );\n }\n\n /**\n * Submit the password to the controller, verify the password validity and unlock the controller.\n *\n * This method will be used especially when user rehydrate/unlock the wallet.\n * The provided password will be verified against the encrypted vault, encryption key will be derived and saved in the controller state.\n *\n * This operation is useful when user performs some actions that requires the user password/encryption key. e.g. add new srp backup\n *\n * @param password - The password to submit.\n * @returns A promise that resolves to the success of the operation.\n */\n async submitPassword(password: string): Promise<void> {\n return await this.#withControllerLock(async () => {\n await this.#unlockVaultAndGetBackupEncKey(password);\n this.#setUnlocked();\n });\n }\n\n /**\n * Set the controller to locked state, and deallocate the secrets (vault encryption key and salt).\n *\n * When the controller is locked, the user will not be able to perform any operations on the controller/vault.\n */\n setLocked() {\n this.update((state) => {\n delete state.vaultEncryptionKey;\n delete state.vaultEncryptionSalt;\n });\n\n this.#isUnlocked = false;\n }\n\n /**\n * Sync the latest global password to the controller.\n * reset vault with latest globalPassword,\n * persist the latest global password authPubKey\n *\n * @param params - The parameters for syncing the latest global password.\n * @param params.oldPassword - The old password to verify.\n * @param params.globalPassword - The latest global password.\n * @returns A promise that resolves to the success of the operation.\n */\n async syncLatestGlobalPassword({\n oldPassword,\n globalPassword,\n }: {\n oldPassword: string;\n globalPassword: string;\n }) {\n return await this.#withControllerLock(async () => {\n // verify correct old password\n await this.verifyVaultPassword(oldPassword, {\n skipLock: true, // skip lock since we already have the lock\n });\n // update vault with latest globalPassword\n const { encKey, authKeyPair } = await this.#recoverEncKey(globalPassword);\n // update and encrypt the vault with new password\n await this.#createNewVaultWithAuthData({\n password: globalPassword,\n rawToprfEncryptionKey: encKey,\n rawToprfAuthKeyPair: authKeyPair,\n });\n // persist the latest global password authPubKey\n this.#persistAuthPubKey({\n authPubKey: authKeyPair.pk,\n });\n this.#resetPasswordOutdatedCache();\n });\n }\n\n /**\n * @description Fetch the password corresponding to the current authPubKey in state (current device password which is already out of sync with the current global password).\n * then we use this recovered old password to unlock the vault and set the password to the new global password.\n *\n * @param params - The parameters for fetching the password.\n * @param params.globalPassword - The latest global password.\n * @returns A promise that resolves to the password corresponding to the current authPubKey in state.\n */\n async recoverCurrentDevicePassword({\n globalPassword,\n }: {\n globalPassword: string;\n }): Promise<{ password: string }> {\n return await this.#withControllerLock(async () => {\n const currentDeviceAuthPubKey = this.#recoverAuthPubKey();\n const { password: currentDevicePassword } = await this.#recoverPassword({\n targetPwPubKey: currentDeviceAuthPubKey,\n globalPassword,\n });\n return {\n password: currentDevicePassword,\n };\n });\n }\n\n /**\n * @description Fetch the password corresponding to the targetPwPubKey.\n *\n * @param params - The parameters for fetching the password.\n * @param params.targetPwPubKey - The target public key of the password to recover.\n * @param params.globalPassword - The latest global password.\n * @returns A promise that resolves to the password corresponding to the current authPubKey in state.\n */\n async #recoverPassword({\n targetPwPubKey,\n globalPassword,\n }: {\n targetPwPubKey: SEC1EncodedPublicKey;\n globalPassword: string;\n }): Promise<{ password: string }> {\n const { encKey: latestPwEncKey, authKeyPair: latestPwAuthKeyPair } =\n await this.#recoverEncKey(globalPassword);\n\n try {\n const res = await this.toprfClient.recoverPassword({\n targetPwPubKey,\n curEncKey: latestPwEncKey,\n curAuthKeyPair: latestPwAuthKeyPair,\n });\n return res;\n } catch (error) {\n throw PasswordSyncError.getInstance(error);\n }\n }\n\n /**\n * @description Check if the current password is outdated compare to the global password.\n *\n * @param options - Optional options object.\n * @param options.skipCache - If true, bypass the cache and force a fresh check.\n * @param options.skipLock - Whether to skip the lock acquisition.\n * @returns A promise that resolves to true if the password is outdated, false otherwise.\n */\n async checkIsPasswordOutdated(options?: {\n skipCache?: boolean;\n skipLock?: boolean;\n }): Promise<boolean> {\n // cache result to reduce load on infra\n // Check cache first unless skipCache is true\n if (!options?.skipCache) {\n const { passwordOutdatedCache } = this.state;\n const now = Date.now();\n const isCacheValid =\n passwordOutdatedCache &&\n now - passwordOutdatedCache.timestamp < PASSWORD_OUTDATED_CACHE_TTL_MS;\n\n if (isCacheValid) {\n return passwordOutdatedCache.isExpiredPwd;\n }\n }\n\n const doCheck = async () => {\n this.#assertIsAuthenticatedUser(this.state);\n const {\n nodeAuthTokens,\n authConnectionId,\n groupedAuthConnectionId,\n userId,\n } = this.state;\n\n const currentDeviceAuthPubKey = this.#recoverAuthPubKey();\n\n const { authPubKey: globalAuthPubKey } =\n await this.toprfClient.fetchAuthPubKey({\n nodeAuthTokens,\n authConnectionId,\n groupedAuthConnectionId,\n userId,\n });\n\n // use noble lib to deserialize and compare curve point\n const isExpiredPwd = !secp256k1.ProjectivePoint.fromHex(\n currentDeviceAuthPubKey,\n ).equals(secp256k1.ProjectivePoint.fromHex(globalAuthPubKey));\n // Cache the result in state\n this.update((state) => {\n state.passwordOutdatedCache = { isExpiredPwd, timestamp: Date.now() };\n });\n return isExpiredPwd;\n };\n\n return options?.skipLock\n ? await doCheck()\n : await this.#withControllerLock(doCheck);\n }\n\n #setUnlocked(): void {\n this.#isUnlocked = true;\n }\n\n /**\n * Clears the current state of the SeedlessOnboardingController.\n */\n clearState() {\n const defaultState = getDefaultSeedlessOnboardingControllerState();\n this.update(() => {\n return defaultState;\n });\n }\n\n /**\n * Persist the encryption key for the seedless onboarding flow.\n *\n * @param oprfKey - The OPRF key to be splited and persisted.\n * @param authPubKey - The authentication public key.\n * @returns A promise that resolves to the success of the operation.\n */\n async #persistOprfKey(oprfKey: bigint, authPubKey: SEC1EncodedPublicKey) {\n this.#assertIsAuthenticatedUser(this.state);\n const { authConnectionId, groupedAuthConnectionId, userId } = this.state;\n\n try {\n await this.toprfClient.persistLocalKey({\n nodeAuthTokens: this.state.nodeAuthTokens,\n authConnectionId,\n groupedAuthConnectionId,\n userId,\n oprfKey,\n authPubKey,\n });\n } catch (error) {\n log('Error persisting local encryption key', error);\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.FailedToPersistOprfKey,\n );\n }\n }\n\n /**\n * Persist the authentication public key for the seedless onboarding flow.\n * convert to suitable format before persisting.\n *\n * @param params - The parameters for persisting the authentication public key.\n * @param params.authPubKey - The authentication public key to be persisted.\n */\n #persistAuthPubKey(params: { authPubKey: SEC1EncodedPublicKey }): void {\n this.update((state) => {\n state.authPubKey = bytesToBase64(params.authPubKey);\n });\n }\n\n /**\n * Recover the authentication public key from the state.\n * convert to pubkey format before recovering.\n *\n * @returns The authentication public key.\n */\n #recoverAuthPubKey(): SEC1EncodedPublicKey {\n this.#assertIsSRPBackedUpUser(this.state);\n const { authPubKey } = this.state;\n\n return base64ToBytes(authPubKey);\n }\n\n /**\n * Recover the encryption key from password.\n *\n * @param password - The password used to derive/recover the encryption key.\n * @returns A promise that resolves to the encryption key and authentication key pair.\n * @throws RecoveryError - If failed to recover the encryption key.\n */\n async #recoverEncKey(password: string) {\n return this.#withRecoveryErrorHandler(async () => {\n this.#assertIsAuthenticatedUser(this.state);\n\n const { authConnectionId, groupedAuthConnectionId, userId } = this.state;\n\n const recoverEncKeyResult = await this.toprfClient.recoverEncKey({\n nodeAuthTokens: this.state.nodeAuthTokens,\n password,\n authConnectionId,\n groupedAuthConnectionId,\n userId,\n });\n return recoverEncKeyResult;\n });\n }\n\n /**\n * Update the encryption key with new password and update the Metadata Store with new encryption key.\n *\n * @param newPassword - The new password to update.\n * @param oldPassword - The old password to verify.\n * @returns A promise that resolves to new encryption key and authentication key pair.\n */\n async #changeEncryptionKey(newPassword: string, oldPassword: string) {\n this.#assertIsAuthenticatedUser(this.state);\n const { authConnectionId, groupedAuthConnectionId, userId } = this.state;\n\n const {\n encKey,\n authKeyPair,\n keyShareIndex: newKeyShareIndex,\n } = await this.#recoverEncKey(oldPassword);\n\n return await this.toprfClient.changeEncKey({\n nodeAuthTokens: this.state.nodeAuthTokens,\n authConnectionId,\n groupedAuthConnectionId,\n userId,\n oldEncKey: encKey,\n oldAuthKeyPair: authKeyPair,\n newKeyShareIndex,\n oldPassword,\n newPassword,\n });\n }\n\n /**\n * Encrypt and store the seed phrase backup in the metadata store.\n *\n * @param params - The parameters for encrypting and storing the seed phrase backup.\n * @param params.data - The seed phrase to store.\n * @param params.type - The type of the secret data.\n * @param params.encKey - The encryption key to store.\n * @param params.authKeyPair - The authentication key pair to store.\n * @param params.options - Optional options object, which includes optional data to be added to the metadata store.\n * @param params.options.keyringId - The keyring id of the backup keyring (SRP).\n *\n * @returns A promise that resolves to the success of the operation.\n */\n async #encryptAndStoreSecretData(params: {\n data: Uint8Array;\n type: SecretType;\n encKey: Uint8Array;\n authKeyPair: KeyPair;\n options?: {\n keyringId?: string;\n };\n }): Promise<void> {\n const { options, data, encKey, authKeyPair, type } = params;\n\n const secretMetadata = new SecretMetadata(data, {\n type,\n });\n const secretData = secretMetadata.toBytes();\n\n const keyringId = options?.keyringId as string;\n if (type === SecretType.Mnemonic && !keyringId) {\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.MissingKeyringId,\n );\n }\n\n try {\n if (type === SecretType.Mnemonic) {\n await this.#withPersistedSeedPhraseBackupsState(async () => {\n await this.toprfClient.addSecretDataItem({\n encKey,\n secretData,\n authKeyPair,\n });\n return {\n keyringId,\n seedPhrase: data,\n };\n });\n return;\n }\n\n await this.toprfClient.addSecretDataItem({\n encKey,\n secretData,\n authKeyPair,\n });\n } catch (error) {\n log('Error encrypting and storing seed phrase backup', error);\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.FailedToEncryptAndStoreSeedPhraseBackup,\n );\n }\n }\n\n /**\n * Unlocks the encrypted vault using the provided password and returns the decrypted vault data.\n * This method ensures thread-safety by using a mutex lock when accessing the vault.\n *\n * @param password - The optional password to unlock the vault.\n * @returns A promise that resolves to an object containing:\n * - nodeAuthTokens: Authentication tokens to communicate with the TOPRF service\n * - toprfEncryptionKey: The decrypted TOPRF encryption key\n * - toprfAuthKeyPair: The decrypted TOPRF authentication key pair\n * @throws {Error} If:\n * - The password is invalid or empty\n * - The vault is not initialized\n * - The password is incorrect (from encryptor.decrypt)\n * - The decrypted vault data is malformed\n */\n async #unlockVaultAndGetBackupEncKey(password?: string): Promise<{\n nodeAuthTokens: NodeAuthTokens;\n toprfEncryptionKey: Uint8Array;\n toprfAuthKeyPair: KeyPair;\n }> {\n return this.#withVaultLock(async () => {\n const {\n vault: encryptedVault,\n vaultEncryptionKey,\n vaultEncryptionSalt,\n } = this.state;\n\n if (!encryptedVault) {\n throw new Error(SeedlessOnboardingControllerErrorMessage.VaultError);\n }\n\n if (!vaultEncryptionKey && !password) {\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.MissingCredentials,\n );\n }\n\n let decryptedVaultData: unknown;\n const updatedState: Partial<SeedlessOnboardingControllerState> = {};\n\n if (password) {\n assertIsValidPassword(password);\n // Note that vault decryption using the password is a very costly operation as it involves deriving the encryption key\n // from the password using an intentionally slow key derivation function.\n // We should make sure that we only call it very intentionally.\n const result = await this.#vaultEncryptor.decryptWithDetail(\n password,\n encryptedVault,\n );\n decryptedVaultData = result.vault;\n updatedState.vaultEncryptionKey = result.exportedKeyString;\n updatedState.vaultEncryptionSalt = result.salt;\n } else {\n const parsedEncryptedVault = JSON.parse(encryptedVault);\n\n if (vaultEncryptionSalt !== parsedEncryptedVault.salt) {\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.ExpiredCredentials,\n );\n }\n\n if (typeof vaultEncryptionKey !== 'string') {\n throw new TypeError(\n SeedlessOnboardingControllerErrorMessage.WrongPasswordType,\n );\n }\n\n const key = await this.#vaultEncryptor.importKey(vaultEncryptionKey);\n decryptedVaultData = await this.#vaultEncryptor.decryptWithKey(\n key,\n parsedEncryptedVault,\n );\n updatedState.vaultEncryptionKey = vaultEncryptionKey;\n updatedState.vaultEncryptionSalt = vaultEncryptionSalt;\n }\n\n const { nodeAuthTokens, toprfEncryptionKey, toprfAuthKeyPair } =\n this.#parseVaultData(decryptedVaultData);\n\n // update the state with the restored nodeAuthTokens\n this.update((state) => {\n state.nodeAuthTokens = nodeAuthTokens;\n state.vaultEncryptionKey = updatedState.vaultEncryptionKey;\n state.vaultEncryptionSalt = updatedState.vaultEncryptionSalt;\n });\n\n return { nodeAuthTokens, toprfEncryptionKey, toprfAuthKeyPair };\n });\n }\n\n /**\n * Executes a callback function that creates or restores seed phrases and persists their hashes in the controller state.\n *\n * This method:\n * 1. Executes the provided callback to create/restore seed phrases\n * 2. Generates keccak256 hashes of the seed phrases\n * 3. Merges new hashes with existing ones in the state, ensuring uniqueness\n * 4. Updates the controller state with the combined hashes\n *\n * This is a wrapper method that should be used around any operation that creates\n * or restores seed phrases to ensure their hashes are properly tracked.\n *\n * @param createSeedPhraseBackupCallback - function that returns either a single seed phrase\n * or an array of seed phrases as Uint8Array(s)\n * @returns The original seed phrase(s) returned by the callback\n * @throws Rethrows any errors from the callback with additional logging\n */\n async #withPersistedSeedPhraseBackupsState(\n createSeedPhraseBackupCallback: () => Promise<{\n keyringId: string;\n seedPhrase: Uint8Array;\n }>,\n ): Promise<{\n keyringId: string;\n seedPhrase: Uint8Array;\n }> {\n try {\n const newBackup = await createSeedPhraseBackupCallback();\n\n this.#filterDupesAndUpdateSocialBackupsMetadata(newBackup);\n\n return newBackup;\n } catch (error) {\n log('Error persisting seed phrase backups', error);\n throw error;\n }\n }\n\n /**\n * Updates the social backups metadata state by adding new unique seed phrase backups.\n * This method ensures no duplicate backups are stored by checking the hash of each seed phrase.\n *\n * @param data - The backup data to add to the state\n * @param data.id - The identifier for the backup\n * @param data.seedPhrase - The seed phrase to backup as a Uint8Array\n */\n #filterDupesAndUpdateSocialBackupsMetadata(\n data:\n | {\n keyringId: string;\n seedPhrase: Uint8Array;\n }\n | {\n keyringId: string;\n seedPhrase: Uint8Array;\n }[],\n ) {\n const currentBackupsMetadata = this.state.socialBackupsMetadata;\n\n const newBackupsMetadata = Array.isArray(data) ? data : [data];\n const filteredNewBackupsMetadata: SocialBackupsMetadata[] = [];\n\n // filter out the backed up metadata that already exists in the state\n // to prevent duplicates\n newBackupsMetadata.forEach((item) => {\n const { keyringId, seedPhrase } = item;\n const backupHash = keccak256AndHexify(seedPhrase);\n\n const backupStateAlreadyExisted = currentBackupsMetadata.some(\n (backup) => backup.hash === backupHash,\n );\n\n if (!backupStateAlreadyExisted) {\n filteredNewBackupsMetadata.push({\n id: keyringId,\n hash: backupHash,\n });\n }\n });\n\n if (filteredNewBackupsMetadata.length > 0) {\n this.update((state) => {\n state.socialBackupsMetadata = [\n ...state.socialBackupsMetadata,\n ...filteredNewBackupsMetadata,\n ];\n });\n }\n }\n\n /**\n * Create a new vault with the given authentication data.\n *\n * Serialize the authentication and key data which will be stored in the vault.\n *\n * @param params - The parameters for creating a new vault.\n * @param params.password - The password to encrypt the vault.\n * @param params.rawToprfEncryptionKey - The encryption key to encrypt the vault.\n * @param params.rawToprfAuthKeyPair - The authentication key pair to encrypt the vault.\n */\n async #createNewVaultWithAuthData({\n password,\n rawToprfEncryptionKey,\n rawToprfAuthKeyPair,\n }: {\n password: string;\n rawToprfEncryptionKey: Uint8Array;\n rawToprfAuthKeyPair: KeyPair;\n }): Promise<void> {\n this.#assertIsAuthenticatedUser(this.state);\n this.#setUnlocked();\n\n const { toprfEncryptionKey, toprfAuthKeyPair } = this.#serializeKeyData(\n rawToprfEncryptionKey,\n rawToprfAuthKeyPair,\n );\n\n const serializedVaultData = JSON.stringify({\n authTokens: this.state.nodeAuthTokens,\n toprfEncryptionKey,\n toprfAuthKeyPair,\n });\n\n await this.#updateVault({\n password,\n serializedVaultData,\n });\n }\n\n /**\n * Encrypt and update the vault with the given authentication data.\n *\n * @param params - The parameters for updating the vault.\n * @param params.password - The password to encrypt the vault.\n * @param params.serializedVaultData - The serialized authentication data to update the vault with.\n * @returns A promise that resolves to the updated vault.\n */\n async #updateVault({\n password,\n serializedVaultData,\n }: {\n password: string;\n serializedVaultData: string;\n }): Promise<void> {\n await this.#withVaultLock(async () => {\n assertIsValidPassword(password);\n\n // Note that vault encryption using the password is a very costly operation as it involves deriving the encryption key\n // from the password using an intentionally slow key derivation function.\n // We should make sure that we only call it very intentionally.\n const { vault, exportedKeyString } =\n await this.#vaultEncryptor.encryptWithDetail(\n password,\n serializedVaultData,\n );\n\n this.update((state) => {\n state.vault = vault;\n state.vaultEncryptionKey = exportedKeyString;\n state.vaultEncryptionSalt = JSON.parse(vault).salt;\n });\n });\n }\n\n /**\n * Lock the controller mutex before executing the given function,\n * and release it after the function is resolved or after an\n * error is thrown.\n *\n * This wrapper ensures that each mutable operation that interacts with the\n * controller and that changes its state is executed in a mutually exclusive way,\n * preventing unsafe concurrent access that could lead to unpredictable behavior.\n *\n * @param callback - The function to execute while the controller mutex is locked.\n * @returns The result of the function.\n */\n async #withControllerLock<Result>(\n callback: MutuallyExclusiveCallback<Result>,\n ): Promise<Result> {\n return await withLock(this.#controllerOperationMutex, callback);\n }\n\n /**\n * Lock the vault mutex before executing the given function,\n * and release it after the function is resolved or after an\n * error is thrown.\n *\n * This ensures that each operation that interacts with the vault\n * is executed in a mutually exclusive way.\n *\n * @param callback - The function to execute while the vault mutex is locked.\n * @returns The result of the function.\n */\n async #withVaultLock<Result>(\n callback: MutuallyExclusiveCallback<Result>,\n ): Promise<Result> {\n return await withLock(this.#vaultOperationMutex, callback);\n }\n\n /**\n * Serialize the encryption key and authentication key pair.\n *\n * @param encKey - The encryption key to serialize.\n * @param authKeyPair - The authentication key pair to serialize.\n * @returns The serialized encryption key and authentication key pair.\n */\n #serializeKeyData(\n encKey: Uint8Array,\n authKeyPair: KeyPair,\n ): {\n toprfEncryptionKey: string;\n toprfAuthKeyPair: string;\n } {\n const b64EncodedEncKey = bytesToBase64(encKey);\n const b64EncodedAuthKeyPair = JSON.stringify({\n sk: bigIntToHex(authKeyPair.sk), // Convert BigInt to hex string\n pk: bytesToBase64(authKeyPair.pk),\n });\n\n return {\n toprfEncryptionKey: b64EncodedEncKey,\n toprfAuthKeyPair: b64EncodedAuthKeyPair,\n };\n }\n\n /**\n * Parse and deserialize the authentication data from the vault.\n *\n * @param data - The decrypted vault data.\n * @returns The parsed authentication data.\n * @throws If the vault data is not valid.\n */\n #parseVaultData(data: unknown): {\n nodeAuthTokens: NodeAuthTokens;\n toprfEncryptionKey: Uint8Array;\n toprfAuthKeyPair: KeyPair;\n } {\n if (typeof data !== 'string') {\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.InvalidVaultData,\n );\n }\n\n let parsedVaultData: unknown;\n try {\n parsedVaultData = JSON.parse(data);\n } catch {\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.InvalidVaultData,\n );\n }\n\n this.#assertIsValidVaultData(parsedVaultData);\n\n const rawToprfEncryptionKey = base64ToBytes(\n parsedVaultData.toprfEncryptionKey,\n );\n const parsedToprfAuthKeyPair = JSON.parse(parsedVaultData.toprfAuthKeyPair);\n const rawToprfAuthKeyPair = {\n sk: BigInt(parsedToprfAuthKeyPair.sk),\n pk: base64ToBytes(parsedToprfAuthKeyPair.pk),\n };\n\n return {\n nodeAuthTokens: parsedVaultData.authTokens,\n toprfEncryptionKey: rawToprfEncryptionKey,\n toprfAuthKeyPair: rawToprfAuthKeyPair,\n };\n }\n\n #assertIsUnlocked(): void {\n if (!this.#isUnlocked) {\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.ControllerLocked,\n );\n }\n }\n\n /**\n * Assert that the provided value contains valid authenticated user information.\n *\n * This method checks that the value is an object containing:\n * - nodeAuthTokens: A non-empty array of authentication tokens\n * - authConnectionId: A string identifier for the OAuth connection\n * - groupedAuthConnectionId: A string identifier for grouped OAuth connections\n * - userId: A string identifier for the authenticated user\n *\n * @param value - The value to validate.\n * @throws {Error} If the value does not contain valid authenticated user information.\n */\n #assertIsAuthenticatedUser(\n value: unknown,\n ): asserts value is AuthenticatedUserDetails {\n if (\n !value ||\n typeof value !== 'object' ||\n !('authConnectionId' in value) ||\n typeof value.authConnectionId !== 'string' ||\n !('userId' in value) ||\n typeof value.userId !== 'string'\n ) {\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.MissingAuthUserInfo,\n );\n }\n\n if (\n !('nodeAuthTokens' in value) ||\n typeof value.nodeAuthTokens !== 'object' ||\n !Array.isArray(value.nodeAuthTokens) ||\n value.nodeAuthTokens.length < 3 // At least 3 auth tokens are required for Threshold OPRF service\n ) {\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.InsufficientAuthToken,\n );\n }\n }\n\n #assertIsSRPBackedUpUser(\n value: unknown,\n ): asserts value is SRPBackedUpUserDetails {\n if (!this.state.authPubKey) {\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.SRPNotBackedUpError,\n );\n }\n }\n\n /**\n * Handle the recovery error and update the recovery error data after executing the given callback.\n *\n * @param recoveryCallback - The callback recovery function to execute.\n * @returns The result of the callback function.\n */\n async #withRecoveryErrorHandler(\n recoveryCallback: () => Promise<RecoverEncryptionKeyResult>,\n ): Promise<RecoverEncryptionKeyResult> {\n const currentRecoveryAttempts =\n this.state.recoveryRatelimitCache?.numberOfAttempts || 0;\n let updatedRecoveryAttempts = currentRecoveryAttempts + 1;\n let updatedRemainingTime =\n this.state.recoveryRatelimitCache?.remainingTime || 0;\n\n try {\n const result = await recoveryCallback();\n\n // reset the ratelimit error data\n updatedRecoveryAttempts = 0;\n updatedRemainingTime = 0;\n\n return result;\n } catch (error) {\n const recoveryError = RecoveryError.getInstance(error, {\n numberOfAttempts: updatedRecoveryAttempts,\n remainingTime: updatedRemainingTime,\n });\n\n if (recoveryError.data?.numberOfAttempts) {\n updatedRecoveryAttempts = recoveryError.data.numberOfAttempts;\n }\n\n if (recoveryError.data?.remainingTime) {\n updatedRemainingTime = recoveryError.data.remainingTime;\n }\n\n throw recoveryError;\n } finally {\n this.update((state) => {\n state.recoveryRatelimitCache = {\n numberOfAttempts: updatedRecoveryAttempts,\n remainingTime: updatedRemainingTime,\n };\n });\n }\n }\n\n /**\n * Assert that the password is in sync with the global password.\n *\n * @param options - The options for asserting the password is in sync.\n * @param options.skipCache - Whether to skip the cache check.\n * @param options.skipLock - Whether to skip the lock acquisition.\n * @throws If the password is outdated.\n */\n async #assertPasswordInSync(options?: {\n skipCache?: boolean;\n skipLock?: boolean;\n }): Promise<void> {\n const isPasswordOutdated = await this.checkIsPasswordOutdated(options);\n if (isPasswordOutdated) {\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.OutdatedPassword,\n );\n }\n }\n\n #resetPasswordOutdatedCache(): void {\n this.update((state) => {\n delete state.passwordOutdatedCache;\n });\n }\n\n /**\n * Check if the provided value is a valid vault data.\n *\n * @param value - The value to check.\n * @throws If the value is not a valid vault data.\n */\n #assertIsValidVaultData(value: unknown): asserts value is VaultData {\n // value is not valid vault data if any of the following conditions are true:\n if (\n !value || // value is not defined\n typeof value !== 'object' || // value is not an object\n !('authTokens' in value) || // authTokens is not defined\n typeof value.authTokens !== 'object' || // authTokens is not an object\n !('toprfEncryptionKey' in value) || // toprfEncryptionKey is not defined\n typeof value.toprfEncryptionKey !== 'string' || // toprfEncryptionKey is not a string\n !('toprfAuthKeyPair' in value) || // toprfAuthKeyPair is not defined\n typeof value.toprfAuthKeyPair !== 'string' // toprfAuthKeyPair is not a string\n ) {\n throw new Error(SeedlessOnboardingControllerErrorMessage.VaultDataError);\n }\n }\n}\n\n/**\n * Assert that the provided password is a valid non-empty string.\n *\n * @param password - The password to check.\n * @throws If the password is not a valid string.\n */\nfunction assertIsValidPassword(password: unknown): asserts password is string {\n if (typeof password !== 'string') {\n throw new Error(SeedlessOnboardingControllerErrorMessage.WrongPasswordType);\n }\n\n if (!password || !password.length) {\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.InvalidEmptyPassword,\n );\n }\n}\n\n/**\n * Lock the given mutex before executing the given function,\n * and release it after the function is resolved or after an\n * error is thrown.\n *\n * @param mutex - The mutex to lock.\n * @param callback - The function to execute while the mutex is locked.\n * @returns The result of the function.\n */\nasync function withLock<Result>(\n mutex: Mutex,\n callback: MutuallyExclusiveCallback<Result>,\n): Promise<Result> {\n const releaseLock = await mutex.acquire();\n\n try {\n return await callback({ releaseLock });\n } finally {\n releaseLock();\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"SeedlessOnboardingController.mjs","sourceRoot":"","sources":["../src/SeedlessOnboardingController.ts"],"names":[],"mappings":"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","sourcesContent":["import { keccak256AndHexify } from '@metamask/auth-network-utils';\nimport type { StateMetadata } from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport type {\n KeyPair,\n NodeAuthTokens,\n RecoverEncryptionKeyResult,\n SEC1EncodedPublicKey,\n} from '@metamask/toprf-secure-backup';\nimport { ToprfSecureBackup } from '@metamask/toprf-secure-backup';\nimport { base64ToBytes, bytesToBase64, bigIntToHex } from '@metamask/utils';\nimport { secp256k1 } from '@noble/curves/secp256k1';\nimport { Mutex } from 'async-mutex';\n\nimport {\n type AuthConnection,\n controllerName,\n PASSWORD_OUTDATED_CACHE_TTL_MS,\n SecretType,\n SeedlessOnboardingControllerErrorMessage,\n Web3AuthNetwork,\n} from './constants';\nimport { PasswordSyncError, RecoveryError } from './errors';\nimport { projectLogger, createModuleLogger } from './logger';\nimport { SecretMetadata } from './SecretMetadata';\nimport type {\n MutuallyExclusiveCallback,\n SeedlessOnboardingControllerMessenger,\n SeedlessOnboardingControllerOptions,\n SeedlessOnboardingControllerState,\n VaultData,\n AuthenticatedUserDetails,\n SocialBackupsMetadata,\n SRPBackedUpUserDetails,\n VaultEncryptor,\n} from './types';\n\nconst log = createModuleLogger(projectLogger, controllerName);\n\n/**\n * Get the default state for the Seedless Onboarding Controller.\n *\n * @returns The default state for the Seedless Onboarding Controller.\n */\nexport function getDefaultSeedlessOnboardingControllerState(): SeedlessOnboardingControllerState {\n return {\n socialBackupsMetadata: [],\n };\n}\n\n/**\n * Seedless Onboarding Controller State Metadata.\n *\n * This allows us to choose if fields of the state should be persisted or not\n * using the `persist` flag; and if they can be sent to Sentry or not, using\n * the `anonymous` flag.\n */\nconst seedlessOnboardingMetadata: StateMetadata<SeedlessOnboardingControllerState> =\n {\n vault: {\n persist: true,\n anonymous: false,\n },\n socialBackupsMetadata: {\n persist: true,\n anonymous: true,\n },\n nodeAuthTokens: {\n persist: true,\n anonymous: true,\n },\n authConnection: {\n persist: true,\n anonymous: true,\n },\n authConnectionId: {\n persist: true,\n anonymous: true,\n },\n groupedAuthConnectionId: {\n persist: true,\n anonymous: true,\n },\n userId: {\n persist: true,\n anonymous: true,\n },\n socialLoginEmail: {\n persist: true,\n anonymous: true,\n },\n vaultEncryptionKey: {\n persist: false,\n anonymous: true,\n },\n vaultEncryptionSalt: {\n persist: false,\n anonymous: true,\n },\n authPubKey: {\n persist: true,\n anonymous: true,\n },\n passwordOutdatedCache: {\n persist: true,\n anonymous: true,\n },\n recoveryRatelimitCache: {\n persist: true,\n anonymous: true,\n },\n };\n\nexport class SeedlessOnboardingController<\n EncryptionKey,\n SupportedKeyDerivationOptions,\n> extends BaseController<\n typeof controllerName,\n SeedlessOnboardingControllerState,\n SeedlessOnboardingControllerMessenger\n> {\n readonly #vaultEncryptor: VaultEncryptor<\n EncryptionKey,\n SupportedKeyDerivationOptions\n >;\n\n readonly #controllerOperationMutex = new Mutex();\n\n readonly #vaultOperationMutex = new Mutex();\n\n readonly toprfClient: ToprfSecureBackup;\n\n /**\n * Controller lock state.\n *\n * The controller lock is synchronized with the keyring lock.\n */\n #isUnlocked = false;\n\n /**\n * Creates a new SeedlessOnboardingController instance.\n *\n * @param options - The options for the SeedlessOnboardingController.\n * @param options.messenger - A restricted messenger.\n * @param options.state - Initial state to set on this controller.\n * @param options.encryptor - An optional encryptor to use for encrypting and decrypting seedless onboarding vault.\n * @param options.toprfKeyDeriver - An optional key derivation interface for the TOPRF client.\n * @param options.network - The network to be used for the Seedless Onboarding flow.\n */\n constructor({\n messenger,\n state,\n encryptor,\n toprfKeyDeriver,\n network = Web3AuthNetwork.Mainnet,\n }: SeedlessOnboardingControllerOptions<\n EncryptionKey,\n SupportedKeyDerivationOptions\n >) {\n super({\n name: controllerName,\n metadata: seedlessOnboardingMetadata,\n state: {\n ...getDefaultSeedlessOnboardingControllerState(),\n ...state,\n },\n messenger,\n });\n\n this.#vaultEncryptor = encryptor;\n this.toprfClient = new ToprfSecureBackup({\n network,\n keyDeriver: toprfKeyDeriver,\n });\n\n // setup subscriptions to the keyring lock event\n // when the keyring is locked (wallet is locked), the controller will be cleared of its credentials\n this.messagingSystem.subscribe('KeyringController:lock', () => {\n this.setLocked();\n });\n this.messagingSystem.subscribe('KeyringController:unlock', () => {\n this.#setUnlocked();\n });\n }\n\n /**\n * Authenticate OAuth user using the seedless onboarding flow\n * and determine if the user is already registered or not.\n *\n * @param params - The parameters for authenticate OAuth user.\n * @param params.idTokens - The ID token(s) issued by OAuth verification service. Currently this array only contains a single idToken which is verified by all the nodes, in future we are considering to issue a unique idToken for each node.\n * @param params.authConnection - The social login provider.\n * @param params.authConnectionId - OAuth authConnectionId from dashboard\n * @param params.userId - user email or id from Social login\n * @param params.groupedAuthConnectionId - Optional grouped authConnectionId to be used for the authenticate request.\n * @param params.socialLoginEmail - The user email from Social login.\n * You can pass this to use aggregate multiple OAuth connections. Useful when you want user to have same account while using different OAuth connections.\n * @returns A promise that resolves to the authentication result.\n */\n async authenticate(params: {\n idTokens: string[];\n authConnection: AuthConnection;\n authConnectionId: string;\n userId: string;\n groupedAuthConnectionId?: string;\n socialLoginEmail?: string;\n }) {\n return await this.#withControllerLock(async () => {\n try {\n const {\n idTokens,\n authConnectionId,\n groupedAuthConnectionId,\n userId,\n authConnection,\n socialLoginEmail,\n } = params;\n\n const authenticationResult = await this.toprfClient.authenticate({\n authConnectionId,\n userId,\n idTokens,\n groupedAuthConnectionId,\n });\n // update the state with the authenticated user info\n this.update((state) => {\n state.nodeAuthTokens = authenticationResult.nodeAuthTokens;\n state.authConnectionId = authConnectionId;\n state.groupedAuthConnectionId = groupedAuthConnectionId;\n state.userId = userId;\n state.authConnection = authConnection;\n state.socialLoginEmail = socialLoginEmail;\n });\n return authenticationResult;\n } catch (error) {\n log('Error authenticating user', error);\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.AuthenticationError,\n );\n }\n });\n }\n\n /**\n * Create a new TOPRF encryption key using given password and backups the provided seed phrase.\n *\n * @param password - The password used to create new wallet and seedphrase\n * @param seedPhrase - The seed phrase to backup\n * @param keyringId - The keyring id of the backup seed phrase\n * @returns A promise that resolves to the encrypted seed phrase and the encryption key.\n */\n async createToprfKeyAndBackupSeedPhrase(\n password: string,\n seedPhrase: Uint8Array,\n keyringId: string,\n ): Promise<void> {\n // to make sure that fail fast,\n // assert that the user is authenticated before creating the TOPRF key and backing up the seed phrase\n this.#assertIsAuthenticatedUser(this.state);\n\n return await this.#withControllerLock(async () => {\n // locally evaluate the encryption key from the password\n const { encKey, authKeyPair, oprfKey } =\n await this.toprfClient.createLocalKey({\n password,\n });\n\n // encrypt and store the seed phrase backup\n await this.#encryptAndStoreSecretData({\n data: seedPhrase,\n type: SecretType.Mnemonic,\n encKey,\n authKeyPair,\n options: {\n keyringId,\n },\n });\n\n // store/persist the encryption key shares\n // We store the seed phrase metadata in the metadata store first. If this operation fails,\n // we avoid persisting the encryption key shares to prevent a situation where a user appears\n // to have an account but with no associated data.\n await this.#persistOprfKey(oprfKey, authKeyPair.pk);\n // create a new vault with the resulting authentication data\n await this.#createNewVaultWithAuthData({\n password,\n rawToprfEncryptionKey: encKey,\n rawToprfAuthKeyPair: authKeyPair,\n });\n this.#persistAuthPubKey({\n authPubKey: authKeyPair.pk,\n });\n });\n }\n\n /**\n * encrypt and add a new secret data to the metadata store.\n *\n * @param data - The data to add.\n * @param type - The type of the secret data.\n * @param options - Optional options object, which includes optional data to be added to the metadata store.\n * @param options.keyringId - The keyring id of the backup keyring (SRP).\n * @returns A promise that resolves to the success of the operation.\n */\n async addNewSecretData(\n data: Uint8Array,\n type: SecretType,\n options?: {\n keyringId?: string;\n },\n ): Promise<void> {\n return await this.#withControllerLock(async () => {\n this.#assertIsUnlocked();\n\n await this.#assertPasswordInSync({\n skipCache: true,\n skipLock: true, // skip lock since we already have the lock\n });\n\n // verify the password and unlock the vault\n const { toprfEncryptionKey, toprfAuthKeyPair } =\n await this.#unlockVaultAndGetBackupEncKey();\n\n // encrypt and store the seed phrase backup\n await this.#encryptAndStoreSecretData({\n data,\n type,\n encKey: toprfEncryptionKey,\n authKeyPair: toprfAuthKeyPair,\n options,\n });\n });\n }\n\n /**\n * Fetches all encrypted secret data and metadata for user's account from the metadata store.\n *\n * Decrypts the secret data and returns the decrypted secret data using the recovered encryption key from the password.\n *\n * @param password - The optional password used to create new wallet and seedphrase. If not provided, `cached Encryption Key` will be used.\n * @returns A promise that resolves to the secret data.\n */\n async fetchAllSecretData(\n password?: string,\n ): Promise<Record<SecretType, Uint8Array[]>> {\n // assert that the user is authenticated before fetching the seed phrases\n this.#assertIsAuthenticatedUser(this.state);\n\n return await this.#withControllerLock(async () => {\n let encKey: Uint8Array;\n let authKeyPair: KeyPair;\n\n if (password) {\n const recoverEncKeyResult = await this.#recoverEncKey(password);\n encKey = recoverEncKeyResult.encKey;\n authKeyPair = recoverEncKeyResult.authKeyPair;\n } else {\n this.#assertIsUnlocked();\n // verify the password and unlock the vault\n const keysFromVault = await this.#unlockVaultAndGetBackupEncKey();\n encKey = keysFromVault.toprfEncryptionKey;\n authKeyPair = keysFromVault.toprfAuthKeyPair;\n }\n\n try {\n const secretData = await this.toprfClient.fetchAllSecretDataItems({\n decKey: encKey,\n authKeyPair,\n });\n\n if (secretData?.length > 0 && password) {\n // if password is provided, we need to create a new vault with the auth data. (supposedly the user is trying to rehydrate the wallet)\n await this.#createNewVaultWithAuthData({\n password,\n rawToprfEncryptionKey: encKey,\n rawToprfAuthKeyPair: authKeyPair,\n });\n\n this.#persistAuthPubKey({\n authPubKey: authKeyPair.pk,\n });\n }\n\n const result: Record<SecretType, Uint8Array[]> = {\n mnemonic: [],\n privateKey: [],\n };\n const secrets =\n SecretMetadata.parseSecretsFromMetadataStore(secretData);\n\n secrets.forEach((secret) => {\n result[secret.type].push(secret.data);\n });\n\n return result;\n } catch (error) {\n log('Error fetching seed phrase metadata', error);\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.FailedToFetchSeedPhraseMetadata,\n );\n }\n });\n }\n\n /**\n * Update the password of the seedless onboarding flow.\n *\n * Changing password will also update the encryption key, metadata store and the vault with new encrypted values.\n *\n * @param newPassword - The new password to update.\n * @param oldPassword - The old password to verify.\n * @returns A promise that resolves to the success of the operation.\n */\n async changePassword(newPassword: string, oldPassword: string) {\n return await this.#withControllerLock(async () => {\n this.#assertIsUnlocked();\n // verify the old password of the encrypted vault\n await this.verifyVaultPassword(oldPassword, {\n skipLock: true, // skip lock since we already have the lock\n });\n await this.#assertPasswordInSync({\n skipCache: true,\n skipLock: true, // skip lock since we already have the lock\n });\n\n try {\n // update the encryption key with new password and update the Metadata Store\n const { encKey: newEncKey, authKeyPair: newAuthKeyPair } =\n await this.#changeEncryptionKey(newPassword, oldPassword);\n\n // update and encrypt the vault with new password\n await this.#createNewVaultWithAuthData({\n password: newPassword,\n rawToprfEncryptionKey: newEncKey,\n rawToprfAuthKeyPair: newAuthKeyPair,\n });\n\n this.#persistAuthPubKey({\n authPubKey: newAuthKeyPair.pk,\n });\n this.#resetPasswordOutdatedCache();\n } catch (error) {\n log('Error changing password', error);\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.FailedToChangePassword,\n );\n }\n });\n }\n\n /**\n * Update the backup metadata state for the given seed phrase.\n *\n * @param data - The data to backup, can be a single backup or array of backups.\n * @param data.keyringId - The keyring id associated with the backup seed phrase.\n * @param data.seedPhrase - The seed phrase to update the backup metadata state.\n */\n updateBackupMetadataState(\n data:\n | {\n keyringId: string;\n seedPhrase: Uint8Array;\n }\n | {\n keyringId: string;\n seedPhrase: Uint8Array;\n }[],\n ) {\n this.#assertIsUnlocked();\n\n this.#filterDupesAndUpdateSocialBackupsMetadata(data);\n }\n\n /**\n * Verify the password validity by decrypting the vault.\n *\n * @param password - The password to verify.\n * @param options - Optional options object.\n * @param options.skipLock - Whether to skip the lock acquisition.\n * @returns A promise that resolves to the success of the operation.\n * @throws {Error} If the password is invalid or the vault is not initialized.\n */\n async verifyVaultPassword(\n password: string,\n options?: {\n skipLock?: boolean;\n },\n ): Promise<void> {\n const doVerify = async () => {\n if (!this.state.vault) {\n throw new Error(SeedlessOnboardingControllerErrorMessage.VaultError);\n }\n await this.#vaultEncryptor.decrypt(password, this.state.vault);\n };\n return options?.skipLock\n ? await doVerify()\n : await this.#withControllerLock(doVerify);\n }\n\n /**\n * Get the hash of the seed phrase backup for the given seed phrase, from the state.\n *\n * If the given seed phrase is not backed up and not found in the state, it will return `undefined`.\n *\n * @param seedPhrase - The seed phrase to get the hash of.\n * @returns A promise that resolves to the hash of the seed phrase backup.\n */\n getSeedPhraseBackupHash(\n seedPhrase: Uint8Array,\n ): SocialBackupsMetadata | undefined {\n const seedPhraseHash = keccak256AndHexify(seedPhrase);\n return this.state.socialBackupsMetadata.find(\n (backup) => backup.hash === seedPhraseHash,\n );\n }\n\n /**\n * Submit the password to the controller, verify the password validity and unlock the controller.\n *\n * This method will be used especially when user rehydrate/unlock the wallet.\n * The provided password will be verified against the encrypted vault, encryption key will be derived and saved in the controller state.\n *\n * This operation is useful when user performs some actions that requires the user password/encryption key. e.g. add new srp backup\n *\n * @param password - The password to submit.\n * @returns A promise that resolves to the success of the operation.\n */\n async submitPassword(password: string): Promise<void> {\n return await this.#withControllerLock(async () => {\n await this.#unlockVaultAndGetBackupEncKey(password);\n this.#setUnlocked();\n });\n }\n\n /**\n * Set the controller to locked state, and deallocate the secrets (vault encryption key and salt).\n *\n * When the controller is locked, the user will not be able to perform any operations on the controller/vault.\n */\n setLocked() {\n this.update((state) => {\n delete state.vaultEncryptionKey;\n delete state.vaultEncryptionSalt;\n });\n\n this.#isUnlocked = false;\n }\n\n /**\n * Sync the latest global password to the controller.\n * reset vault with latest globalPassword,\n * persist the latest global password authPubKey\n *\n * @param params - The parameters for syncing the latest global password.\n * @param params.oldPassword - The old password to verify.\n * @param params.globalPassword - The latest global password.\n * @returns A promise that resolves to the success of the operation.\n */\n async syncLatestGlobalPassword({\n oldPassword,\n globalPassword,\n }: {\n oldPassword: string;\n globalPassword: string;\n }) {\n return await this.#withControllerLock(async () => {\n // verify correct old password\n await this.verifyVaultPassword(oldPassword, {\n skipLock: true, // skip lock since we already have the lock\n });\n // update vault with latest globalPassword\n const { encKey, authKeyPair } = await this.#recoverEncKey(globalPassword);\n // update and encrypt the vault with new password\n await this.#createNewVaultWithAuthData({\n password: globalPassword,\n rawToprfEncryptionKey: encKey,\n rawToprfAuthKeyPair: authKeyPair,\n });\n // persist the latest global password authPubKey\n this.#persistAuthPubKey({\n authPubKey: authKeyPair.pk,\n });\n this.#resetPasswordOutdatedCache();\n });\n }\n\n /**\n * @description Fetch the password corresponding to the current authPubKey in state (current device password which is already out of sync with the current global password).\n * then we use this recovered old password to unlock the vault and set the password to the new global password.\n *\n * @param params - The parameters for fetching the password.\n * @param params.globalPassword - The latest global password.\n * @returns A promise that resolves to the password corresponding to the current authPubKey in state.\n */\n async recoverCurrentDevicePassword({\n globalPassword,\n }: {\n globalPassword: string;\n }): Promise<{ password: string }> {\n return await this.#withControllerLock(async () => {\n const currentDeviceAuthPubKey = this.#recoverAuthPubKey();\n const { password: currentDevicePassword } = await this.#recoverPassword({\n targetPwPubKey: currentDeviceAuthPubKey,\n globalPassword,\n });\n return {\n password: currentDevicePassword,\n };\n });\n }\n\n /**\n * @description Fetch the password corresponding to the targetPwPubKey.\n *\n * @param params - The parameters for fetching the password.\n * @param params.targetPwPubKey - The target public key of the password to recover.\n * @param params.globalPassword - The latest global password.\n * @returns A promise that resolves to the password corresponding to the current authPubKey in state.\n */\n async #recoverPassword({\n targetPwPubKey,\n globalPassword,\n }: {\n targetPwPubKey: SEC1EncodedPublicKey;\n globalPassword: string;\n }): Promise<{ password: string }> {\n const { encKey: latestPwEncKey, authKeyPair: latestPwAuthKeyPair } =\n await this.#recoverEncKey(globalPassword);\n\n try {\n const res = await this.toprfClient.recoverPassword({\n targetPwPubKey,\n curEncKey: latestPwEncKey,\n curAuthKeyPair: latestPwAuthKeyPair,\n });\n return res;\n } catch (error) {\n throw PasswordSyncError.getInstance(error);\n }\n }\n\n /**\n * @description Check if the current password is outdated compare to the global password.\n *\n * @param options - Optional options object.\n * @param options.skipCache - If true, bypass the cache and force a fresh check.\n * @param options.skipLock - Whether to skip the lock acquisition.\n * @returns A promise that resolves to true if the password is outdated, false otherwise.\n */\n async checkIsPasswordOutdated(options?: {\n skipCache?: boolean;\n skipLock?: boolean;\n }): Promise<boolean> {\n // cache result to reduce load on infra\n // Check cache first unless skipCache is true\n if (!options?.skipCache) {\n const { passwordOutdatedCache } = this.state;\n const now = Date.now();\n const isCacheValid =\n passwordOutdatedCache &&\n now - passwordOutdatedCache.timestamp < PASSWORD_OUTDATED_CACHE_TTL_MS;\n\n if (isCacheValid) {\n return passwordOutdatedCache.isExpiredPwd;\n }\n }\n\n const doCheck = async () => {\n this.#assertIsAuthenticatedUser(this.state);\n const {\n nodeAuthTokens,\n authConnectionId,\n groupedAuthConnectionId,\n userId,\n } = this.state;\n\n const currentDeviceAuthPubKey = this.#recoverAuthPubKey();\n\n const { authPubKey: globalAuthPubKey } =\n await this.toprfClient.fetchAuthPubKey({\n nodeAuthTokens,\n authConnectionId,\n groupedAuthConnectionId,\n userId,\n });\n\n // use noble lib to deserialize and compare curve point\n const isExpiredPwd = !secp256k1.ProjectivePoint.fromHex(\n currentDeviceAuthPubKey,\n ).equals(secp256k1.ProjectivePoint.fromHex(globalAuthPubKey));\n // Cache the result in state\n this.update((state) => {\n state.passwordOutdatedCache = { isExpiredPwd, timestamp: Date.now() };\n });\n return isExpiredPwd;\n };\n\n return options?.skipLock\n ? await doCheck()\n : await this.#withControllerLock(doCheck);\n }\n\n #setUnlocked(): void {\n this.#isUnlocked = true;\n }\n\n /**\n * Clears the current state of the SeedlessOnboardingController.\n */\n clearState() {\n const defaultState = getDefaultSeedlessOnboardingControllerState();\n this.update(() => {\n return defaultState;\n });\n }\n\n /**\n * Persist the encryption key for the seedless onboarding flow.\n *\n * @param oprfKey - The OPRF key to be splited and persisted.\n * @param authPubKey - The authentication public key.\n * @returns A promise that resolves to the success of the operation.\n */\n async #persistOprfKey(oprfKey: bigint, authPubKey: SEC1EncodedPublicKey) {\n this.#assertIsAuthenticatedUser(this.state);\n const { authConnectionId, groupedAuthConnectionId, userId } = this.state;\n\n try {\n await this.toprfClient.persistLocalKey({\n nodeAuthTokens: this.state.nodeAuthTokens,\n authConnectionId,\n groupedAuthConnectionId,\n userId,\n oprfKey,\n authPubKey,\n });\n } catch (error) {\n log('Error persisting local encryption key', error);\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.FailedToPersistOprfKey,\n );\n }\n }\n\n /**\n * Persist the authentication public key for the seedless onboarding flow.\n * convert to suitable format before persisting.\n *\n * @param params - The parameters for persisting the authentication public key.\n * @param params.authPubKey - The authentication public key to be persisted.\n */\n #persistAuthPubKey(params: { authPubKey: SEC1EncodedPublicKey }): void {\n this.update((state) => {\n state.authPubKey = bytesToBase64(params.authPubKey);\n });\n }\n\n /**\n * Recover the authentication public key from the state.\n * convert to pubkey format before recovering.\n *\n * @returns The authentication public key.\n */\n #recoverAuthPubKey(): SEC1EncodedPublicKey {\n this.#assertIsSRPBackedUpUser(this.state);\n const { authPubKey } = this.state;\n\n return base64ToBytes(authPubKey);\n }\n\n /**\n * Recover the encryption key from password.\n *\n * @param password - The password used to derive/recover the encryption key.\n * @returns A promise that resolves to the encryption key and authentication key pair.\n * @throws RecoveryError - If failed to recover the encryption key.\n */\n async #recoverEncKey(password: string) {\n return this.#withRecoveryErrorHandler(async () => {\n this.#assertIsAuthenticatedUser(this.state);\n\n const { authConnectionId, groupedAuthConnectionId, userId } = this.state;\n\n const recoverEncKeyResult = await this.toprfClient.recoverEncKey({\n nodeAuthTokens: this.state.nodeAuthTokens,\n password,\n authConnectionId,\n groupedAuthConnectionId,\n userId,\n });\n return recoverEncKeyResult;\n });\n }\n\n /**\n * Update the encryption key with new password and update the Metadata Store with new encryption key.\n *\n * @param newPassword - The new password to update.\n * @param oldPassword - The old password to verify.\n * @returns A promise that resolves to new encryption key and authentication key pair.\n */\n async #changeEncryptionKey(newPassword: string, oldPassword: string) {\n this.#assertIsAuthenticatedUser(this.state);\n const { authConnectionId, groupedAuthConnectionId, userId } = this.state;\n\n const {\n encKey,\n authKeyPair,\n keyShareIndex: newKeyShareIndex,\n } = await this.#recoverEncKey(oldPassword);\n\n return await this.toprfClient.changeEncKey({\n nodeAuthTokens: this.state.nodeAuthTokens,\n authConnectionId,\n groupedAuthConnectionId,\n userId,\n oldEncKey: encKey,\n oldAuthKeyPair: authKeyPair,\n newKeyShareIndex,\n oldPassword,\n newPassword,\n });\n }\n\n /**\n * Encrypt and store the seed phrase backup in the metadata store.\n *\n * @param params - The parameters for encrypting and storing the seed phrase backup.\n * @param params.data - The seed phrase to store.\n * @param params.type - The type of the secret data.\n * @param params.encKey - The encryption key to store.\n * @param params.authKeyPair - The authentication key pair to store.\n * @param params.options - Optional options object, which includes optional data to be added to the metadata store.\n * @param params.options.keyringId - The keyring id of the backup keyring (SRP).\n *\n * @returns A promise that resolves to the success of the operation.\n */\n async #encryptAndStoreSecretData(params: {\n data: Uint8Array;\n type: SecretType;\n encKey: Uint8Array;\n authKeyPair: KeyPair;\n options?: {\n keyringId?: string;\n };\n }): Promise<void> {\n const { options, data, encKey, authKeyPair, type } = params;\n\n const secretMetadata = new SecretMetadata(data, {\n type,\n });\n const secretData = secretMetadata.toBytes();\n\n const keyringId = options?.keyringId as string;\n if (type === SecretType.Mnemonic && !keyringId) {\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.MissingKeyringId,\n );\n }\n\n try {\n if (type === SecretType.Mnemonic) {\n await this.#withPersistedSeedPhraseBackupsState(async () => {\n await this.toprfClient.addSecretDataItem({\n encKey,\n secretData,\n authKeyPair,\n });\n return {\n keyringId,\n seedPhrase: data,\n };\n });\n return;\n }\n\n await this.toprfClient.addSecretDataItem({\n encKey,\n secretData,\n authKeyPair,\n });\n } catch (error) {\n log('Error encrypting and storing seed phrase backup', error);\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.FailedToEncryptAndStoreSeedPhraseBackup,\n );\n }\n }\n\n /**\n * Unlocks the encrypted vault using the provided password and returns the decrypted vault data.\n * This method ensures thread-safety by using a mutex lock when accessing the vault.\n *\n * @param password - The optional password to unlock the vault.\n * @returns A promise that resolves to an object containing:\n * - nodeAuthTokens: Authentication tokens to communicate with the TOPRF service\n * - toprfEncryptionKey: The decrypted TOPRF encryption key\n * - toprfAuthKeyPair: The decrypted TOPRF authentication key pair\n * @throws {Error} If:\n * - The password is invalid or empty\n * - The vault is not initialized\n * - The password is incorrect (from encryptor.decrypt)\n * - The decrypted vault data is malformed\n */\n async #unlockVaultAndGetBackupEncKey(password?: string): Promise<{\n nodeAuthTokens: NodeAuthTokens;\n toprfEncryptionKey: Uint8Array;\n toprfAuthKeyPair: KeyPair;\n }> {\n return this.#withVaultLock(async () => {\n const {\n vault: encryptedVault,\n vaultEncryptionKey,\n vaultEncryptionSalt,\n } = this.state;\n\n if (!encryptedVault) {\n throw new Error(SeedlessOnboardingControllerErrorMessage.VaultError);\n }\n\n if (!vaultEncryptionKey && !password) {\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.MissingCredentials,\n );\n }\n\n let decryptedVaultData: unknown;\n const updatedState: Partial<SeedlessOnboardingControllerState> = {};\n\n if (password) {\n assertIsValidPassword(password);\n // Note that vault decryption using the password is a very costly operation as it involves deriving the encryption key\n // from the password using an intentionally slow key derivation function.\n // We should make sure that we only call it very intentionally.\n const result = await this.#vaultEncryptor.decryptWithDetail(\n password,\n encryptedVault,\n );\n decryptedVaultData = result.vault;\n updatedState.vaultEncryptionKey = result.exportedKeyString;\n updatedState.vaultEncryptionSalt = result.salt;\n } else {\n const parsedEncryptedVault = JSON.parse(encryptedVault);\n\n if (vaultEncryptionSalt !== parsedEncryptedVault.salt) {\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.ExpiredCredentials,\n );\n }\n\n if (typeof vaultEncryptionKey !== 'string') {\n throw new TypeError(\n SeedlessOnboardingControllerErrorMessage.WrongPasswordType,\n );\n }\n\n const key = await this.#vaultEncryptor.importKey(vaultEncryptionKey);\n decryptedVaultData = await this.#vaultEncryptor.decryptWithKey(\n key,\n parsedEncryptedVault,\n );\n updatedState.vaultEncryptionKey = vaultEncryptionKey;\n updatedState.vaultEncryptionSalt = vaultEncryptionSalt;\n }\n\n const { nodeAuthTokens, toprfEncryptionKey, toprfAuthKeyPair } =\n this.#parseVaultData(decryptedVaultData);\n\n // update the state with the restored nodeAuthTokens\n this.update((state) => {\n state.nodeAuthTokens = nodeAuthTokens;\n state.vaultEncryptionKey = updatedState.vaultEncryptionKey;\n state.vaultEncryptionSalt = updatedState.vaultEncryptionSalt;\n });\n\n return { nodeAuthTokens, toprfEncryptionKey, toprfAuthKeyPair };\n });\n }\n\n /**\n * Executes a callback function that creates or restores seed phrases and persists their hashes in the controller state.\n *\n * This method:\n * 1. Executes the provided callback to create/restore seed phrases\n * 2. Generates keccak256 hashes of the seed phrases\n * 3. Merges new hashes with existing ones in the state, ensuring uniqueness\n * 4. Updates the controller state with the combined hashes\n *\n * This is a wrapper method that should be used around any operation that creates\n * or restores seed phrases to ensure their hashes are properly tracked.\n *\n * @param createSeedPhraseBackupCallback - function that returns either a single seed phrase\n * or an array of seed phrases as Uint8Array(s)\n * @returns The original seed phrase(s) returned by the callback\n * @throws Rethrows any errors from the callback with additional logging\n */\n async #withPersistedSeedPhraseBackupsState(\n createSeedPhraseBackupCallback: () => Promise<{\n keyringId: string;\n seedPhrase: Uint8Array;\n }>,\n ): Promise<{\n keyringId: string;\n seedPhrase: Uint8Array;\n }> {\n try {\n const newBackup = await createSeedPhraseBackupCallback();\n\n this.#filterDupesAndUpdateSocialBackupsMetadata(newBackup);\n\n return newBackup;\n } catch (error) {\n log('Error persisting seed phrase backups', error);\n throw error;\n }\n }\n\n /**\n * Updates the social backups metadata state by adding new unique seed phrase backups.\n * This method ensures no duplicate backups are stored by checking the hash of each seed phrase.\n *\n * @param data - The backup data to add to the state\n * @param data.id - The identifier for the backup\n * @param data.seedPhrase - The seed phrase to backup as a Uint8Array\n */\n #filterDupesAndUpdateSocialBackupsMetadata(\n data:\n | {\n keyringId: string;\n seedPhrase: Uint8Array;\n }\n | {\n keyringId: string;\n seedPhrase: Uint8Array;\n }[],\n ) {\n const currentBackupsMetadata = this.state.socialBackupsMetadata;\n\n const newBackupsMetadata = Array.isArray(data) ? data : [data];\n const filteredNewBackupsMetadata: SocialBackupsMetadata[] = [];\n\n // filter out the backed up metadata that already exists in the state\n // to prevent duplicates\n newBackupsMetadata.forEach((item) => {\n const { keyringId, seedPhrase } = item;\n const backupHash = keccak256AndHexify(seedPhrase);\n\n const backupStateAlreadyExisted = currentBackupsMetadata.some(\n (backup) => backup.hash === backupHash,\n );\n\n if (!backupStateAlreadyExisted) {\n filteredNewBackupsMetadata.push({\n id: keyringId,\n hash: backupHash,\n });\n }\n });\n\n if (filteredNewBackupsMetadata.length > 0) {\n this.update((state) => {\n state.socialBackupsMetadata = [\n ...state.socialBackupsMetadata,\n ...filteredNewBackupsMetadata,\n ];\n });\n }\n }\n\n /**\n * Create a new vault with the given authentication data.\n *\n * Serialize the authentication and key data which will be stored in the vault.\n *\n * @param params - The parameters for creating a new vault.\n * @param params.password - The password to encrypt the vault.\n * @param params.rawToprfEncryptionKey - The encryption key to encrypt the vault.\n * @param params.rawToprfAuthKeyPair - The authentication key pair to encrypt the vault.\n */\n async #createNewVaultWithAuthData({\n password,\n rawToprfEncryptionKey,\n rawToprfAuthKeyPair,\n }: {\n password: string;\n rawToprfEncryptionKey: Uint8Array;\n rawToprfAuthKeyPair: KeyPair;\n }): Promise<void> {\n this.#assertIsAuthenticatedUser(this.state);\n this.#setUnlocked();\n\n const { toprfEncryptionKey, toprfAuthKeyPair } = this.#serializeKeyData(\n rawToprfEncryptionKey,\n rawToprfAuthKeyPair,\n );\n\n const serializedVaultData = JSON.stringify({\n authTokens: this.state.nodeAuthTokens,\n toprfEncryptionKey,\n toprfAuthKeyPair,\n });\n\n await this.#updateVault({\n password,\n serializedVaultData,\n });\n }\n\n /**\n * Encrypt and update the vault with the given authentication data.\n *\n * @param params - The parameters for updating the vault.\n * @param params.password - The password to encrypt the vault.\n * @param params.serializedVaultData - The serialized authentication data to update the vault with.\n * @returns A promise that resolves to the updated vault.\n */\n async #updateVault({\n password,\n serializedVaultData,\n }: {\n password: string;\n serializedVaultData: string;\n }): Promise<void> {\n await this.#withVaultLock(async () => {\n assertIsValidPassword(password);\n\n // Note that vault encryption using the password is a very costly operation as it involves deriving the encryption key\n // from the password using an intentionally slow key derivation function.\n // We should make sure that we only call it very intentionally.\n const { vault, exportedKeyString } =\n await this.#vaultEncryptor.encryptWithDetail(\n password,\n serializedVaultData,\n );\n\n this.update((state) => {\n state.vault = vault;\n state.vaultEncryptionKey = exportedKeyString;\n state.vaultEncryptionSalt = JSON.parse(vault).salt;\n });\n });\n }\n\n /**\n * Lock the controller mutex before executing the given function,\n * and release it after the function is resolved or after an\n * error is thrown.\n *\n * This wrapper ensures that each mutable operation that interacts with the\n * controller and that changes its state is executed in a mutually exclusive way,\n * preventing unsafe concurrent access that could lead to unpredictable behavior.\n *\n * @param callback - The function to execute while the controller mutex is locked.\n * @returns The result of the function.\n */\n async #withControllerLock<Result>(\n callback: MutuallyExclusiveCallback<Result>,\n ): Promise<Result> {\n return await withLock(this.#controllerOperationMutex, callback);\n }\n\n /**\n * Lock the vault mutex before executing the given function,\n * and release it after the function is resolved or after an\n * error is thrown.\n *\n * This ensures that each operation that interacts with the vault\n * is executed in a mutually exclusive way.\n *\n * @param callback - The function to execute while the vault mutex is locked.\n * @returns The result of the function.\n */\n async #withVaultLock<Result>(\n callback: MutuallyExclusiveCallback<Result>,\n ): Promise<Result> {\n return await withLock(this.#vaultOperationMutex, callback);\n }\n\n /**\n * Serialize the encryption key and authentication key pair.\n *\n * @param encKey - The encryption key to serialize.\n * @param authKeyPair - The authentication key pair to serialize.\n * @returns The serialized encryption key and authentication key pair.\n */\n #serializeKeyData(\n encKey: Uint8Array,\n authKeyPair: KeyPair,\n ): {\n toprfEncryptionKey: string;\n toprfAuthKeyPair: string;\n } {\n const b64EncodedEncKey = bytesToBase64(encKey);\n const b64EncodedAuthKeyPair = JSON.stringify({\n sk: bigIntToHex(authKeyPair.sk), // Convert BigInt to hex string\n pk: bytesToBase64(authKeyPair.pk),\n });\n\n return {\n toprfEncryptionKey: b64EncodedEncKey,\n toprfAuthKeyPair: b64EncodedAuthKeyPair,\n };\n }\n\n /**\n * Parse and deserialize the authentication data from the vault.\n *\n * @param data - The decrypted vault data.\n * @returns The parsed authentication data.\n * @throws If the vault data is not valid.\n */\n #parseVaultData(data: unknown): {\n nodeAuthTokens: NodeAuthTokens;\n toprfEncryptionKey: Uint8Array;\n toprfAuthKeyPair: KeyPair;\n } {\n if (typeof data !== 'string') {\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.InvalidVaultData,\n );\n }\n\n let parsedVaultData: unknown;\n try {\n parsedVaultData = JSON.parse(data);\n } catch {\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.InvalidVaultData,\n );\n }\n\n this.#assertIsValidVaultData(parsedVaultData);\n\n const rawToprfEncryptionKey = base64ToBytes(\n parsedVaultData.toprfEncryptionKey,\n );\n const parsedToprfAuthKeyPair = JSON.parse(parsedVaultData.toprfAuthKeyPair);\n const rawToprfAuthKeyPair = {\n sk: BigInt(parsedToprfAuthKeyPair.sk),\n pk: base64ToBytes(parsedToprfAuthKeyPair.pk),\n };\n\n return {\n nodeAuthTokens: parsedVaultData.authTokens,\n toprfEncryptionKey: rawToprfEncryptionKey,\n toprfAuthKeyPair: rawToprfAuthKeyPair,\n };\n }\n\n #assertIsUnlocked(): void {\n if (!this.#isUnlocked) {\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.ControllerLocked,\n );\n }\n }\n\n /**\n * Assert that the provided value contains valid authenticated user information.\n *\n * This method checks that the value is an object containing:\n * - nodeAuthTokens: A non-empty array of authentication tokens\n * - authConnectionId: A string identifier for the OAuth connection\n * - groupedAuthConnectionId: A string identifier for grouped OAuth connections\n * - userId: A string identifier for the authenticated user\n *\n * @param value - The value to validate.\n * @throws {Error} If the value does not contain valid authenticated user information.\n */\n #assertIsAuthenticatedUser(\n value: unknown,\n ): asserts value is AuthenticatedUserDetails {\n if (\n !value ||\n typeof value !== 'object' ||\n !('authConnectionId' in value) ||\n typeof value.authConnectionId !== 'string' ||\n !('userId' in value) ||\n typeof value.userId !== 'string'\n ) {\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.MissingAuthUserInfo,\n );\n }\n\n if (\n !('nodeAuthTokens' in value) ||\n typeof value.nodeAuthTokens !== 'object' ||\n !Array.isArray(value.nodeAuthTokens) ||\n value.nodeAuthTokens.length < 3 // At least 3 auth tokens are required for Threshold OPRF service\n ) {\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.InsufficientAuthToken,\n );\n }\n }\n\n #assertIsSRPBackedUpUser(\n value: unknown,\n ): asserts value is SRPBackedUpUserDetails {\n if (!this.state.authPubKey) {\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.SRPNotBackedUpError,\n );\n }\n }\n\n /**\n * Handle the recovery error and update the recovery error data after executing the given callback.\n *\n * @param recoveryCallback - The callback recovery function to execute.\n * @returns The result of the callback function.\n */\n async #withRecoveryErrorHandler(\n recoveryCallback: () => Promise<RecoverEncryptionKeyResult>,\n ): Promise<RecoverEncryptionKeyResult> {\n const currentRecoveryAttempts =\n this.state.recoveryRatelimitCache?.numberOfAttempts || 0;\n let updatedRecoveryAttempts = currentRecoveryAttempts + 1;\n let updatedRemainingTime =\n this.state.recoveryRatelimitCache?.remainingTime || 0;\n\n try {\n const result = await recoveryCallback();\n\n // reset the ratelimit error data\n updatedRecoveryAttempts = 0;\n updatedRemainingTime = 0;\n\n return result;\n } catch (error) {\n const recoveryError = RecoveryError.getInstance(error, {\n numberOfAttempts: updatedRecoveryAttempts,\n remainingTime: updatedRemainingTime,\n });\n\n if (recoveryError.data?.numberOfAttempts) {\n updatedRecoveryAttempts = recoveryError.data.numberOfAttempts;\n }\n\n if (recoveryError.data?.remainingTime) {\n updatedRemainingTime = recoveryError.data.remainingTime;\n }\n\n throw recoveryError;\n } finally {\n this.update((state) => {\n state.recoveryRatelimitCache = {\n numberOfAttempts: updatedRecoveryAttempts,\n remainingTime: updatedRemainingTime,\n };\n });\n }\n }\n\n /**\n * Assert that the password is in sync with the global password.\n *\n * @param options - The options for asserting the password is in sync.\n * @param options.skipCache - Whether to skip the cache check.\n * @param options.skipLock - Whether to skip the lock acquisition.\n * @throws If the password is outdated.\n */\n async #assertPasswordInSync(options?: {\n skipCache?: boolean;\n skipLock?: boolean;\n }): Promise<void> {\n const isPasswordOutdated = await this.checkIsPasswordOutdated(options);\n if (isPasswordOutdated) {\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.OutdatedPassword,\n );\n }\n }\n\n #resetPasswordOutdatedCache(): void {\n this.update((state) => {\n delete state.passwordOutdatedCache;\n });\n }\n\n /**\n * Check if the provided value is a valid vault data.\n *\n * @param value - The value to check.\n * @throws If the value is not a valid vault data.\n */\n #assertIsValidVaultData(value: unknown): asserts value is VaultData {\n // value is not valid vault data if any of the following conditions are true:\n if (\n !value || // value is not defined\n typeof value !== 'object' || // value is not an object\n !('authTokens' in value) || // authTokens is not defined\n typeof value.authTokens !== 'object' || // authTokens is not an object\n !('toprfEncryptionKey' in value) || // toprfEncryptionKey is not defined\n typeof value.toprfEncryptionKey !== 'string' || // toprfEncryptionKey is not a string\n !('toprfAuthKeyPair' in value) || // toprfAuthKeyPair is not defined\n typeof value.toprfAuthKeyPair !== 'string' // toprfAuthKeyPair is not a string\n ) {\n throw new Error(SeedlessOnboardingControllerErrorMessage.VaultDataError);\n }\n }\n}\n\n/**\n * Assert that the provided password is a valid non-empty string.\n *\n * @param password - The password to check.\n * @throws If the password is not a valid string.\n */\nfunction assertIsValidPassword(password: unknown): asserts password is string {\n if (typeof password !== 'string') {\n throw new Error(SeedlessOnboardingControllerErrorMessage.WrongPasswordType);\n }\n\n if (!password || !password.length) {\n throw new Error(\n SeedlessOnboardingControllerErrorMessage.InvalidEmptyPassword,\n );\n }\n}\n\n/**\n * Lock the given mutex before executing the given function,\n * and release it after the function is resolved or after an\n * error is thrown.\n *\n * @param mutex - The mutex to lock.\n * @param callback - The function to execute while the mutex is locked.\n * @returns The result of the function.\n */\nasync function withLock<Result>(\n mutex: Mutex,\n callback: MutuallyExclusiveCallback<Result>,\n): Promise<Result> {\n const releaseLock = await mutex.acquire();\n\n try {\n return await callback({ releaseLock });\n } finally {\n releaseLock();\n }\n}\n"]}
|
package/dist/types.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.cjs","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { RestrictedMessenger } from '@metamask/base-controller';\nimport type { ControllerGetStateAction } from '@metamask/base-controller';\nimport type { ControllerStateChangeEvent } from '@metamask/base-controller';\nimport type {\n ExportableKeyEncryptor,\n KeyringControllerLockEvent,\n KeyringControllerUnlockEvent,\n} from '@metamask/keyring-controller';\nimport type { NodeAuthTokens } from '@metamask/toprf-secure-backup';\nimport type { MutexInterface } from 'async-mutex';\n\nimport type {\n AuthConnection,\n controllerName,\n SecretMetadataVersion,\n SecretType,\n Web3AuthNetwork,\n} from './constants';\n\nexport type SocialBackupsMetadata = {\n id: string;\n hash: string;\n};\n\nexport type AuthenticatedUserDetails = {\n /**\n * Type of social login provider.\n */\n authConnection: AuthConnection;\n\n /**\n * The node auth tokens from OAuth User authentication after the Social login.\n *\n * This values are used to authenticate users when they go through the Seedless Onboarding flow.\n */\n nodeAuthTokens: NodeAuthTokens;\n\n /**\n * OAuth connection id from web3auth dashboard.\n */\n authConnectionId: string;\n\n /**\n * The optional grouped authConnectionId to authenticate the user with Web3Auth network.\n */\n groupedAuthConnectionId?: string;\n\n /**\n * The user email or ID from Social login.\n */\n userId: string;\n\n /**\n * The user email from Social login.\n */\n socialLoginEmail: string;\n};\n\nexport type SRPBackedUpUserDetails = {\n /**\n * The public key of the authentication key pair in base64 format.\n *\n * This value is used to check if the password is outdated compare to the global password and find backed up old password.\n */\n authPubKey: string;\n};\n\n/**\n * The data of the recovery error.\n */\nexport type RecoveryErrorData = {\n /**\n * The remaining time in seconds before the user can try again.\n */\n remainingTime: number;\n\n /**\n * The number of attempts made by the user.\n */\n numberOfAttempts: number;\n};\n\n// State\nexport type SeedlessOnboardingControllerState =\n Partial<AuthenticatedUserDetails> &\n Partial<SRPBackedUpUserDetails> & {\n /**\n * Encrypted array of serialized keyrings data.\n */\n vault?: string;\n\n /**\n * The hashes of the seed phrase backups.\n *\n * This is to facilitate the UI to display backup status of the seed phrases.\n */\n socialBackupsMetadata: SocialBackupsMetadata[];\n\n /**\n * The encryption key derived from the password and used to encrypt\n * the vault.\n */\n vaultEncryptionKey?: string;\n\n /**\n * The salt used to derive the encryption key from the password.\n */\n vaultEncryptionSalt?: string;\n\n /**\n * Cache for checkIsPasswordOutdated result and timestamp.\n */\n passwordOutdatedCache?: { isExpiredPwd: boolean; timestamp: number };\n\n /**\n * The cached data of the recovery error.\n *\n * This data is used to cache the recovery error data to retrieve the accurate ratelimit remainingTime and numberOfAttempts.\n * And it also helps to synchronize the recovery error data across multiple devices.\n */\n recoveryRatelimitCache?: RecoveryErrorData;\n };\n\n// Actions\nexport type SeedlessOnboardingControllerGetStateAction =\n ControllerGetStateAction<\n typeof controllerName,\n SeedlessOnboardingControllerState\n >;\nexport type SeedlessOnboardingControllerActions =\n SeedlessOnboardingControllerGetStateAction;\n\nexport type AllowedActions = never;\n\n// Events\nexport type SeedlessOnboardingControllerStateChangeEvent =\n ControllerStateChangeEvent<\n typeof controllerName,\n SeedlessOnboardingControllerState\n >;\nexport type SeedlessOnboardingControllerEvents =\n SeedlessOnboardingControllerStateChangeEvent;\n\nexport type AllowedEvents =\n | KeyringControllerLockEvent\n | KeyringControllerUnlockEvent;\n\n// Messenger\nexport type SeedlessOnboardingControllerMessenger = RestrictedMessenger<\n typeof controllerName,\n SeedlessOnboardingControllerActions | AllowedActions,\n SeedlessOnboardingControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n\n/**\n * Encryptor interface for encrypting and decrypting seedless onboarding vault.\n */\nexport type VaultEncryptor<EncryptionKey> = Omit<\n ExportableKeyEncryptor<EncryptionKey>,\n 'encryptWithKey'\n>;\n\n/**\n * Additional key deriver for the TOPRF client.\n *\n * This is a function that takes a seed and salt and returns a key in bytes (Uint8Array).\n * It is used as an additional step during key derivation. This can be used, for example, to inject a slow key\n * derivation step to protect against local brute force attacks on the password.\n *\n * @default browser-passworder @link https://github.com/MetaMask/browser-passworder\n */\nexport type ToprfKeyDeriver = {\n /**\n * Derive a key from a seed and salt.\n *\n * @param seed - The seed to derive the key from.\n * @param salt - The salt to derive the key from.\n * @returns The derived key.\n */\n deriveKey: (seed: Uint8Array, salt: Uint8Array) => Promise<Uint8Array>;\n};\n\n/**\n * Seedless Onboarding Controller Options.\n *\n * @param messenger - The messenger to use for this controller.\n * @param state - The initial state to set on this controller.\n * @param encryptor - The encryptor to use for encrypting and decrypting seedless onboarding vault.\n */\nexport type SeedlessOnboardingControllerOptions
|
|
1
|
+
{"version":3,"file":"types.cjs","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { RestrictedMessenger } from '@metamask/base-controller';\nimport type { ControllerGetStateAction } from '@metamask/base-controller';\nimport type { ControllerStateChangeEvent } from '@metamask/base-controller';\nimport type {\n ExportableKeyEncryptor,\n KeyringControllerLockEvent,\n KeyringControllerUnlockEvent,\n} from '@metamask/keyring-controller';\nimport type { NodeAuthTokens } from '@metamask/toprf-secure-backup';\nimport type { MutexInterface } from 'async-mutex';\n\nimport type {\n AuthConnection,\n controllerName,\n SecretMetadataVersion,\n SecretType,\n Web3AuthNetwork,\n} from './constants';\n\nexport type SocialBackupsMetadata = {\n id: string;\n hash: string;\n};\n\nexport type AuthenticatedUserDetails = {\n /**\n * Type of social login provider.\n */\n authConnection: AuthConnection;\n\n /**\n * The node auth tokens from OAuth User authentication after the Social login.\n *\n * This values are used to authenticate users when they go through the Seedless Onboarding flow.\n */\n nodeAuthTokens: NodeAuthTokens;\n\n /**\n * OAuth connection id from web3auth dashboard.\n */\n authConnectionId: string;\n\n /**\n * The optional grouped authConnectionId to authenticate the user with Web3Auth network.\n */\n groupedAuthConnectionId?: string;\n\n /**\n * The user email or ID from Social login.\n */\n userId: string;\n\n /**\n * The user email from Social login.\n */\n socialLoginEmail: string;\n};\n\nexport type SRPBackedUpUserDetails = {\n /**\n * The public key of the authentication key pair in base64 format.\n *\n * This value is used to check if the password is outdated compare to the global password and find backed up old password.\n */\n authPubKey: string;\n};\n\n/**\n * The data of the recovery error.\n */\nexport type RecoveryErrorData = {\n /**\n * The remaining time in seconds before the user can try again.\n */\n remainingTime: number;\n\n /**\n * The number of attempts made by the user.\n */\n numberOfAttempts: number;\n};\n\n// State\nexport type SeedlessOnboardingControllerState =\n Partial<AuthenticatedUserDetails> &\n Partial<SRPBackedUpUserDetails> & {\n /**\n * Encrypted array of serialized keyrings data.\n */\n vault?: string;\n\n /**\n * The hashes of the seed phrase backups.\n *\n * This is to facilitate the UI to display backup status of the seed phrases.\n */\n socialBackupsMetadata: SocialBackupsMetadata[];\n\n /**\n * The encryption key derived from the password and used to encrypt\n * the vault.\n */\n vaultEncryptionKey?: string;\n\n /**\n * The salt used to derive the encryption key from the password.\n */\n vaultEncryptionSalt?: string;\n\n /**\n * Cache for checkIsPasswordOutdated result and timestamp.\n */\n passwordOutdatedCache?: { isExpiredPwd: boolean; timestamp: number };\n\n /**\n * The cached data of the recovery error.\n *\n * This data is used to cache the recovery error data to retrieve the accurate ratelimit remainingTime and numberOfAttempts.\n * And it also helps to synchronize the recovery error data across multiple devices.\n */\n recoveryRatelimitCache?: RecoveryErrorData;\n };\n\n// Actions\nexport type SeedlessOnboardingControllerGetStateAction =\n ControllerGetStateAction<\n typeof controllerName,\n SeedlessOnboardingControllerState\n >;\nexport type SeedlessOnboardingControllerActions =\n SeedlessOnboardingControllerGetStateAction;\n\nexport type AllowedActions = never;\n\n// Events\nexport type SeedlessOnboardingControllerStateChangeEvent =\n ControllerStateChangeEvent<\n typeof controllerName,\n SeedlessOnboardingControllerState\n >;\nexport type SeedlessOnboardingControllerEvents =\n SeedlessOnboardingControllerStateChangeEvent;\n\nexport type AllowedEvents =\n | KeyringControllerLockEvent\n | KeyringControllerUnlockEvent;\n\n// Messenger\nexport type SeedlessOnboardingControllerMessenger = RestrictedMessenger<\n typeof controllerName,\n SeedlessOnboardingControllerActions | AllowedActions,\n SeedlessOnboardingControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n\n/**\n * Encryptor interface for encrypting and decrypting seedless onboarding vault.\n */\nexport type VaultEncryptor<EncryptionKey, KeyDerivationParams> = Omit<\n ExportableKeyEncryptor<EncryptionKey, KeyDerivationParams>,\n 'encryptWithKey'\n>;\n\n/**\n * Additional key deriver for the TOPRF client.\n *\n * This is a function that takes a seed and salt and returns a key in bytes (Uint8Array).\n * It is used as an additional step during key derivation. This can be used, for example, to inject a slow key\n * derivation step to protect against local brute force attacks on the password.\n *\n * @default browser-passworder @link https://github.com/MetaMask/browser-passworder\n */\nexport type ToprfKeyDeriver = {\n /**\n * Derive a key from a seed and salt.\n *\n * @param seed - The seed to derive the key from.\n * @param salt - The salt to derive the key from.\n * @returns The derived key.\n */\n deriveKey: (seed: Uint8Array, salt: Uint8Array) => Promise<Uint8Array>;\n};\n\n/**\n * Seedless Onboarding Controller Options.\n *\n * @param messenger - The messenger to use for this controller.\n * @param state - The initial state to set on this controller.\n * @param encryptor - The encryptor to use for encrypting and decrypting seedless onboarding vault.\n */\nexport type SeedlessOnboardingControllerOptions<\n EncryptionKey,\n SupportedKeyDerivationOptions,\n> = {\n messenger: SeedlessOnboardingControllerMessenger;\n\n /**\n * Initial state to set on this controller.\n */\n state?: Partial<SeedlessOnboardingControllerState>;\n\n /**\n * Encryptor to use for encrypting and decrypting seedless onboarding vault.\n *\n * @default browser-passworder @link https://github.com/MetaMask/browser-passworder\n */\n encryptor: VaultEncryptor<EncryptionKey, SupportedKeyDerivationOptions>;\n\n /**\n * Optional key derivation interface for the TOPRF client.\n *\n * If provided, it will be used as an additional step during\n * key derivation. This can be used, for example, to inject a slow key\n * derivation step to protect against local brute force attacks on the\n * password.\n *\n * @default browser-passworder @link https://github.com/MetaMask/browser-passworder\n */\n toprfKeyDeriver?: ToprfKeyDeriver;\n\n /**\n * Type of Web3Auth network to be used for the Seedless Onboarding flow.\n *\n * @default Web3AuthNetwork.Mainnet\n */\n network?: Web3AuthNetwork;\n};\n\n/**\n * A function executed within a mutually exclusive lock, with\n * a mutex releaser in its option bag.\n *\n * @param releaseLock - A function to release the lock.\n */\nexport type MutuallyExclusiveCallback<Result> = ({\n releaseLock,\n}: {\n releaseLock: MutexInterface.Releaser;\n}) => Promise<Result>;\n\n/**\n * The structure of the data which is serialized and stored in the vault.\n */\nexport type VaultData = {\n /**\n * The node auth tokens from OAuth User authentication after the Social login.\n */\n authTokens: NodeAuthTokens;\n /**\n * The encryption key to encrypt the seed phrase.\n */\n toprfEncryptionKey: string;\n /**\n * The authentication key pair to authenticate the TOPRF.\n */\n toprfAuthKeyPair: string;\n};\n\nexport type SecretDataType = Uint8Array | string | number;\n\n/**\n * The constructor options for the seed phrase metadata.\n */\nexport type SecretMetadataOptions = {\n /**\n * The timestamp when the seed phrase was created.\n */\n timestamp: number;\n /**\n * The type of the seed phrase.\n */\n type: SecretType;\n /**\n * The version of the seed phrase metadata.\n */\n version: SecretMetadataVersion;\n};\n"]}
|
package/dist/types.d.cts
CHANGED
|
@@ -103,7 +103,7 @@ export type SeedlessOnboardingControllerMessenger = RestrictedMessenger<typeof c
|
|
|
103
103
|
/**
|
|
104
104
|
* Encryptor interface for encrypting and decrypting seedless onboarding vault.
|
|
105
105
|
*/
|
|
106
|
-
export type VaultEncryptor<EncryptionKey> = Omit<ExportableKeyEncryptor<EncryptionKey>, 'encryptWithKey'>;
|
|
106
|
+
export type VaultEncryptor<EncryptionKey, KeyDerivationParams> = Omit<ExportableKeyEncryptor<EncryptionKey, KeyDerivationParams>, 'encryptWithKey'>;
|
|
107
107
|
/**
|
|
108
108
|
* Additional key deriver for the TOPRF client.
|
|
109
109
|
*
|
|
@@ -130,7 +130,7 @@ export type ToprfKeyDeriver = {
|
|
|
130
130
|
* @param state - The initial state to set on this controller.
|
|
131
131
|
* @param encryptor - The encryptor to use for encrypting and decrypting seedless onboarding vault.
|
|
132
132
|
*/
|
|
133
|
-
export type SeedlessOnboardingControllerOptions<EncryptionKey> = {
|
|
133
|
+
export type SeedlessOnboardingControllerOptions<EncryptionKey, SupportedKeyDerivationOptions> = {
|
|
134
134
|
messenger: SeedlessOnboardingControllerMessenger;
|
|
135
135
|
/**
|
|
136
136
|
* Initial state to set on this controller.
|
|
@@ -141,7 +141,7 @@ export type SeedlessOnboardingControllerOptions<EncryptionKey> = {
|
|
|
141
141
|
*
|
|
142
142
|
* @default browser-passworder @link https://github.com/MetaMask/browser-passworder
|
|
143
143
|
*/
|
|
144
|
-
encryptor: VaultEncryptor<EncryptionKey>;
|
|
144
|
+
encryptor: VaultEncryptor<EncryptionKey, SupportedKeyDerivationOptions>;
|
|
145
145
|
/**
|
|
146
146
|
* Optional key derivation interface for the TOPRF client.
|
|
147
147
|
*
|
package/dist/types.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.cts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,kCAAkC;AACrE,OAAO,KAAK,EAAE,wBAAwB,EAAE,kCAAkC;AAC1E,OAAO,KAAK,EAAE,0BAA0B,EAAE,kCAAkC;AAC5E,OAAO,KAAK,EACV,sBAAsB,EACtB,0BAA0B,EAC1B,4BAA4B,EAC7B,qCAAqC;AACtC,OAAO,KAAK,EAAE,cAAc,EAAE,sCAAsC;AACpE,OAAO,KAAK,EAAE,cAAc,EAAE,oBAAoB;AAElD,OAAO,KAAK,EACV,cAAc,EACd,cAAc,EACd,qBAAqB,EACrB,UAAU,EACV,eAAe,EAChB,wBAAoB;AAErB,MAAM,MAAM,qBAAqB,GAAG;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC;;OAEG;IACH,cAAc,EAAE,cAAc,CAAC;IAE/B;;;;OAIG;IACH,cAAc,EAAE,cAAc,CAAC;IAE/B;;OAEG;IACH,gBAAgB,EAAE,MAAM,CAAC;IAEzB;;OAEG;IACH,uBAAuB,CAAC,EAAE,MAAM,CAAC;IAEjC;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,gBAAgB,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC;;;;OAIG;IACH,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B;;OAEG;IACH,aAAa,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,gBAAgB,EAAE,MAAM,CAAC;CAC1B,CAAC;AAGF,MAAM,MAAM,iCAAiC,GAC3C,OAAO,CAAC,wBAAwB,CAAC,GAC/B,OAAO,CAAC,sBAAsB,CAAC,GAAG;IAChC;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;;OAIG;IACH,qBAAqB,EAAE,qBAAqB,EAAE,CAAC;IAE/C;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAE5B;;OAEG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAE7B;;OAEG;IACH,qBAAqB,CAAC,EAAE;QAAE,YAAY,EAAE,OAAO,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAErE;;;;;OAKG;IACH,sBAAsB,CAAC,EAAE,iBAAiB,CAAC;CAC5C,CAAC;AAGN,MAAM,MAAM,0CAA0C,GACpD,wBAAwB,CACtB,OAAO,cAAc,EACrB,iCAAiC,CAClC,CAAC;AACJ,MAAM,MAAM,mCAAmC,GAC7C,0CAA0C,CAAC;AAE7C,MAAM,MAAM,cAAc,GAAG,KAAK,CAAC;AAGnC,MAAM,MAAM,4CAA4C,GACtD,0BAA0B,CACxB,OAAO,cAAc,EACrB,iCAAiC,CAClC,CAAC;AACJ,MAAM,MAAM,kCAAkC,GAC5C,4CAA4C,CAAC;AAE/C,MAAM,MAAM,aAAa,GACrB,0BAA0B,GAC1B,4BAA4B,CAAC;AAGjC,MAAM,MAAM,qCAAqC,GAAG,mBAAmB,CACrE,OAAO,cAAc,EACrB,mCAAmC,GAAG,cAAc,EACpD,kCAAkC,GAAG,aAAa,EAClD,cAAc,CAAC,MAAM,CAAC,EACtB,aAAa,CAAC,MAAM,CAAC,CACtB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,cAAc,CAAC,aAAa,IAAI,IAAI,
|
|
1
|
+
{"version":3,"file":"types.d.cts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.mts
CHANGED
|
@@ -103,7 +103,7 @@ export type SeedlessOnboardingControllerMessenger = RestrictedMessenger<typeof c
|
|
|
103
103
|
/**
|
|
104
104
|
* Encryptor interface for encrypting and decrypting seedless onboarding vault.
|
|
105
105
|
*/
|
|
106
|
-
export type VaultEncryptor<EncryptionKey> = Omit<ExportableKeyEncryptor<EncryptionKey>, 'encryptWithKey'>;
|
|
106
|
+
export type VaultEncryptor<EncryptionKey, KeyDerivationParams> = Omit<ExportableKeyEncryptor<EncryptionKey, KeyDerivationParams>, 'encryptWithKey'>;
|
|
107
107
|
/**
|
|
108
108
|
* Additional key deriver for the TOPRF client.
|
|
109
109
|
*
|
|
@@ -130,7 +130,7 @@ export type ToprfKeyDeriver = {
|
|
|
130
130
|
* @param state - The initial state to set on this controller.
|
|
131
131
|
* @param encryptor - The encryptor to use for encrypting and decrypting seedless onboarding vault.
|
|
132
132
|
*/
|
|
133
|
-
export type SeedlessOnboardingControllerOptions<EncryptionKey> = {
|
|
133
|
+
export type SeedlessOnboardingControllerOptions<EncryptionKey, SupportedKeyDerivationOptions> = {
|
|
134
134
|
messenger: SeedlessOnboardingControllerMessenger;
|
|
135
135
|
/**
|
|
136
136
|
* Initial state to set on this controller.
|
|
@@ -141,7 +141,7 @@ export type SeedlessOnboardingControllerOptions<EncryptionKey> = {
|
|
|
141
141
|
*
|
|
142
142
|
* @default browser-passworder @link https://github.com/MetaMask/browser-passworder
|
|
143
143
|
*/
|
|
144
|
-
encryptor: VaultEncryptor<EncryptionKey>;
|
|
144
|
+
encryptor: VaultEncryptor<EncryptionKey, SupportedKeyDerivationOptions>;
|
|
145
145
|
/**
|
|
146
146
|
* Optional key derivation interface for the TOPRF client.
|
|
147
147
|
*
|
package/dist/types.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.mts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,kCAAkC;AACrE,OAAO,KAAK,EAAE,wBAAwB,EAAE,kCAAkC;AAC1E,OAAO,KAAK,EAAE,0BAA0B,EAAE,kCAAkC;AAC5E,OAAO,KAAK,EACV,sBAAsB,EACtB,0BAA0B,EAC1B,4BAA4B,EAC7B,qCAAqC;AACtC,OAAO,KAAK,EAAE,cAAc,EAAE,sCAAsC;AACpE,OAAO,KAAK,EAAE,cAAc,EAAE,oBAAoB;AAElD,OAAO,KAAK,EACV,cAAc,EACd,cAAc,EACd,qBAAqB,EACrB,UAAU,EACV,eAAe,EAChB,wBAAoB;AAErB,MAAM,MAAM,qBAAqB,GAAG;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC;;OAEG;IACH,cAAc,EAAE,cAAc,CAAC;IAE/B;;;;OAIG;IACH,cAAc,EAAE,cAAc,CAAC;IAE/B;;OAEG;IACH,gBAAgB,EAAE,MAAM,CAAC;IAEzB;;OAEG;IACH,uBAAuB,CAAC,EAAE,MAAM,CAAC;IAEjC;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,gBAAgB,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC;;;;OAIG;IACH,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B;;OAEG;IACH,aAAa,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,gBAAgB,EAAE,MAAM,CAAC;CAC1B,CAAC;AAGF,MAAM,MAAM,iCAAiC,GAC3C,OAAO,CAAC,wBAAwB,CAAC,GAC/B,OAAO,CAAC,sBAAsB,CAAC,GAAG;IAChC;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;;OAIG;IACH,qBAAqB,EAAE,qBAAqB,EAAE,CAAC;IAE/C;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAE5B;;OAEG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAE7B;;OAEG;IACH,qBAAqB,CAAC,EAAE;QAAE,YAAY,EAAE,OAAO,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAErE;;;;;OAKG;IACH,sBAAsB,CAAC,EAAE,iBAAiB,CAAC;CAC5C,CAAC;AAGN,MAAM,MAAM,0CAA0C,GACpD,wBAAwB,CACtB,OAAO,cAAc,EACrB,iCAAiC,CAClC,CAAC;AACJ,MAAM,MAAM,mCAAmC,GAC7C,0CAA0C,CAAC;AAE7C,MAAM,MAAM,cAAc,GAAG,KAAK,CAAC;AAGnC,MAAM,MAAM,4CAA4C,GACtD,0BAA0B,CACxB,OAAO,cAAc,EACrB,iCAAiC,CAClC,CAAC;AACJ,MAAM,MAAM,kCAAkC,GAC5C,4CAA4C,CAAC;AAE/C,MAAM,MAAM,aAAa,GACrB,0BAA0B,GAC1B,4BAA4B,CAAC;AAGjC,MAAM,MAAM,qCAAqC,GAAG,mBAAmB,CACrE,OAAO,cAAc,EACrB,mCAAmC,GAAG,cAAc,EACpD,kCAAkC,GAAG,aAAa,EAClD,cAAc,CAAC,MAAM,CAAC,EACtB,aAAa,CAAC,MAAM,CAAC,CACtB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,cAAc,CAAC,aAAa,IAAI,IAAI,
|
|
1
|
+
{"version":3,"file":"types.d.mts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.mjs","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { RestrictedMessenger } from '@metamask/base-controller';\nimport type { ControllerGetStateAction } from '@metamask/base-controller';\nimport type { ControllerStateChangeEvent } from '@metamask/base-controller';\nimport type {\n ExportableKeyEncryptor,\n KeyringControllerLockEvent,\n KeyringControllerUnlockEvent,\n} from '@metamask/keyring-controller';\nimport type { NodeAuthTokens } from '@metamask/toprf-secure-backup';\nimport type { MutexInterface } from 'async-mutex';\n\nimport type {\n AuthConnection,\n controllerName,\n SecretMetadataVersion,\n SecretType,\n Web3AuthNetwork,\n} from './constants';\n\nexport type SocialBackupsMetadata = {\n id: string;\n hash: string;\n};\n\nexport type AuthenticatedUserDetails = {\n /**\n * Type of social login provider.\n */\n authConnection: AuthConnection;\n\n /**\n * The node auth tokens from OAuth User authentication after the Social login.\n *\n * This values are used to authenticate users when they go through the Seedless Onboarding flow.\n */\n nodeAuthTokens: NodeAuthTokens;\n\n /**\n * OAuth connection id from web3auth dashboard.\n */\n authConnectionId: string;\n\n /**\n * The optional grouped authConnectionId to authenticate the user with Web3Auth network.\n */\n groupedAuthConnectionId?: string;\n\n /**\n * The user email or ID from Social login.\n */\n userId: string;\n\n /**\n * The user email from Social login.\n */\n socialLoginEmail: string;\n};\n\nexport type SRPBackedUpUserDetails = {\n /**\n * The public key of the authentication key pair in base64 format.\n *\n * This value is used to check if the password is outdated compare to the global password and find backed up old password.\n */\n authPubKey: string;\n};\n\n/**\n * The data of the recovery error.\n */\nexport type RecoveryErrorData = {\n /**\n * The remaining time in seconds before the user can try again.\n */\n remainingTime: number;\n\n /**\n * The number of attempts made by the user.\n */\n numberOfAttempts: number;\n};\n\n// State\nexport type SeedlessOnboardingControllerState =\n Partial<AuthenticatedUserDetails> &\n Partial<SRPBackedUpUserDetails> & {\n /**\n * Encrypted array of serialized keyrings data.\n */\n vault?: string;\n\n /**\n * The hashes of the seed phrase backups.\n *\n * This is to facilitate the UI to display backup status of the seed phrases.\n */\n socialBackupsMetadata: SocialBackupsMetadata[];\n\n /**\n * The encryption key derived from the password and used to encrypt\n * the vault.\n */\n vaultEncryptionKey?: string;\n\n /**\n * The salt used to derive the encryption key from the password.\n */\n vaultEncryptionSalt?: string;\n\n /**\n * Cache for checkIsPasswordOutdated result and timestamp.\n */\n passwordOutdatedCache?: { isExpiredPwd: boolean; timestamp: number };\n\n /**\n * The cached data of the recovery error.\n *\n * This data is used to cache the recovery error data to retrieve the accurate ratelimit remainingTime and numberOfAttempts.\n * And it also helps to synchronize the recovery error data across multiple devices.\n */\n recoveryRatelimitCache?: RecoveryErrorData;\n };\n\n// Actions\nexport type SeedlessOnboardingControllerGetStateAction =\n ControllerGetStateAction<\n typeof controllerName,\n SeedlessOnboardingControllerState\n >;\nexport type SeedlessOnboardingControllerActions =\n SeedlessOnboardingControllerGetStateAction;\n\nexport type AllowedActions = never;\n\n// Events\nexport type SeedlessOnboardingControllerStateChangeEvent =\n ControllerStateChangeEvent<\n typeof controllerName,\n SeedlessOnboardingControllerState\n >;\nexport type SeedlessOnboardingControllerEvents =\n SeedlessOnboardingControllerStateChangeEvent;\n\nexport type AllowedEvents =\n | KeyringControllerLockEvent\n | KeyringControllerUnlockEvent;\n\n// Messenger\nexport type SeedlessOnboardingControllerMessenger = RestrictedMessenger<\n typeof controllerName,\n SeedlessOnboardingControllerActions | AllowedActions,\n SeedlessOnboardingControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n\n/**\n * Encryptor interface for encrypting and decrypting seedless onboarding vault.\n */\nexport type VaultEncryptor<EncryptionKey> = Omit<\n ExportableKeyEncryptor<EncryptionKey>,\n 'encryptWithKey'\n>;\n\n/**\n * Additional key deriver for the TOPRF client.\n *\n * This is a function that takes a seed and salt and returns a key in bytes (Uint8Array).\n * It is used as an additional step during key derivation. This can be used, for example, to inject a slow key\n * derivation step to protect against local brute force attacks on the password.\n *\n * @default browser-passworder @link https://github.com/MetaMask/browser-passworder\n */\nexport type ToprfKeyDeriver = {\n /**\n * Derive a key from a seed and salt.\n *\n * @param seed - The seed to derive the key from.\n * @param salt - The salt to derive the key from.\n * @returns The derived key.\n */\n deriveKey: (seed: Uint8Array, salt: Uint8Array) => Promise<Uint8Array>;\n};\n\n/**\n * Seedless Onboarding Controller Options.\n *\n * @param messenger - The messenger to use for this controller.\n * @param state - The initial state to set on this controller.\n * @param encryptor - The encryptor to use for encrypting and decrypting seedless onboarding vault.\n */\nexport type SeedlessOnboardingControllerOptions
|
|
1
|
+
{"version":3,"file":"types.mjs","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { RestrictedMessenger } from '@metamask/base-controller';\nimport type { ControllerGetStateAction } from '@metamask/base-controller';\nimport type { ControllerStateChangeEvent } from '@metamask/base-controller';\nimport type {\n ExportableKeyEncryptor,\n KeyringControllerLockEvent,\n KeyringControllerUnlockEvent,\n} from '@metamask/keyring-controller';\nimport type { NodeAuthTokens } from '@metamask/toprf-secure-backup';\nimport type { MutexInterface } from 'async-mutex';\n\nimport type {\n AuthConnection,\n controllerName,\n SecretMetadataVersion,\n SecretType,\n Web3AuthNetwork,\n} from './constants';\n\nexport type SocialBackupsMetadata = {\n id: string;\n hash: string;\n};\n\nexport type AuthenticatedUserDetails = {\n /**\n * Type of social login provider.\n */\n authConnection: AuthConnection;\n\n /**\n * The node auth tokens from OAuth User authentication after the Social login.\n *\n * This values are used to authenticate users when they go through the Seedless Onboarding flow.\n */\n nodeAuthTokens: NodeAuthTokens;\n\n /**\n * OAuth connection id from web3auth dashboard.\n */\n authConnectionId: string;\n\n /**\n * The optional grouped authConnectionId to authenticate the user with Web3Auth network.\n */\n groupedAuthConnectionId?: string;\n\n /**\n * The user email or ID from Social login.\n */\n userId: string;\n\n /**\n * The user email from Social login.\n */\n socialLoginEmail: string;\n};\n\nexport type SRPBackedUpUserDetails = {\n /**\n * The public key of the authentication key pair in base64 format.\n *\n * This value is used to check if the password is outdated compare to the global password and find backed up old password.\n */\n authPubKey: string;\n};\n\n/**\n * The data of the recovery error.\n */\nexport type RecoveryErrorData = {\n /**\n * The remaining time in seconds before the user can try again.\n */\n remainingTime: number;\n\n /**\n * The number of attempts made by the user.\n */\n numberOfAttempts: number;\n};\n\n// State\nexport type SeedlessOnboardingControllerState =\n Partial<AuthenticatedUserDetails> &\n Partial<SRPBackedUpUserDetails> & {\n /**\n * Encrypted array of serialized keyrings data.\n */\n vault?: string;\n\n /**\n * The hashes of the seed phrase backups.\n *\n * This is to facilitate the UI to display backup status of the seed phrases.\n */\n socialBackupsMetadata: SocialBackupsMetadata[];\n\n /**\n * The encryption key derived from the password and used to encrypt\n * the vault.\n */\n vaultEncryptionKey?: string;\n\n /**\n * The salt used to derive the encryption key from the password.\n */\n vaultEncryptionSalt?: string;\n\n /**\n * Cache for checkIsPasswordOutdated result and timestamp.\n */\n passwordOutdatedCache?: { isExpiredPwd: boolean; timestamp: number };\n\n /**\n * The cached data of the recovery error.\n *\n * This data is used to cache the recovery error data to retrieve the accurate ratelimit remainingTime and numberOfAttempts.\n * And it also helps to synchronize the recovery error data across multiple devices.\n */\n recoveryRatelimitCache?: RecoveryErrorData;\n };\n\n// Actions\nexport type SeedlessOnboardingControllerGetStateAction =\n ControllerGetStateAction<\n typeof controllerName,\n SeedlessOnboardingControllerState\n >;\nexport type SeedlessOnboardingControllerActions =\n SeedlessOnboardingControllerGetStateAction;\n\nexport type AllowedActions = never;\n\n// Events\nexport type SeedlessOnboardingControllerStateChangeEvent =\n ControllerStateChangeEvent<\n typeof controllerName,\n SeedlessOnboardingControllerState\n >;\nexport type SeedlessOnboardingControllerEvents =\n SeedlessOnboardingControllerStateChangeEvent;\n\nexport type AllowedEvents =\n | KeyringControllerLockEvent\n | KeyringControllerUnlockEvent;\n\n// Messenger\nexport type SeedlessOnboardingControllerMessenger = RestrictedMessenger<\n typeof controllerName,\n SeedlessOnboardingControllerActions | AllowedActions,\n SeedlessOnboardingControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n\n/**\n * Encryptor interface for encrypting and decrypting seedless onboarding vault.\n */\nexport type VaultEncryptor<EncryptionKey, KeyDerivationParams> = Omit<\n ExportableKeyEncryptor<EncryptionKey, KeyDerivationParams>,\n 'encryptWithKey'\n>;\n\n/**\n * Additional key deriver for the TOPRF client.\n *\n * This is a function that takes a seed and salt and returns a key in bytes (Uint8Array).\n * It is used as an additional step during key derivation. This can be used, for example, to inject a slow key\n * derivation step to protect against local brute force attacks on the password.\n *\n * @default browser-passworder @link https://github.com/MetaMask/browser-passworder\n */\nexport type ToprfKeyDeriver = {\n /**\n * Derive a key from a seed and salt.\n *\n * @param seed - The seed to derive the key from.\n * @param salt - The salt to derive the key from.\n * @returns The derived key.\n */\n deriveKey: (seed: Uint8Array, salt: Uint8Array) => Promise<Uint8Array>;\n};\n\n/**\n * Seedless Onboarding Controller Options.\n *\n * @param messenger - The messenger to use for this controller.\n * @param state - The initial state to set on this controller.\n * @param encryptor - The encryptor to use for encrypting and decrypting seedless onboarding vault.\n */\nexport type SeedlessOnboardingControllerOptions<\n EncryptionKey,\n SupportedKeyDerivationOptions,\n> = {\n messenger: SeedlessOnboardingControllerMessenger;\n\n /**\n * Initial state to set on this controller.\n */\n state?: Partial<SeedlessOnboardingControllerState>;\n\n /**\n * Encryptor to use for encrypting and decrypting seedless onboarding vault.\n *\n * @default browser-passworder @link https://github.com/MetaMask/browser-passworder\n */\n encryptor: VaultEncryptor<EncryptionKey, SupportedKeyDerivationOptions>;\n\n /**\n * Optional key derivation interface for the TOPRF client.\n *\n * If provided, it will be used as an additional step during\n * key derivation. This can be used, for example, to inject a slow key\n * derivation step to protect against local brute force attacks on the\n * password.\n *\n * @default browser-passworder @link https://github.com/MetaMask/browser-passworder\n */\n toprfKeyDeriver?: ToprfKeyDeriver;\n\n /**\n * Type of Web3Auth network to be used for the Seedless Onboarding flow.\n *\n * @default Web3AuthNetwork.Mainnet\n */\n network?: Web3AuthNetwork;\n};\n\n/**\n * A function executed within a mutually exclusive lock, with\n * a mutex releaser in its option bag.\n *\n * @param releaseLock - A function to release the lock.\n */\nexport type MutuallyExclusiveCallback<Result> = ({\n releaseLock,\n}: {\n releaseLock: MutexInterface.Releaser;\n}) => Promise<Result>;\n\n/**\n * The structure of the data which is serialized and stored in the vault.\n */\nexport type VaultData = {\n /**\n * The node auth tokens from OAuth User authentication after the Social login.\n */\n authTokens: NodeAuthTokens;\n /**\n * The encryption key to encrypt the seed phrase.\n */\n toprfEncryptionKey: string;\n /**\n * The authentication key pair to authenticate the TOPRF.\n */\n toprfAuthKeyPair: string;\n};\n\nexport type SecretDataType = Uint8Array | string | number;\n\n/**\n * The constructor options for the seed phrase metadata.\n */\nexport type SecretMetadataOptions = {\n /**\n * The timestamp when the seed phrase was created.\n */\n timestamp: number;\n /**\n * The type of the seed phrase.\n */\n type: SecretType;\n /**\n * The version of the seed phrase metadata.\n */\n version: SecretMetadataVersion;\n};\n"]}
|
package/package.json
CHANGED