@metamask-previews/profile-sync-controller 14.0.0-preview-698a7cc → 14.0.0-preview-5cc6dab9

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.
Files changed (103) hide show
  1. package/dist/controllers/authentication/AuthenticationController.cjs +58 -24
  2. package/dist/controllers/authentication/AuthenticationController.cjs.map +1 -1
  3. package/dist/controllers/authentication/AuthenticationController.d.cts +6 -4
  4. package/dist/controllers/authentication/AuthenticationController.d.cts.map +1 -1
  5. package/dist/controllers/authentication/AuthenticationController.d.mts +6 -4
  6. package/dist/controllers/authentication/AuthenticationController.d.mts.map +1 -1
  7. package/dist/controllers/authentication/AuthenticationController.mjs +59 -25
  8. package/dist/controllers/authentication/AuthenticationController.mjs.map +1 -1
  9. package/dist/controllers/authentication/auth-snap-requests.cjs +25 -4
  10. package/dist/controllers/authentication/auth-snap-requests.cjs.map +1 -1
  11. package/dist/controllers/authentication/auth-snap-requests.d.cts +12 -2
  12. package/dist/controllers/authentication/auth-snap-requests.d.cts.map +1 -1
  13. package/dist/controllers/authentication/auth-snap-requests.d.mts +12 -2
  14. package/dist/controllers/authentication/auth-snap-requests.d.mts.map +1 -1
  15. package/dist/controllers/authentication/auth-snap-requests.mjs +23 -3
  16. package/dist/controllers/authentication/auth-snap-requests.mjs.map +1 -1
  17. package/dist/controllers/user-storage/UserStorageController.cjs +76 -27
  18. package/dist/controllers/user-storage/UserStorageController.cjs.map +1 -1
  19. package/dist/controllers/user-storage/UserStorageController.d.cts +23 -9
  20. package/dist/controllers/user-storage/UserStorageController.d.cts.map +1 -1
  21. package/dist/controllers/user-storage/UserStorageController.d.mts +23 -9
  22. package/dist/controllers/user-storage/UserStorageController.d.mts.map +1 -1
  23. package/dist/controllers/user-storage/UserStorageController.mjs +77 -28
  24. package/dist/controllers/user-storage/UserStorageController.mjs.map +1 -1
  25. package/dist/controllers/user-storage/account-syncing/controller-integration.cjs +33 -28
  26. package/dist/controllers/user-storage/account-syncing/controller-integration.cjs.map +1 -1
  27. package/dist/controllers/user-storage/account-syncing/controller-integration.d.cts +5 -2
  28. package/dist/controllers/user-storage/account-syncing/controller-integration.d.cts.map +1 -1
  29. package/dist/controllers/user-storage/account-syncing/controller-integration.d.mts +5 -2
  30. package/dist/controllers/user-storage/account-syncing/controller-integration.d.mts.map +1 -1
  31. package/dist/controllers/user-storage/account-syncing/controller-integration.mjs +34 -29
  32. package/dist/controllers/user-storage/account-syncing/controller-integration.mjs.map +1 -1
  33. package/dist/controllers/user-storage/account-syncing/sync-utils.cjs +12 -7
  34. package/dist/controllers/user-storage/account-syncing/sync-utils.cjs.map +1 -1
  35. package/dist/controllers/user-storage/account-syncing/sync-utils.d.cts +6 -2
  36. package/dist/controllers/user-storage/account-syncing/sync-utils.d.cts.map +1 -1
  37. package/dist/controllers/user-storage/account-syncing/sync-utils.d.mts +6 -2
  38. package/dist/controllers/user-storage/account-syncing/sync-utils.d.mts.map +1 -1
  39. package/dist/controllers/user-storage/account-syncing/sync-utils.mjs +12 -7
  40. package/dist/controllers/user-storage/account-syncing/sync-utils.mjs.map +1 -1
  41. package/dist/controllers/user-storage/account-syncing/utils.cjs +1 -42
  42. package/dist/controllers/user-storage/account-syncing/utils.cjs.map +1 -1
  43. package/dist/controllers/user-storage/account-syncing/utils.d.cts +1 -18
  44. package/dist/controllers/user-storage/account-syncing/utils.d.cts.map +1 -1
  45. package/dist/controllers/user-storage/account-syncing/utils.d.mts +1 -18
  46. package/dist/controllers/user-storage/account-syncing/utils.d.mts.map +1 -1
  47. package/dist/controllers/user-storage/account-syncing/utils.mjs +0 -39
  48. package/dist/controllers/user-storage/account-syncing/utils.mjs.map +1 -1
  49. package/dist/sdk/authentication-jwt-bearer/flow-siwe.cjs.map +1 -1
  50. package/dist/sdk/authentication-jwt-bearer/flow-siwe.d.cts.map +1 -1
  51. package/dist/sdk/authentication-jwt-bearer/flow-siwe.d.mts.map +1 -1
  52. package/dist/sdk/authentication-jwt-bearer/flow-siwe.mjs.map +1 -1
  53. package/dist/sdk/authentication-jwt-bearer/flow-srp.cjs +23 -21
  54. package/dist/sdk/authentication-jwt-bearer/flow-srp.cjs.map +1 -1
  55. package/dist/sdk/authentication-jwt-bearer/flow-srp.d.cts +4 -4
  56. package/dist/sdk/authentication-jwt-bearer/flow-srp.d.cts.map +1 -1
  57. package/dist/sdk/authentication-jwt-bearer/flow-srp.d.mts +4 -4
  58. package/dist/sdk/authentication-jwt-bearer/flow-srp.d.mts.map +1 -1
  59. package/dist/sdk/authentication-jwt-bearer/flow-srp.mjs +23 -21
  60. package/dist/sdk/authentication-jwt-bearer/flow-srp.mjs.map +1 -1
  61. package/dist/sdk/authentication-jwt-bearer/services.cjs.map +1 -1
  62. package/dist/sdk/authentication-jwt-bearer/services.d.cts.map +1 -1
  63. package/dist/sdk/authentication-jwt-bearer/services.d.mts.map +1 -1
  64. package/dist/sdk/authentication-jwt-bearer/services.mjs.map +1 -1
  65. package/dist/sdk/authentication-jwt-bearer/types.cjs.map +1 -1
  66. package/dist/sdk/authentication-jwt-bearer/types.d.cts +8 -8
  67. package/dist/sdk/authentication-jwt-bearer/types.d.cts.map +1 -1
  68. package/dist/sdk/authentication-jwt-bearer/types.d.mts +8 -8
  69. package/dist/sdk/authentication-jwt-bearer/types.d.mts.map +1 -1
  70. package/dist/sdk/authentication-jwt-bearer/types.mjs.map +1 -1
  71. package/dist/sdk/authentication.cjs +8 -11
  72. package/dist/sdk/authentication.cjs.map +1 -1
  73. package/dist/sdk/authentication.d.cts +4 -4
  74. package/dist/sdk/authentication.d.cts.map +1 -1
  75. package/dist/sdk/authentication.d.mts +4 -4
  76. package/dist/sdk/authentication.d.mts.map +1 -1
  77. package/dist/sdk/authentication.mjs +8 -11
  78. package/dist/sdk/authentication.mjs.map +1 -1
  79. package/dist/sdk/user-storage.cjs +38 -32
  80. package/dist/sdk/user-storage.cjs.map +1 -1
  81. package/dist/sdk/user-storage.d.cts +4 -3
  82. package/dist/sdk/user-storage.d.cts.map +1 -1
  83. package/dist/sdk/user-storage.d.mts +4 -3
  84. package/dist/sdk/user-storage.d.mts.map +1 -1
  85. package/dist/sdk/user-storage.mjs +38 -32
  86. package/dist/sdk/user-storage.mjs.map +1 -1
  87. package/dist/sdk/utils/messaging-signing-snap-requests.cjs +16 -4
  88. package/dist/sdk/utils/messaging-signing-snap-requests.cjs.map +1 -1
  89. package/dist/sdk/utils/messaging-signing-snap-requests.d.cts +2 -2
  90. package/dist/sdk/utils/messaging-signing-snap-requests.d.cts.map +1 -1
  91. package/dist/sdk/utils/messaging-signing-snap-requests.d.mts +2 -2
  92. package/dist/sdk/utils/messaging-signing-snap-requests.d.mts.map +1 -1
  93. package/dist/sdk/utils/messaging-signing-snap-requests.mjs +16 -4
  94. package/dist/sdk/utils/messaging-signing-snap-requests.mjs.map +1 -1
  95. package/dist/shared/storage-schema.cjs +1 -6
  96. package/dist/shared/storage-schema.cjs.map +1 -1
  97. package/dist/shared/storage-schema.d.cts +0 -1
  98. package/dist/shared/storage-schema.d.cts.map +1 -1
  99. package/dist/shared/storage-schema.d.mts +0 -1
  100. package/dist/shared/storage-schema.d.mts.map +1 -1
  101. package/dist/shared/storage-schema.mjs +0 -4
  102. package/dist/shared/storage-schema.mjs.map +1 -1
  103. package/package.json +1 -1
@@ -1,7 +1,6 @@
1
- import { isEvmAccountType } from "@metamask/keyring-api";
2
1
  import { KeyringTypes } from "@metamask/keyring-controller";
3
2
  import { canPerformAccountSyncing, getInternalAccountsList, getUserStorageAccountsList } from "./sync-utils.mjs";
4
- import { isInternalAccountFromPrimarySRPHdKeyring, isNameDefaultAccountName, mapInternalAccountToUserStorageAccount } from "./utils.mjs";
3
+ import { isNameDefaultAccountName, mapInternalAccountToUserStorageAccount } from "./utils.mjs";
5
4
  import { USER_STORAGE_FEATURE_NAMES } from "../../../shared/storage-schema.mjs";
6
5
  /**
7
6
  * Saves an individual internal account to the user storage.
@@ -10,18 +9,28 @@ import { USER_STORAGE_FEATURE_NAMES } from "../../../shared/storage-schema.mjs";
10
9
  * @param options - parameters used for saving the internal account
11
10
  */
