@rosen-bridge/abstract-extractor 0.3.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/dist/ergo/AbstractErgoExtractor.d.ts +31 -8
- package/dist/ergo/AbstractErgoExtractor.d.ts.map +1 -1
- package/dist/ergo/AbstractErgoExtractor.js +73 -8
- package/dist/ergo/AbstractErgoExtractorAction.d.ts +38 -10
- package/dist/ergo/AbstractErgoExtractorAction.d.ts.map +1 -1
- package/dist/ergo/AbstractErgoExtractorAction.js +134 -1
- package/dist/ergo/AbstractErgoExtractorEntity.d.ts +11 -0
- package/dist/ergo/AbstractErgoExtractorEntity.d.ts.map +1 -0
- package/dist/ergo/AbstractErgoExtractorEntity.js +57 -0
- package/dist/ergo/index.d.ts +1 -0
- package/dist/ergo/index.d.ts.map +1 -1
- package/dist/ergo/index.js +2 -1
- package/dist/ergo/initializable/AbstractInitializable.d.ts +4 -3
- package/dist/ergo/initializable/AbstractInitializable.d.ts.map +1 -1
- package/dist/ergo/initializable/AbstractInitializable.js +9 -5
- package/dist/ergo/initializable/AbstractInitializableAction.d.ts +7 -2
- package/dist/ergo/initializable/AbstractInitializableAction.d.ts.map +1 -1
- package/dist/ergo/initializable/AbstractInitializableAction.js +11 -1
- package/dist/ergo/interfaces.d.ts +21 -7
- package/dist/ergo/interfaces.d.ts.map +1 -1
- package/dist/ergo/interfaces.js +8 -1
- package/lib/ergo/AbstractErgoExtractor.ts +107 -23
- package/lib/ergo/AbstractErgoExtractorAction.ts +187 -18
- package/lib/ergo/AbstractErgoExtractorEntity.ts +28 -0
- package/lib/ergo/index.ts +1 -0
- package/lib/ergo/initializable/AbstractInitializable.ts +22 -9
- package/lib/ergo/initializable/AbstractInitializableAction.ts +19 -3
- package/lib/ergo/interfaces.ts +25 -7
- package/package.json +6 -2
- package/tests/{AbstractExtractor.mock.ts → AbstractErgoExtractor.mock.ts} +12 -7
- package/tests/AbstractErgoExtractor.spec.ts +281 -0
- package/tests/AbstractErgoExtractorAction.mock.ts +45 -0
- package/tests/AbstractErgoExtractorAction.spec.ts +269 -0
- package/tests/initializable/AbstractInitializable.mock.ts +15 -8
- package/tests/initializable/AbstractInitializable.spec.ts +37 -5
- package/tests/initializable/AbstractInitializableAction.mock.ts +45 -0
- package/tests/initializable/AbstractInitializableAction.spec.ts +65 -0
- package/tests/testData.ts +38 -2
- package/tests/testUtils.ts +22 -0
- package/tsconfig.build.tsbuildinfo +1 -1
- package/dist/ergo/initializable/InitializableByAddress.d.ts +0 -19
- package/dist/ergo/initializable/InitializableByAddress.d.ts.map +0 -1
- package/dist/ergo/initializable/InitializableByAddress.js +0 -30
- package/dist/ergo/initializable/InitializableByToken.d.ts +0 -19
- package/dist/ergo/initializable/InitializableByToken.d.ts.map +0 -1
- package/dist/ergo/initializable/InitializableByToken.js +0 -30
- package/dist/tsconfig.tsbuildinfo +0 -1
- package/tests/AbstractExtractor.spec.ts +0 -106
|
@@ -1,39 +1,208 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DataSource,
|
|
3
|
+
In,
|
|
4
|
+
Repository,
|
|
5
|
+
Not,
|
|
6
|
+
EntityTarget,
|
|
7
|
+
FindOptionsWhere,
|
|
8
|
+
} from 'typeorm';
|
|
9
|
+
import { chunk, difference, pick } from 'lodash-es';
|
|
10
|
+
import { AbstractLogger, DummyLogger } from '@rosen-bridge/abstract-logger';
|
|
11
|
+
import JsonBigInt from '@rosen-bridge/json-bigint';
|
|
12
|
+
|
|
1
13
|
import { BlockInfo } from '../interfaces';
|
|
2
|
-
import { SpendInfo } from './interfaces';
|
|
14
|
+
import { AbstractBoxData, BoxInfo, SpendInfo } from './interfaces';
|
|
15
|
+
import { DB_CHUNK_SIZE } from '../constants';
|
|
16
|
+
import { AbstractErgoExtractorEntity } from './AbstractErgoExtractorEntity';
|
|
17
|
+
|
|
18
|
+
export abstract class AbstractErgoExtractorAction<
|
|
19
|
+
ExtractedData extends AbstractBoxData,
|
|
20
|
+
ExtractorEntity extends AbstractErgoExtractorEntity
|
|
21
|
+
> {
|
|
22
|
+
private readonly datasource: DataSource;
|
|
23
|
+
readonly logger: AbstractLogger;
|
|
24
|
+
protected readonly repository: Repository<ExtractorEntity>;
|
|
25
|
+
private repo: EntityTarget<ExtractorEntity>;
|
|
26
|
+
|
|
27
|
+
constructor(
|
|
28
|
+
dataSource: DataSource,
|
|
29
|
+
repo: EntityTarget<ExtractorEntity>,
|
|
30
|
+
logger?: AbstractLogger
|
|
31
|
+
) {
|
|
32
|
+
this.datasource = dataSource;
|
|
33
|
+
this.logger = logger ? logger : new DummyLogger();
|
|
34
|
+
this.repository = this.datasource.getRepository(repo);
|
|
35
|
+
this.repo = repo;
|
|
36
|
+
}
|
|
3
37
|
|
|
4
|
-
export abstract class AbstractErgoExtractorAction<ExtractedData> {
|
|
5
38
|
/**
|
|
6
|
-
*
|
|
7
|
-
* @param data
|
|
8
|
-
* @param extractorId
|
|
9
|
-
* @return process success
|
|
39
|
+
* create the database entity from extracted data and block information
|
|
10
40
|
*/
|
|
11
|
-
abstract
|
|
41
|
+
protected abstract createEntity: (
|
|
12
42
|
data: ExtractedData[],
|
|
13
|
-
|
|
14
|
-
|
|
43
|
+
block: BlockInfo,
|
|
44
|
+
extractor: string
|
|
45
|
+
) => Array<Omit<ExtractorEntity, 'id'>>;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* convert the database entity back to raw data
|
|
49
|
+
*/
|
|
50
|
+
protected abstract convertEntityToData: (
|
|
51
|
+
entities: ExtractorEntity[]
|
|
52
|
+
) => ExtractedData[];
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* insert all extracted box data in an atomic transaction
|
|
56
|
+
* update the data if a box with the same id is already stored in db
|
|
57
|
+
* @param boxes
|
|
58
|
+
* @param block
|
|
59
|
+
* @param extractor
|
|
60
|
+
* @return inserted items and updated box ids
|
|
61
|
+
* returns undefined in case of any problem
|
|
62
|
+
*/
|
|
63
|
+
storeBoxes = async (
|
|
64
|
+
boxes: Array<ExtractedData>,
|
|
65
|
+
block: BlockInfo,
|
|
66
|
+
extractor: string
|
|
67
|
+
): Promise<boolean> => {
|
|
68
|
+
let success = true;
|
|
69
|
+
let boxesToInsert: ExtractedData[] = [],
|
|
70
|
+
boxesToUpdate: ExtractedData[] = [];
|
|
71
|
+
const queryRunner = this.datasource.createQueryRunner();
|
|
72
|
+
await queryRunner.connect();
|
|
73
|
+
await queryRunner.startTransaction();
|
|
74
|
+
try {
|
|
75
|
+
const repository = queryRunner.manager.getRepository(this.repo);
|
|
76
|
+
const dbBoxIds = (
|
|
77
|
+
await repository.findBy({
|
|
78
|
+
boxId: In(boxes.map((item) => item.boxId)),
|
|
79
|
+
extractor: extractor,
|
|
80
|
+
} as FindOptionsWhere<ExtractorEntity>)
|
|
81
|
+
).map((box) => box.boxId);
|
|
82
|
+
if (dbBoxIds.length > 0)
|
|
83
|
+
this.logger.debug(`Found stored boxes with same boxId`, dbBoxIds);
|
|
84
|
+
|
|
85
|
+
boxesToUpdate = boxes.filter((box) => dbBoxIds.includes(box.boxId));
|
|
86
|
+
boxesToInsert = difference(boxes, boxesToUpdate);
|
|
87
|
+
|
|
88
|
+
if (boxesToInsert.length > 0) {
|
|
89
|
+
this.logger.debug(`Inserting boxes`);
|
|
90
|
+
await repository.insert(
|
|
91
|
+
this.createEntity(boxesToInsert, block, extractor) as any
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
if (boxesToUpdate.length > 0)
|
|
95
|
+
this.logger.info(
|
|
96
|
+
`Updating boxes with following Ids in the database: [${boxesToUpdate
|
|
97
|
+
.map((col) => col.boxId)
|
|
98
|
+
.join(', ')}]`
|
|
99
|
+
);
|
|
100
|
+
for (const box of this.createEntity(boxesToUpdate, block, extractor)) {
|
|
101
|
+
this.logger.debug(
|
|
102
|
+
`Updating boxes in database [${JsonBigInt.stringify(box)}]`
|
|
103
|
+
);
|
|
104
|
+
await repository.update(
|
|
105
|
+
{
|
|
106
|
+
boxId: box.boxId,
|
|
107
|
+
extractor: extractor,
|
|
108
|
+
} as FindOptionsWhere<ExtractorEntity>,
|
|
109
|
+
box as any
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
await queryRunner.commitTransaction();
|
|
113
|
+
} catch (e) {
|
|
114
|
+
this.logger.error(`An error occurred during store boxes action: ${e}`);
|
|
115
|
+
await queryRunner.rollbackTransaction();
|
|
116
|
+
success = false;
|
|
117
|
+
} finally {
|
|
118
|
+
await queryRunner.release();
|
|
119
|
+
}
|
|
120
|
+
return success;
|
|
121
|
+
};
|
|
15
122
|
|
|
16
123
|
/**
|
|
17
124
|
* update spending information of stored boxes
|
|
125
|
+
* chunk spendInfos to prevent large database queries
|
|
126
|
+
* Note: It only updates the spendHeight and spendBlock fields. If updating
|
|
127
|
+
* anything else is required, override this implementation to include the
|
|
128
|
+
* additional fields.
|
|
18
129
|
* @param spendInfos
|
|
19
130
|
* @param block
|
|
20
|
-
* @param
|
|
131
|
+
* @param extractor
|
|
132
|
+
* @returns spent box ids
|
|
21
133
|
*/
|
|
22
|
-
|
|
23
|
-
spendInfos: SpendInfo
|
|
134
|
+
spendBoxes = async (
|
|
135
|
+
spendInfos: Array<SpendInfo>,
|
|
24
136
|
block: BlockInfo,
|
|
25
|
-
|
|
26
|
-
) =>
|
|
137
|
+
extractor: string
|
|
138
|
+
): Promise<BoxInfo[]> => {
|
|
139
|
+
const spentData = [];
|
|
140
|
+
const spendInfoChunks = chunk(spendInfos, DB_CHUNK_SIZE);
|
|
141
|
+
for (const spendInfoChunk of spendInfoChunks) {
|
|
142
|
+
const boxIds = spendInfoChunk.map((info) => info.boxId);
|
|
143
|
+
const updateResult = await this.repository.update(
|
|
144
|
+
{
|
|
145
|
+
boxId: In(boxIds),
|
|
146
|
+
extractor: extractor,
|
|
147
|
+
} as FindOptionsWhere<ExtractorEntity>,
|
|
148
|
+
{ spendBlock: block.hash, spendHeight: block.height } as any
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
if (updateResult.affected && updateResult.affected > 0) {
|
|
152
|
+
const spentRows = await this.repository.findBy({
|
|
153
|
+
boxId: In(boxIds),
|
|
154
|
+
spendBlock: block.hash,
|
|
155
|
+
} as FindOptionsWhere<ExtractorEntity>);
|
|
156
|
+
spentData.push(...spentRows);
|
|
157
|
+
for (const row of spentRows) {
|
|
158
|
+
this.logger.debug(
|
|
159
|
+
`Spent box with boxId [${row.boxId}] at height ${block.height}`
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return spentData.map((data) => pick(data, 'boxId'));
|
|
165
|
+
};
|
|
27
166
|
|
|
28
167
|
/**
|
|
29
168
|
* delete extracted data from a specific block
|
|
30
169
|
* if a box is spend in this block mark it as unspent
|
|
31
170
|
* if a box is created in this block remove it from database
|
|
32
171
|
* @param block
|
|
33
|
-
* @param
|
|
172
|
+
* @param extractor
|
|
173
|
+
* @return deleted items and updated box ids
|
|
34
174
|
*/
|
|
35
|
-
|
|
175
|
+
deleteBlockBoxes = async (
|
|
36
176
|
block: string,
|
|
37
|
-
|
|
38
|
-
) =>
|
|
177
|
+
extractor: string
|
|
178
|
+
): Promise<{ deletedData: ExtractedData[]; updatedData: BoxInfo[] }> => {
|
|
179
|
+
this.logger.info(
|
|
180
|
+
`Deleting boxes in block ${block} and extractor ${extractor}`
|
|
181
|
+
);
|
|
182
|
+
const deletedData = await this.repository.find({
|
|
183
|
+
where: { extractor: extractor, block: block } as any,
|
|
184
|
+
});
|
|
185
|
+
const updatedData = await this.repository.find({
|
|
186
|
+
where: {
|
|
187
|
+
extractor: extractor,
|
|
188
|
+
spendBlock: block,
|
|
189
|
+
block: Not(block),
|
|
190
|
+
} as any,
|
|
191
|
+
});
|
|
192
|
+
await this.repository.delete({
|
|
193
|
+
extractor: extractor,
|
|
194
|
+
block: block,
|
|
195
|
+
} as any);
|
|
196
|
+
await this.repository.update(
|
|
197
|
+
{
|
|
198
|
+
spendBlock: block,
|
|
199
|
+
extractor: extractor,
|
|
200
|
+
} as FindOptionsWhere<ExtractorEntity>,
|
|
201
|
+
{ spendBlock: null, spendHeight: 0 } as any
|
|
202
|
+
);
|
|
203
|
+
return {
|
|
204
|
+
deletedData: this.convertEntityToData(deletedData),
|
|
205
|
+
updatedData: updatedData.map((data) => pick(data, 'boxId')),
|
|
206
|
+
};
|
|
207
|
+
};
|
|
39
208
|
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Column, PrimaryGeneratedColumn, Unique } from 'typeorm';
|
|
2
|
+
|
|
3
|
+
@Unique(['boxId', 'extractor'])
|
|
4
|
+
export abstract class AbstractErgoExtractorEntity {
|
|
5
|
+
@PrimaryGeneratedColumn()
|
|
6
|
+
id: number;
|
|
7
|
+
|
|
8
|
+
@Column({ type: 'varchar' })
|
|
9
|
+
boxId: string;
|
|
10
|
+
|
|
11
|
+
@Column({ type: 'varchar' })
|
|
12
|
+
block: string;
|
|
13
|
+
|
|
14
|
+
@Column({ type: 'int' })
|
|
15
|
+
height: number;
|
|
16
|
+
|
|
17
|
+
@Column({ nullable: true, type: 'varchar' })
|
|
18
|
+
spendBlock?: string | null;
|
|
19
|
+
|
|
20
|
+
@Column({ nullable: true, type: 'int' })
|
|
21
|
+
spendHeight?: number | null;
|
|
22
|
+
|
|
23
|
+
@Column({ type: 'varchar' })
|
|
24
|
+
extractor: string;
|
|
25
|
+
|
|
26
|
+
@Column({ type: 'varchar' })
|
|
27
|
+
serialized: string;
|
|
28
|
+
}
|
package/lib/ergo/index.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { AbstractLogger } from '@rosen-bridge/abstract-logger';
|
|
2
|
+
import { groupBy, sortBy } from 'lodash-es';
|
|
3
|
+
|
|
2
4
|
import {
|
|
3
|
-
|
|
5
|
+
AbstractBoxData,
|
|
4
6
|
ErgoNetworkType,
|
|
5
7
|
ExtendedTransaction,
|
|
6
8
|
} from '../interfaces';
|
|
@@ -10,14 +12,18 @@ import { AbstractInitializableErgoExtractorAction } from './AbstractInitializabl
|
|
|
10
12
|
import { BlockInfo } from '../../interfaces';
|
|
11
13
|
import { ExplorerNetwork } from '../network/ExplorerNetwork';
|
|
12
14
|
import { NodeNetwork } from '../network/NodeNetwork';
|
|
13
|
-
import {
|
|
15
|
+
import { AbstractErgoExtractorEntity } from '../AbstractErgoExtractorEntity';
|
|
14
16
|
|
|
15
17
|
export abstract class AbstractInitializableErgoExtractor<
|
|
16
|
-
ExtractedData extends
|
|
17
|
-
|
|
18
|
+
ExtractedData extends AbstractBoxData,
|
|
19
|
+
ExtractorEntity extends AbstractErgoExtractorEntity
|
|
20
|
+
> extends AbstractErgoExtractor<ExtractedData, ExtractorEntity> {
|
|
18
21
|
protected initialize: boolean;
|
|
19
22
|
private address: string;
|
|
20
|
-
protected abstract actions: AbstractInitializableErgoExtractorAction<
|
|
23
|
+
protected abstract actions: AbstractInitializableErgoExtractorAction<
|
|
24
|
+
ExtractedData,
|
|
25
|
+
ExtractorEntity
|
|
26
|
+
>;
|
|
21
27
|
|
|
22
28
|
private network: ExplorerNetwork | NodeNetwork;
|
|
23
29
|
|
|
@@ -112,14 +118,15 @@ export abstract class AbstractInitializableErgoExtractor<
|
|
|
112
118
|
*/
|
|
113
119
|
private initializeWithNode = async (initialBlock: BlockInfo) => {
|
|
114
120
|
const txCountBeforeInit = await this.getTotalTxCount();
|
|
121
|
+
let offset = 0,
|
|
122
|
+
total = 1,
|
|
123
|
+
round = 1;
|
|
115
124
|
await this.initWithRetrial(async () => {
|
|
116
125
|
// Repeat the whole process twice to cover all spent boxes
|
|
117
126
|
// After round 1 all boxes have been saved and processed once
|
|
118
127
|
// After round 2 spending information of all stored boxes are updated successfully
|
|
119
|
-
|
|
128
|
+
while (round <= 2) {
|
|
120
129
|
this.logger.debug(`Starting round ${round} of initialization`);
|
|
121
|
-
let offset = 0,
|
|
122
|
-
total = 1;
|
|
123
130
|
while (offset < total) {
|
|
124
131
|
const response = await (
|
|
125
132
|
this.network as NodeNetwork
|
|
@@ -138,6 +145,8 @@ export abstract class AbstractInitializableErgoExtractor<
|
|
|
138
145
|
if (txs.length > 0) await this.processTransactionBatch(txs);
|
|
139
146
|
offset += API_LIMIT;
|
|
140
147
|
}
|
|
148
|
+
round++;
|
|
149
|
+
offset = 0; // next round initial offset
|
|
141
150
|
}
|
|
142
151
|
});
|
|
143
152
|
const txCountAfterInit = await this.getTotalTxCount();
|
|
@@ -167,7 +176,11 @@ export abstract class AbstractInitializableErgoExtractor<
|
|
|
167
176
|
this.logger.debug(
|
|
168
177
|
`Processing transactions at height ${blockTxs[0].inclusionHeight}`
|
|
169
178
|
);
|
|
170
|
-
await this.processTransactions(blockTxs, block);
|
|
179
|
+
const success = await this.processTransactions(blockTxs, block);
|
|
180
|
+
if (!success)
|
|
181
|
+
throw Error(
|
|
182
|
+
`Processing transactions failed at height ${blockTxs[0].inclusionHeight}`
|
|
183
|
+
);
|
|
171
184
|
}
|
|
172
185
|
};
|
|
173
186
|
|
|
@@ -1,11 +1,27 @@
|
|
|
1
|
+
import { DataSource, EntityTarget } from 'typeorm';
|
|
2
|
+
import { AbstractLogger } from '@rosen-bridge/abstract-logger';
|
|
3
|
+
|
|
1
4
|
import { AbstractErgoExtractorAction } from '../AbstractErgoExtractorAction';
|
|
5
|
+
import { AbstractBoxData } from '../interfaces';
|
|
6
|
+
import { AbstractErgoExtractorEntity } from '../AbstractErgoExtractorEntity';
|
|
2
7
|
|
|
3
8
|
export abstract class AbstractInitializableErgoExtractorAction<
|
|
4
|
-
ExtractedData
|
|
5
|
-
|
|
9
|
+
ExtractedData extends AbstractBoxData,
|
|
10
|
+
ExtractorEntity extends AbstractErgoExtractorEntity
|
|
11
|
+
> extends AbstractErgoExtractorAction<ExtractedData, ExtractorEntity> {
|
|
12
|
+
constructor(
|
|
13
|
+
dataSource: DataSource,
|
|
14
|
+
repo: EntityTarget<ExtractorEntity>,
|
|
15
|
+
logger?: AbstractLogger
|
|
16
|
+
) {
|
|
17
|
+
super(dataSource, repo, logger);
|
|
18
|
+
}
|
|
19
|
+
|
|
6
20
|
/**
|
|
7
21
|
* remove all existing data for the extractor
|
|
8
22
|
* @param extractorId
|
|
9
23
|
*/
|
|
10
|
-
|
|
24
|
+
removeAllData = async (extractorId: string) => {
|
|
25
|
+
await this.repository.delete({ extractor: extractorId } as any);
|
|
26
|
+
};
|
|
11
27
|
}
|
package/lib/ergo/interfaces.ts
CHANGED
|
@@ -62,14 +62,32 @@ export interface SpendInfo {
|
|
|
62
62
|
boxId: string;
|
|
63
63
|
txId: string;
|
|
64
64
|
index: number;
|
|
65
|
+
extras?: string[];
|
|
65
66
|
}
|
|
66
67
|
|
|
67
|
-
export interface
|
|
68
|
+
export interface AbstractBoxData {
|
|
69
|
+
boxId: string;
|
|
70
|
+
serialized: string;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export enum CallbackType {
|
|
74
|
+
Insert = 'insert',
|
|
75
|
+
Update = 'update',
|
|
76
|
+
Spend = 'spend',
|
|
77
|
+
Delete = 'delete',
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export interface BoxInfo {
|
|
68
81
|
boxId: string;
|
|
69
|
-
height: number;
|
|
70
|
-
blockId: string;
|
|
71
|
-
spendBlock?: string;
|
|
72
|
-
spendHeight?: number;
|
|
73
|
-
spendTxId?: string;
|
|
74
|
-
spendIndex?: number;
|
|
75
82
|
}
|
|
83
|
+
|
|
84
|
+
export type CallbackDataMap<ExtractedData extends AbstractBoxData> = {
|
|
85
|
+
[CallbackType.Update]: BoxInfo[];
|
|
86
|
+
[CallbackType.Insert]: ExtractedData[];
|
|
87
|
+
[CallbackType.Delete]: ExtractedData[];
|
|
88
|
+
[CallbackType.Spend]: BoxInfo[];
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
export type CallbackMap<ExtractedData extends AbstractBoxData> = {
|
|
92
|
+
[K in CallbackType]: (data: CallbackDataMap<ExtractedData>[K]) => void;
|
|
93
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rosen-bridge/abstract-extractor",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "Rosen Bridge extractor interfaces to work with scanner",
|
|
5
5
|
"repository": "",
|
|
6
6
|
"license": "GPL-3.0",
|
|
@@ -20,9 +20,11 @@
|
|
|
20
20
|
"devDependencies": {
|
|
21
21
|
"@types/lodash-es": "^4.17.12",
|
|
22
22
|
"@types/node": "^20.11.9",
|
|
23
|
+
"@types/uuid": "^10.0.0",
|
|
23
24
|
"@typescript-eslint/eslint-plugin": "^6.19.1",
|
|
24
25
|
"@typescript-eslint/parser": "^6.19.1",
|
|
25
26
|
"@vitest/coverage-istanbul": "^1.2.2",
|
|
27
|
+
"await-semaphore": "^0.1.3",
|
|
26
28
|
"eslint": "^8.56.0",
|
|
27
29
|
"eslint-config-prettier": "^9.1.0",
|
|
28
30
|
"extensionless": "^1.9.6",
|
|
@@ -38,6 +40,8 @@
|
|
|
38
40
|
"@rosen-bridge/json-bigint": "^0.1.0",
|
|
39
41
|
"@rosen-clients/ergo-explorer": "^1.1.2",
|
|
40
42
|
"@rosen-clients/ergo-node": "^1.1.1",
|
|
41
|
-
"lodash-es": "^4.17.21"
|
|
43
|
+
"lodash-es": "^4.17.21",
|
|
44
|
+
"typeorm": "^0.3.20",
|
|
45
|
+
"uuid": "^9.0.0"
|
|
42
46
|
}
|
|
43
47
|
}
|
|
@@ -3,12 +3,19 @@ import {
|
|
|
3
3
|
AbstractErgoExtractor,
|
|
4
4
|
BlockInfo,
|
|
5
5
|
OutputBox,
|
|
6
|
-
|
|
6
|
+
AbstractBoxData,
|
|
7
7
|
AbstractErgoExtractorAction,
|
|
8
|
+
AbstractErgoExtractorEntity,
|
|
8
9
|
} from '../lib';
|
|
9
10
|
|
|
10
|
-
export class MockedErgoExtractor extends AbstractErgoExtractor<
|
|
11
|
-
|
|
11
|
+
export class MockedErgoExtractor extends AbstractErgoExtractor<
|
|
12
|
+
AbstractBoxData,
|
|
13
|
+
AbstractErgoExtractorEntity
|
|
14
|
+
> {
|
|
15
|
+
actions: AbstractErgoExtractorAction<
|
|
16
|
+
AbstractBoxData,
|
|
17
|
+
AbstractErgoExtractorEntity
|
|
18
|
+
>;
|
|
12
19
|
|
|
13
20
|
getId = () => 'Test';
|
|
14
21
|
|
|
@@ -17,10 +24,8 @@ export class MockedErgoExtractor extends AbstractErgoExtractor<ErgoExtractedData
|
|
|
17
24
|
hasData = (box: V1.OutputInfo | OutputBox) => false;
|
|
18
25
|
|
|
19
26
|
extractBoxData = (
|
|
20
|
-
box: V1.OutputInfo | OutputBox
|
|
21
|
-
|
|
22
|
-
height: number
|
|
23
|
-
): Omit<ErgoExtractedData, 'spendBlock' | 'spendHeight'> | undefined => {
|
|
27
|
+
box: V1.OutputInfo | OutputBox
|
|
28
|
+
): AbstractBoxData | undefined => {
|
|
24
29
|
return undefined;
|
|
25
30
|
};
|
|
26
31
|
}
|