@metamask-previews/network-controller 27.0.0-preview-565dfca2 → 27.0.0-preview-3fa1672

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 (33) hide show
  1. package/dist/NetworkController.cjs +22 -27
  2. package/dist/NetworkController.cjs.map +1 -1
  3. package/dist/NetworkController.d.cts +2 -2
  4. package/dist/NetworkController.d.cts.map +1 -1
  5. package/dist/NetworkController.d.mts +2 -2
  6. package/dist/NetworkController.d.mts.map +1 -1
  7. package/dist/NetworkController.mjs +22 -27
  8. package/dist/NetworkController.mjs.map +1 -1
  9. package/dist/create-auto-managed-network-client.cjs +0 -8
  10. package/dist/create-auto-managed-network-client.cjs.map +1 -1
  11. package/dist/create-auto-managed-network-client.d.cts.map +1 -1
  12. package/dist/create-auto-managed-network-client.d.mts.map +1 -1
  13. package/dist/create-auto-managed-network-client.mjs +0 -8
  14. package/dist/create-auto-managed-network-client.mjs.map +1 -1
  15. package/dist/create-network-client.cjs +6 -1
  16. package/dist/create-network-client.cjs.map +1 -1
  17. package/dist/create-network-client.mjs +6 -1
  18. package/dist/create-network-client.mjs.map +1 -1
  19. package/dist/rpc-service/rpc-service-chain.cjs.map +1 -1
  20. package/dist/rpc-service/rpc-service-chain.d.cts +6 -9
  21. package/dist/rpc-service/rpc-service-chain.d.cts.map +1 -1
  22. package/dist/rpc-service/rpc-service-chain.d.mts +6 -9
  23. package/dist/rpc-service/rpc-service-chain.d.mts.map +1 -1
  24. package/dist/rpc-service/rpc-service-chain.mjs.map +1 -1
  25. package/dist/rpc-service/rpc-service.cjs +1 -0
  26. package/dist/rpc-service/rpc-service.cjs.map +1 -1
  27. package/dist/rpc-service/rpc-service.d.cts +6 -5
  28. package/dist/rpc-service/rpc-service.d.cts.map +1 -1
  29. package/dist/rpc-service/rpc-service.d.mts +6 -5
  30. package/dist/rpc-service/rpc-service.d.mts.map +1 -1
  31. package/dist/rpc-service/rpc-service.mjs +1 -0
  32. package/dist/rpc-service/rpc-service.mjs.map +1 -1
  33. package/package.json +1 -1
@@ -1,4 +1,5 @@
1
1
  import type { Json, JsonRpcParams, JsonRpcRequest, JsonRpcResponse } from "@metamask/utils";
2
+ import { IDisposable } from "cockatiel";
2
3
  import { RpcService } from "./rpc-service.cjs";
3
4
  import type { RpcServiceOptions } from "./rpc-service.cjs";
4
5
  import type { CockatielEventToEventListenerWithData, ExcludeCockatielEventData, ExtractCockatielEventData, FetchOptions } from "./shared.cjs";
@@ -46,7 +47,7 @@ export declare class RpcServiceChain {
46
47
  * @returns An object with a `dispose` method which can be used to unregister
47
48
  * the callback.
48
49
  */
49
- onBreak(listener: (data: ExcludeCockatielEventData<ExtractCockatielEventData<RpcService['onBreak']>, 'endpointUrl'>) => void): import("cockatiel").IDisposable;
50
+ onBreak(listener: (data: ExcludeCockatielEventData<ExtractCockatielEventData<RpcService['onBreak']>, 'endpointUrl'>) => void): IDisposable;
50
51
  /**
51
52
  * Calls the provided callback each time when, for *any* of the RPC services
52
53
  * in this chain, the maximum number of failed consecutive attempts to receive
@@ -59,9 +60,7 @@ export declare class RpcServiceChain {
59
60
  */
60
61
  onServiceBreak(listener: CockatielEventToEventListenerWithData<RpcService['onBreak'], {
61
62
  primaryEndpointUrl: string;
62
- }>): {
63
- dispose(): void;
64
- };
63
+ }>): IDisposable;
65
64
  /**
66
65
  * Calls the provided callback if no requests have been initiated yet or
67
66
  * all requests to RPC services in this chain have responded successfully in a
@@ -85,7 +84,7 @@ export declare class RpcServiceChain {
85
84
  * @returns An object with a `dispose` method which can be used to unregister
86
85
  * the callback.
87
86
  */
88
- onDegraded(listener: (data: ExcludeCockatielEventData<ExtractCockatielEventData<RpcService['onDegraded']>, 'endpointUrl'>) => void): import("cockatiel").IDisposable;
87
+ onDegraded(listener: (data: ExcludeCockatielEventData<ExtractCockatielEventData<RpcService['onDegraded']>, 'endpointUrl'>) => void): IDisposable;
89
88
  /**
90
89
  * Calls the provided callback each time one of the two conditions apply:
91
90
  *
@@ -108,9 +107,7 @@ export declare class RpcServiceChain {
108
107
  */
109
108
  onServiceDegraded(listener: CockatielEventToEventListenerWithData<RpcService['onDegraded'], {
110
109
  primaryEndpointUrl: string;
111
- }>): {
112
- dispose(): void;
113
- };
110
+ }>): IDisposable;
114
111
  /**
115
112
  * Calls the provided callback in one of the following two conditions:
116
113
  *
@@ -127,7 +124,7 @@ export declare class RpcServiceChain {
127
124
  * @returns An object with a `dispose` method which can be used to unregister
128
125
  * the callback.
129
126
  */
130
- onAvailable(listener: (data: ExcludeCockatielEventData<ExtractCockatielEventData<RpcService['onAvailable']>, 'endpointUrl'>) => void): import("cockatiel").IDisposable;
127
+ onAvailable(listener: (data: ExcludeCockatielEventData<ExtractCockatielEventData<RpcService['onAvailable']>, 'endpointUrl'>) => void): IDisposable;
131
128
  /**
132
129
  * Uses the RPC services in the chain to make a request, using each service
133
130
  * after the first as a fallback to the previous one as necessary.
@@ -1 +1 @@
1
- {"version":3,"file":"rpc-service-chain.d.cts","sourceRoot":"","sources":["../../src/rpc-service/rpc-service-chain.ts"],"names":[],"mappings":"AAIA,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,EACV,qCAAqC,EACrC,yBAAyB,EACzB,yBAAyB,EACzB,YAAY,EACb,qBAAiB;AAoBlB;;;;;GAKG;AACH,qBAAa,eAAe;;IA8C1B;;;;;;OAMG;gBAED,wBAAwB,EAAE,CAAC,iBAAiB,EAAE,GAAG,iBAAiB,EAAE,CAAC;IAkDvE;;;;;;;;OAQG;IACH,cAAc,CACZ,QAAQ,EAAE,qCAAqC,CAC7C,UAAU,CAAC,SAAS,CAAC,EACrB;QAAE,kBAAkB,EAAE,MAAM,CAAA;KAAE,CAC/B;;;IAkBH;;;;;;;;;;;;;OAaG;IACH,OAAO,CACL,QAAQ,EAAE,CACR,IAAI,EAAE,yBAAyB,CAC7B,yBAAyB,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,EAChD,aAAa,CACd,KACE,IAAI;IAKX;;;;;;;;;OASG;IACH,cAAc,CACZ,QAAQ,EAAE,qCAAqC,CAC7C,UAAU,CAAC,SAAS,CAAC,EACrB;QAAE,kBAAkB,EAAE,MAAM,CAAA;KAAE,CAC/B;;;IAkBH;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,UAAU,CACR,QAAQ,EAAE,CACR,IAAI,EAAE,yBAAyB,CAC7B,yBAAyB,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,EACnD,aAAa,CACd,KACE,IAAI;IAKX;;;;;;;;;;;;;;;;;;;OAmBG;IACH,iBAAiB,CACf,QAAQ,EAAE,qCAAqC,CAC7C,UAAU,CAAC,YAAY,CAAC,EACxB;QAAE,kBAAkB,EAAE,MAAM,CAAA;KAAE,CAC/B;;;IAkBH;;;;;;;;;;;;;;;OAeG;IACH,WAAW,CACT,QAAQ,EAAE,CACR,IAAI,EAAE,yBAAyB,CAC7B,yBAAyB,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC,EACpD,aAAa,CACd,KACE,IAAI;IAKX;;;;;;;;;;;;;;;;;OAiBG;IACG,OAAO,CAAC,MAAM,SAAS,aAAa,EAAE,MAAM,SAAS,IAAI,EAC7D,cAAc,EAAE,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,GAAG;QACjD,MAAM,EAAE,sBAAsB,CAAC;KAChC,EACD,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,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,EAChD,YAAY,CAAC,EAAE,YAAY,GAC1B,OAAO,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;CA8FpC"}
1
+ {"version":3,"file":"rpc-service-chain.d.cts","sourceRoot":"","sources":["../../src/rpc-service/rpc-service-chain.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,IAAI,EACJ,aAAa,EACb,cAAc,EACd,eAAe,EAChB,wBAAwB;AACzB,OAAO,EAAE,WAAW,EAAE,kBAAkB;AAExC,OAAO,EAAE,UAAU,EAAE,0BAAsB;AAC3C,OAAO,KAAK,EAAE,iBAAiB,EAAE,0BAAsB;AACvD,OAAO,KAAK,EACV,qCAAqC,EACrC,yBAAyB,EACzB,yBAAyB,EACzB,YAAY,EACb,qBAAiB;AAoBlB;;;;;GAKG;AACH,qBAAa,eAAe;;IA8C1B;;;;;;OAMG;gBAED,wBAAwB,EAAE,CAAC,iBAAiB,EAAE,GAAG,iBAAiB,EAAE,CAAC;IAkDvE;;;;;;;;OAQG;IACH,cAAc,CACZ,QAAQ,EAAE,qCAAqC,CAC7C,UAAU,CAAC,SAAS,CAAC,EACrB;QAAE,kBAAkB,EAAE,MAAM,CAAA;KAAE,CAC/B,GACA;QAAE,OAAO,IAAI,IAAI,CAAA;KAAE;IAiBtB;;;;;;;;;;;;;OAaG;IACH,OAAO,CACL,QAAQ,EAAE,CACR,IAAI,EAAE,yBAAyB,CAC7B,yBAAyB,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,EAChD,aAAa,CACd,KACE,IAAI,GACR,WAAW;IAId;;;;;;;;;OASG;IACH,cAAc,CACZ,QAAQ,EAAE,qCAAqC,CAC7C,UAAU,CAAC,SAAS,CAAC,EACrB;QAAE,kBAAkB,EAAE,MAAM,CAAA;KAAE,CAC/B,GACA,WAAW;IAiBd;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,UAAU,CACR,QAAQ,EAAE,CACR,IAAI,EAAE,yBAAyB,CAC7B,yBAAyB,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,EACnD,aAAa,CACd,KACE,IAAI,GACR,WAAW;IAId;;;;;;;;;;;;;;;;;;;OAmBG;IACH,iBAAiB,CACf,QAAQ,EAAE,qCAAqC,CAC7C,UAAU,CAAC,YAAY,CAAC,EACxB;QAAE,kBAAkB,EAAE,MAAM,CAAA;KAAE,CAC/B,GACA,WAAW;IAiBd;;;;;;;;;;;;;;;OAeG;IACH,WAAW,CACT,QAAQ,EAAE,CACR,IAAI,EAAE,yBAAyB,CAC7B,yBAAyB,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC,EACpD,aAAa,CACd,KACE,IAAI,GACR,WAAW;IAId;;;;;;;;;;;;;;;;;OAiBG;IACG,OAAO,CAAC,MAAM,SAAS,aAAa,EAAE,MAAM,SAAS,IAAI,EAC7D,cAAc,EAAE,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,GAAG;QACjD,MAAM,EAAE,sBAAsB,CAAC;KAChC,EACD,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,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,EAChD,YAAY,CAAC,EAAE,YAAY,GAC1B,OAAO,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;CA8FpC"}
@@ -1,4 +1,5 @@
1
1
  import type { Json, JsonRpcParams, JsonRpcRequest, JsonRpcResponse } from "@metamask/utils";
2
+ import { IDisposable } from "cockatiel";
2
3
  import { RpcService } from "./rpc-service.mjs";
3
4
  import type { RpcServiceOptions } from "./rpc-service.mjs";
4
5
  import type { CockatielEventToEventListenerWithData, ExcludeCockatielEventData, ExtractCockatielEventData, FetchOptions } from "./shared.mjs";
@@ -46,7 +47,7 @@ export declare class RpcServiceChain {
46
47
  * @returns An object with a `dispose` method which can be used to unregister
47
48
  * the callback.
48
49
  */
49
- onBreak(listener: (data: ExcludeCockatielEventData<ExtractCockatielEventData<RpcService['onBreak']>, 'endpointUrl'>) => void): import("cockatiel").IDisposable;
50
+ onBreak(listener: (data: ExcludeCockatielEventData<ExtractCockatielEventData<RpcService['onBreak']>, 'endpointUrl'>) => void): IDisposable;
50
51
  /**
51
52
  * Calls the provided callback each time when, for *any* of the RPC services
52
53
  * in this chain, the maximum number of failed consecutive attempts to receive
@@ -59,9 +60,7 @@ export declare class RpcServiceChain {
59
60
  */
