@metamask-previews/account-tree-controller 0.1.0-preview-7dcef379 → 0.1.0-preview-5dcecbb7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AccountTreeController.cjs.map +1 -1
- package/dist/AccountTreeController.d.cts +1 -1
- package/dist/AccountTreeController.d.cts.map +1 -1
- package/dist/AccountTreeController.d.mts +1 -1
- package/dist/AccountTreeController.d.mts.map +1 -1
- package/dist/AccountTreeController.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AccountTreeController.cjs","sourceRoot":"","sources":["../src/AccountTreeController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n AccountId,\n AccountsControllerAccountAddedEvent,\n AccountsControllerAccountRemovedEvent,\n AccountsControllerListMultichainAccountsAction,\n} from '@metamask/accounts-controller';\nimport type { StateMetadata } from '@metamask/base-controller';\nimport {\n type ControllerGetStateAction,\n type ControllerStateChangeEvent,\n type RestrictedMessenger,\n BaseController,\n} from '@metamask/base-controller';\nimport type { KeyringControllerGetStateAction } from '@metamask/keyring-controller';\nimport { KeyringTypes } from '@metamask/keyring-controller';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\nimport type { GetSnap as SnapControllerGetSnap } from '@metamask/snaps-controllers';\nimport type { SnapId } from '@metamask/snaps-sdk';\nimport { stripSnapPrefix } from '@metamask/snaps-utils';\n\nimport { getAccountWalletNameFromKeyringType } from './names';\n\nconst controllerName = 'AccountTreeController';\n\nexport enum AccountWalletCategory {\n Entropy = 'entropy',\n Keyring = 'keyring',\n Snap = 'snap',\n}\n\ntype AccountTreeRuleMatch = {\n category: AccountWalletCategory;\n id: AccountWalletId;\n name: string;\n};\n\ntype AccountTreeRuleFunction = (\n account: InternalAccount,\n) => AccountTreeRuleMatch | undefined;\n\ntype AccountReverseMapping = {\n walletId: AccountWalletId;\n groupId: AccountGroupId;\n};\n\nexport type AccountWalletId = `${AccountWalletCategory}:${string}`;\nexport type AccountGroupId = `${AccountWalletId}:${string}`;\n\n// Do not export this one, we just use it to have a common type interface between group and wallet metadata.\ntype Metadata = {\n name: string;\n};\n\nexport type AccountWalletMetadata = Metadata;\n\nexport type AccountGroupMetadata = Metadata;\n\nexport type AccountGroup = {\n id: AccountGroupId;\n // Blockchain Accounts:\n accounts: AccountId[];\n metadata: AccountGroupMetadata;\n};\n\nexport type AccountWallet = {\n id: AccountWalletId;\n // Account groups OR Multichain accounts (once available).\n groups: {\n [groupId: AccountGroupId]: AccountGroup;\n };\n metadata: AccountGroupMetadata; // Assuming Metadata is a defined type\n};\n\nexport type AccountTreeControllerState = {\n accountTree: {\n wallets: {\n // Wallets:\n [walletId: AccountWalletId]: AccountWallet;\n };\n };\n};\n\nexport type AccountTreeControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n AccountTreeControllerState\n>;\n\nexport type AllowedActions =\n | AccountsControllerListMultichainAccountsAction\n | KeyringControllerGetStateAction\n | SnapControllerGetSnap;\n\nexport type AccountTreeControllerActions = never;\n\nexport type AccountTreeControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n AccountTreeControllerState\n>;\n\nexport type AllowedEvents =\n | AccountsControllerAccountAddedEvent\n | AccountsControllerAccountRemovedEvent;\n\nexport type AccountTreeControllerEvents = never;\n\nexport type AccountTreeControllerMessenger = RestrictedMessenger<\n typeof controllerName,\n AccountTreeControllerActions | AllowedActions,\n AccountTreeControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n\nconst accountTreeControllerMetadata: StateMetadata<AccountTreeControllerState> =\n {\n accountTree: {\n persist: false, // We do re-recompute this state everytime.\n anonymous: false,\n },\n };\n\n/**\n * Gets default state of the `AccountTreeController`.\n *\n * @returns The default state of the `AccountTreeController`.\n */\nexport function getDefaultAccountTreeControllerState(): AccountTreeControllerState {\n return {\n accountTree: {\n wallets: {},\n },\n };\n}\n\n// TODO: For now we use this for the 2nd-level of the tree until we implements proper multichain accounts.\nexport const DEFAULT_ACCOUNT_GROUP_UNIQUE_ID: string = 'default'; // This might need to be re-evaluated based on new structure\nexport const DEFAULT_ACCOUNT_GROUP_NAME: string = 'Default';\n\n/**\n * Convert a unique ID to a wallet ID for a given category.\n *\n * @param category - A wallet category.\n * @param id - A unique ID.\n * @returns A wallet ID.\n */\nexport function toAccountWalletId(\n category: AccountWalletCategory,\n id: string,\n): AccountWalletId {\n return `${category}:${id}`;\n}\n\n/**\n * Convert a wallet ID and a unique ID, to a group ID.\n *\n * @param walletId - A wallet ID.\n * @param id - A unique ID.\n * @returns A group ID.\n */\nexport function toAccountGroupId(\n walletId: AccountWalletId,\n id: string,\n): AccountGroupId {\n return `${walletId}:${id}`;\n}\n\n/**\n * Convert a wallet ID to the default group ID.\n *\n * @param walletId - A wallet ID.\n * @returns The default group ID.\n */\nexport function toDefaultAccountGroupId(\n walletId: AccountWalletId,\n): AccountGroupId {\n return toAccountGroupId(walletId, DEFAULT_ACCOUNT_GROUP_UNIQUE_ID);\n}\n\nexport class AccountTreeController extends BaseController<\n typeof controllerName,\n AccountTreeControllerState,\n AccountTreeControllerMessenger\n> {\n readonly #reverse: Map<AccountId, AccountReverseMapping>;\n\n readonly #rules: AccountTreeRuleFunction[];\n\n /**\n * Constructor for AccountTreeController.\n *\n * @param options - The controller options.\n * @param options.messenger - The messenger object.\n * @param options.state - Initial state to set on this controller\n */\n constructor({\n messenger,\n state,\n }: {\n messenger: AccountTreeControllerMessenger;\n state?: Partial<AccountTreeControllerState>;\n }) {\n super({\n messenger,\n name: controllerName,\n metadata: accountTreeControllerMetadata,\n state: {\n ...getDefaultAccountTreeControllerState(),\n ...state,\n },\n });\n\n // Reverse map to allow fast node access from an account ID.\n this.#reverse = new Map();\n\n // Rules to apply to construct the wallets tree.\n this.#rules = [\n // 1. We group by entropy-source\n (account: InternalAccount) => this.#matchGroupByEntropySource(account),\n // 2. We group by Snap ID\n (account: InternalAccount) => this.#matchGroupBySnapId(account),\n // 3. We group by wallet type (this rule cannot fail and will group all non-matching accounts)\n (account: InternalAccount) => this.#matchGroupByKeyringType(account),\n ];\n\n this.messagingSystem.subscribe(\n 'AccountsController:accountAdded',\n (account) => {\n this.#handleAccountAdded(account);\n },\n );\n\n this.messagingSystem.subscribe(\n 'AccountsController:accountRemoved',\n (accountId) => {\n this.#handleAccountRemoved(accountId);\n },\n );\n }\n\n init() {\n const wallets = {};\n\n // For now, we always re-compute all wallets, we do not re-use the existing state.\n for (const account of this.#listAccounts()) {\n this.#insert(wallets, account);\n }\n\n this.update((state) => {\n state.accountTree.wallets = wallets;\n });\n }\n\n #handleAccountAdded(account: InternalAccount) {\n this.update((state) => {\n this.#insert(state.accountTree.wallets, account);\n });\n }\n\n #handleAccountRemoved(accountId: AccountId) {\n const found = this.#reverse.get(accountId);\n\n if (found) {\n const { walletId, groupId } = found;\n this.update((state) => {\n const { accounts } =\n state.accountTree.wallets[walletId].groups[groupId];\n\n const index = accounts.indexOf(accountId);\n if (index !== -1) {\n accounts.splice(index, 1);\n }\n });\n }\n }\n\n #hasKeyringType(account: InternalAccount, type: KeyringTypes): boolean {\n return account.metadata.keyring.type === (type as string);\n }\n\n #matchGroupByEntropySource(\n account: InternalAccount,\n ): AccountTreeRuleMatch | undefined {\n let entropySource: string | undefined;\n\n if (this.#hasKeyringType(account, KeyringTypes.hd)) {\n // TODO: Maybe use superstruct to validate the structure of HD account since they are not strongly-typed for now?\n if (!account.options.entropySource) {\n console.warn(\n \"! Found an HD account with no entropy source: account won't be associated to its wallet\",\n );\n return undefined;\n }\n\n entropySource = account.options.entropySource as string;\n }\n\n // TODO: For now, we're not checking if the Snap is a preinstalled one, and we probably should...\n if (\n this.#hasKeyringType(account, KeyringTypes.snap) &&\n account.metadata.snap?.enabled\n ) {\n // Not all Snaps have an entropy-source and options are not typed yet, so we have to check manually here.\n if (account.options.entropySource) {\n // We blindly trust the `entropySource` for now, but it could be wrong since it comes from a Snap.\n entropySource = account.options.entropySource as string;\n }\n }\n\n if (!entropySource) {\n return undefined;\n }\n\n // We check if we can get the name for that entropy source, if not this means this entropy does not match\n // any HD keyrings, thus, is invalid (this account will be grouped by another rule).\n const entropySourceName = this.#getEntropySourceName(entropySource);\n if (!entropySourceName) {\n console.warn(\n '! Tried to name a wallet using an unknown entropy, this should not be possible.',\n );\n return undefined;\n }\n\n return {\n category: AccountWalletCategory.Entropy,\n id: toAccountWalletId(AccountWalletCategory.Entropy, entropySource),\n name: entropySourceName,\n };\n }\n\n #matchGroupBySnapId(\n account: InternalAccount,\n ): AccountTreeRuleMatch | undefined {\n if (\n this.#hasKeyringType(account, KeyringTypes.snap) &&\n account.metadata.snap &&\n account.metadata.snap.enabled\n ) {\n const { id } = account.metadata.snap;\n\n return {\n category: AccountWalletCategory.Snap,\n id: toAccountWalletId(AccountWalletCategory.Snap, id),\n name: this.#getSnapName(id as SnapId),\n };\n }\n\n return undefined;\n }\n\n #matchGroupByKeyringType(\n account: InternalAccount,\n ): AccountTreeRuleMatch | undefined {\n const { type } = account.metadata.keyring;\n\n return {\n category: AccountWalletCategory.Keyring,\n id: toAccountWalletId(AccountWalletCategory.Keyring, type),\n name: getAccountWalletNameFromKeyringType(type as KeyringTypes),\n };\n }\n\n #getSnapName(snapId: SnapId): string {\n const snap = this.messagingSystem.call('SnapController:get', snapId);\n const snapName = snap\n ? // TODO: Handle localization here, but that's a \"client thing\", so we don't have a `core` controller\n // to refer too.\n snap.manifest.proposedName\n : stripSnapPrefix(snapId);\n\n return `Snap: ${snapName}`;\n }\n\n #getEntropySourceName(entropySource: string): string | undefined {\n const { keyrings } = this.messagingSystem.call(\n 'KeyringController:getState',\n );\n\n const index = keyrings\n .filter((keyring) => keyring.type === (KeyringTypes.hd as string))\n .findIndex((keyring) => keyring.metadata.id === entropySource);\n\n if (index === -1) {\n return undefined;\n }\n\n return `Wallet ${index + 1}`; // Use human indexing.\n }\n\n #insert(\n wallets: { [walletId: AccountWalletId]: AccountWallet },\n account: InternalAccount,\n ) {\n for (const rule of this.#rules) {\n const match = rule(account);\n\n if (!match) {\n // No match for that rule, we go to the next one.\n continue;\n }\n\n const walletId = match.id;\n const walletName = match.name;\n const groupId = toDefaultAccountGroupId(walletId); // Use a single-group for now until multichain accounts is supported.\n const groupName = DEFAULT_ACCOUNT_GROUP_NAME;\n\n if (!wallets[walletId]) {\n wallets[walletId] = {\n id: walletId,\n groups: {\n [groupId]: {\n id: groupId,\n accounts: [],\n metadata: { name: groupName },\n },\n },\n metadata: {\n name: walletName,\n },\n };\n }\n wallets[walletId].groups[groupId].accounts.push(account.id);\n\n // Update the reverse mapping for this account.\n this.#reverse.set(account.id, {\n walletId,\n groupId,\n });\n\n return;\n }\n }\n\n #listAccounts(): InternalAccount[] {\n return this.messagingSystem.call(\n 'AccountsController:listMultichainAccounts',\n );\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"AccountTreeController.cjs","sourceRoot":"","sources":["../src/AccountTreeController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n AccountId,\n AccountsControllerAccountAddedEvent,\n AccountsControllerAccountRemovedEvent,\n AccountsControllerListMultichainAccountsAction,\n} from '@metamask/accounts-controller';\nimport type { StateMetadata } from '@metamask/base-controller';\nimport {\n type ControllerGetStateAction,\n type ControllerStateChangeEvent,\n type RestrictedMessenger,\n BaseController,\n} from '@metamask/base-controller';\nimport type { KeyringControllerGetStateAction } from '@metamask/keyring-controller';\nimport { KeyringTypes } from '@metamask/keyring-controller';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\nimport type { GetSnap as SnapControllerGetSnap } from '@metamask/snaps-controllers';\nimport type { SnapId } from '@metamask/snaps-sdk';\nimport { stripSnapPrefix } from '@metamask/snaps-utils';\n\nimport { getAccountWalletNameFromKeyringType } from './names';\n\nconst controllerName = 'AccountTreeController';\n\nexport enum AccountWalletCategory {\n Entropy = 'entropy',\n Keyring = 'keyring',\n Snap = 'snap',\n}\n\ntype AccountTreeRuleMatch = {\n category: AccountWalletCategory;\n id: AccountWalletId;\n name: string;\n};\n\ntype AccountTreeRuleFunction = (\n account: InternalAccount,\n) => AccountTreeRuleMatch | undefined;\n\ntype AccountReverseMapping = {\n walletId: AccountWalletId;\n groupId: AccountGroupId;\n};\n\nexport type AccountWalletId = `${AccountWalletCategory}:${string}`;\nexport type AccountGroupId = `${AccountWalletId}:${string}`;\n\n// Do not export this one, we just use it to have a common type interface between group and wallet metadata.\ntype Metadata = {\n name: string;\n};\n\nexport type AccountWalletMetadata = Metadata;\n\nexport type AccountGroupMetadata = Metadata;\n\nexport type AccountGroup = {\n id: AccountGroupId;\n // Blockchain Accounts:\n accounts: AccountId[];\n metadata: AccountGroupMetadata;\n};\n\nexport type AccountWallet = {\n id: AccountWalletId;\n // Account groups OR Multichain accounts (once available).\n groups: {\n [groupId: AccountGroupId]: AccountGroup;\n };\n metadata: AccountWalletMetadata;\n};\n\nexport type AccountTreeControllerState = {\n accountTree: {\n wallets: {\n // Wallets:\n [walletId: AccountWalletId]: AccountWallet;\n };\n };\n};\n\nexport type AccountTreeControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n AccountTreeControllerState\n>;\n\nexport type AllowedActions =\n | AccountsControllerListMultichainAccountsAction\n | KeyringControllerGetStateAction\n | SnapControllerGetSnap;\n\nexport type AccountTreeControllerActions = never;\n\nexport type AccountTreeControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n AccountTreeControllerState\n>;\n\nexport type AllowedEvents =\n | AccountsControllerAccountAddedEvent\n | AccountsControllerAccountRemovedEvent;\n\nexport type AccountTreeControllerEvents = never;\n\nexport type AccountTreeControllerMessenger = RestrictedMessenger<\n typeof controllerName,\n AccountTreeControllerActions | AllowedActions,\n AccountTreeControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n\nconst accountTreeControllerMetadata: StateMetadata<AccountTreeControllerState> =\n {\n accountTree: {\n persist: false, // We do re-recompute this state everytime.\n anonymous: false,\n },\n };\n\n/**\n * Gets default state of the `AccountTreeController`.\n *\n * @returns The default state of the `AccountTreeController`.\n */\nexport function getDefaultAccountTreeControllerState(): AccountTreeControllerState {\n return {\n accountTree: {\n wallets: {},\n },\n };\n}\n\n// TODO: For now we use this for the 2nd-level of the tree until we implements proper multichain accounts.\nexport const DEFAULT_ACCOUNT_GROUP_UNIQUE_ID: string = 'default'; // This might need to be re-evaluated based on new structure\nexport const DEFAULT_ACCOUNT_GROUP_NAME: string = 'Default';\n\n/**\n * Convert a unique ID to a wallet ID for a given category.\n *\n * @param category - A wallet category.\n * @param id - A unique ID.\n * @returns A wallet ID.\n */\nexport function toAccountWalletId(\n category: AccountWalletCategory,\n id: string,\n): AccountWalletId {\n return `${category}:${id}`;\n}\n\n/**\n * Convert a wallet ID and a unique ID, to a group ID.\n *\n * @param walletId - A wallet ID.\n * @param id - A unique ID.\n * @returns A group ID.\n */\nexport function toAccountGroupId(\n walletId: AccountWalletId,\n id: string,\n): AccountGroupId {\n return `${walletId}:${id}`;\n}\n\n/**\n * Convert a wallet ID to the default group ID.\n *\n * @param walletId - A wallet ID.\n * @returns The default group ID.\n */\nexport function toDefaultAccountGroupId(\n walletId: AccountWalletId,\n): AccountGroupId {\n return toAccountGroupId(walletId, DEFAULT_ACCOUNT_GROUP_UNIQUE_ID);\n}\n\nexport class AccountTreeController extends BaseController<\n typeof controllerName,\n AccountTreeControllerState,\n AccountTreeControllerMessenger\n> {\n readonly #reverse: Map<AccountId, AccountReverseMapping>;\n\n readonly #rules: AccountTreeRuleFunction[];\n\n /**\n * Constructor for AccountTreeController.\n *\n * @param options - The controller options.\n * @param options.messenger - The messenger object.\n * @param options.state - Initial state to set on this controller\n */\n constructor({\n messenger,\n state,\n }: {\n messenger: AccountTreeControllerMessenger;\n state?: Partial<AccountTreeControllerState>;\n }) {\n super({\n messenger,\n name: controllerName,\n metadata: accountTreeControllerMetadata,\n state: {\n ...getDefaultAccountTreeControllerState(),\n ...state,\n },\n });\n\n // Reverse map to allow fast node access from an account ID.\n this.#reverse = new Map();\n\n // Rules to apply to construct the wallets tree.\n this.#rules = [\n // 1. We group by entropy-source\n (account: InternalAccount) => this.#matchGroupByEntropySource(account),\n // 2. We group by Snap ID\n (account: InternalAccount) => this.#matchGroupBySnapId(account),\n // 3. We group by wallet type (this rule cannot fail and will group all non-matching accounts)\n (account: InternalAccount) => this.#matchGroupByKeyringType(account),\n ];\n\n this.messagingSystem.subscribe(\n 'AccountsController:accountAdded',\n (account) => {\n this.#handleAccountAdded(account);\n },\n );\n\n this.messagingSystem.subscribe(\n 'AccountsController:accountRemoved',\n (accountId) => {\n this.#handleAccountRemoved(accountId);\n },\n );\n }\n\n init() {\n const wallets = {};\n\n // For now, we always re-compute all wallets, we do not re-use the existing state.\n for (const account of this.#listAccounts()) {\n this.#insert(wallets, account);\n }\n\n this.update((state) => {\n state.accountTree.wallets = wallets;\n });\n }\n\n #handleAccountAdded(account: InternalAccount) {\n this.update((state) => {\n this.#insert(state.accountTree.wallets, account);\n });\n }\n\n #handleAccountRemoved(accountId: AccountId) {\n const found = this.#reverse.get(accountId);\n\n if (found) {\n const { walletId, groupId } = found;\n this.update((state) => {\n const { accounts } =\n state.accountTree.wallets[walletId].groups[groupId];\n\n const index = accounts.indexOf(accountId);\n if (index !== -1) {\n accounts.splice(index, 1);\n }\n });\n }\n }\n\n #hasKeyringType(account: InternalAccount, type: KeyringTypes): boolean {\n return account.metadata.keyring.type === (type as string);\n }\n\n #matchGroupByEntropySource(\n account: InternalAccount,\n ): AccountTreeRuleMatch | undefined {\n let entropySource: string | undefined;\n\n if (this.#hasKeyringType(account, KeyringTypes.hd)) {\n // TODO: Maybe use superstruct to validate the structure of HD account since they are not strongly-typed for now?\n if (!account.options.entropySource) {\n console.warn(\n \"! Found an HD account with no entropy source: account won't be associated to its wallet\",\n );\n return undefined;\n }\n\n entropySource = account.options.entropySource as string;\n }\n\n // TODO: For now, we're not checking if the Snap is a preinstalled one, and we probably should...\n if (\n this.#hasKeyringType(account, KeyringTypes.snap) &&\n account.metadata.snap?.enabled\n ) {\n // Not all Snaps have an entropy-source and options are not typed yet, so we have to check manually here.\n if (account.options.entropySource) {\n // We blindly trust the `entropySource` for now, but it could be wrong since it comes from a Snap.\n entropySource = account.options.entropySource as string;\n }\n }\n\n if (!entropySource) {\n return undefined;\n }\n\n // We check if we can get the name for that entropy source, if not this means this entropy does not match\n // any HD keyrings, thus, is invalid (this account will be grouped by another rule).\n const entropySourceName = this.#getEntropySourceName(entropySource);\n if (!entropySourceName) {\n console.warn(\n '! Tried to name a wallet using an unknown entropy, this should not be possible.',\n );\n return undefined;\n }\n\n return {\n category: AccountWalletCategory.Entropy,\n id: toAccountWalletId(AccountWalletCategory.Entropy, entropySource),\n name: entropySourceName,\n };\n }\n\n #matchGroupBySnapId(\n account: InternalAccount,\n ): AccountTreeRuleMatch | undefined {\n if (\n this.#hasKeyringType(account, KeyringTypes.snap) &&\n account.metadata.snap &&\n account.metadata.snap.enabled\n ) {\n const { id } = account.metadata.snap;\n\n return {\n category: AccountWalletCategory.Snap,\n id: toAccountWalletId(AccountWalletCategory.Snap, id),\n name: this.#getSnapName(id as SnapId),\n };\n }\n\n return undefined;\n }\n\n #matchGroupByKeyringType(\n account: InternalAccount,\n ): AccountTreeRuleMatch | undefined {\n const { type } = account.metadata.keyring;\n\n return {\n category: AccountWalletCategory.Keyring,\n id: toAccountWalletId(AccountWalletCategory.Keyring, type),\n name: getAccountWalletNameFromKeyringType(type as KeyringTypes),\n };\n }\n\n #getSnapName(snapId: SnapId): string {\n const snap = this.messagingSystem.call('SnapController:get', snapId);\n const snapName = snap\n ? // TODO: Handle localization here, but that's a \"client thing\", so we don't have a `core` controller\n // to refer too.\n snap.manifest.proposedName\n : stripSnapPrefix(snapId);\n\n return `Snap: ${snapName}`;\n }\n\n #getEntropySourceName(entropySource: string): string | undefined {\n const { keyrings } = this.messagingSystem.call(\n 'KeyringController:getState',\n );\n\n const index = keyrings\n .filter((keyring) => keyring.type === (KeyringTypes.hd as string))\n .findIndex((keyring) => keyring.metadata.id === entropySource);\n\n if (index === -1) {\n return undefined;\n }\n\n return `Wallet ${index + 1}`; // Use human indexing.\n }\n\n #insert(\n wallets: { [walletId: AccountWalletId]: AccountWallet },\n account: InternalAccount,\n ) {\n for (const rule of this.#rules) {\n const match = rule(account);\n\n if (!match) {\n // No match for that rule, we go to the next one.\n continue;\n }\n\n const walletId = match.id;\n const walletName = match.name;\n const groupId = toDefaultAccountGroupId(walletId); // Use a single-group for now until multichain accounts is supported.\n const groupName = DEFAULT_ACCOUNT_GROUP_NAME;\n\n if (!wallets[walletId]) {\n wallets[walletId] = {\n id: walletId,\n groups: {\n [groupId]: {\n id: groupId,\n accounts: [],\n metadata: { name: groupName },\n },\n },\n metadata: {\n name: walletName,\n },\n };\n }\n wallets[walletId].groups[groupId].accounts.push(account.id);\n\n // Update the reverse mapping for this account.\n this.#reverse.set(account.id, {\n walletId,\n groupId,\n });\n\n return;\n }\n }\n\n #listAccounts(): InternalAccount[] {\n return this.messagingSystem.call(\n 'AccountsController:listMultichainAccounts',\n );\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AccountTreeController.d.cts","sourceRoot":"","sources":["../src/AccountTreeController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,EACT,mCAAmC,EACnC,qCAAqC,EACrC,8CAA8C,EAC/C,sCAAsC;AAEvC,OAAO,EACL,KAAK,wBAAwB,EAC7B,KAAK,0BAA0B,EAC/B,KAAK,mBAAmB,EACxB,cAAc,EACf,kCAAkC;AACnC,OAAO,KAAK,EAAE,+BAA+B,EAAE,qCAAqC;AAGpF,OAAO,KAAK,EAAE,OAAO,IAAI,qBAAqB,EAAE,oCAAoC;AAMpF,QAAA,MAAM,cAAc,0BAA0B,CAAC;AAE/C,oBAAY,qBAAqB;IAC/B,OAAO,YAAY;IACnB,OAAO,YAAY;IACnB,IAAI,SAAS;CACd;AAiBD,MAAM,MAAM,eAAe,GAAG,GAAG,qBAAqB,IAAI,MAAM,EAAE,CAAC;AACnE,MAAM,MAAM,cAAc,GAAG,GAAG,eAAe,IAAI,MAAM,EAAE,CAAC;AAG5D,KAAK,QAAQ,GAAG;IACd,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG,QAAQ,CAAC;AAE7C,MAAM,MAAM,oBAAoB,GAAG,QAAQ,CAAC;AAE5C,MAAM,MAAM,YAAY,GAAG;IACzB,EAAE,EAAE,cAAc,CAAC;IAEnB,QAAQ,EAAE,SAAS,EAAE,CAAC;IACtB,QAAQ,EAAE,oBAAoB,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,EAAE,EAAE,eAAe,CAAC;IAEpB,MAAM,EAAE;QACN,CAAC,OAAO,EAAE,cAAc,GAAG,YAAY,CAAC;KACzC,CAAC;IACF,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"AccountTreeController.d.cts","sourceRoot":"","sources":["../src/AccountTreeController.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AccountTreeController.d.mts","sourceRoot":"","sources":["../src/AccountTreeController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,EACT,mCAAmC,EACnC,qCAAqC,EACrC,8CAA8C,EAC/C,sCAAsC;AAEvC,OAAO,EACL,KAAK,wBAAwB,EAC7B,KAAK,0BAA0B,EAC/B,KAAK,mBAAmB,EACxB,cAAc,EACf,kCAAkC;AACnC,OAAO,KAAK,EAAE,+BAA+B,EAAE,qCAAqC;AAGpF,OAAO,KAAK,EAAE,OAAO,IAAI,qBAAqB,EAAE,oCAAoC;AAMpF,QAAA,MAAM,cAAc,0BAA0B,CAAC;AAE/C,oBAAY,qBAAqB;IAC/B,OAAO,YAAY;IACnB,OAAO,YAAY;IACnB,IAAI,SAAS;CACd;AAiBD,MAAM,MAAM,eAAe,GAAG,GAAG,qBAAqB,IAAI,MAAM,EAAE,CAAC;AACnE,MAAM,MAAM,cAAc,GAAG,GAAG,eAAe,IAAI,MAAM,EAAE,CAAC;AAG5D,KAAK,QAAQ,GAAG;IACd,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG,QAAQ,CAAC;AAE7C,MAAM,MAAM,oBAAoB,GAAG,QAAQ,CAAC;AAE5C,MAAM,MAAM,YAAY,GAAG;IACzB,EAAE,EAAE,cAAc,CAAC;IAEnB,QAAQ,EAAE,SAAS,EAAE,CAAC;IACtB,QAAQ,EAAE,oBAAoB,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,EAAE,EAAE,eAAe,CAAC;IAEpB,MAAM,EAAE;QACN,CAAC,OAAO,EAAE,cAAc,GAAG,YAAY,CAAC;KACzC,CAAC;IACF,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"AccountTreeController.d.mts","sourceRoot":"","sources":["../src/AccountTreeController.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AccountTreeController.mjs","sourceRoot":"","sources":["../src/AccountTreeController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n AccountId,\n AccountsControllerAccountAddedEvent,\n AccountsControllerAccountRemovedEvent,\n AccountsControllerListMultichainAccountsAction,\n} from '@metamask/accounts-controller';\nimport type { StateMetadata } from '@metamask/base-controller';\nimport {\n type ControllerGetStateAction,\n type ControllerStateChangeEvent,\n type RestrictedMessenger,\n BaseController,\n} from '@metamask/base-controller';\nimport type { KeyringControllerGetStateAction } from '@metamask/keyring-controller';\nimport { KeyringTypes } from '@metamask/keyring-controller';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\nimport type { GetSnap as SnapControllerGetSnap } from '@metamask/snaps-controllers';\nimport type { SnapId } from '@metamask/snaps-sdk';\nimport { stripSnapPrefix } from '@metamask/snaps-utils';\n\nimport { getAccountWalletNameFromKeyringType } from './names';\n\nconst controllerName = 'AccountTreeController';\n\nexport enum AccountWalletCategory {\n Entropy = 'entropy',\n Keyring = 'keyring',\n Snap = 'snap',\n}\n\ntype AccountTreeRuleMatch = {\n category: AccountWalletCategory;\n id: AccountWalletId;\n name: string;\n};\n\ntype AccountTreeRuleFunction = (\n account: InternalAccount,\n) => AccountTreeRuleMatch | undefined;\n\ntype AccountReverseMapping = {\n walletId: AccountWalletId;\n groupId: AccountGroupId;\n};\n\nexport type AccountWalletId = `${AccountWalletCategory}:${string}`;\nexport type AccountGroupId = `${AccountWalletId}:${string}`;\n\n// Do not export this one, we just use it to have a common type interface between group and wallet metadata.\ntype Metadata = {\n name: string;\n};\n\nexport type AccountWalletMetadata = Metadata;\n\nexport type AccountGroupMetadata = Metadata;\n\nexport type AccountGroup = {\n id: AccountGroupId;\n // Blockchain Accounts:\n accounts: AccountId[];\n metadata: AccountGroupMetadata;\n};\n\nexport type AccountWallet = {\n id: AccountWalletId;\n // Account groups OR Multichain accounts (once available).\n groups: {\n [groupId: AccountGroupId]: AccountGroup;\n };\n metadata: AccountGroupMetadata; // Assuming Metadata is a defined type\n};\n\nexport type AccountTreeControllerState = {\n accountTree: {\n wallets: {\n // Wallets:\n [walletId: AccountWalletId]: AccountWallet;\n };\n };\n};\n\nexport type AccountTreeControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n AccountTreeControllerState\n>;\n\nexport type AllowedActions =\n | AccountsControllerListMultichainAccountsAction\n | KeyringControllerGetStateAction\n | SnapControllerGetSnap;\n\nexport type AccountTreeControllerActions = never;\n\nexport type AccountTreeControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n AccountTreeControllerState\n>;\n\nexport type AllowedEvents =\n | AccountsControllerAccountAddedEvent\n | AccountsControllerAccountRemovedEvent;\n\nexport type AccountTreeControllerEvents = never;\n\nexport type AccountTreeControllerMessenger = RestrictedMessenger<\n typeof controllerName,\n AccountTreeControllerActions | AllowedActions,\n AccountTreeControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n\nconst accountTreeControllerMetadata: StateMetadata<AccountTreeControllerState> =\n {\n accountTree: {\n persist: false, // We do re-recompute this state everytime.\n anonymous: false,\n },\n };\n\n/**\n * Gets default state of the `AccountTreeController`.\n *\n * @returns The default state of the `AccountTreeController`.\n */\nexport function getDefaultAccountTreeControllerState(): AccountTreeControllerState {\n return {\n accountTree: {\n wallets: {},\n },\n };\n}\n\n// TODO: For now we use this for the 2nd-level of the tree until we implements proper multichain accounts.\nexport const DEFAULT_ACCOUNT_GROUP_UNIQUE_ID: string = 'default'; // This might need to be re-evaluated based on new structure\nexport const DEFAULT_ACCOUNT_GROUP_NAME: string = 'Default';\n\n/**\n * Convert a unique ID to a wallet ID for a given category.\n *\n * @param category - A wallet category.\n * @param id - A unique ID.\n * @returns A wallet ID.\n */\nexport function toAccountWalletId(\n category: AccountWalletCategory,\n id: string,\n): AccountWalletId {\n return `${category}:${id}`;\n}\n\n/**\n * Convert a wallet ID and a unique ID, to a group ID.\n *\n * @param walletId - A wallet ID.\n * @param id - A unique ID.\n * @returns A group ID.\n */\nexport function toAccountGroupId(\n walletId: AccountWalletId,\n id: string,\n): AccountGroupId {\n return `${walletId}:${id}`;\n}\n\n/**\n * Convert a wallet ID to the default group ID.\n *\n * @param walletId - A wallet ID.\n * @returns The default group ID.\n */\nexport function toDefaultAccountGroupId(\n walletId: AccountWalletId,\n): AccountGroupId {\n return toAccountGroupId(walletId, DEFAULT_ACCOUNT_GROUP_UNIQUE_ID);\n}\n\nexport class AccountTreeController extends BaseController<\n typeof controllerName,\n AccountTreeControllerState,\n AccountTreeControllerMessenger\n> {\n readonly #reverse: Map<AccountId, AccountReverseMapping>;\n\n readonly #rules: AccountTreeRuleFunction[];\n\n /**\n * Constructor for AccountTreeController.\n *\n * @param options - The controller options.\n * @param options.messenger - The messenger object.\n * @param options.state - Initial state to set on this controller\n */\n constructor({\n messenger,\n state,\n }: {\n messenger: AccountTreeControllerMessenger;\n state?: Partial<AccountTreeControllerState>;\n }) {\n super({\n messenger,\n name: controllerName,\n metadata: accountTreeControllerMetadata,\n state: {\n ...getDefaultAccountTreeControllerState(),\n ...state,\n },\n });\n\n // Reverse map to allow fast node access from an account ID.\n this.#reverse = new Map();\n\n // Rules to apply to construct the wallets tree.\n this.#rules = [\n // 1. We group by entropy-source\n (account: InternalAccount) => this.#matchGroupByEntropySource(account),\n // 2. We group by Snap ID\n (account: InternalAccount) => this.#matchGroupBySnapId(account),\n // 3. We group by wallet type (this rule cannot fail and will group all non-matching accounts)\n (account: InternalAccount) => this.#matchGroupByKeyringType(account),\n ];\n\n this.messagingSystem.subscribe(\n 'AccountsController:accountAdded',\n (account) => {\n this.#handleAccountAdded(account);\n },\n );\n\n this.messagingSystem.subscribe(\n 'AccountsController:accountRemoved',\n (accountId) => {\n this.#handleAccountRemoved(accountId);\n },\n );\n }\n\n init() {\n const wallets = {};\n\n // For now, we always re-compute all wallets, we do not re-use the existing state.\n for (const account of this.#listAccounts()) {\n this.#insert(wallets, account);\n }\n\n this.update((state) => {\n state.accountTree.wallets = wallets;\n });\n }\n\n #handleAccountAdded(account: InternalAccount) {\n this.update((state) => {\n this.#insert(state.accountTree.wallets, account);\n });\n }\n\n #handleAccountRemoved(accountId: AccountId) {\n const found = this.#reverse.get(accountId);\n\n if (found) {\n const { walletId, groupId } = found;\n this.update((state) => {\n const { accounts } =\n state.accountTree.wallets[walletId].groups[groupId];\n\n const index = accounts.indexOf(accountId);\n if (index !== -1) {\n accounts.splice(index, 1);\n }\n });\n }\n }\n\n #hasKeyringType(account: InternalAccount, type: KeyringTypes): boolean {\n return account.metadata.keyring.type === (type as string);\n }\n\n #matchGroupByEntropySource(\n account: InternalAccount,\n ): AccountTreeRuleMatch | undefined {\n let entropySource: string | undefined;\n\n if (this.#hasKeyringType(account, KeyringTypes.hd)) {\n // TODO: Maybe use superstruct to validate the structure of HD account since they are not strongly-typed for now?\n if (!account.options.entropySource) {\n console.warn(\n \"! Found an HD account with no entropy source: account won't be associated to its wallet\",\n );\n return undefined;\n }\n\n entropySource = account.options.entropySource as string;\n }\n\n // TODO: For now, we're not checking if the Snap is a preinstalled one, and we probably should...\n if (\n this.#hasKeyringType(account, KeyringTypes.snap) &&\n account.metadata.snap?.enabled\n ) {\n // Not all Snaps have an entropy-source and options are not typed yet, so we have to check manually here.\n if (account.options.entropySource) {\n // We blindly trust the `entropySource` for now, but it could be wrong since it comes from a Snap.\n entropySource = account.options.entropySource as string;\n }\n }\n\n if (!entropySource) {\n return undefined;\n }\n\n // We check if we can get the name for that entropy source, if not this means this entropy does not match\n // any HD keyrings, thus, is invalid (this account will be grouped by another rule).\n const entropySourceName = this.#getEntropySourceName(entropySource);\n if (!entropySourceName) {\n console.warn(\n '! Tried to name a wallet using an unknown entropy, this should not be possible.',\n );\n return undefined;\n }\n\n return {\n category: AccountWalletCategory.Entropy,\n id: toAccountWalletId(AccountWalletCategory.Entropy, entropySource),\n name: entropySourceName,\n };\n }\n\n #matchGroupBySnapId(\n account: InternalAccount,\n ): AccountTreeRuleMatch | undefined {\n if (\n this.#hasKeyringType(account, KeyringTypes.snap) &&\n account.metadata.snap &&\n account.metadata.snap.enabled\n ) {\n const { id } = account.metadata.snap;\n\n return {\n category: AccountWalletCategory.Snap,\n id: toAccountWalletId(AccountWalletCategory.Snap, id),\n name: this.#getSnapName(id as SnapId),\n };\n }\n\n return undefined;\n }\n\n #matchGroupByKeyringType(\n account: InternalAccount,\n ): AccountTreeRuleMatch | undefined {\n const { type } = account.metadata.keyring;\n\n return {\n category: AccountWalletCategory.Keyring,\n id: toAccountWalletId(AccountWalletCategory.Keyring, type),\n name: getAccountWalletNameFromKeyringType(type as KeyringTypes),\n };\n }\n\n #getSnapName(snapId: SnapId): string {\n const snap = this.messagingSystem.call('SnapController:get', snapId);\n const snapName = snap\n ? // TODO: Handle localization here, but that's a \"client thing\", so we don't have a `core` controller\n // to refer too.\n snap.manifest.proposedName\n : stripSnapPrefix(snapId);\n\n return `Snap: ${snapName}`;\n }\n\n #getEntropySourceName(entropySource: string): string | undefined {\n const { keyrings } = this.messagingSystem.call(\n 'KeyringController:getState',\n );\n\n const index = keyrings\n .filter((keyring) => keyring.type === (KeyringTypes.hd as string))\n .findIndex((keyring) => keyring.metadata.id === entropySource);\n\n if (index === -1) {\n return undefined;\n }\n\n return `Wallet ${index + 1}`; // Use human indexing.\n }\n\n #insert(\n wallets: { [walletId: AccountWalletId]: AccountWallet },\n account: InternalAccount,\n ) {\n for (const rule of this.#rules) {\n const match = rule(account);\n\n if (!match) {\n // No match for that rule, we go to the next one.\n continue;\n }\n\n const walletId = match.id;\n const walletName = match.name;\n const groupId = toDefaultAccountGroupId(walletId); // Use a single-group for now until multichain accounts is supported.\n const groupName = DEFAULT_ACCOUNT_GROUP_NAME;\n\n if (!wallets[walletId]) {\n wallets[walletId] = {\n id: walletId,\n groups: {\n [groupId]: {\n id: groupId,\n accounts: [],\n metadata: { name: groupName },\n },\n },\n metadata: {\n name: walletName,\n },\n };\n }\n wallets[walletId].groups[groupId].accounts.push(account.id);\n\n // Update the reverse mapping for this account.\n this.#reverse.set(account.id, {\n walletId,\n groupId,\n });\n\n return;\n }\n }\n\n #listAccounts(): InternalAccount[] {\n return this.messagingSystem.call(\n 'AccountsController:listMultichainAccounts',\n );\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"AccountTreeController.mjs","sourceRoot":"","sources":["../src/AccountTreeController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n AccountId,\n AccountsControllerAccountAddedEvent,\n AccountsControllerAccountRemovedEvent,\n AccountsControllerListMultichainAccountsAction,\n} from '@metamask/accounts-controller';\nimport type { StateMetadata } from '@metamask/base-controller';\nimport {\n type ControllerGetStateAction,\n type ControllerStateChangeEvent,\n type RestrictedMessenger,\n BaseController,\n} from '@metamask/base-controller';\nimport type { KeyringControllerGetStateAction } from '@metamask/keyring-controller';\nimport { KeyringTypes } from '@metamask/keyring-controller';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\nimport type { GetSnap as SnapControllerGetSnap } from '@metamask/snaps-controllers';\nimport type { SnapId } from '@metamask/snaps-sdk';\nimport { stripSnapPrefix } from '@metamask/snaps-utils';\n\nimport { getAccountWalletNameFromKeyringType } from './names';\n\nconst controllerName = 'AccountTreeController';\n\nexport enum AccountWalletCategory {\n Entropy = 'entropy',\n Keyring = 'keyring',\n Snap = 'snap',\n}\n\ntype AccountTreeRuleMatch = {\n category: AccountWalletCategory;\n id: AccountWalletId;\n name: string;\n};\n\ntype AccountTreeRuleFunction = (\n account: InternalAccount,\n) => AccountTreeRuleMatch | undefined;\n\ntype AccountReverseMapping = {\n walletId: AccountWalletId;\n groupId: AccountGroupId;\n};\n\nexport type AccountWalletId = `${AccountWalletCategory}:${string}`;\nexport type AccountGroupId = `${AccountWalletId}:${string}`;\n\n// Do not export this one, we just use it to have a common type interface between group and wallet metadata.\ntype Metadata = {\n name: string;\n};\n\nexport type AccountWalletMetadata = Metadata;\n\nexport type AccountGroupMetadata = Metadata;\n\nexport type AccountGroup = {\n id: AccountGroupId;\n // Blockchain Accounts:\n accounts: AccountId[];\n metadata: AccountGroupMetadata;\n};\n\nexport type AccountWallet = {\n id: AccountWalletId;\n // Account groups OR Multichain accounts (once available).\n groups: {\n [groupId: AccountGroupId]: AccountGroup;\n };\n metadata: AccountWalletMetadata;\n};\n\nexport type AccountTreeControllerState = {\n accountTree: {\n wallets: {\n // Wallets:\n [walletId: AccountWalletId]: AccountWallet;\n };\n };\n};\n\nexport type AccountTreeControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n AccountTreeControllerState\n>;\n\nexport type AllowedActions =\n | AccountsControllerListMultichainAccountsAction\n | KeyringControllerGetStateAction\n | SnapControllerGetSnap;\n\nexport type AccountTreeControllerActions = never;\n\nexport type AccountTreeControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n AccountTreeControllerState\n>;\n\nexport type AllowedEvents =\n | AccountsControllerAccountAddedEvent\n | AccountsControllerAccountRemovedEvent;\n\nexport type AccountTreeControllerEvents = never;\n\nexport type AccountTreeControllerMessenger = RestrictedMessenger<\n typeof controllerName,\n AccountTreeControllerActions | AllowedActions,\n AccountTreeControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n\nconst accountTreeControllerMetadata: StateMetadata<AccountTreeControllerState> =\n {\n accountTree: {\n persist: false, // We do re-recompute this state everytime.\n anonymous: false,\n },\n };\n\n/**\n * Gets default state of the `AccountTreeController`.\n *\n * @returns The default state of the `AccountTreeController`.\n */\nexport function getDefaultAccountTreeControllerState(): AccountTreeControllerState {\n return {\n accountTree: {\n wallets: {},\n },\n };\n}\n\n// TODO: For now we use this for the 2nd-level of the tree until we implements proper multichain accounts.\nexport const DEFAULT_ACCOUNT_GROUP_UNIQUE_ID: string = 'default'; // This might need to be re-evaluated based on new structure\nexport const DEFAULT_ACCOUNT_GROUP_NAME: string = 'Default';\n\n/**\n * Convert a unique ID to a wallet ID for a given category.\n *\n * @param category - A wallet category.\n * @param id - A unique ID.\n * @returns A wallet ID.\n */\nexport function toAccountWalletId(\n category: AccountWalletCategory,\n id: string,\n): AccountWalletId {\n return `${category}:${id}`;\n}\n\n/**\n * Convert a wallet ID and a unique ID, to a group ID.\n *\n * @param walletId - A wallet ID.\n * @param id - A unique ID.\n * @returns A group ID.\n */\nexport function toAccountGroupId(\n walletId: AccountWalletId,\n id: string,\n): AccountGroupId {\n return `${walletId}:${id}`;\n}\n\n/**\n * Convert a wallet ID to the default group ID.\n *\n * @param walletId - A wallet ID.\n * @returns The default group ID.\n */\nexport function toDefaultAccountGroupId(\n walletId: AccountWalletId,\n): AccountGroupId {\n return toAccountGroupId(walletId, DEFAULT_ACCOUNT_GROUP_UNIQUE_ID);\n}\n\nexport class AccountTreeController extends BaseController<\n typeof controllerName,\n AccountTreeControllerState,\n AccountTreeControllerMessenger\n> {\n readonly #reverse: Map<AccountId, AccountReverseMapping>;\n\n readonly #rules: AccountTreeRuleFunction[];\n\n /**\n * Constructor for AccountTreeController.\n *\n * @param options - The controller options.\n * @param options.messenger - The messenger object.\n * @param options.state - Initial state to set on this controller\n */\n constructor({\n messenger,\n state,\n }: {\n messenger: AccountTreeControllerMessenger;\n state?: Partial<AccountTreeControllerState>;\n }) {\n super({\n messenger,\n name: controllerName,\n metadata: accountTreeControllerMetadata,\n state: {\n ...getDefaultAccountTreeControllerState(),\n ...state,\n },\n });\n\n // Reverse map to allow fast node access from an account ID.\n this.#reverse = new Map();\n\n // Rules to apply to construct the wallets tree.\n this.#rules = [\n // 1. We group by entropy-source\n (account: InternalAccount) => this.#matchGroupByEntropySource(account),\n // 2. We group by Snap ID\n (account: InternalAccount) => this.#matchGroupBySnapId(account),\n // 3. We group by wallet type (this rule cannot fail and will group all non-matching accounts)\n (account: InternalAccount) => this.#matchGroupByKeyringType(account),\n ];\n\n this.messagingSystem.subscribe(\n 'AccountsController:accountAdded',\n (account) => {\n this.#handleAccountAdded(account);\n },\n );\n\n this.messagingSystem.subscribe(\n 'AccountsController:accountRemoved',\n (accountId) => {\n this.#handleAccountRemoved(accountId);\n },\n );\n }\n\n init() {\n const wallets = {};\n\n // For now, we always re-compute all wallets, we do not re-use the existing state.\n for (const account of this.#listAccounts()) {\n this.#insert(wallets, account);\n }\n\n this.update((state) => {\n state.accountTree.wallets = wallets;\n });\n }\n\n #handleAccountAdded(account: InternalAccount) {\n this.update((state) => {\n this.#insert(state.accountTree.wallets, account);\n });\n }\n\n #handleAccountRemoved(accountId: AccountId) {\n const found = this.#reverse.get(accountId);\n\n if (found) {\n const { walletId, groupId } = found;\n this.update((state) => {\n const { accounts } =\n state.accountTree.wallets[walletId].groups[groupId];\n\n const index = accounts.indexOf(accountId);\n if (index !== -1) {\n accounts.splice(index, 1);\n }\n });\n }\n }\n\n #hasKeyringType(account: InternalAccount, type: KeyringTypes): boolean {\n return account.metadata.keyring.type === (type as string);\n }\n\n #matchGroupByEntropySource(\n account: InternalAccount,\n ): AccountTreeRuleMatch | undefined {\n let entropySource: string | undefined;\n\n if (this.#hasKeyringType(account, KeyringTypes.hd)) {\n // TODO: Maybe use superstruct to validate the structure of HD account since they are not strongly-typed for now?\n if (!account.options.entropySource) {\n console.warn(\n \"! Found an HD account with no entropy source: account won't be associated to its wallet\",\n );\n return undefined;\n }\n\n entropySource = account.options.entropySource as string;\n }\n\n // TODO: For now, we're not checking if the Snap is a preinstalled one, and we probably should...\n if (\n this.#hasKeyringType(account, KeyringTypes.snap) &&\n account.metadata.snap?.enabled\n ) {\n // Not all Snaps have an entropy-source and options are not typed yet, so we have to check manually here.\n if (account.options.entropySource) {\n // We blindly trust the `entropySource` for now, but it could be wrong since it comes from a Snap.\n entropySource = account.options.entropySource as string;\n }\n }\n\n if (!entropySource) {\n return undefined;\n }\n\n // We check if we can get the name for that entropy source, if not this means this entropy does not match\n // any HD keyrings, thus, is invalid (this account will be grouped by another rule).\n const entropySourceName = this.#getEntropySourceName(entropySource);\n if (!entropySourceName) {\n console.warn(\n '! Tried to name a wallet using an unknown entropy, this should not be possible.',\n );\n return undefined;\n }\n\n return {\n category: AccountWalletCategory.Entropy,\n id: toAccountWalletId(AccountWalletCategory.Entropy, entropySource),\n name: entropySourceName,\n };\n }\n\n #matchGroupBySnapId(\n account: InternalAccount,\n ): AccountTreeRuleMatch | undefined {\n if (\n this.#hasKeyringType(account, KeyringTypes.snap) &&\n account.metadata.snap &&\n account.metadata.snap.enabled\n ) {\n const { id } = account.metadata.snap;\n\n return {\n category: AccountWalletCategory.Snap,\n id: toAccountWalletId(AccountWalletCategory.Snap, id),\n name: this.#getSnapName(id as SnapId),\n };\n }\n\n return undefined;\n }\n\n #matchGroupByKeyringType(\n account: InternalAccount,\n ): AccountTreeRuleMatch | undefined {\n const { type } = account.metadata.keyring;\n\n return {\n category: AccountWalletCategory.Keyring,\n id: toAccountWalletId(AccountWalletCategory.Keyring, type),\n name: getAccountWalletNameFromKeyringType(type as KeyringTypes),\n };\n }\n\n #getSnapName(snapId: SnapId): string {\n const snap = this.messagingSystem.call('SnapController:get', snapId);\n const snapName = snap\n ? // TODO: Handle localization here, but that's a \"client thing\", so we don't have a `core` controller\n // to refer too.\n snap.manifest.proposedName\n : stripSnapPrefix(snapId);\n\n return `Snap: ${snapName}`;\n }\n\n #getEntropySourceName(entropySource: string): string | undefined {\n const { keyrings } = this.messagingSystem.call(\n 'KeyringController:getState',\n );\n\n const index = keyrings\n .filter((keyring) => keyring.type === (KeyringTypes.hd as string))\n .findIndex((keyring) => keyring.metadata.id === entropySource);\n\n if (index === -1) {\n return undefined;\n }\n\n return `Wallet ${index + 1}`; // Use human indexing.\n }\n\n #insert(\n wallets: { [walletId: AccountWalletId]: AccountWallet },\n account: InternalAccount,\n ) {\n for (const rule of this.#rules) {\n const match = rule(account);\n\n if (!match) {\n // No match for that rule, we go to the next one.\n continue;\n }\n\n const walletId = match.id;\n const walletName = match.name;\n const groupId = toDefaultAccountGroupId(walletId); // Use a single-group for now until multichain accounts is supported.\n const groupName = DEFAULT_ACCOUNT_GROUP_NAME;\n\n if (!wallets[walletId]) {\n wallets[walletId] = {\n id: walletId,\n groups: {\n [groupId]: {\n id: groupId,\n accounts: [],\n metadata: { name: groupName },\n },\n },\n metadata: {\n name: walletName,\n },\n };\n }\n wallets[walletId].groups[groupId].accounts.push(account.id);\n\n // Update the reverse mapping for this account.\n this.#reverse.set(account.id, {\n walletId,\n groupId,\n });\n\n return;\n }\n }\n\n #listAccounts(): InternalAccount[] {\n return this.messagingSystem.call(\n 'AccountsController:listMultichainAccounts',\n );\n }\n}\n"]}
|
package/package.json
CHANGED