@metamask-previews/assets-controllers 45.1.1-preview-a1e11fbb → 45.1.1-preview-3178c25e

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.
@@ -134,9 +134,13 @@ _MultichainBalancesController_tracker = new WeakMap(), _MultichainBalancesContro
134
134
  */
135
135
  async function _MultichainBalancesController_updateBalance(accountId) {
136
136
  const account = __classPrivateFieldGet(this, _MultichainBalancesController_instances, "m", _MultichainBalancesController_getAccount).call(this, accountId);
137
+ console.log('MultichainBalancesController updateBalance', { account });
137
138
  const partialState = { balances: {} };
139
+ console.log('MultichainBalancesController updateBalance', { partialState });
138
140
  const scope = (0, utils_1.getScopeForAddress)(account);
141
+ console.log('MultichainBalancesController updateBalance', { scope });
139
142
  const assetsList = __classPrivateFieldGet(this, _MultichainBalancesController_networkAssetsMap, "f")[scope];
143
+ console.log('MultichainBalancesController updateBalance', { assetsList });
140
144
  if (account.metadata.snap) {
141
145
  partialState.balances[account.id] = await __classPrivateFieldGet(this, _MultichainBalancesController_instances, "m", _MultichainBalancesController_getBalances).call(this, account.id, account.metadata.snap.id, assetsList);
142
146
  }
@@ -198,6 +202,11 @@ async function _MultichainBalancesController_handleOnAccountRemoved(accountId) {
198
202
  * @returns A map of asset types to balances.
199
203
  */
200
204
  async function _MultichainBalancesController_getBalances(accountId, snapId, assetTypes) {
205
+ console.log('MultichainBalancesController - getBalances', {
206
+ accountId,
207
+ snapId,
208
+ assetTypes,
209
+ });
201
210
  const keyringClient = __classPrivateFieldGet(this, _MultichainBalancesController_instances, "m", _MultichainBalancesController_getClient).call(this, snapId);
202
211
  console.log('MultichainBalancesController', { keyringClient });
203
212
  return await keyringClient.getAccountBalances(accountId, assetTypes);
@@ -1 +1 @@
1
- {"version":3,"file":"MultichainBalancesController.cjs","sourceRoot":"","sources":["../../src/MultichainBalancesController/MultichainBalancesController.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAKA,+DAKmC;AACnC,uDAM+B;AAG/B,uDAAoD;AAIpD,kCAIW;AACX,uCAA6C;AAE7C,MAAM,cAAc,GAAG,8BAA8B,CAAC;AAgBtD;;GAEG;AACU,QAAA,YAAY,GAAsC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;AAmEhF;;;;;;GAMG;AACH,MAAM,oCAAoC,GAAG;IAC3C,QAAQ,EAAE;QACR,OAAO,EAAE,IAAI;QACb,SAAS,EAAE,KAAK;KACjB;CACF,CAAC;AAEF;;;GAGG;AACH,MAAa,4BAA6B,SAAQ,gCAIjD;IAQC,YAAY,EACV,SAAS,EACT,KAAK,GAIN;QACC,KAAK,CAAC;YACJ,SAAS;YACT,IAAI,EAAE,cAAc;YACpB,QAAQ,EAAE,oCAAoC;YAC9C,KAAK,EAAE;gBACL,GAAG,oBAAY;gBACf,GAAG,KAAK;aACT;SACF,CAAC,CAAC;;QAtBI,wDAA0B;QAEnC,kEAAkE;QAClE,gEAAgE;QAChE,wEAAwE;QAC/D,yDAA8C,qBAAkB,EAAC;QAmBxE,uBAAA,IAAI,yCAAY,IAAI,kBAAe,CACjC,KAAK,EAAE,SAAiB,EAAE,EAAE,CAAC,MAAM,uBAAA,IAAI,4FAAe,MAAnB,IAAI,EAAgB,SAAS,CAAC,CAClE,MAAA,CAAC;QAEF,iDAAiD;QACjD,KAAK,MAAM,OAAO,IAAI,uBAAA,IAAI,2FAAc,MAAlB,IAAI,CAAgB,EAAE;YAC1C,uBAAA,IAAI,2FAAc,MAAlB,IAAI,EAAe,OAAO,CAAC,CAAC;SAC7B;QAED,IAAI,CAAC,eAAe,CAAC,SAAS,CAC5B,iCAAiC,EACjC,CAAC,OAAO,EAAE,EAAE,CAAC,uBAAA,IAAI,mGAAsB,MAA1B,IAAI,EAAuB,OAAO,CAAC,CACjD,CAAC;QACF,IAAI,CAAC,eAAe,CAAC,SAAS,CAC5B,mCAAmC,EACnC,CAAC,OAAO,EAAE,EAAE,CAAC,uBAAA,IAAI,qGAAwB,MAA5B,IAAI,EAAyB,OAAO,CAAC,CACnD,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK;QACH,uBAAA,IAAI,6CAAS,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;IAED;;OAEG;IACH,IAAI;QACF,uBAAA,IAAI,6CAAS,CAAC,IAAI,EAAE,CAAC;IACvB,CAAC;IAoGD;;;;;OAKG;IACH,KAAK,CAAC,aAAa,CAAC,SAAiB;QACnC,OAAO,CAAC,GAAG,CAAC,4CAA4C,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;QACzE,8EAA8E;QAC9E,kDAAkD;QAClD,MAAM,uBAAA,IAAI,6CAAS,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;IAC/C,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,cAAc;QAClB,OAAO,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC;QAC3D,MAAM,uBAAA,IAAI,6CAAS,CAAC,cAAc,EAAE,CAAC;IACvC,CAAC;CA2FF;AA/QD,oEA+QC;iRA5Me,OAAwB;IACpC,IAAI,CAAC,uBAAA,IAAI,8FAAiB,MAArB,IAAI,EAAkB,OAAO,CAAC,EAAE;QACnC,sCAAsC;QACtC,OAAO,CAAC,GAAG,CACT,8DAA8D,EAC9D,OAAO,CACR,CAAC;QACF,OAAO;KACR;IAED,MAAM,UAAU;IACd,sFAAsF;IACtF,6EAA6E;IAC7E,4EAA4E;IAC5E,2BAAwB,CAAC,uBAAA,IAAI,yFAAY,MAAhB,IAAI,EAAa,OAAO,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;IAC9D,uBAAA,IAAI,6CAAS,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;AAC9C,CAAC;IAQC,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,CAC9B,2CAA2C,CAC5C,CAAC;AACJ,CAAC;IAUC,MAAM,QAAQ,GAAG,uBAAA,IAAI,qGAAwB,MAA5B,IAAI,CAA0B,CAAC;IAEhD,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,uBAAA,IAAI,8FAAiB,MAArB,IAAI,EAAkB,OAAO,CAAC,CAAC,CAAC;AACtE,CAAC,+FAQW,SAAiB;IAC3B,MAAM,OAAO,GACX,uBAAA,IAAI,qGAAwB,MAA5B,IAAI,CAA0B,CAAC,IAAI,CACjC,CAAC,iBAAiB,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,KAAK,SAAS,CAC1D,CAAC;IAEJ,IAAI,CAAC,OAAO,EAAE;QACZ,MAAM,IAAI,KAAK,CAAC,oBAAoB,SAAS,EAAE,CAAC,CAAC;KAClD;IACD,IAAI,CAAC,uBAAA,IAAI,8FAAiB,MAArB,IAAI,EAAkB,OAAO,CAAC,EAAE;QACnC,MAAM,IAAI,KAAK,CAAC,qCAAqC,SAAS,EAAE,CAAC,CAAC;KACnE;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;GAKG;AACH,KAAK,sDAAgB,SAAiB;IACpC,MAAM,OAAO,GAAG,uBAAA,IAAI,yFAAY,MAAhB,IAAI,EAAa,SAAS,CAAC,CAAC;IAC5C,MAAM,YAAY,GAAsC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;IAEzE,MAAM,KAAK,GAAG,IAAA,0BAAkB,EAAC,OAAO,CAAC,CAAC;IAC1C,MAAM,UAAU,GAAG,uBAAA,IAAI,sDAAkB,CAAC,KAAK,CAAC,CAAC;IAEjD,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE;QACzB,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,MAAM,uBAAA,IAAI,0FAAa,MAAjB,IAAI,EAC5C,OAAO,CAAC,EAAE,EACV,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,EACxB,UAAU,CACX,CAAC;KACH;IAED,OAAO,CAAC,GAAG,CAAC,2CAA2C,EAAE,EAAE,YAAY,EAAE,CAAC,CAAC;IAC3E,IAAI,CAAC,MAAM,CAAC,CAAC,KAA+C,EAAE,EAAE;QAC9D,KAAK,CAAC,QAAQ,GAAG;YACf,GAAG,KAAK,CAAC,QAAQ;YACjB,GAAG,YAAY,CAAC,QAAQ;SACzB,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,yGA8BgB,OAAwB;IACvC,OAAO,CACL,CAAC,IAAA,8BAAgB,EAAC,OAAO,CAAC,IAAI,CAAC;QAC/B,gDAAgD;QAChD,OAAO,CAAC,QAAQ,CAAC,IAAI,KAAK,SAAS,CACpC,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,KAAK,6DAAuB,OAAwB;IAClD,OAAO,CAAC,GAAG,CAAC,mDAAmD,EAAE;QAC/D,OAAO;KACR,CAAC,CAAC;IACH,uBAAA,IAAI,2FAAc,MAAlB,IAAI,EAAe,OAAO,CAAC,CAAC;IAC5B,6EAA6E;IAC7E,2EAA2E;IAC3E,gBAAgB;IAChB,6EAA6E;IAC7E,4EAA4E;IAC5E,2BAA2B;IAC3B,sHAAsH;AACxH,CAAC;AAED;;;;GAIG;AACH,KAAK,+DAAyB,SAAiB;IAC7C,OAAO,CAAC,GAAG,CAAC,mDAAmD,EAAE;QAC/D,SAAS;KACV,CAAC,CAAC;IACH,IAAI,uBAAA,IAAI,6CAAS,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE;QACtC,uBAAA,IAAI,6CAAS,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;KAClC;IAED,IAAI,SAAS,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE;QACpC,IAAI,CAAC,MAAM,CAAC,CAAC,KAA+C,EAAE,EAAE;YAC9D,OAAO,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;YACjC,OAAO,KAAK,CAAC;QACf,CAAC,CAAC,CAAC;KACJ;AACH,CAAC;AAED;;;;;;;GAOG;AACH,KAAK,oDACH,SAAiB,EACjB,MAAc,EACd,UAA2B;IAE3B,MAAM,aAAa,GAAG,uBAAA,IAAI,wFAAW,MAAf,IAAI,EAAY,MAAM,CAAC,CAAC;IAC9C,OAAO,CAAC,GAAG,CAAC,8BAA8B,EAAE,EAAE,aAAa,EAAE,CAAC,CAAC;IAC/D,OAAO,MAAM,aAAa,CAAC,kBAAkB,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;AACvE,CAAC,6FAQU,MAAc;IACvB,OAAO,IAAI,2BAAa,CAAC;QACvB,IAAI,EAAE,KAAK,EAAE,OAAuB,EAAE,EAAE,CACtC,CAAC,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,8BAA8B,EAAE;YAC/D,MAAM,EAAE,MAAgB;YACxB,MAAM,EAAE,UAAU;YAClB,OAAO,EAAE,yBAAW,CAAC,gBAAgB;YACrC,OAAO;SACR,CAAC,CAAkB;KACvB,CAAC,CAAC;AACL,CAAC","sourcesContent":["import type {\n AccountsControllerAccountAddedEvent,\n AccountsControllerAccountRemovedEvent,\n AccountsControllerListMultichainAccountsAction,\n} from '@metamask/accounts-controller';\nimport {\n BaseController,\n type ControllerGetStateAction,\n type ControllerStateChangeEvent,\n type RestrictedControllerMessenger,\n} from '@metamask/base-controller';\nimport {\n KeyringClient,\n type Balance,\n type CaipAssetType,\n type InternalAccount,\n isEvmAccountType,\n} from '@metamask/keyring-api';\nimport type { HandleSnapRequest } from '@metamask/snaps-controllers';\nimport type { SnapId } from '@metamask/snaps-sdk';\nimport { HandlerType } from '@metamask/snaps-utils';\nimport type { Json, JsonRpcRequest } from '@metamask/utils';\nimport type { Draft } from 'immer';\n\nimport {\n BalancesTracker,\n BALANCE_UPDATE_INTERVALS,\n NETWORK_ASSETS_MAP,\n} from '.';\nimport { getScopeForAddress } from './utils';\n\nconst controllerName = 'MultichainBalancesController';\n\n/**\n * State used by the {@link MultichainBalancesController} to cache account balances.\n */\nexport type MultichainBalancesControllerState = {\n balances: {\n [account: string]: {\n [asset: string]: {\n amount: string;\n unit: string;\n };\n };\n };\n};\n\n/**\n * Default state of the {@link MultichainBalancesController}.\n */\nexport const defaultState: MultichainBalancesControllerState = { balances: {} };\n\n/**\n * Returns the state of the {@link MultichainBalancesController}.\n */\nexport type MultichainBalancesControllerGetStateAction =\n ControllerGetStateAction<\n typeof controllerName,\n MultichainBalancesControllerState\n >;\n\n/**\n * Updates the balances of all supported accounts in {@link MultichainBalancesController}.\n */\nexport type MultichainBalancesControllerUpdateBalancesAction = {\n type: `${typeof controllerName}:updateBalances`;\n handler: MultichainBalancesController['updateBalances'];\n};\n\n/**\n * Event emitted when the state of the {@link MultichainBalancesController} changes.\n */\nexport type MultichainBalancesControllerStateChange =\n ControllerStateChangeEvent<\n typeof controllerName,\n MultichainBalancesControllerState\n >;\n\n/**\n * Actions exposed by the {@link MultichainBalancesController}.\n */\nexport type MultichainBalancesControllerActions =\n | MultichainBalancesControllerGetStateAction\n | MultichainBalancesControllerUpdateBalancesAction;\n\n/**\n * Events emitted by {@link MultichainBalancesController}.\n */\nexport type MultichainBalancesControllerEvents =\n MultichainBalancesControllerStateChange;\n\n/**\n * Actions that this controller is allowed to call.\n */\nexport type AllowedActions =\n | HandleSnapRequest\n | AccountsControllerListMultichainAccountsAction;\n\n/**\n * Events that this controller is allowed to subscribe.\n */\nexport type AllowedEvents =\n | AccountsControllerAccountAddedEvent\n | AccountsControllerAccountRemovedEvent;\n\n/**\n * Messenger type for the MultichainBalancesController.\n */\nexport type MultichainBalancesControllerMessenger =\n RestrictedControllerMessenger<\n typeof controllerName,\n MultichainBalancesControllerActions | AllowedActions,\n MultichainBalancesControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n >;\n\n/**\n * {@link multichainBalancesController}'s metadata.\n *\n * This allows us to choose if fields of the state should be persisted or not\n * using the `persist` flag; and if they can be sent to Sentry or not, using\n * the `anonymous` flag.\n */\nconst multichainBalancesControllerMetadata = {\n balances: {\n persist: true,\n anonymous: false,\n },\n};\n\n/**\n * The MultichainBalancesController is responsible for fetching and caching account\n * balances.\n */\nexport class MultichainBalancesController extends BaseController<\n typeof controllerName,\n MultichainBalancesControllerState,\n MultichainBalancesControllerMessenger\n> {\n readonly #tracker: BalancesTracker;\n\n // As a temporary solution, we are using a map to store the assets\n // that are hardcoded in the module. In the future, this mapping\n // should be dynamic to allow a client to register and unregister assets\n readonly #networkAssetsMap: Record<string, string[]> = NETWORK_ASSETS_MAP;\n\n constructor({\n messenger,\n state,\n }: {\n messenger: MultichainBalancesControllerMessenger;\n state: MultichainBalancesControllerState;\n }) {\n super({\n messenger,\n name: controllerName,\n metadata: multichainBalancesControllerMetadata,\n state: {\n ...defaultState,\n ...state,\n },\n });\n\n this.#tracker = new BalancesTracker(\n async (accountId: string) => await this.#updateBalance(accountId),\n );\n\n // Register all non-EVM accounts into the tracker\n for (const account of this.#listAccounts()) {\n this.#trackAccount(account);\n }\n\n this.messagingSystem.subscribe(\n 'AccountsController:accountAdded',\n (account) => this.#handleOnAccountAdded(account),\n );\n this.messagingSystem.subscribe(\n 'AccountsController:accountRemoved',\n (account) => this.#handleOnAccountRemoved(account),\n );\n }\n\n /**\n * Starts the polling process.\n */\n start(): void {\n this.#tracker.start();\n }\n\n /**\n * Stops the polling process.\n */\n stop(): void {\n this.#tracker.stop();\n }\n\n /**\n * Tracks an account to get its balances.\n *\n * @param account - The account to track.\n */\n #trackAccount(account: InternalAccount): void {\n if (!this.#isNonEvmAccount(account)) {\n // Nothing to do here for EVM accounts\n console.log(\n 'MultichainBalancesController - early return in #trackAccount',\n account,\n );\n return;\n }\n\n const updateTime =\n // @ts-expect-error - For the moment we are only tracking non-EVM accounts and this is\n // checked with the method `#isNonEvmAccount`. We can ignore this error since\n // eip155:eoa and eip155:erc4337 account type balances are not tracked here.\n BALANCE_UPDATE_INTERVALS[this.#getAccount(account.id).type];\n this.#tracker.track(account.id, updateTime);\n }\n\n /**\n * Lists the multichain accounts coming from the `AccountsController`.\n *\n * @returns A list of multichain accounts.\n */\n #listMultichainAccounts(): InternalAccount[] {\n return this.messagingSystem.call(\n 'AccountsController:listMultichainAccounts',\n );\n }\n\n /**\n * Lists the accounts that we should get balances for.\n *\n * Currently, we only get balances for non-EVM accounts.\n *\n * @returns A list of accounts that we should get balances for.\n */\n #listAccounts(): InternalAccount[] {\n const accounts = this.#listMultichainAccounts();\n\n return accounts.filter((account) => this.#isNonEvmAccount(account));\n }\n\n /**\n * Get a non-EVM account from its ID.\n *\n * @param accountId - The account ID.\n * @returns The non-EVM account.\n */\n #getAccount(accountId: string): InternalAccount {\n const account: InternalAccount | undefined =\n this.#listMultichainAccounts().find(\n (multichainAccount) => multichainAccount.id === accountId,\n );\n\n if (!account) {\n throw new Error(`Unknown account: ${accountId}`);\n }\n if (!this.#isNonEvmAccount(account)) {\n throw new Error(`Account is not a non-EVM account: ${accountId}`);\n }\n return account;\n }\n\n /**\n * Updates the balances of one account. This method doesn't return\n * anything, but it updates the state of the controller.\n *\n * @param accountId - The account ID.\n */\n async #updateBalance(accountId: string) {\n const account = this.#getAccount(accountId);\n const partialState: MultichainBalancesControllerState = { balances: {} };\n\n const scope = getScopeForAddress(account);\n const assetsList = this.#networkAssetsMap[scope];\n\n if (account.metadata.snap) {\n partialState.balances[account.id] = await this.#getBalances(\n account.id,\n account.metadata.snap.id,\n assetsList,\n );\n }\n\n console.log('MultichainBalancesController update state', { partialState });\n this.update((state: Draft<MultichainBalancesControllerState>) => {\n state.balances = {\n ...state.balances,\n ...partialState.balances,\n };\n });\n }\n\n /**\n * Updates the balances of one account. This method doesn't return\n * anything, but it updates the state of the controller.\n *\n * @param accountId - The account ID.\n */\n async updateBalance(accountId: string) {\n console.log('MultichainBalancesController updateBalance', { accountId });\n // NOTE: No need to track the account here, since we start tracking those when\n // the \"AccountsController:accountAdded\" is fired.\n await this.#tracker.updateBalance(accountId);\n }\n\n /**\n * Updates the balances of all supported accounts. This method doesn't return\n * anything, but it updates the state of the controller.\n */\n async updateBalances() {\n console.log('MultichainBalancesController updateBalances');\n await this.#tracker.updateBalances();\n }\n\n /**\n * Checks for non-EVM accounts.\n *\n * @param account - The new account to be checked.\n * @returns True if the account is a non-EVM account, false otherwise.\n */\n #isNonEvmAccount(account: InternalAccount): boolean {\n return (\n !isEvmAccountType(account.type) &&\n // Non-EVM accounts are backed by a Snap for now\n account.metadata.snap !== undefined\n );\n }\n\n /**\n * Handles changes when a new account has been added.\n *\n * @param account - The new account being added.\n */\n async #handleOnAccountAdded(account: InternalAccount) {\n console.log('MultichainBalancesController handleOnAccountAdded', {\n account,\n });\n this.#trackAccount(account);\n // NOTE: Unfortunately, we cannot update the balance right away here, because\n // messenger's events are running synchronously and fetching the balance is\n // asynchronous.\n // Updating the balance here would resume at some point but the event emitter\n // will not `await` this (so we have no real control \"when\" the balance will\n // really be updated), see:\n // - https://github.com/MetaMask/core/blob/v213.0.0/packages/accounts-controller/src/AccountsController.ts#L1036-L1039\n }\n\n /**\n * Handles changes when a new account has been removed.\n *\n * @param accountId - The account ID being removed.\n */\n async #handleOnAccountRemoved(accountId: string) {\n console.log('MultichainBalancesController handleOnAccountAdded', {\n accountId,\n });\n if (this.#tracker.isTracked(accountId)) {\n this.#tracker.untrack(accountId);\n }\n\n if (accountId in this.state.balances) {\n this.update((state: Draft<MultichainBalancesControllerState>) => {\n delete state.balances[accountId];\n return state;\n });\n }\n }\n\n /**\n * Get the balances for an account.\n *\n * @param accountId - ID of the account to get balances for.\n * @param snapId - ID of the Snap which manages the account.\n * @param assetTypes - Array of asset types to get balances for.\n * @returns A map of asset types to balances.\n */\n async #getBalances(\n accountId: string,\n snapId: string,\n assetTypes: CaipAssetType[],\n ): Promise<Record<CaipAssetType, Balance>> {\n const keyringClient = this.#getClient(snapId);\n console.log('MultichainBalancesController', { keyringClient });\n return await keyringClient.getAccountBalances(accountId, assetTypes);\n }\n\n /**\n * Gets a `KeyringClient` for a Snap.\n *\n * @param snapId - ID of the Snap to get the client for.\n * @returns A `KeyringClient` for the Snap.\n */\n #getClient(snapId: string): KeyringClient {\n return new KeyringClient({\n send: async (request: JsonRpcRequest) =>\n (await this.messagingSystem.call('SnapController:handleRequest', {\n snapId: snapId as SnapId,\n origin: 'metamask',\n handler: HandlerType.OnKeyringRequest,\n request,\n })) as Promise<Json>,\n });\n }\n}\n"]}
1
+ {"version":3,"file":"MultichainBalancesController.cjs","sourceRoot":"","sources":["../../src/MultichainBalancesController/MultichainBalancesController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n AccountsControllerAccountAddedEvent,\n AccountsControllerAccountRemovedEvent,\n AccountsControllerListMultichainAccountsAction,\n} from '@metamask/accounts-controller';\nimport {\n BaseController,\n type ControllerGetStateAction,\n type ControllerStateChangeEvent,\n type RestrictedControllerMessenger,\n} from '@metamask/base-controller';\nimport {\n KeyringClient,\n type Balance,\n type CaipAssetType,\n type InternalAccount,\n isEvmAccountType,\n} from '@metamask/keyring-api';\nimport type { HandleSnapRequest } from '@metamask/snaps-controllers';\nimport type { SnapId } from '@metamask/snaps-sdk';\nimport { HandlerType } from '@metamask/snaps-utils';\nimport type { Json, JsonRpcRequest } from '@metamask/utils';\nimport type { Draft } from 'immer';\n\nimport {\n BalancesTracker,\n BALANCE_UPDATE_INTERVALS,\n NETWORK_ASSETS_MAP,\n} from '.';\nimport { getScopeForAddress } from './utils';\n\nconst controllerName = 'MultichainBalancesController';\n\n/**\n * State used by the {@link MultichainBalancesController} to cache account balances.\n */\nexport type MultichainBalancesControllerState = {\n balances: {\n [account: string]: {\n [asset: string]: {\n amount: string;\n unit: string;\n };\n };\n };\n};\n\n/**\n * Default state of the {@link MultichainBalancesController}.\n */\nexport const defaultState: MultichainBalancesControllerState = { balances: {} };\n\n/**\n * Returns the state of the {@link MultichainBalancesController}.\n */\nexport type MultichainBalancesControllerGetStateAction =\n ControllerGetStateAction<\n typeof controllerName,\n MultichainBalancesControllerState\n >;\n\n/**\n * Updates the balances of all supported accounts in {@link MultichainBalancesController}.\n */\nexport type MultichainBalancesControllerUpdateBalancesAction = {\n type: `${typeof controllerName}:updateBalances`;\n handler: MultichainBalancesController['updateBalances'];\n};\n\n/**\n * Event emitted when the state of the {@link MultichainBalancesController} changes.\n */\nexport type MultichainBalancesControllerStateChange =\n ControllerStateChangeEvent<\n typeof controllerName,\n MultichainBalancesControllerState\n >;\n\n/**\n * Actions exposed by the {@link MultichainBalancesController}.\n */\nexport type MultichainBalancesControllerActions =\n | MultichainBalancesControllerGetStateAction\n | MultichainBalancesControllerUpdateBalancesAction;\n\n/**\n * Events emitted by {@link MultichainBalancesController}.\n */\nexport type MultichainBalancesControllerEvents =\n MultichainBalancesControllerStateChange;\n\n/**\n * Actions that this controller is allowed to call.\n */\nexport type AllowedActions =\n | HandleSnapRequest\n | AccountsControllerListMultichainAccountsAction;\n\n/**\n * Events that this controller is allowed to subscribe.\n */\nexport type AllowedEvents =\n | AccountsControllerAccountAddedEvent\n | AccountsControllerAccountRemovedEvent;\n\n/**\n * Messenger type for the MultichainBalancesController.\n */\nexport type MultichainBalancesControllerMessenger =\n RestrictedControllerMessenger<\n typeof controllerName,\n MultichainBalancesControllerActions | AllowedActions,\n MultichainBalancesControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n >;\n\n/**\n * {@link multichainBalancesController}'s metadata.\n *\n * This allows us to choose if fields of the state should be persisted or not\n * using the `persist` flag; and if they can be sent to Sentry or not, using\n * the `anonymous` flag.\n */\nconst multichainBalancesControllerMetadata = {\n balances: {\n persist: true,\n anonymous: false,\n },\n};\n\n/**\n * The MultichainBalancesController is responsible for fetching and caching account\n * balances.\n */\nexport class MultichainBalancesController extends BaseController<\n typeof controllerName,\n MultichainBalancesControllerState,\n MultichainBalancesControllerMessenger\n> {\n readonly #tracker: BalancesTracker;\n\n // As a temporary solution, we are using a map to store the assets\n // that are hardcoded in the module. In the future, this mapping\n // should be dynamic to allow a client to register and unregister assets\n readonly #networkAssetsMap: Record<string, string[]> = NETWORK_ASSETS_MAP;\n\n constructor({\n messenger,\n state,\n }: {\n messenger: MultichainBalancesControllerMessenger;\n state: MultichainBalancesControllerState;\n }) {\n super({\n messenger,\n name: controllerName,\n metadata: multichainBalancesControllerMetadata,\n state: {\n ...defaultState,\n ...state,\n },\n });\n\n this.#tracker = new BalancesTracker(\n async (accountId: string) => await this.#updateBalance(accountId),\n );\n\n // Register all non-EVM accounts into the tracker\n for (const account of this.#listAccounts()) {\n this.#trackAccount(account);\n }\n\n this.messagingSystem.subscribe(\n 'AccountsController:accountAdded',\n (account) => this.#handleOnAccountAdded(account),\n );\n this.messagingSystem.subscribe(\n 'AccountsController:accountRemoved',\n (account) => this.#handleOnAccountRemoved(account),\n );\n }\n\n /**\n * Starts the polling process.\n */\n start(): void {\n this.#tracker.start();\n }\n\n /**\n * Stops the polling process.\n */\n stop(): void {\n this.#tracker.stop();\n }\n\n /**\n * Tracks an account to get its balances.\n *\n * @param account - The account to track.\n */\n #trackAccount(account: InternalAccount): void {\n if (!this.#isNonEvmAccount(account)) {\n // Nothing to do here for EVM accounts\n console.log(\n 'MultichainBalancesController - early return in #trackAccount',\n account,\n );\n return;\n }\n\n const updateTime =\n // @ts-expect-error - For the moment we are only tracking non-EVM accounts and this is\n // checked with the method `#isNonEvmAccount`. We can ignore this error since\n // eip155:eoa and eip155:erc4337 account type balances are not tracked here.\n BALANCE_UPDATE_INTERVALS[this.#getAccount(account.id).type];\n this.#tracker.track(account.id, updateTime);\n }\n\n /**\n * Lists the multichain accounts coming from the `AccountsController`.\n *\n * @returns A list of multichain accounts.\n */\n #listMultichainAccounts(): InternalAccount[] {\n return this.messagingSystem.call(\n 'AccountsController:listMultichainAccounts',\n );\n }\n\n /**\n * Lists the accounts that we should get balances for.\n *\n * Currently, we only get balances for non-EVM accounts.\n *\n * @returns A list of accounts that we should get balances for.\n */\n #listAccounts(): InternalAccount[] {\n const accounts = this.#listMultichainAccounts();\n\n return accounts.filter((account) => this.#isNonEvmAccount(account));\n }\n\n /**\n * Get a non-EVM account from its ID.\n *\n * @param accountId - The account ID.\n * @returns The non-EVM account.\n */\n #getAccount(accountId: string): InternalAccount {\n const account: InternalAccount | undefined =\n this.#listMultichainAccounts().find(\n (multichainAccount) => multichainAccount.id === accountId,\n );\n\n if (!account) {\n throw new Error(`Unknown account: ${accountId}`);\n }\n if (!this.#isNonEvmAccount(account)) {\n throw new Error(`Account is not a non-EVM account: ${accountId}`);\n }\n return account;\n }\n\n /**\n * Updates the balances of one account. This method doesn't return\n * anything, but it updates the state of the controller.\n *\n * @param accountId - The account ID.\n */\n async #updateBalance(accountId: string) {\n const account = this.#getAccount(accountId);\n console.log('MultichainBalancesController updateBalance', { account });\n const partialState: MultichainBalancesControllerState = { balances: {} };\n console.log('MultichainBalancesController updateBalance', { partialState });\n\n const scope = getScopeForAddress(account);\n console.log('MultichainBalancesController updateBalance', { scope });\n const assetsList = this.#networkAssetsMap[scope];\n console.log('MultichainBalancesController updateBalance', { assetsList });\n\n if (account.metadata.snap) {\n partialState.balances[account.id] = await this.#getBalances(\n account.id,\n account.metadata.snap.id,\n assetsList,\n );\n }\n\n console.log('MultichainBalancesController update state', { partialState });\n this.update((state: Draft<MultichainBalancesControllerState>) => {\n state.balances = {\n ...state.balances,\n ...partialState.balances,\n };\n });\n }\n\n /**\n * Updates the balances of one account. This method doesn't return\n * anything, but it updates the state of the controller.\n *\n * @param accountId - The account ID.\n */\n async updateBalance(accountId: string) {\n console.log('MultichainBalancesController updateBalance', { accountId });\n // NOTE: No need to track the account here, since we start tracking those when\n // the \"AccountsController:accountAdded\" is fired.\n await this.#tracker.updateBalance(accountId);\n }\n\n /**\n * Updates the balances of all supported accounts. This method doesn't return\n * anything, but it updates the state of the controller.\n */\n async updateBalances() {\n console.log('MultichainBalancesController updateBalances');\n await this.#tracker.updateBalances();\n }\n\n /**\n * Checks for non-EVM accounts.\n *\n * @param account - The new account to be checked.\n * @returns True if the account is a non-EVM account, false otherwise.\n */\n #isNonEvmAccount(account: InternalAccount): boolean {\n return (\n !isEvmAccountType(account.type) &&\n // Non-EVM accounts are backed by a Snap for now\n account.metadata.snap !== undefined\n );\n }\n\n /**\n * Handles changes when a new account has been added.\n *\n * @param account - The new account being added.\n */\n async #handleOnAccountAdded(account: InternalAccount) {\n console.log('MultichainBalancesController handleOnAccountAdded', {\n account,\n });\n this.#trackAccount(account);\n // NOTE: Unfortunately, we cannot update the balance right away here, because\n // messenger's events are running synchronously and fetching the balance is\n // asynchronous.\n // Updating the balance here would resume at some point but the event emitter\n // will not `await` this (so we have no real control \"when\" the balance will\n // really be updated), see:\n // - https://github.com/MetaMask/core/blob/v213.0.0/packages/accounts-controller/src/AccountsController.ts#L1036-L1039\n }\n\n /**\n * Handles changes when a new account has been removed.\n *\n * @param accountId - The account ID being removed.\n */\n async #handleOnAccountRemoved(accountId: string) {\n console.log('MultichainBalancesController handleOnAccountAdded', {\n accountId,\n });\n if (this.#tracker.isTracked(accountId)) {\n this.#tracker.untrack(accountId);\n }\n\n if (accountId in this.state.balances) {\n this.update((state: Draft<MultichainBalancesControllerState>) => {\n delete state.balances[accountId];\n return state;\n });\n }\n }\n\n /**\n * Get the balances for an account.\n *\n * @param accountId - ID of the account to get balances for.\n * @param snapId - ID of the Snap which manages the account.\n * @param assetTypes - Array of asset types to get balances for.\n * @returns A map of asset types to balances.\n */\n async #getBalances(\n accountId: string,\n snapId: string,\n assetTypes: CaipAssetType[],\n ): Promise<Record<CaipAssetType, Balance>> {\n console.log('MultichainBalancesController - getBalances', {\n accountId,\n snapId,\n assetTypes,\n });\n const keyringClient = this.#getClient(snapId);\n console.log('MultichainBalancesController', { keyringClient });\n return await keyringClient.getAccountBalances(accountId, assetTypes);\n }\n\n /**\n * Gets a `KeyringClient` for a Snap.\n *\n * @param snapId - ID of the Snap to get the client for.\n * @returns A `KeyringClient` for the Snap.\n */\n #getClient(snapId: string): KeyringClient {\n return new KeyringClient({\n send: async (request: JsonRpcRequest) =>\n (await this.messagingSystem.call('SnapController:handleRequest', {\n snapId: snapId as SnapId,\n origin: 'metamask',\n handler: HandlerType.OnKeyringRequest,\n request,\n })) as Promise<Json>,\n });\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"MultichainBalancesController.d.cts","sourceRoot":"","sources":["../../src/MultichainBalancesController/MultichainBalancesController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mCAAmC,EACnC,qCAAqC,EACrC,8CAA8C,EAC/C,sCAAsC;AACvC,OAAO,EACL,cAAc,EACd,KAAK,wBAAwB,EAC7B,KAAK,0BAA0B,EAC/B,KAAK,6BAA6B,EACnC,kCAAkC;AAQnC,OAAO,KAAK,EAAE,iBAAiB,EAAE,oCAAoC;AAarE,QAAA,MAAM,cAAc,iCAAiC,CAAC;AAEtD;;GAEG;AACH,MAAM,MAAM,iCAAiC,GAAG;IAC9C,QAAQ,EAAE;QACR,CAAC,OAAO,EAAE,MAAM,GAAG;YACjB,CAAC,KAAK,EAAE,MAAM,GAAG;gBACf,MAAM,EAAE,MAAM,CAAC;gBACf,IAAI,EAAE,MAAM,CAAC;aACd,CAAC;SACH,CAAC;KACH,CAAC;CACH,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,YAAY,EAAE,iCAAoD,CAAC;AAEhF;;GAEG;AACH,MAAM,MAAM,0CAA0C,GACpD,wBAAwB,CACtB,OAAO,cAAc,EACrB,iCAAiC,CAClC,CAAC;AAEJ;;GAEG;AACH,MAAM,MAAM,gDAAgD,GAAG;IAC7D,IAAI,EAAE,GAAG,OAAO,cAAc,iBAAiB,CAAC;IAChD,OAAO,EAAE,4BAA4B,CAAC,gBAAgB,CAAC,CAAC;CACzD,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,uCAAuC,GACjD,0BAA0B,CACxB,OAAO,cAAc,EACrB,iCAAiC,CAClC,CAAC;AAEJ;;GAEG;AACH,MAAM,MAAM,mCAAmC,GAC3C,0CAA0C,GAC1C,gDAAgD,CAAC;AAErD;;GAEG;AACH,MAAM,MAAM,kCAAkC,GAC5C,uCAAuC,CAAC;AAE1C;;GAEG;AACH,MAAM,MAAM,cAAc,GACtB,iBAAiB,GACjB,8CAA8C,CAAC;AAEnD;;GAEG;AACH,MAAM,MAAM,aAAa,GACrB,mCAAmC,GACnC,qCAAqC,CAAC;AAE1C;;GAEG;AACH,MAAM,MAAM,qCAAqC,GAC/C,6BAA6B,CAC3B,OAAO,cAAc,EACrB,mCAAmC,GAAG,cAAc,EACpD,kCAAkC,GAAG,aAAa,EAClD,cAAc,CAAC,MAAM,CAAC,EACtB,aAAa,CAAC,MAAM,CAAC,CACtB,CAAC;AAgBJ;;;GAGG;AACH,qBAAa,4BAA6B,SAAQ,cAAc,CAC9D,OAAO,cAAc,EACrB,iCAAiC,EACjC,qCAAqC,CACtC;;gBAQa,EACV,SAAS,EACT,KAAK,GACN,EAAE;QACD,SAAS,EAAE,qCAAqC,CAAC;QACjD,KAAK,EAAE,iCAAiC,CAAC;KAC1C;IA8BD;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;OAEG;IACH,IAAI,IAAI,IAAI;IAsGZ;;;;;OAKG;IACG,aAAa,CAAC,SAAS,EAAE,MAAM;IAOrC;;;OAGG;IACG,cAAc;CA8FrB"}
1
+ {"version":3,"file":"MultichainBalancesController.d.cts","sourceRoot":"","sources":["../../src/MultichainBalancesController/MultichainBalancesController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mCAAmC,EACnC,qCAAqC,EACrC,8CAA8C,EAC/C,sCAAsC;AACvC,OAAO,EACL,cAAc,EACd,KAAK,wBAAwB,EAC7B,KAAK,0BAA0B,EAC/B,KAAK,6BAA6B,EACnC,kCAAkC;AAQnC,OAAO,KAAK,EAAE,iBAAiB,EAAE,oCAAoC;AAarE,QAAA,MAAM,cAAc,iCAAiC,CAAC;AAEtD;;GAEG;AACH,MAAM,MAAM,iCAAiC,GAAG;IAC9C,QAAQ,EAAE;QACR,CAAC,OAAO,EAAE,MAAM,GAAG;YACjB,CAAC,KAAK,EAAE,MAAM,GAAG;gBACf,MAAM,EAAE,MAAM,CAAC;gBACf,IAAI,EAAE,MAAM,CAAC;aACd,CAAC;SACH,CAAC;KACH,CAAC;CACH,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,YAAY,EAAE,iCAAoD,CAAC;AAEhF;;GAEG;AACH,MAAM,MAAM,0CAA0C,GACpD,wBAAwB,CACtB,OAAO,cAAc,EACrB,iCAAiC,CAClC,CAAC;AAEJ;;GAEG;AACH,MAAM,MAAM,gDAAgD,GAAG;IAC7D,IAAI,EAAE,GAAG,OAAO,cAAc,iBAAiB,CAAC;IAChD,OAAO,EAAE,4BAA4B,CAAC,gBAAgB,CAAC,CAAC;CACzD,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,uCAAuC,GACjD,0BAA0B,CACxB,OAAO,cAAc,EACrB,iCAAiC,CAClC,CAAC;AAEJ;;GAEG;AACH,MAAM,MAAM,mCAAmC,GAC3C,0CAA0C,GAC1C,gDAAgD,CAAC;AAErD;;GAEG;AACH,MAAM,MAAM,kCAAkC,GAC5C,uCAAuC,CAAC;AAE1C;;GAEG;AACH,MAAM,MAAM,cAAc,GACtB,iBAAiB,GACjB,8CAA8C,CAAC;AAEnD;;GAEG;AACH,MAAM,MAAM,aAAa,GACrB,mCAAmC,GACnC,qCAAqC,CAAC;AAE1C;;GAEG;AACH,MAAM,MAAM,qCAAqC,GAC/C,6BAA6B,CAC3B,OAAO,cAAc,EACrB,mCAAmC,GAAG,cAAc,EACpD,kCAAkC,GAAG,aAAa,EAClD,cAAc,CAAC,MAAM,CAAC,EACtB,aAAa,CAAC,MAAM,CAAC,CACtB,CAAC;AAgBJ;;;GAGG;AACH,qBAAa,4BAA6B,SAAQ,cAAc,CAC9D,OAAO,cAAc,EACrB,iCAAiC,EACjC,qCAAqC,CACtC;;gBAQa,EACV,SAAS,EACT,KAAK,GACN,EAAE;QACD,SAAS,EAAE,qCAAqC,CAAC;QACjD,KAAK,EAAE,iCAAiC,CAAC;KAC1C;IA8BD;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;OAEG;IACH,IAAI,IAAI,IAAI;IA0GZ;;;;;OAKG;IACG,aAAa,CAAC,SAAS,EAAE,MAAM;IAOrC;;;OAGG;IACG,cAAc;CAmGrB"}
@@ -1 +1 @@
1
- {"version":3,"file":"MultichainBalancesController.d.mts","sourceRoot":"","sources":["../../src/MultichainBalancesController/MultichainBalancesController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mCAAmC,EACnC,qCAAqC,EACrC,8CAA8C,EAC/C,sCAAsC;AACvC,OAAO,EACL,cAAc,EACd,KAAK,wBAAwB,EAC7B,KAAK,0BAA0B,EAC/B,KAAK,6BAA6B,EACnC,kCAAkC;AAQnC,OAAO,KAAK,EAAE,iBAAiB,EAAE,oCAAoC;AAarE,QAAA,MAAM,cAAc,iCAAiC,CAAC;AAEtD;;GAEG;AACH,MAAM,MAAM,iCAAiC,GAAG;IAC9C,QAAQ,EAAE;QACR,CAAC,OAAO,EAAE,MAAM,GAAG;YACjB,CAAC,KAAK,EAAE,MAAM,GAAG;gBACf,MAAM,EAAE,MAAM,CAAC;gBACf,IAAI,EAAE,MAAM,CAAC;aACd,CAAC;SACH,CAAC;KACH,CAAC;CACH,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,YAAY,EAAE,iCAAoD,CAAC;AAEhF;;GAEG;AACH,MAAM,MAAM,0CAA0C,GACpD,wBAAwB,CACtB,OAAO,cAAc,EACrB,iCAAiC,CAClC,CAAC;AAEJ;;GAEG;AACH,MAAM,MAAM,gDAAgD,GAAG;IAC7D,IAAI,EAAE,GAAG,OAAO,cAAc,iBAAiB,CAAC;IAChD,OAAO,EAAE,4BAA4B,CAAC,gBAAgB,CAAC,CAAC;CACzD,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,uCAAuC,GACjD,0BAA0B,CACxB,OAAO,cAAc,EACrB,iCAAiC,CAClC,CAAC;AAEJ;;GAEG;AACH,MAAM,MAAM,mCAAmC,GAC3C,0CAA0C,GAC1C,gDAAgD,CAAC;AAErD;;GAEG;AACH,MAAM,MAAM,kCAAkC,GAC5C,uCAAuC,CAAC;AAE1C;;GAEG;AACH,MAAM,MAAM,cAAc,GACtB,iBAAiB,GACjB,8CAA8C,CAAC;AAEnD;;GAEG;AACH,MAAM,MAAM,aAAa,GACrB,mCAAmC,GACnC,qCAAqC,CAAC;AAE1C;;GAEG;AACH,MAAM,MAAM,qCAAqC,GAC/C,6BAA6B,CAC3B,OAAO,cAAc,EACrB,mCAAmC,GAAG,cAAc,EACpD,kCAAkC,GAAG,aAAa,EAClD,cAAc,CAAC,MAAM,CAAC,EACtB,aAAa,CAAC,MAAM,CAAC,CACtB,CAAC;AAgBJ;;;GAGG;AACH,qBAAa,4BAA6B,SAAQ,cAAc,CAC9D,OAAO,cAAc,EACrB,iCAAiC,EACjC,qCAAqC,CACtC;;gBAQa,EACV,SAAS,EACT,KAAK,GACN,EAAE;QACD,SAAS,EAAE,qCAAqC,CAAC;QACjD,KAAK,EAAE,iCAAiC,CAAC;KAC1C;IA8BD;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;OAEG;IACH,IAAI,IAAI,IAAI;IAsGZ;;;;;OAKG;IACG,aAAa,CAAC,SAAS,EAAE,MAAM;IAOrC;;;OAGG;IACG,cAAc;CA8FrB"}
1
+ {"version":3,"file":"MultichainBalancesController.d.mts","sourceRoot":"","sources":["../../src/MultichainBalancesController/MultichainBalancesController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mCAAmC,EACnC,qCAAqC,EACrC,8CAA8C,EAC/C,sCAAsC;AACvC,OAAO,EACL,cAAc,EACd,KAAK,wBAAwB,EAC7B,KAAK,0BAA0B,EAC/B,KAAK,6BAA6B,EACnC,kCAAkC;AAQnC,OAAO,KAAK,EAAE,iBAAiB,EAAE,oCAAoC;AAarE,QAAA,MAAM,cAAc,iCAAiC,CAAC;AAEtD;;GAEG;AACH,MAAM,MAAM,iCAAiC,GAAG;IAC9C,QAAQ,EAAE;QACR,CAAC,OAAO,EAAE,MAAM,GAAG;YACjB,CAAC,KAAK,EAAE,MAAM,GAAG;gBACf,MAAM,EAAE,MAAM,CAAC;gBACf,IAAI,EAAE,MAAM,CAAC;aACd,CAAC;SACH,CAAC;KACH,CAAC;CACH,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,YAAY,EAAE,iCAAoD,CAAC;AAEhF;;GAEG;AACH,MAAM,MAAM,0CAA0C,GACpD,wBAAwB,CACtB,OAAO,cAAc,EACrB,iCAAiC,CAClC,CAAC;AAEJ;;GAEG;AACH,MAAM,MAAM,gDAAgD,GAAG;IAC7D,IAAI,EAAE,GAAG,OAAO,cAAc,iBAAiB,CAAC;IAChD,OAAO,EAAE,4BAA4B,CAAC,gBAAgB,CAAC,CAAC;CACzD,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,uCAAuC,GACjD,0BAA0B,CACxB,OAAO,cAAc,EACrB,iCAAiC,CAClC,CAAC;AAEJ;;GAEG;AACH,MAAM,MAAM,mCAAmC,GAC3C,0CAA0C,GAC1C,gDAAgD,CAAC;AAErD;;GAEG;AACH,MAAM,MAAM,kCAAkC,GAC5C,uCAAuC,CAAC;AAE1C;;GAEG;AACH,MAAM,MAAM,cAAc,GACtB,iBAAiB,GACjB,8CAA8C,CAAC;AAEnD;;GAEG;AACH,MAAM,MAAM,aAAa,GACrB,mCAAmC,GACnC,qCAAqC,CAAC;AAE1C;;GAEG;AACH,MAAM,MAAM,qCAAqC,GAC/C,6BAA6B,CAC3B,OAAO,cAAc,EACrB,mCAAmC,GAAG,cAAc,EACpD,kCAAkC,GAAG,aAAa,EAClD,cAAc,CAAC,MAAM,CAAC,EACtB,aAAa,CAAC,MAAM,CAAC,CACtB,CAAC;AAgBJ;;;GAGG;AACH,qBAAa,4BAA6B,SAAQ,cAAc,CAC9D,OAAO,cAAc,EACrB,iCAAiC,EACjC,qCAAqC,CACtC;;gBAQa,EACV,SAAS,EACT,KAAK,GACN,EAAE;QACD,SAAS,EAAE,qCAAqC,CAAC;QACjD,KAAK,EAAE,iCAAiC,CAAC;KAC1C;IA8BD;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;OAEG;IACH,IAAI,IAAI,IAAI;IA0GZ;;;;;OAKG;IACG,aAAa,CAAC,SAAS,EAAE,MAAM;IAOrC;;;OAGG;IACG,cAAc;CAmGrB"}
@@ -132,9 +132,13 @@ _MultichainBalancesController_tracker = new WeakMap(), _MultichainBalancesContro
132
132
  */
133
133
  async function _MultichainBalancesController_updateBalance(accountId) {
134
134
  const account = __classPrivateFieldGet(this, _MultichainBalancesController_instances, "m", _MultichainBalancesController_getAccount).call(this, accountId);
135
+ console.log('MultichainBalancesController updateBalance', { account });
135
136
  const partialState = { balances: {} };
137
+ console.log('MultichainBalancesController updateBalance', { partialState });
136
138
  const scope = getScopeForAddress(account);
139
+ console.log('MultichainBalancesController updateBalance', { scope });
137
140
  const assetsList = __classPrivateFieldGet(this, _MultichainBalancesController_networkAssetsMap, "f")[scope];
141
+ console.log('MultichainBalancesController updateBalance', { assetsList });
138
142
  if (account.metadata.snap) {
139
143
  partialState.balances[account.id] = await __classPrivateFieldGet(this, _MultichainBalancesController_instances, "m", _MultichainBalancesController_getBalances).call(this, account.id, account.metadata.snap.id, assetsList);
140
144
  }
@@ -196,6 +200,11 @@ async function _MultichainBalancesController_handleOnAccountRemoved(accountId) {
196
200
  * @returns A map of asset types to balances.
197
201
  */
198
202
  async function _MultichainBalancesController_getBalances(accountId, snapId, assetTypes) {
203
+ console.log('MultichainBalancesController - getBalances', {
204
+ accountId,
205
+ snapId,
206
+ assetTypes,
207
+ });
199
208
  const keyringClient = __classPrivateFieldGet(this, _MultichainBalancesController_instances, "m", _MultichainBalancesController_getClient).call(this, snapId);
200
209
  console.log('MultichainBalancesController', { keyringClient });
201
210
  return await keyringClient.getAccountBalances(accountId, assetTypes);
@@ -1 +1 @@
1
- {"version":3,"file":"MultichainBalancesController.mjs","sourceRoot":"","sources":["../../src/MultichainBalancesController/MultichainBalancesController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n AccountsControllerAccountAddedEvent,\n AccountsControllerAccountRemovedEvent,\n AccountsControllerListMultichainAccountsAction,\n} from '@metamask/accounts-controller';\nimport {\n BaseController,\n type ControllerGetStateAction,\n type ControllerStateChangeEvent,\n type RestrictedControllerMessenger,\n} from '@metamask/base-controller';\nimport {\n KeyringClient,\n type Balance,\n type CaipAssetType,\n type InternalAccount,\n isEvmAccountType,\n} from '@metamask/keyring-api';\nimport type { HandleSnapRequest } from '@metamask/snaps-controllers';\nimport type { SnapId } from '@metamask/snaps-sdk';\nimport { HandlerType } from '@metamask/snaps-utils';\nimport type { Json, JsonRpcRequest } from '@metamask/utils';\nimport type { Draft } from 'immer';\n\nimport {\n BalancesTracker,\n BALANCE_UPDATE_INTERVALS,\n NETWORK_ASSETS_MAP,\n} from '.';\nimport { getScopeForAddress } from './utils';\n\nconst controllerName = 'MultichainBalancesController';\n\n/**\n * State used by the {@link MultichainBalancesController} to cache account balances.\n */\nexport type MultichainBalancesControllerState = {\n balances: {\n [account: string]: {\n [asset: string]: {\n amount: string;\n unit: string;\n };\n };\n };\n};\n\n/**\n * Default state of the {@link MultichainBalancesController}.\n */\nexport const defaultState: MultichainBalancesControllerState = { balances: {} };\n\n/**\n * Returns the state of the {@link MultichainBalancesController}.\n */\nexport type MultichainBalancesControllerGetStateAction =\n ControllerGetStateAction<\n typeof controllerName,\n MultichainBalancesControllerState\n >;\n\n/**\n * Updates the balances of all supported accounts in {@link MultichainBalancesController}.\n */\nexport type MultichainBalancesControllerUpdateBalancesAction = {\n type: `${typeof controllerName}:updateBalances`;\n handler: MultichainBalancesController['updateBalances'];\n};\n\n/**\n * Event emitted when the state of the {@link MultichainBalancesController} changes.\n */\nexport type MultichainBalancesControllerStateChange =\n ControllerStateChangeEvent<\n typeof controllerName,\n MultichainBalancesControllerState\n >;\n\n/**\n * Actions exposed by the {@link MultichainBalancesController}.\n */\nexport type MultichainBalancesControllerActions =\n | MultichainBalancesControllerGetStateAction\n | MultichainBalancesControllerUpdateBalancesAction;\n\n/**\n * Events emitted by {@link MultichainBalancesController}.\n */\nexport type MultichainBalancesControllerEvents =\n MultichainBalancesControllerStateChange;\n\n/**\n * Actions that this controller is allowed to call.\n */\nexport type AllowedActions =\n | HandleSnapRequest\n | AccountsControllerListMultichainAccountsAction;\n\n/**\n * Events that this controller is allowed to subscribe.\n */\nexport type AllowedEvents =\n | AccountsControllerAccountAddedEvent\n | AccountsControllerAccountRemovedEvent;\n\n/**\n * Messenger type for the MultichainBalancesController.\n */\nexport type MultichainBalancesControllerMessenger =\n RestrictedControllerMessenger<\n typeof controllerName,\n MultichainBalancesControllerActions | AllowedActions,\n MultichainBalancesControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n >;\n\n/**\n * {@link multichainBalancesController}'s metadata.\n *\n * This allows us to choose if fields of the state should be persisted or not\n * using the `persist` flag; and if they can be sent to Sentry or not, using\n * the `anonymous` flag.\n */\nconst multichainBalancesControllerMetadata = {\n balances: {\n persist: true,\n anonymous: false,\n },\n};\n\n/**\n * The MultichainBalancesController is responsible for fetching and caching account\n * balances.\n */\nexport class MultichainBalancesController extends BaseController<\n typeof controllerName,\n MultichainBalancesControllerState,\n MultichainBalancesControllerMessenger\n> {\n readonly #tracker: BalancesTracker;\n\n // As a temporary solution, we are using a map to store the assets\n // that are hardcoded in the module. In the future, this mapping\n // should be dynamic to allow a client to register and unregister assets\n readonly #networkAssetsMap: Record<string, string[]> = NETWORK_ASSETS_MAP;\n\n constructor({\n messenger,\n state,\n }: {\n messenger: MultichainBalancesControllerMessenger;\n state: MultichainBalancesControllerState;\n }) {\n super({\n messenger,\n name: controllerName,\n metadata: multichainBalancesControllerMetadata,\n state: {\n ...defaultState,\n ...state,\n },\n });\n\n this.#tracker = new BalancesTracker(\n async (accountId: string) => await this.#updateBalance(accountId),\n );\n\n // Register all non-EVM accounts into the tracker\n for (const account of this.#listAccounts()) {\n this.#trackAccount(account);\n }\n\n this.messagingSystem.subscribe(\n 'AccountsController:accountAdded',\n (account) => this.#handleOnAccountAdded(account),\n );\n this.messagingSystem.subscribe(\n 'AccountsController:accountRemoved',\n (account) => this.#handleOnAccountRemoved(account),\n );\n }\n\n /**\n * Starts the polling process.\n */\n start(): void {\n this.#tracker.start();\n }\n\n /**\n * Stops the polling process.\n */\n stop(): void {\n this.#tracker.stop();\n }\n\n /**\n * Tracks an account to get its balances.\n *\n * @param account - The account to track.\n */\n #trackAccount(account: InternalAccount): void {\n if (!this.#isNonEvmAccount(account)) {\n // Nothing to do here for EVM accounts\n console.log(\n 'MultichainBalancesController - early return in #trackAccount',\n account,\n );\n return;\n }\n\n const updateTime =\n // @ts-expect-error - For the moment we are only tracking non-EVM accounts and this is\n // checked with the method `#isNonEvmAccount`. We can ignore this error since\n // eip155:eoa and eip155:erc4337 account type balances are not tracked here.\n BALANCE_UPDATE_INTERVALS[this.#getAccount(account.id).type];\n this.#tracker.track(account.id, updateTime);\n }\n\n /**\n * Lists the multichain accounts coming from the `AccountsController`.\n *\n * @returns A list of multichain accounts.\n */\n #listMultichainAccounts(): InternalAccount[] {\n return this.messagingSystem.call(\n 'AccountsController:listMultichainAccounts',\n );\n }\n\n /**\n * Lists the accounts that we should get balances for.\n *\n * Currently, we only get balances for non-EVM accounts.\n *\n * @returns A list of accounts that we should get balances for.\n */\n #listAccounts(): InternalAccount[] {\n const accounts = this.#listMultichainAccounts();\n\n return accounts.filter((account) => this.#isNonEvmAccount(account));\n }\n\n /**\n * Get a non-EVM account from its ID.\n *\n * @param accountId - The account ID.\n * @returns The non-EVM account.\n */\n #getAccount(accountId: string): InternalAccount {\n const account: InternalAccount | undefined =\n this.#listMultichainAccounts().find(\n (multichainAccount) => multichainAccount.id === accountId,\n );\n\n if (!account) {\n throw new Error(`Unknown account: ${accountId}`);\n }\n if (!this.#isNonEvmAccount(account)) {\n throw new Error(`Account is not a non-EVM account: ${accountId}`);\n }\n return account;\n }\n\n /**\n * Updates the balances of one account. This method doesn't return\n * anything, but it updates the state of the controller.\n *\n * @param accountId - The account ID.\n */\n async #updateBalance(accountId: string) {\n const account = this.#getAccount(accountId);\n const partialState: MultichainBalancesControllerState = { balances: {} };\n\n const scope = getScopeForAddress(account);\n const assetsList = this.#networkAssetsMap[scope];\n\n if (account.metadata.snap) {\n partialState.balances[account.id] = await this.#getBalances(\n account.id,\n account.metadata.snap.id,\n assetsList,\n );\n }\n\n console.log('MultichainBalancesController update state', { partialState });\n this.update((state: Draft<MultichainBalancesControllerState>) => {\n state.balances = {\n ...state.balances,\n ...partialState.balances,\n };\n });\n }\n\n /**\n * Updates the balances of one account. This method doesn't return\n * anything, but it updates the state of the controller.\n *\n * @param accountId - The account ID.\n */\n async updateBalance(accountId: string) {\n console.log('MultichainBalancesController updateBalance', { accountId });\n // NOTE: No need to track the account here, since we start tracking those when\n // the \"AccountsController:accountAdded\" is fired.\n await this.#tracker.updateBalance(accountId);\n }\n\n /**\n * Updates the balances of all supported accounts. This method doesn't return\n * anything, but it updates the state of the controller.\n */\n async updateBalances() {\n console.log('MultichainBalancesController updateBalances');\n await this.#tracker.updateBalances();\n }\n\n /**\n * Checks for non-EVM accounts.\n *\n * @param account - The new account to be checked.\n * @returns True if the account is a non-EVM account, false otherwise.\n */\n #isNonEvmAccount(account: InternalAccount): boolean {\n return (\n !isEvmAccountType(account.type) &&\n // Non-EVM accounts are backed by a Snap for now\n account.metadata.snap !== undefined\n );\n }\n\n /**\n * Handles changes when a new account has been added.\n *\n * @param account - The new account being added.\n */\n async #handleOnAccountAdded(account: InternalAccount) {\n console.log('MultichainBalancesController handleOnAccountAdded', {\n account,\n });\n this.#trackAccount(account);\n // NOTE: Unfortunately, we cannot update the balance right away here, because\n // messenger's events are running synchronously and fetching the balance is\n // asynchronous.\n // Updating the balance here would resume at some point but the event emitter\n // will not `await` this (so we have no real control \"when\" the balance will\n // really be updated), see:\n // - https://github.com/MetaMask/core/blob/v213.0.0/packages/accounts-controller/src/AccountsController.ts#L1036-L1039\n }\n\n /**\n * Handles changes when a new account has been removed.\n *\n * @param accountId - The account ID being removed.\n */\n async #handleOnAccountRemoved(accountId: string) {\n console.log('MultichainBalancesController handleOnAccountAdded', {\n accountId,\n });\n if (this.#tracker.isTracked(accountId)) {\n this.#tracker.untrack(accountId);\n }\n\n if (accountId in this.state.balances) {\n this.update((state: Draft<MultichainBalancesControllerState>) => {\n delete state.balances[accountId];\n return state;\n });\n }\n }\n\n /**\n * Get the balances for an account.\n *\n * @param accountId - ID of the account to get balances for.\n * @param snapId - ID of the Snap which manages the account.\n * @param assetTypes - Array of asset types to get balances for.\n * @returns A map of asset types to balances.\n */\n async #getBalances(\n accountId: string,\n snapId: string,\n assetTypes: CaipAssetType[],\n ): Promise<Record<CaipAssetType, Balance>> {\n const keyringClient = this.#getClient(snapId);\n console.log('MultichainBalancesController', { keyringClient });\n return await keyringClient.getAccountBalances(accountId, assetTypes);\n }\n\n /**\n * Gets a `KeyringClient` for a Snap.\n *\n * @param snapId - ID of the Snap to get the client for.\n * @returns A `KeyringClient` for the Snap.\n */\n #getClient(snapId: string): KeyringClient {\n return new KeyringClient({\n send: async (request: JsonRpcRequest) =>\n (await this.messagingSystem.call('SnapController:handleRequest', {\n snapId: snapId as SnapId,\n origin: 'metamask',\n handler: HandlerType.OnKeyringRequest,\n request,\n })) as Promise<Json>,\n });\n }\n}\n"]}
1
+ {"version":3,"file":"MultichainBalancesController.mjs","sourceRoot":"","sources":["../../src/MultichainBalancesController/MultichainBalancesController.ts"],"names":[],"mappings":";;;;;;;;;;;;AAKA,OAAO,EACL,cAAc,EAIf,kCAAkC;;;;AAUnC,OAAO,EAAE,WAAW,EAAE,8BAA8B;AAIpD,OAAO,EACL,eAAe,EACf,wBAAwB,EACxB,kBAAkB,EACnB,oBAAU;AACX,OAAO,EAAE,kBAAkB,EAAE,oBAAgB;AAE7C,MAAM,cAAc,GAAG,8BAA8B,CAAC;AAgBtD;;GAEG;AACH,MAAM,CAAC,MAAM,YAAY,GAAsC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;AAmEhF;;;;;;GAMG;AACH,MAAM,oCAAoC,GAAG;IAC3C,QAAQ,EAAE;QACR,OAAO,EAAE,IAAI;QACb,SAAS,EAAE,KAAK;KACjB;CACF,CAAC;AAEF;;;GAGG;AACH,MAAM,OAAO,4BAA6B,SAAQ,cAIjD;IAQC,YAAY,EACV,SAAS,EACT,KAAK,GAIN;QACC,KAAK,CAAC;YACJ,SAAS;YACT,IAAI,EAAE,cAAc;YACpB,QAAQ,EAAE,oCAAoC;YAC9C,KAAK,EAAE;gBACL,GAAG,YAAY;gBACf,GAAG,KAAK;aACT;SACF,CAAC,CAAC;;QAtBI,wDAA0B;QAEnC,kEAAkE;QAClE,gEAAgE;QAChE,wEAAwE;QAC/D,yDAA8C,kBAAkB,EAAC;QAmBxE,uBAAA,IAAI,yCAAY,IAAI,eAAe,CACjC,KAAK,EAAE,SAAiB,EAAE,EAAE,CAAC,MAAM,uBAAA,IAAI,4FAAe,MAAnB,IAAI,EAAgB,SAAS,CAAC,CAClE,MAAA,CAAC;QAEF,iDAAiD;QACjD,KAAK,MAAM,OAAO,IAAI,uBAAA,IAAI,2FAAc,MAAlB,IAAI,CAAgB,EAAE;YAC1C,uBAAA,IAAI,2FAAc,MAAlB,IAAI,EAAe,OAAO,CAAC,CAAC;SAC7B;QAED,IAAI,CAAC,eAAe,CAAC,SAAS,CAC5B,iCAAiC,EACjC,CAAC,OAAO,EAAE,EAAE,CAAC,uBAAA,IAAI,mGAAsB,MAA1B,IAAI,EAAuB,OAAO,CAAC,CACjD,CAAC;QACF,IAAI,CAAC,eAAe,CAAC,SAAS,CAC5B,mCAAmC,EACnC,CAAC,OAAO,EAAE,EAAE,CAAC,uBAAA,IAAI,qGAAwB,MAA5B,IAAI,EAAyB,OAAO,CAAC,CACnD,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK;QACH,uBAAA,IAAI,6CAAS,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;IAED;;OAEG;IACH,IAAI;QACF,uBAAA,IAAI,6CAAS,CAAC,IAAI,EAAE,CAAC;IACvB,CAAC;IAwGD;;;;;OAKG;IACH,KAAK,CAAC,aAAa,CAAC,SAAiB;QACnC,OAAO,CAAC,GAAG,CAAC,4CAA4C,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;QACzE,8EAA8E;QAC9E,kDAAkD;QAClD,MAAM,uBAAA,IAAI,6CAAS,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;IAC/C,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,cAAc;QAClB,OAAO,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC;QAC3D,MAAM,uBAAA,IAAI,6CAAS,CAAC,cAAc,EAAE,CAAC;IACvC,CAAC;CAgGF;iRArNe,OAAwB;IACpC,IAAI,CAAC,uBAAA,IAAI,8FAAiB,MAArB,IAAI,EAAkB,OAAO,CAAC,EAAE;QACnC,sCAAsC;QACtC,OAAO,CAAC,GAAG,CACT,8DAA8D,EAC9D,OAAO,CACR,CAAC;QACF,OAAO;KACR;IAED,MAAM,UAAU;IACd,sFAAsF;IACtF,6EAA6E;IAC7E,4EAA4E;IAC5E,wBAAwB,CAAC,uBAAA,IAAI,yFAAY,MAAhB,IAAI,EAAa,OAAO,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;IAC9D,uBAAA,IAAI,6CAAS,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;AAC9C,CAAC;IAQC,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,CAC9B,2CAA2C,CAC5C,CAAC;AACJ,CAAC;IAUC,MAAM,QAAQ,GAAG,uBAAA,IAAI,qGAAwB,MAA5B,IAAI,CAA0B,CAAC;IAEhD,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,uBAAA,IAAI,8FAAiB,MAArB,IAAI,EAAkB,OAAO,CAAC,CAAC,CAAC;AACtE,CAAC,+FAQW,SAAiB;IAC3B,MAAM,OAAO,GACX,uBAAA,IAAI,qGAAwB,MAA5B,IAAI,CAA0B,CAAC,IAAI,CACjC,CAAC,iBAAiB,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,KAAK,SAAS,CAC1D,CAAC;IAEJ,IAAI,CAAC,OAAO,EAAE;QACZ,MAAM,IAAI,KAAK,CAAC,oBAAoB,SAAS,EAAE,CAAC,CAAC;KAClD;IACD,IAAI,CAAC,uBAAA,IAAI,8FAAiB,MAArB,IAAI,EAAkB,OAAO,CAAC,EAAE;QACnC,MAAM,IAAI,KAAK,CAAC,qCAAqC,SAAS,EAAE,CAAC,CAAC;KACnE;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;GAKG;AACH,KAAK,sDAAgB,SAAiB;IACpC,MAAM,OAAO,GAAG,uBAAA,IAAI,yFAAY,MAAhB,IAAI,EAAa,SAAS,CAAC,CAAC;IAC5C,OAAO,CAAC,GAAG,CAAC,4CAA4C,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;IACvE,MAAM,YAAY,GAAsC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;IACzE,OAAO,CAAC,GAAG,CAAC,4CAA4C,EAAE,EAAE,YAAY,EAAE,CAAC,CAAC;IAE5E,MAAM,KAAK,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAC1C,OAAO,CAAC,GAAG,CAAC,4CAA4C,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;IACrE,MAAM,UAAU,GAAG,uBAAA,IAAI,sDAAkB,CAAC,KAAK,CAAC,CAAC;IACjD,OAAO,CAAC,GAAG,CAAC,4CAA4C,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;IAE1E,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE;QACzB,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,MAAM,uBAAA,IAAI,0FAAa,MAAjB,IAAI,EAC5C,OAAO,CAAC,EAAE,EACV,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,EACxB,UAAU,CACX,CAAC;KACH;IAED,OAAO,CAAC,GAAG,CAAC,2CAA2C,EAAE,EAAE,YAAY,EAAE,CAAC,CAAC;IAC3E,IAAI,CAAC,MAAM,CAAC,CAAC,KAA+C,EAAE,EAAE;QAC9D,KAAK,CAAC,QAAQ,GAAG;YACf,GAAG,KAAK,CAAC,QAAQ;YACjB,GAAG,YAAY,CAAC,QAAQ;SACzB,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,yGA8BgB,OAAwB;IACvC,OAAO,CACL,CAAC,gBAAgB,CAAC,OAAO,CAAC,IAAI,CAAC;QAC/B,gDAAgD;QAChD,OAAO,CAAC,QAAQ,CAAC,IAAI,KAAK,SAAS,CACpC,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,KAAK,6DAAuB,OAAwB;IAClD,OAAO,CAAC,GAAG,CAAC,mDAAmD,EAAE;QAC/D,OAAO;KACR,CAAC,CAAC;IACH,uBAAA,IAAI,2FAAc,MAAlB,IAAI,EAAe,OAAO,CAAC,CAAC;IAC5B,6EAA6E;IAC7E,2EAA2E;IAC3E,gBAAgB;IAChB,6EAA6E;IAC7E,4EAA4E;IAC5E,2BAA2B;IAC3B,sHAAsH;AACxH,CAAC;AAED;;;;GAIG;AACH,KAAK,+DAAyB,SAAiB;IAC7C,OAAO,CAAC,GAAG,CAAC,mDAAmD,EAAE;QAC/D,SAAS;KACV,CAAC,CAAC;IACH,IAAI,uBAAA,IAAI,6CAAS,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE;QACtC,uBAAA,IAAI,6CAAS,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;KAClC;IAED,IAAI,SAAS,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE;QACpC,IAAI,CAAC,MAAM,CAAC,CAAC,KAA+C,EAAE,EAAE;YAC9D,OAAO,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;YACjC,OAAO,KAAK,CAAC;QACf,CAAC,CAAC,CAAC;KACJ;AACH,CAAC;AAED;;;;;;;GAOG;AACH,KAAK,oDACH,SAAiB,EACjB,MAAc,EACd,UAA2B;IAE3B,OAAO,CAAC,GAAG,CAAC,4CAA4C,EAAE;QACxD,SAAS;QACT,MAAM;QACN,UAAU;KACX,CAAC,CAAC;IACH,MAAM,aAAa,GAAG,uBAAA,IAAI,wFAAW,MAAf,IAAI,EAAY,MAAM,CAAC,CAAC;IAC9C,OAAO,CAAC,GAAG,CAAC,8BAA8B,EAAE,EAAE,aAAa,EAAE,CAAC,CAAC;IAC/D,OAAO,MAAM,aAAa,CAAC,kBAAkB,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;AACvE,CAAC,6FAQU,MAAc;IACvB,OAAO,IAAI,aAAa,CAAC;QACvB,IAAI,EAAE,KAAK,EAAE,OAAuB,EAAE,EAAE,CACtC,CAAC,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,8BAA8B,EAAE;YAC/D,MAAM,EAAE,MAAgB;YACxB,MAAM,EAAE,UAAU;YAClB,OAAO,EAAE,WAAW,CAAC,gBAAgB;YACrC,OAAO;SACR,CAAC,CAAkB;KACvB,CAAC,CAAC;AACL,CAAC","sourcesContent":["import type {\n AccountsControllerAccountAddedEvent,\n AccountsControllerAccountRemovedEvent,\n AccountsControllerListMultichainAccountsAction,\n} from '@metamask/accounts-controller';\nimport {\n BaseController,\n type ControllerGetStateAction,\n type ControllerStateChangeEvent,\n type RestrictedControllerMessenger,\n} from '@metamask/base-controller';\nimport {\n KeyringClient,\n type Balance,\n type CaipAssetType,\n type InternalAccount,\n isEvmAccountType,\n} from '@metamask/keyring-api';\nimport type { HandleSnapRequest } from '@metamask/snaps-controllers';\nimport type { SnapId } from '@metamask/snaps-sdk';\nimport { HandlerType } from '@metamask/snaps-utils';\nimport type { Json, JsonRpcRequest } from '@metamask/utils';\nimport type { Draft } from 'immer';\n\nimport {\n BalancesTracker,\n BALANCE_UPDATE_INTERVALS,\n NETWORK_ASSETS_MAP,\n} from '.';\nimport { getScopeForAddress } from './utils';\n\nconst controllerName = 'MultichainBalancesController';\n\n/**\n * State used by the {@link MultichainBalancesController} to cache account balances.\n */\nexport type MultichainBalancesControllerState = {\n balances: {\n [account: string]: {\n [asset: string]: {\n amount: string;\n unit: string;\n };\n };\n };\n};\n\n/**\n * Default state of the {@link MultichainBalancesController}.\n */\nexport const defaultState: MultichainBalancesControllerState = { balances: {} };\n\n/**\n * Returns the state of the {@link MultichainBalancesController}.\n */\nexport type MultichainBalancesControllerGetStateAction =\n ControllerGetStateAction<\n typeof controllerName,\n MultichainBalancesControllerState\n >;\n\n/**\n * Updates the balances of all supported accounts in {@link MultichainBalancesController}.\n */\nexport type MultichainBalancesControllerUpdateBalancesAction = {\n type: `${typeof controllerName}:updateBalances`;\n handler: MultichainBalancesController['updateBalances'];\n};\n\n/**\n * Event emitted when the state of the {@link MultichainBalancesController} changes.\n */\nexport type MultichainBalancesControllerStateChange =\n ControllerStateChangeEvent<\n typeof controllerName,\n MultichainBalancesControllerState\n >;\n\n/**\n * Actions exposed by the {@link MultichainBalancesController}.\n */\nexport type MultichainBalancesControllerActions =\n | MultichainBalancesControllerGetStateAction\n | MultichainBalancesControllerUpdateBalancesAction;\n\n/**\n * Events emitted by {@link MultichainBalancesController}.\n */\nexport type MultichainBalancesControllerEvents =\n MultichainBalancesControllerStateChange;\n\n/**\n * Actions that this controller is allowed to call.\n */\nexport type AllowedActions =\n | HandleSnapRequest\n | AccountsControllerListMultichainAccountsAction;\n\n/**\n * Events that this controller is allowed to subscribe.\n */\nexport type AllowedEvents =\n | AccountsControllerAccountAddedEvent\n | AccountsControllerAccountRemovedEvent;\n\n/**\n * Messenger type for the MultichainBalancesController.\n */\nexport type MultichainBalancesControllerMessenger =\n RestrictedControllerMessenger<\n typeof controllerName,\n MultichainBalancesControllerActions | AllowedActions,\n MultichainBalancesControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n >;\n\n/**\n * {@link multichainBalancesController}'s metadata.\n *\n * This allows us to choose if fields of the state should be persisted or not\n * using the `persist` flag; and if they can be sent to Sentry or not, using\n * the `anonymous` flag.\n */\nconst multichainBalancesControllerMetadata = {\n balances: {\n persist: true,\n anonymous: false,\n },\n};\n\n/**\n * The MultichainBalancesController is responsible for fetching and caching account\n * balances.\n */\nexport class MultichainBalancesController extends BaseController<\n typeof controllerName,\n MultichainBalancesControllerState,\n MultichainBalancesControllerMessenger\n> {\n readonly #tracker: BalancesTracker;\n\n // As a temporary solution, we are using a map to store the assets\n // that are hardcoded in the module. In the future, this mapping\n // should be dynamic to allow a client to register and unregister assets\n readonly #networkAssetsMap: Record<string, string[]> = NETWORK_ASSETS_MAP;\n\n constructor({\n messenger,\n state,\n }: {\n messenger: MultichainBalancesControllerMessenger;\n state: MultichainBalancesControllerState;\n }) {\n super({\n messenger,\n name: controllerName,\n metadata: multichainBalancesControllerMetadata,\n state: {\n ...defaultState,\n ...state,\n },\n });\n\n this.#tracker = new BalancesTracker(\n async (accountId: string) => await this.#updateBalance(accountId),\n );\n\n // Register all non-EVM accounts into the tracker\n for (const account of this.#listAccounts()) {\n this.#trackAccount(account);\n }\n\n this.messagingSystem.subscribe(\n 'AccountsController:accountAdded',\n (account) => this.#handleOnAccountAdded(account),\n );\n this.messagingSystem.subscribe(\n 'AccountsController:accountRemoved',\n (account) => this.#handleOnAccountRemoved(account),\n );\n }\n\n /**\n * Starts the polling process.\n */\n start(): void {\n this.#tracker.start();\n }\n\n /**\n * Stops the polling process.\n */\n stop(): void {\n this.#tracker.stop();\n }\n\n /**\n * Tracks an account to get its balances.\n *\n * @param account - The account to track.\n */\n #trackAccount(account: InternalAccount): void {\n if (!this.#isNonEvmAccount(account)) {\n // Nothing to do here for EVM accounts\n console.log(\n 'MultichainBalancesController - early return in #trackAccount',\n account,\n );\n return;\n }\n\n const updateTime =\n // @ts-expect-error - For the moment we are only tracking non-EVM accounts and this is\n // checked with the method `#isNonEvmAccount`. We can ignore this error since\n // eip155:eoa and eip155:erc4337 account type balances are not tracked here.\n BALANCE_UPDATE_INTERVALS[this.#getAccount(account.id).type];\n this.#tracker.track(account.id, updateTime);\n }\n\n /**\n * Lists the multichain accounts coming from the `AccountsController`.\n *\n * @returns A list of multichain accounts.\n */\n #listMultichainAccounts(): InternalAccount[] {\n return this.messagingSystem.call(\n 'AccountsController:listMultichainAccounts',\n );\n }\n\n /**\n * Lists the accounts that we should get balances for.\n *\n * Currently, we only get balances for non-EVM accounts.\n *\n * @returns A list of accounts that we should get balances for.\n */\n #listAccounts(): InternalAccount[] {\n const accounts = this.#listMultichainAccounts();\n\n return accounts.filter((account) => this.#isNonEvmAccount(account));\n }\n\n /**\n * Get a non-EVM account from its ID.\n *\n * @param accountId - The account ID.\n * @returns The non-EVM account.\n */\n #getAccount(accountId: string): InternalAccount {\n const account: InternalAccount | undefined =\n this.#listMultichainAccounts().find(\n (multichainAccount) => multichainAccount.id === accountId,\n );\n\n if (!account) {\n throw new Error(`Unknown account: ${accountId}`);\n }\n if (!this.#isNonEvmAccount(account)) {\n throw new Error(`Account is not a non-EVM account: ${accountId}`);\n }\n return account;\n }\n\n /**\n * Updates the balances of one account. This method doesn't return\n * anything, but it updates the state of the controller.\n *\n * @param accountId - The account ID.\n */\n async #updateBalance(accountId: string) {\n const account = this.#getAccount(accountId);\n console.log('MultichainBalancesController updateBalance', { account });\n const partialState: MultichainBalancesControllerState = { balances: {} };\n console.log('MultichainBalancesController updateBalance', { partialState });\n\n const scope = getScopeForAddress(account);\n console.log('MultichainBalancesController updateBalance', { scope });\n const assetsList = this.#networkAssetsMap[scope];\n console.log('MultichainBalancesController updateBalance', { assetsList });\n\n if (account.metadata.snap) {\n partialState.balances[account.id] = await this.#getBalances(\n account.id,\n account.metadata.snap.id,\n assetsList,\n );\n }\n\n console.log('MultichainBalancesController update state', { partialState });\n this.update((state: Draft<MultichainBalancesControllerState>) => {\n state.balances = {\n ...state.balances,\n ...partialState.balances,\n };\n });\n }\n\n /**\n * Updates the balances of one account. This method doesn't return\n * anything, but it updates the state of the controller.\n *\n * @param accountId - The account ID.\n */\n async updateBalance(accountId: string) {\n console.log('MultichainBalancesController updateBalance', { accountId });\n // NOTE: No need to track the account here, since we start tracking those when\n // the \"AccountsController:accountAdded\" is fired.\n await this.#tracker.updateBalance(accountId);\n }\n\n /**\n * Updates the balances of all supported accounts. This method doesn't return\n * anything, but it updates the state of the controller.\n */\n async updateBalances() {\n console.log('MultichainBalancesController updateBalances');\n await this.#tracker.updateBalances();\n }\n\n /**\n * Checks for non-EVM accounts.\n *\n * @param account - The new account to be checked.\n * @returns True if the account is a non-EVM account, false otherwise.\n */\n #isNonEvmAccount(account: InternalAccount): boolean {\n return (\n !isEvmAccountType(account.type) &&\n // Non-EVM accounts are backed by a Snap for now\n account.metadata.snap !== undefined\n );\n }\n\n /**\n * Handles changes when a new account has been added.\n *\n * @param account - The new account being added.\n */\n async #handleOnAccountAdded(account: InternalAccount) {\n console.log('MultichainBalancesController handleOnAccountAdded', {\n account,\n });\n this.#trackAccount(account);\n // NOTE: Unfortunately, we cannot update the balance right away here, because\n // messenger's events are running synchronously and fetching the balance is\n // asynchronous.\n // Updating the balance here would resume at some point but the event emitter\n // will not `await` this (so we have no real control \"when\" the balance will\n // really be updated), see:\n // - https://github.com/MetaMask/core/blob/v213.0.0/packages/accounts-controller/src/AccountsController.ts#L1036-L1039\n }\n\n /**\n * Handles changes when a new account has been removed.\n *\n * @param accountId - The account ID being removed.\n */\n async #handleOnAccountRemoved(accountId: string) {\n console.log('MultichainBalancesController handleOnAccountAdded', {\n accountId,\n });\n if (this.#tracker.isTracked(accountId)) {\n this.#tracker.untrack(accountId);\n }\n\n if (accountId in this.state.balances) {\n this.update((state: Draft<MultichainBalancesControllerState>) => {\n delete state.balances[accountId];\n return state;\n });\n }\n }\n\n /**\n * Get the balances for an account.\n *\n * @param accountId - ID of the account to get balances for.\n * @param snapId - ID of the Snap which manages the account.\n * @param assetTypes - Array of asset types to get balances for.\n * @returns A map of asset types to balances.\n */\n async #getBalances(\n accountId: string,\n snapId: string,\n assetTypes: CaipAssetType[],\n ): Promise<Record<CaipAssetType, Balance>> {\n console.log('MultichainBalancesController - getBalances', {\n accountId,\n snapId,\n assetTypes,\n });\n const keyringClient = this.#getClient(snapId);\n console.log('MultichainBalancesController', { keyringClient });\n return await keyringClient.getAccountBalances(accountId, assetTypes);\n }\n\n /**\n * Gets a `KeyringClient` for a Snap.\n *\n * @param snapId - ID of the Snap to get the client for.\n * @returns A `KeyringClient` for the Snap.\n */\n #getClient(snapId: string): KeyringClient {\n return new KeyringClient({\n send: async (request: JsonRpcRequest) =>\n (await this.messagingSystem.call('SnapController:handleRequest', {\n snapId: snapId as SnapId,\n origin: 'metamask',\n handler: HandlerType.OnKeyringRequest,\n request,\n })) as Promise<Json>,\n });\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metamask-previews/assets-controllers",
3
- "version": "45.1.1-preview-a1e11fbb",
3
+ "version": "45.1.1-preview-3178c25e",
4
4
  "description": "Controllers which manage interactions involving ERC-20, ERC-721, and ERC-1155 tokens (including NFTs)",
5
5
  "keywords": [
6
6
  "MetaMask",