@rosen-bridge/abstract-extractor 2.1.2 → 3.0.0-8f3c7016

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 (104) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/dist/abstractExtractor.d.ts +24 -12
  3. package/dist/abstractExtractor.d.ts.map +1 -1
  4. package/dist/abstractExtractor.js +1 -1
  5. package/dist/constants.d.ts +1 -0
  6. package/dist/constants.d.ts.map +1 -1
  7. package/dist/constants.js +2 -1
  8. package/dist/ergo/database/actions/abstractErgoAction.d.ts +83 -0
  9. package/dist/ergo/database/actions/abstractErgoAction.d.ts.map +1 -0
  10. package/dist/ergo/database/actions/abstractErgoAction.js +167 -0
  11. package/dist/ergo/database/actions/abstractErgoBoxAction.d.ts +31 -0
  12. package/dist/ergo/database/actions/abstractErgoBoxAction.d.ts.map +1 -0
  13. package/dist/ergo/database/actions/abstractErgoBoxAction.js +70 -0
  14. package/dist/ergo/database/entities/abstractErgoBoxEntity.d.ts +18 -0
  15. package/dist/ergo/database/entities/abstractErgoBoxEntity.d.ts.map +1 -0
  16. package/dist/ergo/database/entities/abstractErgoBoxEntity.js +36 -0
  17. package/dist/ergo/database/entities/abstractErgoEntity.d.ts +26 -0
  18. package/dist/ergo/database/entities/abstractErgoEntity.d.ts.map +1 -0
  19. package/dist/ergo/database/entities/abstractErgoEntity.js +64 -0
  20. package/dist/ergo/database/index.d.ts +5 -0
  21. package/dist/ergo/database/index.d.ts.map +1 -0
  22. package/dist/ergo/database/index.js +5 -0
  23. package/dist/ergo/extractors/abstractErgoBoxExtractor.d.ts +67 -0
  24. package/dist/ergo/extractors/abstractErgoBoxExtractor.d.ts.map +1 -0
  25. package/dist/ergo/extractors/abstractErgoBoxExtractor.js +106 -0
  26. package/dist/ergo/extractors/abstractErgoExtractor.d.ts +53 -0
  27. package/dist/ergo/extractors/abstractErgoExtractor.d.ts.map +1 -0
  28. package/dist/ergo/extractors/abstractErgoExtractor.js +92 -0
  29. package/dist/ergo/extractors/abstractErgoTxExtractor.d.ts +56 -0
  30. package/dist/ergo/extractors/abstractErgoTxExtractor.d.ts.map +1 -0
  31. package/dist/ergo/extractors/abstractErgoTxExtractor.js +81 -0
  32. package/dist/ergo/extractors/index.d.ts +4 -0
  33. package/dist/ergo/extractors/index.d.ts.map +1 -0
  34. package/dist/ergo/extractors/index.js +4 -0
  35. package/dist/ergo/index.d.ts +5 -7
  36. package/dist/ergo/index.d.ts.map +1 -1
  37. package/dist/ergo/index.js +6 -8
  38. package/dist/ergo/initializers/ergoBoxInitializer.d.ts +36 -0
  39. package/dist/ergo/initializers/ergoBoxInitializer.d.ts.map +1 -0
  40. package/dist/ergo/initializers/ergoBoxInitializer.js +80 -0
  41. package/dist/ergo/initializers/ergoInitializer.d.ts +39 -0
  42. package/dist/ergo/initializers/ergoInitializer.d.ts.map +1 -0
  43. package/dist/ergo/initializers/ergoInitializer.js +80 -0
  44. package/dist/ergo/initializers/index.d.ts +4 -0
  45. package/dist/ergo/initializers/index.d.ts.map +1 -0
  46. package/dist/ergo/initializers/index.js +4 -0
  47. package/dist/ergo/initializers/strategies/constants.d.ts +3 -0
  48. package/dist/ergo/initializers/strategies/constants.d.ts.map +1 -0
  49. package/dist/ergo/initializers/strategies/constants.js +3 -0
  50. package/dist/ergo/initializers/strategies/explorerInitializationStrategy.d.ts +59 -0
  51. package/dist/ergo/initializers/strategies/explorerInitializationStrategy.d.ts.map +1 -0
  52. package/dist/ergo/initializers/strategies/explorerInitializationStrategy.js +141 -0
  53. package/dist/ergo/initializers/strategies/index.d.ts +4 -0
  54. package/dist/ergo/initializers/strategies/index.d.ts.map +1 -0
  55. package/dist/ergo/initializers/strategies/index.js +4 -0
  56. package/dist/ergo/initializers/strategies/nodeInitializationStrategy.d.ts +29 -0
  57. package/dist/ergo/initializers/strategies/nodeInitializationStrategy.d.ts.map +1 -0
  58. package/dist/ergo/initializers/strategies/nodeInitializationStrategy.js +66 -0
  59. package/dist/ergo/initializers/strategies/workerManager.d.ts +79 -0
  60. package/dist/ergo/initializers/strategies/workerManager.d.ts.map +1 -0
  61. package/dist/ergo/initializers/strategies/workerManager.js +183 -0
  62. package/dist/ergo/interfaces.d.ts +31 -17
  63. package/dist/ergo/interfaces.d.ts.map +1 -1
  64. package/dist/ergo/interfaces.js +1 -1
  65. package/dist/ergo/networks/explorerNetwork.d.ts +52 -0
  66. package/dist/ergo/networks/explorerNetwork.d.ts.map +1 -0
  67. package/dist/ergo/networks/explorerNetwork.js +127 -0
  68. package/dist/ergo/networks/index.d.ts +3 -0
  69. package/dist/ergo/networks/index.d.ts.map +1 -0
  70. package/dist/ergo/networks/index.js +3 -0
  71. package/dist/ergo/networks/nodeNetwork.d.ts +28 -0
  72. package/dist/ergo/networks/nodeNetwork.d.ts.map +1 -0
  73. package/dist/ergo/networks/nodeNetwork.js +59 -0
  74. package/dist/ergo/utils.d.ts +15 -0
  75. package/dist/ergo/utils.d.ts.map +1 -1
  76. package/dist/ergo/utils.js +34 -1
  77. package/package.json +3 -1
  78. package/dist/ergo/abstractErgoExtractor.d.ts +0 -80
  79. package/dist/ergo/abstractErgoExtractor.d.ts.map +0 -1
  80. package/dist/ergo/abstractErgoExtractor.js +0 -142
  81. package/dist/ergo/abstractErgoExtractorAction.d.ts +0 -89
  82. package/dist/ergo/abstractErgoExtractorAction.d.ts.map +0 -1
  83. package/dist/ergo/abstractErgoExtractorAction.js +0 -219
  84. package/dist/ergo/abstractErgoExtractorEntity.d.ts +0 -11
  85. package/dist/ergo/abstractErgoExtractorEntity.d.ts.map +0 -1
  86. package/dist/ergo/abstractErgoExtractorEntity.js +0 -57
  87. package/dist/ergo/initializable/abstractInitializable.d.ts +0 -48
  88. package/dist/ergo/initializable/abstractInitializable.d.ts.map +0 -1
  89. package/dist/ergo/initializable/abstractInitializable.js +0 -162
  90. package/dist/ergo/initializable/abstractInitializableAction.d.ts +0 -14
  91. package/dist/ergo/initializable/abstractInitializableAction.d.ts.map +0 -1
  92. package/dist/ergo/initializable/abstractInitializableAction.js +0 -16
  93. package/dist/ergo/initializable/index.d.ts +0 -3
  94. package/dist/ergo/initializable/index.d.ts.map +0 -1
  95. package/dist/ergo/initializable/index.js +0 -3
  96. package/dist/ergo/network/abstractNetwork.d.ts +0 -26
  97. package/dist/ergo/network/abstractNetwork.d.ts.map +0 -1
  98. package/dist/ergo/network/abstractNetwork.js +0 -3
  99. package/dist/ergo/network/explorerNetwork.d.ts +0 -74
  100. package/dist/ergo/network/explorerNetwork.d.ts.map +0 -1
  101. package/dist/ergo/network/explorerNetwork.js +0 -185
  102. package/dist/ergo/network/nodeNetwork.d.ts +0 -60
  103. package/dist/ergo/network/nodeNetwork.d.ts.map +0 -1
  104. package/dist/ergo/network/nodeNetwork.js +0 -131
