@metamask-previews/multichain-account-service 4.1.0-preview-a9886279 → 5.0.0-preview-6a568504
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +36 -1
- package/dist/MultichainAccountGroup.cjs +84 -45
- package/dist/MultichainAccountGroup.cjs.map +1 -1
- package/dist/MultichainAccountGroup.d.cts +17 -4
- package/dist/MultichainAccountGroup.d.cts.map +1 -1
- package/dist/MultichainAccountGroup.d.mts +17 -4
- package/dist/MultichainAccountGroup.d.mts.map +1 -1
- package/dist/MultichainAccountGroup.mjs +84 -45
- package/dist/MultichainAccountGroup.mjs.map +1 -1
- package/dist/MultichainAccountService.cjs +150 -112
- package/dist/MultichainAccountService.cjs.map +1 -1
- package/dist/MultichainAccountService.d.cts +49 -20
- package/dist/MultichainAccountService.d.cts.map +1 -1
- package/dist/MultichainAccountService.d.mts +49 -20
- package/dist/MultichainAccountService.d.mts.map +1 -1
- package/dist/MultichainAccountService.mjs +151 -113
- package/dist/MultichainAccountService.mjs.map +1 -1
- package/dist/MultichainAccountWallet.cjs +108 -123
- package/dist/MultichainAccountWallet.cjs.map +1 -1
- package/dist/MultichainAccountWallet.d.cts +5 -4
- package/dist/MultichainAccountWallet.d.cts.map +1 -1
- package/dist/MultichainAccountWallet.d.mts +5 -4
- package/dist/MultichainAccountWallet.d.mts.map +1 -1
- package/dist/MultichainAccountWallet.mjs +108 -123
- package/dist/MultichainAccountWallet.mjs.map +1 -1
- package/dist/providers/AccountProviderWrapper.cjs +18 -0
- package/dist/providers/AccountProviderWrapper.cjs.map +1 -1
- package/dist/providers/AccountProviderWrapper.d.cts +12 -0
- package/dist/providers/AccountProviderWrapper.d.cts.map +1 -1
- package/dist/providers/AccountProviderWrapper.d.mts +12 -0
- package/dist/providers/AccountProviderWrapper.d.mts.map +1 -1
- package/dist/providers/AccountProviderWrapper.mjs +18 -0
- package/dist/providers/AccountProviderWrapper.mjs.map +1 -1
- package/dist/providers/BaseBip44AccountProvider.cjs +45 -20
- package/dist/providers/BaseBip44AccountProvider.cjs.map +1 -1
- package/dist/providers/BaseBip44AccountProvider.d.cts +58 -6
- package/dist/providers/BaseBip44AccountProvider.d.cts.map +1 -1
- package/dist/providers/BaseBip44AccountProvider.d.mts +58 -6
- package/dist/providers/BaseBip44AccountProvider.d.mts.map +1 -1
- package/dist/providers/BaseBip44AccountProvider.mjs +45 -20
- package/dist/providers/BaseBip44AccountProvider.mjs.map +1 -1
- package/dist/providers/BtcAccountProvider.cjs +47 -32
- package/dist/providers/BtcAccountProvider.cjs.map +1 -1
- package/dist/providers/BtcAccountProvider.d.cts +2 -1
- package/dist/providers/BtcAccountProvider.d.cts.map +1 -1
- package/dist/providers/BtcAccountProvider.d.mts +2 -1
- package/dist/providers/BtcAccountProvider.d.mts.map +1 -1
- package/dist/providers/BtcAccountProvider.mjs +47 -32
- package/dist/providers/BtcAccountProvider.mjs.map +1 -1
- package/dist/providers/EvmAccountProvider.cjs +39 -5
- package/dist/providers/EvmAccountProvider.cjs.map +1 -1
- package/dist/providers/EvmAccountProvider.d.cts +8 -0
- package/dist/providers/EvmAccountProvider.d.cts.map +1 -1
- package/dist/providers/EvmAccountProvider.d.mts +8 -0
- package/dist/providers/EvmAccountProvider.d.mts.map +1 -1
- package/dist/providers/EvmAccountProvider.mjs +39 -5
- package/dist/providers/EvmAccountProvider.mjs.map +1 -1
- package/dist/providers/SnapAccountProvider.cjs +81 -54
- package/dist/providers/SnapAccountProvider.cjs.map +1 -1
- package/dist/providers/SnapAccountProvider.d.cts +16 -4
- package/dist/providers/SnapAccountProvider.d.cts.map +1 -1
- package/dist/providers/SnapAccountProvider.d.mts +16 -4
- package/dist/providers/SnapAccountProvider.d.mts.map +1 -1
- package/dist/providers/SnapAccountProvider.mjs +81 -54
- package/dist/providers/SnapAccountProvider.mjs.map +1 -1
- package/dist/providers/SolAccountProvider.cjs +40 -31
- package/dist/providers/SolAccountProvider.cjs.map +1 -1
- package/dist/providers/SolAccountProvider.d.cts.map +1 -1
- package/dist/providers/SolAccountProvider.d.mts.map +1 -1
- package/dist/providers/SolAccountProvider.mjs +40 -31
- package/dist/providers/SolAccountProvider.mjs.map +1 -1
- package/dist/providers/TrxAccountProvider.cjs +48 -29
- package/dist/providers/TrxAccountProvider.cjs.map +1 -1
- package/dist/providers/TrxAccountProvider.d.cts +1 -0
- package/dist/providers/TrxAccountProvider.d.cts.map +1 -1
- package/dist/providers/TrxAccountProvider.d.mts +1 -0
- package/dist/providers/TrxAccountProvider.d.mts.map +1 -1
- package/dist/providers/TrxAccountProvider.mjs +48 -29
- package/dist/providers/TrxAccountProvider.mjs.map +1 -1
- package/dist/snaps/SnapPlatformWatcher.cjs +60 -0
- package/dist/snaps/SnapPlatformWatcher.cjs.map +1 -0
- package/dist/snaps/SnapPlatformWatcher.d.cts +8 -0
- package/dist/snaps/SnapPlatformWatcher.d.cts.map +1 -0
- package/dist/snaps/SnapPlatformWatcher.d.mts +8 -0
- package/dist/snaps/SnapPlatformWatcher.d.mts.map +1 -0
- package/dist/snaps/SnapPlatformWatcher.mjs +57 -0
- package/dist/snaps/SnapPlatformWatcher.mjs.map +1 -0
- package/dist/tests/messenger.cjs +12 -1
- package/dist/tests/messenger.cjs.map +1 -1
- package/dist/tests/messenger.d.cts +9 -4
- package/dist/tests/messenger.d.cts.map +1 -1
- package/dist/tests/messenger.d.mts +9 -4
- package/dist/tests/messenger.d.mts.map +1 -1
- package/dist/tests/messenger.mjs +12 -1
- package/dist/tests/messenger.mjs.map +1 -1
- package/dist/tests/providers.cjs +62 -7
- package/dist/tests/providers.cjs.map +1 -1
- package/dist/tests/providers.d.cts +17 -3
- package/dist/tests/providers.d.cts.map +1 -1
- package/dist/tests/providers.d.mts +17 -3
- package/dist/tests/providers.d.mts.map +1 -1
- package/dist/tests/providers.mjs +60 -6
- package/dist/tests/providers.mjs.map +1 -1
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +14 -6
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +14 -6
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs.map +1 -1
- package/dist/utils.cjs +1 -11
- package/dist/utils.cjs.map +1 -1
- package/dist/utils.d.cts +0 -1
- package/dist/utils.d.cts.map +1 -1
- package/dist/utils.d.mts +0 -1
- package/dist/utils.d.mts.map +1 -1
- package/dist/utils.mjs +0 -9
- package/dist/utils.mjs.map +1 -1
- package/package.json +3 -2
|
@@ -9,16 +9,18 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
9
9
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
10
10
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
11
|
};
|
|
12
|
-
var _MultichainAccountGroup_id, _MultichainAccountGroup_wallet, _MultichainAccountGroup_groupIndex, _MultichainAccountGroup_providers, _MultichainAccountGroup_providerToAccounts, _MultichainAccountGroup_accountToProvider, _MultichainAccountGroup_messenger, _MultichainAccountGroup_log, _MultichainAccountGroup_initialized;
|
|
12
|
+
var _MultichainAccountGroup_instances, _MultichainAccountGroup_id, _MultichainAccountGroup_wallet, _MultichainAccountGroup_groupIndex, _MultichainAccountGroup_providers, _MultichainAccountGroup_providerToAccounts, _MultichainAccountGroup_accountToProvider, _MultichainAccountGroup_messenger, _MultichainAccountGroup_log, _MultichainAccountGroup_initialized, _MultichainAccountGroup_clearAccountToProviderState, _MultichainAccountGroup_setState;
|
|
13
13
|
import { AccountGroupType, select, selectOne } from "@metamask/account-api";
|
|
14
14
|
import { toMultichainAccountGroupId } from "@metamask/account-api";
|
|
15
15
|
import { projectLogger as log, createModuleLogger, WARNING_PREFIX } from "./logger.mjs";
|
|
16
|
+
import { isAccountProviderWrapper } from "./providers/index.mjs";
|
|
16
17
|
import { createSentryError } from "./utils.mjs";
|
|
17
18
|
/**
|
|
18
19
|
* A multichain account group that holds multiple accounts.
|
|
19
20
|
*/
|
|
20
21
|
export class MultichainAccountGroup {
|
|
21
22
|
constructor({ groupIndex, wallet, providers, messenger, }) {
|
|
23
|
+
_MultichainAccountGroup_instances.add(this);
|
|
22
24
|
_MultichainAccountGroup_id.set(this, void 0);
|
|
23
25
|
_MultichainAccountGroup_wallet.set(this, void 0);
|
|
24
26
|
_MultichainAccountGroup_groupIndex.set(this, void 0);
|
|
@@ -27,7 +29,6 @@ export class MultichainAccountGroup {
|
|
|
27
29
|
_MultichainAccountGroup_accountToProvider.set(this, void 0);
|
|
28
30
|
_MultichainAccountGroup_messenger.set(this, void 0);
|
|
29
31
|
_MultichainAccountGroup_log.set(this, void 0);
|
|
30
|
-
// eslint-disable-next-line @typescript-eslint/prefer-readonly
|
|
31
32
|
_MultichainAccountGroup_initialized.set(this, false);
|
|
32
33
|
__classPrivateFieldSet(this, _MultichainAccountGroup_id, toMultichainAccountGroupId(wallet.id, groupIndex), "f");
|
|
33
34
|
__classPrivateFieldSet(this, _MultichainAccountGroup_groupIndex, groupIndex, "f");
|
|
@@ -37,41 +38,26 @@ export class MultichainAccountGroup {
|
|
|
37
38
|
__classPrivateFieldSet(this, _MultichainAccountGroup_providerToAccounts, new Map(), "f");
|
|
38
39
|
__classPrivateFieldSet(this, _MultichainAccountGroup_accountToProvider, new Map(), "f");
|
|
39
40
|
__classPrivateFieldSet(this, _MultichainAccountGroup_log, createModuleLogger(log, `[${__classPrivateFieldGet(this, _MultichainAccountGroup_id, "f")}]`), "f");
|
|
40
|
-
this.sync();
|
|
41
|
-
__classPrivateFieldSet(this, _MultichainAccountGroup_initialized, true, "f");
|
|
42
41
|
}
|
|
43
42
|
/**
|
|
44
|
-
*
|
|
43
|
+
* Initialize the multichain account group and construct the internal representation of accounts.
|
|
45
44
|
*
|
|
46
|
-
*
|
|
47
|
-
* account doesn't know about.
|
|
45
|
+
* @param groupState - The group state.
|
|
48
46
|
*/
|
|
49
|
-
|
|
50
|
-
__classPrivateFieldGet(this, _MultichainAccountGroup_log, "f").call(this, '
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
}
|
|
64
|
-
__classPrivateFieldGet(this, _MultichainAccountGroup_providerToAccounts, "f").set(provider, accounts);
|
|
65
|
-
// Reverse-mapping for fast indexing.
|
|
66
|
-
for (const id of accounts) {
|
|
67
|
-
__classPrivateFieldGet(this, _MultichainAccountGroup_accountToProvider, "f").set(id, provider);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
// Emit update event when group is synced (only if initialized)
|
|
71
|
-
if (__classPrivateFieldGet(this, _MultichainAccountGroup_initialized, "f")) {
|
|
72
|
-
__classPrivateFieldGet(this, _MultichainAccountGroup_messenger, "f").publish('MultichainAccountService:multichainAccountGroupUpdated', this);
|
|
73
|
-
}
|
|
74
|
-
__classPrivateFieldGet(this, _MultichainAccountGroup_log, "f").call(this, 'Synchronized');
|
|
47
|
+
init(groupState) {
|
|
48
|
+
__classPrivateFieldGet(this, _MultichainAccountGroup_log, "f").call(this, 'Initializing group state...');
|
|
49
|
+
__classPrivateFieldGet(this, _MultichainAccountGroup_instances, "m", _MultichainAccountGroup_setState).call(this, groupState);
|
|
50
|
+
__classPrivateFieldGet(this, _MultichainAccountGroup_log, "f").call(this, 'Finished initializing group state...');
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Update the group state.
|
|
54
|
+
*
|
|
55
|
+
* @param groupState - The group state.
|
|
56
|
+
*/
|
|
57
|
+
update(groupState) {
|
|
58
|
+
__classPrivateFieldGet(this, _MultichainAccountGroup_log, "f").call(this, 'Updating group state...');
|
|
59
|
+
__classPrivateFieldGet(this, _MultichainAccountGroup_instances, "m", _MultichainAccountGroup_setState).call(this, groupState);
|
|
60
|
+
__classPrivateFieldGet(this, _MultichainAccountGroup_log, "f").call(this, 'Finished updating group state...');
|
|
75
61
|
}
|
|
76
62
|
/**
|
|
77
63
|
* Gets the multichain account group ID.
|
|
@@ -134,6 +120,14 @@ export class MultichainAccountGroup {
|
|
|
134
120
|
}
|
|
135
121
|
return allAccounts;
|
|
136
122
|
}
|
|
123
|
+
/**
|
|
124
|
+
* Gets the account IDs for this multichain account.
|
|
125
|
+
*
|
|
126
|
+
* @returns The account IDs.
|
|
127
|
+
*/
|
|
128
|
+
getAccountIds() {
|
|
129
|
+
return [...__classPrivateFieldGet(this, _MultichainAccountGroup_accountToProvider, "f").keys()];
|
|
130
|
+
}
|
|
137
131
|
/**
|
|
138
132
|
* Gets the account for a given account ID.
|
|
139
133
|
*
|
|
@@ -175,19 +169,26 @@ export class MultichainAccountGroup {
|
|
|
175
169
|
*/
|
|
176
170
|
async alignAccounts() {
|
|
177
171
|
__classPrivateFieldGet(this, _MultichainAccountGroup_log, "f").call(this, 'Aligning accounts...');
|
|
172
|
+
__classPrivateFieldGet(this, _MultichainAccountGroup_providerToAccounts, "f").clear();
|
|
173
|
+
__classPrivateFieldGet(this, _MultichainAccountGroup_accountToProvider, "f").clear();
|
|
178
174
|
const results = await Promise.allSettled(__classPrivateFieldGet(this, _MultichainAccountGroup_providers, "f").map(async (provider) => {
|
|
179
175
|
try {
|
|
180
|
-
const accounts =
|
|
181
|
-
|
|
176
|
+
const accounts = await provider.alignAccounts({
|
|
177
|
+
entropySource: this.wallet.entropySource,
|
|
178
|
+
groupIndex: this.groupIndex,
|
|
179
|
+
});
|
|
180
|
+
const isDisabled = isAccountProviderWrapper(provider) && provider.isDisabled();
|
|
181
|
+
if (isDisabled) {
|
|
182
|
+
__classPrivateFieldGet(this, _MultichainAccountGroup_log, "f").call(this, `Account provider "${provider.getName()}" is disabled, skipping alignment...`);
|
|
183
|
+
}
|
|
184
|
+
else if (accounts.length > 0) {
|
|
182
185
|
__classPrivateFieldGet(this, _MultichainAccountGroup_log, "f").call(this, `Found missing accounts for account provider "${provider.getName()}", creating them now...`);
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
}
|
|
187
|
-
__classPrivateFieldGet(this, _MultichainAccountGroup_log, "f").call(this, `Created ${created.length} accounts`);
|
|
188
|
-
return created;
|
|
186
|
+
__classPrivateFieldGet(this, _MultichainAccountGroup_providerToAccounts, "f").set(provider, accounts);
|
|
187
|
+
for (const accountId of accounts) {
|
|
188
|
+
__classPrivateFieldGet(this, _MultichainAccountGroup_accountToProvider, "f").set(accountId, provider);
|
|
189
|
+
}
|
|
189
190
|
}
|
|
190
|
-
return
|
|
191
|
+
return accounts;
|
|
191
192
|
}
|
|
192
193
|
catch (error) {
|
|
193
194
|
// istanbul ignore next
|
|
@@ -200,13 +201,51 @@ export class MultichainAccountGroup {
|
|
|
200
201
|
throw error;
|
|
201
202
|
}
|
|
202
203
|
}));
|
|
203
|
-
|
|
204
|
-
|
|
204
|
+
let failureMessage = '';
|
|
205
|
+
let failureCount = 0;
|
|
206
|
+
const groupState = results.reduce((state, result, idx) => {
|
|
207
|
+
if (result.status === 'fulfilled' && result.value.length) {
|
|
208
|
+
state[__classPrivateFieldGet(this, _MultichainAccountGroup_providers, "f")[idx].getName()] = result.value;
|
|
209
|
+
}
|
|
210
|
+
else if (result.status === 'rejected') {
|
|
211
|
+
failureCount += 1;
|
|
212
|
+
failureMessage += `\n- ${__classPrivateFieldGet(this, _MultichainAccountGroup_providers, "f")[idx].getName()}: ${result.reason.message}`;
|
|
213
|
+
}
|
|
214
|
+
return state;
|
|
215
|
+
}, {});
|
|
216
|
+
// Update group state
|
|
217
|
+
this.update(groupState);
|
|
218
|
+
if (failureCount > 0) {
|
|
219
|
+
const hasMultipleFailures = failureCount > 1;
|
|
220
|
+
const message = `Failed to fully align multichain account group for entropy ID: ${this.wallet.entropySource} and group index: ${this.groupIndex}, some accounts might be missing. ${hasMultipleFailures ? 'Providers' : 'Provider'} threw the following ${hasMultipleFailures ? 'errors' : 'error'}:${failureMessage}`;
|
|
205
221
|
__classPrivateFieldGet(this, _MultichainAccountGroup_log, "f").call(this, `${WARNING_PREFIX} ${message}`);
|
|
206
222
|
console.warn(message);
|
|
207
223
|
}
|
|
208
224
|
__classPrivateFieldGet(this, _MultichainAccountGroup_log, "f").call(this, 'Aligned');
|
|
209
225
|
}
|
|
210
226
|
}
|
|
211
|
-
_MultichainAccountGroup_id = new WeakMap(), _MultichainAccountGroup_wallet = new WeakMap(), _MultichainAccountGroup_groupIndex = new WeakMap(), _MultichainAccountGroup_providers = new WeakMap(), _MultichainAccountGroup_providerToAccounts = new WeakMap(), _MultichainAccountGroup_accountToProvider = new WeakMap(), _MultichainAccountGroup_messenger = new WeakMap(), _MultichainAccountGroup_log = new WeakMap(), _MultichainAccountGroup_initialized = new WeakMap()
|
|
227
|
+
_MultichainAccountGroup_id = new WeakMap(), _MultichainAccountGroup_wallet = new WeakMap(), _MultichainAccountGroup_groupIndex = new WeakMap(), _MultichainAccountGroup_providers = new WeakMap(), _MultichainAccountGroup_providerToAccounts = new WeakMap(), _MultichainAccountGroup_accountToProvider = new WeakMap(), _MultichainAccountGroup_messenger = new WeakMap(), _MultichainAccountGroup_log = new WeakMap(), _MultichainAccountGroup_initialized = new WeakMap(), _MultichainAccountGroup_instances = new WeakSet(), _MultichainAccountGroup_clearAccountToProviderState = function _MultichainAccountGroup_clearAccountToProviderState(provider) {
|
|
228
|
+
__classPrivateFieldGet(this, _MultichainAccountGroup_accountToProvider, "f").forEach((accountProvider, id) => {
|
|
229
|
+
if (accountProvider === provider) {
|
|
230
|
+
__classPrivateFieldGet(this, _MultichainAccountGroup_accountToProvider, "f").delete(id);
|
|
231
|
+
}
|
|
232
|
+
});
|
|
233
|
+
}, _MultichainAccountGroup_setState = function _MultichainAccountGroup_setState(groupState) {
|
|
234
|
+
for (const provider of __classPrivateFieldGet(this, _MultichainAccountGroup_providers, "f")) {
|
|
235
|
+
const accountIds = groupState[provider.getName()];
|
|
236
|
+
if (accountIds) {
|
|
237
|
+
__classPrivateFieldGet(this, _MultichainAccountGroup_instances, "m", _MultichainAccountGroup_clearAccountToProviderState).call(this, provider);
|
|
238
|
+
__classPrivateFieldGet(this, _MultichainAccountGroup_providerToAccounts, "f").set(provider, accountIds);
|
|
239
|
+
for (const accountId of accountIds) {
|
|
240
|
+
__classPrivateFieldGet(this, _MultichainAccountGroup_accountToProvider, "f").set(accountId, provider);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
if (__classPrivateFieldGet(this, _MultichainAccountGroup_initialized, "f")) {
|
|
245
|
+
__classPrivateFieldGet(this, _MultichainAccountGroup_messenger, "f").publish('MultichainAccountService:multichainAccountGroupUpdated', this);
|
|
246
|
+
}
|
|
247
|
+
else {
|
|
248
|
+
__classPrivateFieldSet(this, _MultichainAccountGroup_initialized, true, "f");
|
|
249
|
+
}
|
|
250
|
+
};
|
|
212
251
|
//# sourceMappingURL=MultichainAccountGroup.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MultichainAccountGroup.mjs","sourceRoot":"","sources":["../src/MultichainAccountGroup.ts"],"names":[],"mappings":"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","sourcesContent":["import { AccountGroupType, select, selectOne } from '@metamask/account-api';\nimport { toMultichainAccountGroupId } from '@metamask/account-api';\nimport type {\n MultichainAccountGroupId,\n MultichainAccountGroup as MultichainAccountGroupDefinition,\n} from '@metamask/account-api';\nimport type { Bip44Account } from '@metamask/account-api';\nimport type { AccountSelector } from '@metamask/account-api';\nimport type { KeyringAccount } from '@metamask/keyring-api';\n\nimport type { Logger } from './logger';\nimport {\n projectLogger as log,\n createModuleLogger,\n WARNING_PREFIX,\n} from './logger';\nimport type { MultichainAccountWallet } from './MultichainAccountWallet';\nimport type { Bip44AccountProvider } from './providers';\nimport type { MultichainAccountServiceMessenger } from './types';\nimport { createSentryError } from './utils';\n\n/**\n * A multichain account group that holds multiple accounts.\n */\nexport class MultichainAccountGroup<\n Account extends Bip44Account<KeyringAccount>,\n> implements MultichainAccountGroupDefinition<Account>\n{\n readonly #id: MultichainAccountGroupId;\n\n readonly #wallet: MultichainAccountWallet<Account>;\n\n readonly #groupIndex: number;\n\n readonly #providers: Bip44AccountProvider<Account>[];\n\n readonly #providerToAccounts: Map<\n Bip44AccountProvider<Account>,\n Account['id'][]\n >;\n\n readonly #accountToProvider: Map<\n Account['id'],\n Bip44AccountProvider<Account>\n >;\n\n readonly #messenger: MultichainAccountServiceMessenger;\n\n readonly #log: Logger;\n\n // eslint-disable-next-line @typescript-eslint/prefer-readonly\n #initialized = false;\n\n constructor({\n groupIndex,\n wallet,\n providers,\n messenger,\n }: {\n groupIndex: number;\n wallet: MultichainAccountWallet<Account>;\n providers: Bip44AccountProvider<Account>[];\n messenger: MultichainAccountServiceMessenger;\n }) {\n this.#id = toMultichainAccountGroupId(wallet.id, groupIndex);\n this.#groupIndex = groupIndex;\n this.#wallet = wallet;\n this.#providers = providers;\n this.#messenger = messenger;\n this.#providerToAccounts = new Map();\n this.#accountToProvider = new Map();\n\n this.#log = createModuleLogger(log, `[${this.#id}]`);\n\n this.sync();\n this.#initialized = true;\n }\n\n /**\n * Force multichain account synchronization.\n *\n * This can be used if account providers got new accounts that the multichain\n * account doesn't know about.\n */\n sync(): void {\n this.#log('Synchronizing with account providers...');\n // Clear reverse mapping and re-construct it entirely based on the refreshed\n // list of accounts from each providers.\n this.#accountToProvider.clear();\n\n for (const provider of this.#providers) {\n // Filter account only for that index.\n const accounts = [];\n for (const account of provider.getAccounts()) {\n if (\n account.options.entropy.id === this.wallet.entropySource &&\n account.options.entropy.groupIndex === this.groupIndex\n ) {\n // We only use IDs to always fetch the latest version of accounts.\n accounts.push(account.id);\n }\n }\n this.#providerToAccounts.set(provider, accounts);\n\n // Reverse-mapping for fast indexing.\n for (const id of accounts) {\n this.#accountToProvider.set(id, provider);\n }\n }\n\n // Emit update event when group is synced (only if initialized)\n if (this.#initialized) {\n this.#messenger.publish(\n 'MultichainAccountService:multichainAccountGroupUpdated',\n this,\n );\n }\n\n this.#log('Synchronized');\n }\n\n /**\n * Gets the multichain account group ID.\n *\n * @returns The multichain account group ID.\n */\n get id(): MultichainAccountGroupId {\n return this.#id;\n }\n\n /**\n * Gets the multichain account group type.\n *\n * @returns The multichain account type.\n */\n get type(): AccountGroupType.MultichainAccount {\n return AccountGroupType.MultichainAccount;\n }\n\n /**\n * Gets the multichain account's wallet reference (parent).\n *\n * @returns The multichain account's wallet.\n */\n get wallet(): MultichainAccountWallet<Account> {\n return this.#wallet;\n }\n\n /**\n * Gets the multichain account group index.\n *\n * @returns The multichain account group index.\n */\n get groupIndex(): number {\n return this.#groupIndex;\n }\n\n /**\n * Checks if there's any underlying accounts for this multichain accounts.\n *\n * @returns True if there's any underlying accounts, false otherwise.\n */\n hasAccounts(): boolean {\n // If there's anything in the reverse-map, it means we have some accounts.\n return this.#accountToProvider.size > 0;\n }\n\n /**\n * Gets the accounts for this multichain account.\n *\n * @returns The accounts.\n */\n getAccounts(): Account[] {\n const allAccounts: Account[] = [];\n\n for (const [provider, accounts] of this.#providerToAccounts.entries()) {\n for (const id of accounts) {\n const account = provider.getAccount(id);\n\n if (account) {\n // If for some reason we cannot get this account from the provider, it\n // might means it has been deleted or something, so we just filter it\n // out.\n allAccounts.push(account);\n }\n }\n }\n\n return allAccounts;\n }\n\n /**\n * Gets the account for a given account ID.\n *\n * @param id - Account ID.\n * @returns The account or undefined if not found.\n */\n getAccount(id: Account['id']): Account | undefined {\n const provider = this.#accountToProvider.get(id);\n\n // If there's nothing in the map, it means we tried to get an account\n // that does not belong to this multichain account.\n if (!provider) {\n return undefined;\n }\n return provider.getAccount(id);\n }\n\n /**\n * Query an account matching the selector.\n *\n * @param selector - Query selector.\n * @returns The account matching the selector or undefined if not matching.\n * @throws If multiple accounts match the selector.\n */\n get(selector: AccountSelector<Account>): Account | undefined {\n return selectOne(this.getAccounts(), selector);\n }\n\n /**\n * Query accounts matching the selector.\n *\n * @param selector - Query selector.\n * @returns The accounts matching the selector.\n */\n select(selector: AccountSelector<Account>): Account[] {\n return select(this.getAccounts(), selector);\n }\n\n /**\n * Align the multichain account group.\n *\n * This will create accounts for providers that don't have any accounts yet.\n */\n async alignAccounts(): Promise<void> {\n this.#log('Aligning accounts...');\n\n const results = await Promise.allSettled(\n this.#providers.map(async (provider) => {\n try {\n const accounts = this.#providerToAccounts.get(provider);\n if (!accounts || accounts.length === 0) {\n this.#log(\n `Found missing accounts for account provider \"${provider.getName()}\", creating them now...`,\n );\n const created = await provider.createAccounts({\n entropySource: this.wallet.entropySource,\n groupIndex: this.groupIndex,\n });\n this.#log(`Created ${created.length} accounts`);\n\n return created;\n }\n return Promise.resolve();\n } catch (error) {\n // istanbul ignore next\n this.#log(\n `${WARNING_PREFIX} ${error instanceof Error ? error.message : String(error)}`,\n );\n const sentryError = createSentryError(\n `Unable to align accounts with provider \"${provider.getName()}\"`,\n error as Error,\n {\n groupIndex: this.groupIndex,\n provider: provider.getName(),\n },\n );\n this.#messenger.captureException?.(sentryError);\n throw error;\n }\n }),\n );\n\n if (results.some((result) => result.status === 'rejected')) {\n const message = `Failed to fully align multichain account group for entropy ID: ${this.wallet.entropySource} and group index: ${this.groupIndex}, some accounts might be missing`;\n\n this.#log(`${WARNING_PREFIX} ${message}`);\n console.warn(message);\n }\n\n this.#log('Aligned');\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"MultichainAccountGroup.mjs","sourceRoot":"","sources":["../src/MultichainAccountGroup.ts"],"names":[],"mappings":"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","sourcesContent":["import { AccountGroupType, select, selectOne } from '@metamask/account-api';\nimport { toMultichainAccountGroupId } from '@metamask/account-api';\nimport type {\n MultichainAccountGroupId,\n MultichainAccountGroup as MultichainAccountGroupDefinition,\n} from '@metamask/account-api';\nimport type { Bip44Account } from '@metamask/account-api';\nimport type { AccountSelector } from '@metamask/account-api';\nimport type { KeyringAccount } from '@metamask/keyring-api';\n\nimport type { Logger } from './logger';\nimport {\n projectLogger as log,\n createModuleLogger,\n WARNING_PREFIX,\n} from './logger';\nimport type { ServiceState, StateKeys } from './MultichainAccountService';\nimport type { MultichainAccountWallet } from './MultichainAccountWallet';\nimport type { Bip44AccountProvider } from './providers';\nimport { isAccountProviderWrapper } from './providers';\nimport type { MultichainAccountServiceMessenger } from './types';\nimport { createSentryError } from './utils';\n\nexport type GroupState =\n ServiceState[StateKeys['entropySource']][StateKeys['groupIndex']];\n\n/**\n * A multichain account group that holds multiple accounts.\n */\nexport class MultichainAccountGroup<\n Account extends Bip44Account<KeyringAccount>,\n> implements MultichainAccountGroupDefinition<Account>\n{\n readonly #id: MultichainAccountGroupId;\n\n readonly #wallet: MultichainAccountWallet<Account>;\n\n readonly #groupIndex: number;\n\n readonly #providers: Bip44AccountProvider<Account>[];\n\n readonly #providerToAccounts: Map<\n Bip44AccountProvider<Account>,\n Account['id'][]\n >;\n\n readonly #accountToProvider: Map<\n Account['id'],\n Bip44AccountProvider<Account>\n >;\n\n readonly #messenger: MultichainAccountServiceMessenger;\n\n readonly #log: Logger;\n\n #initialized = false;\n\n constructor({\n groupIndex,\n wallet,\n providers,\n messenger,\n }: {\n groupIndex: number;\n wallet: MultichainAccountWallet<Account>;\n providers: Bip44AccountProvider<Account>[];\n messenger: MultichainAccountServiceMessenger;\n }) {\n this.#id = toMultichainAccountGroupId(wallet.id, groupIndex);\n this.#groupIndex = groupIndex;\n this.#wallet = wallet;\n this.#providers = providers;\n this.#messenger = messenger;\n this.#providerToAccounts = new Map();\n this.#accountToProvider = new Map();\n\n this.#log = createModuleLogger(log, `[${this.#id}]`);\n }\n\n /**\n * Clear the account to provider state for a given provider.\n *\n * @param provider - The provider to clear the account to provider state for.\n */\n #clearAccountToProviderState(provider: Bip44AccountProvider<Account>): void {\n this.#accountToProvider.forEach((accountProvider, id) => {\n if (accountProvider === provider) {\n this.#accountToProvider.delete(id);\n }\n });\n }\n\n /**\n * Update the internal representation of accounts with the given group state.\n *\n * @param groupState - The group state.\n */\n #setState(groupState: GroupState): void {\n for (const provider of this.#providers) {\n const accountIds = groupState[provider.getName()];\n\n if (accountIds) {\n this.#clearAccountToProviderState(provider);\n this.#providerToAccounts.set(provider, accountIds);\n\n for (const accountId of accountIds) {\n this.#accountToProvider.set(accountId, provider);\n }\n }\n }\n\n if (this.#initialized) {\n this.#messenger.publish(\n 'MultichainAccountService:multichainAccountGroupUpdated',\n this,\n );\n } else {\n this.#initialized = true;\n }\n }\n\n /**\n * Initialize the multichain account group and construct the internal representation of accounts.\n *\n * @param groupState - The group state.\n */\n init(groupState: GroupState): void {\n this.#log('Initializing group state...');\n this.#setState(groupState);\n this.#log('Finished initializing group state...');\n }\n\n /**\n * Update the group state.\n *\n * @param groupState - The group state.\n */\n update(groupState: GroupState): void {\n this.#log('Updating group state...');\n this.#setState(groupState);\n this.#log('Finished updating group state...');\n }\n\n /**\n * Gets the multichain account group ID.\n *\n * @returns The multichain account group ID.\n */\n get id(): MultichainAccountGroupId {\n return this.#id;\n }\n\n /**\n * Gets the multichain account group type.\n *\n * @returns The multichain account type.\n */\n get type(): AccountGroupType.MultichainAccount {\n return AccountGroupType.MultichainAccount;\n }\n\n /**\n * Gets the multichain account's wallet reference (parent).\n *\n * @returns The multichain account's wallet.\n */\n get wallet(): MultichainAccountWallet<Account> {\n return this.#wallet;\n }\n\n /**\n * Gets the multichain account group index.\n *\n * @returns The multichain account group index.\n */\n get groupIndex(): number {\n return this.#groupIndex;\n }\n\n /**\n * Checks if there's any underlying accounts for this multichain accounts.\n *\n * @returns True if there's any underlying accounts, false otherwise.\n */\n hasAccounts(): boolean {\n // If there's anything in the reverse-map, it means we have some accounts.\n return this.#accountToProvider.size > 0;\n }\n\n /**\n * Gets the accounts for this multichain account.\n *\n * @returns The accounts.\n */\n getAccounts(): Account[] {\n const allAccounts: Account[] = [];\n\n for (const [provider, accounts] of this.#providerToAccounts.entries()) {\n for (const id of accounts) {\n const account = provider.getAccount(id);\n\n if (account) {\n // If for some reason we cannot get this account from the provider, it\n // might means it has been deleted or something, so we just filter it\n // out.\n allAccounts.push(account);\n }\n }\n }\n\n return allAccounts;\n }\n\n /**\n * Gets the account IDs for this multichain account.\n *\n * @returns The account IDs.\n */\n getAccountIds(): Account['id'][] {\n return [...this.#accountToProvider.keys()];\n }\n\n /**\n * Gets the account for a given account ID.\n *\n * @param id - Account ID.\n * @returns The account or undefined if not found.\n */\n getAccount(id: Account['id']): Account | undefined {\n const provider = this.#accountToProvider.get(id);\n\n // If there's nothing in the map, it means we tried to get an account\n // that does not belong to this multichain account.\n if (!provider) {\n return undefined;\n }\n\n return provider.getAccount(id);\n }\n\n /**\n * Query an account matching the selector.\n *\n * @param selector - Query selector.\n * @returns The account matching the selector or undefined if not matching.\n * @throws If multiple accounts match the selector.\n */\n get(selector: AccountSelector<Account>): Account | undefined {\n return selectOne(this.getAccounts(), selector);\n }\n\n /**\n * Query accounts matching the selector.\n *\n * @param selector - Query selector.\n * @returns The accounts matching the selector.\n */\n select(selector: AccountSelector<Account>): Account[] {\n return select(this.getAccounts(), selector);\n }\n\n /**\n * Align the multichain account group.\n *\n * This will create accounts for providers that don't have any accounts yet.\n */\n async alignAccounts(): Promise<void> {\n this.#log('Aligning accounts...');\n\n this.#providerToAccounts.clear();\n this.#accountToProvider.clear();\n\n const results = await Promise.allSettled(\n this.#providers.map(async (provider) => {\n try {\n const accounts = await provider.alignAccounts({\n entropySource: this.wallet.entropySource,\n groupIndex: this.groupIndex,\n });\n\n const isDisabled =\n isAccountProviderWrapper(provider) && provider.isDisabled();\n\n if (isDisabled) {\n this.#log(\n `Account provider \"${provider.getName()}\" is disabled, skipping alignment...`,\n );\n } else if (accounts.length > 0) {\n this.#log(\n `Found missing accounts for account provider \"${provider.getName()}\", creating them now...`,\n );\n this.#providerToAccounts.set(provider, accounts);\n for (const accountId of accounts) {\n this.#accountToProvider.set(accountId, provider);\n }\n }\n\n return accounts;\n } catch (error) {\n // istanbul ignore next\n this.#log(\n `${WARNING_PREFIX} ${error instanceof Error ? error.message : String(error)}`,\n );\n const sentryError = createSentryError(\n `Unable to align accounts with provider \"${provider.getName()}\"`,\n error as Error,\n {\n groupIndex: this.groupIndex,\n provider: provider.getName(),\n },\n );\n this.#messenger.captureException?.(sentryError);\n throw error;\n }\n }),\n );\n\n let failureMessage = '';\n let failureCount = 0;\n const groupState = results.reduce<GroupState>((state, result, idx) => {\n if (result.status === 'fulfilled' && result.value.length) {\n state[this.#providers[idx].getName()] = result.value;\n } else if (result.status === 'rejected') {\n failureCount += 1;\n failureMessage += `\\n- ${this.#providers[idx].getName()}: ${result.reason.message}`;\n }\n return state;\n }, {});\n\n // Update group state\n this.update(groupState);\n\n if (failureCount > 0) {\n const hasMultipleFailures = failureCount > 1;\n const message = `Failed to fully align multichain account group for entropy ID: ${this.wallet.entropySource} and group index: ${this.groupIndex}, some accounts might be missing. ${hasMultipleFailures ? 'Providers' : 'Provider'} threw the following ${hasMultipleFailures ? 'errors' : 'error'}:${failureMessage}`;\n\n this.#log(`${WARNING_PREFIX} ${message}`);\n console.warn(message);\n }\n\n this.#log('Aligned');\n }\n}\n"]}
|
|
@@ -10,11 +10,10 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
10
10
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
11
11
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
12
|
};
|
|
13
|
-
var _MultichainAccountService_instances, _MultichainAccountService_messenger, _MultichainAccountService_providers, _MultichainAccountService_wallets,
|
|
13
|
+
var _MultichainAccountService_instances, _MultichainAccountService_messenger, _MultichainAccountService_watcher, _MultichainAccountService_providers, _MultichainAccountService_wallets, _MultichainAccountService_getStateKeys, _MultichainAccountService_constructServiceState, _MultichainAccountService_getWallet, _MultichainAccountService_getPrimaryEntropySourceId, _MultichainAccountService_createWalletByImport, _MultichainAccountService_createWalletByNewVault, _MultichainAccountService_createWalletByRestore;
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.MultichainAccountService = exports.serviceName = void 0;
|
|
16
16
|
const account_api_1 = require("@metamask/account-api");
|
|
17
|
-
const key_tree_1 = require("@metamask/key-tree");
|
|
18
17
|
const keyring_controller_1 = require("@metamask/keyring-controller");
|
|
19
18
|
const utils_1 = require("@metamask/utils");
|
|
20
19
|
const analytics_1 = require("./analytics/index.cjs");
|
|
@@ -25,6 +24,7 @@ const AccountProviderWrapper_1 = require("./providers/AccountProviderWrapper.cjs
|
|
|
25
24
|
const EvmAccountProvider_1 = require("./providers/EvmAccountProvider.cjs");
|
|
26
25
|
const SolAccountProvider_1 = require("./providers/SolAccountProvider.cjs");
|
|
27
26
|
const SolAccountProvider_2 = require("./providers/SolAccountProvider.cjs");
|
|
27
|
+
const SnapPlatformWatcher_1 = require("./snaps/SnapPlatformWatcher.cjs");
|
|
28
28
|
const utils_2 = require("./utils.cjs");
|
|
29
29
|
exports.serviceName = 'MultichainAccountService';
|
|
30
30
|
/**
|
|
@@ -44,16 +44,15 @@ class MultichainAccountService {
|
|
|
44
44
|
constructor({ messenger, providers = [], providerConfigs, config, }) {
|
|
45
45
|
_MultichainAccountService_instances.add(this);
|
|
46
46
|
_MultichainAccountService_messenger.set(this, void 0);
|
|
47
|
+
_MultichainAccountService_watcher.set(this, void 0);
|
|
47
48
|
_MultichainAccountService_providers.set(this, void 0);
|
|
48
49
|
_MultichainAccountService_wallets.set(this, void 0);
|
|
49
|
-
_MultichainAccountService_accountIdToContext.set(this, void 0);
|
|
50
50
|
/**
|
|
51
51
|
* The name of the service.
|
|
52
52
|
*/
|
|
53
53
|
this.name = exports.serviceName;
|
|
54
54
|
__classPrivateFieldSet(this, _MultichainAccountService_messenger, messenger, "f");
|
|
55
55
|
__classPrivateFieldSet(this, _MultichainAccountService_wallets, new Map(), "f");
|
|
56
|
-
__classPrivateFieldSet(this, _MultichainAccountService_accountIdToContext, new Map(), "f");
|
|
57
56
|
// Pass trace callback directly to preserve original 'this' context
|
|
58
57
|
// This avoids binding the callback to the MultichainAccountService instance
|
|
59
58
|
const traceCallback = config?.trace ?? analytics_1.traceFallback;
|
|
@@ -64,6 +63,7 @@ class MultichainAccountService {
|
|
|
64
63
|
// Custom account providers that can be provided by the MetaMask client.
|
|
65
64
|
...providers,
|
|
66
65
|
], "f");
|
|
66
|
+
__classPrivateFieldSet(this, _MultichainAccountService_watcher, new SnapPlatformWatcher_1.SnapPlatformWatcher(messenger), "f");
|
|
67
67
|
__classPrivateFieldGet(this, _MultichainAccountService_messenger, "f").registerActionHandler('MultichainAccountService:getMultichainAccountGroup', (...args) => this.getMultichainAccountGroup(...args));
|
|
68
68
|
__classPrivateFieldGet(this, _MultichainAccountService_messenger, "f").registerActionHandler('MultichainAccountService:getMultichainAccountGroups', (...args) => this.getMultichainAccountGroups(...args));
|
|
69
69
|
__classPrivateFieldGet(this, _MultichainAccountService_messenger, "f").registerActionHandler('MultichainAccountService:getMultichainAccountWallet', (...args) => this.getMultichainAccountWallet(...args));
|
|
@@ -75,8 +75,8 @@ class MultichainAccountService {
|
|
|
75
75
|
__classPrivateFieldGet(this, _MultichainAccountService_messenger, "f").registerActionHandler('MultichainAccountService:alignWallet', (...args) => this.alignWallet(...args));
|
|
76
76
|
__classPrivateFieldGet(this, _MultichainAccountService_messenger, "f").registerActionHandler('MultichainAccountService:createMultichainAccountWallet', (...args) => this.createMultichainAccountWallet(...args));
|
|
77
77
|
__classPrivateFieldGet(this, _MultichainAccountService_messenger, "f").registerActionHandler('MultichainAccountService:resyncAccounts', (...args) => this.resyncAccounts(...args));
|
|
78
|
-
__classPrivateFieldGet(this, _MultichainAccountService_messenger, "f").
|
|
79
|
-
__classPrivateFieldGet(this, _MultichainAccountService_messenger, "f").
|
|
78
|
+
__classPrivateFieldGet(this, _MultichainAccountService_messenger, "f").registerActionHandler('MultichainAccountService:removeMultichainAccountWallet', (...args) => this.removeMultichainAccountWallet(...args));
|
|
79
|
+
__classPrivateFieldGet(this, _MultichainAccountService_messenger, "f").registerActionHandler('MultichainAccountService:ensureCanUseSnapPlatform', (...args) => this.ensureCanUseSnapPlatform(...args));
|
|
80
80
|
}
|
|
81
81
|
/**
|
|
82
82
|
* Initialize the service and constructs the internal reprensentation of
|
|
@@ -85,32 +85,22 @@ class MultichainAccountService {
|
|
|
85
85
|
async init() {
|
|
86
86
|
(0, logger_1.projectLogger)('Initializing...');
|
|
87
87
|
__classPrivateFieldGet(this, _MultichainAccountService_wallets, "f").clear();
|
|
88
|
-
__classPrivateFieldGet(this,
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
// Reverse mapping between account ID and their multichain wallet/account:
|
|
105
|
-
for (const group of wallet.getMultichainAccountGroups()) {
|
|
106
|
-
for (const account of group.getAccounts()) {
|
|
107
|
-
__classPrivateFieldGet(this, _MultichainAccountService_accountIdToContext, "f").set(account.id, {
|
|
108
|
-
wallet,
|
|
109
|
-
group,
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
}
|
|
88
|
+
const { serviceState, providerState } = __classPrivateFieldGet(this, _MultichainAccountService_instances, "m", _MultichainAccountService_constructServiceState).call(this);
|
|
89
|
+
for (const provider of __classPrivateFieldGet(this, _MultichainAccountService_providers, "f")) {
|
|
90
|
+
const providerName = provider.getName();
|
|
91
|
+
// Initialize providers even if there are no accounts yet.
|
|
92
|
+
// Passing an empty array ensures providers start in a valid state.
|
|
93
|
+
const state = providerState[providerName] ?? [];
|
|
94
|
+
provider.init(state);
|
|
95
|
+
}
|
|
96
|
+
for (const entropySource of Object.keys(serviceState)) {
|
|
97
|
+
const wallet = new MultichainAccountWallet_1.MultichainAccountWallet({
|
|
98
|
+
entropySource,
|
|
99
|
+
providers: __classPrivateFieldGet(this, _MultichainAccountService_providers, "f"),
|
|
100
|
+
messenger: __classPrivateFieldGet(this, _MultichainAccountService_messenger, "f"),
|
|
101
|
+
});
|
|
102
|
+
wallet.init(serviceState[entropySource]);
|
|
103
|
+
__classPrivateFieldGet(this, _MultichainAccountService_wallets, "f").set(wallet.id, wallet);
|
|
114
104
|
}
|
|
115
105
|
(0, logger_1.projectLogger)('Initialized');
|
|
116
106
|
}
|
|
@@ -152,15 +142,8 @@ class MultichainAccountService {
|
|
|
152
142
|
}));
|
|
153
143
|
(0, logger_1.projectLogger)('Providers got re-synced!');
|
|
154
144
|
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
* multichain account group references.
|
|
158
|
-
*
|
|
159
|
-
* @param id - Account ID.
|
|
160
|
-
* @returns The account context if any, undefined otherwise.
|
|
161
|
-
*/
|
|
162
|
-
getAccountContext(id) {
|
|
163
|
-
return __classPrivateFieldGet(this, _MultichainAccountService_accountIdToContext, "f").get(id);
|
|
145
|
+
ensureCanUseSnapPlatform() {
|
|
146
|
+
return __classPrivateFieldGet(this, _MultichainAccountService_watcher, "f").ensureCanUseSnapPlatform();
|
|
164
147
|
}
|
|
165
148
|
/**
|
|
166
149
|
* Gets a reference to the multichain account wallet matching this entropy source.
|
|
@@ -182,39 +165,52 @@ class MultichainAccountService {
|
|
|
182
165
|
return Array.from(__classPrivateFieldGet(this, _MultichainAccountService_wallets, "f").values());
|
|
183
166
|
}
|
|
184
167
|
/**
|
|
185
|
-
* Creates a new multichain account wallet
|
|
168
|
+
* Creates a new multichain account wallet by either importing an existing mnemonic,
|
|
169
|
+
* creating a new vault and keychain, or restoring a vault and keyring.
|
|
186
170
|
*
|
|
187
171
|
* NOTE: This method should only be called in client code where a mutex lock is acquired.
|
|
188
|
-
* `
|
|
172
|
+
* `discoverAccounts` should be called after this method to discover and create accounts.
|
|
189
173
|
*
|
|
190
|
-
* @param
|
|
191
|
-
* @param
|
|
174
|
+
* @param params - The parameters to use to create the new wallet.
|
|
175
|
+
* @param params.mnemonic - The mnemonic to use to create the new wallet.
|
|
176
|
+
* @param params.password - The password to encrypt the vault with.
|
|
177
|
+
* @param params.type - The flow type to use to create the new wallet.
|
|
192
178
|
* @throws If the mnemonic has already been imported.
|
|
193
179
|
* @returns The new multichain account wallet.
|
|
194
180
|
*/
|
|
195
|
-
async createMultichainAccountWallet(
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
return (0, utils_1.areUint8ArraysEqual)(keyring.mnemonic, mnemonicAsBytes);
|
|
203
|
-
});
|
|
204
|
-
if (alreadyHasImportedSrp) {
|
|
205
|
-
throw new Error('This Secret Recovery Phrase has already been imported.');
|
|
181
|
+
async createMultichainAccountWallet(params) {
|
|
182
|
+
let wallet;
|
|
183
|
+
if (params.type === 'import') {
|
|
184
|
+
wallet = await __classPrivateFieldGet(this, _MultichainAccountService_instances, "m", _MultichainAccountService_createWalletByImport).call(this, params.mnemonic);
|
|
185
|
+
}
|
|
186
|
+
else if (params.type === 'create') {
|
|
187
|
+
wallet = await __classPrivateFieldGet(this, _MultichainAccountService_instances, "m", _MultichainAccountService_createWalletByNewVault).call(this, params.password);
|
|
206
188
|
}
|
|
207
|
-
(
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
messenger: __classPrivateFieldGet(this, _MultichainAccountService_messenger, "f"),
|
|
213
|
-
});
|
|
189
|
+
else if (params.type === 'restore') {
|
|
190
|
+
wallet = await __classPrivateFieldGet(this, _MultichainAccountService_instances, "m", _MultichainAccountService_createWalletByRestore).call(this, params.password, params.mnemonic);
|
|
191
|
+
}
|
|
192
|
+
(0, utils_1.assert)(wallet, 'Failed to create wallet.');
|
|
193
|
+
wallet.init({});
|
|
214
194
|
__classPrivateFieldGet(this, _MultichainAccountService_wallets, "f").set(wallet.id, wallet);
|
|
215
195
|
(0, logger_1.projectLogger)(`Wallet created: [${wallet.id}]`);
|
|
216
196
|
return wallet;
|
|
217
197
|
}
|
|
198
|
+
/**
|
|
199
|
+
* Removes a multichain account wallet.
|
|
200
|
+
*
|
|
201
|
+
* NOTE: This method should only be called in client code as a revert mechanism.
|
|
202
|
+
* At the point that this code is called, discovery shouldn't have been triggered.
|
|
203
|
+
* This is meant to be used in the scenario where a seed phrase backup is not successful.
|
|
204
|
+
*
|
|
205
|
+
* @param entropySource - The entropy source of the multichain account wallet.
|
|
206
|
+
* @param accountAddress - The address of the account to remove.
|
|
207
|
+
* @returns The removed multichain account wallet.
|
|
208
|
+
*/
|
|
209
|
+
async removeMultichainAccountWallet(entropySource, accountAddress) {
|
|
210
|
+
const wallet = __classPrivateFieldGet(this, _MultichainAccountService_instances, "m", _MultichainAccountService_getWallet).call(this, entropySource);
|
|
211
|
+
await __classPrivateFieldGet(this, _MultichainAccountService_messenger, "f").call('KeyringController:removeAccount', accountAddress);
|
|
212
|
+
__classPrivateFieldGet(this, _MultichainAccountService_wallets, "f").delete(wallet.id);
|
|
213
|
+
}
|
|
218
214
|
/**
|
|
219
215
|
* Gets a reference to the multichain account group matching this entropy source
|
|
220
216
|
* and a group index.
|
|
@@ -309,64 +305,106 @@ class MultichainAccountService {
|
|
|
309
305
|
}
|
|
310
306
|
}
|
|
311
307
|
exports.MultichainAccountService = MultichainAccountService;
|
|
312
|
-
_MultichainAccountService_messenger = new WeakMap(),
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
(0, logger_1.projectLogger)(`Adding new wallet for entropy: "${account.options.entropy.id}" (for account: "${account.id}")`);
|
|
321
|
-
// That's a new wallet.
|
|
322
|
-
wallet = new MultichainAccountWallet_1.MultichainAccountWallet({
|
|
323
|
-
entropySource: account.options.entropy.id,
|
|
324
|
-
providers: __classPrivateFieldGet(this, _MultichainAccountService_providers, "f"),
|
|
325
|
-
messenger: __classPrivateFieldGet(this, _MultichainAccountService_messenger, "f"),
|
|
326
|
-
});
|
|
327
|
-
__classPrivateFieldGet(this, _MultichainAccountService_wallets, "f").set(wallet.id, wallet);
|
|
328
|
-
// If that's a new wallet wallet. There's nothing to "force-sync".
|
|
329
|
-
sync = false;
|
|
330
|
-
}
|
|
331
|
-
let group = wallet.getMultichainAccountGroup(account.options.entropy.groupIndex);
|
|
332
|
-
if (!group) {
|
|
333
|
-
// This new account is a new multichain account, let the wallet know
|
|
334
|
-
// it has to re-sync with its providers.
|
|
335
|
-
if (sync) {
|
|
336
|
-
wallet.sync();
|
|
308
|
+
_MultichainAccountService_messenger = new WeakMap(), _MultichainAccountService_watcher = new WeakMap(), _MultichainAccountService_providers = new WeakMap(), _MultichainAccountService_wallets = new WeakMap(), _MultichainAccountService_instances = new WeakSet(), _MultichainAccountService_getStateKeys = function _MultichainAccountService_getStateKeys(account) {
|
|
309
|
+
for (const provider of __classPrivateFieldGet(this, _MultichainAccountService_providers, "f")) {
|
|
310
|
+
if ((0, account_api_1.isBip44Account)(account) && provider.isAccountCompatible(account)) {
|
|
311
|
+
return {
|
|
312
|
+
entropySource: account.options.entropy.id,
|
|
313
|
+
groupIndex: account.options.entropy.groupIndex,
|
|
314
|
+
providerName: provider.getName(),
|
|
315
|
+
};
|
|
337
316
|
}
|
|
338
|
-
group = wallet.getMultichainAccountGroup(account.options.entropy.groupIndex);
|
|
339
|
-
// If that's a new multichain account. There's nothing to "force-sync".
|
|
340
|
-
sync = false;
|
|
341
317
|
}
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
318
|
+
return null;
|
|
319
|
+
}, _MultichainAccountService_constructServiceState = function _MultichainAccountService_constructServiceState() {
|
|
320
|
+
var _a, _b;
|
|
321
|
+
const accounts = __classPrivateFieldGet(this, _MultichainAccountService_messenger, "f").call('AccountsController:listMultichainAccounts');
|
|
322
|
+
const serviceState = {};
|
|
323
|
+
const providerState = {};
|
|
324
|
+
for (const account of accounts) {
|
|
325
|
+
const keys = __classPrivateFieldGet(this, _MultichainAccountService_instances, "m", _MultichainAccountService_getStateKeys).call(this, account);
|
|
326
|
+
if (keys) {
|
|
327
|
+
const { entropySource, groupIndex, providerName } = keys;
|
|
328
|
+
serviceState[entropySource] ?? (serviceState[entropySource] = {});
|
|
329
|
+
(_a = serviceState[entropySource])[groupIndex] ?? (_a[groupIndex] = {});
|
|
330
|
+
(_b = serviceState[entropySource][groupIndex])[providerName] ?? (_b[providerName] = []);
|
|
331
|
+
serviceState[entropySource][groupIndex][providerName].push(account.id);
|
|
332
|
+
providerState[providerName] ?? (providerState[providerName] = []);
|
|
333
|
+
providerState[providerName].push(account.id);
|
|
347
334
|
}
|
|
348
|
-
// Same here, this account should have been already grouped in that
|
|
349
|
-
// multichain account.
|
|
350
|
-
__classPrivateFieldGet(this, _MultichainAccountService_accountIdToContext, "f").set(account.id, {
|
|
351
|
-
wallet,
|
|
352
|
-
group,
|
|
353
|
-
});
|
|
354
335
|
}
|
|
355
|
-
|
|
356
|
-
// Force sync of the appropriate wallet if an account got removed.
|
|
357
|
-
const found = __classPrivateFieldGet(this, _MultichainAccountService_accountIdToContext, "f").get(id);
|
|
358
|
-
if (found) {
|
|
359
|
-
const { wallet } = found;
|
|
360
|
-
(0, logger_1.projectLogger)(`Re-synchronize wallet [${wallet.id}] since account "${id}" got removed`);
|
|
361
|
-
wallet.sync();
|
|
362
|
-
}
|
|
363
|
-
// Safe to call delete even if the `id` was not referencing a BIP-44 account.
|
|
364
|
-
__classPrivateFieldGet(this, _MultichainAccountService_accountIdToContext, "f").delete(id);
|
|
336
|
+
return { serviceState, providerState };
|
|
365
337
|
}, _MultichainAccountService_getWallet = function _MultichainAccountService_getWallet(entropySource) {
|
|
366
338
|
const wallet = __classPrivateFieldGet(this, _MultichainAccountService_wallets, "f").get((0, account_api_1.toMultichainAccountWalletId)(entropySource));
|
|
367
339
|
if (!wallet) {
|
|
368
340
|
throw new Error('Unknown wallet, no wallet matching this entropy source');
|
|
369
341
|
}
|
|
370
342
|
return wallet;
|
|
343
|
+
}, _MultichainAccountService_getPrimaryEntropySourceId = function _MultichainAccountService_getPrimaryEntropySourceId() {
|
|
344
|
+
const { keyrings } = __classPrivateFieldGet(this, _MultichainAccountService_messenger, "f").call('KeyringController:getState');
|
|
345
|
+
const primaryKeyring = keyrings.find((keyring) => keyring.type === 'HD Key Tree');
|
|
346
|
+
(0, utils_1.assert)(primaryKeyring, 'Primary keyring not found');
|
|
347
|
+
return primaryKeyring.metadata.id;
|
|
348
|
+
}, _MultichainAccountService_createWalletByImport =
|
|
349
|
+
/**
|
|
350
|
+
* Creates a new multichain account wallet by importing an existing mnemonic.
|
|
351
|
+
*
|
|
352
|
+
* @param mnemonic - The mnemonic to use to create the new wallet.
|
|
353
|
+
* @returns The new multichain account wallet.
|
|
354
|
+
*/
|
|
355
|
+
async function _MultichainAccountService_createWalletByImport(mnemonic) {
|
|
356
|
+
(0, logger_1.projectLogger)(`Creating new wallet by importing an existing mnemonic...`);
|
|
357
|
+
const existingKeyrings = __classPrivateFieldGet(this, _MultichainAccountService_messenger, "f").call('KeyringController:getKeyringsByType', keyring_controller_1.KeyringTypes.hd);
|
|
358
|
+
const alreadyHasImportedSrp = existingKeyrings.some((keyring) => {
|
|
359
|
+
if (!keyring.mnemonic) {
|
|
360
|
+
return false;
|
|
361
|
+
}
|
|
362
|
+
return (0, utils_1.areUint8ArraysEqual)(keyring.mnemonic, mnemonic);
|
|
363
|
+
});
|
|
364
|
+
if (alreadyHasImportedSrp) {
|
|
365
|
+
throw new Error('This Secret Recovery Phrase has already been imported.');
|
|
366
|
+
}
|
|
367
|
+
const result = await __classPrivateFieldGet(this, _MultichainAccountService_messenger, "f").call('KeyringController:addNewKeyring', keyring_controller_1.KeyringTypes.hd, { mnemonic });
|
|
368
|
+
// The wallet is ripe for discovery
|
|
369
|
+
return new MultichainAccountWallet_1.MultichainAccountWallet({
|
|
370
|
+
providers: __classPrivateFieldGet(this, _MultichainAccountService_providers, "f"),
|
|
371
|
+
entropySource: result.id,
|
|
372
|
+
messenger: __classPrivateFieldGet(this, _MultichainAccountService_messenger, "f"),
|
|
373
|
+
});
|
|
374
|
+
}, _MultichainAccountService_createWalletByNewVault =
|
|
375
|
+
/**
|
|
376
|
+
* Creates a new multichain account wallet by creating a new vault and keychain.
|
|
377
|
+
*
|
|
378
|
+
* @param password - The password to encrypt the vault with.
|
|
379
|
+
* @returns The new multichain account wallet.
|
|
380
|
+
*/
|
|
381
|
+
async function _MultichainAccountService_createWalletByNewVault(password) {
|
|
382
|
+
(0, logger_1.projectLogger)(`Creating new wallet by creating a new vault and keychain...`);
|
|
383
|
+
await __classPrivateFieldGet(this, _MultichainAccountService_messenger, "f").call('KeyringController:createNewVaultAndKeychain', password);
|
|
384
|
+
const entropySourceId = __classPrivateFieldGet(this, _MultichainAccountService_instances, "m", _MultichainAccountService_getPrimaryEntropySourceId).call(this);
|
|
385
|
+
// The wallet is ripe for discovery
|
|
386
|
+
return new MultichainAccountWallet_1.MultichainAccountWallet({
|
|
387
|
+
providers: __classPrivateFieldGet(this, _MultichainAccountService_providers, "f"),
|
|
388
|
+
entropySource: entropySourceId,
|
|
389
|
+
messenger: __classPrivateFieldGet(this, _MultichainAccountService_messenger, "f"),
|
|
390
|
+
});
|
|
391
|
+
}, _MultichainAccountService_createWalletByRestore =
|
|
392
|
+
/**
|
|
393
|
+
* Creates a new multichain account wallet by restoring a vault and keyring.
|
|
394
|
+
*
|
|
395
|
+
* @param password - The password to encrypt the vault with.
|
|
396
|
+
* @param mnemonic - The mnemonic to use to restore the new wallet.
|
|
397
|
+
* @returns The new multichain account wallet.
|
|
398
|
+
*/
|
|
399
|
+
async function _MultichainAccountService_createWalletByRestore(password, mnemonic) {
|
|
400
|
+
(0, logger_1.projectLogger)(`Creating new wallet by restoring vault and keyring...`);
|
|
401
|
+
await __classPrivateFieldGet(this, _MultichainAccountService_messenger, "f").call('KeyringController:createNewVaultAndRestore', password, mnemonic);
|
|
402
|
+
const entropySourceId = __classPrivateFieldGet(this, _MultichainAccountService_instances, "m", _MultichainAccountService_getPrimaryEntropySourceId).call(this);
|
|
403
|
+
// The wallet is ripe for discovery
|
|
404
|
+
return new MultichainAccountWallet_1.MultichainAccountWallet({
|
|
405
|
+
providers: __classPrivateFieldGet(this, _MultichainAccountService_providers, "f"),
|
|
406
|
+
entropySource: entropySourceId,
|
|
407
|
+
messenger: __classPrivateFieldGet(this, _MultichainAccountService_messenger, "f"),
|
|
408
|
+
});
|
|
371
409
|
};
|
|
372
410
|
//# sourceMappingURL=MultichainAccountService.cjs.map
|