@metamask/delegation-controller 1.0.0 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [2.0.1]
11
+
12
+ ### Changed
13
+
14
+ - Upgrade `@metamask/utils` from `^11.8.1` to `^11.9.0` ([#7511](https://github.com/MetaMask/core/pull/7511))
15
+ - Move peer dependencies for controller and service packages to direct dependencies ([#7209](https://github.com/MetaMask/core/pull/7209), [#7604](https://github.com/MetaMask/core/pull/7604), [#7642](https://github.com/MetaMask/core/pull/7642), [#7713](https://github.com/MetaMask/core/pull/7713)), ([#7897](https://github.com/MetaMask/core/pull/7897))
16
+ - The dependencies moved are:
17
+ - `@metamask/accounts-controller` (^36.0.0)
18
+ - `@metamask/keyring-controller` (^25.1.0)
19
+ - In clients, it is now possible for multiple versions of these packages to exist in the dependency tree.
20
+ - For example, this scenario would be valid: a client relies on `@metamask/controller-a` 1.0.0 and `@metamask/controller-b` 1.0.0, and `@metamask/controller-b` depends on `@metamask/controller-a` 1.1.0.
21
+ - Note, however, that the versions specified in the client's `package.json` always "win", and you are expected to keep them up to date so as not to break controller and service intercommunication.
22
+
23
+ ## [2.0.0]
24
+
25
+ ### Changed
26
+
27
+ - **BREAKING:** Bump `@metamask/keyring-controller` from `^24.0.0` to `^25.0.0` ([#7202](https://github.com/MetaMask/core/pull/7202))
28
+ - **BREAKING:** Bump `@metamask/accounts-controller` from `^34.0.0` to `^35.0.0` ([#7202](https://github.com/MetaMask/core/pull/7202))
29
+
10
30
  ## [1.0.0]
11
31
 
12
32
  ### Changed
@@ -82,7 +102,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
82
102
 
83
103
  - Initial release ([#5592](https://github.com/MetaMask/core/pull/5592))
84
104
 
85
- [Unreleased]: https://github.com/MetaMask/core/compare/@metamask/delegation-controller@1.0.0...HEAD
105
+ [Unreleased]: https://github.com/MetaMask/core/compare/@metamask/delegation-controller@2.0.1...HEAD
106
+ [2.0.1]: https://github.com/MetaMask/core/compare/@metamask/delegation-controller@2.0.0...@metamask/delegation-controller@2.0.1
107
+ [2.0.0]: https://github.com/MetaMask/core/compare/@metamask/delegation-controller@1.0.0...@metamask/delegation-controller@2.0.0
86
108
  [1.0.0]: https://github.com/MetaMask/core/compare/@metamask/delegation-controller@0.8.1...@metamask/delegation-controller@1.0.0
87
109
  [0.8.1]: https://github.com/MetaMask/core/compare/@metamask/delegation-controller@0.8.0...@metamask/delegation-controller@0.8.1
88
110
  [0.8.0]: https://github.com/MetaMask/core/compare/@metamask/delegation-controller@0.7.0...@metamask/delegation-controller@0.8.0
@@ -1 +1 @@
1
- {"version":3,"file":"DelegationController.cjs","sourceRoot":"","sources":["../src/DelegationController.ts"],"names":[],"mappings":"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","sourcesContent":["import type { StateMetadata } from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport { SignTypedDataVersion } from '@metamask/keyring-controller';\nimport { hexToNumber } from '@metamask/utils';\n\nimport { ROOT_AUTHORITY } from './constants';\nimport type {\n Address,\n Delegation,\n DelegationControllerMessenger,\n DelegationControllerState,\n DelegationEntry,\n DelegationFilter,\n DeleGatorEnvironment,\n Hex,\n UnsignedDelegation,\n} from './types';\nimport { createTypedMessageParams, isHexEqual } from './utils';\n\nexport const controllerName = 'DelegationController';\n\nconst delegationControllerMetadata = {\n delegations: {\n includeInStateLogs: false,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: false,\n },\n} satisfies StateMetadata<DelegationControllerState>;\n\n/**\n * Constructs the default {@link DelegationController} state. This allows\n * consumers to provide a partial state object when initializing the controller\n * and also helps in constructing complete state objects for this controller in\n * tests.\n *\n * @returns The default {@link DelegationController} state.\n */\nfunction getDefaultDelegationControllerState(): DelegationControllerState {\n return {\n delegations: {},\n };\n}\n\n/**\n * The {@link DelegationController} class.\n * This controller is meant to be a centralized place to store and sign delegations.\n */\nexport class DelegationController extends BaseController<\n typeof controllerName,\n DelegationControllerState,\n DelegationControllerMessenger\n> {\n readonly #hashDelegation: (delegation: Delegation) => Hex;\n\n readonly #getDelegationEnvironment: (chainId: Hex) => DeleGatorEnvironment;\n\n /**\n * Constructs a new {@link DelegationController} instance.\n *\n * @param params - The parameters for constructing the controller.\n * @param params.messenger - The messenger instance to use for the controller.\n * @param params.state - The initial state for the controller.\n * @param params.hashDelegation - A function to hash delegations.\n * @param params.getDelegationEnvironment - A function to get the delegation environment for a given chainId.\n */\n constructor({\n messenger,\n state,\n hashDelegation,\n getDelegationEnvironment,\n }: {\n messenger: DelegationControllerMessenger;\n state?: Partial<DelegationControllerState>;\n hashDelegation: (delegation: Delegation) => Hex;\n getDelegationEnvironment: (chainId: Hex) => DeleGatorEnvironment;\n }) {\n super({\n messenger,\n metadata: delegationControllerMetadata,\n name: controllerName,\n state: {\n ...getDefaultDelegationControllerState(),\n ...state,\n },\n });\n this.#hashDelegation = hashDelegation;\n this.#getDelegationEnvironment = getDelegationEnvironment;\n }\n\n /**\n * Signs a delegation.\n *\n * @param params - The parameters for signing the delegation.\n * @param params.delegation - The delegation to sign.\n * @param params.chainId - The chainId of the chain to sign the delegation for.\n * @returns The signature of the delegation.\n */\n async signDelegation(params: {\n delegation: UnsignedDelegation;\n chainId: Hex;\n }) {\n const { delegation, chainId } = params;\n const { DelegationManager } = this.#getDelegationEnvironment(chainId);\n\n const data = createTypedMessageParams({\n chainId: hexToNumber(chainId),\n from: delegation.delegator,\n delegation: {\n ...delegation,\n signature: '0x',\n },\n verifyingContract: DelegationManager,\n });\n\n // TODO:: Replace with `SignatureController:newUnsignedTypedMessage`.\n // Waiting on confirmations team to implement this.\n const signature: string = await this.messenger.call(\n 'KeyringController:signTypedMessage',\n data,\n SignTypedDataVersion.V4,\n );\n\n return signature;\n }\n\n /**\n * Stores a delegation in storage.\n *\n * @param params - The parameters for storing the delegation.\n * @param params.entry - The delegation entry to store.\n */\n store(params: { entry: DelegationEntry }) {\n const { entry } = params;\n const hash = this.#hashDelegation(entry.delegation);\n\n // If the authority is not the root authority, validate that the\n // parent entry does exist.\n if (\n !isHexEqual(entry.delegation.authority, ROOT_AUTHORITY) &&\n !this.state.delegations[entry.delegation.authority]\n ) {\n throw new Error('Invalid authority');\n }\n this.update((state) => {\n state.delegations[hash] = entry;\n });\n }\n\n /**\n * Lists delegation entries.\n *\n * @param filter - The filter to use to list the delegation entries.\n * @returns A list of delegation entries that match the filter.\n */\n list(filter?: DelegationFilter) {\n const account = this.messenger.call(\n 'AccountsController:getSelectedAccount',\n );\n const requester = account.address as Address;\n\n let list: DelegationEntry[] = Object.values(this.state.delegations);\n\n if (filter?.from) {\n list = list.filter((entry) =>\n isHexEqual(entry.delegation.delegator, filter.from as Address),\n );\n }\n\n if (\n !filter?.from ||\n (filter?.from && !isHexEqual(filter.from, requester))\n ) {\n list = list.filter((entry) =>\n isHexEqual(entry.delegation.delegate, requester),\n );\n }\n\n const filterChainId = filter?.chainId;\n if (filterChainId) {\n list = list.filter((entry) => isHexEqual(entry.chainId, filterChainId));\n }\n\n const tags = filter?.tags;\n if (tags && tags.length > 0) {\n // Filter entries that contain all of the filter tags\n list = list.filter((entry) =>\n tags.every((tag) => entry.tags.includes(tag)),\n );\n }\n\n return list;\n }\n\n /**\n * Retrieves the delegation entry for a given delegation hash.\n *\n * @param hash - The hash of the delegation to retrieve.\n * @returns The delegation entry, or null if not found.\n */\n retrieve(hash: Hex) {\n return this.state.delegations[hash] ?? null;\n }\n\n /**\n * Retrieves a delegation chain from a delegation hash.\n *\n * @param hash - The hash of the delegation to retrieve.\n * @returns The delegation chain, or null if not found.\n */\n chain(hash: Hex) {\n const chain: DelegationEntry[] = [];\n\n const entry = this.retrieve(hash);\n if (!entry) {\n return null;\n }\n chain.push(entry);\n\n for (let _hash = entry.delegation.authority; _hash !== ROOT_AUTHORITY; ) {\n const parent = this.retrieve(_hash);\n if (!parent) {\n throw new Error('Invalid delegation chain');\n }\n chain.push(parent);\n _hash = parent.delegation.authority;\n }\n\n return chain;\n }\n\n /**\n * Deletes a delegation entrie from storage, along with any other entries\n * that are redelegated from it.\n *\n * @param hash - The hash of the delegation to delete.\n * @returns The number of entries deleted.\n */\n delete(hash: Hex): number {\n const root = this.retrieve(hash);\n if (!root) {\n return 0;\n }\n\n const entries = Object.entries(this.state.delegations);\n const nextHashes: Hex[] = [hash];\n const deletedHashes: Hex[] = [];\n\n while (nextHashes.length > 0) {\n const currentHash = nextHashes.pop() as Hex;\n\n // Find all delegations that have this hash as their authority\n const children = entries.filter(\n ([_, v]) => v.delegation.authority === currentHash,\n );\n\n // Add the hashes of all child delegations to be processed next\n children.forEach(([k]) => {\n nextHashes.push(k as Hex);\n });\n\n deletedHashes.push(currentHash);\n }\n\n // Delete delegations\n this.update((state) => {\n deletedHashes.forEach((h) => {\n delete state.delegations[h];\n });\n });\n\n return deletedHashes.length;\n }\n}\n"]}
1
+ {"version":3,"file":"DelegationController.cjs","sourceRoot":"","sources":["../src/DelegationController.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AACA,+DAA2D;AAC3D,qEAAoE;AACpE,2CAA8C;AAE9C,+CAA6C;AAY7C,uCAA+D;AAElD,QAAA,cAAc,GAAG,sBAAsB,CAAC;AAErD,MAAM,4BAA4B,GAAG;IACnC,WAAW,EAAE;QACX,kBAAkB,EAAE,KAAK;QACzB,OAAO,EAAE,IAAI;QACb,sBAAsB,EAAE,KAAK;QAC7B,QAAQ,EAAE,KAAK;KAChB;CACiD,CAAC;AAErD;;;;;;;GAOG;AACH,SAAS,mCAAmC;IAC1C,OAAO;QACL,WAAW,EAAE,EAAE;KAChB,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAa,oBAAqB,SAAQ,gCAIzC;IAKC;;;;;;;;OAQG;IACH,YAAY,EACV,SAAS,EACT,KAAK,EACL,cAAc,EACd,wBAAwB,GAMzB;QACC,KAAK,CAAC;YACJ,SAAS;YACT,QAAQ,EAAE,4BAA4B;YACtC,IAAI,EAAE,sBAAc;YACpB,KAAK,EAAE;gBACL,GAAG,mCAAmC,EAAE;gBACxC,GAAG,KAAK;aACT;SACF,CAAC,CAAC;QAhCI,uDAAiD;QAEjD,iEAAkE;QA+BzE,uBAAA,IAAI,wCAAmB,cAAc,MAAA,CAAC;QACtC,uBAAA,IAAI,kDAA6B,wBAAwB,MAAA,CAAC;IAC5D,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,cAAc,CAAC,MAGpB;QACC,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;QACvC,MAAM,EAAE,iBAAiB,EAAE,GAAG,uBAAA,IAAI,sDAA0B,MAA9B,IAAI,EAA2B,OAAO,CAAC,CAAC;QAEtE,MAAM,IAAI,GAAG,IAAA,gCAAwB,EAAC;YACpC,OAAO,EAAE,IAAA,mBAAW,EAAC,OAAO,CAAC;YAC7B,IAAI,EAAE,UAAU,CAAC,SAAS;YAC1B,UAAU,EAAE;gBACV,GAAG,UAAU;gBACb,SAAS,EAAE,IAAI;aAChB;YACD,iBAAiB,EAAE,iBAAiB;SACrC,CAAC,CAAC;QAEH,qEAAqE;QACrE,mDAAmD;QACnD,MAAM,SAAS,GAAW,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CACjD,oCAAoC,EACpC,IAAI,EACJ,yCAAoB,CAAC,EAAE,CACxB,CAAC;QAEF,OAAO,SAAS,CAAC;IACnB,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,MAAkC;QACtC,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC;QACzB,MAAM,IAAI,GAAG,uBAAA,IAAI,4CAAgB,MAApB,IAAI,EAAiB,KAAK,CAAC,UAAU,CAAC,CAAC;QAEpD,gEAAgE;QAChE,2BAA2B;QAC3B,IACE,CAAC,IAAA,kBAAU,EAAC,KAAK,CAAC,UAAU,CAAC,SAAS,EAAE,0BAAc,CAAC;YACvD,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC,EACnD,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;QACvC,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YACpB,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;QAClC,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;OAKG;IACH,IAAI,CAAC,MAAyB;QAC5B,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CACjC,uCAAuC,CACxC,CAAC;QACF,MAAM,SAAS,GAAG,OAAO,CAAC,OAAkB,CAAC;QAE7C,IAAI,IAAI,GAAsB,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAEpE,IAAI,MAAM,EAAE,IAAI,EAAE,CAAC;YACjB,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAC3B,IAAA,kBAAU,EAAC,KAAK,CAAC,UAAU,CAAC,SAAS,EAAE,MAAM,CAAC,IAAe,CAAC,CAC/D,CAAC;QACJ,CAAC;QAED,IACE,CAAC,MAAM,EAAE,IAAI;YACb,CAAC,MAAM,EAAE,IAAI,IAAI,CAAC,IAAA,kBAAU,EAAC,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,EACrD,CAAC;YACD,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAC3B,IAAA,kBAAU,EAAC,KAAK,CAAC,UAAU,CAAC,QAAQ,EAAE,SAAS,CAAC,CACjD,CAAC;QACJ,CAAC;QAED,MAAM,aAAa,GAAG,MAAM,EAAE,OAAO,CAAC;QACtC,IAAI,aAAa,EAAE,CAAC;YAClB,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAA,kBAAU,EAAC,KAAK,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC;QAC1E,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,EAAE,IAAI,CAAC;QAC1B,IAAI,IAAI,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5B,qDAAqD;YACrD,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAC3B,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAC9C,CAAC;QACJ,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;OAKG;IACH,QAAQ,CAAC,IAAS;QAChB,OAAO,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC;IAC9C,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,IAAS;QACb,MAAM,KAAK,GAAsB,EAAE,CAAC;QAEpC,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAClC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,IAAI,CAAC;QACd,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAElB,KAAK,IAAI,KAAK,GAAG,KAAK,CAAC,UAAU,CAAC,SAAS,EAAE,KAAK,KAAK,0BAAc,GAAI,CAAC;YACxE,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YACpC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;YAC9C,CAAC;YACD,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACnB,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC;QACtC,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;;;;OAMG;IACH,MAAM,CAAC,IAAS;QACd,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACjC,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO,CAAC,CAAC;QACX,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QACvD,MAAM,UAAU,GAAU,CAAC,IAAI,CAAC,CAAC;QACjC,MAAM,aAAa,GAAU,EAAE,CAAC;QAEhC,OAAO,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7B,MAAM,WAAW,GAAG,UAAU,CAAC,GAAG,EAAS,CAAC;YAE5C,8DAA8D;YAC9D,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAC7B,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,SAAS,KAAK,WAAW,CACnD,CAAC;YAEF,+DAA+D;YAC/D,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE;gBACvB,UAAU,CAAC,IAAI,CAAC,CAAQ,CAAC,CAAC;YAC5B,CAAC,CAAC,CAAC;YAEH,aAAa,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAClC,CAAC;QAED,qBAAqB;QACrB,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YACpB,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;gBAC1B,OAAO,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;YAC9B,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,OAAO,aAAa,CAAC,MAAM,CAAC;IAC9B,CAAC;CACF;AAjOD,oDAiOC","sourcesContent":["import type { StateMetadata } from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport { SignTypedDataVersion } from '@metamask/keyring-controller';\nimport { hexToNumber } from '@metamask/utils';\n\nimport { ROOT_AUTHORITY } from './constants';\nimport type {\n Address,\n Delegation,\n DelegationControllerMessenger,\n DelegationControllerState,\n DelegationEntry,\n DelegationFilter,\n DeleGatorEnvironment,\n Hex,\n UnsignedDelegation,\n} from './types';\nimport { createTypedMessageParams, isHexEqual } from './utils';\n\nexport const controllerName = 'DelegationController';\n\nconst delegationControllerMetadata = {\n delegations: {\n includeInStateLogs: false,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: false,\n },\n} satisfies StateMetadata<DelegationControllerState>;\n\n/**\n * Constructs the default {@link DelegationController} state. This allows\n * consumers to provide a partial state object when initializing the controller\n * and also helps in constructing complete state objects for this controller in\n * tests.\n *\n * @returns The default {@link DelegationController} state.\n */\nfunction getDefaultDelegationControllerState(): DelegationControllerState {\n return {\n delegations: {},\n };\n}\n\n/**\n * The {@link DelegationController} class.\n * This controller is meant to be a centralized place to store and sign delegations.\n */\nexport class DelegationController extends BaseController<\n typeof controllerName,\n DelegationControllerState,\n DelegationControllerMessenger\n> {\n readonly #hashDelegation: (delegation: Delegation) => Hex;\n\n readonly #getDelegationEnvironment: (chainId: Hex) => DeleGatorEnvironment;\n\n /**\n * Constructs a new {@link DelegationController} instance.\n *\n * @param params - The parameters for constructing the controller.\n * @param params.messenger - The messenger instance to use for the controller.\n * @param params.state - The initial state for the controller.\n * @param params.hashDelegation - A function to hash delegations.\n * @param params.getDelegationEnvironment - A function to get the delegation environment for a given chainId.\n */\n constructor({\n messenger,\n state,\n hashDelegation,\n getDelegationEnvironment,\n }: {\n messenger: DelegationControllerMessenger;\n state?: Partial<DelegationControllerState>;\n hashDelegation: (delegation: Delegation) => Hex;\n getDelegationEnvironment: (chainId: Hex) => DeleGatorEnvironment;\n }) {\n super({\n messenger,\n metadata: delegationControllerMetadata,\n name: controllerName,\n state: {\n ...getDefaultDelegationControllerState(),\n ...state,\n },\n });\n this.#hashDelegation = hashDelegation;\n this.#getDelegationEnvironment = getDelegationEnvironment;\n }\n\n /**\n * Signs a delegation.\n *\n * @param params - The parameters for signing the delegation.\n * @param params.delegation - The delegation to sign.\n * @param params.chainId - The chainId of the chain to sign the delegation for.\n * @returns The signature of the delegation.\n */\n async signDelegation(params: {\n delegation: UnsignedDelegation;\n chainId: Hex;\n }) {\n const { delegation, chainId } = params;\n const { DelegationManager } = this.#getDelegationEnvironment(chainId);\n\n const data = createTypedMessageParams({\n chainId: hexToNumber(chainId),\n from: delegation.delegator,\n delegation: {\n ...delegation,\n signature: '0x',\n },\n verifyingContract: DelegationManager,\n });\n\n // TODO:: Replace with `SignatureController:newUnsignedTypedMessage`.\n // Waiting on confirmations team to implement this.\n const signature: string = await this.messenger.call(\n 'KeyringController:signTypedMessage',\n data,\n SignTypedDataVersion.V4,\n );\n\n return signature;\n }\n\n /**\n * Stores a delegation in storage.\n *\n * @param params - The parameters for storing the delegation.\n * @param params.entry - The delegation entry to store.\n */\n store(params: { entry: DelegationEntry }) {\n const { entry } = params;\n const hash = this.#hashDelegation(entry.delegation);\n\n // If the authority is not the root authority, validate that the\n // parent entry does exist.\n if (\n !isHexEqual(entry.delegation.authority, ROOT_AUTHORITY) &&\n !this.state.delegations[entry.delegation.authority]\n ) {\n throw new Error('Invalid authority');\n }\n this.update((state) => {\n state.delegations[hash] = entry;\n });\n }\n\n /**\n * Lists delegation entries.\n *\n * @param filter - The filter to use to list the delegation entries.\n * @returns A list of delegation entries that match the filter.\n */\n list(filter?: DelegationFilter) {\n const account = this.messenger.call(\n 'AccountsController:getSelectedAccount',\n );\n const requester = account.address as Address;\n\n let list: DelegationEntry[] = Object.values(this.state.delegations);\n\n if (filter?.from) {\n list = list.filter((entry) =>\n isHexEqual(entry.delegation.delegator, filter.from as Address),\n );\n }\n\n if (\n !filter?.from ||\n (filter?.from && !isHexEqual(filter.from, requester))\n ) {\n list = list.filter((entry) =>\n isHexEqual(entry.delegation.delegate, requester),\n );\n }\n\n const filterChainId = filter?.chainId;\n if (filterChainId) {\n list = list.filter((entry) => isHexEqual(entry.chainId, filterChainId));\n }\n\n const tags = filter?.tags;\n if (tags && tags.length > 0) {\n // Filter entries that contain all of the filter tags\n list = list.filter((entry) =>\n tags.every((tag) => entry.tags.includes(tag)),\n );\n }\n\n return list;\n }\n\n /**\n * Retrieves the delegation entry for a given delegation hash.\n *\n * @param hash - The hash of the delegation to retrieve.\n * @returns The delegation entry, or null if not found.\n */\n retrieve(hash: Hex) {\n return this.state.delegations[hash] ?? null;\n }\n\n /**\n * Retrieves a delegation chain from a delegation hash.\n *\n * @param hash - The hash of the delegation to retrieve.\n * @returns The delegation chain, or null if not found.\n */\n chain(hash: Hex) {\n const chain: DelegationEntry[] = [];\n\n const entry = this.retrieve(hash);\n if (!entry) {\n return null;\n }\n chain.push(entry);\n\n for (let _hash = entry.delegation.authority; _hash !== ROOT_AUTHORITY; ) {\n const parent = this.retrieve(_hash);\n if (!parent) {\n throw new Error('Invalid delegation chain');\n }\n chain.push(parent);\n _hash = parent.delegation.authority;\n }\n\n return chain;\n }\n\n /**\n * Deletes a delegation entrie from storage, along with any other entries\n * that are redelegated from it.\n *\n * @param hash - The hash of the delegation to delete.\n * @returns The number of entries deleted.\n */\n delete(hash: Hex): number {\n const root = this.retrieve(hash);\n if (!root) {\n return 0;\n }\n\n const entries = Object.entries(this.state.delegations);\n const nextHashes: Hex[] = [hash];\n const deletedHashes: Hex[] = [];\n\n while (nextHashes.length > 0) {\n const currentHash = nextHashes.pop() as Hex;\n\n // Find all delegations that have this hash as their authority\n const children = entries.filter(\n ([_, v]) => v.delegation.authority === currentHash,\n );\n\n // Add the hashes of all child delegations to be processed next\n children.forEach(([k]) => {\n nextHashes.push(k as Hex);\n });\n\n deletedHashes.push(currentHash);\n }\n\n // Delete delegations\n this.update((state) => {\n deletedHashes.forEach((h) => {\n delete state.delegations[h];\n });\n });\n\n return deletedHashes.length;\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"DelegationController.mjs","sourceRoot":"","sources":["../src/DelegationController.ts"],"names":[],"mappings":"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","sourcesContent":["import type { StateMetadata } from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport { SignTypedDataVersion } from '@metamask/keyring-controller';\nimport { hexToNumber } from '@metamask/utils';\n\nimport { ROOT_AUTHORITY } from './constants';\nimport type {\n Address,\n Delegation,\n DelegationControllerMessenger,\n DelegationControllerState,\n DelegationEntry,\n DelegationFilter,\n DeleGatorEnvironment,\n Hex,\n UnsignedDelegation,\n} from './types';\nimport { createTypedMessageParams, isHexEqual } from './utils';\n\nexport const controllerName = 'DelegationController';\n\nconst delegationControllerMetadata = {\n delegations: {\n includeInStateLogs: false,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: false,\n },\n} satisfies StateMetadata<DelegationControllerState>;\n\n/**\n * Constructs the default {@link DelegationController} state. This allows\n * consumers to provide a partial state object when initializing the controller\n * and also helps in constructing complete state objects for this controller in\n * tests.\n *\n * @returns The default {@link DelegationController} state.\n */\nfunction getDefaultDelegationControllerState(): DelegationControllerState {\n return {\n delegations: {},\n };\n}\n\n/**\n * The {@link DelegationController} class.\n * This controller is meant to be a centralized place to store and sign delegations.\n */\nexport class DelegationController extends BaseController<\n typeof controllerName,\n DelegationControllerState,\n DelegationControllerMessenger\n> {\n readonly #hashDelegation: (delegation: Delegation) => Hex;\n\n readonly #getDelegationEnvironment: (chainId: Hex) => DeleGatorEnvironment;\n\n /**\n * Constructs a new {@link DelegationController} instance.\n *\n * @param params - The parameters for constructing the controller.\n * @param params.messenger - The messenger instance to use for the controller.\n * @param params.state - The initial state for the controller.\n * @param params.hashDelegation - A function to hash delegations.\n * @param params.getDelegationEnvironment - A function to get the delegation environment for a given chainId.\n */\n constructor({\n messenger,\n state,\n hashDelegation,\n getDelegationEnvironment,\n }: {\n messenger: DelegationControllerMessenger;\n state?: Partial<DelegationControllerState>;\n hashDelegation: (delegation: Delegation) => Hex;\n getDelegationEnvironment: (chainId: Hex) => DeleGatorEnvironment;\n }) {\n super({\n messenger,\n metadata: delegationControllerMetadata,\n name: controllerName,\n state: {\n ...getDefaultDelegationControllerState(),\n ...state,\n },\n });\n this.#hashDelegation = hashDelegation;\n this.#getDelegationEnvironment = getDelegationEnvironment;\n }\n\n /**\n * Signs a delegation.\n *\n * @param params - The parameters for signing the delegation.\n * @param params.delegation - The delegation to sign.\n * @param params.chainId - The chainId of the chain to sign the delegation for.\n * @returns The signature of the delegation.\n */\n async signDelegation(params: {\n delegation: UnsignedDelegation;\n chainId: Hex;\n }) {\n const { delegation, chainId } = params;\n const { DelegationManager } = this.#getDelegationEnvironment(chainId);\n\n const data = createTypedMessageParams({\n chainId: hexToNumber(chainId),\n from: delegation.delegator,\n delegation: {\n ...delegation,\n signature: '0x',\n },\n verifyingContract: DelegationManager,\n });\n\n // TODO:: Replace with `SignatureController:newUnsignedTypedMessage`.\n // Waiting on confirmations team to implement this.\n const signature: string = await this.messenger.call(\n 'KeyringController:signTypedMessage',\n data,\n SignTypedDataVersion.V4,\n );\n\n return signature;\n }\n\n /**\n * Stores a delegation in storage.\n *\n * @param params - The parameters for storing the delegation.\n * @param params.entry - The delegation entry to store.\n */\n store(params: { entry: DelegationEntry }) {\n const { entry } = params;\n const hash = this.#hashDelegation(entry.delegation);\n\n // If the authority is not the root authority, validate that the\n // parent entry does exist.\n if (\n !isHexEqual(entry.delegation.authority, ROOT_AUTHORITY) &&\n !this.state.delegations[entry.delegation.authority]\n ) {\n throw new Error('Invalid authority');\n }\n this.update((state) => {\n state.delegations[hash] = entry;\n });\n }\n\n /**\n * Lists delegation entries.\n *\n * @param filter - The filter to use to list the delegation entries.\n * @returns A list of delegation entries that match the filter.\n */\n list(filter?: DelegationFilter) {\n const account = this.messenger.call(\n 'AccountsController:getSelectedAccount',\n );\n const requester = account.address as Address;\n\n let list: DelegationEntry[] = Object.values(this.state.delegations);\n\n if (filter?.from) {\n list = list.filter((entry) =>\n isHexEqual(entry.delegation.delegator, filter.from as Address),\n );\n }\n\n if (\n !filter?.from ||\n (filter?.from && !isHexEqual(filter.from, requester))\n ) {\n list = list.filter((entry) =>\n isHexEqual(entry.delegation.delegate, requester),\n );\n }\n\n const filterChainId = filter?.chainId;\n if (filterChainId) {\n list = list.filter((entry) => isHexEqual(entry.chainId, filterChainId));\n }\n\n const tags = filter?.tags;\n if (tags && tags.length > 0) {\n // Filter entries that contain all of the filter tags\n list = list.filter((entry) =>\n tags.every((tag) => entry.tags.includes(tag)),\n );\n }\n\n return list;\n }\n\n /**\n * Retrieves the delegation entry for a given delegation hash.\n *\n * @param hash - The hash of the delegation to retrieve.\n * @returns The delegation entry, or null if not found.\n */\n retrieve(hash: Hex) {\n return this.state.delegations[hash] ?? null;\n }\n\n /**\n * Retrieves a delegation chain from a delegation hash.\n *\n * @param hash - The hash of the delegation to retrieve.\n * @returns The delegation chain, or null if not found.\n */\n chain(hash: Hex) {\n const chain: DelegationEntry[] = [];\n\n const entry = this.retrieve(hash);\n if (!entry) {\n return null;\n }\n chain.push(entry);\n\n for (let _hash = entry.delegation.authority; _hash !== ROOT_AUTHORITY; ) {\n const parent = this.retrieve(_hash);\n if (!parent) {\n throw new Error('Invalid delegation chain');\n }\n chain.push(parent);\n _hash = parent.delegation.authority;\n }\n\n return chain;\n }\n\n /**\n * Deletes a delegation entrie from storage, along with any other entries\n * that are redelegated from it.\n *\n * @param hash - The hash of the delegation to delete.\n * @returns The number of entries deleted.\n */\n delete(hash: Hex): number {\n const root = this.retrieve(hash);\n if (!root) {\n return 0;\n }\n\n const entries = Object.entries(this.state.delegations);\n const nextHashes: Hex[] = [hash];\n const deletedHashes: Hex[] = [];\n\n while (nextHashes.length > 0) {\n const currentHash = nextHashes.pop() as Hex;\n\n // Find all delegations that have this hash as their authority\n const children = entries.filter(\n ([_, v]) => v.delegation.authority === currentHash,\n );\n\n // Add the hashes of all child delegations to be processed next\n children.forEach(([k]) => {\n nextHashes.push(k as Hex);\n });\n\n deletedHashes.push(currentHash);\n }\n\n // Delete delegations\n this.update((state) => {\n deletedHashes.forEach((h) => {\n delete state.delegations[h];\n });\n });\n\n return deletedHashes.length;\n }\n}\n"]}
1
+ {"version":3,"file":"DelegationController.mjs","sourceRoot":"","sources":["../src/DelegationController.ts"],"names":[],"mappings":"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","sourcesContent":["import type { StateMetadata } from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport { SignTypedDataVersion } from '@metamask/keyring-controller';\nimport { hexToNumber } from '@metamask/utils';\n\nimport { ROOT_AUTHORITY } from './constants';\nimport type {\n Address,\n Delegation,\n DelegationControllerMessenger,\n DelegationControllerState,\n DelegationEntry,\n DelegationFilter,\n DeleGatorEnvironment,\n Hex,\n UnsignedDelegation,\n} from './types';\nimport { createTypedMessageParams, isHexEqual } from './utils';\n\nexport const controllerName = 'DelegationController';\n\nconst delegationControllerMetadata = {\n delegations: {\n includeInStateLogs: false,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: false,\n },\n} satisfies StateMetadata<DelegationControllerState>;\n\n/**\n * Constructs the default {@link DelegationController} state. This allows\n * consumers to provide a partial state object when initializing the controller\n * and also helps in constructing complete state objects for this controller in\n * tests.\n *\n * @returns The default {@link DelegationController} state.\n */\nfunction getDefaultDelegationControllerState(): DelegationControllerState {\n return {\n delegations: {},\n };\n}\n\n/**\n * The {@link DelegationController} class.\n * This controller is meant to be a centralized place to store and sign delegations.\n */\nexport class DelegationController extends BaseController<\n typeof controllerName,\n DelegationControllerState,\n DelegationControllerMessenger\n> {\n readonly #hashDelegation: (delegation: Delegation) => Hex;\n\n readonly #getDelegationEnvironment: (chainId: Hex) => DeleGatorEnvironment;\n\n /**\n * Constructs a new {@link DelegationController} instance.\n *\n * @param params - The parameters for constructing the controller.\n * @param params.messenger - The messenger instance to use for the controller.\n * @param params.state - The initial state for the controller.\n * @param params.hashDelegation - A function to hash delegations.\n * @param params.getDelegationEnvironment - A function to get the delegation environment for a given chainId.\n */\n constructor({\n messenger,\n state,\n hashDelegation,\n getDelegationEnvironment,\n }: {\n messenger: DelegationControllerMessenger;\n state?: Partial<DelegationControllerState>;\n hashDelegation: (delegation: Delegation) => Hex;\n getDelegationEnvironment: (chainId: Hex) => DeleGatorEnvironment;\n }) {\n super({\n messenger,\n metadata: delegationControllerMetadata,\n name: controllerName,\n state: {\n ...getDefaultDelegationControllerState(),\n ...state,\n },\n });\n this.#hashDelegation = hashDelegation;\n this.#getDelegationEnvironment = getDelegationEnvironment;\n }\n\n /**\n * Signs a delegation.\n *\n * @param params - The parameters for signing the delegation.\n * @param params.delegation - The delegation to sign.\n * @param params.chainId - The chainId of the chain to sign the delegation for.\n * @returns The signature of the delegation.\n */\n async signDelegation(params: {\n delegation: UnsignedDelegation;\n chainId: Hex;\n }) {\n const { delegation, chainId } = params;\n const { DelegationManager } = this.#getDelegationEnvironment(chainId);\n\n const data = createTypedMessageParams({\n chainId: hexToNumber(chainId),\n from: delegation.delegator,\n delegation: {\n ...delegation,\n signature: '0x',\n },\n verifyingContract: DelegationManager,\n });\n\n // TODO:: Replace with `SignatureController:newUnsignedTypedMessage`.\n // Waiting on confirmations team to implement this.\n const signature: string = await this.messenger.call(\n 'KeyringController:signTypedMessage',\n data,\n SignTypedDataVersion.V4,\n );\n\n return signature;\n }\n\n /**\n * Stores a delegation in storage.\n *\n * @param params - The parameters for storing the delegation.\n * @param params.entry - The delegation entry to store.\n */\n store(params: { entry: DelegationEntry }) {\n const { entry } = params;\n const hash = this.#hashDelegation(entry.delegation);\n\n // If the authority is not the root authority, validate that the\n // parent entry does exist.\n if (\n !isHexEqual(entry.delegation.authority, ROOT_AUTHORITY) &&\n !this.state.delegations[entry.delegation.authority]\n ) {\n throw new Error('Invalid authority');\n }\n this.update((state) => {\n state.delegations[hash] = entry;\n });\n }\n\n /**\n * Lists delegation entries.\n *\n * @param filter - The filter to use to list the delegation entries.\n * @returns A list of delegation entries that match the filter.\n */\n list(filter?: DelegationFilter) {\n const account = this.messenger.call(\n 'AccountsController:getSelectedAccount',\n );\n const requester = account.address as Address;\n\n let list: DelegationEntry[] = Object.values(this.state.delegations);\n\n if (filter?.from) {\n list = list.filter((entry) =>\n isHexEqual(entry.delegation.delegator, filter.from as Address),\n );\n }\n\n if (\n !filter?.from ||\n (filter?.from && !isHexEqual(filter.from, requester))\n ) {\n list = list.filter((entry) =>\n isHexEqual(entry.delegation.delegate, requester),\n );\n }\n\n const filterChainId = filter?.chainId;\n if (filterChainId) {\n list = list.filter((entry) => isHexEqual(entry.chainId, filterChainId));\n }\n\n const tags = filter?.tags;\n if (tags && tags.length > 0) {\n // Filter entries that contain all of the filter tags\n list = list.filter((entry) =>\n tags.every((tag) => entry.tags.includes(tag)),\n );\n }\n\n return list;\n }\n\n /**\n * Retrieves the delegation entry for a given delegation hash.\n *\n * @param hash - The hash of the delegation to retrieve.\n * @returns The delegation entry, or null if not found.\n */\n retrieve(hash: Hex) {\n return this.state.delegations[hash] ?? null;\n }\n\n /**\n * Retrieves a delegation chain from a delegation hash.\n *\n * @param hash - The hash of the delegation to retrieve.\n * @returns The delegation chain, or null if not found.\n */\n chain(hash: Hex) {\n const chain: DelegationEntry[] = [];\n\n const entry = this.retrieve(hash);\n if (!entry) {\n return null;\n }\n chain.push(entry);\n\n for (let _hash = entry.delegation.authority; _hash !== ROOT_AUTHORITY; ) {\n const parent = this.retrieve(_hash);\n if (!parent) {\n throw new Error('Invalid delegation chain');\n }\n chain.push(parent);\n _hash = parent.delegation.authority;\n }\n\n return chain;\n }\n\n /**\n * Deletes a delegation entrie from storage, along with any other entries\n * that are redelegated from it.\n *\n * @param hash - The hash of the delegation to delete.\n * @returns The number of entries deleted.\n */\n delete(hash: Hex): number {\n const root = this.retrieve(hash);\n if (!root) {\n return 0;\n }\n\n const entries = Object.entries(this.state.delegations);\n const nextHashes: Hex[] = [hash];\n const deletedHashes: Hex[] = [];\n\n while (nextHashes.length > 0) {\n const currentHash = nextHashes.pop() as Hex;\n\n // Find all delegations that have this hash as their authority\n const children = entries.filter(\n ([_, v]) => v.delegation.authority === currentHash,\n );\n\n // Add the hashes of all child delegations to be processed next\n children.forEach(([k]) => {\n nextHashes.push(k as Hex);\n });\n\n deletedHashes.push(currentHash);\n }\n\n // Delete delegations\n this.update((state) => {\n deletedHashes.forEach((h) => {\n delete state.delegations[h];\n });\n });\n\n return deletedHashes.length;\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metamask/delegation-controller",
3
- "version": "1.0.0",
3
+ "version": "2.0.1",
4
4
  "description": "Manages delegations for MetaMask",
5
5
  "keywords": [
6
6
  "MetaMask",
@@ -36,6 +36,7 @@
36
36
  ],
37
37
  "scripts": {
38
38
  "build": "ts-bridge --project tsconfig.build.json --verbose --clean --no-references",
39
+ "build:all": "ts-bridge --project tsconfig.build.json --verbose --clean",
39
40
  "build:docs": "typedoc",
40
41
  "changelog:update": "../../scripts/update-changelog.sh @metamask/delegation-controller",
41
42
  "changelog:validate": "../../scripts/validate-changelog.sh @metamask/delegation-controller",
@@ -47,26 +48,22 @@
47
48
  "test:watch": "NODE_OPTIONS=--experimental-vm-modules jest --watch"
48
49
  },
49
50
  "dependencies": {
51
+ "@metamask/accounts-controller": "^36.0.0",
50
52
  "@metamask/base-controller": "^9.0.0",
53
+ "@metamask/keyring-controller": "^25.1.0",
51
54
  "@metamask/messenger": "^0.3.0",
52
- "@metamask/utils": "^11.8.1"
55
+ "@metamask/utils": "^11.9.0"
53
56
  },
54
57
  "devDependencies": {
55
- "@metamask/accounts-controller": "^34.0.0",
56
58
  "@metamask/auto-changelog": "^3.4.4",
57
- "@metamask/keyring-controller": "^24.0.0",
58
- "@ts-bridge/cli": "^0.6.1",
59
- "@types/jest": "^27.4.1",
59
+ "@ts-bridge/cli": "^0.6.4",
60
+ "@types/jest": "^29.5.14",
60
61
  "deepmerge": "^4.2.2",
61
- "jest": "^27.5.1",
62
- "ts-jest": "^27.1.4",
63
- "typedoc": "^0.24.8",
62
+ "jest": "^29.7.0",
63
+ "ts-jest": "^29.2.5",
64
+ "typedoc": "^0.25.13",
64
65
  "typedoc-plugin-missing-exports": "^2.0.0",
65
- "typescript": "~5.2.2"
66
- },
67
- "peerDependencies": {
68
- "@metamask/accounts-controller": "^34.0.0",
69
- "@metamask/keyring-controller": "^24.0.0"
66
+ "typescript": "~5.3.3"
70
67
  },
71
68
  "engines": {
72
69
  "node": "^18.18 || >=20"