@metamask-previews/seedless-onboarding-controller 10.0.2-preview-55f166437 → 10.0.2-preview-e80844493

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 CHANGED
@@ -12,6 +12,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
12
12
  - Bump `@metamask/utils` from `^11.9.0` to `^11.11.0` ([#9074](https://github.com/MetaMask/core/pull/9074))
13
13
  - Bump `@metamask/keyring-controller` from `^27.0.0` to `^27.1.0` ([#9129](https://github.com/MetaMask/core/pull/9129))
14
14
 
15
+ ### Fixed
16
+
17
+ - Fix `InvalidPrimarySecretDataType` thrown for legacy accounts where client clock skew sorts a non-mnemonic item ahead of the primary SRP ([#9247](https://github.com/MetaMask/core/pull/9247))
18
+
15
19
  ## [10.0.2]
16
20
 
17
21
  ### Changed
@@ -1325,15 +1325,30 @@ async function _SeedlessOnboardingController_recoverEncKey(password) {
1325
1325
  }));
1326
1326
  // Sort: PrimarySrp first, then by createdAt/timestamp (oldest first)
1327
1327
  results.sort((a, b) => SecretMetadata_1.SecretMetadata.compare(a, b, 'asc'));
1328
- // Validate the first item is the primary SRP
1329
- const firstItem = results[0];
1330
- const isDataTypePrimary = firstItem.dataType === undefined ||
1331
- firstItem.dataType === null ||
1332
- firstItem.dataType === toprf_secure_backup_1.EncAccountDataType.PrimarySrp;
1333
- const isMnemonic = SecretMetadata_1.SecretMetadata.matchesType(firstItem, constants_1.SecretType.Mnemonic);
1334
- if (!isDataTypePrimary || !isMnemonic) {
1328
+ // Find the primary SRP instead of assuming it is at index 0: legacy
1329
+ // items have no `createdAt`, so ordering falls back to the client
1330
+ // `timestamp`, which clock skew can sort a private key ahead of.
1331
+ // A candidate is a mnemonic whose `dataType` is `PrimarySrp` or unset.
1332
+ // `dataType` (a plaintext server field) is the only thing separating
1333
+ // primary from imported SRP; legacy items lack it and the encrypted
1334
+ // `SecretType` groups both, so among legacy mnemonics the primary is
1335
+ // indistinguishable — we take the oldest (best-effort).
1336
+ const primaryIndex = results.findIndex((item) => {
1337
+ const isDataTypePrimary = item.dataType === undefined ||
1338
+ item.dataType === null ||
1339
+ item.dataType === toprf_secure_backup_1.EncAccountDataType.PrimarySrp;
1340
+ return (isDataTypePrimary &&
1341
+ SecretMetadata_1.SecretMetadata.matchesType(item, constants_1.SecretType.Mnemonic));
1342
+ });
1343
+ // No recoverable primary SRP exists in the metadata store.
1344
+ if (primaryIndex === -1) {
1335
1345
  throw new Error(constants_1.SeedlessOnboardingControllerErrorMessage.InvalidPrimarySecretDataType);
1336
1346
  }
1347
+ // Ensure the primary SRP is first; callers rely on `results[0]` being it.
1348
+ if (primaryIndex > 0) {
1349
+ const [primary] = results.splice(primaryIndex, 1);
1350
+ results.unshift(primary);
1351
+ }
1337
1352
  return results;
1338
1353
  }
1339
1354
  throw new Error(constants_1.SeedlessOnboardingControllerErrorMessage.NoSecretDataFound);