@rosen-bridge/evm-address-tx-extractor 1.2.0 → 1.2.2-82c56984

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 (33) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/dist/actions/db.d.ts +2 -2
  3. package/dist/actions/db.d.ts.map +1 -1
  4. package/dist/actions/db.js +2 -2
  5. package/dist/entities/{AddressTxsEntity.d.ts → addressTxsEntity.d.ts} +1 -1
  6. package/dist/entities/{AddressTxsEntity.d.ts.map → addressTxsEntity.d.ts.map} +1 -1
  7. package/dist/entities/{AddressTxsEntity.js → addressTxsEntity.js} +1 -1
  8. package/dist/extractors/{EvmTxExtractor.d.ts → evmTxExtractor.d.ts} +3 -3
  9. package/dist/extractors/evmTxExtractor.d.ts.map +1 -0
  10. package/dist/extractors/{EvmTxExtractor.js → evmTxExtractor.js} +3 -3
  11. package/dist/index.d.ts +2 -2
  12. package/dist/index.js +3 -3
  13. package/package.json +25 -17
  14. package/.eslintignore +0 -1
  15. package/dist/extractors/EvmTxExtractor.d.ts.map +0 -1
  16. package/lib/actions/db.ts +0 -69
  17. package/lib/entities/AddressTxsEntity.ts +0 -32
  18. package/lib/extractors/EvmTxExtractor.ts +0 -95
  19. package/lib/index.ts +0 -5
  20. package/lib/interfaces/types.ts +0 -12
  21. package/lib/migrations/index.ts +0 -9
  22. package/lib/migrations/postgres/1713694851290-migration.ts +0 -29
  23. package/lib/migrations/postgres/1722346608595-migration.ts +0 -21
  24. package/lib/migrations/sqlite/1713694799333-migration.ts +0 -28
  25. package/lib/migrations/sqlite/1722346500068-migration.ts +0 -91
  26. package/tests/actions/db.spec.ts +0 -124
  27. package/tests/extractor/EvmTxExtractor.spec.ts +0 -70
  28. package/tests/extractor/testData.ts +0 -104
  29. package/tests/testUtils.ts +0 -22
  30. package/tsconfig.build.json +0 -11
  31. package/tsconfig.build.tsbuildinfo +0 -1
  32. package/tsconfig.json +0 -11
  33. package/vitest.config.ts +0 -18
