@metamask-previews/multichain-account-service 0.0.0-preview-d05158e7 → 0.0.0-preview-21067ca7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/CHANGELOG.md +1 -1
  2. package/dist/MultichainAccountService.cjs +72 -2
  3. package/dist/MultichainAccountService.cjs.map +1 -1
  4. package/dist/MultichainAccountService.d.cts +26 -4
  5. package/dist/MultichainAccountService.d.cts.map +1 -1
  6. package/dist/MultichainAccountService.d.mts +26 -4
  7. package/dist/MultichainAccountService.d.mts.map +1 -1
  8. package/dist/MultichainAccountService.mjs +73 -3
  9. package/dist/MultichainAccountService.mjs.map +1 -1
  10. package/dist/providers/BaseAccountProvider.cjs +4 -19
  11. package/dist/providers/BaseAccountProvider.cjs.map +1 -1
  12. package/dist/providers/BaseAccountProvider.d.cts +5 -19
  13. package/dist/providers/BaseAccountProvider.d.cts.map +1 -1
  14. package/dist/providers/BaseAccountProvider.d.mts +5 -19
  15. package/dist/providers/BaseAccountProvider.d.mts.map +1 -1
  16. package/dist/providers/BaseAccountProvider.mjs +3 -17
  17. package/dist/providers/BaseAccountProvider.mjs.map +1 -1
  18. package/dist/providers/EvmAccountProvider.cjs.map +1 -1
  19. package/dist/providers/EvmAccountProvider.d.cts +2 -1
  20. package/dist/providers/EvmAccountProvider.d.cts.map +1 -1
  21. package/dist/providers/EvmAccountProvider.d.mts +2 -1
  22. package/dist/providers/EvmAccountProvider.d.mts.map +1 -1
  23. package/dist/providers/EvmAccountProvider.mjs.map +1 -1
  24. package/dist/providers/SolAccountProvider.cjs.map +1 -1
  25. package/dist/providers/SolAccountProvider.d.cts +2 -1
  26. package/dist/providers/SolAccountProvider.d.cts.map +1 -1
  27. package/dist/providers/SolAccountProvider.d.mts +2 -1
  28. package/dist/providers/SolAccountProvider.d.mts.map +1 -1
  29. package/dist/providers/SolAccountProvider.mjs.map +1 -1
  30. package/dist/tests/accounts.cjs +7 -3
  31. package/dist/tests/accounts.cjs.map +1 -1
  32. package/dist/tests/accounts.d.cts +1 -0
  33. package/dist/tests/accounts.d.cts.map +1 -1
  34. package/dist/tests/accounts.d.mts +1 -0
  35. package/dist/tests/accounts.d.mts.map +1 -1
  36. package/dist/tests/accounts.mjs +5 -1
  37. package/dist/tests/accounts.mjs.map +1 -1
  38. package/dist/tests/messenger.cjs +5 -1
  39. package/dist/tests/messenger.cjs.map +1 -1
  40. package/dist/tests/messenger.d.cts +2 -2
  41. package/dist/tests/messenger.d.cts.map +1 -1
  42. package/dist/tests/messenger.d.mts +2 -2
  43. package/dist/tests/messenger.d.mts.map +1 -1
  44. package/dist/tests/messenger.mjs +5 -1
  45. package/dist/tests/messenger.mjs.map +1 -1
  46. package/dist/types.cjs.map +1 -1
  47. package/dist/types.d.cts +2 -2
  48. package/dist/types.d.cts.map +1 -1
  49. package/dist/types.d.mts +2 -2
  50. package/dist/types.d.mts.map +1 -1
  51. package/dist/types.mjs.map +1 -1
  52. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
9
9
 
10
10
  ### Added
11
11
 
