@my-packages-changeit/abstract-scanner 2.0.3

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 (73) hide show
  1. package/CHANGELOG.md +135 -0
  2. package/README.md +49 -0
  3. package/dist/entities/blockEntity.d.ts +17 -0
  4. package/dist/entities/blockEntity.d.ts.map +1 -0
  5. package/dist/entities/blockEntity.js +78 -0
  6. package/dist/entities/extractorStatusEntity.d.ts +7 -0
  7. package/dist/entities/extractorStatusEntity.d.ts.map +1 -0
  8. package/dist/entities/extractorStatusEntity.js +37 -0
  9. package/dist/index.d.ts +11 -0
  10. package/dist/index.d.ts.map +1 -0
  11. package/dist/index.js +10 -0
  12. package/dist/migrations/index.d.ts +7 -0
  13. package/dist/migrations/index.d.ts.map +1 -0
  14. package/dist/migrations/index.js +31 -0
  15. package/dist/migrations/postgres/1688545690867-migration.d.ts +7 -0
  16. package/dist/migrations/postgres/1688545690867-migration.d.ts.map +1 -0
  17. package/dist/migrations/postgres/1688545690867-migration.js +30 -0
  18. package/dist/migrations/postgres/1713803486477-migration.d.ts +7 -0
  19. package/dist/migrations/postgres/1713803486477-migration.d.ts.map +1 -0
  20. package/dist/migrations/postgres/1713803486477-migration.js +20 -0
  21. package/dist/migrations/postgres/1718789786123-migration.d.ts +7 -0
  22. package/dist/migrations/postgres/1718789786123-migration.d.ts.map +1 -0
  23. package/dist/migrations/postgres/1718789786123-migration.js +12 -0
  24. package/dist/migrations/postgres/1722697954558-migration.d.ts +7 -0
  25. package/dist/migrations/postgres/1722697954558-migration.d.ts.map +1 -0
  26. package/dist/migrations/postgres/1722697954558-migration.js +52 -0
  27. package/dist/migrations/postgres/1746701087567-migration.d.ts +7 -0
  28. package/dist/migrations/postgres/1746701087567-migration.d.ts.map +1 -0
  29. package/dist/migrations/postgres/1746701087567-migration.js +32 -0
  30. package/dist/migrations/postgres/1747657653564-migration.d.ts +7 -0
  31. package/dist/migrations/postgres/1747657653564-migration.d.ts.map +1 -0
  32. package/dist/migrations/postgres/1747657653564-migration.js +134 -0
  33. package/dist/migrations/sqlite/1688555497475-migration.d.ts +7 -0
  34. package/dist/migrations/sqlite/1688555497475-migration.d.ts.map +1 -0
  35. package/dist/migrations/sqlite/1688555497475-migration.js +29 -0
  36. package/dist/migrations/sqlite/1713786682123-migration.d.ts +7 -0
  37. package/dist/migrations/sqlite/1713786682123-migration.d.ts.map +1 -0
  38. package/dist/migrations/sqlite/1713786682123-migration.js +20 -0
  39. package/dist/migrations/sqlite/1718789744123-migration.d.ts +7 -0
  40. package/dist/migrations/sqlite/1718789744123-migration.d.ts.map +1 -0
  41. package/dist/migrations/sqlite/1718789744123-migration.js +12 -0
  42. package/dist/migrations/sqlite/1722697111974-migration.d.ts +7 -0
  43. package/dist/migrations/sqlite/1722697111974-migration.d.ts.map +1 -0
  44. package/dist/migrations/sqlite/1722697111974-migration.js +112 -0
  45. package/dist/migrations/sqlite/1746701087234-migration.d.ts +7 -0
  46. package/dist/migrations/sqlite/1746701087234-migration.d.ts.map +1 -0
  47. package/dist/migrations/sqlite/1746701087234-migration.js +32 -0
  48. package/dist/migrations/sqlite/1747655941239-migration.d.ts +7 -0
  49. package/dist/migrations/sqlite/1747655941239-migration.d.ts.map +1 -0
  50. package/dist/migrations/sqlite/1747655941239-migration.js +134 -0
  51. package/dist/scanner/abstract/generalScanner.d.ts +78 -0
  52. package/dist/scanner/abstract/generalScanner.d.ts.map +1 -0
  53. package/dist/scanner/abstract/generalScanner.js +210 -0
  54. package/dist/scanner/abstract/scanner.d.ts +49 -0
  55. package/dist/scanner/abstract/scanner.d.ts.map +1 -0
  56. package/dist/scanner/abstract/scanner.js +142 -0
  57. package/dist/scanner/abstract/webSocketScanner.d.ts +29 -0
  58. package/dist/scanner/abstract/webSocketScanner.d.ts.map +1 -0
  59. package/dist/scanner/abstract/webSocketScanner.js +90 -0
  60. package/dist/scanner/action.d.ts +83 -0
  61. package/dist/scanner/action.d.ts.map +1 -0
  62. package/dist/scanner/action.js +251 -0
  63. package/dist/scanner/interfaces.d.ts +13 -0
  64. package/dist/scanner/interfaces.d.ts.map +1 -0
  65. package/dist/scanner/interfaces.js +2 -0
  66. package/dist/scanner/network/connectorSelectionStrategies.d.ts +27 -0
  67. package/dist/scanner/network/connectorSelectionStrategies.d.ts.map +1 -0
  68. package/dist/scanner/network/connectorSelectionStrategies.js +22 -0
  69. package/dist/scanner/network/networkConnectorManager.d.ts +65 -0
  70. package/dist/scanner/network/networkConnectorManager.d.ts.map +1 -0
  71. package/dist/scanner/network/networkConnectorManager.js +126 -0
  72. package/dist/tsconfig.tsbuildinfo +1 -0
  73. package/package.json +46 -0
