@metamask/snaps-controllers 0.33.1-flask.1 → 0.34.0-flask.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 +73 -65
- package/dist/cronjob/CronjobController.d.ts +3 -3
- package/dist/cronjob/CronjobController.js.map +1 -1
- package/dist/multichain/MultiChainController.js +1 -1
- package/dist/multichain/MultiChainController.js.map +1 -1
- package/dist/snaps/SnapController.d.ts +22 -22
- package/dist/snaps/SnapController.js +8 -22
- package/dist/snaps/SnapController.js.map +1 -1
- package/dist/snaps/endowments/cronjob.d.ts +2 -2
- package/dist/snaps/endowments/cronjob.js +2 -2
- package/dist/snaps/endowments/cronjob.js.map +1 -1
- package/dist/snaps/endowments/ethereum-provider.d.ts +2 -2
- package/dist/snaps/endowments/ethereum-provider.js +2 -2
- package/dist/snaps/endowments/ethereum-provider.js.map +1 -1
- package/dist/snaps/endowments/index.d.ts +16 -16
- package/dist/snaps/endowments/index.js +16 -16
- package/dist/snaps/endowments/index.js.map +1 -1
- package/dist/snaps/endowments/keyring.d.ts +3 -3
- package/dist/snaps/endowments/keyring.js +5 -4
- package/dist/snaps/endowments/keyring.js.map +1 -1
- package/dist/snaps/endowments/long-running.d.ts +2 -2
- package/dist/snaps/endowments/long-running.js +2 -2
- package/dist/snaps/endowments/long-running.js.map +1 -1
- package/dist/snaps/endowments/network-access.d.ts +2 -2
- package/dist/snaps/endowments/network-access.js +2 -2
- package/dist/snaps/endowments/network-access.js.map +1 -1
- package/dist/snaps/endowments/rpc.d.ts +3 -3
- package/dist/snaps/endowments/rpc.js +5 -4
- package/dist/snaps/endowments/rpc.js.map +1 -1
- package/dist/snaps/endowments/transaction-insight.d.ts +2 -2
- package/dist/snaps/endowments/transaction-insight.js +2 -2
- package/dist/snaps/endowments/transaction-insight.js.map +1 -1
- package/dist/snaps/endowments/web-assembly.d.ts +2 -2
- package/dist/snaps/endowments/web-assembly.js +2 -2
- package/dist/snaps/endowments/web-assembly.js.map +1 -1
- package/dist/snaps/index.d.ts +1 -0
- package/dist/snaps/index.js +1 -0
- package/dist/snaps/index.js.map +1 -1
- package/dist/snaps/location/npm.d.ts +20 -0
- package/dist/snaps/location/npm.js +30 -14
- package/dist/snaps/location/npm.js.map +1 -1
- package/dist/snaps/permissions.d.ts +16 -0
- package/dist/snaps/permissions.js +54 -0
- package/dist/snaps/permissions.js.map +1 -0
- package/dist/snaps/registry/registry.d.ts +3 -3
- package/dist/snaps/registry/registry.js.map +1 -1
- package/package.json +10 -10
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.34.0-flask.1]
|
|
10
|
+
### Changed
|
|
11
|
+
- **BREAKING:** Rename `targetKey` to `targetName` as part of updating `PermissionController` ([#1450](https://github.com/MetaMask/snaps/pull/1450))
|
|
12
|
+
- Add SVG validation ([#1401](https://github.com/MetaMask/snaps/pull/1401))
|
|
13
|
+
- Export permissions specification builders ([#1432](https://github.com/MetaMask/snaps/pull/1432))
|
|
14
|
+
- Export `processSnapPermissions` ([#1402](https://github.com/MetaMask/snaps/pull/1402))
|
|
15
|
+
|
|
9
16
|
## [0.33.1-flask.1]
|
|
10
17
|
### Fixed
|
|
11
18
|
- Skip subjects without the `wallet_snap` permission in `removeSnapFromSubject` ([#1388](https://github.com/MetaMask/snaps-monorepo/pull/1388))
|
|
@@ -508,68 +515,69 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
508
515
|
### Added
|
|
509
516
|
- First semi-stable release.
|
|
510
517
|
|
|
511
|
-
[Unreleased]: https://github.com/MetaMask/snaps
|
|
512
|
-
[0.
|
|
513
|
-
[0.33.
|
|
514
|
-
[0.
|
|
515
|
-
[0.32.
|
|
516
|
-
[0.32.
|
|
517
|
-
[0.
|
|
518
|
-
[0.
|
|
519
|
-
[0.
|
|
520
|
-
[0.
|
|
521
|
-
[0.
|
|
522
|
-
[0.27.
|
|
523
|
-
[0.
|
|
524
|
-
[0.26.
|
|
525
|
-
[0.26.
|
|
526
|
-
[0.
|
|
527
|
-
[0.
|
|
528
|
-
[0.24.
|
|
529
|
-
[0.
|
|
530
|
-
[0.
|
|
531
|
-
[0.22.
|
|
532
|
-
[0.22.
|
|
533
|
-
[0.22.
|
|
534
|
-
[0.
|
|
535
|
-
[0.
|
|
536
|
-
[0.
|
|
537
|
-
[0.19.
|
|
538
|
-
[0.
|
|
539
|
-
[0.18.
|
|
540
|
-
[0.
|
|
541
|
-
[0.
|
|
542
|
-
[0.
|
|
543
|
-
[0.
|
|
544
|
-
[0.
|
|
545
|
-
[0.
|
|
546
|
-
[0.
|
|
547
|
-
[0.11.
|
|
548
|
-
[0.
|
|
549
|
-
[0.10.
|
|
550
|
-
[0.10.
|
|
551
|
-
[0.10.
|
|
552
|
-
[0.10.
|
|
553
|
-
[0.10.
|
|
554
|
-
[0.10.
|
|
555
|
-
[0.
|
|
556
|
-
[0.
|
|
557
|
-
[0.8.
|
|
558
|
-
[0.
|
|
559
|
-
[0.
|
|
560
|
-
[0.6.
|
|
561
|
-
[0.6.
|
|
562
|
-
[0.6.
|
|
563
|
-
[0.
|
|
564
|
-
[0.
|
|
565
|
-
[0.
|
|
566
|
-
[0.3.
|
|
567
|
-
[0.
|
|
568
|
-
[0.2.
|
|
569
|
-
[0.
|
|
570
|
-
[0.1.
|
|
571
|
-
[0.1.
|
|
572
|
-
[0.0
|
|
573
|
-
[0.0.
|
|
574
|
-
[0.0.
|
|
575
|
-
[0.0.
|
|
518
|
+
[Unreleased]: https://github.com/MetaMask/snaps/compare/v0.34.0-flask.1...HEAD
|
|
519
|
+
[0.34.0-flask.1]: https://github.com/MetaMask/snaps/compare/v0.33.1-flask.1...v0.34.0-flask.1
|
|
520
|
+
[0.33.1-flask.1]: https://github.com/MetaMask/snaps/compare/v0.33.0-flask.1...v0.33.1-flask.1
|
|
521
|
+
[0.33.0-flask.1]: https://github.com/MetaMask/snaps/compare/v0.32.2...v0.33.0-flask.1
|
|
522
|
+
[0.32.2]: https://github.com/MetaMask/snaps/compare/v0.32.1...v0.32.2
|
|
523
|
+
[0.32.1]: https://github.com/MetaMask/snaps/compare/v0.32.0...v0.32.1
|
|
524
|
+
[0.32.0]: https://github.com/MetaMask/snaps/compare/v0.31.0...v0.32.0
|
|
525
|
+
[0.31.0]: https://github.com/MetaMask/snaps/compare/v0.30.0...v0.31.0
|
|
526
|
+
[0.30.0]: https://github.com/MetaMask/snaps/compare/v0.29.0...v0.30.0
|
|
527
|
+
[0.29.0]: https://github.com/MetaMask/snaps/compare/v0.28.0...v0.29.0
|
|
528
|
+
[0.28.0]: https://github.com/MetaMask/snaps/compare/v0.27.1...v0.28.0
|
|
529
|
+
[0.27.1]: https://github.com/MetaMask/snaps/compare/v0.27.0...v0.27.1
|
|
530
|
+
[0.27.0]: https://github.com/MetaMask/snaps/compare/v0.26.2...v0.27.0
|
|
531
|
+
[0.26.2]: https://github.com/MetaMask/snaps/compare/v0.26.1...v0.26.2
|
|
532
|
+
[0.26.1]: https://github.com/MetaMask/snaps/compare/v0.26.0...v0.26.1
|
|
533
|
+
[0.26.0]: https://github.com/MetaMask/snaps/compare/v0.25.0...v0.26.0
|
|
534
|
+
[0.25.0]: https://github.com/MetaMask/snaps/compare/v0.24.1...v0.25.0
|
|
535
|
+
[0.24.1]: https://github.com/MetaMask/snaps/compare/v0.24.0...v0.24.1
|
|
536
|
+
[0.24.0]: https://github.com/MetaMask/snaps/compare/v0.23.0...v0.24.0
|
|
537
|
+
[0.23.0]: https://github.com/MetaMask/snaps/compare/v0.22.3...v0.23.0
|
|
538
|
+
[0.22.3]: https://github.com/MetaMask/snaps/compare/v0.22.2...v0.22.3
|
|
539
|
+
[0.22.2]: https://github.com/MetaMask/snaps/compare/v0.22.1...v0.22.2
|
|
540
|
+
[0.22.1]: https://github.com/MetaMask/snaps/compare/v0.22.0...v0.22.1
|
|
541
|
+
[0.22.0]: https://github.com/MetaMask/snaps/compare/v0.21.0...v0.22.0
|
|
542
|
+
[0.21.0]: https://github.com/MetaMask/snaps/compare/v0.20.0...v0.21.0
|
|
543
|
+
[0.20.0]: https://github.com/MetaMask/snaps/compare/v0.19.1...v0.20.0
|
|
544
|
+
[0.19.1]: https://github.com/MetaMask/snaps/compare/v0.19.0...v0.19.1
|
|
545
|
+
[0.19.0]: https://github.com/MetaMask/snaps/compare/v0.18.1...v0.19.0
|
|
546
|
+
[0.18.1]: https://github.com/MetaMask/snaps/compare/v0.18.0...v0.18.1
|
|
547
|
+
[0.18.0]: https://github.com/MetaMask/snaps/compare/v0.17.0...v0.18.0
|
|
548
|
+
[0.17.0]: https://github.com/MetaMask/snaps/compare/v0.16.0...v0.17.0
|
|
549
|
+
[0.16.0]: https://github.com/MetaMask/snaps/compare/v0.15.0...v0.16.0
|
|
550
|
+
[0.15.0]: https://github.com/MetaMask/snaps/compare/v0.14.0...v0.15.0
|
|
551
|
+
[0.14.0]: https://github.com/MetaMask/snaps/compare/v0.13.0...v0.14.0
|
|
552
|
+
[0.13.0]: https://github.com/MetaMask/snaps/compare/v0.12.0...v0.13.0
|
|
553
|
+
[0.12.0]: https://github.com/MetaMask/snaps/compare/v0.11.1...v0.12.0
|
|
554
|
+
[0.11.1]: https://github.com/MetaMask/snaps/compare/v0.11.0...v0.11.1
|
|
555
|
+
[0.11.0]: https://github.com/MetaMask/snaps/compare/v0.10.7...v0.11.0
|
|
556
|
+
[0.10.7]: https://github.com/MetaMask/snaps/compare/v0.10.6...v0.10.7
|
|
557
|
+
[0.10.6]: https://github.com/MetaMask/snaps/compare/v0.10.5...v0.10.6
|
|
558
|
+
[0.10.5]: https://github.com/MetaMask/snaps/compare/v0.10.3...v0.10.5
|
|
559
|
+
[0.10.3]: https://github.com/MetaMask/snaps/compare/v0.10.2...v0.10.3
|
|
560
|
+
[0.10.2]: https://github.com/MetaMask/snaps/compare/v0.10.1...v0.10.2
|
|
561
|
+
[0.10.1]: https://github.com/MetaMask/snaps/compare/v0.10.0...v0.10.1
|
|
562
|
+
[0.10.0]: https://github.com/MetaMask/snaps/compare/v0.9.0...v0.10.0
|
|
563
|
+
[0.9.0]: https://github.com/MetaMask/snaps/compare/v0.8.1...v0.9.0
|
|
564
|
+
[0.8.1]: https://github.com/MetaMask/snaps/compare/v0.8.0...v0.8.1
|
|
565
|
+
[0.8.0]: https://github.com/MetaMask/snaps/compare/v0.7.0...v0.8.0
|
|
566
|
+
[0.7.0]: https://github.com/MetaMask/snaps/compare/v0.6.3...v0.7.0
|
|
567
|
+
[0.6.3]: https://github.com/MetaMask/snaps/compare/v0.6.2...v0.6.3
|
|
568
|
+
[0.6.2]: https://github.com/MetaMask/snaps/compare/v0.6.1...v0.6.2
|
|
569
|
+
[0.6.1]: https://github.com/MetaMask/snaps/compare/v0.6.0...v0.6.1
|
|
570
|
+
[0.6.0]: https://github.com/MetaMask/snaps/compare/v0.5.0...v0.6.0
|
|
571
|
+
[0.5.0]: https://github.com/MetaMask/snaps/compare/v0.4.0...v0.5.0
|
|
572
|
+
[0.4.0]: https://github.com/MetaMask/snaps/compare/v0.3.1...v0.4.0
|
|
573
|
+
[0.3.1]: https://github.com/MetaMask/snaps/compare/v0.3.0...v0.3.1
|
|
574
|
+
[0.3.0]: https://github.com/MetaMask/snaps/compare/v0.2.2...v0.3.0
|
|
575
|
+
[0.2.2]: https://github.com/MetaMask/snaps/compare/v0.2.0...v0.2.2
|
|
576
|
+
[0.2.0]: https://github.com/MetaMask/snaps/compare/v0.1.2...v0.2.0
|
|
577
|
+
[0.1.2]: https://github.com/MetaMask/snaps/compare/v0.1.1...v0.1.2
|
|
578
|
+
[0.1.1]: https://github.com/MetaMask/snaps/compare/v0.1.0...v0.1.1
|
|
579
|
+
[0.1.0]: https://github.com/MetaMask/snaps/compare/v0.0.9...v0.1.0
|
|
580
|
+
[0.0.9]: https://github.com/MetaMask/snaps/compare/v0.0.7...v0.0.9
|
|
581
|
+
[0.0.7]: https://github.com/MetaMask/snaps/compare/v0.0.6...v0.0.7
|
|
582
|
+
[0.0.6]: https://github.com/MetaMask/snaps/compare/v0.0.5...v0.0.6
|
|
583
|
+
[0.0.5]: https://github.com/MetaMask/snaps/releases/tag/v0.0.5
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BaseControllerV2 as BaseController, RestrictedControllerMessenger } from '@metamask/base-controller';
|
|
2
2
|
import { GetPermissions } from '@metamask/permission-controller';
|
|
3
|
-
import { SnapId, CronjobSpecification } from '@metamask/snaps-utils';
|
|
3
|
+
import { SnapId, ValidatedSnapId, CronjobSpecification } from '@metamask/snaps-utils';
|
|
4
4
|
import { GetAllSnaps, HandleSnapRequest, SnapInstalled, SnapRemoved, SnapUpdated } from '..';
|
|
5
5
|
import { Timer } from '../snaps/Timer';
|
|
6
6
|
export declare type CronjobControllerActions = GetAllSnaps | HandleSnapRequest | GetPermissions;
|
|
@@ -17,7 +17,7 @@ export declare type CronjobControllerArgs = {
|
|
|
17
17
|
export declare type Cronjob = {
|
|
18
18
|
timer?: Timer;
|
|
19
19
|
id: string;
|
|
20
|
-
snapId:
|
|
20
|
+
snapId: ValidatedSnapId;
|
|
21
21
|
} & CronjobSpecification;
|
|
22
22
|
export declare type StoredJobInformation = {
|
|
23
23
|
lastRun: number;
|
|
@@ -52,7 +52,7 @@ export declare class CronjobController extends BaseController<typeof controllerN
|
|
|
52
52
|
*
|
|
53
53
|
* @param snapId - ID of a snap.
|
|
54
54
|
*/
|
|
55
|
-
register(snapId:
|
|
55
|
+
register(snapId: ValidatedSnapId): void;
|
|
56
56
|
/**
|
|
57
57
|
* Schedule a new job.
|
|
58
58
|
* This will interpret the cron expression and tell the timer to execute the job
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CronjobController.js","sourceRoot":"","sources":["../../src/cronjob/CronjobController.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n BaseControllerV2 as BaseController,\n RestrictedControllerMessenger,\n} from '@metamask/base-controller';\nimport { GetPermissions } from '@metamask/permission-controller';\nimport {\n HandlerType,\n SnapId,\n TruncatedSnap,\n CronjobSpecification,\n parseCronExpression,\n logError,\n} from '@metamask/snaps-utils';\nimport { Duration, inMilliseconds } from '@metamask/utils';\n\nimport {\n GetAllSnaps,\n getRunnableSnaps,\n HandleSnapRequest,\n SnapEndowments,\n SnapInstalled,\n SnapRemoved,\n SnapUpdated,\n} from '..';\nimport { getCronjobCaveatJobs } from '../snaps/endowments/cronjob';\nimport { Timer } from '../snaps/Timer';\n\nexport type CronjobControllerActions =\n | GetAllSnaps\n | HandleSnapRequest\n | GetPermissions;\n\nexport type CronjobControllerEvents = SnapInstalled | SnapRemoved | SnapUpdated;\n\nexport type CronjobControllerMessenger = RestrictedControllerMessenger<\n 'CronjobController',\n CronjobControllerActions,\n CronjobControllerEvents,\n CronjobControllerActions['type'],\n CronjobControllerEvents['type']\n>;\n\nexport const DAILY_TIMEOUT = inMilliseconds(24, Duration.Hour);\n\nexport type CronjobControllerArgs = {\n messenger: CronjobControllerMessenger;\n /**\n * Persisted state that will be used for rehydration.\n */\n state?: CronjobControllerState;\n};\n\nexport type Cronjob = {\n timer?: Timer;\n id: string;\n snapId: SnapId;\n} & CronjobSpecification;\n\nexport type StoredJobInformation = {\n lastRun: number;\n};\n\nexport type CronjobControllerState = {\n jobs: Record<string, StoredJobInformation>;\n};\n\nconst controllerName = 'CronjobController';\n\n/**\n * Use this controller to register and schedule periodically executed jobs\n * using RPC method hooks.\n */\nexport class CronjobController extends BaseController<\n typeof controllerName,\n CronjobControllerState,\n CronjobControllerMessenger\n> {\n #messenger: CronjobControllerMessenger;\n\n #dailyTimer!: Timer;\n\n #timers: Map<string, Timer>;\n\n // Mapping from jobId to snapId\n #snapIds: Map<string, string>;\n\n constructor({ messenger, state }: CronjobControllerArgs) {\n super({\n messenger,\n metadata: {\n jobs: { persist: true, anonymous: false },\n },\n name: controllerName,\n state: {\n jobs: {},\n ...state,\n },\n });\n this.#timers = new Map();\n this.#snapIds = new Map();\n this.#messenger = messenger;\n\n this._handleEventSnapInstalled = this._handleEventSnapInstalled.bind(this);\n this._handleEventSnapRemoved = this._handleEventSnapRemoved.bind(this);\n this._handleEventSnapUpdated = this._handleEventSnapUpdated.bind(this);\n\n // Subscribe to Snap events\n /* eslint-disable @typescript-eslint/unbound-method */\n this.messagingSystem.subscribe(\n 'SnapController:snapInstalled',\n this._handleEventSnapInstalled,\n );\n\n this.messagingSystem.subscribe(\n 'SnapController:snapRemoved',\n this._handleEventSnapRemoved,\n );\n\n this.messagingSystem.subscribe(\n 'SnapController:snapUpdated',\n this._handleEventSnapUpdated,\n );\n /* eslint-enable @typescript-eslint/unbound-method */\n\n this.dailyCheckIn().catch((error) => {\n logError(error);\n });\n }\n\n /**\n * Retrieve all cronjob specifications for all runnable snaps.\n *\n * @returns Array of Cronjob specifications.\n */\n private getAllJobs(): Cronjob[] {\n const snaps = this.messagingSystem.call('SnapController:getAll');\n const filteredSnaps = getRunnableSnaps(snaps);\n\n const jobs = filteredSnaps.map((snap) => this.getSnapJobs(snap.id));\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n return jobs.flat().filter((job) => job !== undefined) as Cronjob[];\n }\n\n /**\n * Retrieve all Cronjob specifications for a Snap.\n *\n * @param snapId - ID of a Snap.\n * @returns Array of Cronjob specifications.\n */\n private getSnapJobs(snapId: SnapId): Cronjob[] | undefined {\n const permissions = this.#messenger.call(\n 'PermissionController:getPermissions',\n snapId,\n );\n\n const permission = permissions?.[SnapEndowments.Cronjob];\n const definitions = getCronjobCaveatJobs(permission);\n\n return definitions?.map((definition, idx) => {\n return { ...definition, id: `${snapId}-${idx}`, snapId };\n });\n }\n\n /**\n * Register cron jobs for a given snap by getting specification from a permission caveats.\n * Once registered, each job will be scheduled.\n *\n * @param snapId - ID of a snap.\n */\n register(snapId: SnapId) {\n const jobs = this.getSnapJobs(snapId);\n jobs?.forEach((job) => this.schedule(job));\n }\n\n /**\n * Schedule a new job.\n * This will interpret the cron expression and tell the timer to execute the job\n * at the next suitable point in time.\n * Job last run state will be initialized afterwards.\n *\n * Note: Schedule will be skipped if the job's execution time is too far in the future and\n * will be revisited on a daily check.\n *\n * @param job - Cronjob specification.\n */\n private schedule(job: Cronjob) {\n if (this.#timers.has(job.id)) {\n return;\n }\n\n const parsed = parseCronExpression(job.expression);\n const next = parsed.next();\n const now = new Date();\n const ms = next.getTime() - now.getTime();\n\n // Don't schedule this job yet as it is too far in the future\n if (ms > DAILY_TIMEOUT) {\n return;\n }\n\n const timer = new Timer(ms);\n timer.start(() => {\n this.executeCronjob(job).catch((error) => {\n // TODO: Decide how to handle errors.\n logError(error);\n });\n\n this.#timers.delete(job.id);\n this.schedule(job);\n });\n\n this.updateJobLastRunState(job.id, 0); // 0 for init, never ran actually\n this.#timers.set(job.id, timer);\n this.#snapIds.set(job.id, job.snapId);\n }\n\n /**\n * Execute job.\n *\n * @param job - Cronjob specification.\n */\n private async executeCronjob(job: Cronjob) {\n this.updateJobLastRunState(job.id, Date.now());\n await this.#messenger.call('SnapController:handleRequest', {\n snapId: job.snapId,\n origin: '',\n handler: HandlerType.OnCronjob,\n request: job.request,\n });\n }\n\n /**\n * Unregister all jobs related to the given snapId.\n *\n * @param snapId - ID of a snap.\n */\n unregister(snapId: SnapId) {\n const jobs = [...this.#snapIds.entries()].filter(\n ([_, jobSnapId]) => jobSnapId === snapId,\n );\n\n if (jobs.length) {\n jobs.forEach(([id]) => {\n const timer = this.#timers.get(id);\n if (timer) {\n timer.cancel();\n this.#timers.delete(id);\n this.#snapIds.delete(id);\n }\n });\n }\n }\n\n /**\n * Update time of a last run for the Cronjob specified by ID.\n *\n * @param jobId - ID of a cron job.\n * @param lastRun - Unix timestamp when the job was last ran.\n */\n private updateJobLastRunState(jobId: string, lastRun: number) {\n this.update((state) => {\n state.jobs[jobId] = {\n lastRun,\n };\n });\n }\n\n /**\n * Runs every 24 hours to check if new jobs need to be scheduled.\n *\n * This is necesary for longer running jobs that execute with more than 24 hours between them.\n */\n async dailyCheckIn() {\n const jobs = this.getAllJobs();\n\n for (const job of jobs) {\n const parsed = parseCronExpression(job.expression);\n const lastRun = this.state.jobs[job.id]?.lastRun;\n // If a job was supposed to run while we were shut down but wasn't we run it now\n if (\n lastRun !== undefined &&\n parsed.hasPrev() &&\n parsed.prev().getTime() > lastRun\n ) {\n await this.executeCronjob(job);\n }\n\n // Try scheduling, will fail if an existing scheduled job is found\n this.schedule(job);\n }\n\n this.#dailyTimer = new Timer(DAILY_TIMEOUT);\n this.#dailyTimer.start(() => {\n this.dailyCheckIn().catch((error) => {\n // TODO: Decide how to handle errors.\n logError(error);\n });\n });\n }\n\n /**\n * Run controller teardown process and unsubscribe from Snap events.\n */\n destroy() {\n super.destroy();\n\n /* eslint-disable @typescript-eslint/unbound-method */\n this.messagingSystem.unsubscribe(\n 'SnapController:snapInstalled',\n this._handleEventSnapInstalled,\n );\n\n this.messagingSystem.unsubscribe(\n 'SnapController:snapRemoved',\n this._handleEventSnapRemoved,\n );\n\n this.messagingSystem.unsubscribe(\n 'SnapController:snapUpdated',\n this._handleEventSnapUpdated,\n );\n /* eslint-enable @typescript-eslint/unbound-method */\n\n this.#snapIds.forEach((snapId) => {\n this.unregister(snapId);\n });\n }\n\n /**\n * Handle cron jobs on 'snapInstalled' event.\n *\n * @param snap - Basic Snap information.\n */\n private _handleEventSnapInstalled(snap: TruncatedSnap) {\n this.register(snap.id);\n }\n\n /**\n * Handle cron jobs on 'snapRemoved' event.\n *\n * @param snap - Basic Snap information.\n */\n private _handleEventSnapRemoved(snap: TruncatedSnap) {\n this.unregister(snap.id);\n }\n\n /**\n * Handle cron jobs on 'snapUpdated' event.\n *\n * @param snap - Basic Snap information.\n */\n private _handleEventSnapUpdated(snap: TruncatedSnap) {\n this.unregister(snap.id);\n this.register(snap.id);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"CronjobController.js","sourceRoot":"","sources":["../../src/cronjob/CronjobController.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n BaseControllerV2 as BaseController,\n RestrictedControllerMessenger,\n} from '@metamask/base-controller';\nimport { GetPermissions } from '@metamask/permission-controller';\nimport {\n HandlerType,\n SnapId,\n ValidatedSnapId,\n TruncatedSnap,\n CronjobSpecification,\n parseCronExpression,\n logError,\n} from '@metamask/snaps-utils';\nimport { Duration, inMilliseconds } from '@metamask/utils';\n\nimport {\n GetAllSnaps,\n getRunnableSnaps,\n HandleSnapRequest,\n SnapEndowments,\n SnapInstalled,\n SnapRemoved,\n SnapUpdated,\n} from '..';\nimport { getCronjobCaveatJobs } from '../snaps/endowments/cronjob';\nimport { Timer } from '../snaps/Timer';\n\nexport type CronjobControllerActions =\n | GetAllSnaps\n | HandleSnapRequest\n | GetPermissions;\n\nexport type CronjobControllerEvents = SnapInstalled | SnapRemoved | SnapUpdated;\n\nexport type CronjobControllerMessenger = RestrictedControllerMessenger<\n 'CronjobController',\n CronjobControllerActions,\n CronjobControllerEvents,\n CronjobControllerActions['type'],\n CronjobControllerEvents['type']\n>;\n\nexport const DAILY_TIMEOUT = inMilliseconds(24, Duration.Hour);\n\nexport type CronjobControllerArgs = {\n messenger: CronjobControllerMessenger;\n /**\n * Persisted state that will be used for rehydration.\n */\n state?: CronjobControllerState;\n};\n\nexport type Cronjob = {\n timer?: Timer;\n id: string;\n snapId: ValidatedSnapId;\n} & CronjobSpecification;\n\nexport type StoredJobInformation = {\n lastRun: number;\n};\n\nexport type CronjobControllerState = {\n jobs: Record<string, StoredJobInformation>;\n};\n\nconst controllerName = 'CronjobController';\n\n/**\n * Use this controller to register and schedule periodically executed jobs\n * using RPC method hooks.\n */\nexport class CronjobController extends BaseController<\n typeof controllerName,\n CronjobControllerState,\n CronjobControllerMessenger\n> {\n #messenger: CronjobControllerMessenger;\n\n #dailyTimer!: Timer;\n\n #timers: Map<string, Timer>;\n\n // Mapping from jobId to snapId\n #snapIds: Map<string, string>;\n\n constructor({ messenger, state }: CronjobControllerArgs) {\n super({\n messenger,\n metadata: {\n jobs: { persist: true, anonymous: false },\n },\n name: controllerName,\n state: {\n jobs: {},\n ...state,\n },\n });\n this.#timers = new Map();\n this.#snapIds = new Map();\n this.#messenger = messenger;\n\n this._handleEventSnapInstalled = this._handleEventSnapInstalled.bind(this);\n this._handleEventSnapRemoved = this._handleEventSnapRemoved.bind(this);\n this._handleEventSnapUpdated = this._handleEventSnapUpdated.bind(this);\n\n // Subscribe to Snap events\n /* eslint-disable @typescript-eslint/unbound-method */\n this.messagingSystem.subscribe(\n 'SnapController:snapInstalled',\n this._handleEventSnapInstalled,\n );\n\n this.messagingSystem.subscribe(\n 'SnapController:snapRemoved',\n this._handleEventSnapRemoved,\n );\n\n this.messagingSystem.subscribe(\n 'SnapController:snapUpdated',\n this._handleEventSnapUpdated,\n );\n /* eslint-enable @typescript-eslint/unbound-method */\n\n this.dailyCheckIn().catch((error) => {\n logError(error);\n });\n }\n\n /**\n * Retrieve all cronjob specifications for all runnable snaps.\n *\n * @returns Array of Cronjob specifications.\n */\n private getAllJobs(): Cronjob[] {\n const snaps = this.messagingSystem.call('SnapController:getAll');\n const filteredSnaps = getRunnableSnaps(snaps);\n\n const jobs = filteredSnaps.map((snap) => this.getSnapJobs(snap.id));\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n return jobs.flat().filter((job) => job !== undefined) as Cronjob[];\n }\n\n /**\n * Retrieve all Cronjob specifications for a Snap.\n *\n * @param snapId - ID of a Snap.\n * @returns Array of Cronjob specifications.\n */\n private getSnapJobs(snapId: ValidatedSnapId): Cronjob[] | undefined {\n const permissions = this.#messenger.call(\n 'PermissionController:getPermissions',\n snapId,\n );\n\n const permission = permissions?.[SnapEndowments.Cronjob];\n const definitions = getCronjobCaveatJobs(permission);\n\n return definitions?.map((definition, idx) => {\n return { ...definition, id: `${snapId}-${idx}`, snapId };\n });\n }\n\n /**\n * Register cron jobs for a given snap by getting specification from a permission caveats.\n * Once registered, each job will be scheduled.\n *\n * @param snapId - ID of a snap.\n */\n register(snapId: ValidatedSnapId) {\n const jobs = this.getSnapJobs(snapId);\n jobs?.forEach((job) => this.schedule(job));\n }\n\n /**\n * Schedule a new job.\n * This will interpret the cron expression and tell the timer to execute the job\n * at the next suitable point in time.\n * Job last run state will be initialized afterwards.\n *\n * Note: Schedule will be skipped if the job's execution time is too far in the future and\n * will be revisited on a daily check.\n *\n * @param job - Cronjob specification.\n */\n private schedule(job: Cronjob) {\n if (this.#timers.has(job.id)) {\n return;\n }\n\n const parsed = parseCronExpression(job.expression);\n const next = parsed.next();\n const now = new Date();\n const ms = next.getTime() - now.getTime();\n\n // Don't schedule this job yet as it is too far in the future\n if (ms > DAILY_TIMEOUT) {\n return;\n }\n\n const timer = new Timer(ms);\n timer.start(() => {\n this.executeCronjob(job).catch((error) => {\n // TODO: Decide how to handle errors.\n logError(error);\n });\n\n this.#timers.delete(job.id);\n this.schedule(job);\n });\n\n this.updateJobLastRunState(job.id, 0); // 0 for init, never ran actually\n this.#timers.set(job.id, timer);\n this.#snapIds.set(job.id, job.snapId);\n }\n\n /**\n * Execute job.\n *\n * @param job - Cronjob specification.\n */\n private async executeCronjob(job: Cronjob) {\n this.updateJobLastRunState(job.id, Date.now());\n await this.#messenger.call('SnapController:handleRequest', {\n snapId: job.snapId,\n origin: '',\n handler: HandlerType.OnCronjob,\n request: job.request,\n });\n }\n\n /**\n * Unregister all jobs related to the given snapId.\n *\n * @param snapId - ID of a snap.\n */\n unregister(snapId: SnapId) {\n const jobs = [...this.#snapIds.entries()].filter(\n ([_, jobSnapId]) => jobSnapId === snapId,\n );\n\n if (jobs.length) {\n jobs.forEach(([id]) => {\n const timer = this.#timers.get(id);\n if (timer) {\n timer.cancel();\n this.#timers.delete(id);\n this.#snapIds.delete(id);\n }\n });\n }\n }\n\n /**\n * Update time of a last run for the Cronjob specified by ID.\n *\n * @param jobId - ID of a cron job.\n * @param lastRun - Unix timestamp when the job was last ran.\n */\n private updateJobLastRunState(jobId: string, lastRun: number) {\n this.update((state) => {\n state.jobs[jobId] = {\n lastRun,\n };\n });\n }\n\n /**\n * Runs every 24 hours to check if new jobs need to be scheduled.\n *\n * This is necesary for longer running jobs that execute with more than 24 hours between them.\n */\n async dailyCheckIn() {\n const jobs = this.getAllJobs();\n\n for (const job of jobs) {\n const parsed = parseCronExpression(job.expression);\n const lastRun = this.state.jobs[job.id]?.lastRun;\n // If a job was supposed to run while we were shut down but wasn't we run it now\n if (\n lastRun !== undefined &&\n parsed.hasPrev() &&\n parsed.prev().getTime() > lastRun\n ) {\n await this.executeCronjob(job);\n }\n\n // Try scheduling, will fail if an existing scheduled job is found\n this.schedule(job);\n }\n\n this.#dailyTimer = new Timer(DAILY_TIMEOUT);\n this.#dailyTimer.start(() => {\n this.dailyCheckIn().catch((error) => {\n // TODO: Decide how to handle errors.\n logError(error);\n });\n });\n }\n\n /**\n * Run controller teardown process and unsubscribe from Snap events.\n */\n destroy() {\n super.destroy();\n\n /* eslint-disable @typescript-eslint/unbound-method */\n this.messagingSystem.unsubscribe(\n 'SnapController:snapInstalled',\n this._handleEventSnapInstalled,\n );\n\n this.messagingSystem.unsubscribe(\n 'SnapController:snapRemoved',\n this._handleEventSnapRemoved,\n );\n\n this.messagingSystem.unsubscribe(\n 'SnapController:snapUpdated',\n this._handleEventSnapUpdated,\n );\n /* eslint-enable @typescript-eslint/unbound-method */\n\n this.#snapIds.forEach((snapId) => {\n this.unregister(snapId);\n });\n }\n\n /**\n * Handle cron jobs on 'snapInstalled' event.\n *\n * @param snap - Basic Snap information.\n */\n private _handleEventSnapInstalled(snap: TruncatedSnap) {\n this.register(snap.id);\n }\n\n /**\n * Handle cron jobs on 'snapRemoved' event.\n *\n * @param snap - Basic Snap information.\n */\n private _handleEventSnapRemoved(snap: TruncatedSnap) {\n this.unregister(snap.id);\n }\n\n /**\n * Handle cron jobs on 'snapUpdated' event.\n *\n * @param snap - Basic Snap information.\n */\n private _handleEventSnapUpdated(snap: TruncatedSnap) {\n this.unregister(snap.id);\n this.register(snap.id);\n }\n}\n"]}
|
|
@@ -189,7 +189,7 @@ class MultiChainController extends base_controller_1.BaseControllerV2 {
|
|
|
189
189
|
(0, utils_1.assert)(permissions !== undefined, `${origin} does not have any permissions.`);
|
|
190
190
|
(0, utils_1.assert)((0, snaps_utils_1.isSnapPermitted)(permissions, snapId), `${origin} does not have permission to communicate with ${snapId}.`);
|
|
191
191
|
return this.snapRequest({
|
|
192
|
-
snapId,
|
|
192
|
+
snapId: snapId,
|
|
193
193
|
origin,
|
|
194
194
|
method: 'handleRequest',
|
|
195
195
|
args: data,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MultiChainController.js","sourceRoot":"","sources":["../../src/multichain/MultiChainController.ts"],"names":[],"mappings":"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","sourcesContent":["import { AddApprovalRequest } from '@metamask/approval-controller';\nimport {\n BaseControllerV2 as BaseController,\n RestrictedControllerMessenger,\n} from '@metamask/base-controller';\nimport {\n GetPermissions,\n GrantPermissions,\n HasPermission,\n PermissionConstraint,\n} from '@metamask/permission-controller';\nimport { WALLET_SNAP_PERMISSION_KEY } from '@metamask/rpc-methods';\nimport {\n SnapKeyring,\n parseAccountId,\n AccountId,\n parseChainId,\n ChainId,\n ConnectArguments,\n isSnapPermitted,\n HandlerType,\n NamespaceId,\n RequestArguments,\n RequestNamespace,\n Session,\n TruncatedSnap,\n SnapId,\n SessionNamespace,\n isAccountIdArray,\n Namespaces,\n logError,\n} from '@metamask/snaps-utils';\nimport { hasProperty, assert } from '@metamask/utils';\nimport { nanoid } from 'nanoid';\n\nimport {\n GetAllSnaps,\n HandleSnapRequest,\n IncrementActiveReferences,\n DecrementActiveReferences,\n SnapEndowments,\n getRunnableSnaps,\n} from '../snaps';\nimport { getKeyringCaveatNamespaces } from '../snaps/endowments/keyring';\nimport { findMatchingKeyringSnaps } from './matching';\n\nconst controllerName = 'MultiChainController';\n\nconst defaultState: MultiChainControllerState = {\n sessions: {},\n};\n\ntype AllowedActions =\n | GetAllSnaps\n | IncrementActiveReferences\n | DecrementActiveReferences\n | HandleSnapRequest\n | GetPermissions\n | HasPermission\n | AddApprovalRequest\n | GrantPermissions;\n\ntype MultiChainControllerMessenger = RestrictedControllerMessenger<\n typeof controllerName,\n AllowedActions,\n never,\n AllowedActions['type'],\n never\n>;\n\ntype SessionData = {\n origin: string;\n requestedNamespaces: Record<NamespaceId, RequestNamespace>;\n providedNamespaces: Record<NamespaceId, RequestNamespace>;\n handlingSnaps: Record<NamespaceId, SnapId>;\n};\n\ntype MultiChainControllerState = {\n sessions: { [origin: string]: SessionData };\n};\n\ntype Notify = (\n origin: string,\n data: { method: string; params?: Record<string, unknown> },\n) => Promise<void>;\n\ntype MultiChainControllerArgs = {\n notify: Notify;\n messenger: MultiChainControllerMessenger;\n};\n\n// TODO(ritave): Support for legacy ethereum operations, not just snaps\nexport class MultiChainController extends BaseController<\n typeof controllerName,\n MultiChainControllerState,\n MultiChainControllerMessenger\n> {\n readonly #notify: Notify;\n\n /**\n * Construct a new {@link MultiChainController} instance.\n *\n * @param args - The arguments to construct the controller with.\n * @param args.messenger - The controller messenger to use.\n * @param args.notify - A function that should handle JSON-RPC notifications.\n */\n constructor({ messenger, notify }: MultiChainControllerArgs) {\n super({\n messenger,\n metadata: {\n sessions: { persist: false, anonymous: false },\n },\n name: controllerName,\n state: defaultState,\n });\n\n this.#notify = notify;\n }\n\n /**\n * Get an open session for the given origin.\n *\n * @param origin - The origin to get the session for.\n * @returns The session, if it exists, or `undefined` otherwise.\n */\n getSession(origin: string): SessionData | undefined {\n return this.state.sessions[origin];\n }\n\n /**\n * Close a session for the given origin.\n *\n * @param origin - The origin to close the session for.\n * @throws If the session does not exist.\n */\n async closeSession(origin: string): Promise<void> {\n const session = this.getSession(origin);\n assert(session, 'No session to close.');\n\n await this.#notify(origin, {\n method: 'multichainHack_metamask_disconnect',\n });\n\n this.update((state) => {\n delete state.sessions[origin];\n });\n\n await Promise.all(\n Object.values(session.handlingSnaps).map((snapId) =>\n this.messagingSystem.call(\n 'SnapController:decrementActiveReferences',\n snapId,\n ),\n ),\n );\n }\n\n /**\n * Handles a new connection from the given origin. This will create a new\n * session, and close any existing session for the origin.\n *\n * @param origin - The origin to create the session for.\n * @param connection - The connection arguments.\n * @param connection.requiredNamespaces - The namespaces that the origin\n * requires.\n * @returns The session that was created.\n */\n async onConnect(\n origin: string,\n connection: ConnectArguments,\n ): Promise<Session> {\n const existingSession = this.getSession(origin);\n if (existingSession) {\n await this.closeSession(origin);\n }\n\n const snaps = this.messagingSystem.call('SnapController:getAll');\n const filteredSnaps = getRunnableSnaps(snaps);\n\n // Get available namespaces supported by currently installed Snaps.\n const availableNamespaces = Object.fromEntries(\n await Promise.all(\n filteredSnaps.map(async (snap) => [\n snap.id,\n await this.snapToNamespaces(snap),\n ]),\n ),\n );\n\n // The magical matching algorithm specified in SIP-2.\n const namespaceToSnaps = findMatchingKeyringSnaps(\n connection.requiredNamespaces,\n availableNamespaces,\n );\n\n const permissions = this.messagingSystem.call(\n 'PermissionController:getPermissions',\n origin,\n );\n\n assert(\n permissions !== undefined,\n `${origin} does not have any permissions.`,\n );\n\n // Find namespaces that can be satisfied with existing approved Snaps.\n const approvedNamespacesAndSnaps = Object.entries(namespaceToSnaps).reduce<\n Record<NamespaceId, SnapId[]>\n >((acc, [namespace, snapIds]) => {\n const approvedSnaps = snapIds.filter((snapId) =>\n isSnapPermitted(permissions, snapId),\n );\n\n if (approvedSnaps.length > 0) {\n acc[namespace] = approvedSnaps;\n }\n return acc;\n }, {});\n\n // If we either don't have a snap to handle a namespace or we have multiple we have conflicts\n const hasConflicts = Object.keys(namespaceToSnaps).some(\n (namespace) =>\n !hasProperty(approvedNamespacesAndSnaps, namespace) ||\n approvedNamespacesAndSnaps[namespace]?.length > 1,\n );\n\n // Use already approved snaps if they satisfy the requested namespaces.\n const filteredNamespacesAndSnaps = hasConflicts\n ? namespaceToSnaps\n : approvedNamespacesAndSnaps;\n\n // Fetch possible accounts from snaps.\n const possibleAccounts = await this.namespacesToAccounts(\n origin,\n filteredNamespacesAndSnaps,\n connection.requiredNamespaces,\n );\n\n // For now we fail here if no namespaces could be matched to a snap.\n // We don't fail if at least one namespace is matched to a snap.\n // TODO: Decide whether this is what we want\n assert(\n Object.values(possibleAccounts).some(\n (possibleAccount) => possibleAccount.length > 0,\n ),\n 'No installed snaps found for any requested namespace.',\n );\n\n // If currently installed Snaps / configuration doesn't solve request, we\n // need to show a prompt. This is handled by `resolveConflicts`.\n const resolvedAccounts = hasConflicts\n ? await this.resolveConflicts(origin, possibleAccounts)\n : Object.fromEntries(\n Object.entries(possibleAccounts).map(\n ([namespace, snapAndAccounts]) => [\n namespace,\n snapAndAccounts[0] ?? null,\n ],\n ),\n );\n\n // Aggregate information about session namespaces.\n const providedNamespaces = Object.entries(\n connection.requiredNamespaces,\n ).reduce<Record<NamespaceId, SessionNamespace>>(\n (acc, [namespaceId, namespace]) => {\n const accounts = resolvedAccounts[namespaceId]?.accounts;\n if (accounts) {\n acc[namespaceId] = {\n accounts,\n chains: namespace.chains,\n events: namespace.events,\n methods: namespace.methods,\n };\n }\n return acc;\n },\n {},\n );\n\n // Collect information about handler Snaps for each namespace.\n const handlingSnaps = Object.entries(resolvedAccounts).reduce<\n Record<NamespaceId, SnapId>\n >((acc, [namespaceId, accountsAndSnap]) => {\n if (accountsAndSnap) {\n acc[namespaceId] = accountsAndSnap.snapId;\n }\n return acc;\n }, {});\n\n const session: SessionData = {\n origin,\n requestedNamespaces: connection.requiredNamespaces,\n providedNamespaces,\n handlingSnaps,\n };\n\n // Makes sure used Snaps aren't killed while they are serving the session.\n await Promise.all(\n Object.values(session.handlingSnaps).map((snapId) =>\n this.messagingSystem.call(\n 'SnapController:incrementActiveReferences',\n snapId,\n ),\n ),\n );\n\n this.update((state) => {\n state.sessions[origin] = session;\n });\n\n return { namespaces: providedNamespaces };\n }\n\n /**\n * Handle an incoming multichain request from the given origin. This will\n * forward the request to the appropriate Snap, and return the response.\n *\n * @param origin - The origin to handle the request for.\n * @param data - The request data.\n * @param data.chainId - The chain ID for the request.\n * @param data.request - The request arguments, i.e., the method and params.\n * @returns The response from the Snap.\n * @throws If the session does not exist, or the session does not provide the\n * requested namespace.\n */\n async onRequest(\n origin: string,\n data: { chainId: ChainId; request: RequestArguments },\n ): Promise<unknown> {\n const session = this.getSession(origin);\n assert(session, `Session for \"${origin}\" doesn't exist.`);\n\n const { namespace } = parseChainId(data.chainId);\n const sessionNamespace = session.providedNamespaces[namespace];\n assert(\n session.providedNamespaces[namespace]?.chains.includes(data.chainId),\n `Session for \"${origin}\" is not connected to \"${data.chainId}\" chain.`,\n );\n\n const { method } = data.request;\n assert(\n sessionNamespace?.methods?.includes(method),\n `Session for \"${origin}\" does not support ${method}`,\n );\n\n const snapId = session.handlingSnaps[namespace];\n assert(snapId !== undefined);\n\n // TODO: Get permission for origin connecting to snap, or get user approval.\n // In the future this is where we should prompt for this permission.\n // In this iteration, we will grant this permission in `onConnect`.\n const permissions = this.messagingSystem.call(\n 'PermissionController:getPermissions',\n origin,\n );\n\n assert(\n permissions !== undefined,\n `${origin} does not have any permissions.`,\n );\n\n assert(\n isSnapPermitted(permissions, snapId),\n `${origin} does not have permission to communicate with ${snapId}.`,\n );\n\n return this.snapRequest({\n snapId,\n origin,\n method: 'handleRequest',\n args: data,\n });\n }\n\n /**\n * Send a request to the given Snap. This calls the given method with the\n * given arguments on the keyring class in the given Snap.\n *\n * @param options - The request options.\n * @param options.snapId - The ID of the Snap to send the request to.\n * @param options.origin - The origin of the request.\n * @param options.method - The request method.\n * @param options.args - The request params.\n * @returns The response from the Snap.\n */\n private async snapRequest({\n snapId,\n origin,\n method,\n args,\n }: {\n snapId: SnapId;\n origin: string;\n method: keyof SnapKeyring;\n args?: unknown;\n }) {\n return this.messagingSystem.call('SnapController:handleRequest', {\n snapId,\n origin,\n handler: HandlerType.SnapKeyring,\n request: { method, params: args ? [args] : [] },\n });\n }\n\n /**\n * Get the accounts exposed by the Snap's keyring.\n *\n * This also verifies that the accounts returned by the snap are valid CAIP-10\n * account IDs.\n *\n * @param origin - The origin of the request.\n * @param snapId - The ID of the Snap to get the accounts from.\n * @returns The accounts, or `null` if the Snap does not have any accounts, or\n * the accounts are invalid (i.e., not valid CAIP-10 account IDs).\n */\n private async getSnapAccounts(\n origin: string,\n snapId: SnapId,\n ): Promise<AccountId[] | null> {\n try {\n const result = await this.snapRequest({\n snapId,\n origin,\n method: 'getAccounts',\n });\n\n if (isAccountIdArray(result)) {\n return result;\n }\n } catch (error) {\n // Ignore errors for now\n logError(error);\n }\n\n return null;\n }\n\n /**\n * Get the namespaces for the given Snap, as described in the Snap's manifest.\n *\n * @param snap - The Snap to get the namespaces for.\n * @returns The namespaces, or `null` if the Snap does not have any\n * namespaces.\n */\n private snapToNamespaces(snap: TruncatedSnap): Namespaces | null {\n const permissions = this.messagingSystem.call(\n 'PermissionController:getPermissions',\n snap.id,\n );\n\n const keyringPermission = permissions?.[SnapEndowments.Keyring];\n return getKeyringCaveatNamespaces(keyringPermission);\n }\n\n /**\n * Maps from an object of namespace IDs and Snap IDs, and an object of\n * namespace IDs and requested namespaces, to an object of namespace IDs and\n * resolved accounts, with the Snap ID providing the accounts.\n *\n * @param origin - The origin of the request.\n * @param namespacesAndSnaps - An object of namespace IDs and Snap IDs\n * providing the namespace.\n * @param requestedNamespaces - An object of namespace IDs and requested\n * namespaces.\n * @returns An object of namespace IDs and resolved accounts, with the Snap ID\n * providing the accounts.\n */\n private async namespacesToAccounts(\n origin: string,\n namespacesAndSnaps: Record<NamespaceId, SnapId[]>,\n requestedNamespaces: Record<NamespaceId, RequestNamespace>,\n ): Promise<Record<NamespaceId, { snapId: SnapId; accounts: AccountId[] }[]>> {\n const dedupedSnaps = [\n ...new Set(Object.values(namespacesAndSnaps).flat()),\n ] as SnapId[];\n\n const allAccounts = await dedupedSnaps.reduce<\n Promise<Record<string, AccountId[]>>\n >(async (previousPromise, snapId) => {\n const result = await this.getSnapAccounts(origin, snapId);\n const acc = await previousPromise;\n if (result) {\n acc[snapId] = result;\n }\n return acc;\n }, Promise.resolve({}));\n\n return Object.keys(namespacesAndSnaps).reduce<\n Record<NamespaceId, { snapId: SnapId; accounts: AccountId[] }[]>\n >((acc, namespaceId) => {\n const { chains } = requestedNamespaces[namespaceId];\n\n const accountInAnyRequestedChain = (account: AccountId) => {\n const { chainId: parsedChainId } = parseAccountId(account);\n return chains.some((chainId) => chainId === parsedChainId);\n };\n\n const result = Object.entries(allAccounts)\n .map(([snapId, accounts]) => ({\n snapId,\n accounts: accounts.filter(accountInAnyRequestedChain),\n }))\n .filter(({ accounts }) => accounts.length > 0);\n\n acc[namespaceId] = result;\n\n return acc;\n }, {});\n }\n\n /**\n * If multiple Snap IDs are provided for a namespace, this method will\n * determine which Snap ID to use for the namespace, by showing the user a\n * prompt.\n *\n * @param origin - The origin of the request.\n * @param possibleAccounts - An object containing the accounts provided by\n * each Snap ID for each namespace.\n * @returns An object containing the Snap ID to use for each namespace.\n */\n private async resolveConflicts(\n origin: string,\n possibleAccounts: Record<\n NamespaceId,\n { snapId: SnapId; accounts: AccountId[] }[]\n >,\n ): Promise<\n Record<NamespaceId, { snapId: SnapId; accounts: AccountId[] } | null>\n > {\n // Get user approval for connection.\n const id = nanoid();\n const resolvedAccounts = (await this.messagingSystem.call(\n 'ApprovalController:addRequest',\n {\n origin,\n id,\n type: 'multichain_connect',\n requestData: {\n possibleAccounts,\n },\n },\n true,\n )) as Record<NamespaceId, { snapId: SnapId; accounts: AccountId[] } | null>;\n\n // TODO: In the future, use another permission here to not give full\n // permission after handshake.\n // Instead we should give origin only a read-only access to list of accounts\n // without allowing provider.request() talking to a snap before additional\n // user approval. The additional approval would be requested in `onRequest`.\n\n const approvedPermissions = Object.values(resolvedAccounts).reduce<\n Record<string, Record<string, Partial<PermissionConstraint>>>\n >(\n (acc, curr) => {\n if (curr !== null) {\n acc[WALLET_SNAP_PERMISSION_KEY][curr.snapId] = {};\n }\n return acc;\n },\n { [WALLET_SNAP_PERMISSION_KEY]: {} },\n );\n\n this.messagingSystem.call('PermissionController:grantPermissions', {\n approvedPermissions,\n subject: { origin },\n });\n\n return resolvedAccounts;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"MultiChainController.js","sourceRoot":"","sources":["../../src/multichain/MultiChainController.ts"],"names":[],"mappings":"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","sourcesContent":["import { AddApprovalRequest } from '@metamask/approval-controller';\nimport {\n BaseControllerV2 as BaseController,\n RestrictedControllerMessenger,\n} from '@metamask/base-controller';\nimport {\n GetPermissions,\n GrantPermissions,\n HasPermission,\n PermissionConstraint,\n} from '@metamask/permission-controller';\nimport { WALLET_SNAP_PERMISSION_KEY } from '@metamask/rpc-methods';\nimport {\n SnapKeyring,\n parseAccountId,\n AccountId,\n parseChainId,\n ChainId,\n ConnectArguments,\n isSnapPermitted,\n HandlerType,\n NamespaceId,\n RequestArguments,\n RequestNamespace,\n Session,\n TruncatedSnap,\n SnapId,\n SessionNamespace,\n isAccountIdArray,\n Namespaces,\n logError,\n ValidatedSnapId,\n} from '@metamask/snaps-utils';\nimport { hasProperty, assert } from '@metamask/utils';\nimport { nanoid } from 'nanoid';\n\nimport {\n GetAllSnaps,\n HandleSnapRequest,\n IncrementActiveReferences,\n DecrementActiveReferences,\n SnapEndowments,\n getRunnableSnaps,\n} from '../snaps';\nimport { getKeyringCaveatNamespaces } from '../snaps/endowments/keyring';\nimport { findMatchingKeyringSnaps } from './matching';\n\nconst controllerName = 'MultiChainController';\n\nconst defaultState: MultiChainControllerState = {\n sessions: {},\n};\n\ntype AllowedActions =\n | GetAllSnaps\n | IncrementActiveReferences\n | DecrementActiveReferences\n | HandleSnapRequest\n | GetPermissions\n | HasPermission\n | AddApprovalRequest\n | GrantPermissions;\n\ntype MultiChainControllerMessenger = RestrictedControllerMessenger<\n typeof controllerName,\n AllowedActions,\n never,\n AllowedActions['type'],\n never\n>;\n\ntype SessionData = {\n origin: string;\n requestedNamespaces: Record<NamespaceId, RequestNamespace>;\n providedNamespaces: Record<NamespaceId, RequestNamespace>;\n handlingSnaps: Record<NamespaceId, SnapId>;\n};\n\ntype MultiChainControllerState = {\n sessions: { [origin: string]: SessionData };\n};\n\ntype Notify = (\n origin: string,\n data: { method: string; params?: Record<string, unknown> },\n) => Promise<void>;\n\ntype MultiChainControllerArgs = {\n notify: Notify;\n messenger: MultiChainControllerMessenger;\n};\n\n// TODO(ritave): Support for legacy ethereum operations, not just snaps\nexport class MultiChainController extends BaseController<\n typeof controllerName,\n MultiChainControllerState,\n MultiChainControllerMessenger\n> {\n readonly #notify: Notify;\n\n /**\n * Construct a new {@link MultiChainController} instance.\n *\n * @param args - The arguments to construct the controller with.\n * @param args.messenger - The controller messenger to use.\n * @param args.notify - A function that should handle JSON-RPC notifications.\n */\n constructor({ messenger, notify }: MultiChainControllerArgs) {\n super({\n messenger,\n metadata: {\n sessions: { persist: false, anonymous: false },\n },\n name: controllerName,\n state: defaultState,\n });\n\n this.#notify = notify;\n }\n\n /**\n * Get an open session for the given origin.\n *\n * @param origin - The origin to get the session for.\n * @returns The session, if it exists, or `undefined` otherwise.\n */\n getSession(origin: string): SessionData | undefined {\n return this.state.sessions[origin];\n }\n\n /**\n * Close a session for the given origin.\n *\n * @param origin - The origin to close the session for.\n * @throws If the session does not exist.\n */\n async closeSession(origin: string): Promise<void> {\n const session = this.getSession(origin);\n assert(session, 'No session to close.');\n\n await this.#notify(origin, {\n method: 'multichainHack_metamask_disconnect',\n });\n\n this.update((state) => {\n delete state.sessions[origin];\n });\n\n await Promise.all(\n Object.values(session.handlingSnaps).map((snapId) =>\n this.messagingSystem.call(\n 'SnapController:decrementActiveReferences',\n snapId as ValidatedSnapId,\n ),\n ),\n );\n }\n\n /**\n * Handles a new connection from the given origin. This will create a new\n * session, and close any existing session for the origin.\n *\n * @param origin - The origin to create the session for.\n * @param connection - The connection arguments.\n * @param connection.requiredNamespaces - The namespaces that the origin\n * requires.\n * @returns The session that was created.\n */\n async onConnect(\n origin: string,\n connection: ConnectArguments,\n ): Promise<Session> {\n const existingSession = this.getSession(origin);\n if (existingSession) {\n await this.closeSession(origin);\n }\n\n const snaps = this.messagingSystem.call('SnapController:getAll');\n const filteredSnaps = getRunnableSnaps(snaps);\n\n // Get available namespaces supported by currently installed Snaps.\n const availableNamespaces = Object.fromEntries(\n await Promise.all(\n filteredSnaps.map(async (snap) => [\n snap.id,\n await this.snapToNamespaces(snap),\n ]),\n ),\n );\n\n // The magical matching algorithm specified in SIP-2.\n const namespaceToSnaps = findMatchingKeyringSnaps(\n connection.requiredNamespaces,\n availableNamespaces,\n );\n\n const permissions = this.messagingSystem.call(\n 'PermissionController:getPermissions',\n origin,\n );\n\n assert(\n permissions !== undefined,\n `${origin} does not have any permissions.`,\n );\n\n // Find namespaces that can be satisfied with existing approved Snaps.\n const approvedNamespacesAndSnaps = Object.entries(namespaceToSnaps).reduce<\n Record<NamespaceId, SnapId[]>\n >((acc, [namespace, snapIds]) => {\n const approvedSnaps = snapIds.filter((snapId) =>\n isSnapPermitted(permissions, snapId),\n );\n\n if (approvedSnaps.length > 0) {\n acc[namespace] = approvedSnaps;\n }\n return acc;\n }, {});\n\n // If we either don't have a snap to handle a namespace or we have multiple we have conflicts\n const hasConflicts = Object.keys(namespaceToSnaps).some(\n (namespace) =>\n !hasProperty(approvedNamespacesAndSnaps, namespace) ||\n approvedNamespacesAndSnaps[namespace]?.length > 1,\n );\n\n // Use already approved snaps if they satisfy the requested namespaces.\n const filteredNamespacesAndSnaps = hasConflicts\n ? namespaceToSnaps\n : approvedNamespacesAndSnaps;\n\n // Fetch possible accounts from snaps.\n const possibleAccounts = await this.namespacesToAccounts(\n origin,\n filteredNamespacesAndSnaps,\n connection.requiredNamespaces,\n );\n\n // For now we fail here if no namespaces could be matched to a snap.\n // We don't fail if at least one namespace is matched to a snap.\n // TODO: Decide whether this is what we want\n assert(\n Object.values(possibleAccounts).some(\n (possibleAccount) => possibleAccount.length > 0,\n ),\n 'No installed snaps found for any requested namespace.',\n );\n\n // If currently installed Snaps / configuration doesn't solve request, we\n // need to show a prompt. This is handled by `resolveConflicts`.\n const resolvedAccounts = hasConflicts\n ? await this.resolveConflicts(origin, possibleAccounts)\n : Object.fromEntries(\n Object.entries(possibleAccounts).map(\n ([namespace, snapAndAccounts]) => [\n namespace,\n snapAndAccounts[0] ?? null,\n ],\n ),\n );\n\n // Aggregate information about session namespaces.\n const providedNamespaces = Object.entries(\n connection.requiredNamespaces,\n ).reduce<Record<NamespaceId, SessionNamespace>>(\n (acc, [namespaceId, namespace]) => {\n const accounts = resolvedAccounts[namespaceId]?.accounts;\n if (accounts) {\n acc[namespaceId] = {\n accounts,\n chains: namespace.chains,\n events: namespace.events,\n methods: namespace.methods,\n };\n }\n return acc;\n },\n {},\n );\n\n // Collect information about handler Snaps for each namespace.\n const handlingSnaps = Object.entries(resolvedAccounts).reduce<\n Record<NamespaceId, SnapId>\n >((acc, [namespaceId, accountsAndSnap]) => {\n if (accountsAndSnap) {\n acc[namespaceId] = accountsAndSnap.snapId;\n }\n return acc;\n }, {});\n\n const session: SessionData = {\n origin,\n requestedNamespaces: connection.requiredNamespaces,\n providedNamespaces,\n handlingSnaps,\n };\n\n // Makes sure used Snaps aren't killed while they are serving the session.\n await Promise.all(\n Object.values(session.handlingSnaps).map((snapId) =>\n this.messagingSystem.call(\n 'SnapController:incrementActiveReferences',\n snapId as ValidatedSnapId,\n ),\n ),\n );\n\n this.update((state) => {\n state.sessions[origin] = session;\n });\n\n return { namespaces: providedNamespaces };\n }\n\n /**\n * Handle an incoming multichain request from the given origin. This will\n * forward the request to the appropriate Snap, and return the response.\n *\n * @param origin - The origin to handle the request for.\n * @param data - The request data.\n * @param data.chainId - The chain ID for the request.\n * @param data.request - The request arguments, i.e., the method and params.\n * @returns The response from the Snap.\n * @throws If the session does not exist, or the session does not provide the\n * requested namespace.\n */\n async onRequest(\n origin: string,\n data: { chainId: ChainId; request: RequestArguments },\n ): Promise<unknown> {\n const session = this.getSession(origin);\n assert(session, `Session for \"${origin}\" doesn't exist.`);\n\n const { namespace } = parseChainId(data.chainId);\n const sessionNamespace = session.providedNamespaces[namespace];\n assert(\n session.providedNamespaces[namespace]?.chains.includes(data.chainId),\n `Session for \"${origin}\" is not connected to \"${data.chainId}\" chain.`,\n );\n\n const { method } = data.request;\n assert(\n sessionNamespace?.methods?.includes(method),\n `Session for \"${origin}\" does not support ${method}`,\n );\n\n const snapId = session.handlingSnaps[namespace];\n assert(snapId !== undefined);\n\n // TODO: Get permission for origin connecting to snap, or get user approval.\n // In the future this is where we should prompt for this permission.\n // In this iteration, we will grant this permission in `onConnect`.\n const permissions = this.messagingSystem.call(\n 'PermissionController:getPermissions',\n origin,\n );\n\n assert(\n permissions !== undefined,\n `${origin} does not have any permissions.`,\n );\n\n assert(\n isSnapPermitted(permissions, snapId),\n `${origin} does not have permission to communicate with ${snapId}.`,\n );\n\n return this.snapRequest({\n snapId: snapId as ValidatedSnapId,\n origin,\n method: 'handleRequest',\n args: data,\n });\n }\n\n /**\n * Send a request to the given Snap. This calls the given method with the\n * given arguments on the keyring class in the given Snap.\n *\n * @param options - The request options.\n * @param options.snapId - The ID of the Snap to send the request to.\n * @param options.origin - The origin of the request.\n * @param options.method - The request method.\n * @param options.args - The request params.\n * @returns The response from the Snap.\n */\n private async snapRequest({\n snapId,\n origin,\n method,\n args,\n }: {\n snapId: ValidatedSnapId;\n origin: string;\n method: keyof SnapKeyring;\n args?: unknown;\n }) {\n return this.messagingSystem.call('SnapController:handleRequest', {\n snapId,\n origin,\n handler: HandlerType.SnapKeyring,\n request: { method, params: args ? [args] : [] },\n });\n }\n\n /**\n * Get the accounts exposed by the Snap's keyring.\n *\n * This also verifies that the accounts returned by the snap are valid CAIP-10\n * account IDs.\n *\n * @param origin - The origin of the request.\n * @param snapId - The ID of the Snap to get the accounts from.\n * @returns The accounts, or `null` if the Snap does not have any accounts, or\n * the accounts are invalid (i.e., not valid CAIP-10 account IDs).\n */\n private async getSnapAccounts(\n origin: string,\n snapId: ValidatedSnapId,\n ): Promise<AccountId[] | null> {\n try {\n const result = await this.snapRequest({\n snapId,\n origin,\n method: 'getAccounts',\n });\n\n if (isAccountIdArray(result)) {\n return result;\n }\n } catch (error) {\n // Ignore errors for now\n logError(error);\n }\n\n return null;\n }\n\n /**\n * Get the namespaces for the given Snap, as described in the Snap's manifest.\n *\n * @param snap - The Snap to get the namespaces for.\n * @returns The namespaces, or `null` if the Snap does not have any\n * namespaces.\n */\n private snapToNamespaces(snap: TruncatedSnap): Namespaces | null {\n const permissions = this.messagingSystem.call(\n 'PermissionController:getPermissions',\n snap.id,\n );\n\n const keyringPermission = permissions?.[SnapEndowments.Keyring];\n return getKeyringCaveatNamespaces(keyringPermission);\n }\n\n /**\n * Maps from an object of namespace IDs and Snap IDs, and an object of\n * namespace IDs and requested namespaces, to an object of namespace IDs and\n * resolved accounts, with the Snap ID providing the accounts.\n *\n * @param origin - The origin of the request.\n * @param namespacesAndSnaps - An object of namespace IDs and Snap IDs\n * providing the namespace.\n * @param requestedNamespaces - An object of namespace IDs and requested\n * namespaces.\n * @returns An object of namespace IDs and resolved accounts, with the Snap ID\n * providing the accounts.\n */\n private async namespacesToAccounts(\n origin: string,\n namespacesAndSnaps: Record<NamespaceId, SnapId[]>,\n requestedNamespaces: Record<NamespaceId, RequestNamespace>,\n ): Promise<Record<NamespaceId, { snapId: SnapId; accounts: AccountId[] }[]>> {\n const dedupedSnaps = [\n ...new Set(Object.values(namespacesAndSnaps).flat()),\n ] as ValidatedSnapId[];\n\n const allAccounts = await dedupedSnaps.reduce<\n Promise<Record<string, AccountId[]>>\n >(async (previousPromise, snapId) => {\n const result = await this.getSnapAccounts(origin, snapId);\n const acc = await previousPromise;\n if (result) {\n acc[snapId] = result;\n }\n return acc;\n }, Promise.resolve({}));\n\n return Object.keys(namespacesAndSnaps).reduce<\n Record<NamespaceId, { snapId: SnapId; accounts: AccountId[] }[]>\n >((acc, namespaceId) => {\n const { chains } = requestedNamespaces[namespaceId];\n\n const accountInAnyRequestedChain = (account: AccountId) => {\n const { chainId: parsedChainId } = parseAccountId(account);\n return chains.some((chainId) => chainId === parsedChainId);\n };\n\n const result = Object.entries(allAccounts)\n .map(([snapId, accounts]) => ({\n snapId,\n accounts: accounts.filter(accountInAnyRequestedChain),\n }))\n .filter(({ accounts }) => accounts.length > 0);\n\n acc[namespaceId] = result;\n\n return acc;\n }, {});\n }\n\n /**\n * If multiple Snap IDs are provided for a namespace, this method will\n * determine which Snap ID to use for the namespace, by showing the user a\n * prompt.\n *\n * @param origin - The origin of the request.\n * @param possibleAccounts - An object containing the accounts provided by\n * each Snap ID for each namespace.\n * @returns An object containing the Snap ID to use for each namespace.\n */\n private async resolveConflicts(\n origin: string,\n possibleAccounts: Record<\n NamespaceId,\n { snapId: SnapId; accounts: AccountId[] }[]\n >,\n ): Promise<\n Record<NamespaceId, { snapId: SnapId; accounts: AccountId[] } | null>\n > {\n // Get user approval for connection.\n const id = nanoid();\n const resolvedAccounts = (await this.messagingSystem.call(\n 'ApprovalController:addRequest',\n {\n origin,\n id,\n type: 'multichain_connect',\n requestData: {\n possibleAccounts,\n },\n },\n true,\n )) as Record<NamespaceId, { snapId: SnapId; accounts: AccountId[] } | null>;\n\n // TODO: In the future, use another permission here to not give full\n // permission after handshake.\n // Instead we should give origin only a read-only access to list of accounts\n // without allowing provider.request() talking to a snap before additional\n // user approval. The additional approval would be requested in `onRequest`.\n\n const approvedPermissions = Object.values(resolvedAccounts).reduce<\n Record<string, Record<string, Partial<PermissionConstraint>>>\n >(\n (acc, curr) => {\n if (curr !== null) {\n acc[WALLET_SNAP_PERMISSION_KEY][curr.snapId] = {};\n }\n return acc;\n },\n { [WALLET_SNAP_PERMISSION_KEY]: {} },\n );\n\n this.messagingSystem.call('PermissionController:grantPermissions', {\n approvedPermissions,\n subject: { origin },\n });\n\n return resolvedAccounts;\n }\n}\n"]}
|
|
@@ -71,7 +71,7 @@ export declare type SnapError = {
|
|
|
71
71
|
data?: Json;
|
|
72
72
|
};
|
|
73
73
|
declare type CloseAllConnectionsFunction = (origin: string) => void;
|
|
74
|
-
declare type StoredSnaps = Record<
|
|
74
|
+
declare type StoredSnaps = Record<ValidatedSnapId, Snap>;
|
|
75
75
|
export declare type SnapControllerState = {
|
|
76
76
|
snaps: StoredSnaps;
|
|
77
77
|
snapStates: {};
|
|
@@ -82,8 +82,8 @@ export declare type SnapControllerState = {
|
|
|
82
82
|
};
|
|
83
83
|
};
|
|
84
84
|
export declare type PersistedSnapControllerState = SnapControllerState & {
|
|
85
|
-
snaps: Record<
|
|
86
|
-
snapStates: Record<
|
|
85
|
+
snaps: Record<ValidatedSnapId, PersistedSnap>;
|
|
86
|
+
snapStates: Record<ValidatedSnapId, string>;
|
|
87
87
|
};
|
|
88
88
|
/**
|
|
89
89
|
* Gets the specified Snap from state.
|
|
@@ -334,21 +334,21 @@ export declare class SnapController extends BaseController<string, SnapControlle
|
|
|
334
334
|
*
|
|
335
335
|
* @param snapId - The id of the Snap to start.
|
|
336
336
|
*/
|
|
337
|
-
startSnap(snapId:
|
|
337
|
+
startSnap(snapId: ValidatedSnapId): Promise<void>;
|
|
338
338
|
/**
|
|
339
339
|
* Enables the given snap. A snap can only be started if it is enabled. A snap
|
|
340
340
|
* can only be enabled if it isn't blocked.
|
|
341
341
|
*
|
|
342
342
|
* @param snapId - The id of the Snap to enable.
|
|
343
343
|
*/
|
|
344
|
-
enableSnap(snapId:
|
|
344
|
+
enableSnap(snapId: ValidatedSnapId): void;
|
|
345
345
|
/**
|
|
346
346
|
* Disables the given snap. A snap can only be started if it is enabled.
|
|
347
347
|
*
|
|
348
348
|
* @param snapId - The id of the Snap to disable.
|
|
349
349
|
* @returns A promise that resolves once the snap has been disabled.
|
|
350
350
|
*/
|
|
351
|
-
disableSnap(snapId:
|
|
351
|
+
disableSnap(snapId: ValidatedSnapId): Promise<void>;
|
|
352
352
|
/**
|
|
353
353
|
* Stops the given snap, removes all hooks, closes all connections, and
|
|
354
354
|
* terminates its worker.
|
|
@@ -357,7 +357,7 @@ export declare class SnapController extends BaseController<string, SnapControlle
|
|
|
357
357
|
* @param statusEvent - The Snap status event that caused the snap to be
|
|
358
358
|
* stopped.
|
|
359
359
|
*/
|
|
360
|
-
stopSnap(snapId:
|
|
360
|
+
stopSnap(snapId: ValidatedSnapId, statusEvent?: SnapStatusEvents.Stop | SnapStatusEvents.Crash): Promise<void>;
|
|
361
361
|
/**
|
|
362
362
|
* Returns whether the given snap is running.
|
|
363
363
|
* Throws an error if the snap doesn't exist.
|
|
@@ -365,14 +365,14 @@ export declare class SnapController extends BaseController<string, SnapControlle
|
|
|
365
365
|
* @param snapId - The id of the Snap to check.
|
|
366
366
|
* @returns `true` if the snap is running, otherwise `false`.
|
|
367
367
|
*/
|
|
368
|
-
isRunning(snapId:
|
|
368
|
+
isRunning(snapId: ValidatedSnapId): boolean;
|
|
369
369
|
/**
|
|
370
370
|
* Returns whether the given snap has been added to state.
|
|
371
371
|
*
|
|
372
372
|
* @param snapId - The id of the Snap to check for.
|
|
373
373
|
* @returns `true` if the snap exists in the controller state, otherwise `false`.
|
|
374
374
|
*/
|
|
375
|
-
has(snapId:
|
|
375
|
+
has(snapId: ValidatedSnapId): boolean;
|
|
376
376
|
/**
|
|
377
377
|
* Gets the snap with the given id if it exists, including all data.
|
|
378
378
|
* This should not be used if the snap is to be serializable, as e.g.
|
|
@@ -392,7 +392,7 @@ export declare class SnapController extends BaseController<string, SnapControlle
|
|
|
392
392
|
* @param snapId - The id of the snap to get.
|
|
393
393
|
* @returns The entire snap object.
|
|
394
394
|
*/
|
|
395
|
-
getExpect(snapId:
|
|
395
|
+
getExpect(snapId: ValidatedSnapId): Snap;
|
|
396
396
|
/**
|
|
397
397
|
* Gets the snap with the given id if it exists, excluding any
|
|
398
398
|
* non-serializable or expensive-to-serialize data.
|
|
@@ -400,7 +400,7 @@ export declare class SnapController extends BaseController<string, SnapControlle
|
|
|
400
400
|
* @param snapId - The id of the Snap to get.
|
|
401
401
|
* @returns A truncated version of the snap state, that is less expensive to serialize.
|
|
402
402
|
*/
|
|
403
|
-
getTruncated(snapId:
|
|
403
|
+
getTruncated(snapId: ValidatedSnapId): TruncatedSnap | null;
|
|
404
404
|
/**
|
|
405
405
|
* Gets the snap with the given id, throw if it doesn't exist.
|
|
406
406
|
*
|
|
@@ -408,7 +408,7 @@ export declare class SnapController extends BaseController<string, SnapControlle
|
|
|
408
408
|
* @param snapId - The id of the snap to get.
|
|
409
409
|
* @returns A truncated version of the snap state, that is less expensive to serialize.
|
|
410
410
|
*/
|
|
411
|
-
getTruncatedExpect(snapId:
|
|
411
|
+
getTruncatedExpect(snapId: ValidatedSnapId): TruncatedSnap;
|
|
412
412
|
/**
|
|
413
413
|
* Updates the own state of the snap with the given id.
|
|
414
414
|
* This is distinct from the state MetaMask uses to manage snaps.
|
|
@@ -416,14 +416,14 @@ export declare class SnapController extends BaseController<string, SnapControlle
|
|
|
416
416
|
* @param snapId - The id of the Snap whose state should be updated.
|
|
417
417
|
* @param newSnapState - The new state of the snap.
|
|
418
418
|
*/
|
|
419
|
-
updateSnapState(snapId:
|
|
419
|
+
updateSnapState(snapId: ValidatedSnapId, newSnapState: string): Promise<void>;
|
|
420
420
|
/**
|
|
421
421
|
* Clears the state of the snap with the given id.
|
|
422
422
|
* This is distinct from the state MetaMask uses to manage snaps.
|
|
423
423
|
*
|
|
424
424
|
* @param snapId - The id of the Snap whose state should be cleared.
|
|
425
425
|
*/
|
|
426
|
-
clearSnapState(snapId:
|
|
426
|
+
clearSnapState(snapId: ValidatedSnapId): void;
|
|
427
427
|
/**
|
|
428
428
|
* Adds error from a snap to the SnapController state.
|
|
429
429
|
*
|
|
@@ -448,7 +448,7 @@ export declare class SnapController extends BaseController<string, SnapControlle
|
|
|
448
448
|
* @returns A promise that resolves with the decrypted snap state or null if no state exists.
|
|
449
449
|
* @throws If the snap state decryption fails.
|
|
450
450
|
*/
|
|
451
|
-
getSnapState(snapId:
|
|
451
|
+
getSnapState(snapId: ValidatedSnapId): Promise<Json>;
|
|
452
452
|
/**
|
|
453
453
|
* Completely clear the controller's state: delete all associated data,
|
|
454
454
|
* handlers, event listeners, and permissions; tear down all snap providers.
|
|
@@ -461,21 +461,21 @@ export declare class SnapController extends BaseController<string, SnapControlle
|
|
|
461
461
|
* @param snapId - The id of the Snap.
|
|
462
462
|
* @returns A promise that resolves once the snap has been removed.
|
|
463
463
|
*/
|
|
464
|
-
removeSnap(snapId:
|
|
464
|
+
removeSnap(snapId: ValidatedSnapId): Promise<void>;
|
|
465
465
|
/**
|
|
466
466
|
* Stops the given snaps, removes them from state, and clears all associated
|
|
467
467
|
* permissions, handlers, and listeners.
|
|
468
468
|
*
|
|
469
469
|
* @param snapIds - The ids of the Snaps.
|
|
470
470
|
*/
|
|
471
|
-
removeSnaps(snapIds:
|
|
471
|
+
removeSnaps(snapIds: ValidatedSnapId[]): Promise<void>;
|
|
472
472
|
/**
|
|
473
473
|
* Removes a snap's permission (caveat) from the specified subject.
|
|
474
474
|
*
|
|
475
475
|
* @param origin - The origin from which to remove the snap.
|
|
476
476
|
* @param snapId - The id of the snap to remove.
|
|
477
477
|
*/
|
|
478
|
-
removeSnapFromSubject(origin: string, snapId:
|
|
478
|
+
removeSnapFromSubject(origin: string, snapId: ValidatedSnapId): void;
|
|
479
479
|
/**
|
|
480
480
|
* Safely revokes all permissions granted to a Snap.
|
|
481
481
|
*
|
|
@@ -487,13 +487,13 @@ export declare class SnapController extends BaseController<string, SnapControlle
|
|
|
487
487
|
*
|
|
488
488
|
* @param snapId - The snap id of the snap that was referenced.
|
|
489
489
|
*/
|
|
490
|
-
incrementActiveReferences(snapId:
|
|
490
|
+
incrementActiveReferences(snapId: ValidatedSnapId): void;
|
|
491
491
|
/**
|
|
492
492
|
* Handles decrement the activeReferences counter.
|
|
493
493
|
*
|
|
494
494
|
* @param snapId - The snap id of the snap that was referenced..
|
|
495
495
|
*/
|
|
496
|
-
decrementActiveReferences(snapId:
|
|
496
|
+
decrementActiveReferences(snapId: ValidatedSnapId): void;
|
|
497
497
|
/**
|
|
498
498
|
* Gets all snaps in their truncated format.
|
|
499
499
|
*
|
|
@@ -555,7 +555,7 @@ export declare class SnapController extends BaseController<string, SnapControlle
|
|
|
555
555
|
* @returns The metadata for the given snap ID, or `null` if the snap is not
|
|
556
556
|
* verified.
|
|
557
557
|
*/
|
|
558
|
-
getRegistryMetadata(snapId:
|
|
558
|
+
getRegistryMetadata(snapId: ValidatedSnapId): Promise<SnapsRegistryMetadata | null>;
|
|
559
559
|
/**
|
|
560
560
|
* Initiates a request for the given snap's initial permissions.
|
|
561
561
|
* Must be called in order. See processRequestedSnap.
|
|
@@ -579,7 +579,7 @@ export declare class SnapController extends BaseController<string, SnapControlle
|
|
|
579
579
|
* @returns The result of the JSON-RPC request.
|
|
580
580
|
*/
|
|
581
581
|
handleRequest({ snapId, origin, handler: handlerType, request, }: SnapRpcHookArgs & {
|
|
582
|
-
snapId:
|
|
582
|
+
snapId: ValidatedSnapId;
|
|
583
583
|
}): Promise<unknown>;
|
|
584
584
|
}
|
|
585
585
|
export {};
|