@metamask-previews/sentinel-api-service 1.0.1-preview-abca9bcea → 2.0.0-preview-0a30e47
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 +12 -1
- package/dist/{constants.d.mts → constants.d.ts} +1 -1
- package/dist/constants.d.ts.map +1 -0
- package/dist/{constants.mjs → constants.js} +1 -1
- package/dist/constants.js.map +1 -0
- package/dist/{errors.d.cts → errors.d.ts} +1 -1
- package/dist/errors.d.ts.map +1 -0
- package/dist/{errors.mjs → errors.js} +3 -1
- package/dist/errors.js.map +1 -0
- package/dist/{index.d.cts → index.d.ts} +7 -7
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/logger.d.ts +4 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +4 -0
- package/dist/logger.js.map +1 -0
- package/dist/{sentinel-api-service-method-action-types.d.cts → sentinel-api-service-method-action-types.d.ts} +2 -2
- package/dist/sentinel-api-service-method-action-types.d.ts.map +1 -0
- package/dist/{sentinel-api-service-method-action-types.mjs → sentinel-api-service-method-action-types.js} +1 -1
- package/dist/sentinel-api-service-method-action-types.js.map +1 -0
- package/dist/{sentinel-api-service.d.mts → sentinel-api-service.d.ts} +5 -5
- package/dist/sentinel-api-service.d.ts.map +1 -0
- package/dist/{sentinel-api-service.mjs → sentinel-api-service.js} +119 -125
- package/dist/sentinel-api-service.js.map +1 -0
- package/dist/{structs.d.cts → structs.d.ts} +4 -4
- package/dist/structs.d.ts.map +1 -0
- package/dist/{structs.mjs → structs.js} +2 -2
- package/dist/structs.js.map +1 -0
- package/dist/{types.d.mts → types.d.ts} +8 -8
- package/dist/types.d.ts.map +1 -0
- package/dist/{types.mjs → types.js} +1 -1
- package/dist/types.js.map +1 -0
- package/package.json +15 -19
- package/dist/constants.cjs +0 -71
- package/dist/constants.cjs.map +0 -1
- package/dist/constants.d.cts +0 -63
- package/dist/constants.d.cts.map +0 -1
- package/dist/constants.d.mts.map +0 -1
- package/dist/constants.mjs.map +0 -1
- package/dist/errors.cjs +0 -43
- package/dist/errors.cjs.map +0 -1
- package/dist/errors.d.cts.map +0 -1
- package/dist/errors.d.mts +0 -27
- package/dist/errors.d.mts.map +0 -1
- package/dist/errors.mjs.map +0 -1
- package/dist/index.cjs +0 -17
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.cts.map +0 -1
- package/dist/index.d.mts +0 -7
- package/dist/index.d.mts.map +0 -1
- package/dist/index.mjs +0 -5
- package/dist/index.mjs.map +0 -1
- package/dist/logger.cjs +0 -7
- package/dist/logger.cjs.map +0 -1
- package/dist/logger.d.cts +0 -5
- package/dist/logger.d.cts.map +0 -1
- package/dist/logger.d.mts +0 -5
- package/dist/logger.d.mts.map +0 -1
- package/dist/logger.mjs +0 -4
- package/dist/logger.mjs.map +0 -1
- package/dist/sentinel-api-service-method-action-types.cjs +0 -7
- package/dist/sentinel-api-service-method-action-types.cjs.map +0 -1
- package/dist/sentinel-api-service-method-action-types.d.cts.map +0 -1
- package/dist/sentinel-api-service-method-action-types.d.mts +0 -62
- package/dist/sentinel-api-service-method-action-types.d.mts.map +0 -1
- package/dist/sentinel-api-service-method-action-types.mjs.map +0 -1
- package/dist/sentinel-api-service.cjs +0 -316
- package/dist/sentinel-api-service.cjs.map +0 -1
- package/dist/sentinel-api-service.d.cts +0 -90
- package/dist/sentinel-api-service.d.cts.map +0 -1
- package/dist/sentinel-api-service.d.mts.map +0 -1
- package/dist/sentinel-api-service.mjs.map +0 -1
- package/dist/structs.cjs +0 -58
- package/dist/structs.cjs.map +0 -1
- package/dist/structs.d.cts.map +0 -1
- package/dist/structs.d.mts +0 -63
- package/dist/structs.d.mts.map +0 -1
- package/dist/structs.mjs.map +0 -1
- package/dist/types.cjs +0 -36
- package/dist/types.cjs.map +0 -1
- package/dist/types.d.cts +0 -420
- package/dist/types.d.cts.map +0 -1
- package/dist/types.d.mts.map +0 -1
- package/dist/types.mjs.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,9 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [2.0.0]
|
|
11
|
+
|
|
10
12
|
### Changed
|
|
11
13
|
|
|
14
|
+
- **BREAKING:** Drop CommonJS support ([#9536](https://github.com/MetaMask/core/pull/9536))
|
|
15
|
+
- This package is now ESM-only, but can still be used in CommonJS projects via `require(esm)` in modern Node.js versions (22+), or dynamic imports in older Node.js versions.
|
|
16
|
+
- **BREAKING:** Bump minimum Node.js version to 22 ([#9976](https://github.com/MetaMask/core/pull/9976))
|
|
17
|
+
- **BREAKING:** Bump TypeScript target to ES2022 ([#10019](https://github.com/MetaMask/core/pull/10019))
|
|
18
|
+
- This package now ships ES2022 code, requiring a compatible modern environment or bundler configuration to consume.
|
|
12
19
|
- Bump `@metamask/utils` from `^11.11.0` to `^11.12.0` ([#10076](https://github.com/MetaMask/core/pull/10076))
|
|
20
|
+
- Bump `@metamask/base-data-service` from `^1.0.0` to `^2.0.0` ([#10160](https://github.com/MetaMask/core/pull/10160))
|
|
21
|
+
- Bump `@metamask/controller-utils` from `^12.3.0` to `^13.0.0` ([#10160](https://github.com/MetaMask/core/pull/10160))
|
|
22
|
+
- Bump `@metamask/messenger` from `^2.0.0` to `^3.0.0` ([#10160](https://github.com/MetaMask/core/pull/10160))
|
|
13
23
|
|
|
14
24
|
## [1.0.1]
|
|
15
25
|
|
|
@@ -26,6 +36,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
26
36
|
- Initial commit ([#9466](https://github.com/MetaMask/core/pull/9466))
|
|
27
37
|
- Supports `getNetworks`, `simulateTransactions`, `submitRelayTransaction`, and `getSmartTransaction`
|
|
28
38
|
|
|
29
|
-
[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/sentinel-api-service@
|
|
39
|
+
[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/sentinel-api-service@2.0.0...HEAD
|
|
40
|
+
[2.0.0]: https://github.com/MetaMask/core/compare/@metamask/sentinel-api-service@1.0.1...@metamask/sentinel-api-service@2.0.0
|
|
30
41
|
[1.0.1]: https://github.com/MetaMask/core/compare/@metamask/sentinel-api-service@1.0.0...@metamask/sentinel-api-service@1.0.1
|
|
31
42
|
[1.0.0]: https://github.com/MetaMask/core/releases/tag/@metamask/sentinel-api-service@1.0.0
|
|
@@ -60,4 +60,4 @@ export declare const ENDPOINT_SMART_TRANSACTIONS = "smart-transactions";
|
|
|
60
60
|
* The registry is stable, so caching it avoids re-fetching on every request.
|
|
61
61
|
*/
|
|
62
62
|
export declare const NETWORKS_STALE_TIME_MS: number;
|
|
63
|
-
//# sourceMappingURL=constants.d.
|
|
63
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,WAAW,uBAAuB,CAAC;AAEhD;;GAEG;AACH,eAAO,MAAM,mBAAmB,gCAAgC,CAAC;AAEjE;;;GAGG;AACH,eAAO,MAAM,qBAAqB,6BAA6B,CAAC;AAEhE;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,gDAAgD,CAAC;AAE/E;;;GAGG;AACH,oBAAY,mBAAmB;IAC7B,0DAA0D;IAC1D,GAAG,QAAQ;IACX,sEAAsE;IACtE,GAAG,QAAQ;IACX,qDAAqD;IACrD,IAAI,SAAS;CACd;AAED;;;GAGG;AACH,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,mBAAmB,EAAE,MAAM,CAIlE,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,2BAA2B,CAAC;AAE5D;;;GAGG;AACH,eAAO,MAAM,kBAAkB,qBAAqB,CAAC;AAErD;;GAEG;AACH,eAAO,MAAM,iBAAiB,aAAa,CAAC;AAE5C;;;GAGG;AACH,eAAO,MAAM,2BAA2B,uBAAuB,CAAC;AAEhE;;;GAGG;AACH,eAAO,MAAM,sBAAsB,QAAgB,CAAC"}
|
|
@@ -65,4 +65,4 @@ export const ENDPOINT_SMART_TRANSACTIONS = 'smart-transactions';
|
|
|
65
65
|
* The registry is stable, so caching it avoids re-fetching on every request.
|
|
66
66
|
*/
|
|
67
67
|
export const NETWORKS_STALE_TIME_MS = 5 * 60 * 1000;
|
|
68
|
-
//# sourceMappingURL=constants.
|
|
68
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,oBAAoB,CAAC;AAEhD;;GAEG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,6BAA6B,CAAC;AAEjE;;;GAGG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,0BAA0B,CAAC;AAEhE;;;;GAIG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,6CAA6C,CAAC;AAE/E;;;GAGG;AACH,MAAM,CAAN,IAAY,mBAOX;AAPD,WAAY,mBAAmB;IAC7B,0DAA0D;IAC1D,kCAAW,CAAA;IACX,sEAAsE;IACtE,kCAAW,CAAA;IACX,qDAAqD;IACrD,oCAAa,CAAA;AACf,CAAC,EAPW,mBAAmB,KAAnB,mBAAmB,QAO9B;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAwC;IACrE,CAAC,mBAAmB,CAAC,GAAG,CAAC,EAAE,SAAS;IACpC,CAAC,mBAAmB,CAAC,GAAG,CAAC,EAAE,SAAS;IACpC,CAAC,mBAAmB,CAAC,IAAI,CAAC,EAAE,KAAK;CAClC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,mBAAmB,CAAC,IAAI,CAAC;AAE5D;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,kBAAkB,CAAC;AAErD;;GAEG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,UAAU,CAAC;AAE5C;;;GAGG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,oBAAoB,CAAC;AAEhE;;;GAGG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC","sourcesContent":["/**\n * The name of the {@link SentinelApiService}, used to namespace the service's\n * actions and events.\n */\nexport const serviceName = 'SentinelApiService';\n\n/**\n * JSON-RPC method used to simulate transactions against the Sentinel API.\n */\nexport const RPC_METHOD_SIMULATE = 'infura_simulateTransactions';\n\n/**\n * JSON-RPC method used to submit a signed relay (gas station) transaction to\n * the Sentinel API.\n */\nexport const RPC_METHOD_SEND_RELAY = 'eth_sendRelayTransaction';\n\n/**\n * Template for the Sentinel API base URL. `{0}` is replaced with the network\n * subdomain (for example `ethereum-mainnet`) and `{1}` with the environment\n * API-domain segment (see {@link ENVIRONMENT_DOMAIN}).\n */\nexport const BASE_URL_TEMPLATE = 'https://tx-sentinel-{0}.{1}.cx.metamask.io/';\n\n/**\n * The Sentinel API environments. Each maps to a distinct API domain segment;\n * see {@link ENVIRONMENT_DOMAIN}.\n */\nexport enum SentinelEnvironment {\n /** Development environment (`dev-api.cx.metamask.io`). */\n Dev = 'dev',\n /** User-acceptance-testing environment (`uat-api.cx.metamask.io`). */\n Uat = 'uat',\n /** Production environment (`api.cx.metamask.io`). */\n Prod = 'prod',\n}\n\n/**\n * Maps a {@link SentinelEnvironment} to the API-domain segment substituted into\n * {@link BASE_URL_TEMPLATE} (the `{1}` placeholder).\n */\nexport const ENVIRONMENT_DOMAIN: Record<SentinelEnvironment, string> = {\n [SentinelEnvironment.Dev]: 'dev-api',\n [SentinelEnvironment.Uat]: 'uat-api',\n [SentinelEnvironment.Prod]: 'api',\n};\n\n/**\n * The default {@link SentinelEnvironment} used when the constructor does not\n * specify one. Production, matching the behaviour of the clients this service\n * replaces.\n */\nexport const DEFAULT_ENVIRONMENT = SentinelEnvironment.Prod;\n\n/**\n * The subdomain used for network-registry lookups. The `/networks` endpoint\n * returns identical data regardless of subdomain, so a stable one is used.\n */\nexport const NETWORKS_SUBDOMAIN = 'ethereum-mainnet';\n\n/**\n * The REST path used to retrieve the supported-network registry.\n */\nexport const ENDPOINT_NETWORKS = 'networks';\n\n/**\n * The REST path prefix used to poll the status of a submitted smart\n * transaction by UUID.\n */\nexport const ENDPOINT_SMART_TRANSACTIONS = 'smart-transactions';\n\n/**\n * How long the network registry (`/networks`) response is considered fresh.\n * The registry is stable, so caching it avoids re-fetching on every request.\n */\nexport const NETWORKS_STALE_TIME_MS = 5 * 60 * 1000;\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,uDAAuD;IACvD,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAEvB,YAAY,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,EAIzC;CACF;AAED;;;;GAIG;AACH,qBAAa,8BAA+B,SAAQ,KAAK;IACvD,YAAY,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAO/C;CACF;AAED;;;;;GAKG;AACH,qBAAa,kCAAmC,SAAQ,KAAK;IAC3D,YAAY,OAAO,CAAC,EAAE,MAAM,EAG3B;CACF"}
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
* from `infura_simulateTransactions` or `eth_sendRelayTransaction`).
|
|
4
4
|
*/
|
|
5
5
|
export class SentinelJsonRpcError extends Error {
|
|
6
|
+
/** The JSON-RPC error code, if provided by the API. */
|
|
7
|
+
code;
|
|
6
8
|
constructor(message, code) {
|
|
7
9
|
super(message);
|
|
8
10
|
this.name = 'SentinelJsonRpcError';
|
|
@@ -34,4 +36,4 @@ export class SentinelApiResponseValidationError extends Error {
|
|
|
34
36
|
this.name = 'SentinelApiResponseValidationError';
|
|
35
37
|
}
|
|
36
38
|
}
|
|
37
|
-
//# sourceMappingURL=errors.
|
|
39
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IAC7C,uDAAuD;IAC9C,IAAI,CAAU;IAEvB,YAAY,OAAe,EAAE,IAAa;QACxC,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;QACnC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF;AAED;;;;GAIG;AACH,MAAM,OAAO,8BAA+B,SAAQ,KAAK;IACvD,YAAY,OAAe,EAAE,UAAmB;QAC9C,KAAK,CACH,UAAU;YACR,CAAC,CAAC,mCAAmC,UAAU,eAAe,OAAO,EAAE;YACvE,CAAC,CAAC,wCAAwC,OAAO,EAAE,CACtD,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,gCAAgC,CAAC;IAC/C,CAAC;CACF;AAED;;;;;GAKG;AACH,MAAM,OAAO,kCAAmC,SAAQ,KAAK;IAC3D,YAAY,OAAgB;QAC1B,KAAK,CAAC,OAAO,IAAI,2CAA2C,CAAC,CAAC;QAC9D,IAAI,CAAC,IAAI,GAAG,oCAAoC,CAAC;IACnD,CAAC;CACF","sourcesContent":["/**\n * Thrown when the Sentinel API returns a JSON-RPC error object (for example\n * from `infura_simulateTransactions` or `eth_sendRelayTransaction`).\n */\nexport class SentinelJsonRpcError extends Error {\n /** The JSON-RPC error code, if provided by the API. */\n readonly code?: number;\n\n constructor(message: string, code?: number) {\n super(message);\n this.name = 'SentinelJsonRpcError';\n this.code = code;\n }\n}\n\n/**\n * Thrown when a Sentinel operation is requested for a chain that the API does\n * not support (either not present in the network registry, or the required\n * capability flag is not enabled for that chain).\n */\nexport class SentinelChainNotSupportedError extends Error {\n constructor(chainId: string, capability?: string) {\n super(\n capability\n ? `Sentinel API: Does not support '${capability}' for chain ${chainId}`\n : `Sentinel API: Does not support chain ${chainId}`,\n );\n this.name = 'SentinelChainNotSupportedError';\n }\n}\n\n/**\n * Thrown when a response from the Sentinel API fails superstruct validation.\n * Indicates a contract mismatch between client and server. Excluded from the\n * service policy's retry filter, since retrying will not fix a malformed\n * response.\n */\nexport class SentinelApiResponseValidationError extends Error {\n constructor(message?: string) {\n super(message ?? 'Sentinel API: Malformed response received');\n this.name = 'SentinelApiResponseValidationError';\n }\n}\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export { SentinelApiService } from
|
|
2
|
-
export { SentinelEnvironment, serviceName } from
|
|
3
|
-
export type { SentinelApiServiceActions, SentinelApiServiceEvents, SentinelApiServiceMessenger, SentinelApiServiceOptions, SentinelApiServiceInvalidateQueriesAction, SentinelApiServiceCacheUpdatedEvent, SentinelApiServiceGranularCacheUpdatedEvent, SentinelAuthorization, SentinelMeta, SentinelNetwork, SentinelNetworkRegistry, SentinelRelaySubmitRequest, SentinelRelaySubmitResponse, SentinelSignedAuthorization, SentinelSimulationCallTrace, SentinelSimulationLog, SentinelSimulationRequest, SentinelSimulationResponse, SentinelSimulationResponseTransaction, SentinelSimulationStateDiff, SentinelSimulationTokenFee, SentinelSimulationTransaction, SentinelSmartTransaction, SentinelSmartTransactionRequest, SentinelSmartTransactionResponse, SentinelStateOverrides, } from
|
|
4
|
-
export { SentinelFeature, SentinelKind, SentinelSmartTransactionStatus, } from
|
|
5
|
-
export type { SentinelApiServiceGetNetworksAction, SentinelApiServiceSimulateTransactionsAction, SentinelApiServiceSubmitRelayTransactionAction, SentinelApiServiceGetSmartTransactionAction, } from
|
|
6
|
-
export { SentinelApiResponseValidationError, SentinelChainNotSupportedError, SentinelJsonRpcError, } from
|
|
7
|
-
//# sourceMappingURL=index.d.
|
|
1
|
+
export { SentinelApiService } from './sentinel-api-service.js';
|
|
2
|
+
export { SentinelEnvironment, serviceName } from './constants.js';
|
|
3
|
+
export type { SentinelApiServiceActions, SentinelApiServiceEvents, SentinelApiServiceMessenger, SentinelApiServiceOptions, SentinelApiServiceInvalidateQueriesAction, SentinelApiServiceCacheUpdatedEvent, SentinelApiServiceGranularCacheUpdatedEvent, SentinelAuthorization, SentinelMeta, SentinelNetwork, SentinelNetworkRegistry, SentinelRelaySubmitRequest, SentinelRelaySubmitResponse, SentinelSignedAuthorization, SentinelSimulationCallTrace, SentinelSimulationLog, SentinelSimulationRequest, SentinelSimulationResponse, SentinelSimulationResponseTransaction, SentinelSimulationStateDiff, SentinelSimulationTokenFee, SentinelSimulationTransaction, SentinelSmartTransaction, SentinelSmartTransactionRequest, SentinelSmartTransactionResponse, SentinelStateOverrides, } from './types.js';
|
|
4
|
+
export { SentinelFeature, SentinelKind, SentinelSmartTransactionStatus, } from './types.js';
|
|
5
|
+
export type { SentinelApiServiceGetNetworksAction, SentinelApiServiceSimulateTransactionsAction, SentinelApiServiceSubmitRelayTransactionAction, SentinelApiServiceGetSmartTransactionAction, } from './sentinel-api-service-method-action-types.js';
|
|
6
|
+
export { SentinelApiResponseValidationError, SentinelChainNotSupportedError, SentinelJsonRpcError, } from './errors.js';
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClE,YAAY,EACV,yBAAyB,EACzB,wBAAwB,EACxB,2BAA2B,EAC3B,yBAAyB,EACzB,yCAAyC,EACzC,mCAAmC,EACnC,2CAA2C,EAC3C,qBAAqB,EACrB,YAAY,EACZ,eAAe,EACf,uBAAuB,EACvB,0BAA0B,EAC1B,2BAA2B,EAC3B,2BAA2B,EAC3B,2BAA2B,EAC3B,qBAAqB,EACrB,yBAAyB,EACzB,0BAA0B,EAC1B,qCAAqC,EACrC,2BAA2B,EAC3B,0BAA0B,EAC1B,6BAA6B,EAC7B,wBAAwB,EACxB,+BAA+B,EAC/B,gCAAgC,EAChC,sBAAsB,GACvB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,eAAe,EACf,YAAY,EACZ,8BAA8B,GAC/B,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,mCAAmC,EACnC,4CAA4C,EAC5C,8CAA8C,EAC9C,2CAA2C,GAC5C,MAAM,+CAA+C,CAAC;AACvD,OAAO,EACL,kCAAkC,EAClC,8BAA8B,EAC9B,oBAAoB,GACrB,MAAM,aAAa,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { SentinelApiService } from './sentinel-api-service.js';
|
|
2
|
+
export { SentinelEnvironment, serviceName } from './constants.js';
|
|
3
|
+
export { SentinelFeature, SentinelKind, SentinelSmartTransactionStatus, } from './types.js';
|
|
4
|
+
export { SentinelApiResponseValidationError, SentinelChainNotSupportedError, SentinelJsonRpcError, } from './errors.js';
|
|
5
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AA6BlE,OAAO,EACL,eAAe,EACf,YAAY,EACZ,8BAA8B,GAC/B,MAAM,YAAY,CAAC;AAOpB,OAAO,EACL,kCAAkC,EAClC,8BAA8B,EAC9B,oBAAoB,GACrB,MAAM,aAAa,CAAC","sourcesContent":["export { SentinelApiService } from './sentinel-api-service.js';\nexport { SentinelEnvironment, serviceName } from './constants.js';\nexport type {\n SentinelApiServiceActions,\n SentinelApiServiceEvents,\n SentinelApiServiceMessenger,\n SentinelApiServiceOptions,\n SentinelApiServiceInvalidateQueriesAction,\n SentinelApiServiceCacheUpdatedEvent,\n SentinelApiServiceGranularCacheUpdatedEvent,\n SentinelAuthorization,\n SentinelMeta,\n SentinelNetwork,\n SentinelNetworkRegistry,\n SentinelRelaySubmitRequest,\n SentinelRelaySubmitResponse,\n SentinelSignedAuthorization,\n SentinelSimulationCallTrace,\n SentinelSimulationLog,\n SentinelSimulationRequest,\n SentinelSimulationResponse,\n SentinelSimulationResponseTransaction,\n SentinelSimulationStateDiff,\n SentinelSimulationTokenFee,\n SentinelSimulationTransaction,\n SentinelSmartTransaction,\n SentinelSmartTransactionRequest,\n SentinelSmartTransactionResponse,\n SentinelStateOverrides,\n} from './types.js';\nexport {\n SentinelFeature,\n SentinelKind,\n SentinelSmartTransactionStatus,\n} from './types.js';\nexport type {\n SentinelApiServiceGetNetworksAction,\n SentinelApiServiceSimulateTransactionsAction,\n SentinelApiServiceSubmitRelayTransactionAction,\n SentinelApiServiceGetSmartTransactionAction,\n} from './sentinel-api-service-method-action-types.js';\nexport {\n SentinelApiResponseValidationError,\n SentinelChainNotSupportedError,\n SentinelJsonRpcError,\n} from './errors.js';\n"]}
|
package/dist/logger.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAE1E,eAAO,MAAM,aAAa,0BAA8C,CAAC;AAEzE,OAAO,EAAE,kBAAkB,EAAE,CAAC"}
|
package/dist/logger.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAE1E,MAAM,CAAC,MAAM,aAAa,GAAG,mBAAmB,CAAC,sBAAsB,CAAC,CAAC;AAEzE,OAAO,EAAE,kBAAkB,EAAE,CAAC","sourcesContent":["import { createProjectLogger, createModuleLogger } from '@metamask/utils';\n\nexport const projectLogger = createProjectLogger('sentinel-api-service');\n\nexport { createModuleLogger };\n"]}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* This file is auto generated.
|
|
3
3
|
* Do not edit manually.
|
|
4
4
|
*/
|
|
5
|
-
import type { SentinelApiService } from
|
|
5
|
+
import type { SentinelApiService } from './sentinel-api-service.js';
|
|
6
6
|
/**
|
|
7
7
|
* Fetches the Sentinel supported-network registry. The result is cached, as
|
|
8
8
|
* the registry is stable and identical across network subdomains.
|
|
@@ -59,4 +59,4 @@ export type SentinelApiServiceGetSmartTransactionAction = {
|
|
|
59
59
|
* Union of all SentinelApiService action types.
|
|
60
60
|
*/
|
|
61
61
|
export type SentinelApiServiceMethodActions = SentinelApiServiceGetNetworksAction | SentinelApiServiceSimulateTransactionsAction | SentinelApiServiceSubmitRelayTransactionAction | SentinelApiServiceGetSmartTransactionAction;
|
|
62
|
-
//# sourceMappingURL=sentinel-api-service-method-action-types.d.
|
|
62
|
+
//# sourceMappingURL=sentinel-api-service-method-action-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sentinel-api-service-method-action-types.d.ts","sourceRoot":"","sources":["../src/sentinel-api-service-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAEpE;;;;;GAKG;AACH,MAAM,MAAM,mCAAmC,GAAG;IAChD,IAAI,EAAE,gCAAgC,CAAC;IACvC,OAAO,EAAE,kBAAkB,CAAC,aAAa,CAAC,CAAC;CAC5C,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,4CAA4C,GAAG;IACzD,IAAI,EAAE,yCAAyC,CAAC;IAChD,OAAO,EAAE,kBAAkB,CAAC,sBAAsB,CAAC,CAAC;CACrD,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,8CAA8C,GAAG;IAC3D,IAAI,EAAE,2CAA2C,CAAC;IAClD,OAAO,EAAE,kBAAkB,CAAC,wBAAwB,CAAC,CAAC;CACvD,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,MAAM,2CAA2C,GAAG;IACxD,IAAI,EAAE,wCAAwC,CAAC;IAC/C,OAAO,EAAE,kBAAkB,CAAC,qBAAqB,CAAC,CAAC;CACpD,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,+BAA+B,GACvC,mCAAmC,GACnC,4CAA4C,GAC5C,8CAA8C,GAC9C,2CAA2C,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sentinel-api-service-method-action-types.js","sourceRoot":"","sources":["../src/sentinel-api-service-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/**\n * This file is auto generated.\n * Do not edit manually.\n */\n\nimport type { SentinelApiService } from './sentinel-api-service.js';\n\n/**\n * Fetches the Sentinel supported-network registry. The result is cached, as\n * the registry is stable and identical across network subdomains.\n *\n * @returns The network registry, keyed by decimal chain ID.\n */\nexport type SentinelApiServiceGetNetworksAction = {\n type: `SentinelApiService:getNetworks`;\n handler: SentinelApiService['getNetworks'];\n};\n\n/**\n * Simulates transactions against the Sentinel API via\n * `infura_simulateTransactions`. Not cached, since each request body is\n * unique and stale simulations must not be reused.\n *\n * @param chainId - The chain ID to simulate on.\n * @param request - The simulation request.\n * @param options - Additional options.\n * @param options.getUrl - Optional callback that receives the default\n * Sentinel URL resolved for the chain and returns the URL to use instead.\n * Lets consumers rewrite the request URL (for example to route through the\n * MetaMask Shield proxy) without the service knowing about those concerns.\n * @returns The simulation response.\n */\nexport type SentinelApiServiceSimulateTransactionsAction = {\n type: `SentinelApiService:simulateTransactions`;\n handler: SentinelApiService['simulateTransactions'];\n};\n\n/**\n * Submits a signed relay (gas station) transaction to the Sentinel API via\n * `eth_sendRelayTransaction`. Not cached.\n *\n * @param request - The relay submit request.\n * @returns The relay submit response containing the tracking UUID.\n */\nexport type SentinelApiServiceSubmitRelayTransactionAction = {\n type: `SentinelApiService:submitRelayTransaction`;\n handler: SentinelApiService['submitRelayTransaction'];\n};\n\n/**\n * Looks up the state of a submitted smart transaction by UUID against the\n * `/smart-transactions/{uuid}` endpoint. Performs a single request; callers\n * own any polling loop. Not cached.\n *\n * @param request - The smart-transaction lookup request.\n * @returns The response envelope containing the smart transaction(s)\n * associated with the requested UUID.\n */\nexport type SentinelApiServiceGetSmartTransactionAction = {\n type: `SentinelApiService:getSmartTransaction`;\n handler: SentinelApiService['getSmartTransaction'];\n};\n\n/**\n * Union of all SentinelApiService action types.\n */\nexport type SentinelApiServiceMethodActions =\n | SentinelApiServiceGetNetworksAction\n | SentinelApiServiceSimulateTransactionsAction\n | SentinelApiServiceSubmitRelayTransactionAction\n | SentinelApiServiceGetSmartTransactionAction;\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { BaseDataService } from
|
|
2
|
-
import type { Hex } from
|
|
3
|
-
import { serviceName } from
|
|
4
|
-
import type { SentinelApiServiceMessenger, SentinelApiServiceOptions, SentinelNetworkRegistry, SentinelRelaySubmitRequest, SentinelRelaySubmitResponse, SentinelSimulationRequest, SentinelSimulationResponse, SentinelSmartTransactionRequest, SentinelSmartTransactionResponse } from
|
|
1
|
+
import { BaseDataService } from '@metamask/base-data-service';
|
|
2
|
+
import type { Hex } from '@metamask/utils';
|
|
3
|
+
import { serviceName } from './constants.js';
|
|
4
|
+
import type { SentinelApiServiceMessenger, SentinelApiServiceOptions, SentinelNetworkRegistry, SentinelRelaySubmitRequest, SentinelRelaySubmitResponse, SentinelSimulationRequest, SentinelSimulationResponse, SentinelSmartTransactionRequest, SentinelSmartTransactionResponse } from './types.js';
|
|
5
5
|
/**
|
|
6
6
|
* Data service that centralises all interactions with the MetaMask Sentinel
|
|
7
7
|
* API (`tx-sentinel-<network>.api.cx.metamask.io`).
|
|
@@ -87,4 +87,4 @@ export declare class SentinelApiService extends BaseDataService<typeof serviceNa
|
|
|
87
87
|
*/
|
|
88
88
|
getSmartTransaction(request: SentinelSmartTransactionRequest): Promise<SentinelSmartTransactionResponse>;
|
|
89
89
|
}
|
|
90
|
-
//# sourceMappingURL=sentinel-api-service.d.
|
|
90
|
+
//# sourceMappingURL=sentinel-api-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sentinel-api-service.d.ts","sourceRoot":"","sources":["../src/sentinel-api-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAG9D,OAAO,KAAK,EAAE,GAAG,EAAQ,MAAM,iBAAiB,CAAC;AAEjD,OAAO,EAUL,WAAW,EACZ,MAAM,gBAAgB,CAAC;AAaxB,OAAO,KAAK,EACV,2BAA2B,EAC3B,yBAAyB,EAEzB,uBAAuB,EACvB,0BAA0B,EAC1B,2BAA2B,EAC3B,yBAAyB,EACzB,0BAA0B,EAC1B,+BAA+B,EAC/B,gCAAgC,EACjC,MAAM,YAAY,CAAC;AAWpB;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,kBAAmB,SAAQ,eAAe,CACrD,OAAO,WAAW,EAClB,2BAA2B,CAC5B;;IASC;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,YAAY,EACV,SAAS,EACT,KAAK,EAAE,aAAgC,EACvC,WAAiC,EACjC,QAAQ,EACR,aAAa,EACb,iBAAsB,EACtB,aAAkB,GACnB,EAAE,yBAAyB,EA+B3B;IAED;;;;;OAKG;IACG,WAAW,IAAI,OAAO,CAAC,uBAAuB,CAAC,CAoCpD;IAED;;;;;;;;;;;;;OAaG;IACG,oBAAoB,CACxB,OAAO,EAAE,GAAG,EACZ,OAAO,EAAE,yBAAyB,EAClC,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;KAAO,GAC1E,OAAO,CAAC,0BAA0B,CAAC,CA4BrC;IAED;;;;;;OAMG;IACG,sBAAsB,CAC1B,OAAO,EAAE,0BAA0B,GAClC,OAAO,CAAC,2BAA2B,CAAC,CA2BtC;IAED;;;;;;;;OAQG;IACG,mBAAmB,CACvB,OAAO,EAAE,+BAA+B,GACvC,OAAO,CAAC,gCAAgC,CAAC,CAsC3C;CA2IF"}
|
|
@@ -1,22 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
};
|
|
7
|
-
|
|
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 _SentinelApiService_instances, _SentinelApiService_fetch, _SentinelApiService_clientId, _SentinelApiService_clientVersion, _SentinelApiService_environmentDomain, _SentinelApiService_jsonRpc, _SentinelApiService_getHeaders, _SentinelApiService_resolveUrl, _SentinelApiService_getNetwork, _SentinelApiService_buildUrl;
|
|
13
|
-
import { BaseDataService } from "@metamask/base-data-service";
|
|
14
|
-
import { handleWhen, HttpError } from "@metamask/controller-utils";
|
|
15
|
-
import { validate } from "@metamask/superstruct";
|
|
16
|
-
import { BASE_URL_TEMPLATE, DEFAULT_ENVIRONMENT, ENDPOINT_NETWORKS, ENDPOINT_SMART_TRANSACTIONS, ENVIRONMENT_DOMAIN, NETWORKS_STALE_TIME_MS, NETWORKS_SUBDOMAIN, RPC_METHOD_SEND_RELAY, RPC_METHOD_SIMULATE, serviceName } from "./constants.mjs";
|
|
17
|
-
import { SentinelApiResponseValidationError, SentinelChainNotSupportedError, SentinelJsonRpcError } from "./errors.mjs";
|
|
18
|
-
import { projectLogger, createModuleLogger } from "./logger.mjs";
|
|
19
|
-
import { SentinelSmartTransactionResponseStruct, SentinelNetworkRegistryStruct, SentinelRelaySubmitResponseStruct, SentinelSimulationResponseStruct } from "./structs.mjs";
|
|
1
|
+
import { BaseDataService } from '@metamask/base-data-service';
|
|
2
|
+
import { handleWhen, HttpError } from '@metamask/controller-utils';
|
|
3
|
+
import { validate } from '@metamask/superstruct';
|
|
4
|
+
import { BASE_URL_TEMPLATE, DEFAULT_ENVIRONMENT, ENDPOINT_NETWORKS, ENDPOINT_SMART_TRANSACTIONS, ENVIRONMENT_DOMAIN, NETWORKS_STALE_TIME_MS, NETWORKS_SUBDOMAIN, RPC_METHOD_SEND_RELAY, RPC_METHOD_SIMULATE, serviceName, } from './constants.js';
|
|
5
|
+
import { SentinelApiResponseValidationError, SentinelChainNotSupportedError, SentinelJsonRpcError, } from './errors.js';
|
|
6
|
+
import { projectLogger, createModuleLogger } from './logger.js';
|
|
7
|
+
import { SentinelSmartTransactionResponseStruct, SentinelNetworkRegistryStruct, SentinelRelaySubmitResponseStruct, SentinelSimulationResponseStruct, } from './structs.js';
|
|
20
8
|
const log = createModuleLogger(projectLogger, serviceName);
|
|
21
9
|
const MESSENGER_EXPOSED_METHODS = [
|
|
22
10
|
'getNetworks',
|
|
@@ -43,6 +31,10 @@ const MESSENGER_EXPOSED_METHODS = [
|
|
|
43
31
|
* or relay, polling loops, etc.) from the raw endpoint responses.
|
|
44
32
|
*/
|
|
45
33
|
export class SentinelApiService extends BaseDataService {
|
|
34
|
+
#fetch;
|
|
35
|
+
#clientId;
|
|
36
|
+
#clientVersion;
|
|
37
|
+
#environmentDomain;
|
|
46
38
|
/**
|
|
47
39
|
* Constructs a new SentinelApiService.
|
|
48
40
|
*
|
|
@@ -80,15 +72,10 @@ export class SentinelApiService extends BaseDataService {
|
|
|
80
72
|
...policyOptions,
|
|
81
73
|
},
|
|
82
74
|
});
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
_SentinelApiService_environmentDomain.set(this, void 0);
|
|
88
|
-
__classPrivateFieldSet(this, _SentinelApiService_fetch, fetchFunction, "f");
|
|
89
|
-
__classPrivateFieldSet(this, _SentinelApiService_environmentDomain, ENVIRONMENT_DOMAIN[environment], "f");
|
|
90
|
-
__classPrivateFieldSet(this, _SentinelApiService_clientId, clientId, "f");
|
|
91
|
-
__classPrivateFieldSet(this, _SentinelApiService_clientVersion, clientVersion, "f");
|
|
75
|
+
this.#fetch = fetchFunction;
|
|
76
|
+
this.#environmentDomain = ENVIRONMENT_DOMAIN[environment];
|
|
77
|
+
this.#clientId = clientId;
|
|
78
|
+
this.#clientVersion = clientVersion;
|
|
92
79
|
this.messenger.registerMethodActionHandlers(this, MESSENGER_EXPOSED_METHODS);
|
|
93
80
|
log('Initialized');
|
|
94
81
|
}
|
|
@@ -99,14 +86,14 @@ export class SentinelApiService extends BaseDataService {
|
|
|
99
86
|
* @returns The network registry, keyed by decimal chain ID.
|
|
100
87
|
*/
|
|
101
88
|
async getNetworks() {
|
|
102
|
-
const url = `${
|
|
89
|
+
const url = `${this.#buildUrl(NETWORKS_SUBDOMAIN)}${ENDPOINT_NETWORKS}`;
|
|
103
90
|
const result = await this.fetchQuery({
|
|
104
91
|
queryKey: [`${this.name}:getNetworks`],
|
|
105
92
|
staleTime: NETWORKS_STALE_TIME_MS,
|
|
106
93
|
queryFn: async () => {
|
|
107
|
-
const headers = await
|
|
94
|
+
const headers = await this.#getHeaders();
|
|
108
95
|
log('getNetworks', 'Request', url);
|
|
109
|
-
const response = await
|
|
96
|
+
const response = await this.#fetch(url, { headers });
|
|
110
97
|
if (!response.ok) {
|
|
111
98
|
throw new HttpError(response.status, `Sentinel API: Networks request failed with status '${response.status}'`);
|
|
112
99
|
}
|
|
@@ -136,14 +123,14 @@ export class SentinelApiService extends BaseDataService {
|
|
|
136
123
|
* @returns The simulation response.
|
|
137
124
|
*/
|
|
138
125
|
async simulateTransactions(chainId, request, options = {}) {
|
|
139
|
-
const defaultUrl = await
|
|
126
|
+
const defaultUrl = await this.#resolveUrl(chainId, 'confirmations');
|
|
140
127
|
const url = options.getUrl ? await options.getUrl(defaultUrl) : defaultUrl;
|
|
141
128
|
const result = await this.fetchQuery({
|
|
142
129
|
queryKey: [`${this.name}:simulateTransactions`, chainId, request, url],
|
|
143
130
|
staleTime: 0,
|
|
144
131
|
queryFn: async () => {
|
|
145
132
|
log('simulateTransactions', 'Request', url, request);
|
|
146
|
-
const rpcResult = await
|
|
133
|
+
const rpcResult = await this.#jsonRpc(url, RPC_METHOD_SIMULATE, [
|
|
147
134
|
request,
|
|
148
135
|
]);
|
|
149
136
|
const [error] = validate(rpcResult, SentinelSimulationResponseStruct);
|
|
@@ -164,13 +151,13 @@ export class SentinelApiService extends BaseDataService {
|
|
|
164
151
|
* @returns The relay submit response containing the tracking UUID.
|
|
165
152
|
*/
|
|
166
153
|
async submitRelayTransaction(request) {
|
|
167
|
-
const url = await
|
|
154
|
+
const url = await this.#resolveUrl(request.chainId, 'relayTransactions');
|
|
168
155
|
const result = await this.fetchQuery({
|
|
169
156
|
queryKey: [`${this.name}:submitRelayTransaction`, request],
|
|
170
157
|
staleTime: 0,
|
|
171
158
|
queryFn: async () => {
|
|
172
159
|
log('submitRelayTransaction', 'Request', url, request);
|
|
173
|
-
const rpcResult = await
|
|
160
|
+
const rpcResult = await this.#jsonRpc(url, RPC_METHOD_SEND_RELAY, [
|
|
174
161
|
request,
|
|
175
162
|
]);
|
|
176
163
|
const [error] = validate(rpcResult, SentinelRelaySubmitResponseStruct);
|
|
@@ -194,15 +181,15 @@ export class SentinelApiService extends BaseDataService {
|
|
|
194
181
|
*/
|
|
195
182
|
async getSmartTransaction(request) {
|
|
196
183
|
const { chainId, uuid } = request;
|
|
197
|
-
const baseUrl = await
|
|
184
|
+
const baseUrl = await this.#resolveUrl(chainId, 'relayTransactions');
|
|
198
185
|
const url = `${baseUrl}${ENDPOINT_SMART_TRANSACTIONS}/${uuid}`;
|
|
199
186
|
const result = await this.fetchQuery({
|
|
200
187
|
queryKey: [`${this.name}:getSmartTransaction`, chainId, uuid],
|
|
201
188
|
staleTime: 0,
|
|
202
189
|
queryFn: async () => {
|
|
203
|
-
const headers = await
|
|
190
|
+
const headers = await this.#getHeaders();
|
|
204
191
|
log('getSmartTransaction', 'Request', url);
|
|
205
|
-
const response = await
|
|
192
|
+
const response = await this.#fetch(url, { headers });
|
|
206
193
|
if (!response.ok) {
|
|
207
194
|
throw new HttpError(response.status, `Sentinel API: Smart-transaction request failed with status '${response.status}'`);
|
|
208
195
|
}
|
|
@@ -217,96 +204,103 @@ export class SentinelApiService extends BaseDataService {
|
|
|
217
204
|
});
|
|
218
205
|
return result;
|
|
219
206
|
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
}
|
|
256
|
-
return responseJson.result;
|
|
257
|
-
}, _SentinelApiService_getHeaders =
|
|
258
|
-
/**
|
|
259
|
-
* Builds the outbound headers for a Sentinel request: the client identity
|
|
260
|
-
* headers plus a best-effort `Authorization` bearer token. Token retrieval
|
|
261
|
-
* failures are swallowed so unauthenticated requests still proceed.
|
|
262
|
-
*
|
|
263
|
-
* @returns The headers to attach to the request.
|
|
264
|
-
*/
|
|
265
|
-
async function _SentinelApiService_getHeaders() {
|
|
266
|
-
const headers = {};
|
|
267
|
-
if (__classPrivateFieldGet(this, _SentinelApiService_clientId, "f") !== undefined) {
|
|
268
|
-
headers['X-Client-Id'] = __classPrivateFieldGet(this, _SentinelApiService_clientId, "f");
|
|
207
|
+
/**
|
|
208
|
+
* Performs a JSON-RPC POST to the Sentinel API and returns the `result`.
|
|
209
|
+
*
|
|
210
|
+
* @param url - The URL to post to.
|
|
211
|
+
* @param method - The JSON-RPC method name.
|
|
212
|
+
* @param params - The JSON-RPC params.
|
|
213
|
+
* @returns The `result` field of the JSON-RPC response.
|
|
214
|
+
*/
|
|
215
|
+
async #jsonRpc(url, method, params) {
|
|
216
|
+
const headers = await this.#getHeaders();
|
|
217
|
+
const response = await this.#fetch(url, {
|
|
218
|
+
method: 'POST',
|
|
219
|
+
headers: {
|
|
220
|
+
...headers,
|
|
221
|
+
'Content-Type': 'application/json',
|
|
222
|
+
},
|
|
223
|
+
body: JSON.stringify({
|
|
224
|
+
id: '1',
|
|
225
|
+
jsonrpc: '2.0',
|
|
226
|
+
method,
|
|
227
|
+
params,
|
|
228
|
+
}),
|
|
229
|
+
});
|
|
230
|
+
if (!response.ok) {
|
|
231
|
+
throw new HttpError(response.status, `Sentinel API: JSON-RPC request '${method}' failed with status '${response.status}'`);
|
|
232
|
+
}
|
|
233
|
+
const responseJson = (await response.json());
|
|
234
|
+
if (responseJson.error) {
|
|
235
|
+
const { code, message } = responseJson.error;
|
|
236
|
+
throw new SentinelJsonRpcError(`Sentinel API: JSON-RPC error: ${message}`, code);
|
|
237
|
+
}
|
|
238
|
+
if (responseJson.result === undefined) {
|
|
239
|
+
throw new SentinelJsonRpcError('Sentinel API: JSON-RPC response missing result', -32603);
|
|
240
|
+
}
|
|
241
|
+
return responseJson.result;
|
|
269
242
|
}
|
|
270
|
-
|
|
271
|
-
|
|
243
|
+
/**
|
|
244
|
+
* Builds the outbound headers for a Sentinel request: the client identity
|
|
245
|
+
* headers plus a best-effort `Authorization` bearer token. Token retrieval
|
|
246
|
+
* failures are swallowed so unauthenticated requests still proceed.
|
|
247
|
+
*
|
|
248
|
+
* @returns The headers to attach to the request.
|
|
249
|
+
*/
|
|
250
|
+
async #getHeaders() {
|
|
251
|
+
const headers = {};
|
|
252
|
+
if (this.#clientId !== undefined) {
|
|
253
|
+
headers['X-Client-Id'] = this.#clientId;
|
|
254
|
+
}
|
|
255
|
+
if (this.#clientVersion !== undefined) {
|
|
256
|
+
headers['X-Client-Version'] = this.#clientVersion;
|
|
257
|
+
}
|
|
258
|
+
try {
|
|
259
|
+
const token = await this.messenger.call('AuthenticationController:getBearerToken');
|
|
260
|
+
if (token) {
|
|
261
|
+
headers.Authorization = `Bearer ${token}`;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
catch (error) {
|
|
265
|
+
// Proceed without auth if token retrieval fails.
|
|
266
|
+
log('getHeaders', 'Auth token unavailable, proceeding unauthenticated', error);
|
|
267
|
+
}
|
|
268
|
+
return headers;
|
|
272
269
|
}
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
270
|
+
/**
|
|
271
|
+
* Resolves the Sentinel URL for a chain, asserting the required capability.
|
|
272
|
+
*
|
|
273
|
+
* @param chainId - The chain ID to resolve a URL for.
|
|
274
|
+
* @param capability - The capability flag that must be enabled.
|
|
275
|
+
* @returns The resolved base URL.
|
|
276
|
+
*/
|
|
277
|
+
async #resolveUrl(chainId, capability) {
|
|
278
|
+
const network = await this.#getNetwork(chainId);
|
|
279
|
+
if (!network?.[capability]) {
|
|
280
|
+
throw new SentinelChainNotSupportedError(chainId, capability);
|
|
277
281
|
}
|
|
282
|
+
return this.#buildUrl(network.network);
|
|
278
283
|
}
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
284
|
+
/**
|
|
285
|
+
* Looks up a single network entry from the registry by chain ID.
|
|
286
|
+
*
|
|
287
|
+
* @param chainId - The chain ID to look up.
|
|
288
|
+
* @returns The network entry, or undefined if not present.
|
|
289
|
+
*/
|
|
290
|
+
async #getNetwork(chainId) {
|
|
291
|
+
const registry = await this.getNetworks();
|
|
292
|
+
const chainIdDecimal = BigInt(chainId).toString(10);
|
|
293
|
+
return registry[chainIdDecimal];
|
|
282
294
|
}
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
async function _SentinelApiService_resolveUrl(chainId, capability) {
|
|
293
|
-
const network = await __classPrivateFieldGet(this, _SentinelApiService_instances, "m", _SentinelApiService_getNetwork).call(this, chainId);
|
|
294
|
-
if (!network?.[capability]) {
|
|
295
|
-
throw new SentinelChainNotSupportedError(chainId, capability);
|
|
295
|
+
/**
|
|
296
|
+
* Builds a Sentinel base URL for the given network subdomain, targeting the
|
|
297
|
+
* environment this service was constructed with.
|
|
298
|
+
*
|
|
299
|
+
* @param subdomain - The network subdomain (for example `ethereum-mainnet`).
|
|
300
|
+
* @returns The full base URL.
|
|
301
|
+
*/
|
|
302
|
+
#buildUrl(subdomain) {
|
|
303
|
+
return BASE_URL_TEMPLATE.replace('{0}', subdomain).replace('{1}', this.#environmentDomain);
|
|
296
304
|
}
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
/**
|
|
300
|
-
* Looks up a single network entry from the registry by chain ID.
|
|
301
|
-
*
|
|
302
|
-
* @param chainId - The chain ID to look up.
|
|
303
|
-
* @returns The network entry, or undefined if not present.
|
|
304
|
-
*/
|
|
305
|
-
async function _SentinelApiService_getNetwork(chainId) {
|
|
306
|
-
const registry = await this.getNetworks();
|
|
307
|
-
const chainIdDecimal = BigInt(chainId).toString(10);
|
|
308
|
-
return registry[chainIdDecimal];
|
|
309
|
-
}, _SentinelApiService_buildUrl = function _SentinelApiService_buildUrl(subdomain) {
|
|
310
|
-
return BASE_URL_TEMPLATE.replace('{0}', subdomain).replace('{1}', __classPrivateFieldGet(this, _SentinelApiService_environmentDomain, "f"));
|
|
311
|
-
};
|
|
312
|
-
//# sourceMappingURL=sentinel-api-service.mjs.map
|
|
305
|
+
}
|
|
306
|
+
//# sourceMappingURL=sentinel-api-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sentinel-api-service.js","sourceRoot":"","sources":["../src/sentinel-api-service.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseDataService } from '@metamask/base-data-service';\nimport { handleWhen, HttpError } from '@metamask/controller-utils';\nimport { validate } from '@metamask/superstruct';\nimport type { Hex, Json } from '@metamask/utils';\n\nimport {\n BASE_URL_TEMPLATE,\n DEFAULT_ENVIRONMENT,\n ENDPOINT_NETWORKS,\n ENDPOINT_SMART_TRANSACTIONS,\n ENVIRONMENT_DOMAIN,\n NETWORKS_STALE_TIME_MS,\n NETWORKS_SUBDOMAIN,\n RPC_METHOD_SEND_RELAY,\n RPC_METHOD_SIMULATE,\n serviceName,\n} from './constants.js';\nimport {\n SentinelApiResponseValidationError,\n SentinelChainNotSupportedError,\n SentinelJsonRpcError,\n} from './errors.js';\nimport { projectLogger, createModuleLogger } from './logger.js';\nimport {\n SentinelSmartTransactionResponseStruct,\n SentinelNetworkRegistryStruct,\n SentinelRelaySubmitResponseStruct,\n SentinelSimulationResponseStruct,\n} from './structs.js';\nimport type {\n SentinelApiServiceMessenger,\n SentinelApiServiceOptions,\n SentinelNetwork,\n SentinelNetworkRegistry,\n SentinelRelaySubmitRequest,\n SentinelRelaySubmitResponse,\n SentinelSimulationRequest,\n SentinelSimulationResponse,\n SentinelSmartTransactionRequest,\n SentinelSmartTransactionResponse,\n} from './types.js';\n\nconst log = createModuleLogger(projectLogger, serviceName);\n\nconst MESSENGER_EXPOSED_METHODS = [\n 'getNetworks',\n 'simulateTransactions',\n 'submitRelayTransaction',\n 'getSmartTransaction',\n] as const;\n\n/**\n * Data service that centralises all interactions with the MetaMask Sentinel\n * API (`tx-sentinel-<network>.api.cx.metamask.io`).\n *\n * It exposes one method per Sentinel endpoint:\n * - {@link SentinelApiService.getNetworks} — the supported-network registry\n * (`/networks`), cached since it is stable and identical across subdomains.\n * - {@link SentinelApiService.simulateTransactions} — transaction simulation\n * (`infura_simulateTransactions`), used by `@metamask/transaction-controller`\n * and `@metamask/transaction-pay-controller`.\n * - {@link SentinelApiService.submitRelayTransaction} — gas station relay\n * submission (`eth_sendRelayTransaction`), used by the extension and mobile.\n * - {@link SentinelApiService.getSmartTransaction} — smart-transaction status\n * lookup (`/smart-transactions/{uuid}`).\n *\n * Consumers derive higher-level concerns (whether a chain supports simulation\n * or relay, polling loops, etc.) from the raw endpoint responses.\n */\nexport class SentinelApiService extends BaseDataService<\n typeof serviceName,\n SentinelApiServiceMessenger\n> {\n readonly #fetch: typeof fetch;\n\n readonly #clientId?: string;\n\n readonly #clientVersion?: string;\n\n readonly #environmentDomain: string;\n\n /**\n * Constructs a new SentinelApiService.\n *\n * @param options - The constructor options. See\n * {@link SentinelApiServiceOptions}.\n * @param options.messenger - The messenger suited for this service.\n * @param options.fetch - The `fetch` function to use for requests. Defaults\n * to the global `fetch`.\n * @param options.environment - The Sentinel API environment to target\n * (`dev`, `uat`, or `prod`). Defaults to `prod`.\n * @param options.clientId - Identifier for the calling client (for example\n * `extension` or `mobile`), sent as the `X-Client-Id` header.\n * @param options.clientVersion - Version of the calling client, sent as the\n * `X-Client-Version` header when provided.\n * @param options.queryClientConfig - Configuration for the underlying\n * TanStack Query client.\n * @param options.policyOptions - Options to pass to `createServicePolicy`.\n * Retries are disabled by default (`maxRetries: 0`) to preserve the\n * single-attempt behaviour of the clients this service replaces; pass\n * `maxRetries` here to opt in.\n */\n constructor({\n messenger,\n fetch: fetchFunction = globalThis.fetch,\n environment = DEFAULT_ENVIRONMENT,\n clientId,\n clientVersion,\n queryClientConfig = {},\n policyOptions = {},\n }: SentinelApiServiceOptions) {\n super({\n name: serviceName,\n messenger,\n queryClientConfig,\n policyOptions: {\n // Disable retries by default so the service is behaviourally\n // backwards-compatible with the single-request clients it replaces.\n // Callers can override via `policyOptions.maxRetries`.\n maxRetries: 0,\n retryFilterPolicy: handleWhen(\n (error) =>\n !(error instanceof SentinelApiResponseValidationError) &&\n !(error instanceof SentinelChainNotSupportedError) &&\n !(error instanceof SentinelJsonRpcError),\n ),\n ...policyOptions,\n },\n });\n\n this.#fetch = fetchFunction;\n this.#environmentDomain = ENVIRONMENT_DOMAIN[environment];\n this.#clientId = clientId;\n this.#clientVersion = clientVersion;\n\n this.messenger.registerMethodActionHandlers(\n this,\n MESSENGER_EXPOSED_METHODS,\n );\n\n log('Initialized');\n }\n\n /**\n * Fetches the Sentinel supported-network registry. The result is cached, as\n * the registry is stable and identical across network subdomains.\n *\n * @returns The network registry, keyed by decimal chain ID.\n */\n async getNetworks(): Promise<SentinelNetworkRegistry> {\n const url = `${this.#buildUrl(NETWORKS_SUBDOMAIN)}${ENDPOINT_NETWORKS}`;\n\n const result = await this.fetchQuery({\n queryKey: [`${this.name}:getNetworks`],\n staleTime: NETWORKS_STALE_TIME_MS,\n queryFn: async (): Promise<Json> => {\n const headers = await this.#getHeaders();\n\n log('getNetworks', 'Request', url);\n\n const response = await this.#fetch(url, { headers });\n\n if (!response.ok) {\n throw new HttpError(\n response.status,\n `Sentinel API: Networks request failed with status '${response.status}'`,\n );\n }\n\n const json: Json = await response.json();\n\n const [error] = validate(json, SentinelNetworkRegistryStruct);\n if (error) {\n throw new SentinelApiResponseValidationError(\n `Sentinel API: Malformed response from networks endpoint: ${error.message}`,\n );\n }\n\n log('getNetworks', 'Response', json);\n\n return json;\n },\n });\n\n return result as unknown as SentinelNetworkRegistry;\n }\n\n /**\n * Simulates transactions against the Sentinel API via\n * `infura_simulateTransactions`. Not cached, since each request body is\n * unique and stale simulations must not be reused.\n *\n * @param chainId - The chain ID to simulate on.\n * @param request - The simulation request.\n * @param options - Additional options.\n * @param options.getUrl - Optional callback that receives the default\n * Sentinel URL resolved for the chain and returns the URL to use instead.\n * Lets consumers rewrite the request URL (for example to route through the\n * MetaMask Shield proxy) without the service knowing about those concerns.\n * @returns The simulation response.\n */\n async simulateTransactions(\n chainId: Hex,\n request: SentinelSimulationRequest,\n options: { getUrl?: (defaultUrl: string) => string | Promise<string> } = {},\n ): Promise<SentinelSimulationResponse> {\n const defaultUrl = await this.#resolveUrl(chainId, 'confirmations');\n const url = options.getUrl ? await options.getUrl(defaultUrl) : defaultUrl;\n\n const result = await this.fetchQuery({\n queryKey: [`${this.name}:simulateTransactions`, chainId, request, url],\n staleTime: 0,\n queryFn: async (): Promise<Json> => {\n log('simulateTransactions', 'Request', url, request);\n\n const rpcResult = await this.#jsonRpc(url, RPC_METHOD_SIMULATE, [\n request,\n ]);\n\n const [error] = validate(rpcResult, SentinelSimulationResponseStruct);\n if (error) {\n throw new SentinelApiResponseValidationError(\n `Sentinel API: Malformed response from simulation endpoint: ${error.message}`,\n );\n }\n\n log('simulateTransactions', 'Response', rpcResult);\n\n return rpcResult;\n },\n });\n\n return result as unknown as SentinelSimulationResponse;\n }\n\n /**\n * Submits a signed relay (gas station) transaction to the Sentinel API via\n * `eth_sendRelayTransaction`. Not cached.\n *\n * @param request - The relay submit request.\n * @returns The relay submit response containing the tracking UUID.\n */\n async submitRelayTransaction(\n request: SentinelRelaySubmitRequest,\n ): Promise<SentinelRelaySubmitResponse> {\n const url = await this.#resolveUrl(request.chainId, 'relayTransactions');\n\n const result = await this.fetchQuery({\n queryKey: [`${this.name}:submitRelayTransaction`, request],\n staleTime: 0,\n queryFn: async (): Promise<Json> => {\n log('submitRelayTransaction', 'Request', url, request);\n\n const rpcResult = await this.#jsonRpc(url, RPC_METHOD_SEND_RELAY, [\n request,\n ]);\n\n const [error] = validate(rpcResult, SentinelRelaySubmitResponseStruct);\n if (error) {\n throw new SentinelApiResponseValidationError(\n `Sentinel API: Malformed response from relay submit endpoint: ${error.message}`,\n );\n }\n\n log('submitRelayTransaction', 'Response', rpcResult);\n\n return rpcResult;\n },\n });\n\n return result as unknown as SentinelRelaySubmitResponse;\n }\n\n /**\n * Looks up the state of a submitted smart transaction by UUID against the\n * `/smart-transactions/{uuid}` endpoint. Performs a single request; callers\n * own any polling loop. Not cached.\n *\n * @param request - The smart-transaction lookup request.\n * @returns The response envelope containing the smart transaction(s)\n * associated with the requested UUID.\n */\n async getSmartTransaction(\n request: SentinelSmartTransactionRequest,\n ): Promise<SentinelSmartTransactionResponse> {\n const { chainId, uuid } = request;\n const baseUrl = await this.#resolveUrl(chainId, 'relayTransactions');\n const url = `${baseUrl}${ENDPOINT_SMART_TRANSACTIONS}/${uuid}`;\n\n const result = await this.fetchQuery({\n queryKey: [`${this.name}:getSmartTransaction`, chainId, uuid],\n staleTime: 0,\n queryFn: async (): Promise<Json> => {\n const headers = await this.#getHeaders();\n\n log('getSmartTransaction', 'Request', url);\n\n const response = await this.#fetch(url, { headers });\n\n if (!response.ok) {\n throw new HttpError(\n response.status,\n `Sentinel API: Smart-transaction request failed with status '${response.status}'`,\n );\n }\n\n const json: Json = await response.json();\n\n const [error] = validate(json, SentinelSmartTransactionResponseStruct);\n if (error) {\n throw new SentinelApiResponseValidationError(\n `Sentinel API: Malformed response from smart-transactions endpoint: ${error.message}`,\n );\n }\n\n log('getSmartTransaction', 'Response', json);\n\n return json;\n },\n });\n\n return result as unknown as SentinelSmartTransactionResponse;\n }\n\n /**\n * Performs a JSON-RPC POST to the Sentinel API and returns the `result`.\n *\n * @param url - The URL to post to.\n * @param method - The JSON-RPC method name.\n * @param params - The JSON-RPC params.\n * @returns The `result` field of the JSON-RPC response.\n */\n async #jsonRpc(url: string, method: string, params: Json[]): Promise<Json> {\n const headers = await this.#getHeaders();\n\n const response = await this.#fetch(url, {\n method: 'POST',\n headers: {\n ...headers,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n id: '1',\n jsonrpc: '2.0',\n method,\n params,\n }),\n });\n\n if (!response.ok) {\n throw new HttpError(\n response.status,\n `Sentinel API: JSON-RPC request '${method}' failed with status '${response.status}'`,\n );\n }\n\n const responseJson = (await response.json()) as {\n error?: { code?: number; message?: string };\n result?: Json;\n };\n\n if (responseJson.error) {\n const { code, message } = responseJson.error;\n throw new SentinelJsonRpcError(\n `Sentinel API: JSON-RPC error: ${message}`,\n code,\n );\n }\n\n if (responseJson.result === undefined) {\n throw new SentinelJsonRpcError(\n 'Sentinel API: JSON-RPC response missing result',\n -32603,\n );\n }\n\n return responseJson.result;\n }\n\n /**\n * Builds the outbound headers for a Sentinel request: the client identity\n * headers plus a best-effort `Authorization` bearer token. Token retrieval\n * failures are swallowed so unauthenticated requests still proceed.\n *\n * @returns The headers to attach to the request.\n */\n async #getHeaders(): Promise<Record<string, string>> {\n const headers: Record<string, string> = {};\n\n if (this.#clientId !== undefined) {\n headers['X-Client-Id'] = this.#clientId;\n }\n\n if (this.#clientVersion !== undefined) {\n headers['X-Client-Version'] = this.#clientVersion;\n }\n\n try {\n const token = await this.messenger.call(\n 'AuthenticationController:getBearerToken',\n );\n if (token) {\n headers.Authorization = `Bearer ${token}`;\n }\n } catch (error: unknown) {\n // Proceed without auth if token retrieval fails.\n log(\n 'getHeaders',\n 'Auth token unavailable, proceeding unauthenticated',\n error,\n );\n }\n\n return headers;\n }\n\n /**\n * Resolves the Sentinel URL for a chain, asserting the required capability.\n *\n * @param chainId - The chain ID to resolve a URL for.\n * @param capability - The capability flag that must be enabled.\n * @returns The resolved base URL.\n */\n async #resolveUrl(\n chainId: Hex,\n capability: 'confirmations' | 'relayTransactions',\n ): Promise<string> {\n const network = await this.#getNetwork(chainId);\n\n if (!network?.[capability]) {\n throw new SentinelChainNotSupportedError(chainId, capability);\n }\n\n return this.#buildUrl(network.network);\n }\n\n /**\n * Looks up a single network entry from the registry by chain ID.\n *\n * @param chainId - The chain ID to look up.\n * @returns The network entry, or undefined if not present.\n */\n async #getNetwork(chainId: Hex): Promise<SentinelNetwork | undefined> {\n const registry = await this.getNetworks();\n const chainIdDecimal = BigInt(chainId).toString(10);\n return registry[chainIdDecimal];\n }\n\n /**\n * Builds a Sentinel base URL for the given network subdomain, targeting the\n * environment this service was constructed with.\n *\n * @param subdomain - The network subdomain (for example `ethereum-mainnet`).\n * @returns The full base URL.\n */\n #buildUrl(subdomain: string): string {\n return BASE_URL_TEMPLATE.replace('{0}', subdomain).replace(\n '{1}',\n this.#environmentDomain,\n );\n }\n}\n"]}
|