@@ -0,0 +1,134 @@
1
+ export class migration1747655941239 {
2
+ name = 'migration1747655941239';
3
+ async up(queryRunner) {
4
+ // Update block_entity table for cardano
5
+ await queryRunner.query(`
6
+ UPDATE block_entity
7
+ SET scanner = 'cardano'
8
+ WHERE scanner IN (
9
+ 'cardano-BlockFrost',
10
+ 'cardano-graphql',
11
+ 'cardano-koios',
12
+ 'cardano-ogmios'
13
+ )
14
+ `);
15
+ await queryRunner.query(`
16
+ UPDATE block_entity
17
+ SET scanner = 'bitcoin'
18
+ WHERE scanner IN (
19
+ 'bitcoin-esplora',
20
+ 'bitcoin-rpc'
21
+ )
22
+ `);
23
+ await queryRunner.query(`
24
+ UPDATE block_entity
25
+ SET scanner = 'ethereum'
26
+ WHERE scanner = 'ethereum-evm-rpc';
27
+ `);
28
+ await queryRunner.query(`
29
+ UPDATE block_entity
30
+ SET scanner = 'binance'
31
+ WHERE scanner = 'binance-evm-rpc';
32
+ `);
33
+ await queryRunner.query(`
34
+ UPDATE block_entity
35
+ SET scanner = 'doge'
36
+ WHERE scanner IN (
37
+ 'doge-esplora',
38
+ 'doge-rpc'
39
+ )
40
+ `);
41
+ // Update extractor_status_entity table for cardano
42
+ await queryRunner.query(`
43
+ UPDATE extractor_status_entity
44
+ SET scannerId = 'cardano'
45
+ WHERE scannerId IN (
46
+ 'cardano-BlockFrost',
47
+ 'cardano-graphql',
48
+ 'cardano-koios',
49
+ 'cardano-ogmios'
50
+ )
51
+ `);
52
+ await queryRunner.query(`
53
+ UPDATE extractor_status_entity
54
+ SET scannerId = 'bitcoin'
55
+ WHERE scannerId IN (
56
+ 'bitcoin-esplora',
57
+ 'bitcoin-rpc'
58
+ )
59
+ `);
60
+ await queryRunner.query(`
61
+ UPDATE extractor_status_entity
62
+ SET scannerId = 'ethereum'
63
+ WHERE scannerId = 'ethereum-evm-rpc';
64
+ `);
65
+ await queryRunner.query(`
66
+ UPDATE extractor_status_entity
67
+ SET scannerId = 'binance'
68
+ WHERE scannerId = 'binance-evm-rpc';
69
+ `);
70
+ await queryRunner.query(`
71
+ UPDATE extractor_status_entity
72
+ SET scannerId = 'doge'
73
+ WHERE scannerId IN (
74
+ 'doge-esplora',
75
+ 'doge-rpc'
76
+ )
77
+ `);
78
+ }
79
+ async down(queryRunner) {
80
+ // Revert block_entity table
81
+ await queryRunner.query(`
82
+ UPDATE block_entity
83
+ SET scanner = 'cardano-koios'
84
+ WHERE scanner = 'cardano'
85
+ `);
86
+ await queryRunner.query(`
87
+ UPDATE block_entity
88
+ SET scanner = 'bitcoin-esplora'
89
+ WHERE scanner = 'bitcoin'
90
+ `);
91
+ await queryRunner.query(`
92
+ UPDATE block_entity
93
+ SET scanner = 'ethereum-evm-rpc'
94
+ WHERE scanner = 'ethereum';
95
+ `);
96
+ await queryRunner.query(`
97
+ UPDATE block_entity
98
+ SET scanner = 'binance-evm-rpc'
99
+ WHERE scanner = 'binance';
100
+ `);
101
+ await queryRunner.query(`
102
+ UPDATE block_entity
103
+ SET scanner = 'doge-esplora'
104
+ WHERE scanner = 'doge'
105
+ `);
106
+ // Revert extractor_status_entity table
107
+ await queryRunner.query(`
108
+ UPDATE extractor_status_entity
109
+ SET scannerId = 'cardano-koios'
110
+ WHERE scannerId = 'cardano'
111
+ `);
112
+ await queryRunner.query(`
113
+ UPDATE extractor_status_entity
114
+ SET scannerId = 'bitcoin-esplora'
115
+ WHERE scannerId = 'bitcoin'
116
+ `);
117
+ await queryRunner.query(`
118
+ UPDATE extractor_status_entity
119
+ SET scannerId = 'ethereum-evm-rpc'
120
+ WHERE scannerId = 'ethereum';
121
+ `);
122
+ await queryRunner.query(`
123
+ UPDATE extractor_status_entity
124
+ SET scannerId = 'binance-evm-rpc'
125
+ WHERE scannerId = 'binance';
126
+ `);
127
+ await queryRunner.query(`
128
+ UPDATE extractor_status_entity
129
+ SET scannerId = 'doge-esplora'
130
+ WHERE scannerId = 'doge'
131
+ `);
132
+ }
133
+ }
134
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTc0NzY1NTk0MTIzOS1taWdyYXRpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9saWIvbWlncmF0aW9ucy9zcWxpdGUvMTc0NzY1NTk0MTIzOS1taWdyYXRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBS0EsTUFBTSxPQUFPLHNCQUFzQjtJQUNqQyxJQUFJLEdBQUcsd0JBQXdCLENBQUM7SUFFekIsS0FBSyxDQUFDLEVBQUUsQ0FBQyxXQUF3QjtRQUN0Qyx3Q0FBd0M7UUFDeEMsTUFBTSxXQUFXLENBQUMsS0FBSyxDQUFDOzs7Ozs7Ozs7S0FTdkIsQ0FBQyxDQUFDO1FBRUgsTUFBTSxXQUFXLENBQUMsS0FBSyxDQUFDOzs7Ozs7O0tBT3ZCLENBQUMsQ0FBQztRQUNILE1BQU0sV0FBVyxDQUFDLEtBQUssQ0FBQzs7OztLQUl2QixDQUFDLENBQUM7UUFFSCxNQUFNLFdBQVcsQ0FBQyxLQUFLLENBQUM7Ozs7S0FJdkIsQ0FBQyxDQUFDO1FBRUgsTUFBTSxXQUFXLENBQUMsS0FBSyxDQUFDOzs7Ozs7O0tBT3ZCLENBQUMsQ0FBQztRQUVILG1EQUFtRDtRQUNuRCxNQUFNLFdBQVcsQ0FBQyxLQUFLLENBQUM7Ozs7Ozs7OztLQVN2QixDQUFDLENBQUM7UUFFSCxNQUFNLFdBQVcsQ0FBQyxLQUFLLENBQUM7Ozs7Ozs7S0FPdkIsQ0FBQyxDQUFDO1FBQ0gsTUFBTSxXQUFXLENBQUMsS0FBSyxDQUFDOzs7O0tBSXZCLENBQUMsQ0FBQztRQUVILE1BQU0sV0FBVyxDQUFDLEtBQUssQ0FBQzs7OztLQUl2QixDQUFDLENBQUM7UUFFSCxNQUFNLFdBQVcsQ0FBQyxLQUFLLENBQUM7Ozs7Ozs7S0FPdkIsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVNLEtBQUssQ0FBQyxJQUFJLENBQUMsV0FBd0I7UUFDeEMsNEJBQTRCO1FBQzVCLE1BQU0sV0FBVyxDQUFDLEtBQUssQ0FBQzs7OztLQUl2QixDQUFDLENBQUM7UUFFSCxNQUFNLFdBQVcsQ0FBQyxLQUFLLENBQUM7Ozs7S0FJdkIsQ0FBQyxDQUFDO1FBQ0gsTUFBTSxXQUFXLENBQUMsS0FBSyxDQUFDOzs7O0tBSXZCLENBQUMsQ0FBQztRQUVILE1BQU0sV0FBVyxDQUFDLEtBQUssQ0FBQzs7OztLQUl2QixDQUFDLENBQUM7UUFFSCxNQUFNLFdBQVcsQ0FBQyxLQUFLLENBQUM7Ozs7S0FJdkIsQ0FBQyxDQUFDO1FBRUgsdUNBQXVDO1FBQ3ZDLE1BQU0sV0FBVyxDQUFDLEtBQUssQ0FBQzs7OztLQUl2QixDQUFDLENBQUM7UUFFSCxNQUFNLFdBQVcsQ0FBQyxLQUFLLENBQUM7Ozs7S0FJdkIsQ0FBQyxDQUFDO1FBRUgsTUFBTSxXQUFXLENBQUMsS0FBSyxDQUFDOzs7O0tBSXZCLENBQUMsQ0FBQztRQUVILE1BQU0sV0FBVyxDQUFDLEtBQUssQ0FBQzs7OztLQUl2QixDQUFDLENBQUM7UUFFSCxNQUFNLFdBQVcsQ0FBQyxLQUFLLENBQUM7Ozs7S0FJdkIsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgTWlncmF0aW9uSW50ZXJmYWNlLFxuICBRdWVyeVJ1bm5lcixcbn0gZnJvbSAnQHJvc2VuLWJyaWRnZS9leHRlbmRlZC10eXBlb3JtJztcblxuZXhwb3J0IGNsYXNzIG1pZ3JhdGlvbjE3NDc2NTU5NDEyMzkgaW1wbGVtZW50cyBNaWdyYXRpb25JbnRlcmZhY2Uge1xuICBuYW1lID0gJ21pZ3JhdGlvbjE3NDc2NTU5NDEyMzknO1xuXG4gIHB1YmxpYyBhc3luYyB1cChxdWVyeVJ1bm5lcjogUXVlcnlSdW5uZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAvLyBVcGRhdGUgYmxvY2tfZW50aXR5IHRhYmxlIGZvciBjYXJkYW5vXG4gICAgYXdhaXQgcXVlcnlSdW5uZXIucXVlcnkoYFxuICAgICAgVVBEQVRFIGJsb2NrX2VudGl0eSBcbiAgICAgIFNFVCBzY2FubmVyID0gJ2NhcmRhbm8nIFxuICAgICAgV0hFUkUgc2Nhbm5lciBJTiAoXG4gICAgICAgICdjYXJkYW5vLUJsb2NrRnJvc3QnLFxuICAgICAgICAnY2FyZGFuby1ncmFwaHFsJyxcbiAgICAgICAgJ2NhcmRhbm8ta29pb3MnLFxuICAgICAgICAnY2FyZGFuby1vZ21pb3MnXG4gICAgICApXG4gICAgYCk7XG5cbiAgICBhd2FpdCBxdWVyeVJ1bm5lci5xdWVyeShgXG4gICAgICBVUERBVEUgYmxvY2tfZW50aXR5IFxuICAgICAgU0VUIHNjYW5uZXIgPSAnYml0Y29pbicgXG4gICAgICBXSEVSRSBzY2FubmVyIElOIChcbiAgICAgICAgJ2JpdGNvaW4tZXNwbG9yYScsXG4gICAgICAgICdiaXRjb2luLXJwYydcbiAgICAgIClcbiAgICBgKTtcbiAgICBhd2FpdCBxdWVyeVJ1bm5lci5xdWVyeShgXG4gICAgICBVUERBVEUgYmxvY2tfZW50aXR5XG4gICAgICBTRVQgc2Nhbm5lciA9ICdldGhlcmV1bSdcbiAgICAgIFdIRVJFIHNjYW5uZXIgPSAnZXRoZXJldW0tZXZtLXJwYyc7XG4gICAgYCk7XG5cbiAgICBhd2FpdCBxdWVyeVJ1bm5lci5xdWVyeShgXG4gICAgICBVUERBVEUgYmxvY2tfZW50aXR5XG4gICAgICBTRVQgc2Nhbm5lciA9ICdiaW5hbmNlJ1xuICAgICAgV0hFUkUgc2Nhbm5lciA9ICdiaW5hbmNlLWV2bS1ycGMnO1xuICAgIGApO1xuXG4gICAgYXdhaXQgcXVlcnlSdW5uZXIucXVlcnkoYFxuICAgICAgVVBEQVRFIGJsb2NrX2VudGl0eSBcbiAgICAgIFNFVCBzY2FubmVyID0gJ2RvZ2UnIFxuICAgICAgV0hFUkUgc2Nhbm5lciBJTiAoXG4gICAgICAgICdkb2dlLWVzcGxvcmEnLFxuICAgICAgICAnZG9nZS1ycGMnXG4gICAgICApXG4gICAgYCk7XG5cbiAgICAvLyBVcGRhdGUgZXh0cmFjdG9yX3N0YXR1c19lbnRpdHkgdGFibGUgZm9yIGNhcmRhbm9cbiAgICBhd2FpdCBxdWVyeVJ1bm5lci5xdWVyeShgXG4gICAgICBVUERBVEUgZXh0cmFjdG9yX3N0YXR1c19lbnRpdHkgXG4gICAgICBTRVQgc2Nhbm5lcklkID0gJ2NhcmRhbm8nIFxuICAgICAgV0hFUkUgc2Nhbm5lcklkIElOIChcbiAgICAgICAgJ2NhcmRhbm8tQmxvY2tGcm9zdCcsXG4gICAgICAgICdjYXJkYW5vLWdyYXBocWwnLFxuICAgICAgICAnY2FyZGFuby1rb2lvcycsXG4gICAgICAgICdjYXJkYW5vLW9nbWlvcydcbiAgICAgIClcbiAgICBgKTtcblxuICAgIGF3YWl0IHF1ZXJ5UnVubmVyLnF1ZXJ5KGBcbiAgICAgIFVQREFURSBleHRyYWN0b3Jfc3RhdHVzX2VudGl0eSBcbiAgICAgIFNFVCBzY2FubmVySWQgPSAnYml0Y29pbicgXG4gICAgICBXSEVSRSBzY2FubmVySWQgSU4gKFxuICAgICAgICAnYml0Y29pbi1lc3Bsb3JhJyxcbiAgICAgICAgJ2JpdGNvaW4tcnBjJ1xuICAgICAgKVxuICAgIGApO1xuICAgIGF3YWl0IHF1ZXJ5UnVubmVyLnF1ZXJ5KGBcbiAgICAgIFVQREFURSBleHRyYWN0b3Jfc3RhdHVzX2VudGl0eVxuICAgICAgU0VUIHNjYW5uZXJJZCA9ICdldGhlcmV1bSdcbiAgICAgIFdIRVJFIHNjYW5uZXJJZCA9ICdldGhlcmV1bS1ldm0tcnBjJztcbiAgICBgKTtcblxuICAgIGF3YWl0IHF1ZXJ5UnVubmVyLnF1ZXJ5KGBcbiAgICAgIFVQREFURSBleHRyYWN0b3Jfc3RhdHVzX2VudGl0eVxuICAgICAgU0VUIHNjYW5uZXJJZCA9ICdiaW5hbmNlJ1xuICAgICAgV0hFUkUgc2Nhbm5lcklkID0gJ2JpbmFuY2UtZXZtLXJwYyc7XG4gICAgYCk7XG5cbiAgICBhd2FpdCBxdWVyeVJ1bm5lci5xdWVyeShgXG4gICAgICBVUERBVEUgZXh0cmFjdG9yX3N0YXR1c19lbnRpdHkgXG4gICAgICBTRVQgc2Nhbm5lcklkID0gJ2RvZ2UnIFxuICAgICAgV0hFUkUgc2Nhbm5lcklkIElOIChcbiAgICAgICAgJ2RvZ2UtZXNwbG9yYScsXG4gICAgICAgICdkb2dlLXJwYydcbiAgICAgIClcbiAgICBgKTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBkb3duKHF1ZXJ5UnVubmVyOiBRdWVyeVJ1bm5lcik6IFByb21pc2U8dm9pZD4ge1xuICAgIC8vIFJldmVydCBibG9ja19lbnRpdHkgdGFibGVcbiAgICBhd2FpdCBxdWVyeVJ1bm5lci5xdWVyeShgXG4gICAgICBVUERBVEUgYmxvY2tfZW50aXR5IFxuICAgICAgU0VUIHNjYW5uZXIgPSAnY2FyZGFuby1rb2lvcycgXG4gICAgICBXSEVSRSBzY2FubmVyID0gJ2NhcmRhbm8nXG4gICAgYCk7XG5cbiAgICBhd2FpdCBxdWVyeVJ1bm5lci5xdWVyeShgXG4gICAgICBVUERBVEUgYmxvY2tfZW50aXR5IFxuICAgICAgU0VUIHNjYW5uZXIgPSAnYml0Y29pbi1lc3Bsb3JhJyBcbiAgICAgIFdIRVJFIHNjYW5uZXIgPSAnYml0Y29pbidcbiAgICBgKTtcbiAgICBhd2FpdCBxdWVyeVJ1bm5lci5xdWVyeShgXG4gICAgICBVUERBVEUgYmxvY2tfZW50aXR5XG4gICAgICBTRVQgc2Nhbm5lciA9ICdldGhlcmV1bS1ldm0tcnBjJ1xuICAgICAgV0hFUkUgc2Nhbm5lciA9ICdldGhlcmV1bSc7XG4gICAgYCk7XG5cbiAgICBhd2FpdCBxdWVyeVJ1bm5lci5xdWVyeShgXG4gICAgICBVUERBVEUgYmxvY2tfZW50aXR5XG4gICAgICBTRVQgc2Nhbm5lciA9ICdiaW5hbmNlLWV2bS1ycGMnXG4gICAgICBXSEVSRSBzY2FubmVyID0gJ2JpbmFuY2UnO1xuICAgIGApO1xuXG4gICAgYXdhaXQgcXVlcnlSdW5uZXIucXVlcnkoYFxuICAgICAgVVBEQVRFIGJsb2NrX2VudGl0eSBcbiAgICAgIFNFVCBzY2FubmVyID0gJ2RvZ2UtZXNwbG9yYScgXG4gICAgICBXSEVSRSBzY2FubmVyID0gJ2RvZ2UnXG4gICAgYCk7XG5cbiAgICAvLyBSZXZlcnQgZXh0cmFjdG9yX3N0YXR1c19lbnRpdHkgdGFibGVcbiAgICBhd2FpdCBxdWVyeVJ1bm5lci5xdWVyeShgXG4gICAgICBVUERBVEUgZXh0cmFjdG9yX3N0YXR1c19lbnRpdHkgXG4gICAgICBTRVQgc2Nhbm5lcklkID0gJ2NhcmRhbm8ta29pb3MnIFxuICAgICAgV0hFUkUgc2Nhbm5lcklkID0gJ2NhcmRhbm8nXG4gICAgYCk7XG5cbiAgICBhd2FpdCBxdWVyeVJ1bm5lci5xdWVyeShgXG4gICAgICBVUERBVEUgZXh0cmFjdG9yX3N0YXR1c19lbnRpdHkgXG4gICAgICBTRVQgc2Nhbm5lcklkID0gJ2JpdGNvaW4tZXNwbG9yYScgXG4gICAgICBXSEVSRSBzY2FubmVySWQgPSAnYml0Y29pbidcbiAgICBgKTtcblxuICAgIGF3YWl0IHF1ZXJ5UnVubmVyLnF1ZXJ5KGBcbiAgICAgIFVQREFURSBleHRyYWN0b3Jfc3RhdHVzX2VudGl0eVxuICAgICAgU0VUIHNjYW5uZXJJZCA9ICdldGhlcmV1bS1ldm0tcnBjJ1xuICAgICAgV0hFUkUgc2Nhbm5lcklkID0gJ2V0aGVyZXVtJztcbiAgICBgKTtcblxuICAgIGF3YWl0IHF1ZXJ5UnVubmVyLnF1ZXJ5KGBcbiAgICAgIFVQREFURSBleHRyYWN0b3Jfc3RhdHVzX2VudGl0eVxuICAgICAgU0VUIHNjYW5uZXJJZCA9ICdiaW5hbmNlLWV2bS1ycGMnXG4gICAgICBXSEVSRSBzY2FubmVySWQgPSAnYmluYW5jZSc7XG4gICAgYCk7XG5cbiAgICBhd2FpdCBxdWVyeVJ1bm5lci5xdWVyeShgXG4gICAgICBVUERBVEUgZXh0cmFjdG9yX3N0YXR1c19lbnRpdHkgXG4gICAgICBTRVQgc2Nhbm5lcklkID0gJ2RvZ2UtZXNwbG9yYScgXG4gICAgICBXSEVSRSBzY2FubmVySWQgPSAnZG9nZSdcbiAgICBgKTtcbiAgfVxufVxuIl19
@@ -0,0 +1,78 @@
1
+ import { AbstractLogger } from '@rosen-bridge/abstract-logger';
2
+ import { DataSource } from '@rosen-bridge/extended-typeorm';
3
+ import { AbstractNetworkConnector, Block } from '@rosen-bridge/scanner-interfaces';
4
+ import { BlockEntity } from '../../entities/blockEntity';
5
+ import { AbstractScanner } from './scanner';
6
+ declare abstract class GeneralScanner<TransactionType> extends AbstractScanner<TransactionType> {
7
+ private scannerName;
8
+ private dataSource;
9
+ private network;
10
+ private blockRetrieveGap;
11
+ private suffix?;
12
+ private heightGap;
13
+ private readonly initialHeight;
14
+ protected blockChainLastHeight: number | undefined;
15
+ name: () => string;
16
+ constructor(scannerName: string, dataSource: DataSource, initialHeight: number, network: AbstractNetworkConnector<TransactionType>, blockRetrieveGap?: number, logger?: AbstractLogger, suffix?: string | undefined, heightGap?: number);
17
+ /**
18
+ * Get the first block to process
19
+ * @returns The first block at the configured initial height
20
+ */
21
+ protected getFirstBlock: () => Promise<Block>;
22
+ /**
23
+ * function that checks if fork is happen in the blockchain or not
24
+ * @return Promise<Boolean>
25
+ */
26
+ protected isForkHappen: () => Promise<boolean>;
27
+ /**
28
+ * This method introduces delay between consecutive block processing
29
+ * operations
30
+ */
31
+ protected delayBetweenBlocksProcessing: (startTime: number) => Promise<void>;
32
+ /**
33
+ * process a block and execute all extractor on it.
34
+ * @param block
35
+ */
36
+ protected processBlock: (block: Block) => Promise<false | BlockEntity>;
37
+ /**
38
+ * process forward in scanner. get blocks and store information from
39
+ * transactions.
40
+ * @param lastSavedBlock last saved block entity in the database
41
+ */
42
+ protected stepForward: (lastSavedBlock: BlockEntity) => Promise<void>;
43
+ /**
44
+ * Step backward in blockchain and find fork point.
45
+ * and remove all forked blocks from database
46
+ */
47
+ protected stepBackward: () => Promise<void>;
48
+ /**
49
+ * Initialize the extractors with the first block
50
+ * Process and store the first block in database
51
+ * @returns
52
+ */
53
+ protected initialize: () => Promise<BlockEntity>;
54
+ /**
55
+ * Return the latest height of the blockchain
56
+ * @returns { number | undefined }
57
+ */
58
+ getBlockChainLastHeight: () => number | undefined;
59
+ /**
60
+ * Checks if any registered extractor detects an event
61
+ * within the given block height range.
62
+ *
63
+ * @param {number} fromHeight - The starting block height to check.
64
+ * @param {number} toHeight - The ending block height to check.
65
+ * @returns {Promise<boolean>} True if at least one event is found,
66
+ * false otherwise.
67
+ */
68
+ protected checkExtractorsForEvents: (fromHeight: number, toHeight: number) => Promise<boolean>;
69
+ /**
70
+ * worker function that synchronizes the database with the blockchain.
71
+ * It handles scanner initialization, fork resolution,
72
+ * step-by-step block processing,
73
+ * and fast-forwarding when no events are detected.
74
+ */
75
+ update: () => Promise<void>;
76
+ }
77
+ export { GeneralScanner };
78
+ //# sourceMappingURL=generalScanner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generalScanner.d.ts","sourceRoot":"","sources":["../../../lib/scanner/abstract/generalScanner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAE5D,OAAO,EACL,wBAAwB,EACxB,KAAK,EACN,MAAM,kCAAkC,CAAC;AAE1C,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAEzD,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAE5C,uBAAe,cAAc,CAC3B,eAAe,CACf,SAAQ,eAAe,CAAC,eAAe,CAAC;IAOtC,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,UAAU;IAElB,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,gBAAgB;IAExB,OAAO,CAAC,MAAM,CAAC;IACf,OAAO,CAAC,SAAS;IAbnB,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,SAAS,CAAC,oBAAoB,EAAE,MAAM,GAAG,SAAS,CAAa;IAE/D,IAAI,eAAmE;gBAG7D,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,UAAU,EAC9B,aAAa,EAAE,MAAM,EACb,OAAO,EAAE,wBAAwB,CAAC,eAAe,CAAC,EAClD,gBAAgB,SAAI,EAC5B,MAAM,CAAC,EAAE,cAAc,EACf,MAAM,CAAC,EAAE,MAAM,YAAA,EACf,SAAS,SAAI;IAgBvB;;;OAGG;IACH,SAAS,CAAC,aAAa,QAAO,OAAO,CAAC,KAAK,CAAC,CAE1C;IAEF;;;OAGG;IACH,SAAS,CAAC,YAAY,QAAa,OAAO,CAAC,OAAO,CAAC,CAUjD;IAEF;;;OAGG;IACH,SAAS,CAAC,4BAA4B,GAAU,WAAW,MAAM,mBAK/D;IAEF;;;OAGG;IACH,SAAS,CAAC,YAAY,GAAU,OAAO,KAAK,kCA0B1C;IAEF;;;;OAIG;IACH,SAAS,CAAC,WAAW,GAAU,gBAAgB,WAAW,mBAuCxD;IAEF;;;OAGG;IACH,SAAS,CAAC,YAAY,sBAepB;IAEF;;;;OAIG;IACH,SAAS,CAAC,UAAU,6BAYlB;IAEF;;;OAGG;IACI,uBAAuB,QAAO,MAAM,GAAG,SAAS,CAC3B;IAE5B;;;;;;;;OAQG;IACH,SAAS,CAAC,wBAAwB,GAChC,YAAY,MAAM,EAClB,UAAU,MAAM,KACf,OAAO,CAAC,OAAO,CAAC,CASjB;IAEF;;;;;OAKG;IACH,MAAM,sBAwBJ;CACH;AAED,OAAO,EAAE,cAAc,EAAE,CAAC"}
@@ -0,0 +1,210 @@
1
+ import JsonBI from '@rosen-bridge/json-bigint';
2
+ import { BlockDbAction } from '../action';
3
+ import { AbstractScanner } from './scanner';
4
+ class GeneralScanner extends AbstractScanner {
5
+ scannerName;
6
+ dataSource;
7
+ network;
8
+ blockRetrieveGap;
9
+ suffix;
10
+ heightGap;
11
+ initialHeight;
12
+ blockChainLastHeight = undefined;
13
+ name = () => this.scannerName + (this.suffix ? `-${this.suffix}` : '');
14
+ constructor(scannerName, dataSource, initialHeight, network, blockRetrieveGap = 0, logger, suffix, heightGap = 1) {
15
+ super(logger);
16
+ this.scannerName = scannerName;
17
+ this.dataSource = dataSource;
18
+ this.network = network;
19
+ this.blockRetrieveGap = blockRetrieveGap;
20
+ this.suffix = suffix;
21
+ this.heightGap = heightGap;
22
+ /**
23
+ * In order to keep the scanners functionalities consistent, we add config
24
+ * `initialHeight` by one so that it matches how other scanners work.
25
+ */
26
+ this.initialHeight = initialHeight + 1;
27
+ this.suffix = suffix;
28
+ this.action = new BlockDbAction(this.dataSource, this.name(), this.logger.child('BlockDbAction'));
29
+ }
30
+ /**
31
+ * Get the first block to process
32
+ * @returns The first block at the configured initial height
33
+ */
34
+ getFirstBlock = () => {
35
+ return this.network.getBlockAtHeight(this.initialHeight);
36
+ };
37
+ /**
38
+ * function that checks if fork is happen in the blockchain or not
39
+ * @return Promise<Boolean>
40
+ */
41
+ isForkHappen = async () => {
42
+ const lastSavedBlock = await this.action.getLastSavedBlock();
43
+ if (lastSavedBlock !== undefined) {
44
+ const lastSavedBlockFromNetwork = await this.network.getBlockAtHeight(lastSavedBlock.height);
45
+ return lastSavedBlockFromNetwork.hash !== lastSavedBlock.hash;
46
+ }
47
+ else {
48
+ return false;
49
+ }
50
+ };
51
+ /**
52
+ * This method introduces delay between consecutive block processing
53
+ * operations
54
+ */
55
+ delayBetweenBlocksProcessing = async (startTime) => {
56
+ const spentTime = new Date().getTime() - startTime;
57
+ await new Promise((resolve) => setTimeout(() => resolve(null), this.blockRetrieveGap - spentTime));
58
+ };
59
+ /**
60
+ * process a block and execute all extractor on it.
61
+ * @param block
62
+ */
63
+ processBlock = async (block) => {
64
+ const startTime = new Date().getTime();
65
+ this.logger.debug(`Processing block at height [${block.height}] in scanner ${this.name()}`);
66
+ const txs = await this.network.getBlockTxs(block.hash, block.height);
67
+ if (block.txCount) {
68
+ if (txs.length != block.txCount) {
69
+ this.logger.debug(`Aborting block process with hash [${block.hash}] expected to have
70
+ ${block.txCount} transactions but had ${txs.length}`);
71
+ return false;
72
+ }
73
+ this.logger.debug(`processing ${block.txCount} transactions of block with hash [${block.hash}]`);
74
+ }
75
+ const result = await this.processBlockTransactions(block, txs);
76
+ // Spending time between block fetches if the setting is enabled
77
+ if (this.blockRetrieveGap)
78
+ await this.delayBetweenBlocksProcessing(startTime);
79
+ return result;
80
+ };
81
+ /**
82
+ * process forward in scanner. get blocks and store information from
83
+ * transactions.
84
+ * @param lastSavedBlock last saved block entity in the database
85
+ */
86
+ stepForward = async (lastSavedBlock) => {
87
+ const currentHeight = await this.network.getCurrentHeight();
88
+ const firstBlock = await this.action.getFirstSavedBlock();
89
+ if (!firstBlock || firstBlock.height >= currentHeight) {
90
+ return;
91
+ }
92
+ let step = Math.min(this.heightGap, currentHeight - lastSavedBlock.height);
93
+ let stopHeight = lastSavedBlock.height + step;
94
+ for (let height = lastSavedBlock.height; height < currentHeight;) {
95
+ if (step > 1 &&
96
+ (await this.checkExtractorsForEvents(height, height + step))) {
97
+ stopHeight = height + step;
98
+ step = 1;
99
+ }
100
+ height += step;
101
+ const block = await this.network.getBlockAtHeight(height);
102
+ if (block.parentHash != lastSavedBlock.hash && step === 1) {
103
+ this.logger.debug(`Invalid block at height ${lastSavedBlock.height + 1}. Block info
104
+ is [${JsonBI.stringify(block)} and the expected parent hash is [${lastSavedBlock.hash}]`);
105
+ break;
106
+ }
107
+ const savedBlock = await this.processBlock(block);
108
+ if (typeof savedBlock === 'boolean') {
109
+ break;
110
+ }
111
+ else {
112
+ lastSavedBlock = savedBlock;
113
+ }
114
+ if (height == stopHeight) {
115
+ step = Math.min(this.heightGap, currentHeight - height);
116
+ stopHeight = height + step;
117
+ }
118
+ }
119
+ };
120
+ /**
121
+ * Step backward in blockchain and find fork point.
122
+ * and remove all forked blocks from database
123
+ */
124
+ stepBackward = async () => {
125
+ let block = await this.action.getLastSavedBlock();
126
+ while (block) {
127
+ const blockFromNetwork = await this.network.getBlockAtHeight(block.height);
128
+ if (blockFromNetwork.hash === block.hash &&
129
+ block.parentHash === blockFromNetwork.parentHash) {
130
+ return;
131
+ }
132
+ await this.forkBlock(block.height);
133
+ block = await this.action.getLastSavedBlock();
134
+ }
135
+ };
136
+ /**
137
+ * Initialize the extractors with the first block
138
+ * Process and store the first block in database
139
+ * @returns
140
+ */
141
+ initialize = async () => {
142
+ const block = await this.getFirstBlock();
143
+ await this.verifyExtractorsInitialization({
144
+ height: block.height - 1,
145
+ hash: block.parentHash,
146
+ });
147
+ await this.processBlock(block);
148
+ const entity = await this.action.getFirstSavedBlock();
149
+ if (entity === undefined) {
150
+ throw new Error('Can not store block in database');
151
+ }
152
+ return entity;
153
+ };
154
+ /**
155
+ * Return the latest height of the blockchain
156
+ * @returns { number | undefined }
157
+ */
158
+ getBlockChainLastHeight = () => this.blockChainLastHeight;
159
+ /**
160
+ * Checks if any registered extractor detects an event
161
+ * within the given block height range.
162
+ *
163
+ * @param {number} fromHeight - The starting block height to check.
164
+ * @param {number} toHeight - The ending block height to check.
165
+ * @returns {Promise<boolean>} True if at least one event is found,
166
+ * false otherwise.
167
+ */
168
+ checkExtractorsForEvents = async (fromHeight, toHeight) => {
169
+ for (const extractor of this.extractors) {
170
+ const hasEvent = await extractor.hasEventInHeightRange(fromHeight, toHeight);
171
+ if (hasEvent)
172
+ return true;
173
+ }
174
+ return false;
175
+ };
176
+ /**
177
+ * worker function that synchronizes the database with the blockchain.
178
+ * It handles scanner initialization, fork resolution,
179
+ * step-by-step block processing,
180
+ * and fast-forwarding when no events are detected.
181
+ */
182
+ update = async () => {
183
+ try {
184
+ const latestHeight = await this.network.getCurrentHeight();
185
+ if (!this.blockChainLastHeight ||
186
+ this.blockChainLastHeight < latestHeight)
187
+ this.blockChainLastHeight = latestHeight;
188
+ let lastSavedBlock = await this.action.getLastSavedBlock();
189
+ if (!lastSavedBlock) {
190
+ lastSavedBlock = await this.initialize();
191
+ }
192
+ else
193
+ await this.verifyExtractorsInitialization(lastSavedBlock);
194
+ if (!(await this.isForkHappen())) {
195
+ await this.stepForward(lastSavedBlock);
196
+ }
197
+ else {
198
+ await this.stepBackward();
199
+ }
200
+ }
201
+ catch (e) {
202
+ this.logger.error(`An error occurred during update process. ${e}`);
203
+ if (e instanceof Error && e.stack) {
204
+ this.logger.error(`error stack: ${e.stack}`);
205
+ }
206
+ }
207
+ };
208
+ }
209
+ export { GeneralScanner };
210
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2VuZXJhbFNjYW5uZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9saWIvc2Nhbm5lci9hYnN0cmFjdC9nZW5lcmFsU2Nhbm5lci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxPQUFPLE1BQU0sTUFBTSwyQkFBMkIsQ0FBQztBQU8vQyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQzFDLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFFNUMsTUFBZSxjQUViLFNBQVEsZUFBZ0M7SUFPOUI7SUFDQTtJQUVBO0lBQ0E7SUFFQTtJQUNBO0lBYk8sYUFBYSxDQUFTO0lBQzdCLG9CQUFvQixHQUF1QixTQUFTLENBQUM7SUFFL0QsSUFBSSxHQUFHLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxXQUFXLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7SUFFdkUsWUFDVSxXQUFtQixFQUNuQixVQUFzQixFQUM5QixhQUFxQixFQUNiLE9BQWtELEVBQ2xELG1CQUFtQixDQUFDLEVBQzVCLE1BQXVCLEVBQ2YsTUFBZSxFQUNmLFlBQVksQ0FBQztRQUVyQixLQUFLLENBQUMsTUFBTSxDQUFDLENBQUM7UUFUTixnQkFBVyxHQUFYLFdBQVcsQ0FBUTtRQUNuQixlQUFVLEdBQVYsVUFBVSxDQUFZO1FBRXRCLFlBQU8sR0FBUCxPQUFPLENBQTJDO1FBQ2xELHFCQUFnQixHQUFoQixnQkFBZ0IsQ0FBSTtRQUVwQixXQUFNLEdBQU4sTUFBTSxDQUFTO1FBQ2YsY0FBUyxHQUFULFNBQVMsQ0FBSTtRQUdyQjs7O1dBR0c7UUFDSCxJQUFJLENBQUMsYUFBYSxHQUFHLGFBQWEsR0FBRyxDQUFDLENBQUM7UUFDdkMsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7UUFDckIsSUFB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WUFDM0QsSUFDRSxDQUFDLElBQUksQ0FBQyxvQkFBb0I7Z0JBQzFCLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxZQUFZO2dCQUV4QyxJQUFJLENBQUMsb0JBQW9CLEdBQUcsWUFBWSxDQUFDO1lBRTNDLElBQUksY0FBYyxHQUFHLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1lBQzNELElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztnQkFDcEIsY0FBYyxHQUFHLE1BQU0sSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQzNDLENBQUM7O2dCQUFNLE1BQU0sSUFBSSxDQUFDLDhCQUE4QixDQUFDLGNBQWMsQ0FBQyxDQUFDO1lBQ2pFLElBQUksQ0FBQyxDQUFDLE1BQU0sSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDLEVBQUUsQ0FBQztnQkFDakMsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLGNBQWMsQ0FBQyxDQUFDO1lBQ3pDLENBQUM7aUJBQU0sQ0FBQztnQkFDTixNQUFNLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUM1QixDQUFDO1FBQ0gsQ0FBQztRQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDWCxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyw0Q0FBNEMsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNuRSxJQUFJLENBQUMsWUFBWSxLQUFLLElBQUksQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUNsQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUM7WUFDL0MsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDLENBQUM7Q0FDSDtBQUVELE9BQU8sRUFBRSxjQUFjLEVBQUUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFic3RyYWN0TG9nZ2VyIH0gZnJvbSAnQHJvc2VuLWJyaWRnZS9hYnN0cmFjdC1sb2dnZXInO1xuaW1wb3J0IHsgRGF0YVNvdXJjZSB9IGZyb20gJ0Byb3Nlbi1icmlkZ2UvZXh0ZW5kZWQtdHlwZW9ybSc7XG5pbXBvcnQgSnNvbkJJIGZyb20gJ0Byb3Nlbi1icmlkZ2UvanNvbi1iaWdpbnQnO1xuaW1wb3J0IHtcbiAgQWJzdHJhY3ROZXR3b3JrQ29ubmVjdG9yLFxuICBCbG9jayxcbn0gZnJvbSAnQHJvc2VuLWJyaWRnZS9zY2FubmVyLWludGVyZmFjZXMnO1xuXG5pbXBvcnQgeyBCbG9ja0VudGl0eSB9IGZyb20gJy4uLy4uL2VudGl0aWVzL2Jsb2NrRW50aXR5JztcbmltcG9ydCB7IEJsb2NrRGJBY3Rpb24gfSBmcm9tICcuLi9hY3Rpb24nO1xuaW1wb3J0IHsgQWJzdHJhY3RTY2FubmVyIH0gZnJvbSAnLi9zY2FubmVyJztcblxuYWJzdHJhY3QgY2xhc3MgR2VuZXJhbFNjYW5uZXI8XG4gIFRyYW5zYWN0aW9uVHlwZSxcbj4gZXh0ZW5kcyBBYnN0cmFjdFNjYW5uZXI8VHJhbnNhY3Rpb25UeXBlPiB7XG4gIHByaXZhdGUgcmVhZG9ubHkgaW5pdGlhbEhlaWdodDogbnVtYmVyO1xuICBwcm90ZWN0ZWQgYmxvY2tDaGFpbkxhc3RIZWlnaHQ6IG51bWJlciB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcblxuICBuYW1lID0gKCkgPT4gdGhpcy5zY2FubmVyTmFtZSArICh0aGlzLnN1ZmZpeCA/IGAtJHt0aGlzLnN1ZmZpeH1gIDogJycpO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgc2Nhbm5lck5hbWU6IHN0cmluZyxcbiAgICBwcml2YXRlIGRhdGFTb3VyY2U6IERhdGFTb3VyY2UsXG4gICAgaW5pdGlhbEhlaWdodDogbnVtYmVyLFxuICAgIHByaXZhdGUgbmV0d29yazogQWJzdHJhY3ROZXR3b3JrQ29ubmVjdG9yPFRyYW5zYWN0aW9uVHlwZT4sXG4gICAgcHJpdmF0ZSBibG9ja1JldHJpZXZlR2FwID0gMCxcbiAgICBsb2dnZXI/OiBBYnN0cmFjdExvZ2dlcixcbiAgICBwcml2YXRlIHN1ZmZpeD86IHN0cmluZyxcbiAgICBwcml2YXRlIGhlaWdodEdhcCA9IDEsXG4gICkge1xuICAgIHN1cGVyKGxvZ2dlcik7XG4gICAgLyoqXG4gICAgICogSW4gb3JkZXIgdG8ga2VlcCB0aGUgc2Nhbm5lcnMgZnVuY3Rpb25hbGl0aWVzIGNvbnNpc3RlbnQsIHdlIGFkZCBjb25maWdcbiAgICAgKiBgaW5pdGlhbEhlaWdodGAgYnkgb25lIHNvIHRoYXQgaXQgbWF0Y2hlcyBob3cgb3RoZXIgc2Nhbm5lcnMgd29yay5cbiAgICAgKi9cbiAgICB0aGlzLmluaXRpYWxIZWlnaHQgPSBpbml0aWFsSGVpZ2h0ICsgMTtcbiAgICB0aGlzLnN1ZmZpeCA9IHN1ZmZpeDtcbiAgICB0aGlzLmFjdGlvbiA9IG5ldyBCbG9ja0RiQWN0aW9uKFxuICAgICAgdGhpcy5kYXRhU291cmNlLFxuICAgICAgdGhpcy5uYW1lKCksXG4gICAgICB0aGlzLmxvZ2dlci5jaGlsZCgnQmxvY2tEYkFjdGlvbicpLFxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBmaXJzdCBibG9jayB0byBwcm9jZXNzXG4gICAqIEByZXR1cm5zIFRoZSBmaXJzdCBibG9jayBhdCB0aGUgY29uZmlndXJlZCBpbml0aWFsIGhlaWdodFxuICAgKi9cbiAgcHJvdGVjdGVkIGdldEZpcnN0QmxvY2sgPSAoKTogUHJvbWlzZTxCbG9jaz4gPT4ge1xuICAgIHJldHVybiB0aGlzLm5ldHdvcmsuZ2V0QmxvY2tBdEhlaWdodCh0aGlzLmluaXRpYWxIZWlnaHQpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBmdW5jdGlvbiB0aGF0IGNoZWNrcyBpZiBmb3JrIGlzIGhhcHBlbiBpbiB0aGUgYmxvY2tjaGFpbiBvciBub3RcbiAgICogQHJldHVybiBQcm9taXNlPEJvb2xlYW4+XG4gICAqL1xuICBwcm90ZWN0ZWQgaXNGb3JrSGFwcGVuID0gYXN5bmMgKCk6IFByb21pc2U8Ym9vbGVhbj4gPT4ge1xuICAgIGNvbnN0IGxhc3RTYXZlZEJsb2NrID0gYXdhaXQgdGhpcy5hY3Rpb24uZ2V0TGFzdFNhdmVkQmxvY2soKTtcbiAgICBpZiAobGFzdFNhdmVkQmxvY2sgIT09IHVuZGVmaW5lZCkge1xuICAgICAgY29uc3QgbGFzdFNhdmVkQmxvY2tGcm9tTmV0d29yayA9IGF3YWl0IHRoaXMubmV0d29yay5nZXRCbG9ja0F0SGVpZ2h0KFxuICAgICAgICBsYXN0U2F2ZWRCbG9jay5oZWlnaHQsXG4gICAgICApO1xuICAgICAgcmV0dXJuIGxhc3RTYXZlZEJsb2NrRnJvbU5ldHdvcmsuaGFzaCAhPT0gbGFzdFNhdmVkQmxvY2suaGFzaDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfTtcblxuICAvKipcbiAgICogVGhpcyBtZXRob2QgaW50cm9kdWNlcyBkZWxheSBiZXR3ZWVuIGNvbnNlY3V0aXZlIGJsb2NrIHByb2Nlc3NpbmdcbiAgICogb3BlcmF0aW9uc1xuICAgKi9cbiAgcHJvdGVjdGVkIGRlbGF5QmV0d2VlbkJsb2Nrc1Byb2Nlc3NpbmcgPSBhc3luYyAoc3RhcnRUaW1lOiBudW1iZXIpID0+IHtcbiAgICBjb25zdCBzcGVudFRpbWUgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKSAtIHN0YXJ0VGltZTtcbiAgICBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT5cbiAgICAgIHNldFRpbWVvdXQoKCkgPT4gcmVzb2x2ZShudWxsKSwgdGhpcy5ibG9ja1JldHJpZXZlR2FwIC0gc3BlbnRUaW1lKSxcbiAgICApO1xuICB9O1xuXG4gIC8qKlxuICAgKiBwcm9jZXNzIGEgYmxvY2sgYW5kIGV4ZWN1dGUgYWxsIGV4dHJhY3RvciBvbiBpdC5cbiAgICogQHBhcmFtIGJsb2NrXG4gICAqL1xuICBwcm90ZWN0ZWQgcHJvY2Vzc0Jsb2NrID0gYXN5bmMgKGJsb2NrOiBCbG9jaykgPT4ge1xuICAgIGNvbnN0IHN0YXJ0VGltZSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuICAgIHRoaXMubG9nZ2VyLmRlYnVnKFxuICAgICAgYFByb2Nlc3NpbmcgYmxvY2sgYXQgaGVpZ2h0IFske2Jsb2NrLmhlaWdodH1dIGluIHNjYW5uZXIgJHt0aGlzLm5hbWUoKX1gLFxuICAgICk7XG4gICAgY29uc3QgdHhzID0gYXdhaXQgdGhpcy5uZXR3b3JrLmdldEJsb2NrVHhzKGJsb2NrLmhhc2gsIGJsb2NrLmhlaWdodCk7XG4gICAgaWYgKGJsb2NrLnR4Q291bnQpIHtcbiAgICAgIGlmICh0eHMubGVuZ3RoICE9IGJsb2NrLnR4Q291bnQpIHtcbiAgICAgICAgdGhpcy5sb2dnZXIuZGVidWcoXG4gICAgICAgICAgYEFib3J0aW5nIGJsb2NrIHByb2Nlc3Mgd2l0aCBoYXNoIFske2Jsb2NrLmhhc2h9XSBleHBlY3RlZCB0byBoYXZlIFxuICAgICAgICAgICR7YmxvY2sudHhDb3VudH0gdHJhbnNhY3Rpb25zIGJ1dCBoYWQgJHt0eHMubGVuZ3RofWAsXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKFxuICAgICAgICBgcHJvY2Vzc2luZyAke2Jsb2NrLnR4Q291bnR9IHRyYW5zYWN0aW9ucyBvZiBibG9jayB3aXRoIGhhc2ggWyR7YmxvY2suaGFzaH1dYCxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5wcm9jZXNzQmxvY2tUcmFuc2FjdGlvbnMoYmxvY2ssIHR4cyk7XG5cbiAgICAvLyBTcGVuZGluZyB0aW1lIGJldHdlZW4gYmxvY2sgZmV0Y2hlcyBpZiB0aGUgc2V0dGluZyBpcyBlbmFibGVkXG4gICAgaWYgKHRoaXMuYmxvY2tSZXRyaWV2ZUdhcClcbiAgICAgIGF3YWl0IHRoaXMuZGVsYXlCZXR3ZWVuQmxvY2tzUHJvY2Vzc2luZyhzdGFydFRpbWUpO1xuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfTtcblxuICAvKipcbiAgICogcHJvY2VzcyBmb3J3YXJkIGluIHNjYW5uZXIuIGdldCBibG9ja3MgYW5kIHN0b3JlIGluZm9ybWF0aW9uIGZyb21cbiAgICogdHJhbnNhY3Rpb25zLlxuICAgKiBAcGFyYW0gbGFzdFNhdmVkQmxvY2sgbGFzdCBzYXZlZCBibG9jayBlbnRpdHkgaW4gdGhlIGRhdGFiYXNlXG4gICAqL1xuICBwcm90ZWN0ZWQgc3RlcEZvcndhcmQgPSBhc3luYyAobGFzdFNhdmVkQmxvY2s6IEJsb2NrRW50aXR5KSA9PiB7XG4gICAgY29uc3QgY3VycmVudEhlaWdodCA9IGF3YWl0IHRoaXMubmV0d29yay5nZXRDdXJyZW50SGVpZ2h0KCk7XG4gICAgY29uc3QgZmlyc3RCbG9jayA9IGF3YWl0IHRoaXMuYWN0aW9uLmdldEZpcnN0U2F2ZWRCbG9jaygpO1xuXG4gICAgaWYgKCFmaXJzdEJsb2NrIHx8IGZpcnN0QmxvY2suaGVpZ2h0ID49IGN1cnJlbnRIZWlnaHQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgbGV0IHN0ZXAgPSBNYXRoLm1pbih0aGlzLmhlaWdodEdhcCwgY3VycmVudEhlaWdodCAtIGxhc3RTYXZlZEJsb2NrLmhlaWdodCk7XG4gICAgbGV0IHN0b3BIZWlnaHQgPSBsYXN0U2F2ZWRCbG9jay5oZWlnaHQgKyBzdGVwO1xuICAgIGZvciAobGV0IGhlaWdodCA9IGxhc3RTYXZlZEJsb2NrLmhlaWdodDsgaGVpZ2h0IDwgY3VycmVudEhlaWdodDsgKSB7XG4gICAgICBpZiAoXG4gICAgICAgIHN0ZXAgPiAxICYmXG4gICAgICAgIChhd2FpdCB0aGlzLmNoZWNrRXh0cmFjdG9yc0ZvckV2ZW50cyhoZWlnaHQsIGhlaWdodCArIHN0ZXApKVxuICAgICAgKSB7XG4gICAgICAgIHN0b3BIZWlnaHQgPSBoZWlnaHQgKyBzdGVwO1xuICAgICAgICBzdGVwID0gMTtcbiAgICAgIH1cbiAgICAgIGhlaWdodCArPSBzdGVwO1xuICAgICAgY29uc3QgYmxvY2sgPSBhd2FpdCB0aGlzLm5ldHdvcmsuZ2V0QmxvY2tBdEhlaWdodChoZWlnaHQpO1xuICAgICAgaWYgKGJsb2NrLnBhcmVudEhhc2ggIT0gbGFzdFNhdmVkQmxvY2suaGFzaCAmJiBzdGVwID09PSAxKSB7XG4gICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKFxuICAgICAgICAgIGBJbnZhbGlkIGJsb2NrIGF0IGhlaWdodCAke2xhc3RTYXZlZEJsb2NrLmhlaWdodCArIDF9LiBCbG9jayBpbmZvIFxuICAgICAgICAgICAgaXMgWyR7SnNvbkJJLnN0cmluZ2lmeShcbiAgICAgICAgICAgICAgYmxvY2ssXG4gICAgICAgICAgICApfSBhbmQgdGhlIGV4cGVjdGVkIHBhcmVudCBoYXNoIGlzIFske2xhc3RTYXZlZEJsb2NrLmhhc2h9XWAsXG4gICAgICAgICk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY29uc3Qgc2F2ZWRCbG9jayA9IGF3YWl0IHRoaXMucHJvY2Vzc0Jsb2NrKGJsb2NrKTtcbiAgICAgIGlmICh0eXBlb2Ygc2F2ZWRCbG9jayA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbGFzdFNhdmVkQmxvY2sgPSBzYXZlZEJsb2NrO1xuICAgICAgfVxuICAgICAgaWYgKGhlaWdodCA9PSBzdG9wSGVpZ2h0KSB7XG4gICAgICAgIHN0ZXAgPSBNYXRoLm1pbih0aGlzLmhlaWdodEdhcCwgY3VycmVudEhlaWdodCAtIGhlaWdodCk7XG4gICAgICAgIHN0b3BIZWlnaHQgPSBoZWlnaHQgKyBzdGVwO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICAvKipcbiAgICogU3RlcCBiYWNrd2FyZCBpbiBibG9ja2NoYWluIGFuZCBmaW5kIGZvcmsgcG9pbnQuXG4gICAqIGFuZCByZW1vdmUgYWxsIGZvcmtlZCBibG9ja3MgZnJvbSBkYXRhYmFzZVxuICAgKi9cbiAgcHJvdGVjdGVkIHN0ZXBCYWNrd2FyZCA9IGFzeW5jICgpID0+IHtcbiAgICBsZXQgYmxvY2sgPSBhd2FpdCB0aGlzLmFjdGlvbi5nZXRMYXN0U2F2ZWRCbG9jaygpO1xuICAgIHdoaWxlIChibG9jaykge1xuICAgICAgY29uc3QgYmxvY2tGcm9tTmV0d29yayA9IGF3YWl0IHRoaXMubmV0d29yay5nZXRCbG9ja0F0SGVpZ2h0KFxuICAgICAgICBibG9jay5oZWlnaHQsXG4gICAgICApO1xuICAgICAgaWYgKFxuICAgICAgICBibG9ja0Zyb21OZXR3b3JrLmhhc2ggPT09IGJsb2NrLmhhc2ggJiZcbiAgICAgICAgYmxvY2sucGFyZW50SGFzaCA9PT0gYmxvY2tGcm9tTmV0d29yay5wYXJlbnRIYXNoXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgYXdhaXQgdGhpcy5mb3JrQmxvY2soYmxvY2suaGVpZ2h0KTtcbiAgICAgIGJsb2NrID0gYXdhaXQgdGhpcy5hY3Rpb24uZ2V0TGFzdFNhdmVkQmxvY2soKTtcbiAgICB9XG4gIH07XG5cbiAgLyoqXG4gICAqIEluaXRpYWxpemUgdGhlIGV4dHJhY3RvcnMgd2l0aCB0aGUgZmlyc3QgYmxvY2tcbiAgICogUHJvY2VzcyBhbmQgc3RvcmUgdGhlIGZpcnN0IGJsb2NrIGluIGRhdGFiYXNlXG4gICAqIEByZXR1cm5zXG4gICAqL1xuICBwcm90ZWN0ZWQgaW5pdGlhbGl6ZSA9IGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBibG9jayA9IGF3YWl0IHRoaXMuZ2V0Rmlyc3RCbG9jaygpO1xuICAgIGF3YWl0IHRoaXMudmVyaWZ5RXh0cmFjdG9yc0luaXRpYWxpemF0aW9uKHtcbiAgICAgIGhlaWdodDogYmxvY2suaGVpZ2h0IC0gMSxcbiAgICAgIGhhc2g6IGJsb2NrLnBhcmVudEhhc2gsXG4gICAgfSk7XG4gICAgYXdhaXQgdGhpcy5wcm9jZXNzQmxvY2soYmxvY2spO1xuICAgIGNvbnN0IGVudGl0eSA9IGF3YWl0IHRoaXMuYWN0aW9uLmdldEZpcnN0U2F2ZWRCbG9jaygpO1xuICAgIGlmIChlbnRpdHkgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYW4gbm90IHN0b3JlIGJsb2NrIGluIGRhdGFiYXNlJyk7XG4gICAgfVxuICAgIHJldHVybiBlbnRpdHk7XG4gIH07XG5cbiAgLyoqXG4gICAqIFJldHVybiB0aGUgbGF0ZXN0IGhlaWdodCBvZiB0aGUgYmxvY2tjaGFpblxuICAgKiBAcmV0dXJucyB7IG51bWJlciB8IHVuZGVmaW5lZCB9XG4gICAqL1xuICBwdWJsaWMgZ2V0QmxvY2tDaGFpbkxhc3RIZWlnaHQgPSAoKTogbnVtYmVyIHwgdW5kZWZpbmVkID0+XG4gICAgdGhpcy5ibG9ja0NoYWluTGFzdEhlaWdodDtcblxuICAvKipcbiAgICogQ2hlY2tzIGlmIGFueSByZWdpc3RlcmVkIGV4dHJhY3RvciBkZXRlY3RzIGFuIGV2ZW50XG4gICAqIHdpdGhpbiB0aGUgZ2l2ZW4gYmxvY2sgaGVpZ2h0IHJhbmdlLlxuICAgKlxuICAgKiBAcGFyYW0ge251bWJlcn0gZnJvbUhlaWdodCAtIFRoZSBzdGFydGluZyBibG9jayBoZWlnaHQgdG8gY2hlY2suXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB0b0hlaWdodCAtIFRoZSBlbmRpbmcgYmxvY2sgaGVpZ2h0IHRvIGNoZWNrLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxib29sZWFuPn0gVHJ1ZSBpZiBhdCBsZWFzdCBvbmUgZXZlbnQgaXMgZm91bmQsXG4gICAqIGZhbHNlIG90aGVyd2lzZS5cbiAgICovXG4gIHByb3RlY3RlZCBjaGVja0V4dHJhY3RvcnNGb3JFdmVudHMgPSBhc3luYyAoXG4gICAgZnJvbUhlaWdodDogbnVtYmVyLFxuICAgIHRvSGVpZ2h0OiBudW1iZXIsXG4gICk6IFByb21pc2U8Ym9vbGVhbj4gPT4ge1xuICAgIGZvciAoY29uc3QgZXh0cmFjdG9yIG9mIHRoaXMuZXh0cmFjdG9ycykge1xuICAgICAgY29uc3QgaGFzRXZlbnQgPSBhd2FpdCBleHRyYWN0b3IuaGFzRXZlbnRJbkhlaWdodFJhbmdlKFxuICAgICAgICBmcm9tSGVpZ2h0LFxuICAgICAgICB0b0hlaWdodCxcbiAgICAgICk7XG4gICAgICBpZiAoaGFzRXZlbnQpIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH07XG5cbiAgLyoqXG4gICAqIHdvcmtlciBmdW5jdGlvbiB0aGF0IHN5bmNocm9uaXplcyB0aGUgZGF0YWJhc2Ugd2l0aCB0aGUgYmxvY2tjaGFpbi5cbiAgICogSXQgaGFuZGxlcyBzY2FubmVyIGluaXRpYWxpemF0aW9uLCBmb3JrIHJlc29sdXRpb24sXG4gICAqIHN0ZXAtYnktc3RlcCBibG9jayBwcm9jZXNzaW5nLFxuICAgKiBhbmQgZmFzdC1mb3J3YXJkaW5nIHdoZW4gbm8gZXZlbnRzIGFyZSBkZXRlY3RlZC5cbiAgICovXG4gIHVwZGF0ZSA9IGFzeW5jICgpID0+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgbGF0ZXN0SGVpZ2h0ID0gYXdhaXQgdGhpcy5uZXR3b3JrLmdldEN1cnJlbnRIZWlnaHQoKTtcbiAgICAgIGlmIChcbiAgICAgICAgIXRoaXMuYmxvY2tDaGFpbkxhc3RIZWlnaHQgfHxcbiAgICAgICAgdGhpcy5ibG9ja0NoYWluTGFzdEhlaWdodCA8IGxhdGVzdEhlaWdodFxuICAgICAgKVxuICAgICAgICB0aGlzLmJsb2NrQ2hhaW5MYXN0SGVpZ2h0ID0gbGF0ZXN0SGVpZ2h0O1xuXG4gICAgICBsZXQgbGFzdFNhdmVkQmxvY2sgPSBhd2FpdCB0aGlzLmFjdGlvbi5nZXRMYXN0U2F2ZWRCbG9jaygpO1xuICAgICAgaWYgKCFsYXN0U2F2ZWRCbG9jaykge1xuICAgICAgICBsYXN0U2F2ZWRCbG9jayA9IGF3YWl0IHRoaXMuaW5pdGlhbGl6ZSgpO1xuICAgICAgfSBlbHNlIGF3YWl0IHRoaXMudmVyaWZ5RXh0cmFjdG9yc0luaXRpYWxpemF0aW9uKGxhc3RTYXZlZEJsb2NrKTtcbiAgICAgIGlmICghKGF3YWl0IHRoaXMuaXNGb3JrSGFwcGVuKCkpKSB7XG4gICAgICAgIGF3YWl0IHRoaXMuc3RlcEZvcndhcmQobGFzdFNhdmVkQmxvY2spO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYXdhaXQgdGhpcy5zdGVwQmFja3dhcmQoKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB0aGlzLmxvZ2dlci5lcnJvcihgQW4gZXJyb3Igb2NjdXJyZWQgZHVyaW5nIHVwZGF0ZSBwcm9jZXNzLiAke2V9YCk7XG4gICAgICBpZiAoZSBpbnN0YW5jZW9mIEVycm9yICYmIGUuc3RhY2spIHtcbiAgICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoYGVycm9yIHN0YWNrOiAke2Uuc3RhY2t9YCk7XG4gICAgICB9XG4gICAgfVxuICB9O1xufVxuXG5leHBvcnQgeyBHZW5lcmFsU2Nhbm5lciB9O1xuIl19
@@ -0,0 +1,49 @@
1
+ import { AbstractExtractor } from '@rosen-bridge/abstract-extractor';
2
+ import { AbstractLogger } from '@rosen-bridge/abstract-logger';
3
+ import { ObjectLiteral } from '@rosen-bridge/extended-typeorm';
4
+ import { Block, BlockInfo } from '@rosen-bridge/scanner-interfaces';
5
+ import { Mutex } from '@rosen-bridge/semaphore';
6
+ import { BlockDbAction } from '../action';
7
+ export declare abstract class AbstractScanner<TransactionType> {
8
+ action: BlockDbAction;
9
+ extractors: Array<AbstractExtractor<TransactionType, ObjectLiteral>>;
10
+ newExtractors: Array<AbstractExtractor<TransactionType, ObjectLiteral>>;
11
+ logger: AbstractLogger;
12
+ initializeMutex: Mutex;
13
+ constructor(logger?: AbstractLogger);
14
+ abstract name: () => string;
15
+ /**
16
+ * fork blocks from specific height from scanner.
17
+ * @param height: selected height
18
+ */
19
+ protected forkBlock: (height: number) => Promise<void>;
20
+ /**
21
+ * process a block and all of its transactions. store any information into database
22
+ * @param block: selected block
23
+ * @param transactions: list of transaction for selected block
24
+ */
25
+ protected processBlockTransactions: (block: Block, transactions: Array<TransactionType>) => Promise<false | import("../..").BlockEntity>;
26
+ /**
27
+ * register a nre extractor to scanner.
28
+ * @param extractor
29
+ */
30
+ registerExtractor: (extractor: AbstractExtractor<TransactionType, ObjectLiteral>) => Promise<void>;
31
+ /**
32
+ * remove an extractor from scanner
33
+ * @param extractor
34
+ */
35
+ removeExtractor: (extractor: AbstractExtractor<TransactionType, ObjectLiteral>) => Promise<void>;
36
+ /**
37
+ * Initialize all specified extractors and store the updated status
38
+ * @param extractorIds
39
+ * @param height
40
+ */
41
+ private initializeExtractors;
42
+ /**
43
+ * Initializes the extractors if they're not synced or not initialized yet,
44
+ * and update the active extractors list
45
+ * @param block
46
+ */
47
+ protected verifyExtractorsInitialization: (block: BlockInfo) => Promise<void>;
48
+ }
49
+ //# sourceMappingURL=scanner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../../../lib/scanner/abstract/scanner.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EAAE,cAAc,EAAe,MAAM,+BAA+B,CAAC;AAC5E,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAC/D,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAC;AACpE,OAAO,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAC;AAEhD,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE1C,8BAAsB,eAAe,CAAC,eAAe;IACnD,MAAM,EAAE,aAAa,CAAC;IACtB,UAAU,EAAE,KAAK,CAAC,iBAAiB,CAAC,eAAe,EAAE,aAAa,CAAC,CAAC,CAAC;IACrE,aAAa,EAAE,KAAK,CAAC,iBAAiB,CAAC,eAAe,EAAE,aAAa,CAAC,CAAC,CAAC;IACxE,MAAM,EAAE,cAAc,CAAC;IACvB,eAAe,EAAE,KAAK,CAAC;gBAEX,MAAM,CAAC,EAAE,cAAc;IAOnC,QAAQ,CAAC,IAAI,EAAE,MAAM,MAAM,CAAC;IAE5B;;;OAGG;IACH,SAAS,CAAC,SAAS,GAAU,QAAQ,MAAM,mBAiBzC;IAEF;;;;OAIG;IACH,SAAS,CAAC,wBAAwB,GAChC,OAAO,KAAK,EACZ,cAAc,KAAK,CAAC,eAAe,CAAC,kDAyBpC;IAEF;;;OAGG;IACH,iBAAiB,GACf,WAAW,iBAAiB,CAAC,eAAe,EAAE,aAAa,CAAC,KAC3D,OAAO,CAAC,IAAI,CAAC,CAmBd;IAEF;;;OAGG;IACH,eAAe,GACb,WAAW,iBAAiB,CAAC,eAAe,EAAE,aAAa,CAAC,KAC3D,OAAO,CAAC,IAAI,CAAC,CAQd;IAEF;;;;OAIG;IACH,OAAO,CAAC,oBAAoB,CAkB1B;IAEF;;;;OAIG;IACH,SAAS,CAAC,8BAA8B,GAAU,OAAO,SAAS,mBAqDhE;CACH"}