@metamask-previews/sample-controllers 4.0.4-preview-bfb4d9f5a → 4.0.4-preview-1d148d2
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 +26 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/sample-gas-prices-service/sample-gas-prices-service.cjs +50 -111
- package/dist/sample-gas-prices-service/sample-gas-prices-service.cjs.map +1 -1
- package/dist/sample-gas-prices-service/sample-gas-prices-service.d.cts +47 -64
- package/dist/sample-gas-prices-service/sample-gas-prices-service.d.cts.map +1 -1
- package/dist/sample-gas-prices-service/sample-gas-prices-service.d.mts +47 -64
- package/dist/sample-gas-prices-service/sample-gas-prices-service.d.mts.map +1 -1
- package/dist/sample-gas-prices-service/sample-gas-prices-service.mjs +51 -112
- package/dist/sample-gas-prices-service/sample-gas-prices-service.mjs.map +1 -1
- package/package.json +6 -3
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,32 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- Add actions and events for accessing and interacting with the new query cache for `SampleGasPricesService` ([#8343](https://github.com/MetaMask/core/pull/8343))
|
|
13
|
+
- New actions and events are:
|
|
14
|
+
- `SampleGasPricesServiceInvalidateQueriesAction`
|
|
15
|
+
- `SampleGasPricesServiceCacheUpdatedEvent`
|
|
16
|
+
- `SampleGasPricesServiceGranularCacheUpdatedEvent`
|
|
17
|
+
- Additionally, the actions are available within `SampleGasPricesServiceActions` and the events are available within `SampleGasPricesServiceEvents`
|
|
18
|
+
- Add optional `queryClientConfig` constructor argument which can be used to configure the underlying TanStack Query client ([#8343](https://github.com/MetaMask/core/pull/8343))
|
|
19
|
+
- Add `destroy` method to `BaseDataService` ([#8343](https://github.com/MetaMask/core/pull/8343))
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
|
|
23
|
+
- **BREAKING:** `SampleGasPricesService` now inherits from `BaseDataService` from `@metamask/base-data-service` ([#8343](https://github.com/MetaMask/core/pull/8343))
|
|
24
|
+
- Update `SampleGasPricesService.fetchGasPrices` (and messenger action) so requests to API will be cached and/or deduplicated ([#8343](https://github.com/MetaMask/core/pull/8343))
|
|
25
|
+
- Add new dependencies ([#8343](https://github.com/MetaMask/core/pull/8343))
|
|
26
|
+
- Add `@metamask/base-data-service` ^0.1.1
|
|
27
|
+
- Add `@tanstack/query-core` ^4.43.0
|
|
28
|
+
- Add `@metamask/superstruct` ^3.2.1
|
|
29
|
+
- Bump `@metamask/messenger` from `^1.0.0` to `^1.1.0` ([#8364](https://github.com/MetaMask/core/pull/8364))
|
|
30
|
+
|
|
31
|
+
### Removed
|
|
32
|
+
|
|
33
|
+
- **BREAKING:** Remove `onRetry`, `onBreak`, and `onDegraded` ([#8343](https://github.com/MetaMask/core/pull/8343))
|
|
34
|
+
- You are free to implement these methods in your "real" service class if you need them, but we no longer require you to do so.
|
|
35
|
+
|
|
10
36
|
## [4.0.4]
|
|
11
37
|
|
|
12
38
|
### Changed
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"index.cjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AASA,uGAA+F;AAAtF,mIAAA,sBAAsB,OAAA;AAS/B,mFAGwC;AAFtC,yIAAA,yBAAyB,OAAA;AACzB,wJAAA,wCAAwC,OAAA;AAW1C,+EAGsC;AAFpC,sIAAA,wBAAwB,OAAA;AACxB,+IAAA,iCAAiC,OAAA","sourcesContent":["export type {\n SampleGasPricesServiceInvalidateQueriesAction,\n SampleGasPricesServiceActions,\n SampleGasPricesServiceCacheUpdatedEvent,\n SampleGasPricesServiceGranularCacheUpdatedEvent,\n SampleGasPricesServiceEvents,\n SampleGasPricesServiceMessenger,\n} from './sample-gas-prices-service/sample-gas-prices-service';\nexport type { SampleGasPricesServiceFetchGasPricesAction } from './sample-gas-prices-service/sample-gas-prices-service-method-action-types';\nexport { SampleGasPricesService } from './sample-gas-prices-service/sample-gas-prices-service';\nexport type {\n SampleGasPricesControllerActions,\n SampleGasPricesControllerEvents,\n SampleGasPricesControllerGetStateAction,\n SampleGasPricesControllerMessenger,\n SampleGasPricesControllerState,\n SampleGasPricesControllerStateChangeEvent,\n} from './sample-gas-prices-controller';\nexport {\n SampleGasPricesController,\n getDefaultSampleGasPricesControllerState,\n} from './sample-gas-prices-controller';\nexport type { SampleGasPricesControllerUpdateGasPricesAction } from './sample-gas-prices-controller-method-action-types';\nexport type {\n SamplePetnamesControllerActions,\n SamplePetnamesControllerEvents,\n SamplePetnamesControllerGetStateAction,\n SamplePetnamesControllerMessenger,\n SamplePetnamesControllerState,\n SamplePetnamesControllerStateChangeEvent,\n} from './sample-petnames-controller';\nexport {\n SamplePetnamesController,\n getDefaultPetnamesControllerState,\n} from './sample-petnames-controller';\nexport type { SamplePetnamesControllerAssignPetnameAction } from './sample-petnames-controller-method-action-types';\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type { SampleGasPricesServiceActions, SampleGasPricesServiceEvents, SampleGasPricesServiceMessenger, } from "./sample-gas-prices-service/sample-gas-prices-service.cjs";
|
|
1
|
+
export type { SampleGasPricesServiceInvalidateQueriesAction, SampleGasPricesServiceActions, SampleGasPricesServiceCacheUpdatedEvent, SampleGasPricesServiceGranularCacheUpdatedEvent, SampleGasPricesServiceEvents, SampleGasPricesServiceMessenger, } from "./sample-gas-prices-service/sample-gas-prices-service.cjs";
|
|
2
2
|
export type { SampleGasPricesServiceFetchGasPricesAction } from "./sample-gas-prices-service/sample-gas-prices-service-method-action-types.cjs";
|
|
3
3
|
export { SampleGasPricesService } from "./sample-gas-prices-service/sample-gas-prices-service.cjs";
|
|
4
4
|
export type { SampleGasPricesControllerActions, SampleGasPricesControllerEvents, SampleGasPricesControllerGetStateAction, SampleGasPricesControllerMessenger, SampleGasPricesControllerState, SampleGasPricesControllerStateChangeEvent, } from "./sample-gas-prices-controller.cjs";
|
package/dist/index.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,6BAA6B,EAC7B,4BAA4B,EAC5B,+BAA+B,GAChC,kEAA8D;AAC/D,YAAY,EAAE,0CAA0C,EAAE,sFAAkF;AAC5I,OAAO,EAAE,sBAAsB,EAAE,kEAA8D;AAC/F,YAAY,EACV,gCAAgC,EAChC,+BAA+B,EAC/B,uCAAuC,EACvC,kCAAkC,EAClC,8BAA8B,EAC9B,yCAAyC,GAC1C,2CAAuC;AACxC,OAAO,EACL,yBAAyB,EACzB,wCAAwC,GACzC,2CAAuC;AACxC,YAAY,EAAE,8CAA8C,EAAE,+DAA2D;AACzH,YAAY,EACV,+BAA+B,EAC/B,8BAA8B,EAC9B,sCAAsC,EACtC,iCAAiC,EACjC,6BAA6B,EAC7B,wCAAwC,GACzC,yCAAqC;AACtC,OAAO,EACL,wBAAwB,EACxB,iCAAiC,GAClC,yCAAqC;AACtC,YAAY,EAAE,2CAA2C,EAAE,6DAAyD"}
|
|
1
|
+
{"version":3,"file":"index.d.cts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,6CAA6C,EAC7C,6BAA6B,EAC7B,uCAAuC,EACvC,+CAA+C,EAC/C,4BAA4B,EAC5B,+BAA+B,GAChC,kEAA8D;AAC/D,YAAY,EAAE,0CAA0C,EAAE,sFAAkF;AAC5I,OAAO,EAAE,sBAAsB,EAAE,kEAA8D;AAC/F,YAAY,EACV,gCAAgC,EAChC,+BAA+B,EAC/B,uCAAuC,EACvC,kCAAkC,EAClC,8BAA8B,EAC9B,yCAAyC,GAC1C,2CAAuC;AACxC,OAAO,EACL,yBAAyB,EACzB,wCAAwC,GACzC,2CAAuC;AACxC,YAAY,EAAE,8CAA8C,EAAE,+DAA2D;AACzH,YAAY,EACV,+BAA+B,EAC/B,8BAA8B,EAC9B,sCAAsC,EACtC,iCAAiC,EACjC,6BAA6B,EAC7B,wCAAwC,GACzC,yCAAqC;AACtC,OAAO,EACL,wBAAwB,EACxB,iCAAiC,GAClC,yCAAqC;AACtC,YAAY,EAAE,2CAA2C,EAAE,6DAAyD"}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type { SampleGasPricesServiceActions, SampleGasPricesServiceEvents, SampleGasPricesServiceMessenger, } from "./sample-gas-prices-service/sample-gas-prices-service.mjs";
|
|
1
|
+
export type { SampleGasPricesServiceInvalidateQueriesAction, SampleGasPricesServiceActions, SampleGasPricesServiceCacheUpdatedEvent, SampleGasPricesServiceGranularCacheUpdatedEvent, SampleGasPricesServiceEvents, SampleGasPricesServiceMessenger, } from "./sample-gas-prices-service/sample-gas-prices-service.mjs";
|
|
2
2
|
export type { SampleGasPricesServiceFetchGasPricesAction } from "./sample-gas-prices-service/sample-gas-prices-service-method-action-types.mjs";
|
|
3
3
|
export { SampleGasPricesService } from "./sample-gas-prices-service/sample-gas-prices-service.mjs";
|
|
4
4
|
export type { SampleGasPricesControllerActions, SampleGasPricesControllerEvents, SampleGasPricesControllerGetStateAction, SampleGasPricesControllerMessenger, SampleGasPricesControllerState, SampleGasPricesControllerStateChangeEvent, } from "./sample-gas-prices-controller.mjs";
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,6BAA6B,EAC7B,4BAA4B,EAC5B,+BAA+B,GAChC,kEAA8D;AAC/D,YAAY,EAAE,0CAA0C,EAAE,sFAAkF;AAC5I,OAAO,EAAE,sBAAsB,EAAE,kEAA8D;AAC/F,YAAY,EACV,gCAAgC,EAChC,+BAA+B,EAC/B,uCAAuC,EACvC,kCAAkC,EAClC,8BAA8B,EAC9B,yCAAyC,GAC1C,2CAAuC;AACxC,OAAO,EACL,yBAAyB,EACzB,wCAAwC,GACzC,2CAAuC;AACxC,YAAY,EAAE,8CAA8C,EAAE,+DAA2D;AACzH,YAAY,EACV,+BAA+B,EAC/B,8BAA8B,EAC9B,sCAAsC,EACtC,iCAAiC,EACjC,6BAA6B,EAC7B,wCAAwC,GACzC,yCAAqC;AACtC,OAAO,EACL,wBAAwB,EACxB,iCAAiC,GAClC,yCAAqC;AACtC,YAAY,EAAE,2CAA2C,EAAE,6DAAyD"}
|
|
1
|
+
{"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,6CAA6C,EAC7C,6BAA6B,EAC7B,uCAAuC,EACvC,+CAA+C,EAC/C,4BAA4B,EAC5B,+BAA+B,GAChC,kEAA8D;AAC/D,YAAY,EAAE,0CAA0C,EAAE,sFAAkF;AAC5I,OAAO,EAAE,sBAAsB,EAAE,kEAA8D;AAC/F,YAAY,EACV,gCAAgC,EAChC,+BAA+B,EAC/B,uCAAuC,EACvC,kCAAkC,EAClC,8BAA8B,EAC9B,yCAAyC,GAC1C,2CAAuC;AACxC,OAAO,EACL,yBAAyB,EACzB,wCAAwC,GACzC,2CAAuC;AACxC,YAAY,EAAE,8CAA8C,EAAE,+DAA2D;AACzH,YAAY,EACV,+BAA+B,EAC/B,8BAA8B,EAC9B,sCAAsC,EACtC,iCAAiC,EACjC,6BAA6B,EAC7B,wCAAwC,GACzC,yCAAqC;AACtC,OAAO,EACL,wBAAwB,EACxB,iCAAiC,GAClC,yCAAqC;AACtC,YAAY,EAAE,2CAA2C,EAAE,6DAAyD"}
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.mjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,sBAAsB,EAAE,kEAA8D;AAS/F,OAAO,EACL,yBAAyB,EACzB,wCAAwC,EACzC,2CAAuC;AAUxC,OAAO,EACL,wBAAwB,EACxB,iCAAiC,EAClC,yCAAqC","sourcesContent":["export type {\n SampleGasPricesServiceInvalidateQueriesAction,\n SampleGasPricesServiceActions,\n SampleGasPricesServiceCacheUpdatedEvent,\n SampleGasPricesServiceGranularCacheUpdatedEvent,\n SampleGasPricesServiceEvents,\n SampleGasPricesServiceMessenger,\n} from './sample-gas-prices-service/sample-gas-prices-service';\nexport type { SampleGasPricesServiceFetchGasPricesAction } from './sample-gas-prices-service/sample-gas-prices-service-method-action-types';\nexport { SampleGasPricesService } from './sample-gas-prices-service/sample-gas-prices-service';\nexport type {\n SampleGasPricesControllerActions,\n SampleGasPricesControllerEvents,\n SampleGasPricesControllerGetStateAction,\n SampleGasPricesControllerMessenger,\n SampleGasPricesControllerState,\n SampleGasPricesControllerStateChangeEvent,\n} from './sample-gas-prices-controller';\nexport {\n SampleGasPricesController,\n getDefaultSampleGasPricesControllerState,\n} from './sample-gas-prices-controller';\nexport type { SampleGasPricesControllerUpdateGasPricesAction } from './sample-gas-prices-controller-method-action-types';\nexport type {\n SamplePetnamesControllerActions,\n SamplePetnamesControllerEvents,\n SamplePetnamesControllerGetStateAction,\n SamplePetnamesControllerMessenger,\n SamplePetnamesControllerState,\n SamplePetnamesControllerStateChangeEvent,\n} from './sample-petnames-controller';\nexport {\n SamplePetnamesController,\n getDefaultPetnamesControllerState,\n} from './sample-petnames-controller';\nexport type { SamplePetnamesControllerAssignPetnameAction } from './sample-petnames-controller-method-action-types';\n"]}
|
|
@@ -1,20 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
3
|
-
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
4
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
5
|
-
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
6
|
-
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
7
|
-
};
|
|
8
|
-
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
9
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
10
|
-
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
11
|
-
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
|
-
};
|
|
13
|
-
var _a, _SampleGasPricesService_messenger, _SampleGasPricesService_fetch, _SampleGasPricesService_policy;
|
|
14
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
3
|
exports.SampleGasPricesService = exports.serviceName = void 0;
|
|
4
|
+
const base_data_service_1 = require("@metamask/base-data-service");
|
|
16
5
|
const controller_utils_1 = require("@metamask/controller-utils");
|
|
17
|
-
const
|
|
6
|
+
const superstruct_1 = require("@metamask/superstruct");
|
|
18
7
|
// === GENERAL ===
|
|
19
8
|
/**
|
|
20
9
|
* The name of the {@link SampleGasPricesService}, used to namespace the
|
|
@@ -22,17 +11,36 @@ const utils_1 = require("@metamask/utils");
|
|
|
22
11
|
*/
|
|
23
12
|
exports.serviceName = 'SampleGasPricesService';
|
|
24
13
|
// === MESSENGER ===
|
|
14
|
+
/**
|
|
15
|
+
* All of the methods within {@link SampleGasPricesService} that are exposed via
|
|
16
|
+
* the messenger.
|
|
17
|
+
*/
|
|
25
18
|
const MESSENGER_EXPOSED_METHODS = ['fetchGasPrices'];
|
|
19
|
+
// === SERVICE DEFINITION ===
|
|
20
|
+
/**
|
|
21
|
+
* Struct to validate what the API endpoint returns.
|
|
22
|
+
*/
|
|
23
|
+
const GasPricesResponseStruct = (0, superstruct_1.type)({
|
|
24
|
+
data: (0, superstruct_1.type)({
|
|
25
|
+
low: (0, superstruct_1.number)(),
|
|
26
|
+
average: (0, superstruct_1.number)(),
|
|
27
|
+
high: (0, superstruct_1.number)(),
|
|
28
|
+
}),
|
|
29
|
+
});
|
|
30
|
+
/**
|
|
31
|
+
* The base URL of the API that the service represents.
|
|
32
|
+
*/
|
|
33
|
+
const BASE_URL = 'https://api.example.com';
|
|
26
34
|
/**
|
|
27
35
|
* This service object is responsible for fetching gas prices via an API.
|
|
28
36
|
*
|
|
29
37
|
* @example
|
|
30
38
|
*
|
|
31
39
|
* ``` ts
|
|
40
|
+
* import type { MessengerActions, MessengerEvents } from '@metamask/messenger';
|
|
32
41
|
* import { Messenger } from '@metamask/messenger';
|
|
33
42
|
* import type {
|
|
34
|
-
*
|
|
35
|
-
* SampleGasPricesServiceEvents,
|
|
43
|
+
* SampleGasPricesServiceMessenger,
|
|
36
44
|
* } from '@metamask/sample-controllers';
|
|
37
45
|
*
|
|
38
46
|
* const rootMessenger = new Messenger<
|
|
@@ -42,8 +50,8 @@ const MESSENGER_EXPOSED_METHODS = ['fetchGasPrices'];
|
|
|
42
50
|
* >({ namespace: 'Root' });
|
|
43
51
|
* const gasPricesServiceMessenger = new Messenger<
|
|
44
52
|
* 'SampleGasPricesService',
|
|
45
|
-
*
|
|
46
|
-
*
|
|
53
|
+
* MessengerActions<SampleGasPricesServiceMessenger>,
|
|
54
|
+
* MessengerEvents<SampleGasPricesServiceMessenger>,
|
|
47
55
|
* typeof rootMessenger,
|
|
48
56
|
* >({
|
|
49
57
|
* namespace: 'SampleGasPricesService',
|
|
@@ -52,7 +60,6 @@ const MESSENGER_EXPOSED_METHODS = ['fetchGasPrices'];
|
|
|
52
60
|
* // Instantiate the service to register its actions on the messenger
|
|
53
61
|
* new SampleGasPricesService({
|
|
54
62
|
* messenger: gasPricesServiceMessenger,
|
|
55
|
-
* fetch,
|
|
56
63
|
* });
|
|
57
64
|
*
|
|
58
65
|
* // Later...
|
|
@@ -64,84 +71,25 @@ const MESSENGER_EXPOSED_METHODS = ['fetchGasPrices'];
|
|
|
64
71
|
* // ... Do something with the gas prices ...
|
|
65
72
|
* ```
|
|
66
73
|
*/
|
|
67
|
-
class SampleGasPricesService {
|
|
74
|
+
class SampleGasPricesService extends base_data_service_1.BaseDataService {
|
|
68
75
|
/**
|
|
69
76
|
* Constructs a new SampleGasPricesService object.
|
|
70
77
|
*
|
|
71
78
|
* @param args - The constructor arguments.
|
|
72
79
|
* @param args.messenger - The messenger suited for this service.
|
|
73
|
-
* @param args.
|
|
74
|
-
*
|
|
75
|
-
* to pass that; otherwise you can pass an equivalent (such as `fetch` via
|
|
76
|
-
* `node-fetch`).
|
|
80
|
+
* @param args.queryClientConfig - Configuration for the underlying TanStack
|
|
81
|
+
* Query client.
|
|
77
82
|
* @param args.policyOptions - Options to pass to `createServicePolicy`, which
|
|
78
83
|
* is used to wrap each request. See {@link CreateServicePolicyOptions}.
|
|
79
84
|
*/
|
|
80
|
-
constructor({ messenger,
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
_SampleGasPricesService_fetch.set(this, void 0);
|
|
89
|
-
/**
|
|
90
|
-
* The policy that wraps the request.
|
|
91
|
-
*
|
|
92
|
-
* @see {@link createServicePolicy}
|
|
93
|
-
*/
|
|
94
|
-
_SampleGasPricesService_policy.set(this, void 0);
|
|
95
|
-
this.name = exports.serviceName;
|
|
96
|
-
__classPrivateFieldSet(this, _SampleGasPricesService_messenger, messenger, "f");
|
|
97
|
-
__classPrivateFieldSet(this, _SampleGasPricesService_fetch, fetchFunction, "f");
|
|
98
|
-
__classPrivateFieldSet(this, _SampleGasPricesService_policy, (0, controller_utils_1.createServicePolicy)(policyOptions), "f");
|
|
99
|
-
__classPrivateFieldGet(this, _SampleGasPricesService_messenger, "f").registerMethodActionHandlers(this, MESSENGER_EXPOSED_METHODS);
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* Registers a handler that will be called after a request returns a non-500
|
|
103
|
-
* response, causing a retry. Primarily useful in tests where timers are being
|
|
104
|
-
* mocked.
|
|
105
|
-
*
|
|
106
|
-
* @param listener - The handler to be called.
|
|
107
|
-
* @returns An object that can be used to unregister the handler. See
|
|
108
|
-
* {@link CockatielEvent}.
|
|
109
|
-
* @see {@link createServicePolicy}
|
|
110
|
-
*/
|
|
111
|
-
onRetry(listener) {
|
|
112
|
-
return __classPrivateFieldGet(this, _SampleGasPricesService_policy, "f").onRetry(listener);
|
|
113
|
-
}
|
|
114
|
-
/**
|
|
115
|
-
* Registers a handler that will be called after a set number of retry rounds
|
|
116
|
-
* prove that requests to the API endpoint consistently return a 5xx response.
|
|
117
|
-
*
|
|
118
|
-
* @param listener - The handler to be called.
|
|
119
|
-
* @returns An object that can be used to unregister the handler. See
|
|
120
|
-
* {@link CockatielEvent}.
|
|
121
|
-
* @see {@link createServicePolicy}
|
|
122
|
-
*/
|
|
123
|
-
onBreak(listener) {
|
|
124
|
-
return __classPrivateFieldGet(this, _SampleGasPricesService_policy, "f").onBreak(listener);
|
|
125
|
-
}
|
|
126
|
-
/**
|
|
127
|
-
* Registers a handler that will be called under one of two circumstances:
|
|
128
|
-
*
|
|
129
|
-
* 1. After a set number of retries prove that requests to the API
|
|
130
|
-
* consistently result in one of the following failures:
|
|
131
|
-
* 1. A connection initiation error
|
|
132
|
-
* 2. A connection reset error
|
|
133
|
-
* 3. A timeout error
|
|
134
|
-
* 4. A non-JSON response
|
|
135
|
-
* 5. A 502, 503, or 504 response
|
|
136
|
-
* 2. After a successful request is made to the API, but the response takes
|
|
137
|
-
* longer than a set duration to return.
|
|
138
|
-
*
|
|
139
|
-
* @param listener - The handler to be called.
|
|
140
|
-
* @returns An object that can be used to unregister the handler. See
|
|
141
|
-
* {@link CockatielEvent}.
|
|
142
|
-
*/
|
|
143
|
-
onDegraded(listener) {
|
|
144
|
-
return __classPrivateFieldGet(this, _SampleGasPricesService_policy, "f").onDegraded(listener);
|
|
85
|
+
constructor({ messenger, queryClientConfig = {}, policyOptions = {}, }) {
|
|
86
|
+
super({
|
|
87
|
+
name: exports.serviceName,
|
|
88
|
+
messenger,
|
|
89
|
+
queryClientConfig,
|
|
90
|
+
policyOptions,
|
|
91
|
+
});
|
|
92
|
+
this.messenger.registerMethodActionHandlers(this, MESSENGER_EXPOSED_METHODS);
|
|
145
93
|
}
|
|
146
94
|
/**
|
|
147
95
|
* Makes a request to the API in order to retrieve gas prices for a particular
|
|
@@ -151,32 +99,23 @@ class SampleGasPricesService {
|
|
|
151
99
|
* @returns The gas prices for the given chain.
|
|
152
100
|
*/
|
|
153
101
|
async fetchGasPrices(chainId) {
|
|
154
|
-
const
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
102
|
+
const url = new URL('/gas-prices', BASE_URL);
|
|
103
|
+
url.searchParams.append('chainId', `eip155:${(0, controller_utils_1.fromHex)(chainId).toString()}`);
|
|
104
|
+
const jsonResponse = await this.fetchQuery({
|
|
105
|
+
queryKey: [`${this.name}:fetchGasPrices`, chainId],
|
|
106
|
+
queryFn: async () => {
|
|
107
|
+
const response = await fetch(url);
|
|
108
|
+
if (!response.ok) {
|
|
109
|
+
throw new controller_utils_1.HttpError(response.status, `Gas prices API failed with status '${response.status}'`);
|
|
110
|
+
}
|
|
111
|
+
return response.json();
|
|
112
|
+
},
|
|
162
113
|
});
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
(0, utils_1.hasProperty)(jsonResponse, 'data') &&
|
|
166
|
-
(0, utils_1.isPlainObject)(jsonResponse.data) &&
|
|
167
|
-
(0, utils_1.hasProperty)(jsonResponse.data, 'low') &&
|
|
168
|
-
(0, utils_1.hasProperty)(jsonResponse.data, 'average') &&
|
|
169
|
-
(0, utils_1.hasProperty)(jsonResponse.data, 'high')) {
|
|
170
|
-
const { data: { low, average, high }, } = jsonResponse;
|
|
171
|
-
if (typeof low === 'number' &&
|
|
172
|
-
typeof average === 'number' &&
|
|
173
|
-
typeof high === 'number') {
|
|
174
|
-
return { low, average, high };
|
|
175
|
-
}
|
|
114
|
+
if (!(0, superstruct_1.is)(jsonResponse, GasPricesResponseStruct)) {
|
|
115
|
+
throw new Error('Malformed response received from gas prices API');
|
|
176
116
|
}
|
|
177
|
-
|
|
117
|
+
return jsonResponse.data;
|
|
178
118
|
}
|
|
179
119
|
}
|
|
180
120
|
exports.SampleGasPricesService = SampleGasPricesService;
|
|
181
|
-
_a = SampleGasPricesService, _SampleGasPricesService_messenger = new WeakMap(), _SampleGasPricesService_fetch = new WeakMap(), _SampleGasPricesService_policy = new WeakMap();
|
|
182
121
|
//# sourceMappingURL=sample-gas-prices-service.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sample-gas-prices-service.cjs","sourceRoot":"","sources":["../../src/sample-gas-prices-service/sample-gas-prices-service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAIA,iEAIoC;AAEpC,2CAA6D;AAM7D,kBAAkB;AAElB;;;GAGG;AACU,QAAA,WAAW,GAAG,wBAAwB,CAAC;AAEpD,oBAAoB;AAEpB,MAAM,yBAAyB,GAAG,CAAC,gBAAgB,CAAU,CAAC;AA8C9D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,MAAa,sBAAsB;IA2BjC;;;;;;;;;;;OAWG;IACH,YAAY,EACV,SAAS,EACT,KAAK,EAAE,aAAa,EACpB,aAAa,GAAG,EAAE,GAKnB;QAzCD;;WAEG;QACM,oDAES;QAElB;;WAEG;QACM,gDAEK;QAEd;;;;WAIG;QACM,iDAAuB;QAuB9B,IAAI,CAAC,IAAI,GAAG,mBAAW,CAAC;QACxB,uBAAA,IAAI,qCAAc,SAAS,MAAA,CAAC;QAC5B,uBAAA,IAAI,iCAAU,aAAa,MAAA,CAAC;QAC5B,uBAAA,IAAI,kCAAW,IAAA,sCAAmB,EAAC,aAAa,CAAC,MAAA,CAAC;QAElD,uBAAA,IAAI,yCAAW,CAAC,4BAA4B,CAC1C,IAAI,EACJ,yBAAyB,CAC1B,CAAC;IACJ,CAAC;IAED;;;;;;;;;OASG;IACH,OAAO,CAAC,QAAiD;QACvD,OAAO,uBAAA,IAAI,sCAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACxC,CAAC;IAED;;;;;;;;OAQG;IACH,OAAO,CAAC,QAAiD;QACvD,OAAO,uBAAA,IAAI,sCAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACxC,CAAC;IAED;;;;;;;;;;;;;;;;OAgBG;IACH,UAAU,CACR,QAAoD;QAEpD,OAAO,uBAAA,IAAI,sCAAQ,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;IAC3C,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,cAAc,CAAC,OAAY;QAC/B,MAAM,QAAQ,GAAG,MAAM,uBAAA,IAAI,sCAAQ,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE;YACrD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,oCAAoC,CAAC,CAAC;YAC1D,GAAG,CAAC,YAAY,CAAC,MAAM,CACrB,SAAS,EACT,UAAU,IAAA,0BAAO,EAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE,CACxC,CAAC;YACF,MAAM,aAAa,GAAG,MAAM,uBAAA,IAAI,qCAAO,MAAX,IAAI,EAAQ,GAAG,CAAC,CAAC;YAC7C,IAAI,CAAC,aAAa,CAAC,EAAE,EAAE,CAAC;gBACtB,MAAM,IAAI,4BAAS,CACjB,aAAa,CAAC,MAAM,EACpB,aAAa,GAAG,CAAC,QAAQ,EAAE,yBAAyB,aAAa,CAAC,MAAM,GAAG,CAC5E,CAAC;YACJ,CAAC;YACD,OAAO,aAAa,CAAC;QACvB,CAAC,CAAC,CAAC;QACH,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QAE3C,IACE,IAAA,qBAAa,EAAC,YAAY,CAAC;YAC3B,IAAA,mBAAW,EAAC,YAAY,EAAE,MAAM,CAAC;YACjC,IAAA,qBAAa,EAAC,YAAY,CAAC,IAAI,CAAC;YAChC,IAAA,mBAAW,EAAC,YAAY,CAAC,IAAI,EAAE,KAAK,CAAC;YACrC,IAAA,mBAAW,EAAC,YAAY,CAAC,IAAI,EAAE,SAAS,CAAC;YACzC,IAAA,mBAAW,EAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,EACtC,CAAC;YACD,MAAM,EACJ,IAAI,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,GAC7B,GAAG,YAAY,CAAC;YACjB,IACE,OAAO,GAAG,KAAK,QAAQ;gBACvB,OAAO,OAAO,KAAK,QAAQ;gBAC3B,OAAO,IAAI,KAAK,QAAQ,EACxB,CAAC;gBACD,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;YAChC,CAAC;QACH,CAAC;QAED,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACrE,CAAC;CACF;AA5JD,wDA4JC","sourcesContent":["import type {\n CreateServicePolicyOptions,\n ServicePolicy,\n} from '@metamask/controller-utils';\nimport {\n createServicePolicy,\n fromHex,\n HttpError,\n} from '@metamask/controller-utils';\nimport type { Messenger } from '@metamask/messenger';\nimport { hasProperty, isPlainObject } from '@metamask/utils';\nimport type { Hex } from '@metamask/utils';\nimport type { IDisposable } from 'cockatiel';\n\nimport type { SampleGasPricesServiceMethodActions } from './sample-gas-prices-service-method-action-types';\n\n// === GENERAL ===\n\n/**\n * The name of the {@link SampleGasPricesService}, used to namespace the\n * service's actions and events.\n */\nexport const serviceName = 'SampleGasPricesService';\n\n// === MESSENGER ===\n\nconst MESSENGER_EXPOSED_METHODS = ['fetchGasPrices'] as const;\n\n/**\n * Actions that {@link SampleGasPricesService} exposes to other consumers.\n */\nexport type SampleGasPricesServiceActions = SampleGasPricesServiceMethodActions;\n\n/**\n * Actions from other messengers that {@link SampleGasPricesMessenger} calls.\n */\ntype AllowedActions = never;\n\n/**\n * Events that {@link SampleGasPricesService} exposes to other consumers.\n */\nexport type SampleGasPricesServiceEvents = never;\n\n/**\n * Events from other messengers that {@link SampleGasPricesService} subscribes\n * to.\n */\ntype AllowedEvents = never;\n\n/**\n * The messenger which is restricted to actions and events accessed by\n * {@link SampleGasPricesService}.\n */\nexport type SampleGasPricesServiceMessenger = Messenger<\n typeof serviceName,\n SampleGasPricesServiceActions | AllowedActions,\n SampleGasPricesServiceEvents | AllowedEvents\n>;\n\n// === SERVICE DEFINITION ===\n\n/**\n * What the API endpoint returns.\n */\ntype GasPricesResponse = {\n data: {\n low: number;\n average: number;\n high: number;\n };\n};\n\n/**\n * This service object is responsible for fetching gas prices via an API.\n *\n * @example\n *\n * ``` ts\n * import { Messenger } from '@metamask/messenger';\n * import type {\n * SampleGasPricesServiceActions,\n * SampleGasPricesServiceEvents,\n * } from '@metamask/sample-controllers';\n *\n * const rootMessenger = new Messenger<\n * 'Root',\n * SampleGasPricesServiceActions\n * SampleGasPricesServiceEvents\n * >({ namespace: 'Root' });\n * const gasPricesServiceMessenger = new Messenger<\n * 'SampleGasPricesService',\n * SampleGasPricesServiceActions,\n * SampleGasPricesServiceEvents,\n * typeof rootMessenger,\n * >({\n * namespace: 'SampleGasPricesService',\n * parent: rootMessenger,\n * });\n * // Instantiate the service to register its actions on the messenger\n * new SampleGasPricesService({\n * messenger: gasPricesServiceMessenger,\n * fetch,\n * });\n *\n * // Later...\n * // Fetch gas prices for Mainnet\n * const gasPrices = await rootMessenger.call(\n * 'SampleGasPricesService:fetchGasPrices',\n * '0x1',\n * );\n * // ... Do something with the gas prices ...\n * ```\n */\nexport class SampleGasPricesService {\n /**\n * The name of the service.\n */\n readonly name: typeof serviceName;\n\n /**\n * The messenger suited for this service.\n */\n readonly #messenger: ConstructorParameters<\n typeof SampleGasPricesService\n >[0]['messenger'];\n\n /**\n * A function that can be used to make an HTTP request.\n */\n readonly #fetch: ConstructorParameters<\n typeof SampleGasPricesService\n >[0]['fetch'];\n\n /**\n * The policy that wraps the request.\n *\n * @see {@link createServicePolicy}\n */\n readonly #policy: ServicePolicy;\n\n /**\n * Constructs a new SampleGasPricesService object.\n *\n * @param args - The constructor arguments.\n * @param args.messenger - The messenger suited for this service.\n * @param args.fetch - A function that can be used to make an HTTP request. If\n * your JavaScript environment supports `fetch` natively, you'll probably want\n * to pass that; otherwise you can pass an equivalent (such as `fetch` via\n * `node-fetch`).\n * @param args.policyOptions - Options to pass to `createServicePolicy`, which\n * is used to wrap each request. See {@link CreateServicePolicyOptions}.\n */\n constructor({\n messenger,\n fetch: fetchFunction,\n policyOptions = {},\n }: {\n messenger: SampleGasPricesServiceMessenger;\n fetch: typeof fetch;\n policyOptions?: CreateServicePolicyOptions;\n }) {\n this.name = serviceName;\n this.#messenger = messenger;\n this.#fetch = fetchFunction;\n this.#policy = createServicePolicy(policyOptions);\n\n this.#messenger.registerMethodActionHandlers(\n this,\n MESSENGER_EXPOSED_METHODS,\n );\n }\n\n /**\n * Registers a handler that will be called after a request returns a non-500\n * response, causing a retry. Primarily useful in tests where timers are being\n * mocked.\n *\n * @param listener - The handler to be called.\n * @returns An object that can be used to unregister the handler. See\n * {@link CockatielEvent}.\n * @see {@link createServicePolicy}\n */\n onRetry(listener: Parameters<ServicePolicy['onRetry']>[0]): IDisposable {\n return this.#policy.onRetry(listener);\n }\n\n /**\n * Registers a handler that will be called after a set number of retry rounds\n * prove that requests to the API endpoint consistently return a 5xx response.\n *\n * @param listener - The handler to be called.\n * @returns An object that can be used to unregister the handler. See\n * {@link CockatielEvent}.\n * @see {@link createServicePolicy}\n */\n onBreak(listener: Parameters<ServicePolicy['onBreak']>[0]): IDisposable {\n return this.#policy.onBreak(listener);\n }\n\n /**\n * Registers a handler that will be called under one of two circumstances:\n *\n * 1. After a set number of retries prove that requests to the API\n * consistently result in one of the following failures:\n * 1. A connection initiation error\n * 2. A connection reset error\n * 3. A timeout error\n * 4. A non-JSON response\n * 5. A 502, 503, or 504 response\n * 2. After a successful request is made to the API, but the response takes\n * longer than a set duration to return.\n *\n * @param listener - The handler to be called.\n * @returns An object that can be used to unregister the handler. See\n * {@link CockatielEvent}.\n */\n onDegraded(\n listener: Parameters<ServicePolicy['onDegraded']>[0],\n ): IDisposable {\n return this.#policy.onDegraded(listener);\n }\n\n /**\n * Makes a request to the API in order to retrieve gas prices for a particular\n * chain.\n *\n * @param chainId - The chain ID for which you want to fetch gas prices.\n * @returns The gas prices for the given chain.\n */\n async fetchGasPrices(chainId: Hex): Promise<GasPricesResponse['data']> {\n const response = await this.#policy.execute(async () => {\n const url = new URL('https://api.example.com/gas-prices');\n url.searchParams.append(\n 'chainId',\n `eip155:${fromHex(chainId).toString()}`,\n );\n const localResponse = await this.#fetch(url);\n if (!localResponse.ok) {\n throw new HttpError(\n localResponse.status,\n `Fetching '${url.toString()}' failed with status '${localResponse.status}'`,\n );\n }\n return localResponse;\n });\n const jsonResponse = await response.json();\n\n if (\n isPlainObject(jsonResponse) &&\n hasProperty(jsonResponse, 'data') &&\n isPlainObject(jsonResponse.data) &&\n hasProperty(jsonResponse.data, 'low') &&\n hasProperty(jsonResponse.data, 'average') &&\n hasProperty(jsonResponse.data, 'high')\n ) {\n const {\n data: { low, average, high },\n } = jsonResponse;\n if (\n typeof low === 'number' &&\n typeof average === 'number' &&\n typeof high === 'number'\n ) {\n return { low, average, high };\n }\n }\n\n throw new Error('Malformed response received from gas prices API');\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"sample-gas-prices-service.cjs","sourceRoot":"","sources":["../../src/sample-gas-prices-service/sample-gas-prices-service.ts"],"names":[],"mappings":";;;AAAA,mEAA8D;AAO9D,iEAAgE;AAGhE,uDAAyD;AAMzD,kBAAkB;AAElB;;;GAGG;AACU,QAAA,WAAW,GAAG,wBAAwB,CAAC;AAEpD,oBAAoB;AAEpB;;;GAGG;AACH,MAAM,yBAAyB,GAAG,CAAC,gBAAgB,CAAU,CAAC;AAwD9D,6BAA6B;AAE7B;;GAEG;AACH,MAAM,uBAAuB,GAAG,IAAA,kBAAI,EAAC;IACnC,IAAI,EAAE,IAAA,kBAAI,EAAC;QACT,GAAG,EAAE,IAAA,oBAAM,GAAE;QACb,OAAO,EAAE,IAAA,oBAAM,GAAE;QACjB,IAAI,EAAE,IAAA,oBAAM,GAAE;KACf,CAAC;CACH,CAAC,CAAC;AAOH;;GAEG;AACH,MAAM,QAAQ,GAAG,yBAAyB,CAAC;AAE3C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,MAAa,sBAAuB,SAAQ,mCAG3C;IACC;;;;;;;;;OASG;IACH,YAAY,EACV,SAAS,EACT,iBAAiB,GAAG,EAAE,EACtB,aAAa,GAAG,EAAE,GAKnB;QACC,KAAK,CAAC;YACJ,IAAI,EAAE,mBAAW;YACjB,SAAS;YACT,iBAAiB;YACjB,aAAa;SACd,CAAC,CAAC;QAEH,IAAI,CAAC,SAAS,CAAC,4BAA4B,CACzC,IAAI,EACJ,yBAAyB,CAC1B,CAAC;IACJ,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,cAAc,CAAC,OAAY;QAC/B,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;QAC7C,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,SAAS,EAAE,UAAU,IAAA,0BAAO,EAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAE5E,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC;YACzC,QAAQ,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,iBAAiB,EAAE,OAAO,CAAC;YAClD,OAAO,EAAE,KAAK,IAAI,EAAE;gBAClB,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;gBAElC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;oBACjB,MAAM,IAAI,4BAAS,CACjB,QAAQ,CAAC,MAAM,EACf,sCAAsC,QAAQ,CAAC,MAAM,GAAG,CACzD,CAAC;gBACJ,CAAC;gBAED,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC;YACzB,CAAC;SACF,CAAC,CAAC;QAEH,IAAI,CAAC,IAAA,gBAAE,EAAC,YAAY,EAAE,uBAAuB,CAAC,EAAE,CAAC;YAC/C,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;QACrE,CAAC;QAED,OAAO,YAAY,CAAC,IAAI,CAAC;IAC3B,CAAC;CACF;AArED,wDAqEC","sourcesContent":["import { BaseDataService } from '@metamask/base-data-service';\nimport type {\n DataServiceCacheUpdatedEvent,\n DataServiceGranularCacheUpdatedEvent,\n DataServiceInvalidateQueriesAction,\n} from '@metamask/base-data-service';\nimport type { CreateServicePolicyOptions } from '@metamask/controller-utils';\nimport { HttpError, fromHex } from '@metamask/controller-utils';\nimport type { Messenger } from '@metamask/messenger';\nimport type { Infer } from '@metamask/superstruct';\nimport { is, number, type } from '@metamask/superstruct';\nimport type { Hex } from '@metamask/utils';\nimport type { QueryClientConfig } from '@tanstack/query-core';\n\nimport type { SampleGasPricesServiceMethodActions } from './sample-gas-prices-service-method-action-types';\n\n// === GENERAL ===\n\n/**\n * The name of the {@link SampleGasPricesService}, used to namespace the\n * service's actions and events.\n */\nexport const serviceName = 'SampleGasPricesService';\n\n// === MESSENGER ===\n\n/**\n * All of the methods within {@link SampleGasPricesService} that are exposed via\n * the messenger.\n */\nconst MESSENGER_EXPOSED_METHODS = ['fetchGasPrices'] as const;\n\n/**\n * Invalidates cached queries for {@link SampleGasPricesService}.\n */\nexport type SampleGasPricesServiceInvalidateQueriesAction =\n DataServiceInvalidateQueriesAction<typeof serviceName>;\n\n/**\n * Actions that {@link SampleGasPricesService} exposes to other consumers.\n */\nexport type SampleGasPricesServiceActions =\n | SampleGasPricesServiceMethodActions\n | SampleGasPricesServiceInvalidateQueriesAction;\n\n/**\n * Actions from other messengers that {@link SampleGasPricesService} calls.\n */\ntype AllowedActions = never;\n\n/**\n * Published when {@link SampleGasPricesService}'s cache is updated.\n */\nexport type SampleGasPricesServiceCacheUpdatedEvent =\n DataServiceCacheUpdatedEvent<typeof serviceName>;\n\n/**\n * Published when a key within {@link SampleGasPricesService}'s cache is\n * updated.\n */\nexport type SampleGasPricesServiceGranularCacheUpdatedEvent =\n DataServiceGranularCacheUpdatedEvent<typeof serviceName>;\n\n/**\n * Events that {@link SampleGasPricesService} exposes to other consumers.\n */\nexport type SampleGasPricesServiceEvents =\n | SampleGasPricesServiceCacheUpdatedEvent\n | SampleGasPricesServiceGranularCacheUpdatedEvent;\n\n/**\n * Events from other messengers that {@link SampleGasPricesService} subscribes\n * to.\n */\ntype AllowedEvents = never;\n\n/**\n * The messenger which is restricted to actions and events accessed by\n * {@link SampleGasPricesService}.\n */\nexport type SampleGasPricesServiceMessenger = Messenger<\n typeof serviceName,\n SampleGasPricesServiceActions | AllowedActions,\n SampleGasPricesServiceEvents | AllowedEvents\n>;\n\n// === SERVICE DEFINITION ===\n\n/**\n * Struct to validate what the API endpoint returns.\n */\nconst GasPricesResponseStruct = type({\n data: type({\n low: number(),\n average: number(),\n high: number(),\n }),\n});\n\n/**\n * What the API endpoint returns.\n */\ntype GasPricesResponse = Infer<typeof GasPricesResponseStruct>;\n\n/**\n * The base URL of the API that the service represents.\n */\nconst BASE_URL = 'https://api.example.com';\n\n/**\n * This service object is responsible for fetching gas prices via an API.\n *\n * @example\n *\n * ``` ts\n * import type { MessengerActions, MessengerEvents } from '@metamask/messenger';\n * import { Messenger } from '@metamask/messenger';\n * import type {\n * SampleGasPricesServiceMessenger,\n * } from '@metamask/sample-controllers';\n *\n * const rootMessenger = new Messenger<\n * 'Root',\n * SampleGasPricesServiceActions\n * SampleGasPricesServiceEvents\n * >({ namespace: 'Root' });\n * const gasPricesServiceMessenger = new Messenger<\n * 'SampleGasPricesService',\n * MessengerActions<SampleGasPricesServiceMessenger>,\n * MessengerEvents<SampleGasPricesServiceMessenger>,\n * typeof rootMessenger,\n * >({\n * namespace: 'SampleGasPricesService',\n * parent: rootMessenger,\n * });\n * // Instantiate the service to register its actions on the messenger\n * new SampleGasPricesService({\n * messenger: gasPricesServiceMessenger,\n * });\n *\n * // Later...\n * // Fetch gas prices for Mainnet\n * const gasPrices = await rootMessenger.call(\n * 'SampleGasPricesService:fetchGasPrices',\n * '0x1',\n * );\n * // ... Do something with the gas prices ...\n * ```\n */\nexport class SampleGasPricesService extends BaseDataService<\n typeof serviceName,\n SampleGasPricesServiceMessenger\n> {\n /**\n * Constructs a new SampleGasPricesService object.\n *\n * @param args - The constructor arguments.\n * @param args.messenger - The messenger suited for this service.\n * @param args.queryClientConfig - Configuration for the underlying TanStack\n * Query client.\n * @param args.policyOptions - Options to pass to `createServicePolicy`, which\n * is used to wrap each request. See {@link CreateServicePolicyOptions}.\n */\n constructor({\n messenger,\n queryClientConfig = {},\n policyOptions = {},\n }: {\n messenger: SampleGasPricesServiceMessenger;\n queryClientConfig?: QueryClientConfig;\n policyOptions?: CreateServicePolicyOptions;\n }) {\n super({\n name: serviceName,\n messenger,\n queryClientConfig,\n policyOptions,\n });\n\n this.messenger.registerMethodActionHandlers(\n this,\n MESSENGER_EXPOSED_METHODS,\n );\n }\n\n /**\n * Makes a request to the API in order to retrieve gas prices for a particular\n * chain.\n *\n * @param chainId - The chain ID for which you want to fetch gas prices.\n * @returns The gas prices for the given chain.\n */\n async fetchGasPrices(chainId: Hex): Promise<GasPricesResponse['data']> {\n const url = new URL('/gas-prices', BASE_URL);\n url.searchParams.append('chainId', `eip155:${fromHex(chainId).toString()}`);\n\n const jsonResponse = await this.fetchQuery({\n queryKey: [`${this.name}:fetchGasPrices`, chainId],\n queryFn: async () => {\n const response = await fetch(url);\n\n if (!response.ok) {\n throw new HttpError(\n response.status,\n `Gas prices API failed with status '${response.status}'`,\n );\n }\n\n return response.json();\n },\n });\n\n if (!is(jsonResponse, GasPricesResponseStruct)) {\n throw new Error('Malformed response received from gas prices API');\n }\n\n return jsonResponse.data;\n }\n}\n"]}
|
|
@@ -1,25 +1,41 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { BaseDataService } from "@metamask/base-data-service";
|
|
2
|
+
import type { DataServiceCacheUpdatedEvent, DataServiceGranularCacheUpdatedEvent, DataServiceInvalidateQueriesAction } from "@metamask/base-data-service";
|
|
3
|
+
import type { CreateServicePolicyOptions } from "@metamask/controller-utils";
|
|
2
4
|
import type { Messenger } from "@metamask/messenger";
|
|
5
|
+
import type { Infer } from "@metamask/superstruct";
|
|
3
6
|
import type { Hex } from "@metamask/utils";
|
|
4
|
-
import type {
|
|
7
|
+
import type { QueryClientConfig } from "@tanstack/query-core";
|
|
5
8
|
import type { SampleGasPricesServiceMethodActions } from "./sample-gas-prices-service-method-action-types.cjs";
|
|
6
9
|
/**
|
|
7
10
|
* The name of the {@link SampleGasPricesService}, used to namespace the
|
|
8
11
|
* service's actions and events.
|
|
9
12
|
*/
|
|
10
13
|
export declare const serviceName = "SampleGasPricesService";
|
|
14
|
+
/**
|
|
15
|
+
* Invalidates cached queries for {@link SampleGasPricesService}.
|
|
16
|
+
*/
|
|
17
|
+
export type SampleGasPricesServiceInvalidateQueriesAction = DataServiceInvalidateQueriesAction<typeof serviceName>;
|
|
11
18
|
/**
|
|
12
19
|
* Actions that {@link SampleGasPricesService} exposes to other consumers.
|
|
13
20
|
*/
|
|
14
|
-
export type SampleGasPricesServiceActions = SampleGasPricesServiceMethodActions;
|
|
21
|
+
export type SampleGasPricesServiceActions = SampleGasPricesServiceMethodActions | SampleGasPricesServiceInvalidateQueriesAction;
|
|
15
22
|
/**
|
|
16
|
-
* Actions from other messengers that {@link
|
|
23
|
+
* Actions from other messengers that {@link SampleGasPricesService} calls.
|
|
17
24
|
*/
|
|
18
25
|
type AllowedActions = never;
|
|
26
|
+
/**
|
|
27
|
+
* Published when {@link SampleGasPricesService}'s cache is updated.
|
|
28
|
+
*/
|
|
29
|
+
export type SampleGasPricesServiceCacheUpdatedEvent = DataServiceCacheUpdatedEvent<typeof serviceName>;
|
|
30
|
+
/**
|
|
31
|
+
* Published when a key within {@link SampleGasPricesService}'s cache is
|
|
32
|
+
* updated.
|
|
33
|
+
*/
|
|
34
|
+
export type SampleGasPricesServiceGranularCacheUpdatedEvent = DataServiceGranularCacheUpdatedEvent<typeof serviceName>;
|
|
19
35
|
/**
|
|
20
36
|
* Events that {@link SampleGasPricesService} exposes to other consumers.
|
|
21
37
|
*/
|
|
22
|
-
export type SampleGasPricesServiceEvents =
|
|
38
|
+
export type SampleGasPricesServiceEvents = SampleGasPricesServiceCacheUpdatedEvent | SampleGasPricesServiceGranularCacheUpdatedEvent;
|
|
23
39
|
/**
|
|
24
40
|
* Events from other messengers that {@link SampleGasPricesService} subscribes
|
|
25
41
|
* to.
|
|
@@ -31,25 +47,39 @@ type AllowedEvents = never;
|
|
|
31
47
|
*/
|
|
32
48
|
export type SampleGasPricesServiceMessenger = Messenger<typeof serviceName, SampleGasPricesServiceActions | AllowedActions, SampleGasPricesServiceEvents | AllowedEvents>;
|
|
33
49
|
/**
|
|
34
|
-
*
|
|
50
|
+
* Struct to validate what the API endpoint returns.
|
|
35
51
|
*/
|
|
36
|
-
|
|
52
|
+
declare const GasPricesResponseStruct: import("@metamask/superstruct").Struct<{
|
|
37
53
|
data: {
|
|
38
54
|
low: number;
|
|
39
55
|
average: number;
|
|
40
56
|
high: number;
|
|
41
57
|
};
|
|
42
|
-
}
|
|
58
|
+
}, {
|
|
59
|
+
data: import("@metamask/superstruct").Struct<{
|
|
60
|
+
low: number;
|
|
61
|
+
average: number;
|
|
62
|
+
high: number;
|
|
63
|
+
}, {
|
|
64
|
+
low: import("@metamask/superstruct").Struct<number, null>;
|
|
65
|
+
average: import("@metamask/superstruct").Struct<number, null>;
|
|
66
|
+
high: import("@metamask/superstruct").Struct<number, null>;
|
|
67
|
+
}>;
|
|
68
|
+
}>;
|
|
69
|
+
/**
|
|
70
|
+
* What the API endpoint returns.
|
|
71
|
+
*/
|
|
72
|
+
type GasPricesResponse = Infer<typeof GasPricesResponseStruct>;
|
|
43
73
|
/**
|
|
44
74
|
* This service object is responsible for fetching gas prices via an API.
|
|
45
75
|
*
|
|
46
76
|
* @example
|
|
47
77
|
*
|
|
48
78
|
* ``` ts
|
|
79
|
+
* import type { MessengerActions, MessengerEvents } from '@metamask/messenger';
|
|
49
80
|
* import { Messenger } from '@metamask/messenger';
|
|
50
81
|
* import type {
|
|
51
|
-
*
|
|
52
|
-
* SampleGasPricesServiceEvents,
|
|
82
|
+
* SampleGasPricesServiceMessenger,
|
|
53
83
|
* } from '@metamask/sample-controllers';
|
|
54
84
|
*
|
|
55
85
|
* const rootMessenger = new Messenger<
|
|
@@ -59,8 +89,8 @@ type GasPricesResponse = {
|
|
|
59
89
|
* >({ namespace: 'Root' });
|
|
60
90
|
* const gasPricesServiceMessenger = new Messenger<
|
|
61
91
|
* 'SampleGasPricesService',
|
|
62
|
-
*
|
|
63
|
-
*
|
|
92
|
+
* MessengerActions<SampleGasPricesServiceMessenger>,
|
|
93
|
+
* MessengerEvents<SampleGasPricesServiceMessenger>,
|
|
64
94
|
* typeof rootMessenger,
|
|
65
95
|
* >({
|
|
66
96
|
* namespace: 'SampleGasPricesService',
|
|
@@ -69,7 +99,6 @@ type GasPricesResponse = {
|
|
|
69
99
|
* // Instantiate the service to register its actions on the messenger
|
|
70
100
|
* new SampleGasPricesService({
|
|
71
101
|
* messenger: gasPricesServiceMessenger,
|
|
72
|
-
* fetch,
|
|
73
102
|
* });
|
|
74
103
|
*
|
|
75
104
|
* // Later...
|
|
@@ -81,68 +110,22 @@ type GasPricesResponse = {
|
|
|
81
110
|
* // ... Do something with the gas prices ...
|
|
82
111
|
* ```
|
|
83
112
|
*/
|
|
84
|
-
export declare class SampleGasPricesService {
|
|
85
|
-
#private;
|
|
86
|
-
/**
|
|
87
|
-
* The name of the service.
|
|
88
|
-
*/
|
|
89
|
-
readonly name: typeof serviceName;
|
|
113
|
+
export declare class SampleGasPricesService extends BaseDataService<typeof serviceName, SampleGasPricesServiceMessenger> {
|
|
90
114
|
/**
|
|
91
115
|
* Constructs a new SampleGasPricesService object.
|
|
92
116
|
*
|
|
93
117
|
* @param args - The constructor arguments.
|
|
94
118
|
* @param args.messenger - The messenger suited for this service.
|
|
95
|
-
* @param args.
|
|
96
|
-
*
|
|
97
|
-
* to pass that; otherwise you can pass an equivalent (such as `fetch` via
|
|
98
|
-
* `node-fetch`).
|
|
119
|
+
* @param args.queryClientConfig - Configuration for the underlying TanStack
|
|
120
|
+
* Query client.
|
|
99
121
|
* @param args.policyOptions - Options to pass to `createServicePolicy`, which
|
|
100
122
|
* is used to wrap each request. See {@link CreateServicePolicyOptions}.
|
|
101
123
|
*/
|
|
102
|
-
constructor({ messenger,
|
|
124
|
+
constructor({ messenger, queryClientConfig, policyOptions, }: {
|
|
103
125
|
messenger: SampleGasPricesServiceMessenger;
|
|
104
|
-
|
|
126
|
+
queryClientConfig?: QueryClientConfig;
|
|
105
127
|
policyOptions?: CreateServicePolicyOptions;
|
|
106
128
|
});
|
|
107
|
-
/**
|
|
108
|
-
* Registers a handler that will be called after a request returns a non-500
|
|
109
|
-
* response, causing a retry. Primarily useful in tests where timers are being
|
|
110
|
-
* mocked.
|
|
111
|
-
*
|
|
112
|
-
* @param listener - The handler to be called.
|
|
113
|
-
* @returns An object that can be used to unregister the handler. See
|
|
114
|
-
* {@link CockatielEvent}.
|
|
115
|
-
* @see {@link createServicePolicy}
|
|
116
|
-
*/
|
|
117
|
-
onRetry(listener: Parameters<ServicePolicy['onRetry']>[0]): IDisposable;
|
|
118
|
-
/**
|
|
119
|
-
* Registers a handler that will be called after a set number of retry rounds
|
|
120
|
-
* prove that requests to the API endpoint consistently return a 5xx response.
|
|
121
|
-
*
|
|
122
|
-
* @param listener - The handler to be called.
|
|
123
|
-
* @returns An object that can be used to unregister the handler. See
|
|
124
|
-
* {@link CockatielEvent}.
|
|
125
|
-
* @see {@link createServicePolicy}
|
|
126
|
-
*/
|
|
127
|
-
onBreak(listener: Parameters<ServicePolicy['onBreak']>[0]): IDisposable;
|
|
128
|
-
/**
|
|
129
|
-
* Registers a handler that will be called under one of two circumstances:
|
|
130
|
-
*
|
|
131
|
-
* 1. After a set number of retries prove that requests to the API
|
|
132
|
-
* consistently result in one of the following failures:
|
|
133
|
-
* 1. A connection initiation error
|
|
134
|
-
* 2. A connection reset error
|
|
135
|
-
* 3. A timeout error
|
|
136
|
-
* 4. A non-JSON response
|
|
137
|
-
* 5. A 502, 503, or 504 response
|
|
138
|
-
* 2. After a successful request is made to the API, but the response takes
|
|
139
|
-
* longer than a set duration to return.
|
|
140
|
-
*
|
|
141
|
-
* @param listener - The handler to be called.
|
|
142
|
-
* @returns An object that can be used to unregister the handler. See
|
|
143
|
-
* {@link CockatielEvent}.
|
|
144
|
-
*/
|
|
145
|
-
onDegraded(listener: Parameters<ServicePolicy['onDegraded']>[0]): IDisposable;
|
|
146
129
|
/**
|
|
147
130
|
* Makes a request to the API in order to retrieve gas prices for a particular
|
|
148
131
|
* chain.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sample-gas-prices-service.d.cts","sourceRoot":"","sources":["../../src/sample-gas-prices-service/sample-gas-prices-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,
|
|
1
|
+
{"version":3,"file":"sample-gas-prices-service.d.cts","sourceRoot":"","sources":["../../src/sample-gas-prices-service/sample-gas-prices-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,oCAAoC;AAC9D,OAAO,KAAK,EACV,4BAA4B,EAC5B,oCAAoC,EACpC,kCAAkC,EACnC,oCAAoC;AACrC,OAAO,KAAK,EAAE,0BAA0B,EAAE,mCAAmC;AAE7E,OAAO,KAAK,EAAE,SAAS,EAAE,4BAA4B;AACrD,OAAO,KAAK,EAAE,KAAK,EAAE,8BAA8B;AAEnD,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAC3C,OAAO,KAAK,EAAE,iBAAiB,EAAE,6BAA6B;AAE9D,OAAO,KAAK,EAAE,mCAAmC,EAAE,4DAAwD;AAI3G;;;GAGG;AACH,eAAO,MAAM,WAAW,2BAA2B,CAAC;AAUpD;;GAEG;AACH,MAAM,MAAM,6CAA6C,GACvD,kCAAkC,CAAC,OAAO,WAAW,CAAC,CAAC;AAEzD;;GAEG;AACH,MAAM,MAAM,6BAA6B,GACrC,mCAAmC,GACnC,6CAA6C,CAAC;AAElD;;GAEG;AACH,KAAK,cAAc,GAAG,KAAK,CAAC;AAE5B;;GAEG;AACH,MAAM,MAAM,uCAAuC,GACjD,4BAA4B,CAAC,OAAO,WAAW,CAAC,CAAC;AAEnD;;;GAGG;AACH,MAAM,MAAM,+CAA+C,GACzD,oCAAoC,CAAC,OAAO,WAAW,CAAC,CAAC;AAE3D;;GAEG;AACH,MAAM,MAAM,4BAA4B,GACpC,uCAAuC,GACvC,+CAA+C,CAAC;AAEpD;;;GAGG;AACH,KAAK,aAAa,GAAG,KAAK,CAAC;AAE3B;;;GAGG;AACH,MAAM,MAAM,+BAA+B,GAAG,SAAS,CACrD,OAAO,WAAW,EAClB,6BAA6B,GAAG,cAAc,EAC9C,4BAA4B,GAAG,aAAa,CAC7C,CAAC;AAIF;;GAEG;AACH,QAAA,MAAM,uBAAuB;;;;;;;;;;;;;;;;EAM3B,CAAC;AAEH;;GAEG;AACH,KAAK,iBAAiB,GAAG,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAO/D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,qBAAa,sBAAuB,SAAQ,eAAe,CACzD,OAAO,WAAW,EAClB,+BAA+B,CAChC;IACC;;;;;;;;;OASG;gBACS,EACV,SAAS,EACT,iBAAsB,EACtB,aAAkB,GACnB,EAAE;QACD,SAAS,EAAE,+BAA+B,CAAC;QAC3C,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;QACtC,aAAa,CAAC,EAAE,0BAA0B,CAAC;KAC5C;IAcD;;;;;;OAMG;IACG,cAAc,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;CA0BvE"}
|
|
@@ -1,25 +1,41 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { BaseDataService } from "@metamask/base-data-service";
|
|
2
|
+
import type { DataServiceCacheUpdatedEvent, DataServiceGranularCacheUpdatedEvent, DataServiceInvalidateQueriesAction } from "@metamask/base-data-service";
|
|
3
|
+
import type { CreateServicePolicyOptions } from "@metamask/controller-utils";
|
|
2
4
|
import type { Messenger } from "@metamask/messenger";
|
|
5
|
+
import type { Infer } from "@metamask/superstruct";
|
|
3
6
|
import type { Hex } from "@metamask/utils";
|
|
4
|
-
import type {
|
|
7
|
+
import type { QueryClientConfig } from "@tanstack/query-core";
|
|
5
8
|
import type { SampleGasPricesServiceMethodActions } from "./sample-gas-prices-service-method-action-types.mjs";
|
|
6
9
|
/**
|
|
7
10
|
* The name of the {@link SampleGasPricesService}, used to namespace the
|
|
8
11
|
* service's actions and events.
|
|
9
12
|
*/
|
|
10
13
|
export declare const serviceName = "SampleGasPricesService";
|
|
14
|
+
/**
|
|
15
|
+
* Invalidates cached queries for {@link SampleGasPricesService}.
|
|
16
|
+
*/
|
|
17
|
+
export type SampleGasPricesServiceInvalidateQueriesAction = DataServiceInvalidateQueriesAction<typeof serviceName>;
|
|
11
18
|
/**
|
|
12
19
|
* Actions that {@link SampleGasPricesService} exposes to other consumers.
|
|
13
20
|
*/
|
|
14
|
-
export type SampleGasPricesServiceActions = SampleGasPricesServiceMethodActions;
|
|
21
|
+
export type SampleGasPricesServiceActions = SampleGasPricesServiceMethodActions | SampleGasPricesServiceInvalidateQueriesAction;
|
|
15
22
|
/**
|
|
16
|
-
* Actions from other messengers that {@link
|
|
23
|
+
* Actions from other messengers that {@link SampleGasPricesService} calls.
|
|
17
24
|
*/
|
|
18
25
|
type AllowedActions = never;
|
|
26
|
+
/**
|
|
27
|
+
* Published when {@link SampleGasPricesService}'s cache is updated.
|
|
28
|
+
*/
|
|
29
|
+
export type SampleGasPricesServiceCacheUpdatedEvent = DataServiceCacheUpdatedEvent<typeof serviceName>;
|
|
30
|
+
/**
|
|
31
|
+
* Published when a key within {@link SampleGasPricesService}'s cache is
|
|
32
|
+
* updated.
|
|
33
|
+
*/
|
|
34
|
+
export type SampleGasPricesServiceGranularCacheUpdatedEvent = DataServiceGranularCacheUpdatedEvent<typeof serviceName>;
|
|
19
35
|
/**
|
|
20
36
|
* Events that {@link SampleGasPricesService} exposes to other consumers.
|
|
21
37
|
*/
|
|
22
|
-
export type SampleGasPricesServiceEvents =
|
|
38
|
+
export type SampleGasPricesServiceEvents = SampleGasPricesServiceCacheUpdatedEvent | SampleGasPricesServiceGranularCacheUpdatedEvent;
|
|
23
39
|
/**
|
|
24
40
|
* Events from other messengers that {@link SampleGasPricesService} subscribes
|
|
25
41
|
* to.
|
|
@@ -31,25 +47,39 @@ type AllowedEvents = never;
|
|
|
31
47
|
*/
|
|
32
48
|
export type SampleGasPricesServiceMessenger = Messenger<typeof serviceName, SampleGasPricesServiceActions | AllowedActions, SampleGasPricesServiceEvents | AllowedEvents>;
|
|
33
49
|
/**
|
|
34
|
-
*
|
|
50
|
+
* Struct to validate what the API endpoint returns.
|
|
35
51
|
*/
|
|
36
|
-
|
|
52
|
+
declare const GasPricesResponseStruct: import("@metamask/superstruct").Struct<{
|
|
37
53
|
data: {
|
|
38
54
|
low: number;
|
|
39
55
|
average: number;
|
|
40
56
|
high: number;
|
|
41
57
|
};
|
|
42
|
-
}
|
|
58
|
+
}, {
|
|
59
|
+
data: import("@metamask/superstruct").Struct<{
|
|
60
|
+
low: number;
|
|
61
|
+
average: number;
|
|
62
|
+
high: number;
|
|
63
|
+
}, {
|
|
64
|
+
low: import("@metamask/superstruct").Struct<number, null>;
|
|
65
|
+
average: import("@metamask/superstruct").Struct<number, null>;
|
|
66
|
+
high: import("@metamask/superstruct").Struct<number, null>;
|
|
67
|
+
}>;
|
|
68
|
+
}>;
|
|
69
|
+
/**
|
|
70
|
+
* What the API endpoint returns.
|
|
71
|
+
*/
|
|
72
|
+
type GasPricesResponse = Infer<typeof GasPricesResponseStruct>;
|
|
43
73
|
/**
|
|
44
74
|
* This service object is responsible for fetching gas prices via an API.
|
|
45
75
|
*
|
|
46
76
|
* @example
|
|
47
77
|
*
|
|
48
78
|
* ``` ts
|
|
79
|
+
* import type { MessengerActions, MessengerEvents } from '@metamask/messenger';
|
|
49
80
|
* import { Messenger } from '@metamask/messenger';
|
|
50
81
|
* import type {
|
|
51
|
-
*
|
|
52
|
-
* SampleGasPricesServiceEvents,
|
|
82
|
+
* SampleGasPricesServiceMessenger,
|
|
53
83
|
* } from '@metamask/sample-controllers';
|
|
54
84
|
*
|
|
55
85
|
* const rootMessenger = new Messenger<
|
|
@@ -59,8 +89,8 @@ type GasPricesResponse = {
|
|
|
59
89
|
* >({ namespace: 'Root' });
|
|
60
90
|
* const gasPricesServiceMessenger = new Messenger<
|
|
61
91
|
* 'SampleGasPricesService',
|
|
62
|
-
*
|
|
63
|
-
*
|
|
92
|
+
* MessengerActions<SampleGasPricesServiceMessenger>,
|
|
93
|
+
* MessengerEvents<SampleGasPricesServiceMessenger>,
|
|
64
94
|
* typeof rootMessenger,
|
|
65
95
|
* >({
|
|
66
96
|
* namespace: 'SampleGasPricesService',
|
|
@@ -69,7 +99,6 @@ type GasPricesResponse = {
|
|
|
69
99
|
* // Instantiate the service to register its actions on the messenger
|
|
70
100
|
* new SampleGasPricesService({
|
|
71
101
|
* messenger: gasPricesServiceMessenger,
|
|
72
|
-
* fetch,
|
|
73
102
|
* });
|
|
74
103
|
*
|
|
75
104
|
* // Later...
|
|
@@ -81,68 +110,22 @@ type GasPricesResponse = {
|
|
|
81
110
|
* // ... Do something with the gas prices ...
|
|
82
111
|
* ```
|
|
83
112
|
*/
|
|
84
|
-
export declare class SampleGasPricesService {
|
|
85
|
-
#private;
|
|
86
|
-
/**
|
|
87
|
-
* The name of the service.
|
|
88
|
-
*/
|
|
89
|
-
readonly name: typeof serviceName;
|
|
113
|
+
export declare class SampleGasPricesService extends BaseDataService<typeof serviceName, SampleGasPricesServiceMessenger> {
|
|
90
114
|
/**
|
|
91
115
|
* Constructs a new SampleGasPricesService object.
|
|
92
116
|
*
|
|
93
117
|
* @param args - The constructor arguments.
|
|
94
118
|
* @param args.messenger - The messenger suited for this service.
|
|
95
|
-
* @param args.
|
|
96
|
-
*
|
|
97
|
-
* to pass that; otherwise you can pass an equivalent (such as `fetch` via
|
|
98
|
-
* `node-fetch`).
|
|
119
|
+
* @param args.queryClientConfig - Configuration for the underlying TanStack
|
|
120
|
+
* Query client.
|
|
99
121
|
* @param args.policyOptions - Options to pass to `createServicePolicy`, which
|
|
100
122
|
* is used to wrap each request. See {@link CreateServicePolicyOptions}.
|
|
101
123
|
*/
|
|
102
|
-
constructor({ messenger,
|
|
124
|
+
constructor({ messenger, queryClientConfig, policyOptions, }: {
|
|
103
125
|
messenger: SampleGasPricesServiceMessenger;
|
|
104
|
-
|
|
126
|
+
queryClientConfig?: QueryClientConfig;
|
|
105
127
|
policyOptions?: CreateServicePolicyOptions;
|
|
106
128
|
});
|
|
107
|
-
/**
|
|
108
|
-
* Registers a handler that will be called after a request returns a non-500
|
|
109
|
-
* response, causing a retry. Primarily useful in tests where timers are being
|
|
110
|
-
* mocked.
|
|
111
|
-
*
|
|
112
|
-
* @param listener - The handler to be called.
|
|
113
|
-
* @returns An object that can be used to unregister the handler. See
|
|
114
|
-
* {@link CockatielEvent}.
|
|
115
|
-
* @see {@link createServicePolicy}
|
|
116
|
-
*/
|
|
117
|
-
onRetry(listener: Parameters<ServicePolicy['onRetry']>[0]): IDisposable;
|
|
118
|
-
/**
|
|
119
|
-
* Registers a handler that will be called after a set number of retry rounds
|
|
120
|
-
* prove that requests to the API endpoint consistently return a 5xx response.
|
|
121
|
-
*
|
|
122
|
-
* @param listener - The handler to be called.
|
|
123
|
-
* @returns An object that can be used to unregister the handler. See
|
|
124
|
-
* {@link CockatielEvent}.
|
|
125
|
-
* @see {@link createServicePolicy}
|
|
126
|
-
*/
|
|
127
|
-
onBreak(listener: Parameters<ServicePolicy['onBreak']>[0]): IDisposable;
|
|
128
|
-
/**
|
|
129
|
-
* Registers a handler that will be called under one of two circumstances:
|
|
130
|
-
*
|
|
131
|
-
* 1. After a set number of retries prove that requests to the API
|
|
132
|
-
* consistently result in one of the following failures:
|
|
133
|
-
* 1. A connection initiation error
|
|
134
|
-
* 2. A connection reset error
|
|
135
|
-
* 3. A timeout error
|
|
136
|
-
* 4. A non-JSON response
|
|
137
|
-
* 5. A 502, 503, or 504 response
|
|
138
|
-
* 2. After a successful request is made to the API, but the response takes
|
|
139
|
-
* longer than a set duration to return.
|
|
140
|
-
*
|
|
141
|
-
* @param listener - The handler to be called.
|
|
142
|
-
* @returns An object that can be used to unregister the handler. See
|
|
143
|
-
* {@link CockatielEvent}.
|
|
144
|
-
*/
|
|
145
|
-
onDegraded(listener: Parameters<ServicePolicy['onDegraded']>[0]): IDisposable;
|
|
146
129
|
/**
|
|
147
130
|
* Makes a request to the API in order to retrieve gas prices for a particular
|
|
148
131
|
* chain.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sample-gas-prices-service.d.mts","sourceRoot":"","sources":["../../src/sample-gas-prices-service/sample-gas-prices-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,
|
|
1
|
+
{"version":3,"file":"sample-gas-prices-service.d.mts","sourceRoot":"","sources":["../../src/sample-gas-prices-service/sample-gas-prices-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,oCAAoC;AAC9D,OAAO,KAAK,EACV,4BAA4B,EAC5B,oCAAoC,EACpC,kCAAkC,EACnC,oCAAoC;AACrC,OAAO,KAAK,EAAE,0BAA0B,EAAE,mCAAmC;AAE7E,OAAO,KAAK,EAAE,SAAS,EAAE,4BAA4B;AACrD,OAAO,KAAK,EAAE,KAAK,EAAE,8BAA8B;AAEnD,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAC3C,OAAO,KAAK,EAAE,iBAAiB,EAAE,6BAA6B;AAE9D,OAAO,KAAK,EAAE,mCAAmC,EAAE,4DAAwD;AAI3G;;;GAGG;AACH,eAAO,MAAM,WAAW,2BAA2B,CAAC;AAUpD;;GAEG;AACH,MAAM,MAAM,6CAA6C,GACvD,kCAAkC,CAAC,OAAO,WAAW,CAAC,CAAC;AAEzD;;GAEG;AACH,MAAM,MAAM,6BAA6B,GACrC,mCAAmC,GACnC,6CAA6C,CAAC;AAElD;;GAEG;AACH,KAAK,cAAc,GAAG,KAAK,CAAC;AAE5B;;GAEG;AACH,MAAM,MAAM,uCAAuC,GACjD,4BAA4B,CAAC,OAAO,WAAW,CAAC,CAAC;AAEnD;;;GAGG;AACH,MAAM,MAAM,+CAA+C,GACzD,oCAAoC,CAAC,OAAO,WAAW,CAAC,CAAC;AAE3D;;GAEG;AACH,MAAM,MAAM,4BAA4B,GACpC,uCAAuC,GACvC,+CAA+C,CAAC;AAEpD;;;GAGG;AACH,KAAK,aAAa,GAAG,KAAK,CAAC;AAE3B;;;GAGG;AACH,MAAM,MAAM,+BAA+B,GAAG,SAAS,CACrD,OAAO,WAAW,EAClB,6BAA6B,GAAG,cAAc,EAC9C,4BAA4B,GAAG,aAAa,CAC7C,CAAC;AAIF;;GAEG;AACH,QAAA,MAAM,uBAAuB;;;;;;;;;;;;;;;;EAM3B,CAAC;AAEH;;GAEG;AACH,KAAK,iBAAiB,GAAG,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAO/D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,qBAAa,sBAAuB,SAAQ,eAAe,CACzD,OAAO,WAAW,EAClB,+BAA+B,CAChC;IACC;;;;;;;;;OASG;gBACS,EACV,SAAS,EACT,iBAAsB,EACtB,aAAkB,GACnB,EAAE;QACD,SAAS,EAAE,+BAA+B,CAAC;QAC3C,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;QACtC,aAAa,CAAC,EAAE,0BAA0B,CAAC;KAC5C;IAcD;;;;;;OAMG;IACG,cAAc,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;CA0BvE"}
|
|
@@ -1,17 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
5
|
-
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
6
|
-
};
|
|
7
|
-
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
8
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
9
|
-
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
10
|
-
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
|
-
};
|
|
12
|
-
var _a, _SampleGasPricesService_messenger, _SampleGasPricesService_fetch, _SampleGasPricesService_policy;
|
|
13
|
-
import { createServicePolicy, fromHex, HttpError } from "@metamask/controller-utils";
|
|
14
|
-
import { hasProperty, isPlainObject } from "@metamask/utils";
|
|
1
|
+
import { BaseDataService } from "@metamask/base-data-service";
|
|
2
|
+
import { HttpError, fromHex } from "@metamask/controller-utils";
|
|
3
|
+
import { is, number, type } from "@metamask/superstruct";
|
|
15
4
|
// === GENERAL ===
|
|
16
5
|
/**
|
|
17
6
|
* The name of the {@link SampleGasPricesService}, used to namespace the
|
|
@@ -19,17 +8,36 @@ import { hasProperty, isPlainObject } from "@metamask/utils";
|
|
|
19
8
|
*/
|
|
20
9
|
export const serviceName = 'SampleGasPricesService';
|
|
21
10
|
// === MESSENGER ===
|
|
11
|
+
/**
|
|
12
|
+
* All of the methods within {@link SampleGasPricesService} that are exposed via
|
|
13
|
+
* the messenger.
|
|
14
|
+
*/
|
|
22
15
|
const MESSENGER_EXPOSED_METHODS = ['fetchGasPrices'];
|
|
16
|
+
// === SERVICE DEFINITION ===
|
|
17
|
+
/**
|
|
18
|
+
* Struct to validate what the API endpoint returns.
|
|
19
|
+
*/
|
|
20
|
+
const GasPricesResponseStruct = type({
|
|
21
|
+
data: type({
|
|
22
|
+
low: number(),
|
|
23
|
+
average: number(),
|
|
24
|
+
high: number(),
|
|
25
|
+
}),
|
|
26
|
+
});
|
|
27
|
+
/**
|
|
28
|
+
* The base URL of the API that the service represents.
|
|
29
|
+
*/
|
|
30
|
+
const BASE_URL = 'https://api.example.com';
|
|
23
31
|
/**
|
|
24
32
|
* This service object is responsible for fetching gas prices via an API.
|
|
25
33
|
*
|
|
26
34
|
* @example
|
|
27
35
|
*
|
|
28
36
|
* ``` ts
|
|
37
|
+
* import type { MessengerActions, MessengerEvents } from '@metamask/messenger';
|
|
29
38
|
* import { Messenger } from '@metamask/messenger';
|
|
30
39
|
* import type {
|
|
31
|
-
*
|
|
32
|
-
* SampleGasPricesServiceEvents,
|
|
40
|
+
* SampleGasPricesServiceMessenger,
|
|
33
41
|
* } from '@metamask/sample-controllers';
|
|
34
42
|
*
|
|
35
43
|
* const rootMessenger = new Messenger<
|
|
@@ -39,8 +47,8 @@ const MESSENGER_EXPOSED_METHODS = ['fetchGasPrices'];
|
|
|
39
47
|
* >({ namespace: 'Root' });
|
|
40
48
|
* const gasPricesServiceMessenger = new Messenger<
|
|
41
49
|
* 'SampleGasPricesService',
|
|
42
|
-
*
|
|
43
|
-
*
|
|
50
|
+
* MessengerActions<SampleGasPricesServiceMessenger>,
|
|
51
|
+
* MessengerEvents<SampleGasPricesServiceMessenger>,
|
|
44
52
|
* typeof rootMessenger,
|
|
45
53
|
* >({
|
|
46
54
|
* namespace: 'SampleGasPricesService',
|
|
@@ -49,7 +57,6 @@ const MESSENGER_EXPOSED_METHODS = ['fetchGasPrices'];
|
|
|
49
57
|
* // Instantiate the service to register its actions on the messenger
|
|
50
58
|
* new SampleGasPricesService({
|
|
51
59
|
* messenger: gasPricesServiceMessenger,
|
|
52
|
-
* fetch,
|
|
53
60
|
* });
|
|
54
61
|
*
|
|
55
62
|
* // Later...
|
|
@@ -61,84 +68,25 @@ const MESSENGER_EXPOSED_METHODS = ['fetchGasPrices'];
|
|
|
61
68
|
* // ... Do something with the gas prices ...
|
|
62
69
|
* ```
|
|
63
70
|
*/
|
|
64
|
-
export class SampleGasPricesService {
|
|
71
|
+
export class SampleGasPricesService extends BaseDataService {
|
|
65
72
|
/**
|
|
66
73
|
* Constructs a new SampleGasPricesService object.
|
|
67
74
|
*
|
|
68
75
|
* @param args - The constructor arguments.
|
|
69
76
|
* @param args.messenger - The messenger suited for this service.
|
|
70
|
-
* @param args.
|
|
71
|
-
*
|
|
72
|
-
* to pass that; otherwise you can pass an equivalent (such as `fetch` via
|
|
73
|
-
* `node-fetch`).
|
|
77
|
+
* @param args.queryClientConfig - Configuration for the underlying TanStack
|
|
78
|
+
* Query client.
|
|
74
79
|
* @param args.policyOptions - Options to pass to `createServicePolicy`, which
|
|
75
80
|
* is used to wrap each request. See {@link CreateServicePolicyOptions}.
|
|
76
81
|
*/
|
|
77
|
-
constructor({ messenger,
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
_SampleGasPricesService_fetch.set(this, void 0);
|
|
86
|
-
/**
|
|
87
|
-
* The policy that wraps the request.
|
|
88
|
-
*
|
|
89
|
-
* @see {@link createServicePolicy}
|
|
90
|
-
*/
|
|
91
|
-
_SampleGasPricesService_policy.set(this, void 0);
|
|
92
|
-
this.name = serviceName;
|
|
93
|
-
__classPrivateFieldSet(this, _SampleGasPricesService_messenger, messenger, "f");
|
|
94
|
-
__classPrivateFieldSet(this, _SampleGasPricesService_fetch, fetchFunction, "f");
|
|
95
|
-
__classPrivateFieldSet(this, _SampleGasPricesService_policy, createServicePolicy(policyOptions), "f");
|
|
96
|
-
__classPrivateFieldGet(this, _SampleGasPricesService_messenger, "f").registerMethodActionHandlers(this, MESSENGER_EXPOSED_METHODS);
|
|
97
|
-
}
|
|
98
|
-
/**
|
|
99
|
-
* Registers a handler that will be called after a request returns a non-500
|
|
100
|
-
* response, causing a retry. Primarily useful in tests where timers are being
|
|
101
|
-
* mocked.
|
|
102
|
-
*
|
|
103
|
-
* @param listener - The handler to be called.
|
|
104
|
-
* @returns An object that can be used to unregister the handler. See
|
|
105
|
-
* {@link CockatielEvent}.
|
|
106
|
-
* @see {@link createServicePolicy}
|
|
107
|
-
*/
|
|
108
|
-
onRetry(listener) {
|
|
109
|
-
return __classPrivateFieldGet(this, _SampleGasPricesService_policy, "f").onRetry(listener);
|
|
110
|
-
}
|
|
111
|
-
/**
|
|
112
|
-
* Registers a handler that will be called after a set number of retry rounds
|
|
113
|
-
* prove that requests to the API endpoint consistently return a 5xx response.
|
|
114
|
-
*
|
|
115
|
-
* @param listener - The handler to be called.
|
|
116
|
-
* @returns An object that can be used to unregister the handler. See
|
|
117
|
-
* {@link CockatielEvent}.
|
|
118
|
-
* @see {@link createServicePolicy}
|
|
119
|
-
*/
|
|
120
|
-
onBreak(listener) {
|
|
121
|
-
return __classPrivateFieldGet(this, _SampleGasPricesService_policy, "f").onBreak(listener);
|
|
122
|
-
}
|
|
123
|
-
/**
|
|
124
|
-
* Registers a handler that will be called under one of two circumstances:
|
|
125
|
-
*
|
|
126
|
-
* 1. After a set number of retries prove that requests to the API
|
|
127
|
-
* consistently result in one of the following failures:
|
|
128
|
-
* 1. A connection initiation error
|
|
129
|
-
* 2. A connection reset error
|
|
130
|
-
* 3. A timeout error
|
|
131
|
-
* 4. A non-JSON response
|
|
132
|
-
* 5. A 502, 503, or 504 response
|
|
133
|
-
* 2. After a successful request is made to the API, but the response takes
|
|
134
|
-
* longer than a set duration to return.
|
|
135
|
-
*
|
|
136
|
-
* @param listener - The handler to be called.
|
|
137
|
-
* @returns An object that can be used to unregister the handler. See
|
|
138
|
-
* {@link CockatielEvent}.
|
|
139
|
-
*/
|
|
140
|
-
onDegraded(listener) {
|
|
141
|
-
return __classPrivateFieldGet(this, _SampleGasPricesService_policy, "f").onDegraded(listener);
|
|
82
|
+
constructor({ messenger, queryClientConfig = {}, policyOptions = {}, }) {
|
|
83
|
+
super({
|
|
84
|
+
name: serviceName,
|
|
85
|
+
messenger,
|
|
86
|
+
queryClientConfig,
|
|
87
|
+
policyOptions,
|
|
88
|
+
});
|
|
89
|
+
this.messenger.registerMethodActionHandlers(this, MESSENGER_EXPOSED_METHODS);
|
|
142
90
|
}
|
|
143
91
|
/**
|
|
144
92
|
* Makes a request to the API in order to retrieve gas prices for a particular
|
|
@@ -148,31 +96,22 @@ export class SampleGasPricesService {
|
|
|
148
96
|
* @returns The gas prices for the given chain.
|
|
149
97
|
*/
|
|
150
98
|
async fetchGasPrices(chainId) {
|
|
151
|
-
const
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
99
|
+
const url = new URL('/gas-prices', BASE_URL);
|
|
100
|
+
url.searchParams.append('chainId', `eip155:${fromHex(chainId).toString()}`);
|
|
101
|
+
const jsonResponse = await this.fetchQuery({
|
|
102
|
+
queryKey: [`${this.name}:fetchGasPrices`, chainId],
|
|
103
|
+
queryFn: async () => {
|
|
104
|
+
const response = await fetch(url);
|
|
105
|
+
if (!response.ok) {
|
|
106
|
+
throw new HttpError(response.status, `Gas prices API failed with status '${response.status}'`);
|
|
107
|
+
}
|
|
108
|
+
return response.json();
|
|
109
|
+
},
|
|
159
110
|
});
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
hasProperty(jsonResponse, 'data') &&
|
|
163
|
-
isPlainObject(jsonResponse.data) &&
|
|
164
|
-
hasProperty(jsonResponse.data, 'low') &&
|
|
165
|
-
hasProperty(jsonResponse.data, 'average') &&
|
|
166
|
-
hasProperty(jsonResponse.data, 'high')) {
|
|
167
|
-
const { data: { low, average, high }, } = jsonResponse;
|
|
168
|
-
if (typeof low === 'number' &&
|
|
169
|
-
typeof average === 'number' &&
|
|
170
|
-
typeof high === 'number') {
|
|
171
|
-
return { low, average, high };
|
|
172
|
-
}
|
|
111
|
+
if (!is(jsonResponse, GasPricesResponseStruct)) {
|
|
112
|
+
throw new Error('Malformed response received from gas prices API');
|
|
173
113
|
}
|
|
174
|
-
|
|
114
|
+
return jsonResponse.data;
|
|
175
115
|
}
|
|
176
116
|
}
|
|
177
|
-
_a = SampleGasPricesService, _SampleGasPricesService_messenger = new WeakMap(), _SampleGasPricesService_fetch = new WeakMap(), _SampleGasPricesService_policy = new WeakMap();
|
|
178
117
|
//# sourceMappingURL=sample-gas-prices-service.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sample-gas-prices-service.mjs","sourceRoot":"","sources":["../../src/sample-gas-prices-service/sample-gas-prices-service.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n CreateServicePolicyOptions,\n ServicePolicy,\n} from '@metamask/controller-utils';\nimport {\n createServicePolicy,\n fromHex,\n HttpError,\n} from '@metamask/controller-utils';\nimport type { Messenger } from '@metamask/messenger';\nimport { hasProperty, isPlainObject } from '@metamask/utils';\nimport type { Hex } from '@metamask/utils';\nimport type { IDisposable } from 'cockatiel';\n\nimport type { SampleGasPricesServiceMethodActions } from './sample-gas-prices-service-method-action-types';\n\n// === GENERAL ===\n\n/**\n * The name of the {@link SampleGasPricesService}, used to namespace the\n * service's actions and events.\n */\nexport const serviceName = 'SampleGasPricesService';\n\n// === MESSENGER ===\n\nconst MESSENGER_EXPOSED_METHODS = ['fetchGasPrices'] as const;\n\n/**\n * Actions that {@link SampleGasPricesService} exposes to other consumers.\n */\nexport type SampleGasPricesServiceActions = SampleGasPricesServiceMethodActions;\n\n/**\n * Actions from other messengers that {@link SampleGasPricesMessenger} calls.\n */\ntype AllowedActions = never;\n\n/**\n * Events that {@link SampleGasPricesService} exposes to other consumers.\n */\nexport type SampleGasPricesServiceEvents = never;\n\n/**\n * Events from other messengers that {@link SampleGasPricesService} subscribes\n * to.\n */\ntype AllowedEvents = never;\n\n/**\n * The messenger which is restricted to actions and events accessed by\n * {@link SampleGasPricesService}.\n */\nexport type SampleGasPricesServiceMessenger = Messenger<\n typeof serviceName,\n SampleGasPricesServiceActions | AllowedActions,\n SampleGasPricesServiceEvents | AllowedEvents\n>;\n\n// === SERVICE DEFINITION ===\n\n/**\n * What the API endpoint returns.\n */\ntype GasPricesResponse = {\n data: {\n low: number;\n average: number;\n high: number;\n };\n};\n\n/**\n * This service object is responsible for fetching gas prices via an API.\n *\n * @example\n *\n * ``` ts\n * import { Messenger } from '@metamask/messenger';\n * import type {\n * SampleGasPricesServiceActions,\n * SampleGasPricesServiceEvents,\n * } from '@metamask/sample-controllers';\n *\n * const rootMessenger = new Messenger<\n * 'Root',\n * SampleGasPricesServiceActions\n * SampleGasPricesServiceEvents\n * >({ namespace: 'Root' });\n * const gasPricesServiceMessenger = new Messenger<\n * 'SampleGasPricesService',\n * SampleGasPricesServiceActions,\n * SampleGasPricesServiceEvents,\n * typeof rootMessenger,\n * >({\n * namespace: 'SampleGasPricesService',\n * parent: rootMessenger,\n * });\n * // Instantiate the service to register its actions on the messenger\n * new SampleGasPricesService({\n * messenger: gasPricesServiceMessenger,\n * fetch,\n * });\n *\n * // Later...\n * // Fetch gas prices for Mainnet\n * const gasPrices = await rootMessenger.call(\n * 'SampleGasPricesService:fetchGasPrices',\n * '0x1',\n * );\n * // ... Do something with the gas prices ...\n * ```\n */\nexport class SampleGasPricesService {\n /**\n * The name of the service.\n */\n readonly name: typeof serviceName;\n\n /**\n * The messenger suited for this service.\n */\n readonly #messenger: ConstructorParameters<\n typeof SampleGasPricesService\n >[0]['messenger'];\n\n /**\n * A function that can be used to make an HTTP request.\n */\n readonly #fetch: ConstructorParameters<\n typeof SampleGasPricesService\n >[0]['fetch'];\n\n /**\n * The policy that wraps the request.\n *\n * @see {@link createServicePolicy}\n */\n readonly #policy: ServicePolicy;\n\n /**\n * Constructs a new SampleGasPricesService object.\n *\n * @param args - The constructor arguments.\n * @param args.messenger - The messenger suited for this service.\n * @param args.fetch - A function that can be used to make an HTTP request. If\n * your JavaScript environment supports `fetch` natively, you'll probably want\n * to pass that; otherwise you can pass an equivalent (such as `fetch` via\n * `node-fetch`).\n * @param args.policyOptions - Options to pass to `createServicePolicy`, which\n * is used to wrap each request. See {@link CreateServicePolicyOptions}.\n */\n constructor({\n messenger,\n fetch: fetchFunction,\n policyOptions = {},\n }: {\n messenger: SampleGasPricesServiceMessenger;\n fetch: typeof fetch;\n policyOptions?: CreateServicePolicyOptions;\n }) {\n this.name = serviceName;\n this.#messenger = messenger;\n this.#fetch = fetchFunction;\n this.#policy = createServicePolicy(policyOptions);\n\n this.#messenger.registerMethodActionHandlers(\n this,\n MESSENGER_EXPOSED_METHODS,\n );\n }\n\n /**\n * Registers a handler that will be called after a request returns a non-500\n * response, causing a retry. Primarily useful in tests where timers are being\n * mocked.\n *\n * @param listener - The handler to be called.\n * @returns An object that can be used to unregister the handler. See\n * {@link CockatielEvent}.\n * @see {@link createServicePolicy}\n */\n onRetry(listener: Parameters<ServicePolicy['onRetry']>[0]): IDisposable {\n return this.#policy.onRetry(listener);\n }\n\n /**\n * Registers a handler that will be called after a set number of retry rounds\n * prove that requests to the API endpoint consistently return a 5xx response.\n *\n * @param listener - The handler to be called.\n * @returns An object that can be used to unregister the handler. See\n * {@link CockatielEvent}.\n * @see {@link createServicePolicy}\n */\n onBreak(listener: Parameters<ServicePolicy['onBreak']>[0]): IDisposable {\n return this.#policy.onBreak(listener);\n }\n\n /**\n * Registers a handler that will be called under one of two circumstances:\n *\n * 1. After a set number of retries prove that requests to the API\n * consistently result in one of the following failures:\n * 1. A connection initiation error\n * 2. A connection reset error\n * 3. A timeout error\n * 4. A non-JSON response\n * 5. A 502, 503, or 504 response\n * 2. After a successful request is made to the API, but the response takes\n * longer than a set duration to return.\n *\n * @param listener - The handler to be called.\n * @returns An object that can be used to unregister the handler. See\n * {@link CockatielEvent}.\n */\n onDegraded(\n listener: Parameters<ServicePolicy['onDegraded']>[0],\n ): IDisposable {\n return this.#policy.onDegraded(listener);\n }\n\n /**\n * Makes a request to the API in order to retrieve gas prices for a particular\n * chain.\n *\n * @param chainId - The chain ID for which you want to fetch gas prices.\n * @returns The gas prices for the given chain.\n */\n async fetchGasPrices(chainId: Hex): Promise<GasPricesResponse['data']> {\n const response = await this.#policy.execute(async () => {\n const url = new URL('https://api.example.com/gas-prices');\n url.searchParams.append(\n 'chainId',\n `eip155:${fromHex(chainId).toString()}`,\n );\n const localResponse = await this.#fetch(url);\n if (!localResponse.ok) {\n throw new HttpError(\n localResponse.status,\n `Fetching '${url.toString()}' failed with status '${localResponse.status}'`,\n );\n }\n return localResponse;\n });\n const jsonResponse = await response.json();\n\n if (\n isPlainObject(jsonResponse) &&\n hasProperty(jsonResponse, 'data') &&\n isPlainObject(jsonResponse.data) &&\n hasProperty(jsonResponse.data, 'low') &&\n hasProperty(jsonResponse.data, 'average') &&\n hasProperty(jsonResponse.data, 'high')\n ) {\n const {\n data: { low, average, high },\n } = jsonResponse;\n if (\n typeof low === 'number' &&\n typeof average === 'number' &&\n typeof high === 'number'\n ) {\n return { low, average, high };\n }\n }\n\n throw new Error('Malformed response received from gas prices API');\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"sample-gas-prices-service.mjs","sourceRoot":"","sources":["../../src/sample-gas-prices-service/sample-gas-prices-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,oCAAoC;AAO9D,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,mCAAmC;AAGhE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,8BAA8B;AAMzD,kBAAkB;AAElB;;;GAGG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,wBAAwB,CAAC;AAEpD,oBAAoB;AAEpB;;;GAGG;AACH,MAAM,yBAAyB,GAAG,CAAC,gBAAgB,CAAU,CAAC;AAwD9D,6BAA6B;AAE7B;;GAEG;AACH,MAAM,uBAAuB,GAAG,IAAI,CAAC;IACnC,IAAI,EAAE,IAAI,CAAC;QACT,GAAG,EAAE,MAAM,EAAE;QACb,OAAO,EAAE,MAAM,EAAE;QACjB,IAAI,EAAE,MAAM,EAAE;KACf,CAAC;CACH,CAAC,CAAC;AAOH;;GAEG;AACH,MAAM,QAAQ,GAAG,yBAAyB,CAAC;AAE3C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,MAAM,OAAO,sBAAuB,SAAQ,eAG3C;IACC;;;;;;;;;OASG;IACH,YAAY,EACV,SAAS,EACT,iBAAiB,GAAG,EAAE,EACtB,aAAa,GAAG,EAAE,GAKnB;QACC,KAAK,CAAC;YACJ,IAAI,EAAE,WAAW;YACjB,SAAS;YACT,iBAAiB;YACjB,aAAa;SACd,CAAC,CAAC;QAEH,IAAI,CAAC,SAAS,CAAC,4BAA4B,CACzC,IAAI,EACJ,yBAAyB,CAC1B,CAAC;IACJ,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,cAAc,CAAC,OAAY;QAC/B,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;QAC7C,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,SAAS,EAAE,UAAU,OAAO,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAE5E,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC;YACzC,QAAQ,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,iBAAiB,EAAE,OAAO,CAAC;YAClD,OAAO,EAAE,KAAK,IAAI,EAAE;gBAClB,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;gBAElC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;oBACjB,MAAM,IAAI,SAAS,CACjB,QAAQ,CAAC,MAAM,EACf,sCAAsC,QAAQ,CAAC,MAAM,GAAG,CACzD,CAAC;gBACJ,CAAC;gBAED,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC;YACzB,CAAC;SACF,CAAC,CAAC;QAEH,IAAI,CAAC,EAAE,CAAC,YAAY,EAAE,uBAAuB,CAAC,EAAE,CAAC;YAC/C,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;QACrE,CAAC;QAED,OAAO,YAAY,CAAC,IAAI,CAAC;IAC3B,CAAC;CACF","sourcesContent":["import { BaseDataService } from '@metamask/base-data-service';\nimport type {\n DataServiceCacheUpdatedEvent,\n DataServiceGranularCacheUpdatedEvent,\n DataServiceInvalidateQueriesAction,\n} from '@metamask/base-data-service';\nimport type { CreateServicePolicyOptions } from '@metamask/controller-utils';\nimport { HttpError, fromHex } from '@metamask/controller-utils';\nimport type { Messenger } from '@metamask/messenger';\nimport type { Infer } from '@metamask/superstruct';\nimport { is, number, type } from '@metamask/superstruct';\nimport type { Hex } from '@metamask/utils';\nimport type { QueryClientConfig } from '@tanstack/query-core';\n\nimport type { SampleGasPricesServiceMethodActions } from './sample-gas-prices-service-method-action-types';\n\n// === GENERAL ===\n\n/**\n * The name of the {@link SampleGasPricesService}, used to namespace the\n * service's actions and events.\n */\nexport const serviceName = 'SampleGasPricesService';\n\n// === MESSENGER ===\n\n/**\n * All of the methods within {@link SampleGasPricesService} that are exposed via\n * the messenger.\n */\nconst MESSENGER_EXPOSED_METHODS = ['fetchGasPrices'] as const;\n\n/**\n * Invalidates cached queries for {@link SampleGasPricesService}.\n */\nexport type SampleGasPricesServiceInvalidateQueriesAction =\n DataServiceInvalidateQueriesAction<typeof serviceName>;\n\n/**\n * Actions that {@link SampleGasPricesService} exposes to other consumers.\n */\nexport type SampleGasPricesServiceActions =\n | SampleGasPricesServiceMethodActions\n | SampleGasPricesServiceInvalidateQueriesAction;\n\n/**\n * Actions from other messengers that {@link SampleGasPricesService} calls.\n */\ntype AllowedActions = never;\n\n/**\n * Published when {@link SampleGasPricesService}'s cache is updated.\n */\nexport type SampleGasPricesServiceCacheUpdatedEvent =\n DataServiceCacheUpdatedEvent<typeof serviceName>;\n\n/**\n * Published when a key within {@link SampleGasPricesService}'s cache is\n * updated.\n */\nexport type SampleGasPricesServiceGranularCacheUpdatedEvent =\n DataServiceGranularCacheUpdatedEvent<typeof serviceName>;\n\n/**\n * Events that {@link SampleGasPricesService} exposes to other consumers.\n */\nexport type SampleGasPricesServiceEvents =\n | SampleGasPricesServiceCacheUpdatedEvent\n | SampleGasPricesServiceGranularCacheUpdatedEvent;\n\n/**\n * Events from other messengers that {@link SampleGasPricesService} subscribes\n * to.\n */\ntype AllowedEvents = never;\n\n/**\n * The messenger which is restricted to actions and events accessed by\n * {@link SampleGasPricesService}.\n */\nexport type SampleGasPricesServiceMessenger = Messenger<\n typeof serviceName,\n SampleGasPricesServiceActions | AllowedActions,\n SampleGasPricesServiceEvents | AllowedEvents\n>;\n\n// === SERVICE DEFINITION ===\n\n/**\n * Struct to validate what the API endpoint returns.\n */\nconst GasPricesResponseStruct = type({\n data: type({\n low: number(),\n average: number(),\n high: number(),\n }),\n});\n\n/**\n * What the API endpoint returns.\n */\ntype GasPricesResponse = Infer<typeof GasPricesResponseStruct>;\n\n/**\n * The base URL of the API that the service represents.\n */\nconst BASE_URL = 'https://api.example.com';\n\n/**\n * This service object is responsible for fetching gas prices via an API.\n *\n * @example\n *\n * ``` ts\n * import type { MessengerActions, MessengerEvents } from '@metamask/messenger';\n * import { Messenger } from '@metamask/messenger';\n * import type {\n * SampleGasPricesServiceMessenger,\n * } from '@metamask/sample-controllers';\n *\n * const rootMessenger = new Messenger<\n * 'Root',\n * SampleGasPricesServiceActions\n * SampleGasPricesServiceEvents\n * >({ namespace: 'Root' });\n * const gasPricesServiceMessenger = new Messenger<\n * 'SampleGasPricesService',\n * MessengerActions<SampleGasPricesServiceMessenger>,\n * MessengerEvents<SampleGasPricesServiceMessenger>,\n * typeof rootMessenger,\n * >({\n * namespace: 'SampleGasPricesService',\n * parent: rootMessenger,\n * });\n * // Instantiate the service to register its actions on the messenger\n * new SampleGasPricesService({\n * messenger: gasPricesServiceMessenger,\n * });\n *\n * // Later...\n * // Fetch gas prices for Mainnet\n * const gasPrices = await rootMessenger.call(\n * 'SampleGasPricesService:fetchGasPrices',\n * '0x1',\n * );\n * // ... Do something with the gas prices ...\n * ```\n */\nexport class SampleGasPricesService extends BaseDataService<\n typeof serviceName,\n SampleGasPricesServiceMessenger\n> {\n /**\n * Constructs a new SampleGasPricesService object.\n *\n * @param args - The constructor arguments.\n * @param args.messenger - The messenger suited for this service.\n * @param args.queryClientConfig - Configuration for the underlying TanStack\n * Query client.\n * @param args.policyOptions - Options to pass to `createServicePolicy`, which\n * is used to wrap each request. See {@link CreateServicePolicyOptions}.\n */\n constructor({\n messenger,\n queryClientConfig = {},\n policyOptions = {},\n }: {\n messenger: SampleGasPricesServiceMessenger;\n queryClientConfig?: QueryClientConfig;\n policyOptions?: CreateServicePolicyOptions;\n }) {\n super({\n name: serviceName,\n messenger,\n queryClientConfig,\n policyOptions,\n });\n\n this.messenger.registerMethodActionHandlers(\n this,\n MESSENGER_EXPOSED_METHODS,\n );\n }\n\n /**\n * Makes a request to the API in order to retrieve gas prices for a particular\n * chain.\n *\n * @param chainId - The chain ID for which you want to fetch gas prices.\n * @returns The gas prices for the given chain.\n */\n async fetchGasPrices(chainId: Hex): Promise<GasPricesResponse['data']> {\n const url = new URL('/gas-prices', BASE_URL);\n url.searchParams.append('chainId', `eip155:${fromHex(chainId).toString()}`);\n\n const jsonResponse = await this.fetchQuery({\n queryKey: [`${this.name}:fetchGasPrices`, chainId],\n queryFn: async () => {\n const response = await fetch(url);\n\n if (!response.ok) {\n throw new HttpError(\n response.status,\n `Gas prices API failed with status '${response.status}'`,\n );\n }\n\n return response.json();\n },\n });\n\n if (!is(jsonResponse, GasPricesResponseStruct)) {\n throw new Error('Malformed response received from gas prices API');\n }\n\n return jsonResponse.data;\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@metamask-previews/sample-controllers",
|
|
3
|
-
"version": "4.0.4-preview-
|
|
3
|
+
"version": "4.0.4-preview-1d148d2",
|
|
4
4
|
"description": "Sample package to illustrate best practices for controllers",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"MetaMask",
|
|
@@ -49,9 +49,12 @@
|
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
51
|
"@metamask/base-controller": "^9.0.1",
|
|
52
|
-
"@metamask/
|
|
52
|
+
"@metamask/base-data-service": "^0.1.1",
|
|
53
|
+
"@metamask/messenger": "^1.1.0",
|
|
53
54
|
"@metamask/network-controller": "^30.0.1",
|
|
54
|
-
"@metamask/
|
|
55
|
+
"@metamask/superstruct": "^3.1.0",
|
|
56
|
+
"@metamask/utils": "^11.9.0",
|
|
57
|
+
"@tanstack/query-core": "^4.43.0"
|
|
55
58
|
},
|
|
56
59
|
"devDependencies": {
|
|
57
60
|
"@metamask/auto-changelog": "^3.4.4",
|