@pjts/web3 0.0.19
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/README.md +3 -0
- package/dist/BlockSubscriber.d.ts +10 -0
- package/dist/BlockSubscriber.js +49 -0
- package/dist/BlockSubscriber.js.map +1 -0
- package/dist/BlockchainAddress.d.ts +10 -0
- package/dist/BlockchainAddress.js +42 -0
- package/dist/BlockchainAddress.js.map +1 -0
- package/dist/BlockchainEventProvider.d.ts +14 -0
- package/dist/BlockchainEventProvider.js +84 -0
- package/dist/BlockchainEventProvider.js.map +1 -0
- package/dist/BlockchainEventSinkBase.d.ts +25 -0
- package/dist/BlockchainEventSinkBase.js +102 -0
- package/dist/BlockchainEventSinkBase.js.map +1 -0
- package/dist/NetworkSettings.d.ts +24 -0
- package/dist/NetworkSettings.js +77 -0
- package/dist/NetworkSettings.js.map +1 -0
- package/dist/SmartContractBase.d.ts +18 -0
- package/dist/SmartContractBase.js +55 -0
- package/dist/SmartContractBase.js.map +1 -0
- package/dist/buildBatches.d.ts +1 -0
- package/dist/buildBatches.js +33 -0
- package/dist/buildBatches.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/interfaces/BlockCursorProviderPort.d.ts +4 -0
- package/dist/interfaces/BlockCursorProviderPort.js +3 -0
- package/dist/interfaces/BlockCursorProviderPort.js.map +1 -0
- package/dist/interfaces/BlockSubscriberPort.d.ts +5 -0
- package/dist/interfaces/BlockSubscriberPort.js +3 -0
- package/dist/interfaces/BlockSubscriberPort.js.map +1 -0
- package/dist/interfaces/BlockchainEventProviderPort.d.ts +4 -0
- package/dist/interfaces/BlockchainEventProviderPort.js +3 -0
- package/dist/interfaces/BlockchainEventProviderPort.js.map +1 -0
- package/dist/interfaces/BlockchainEventReceived.d.ts +15 -0
- package/dist/interfaces/BlockchainEventReceived.js +3 -0
- package/dist/interfaces/BlockchainEventReceived.js.map +1 -0
- package/package.json +39 -0
package/README.md
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Unsubscribe } from '@pjts/infra';
|
|
2
|
+
import { BlockSubscriberPort } from './interfaces/BlockSubscriberPort';
|
|
3
|
+
import { NetworkSettings } from './NetworkSettings';
|
|
4
|
+
export declare class BlockSubscriber implements BlockSubscriberPort {
|
|
5
|
+
private readonly networkSettings;
|
|
6
|
+
private readonly provider;
|
|
7
|
+
constructor(networkSettings: NetworkSettings);
|
|
8
|
+
getCurrentBlockNumber(): Promise<number>;
|
|
9
|
+
subscribe(handler: (blockNumber: number) => Promise<void>): Promise<Unsubscribe>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BlockSubscriber = void 0;
|
|
4
|
+
const core_1 = require("@pjts/core");
|
|
5
|
+
const ethers_1 = require("ethers");
|
|
6
|
+
const infra_1 = require("@pjts/infra");
|
|
7
|
+
// getCurrentBlockNumber can be called from many different processes, this is to limit calls to node rpc endpoint
|
|
8
|
+
const blockNumberCache = new infra_1.InMemoryCache();
|
|
9
|
+
class BlockSubscriber {
|
|
10
|
+
networkSettings;
|
|
11
|
+
provider;
|
|
12
|
+
constructor(networkSettings) {
|
|
13
|
+
this.networkSettings = networkSettings;
|
|
14
|
+
this.provider = new ethers_1.ethers.JsonRpcProvider(networkSettings.rpcUrl);
|
|
15
|
+
}
|
|
16
|
+
async getCurrentBlockNumber() {
|
|
17
|
+
return blockNumberCache.cache('*', async () => {
|
|
18
|
+
try {
|
|
19
|
+
return await this.provider.getBlockNumber();
|
|
20
|
+
}
|
|
21
|
+
catch (err) {
|
|
22
|
+
core_1.Logger.debug(`BlockSubscriber#getCurrentBlockNumber | error: ${err}`);
|
|
23
|
+
await (0, core_1.sleep)(1000);
|
|
24
|
+
throw err;
|
|
25
|
+
}
|
|
26
|
+
}, this.networkSettings.blocksInterval);
|
|
27
|
+
}
|
|
28
|
+
async subscribe(handler) {
|
|
29
|
+
let interval;
|
|
30
|
+
let isRunning = true;
|
|
31
|
+
let lastProcessedBlockNumber = Math.max((await this.getCurrentBlockNumber()) - this.networkSettings.confirmedBlockCount, 0);
|
|
32
|
+
const processQueue = async () => {
|
|
33
|
+
const currentBlockNumber = await this.getCurrentBlockNumber();
|
|
34
|
+
while (isRunning && currentBlockNumber >= lastProcessedBlockNumber) {
|
|
35
|
+
core_1.Logger.debug(`BlockSubscriber#processQueue | processing block: ${currentBlockNumber}`);
|
|
36
|
+
await handler(lastProcessedBlockNumber);
|
|
37
|
+
lastProcessedBlockNumber++;
|
|
38
|
+
}
|
|
39
|
+
interval = setTimeout(processQueue, this.networkSettings.blocksInterval);
|
|
40
|
+
};
|
|
41
|
+
processQueue();
|
|
42
|
+
return async () => {
|
|
43
|
+
isRunning = false;
|
|
44
|
+
clearTimeout(interval);
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
exports.BlockSubscriber = BlockSubscriber;
|
|
49
|
+
//# sourceMappingURL=BlockSubscriber.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BlockSubscriber.js","sourceRoot":"","sources":["../src/BlockSubscriber.ts"],"names":[],"mappings":";;;AAAA,qCAA0C;AAC1C,mCAA+B;AAC/B,uCAAwD;AAIxD,iHAAiH;AACjH,MAAM,gBAAgB,GAAG,IAAI,qBAAa,EAAU,CAAC;AAErD,MAAa,eAAe;IAGG;IAFZ,QAAQ,CAAwB;IAEjD,YAA6B,eAAgC;QAAhC,oBAAe,GAAf,eAAe,CAAiB;QAC3D,IAAI,CAAC,QAAQ,GAAG,IAAI,eAAM,CAAC,eAAe,CAAC,eAAe,CAAC,MAAM,CAAC,CAAA;IACpE,CAAC;IAEM,KAAK,CAAC,qBAAqB;QAChC,OAAO,gBAAgB,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,IAAI,EAAE;YAC5C,IAAI;gBACF,OAAO,MAAM,IAAI,CAAC,QAAQ,CAAC,cAAc,EAAE,CAAA;aAC5C;YAAC,OAAO,GAAG,EAAE;gBACZ,aAAM,CAAC,KAAK,CAAC,kDAAkD,GAAG,EAAE,CAAC,CAAA;gBACrE,MAAM,IAAA,YAAK,EAAC,IAAI,CAAC,CAAA;gBACjB,MAAM,GAAG,CAAA;aACV;QACH,CAAC,EAAE,IAAI,CAAC,eAAe,CAAC,cAAc,CAAC,CAAA;IACzC,CAAC;IAEM,KAAK,CAAC,SAAS,CAAC,OAA+C;QACpE,IAAI,QAAwB,CAAA;QAC5B,IAAI,SAAS,GAAG,IAAI,CAAA;QACpB,IAAI,wBAAwB,GAAG,IAAI,CAAC,GAAG,CACrC,CAAC,MAAM,IAAI,CAAC,qBAAqB,EAAE,CAAC,GAAG,IAAI,CAAC,eAAe,CAAC,mBAAmB,EAC/E,CAAC,CACF,CAAA;QAED,MAAM,YAAY,GAAG,KAAK,IAAI,EAAE;YAC9B,MAAM,kBAAkB,GAAG,MAAM,IAAI,CAAC,qBAAqB,EAAE,CAAA;YAC7D,OAAO,SAAS,IAAI,kBAAkB,IAAI,wBAAwB,EAAE;gBAClE,aAAM,CAAC,KAAK,CAAC,oDAAoD,kBAAkB,EAAE,CAAC,CAAA;gBACtF,MAAM,OAAO,CAAC,wBAAwB,CAAC,CAAA;gBACvC,wBAAwB,EAAE,CAAA;aAC3B;YACD,QAAQ,GAAG,UAAU,CAAC,YAAY,EAAE,IAAI,CAAC,eAAe,CAAC,cAAc,CAAC,CAAA;QAC1E,CAAC,CAAA;QAED,YAAY,EAAE,CAAA;QAEd,OAAO,KAAK,IAAI,EAAE;YAChB,SAAS,GAAG,KAAK,CAAA;YACjB,YAAY,CAAC,QAAQ,CAAC,CAAA;QACxB,CAAC,CAAA;IACH,CAAC;CACF;AA5CD,0CA4CC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Id } from '@pjts/infra';
|
|
2
|
+
export declare class BlockchainAddress {
|
|
3
|
+
private readonly value;
|
|
4
|
+
static isValid(value: string): boolean;
|
|
5
|
+
constructor(value: string);
|
|
6
|
+
toId(): Id;
|
|
7
|
+
eq(other: BlockchainAddress): boolean;
|
|
8
|
+
getValue(): string;
|
|
9
|
+
toJSON(): string;
|
|
10
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var BlockchainAddress_1;
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.BlockchainAddress = void 0;
|
|
5
|
+
const tslib_1 = require("tslib");
|
|
6
|
+
const core_1 = require("@pjts/core");
|
|
7
|
+
const infra_1 = require("@pjts/infra");
|
|
8
|
+
const ethers_1 = require("ethers");
|
|
9
|
+
const uuid_1 = require("uuid");
|
|
10
|
+
let BlockchainAddress = BlockchainAddress_1 = class BlockchainAddress {
|
|
11
|
+
value;
|
|
12
|
+
static isValid(value) {
|
|
13
|
+
return ethers_1.ethers.isAddress(value);
|
|
14
|
+
}
|
|
15
|
+
constructor(value) {
|
|
16
|
+
if (value.length !== 42) {
|
|
17
|
+
throw core_1.AppError.badRequest('Invalid Blockchain Address');
|
|
18
|
+
}
|
|
19
|
+
if (!BlockchainAddress_1.isValid(value)) {
|
|
20
|
+
throw core_1.AppError.badRequest('Invalid Blockchain Address');
|
|
21
|
+
}
|
|
22
|
+
this.value = value.toLowerCase();
|
|
23
|
+
}
|
|
24
|
+
toId() {
|
|
25
|
+
return new infra_1.Id((0, uuid_1.v5)(this.value, uuid_1.v5.URL));
|
|
26
|
+
}
|
|
27
|
+
eq(other) {
|
|
28
|
+
return this.value === other.getValue();
|
|
29
|
+
}
|
|
30
|
+
getValue() {
|
|
31
|
+
return this.value;
|
|
32
|
+
}
|
|
33
|
+
toJSON() {
|
|
34
|
+
return this.value;
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
BlockchainAddress = BlockchainAddress_1 = tslib_1.__decorate([
|
|
38
|
+
core_1.StringDomainPrimitive,
|
|
39
|
+
tslib_1.__metadata("design:paramtypes", [String])
|
|
40
|
+
], BlockchainAddress);
|
|
41
|
+
exports.BlockchainAddress = BlockchainAddress;
|
|
42
|
+
//# sourceMappingURL=BlockchainAddress.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BlockchainAddress.js","sourceRoot":"","sources":["../src/BlockchainAddress.ts"],"names":[],"mappings":";;;;;AAAA,qCAA4D;AAC5D,uCAAgC;AAChC,mCAA+B;AAC/B,+BAAyB;AAGlB,IAAM,iBAAiB,yBAAvB,MAAM,iBAAiB;IACX,KAAK,CAAQ;IAEvB,MAAM,CAAC,OAAO,CAAC,KAAa;QACjC,OAAO,eAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;IAChC,CAAC;IAED,YAAY,KAAa;QACvB,IAAI,KAAK,CAAC,MAAM,KAAK,EAAE,EAAE;YACvB,MAAM,eAAQ,CAAC,UAAU,CAAC,4BAA4B,CAAC,CAAA;SACxD;QACD,IAAI,CAAC,mBAAiB,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;YACrC,MAAM,eAAQ,CAAC,UAAU,CAAC,4BAA4B,CAAC,CAAA;SACxD;QACD,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,WAAW,EAAE,CAAA;IAClC,CAAC;IAEM,IAAI;QACT,OAAO,IAAI,UAAE,CAAC,IAAA,SAAE,EAAC,IAAI,CAAC,KAAK,EAAE,SAAE,CAAC,GAAG,CAAC,CAAC,CAAA;IACvC,CAAC;IAEM,EAAE,CAAC,KAAwB;QAChC,OAAO,IAAI,CAAC,KAAK,KAAK,KAAK,CAAC,QAAQ,EAAE,CAAA;IACxC,CAAC;IAEM,QAAQ;QACb,OAAO,IAAI,CAAC,KAAK,CAAA;IACnB,CAAC;IAEM,MAAM;QACX,OAAO,IAAI,CAAC,KAAK,CAAA;IACnB,CAAC;CACF,CAAA;AAhCY,iBAAiB;IAD7B,4BAAqB;;GACT,iBAAiB,CAgC7B;AAhCY,8CAAiB"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { JSONArrayType } from '@pjts/infra';
|
|
2
|
+
import { BlockchainAddress } from './BlockchainAddress';
|
|
3
|
+
import { NetworkSettings } from './NetworkSettings';
|
|
4
|
+
import { BlockchainEventReceived } from './interfaces/BlockchainEventReceived';
|
|
5
|
+
import { BlockchainEventProviderPort } from './interfaces/BlockchainEventProviderPort';
|
|
6
|
+
export declare class BlockchainEventProvider implements BlockchainEventProviderPort {
|
|
7
|
+
private readonly networkSettings;
|
|
8
|
+
private readonly contractAddress;
|
|
9
|
+
private readonly provider;
|
|
10
|
+
private readonly interface;
|
|
11
|
+
constructor(networkSettings: NetworkSettings, contractAddress: BlockchainAddress, abi: JSONArrayType);
|
|
12
|
+
get(fromBlock: number, toBlock: number, confirmedSinceBlock: number): Promise<BlockchainEventReceived[]>;
|
|
13
|
+
private getBlock;
|
|
14
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BlockchainEventProvider = void 0;
|
|
4
|
+
const core_1 = require("@pjts/core");
|
|
5
|
+
const infra_1 = require("@pjts/infra");
|
|
6
|
+
const ethers_1 = require("ethers");
|
|
7
|
+
const uuid_1 = require("uuid");
|
|
8
|
+
const cache = new infra_1.InMemoryCache();
|
|
9
|
+
class BlockchainEventProvider {
|
|
10
|
+
networkSettings;
|
|
11
|
+
contractAddress;
|
|
12
|
+
provider;
|
|
13
|
+
interface;
|
|
14
|
+
constructor(networkSettings, contractAddress, abi) {
|
|
15
|
+
this.networkSettings = networkSettings;
|
|
16
|
+
this.contractAddress = contractAddress;
|
|
17
|
+
this.provider = new ethers_1.ethers.JsonRpcProvider(networkSettings.rpcUrl, networkSettings.number);
|
|
18
|
+
this.interface = new ethers_1.ethers.Interface(abi);
|
|
19
|
+
}
|
|
20
|
+
async get(fromBlock, toBlock, confirmedSinceBlock) {
|
|
21
|
+
const logs = await this.provider.getLogs({
|
|
22
|
+
address: this.contractAddress.getValue(),
|
|
23
|
+
fromBlock,
|
|
24
|
+
toBlock,
|
|
25
|
+
});
|
|
26
|
+
const events = [];
|
|
27
|
+
for (const log of logs) {
|
|
28
|
+
if (log.removed) {
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
const block = await this.getBlock(log.blockNumber);
|
|
32
|
+
if (!block) {
|
|
33
|
+
core_1.Logger.error(`BlockchainEventProvider | Cannot get block header ${log.blockNumber}`);
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
const parsed = this.interface.parseLog(log);
|
|
37
|
+
if (parsed?.name) {
|
|
38
|
+
const envelope = {
|
|
39
|
+
...parsed?.fragment.inputs
|
|
40
|
+
.map(i => i.name)
|
|
41
|
+
.reduce((acc, key, idx) => {
|
|
42
|
+
const value = parsed?.args[idx];
|
|
43
|
+
if (typeof value !== 'bigint') {
|
|
44
|
+
acc[key] = value.toString();
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
acc[key] = String(value);
|
|
48
|
+
}
|
|
49
|
+
return acc;
|
|
50
|
+
}, {}),
|
|
51
|
+
};
|
|
52
|
+
const isConfirmed = log.blockNumber <= confirmedSinceBlock;
|
|
53
|
+
const eventId = [
|
|
54
|
+
log.transactionHash,
|
|
55
|
+
this.contractAddress.getValue(),
|
|
56
|
+
logs.indexOf(log),
|
|
57
|
+
Number(isConfirmed),
|
|
58
|
+
].join('@');
|
|
59
|
+
events.push({
|
|
60
|
+
name: 'BLOCKCHAIN_EVENT_RECEIVED',
|
|
61
|
+
aggregateId: (0, uuid_1.v5)(this.contractAddress.getValue(), uuid_1.v5.URL),
|
|
62
|
+
uuid: (0, uuid_1.v5)(eventId, uuid_1.v5.URL),
|
|
63
|
+
networkId: this.networkSettings.number,
|
|
64
|
+
timestamp: new Date(),
|
|
65
|
+
blockchainEventName: parsed?.name,
|
|
66
|
+
blockTimestamp: new Date(block.timestamp * 1000).toISOString(),
|
|
67
|
+
txHash: log.transactionHash,
|
|
68
|
+
blockNumber: log.blockNumber,
|
|
69
|
+
contractAddress: this.contractAddress.getValue(),
|
|
70
|
+
envelope,
|
|
71
|
+
isConfirmed,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return events;
|
|
76
|
+
}
|
|
77
|
+
getBlock = async (blockNumber) => {
|
|
78
|
+
return cache.cache(blockNumber.toString(), async () => {
|
|
79
|
+
return await this.provider.getBlock(blockNumber);
|
|
80
|
+
}, 1000 * 60 * 60 * 24);
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
exports.BlockchainEventProvider = BlockchainEventProvider;
|
|
84
|
+
//# sourceMappingURL=BlockchainEventProvider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BlockchainEventProvider.js","sourceRoot":"","sources":["../src/BlockchainEventProvider.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Worker } from '@pjts/infra';
|
|
2
|
+
import { BlockchainAddress } from './BlockchainAddress';
|
|
3
|
+
import { NetworkSettings } from './NetworkSettings';
|
|
4
|
+
import { BlockCursorProviderPort } from './interfaces/BlockCursorProviderPort';
|
|
5
|
+
import { BlockSubscriberPort } from './interfaces/BlockSubscriberPort';
|
|
6
|
+
import { BlockchainEventProviderPort } from './interfaces/BlockchainEventProviderPort';
|
|
7
|
+
import { BlockchainEventReceived } from './interfaces/BlockchainEventReceived';
|
|
8
|
+
export declare abstract class BlockchainEventSinkBase implements Worker {
|
|
9
|
+
private readonly contractAddress;
|
|
10
|
+
private readonly networkSettings;
|
|
11
|
+
private readonly blockCursorProvider;
|
|
12
|
+
private readonly blockSubscriber;
|
|
13
|
+
private readonly blockchainEventProvider;
|
|
14
|
+
private unsubscribe?;
|
|
15
|
+
private processedIds;
|
|
16
|
+
private purgeCacheInterval;
|
|
17
|
+
constructor(contractAddress: BlockchainAddress, networkSettings: NetworkSettings, blockCursorProvider: BlockCursorProviderPort, blockSubscriber: BlockSubscriberPort, blockchainEventProvider: BlockchainEventProviderPort);
|
|
18
|
+
protected abstract handleEvents(events: BlockchainEventReceived[]): Promise<void>;
|
|
19
|
+
private get name();
|
|
20
|
+
start(): Promise<void>;
|
|
21
|
+
private handleBlock;
|
|
22
|
+
private recover;
|
|
23
|
+
private handleRestart;
|
|
24
|
+
stop(): Promise<void>;
|
|
25
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BlockchainEventSinkBase = void 0;
|
|
4
|
+
const core_1 = require("@pjts/core");
|
|
5
|
+
const buildBatches_1 = require("./buildBatches");
|
|
6
|
+
class BlockchainEventSinkBase {
|
|
7
|
+
contractAddress;
|
|
8
|
+
networkSettings;
|
|
9
|
+
blockCursorProvider;
|
|
10
|
+
blockSubscriber;
|
|
11
|
+
blockchainEventProvider;
|
|
12
|
+
unsubscribe;
|
|
13
|
+
processedIds = new Set();
|
|
14
|
+
purgeCacheInterval;
|
|
15
|
+
constructor(contractAddress, networkSettings, blockCursorProvider, blockSubscriber, blockchainEventProvider) {
|
|
16
|
+
this.contractAddress = contractAddress;
|
|
17
|
+
this.networkSettings = networkSettings;
|
|
18
|
+
this.blockCursorProvider = blockCursorProvider;
|
|
19
|
+
this.blockSubscriber = blockSubscriber;
|
|
20
|
+
this.blockchainEventProvider = blockchainEventProvider;
|
|
21
|
+
this.purgeCacheInterval = setInterval(() => {
|
|
22
|
+
this.processedIds = new Set();
|
|
23
|
+
}, 5 * 60_000);
|
|
24
|
+
}
|
|
25
|
+
get name() {
|
|
26
|
+
return this.contractAddress.getValue() + '@' + this.networkSettings.number;
|
|
27
|
+
}
|
|
28
|
+
async start() {
|
|
29
|
+
core_1.Logger.info(`BlockchainEventSink | ${this.name} | start`);
|
|
30
|
+
const lastProcessedBlockNumber = await this.blockCursorProvider.getLastProcessedBlockNumber(this.name);
|
|
31
|
+
const currentBlockNumber = await this.blockSubscriber.getCurrentBlockNumber();
|
|
32
|
+
const offset = currentBlockNumber - lastProcessedBlockNumber;
|
|
33
|
+
if (offset > 10) {
|
|
34
|
+
this.recover(lastProcessedBlockNumber, currentBlockNumber).then(async () => {
|
|
35
|
+
core_1.Logger.info(`BlockchainEventSink | ${this.name} | real time processing`);
|
|
36
|
+
this.unsubscribe = await this.blockSubscriber.subscribe(this.handleBlock);
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
core_1.Logger.info(`BlockchainEventSink | ${this.name} | real time processing`);
|
|
41
|
+
this.unsubscribe = await this.blockSubscriber.subscribe(this.handleBlock);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
handleBlock = async (blockNumber) => {
|
|
45
|
+
try {
|
|
46
|
+
core_1.Logger.debug(`BlockchainEventSink | ${this.name} | block ${blockNumber}, networkId: ${this.networkSettings.number}, rpcUrl: ${this.networkSettings.rpcUrl}`);
|
|
47
|
+
const currentBlockNumber = await this.blockSubscriber.getCurrentBlockNumber();
|
|
48
|
+
const confirmedSinceBlockNumber = Math.max(currentBlockNumber - this.networkSettings.confirmedBlockCount, 1);
|
|
49
|
+
const events = await this.blockchainEventProvider.get(Math.max(blockNumber - this.networkSettings.confirmedBlockCount, 1), Math.max(blockNumber - this.networkSettings.pendingBlockCount, 2), confirmedSinceBlockNumber);
|
|
50
|
+
const unprocessedEvents = events.filter(event => !this.processedIds.has(event.uuid));
|
|
51
|
+
core_1.Logger.debug(`BlockchainEventSink | ${this.name} | block ${blockNumber}, networkId: ${this.networkSettings.number}, rpcUrl: ${this.networkSettings.rpcUrl}, unprocessedEventsCount: ${unprocessedEvents.length}`);
|
|
52
|
+
if (unprocessedEvents.length > 0) {
|
|
53
|
+
await this.handleEvents(unprocessedEvents);
|
|
54
|
+
unprocessedEvents.forEach(event => {
|
|
55
|
+
this.processedIds.add(event.uuid);
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
await this.blockCursorProvider.markAsProcessed(this.name, blockNumber);
|
|
59
|
+
}
|
|
60
|
+
catch (err) {
|
|
61
|
+
await this.handleRestart(err);
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
async recover(lastProcessedBlockNumber, currentBlockNumber) {
|
|
65
|
+
try {
|
|
66
|
+
const fromBlock = Math.max(lastProcessedBlockNumber - this.networkSettings.confirmedBlockCount, 0);
|
|
67
|
+
const toBlock = Math.max(currentBlockNumber - this.networkSettings.confirmedBlockCount, 0);
|
|
68
|
+
const batchSize = this.networkSettings.batchProcessingLimit;
|
|
69
|
+
core_1.Logger.info(`BlockchainEventSink | ${this.name} | recovery started | fromBlock: ${fromBlock}, toBlock: ${toBlock}, batchSize: ${batchSize}, currentBlockNumber: ${currentBlockNumber}`);
|
|
70
|
+
const batches = (0, buildBatches_1.buildBatches)(fromBlock, toBlock, batchSize);
|
|
71
|
+
for (const batch of batches) {
|
|
72
|
+
core_1.Logger.info(`BlockchainEventSink | recovering events | fromBlock: ${batch[0]}, toBlock: ${batch[1]}`);
|
|
73
|
+
const events = await this.blockchainEventProvider.get(batch[0], batch[1], toBlock);
|
|
74
|
+
if (events.length > 0) {
|
|
75
|
+
await this.handleEvents(events);
|
|
76
|
+
}
|
|
77
|
+
await this.blockCursorProvider.markAsProcessed(this.name, batch[1]);
|
|
78
|
+
}
|
|
79
|
+
core_1.Logger.info(`BlockchainEventSink | recovery completed`);
|
|
80
|
+
}
|
|
81
|
+
catch (err) {
|
|
82
|
+
await this.handleRestart(err);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
handleRestart = async (err) => {
|
|
86
|
+
core_1.Logger.info(`BlockchainEventSink | name: ${this.name}, error: ${err}`);
|
|
87
|
+
await this.stop();
|
|
88
|
+
await (0, core_1.sleep)(5000);
|
|
89
|
+
core_1.Logger.info(`BlockchainEventSink | ${this.name} | restarting`);
|
|
90
|
+
this.start();
|
|
91
|
+
};
|
|
92
|
+
async stop() {
|
|
93
|
+
if (this.unsubscribe) {
|
|
94
|
+
await this.unsubscribe();
|
|
95
|
+
}
|
|
96
|
+
if (this.purgeCacheInterval) {
|
|
97
|
+
clearInterval(this.purgeCacheInterval);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
exports.BlockchainEventSinkBase = BlockchainEventSinkBase;
|
|
102
|
+
//# sourceMappingURL=BlockchainEventSinkBase.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BlockchainEventSinkBase.js","sourceRoot":"","sources":["../src/BlockchainEventSinkBase.ts"],"names":[],"mappings":";;;AAAA,qCAA0C;AAE1C,iDAA6C;AAQ7C,MAAsB,uBAAuB;IAMxB;IACA;IACA;IACA;IACA;IATX,WAAW,CAAc;IACzB,YAAY,GAAG,IAAI,GAAG,EAAE,CAAA;IACxB,kBAAkB,CAAC;IAE3B,YACmB,eAAkC,EAClC,eAAgC,EAChC,mBAA4C,EAC5C,eAAoC,EACpC,uBAAoD;QAJpD,oBAAe,GAAf,eAAe,CAAmB;QAClC,oBAAe,GAAf,eAAe,CAAiB;QAChC,wBAAmB,GAAnB,mBAAmB,CAAyB;QAC5C,oBAAe,GAAf,eAAe,CAAqB;QACpC,4BAAuB,GAAvB,uBAAuB,CAA6B;QAErE,IAAI,CAAC,kBAAkB,GAAG,WAAW,CAAC,GAAG,EAAE;YACzC,IAAI,CAAC,YAAY,GAAG,IAAI,GAAG,EAAE,CAAA;QAC/B,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,CAAA;IAChB,CAAC;IAID,IAAY,IAAI;QACd,OAAO,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,GAAG,GAAG,GAAG,IAAI,CAAC,eAAe,CAAC,MAAM,CAAA;IAC5E,CAAC;IAEM,KAAK,CAAC,KAAK;QAChB,aAAM,CAAC,IAAI,CAAC,yBAAyB,IAAI,CAAC,IAAI,UAAU,CAAC,CAAA;QACzD,MAAM,wBAAwB,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAAC,2BAA2B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACtG,MAAM,kBAAkB,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,qBAAqB,EAAE,CAAA;QAC7E,MAAM,MAAM,GAAG,kBAAkB,GAAG,wBAAwB,CAAA;QAC5D,IAAI,MAAM,GAAG,EAAE,EAAE;YACf,IAAI,CAAC,OAAO,CAAC,wBAAwB,EAAE,kBAAkB,CAAC,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;gBACzE,aAAM,CAAC,IAAI,CAAC,yBAAyB,IAAI,CAAC,IAAI,yBAAyB,CAAC,CAAA;gBACxE,IAAI,CAAC,WAAW,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;YAC3E,CAAC,CAAC,CAAA;SACH;aAAM;YACL,aAAM,CAAC,IAAI,CAAC,yBAAyB,IAAI,CAAC,IAAI,yBAAyB,CAAC,CAAA;YACxE,IAAI,CAAC,WAAW,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;SAC1E;IACH,CAAC;IAEO,WAAW,GAAG,KAAK,EAAE,WAAmB,EAAiB,EAAE;QACjE,IAAI;YACF,aAAM,CAAC,KAAK,CACV,yBAAyB,IAAI,CAAC,IAAI,YAAY,WAAW,gBAAgB,IAAI,CAAC,eAAe,CAAC,MAAM,aAAa,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,CAC/I,CAAA;YACD,MAAM,kBAAkB,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,qBAAqB,EAAE,CAAA;YAC7E,MAAM,yBAAyB,GAAG,IAAI,CAAC,GAAG,CAAC,kBAAkB,GAAG,IAAI,CAAC,eAAe,CAAC,mBAAmB,EAAE,CAAC,CAAC,CAAA;YAC5G,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,uBAAuB,CAAC,GAAG,CACnD,IAAI,CAAC,GAAG,CAAC,WAAW,GAAG,IAAI,CAAC,eAAe,CAAC,mBAAmB,EAAE,CAAC,CAAC,EACnE,IAAI,CAAC,GAAG,CAAC,WAAW,GAAG,IAAI,CAAC,eAAe,CAAC,iBAAiB,EAAE,CAAC,CAAC,EACjE,yBAAyB,CAC1B,CAAA;YACD,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAA;YACpF,aAAM,CAAC,KAAK,CACV,yBAAyB,IAAI,CAAC,IAAI,YAAY,WAAW,gBAAgB,IAAI,CAAC,eAAe,CAAC,MAAM,aAAa,IAAI,CAAC,eAAe,CAAC,MAAM,6BAA6B,iBAAiB,CAAC,MAAM,EAAE,CACpM,CAAA;YACD,IAAI,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE;gBAChC,MAAM,IAAI,CAAC,YAAY,CAAC,iBAAiB,CAAC,CAAA;gBAC1C,iBAAiB,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;oBAChC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;gBACnC,CAAC,CAAC,CAAA;aACH;YACD,MAAM,IAAI,CAAC,mBAAmB,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAA;SACvE;QAAC,OAAO,GAAG,EAAE;YACZ,MAAM,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAA;SAC9B;IACH,CAAC,CAAA;IAEO,KAAK,CAAC,OAAO,CAAC,wBAAgC,EAAE,kBAA0B;QAChF,IAAI;YACF,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,wBAAwB,GAAG,IAAI,CAAC,eAAe,CAAC,mBAAmB,EAAE,CAAC,CAAC,CAAA;YAClG,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,kBAAkB,GAAG,IAAI,CAAC,eAAe,CAAC,mBAAmB,EAAE,CAAC,CAAC,CAAA;YAC1F,MAAM,SAAS,GAAG,IAAI,CAAC,eAAe,CAAC,oBAAoB,CAAA;YAC3D,aAAM,CAAC,IAAI,CACT,yBAAyB,IAAI,CAAC,IAAI,oCAAoC,SAAS,cAAc,OAAO,gBAAgB,SAAS,yBAAyB,kBAAkB,EAAE,CAC3K,CAAA;YACD,MAAM,OAAO,GAAG,IAAA,2BAAY,EAAC,SAAS,EAAE,OAAO,EAAE,SAAS,CAAC,CAAA;YAE3D,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE;gBAC3B,aAAM,CAAC,IAAI,CAAC,wDAAwD,KAAK,CAAC,CAAC,CAAC,cAAc,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;gBACrG,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,uBAAuB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAA;gBAClF,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE;oBACrB,MAAM,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAA;iBAChC;gBACD,MAAM,IAAI,CAAC,mBAAmB,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;aACpE;YACD,aAAM,CAAC,IAAI,CAAC,0CAA0C,CAAC,CAAA;SACxD;QAAC,OAAO,GAAG,EAAE;YACZ,MAAM,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAA;SAC9B;IACH,CAAC;IAEO,aAAa,GAAG,KAAK,EAAE,GAAG,EAAE,EAAE;QACpC,aAAM,CAAC,IAAI,CAAC,+BAA+B,IAAI,CAAC,IAAI,YAAY,GAAG,EAAE,CAAC,CAAA;QACtE,MAAM,IAAI,CAAC,IAAI,EAAE,CAAA;QACjB,MAAM,IAAA,YAAK,EAAC,IAAI,CAAC,CAAA;QACjB,aAAM,CAAC,IAAI,CAAC,yBAAyB,IAAI,CAAC,IAAI,eAAe,CAAC,CAAA;QAC9D,IAAI,CAAC,KAAK,EAAE,CAAA;IACd,CAAC,CAAA;IAEM,KAAK,CAAC,IAAI;QACf,IAAI,IAAI,CAAC,WAAW,EAAE;YACpB,MAAM,IAAI,CAAC,WAAW,EAAE,CAAA;SACzB;QACD,IAAI,IAAI,CAAC,kBAAkB,EAAE;YAC3B,aAAa,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAA;SACvC;IACH,CAAC;CACF;AA3GD,0DA2GC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { JSONObjectType } from '@pjts/infra';
|
|
2
|
+
interface NetworkSettingsData {
|
|
3
|
+
number: number;
|
|
4
|
+
rpcUrl: string;
|
|
5
|
+
blocksInterval?: number;
|
|
6
|
+
confirmedBlockCount?: number;
|
|
7
|
+
pendingBlockCount?: number;
|
|
8
|
+
batchProcessingLimit?: number;
|
|
9
|
+
initialBlockNumber?: number;
|
|
10
|
+
isEphemeral?: boolean;
|
|
11
|
+
}
|
|
12
|
+
export declare class NetworkSettings {
|
|
13
|
+
readonly number: number;
|
|
14
|
+
readonly rpcUrl: string;
|
|
15
|
+
readonly confirmedBlockCount: number;
|
|
16
|
+
readonly pendingBlockCount: number;
|
|
17
|
+
readonly blocksInterval: number;
|
|
18
|
+
readonly batchProcessingLimit: number;
|
|
19
|
+
readonly initialBlockNumber: number;
|
|
20
|
+
readonly isEphemeral: boolean;
|
|
21
|
+
static fromJson(data: JSONObjectType): NetworkSettings;
|
|
22
|
+
constructor(data: NetworkSettingsData);
|
|
23
|
+
}
|
|
24
|
+
export {};
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var NetworkSettings_1;
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.NetworkSettings = void 0;
|
|
5
|
+
const tslib_1 = require("tslib");
|
|
6
|
+
const core_1 = require("@pjts/core");
|
|
7
|
+
const class_validator_1 = require("class-validator");
|
|
8
|
+
let NetworkSettings = NetworkSettings_1 = class NetworkSettings {
|
|
9
|
+
number;
|
|
10
|
+
rpcUrl;
|
|
11
|
+
confirmedBlockCount;
|
|
12
|
+
pendingBlockCount;
|
|
13
|
+
blocksInterval;
|
|
14
|
+
batchProcessingLimit;
|
|
15
|
+
initialBlockNumber;
|
|
16
|
+
isEphemeral;
|
|
17
|
+
static fromJson(data) {
|
|
18
|
+
return new NetworkSettings_1({
|
|
19
|
+
number: Number(data.number),
|
|
20
|
+
rpcUrl: String(data.rpcUrl),
|
|
21
|
+
blocksInterval: Number(data.blocksInterval),
|
|
22
|
+
confirmedBlockCount: Number(data.confirmedBlockCount),
|
|
23
|
+
pendingBlockCount: Number(data.pendingBlockCount),
|
|
24
|
+
batchProcessingLimit: Number(data.batchProcessingLimit),
|
|
25
|
+
initialBlockNumber: Number(data.initialBlockNumber),
|
|
26
|
+
isEphemeral: data.isEphemeral === 'true',
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
constructor(data) {
|
|
30
|
+
this.number = data.number;
|
|
31
|
+
this.rpcUrl = data.rpcUrl;
|
|
32
|
+
this.confirmedBlockCount = data.confirmedBlockCount || 30;
|
|
33
|
+
this.pendingBlockCount = data.pendingBlockCount || 2;
|
|
34
|
+
this.blocksInterval = data.blocksInterval || 1000 * 3;
|
|
35
|
+
this.batchProcessingLimit = data.batchProcessingLimit || 50;
|
|
36
|
+
this.isEphemeral = data.isEphemeral || false;
|
|
37
|
+
this.initialBlockNumber = data.initialBlockNumber || 0;
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
tslib_1.__decorate([
|
|
41
|
+
(0, class_validator_1.IsInt)(),
|
|
42
|
+
tslib_1.__metadata("design:type", Number)
|
|
43
|
+
], NetworkSettings.prototype, "number", void 0);
|
|
44
|
+
tslib_1.__decorate([
|
|
45
|
+
(0, class_validator_1.IsUrl)(),
|
|
46
|
+
tslib_1.__metadata("design:type", String)
|
|
47
|
+
], NetworkSettings.prototype, "rpcUrl", void 0);
|
|
48
|
+
tslib_1.__decorate([
|
|
49
|
+
(0, class_validator_1.IsInt)(),
|
|
50
|
+
tslib_1.__metadata("design:type", Number)
|
|
51
|
+
], NetworkSettings.prototype, "confirmedBlockCount", void 0);
|
|
52
|
+
tslib_1.__decorate([
|
|
53
|
+
(0, class_validator_1.IsInt)(),
|
|
54
|
+
tslib_1.__metadata("design:type", Number)
|
|
55
|
+
], NetworkSettings.prototype, "pendingBlockCount", void 0);
|
|
56
|
+
tslib_1.__decorate([
|
|
57
|
+
(0, class_validator_1.IsInt)(),
|
|
58
|
+
tslib_1.__metadata("design:type", Number)
|
|
59
|
+
], NetworkSettings.prototype, "blocksInterval", void 0);
|
|
60
|
+
tslib_1.__decorate([
|
|
61
|
+
(0, class_validator_1.IsInt)(),
|
|
62
|
+
tslib_1.__metadata("design:type", Number)
|
|
63
|
+
], NetworkSettings.prototype, "batchProcessingLimit", void 0);
|
|
64
|
+
tslib_1.__decorate([
|
|
65
|
+
(0, class_validator_1.IsInt)(),
|
|
66
|
+
tslib_1.__metadata("design:type", Number)
|
|
67
|
+
], NetworkSettings.prototype, "initialBlockNumber", void 0);
|
|
68
|
+
tslib_1.__decorate([
|
|
69
|
+
(0, class_validator_1.IsBoolean)(),
|
|
70
|
+
tslib_1.__metadata("design:type", Boolean)
|
|
71
|
+
], NetworkSettings.prototype, "isEphemeral", void 0);
|
|
72
|
+
NetworkSettings = NetworkSettings_1 = tslib_1.__decorate([
|
|
73
|
+
core_1.ObjectDomainPrimitive,
|
|
74
|
+
tslib_1.__metadata("design:paramtypes", [Object])
|
|
75
|
+
], NetworkSettings);
|
|
76
|
+
exports.NetworkSettings = NetworkSettings;
|
|
77
|
+
//# sourceMappingURL=NetworkSettings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NetworkSettings.js","sourceRoot":"","sources":["../src/NetworkSettings.ts"],"names":[],"mappings":";;;;;AAAA,qCAAkD;AAElD,qDAAyD;AAclD,IAAM,eAAe,uBAArB,MAAM,eAAe;IAEV,MAAM,CAAQ;IAGd,MAAM,CAAQ;IAGd,mBAAmB,CAAQ;IAG3B,iBAAiB,CAAQ;IAGzB,cAAc,CAAQ;IAGtB,oBAAoB,CAAQ;IAG5B,kBAAkB,CAAQ;IAG1B,WAAW,CAAS;IAE7B,MAAM,CAAC,QAAQ,CAAC,IAAoB;QACzC,OAAO,IAAI,iBAAe,CAAC;YACzB,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;YAC3B,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;YAC3B,cAAc,EAAE,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC;YAC3C,mBAAmB,EAAE,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC;YACrD,iBAAiB,EAAE,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC;YACjD,oBAAoB,EAAE,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC;YACvD,kBAAkB,EAAE,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC;YACnD,WAAW,EAAE,IAAI,CAAC,WAAW,KAAK,MAAM;SACzC,CAAC,CAAA;IACJ,CAAC;IAED,YAAY,IAAyB;QACnC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;QACzB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;QACzB,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC,mBAAmB,IAAI,EAAE,CAAA;QACzD,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,iBAAiB,IAAI,CAAC,CAAA;QACpD,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,cAAc,IAAI,IAAI,GAAG,CAAC,CAAA;QACrD,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC,oBAAoB,IAAI,EAAE,CAAA;QAC3D,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,IAAI,KAAK,CAAA;QAC5C,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC,kBAAkB,IAAI,CAAC,CAAA;IACxD,CAAC;CACF,CAAA;AA/CC;IAAC,IAAA,uBAAK,GAAE;;+CACsB;AAE9B;IAAC,IAAA,uBAAK,GAAE;;+CACsB;AAE9B;IAAC,IAAA,uBAAK,GAAE;;4DACmC;AAE3C;IAAC,IAAA,uBAAK,GAAE;;0DACiC;AAEzC;IAAC,IAAA,uBAAK,GAAE;;uDAC8B;AAEtC;IAAC,IAAA,uBAAK,GAAE;;6DACoC;AAE5C;IAAC,IAAA,uBAAK,GAAE;;2DACkC;AAE1C;IAAC,IAAA,2BAAS,GAAE;;oDACwB;AAvBzB,eAAe;IAD3B,4BAAqB;;GACT,eAAe,CAgD3B;AAhDY,0CAAe"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { JSONArrayType } from '@pjts/infra';
|
|
2
|
+
import { ethers } from 'ethers';
|
|
3
|
+
import { NetworkSettings } from './NetworkSettings';
|
|
4
|
+
import { BlockchainAddress } from './BlockchainAddress';
|
|
5
|
+
export interface SmartContractConfig {
|
|
6
|
+
operatorPrivateKey?: string;
|
|
7
|
+
network: NetworkSettings;
|
|
8
|
+
address: BlockchainAddress;
|
|
9
|
+
abi: JSONArrayType;
|
|
10
|
+
}
|
|
11
|
+
export declare abstract class SmartContractBase {
|
|
12
|
+
protected readonly provider: ethers.JsonRpcProvider;
|
|
13
|
+
protected readonly contract: ethers.Contract;
|
|
14
|
+
constructor(config: SmartContractConfig);
|
|
15
|
+
protected call<T>(func: () => Promise<T>): Promise<T>;
|
|
16
|
+
protected execute(callPromise: any): Promise<void>;
|
|
17
|
+
private handleInsufficientFundsError;
|
|
18
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SmartContractBase = void 0;
|
|
4
|
+
const core_1 = require("@pjts/core");
|
|
5
|
+
const ethers_1 = require("ethers");
|
|
6
|
+
class SmartContractBase {
|
|
7
|
+
provider;
|
|
8
|
+
contract;
|
|
9
|
+
constructor(config) {
|
|
10
|
+
this.provider = new ethers_1.ethers.JsonRpcProvider(config.network.rpcUrl, config.network.number);
|
|
11
|
+
const operatorSigner = config.operatorPrivateKey
|
|
12
|
+
? new ethers_1.ethers.Wallet(config.operatorPrivateKey, this.provider)
|
|
13
|
+
: this.provider;
|
|
14
|
+
this.contract = new ethers_1.ethers.Contract(config.address.getValue(), config.abi, operatorSigner);
|
|
15
|
+
}
|
|
16
|
+
async call(func) {
|
|
17
|
+
try {
|
|
18
|
+
return await func();
|
|
19
|
+
}
|
|
20
|
+
catch (err) {
|
|
21
|
+
this.handleInsufficientFundsError(err);
|
|
22
|
+
if (err.reason) {
|
|
23
|
+
console.log(err);
|
|
24
|
+
throw core_1.AppError.badGateway(err.reason);
|
|
25
|
+
}
|
|
26
|
+
throw err;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
async execute(callPromise) {
|
|
30
|
+
try {
|
|
31
|
+
const tx = await callPromise;
|
|
32
|
+
await tx.wait();
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
35
|
+
this.handleInsufficientFundsError(err);
|
|
36
|
+
if (err.reason) {
|
|
37
|
+
// TODO: Ignore stale requests as they are crashing message handlers?
|
|
38
|
+
if (String(err.reason).toLowerCase().includes('stale request')) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
throw core_1.AppError.badGateway(err.reason);
|
|
42
|
+
}
|
|
43
|
+
throw err;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
handleInsufficientFundsError(err) {
|
|
47
|
+
const message = String(err);
|
|
48
|
+
if (message.includes('insufficient funds for intrinsic transaction cost') ||
|
|
49
|
+
message.includes('insufficient funds for gas')) {
|
|
50
|
+
throw core_1.AppError.badGateway('Nativ operator account is temporarily out of funds for transaction costs. Please try again in a few moments.');
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
exports.SmartContractBase = SmartContractBase;
|
|
55
|
+
//# sourceMappingURL=SmartContractBase.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SmartContractBase.js","sourceRoot":"","sources":["../src/SmartContractBase.ts"],"names":[],"mappings":";;;AAAA,qCAAqC;AAErC,mCAA+B;AAW/B,MAAsB,iBAAiB;IAClB,QAAQ,CAAwB;IAChC,QAAQ,CAAiB;IAE5C,YAAmB,MAA2B;QAC5C,IAAI,CAAC,QAAQ,GAAG,IAAI,eAAM,CAAC,eAAe,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;QACxF,MAAM,cAAc,GAAG,MAAM,CAAC,kBAAkB;YAC9C,CAAC,CAAC,IAAI,eAAM,CAAC,MAAM,CAAC,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,QAAQ,CAAC;YAC7D,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAA;QACjB,IAAI,CAAC,QAAQ,GAAG,IAAI,eAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,MAAM,CAAC,GAAG,EAAE,cAAc,CAAC,CAAA;IAC5F,CAAC;IAES,KAAK,CAAC,IAAI,CAAI,IAAsB;QAC5C,IAAI;YACF,OAAO,MAAM,IAAI,EAAE,CAAA;SACpB;QAAC,OAAO,GAAQ,EAAE;YACjB,IAAI,CAAC,4BAA4B,CAAC,GAAG,CAAC,CAAA;YACtC,IAAI,GAAG,CAAC,MAAM,EAAE;gBACd,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;gBAChB,MAAM,eAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;aACtC;YACD,MAAM,GAAG,CAAA;SACV;IACH,CAAC;IAES,KAAK,CAAC,OAAO,CAAC,WAAgB;QACtC,IAAI;YACF,MAAM,EAAE,GAAG,MAAM,WAAW,CAAA;YAC5B,MAAM,EAAE,CAAC,IAAI,EAAE,CAAA;SAChB;QAAC,OAAO,GAAQ,EAAE;YACjB,IAAI,CAAC,4BAA4B,CAAC,GAAG,CAAC,CAAA;YACtC,IAAI,GAAG,CAAC,MAAM,EAAE;gBACd,qEAAqE;gBACrE,IAAI,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE;oBAC9D,OAAM;iBACP;gBACD,MAAM,eAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;aACtC;YACD,MAAM,GAAG,CAAA;SACV;IACH,CAAC;IAEO,4BAA4B,CAAC,GAAQ;QAC3C,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,CAAA;QAC3B,IACE,OAAO,CAAC,QAAQ,CAAC,mDAAmD,CAAC;YACrE,OAAO,CAAC,QAAQ,CAAC,4BAA4B,CAAC,EAC9C;YACA,MAAM,eAAQ,CAAC,UAAU,CACvB,8GAA8G,CAC/G,CAAA;SACF;IACH,CAAC;CACF;AArDD,8CAqDC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const buildBatches: (_from: number, _to: number, size: number) => [number, number][];
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildBatches = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const assert_1 = tslib_1.__importDefault(require("assert"));
|
|
6
|
+
const buildBatches = (_from, _to, size) => {
|
|
7
|
+
const from = Math.max(_from, 1);
|
|
8
|
+
const to = Math.max(_to, 1);
|
|
9
|
+
(0, assert_1.default)(from <= to, '`from` must be lower than `to`');
|
|
10
|
+
(0, assert_1.default)(size > 0, '`size` must be greater than 0');
|
|
11
|
+
const intervals = [from];
|
|
12
|
+
while (intervals[intervals.length - 1] < to) {
|
|
13
|
+
intervals.push(Math.min(intervals[intervals.length - 1] + size, to));
|
|
14
|
+
}
|
|
15
|
+
if (intervals.length == 1) {
|
|
16
|
+
return [[intervals[0], intervals[0]]];
|
|
17
|
+
}
|
|
18
|
+
return intervals.reduce((batches, interval, idx) => {
|
|
19
|
+
const next = intervals[idx + 1];
|
|
20
|
+
if (!next) {
|
|
21
|
+
return batches;
|
|
22
|
+
}
|
|
23
|
+
if (intervals.length - 2 === idx) {
|
|
24
|
+
batches.push([interval, next]);
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
batches.push([interval, next - 1]);
|
|
28
|
+
}
|
|
29
|
+
return batches;
|
|
30
|
+
}, []);
|
|
31
|
+
};
|
|
32
|
+
exports.buildBatches = buildBatches;
|
|
33
|
+
//# sourceMappingURL=buildBatches.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buildBatches.js","sourceRoot":"","sources":["../src/buildBatches.ts"],"names":[],"mappings":";;;;AAAA,4DAA2B;AAEpB,MAAM,YAAY,GAAG,CAAC,KAAa,EAAE,GAAW,EAAE,IAAY,EAAsB,EAAE;IAC3F,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAA;IAC/B,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAA;IAC3B,IAAA,gBAAM,EAAC,IAAI,IAAI,EAAE,EAAE,gCAAgC,CAAC,CAAA;IACpD,IAAA,gBAAM,EAAC,IAAI,GAAG,CAAC,EAAE,+BAA+B,CAAC,CAAA;IACjD,MAAM,SAAS,GAAG,CAAC,IAAI,CAAC,CAAA;IACxB,OAAO,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QAC3C,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,CAAC,CAAA;KACrE;IACD,IAAI,SAAS,CAAC,MAAM,IAAI,CAAC,EAAE;QACzB,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;KACtC;IACD,OAAO,SAAS,CAAC,MAAM,CAAC,CAAC,OAA2B,EAAE,QAAgB,EAAE,GAAW,EAAE,EAAE;QACrF,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,GAAG,CAAC,CAAC,CAAA;QAC/B,IAAI,CAAC,IAAI,EAAE;YACT,OAAO,OAAO,CAAA;SACf;QACD,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,KAAK,GAAG,EAAE;YAChC,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAA;SAC/B;aAAM;YACL,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,CAAA;SACnC;QACD,OAAO,OAAO,CAAA;IAChB,CAAC,EAAE,EAAE,CAAC,CAAA;AACR,CAAC,CAAA;AAxBY,QAAA,YAAY,gBAwBxB"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from './BlockchainAddress';
|
|
2
|
+
export * from './BlockchainEventProvider';
|
|
3
|
+
export * from './BlockchainEventSinkBase';
|
|
4
|
+
export * from './BlockSubscriber';
|
|
5
|
+
export * from './NetworkSettings';
|
|
6
|
+
export * from './interfaces/BlockCursorProviderPort';
|
|
7
|
+
export * from './interfaces/BlockSubscriberPort';
|
|
8
|
+
export * from './interfaces/BlockchainEventReceived';
|
|
9
|
+
export * from './interfaces/BlockchainEventProviderPort';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
tslib_1.__exportStar(require("./BlockchainAddress"), exports);
|
|
5
|
+
tslib_1.__exportStar(require("./BlockchainEventProvider"), exports);
|
|
6
|
+
tslib_1.__exportStar(require("./BlockchainEventSinkBase"), exports);
|
|
7
|
+
tslib_1.__exportStar(require("./BlockSubscriber"), exports);
|
|
8
|
+
tslib_1.__exportStar(require("./NetworkSettings"), exports);
|
|
9
|
+
tslib_1.__exportStar(require("./interfaces/BlockCursorProviderPort"), exports);
|
|
10
|
+
tslib_1.__exportStar(require("./interfaces/BlockSubscriberPort"), exports);
|
|
11
|
+
tslib_1.__exportStar(require("./interfaces/BlockchainEventReceived"), exports);
|
|
12
|
+
tslib_1.__exportStar(require("./interfaces/BlockchainEventProviderPort"), exports);
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,8DAAmC;AACnC,oEAAyC;AACzC,oEAAyC;AACzC,4DAAiC;AACjC,4DAAiC;AACjC,+EAAoD;AACpD,2EAAgD;AAChD,+EAAoD;AACpD,mFAAwD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BlockCursorProviderPort.js","sourceRoot":"","sources":["../../src/interfaces/BlockCursorProviderPort.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BlockSubscriberPort.js","sourceRoot":"","sources":["../../src/interfaces/BlockSubscriberPort.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BlockchainEventProviderPort.js","sourceRoot":"","sources":["../../src/interfaces/BlockchainEventProviderPort.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Message } from '@pjts/infra';
|
|
2
|
+
export type Envelope = {
|
|
3
|
+
[key: string]: string;
|
|
4
|
+
};
|
|
5
|
+
export interface BlockchainEventReceived extends Message {
|
|
6
|
+
name: 'BLOCKCHAIN_EVENT_RECEIVED';
|
|
7
|
+
txHash: string;
|
|
8
|
+
networkId: number;
|
|
9
|
+
contractAddress: string;
|
|
10
|
+
blockNumber: number;
|
|
11
|
+
blockchainEventName: string;
|
|
12
|
+
blockTimestamp: string;
|
|
13
|
+
envelope: Envelope;
|
|
14
|
+
isConfirmed: boolean;
|
|
15
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BlockchainEventReceived.js","sourceRoot":"","sources":["../../src/interfaces/BlockchainEventReceived.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@pjts/web3",
|
|
3
|
+
"version": "0.0.19",
|
|
4
|
+
"description": "Piotr Józefów DDD utility package",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"author": "Piotr Józefów",
|
|
8
|
+
"license": "MIT",
|
|
9
|
+
"engines": {
|
|
10
|
+
"node": "^18.14.0"
|
|
11
|
+
},
|
|
12
|
+
"engineStrict": true,
|
|
13
|
+
"scripts": {
|
|
14
|
+
"lint": "eslint src/ --ext .js,.jsx,.ts,.tsx",
|
|
15
|
+
"test": "NODE_ENV=test jest --coverage=false --verbose",
|
|
16
|
+
"test:watch": "NODE_ENV=test jest --coverage=false --watchAll --testNamePattern=",
|
|
17
|
+
"test:coverage": "npm run test --collectCoverage",
|
|
18
|
+
"build": "rm -rf ./dist && tsc",
|
|
19
|
+
"package": "npm run build && npm publish --access=public",
|
|
20
|
+
"prepare": "npm install @pjts/infra@latest & npm install @pjts/core & npm version patch"
|
|
21
|
+
},
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"@types/jest": "29.5.12",
|
|
24
|
+
"jest": "29.4.2",
|
|
25
|
+
"prettier": "2.8.4",
|
|
26
|
+
"ts-jest": "29.0.5",
|
|
27
|
+
"ts-node": "10.9.1",
|
|
28
|
+
"typescript": "4.9.5"
|
|
29
|
+
},
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"@pjts/core": "^0.0.59",
|
|
32
|
+
"@pjts/infra": "^0.0.81",
|
|
33
|
+
"@types/node": "18.13.0",
|
|
34
|
+
"ethers": "6.13.2"
|
|
35
|
+
},
|
|
36
|
+
"publishConfig": {
|
|
37
|
+
"registry": "https://registry.npmjs.org"
|
|
38
|
+
}
|
|
39
|
+
}
|