@@ -1,162 +0,0 @@
1
- import { groupBy, sortBy } from 'lodash-es';
2
- import { ErgoNetworkType } from '@rosen-bridge/scanner-interfaces';
3
- import { API_LIMIT, RETRIAL_COUNT } from '../../constants';
4
- import { AbstractErgoExtractor } from '../abstractErgoExtractor';
5
- import { ExplorerNetwork } from '../network/explorerNetwork';
6
- import { NodeNetwork } from '../network/nodeNetwork';
7
- export class AbstractInitializableErgoExtractor extends AbstractErgoExtractor {
8
- initialize;
9
- address;
10
- network;
11
- constructor(type, url, address, logger, initialize = true) {
12
- super(logger);
13
- this.address = address;
14
- this.initialize = initialize;
15
- if (type == ErgoNetworkType.Explorer) {
16
- this.network = new ExplorerNetwork(url);
17
- this.initializeBoxes = (initialBlock) => {
18
- return this.initializeWithExplorer(initialBlock);
19
- };
20
- }
21
- else if (type == ErgoNetworkType.Node) {
22
- this.network = new NodeNetwork(url);
23
- this.initializeBoxes = (initialBlock) => {
24
- return this.initializeWithNode(initialBlock);
25
- };
26
- }
27
- else
28
- throw new Error(`Network type ${type} is not supported`);
29
- }
30
- /**
31
- * Initialize extractor using Explorer network
32
- * @param initialBlock
33
- */
34
- initializeWithExplorer = async (initialBlock) => {
35
- const explorerNetwork = this.network;
36
- let fromHeight = 0, toHeight = initialBlock.height;
37
- await this.initWithRetrial(async () => {
38
- while (fromHeight < toHeight) {
39
- let txs;
40
- while (true) {
41
- txs = await explorerNetwork.getAddressTransactionsWithHeight(this.address, fromHeight, toHeight);
42
- this.logger.debug(`Found ${txs.length} transactions for the address from height ${fromHeight} to height ${toHeight}`);
43
- if (txs.length < API_LIMIT || fromHeight === toHeight) {
44
- break; // Exit loop if we have fewer transactions than the limit or if the range is reduced to a single height
45
- }
46
- toHeight = Math.floor((toHeight - fromHeight) / 2) + fromHeight;
47
- this.logger.debug(`Limiting the query height range to [${fromHeight}, ${toHeight}]`);
48
- }
49
- if (txs.length < API_LIMIT) {
50
- if (txs.length > 0)
51
- await this.processTransactionBatch(txs);
52
- }
53
- else {
54
- this.logger.debug(`Block at height ${fromHeight} has more than (or equal) ${API_LIMIT} relevant txs, processing all txs in the block`);
55
- const blockId = await explorerNetwork.getBlockIdAtHeight(fromHeight);
56
- const blockTxs = await explorerNetwork.getBlockTxs(blockId);
57
- this.logger.debug(`Found ${blockTxs.length} transactions at height ${fromHeight}`);
58
- await this.processTransactions(blockTxs, {
59
- hash: blockId,
60
- height: fromHeight,
61
- });
62
- }
63
- fromHeight = toHeight + 1;
64
- toHeight = initialBlock.height;
65
- }
66
- });
67
- };
68
- /**
69
- * Get the total tx count from Node network
70
- * @returns total tx count of the address
71
- */
72
- getTotalTxCount = async () => {
73
- const response = await this.network.getAddressTransactionsWithOffsetLimit(this.address, 0, 0);
74
- return response.total;
75
- };
76
- /**
77
- * Initialize extractor using Node network
78
- * @param initialBlock
79
- */
80
- initializeWithNode = async (initialBlock) => {
81
- const txCountBeforeInit = await this.getTotalTxCount();
82
- let offset = 0, total = 1, round = 1;
83
- await this.initWithRetrial(async () => {
84
- // Repeat the whole process twice to cover all spent boxes
85
- // After round 1 all boxes have been saved and processed once
86
- // After round 2 spending information of all stored boxes are updated successfully
87
- while (round <= 2) {
88
- this.logger.debug(`Starting round ${round} of initialization`);
89
- while (offset < total) {
90
- const response = await this.network.getAddressTransactionsWithOffsetLimit(this.address, offset, API_LIMIT);
91
- total = response.total;
92
- const txs = response.items.filter((tx) => tx.inclusionHeight <= initialBlock.height);
93
- this.logger.debug(`Found ${txs.length} transactions below the initial height with offset ${offset} and total number of transactions ${total}`);
94
- if (txs.length > 0)
95
- await this.processTransactionBatch(txs);
96
- offset += API_LIMIT;
97
- }
98
- round++;
99
- offset = 0; // next round initial offset
100
- }
101
- });
102
- const txCountAfterInit = await this.getTotalTxCount();
103
- if (txCountAfterInit != txCountBeforeInit) {
104
- throw Error('Total transaction count changed during initialization phase, the stored data is not valid');
105
- }
106
- };
107
- /**
108
- * Process a batch of transactions
109
- * group txs into blocks and process them using `processTransactions`
110
- * @param txs
111
- */
112
- processTransactionBatch = async (txs) => {
113
- txs = sortBy(txs, (tx) => tx.inclusionHeight);
114
- const groupedTxs = groupBy(txs, (tx) => tx.blockId);
115
- this.logger.debug(`The transaction batch grouped to ${Object.keys(groupedTxs).length} blocks`);
116
- for (const blockId in groupedTxs) {
117
- const blockTxs = groupedTxs[blockId];
118
- const block = { hash: blockId, height: blockTxs[0].inclusionHeight };
119
- this.logger.debug(`Processing transactions at height ${blockTxs[0].inclusionHeight}`);
120
- const success = await this.processTransactions(blockTxs, block);
121
- if (!success)
122
- throw Error(`Processing transactions failed at height ${blockTxs[0].inclusionHeight}`);
123
- }
124
- };
125
- /**
126
- * Initialize the extractor with retrial on any unexpected problem
127
- * its the common part of initialize with Node and Explorer network
128
- * @param job
129
- */
130
- initWithRetrial = async (job) => {
131
- let trial = 1;
132
- if (this.initialize) {
133
- this.logger.debug(`Initializing ${this.getId()} started, removing all existing data`);
134
- await this.actions.removeAllData(this.getId());
135
- while (trial <= RETRIAL_COUNT) {
136
- try {
137
- await job();
138
- break;
139
- }
140
- catch (e) {
141
- this.logger.warn(`Initialization for ${this.getId()} failed with error :${e}`);
142
- if (trial == RETRIAL_COUNT)
143
- throw Error(`Initialization for ${this.getId()} failed after ${RETRIAL_COUNT} retrial`);
144
- trial += 1;
145
- this.logger.info(`Trying again to initialize ${this.getId()} with trial step ${trial}`);
146
- }
147
- }
148
- this.logger.info(`Initialization completed successfully for ${this.getId()}`);
149
- }
150
- else {
151
- this.logger.info(`Initialization for ${this.getId()} is turned off`);
152
- }
153
- };
154
- /**
155
- * initialize extractor database with data created below the initial height
156
- * ignore initialization if this feature is off
157
- * try to get data multiple times to pass accidental network problems
158
- * @param initialBlock
159
- */
160
- initializeBoxes;
161
- }
162
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWJzdHJhY3RJbml0aWFsaXphYmxlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vbGliL2VyZ28vaW5pdGlhbGl6YWJsZS9hYnN0cmFjdEluaXRpYWxpemFibGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFHNUMsT0FBTyxFQUFhLGVBQWUsRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBRTlFLE9BQU8sRUFBRSxTQUFTLEVBQUUsYUFBYSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDM0QsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFHakUsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQzdELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUdyRCxNQUFNLE9BQWdCLGtDQUdwQixTQUFRLHFCQUFxRDtJQUNuRCxVQUFVLENBQVU7SUFDdEIsT0FBTyxDQUFTO0lBTWhCLE9BQU8sQ0FBZ0M7SUFFL0MsWUFDRSxJQUFxQixFQUNyQixHQUFXLEVBQ1gsT0FBZSxFQUNmLE1BQXVCLEVBQ3ZCLFVBQVUsR0FBRyxJQUFJO1FBRWpCLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNkLElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFDO1FBQzdCLElBQUksSUFBSSxJQUFJLGVBQWUsQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUNyQyxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksZUFBZSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ3hDLElBQUksQ0FBQyxlQUFlLEdBQUcsQ0FBQyxZQUF1QixFQUFFLEVBQUU7Z0JBQ2pELE9BQU8sSUFBSSxDQUFDLHNCQUFzQixDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQ25ELENBQUMs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QUNkLDhCQUE4QixJQUFJLENBQUMsS0FBSyxFQUFFLG9CQUFvQixLQUFLLEVBQUUsQ0FDdEUsQ0FBQztnQkFDSixDQUFDO1lBQ0gsQ0FBQztZQUNELElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUNkLDZDQUE2QyxJQUFJLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FDNUQsQ0FBQztRQUNKLENBQUM7YUFBTSxDQUFDO1lBQ04sSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsc0JBQXNCLElBQUksQ0FBQyxLQUFLLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQztRQUN2RSxDQUFDO0lBQ0gsQ0FBQyxDQUFDO0lBRUY7Ozs7O09BS0c7SUFDSCxlQUFlLENBQTZDO0NBQzdEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZ3JvdXBCeSwgc29ydEJ5IH0gZnJvbSAnbG9kYXNoLWVzJztcblxuaW1wb3J0IHsgQWJzdHJhY3RMb2dnZXIgfSBmcm9tICdAcm9zZW4tYnJpZGdlL2Fic3RyYWN0LWxvZ2dlcic7XG5pbXBvcnQgeyBCbG9ja0luZm8sIEVyZ29OZXR3b3JrVHlwZSB9IGZyb20gJ0Byb3Nlbi1icmlkZ2Uvc2Nhbm5lci1pbnRlcmZhY2VzJztcblxuaW1wb3J0IHsgQVBJX0xJTUlULCBSRVRSSUFMX0NPVU5UIH0gZnJvbSAnLi4vLi4vY29uc3RhbnRzJztcbmltcG9ydCB7IEFic3RyYWN0RXJnb0V4dHJhY3RvciB9IGZyb20gJy4uL2Fic3RyYWN0RXJnb0V4dHJhY3Rvcic7XG5pbXBvcnQgeyBBYnN0cmFjdEVyZ29FeHRyYWN0b3JFbnRpdHkgfSBmcm9tICcuLi9hYnN0cmFjdEVyZ29FeHRyYWN0b3JFbnRpdHknO1xuaW1wb3J0IHsgQWJzdHJhY3RCb3hEYXRhLCBFeHRlbmRlZFRyYW5zYWN0aW9uIH0gZnJvbSAnLi4vaW50ZXJmYWNlcyc7XG5pbXBvcnQgeyBFeHBsb3Jlck5ldHdvcmsgfSBmcm9tICcuLi9uZXR3b3JrL2V4cGxvcmVyTmV0d29yayc7XG5pbXBvcnQgeyBOb2RlTmV0d29yayB9IGZyb20gJy4uL25ldHdvcmsvbm9kZU5ldHdvcmsnO1xuaW1wb3J0IHsgQWJzdHJhY3RJbml0aWFsaXphYmxlRXJnb0V4dHJhY3RvckFjdGlvbiB9IGZyb20gJy4vYWJzdHJhY3RJbml0aWFsaXphYmxlQWN0aW9uJztcblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIEFic3RyYWN0SW5pdGlhbGl6YWJsZUVyZ29FeHRyYWN0b3I8XG4gIEV4dHJhY3RlZERhdGEgZXh0ZW5kcyBBYnN0cmFjdEJveERhdGEsXG4gIEV4dHJhY3RvckVudGl0eSBleHRlbmRzIEFic3RyYWN0RXJnb0V4dHJhY3RvckVudGl0eSxcbj4gZXh0ZW5kcyBBYnN0cmFjdEVyZ29FeHRyYWN0b3I8RXh0cmFjdGVkRGF0YSwgRXh0cmFjdG9yRW50aXR5PiB7XG4gIHByb3RlY3RlZCBpbml0aWFsaXplOiBib29sZWFuO1xuICBwcml2YXRlIGFkZHJlc3M6IHN0cmluZztcbiAgcHJvdGVjdGVkIGFic3RyYWN0IGFjdGlvbnM6IEFic3RyYWN0SW5pdGlhbGl6YWJsZUVyZ29FeHRyYWN0b3JBY3Rpb248XG4gICAgRXh0cmFjdGVkRGF0YSxcbiAgICBFeHRyYWN0b3JFbnRpdHlcbiAgPjtcblxuICBwcml2YXRlIG5ldHdvcms6IEV4cGxvcmVyTmV0d29yayB8IE5vZGVOZXR3b3JrO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHR5cGU6IEVyZ29OZXR3b3JrVHlwZSxcbiAgICB1cmw6IHN0cmluZyxcbiAgICBhZGRyZXNzOiBzdHJpbmcsXG4gICAgbG9nZ2VyPzogQWJzdHJhY3RMb2dnZXIsXG4gICAgaW5pdGlhbGl6ZSA9IHRydWUsXG4gICkge1xuICAgIHN1cGVyKGxvZ2dlcik7XG4gICAgdGhpcy5hZGRyZXNzID0gYWRkcmVzcztcbiAgICB0aGlzLmluaXRpYWxpemUgPSBpbml0aWFsaXplO1xuICAgIGlmICh0eXBlID09IEVyZ29OZXR3b3JrVHlwZS5FeHBsb3Jlcikge1xuICAgICAgdGhpcy5uZXR3b3JrID0gbmV3IEV4cGxvcmVyTmV0d29yayh1cmwpO1xuICAgICAgdGhpcy5pbml0aWFsaXplQm94ZXMgPSAoaW5pdGlhbEJsb2NrOiBCbG9ja0luZm8pID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaW5pdGlhbGl6ZVdpdGhFeHBsb3Jlcihpbml0aWFsQmxvY2spO1xuICAgICAgfTtcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT0gRXJnb05ldHdvcmtUeXBlLk5vZGUpIHtcbiAgICAgIHRoaXMubmV0d29yayA9IG5ldyBOb2RlTmV0d29yayh1cmwpO1xuICAgICAgdGhpcy5pbml0aWFsaXplQm94ZXMgPSAoaW5pdGlhbEJsb2NrOiBCbG9ja0luZm8pID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaW5pdGlhbGl6ZVdpdGhOb2RlKGluaXRpYWxCbG9jayk7XG4gICAgICB9O1xuICAgIH0gZWxzZSB0aHJvdyBuZXcgRXJyb3IoYE5ldHdvcmsgdHlwZSAke3R5cGV9IGlzIG5vdCBzdXBwb3J0ZWRgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbml0aWFsaXplIGV4dHJhY3RvciB1c2luZyBFeHBsb3JlciBuZXR3b3JrXG4gICAqIEBwYXJhbSBpbml0aWFsQmxvY2tcbiAgICovXG4gIHByaXZhdGUgaW5pdGlhbGl6ZVdpdGhFeHBsb3JlciA9IGFzeW5jIChpbml0aWFsQmxvY2s6IEJsb2NrSW5mbykgPT4ge1xuICAgIGNvbnN0IGV4cGxvcmVyTmV0d29yayA9IHRoaXMubmV0d29yayBhcyBFeHBsb3Jlck5ldHdvcms7XG4gICAgbGV0IGZyb21IZWlnaHQgPSAwLFxuICAgICAgdG9IZWlnaHQgPSBpbml0aWFsQmxvY2suaGVpZ2h0O1xuICAgIGF3YWl0IHRoaXMuaW5pdFdpdGhSZXRyaWFsKGFzeW5jICgpID0+IHtcbiAgICAgIHdoaWxlIChmcm9tSGVpZ2h0IDwgdG9IZWlnaHQpIHtcbiAgICAgICAgbGV0IHR4czogQXJyYXk8RXh0ZW5kZWRUcmFuc2FjdGlvbj47XG5cbiAgICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgICB0eHMgPSBhd2FpdCBleHBsb3Jlck5ldHdvcmsuZ2V0QWRkcmVzc1RyYW5zYWN0aW9uc1dpdGhIZWlnaHQoXG4gICAgICAgICAgICB0aGlzLmFkZHJlc3MsXG4gICAgICAgICAgICBmcm9tSGVpZ2h0LFxuICAgICAgICAgICAgdG9IZWlnaHQsXG4gICAgICAgICAgKTtcbiAgICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhcbiAgICAgICAgICAgIGBGb3VuZCAke3R4cy5sZW5ndGh9IHRyYW5zYWN0aW9ucyBmb3IgdGhlIGFkZHJlc3MgZnJvbSBoZWlnaHQgJHtmcm9tSGVpZ2h0fSB0byBoZWlnaHQgJHt0b0hlaWdodH1gLFxuICAgICAgICAgICk7XG4gICAgICAgICAgaWYgKHR4cy5sZW5ndGggPCBBUElfTElNSVQgfHwgZnJvbUhlaWdodCA9PT0gdG9IZWlnaHQpIHtcbiAgICAgICAgICAgIGJyZWFrOyAvLyBFeGl0IGxvb3AgaWYgd2UgaGF2ZSBmZXdlciB0cmFuc2FjdGlvbnMgdGhhbiB0aGUgbGltaXQgb3IgaWYgdGhlIHJhbmdlIGlzIHJlZHVjZWQgdG8gYSBzaW5nbGUgaGVpZ2h0XG4gICAgICAgICAgfVxuICAgICAgICAgIHRvSGVpZ2h0ID0gTWF0aC5mbG9vcigodG9IZWlnaHQgLSBmcm9tSGVpZ2h0KSAvIDIpICsgZnJvbUhlaWdodDtcbiAgICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhcbiAgICAgICAgICAgIGBMaW1pdGluZyB0aGUgcXVlcnkgaGVpZ2h0IHJhbmdlIHRvIFske2Zyb21IZWlnaHR9LCAke3RvSGVpZ2h0fV1gLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR4cy5sZW5ndGggPCBBUElfTElNSVQpIHtcbiAgICAgICAgICBpZiAodHhzLmxlbmd0aCA+IDApIGF3YWl0IHRoaXMucHJvY2Vzc1RyYW5zYWN0aW9uQmF0Y2godHhzKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhcbiAgICAgICAgICAgIGBCbG9jayBhdCBoZWlnaHQgJHtmcm9tSGVpZ2h0fSBoYXMgbW9yZSB0aGFuIChvciBlcXVhbCkgJHtBUElfTElNSVR9IHJlbGV2YW50IHR4cywgcHJvY2Vzc2luZyBhbGwgdHhzIGluIHRoZSBibG9ja2AsXG4gICAgICAgICAgKTtcbiAgICAgICAgICBjb25zdCBibG9ja0lkID0gYXdhaXQgZXhwbG9yZXJOZXR3b3JrLmdldEJsb2NrSWRBdEhlaWdodChmcm9tSGVpZ2h0KTtcbiAgICAgICAgICBjb25zdCBibG9ja1R4cyA9IGF3YWl0IGV4cGxvcmVyTmV0d29yay5nZXRCbG9ja1R4cyhibG9ja0lkKTtcbiAgICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhcbiAgICAgICAgICAgIGBGb3VuZCAke2Jsb2NrVHhzLmxlbmd0aH0gdHJhbnNhY3Rpb25zIGF0IGhlaWdodCAke2Zyb21IZWlnaHR9YCxcbiAgICAgICAgICApO1xuICAgICAgICAgIGF3YWl0IHRoaXMucHJvY2Vzc1RyYW5zYWN0aW9ucyhibG9ja1R4cywge1xuICAgICAgICAgICAgaGFzaDogYmxvY2tJZCxcbiAgICAgICAgICAgIGhlaWdodDogZnJvbUhlaWdodCxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBmcm9tSGVpZ2h0ID0gdG9IZWlnaHQgKyAxO1xuICAgICAgICB0b0hlaWdodCA9IGluaXRpYWxCbG9jay5oZWlnaHQ7XG4gICAgICB9XG4gICAgfSk7XG4gIH07XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgdG90YWwgdHggY291bnQgZnJvbSBOb2RlIG5ldHdvcmtcbiAgICogQHJldHVybnMgdG90YWwgdHggY291bnQgb2YgdGhlIGFkZHJlc3NcbiAgICovXG4gIHByaXZhdGUgZ2V0VG90YWxUeENvdW50ID0gYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgKFxuICAgICAgdGhpcy5uZXR3b3JrIGFzIE5vZGVOZXR3b3JrXG4gICAgKS5nZXRBZGRyZXNzVHJhbnNhY3Rpb25zV2l0aE9mZnNldExpbWl0KHRoaXMuYWRkcmVzcywgMCwgMCk7XG4gICAgcmV0dXJuIHJlc3BvbnNlLnRvdGFsO1xuICB9O1xuXG4gIC8qKlxuICAgKiBJbml0aWFsaXplIGV4dHJhY3RvciB1c2luZyBOb2RlIG5ldHdvcmtcbiAgICogQHBhcmFtIGluaXRpYWxCbG9ja1xuICAgKi9cbiAgcHJpdmF0ZSBpbml0aWFsaXplV2l0aE5vZGUgPSBhc3luYyAoaW5pdGlhbEJsb2NrOiBCbG9ja0luZm8pID0+IHtcbiAgICBjb25zdCB0eENvdW50QmVmb3JlSW5pdCA9IGF3YWl0IHRoaXMuZ2V0VG90YWxUeENvdW50KCk7XG4gICAgbGV0IG9mZnNldCA9IDAsXG4gICAgICB0b3RhbCA9IDEsXG4gICAgICByb3VuZCA9IDE7XG4gICAgYXdhaXQgdGhpcy5pbml0V2l0aFJldHJpYWwoYXN5bmMgKCkgPT4ge1xuICAgICAgLy8gUmVwZWF0IHRoZSB3aG9sZSBwcm9jZXNzIHR3aWNlIHRvIGNvdmVyIGFsbCBzcGVudCBib3hlc1xuICAgICAgLy8gQWZ0ZXIgcm91bmQgMSBhbGwgYm94ZXMgaGF2ZSBiZWVuIHNhdmVkIGFuZCBwcm9jZXNzZWQgb25jZVxuICAgICAgLy8gQWZ0ZXIgcm91bmQgMiBzcGVuZGluZyBpbmZvcm1hdGlvbiBvZiBhbGwgc3RvcmVkIGJveGVzIGFyZSB1cGRhdGVkIHN1Y2Nlc3NmdWxseVxuICAgICAgd2hpbGUgKHJvdW5kIDw9IDIpIHtcbiAgICAgICAgdGhpcy5sb2dnZXIuZGVidWcoYFN0YXJ0aW5nIHJvdW5kICR7cm91bmR9IG9mIGluaXRpYWxpemF0aW9uYCk7XG4gICAgICAgIHdoaWxlIChvZmZzZXQgPCB0b3RhbCkge1xuICAgICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgKFxuICAgICAgICAgICAgdGhpcy5uZXR3b3JrIGFzIE5vZGVOZXR3b3JrXG4gICAgICAgICAgKS5nZXRBZGRyZXNzVHJhbnNhY3Rpb25zV2l0aE9mZnNldExpbWl0KFxuICAgICAgICAgICAgdGhpcy5hZGRyZXNzLFxuICAgICAgICAgICAgb2Zmc2V0LFxuICAgICAgICAgICAgQVBJX0xJTUlULFxuICAgICAgICAgICk7XG4gICAgICAgICAgdG90YWwgPSByZXNwb25zZS50b3RhbDtcbiAgICAgICAgICBjb25zdCB0eHMgPSByZXNwb25zZS5pdGVtcy5maWx0ZXIoXG4gICAgICAgICAgICAodHgpID0+IHR4LmluY2x1c2lvbkhlaWdodCA8PSBpbml0aWFsQmxvY2suaGVpZ2h0LFxuICAgICAgICAgICk7XG4gICAgICAgICAgdGhpcy5sb2dnZXIuZGVidWcoXG4gICAgICAgICAgICBgRm91bmQgJHt0eHMubGVuZ3RofSB0cmFuc2FjdGlvbnMgYmVsb3cgdGhlIGluaXRpYWwgaGVpZ2h0IHdpdGggb2Zmc2V0ICR7b2Zmc2V0fSBhbmQgdG90YWwgbnVtYmVyIG9mIHRyYW5zYWN0aW9ucyAke3RvdGFsfWAsXG4gICAgICAgICAgKTtcbiAgICAgICAgICBpZiAodHhzLmxlbmd0aCA+IDApIGF3YWl0IHRoaXMucHJvY2Vzc1RyYW5zYWN0aW9uQmF0Y2godHhzKTtcbiAgICAgICAgICBvZmZzZXQgKz0gQVBJX0xJTUlUO1xuICAgICAgICB9XG4gICAgICAgIHJvdW5kKys7XG4gICAgICAgIG9mZnNldCA9IDA7IC8vIG5leHQgcm91bmQgaW5pdGlhbCBvZmZzZXRcbiAgICAgIH1cbiAgICB9KTtcbiAgICBjb25zdCB0eENvdW50QWZ0ZXJJbml0ID0gYXdhaXQgdGhpcy5nZXRUb3RhbFR4Q291bnQoKTtcbiAgICBpZiAodHhDb3VudEFmdGVySW5pdCAhPSB0eENvdW50QmVmb3JlSW5pdCkge1xuICAgICAgdGhyb3cgRXJyb3IoXG4gICAgICAgICdUb3RhbCB0cmFuc2FjdGlvbiBjb3VudCBjaGFuZ2VkIGR1cmluZyBpbml0aWFsaXphdGlvbiBwaGFzZSwgdGhlIHN0b3JlZCBkYXRhIGlzIG5vdCB2YWxpZCcsXG4gICAgICApO1xuICAgIH1cbiAgfTtcblxuICAvKipcbiAgICogUHJvY2VzcyBhIGJhdGNoIG9mIHRyYW5zYWN0aW9uc1xuICAgKiBncm91cCB0eHMgaW50byBibG9ja3MgYW5kIHByb2Nlc3MgdGhlbSB1c2luZyBgcHJvY2Vzc1RyYW5zYWN0aW9uc2BcbiAgICogQHBhcmFtIHR4c1xuICAgKi9cbiAgcHJpdmF0ZSBwcm9jZXNzVHJhbnNhY3Rpb25CYXRjaCA9IGFzeW5jICh0eHM6IEFycmF5PEV4dGVuZGVkVHJhbnNhY3Rpb24+KSA9PiB7XG4gICAgdHhzID0gc29ydEJ5KHR4cywgKHR4KSA9PiB0eC5pbmNsdXNpb25IZWlnaHQpO1xuICAgIGNvbnN0IGdyb3VwZWRUeHMgPSBncm91cEJ5KHR4cywgKHR4KSA9PiB0eC5ibG9ja0lkKTtcbiAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhcbiAgICAgIGBUaGUgdHJhbnNhY3Rpb24gYmF0Y2ggZ3JvdXBlZCB0byAke1xuICAgICAgICBPYmplY3Qua2V5cyhncm91cGVkVHhzKS5sZW5ndGhcbiAgICAgIH0gYmxvY2tzYCxcbiAgICApO1xuICAgIGZvciAoY29uc3QgYmxvY2tJZCBpbiBncm91cGVkVHhzKSB7XG4gICAgICBjb25zdCBibG9ja1R4cyA9IGdyb3VwZWRUeHNbYmxvY2tJZF07XG4gICAgICBjb25zdCBibG9jayA9IHsgaGFzaDogYmxvY2tJZCwgaGVpZ2h0OiBibG9ja1R4c1swXS5pbmNsdXNpb25IZWlnaHQgfTtcbiAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKFxuICAgICAgICBgUHJvY2Vzc2luZyB0cmFuc2FjdGlvbnMgYXQgaGVpZ2h0ICR7YmxvY2tUeHNbMF0uaW5jbHVzaW9uSGVpZ2h0fWAsXG4gICAgICApO1xuICAgICAgY29uc3Qgc3VjY2VzcyA9IGF3YWl0IHRoaXMucHJvY2Vzc1RyYW5zYWN0aW9ucyhibG9ja1R4cywgYmxvY2spO1xuICAgICAgaWYgKCFzdWNjZXNzKVxuICAgICAgICB0aHJvdyBFcnJvcihcbiAgICAgICAgICBgUHJvY2Vzc2luZyB0cmFuc2FjdGlvbnMgZmFpbGVkIGF0IGhlaWdodCAke2Jsb2NrVHhzWzBdLmluY2x1c2lvbkhlaWdodH1gLFxuICAgICAgICApO1xuICAgIH1cbiAgfTtcblxuICAvKipcbiAgICogSW5pdGlhbGl6ZSB0aGUgZXh0cmFjdG9yIHdpdGggcmV0cmlhbCBvbiBhbnkgdW5leHBlY3RlZCBwcm9ibGVtXG4gICAqIGl0cyB0aGUgY29tbW9uIHBhcnQgb2YgaW5pdGlhbGl6ZSB3aXRoIE5vZGUgYW5kIEV4cGxvcmVyIG5ldHdvcmtcbiAgICogQHBhcmFtIGpvYlxuICAgKi9cbiAgcHJpdmF0ZSBpbml0V2l0aFJldHJpYWwgPSBhc3luYyAoam9iOiAoKSA9PiBQcm9taXNlPHZvaWQ+KSA9PiB7XG4gICAgbGV0IHRyaWFsID0gMTtcbiAgICBpZiAodGhpcy5pbml0aWFsaXplKSB7XG4gICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhcbiAgICAgICAgYEluaXRpYWxpemluZyAke3RoaXMuZ2V0SWQoKX0gc3RhcnRlZCwgcmVtb3ZpbmcgYWxsIGV4aXN0aW5nIGRhdGFgLFxuICAgICAgKTtcbiAgICAgIGF3YWl0IHRoaXMuYWN0aW9ucy5yZW1vdmVBbGxEYXRhKHRoaXMuZ2V0SWQoKSk7XG4gICAgICB3aGlsZSAodHJpYWwgPD0gUkVUUklBTF9DT1VOVCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGF3YWl0IGpvYigpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgdGhpcy5sb2dnZXIud2FybihcbiAgICAgICAgICAgIGBJbml0aWFsaXphdGlvbiBmb3IgJHt0aGlzLmdldElkKCl9IGZhaWxlZCB3aXRoIGVycm9yIDoke2V9YCxcbiAgICAgICAgICApO1xuICAgICAgICAgIGlmICh0cmlhbCA9PSBSRVRSSUFMX0NPVU5UKVxuICAgICAgICAgICAgdGhyb3cgRXJyb3IoXG4gICAgICAgICAgICAgIGBJbml0aWFsaXphdGlvbiBmb3IgJHt0aGlzLmdldElkKCl9IGZhaWxlZCBhZnRlciAke1JFVFJJQUxfQ09VTlR9IHJldHJpYWxgLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB0cmlhbCArPSAxO1xuICAgICAgICAgIHRoaXMubG9nZ2VyLmluZm8oXG4gICAgICAgICAgICBgVHJ5aW5nIGFnYWluIHRvIGluaXRpYWxpemUgJHt0aGlzLmdldElkKCl9IHdpdGggdHJpYWwgc3RlcCAke3RyaWFsfWAsXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgdGhpcy5sb2dnZXIuaW5mbyhcbiAgICAgICAgYEluaXRpYWxpemF0aW9uIGNvbXBsZXRlZCBzdWNjZXNzZnVsbHkgZm9yICR7dGhpcy5nZXRJZCgpfWAsXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmxvZ2dlci5pbmZvKGBJbml0aWFsaXphdGlvbiBmb3IgJHt0aGlzLmdldElkKCl9IGlzIHR1cm5lZCBvZmZgKTtcbiAgICB9XG4gIH07XG5cbiAgLyoqXG4gICAqIGluaXRpYWxpemUgZXh0cmFjdG9yIGRhdGFiYXNlIHdpdGggZGF0YSBjcmVhdGVkIGJlbG93IHRoZSBpbml0aWFsIGhlaWdodFxuICAgKiBpZ25vcmUgaW5pdGlhbGl6YXRpb24gaWYgdGhpcyBmZWF0dXJlIGlzIG9mZlxuICAgKiB0cnkgdG8gZ2V0IGRhdGEgbXVsdGlwbGUgdGltZXMgdG8gcGFzcyBhY2NpZGVudGFsIG5ldHdvcmsgcHJvYmxlbXNcbiAgICogQHBhcmFtIGluaXRpYWxCbG9ja1xuICAgKi9cbiAgaW5pdGlhbGl6ZUJveGVzOiAoaW5pdGlhbEJsb2NrOiBCbG9ja0luZm8pID0+IFByb21pc2U8dm9pZD47XG59XG4iXX0=
@@ -1,14 +0,0 @@
1
- import { AbstractLogger } from '@rosen-bridge/abstract-logger';
2
- import { DataSource, EntityTarget } from '@rosen-bridge/extended-typeorm';
3
- import { AbstractErgoExtractorAction } from '../abstractErgoExtractorAction';
4
- import { AbstractErgoExtractorEntity } from '../abstractErgoExtractorEntity';
5
- import { AbstractBoxData } from '../interfaces';
6
- export declare abstract class AbstractInitializableErgoExtractorAction<ExtractedData extends AbstractBoxData, ExtractorEntity extends AbstractErgoExtractorEntity> extends AbstractErgoExtractorAction<ExtractedData, ExtractorEntity> {
7
- constructor(dataSource: DataSource, repo: EntityTarget<ExtractorEntity>, logger?: AbstractLogger);
8
- /**
9
- * remove all existing data for the extractor
10
- * @param extractorId
11
- */
12
- removeAllData: (extractorId: string) => Promise<void>;
13
- }
14
- //# sourceMappingURL=abstractInitializableAction.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"abstractInitializableAction.d.ts","sourceRoot":"","sources":["../../../lib/ergo/initializable/abstractInitializableAction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EACL,UAAU,EACV,YAAY,EAEb,MAAM,gCAAgC,CAAC;AAExC,OAAO,EAAE,2BAA2B,EAAE,MAAM,gCAAgC,CAAC;AAC7E,OAAO,EAAE,2BAA2B,EAAE,MAAM,gCAAgC,CAAC;AAC7E,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD,8BAAsB,wCAAwC,CAC5D,aAAa,SAAS,eAAe,EACrC,eAAe,SAAS,2BAA2B,CACnD,SAAQ,2BAA2B,CAAC,aAAa,EAAE,eAAe,CAAC;gBAEjE,UAAU,EAAE,UAAU,EACtB,IAAI,EAAE,YAAY,CAAC,eAAe,CAAC,EACnC,MAAM,CAAC,EAAE,cAAc;IAKzB;;;OAGG;IACH,aAAa,GAAU,aAAa,MAAM,mBAIxC;CACH"}
@@ -1,16 +0,0 @@
1
- import { AbstractErgoExtractorAction } from '../abstractErgoExtractorAction';
2
- export class AbstractInitializableErgoExtractorAction extends AbstractErgoExtractorAction {
3
- constructor(dataSource, repo, logger) {
4
- super(dataSource, repo, logger);
5
- }
6
- /**
7
- * remove all existing data for the extractor
8
- * @param extractorId
9
- */
10
- removeAllData = async (extractorId) => {
11
- await this.repository.delete({
12
- extractor: extractorId,
13
- });
14
- };
15
- }
16
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWJzdHJhY3RJbml0aWFsaXphYmxlQWN0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vbGliL2VyZ28vaW5pdGlhbGl6YWJsZS9hYnN0cmFjdEluaXRpYWxpemFibGVBY3Rpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBT0EsT0FBTyxFQUFFLDJCQUEyQixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFJN0UsTUFBTSxPQUFnQix3Q0FHcEIsU0FBUSwyQkFBMkQ7SUFDbkUsWUFDRSxVQUFzQixFQUN0QixJQUFtQyxFQUNuQyxNQUF1QjtRQUV2QixLQUFLLENBQUMsVUFBVSxFQUFFLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQztJQUNsQyxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsYUFBYSxHQUFHLEtBQUssRUFBRSxXQUFtQixFQUFFLEVBQUU7UUFDNUMsTUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQztZQUMzQixTQUFTLEVBQUUsV0FBVztTQUNjLENBQUMsQ0FBQztJQUMxQyxDQUFDLENBQUM7Q0FDSCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFic3RyYWN0TG9nZ2VyIH0gZnJvbSAnQHJvc2VuLWJyaWRnZS9hYnN0cmFjdC1sb2dnZXInO1xuaW1wb3J0IHtcbiAgRGF0YVNvdXJjZSxcbiAgRW50aXR5VGFyZ2V0LFxuICBGaW5kT3B0aW9uc1doZXJlLFxufSBmcm9tICdAcm9zZW4tYnJpZGdlL2V4dGVuZGVkLXR5cGVvcm0nO1xuXG5pbXBvcnQgeyBBYnN0cmFjdEVyZ29FeHRyYWN0b3JBY3Rpb24gfSBmcm9tICcuLi9hYnN0cmFjdEVyZ29FeHRyYWN0b3JBY3Rpb24nO1xuaW1wb3J0IHsgQWJzdHJhY3RFcmdvRXh0cmFjdG9yRW50aXR5IH0gZnJvbSAnLi4vYWJzdHJhY3RFcmdvRXh0cmFjdG9yRW50aXR5JztcbmltcG9ydCB7IEFic3RyYWN0Qm94RGF0YSB9IGZyb20gJy4uL2ludGVyZmFjZXMnO1xuXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgQWJzdHJhY3RJbml0aWFsaXphYmxlRXJnb0V4dHJhY3RvckFjdGlvbjxcbiAgRXh0cmFjdGVkRGF0YSBleHRlbmRzIEFic3RyYWN0Qm94RGF0YSxcbiAgRXh0cmFjdG9yRW50aXR5IGV4dGVuZHMgQWJzdHJhY3RFcmdvRXh0cmFjdG9yRW50aXR5LFxuPiBleHRlbmRzIEFic3RyYWN0RXJnb0V4dHJhY3RvckFjdGlvbjxFeHRyYWN0ZWREYXRhLCBFeHRyYWN0b3JFbnRpdHk+IHtcbiAgY29uc3RydWN0b3IoXG4gICAgZGF0YVNvdXJjZTogRGF0YVNvdXJjZSxcbiAgICByZXBvOiBFbnRpdHlUYXJnZXQ8RXh0cmFjdG9yRW50aXR5PixcbiAgICBsb2dnZXI/OiBBYnN0cmFjdExvZ2dlcixcbiAgKSB7XG4gICAgc3VwZXIoZGF0YVNvdXJjZSwgcmVwbywgbG9nZ2VyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiByZW1vdmUgYWxsIGV4aXN0aW5nIGRhdGEgZm9yIHRoZSBleHRyYWN0b3JcbiAgICogQHBhcmFtIGV4dHJhY3RvcklkXG4gICAqL1xuICByZW1vdmVBbGxEYXRhID0gYXN5bmMgKGV4dHJhY3RvcklkOiBzdHJpbmcpID0+IHtcbiAgICBhd2FpdCB0aGlzLnJlcG9zaXRvcnkuZGVsZXRlKHtcbiAgICAgIGV4dHJhY3RvcjogZXh0cmFjdG9ySWQsXG4gICAgfSBhcyBGaW5kT3B0aW9uc1doZXJlPEV4dHJhY3RvckVudGl0eT4pO1xuICB9O1xufVxuIl19
@@ -1,3 +0,0 @@
1
- export * from './abstractInitializable';
2
- export * from './abstractInitializableAction';
3
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../lib/ergo/initializable/index.ts"],"names":[],"mappings":"AAAA,cAAc,yBAAyB,CAAC;AACxC,cAAc,+BAA+B,CAAC"}
@@ -1,3 +0,0 @@
1
- export * from './abstractInitializable';
2
- export * from './abstractInitializableAction';
3
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9saWIvZXJnby9pbml0aWFsaXphYmxlL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGNBQWMseUJBQXlCLENBQUM7QUFDeEMsY0FBYywrQkFBK0IsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCAqIGZyb20gJy4vYWJzdHJhY3RJbml0aWFsaXphYmxlJztcbmV4cG9ydCAqIGZyb20gJy4vYWJzdHJhY3RJbml0aWFsaXphYmxlQWN0aW9uJztcbiJdfQ==
@@ -1,26 +0,0 @@
1
- import { ErgoBox } from '../interfaces';
2
- export declare abstract class AbstractNetwork {
3
- /**
4
- * return related boxes by specified address with limit offset
5
- * @param address
6
- * @param offset
7
- * @param limit
8
- * @returns related boxes
9
- */
10
- abstract getBoxesByAddress: (address: string, offset: number, limit: number) => Promise<{
11
- boxes: ErgoBox[];
12
- hasNextBatch: boolean;
13
- }>;
14
- /**
15
- * return related boxes by specified token with limit offset
16
- * @param tokenId
17
- * @param offset
18
- * @param limit
19
- * @returns related boxes
20
- */
21
- abstract getBoxesByTokenId: (tokenId: string, offset: number, limit: number) => Promise<{
22
- boxes: ErgoBox[];
23
- hasNextBatch: boolean;
24
- }>;
25
- }
26
- //# sourceMappingURL=abstractNetwork.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"abstractNetwork.d.ts","sourceRoot":"","sources":["../../../lib/ergo/network/abstractNetwork.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAExC,8BAAsB,eAAe;IACnC;;;;;;OAMG;IACH,QAAQ,CAAC,iBAAiB,EAAE,CAC1B,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,KACV,OAAO,CAAC;QAAE,KAAK,EAAE,OAAO,EAAE,CAAC;QAAC,YAAY,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAE1D;;;;;;OAMG;IACH,QAAQ,CAAC,iBAAiB,EAAE,CAC1B,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,KACV,OAAO,CAAC;QAAE,KAAK,EAAE,OAAO,EAAE,CAAC;QAAC,YAAY,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CAC3D"}
@@ -1,3 +0,0 @@
1
- export class AbstractNetwork {
2
- }
3
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWJzdHJhY3ROZXR3b3JrLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vbGliL2VyZ28vbmV0d29yay9hYnN0cmFjdE5ldHdvcmsudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsTUFBTSxPQUFnQixlQUFlO0NBMEJwQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEVyZ29Cb3ggfSBmcm9tICcuLi9pbnRlcmZhY2VzJztcblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIEFic3RyYWN0TmV0d29yayB7XG4gIC8qKlxuICAgKiByZXR1cm4gcmVsYXRlZCBib3hlcyBieSBzcGVjaWZpZWQgYWRkcmVzcyB3aXRoIGxpbWl0IG9mZnNldFxuICAgKiBAcGFyYW0gYWRkcmVzc1xuICAgKiBAcGFyYW0gb2Zmc2V0XG4gICAqIEBwYXJhbSBsaW1pdFxuICAgKiBAcmV0dXJucyByZWxhdGVkIGJveGVzXG4gICAqL1xuICBhYnN0cmFjdCBnZXRCb3hlc0J5QWRkcmVzczogKFxuICAgIGFkZHJlc3M6IHN0cmluZyxcbiAgICBvZmZzZXQ6IG51bWJlcixcbiAgICBsaW1pdDogbnVtYmVyLFxuICApID0+IFByb21pc2U8eyBib3hlczogRXJnb0JveFtdOyBoYXNOZXh0QmF0Y2g6IGJvb2xlYW4gfT47XG5cbiAgLyoqXG4gICAqIHJldHVybiByZWxhdGVkIGJveGVzIGJ5IHNwZWNpZmllZCB0b2tlbiB3aXRoIGxpbWl0IG9mZnNldFxuICAgKiBAcGFyYW0gdG9rZW5JZFxuICAgKiBAcGFyYW0gb2Zmc2V0XG4gICAqIEBwYXJhbSBsaW1pdFxuICAgKiBAcmV0dXJucyByZWxhdGVkIGJveGVzXG4gICAqL1xuICBhYnN0cmFjdCBnZXRCb3hlc0J5VG9rZW5JZDogKFxuICAgIHRva2VuSWQ6IHN0cmluZyxcbiAgICBvZmZzZXQ6IG51bWJlcixcbiAgICBsaW1pdDogbnVtYmVyLFxuICApID0+IFByb21pc2U8eyBib3hlczogRXJnb0JveFtdOyBoYXNOZXh0QmF0Y2g6IGJvb2xlYW4gfT47XG59XG4iXX0=
@@ -1,74 +0,0 @@
1
- import { BlockInfo, Transaction } from '@rosen-bridge/scanner-interfaces';
2
- import { ErgoBox, ExtendedTransaction } from '../interfaces';
3
- import { AbstractNetwork } from './abstractNetwork';
4
- export declare class ExplorerNetwork extends AbstractNetwork {
5
- private api;
6
- constructor(url: string);
7
- /**
8
- * return spending information of a specified box by having spendTxId
9
- * @param boxId
10
- * @param spendTxId
11
- */
12
- getSpendingInfo: (boxId: string, spendTxId: string) => Promise<BlockInfo & {
13
- spendIndex: number;
14
- }>;
15
- /**
16
- * convert explorer api boxes to ErgoBox interface
17
- * @param box
18
- * @returns ErgoBox
19
- */
20
- private convertBox;
21
- /**
22
- * convert explorer transaction to extractor transaction type
23
- * @param tx
24
- */
25
- private convertTransaction;
26
- /**
27
- * convert explorer block transaction to transaction type
28
- * @param tx
29
- */
30
- private convertBlockTransaction;
31
- /**
32
- * use explorer api to return related transactions of the specified address in the height range
33
- * @param tokenId
34
- * @param offset
35
- * @param limit
36
- * @returns related transactions
37
- */
38
- getAddressTransactionsWithHeight: (address: string, fromHeight: number, toHeight: number) => Promise<Array<ExtendedTransaction>>;
39
- /**
40
- * use explorer api to get the block id at the specified height
41
- * @param height
42
- * @returns block id
43
- */
44
- getBlockIdAtHeight: (height: number) => Promise<string>;
45
- /**
46
- * use explorer api to return all transactions in a block
47
- * @param blockId
48
- * @returns converted transactions
49
- */
50
- getBlockTxs: (blockId: string) => Promise<Array<Transaction>>;
51
- /**
52
- * use explorer api to return related boxes by specified address
53
- * @param address
54
- * @param offset
55
- * @param limit
56
- * @returns related boxes
57
- */
58
- getBoxesByAddress: (address: string, offset: number, limit: number) => Promise<{
59
- boxes: ErgoBox[];
60
- hasNextBatch: boolean;
61
- }>;
62
- /**
63
- * use explorer api to return related boxes by specified token id
64
- * @param tokenId
65
- * @param offset
66
- * @param limit
67
- * @returns related boxes
68
- */
69
- getBoxesByTokenId: (tokenId: string, offset: number, limit: number) => Promise<{
70
- boxes: ErgoBox[];
71
- hasNextBatch: boolean;
72
- }>;
73
- }
74
- //# sourceMappingURL=explorerNetwork.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"explorerNetwork.d.ts","sourceRoot":"","sources":["../../../lib/ergo/network/explorerNetwork.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAK1E,OAAO,EAAE,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,qBAAa,eAAgB,SAAQ,eAAe;IAClD,OAAO,CAAC,GAAG,CAAC;gBAEA,GAAG,EAAE,MAAM;IAKvB;;;;OAIG;IACH,eAAe,GACb,OAAO,MAAM,EACb,WAAW,MAAM,KAChB,OAAO,CAAC,SAAS,GAAG;QAAE,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC,CAY5C;IAEF;;;;OAIG;IACH,OAAO,CAAC,UAAU,CAwBhB;IAEF;;;OAGG;IACH,OAAO,CAAC,kBAAkB,CA8BxB;IAEF;;;OAGG;IACH,OAAO,CAAC,uBAAuB,CAuB7B;IAEF;;;;;;OAMG;IACH,gCAAgC,GAC9B,SAAS,MAAM,EACf,YAAY,MAAM,EAClB,UAAU,MAAM,KACf,OAAO,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC,CAWpC;IAEF;;;;OAIG;IACH,kBAAkB,GAAU,QAAQ,MAAM,KAAG,OAAO,CAAC,MAAM,CAAC,CAG1D;IAEF;;;;OAIG;IACH,WAAW,GAAU,SAAS,MAAM,KAAG,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAUhE;IAEF;;;;;;OAMG;IACH,iBAAiB,GACf,SAAS,MAAM,EACf,QAAQ,MAAM,EACd,OAAO,MAAM,KACZ,OAAO,CAAC;QAAE,KAAK,EAAE,OAAO,EAAE,CAAC;QAAC,YAAY,EAAE,OAAO,CAAA;KAAE,CAAC,CAarD;IAEF;;;;;;OAMG;IACH,iBAAiB,GACf,SAAS,MAAM,EACf,QAAQ,MAAM,EACd,OAAO,MAAM,KACZ,OAAO,CAAC;QAAE,KAAK,EAAE,OAAO,EAAE,CAAC;QAAC,YAAY,EAAE,OAAO,CAAA;KAAE,CAAC,CAYrD;CACH"}
@@ -1,185 +0,0 @@
1
- import { mapValues, pick } from 'lodash-es';
2
- import ergoExplorerClientFactory from '@rosen-clients/ergo-explorer';
3
- import { API_LIMIT } from '../../constants';
4
- import { AbstractNetwork } from './abstractNetwork';
5
- export class ExplorerNetwork extends AbstractNetwork {
6
- api;
7
- constructor(url) {
8
- super();
9
- this.api = ergoExplorerClientFactory(url);
10
- }
11
- /**
12
- * return spending information of a specified box by having spendTxId
13
- * @param boxId
14
- * @param spendTxId
15
- */
16
- getSpendingInfo = async (boxId, spendTxId) => {
17
- const tx = await this.api.v1.getApiV1TransactionsP1(spendTxId);
18
- const spendIndex = tx.inputs?.findIndex((box) => box.boxId === boxId);
19
- if (spendIndex == undefined)
20
- throw Error(`Impossible behavior, the box [${boxId}] should have been spent in tx [${spendTxId}]`);
21
- return {
22
- hash: tx.blockId,
23
- height: tx.inclusionHeight,
24
- spendIndex,
25
- };
26
- };
27
- /**
28
- * convert explorer api boxes to ErgoBox interface
29
- * @param box
30
- * @returns ErgoBox
31
- */
32
- convertBox = async (box) => {
33
- const spendInfo = box.spentTransactionId
34
- ? await this.getSpendingInfo(box.boxId, box.spentTransactionId)
35
- : undefined;
36
- return {
37
- blockId: box.blockId,
38
- boxId: box.boxId,
39
- creationHeight: box.creationHeight,
40
- inclusionHeight: box.settlementHeight,
41
- ergoTree: box.ergoTree,
42
- index: box.index,
43
- transactionId: box.transactionId,
44
- value: box.value,
45
- additionalRegisters: mapValues(box.additionalRegisters, 'serializedValue'),
46
- assets: box.assets?.map((asset) => pick(asset, ['tokenId', 'amount'])) ?? [],
47
- spentHeight: spendInfo?.height,
48
- spentBlockId: spendInfo?.hash,
49
- spentTransactionId: box.spentTransactionId,
50
- spentIndex: spendInfo?.spendIndex,
51
- };
52
- };
53
- /**
54
- * convert explorer transaction to extractor transaction type
55
- * @param tx
56
- */
57
- convertTransaction = (tx) => {
58
- return {
59
- id: tx.id,
60
- inclusionHeight: tx.inclusionHeight,
61
- blockId: tx.blockId,
62
- dataInputs: tx.dataInputs?.map((dataInput) => ({
63
- boxId: dataInput.boxId,
64
- })) ?? [],
65
- // TODO: Add input extension to explorer local/ergo/rosen-bridge/scanner/-/issues/156
66
- inputs: tx.inputs?.map((input) => ({ boxId: input.boxId })) ?? [],
67
- outputs: tx.outputs?.map((output) => ({
68
- boxId: output.boxId,
69
- transactionId: output.transactionId,
70
- additionalRegisters: mapValues(output.additionalRegisters, 'serializedValue'),
71
- assets: output.assets?.map((asset) => pick(asset, ['tokenId', 'amount'])) ??
72
- [],
73
- ergoTree: output.ergoTree,
74
- creationHeight: output.creationHeight,
75
- index: output.index,
76
- value: output.value,
77
- })) ?? [],
78
- };
79
- };
80
- /**
81
- * convert explorer block transaction to transaction type
82
- * @param tx
83
- */
84
- convertBlockTransaction = (tx) => {
85
- return {
86
- id: tx.id,
87
- dataInputs: tx.dataInputs?.map((dataInput) => ({
88
- boxId: dataInput.id,
89
- })) ?? [],
90
- // TODO: Add input extension local/ergo/rosen-bridge/scanner/-/issues/156
91
- inputs: tx.inputs?.map((input) => ({ boxId: input.id })) ?? [],
92
- outputs: tx.outputs?.map((output) => ({
93
- boxId: output.id,
94
- transactionId: output.txId,
95
- additionalRegisters: output.additionalRegisters,
96
- assets: output.assets?.map((asset) => pick(asset, ['tokenId', 'amount'])) ??
97
- [],
98
- ergoTree: output.ergoTree,
99
- creationHeight: output.creationHeight,
100
- index: output.index,
101
- value: output.value,
102
- })) ?? [],
103
- };
104
- };
105
- /**
106
- * use explorer api to return related transactions of the specified address in the height range
107
- * @param tokenId
108
- * @param offset
109
- * @param limit
110
- * @returns related transactions
111
- */
112
- getAddressTransactionsWithHeight = async (address, fromHeight, toHeight) => {
113
- const txs = await this.api.v1.getApiV1AddressesP1Transactions(address, {
114
- fromHeight,
115
- toHeight,
116
- limit: API_LIMIT,
117
- });
118
- if (!txs.items)
119
- throw new Error('Explorer AddressTransactions api expected to have items');
120
- return txs.items.map((tx) => this.convertTransaction(tx));
121
- };
122
- /**
123
- * use explorer api to get the block id at the specified height
124
- * @param height
125
- * @returns block id
126
- */
127
- getBlockIdAtHeight = async (height) => {
128
- const id = await this.api.v0.getApiV0BlocksAtP1(height);
129
- return id[0];
130
- };
131
- /**
132
- * use explorer api to return all transactions in a block
133
- * @param blockId
134
- * @returns converted transactions
135
- */
136
- getBlockTxs = async (blockId) => {
137
- const block = await this.api.v1.getApiV1BlocksP1(blockId);
138
- if (!block.block.blockTransactions) {
139
- throw new Error(`Expected explorer block api to include block transactions for block ${blockId}`);
140
- }
141
- return block.block.blockTransactions.map((tx) => this.convertBlockTransaction(tx));
142
- };
143
- /**
144
- * use explorer api to return related boxes by specified address
145
- * @param address
146
- * @param offset
147
- * @param limit
148
- * @returns related boxes
149
- */
150
- getBoxesByAddress = async (address, offset, limit) => {
151
- const boxes = await this.api.v1.getApiV1BoxesUnspentByaddressP1(address, {
152
- offset: offset,
153
- limit: limit,
154
- sortDirection: 'desc',
155
- });
156
- if (!boxes.items)
157
- throw new Error('Explorer BoxesByAddress api expected to have items');
158
- const resultBoxes = [];
159
- for (const box of boxes.items) {
160
- resultBoxes.push(await this.convertBox(box));
161
- }
162
- return { boxes: resultBoxes, hasNextBatch: boxes.total > offset + limit };
163
- };
164
- /**
165
- * use explorer api to return related boxes by specified token id
166
- * @param tokenId
167
- * @param offset
168
- * @param limit
169
- * @returns related boxes
170
- */
171
- getBoxesByTokenId = async (tokenId, offset, limit) => {
172
- const boxes = await this.api.v1.getApiV1BoxesBytokenidP1(tokenId, {
173
- offset: offset,
174
- limit: limit,
175
- });
176
- if (!boxes.items)
177
- throw new Error('Explorer BoxesByTokeId api expected to have items');
178
- const resultBoxes = [];
179
- for (const box of boxes.items) {
180
- resultBoxes.push(await this.convertBox(box));
181
- }
182
- return { boxes: resultBoxes, hasNextBatch: boxes.total > offset + limit };
183
- };
184
- }
185
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXhwbG9yZXJOZXR3b3JrLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vbGliL2VyZ28vbmV0d29yay9leHBsb3Jlck5ldHdvcmsudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFHNUMsT0FBTyx5QkFBeUIsTUFBTSw4QkFBOEIsQ0FBQztBQUdyRSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFFNUMsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBRXBELE1BQU0sT0FBTyxlQUFnQixTQUFRLGVBQWU7SUFDMUMsR0FBRyxDQUFDO0lBRVosWUFBWSxHQUFXO1FBQ3JCLEtBQUssRUFBRSxDQUFDO1FBQ1IsSUFBSSxDQUFDLEdBQUcsR0FBRyx5QkFBeUIsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUM1QyxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILGVBQWUsR0FBRyxLQUFLLEVBQ3JCLEtBQWEsRUFDYixTQUFpQixFQUM0QixFQUFFO1FBQy9DLE1BQU0sRUFBRSxHQUFHLE1BQU0sSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsc0JBQXNCLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDL0QsTUFBTSxVQUFVLEdBQUcsRUFBRSxDQUFDLE1BQU0sRUFBRSxTQUFTLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxLQUFLLEtBQUssS0FBSyxDQUFDLENBQUM7UUFDdEUsSUFBSSxVQUFVLElBQUksU0FBUztZQUN6QixNQUFNLEtBQUssQ0FDVCxpQ0FBaUMsS0FBSyxtQ0FBbUMsU0FBUyxHQUFHLENBQ3RGLENBQUM7UUFDSixPQUFPO1lBQ0wsSUFBSSxFQUFFLEVBQUUsQ0FBQyxPQUFPO1lBQ2hCLE1BQU0sRUFBRSxFQUFFLENBQUMsZUFBZTtZQUMxQixVQUFVO1NBQ1gsQ0FBQztJQUNK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QUFNLFdBQVcsR0FBbUIsRUFBRSxDQUFDO1FBQ3ZDLEtBQUssTUFBTSxHQUFHLElBQUksS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQzlCLFdBQVcsQ0FBQyxJQUFJLENBQUMsTUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDL0MsQ0FBQztRQUNELE9BQU8sRUFBRSxLQUFLLEVBQUUsV0FBVyxFQUFFLFlBQVksRUFBRSxLQUFLLENBQUMsS0FBSyxHQUFHLE1BQU0sR0FBRyxLQUFLLEVBQUUsQ0FBQztJQUM1RSxDQUFDLENBQUM7Q0FDSCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IG1hcFZhbHVlcywgcGljayB9IGZyb20gJ2xvZGFzaC1lcyc7XG5cbmltcG9ydCB7IEJsb2NrSW5mbywgVHJhbnNhY3Rpb24gfSBmcm9tICdAcm9zZW4tYnJpZGdlL3NjYW5uZXItaW50ZXJmYWNlcyc7XG5pbXBvcnQgZXJnb0V4cGxvcmVyQ2xpZW50RmFjdG9yeSBmcm9tICdAcm9zZW4tY2xpZW50cy9lcmdvLWV4cGxvcmVyJztcbmltcG9ydCB7IFYxIH0gZnJvbSAnQHJvc2VuLWNsaWVudHMvZXJnby1leHBsb3Jlcic7XG5cbmltcG9ydCB7IEFQSV9MSU1JVCB9IGZyb20gJy4uLy4uL2NvbnN0YW50cyc7XG5pbXBvcnQgeyBFcmdvQm94LCBFeHRlbmRlZFRyYW5zYWN0aW9uIH0gZnJvbSAnLi4vaW50ZXJmYWNlcyc7XG5pbXBvcnQgeyBBYnN0cmFjdE5ldHdvcmsgfSBmcm9tICcuL2Fic3RyYWN0TmV0d29yayc7XG5cbmV4cG9ydCBjbGFzcyBFeHBsb3Jlck5ldHdvcmsgZXh0ZW5kcyBBYnN0cmFjdE5ldHdvcmsge1xuICBwcml2YXRlIGFwaTtcblxuICBjb25zdHJ1Y3Rvcih1cmw6IHN0cmluZykge1xuICAgIHN1cGVyKCk7XG4gICAgdGhpcy5hcGkgPSBlcmdvRXhwbG9yZXJDbGllbnRGYWN0b3J5KHVybCk7XG4gIH1cblxuICAvKipcbiAgICogcmV0dXJuIHNwZW5kaW5nIGluZm9ybWF0aW9uIG9mIGEgc3BlY2lmaWVkIGJveCBieSBoYXZpbmcgc3BlbmRUeElkXG4gICAqIEBwYXJhbSBib3hJZFxuICAgKiBAcGFyYW0gc3BlbmRUeElkXG4gICAqL1xuICBnZXRTcGVuZGluZ0luZm8gPSBhc3luYyAoXG4gICAgYm94SWQ6IHN0cmluZyxcbiAgICBzcGVuZFR4SWQ6IHN0cmluZyxcbiAgKTogUHJvbWlzZTxCbG9ja0luZm8gJiB7IHNwZW5kSW5kZXg6IG51bWJlciB9PiA9PiB7XG4gICAgY29uc3QgdHggPSBhd2FpdCB0aGlzLmFwaS52MS5nZXRBcGlWMVRyYW5zYWN0aW9uc1AxKHNwZW5kVHhJZCk7XG4gICAgY29uc3Qgc3BlbmRJbmRleCA9IHR4LmlucHV0cz8uZmluZEluZGV4KChib3gpID0+IGJveC5ib3hJZCA9PT0gYm94SWQpO1xuICAgIGlmIChzcGVuZEluZGV4ID09IHVuZGVmaW5lZClcbiAgICAgIHRocm93IEVycm9yKFxuICAgICAgICBgSW1wb3NzaWJsZSBiZWhhdmlvciwgdGhlIGJveCBbJHtib3hJZH1dIHNob3VsZCBoYXZlIGJlZW4gc3BlbnQgaW4gdHggWyR7c3BlbmRUeElkfV1gLFxuICAgICAgKTtcbiAgICByZXR1cm4ge1xuICAgICAgaGFzaDogdHguYmxvY2tJZCxcbiAgICAgIGhlaWdodDogdHguaW5jbHVzaW9uSGVpZ2h0LFxuICAgICAgc3BlbmRJbmRleCxcbiAgICB9O1xuICB9O1xuXG4gIC8qKlxuICAgKiBjb252ZXJ0IGV4cGxvcmVyIGFwaSBib3hlcyB0byBFcmdvQm94IGludGVyZmFjZVxuICAgKiBAcGFyYW0gYm94XG4gICAqIEByZXR1cm5zIEVyZ29Cb3hcbiAgICovXG4gIHByaXZhdGUgY29udmVydEJveCA9IGFzeW5jIChib3g6IFYxLk91dHB1dEluZm8pOiBQcm9taXNlPEVyZ29Cb3g+ID0+IHtcbiAgICBjb25zdCBzcGVuZEluZm8gPSBib3guc3BlbnRUcmFuc2FjdGlvbklkXG4gICAgICA/IGF3YWl0IHRoaXMuZ2V0U3BlbmRpbmdJbmZvKGJveC5ib3hJZCwgYm94LnNwZW50VHJhbnNhY3Rpb25JZClcbiAgICAgIDogdW5kZWZpbmVkO1xuICAgIHJldHVybiB7XG4gICAgICBibG9ja0lkOiBib3guYmxvY2tJZCxcbiAgICAgIGJveElkOiBib3guYm94SWQsXG4gICAgICBjcmVhdGlvbkhlaWdodDogYm94LmNyZWF0aW9uSGVpZ2h0LFxuICAgICAgaW5jbHVzaW9uSGVpZ2h0OiBib3guc2V0dGxlbWVudEhlaWdodCxcbiAgICAgIGVyZ29UcmVlOiBib3guZXJnb1RyZWUsXG4gICAgICBpbmRleDogYm94LmluZGV4LFxuICAgICAgdHJhbnNhY3Rpb25JZDogYm94LnRyYW5zYWN0aW9uSWQsXG4gICAgICB2YWx1ZTogYm94LnZhbHVlLFxuICAgICAgYWRkaXRpb25hbFJlZ2lzdGVyczogbWFwVmFsdWVzKFxuICAgICAgICBib3guYWRkaXRpb25hbFJlZ2lzdGVycyxcbiAgICAgICAgJ3NlcmlhbGl6ZWRWYWx1ZScsXG4gICAgICApLFxuICAgICAgYXNzZXRzOlxuICAgICAgICBib3guYXNzZXRzPy5tYXAoKGFzc2V0KSA9PiBwaWNrKGFzc2V0LCBbJ3Rva2VuSWQnLCAnYW1vdW50J10pKSA/PyBbXSxcbiAgICAgIHNwZW50SGVpZ2h0OiBzcGVuZEluZm8/LmhlaWdodCxcbiAgICAgIHNwZW50QmxvY2tJZDogc3BlbmRJbmZvPy5oYXNoLFxuICAgICAgc3BlbnRUcmFuc2FjdGlvbklkOiBib3guc3BlbnRUcmFuc2FjdGlvbklkLFxuICAgICAgc3BlbnRJbmRleDogc3BlbmRJbmZvPy5zcGVuZEluZGV4LFxuICAgIH07XG4gIH07XG5cbiAgLyoqXG4gICAqIGNvbnZlcnQgZXhwbG9yZXIgdHJhbnNhY3Rpb24gdG8gZXh0cmFjdG9yIHRyYW5zYWN0aW9uIHR5cGVcbiAgICogQHBhcmFtIHR4XG4gICAqL1xuICBwcml2YXRlIGNvbnZlcnRUcmFuc2FjdGlvbiA9IChcbiAgICB0eDogVjEuVHJhbnNhY3Rpb25JbmZvLFxuICApOiBFeHRlbmRlZFRyYW5zYWN0aW9uID0+IHtcbiAgICByZXR1cm4ge1xuICAgICAgaWQ6IHR4LmlkLFxuICAgICAgaW5jbHVzaW9uSGVpZ2h0OiB0eC5pbmNsdXNpb25IZWlnaHQsXG4gICAgICBibG9ja0lkOiB0eC5ibG9ja0lkLFxuICAgICAgZGF0YUlucHV0czpcbiAgICAgICAgdHguZGF0YUlucHV0cz8ubWFwKChkYXRhSW5wdXQpID0+ICh7XG4gICAgICAgICAgYm94SWQ6IGRhdGFJbnB1dC5ib3hJZCxcbiAgICAgICAgfSkpID8/IFtdLFxuICAgICAgLy8gVE9ETzogQWRkIGlucHV0IGV4dGVuc2lvbiB0byBleHBsb3JlciBsb2NhbC9lcmdvL3Jvc2VuLWJyaWRnZS9zY2FubmVyLy0vaXNzdWVzLzE1NlxuICAgICAgaW5wdXRzOiB0eC5pbnB1dHM/Lm1hcCgoaW5wdXQpID0+ICh7IGJveElkOiBpbnB1dC5ib3hJZCB9KSkgPz8gW10sXG4gICAgICBvdXRwdXRzOlxuICAgICAgICB0eC5vdXRwdXRzPy5tYXAoKG91dHB1dCkgPT4gKHtcbiAgICAgICAgICBib3hJZDogb3V0cHV0LmJveElkLFxuICAgICAgICAgIHRyYW5zYWN0aW9uSWQ6IG91dHB1dC50cmFuc2FjdGlvbklkLFxuICAgICAgICAgIGFkZGl0aW9uYWxSZWdpc3RlcnM6IG1hcFZhbHVlcyhcbiAgICAgICAgICAgIG91dHB1dC5hZGRpdGlvbmFsUmVnaXN0ZXJzLFxuICAgICAgICAgICAgJ3NlcmlhbGl6ZWRWYWx1ZScsXG4gICAgICAgICAgKSxcbiAgICAgICAgICBhc3NldHM6XG4gICAgICAgICAgICBvdXRwdXQuYXNzZXRzPy5tYXAoKGFzc2V0KSA9PiBwaWNrKGFzc2V0LCBbJ3Rva2VuSWQnLCAnYW1vdW50J10pKSA/P1xuICAgICAgICAgICAgW10sXG4gICAgICAgICAgZXJnb1RyZWU6IG91dHB1dC5lcmdvVHJlZSxcbiAgICAgICAgICBjcmVhdGlvbkhlaWdodDogb3V0cHV0LmNyZWF0aW9uSGVpZ2h0LFxuICAgICAgICAgIGluZGV4OiBvdXRwdXQuaW5kZXgsXG4gICAgICAgICAgdmFsdWU6IG91dHB1dC52YWx1ZSxcbiAgICAgICAgfSkpID8/IFtdLFxuICAgIH07XG4gIH07XG5cbiAgLyoqXG4gICAqIGNvbnZlcnQgZXhwbG9yZXIgYmxvY2sgdHJhbnNhY3Rpb24gdG8gdHJhbnNhY3Rpb24gdHlwZVxuICAgKiBAcGFyYW0gdHhcbiAgICovXG4gIHByaXZhdGUgY29udmVydEJsb2NrVHJhbnNhY3Rpb24gPSAodHg6IFYxLlRyYW5zYWN0aW9uSW5mbzEpOiBUcmFuc2FjdGlvbiA9PiB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGlkOiB0eC5pZCxcbiAgICAgIGRhdGFJbnB1dHM6XG4gICAgICAgIHR4LmRhdGFJbnB1dHM/Lm1hcCgoZGF0YUlucHV0KSA9PiAoe1xuICAgICAgICAgIGJveElkOiBkYXRhSW5wdXQuaWQsXG4gICAgICAgIH0pKSA/PyBbXSxcbiAgICAgIC8vIFRPRE86IEFkZCBpbnB1dCBleHRlbnNpb24gbG9jYWwvZXJnby9yb3Nlbi1icmlkZ2Uvc2Nhbm5lci8tL2lzc3Vlcy8xNTZcbiAgICAgIGlucHV0czogdHguaW5wdXRzPy5tYXAoKGlucHV0KSA9PiAoeyBib3hJZDogaW5wdXQuaWQgfSkpID8/IFtdLFxuICAgICAgb3V0cHV0czpcbiAgICAgICAgdHgub3V0cHV0cz8ubWFwKChvdXRwdXQpID0+ICh7XG4gICAgICAgICAgYm94SWQ6IG91dHB1dC5pZCxcbiAgICAgICAgICB0cmFuc2FjdGlvbklkOiBvdXRwdXQudHhJZCxcbiAgICAgICAgICBhZGRpdGlvbmFsUmVnaXN0ZXJzOiBvdXRwdXQuYWRkaXRpb25hbFJlZ2lzdGVycyxcbiAgICAgICAgICBhc3NldHM6XG4gICAgICAgICAgICBvdXRwdXQuYXNzZXRzPy5tYXAoKGFzc2V0KSA9PiBwaWNrKGFzc2V0LCBbJ3Rva2VuSWQnLCAnYW1vdW50J10pKSA/P1xuICAgICAgICAgICAgW10sXG4gICAgICAgICAgZXJnb1RyZWU6IG91dHB1dC5lcmdvVHJlZSxcbiAgICAgICAgICBjcmVhdGlvbkhlaWdodDogb3V0cHV0LmNyZWF0aW9uSGVpZ2h0LFxuICAgICAgICAgIGluZGV4OiBvdXRwdXQuaW5kZXgsXG4gICAgICAgICAgdmFsdWU6IG91dHB1dC52YWx1ZSxcbiAgICAgICAgfSkpID8/IFtdLFxuICAgIH07XG4gIH07XG5cbiAgLyoqXG4gICAqIHVzZSBleHBsb3JlciBhcGkgdG8gcmV0dXJuIHJlbGF0ZWQgdHJhbnNhY3Rpb25zIG9mIHRoZSBzcGVjaWZpZWQgYWRkcmVzcyBpbiB0aGUgaGVpZ2h0IHJhbmdlXG4gICAqIEBwYXJhbSB0b2tlbklkXG4gICAqIEBwYXJhbSBvZmZzZXRcbiAgICogQHBhcmFtIGxpbWl0XG4gICAqIEByZXR1cm5zIHJlbGF0ZWQgdHJhbnNhY3Rpb25zXG4gICAqL1xuICBnZXRBZGRyZXNzVHJhbnNhY3Rpb25zV2l0aEhlaWdodCA9IGFzeW5jIChcbiAgICBhZGRyZXNzOiBzdHJpbmcsXG4gICAgZnJvbUhlaWdodDogbnVtYmVyLFxuICAgIHRvSGVpZ2h0OiBudW1iZXIsXG4gICk6IFByb21pc2U8QXJyYXk8RXh0ZW5kZWRUcmFuc2FjdGlvbj4+ID0+IHtcbiAgICBjb25zdCB0eHMgPSBhd2FpdCB0aGlzLmFwaS52MS5nZXRBcGlWMUFkZHJlc3Nlc1AxVHJhbnNhY3Rpb25zKGFkZHJlc3MsIHtcbiAgICAgIGZyb21IZWlnaHQsXG4gICAgICB0b0hlaWdodCxcbiAgICAgIGxpbWl0OiBBUElfTElNSVQsXG4gICAgfSk7XG4gICAgaWYgKCF0eHMuaXRlbXMpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICdFeHBsb3JlciBBZGRyZXNzVHJhbnNhY3Rpb25zIGFwaSBleHBlY3RlZCB0byBoYXZlIGl0ZW1zJyxcbiAgICAgICk7XG4gICAgcmV0dXJuIHR4cy5pdGVtcy5tYXAoKHR4KSA9PiB0aGlzLmNvbnZlcnRUcmFuc2FjdGlvbih0eCkpO1xuICB9O1xuXG4gIC8qKlxuICAgKiB1c2UgZXhwbG9yZXIgYXBpIHRvIGdldCB0aGUgYmxvY2sgaWQgYXQgdGhlIHNwZWNpZmllZCBoZWlnaHRcbiAgICogQHBhcmFtIGhlaWdodFxuICAgKiBAcmV0dXJucyBibG9jayBpZFxuICAgKi9cbiAgZ2V0QmxvY2tJZEF0SGVpZ2h0ID0gYXN5bmMgKGhlaWdodDogbnVtYmVyKTogUHJvbWlzZTxzdHJpbmc+ID0+IHtcbiAgICBjb25zdCBpZCA9IGF3YWl0IHRoaXMuYXBpLnYwLmdldEFwaVYwQmxvY2tzQXRQMShoZWlnaHQpO1xuICAgIHJldHVybiBpZFswXTtcbiAgfTtcblxuICAvKipcbiAgICogdXNlIGV4cGxvcmVyIGFwaSB0byByZXR1cm4gYWxsIHRyYW5zYWN0aW9ucyBpbiBhIGJsb2NrXG4gICAqIEBwYXJhbSBibG9ja0lkXG4gICAqIEByZXR1cm5zIGNvbnZlcnRlZCB0cmFuc2FjdGlvbnNcbiAgICovXG4gIGdldEJsb2NrVHhzID0gYXN5bmMgKGJsb2NrSWQ6IHN0cmluZyk6IFByb21pc2U8QXJyYXk8VHJhbnNhY3Rpb24+PiA9PiB7XG4gICAgY29uc3QgYmxvY2sgPSBhd2FpdCB0aGlzLmFwaS52MS5nZXRBcGlWMUJsb2Nrc1AxKGJsb2NrSWQpO1xuICAgIGlmICghYmxvY2suYmxvY2suYmxvY2tUcmFuc2FjdGlvbnMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYEV4cGVjdGVkIGV4cGxvcmVyIGJsb2NrIGFwaSB0byBpbmNsdWRlIGJsb2NrIHRyYW5zYWN0aW9ucyBmb3IgYmxvY2sgJHtibG9ja0lkfWAsXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gYmxvY2suYmxvY2suYmxvY2tUcmFuc2FjdGlvbnMubWFwKCh0eCkgPT5cbiAgICAgIHRoaXMuY29udmVydEJsb2NrVHJhbnNhY3Rpb24odHgpLFxuICAgICk7XG4gIH07XG5cbiAgLyoqXG4gICAqIHVzZSBleHBsb3JlciBhcGkgdG8gcmV0dXJuIHJlbGF0ZWQgYm94ZXMgYnkgc3BlY2lmaWVkIGFkZHJlc3NcbiAgICogQHBhcmFtIGFkZHJlc3NcbiAgICogQHBhcmFtIG9mZnNldFxuICAgKiBAcGFyYW0gbGltaXRcbiAgICogQHJldHVybnMgcmVsYXRlZCBib3hlc1xuICAgKi9cbiAgZ2V0Qm94ZXNCeUFkZHJlc3MgPSBhc3luYyAoXG4gICAgYWRkcmVzczogc3RyaW5nLFxuICAgIG9mZnNldDogbnVtYmVyLFxuICAgIGxpbWl0OiBudW1iZXIsXG4gICk6IFByb21pc2U8eyBib3hlczogRXJnb0JveFtdOyBoYXNOZXh0QmF0Y2g6IGJvb2xlYW4gfT4gPT4ge1xuICAgIGNvbnN0IGJveGVzID0gYXdhaXQgdGhpcy5hcGkudjEuZ2V0QXBpVjFCb3hlc1Vuc3BlbnRCeWFkZHJlc3NQMShhZGRyZXNzLCB7XG4gICAgICBvZmZzZXQ6IG9mZnNldCxcbiAgICAgIGxpbWl0OiBsaW1pdCxcbiAgICAgIHNvcnREaXJlY3Rpb246ICdkZXNjJyxcbiAgICB9KTtcbiAgICBpZiAoIWJveGVzLml0ZW1zKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdFeHBsb3JlciBCb3hlc0J5QWRkcmVzcyBhcGkgZXhwZWN0ZWQgdG8gaGF2ZSBpdGVtcycpO1xuICAgIGNvbnN0IHJlc3VsdEJveGVzOiBBcnJheTxFcmdvQm94PiA9IFtdO1xuICAgIGZvciAoY29uc3QgYm94IG9mIGJveGVzLml0ZW1zKSB7XG4gICAgICByZXN1bHRCb3hlcy5wdXNoKGF3YWl0IHRoaXMuY29udmVydEJveChib3gpKTtcbiAgICB9XG4gICAgcmV0dXJuIHsgYm94ZXM6IHJlc3VsdEJveGVzLCBoYXNOZXh0QmF0Y2g6IGJveGVzLnRvdGFsID4gb2Zmc2V0ICsgbGltaXQgfTtcbiAgfTtcblxuICAvKipcbiAgICogdXNlIGV4cGxvcmVyIGFwaSB0byByZXR1cm4gcmVsYXRlZCBib3hlcyBieSBzcGVjaWZpZWQgdG9rZW4gaWRcbiAgICogQHBhcmFtIHRva2VuSWRcbiAgICogQHBhcmFtIG9mZnNldFxuICAgKiBAcGFyYW0gbGltaXRcbiAgICogQHJldHVybnMgcmVsYXRlZCBib3hlc1xuICAgKi9cbiAgZ2V0Qm94ZXNCeVRva2VuSWQgPSBhc3luYyAoXG4gICAgdG9rZW5JZDogc3RyaW5nLFxuICAgIG9mZnNldDogbnVtYmVyLFxuICAgIGxpbWl0OiBudW1iZXIsXG4gICk6IFByb21pc2U8eyBib3hlczogRXJnb0JveFtdOyBoYXNOZXh0QmF0Y2g6IGJvb2xlYW4gfT4gPT4ge1xuICAgIGNvbnN0IGJveGVzID0gYXdhaXQgdGhpcy5hcGkudjEuZ2V0QXBpVjFCb3hlc0J5dG9rZW5pZFAxKHRva2VuSWQsIHtcbiAgICAgIG9mZnNldDogb2Zmc2V0LFxuICAgICAgbGltaXQ6IGxpbWl0LFxuICAgIH0pO1xuICAgIGlmICghYm94ZXMuaXRlbXMpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0V4cGxvcmVyIEJveGVzQnlUb2tlSWQgYXBpIGV4cGVjdGVkIHRvIGhhdmUgaXRlbXMnKTtcbiAgICBjb25zdCByZXN1bHRCb3hlczogQXJyYXk8RXJnb0JveD4gPSBbXTtcbiAgICBmb3IgKGNvbnN0IGJveCBvZiBib3hlcy5pdGVtcykge1xuICAgICAgcmVzdWx0Qm94ZXMucHVzaChhd2FpdCB0aGlzLmNvbnZlcnRCb3goYm94KSk7XG4gICAgfVxuICAgIHJldHVybiB7IGJveGVzOiByZXN1bHRCb3hlcywgaGFzTmV4dEJhdGNoOiBib3hlcy50b3RhbCA+IG9mZnNldCArIGxpbWl0IH07XG4gIH07XG59XG4iXX0=