All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
- Bump
@metamask/utilsfrom^11.9.0to^11.11.0(#9074) - Bump
@metamask/keyring-controllerfrom^27.0.0to^27.1.0(#9129)
- Bump
@metamask/keyring-controllerfrom^26.0.0to^27.0.0(#9058)
- Expose
runMigrationsas a messenger action (SeedlessOnboardingController:runMigrations) (#9031)
- Add
runMigrationsmethod to run pending data migrations for legacy secrets (#7284) - Add
setMigrationVersionmethod to set migration version directly for new users (#7284) - Add
SeedlessOnboardingMigrationVersionenum for tracking migration versions (#7284) - Add
migrationVersionto controller state to track applied migrations (#7284) - Add
itemId,dataType,createdAt, andstorageVersionstorage-level properties toSecretMetadata(#7284) - Add
SecretMetadata.comparestatic method for comparing metadata with PrimarySrp prioritization and TIMEUUID-based sorting (#7284) - Add
SecretMetadata.compareByTimestampstatic method for comparing metadata by timestamp (#7284) - Add
SecretMetadata.matchesTypestatic method for checking if metadata matches a given type (#7284) - Re-export
EncAccountDataTypefrom@metamask/toprf-secure-backup(#7284) - Add third generic type parameter
EncryptionResulttoSeedlessOnboardingControllerandSeedlessOnboardingControllerOptions, constrained byEncryptionResultConstraintand defaulting toDefaultEncryptionResult, so the vaultencryptormatches the fullEncryptortyping from@metamask/keyring-controller(#8411)
- Bump
@metamask/keyring-controllerfrom^25.1.1to^26.0.0(#8363, #8634, #8665, #8722, #8912) - Bump
@metamask/messengerfrom^1.0.0to^1.2.0(#8364, #8373, #8632) - Bump
@metamask/toprf-secure-backupfrom^0.11.0to^1.0.0(#7284) - BREAKING: Change
addNewSecretDatamethod signature to requiredataType: EncAccountDataTypeinstead oftype: SecretType(#7284)SecretTypeis now derived internally fromEncAccountDataType- Encrypted payload still includes
typefor backward compatibility with older clients
- BREAKING: Remove
parseSecretsFromMetadataStore,fromBatch, andsortmethods fromSecretMetadata(#7284)- Use
SecretMetadata.compareorSecretMetadata.compareByTimestampfor sorting - Use
SecretMetadata.matchesTypefor filtering
- Use
- BREAKING: Change
SecretMetadata.fromRawMetadatasignature to requirestorageMetadataparameter (#7284) - BREAKING: Remove
versiongetter fromSecretMetadata; usestorageVersioninstead (#7284) - Bump
@metamask/base-controllerfrom^9.0.1to^9.1.0(#8457) - BREAKING: Remove
VaultEncryptortype alias; useEncryptorfrom@metamask/keyring-controllerwith encryption key, key derivation params, and encryption result types (#8411)
- Fix TIMEUUID sorting by extracting actual timestamps instead of using lexicographic comparison (#7284)
- Expose all public
SeedlessOnboardingControllermethods through its messenger (#8219)- The following actions are now available:
SeedlessOnboardingController:fetchMetadataAccessCredsSeedlessOnboardingController:preloadToprfNodeDetailsSeedlessOnboardingController:authenticateSeedlessOnboardingController:createToprfKeyAndBackupSeedPhraseSeedlessOnboardingController:addNewSecretDataSeedlessOnboardingController:fetchAllSecretDataSeedlessOnboardingController:changePasswordSeedlessOnboardingController:updateBackupMetadataStateSeedlessOnboardingController:verifyVaultPasswordSeedlessOnboardingController:getSecretDataBackupStateSeedlessOnboardingController:submitPasswordSeedlessOnboardingController:setLockedSeedlessOnboardingController:syncLatestGlobalPasswordSeedlessOnboardingController:submitGlobalPasswordSeedlessOnboardingController:checkIsPasswordOutdatedSeedlessOnboardingController:getIsUserAuthenticatedSeedlessOnboardingController:clearStateSeedlessOnboardingController:storeKeyringEncryptionKeySeedlessOnboardingController:loadKeyringEncryptionKeySeedlessOnboardingController:refreshAuthTokensSeedlessOnboardingController:revokePendingRefreshTokensSeedlessOnboardingController:rotateRefreshTokenSeedlessOnboardingController:checkNodeAuthTokenExpiredSeedlessOnboardingController:checkMetadataAccessTokenExpiredSeedlessOnboardingController:checkAccessTokenExpired
- Corresponding action types are now exported (e.g.
SeedlessOnboardingControllerGetAccessTokenAction)
- The following actions are now available:
- Bump
@metamask/base-controllerfrom^9.0.0to^9.0.1(#8317) - Bump
@metamask/keyring-controllerfrom^25.1.0to^25.1.1(#8317) - Bump
@metamask/messengerfrom^0.3.0to^1.0.0(#8317)
- Token refresh now uses a dedicated private
#reAuthenticatemethod that only accepts the tokens returned by the JWT-refresh service (idTokens,accessToken,metadataAccessToken), making the re-authentication path stricter than the initialauthenticatecall (#8148) - After a successful JWT refresh the controller proactively rotates the refresh/revoke token pair (when the vault is unlocked) via the public
rotateRefreshTokenmethod (#8148) - Token expiry checks now use a 90% lifetime threshold for proactive refresh: access tokens and metadata access tokens are refreshed when less than 10% of their lifetime remains (requires
iat), while node auth tokens fall back to exact-expiry checking (#8148) - chore: secure PUBLISH_PREVIEW_NPM_TOKEN with GitHub environment (#8011)
- BREAKING: Removed public
renewRefreshTokenmethod — refresh token rotation is now handled byrotateRefreshToken, which can also be called directly (#8148)
- Fixed
FailedToFetchAuthPubKeyerrors caused by expired tokens inaddNewSecretDataandchangePassword—assertPasswordInSyncis now called inside the token-refresh wrapper so expirednodeAuthTokensare refreshed before reaching the backend
refreshAuthTokensnow coalesces concurrent calls — if a refresh is already in-flight, subsequent callers share the same promise rather than issuing duplicate HTTP requests with the same token (#7989)refreshAuthTokensnow uses the livestate.refreshTokenvalue when callingauthenticateafter a successful HTTP refresh, preventing a stale-capture bug that could overwrite a concurrently-renewed token with an older one (#7989)renewRefreshTokennow queues the old token for revocation only after#createNewVaultWithAuthDatasucceeds, ensuring tokens are not queued if vault creation fails (#7989)
- Fixed
refreshAuthTokensthrowing the genericFailedToRefreshJWTTokenserror for all HTTP failures — a 401 response (permanently revoked token) now throwsInvalidRefreshTokeninstead, giving callers a distinct signal to distinguish permanent from transient failures (#7989)
- Add new
SeedlessOnboardingErrorclass for generic controller errors with support forcauseanddetailsproperties (#7660)- Enables proper error chaining by wrapping underlying errors with additional context
- Includes
toJSON()method for serialization in logging/transmission
- BREAKING The
encryptorconstructor param requiresencryptWithKeymethod. (#7800)- The method is to encrypt the vault with cached encryption key while the wallet is unlocked.
- Added new public method,
getAccessToken. (#7800)- Clients can use this method to get
accessTokenfrom the controller, instead of directly accessing from the state. - This method also adds refresh token mechanism when
accessTokenis expired, hence preventing expired token usage in the clients.
- Clients can use this method to get
- Update StateMetadata's
includeInStateLogsproperty. (#7750)- Exclude All the tokens values from the state log explicitly.
- Bump
@metamask/keyring-controllerfrom^25.0.0to^25.1.0(#7713) - Upgrade
@metamask/utilsfrom^11.8.1to^11.9.0(#7511) - Refactor controller methods to throw
SeedlessOnboardingErrorwith original error ascausefor better error tracing (#7660)- Affected methods:
authenticate,changePassword,#persistLocalEncryptionKey,#fetchAndParseSecretMetadata,refreshAuthTokens
- Affected methods:
- Fixed new
accessTokennot being persisted in the vault after the token refresh. (#7800)
- Added new public method,
preloadToprfNodeDetailsto pre-load the TROPF Node details. (#7300)
- Bump
@metamask/toprf-secure-backupto0.11.0. (#7300) - Move peer dependencies for controller and service packages to direct dependencies (#7209)
- The dependencies moved are:
@metamask/keyring-controller(^25.0.0)
- In clients, it is now possible for multiple versions of these packages to exist in the dependency tree.
- For example, this scenario would be valid: a client relies on
@metamask/controller-a1.0.0 and@metamask/controller-b1.0.0, and@metamask/controller-bdepends on@metamask/controller-a1.1.0.
- For example, this scenario would be valid: a client relies on
- Note, however, that the versions specified in the client's
package.jsonalways "win", and you are expected to keep them up to date so as not to break controller and service intercommunication.
- The dependencies moved are:
- BREAKING: Bump
@metamask/keyring-controllerfrom^24.0.0to^25.0.0(#7202) - BREAKING: The
encryptorconstructor param requiresexportKey,keyFromPasswordandgenerateSaltmethods (#7128) SeedlessOnboardingControllernow accepts an optionalSupportedKeyDerivationOptionstype parameter (#7127)- The type parameter can be used to specify which key derivation algorithms are supported by the controller instance.
- Revert
revokeTokenvalue as optional inauthenticatemethod. (#7012) - Renamed
checkIsSeedlessOnboardingUserAuthenticatedtogetIsUserAuthenticated. (#7012)
- Fixed
InvalidRevokeTokenissue inrefreshAuthTokensmethod. (#7012)
- Added new public method,
checkIsSeedlessOnboardingUserAuthenticatedto validate the controller authenticate tokens state. (#6998)
- BREAKING Update
refreshTokenandrevokeTokenparams as required inAuthenticatemethod. (#6998) - Refactor
refreshAuthTokensmethod, separately catch refreshJWTToken and authenticate errors. (#6998) - Bump
@metamask/toprf-secure-backuppackage to0.10.0. (#6998)
- Fixed
Invalid Access Tokenerror during rehydration. (#6998)
- BREAKING: Use new
Messengerfrom@metamask/messenger(#6364)- Previously,
SeedlessOnboardingControlleraccepted aRestrictedMessengerinstance from@metamask/base-controller.
- Previously,
- BREAKING: Metadata property
anonymousrenamed toincludeInDebugSnapshot(#6364) - BREAKING: Bump
@metamask/keyring-controllerfrom^23.0.0to^24.0.0(#6962) - Bump
@metamask/base-controllerfrom^8.4.2to^9.0.0(#6962)
- Bump
@metamask/base-controllerfrom^8.4.1to^8.4.2(#6917)
- Add two new controller state metadata properties:
includeInStateLogsandusedInUi(#6504)
- Bump
@metamask/utilsfrom^11.4.2to^11.8.1(#6588, #6708) - Bump
@metamask/base-controllerfrom^8.3.0to^8.4.1(#6632, #6807)
- Added
renewRefreshTokenoptions in SeedlessOnboardingController constructor - A function to renew the refresh token and get new revoke token. (#6275) - Added
renewRefreshTokenmethod to renew refresh token from client (#6275) - Added
revokePendingRefreshTokensmethod to revoke all pending old refresh tokens instead from client (#6275)
- BREAKING: Updated ControllerMessenger
AllowedEvents. (#6292) - Update
setLocked()method withmutexand it becomesasyncmethod. (#6292) - Bump
@metamask/base-controllerfrom^8.1.0to^8.3.0(#6355, #6465) - refactor: cache vault data while unlock (#6205)
- BREAKING: Removed
Keyring:lockandKeyring:unlockevents from the controller allowed events. (#6292) - Removed
revokeRefreshTokenmethod (#6275)
- BREAKING: Bump peer dependency
@metamask/keyring-controllerfrom^22.0.0to^23.0.0(#6345)
- Added new persisted state value,
isSeedlessOnboardingUserAuthenticated. (#6288)- This is for the UI state in the clients, to avoid querying sensistive controller state data to determine the social login authentication state.
- Bump
@metamask/base-controllerfrom^8.0.1to^8.1.0(#6284)
- Set
anonymoustofalsefor sensitive fields in the controller state. (#6283)
- Moved
@noble/hashesfrom dev dependencies to main dependencies and bumped from^1.4.0to^1.8.0(#6101) - Moved
@noble/ciphersfrom dev dependencies to main dependencies and bumped from^0.5.2to^1.3.0(#6101) - Moved
@noble/curvesfrom dev dependencies to main dependencies and bumped from^1.2.0to^1.9.2(#6101)
- Fixed the vault creation with incorrect revokeToken value after fetching new revoke token asynchronously. (#6272)
-
Added an optional parameter,
passwordOutdatedCacheTTLto the constructor params and exportedSecretMetadataclass from the controller.(#6169) -
Added
revokeRefreshTokenfunction to revoke refresh token and update vault with the new revoke token.(#6187)
- Retrieve
accessTokenfrom the encrypted vault if it's not available as an in-memory state. (#6155)
- Added a optional param
maxKeyChainLengthinsubmitGlobalPasswordfunction.(#6134) - Separated vault update logic from
revokeRefreshToken,revokeRefreshTokennow accepts a revokeToken instead of password. (#6134)
revokeRefreshTokenis removed and a private function namedrevokeRefreshTokenAndUpdateStateis added as a replacement.(#6136)
- Seedless onboarding controller: Remove usage of
Buffer(#6140)
- Removed
access_tokenvalidation when the wallet is locked. (#6133) - Removed
revoke_tokenvalidation from#parseVaultandcreateNewVaultWithAuthDatato handle the case when max key chain length exceeds. (#6136)
- Added
access_tokenandmetadata_access_tokenin seedless controller state. (#6060)access_tokencan be used by profile sync pairing and for other apis access after wallet is unlocked.metadata_access_tokenis used to give access for web3auth metadata apis.
- remove buffer usage in seedless controller (#6080)
- Added
PrivateKey syncfeature to the controller (#5948).- BREAKING Updated controller methods signatures.
- removed
addNewSeedPhraseBackupand replaced withaddNewSecretDatamethod. - added
addNewSecretDatamethod implementation to support adding different secret data types. - renamed
fetchAllSeedPhrasesmethod tofetchAllSecretDataand updated the return value toRecord<SecretType, Uint8Array[]>. - added new error message,
MissingKeyringIdwhich will throw if nokeyringIdis provided during seed phrase (Mnemonic) backup.
- Added a check for
duplicate databefore adding it to the metadata store. (#5955)- renamed
getSeedPhraseBackupHashtogetSecretDataBackupStateand added optional param (type) to look for data with specific type in the controller backup state. - updated
updateBackupMetadataStatemethod param with{ keyringId?: string; data: Uint8Array; type: SecretType }. Previously ,{ keyringId: string; seedPhrase: Uint8Array }.
- renamed
- Added
submitGlobalPassword. (#5995) - Added
storeKeyringEncryptionKeyandloadKeyringEncryptionKey. (#5995) - Added validations in
fetchAllSecretData. (#6047)- Throwing
NoSecretDataFounderror when the client receives the empty secret data from the metadata store. - Throwing
InvalidPrimarySecretDataTypeerror when the first secret data backup is not aMnemonic. First backup must always be aMnemonicsince generating a new mnemonic (SRP) is the only way to create a new wallet for a Social Login user.
- Throwing
- Refresh and revoke token handling (#5917)
- BREAKING:
authenticateneed extrarefreshTokenandrevokeTokenparams, persist refresh token in state and store revoke token temporarily for user in next step createToprfKeyAndBackupSeedPhrase,fetchAllSecretDatastore revoke token in vault- check for token expired in toprf call, refresh token and retry if expired
submitPasswordrevoke refresh token and replace with new one after password submit to prevent malicious use if refresh token leak in persisted state
- BREAKING:
- Removed
recoveryRatelimitCachefrom the controller state. (#5976). - BREAKING: Changed
syncLatestGlobalPassword. (#5995)- removed parameter
oldPassword - no longer verifying old password
- explicitly requring unlocked controller
- removed parameter
- BREAKING Changed data structure of return values from
fetchAllSecretData. (#6047)- Now returns
SecretMetadata[]object instead ofRecord<SecretType, Uint8Array[]>
- Now returns
- Bump
@metamask/utilsfrom^11.2.0to^11.4.2(#6054)
- Removed
recoverCurrentDevicePassword. (#5995)
- Initial release of the seedless onboarding controller (#5874, #5875, #5880)
- This controller allows MM extension and mobile users to login with google, apple accounts. This controller communicates with web3auth nodes + relies on toprf sdk (unreleased) to perform CRU operations related to backing up srps.
- The controller contains the following methods:
authenticate: Authenticate OAuth user, generate Valid Authentication Token to interact with TOPRF Services and determine if the user has already registered or not.createToprfKeyAndBackupSeedPhrase: Create a new TOPRF encryption key using given password, encrypt the Seed Phrase and store the encrypted data in the metadata store.addNewSeedPhraseBackup: Add and encrypt a new seed phrase backup to the metadata store without create a new TOPRF encryption key.fetchAllSeedPhrases: Retrieve the encrypted backed-up Seed Phrases from the metadatastore and return decrypted Seed Phrases.changePassword: Update the password of the seedless onboarding flowupdateBackupMetadataState: Update the backup metadata state of the controller.verifyVaultPassword: Verify the password validity by decrypting the vaultgetSeedPhraseBackupHash: Get the hash of the seed phrase backup for the given seed phrase from the state.submitPassword: Validate a password and unlock the controller.setLocked: Remove secrets from state and set the controller status to locked.syncLatestGlobalPassword: Sync the latest global password to the controller. This is useful for syncing the password change update across multiple devices.recoverCurrentDevicePassword:- Recover the vault which is encrypted with the outdated password with the new password.
- This is useful when user wants to sync the current device without logging out.
- e.g. User enters the new password, decrypts the current vault (which was initially encrypted with old password) using the new password and recover the Key data.
checkIsPasswordOutdated: Check if the password is current device is outdated, i.e. user changed password in another device.clearState: Reset the state of the controller to the defaults.