12
- - Add `MultichainAccountService` ([#6141](https://github.com/MetaMask/core/pull/6141))
12
+ - Add `MultichainAccountService` ([#6141](https://github.com/MetaMask/core/pull/6141)), ([#6165](https://github.com/MetaMask/core/pull/6165))
13
13
  - This service manages multichain accounts/wallets.
14
14
 
15
15
  [Unreleased]: https://github.com/MetaMask/core/
@@ -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 _MultichainAccountService_instances, _MultichainAccountService_messenger, _MultichainAccountService_providers, _MultichainAccountService_wallets, _MultichainAccountService_setMultichainAccountWallets, _MultichainAccountService_getWallet;
13
+ var _MultichainAccountService_instances, _MultichainAccountService_messenger, _MultichainAccountService_providers, _MultichainAccountService_wallets, _MultichainAccountService_reverse, _MultichainAccountService_handleOnAccountAdded, _MultichainAccountService_handleOnAccountRemoved, _MultichainAccountService_setMultichainAccountWallets, _MultichainAccountService_getWallet;
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.MultichainAccountService = void 0;
16
16
  const account_api_1 = require("@metamask/account-api");
@@ -42,8 +42,10 @@ class MultichainAccountService {
42
42
  _MultichainAccountService_messenger.set(this, void 0);
43
43
  _MultichainAccountService_providers.set(this, void 0);
44
44
  _MultichainAccountService_wallets.set(this, void 0);
45
+ _MultichainAccountService_reverse.set(this, void 0);
45
46
  __classPrivateFieldSet(this, _MultichainAccountService_messenger, messenger, "f");
46
47
  __classPrivateFieldSet(this, _MultichainAccountService_wallets, new Map(), "f");
48
+ __classPrivateFieldSet(this, _MultichainAccountService_reverse, new Map(), "f");
47
49
  // TODO: Rely on keyring capabilities once the keyring API is used by all keyrings.
48
50
  __classPrivateFieldSet(this, _MultichainAccountService_providers, [
49
51
  new EvmAccountProvider_1.EvmAccountProvider(__classPrivateFieldGet(this, _MultichainAccountService_messenger, "f")),
@@ -61,6 +63,43 @@ class MultichainAccountService {
61
63
  __classPrivateFieldGet(this, _MultichainAccountService_messenger, "f").subscribe('KeyringController:stateChange', (keyrings) => {
62
64
  __classPrivateFieldGet(this, _MultichainAccountService_instances, "m", _MultichainAccountService_setMultichainAccountWallets).call(this, keyrings);
63
65
  }, selectKeyringControllerKeyrings);
66
+ // Reverse mapping between account ID and their multichain wallet/account:
67
+ // QUESTION: Should we move the reverse mapping logic to the
68
+ // `MultichainAccount{,Wallet}` implementation instead? For now they do not
69
+ // store any accounts and they heavily rely on the `AccountProvider`s, which
70
+ // makes it hard to implement it there...
71
+ for (const wallet of __classPrivateFieldGet(this, _MultichainAccountService_wallets, "f").values()) {
72
+ for (const multichainAccount of wallet.getMultichainAccounts()) {
73
+ for (const account of multichainAccount.getAccounts()) {
74
+ __classPrivateFieldGet(this, _MultichainAccountService_reverse, "f").set(account.id, {
75
+ wallet,
76
+ multichainAccount,
77
+ });
78
+ }
79
+ }
80
+ }
81
+ __classPrivateFieldGet(this, _MultichainAccountService_messenger, "f").subscribe('AccountsController:accountAdded', (account) => __classPrivateFieldGet(this, _MultichainAccountService_instances, "m", _MultichainAccountService_handleOnAccountAdded).call(this, account));
82
+ __classPrivateFieldGet(this, _MultichainAccountService_messenger, "f").subscribe('AccountsController:accountRemoved', (id) => __classPrivateFieldGet(this, _MultichainAccountService_instances, "m", _MultichainAccountService_handleOnAccountRemoved).call(this, id));
83
+ }
84
+ /**
85
+ * Gets a reference to the wallet and multichain account for a given account ID.
86
+ *
87
+ * @param id - Account ID.
88
+ * @returns An object with references to the wallet and multichain account associated for
89
+ * that account ID, or undefined if this account ID is not part of any.
90
+ */
91
+ getMultichainAccountAndWallet(id) {
92
+ return __classPrivateFieldGet(this, _MultichainAccountService_reverse, "f").get(id);
93
+ }
94
+ /**
95
+ * Gets a reference to the multichain account wallet matching this entropy source.
96
+ *
97
+ * @param entropySource - The entropy source of the multichain account.
98
+ * @throws If none multichain account match this entropy.
99
+ * @returns A reference to the multichain account wallet.
100
+ */
101
+ getMultichainAccountWallet(entropySource) {
102
+ return __classPrivateFieldGet(this, _MultichainAccountService_instances, "m", _MultichainAccountService_getWallet).call(this, entropySource);
64
103
  }
65
104
  /**
66
105
  * Gets a reference to the multichain account matching this entropy source and group index.
@@ -91,7 +130,38 @@ class MultichainAccountService {
91
130
  }
92
131
  }
93
132
  exports.MultichainAccountService = MultichainAccountService;
94
- _MultichainAccountService_messenger = new WeakMap(), _MultichainAccountService_providers = new WeakMap(), _MultichainAccountService_wallets = new WeakMap(), _MultichainAccountService_instances = new WeakSet(), _MultichainAccountService_setMultichainAccountWallets = function _MultichainAccountService_setMultichainAccountWallets(keyrings) {
133
+ _MultichainAccountService_messenger = new WeakMap(), _MultichainAccountService_providers = new WeakMap(), _MultichainAccountService_wallets = new WeakMap(), _MultichainAccountService_reverse = new WeakMap(), _MultichainAccountService_instances = new WeakSet(), _MultichainAccountService_handleOnAccountAdded = function _MultichainAccountService_handleOnAccountAdded(account) {
134
+ // We completely omit non-BIP-44 accounts!
135
+ if (!(0, account_api_1.isBip44Account)(account)) {
136
+ return;
137
+ }
138
+ const wallet = __classPrivateFieldGet(this, _MultichainAccountService_wallets, "f").get((0, account_api_1.toMultichainAccountWalletId)(account.options.entropy.id));
139
+ if (wallet) {
140
+ // This new account might be a new multichain account, and the wallet might not
141
+ // know it yet, so we need to force-sync here.
142
+ wallet.sync();
143
+ // We should always have a wallet here, since we are refreshing that
144
+ // list when any keyring's states got changed.
145
+ const multichainAccount = wallet.getMultichainAccount(account.options.entropy.groupIndex);
146
+ if (multichainAccount) {
147
+ // Same here, this account should have been already grouped in that
148
+ // multichain account.
149
+ __classPrivateFieldGet(this, _MultichainAccountService_reverse, "f").set(account.id, {
150
+ wallet,
151
+ multichainAccount,
152
+ });
153
+ }
154
+ }
155
+ }, _MultichainAccountService_handleOnAccountRemoved = function _MultichainAccountService_handleOnAccountRemoved(id) {
156
+ // Force sync of the appropriate wallet if an account got removed.
157
+ const found = __classPrivateFieldGet(this, _MultichainAccountService_reverse, "f").get(id);
158
+ if (found) {
159
+ const { wallet } = found;
160
+ wallet.sync();
161
+ }
162
+ // Safe to call delete even if the `id` was not referencing a BIP-44 account.
163
+ __classPrivateFieldGet(this, _MultichainAccountService_reverse, "f").delete(id);
164
+ }, _MultichainAccountService_setMultichainAccountWallets = function _MultichainAccountService_setMultichainAccountWallets(keyrings) {
95
165
  for (const keyring of keyrings) {
96
166
  if (keyring.type === keyring_controller_1.KeyringTypes.hd) {
97
167
  // Only HD keyrings have an entropy source/SRP.
@@ -1 +1 @@
1
- {"version":3,"file":"MultichainAccountService.cjs","sourceRoot":"","sources":["../src/MultichainAccountService.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAIA,uDAI+B;AAM/B,qEAA4D;AAG5D,2EAAoE;AACpE,2EAAoE;AAUpE;;;;;GAKG;AACH,SAAS,+BAA+B,CAAC,KAA6B;IACpE,OAAO,KAAK,CAAC,QAAQ,CAAC;AACxB,CAAC;AAED;;GAEG;AACH,MAAa,wBAAwB;IAUnC;;;;;;OAMG;IACH,YAAY,EAAE,SAAS,EAAmC;;QAhBjD,sDAA8C;QAE9C,sDAA+C;QAE/C,oDAGP;QAUA,uBAAA,IAAI,uCAAc,SAAS,MAAA,CAAC;QAC5B,uBAAA,IAAI,qCAAY,IAAI,GAAG,EAAE,MAAA,CAAC;QAC1B,mFAAmF;QACnF,uBAAA,IAAI,uCAAc;YAChB,IAAI,uCAAkB,CAAC,uBAAA,IAAI,2CAAW,CAAC;YACvC,IAAI,uCAAkB,CAAC,uBAAA,IAAI,2CAAW,CAAC;SACxC,MAAA,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,IAAI;QACF,oCAAoC;QACpC,MAAM,KAAK,GAAG,uBAAA,IAAI,2CAAW,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;QACjE,uBAAA,IAAI,kGAA6B,MAAjC,IAAI,EAA8B,KAAK,CAAC,QAAQ,CAAC,CAAC;QAElD,uBAAA,IAAI,2CAAW,CAAC,SAAS,CACvB,+BAA+B,EAC/B,CAAC,QAAQ,EAAE,EAAE;YACX,uBAAA,IAAI,kGAA6B,MAAjC,IAAI,EAA8B,QAAQ,CAAC,CAAC;QAC9C,CAAC,EACD,+BAA+B,CAChC,CAAC;IACJ,CAAC;IAuCD;;;;;;;;OAQG;IACH,oBAAoB,CAAC,EACnB,aAAa,EACb,UAAU,GAIX;QACC,MAAM,iBAAiB,GACrB,uBAAA,IAAI,gFAAW,MAAf,IAAI,EAAY,aAAa,CAAC,CAAC,oBAAoB,CAAC,UAAU,CAAC,CAAC;QAElE,IAAI,CAAC,iBAAiB,EAAE;YACtB,MAAM,IAAI,KAAK,CAAC,oCAAoC,UAAU,EAAE,CAAC,CAAC;SACnE;QAED,OAAO,iBAAiB,CAAC;IAC3B,CAAC;IAED;;;;;;;OAOG;IACH,qBAAqB,CAAC,EACpB,aAAa,GAGd;QACC,OAAO,uBAAA,IAAI,gFAAW,MAAf,IAAI,EAAY,aAAa,CAAC,CAAC,qBAAqB,EAAE,CAAC;IAChE,CAAC;CACF;AA3HD,4DA2HC;yUA9E8B,QAAyB;IACpD,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE;QAC9B,IAAI,OAAO,CAAC,IAAI,KAAM,iCAAY,CAAC,EAAa,EAAE;YAChD,+CAA+C;YAC/C,MAAM,aAAa,GAAG,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;YAE1C,qFAAqF;YACrF,iFAAiF;YACjF,4DAA4D;YAC5D,IAAI,CAAC,uBAAA,IAAI,yCAAS,CAAC,GAAG,CAAC,IAAA,yCAA2B,EAAC,aAAa,CAAC,CAAC,EAAE;gBAClE,8EAA8E;gBAC9E,2DAA2D;gBAC3D,MAAM,MAAM,GAAG,IAAI,qCAAuB,CAAC;oBACzC,aAAa;oBACb,SAAS,EAAE,uBAAA,IAAI,2CAAW;iBAC3B,CAAC,CAAC;gBAEH,uBAAA,IAAI,yCAAS,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;aACtC;SACF;KACF;AACH,CAAC,qFAGC,aAA8B;IAE9B,MAAM,MAAM,GAAG,uBAAA,IAAI,yCAAS,CAAC,GAAG,CAC9B,IAAA,yCAA2B,EAAC,aAAa,CAAC,CAC3C,CAAC;IAEF,IAAI,CAAC,MAAM,EAAE;QACX,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;KAC3E;IAED,OAAO,MAAM,CAAC;AAChB,CAAC","sourcesContent":["import type {\n MultichainAccountWalletId,\n AccountProvider,\n} from '@metamask/account-api';\nimport {\n MultichainAccountWallet,\n toMultichainAccountWalletId,\n type MultichainAccount,\n} from '@metamask/account-api';\nimport type { EntropySourceId } from '@metamask/keyring-api';\nimport type {\n KeyringControllerState,\n KeyringObject,\n} from '@metamask/keyring-controller';\nimport { KeyringTypes } from '@metamask/keyring-controller';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\n\nimport { EvmAccountProvider } from './providers/EvmAccountProvider';\nimport { SolAccountProvider } from './providers/SolAccountProvider';\nimport type { MultichainAccountServiceMessenger } from './types';\n\n/**\n * The options that {@link MultichainAccountService} takes.\n */\ntype MultichainAccountServiceOptions = {\n messenger: MultichainAccountServiceMessenger;\n};\n\n/**\n * Select keyrings from keyring controller state.\n *\n * @param state - The keyring controller state.\n * @returns The keyrings.\n */\nfunction selectKeyringControllerKeyrings(state: KeyringControllerState) {\n return state.keyrings;\n}\n\n/**\n * Service to expose multichain accounts capabilities.\n */\nexport class MultichainAccountService {\n readonly #messenger: MultichainAccountServiceMessenger;\n\n readonly #providers: AccountProvider<InternalAccount>[];\n\n readonly #wallets: Map<\n MultichainAccountWalletId,\n MultichainAccountWallet<InternalAccount>\n >;\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 */\n constructor({ messenger }: MultichainAccountServiceOptions) {\n this.#messenger = messenger;\n this.#wallets = new Map();\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 SolAccountProvider(this.#messenger),\n ];\n }\n\n /**\n * Initialize the service and constructs the internal reprensentation of\n * multichain accounts and wallets.\n */\n init(): void {\n // Gather all entropy sources first.\n const state = this.#messenger.call('KeyringController:getState');\n this.#setMultichainAccountWallets(state.keyrings);\n\n this.#messenger.subscribe(\n 'KeyringController:stateChange',\n (keyrings) => {\n this.#setMultichainAccountWallets(keyrings);\n },\n selectKeyringControllerKeyrings,\n );\n }\n\n #setMultichainAccountWallets(keyrings: KeyringObject[]) {\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 // Do not re-create wallets if they exists. Even if a keyrings got new accounts, this\n // will be handled by the `*AccountProvider`s which are always in-sync with their\n // keyrings and controllers (like the `AccountsController`).\n if (!this.#wallets.has(toMultichainAccountWalletId(entropySource))) {\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\n this.#wallets.set(wallet.id, wallet);\n }\n }\n }\n }\n\n #getWallet(\n entropySource: EntropySourceId,\n ): MultichainAccountWallet<InternalAccount> {\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 a reference to the multichain account matching this entropy source and 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 getMultichainAccount({\n entropySource,\n groupIndex,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }): MultichainAccount<InternalAccount> {\n const multichainAccount =\n this.#getWallet(entropySource).getMultichainAccount(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 accounts 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 getMultichainAccounts({\n entropySource,\n }: {\n entropySource: EntropySourceId;\n }): MultichainAccount<InternalAccount>[] {\n return this.#getWallet(entropySource).getMultichainAccounts();\n }\n}\n"]}
1
+ {"version":3,"file":"MultichainAccountService.cjs","sourceRoot":"","sources":["../src/MultichainAccountService.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAKA,uDAK+B;AAM/B,qEAA4D;AAG5D,2EAAoE;AACpE,2EAAoE;AAUpE;;;;;GAKG;AACH,SAAS,+BAA+B,CAAC,KAA6B;IACpE,OAAO,KAAK,CAAC,QAAQ,CAAC;AACxB,CAAC;AAQD;;GAEG;AACH,MAAa,wBAAwB;IAenC;;;;;;OAMG;IACH,YAAY,EAAE,SAAS,EAAmC;;QArBjD,sDAA8C;QAE9C,sDAA6D;QAE7D,oDAGP;QAEO,oDAGP;QAUA,uBAAA,IAAI,uCAAc,SAAS,MAAA,CAAC;QAC5B,uBAAA,IAAI,qCAAY,IAAI,GAAG,EAAE,MAAA,CAAC;QAC1B,uBAAA,IAAI,qCAAY,IAAI,GAAG,EAAE,MAAA,CAAC;QAC1B,mFAAmF;QACnF,uBAAA,IAAI,uCAAc;YAChB,IAAI,uCAAkB,CAAC,uBAAA,IAAI,2CAAW,CAAC;YACvC,IAAI,uCAAkB,CAAC,uBAAA,IAAI,2CAAW,CAAC;SACxC,MAAA,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,IAAI;QACF,oCAAoC;QACpC,MAAM,KAAK,GAAG,uBAAA,IAAI,2CAAW,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;QACjE,uBAAA,IAAI,kGAA6B,MAAjC,IAAI,EAA8B,KAAK,CAAC,QAAQ,CAAC,CAAC;QAElD,uBAAA,IAAI,2CAAW,CAAC,SAAS,CACvB,+BAA+B,EAC/B,CAAC,QAAQ,EAAE,EAAE;YACX,uBAAA,IAAI,kGAA6B,MAAjC,IAAI,EAA8B,QAAQ,CAAC,CAAC;QAC9C,CAAC,EACD,+BAA+B,CAChC,CAAC;QAEF,0EAA0E;QAC1E,4DAA4D;QAC5D,2EAA2E;QAC3E,4EAA4E;QAC5E,yCAAyC;QACzC,KAAK,MAAM,MAAM,IAAI,uBAAA,IAAI,yCAAS,CAAC,MAAM,EAAE,EAAE;YAC3C,KAAK,MAAM,iBAAiB,IAAI,MAAM,CAAC,qBAAqB,EAAE,EAAE;gBAC9D,KAAK,MAAM,OAAO,IAAI,iBAAiB,CAAC,WAAW,EAAE,EAAE;oBACrD,uBAAA,IAAI,yCAAS,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE;wBAC5B,MAAM;wBACN,iBAAiB;qBAClB,CAAC,CAAC;iBACJ;aACF;SACF;QAED,uBAAA,IAAI,2CAAW,CAAC,SAAS,CAAC,iCAAiC,EAAE,CAAC,OAAO,EAAE,EAAE,CACvE,uBAAA,IAAI,2FAAsB,MAA1B,IAAI,EAAuB,OAAO,CAAC,CACpC,CAAC;QACF,uBAAA,IAAI,2CAAW,CAAC,SAAS,CAAC,mCAAmC,EAAE,CAAC,EAAE,EAAE,EAAE,CACpE,uBAAA,IAAI,6FAAwB,MAA5B,IAAI,EAAyB,EAAE,CAAC,CACjC,CAAC;IACJ,CAAC;IAkFD;;;;;;OAMG;IACH,6BAA6B,CAC3B,EAAyB;QAEzB,OAAO,uBAAA,IAAI,yCAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC/B,CAAC;IAED;;;;;;OAMG;IACH,0BAA0B,CACxB,aAA8B;QAE9B,OAAO,uBAAA,IAAI,gFAAW,MAAf,IAAI,EAAY,aAAa,CAAC,CAAC;IACxC,CAAC;IAED;;;;;;;;OAQG;IACH,oBAAoB,CAAC,EACnB,aAAa,EACb,UAAU,GAIX;QACC,MAAM,iBAAiB,GACrB,uBAAA,IAAI,gFAAW,MAAf,IAAI,EAAY,aAAa,CAAC,CAAC,oBAAoB,CAAC,UAAU,CAAC,CAAC;QAElE,IAAI,CAAC,iBAAiB,EAAE;YACtB,MAAM,IAAI,KAAK,CAAC,oCAAoC,UAAU,EAAE,CAAC,CAAC;SACnE;QAED,OAAO,iBAAiB,CAAC;IAC3B,CAAC;IAED;;;;;;;OAOG;IACH,qBAAqB,CAAC,EACpB,aAAa,GAGd;QACC,OAAO,uBAAA,IAAI,gFAAW,MAAf,IAAI,EAAY,aAAa,CAAC,CAAC,qBAAqB,EAAE,CAAC;IAChE,CAAC;CACF;AA7ND,4DA6NC;8WAnJuB,OAAwB;IAC5C,0CAA0C;IAC1C,IAAI,CAAC,IAAA,4BAAc,EAAC,OAAO,CAAC,EAAE;QAC5B,OAAO;KACR;IAED,MAAM,MAAM,GAAG,uBAAA,IAAI,yCAAS,CAAC,GAAG,CAC9B,IAAA,yCAA2B,EAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CACxD,CAAC;IACF,IAAI,MAAM,EAAE;QACV,+EAA+E;QAC/E,8CAA8C;QAC9C,MAAM,CAAC,IAAI,EAAE,CAAC;QAEd,oEAAoE;QACpE,8CAA8C;QAC9C,MAAM,iBAAiB,GAAG,MAAM,CAAC,oBAAoB,CACnD,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,CACnC,CAAC;QACF,IAAI,iBAAiB,EAAE;YACrB,mEAAmE;YACnE,sBAAsB;YACtB,uBAAA,IAAI,yCAAS,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE;gBAC5B,MAAM;gBACN,iBAAiB;aAClB,CAAC,CAAC;SACJ;KACF;AACH,CAAC,+GAEuB,EAAyB;IAC/C,kEAAkE;IAClE,MAAM,KAAK,GAAG,uBAAA,IAAI,yCAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACpC,IAAI,KAAK,EAAE;QACT,MAAM,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;QAEzB,MAAM,CAAC,IAAI,EAAE,CAAC;KACf;IAED,6EAA6E;IAC7E,uBAAA,IAAI,yCAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAC3B,CAAC,yHAE4B,QAAyB;IACpD,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE;QAC9B,IAAI,OAAO,CAAC,IAAI,KAAM,iCAAY,CAAC,EAAa,EAAE;YAChD,+CAA+C;YAC/C,MAAM,aAAa,GAAG,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;YAE1C,qFAAqF;YACrF,iFAAiF;YACjF,4DAA4D;YAC5D,IAAI,CAAC,uBAAA,IAAI,yCAAS,CAAC,GAAG,CAAC,IAAA,yCAA2B,EAAC,aAAa,CAAC,CAAC,EAAE;gBAClE,8EAA8E;gBAC9E,2DAA2D;gBAC3D,MAAM,MAAM,GAAG,IAAI,qCAAuB,CAAC;oBACzC,aAAa;oBACb,SAAS,EAAE,uBAAA,IAAI,2CAAW;iBAC3B,CAAC,CAAC;gBAEH,uBAAA,IAAI,yCAAS,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;aACtC;SACF;KACF;AACH,CAAC,qFAGC,aAA8B;IAE9B,MAAM,MAAM,GAAG,uBAAA,IAAI,yCAAS,CAAC,GAAG,CAC9B,IAAA,yCAA2B,EAAC,aAAa,CAAC,CAC3C,CAAC;IAEF,IAAI,CAAC,MAAM,EAAE;QACX,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;KAC3E;IAED,OAAO,MAAM,CAAC;AAChB,CAAC","sourcesContent":["import type {\n MultichainAccountWalletId,\n AccountProvider,\n Bip44Account,\n} from '@metamask/account-api';\nimport {\n isBip44Account,\n MultichainAccountWallet,\n toMultichainAccountWalletId,\n type MultichainAccount,\n} from '@metamask/account-api';\nimport type { EntropySourceId, KeyringAccount } from '@metamask/keyring-api';\nimport type {\n KeyringControllerState,\n KeyringObject,\n} from '@metamask/keyring-controller';\nimport { KeyringTypes } from '@metamask/keyring-controller';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\n\nimport { EvmAccountProvider } from './providers/EvmAccountProvider';\nimport { SolAccountProvider } from './providers/SolAccountProvider';\nimport type { MultichainAccountServiceMessenger } from './types';\n\n/**\n * The options that {@link MultichainAccountService} takes.\n */\ntype MultichainAccountServiceOptions = {\n messenger: MultichainAccountServiceMessenger;\n};\n\n/**\n * Select keyrings from keyring controller state.\n *\n * @param state - The keyring controller state.\n * @returns The keyrings.\n */\nfunction selectKeyringControllerKeyrings(state: KeyringControllerState) {\n return state.keyrings;\n}\n\n/** Reverse mapping object used to map account IDs and their wallet/multichain account. */\ntype AccountReverseMapping<Account extends Bip44Account<KeyringAccount>> = {\n wallet: MultichainAccountWallet<Account>;\n multichainAccount: MultichainAccount<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<InternalAccount>>[];\n\n readonly #wallets: Map<\n MultichainAccountWalletId,\n MultichainAccountWallet<Bip44Account<InternalAccount>>\n >;\n\n readonly #reverse: Map<\n InternalAccount['id'],\n AccountReverseMapping<Bip44Account<InternalAccount>>\n >;\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 */\n constructor({ messenger }: MultichainAccountServiceOptions) {\n this.#messenger = messenger;\n this.#wallets = new Map();\n this.#reverse = new Map();\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 SolAccountProvider(this.#messenger),\n ];\n }\n\n /**\n * Initialize the service and constructs the internal reprensentation of\n * multichain accounts and wallets.\n */\n init(): void {\n // Gather all entropy sources first.\n const state = this.#messenger.call('KeyringController:getState');\n this.#setMultichainAccountWallets(state.keyrings);\n\n this.#messenger.subscribe(\n 'KeyringController:stateChange',\n (keyrings) => {\n this.#setMultichainAccountWallets(keyrings);\n },\n selectKeyringControllerKeyrings,\n );\n\n // Reverse mapping between account ID and their multichain wallet/account:\n // QUESTION: Should we move the reverse mapping logic to the\n // `MultichainAccount{,Wallet}` implementation instead? For now they do not\n // store any accounts and they heavily rely on the `AccountProvider`s, which\n // makes it hard to implement it there...\n for (const wallet of this.#wallets.values()) {\n for (const multichainAccount of wallet.getMultichainAccounts()) {\n for (const account of multichainAccount.getAccounts()) {\n this.#reverse.set(account.id, {\n wallet,\n multichainAccount,\n });\n }\n }\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 #handleOnAccountAdded(account: InternalAccount): void {\n // We completely omit non-BIP-44 accounts!\n if (!isBip44Account(account)) {\n return;\n }\n\n const wallet = this.#wallets.get(\n toMultichainAccountWalletId(account.options.entropy.id),\n );\n if (wallet) {\n // This new account might be a new multichain account, and the wallet might not\n // know it yet, so we need to force-sync here.\n wallet.sync();\n\n // We should always have a wallet here, since we are refreshing that\n // list when any keyring's states got changed.\n const multichainAccount = wallet.getMultichainAccount(\n account.options.entropy.groupIndex,\n );\n if (multichainAccount) {\n // Same here, this account should have been already grouped in that\n // multichain account.\n this.#reverse.set(account.id, {\n wallet,\n multichainAccount,\n });\n }\n }\n }\n\n #handleOnAccountRemoved(id: InternalAccount['id']): void {\n // Force sync of the appropriate wallet if an account got removed.\n const found = this.#reverse.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.#reverse.delete(id);\n }\n\n #setMultichainAccountWallets(keyrings: KeyringObject[]) {\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 // Do not re-create wallets if they exists. Even if a keyrings got new accounts, this\n // will be handled by the `*AccountProvider`s which are always in-sync with their\n // keyrings and controllers (like the `AccountsController`).\n if (!this.#wallets.has(toMultichainAccountWalletId(entropySource))) {\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\n this.#wallets.set(wallet.id, wallet);\n }\n }\n }\n }\n\n #getWallet(\n entropySource: EntropySourceId,\n ): MultichainAccountWallet<Bip44Account<InternalAccount>> {\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 a reference to the wallet and multichain account for a given account ID.\n *\n * @param id - Account ID.\n * @returns An object with references to the wallet and multichain account associated for\n * that account ID, or undefined if this account ID is not part of any.\n */\n getMultichainAccountAndWallet(\n id: InternalAccount['id'],\n ): AccountReverseMapping<Bip44Account<InternalAccount>> | undefined {\n return this.#reverse.get(id);\n }\n\n /**\n * Gets a reference to the multichain account wallet matching this entropy source.\n *\n * @param 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: EntropySourceId,\n ): MultichainAccountWallet<Bip44Account<InternalAccount>> {\n return this.#getWallet(entropySource);\n }\n\n /**\n * Gets a reference to the multichain account matching this entropy source and 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 getMultichainAccount({\n entropySource,\n groupIndex,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }): MultichainAccount<Bip44Account<InternalAccount>> {\n const multichainAccount =\n this.#getWallet(entropySource).getMultichainAccount(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 accounts 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 getMultichainAccounts({\n entropySource,\n }: {\n entropySource: EntropySourceId;\n }): MultichainAccount<Bip44Account<InternalAccount>>[] {\n return this.#getWallet(entropySource).getMultichainAccounts();\n }\n}\n"]}
@@ -1,5 +1,6 @@
1
- import { type MultichainAccount } from "@metamask/account-api";
2
- import type { EntropySourceId } from "@metamask/keyring-api";
1
+ import type { Bip44Account } from "@metamask/account-api";
2
+ import { MultichainAccountWallet, type MultichainAccount } from "@metamask/account-api";
3
+ import type { EntropySourceId, KeyringAccount } from "@metamask/keyring-api";
3
4
  import type { InternalAccount } from "@metamask/keyring-internal-api";
4
5
  import type { MultichainAccountServiceMessenger } from "./types.cjs";
5
6
  /**
@@ -8,6 +9,11 @@ import type { MultichainAccountServiceMessenger } from "./types.cjs";
8
9
  type MultichainAccountServiceOptions = {
9
10
  messenger: MultichainAccountServiceMessenger;
10
11
  };
12
+ /** Reverse mapping object used to map account IDs and their wallet/multichain account. */
13
+ type AccountReverseMapping<Account extends Bip44Account<KeyringAccount>> = {
14
+ wallet: MultichainAccountWallet<Account>;
15
+ multichainAccount: MultichainAccount<Account>;
16
+ };
11
17
  /**
12
18
  * Service to expose multichain accounts capabilities.
13
19
  */
@@ -26,6 +32,22 @@ export declare class MultichainAccountService {
26
32
  * multichain accounts and wallets.
27
33
  */
28
34
  init(): void;
35
+ /**
36
+ * Gets a reference to the wallet and multichain account for a given account ID.
37
+ *
38
+ * @param id - Account ID.
39
+ * @returns An object with references to the wallet and multichain account associated for
40
+ * that account ID, or undefined if this account ID is not part of any.
41
+ */
42
+ getMultichainAccountAndWallet(id: InternalAccount['id']): AccountReverseMapping<Bip44Account<InternalAccount>> | undefined;
43
+ /**
44
+ * Gets a reference to the multichain account wallet matching this entropy source.
45
+ *
46
+ * @param entropySource - The entropy source of the multichain account.
47
+ * @throws If none multichain account match this entropy.
48
+ * @returns A reference to the multichain account wallet.
49
+ */
50
+ getMultichainAccountWallet(entropySource: EntropySourceId): MultichainAccountWallet<Bip44Account<InternalAccount>>;
29
51
  /**
30
52
  * Gets a reference to the multichain account matching this entropy source and group index.
31
53
  *
@@ -38,7 +60,7 @@ export declare class MultichainAccountService {
38
60
  getMultichainAccount({ entropySource, groupIndex, }: {
39
61
  entropySource: EntropySourceId;
40
62
  groupIndex: number;
41
- }): MultichainAccount<InternalAccount>;
63
+ }): MultichainAccount<Bip44Account<InternalAccount>>;
42
64
  /**
43
65
  * Gets all multichain accounts for a given entropy source.
44
66
  *
@@ -49,7 +71,7 @@ export declare class MultichainAccountService {
49
71
  */
50
72
  getMultichainAccounts({ entropySource, }: {
51
73
  entropySource: EntropySourceId;
52
- }): MultichainAccount<InternalAccount>[];
74
+ }): MultichainAccount<Bip44Account<InternalAccount>>[];
53
75
  }
54
76
  export {};
55
77
  //# sourceMappingURL=MultichainAccountService.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"MultichainAccountService.d.cts","sourceRoot":"","sources":["../src/MultichainAccountService.ts"],"names":[],"mappings":"AAIA,OAAO,EAGL,KAAK,iBAAiB,EACvB,8BAA8B;AAC/B,OAAO,KAAK,EAAE,eAAe,EAAE,8BAA8B;AAM7D,OAAO,KAAK,EAAE,eAAe,EAAE,uCAAuC;AAItE,OAAO,KAAK,EAAE,iCAAiC,EAAE,oBAAgB;AAEjE;;GAEG;AACH,KAAK,+BAA+B,GAAG;IACrC,SAAS,EAAE,iCAAiC,CAAC;CAC9C,CAAC;AAYF;;GAEG;AACH,qBAAa,wBAAwB;;IAUnC;;;;;;OAMG;gBACS,EAAE,SAAS,EAAE,EAAE,+BAA+B;IAU1D;;;OAGG;IACH,IAAI,IAAI,IAAI;IAmDZ;;;;;;;;OAQG;IACH,oBAAoB,CAAC,EACnB,aAAa,EACb,UAAU,GACX,EAAE;QACD,aAAa,EAAE,eAAe,CAAC;QAC/B,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,iBAAiB,CAAC,eAAe,CAAC;IAWtC;;;;;;;OAOG;IACH,qBAAqB,CAAC,EACpB,aAAa,GACd,EAAE;QACD,aAAa,EAAE,eAAe,CAAC;KAChC,GAAG,iBAAiB,CAAC,eAAe,CAAC,EAAE;CAGzC"}
1
+ {"version":3,"file":"MultichainAccountService.d.cts","sourceRoot":"","sources":["../src/MultichainAccountService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGV,YAAY,EACb,8BAA8B;AAC/B,OAAO,EAEL,uBAAuB,EAEvB,KAAK,iBAAiB,EACvB,8BAA8B;AAC/B,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,8BAA8B;AAM7E,OAAO,KAAK,EAAE,eAAe,EAAE,uCAAuC;AAItE,OAAO,KAAK,EAAE,iCAAiC,EAAE,oBAAgB;AAEjE;;GAEG;AACH,KAAK,+BAA+B,GAAG;IACrC,SAAS,EAAE,iCAAiC,CAAC;CAC9C,CAAC;AAYF,0FAA0F;AAC1F,KAAK,qBAAqB,CAAC,OAAO,SAAS,YAAY,CAAC,cAAc,CAAC,IAAI;IACzE,MAAM,EAAE,uBAAuB,CAAC,OAAO,CAAC,CAAC;IACzC,iBAAiB,EAAE,iBAAiB,CAAC,OAAO,CAAC,CAAC;CAC/C,CAAC;AAEF;;GAEG;AACH,qBAAa,wBAAwB;;IAenC;;;;;;OAMG;gBACS,EAAE,SAAS,EAAE,EAAE,+BAA+B;IAW1D;;;OAGG;IACH,IAAI,IAAI,IAAI;IAqHZ;;;;;;OAMG;IACH,6BAA6B,CAC3B,EAAE,EAAE,eAAe,CAAC,IAAI,CAAC,GACxB,qBAAqB,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC,GAAG,SAAS;IAInE;;;;;;OAMG;IACH,0BAA0B,CACxB,aAAa,EAAE,eAAe,GAC7B,uBAAuB,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC;IAIzD;;;;;;;;OAQG;IACH,oBAAoB,CAAC,EACnB,aAAa,EACb,UAAU,GACX,EAAE;QACD,aAAa,EAAE,eAAe,CAAC;QAC/B,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,iBAAiB,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC;IAWpD;;;;;;;OAOG;IACH,qBAAqB,CAAC,EACpB,aAAa,GACd,EAAE;QACD,aAAa,EAAE,eAAe,CAAC;KAChC,GAAG,iBAAiB,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC,EAAE;CAGvD"}
@@ -1,5 +1,6 @@
1
- import { type MultichainAccount } from "@metamask/account-api";
2
- import type { EntropySourceId } from "@metamask/keyring-api";
1
+ import type { Bip44Account } from "@metamask/account-api";
2
+ import { MultichainAccountWallet, type MultichainAccount } from "@metamask/account-api";
3
+ import type { EntropySourceId, KeyringAccount } from "@metamask/keyring-api";
3
4
  import type { InternalAccount } from "@metamask/keyring-internal-api";
4
5
  import type { MultichainAccountServiceMessenger } from "./types.mjs";
5
6
  /**
@@ -8,6 +9,11 @@ import type { MultichainAccountServiceMessenger } from "./types.mjs";
8
9
  type MultichainAccountServiceOptions = {
9
10
  messenger: MultichainAccountServiceMessenger;
10
11
  };
12
+ /** Reverse mapping object used to map account IDs and their wallet/multichain account. */
13
+ type AccountReverseMapping<Account extends Bip44Account<KeyringAccount>> = {
14
+ wallet: MultichainAccountWallet<Account>;
15
+ multichainAccount: MultichainAccount<Account>;
16
+ };
11
17
  /**
12
18
  * Service to expose multichain accounts capabilities.
13
19
  */
@@ -26,6 +32,22 @@ export declare class MultichainAccountService {
26
32
  * multichain accounts and wallets.
27
33
  */
28
34
  init(): void;
35
+ /**
36
+ * Gets a reference to the wallet and multichain account for a given account ID.
37
+ *
38
+ * @param id - Account ID.
39
+ * @returns An object with references to the wallet and multichain account associated for
40
+ * that account ID, or undefined if this account ID is not part of any.
41
+ */
42
+ getMultichainAccountAndWallet(id: InternalAccount['id']): AccountReverseMapping<Bip44Account<InternalAccount>> | undefined;
43
+ /**
44
+ * Gets a reference to the multichain account wallet matching this entropy source.
45
+ *
46
+ * @param entropySource - The entropy source of the multichain account.
47
+ * @throws If none multichain account match this entropy.
48
+ * @returns A reference to the multichain account wallet.
49
+ */
50
+ getMultichainAccountWallet(entropySource: EntropySourceId): MultichainAccountWallet<Bip44Account<InternalAccount>>;
29
51
  /**
30
52
  * Gets a reference to the multichain account matching this entropy source and group index.
31
53
  *
@@ -38,7 +60,7 @@ export declare class MultichainAccountService {
38
60
  getMultichainAccount({ entropySource, groupIndex, }: {
39
61
  entropySource: EntropySourceId;
40
62
  groupIndex: number;
41
- }): MultichainAccount<InternalAccount>;
63
+ }): MultichainAccount<Bip44Account<InternalAccount>>;
42
64
  /**
43
65
  * Gets all multichain accounts for a given entropy source.
44
66
  *
@@ -49,7 +71,7 @@ export declare class MultichainAccountService {
49
71
  */
50
72
  getMultichainAccounts({ entropySource, }: {
51
73
  entropySource: EntropySourceId;
52
- }): MultichainAccount<InternalAccount>[];
74
+ }): MultichainAccount<Bip44Account<InternalAccount>>[];
53
75
  }
54
76
  export {};
55
77
  //# sourceMappingURL=MultichainAccountService.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"MultichainAccountService.d.mts","sourceRoot":"","sources":["../src/MultichainAccountService.ts"],"names":[],"mappings":"AAIA,OAAO,EAGL,KAAK,iBAAiB,EACvB,8BAA8B;AAC/B,OAAO,KAAK,EAAE,eAAe,EAAE,8BAA8B;AAM7D,OAAO,KAAK,EAAE,eAAe,EAAE,uCAAuC;AAItE,OAAO,KAAK,EAAE,iCAAiC,EAAE,oBAAgB;AAEjE;;GAEG;AACH,KAAK,+BAA+B,GAAG;IACrC,SAAS,EAAE,iCAAiC,CAAC;CAC9C,CAAC;AAYF;;GAEG;AACH,qBAAa,wBAAwB;;IAUnC;;;;;;OAMG;gBACS,EAAE,SAAS,EAAE,EAAE,+BAA+B;IAU1D;;;OAGG;IACH,IAAI,IAAI,IAAI;IAmDZ;;;;;;;;OAQG;IACH,oBAAoB,CAAC,EACnB,aAAa,EACb,UAAU,GACX,EAAE;QACD,aAAa,EAAE,eAAe,CAAC;QAC/B,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,iBAAiB,CAAC,eAAe,CAAC;IAWtC;;;;;;;OAOG;IACH,qBAAqB,CAAC,EACpB,aAAa,GACd,EAAE;QACD,aAAa,EAAE,eAAe,CAAC;KAChC,GAAG,iBAAiB,CAAC,eAAe,CAAC,EAAE;CAGzC"}
1
+ {"version":3,"file":"MultichainAccountService.d.mts","sourceRoot":"","sources":["../src/MultichainAccountService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGV,YAAY,EACb,8BAA8B;AAC/B,OAAO,EAEL,uBAAuB,EAEvB,KAAK,iBAAiB,EACvB,8BAA8B;AAC/B,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,8BAA8B;AAM7E,OAAO,KAAK,EAAE,eAAe,EAAE,uCAAuC;AAItE,OAAO,KAAK,EAAE,iCAAiC,EAAE,oBAAgB;AAEjE;;GAEG;AACH,KAAK,+BAA+B,GAAG;IACrC,SAAS,EAAE,iCAAiC,CAAC;CAC9C,CAAC;AAYF,0FAA0F;AAC1F,KAAK,qBAAqB,CAAC,OAAO,SAAS,YAAY,CAAC,cAAc,CAAC,IAAI;IACzE,MAAM,EAAE,uBAAuB,CAAC,OAAO,CAAC,CAAC;IACzC,iBAAiB,EAAE,iBAAiB,CAAC,OAAO,CAAC,CAAC;CAC/C,CAAC;AAEF;;GAEG;AACH,qBAAa,wBAAwB;;IAenC;;;;;;OAMG;gBACS,EAAE,SAAS,EAAE,EAAE,+BAA+B;IAW1D;;;OAGG;IACH,IAAI,IAAI,IAAI;IAqHZ;;;;;;OAMG;IACH,6BAA6B,CAC3B,EAAE,EAAE,eAAe,CAAC,IAAI,CAAC,GACxB,qBAAqB,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC,GAAG,SAAS;IAInE;;;;;;OAMG;IACH,0BAA0B,CACxB,aAAa,EAAE,eAAe,GAC7B,uBAAuB,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC;IAIzD;;;;;;;;OAQG;IACH,oBAAoB,CAAC,EACnB,aAAa,EACb,UAAU,GACX,EAAE;QACD,aAAa,EAAE,eAAe,CAAC;QAC/B,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,iBAAiB,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC;IAWpD;;;;;;;OAOG;IACH,qBAAqB,CAAC,EACpB,aAAa,GACd,EAAE;QACD,aAAa,EAAE,eAAe,CAAC;KAChC,GAAG,iBAAiB,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC,EAAE;CAGvD"}
@@ -9,8 +9,8 @@ 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_setMultichainAccountWallets, _MultichainAccountService_getWallet;
13
- import { MultichainAccountWallet, toMultichainAccountWalletId } from "@metamask/account-api";
12
+ var _MultichainAccountService_instances, _MultichainAccountService_messenger, _MultichainAccountService_providers, _MultichainAccountService_wallets, _MultichainAccountService_reverse, _MultichainAccountService_handleOnAccountAdded, _MultichainAccountService_handleOnAccountRemoved, _MultichainAccountService_setMultichainAccountWallets, _MultichainAccountService_getWallet;
13
+ import { isBip44Account, MultichainAccountWallet, toMultichainAccountWalletId } from "@metamask/account-api";
14
14
  import { KeyringTypes } from "@metamask/keyring-controller";
15
15
  import { EvmAccountProvider } from "./providers/EvmAccountProvider.mjs";
16
16
  import { SolAccountProvider } from "./providers/SolAccountProvider.mjs";
@@ -39,8 +39,10 @@ export class MultichainAccountService {
39
39
  _MultichainAccountService_messenger.set(this, void 0);
40
40
  _MultichainAccountService_providers.set(this, void 0);
41
41
  _MultichainAccountService_wallets.set(this, void 0);
42
+ _MultichainAccountService_reverse.set(this, void 0);
42
43
  __classPrivateFieldSet(this, _MultichainAccountService_messenger, messenger, "f");
43
44
  __classPrivateFieldSet(this, _MultichainAccountService_wallets, new Map(), "f");
45
+ __classPrivateFieldSet(this, _MultichainAccountService_reverse, new Map(), "f");
44
46
  // TODO: Rely on keyring capabilities once the keyring API is used by all keyrings.
45
47
  __classPrivateFieldSet(this, _MultichainAccountService_providers, [
46
48
  new EvmAccountProvider(__classPrivateFieldGet(this, _MultichainAccountService_messenger, "f")),
@@ -58,6 +60,43 @@ export class MultichainAccountService {
58
60
  __classPrivateFieldGet(this, _MultichainAccountService_messenger, "f").subscribe('KeyringController:stateChange', (keyrings) => {
59
61
  __classPrivateFieldGet(this, _MultichainAccountService_instances, "m", _MultichainAccountService_setMultichainAccountWallets).call(this, keyrings);
60
62
  }, selectKeyringControllerKeyrings);
63
+ // Reverse mapping between account ID and their multichain wallet/account:
64
+ // QUESTION: Should we move the reverse mapping logic to the
65
+ // `MultichainAccount{,Wallet}` implementation instead? For now they do not
66
+ // store any accounts and they heavily rely on the `AccountProvider`s, which
67
+ // makes it hard to implement it there...
68
+ for (const wallet of __classPrivateFieldGet(this, _MultichainAccountService_wallets, "f").values()) {
69
+ for (const multichainAccount of wallet.getMultichainAccounts()) {
70
+ for (const account of multichainAccount.getAccounts()) {
71
+ __classPrivateFieldGet(this, _MultichainAccountService_reverse, "f").set(account.id, {
72
+ wallet,
73
+ multichainAccount,
74
+ });
75
+ }
76
+ }
77
+ }
78
+ __classPrivateFieldGet(this, _MultichainAccountService_messenger, "f").subscribe('AccountsController:accountAdded', (account) => __classPrivateFieldGet(this, _MultichainAccountService_instances, "m", _MultichainAccountService_handleOnAccountAdded).call(this, account));
79
+ __classPrivateFieldGet(this, _MultichainAccountService_messenger, "f").subscribe('AccountsController:accountRemoved', (id) => __classPrivateFieldGet(this, _MultichainAccountService_instances, "m", _MultichainAccountService_handleOnAccountRemoved).call(this, id));
80
+ }
81
+ /**
82
+ * Gets a reference to the wallet and multichain account for a given account ID.
83
+ *
84
+ * @param id - Account ID.
85
+ * @returns An object with references to the wallet and multichain account associated for
86
+ * that account ID, or undefined if this account ID is not part of any.
87
+ */
88
+ getMultichainAccountAndWallet(id) {
89
+ return __classPrivateFieldGet(this, _MultichainAccountService_reverse, "f").get(id);
90
+ }
91
+ /**
92
+ * Gets a reference to the multichain account wallet matching this entropy source.
93
+ *
94
+ * @param entropySource - The entropy source of the multichain account.
95
+ * @throws If none multichain account match this entropy.
96
+ * @returns A reference to the multichain account wallet.
97
+ */
98
+ getMultichainAccountWallet(entropySource) {
99
+ return __classPrivateFieldGet(this, _MultichainAccountService_instances, "m", _MultichainAccountService_getWallet).call(this, entropySource);
61
100
  }
62
101
  /**
63
102
  * Gets a reference to the multichain account matching this entropy source and group index.
@@ -87,7 +126,38 @@ export class MultichainAccountService {
87
126
  return __classPrivateFieldGet(this, _MultichainAccountService_instances, "m", _MultichainAccountService_getWallet).call(this, entropySource).getMultichainAccounts();
88
127
  }
89
128
  }
90
- _MultichainAccountService_messenger = new WeakMap(), _MultichainAccountService_providers = new WeakMap(), _MultichainAccountService_wallets = new WeakMap(), _MultichainAccountService_instances = new WeakSet(), _MultichainAccountService_setMultichainAccountWallets = function _MultichainAccountService_setMultichainAccountWallets(keyrings) {
129
+ _MultichainAccountService_messenger = new WeakMap(), _MultichainAccountService_providers = new WeakMap(), _MultichainAccountService_wallets = new WeakMap(), _MultichainAccountService_reverse = new WeakMap(), _MultichainAccountService_instances = new WeakSet(), _MultichainAccountService_handleOnAccountAdded = function _MultichainAccountService_handleOnAccountAdded(account) {
130
+ // We completely omit non-BIP-44 accounts!
131
+ if (!isBip44Account(account)) {
132
+ return;
133
+ }
134
+ const wallet = __classPrivateFieldGet(this, _MultichainAccountService_wallets, "f").get(toMultichainAccountWalletId(account.options.entropy.id));
135
+ if (wallet) {
136
+ // This new account might be a new multichain account, and the wallet might not
137
+ // know it yet, so we need to force-sync here.
138
+ wallet.sync();
139
+ // We should always have a wallet here, since we are refreshing that
140
+ // list when any keyring's states got changed.
141
+ const multichainAccount = wallet.getMultichainAccount(account.options.entropy.groupIndex);
142
+ if (multichainAccount) {
143
+ // Same here, this account should have been already grouped in that
144
+ // multichain account.
145
+ __classPrivateFieldGet(this, _MultichainAccountService_reverse, "f").set(account.id, {
146
+ wallet,
147
+ multichainAccount,
148
+ });
149
+ }
150
+ }
151
+ }, _MultichainAccountService_handleOnAccountRemoved = function _MultichainAccountService_handleOnAccountRemoved(id) {
152
+ // Force sync of the appropriate wallet if an account got removed.
153
+ const found = __classPrivateFieldGet(this, _MultichainAccountService_reverse, "f").get(id);
154
+ if (found) {
155
+ const { wallet } = found;
156
+ wallet.sync();
157
+ }
158
+ // Safe to call delete even if the `id` was not referencing a BIP-44 account.
159
+ __classPrivateFieldGet(this, _MultichainAccountService_reverse, "f").delete(id);
160
+ }, _MultichainAccountService_setMultichainAccountWallets = function _MultichainAccountService_setMultichainAccountWallets(keyrings) {
91
161
  for (const keyring of keyrings) {
92
162
  if (keyring.type === KeyringTypes.hd) {
93
163
  // Only HD keyrings have an entropy source/SRP.
@@ -1 +1 @@
1
- {"version":3,"file":"MultichainAccountService.mjs","sourceRoot":"","sources":["../src/MultichainAccountService.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n MultichainAccountWalletId,\n AccountProvider,\n} from '@metamask/account-api';\nimport {\n MultichainAccountWallet,\n toMultichainAccountWalletId,\n type MultichainAccount,\n} from '@metamask/account-api';\nimport type { EntropySourceId } from '@metamask/keyring-api';\nimport type {\n KeyringControllerState,\n KeyringObject,\n} from '@metamask/keyring-controller';\nimport { KeyringTypes } from '@metamask/keyring-controller';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\n\nimport { EvmAccountProvider } from './providers/EvmAccountProvider';\nimport { SolAccountProvider } from './providers/SolAccountProvider';\nimport type { MultichainAccountServiceMessenger } from './types';\n\n/**\n * The options that {@link MultichainAccountService} takes.\n */\ntype MultichainAccountServiceOptions = {\n messenger: MultichainAccountServiceMessenger;\n};\n\n/**\n * Select keyrings from keyring controller state.\n *\n * @param state - The keyring controller state.\n * @returns The keyrings.\n */\nfunction selectKeyringControllerKeyrings(state: KeyringControllerState) {\n return state.keyrings;\n}\n\n/**\n * Service to expose multichain accounts capabilities.\n */\nexport class MultichainAccountService {\n readonly #messenger: MultichainAccountServiceMessenger;\n\n readonly #providers: AccountProvider<InternalAccount>[];\n\n readonly #wallets: Map<\n MultichainAccountWalletId,\n MultichainAccountWallet<InternalAccount>\n >;\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 */\n constructor({ messenger }: MultichainAccountServiceOptions) {\n this.#messenger = messenger;\n this.#wallets = new Map();\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 SolAccountProvider(this.#messenger),\n ];\n }\n\n /**\n * Initialize the service and constructs the internal reprensentation of\n * multichain accounts and wallets.\n */\n init(): void {\n // Gather all entropy sources first.\n const state = this.#messenger.call('KeyringController:getState');\n this.#setMultichainAccountWallets(state.keyrings);\n\n this.#messenger.subscribe(\n 'KeyringController:stateChange',\n (keyrings) => {\n this.#setMultichainAccountWallets(keyrings);\n },\n selectKeyringControllerKeyrings,\n );\n }\n\n #setMultichainAccountWallets(keyrings: KeyringObject[]) {\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 // Do not re-create wallets if they exists. Even if a keyrings got new accounts, this\n // will be handled by the `*AccountProvider`s which are always in-sync with their\n // keyrings and controllers (like the `AccountsController`).\n if (!this.#wallets.has(toMultichainAccountWalletId(entropySource))) {\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\n this.#wallets.set(wallet.id, wallet);\n }\n }\n }\n }\n\n #getWallet(\n entropySource: EntropySourceId,\n ): MultichainAccountWallet<InternalAccount> {\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 a reference to the multichain account matching this entropy source and 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 getMultichainAccount({\n entropySource,\n groupIndex,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }): MultichainAccount<InternalAccount> {\n const multichainAccount =\n this.#getWallet(entropySource).getMultichainAccount(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 accounts 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 getMultichainAccounts({\n entropySource,\n }: {\n entropySource: EntropySourceId;\n }): MultichainAccount<InternalAccount>[] {\n return this.#getWallet(entropySource).getMultichainAccounts();\n }\n}\n"]}
1
+ {"version":3,"file":"MultichainAccountService.mjs","sourceRoot":"","sources":["../src/MultichainAccountService.ts"],"names":[],"mappings":";;;;;;;;;;;;AAKA,OAAO,EACL,cAAc,EACd,uBAAuB,EACvB,2BAA2B,EAE5B,8BAA8B;AAM/B,OAAO,EAAE,YAAY,EAAE,qCAAqC;AAG5D,OAAO,EAAE,kBAAkB,EAAE,2CAAuC;AACpE,OAAO,EAAE,kBAAkB,EAAE,2CAAuC;AAUpE;;;;;GAKG;AACH,SAAS,+BAA+B,CAAC,KAA6B;IACpE,OAAO,KAAK,CAAC,QAAQ,CAAC;AACxB,CAAC;AAQD;;GAEG;AACH,MAAM,OAAO,wBAAwB;IAenC;;;;;;OAMG;IACH,YAAY,EAAE,SAAS,EAAmC;;QArBjD,sDAA8C;QAE9C,sDAA6D;QAE7D,oDAGP;QAEO,oDAGP;QAUA,uBAAA,IAAI,uCAAc,SAAS,MAAA,CAAC;QAC5B,uBAAA,IAAI,qCAAY,IAAI,GAAG,EAAE,MAAA,CAAC;QAC1B,uBAAA,IAAI,qCAAY,IAAI,GAAG,EAAE,MAAA,CAAC;QAC1B,mFAAmF;QACnF,uBAAA,IAAI,uCAAc;YAChB,IAAI,kBAAkB,CAAC,uBAAA,IAAI,2CAAW,CAAC;YACvC,IAAI,kBAAkB,CAAC,uBAAA,IAAI,2CAAW,CAAC;SACxC,MAAA,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,IAAI;QACF,oCAAoC;QACpC,MAAM,KAAK,GAAG,uBAAA,IAAI,2CAAW,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;QACjE,uBAAA,IAAI,kGAA6B,MAAjC,IAAI,EAA8B,KAAK,CAAC,QAAQ,CAAC,CAAC;QAElD,uBAAA,IAAI,2CAAW,CAAC,SAAS,CACvB,+BAA+B,EAC/B,CAAC,QAAQ,EAAE,EAAE;YACX,uBAAA,IAAI,kGAA6B,MAAjC,IAAI,EAA8B,QAAQ,CAAC,CAAC;QAC9C,CAAC,EACD,+BAA+B,CAChC,CAAC;QAEF,0EAA0E;QAC1E,4DAA4D;QAC5D,2EAA2E;QAC3E,4EAA4E;QAC5E,yCAAyC;QACzC,KAAK,MAAM,MAAM,IAAI,uBAAA,IAAI,yCAAS,CAAC,MAAM,EAAE,EAAE;YAC3C,KAAK,MAAM,iBAAiB,IAAI,MAAM,CAAC,qBAAqB,EAAE,EAAE;gBAC9D,KAAK,MAAM,OAAO,IAAI,iBAAiB,CAAC,WAAW,EAAE,EAAE;oBACrD,uBAAA,IAAI,yCAAS,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE;wBAC5B,MAAM;wBACN,iBAAiB;qBAClB,CAAC,CAAC;iBACJ;aACF;SACF;QAED,uBAAA,IAAI,2CAAW,CAAC,SAAS,CAAC,iCAAiC,EAAE,CAAC,OAAO,EAAE,EAAE,CACvE,uBAAA,IAAI,2FAAsB,MAA1B,IAAI,EAAuB,OAAO,CAAC,CACpC,CAAC;QACF,uBAAA,IAAI,2CAAW,CAAC,SAAS,CAAC,mCAAmC,EAAE,CAAC,EAAE,EAAE,EAAE,CACpE,uBAAA,IAAI,6FAAwB,MAA5B,IAAI,EAAyB,EAAE,CAAC,CACjC,CAAC;IACJ,CAAC;IAkFD;;;;;;OAMG;IACH,6BAA6B,CAC3B,EAAyB;QAEzB,OAAO,uBAAA,IAAI,yCAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC/B,CAAC;IAED;;;;;;OAMG;IACH,0BAA0B,CACxB,aAA8B;QAE9B,OAAO,uBAAA,IAAI,gFAAW,MAAf,IAAI,EAAY,aAAa,CAAC,CAAC;IACxC,CAAC;IAED;;;;;;;;OAQG;IACH,oBAAoB,CAAC,EACnB,aAAa,EACb,UAAU,GAIX;QACC,MAAM,iBAAiB,GACrB,uBAAA,IAAI,gFAAW,MAAf,IAAI,EAAY,aAAa,CAAC,CAAC,oBAAoB,CAAC,UAAU,CAAC,CAAC;QAElE,IAAI,CAAC,iBAAiB,EAAE;YACtB,MAAM,IAAI,KAAK,CAAC,oCAAoC,UAAU,EAAE,CAAC,CAAC;SACnE;QAED,OAAO,iBAAiB,CAAC;IAC3B,CAAC;IAED;;;;;;;OAOG;IACH,qBAAqB,CAAC,EACpB,aAAa,GAGd;QACC,OAAO,uBAAA,IAAI,gFAAW,MAAf,IAAI,EAAY,aAAa,CAAC,CAAC,qBAAqB,EAAE,CAAC;IAChE,CAAC;CACF;8WAnJuB,OAAwB;IAC5C,0CAA0C;IAC1C,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE;QAC5B,OAAO;KACR;IAED,MAAM,MAAM,GAAG,uBAAA,IAAI,yCAAS,CAAC,GAAG,CAC9B,2BAA2B,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CACxD,CAAC;IACF,IAAI,MAAM,EAAE;QACV,+EAA+E;QAC/E,8CAA8C;QAC9C,MAAM,CAAC,IAAI,EAAE,CAAC;QAEd,oEAAoE;QACpE,8CAA8C;QAC9C,MAAM,iBAAiB,GAAG,MAAM,CAAC,oBAAoB,CACnD,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,CACnC,CAAC;QACF,IAAI,iBAAiB,EAAE;YACrB,mEAAmE;YACnE,sBAAsB;YACtB,uBAAA,IAAI,yCAAS,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE;gBAC5B,MAAM;gBACN,iBAAiB;aAClB,CAAC,CAAC;SACJ;KACF;AACH,CAAC,+GAEuB,EAAyB;IAC/C,kEAAkE;IAClE,MAAM,KAAK,GAAG,uBAAA,IAAI,yCAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACpC,IAAI,KAAK,EAAE;QACT,MAAM,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;QAEzB,MAAM,CAAC,IAAI,EAAE,CAAC;KACf;IAED,6EAA6E;IAC7E,uBAAA,IAAI,yCAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAC3B,CAAC,yHAE4B,QAAyB;IACpD,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE;QAC9B,IAAI,OAAO,CAAC,IAAI,KAAM,YAAY,CAAC,EAAa,EAAE;YAChD,+CAA+C;YAC/C,MAAM,aAAa,GAAG,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;YAE1C,qFAAqF;YACrF,iFAAiF;YACjF,4DAA4D;YAC5D,IAAI,CAAC,uBAAA,IAAI,yCAAS,CAAC,GAAG,CAAC,2BAA2B,CAAC,aAAa,CAAC,CAAC,EAAE;gBAClE,8EAA8E;gBAC9E,2DAA2D;gBAC3D,MAAM,MAAM,GAAG,IAAI,uBAAuB,CAAC;oBACzC,aAAa;oBACb,SAAS,EAAE,uBAAA,IAAI,2CAAW;iBAC3B,CAAC,CAAC;gBAEH,uBAAA,IAAI,yCAAS,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;aACtC;SACF;KACF;AACH,CAAC,qFAGC,aAA8B;IAE9B,MAAM,MAAM,GAAG,uBAAA,IAAI,yCAAS,CAAC,GAAG,CAC9B,2BAA2B,CAAC,aAAa,CAAC,CAC3C,CAAC;IAEF,IAAI,CAAC,MAAM,EAAE;QACX,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;KAC3E;IAED,OAAO,MAAM,CAAC;AAChB,CAAC","sourcesContent":["import type {\n MultichainAccountWalletId,\n AccountProvider,\n Bip44Account,\n} from '@metamask/account-api';\nimport {\n isBip44Account,\n MultichainAccountWallet,\n toMultichainAccountWalletId,\n type MultichainAccount,\n} from '@metamask/account-api';\nimport type { EntropySourceId, KeyringAccount } from '@metamask/keyring-api';\nimport type {\n KeyringControllerState,\n KeyringObject,\n} from '@metamask/keyring-controller';\nimport { KeyringTypes } from '@metamask/keyring-controller';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\n\nimport { EvmAccountProvider } from './providers/EvmAccountProvider';\nimport { SolAccountProvider } from './providers/SolAccountProvider';\nimport type { MultichainAccountServiceMessenger } from './types';\n\n/**\n * The options that {@link MultichainAccountService} takes.\n */\ntype MultichainAccountServiceOptions = {\n messenger: MultichainAccountServiceMessenger;\n};\n\n/**\n * Select keyrings from keyring controller state.\n *\n * @param state - The keyring controller state.\n * @returns The keyrings.\n */\nfunction selectKeyringControllerKeyrings(state: KeyringControllerState) {\n return state.keyrings;\n}\n\n/** Reverse mapping object used to map account IDs and their wallet/multichain account. */\ntype AccountReverseMapping<Account extends Bip44Account<KeyringAccount>> = {\n wallet: MultichainAccountWallet<Account>;\n multichainAccount: MultichainAccount<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<InternalAccount>>[];\n\n readonly #wallets: Map<\n MultichainAccountWalletId,\n MultichainAccountWallet<Bip44Account<InternalAccount>>\n >;\n\n readonly #reverse: Map<\n InternalAccount['id'],\n AccountReverseMapping<Bip44Account<InternalAccount>>\n >;\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 */\n constructor({ messenger }: MultichainAccountServiceOptions) {\n this.#messenger = messenger;\n this.#wallets = new Map();\n this.#reverse = new Map();\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 SolAccountProvider(this.#messenger),\n ];\n }\n\n /**\n * Initialize the service and constructs the internal reprensentation of\n * multichain accounts and wallets.\n */\n init(): void {\n // Gather all entropy sources first.\n const state = this.#messenger.call('KeyringController:getState');\n this.#setMultichainAccountWallets(state.keyrings);\n\n this.#messenger.subscribe(\n 'KeyringController:stateChange',\n (keyrings) => {\n this.#setMultichainAccountWallets(keyrings);\n },\n selectKeyringControllerKeyrings,\n );\n\n // Reverse mapping between account ID and their multichain wallet/account:\n // QUESTION: Should we move the reverse mapping logic to the\n // `MultichainAccount{,Wallet}` implementation instead? For now they do not\n // store any accounts and they heavily rely on the `AccountProvider`s, which\n // makes it hard to implement it there...\n for (const wallet of this.#wallets.values()) {\n for (const multichainAccount of wallet.getMultichainAccounts()) {\n for (const account of multichainAccount.getAccounts()) {\n this.#reverse.set(account.id, {\n wallet,\n multichainAccount,\n });\n }\n }\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 #handleOnAccountAdded(account: InternalAccount): void {\n // We completely omit non-BIP-44 accounts!\n if (!isBip44Account(account)) {\n return;\n }\n\n const wallet = this.#wallets.get(\n toMultichainAccountWalletId(account.options.entropy.id),\n );\n if (wallet) {\n // This new account might be a new multichain account, and the wallet might not\n // know it yet, so we need to force-sync here.\n wallet.sync();\n\n // We should always have a wallet here, since we are refreshing that\n // list when any keyring's states got changed.\n const multichainAccount = wallet.getMultichainAccount(\n account.options.entropy.groupIndex,\n );\n if (multichainAccount) {\n // Same here, this account should have been already grouped in that\n // multichain account.\n this.#reverse.set(account.id, {\n wallet,\n multichainAccount,\n });\n }\n }\n }\n\n #handleOnAccountRemoved(id: InternalAccount['id']): void {\n // Force sync of the appropriate wallet if an account got removed.\n const found = this.#reverse.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.#reverse.delete(id);\n }\n\n #setMultichainAccountWallets(keyrings: KeyringObject[]) {\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 // Do not re-create wallets if they exists. Even if a keyrings got new accounts, this\n // will be handled by the `*AccountProvider`s which are always in-sync with their\n // keyrings and controllers (like the `AccountsController`).\n if (!this.#wallets.has(toMultichainAccountWalletId(entropySource))) {\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\n this.#wallets.set(wallet.id, wallet);\n }\n }\n }\n }\n\n #getWallet(\n entropySource: EntropySourceId,\n ): MultichainAccountWallet<Bip44Account<InternalAccount>> {\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 a reference to the wallet and multichain account for a given account ID.\n *\n * @param id - Account ID.\n * @returns An object with references to the wallet and multichain account associated for\n * that account ID, or undefined if this account ID is not part of any.\n */\n getMultichainAccountAndWallet(\n id: InternalAccount['id'],\n ): AccountReverseMapping<Bip44Account<InternalAccount>> | undefined {\n return this.#reverse.get(id);\n }\n\n /**\n * Gets a reference to the multichain account wallet matching this entropy source.\n *\n * @param 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: EntropySourceId,\n ): MultichainAccountWallet<Bip44Account<InternalAccount>> {\n return this.#getWallet(entropySource);\n }\n\n /**\n * Gets a reference to the multichain account matching this entropy source and 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 getMultichainAccount({\n entropySource,\n groupIndex,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }): MultichainAccount<Bip44Account<InternalAccount>> {\n const multichainAccount =\n this.#getWallet(entropySource).getMultichainAccount(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 accounts 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 getMultichainAccounts({\n entropySource,\n }: {\n entropySource: EntropySourceId;\n }): MultichainAccount<Bip44Account<InternalAccount>>[] {\n return this.#getWallet(entropySource).getMultichainAccounts();\n }\n}\n"]}
@@ -6,23 +6,8 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
6
6
  };
7
7
  var _BaseAccountProvider_instances, _BaseAccountProvider_getAccounts;
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.BaseAccountProvider = exports.isBip44Account = void 0;
10
- const keyring_api_1 = require("@metamask/keyring-api");
11
- /**
12
- * Checks if an account is BIP-44 compatible.
13
- *
14
- * @param account - The account to be tested.
15
- * @returns True if the account is BIP-44 compatible.
16
- */
17
- function isBip44Account(account) {
18
- if (!account.options.entropy ||
19
- account.options.entropy.type !== keyring_api_1.KeyringAccountEntropyTypeOption.Mnemonic) {
20
- console.warn("! Found an HD account with invalid entropy options: account won't be associated to its wallet.");
21
- return false;
22
- }
23
- return true;
24
- }
25
- exports.isBip44Account = isBip44Account;
9
+ exports.BaseAccountProvider = void 0;
10
+ const account_api_1 = require("@metamask/account-api");
26
11
  class BaseAccountProvider {
27
12
  constructor(messenger) {
28
13
  _BaseAccountProvider_instances.add(this);
@@ -48,8 +33,8 @@ _BaseAccountProvider_instances = new WeakSet(), _BaseAccountProvider_getAccounts
48
33
  // accounts, including EVM and non-EVM. We might wanna change this action
49
34
  // name once we fully support multichain accounts.
50
35
  'AccountsController:listMultichainAccounts')) {
51
- if (this.isAccountCompatible(account) &&
52
- isBip44Account(account) &&
36
+ if ((0, account_api_1.isBip44Account)(account) &&
37
+ this.isAccountCompatible(account) &&
53
38
  filter(account)) {
54
39
  accounts.push(account);
55
40
  }
@@ -1 +1 @@
1
- {"version":3,"file":"BaseAccountProvider.cjs","sourceRoot":"","sources":["../../src/providers/BaseAccountProvider.ts"],"names":[],"mappings":";;;;;;;;;AAMA,uDAAwE;AAWxE;;;;;GAKG;AACH,SAAgB,cAAc,CAC5B,OAAgB;IAEhB,IACE,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO;QACxB,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,KAAK,6CAA+B,CAAC,QAAQ,EACzE;QACA,OAAO,CAAC,IAAI,CACV,gGAAgG,CACjG,CAAC;QACF,OAAO,KAAK,CAAC;KACd;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAdD,wCAcC;AAED,MAAsB,mBAAmB;IAKvC,YAAY,SAA4C;;QACtD,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;IAyBD,WAAW;QACT,OAAO,uBAAA,IAAI,wEAAa,MAAjB,IAAI,CAAe,CAAC;IAC7B,CAAC;IAED,UAAU,CAAC,EAAa;QACtB,wDAAwD;QACxD,MAAM,CAAC,KAAK,CAAC,GAAG,uBAAA,IAAI,wEAAa,MAAjB,IAAI,EAAc,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;QAElE,IAAI,CAAC,KAAK,EAAE;YACV,MAAM,IAAI,KAAK,CAAC,2BAA2B,EAAE,EAAE,CAAC,CAAC;SAClD;QAED,OAAO,KAAK,CAAC;IACf,CAAC;CAGF;AAhDD,kDAgDC;6HAtCG,SAAgD,GAAG,EAAE,CAAC,IAAI;IAE1D,MAAM,QAAQ,GAAoC,EAAE,CAAC;IAErD,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI;IACvC,2EAA2E;IAC3E,yEAAyE;IACzE,kDAAkD;IAClD,2CAA2C,CAC5C,EAAE;QACD,IACE,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC;YACjC,cAAc,CAAC,OAAO,CAAC;YACvB,MAAM,CAAC,OAAO,CAAC,EACf;YACA,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;SACxB;KACF;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC","sourcesContent":["import type { AccountProvider } from '@metamask/account-api';\nimport type { AccountId } from '@metamask/accounts-controller';\nimport type {\n KeyringAccount,\n KeyringAccountEntropyMnemonicOptions,\n} from '@metamask/keyring-api';\nimport { KeyringAccountEntropyTypeOption } from '@metamask/keyring-api';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\n\nimport type { MultichainAccountServiceMessenger } from '../types';\n\nexport type Bip44Account<Account extends KeyringAccount> = Account & {\n options: {\n entropy: KeyringAccountEntropyMnemonicOptions;\n };\n};\n\n/**\n * Checks if an account is BIP-44 compatible.\n *\n * @param account - The account to be tested.\n * @returns True if the account is BIP-44 compatible.\n */\nexport function isBip44Account<Account extends KeyringAccount>(\n account: Account,\n): account is Bip44Account<Account> {\n if (\n !account.options.entropy ||\n account.options.entropy.type !== KeyringAccountEntropyTypeOption.Mnemonic\n ) {\n console.warn(\n \"! Found an HD account with invalid entropy options: account won't be associated to its wallet.\",\n );\n return false;\n }\n\n return true;\n}\n\nexport abstract class BaseAccountProvider\n implements AccountProvider<InternalAccount>\n{\n protected readonly messenger: MultichainAccountServiceMessenger;\n\n constructor(messenger: MultichainAccountServiceMessenger) {\n this.messenger = messenger;\n }\n\n #getAccounts(\n filter: (account: InternalAccount) => boolean = () => true,\n ): Bip44Account<InternalAccount>[] {\n const accounts: Bip44Account<InternalAccount>[] = [];\n\n for (const account of this.messenger.call(\n // NOTE: Even though the name is misleading, this only fetches all internal\n // accounts, including EVM and non-EVM. We might wanna change this action\n // name once we fully support multichain accounts.\n 'AccountsController:listMultichainAccounts',\n )) {\n if (\n this.isAccountCompatible(account) &&\n isBip44Account(account) &&\n filter(account)\n ) {\n accounts.push(account);\n }\n }\n\n return accounts;\n }\n\n getAccounts(): InternalAccount[] {\n return this.#getAccounts();\n }\n\n getAccount(id: AccountId): InternalAccount {\n // TODO: Maybe just use a proper find for faster lookup?\n const [found] = this.#getAccounts((account) => account.id === id);\n\n if (!found) {\n throw new Error(`Unable to find account: ${id}`);\n }\n\n return found;\n }\n\n abstract isAccountCompatible(account: InternalAccount): boolean;\n}\n"]}
1
+ {"version":3,"file":"BaseAccountProvider.cjs","sourceRoot":"","sources":["../../src/providers/BaseAccountProvider.ts"],"names":[],"mappings":";;;;;;;;;AAAA,uDAI+B;AAK/B,MAAsB,mBAAmB;IAKvC,YAAY,SAA4C;;QACtD,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;IAyBD,WAAW;QACT,OAAO,uBAAA,IAAI,wEAAa,MAAjB,IAAI,CAAe,CAAC;IAC7B,CAAC;IAED,UAAU,CAAC,EAAyB;QAClC,wDAAwD;QACxD,MAAM,CAAC,KAAK,CAAC,GAAG,uBAAA,IAAI,wEAAa,MAAjB,IAAI,EAAc,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;QAElE,IAAI,CAAC,KAAK,EAAE;YACV,MAAM,IAAI,KAAK,CAAC,2BAA2B,EAAE,EAAE,CAAC,CAAC;SAClD;QAED,OAAO,KAAK,CAAC;IACf,CAAC;CAGF;AAhDD,kDAgDC;6HAtCG,SAAgD,GAAG,EAAE,CAAC,IAAI;IAE1D,MAAM,QAAQ,GAAoC,EAAE,CAAC;IAErD,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI;IACvC,2EAA2E;IAC3E,yEAAyE;IACzE,kDAAkD;IAClD,2CAA2C,CAC5C,EAAE;QACD,IACE,IAAA,4BAAc,EAAC,OAAO,CAAC;YACvB,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC;YACjC,MAAM,CAAC,OAAO,CAAC,EACf;YACA,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;SACxB;KACF;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC","sourcesContent":["import {\n isBip44Account,\n type AccountProvider,\n type Bip44Account,\n} from '@metamask/account-api';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\n\nimport type { MultichainAccountServiceMessenger } from '../types';\n\nexport abstract class BaseAccountProvider\n implements AccountProvider<Bip44Account<InternalAccount>>\n{\n protected readonly messenger: MultichainAccountServiceMessenger;\n\n constructor(messenger: MultichainAccountServiceMessenger) {\n this.messenger = messenger;\n }\n\n #getAccounts(\n filter: (account: InternalAccount) => boolean = () => true,\n ): Bip44Account<InternalAccount>[] {\n const accounts: Bip44Account<InternalAccount>[] = [];\n\n for (const account of this.messenger.call(\n // NOTE: Even though the name is misleading, this only fetches all internal\n // accounts, including EVM and non-EVM. We might wanna change this action\n // name once we fully support multichain accounts.\n 'AccountsController:listMultichainAccounts',\n )) {\n if (\n isBip44Account(account) &&\n this.isAccountCompatible(account) &&\n filter(account)\n ) {\n accounts.push(account);\n }\n }\n\n return accounts;\n }\n\n getAccounts(): Bip44Account<InternalAccount>[] {\n return this.#getAccounts();\n }\n\n getAccount(id: InternalAccount['id']): Bip44Account<InternalAccount> {\n // TODO: Maybe just use a proper find for faster lookup?\n const [found] = this.#getAccounts((account) => account.id === id);\n\n if (!found) {\n throw new Error(`Unable to find account: ${id}`);\n }\n\n return found;\n }\n\n abstract isAccountCompatible(account: Bip44Account<InternalAccount>): boolean;\n}\n"]}
@@ -1,26 +1,12 @@
1
- import type { AccountProvider } from "@metamask/account-api";
2
- import type { AccountId } from "@metamask/accounts-controller";
3
- import type { KeyringAccount, KeyringAccountEntropyMnemonicOptions } from "@metamask/keyring-api";
1
+ import { type AccountProvider, type Bip44Account } from "@metamask/account-api";
4
2
  import type { InternalAccount } from "@metamask/keyring-internal-api";
5
3
  import type { MultichainAccountServiceMessenger } from "../types.cjs";
6
- export type Bip44Account<Account extends KeyringAccount> = Account & {
7
- options: {
8
- entropy: KeyringAccountEntropyMnemonicOptions;
9
- };
10
- };
11
- /**
12
- * Checks if an account is BIP-44 compatible.
13
- *
14
- * @param account - The account to be tested.
15
- * @returns True if the account is BIP-44 compatible.
16
- */
17
- export declare function isBip44Account<Account extends KeyringAccount>(account: Account): account is Bip44Account<Account>;
18
- export declare abstract class BaseAccountProvider implements AccountProvider<InternalAccount> {
4
+ export declare abstract class BaseAccountProvider implements AccountProvider<Bip44Account<InternalAccount>> {
19
5
  #private;
20
6
  protected readonly messenger: MultichainAccountServiceMessenger;
21
7
  constructor(messenger: MultichainAccountServiceMessenger);
22
- getAccounts(): InternalAccount[];
23
- getAccount(id: AccountId): InternalAccount;
24
- abstract isAccountCompatible(account: InternalAccount): boolean;
8
+ getAccounts(): Bip44Account<InternalAccount>[];
9
+ getAccount(id: InternalAccount['id']): Bip44Account<InternalAccount>;
10
+ abstract isAccountCompatible(account: Bip44Account<InternalAccount>): boolean;
25
11
  }
26
12
  //# sourceMappingURL=BaseAccountProvider.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"BaseAccountProvider.d.cts","sourceRoot":"","sources":["../../src/providers/BaseAccountProvider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,8BAA8B;AAC7D,OAAO,KAAK,EAAE,SAAS,EAAE,sCAAsC;AAC/D,OAAO,KAAK,EACV,cAAc,EACd,oCAAoC,EACrC,8BAA8B;AAE/B,OAAO,KAAK,EAAE,eAAe,EAAE,uCAAuC;AAEtE,OAAO,KAAK,EAAE,iCAAiC,EAAE,qBAAiB;AAElE,MAAM,MAAM,YAAY,CAAC,OAAO,SAAS,cAAc,IAAI,OAAO,GAAG;IACnE,OAAO,EAAE;QACP,OAAO,EAAE,oCAAoC,CAAC;KAC/C,CAAC;CACH,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,OAAO,SAAS,cAAc,EAC3D,OAAO,EAAE,OAAO,GACf,OAAO,IAAI,YAAY,CAAC,OAAO,CAAC,CAYlC;AAED,8BAAsB,mBACpB,YAAW,eAAe,CAAC,eAAe,CAAC;;IAE3C,SAAS,CAAC,QAAQ,CAAC,SAAS,EAAE,iCAAiC,CAAC;gBAEpD,SAAS,EAAE,iCAAiC;IA2BxD,WAAW,IAAI,eAAe,EAAE;IAIhC,UAAU,CAAC,EAAE,EAAE,SAAS,GAAG,eAAe;IAW1C,QAAQ,CAAC,mBAAmB,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO;CAChE"}
1
+ {"version":3,"file":"BaseAccountProvider.d.cts","sourceRoot":"","sources":["../../src/providers/BaseAccountProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,YAAY,EAClB,8BAA8B;AAC/B,OAAO,KAAK,EAAE,eAAe,EAAE,uCAAuC;AAEtE,OAAO,KAAK,EAAE,iCAAiC,EAAE,qBAAiB;AAElE,8BAAsB,mBACpB,YAAW,eAAe,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC;;IAEzD,SAAS,CAAC,QAAQ,CAAC,SAAS,EAAE,iCAAiC,CAAC;gBAEpD,SAAS,EAAE,iCAAiC;IA2BxD,WAAW,IAAI,YAAY,CAAC,eAAe,CAAC,EAAE;IAI9C,UAAU,CAAC,EAAE,EAAE,eAAe,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,eAAe,CAAC;IAWpE,QAAQ,CAAC,mBAAmB,CAAC,OAAO,EAAE,YAAY,CAAC,eAAe,CAAC,GAAG,OAAO;CAC9E"}
@@ -1,26 +1,12 @@
1
- import type { AccountProvider } from "@metamask/account-api";
2
- import type { AccountId } from "@metamask/accounts-controller";
3
- import type { KeyringAccount, KeyringAccountEntropyMnemonicOptions } from "@metamask/keyring-api";
1
+ import { type AccountProvider, type Bip44Account } from "@metamask/account-api";
4
2
  import type { InternalAccount } from "@metamask/keyring-internal-api";
5
3
  import type { MultichainAccountServiceMessenger } from "../types.mjs";
6
- export type Bip44Account<Account extends KeyringAccount> = Account & {
7
- options: {
8
- entropy: KeyringAccountEntropyMnemonicOptions;
9
- };
10
- };
11
- /**
12
- * Checks if an account is BIP-44 compatible.
13
- *
14
- * @param account - The account to be tested.
15
- * @returns True if the account is BIP-44 compatible.
16
- */
17
- export declare function isBip44Account<Account extends KeyringAccount>(account: Account): account is Bip44Account<Account>;
18
- export declare abstract class BaseAccountProvider implements AccountProvider<InternalAccount> {
4
+ export declare abstract class BaseAccountProvider implements AccountProvider<Bip44Account<InternalAccount>> {
19
5
  #private;
20
6
  protected readonly messenger: MultichainAccountServiceMessenger;
21
7
  constructor(messenger: MultichainAccountServiceMessenger);
22
- getAccounts(): InternalAccount[];
23
- getAccount(id: AccountId): InternalAccount;
24
- abstract isAccountCompatible(account: InternalAccount): boolean;
8
+ getAccounts(): Bip44Account<InternalAccount>[];
9
+ getAccount(id: InternalAccount['id']): Bip44Account<InternalAccount>;
10
+ abstract isAccountCompatible(account: Bip44Account<InternalAccount>): boolean;
25
11
  }
26
12
  //# sourceMappingURL=BaseAccountProvider.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"BaseAccountProvider.d.mts","sourceRoot":"","sources":["../../src/providers/BaseAccountProvider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,8BAA8B;AAC7D,OAAO,KAAK,EAAE,SAAS,EAAE,sCAAsC;AAC/D,OAAO,KAAK,EACV,cAAc,EACd,oCAAoC,EACrC,8BAA8B;AAE/B,OAAO,KAAK,EAAE,eAAe,EAAE,uCAAuC;AAEtE,OAAO,KAAK,EAAE,iCAAiC,EAAE,qBAAiB;AAElE,MAAM,MAAM,YAAY,CAAC,OAAO,SAAS,cAAc,IAAI,OAAO,GAAG;IACnE,OAAO,EAAE;QACP,OAAO,EAAE,oCAAoC,CAAC;KAC/C,CAAC;CACH,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,OAAO,SAAS,cAAc,EAC3D,OAAO,EAAE,OAAO,GACf,OAAO,IAAI,YAAY,CAAC,OAAO,CAAC,CAYlC;AAED,8BAAsB,mBACpB,YAAW,eAAe,CAAC,eAAe,CAAC;;IAE3C,SAAS,CAAC,QAAQ,CAAC,SAAS,EAAE,iCAAiC,CAAC;gBAEpD,SAAS,EAAE,iCAAiC;IA2BxD,WAAW,IAAI,eAAe,EAAE;IAIhC,UAAU,CAAC,EAAE,EAAE,SAAS,GAAG,eAAe;IAW1C,QAAQ,CAAC,mBAAmB,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO;CAChE"}
1
+ {"version":3,"file":"BaseAccountProvider.d.mts","sourceRoot":"","sources":["../../src/providers/BaseAccountProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,YAAY,EAClB,8BAA8B;AAC/B,OAAO,KAAK,EAAE,eAAe,EAAE,uCAAuC;AAEtE,OAAO,KAAK,EAAE,iCAAiC,EAAE,qBAAiB;AAElE,8BAAsB,mBACpB,YAAW,eAAe,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC;;IAEzD,SAAS,CAAC,QAAQ,CAAC,SAAS,EAAE,iCAAiC,CAAC;gBAEpD,SAAS,EAAE,iCAAiC;IA2BxD,WAAW,IAAI,YAAY,CAAC,eAAe,CAAC,EAAE;IAI9C,UAAU,CAAC,EAAE,EAAE,eAAe,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,eAAe,CAAC;IAWpE,QAAQ,CAAC,mBAAmB,CAAC,OAAO,EAAE,YAAY,CAAC,eAAe,CAAC,GAAG,OAAO;CAC9E"}