60
61
  onServiceBreak(listener: CockatielEventToEventListenerWithData<RpcService['onBreak'], {
61
62
  primaryEndpointUrl: string;
62
- }>): {
63
- dispose(): void;
64
- };
63
+ }>): IDisposable;
65
64
  /**
66
65
  * Calls the provided callback if no requests have been initiated yet or
67
66
  * all requests to RPC services in this chain have responded successfully in a
@@ -85,7 +84,7 @@ export declare class RpcServiceChain {
85
84
  * @returns An object with a `dispose` method which can be used to unregister
86
85
  * the callback.
87
86
  */
88
- onDegraded(listener: (data: ExcludeCockatielEventData<ExtractCockatielEventData<RpcService['onDegraded']>, 'endpointUrl'>) => void): import("cockatiel").IDisposable;
87
+ onDegraded(listener: (data: ExcludeCockatielEventData<ExtractCockatielEventData<RpcService['onDegraded']>, 'endpointUrl'>) => void): IDisposable;
89
88
  /**
90
89
  * Calls the provided callback each time one of the two conditions apply:
91
90
  *
@@ -108,9 +107,7 @@ export declare class RpcServiceChain {
108
107
  */
109
108
  onServiceDegraded(listener: CockatielEventToEventListenerWithData<RpcService['onDegraded'], {
110
109
  primaryEndpointUrl: string;
111
- }>): {
112
- dispose(): void;
113
- };
110
+ }>): IDisposable;
114
111
  /**
115
112
  * Calls the provided callback in one of the following two conditions:
116
113
  *
@@ -127,7 +124,7 @@ export declare class RpcServiceChain {
127
124
  * @returns An object with a `dispose` method which can be used to unregister
128
125
  * the callback.
129
126
  */
