@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
@@ -0,0 +1,127 @@
1
+ import { mapValues, pick } from 'lodash-es';
2
+ import ergoExplorerClientFactory from '@rosen-clients/ergo-explorer';
3
+ import { API_LIMIT } from '../../constants';
4
+ export class ExplorerNetwork {
5
+ api;
6
+ constructor(url) {
7
+ this.api = ergoExplorerClientFactory(url);
8
+ }
9
+ /**
10
+ * convert explorer api output boxes to OutputBox interface
11
+ * @param box
12
+ * @returns OutputBox
13
+ */
14
+ convertOutputBox = (box) => {
15
+ return {
16
+ boxId: box.boxId,
17
+ creationHeight: box.creationHeight,
18
+ ergoTree: box.ergoTree,
19
+ index: box.index,
20
+ transactionId: box.transactionId,
21
+ value: box.value,
22
+ additionalRegisters: mapValues(box.additionalRegisters, 'serializedValue'),
23
+ assets: box.assets?.map((asset) => pick(asset, ['tokenId', 'amount'])) ?? [],
24
+ };
25
+ };
26
+ /**
27
+ * convert explorer api input boxes to OutputBox interface
28
+ * @param box
29
+ * @returns OutputBox
30
+ */
31
+ convertInputBox = (box) => {
32
+ return {
33
+ boxId: box.boxId,
34
+ creationHeight: box.outputCreatedAt,
35
+ ergoTree: box.ergoTree,
36
+ index: box.outputIndex,
37
+ transactionId: box.outputTransactionId,
38
+ value: box.value,
39
+ additionalRegisters: mapValues(box.additionalRegisters, 'serializedValue'),
40
+ assets: box.assets?.map((asset) => pick(asset, ['tokenId', 'amount'])) ?? [],
41
+ };
42
+ };
43
+ /**
44
+ * convert explorer transaction to extractor transaction type
45
+ * @param tx
46
+ */
47
+ convertTransaction = (tx) => {
48
+ return {
49
+ id: tx.id,
50
+ inclusionHeight: tx.inclusionHeight,
51
+ blockId: tx.blockId,
52
+ dataInputs: tx.dataInputs?.map((dataInput) => ({
53
+ boxId: dataInput.boxId,
54
+ })) ?? [],
55
+ // TODO: Add input extension to explorer local/ergo/rosen-bridge/scanner/-/issues/156
56
+ inputs: tx.inputs?.map((input) => this.convertInputBox(input)) ?? [],
57
+ outputs: tx.outputs?.map((output) => this.convertOutputBox(output)) ?? [],
58
+ };
59
+ };
60
+ /**
61
+ * convert explorer block transaction to transaction type
62
+ * @param tx
63
+ */
64
+ convertBlockTransaction = (tx) => {
65
+ return {
66
+ id: tx.id,
67
+ dataInputs: tx.dataInputs?.map((dataInput) => ({
68
+ boxId: dataInput.id,
69
+ })) ?? [],
70
+ // TODO: Add input extension local/ergo/rosen-bridge/scanner/-/issues/156
71
+ inputs: tx.inputs?.map((input) => ({ boxId: input.id })) ?? [],
72
+ outputs: tx.outputs?.map((output) => ({
73
+ boxId: output.id,
74
+ transactionId: output.txId,
75
+ additionalRegisters: output.additionalRegisters,
76
+ assets: output.assets?.map((asset) => pick(asset, ['tokenId', 'amount'])) ??
77
+ [],
78
+ ergoTree: output.ergoTree,
79
+ creationHeight: output.creationHeight,
80
+ index: output.index,
81
+ value: output.value,
82
+ })) ?? [],
83
+ };
84
+ };
85
+ /**
86
+ * use explorer api to return related transactions of the specified address in the height range
87
+ * @param tokenId
88
+ * @param offset
89
+ * @param limit
90
+ * @returns related transactions
91
+ */
92
+ getAddressTransactionsWithHeight = async (address, fromHeight, toHeight, limit = API_LIMIT) => {
93
+ const txs = await this.api.v1.getApiV1AddressesP1Transactions(address, {
94
+ fromHeight,
95
+ toHeight,
96
+ limit: limit,
97
+ });
98
+ if (!txs.items)
99
+ throw new Error('Explorer AddressTransactions api expected to have items');
100
+ return {
101
+ items: txs.items.map((tx) => this.convertTransaction(tx)),
102
+ total: txs.total,
103
+ };
104
+ };
105
+ /**
106
+ * use explorer api to get the block id at the specified height
107
+ * @param height
108
+ * @returns block id
109
+ */
110
+ getBlockIdAtHeight = async (height) => {
111
+ const id = await this.api.v0.getApiV0BlocksAtP1(height);
112
+ return id[0];
113
+ };
114
+ /**
115
+ * use explorer api to return all transactions in a block
116
+ * @param blockId
117
+ * @returns converted transactions
118
+ */
119
+ getBlockTxs = async (blockId) => {
120
+ const block = await this.api.v1.getApiV1BlocksP1(blockId);
121
+ if (!block.block.blockTransactions) {
122
+ throw new Error(`Expected explorer block api to include block transactions for block ${blockId}`);
123
+ }
124
+ return block.block.blockTransactions.map((tx) => this.convertBlockTransaction(tx));
125
+ };
126
+ }
127
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXhwbG9yZXJOZXR3b3JrLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vbGliL2VyZ28vbmV0d29ya3MvZXhwbG9yZXJOZXR3b3JrLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBRzVDLE9BQU8seUJBQXlCLE1BQU0sOEJBQThCLENBQUM7QUFHckUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBRzVDLE1BQU0sT0FBTyxlQUFlO0lBQ2xCLEdBQUcsQ0FBQztJQUVaLFlBQVksR0FBVztRQUNyQixJQUFJLENBQUMsR0FBRyxHQUFHLHlCQUF5QixDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQzVDLENBQUM7SUFFRDs7OztPQUlHO0lBQ0ssZ0JBQWdCLEdBQUcsQ0FBQyxHQUFrQixFQUFhLEVBQUU7UUFDM0QsT0FBTztZQUNMLEtBQUssRUFBRSxHQUFHLENBQUMsS0FBSztZQUNoQixjQUFjLEVBQUUsR0FBRyxDQUFDLGNBQWM7WUFDbEMsUUFBUSxFQUFFLEdBQUcsQ0FBQyxRQUFRO1lBQ3RCLEtBQUssRUFBRSxHQUFHLENBQUMsS0FBSztZQUNoQixhQUFhLEVBQUUsR0FBRyxDQUFDLGFBQWE7WUFDaEMsS0FBSyxFQUFFLEdBQUcsQ0FBQyxLQUFLO1lBQ2hCLG1CQUFtQixFQUFFLFNBQVMsQ0FDNUIsR0FBRyxDQUFDLG1CQUFtQixFQUN2QixpQkFBaUIsQ0FDbEI7WUFDRCxNQUFNLEVBQ0osR0FBRyxDQUFDLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQyxTQUFTLEVBQUUsUUFBUSxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUU7U0FDdkUsQ0FBQztJQUNKLENBQUMsQ0FBQztJQUVGOzs7O09BSUc7SUFDSyxlQUFlLEdBQUcsQ0FBQyxHQUFpQixFQUFh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aUIsRUFBRSxDQUFDO1lBQ25DLE1BQU0sSUFBSSxLQUFLLENBQ2IsdUVBQXVFLE9BQU8sRUFBRSxDQUNqRixDQUFDO1FBQ0osQ0FBQztRQUNELE9BQU8sS0FBSyxDQUFDLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUM5QyxJQUFJLENBQUMsdUJBQXVCLENBQUMsRUFBRSxDQUFDLENBQ2pDLENBQUM7SUFDSixDQUFDLENBQUM7Q0FDSCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IG1hcFZhbHVlcywgcGljayB9IGZyb20gJ2xvZGFzaC1lcyc7XG5cbmltcG9ydCB7IE91dHB1dEJveCwgVHJhbnNhY3Rpb24gfSBmcm9tICdAcm9zZW4tYnJpZGdlL3NjYW5uZXItaW50ZXJmYWNlcyc7XG5pbXBvcnQgZXJnb0V4cGxvcmVyQ2xpZW50RmFjdG9yeSBmcm9tICdAcm9zZW4tY2xpZW50cy9lcmdvLWV4cGxvcmVyJztcbmltcG9ydCB7IFYxIH0gZnJvbSAnQHJvc2VuLWNsaWVudHMvZXJnby1leHBsb3Jlcic7XG5cbmltcG9ydCB7IEFQSV9MSU1JVCB9IGZyb20gJy4uLy4uL2NvbnN0YW50cyc7XG5pbXBvcnQgeyBFeHRlbmRlZFRyYW5zYWN0aW9uIH0gZnJvbSAnLi4vaW50ZXJmYWNlcyc7XG5cbmV4cG9ydCBjbGFzcyBFeHBsb3Jlck5ldHdvcmsge1xuICBwcml2YXRlIGFwaTtcblxuICBjb25zdHJ1Y3Rvcih1cmw6IHN0cmluZykge1xuICAgIHRoaXMuYXBpID0gZXJnb0V4cGxvcmVyQ2xpZW50RmFjdG9yeSh1cmwpO1xuICB9XG5cbiAgLyoqXG4gICAqIGNvbnZlcnQgZXhwbG9yZXIgYXBpIG91dHB1dCBib3hlcyB0byBPdXRwdXRCb3ggaW50ZXJmYWNlXG4gICAqIEBwYXJhbSBib3hcbiAgICogQHJldHVybnMgT3V0cHV0Qm94XG4gICAqL1xuICBwcml2YXRlIGNvbnZlcnRPdXRwdXRCb3ggPSAoYm94OiBWMS5PdXRwdXRJbmZvKTogT3V0cHV0Qm94ID0+IHtcbiAgICByZXR1cm4ge1xuICAgICAgYm94SWQ6IGJveC5ib3hJZCxcbiAgICAgIGNyZWF0aW9uSGVpZ2h0OiBib3guY3JlYXRpb25IZWlnaHQsXG4gICAgICBlcmdvVHJlZTogYm94LmVyZ29UcmVlLFxuICAgICAgaW5kZXg6IGJveC5pbmRleCxcbiAgICAgIHRyYW5zYWN0aW9uSWQ6IGJveC50cmFuc2FjdGlvbklkLFxuICAgICAgdmFsdWU6IGJveC52YWx1ZSxcbiAgICAgIGFkZGl0aW9uYWxSZWdpc3RlcnM6IG1hcFZhbHVlcyhcbiAgICAgICAgYm94LmFkZGl0aW9uYWxSZWdpc3RlcnMsXG4gICAgICAgICdzZXJpYWxpemVkVmFsdWUnLFxuICAgICAgKSxcbiAgICAgIGFzc2V0czpcbiAgICAgICAgYm94LmFzc2V0cz8ubWFwKChhc3NldCkgPT4gcGljayhhc3NldCwgWyd0b2tlbklkJywgJ2Ftb3VudCddKSkgPz8gW10sXG4gICAgfTtcbiAgfTtcblxuICAvKipcbiAgICogY29udmVydCBleHBsb3JlciBhcGkgaW5wdXQgYm94ZXMgdG8gT3V0cHV0Qm94IGludGVyZmFjZVxuICAgKiBAcGFyYW0gYm94XG4gICAqIEByZXR1cm5zIE91dHB1dEJveFxuICAgKi9cbiAgcHJpdmF0ZSBjb252ZXJ0SW5wdXRCb3ggPSAoYm94OiBWMS5JbnB1dEluZm8pOiBPdXRwdXRCb3ggPT4ge1xuICAgIHJldHVybiB7XG4gICAgICBib3hJZDogYm94LmJveElkLFxuICAgICAgY3JlYXRpb25IZWlnaHQ6IGJveC5vdXRwdXRDcmVhdGVkQXQsXG4gICAgICBlcmdvVHJlZTogYm94LmVyZ29UcmVlLFxuICAgICAgaW5kZXg6IGJveC5vdXRwdXRJbmRleCxcbiAgICAgIHRyYW5zYWN0aW9uSWQ6IGJveC5vdXRwdXRUcmFuc2FjdGlvbklkLFxuICAgICAgdmFsdWU6IGJveC52YWx1ZSxcbiAgICAgIGFkZGl0aW9uYWxSZWdpc3RlcnM6IG1hcFZhbHVlcyhcbiAgICAgICAgYm94LmFkZGl0aW9uYWxSZWdpc3RlcnMsXG4gICAgICAgICdzZXJpYWxpemVkVmFsdWUnLFxuICAgICAgKSxcbiAgICAgIGFzc2V0czpcbiAgICAgICAgYm94LmFzc2V0cz8ubWFwKChhc3NldCkgPT4gcGljayhhc3NldCwgWyd0b2tlbklkJywgJ2Ftb3VudCddKSkgPz8gW10sXG4gICAgfTtcbiAgfTtcblxuICAvKipcbiAgICogY29udmVydCBleHBsb3JlciB0cmFuc2FjdGlvbiB0byBleHRyYWN0b3IgdHJhbnNhY3Rpb24gdHlwZVxuICAgKiBAcGFyYW0gdHhcbiAgICovXG4gIHByaXZhdGUgY29udmVydFRyYW5zYWN0aW9uID0gKFxuICAgIHR4OiBWMS5UcmFuc2FjdGlvbkluZm8sXG4gICk6IEV4dGVuZGVkVHJhbnNhY3Rpb24gPT4ge1xuICAgIHJldHVybiB7XG4gICAgICBpZDogdHguaWQsXG4gICAgICBpbmNsdXNpb25IZWlnaHQ6IHR4LmluY2x1c2lvbkhlaWdodCxcbiAgICAgIGJsb2NrSWQ6IHR4LmJsb2NrSWQsXG4gICAgICBkYXRhSW5wdXRzOlxuICAgICAgICB0eC5kYXRhSW5wdXRzPy5tYXAoKGRhdGFJbnB1dCkgPT4gKHtcbiAgICAgICAgICBib3hJZDogZGF0YUlucHV0LmJveElkLFxuICAgICAgICB9KSkgPz8gW10sXG4gICAgICAvLyBUT0RPOiBBZGQgaW5wdXQgZXh0ZW5zaW9uIHRvIGV4cGxvcmVyIGxvY2FsL2VyZ28vcm9zZW4tYnJpZGdlL3NjYW5uZXIvLS9pc3N1ZXMvMTU2XG4gICAgICBpbnB1dHM6IHR4LmlucHV0cz8ubWFwKChpbnB1dCkgPT4gdGhpcy5jb252ZXJ0SW5wdXRCb3goaW5wdXQpKSA/PyBbXSxcbiAgICAgIG91dHB1dHM6IHR4Lm91dHB1dHM/Lm1hcCgob3V0cHV0KSA9PiB0aGlzLmNvbnZlcnRPdXRwdXRCb3gob3V0cHV0KSkgPz8gW10sXG4gICAgfTtcbiAgfTtcblxuICAvKipcbiAgICogY29udmVydCBleHBsb3JlciBibG9jayB0cmFuc2FjdGlvbiB0byB0cmFuc2FjdGlvbiB0eXBlXG4gICAqIEBwYXJhbSB0eFxuICAgKi9cbiAgcHJpdmF0ZSBjb252ZXJ0QmxvY2tUcmFuc2FjdGlvbiA9ICh0eDogVjEuVHJhbnNhY3Rpb25JbmZvMSk6IFRyYW5zYWN0aW9uID0+IHtcbiAgICByZXR1cm4ge1xuICAgICAgaWQ6IHR4LmlkLFxuICAgICAgZGF0YUlucHV0czpcbiAgICAgICAgdHguZGF0YUlucHV0cz8ubWFwKChkYXRhSW5wdXQpID0+ICh7XG4gICAgICAgICAgYm94SWQ6IGRhdGFJbnB1dC5pZCxcbiAgICAgICAgfSkpID8/IFtdLFxuICAgICAgLy8gVE9ETzogQWRkIGlucHV0IGV4dGVuc2lvbiBsb2NhbC9lcmdvL3Jvc2VuLWJyaWRnZS9zY2FubmVyLy0vaXNzdWVzLzE1NlxuICAgICAgaW5wdXRzOiB0eC5pbnB1dHM/Lm1hcCgoaW5wdXQpID0+ICh7IGJveElkOiBpbnB1dC5pZCB9KSkgPz8gW10sXG4gICAgICBvdXRwdXRzOlxuICAgICAgICB0eC5vdXRwdXRzPy5tYXAoKG91dHB1dCkgPT4gKHtcbiAgICAgICAgICBib3hJZDogb3V0cHV0LmlkLFxuICAgICAgICAgIHRyYW5zYWN0aW9uSWQ6IG91dHB1dC50eElkLFxuICAgICAgICAgIGFkZGl0aW9uYWxSZWdpc3RlcnM6IG91dHB1dC5hZGRpdGlvbmFsUmVnaXN0ZXJzLFxuICAgICAgICAgIGFzc2V0czpcbiAgICAgICAgICAgIG91dHB1dC5hc3NldHM/Lm1hcCgoYXNzZXQpID0+IHBpY2soYXNzZXQsIFsndG9rZW5JZCcsICdhbW91bnQnXSkpID8/XG4gICAgICAgICAgICBbXSxcbiAgICAgICAgICBlcmdvVHJlZTogb3V0cHV0LmVyZ29UcmVlLFxuICAgICAgICAgIGNyZWF0aW9uSGVpZ2h0OiBvdXRwdXQuY3JlYXRpb25IZWlnaHQsXG4gICAgICAgICAgaW5kZXg6IG91dHB1dC5pbmRleCxcbiAgICAgICAgICB2YWx1ZTogb3V0cHV0LnZhbHVlLFxuICAgICAgICB9KSkgPz8gW10sXG4gICAgfTtcbiAgfTtcblxuICAvKipcbiAgICogdXNlIGV4cGxvcmVyIGFwaSB0byByZXR1cm4gcmVsYXRlZCB0cmFuc2FjdGlvbnMgb2YgdGhlIHNwZWNpZmllZCBhZGRyZXNzIGluIHRoZSBoZWlnaHQgcmFuZ2VcbiAgICogQHBhcmFtIHRva2VuSWRcbiAgICogQHBhcmFtIG9mZnNldFxuICAgKiBAcGFyYW0gbGltaXRcbiAgICogQHJldHVybnMgcmVsYXRlZCB0cmFuc2FjdGlvbnNcbiAgICovXG4gIGdldEFkZHJlc3NUcmFuc2FjdGlvbnNXaXRoSGVpZ2h0ID0gYXN5bmMgKFxuICAgIGFkZHJlc3M6IHN0cmluZyxcbiAgICBmcm9tSGVpZ2h0OiBudW1iZXIsXG4gICAgdG9IZWlnaHQ6IG51bWJlcixcbiAgICBsaW1pdCA9IEFQSV9MSU1JVCxcbiAgKTogUHJvbWlzZTx7IGl0ZW1zOiBBcnJheTxFeHRlbmRlZFRyYW5zYWN0aW9uPjsgdG90YWw6IG51bWJlciB9PiA9PiB7XG4gICAgY29uc3QgdHhzID0gYXdhaXQgdGhpcy5hcGkudjEuZ2V0QXBpVjFBZGRyZXNzZXNQMVRyYW5zYWN0aW9ucyhhZGRyZXNzLCB7XG4gICAgICBmcm9tSGVpZ2h0LFxuICAgICAgdG9IZWlnaHQsXG4gICAgICBsaW1pdDogbGltaXQsXG4gICAgfSk7XG4gICAgaWYgKCF0eHMuaXRlbXMpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICdFeHBsb3JlciBBZGRyZXNzVHJhbnNhY3Rpb25zIGFwaSBleHBlY3RlZCB0byBoYXZlIGl0ZW1zJyxcbiAgICAgICk7XG4gICAgcmV0dXJuIHtcbiAgICAgIGl0ZW1zOiB0eHMuaXRlbXMubWFwKCh0eCkgPT4gdGhpcy5jb252ZXJ0VHJhbnNhY3Rpb24odHgpKSxcbiAgICAgIHRvdGFsOiB0eHMudG90YWwsXG4gICAgfTtcbiAgfTtcblxuICAvKipcbiAgICogdXNlIGV4cGxvcmVyIGFwaSB0byBnZXQgdGhlIGJsb2NrIGlkIGF0IHRoZSBzcGVjaWZpZWQgaGVpZ2h0XG4gICAqIEBwYXJhbSBoZWlnaHRcbiAgICogQHJldHVybnMgYmxvY2sgaWRcbiAgICovXG4gIGdldEJsb2NrSWRBdEhlaWdodCA9IGFzeW5jIChoZWlnaHQ6IG51bWJlcik6IFByb21pc2U8c3RyaW5nPiA9PiB7XG4gICAgY29uc3QgaWQgPSBhd2FpdCB0aGlzLmFwaS52MC5nZXRBcGlWMEJsb2Nrc0F0UDEoaGVpZ2h0KTtcbiAgICByZXR1cm4gaWRbMF07XG4gIH07XG5cbiAgLyoqXG4gICAqIHVzZSBleHBsb3JlciBhcGkgdG8gcmV0dXJuIGFsbCB0cmFuc2FjdGlvbnMgaW4gYSBibG9ja1xuICAgKiBAcGFyYW0gYmxvY2tJZFxuICAgKiBAcmV0dXJucyBjb252ZXJ0ZWQgdHJhbnNhY3Rpb25zXG4gICAqL1xuICBnZXRCbG9ja1R4cyA9IGFzeW5jIChibG9ja0lkOiBzdHJpbmcpOiBQcm9taXNlPEFycmF5PFRyYW5zYWN0aW9uPj4gPT4ge1xuICAgIGNvbnN0IGJsb2NrID0gYXdhaXQgdGhpcy5hcGkudjEuZ2V0QXBpVjFCbG9ja3NQMShibG9ja0lkKTtcbiAgICBpZiAoIWJsb2NrLmJsb2NrLmJsb2NrVHJhbnNhY3Rpb25zKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBFeHBlY3RlZCBleHBsb3JlciBibG9jayBhcGkgdG8gaW5jbHVkZSBibG9jayB0cmFuc2FjdGlvbnMgZm9yIGJsb2NrICR7YmxvY2tJZH1gLFxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIGJsb2NrLmJsb2NrLmJsb2NrVHJhbnNhY3Rpb25zLm1hcCgodHgpID0+XG4gICAgICB0aGlzLmNvbnZlcnRCbG9ja1RyYW5zYWN0aW9uKHR4KSxcbiAgICApO1xuICB9O1xufVxuIl19
@@ -0,0 +1,3 @@
1
+ export * from './explorerNetwork';
2
+ export * from './nodeNetwork';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../lib/ergo/networks/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from './explorerNetwork';
2
+ export * from './nodeNetwork';
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9saWIvZXJnby9uZXR3b3Jrcy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjLG1CQUFtQixDQUFDO0FBQ2xDLGNBQWMsZUFBZSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0ICogZnJvbSAnLi9leHBsb3Jlck5ldHdvcmsnO1xuZXhwb3J0ICogZnJvbSAnLi9ub2RlTmV0d29yayc7XG4iXX0=
@@ -0,0 +1,28 @@
1
+ import { ExtendedTransaction } from '../interfaces';
2
+ export declare class NodeNetwork {
3
+ private api;
4
+ constructor(url: string);
5
+ /**
6
+ * convert node api boxes to OutputBox interface
7
+ * @param box
8
+ * @returns ErgoBox
9
+ */
10
+ private convertBox;
11
+ /**
12
+ * convert Node transaction to extractor transaction type
13
+ * @param tx
14
+ */
15
+ private convertTransaction;
16
+ /**
17
+ * use node api to return related transactions of the specified address with limit offset
18
+ * @param address
19
+ * @param offset
20
+ * @param limit
21
+ * @returns related transactions
22
+ */
23
+ getAddressTransactionsWithOffsetLimit: (address: string, offset: number, limit: number) => Promise<{
24
+ items: Array<ExtendedTransaction>;
25
+ total: number;
26
+ }>;
27
+ }
28
+ //# sourceMappingURL=nodeNetwork.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nodeNetwork.d.ts","sourceRoot":"","sources":["../../../lib/ergo/networks/nodeNetwork.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAEpD,qBAAa,WAAW;IACtB,OAAO,CAAC,GAAG,CAAC;gBAEA,GAAG,EAAE,MAAM;IAIvB;;;;OAIG;IACH,OAAO,CAAC,UAAU,CAWhB;IAEF;;;OAGG;IACH,OAAO,CAAC,kBAAkB,CAYxB;IAEF;;;;;;OAMG;IACH,qCAAqC,GACnC,SAAS,MAAM,EACf,QAAQ,MAAM,EACd,OAAO,MAAM,KACZ,OAAO,CAAC;QAAE,KAAK,EAAE,KAAK,CAAC,mBAAmB,CAAC,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAa9D;CACH"}
@@ -0,0 +1,59 @@
1
+ import ergoNodeClientFactory from '@rosen-clients/ergo-node';
2
+ export class NodeNetwork {
3
+ api;
4
+ constructor(url) {
5
+ this.api = ergoNodeClientFactory(url);
6
+ }
7
+ /**
8
+ * convert node api boxes to OutputBox interface
9
+ * @param box
10
+ * @returns ErgoBox
11
+ */
12
+ convertBox = (box) => {
13
+ return {
14
+ transactionId: box.transactionId || '',
15
+ index: box.index || 0,
16
+ value: box.value || 0n,
17
+ ergoTree: box.ergoTree || '',
18
+ creationHeight: box.creationHeight || 0,
19
+ assets: box.assets || [],
20
+ additionalRegisters: box.additionalRegisters,
21
+ boxId: box.boxId || '',
22
+ };
23
+ };
24
+ /**
25
+ * convert Node transaction to extractor transaction type
26
+ * @param tx
27
+ */
28
+ convertTransaction = (tx) => {
29
+ return {
30
+ id: tx.id || '',
31
+ inclusionHeight: tx.inclusionHeight,
32
+ blockId: tx.blockId,
33
+ outputs: tx.outputs.map((output) => this.convertBox(output)),
34
+ // TODO: Add input extension local/ergo/rosen-bridge/scanner/-/issues/156
35
+ inputs: tx.inputs.map((input) => this.convertBox(input)),
36
+ dataInputs: tx.dataInputs,
37
+ };
38
+ };
39
+ /**
40
+ * use node api to return related transactions of the specified address with limit offset
41
+ * @param address
42
+ * @param offset
43
+ * @param limit
44
+ * @returns related transactions
45
+ */
46
+ getAddressTransactionsWithOffsetLimit = async (address, offset, limit) => {
47
+ const txs = await this.api.getTxsByAddress(address, {
48
+ offset,
49
+ limit,
50
+ });
51
+ if (!txs.items)
52
+ throw new Error('Explorer AddressTransactions api expected to have items');
53
+ return {
54
+ items: txs.items.map((tx) => this.convertTransaction(tx)),
55
+ total: txs.total,
56
+ };
57
+ };
58
+ }
59
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9kZU5ldHdvcmsuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9saWIvZXJnby9uZXR3b3Jrcy9ub2RlTmV0d29yay50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLHFCQUdOLE1BQU0sMEJBQTBCLENBQUM7QUFJbEMsTUFBTSxPQUFPLFdBQVc7SUFDZCxHQUFHLENBQUM7SUFFWixZQUFZLEdBQVc7UUFDckIsSUFBSSxDQUFDLEdBQUcsR0FBRyxxQkFBcUIsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUN4QyxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNLLFVBQVUsR0FBRyxDQUFDLEdBQW1CLEVBQWEsRUFBRTtRQUN0RCxPQUFPO1lBQ0wsYUFBYSxFQUFFLEdBQUcsQ0FBQyxhQUFhLElBQUksRUFBRTtZQUN0QyxLQUFLLEVBQUUsR0FBRyxDQUFDLEtBQUssSUFBSSxDQUFDO1lBQ3JCLEtBQUssRUFBRSxHQUFHLENBQUMsS0FBSyxJQUFJLEVBQUU7WUFDdEIsUUFBUSxFQUFFLEdBQUcsQ0FBQyxRQUFRLElBQUksRUFBRTtZQUM1QixjQUFjLEVBQUUsR0FBRyxDQUFDLGNBQWMsSUFBSSxDQUFDO1lBQ3ZDLE1BQU0sRUFBRSxHQUFHLENBQUMsTUFBTSxJQUFJLEVBQUU7WUFDeEIsbUJBQW1CLEVBQUUsR0FBRyxDQUFDLG1CQUFtQjtZQUM1QyxLQUFLLEVBQUUsR0FBRyxDQUFDLEtBQUssSUFBSSxFQUFFO1NBQ3ZCLENBQUM7SUFDSixDQUFDLENBQUM7SUFFRjs7O09BR0c7SUFDSyxrQkFBa0IsR0FBRyxDQUMzQixFQUEwQixFQUNMLEVBQUU7UUFDdkIsT0FBTztZQUNMLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUU7WUFDZixlQUFlLEVBQUUsRUFBRSxDQUFDLGVBQWU7WUFDbkMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxPQUFPO1lBQ25CLE9BQU8sRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUM1RCx5RUFBeUU7WUFDekUsTUFBTSxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3hELFVBQVUsRUFBRSxFQUFFLENBQUMsVUFBVTtTQUMxQixDQUFDO0lBQ0osQ0FBQyxDQUFDO0lBRUY7Ozs7OztPQU1HO0lBQ0gscUNBQXFDLEdBQUcsS0FBSyxFQUMzQyxPQUFlLEVBQ2YsTUFBYyxFQUNkLEtBQWEsRUFDa0QsRUFBRTtRQUNqRSxNQUFNLEdBQUcsR0FBRyxNQUFNLElBQUksQ0FBQyxHQUFHLENBQUMsZUFBZSxDQUFDLE9BQU8sRUFBRTtZQUNsRCxNQUFNO1lBQ04sS0FBSztTQUNOLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSztZQUNaLE1BQU0sSUFBSSxLQUFLLENBQ2IseURBQXlELENBQzFELENBQUM7UUFDSixPQUFPO1lBQ0wsS0FBSyxFQUFFLEdBQUcsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDekQsS0FBSyxFQUFFLEdBQUcsQ0FBQyxLQUFNO1NBQ2xCLENBQUM7SUFDSixDQUFDLENBQUM7Q0FDSCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IE91dHB1dEJveCB9IGZyb20gJ0Byb3Nlbi1icmlkZ2Uvc2Nhbm5lci1pbnRlcmZhY2VzJztcbmltcG9ydCBlcmdvTm9kZUNsaWVudEZhY3RvcnksIHtcbiAgSW5kZXhlZEVyZ29Cb3gsXG4gIEluZGV4ZWRFcmdvVHJhbnNhY3Rpb24sXG59IGZyb20gJ0Byb3Nlbi1jbGllbnRzL2VyZ28tbm9kZSc7XG5cbmltcG9ydCB7IEV4dGVuZGVkVHJhbnNhY3Rpb24gfSBmcm9tICcuLi9pbnRlcmZhY2VzJztcblxuZXhwb3J0IGNsYXNzIE5vZGVOZXR3b3JrIHtcbiAgcHJpdmF0ZSBhcGk7XG5cbiAgY29uc3RydWN0b3IodXJsOiBzdHJpbmcpIHtcbiAgICB0aGlzLmFwaSA9IGVyZ29Ob2RlQ2xpZW50RmFjdG9yeSh1cmwpO1xuICB9XG5cbiAgLyoqXG4gICAqIGNvbnZlcnQgbm9kZSBhcGkgYm94ZXMgdG8gT3V0cHV0Qm94IGludGVyZmFjZVxuICAgKiBAcGFyYW0gYm94XG4gICAqIEByZXR1cm5zIEVyZ29Cb3hcbiAgICovXG4gIHByaXZhdGUgY29udmVydEJveCA9IChib3g6IEluZGV4ZWRFcmdvQm94KTogT3V0cHV0Qm94ID0+IHtcbiAgICByZXR1cm4ge1xuICAgICAgdHJhbnNhY3Rpb25JZDogYm94LnRyYW5zYWN0aW9uSWQgfHwgJycsXG4gICAgICBpbmRleDogYm94LmluZGV4IHx8IDAsXG4gICAgICB2YWx1ZTogYm94LnZhbHVlIHx8IDBuLFxuICAgICAgZXJnb1RyZWU6IGJveC5lcmdvVHJlZSB8fCAnJyxcbiAgICAgIGNyZWF0aW9uSGVpZ2h0OiBib3guY3JlYXRpb25IZWlnaHQgfHwgMCxcbiAgICAgIGFzc2V0czogYm94LmFzc2V0cyB8fCBbXSxcbiAgICAgIGFkZGl0aW9uYWxSZWdpc3RlcnM6IGJveC5hZGRpdGlvbmFsUmVnaXN0ZXJzLFxuICAgICAgYm94SWQ6IGJveC5ib3hJZCB8fCAnJyxcbiAgICB9O1xuICB9O1xuXG4gIC8qKlxuICAgKiBjb252ZXJ0IE5vZGUgdHJhbnNhY3Rpb24gdG8gZXh0cmFjdG9yIHRyYW5zYWN0aW9uIHR5cGVcbiAgICogQHBhcmFtIHR4XG4gICAqL1xuICBwcml2YXRlIGNvbnZlcnRUcmFuc2FjdGlvbiA9IChcbiAgICB0eDogSW5kZXhlZEVyZ29UcmFuc2FjdGlvbixcbiAgKTogRXh0ZW5kZWRUcmFuc2FjdGlvbiA9PiB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGlkOiB0eC5pZCB8fCAnJyxcbiAgICAgIGluY2x1c2lvbkhlaWdodDogdHguaW5jbHVzaW9uSGVpZ2h0LFxuICAgICAgYmxvY2tJZDogdHguYmxvY2tJZCxcbiAgICAgIG91dHB1dHM6IHR4Lm91dHB1dHMubWFwKChvdXRwdXQpID0+IHRoaXMuY29udmVydEJveChvdXRwdXQpKSxcbiAgICAgIC8vIFRPRE86IEFkZCBpbnB1dCBleHRlbnNpb24gbG9jYWwvZXJnby9yb3Nlbi1icmlkZ2Uvc2Nhbm5lci8tL2lzc3Vlcy8xNTZcbiAgICAgIGlucHV0czogdHguaW5wdXRzLm1hcCgoaW5wdXQpID0+IHRoaXMuY29udmVydEJveChpbnB1dCkpLFxuICAgICAgZGF0YUlucHV0czogdHguZGF0YUlucHV0cyxcbiAgICB9O1xuICB9O1xuXG4gIC8qKlxuICAgKiB1c2Ugbm9kZSBhcGkgdG8gcmV0dXJuIHJlbGF0ZWQgdHJhbnNhY3Rpb25zIG9mIHRoZSBzcGVjaWZpZWQgYWRkcmVzcyB3aXRoIGxpbWl0IG9mZnNldFxuICAgKiBAcGFyYW0gYWRkcmVzc1xuICAgKiBAcGFyYW0gb2Zmc2V0XG4gICAqIEBwYXJhbSBsaW1pdFxuICAgKiBAcmV0dXJucyByZWxhdGVkIHRyYW5zYWN0aW9uc1xuICAgKi9cbiAgZ2V0QWRkcmVzc1RyYW5zYWN0aW9uc1dpdGhPZmZzZXRMaW1pdCA9IGFzeW5jIChcbiAgICBhZGRyZXNzOiBzdHJpbmcsXG4gICAgb2Zmc2V0OiBudW1iZXIsXG4gICAgbGltaXQ6IG51bWJlcixcbiAgKTogUHJvbWlzZTx7IGl0ZW1zOiBBcnJheTxFeHRlbmRlZFRyYW5zYWN0aW9uPjsgdG90YWw6IG51bWJlciB9PiA9PiB7XG4gICAgY29uc3QgdHhzID0gYXdhaXQgdGhpcy5hcGkuZ2V0VHhzQnlBZGRyZXNzKGFkZHJlc3MsIHtcbiAgICAgIG9mZnNldCxcbiAgICAgIGxpbWl0LFxuICAgIH0pO1xuICAgIGlmICghdHhzLml0ZW1zKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAnRXhwbG9yZXIgQWRkcmVzc1RyYW5zYWN0aW9ucyBhcGkgZXhwZWN0ZWQgdG8gaGF2ZSBpdGVtcycsXG4gICAgICApO1xuICAgIHJldHVybiB7XG4gICAgICBpdGVtczogdHhzLml0ZW1zLm1hcCgodHgpID0+IHRoaXMuY29udmVydFRyYW5zYWN0aW9uKHR4KSksXG4gICAgICB0b3RhbDogdHhzLnRvdGFsISxcbiAgICB9O1xuICB9O1xufVxuIl19
@@ -1,3 +1,4 @@
1
+ import { DummyLogger } from '@rosen-bridge/abstract-logger';
1
2
  import { OutputBox } from '@rosen-bridge/scanner-interfaces';
