@lido-nestjs/execution 1.0.1 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -16,13 +16,13 @@ yarn add @lido-nestjs/execution
16
16
  ```ts
17
17
  // Import
18
18
  import { Injectable, Module } from '@nestjs/common';
19
- import { ExecutionModule } from '@lido-nestjs/execution';
19
+ import { FallbackProviderModule } from '@lido-nestjs/execution';
20
20
  import { MyService } from './my.service';
21
21
 
22
22
  @Module({
23
23
  imports: [
24
24
  LoggerModule.forRoot({}),
25
- ExecutionModule.forRoot({
25
+ FallbackProviderModule.forRoot({
26
26
  imports: [],
27
27
  urls: ['http://localhost:8545', 'http://fallback:8545'],
28
28
  network: 1,
@@ -48,4 +48,25 @@ export class MyService {
48
48
 
49
49
  ### Async usage
50
50
 
51
- // TODO
51
+ ```ts
52
+ import { Module } from '@nestjs/common';
53
+ import { FallbackProviderModule } from '@lido-nestjs/execution';
54
+ import { ConfigModule, ConfigService } from './my.service';
55
+
56
+ @Module({
57
+ imports: [
58
+ ConfigModule.forRoot(),
59
+ FetchModule.forRoot(),
60
+ FallbackProviderModule.forRootAsync({
61
+ async useFactory(configService: ConfigService) {
62
+ return {
63
+ urls: configService.urls,
64
+ network: configService.network,
65
+ };
66
+ },
67
+ inject: [ConfigService],
68
+ }),
69
+ ],
70
+ })
71
+ export class MyModule {}
72
+ ```
@@ -0,0 +1,8 @@
1
+ import { DynamicModule } from '@nestjs/common';
2
+ import { BatchProviderModuleAsyncOptions, BatchProviderModuleSyncOptions } from './interfaces/module.options';
3
+ export declare class BatchProviderModule {
4
+ static forRoot(options: BatchProviderModuleSyncOptions): DynamicModule;
5
+ static forFeature(options: BatchProviderModuleSyncOptions): DynamicModule;
6
+ static forRootAsync(options: BatchProviderModuleAsyncOptions): DynamicModule;
7
+ static forFeatureAsync(options: BatchProviderModuleAsyncOptions): DynamicModule;
8
+ }
@@ -0,0 +1,61 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var tslib = require('tslib');
6
+ var common = require('@nestjs/common');
7
+ var extendedJsonRpcBatchProvider = require('./provider/extended-json-rpc-batch-provider.js');
8
+ var constants = require('./constants/constants.js');
9
+
10
+ var BatchProviderModule_1;
11
+ const getModuleProviders = (options) => {
12
+ return [
13
+ {
14
+ provide: extendedJsonRpcBatchProvider.ExtendedJsonRpcBatchProvider,
15
+ useFactory: () => {
16
+ return new extendedJsonRpcBatchProvider.ExtendedJsonRpcBatchProvider(options.url, options.network, options.requestPolicy, options.fetchMiddlewares);
17
+ },
18
+ },
19
+ ];
20
+ };
21
+ exports.BatchProviderModule = BatchProviderModule_1 = class BatchProviderModule {
22
+ static forRoot(options) {
23
+ return Object.assign({ global: true }, this.forFeature(options));
24
+ }
25
+ static forFeature(options) {
26
+ return {
27
+ module: BatchProviderModule_1,
28
+ imports: options.imports,
29
+ providers: getModuleProviders(options),
30
+ exports: [extendedJsonRpcBatchProvider.ExtendedJsonRpcBatchProvider],
31
+ };
32
+ }
33
+ static forRootAsync(options) {
34
+ return Object.assign({ global: true }, this.forFeatureAsync(options));
35
+ }
36
+ static forFeatureAsync(options) {
37
+ return {
38
+ module: BatchProviderModule_1,
39
+ imports: options.imports,
40
+ providers: [
41
+ {
42
+ provide: constants.BATCH_PROVIDER_MODULE_OPTIONS,
43
+ useFactory: options.useFactory,
44
+ inject: options.inject,
45
+ },
46
+ {
47
+ provide: extendedJsonRpcBatchProvider.ExtendedJsonRpcBatchProvider,
48
+ useFactory: (options) => {
49
+ return new extendedJsonRpcBatchProvider.ExtendedJsonRpcBatchProvider(options.url, options.network, options.requestPolicy, options.fetchMiddlewares);
50
+ },
51
+ inject: [constants.BATCH_PROVIDER_MODULE_OPTIONS],
52
+ },
53
+ ...(options.providers || []),
54
+ ],
55
+ exports: [extendedJsonRpcBatchProvider.ExtendedJsonRpcBatchProvider],
56
+ };
57
+ }
58
+ };
59
+ exports.BatchProviderModule = BatchProviderModule_1 = tslib.__decorate([
60
+ common.Module({})
61
+ ], exports.BatchProviderModule);
@@ -1,5 +1,2 @@
1
- export declare const EXECUTION_MODULE_OPTIONS: unique symbol;
2
- export declare enum Provider {
3
- ExtendedJsonRpcBatchProvider = 0,
4
- SimpleFallbackJsonRpcBatchProvider = 1
5
- }
1
+ export declare const FALLBACK_PROVIDER_MODULE_OPTIONS: unique symbol;
2
+ export declare const BATCH_PROVIDER_MODULE_OPTIONS: unique symbol;
@@ -2,16 +2,8 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- const EXECUTION_MODULE_OPTIONS = Symbol('execution-module-options');
6
- exports.Provider = void 0;
7
- (function (Provider) {
8
- Provider[Provider["ExtendedJsonRpcBatchProvider"] = 0] = "ExtendedJsonRpcBatchProvider";
9
- Provider[Provider["SimpleFallbackJsonRpcBatchProvider"] = 1] = "SimpleFallbackJsonRpcBatchProvider";
10
- })(exports.Provider || (exports.Provider = {}));
11
- // export type Providers =
12
- // [Provider.ExtendedJsonRpcBatchProvider, Provider.SimpleFallbackJsonRpcBatchProvider] |
13
- // [Provider.SimpleFallbackJsonRpcBatchProvider, Provider.ExtendedJsonRpcBatchProvider] |
14
- // [Provider.SimpleFallbackJsonRpcBatchProvider] |
15
- // [Provider.ExtendedJsonRpcBatchProvider];
5
+ const FALLBACK_PROVIDER_MODULE_OPTIONS = Symbol('fallback-provider-module-options');
6
+ const BATCH_PROVIDER_MODULE_OPTIONS = Symbol('batch-provider-module-options');
16
7
 
17
- exports.EXECUTION_MODULE_OPTIONS = EXECUTION_MODULE_OPTIONS;
8
+ exports.BATCH_PROVIDER_MODULE_OPTIONS = BATCH_PROVIDER_MODULE_OPTIONS;
9
+ exports.FALLBACK_PROVIDER_MODULE_OPTIONS = FALLBACK_PROVIDER_MODULE_OPTIONS;
@@ -0,0 +1,8 @@
1
+ import { DynamicModule } from '@nestjs/common';
2
+ import { FallbackProviderModuleAsyncOptions, FallbackProviderModuleSyncOptions } from './interfaces/module.options';
3
+ export declare class FallbackProviderModule {
4
+ static forRoot(options: FallbackProviderModuleSyncOptions): DynamicModule;
5
+ static forFeature(options: FallbackProviderModuleSyncOptions): DynamicModule;
6
+ static forRootAsync(options: FallbackProviderModuleAsyncOptions): DynamicModule;
7
+ static forFeatureAsync(options: FallbackProviderModuleAsyncOptions): DynamicModule;
8
+ }
@@ -9,7 +9,7 @@ var constants = require('./constants/constants.js');
9
9
  var simpleFallbackJsonRpcBatchProvider = require('./provider/simple-fallback-json-rpc-batch-provider.js');
10
10
  var logger = require('@lido-nestjs/logger');
11
11
 
12
- var ExecutionModule_1;
12
+ var FallbackProviderModule_1;
13
13
  const getModuleProviders = (options) => {
14
14
  return [
15
15
  {
@@ -28,19 +28,16 @@ const getModuleProviders = (options) => {
28
28
  },
29
29
  ];
30
30
  };
31
- exports.ExecutionModule = ExecutionModule_1 = class ExecutionModule {
31
+ exports.FallbackProviderModule = FallbackProviderModule_1 = class FallbackProviderModule {
32
32
  static forRoot(options) {
33
33
  return Object.assign({ global: true }, this.forFeature(options));
34
34
  }
35
35
  static forFeature(options) {
36
36
  return {
37
- module: ExecutionModule_1,
37
+ module: FallbackProviderModule_1,
38
38
  imports: options.imports,
39
39
  providers: getModuleProviders(options),
40
- exports: [
41
- simpleFallbackJsonRpcBatchProvider.SimpleFallbackJsonRpcBatchProvider,
42
- extendedJsonRpcBatchProvider.ExtendedJsonRpcBatchProvider,
43
- ],
40
+ exports: [simpleFallbackJsonRpcBatchProvider.SimpleFallbackJsonRpcBatchProvider],
44
41
  };
45
42
  }
46
43
  static forRootAsync(options) {
@@ -48,11 +45,11 @@ exports.ExecutionModule = ExecutionModule_1 = class ExecutionModule {
48
45
  }
49
46
  static forFeatureAsync(options) {
50
47
  return {
51
- module: ExecutionModule_1,
48
+ module: FallbackProviderModule_1,
52
49
  imports: options.imports,
53
50
  providers: [
54
51
  {
55
- provide: constants.EXECUTION_MODULE_OPTIONS,
52
+ provide: constants.FALLBACK_PROVIDER_MODULE_OPTIONS,
56
53
  useFactory: options.useFactory,
57
54
  inject: options.inject,
58
55
  },
@@ -61,25 +58,14 @@ exports.ExecutionModule = ExecutionModule_1 = class ExecutionModule {
61
58
  useFactory: (logger, options) => {
62
59
  return new simpleFallbackJsonRpcBatchProvider.SimpleFallbackJsonRpcBatchProvider(options, logger);
63
60
  },
64
- inject: [logger.LOGGER_PROVIDER, constants.EXECUTION_MODULE_OPTIONS],
65
- },
66
- {
67
- provide: extendedJsonRpcBatchProvider.ExtendedJsonRpcBatchProvider,
68
- useFactory: (options) => {
69
- return new extendedJsonRpcBatchProvider.ExtendedJsonRpcBatchProvider(options.urls[0], undefined, // options.network,
70
- options.requestPolicy);
71
- },
72
- inject: [constants.EXECUTION_MODULE_OPTIONS],
61
+ inject: [logger.LOGGER_PROVIDER, constants.FALLBACK_PROVIDER_MODULE_OPTIONS],
73
62
  },
74
63
  ...(options.providers || []),
75
64
  ],
76
- exports: [
77
- simpleFallbackJsonRpcBatchProvider.SimpleFallbackJsonRpcBatchProvider,
78
- extendedJsonRpcBatchProvider.ExtendedJsonRpcBatchProvider,
79
- ],
65
+ exports: [simpleFallbackJsonRpcBatchProvider.SimpleFallbackJsonRpcBatchProvider],
80
66
  };
81
67
  }
82
68
  };
83
- exports.ExecutionModule = ExecutionModule_1 = tslib.__decorate([
69
+ exports.FallbackProviderModule = FallbackProviderModule_1 = tslib.__decorate([
84
70
  common.Module({})
85
- ], exports.ExecutionModule);
71
+ ], exports.FallbackProviderModule);
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  export * from './provider/extended-json-rpc-batch-provider';
2
2
  export * from './provider/simple-fallback-json-rpc-batch-provider';
3
3
  export * from './common/queue';
4
- export * from './execution.module';
4
+ export * from './fallback-provider.module';
5
+ export * from './batch-provider.module';
5
6
  export * from './interfaces/fallback-provider';
6
7
  export * from './interfaces/simple-fallback-provider-config';
7
- export { ExecutionModuleAsyncOptions } from './interfaces/module.options';
8
- export { ExecutionModuleSyncOptions } from './interfaces/module.options';
8
+ export * from './interfaces/module.options';
package/dist/index.js CHANGED
@@ -5,7 +5,8 @@ Object.defineProperty(exports, '__esModule', { value: true });
5
5
  var extendedJsonRpcBatchProvider = require('./provider/extended-json-rpc-batch-provider.js');
6
6
  var simpleFallbackJsonRpcBatchProvider = require('./provider/simple-fallback-json-rpc-batch-provider.js');
7
7
  var queue = require('./common/queue.js');
8
- var execution_module = require('./execution.module.js');
8
+ var fallbackProvider_module = require('./fallback-provider.module.js');
9
+ var batchProvider_module = require('./batch-provider.module.js');
9
10
 
10
11
 
11
12
 
@@ -18,7 +19,11 @@ Object.defineProperty(exports, 'SimpleFallbackJsonRpcBatchProvider', {
18
19
  get: function () { return simpleFallbackJsonRpcBatchProvider.SimpleFallbackJsonRpcBatchProvider; }
19
20
  });
20
21
  exports.Queue = queue.Queue;
21
- Object.defineProperty(exports, 'ExecutionModule', {
22
+ Object.defineProperty(exports, 'FallbackProviderModule', {
22
23
  enumerable: true,
23
- get: function () { return execution_module.ExecutionModule; }
24
+ get: function () { return fallbackProvider_module.FallbackProviderModule; }
25
+ });
26
+ Object.defineProperty(exports, 'BatchProviderModule', {
27
+ enumerable: true,
28
+ get: function () { return batchProvider_module.BatchProviderModule; }
24
29
  });
@@ -4,4 +4,5 @@ export interface FallbackProvider {
4
4
  provider: ExtendedJsonRpcBatchProvider;
5
5
  network: Network | null;
6
6
  index: number;
7
+ unreachable: boolean;
7
8
  }
@@ -1,8 +1,22 @@
1
1
  import { ModuleMetadata } from '@nestjs/common';
2
2
  import { SimpleFallbackProviderConfig } from './simple-fallback-provider-config';
3
- export interface ExecutionModuleSyncOptions extends Pick<ModuleMetadata, 'imports'>, SimpleFallbackProviderConfig {
3
+ import { ConnectionInfo } from '@ethersproject/web';
4
+ import { Networkish } from './networkish';
5
+ import { RequestPolicy } from '../provider/extended-json-rpc-batch-provider';
6
+ import { MiddlewareCallback } from '@lido-nestjs/middleware';
7
+ export interface FallbackProviderModuleSyncOptions extends Pick<ModuleMetadata, 'imports'>, SimpleFallbackProviderConfig {
4
8
  }
5
- export interface ExecutionModuleAsyncOptions extends Pick<ModuleMetadata, 'imports' | 'providers'> {
6
- useFactory: (...args: any[]) => Promise<ExecutionModuleSyncOptions> | ExecutionModuleSyncOptions;
9
+ export interface BatchProviderModuleSyncOptions extends Pick<ModuleMetadata, 'imports'> {
10
+ url: ConnectionInfo | string;
11
+ network?: Networkish;
12
+ requestPolicy?: RequestPolicy;
13
+ fetchMiddlewares?: MiddlewareCallback<Promise<any>>[];
14
+ }
15
+ export interface FallbackProviderModuleAsyncOptions extends Pick<ModuleMetadata, 'imports' | 'providers'> {
16
+ useFactory: (...args: any[]) => Promise<FallbackProviderModuleSyncOptions> | FallbackProviderModuleSyncOptions;
17
+ inject: any[];
18
+ }
19
+ export interface BatchProviderModuleAsyncOptions extends Pick<ModuleMetadata, 'imports' | 'providers'> {
20
+ useFactory: (...args: any[]) => Promise<BatchProviderModuleSyncOptions> | BatchProviderModuleSyncOptions;
7
21
  inject: any[];
8
22
  }
@@ -11,5 +11,6 @@ export interface SimpleFallbackProviderConfig {
11
11
  minBackoffMs?: number;
12
12
  maxBackoffMs?: number;
13
13
  logRetries?: boolean;
14
+ resetIntervalMs?: number;
14
15
  fetchMiddlewares?: MiddlewareCallback<Promise<any>>[];
15
16
  }
@@ -26,6 +26,7 @@ export declare class SimpleFallbackJsonRpcBatchProvider extends BaseProvider {
26
26
  protected fallbackProviders: [FallbackProvider];
27
27
  protected activeFallbackProviderIndex: number;
28
28
  protected detectNetworkFirstRun: boolean;
29
+ protected resetTimer: ReturnType<typeof setTimeout> | null;
29
30
  constructor(config: SimpleFallbackProviderConfig, logger: LoggerService);
30
31
  static _formatter: Formatter | null;
31
32
  static getFormatter(): Formatter;
@@ -35,5 +36,6 @@ export declare class SimpleFallbackJsonRpcBatchProvider extends BaseProvider {
35
36
  [name: string]: unknown;
36
37
  }): Promise<unknown>;
37
38
  detectNetwork(): Promise<Network>;
39
+ protected resetFallbacks(): void;
38
40
  protected networksEqual(networkA: Network, networkB: Network): boolean;
39
41
  }
@@ -14,6 +14,7 @@ exports.SimpleFallbackJsonRpcBatchProvider = class SimpleFallbackJsonRpcBatchPro
14
14
  constructor(config, logger) {
15
15
  super(config.network);
16
16
  this.detectNetworkFirstRun = true;
17
+ this.resetTimer = null;
17
18
  this.config = Object.assign({ maxRetries: 3, minBackoffMs: 500, maxBackoffMs: 5000, logRetries: true }, config);
18
19
  this.logger = logger;
19
20
  const conns = config.urls.filter((url) => {
@@ -35,6 +36,7 @@ exports.SimpleFallbackJsonRpcBatchProvider = class SimpleFallbackJsonRpcBatchPro
35
36
  network: null,
36
37
  provider,
37
38
  index,
39
+ unreachable: false,
38
40
  };
39
41
  });
40
42
  this.activeFallbackProviderIndex = 0;
@@ -96,13 +98,17 @@ exports.SimpleFallbackJsonRpcBatchProvider = class SimpleFallbackJsonRpcBatchPro
96
98
  throw new Error('All attempts to do ETH1 RPC request failed');
97
99
  }
98
100
  async detectNetwork() {
99
- const results = await Promise.allSettled(this.fallbackProviders.map((c) => c.provider.getNetwork()));
100
- results.forEach((result, i) => {
101
+ const results = await Promise.allSettled(this.fallbackProviders
102
+ .filter((c) => !c.unreachable)
103
+ .map((c) => c.provider.getNetwork()));
104
+ results.forEach((result, index) => {
101
105
  if (result.status === 'fulfilled') {
102
- this.fallbackProviders[i].network = result.value;
106
+ this.fallbackProviders[index].network = result.value;
107
+ this.fallbackProviders[index].unreachable = false;
103
108
  }
104
109
  else {
105
- this.fallbackProviders[i].network = null;
110
+ this.fallbackProviders[index].network = null;
111
+ this.fallbackProviders[index].unreachable = true;
106
112
  }
107
113
  });
108
114
  let previousNetwork = null;
@@ -139,8 +145,26 @@ exports.SimpleFallbackJsonRpcBatchProvider = class SimpleFallbackJsonRpcBatchPro
139
145
  if (this.detectNetworkFirstRun) {
140
146
  this.detectNetworkFirstRun = false;
141
147
  }
148
+ if (this.resetTimer) {
149
+ clearTimeout(this.resetTimer);
150
+ }
151
+ this.resetTimer = setTimeout(() => {
152
+ this.resetFallbacks();
153
+ }, this.config.resetIntervalMs || 10000);
142
154
  return previousNetwork;
143
155
  }
156
+ resetFallbacks() {
157
+ if (this.resetTimer) {
158
+ clearTimeout(this.resetTimer);
159
+ }
160
+ this.fallbackProviders.forEach((fallbackProvider, index) => {
161
+ var _a;
162
+ if (!((_a = this.fallbackProviders[index].network) === null || _a === void 0 ? void 0 : _a.chainId)) {
163
+ this.fallbackProviders[index].unreachable = false;
164
+ }
165
+ });
166
+ this.activeFallbackProviderIndex = 0;
167
+ }
144
168
  networksEqual(networkA, networkB) {
145
169
  return networks.networksEqual(networkA, networkB);
146
170
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lido-nestjs/execution",
3
- "version": "1.0.1",
3
+ "version": "1.3.0",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "license": "MIT",
@@ -38,7 +38,7 @@
38
38
  "@ethersproject/properties": "^5.5.0",
39
39
  "@ethersproject/providers": "^5.5.3",
40
40
  "@ethersproject/web": "^5.5.1",
41
- "@lido-nestjs/logger": "1.0.3",
41
+ "@lido-nestjs/logger": "1.1.0",
42
42
  "@lido-nestjs/middleware": "1.1.1"
43
43
  },
44
44
  "peerDependencies": {
@@ -1,8 +0,0 @@
1
- import { DynamicModule } from '@nestjs/common';
2
- import { ExecutionModuleAsyncOptions, ExecutionModuleSyncOptions } from './interfaces/module.options';
3
- export declare class ExecutionModule {
4
- static forRoot(options: ExecutionModuleSyncOptions): DynamicModule;
5
- static forFeature(options: ExecutionModuleSyncOptions): DynamicModule;
6
- static forRootAsync(options: ExecutionModuleAsyncOptions): DynamicModule;
7
- static forFeatureAsync(options: ExecutionModuleAsyncOptions): DynamicModule;
8
- }