@metamask-previews/multichain-account-service 0.5.0-preview-e821953 → 0.5.0-preview-8159614
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/dist/MultichainAccountService.cjs +50 -3
- package/dist/MultichainAccountService.cjs.map +1 -1
- package/dist/MultichainAccountService.d.cts +3 -2
- package/dist/MultichainAccountService.d.cts.map +1 -1
- package/dist/MultichainAccountService.d.mts +3 -2
- package/dist/MultichainAccountService.d.mts.map +1 -1
- package/dist/MultichainAccountService.mjs +50 -3
- package/dist/MultichainAccountService.mjs.map +1 -1
- package/dist/MultichainAccountWallet.cjs +12 -11
- package/dist/MultichainAccountWallet.cjs.map +1 -1
- package/dist/MultichainAccountWallet.d.cts +12 -1
- package/dist/MultichainAccountWallet.d.cts.map +1 -1
- package/dist/MultichainAccountWallet.d.mts +12 -1
- package/dist/MultichainAccountWallet.d.mts.map +1 -1
- package/dist/MultichainAccountWallet.mjs +12 -11
- package/dist/MultichainAccountWallet.mjs.map +1 -1
- package/dist/transient-state.cjs +3 -0
- package/dist/transient-state.cjs.map +1 -0
- package/dist/transient-state.d.cts +12 -0
- package/dist/transient-state.d.cts.map +1 -0
- package/dist/transient-state.d.mts +12 -0
- package/dist/transient-state.d.mts.map +1 -0
- package/dist/transient-state.mjs +2 -0
- package/dist/transient-state.mjs.map +1 -0
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +7 -0
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +7 -0
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -10,20 +10,28 @@ 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, _MultichainAccountService_accountIdToContext, _MultichainAccountService_handleOnAccountAdded, _MultichainAccountService_handleOnAccountRemoved, _MultichainAccountService_getWallet;
|
|
13
|
+
var _MultichainAccountService_instances, _MultichainAccountService_messenger, _MultichainAccountService_providers, _MultichainAccountService_wallets, _MultichainAccountService_accountIdToContext, _MultichainAccountService_getMultichainAccoultWalletTransientStateProxy, _MultichainAccountService_handleOnAccountAdded, _MultichainAccountService_handleOnAccountRemoved, _MultichainAccountService_getWallet;
|
|
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 base_controller_1 = require("@metamask/base-controller");
|
|
17
18
|
const keyring_controller_1 = require("@metamask/keyring-controller");
|
|
18
19
|
const MultichainAccountWallet_1 = require("./MultichainAccountWallet.cjs");
|
|
19
20
|
const AccountProviderWrapper_1 = require("./providers/AccountProviderWrapper.cjs");
|
|
20
21
|
const EvmAccountProvider_1 = require("./providers/EvmAccountProvider.cjs");
|
|
21
22
|
const SolAccountProvider_1 = require("./providers/SolAccountProvider.cjs");
|
|
22
23
|
exports.serviceName = 'MultichainAccountService';
|
|
24
|
+
const serviceMetadata = {
|
|
25
|
+
accountWalletsTransientState: {
|
|
26
|
+
// Transient states are never persisted.
|
|
27
|
+
persist: false,
|
|
28
|
+
anonymous: false,
|
|
29
|
+
},
|
|
30
|
+
};
|
|
23
31
|
/**
|
|
24
32
|
* Service to expose multichain accounts capabilities.
|
|
25
33
|
*/
|
|
26
|
-
class MultichainAccountService {
|
|
34
|
+
class MultichainAccountService extends base_controller_1.BaseController {
|
|
27
35
|
/**
|
|
28
36
|
* Constructs a new MultichainAccountService.
|
|
29
37
|
*
|
|
@@ -34,6 +42,14 @@ class MultichainAccountService {
|
|
|
34
42
|
* providers.
|
|
35
43
|
*/
|
|
36
44
|
constructor({ messenger, providers = [] }) {
|
|
45
|
+
super({
|
|
46
|
+
messenger,
|
|
47
|
+
name: exports.serviceName,
|
|
48
|
+
metadata: serviceMetadata,
|
|
49
|
+
state: {
|
|
50
|
+
accountWalletsTransientState: {},
|
|
51
|
+
},
|
|
52
|
+
});
|
|
37
53
|
_MultichainAccountService_instances.add(this);
|
|
38
54
|
_MultichainAccountService_messenger.set(this, void 0);
|
|
39
55
|
_MultichainAccountService_providers.set(this, void 0);
|
|
@@ -81,9 +97,11 @@ class MultichainAccountService {
|
|
|
81
97
|
const entropySource = keyring.metadata.id;
|
|
82
98
|
// This will automatically "associate" all multichain accounts for that wallet
|
|
83
99
|
// (based on the accounts owned by each account providers).
|
|
100
|
+
const walletId = (0, account_api_1.toMultichainAccountWalletId)(entropySource);
|
|
84
101
|
const wallet = new MultichainAccountWallet_1.MultichainAccountWallet({
|
|
85
102
|
entropySource,
|
|
86
103
|
providers: __classPrivateFieldGet(this, _MultichainAccountService_providers, "f"),
|
|
104
|
+
transientState: __classPrivateFieldGet(this, _MultichainAccountService_instances, "m", _MultichainAccountService_getMultichainAccoultWalletTransientStateProxy).call(this, walletId),
|
|
87
105
|
});
|
|
88
106
|
__classPrivateFieldGet(this, _MultichainAccountService_wallets, "f").set(wallet.id, wallet);
|
|
89
107
|
// Reverse mapping between account ID and their multichain wallet/account:
|
|
@@ -223,18 +241,47 @@ class MultichainAccountService {
|
|
|
223
241
|
}
|
|
224
242
|
}
|
|
225
243
|
exports.MultichainAccountService = MultichainAccountService;
|
|
226
|
-
_MultichainAccountService_messenger = new WeakMap(), _MultichainAccountService_providers = new WeakMap(), _MultichainAccountService_wallets = new WeakMap(), _MultichainAccountService_accountIdToContext = new WeakMap(), _MultichainAccountService_instances = new WeakSet(),
|
|
244
|
+
_MultichainAccountService_messenger = new WeakMap(), _MultichainAccountService_providers = new WeakMap(), _MultichainAccountService_wallets = new WeakMap(), _MultichainAccountService_accountIdToContext = new WeakMap(), _MultichainAccountService_instances = new WeakSet(), _MultichainAccountService_getMultichainAccoultWalletTransientStateProxy = function _MultichainAccountService_getMultichainAccoultWalletTransientStateProxy(walletId) {
|
|
245
|
+
// eslint-disable-next-line consistent-this, @typescript-eslint/no-this-alias
|
|
246
|
+
const service = this;
|
|
247
|
+
const getTransientState = (state, then) => {
|
|
248
|
+
return then(state.accountWalletsTransientState[walletId]);
|
|
249
|
+
};
|
|
250
|
+
const setTransientState = (state, then) => {
|
|
251
|
+
then(state.accountWalletsTransientState[walletId]);
|
|
252
|
+
};
|
|
253
|
+
// Create initial transient state for this wallet if it does not exists yet.
|
|
254
|
+
if (!service.state.accountWalletsTransientState[walletId]) {
|
|
255
|
+
this.update((state) => {
|
|
256
|
+
state.accountWalletsTransientState[walletId] = {
|
|
257
|
+
isAlignmentInProgress: false,
|
|
258
|
+
};
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
return {
|
|
262
|
+
get isAlignmentInProgress() {
|
|
263
|
+
return getTransientState(service.state, (transientState) => transientState.isAlignmentInProgress);
|
|
264
|
+
},
|
|
265
|
+
set isAlignmentInProgress(inProgress) {
|
|
266
|
+
service.update((state) => {
|
|
267
|
+
setTransientState(state, (transientState) => (transientState.isAlignmentInProgress = inProgress));
|
|
268
|
+
});
|
|
269
|
+
},
|
|
270
|
+
};
|
|
271
|
+
}, _MultichainAccountService_handleOnAccountAdded = function _MultichainAccountService_handleOnAccountAdded(account) {
|
|
227
272
|
// We completely omit non-BIP-44 accounts!
|
|
228
273
|
if (!(0, account_api_1.isBip44Account)(account)) {
|
|
229
274
|
return;
|
|
230
275
|
}
|
|
231
276
|
let sync = true;
|
|
277
|
+
const walletId = (0, account_api_1.toMultichainAccountWalletId)(account.options.entropy.id);
|
|
232
278
|
let wallet = __classPrivateFieldGet(this, _MultichainAccountService_wallets, "f").get((0, account_api_1.toMultichainAccountWalletId)(account.options.entropy.id));
|
|
233
279
|
if (!wallet) {
|
|
234
280
|
// That's a new wallet.
|
|
235
281
|
wallet = new MultichainAccountWallet_1.MultichainAccountWallet({
|
|
236
282
|
entropySource: account.options.entropy.id,
|
|
237
283
|
providers: __classPrivateFieldGet(this, _MultichainAccountService_providers, "f"),
|
|
284
|
+
transientState: __classPrivateFieldGet(this, _MultichainAccountService_instances, "m", _MultichainAccountService_getMultichainAccoultWalletTransientStateProxy).call(this, walletId),
|
|
238
285
|
});
|
|
239
286
|
__classPrivateFieldGet(this, _MultichainAccountService_wallets, "f").set(wallet.id, wallet);
|
|
240
287
|
// If that's a new wallet wallet. There's nothing to "force-sync".
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MultichainAccountService.cjs","sourceRoot":"","sources":["../src/MultichainAccountService.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n isBip44Account,\n toMultichainAccountWalletId,\n} from '@metamask/account-api';\nimport type {\n MultichainAccountWalletId,\n Bip44Account,\n AccountProvider,\n} from '@metamask/account-api';\nimport type { EntropySourceId, KeyringAccount } from '@metamask/keyring-api';\nimport { KeyringTypes } from '@metamask/keyring-controller';\n\nimport type { MultichainAccountGroup } from './MultichainAccountGroup';\nimport { MultichainAccountWallet } from './MultichainAccountWallet';\nimport {\n AccountProviderWrapper,\n isAccountProviderWrapper,\n} from './providers/AccountProviderWrapper';\nimport { EvmAccountProvider } from './providers/EvmAccountProvider';\nimport { SolAccountProvider } from './providers/SolAccountProvider';\nimport type { MultichainAccountServiceMessenger } from './types';\n\nexport const serviceName = 'MultichainAccountService';\n\n/**\n * The options that {@link MultichainAccountService} takes.\n */\ntype MultichainAccountServiceOptions = {\n messenger: MultichainAccountServiceMessenger;\n providers?: AccountProvider<Bip44Account<KeyringAccount>>[];\n};\n\n/** Reverse mapping object used to map account IDs and their wallet/multichain account. */\ntype AccountContext<Account extends Bip44Account<KeyringAccount>> = {\n wallet: MultichainAccountWallet<Account>;\n group: MultichainAccountGroup<Account>;\n};\n\n/**\n * Service to expose multichain accounts capabilities.\n */\nexport class MultichainAccountService {\n readonly #messenger: MultichainAccountServiceMessenger;\n\n readonly #providers: AccountProvider<Bip44Account<KeyringAccount>>[];\n\n readonly #wallets: Map<\n MultichainAccountWalletId,\n MultichainAccountWallet<Bip44Account<KeyringAccount>>\n >;\n\n readonly #accountIdToContext: Map<\n Bip44Account<KeyringAccount>['id'],\n AccountContext<Bip44Account<KeyringAccount>>\n >;\n\n /**\n * The name of the service.\n */\n name: typeof serviceName = serviceName;\n\n /**\n * Constructs a new MultichainAccountService.\n *\n * @param options - The options.\n * @param options.messenger - The messenger suited to this\n * MultichainAccountService.\n * @param options.providers - Optional list of account\n * providers.\n */\n constructor({ messenger, providers = [] }: MultichainAccountServiceOptions) {\n this.#messenger = messenger;\n this.#wallets = new Map();\n this.#accountIdToContext = new Map();\n\n // TODO: Rely on keyring capabilities once the keyring API is used by all keyrings.\n this.#providers = [\n new EvmAccountProvider(this.#messenger),\n new AccountProviderWrapper(\n this.#messenger,\n new SolAccountProvider(this.#messenger),\n ),\n // Custom account providers that can be provided by the MetaMask client.\n ...providers,\n ];\n\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:getMultichainAccountGroup',\n (...args) => this.getMultichainAccountGroup(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:getMultichainAccountGroups',\n (...args) => this.getMultichainAccountGroups(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:getMultichainAccountWallet',\n (...args) => this.getMultichainAccountWallet(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:getMultichainAccountWallets',\n (...args) => this.getMultichainAccountWallets(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:createNextMultichainAccountGroup',\n (...args) => this.createNextMultichainAccountGroup(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:createMultichainAccountGroup',\n (...args) => this.createMultichainAccountGroup(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:setBasicFunctionality',\n (...args) => this.setBasicFunctionality(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:alignWallets',\n (...args) => this.alignWallets(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:alignWallet',\n (...args) => this.alignWallet(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:getIsAlignmentInProgress',\n () => this.getIsAlignmentInProgress(),\n );\n\n this.#messenger.subscribe('AccountsController:accountAdded', (account) =>\n this.#handleOnAccountAdded(account),\n );\n this.#messenger.subscribe('AccountsController:accountRemoved', (id) =>\n this.#handleOnAccountRemoved(id),\n );\n }\n\n /**\n * Initialize the service and constructs the internal reprensentation of\n * multichain accounts and wallets.\n */\n init(): void {\n this.#wallets.clear();\n this.#accountIdToContext.clear();\n\n // Create initial wallets.\n const { keyrings } = this.#messenger.call('KeyringController:getState');\n for (const keyring of keyrings) {\n if (keyring.type === (KeyringTypes.hd as string)) {\n // Only HD keyrings have an entropy source/SRP.\n const entropySource = keyring.metadata.id;\n\n // This will automatically \"associate\" all multichain accounts for that wallet\n // (based on the accounts owned by each account providers).\n const wallet = new MultichainAccountWallet({\n entropySource,\n providers: this.#providers,\n });\n this.#wallets.set(wallet.id, wallet);\n\n // Reverse mapping between account ID and their multichain wallet/account:\n for (const group of wallet.getMultichainAccountGroups()) {\n for (const account of group.getAccounts()) {\n this.#accountIdToContext.set(account.id, {\n wallet,\n group,\n });\n }\n }\n }\n }\n }\n\n #handleOnAccountAdded(account: KeyringAccount): void {\n // We completely omit non-BIP-44 accounts!\n if (!isBip44Account(account)) {\n return;\n }\n\n let sync = true;\n\n let wallet = this.#wallets.get(\n toMultichainAccountWalletId(account.options.entropy.id),\n );\n if (!wallet) {\n // That's a new wallet.\n wallet = new MultichainAccountWallet({\n entropySource: account.options.entropy.id,\n providers: this.#providers,\n });\n this.#wallets.set(wallet.id, wallet);\n\n // If that's a new wallet wallet. There's nothing to \"force-sync\".\n sync = false;\n }\n\n let group = wallet.getMultichainAccountGroup(\n account.options.entropy.groupIndex,\n );\n if (!group) {\n // This new account is a new multichain account, let the wallet know\n // it has to re-sync with its providers.\n if (sync) {\n wallet.sync();\n }\n\n group = wallet.getMultichainAccountGroup(\n account.options.entropy.groupIndex,\n );\n\n // If that's a new multichain account. There's nothing to \"force-sync\".\n sync = false;\n }\n\n // We have to check against `undefined` in case `getMultichainAccount` is\n // not able to find this multichain account (which should not be possible...)\n if (group) {\n if (sync) {\n group.sync();\n }\n\n // Same here, this account should have been already grouped in that\n // multichain account.\n this.#accountIdToContext.set(account.id, {\n wallet,\n group,\n });\n }\n }\n\n #handleOnAccountRemoved(id: KeyringAccount['id']): void {\n // Force sync of the appropriate wallet if an account got removed.\n const found = this.#accountIdToContext.get(id);\n if (found) {\n const { wallet } = found;\n\n wallet.sync();\n }\n\n // Safe to call delete even if the `id` was not referencing a BIP-44 account.\n this.#accountIdToContext.delete(id);\n }\n\n #getWallet(\n entropySource: EntropySourceId,\n ): MultichainAccountWallet<Bip44Account<KeyringAccount>> {\n const wallet = this.#wallets.get(\n toMultichainAccountWalletId(entropySource),\n );\n\n if (!wallet) {\n throw new Error('Unknown wallet, no wallet matching this entropy source');\n }\n\n return wallet;\n }\n\n /**\n * Gets the account's context which contains its multichain wallet and\n * multichain account group references.\n *\n * @param id - Account ID.\n * @returns The account context if any, undefined otherwise.\n */\n getAccountContext(\n id: KeyringAccount['id'],\n ): AccountContext<Bip44Account<KeyringAccount>> | undefined {\n return this.#accountIdToContext.get(id);\n }\n\n /**\n * Gets a reference to the multichain account wallet matching this entropy source.\n *\n * @param options - Options.\n * @param options.entropySource - The entropy source of the multichain account.\n * @throws If none multichain account match this entropy.\n * @returns A reference to the multichain account wallet.\n */\n getMultichainAccountWallet({\n entropySource,\n }: {\n entropySource: EntropySourceId;\n }): MultichainAccountWallet<Bip44Account<KeyringAccount>> {\n return this.#getWallet(entropySource);\n }\n\n /**\n * Gets an array of all multichain account wallets.\n *\n * @returns An array of all multichain account wallets.\n */\n getMultichainAccountWallets(): MultichainAccountWallet<\n Bip44Account<KeyringAccount>\n >[] {\n return Array.from(this.#wallets.values());\n }\n\n /**\n * Gets a reference to the multichain account group matching this entropy source\n * and a group index.\n *\n * @param options - Options.\n * @param options.entropySource - The entropy source of the multichain account.\n * @param options.groupIndex - The group index of the multichain account.\n * @throws If none multichain account match this entropy source and group index.\n * @returns A reference to the multichain account.\n */\n getMultichainAccountGroup({\n entropySource,\n groupIndex,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }): MultichainAccountGroup<Bip44Account<KeyringAccount>> {\n const multichainAccount =\n this.#getWallet(entropySource).getMultichainAccountGroup(groupIndex);\n\n if (!multichainAccount) {\n throw new Error(`No multichain account for index: ${groupIndex}`);\n }\n\n return multichainAccount;\n }\n\n /**\n * Gets all multichain account groups for a given entropy source.\n *\n * @param options - Options.\n * @param options.entropySource - The entropy source to query.\n * @throws If no multichain accounts match this entropy source.\n * @returns A list of all multichain accounts.\n */\n getMultichainAccountGroups({\n entropySource,\n }: {\n entropySource: EntropySourceId;\n }): MultichainAccountGroup<Bip44Account<KeyringAccount>>[] {\n return this.#getWallet(entropySource).getMultichainAccountGroups();\n }\n\n /**\n * Creates the next multichain account group.\n *\n * @param options - Options.\n * @param options.entropySource - The wallet's entropy source.\n * @returns The next multichain account group.\n */\n async createNextMultichainAccountGroup({\n entropySource,\n }: {\n entropySource: EntropySourceId;\n }): Promise<MultichainAccountGroup<Bip44Account<KeyringAccount>>> {\n return await this.#getWallet(\n entropySource,\n ).createNextMultichainAccountGroup();\n }\n\n /**\n * Creates a multichain account group.\n *\n * @param options - Options.\n * @param options.groupIndex - The group index to use.\n * @param options.entropySource - The wallet's entropy source.\n * @returns The multichain account group for this group index.\n */\n async createMultichainAccountGroup({\n groupIndex,\n entropySource,\n }: {\n groupIndex: number;\n entropySource: EntropySourceId;\n }): Promise<MultichainAccountGroup<Bip44Account<KeyringAccount>>> {\n return await this.#getWallet(entropySource).createMultichainAccountGroup(\n groupIndex,\n );\n }\n\n /**\n * Set basic functionality state and trigger alignment if enabled.\n * When basic functionality is disabled, snap-based providers are disabled.\n * When enabled, all snap providers are enabled and wallet alignment is triggered.\n * EVM providers are never disabled as they're required for basic wallet functionality.\n *\n * @param enabled - Whether basic functionality is enabled.\n */\n async setBasicFunctionality(enabled: boolean): Promise<void> {\n // Loop through providers and enable/disable only wrapped ones when basic functionality changes\n for (const provider of this.#providers) {\n if (isAccountProviderWrapper(provider)) {\n provider.setEnabled(enabled);\n }\n // Regular providers (like EVM) are never disabled for basic functionality\n }\n\n // Trigger alignment only when basic functionality is enabled\n if (enabled) {\n await this.alignWallets();\n }\n }\n\n /**\n * Gets whether wallet alignment is currently in progress.\n *\n * @returns True if any wallet alignment is in progress, false otherwise.\n */\n getIsAlignmentInProgress(): boolean {\n return Array.from(this.#wallets.values()).some((wallet) =>\n wallet.getIsAlignmentInProgress(),\n );\n }\n\n /**\n * Align all multichain account wallets.\n */\n async alignWallets(): Promise<void> {\n const wallets = this.getMultichainAccountWallets();\n await Promise.all(wallets.map((w) => w.alignGroups()));\n }\n\n /**\n * Align a specific multichain account wallet.\n *\n * @param entropySource - The entropy source of the multichain account wallet.\n */\n async alignWallet(entropySource: EntropySourceId): Promise<void> {\n const wallet = this.getMultichainAccountWallet({ entropySource });\n await wallet.alignGroups();\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"MultichainAccountService.cjs","sourceRoot":"","sources":["../src/MultichainAccountService.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n isBip44Account,\n toMultichainAccountWalletId,\n} from '@metamask/account-api';\nimport type {\n MultichainAccountWalletId,\n Bip44Account,\n AccountProvider,\n} from '@metamask/account-api';\nimport { BaseController } from '@metamask/base-controller';\nimport type { EntropySourceId, KeyringAccount } from '@metamask/keyring-api';\nimport { KeyringTypes } from '@metamask/keyring-controller';\n\nimport type { MultichainAccountGroup } from './MultichainAccountGroup';\nimport type { MultichainAccountWalletTransientState } from './MultichainAccountWallet';\nimport { MultichainAccountWallet } from './MultichainAccountWallet';\nimport {\n AccountProviderWrapper,\n isAccountProviderWrapper,\n} from './providers/AccountProviderWrapper';\nimport { EvmAccountProvider } from './providers/EvmAccountProvider';\nimport { SolAccountProvider } from './providers/SolAccountProvider';\nimport type { TransientStateMetadata } from './transient-state';\nimport type {\n MultichainAccountServiceMessenger,\n MultichainAccountServiceTransientState,\n} from './types';\n\nexport const serviceName = 'MultichainAccountService';\n\nconst serviceMetadata: TransientStateMetadata<MultichainAccountServiceTransientState> =\n {\n accountWalletsTransientState: {\n // Transient states are never persisted.\n persist: false,\n anonymous: false,\n },\n };\n\n/**\n * The options that {@link MultichainAccountService} takes.\n */\ntype MultichainAccountServiceOptions = {\n messenger: MultichainAccountServiceMessenger;\n providers?: AccountProvider<Bip44Account<KeyringAccount>>[];\n};\n\n/** Reverse mapping object used to map account IDs and their wallet/multichain account. */\ntype AccountContext<Account extends Bip44Account<KeyringAccount>> = {\n wallet: MultichainAccountWallet<Account>;\n group: MultichainAccountGroup<Account>;\n};\n\n/**\n * Service to expose multichain accounts capabilities.\n */\nexport class MultichainAccountService extends BaseController<\n typeof serviceName,\n MultichainAccountServiceTransientState,\n MultichainAccountServiceMessenger\n> {\n readonly #messenger: MultichainAccountServiceMessenger;\n\n readonly #providers: AccountProvider<Bip44Account<KeyringAccount>>[];\n\n readonly #wallets: Map<\n MultichainAccountWalletId,\n MultichainAccountWallet<Bip44Account<KeyringAccount>>\n >;\n\n readonly #accountIdToContext: Map<\n Bip44Account<KeyringAccount>['id'],\n AccountContext<Bip44Account<KeyringAccount>>\n >;\n\n /**\n * The name of the service.\n */\n name: typeof serviceName = serviceName;\n\n /**\n * Constructs a new MultichainAccountService.\n *\n * @param options - The options.\n * @param options.messenger - The messenger suited to this\n * MultichainAccountService.\n * @param options.providers - Optional list of account\n * providers.\n */\n constructor({ messenger, providers = [] }: MultichainAccountServiceOptions) {\n super({\n messenger,\n name: serviceName,\n metadata: serviceMetadata,\n state: {\n accountWalletsTransientState: {},\n },\n });\n\n this.#messenger = messenger;\n this.#wallets = new Map();\n this.#accountIdToContext = new Map();\n\n // TODO: Rely on keyring capabilities once the keyring API is used by all keyrings.\n this.#providers = [\n new EvmAccountProvider(this.#messenger),\n new AccountProviderWrapper(\n this.#messenger,\n new SolAccountProvider(this.#messenger),\n ),\n // Custom account providers that can be provided by the MetaMask client.\n ...providers,\n ];\n\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:getMultichainAccountGroup',\n (...args) => this.getMultichainAccountGroup(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:getMultichainAccountGroups',\n (...args) => this.getMultichainAccountGroups(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:getMultichainAccountWallet',\n (...args) => this.getMultichainAccountWallet(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:getMultichainAccountWallets',\n (...args) => this.getMultichainAccountWallets(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:createNextMultichainAccountGroup',\n (...args) => this.createNextMultichainAccountGroup(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:createMultichainAccountGroup',\n (...args) => this.createMultichainAccountGroup(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:setBasicFunctionality',\n (...args) => this.setBasicFunctionality(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:alignWallets',\n (...args) => this.alignWallets(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:alignWallet',\n (...args) => this.alignWallet(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:getIsAlignmentInProgress',\n () => this.getIsAlignmentInProgress(),\n );\n\n this.#messenger.subscribe('AccountsController:accountAdded', (account) =>\n this.#handleOnAccountAdded(account),\n );\n this.#messenger.subscribe('AccountsController:accountRemoved', (id) =>\n this.#handleOnAccountRemoved(id),\n );\n }\n\n /**\n * Initialize the service and constructs the internal reprensentation of\n * multichain accounts and wallets.\n */\n init(): void {\n this.#wallets.clear();\n this.#accountIdToContext.clear();\n\n // Create initial wallets.\n const { keyrings } = this.#messenger.call('KeyringController:getState');\n for (const keyring of keyrings) {\n if (keyring.type === (KeyringTypes.hd as string)) {\n // Only HD keyrings have an entropy source/SRP.\n const entropySource = keyring.metadata.id;\n\n // This will automatically \"associate\" all multichain accounts for that wallet\n // (based on the accounts owned by each account providers).\n const walletId = toMultichainAccountWalletId(entropySource);\n const wallet = new MultichainAccountWallet({\n entropySource,\n providers: this.#providers,\n transientState:\n this.#getMultichainAccoultWalletTransientStateProxy(walletId),\n });\n this.#wallets.set(wallet.id, wallet);\n\n // Reverse mapping between account ID and their multichain wallet/account:\n for (const group of wallet.getMultichainAccountGroups()) {\n for (const account of group.getAccounts()) {\n this.#accountIdToContext.set(account.id, {\n wallet,\n group,\n });\n }\n }\n }\n }\n }\n\n #getMultichainAccoultWalletTransientStateProxy(\n walletId: MultichainAccountWalletId,\n ): MultichainAccountWalletTransientState {\n // eslint-disable-next-line consistent-this, @typescript-eslint/no-this-alias\n const service = this;\n\n const getTransientState = <Return>(\n state: MultichainAccountServiceTransientState,\n then: (transientState: MultichainAccountWalletTransientState) => Return,\n ) => {\n return then(state.accountWalletsTransientState[walletId]);\n };\n\n const setTransientState = (\n state: MultichainAccountServiceTransientState,\n then: (transientState: MultichainAccountWalletTransientState) => void,\n ) => {\n then(state.accountWalletsTransientState[walletId]);\n };\n\n // Create initial transient state for this wallet if it does not exists yet.\n if (!service.state.accountWalletsTransientState[walletId]) {\n this.update((state) => {\n state.accountWalletsTransientState[walletId] = {\n isAlignmentInProgress: false,\n };\n });\n }\n\n return {\n get isAlignmentInProgress(): boolean {\n return getTransientState(\n service.state,\n (transientState) => transientState.isAlignmentInProgress,\n );\n },\n set isAlignmentInProgress(inProgress: boolean) {\n service.update((state) => {\n setTransientState(\n state,\n (transientState) =>\n (transientState.isAlignmentInProgress = inProgress),\n );\n });\n },\n };\n }\n\n #handleOnAccountAdded(account: KeyringAccount): void {\n // We completely omit non-BIP-44 accounts!\n if (!isBip44Account(account)) {\n return;\n }\n\n let sync = true;\n\n const walletId = toMultichainAccountWalletId(account.options.entropy.id);\n let wallet = this.#wallets.get(\n toMultichainAccountWalletId(account.options.entropy.id),\n );\n if (!wallet) {\n // That's a new wallet.\n wallet = new MultichainAccountWallet({\n entropySource: account.options.entropy.id,\n providers: this.#providers,\n transientState:\n this.#getMultichainAccoultWalletTransientStateProxy(walletId),\n });\n this.#wallets.set(wallet.id, wallet);\n\n // If that's a new wallet wallet. There's nothing to \"force-sync\".\n sync = false;\n }\n\n let group = wallet.getMultichainAccountGroup(\n account.options.entropy.groupIndex,\n );\n if (!group) {\n // This new account is a new multichain account, let the wallet know\n // it has to re-sync with its providers.\n if (sync) {\n wallet.sync();\n }\n\n group = wallet.getMultichainAccountGroup(\n account.options.entropy.groupIndex,\n );\n\n // If that's a new multichain account. There's nothing to \"force-sync\".\n sync = false;\n }\n\n // We have to check against `undefined` in case `getMultichainAccount` is\n // not able to find this multichain account (which should not be possible...)\n if (group) {\n if (sync) {\n group.sync();\n }\n\n // Same here, this account should have been already grouped in that\n // multichain account.\n this.#accountIdToContext.set(account.id, {\n wallet,\n group,\n });\n }\n }\n\n #handleOnAccountRemoved(id: KeyringAccount['id']): void {\n // Force sync of the appropriate wallet if an account got removed.\n const found = this.#accountIdToContext.get(id);\n if (found) {\n const { wallet } = found;\n\n wallet.sync();\n }\n\n // Safe to call delete even if the `id` was not referencing a BIP-44 account.\n this.#accountIdToContext.delete(id);\n }\n\n #getWallet(\n entropySource: EntropySourceId,\n ): MultichainAccountWallet<Bip44Account<KeyringAccount>> {\n const wallet = this.#wallets.get(\n toMultichainAccountWalletId(entropySource),\n );\n\n if (!wallet) {\n throw new Error('Unknown wallet, no wallet matching this entropy source');\n }\n\n return wallet;\n }\n\n /**\n * Gets the account's context which contains its multichain wallet and\n * multichain account group references.\n *\n * @param id - Account ID.\n * @returns The account context if any, undefined otherwise.\n */\n getAccountContext(\n id: KeyringAccount['id'],\n ): AccountContext<Bip44Account<KeyringAccount>> | undefined {\n return this.#accountIdToContext.get(id);\n }\n\n /**\n * Gets a reference to the multichain account wallet matching this entropy source.\n *\n * @param options - Options.\n * @param options.entropySource - The entropy source of the multichain account.\n * @throws If none multichain account match this entropy.\n * @returns A reference to the multichain account wallet.\n */\n getMultichainAccountWallet({\n entropySource,\n }: {\n entropySource: EntropySourceId;\n }): MultichainAccountWallet<Bip44Account<KeyringAccount>> {\n return this.#getWallet(entropySource);\n }\n\n /**\n * Gets an array of all multichain account wallets.\n *\n * @returns An array of all multichain account wallets.\n */\n getMultichainAccountWallets(): MultichainAccountWallet<\n Bip44Account<KeyringAccount>\n >[] {\n return Array.from(this.#wallets.values());\n }\n\n /**\n * Gets a reference to the multichain account group matching this entropy source\n * and a group index.\n *\n * @param options - Options.\n * @param options.entropySource - The entropy source of the multichain account.\n * @param options.groupIndex - The group index of the multichain account.\n * @throws If none multichain account match this entropy source and group index.\n * @returns A reference to the multichain account.\n */\n getMultichainAccountGroup({\n entropySource,\n groupIndex,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }): MultichainAccountGroup<Bip44Account<KeyringAccount>> {\n const multichainAccount =\n this.#getWallet(entropySource).getMultichainAccountGroup(groupIndex);\n\n if (!multichainAccount) {\n throw new Error(`No multichain account for index: ${groupIndex}`);\n }\n\n return multichainAccount;\n }\n\n /**\n * Gets all multichain account groups for a given entropy source.\n *\n * @param options - Options.\n * @param options.entropySource - The entropy source to query.\n * @throws If no multichain accounts match this entropy source.\n * @returns A list of all multichain accounts.\n */\n getMultichainAccountGroups({\n entropySource,\n }: {\n entropySource: EntropySourceId;\n }): MultichainAccountGroup<Bip44Account<KeyringAccount>>[] {\n return this.#getWallet(entropySource).getMultichainAccountGroups();\n }\n\n /**\n * Creates the next multichain account group.\n *\n * @param options - Options.\n * @param options.entropySource - The wallet's entropy source.\n * @returns The next multichain account group.\n */\n async createNextMultichainAccountGroup({\n entropySource,\n }: {\n entropySource: EntropySourceId;\n }): Promise<MultichainAccountGroup<Bip44Account<KeyringAccount>>> {\n return await this.#getWallet(\n entropySource,\n ).createNextMultichainAccountGroup();\n }\n\n /**\n * Creates a multichain account group.\n *\n * @param options - Options.\n * @param options.groupIndex - The group index to use.\n * @param options.entropySource - The wallet's entropy source.\n * @returns The multichain account group for this group index.\n */\n async createMultichainAccountGroup({\n groupIndex,\n entropySource,\n }: {\n groupIndex: number;\n entropySource: EntropySourceId;\n }): Promise<MultichainAccountGroup<Bip44Account<KeyringAccount>>> {\n return await this.#getWallet(entropySource).createMultichainAccountGroup(\n groupIndex,\n );\n }\n\n /**\n * Set basic functionality state and trigger alignment if enabled.\n * When basic functionality is disabled, snap-based providers are disabled.\n * When enabled, all snap providers are enabled and wallet alignment is triggered.\n * EVM providers are never disabled as they're required for basic wallet functionality.\n *\n * @param enabled - Whether basic functionality is enabled.\n */\n async setBasicFunctionality(enabled: boolean): Promise<void> {\n // Loop through providers and enable/disable only wrapped ones when basic functionality changes\n for (const provider of this.#providers) {\n if (isAccountProviderWrapper(provider)) {\n provider.setEnabled(enabled);\n }\n // Regular providers (like EVM) are never disabled for basic functionality\n }\n\n // Trigger alignment only when basic functionality is enabled\n if (enabled) {\n await this.alignWallets();\n }\n }\n\n /**\n * Gets whether wallet alignment is currently in progress.\n *\n * @returns True if any wallet alignment is in progress, false otherwise.\n */\n getIsAlignmentInProgress(): boolean {\n return Array.from(this.#wallets.values()).some((wallet) =>\n wallet.getIsAlignmentInProgress(),\n );\n }\n\n /**\n * Align all multichain account wallets.\n */\n async alignWallets(): Promise<void> {\n const wallets = this.getMultichainAccountWallets();\n await Promise.all(wallets.map((w) => w.alignGroups()));\n }\n\n /**\n * Align a specific multichain account wallet.\n *\n * @param entropySource - The entropy source of the multichain account wallet.\n */\n async alignWallet(entropySource: EntropySourceId): Promise<void> {\n const wallet = this.getMultichainAccountWallet({ entropySource });\n await wallet.alignGroups();\n }\n}\n"]}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { Bip44Account, AccountProvider } from "@metamask/account-api";
|
|
2
|
+
import { BaseController } from "@metamask/base-controller";
|
|
2
3
|
import type { EntropySourceId, KeyringAccount } from "@metamask/keyring-api";
|
|
3
4
|
import type { MultichainAccountGroup } from "./MultichainAccountGroup.cjs";
|
|
4
5
|
import { MultichainAccountWallet } from "./MultichainAccountWallet.cjs";
|
|
5
|
-
import type { MultichainAccountServiceMessenger } from "./types.cjs";
|
|
6
|
+
import type { MultichainAccountServiceMessenger, MultichainAccountServiceTransientState } from "./types.cjs";
|
|
6
7
|
export declare const serviceName = "MultichainAccountService";
|
|
7
8
|
/**
|
|
8
9
|
* The options that {@link MultichainAccountService} takes.
|
|
@@ -19,7 +20,7 @@ type AccountContext<Account extends Bip44Account<KeyringAccount>> = {
|
|
|
19
20
|
/**
|
|
20
21
|
* Service to expose multichain accounts capabilities.
|
|
21
22
|
*/
|
|
22
|
-
export declare class MultichainAccountService {
|
|
23
|
+
export declare class MultichainAccountService extends BaseController<typeof serviceName, MultichainAccountServiceTransientState, MultichainAccountServiceMessenger> {
|
|
23
24
|
#private;
|
|
24
25
|
/**
|
|
25
26
|
* The name of the service.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MultichainAccountService.d.cts","sourceRoot":"","sources":["../src/MultichainAccountService.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAEV,YAAY,EACZ,eAAe,EAChB,8BAA8B;AAC/B,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,8BAA8B;AAG7E,OAAO,KAAK,EAAE,sBAAsB,EAAE,qCAAiC;
|
|
1
|
+
{"version":3,"file":"MultichainAccountService.d.cts","sourceRoot":"","sources":["../src/MultichainAccountService.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAEV,YAAY,EACZ,eAAe,EAChB,8BAA8B;AAC/B,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,8BAA8B;AAG7E,OAAO,KAAK,EAAE,sBAAsB,EAAE,qCAAiC;AAEvE,OAAO,EAAE,uBAAuB,EAAE,sCAAkC;AAQpE,OAAO,KAAK,EACV,iCAAiC,EACjC,sCAAsC,EACvC,oBAAgB;AAEjB,eAAO,MAAM,WAAW,6BAA6B,CAAC;AAWtD;;GAEG;AACH,KAAK,+BAA+B,GAAG;IACrC,SAAS,EAAE,iCAAiC,CAAC;IAC7C,SAAS,CAAC,EAAE,eAAe,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC;CAC7D,CAAC;AAEF,0FAA0F;AAC1F,KAAK,cAAc,CAAC,OAAO,SAAS,YAAY,CAAC,cAAc,CAAC,IAAI;IAClE,MAAM,EAAE,uBAAuB,CAAC,OAAO,CAAC,CAAC;IACzC,KAAK,EAAE,sBAAsB,CAAC,OAAO,CAAC,CAAC;CACxC,CAAC;AAEF;;GAEG;AACH,qBAAa,wBAAyB,SAAQ,cAAc,CAC1D,OAAO,WAAW,EAClB,sCAAsC,EACtC,iCAAiC,CAClC;;IAeC;;OAEG;IACH,IAAI,EAAE,OAAO,WAAW,CAAe;IAEvC;;;;;;;;OAQG;gBACS,EAAE,SAAS,EAAE,SAAc,EAAE,EAAE,+BAA+B;IA0E1E;;;OAGG;IACH,IAAI,IAAI,IAAI;IA0KZ;;;;;;OAMG;IACH,iBAAiB,CACf,EAAE,EAAE,cAAc,CAAC,IAAI,CAAC,GACvB,cAAc,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC,GAAG,SAAS;IAI3D;;;;;;;OAOG;IACH,0BAA0B,CAAC,EACzB,aAAa,GACd,EAAE;QACD,aAAa,EAAE,eAAe,CAAC;KAChC,GAAG,uBAAuB,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC;IAIzD;;;;OAIG;IACH,2BAA2B,IAAI,uBAAuB,CACpD,YAAY,CAAC,cAAc,CAAC,CAC7B,EAAE;IAIH;;;;;;;;;OASG;IACH,yBAAyB,CAAC,EACxB,aAAa,EACb,UAAU,GACX,EAAE;QACD,aAAa,EAAE,eAAe,CAAC;QAC/B,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,sBAAsB,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC;IAWxD;;;;;;;OAOG;IACH,0BAA0B,CAAC,EACzB,aAAa,GACd,EAAE;QACD,aAAa,EAAE,eAAe,CAAC;KAChC,GAAG,sBAAsB,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC,EAAE;IAI1D;;;;;;OAMG;IACG,gCAAgC,CAAC,EACrC,aAAa,GACd,EAAE;QACD,aAAa,EAAE,eAAe,CAAC;KAChC,GAAG,OAAO,CAAC,sBAAsB,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC,CAAC;IAMjE;;;;;;;OAOG;IACG,4BAA4B,CAAC,EACjC,UAAU,EACV,aAAa,GACd,EAAE;QACD,UAAU,EAAE,MAAM,CAAC;QACnB,aAAa,EAAE,eAAe,CAAC;KAChC,GAAG,OAAO,CAAC,sBAAsB,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC,CAAC;IAMjE;;;;;;;OAOG;IACG,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAe5D;;;;OAIG;IACH,wBAAwB,IAAI,OAAO;IAMnC;;OAEG;IACG,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAKnC;;;;OAIG;IACG,WAAW,CAAC,aAAa,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;CAIjE"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { Bip44Account, AccountProvider } from "@metamask/account-api";
|
|
2
|
+
import { BaseController } from "@metamask/base-controller";
|
|
2
3
|
import type { EntropySourceId, KeyringAccount } from "@metamask/keyring-api";
|
|
3
4
|
import type { MultichainAccountGroup } from "./MultichainAccountGroup.mjs";
|
|
4
5
|
import { MultichainAccountWallet } from "./MultichainAccountWallet.mjs";
|
|
5
|
-
import type { MultichainAccountServiceMessenger } from "./types.mjs";
|
|
6
|
+
import type { MultichainAccountServiceMessenger, MultichainAccountServiceTransientState } from "./types.mjs";
|
|
6
7
|
export declare const serviceName = "MultichainAccountService";
|
|
7
8
|
/**
|
|
8
9
|
* The options that {@link MultichainAccountService} takes.
|
|
@@ -19,7 +20,7 @@ type AccountContext<Account extends Bip44Account<KeyringAccount>> = {
|
|
|
19
20
|
/**
|
|
20
21
|
* Service to expose multichain accounts capabilities.
|
|
21
22
|
*/
|
|
22
|
-
export declare class MultichainAccountService {
|
|
23
|
+
export declare class MultichainAccountService extends BaseController<typeof serviceName, MultichainAccountServiceTransientState, MultichainAccountServiceMessenger> {
|
|
23
24
|
#private;
|
|
24
25
|
/**
|
|
25
26
|
* The name of the service.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MultichainAccountService.d.mts","sourceRoot":"","sources":["../src/MultichainAccountService.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAEV,YAAY,EACZ,eAAe,EAChB,8BAA8B;AAC/B,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,8BAA8B;AAG7E,OAAO,KAAK,EAAE,sBAAsB,EAAE,qCAAiC;
|
|
1
|
+
{"version":3,"file":"MultichainAccountService.d.mts","sourceRoot":"","sources":["../src/MultichainAccountService.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAEV,YAAY,EACZ,eAAe,EAChB,8BAA8B;AAC/B,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,8BAA8B;AAG7E,OAAO,KAAK,EAAE,sBAAsB,EAAE,qCAAiC;AAEvE,OAAO,EAAE,uBAAuB,EAAE,sCAAkC;AAQpE,OAAO,KAAK,EACV,iCAAiC,EACjC,sCAAsC,EACvC,oBAAgB;AAEjB,eAAO,MAAM,WAAW,6BAA6B,CAAC;AAWtD;;GAEG;AACH,KAAK,+BAA+B,GAAG;IACrC,SAAS,EAAE,iCAAiC,CAAC;IAC7C,SAAS,CAAC,EAAE,eAAe,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC;CAC7D,CAAC;AAEF,0FAA0F;AAC1F,KAAK,cAAc,CAAC,OAAO,SAAS,YAAY,CAAC,cAAc,CAAC,IAAI;IAClE,MAAM,EAAE,uBAAuB,CAAC,OAAO,CAAC,CAAC;IACzC,KAAK,EAAE,sBAAsB,CAAC,OAAO,CAAC,CAAC;CACxC,CAAC;AAEF;;GAEG;AACH,qBAAa,wBAAyB,SAAQ,cAAc,CAC1D,OAAO,WAAW,EAClB,sCAAsC,EACtC,iCAAiC,CAClC;;IAeC;;OAEG;IACH,IAAI,EAAE,OAAO,WAAW,CAAe;IAEvC;;;;;;;;OAQG;gBACS,EAAE,SAAS,EAAE,SAAc,EAAE,EAAE,+BAA+B;IA0E1E;;;OAGG;IACH,IAAI,IAAI,IAAI;IA0KZ;;;;;;OAMG;IACH,iBAAiB,CACf,EAAE,EAAE,cAAc,CAAC,IAAI,CAAC,GACvB,cAAc,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC,GAAG,SAAS;IAI3D;;;;;;;OAOG;IACH,0BAA0B,CAAC,EACzB,aAAa,GACd,EAAE;QACD,aAAa,EAAE,eAAe,CAAC;KAChC,GAAG,uBAAuB,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC;IAIzD;;;;OAIG;IACH,2BAA2B,IAAI,uBAAuB,CACpD,YAAY,CAAC,cAAc,CAAC,CAC7B,EAAE;IAIH;;;;;;;;;OASG;IACH,yBAAyB,CAAC,EACxB,aAAa,EACb,UAAU,GACX,EAAE;QACD,aAAa,EAAE,eAAe,CAAC;QAC/B,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,sBAAsB,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC;IAWxD;;;;;;;OAOG;IACH,0BAA0B,CAAC,EACzB,aAAa,GACd,EAAE;QACD,aAAa,EAAE,eAAe,CAAC;KAChC,GAAG,sBAAsB,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC,EAAE;IAI1D;;;;;;OAMG;IACG,gCAAgC,CAAC,EACrC,aAAa,GACd,EAAE;QACD,aAAa,EAAE,eAAe,CAAC;KAChC,GAAG,OAAO,CAAC,sBAAsB,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC,CAAC;IAMjE;;;;;;;OAOG;IACG,4BAA4B,CAAC,EACjC,UAAU,EACV,aAAa,GACd,EAAE;QACD,UAAU,EAAE,MAAM,CAAC;QACnB,aAAa,EAAE,eAAe,CAAC;KAChC,GAAG,OAAO,CAAC,sBAAsB,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC,CAAC;IAMjE;;;;;;;OAOG;IACG,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAe5D;;;;OAIG;IACH,wBAAwB,IAAI,OAAO;IAMnC;;OAEG;IACG,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAKnC;;;;OAIG;IACG,WAAW,CAAC,aAAa,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;CAIjE"}
|
|
@@ -9,18 +9,26 @@ 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 _MultichainAccountService_instances, _MultichainAccountService_messenger, _MultichainAccountService_providers, _MultichainAccountService_wallets, _MultichainAccountService_accountIdToContext, _MultichainAccountService_handleOnAccountAdded, _MultichainAccountService_handleOnAccountRemoved, _MultichainAccountService_getWallet;
|
|
12
|
+
var _MultichainAccountService_instances, _MultichainAccountService_messenger, _MultichainAccountService_providers, _MultichainAccountService_wallets, _MultichainAccountService_accountIdToContext, _MultichainAccountService_getMultichainAccoultWalletTransientStateProxy, _MultichainAccountService_handleOnAccountAdded, _MultichainAccountService_handleOnAccountRemoved, _MultichainAccountService_getWallet;
|
|
13
13
|
import { isBip44Account, toMultichainAccountWalletId } from "@metamask/account-api";
|
|
14
|
+
import { BaseController } from "@metamask/base-controller";
|
|
14
15
|
import { KeyringTypes } from "@metamask/keyring-controller";
|
|
15
16
|
import { MultichainAccountWallet } from "./MultichainAccountWallet.mjs";
|
|
16
17
|
import { AccountProviderWrapper, isAccountProviderWrapper } from "./providers/AccountProviderWrapper.mjs";
|
|
17
18
|
import { EvmAccountProvider } from "./providers/EvmAccountProvider.mjs";
|
|
18
19
|
import { SolAccountProvider } from "./providers/SolAccountProvider.mjs";
|
|
19
20
|
export const serviceName = 'MultichainAccountService';
|
|
21
|
+
const serviceMetadata = {
|
|
22
|
+
accountWalletsTransientState: {
|
|
23
|
+
// Transient states are never persisted.
|
|
24
|
+
persist: false,
|
|
25
|
+
anonymous: false,
|
|
26
|
+
},
|
|
27
|
+
};
|
|
20
28
|
/**
|
|
21
29
|
* Service to expose multichain accounts capabilities.
|
|
22
30
|
*/
|
|
23
|
-
export class MultichainAccountService {
|
|
31
|
+
export class MultichainAccountService extends BaseController {
|
|
24
32
|
/**
|
|
25
33
|
* Constructs a new MultichainAccountService.
|
|
26
34
|
*
|
|
@@ -31,6 +39,14 @@ export class MultichainAccountService {
|
|
|
31
39
|
* providers.
|
|
32
40
|
*/
|
|
33
41
|
constructor({ messenger, providers = [] }) {
|
|
42
|
+
super({
|
|
43
|
+
messenger,
|
|
44
|
+
name: serviceName,
|
|
45
|
+
metadata: serviceMetadata,
|
|
46
|
+
state: {
|
|
47
|
+
accountWalletsTransientState: {},
|
|
48
|
+
},
|
|
49
|
+
});
|
|
34
50
|
_MultichainAccountService_instances.add(this);
|
|
35
51
|
_MultichainAccountService_messenger.set(this, void 0);
|
|
36
52
|
_MultichainAccountService_providers.set(this, void 0);
|
|
@@ -78,9 +94,11 @@ export class MultichainAccountService {
|
|
|
78
94
|
const entropySource = keyring.metadata.id;
|
|
79
95
|
// This will automatically "associate" all multichain accounts for that wallet
|
|
80
96
|
// (based on the accounts owned by each account providers).
|
|
97
|
+
const walletId = toMultichainAccountWalletId(entropySource);
|
|
81
98
|
const wallet = new MultichainAccountWallet({
|
|
82
99
|
entropySource,
|
|
83
100
|
providers: __classPrivateFieldGet(this, _MultichainAccountService_providers, "f"),
|
|
101
|
+
transientState: __classPrivateFieldGet(this, _MultichainAccountService_instances, "m", _MultichainAccountService_getMultichainAccoultWalletTransientStateProxy).call(this, walletId),
|
|
84
102
|
});
|
|
85
103
|
__classPrivateFieldGet(this, _MultichainAccountService_wallets, "f").set(wallet.id, wallet);
|
|
86
104
|
// Reverse mapping between account ID and their multichain wallet/account:
|
|
@@ -219,18 +237,47 @@ export class MultichainAccountService {
|
|
|
219
237
|
await wallet.alignGroups();
|
|
220
238
|
}
|
|
221
239
|
}
|
|
222
|
-
_MultichainAccountService_messenger = new WeakMap(), _MultichainAccountService_providers = new WeakMap(), _MultichainAccountService_wallets = new WeakMap(), _MultichainAccountService_accountIdToContext = new WeakMap(), _MultichainAccountService_instances = new WeakSet(),
|
|
240
|
+
_MultichainAccountService_messenger = new WeakMap(), _MultichainAccountService_providers = new WeakMap(), _MultichainAccountService_wallets = new WeakMap(), _MultichainAccountService_accountIdToContext = new WeakMap(), _MultichainAccountService_instances = new WeakSet(), _MultichainAccountService_getMultichainAccoultWalletTransientStateProxy = function _MultichainAccountService_getMultichainAccoultWalletTransientStateProxy(walletId) {
|
|
241
|
+
// eslint-disable-next-line consistent-this, @typescript-eslint/no-this-alias
|
|
242
|
+
const service = this;
|
|
243
|
+
const getTransientState = (state, then) => {
|
|
244
|
+
return then(state.accountWalletsTransientState[walletId]);
|
|
245
|
+
};
|
|
246
|
+
const setTransientState = (state, then) => {
|
|
247
|
+
then(state.accountWalletsTransientState[walletId]);
|
|
248
|
+
};
|
|
249
|
+
// Create initial transient state for this wallet if it does not exists yet.
|
|
250
|
+
if (!service.state.accountWalletsTransientState[walletId]) {
|
|
251
|
+
this.update((state) => {
|
|
252
|
+
state.accountWalletsTransientState[walletId] = {
|
|
253
|
+
isAlignmentInProgress: false,
|
|
254
|
+
};
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
return {
|
|
258
|
+
get isAlignmentInProgress() {
|
|
259
|
+
return getTransientState(service.state, (transientState) => transientState.isAlignmentInProgress);
|
|
260
|
+
},
|
|
261
|
+
set isAlignmentInProgress(inProgress) {
|
|
262
|
+
service.update((state) => {
|
|
263
|
+
setTransientState(state, (transientState) => (transientState.isAlignmentInProgress = inProgress));
|
|
264
|
+
});
|
|
265
|
+
},
|
|
266
|
+
};
|
|
267
|
+
}, _MultichainAccountService_handleOnAccountAdded = function _MultichainAccountService_handleOnAccountAdded(account) {
|
|
223
268
|
// We completely omit non-BIP-44 accounts!
|
|
224
269
|
if (!isBip44Account(account)) {
|
|
225
270
|
return;
|
|
226
271
|
}
|
|
227
272
|
let sync = true;
|
|
273
|
+
const walletId = toMultichainAccountWalletId(account.options.entropy.id);
|
|
228
274
|
let wallet = __classPrivateFieldGet(this, _MultichainAccountService_wallets, "f").get(toMultichainAccountWalletId(account.options.entropy.id));
|
|
229
275
|
if (!wallet) {
|
|
230
276
|
// That's a new wallet.
|
|
231
277
|
wallet = new MultichainAccountWallet({
|
|
232
278
|
entropySource: account.options.entropy.id,
|
|
233
279
|
providers: __classPrivateFieldGet(this, _MultichainAccountService_providers, "f"),
|
|
280
|
+
transientState: __classPrivateFieldGet(this, _MultichainAccountService_instances, "m", _MultichainAccountService_getMultichainAccoultWalletTransientStateProxy).call(this, walletId),
|
|
234
281
|
});
|
|
235
282
|
__classPrivateFieldGet(this, _MultichainAccountService_wallets, "f").set(wallet.id, wallet);
|
|
236
283
|
// If that's a new wallet wallet. There's nothing to "force-sync".
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MultichainAccountService.mjs","sourceRoot":"","sources":["../src/MultichainAccountService.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n isBip44Account,\n toMultichainAccountWalletId,\n} from '@metamask/account-api';\nimport type {\n MultichainAccountWalletId,\n Bip44Account,\n AccountProvider,\n} from '@metamask/account-api';\nimport type { EntropySourceId, KeyringAccount } from '@metamask/keyring-api';\nimport { KeyringTypes } from '@metamask/keyring-controller';\n\nimport type { MultichainAccountGroup } from './MultichainAccountGroup';\nimport { MultichainAccountWallet } from './MultichainAccountWallet';\nimport {\n AccountProviderWrapper,\n isAccountProviderWrapper,\n} from './providers/AccountProviderWrapper';\nimport { EvmAccountProvider } from './providers/EvmAccountProvider';\nimport { SolAccountProvider } from './providers/SolAccountProvider';\nimport type { MultichainAccountServiceMessenger } from './types';\n\nexport const serviceName = 'MultichainAccountService';\n\n/**\n * The options that {@link MultichainAccountService} takes.\n */\ntype MultichainAccountServiceOptions = {\n messenger: MultichainAccountServiceMessenger;\n providers?: AccountProvider<Bip44Account<KeyringAccount>>[];\n};\n\n/** Reverse mapping object used to map account IDs and their wallet/multichain account. */\ntype AccountContext<Account extends Bip44Account<KeyringAccount>> = {\n wallet: MultichainAccountWallet<Account>;\n group: MultichainAccountGroup<Account>;\n};\n\n/**\n * Service to expose multichain accounts capabilities.\n */\nexport class MultichainAccountService {\n readonly #messenger: MultichainAccountServiceMessenger;\n\n readonly #providers: AccountProvider<Bip44Account<KeyringAccount>>[];\n\n readonly #wallets: Map<\n MultichainAccountWalletId,\n MultichainAccountWallet<Bip44Account<KeyringAccount>>\n >;\n\n readonly #accountIdToContext: Map<\n Bip44Account<KeyringAccount>['id'],\n AccountContext<Bip44Account<KeyringAccount>>\n >;\n\n /**\n * The name of the service.\n */\n name: typeof serviceName = serviceName;\n\n /**\n * Constructs a new MultichainAccountService.\n *\n * @param options - The options.\n * @param options.messenger - The messenger suited to this\n * MultichainAccountService.\n * @param options.providers - Optional list of account\n * providers.\n */\n constructor({ messenger, providers = [] }: MultichainAccountServiceOptions) {\n this.#messenger = messenger;\n this.#wallets = new Map();\n this.#accountIdToContext = new Map();\n\n // TODO: Rely on keyring capabilities once the keyring API is used by all keyrings.\n this.#providers = [\n new EvmAccountProvider(this.#messenger),\n new AccountProviderWrapper(\n this.#messenger,\n new SolAccountProvider(this.#messenger),\n ),\n // Custom account providers that can be provided by the MetaMask client.\n ...providers,\n ];\n\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:getMultichainAccountGroup',\n (...args) => this.getMultichainAccountGroup(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:getMultichainAccountGroups',\n (...args) => this.getMultichainAccountGroups(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:getMultichainAccountWallet',\n (...args) => this.getMultichainAccountWallet(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:getMultichainAccountWallets',\n (...args) => this.getMultichainAccountWallets(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:createNextMultichainAccountGroup',\n (...args) => this.createNextMultichainAccountGroup(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:createMultichainAccountGroup',\n (...args) => this.createMultichainAccountGroup(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:setBasicFunctionality',\n (...args) => this.setBasicFunctionality(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:alignWallets',\n (...args) => this.alignWallets(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:alignWallet',\n (...args) => this.alignWallet(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:getIsAlignmentInProgress',\n () => this.getIsAlignmentInProgress(),\n );\n\n this.#messenger.subscribe('AccountsController:accountAdded', (account) =>\n this.#handleOnAccountAdded(account),\n );\n this.#messenger.subscribe('AccountsController:accountRemoved', (id) =>\n this.#handleOnAccountRemoved(id),\n );\n }\n\n /**\n * Initialize the service and constructs the internal reprensentation of\n * multichain accounts and wallets.\n */\n init(): void {\n this.#wallets.clear();\n this.#accountIdToContext.clear();\n\n // Create initial wallets.\n const { keyrings } = this.#messenger.call('KeyringController:getState');\n for (const keyring of keyrings) {\n if (keyring.type === (KeyringTypes.hd as string)) {\n // Only HD keyrings have an entropy source/SRP.\n const entropySource = keyring.metadata.id;\n\n // This will automatically \"associate\" all multichain accounts for that wallet\n // (based on the accounts owned by each account providers).\n const wallet = new MultichainAccountWallet({\n entropySource,\n providers: this.#providers,\n });\n this.#wallets.set(wallet.id, wallet);\n\n // Reverse mapping between account ID and their multichain wallet/account:\n for (const group of wallet.getMultichainAccountGroups()) {\n for (const account of group.getAccounts()) {\n this.#accountIdToContext.set(account.id, {\n wallet,\n group,\n });\n }\n }\n }\n }\n }\n\n #handleOnAccountAdded(account: KeyringAccount): void {\n // We completely omit non-BIP-44 accounts!\n if (!isBip44Account(account)) {\n return;\n }\n\n let sync = true;\n\n let wallet = this.#wallets.get(\n toMultichainAccountWalletId(account.options.entropy.id),\n );\n if (!wallet) {\n // That's a new wallet.\n wallet = new MultichainAccountWallet({\n entropySource: account.options.entropy.id,\n providers: this.#providers,\n });\n this.#wallets.set(wallet.id, wallet);\n\n // If that's a new wallet wallet. There's nothing to \"force-sync\".\n sync = false;\n }\n\n let group = wallet.getMultichainAccountGroup(\n account.options.entropy.groupIndex,\n );\n if (!group) {\n // This new account is a new multichain account, let the wallet know\n // it has to re-sync with its providers.\n if (sync) {\n wallet.sync();\n }\n\n group = wallet.getMultichainAccountGroup(\n account.options.entropy.groupIndex,\n );\n\n // If that's a new multichain account. There's nothing to \"force-sync\".\n sync = false;\n }\n\n // We have to check against `undefined` in case `getMultichainAccount` is\n // not able to find this multichain account (which should not be possible...)\n if (group) {\n if (sync) {\n group.sync();\n }\n\n // Same here, this account should have been already grouped in that\n // multichain account.\n this.#accountIdToContext.set(account.id, {\n wallet,\n group,\n });\n }\n }\n\n #handleOnAccountRemoved(id: KeyringAccount['id']): void {\n // Force sync of the appropriate wallet if an account got removed.\n const found = this.#accountIdToContext.get(id);\n if (found) {\n const { wallet } = found;\n\n wallet.sync();\n }\n\n // Safe to call delete even if the `id` was not referencing a BIP-44 account.\n this.#accountIdToContext.delete(id);\n }\n\n #getWallet(\n entropySource: EntropySourceId,\n ): MultichainAccountWallet<Bip44Account<KeyringAccount>> {\n const wallet = this.#wallets.get(\n toMultichainAccountWalletId(entropySource),\n );\n\n if (!wallet) {\n throw new Error('Unknown wallet, no wallet matching this entropy source');\n }\n\n return wallet;\n }\n\n /**\n * Gets the account's context which contains its multichain wallet and\n * multichain account group references.\n *\n * @param id - Account ID.\n * @returns The account context if any, undefined otherwise.\n */\n getAccountContext(\n id: KeyringAccount['id'],\n ): AccountContext<Bip44Account<KeyringAccount>> | undefined {\n return this.#accountIdToContext.get(id);\n }\n\n /**\n * Gets a reference to the multichain account wallet matching this entropy source.\n *\n * @param options - Options.\n * @param options.entropySource - The entropy source of the multichain account.\n * @throws If none multichain account match this entropy.\n * @returns A reference to the multichain account wallet.\n */\n getMultichainAccountWallet({\n entropySource,\n }: {\n entropySource: EntropySourceId;\n }): MultichainAccountWallet<Bip44Account<KeyringAccount>> {\n return this.#getWallet(entropySource);\n }\n\n /**\n * Gets an array of all multichain account wallets.\n *\n * @returns An array of all multichain account wallets.\n */\n getMultichainAccountWallets(): MultichainAccountWallet<\n Bip44Account<KeyringAccount>\n >[] {\n return Array.from(this.#wallets.values());\n }\n\n /**\n * Gets a reference to the multichain account group matching this entropy source\n * and a group index.\n *\n * @param options - Options.\n * @param options.entropySource - The entropy source of the multichain account.\n * @param options.groupIndex - The group index of the multichain account.\n * @throws If none multichain account match this entropy source and group index.\n * @returns A reference to the multichain account.\n */\n getMultichainAccountGroup({\n entropySource,\n groupIndex,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }): MultichainAccountGroup<Bip44Account<KeyringAccount>> {\n const multichainAccount =\n this.#getWallet(entropySource).getMultichainAccountGroup(groupIndex);\n\n if (!multichainAccount) {\n throw new Error(`No multichain account for index: ${groupIndex}`);\n }\n\n return multichainAccount;\n }\n\n /**\n * Gets all multichain account groups for a given entropy source.\n *\n * @param options - Options.\n * @param options.entropySource - The entropy source to query.\n * @throws If no multichain accounts match this entropy source.\n * @returns A list of all multichain accounts.\n */\n getMultichainAccountGroups({\n entropySource,\n }: {\n entropySource: EntropySourceId;\n }): MultichainAccountGroup<Bip44Account<KeyringAccount>>[] {\n return this.#getWallet(entropySource).getMultichainAccountGroups();\n }\n\n /**\n * Creates the next multichain account group.\n *\n * @param options - Options.\n * @param options.entropySource - The wallet's entropy source.\n * @returns The next multichain account group.\n */\n async createNextMultichainAccountGroup({\n entropySource,\n }: {\n entropySource: EntropySourceId;\n }): Promise<MultichainAccountGroup<Bip44Account<KeyringAccount>>> {\n return await this.#getWallet(\n entropySource,\n ).createNextMultichainAccountGroup();\n }\n\n /**\n * Creates a multichain account group.\n *\n * @param options - Options.\n * @param options.groupIndex - The group index to use.\n * @param options.entropySource - The wallet's entropy source.\n * @returns The multichain account group for this group index.\n */\n async createMultichainAccountGroup({\n groupIndex,\n entropySource,\n }: {\n groupIndex: number;\n entropySource: EntropySourceId;\n }): Promise<MultichainAccountGroup<Bip44Account<KeyringAccount>>> {\n return await this.#getWallet(entropySource).createMultichainAccountGroup(\n groupIndex,\n );\n }\n\n /**\n * Set basic functionality state and trigger alignment if enabled.\n * When basic functionality is disabled, snap-based providers are disabled.\n * When enabled, all snap providers are enabled and wallet alignment is triggered.\n * EVM providers are never disabled as they're required for basic wallet functionality.\n *\n * @param enabled - Whether basic functionality is enabled.\n */\n async setBasicFunctionality(enabled: boolean): Promise<void> {\n // Loop through providers and enable/disable only wrapped ones when basic functionality changes\n for (const provider of this.#providers) {\n if (isAccountProviderWrapper(provider)) {\n provider.setEnabled(enabled);\n }\n // Regular providers (like EVM) are never disabled for basic functionality\n }\n\n // Trigger alignment only when basic functionality is enabled\n if (enabled) {\n await this.alignWallets();\n }\n }\n\n /**\n * Gets whether wallet alignment is currently in progress.\n *\n * @returns True if any wallet alignment is in progress, false otherwise.\n */\n getIsAlignmentInProgress(): boolean {\n return Array.from(this.#wallets.values()).some((wallet) =>\n wallet.getIsAlignmentInProgress(),\n );\n }\n\n /**\n * Align all multichain account wallets.\n */\n async alignWallets(): Promise<void> {\n const wallets = this.getMultichainAccountWallets();\n await Promise.all(wallets.map((w) => w.alignGroups()));\n }\n\n /**\n * Align a specific multichain account wallet.\n *\n * @param entropySource - The entropy source of the multichain account wallet.\n */\n async alignWallet(entropySource: EntropySourceId): Promise<void> {\n const wallet = this.getMultichainAccountWallet({ entropySource });\n await wallet.alignGroups();\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"MultichainAccountService.mjs","sourceRoot":"","sources":["../src/MultichainAccountService.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n isBip44Account,\n toMultichainAccountWalletId,\n} from '@metamask/account-api';\nimport type {\n MultichainAccountWalletId,\n Bip44Account,\n AccountProvider,\n} from '@metamask/account-api';\nimport { BaseController } from '@metamask/base-controller';\nimport type { EntropySourceId, KeyringAccount } from '@metamask/keyring-api';\nimport { KeyringTypes } from '@metamask/keyring-controller';\n\nimport type { MultichainAccountGroup } from './MultichainAccountGroup';\nimport type { MultichainAccountWalletTransientState } from './MultichainAccountWallet';\nimport { MultichainAccountWallet } from './MultichainAccountWallet';\nimport {\n AccountProviderWrapper,\n isAccountProviderWrapper,\n} from './providers/AccountProviderWrapper';\nimport { EvmAccountProvider } from './providers/EvmAccountProvider';\nimport { SolAccountProvider } from './providers/SolAccountProvider';\nimport type { TransientStateMetadata } from './transient-state';\nimport type {\n MultichainAccountServiceMessenger,\n MultichainAccountServiceTransientState,\n} from './types';\n\nexport const serviceName = 'MultichainAccountService';\n\nconst serviceMetadata: TransientStateMetadata<MultichainAccountServiceTransientState> =\n {\n accountWalletsTransientState: {\n // Transient states are never persisted.\n persist: false,\n anonymous: false,\n },\n };\n\n/**\n * The options that {@link MultichainAccountService} takes.\n */\ntype MultichainAccountServiceOptions = {\n messenger: MultichainAccountServiceMessenger;\n providers?: AccountProvider<Bip44Account<KeyringAccount>>[];\n};\n\n/** Reverse mapping object used to map account IDs and their wallet/multichain account. */\ntype AccountContext<Account extends Bip44Account<KeyringAccount>> = {\n wallet: MultichainAccountWallet<Account>;\n group: MultichainAccountGroup<Account>;\n};\n\n/**\n * Service to expose multichain accounts capabilities.\n */\nexport class MultichainAccountService extends BaseController<\n typeof serviceName,\n MultichainAccountServiceTransientState,\n MultichainAccountServiceMessenger\n> {\n readonly #messenger: MultichainAccountServiceMessenger;\n\n readonly #providers: AccountProvider<Bip44Account<KeyringAccount>>[];\n\n readonly #wallets: Map<\n MultichainAccountWalletId,\n MultichainAccountWallet<Bip44Account<KeyringAccount>>\n >;\n\n readonly #accountIdToContext: Map<\n Bip44Account<KeyringAccount>['id'],\n AccountContext<Bip44Account<KeyringAccount>>\n >;\n\n /**\n * The name of the service.\n */\n name: typeof serviceName = serviceName;\n\n /**\n * Constructs a new MultichainAccountService.\n *\n * @param options - The options.\n * @param options.messenger - The messenger suited to this\n * MultichainAccountService.\n * @param options.providers - Optional list of account\n * providers.\n */\n constructor({ messenger, providers = [] }: MultichainAccountServiceOptions) {\n super({\n messenger,\n name: serviceName,\n metadata: serviceMetadata,\n state: {\n accountWalletsTransientState: {},\n },\n });\n\n this.#messenger = messenger;\n this.#wallets = new Map();\n this.#accountIdToContext = new Map();\n\n // TODO: Rely on keyring capabilities once the keyring API is used by all keyrings.\n this.#providers = [\n new EvmAccountProvider(this.#messenger),\n new AccountProviderWrapper(\n this.#messenger,\n new SolAccountProvider(this.#messenger),\n ),\n // Custom account providers that can be provided by the MetaMask client.\n ...providers,\n ];\n\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:getMultichainAccountGroup',\n (...args) => this.getMultichainAccountGroup(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:getMultichainAccountGroups',\n (...args) => this.getMultichainAccountGroups(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:getMultichainAccountWallet',\n (...args) => this.getMultichainAccountWallet(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:getMultichainAccountWallets',\n (...args) => this.getMultichainAccountWallets(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:createNextMultichainAccountGroup',\n (...args) => this.createNextMultichainAccountGroup(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:createMultichainAccountGroup',\n (...args) => this.createMultichainAccountGroup(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:setBasicFunctionality',\n (...args) => this.setBasicFunctionality(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:alignWallets',\n (...args) => this.alignWallets(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:alignWallet',\n (...args) => this.alignWallet(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:getIsAlignmentInProgress',\n () => this.getIsAlignmentInProgress(),\n );\n\n this.#messenger.subscribe('AccountsController:accountAdded', (account) =>\n this.#handleOnAccountAdded(account),\n );\n this.#messenger.subscribe('AccountsController:accountRemoved', (id) =>\n this.#handleOnAccountRemoved(id),\n );\n }\n\n /**\n * Initialize the service and constructs the internal reprensentation of\n * multichain accounts and wallets.\n */\n init(): void {\n this.#wallets.clear();\n this.#accountIdToContext.clear();\n\n // Create initial wallets.\n const { keyrings } = this.#messenger.call('KeyringController:getState');\n for (const keyring of keyrings) {\n if (keyring.type === (KeyringTypes.hd as string)) {\n // Only HD keyrings have an entropy source/SRP.\n const entropySource = keyring.metadata.id;\n\n // This will automatically \"associate\" all multichain accounts for that wallet\n // (based on the accounts owned by each account providers).\n const walletId = toMultichainAccountWalletId(entropySource);\n const wallet = new MultichainAccountWallet({\n entropySource,\n providers: this.#providers,\n transientState:\n this.#getMultichainAccoultWalletTransientStateProxy(walletId),\n });\n this.#wallets.set(wallet.id, wallet);\n\n // Reverse mapping between account ID and their multichain wallet/account:\n for (const group of wallet.getMultichainAccountGroups()) {\n for (const account of group.getAccounts()) {\n this.#accountIdToContext.set(account.id, {\n wallet,\n group,\n });\n }\n }\n }\n }\n }\n\n #getMultichainAccoultWalletTransientStateProxy(\n walletId: MultichainAccountWalletId,\n ): MultichainAccountWalletTransientState {\n // eslint-disable-next-line consistent-this, @typescript-eslint/no-this-alias\n const service = this;\n\n const getTransientState = <Return>(\n state: MultichainAccountServiceTransientState,\n then: (transientState: MultichainAccountWalletTransientState) => Return,\n ) => {\n return then(state.accountWalletsTransientState[walletId]);\n };\n\n const setTransientState = (\n state: MultichainAccountServiceTransientState,\n then: (transientState: MultichainAccountWalletTransientState) => void,\n ) => {\n then(state.accountWalletsTransientState[walletId]);\n };\n\n // Create initial transient state for this wallet if it does not exists yet.\n if (!service.state.accountWalletsTransientState[walletId]) {\n this.update((state) => {\n state.accountWalletsTransientState[walletId] = {\n isAlignmentInProgress: false,\n };\n });\n }\n\n return {\n get isAlignmentInProgress(): boolean {\n return getTransientState(\n service.state,\n (transientState) => transientState.isAlignmentInProgress,\n );\n },\n set isAlignmentInProgress(inProgress: boolean) {\n service.update((state) => {\n setTransientState(\n state,\n (transientState) =>\n (transientState.isAlignmentInProgress = inProgress),\n );\n });\n },\n };\n }\n\n #handleOnAccountAdded(account: KeyringAccount): void {\n // We completely omit non-BIP-44 accounts!\n if (!isBip44Account(account)) {\n return;\n }\n\n let sync = true;\n\n const walletId = toMultichainAccountWalletId(account.options.entropy.id);\n let wallet = this.#wallets.get(\n toMultichainAccountWalletId(account.options.entropy.id),\n );\n if (!wallet) {\n // That's a new wallet.\n wallet = new MultichainAccountWallet({\n entropySource: account.options.entropy.id,\n providers: this.#providers,\n transientState:\n this.#getMultichainAccoultWalletTransientStateProxy(walletId),\n });\n this.#wallets.set(wallet.id, wallet);\n\n // If that's a new wallet wallet. There's nothing to \"force-sync\".\n sync = false;\n }\n\n let group = wallet.getMultichainAccountGroup(\n account.options.entropy.groupIndex,\n );\n if (!group) {\n // This new account is a new multichain account, let the wallet know\n // it has to re-sync with its providers.\n if (sync) {\n wallet.sync();\n }\n\n group = wallet.getMultichainAccountGroup(\n account.options.entropy.groupIndex,\n );\n\n // If that's a new multichain account. There's nothing to \"force-sync\".\n sync = false;\n }\n\n // We have to check against `undefined` in case `getMultichainAccount` is\n // not able to find this multichain account (which should not be possible...)\n if (group) {\n if (sync) {\n group.sync();\n }\n\n // Same here, this account should have been already grouped in that\n // multichain account.\n this.#accountIdToContext.set(account.id, {\n wallet,\n group,\n });\n }\n }\n\n #handleOnAccountRemoved(id: KeyringAccount['id']): void {\n // Force sync of the appropriate wallet if an account got removed.\n const found = this.#accountIdToContext.get(id);\n if (found) {\n const { wallet } = found;\n\n wallet.sync();\n }\n\n // Safe to call delete even if the `id` was not referencing a BIP-44 account.\n this.#accountIdToContext.delete(id);\n }\n\n #getWallet(\n entropySource: EntropySourceId,\n ): MultichainAccountWallet<Bip44Account<KeyringAccount>> {\n const wallet = this.#wallets.get(\n toMultichainAccountWalletId(entropySource),\n );\n\n if (!wallet) {\n throw new Error('Unknown wallet, no wallet matching this entropy source');\n }\n\n return wallet;\n }\n\n /**\n * Gets the account's context which contains its multichain wallet and\n * multichain account group references.\n *\n * @param id - Account ID.\n * @returns The account context if any, undefined otherwise.\n */\n getAccountContext(\n id: KeyringAccount['id'],\n ): AccountContext<Bip44Account<KeyringAccount>> | undefined {\n return this.#accountIdToContext.get(id);\n }\n\n /**\n * Gets a reference to the multichain account wallet matching this entropy source.\n *\n * @param options - Options.\n * @param options.entropySource - The entropy source of the multichain account.\n * @throws If none multichain account match this entropy.\n * @returns A reference to the multichain account wallet.\n */\n getMultichainAccountWallet({\n entropySource,\n }: {\n entropySource: EntropySourceId;\n }): MultichainAccountWallet<Bip44Account<KeyringAccount>> {\n return this.#getWallet(entropySource);\n }\n\n /**\n * Gets an array of all multichain account wallets.\n *\n * @returns An array of all multichain account wallets.\n */\n getMultichainAccountWallets(): MultichainAccountWallet<\n Bip44Account<KeyringAccount>\n >[] {\n return Array.from(this.#wallets.values());\n }\n\n /**\n * Gets a reference to the multichain account group matching this entropy source\n * and a group index.\n *\n * @param options - Options.\n * @param options.entropySource - The entropy source of the multichain account.\n * @param options.groupIndex - The group index of the multichain account.\n * @throws If none multichain account match this entropy source and group index.\n * @returns A reference to the multichain account.\n */\n getMultichainAccountGroup({\n entropySource,\n groupIndex,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }): MultichainAccountGroup<Bip44Account<KeyringAccount>> {\n const multichainAccount =\n this.#getWallet(entropySource).getMultichainAccountGroup(groupIndex);\n\n if (!multichainAccount) {\n throw new Error(`No multichain account for index: ${groupIndex}`);\n }\n\n return multichainAccount;\n }\n\n /**\n * Gets all multichain account groups for a given entropy source.\n *\n * @param options - Options.\n * @param options.entropySource - The entropy source to query.\n * @throws If no multichain accounts match this entropy source.\n * @returns A list of all multichain accounts.\n */\n getMultichainAccountGroups({\n entropySource,\n }: {\n entropySource: EntropySourceId;\n }): MultichainAccountGroup<Bip44Account<KeyringAccount>>[] {\n return this.#getWallet(entropySource).getMultichainAccountGroups();\n }\n\n /**\n * Creates the next multichain account group.\n *\n * @param options - Options.\n * @param options.entropySource - The wallet's entropy source.\n * @returns The next multichain account group.\n */\n async createNextMultichainAccountGroup({\n entropySource,\n }: {\n entropySource: EntropySourceId;\n }): Promise<MultichainAccountGroup<Bip44Account<KeyringAccount>>> {\n return await this.#getWallet(\n entropySource,\n ).createNextMultichainAccountGroup();\n }\n\n /**\n * Creates a multichain account group.\n *\n * @param options - Options.\n * @param options.groupIndex - The group index to use.\n * @param options.entropySource - The wallet's entropy source.\n * @returns The multichain account group for this group index.\n */\n async createMultichainAccountGroup({\n groupIndex,\n entropySource,\n }: {\n groupIndex: number;\n entropySource: EntropySourceId;\n }): Promise<MultichainAccountGroup<Bip44Account<KeyringAccount>>> {\n return await this.#getWallet(entropySource).createMultichainAccountGroup(\n groupIndex,\n );\n }\n\n /**\n * Set basic functionality state and trigger alignment if enabled.\n * When basic functionality is disabled, snap-based providers are disabled.\n * When enabled, all snap providers are enabled and wallet alignment is triggered.\n * EVM providers are never disabled as they're required for basic wallet functionality.\n *\n * @param enabled - Whether basic functionality is enabled.\n */\n async setBasicFunctionality(enabled: boolean): Promise<void> {\n // Loop through providers and enable/disable only wrapped ones when basic functionality changes\n for (const provider of this.#providers) {\n if (isAccountProviderWrapper(provider)) {\n provider.setEnabled(enabled);\n }\n // Regular providers (like EVM) are never disabled for basic functionality\n }\n\n // Trigger alignment only when basic functionality is enabled\n if (enabled) {\n await this.alignWallets();\n }\n }\n\n /**\n * Gets whether wallet alignment is currently in progress.\n *\n * @returns True if any wallet alignment is in progress, false otherwise.\n */\n getIsAlignmentInProgress(): boolean {\n return Array.from(this.#wallets.values()).some((wallet) =>\n wallet.getIsAlignmentInProgress(),\n );\n }\n\n /**\n * Align all multichain account wallets.\n */\n async alignWallets(): Promise<void> {\n const wallets = this.getMultichainAccountWallets();\n await Promise.all(wallets.map((w) => w.alignGroups()));\n }\n\n /**\n * Align a specific multichain account wallet.\n *\n * @param entropySource - The entropy source of the multichain account wallet.\n */\n async alignWallet(entropySource: EntropySourceId): Promise<void> {\n const wallet = this.getMultichainAccountWallet({ entropySource });\n await wallet.alignGroups();\n }\n}\n"]}
|
|
@@ -10,7 +10,7 @@ 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 _MultichainAccountWallet_id, _MultichainAccountWallet_providers, _MultichainAccountWallet_entropySource, _MultichainAccountWallet_accountGroups,
|
|
13
|
+
var _MultichainAccountWallet_id, _MultichainAccountWallet_providers, _MultichainAccountWallet_entropySource, _MultichainAccountWallet_accountGroups, _MultichainAccountWallet_transientState;
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.MultichainAccountWallet = void 0;
|
|
16
16
|
const account_api_1 = require("@metamask/account-api");
|
|
@@ -22,16 +22,17 @@ const MultichainAccountGroup_1 = require("./MultichainAccountGroup.cjs");
|
|
|
22
22
|
* group index).
|
|
23
23
|
*/
|
|
24
24
|
class MultichainAccountWallet {
|
|
25
|
-
constructor({ providers, entropySource, }) {
|
|
25
|
+
constructor({ providers, entropySource, transientState, }) {
|
|
26
26
|
_MultichainAccountWallet_id.set(this, void 0);
|
|
27
27
|
_MultichainAccountWallet_providers.set(this, void 0);
|
|
28
28
|
_MultichainAccountWallet_entropySource.set(this, void 0);
|
|
29
29
|
_MultichainAccountWallet_accountGroups.set(this, void 0);
|
|
30
|
-
|
|
30
|
+
_MultichainAccountWallet_transientState.set(this, void 0);
|
|
31
31
|
__classPrivateFieldSet(this, _MultichainAccountWallet_id, (0, account_api_1.toMultichainAccountWalletId)(entropySource), "f");
|
|
32
32
|
__classPrivateFieldSet(this, _MultichainAccountWallet_providers, providers, "f");
|
|
33
33
|
__classPrivateFieldSet(this, _MultichainAccountWallet_entropySource, entropySource, "f");
|
|
34
34
|
__classPrivateFieldSet(this, _MultichainAccountWallet_accountGroups, new Map(), "f");
|
|
35
|
+
__classPrivateFieldSet(this, _MultichainAccountWallet_transientState, transientState, "f");
|
|
35
36
|
// Initial synchronization.
|
|
36
37
|
this.sync();
|
|
37
38
|
}
|
|
@@ -247,22 +248,22 @@ class MultichainAccountWallet {
|
|
|
247
248
|
* @returns True if alignment is in progress, false otherwise.
|
|
248
249
|
*/
|
|
249
250
|
getIsAlignmentInProgress() {
|
|
250
|
-
return __classPrivateFieldGet(this,
|
|
251
|
+
return __classPrivateFieldGet(this, _MultichainAccountWallet_transientState, "f").isAlignmentInProgress;
|
|
251
252
|
}
|
|
252
253
|
/**
|
|
253
254
|
* Align all multichain account groups.
|
|
254
255
|
*/
|
|
255
256
|
async alignGroups() {
|
|
256
|
-
if (__classPrivateFieldGet(this,
|
|
257
|
+
if (__classPrivateFieldGet(this, _MultichainAccountWallet_transientState, "f").isAlignmentInProgress) {
|
|
257
258
|
return; // Prevent concurrent alignments
|
|
258
259
|
}
|
|
259
|
-
|
|
260
|
+
__classPrivateFieldGet(this, _MultichainAccountWallet_transientState, "f").isAlignmentInProgress = true;
|
|
260
261
|
try {
|
|
261
262
|
const groups = this.getMultichainAccountGroups();
|
|
262
263
|
await Promise.all(groups.map((g) => g.align()));
|
|
263
264
|
}
|
|
264
265
|
finally {
|
|
265
|
-
|
|
266
|
+
__classPrivateFieldGet(this, _MultichainAccountWallet_transientState, "f").isAlignmentInProgress = false;
|
|
266
267
|
}
|
|
267
268
|
}
|
|
268
269
|
/**
|
|
@@ -271,10 +272,10 @@ class MultichainAccountWallet {
|
|
|
271
272
|
* @param groupIndex - The group index to align.
|
|
272
273
|
*/
|
|
273
274
|
async alignGroup(groupIndex) {
|
|
274
|
-
if (__classPrivateFieldGet(this,
|
|
275
|
+
if (__classPrivateFieldGet(this, _MultichainAccountWallet_transientState, "f").isAlignmentInProgress) {
|
|
275
276
|
return; // Prevent concurrent alignments
|
|
276
277
|
}
|
|
277
|
-
|
|
278
|
+
__classPrivateFieldGet(this, _MultichainAccountWallet_transientState, "f").isAlignmentInProgress = true;
|
|
278
279
|
try {
|
|
279
280
|
const group = this.getMultichainAccountGroup(groupIndex);
|
|
280
281
|
if (group) {
|
|
@@ -282,10 +283,10 @@ class MultichainAccountWallet {
|
|
|
282
283
|
}
|
|
283
284
|
}
|
|
284
285
|
finally {
|
|
285
|
-
|
|
286
|
+
__classPrivateFieldGet(this, _MultichainAccountWallet_transientState, "f").isAlignmentInProgress = false;
|
|
286
287
|
}
|
|
287
288
|
}
|
|
288
289
|
}
|
|
289
290
|
exports.MultichainAccountWallet = MultichainAccountWallet;
|
|
290
|
-
_MultichainAccountWallet_id = new WeakMap(), _MultichainAccountWallet_providers = new WeakMap(), _MultichainAccountWallet_entropySource = new WeakMap(), _MultichainAccountWallet_accountGroups = new WeakMap(),
|
|
291
|
+
_MultichainAccountWallet_id = new WeakMap(), _MultichainAccountWallet_providers = new WeakMap(), _MultichainAccountWallet_entropySource = new WeakMap(), _MultichainAccountWallet_accountGroups = new WeakMap(), _MultichainAccountWallet_transientState = new WeakMap();
|
|
291
292
|
//# sourceMappingURL=MultichainAccountWallet.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MultichainAccountWallet.cjs","sourceRoot":"","sources":["../src/MultichainAccountWallet.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n getGroupIndexFromMultichainAccountGroupId,\n isMultichainAccountGroupId,\n toMultichainAccountWalletId,\n} from '@metamask/account-api';\nimport { toDefaultAccountGroupId } from '@metamask/account-api';\nimport { AccountWalletType } from '@metamask/account-api';\nimport type {\n Bip44Account,\n MultichainAccountWalletId,\n MultichainAccountWallet as MultichainAccountWalletDefinition,\n} from '@metamask/account-api';\nimport type { AccountGroupId } from '@metamask/account-api';\nimport type { AccountProvider } from '@metamask/account-api';\nimport {\n type EntropySourceId,\n type KeyringAccount,\n} from '@metamask/keyring-api';\n\nimport { MultichainAccountGroup } from './MultichainAccountGroup';\n\n/**\n * A multichain account wallet that holds multiple multichain accounts (one multichain account per\n * group index).\n */\nexport class MultichainAccountWallet<\n Account extends Bip44Account<KeyringAccount>,\n> implements MultichainAccountWalletDefinition<Account>\n{\n readonly #id: MultichainAccountWalletId;\n\n readonly #providers: AccountProvider<Account>[];\n\n readonly #entropySource: EntropySourceId;\n\n readonly #accountGroups: Map<number, MultichainAccountGroup<Account>>;\n\n #isAlignmentInProgress: boolean = false;\n\n constructor({\n providers,\n entropySource,\n }: {\n providers: AccountProvider<Account>[];\n entropySource: EntropySourceId;\n }) {\n this.#id = toMultichainAccountWalletId(entropySource);\n this.#providers = providers;\n this.#entropySource = entropySource;\n this.#accountGroups = new Map();\n\n // Initial synchronization.\n this.sync();\n }\n\n /**\n * Force wallet synchronization.\n *\n * This can be used if account providers got new accounts that the wallet\n * doesn't know about.\n */\n sync(): void {\n for (const provider of this.#providers) {\n for (const account of provider.getAccounts()) {\n const { entropy } = account.options;\n\n // Filter for this wallet only.\n if (entropy.id !== this.entropySource) {\n continue;\n }\n\n // This multichain account might exists already.\n let multichainAccount = this.#accountGroups.get(entropy.groupIndex);\n if (!multichainAccount) {\n multichainAccount = new MultichainAccountGroup<Account>({\n groupIndex: entropy.groupIndex,\n wallet: this,\n providers: this.#providers,\n });\n\n // This existing multichain account group might differ from the\n // `createMultichainAccountGroup` behavior. When creating a new\n // group, we expect the providers to all succeed. But here, we're\n // just fetching the account lists from them, so this group might\n // not be \"aligned\" yet (e.g having a missing Solana account).\n //\n // Since \"aligning\" is an async operation, it would have to be run\n // after the first-sync.\n // TODO: Implement align mechanism to create \"missing\" accounts.\n\n this.#accountGroups.set(entropy.groupIndex, multichainAccount);\n }\n }\n }\n\n // Now force-sync all remaining multichain accounts.\n for (const [\n groupIndex,\n multichainAccount,\n ] of this.#accountGroups.entries()) {\n multichainAccount.sync();\n\n // Clean up old multichain accounts.\n if (!multichainAccount.hasAccounts()) {\n this.#accountGroups.delete(groupIndex);\n }\n }\n }\n\n /**\n * Gets the multichain account wallet ID.\n *\n * @returns The multichain account wallet ID.\n */\n get id(): MultichainAccountWalletId {\n return this.#id;\n }\n\n /**\n * Gets the multichain account wallet type, which is always {@link AccountWalletType.Entropy}.\n *\n * @returns The multichain account wallet type.\n */\n get type(): AccountWalletType.Entropy {\n return AccountWalletType.Entropy;\n }\n\n /**\n * Gets the multichain account wallet entropy source.\n *\n * @returns The multichain account wallet entropy source.\n */\n get entropySource(): EntropySourceId {\n return this.#entropySource;\n }\n\n /**\n * Gets multichain account for a given ID.\n * The default group ID will default to the multichain account with index 0.\n *\n * @param id - Account group ID.\n * @returns Account group.\n */\n getAccountGroup(\n id: AccountGroupId,\n ): MultichainAccountGroup<Account> | undefined {\n // We consider the \"default case\" to be mapped to index 0.\n if (id === toDefaultAccountGroupId(this.id)) {\n return this.#accountGroups.get(0);\n }\n\n // If it is not a valid ID, we cannot extract the group index\n // from it, so we fail fast.\n if (!isMultichainAccountGroupId(id)) {\n return undefined;\n }\n\n const groupIndex = getGroupIndexFromMultichainAccountGroupId(id);\n return this.#accountGroups.get(groupIndex);\n }\n\n /**\n * Gets all multichain accounts. Similar to {@link MultichainAccountWallet.getMultichainAccountGroups}.\n *\n * @returns The multichain accounts.\n */\n getAccountGroups(): MultichainAccountGroup<Account>[] {\n return this.getMultichainAccountGroups();\n }\n\n /**\n * Gets multichain account group for a given index.\n *\n * @param groupIndex - Multichain account index.\n * @returns The multichain account associated with the given index.\n */\n getMultichainAccountGroup(\n groupIndex: number,\n ): MultichainAccountGroup<Account> | undefined {\n return this.#accountGroups.get(groupIndex);\n }\n\n /**\n * Gets all multichain account groups.\n *\n * @returns The multichain accounts.\n */\n getMultichainAccountGroups(): MultichainAccountGroup<Account>[] {\n return Array.from(this.#accountGroups.values()); // TODO: Prevent copy here.\n }\n\n /**\n * Gets next group index for this wallet.\n *\n * @returns The next group index of this wallet.\n */\n getNextGroupIndex(): number {\n // We do not check for gaps.\n return (\n Math.max(\n -1, // So it will default to 0 if no groups.\n ...this.#accountGroups.keys(),\n ) + 1\n );\n }\n\n /**\n * Creates a multichain account group for a given group index.\n *\n * @param groupIndex - The group index to use.\n * @throws If any of the account providers fails to create their accounts.\n * @returns The multichain account group for this group index.\n */\n async createMultichainAccountGroup(\n groupIndex: number,\n ): Promise<MultichainAccountGroup<Account>> {\n const nextGroupIndex = this.getNextGroupIndex();\n if (groupIndex > nextGroupIndex) {\n throw new Error(\n `You cannot use a group index that is higher than the next available one: expected <=${nextGroupIndex}, got ${groupIndex}`,\n );\n }\n\n let group = this.getMultichainAccountGroup(groupIndex);\n if (group) {\n // If the group already exists, we just `sync` it and returns the same\n // reference.\n group.sync();\n\n return group;\n }\n\n const results = await Promise.allSettled(\n this.#providers.map((provider) =>\n provider.createAccounts({\n entropySource: this.#entropySource,\n groupIndex,\n }),\n ),\n );\n\n // --------------------------------------------------------------------------------\n // READ THIS CAREFULLY:\n //\n // Since we're not \"fully supporting multichain\" for now, we still rely on single\n // :accountCreated events to sync multichain account groups and wallets. Which means\n // that even if of the provider fails, some accounts will still be created on some\n // other providers and will become \"available\" on the `AccountsController`, like:\n //\n // 1. Creating a multichain account group for index 1\n // 2. EvmAccountProvider.createAccounts returns the EVM account for index 1\n // * AccountsController WILL fire :accountCreated for this account\n // * This account WILL BE \"available\" on the AccountsController state\n // 3. SolAccountProvider.createAccounts fails to create a Solana account for index 1\n // * AccountsController WON't fire :accountCreated for this account\n // * This account WON'T be \"available\" on the Account\n // 4. MultichainAccountService will receive a :accountCreated for the EVM account from\n // step 2 and will create a new multichain account group for index 1, but it won't\n // receive any event for the Solana account of this group. Thus, this group won't be\n // \"aligned\" (missing \"blockchain account\" on this group).\n //\n // --------------------------------------------------------------------------------\n\n // If any of the provider failed to create their accounts, then we consider the\n // multichain account group to have failed too.\n if (results.some((result) => result.status === 'rejected')) {\n // NOTE: Some accounts might still have been created on other account providers. We\n // don't rollback them.\n const error = `Unable to create multichain account group for index: ${groupIndex}`;\n\n let warn = `${error}:`;\n for (const result of results) {\n if (result.status === 'rejected') {\n warn += `\\n- ${result.reason}`;\n }\n }\n console.warn(warn);\n\n throw new Error(error);\n }\n\n // Because of the :accountAdded automatic sync, we might already have created the\n // group, so we first try to get it.\n group = this.getMultichainAccountGroup(groupIndex);\n if (!group) {\n // If for some reason it's still not created, we're creating it explicitly now:\n group = new MultichainAccountGroup({\n wallet: this,\n providers: this.#providers,\n groupIndex,\n });\n }\n\n // Register the account to our internal map.\n this.#accountGroups.set(groupIndex, group); // `group` cannot be undefined here.\n\n return group;\n }\n\n /**\n * Creates the next multichain account group.\n *\n * @throws If any of the account providers fails to create their accounts.\n * @returns The multichain account group for the next group index available.\n */\n async createNextMultichainAccountGroup(): Promise<\n MultichainAccountGroup<Account>\n > {\n return this.createMultichainAccountGroup(this.getNextGroupIndex());\n }\n\n /**\n * Gets whether alignment is currently in progress for this wallet.\n *\n * @returns True if alignment is in progress, false otherwise.\n */\n getIsAlignmentInProgress(): boolean {\n return this.#isAlignmentInProgress;\n }\n\n /**\n * Align all multichain account groups.\n */\n async alignGroups(): Promise<void> {\n if (this.#isAlignmentInProgress) {\n return; // Prevent concurrent alignments\n }\n\n this.#isAlignmentInProgress = true;\n try {\n const groups = this.getMultichainAccountGroups();\n await Promise.all(groups.map((g) => g.align()));\n } finally {\n this.#isAlignmentInProgress = false;\n }\n }\n\n /**\n * Align a specific multichain account group.\n *\n * @param groupIndex - The group index to align.\n */\n async alignGroup(groupIndex: number): Promise<void> {\n if (this.#isAlignmentInProgress) {\n return; // Prevent concurrent alignments\n }\n\n this.#isAlignmentInProgress = true;\n try {\n const group = this.getMultichainAccountGroup(groupIndex);\n if (group) {\n await group.align();\n }\n } finally {\n this.#isAlignmentInProgress = false;\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"MultichainAccountWallet.cjs","sourceRoot":"","sources":["../src/MultichainAccountWallet.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n getGroupIndexFromMultichainAccountGroupId,\n isMultichainAccountGroupId,\n toMultichainAccountWalletId,\n} from '@metamask/account-api';\nimport { toDefaultAccountGroupId } from '@metamask/account-api';\nimport { AccountWalletType } from '@metamask/account-api';\nimport type {\n Bip44Account,\n MultichainAccountWalletId,\n MultichainAccountWallet as MultichainAccountWalletDefinition,\n} from '@metamask/account-api';\nimport type { AccountGroupId } from '@metamask/account-api';\nimport type { AccountProvider } from '@metamask/account-api';\nimport {\n type EntropySourceId,\n type KeyringAccount,\n} from '@metamask/keyring-api';\n\nimport { MultichainAccountGroup } from './MultichainAccountGroup';\n\n/**\n * Transient state for a multichain account wallet.\n *\n * This state WILL NEVER be persisted. It will be shared with the client's UI\n * so the UI can reflect th current state of the wallet (aligning, discovering, etc...)\n */\nexport type MultichainAccountWalletTransientState = {\n /** True when the wallet is being aligned (creating missing accounts on each groups). */\n isAlignmentInProgress: boolean;\n};\n\n/**\n * A multichain account wallet that holds multiple multichain accounts (one multichain account per\n * group index).\n */\nexport class MultichainAccountWallet<\n Account extends Bip44Account<KeyringAccount>,\n> implements MultichainAccountWalletDefinition<Account>\n{\n readonly #id: MultichainAccountWalletId;\n\n readonly #providers: AccountProvider<Account>[];\n\n readonly #entropySource: EntropySourceId;\n\n readonly #accountGroups: Map<number, MultichainAccountGroup<Account>>;\n\n readonly #transientState: MultichainAccountWalletTransientState;\n\n constructor({\n providers,\n entropySource,\n transientState,\n }: {\n providers: AccountProvider<Account>[];\n entropySource: EntropySourceId;\n transientState: MultichainAccountWalletTransientState;\n }) {\n this.#id = toMultichainAccountWalletId(entropySource);\n this.#providers = providers;\n this.#entropySource = entropySource;\n this.#accountGroups = new Map();\n this.#transientState = transientState;\n\n // Initial synchronization.\n this.sync();\n }\n\n /**\n * Force wallet synchronization.\n *\n * This can be used if account providers got new accounts that the wallet\n * doesn't know about.\n */\n sync(): void {\n for (const provider of this.#providers) {\n for (const account of provider.getAccounts()) {\n const { entropy } = account.options;\n\n // Filter for this wallet only.\n if (entropy.id !== this.entropySource) {\n continue;\n }\n\n // This multichain account might exists already.\n let multichainAccount = this.#accountGroups.get(entropy.groupIndex);\n if (!multichainAccount) {\n multichainAccount = new MultichainAccountGroup<Account>({\n groupIndex: entropy.groupIndex,\n wallet: this,\n providers: this.#providers,\n });\n\n // This existing multichain account group might differ from the\n // `createMultichainAccountGroup` behavior. When creating a new\n // group, we expect the providers to all succeed. But here, we're\n // just fetching the account lists from them, so this group might\n // not be \"aligned\" yet (e.g having a missing Solana account).\n //\n // Since \"aligning\" is an async operation, it would have to be run\n // after the first-sync.\n // TODO: Implement align mechanism to create \"missing\" accounts.\n\n this.#accountGroups.set(entropy.groupIndex, multichainAccount);\n }\n }\n }\n\n // Now force-sync all remaining multichain accounts.\n for (const [\n groupIndex,\n multichainAccount,\n ] of this.#accountGroups.entries()) {\n multichainAccount.sync();\n\n // Clean up old multichain accounts.\n if (!multichainAccount.hasAccounts()) {\n this.#accountGroups.delete(groupIndex);\n }\n }\n }\n\n /**\n * Gets the multichain account wallet ID.\n *\n * @returns The multichain account wallet ID.\n */\n get id(): MultichainAccountWalletId {\n return this.#id;\n }\n\n /**\n * Gets the multichain account wallet type, which is always {@link AccountWalletType.Entropy}.\n *\n * @returns The multichain account wallet type.\n */\n get type(): AccountWalletType.Entropy {\n return AccountWalletType.Entropy;\n }\n\n /**\n * Gets the multichain account wallet entropy source.\n *\n * @returns The multichain account wallet entropy source.\n */\n get entropySource(): EntropySourceId {\n return this.#entropySource;\n }\n\n /**\n * Gets multichain account for a given ID.\n * The default group ID will default to the multichain account with index 0.\n *\n * @param id - Account group ID.\n * @returns Account group.\n */\n getAccountGroup(\n id: AccountGroupId,\n ): MultichainAccountGroup<Account> | undefined {\n // We consider the \"default case\" to be mapped to index 0.\n if (id === toDefaultAccountGroupId(this.id)) {\n return this.#accountGroups.get(0);\n }\n\n // If it is not a valid ID, we cannot extract the group index\n // from it, so we fail fast.\n if (!isMultichainAccountGroupId(id)) {\n return undefined;\n }\n\n const groupIndex = getGroupIndexFromMultichainAccountGroupId(id);\n return this.#accountGroups.get(groupIndex);\n }\n\n /**\n * Gets all multichain accounts. Similar to {@link MultichainAccountWallet.getMultichainAccountGroups}.\n *\n * @returns The multichain accounts.\n */\n getAccountGroups(): MultichainAccountGroup<Account>[] {\n return this.getMultichainAccountGroups();\n }\n\n /**\n * Gets multichain account group for a given index.\n *\n * @param groupIndex - Multichain account index.\n * @returns The multichain account associated with the given index.\n */\n getMultichainAccountGroup(\n groupIndex: number,\n ): MultichainAccountGroup<Account> | undefined {\n return this.#accountGroups.get(groupIndex);\n }\n\n /**\n * Gets all multichain account groups.\n *\n * @returns The multichain accounts.\n */\n getMultichainAccountGroups(): MultichainAccountGroup<Account>[] {\n return Array.from(this.#accountGroups.values()); // TODO: Prevent copy here.\n }\n\n /**\n * Gets next group index for this wallet.\n *\n * @returns The next group index of this wallet.\n */\n getNextGroupIndex(): number {\n // We do not check for gaps.\n return (\n Math.max(\n -1, // So it will default to 0 if no groups.\n ...this.#accountGroups.keys(),\n ) + 1\n );\n }\n\n /**\n * Creates a multichain account group for a given group index.\n *\n * @param groupIndex - The group index to use.\n * @throws If any of the account providers fails to create their accounts.\n * @returns The multichain account group for this group index.\n */\n async createMultichainAccountGroup(\n groupIndex: number,\n ): Promise<MultichainAccountGroup<Account>> {\n const nextGroupIndex = this.getNextGroupIndex();\n if (groupIndex > nextGroupIndex) {\n throw new Error(\n `You cannot use a group index that is higher than the next available one: expected <=${nextGroupIndex}, got ${groupIndex}`,\n );\n }\n\n let group = this.getMultichainAccountGroup(groupIndex);\n if (group) {\n // If the group already exists, we just `sync` it and returns the same\n // reference.\n group.sync();\n\n return group;\n }\n\n const results = await Promise.allSettled(\n this.#providers.map((provider) =>\n provider.createAccounts({\n entropySource: this.#entropySource,\n groupIndex,\n }),\n ),\n );\n\n // --------------------------------------------------------------------------------\n // READ THIS CAREFULLY:\n //\n // Since we're not \"fully supporting multichain\" for now, we still rely on single\n // :accountCreated events to sync multichain account groups and wallets. Which means\n // that even if of the provider fails, some accounts will still be created on some\n // other providers and will become \"available\" on the `AccountsController`, like:\n //\n // 1. Creating a multichain account group for index 1\n // 2. EvmAccountProvider.createAccounts returns the EVM account for index 1\n // * AccountsController WILL fire :accountCreated for this account\n // * This account WILL BE \"available\" on the AccountsController state\n // 3. SolAccountProvider.createAccounts fails to create a Solana account for index 1\n // * AccountsController WON't fire :accountCreated for this account\n // * This account WON'T be \"available\" on the Account\n // 4. MultichainAccountService will receive a :accountCreated for the EVM account from\n // step 2 and will create a new multichain account group for index 1, but it won't\n // receive any event for the Solana account of this group. Thus, this group won't be\n // \"aligned\" (missing \"blockchain account\" on this group).\n //\n // --------------------------------------------------------------------------------\n\n // If any of the provider failed to create their accounts, then we consider the\n // multichain account group to have failed too.\n if (results.some((result) => result.status === 'rejected')) {\n // NOTE: Some accounts might still have been created on other account providers. We\n // don't rollback them.\n const error = `Unable to create multichain account group for index: ${groupIndex}`;\n\n let warn = `${error}:`;\n for (const result of results) {\n if (result.status === 'rejected') {\n warn += `\\n- ${result.reason}`;\n }\n }\n console.warn(warn);\n\n throw new Error(error);\n }\n\n // Because of the :accountAdded automatic sync, we might already have created the\n // group, so we first try to get it.\n group = this.getMultichainAccountGroup(groupIndex);\n if (!group) {\n // If for some reason it's still not created, we're creating it explicitly now:\n group = new MultichainAccountGroup({\n wallet: this,\n providers: this.#providers,\n groupIndex,\n });\n }\n\n // Register the account to our internal map.\n this.#accountGroups.set(groupIndex, group); // `group` cannot be undefined here.\n\n return group;\n }\n\n /**\n * Creates the next multichain account group.\n *\n * @throws If any of the account providers fails to create their accounts.\n * @returns The multichain account group for the next group index available.\n */\n async createNextMultichainAccountGroup(): Promise<\n MultichainAccountGroup<Account>\n > {\n return this.createMultichainAccountGroup(this.getNextGroupIndex());\n }\n\n /**\n * Gets whether alignment is currently in progress for this wallet.\n *\n * @returns True if alignment is in progress, false otherwise.\n */\n getIsAlignmentInProgress(): boolean {\n return this.#transientState.isAlignmentInProgress;\n }\n\n /**\n * Align all multichain account groups.\n */\n async alignGroups(): Promise<void> {\n if (this.#transientState.isAlignmentInProgress) {\n return; // Prevent concurrent alignments\n }\n\n this.#transientState.isAlignmentInProgress = true;\n try {\n const groups = this.getMultichainAccountGroups();\n await Promise.all(groups.map((g) => g.align()));\n } finally {\n this.#transientState.isAlignmentInProgress = false;\n }\n }\n\n /**\n * Align a specific multichain account group.\n *\n * @param groupIndex - The group index to align.\n */\n async alignGroup(groupIndex: number): Promise<void> {\n if (this.#transientState.isAlignmentInProgress) {\n return; // Prevent concurrent alignments\n }\n\n this.#transientState.isAlignmentInProgress = true;\n try {\n const group = this.getMultichainAccountGroup(groupIndex);\n if (group) {\n await group.align();\n }\n } finally {\n this.#transientState.isAlignmentInProgress = false;\n }\n }\n}\n"]}
|
|
@@ -4,15 +4,26 @@ import type { AccountGroupId } from "@metamask/account-api";
|
|
|
4
4
|
import type { AccountProvider } from "@metamask/account-api";
|
|
5
5
|
import { type EntropySourceId, type KeyringAccount } from "@metamask/keyring-api";
|
|
6
6
|
import { MultichainAccountGroup } from "./MultichainAccountGroup.cjs";
|
|
7
|
+
/**
|
|
8
|
+
* Transient state for a multichain account wallet.
|
|
9
|
+
*
|
|
10
|
+
* This state WILL NEVER be persisted. It will be shared with the client's UI
|
|
11
|
+
* so the UI can reflect th current state of the wallet (aligning, discovering, etc...)
|
|
12
|
+
*/
|
|
13
|
+
export type MultichainAccountWalletTransientState = {
|
|
14
|
+
/** True when the wallet is being aligned (creating missing accounts on each groups). */
|
|
15
|
+
isAlignmentInProgress: boolean;
|
|
16
|
+
};
|
|
7
17
|
/**
|
|
8
18
|
* A multichain account wallet that holds multiple multichain accounts (one multichain account per
|
|
9
19
|
* group index).
|
|
10
20
|
*/
|
|
11
21
|
export declare class MultichainAccountWallet<Account extends Bip44Account<KeyringAccount>> implements MultichainAccountWalletDefinition<Account> {
|
|
12
22
|
#private;
|
|
13
|
-
constructor({ providers, entropySource, }: {
|
|
23
|
+
constructor({ providers, entropySource, transientState, }: {
|
|
14
24
|
providers: AccountProvider<Account>[];
|
|
15
25
|
entropySource: EntropySourceId;
|
|
26
|
+
transientState: MultichainAccountWalletTransientState;
|
|
16
27
|
});
|
|
17
28
|
/**
|
|
18
29
|
* Force wallet synchronization.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MultichainAccountWallet.d.cts","sourceRoot":"","sources":["../src/MultichainAccountWallet.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,iBAAiB,EAAE,8BAA8B;AAC1D,OAAO,KAAK,EACV,YAAY,EACZ,yBAAyB,EACzB,uBAAuB,IAAI,iCAAiC,EAC7D,8BAA8B;AAC/B,OAAO,KAAK,EAAE,cAAc,EAAE,8BAA8B;AAC5D,OAAO,KAAK,EAAE,eAAe,EAAE,8BAA8B;AAC7D,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,cAAc,EACpB,8BAA8B;AAE/B,OAAO,EAAE,sBAAsB,EAAE,qCAAiC;AAElE;;;GAGG;AACH,qBAAa,uBAAuB,CAClC,OAAO,SAAS,YAAY,CAAC,cAAc,CAAC,CAC5C,YAAW,iCAAiC,CAAC,OAAO,CAAC;;gBAYzC,EACV,SAAS,EACT,aAAa,
|
|
1
|
+
{"version":3,"file":"MultichainAccountWallet.d.cts","sourceRoot":"","sources":["../src/MultichainAccountWallet.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,iBAAiB,EAAE,8BAA8B;AAC1D,OAAO,KAAK,EACV,YAAY,EACZ,yBAAyB,EACzB,uBAAuB,IAAI,iCAAiC,EAC7D,8BAA8B;AAC/B,OAAO,KAAK,EAAE,cAAc,EAAE,8BAA8B;AAC5D,OAAO,KAAK,EAAE,eAAe,EAAE,8BAA8B;AAC7D,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,cAAc,EACpB,8BAA8B;AAE/B,OAAO,EAAE,sBAAsB,EAAE,qCAAiC;AAElE;;;;;GAKG;AACH,MAAM,MAAM,qCAAqC,GAAG;IAClD,wFAAwF;IACxF,qBAAqB,EAAE,OAAO,CAAC;CAChC,CAAC;AAEF;;;GAGG;AACH,qBAAa,uBAAuB,CAClC,OAAO,SAAS,YAAY,CAAC,cAAc,CAAC,CAC5C,YAAW,iCAAiC,CAAC,OAAO,CAAC;;gBAYzC,EACV,SAAS,EACT,aAAa,EACb,cAAc,GACf,EAAE;QACD,SAAS,EAAE,eAAe,CAAC,OAAO,CAAC,EAAE,CAAC;QACtC,aAAa,EAAE,eAAe,CAAC;QAC/B,cAAc,EAAE,qCAAqC,CAAC;KACvD;IAWD;;;;;OAKG;IACH,IAAI,IAAI,IAAI;IAgDZ;;;;OAIG;IACH,IAAI,EAAE,IAAI,yBAAyB,CAElC;IAED;;;;OAIG;IACH,IAAI,IAAI,IAAI,iBAAiB,CAAC,OAAO,CAEpC;IAED;;;;OAIG;IACH,IAAI,aAAa,IAAI,eAAe,CAEnC;IAED;;;;;;OAMG;IACH,eAAe,CACb,EAAE,EAAE,cAAc,GACjB,sBAAsB,CAAC,OAAO,CAAC,GAAG,SAAS;IAgB9C;;;;OAIG;IACH,gBAAgB,IAAI,sBAAsB,CAAC,OAAO,CAAC,EAAE;IAIrD;;;;;OAKG;IACH,yBAAyB,CACvB,UAAU,EAAE,MAAM,GACjB,sBAAsB,CAAC,OAAO,CAAC,GAAG,SAAS;IAI9C;;;;OAIG;IACH,0BAA0B,IAAI,sBAAsB,CAAC,OAAO,CAAC,EAAE;IAI/D;;;;OAIG;IACH,iBAAiB,IAAI,MAAM;IAU3B;;;;;;OAMG;IACG,4BAA4B,CAChC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC;IAoF3C;;;;;OAKG;IACG,gCAAgC,IAAI,OAAO,CAC/C,sBAAsB,CAAC,OAAO,CAAC,CAChC;IAID;;;;OAIG;IACH,wBAAwB,IAAI,OAAO;IAInC;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAclC;;;;OAIG;IACG,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAepD"}
|
|
@@ -4,15 +4,26 @@ import type { AccountGroupId } from "@metamask/account-api";
|
|
|
4
4
|
import type { AccountProvider } from "@metamask/account-api";
|
|
5
5
|
import { type EntropySourceId, type KeyringAccount } from "@metamask/keyring-api";
|
|
6
6
|
import { MultichainAccountGroup } from "./MultichainAccountGroup.mjs";
|
|
7
|
+
/**
|
|
8
|
+
* Transient state for a multichain account wallet.
|
|
9
|
+
*
|
|
10
|
+
* This state WILL NEVER be persisted. It will be shared with the client's UI
|
|
11
|
+
* so the UI can reflect th current state of the wallet (aligning, discovering, etc...)
|
|
12
|
+
*/
|
|
13
|
+
export type MultichainAccountWalletTransientState = {
|
|
14
|
+
/** True when the wallet is being aligned (creating missing accounts on each groups). */
|
|
15
|
+
isAlignmentInProgress: boolean;
|
|
16
|
+
};
|
|
7
17
|
/**
|
|
8
18
|
* A multichain account wallet that holds multiple multichain accounts (one multichain account per
|
|
9
19
|
* group index).
|
|
10
20
|
*/
|
|
11
21
|
export declare class MultichainAccountWallet<Account extends Bip44Account<KeyringAccount>> implements MultichainAccountWalletDefinition<Account> {
|
|
12
22
|
#private;
|
|
13
|
-
constructor({ providers, entropySource, }: {
|
|
23
|
+
constructor({ providers, entropySource, transientState, }: {
|
|
14
24
|
providers: AccountProvider<Account>[];
|
|
15
25
|
entropySource: EntropySourceId;
|
|
26
|
+
transientState: MultichainAccountWalletTransientState;
|
|
16
27
|
});
|
|
17
28
|
/**
|
|
18
29
|
* Force wallet synchronization.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MultichainAccountWallet.d.mts","sourceRoot":"","sources":["../src/MultichainAccountWallet.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,iBAAiB,EAAE,8BAA8B;AAC1D,OAAO,KAAK,EACV,YAAY,EACZ,yBAAyB,EACzB,uBAAuB,IAAI,iCAAiC,EAC7D,8BAA8B;AAC/B,OAAO,KAAK,EAAE,cAAc,EAAE,8BAA8B;AAC5D,OAAO,KAAK,EAAE,eAAe,EAAE,8BAA8B;AAC7D,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,cAAc,EACpB,8BAA8B;AAE/B,OAAO,EAAE,sBAAsB,EAAE,qCAAiC;AAElE;;;GAGG;AACH,qBAAa,uBAAuB,CAClC,OAAO,SAAS,YAAY,CAAC,cAAc,CAAC,CAC5C,YAAW,iCAAiC,CAAC,OAAO,CAAC;;gBAYzC,EACV,SAAS,EACT,aAAa,
|
|
1
|
+
{"version":3,"file":"MultichainAccountWallet.d.mts","sourceRoot":"","sources":["../src/MultichainAccountWallet.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,iBAAiB,EAAE,8BAA8B;AAC1D,OAAO,KAAK,EACV,YAAY,EACZ,yBAAyB,EACzB,uBAAuB,IAAI,iCAAiC,EAC7D,8BAA8B;AAC/B,OAAO,KAAK,EAAE,cAAc,EAAE,8BAA8B;AAC5D,OAAO,KAAK,EAAE,eAAe,EAAE,8BAA8B;AAC7D,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,cAAc,EACpB,8BAA8B;AAE/B,OAAO,EAAE,sBAAsB,EAAE,qCAAiC;AAElE;;;;;GAKG;AACH,MAAM,MAAM,qCAAqC,GAAG;IAClD,wFAAwF;IACxF,qBAAqB,EAAE,OAAO,CAAC;CAChC,CAAC;AAEF;;;GAGG;AACH,qBAAa,uBAAuB,CAClC,OAAO,SAAS,YAAY,CAAC,cAAc,CAAC,CAC5C,YAAW,iCAAiC,CAAC,OAAO,CAAC;;gBAYzC,EACV,SAAS,EACT,aAAa,EACb,cAAc,GACf,EAAE;QACD,SAAS,EAAE,eAAe,CAAC,OAAO,CAAC,EAAE,CAAC;QACtC,aAAa,EAAE,eAAe,CAAC;QAC/B,cAAc,EAAE,qCAAqC,CAAC;KACvD;IAWD;;;;;OAKG;IACH,IAAI,IAAI,IAAI;IAgDZ;;;;OAIG;IACH,IAAI,EAAE,IAAI,yBAAyB,CAElC;IAED;;;;OAIG;IACH,IAAI,IAAI,IAAI,iBAAiB,CAAC,OAAO,CAEpC;IAED;;;;OAIG;IACH,IAAI,aAAa,IAAI,eAAe,CAEnC;IAED;;;;;;OAMG;IACH,eAAe,CACb,EAAE,EAAE,cAAc,GACjB,sBAAsB,CAAC,OAAO,CAAC,GAAG,SAAS;IAgB9C;;;;OAIG;IACH,gBAAgB,IAAI,sBAAsB,CAAC,OAAO,CAAC,EAAE;IAIrD;;;;;OAKG;IACH,yBAAyB,CACvB,UAAU,EAAE,MAAM,GACjB,sBAAsB,CAAC,OAAO,CAAC,GAAG,SAAS;IAI9C;;;;OAIG;IACH,0BAA0B,IAAI,sBAAsB,CAAC,OAAO,CAAC,EAAE;IAI/D;;;;OAIG;IACH,iBAAiB,IAAI,MAAM;IAU3B;;;;;;OAMG;IACG,4BAA4B,CAChC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC;IAoF3C;;;;;OAKG;IACG,gCAAgC,IAAI,OAAO,CAC/C,sBAAsB,CAAC,OAAO,CAAC,CAChC;IAID;;;;OAIG;IACH,wBAAwB,IAAI,OAAO;IAInC;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAclC;;;;OAIG;IACG,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAepD"}
|
|
@@ -9,7 +9,7 @@ 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 _MultichainAccountWallet_id, _MultichainAccountWallet_providers, _MultichainAccountWallet_entropySource, _MultichainAccountWallet_accountGroups,
|
|
12
|
+
var _MultichainAccountWallet_id, _MultichainAccountWallet_providers, _MultichainAccountWallet_entropySource, _MultichainAccountWallet_accountGroups, _MultichainAccountWallet_transientState;
|
|
13
13
|
import { getGroupIndexFromMultichainAccountGroupId, isMultichainAccountGroupId, toMultichainAccountWalletId } from "@metamask/account-api";
|
|
14
14
|
import { toDefaultAccountGroupId } from "@metamask/account-api";
|
|
15
15
|
import { AccountWalletType } from "@metamask/account-api";
|
|
@@ -19,16 +19,17 @@ import { MultichainAccountGroup } from "./MultichainAccountGroup.mjs";
|
|
|
19
19
|
* group index).
|
|
20
20
|
*/
|
|
21
21
|
export class MultichainAccountWallet {
|
|
22
|
-
constructor({ providers, entropySource, }) {
|
|
22
|
+
constructor({ providers, entropySource, transientState, }) {
|
|
23
23
|
_MultichainAccountWallet_id.set(this, void 0);
|
|
24
24
|
_MultichainAccountWallet_providers.set(this, void 0);
|
|
25
25
|
_MultichainAccountWallet_entropySource.set(this, void 0);
|
|
26
26
|
_MultichainAccountWallet_accountGroups.set(this, void 0);
|
|
27
|
-
|
|
27
|
+
_MultichainAccountWallet_transientState.set(this, void 0);
|
|
28
28
|
__classPrivateFieldSet(this, _MultichainAccountWallet_id, toMultichainAccountWalletId(entropySource), "f");
|
|
29
29
|
__classPrivateFieldSet(this, _MultichainAccountWallet_providers, providers, "f");
|
|
30
30
|
__classPrivateFieldSet(this, _MultichainAccountWallet_entropySource, entropySource, "f");
|
|
31
31
|
__classPrivateFieldSet(this, _MultichainAccountWallet_accountGroups, new Map(), "f");
|
|
32
|
+
__classPrivateFieldSet(this, _MultichainAccountWallet_transientState, transientState, "f");
|
|
32
33
|
// Initial synchronization.
|
|
33
34
|
this.sync();
|
|
34
35
|
}
|
|
@@ -244,22 +245,22 @@ export class MultichainAccountWallet {
|
|
|
244
245
|
* @returns True if alignment is in progress, false otherwise.
|
|
245
246
|
*/
|
|
246
247
|
getIsAlignmentInProgress() {
|
|
247
|
-
return __classPrivateFieldGet(this,
|
|
248
|
+
return __classPrivateFieldGet(this, _MultichainAccountWallet_transientState, "f").isAlignmentInProgress;
|
|
248
249
|
}
|
|
249
250
|
/**
|
|
250
251
|
* Align all multichain account groups.
|
|
251
252
|
*/
|
|
252
253
|
async alignGroups() {
|
|
253
|
-
if (__classPrivateFieldGet(this,
|
|
254
|
+
if (__classPrivateFieldGet(this, _MultichainAccountWallet_transientState, "f").isAlignmentInProgress) {
|
|
254
255
|
return; // Prevent concurrent alignments
|
|
255
256
|
}
|
|
256
|
-
|
|
257
|
+
__classPrivateFieldGet(this, _MultichainAccountWallet_transientState, "f").isAlignmentInProgress = true;
|
|
257
258
|
try {
|
|
258
259
|
const groups = this.getMultichainAccountGroups();
|
|
259
260
|
await Promise.all(groups.map((g) => g.align()));
|
|
260
261
|
}
|
|
261
262
|
finally {
|
|
262
|
-
|
|
263
|
+
__classPrivateFieldGet(this, _MultichainAccountWallet_transientState, "f").isAlignmentInProgress = false;
|
|
263
264
|
}
|
|
264
265
|
}
|
|
265
266
|
/**
|
|
@@ -268,10 +269,10 @@ export class MultichainAccountWallet {
|
|
|
268
269
|
* @param groupIndex - The group index to align.
|
|
269
270
|
*/
|
|
270
271
|
async alignGroup(groupIndex) {
|
|
271
|
-
if (__classPrivateFieldGet(this,
|
|
272
|
+
if (__classPrivateFieldGet(this, _MultichainAccountWallet_transientState, "f").isAlignmentInProgress) {
|
|
272
273
|
return; // Prevent concurrent alignments
|
|
273
274
|
}
|
|
274
|
-
|
|
275
|
+
__classPrivateFieldGet(this, _MultichainAccountWallet_transientState, "f").isAlignmentInProgress = true;
|
|
275
276
|
try {
|
|
276
277
|
const group = this.getMultichainAccountGroup(groupIndex);
|
|
277
278
|
if (group) {
|
|
@@ -279,9 +280,9 @@ export class MultichainAccountWallet {
|
|
|
279
280
|
}
|
|
280
281
|
}
|
|
281
282
|
finally {
|
|
282
|
-
|
|
283
|
+
__classPrivateFieldGet(this, _MultichainAccountWallet_transientState, "f").isAlignmentInProgress = false;
|
|
283
284
|
}
|
|
284
285
|
}
|
|
285
286
|
}
|
|
286
|
-
_MultichainAccountWallet_id = new WeakMap(), _MultichainAccountWallet_providers = new WeakMap(), _MultichainAccountWallet_entropySource = new WeakMap(), _MultichainAccountWallet_accountGroups = new WeakMap(),
|
|
287
|
+
_MultichainAccountWallet_id = new WeakMap(), _MultichainAccountWallet_providers = new WeakMap(), _MultichainAccountWallet_entropySource = new WeakMap(), _MultichainAccountWallet_accountGroups = new WeakMap(), _MultichainAccountWallet_transientState = new WeakMap();
|
|
287
288
|
//# sourceMappingURL=MultichainAccountWallet.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MultichainAccountWallet.mjs","sourceRoot":"","sources":["../src/MultichainAccountWallet.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n getGroupIndexFromMultichainAccountGroupId,\n isMultichainAccountGroupId,\n toMultichainAccountWalletId,\n} from '@metamask/account-api';\nimport { toDefaultAccountGroupId } from '@metamask/account-api';\nimport { AccountWalletType } from '@metamask/account-api';\nimport type {\n Bip44Account,\n MultichainAccountWalletId,\n MultichainAccountWallet as MultichainAccountWalletDefinition,\n} from '@metamask/account-api';\nimport type { AccountGroupId } from '@metamask/account-api';\nimport type { AccountProvider } from '@metamask/account-api';\nimport {\n type EntropySourceId,\n type KeyringAccount,\n} from '@metamask/keyring-api';\n\nimport { MultichainAccountGroup } from './MultichainAccountGroup';\n\n/**\n * A multichain account wallet that holds multiple multichain accounts (one multichain account per\n * group index).\n */\nexport class MultichainAccountWallet<\n Account extends Bip44Account<KeyringAccount>,\n> implements MultichainAccountWalletDefinition<Account>\n{\n readonly #id: MultichainAccountWalletId;\n\n readonly #providers: AccountProvider<Account>[];\n\n readonly #entropySource: EntropySourceId;\n\n readonly #accountGroups: Map<number, MultichainAccountGroup<Account>>;\n\n #isAlignmentInProgress: boolean = false;\n\n constructor({\n providers,\n entropySource,\n }: {\n providers: AccountProvider<Account>[];\n entropySource: EntropySourceId;\n }) {\n this.#id = toMultichainAccountWalletId(entropySource);\n this.#providers = providers;\n this.#entropySource = entropySource;\n this.#accountGroups = new Map();\n\n // Initial synchronization.\n this.sync();\n }\n\n /**\n * Force wallet synchronization.\n *\n * This can be used if account providers got new accounts that the wallet\n * doesn't know about.\n */\n sync(): void {\n for (const provider of this.#providers) {\n for (const account of provider.getAccounts()) {\n const { entropy } = account.options;\n\n // Filter for this wallet only.\n if (entropy.id !== this.entropySource) {\n continue;\n }\n\n // This multichain account might exists already.\n let multichainAccount = this.#accountGroups.get(entropy.groupIndex);\n if (!multichainAccount) {\n multichainAccount = new MultichainAccountGroup<Account>({\n groupIndex: entropy.groupIndex,\n wallet: this,\n providers: this.#providers,\n });\n\n // This existing multichain account group might differ from the\n // `createMultichainAccountGroup` behavior. When creating a new\n // group, we expect the providers to all succeed. But here, we're\n // just fetching the account lists from them, so this group might\n // not be \"aligned\" yet (e.g having a missing Solana account).\n //\n // Since \"aligning\" is an async operation, it would have to be run\n // after the first-sync.\n // TODO: Implement align mechanism to create \"missing\" accounts.\n\n this.#accountGroups.set(entropy.groupIndex, multichainAccount);\n }\n }\n }\n\n // Now force-sync all remaining multichain accounts.\n for (const [\n groupIndex,\n multichainAccount,\n ] of this.#accountGroups.entries()) {\n multichainAccount.sync();\n\n // Clean up old multichain accounts.\n if (!multichainAccount.hasAccounts()) {\n this.#accountGroups.delete(groupIndex);\n }\n }\n }\n\n /**\n * Gets the multichain account wallet ID.\n *\n * @returns The multichain account wallet ID.\n */\n get id(): MultichainAccountWalletId {\n return this.#id;\n }\n\n /**\n * Gets the multichain account wallet type, which is always {@link AccountWalletType.Entropy}.\n *\n * @returns The multichain account wallet type.\n */\n get type(): AccountWalletType.Entropy {\n return AccountWalletType.Entropy;\n }\n\n /**\n * Gets the multichain account wallet entropy source.\n *\n * @returns The multichain account wallet entropy source.\n */\n get entropySource(): EntropySourceId {\n return this.#entropySource;\n }\n\n /**\n * Gets multichain account for a given ID.\n * The default group ID will default to the multichain account with index 0.\n *\n * @param id - Account group ID.\n * @returns Account group.\n */\n getAccountGroup(\n id: AccountGroupId,\n ): MultichainAccountGroup<Account> | undefined {\n // We consider the \"default case\" to be mapped to index 0.\n if (id === toDefaultAccountGroupId(this.id)) {\n return this.#accountGroups.get(0);\n }\n\n // If it is not a valid ID, we cannot extract the group index\n // from it, so we fail fast.\n if (!isMultichainAccountGroupId(id)) {\n return undefined;\n }\n\n const groupIndex = getGroupIndexFromMultichainAccountGroupId(id);\n return this.#accountGroups.get(groupIndex);\n }\n\n /**\n * Gets all multichain accounts. Similar to {@link MultichainAccountWallet.getMultichainAccountGroups}.\n *\n * @returns The multichain accounts.\n */\n getAccountGroups(): MultichainAccountGroup<Account>[] {\n return this.getMultichainAccountGroups();\n }\n\n /**\n * Gets multichain account group for a given index.\n *\n * @param groupIndex - Multichain account index.\n * @returns The multichain account associated with the given index.\n */\n getMultichainAccountGroup(\n groupIndex: number,\n ): MultichainAccountGroup<Account> | undefined {\n return this.#accountGroups.get(groupIndex);\n }\n\n /**\n * Gets all multichain account groups.\n *\n * @returns The multichain accounts.\n */\n getMultichainAccountGroups(): MultichainAccountGroup<Account>[] {\n return Array.from(this.#accountGroups.values()); // TODO: Prevent copy here.\n }\n\n /**\n * Gets next group index for this wallet.\n *\n * @returns The next group index of this wallet.\n */\n getNextGroupIndex(): number {\n // We do not check for gaps.\n return (\n Math.max(\n -1, // So it will default to 0 if no groups.\n ...this.#accountGroups.keys(),\n ) + 1\n );\n }\n\n /**\n * Creates a multichain account group for a given group index.\n *\n * @param groupIndex - The group index to use.\n * @throws If any of the account providers fails to create their accounts.\n * @returns The multichain account group for this group index.\n */\n async createMultichainAccountGroup(\n groupIndex: number,\n ): Promise<MultichainAccountGroup<Account>> {\n const nextGroupIndex = this.getNextGroupIndex();\n if (groupIndex > nextGroupIndex) {\n throw new Error(\n `You cannot use a group index that is higher than the next available one: expected <=${nextGroupIndex}, got ${groupIndex}`,\n );\n }\n\n let group = this.getMultichainAccountGroup(groupIndex);\n if (group) {\n // If the group already exists, we just `sync` it and returns the same\n // reference.\n group.sync();\n\n return group;\n }\n\n const results = await Promise.allSettled(\n this.#providers.map((provider) =>\n provider.createAccounts({\n entropySource: this.#entropySource,\n groupIndex,\n }),\n ),\n );\n\n // --------------------------------------------------------------------------------\n // READ THIS CAREFULLY:\n //\n // Since we're not \"fully supporting multichain\" for now, we still rely on single\n // :accountCreated events to sync multichain account groups and wallets. Which means\n // that even if of the provider fails, some accounts will still be created on some\n // other providers and will become \"available\" on the `AccountsController`, like:\n //\n // 1. Creating a multichain account group for index 1\n // 2. EvmAccountProvider.createAccounts returns the EVM account for index 1\n // * AccountsController WILL fire :accountCreated for this account\n // * This account WILL BE \"available\" on the AccountsController state\n // 3. SolAccountProvider.createAccounts fails to create a Solana account for index 1\n // * AccountsController WON't fire :accountCreated for this account\n // * This account WON'T be \"available\" on the Account\n // 4. MultichainAccountService will receive a :accountCreated for the EVM account from\n // step 2 and will create a new multichain account group for index 1, but it won't\n // receive any event for the Solana account of this group. Thus, this group won't be\n // \"aligned\" (missing \"blockchain account\" on this group).\n //\n // --------------------------------------------------------------------------------\n\n // If any of the provider failed to create their accounts, then we consider the\n // multichain account group to have failed too.\n if (results.some((result) => result.status === 'rejected')) {\n // NOTE: Some accounts might still have been created on other account providers. We\n // don't rollback them.\n const error = `Unable to create multichain account group for index: ${groupIndex}`;\n\n let warn = `${error}:`;\n for (const result of results) {\n if (result.status === 'rejected') {\n warn += `\\n- ${result.reason}`;\n }\n }\n console.warn(warn);\n\n throw new Error(error);\n }\n\n // Because of the :accountAdded automatic sync, we might already have created the\n // group, so we first try to get it.\n group = this.getMultichainAccountGroup(groupIndex);\n if (!group) {\n // If for some reason it's still not created, we're creating it explicitly now:\n group = new MultichainAccountGroup({\n wallet: this,\n providers: this.#providers,\n groupIndex,\n });\n }\n\n // Register the account to our internal map.\n this.#accountGroups.set(groupIndex, group); // `group` cannot be undefined here.\n\n return group;\n }\n\n /**\n * Creates the next multichain account group.\n *\n * @throws If any of the account providers fails to create their accounts.\n * @returns The multichain account group for the next group index available.\n */\n async createNextMultichainAccountGroup(): Promise<\n MultichainAccountGroup<Account>\n > {\n return this.createMultichainAccountGroup(this.getNextGroupIndex());\n }\n\n /**\n * Gets whether alignment is currently in progress for this wallet.\n *\n * @returns True if alignment is in progress, false otherwise.\n */\n getIsAlignmentInProgress(): boolean {\n return this.#isAlignmentInProgress;\n }\n\n /**\n * Align all multichain account groups.\n */\n async alignGroups(): Promise<void> {\n if (this.#isAlignmentInProgress) {\n return; // Prevent concurrent alignments\n }\n\n this.#isAlignmentInProgress = true;\n try {\n const groups = this.getMultichainAccountGroups();\n await Promise.all(groups.map((g) => g.align()));\n } finally {\n this.#isAlignmentInProgress = false;\n }\n }\n\n /**\n * Align a specific multichain account group.\n *\n * @param groupIndex - The group index to align.\n */\n async alignGroup(groupIndex: number): Promise<void> {\n if (this.#isAlignmentInProgress) {\n return; // Prevent concurrent alignments\n }\n\n this.#isAlignmentInProgress = true;\n try {\n const group = this.getMultichainAccountGroup(groupIndex);\n if (group) {\n await group.align();\n }\n } finally {\n this.#isAlignmentInProgress = false;\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"MultichainAccountWallet.mjs","sourceRoot":"","sources":["../src/MultichainAccountWallet.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n getGroupIndexFromMultichainAccountGroupId,\n isMultichainAccountGroupId,\n toMultichainAccountWalletId,\n} from '@metamask/account-api';\nimport { toDefaultAccountGroupId } from '@metamask/account-api';\nimport { AccountWalletType } from '@metamask/account-api';\nimport type {\n Bip44Account,\n MultichainAccountWalletId,\n MultichainAccountWallet as MultichainAccountWalletDefinition,\n} from '@metamask/account-api';\nimport type { AccountGroupId } from '@metamask/account-api';\nimport type { AccountProvider } from '@metamask/account-api';\nimport {\n type EntropySourceId,\n type KeyringAccount,\n} from '@metamask/keyring-api';\n\nimport { MultichainAccountGroup } from './MultichainAccountGroup';\n\n/**\n * Transient state for a multichain account wallet.\n *\n * This state WILL NEVER be persisted. It will be shared with the client's UI\n * so the UI can reflect th current state of the wallet (aligning, discovering, etc...)\n */\nexport type MultichainAccountWalletTransientState = {\n /** True when the wallet is being aligned (creating missing accounts on each groups). */\n isAlignmentInProgress: boolean;\n};\n\n/**\n * A multichain account wallet that holds multiple multichain accounts (one multichain account per\n * group index).\n */\nexport class MultichainAccountWallet<\n Account extends Bip44Account<KeyringAccount>,\n> implements MultichainAccountWalletDefinition<Account>\n{\n readonly #id: MultichainAccountWalletId;\n\n readonly #providers: AccountProvider<Account>[];\n\n readonly #entropySource: EntropySourceId;\n\n readonly #accountGroups: Map<number, MultichainAccountGroup<Account>>;\n\n readonly #transientState: MultichainAccountWalletTransientState;\n\n constructor({\n providers,\n entropySource,\n transientState,\n }: {\n providers: AccountProvider<Account>[];\n entropySource: EntropySourceId;\n transientState: MultichainAccountWalletTransientState;\n }) {\n this.#id = toMultichainAccountWalletId(entropySource);\n this.#providers = providers;\n this.#entropySource = entropySource;\n this.#accountGroups = new Map();\n this.#transientState = transientState;\n\n // Initial synchronization.\n this.sync();\n }\n\n /**\n * Force wallet synchronization.\n *\n * This can be used if account providers got new accounts that the wallet\n * doesn't know about.\n */\n sync(): void {\n for (const provider of this.#providers) {\n for (const account of provider.getAccounts()) {\n const { entropy } = account.options;\n\n // Filter for this wallet only.\n if (entropy.id !== this.entropySource) {\n continue;\n }\n\n // This multichain account might exists already.\n let multichainAccount = this.#accountGroups.get(entropy.groupIndex);\n if (!multichainAccount) {\n multichainAccount = new MultichainAccountGroup<Account>({\n groupIndex: entropy.groupIndex,\n wallet: this,\n providers: this.#providers,\n });\n\n // This existing multichain account group might differ from the\n // `createMultichainAccountGroup` behavior. When creating a new\n // group, we expect the providers to all succeed. But here, we're\n // just fetching the account lists from them, so this group might\n // not be \"aligned\" yet (e.g having a missing Solana account).\n //\n // Since \"aligning\" is an async operation, it would have to be run\n // after the first-sync.\n // TODO: Implement align mechanism to create \"missing\" accounts.\n\n this.#accountGroups.set(entropy.groupIndex, multichainAccount);\n }\n }\n }\n\n // Now force-sync all remaining multichain accounts.\n for (const [\n groupIndex,\n multichainAccount,\n ] of this.#accountGroups.entries()) {\n multichainAccount.sync();\n\n // Clean up old multichain accounts.\n if (!multichainAccount.hasAccounts()) {\n this.#accountGroups.delete(groupIndex);\n }\n }\n }\n\n /**\n * Gets the multichain account wallet ID.\n *\n * @returns The multichain account wallet ID.\n */\n get id(): MultichainAccountWalletId {\n return this.#id;\n }\n\n /**\n * Gets the multichain account wallet type, which is always {@link AccountWalletType.Entropy}.\n *\n * @returns The multichain account wallet type.\n */\n get type(): AccountWalletType.Entropy {\n return AccountWalletType.Entropy;\n }\n\n /**\n * Gets the multichain account wallet entropy source.\n *\n * @returns The multichain account wallet entropy source.\n */\n get entropySource(): EntropySourceId {\n return this.#entropySource;\n }\n\n /**\n * Gets multichain account for a given ID.\n * The default group ID will default to the multichain account with index 0.\n *\n * @param id - Account group ID.\n * @returns Account group.\n */\n getAccountGroup(\n id: AccountGroupId,\n ): MultichainAccountGroup<Account> | undefined {\n // We consider the \"default case\" to be mapped to index 0.\n if (id === toDefaultAccountGroupId(this.id)) {\n return this.#accountGroups.get(0);\n }\n\n // If it is not a valid ID, we cannot extract the group index\n // from it, so we fail fast.\n if (!isMultichainAccountGroupId(id)) {\n return undefined;\n }\n\n const groupIndex = getGroupIndexFromMultichainAccountGroupId(id);\n return this.#accountGroups.get(groupIndex);\n }\n\n /**\n * Gets all multichain accounts. Similar to {@link MultichainAccountWallet.getMultichainAccountGroups}.\n *\n * @returns The multichain accounts.\n */\n getAccountGroups(): MultichainAccountGroup<Account>[] {\n return this.getMultichainAccountGroups();\n }\n\n /**\n * Gets multichain account group for a given index.\n *\n * @param groupIndex - Multichain account index.\n * @returns The multichain account associated with the given index.\n */\n getMultichainAccountGroup(\n groupIndex: number,\n ): MultichainAccountGroup<Account> | undefined {\n return this.#accountGroups.get(groupIndex);\n }\n\n /**\n * Gets all multichain account groups.\n *\n * @returns The multichain accounts.\n */\n getMultichainAccountGroups(): MultichainAccountGroup<Account>[] {\n return Array.from(this.#accountGroups.values()); // TODO: Prevent copy here.\n }\n\n /**\n * Gets next group index for this wallet.\n *\n * @returns The next group index of this wallet.\n */\n getNextGroupIndex(): number {\n // We do not check for gaps.\n return (\n Math.max(\n -1, // So it will default to 0 if no groups.\n ...this.#accountGroups.keys(),\n ) + 1\n );\n }\n\n /**\n * Creates a multichain account group for a given group index.\n *\n * @param groupIndex - The group index to use.\n * @throws If any of the account providers fails to create their accounts.\n * @returns The multichain account group for this group index.\n */\n async createMultichainAccountGroup(\n groupIndex: number,\n ): Promise<MultichainAccountGroup<Account>> {\n const nextGroupIndex = this.getNextGroupIndex();\n if (groupIndex > nextGroupIndex) {\n throw new Error(\n `You cannot use a group index that is higher than the next available one: expected <=${nextGroupIndex}, got ${groupIndex}`,\n );\n }\n\n let group = this.getMultichainAccountGroup(groupIndex);\n if (group) {\n // If the group already exists, we just `sync` it and returns the same\n // reference.\n group.sync();\n\n return group;\n }\n\n const results = await Promise.allSettled(\n this.#providers.map((provider) =>\n provider.createAccounts({\n entropySource: this.#entropySource,\n groupIndex,\n }),\n ),\n );\n\n // --------------------------------------------------------------------------------\n // READ THIS CAREFULLY:\n //\n // Since we're not \"fully supporting multichain\" for now, we still rely on single\n // :accountCreated events to sync multichain account groups and wallets. Which means\n // that even if of the provider fails, some accounts will still be created on some\n // other providers and will become \"available\" on the `AccountsController`, like:\n //\n // 1. Creating a multichain account group for index 1\n // 2. EvmAccountProvider.createAccounts returns the EVM account for index 1\n // * AccountsController WILL fire :accountCreated for this account\n // * This account WILL BE \"available\" on the AccountsController state\n // 3. SolAccountProvider.createAccounts fails to create a Solana account for index 1\n // * AccountsController WON't fire :accountCreated for this account\n // * This account WON'T be \"available\" on the Account\n // 4. MultichainAccountService will receive a :accountCreated for the EVM account from\n // step 2 and will create a new multichain account group for index 1, but it won't\n // receive any event for the Solana account of this group. Thus, this group won't be\n // \"aligned\" (missing \"blockchain account\" on this group).\n //\n // --------------------------------------------------------------------------------\n\n // If any of the provider failed to create their accounts, then we consider the\n // multichain account group to have failed too.\n if (results.some((result) => result.status === 'rejected')) {\n // NOTE: Some accounts might still have been created on other account providers. We\n // don't rollback them.\n const error = `Unable to create multichain account group for index: ${groupIndex}`;\n\n let warn = `${error}:`;\n for (const result of results) {\n if (result.status === 'rejected') {\n warn += `\\n- ${result.reason}`;\n }\n }\n console.warn(warn);\n\n throw new Error(error);\n }\n\n // Because of the :accountAdded automatic sync, we might already have created the\n // group, so we first try to get it.\n group = this.getMultichainAccountGroup(groupIndex);\n if (!group) {\n // If for some reason it's still not created, we're creating it explicitly now:\n group = new MultichainAccountGroup({\n wallet: this,\n providers: this.#providers,\n groupIndex,\n });\n }\n\n // Register the account to our internal map.\n this.#accountGroups.set(groupIndex, group); // `group` cannot be undefined here.\n\n return group;\n }\n\n /**\n * Creates the next multichain account group.\n *\n * @throws If any of the account providers fails to create their accounts.\n * @returns The multichain account group for the next group index available.\n */\n async createNextMultichainAccountGroup(): Promise<\n MultichainAccountGroup<Account>\n > {\n return this.createMultichainAccountGroup(this.getNextGroupIndex());\n }\n\n /**\n * Gets whether alignment is currently in progress for this wallet.\n *\n * @returns True if alignment is in progress, false otherwise.\n */\n getIsAlignmentInProgress(): boolean {\n return this.#transientState.isAlignmentInProgress;\n }\n\n /**\n * Align all multichain account groups.\n */\n async alignGroups(): Promise<void> {\n if (this.#transientState.isAlignmentInProgress) {\n return; // Prevent concurrent alignments\n }\n\n this.#transientState.isAlignmentInProgress = true;\n try {\n const groups = this.getMultichainAccountGroups();\n await Promise.all(groups.map((g) => g.align()));\n } finally {\n this.#transientState.isAlignmentInProgress = false;\n }\n }\n\n /**\n * Align a specific multichain account group.\n *\n * @param groupIndex - The group index to align.\n */\n async alignGroup(groupIndex: number): Promise<void> {\n if (this.#transientState.isAlignmentInProgress) {\n return; // Prevent concurrent alignments\n }\n\n this.#transientState.isAlignmentInProgress = true;\n try {\n const group = this.getMultichainAccountGroup(groupIndex);\n if (group) {\n await group.align();\n }\n } finally {\n this.#transientState.isAlignmentInProgress = false;\n }\n }\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transient-state.cjs","sourceRoot":"","sources":["../src/transient-state.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n StateConstraint,\n StatePropertyMetadata,\n} from '@metamask/base-controller';\n\n/**\n * Transient state metadata.\n *\n * This metadata describes how to get an anonymized representation of the state.\n */\nexport type TransientStateMetadata<T extends StateConstraint> = {\n [P in keyof T]-?: StatePropertyMetadata<T[P]> & {\n // Since the state is transient, it cannot be persisted.\n persist: false;\n };\n};\n"]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { StateConstraint, StatePropertyMetadata } from "@metamask/base-controller";
|
|
2
|
+
/**
|
|
3
|
+
* Transient state metadata.
|
|
4
|
+
*
|
|
5
|
+
* This metadata describes how to get an anonymized representation of the state.
|
|
6
|
+
*/
|
|
7
|
+
export type TransientStateMetadata<T extends StateConstraint> = {
|
|
8
|
+
[P in keyof T]-?: StatePropertyMetadata<T[P]> & {
|
|
9
|
+
persist: false;
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=transient-state.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transient-state.d.cts","sourceRoot":"","sources":["../src/transient-state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,qBAAqB,EACtB,kCAAkC;AAEnC;;;;GAIG;AACH,MAAM,MAAM,sBAAsB,CAAC,CAAC,SAAS,eAAe,IAAI;KAC7D,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG;QAE9C,OAAO,EAAE,KAAK,CAAC;KAChB;CACF,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { StateConstraint, StatePropertyMetadata } from "@metamask/base-controller";
|
|
2
|
+
/**
|
|
3
|
+
* Transient state metadata.
|
|
4
|
+
*
|
|
5
|
+
* This metadata describes how to get an anonymized representation of the state.
|
|
6
|
+
*/
|
|
7
|
+
export type TransientStateMetadata<T extends StateConstraint> = {
|
|
8
|
+
[P in keyof T]-?: StatePropertyMetadata<T[P]> & {
|
|
9
|
+
persist: false;
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=transient-state.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transient-state.d.mts","sourceRoot":"","sources":["../src/transient-state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,qBAAqB,EACtB,kCAAkC;AAEnC;;;;GAIG;AACH,MAAM,MAAM,sBAAsB,CAAC,CAAC,SAAS,eAAe,IAAI;KAC7D,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG;QAE9C,OAAO,EAAE,KAAK,CAAC;KAChB;CACF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transient-state.mjs","sourceRoot":"","sources":["../src/transient-state.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n StateConstraint,\n StatePropertyMetadata,\n} from '@metamask/base-controller';\n\n/**\n * Transient state metadata.\n *\n * This metadata describes how to get an anonymized representation of the state.\n */\nexport type TransientStateMetadata<T extends StateConstraint> = {\n [P in keyof T]-?: StatePropertyMetadata<T[P]> & {\n // Since the state is transient, it cannot be persisted.\n persist: false;\n };\n};\n"]}
|
package/dist/types.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.cjs","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n AccountsControllerAccountAddedEvent,\n AccountsControllerAccountRemovedEvent,\n AccountsControllerGetAccountAction,\n AccountsControllerGetAccountByAddressAction,\n AccountsControllerListMultichainAccountsAction,\n} from '@metamask/accounts-controller';\nimport type { RestrictedMessenger } from '@metamask/base-controller';\nimport type {\n KeyringControllerGetStateAction,\n KeyringControllerStateChangeEvent,\n KeyringControllerWithKeyringAction,\n} from '@metamask/keyring-controller';\nimport type { HandleSnapRequest as SnapControllerHandleSnapRequestAction } from '@metamask/snaps-controllers';\n\nimport type {\n MultichainAccountService,\n serviceName,\n} from './MultichainAccountService';\n\nexport type MultichainAccountServiceGetMultichainAccountGroupAction = {\n type: `${typeof serviceName}:getMultichainAccountGroup`;\n handler: MultichainAccountService['getMultichainAccountGroup'];\n};\n\nexport type MultichainAccountServiceGetMultichainAccountGroupsAction = {\n type: `${typeof serviceName}:getMultichainAccountGroups`;\n handler: MultichainAccountService['getMultichainAccountGroups'];\n};\n\nexport type MultichainAccountServiceGetMultichainAccountWalletAction = {\n type: `${typeof serviceName}:getMultichainAccountWallet`;\n handler: MultichainAccountService['getMultichainAccountWallet'];\n};\n\nexport type MultichainAccountServiceGetMultichainAccountWalletsAction = {\n type: `${typeof serviceName}:getMultichainAccountWallets`;\n handler: MultichainAccountService['getMultichainAccountWallets'];\n};\n\nexport type MultichainAccountServiceCreateNextMultichainAccountGroupAction = {\n type: `${typeof serviceName}:createNextMultichainAccountGroup`;\n handler: MultichainAccountService['createNextMultichainAccountGroup'];\n};\n\nexport type MultichainAccountServiceCreateMultichainAccountGroupAction = {\n type: `${typeof serviceName}:createMultichainAccountGroup`;\n handler: MultichainAccountService['createMultichainAccountGroup'];\n};\n\nexport type MultichainAccountServiceSetBasicFunctionalityAction = {\n type: `${typeof serviceName}:setBasicFunctionality`;\n handler: MultichainAccountService['setBasicFunctionality'];\n};\n\nexport type MultichainAccountServiceAlignWalletAction = {\n type: `${typeof serviceName}:alignWallet`;\n handler: MultichainAccountService['alignWallet'];\n};\n\nexport type MultichainAccountServiceAlignWalletsAction = {\n type: `${typeof serviceName}:alignWallets`;\n handler: MultichainAccountService['alignWallets'];\n};\n\nexport type MultichainAccountServiceGetIsAlignmentInProgressAction = {\n type: `${typeof serviceName}:getIsAlignmentInProgress`;\n handler: MultichainAccountService['getIsAlignmentInProgress'];\n};\n\n/**\n * All actions that {@link MultichainAccountService} registers so that other\n * modules can call them.\n */\nexport type MultichainAccountServiceActions =\n | MultichainAccountServiceGetMultichainAccountGroupAction\n | MultichainAccountServiceGetMultichainAccountGroupsAction\n | MultichainAccountServiceGetMultichainAccountWalletAction\n | MultichainAccountServiceGetMultichainAccountWalletsAction\n | MultichainAccountServiceCreateNextMultichainAccountGroupAction\n | MultichainAccountServiceCreateMultichainAccountGroupAction\n | MultichainAccountServiceSetBasicFunctionalityAction\n | MultichainAccountServiceAlignWalletAction\n | MultichainAccountServiceAlignWalletsAction\n | MultichainAccountServiceGetIsAlignmentInProgressAction;\n\n/**\n * All events that {@link MultichainAccountService} publishes so that other modules\n * can subscribe to them.\n */\nexport type MultichainAccountServiceEvents = never;\n\n/**\n * All actions registered by other modules that {@link MultichainAccountService}\n * calls.\n */\nexport type AllowedActions =\n | AccountsControllerListMultichainAccountsAction\n | AccountsControllerGetAccountAction\n | AccountsControllerGetAccountByAddressAction\n | SnapControllerHandleSnapRequestAction\n | KeyringControllerWithKeyringAction\n | KeyringControllerGetStateAction;\n\n/**\n * All events published by other modules that {@link MultichainAccountService}\n * subscribes to.\n */\nexport type AllowedEvents =\n | KeyringControllerStateChangeEvent\n | AccountsControllerAccountAddedEvent\n | AccountsControllerAccountRemovedEvent;\n\n/**\n * The messenger restricted to actions and events that\n * {@link MultichainAccountService} needs to access.\n */\nexport type MultichainAccountServiceMessenger = RestrictedMessenger<\n 'MultichainAccountService',\n MultichainAccountServiceActions | AllowedActions,\n MultichainAccountServiceEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n"]}
|
|
1
|
+
{"version":3,"file":"types.cjs","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { MultichainAccountWalletId } from '@metamask/account-api';\nimport type {\n AccountsControllerAccountAddedEvent,\n AccountsControllerAccountRemovedEvent,\n AccountsControllerGetAccountAction,\n AccountsControllerGetAccountByAddressAction,\n AccountsControllerListMultichainAccountsAction,\n} from '@metamask/accounts-controller';\nimport type { RestrictedMessenger } from '@metamask/base-controller';\nimport type {\n KeyringControllerGetStateAction,\n KeyringControllerStateChangeEvent,\n KeyringControllerWithKeyringAction,\n} from '@metamask/keyring-controller';\nimport type { HandleSnapRequest as SnapControllerHandleSnapRequestAction } from '@metamask/snaps-controllers';\n\nimport type {\n MultichainAccountService,\n serviceName,\n} from './MultichainAccountService';\nimport type { MultichainAccountWalletTransientState } from './MultichainAccountWallet';\n\nexport type MultichainAccountServiceTransientState = {\n accountWalletsTransientState: {\n [\n walletId: MultichainAccountWalletId\n ]: MultichainAccountWalletTransientState;\n };\n};\n\nexport type MultichainAccountServiceGetMultichainAccountGroupAction = {\n type: `${typeof serviceName}:getMultichainAccountGroup`;\n handler: MultichainAccountService['getMultichainAccountGroup'];\n};\n\nexport type MultichainAccountServiceGetMultichainAccountGroupsAction = {\n type: `${typeof serviceName}:getMultichainAccountGroups`;\n handler: MultichainAccountService['getMultichainAccountGroups'];\n};\n\nexport type MultichainAccountServiceGetMultichainAccountWalletAction = {\n type: `${typeof serviceName}:getMultichainAccountWallet`;\n handler: MultichainAccountService['getMultichainAccountWallet'];\n};\n\nexport type MultichainAccountServiceGetMultichainAccountWalletsAction = {\n type: `${typeof serviceName}:getMultichainAccountWallets`;\n handler: MultichainAccountService['getMultichainAccountWallets'];\n};\n\nexport type MultichainAccountServiceCreateNextMultichainAccountGroupAction = {\n type: `${typeof serviceName}:createNextMultichainAccountGroup`;\n handler: MultichainAccountService['createNextMultichainAccountGroup'];\n};\n\nexport type MultichainAccountServiceCreateMultichainAccountGroupAction = {\n type: `${typeof serviceName}:createMultichainAccountGroup`;\n handler: MultichainAccountService['createMultichainAccountGroup'];\n};\n\nexport type MultichainAccountServiceSetBasicFunctionalityAction = {\n type: `${typeof serviceName}:setBasicFunctionality`;\n handler: MultichainAccountService['setBasicFunctionality'];\n};\n\nexport type MultichainAccountServiceAlignWalletAction = {\n type: `${typeof serviceName}:alignWallet`;\n handler: MultichainAccountService['alignWallet'];\n};\n\nexport type MultichainAccountServiceAlignWalletsAction = {\n type: `${typeof serviceName}:alignWallets`;\n handler: MultichainAccountService['alignWallets'];\n};\n\nexport type MultichainAccountServiceGetIsAlignmentInProgressAction = {\n type: `${typeof serviceName}:getIsAlignmentInProgress`;\n handler: MultichainAccountService['getIsAlignmentInProgress'];\n};\n\n/**\n * All actions that {@link MultichainAccountService} registers so that other\n * modules can call them.\n */\nexport type MultichainAccountServiceActions =\n | MultichainAccountServiceGetMultichainAccountGroupAction\n | MultichainAccountServiceGetMultichainAccountGroupsAction\n | MultichainAccountServiceGetMultichainAccountWalletAction\n | MultichainAccountServiceGetMultichainAccountWalletsAction\n | MultichainAccountServiceCreateNextMultichainAccountGroupAction\n | MultichainAccountServiceCreateMultichainAccountGroupAction\n | MultichainAccountServiceSetBasicFunctionalityAction\n | MultichainAccountServiceAlignWalletAction\n | MultichainAccountServiceAlignWalletsAction\n | MultichainAccountServiceGetIsAlignmentInProgressAction;\n\n/**\n * All events that {@link MultichainAccountService} publishes so that other modules\n * can subscribe to them.\n */\nexport type MultichainAccountServiceEvents = never;\n\n/**\n * All actions registered by other modules that {@link MultichainAccountService}\n * calls.\n */\nexport type AllowedActions =\n | AccountsControllerListMultichainAccountsAction\n | AccountsControllerGetAccountAction\n | AccountsControllerGetAccountByAddressAction\n | SnapControllerHandleSnapRequestAction\n | KeyringControllerWithKeyringAction\n | KeyringControllerGetStateAction;\n\n/**\n * All events published by other modules that {@link MultichainAccountService}\n * subscribes to.\n */\nexport type AllowedEvents =\n | KeyringControllerStateChangeEvent\n | AccountsControllerAccountAddedEvent\n | AccountsControllerAccountRemovedEvent;\n\n/**\n * The messenger restricted to actions and events that\n * {@link MultichainAccountService} needs to access.\n */\nexport type MultichainAccountServiceMessenger = RestrictedMessenger<\n 'MultichainAccountService',\n MultichainAccountServiceActions | AllowedActions,\n MultichainAccountServiceEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n"]}
|
package/dist/types.d.cts
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
|
+
import type { MultichainAccountWalletId } from "@metamask/account-api";
|
|
1
2
|
import type { AccountsControllerAccountAddedEvent, AccountsControllerAccountRemovedEvent, AccountsControllerGetAccountAction, AccountsControllerGetAccountByAddressAction, AccountsControllerListMultichainAccountsAction } from "@metamask/accounts-controller";
|
|
2
3
|
import type { RestrictedMessenger } from "@metamask/base-controller";
|
|
3
4
|
import type { KeyringControllerGetStateAction, KeyringControllerStateChangeEvent, KeyringControllerWithKeyringAction } from "@metamask/keyring-controller";
|
|
4
5
|
import type { HandleSnapRequest as SnapControllerHandleSnapRequestAction } from "@metamask/snaps-controllers";
|
|
5
6
|
import type { MultichainAccountService, serviceName } from "./MultichainAccountService.cjs";
|
|
7
|
+
import type { MultichainAccountWalletTransientState } from "./MultichainAccountWallet.cjs";
|
|
8
|
+
export type MultichainAccountServiceTransientState = {
|
|
9
|
+
accountWalletsTransientState: {
|
|
10
|
+
[walletId: MultichainAccountWalletId]: MultichainAccountWalletTransientState;
|
|
11
|
+
};
|
|
12
|
+
};
|
|
6
13
|
export type MultichainAccountServiceGetMultichainAccountGroupAction = {
|
|
7
14
|
type: `${typeof serviceName}:getMultichainAccountGroup`;
|
|
8
15
|
handler: MultichainAccountService['getMultichainAccountGroup'];
|
package/dist/types.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.cts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mCAAmC,EACnC,qCAAqC,EACrC,kCAAkC,EAClC,2CAA2C,EAC3C,8CAA8C,EAC/C,sCAAsC;AACvC,OAAO,KAAK,EAAE,mBAAmB,EAAE,kCAAkC;AACrE,OAAO,KAAK,EACV,+BAA+B,EAC/B,iCAAiC,EACjC,kCAAkC,EACnC,qCAAqC;AACtC,OAAO,KAAK,EAAE,iBAAiB,IAAI,qCAAqC,EAAE,oCAAoC;AAE9G,OAAO,KAAK,EACV,wBAAwB,EACxB,WAAW,EACZ,uCAAmC;
|
|
1
|
+
{"version":3,"file":"types.d.cts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,8BAA8B;AACvE,OAAO,KAAK,EACV,mCAAmC,EACnC,qCAAqC,EACrC,kCAAkC,EAClC,2CAA2C,EAC3C,8CAA8C,EAC/C,sCAAsC;AACvC,OAAO,KAAK,EAAE,mBAAmB,EAAE,kCAAkC;AACrE,OAAO,KAAK,EACV,+BAA+B,EAC/B,iCAAiC,EACjC,kCAAkC,EACnC,qCAAqC;AACtC,OAAO,KAAK,EAAE,iBAAiB,IAAI,qCAAqC,EAAE,oCAAoC;AAE9G,OAAO,KAAK,EACV,wBAAwB,EACxB,WAAW,EACZ,uCAAmC;AACpC,OAAO,KAAK,EAAE,qCAAqC,EAAE,sCAAkC;AAEvF,MAAM,MAAM,sCAAsC,GAAG;IACnD,4BAA4B,EAAE;QAC5B,CACE,QAAQ,EAAE,yBAAyB,GAClC,qCAAqC,CAAC;KAC1C,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,uDAAuD,GAAG;IACpE,IAAI,EAAE,GAAG,OAAO,WAAW,4BAA4B,CAAC;IACxD,OAAO,EAAE,wBAAwB,CAAC,2BAA2B,CAAC,CAAC;CAChE,CAAC;AAEF,MAAM,MAAM,wDAAwD,GAAG;IACrE,IAAI,EAAE,GAAG,OAAO,WAAW,6BAA6B,CAAC;IACzD,OAAO,EAAE,wBAAwB,CAAC,4BAA4B,CAAC,CAAC;CACjE,CAAC;AAEF,MAAM,MAAM,wDAAwD,GAAG;IACrE,IAAI,EAAE,GAAG,OAAO,WAAW,6BAA6B,CAAC;IACzD,OAAO,EAAE,wBAAwB,CAAC,4BAA4B,CAAC,CAAC;CACjE,CAAC;AAEF,MAAM,MAAM,yDAAyD,GAAG;IACtE,IAAI,EAAE,GAAG,OAAO,WAAW,8BAA8B,CAAC;IAC1D,OAAO,EAAE,wBAAwB,CAAC,6BAA6B,CAAC,CAAC;CAClE,CAAC;AAEF,MAAM,MAAM,8DAA8D,GAAG;IAC3E,IAAI,EAAE,GAAG,OAAO,WAAW,mCAAmC,CAAC;IAC/D,OAAO,EAAE,wBAAwB,CAAC,kCAAkC,CAAC,CAAC;CACvE,CAAC;AAEF,MAAM,MAAM,0DAA0D,GAAG;IACvE,IAAI,EAAE,GAAG,OAAO,WAAW,+BAA+B,CAAC;IAC3D,OAAO,EAAE,wBAAwB,CAAC,8BAA8B,CAAC,CAAC;CACnE,CAAC;AAEF,MAAM,MAAM,mDAAmD,GAAG;IAChE,IAAI,EAAE,GAAG,OAAO,WAAW,wBAAwB,CAAC;IACpD,OAAO,EAAE,wBAAwB,CAAC,uBAAuB,CAAC,CAAC;CAC5D,CAAC;AAEF,MAAM,MAAM,yCAAyC,GAAG;IACtD,IAAI,EAAE,GAAG,OAAO,WAAW,cAAc,CAAC;IAC1C,OAAO,EAAE,wBAAwB,CAAC,aAAa,CAAC,CAAC;CAClD,CAAC;AAEF,MAAM,MAAM,0CAA0C,GAAG;IACvD,IAAI,EAAE,GAAG,OAAO,WAAW,eAAe,CAAC;IAC3C,OAAO,EAAE,wBAAwB,CAAC,cAAc,CAAC,CAAC;CACnD,CAAC;AAEF,MAAM,MAAM,sDAAsD,GAAG;IACnE,IAAI,EAAE,GAAG,OAAO,WAAW,2BAA2B,CAAC;IACvD,OAAO,EAAE,wBAAwB,CAAC,0BAA0B,CAAC,CAAC;CAC/D,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,+BAA+B,GACvC,uDAAuD,GACvD,wDAAwD,GACxD,wDAAwD,GACxD,yDAAyD,GACzD,8DAA8D,GAC9D,0DAA0D,GAC1D,mDAAmD,GACnD,yCAAyC,GACzC,0CAA0C,GAC1C,sDAAsD,CAAC;AAE3D;;;GAGG;AACH,MAAM,MAAM,8BAA8B,GAAG,KAAK,CAAC;AAEnD;;;GAGG;AACH,MAAM,MAAM,cAAc,GACtB,8CAA8C,GAC9C,kCAAkC,GAClC,2CAA2C,GAC3C,qCAAqC,GACrC,kCAAkC,GAClC,+BAA+B,CAAC;AAEpC;;;GAGG;AACH,MAAM,MAAM,aAAa,GACrB,iCAAiC,GACjC,mCAAmC,GACnC,qCAAqC,CAAC;AAE1C;;;GAGG;AACH,MAAM,MAAM,iCAAiC,GAAG,mBAAmB,CACjE,0BAA0B,EAC1B,+BAA+B,GAAG,cAAc,EAChD,8BAA8B,GAAG,aAAa,EAC9C,cAAc,CAAC,MAAM,CAAC,EACtB,aAAa,CAAC,MAAM,CAAC,CACtB,CAAC"}
|
package/dist/types.d.mts
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
|
+
import type { MultichainAccountWalletId } from "@metamask/account-api";
|
|
1
2
|
import type { AccountsControllerAccountAddedEvent, AccountsControllerAccountRemovedEvent, AccountsControllerGetAccountAction, AccountsControllerGetAccountByAddressAction, AccountsControllerListMultichainAccountsAction } from "@metamask/accounts-controller";
|
|
2
3
|
import type { RestrictedMessenger } from "@metamask/base-controller";
|
|
3
4
|
import type { KeyringControllerGetStateAction, KeyringControllerStateChangeEvent, KeyringControllerWithKeyringAction } from "@metamask/keyring-controller";
|
|
4
5
|
import type { HandleSnapRequest as SnapControllerHandleSnapRequestAction } from "@metamask/snaps-controllers";
|
|
5
6
|
import type { MultichainAccountService, serviceName } from "./MultichainAccountService.mjs";
|
|
7
|
+
import type { MultichainAccountWalletTransientState } from "./MultichainAccountWallet.mjs";
|
|
8
|
+
export type MultichainAccountServiceTransientState = {
|
|
9
|
+
accountWalletsTransientState: {
|
|
10
|
+
[walletId: MultichainAccountWalletId]: MultichainAccountWalletTransientState;
|
|
11
|
+
};
|
|
12
|
+
};
|
|
6
13
|
export type MultichainAccountServiceGetMultichainAccountGroupAction = {
|
|
7
14
|
type: `${typeof serviceName}:getMultichainAccountGroup`;
|
|
8
15
|
handler: MultichainAccountService['getMultichainAccountGroup'];
|
package/dist/types.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.mts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mCAAmC,EACnC,qCAAqC,EACrC,kCAAkC,EAClC,2CAA2C,EAC3C,8CAA8C,EAC/C,sCAAsC;AACvC,OAAO,KAAK,EAAE,mBAAmB,EAAE,kCAAkC;AACrE,OAAO,KAAK,EACV,+BAA+B,EAC/B,iCAAiC,EACjC,kCAAkC,EACnC,qCAAqC;AACtC,OAAO,KAAK,EAAE,iBAAiB,IAAI,qCAAqC,EAAE,oCAAoC;AAE9G,OAAO,KAAK,EACV,wBAAwB,EACxB,WAAW,EACZ,uCAAmC;
|
|
1
|
+
{"version":3,"file":"types.d.mts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.mjs","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n AccountsControllerAccountAddedEvent,\n AccountsControllerAccountRemovedEvent,\n AccountsControllerGetAccountAction,\n AccountsControllerGetAccountByAddressAction,\n AccountsControllerListMultichainAccountsAction,\n} from '@metamask/accounts-controller';\nimport type { RestrictedMessenger } from '@metamask/base-controller';\nimport type {\n KeyringControllerGetStateAction,\n KeyringControllerStateChangeEvent,\n KeyringControllerWithKeyringAction,\n} from '@metamask/keyring-controller';\nimport type { HandleSnapRequest as SnapControllerHandleSnapRequestAction } from '@metamask/snaps-controllers';\n\nimport type {\n MultichainAccountService,\n serviceName,\n} from './MultichainAccountService';\n\nexport type MultichainAccountServiceGetMultichainAccountGroupAction = {\n type: `${typeof serviceName}:getMultichainAccountGroup`;\n handler: MultichainAccountService['getMultichainAccountGroup'];\n};\n\nexport type MultichainAccountServiceGetMultichainAccountGroupsAction = {\n type: `${typeof serviceName}:getMultichainAccountGroups`;\n handler: MultichainAccountService['getMultichainAccountGroups'];\n};\n\nexport type MultichainAccountServiceGetMultichainAccountWalletAction = {\n type: `${typeof serviceName}:getMultichainAccountWallet`;\n handler: MultichainAccountService['getMultichainAccountWallet'];\n};\n\nexport type MultichainAccountServiceGetMultichainAccountWalletsAction = {\n type: `${typeof serviceName}:getMultichainAccountWallets`;\n handler: MultichainAccountService['getMultichainAccountWallets'];\n};\n\nexport type MultichainAccountServiceCreateNextMultichainAccountGroupAction = {\n type: `${typeof serviceName}:createNextMultichainAccountGroup`;\n handler: MultichainAccountService['createNextMultichainAccountGroup'];\n};\n\nexport type MultichainAccountServiceCreateMultichainAccountGroupAction = {\n type: `${typeof serviceName}:createMultichainAccountGroup`;\n handler: MultichainAccountService['createMultichainAccountGroup'];\n};\n\nexport type MultichainAccountServiceSetBasicFunctionalityAction = {\n type: `${typeof serviceName}:setBasicFunctionality`;\n handler: MultichainAccountService['setBasicFunctionality'];\n};\n\nexport type MultichainAccountServiceAlignWalletAction = {\n type: `${typeof serviceName}:alignWallet`;\n handler: MultichainAccountService['alignWallet'];\n};\n\nexport type MultichainAccountServiceAlignWalletsAction = {\n type: `${typeof serviceName}:alignWallets`;\n handler: MultichainAccountService['alignWallets'];\n};\n\nexport type MultichainAccountServiceGetIsAlignmentInProgressAction = {\n type: `${typeof serviceName}:getIsAlignmentInProgress`;\n handler: MultichainAccountService['getIsAlignmentInProgress'];\n};\n\n/**\n * All actions that {@link MultichainAccountService} registers so that other\n * modules can call them.\n */\nexport type MultichainAccountServiceActions =\n | MultichainAccountServiceGetMultichainAccountGroupAction\n | MultichainAccountServiceGetMultichainAccountGroupsAction\n | MultichainAccountServiceGetMultichainAccountWalletAction\n | MultichainAccountServiceGetMultichainAccountWalletsAction\n | MultichainAccountServiceCreateNextMultichainAccountGroupAction\n | MultichainAccountServiceCreateMultichainAccountGroupAction\n | MultichainAccountServiceSetBasicFunctionalityAction\n | MultichainAccountServiceAlignWalletAction\n | MultichainAccountServiceAlignWalletsAction\n | MultichainAccountServiceGetIsAlignmentInProgressAction;\n\n/**\n * All events that {@link MultichainAccountService} publishes so that other modules\n * can subscribe to them.\n */\nexport type MultichainAccountServiceEvents = never;\n\n/**\n * All actions registered by other modules that {@link MultichainAccountService}\n * calls.\n */\nexport type AllowedActions =\n | AccountsControllerListMultichainAccountsAction\n | AccountsControllerGetAccountAction\n | AccountsControllerGetAccountByAddressAction\n | SnapControllerHandleSnapRequestAction\n | KeyringControllerWithKeyringAction\n | KeyringControllerGetStateAction;\n\n/**\n * All events published by other modules that {@link MultichainAccountService}\n * subscribes to.\n */\nexport type AllowedEvents =\n | KeyringControllerStateChangeEvent\n | AccountsControllerAccountAddedEvent\n | AccountsControllerAccountRemovedEvent;\n\n/**\n * The messenger restricted to actions and events that\n * {@link MultichainAccountService} needs to access.\n */\nexport type MultichainAccountServiceMessenger = RestrictedMessenger<\n 'MultichainAccountService',\n MultichainAccountServiceActions | AllowedActions,\n MultichainAccountServiceEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n"]}
|
|
1
|
+
{"version":3,"file":"types.mjs","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { MultichainAccountWalletId } from '@metamask/account-api';\nimport type {\n AccountsControllerAccountAddedEvent,\n AccountsControllerAccountRemovedEvent,\n AccountsControllerGetAccountAction,\n AccountsControllerGetAccountByAddressAction,\n AccountsControllerListMultichainAccountsAction,\n} from '@metamask/accounts-controller';\nimport type { RestrictedMessenger } from '@metamask/base-controller';\nimport type {\n KeyringControllerGetStateAction,\n KeyringControllerStateChangeEvent,\n KeyringControllerWithKeyringAction,\n} from '@metamask/keyring-controller';\nimport type { HandleSnapRequest as SnapControllerHandleSnapRequestAction } from '@metamask/snaps-controllers';\n\nimport type {\n MultichainAccountService,\n serviceName,\n} from './MultichainAccountService';\nimport type { MultichainAccountWalletTransientState } from './MultichainAccountWallet';\n\nexport type MultichainAccountServiceTransientState = {\n accountWalletsTransientState: {\n [\n walletId: MultichainAccountWalletId\n ]: MultichainAccountWalletTransientState;\n };\n};\n\nexport type MultichainAccountServiceGetMultichainAccountGroupAction = {\n type: `${typeof serviceName}:getMultichainAccountGroup`;\n handler: MultichainAccountService['getMultichainAccountGroup'];\n};\n\nexport type MultichainAccountServiceGetMultichainAccountGroupsAction = {\n type: `${typeof serviceName}:getMultichainAccountGroups`;\n handler: MultichainAccountService['getMultichainAccountGroups'];\n};\n\nexport type MultichainAccountServiceGetMultichainAccountWalletAction = {\n type: `${typeof serviceName}:getMultichainAccountWallet`;\n handler: MultichainAccountService['getMultichainAccountWallet'];\n};\n\nexport type MultichainAccountServiceGetMultichainAccountWalletsAction = {\n type: `${typeof serviceName}:getMultichainAccountWallets`;\n handler: MultichainAccountService['getMultichainAccountWallets'];\n};\n\nexport type MultichainAccountServiceCreateNextMultichainAccountGroupAction = {\n type: `${typeof serviceName}:createNextMultichainAccountGroup`;\n handler: MultichainAccountService['createNextMultichainAccountGroup'];\n};\n\nexport type MultichainAccountServiceCreateMultichainAccountGroupAction = {\n type: `${typeof serviceName}:createMultichainAccountGroup`;\n handler: MultichainAccountService['createMultichainAccountGroup'];\n};\n\nexport type MultichainAccountServiceSetBasicFunctionalityAction = {\n type: `${typeof serviceName}:setBasicFunctionality`;\n handler: MultichainAccountService['setBasicFunctionality'];\n};\n\nexport type MultichainAccountServiceAlignWalletAction = {\n type: `${typeof serviceName}:alignWallet`;\n handler: MultichainAccountService['alignWallet'];\n};\n\nexport type MultichainAccountServiceAlignWalletsAction = {\n type: `${typeof serviceName}:alignWallets`;\n handler: MultichainAccountService['alignWallets'];\n};\n\nexport type MultichainAccountServiceGetIsAlignmentInProgressAction = {\n type: `${typeof serviceName}:getIsAlignmentInProgress`;\n handler: MultichainAccountService['getIsAlignmentInProgress'];\n};\n\n/**\n * All actions that {@link MultichainAccountService} registers so that other\n * modules can call them.\n */\nexport type MultichainAccountServiceActions =\n | MultichainAccountServiceGetMultichainAccountGroupAction\n | MultichainAccountServiceGetMultichainAccountGroupsAction\n | MultichainAccountServiceGetMultichainAccountWalletAction\n | MultichainAccountServiceGetMultichainAccountWalletsAction\n | MultichainAccountServiceCreateNextMultichainAccountGroupAction\n | MultichainAccountServiceCreateMultichainAccountGroupAction\n | MultichainAccountServiceSetBasicFunctionalityAction\n | MultichainAccountServiceAlignWalletAction\n | MultichainAccountServiceAlignWalletsAction\n | MultichainAccountServiceGetIsAlignmentInProgressAction;\n\n/**\n * All events that {@link MultichainAccountService} publishes so that other modules\n * can subscribe to them.\n */\nexport type MultichainAccountServiceEvents = never;\n\n/**\n * All actions registered by other modules that {@link MultichainAccountService}\n * calls.\n */\nexport type AllowedActions =\n | AccountsControllerListMultichainAccountsAction\n | AccountsControllerGetAccountAction\n | AccountsControllerGetAccountByAddressAction\n | SnapControllerHandleSnapRequestAction\n | KeyringControllerWithKeyringAction\n | KeyringControllerGetStateAction;\n\n/**\n * All events published by other modules that {@link MultichainAccountService}\n * subscribes to.\n */\nexport type AllowedEvents =\n | KeyringControllerStateChangeEvent\n | AccountsControllerAccountAddedEvent\n | AccountsControllerAccountRemovedEvent;\n\n/**\n * The messenger restricted to actions and events that\n * {@link MultichainAccountService} needs to access.\n */\nexport type MultichainAccountServiceMessenger = RestrictedMessenger<\n 'MultichainAccountService',\n MultichainAccountServiceActions | AllowedActions,\n MultichainAccountServiceEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n"]}
|