@metamask/network-controller 22.2.1 → 23.0.0

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.
Files changed (70) hide show
  1. package/CHANGELOG.md +62 -2
  2. package/dist/NetworkController.cjs +63 -30
  3. package/dist/NetworkController.cjs.map +1 -1
  4. package/dist/NetworkController.d.cts +89 -5
  5. package/dist/NetworkController.d.cts.map +1 -1
  6. package/dist/NetworkController.d.mts +89 -5
  7. package/dist/NetworkController.d.mts.map +1 -1
  8. package/dist/NetworkController.mjs +63 -30
  9. package/dist/NetworkController.mjs.map +1 -1
  10. package/dist/create-auto-managed-network-client.cjs +26 -6
  11. package/dist/create-auto-managed-network-client.cjs.map +1 -1
  12. package/dist/create-auto-managed-network-client.d.cts +12 -2
  13. package/dist/create-auto-managed-network-client.d.cts.map +1 -1
  14. package/dist/create-auto-managed-network-client.d.mts +12 -2
  15. package/dist/create-auto-managed-network-client.d.mts.map +1 -1
  16. package/dist/create-auto-managed-network-client.mjs +26 -6
  17. package/dist/create-auto-managed-network-client.mjs.map +1 -1
  18. package/dist/create-network-client.cjs +56 -17
  19. package/dist/create-network-client.cjs.map +1 -1
  20. package/dist/create-network-client.d.cts +13 -2
  21. package/dist/create-network-client.d.cts.map +1 -1
  22. package/dist/create-network-client.d.mts +13 -2
  23. package/dist/create-network-client.d.mts.map +1 -1
  24. package/dist/create-network-client.mjs +56 -17
  25. package/dist/create-network-client.mjs.map +1 -1
  26. package/dist/index.cjs +3 -1
  27. package/dist/index.cjs.map +1 -1
  28. package/dist/index.d.cts +3 -1
  29. package/dist/index.d.cts.map +1 -1
  30. package/dist/index.d.mts +3 -1
  31. package/dist/index.d.mts.map +1 -1
  32. package/dist/index.mjs +1 -0
  33. package/dist/index.mjs.map +1 -1
  34. package/dist/rpc-service/abstract-rpc-service.cjs.map +1 -1
  35. package/dist/rpc-service/abstract-rpc-service.d.cts +5 -39
  36. package/dist/rpc-service/abstract-rpc-service.d.cts.map +1 -1
  37. package/dist/rpc-service/abstract-rpc-service.d.mts +5 -39
  38. package/dist/rpc-service/abstract-rpc-service.d.mts.map +1 -1
  39. package/dist/rpc-service/abstract-rpc-service.mjs.map +1 -1
  40. package/dist/rpc-service/rpc-service-chain.cjs +10 -23
  41. package/dist/rpc-service/rpc-service-chain.cjs.map +1 -1
  42. package/dist/rpc-service/rpc-service-chain.d.cts +10 -35
  43. package/dist/rpc-service/rpc-service-chain.d.cts.map +1 -1
  44. package/dist/rpc-service/rpc-service-chain.d.mts +10 -35
  45. package/dist/rpc-service/rpc-service-chain.d.mts.map +1 -1
  46. package/dist/rpc-service/rpc-service-chain.mjs +10 -23
  47. package/dist/rpc-service/rpc-service-chain.mjs.map +1 -1
  48. package/dist/rpc-service/rpc-service-requestable.cjs +3 -0
  49. package/dist/rpc-service/rpc-service-requestable.cjs.map +1 -0
  50. package/dist/rpc-service/rpc-service-requestable.d.cts +47 -0
  51. package/dist/rpc-service/rpc-service-requestable.d.cts.map +1 -0
  52. package/dist/rpc-service/rpc-service-requestable.d.mts +47 -0
  53. package/dist/rpc-service/rpc-service-requestable.d.mts.map +1 -0
  54. package/dist/rpc-service/rpc-service-requestable.mjs +2 -0
  55. package/dist/rpc-service/rpc-service-requestable.mjs.map +1 -0
  56. package/dist/rpc-service/rpc-service.cjs +108 -47
  57. package/dist/rpc-service/rpc-service.cjs.map +1 -1
  58. package/dist/rpc-service/rpc-service.d.cts +63 -27
  59. package/dist/rpc-service/rpc-service.d.cts.map +1 -1
  60. package/dist/rpc-service/rpc-service.d.mts +63 -27
  61. package/dist/rpc-service/rpc-service.d.mts.map +1 -1
  62. package/dist/rpc-service/rpc-service.mjs +106 -45
  63. package/dist/rpc-service/rpc-service.mjs.map +1 -1
  64. package/dist/types.cjs.map +1 -1
  65. package/dist/types.d.cts +11 -6
  66. package/dist/types.d.cts.map +1 -1
  67. package/dist/types.d.mts +11 -6
  68. package/dist/types.d.mts.map +1 -1
  69. package/dist/types.mjs.map +1 -1
  70. package/package.json +7 -5
@@ -1,48 +1,24 @@
1
1
  import type { Json, JsonRpcParams, JsonRpcRequest, JsonRpcResponse } from "@metamask/utils";
2
- import type { AbstractRpcService } from "./abstract-rpc-service.mjs";
3
2
  import { RpcService } from "./rpc-service.mjs";
3
+ import type { RpcServiceOptions } from "./rpc-service.mjs";
4
+ import type { RpcServiceRequestable } from "./rpc-service-requestable.mjs";
4
5
  import type { FetchOptions } from "./shared.mjs";
5
- /**
6
- * The subset of options accepted by the RpcServiceChain constructor which
7
- * represent a single endpoint.
8
- */
9
- type RpcServiceConfiguration = {
10
- /**
11
- * The URL of the endpoint.
12
- */
13
- endpointUrl: URL | string;
14
- /**
15
- * The options to pass to `fetch` when making the request to the endpoint.
16
- */
17
- fetchOptions?: FetchOptions;
18
- };
19
6
  /**
20
7
  * This class constructs a chain of RpcService objects which represent a
21
- * particular network. The first object in the chain is intended to be the primary
22
- * way of reaching the network and the remaining objects are used as failovers.
8
+ * particular network. The first object in the chain is intended to be the
9
+ * primary way of reaching the network and the remaining objects are used as
10
+ * failovers.
23
11
  */