2
3
  /**
3
4
  * Check box to have specified tokens
@@ -5,4 +6,18 @@ import { OutputBox } from '@rosen-bridge/scanner-interfaces';
5
6
  * @return true if box has the required token and false otherwise
6
7
  */
7
8
  export declare const boxHasToken: (box: OutputBox, tokenIds: string[]) => boolean;
9
+ /**
10
+ * Create delay in procedures based on the specified time in milliseconds
11
+ * @param time
12
+ */
13
+ export declare const delay: (time: number) => Promise<unknown>;
14
+ /**
15
+ * Retry the request in case of failure
16
+ * Throw error if request fails after RETRIAL_COUNT retrials
17
+ * Wait for 1 second between each trial
18
+ * @param request
19
+ * @param logger
20
+ * @returns
21
+ */
22
+ export declare const requestWithRetrial: <returnT>(request: () => Promise<returnT>, logger?: DummyLogger) => Promise<returnT>;
8
23
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../lib/ergo/utils.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAC;AAE7D;;;;GAIG;AACH,eAAO,MAAM,WAAW,GAAI,KAAK,SAAS,EAAE,UAAU,MAAM,EAAE,YAM7D,CAAC"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../lib/ergo/utils.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAC;AAI7D;;;;GAIG;AACH,eAAO,MAAM,WAAW,GAAI,KAAK,SAAS,EAAE,UAAU,MAAM,EAAE,YAM7D,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,KAAK,GAAU,MAAM,MAAM,qBACa,CAAC;AAEtD;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,GAAU,OAAO,EAC9C,SAAS,MAAM,OAAO,CAAC,OAAO,CAAC,EAC/B,oBAA0B,KACzB,OAAO,CAAC,OAAO,CAkBjB,CAAC"}
@@ -1,4 +1,6 @@
1
1
  import { intersection } from 'lodash-es';