130
- onAvailable(listener: (data: ExcludeCockatielEventData<ExtractCockatielEventData<RpcService['onAvailable']>, 'endpointUrl'>) => void): import("cockatiel").IDisposable;
127
+ onAvailable(listener: (data: ExcludeCockatielEventData<ExtractCockatielEventData<RpcService['onAvailable']>, 'endpointUrl'>) => void): IDisposable;
131
128
  /**
132
129
  * Uses the RPC services in the chain to make a request, using each service
133
130
  * after the first as a fallback to the previous one as necessary.
@@ -1 +1 @@
1
- {"version":3,"file":"rpc-service-chain.d.mts","sourceRoot":"","sources":["../../src/rpc-service/rpc-service-chain.ts"],"names":[],"mappings":"AAIA,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,EACV,qCAAqC,EACrC,yBAAyB,EACzB,yBAAyB,EACzB,YAAY,EACb,qBAAiB;AAoBlB;;;;;GAKG;AACH,qBAAa,eAAe;;IA8C1B;;;;;;OAMG;gBAED,wBAAwB,EAAE,CAAC,iBAAiB,EAAE,GAAG,iBAAiB,EAAE,CAAC;IAkDvE;;;;;;;;OAQG;IACH,cAAc,CACZ,QAAQ,EAAE,qCAAqC,CAC7C,UAAU,CAAC,SAAS,CAAC,EACrB;QAAE,kBAAkB,EAAE,MAAM,CAAA;KAAE,CAC/B;;;IAkBH;;;;;;;;;;;;;OAaG;IACH,OAAO,CACL,QAAQ,EAAE,CACR,IAAI,EAAE,yBAAyB,CAC7B,yBAAyB,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,EAChD,aAAa,CACd,KACE,IAAI;IAKX;;;;;;;;;OASG;IACH,cAAc,CACZ,QAAQ,EAAE,qCAAqC,CAC7C,UAAU,CAAC,SAAS,CAAC,EACrB;QAAE,kBAAkB,EAAE,MAAM,CAAA;KAAE,CAC/B;;;IAkBH;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,UAAU,CACR,QAAQ,EAAE,CACR,IAAI,EAAE,yBAAyB,CAC7B,yBAAyB,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,EACnD,aAAa,CACd,KACE,IAAI;IAKX;;;;;;;;;;;;;;;;;;;OAmBG;IACH,iBAAiB,CACf,QAAQ,EAAE,qCAAqC,CAC7C,UAAU,CAAC,YAAY,CAAC,EACxB;QAAE,kBAAkB,EAAE,MAAM,CAAA;KAAE,CAC/B;;;IAkBH;;;;;;;;;;;;;;;OAeG;IACH,WAAW,CACT,QAAQ,EAAE,CACR,IAAI,EAAE,yBAAyB,CAC7B,yBAAyB,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC,EACpD,aAAa,CACd,KACE,IAAI;IAKX;;;;;;;;;;;;;;;;;OAiBG;IACG,OAAO,CAAC,MAAM,SAAS,aAAa,EAAE,MAAM,SAAS,IAAI,EAC7D,cAAc,EAAE,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,GAAG;QACjD,MAAM,EAAE,sBAAsB,CAAC;KAChC,EACD,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,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,EAChD,YAAY,CAAC,EAAE,YAAY,GAC1B,OAAO,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;CA8FpC"}
1
+ {"version":3,"file":"rpc-service-chain.d.mts","sourceRoot":"","sources":["../../src/rpc-service/rpc-service-chain.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,IAAI,EACJ,aAAa,EACb,cAAc,EACd,eAAe,EAChB,wBAAwB;AACzB,OAAO,EAAE,WAAW,EAAE,kBAAkB;AAExC,OAAO,EAAE,UAAU,EAAE,0BAAsB;AAC3C,OAAO,KAAK,EAAE,iBAAiB,EAAE,0BAAsB;AACvD,OAAO,KAAK,EACV,qCAAqC,EACrC,yBAAyB,EACzB,yBAAyB,EACzB,YAAY,EACb,qBAAiB;AAoBlB;;;;;GAKG;AACH,qBAAa,eAAe;;IA8C1B;;;;;;OAMG;gBAED,wBAAwB,EAAE,CAAC,iBAAiB,EAAE,GAAG,iBAAiB,EAAE,CAAC;IAkDvE;;;;;;;;OAQG;IACH,cAAc,CACZ,QAAQ,EAAE,qCAAqC,CAC7C,UAAU,CAAC,SAAS,CAAC,EACrB;QAAE,kBAAkB,EAAE,MAAM,CAAA;KAAE,CAC/B,GACA;QAAE,OAAO,IAAI,IAAI,CAAA;KAAE;IAiBtB;;;;;;;;;;;;;OAaG;IACH,OAAO,CACL,QAAQ,EAAE,CACR,IAAI,EAAE,yBAAyB,CAC7B,yBAAyB,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,EAChD,aAAa,CACd,KACE,IAAI,GACR,WAAW;IAId;;;;;;;;;OASG;IACH,cAAc,CACZ,QAAQ,EAAE,qCAAqC,CAC7C,UAAU,CAAC,SAAS,CAAC,EACrB;QAAE,kBAAkB,EAAE,MAAM,CAAA;KAAE,CAC/B,GACA,WAAW;IAiBd;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,UAAU,CACR,QAAQ,EAAE,CACR,IAAI,EAAE,yBAAyB,CAC7B,yBAAyB,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,EACnD,aAAa,CACd,KACE,IAAI,GACR,WAAW;IAId;;;;;;;;;;;;;;;;;;;OAmBG;IACH,iBAAiB,CACf,QAAQ,EAAE,qCAAqC,CAC7C,UAAU,CAAC,YAAY,CAAC,EACxB;QAAE,kBAAkB,EAAE,MAAM,CAAA;KAAE,CAC/B,GACA,WAAW;IAiBd;;;;;;;;;;;;;;;OAeG;IACH,WAAW,CACT,QAAQ,EAAE,CACR,IAAI,EAAE,yBAAyB,CAC7B,yBAAyB,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC,EACpD,aAAa,CACd,KACE,IAAI,GACR,WAAW;IAId;;;;;;;;;;;;;;;;;OAiBG;IACG,OAAO,CAAC,MAAM,SAAS,aAAa,EAAE,MAAM,SAAS,IAAI,EAC7D,cAAc,EAAE,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,GAAG;QACjD,MAAM,EAAE,sBAAsB,CAAC;KAChC,EACD,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,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,EAChD,YAAY,CAAC,EAAE,YAAY,GAC1B,OAAO,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;CA8FpC"}
@@ -1 +1 @@
1
- {"version":3,"file":"rpc-service-chain.mjs","sourceRoot":"","sources":["../../src/rpc-service/rpc-service-chain.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n CircuitState,\n CockatielEventEmitter,\n} from '@metamask/controller-utils';\nimport 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 {\n CockatielEventToEventListenerWithData,\n ExcludeCockatielEventData,\n ExtractCockatielEventData,\n FetchOptions,\n} from './shared';\nimport { projectLogger, createModuleLogger } from '../logger';\n\nconst log = createModuleLogger(projectLogger, 'RpcServiceChain');\n\n/**\n * Statuses that the RPC service chain can be in.\n */\nconst STATUSES = {\n Available: 'available',\n Degraded: 'degraded',\n Unknown: 'unknown',\n Unavailable: 'unavailable',\n} as const;\n\n/**\n * Statuses that the RPC service chain can be in.\n */\ntype Status = (typeof STATUSES)[keyof typeof STATUSES];\n\n/**\n * This class constructs and manages requests to a chain of RpcService objects\n * which represent RPC endpoints with which to access a particular network. The\n * first service in the chain is intended to be the primary way of hitting the\n * network and the remaining services are used as failovers.\n */\nexport class RpcServiceChain {\n /**\n * The event emitter for the `onAvailable` event.\n */\n readonly #onAvailableEventEmitter: CockatielEventEmitter<\n ExcludeCockatielEventData<\n ExtractCockatielEventData<RpcService['onAvailable']>,\n 'endpointUrl'\n >\n >;\n\n /**\n * The event emitter for the `onBreak` event.\n */\n readonly #onBreakEventEmitter: CockatielEventEmitter<\n ExcludeCockatielEventData<\n ExtractCockatielEventData<RpcService['onBreak']>,\n 'endpointUrl'\n >\n >;\n\n /**\n * The event emitter for the `onDegraded` event.\n */\n readonly #onDegradedEventEmitter: CockatielEventEmitter<\n ExcludeCockatielEventData<\n ExtractCockatielEventData<RpcService['onDegraded']>,\n 'endpointUrl'\n >\n >;\n\n /**\n * The first RPC service that requests will be sent to.\n */\n readonly #primaryService: RpcService;\n\n /**\n * The RPC services in the chain.\n */\n readonly #services: RpcService[];\n\n /**\n * The status of the RPC service chain.\n */\n #status: Status;\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: [RpcServiceOptions, ...RpcServiceOptions[]],\n ) {\n this.#services = rpcServiceConfigurations.map(\n (rpcServiceConfiguration) => new RpcService(rpcServiceConfiguration),\n );\n this.#primaryService = this.#services[0];\n\n this.#status = STATUSES.Unknown;\n this.#onBreakEventEmitter = new CockatielEventEmitter<\n ExcludeCockatielEventData<\n ExtractCockatielEventData<RpcService['onBreak']>,\n 'endpointUrl'\n >\n >();\n\n this.#onDegradedEventEmitter = new CockatielEventEmitter<\n ExcludeCockatielEventData<\n ExtractCockatielEventData<RpcService['onDegraded']>,\n 'endpointUrl'\n >\n >();\n for (const service of this.#services) {\n service.onDegraded((data) => {\n if (this.#status !== STATUSES.Degraded) {\n log('Updating status to \"degraded\"', data);\n this.#status = STATUSES.Degraded;\n const { endpointUrl, ...rest } = data;\n this.#onDegradedEventEmitter.emit(rest);\n }\n });\n }\n\n this.#onAvailableEventEmitter = new CockatielEventEmitter<\n ExcludeCockatielEventData<\n ExtractCockatielEventData<RpcService['onAvailable']>,\n 'endpointUrl'\n >\n >();\n for (const service of this.#services) {\n service.onAvailable((data) => {\n if (this.#status !== STATUSES.Available) {\n log('Updating status to \"available\"', data);\n this.#status = STATUSES.Available;\n const { endpointUrl, ...rest } = data;\n this.#onAvailableEventEmitter.emit(rest);\n }\n });\n }\n }\n\n /**\n * Calls the provided callback when any of the RPC services is retried.\n *\n * This is mainly useful for tests.\n *\n * @param listener - The callback to be called.\n * @returns An object with a `dispose` method which can be used to unregister\n * the event listener.\n */\n onServiceRetry(\n listener: CockatielEventToEventListenerWithData<\n RpcService['onRetry'],\n { primaryEndpointUrl: string }\n >,\n ) {\n const disposables = this.#services.map((service) =>\n service.onRetry((data) => {\n listener({\n ...data,\n primaryEndpointUrl: this.#primaryService.endpointUrl.toString(),\n });\n }),\n );\n\n return {\n dispose() {\n disposables.forEach((disposable) => disposable.dispose());\n },\n };\n }\n\n /**\n * Calls the provided callback only when the maximum number of failed\n * consecutive attempts to receive a 2xx response has been reached for all\n * RPC services in the chain, and all services' underlying circuits have\n * broken.\n *\n * The callback will not be called if a service's circuit breaks but its\n * failover does not. Use `onServiceBreak` if you'd like a lower level of\n * granularity.\n *\n * @param listener - The callback to be called.\n * @returns An object with a `dispose` method which can be used to unregister\n * the callback.\n */\n onBreak(\n listener: (\n data: ExcludeCockatielEventData<\n ExtractCockatielEventData<RpcService['onBreak']>,\n 'endpointUrl'\n >,\n ) => void,\n ) {\n return this.#onBreakEventEmitter.addListener(listener);\n }\n\n /**\n * Calls the provided callback each time when, for *any* of the RPC services\n * in this chain, the maximum number of failed consecutive attempts to receive\n * a 2xx response has been reached and the underlying circuit has broken. A\n * more granular version of `onBreak`.\n *\n * @param listener - The callback to be called.\n * @returns An object with a `dispose` method which can be used to unregister\n * the callback.\n */\n onServiceBreak(\n listener: CockatielEventToEventListenerWithData<\n RpcService['onBreak'],\n { primaryEndpointUrl: string }\n >,\n ) {\n const disposables = this.#services.map((service) =>\n service.onBreak((data) => {\n listener({\n ...data,\n primaryEndpointUrl: this.#primaryService.endpointUrl.toString(),\n });\n }),\n );\n\n return {\n dispose() {\n disposables.forEach((disposable) => disposable.dispose());\n },\n };\n }\n\n /**\n * Calls the provided callback if no requests have been initiated yet or\n * all requests to RPC services in this chain have responded successfully in a\n * timely fashion, and then one of the two conditions apply:\n *\n * 1. When a retriable error is encountered making a request to an RPC\n * service, and the request is retried until a set maximum is reached.\n * 2. When a RPC service responds successfully, but the request takes longer\n * than a set number of seconds to complete.\n *\n * Note that the callback will be called even if there are local connectivity\n * issues which prevent requests from being initiated. This is intentional.\n *\n * Also note this callback will only be called if the RPC service chain as a\n * whole is in a \"degraded\" state, and will then only be called once (e.g., it\n * will not be called if a failover service falls into a degraded state, then\n * the primary comes back online, but it is slow). Use `onServiceDegraded` if\n * you'd like a lower level of granularity.\n *\n * @param listener - The callback to be called.\n * @returns An object with a `dispose` method which can be used to unregister\n * the callback.\n */\n onDegraded(\n listener: (\n data: ExcludeCockatielEventData<\n ExtractCockatielEventData<RpcService['onDegraded']>,\n 'endpointUrl'\n >,\n ) => void,\n ) {\n return this.#onDegradedEventEmitter.addListener(listener);\n }\n\n /**\n * Calls the provided callback each time one of the two conditions apply:\n *\n * 1. When a retriable error is encountered making a request to an RPC\n * service, and the request is retried until a set maximum is reached.\n * 2. When a RPC service responds successfully, but the request takes longer\n * than a set number of seconds to complete.\n *\n * Note that the callback will be called even if there are local connectivity\n * issues which prevent requests from being initiated. This is intentional.\n *\n * This is a more granular version of `onDegraded`. The callback will be\n * called for each slow request to an RPC service. It may also be called again\n * if a failover service falls into a degraded state, then the primary comes\n * back online, but it is slow.\n *\n * @param listener - The callback to be called.\n * @returns An object with a `dispose` method which can be used to unregister\n * the callback.\n */\n onServiceDegraded(\n listener: CockatielEventToEventListenerWithData<\n RpcService['onDegraded'],\n { primaryEndpointUrl: string }\n >,\n ) {\n const disposables = this.#services.map((service) =>\n service.onDegraded((data) => {\n listener({\n ...data,\n primaryEndpointUrl: this.#primaryService.endpointUrl.toString(),\n });\n }),\n );\n\n return {\n dispose() {\n disposables.forEach((disposable) => disposable.dispose());\n },\n };\n }\n\n /**\n * Calls the provided callback in one of the following two conditions:\n *\n * 1. The first time that a 2xx request is made to any of the RPC services in\n * this chain.\n * 2. When requests to any the failover RPC services in this chain were\n * failing such that they were degraded or their underyling circuits broke,\n * but the first request to the primary succeeds again.\n *\n * Note this callback will only be called if the RPC service chain as a whole\n * is in an \"available\" state.\n *\n * @param listener - The callback to be called.\n * @returns An object with a `dispose` method which can be used to unregister\n * the callback.\n */\n onAvailable(\n listener: (\n data: ExcludeCockatielEventData<\n ExtractCockatielEventData<RpcService['onAvailable']>,\n 'endpointUrl'\n >,\n ) => void,\n ) {\n return this.#onAvailableEventEmitter.addListener(listener);\n }\n\n /**\n * Uses the RPC services in the chain to make a request, using each service\n * after the first as a fallback to the previous one as necessary.\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 401 error if the response status is 401.\n * @throws A \"rate limiting\" error if the response HTTP status is 429.\n * @throws A \"resource unavailable\" error if the response status is 402, 404, or any 5xx.\n * @throws A generic HTTP client error (-32100) for any other 4xx status codes.\n * @throws A \"parse\" error if the response is not valid JSON.\n */\n async request<Params extends JsonRpcParams, Result extends Json>(\n jsonRpcRequest: Readonly<JsonRpcRequest<Params>> & {\n method: 'eth_getBlockByNumber';\n },\n fetchOptions?: FetchOptions,\n ): Promise<JsonRpcResponse<Result> | JsonRpcResponse<null>>;\n\n /**\n * Uses the RPC services in the chain to make a request, using each service\n * after the first as a fallback to the previous one as necessary.\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 401 error if the response status is 401.\n * @throws A \"rate limiting\" error if the response HTTP status is 429.\n * @throws A \"resource unavailable\" error if the response status is 402, 404, or any 5xx.\n * @throws A generic HTTP client error (-32100) for any other 4xx status codes.\n * @throws A \"parse\" error if the response is not valid JSON.\n */\n async request<Params extends JsonRpcParams, Result extends Json>(\n jsonRpcRequest: Readonly<JsonRpcRequest<Params>>,\n fetchOptions?: FetchOptions,\n ): Promise<JsonRpcResponse<Result>>;\n\n async request<Params extends JsonRpcParams, Result extends Json>(\n jsonRpcRequest: Readonly<JsonRpcRequest<Params>>,\n fetchOptions: FetchOptions = {},\n ): Promise<JsonRpcResponse<Result | null>> {\n // Start with the primary (first) service and switch to failovers as the\n // need arises. This is a bit confusing, so keep reading for more on how\n // this works.\n\n let availableServiceIndex: number | undefined;\n let response: JsonRpcResponse<Result> | undefined;\n\n for (const [i, service] of this.#services.entries()) {\n log(`Trying service #${i + 1}...`);\n const previousCircuitState = service.getCircuitState();\n\n try {\n // Try making the request through the service.\n response = await service.request<Params, Result>(\n jsonRpcRequest,\n fetchOptions,\n );\n log('Service successfully received request.');\n availableServiceIndex = i;\n break;\n } catch (error) {\n // Oops, that didn't work.\n // Capture this error so that we can handle it later.\n\n const { lastError } = service;\n const isCircuitOpen = service.getCircuitState() === CircuitState.Open;\n\n log('Service failed! error =', error, 'lastError = ', lastError);\n\n if (isCircuitOpen) {\n if (i < this.#services.length - 1) {\n log(\n \"This service's circuit is open. Proceeding to next service...\",\n );\n continue;\n }\n\n if (\n previousCircuitState !== CircuitState.Open &&\n this.#status !== STATUSES.Unavailable &&\n lastError !== undefined\n ) {\n // If the service's circuit just broke and it's the last one in the\n // chain, then trigger the onBreak event. (But if for some reason we\n // have already done this, then don't do it.)\n log(\n 'This service\\'s circuit just opened and it is the last service. Updating status to \"unavailable\" and triggering onBreak.',\n );\n this.#status = STATUSES.Unavailable;\n this.#onBreakEventEmitter.emit({\n error: lastError,\n });\n }\n }\n\n // The service failed, and we throw whatever the error is. The calling\n // code can try again if it so desires.\n log(\n `${isCircuitOpen ? '' : \"This service's circuit is closed. \"}Re-throwing error.`,\n );\n throw error;\n }\n }\n\n if (response) {\n // If one of the services is available, reset all of the circuits of the\n // following services. If we didn't do this and the service became\n // unavailable in the future, and any of the failovers' circuits were\n // open (due to previous failures), we would receive a \"circuit broken\"\n // error when we attempted to divert traffic to the failovers again.\n //\n if (availableServiceIndex !== undefined) {\n for (const [i, service] of [...this.#services.entries()].slice(\n availableServiceIndex + 1,\n )) {\n log(`Resetting policy for service #${i + 1}.`);\n service.resetPolicy();\n }\n }\n\n return response;\n }\n\n // The only way we can end up here is if there are no services to loop over.\n // That is not possible due to the types on the constructor, but TypeScript\n // doesn't know this, so we have to appease it.\n throw new Error('Nothing to return');\n }\n}\n"]}
1
+ {"version":3,"file":"rpc-service-chain.mjs","sourceRoot":"","sources":["../../src/rpc-service/rpc-service-chain.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n CircuitState,\n CockatielEventEmitter,\n} from '@metamask/controller-utils';\nimport type {\n Json,\n JsonRpcParams,\n JsonRpcRequest,\n JsonRpcResponse,\n} from '@metamask/utils';\nimport { IDisposable } from 'cockatiel';\n\nimport { RpcService } from './rpc-service';\nimport type { RpcServiceOptions } from './rpc-service';\nimport type {\n CockatielEventToEventListenerWithData,\n ExcludeCockatielEventData,\n ExtractCockatielEventData,\n FetchOptions,\n} from './shared';\nimport { projectLogger, createModuleLogger } from '../logger';\n\nconst log = createModuleLogger(projectLogger, 'RpcServiceChain');\n\n/**\n * Statuses that the RPC service chain can be in.\n */\nconst STATUSES = {\n Available: 'available',\n Degraded: 'degraded',\n Unknown: 'unknown',\n Unavailable: 'unavailable',\n} as const;\n\n/**\n * Statuses that the RPC service chain can be in.\n */\ntype Status = (typeof STATUSES)[keyof typeof STATUSES];\n\n/**\n * This class constructs and manages requests to a chain of RpcService objects\n * which represent RPC endpoints with which to access a particular network. The\n * first service in the chain is intended to be the primary way of hitting the\n * network and the remaining services are used as failovers.\n */\nexport class RpcServiceChain {\n /**\n * The event emitter for the `onAvailable` event.\n */\n readonly #onAvailableEventEmitter: CockatielEventEmitter<\n ExcludeCockatielEventData<\n ExtractCockatielEventData<RpcService['onAvailable']>,\n 'endpointUrl'\n >\n >;\n\n /**\n * The event emitter for the `onBreak` event.\n */\n readonly #onBreakEventEmitter: CockatielEventEmitter<\n ExcludeCockatielEventData<\n ExtractCockatielEventData<RpcService['onBreak']>,\n 'endpointUrl'\n >\n >;\n\n /**\n * The event emitter for the `onDegraded` event.\n */\n readonly #onDegradedEventEmitter: CockatielEventEmitter<\n ExcludeCockatielEventData<\n ExtractCockatielEventData<RpcService['onDegraded']>,\n 'endpointUrl'\n >\n >;\n\n /**\n * The first RPC service that requests will be sent to.\n */\n readonly #primaryService: RpcService;\n\n /**\n * The RPC services in the chain.\n */\n readonly #services: RpcService[];\n\n /**\n * The status of the RPC service chain.\n */\n #status: Status;\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: [RpcServiceOptions, ...RpcServiceOptions[]],\n ) {\n this.#services = rpcServiceConfigurations.map(\n (rpcServiceConfiguration) => new RpcService(rpcServiceConfiguration),\n );\n this.#primaryService = this.#services[0];\n\n this.#status = STATUSES.Unknown;\n this.#onBreakEventEmitter = new CockatielEventEmitter<\n ExcludeCockatielEventData<\n ExtractCockatielEventData<RpcService['onBreak']>,\n 'endpointUrl'\n >\n >();\n\n this.#onDegradedEventEmitter = new CockatielEventEmitter<\n ExcludeCockatielEventData<\n ExtractCockatielEventData<RpcService['onDegraded']>,\n 'endpointUrl'\n >\n >();\n for (const service of this.#services) {\n service.onDegraded((data) => {\n if (this.#status !== STATUSES.Degraded) {\n log('Updating status to \"degraded\"', data);\n this.#status = STATUSES.Degraded;\n const { endpointUrl, ...rest } = data;\n this.#onDegradedEventEmitter.emit(rest);\n }\n });\n }\n\n this.#onAvailableEventEmitter = new CockatielEventEmitter<\n ExcludeCockatielEventData<\n ExtractCockatielEventData<RpcService['onAvailable']>,\n 'endpointUrl'\n >\n >();\n for (const service of this.#services) {\n service.onAvailable((data) => {\n if (this.#status !== STATUSES.Available) {\n log('Updating status to \"available\"', data);\n this.#status = STATUSES.Available;\n const { endpointUrl, ...rest } = data;\n this.#onAvailableEventEmitter.emit(rest);\n }\n });\n }\n }\n\n /**\n * Calls the provided callback when any of the RPC services is retried.\n *\n * This is mainly useful for tests.\n *\n * @param listener - The callback to be called.\n * @returns An object with a `dispose` method which can be used to unregister\n * the event listener.\n */\n onServiceRetry(\n listener: CockatielEventToEventListenerWithData<\n RpcService['onRetry'],\n { primaryEndpointUrl: string }\n >,\n ): { dispose(): void } {\n const disposables = this.#services.map((service) =>\n service.onRetry((data) => {\n listener({\n ...data,\n primaryEndpointUrl: this.#primaryService.endpointUrl.toString(),\n });\n }),\n );\n\n return {\n dispose(): void {\n disposables.forEach((disposable) => disposable.dispose());\n },\n };\n }\n\n /**\n * Calls the provided callback only when the maximum number of failed\n * consecutive attempts to receive a 2xx response has been reached for all\n * RPC services in the chain, and all services' underlying circuits have\n * broken.\n *\n * The callback will not be called if a service's circuit breaks but its\n * failover does not. Use `onServiceBreak` if you'd like a lower level of\n * granularity.\n *\n * @param listener - The callback to be called.\n * @returns An object with a `dispose` method which can be used to unregister\n * the callback.\n */\n onBreak(\n listener: (\n data: ExcludeCockatielEventData<\n ExtractCockatielEventData<RpcService['onBreak']>,\n 'endpointUrl'\n >,\n ) => void,\n ): IDisposable {\n return this.#onBreakEventEmitter.addListener(listener);\n }\n\n /**\n * Calls the provided callback each time when, for *any* of the RPC services\n * in this chain, the maximum number of failed consecutive attempts to receive\n * a 2xx response has been reached and the underlying circuit has broken. A\n * more granular version of `onBreak`.\n *\n * @param listener - The callback to be called.\n * @returns An object with a `dispose` method which can be used to unregister\n * the callback.\n */\n onServiceBreak(\n listener: CockatielEventToEventListenerWithData<\n RpcService['onBreak'],\n { primaryEndpointUrl: string }\n >,\n ): IDisposable {\n const disposables = this.#services.map((service) =>\n service.onBreak((data) => {\n listener({\n ...data,\n primaryEndpointUrl: this.#primaryService.endpointUrl.toString(),\n });\n }),\n );\n\n return {\n dispose(): void {\n disposables.forEach((disposable) => disposable.dispose());\n },\n };\n }\n\n /**\n * Calls the provided callback if no requests have been initiated yet or\n * all requests to RPC services in this chain have responded successfully in a\n * timely fashion, and then one of the two conditions apply:\n *\n * 1. When a retriable error is encountered making a request to an RPC\n * service, and the request is retried until a set maximum is reached.\n * 2. When a RPC service responds successfully, but the request takes longer\n * than a set number of seconds to complete.\n *\n * Note that the callback will be called even if there are local connectivity\n * issues which prevent requests from being initiated. This is intentional.\n *\n * Also note this callback will only be called if the RPC service chain as a\n * whole is in a \"degraded\" state, and will then only be called once (e.g., it\n * will not be called if a failover service falls into a degraded state, then\n * the primary comes back online, but it is slow). Use `onServiceDegraded` if\n * you'd like a lower level of granularity.\n *\n * @param listener - The callback to be called.\n * @returns An object with a `dispose` method which can be used to unregister\n * the callback.\n */\n onDegraded(\n listener: (\n data: ExcludeCockatielEventData<\n ExtractCockatielEventData<RpcService['onDegraded']>,\n 'endpointUrl'\n >,\n ) => void,\n ): IDisposable {\n return this.#onDegradedEventEmitter.addListener(listener);\n }\n\n /**\n * Calls the provided callback each time one of the two conditions apply:\n *\n * 1. When a retriable error is encountered making a request to an RPC\n * service, and the request is retried until a set maximum is reached.\n * 2. When a RPC service responds successfully, but the request takes longer\n * than a set number of seconds to complete.\n *\n * Note that the callback will be called even if there are local connectivity\n * issues which prevent requests from being initiated. This is intentional.\n *\n * This is a more granular version of `onDegraded`. The callback will be\n * called for each slow request to an RPC service. It may also be called again\n * if a failover service falls into a degraded state, then the primary comes\n * back online, but it is slow.\n *\n * @param listener - The callback to be called.\n * @returns An object with a `dispose` method which can be used to unregister\n * the callback.\n */\n onServiceDegraded(\n listener: CockatielEventToEventListenerWithData<\n RpcService['onDegraded'],\n { primaryEndpointUrl: string }\n >,\n ): IDisposable {\n const disposables = this.#services.map((service) =>\n service.onDegraded((data) => {\n listener({\n ...data,\n primaryEndpointUrl: this.#primaryService.endpointUrl.toString(),\n });\n }),\n );\n\n return {\n dispose(): void {\n disposables.forEach((disposable) => disposable.dispose());\n },\n };\n }\n\n /**\n * Calls the provided callback in one of the following two conditions:\n *\n * 1. The first time that a 2xx request is made to any of the RPC services in\n * this chain.\n * 2. When requests to any the failover RPC services in this chain were\n * failing such that they were degraded or their underyling circuits broke,\n * but the first request to the primary succeeds again.\n *\n * Note this callback will only be called if the RPC service chain as a whole\n * is in an \"available\" state.\n *\n * @param listener - The callback to be called.\n * @returns An object with a `dispose` method which can be used to unregister\n * the callback.\n */\n onAvailable(\n listener: (\n data: ExcludeCockatielEventData<\n ExtractCockatielEventData<RpcService['onAvailable']>,\n 'endpointUrl'\n >,\n ) => void,\n ): IDisposable {\n return this.#onAvailableEventEmitter.addListener(listener);\n }\n\n /**\n * Uses the RPC services in the chain to make a request, using each service\n * after the first as a fallback to the previous one as necessary.\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 401 error if the response status is 401.\n * @throws A \"rate limiting\" error if the response HTTP status is 429.\n * @throws A \"resource unavailable\" error if the response status is 402, 404, or any 5xx.\n * @throws A generic HTTP client error (-32100) for any other 4xx status codes.\n * @throws A \"parse\" error if the response is not valid JSON.\n */\n async request<Params extends JsonRpcParams, Result extends Json>(\n jsonRpcRequest: Readonly<JsonRpcRequest<Params>> & {\n method: 'eth_getBlockByNumber';\n },\n fetchOptions?: FetchOptions,\n ): Promise<JsonRpcResponse<Result> | JsonRpcResponse<null>>;\n\n /**\n * Uses the RPC services in the chain to make a request, using each service\n * after the first as a fallback to the previous one as necessary.\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 401 error if the response status is 401.\n * @throws A \"rate limiting\" error if the response HTTP status is 429.\n * @throws A \"resource unavailable\" error if the response status is 402, 404, or any 5xx.\n * @throws A generic HTTP client error (-32100) for any other 4xx status codes.\n * @throws A \"parse\" error if the response is not valid JSON.\n */\n async request<Params extends JsonRpcParams, Result extends Json>(\n jsonRpcRequest: Readonly<JsonRpcRequest<Params>>,\n fetchOptions?: FetchOptions,\n ): Promise<JsonRpcResponse<Result>>;\n\n async request<Params extends JsonRpcParams, Result extends Json>(\n jsonRpcRequest: Readonly<JsonRpcRequest<Params>>,\n fetchOptions: FetchOptions = {},\n ): Promise<JsonRpcResponse<Result | null>> {\n // Start with the primary (first) service and switch to failovers as the\n // need arises. This is a bit confusing, so keep reading for more on how\n // this works.\n\n let availableServiceIndex: number | undefined;\n let response: JsonRpcResponse<Result> | undefined;\n\n for (const [i, service] of this.#services.entries()) {\n log(`Trying service #${i + 1}...`);\n const previousCircuitState = service.getCircuitState();\n\n try {\n // Try making the request through the service.\n response = await service.request<Params, Result>(\n jsonRpcRequest,\n fetchOptions,\n );\n log('Service successfully received request.');\n availableServiceIndex = i;\n break;\n } catch (error) {\n // Oops, that didn't work.\n // Capture this error so that we can handle it later.\n\n const { lastError } = service;\n const isCircuitOpen = service.getCircuitState() === CircuitState.Open;\n\n log('Service failed! error =', error, 'lastError = ', lastError);\n\n if (isCircuitOpen) {\n if (i < this.#services.length - 1) {\n log(\n \"This service's circuit is open. Proceeding to next service...\",\n );\n continue;\n }\n\n if (\n previousCircuitState !== CircuitState.Open &&\n this.#status !== STATUSES.Unavailable &&\n lastError !== undefined\n ) {\n // If the service's circuit just broke and it's the last one in the\n // chain, then trigger the onBreak event. (But if for some reason we\n // have already done this, then don't do it.)\n log(\n 'This service\\'s circuit just opened and it is the last service. Updating status to \"unavailable\" and triggering onBreak.',\n );\n this.#status = STATUSES.Unavailable;\n this.#onBreakEventEmitter.emit({\n error: lastError,\n });\n }\n }\n\n // The service failed, and we throw whatever the error is. The calling\n // code can try again if it so desires.\n log(\n `${isCircuitOpen ? '' : \"This service's circuit is closed. \"}Re-throwing error.`,\n );\n throw error;\n }\n }\n\n if (response) {\n // If one of the services is available, reset all of the circuits of the\n // following services. If we didn't do this and the service became\n // unavailable in the future, and any of the failovers' circuits were\n // open (due to previous failures), we would receive a \"circuit broken\"\n // error when we attempted to divert traffic to the failovers again.\n //\n if (availableServiceIndex !== undefined) {\n for (const [i, service] of [...this.#services.entries()].slice(\n availableServiceIndex + 1,\n )) {\n log(`Resetting policy for service #${i + 1}.`);\n service.resetPolicy();\n }\n }\n\n return response;\n }\n\n // The only way we can end up here is if there are no services to loop over.\n // That is not possible due to the types on the constructor, but TypeScript\n // doesn't know this, so we have to appease it.\n throw new Error('Nothing to return');\n }\n}\n"]}
@@ -19,6 +19,7 @@ exports.RpcService = exports.isConnectionError = exports.CUSTOM_RPC_ERRORS = exp
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
+ const cockatiel_1 = require("cockatiel");
22
23
  const deepmerge_1 = __importDefault(require("deepmerge"));
23
24
  const logger_1 = require("../logger.cjs");
24
25
  const log = (0, logger_1.createModuleLogger)(logger_1.projectLogger, 'RpcService');
@@ -1 +1 @@
1
- {"version":3,"file":"rpc-service.cjs","sourceRoot":"","sources":["../../src/rpc-service/rpc-service.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n CreateServicePolicyOptions,\n ServicePolicy,\n} from '@metamask/controller-utils';\nimport {\n BrokenCircuitError,\n HttpError,\n createServicePolicy,\n handleWhen,\n} from '@metamask/controller-utils';\nimport { JsonRpcError, rpcErrors } from '@metamask/rpc-errors';\nimport { Duration, getErrorMessage, hasProperty } from '@metamask/utils';\nimport type {\n Json,\n JsonRpcParams,\n JsonRpcRequest,\n JsonRpcResponse,\n} from '@metamask/utils';\nimport deepmerge from 'deepmerge';\nimport type { Logger } from 'loglevel';\n\nimport type { AbstractRpcService } from './abstract-rpc-service';\nimport type { FetchOptions } from './shared';\nimport { projectLogger, createModuleLogger } from '../logger';\n\n/**\n * Options for the RpcService constructor.\n */\nexport type RpcServiceOptions = {\n /**\n * A function that can be used to convert a binary string into a\n * base64-encoded ASCII string. Used to encode authorization credentials.\n */\n btoa: typeof btoa;\n /**\n * The URL of the RPC endpoint to hit.\n */\n endpointUrl: URL | string;\n /**\n * A function that can be used to make an HTTP request. If your JavaScript\n * environment supports `fetch` natively, you'll probably want to pass that;\n * otherwise you can pass an equivalent (such as `fetch` via `node-fetch`).\n */\n fetch: typeof fetch;\n /**\n * A common set of options that will be used to make every request. Can be\n * overridden on the request level (e.g. to add headers).\n */\n fetchOptions?: FetchOptions;\n /**\n * A `loglevel` logger.\n */\n logger?: Pick<Logger, 'warn'>;\n /**\n * Options to pass to `createServicePolicy`. Note that `retryFilterPolicy` is\n * not accepted, as it is overwritten. See {@link createServicePolicy}.\n */\n policyOptions?: Omit<CreateServicePolicyOptions, 'retryFilterPolicy'>;\n};\n\nconst log = createModuleLogger(projectLogger, 'RpcService');\n\n/**\n * The maximum number of times that a failing service should be re-run before\n * giving up.\n */\nexport const DEFAULT_MAX_RETRIES = 4;\n\n/**\n * The maximum number of times that the service is allowed to fail before\n * pausing further retries. This is set to a value such that if given a\n * service that continually fails, the policy needs to be executed 3 times\n * before further retries are paused.\n */\nexport const DEFAULT_MAX_CONSECUTIVE_FAILURES = (1 + DEFAULT_MAX_RETRIES) * 3;\n\n/**\n * The list of error messages that represent a failure to connect to the network.\n *\n * This list was derived from Sindre Sorhus's `is-network-error` package:\n * <https://github.com/sindresorhus/is-network-error/blob/7bbfa8be9482ce1427a21fbff60e3ee1650dd091/index.js>\n */\nexport const CONNECTION_ERRORS = [\n // Chrome\n {\n constructorName: 'TypeError',\n pattern: /network error/u,\n },\n // Chrome\n {\n constructorName: 'TypeError',\n pattern: /Failed to fetch/u,\n },\n // Firefox\n {\n constructorName: 'TypeError',\n pattern: /NetworkError when attempting to fetch resource\\./u,\n },\n // Safari 16\n {\n constructorName: 'TypeError',\n pattern: /The Internet connection appears to be offline\\./u,\n },\n // Safari 17+\n {\n constructorName: 'TypeError',\n pattern: /Load failed/u,\n },\n // `cross-fetch`\n {\n constructorName: 'TypeError',\n pattern: /Network request failed/u,\n },\n // `node-fetch`\n {\n constructorName: 'FetchError',\n pattern: /request to (.+) failed/u,\n },\n // Undici (Node.js)\n {\n constructorName: 'TypeError',\n pattern: /fetch failed/u,\n },\n // Undici (Node.js)\n {\n constructorName: 'TypeError',\n pattern: /terminated/u,\n },\n];\n\n/**\n * Custom JSON-RPC error codes for specific cases.\n *\n * These should be moved to `@metamask/rpc-errors` eventually.\n */\nexport const CUSTOM_RPC_ERRORS = {\n unauthorized: -32006,\n httpClientError: -32080,\n} as const;\n\n/**\n * Determines whether the given error represents a failure to reach the network\n * after request parameters have been validated.\n *\n * This is somewhat difficult to verify because JavaScript engines (and in\n * some cases libraries) produce slightly different error messages for this\n * particular scenario, and we need to account for this.\n *\n * @param error - The error.\n * @returns True if the error indicates that the network cannot be connected to,\n * and false otherwise.\n */\nexport function isConnectionError(error: unknown) {\n if (!(typeof error === 'object' && error !== null && 'message' in error)) {\n return false;\n }\n\n const { message } = error;\n\n return (\n typeof message === 'string' &&\n !isNockError(message) &&\n CONNECTION_ERRORS.some(({ constructorName, pattern }) => {\n return (\n error.constructor.name === constructorName && pattern.test(message)\n );\n })\n );\n}\n\n/**\n * Determines whether the given error message refers to a Nock error.\n *\n * It's important that if we failed to mock a request in a test, the resulting\n * error does not cause the request to be retried so that we can see it right\n * away.\n *\n * @param message - The error message to test.\n * @returns True if the message indicates a missing Nock mock, false otherwise.\n */\nfunction isNockError(message: string) {\n return message.includes('Nock:');\n}\n\n/**\n * Determine whether the given error message indicates a failure to parse JSON.\n *\n * This is different in tests vs. implementation code because it may manifest as\n * a FetchError or a SyntaxError.\n *\n * @param error - The error object to test.\n * @returns True if the error indicates a JSON parse error, false otherwise.\n */\nfunction isJsonParseError(error: unknown) {\n return (\n error instanceof SyntaxError ||\n /invalid json/iu.test(getErrorMessage(error))\n );\n}\n\n/**\n * Guarantees a URL, even given a string. This is useful for checking components\n * of that URL.\n *\n * @param endpointUrlOrUrlString - Either a URL object or a string that\n * represents the URL of an endpoint.\n * @returns A URL object.\n */\nfunction getNormalizedEndpointUrl(endpointUrlOrUrlString: URL | string): URL {\n return endpointUrlOrUrlString instanceof URL\n ? endpointUrlOrUrlString\n : new URL(endpointUrlOrUrlString);\n}\n\n/**\n * Strips username and password from a URL.\n *\n * @param url - The URL to strip credentials from.\n * @returns A new URL object with credentials removed.\n */\nfunction stripCredentialsFromUrl(url: URL): URL {\n const strippedUrl = new URL(url.toString());\n strippedUrl.username = '';\n strippedUrl.password = '';\n return strippedUrl;\n}\n\n/**\n * This class is responsible for making a request to an endpoint that implements\n * the JSON-RPC protocol. It is designed to gracefully handle network and server\n * failures, retrying requests using exponential backoff. It also offers a hook\n * which can used to respond to slow requests.\n */\nexport class RpcService implements AbstractRpcService {\n /**\n * The URL of the RPC endpoint.\n */\n readonly endpointUrl: URL;\n\n /**\n * The last error that the retry policy captured (or `undefined` if the last\n * execution of the service was successful).\n */\n lastError: Error | undefined;\n\n /**\n * The function used to make an HTTP request.\n */\n readonly #fetch: typeof fetch;\n\n /**\n * A common set of options that the request options will extend.\n */\n readonly #fetchOptions: FetchOptions;\n\n /**\n * A `loglevel` logger.\n */\n readonly #logger: RpcServiceOptions['logger'];\n\n /**\n * The policy that wraps the request.\n */\n readonly #policy: ServicePolicy;\n\n /**\n * Constructs a new RpcService object.\n *\n * @param options - The options. See {@link RpcServiceOptions}.\n */\n constructor(options: RpcServiceOptions) {\n const {\n btoa: givenBtoa,\n endpointUrl,\n fetch: givenFetch,\n logger,\n fetchOptions = {},\n policyOptions = {},\n } = options;\n\n this.#fetch = givenFetch;\n const normalizedUrl = getNormalizedEndpointUrl(endpointUrl);\n this.#fetchOptions = this.#getDefaultFetchOptions(\n normalizedUrl,\n fetchOptions,\n givenBtoa,\n );\n this.endpointUrl = stripCredentialsFromUrl(normalizedUrl);\n this.#logger = logger;\n\n this.#policy = createServicePolicy({\n maxRetries: DEFAULT_MAX_RETRIES,\n maxConsecutiveFailures: DEFAULT_MAX_CONSECUTIVE_FAILURES,\n ...policyOptions,\n retryFilterPolicy: handleWhen((error) => {\n return (\n // Ignore errors where the request failed to establish\n isConnectionError(error) ||\n // Ignore server sent HTML error pages or truncated JSON responses\n isJsonParseError(error) ||\n // Ignore server overload errors\n ('httpStatus' in error &&\n (error.httpStatus === 502 ||\n error.httpStatus === 503 ||\n error.httpStatus === 504)) ||\n (hasProperty(error, 'code') &&\n (error.code === 'ETIMEDOUT' || error.code === 'ECONNRESET'))\n );\n }),\n });\n }\n\n /**\n * Resets the underlying composite Cockatiel policy.\n *\n * This is useful in a collection of RpcServices where some act as failovers\n * for others where you effectively want to invalidate the failovers when the\n * primary recovers.\n */\n resetPolicy() {\n this.#policy.reset();\n }\n\n /**\n * @returns The state of the underlying circuit.\n */\n getCircuitState() {\n return this.#policy.getCircuitState();\n }\n\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(listener: Parameters<AbstractRpcService['onRetry']>[0]) {\n return this.#policy.onRetry((data) => {\n listener({ ...data, endpointUrl: this.endpointUrl.toString() });\n });\n }\n\n /**\n * Listens for when the RPC service retries the request too many times in a\n * row, causing the underlying circuit to break.\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(listener: Parameters<AbstractRpcService['onBreak']>[0]) {\n return this.#policy.onBreak((data) => {\n // `{ isolated: true }` is a special object that shows up when `isolate`\n // is called on the circuit breaker. Usually `isolate` is used to hold the\n // circuit open, but we (ab)use this method in `createServicePolicy` to\n // reset the circuit breaker policy. When we do this, we don't want to\n // call `onBreak` handlers, because then it causes\n // `NetworkController:rpcEndpointUnavailable` and\n // `NetworkController:rpcEndpointChainUnavailable` to be published. So we\n // have to ignore that object here. The consequence is that `isolate`\n // doesn't function the way it is intended, at least in the context of an\n // RpcService. However, we are making a bet that we won't need to use it\n // other than how we are already using it.\n if (!('isolated' in data)) {\n listener({ ...data, endpointUrl: this.endpointUrl.toString() });\n }\n });\n }\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(listener: Parameters<AbstractRpcService['onDegraded']>[0]) {\n return this.#policy.onDegraded((data) => {\n listener({ ...(data ?? {}), endpointUrl: this.endpointUrl.toString() });\n });\n }\n\n /**\n * Listens for when the policy underlying this RPC service is available.\n *\n * @param listener - The callback to be called when the request is available.\n * @returns What {@link ServicePolicy.onAvailable} returns.\n * @see {@link createServicePolicy}\n */\n onAvailable(listener: Parameters<AbstractRpcService['onAvailable']>[0]) {\n return this.#policy.onAvailable(() => {\n listener({ endpointUrl: this.endpointUrl.toString() });\n });\n }\n\n /**\n * Makes a request to the RPC endpoint.\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 An \"authorized\" JSON-RPC error (code -32006) if the response HTTP status is 401.\n * @throws A \"rate limiting\" JSON-RPC error (code -32005) if the response HTTP status is 429.\n * @throws A \"resource unavailable\" JSON-RPC error (code -32002) if the response HTTP status is 402, 404, or any 5xx.\n * @throws A generic HTTP client JSON-RPC error (code -32050) for any other 4xx HTTP status codes.\n * @throws A \"parse\" JSON-RPC error (code -32700) if the response is not valid JSON.\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 RPC endpoint.\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 An \"authorized\" JSON-RPC error (code -32006) if the response HTTP status is 401.\n * @throws A \"rate limiting\" JSON-RPC error (code -32005) if the response HTTP status is 429.\n * @throws A \"resource unavailable\" JSON-RPC error (code -32002) if the response HTTP status is 402, 404, or any 5xx.\n * @throws A generic HTTP client JSON-RPC error (code -32050) for any other 4xx HTTP status codes.\n * @throws A \"parse\" JSON-RPC error (code -32700) if the response is not valid JSON.\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 // The request object may be frozen and must not be mutated.\n jsonRpcRequest: Readonly<JsonRpcRequest<Params>>,\n fetchOptions: FetchOptions = {},\n ): Promise<JsonRpcResponse<Result | null>> {\n const completeFetchOptions = this.#getCompleteFetchOptions(\n jsonRpcRequest,\n fetchOptions,\n );\n return await this.#executeAndProcessRequest<Result>(completeFetchOptions);\n }\n\n /**\n * Constructs a default set of options to `fetch`.\n *\n * If a username and password are present in the URL, they are extracted to an\n * Authorization header.\n *\n * @param endpointUrl - The endpoint URL.\n * @param fetchOptions - The options to `fetch`.\n * @param givenBtoa - An implementation of `btoa`.\n * @returns The default fetch options.\n */\n #getDefaultFetchOptions(\n endpointUrl: URL,\n fetchOptions: FetchOptions,\n givenBtoa: (stringToEncode: string) => string,\n ): FetchOptions {\n if (endpointUrl.username && endpointUrl.password) {\n const authString = `${endpointUrl.username}:${endpointUrl.password}`;\n const encodedCredentials = givenBtoa(authString);\n return deepmerge(fetchOptions, {\n headers: { Authorization: `Basic ${encodedCredentials}` },\n });\n }\n\n return fetchOptions;\n }\n\n /**\n * Constructs a final set of options to pass to `fetch`. Note that the method\n * defaults to `post`, and the JSON-RPC request is automatically JSON-encoded.\n *\n * @param jsonRpcRequest - The JSON-RPC request.\n * @param fetchOptions - Custom `fetch` options.\n * @returns The complete set of `fetch` options.\n */\n #getCompleteFetchOptions<Params extends JsonRpcParams>(\n jsonRpcRequest: Readonly<JsonRpcRequest<Params>>,\n fetchOptions: FetchOptions,\n ): FetchOptions {\n const defaultOptions = {\n method: 'POST',\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n },\n };\n const mergedOptions = deepmerge(\n defaultOptions,\n deepmerge(this.#fetchOptions, fetchOptions),\n );\n\n const { id, jsonrpc, method, params } = jsonRpcRequest;\n const body = JSON.stringify({\n id,\n jsonrpc,\n method,\n params,\n });\n\n return { ...mergedOptions, body };\n }\n\n /**\n * Makes the request using the Cockatiel policy that this service creates.\n *\n * @param fetchOptions - The options for `fetch`; will be combined with the\n * fetch options passed to the constructor\n * @returns The decoded JSON-RPC response from the endpoint.\n * @throws An \"authorized\" JSON-RPC error (code -32006) if the response HTTP status is 401.\n * @throws A \"rate limiting\" JSON-RPC error (code -32005) if the response HTTP status is 429.\n * @throws A \"resource unavailable\" JSON-RPC error (code -32002) if the response HTTP status is 402, 404, or any 5xx.\n * @throws A generic HTTP client JSON-RPC error (code -32050) for any other 4xx HTTP status codes.\n * @throws A \"parse\" JSON-RPC error (code -32700) if the response is not valid JSON.\n */\n async #executeAndProcessRequest<Result extends Json>(\n fetchOptions: FetchOptions,\n ): Promise<JsonRpcResponse<Result> | JsonRpcResponse<null>> {\n let response: Response | undefined;\n try {\n log(\n `[${this.endpointUrl}] Circuit state`,\n this.#policy.getCircuitState(),\n );\n const jsonDecodedResponse = await this.#policy.execute(\n async (context) => {\n log(\n 'REQUEST INITIATED:',\n this.endpointUrl.toString(),\n '::',\n fetchOptions,\n // @ts-expect-error This property _is_ here, the type of\n // ServicePolicy is just wrong.\n `(attempt ${context.attempt + 1})`,\n );\n response = await this.#fetch(this.endpointUrl, fetchOptions);\n if (!response.ok) {\n throw new HttpError(response.status);\n }\n log(\n 'REQUEST SUCCESSFUL:',\n this.endpointUrl.toString(),\n response.status,\n );\n return await response.json();\n },\n );\n this.lastError = undefined;\n return jsonDecodedResponse;\n } catch (error) {\n log('REQUEST ERROR:', this.endpointUrl.toString(), error);\n\n this.lastError =\n error instanceof Error ? error : new Error(getErrorMessage(error));\n\n if (error instanceof HttpError) {\n const status = error.httpStatus;\n if (status === 401) {\n throw new JsonRpcError(\n CUSTOM_RPC_ERRORS.unauthorized,\n 'Unauthorized.',\n {\n httpStatus: status,\n },\n );\n }\n if (status === 429) {\n throw rpcErrors.limitExceeded({\n message: 'Request is being rate limited.',\n data: {\n httpStatus: status,\n },\n });\n }\n if (status >= 500 || status === 402 || status === 404) {\n throw rpcErrors.resourceUnavailable({\n message: 'RPC endpoint not found or unavailable.',\n data: {\n httpStatus: status,\n },\n });\n }\n\n // Handle all other 4xx errors as generic HTTP client errors\n throw new JsonRpcError(\n CUSTOM_RPC_ERRORS.httpClientError,\n 'RPC endpoint returned HTTP client error.',\n {\n httpStatus: status,\n },\n );\n } else if (isJsonParseError(error)) {\n throw rpcErrors.parse({\n message: 'RPC endpoint did not return JSON.',\n });\n } else if (error instanceof BrokenCircuitError) {\n this.#logger?.warn(error);\n const remainingCircuitOpenDuration =\n this.#policy.getRemainingCircuitOpenDuration();\n const formattedRemainingCircuitOpenDuration = Intl.NumberFormat(\n undefined,\n { maximumFractionDigits: 2 },\n ).format(\n (remainingCircuitOpenDuration ?? this.#policy.circuitBreakDuration) /\n Duration.Minute,\n );\n throw rpcErrors.resourceUnavailable({\n message: `RPC endpoint returned too many errors, retrying in ${formattedRemainingCircuitOpenDuration} minutes. Consider using a different RPC endpoint.`,\n });\n }\n throw error;\n }\n }\n}\n"]}
1
+ {"version":3,"file":"rpc-service.cjs","sourceRoot":"","sources":["../../src/rpc-service/rpc-service.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n CreateServicePolicyOptions,\n ServicePolicy,\n} from '@metamask/controller-utils';\nimport {\n BrokenCircuitError,\n HttpError,\n createServicePolicy,\n handleWhen,\n} from '@metamask/controller-utils';\nimport { JsonRpcError, rpcErrors } from '@metamask/rpc-errors';\nimport { Duration, getErrorMessage, hasProperty } from '@metamask/utils';\nimport type {\n Json,\n JsonRpcParams,\n JsonRpcRequest,\n JsonRpcResponse,\n} from '@metamask/utils';\nimport { CircuitState, IDisposable } from 'cockatiel';\nimport deepmerge from 'deepmerge';\nimport type { Logger } from 'loglevel';\n\nimport type { AbstractRpcService } from './abstract-rpc-service';\nimport type { FetchOptions } from './shared';\nimport { projectLogger, createModuleLogger } from '../logger';\n\n/**\n * Options for the RpcService constructor.\n */\nexport type RpcServiceOptions = {\n /**\n * A function that can be used to convert a binary string into a\n * base64-encoded ASCII string. Used to encode authorization credentials.\n */\n btoa: typeof btoa;\n /**\n * The URL of the RPC endpoint to hit.\n */\n endpointUrl: URL | string;\n /**\n * A function that can be used to make an HTTP request. If your JavaScript\n * environment supports `fetch` natively, you'll probably want to pass that;\n * otherwise you can pass an equivalent (such as `fetch` via `node-fetch`).\n */\n fetch: typeof fetch;\n /**\n * A common set of options that will be used to make every request. Can be\n * overridden on the request level (e.g. to add headers).\n */\n fetchOptions?: FetchOptions;\n /**\n * A `loglevel` logger.\n */\n logger?: Pick<Logger, 'warn'>;\n /**\n * Options to pass to `createServicePolicy`. Note that `retryFilterPolicy` is\n * not accepted, as it is overwritten. See {@link createServicePolicy}.\n */\n policyOptions?: Omit<CreateServicePolicyOptions, 'retryFilterPolicy'>;\n};\n\nconst log = createModuleLogger(projectLogger, 'RpcService');\n\n/**\n * The maximum number of times that a failing service should be re-run before\n * giving up.\n */\nexport const DEFAULT_MAX_RETRIES = 4;\n\n/**\n * The maximum number of times that the service is allowed to fail before\n * pausing further retries. This is set to a value such that if given a\n * service that continually fails, the policy needs to be executed 3 times\n * before further retries are paused.\n */\nexport const DEFAULT_MAX_CONSECUTIVE_FAILURES = (1 + DEFAULT_MAX_RETRIES) * 3;\n\n/**\n * The list of error messages that represent a failure to connect to the network.\n *\n * This list was derived from Sindre Sorhus's `is-network-error` package:\n * <https://github.com/sindresorhus/is-network-error/blob/7bbfa8be9482ce1427a21fbff60e3ee1650dd091/index.js>\n */\nexport const CONNECTION_ERRORS = [\n // Chrome\n {\n constructorName: 'TypeError',\n pattern: /network error/u,\n },\n // Chrome\n {\n constructorName: 'TypeError',\n pattern: /Failed to fetch/u,\n },\n // Firefox\n {\n constructorName: 'TypeError',\n pattern: /NetworkError when attempting to fetch resource\\./u,\n },\n // Safari 16\n {\n constructorName: 'TypeError',\n pattern: /The Internet connection appears to be offline\\./u,\n },\n // Safari 17+\n {\n constructorName: 'TypeError',\n pattern: /Load failed/u,\n },\n // `cross-fetch`\n {\n constructorName: 'TypeError',\n pattern: /Network request failed/u,\n },\n // `node-fetch`\n {\n constructorName: 'FetchError',\n pattern: /request to (.+) failed/u,\n },\n // Undici (Node.js)\n {\n constructorName: 'TypeError',\n pattern: /fetch failed/u,\n },\n // Undici (Node.js)\n {\n constructorName: 'TypeError',\n pattern: /terminated/u,\n },\n];\n\n/**\n * Custom JSON-RPC error codes for specific cases.\n *\n * These should be moved to `@metamask/rpc-errors` eventually.\n */\nexport const CUSTOM_RPC_ERRORS = {\n unauthorized: -32006,\n httpClientError: -32080,\n} as const;\n\n/**\n * Determines whether the given error represents a failure to reach the network\n * after request parameters have been validated.\n *\n * This is somewhat difficult to verify because JavaScript engines (and in\n * some cases libraries) produce slightly different error messages for this\n * particular scenario, and we need to account for this.\n *\n * @param error - The error.\n * @returns True if the error indicates that the network cannot be connected to,\n * and false otherwise.\n */\nexport function isConnectionError(error: unknown): boolean {\n if (!(typeof error === 'object' && error !== null && 'message' in error)) {\n return false;\n }\n\n const { message } = error;\n\n return (\n typeof message === 'string' &&\n !isNockError(message) &&\n CONNECTION_ERRORS.some(({ constructorName, pattern }) => {\n return (\n error.constructor.name === constructorName && pattern.test(message)\n );\n })\n );\n}\n\n/**\n * Determines whether the given error message refers to a Nock error.\n *\n * It's important that if we failed to mock a request in a test, the resulting\n * error does not cause the request to be retried so that we can see it right\n * away.\n *\n * @param message - The error message to test.\n * @returns True if the message indicates a missing Nock mock, false otherwise.\n */\nfunction isNockError(message: string): boolean {\n return message.includes('Nock:');\n}\n\n/**\n * Determine whether the given error message indicates a failure to parse JSON.\n *\n * This is different in tests vs. implementation code because it may manifest as\n * a FetchError or a SyntaxError.\n *\n * @param error - The error object to test.\n * @returns True if the error indicates a JSON parse error, false otherwise.\n */\nfunction isJsonParseError(error: unknown): boolean {\n return (\n error instanceof SyntaxError ||\n /invalid json/iu.test(getErrorMessage(error))\n );\n}\n\n/**\n * Guarantees a URL, even given a string. This is useful for checking components\n * of that URL.\n *\n * @param endpointUrlOrUrlString - Either a URL object or a string that\n * represents the URL of an endpoint.\n * @returns A URL object.\n */\nfunction getNormalizedEndpointUrl(endpointUrlOrUrlString: URL | string): URL {\n return endpointUrlOrUrlString instanceof URL\n ? endpointUrlOrUrlString\n : new URL(endpointUrlOrUrlString);\n}\n\n/**\n * Strips username and password from a URL.\n *\n * @param url - The URL to strip credentials from.\n * @returns A new URL object with credentials removed.\n */\nfunction stripCredentialsFromUrl(url: URL): URL {\n const strippedUrl = new URL(url.toString());\n strippedUrl.username = '';\n strippedUrl.password = '';\n return strippedUrl;\n}\n\n/**\n * This class is responsible for making a request to an endpoint that implements\n * the JSON-RPC protocol. It is designed to gracefully handle network and server\n * failures, retrying requests using exponential backoff. It also offers a hook\n * which can used to respond to slow requests.\n */\nexport class RpcService implements AbstractRpcService {\n /**\n * The URL of the RPC endpoint.\n */\n readonly endpointUrl: URL;\n\n /**\n * The last error that the retry policy captured (or `undefined` if the last\n * execution of the service was successful).\n */\n lastError: Error | undefined;\n\n /**\n * The function used to make an HTTP request.\n */\n readonly #fetch: typeof fetch;\n\n /**\n * A common set of options that the request options will extend.\n */\n readonly #fetchOptions: FetchOptions;\n\n /**\n * A `loglevel` logger.\n */\n readonly #logger: RpcServiceOptions['logger'];\n\n /**\n * The policy that wraps the request.\n */\n readonly #policy: ServicePolicy;\n\n /**\n * Constructs a new RpcService object.\n *\n * @param options - The options. See {@link RpcServiceOptions}.\n */\n constructor(options: RpcServiceOptions) {\n const {\n btoa: givenBtoa,\n endpointUrl,\n fetch: givenFetch,\n logger,\n fetchOptions = {},\n policyOptions = {},\n } = options;\n\n this.#fetch = givenFetch;\n const normalizedUrl = getNormalizedEndpointUrl(endpointUrl);\n this.#fetchOptions = this.#getDefaultFetchOptions(\n normalizedUrl,\n fetchOptions,\n givenBtoa,\n );\n this.endpointUrl = stripCredentialsFromUrl(normalizedUrl);\n this.#logger = logger;\n\n this.#policy = createServicePolicy({\n maxRetries: DEFAULT_MAX_RETRIES,\n maxConsecutiveFailures: DEFAULT_MAX_CONSECUTIVE_FAILURES,\n ...policyOptions,\n retryFilterPolicy: handleWhen((error) => {\n return (\n // Ignore errors where the request failed to establish\n isConnectionError(error) ||\n // Ignore server sent HTML error pages or truncated JSON responses\n isJsonParseError(error) ||\n // Ignore server overload errors\n ('httpStatus' in error &&\n (error.httpStatus === 502 ||\n error.httpStatus === 503 ||\n error.httpStatus === 504)) ||\n (hasProperty(error, 'code') &&\n (error.code === 'ETIMEDOUT' || error.code === 'ECONNRESET'))\n );\n }),\n });\n }\n\n /**\n * Resets the underlying composite Cockatiel policy.\n *\n * This is useful in a collection of RpcServices where some act as failovers\n * for others where you effectively want to invalidate the failovers when the\n * primary recovers.\n */\n resetPolicy(): void {\n this.#policy.reset();\n }\n\n /**\n * @returns The state of the underlying circuit.\n */\n getCircuitState(): CircuitState {\n return this.#policy.getCircuitState();\n }\n\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(listener: Parameters<AbstractRpcService['onRetry']>[0]): IDisposable {\n return this.#policy.onRetry((data) => {\n listener({ ...data, endpointUrl: this.endpointUrl.toString() });\n });\n }\n\n /**\n * Listens for when the RPC service retries the request too many times in a\n * row, causing the underlying circuit to break.\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(listener: Parameters<AbstractRpcService['onBreak']>[0]): IDisposable {\n return this.#policy.onBreak((data) => {\n // `{ isolated: true }` is a special object that shows up when `isolate`\n // is called on the circuit breaker. Usually `isolate` is used to hold the\n // circuit open, but we (ab)use this method in `createServicePolicy` to\n // reset the circuit breaker policy. When we do this, we don't want to\n // call `onBreak` handlers, because then it causes\n // `NetworkController:rpcEndpointUnavailable` and\n // `NetworkController:rpcEndpointChainUnavailable` to be published. So we\n // have to ignore that object here. The consequence is that `isolate`\n // doesn't function the way it is intended, at least in the context of an\n // RpcService. However, we are making a bet that we won't need to use it\n // other than how we are already using it.\n if (!('isolated' in data)) {\n listener({ ...data, endpointUrl: this.endpointUrl.toString() });\n }\n });\n }\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: Parameters<AbstractRpcService['onDegraded']>[0],\n ): IDisposable {\n return this.#policy.onDegraded((data) => {\n listener({ ...(data ?? {}), endpointUrl: this.endpointUrl.toString() });\n });\n }\n\n /**\n * Listens for when the policy underlying this RPC service is available.\n *\n * @param listener - The callback to be called when the request is available.\n * @returns What {@link ServicePolicy.onAvailable} returns.\n * @see {@link createServicePolicy}\n */\n onAvailable(\n listener: Parameters<AbstractRpcService['onAvailable']>[0],\n ): IDisposable {\n return this.#policy.onAvailable(() => {\n listener({ endpointUrl: this.endpointUrl.toString() });\n });\n }\n\n /**\n * Makes a request to the RPC endpoint.\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 An \"authorized\" JSON-RPC error (code -32006) if the response HTTP status is 401.\n * @throws A \"rate limiting\" JSON-RPC error (code -32005) if the response HTTP status is 429.\n * @throws A \"resource unavailable\" JSON-RPC error (code -32002) if the response HTTP status is 402, 404, or any 5xx.\n * @throws A generic HTTP client JSON-RPC error (code -32050) for any other 4xx HTTP status codes.\n * @throws A \"parse\" JSON-RPC error (code -32700) if the response is not valid JSON.\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 RPC endpoint.\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 An \"authorized\" JSON-RPC error (code -32006) if the response HTTP status is 401.\n * @throws A \"rate limiting\" JSON-RPC error (code -32005) if the response HTTP status is 429.\n * @throws A \"resource unavailable\" JSON-RPC error (code -32002) if the response HTTP status is 402, 404, or any 5xx.\n * @throws A generic HTTP client JSON-RPC error (code -32050) for any other 4xx HTTP status codes.\n * @throws A \"parse\" JSON-RPC error (code -32700) if the response is not valid JSON.\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 // The request object may be frozen and must not be mutated.\n jsonRpcRequest: Readonly<JsonRpcRequest<Params>>,\n fetchOptions: FetchOptions = {},\n ): Promise<JsonRpcResponse<Result | null>> {\n const completeFetchOptions = this.#getCompleteFetchOptions(\n jsonRpcRequest,\n fetchOptions,\n );\n return await this.#executeAndProcessRequest<Result>(completeFetchOptions);\n }\n\n /**\n * Constructs a default set of options to `fetch`.\n *\n * If a username and password are present in the URL, they are extracted to an\n * Authorization header.\n *\n * @param endpointUrl - The endpoint URL.\n * @param fetchOptions - The options to `fetch`.\n * @param givenBtoa - An implementation of `btoa`.\n * @returns The default fetch options.\n */\n #getDefaultFetchOptions(\n endpointUrl: URL,\n fetchOptions: FetchOptions,\n givenBtoa: (stringToEncode: string) => string,\n ): FetchOptions {\n if (endpointUrl.username && endpointUrl.password) {\n const authString = `${endpointUrl.username}:${endpointUrl.password}`;\n const encodedCredentials = givenBtoa(authString);\n return deepmerge(fetchOptions, {\n headers: { Authorization: `Basic ${encodedCredentials}` },\n });\n }\n\n return fetchOptions;\n }\n\n /**\n * Constructs a final set of options to pass to `fetch`. Note that the method\n * defaults to `post`, and the JSON-RPC request is automatically JSON-encoded.\n *\n * @param jsonRpcRequest - The JSON-RPC request.\n * @param fetchOptions - Custom `fetch` options.\n * @returns The complete set of `fetch` options.\n */\n #getCompleteFetchOptions<Params extends JsonRpcParams>(\n jsonRpcRequest: Readonly<JsonRpcRequest<Params>>,\n fetchOptions: FetchOptions,\n ): FetchOptions {\n const defaultOptions = {\n method: 'POST',\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n },\n };\n const mergedOptions = deepmerge(\n defaultOptions,\n deepmerge(this.#fetchOptions, fetchOptions),\n );\n\n const { id, jsonrpc, method, params } = jsonRpcRequest;\n const body = JSON.stringify({\n id,\n jsonrpc,\n method,\n params,\n });\n\n return { ...mergedOptions, body };\n }\n\n /**\n * Makes the request using the Cockatiel policy that this service creates.\n *\n * @param fetchOptions - The options for `fetch`; will be combined with the\n * fetch options passed to the constructor\n * @returns The decoded JSON-RPC response from the endpoint.\n * @throws An \"authorized\" JSON-RPC error (code -32006) if the response HTTP status is 401.\n * @throws A \"rate limiting\" JSON-RPC error (code -32005) if the response HTTP status is 429.\n * @throws A \"resource unavailable\" JSON-RPC error (code -32002) if the response HTTP status is 402, 404, or any 5xx.\n * @throws A generic HTTP client JSON-RPC error (code -32050) for any other 4xx HTTP status codes.\n * @throws A \"parse\" JSON-RPC error (code -32700) if the response is not valid JSON.\n */\n async #executeAndProcessRequest<Result extends Json>(\n fetchOptions: FetchOptions,\n ): Promise<JsonRpcResponse<Result> | JsonRpcResponse<null>> {\n let response: Response | undefined;\n try {\n log(\n `[${this.endpointUrl}] Circuit state`,\n this.#policy.getCircuitState(),\n );\n const jsonDecodedResponse = await this.#policy.execute(\n async (context) => {\n log(\n 'REQUEST INITIATED:',\n this.endpointUrl.toString(),\n '::',\n fetchOptions,\n // @ts-expect-error This property _is_ here, the type of\n // ServicePolicy is just wrong.\n `(attempt ${context.attempt + 1})`,\n );\n response = await this.#fetch(this.endpointUrl, fetchOptions);\n if (!response.ok) {\n throw new HttpError(response.status);\n }\n log(\n 'REQUEST SUCCESSFUL:',\n this.endpointUrl.toString(),\n response.status,\n );\n return await response.json();\n },\n );\n this.lastError = undefined;\n return jsonDecodedResponse;\n } catch (error) {\n log('REQUEST ERROR:', this.endpointUrl.toString(), error);\n\n this.lastError =\n error instanceof Error ? error : new Error(getErrorMessage(error));\n\n if (error instanceof HttpError) {\n const status = error.httpStatus;\n if (status === 401) {\n throw new JsonRpcError(\n CUSTOM_RPC_ERRORS.unauthorized,\n 'Unauthorized.',\n {\n httpStatus: status,\n },\n );\n }\n if (status === 429) {\n throw rpcErrors.limitExceeded({\n message: 'Request is being rate limited.',\n data: {\n httpStatus: status,\n },\n });\n }\n if (status >= 500 || status === 402 || status === 404) {\n throw rpcErrors.resourceUnavailable({\n message: 'RPC endpoint not found or unavailable.',\n data: {\n httpStatus: status,\n },\n });\n }\n\n // Handle all other 4xx errors as generic HTTP client errors\n throw new JsonRpcError(\n CUSTOM_RPC_ERRORS.httpClientError,\n 'RPC endpoint returned HTTP client error.',\n {\n httpStatus: status,\n },\n );\n } else if (isJsonParseError(error)) {\n throw rpcErrors.parse({\n message: 'RPC endpoint did not return JSON.',\n });\n } else if (error instanceof BrokenCircuitError) {\n this.#logger?.warn(error);\n const remainingCircuitOpenDuration =\n this.#policy.getRemainingCircuitOpenDuration();\n const formattedRemainingCircuitOpenDuration = Intl.NumberFormat(\n undefined,\n { maximumFractionDigits: 2 },\n ).format(\n (remainingCircuitOpenDuration ?? this.#policy.circuitBreakDuration) /\n Duration.Minute,\n );\n throw rpcErrors.resourceUnavailable({\n message: `RPC endpoint returned too many errors, retrying in ${formattedRemainingCircuitOpenDuration} minutes. Consider using a different RPC endpoint.`,\n });\n }\n throw error;\n }\n }\n}\n"]}
@@ -1,5 +1,6 @@
1
1
  import type { CreateServicePolicyOptions } from "@metamask/controller-utils";
2
2
  import type { Json, JsonRpcParams, JsonRpcRequest, JsonRpcResponse } from "@metamask/utils";
3
+ import { CircuitState, IDisposable } from "cockatiel";
3
4
  import type { Logger } from "loglevel";
4
5
  import type { AbstractRpcService } from "./abstract-rpc-service.cjs";
5
6
  import type { FetchOptions } from "./shared.cjs";
@@ -115,7 +116,7 @@ export declare class RpcService implements AbstractRpcService {
115
116
  /**
116
117
  * @returns The state of the underlying circuit.
117
118
  */
118
- getCircuitState(): import("@metamask/controller-utils").CircuitState;
119
+ getCircuitState(): CircuitState;
119
120
  /**
120
121
  * Listens for when the RPC service retries the request.
121
122
  *
@@ -123,7 +124,7 @@ export declare class RpcService implements AbstractRpcService {
123
124
  * @returns What {@link ServicePolicy.onRetry} returns.
124
125
  * @see {@link createServicePolicy}
125
126
  */
126
- onRetry(listener: Parameters<AbstractRpcService['onRetry']>[0]): import("cockatiel").IDisposable;
127
+ onRetry(listener: Parameters<AbstractRpcService['onRetry']>[0]): IDisposable;
127
128
  /**
128
129
  * Listens for when the RPC service retries the request too many times in a
129
130
  * row, causing the underlying circuit to break.
@@ -132,7 +133,7 @@ export declare class RpcService implements AbstractRpcService {
132
133
  * @returns What {@link ServicePolicy.onBreak} returns.
133
134
  * @see {@link createServicePolicy}
134
135
  */
135
- onBreak(listener: Parameters<AbstractRpcService['onBreak']>[0]): import("cockatiel").IDisposable;
136
+ onBreak(listener: Parameters<AbstractRpcService['onBreak']>[0]): IDisposable;
136
137
  /**
137
138
  * Listens for when the policy underlying this RPC service detects a slow
138
139
  * request.
@@ -141,7 +142,7 @@ export declare class RpcService implements AbstractRpcService {
141
142
  * @returns What {@link ServicePolicy.onDegraded} returns.
142
143
  * @see {@link createServicePolicy}
143
144
  */
144
- onDegraded(listener: Parameters<AbstractRpcService['onDegraded']>[0]): import("cockatiel").IDisposable;
145
+ onDegraded(listener: Parameters<AbstractRpcService['onDegraded']>[0]): IDisposable;
145
146
  /**
146
147
  * Listens for when the policy underlying this RPC service is available.
147
148
  *
@@ -149,7 +150,7 @@ export declare class RpcService implements AbstractRpcService {
149
150
  * @returns What {@link ServicePolicy.onAvailable} returns.
150
151
  * @see {@link createServicePolicy}
151
152
  */
152
- onAvailable(listener: Parameters<AbstractRpcService['onAvailable']>[0]): import("cockatiel").IDisposable;
153
+ onAvailable(listener: Parameters<AbstractRpcService['onAvailable']>[0]): IDisposable;
153
154
  /**
154
155
  * Makes a request to the RPC endpoint.
155
156
  *
@@ -1 +1 @@
1
- {"version":3,"file":"rpc-service.d.cts","sourceRoot":"","sources":["../../src/rpc-service/rpc-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,0BAA0B,EAE3B,mCAAmC;AASpC,OAAO,KAAK,EACV,IAAI,EACJ,aAAa,EACb,cAAc,EACd,eAAe,EAChB,wBAAwB;AAEzB,OAAO,KAAK,EAAE,MAAM,EAAE,iBAAiB;AAEvC,OAAO,KAAK,EAAE,kBAAkB,EAAE,mCAA+B;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,qBAAiB;AAG7C;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B;;;OAGG;IACH,IAAI,EAAE,OAAO,IAAI,CAAC;IAClB;;OAEG;IACH,WAAW,EAAE,GAAG,GAAG,MAAM,CAAC;IAC1B;;;;OAIG;IACH,KAAK,EAAE,OAAO,KAAK,CAAC;IACpB;;;OAGG;IACH,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B;;OAEG;IACH,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B;;;OAGG;IACH,aAAa,CAAC,EAAE,IAAI,CAAC,0BAA0B,EAAE,mBAAmB,CAAC,CAAC;CACvE,CAAC;AAIF;;;GAGG;AACH,eAAO,MAAM,mBAAmB,IAAI,CAAC;AAErC;;;;;GAKG;AACH,eAAO,MAAM,gCAAgC,QAAgC,CAAC;AAE9E;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB;;;GA8C7B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,iBAAiB;;;CAGpB,CAAC;AAEX;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,WAgB/C;AA2DD;;;;;GAKG;AACH,qBAAa,UAAW,YAAW,kBAAkB;;IACnD;;OAEG;IACH,QAAQ,CAAC,WAAW,EAAE,GAAG,CAAC;IAE1B;;;OAGG;IACH,SAAS,EAAE,KAAK,GAAG,SAAS,CAAC;IAsB7B;;;;OAIG;gBACS,OAAO,EAAE,iBAAiB;IA0CtC;;;;;;OAMG;IACH,WAAW;IAIX;;OAEG;IACH,eAAe;IAIf;;;;;;OAMG;IACH,OAAO,CAAC,QAAQ,EAAE,UAAU,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IAM9D;;;;;;;OAOG;IACH,OAAO,CAAC,QAAQ,EAAE,UAAU,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IAmB9D;;;;;;;OAOG;IACH,UAAU,CAAC,QAAQ,EAAE,UAAU,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;IAMpE;;;;;;OAMG;IACH,WAAW,CAAC,QAAQ,EAAE,UAAU,CAAC,kBAAkB,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;IAMtE;;;;;;;;;;;;;;;;OAgBG;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;;;;;;;;;;;;;;;;OAgBG;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;CA0LpC"}
1
+ {"version":3,"file":"rpc-service.d.cts","sourceRoot":"","sources":["../../src/rpc-service/rpc-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,0BAA0B,EAE3B,mCAAmC;AASpC,OAAO,KAAK,EACV,IAAI,EACJ,aAAa,EACb,cAAc,EACd,eAAe,EAChB,wBAAwB;AACzB,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,kBAAkB;AAEtD,OAAO,KAAK,EAAE,MAAM,EAAE,iBAAiB;AAEvC,OAAO,KAAK,EAAE,kBAAkB,EAAE,mCAA+B;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,qBAAiB;AAG7C;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B;;;OAGG;IACH,IAAI,EAAE,OAAO,IAAI,CAAC;IAClB;;OAEG;IACH,WAAW,EAAE,GAAG,GAAG,MAAM,CAAC;IAC1B;;;;OAIG;IACH,KAAK,EAAE,OAAO,KAAK,CAAC;IACpB;;;OAGG;IACH,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B;;OAEG;IACH,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B;;;OAGG;IACH,aAAa,CAAC,EAAE,IAAI,CAAC,0BAA0B,EAAE,mBAAmB,CAAC,CAAC;CACvE,CAAC;AAIF;;;GAGG;AACH,eAAO,MAAM,mBAAmB,IAAI,CAAC;AAErC;;;;;GAKG;AACH,eAAO,MAAM,gCAAgC,QAAgC,CAAC;AAE9E;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB;;;GA8C7B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,iBAAiB;;;CAGpB,CAAC;AAEX;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAgBzD;AA2DD;;;;;GAKG;AACH,qBAAa,UAAW,YAAW,kBAAkB;;IACnD;;OAEG;IACH,QAAQ,CAAC,WAAW,EAAE,GAAG,CAAC;IAE1B;;;OAGG;IACH,SAAS,EAAE,KAAK,GAAG,SAAS,CAAC;IAsB7B;;;;OAIG;gBACS,OAAO,EAAE,iBAAiB;IA0CtC;;;;;;OAMG;IACH,WAAW,IAAI,IAAI;IAInB;;OAEG;IACH,eAAe,IAAI,YAAY;IAI/B;;;;;;OAMG;IACH,OAAO,CAAC,QAAQ,EAAE,UAAU,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,WAAW;IAM5E;;;;;;;OAOG;IACH,OAAO,CAAC,QAAQ,EAAE,UAAU,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,WAAW;IAmB5E;;;;;;;OAOG;IACH,UAAU,CACR,QAAQ,EAAE,UAAU,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,GACxD,WAAW;IAMd;;;;;;OAMG;IACH,WAAW,CACT,QAAQ,EAAE,UAAU,CAAC,kBAAkB,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,GACzD,WAAW;IAMd;;;;;;;;;;;;;;;;OAgBG;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;;;;;;;;;;;;;;;;OAgBG;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;CA0LpC"}
@@ -1,5 +1,6 @@
1
1
  import type { CreateServicePolicyOptions } from "@metamask/controller-utils";
2
2
  import type { Json, JsonRpcParams, JsonRpcRequest, JsonRpcResponse } from "@metamask/utils";
3
+ import { CircuitState, IDisposable } from "cockatiel";
3
4
  import type { Logger } from "loglevel";
4
5
  import type { AbstractRpcService } from "./abstract-rpc-service.mjs";
5
6
  import type { FetchOptions } from "./shared.mjs";
@@ -115,7 +116,7 @@ export declare class RpcService implements AbstractRpcService {
115
116
  /**
116
117
  * @returns The state of the underlying circuit.
117
118
  */
118
- getCircuitState(): import("@metamask/controller-utils").CircuitState;
119
+ getCircuitState(): CircuitState;
119
120
  /**
120
121
  * Listens for when the RPC service retries the request.
121
122
  *
@@ -123,7 +124,7 @@ export declare class RpcService implements AbstractRpcService {
123
124
  * @returns What {@link ServicePolicy.onRetry} returns.
124
125
  * @see {@link createServicePolicy}
125
126
  */
126
- onRetry(listener: Parameters<AbstractRpcService['onRetry']>[0]): import("cockatiel").IDisposable;
127
+ onRetry(listener: Parameters<AbstractRpcService['onRetry']>[0]): IDisposable;
127
128
  /**
128
129
  * Listens for when the RPC service retries the request too many times in a
129
130
  * row, causing the underlying circuit to break.
@@ -132,7 +133,7 @@ export declare class RpcService implements AbstractRpcService {
132
133
  * @returns What {@link ServicePolicy.onBreak} returns.
133
134
  * @see {@link createServicePolicy}
134
135
  */
135
- onBreak(listener: Parameters<AbstractRpcService['onBreak']>[0]): import("cockatiel").IDisposable;
136
+ onBreak(listener: Parameters<AbstractRpcService['onBreak']>[0]): IDisposable;
136
137
  /**
137
138
  * Listens for when the policy underlying this RPC service detects a slow
138
139
  * request.
@@ -141,7 +142,7 @@ export declare class RpcService implements AbstractRpcService {
141
142
  * @returns What {@link ServicePolicy.onDegraded} returns.
142
143
  * @see {@link createServicePolicy}
143
144
  */
144
- onDegraded(listener: Parameters<AbstractRpcService['onDegraded']>[0]): import("cockatiel").IDisposable;
145
+ onDegraded(listener: Parameters<AbstractRpcService['onDegraded']>[0]): IDisposable;
145
146
  /**
146
147
  * Listens for when the policy underlying this RPC service is available.
147
148
  *
@@ -149,7 +150,7 @@ export declare class RpcService implements AbstractRpcService {
149
150
  * @returns What {@link ServicePolicy.onAvailable} returns.
150
151
  * @see {@link createServicePolicy}
151
152
  */
152
- onAvailable(listener: Parameters<AbstractRpcService['onAvailable']>[0]): import("cockatiel").IDisposable;
153
+ onAvailable(listener: Parameters<AbstractRpcService['onAvailable']>[0]): IDisposable;
153
154
  /**
154
155
  * Makes a request to the RPC endpoint.
155
156
  *
@@ -1 +1 @@
1
- {"version":3,"file":"rpc-service.d.mts","sourceRoot":"","sources":["../../src/rpc-service/rpc-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,0BAA0B,EAE3B,mCAAmC;AASpC,OAAO,KAAK,EACV,IAAI,EACJ,aAAa,EACb,cAAc,EACd,eAAe,EAChB,wBAAwB;AAEzB,OAAO,KAAK,EAAE,MAAM,EAAE,iBAAiB;AAEvC,OAAO,KAAK,EAAE,kBAAkB,EAAE,mCAA+B;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,qBAAiB;AAG7C;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B;;;OAGG;IACH,IAAI,EAAE,OAAO,IAAI,CAAC;IAClB;;OAEG;IACH,WAAW,EAAE,GAAG,GAAG,MAAM,CAAC;IAC1B;;;;OAIG;IACH,KAAK,EAAE,OAAO,KAAK,CAAC;IACpB;;;OAGG;IACH,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B;;OAEG;IACH,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B;;;OAGG;IACH,aAAa,CAAC,EAAE,IAAI,CAAC,0BAA0B,EAAE,mBAAmB,CAAC,CAAC;CACvE,CAAC;AAIF;;;GAGG;AACH,eAAO,MAAM,mBAAmB,IAAI,CAAC;AAErC;;;;;GAKG;AACH,eAAO,MAAM,gCAAgC,QAAgC,CAAC;AAE9E;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB;;;GA8C7B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,iBAAiB;;;CAGpB,CAAC;AAEX;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,WAgB/C;AA2DD;;;;;GAKG;AACH,qBAAa,UAAW,YAAW,kBAAkB;;IACnD;;OAEG;IACH,QAAQ,CAAC,WAAW,EAAE,GAAG,CAAC;IAE1B;;;OAGG;IACH,SAAS,EAAE,KAAK,GAAG,SAAS,CAAC;IAsB7B;;;;OAIG;gBACS,OAAO,EAAE,iBAAiB;IA0CtC;;;;;;OAMG;IACH,WAAW;IAIX;;OAEG;IACH,eAAe;IAIf;;;;;;OAMG;IACH,OAAO,CAAC,QAAQ,EAAE,UAAU,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IAM9D;;;;;;;OAOG;IACH,OAAO,CAAC,QAAQ,EAAE,UAAU,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IAmB9D;;;;;;;OAOG;IACH,UAAU,CAAC,QAAQ,EAAE,UAAU,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;IAMpE;;;;;;OAMG;IACH,WAAW,CAAC,QAAQ,EAAE,UAAU,CAAC,kBAAkB,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;IAMtE;;;;;;;;;;;;;;;;OAgBG;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;;;;;;;;;;;;;;;;OAgBG;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;CA0LpC"}
1
+ {"version":3,"file":"rpc-service.d.mts","sourceRoot":"","sources":["../../src/rpc-service/rpc-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,0BAA0B,EAE3B,mCAAmC;AASpC,OAAO,KAAK,EACV,IAAI,EACJ,aAAa,EACb,cAAc,EACd,eAAe,EAChB,wBAAwB;AACzB,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,kBAAkB;AAEtD,OAAO,KAAK,EAAE,MAAM,EAAE,iBAAiB;AAEvC,OAAO,KAAK,EAAE,kBAAkB,EAAE,mCAA+B;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,qBAAiB;AAG7C;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B;;;OAGG;IACH,IAAI,EAAE,OAAO,IAAI,CAAC;IAClB;;OAEG;IACH,WAAW,EAAE,GAAG,GAAG,MAAM,CAAC;IAC1B;;;;OAIG;IACH,KAAK,EAAE,OAAO,KAAK,CAAC;IACpB;;;OAGG;IACH,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B;;OAEG;IACH,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B;;;OAGG;IACH,aAAa,CAAC,EAAE,IAAI,CAAC,0BAA0B,EAAE,mBAAmB,CAAC,CAAC;CACvE,CAAC;AAIF;;;GAGG;AACH,eAAO,MAAM,mBAAmB,IAAI,CAAC;AAErC;;;;;GAKG;AACH,eAAO,MAAM,gCAAgC,QAAgC,CAAC;AAE9E;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB;;;GA8C7B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,iBAAiB;;;CAGpB,CAAC;AAEX;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAgBzD;AA2DD;;;;;GAKG;AACH,qBAAa,UAAW,YAAW,kBAAkB;;IACnD;;OAEG;IACH,QAAQ,CAAC,WAAW,EAAE,GAAG,CAAC;IAE1B;;;OAGG;IACH,SAAS,EAAE,KAAK,GAAG,SAAS,CAAC;IAsB7B;;;;OAIG;gBACS,OAAO,EAAE,iBAAiB;IA0CtC;;;;;;OAMG;IACH,WAAW,IAAI,IAAI;IAInB;;OAEG;IACH,eAAe,IAAI,YAAY;IAI/B;;;;;;OAMG;IACH,OAAO,CAAC,QAAQ,EAAE,UAAU,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,WAAW;IAM5E;;;;;;;OAOG;IACH,OAAO,CAAC,QAAQ,EAAE,UAAU,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,WAAW;IAmB5E;;;;;;;OAOG;IACH,UAAU,CACR,QAAQ,EAAE,UAAU,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,GACxD,WAAW;IAMd;;;;;;OAMG;IACH,WAAW,CACT,QAAQ,EAAE,UAAU,CAAC,kBAAkB,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,GACzD,WAAW;IAMd;;;;;;;;;;;;;;;;OAgBG;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;;;;;;;;;;;;;;;;OAgBG;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;CA0LpC"}
@@ -19,6 +19,7 @@ function $importDefault(module) {
19
19
  import { BrokenCircuitError, HttpError, createServicePolicy, handleWhen } from "@metamask/controller-utils";
20
20
  import { JsonRpcError, rpcErrors } from "@metamask/rpc-errors";
21
21
  import { Duration, getErrorMessage, hasProperty } from "@metamask/utils";
22
+ import { CircuitState } from "cockatiel";
22
23
  import $deepmerge from "deepmerge";
23
24
  const deepmerge = $importDefault($deepmerge);
24
25
  import { projectLogger, createModuleLogger } from "../logger.mjs";