24
- export declare class RpcServiceChain implements AbstractRpcService {
12
+ export declare class RpcServiceChain implements RpcServiceRequestable {
25
13
  #private;
26
14
  /**
27
15
  * Constructs a new RpcServiceChain object.
28
16
  *
29
- * @param args - The arguments.
30
- * @param args.fetch - A function that can be used to make an HTTP request.
31
- * If your JavaScript environment supports `fetch` natively, you'll probably
32
- * want to pass that; otherwise you can pass an equivalent (such as `fetch`
33
- * via `node-fetch`).
34
- * @param args.btoa - A function that can be used to convert a binary string
35
- * into base-64. Used to encode authorization credentials.
36
- * @param args.serviceConfigurations - The options for the RPC services that
37
- * you want to construct. This class takes a set of configuration objects and
38
- * not literal `RpcService`s to account for the possibility that we may want
39
- * to send request headers to official Infura endpoints and not failovers.
17
+ * @param rpcServiceConfigurations - The options for the RPC services
18
+ * that you want to construct. Each object in this array is the same as
19
+ * {@link RpcServiceOptions}.
40
20
  */
41
- constructor({ fetch: givenFetch, btoa: givenBtoa, serviceConfigurations, }: {
42
- fetch: typeof fetch;
43
- btoa: typeof btoa;
44
- serviceConfigurations: RpcServiceConfiguration[];
45
- });
21
+ constructor(rpcServiceConfigurations: Omit<RpcServiceOptions, 'failoverService'>[]);
46
22
  /**
47
23
  * Listens for when any of the RPC services retry a request.
48
24
  *
@@ -112,5 +88,4 @@ export declare class RpcServiceChain implements AbstractRpcService {
112
88
  */
113
89
  request<Params extends JsonRpcParams, Result extends Json>(jsonRpcRequest: JsonRpcRequest<Params>, fetchOptions?: FetchOptions): Promise<JsonRpcResponse<Result>>;
114
90
  }
115
- export {};
116
91
  //# sourceMappingURL=rpc-service-chain.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"rpc-service-chain.d.mts","sourceRoot":"","sources":["../../src/rpc-service/rpc-service-chain.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,IAAI,EACJ,aAAa,EACb,cAAc,EACd,eAAe,EAChB,wBAAwB;AAEzB,OAAO,KAAK,EAAE,kBAAkB,EAAE,mCAA+B;AACjE,OAAO,EAAE,UAAU,EAAE,0BAAsB;AAC3C,OAAO,KAAK,EAAE,YAAY,EAAE,qBAAiB;AAE7C;;;GAGG;AACH,KAAK,uBAAuB,GAAG;IAC7B;;OAEG;IACH,WAAW,EAAE,GAAG,GAAG,MAAM,CAAC;IAC1B;;OAEG;IACH,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B,CAAC;AAEF;;;;GAIG;AACH,qBAAa,eAAgB,YAAW,kBAAkB;;IAGxD;;;;;;;;;;;;;;OAcG;gBACS,EACV,KAAK,EAAE,UAAU,EACjB,IAAI,EAAE,SAAS,EACf,qBAAqB,GACtB,EAAE;QACD,KAAK,EAAE,OAAO,KAAK,CAAC;QACpB,IAAI,EAAE,OAAO,IAAI,CAAC;QAClB,qBAAqB,EAAE,uBAAuB,EAAE,CAAC;KAClD;IAQD;;;;;OAKG;IACH,OAAO,CAAC,QAAQ,EAAE,UAAU,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;;;IAYtD;;;;;;OAMG;IACH,OAAO,CAAC,QAAQ,EAAE,UAAU,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;;;IAYtD;;;;;OAKG;IACH,UAAU,CAAC,QAAQ,EAAE,UAAU,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;;;IAY5D;;;;;;;;;;;;;;;;;OAiBG;IACG,OAAO,CAAC,MAAM,SAAS,aAAa,EAAE,MAAM,SAAS,IAAI,EAC7D,cAAc,EAAE,cAAc,CAAC,MAAM,CAAC,GAAG;QAAE,MAAM,EAAE,sBAAsB,CAAA;KAAE,EAC3E,YAAY,CAAC,EAAE,YAAY,GAC1B,OAAO,CAAC,eAAe,CAAC,MAAM,CAAC,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IAE3D;;;;;;;;;;;;;;;;;OAiBG;IACG,OAAO,CAAC,MAAM,SAAS,aAAa,EAAE,MAAM,SAAS,IAAI,EAC7D,cAAc,EAAE,cAAc,CAAC,MAAM,CAAC,EACtC,YAAY,CAAC,EAAE,YAAY,GAC1B,OAAO,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;CA4CpC"}
1
+ {"version":3,"file":"rpc-service-chain.d.mts","sourceRoot":"","sources":["../../src/rpc-service/rpc-service-chain.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,IAAI,EACJ,aAAa,EACb,cAAc,EACd,eAAe,EAChB,wBAAwB;AAEzB,OAAO,EAAE,UAAU,EAAE,0BAAsB;AAC3C,OAAO,KAAK,EAAE,iBAAiB,EAAE,0BAAsB;AACvD,OAAO,KAAK,EAAE,qBAAqB,EAAE,sCAAkC;AACvE,OAAO,KAAK,EAAE,YAAY,EAAE,qBAAiB;AAE7C;;;;;GAKG;AACH,qBAAa,eAAgB,YAAW,qBAAqB;;IAG3D;;;;;;OAMG;gBAED,wBAAwB,EAAE,IAAI,CAAC,iBAAiB,EAAE,iBAAiB,CAAC,EAAE;IAKxE;;;;;OAKG;IACH,OAAO,CAAC,QAAQ,EAAE,UAAU,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;;;IAYtD;;;;;;OAMG;IACH,OAAO,CAAC,QAAQ,EAAE,UAAU,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;;;IAYtD;;;;;OAKG;IACH,UAAU,CAAC,QAAQ,EAAE,UAAU,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;;;IAY5D;;;;;;;;;;;;;;;;;OAiBG;IACG,OAAO,CAAC,MAAM,SAAS,aAAa,EAAE,MAAM,SAAS,IAAI,EAC7D,cAAc,EAAE,cAAc,CAAC,MAAM,CAAC,GAAG;QAAE,MAAM,EAAE,sBAAsB,CAAA;KAAE,EAC3E,YAAY,CAAC,EAAE,YAAY,GAC1B,OAAO,CAAC,eAAe,CAAC,MAAM,CAAC,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IAE3D;;;;;;;;;;;;;;;;;OAiBG;IACG,OAAO,CAAC,MAAM,SAAS,aAAa,EAAE,MAAM,SAAS,IAAI,EAC7D,cAAc,EAAE,cAAc,CAAC,MAAM,CAAC,EACtC,YAAY,CAAC,EAAE,YAAY,GAC1B,OAAO,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;CAiCpC"}
@@ -13,33 +13,22 @@ var _RpcServiceChain_instances, _RpcServiceChain_services, _RpcServiceChain_buil
13
13
  import { RpcService } from "./rpc-service.mjs";
14
14
  /**
15
15
  * This class constructs a chain of RpcService objects which represent a
16
- * particular network. The first object in the chain is intended to be the primary
17
- * way of reaching the network and the remaining objects are used as failovers.
16
+ * particular network. The first object in the chain is intended to be the
17
+ * primary way of reaching the network and the remaining objects are used as
18
+ * failovers.
18
19
  */
19
20
  export class RpcServiceChain {
20
21
  /**
21
22
  * Constructs a new RpcServiceChain object.
22
23
  *
23
- * @param args - The arguments.
24
- * @param args.fetch - A function that can be used to make an HTTP request.
25
- * If your JavaScript environment supports `fetch` natively, you'll probably
26
- * want to pass that; otherwise you can pass an equivalent (such as `fetch`
27
- * via `node-fetch`).
28
- * @param args.btoa - A function that can be used to convert a binary string
29
- * into base-64. Used to encode authorization credentials.
30
- * @param args.serviceConfigurations - The options for the RPC services that
31
- * you want to construct. This class takes a set of configuration objects and
32
- * not literal `RpcService`s to account for the possibility that we may want
33
- * to send request headers to official Infura endpoints and not failovers.
24
+ * @param rpcServiceConfigurations - The options for the RPC services
25
+ * that you want to construct. Each object in this array is the same as
26
+ * {@link RpcServiceOptions}.
34
27
  */
35
- constructor({ fetch: givenFetch, btoa: givenBtoa, serviceConfigurations, }) {
28
+ constructor(rpcServiceConfigurations) {
36
29
  _RpcServiceChain_instances.add(this);
37
30
  _RpcServiceChain_services.set(this, void 0);
38
- __classPrivateFieldSet(this, _RpcServiceChain_services, __classPrivateFieldGet(this, _RpcServiceChain_instances, "m", _RpcServiceChain_buildRpcServiceChain).call(this, {
39
- serviceConfigurations,
40
- fetch: givenFetch,
41
- btoa: givenBtoa,
42
- }), "f");
31
+ __classPrivateFieldSet(this, _RpcServiceChain_services, __classPrivateFieldGet(this, _RpcServiceChain_instances, "m", _RpcServiceChain_buildRpcServiceChain).call(this, rpcServiceConfigurations), "f");
43
32
  }
44
33
  /**
45
34
  * Listens for when any of the RPC services retry a request.
@@ -88,14 +77,12 @@ export class RpcServiceChain {
88
77
  return __classPrivateFieldGet(this, _RpcServiceChain_services, "f")[0].request(jsonRpcRequest, fetchOptions);
89
78
  }
90
79
  }
91
- _RpcServiceChain_services = new WeakMap(), _RpcServiceChain_instances = new WeakSet(), _RpcServiceChain_buildRpcServiceChain = function _RpcServiceChain_buildRpcServiceChain({ serviceConfigurations, fetch: givenFetch, btoa: givenBtoa, }) {
92
- return [...serviceConfigurations]
80
+ _RpcServiceChain_services = new WeakMap(), _RpcServiceChain_instances = new WeakSet(), _RpcServiceChain_buildRpcServiceChain = function _RpcServiceChain_buildRpcServiceChain(rpcServiceConfigurations) {
81
+ return [...rpcServiceConfigurations]
93
82
  .reverse()
94
83
  .reduce((workingServices, serviceConfiguration, index) => {
95
84
  const failoverService = index > 0 ? workingServices[0] : undefined;
96
85
  const service = new RpcService({
97
- fetch: givenFetch,
98
- btoa: givenBtoa,
99
86
  ...serviceConfiguration,
100
87
  failoverService,
101
88
  });
@@ -1 +1 @@
1
- {"version":3,"file":"rpc-service-chain.mjs","sourceRoot":"","sources":["../../src/rpc-service/rpc-service-chain.ts"],"names":[],"mappings":";;;;;;;;;;;;AAQA,OAAO,EAAE,UAAU,EAAE,0BAAsB;AAkB3C;;;;GAIG;AACH,MAAM,OAAO,eAAe;IAG1B;;;;;;;;;;;;;;OAcG;IACH,YAAY,EACV,KAAK,EAAE,UAAU,EACjB,IAAI,EAAE,SAAS,EACf,qBAAqB,GAKtB;;QAzBQ,4CAAwB;QA0B/B,uBAAA,IAAI,6BAAa,uBAAA,IAAI,yEAAsB,MAA1B,IAAI,EAAuB;YAC1C,qBAAqB;YACrB,KAAK,EAAE,UAAU;YACjB,IAAI,EAAE,SAAS;SAChB,CAAC,MAAA,CAAC;IACL,CAAC;IAED;;;;;OAKG;IACH,OAAO,CAAC,QAA8C;QACpD,MAAM,WAAW,GAAG,uBAAA,IAAI,iCAAU,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CACjD,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAC1B,CAAC;QAEF,OAAO;YACL,OAAO;gBACL,WAAW,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC;YAC5D,CAAC;SACF,CAAC;IACJ,CAAC;IAED;;;;;;OAMG;IACH,OAAO,CAAC,QAA8C;QACpD,MAAM,WAAW,GAAG,uBAAA,IAAI,iCAAU,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CACjD,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAC1B,CAAC;QAEF,OAAO;YACL,OAAO;gBACL,WAAW,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC;YAC5D,CAAC;SACF,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACH,UAAU,CAAC,QAAiD;QAC1D,MAAM,WAAW,GAAG,uBAAA,IAAI,iCAAU,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CACjD,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,CAC7B,CAAC;QAEF,OAAO;YACL,OAAO;gBACL,WAAW,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC;YAC5D,CAAC;SACF,CAAC;IACJ,CAAC;IAgDD,KAAK,CAAC,OAAO,CACX,cAAsC,EACtC,eAA6B,EAAE;QAE/B,OAAO,uBAAA,IAAI,iCAAU,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC;IACjE,CAAC;CAqCF;8KAtBuB,EACpB,qBAAqB,EACrB,KAAK,EAAE,UAAU,EACjB,IAAI,EAAE,SAAS,GAKhB;IACC,OAAO,CAAC,GAAG,qBAAqB,CAAC;SAC9B,OAAO,EAAE;SACT,MAAM,CAAC,CAAC,eAA6B,EAAE,oBAAoB,EAAE,KAAK,EAAE,EAAE;QACrE,MAAM,eAAe,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACnE,MAAM,OAAO,GAAG,IAAI,UAAU,CAAC;YAC7B,KAAK,EAAE,UAAU;YACjB,IAAI,EAAE,SAAS;YACf,GAAG,oBAAoB;YACvB,eAAe;SAChB,CAAC,CAAC;QACH,OAAO,CAAC,OAAO,EAAE,GAAG,eAAe,CAAC,CAAC;IACvC,CAAC,EAAE,EAAE,CAAC,CAAC;AACX,CAAC","sourcesContent":["import type {\n Json,\n JsonRpcParams,\n JsonRpcRequest,\n JsonRpcResponse,\n} from '@metamask/utils';\n\nimport type { AbstractRpcService } from './abstract-rpc-service';\nimport { RpcService } from './rpc-service';\nimport type { FetchOptions } from './shared';\n\n/**\n * The subset of options accepted by the RpcServiceChain constructor which\n * represent a single endpoint.\n */\ntype RpcServiceConfiguration = {\n /**\n * The URL of the endpoint.\n */\n endpointUrl: URL | string;\n /**\n * The options to pass to `fetch` when making the request to the endpoint.\n */\n fetchOptions?: FetchOptions;\n};\n\n/**\n * This class constructs a chain of RpcService objects which represent a\n * particular network. The first object in the chain is intended to be the primary\n * way of reaching the network and the remaining objects are used as failovers.\n */\nexport class RpcServiceChain implements AbstractRpcService {\n readonly #services: RpcService[];\n\n /**\n * Constructs a new RpcServiceChain object.\n *\n * @param args - The arguments.\n * @param args.fetch - A function that can be used to make an HTTP request.\n * If your JavaScript environment supports `fetch` natively, you'll probably\n * want to pass that; otherwise you can pass an equivalent (such as `fetch`\n * via `node-fetch`).\n * @param args.btoa - A function that can be used to convert a binary string\n * into base-64. Used to encode authorization credentials.\n * @param args.serviceConfigurations - The options for the RPC services that\n * you want to construct. This class takes a set of configuration objects and\n * not literal `RpcService`s to account for the possibility that we may want\n * to send request headers to official Infura endpoints and not failovers.\n */\n constructor({\n fetch: givenFetch,\n btoa: givenBtoa,\n serviceConfigurations,\n }: {\n fetch: typeof fetch;\n btoa: typeof btoa;\n serviceConfigurations: RpcServiceConfiguration[];\n }) {\n this.#services = this.#buildRpcServiceChain({\n serviceConfigurations,\n fetch: givenFetch,\n btoa: givenBtoa,\n });\n }\n\n /**\n * Listens for when any of the RPC services retry a request.\n *\n * @param listener - The callback to be called when the retry occurs.\n * @returns What {@link RpcService.onRetry} returns.\n */\n onRetry(listener: Parameters<RpcService['onRetry']>[0]) {\n const disposables = this.#services.map((service) =>\n service.onRetry(listener),\n );\n\n return {\n dispose() {\n disposables.forEach((disposable) => disposable.dispose());\n },\n };\n }\n\n /**\n * Listens for when any of the RPC services retry the request too many times\n * in a row.\n *\n * @param listener - The callback to be called when the retry occurs.\n * @returns What {@link RpcService.onBreak} returns.\n */\n onBreak(listener: Parameters<RpcService['onBreak']>[0]) {\n const disposables = this.#services.map((service) =>\n service.onBreak(listener),\n );\n\n return {\n dispose() {\n disposables.forEach((disposable) => disposable.dispose());\n },\n };\n }\n\n /**\n * Listens for when any of the RPC services send a slow request.\n *\n * @param listener - The callback to be called when the retry occurs.\n * @returns What {@link RpcService.onRetry} returns.\n */\n onDegraded(listener: Parameters<RpcService['onDegraded']>[0]) {\n const disposables = this.#services.map((service) =>\n service.onDegraded(listener),\n );\n\n return {\n dispose() {\n disposables.forEach((disposable) => disposable.dispose());\n },\n };\n }\n\n /**\n * Makes a request to the first RPC service in the chain. If this service is\n * down, then the request is forwarded to the next service in the chain, etc.\n *\n * This overload is specifically designed for `eth_getBlockByNumber`, which\n * can return a `result` of `null` despite an expected `Result` being\n * provided.\n *\n * @param jsonRpcRequest - The JSON-RPC request to send to the endpoint.\n * @param fetchOptions - An options bag for {@link fetch} which further\n * specifies the request.\n * @returns The decoded JSON-RPC response from the endpoint.\n * @throws A \"method not found\" error if the response status is 405.\n * @throws A rate limiting error if the response HTTP status is 429.\n * @throws A timeout error if the response HTTP status is 503 or 504.\n * @throws A generic error if the response HTTP status is not 2xx but also not\n * 405, 429, 503, or 504.\n */\n async request<Params extends JsonRpcParams, Result extends Json>(\n jsonRpcRequest: JsonRpcRequest<Params> & { method: 'eth_getBlockByNumber' },\n fetchOptions?: FetchOptions,\n ): Promise<JsonRpcResponse<Result> | JsonRpcResponse<null>>;\n\n /**\n * Makes a request to the first RPC service in the chain. If this service is\n * down, then the request is forwarded to the next service in the chain, etc.\n *\n * This overload is designed for all RPC methods except for\n * `eth_getBlockByNumber`, which are expected to return a `result` of the\n * expected `Result`.\n *\n * @param jsonRpcRequest - The JSON-RPC request to send to the endpoint.\n * @param fetchOptions - An options bag for {@link fetch} which further\n * specifies the request.\n * @returns The decoded JSON-RPC response from the endpoint.\n * @throws A \"method not found\" error if the response status is 405.\n * @throws A rate limiting error if the response HTTP status is 429.\n * @throws A timeout error if the response HTTP status is 503 or 504.\n * @throws A generic error if the response HTTP status is not 2xx but also not\n * 405, 429, 503, or 504.\n */\n async request<Params extends JsonRpcParams, Result extends Json>(\n jsonRpcRequest: JsonRpcRequest<Params>,\n fetchOptions?: FetchOptions,\n ): Promise<JsonRpcResponse<Result>>;\n\n async request<Params extends JsonRpcParams, Result extends Json>(\n jsonRpcRequest: JsonRpcRequest<Params>,\n fetchOptions: FetchOptions = {},\n ): Promise<JsonRpcResponse<Result | null>> {\n return this.#services[0].request(jsonRpcRequest, fetchOptions);\n }\n\n /**\n * Constructs the chain of RPC services. The second RPC service is\n * configured as the failover for the first, the third service is\n * configured as the failover for the second, etc.\n *\n * @param args - The arguments.\n * @param args.serviceConfigurations - The options for the RPC services that\n * you want to construct.\n * @param args.fetch - A function that can be used to make an HTTP request.\n * @param args.btoa - A function that can be used to convert a binary string\n * into base-64. Used to encode authorization credentials.\n * @returns The constructed chain of RPC services.\n */\n #buildRpcServiceChain({\n serviceConfigurations,\n fetch: givenFetch,\n btoa: givenBtoa,\n }: {\n serviceConfigurations: RpcServiceConfiguration[];\n fetch: typeof fetch;\n btoa: typeof btoa;\n }): RpcService[] {\n return [...serviceConfigurations]\n .reverse()\n .reduce((workingServices: RpcService[], serviceConfiguration, index) => {\n const failoverService = index > 0 ? workingServices[0] : undefined;\n const service = new RpcService({\n fetch: givenFetch,\n btoa: givenBtoa,\n ...serviceConfiguration,\n failoverService,\n });\n return [service, ...workingServices];\n }, []);\n }\n}\n"]}
1
+ {"version":3,"file":"rpc-service-chain.mjs","sourceRoot":"","sources":["../../src/rpc-service/rpc-service-chain.ts"],"names":[],"mappings":";;;;;;;;;;;;AAOA,OAAO,EAAE,UAAU,EAAE,0BAAsB;AAK3C;;;;;GAKG;AACH,MAAM,OAAO,eAAe;IAG1B;;;;;;OAMG;IACH,YACE,wBAAsE;;QAV/D,4CAAwB;QAY/B,uBAAA,IAAI,6BAAa,uBAAA,IAAI,yEAAsB,MAA1B,IAAI,EAAuB,wBAAwB,CAAC,MAAA,CAAC;IACxE,CAAC;IAED;;;;;OAKG;IACH,OAAO,CAAC,QAA8C;QACpD,MAAM,WAAW,GAAG,uBAAA,IAAI,iCAAU,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CACjD,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAC1B,CAAC;QAEF,OAAO;YACL,OAAO;gBACL,WAAW,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC;YAC5D,CAAC;SACF,CAAC;IACJ,CAAC;IAED;;;;;;OAMG;IACH,OAAO,CAAC,QAA8C;QACpD,MAAM,WAAW,GAAG,uBAAA,IAAI,iCAAU,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CACjD,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAC1B,CAAC;QAEF,OAAO;YACL,OAAO;gBACL,WAAW,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC;YAC5D,CAAC;SACF,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACH,UAAU,CAAC,QAAiD;QAC1D,MAAM,WAAW,GAAG,uBAAA,IAAI,iCAAU,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CACjD,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,CAC7B,CAAC;QAEF,OAAO;YACL,OAAO;gBACL,WAAW,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC;YAC5D,CAAC;SACF,CAAC;IACJ,CAAC;IAgDD,KAAK,CAAC,OAAO,CACX,cAAsC,EACtC,eAA6B,EAAE;QAE/B,OAAO,uBAAA,IAAI,iCAAU,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC;IACjE,CAAC;CA0BF;8KAbG,wBAAsE;IAEtE,OAAO,CAAC,GAAG,wBAAwB,CAAC;SACjC,OAAO,EAAE;SACT,MAAM,CAAC,CAAC,eAA6B,EAAE,oBAAoB,EAAE,KAAK,EAAE,EAAE;QACrE,MAAM,eAAe,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACnE,MAAM,OAAO,GAAG,IAAI,UAAU,CAAC;YAC7B,GAAG,oBAAoB;YACvB,eAAe;SAChB,CAAC,CAAC;QACH,OAAO,CAAC,OAAO,EAAE,GAAG,eAAe,CAAC,CAAC;IACvC,CAAC,EAAE,EAAE,CAAC,CAAC;AACX,CAAC","sourcesContent":["import type {\n Json,\n JsonRpcParams,\n JsonRpcRequest,\n JsonRpcResponse,\n} from '@metamask/utils';\n\nimport { RpcService } from './rpc-service';\nimport type { RpcServiceOptions } from './rpc-service';\nimport type { RpcServiceRequestable } from './rpc-service-requestable';\nimport type { FetchOptions } from './shared';\n\n/**\n * This class constructs a chain of RpcService objects which represent a\n * particular network. The first object in the chain is intended to be the\n * primary way of reaching the network and the remaining objects are used as\n * failovers.\n */\nexport class RpcServiceChain implements RpcServiceRequestable {\n readonly #services: RpcService[];\n\n /**\n * Constructs a new RpcServiceChain object.\n *\n * @param rpcServiceConfigurations - The options for the RPC services\n * that you want to construct. Each object in this array is the same as\n * {@link RpcServiceOptions}.\n */\n constructor(\n rpcServiceConfigurations: Omit<RpcServiceOptions, 'failoverService'>[],\n ) {\n this.#services = this.#buildRpcServiceChain(rpcServiceConfigurations);\n }\n\n /**\n * Listens for when any of the RPC services retry a request.\n *\n * @param listener - The callback to be called when the retry occurs.\n * @returns What {@link RpcService.onRetry} returns.\n */\n onRetry(listener: Parameters<RpcService['onRetry']>[0]) {\n const disposables = this.#services.map((service) =>\n service.onRetry(listener),\n );\n\n return {\n dispose() {\n disposables.forEach((disposable) => disposable.dispose());\n },\n };\n }\n\n /**\n * Listens for when any of the RPC services retry the request too many times\n * in a row.\n *\n * @param listener - The callback to be called when the retry occurs.\n * @returns What {@link RpcService.onBreak} returns.\n */\n onBreak(listener: Parameters<RpcService['onBreak']>[0]) {\n const disposables = this.#services.map((service) =>\n service.onBreak(listener),\n );\n\n return {\n dispose() {\n disposables.forEach((disposable) => disposable.dispose());\n },\n };\n }\n\n /**\n * Listens for when any of the RPC services send a slow request.\n *\n * @param listener - The callback to be called when the retry occurs.\n * @returns What {@link RpcService.onRetry} returns.\n */\n onDegraded(listener: Parameters<RpcService['onDegraded']>[0]) {\n const disposables = this.#services.map((service) =>\n service.onDegraded(listener),\n );\n\n return {\n dispose() {\n disposables.forEach((disposable) => disposable.dispose());\n },\n };\n }\n\n /**\n * Makes a request to the first RPC service in the chain. If this service is\n * down, then the request is forwarded to the next service in the chain, etc.\n *\n * This overload is specifically designed for `eth_getBlockByNumber`, which\n * can return a `result` of `null` despite an expected `Result` being\n * provided.\n *\n * @param jsonRpcRequest - The JSON-RPC request to send to the endpoint.\n * @param fetchOptions - An options bag for {@link fetch} which further\n * specifies the request.\n * @returns The decoded JSON-RPC response from the endpoint.\n * @throws A \"method not found\" error if the response status is 405.\n * @throws A rate limiting error if the response HTTP status is 429.\n * @throws A timeout error if the response HTTP status is 503 or 504.\n * @throws A generic error if the response HTTP status is not 2xx but also not\n * 405, 429, 503, or 504.\n */\n async request<Params extends JsonRpcParams, Result extends Json>(\n jsonRpcRequest: JsonRpcRequest<Params> & { method: 'eth_getBlockByNumber' },\n fetchOptions?: FetchOptions,\n ): Promise<JsonRpcResponse<Result> | JsonRpcResponse<null>>;\n\n /**\n * Makes a request to the first RPC service in the chain. If this service is\n * down, then the request is forwarded to the next service in the chain, etc.\n *\n * This overload is designed for all RPC methods except for\n * `eth_getBlockByNumber`, which are expected to return a `result` of the\n * expected `Result`.\n *\n * @param jsonRpcRequest - The JSON-RPC request to send to the endpoint.\n * @param fetchOptions - An options bag for {@link fetch} which further\n * specifies the request.\n * @returns The decoded JSON-RPC response from the endpoint.\n * @throws A \"method not found\" error if the response status is 405.\n * @throws A rate limiting error if the response HTTP status is 429.\n * @throws A timeout error if the response HTTP status is 503 or 504.\n * @throws A generic error if the response HTTP status is not 2xx but also not\n * 405, 429, 503, or 504.\n */\n async request<Params extends JsonRpcParams, Result extends Json>(\n jsonRpcRequest: JsonRpcRequest<Params>,\n fetchOptions?: FetchOptions,\n ): Promise<JsonRpcResponse<Result>>;\n\n async request<Params extends JsonRpcParams, Result extends Json>(\n jsonRpcRequest: JsonRpcRequest<Params>,\n fetchOptions: FetchOptions = {},\n ): Promise<JsonRpcResponse<Result | null>> {\n return this.#services[0].request(jsonRpcRequest, fetchOptions);\n }\n\n /**\n * Constructs the chain of RPC services. The second RPC service is\n * configured as the failover for the first, the third service is\n * configured as the failover for the second, etc.\n *\n * @param rpcServiceConfigurations - The options for the RPC services that\n * you want to construct. Each object in this array is the same as\n * {@link RpcServiceOptions}.\n * @returns The constructed chain of RPC services.\n */\n #buildRpcServiceChain(\n rpcServiceConfigurations: Omit<RpcServiceOptions, 'failoverService'>[],\n ): RpcService[] {\n return [...rpcServiceConfigurations]\n .reverse()\n .reduce((workingServices: RpcService[], serviceConfiguration, index) => {\n const failoverService = index > 0 ? workingServices[0] : undefined;\n const service = new RpcService({\n ...serviceConfiguration,\n failoverService,\n });\n return [service, ...workingServices];\n }, []);\n }\n}\n"]}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=rpc-service-requestable.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rpc-service-requestable.cjs","sourceRoot":"","sources":["../../src/rpc-service/rpc-service-requestable.ts"],"names":[],"mappings":"","sourcesContent":["import type { ServicePolicy } from '@metamask/controller-utils';\nimport type {\n Json,\n JsonRpcParams,\n JsonRpcRequest,\n JsonRpcResponse,\n} from '@metamask/utils';\n\nimport type { AddToCockatielEventData, FetchOptions } from './shared';\n\n/**\n * The interface for a service class responsible for making a request to a\n * target, whether that is a single RPC endpoint or an RPC endpoint in an RPC\n * service chain.\n */\nexport type RpcServiceRequestable = {\n /**\n * Listens for when the RPC service retries the request.\n *\n * @param listener - The callback to be called when the retry occurs.\n * @returns What {@link ServicePolicy.onRetry} returns.\n * @see {@link createServicePolicy}\n */\n onRetry(\n listener: AddToCockatielEventData<\n Parameters<ServicePolicy['onRetry']>[0],\n { endpointUrl: string }\n >,\n ): ReturnType<ServicePolicy['onRetry']>;\n\n /**\n * Listens for when the RPC service retries the request too many times in a\n * row.\n *\n * @param listener - The callback to be called when the circuit is broken.\n * @returns What {@link ServicePolicy.onBreak} returns.\n * @see {@link createServicePolicy}\n */\n onBreak(\n listener: AddToCockatielEventData<\n Parameters<ServicePolicy['onBreak']>[0],\n { endpointUrl: string }\n >,\n ): ReturnType<ServicePolicy['onBreak']>;\n\n /**\n * Listens for when the policy underlying this RPC service detects a slow\n * request.\n *\n * @param listener - The callback to be called when the request is slow.\n * @returns What {@link ServicePolicy.onDegraded} returns.\n * @see {@link createServicePolicy}\n */\n onDegraded(\n listener: AddToCockatielEventData<\n Parameters<ServicePolicy['onDegraded']>[0],\n { endpointUrl: string }\n >,\n ): ReturnType<ServicePolicy['onDegraded']>;\n\n /**\n * Makes a request to the target.\n */\n request<Params extends JsonRpcParams, Result extends Json>(\n jsonRpcRequest: JsonRpcRequest<Params>,\n fetchOptions?: FetchOptions,\n ): Promise<JsonRpcResponse<Result | null>>;\n};\n"]}
@@ -0,0 +1,47 @@
1
+ import type { ServicePolicy } from "@metamask/controller-utils";
2
+ import type { Json, JsonRpcParams, JsonRpcRequest, JsonRpcResponse } from "@metamask/utils";
3
+ import type { AddToCockatielEventData, FetchOptions } from "./shared.cjs";
4
+ /**
5
+ * The interface for a service class responsible for making a request to a
6
+ * target, whether that is a single RPC endpoint or an RPC endpoint in an RPC
7
+ * service chain.
8
+ */
9
+ export type RpcServiceRequestable = {
10
+ /**
11
+ * Listens for when the RPC service retries the request.
12
+ *
13
+ * @param listener - The callback to be called when the retry occurs.
14
+ * @returns What {@link ServicePolicy.onRetry} returns.
15
+ * @see {@link createServicePolicy}
16
+ */
17
+ onRetry(listener: AddToCockatielEventData<Parameters<ServicePolicy['onRetry']>[0], {
18
+ endpointUrl: string;
19
+ }>): ReturnType<ServicePolicy['onRetry']>;
20
+ /**
21
+ * Listens for when the RPC service retries the request too many times in a
22
+ * row.
23
+ *
24
+ * @param listener - The callback to be called when the circuit is broken.
25
+ * @returns What {@link ServicePolicy.onBreak} returns.
26
+ * @see {@link createServicePolicy}
27
+ */
28
+ onBreak(listener: AddToCockatielEventData<Parameters<ServicePolicy['onBreak']>[0], {
29
+ endpointUrl: string;
30
+ }>): ReturnType<ServicePolicy['onBreak']>;
31
+ /**
32
+ * Listens for when the policy underlying this RPC service detects a slow
33
+ * request.
34
+ *
35
+ * @param listener - The callback to be called when the request is slow.
36
+ * @returns What {@link ServicePolicy.onDegraded} returns.
37
+ * @see {@link createServicePolicy}
38
+ */
39
+ onDegraded(listener: AddToCockatielEventData<Parameters<ServicePolicy['onDegraded']>[0], {
40
+ endpointUrl: string;
41
+ }>): ReturnType<ServicePolicy['onDegraded']>;
42
+ /**
43
+ * Makes a request to the target.
44
+ */
45
+ request<Params extends JsonRpcParams, Result extends Json>(jsonRpcRequest: JsonRpcRequest<Params>, fetchOptions?: FetchOptions): Promise<JsonRpcResponse<Result | null>>;
46
+ };
47
+ //# sourceMappingURL=rpc-service-requestable.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rpc-service-requestable.d.cts","sourceRoot":"","sources":["../../src/rpc-service/rpc-service-requestable.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,mCAAmC;AAChE,OAAO,KAAK,EACV,IAAI,EACJ,aAAa,EACb,cAAc,EACd,eAAe,EAChB,wBAAwB;AAEzB,OAAO,KAAK,EAAE,uBAAuB,EAAE,YAAY,EAAE,qBAAiB;AAEtE;;;;GAIG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC;;;;;;OAMG;IACH,OAAO,CACL,QAAQ,EAAE,uBAAuB,CAC/B,UAAU,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,EACvC;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,CACxB,GACA,UAAU,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,CAAC;IAExC;;;;;;;OAOG;IACH,OAAO,CACL,QAAQ,EAAE,uBAAuB,CAC/B,UAAU,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,EACvC;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,CACxB,GACA,UAAU,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,CAAC;IAExC;;;;;;;OAOG;IACH,UAAU,CACR,QAAQ,EAAE,uBAAuB,CAC/B,UAAU,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,EAC1C;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,CACxB,GACA,UAAU,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,CAAC;IAE3C;;OAEG;IACH,OAAO,CAAC,MAAM,SAAS,aAAa,EAAE,MAAM,SAAS,IAAI,EACvD,cAAc,EAAE,cAAc,CAAC,MAAM,CAAC,EACtC,YAAY,CAAC,EAAE,YAAY,GAC1B,OAAO,CAAC,eAAe,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC;CAC5C,CAAC"}
@@ -0,0 +1,47 @@
1
+ import type { ServicePolicy } from "@metamask/controller-utils";
2
+ import type { Json, JsonRpcParams, JsonRpcRequest, JsonRpcResponse } from "@metamask/utils";
3
+ import type { AddToCockatielEventData, FetchOptions } from "./shared.mjs";
4
+ /**
5
+ * The interface for a service class responsible for making a request to a
6
+ * target, whether that is a single RPC endpoint or an RPC endpoint in an RPC
7
+ * service chain.
8
+ */
9
+ export type RpcServiceRequestable = {
10
+ /**
11
+ * Listens for when the RPC service retries the request.
12
+ *
13
+ * @param listener - The callback to be called when the retry occurs.
14
+ * @returns What {@link ServicePolicy.onRetry} returns.
15
+ * @see {@link createServicePolicy}
16
+ */
17
+ onRetry(listener: AddToCockatielEventData<Parameters<ServicePolicy['onRetry']>[0], {
18
+ endpointUrl: string;
19
+ }>): ReturnType<ServicePolicy['onRetry']>;
20
+ /**
21
+ * Listens for when the RPC service retries the request too many times in a
22
+ * row.
23
+ *
24
+ * @param listener - The callback to be called when the circuit is broken.
25
+ * @returns What {@link ServicePolicy.onBreak} returns.
26
+ * @see {@link createServicePolicy}
27
+ */
28
+ onBreak(listener: AddToCockatielEventData<Parameters<ServicePolicy['onBreak']>[0], {
29
+ endpointUrl: string;
30
+ }>): ReturnType<ServicePolicy['onBreak']>;
31
+ /**
32
+ * Listens for when the policy underlying this RPC service detects a slow
33
+ * request.
34
+ *
35
+ * @param listener - The callback to be called when the request is slow.
36
+ * @returns What {@link ServicePolicy.onDegraded} returns.
37
+ * @see {@link createServicePolicy}
38
+ */
39
+ onDegraded(listener: AddToCockatielEventData<Parameters<ServicePolicy['onDegraded']>[0], {
40
+ endpointUrl: string;
41
+ }>): ReturnType<ServicePolicy['onDegraded']>;
42
+ /**
43
+ * Makes a request to the target.
44
+ */
45
+ request<Params extends JsonRpcParams, Result extends Json>(jsonRpcRequest: JsonRpcRequest<Params>, fetchOptions?: FetchOptions): Promise<JsonRpcResponse<Result | null>>;
46
+ };
47
+ //# sourceMappingURL=rpc-service-requestable.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rpc-service-requestable.d.mts","sourceRoot":"","sources":["../../src/rpc-service/rpc-service-requestable.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,mCAAmC;AAChE,OAAO,KAAK,EACV,IAAI,EACJ,aAAa,EACb,cAAc,EACd,eAAe,EAChB,wBAAwB;AAEzB,OAAO,KAAK,EAAE,uBAAuB,EAAE,YAAY,EAAE,qBAAiB;AAEtE;;;;GAIG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC;;;;;;OAMG;IACH,OAAO,CACL,QAAQ,EAAE,uBAAuB,CAC/B,UAAU,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,EACvC;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,CACxB,GACA,UAAU,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,CAAC;IAExC;;;;;;;OAOG;IACH,OAAO,CACL,QAAQ,EAAE,uBAAuB,CAC/B,UAAU,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,EACvC;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,CACxB,GACA,UAAU,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,CAAC;IAExC;;;;;;;OAOG;IACH,UAAU,CACR,QAAQ,EAAE,uBAAuB,CAC/B,UAAU,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,EAC1C;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,CACxB,GACA,UAAU,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,CAAC;IAE3C;;OAEG;IACH,OAAO,CAAC,MAAM,SAAS,aAAa,EAAE,MAAM,SAAS,IAAI,EACvD,cAAc,EAAE,cAAc,CAAC,MAAM,CAAC,EACtC,YAAY,CAAC,EAAE,YAAY,GAC1B,OAAO,CAAC,eAAe,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC;CAC5C,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=rpc-service-requestable.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rpc-service-requestable.mjs","sourceRoot":"","sources":["../../src/rpc-service/rpc-service-requestable.ts"],"names":[],"mappings":"","sourcesContent":["import type { ServicePolicy } from '@metamask/controller-utils';\nimport type {\n Json,\n JsonRpcParams,\n JsonRpcRequest,\n JsonRpcResponse,\n} from '@metamask/utils';\n\nimport type { AddToCockatielEventData, FetchOptions } from './shared';\n\n/**\n * The interface for a service class responsible for making a request to a\n * target, whether that is a single RPC endpoint or an RPC endpoint in an RPC\n * service chain.\n */\nexport type RpcServiceRequestable = {\n /**\n * Listens for when the RPC service retries the request.\n *\n * @param listener - The callback to be called when the retry occurs.\n * @returns What {@link ServicePolicy.onRetry} returns.\n * @see {@link createServicePolicy}\n */\n onRetry(\n listener: AddToCockatielEventData<\n Parameters<ServicePolicy['onRetry']>[0],\n { endpointUrl: string }\n >,\n ): ReturnType<ServicePolicy['onRetry']>;\n\n /**\n * Listens for when the RPC service retries the request too many times in a\n * row.\n *\n * @param listener - The callback to be called when the circuit is broken.\n * @returns What {@link ServicePolicy.onBreak} returns.\n * @see {@link createServicePolicy}\n */\n onBreak(\n listener: AddToCockatielEventData<\n Parameters<ServicePolicy['onBreak']>[0],\n { endpointUrl: string }\n >,\n ): ReturnType<ServicePolicy['onBreak']>;\n\n /**\n * Listens for when the policy underlying this RPC service detects a slow\n * request.\n *\n * @param listener - The callback to be called when the request is slow.\n * @returns What {@link ServicePolicy.onDegraded} returns.\n * @see {@link createServicePolicy}\n */\n onDegraded(\n listener: AddToCockatielEventData<\n Parameters<ServicePolicy['onDegraded']>[0],\n { endpointUrl: string }\n >,\n ): ReturnType<ServicePolicy['onDegraded']>;\n\n /**\n * Makes a request to the target.\n */\n request<Params extends JsonRpcParams, Result extends Json>(\n jsonRpcRequest: JsonRpcRequest<Params>,\n fetchOptions?: FetchOptions,\n ): Promise<JsonRpcResponse<Result | null>>;\n};\n"]}
@@ -13,29 +13,78 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
13
13
  var __importDefault = (this && this.__importDefault) || function (mod) {
14
14
  return (mod && mod.__esModule) ? mod : { "default": mod };
15
15
  };
16
- var _RpcService_instances, _RpcService_fetch, _RpcService_endpointUrl, _RpcService_fetchOptions, _RpcService_failoverService, _RpcService_policy, _RpcService_getDefaultFetchOptions, _RpcService_getCompleteFetchOptions, _RpcService_executePolicy;
16
+ var _RpcService_instances, _RpcService_fetch, _RpcService_fetchOptions, _RpcService_failoverService, _RpcService_policy, _RpcService_getDefaultFetchOptions, _RpcService_getCompleteFetchOptions, _RpcService_executePolicy;
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
- exports.RpcService = exports.NETWORK_UNREACHABLE_ERRORS = void 0;
18
+ exports.RpcService = exports.isConnectionError = exports.CONNECTION_ERRORS = exports.DEFAULT_MAX_CONSECUTIVE_FAILURES = exports.DEFAULT_MAX_RETRIES = void 0;
19
19
  const controller_utils_1 = require("@metamask/controller-utils");
20
20
  const rpc_errors_1 = require("@metamask/rpc-errors");
21
21
  const utils_1 = require("@metamask/utils");
22
22
  const deepmerge_1 = __importDefault(require("deepmerge"));
23
23
  /**
24
- * The list of error messages that represent a failure to reach the network.
24
+ * The maximum number of times that a failing service should be re-run before
25
+ * giving up.
26
+ */
27
+ exports.DEFAULT_MAX_RETRIES = 4;
28
+ /**
29
+ * The maximum number of times that the service is allowed to fail before
30
+ * pausing further retries. This is set to a value such that if given a
31
+ * service that continually fails, the policy needs to be executed 3 times
32
+ * before further retries are paused.
33
+ */
34
+ exports.DEFAULT_MAX_CONSECUTIVE_FAILURES = (1 + exports.DEFAULT_MAX_RETRIES) * 3;
35
+ /**
36
+ * The list of error messages that represent a failure to connect to the network.
25
37
  *
26
38
  * This list was derived from Sindre Sorhus's `is-network-error` package:
27
39
  * <https://github.com/sindresorhus/is-network-error/blob/7bbfa8be9482ce1427a21fbff60e3ee1650dd091/index.js>
28
40
  */
29
- exports.NETWORK_UNREACHABLE_ERRORS = new Set([
30
- 'network error',
31
- 'Failed to fetch',
32
- 'NetworkError when attempting to fetch resource.',
33
- 'The Internet connection appears to be offline.',
34
- 'Load failed',
35
- 'Network request failed',
36
- 'fetch failed',
37
- 'terminated', // Undici (Node.js)
38
- ]);
41
+ exports.CONNECTION_ERRORS = [
42
+ // Chrome
43
+ {
44
+ constructorName: 'TypeError',
45
+ pattern: /network error/u,
46
+ },
47
+ // Chrome
48
+ {
49
+ constructorName: 'TypeError',
50
+ pattern: /Failed to fetch/u,
51
+ },
52
+ // Firefox
53
+ {
54
+ constructorName: 'TypeError',
55
+ pattern: /NetworkError when attempting to fetch resource\./u,
56
+ },
57
+ // Safari 16
58
+ {
59
+ constructorName: 'TypeError',
60
+ pattern: /The Internet connection appears to be offline\./u,
61
+ },
62
+ // Safari 17+
63
+ {
64
+ constructorName: 'TypeError',
65
+ pattern: /Load failed/u,
66
+ },
67
+ // `cross-fetch`
68
+ {
69
+ constructorName: 'TypeError',
70
+ pattern: /Network request failed/u,
71
+ },
72
+ // `node-fetch`
73
+ {
74
+ constructorName: 'FetchError',
75
+ pattern: /request to (.+) failed/u,
76
+ },
77
+ // Undici (Node.js)
78
+ {
79
+ constructorName: 'TypeError',
80
+ pattern: /fetch failed/u,
81
+ },
82
+ // Undici (Node.js)
83
+ {
84
+ constructorName: 'TypeError',
85
+ pattern: /terminated/u,
86
+ },
87
+ ];
39
88
  /**
40
89
  * Determines whether the given error represents a failure to reach the network
41
90
  * after request parameters have been validated.
@@ -45,13 +94,34 @@ exports.NETWORK_UNREACHABLE_ERRORS = new Set([
45
94
  * particular scenario, and we need to account for this.
46
95
  *
47
96
  * @param error - The error.
48
- * @returns True if the error indicates that the network is unreachable, and
49
- * false otherwise.
97
+ * @returns True if the error indicates that the network cannot be connected to,
98
+ * and false otherwise.
50
99
  */
51
- function isNetworkUnreachableError(error) {
52
- return (error instanceof TypeError && exports.NETWORK_UNREACHABLE_ERRORS.has(error.message));
100
+ function isConnectionError(error) {
101
+ if (!(typeof error === 'object' && error !== null && 'message' in error)) {
102
+ return false;
103
+ }
104
+ const { message } = error;
105
+ return (typeof message === 'string' &&
106
+ !isNockError(message) &&
107
+ exports.CONNECTION_ERRORS.some(({ constructorName, pattern }) => {
108
+ return (error.constructor.name === constructorName && pattern.test(message));
109
+ }));
110
+ }
111
+ exports.isConnectionError = isConnectionError;
112
+ /**
113
+ * Determines whether the given error message refers to a Nock error.
114
+ *
115
+ * It's important that if we failed to mock a request in a test, the resulting
116
+ * error does not cause the request to be retried so that we can see it right
117
+ * away.
118
+ *
119
+ * @param message - The error message to test.
120
+ * @returns True if the message indicates a missing Nock mock, false otherwise.
121
+ */
122
+ function isNockError(message) {
123
+ return message.includes('Nock:');
53
124
  }
54
- exports.default = isNetworkUnreachableError;
55
125
  /**
56
126
  * Guarantees a URL, even given a string. This is useful for checking components
57
127
  * of that URL.
@@ -75,31 +145,14 @@ class RpcService {
75
145
  /**
76
146
  * Constructs a new RpcService object.
77
147
  *
78
- * @param args - The arguments.
79
- * @param args.fetch - A function that can be used to make an HTTP request.
80
- * If your JavaScript environment supports `fetch` natively, you'll probably
81
- * want to pass that; otherwise you can pass an equivalent (such as `fetch`
82
- * via `node-fetch`).
83
- * @param args.btoa - A function that can be used to convert a binary string
84
- * into base-64. Used to encode authorization credentials.
85
- * @param args.endpointUrl - The URL of the RPC endpoint.
86
- * @param args.fetchOptions - A common set of options that will be used to
87
- * make every request. Can be overridden on the request level (e.g. to add
88
- * headers).
89
- * @param args.failoverService - An RPC service that represents a failover
90
- * endpoint which will be invoked while the circuit for _this_ service is
91
- * open.
148
+ * @param options - The options. See {@link RpcServiceOptions}.
92
149
  */
93
- constructor({ fetch: givenFetch, btoa: givenBtoa, endpointUrl, fetchOptions = {}, failoverService, }) {
150
+ constructor(options) {
94
151
  _RpcService_instances.add(this);
95
152
  /**
96
153
  * The function used to make an HTTP request.
97
154
  */
98
155
  _RpcService_fetch.set(this, void 0);
99
- /**
100
- * The URL of the RPC endpoint.
101
- */
102
- _RpcService_endpointUrl.set(this, void 0);
103
156
  /**
104
157
  * A common set of options that the request options will extend.
105
158
  */
@@ -113,17 +166,19 @@ class RpcService {
113
166
  * The policy that wraps the request.
114
167
  */
115
168
  _RpcService_policy.set(this, void 0);
169
+ const { btoa: givenBtoa, endpointUrl, failoverService, fetch: givenFetch, fetchOptions = {}, policyOptions = {}, } = options;
116
170
  __classPrivateFieldSet(this, _RpcService_fetch, givenFetch, "f");
117
- __classPrivateFieldSet(this, _RpcService_endpointUrl, getNormalizedEndpointUrl(endpointUrl), "f");
118
- __classPrivateFieldSet(this, _RpcService_fetchOptions, __classPrivateFieldGet(this, _RpcService_instances, "m", _RpcService_getDefaultFetchOptions).call(this, __classPrivateFieldGet(this, _RpcService_endpointUrl, "f"), fetchOptions, givenBtoa), "f");
171
+ this.endpointUrl = getNormalizedEndpointUrl(endpointUrl);
172
+ __classPrivateFieldSet(this, _RpcService_fetchOptions, __classPrivateFieldGet(this, _RpcService_instances, "m", _RpcService_getDefaultFetchOptions).call(this, this.endpointUrl, fetchOptions, givenBtoa), "f");
119
173
  __classPrivateFieldSet(this, _RpcService_failoverService, failoverService, "f");
120
174
  const policy = (0, controller_utils_1.createServicePolicy)({
121
- maxRetries: 4,
122
- maxConsecutiveFailures: 15,
175
+ maxRetries: exports.DEFAULT_MAX_RETRIES,
176
+ maxConsecutiveFailures: exports.DEFAULT_MAX_CONSECUTIVE_FAILURES,
177
+ ...policyOptions,
123
178
  retryFilterPolicy: (0, controller_utils_1.handleWhen)((error) => {
124
179
  return (
125
180
  // Ignore errors where the request failed to establish
126
- isNetworkUnreachableError(error) ||
181
+ isConnectionError(error) ||
127
182
  // Ignore server sent HTML error pages or truncated JSON responses
128
183
  error.message.includes('not valid JSON') ||
129
184
  // Ignore server overload errors
@@ -143,7 +198,7 @@ class RpcService {
143
198
  */
144
199
  onRetry(listener) {
145
200
  return __classPrivateFieldGet(this, _RpcService_policy, "f").onRetry((data) => {
146
- listener({ ...data, endpointUrl: __classPrivateFieldGet(this, _RpcService_endpointUrl, "f").toString() });
201
+ listener({ ...data, endpointUrl: this.endpointUrl.toString() });
147
202
  });
148
203
  }
149
204
  /**
@@ -156,7 +211,13 @@ class RpcService {
156
211
  */
157
212
  onBreak(listener) {
158
213
  return __classPrivateFieldGet(this, _RpcService_policy, "f").onBreak((data) => {
159
- listener({ ...data, endpointUrl: __classPrivateFieldGet(this, _RpcService_endpointUrl, "f").toString() });
214
+ listener({
215
+ ...data,
216
+ endpointUrl: this.endpointUrl.toString(),
217
+ failoverEndpointUrl: __classPrivateFieldGet(this, _RpcService_failoverService, "f")
218
+ ? __classPrivateFieldGet(this, _RpcService_failoverService, "f").endpointUrl.toString()
219
+ : undefined,
220
+ });
160
221
  });
161
222
  }
162
223
  /**
@@ -169,7 +230,7 @@ class RpcService {
169
230
  */
170
231
  onDegraded(listener) {
171
232
  return __classPrivateFieldGet(this, _RpcService_policy, "f").onDegraded(() => {
172
- listener({ endpointUrl: __classPrivateFieldGet(this, _RpcService_endpointUrl, "f").toString() });
233
+ listener({ endpointUrl: this.endpointUrl.toString() });
173
234
  });
174
235
  }
175
236
  async request(jsonRpcRequest, fetchOptions = {}) {
@@ -187,7 +248,7 @@ class RpcService {
187
248
  }
188
249
  }
189
250
  exports.RpcService = RpcService;
190
- _RpcService_fetch = new WeakMap(), _RpcService_endpointUrl = new WeakMap(), _RpcService_fetchOptions = new WeakMap(), _RpcService_failoverService = new WeakMap(), _RpcService_policy = new WeakMap(), _RpcService_instances = new WeakSet(), _RpcService_getDefaultFetchOptions = function _RpcService_getDefaultFetchOptions(endpointUrl, fetchOptions, givenBtoa) {
251
+ _RpcService_fetch = new WeakMap(), _RpcService_fetchOptions = new WeakMap(), _RpcService_failoverService = new WeakMap(), _RpcService_policy = new WeakMap(), _RpcService_instances = new WeakSet(), _RpcService_getDefaultFetchOptions = function _RpcService_getDefaultFetchOptions(endpointUrl, fetchOptions, givenBtoa) {
191
252
  if (endpointUrl.username && endpointUrl.password) {
192
253
  const authString = `${endpointUrl.username}:${endpointUrl.password}`;
193
254
  const encodedCredentials = givenBtoa(authString);
@@ -229,7 +290,7 @@ _RpcService_fetch = new WeakMap(), _RpcService_endpointUrl = new WeakMap(), _Rpc
229
290
  */
230
291
  async function _RpcService_executePolicy(jsonRpcRequest, fetchOptions) {
231
292
  return await __classPrivateFieldGet(this, _RpcService_policy, "f").execute(async () => {
232
- const response = await __classPrivateFieldGet(this, _RpcService_fetch, "f").call(this, __classPrivateFieldGet(this, _RpcService_endpointUrl, "f"), fetchOptions);
293
+ const response = await __classPrivateFieldGet(this, _RpcService_fetch, "f").call(this, this.endpointUrl, fetchOptions);
233
294
  if (response.status === 405) {
234
295
  throw rpc_errors_1.rpcErrors.methodNotFound();
235
296
  }