2
+ import { DummyLogger } from '@rosen-bridge/abstract-logger';
3
+ import { RETRIAL_COUNT } from '../constants';
2
4
  /**
3
5
  * Check box to have specified tokens
4
6
  * @param box
@@ -13,4 +15,35 @@ export const boxHasToken = (box, tokenIds) => {
13
15
  return true;
14
16
  return false;
15
17
  };
16
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9saWIvZXJnby91dGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBSXpDOzs7O0dBSUc7QUFDSCxNQUFNLENBQUMsTUFBTSxXQUFXLEdBQUcsQ0FBQyxHQUFjLEVBQUUsUUFBa0IsRUFBRSxFQUFFO0lBQ2hFLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTTtRQUFFLE9BQU8sS0FBSyxDQUFDO0lBQzlCLE1BQU0sU0FBUyxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDM0QsTUFBTSxjQUFjLEdBQUcsWUFBWSxDQUFDLFFBQVEsRUFBRSxTQUFTLENBQUMsQ0FBQztJQUN6RCxJQUFJLGNBQWMsQ0FBQyxNQUFNLElBQUksUUFBUSxDQUFDLE1BQU07UUFBRSxPQUFPLElBQUksQ0FBQztJQUMxRCxPQUFPLEtBQUssQ0FBQztBQUNmLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGludGVyc2VjdGlvbiB9IGZyb20gJ2xvZGFzaC1lcyc7XG5cbmltcG9ydCB7IE91dHB1dEJveCB9IGZyb20gJ0Byb3Nlbi1icmlkZ2Uvc2Nhbm5lci1pbnRlcmZhY2VzJztcblxuLyoqXG4gKiBDaGVjayBib3ggdG8gaGF2ZSBzcGVjaWZpZWQgdG9rZW5zXG4gKiBAcGFyYW0gYm94XG4gKiBAcmV0dXJuIHRydWUgaWYgYm94IGhhcyB0aGUgcmVxdWlyZWQgdG9rZW4gYW5kIGZhbHNlIG90aGVyd2lzZVxuICovXG5leHBvcnQgY29uc3QgYm94SGFzVG9rZW4gPSAoYm94OiBPdXRwdXRCb3gsIHRva2VuSWRzOiBzdHJpbmdbXSkgPT4ge1xuICBpZiAoIWJveC5hc3NldHMpIHJldHVybiBmYWxzZTtcbiAgY29uc3QgYm94VG9rZW5zID0gYm94LmFzc2V0cy5tYXAoKHRva2VuKSA9PiB0b2tlbi50b2tlbklkKTtcbiAgY29uc3QgcmVxdWlyZWRUb2tlbnMgPSBpbnRlcnNlY3Rpb24odG9rZW5JZHMsIGJveFRva2Vucyk7XG4gIGlmIChyZXF1aXJlZFRva2Vucy5sZW5ndGggPT0gdG9rZW5JZHMubGVuZ3RoKSByZXR1cm4gdHJ1ZTtcbiAgcmV0dXJuIGZhbHNlO1xufTtcbiJdfQ==
18
+ /**
19
+ * Create delay in procedures based on the specified time in milliseconds
20
+ * @param time
21
+ */
22
+ export const delay = async (time) => new Promise((resolve) => setTimeout(resolve, time));
23
+ /**
24
+ * Retry the request in case of failure
25
+ * Throw error if request fails after RETRIAL_COUNT retrials
26
+ * Wait for 1 second between each trial
27
+ * @param request
28
+ * @param logger
29
+ * @returns
30
+ */
31
+ export const requestWithRetrial = async (request, logger = new DummyLogger()) => {
32
+ let trial = 0;
33
+ let lastErrorMessage;
34
+ while (trial < RETRIAL_COUNT) {
35
+ try {
36
+ const result = await request();
37
+ return result;
38
+ }
39
+ catch (e) {
40
+ lastErrorMessage = e instanceof Error ? e.message : String(e);
41
+ trial++;
42
+ logger.warn(`request failed with error ${lastErrorMessage}`);
43
+ logger.debug(`Retrying the request with retrial step ${trial}`);
44
+ await delay(1000);
45
+ }
46
+ }
47
+ throw new Error(`request failed after ${trial} retrials with error: ${lastErrorMessage}`);
48
+ };
49
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9saWIvZXJnby91dGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBRXpDLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUc1RCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBRTdDOzs7O0dBSUc7QUFDSCxNQUFNLENBQUMsTUFBTSxXQUFXLEdBQUcsQ0FBQyxHQUFjLEVBQUUsUUFBa0IsRUFBRSxFQUFFO0lBQ2hFLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTTtRQUFFLE9BQU8sS0FBSyxDQUFDO0lBQzlCLE1BQU0sU0FBUyxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDM0QsTUFBTSxjQUFjLEdBQUcsWUFBWSxDQUFDLFFBQVEsRUFBRSxTQUFTLENBQUMsQ0FBQztJQUN6RCxJQUFJLGNBQWMsQ0FBQyxNQUFNLElBQUksUUFBUSxDQUFDLE1BQU07UUFBRSxPQUFPLElBQUksQ0FBQztJQUMxRCxPQUFPLEtBQUssQ0FBQztBQUNmLENBQUMsQ0FBQztBQUVGOzs7R0FHRztBQUNILE1BQU0sQ0FBQyxNQUFNLEtBQUssR0FBRyxLQUFLLEVBQUUsSUFBWSxFQUFFLEVBQUUsQ0FDMUMsSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLFVBQVUsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQztBQUV0RDs7Ozs7OztHQU9HO0FBQ0gsTUFBTSxDQUFDLE1BQU0sa0JBQWtCLEdBQUcsS0FBSyxFQUNyQyxPQUErQixFQUMvQixNQUFNLEdBQUcsSUFBSSxXQUFXLEVBQUUsRUFDUixFQUFFO0lBQ3BCLElBQUksS0FBSyxHQUFHLENBQUMsQ0FBQztJQUNkLElBQUksZ0JBQW9DLENBQUM7SUFDekMsT0FBTyxLQUFLLEdBQUcsYUFBYSxFQUFFLENBQUM7UUFDN0IsSUFBSSxDQUFDO1lBQ0gsTUFBTSxNQUFNLEdBQUcsTUFBTSxPQUFPLEVBQUUsQ0FBQztZQUMvQixPQUFPLE1BQU0sQ0FBQztRQUNoQixDQUFDO1FBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztZQUNYLGdCQUFnQixHQUFHLENBQUMsWUFBWSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUM5RCxLQUFLLEVBQUUsQ0FBQztZQUNSLE1BQU0sQ0FBQyxJQUFJLENBQUMsNkJBQTZCLGdCQUFnQixFQUFFLENBQUMsQ0FBQztZQUM3RCxNQUFNLENBQUMsS0FBSyxDQUFDLDBDQUEwQyxLQUFLLEVBQUUsQ0FBQyxDQUFDO1lBQ2hFLE1BQU0sS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3BCLENBQUM7SUFDSCxDQUFDO0lBQ0QsTUFBTSxJQUFJLEtBQUssQ0FDYix3QkFBd0IsS0FBSyx5QkFBeUIsZ0JBQWdCLEVBQUUsQ0FDekUsQ0FBQztBQUNKLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGludGVyc2VjdGlvbiB9IGZyb20gJ2xvZGFzaC1lcyc7XG5cbmltcG9ydCB7IER1bW15TG9nZ2VyIH0gZnJvbSAnQHJvc2VuLWJyaWRnZS9hYnN0cmFjdC1sb2dnZXInO1xuaW1wb3J0IHsgT3V0cHV0Qm94IH0gZnJvbSAnQHJvc2VuLWJyaWRnZS9zY2FubmVyLWludGVyZmFjZXMnO1xuXG5pbXBvcnQgeyBSRVRSSUFMX0NPVU5UIH0gZnJvbSAnLi4vY29uc3RhbnRzJztcblxuLyoqXG4gKiBDaGVjayBib3ggdG8gaGF2ZSBzcGVjaWZpZWQgdG9rZW5zXG4gKiBAcGFyYW0gYm94XG4gKiBAcmV0dXJuIHRydWUgaWYgYm94IGhhcyB0aGUgcmVxdWlyZWQgdG9rZW4gYW5kIGZhbHNlIG90aGVyd2lzZVxuICovXG5leHBvcnQgY29uc3QgYm94SGFzVG9rZW4gPSAoYm94OiBPdXRwdXRCb3gsIHRva2VuSWRzOiBzdHJpbmdbXSkgPT4ge1xuICBpZiAoIWJveC5hc3NldHMpIHJldHVybiBmYWxzZTtcbiAgY29uc3QgYm94VG9rZW5zID0gYm94LmFzc2V0cy5tYXAoKHRva2VuKSA9PiB0b2tlbi50b2tlbklkKTtcbiAgY29uc3QgcmVxdWlyZWRUb2tlbnMgPSBpbnRlcnNlY3Rpb24odG9rZW5JZHMsIGJveFRva2Vucyk7XG4gIGlmIChyZXF1aXJlZFRva2Vucy5sZW5ndGggPT0gdG9rZW5JZHMubGVuZ3RoKSByZXR1cm4gdHJ1ZTtcbiAgcmV0dXJuIGZhbHNlO1xufTtcblxuLyoqXG4gKiBDcmVhdGUgZGVsYXkgaW4gcHJvY2VkdXJlcyBiYXNlZCBvbiB0aGUgc3BlY2lmaWVkIHRpbWUgaW4gbWlsbGlzZWNvbmRzXG4gKiBAcGFyYW0gdGltZVxuICovXG5leHBvcnQgY29uc3QgZGVsYXkgPSBhc3luYyAodGltZTogbnVtYmVyKSA9PlxuICBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4gc2V0VGltZW91dChyZXNvbHZlLCB0aW1lKSk7XG5cbi8qKlxuICogUmV0cnkgdGhlIHJlcXVlc3QgaW4gY2FzZSBvZiBmYWlsdXJlXG4gKiBUaHJvdyBlcnJvciBpZiByZXF1ZXN0IGZhaWxzIGFmdGVyIFJFVFJJQUxfQ09VTlQgcmV0cmlhbHNcbiAqIFdhaXQgZm9yIDEgc2Vjb25kIGJldHdlZW4gZWFjaCB0cmlhbFxuICogQHBhcmFtIHJlcXVlc3RcbiAqIEBwYXJhbSBsb2dnZXJcbiAqIEByZXR1cm5zXG4gKi9cbmV4cG9ydCBjb25zdCByZXF1ZXN0V2l0aFJldHJpYWwgPSBhc3luYyA8cmV0dXJuVD4oXG4gIHJlcXVlc3Q6ICgpID0+IFByb21pc2U8cmV0dXJuVD4sXG4gIGxvZ2dlciA9IG5ldyBEdW1teUxvZ2dlcigpLFxuKTogUHJvbWlzZTxyZXR1cm5UPiA9PiB7XG4gIGxldCB0cmlhbCA9IDA7XG4gIGxldCBsYXN0RXJyb3JNZXNzYWdlOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gIHdoaWxlICh0cmlhbCA8IFJFVFJJQUxfQ09VTlQpIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcmVxdWVzdCgpO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBsYXN0RXJyb3JNZXNzYWdlID0gZSBpbnN0YW5jZW9mIEVycm9yID8gZS5tZXNzYWdlIDogU3RyaW5nKGUpO1xuICAgICAgdHJpYWwrKztcbiAgICAgIGxvZ2dlci53YXJuKGByZXF1ZXN0IGZhaWxlZCB3aXRoIGVycm9yICR7bGFzdEVycm9yTWVzc2FnZX1gKTtcbiAgICAgIGxvZ2dlci5kZWJ1ZyhgUmV0cnlpbmcgdGhlIHJlcXVlc3Qgd2l0aCByZXRyaWFsIHN0ZXAgJHt0cmlhbH1gKTtcbiAgICAgIGF3YWl0IGRlbGF5KDEwMDApO1xuICAgIH1cbiAgfVxuICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgYHJlcXVlc3QgZmFpbGVkIGFmdGVyICR7dHJpYWx9IHJldHJpYWxzIHdpdGggZXJyb3I6ICR7bGFzdEVycm9yTWVzc2FnZX1gLFxuICApO1xufTtcbiJdfQ==
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rosen-bridge/abstract-extractor",
3
- "version": "2.1.2",
3
+ "version": "3.0.0-8f3c7016",
4
4
  "description": "Rosen Bridge extractor interfaces to work with scanner",