@@ -1,91 +0,0 @@
1
- import {
2
- MigrationInterface,
3
- QueryRunner,
4
- } from '@rosen-bridge/extended-typeorm';
5
-
6
- export class Migration1722346500068 implements MigrationInterface {
7
- name = 'Migration1722346500068';
8
-
9
- public async up(queryRunner: QueryRunner): Promise<void> {
10
- await queryRunner.query(`
11
- CREATE TABLE "temporary_address_txs_entity" (
12
- "id" integer PRIMARY KEY AUTOINCREMENT NOT NULL,
13
- "unsignedHash" varchar NOT NULL,
14
- "signedHash" varchar NOT NULL,
15
- "nonce" integer NOT NULL,
16
- "address" varchar NOT NULL,
17
- "blockId" varchar NOT NULL,
18
- "extractor" varchar NOT NULL,
19
- "status" varchar NOT NULL
20
- )
21
- `);
22
- await queryRunner.query(`
23
- INSERT INTO "temporary_address_txs_entity"(
24
- "id",
25
- "unsignedHash",
26
- "signedHash",
27
- "nonce",
28
- "address",
29
- "blockId",
30
- "extractor",
31
- "status"
32
- )
33
- SELECT "id",
34
- "unsignedHash",
35
- "signedHash",
36
- "nonce",
37
- "address",
38
- "blockId",
39
- "extractor",
40
- 'succeed'
41
- FROM "address_txs_entity"
42
- `);
43
- await queryRunner.query(`
44
- DROP TABLE "address_txs_entity"
45
- `);
46
- await queryRunner.query(`
47
- ALTER TABLE "temporary_address_txs_entity"
48
- RENAME TO "address_txs_entity"
49
- `);
50
- }
51
-
52
- public async down(queryRunner: QueryRunner): Promise<void> {
53
- await queryRunner.query(`
54
- ALTER TABLE "address_txs_entity"
55
- RENAME TO "temporary_address_txs_entity"
56
- `);
57
- await queryRunner.query(`
58
- CREATE TABLE "address_txs_entity" (
59
- "id" integer PRIMARY KEY AUTOINCREMENT NOT NULL,
60
- "unsignedHash" varchar NOT NULL,
61
- "signedHash" varchar NOT NULL,
62
- "nonce" integer NOT NULL,
63
- "address" varchar NOT NULL,
64
- "blockId" varchar NOT NULL,
65
- "extractor" varchar NOT NULL
66
- )
67
- `);
68
- await queryRunner.query(`
69
- INSERT INTO "address_txs_entity"(
70
- "id",
71
- "unsignedHash",
72
- "signedHash",
73
- "nonce",
74
- "address",
75
- "blockId",
76
- "extractor"
77
- )
78
- SELECT "id",
79
- "unsignedHash",
80
- "signedHash",
81
- "nonce",
82
- "address",
83
- "blockId",
84
- "extractor"
85
- FROM "temporary_address_txs_entity"
86
- `);
87
- await queryRunner.query(`
88
- DROP TABLE "temporary_address_txs_entity"
89
- `);
90
- }
91
- }
@@ -1,124 +0,0 @@
1
- import { createDatabase, generateRandomId } from '../testUtils';
2
- import { TxAction } from '../../lib/actions/db';
3
- import { AddressTxsEntity, EvmTxStatus } from '../../lib';
4
- import { DataSource, Repository } from '@rosen-bridge/extended-typeorm';
5
-
6
- let dataSource: DataSource;
7
- let action: TxAction;
8
- let repository: Repository<AddressTxsEntity>;
9
-
10
- describe('TxAction', () => {
11
- beforeEach(async () => {
12
- dataSource = await createDatabase();
13
- action = new TxAction(dataSource);
14
- repository = dataSource.getRepository(AddressTxsEntity);
15
- });
16
-
17
- describe('deleteBlockTxs', () => {
18
- /**
19
- * @target TxAction.deleteBlockTxs should delete only expected block txs
20
- * @dependency
21
- * @scenario
22
- * - insert five transaction for two blocks
23
- * - call deleteBlockTxs
24
- * @expected
25
- * - AddressTxsEntity records count must be 2
26
- */
27
- it('should delete only expected block txs', async () => {
28
- const txs = [0, 1, 2, 3, 4].map((i) => {
29
- return {
30
- unsignedHash: '0x' + generateRandomId(),
31
- signedHash: '0x' + generateRandomId(),
32
- nonce: i,
33
- address: '0xedee4752e5a2f595151c94762fb38e5730357785',
34
- blockId: i < 2 ? 'block1' : 'block2',
35
- extractor: 'extractor 1',
36
- status: EvmTxStatus.succeed,
37
- };
38
- });
39
- for (const tx of txs) await repository.insert(tx);
40
- await action.deleteBlockTxs('block1', 'extractor 1');
41
- expect(await repository.count()).toEqual(3);
42
- });
43
-
44
- /**
45
- * @target TxAction.deleteBlockTxs should delete only selected extractor txs
46
- * @dependency
47
- * @scenario
48
- * - insert five transaction for two extractor for same block
49
- * - call deleteBlockTxs
50
- * @expected
51
- * - AddressTxsEntity records count must be 2
52
- */
53
- it('should delete only selected extractor txs', async () => {
54
- const txs = [0, 1, 2, 3, 4].map((i) => {
55
- return {
56
- unsignedHash: '0x' + generateRandomId(),
57
- signedHash: '0x' + generateRandomId(),
58
- nonce: i,
59
- address: '0xedee4752e5a2f595151c94762fb38e5730357785',
60
- blockId: 'block1',
61
- extractor: i < 2 ? 'extractor 1' : 'extractor 2',
62
- status: EvmTxStatus.succeed,
63
- };
64
- });
65
- for (const tx of txs) await repository.insert(tx);
66
- await action.deleteBlockTxs('block1', 'extractor 1');
67
- expect(await repository.count()).toEqual(3);
68
- });
69
- });
70
-
71
- describe('storeTxs', () => {
72
- /**
73
- * @target TxAction.storeTxs should insert all extracted transactions
74
- * @dependency
75
- * @scenario
76
- * - call storeTxs with 2 txs in a block
77
- * @expected
78
- * - AddressTxsEntity records count must be 2
79
- * - for each txId one entity exists with correct data
80
- */
81
- it('should insert all extracted transactions', async () => {
82
- const txs = [
83
- {
84
- unsignedHash: '0x' + generateRandomId(),
85
- signedHash: '0x' + generateRandomId(),
86
- nonce: 0,
87
- address: '0xedee4752e5a2f595151c94762fb38e5730357785',
88
- status: EvmTxStatus.succeed,
89
- },
90
- {
91
- unsignedHash: '0x' + generateRandomId(),
92
- signedHash: '0x' + generateRandomId(),
93
- nonce: 1,
94
- address: '0xedee4752e5a2f595151c94762fb38e5730357785',
95
- status: EvmTxStatus.succeed,
96
- },
97
- ];
98
-
99
- await action.storeTxs(
100
- txs,
101
- {
102
- height: 0,
103
- hash: 'block 1',
104
- parentHash: '',
105
- timestamp: 10,
106
- },
107
- 'extractor 1',
108
- );
109
- const records = await repository.find();
110
- expect(records.length).toEqual(2);
111
- for (const tx of txs) {
112
- const element = records.filter(
113
- (item) => item.signedHash === tx.signedHash,
114
- );
115
- expect(element.length).toEqual(1);
116
- expect(element[0].unsignedHash).toEqual(tx.unsignedHash);
117
- expect(element[0].nonce).toEqual(tx.nonce);
118
- expect(element[0].address).toEqual(tx.address);
119
- expect(element[0].blockId).toEqual('block 1');
120
- expect(element[0].extractor).toEqual('extractor 1');
121
- }
122
- });
123
- });
124
- });
@@ -1,70 +0,0 @@
1
- /* eslint-disable @typescript-eslint/no-explicit-any */
2
-
3
- import { vi } from 'vitest';
4
- import { Transaction } from 'ethers';
5
- import { DataSource } from '@rosen-bridge/extended-typeorm';
6
- import { createDatabase } from '../testUtils';
7
- import { EvmTxExtractor, AddressTxsEntity } from '../../lib';
8
- import { address, txs, expectedExtractedTxs } from './testData';
9
-
10
- let dataSource: DataSource;
11
-
12
- vi.mock('ethers', async (importOriginal) => {
13
- const ref = await importOriginal<typeof import('ethers')>();
14
- return {
15
- ...ref,
16
- JsonRpcProvider: vi.fn().mockImplementation(() => {
17
- return {};
18
- }),
19
- };
20
- });
21
-
22
- describe('EvmTxExtractor', () => {
23
- beforeEach(async () => {
24
- dataSource = await createDatabase();
25
- });
26
- describe('processTransactions', () => {
27
- /**
28
- * @target EvmTxExtractor.processTransactions should insert all
29
- * transactions of the address into database
30
- * @dependency
31
- * @scenario
32
- * - mock `wait` function of the transactions
33
- * - two txs to return the transaction
34
- * - one tx to throw CallException
35
- * - call processTransactions with 3 txs in a block
36
- * @expected
37
- * - two instances of txId must be inserted into database with expected data
38
- */
39
- it('should insert all transactions of the address into database', async () => {
40
- const extractor = new EvmTxExtractor(dataSource, 'extractor1', address);
41
- const repository = dataSource.getRepository(AddressTxsEntity);
42
- await repository.createQueryBuilder().delete().execute();
43
- vi.spyOn(txs[0], 'wait').mockReturnValue(Transaction.from(txs[0]) as any);
44
- vi.spyOn(txs[1], 'wait').mockReturnValue(Transaction.from(txs[1]) as any);
45
- vi.spyOn(txs[2], 'wait').mockImplementation(() => {
46
- throw {
47
- code: 'CALL_EXCEPTION',
48
- };
49
- });
50
- await extractor.processTransactions(txs, {
51
- height: 0,
52
- hash: 'block 1',
53
- parentHash: '',
54
- timestamp: 10,
55
- });
56
- const elements = await repository.find();
57
- expect(elements.length).toEqual(expectedExtractedTxs.length);
58
- for (const { status, tx } of expectedExtractedTxs) {
59
- const filteredElements = elements.filter(
60
- (item) => item.signedHash === tx.signedHash,
61
- );
62
- expect(filteredElements.length).toEqual(1);
63
- const element = filteredElements[0];
64
- expect(element.blockId).toEqual('block 1');
65
- expect(element.extractor).toEqual('extractor1');
66
- expect(element.status).toEqual(status);
67
- }
68
- });
69
- });
70
- });
@@ -1,104 +0,0 @@
1
- import {
2
- JsonRpcProvider,
3
- Transaction,
4
- TransactionResponse,
5
- TransactionResponseParams,
6
- } from 'ethers';
7
- import { EvmTxStatus } from '../../lib';
8
-
9
- export const address = '0x103931ca7ea5a385918e77e64fdd96430f6d2eca';
10
- export const txs: Array<TransactionResponse> = [
11
- Transaction.from({
12
- type: 2,
13
- to: '0xeDee4752e5a2F595151c94762fB38e5730357785',
14
- data: '0xa9059cbb0000000000000000000000004f0d2dde80b45e24ad4019a5aabd6c23aff2842b00000000000000000000000000000000000000000000000000000000e319aa30bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',
15
- nonce: 53,
16
- gasLimit: '21000',
17
- gasPrice: null,
18
- maxPriorityFeePerGas: '500000000',
19
- maxFeePerGas: '48978500000',
20
- value: '0',
21
- chainId: '1',
22
- accessList: [],
23
- signature: {
24
- r: '0xc15a4d9e300114ed005a2821f01f4aa74dcfd3daf10749f26d8cc1bd8507673c',
25
- s: '0x090492307ff4c7d2d514f373fa8fb01212c6af83391b6aed7039a3c9d6ecad11',
26
- yParity: 0,
27
- },
28
- hash: '0x3b194eea7cf9507e745806265738ca19213be209885534161ec0fa9c232c9fea',
29
- }),
30
- Transaction.from({
31
- type: 2,
32
- to: '0xb416c8a6d7ec94706a9ae2c26c11d320519482b1',
33
- data: '0xa9059cbb000000000000000000000000edee4752e5a2f595151c94762fb38e573035778500000000000000000000000000000000000000000000000000000000c502fc7000000000007554fc820000000000962f582103f999da8e6e42660e4464d17d29e63bc006734a6710a24eb489b466323d3a9339',
34
- nonce: 10,
35
- gasLimit: '21000',
36
- gasPrice: null,
37
- maxPriorityFeePerGas: '500000000',
38
- maxFeePerGas: '48978500000',
39
- value: '92850988521632054',
40
- chainId: '1',
41
- accessList: [],
42
- signature: {
43
- r: '0x7af681001bf23365afc66fbdb18e33bbd69779d3436c3ad2d27797bd133b2235',
44
- s: '0x79b8f448c88ba863f450ebe916d386d696efe49ed33932c20951ed53fe50f915',
45
- yParity: 0,
46
- },
47
- }),
48
- Transaction.from({
49
- type: 2,
50
- to: '0xEDee4752e5a2F595151c94762fb38e5730437785',
51
- data: '0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',
52
- nonce: 53,
53
- gasLimit: '21000',
54
- gasPrice: null,
55
- maxPriorityFeePerGas: '500000000',
56
- maxFeePerGas: '48978500000',
57
- value: '0',
58
- chainId: '1',
59
- accessList: [],
60
- signature: {
61
- r: '0xbd9f0cae0d3e31b026cc828b7e5778ab79cf09b86f32ef07ad364f3e8fc1c31d',
62
- s: '0x1d8db0fd3bc212ccff7661ecc9b95f9d985b4e75dfd211545f78ab0cef169ee1',
63
- yParity: 0,
64
- },
65
- hash: '0x51aff9363672214b387a471b7c973de7fa06cd020d7e46f5b11e7794ff4dc29b',
66
- }),
67
- ].map(
68
- (tx) =>
69
- new TransactionResponse(
70
- tx as unknown as TransactionResponseParams,
71
- new JsonRpcProvider(),
72
- ),
73
- );
74
-
75
- export const expectedExtractedTxs = [
76
- {
77
- status: EvmTxStatus.succeed,
78
- tx: {
79
- id: 1,
80
- unsignedHash:
81
- '0x47098cb4de103a91ce4c73543ec5658b2ca530050ebf77d9dfa22611e9781c54',
82
- signedHash:
83
- '0x3b194eea7cf9507e745806265738ca19213be209885534161ec0fa9c232c9fea',
84
- nonce: 53,
85
- address: '0x103931ca7ea5a385918E77E64Fdd96430F6d2ECa',
86
- blockId: 'block 1',
87
- extractor: 'extractor1',
88
- },
89
- },
90
- {
91
- status: EvmTxStatus.failed,
92
- tx: {
93
- id: 2,
94
- unsignedHash:
95
- '0xc042ca344198b72db99e55b44ceb51cdc719e32bd1ed4881c11e14915654da90',
96
- signedHash:
97
- '0x51aff9363672214b387a471b7c973de7fa06cd020d7e46f5b11e7794ff4dc29b',
98
- nonce: 53,
99
- address: '0x103931ca7ea5a385918E77E64Fdd96430F6d2ECa',
100
- blockId: 'block 1',
101
- extractor: 'extractor1',
102
- },
103
- },
104
- ];
@@ -1,22 +0,0 @@
1
- import { DataSource } from '@rosen-bridge/extended-typeorm';
2
- import { AddressTxsEntity } from '../lib';
3
- import { migrations } from '../lib';
4
- import { randomBytes } from 'crypto';
5
-
6
- export const createDatabase = async (): Promise<DataSource> => {
7
- return new DataSource({
8
- type: 'sqlite',
9
- database: ':memory:',
10
- entities: [AddressTxsEntity],
11
- migrations: migrations.sqlite,
12
- synchronize: false,
13
- logging: false,
14
- })
15
- .initialize()
16
- .then(async (dataSource) => {
17
- await dataSource.runMigrations();
18
- return dataSource;
19
- });
20
- };
21
-
22
- export const generateRandomId = (): string => randomBytes(32).toString('hex');
@@ -1,11 +0,0 @@
1
- {
2
- "extends": "./tsconfig.json",
3
- "compilerOptions": {
4
- "rootDir": "./lib"
5
- },
6
- "exclude": ["tests", "vitest.config.ts"],
7
- "references": [
8
- { "path": "../abstract-extractor/tsconfig.build.json" },
9
- { "path": "../scanner-interfaces/tsconfig.build.json" }
10
- ]
11
- }