12
11
  export async function saveInternalAccountToUserStorage(internalAccount, options) {
13
- const { getUserStorageControllerInstance } = options;
12
+ const { getUserStorageControllerInstance, getMessenger } = options;
14
13
  if (!canPerformAccountSyncing(options) ||
15
- !isEvmAccountType(internalAccount.type) ||
16
- !(await isInternalAccountFromPrimarySRPHdKeyring(internalAccount, options))) {
14
+ internalAccount.metadata.keyring.type !== String(KeyringTypes.hd) // sync only EVM accounts until we support multichain accounts
15
+ ) {
17
16
  return;
18
17
  }
18
+ // Refresh the internal accounts list so that it populates entropySourceId and derivationPath for all accounts
19
+ await getMessenger().call('AccountsController:updateAccounts');
20
+ // Find back our account from this refreshed list
21
+ const internalAccountsList = getMessenger().call('AccountsController:listAccounts');
22
+ const internalAccountFromList = internalAccountsList.find((account) => account.address === internalAccount.address);
23
+ // This should never happen because users don't have the ability to remove an accounts
24
+ // but if it does, we throw an error
25
+ // istanbul ignore next
26
+ if (!internalAccountFromList) {
27
+ throw new Error(`UserStorageController - failed to find internal account in the list - ${internalAccount.address}`);
28
+ }
29
+ const entropySourceId = JSON.stringify(internalAccountFromList.options.entropySource);
19
30
  try {
20
31
  // Map the internal account to the user storage account schema
21
- const mappedAccount = mapInternalAccountToUserStorageAccount(internalAccount);
22
- await getUserStorageControllerInstance().performSetStorage(
23
- // ESLint is confused here.
24
- `${USER_STORAGE_FEATURE_NAMES.accounts}.${internalAccount.address}`, JSON.stringify(mappedAccount));
32
+ const mappedAccount = mapInternalAccountToUserStorageAccount(internalAccountFromList);
33
+ await getUserStorageControllerInstance().performSetStorage(`${USER_STORAGE_FEATURE_NAMES.accounts}.${internalAccountFromList.address}`, JSON.stringify(mappedAccount), entropySourceId);
25
34
  }
26
35
  catch (e) {
27
36
  // istanbul ignore next
@@ -33,10 +42,12 @@ export async function saveInternalAccountToUserStorage(internalAccount, options)
33
42
  * Saves the list of internal accounts to the user storage.
34
43
  *
35
44
  * @param options - parameters used for saving the list of internal accounts
45
+ * @param entropySourceId - The entropy source ID used to derive the key,
46
+ * when multiple sources are available (Multi-SRP).
36
47
  */
37
- export async function saveInternalAccountsListToUserStorage(options) {
48
+ export async function saveInternalAccountsListToUserStorage(options, entropySourceId) {
38
49
  const { getUserStorageControllerInstance } = options;
39
- const internalAccountsList = await getInternalAccountsList(options);
50
+ const internalAccountsList = await getInternalAccountsList(options, entropySourceId);
40
51
  if (!internalAccountsList?.length) {
41
52
  return;
42
53
  }
@@ -44,7 +55,7 @@ export async function saveInternalAccountsListToUserStorage(options) {
44
55
  await getUserStorageControllerInstance().performBatchSetStorage(USER_STORAGE_FEATURE_NAMES.accounts, internalAccountsListFormattedForUserStorage.map((account) => [
45
56
  account.a,
46
57
  JSON.stringify(account),
47
- ]));
58
+ ]), entropySourceId);
48
59
  }
49
60
  /**
50
61
  * Syncs the internal accounts list with the user storage accounts list.
@@ -53,8 +64,9 @@ export async function saveInternalAccountsListToUserStorage(options) {
53
64
  *
54
65
  * @param config - parameters used for syncing the internal accounts list with the user storage accounts list
55
66
  * @param options - parameters used for syncing the internal accounts list with the user storage accounts list
67
+ * @param entropySourceId - The entropy source ID used to derive the key,
56
68
  */
57
- export async function syncInternalAccountsWithUserStorage(config, options) {
69
+ export async function syncInternalAccountsWithUserStorage(config, options, entropySourceId) {
58
70
  if (!canPerformAccountSyncing(options)) {
59
71
  return;
60
72
  }
@@ -62,10 +74,9 @@ export async function syncInternalAccountsWithUserStorage(config, options) {
62
74
  const { getMessenger, getUserStorageControllerInstance } = options;
63
75
  try {
64
76
  await getUserStorageControllerInstance().setIsAccountSyncingInProgress(true);
65
- const userStorageAccountsList = await getUserStorageAccountsList(options);
77
+ const userStorageAccountsList = await getUserStorageAccountsList(options, entropySourceId);
66
78
  if (!userStorageAccountsList || !userStorageAccountsList.length) {
67
- await saveInternalAccountsListToUserStorage(options);
68
- await getUserStorageControllerInstance().setHasAccountSyncingSyncedAtLeastOnce(true);
79
+ await saveInternalAccountsListToUserStorage(options, entropySourceId);
69
80
  return;
70
81
  }
71
82
  // Keep a record if erroneous situations are found during the sync
@@ -75,7 +86,7 @@ export async function syncInternalAccountsWithUserStorage(config, options) {
75
86
  const internalAccountsToBeSavedToUserStorage = [];
76
87
  // Compare internal accounts list with user storage accounts list
77
88
  // First step: compare lengths
78
- const internalAccountsList = await getInternalAccountsList(options);
89
+ const internalAccountsList = await getInternalAccountsList(options, entropySourceId);
79
90
  if (!internalAccountsList || !internalAccountsList.length) {
80
91
  throw new Error(`Failed to get internal accounts list`);
81
92
  }
@@ -86,11 +97,8 @@ export async function syncInternalAccountsWithUserStorage(config, options) {
86
97
  const numberOfAccountsToAdd = Math.min(userStorageAccountsList.length, maxNumberOfAccountsToAdd) -
87
98
  internalAccountsList.length;
88
99
  // Create new accounts to match the user storage accounts list
89
- // NOTE: we only support the primary SRP HD keyring for now
90
- // This is why we are hardcoding the index to 0
91
100
  await getMessenger().call('KeyringController:withKeyring', {
92
- type: KeyringTypes.hd,
93
- index: 0,
101
+ id: entropySourceId,
94
102
  }, async ({ keyring }) => {
95
103
  await keyring.addAccounts(numberOfAccountsToAdd);
96
104
  });
@@ -101,7 +109,7 @@ export async function syncInternalAccountsWithUserStorage(config, options) {
101
109
  }
102
110
  // Second step: compare account names
103
111
  // Get the internal accounts list again since new accounts might have been added in the previous step
104
- const refreshedInternalAccountsList = await getInternalAccountsList(options);
112
+ const refreshedInternalAccountsList = await getInternalAccountsList(options, entropySourceId);
105
113
  const newlyAddedAccounts = refreshedInternalAccountsList.filter((account) => !internalAccountsList.find((a) => a.address === account.address));
106
114
  for (const internalAccount of refreshedInternalAccountsList) {
107
115
  const userStorageAccount = userStorageAccountsList.find((account) => account.a === internalAccount.address);
@@ -177,13 +185,13 @@ export async function syncInternalAccountsWithUserStorage(config, options) {
177
185
  await getUserStorageControllerInstance().performBatchSetStorage(USER_STORAGE_FEATURE_NAMES.accounts, internalAccountsToBeSavedToUserStorage.map((account) => [
178
186
  account.address,
179
187
  JSON.stringify(mapInternalAccountToUserStorageAccount(account)),
180
- ]));
188
+ ]), entropySourceId);
181
189
  }
182
190
  // In case we have corrupted user storage with accounts that don't exist in the internal accounts list
183
191
  // Delete those accounts from the user storage
184
192
  const userStorageAccountsToBeDeleted = userStorageAccountsList.filter((account) => !refreshedInternalAccountsList.find((a) => a.address === account.a));
185
193
  if (userStorageAccountsToBeDeleted.length) {
186
- await getUserStorageControllerInstance().performBatchDeleteStorage(USER_STORAGE_FEATURE_NAMES.accounts, userStorageAccountsToBeDeleted.map((account) => account.a));
194
+ await getUserStorageControllerInstance().performBatchDeleteStorage(USER_STORAGE_FEATURE_NAMES.accounts, userStorageAccountsToBeDeleted.map((account) => account.a), entropySourceId);
187
195
  erroneousSituationsFound = true;
188
196
  onAccountSyncErroneousSituation?.('An account was present in the user storage accounts list but was not found in the internal accounts list after the sync', {
189
197
  userStorageAccountsToBeDeleted,
@@ -195,8 +203,8 @@ export async function syncInternalAccountsWithUserStorage(config, options) {
195
203
  }
196
204
  if (erroneousSituationsFound) {
197
205
  const [finalUserStorageAccountsList, finalInternalAccountsList] = await Promise.all([
198
- getUserStorageAccountsList(options),
199
- getInternalAccountsList(options),
206
+ getUserStorageAccountsList(options, entropySourceId),
207
+ getInternalAccountsList(options, entropySourceId),
200
208
  ]);
201
209
  const doesEveryAccountInInternalAccountsListExistInUserStorageAccountsList = finalInternalAccountsList.every((account) => finalUserStorageAccountsList?.some((userStorageAccount) => userStorageAccount.a === account.address));
202
210
  // istanbul ignore next
@@ -216,9 +224,6 @@ export async function syncInternalAccountsWithUserStorage(config, options) {
216
224
  onAccountSyncErroneousSituation?.('Erroneous situations were found during the sync, and final state does not match the expected state', context);
217
225
  }
218
226
  }
219
- // We do this here and not in the finally statement because we want to make sure that
220
- // the accounts are saved / updated / deleted at least once before we set this flag
221
- await getUserStorageControllerInstance().setHasAccountSyncingSyncedAtLeastOnce(true);
222
227
  }
223
228
  catch (e) {
224
229
  // istanbul ignore next
@@ -1 +1 @@
1
- {"version":3,"file":"controller-integration.mjs","sourceRoot":"","sources":["../../../../src/controllers/user-storage/account-syncing/controller-integration.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,8BAA8B;AACzD,OAAO,EAAE,YAAY,EAAE,qCAAqC;AAG5D,OAAO,EACL,wBAAwB,EACxB,uBAAuB,EACvB,0BAA0B,EAC3B,yBAAqB;AAEtB,OAAO,EACL,wCAAwC,EACxC,wBAAwB,EACxB,sCAAsC,EACvC,oBAAgB;AACjB,OAAO,EAAE,0BAA0B,EAAE,2CAAuC;AAE5E;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,gCAAgC,CACpD,eAAgC,EAChC,OAA8B;IAE9B,MAAM,EAAE,gCAAgC,EAAE,GAAG,OAAO,CAAC;IAErD,IACE,CAAC,wBAAwB,CAAC,OAAO,CAAC;QAClC,CAAC,gBAAgB,CAAC,eAAe,CAAC,IAAI,CAAC;QACvC,CAAC,CAAC,MAAM,wCAAwC,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC,EAC3E;QACA,OAAO;KACR;IAED,IAAI;QACF,8DAA8D;QAC9D,MAAM,aAAa,GACjB,sCAAsC,CAAC,eAAe,CAAC,CAAC;QAE1D,MAAM,gCAAgC,EAAE,CAAC,iBAAiB;QACxD,2BAA2B;QAE3B,GAAG,0BAA0B,CAAC,QAAQ,IAAI,eAAe,CAAC,OAAO,EAAE,EACnE,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,CAC9B,CAAC;KACH;IAAC,OAAO,CAAC,EAAE;QACV,uBAAuB;QACvB,MAAM,YAAY,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;QACxE,MAAM,IAAI,KAAK,CACb,oEAAoE,YAAY,EAAE,CACnF,CAAC;KACH;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,qCAAqC,CACzD,OAA8B;IAE9B,MAAM,EAAE,gCAAgC,EAAE,GAAG,OAAO,CAAC;IAErD,MAAM,oBAAoB,GAAG,MAAM,uBAAuB,CAAC,OAAO,CAAC,CAAC;IAEpE,IAAI,CAAC,oBAAoB,EAAE,MAAM,EAAE;QACjC,OAAO;KACR;IAED,MAAM,2CAA2C,GAAG,oBAAoB,CAAC,GAAG,CAC1E,sCAAsC,CACvC,CAAC;IAEF,MAAM,gCAAgC,EAAE,CAAC,sBAAsB,CAC7D,0BAA0B,CAAC,QAAQ,EACnC,2CAA2C,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;QAC3D,OAAO,CAAC,CAAC;QACT,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;KACxB,CAAC,CACH,CAAC;AACJ,CAAC;AAYD;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,mCAAmC,CACvD,MAAiD,EACjD,OAA8B;IAE9B,IAAI,CAAC,wBAAwB,CAAC,OAAO,CAAC,EAAE;QACtC,OAAO;KACR;IAED,MAAM,EACJ,wBAAwB,GAAG,QAAQ,EACnC,cAAc,EACd,oBAAoB,EACpB,+BAA+B,GAChC,GAAG,MAAM,CAAC;IACX,MAAM,EAAE,YAAY,EAAE,gCAAgC,EAAE,GAAG,OAAO,CAAC;IAEnE,IAAI;QACF,MAAM,gCAAgC,EAAE,CAAC,6BAA6B,CACpE,IAAI,CACL,CAAC;QAEF,MAAM,uBAAuB,GAAG,MAAM,0BAA0B,CAAC,OAAO,CAAC,CAAC;QAE1E,IAAI,CAAC,uBAAuB,IAAI,CAAC,uBAAuB,CAAC,MAAM,EAAE;YAC/D,MAAM,qCAAqC,CAAC,OAAO,CAAC,CAAC;YACrD,MAAM,gCAAgC,EAAE,CAAC,qCAAqC,CAC5E,IAAI,CACL,CAAC;YACF,OAAO;SACR;QACD,kEAAkE;QAClE,sFAAsF;QACtF,IAAI,wBAAwB,GAAG,KAAK,CAAC;QAErC,wEAAwE;QACxE,MAAM,sCAAsC,GAAsB,EAAE,CAAC;QAErE,iEAAiE;QACjE,8BAA8B;QAC9B,MAAM,oBAAoB,GAAG,MAAM,uBAAuB,CAAC,OAAO,CAAC,CAAC;QAEpE,IAAI,CAAC,oBAAoB,IAAI,CAAC,oBAAoB,CAAC,MAAM,EAAE;YACzD,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;SACzD;QAED,MAAM,8CAA8C,GAClD,uBAAuB,CAAC,MAAM,GAAG,oBAAoB,CAAC,MAAM,CAAC;QAE/D,uDAAuD;QACvD,mGAAmG;QACnG,IAAI,8CAA8C,EAAE;YAClD,MAAM,qBAAqB,GACzB,IAAI,CAAC,GAAG,CAAC,uBAAuB,CAAC,MAAM,EAAE,wBAAwB,CAAC;gBAClE,oBAAoB,CAAC,MAAM,CAAC;YAE9B,8DAA8D;YAC9D,2DAA2D;YAC3D,+CAA+C;YAC/C,MAAM,YAAY,EAAE,CAAC,IAAI,CACvB,+BAA+B,EAC/B;gBACE,IAAI,EAAE,YAAY,CAAC,EAAE;gBACrB,KAAK,EAAE,CAAC;aACT,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;gBACpB,MAAM,OAAO,CAAC,WAAW,CAAC,qBAAqB,CAAC,CAAC;YACnD,CAAC,CACF,CAAC;YAEF,2EAA2E;YAC3E,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,qBAAqB,EAAE,CAAC,EAAE,EAAE;gBAC9C,cAAc,EAAE,EAAE,CAAC;aACpB;SACF;QAED,qCAAqC;QACrC,qGAAqG;QACrG,MAAM,6BAA6B,GACjC,MAAM,uBAAuB,CAAC,OAAO,CAAC,CAAC;QAEzC,MAAM,kBAAkB,GAAG,6BAA6B,CAAC,MAAM,CAC7D,CAAC,OAAO,EAAE,EAAE,CACV,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CACnE,CAAC;QAEF,KAAK,MAAM,eAAe,IAAI,6BAA6B,EAAE;YAC3D,MAAM,kBAAkB,GAAG,uBAAuB,CAAC,IAAI,CACrD,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,KAAK,eAAe,CAAC,OAAO,CACnD,CAAC;YAEF,gDAAgD;YAChD,uBAAuB;YACvB,IAAI,CAAC,kBAAkB,EAAE;gBACvB,wGAAwG;gBACxG,IAAI,kBAAkB,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE;oBAChD,wBAAwB,GAAG,IAAI,CAAC;oBAChC,+BAA+B,EAAE,CAC/B,0GAA0G,EAC1G;wBACE,eAAe;wBACf,kBAAkB;wBAClB,kBAAkB;wBAClB,uBAAuB;wBACvB,oBAAoB;wBACpB,6BAA6B;wBAC7B,sCAAsC;qBACvC,CACF,CAAC;oBACF,SAAS;iBACV;gBACD,wHAAwH;gBACxH,sCAAsC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;gBAC7D,SAAS;aACV;YAED,6DAA6D;YAC7D,qEAAqE;YAErE,0CAA0C;YAC1C,MAAM,4BAA4B,GAAG,wBAAwB,CAC3D,eAAe,CAAC,QAAQ,CAAC,IAAI,CAC9B,CAAC;YACF,MAAM,+BAA+B,GAAG,wBAAwB,CAC9D,kBAAkB,CAAC,CAAC,CACrB,CAAC;YAEF,oCAAoC;YACpC,IAAI,4BAA4B,EAAE;gBAChC,IAAI,CAAC,+BAA+B,EAAE;oBACpC,YAAY,EAAE,CAAC,IAAI,CACjB,0CAA0C,EAC1C,eAAe,CAAC,EAAE,EAClB;wBACE,IAAI,EAAE,kBAAkB,CAAC,CAAC;qBAC3B,CACF,CAAC;oBAEF,oBAAoB,EAAE,EAAE,CAAC;iBAC1B;gBACD,SAAS;aACV;YAED,6EAA6E;YAC7E,IAAI,+BAA+B,EAAE;gBACnC,sCAAsC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;gBAC7D,SAAS;aACV;YAED,kCAAkC;YAElC,yDAAyD;YACzD,6EAA6E;YAC7E,IAAI,kBAAkB,CAAC,GAAG,KAAK,SAAS,EAAE;gBACxC,IAAI,eAAe,CAAC,QAAQ,CAAC,iBAAiB,KAAK,SAAS,EAAE;oBAC5D,MAAM,0BAA0B,GAC9B,eAAe,CAAC,QAAQ,CAAC,iBAAiB,GAAG,kBAAkB,CAAC,GAAG,CAAC;oBAEtE,IAAI,0BAA0B,EAAE;wBAC9B,sCAAsC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;wBAC7D,SAAS;qBACV;iBACF;gBAED,YAAY,EAAE,CAAC,IAAI,CACjB,0CAA0C,EAC1C,eAAe,CAAC,EAAE,EAClB;oBACE,IAAI,EAAE,kBAAkB,CAAC,CAAC;oBAC1B,iBAAiB,EAAE,kBAAkB,CAAC,GAAG;iBAC1C,CACF,CAAC;gBAEF,MAAM,0CAA0C,GAC9C,eAAe,CAAC,QAAQ,CAAC,IAAI,KAAK,kBAAkB,CAAC,CAAC,CAAC;gBAEzD,IAAI,CAAC,0CAA0C,EAAE;oBAC/C,oBAAoB,EAAE,EAAE,CAAC;iBAC1B;gBAED,SAAS;aACV;iBAAM,IAAI,eAAe,CAAC,QAAQ,CAAC,iBAAiB,KAAK,SAAS,EAAE;gBACnE,sCAAsC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;gBAC7D,SAAS;aACV;SACF;QAED,sDAAsD;QACtD,IAAI,sCAAsC,CAAC,MAAM,EAAE;YACjD,MAAM,gCAAgC,EAAE,CAAC,sBAAsB,CAC7D,0BAA0B,CAAC,QAAQ,EACnC,sCAAsC,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;gBACtD,OAAO,CAAC,OAAO;gBACf,IAAI,CAAC,SAAS,CAAC,sCAAsC,CAAC,OAAO,CAAC,CAAC;aAChE,CAAC,CACH,CAAC;SACH;QAED,sGAAsG;QACtG,8CAA8C;QAC9C,MAAM,8BAA8B,GAAG,uBAAuB,CAAC,MAAM,CACnE,CAAC,OAAO,EAAE,EAAE,CACV,CAAC,6BAA6B,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,CACtE,CAAC;QAEF,IAAI,8BAA8B,CAAC,MAAM,EAAE;YACzC,MAAM,gCAAgC,EAAE,CAAC,yBAAyB,CAChE,0BAA0B,CAAC,QAAQ,EACnC,8BAA8B,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAC3D,CAAC;YACF,wBAAwB,GAAG,IAAI,CAAC;YAChC,+BAA+B,EAAE,CAC/B,yHAAyH,EACzH;gBACE,8BAA8B;gBAC9B,oBAAoB;gBACpB,6BAA6B;gBAC7B,sCAAsC;gBACtC,uBAAuB;aACxB,CACF,CAAC;SACH;QAED,IAAI,wBAAwB,EAAE;YAC5B,MAAM,CAAC,4BAA4B,EAAE,yBAAyB,CAAC,GAC7D,MAAM,OAAO,CAAC,GAAG,CAAC;gBAChB,0BAA0B,CAAC,OAAO,CAAC;gBACnC,uBAAuB,CAAC,OAAO,CAAC;aACjC,CAAC,CAAC;YAEL,MAAM,oEAAoE,GACxE,yBAAyB,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,EAAE,CAC1C,4BAA4B,EAAE,IAAI,CAChC,CAAC,kBAAkB,EAAE,EAAE,CAAC,kBAAkB,CAAC,CAAC,KAAK,OAAO,CAAC,OAAO,CACjE,CACF,CAAC;YAEJ,uBAAuB;YACvB,MAAM,oEAAoE,GACxE,CAAC,4BAA4B,EAAE,MAAM,IAAI,CAAC,CAAC,GAAG,wBAAwB;gBACpE,CAAC,CAAC,IAAI;gBACN,CAAC,CAAC,4BAA4B,EAAE,KAAK,CAAC,CAAC,OAAO,EAAE,EAAE,CAC9C,yBAAyB,CAAC,IAAI,CAC5B,CAAC,eAAe,EAAE,EAAE,CAAC,eAAe,CAAC,OAAO,KAAK,OAAO,CAAC,CAAC,CAC3D,CACF,CAAC;YAER,MAAM,iBAAiB,GACrB,oEAAoE;gBACpE,oEAAoE,CAAC;YAEvE,MAAM,OAAO,GAAG;gBACd,4BAA4B;gBAC5B,yBAAyB;aAC1B,CAAC;YACF,IAAI,iBAAiB,EAAE;gBACrB,+BAA+B,EAAE,CAC/B,6FAA6F,EAC7F,OAAO,CACR,CAAC;aACH;iBAAM;gBACL,+BAA+B,EAAE,CAC/B,oGAAoG,EACpG,OAAO,CACR,CAAC;aACH;SACF;QAED,qFAAqF;QACrF,mFAAmF;QACnF,MAAM,gCAAgC,EAAE,CAAC,qCAAqC,CAC5E,IAAI,CACL,CAAC;KACH;IAAC,OAAO,CAAC,EAAE;QACV,uBAAuB;QACvB,MAAM,YAAY,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;QACxE,MAAM,IAAI,KAAK,CACb,uEAAuE,YAAY,EAAE,CACtF,CAAC;KACH;YAAS;QACR,MAAM,gCAAgC,EAAE,CAAC,6BAA6B,CACpE,KAAK,CACN,CAAC;KACH;AACH,CAAC","sourcesContent":["import { isEvmAccountType } from '@metamask/keyring-api';\nimport { KeyringTypes } from '@metamask/keyring-controller';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\n\nimport {\n canPerformAccountSyncing,\n getInternalAccountsList,\n getUserStorageAccountsList,\n} from './sync-utils';\nimport type { AccountSyncingOptions } from './types';\nimport {\n isInternalAccountFromPrimarySRPHdKeyring,\n isNameDefaultAccountName,\n mapInternalAccountToUserStorageAccount,\n} from './utils';\nimport { USER_STORAGE_FEATURE_NAMES } from '../../../shared/storage-schema';\n\n/**\n * Saves an individual internal account to the user storage.\n *\n * @param internalAccount - The internal account to save\n * @param options - parameters used for saving the internal account\n */\nexport async function saveInternalAccountToUserStorage(\n internalAccount: InternalAccount,\n options: AccountSyncingOptions,\n): Promise<void> {\n const { getUserStorageControllerInstance } = options;\n\n if (\n !canPerformAccountSyncing(options) ||\n !isEvmAccountType(internalAccount.type) ||\n !(await isInternalAccountFromPrimarySRPHdKeyring(internalAccount, options))\n ) {\n return;\n }\n\n try {\n // Map the internal account to the user storage account schema\n const mappedAccount =\n mapInternalAccountToUserStorageAccount(internalAccount);\n\n await getUserStorageControllerInstance().performSetStorage(\n // ESLint is confused here.\n\n `${USER_STORAGE_FEATURE_NAMES.accounts}.${internalAccount.address}`,\n JSON.stringify(mappedAccount),\n );\n } catch (e) {\n // istanbul ignore next\n const errorMessage = e instanceof Error ? e.message : JSON.stringify(e);\n throw new Error(\n `UserStorageController - failed to save account to user storage - ${errorMessage}`,\n );\n }\n}\n\n/**\n * Saves the list of internal accounts to the user storage.\n *\n * @param options - parameters used for saving the list of internal accounts\n */\nexport async function saveInternalAccountsListToUserStorage(\n options: AccountSyncingOptions,\n): Promise<void> {\n const { getUserStorageControllerInstance } = options;\n\n const internalAccountsList = await getInternalAccountsList(options);\n\n if (!internalAccountsList?.length) {\n return;\n }\n\n const internalAccountsListFormattedForUserStorage = internalAccountsList.map(\n mapInternalAccountToUserStorageAccount,\n );\n\n await getUserStorageControllerInstance().performBatchSetStorage(\n USER_STORAGE_FEATURE_NAMES.accounts,\n internalAccountsListFormattedForUserStorage.map((account) => [\n account.a,\n JSON.stringify(account),\n ]),\n );\n}\n\ntype SyncInternalAccountsWithUserStorageConfig = {\n maxNumberOfAccountsToAdd?: number;\n onAccountAdded?: () => void;\n onAccountNameUpdated?: () => void;\n onAccountSyncErroneousSituation?: (\n errorMessage: string,\n sentryContext?: Record<string, unknown>,\n ) => void;\n};\n\n/**\n * Syncs the internal accounts list with the user storage accounts list.\n * This method is used to make sure that the internal accounts list is up-to-date with the user storage accounts list and vice-versa.\n * It will add new accounts to the internal accounts list, update/merge conflicting names and re-upload the results in some cases to the user storage.\n *\n * @param config - parameters used for syncing the internal accounts list with the user storage accounts list\n * @param options - parameters used for syncing the internal accounts list with the user storage accounts list\n */\nexport async function syncInternalAccountsWithUserStorage(\n config: SyncInternalAccountsWithUserStorageConfig,\n options: AccountSyncingOptions,\n): Promise<void> {\n if (!canPerformAccountSyncing(options)) {\n return;\n }\n\n const {\n maxNumberOfAccountsToAdd = Infinity,\n onAccountAdded,\n onAccountNameUpdated,\n onAccountSyncErroneousSituation,\n } = config;\n const { getMessenger, getUserStorageControllerInstance } = options;\n\n try {\n await getUserStorageControllerInstance().setIsAccountSyncingInProgress(\n true,\n );\n\n const userStorageAccountsList = await getUserStorageAccountsList(options);\n\n if (!userStorageAccountsList || !userStorageAccountsList.length) {\n await saveInternalAccountsListToUserStorage(options);\n await getUserStorageControllerInstance().setHasAccountSyncingSyncedAtLeastOnce(\n true,\n );\n return;\n }\n // Keep a record if erroneous situations are found during the sync\n // This is done so we can send the context to Sentry in case of an erroneous situation\n let erroneousSituationsFound = false;\n\n // Prepare an array of internal accounts to be saved to the user storage\n const internalAccountsToBeSavedToUserStorage: InternalAccount[] = [];\n\n // Compare internal accounts list with user storage accounts list\n // First step: compare lengths\n const internalAccountsList = await getInternalAccountsList(options);\n\n if (!internalAccountsList || !internalAccountsList.length) {\n throw new Error(`Failed to get internal accounts list`);\n }\n\n const hasMoreUserStorageAccountsThanInternalAccounts =\n userStorageAccountsList.length > internalAccountsList.length;\n\n // We don't want to remove existing accounts for a user\n // so we only add new accounts if the user has more accounts in user storage than internal accounts\n if (hasMoreUserStorageAccountsThanInternalAccounts) {\n const numberOfAccountsToAdd =\n Math.min(userStorageAccountsList.length, maxNumberOfAccountsToAdd) -\n internalAccountsList.length;\n\n // Create new accounts to match the user storage accounts list\n // NOTE: we only support the primary SRP HD keyring for now\n // This is why we are hardcoding the index to 0\n await getMessenger().call(\n 'KeyringController:withKeyring',\n {\n type: KeyringTypes.hd,\n index: 0,\n },\n async ({ keyring }) => {\n await keyring.addAccounts(numberOfAccountsToAdd);\n },\n );\n\n // TODO: below code is kept for analytics but should probably be re-thought\n for (let i = 0; i < numberOfAccountsToAdd; i++) {\n onAccountAdded?.();\n }\n }\n\n // Second step: compare account names\n // Get the internal accounts list again since new accounts might have been added in the previous step\n const refreshedInternalAccountsList =\n await getInternalAccountsList(options);\n\n const newlyAddedAccounts = refreshedInternalAccountsList.filter(\n (account) =>\n !internalAccountsList.find((a) => a.address === account.address),\n );\n\n for (const internalAccount of refreshedInternalAccountsList) {\n const userStorageAccount = userStorageAccountsList.find(\n (account) => account.a === internalAccount.address,\n );\n\n // If the account is not present in user storage\n // istanbul ignore next\n if (!userStorageAccount) {\n // If the account was just added in the previous step, skip saving it, it's likely to be a bogus account\n if (newlyAddedAccounts.includes(internalAccount)) {\n erroneousSituationsFound = true;\n onAccountSyncErroneousSituation?.(\n 'An account was added to the internal accounts list but was not present in the user storage accounts list',\n {\n internalAccount,\n userStorageAccount,\n newlyAddedAccounts,\n userStorageAccountsList,\n internalAccountsList,\n refreshedInternalAccountsList,\n internalAccountsToBeSavedToUserStorage,\n },\n );\n continue;\n }\n // Otherwise, it means that this internal account was present before the sync, and needs to be saved to the user storage\n internalAccountsToBeSavedToUserStorage.push(internalAccount);\n continue;\n }\n\n // From this point on, we know that the account is present in\n // both the internal accounts list and the user storage accounts list\n\n // One or both accounts have default names\n const isInternalAccountNameDefault = isNameDefaultAccountName(\n internalAccount.metadata.name,\n );\n const isUserStorageAccountNameDefault = isNameDefaultAccountName(\n userStorageAccount.n,\n );\n\n // Internal account has default name\n if (isInternalAccountNameDefault) {\n if (!isUserStorageAccountNameDefault) {\n getMessenger().call(\n 'AccountsController:updateAccountMetadata',\n internalAccount.id,\n {\n name: userStorageAccount.n,\n },\n );\n\n onAccountNameUpdated?.();\n }\n continue;\n }\n\n // Internal account has custom name but user storage account has default name\n if (isUserStorageAccountNameDefault) {\n internalAccountsToBeSavedToUserStorage.push(internalAccount);\n continue;\n }\n\n // Both accounts have custom names\n\n // User storage account has a nameLastUpdatedAt timestamp\n // Note: not storing the undefined checks in constants to act as a type guard\n if (userStorageAccount.nlu !== undefined) {\n if (internalAccount.metadata.nameLastUpdatedAt !== undefined) {\n const isInternalAccountNameNewer =\n internalAccount.metadata.nameLastUpdatedAt > userStorageAccount.nlu;\n\n if (isInternalAccountNameNewer) {\n internalAccountsToBeSavedToUserStorage.push(internalAccount);\n continue;\n }\n }\n\n getMessenger().call(\n 'AccountsController:updateAccountMetadata',\n internalAccount.id,\n {\n name: userStorageAccount.n,\n nameLastUpdatedAt: userStorageAccount.nlu,\n },\n );\n\n const areInternalAndUserStorageAccountNamesEqual =\n internalAccount.metadata.name === userStorageAccount.n;\n\n if (!areInternalAndUserStorageAccountNamesEqual) {\n onAccountNameUpdated?.();\n }\n\n continue;\n } else if (internalAccount.metadata.nameLastUpdatedAt !== undefined) {\n internalAccountsToBeSavedToUserStorage.push(internalAccount);\n continue;\n }\n }\n\n // Save the internal accounts list to the user storage\n if (internalAccountsToBeSavedToUserStorage.length) {\n await getUserStorageControllerInstance().performBatchSetStorage(\n USER_STORAGE_FEATURE_NAMES.accounts,\n internalAccountsToBeSavedToUserStorage.map((account) => [\n account.address,\n JSON.stringify(mapInternalAccountToUserStorageAccount(account)),\n ]),\n );\n }\n\n // In case we have corrupted user storage with accounts that don't exist in the internal accounts list\n // Delete those accounts from the user storage\n const userStorageAccountsToBeDeleted = userStorageAccountsList.filter(\n (account) =>\n !refreshedInternalAccountsList.find((a) => a.address === account.a),\n );\n\n if (userStorageAccountsToBeDeleted.length) {\n await getUserStorageControllerInstance().performBatchDeleteStorage(\n USER_STORAGE_FEATURE_NAMES.accounts,\n userStorageAccountsToBeDeleted.map((account) => account.a),\n );\n erroneousSituationsFound = true;\n onAccountSyncErroneousSituation?.(\n 'An account was present in the user storage accounts list but was not found in the internal accounts list after the sync',\n {\n userStorageAccountsToBeDeleted,\n internalAccountsList,\n refreshedInternalAccountsList,\n internalAccountsToBeSavedToUserStorage,\n userStorageAccountsList,\n },\n );\n }\n\n if (erroneousSituationsFound) {\n const [finalUserStorageAccountsList, finalInternalAccountsList] =\n await Promise.all([\n getUserStorageAccountsList(options),\n getInternalAccountsList(options),\n ]);\n\n const doesEveryAccountInInternalAccountsListExistInUserStorageAccountsList =\n finalInternalAccountsList.every((account) =>\n finalUserStorageAccountsList?.some(\n (userStorageAccount) => userStorageAccount.a === account.address,\n ),\n );\n\n // istanbul ignore next\n const doesEveryAccountInUserStorageAccountsListExistInInternalAccountsList =\n (finalUserStorageAccountsList?.length || 0) > maxNumberOfAccountsToAdd\n ? true\n : finalUserStorageAccountsList?.every((account) =>\n finalInternalAccountsList.some(\n (internalAccount) => internalAccount.address === account.a,\n ),\n );\n\n const doFinalListsMatch =\n doesEveryAccountInInternalAccountsListExistInUserStorageAccountsList &&\n doesEveryAccountInUserStorageAccountsListExistInInternalAccountsList;\n\n const context = {\n finalUserStorageAccountsList,\n finalInternalAccountsList,\n };\n if (doFinalListsMatch) {\n onAccountSyncErroneousSituation?.(\n 'Erroneous situations were found during the sync, but final state matches the expected state',\n context,\n );\n } else {\n onAccountSyncErroneousSituation?.(\n 'Erroneous situations were found during the sync, and final state does not match the expected state',\n context,\n );\n }\n }\n\n // We do this here and not in the finally statement because we want to make sure that\n // the accounts are saved / updated / deleted at least once before we set this flag\n await getUserStorageControllerInstance().setHasAccountSyncingSyncedAtLeastOnce(\n true,\n );\n } catch (e) {\n // istanbul ignore next\n const errorMessage = e instanceof Error ? e.message : JSON.stringify(e);\n throw new Error(\n `UserStorageController - failed to sync user storage accounts list - ${errorMessage}`,\n );\n } finally {\n await getUserStorageControllerInstance().setIsAccountSyncingInProgress(\n false,\n );\n }\n}\n"]}
1
+ {"version":3,"file":"controller-integration.mjs","sourceRoot":"","sources":["../../../../src/controllers/user-storage/account-syncing/controller-integration.ts"],"names":[],"mappings":"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","sourcesContent":["import { KeyringTypes } from '@metamask/keyring-controller';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\n\nimport {\n canPerformAccountSyncing,\n getInternalAccountsList,\n getUserStorageAccountsList,\n} from './sync-utils';\nimport type { AccountSyncingOptions } from './types';\nimport {\n isNameDefaultAccountName,\n mapInternalAccountToUserStorageAccount,\n} from './utils';\nimport { USER_STORAGE_FEATURE_NAMES } from '../../../shared/storage-schema';\n\n/**\n * Saves an individual internal account to the user storage.\n *\n * @param internalAccount - The internal account to save\n * @param options - parameters used for saving the internal account\n */\nexport async function saveInternalAccountToUserStorage(\n internalAccount: InternalAccount,\n options: AccountSyncingOptions,\n): Promise<void> {\n const { getUserStorageControllerInstance, getMessenger } = options;\n\n if (\n !canPerformAccountSyncing(options) ||\n internalAccount.metadata.keyring.type !== String(KeyringTypes.hd) // sync only EVM accounts until we support multichain accounts\n ) {\n return;\n }\n\n // Refresh the internal accounts list so that it populates entropySourceId and derivationPath for all accounts\n await getMessenger().call('AccountsController:updateAccounts');\n // Find back our account from this refreshed list\n const internalAccountsList = getMessenger().call(\n 'AccountsController:listAccounts',\n );\n\n const internalAccountFromList = internalAccountsList.find(\n (account) => account.address === internalAccount.address,\n );\n\n // This should never happen because users don't have the ability to remove an accounts\n // but if it does, we throw an error\n // istanbul ignore next\n if (!internalAccountFromList) {\n throw new Error(\n `UserStorageController - failed to find internal account in the list - ${internalAccount.address}`,\n );\n }\n\n const entropySourceId = JSON.stringify(\n internalAccountFromList.options.entropySource,\n );\n\n try {\n // Map the internal account to the user storage account schema\n const mappedAccount = mapInternalAccountToUserStorageAccount(\n internalAccountFromList,\n );\n\n await getUserStorageControllerInstance().performSetStorage(\n `${USER_STORAGE_FEATURE_NAMES.accounts}.${internalAccountFromList.address}`,\n JSON.stringify(mappedAccount),\n entropySourceId,\n );\n } catch (e) {\n // istanbul ignore next\n const errorMessage = e instanceof Error ? e.message : JSON.stringify(e);\n throw new Error(\n `UserStorageController - failed to save account to user storage - ${errorMessage}`,\n );\n }\n}\n\n/**\n * Saves the list of internal accounts to the user storage.\n *\n * @param options - parameters used for saving the list of internal accounts\n * @param entropySourceId - The entropy source ID used to derive the key,\n * when multiple sources are available (Multi-SRP).\n */\nexport async function saveInternalAccountsListToUserStorage(\n options: AccountSyncingOptions,\n entropySourceId: string,\n): Promise<void> {\n const { getUserStorageControllerInstance } = options;\n\n const internalAccountsList = await getInternalAccountsList(\n options,\n entropySourceId,\n );\n\n if (!internalAccountsList?.length) {\n return;\n }\n\n const internalAccountsListFormattedForUserStorage = internalAccountsList.map(\n mapInternalAccountToUserStorageAccount,\n );\n\n await getUserStorageControllerInstance().performBatchSetStorage(\n USER_STORAGE_FEATURE_NAMES.accounts,\n internalAccountsListFormattedForUserStorage.map((account) => [\n account.a,\n JSON.stringify(account),\n ]),\n entropySourceId,\n );\n}\n\ntype SyncInternalAccountsWithUserStorageConfig = {\n maxNumberOfAccountsToAdd?: number;\n onAccountAdded?: () => void;\n onAccountNameUpdated?: () => void;\n onAccountSyncErroneousSituation?: (\n errorMessage: string,\n sentryContext?: Record<string, unknown>,\n ) => void;\n};\n\n/**\n * Syncs the internal accounts list with the user storage accounts list.\n * This method is used to make sure that the internal accounts list is up-to-date with the user storage accounts list and vice-versa.\n * It will add new accounts to the internal accounts list, update/merge conflicting names and re-upload the results in some cases to the user storage.\n *\n * @param config - parameters used for syncing the internal accounts list with the user storage accounts list\n * @param options - parameters used for syncing the internal accounts list with the user storage accounts list\n * @param entropySourceId - The entropy source ID used to derive the key,\n */\nexport async function syncInternalAccountsWithUserStorage(\n config: SyncInternalAccountsWithUserStorageConfig,\n options: AccountSyncingOptions,\n entropySourceId: string,\n): Promise<void> {\n if (!canPerformAccountSyncing(options)) {\n return;\n }\n\n const {\n maxNumberOfAccountsToAdd = Infinity,\n onAccountAdded,\n onAccountNameUpdated,\n onAccountSyncErroneousSituation,\n } = config;\n const { getMessenger, getUserStorageControllerInstance } = options;\n\n try {\n await getUserStorageControllerInstance().setIsAccountSyncingInProgress(\n true,\n );\n\n const userStorageAccountsList = await getUserStorageAccountsList(\n options,\n entropySourceId,\n );\n\n if (!userStorageAccountsList || !userStorageAccountsList.length) {\n await saveInternalAccountsListToUserStorage(options, entropySourceId);\n return;\n }\n // Keep a record if erroneous situations are found during the sync\n // This is done so we can send the context to Sentry in case of an erroneous situation\n let erroneousSituationsFound = false;\n\n // Prepare an array of internal accounts to be saved to the user storage\n const internalAccountsToBeSavedToUserStorage: InternalAccount[] = [];\n\n // Compare internal accounts list with user storage accounts list\n // First step: compare lengths\n const internalAccountsList = await getInternalAccountsList(\n options,\n entropySourceId,\n );\n\n if (!internalAccountsList || !internalAccountsList.length) {\n throw new Error(`Failed to get internal accounts list`);\n }\n\n const hasMoreUserStorageAccountsThanInternalAccounts =\n userStorageAccountsList.length > internalAccountsList.length;\n\n // We don't want to remove existing accounts for a user\n // so we only add new accounts if the user has more accounts in user storage than internal accounts\n if (hasMoreUserStorageAccountsThanInternalAccounts) {\n const numberOfAccountsToAdd =\n Math.min(userStorageAccountsList.length, maxNumberOfAccountsToAdd) -\n internalAccountsList.length;\n\n // Create new accounts to match the user storage accounts list\n await getMessenger().call(\n 'KeyringController:withKeyring',\n {\n id: entropySourceId,\n },\n async ({ keyring }) => {\n await keyring.addAccounts(numberOfAccountsToAdd);\n },\n );\n\n // TODO: below code is kept for analytics but should probably be re-thought\n for (let i = 0; i < numberOfAccountsToAdd; i++) {\n onAccountAdded?.();\n }\n }\n\n // Second step: compare account names\n // Get the internal accounts list again since new accounts might have been added in the previous step\n const refreshedInternalAccountsList = await getInternalAccountsList(\n options,\n entropySourceId,\n );\n\n const newlyAddedAccounts = refreshedInternalAccountsList.filter(\n (account) =>\n !internalAccountsList.find((a) => a.address === account.address),\n );\n\n for (const internalAccount of refreshedInternalAccountsList) {\n const userStorageAccount = userStorageAccountsList.find(\n (account) => account.a === internalAccount.address,\n );\n\n // If the account is not present in user storage\n // istanbul ignore next\n if (!userStorageAccount) {\n // If the account was just added in the previous step, skip saving it, it's likely to be a bogus account\n if (newlyAddedAccounts.includes(internalAccount)) {\n erroneousSituationsFound = true;\n onAccountSyncErroneousSituation?.(\n 'An account was added to the internal accounts list but was not present in the user storage accounts list',\n {\n internalAccount,\n userStorageAccount,\n newlyAddedAccounts,\n userStorageAccountsList,\n internalAccountsList,\n refreshedInternalAccountsList,\n internalAccountsToBeSavedToUserStorage,\n },\n );\n continue;\n }\n // Otherwise, it means that this internal account was present before the sync, and needs to be saved to the user storage\n internalAccountsToBeSavedToUserStorage.push(internalAccount);\n continue;\n }\n\n // From this point on, we know that the account is present in\n // both the internal accounts list and the user storage accounts list\n\n // One or both accounts have default names\n const isInternalAccountNameDefault = isNameDefaultAccountName(\n internalAccount.metadata.name,\n );\n const isUserStorageAccountNameDefault = isNameDefaultAccountName(\n userStorageAccount.n,\n );\n\n // Internal account has default name\n if (isInternalAccountNameDefault) {\n if (!isUserStorageAccountNameDefault) {\n getMessenger().call(\n 'AccountsController:updateAccountMetadata',\n internalAccount.id,\n {\n name: userStorageAccount.n,\n },\n );\n\n onAccountNameUpdated?.();\n }\n continue;\n }\n\n // Internal account has custom name but user storage account has default name\n if (isUserStorageAccountNameDefault) {\n internalAccountsToBeSavedToUserStorage.push(internalAccount);\n continue;\n }\n\n // Both accounts have custom names\n\n // User storage account has a nameLastUpdatedAt timestamp\n // Note: not storing the undefined checks in constants to act as a type guard\n if (userStorageAccount.nlu !== undefined) {\n if (internalAccount.metadata.nameLastUpdatedAt !== undefined) {\n const isInternalAccountNameNewer =\n internalAccount.metadata.nameLastUpdatedAt > userStorageAccount.nlu;\n\n if (isInternalAccountNameNewer) {\n internalAccountsToBeSavedToUserStorage.push(internalAccount);\n continue;\n }\n }\n\n getMessenger().call(\n 'AccountsController:updateAccountMetadata',\n internalAccount.id,\n {\n name: userStorageAccount.n,\n nameLastUpdatedAt: userStorageAccount.nlu,\n },\n );\n\n const areInternalAndUserStorageAccountNamesEqual =\n internalAccount.metadata.name === userStorageAccount.n;\n\n if (!areInternalAndUserStorageAccountNamesEqual) {\n onAccountNameUpdated?.();\n }\n\n continue;\n } else if (internalAccount.metadata.nameLastUpdatedAt !== undefined) {\n internalAccountsToBeSavedToUserStorage.push(internalAccount);\n continue;\n }\n }\n\n // Save the internal accounts list to the user storage\n if (internalAccountsToBeSavedToUserStorage.length) {\n await getUserStorageControllerInstance().performBatchSetStorage(\n USER_STORAGE_FEATURE_NAMES.accounts,\n internalAccountsToBeSavedToUserStorage.map((account) => [\n account.address,\n JSON.stringify(mapInternalAccountToUserStorageAccount(account)),\n ]),\n entropySourceId,\n );\n }\n\n // In case we have corrupted user storage with accounts that don't exist in the internal accounts list\n // Delete those accounts from the user storage\n const userStorageAccountsToBeDeleted = userStorageAccountsList.filter(\n (account) =>\n !refreshedInternalAccountsList.find((a) => a.address === account.a),\n );\n\n if (userStorageAccountsToBeDeleted.length) {\n await getUserStorageControllerInstance().performBatchDeleteStorage(\n USER_STORAGE_FEATURE_NAMES.accounts,\n userStorageAccountsToBeDeleted.map((account) => account.a),\n entropySourceId,\n );\n erroneousSituationsFound = true;\n onAccountSyncErroneousSituation?.(\n 'An account was present in the user storage accounts list but was not found in the internal accounts list after the sync',\n {\n userStorageAccountsToBeDeleted,\n internalAccountsList,\n refreshedInternalAccountsList,\n internalAccountsToBeSavedToUserStorage,\n userStorageAccountsList,\n },\n );\n }\n\n if (erroneousSituationsFound) {\n const [finalUserStorageAccountsList, finalInternalAccountsList] =\n await Promise.all([\n getUserStorageAccountsList(options, entropySourceId),\n getInternalAccountsList(options, entropySourceId),\n ]);\n\n const doesEveryAccountInInternalAccountsListExistInUserStorageAccountsList =\n finalInternalAccountsList.every((account) =>\n finalUserStorageAccountsList?.some(\n (userStorageAccount) => userStorageAccount.a === account.address,\n ),\n );\n\n // istanbul ignore next\n const doesEveryAccountInUserStorageAccountsListExistInInternalAccountsList =\n (finalUserStorageAccountsList?.length || 0) > maxNumberOfAccountsToAdd\n ? true\n : finalUserStorageAccountsList?.every((account) =>\n finalInternalAccountsList.some(\n (internalAccount) => internalAccount.address === account.a,\n ),\n );\n\n const doFinalListsMatch =\n doesEveryAccountInInternalAccountsListExistInUserStorageAccountsList &&\n doesEveryAccountInUserStorageAccountsListExistInInternalAccountsList;\n\n const context = {\n finalUserStorageAccountsList,\n finalInternalAccountsList,\n };\n if (doFinalListsMatch) {\n onAccountSyncErroneousSituation?.(\n 'Erroneous situations were found during the sync, but final state matches the expected state',\n context,\n );\n } else {\n onAccountSyncErroneousSituation?.(\n 'Erroneous situations were found during the sync, and final state does not match the expected state',\n context,\n );\n }\n }\n } catch (e) {\n // istanbul ignore next\n const errorMessage = e instanceof Error ? e.message : JSON.stringify(e);\n throw new Error(\n `UserStorageController - failed to sync user storage accounts list - ${errorMessage}`,\n );\n } finally {\n await getUserStorageControllerInstance().setIsAccountSyncingInProgress(\n false,\n );\n }\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getUserStorageAccountsList = exports.getInternalAccountsList = exports.canPerformAccountSyncing = void 0;
4
- const utils_1 = require("./utils.cjs");
4
+ const keyring_controller_1 = require("@metamask/keyring-controller");
5
5
  const storage_schema_1 = require("../../../shared/storage-schema.cjs");
6
6
  /**
7
7
  * Checks if account syncing can be performed based on a set of conditions
@@ -28,24 +28,29 @@ exports.canPerformAccountSyncing = canPerformAccountSyncing;
28
28
  * and are from the HD keyring
29
29
  *
30
30
  * @param options - parameters used for getting the list of internal accounts
31
+ * @param entropySourceId - The entropy source ID used to derive the key,
32
+ * when multiple sources are available (Multi-SRP).
31
33
  * @returns the list of internal accounts
32
34
  */
33
- async function getInternalAccountsList(options) {
35
+ async function getInternalAccountsList(options, entropySourceId) {
34
36
  const { getMessenger } = options;
35
- // eslint-disable-next-line @typescript-eslint/await-thenable
36
- const internalAccountsList = await getMessenger().call('AccountsController:listAccounts');
37
- return await (0, utils_1.mapInternalAccountsListToPrimarySRPHdKeyringInternalAccountsList)(internalAccountsList, options);
37
+ await getMessenger().call('AccountsController:updateAccounts');
38
+ const internalAccountsList = getMessenger().call('AccountsController:listAccounts');
39
+ return internalAccountsList.filter((account) => entropySourceId === account.options.entropySource &&
40
+ account.metadata.keyring.type === String(keyring_controller_1.KeyringTypes.hd));
38
41
  }
39
42
  exports.getInternalAccountsList = getInternalAccountsList;
40
43
  /**
41
44
  * Get the list of user storage accounts
42
45
  *
43
46
  * @param options - parameters used for getting the list of user storage accounts
47
+ * @param entropySourceId - The entropy source ID used to derive the storage key,
48
+ * when multiple sources are available (Multi-SRP).
44
49
  * @returns the list of user storage accounts
45
50
  */
46
- async function getUserStorageAccountsList(options) {
51
+ async function getUserStorageAccountsList(options, entropySourceId) {
47
52
  const { getUserStorageControllerInstance } = options;
48
- const rawAccountsListResponse = await getUserStorageControllerInstance().performGetStorageAllFeatureEntries(storage_schema_1.USER_STORAGE_FEATURE_NAMES.accounts);
53
+ const rawAccountsListResponse = await getUserStorageControllerInstance().performGetStorageAllFeatureEntries(storage_schema_1.USER_STORAGE_FEATURE_NAMES.accounts, entropySourceId);
49
54
  return (rawAccountsListResponse?.map((rawAccount) => JSON.parse(rawAccount)) ?? null);
50
55
  }
51
56
  exports.getUserStorageAccountsList = getUserStorageAccountsList;
@@ -1 +1 @@
1
- {"version":3,"file":"sync-utils.cjs","sourceRoot":"","sources":["../../../../src/controllers/user-storage/account-syncing/sync-utils.ts"],"names":[],"mappings":";;;AAGA,uCAA2F;AAC3F,uEAA4E;AAE5E;;;;;GAKG;AACH,SAAgB,wBAAwB,CACtC,OAA8B;IAE9B,MAAM,EAAE,YAAY,EAAE,gCAAgC,EAAE,GAAG,OAAO,CAAC;IAEnE,MAAM,EACJ,sBAAsB,EACtB,uBAAuB,EACvB,0BAA0B,GAC3B,GAAG,gCAAgC,EAAE,CAAC,KAAK,CAAC;IAC7C,MAAM,aAAa,GAAG,YAAY,EAAE,CAAC,IAAI,CACvC,qCAAqC,CACtC,CAAC;IAEF,IACE,CAAC,sBAAsB;QACvB,CAAC,uBAAuB;QACxB,CAAC,aAAa;QACd,0BAA0B,EAC1B;QACA,OAAO,KAAK,CAAC;KACd;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAxBD,4DAwBC;AAED;;;;;;;GAOG;AACI,KAAK,UAAU,uBAAuB,CAC3C,OAA8B;IAE9B,MAAM,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC;IAEjC,6DAA6D;IAC7D,MAAM,oBAAoB,GAAG,MAAM,YAAY,EAAE,CAAC,IAAI,CACpD,iCAAiC,CAClC,CAAC;IAEF,OAAO,MAAM,IAAA,wEAAgE,EAC3E,oBAAoB,EACpB,OAAO,CACR,CAAC;AACJ,CAAC;AAdD,0DAcC;AAED;;;;;GAKG;AACI,KAAK,UAAU,0BAA0B,CAC9C,OAA8B;IAE9B,MAAM,EAAE,gCAAgC,EAAE,GAAG,OAAO,CAAC;IAErD,MAAM,uBAAuB,GAC3B,MAAM,gCAAgC,EAAE,CAAC,kCAAkC,CACzE,2CAA0B,CAAC,QAAQ,CACpC,CAAC;IAEJ,OAAO,CACL,uBAAuB,EAAE,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,IAAI,IAAI,CAC7E,CAAC;AACJ,CAAC;AAbD,gEAaC","sourcesContent":["import type { InternalAccount } from '@metamask/keyring-internal-api';\n\nimport type { AccountSyncingOptions, UserStorageAccount } from './types';\nimport { mapInternalAccountsListToPrimarySRPHdKeyringInternalAccountsList } from './utils';\nimport { USER_STORAGE_FEATURE_NAMES } from '../../../shared/storage-schema';\n\n/**\n * Checks if account syncing can be performed based on a set of conditions\n *\n * @param options - parameters used for checking if account syncing can be performed\n * @returns Returns true if account syncing can be performed, false otherwise.\n */\nexport function canPerformAccountSyncing(\n options: AccountSyncingOptions,\n): boolean {\n const { getMessenger, getUserStorageControllerInstance } = options;\n\n const {\n isBackupAndSyncEnabled,\n isAccountSyncingEnabled,\n isAccountSyncingInProgress,\n } = getUserStorageControllerInstance().state;\n const isAuthEnabled = getMessenger().call(\n 'AuthenticationController:isSignedIn',\n );\n\n if (\n !isBackupAndSyncEnabled ||\n !isAccountSyncingEnabled ||\n !isAuthEnabled ||\n isAccountSyncingInProgress\n ) {\n return false;\n }\n\n return true;\n}\n\n/**\n * Get the list of internal accounts\n * This function returns only the internal accounts that are from the primary SRP\n * and are from the HD keyring\n *\n * @param options - parameters used for getting the list of internal accounts\n * @returns the list of internal accounts\n */\nexport async function getInternalAccountsList(\n options: AccountSyncingOptions,\n): Promise<InternalAccount[]> {\n const { getMessenger } = options;\n\n // eslint-disable-next-line @typescript-eslint/await-thenable\n const internalAccountsList = await getMessenger().call(\n 'AccountsController:listAccounts',\n );\n\n return await mapInternalAccountsListToPrimarySRPHdKeyringInternalAccountsList(\n internalAccountsList,\n options,\n );\n}\n\n/**\n * Get the list of user storage accounts\n *\n * @param options - parameters used for getting the list of user storage accounts\n * @returns the list of user storage accounts\n */\nexport async function getUserStorageAccountsList(\n options: AccountSyncingOptions,\n): Promise<UserStorageAccount[] | null> {\n const { getUserStorageControllerInstance } = options;\n\n const rawAccountsListResponse =\n await getUserStorageControllerInstance().performGetStorageAllFeatureEntries(\n USER_STORAGE_FEATURE_NAMES.accounts,\n );\n\n return (\n rawAccountsListResponse?.map((rawAccount) => JSON.parse(rawAccount)) ?? null\n );\n}\n"]}
1
+ {"version":3,"file":"sync-utils.cjs","sourceRoot":"","sources":["../../../../src/controllers/user-storage/account-syncing/sync-utils.ts"],"names":[],"mappings":";;;AAAA,qEAA4D;AAI5D,uEAA4E;AAE5E;;;;;GAKG;AACH,SAAgB,wBAAwB,CACtC,OAA8B;IAE9B,MAAM,EAAE,YAAY,EAAE,gCAAgC,EAAE,GAAG,OAAO,CAAC;IAEnE,MAAM,EACJ,sBAAsB,EACtB,uBAAuB,EACvB,0BAA0B,GAC3B,GAAG,gCAAgC,EAAE,CAAC,KAAK,CAAC;IAC7C,MAAM,aAAa,GAAG,YAAY,EAAE,CAAC,IAAI,CACvC,qCAAqC,CACtC,CAAC;IAEF,IACE,CAAC,sBAAsB;QACvB,CAAC,uBAAuB;QACxB,CAAC,aAAa;QACd,0BAA0B,EAC1B;QACA,OAAO,KAAK,CAAC;KACd;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAxBD,4DAwBC;AAED;;;;;;;;;GASG;AACI,KAAK,UAAU,uBAAuB,CAC3C,OAA8B,EAC9B,eAAuB;IAEvB,MAAM,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC;IAEjC,MAAM,YAAY,EAAE,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;IAE/D,MAAM,oBAAoB,GAAG,YAAY,EAAE,CAAC,IAAI,CAC9C,iCAAiC,CAClC,CAAC;IAEF,OAAO,oBAAoB,CAAC,MAAM,CAChC,CAAC,OAAO,EAAE,EAAE,CACV,eAAe,KAAK,OAAO,CAAC,OAAO,CAAC,aAAa;QACjD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,KAAK,MAAM,CAAC,iCAAY,CAAC,EAAE,CAAC,CAC5D,CAAC;AACJ,CAAC;AAjBD,0DAiBC;AAED;;;;;;;GAOG;AACI,KAAK,UAAU,0BAA0B,CAC9C,OAA8B,EAC9B,eAAwB;IAExB,MAAM,EAAE,gCAAgC,EAAE,GAAG,OAAO,CAAC;IAErD,MAAM,uBAAuB,GAC3B,MAAM,gCAAgC,EAAE,CAAC,kCAAkC,CACzE,2CAA0B,CAAC,QAAQ,EACnC,eAAe,CAChB,CAAC;IAEJ,OAAO,CACL,uBAAuB,EAAE,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,IAAI,IAAI,CAC7E,CAAC;AACJ,CAAC;AAfD,gEAeC","sourcesContent":["import { KeyringTypes } from '@metamask/keyring-controller';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\n\nimport type { AccountSyncingOptions, UserStorageAccount } from './types';\nimport { USER_STORAGE_FEATURE_NAMES } from '../../../shared/storage-schema';\n\n/**\n * Checks if account syncing can be performed based on a set of conditions\n *\n * @param options - parameters used for checking if account syncing can be performed\n * @returns Returns true if account syncing can be performed, false otherwise.\n */\nexport function canPerformAccountSyncing(\n options: AccountSyncingOptions,\n): boolean {\n const { getMessenger, getUserStorageControllerInstance } = options;\n\n const {\n isBackupAndSyncEnabled,\n isAccountSyncingEnabled,\n isAccountSyncingInProgress,\n } = getUserStorageControllerInstance().state;\n const isAuthEnabled = getMessenger().call(\n 'AuthenticationController:isSignedIn',\n );\n\n if (\n !isBackupAndSyncEnabled ||\n !isAccountSyncingEnabled ||\n !isAuthEnabled ||\n isAccountSyncingInProgress\n ) {\n return false;\n }\n\n return true;\n}\n\n/**\n * Get the list of internal accounts\n * This function returns only the internal accounts that are from the primary SRP\n * and are from the HD keyring\n *\n * @param options - parameters used for getting the list of internal accounts\n * @param entropySourceId - The entropy source ID used to derive the key,\n * when multiple sources are available (Multi-SRP).\n * @returns the list of internal accounts\n */\nexport async function getInternalAccountsList(\n options: AccountSyncingOptions,\n entropySourceId: string,\n): Promise<InternalAccount[]> {\n const { getMessenger } = options;\n\n await getMessenger().call('AccountsController:updateAccounts');\n\n const internalAccountsList = getMessenger().call(\n 'AccountsController:listAccounts',\n );\n\n return internalAccountsList.filter(\n (account) =>\n entropySourceId === account.options.entropySource &&\n account.metadata.keyring.type === String(KeyringTypes.hd), // sync only EVM accounts until we support multichain accounts\n );\n}\n\n/**\n * Get the list of user storage accounts\n *\n * @param options - parameters used for getting the list of user storage accounts\n * @param entropySourceId - The entropy source ID used to derive the storage key,\n * when multiple sources are available (Multi-SRP).\n * @returns the list of user storage accounts\n */\nexport async function getUserStorageAccountsList(\n options: AccountSyncingOptions,\n entropySourceId?: string,\n): Promise<UserStorageAccount[] | null> {\n const { getUserStorageControllerInstance } = options;\n\n const rawAccountsListResponse =\n await getUserStorageControllerInstance().performGetStorageAllFeatureEntries(\n USER_STORAGE_FEATURE_NAMES.accounts,\n entropySourceId,\n );\n\n return (\n rawAccountsListResponse?.map((rawAccount) => JSON.parse(rawAccount)) ?? null\n );\n}\n"]}
@@ -13,14 +13,18 @@ export declare function canPerformAccountSyncing(options: AccountSyncingOptions)
13
13
  * and are from the HD keyring
14
14
  *
15
15
  * @param options - parameters used for getting the list of internal accounts
16
+ * @param entropySourceId - The entropy source ID used to derive the key,
17
+ * when multiple sources are available (Multi-SRP).
16
18
  * @returns the list of internal accounts
17
19
  */
18
- export declare function getInternalAccountsList(options: AccountSyncingOptions): Promise<InternalAccount[]>;
20
+ export declare function getInternalAccountsList(options: AccountSyncingOptions, entropySourceId: string): Promise<InternalAccount[]>;
19
21
  /**
20
22
  * Get the list of user storage accounts
21
23
  *
22
24
  * @param options - parameters used for getting the list of user storage accounts
25
+ * @param entropySourceId - The entropy source ID used to derive the storage key,
26
+ * when multiple sources are available (Multi-SRP).
23
27
  * @returns the list of user storage accounts
24
28
  */
25
- export declare function getUserStorageAccountsList(options: AccountSyncingOptions): Promise<UserStorageAccount[] | null>;
29
+ export declare function getUserStorageAccountsList(options: AccountSyncingOptions, entropySourceId?: string): Promise<UserStorageAccount[] | null>;
26
30
  //# sourceMappingURL=sync-utils.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sync-utils.d.cts","sourceRoot":"","sources":["../../../../src/controllers/user-storage/account-syncing/sync-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,uCAAuC;AAEtE,OAAO,KAAK,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,oBAAgB;AAIzE;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAsBT;AAED;;;;;;;GAOG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,eAAe,EAAE,CAAC,CAY5B;AAED;;;;;GAKG;AACH,wBAAsB,0BAA0B,CAC9C,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,kBAAkB,EAAE,GAAG,IAAI,CAAC,CAWtC"}
1
+ {"version":3,"file":"sync-utils.d.cts","sourceRoot":"","sources":["../../../../src/controllers/user-storage/account-syncing/sync-utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,uCAAuC;AAEtE,OAAO,KAAK,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,oBAAgB;AAGzE;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAsBT;AAED;;;;;;;;;GASG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,qBAAqB,EAC9B,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,eAAe,EAAE,CAAC,CAc5B;AAED;;;;;;;GAOG;AACH,wBAAsB,0BAA0B,CAC9C,OAAO,EAAE,qBAAqB,EAC9B,eAAe,CAAC,EAAE,MAAM,GACvB,OAAO,CAAC,kBAAkB,EAAE,GAAG,IAAI,CAAC,CAYtC"}
@@ -13,14 +13,18 @@ export declare function canPerformAccountSyncing(options: AccountSyncingOptions)
13
13
  * and are from the HD keyring
14
14
  *
15
15
  * @param options - parameters used for getting the list of internal accounts
16
+ * @param entropySourceId - The entropy source ID used to derive the key,
17
+ * when multiple sources are available (Multi-SRP).
16
18
  * @returns the list of internal accounts
17
19
  */
18
- export declare function getInternalAccountsList(options: AccountSyncingOptions): Promise<InternalAccount[]>;
20
+ export declare function getInternalAccountsList(options: AccountSyncingOptions, entropySourceId: string): Promise<InternalAccount[]>;
19
21
  /**
20
22
  * Get the list of user storage accounts
21
23
  *
22
24
  * @param options - parameters used for getting the list of user storage accounts
25
+ * @param entropySourceId - The entropy source ID used to derive the storage key,
26
+ * when multiple sources are available (Multi-SRP).
23
27
  * @returns the list of user storage accounts
24
28
  */
25
- export declare function getUserStorageAccountsList(options: AccountSyncingOptions): Promise<UserStorageAccount[] | null>;
29
+ export declare function getUserStorageAccountsList(options: AccountSyncingOptions, entropySourceId?: string): Promise<UserStorageAccount[] | null>;
26
30
  //# sourceMappingURL=sync-utils.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sync-utils.d.mts","sourceRoot":"","sources":["../../../../src/controllers/user-storage/account-syncing/sync-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,uCAAuC;AAEtE,OAAO,KAAK,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,oBAAgB;AAIzE;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAsBT;AAED;;;;;;;GAOG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,eAAe,EAAE,CAAC,CAY5B;AAED;;;;;GAKG;AACH,wBAAsB,0BAA0B,CAC9C,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,kBAAkB,EAAE,GAAG,IAAI,CAAC,CAWtC"}
1
+ {"version":3,"file":"sync-utils.d.mts","sourceRoot":"","sources":["../../../../src/controllers/user-storage/account-syncing/sync-utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,uCAAuC;AAEtE,OAAO,KAAK,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,oBAAgB;AAGzE;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAsBT;AAED;;;;;;;;;GASG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,qBAAqB,EAC9B,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,eAAe,EAAE,CAAC,CAc5B;AAED;;;;;;;GAOG;AACH,wBAAsB,0BAA0B,CAC9C,OAAO,EAAE,qBAAqB,EAC9B,eAAe,CAAC,EAAE,MAAM,GACvB,OAAO,CAAC,kBAAkB,EAAE,GAAG,IAAI,CAAC,CAYtC"}
@@ -1,4 +1,4 @@
1
- import { mapInternalAccountsListToPrimarySRPHdKeyringInternalAccountsList } from "./utils.mjs";
1
+ import { KeyringTypes } from "@metamask/keyring-controller";
2
2
  import { USER_STORAGE_FEATURE_NAMES } from "../../../shared/storage-schema.mjs";
3
3
  /**
4
4
  * Checks if account syncing can be performed based on a set of conditions
@@ -24,23 +24,28 @@ export function canPerformAccountSyncing(options) {
24
24
  * and are from the HD keyring
25
25
  *
26
26
  * @param options - parameters used for getting the list of internal accounts
27
+ * @param entropySourceId - The entropy source ID used to derive the key,
28
+ * when multiple sources are available (Multi-SRP).
27
29
  * @returns the list of internal accounts
28
30
  */
29
- export async function getInternalAccountsList(options) {
31
+ export async function getInternalAccountsList(options, entropySourceId) {
30
32
  const { getMessenger } = options;
31
- // eslint-disable-next-line @typescript-eslint/await-thenable
32
- const internalAccountsList = await getMessenger().call('AccountsController:listAccounts');
33
- return await mapInternalAccountsListToPrimarySRPHdKeyringInternalAccountsList(internalAccountsList, options);
33
+ await getMessenger().call('AccountsController:updateAccounts');
34
+ const internalAccountsList = getMessenger().call('AccountsController:listAccounts');
35
+ return internalAccountsList.filter((account) => entropySourceId === account.options.entropySource &&
36
+ account.metadata.keyring.type === String(KeyringTypes.hd));
34
37
  }
35
38
  /**
36
39
  * Get the list of user storage accounts
37
40
  *
38
41
  * @param options - parameters used for getting the list of user storage accounts
42
+ * @param entropySourceId - The entropy source ID used to derive the storage key,
43
+ * when multiple sources are available (Multi-SRP).
39
44
  * @returns the list of user storage accounts
40
45
  */
41
- export async function getUserStorageAccountsList(options) {
46
+ export async function getUserStorageAccountsList(options, entropySourceId) {
42
47
  const { getUserStorageControllerInstance } = options;
43
- const rawAccountsListResponse = await getUserStorageControllerInstance().performGetStorageAllFeatureEntries(USER_STORAGE_FEATURE_NAMES.accounts);
48
+ const rawAccountsListResponse = await getUserStorageControllerInstance().performGetStorageAllFeatureEntries(USER_STORAGE_FEATURE_NAMES.accounts, entropySourceId);
44
49
  return (rawAccountsListResponse?.map((rawAccount) => JSON.parse(rawAccount)) ?? null);
45
50
  }
46
51
  //# sourceMappingURL=sync-utils.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"sync-utils.mjs","sourceRoot":"","sources":["../../../../src/controllers/user-storage/account-syncing/sync-utils.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,gEAAgE,EAAE,oBAAgB;AAC3F,OAAO,EAAE,0BAA0B,EAAE,2CAAuC;AAE5E;;;;;GAKG;AACH,MAAM,UAAU,wBAAwB,CACtC,OAA8B;IAE9B,MAAM,EAAE,YAAY,EAAE,gCAAgC,EAAE,GAAG,OAAO,CAAC;IAEnE,MAAM,EACJ,sBAAsB,EACtB,uBAAuB,EACvB,0BAA0B,GAC3B,GAAG,gCAAgC,EAAE,CAAC,KAAK,CAAC;IAC7C,MAAM,aAAa,GAAG,YAAY,EAAE,CAAC,IAAI,CACvC,qCAAqC,CACtC,CAAC;IAEF,IACE,CAAC,sBAAsB;QACvB,CAAC,uBAAuB;QACxB,CAAC,aAAa;QACd,0BAA0B,EAC1B;QACA,OAAO,KAAK,CAAC;KACd;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,OAA8B;IAE9B,MAAM,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC;IAEjC,6DAA6D;IAC7D,MAAM,oBAAoB,GAAG,MAAM,YAAY,EAAE,CAAC,IAAI,CACpD,iCAAiC,CAClC,CAAC;IAEF,OAAO,MAAM,gEAAgE,CAC3E,oBAAoB,EACpB,OAAO,CACR,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC9C,OAA8B;IAE9B,MAAM,EAAE,gCAAgC,EAAE,GAAG,OAAO,CAAC;IAErD,MAAM,uBAAuB,GAC3B,MAAM,gCAAgC,EAAE,CAAC,kCAAkC,CACzE,0BAA0B,CAAC,QAAQ,CACpC,CAAC;IAEJ,OAAO,CACL,uBAAuB,EAAE,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,IAAI,IAAI,CAC7E,CAAC;AACJ,CAAC","sourcesContent":["import type { InternalAccount } from '@metamask/keyring-internal-api';\n\nimport type { AccountSyncingOptions, UserStorageAccount } from './types';\nimport { mapInternalAccountsListToPrimarySRPHdKeyringInternalAccountsList } from './utils';\nimport { USER_STORAGE_FEATURE_NAMES } from '../../../shared/storage-schema';\n\n/**\n * Checks if account syncing can be performed based on a set of conditions\n *\n * @param options - parameters used for checking if account syncing can be performed\n * @returns Returns true if account syncing can be performed, false otherwise.\n */\nexport function canPerformAccountSyncing(\n options: AccountSyncingOptions,\n): boolean {\n const { getMessenger, getUserStorageControllerInstance } = options;\n\n const {\n isBackupAndSyncEnabled,\n isAccountSyncingEnabled,\n isAccountSyncingInProgress,\n } = getUserStorageControllerInstance().state;\n const isAuthEnabled = getMessenger().call(\n 'AuthenticationController:isSignedIn',\n );\n\n if (\n !isBackupAndSyncEnabled ||\n !isAccountSyncingEnabled ||\n !isAuthEnabled ||\n isAccountSyncingInProgress\n ) {\n return false;\n }\n\n return true;\n}\n\n/**\n * Get the list of internal accounts\n * This function returns only the internal accounts that are from the primary SRP\n * and are from the HD keyring\n *\n * @param options - parameters used for getting the list of internal accounts\n * @returns the list of internal accounts\n */\nexport async function getInternalAccountsList(\n options: AccountSyncingOptions,\n): Promise<InternalAccount[]> {\n const { getMessenger } = options;\n\n // eslint-disable-next-line @typescript-eslint/await-thenable\n const internalAccountsList = await getMessenger().call(\n 'AccountsController:listAccounts',\n );\n\n return await mapInternalAccountsListToPrimarySRPHdKeyringInternalAccountsList(\n internalAccountsList,\n options,\n );\n}\n\n/**\n * Get the list of user storage accounts\n *\n * @param options - parameters used for getting the list of user storage accounts\n * @returns the list of user storage accounts\n */\nexport async function getUserStorageAccountsList(\n options: AccountSyncingOptions,\n): Promise<UserStorageAccount[] | null> {\n const { getUserStorageControllerInstance } = options;\n\n const rawAccountsListResponse =\n await getUserStorageControllerInstance().performGetStorageAllFeatureEntries(\n USER_STORAGE_FEATURE_NAMES.accounts,\n );\n\n return (\n rawAccountsListResponse?.map((rawAccount) => JSON.parse(rawAccount)) ?? null\n );\n}\n"]}
1
+ {"version":3,"file":"sync-utils.mjs","sourceRoot":"","sources":["../../../../src/controllers/user-storage/account-syncing/sync-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,qCAAqC;AAI5D,OAAO,EAAE,0BAA0B,EAAE,2CAAuC;AAE5E;;;;;GAKG;AACH,MAAM,UAAU,wBAAwB,CACtC,OAA8B;IAE9B,MAAM,EAAE,YAAY,EAAE,gCAAgC,EAAE,GAAG,OAAO,CAAC;IAEnE,MAAM,EACJ,sBAAsB,EACtB,uBAAuB,EACvB,0BAA0B,GAC3B,GAAG,gCAAgC,EAAE,CAAC,KAAK,CAAC;IAC7C,MAAM,aAAa,GAAG,YAAY,EAAE,CAAC,IAAI,CACvC,qCAAqC,CACtC,CAAC;IAEF,IACE,CAAC,sBAAsB;QACvB,CAAC,uBAAuB;QACxB,CAAC,aAAa;QACd,0BAA0B,EAC1B;QACA,OAAO,KAAK,CAAC;KACd;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,OAA8B,EAC9B,eAAuB;IAEvB,MAAM,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC;IAEjC,MAAM,YAAY,EAAE,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;IAE/D,MAAM,oBAAoB,GAAG,YAAY,EAAE,CAAC,IAAI,CAC9C,iCAAiC,CAClC,CAAC;IAEF,OAAO,oBAAoB,CAAC,MAAM,CAChC,CAAC,OAAO,EAAE,EAAE,CACV,eAAe,KAAK,OAAO,CAAC,OAAO,CAAC,aAAa;QACjD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,KAAK,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC,CAC5D,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC9C,OAA8B,EAC9B,eAAwB;IAExB,MAAM,EAAE,gCAAgC,EAAE,GAAG,OAAO,CAAC;IAErD,MAAM,uBAAuB,GAC3B,MAAM,gCAAgC,EAAE,CAAC,kCAAkC,CACzE,0BAA0B,CAAC,QAAQ,EACnC,eAAe,CAChB,CAAC;IAEJ,OAAO,CACL,uBAAuB,EAAE,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,IAAI,IAAI,CAC7E,CAAC;AACJ,CAAC","sourcesContent":["import { KeyringTypes } from '@metamask/keyring-controller';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\n\nimport type { AccountSyncingOptions, UserStorageAccount } from './types';\nimport { USER_STORAGE_FEATURE_NAMES } from '../../../shared/storage-schema';\n\n/**\n * Checks if account syncing can be performed based on a set of conditions\n *\n * @param options - parameters used for checking if account syncing can be performed\n * @returns Returns true if account syncing can be performed, false otherwise.\n */\nexport function canPerformAccountSyncing(\n options: AccountSyncingOptions,\n): boolean {\n const { getMessenger, getUserStorageControllerInstance } = options;\n\n const {\n isBackupAndSyncEnabled,\n isAccountSyncingEnabled,\n isAccountSyncingInProgress,\n } = getUserStorageControllerInstance().state;\n const isAuthEnabled = getMessenger().call(\n 'AuthenticationController:isSignedIn',\n );\n\n if (\n !isBackupAndSyncEnabled ||\n !isAccountSyncingEnabled ||\n !isAuthEnabled ||\n isAccountSyncingInProgress\n ) {\n return false;\n }\n\n return true;\n}\n\n/**\n * Get the list of internal accounts\n * This function returns only the internal accounts that are from the primary SRP\n * and are from the HD keyring\n *\n * @param options - parameters used for getting the list of internal accounts\n * @param entropySourceId - The entropy source ID used to derive the key,\n * when multiple sources are available (Multi-SRP).\n * @returns the list of internal accounts\n */\nexport async function getInternalAccountsList(\n options: AccountSyncingOptions,\n entropySourceId: string,\n): Promise<InternalAccount[]> {\n const { getMessenger } = options;\n\n await getMessenger().call('AccountsController:updateAccounts');\n\n const internalAccountsList = getMessenger().call(\n 'AccountsController:listAccounts',\n );\n\n return internalAccountsList.filter(\n (account) =>\n entropySourceId === account.options.entropySource &&\n account.metadata.keyring.type === String(KeyringTypes.hd), // sync only EVM accounts until we support multichain accounts\n );\n}\n\n/**\n * Get the list of user storage accounts\n *\n * @param options - parameters used for getting the list of user storage accounts\n * @param entropySourceId - The entropy source ID used to derive the storage key,\n * when multiple sources are available (Multi-SRP).\n * @returns the list of user storage accounts\n */\nexport async function getUserStorageAccountsList(\n options: AccountSyncingOptions,\n entropySourceId?: string,\n): Promise<UserStorageAccount[] | null> {\n const { getUserStorageControllerInstance } = options;\n\n const rawAccountsListResponse =\n await getUserStorageControllerInstance().performGetStorageAllFeatureEntries(\n USER_STORAGE_FEATURE_NAMES.accounts,\n entropySourceId,\n );\n\n return (\n rawAccountsListResponse?.map((rawAccount) => JSON.parse(rawAccount)) ?? null\n );\n}\n"]}
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isInternalAccountFromPrimarySRPHdKeyring = exports.mapInternalAccountsListToPrimarySRPHdKeyringInternalAccountsList = exports.mapInternalAccountToUserStorageAccount = exports.isNameDefaultAccountName = void 0;
4
- const keyring_controller_1 = require("@metamask/keyring-controller");
3
+ exports.mapInternalAccountToUserStorageAccount = exports.isNameDefaultAccountName = void 0;
5
4
  const constants_1 = require("./constants.cjs");
6
5
  /**
7
6
  * Tells if the given name is a default account name.
@@ -34,44 +33,4 @@ const mapInternalAccountToUserStorageAccount = (internalAccount) => {
34
33
  };
35
34
  };
36
35
  exports.mapInternalAccountToUserStorageAccount = mapInternalAccountToUserStorageAccount;
37
- /**
38
- * Transforms a list of any internal accounts to a list of internal accounts that
39
- * have the correct keyring type and are from the primary SRP.
40
- *
41
- * @param internalAccountsList - The list of internal accounts
42
- * @param options - Parameters used for checking if the internal account is from the primary SRP
43
- * @returns Returns a list of internal accounts that have the correct keyring type and are from the primary SRP.
44
- */
45
- async function mapInternalAccountsListToPrimarySRPHdKeyringInternalAccountsList(internalAccountsList, options) {
46
- const { getMessenger } = options;
47
- const primarySRPHdKeyringAccountsAddresses = (await getMessenger().call('KeyringController:withKeyring', {
48
- type: keyring_controller_1.KeyringTypes.hd,
49
- index: 0,
50
- }, async ({ keyring }) => {
51
- return await keyring.getAccounts();
52
- }));
53
- return internalAccountsList.filter((account) => primarySRPHdKeyringAccountsAddresses?.includes(account.address));
54
- }
55
- exports.mapInternalAccountsListToPrimarySRPHdKeyringInternalAccountsList = mapInternalAccountsListToPrimarySRPHdKeyringInternalAccountsList;
56
- /**
57
- * Checks if the given internal account is from the primary SRP and is from the HD keyring.
58
- *
59
- * @param account - The internal account to check
60
- * @param options - Parameters used for checking if the internal account is from the primary SRP
61
- * @returns Returns true if the internal account is from the primary SRP, false otherwise.
62
- */
63
- async function isInternalAccountFromPrimarySRPHdKeyring(account, options) {
64
- if (account.metadata.keyring.type !== keyring_controller_1.KeyringTypes.hd) {
65
- return false;
66
- }
67
- const { getMessenger } = options;
68
- const primarySRPHdKeyringAccountsAddresses = (await getMessenger().call('KeyringController:withKeyring', {
69
- type: keyring_controller_1.KeyringTypes.hd,
70
- index: 0,
71
- }, async ({ keyring }) => {
72
- return await keyring.getAccounts();
73
- }));
74
- return primarySRPHdKeyringAccountsAddresses.includes(account.address);
75
- }
76
- exports.isInternalAccountFromPrimarySRPHdKeyring = isInternalAccountFromPrimarySRPHdKeyring;
77
36
  //# sourceMappingURL=utils.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.cjs","sourceRoot":"","sources":["../../../../src/controllers/user-storage/account-syncing/utils.ts"],"names":[],"mappings":";;;AAAA,qEAA4D;AAG5D,+CAIqB;AAGrB;;;;;;GAMG;AAEI,MAAM,wBAAwB,GAAG,CAAC,IAAY,EAAE,EAAE;IACvD,OAAO,2CAA+B,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE;QACrD,OAAO,IAAI,MAAM,CAAC,IAAI,MAAM,YAAY,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAJW,QAAA,wBAAwB,4BAInC;AAEF;;;;;GAKG;AACI,MAAM,sCAAsC,GAAG,CACpD,eAAgC,EACZ,EAAE;IACtB,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,GAAG,eAAe,CAAC;IAClD,MAAM,EAAE,IAAI,EAAE,iBAAiB,EAAE,GAAG,QAAQ,CAAC;IAE7C,OAAO;QACL,CAAC,oCAAwB,CAAC,EAAE,gCAAoB;QAChD,CAAC,EAAE,OAAO;QACV,CAAC,EAAE,EAAE;QACL,CAAC,EAAE,IAAI;QACP,GAAG,CAAC,IAAA,gCAAwB,EAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,iBAAiB,EAAE,CAAC;KACtE,CAAC;AACJ,CAAC,CAAC;AAbW,QAAA,sCAAsC,0CAajD;AAEF;;;;;;;GAOG;AACI,KAAK,UAAU,gEAAgE,CACpF,oBAAuC,EACvC,OAA8B;IAE9B,MAAM,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC;IAEjC,MAAM,oCAAoC,GAAG,CAAC,MAAM,YAAY,EAAE,CAAC,IAAI,CACrE,+BAA+B,EAC/B;QACE,IAAI,EAAE,iCAAY,CAAC,EAAE;QACrB,KAAK,EAAE,CAAC;KACT,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;QACpB,OAAO,MAAM,OAAO,CAAC,WAAW,EAAE,CAAC;IACrC,CAAC,CACF,CAAa,CAAC;IAEf,OAAO,oBAAoB,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAC7C,oCAAoC,EAAE,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,CAChE,CAAC;AACJ,CAAC;AApBD,4IAoBC;AAED;;;;;;GAMG;AACI,KAAK,UAAU,wCAAwC,CAC5D,OAAwB,EACxB,OAA8B;IAE9B,IAAI,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,KAAK,iCAAY,CAAC,EAAE,EAAE;QACrD,OAAO,KAAK,CAAC;KACd;IAED,MAAM,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC;IAEjC,MAAM,oCAAoC,GAAG,CAAC,MAAM,YAAY,EAAE,CAAC,IAAI,CACrE,+BAA+B,EAC/B;QACE,IAAI,EAAE,iCAAY,CAAC,EAAE;QACrB,KAAK,EAAE,CAAC;KACT,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;QACpB,OAAO,MAAM,OAAO,CAAC,WAAW,EAAE,CAAC;IACrC,CAAC,CACF,CAAa,CAAC;IAEf,OAAO,oCAAoC,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;AACxE,CAAC;AAtBD,4FAsBC","sourcesContent":["import { KeyringTypes } from '@metamask/keyring-controller';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\n\nimport {\n USER_STORAGE_VERSION_KEY,\n USER_STORAGE_VERSION,\n LOCALIZED_DEFAULT_ACCOUNT_NAMES,\n} from './constants';\nimport type { AccountSyncingOptions, UserStorageAccount } from './types';\n\n/**\n * Tells if the given name is a default account name.\n * Default account names are localized names that are automatically generated by the clients.\n *\n * @param name - the name to check\n * @returns true if the name is a default account name, false otherwise\n */\n\nexport const isNameDefaultAccountName = (name: string) => {\n return LOCALIZED_DEFAULT_ACCOUNT_NAMES.some((prefix) => {\n return new RegExp(`^${prefix} ([0-9]+)$`, 'u').test(name);\n });\n};\n\n/**\n * Map an internal account to a user storage account\n *\n * @param internalAccount - An internal account\n * @returns A user storage account\n */\nexport const mapInternalAccountToUserStorageAccount = (\n internalAccount: InternalAccount,\n): UserStorageAccount => {\n const { address, id, metadata } = internalAccount;\n const { name, nameLastUpdatedAt } = metadata;\n\n return {\n [USER_STORAGE_VERSION_KEY]: USER_STORAGE_VERSION,\n a: address,\n i: id,\n n: name,\n ...(isNameDefaultAccountName(name) ? {} : { nlu: nameLastUpdatedAt }),\n };\n};\n\n/**\n * Transforms a list of any internal accounts to a list of internal accounts that\n * have the correct keyring type and are from the primary SRP.\n *\n * @param internalAccountsList - The list of internal accounts\n * @param options - Parameters used for checking if the internal account is from the primary SRP\n * @returns Returns a list of internal accounts that have the correct keyring type and are from the primary SRP.\n */\nexport async function mapInternalAccountsListToPrimarySRPHdKeyringInternalAccountsList(\n internalAccountsList: InternalAccount[],\n options: AccountSyncingOptions,\n): Promise<InternalAccount[]> {\n const { getMessenger } = options;\n\n const primarySRPHdKeyringAccountsAddresses = (await getMessenger().call(\n 'KeyringController:withKeyring',\n {\n type: KeyringTypes.hd,\n index: 0,\n },\n async ({ keyring }) => {\n return await keyring.getAccounts();\n },\n )) as string[];\n\n return internalAccountsList.filter((account) =>\n primarySRPHdKeyringAccountsAddresses?.includes(account.address),\n );\n}\n\n/**\n * Checks if the given internal account is from the primary SRP and is from the HD keyring.\n *\n * @param account - The internal account to check\n * @param options - Parameters used for checking if the internal account is from the primary SRP\n * @returns Returns true if the internal account is from the primary SRP, false otherwise.\n */\nexport async function isInternalAccountFromPrimarySRPHdKeyring(\n account: InternalAccount,\n options: AccountSyncingOptions,\n): Promise<boolean> {\n if (account.metadata.keyring.type !== KeyringTypes.hd) {\n return false;\n }\n\n const { getMessenger } = options;\n\n const primarySRPHdKeyringAccountsAddresses = (await getMessenger().call(\n 'KeyringController:withKeyring',\n {\n type: KeyringTypes.hd,\n index: 0,\n },\n async ({ keyring }) => {\n return await keyring.getAccounts();\n },\n )) as string[];\n\n return primarySRPHdKeyringAccountsAddresses.includes(account.address);\n}\n"]}
1
+ {"version":3,"file":"utils.cjs","sourceRoot":"","sources":["../../../../src/controllers/user-storage/account-syncing/utils.ts"],"names":[],"mappings":";;;AAEA,+CAIqB;AAGrB;;;;;;GAMG;AAEI,MAAM,wBAAwB,GAAG,CAAC,IAAY,EAAE,EAAE;IACvD,OAAO,2CAA+B,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE;QACrD,OAAO,IAAI,MAAM,CAAC,IAAI,MAAM,YAAY,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAJW,QAAA,wBAAwB,4BAInC;AAEF;;;;;GAKG;AACI,MAAM,sCAAsC,GAAG,CACpD,eAAgC,EACZ,EAAE;IACtB,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,GAAG,eAAe,CAAC;IAClD,MAAM,EAAE,IAAI,EAAE,iBAAiB,EAAE,GAAG,QAAQ,CAAC;IAE7C,OAAO;QACL,CAAC,oCAAwB,CAAC,EAAE,gCAAoB;QAChD,CAAC,EAAE,OAAO;QACV,CAAC,EAAE,EAAE;QACL,CAAC,EAAE,IAAI;QACP,GAAG,CAAC,IAAA,gCAAwB,EAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,iBAAiB,EAAE,CAAC;KACtE,CAAC;AACJ,CAAC,CAAC;AAbW,QAAA,sCAAsC,0CAajD","sourcesContent":["import type { InternalAccount } from '@metamask/keyring-internal-api';\n\nimport {\n USER_STORAGE_VERSION_KEY,\n USER_STORAGE_VERSION,\n LOCALIZED_DEFAULT_ACCOUNT_NAMES,\n} from './constants';\nimport type { UserStorageAccount } from './types';\n\n/**\n * Tells if the given name is a default account name.\n * Default account names are localized names that are automatically generated by the clients.\n *\n * @param name - the name to check\n * @returns true if the name is a default account name, false otherwise\n */\n\nexport const isNameDefaultAccountName = (name: string) => {\n return LOCALIZED_DEFAULT_ACCOUNT_NAMES.some((prefix) => {\n return new RegExp(`^${prefix} ([0-9]+)$`, 'u').test(name);\n });\n};\n\n/**\n * Map an internal account to a user storage account\n *\n * @param internalAccount - An internal account\n * @returns A user storage account\n */\nexport const mapInternalAccountToUserStorageAccount = (\n internalAccount: InternalAccount,\n): UserStorageAccount => {\n const { address, id, metadata } = internalAccount;\n const { name, nameLastUpdatedAt } = metadata;\n\n return {\n [USER_STORAGE_VERSION_KEY]: USER_STORAGE_VERSION,\n a: address,\n i: id,\n n: name,\n ...(isNameDefaultAccountName(name) ? {} : { nlu: nameLastUpdatedAt }),\n };\n};\n"]}
@@ -1,5 +1,5 @@
1
1
  import type { InternalAccount } from "@metamask/keyring-internal-api";
2
- import type { AccountSyncingOptions, UserStorageAccount } from "./types.cjs";
2
+ import type { UserStorageAccount } from "./types.cjs";
3
3
  /**
4
4
  * Tells if the given name is a default account name.
5
5
  * Default account names are localized names that are automatically generated by the clients.
@@ -15,21 +15,4 @@ export declare const isNameDefaultAccountName: (name: string) => boolean;
15
15
  * @returns A user storage account
16
16
  */
17
17
  export declare const mapInternalAccountToUserStorageAccount: (internalAccount: InternalAccount) => UserStorageAccount;
18
- /**
19
- * Transforms a list of any internal accounts to a list of internal accounts that
20
- * have the correct keyring type and are from the primary SRP.
21
- *
22
- * @param internalAccountsList - The list of internal accounts
23
- * @param options - Parameters used for checking if the internal account is from the primary SRP
24
- * @returns Returns a list of internal accounts that have the correct keyring type and are from the primary SRP.
25
- */
26
- export declare function mapInternalAccountsListToPrimarySRPHdKeyringInternalAccountsList(internalAccountsList: InternalAccount[], options: AccountSyncingOptions): Promise<InternalAccount[]>;
27
- /**
28
- * Checks if the given internal account is from the primary SRP and is from the HD keyring.
29
- *
30
- * @param account - The internal account to check
31
- * @param options - Parameters used for checking if the internal account is from the primary SRP
32
- * @returns Returns true if the internal account is from the primary SRP, false otherwise.
33
- */
34
- export declare function isInternalAccountFromPrimarySRPHdKeyring(account: InternalAccount, options: AccountSyncingOptions): Promise<boolean>;
35
18
  //# sourceMappingURL=utils.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.cts","sourceRoot":"","sources":["../../../../src/controllers/user-storage/account-syncing/utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,uCAAuC;AAOtE,OAAO,KAAK,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,oBAAgB;AAEzE;;;;;;GAMG;AAEH,eAAO,MAAM,wBAAwB,SAAU,MAAM,YAIpD,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,sCAAsC,oBAChC,eAAe,KAC/B,kBAWF,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAsB,gEAAgE,CACpF,oBAAoB,EAAE,eAAe,EAAE,EACvC,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,eAAe,EAAE,CAAC,CAiB5B;AAED;;;;;;GAMG;AACH,wBAAsB,wCAAwC,CAC5D,OAAO,EAAE,eAAe,EACxB,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,OAAO,CAAC,CAmBlB"}
1
+ {"version":3,"file":"utils.d.cts","sourceRoot":"","sources":["../../../../src/controllers/user-storage/account-syncing/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,uCAAuC;AAOtE,OAAO,KAAK,EAAE,kBAAkB,EAAE,oBAAgB;AAElD;;;;;;GAMG;AAEH,eAAO,MAAM,wBAAwB,SAAU,MAAM,YAIpD,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,sCAAsC,oBAChC,eAAe,KAC/B,kBAWF,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import type { InternalAccount } from "@metamask/keyring-internal-api";
2
- import type { AccountSyncingOptions, UserStorageAccount } from "./types.mjs";
2
+ import type { UserStorageAccount } from "./types.mjs";
3
3
  /**
4
4
  * Tells if the given name is a default account name.
5
5
  * Default account names are localized names that are automatically generated by the clients.
@@ -15,21 +15,4 @@ export declare const isNameDefaultAccountName: (name: string) => boolean;
15
15
  * @returns A user storage account
16
16
  */
17
17
  export declare const mapInternalAccountToUserStorageAccount: (internalAccount: InternalAccount) => UserStorageAccount;
18
- /**
19
- * Transforms a list of any internal accounts to a list of internal accounts that
20
- * have the correct keyring type and are from the primary SRP.
21
- *
22
- * @param internalAccountsList - The list of internal accounts
23
- * @param options - Parameters used for checking if the internal account is from the primary SRP
24
- * @returns Returns a list of internal accounts that have the correct keyring type and are from the primary SRP.
25
- */
26
- export declare function mapInternalAccountsListToPrimarySRPHdKeyringInternalAccountsList(internalAccountsList: InternalAccount[], options: AccountSyncingOptions): Promise<InternalAccount[]>;
27
- /**
28
- * Checks if the given internal account is from the primary SRP and is from the HD keyring.
29
- *
30
- * @param account - The internal account to check
31
- * @param options - Parameters used for checking if the internal account is from the primary SRP
32
- * @returns Returns true if the internal account is from the primary SRP, false otherwise.
33
- */
34
- export declare function isInternalAccountFromPrimarySRPHdKeyring(account: InternalAccount, options: AccountSyncingOptions): Promise<boolean>;
35
18
  //# sourceMappingURL=utils.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.mts","sourceRoot":"","sources":["../../../../src/controllers/user-storage/account-syncing/utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,uCAAuC;AAOtE,OAAO,KAAK,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,oBAAgB;AAEzE;;;;;;GAMG;AAEH,eAAO,MAAM,wBAAwB,SAAU,MAAM,YAIpD,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,sCAAsC,oBAChC,eAAe,KAC/B,kBAWF,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAsB,gEAAgE,CACpF,oBAAoB,EAAE,eAAe,EAAE,EACvC,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,eAAe,EAAE,CAAC,CAiB5B;AAED;;;;;;GAMG;AACH,wBAAsB,wCAAwC,CAC5D,OAAO,EAAE,eAAe,EACxB,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,OAAO,CAAC,CAmBlB"}
1
+ {"version":3,"file":"utils.d.mts","sourceRoot":"","sources":["../../../../src/controllers/user-storage/account-syncing/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,uCAAuC;AAOtE,OAAO,KAAK,EAAE,kBAAkB,EAAE,oBAAgB;AAElD;;;;;;GAMG;AAEH,eAAO,MAAM,wBAAwB,SAAU,MAAM,YAIpD,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,sCAAsC,oBAChC,eAAe,KAC/B,kBAWF,CAAC"}