5
5
  "repository": {
6
6
  "type": "git",
@@ -34,7 +34,9 @@
34
34
  "@rosen-bridge/scanner-interfaces": "^0.2.1",
35
35
  "@rosen-clients/ergo-explorer": "^2.1.0",
36
36
  "@rosen-clients/ergo-node": "^3.1.0",
37
+ "await-semaphore": "^0.1.3",
37
38
  "lodash-es": "^4.17.21",
39
+ "p-queue": "^9.0.0",
38
40
  "uuid": "^9.0.0"
39
41
  },
40
42
  "devDependencies": {
@@ -1,80 +0,0 @@
1
- import { AbstractLogger, DummyLogger } from '@rosen-bridge/abstract-logger';
2
- import { Transaction, OutputBox, InputExtension, BlockInfo } from '@rosen-bridge/scanner-interfaces';
3
- import { AbstractExtractor } from '../abstractExtractor';
4
- import { AbstractErgoExtractorAction } from './abstractErgoExtractorAction';
5
- import { AbstractErgoExtractorEntity } from './abstractErgoExtractorEntity';
6
- import { AbstractBoxData, CallbackType, CallbackMap, CallbackDataMap, TxExtra } from './interfaces';
7
- export declare abstract class AbstractErgoExtractor<ExtractedData extends AbstractBoxData, ExtractorEntity extends AbstractErgoExtractorEntity> extends AbstractExtractor<Transaction> {
8
- protected abstract actions: AbstractErgoExtractorAction<ExtractedData, ExtractorEntity>;
9
- protected logger: AbstractLogger;
10
- protected callbacks: {
11
- [K in CallbackType]: Map<string, CallbackMap<ExtractedData>[K]>;
12
- };
13
- private callbackMutex;
14
- constructor(logger?: DummyLogger);
15
- /**
16
- * hook a new callback on a callback type
17
- * @param type
18
- * @param id
19
- * @param callback
20
- * @returns callback registered id
21
- */
22
- hook: <T extends CallbackType>(type: T, callback: CallbackMap<ExtractedData>[T]) => Promise<string>;
23
- /**
24
- * unhook a callback on a type
25
- * returns false if there is no registered callback with the id
26
- * @param type
27
- * @param id
28
- * @returns success status
29
- */
30
- unhook: (type: CallbackType, id: string) => Promise<boolean>;
31
- /**
32
- * trigger all callbacks registered on a specific type with the provided data
33
- * @param type
34
- * @param data
35
- */
36
- protected triggerCallbacks<T extends CallbackType>(type: T, data: CallbackDataMap<ExtractedData>[T]): void;
37
- /**
38
- * extract box data to proper format (not including spending information)
39
- * @param box
40
- * @param inputExtensions all input box extensions in transaction
41
- * @return extracted data in proper format
42
- */
43
- abstract extractBoxData: (box: OutputBox, inputExtensions: InputExtension[], txExtra?: TxExtra) => ExtractedData | undefined;
44
- /**
45
- * check proper data format in the box
46
- * @param box
47
- * @return true if the box has the required data and false otherwise
48
- */
49
- abstract hasData: (box: OutputBox) => boolean;
50
- /**
51
- * create spend info array for the transaction
52
- * @param tx
53
- * @returns spend info array of the transaction
54
- */
55
- getTransactionSpendInfo: (tx: Transaction) => {
56
- txId: string;
57
- boxId: string;
58
- index: number;
59
- }[];
60
- /**
61
- * extract transaction extra information
62
- * override this function if there is extra needed information
63
- * @param tx
64
- * @returns
65
- */
66
- getTransactionExtraData: (tx: Transaction) => TxExtra;
67
- /**
68
- * process a list of transactions in a block and store required information
69
- * @param txs list of transactions in the block
70
- * @param block
71
- * @return true if the process is completed successfully and false otherwise
72
- */
73
- processTransactions: (txs: Transaction[], block: BlockInfo) => Promise<boolean>;
74
- /**
75
- * fork one block and remove all stored information for this block
76
- * @param hash block hash
77
- */
78
- forkBlock: (hash: string) => Promise<void>;
79
- }
80
- //# sourceMappingURL=abstractErgoExtractor.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"abstractErgoExtractor.d.ts","sourceRoot":"","sources":["../../lib/ergo/abstractErgoExtractor.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAE5E,OAAO,EACL,WAAW,EACX,SAAS,EACT,cAAc,EACd,SAAS,EACV,MAAM,kCAAkC,CAAC;AAE1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,2BAA2B,EAAE,MAAM,+BAA+B,CAAC;AAC5E,OAAO,EAAE,2BAA2B,EAAE,MAAM,+BAA+B,CAAC;AAC5E,OAAO,EACL,eAAe,EAEf,YAAY,EACZ,WAAW,EACX,eAAe,EACf,OAAO,EACR,MAAM,cAAc,CAAC;AAEtB,8BAAsB,qBAAqB,CACzC,aAAa,SAAS,eAAe,EACrC,eAAe,SAAS,2BAA2B,CACnD,SAAQ,iBAAiB,CAAC,WAAW,CAAC;IACtC,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,2BAA2B,CACrD,aAAa,EACb,eAAe,CAChB,CAAC;IACF,SAAS,CAAC,MAAM,EAAE,cAAc,CAAC;IACjC,SAAS,CAAC,SAAS,EAAE;SAClB,CAAC,IAAI,YAAY,GAAG,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;KAChE,CAKC;IACF,OAAO,CAAC,aAAa,CAAe;gBAExB,MAAM,cAAoB;IAKtC;;;;;;OAMG;IACH,IAAI,GAAU,CAAC,SAAS,YAAY,EAClC,MAAM,CAAC,EACP,UAAU,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,KACtC,OAAO,CAAC,MAAM,CAAC,CAOhB;IAEF;;;;;;OAMG;IACH,MAAM,GAAU,MAAM,YAAY,EAAE,IAAI,MAAM,KAAG,OAAO,CAAC,OAAO,CAAC,CAY/D;IAEF;;;;OAIG;IACH,SAAS,CAAC,gBAAgB,CAAC,CAAC,SAAS,YAAY,EAC/C,IAAI,EAAE,CAAC,EACP,IAAI,EAAE,eAAe,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,GACtC,IAAI;IAOP;;;;;OAKG;IACH,QAAQ,CAAC,cAAc,EAAE,CACvB,GAAG,EAAE,SAAS,EACd,eAAe,EAAE,cAAc,EAAE,EACjC,OAAO,CAAC,EAAE,OAAO,KACd,aAAa,GAAG,SAAS,CAAC;IAE/B;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,SAAS,KAAK,OAAO,CAAC;IAE9C;;;;OAIG;IACH,uBAAuB,GAAI,IAAI,WAAW;;;;QAQxC;IAEF;;;;;OAKG;IACH,uBAAuB,GACrB,IAAI,WAAW,KACd,OAAO,CAER;IAEF;;;;;OAKG;IACH,mBAAmB,GACjB,KAAK,WAAW,EAAE,EAClB,OAAO,SAAS,KACf,OAAO,CAAC,OAAO,CAAC,CAwDjB;IAEF;;;OAGG;IACH,SAAS,GAAU,MAAM,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC,CAM7C;CACH"}
@@ -1,142 +0,0 @@
1
- import { Mutex } from 'await-semaphore';
2
- import { v4 as uuidv4 } from 'uuid';
3
- import { DummyLogger } from '@rosen-bridge/abstract-logger';
4
- import JsonBigInt from '@rosen-bridge/json-bigint';
5
- import { AbstractExtractor } from '../abstractExtractor';
6
- import { CallbackType, } from './interfaces';
7
- export class AbstractErgoExtractor extends AbstractExtractor {
8
- logger;
9
- callbacks = {
10
- [CallbackType.Update]: new Map(),
11
- [CallbackType.Insert]: new Map(),
12
- [CallbackType.Delete]: new Map(),
13
- [CallbackType.Spend]: new Map(),
14
- };
15
- callbackMutex = new Mutex();
16
- constructor(logger = new DummyLogger()) {
17
- super();
18
- this.logger = logger;
19
- }
20
- /**
21
- * hook a new callback on a callback type
22
- * @param type
23
- * @param id
24
- * @param callback
25
- * @returns callback registered id
26
- */
27
- hook = async (type, callback) => {
28
- const release = await this.callbackMutex.acquire();
29
- const callbackMap = this.callbacks[type];
30
- const id = uuidv4();
31
- callbackMap.set(id, callback);
32
- release();
33
- return id;
34
- };
35
- /**
36
- * unhook a callback on a type
37
- * returns false if there is no registered callback with the id
38
- * @param type
39
- * @param id
40
- * @returns success status
41
- */
42
- unhook = async (type, id) => {
43
- const release = await this.callbackMutex.acquire();
44
- const callbackMap = this.callbacks[type];
45
- if (!callbackMap.has(id)) {
46
- this.logger.warn(`Callback with Id [${id}] is not registered for type [${type}].`);
47
- return false;
48
- }
49
- callbackMap.delete(id);
50
- release();
51
- return true;
52
- };
53
- /**
54
- * trigger all callbacks registered on a specific type with the provided data
55
- * @param type
56
- * @param data
57
- */
58
- triggerCallbacks(type, data) {
59
- const callbackMap = this.callbacks[type];
60
- callbackMap.forEach((callback) => {
61
- callback(data);
62
- });
63
- }
64
- /**
65
- * create spend info array for the transaction
66
- * @param tx
67
- * @returns spend info array of the transaction
68
- */
69
- getTransactionSpendInfo = (tx) => {
70
- let boxIndex = 1;
71
- const spendInfoArray = [];
72
- for (const input of tx.inputs) {
73
- spendInfoArray.push({ txId: tx.id, boxId: input.boxId, index: boxIndex });
74
- boxIndex += 1;
75
- }
76
- return spendInfoArray;
77
- };
78
- /**
79
- * extract transaction extra information
80
- * override this function if there is extra needed information
81
- * @param tx
82
- * @returns
83
- */
84
- getTransactionExtraData = (tx) => {
85
- return {};
86
- };
87
- /**
88
- * process a list of transactions in a block and store required information
89
- * @param txs list of transactions in the block
90
- * @param block
91
- * @return true if the process is completed successfully and false otherwise
92
- */
93
- processTransactions = async (txs, block) => {
94
- try {
95
- const boxes = [];
96
- const spentInfos = [];
97
- for (const tx of txs) {
98
- const inputExtensions = tx.inputs.map((input) => input.extension || {});
99
- for (const output of tx.outputs) {
100
- if (!this.hasData(output)) {
101
- continue;
102
- }
103
- this.logger.debug(`Trying to extract data from box ${output.boxId}`);
104
- const extractedData = this.extractBoxData(output, inputExtensions, this.getTransactionExtraData(tx));
105
- if (extractedData) {
106
- this.logger.debug(`Extracted data ${JsonBigInt.stringify(extractedData)} from box ${output.boxId}`);
107
- boxes.push(extractedData);
108
- }
109
- }
110
- spentInfos.push(...this.getTransactionSpendInfo(tx));
111
- }
112
- if (boxes.length > 0) {
113
- if (!(await this.actions.storeBoxes(boxes, block, this.getId()))) {
114
- this.logger.warn(`Data insertion failed for ${this.getId()} at the block ${block.height}`);
115
- return false;
116
- }
117
- this.triggerCallbacks(CallbackType.Insert, boxes);
118
- }
119
- const spentData = await this.actions.spendBoxes(spentInfos, block, this.getId());
120
- if (spentData.length > 0) {
121
- this.triggerCallbacks(CallbackType.Spend, spentData);
122
- }
123
- }
124
- catch (e) {
125
- this.logger.error(`Processing transactions failed for ${this.getId()} at the block ${block.height} with error: ${e}`);
126
- return false;
127
- }
128
- return true;
129
- };
130
- /**
131
- * fork one block and remove all stored information for this block
132
- * @param hash block hash
133
- */
134
- forkBlock = async (hash) => {
135
- const result = await this.actions.deleteBlockBoxes(hash, this.getId());
136
- if (result.deletedData.length > 0)
137
- this.triggerCallbacks(CallbackType.Delete, result.deletedData);
138
- if (result.updatedData.length > 0)
139
- this.triggerCallbacks(CallbackType.Update, result.updatedData);
140
- };
141
- }
142
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWJzdHJhY3RFcmdvRXh0cmFjdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vbGliL2VyZ28vYWJzdHJhY3RFcmdvRXh0cmFjdG9yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUN4QyxPQUFPLEVBQUUsRUFBRSxJQUFJLE1BQU0sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUVwQyxPQUFPLEVBQWtCLFdBQVcsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQzVFLE9BQU8sVUFBVSxNQUFNLDJCQUEyQixDQUFDO0FBUW5ELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBR3pELE9BQU8sRUFHTCxZQUFZLEdBSWIsTUFBTSxjQUFjLENBQUM7QUFFdEIsTUFBTSxPQUFnQixxQkFHcEIsU0FBUSxpQkFBOEI7SUFLNUIsTUFBTSxDQUFpQjtJQUN2QixTQUFTLEdBRWY7UUFDRixDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsRUFBRSxJQUFJLEdBQUcsRUFBRTtRQUNoQyxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsRUFBRSxJQUFJLEdBQUcsRUFBRTtRQUNoQyxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsRUFBRSxJQUFJLEdBQUcsRUFBRTtRQUNoQyxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsRUFBRSxJQUFJLEdBQUcsRUFBRTtLQUNoQyxDQUFDO0lBQ00sYUFBYSxHQUFHLElBQUksS0FBSyxFQUFFLENBQUM7SUFFcEMsWUFBWSxNQUFNLEdBQUcsSUFBSSxXQUFXLEVBQUU7UUFDcEMsS0FBSyxFQUFFLENBQUM7UUFDUixJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztJQUN2QixDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0gsSUFBSSxHQUFHLEtBQUssRUFDVixJQUFPLEVBQ1AsUUFBdUMsRUFDdEIsRUFBRTtRQUNuQixNQUFNLE9BQU8s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QUFFLENBQ2IsQ0FBQztZQUNGLElBQUksU0FBUyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztnQkFDekIsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFlBQVksQ0FBQyxLQUFLLEVBQUUsU0FBUyxDQUFDLENBQUM7WUFDdkQsQ0FBQztRQUNILENBQUM7UUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1lBQ1gsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQ2Ysc0NBQXNDLElBQUksQ0FBQyxLQUFLLEVBQUUsaUJBQ2hELEtBQUssQ0FBQyxNQUNSLGdCQUFnQixDQUFDLEVBQUUsQ0FDcEIsQ0FBQztZQUNGLE9BQU8sS0FBSyxDQUFDO1FBQ2YsQ0FBQztRQUNELE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQyxDQUFDO0lBRUY7OztPQUdHO0lBQ0gsU0FBUyxHQUFHLEtBQUssRUFBRSxJQUFZLEVBQWlCLEVBQUU7UUFDaEQsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsT0FBTyxDQUFDLGdCQUFnQixDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUN2RSxJQUFJLE1BQU0sQ0FBQyxXQUFXLENBQUMsTUFBTSxHQUFHLENBQUM7WUFDL0IsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ2pFLElBQUksTUFBTSxDQUFDLFdBQVcsQ0FBQyxNQUFNLEdBQUcsQ0FBQztZQUMvQixJQUFJLENBQUMsZ0JBQWdCLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDbkUsQ0FBQyxDQUFDO0NBQ0giLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBNdXRleCB9IGZyb20gJ2F3YWl0LXNlbWFwaG9yZSc7XG5pbXBvcnQgeyB2NCBhcyB1dWlkdjQgfSBmcm9tICd1dWlkJztcblxuaW1wb3J0IHsgQWJzdHJhY3RMb2dnZXIsIER1bW15TG9nZ2VyIH0gZnJvbSAnQHJvc2VuLWJyaWRnZS9hYnN0cmFjdC1sb2dnZXInO1xuaW1wb3J0IEpzb25CaWdJbnQgZnJvbSAnQHJvc2VuLWJyaWRnZS9qc29uLWJpZ2ludCc7XG5pbXBvcnQge1xuICBUcmFuc2FjdGlvbixcbiAgT3V0cHV0Qm94LFxuICBJbnB1dEV4dGVuc2lvbixcbiAgQmxvY2tJbmZvLFxufSBmcm9tICdAcm9zZW4tYnJpZGdlL3NjYW5uZXItaW50ZXJmYWNlcyc7XG5cbmltcG9ydCB7IEFic3RyYWN0RXh0cmFjdG9yIH0gZnJvbSAnLi4vYWJzdHJhY3RFeHRyYWN0b3InO1xuaW1wb3J0IHsgQWJzdHJhY3RFcmdvRXh0cmFjdG9yQWN0aW9uIH0gZnJvbSAnLi9hYnN0cmFjdEVyZ29FeHRyYWN0b3JBY3Rpb24nO1xuaW1wb3J0IHsgQWJzdHJhY3RFcmdvRXh0cmFjdG9yRW50aXR5IH0gZnJvbSAnLi9hYnN0cmFjdEVyZ29FeHRyYWN0b3JFbnRpdHknO1xuaW1wb3J0IHtcbiAgQWJzdHJhY3RCb3hEYXRhLFxuICBTcGVuZEluZm8sXG4gIENhbGxiYWNrVHlwZSxcbiAgQ2FsbGJhY2tNYXAsXG4gIENhbGxiYWNrRGF0YU1hcCxcbiAgVHhFeHRyYSxcbn0gZnJvbSAnLi9pbnRlcmZhY2VzJztcblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIEFic3RyYWN0RXJnb0V4dHJhY3RvcjxcbiAgRXh0cmFjdGVkRGF0YSBleHRlbmRzIEFic3RyYWN0Qm94RGF0YSxcbiAgRXh0cmFjdG9yRW50aXR5IGV4dGVuZHMgQWJzdHJhY3RFcmdvRXh0cmFjdG9yRW50aXR5LFxuPiBleHRlbmRzIEFic3RyYWN0RXh0cmFjdG9yPFRyYW5zYWN0aW9uPiB7XG4gIHByb3RlY3RlZCBhYnN0cmFjdCBhY3Rpb25zOiBBYnN0cmFjdEVyZ29FeHRyYWN0b3JBY3Rpb248XG4gICAgRXh0cmFjdGVkRGF0YSxcbiAgICBFeHRyYWN0b3JFbnRpdHlcbiAgPjtcbiAgcHJvdGVjdGVkIGxvZ2dlcjogQWJzdHJhY3RMb2dnZXI7XG4gIHByb3RlY3RlZCBjYWxsYmFja3M6IHtcbiAgICBbSyBpbiBDYWxsYmFja1R5cGVdOiBNYXA8c3RyaW5nLCBDYWxsYmFja01hcDxFeHRyYWN0ZWREYXRhPltLXT47XG4gIH0gPSB7XG4gICAgW0NhbGxiYWNrVHlwZS5VcGRhdGVdOiBuZXcgTWFwKCksXG4gICAgW0NhbGxiYWNrVHlwZS5JbnNlcnRdOiBuZXcgTWFwKCksXG4gICAgW0NhbGxiYWNrVHlwZS5EZWxldGVdOiBuZXcgTWFwKCksXG4gICAgW0NhbGxiYWNrVHlwZS5TcGVuZF06IG5ldyBNYXAoKSxcbiAgfTtcbiAgcHJpdmF0ZSBjYWxsYmFja011dGV4ID0gbmV3IE11dGV4KCk7XG5cbiAgY29uc3RydWN0b3IobG9nZ2VyID0gbmV3IER1bW15TG9nZ2VyKCkpIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMubG9nZ2VyID0gbG9nZ2VyO1xuICB9XG5cbiAgLyoqXG4gICAqIGhvb2sgYSBuZXcgY2FsbGJhY2sgb24gYSBjYWxsYmFjayB0eXBlXG4gICAqIEBwYXJhbSB0eXBlXG4gICAqIEBwYXJhbSBpZFxuICAgKiBAcGFyYW0gY2FsbGJhY2tcbiAgICogQHJldHVybnMgY2FsbGJhY2sgcmVnaXN0ZXJlZCBpZFxuICAgKi9cbiAgaG9vayA9IGFzeW5jIDxUIGV4dGVuZHMgQ2FsbGJhY2tUeXBlPihcbiAgICB0eXBlOiBULFxuICAgIGNhbGxiYWNrOiBDYWxsYmFja01hcDxFeHRyYWN0ZWREYXRhPltUXSxcbiAgKTogUHJvbWlzZTxzdHJpbmc+ID0+IHtcbiAgICBjb25zdCByZWxlYXNlID0gYXdhaXQgdGhpcy5jYWxsYmFja011dGV4LmFjcXVpcmUoKTtcbiAgICBjb25zdCBjYWxsYmFja01hcCA9IHRoaXMuY2FsbGJhY2tzW3R5cGVdO1xuICAgIGNvbnN0IGlkID0gdXVpZHY0KCk7XG4gICAgY2FsbGJhY2tNYXAuc2V0KGlkLCBjYWxsYmFjayk7XG4gICAgcmVsZWFzZSgpO1xuICAgIHJldHVybiBpZDtcbiAgfTtcblxuICAvKipcbiAgICogdW5ob29rIGEgY2FsbGJhY2sgb24gYSB0eXBlXG4gICAqIHJldHVybnMgZmFsc2UgaWYgdGhlcmUgaXMgbm8gcmVnaXN0ZXJlZCBjYWxsYmFjayB3aXRoIHRoZSBpZFxuICAgKiBAcGFyYW0gdHlwZVxuICAgKiBAcGFyYW0gaWRcbiAgICogQHJldHVybnMgc3VjY2VzcyBzdGF0dXNcbiAgICovXG4gIHVuaG9vayA9IGFzeW5jICh0eXBlOiBDYWxsYmFja1R5cGUsIGlkOiBzdHJpbmcpOiBQcm9taXNlPGJvb2xlYW4+ID0+IHtcbiAgICBjb25zdCByZWxlYXNlID0gYXdhaXQgdGhpcy5jYWxsYmFja011dGV4LmFjcXVpcmUoKTtcbiAgICBjb25zdCBjYWxsYmFja01hcCA9IHRoaXMuY2FsbGJhY2tzW3R5cGVdO1xuICAgIGlmICghY2FsbGJhY2tNYXAuaGFzKGlkKSkge1xuICAgICAgdGhpcy5sb2dnZXIud2FybihcbiAgICAgICAgYENhbGxiYWNrIHdpdGggSWQgWyR7aWR9XSBpcyBub3QgcmVnaXN0ZXJlZCBmb3IgdHlwZSBbJHt0eXBlfV0uYCxcbiAgICAgICk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGNhbGxiYWNrTWFwLmRlbGV0ZShpZCk7XG4gICAgcmVsZWFzZSgpO1xuICAgIHJldHVybiB0cnVlO1xuICB9O1xuXG4gIC8qKlxuICAgKiB0cmlnZ2VyIGFsbCBjYWxsYmFja3MgcmVnaXN0ZXJlZCBvbiBhIHNwZWNpZmljIHR5cGUgd2l0aCB0aGUgcHJvdmlkZWQgZGF0YVxuICAgKiBAcGFyYW0gdHlwZVxuICAgKiBAcGFyYW0gZGF0YVxuICAgKi9cbiAgcHJvdGVjdGVkIHRyaWdnZXJDYWxsYmFja3M8VCBleHRlbmRzIENhbGxiYWNrVHlwZT4oXG4gICAgdHlwZTogVCxcbiAgICBkYXRhOiBDYWxsYmFja0RhdGFNYXA8RXh0cmFjdGVkRGF0YT5bVF0sXG4gICk6IHZvaWQge1xuICAgIGNvbnN0IGNhbGxiYWNrTWFwID0gdGhpcy5jYWxsYmFja3NbdHlwZV07XG4gICAgY2FsbGJhY2tNYXAuZm9yRWFjaCgoY2FsbGJhY2spID0+IHtcbiAgICAgIGNhbGxiYWNrKGRhdGEpO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIGV4dHJhY3QgYm94IGRhdGEgdG8gcHJvcGVyIGZvcm1hdCAobm90IGluY2x1ZGluZyBzcGVuZGluZyBpbmZvcm1hdGlvbilcbiAgICogQHBhcmFtIGJveFxuICAgKiBAcGFyYW0gaW5wdXRFeHRlbnNpb25zIGFsbCBpbnB1dCBib3ggZXh0ZW5zaW9ucyBpbiB0cmFuc2FjdGlvblxuICAgKiBAcmV0dXJuIGV4dHJhY3RlZCBkYXRhIGluIHByb3BlciBmb3JtYXRcbiAgICovXG4gIGFic3RyYWN0IGV4dHJhY3RCb3hEYXRhOiAoXG4gICAgYm94OiBPdXRwdXRCb3gsXG4gICAgaW5wdXRFeHRlbnNpb25zOiBJbnB1dEV4dGVuc2lvbltdLFxuICAgIHR4RXh0cmE/OiBUeEV4dHJhLFxuICApID0+IEV4dHJhY3RlZERhdGEgfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIGNoZWNrIHByb3BlciBkYXRhIGZvcm1hdCBpbiB0aGUgYm94XG4gICAqIEBwYXJhbSBib3hcbiAgICogQHJldHVybiB0cnVlIGlmIHRoZSBib3ggaGFzIHRoZSByZXF1aXJlZCBkYXRhIGFuZCBmYWxzZSBvdGhlcndpc2VcbiAgICovXG4gIGFic3RyYWN0IGhhc0RhdGE6IChib3g6IE91dHB1dEJveCkgPT4gYm9vbGVhbjtcblxuICAvKipcbiAgICogY3JlYXRlIHNwZW5kIGluZm8gYXJyYXkgZm9yIHRoZSB0cmFuc2FjdGlvblxuICAgKiBAcGFyYW0gdHhcbiAgICogQHJldHVybnMgc3BlbmQgaW5mbyBhcnJheSBvZiB0aGUgdHJhbnNhY3Rpb25cbiAgICovXG4gIGdldFRyYW5zYWN0aW9uU3BlbmRJbmZvID0gKHR4OiBUcmFuc2FjdGlvbikgPT4ge1xuICAgIGxldCBib3hJbmRleCA9IDE7XG4gICAgY29uc3Qgc3BlbmRJbmZvQXJyYXkgPSBbXTtcbiAgICBmb3IgKGNvbnN0IGlucHV0IG9mIHR4LmlucHV0cykge1xuICAgICAgc3BlbmRJbmZvQXJyYXkucHVzaCh7IHR4SWQ6IHR4LmlkLCBib3hJZDogaW5wdXQuYm94SWQsIGluZGV4OiBib3hJbmRleCB9KTtcbiAgICAgIGJveEluZGV4ICs9IDE7XG4gICAgfVxuICAgIHJldHVybiBzcGVuZEluZm9BcnJheTtcbiAgfTtcblxuICAvKipcbiAgICogZXh0cmFjdCB0cmFuc2FjdGlvbiBleHRyYSBpbmZvcm1hdGlvblxuICAgKiBvdmVycmlkZSB0aGlzIGZ1bmN0aW9uIGlmIHRoZXJlIGlzIGV4dHJhIG5lZWRlZCBpbmZvcm1hdGlvblxuICAgKiBAcGFyYW0gdHhcbiAgICogQHJldHVybnNcbiAgICovXG4gIGdldFRyYW5zYWN0aW9uRXh0cmFEYXRhID0gKFxuICAgIHR4OiBUcmFuc2FjdGlvbiwgLy8gZXNsaW50LWRpc2FibGUtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgKTogVHhFeHRyYSA9PiB7XG4gICAgcmV0dXJuIHt9O1xuICB9O1xuXG4gIC8qKlxuICAgKiBwcm9jZXNzIGEgbGlzdCBvZiB0cmFuc2FjdGlvbnMgaW4gYSBibG9jayBhbmQgc3RvcmUgcmVxdWlyZWQgaW5mb3JtYXRpb25cbiAgICogQHBhcmFtIHR4cyBsaXN0IG9mIHRyYW5zYWN0aW9ucyBpbiB0aGUgYmxvY2tcbiAgICogQHBhcmFtIGJsb2NrXG4gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgcHJvY2VzcyBpcyBjb21wbGV0ZWQgc3VjY2Vzc2Z1bGx5IGFuZCBmYWxzZSBvdGhlcndpc2VcbiAgICovXG4gIHByb2Nlc3NUcmFuc2FjdGlvbnMgPSBhc3luYyAoXG4gICAgdHhzOiBUcmFuc2FjdGlvbltdLFxuICAgIGJsb2NrOiBCbG9ja0luZm8sXG4gICk6IFByb21pc2U8Ym9vbGVhbj4gPT4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBib3hlczogQXJyYXk8RXh0cmFjdGVkRGF0YT4gPSBbXTtcbiAgICAgIGNvbnN0IHNwZW50SW5mb3M6IEFycmF5PFNwZW5kSW5mbz4gPSBbXTtcbiAgICAgIGZvciAoY29uc3QgdHggb2YgdHhzKSB7XG4gICAgICAgIGNvbnN0IGlucHV0RXh0ZW5zaW9ucyA9IHR4LmlucHV0cy5tYXAoKGlucHV0KSA9PiBpbnB1dC5leHRlbnNpb24gfHwge30pO1xuICAgICAgICBmb3IgKGNvbnN0IG91dHB1dCBvZiB0eC5vdXRwdXRzKSB7XG4gICAgICAgICAgaWYgKCF0aGlzLmhhc0RhdGEob3V0cHV0KSkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKGBUcnlpbmcgdG8gZXh0cmFjdCBkYXRhIGZyb20gYm94ICR7b3V0cHV0LmJveElkfWApO1xuICAgICAgICAgIGNvbnN0IGV4dHJhY3RlZERhdGEgPSB0aGlzLmV4dHJhY3RCb3hEYXRhKFxuICAgICAgICAgICAgb3V0cHV0LFxuICAgICAgICAgICAgaW5wdXRFeHRlbnNpb25zLFxuICAgICAgICAgICAgdGhpcy5nZXRUcmFuc2FjdGlvbkV4dHJhRGF0YSh0eCksXG4gICAgICAgICAgKTtcbiAgICAgICAgICBpZiAoZXh0cmFjdGVkRGF0YSkge1xuICAgICAgICAgICAgdGhpcy5sb2dnZXIuZGVidWcoXG4gICAgICAgICAgICAgIGBFeHRyYWN0ZWQgZGF0YSAke0pzb25CaWdJbnQuc3RyaW5naWZ5KGV4dHJhY3RlZERhdGEpfSBmcm9tIGJveCAke1xuICAgICAgICAgICAgICAgIG91dHB1dC5ib3hJZFxuICAgICAgICAgICAgICB9YCxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBib3hlcy5wdXNoKGV4dHJhY3RlZERhdGEpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBzcGVudEluZm9zLnB1c2goLi4udGhpcy5nZXRUcmFuc2FjdGlvblNwZW5kSW5mbyh0eCkpO1xuICAgICAgfVxuXG4gICAgICBpZiAoYm94ZXMubGVuZ3RoID4gMCkge1xuICAgICAgICBpZiAoIShhd2FpdCB0aGlzLmFjdGlvbnMuc3RvcmVCb3hlcyhib3hlcywgYmxvY2ssIHRoaXMuZ2V0SWQoKSkpKSB7XG4gICAgICAgICAgdGhpcy5sb2dnZXIud2FybihcbiAgICAgICAgICAgIGBEYXRhIGluc2VydGlvbiBmYWlsZWQgZm9yICR7dGhpcy5nZXRJZCgpfSBhdCB0aGUgYmxvY2sgJHtcbiAgICAgICAgICAgICAgYmxvY2suaGVpZ2h0XG4gICAgICAgICAgICB9YCxcbiAgICAgICAgICApO1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnRyaWdnZXJDYWxsYmFja3MoQ2FsbGJhY2tUeXBlLkluc2VydCwgYm94ZXMpO1xuICAgICAgfVxuICAgICAgY29uc3Qgc3BlbnREYXRhID0gYXdhaXQgdGhpcy5hY3Rpb25zLnNwZW5kQm94ZXMoXG4gICAgICAgIHNwZW50SW5mb3MsXG4gICAgICAgIGJsb2NrLFxuICAgICAgICB0aGlzLmdldElkKCksXG4gICAgICApO1xuICAgICAgaWYgKHNwZW50RGF0YS5sZW5ndGggPiAwKSB7XG4gICAgICAgIHRoaXMudHJpZ2dlckNhbGxiYWNrcyhDYWxsYmFja1R5cGUuU3BlbmQsIHNwZW50RGF0YSk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoXG4gICAgICAgIGBQcm9jZXNzaW5nIHRyYW5zYWN0aW9ucyBmYWlsZWQgZm9yICR7dGhpcy5nZXRJZCgpfSBhdCB0aGUgYmxvY2sgJHtcbiAgICAgICAgICBibG9jay5oZWlnaHRcbiAgICAgICAgfSB3aXRoIGVycm9yOiAke2V9YCxcbiAgICAgICk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9O1xuXG4gIC8qKlxuICAgKiBmb3JrIG9uZSBibG9jayBhbmQgcmVtb3ZlIGFsbCBzdG9yZWQgaW5mb3JtYXRpb24gZm9yIHRoaXMgYmxvY2tcbiAgICogQHBhcmFtIGhhc2ggYmxvY2sgaGFzaFxuICAgKi9cbiAgZm9ya0Jsb2NrID0gYXN5bmMgKGhhc2g6IHN0cmluZyk6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMuYWN0aW9ucy5kZWxldGVCbG9ja0JveGVzKGhhc2gsIHRoaXMuZ2V0SWQoKSk7XG4gICAgaWYgKHJlc3VsdC5kZWxldGVkRGF0YS5sZW5ndGggPiAwKVxuICAgICAgdGhpcy50cmlnZ2VyQ2FsbGJhY2tzKENhbGxiYWNrVHlwZS5EZWxldGUsIHJlc3VsdC5kZWxldGVkRGF0YSk7XG4gICAgaWYgKHJlc3VsdC51cGRhdGVkRGF0YS5sZW5ndGggPiAwKVxuICAgICAgdGhpcy50cmlnZ2VyQ2FsbGJhY2tzKENhbGxiYWNrVHlwZS5VcGRhdGUsIHJlc3VsdC51cGRhdGVkRGF0YSk7XG4gIH07XG59XG4iXX0=