@hugomrdias/foxer 0.1.9 → 0.2.1
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/.turbo/turbo-build.log +1 -0
- package/.turbo/turbo-check.log +2 -0
- package/CHANGELOG.md +30 -0
- package/README.md +71 -2
- package/dist/bin/create.d.ts.map +1 -1
- package/dist/bin/create.js +9 -1
- package/dist/bin/create.js.map +1 -1
- package/dist/bin/index.js +0 -0
- package/dist/config/env.d.ts +1 -1
- package/dist/config/env.d.ts.map +1 -1
- package/dist/config/env.js +2 -2
- package/dist/config/env.js.map +1 -1
- package/dist/db/actions/blocks.d.ts +9 -6
- package/dist/db/actions/blocks.d.ts.map +1 -1
- package/dist/db/actions/blocks.js +39 -43
- package/dist/db/actions/blocks.js.map +1 -1
- package/dist/db/client.d.ts +1 -1
- package/dist/db/client.d.ts.map +1 -1
- package/dist/db/client.js +5 -1
- package/dist/db/client.js.map +1 -1
- package/dist/db/column-types.d.ts +2 -2
- package/dist/db/column-types.d.ts.map +1 -1
- package/dist/db/column-types.js +11 -3
- package/dist/db/column-types.js.map +1 -1
- package/dist/db/schema/blocks.d.ts +16 -16
- package/dist/db/schema/index.d.ts +44 -44
- package/dist/db/schema/transactions.d.ts +6 -6
- package/dist/db/schema/transactions.d.ts.map +1 -1
- package/dist/db/schema/transactions.js +3 -1
- package/dist/db/schema/transactions.js.map +1 -1
- package/dist/hooks/registry.d.ts +3 -3
- package/dist/hooks/registry.d.ts.map +1 -1
- package/dist/indexer/backfill.d.ts.map +1 -1
- package/dist/indexer/backfill.js +19 -12
- package/dist/indexer/backfill.js.map +1 -1
- package/dist/indexer/process-block.d.ts +4 -4
- package/dist/indexer/process-block.d.ts.map +1 -1
- package/dist/indexer/process-block.js +4 -29
- package/dist/indexer/process-block.js.map +1 -1
- package/dist/indexer/queue-block.d.ts.map +1 -1
- package/dist/indexer/queue-block.js +19 -1
- package/dist/indexer/queue-block.js.map +1 -1
- package/dist/indexer/reorg.d.ts +2 -2
- package/dist/indexer/reorg.d.ts.map +1 -1
- package/dist/rpc/get-logs.js +1 -1
- package/dist/rpc/get-logs.js.map +1 -1
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +16 -15
- package/src/bin/create.ts +16 -2
- package/src/config/env.ts +2 -2
- package/src/db/actions/blocks.ts +51 -51
- package/src/db/client.ts +5 -1
- package/src/db/column-types.ts +17 -6
- package/src/db/schema/transactions.ts +3 -1
- package/src/hooks/registry.ts +3 -3
- package/src/indexer/backfill.ts +28 -10
- package/src/indexer/process-block.ts +10 -39
- package/src/indexer/queue-block.ts +24 -1
- package/src/indexer/reorg.ts +2 -2
- package/src/rpc/get-logs.ts +1 -1
- package/src/types.ts +2 -0
- package/template/.gitignore.tpl +22 -0
- package/template/biome.json.tpl +87 -0
- package/template/package.json.tpl +5 -5
- package/template/tsconfig.json.tpl +25 -17
- package/template/turbo.json.tpl +1 -1
package/dist/indexer/backfill.js
CHANGED
|
@@ -39,32 +39,39 @@ export async function runBackfill(args) {
|
|
|
39
39
|
batchBlockNumbers.push(blockNumber);
|
|
40
40
|
blockNumber += 1n;
|
|
41
41
|
}
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
42
|
+
const logsByBlock = await getLogsInRange({
|
|
43
|
+
logger,
|
|
44
|
+
client,
|
|
45
|
+
addresses: windowContracts.addresses,
|
|
46
|
+
events: windowContracts.eventAbis,
|
|
47
|
+
fromBlock: cursor,
|
|
48
|
+
toBlock,
|
|
49
|
+
});
|
|
50
|
+
const logsTxsSet = new Set();
|
|
51
|
+
for (const logs of logsByBlock.values()) {
|
|
52
|
+
for (const log of logs) {
|
|
53
|
+
logsTxsSet.add(log.transactionHash);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
const { blocks: blocksByNumber, transactions: transactionsMap } = await getBlocksInRange(logger, db, batchBlockNumbers, client, Array.from(logsTxsSet));
|
|
53
57
|
let blockIndex = 0;
|
|
54
58
|
const endClockBatch = startClock();
|
|
55
59
|
await withTransaction(db, async (tx) => {
|
|
56
60
|
while (blockIndex < batchBlockNumbers.length) {
|
|
57
61
|
const blockNumber = batchBlockNumbers[blockIndex];
|
|
58
62
|
const prefetchedBlock = blocksByNumber.get(blockNumber);
|
|
63
|
+
if (!prefetchedBlock) {
|
|
64
|
+
throw new Error(`Block ${blockNumber} not found`);
|
|
65
|
+
}
|
|
59
66
|
await processBlock({
|
|
60
67
|
logger,
|
|
61
68
|
config,
|
|
62
69
|
db: tx,
|
|
63
70
|
client,
|
|
64
71
|
registry,
|
|
65
|
-
blockNumber,
|
|
66
72
|
logs: logsByBlock.get(blockNumber) ?? [],
|
|
67
73
|
block: prefetchedBlock,
|
|
74
|
+
transactionsMap,
|
|
68
75
|
type: 'backfill',
|
|
69
76
|
contracts: windowContracts,
|
|
70
77
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backfill.js","sourceRoot":"","sources":["../../src/indexer/backfill.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"backfill.js","sourceRoot":"","sources":["../../src/indexer/backfill.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,7 +3,7 @@ import type { FilteredContracts, InternalConfig } from '../config/config.ts';
|
|
|
3
3
|
import type { Database } from '../db/client.ts';
|
|
4
4
|
import type { relations, schema } from '../db/schema/index.ts';
|
|
5
5
|
import type { HookRegistry } from '../hooks/registry.ts';
|
|
6
|
-
import type {
|
|
6
|
+
import type { EncodedBlock, TransactionsMap } from '../types';
|
|
7
7
|
import type { Logger } from '../utils/logger.ts';
|
|
8
8
|
export type ProcessBlockResult = {
|
|
9
9
|
status: 'processed';
|
|
@@ -20,9 +20,9 @@ export declare function processBlock(args: {
|
|
|
20
20
|
db: Database<typeof schema, typeof relations>;
|
|
21
21
|
client: PublicClient;
|
|
22
22
|
registry: HookRegistry<NonNullable<unknown>>;
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
logs: Log<bigint, number, false, AbiEvent>[];
|
|
24
|
+
block: EncodedBlock;
|
|
25
|
+
transactionsMap: TransactionsMap;
|
|
26
26
|
type: 'backfill' | 'live';
|
|
27
27
|
contracts: FilteredContracts;
|
|
28
28
|
}): Promise<ProcessBlockResult>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process-block.d.ts","sourceRoot":"","sources":["../../src/indexer/process-block.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,YAAY,EAAE,MAAM,MAAM,CAAA;AAEvD,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAE5E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAC/C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AAE9D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;
|
|
1
|
+
{"version":3,"file":"process-block.d.ts","sourceRoot":"","sources":["../../src/indexer/process-block.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,YAAY,EAAE,MAAM,MAAM,CAAA;AAEvD,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAE5E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAC/C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AAE9D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAC7D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAGhD,MAAM,MAAM,kBAAkB,GAC1B;IAAE,MAAM,EAAE,WAAW,CAAA;CAAE,GACvB;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAA;AAEzC;;GAEG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE;IACvC,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,cAAc,CAAA;IACtB,EAAE,EAAE,QAAQ,CAAC,OAAO,MAAM,EAAE,OAAO,SAAS,CAAC,CAAA;IAC7C,MAAM,EAAE,YAAY,CAAA;IACpB,QAAQ,EAAE,YAAY,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAA;IAC5C,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,CAAC,EAAE,CAAA;IAC5C,KAAK,EAAE,YAAY,CAAA;IACnB,eAAe,EAAE,eAAe,CAAA;IAChC,IAAI,EAAE,UAAU,GAAG,MAAM,CAAA;IACzB,SAAS,EAAE,iBAAiB,CAAA;CAC7B,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAmF9B"}
|
|
@@ -1,37 +1,11 @@
|
|
|
1
1
|
import { cacheBlockAndTransactions } from "../db/actions/blocks.js";
|
|
2
2
|
import { withTransaction } from "../db/transaction.js";
|
|
3
|
-
import { safeGetBlock } from "../rpc/get-block.js";
|
|
4
3
|
import { ensureParentContinuity } from "./reorg.js";
|
|
5
4
|
/**
|
|
6
5
|
* Processes one block: continuity check, event writes, and optional cursor update.
|
|
7
6
|
*/
|
|
8
7
|
export async function processBlock(args) {
|
|
9
|
-
const { logger, config, db, client, registry,
|
|
10
|
-
const transactionByHash = new Map();
|
|
11
|
-
let block;
|
|
12
|
-
let logs;
|
|
13
|
-
if (prefetchedBlock) {
|
|
14
|
-
block = prefetchedBlock;
|
|
15
|
-
}
|
|
16
|
-
if (prefetchedLogs) {
|
|
17
|
-
logs = prefetchedLogs;
|
|
18
|
-
}
|
|
19
|
-
if (!block || !logs) {
|
|
20
|
-
const [blockResult, logsResult] = await Promise.all([
|
|
21
|
-
safeGetBlock({ client, blockNumber, db }),
|
|
22
|
-
client.getLogs({
|
|
23
|
-
address: contracts.addresses,
|
|
24
|
-
events: contracts.eventAbis,
|
|
25
|
-
fromBlock: blockNumber,
|
|
26
|
-
toBlock: blockNumber,
|
|
27
|
-
}),
|
|
28
|
-
]);
|
|
29
|
-
block = blockResult;
|
|
30
|
-
logs = logsResult;
|
|
31
|
-
}
|
|
32
|
-
for (const tx of block.transactions) {
|
|
33
|
-
transactionByHash.set(tx.hash, tx);
|
|
34
|
-
}
|
|
8
|
+
const { logger, config, db, client, registry, block, transactionsMap, logs, type, contracts, } = args;
|
|
35
9
|
if (type === 'live') {
|
|
36
10
|
const rewindTo = await ensureParentContinuity({
|
|
37
11
|
logger,
|
|
@@ -47,7 +21,8 @@ export async function processBlock(args) {
|
|
|
47
21
|
if (type === 'live') {
|
|
48
22
|
await cacheBlockAndTransactions({
|
|
49
23
|
db: tx,
|
|
50
|
-
block,
|
|
24
|
+
blocks: [block],
|
|
25
|
+
transactions: Array.from(transactionsMap.values()),
|
|
51
26
|
logger,
|
|
52
27
|
});
|
|
53
28
|
}
|
|
@@ -61,7 +36,7 @@ export async function processBlock(args) {
|
|
|
61
36
|
if (!contracts.eventNames.has(eventName)) {
|
|
62
37
|
continue;
|
|
63
38
|
}
|
|
64
|
-
const transaction =
|
|
39
|
+
const transaction = transactionsMap.get(log.transactionHash);
|
|
65
40
|
if (!transaction) {
|
|
66
41
|
logger.debug({ transactionHash: log.transactionHash }, 'transaction not found in block transaction list');
|
|
67
42
|
continue;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process-block.js","sourceRoot":"","sources":["../../src/indexer/process-block.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAA;AAGnE,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;
|
|
1
|
+
{"version":3,"file":"process-block.js","sourceRoot":"","sources":["../../src/indexer/process-block.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAA;AAGnE,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAItD,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAA;AAMnD;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAWlC;IACC,MAAM,EACJ,MAAM,EACN,MAAM,EACN,EAAE,EACF,MAAM,EACN,QAAQ,EACR,KAAK,EACL,eAAe,EACf,IAAI,EACJ,IAAI,EACJ,SAAS,GACV,GAAG,IAAI,CAAA;IAER,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;QACpB,MAAM,QAAQ,GAAG,MAAM,sBAAsB,CAAC;YAC5C,MAAM;YACN,EAAE;YACF,MAAM;YACN,KAAK;SACN,CAAC,CAAA;QACF,IAAI,QAAQ,IAAI,IAAI,EAAE,CAAC;YACrB,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAA;QACtC,CAAC;IACH,CAAC;IAED,MAAM,KAAK,GAAG,KAAK,EAAE,EAA6C,EAAE,EAAE;QACpE,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;YACpB,MAAM,yBAAyB,CAAC;gBAC9B,EAAE,EAAE,EAAE;gBACN,MAAM,EAAE,CAAC,KAAK,CAAC;gBACf,YAAY,EAAE,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,CAAC;gBAClD,MAAM;aACP,CAAC,CAAA;QACJ,CAAC;QAED,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,MAAM,YAAY,GAAG,SAAS,CAAC,qBAAqB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;YAEjE,IAAI,CAAC,YAAY,EAAE,CAAC;gBAClB,MAAM,CAAC,KAAK,CACV,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,EACxB,gDAAgD,CACjD,CAAA;gBACD,SAAQ;YACV,CAAC;YACD,MAAM,SAAS,GAAG,GAAG,CAAC,SAAS,CAAA;YAE/B,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;gBACzC,SAAQ;YACV,CAAC;YACD,MAAM,WAAW,GAAG,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,eAAe,CAAC,CAAA;YAE5D,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,MAAM,CAAC,KAAK,CACV,EAAE,eAAe,EAAE,GAAG,CAAC,eAAe,EAAE,EAExC,iDAAiD,CAClD,CAAA;gBACD,SAAQ;YACV,CAAC;YACD,MAAM,QAAQ,CAAC,QAAQ,CAAC;gBACtB,GAAG,EAAE,GAAG,YAAY,IAAI,SAAS,EAAW;gBAC5C,IAAI,EAAE,GAAG,CAAC,IAAa;gBACvB,GAAG,EAAE,GAAY;gBACjB,KAAK;gBACL,WAAW;gBACX,OAAO,EAAE;oBACP,EAAE,EAAE,EAAE;oBACN,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;oBAC/B,MAAM;iBACP;aACF,CAAC,CAAA;QACJ,CAAC;IACH,CAAC,CAAA;IAED,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;QACxB,MAAM,KAAK,CAAC,EAAE,CAAC,CAAA;IACjB,CAAC;SAAM,CAAC;QACN,MAAM,eAAe,CAAC,EAAE,EAAE,KAAK,CAAC,CAAA;IAClC,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,CAAA;AAChC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queue-block.d.ts","sourceRoot":"","sources":["../../src/indexer/queue-block.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AAClC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,MAAM,CAAA;AAExC,OAAO,EAAmB,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAC1E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAC/C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AAC9D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;
|
|
1
|
+
{"version":3,"file":"queue-block.d.ts","sourceRoot":"","sources":["../../src/indexer/queue-block.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AAClC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,MAAM,CAAA;AAExC,OAAO,EAAmB,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAC1E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAC/C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AAC9D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAMxD,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,MAAM,CAAA;IACd,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAA;IACpC,MAAM,EAAE,cAAc,CAAA;IACtB,EAAE,EAAE,QAAQ,CAAC,OAAO,MAAM,EAAE,OAAO,SAAS,CAAC,CAAA;IAC7C,MAAM,EAAE,YAAY,CAAA;IACpB,QAAQ,EAAE,YAAY,CAAA;IACtB,SAAS,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CA0EpE"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { filterContracts } from "../config/config.js";
|
|
2
|
+
import { safeGetBlock } from "../rpc/get-block.js";
|
|
2
3
|
import { startClock } from "../utils/timer.js";
|
|
3
4
|
import { processBlock } from "./process-block.js";
|
|
4
5
|
export async function queueBlock(args) {
|
|
@@ -6,15 +7,32 @@ export async function queueBlock(args) {
|
|
|
6
7
|
const endClock = startClock();
|
|
7
8
|
try {
|
|
8
9
|
const contracts = filterContracts(config, blockNumber, blockNumber);
|
|
10
|
+
const [blockResult, logsResult] = await Promise.all([
|
|
11
|
+
safeGetBlock({ client, blockNumber, db }),
|
|
12
|
+
client.getLogs({
|
|
13
|
+
address: contracts.addresses,
|
|
14
|
+
events: contracts.eventAbis,
|
|
15
|
+
fromBlock: blockNumber,
|
|
16
|
+
toBlock: blockNumber,
|
|
17
|
+
}),
|
|
18
|
+
]);
|
|
19
|
+
const { transactions, ..._block } = blockResult;
|
|
20
|
+
const block = _block;
|
|
21
|
+
const transactionsMap = new Map();
|
|
22
|
+
for (const tx of transactions) {
|
|
23
|
+
transactionsMap.set(tx.hash, tx);
|
|
24
|
+
}
|
|
9
25
|
const result = await processBlock({
|
|
10
26
|
logger,
|
|
11
27
|
config,
|
|
12
28
|
db,
|
|
13
29
|
client,
|
|
14
30
|
registry,
|
|
15
|
-
blockNumber,
|
|
16
31
|
type: 'live',
|
|
17
32
|
contracts,
|
|
33
|
+
block,
|
|
34
|
+
transactionsMap,
|
|
35
|
+
logs: logsResult,
|
|
18
36
|
});
|
|
19
37
|
if (result.status === 'reorg') {
|
|
20
38
|
logger.warn({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queue-block.js","sourceRoot":"","sources":["../../src/indexer/queue-block.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAuB,MAAM,qBAAqB,CAAA;AAI1E,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAajD,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAAoB;IACnD,MAAM,EACJ,MAAM,EACN,EAAE,EACF,MAAM,EACN,QAAQ,EACR,WAAW,EACX,MAAM,EACN,QAAQ,EACR,SAAS,GACV,GAAG,IAAI,CAAA;IAER,MAAM,QAAQ,GAAG,UAAU,EAAE,CAAA;IAC7B,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,eAAe,CAAC,MAAM,EAAE,WAAW,EAAE,WAAW,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"queue-block.js","sourceRoot":"","sources":["../../src/indexer/queue-block.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAuB,MAAM,qBAAqB,CAAA;AAI1E,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAElD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAajD,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAAoB;IACnD,MAAM,EACJ,MAAM,EACN,EAAE,EACF,MAAM,EACN,QAAQ,EACR,WAAW,EACX,MAAM,EACN,QAAQ,EACR,SAAS,GACV,GAAG,IAAI,CAAA;IAER,MAAM,QAAQ,GAAG,UAAU,EAAE,CAAA;IAC7B,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,eAAe,CAAC,MAAM,EAAE,WAAW,EAAE,WAAW,CAAC,CAAA;QAEnE,MAAM,CAAC,WAAW,EAAE,UAAU,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YAClD,YAAY,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC;YACzC,MAAM,CAAC,OAAO,CAAC;gBACb,OAAO,EAAE,SAAS,CAAC,SAAS;gBAC5B,MAAM,EAAE,SAAS,CAAC,SAAS;gBAC3B,SAAS,EAAE,WAAW;gBACtB,OAAO,EAAE,WAAW;aACrB,CAAC;SACH,CAAC,CAAA;QAEF,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,EAAE,GAAG,WAAW,CAAA;QAC/C,MAAM,KAAK,GAAiB,MAAM,CAAA;QAClC,MAAM,eAAe,GAAG,IAAI,GAAG,EAAqC,CAAA;QAEpE,KAAK,MAAM,EAAE,IAAI,YAAY,EAAE,CAAC;YAC9B,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;QAClC,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC;YAChC,MAAM;YACN,MAAM;YACN,EAAE;YACF,MAAM;YACN,QAAQ;YACR,IAAI,EAAE,MAAM;YACZ,SAAS;YACT,KAAK;YACL,eAAe;YACf,IAAI,EAAE,UAAU;SACjB,CAAC,CAAA;QAEF,IAAI,MAAM,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;YAC9B,MAAM,CAAC,IAAI,CACT;gBACE,WAAW,EAAE,WAAW,CAAC,QAAQ,EAAE;gBACnC,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE;aACrC,EACD,kDAAkD,CACnD,CAAA;YACD,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;YACzB,OAAM;QACR,CAAC;QAED,MAAM,CAAC,IAAI,CACT;YACE,QAAQ,EAAE,QAAQ,EAAE;YACpB,WAAW,EAAE,WAAW,CAAC,QAAQ,EAAE;YACnC,SAAS;SACV,EACD,sBAAsB,CACvB,CAAA;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,KAAK,CACV,EAAE,KAAK,EAAE,WAAW,EAAE,WAAW,CAAC,QAAQ,EAAE,EAAE,EAC9C,oCAAoC,CACrC,CAAA;QACD,QAAQ,CAAC,WAAW,GAAG,EAAE,CAAC,CAAA;IAC5B,CAAC;AACH,CAAC"}
|
package/dist/indexer/reorg.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { PublicClient } from 'viem';
|
|
2
2
|
import type { Database } from '../db/client.ts';
|
|
3
|
-
import type {
|
|
3
|
+
import type { EncodedBlock } from '../types';
|
|
4
4
|
import type { Logger } from '../utils/logger.ts';
|
|
5
5
|
/**
|
|
6
6
|
* Verifies parent-hash continuity and rolls back divergent canonical rows if needed.
|
|
@@ -10,7 +10,7 @@ export declare function ensureParentContinuity(args: {
|
|
|
10
10
|
logger: Logger;
|
|
11
11
|
db: Database;
|
|
12
12
|
client: PublicClient;
|
|
13
|
-
block:
|
|
13
|
+
block: EncodedBlock;
|
|
14
14
|
}): Promise<bigint | null>;
|
|
15
15
|
/**
|
|
16
16
|
* Validates recent indexed blocks against chain state on startup.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reorg.d.ts","sourceRoot":"","sources":["../../src/indexer/reorg.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,MAAM,CAAA;AAGxC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAE/C,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"reorg.d.ts","sourceRoot":"","sources":["../../src/indexer/reorg.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,MAAM,CAAA;AAGxC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAE/C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAE5C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAGhD;;;GAGG;AACH,wBAAsB,sBAAsB,CAAC,IAAI,EAAE;IACjD,MAAM,EAAE,MAAM,CAAA;IACd,EAAE,EAAE,QAAQ,CAAA;IACZ,MAAM,EAAE,YAAY,CAAA;IACpB,KAAK,EAAE,YAAY,CAAA;CACpB,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA2DzB;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,EAAE;IAC7C,MAAM,EAAE,MAAM,CAAA;IACd,EAAE,EAAE,QAAQ,CAAA;IACZ,MAAM,EAAE,YAAY,CAAA;IACpB,KAAK,EAAE,MAAM,CAAA;CACd,GAAG,OAAO,CAAC,IAAI,CAAC,CAgChB"}
|
package/dist/rpc/get-logs.js
CHANGED
package/dist/rpc/get-logs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-logs.js","sourceRoot":"","sources":["../../src/rpc/get-logs.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAE9C,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAOpC;IACC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,IAAI,CAAA;IAEtE,MAAM,QAAQ,GAAG,UAAU,EAAE,CAAA;IAE7B,MAAM,WAAW,GAAG,IAAI,GAAG,EAAkD,CAAA;IAC7E,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC;QAChC,OAAO,EAAE,SAAS;QAClB,MAAM,EAAE,MAAM;QACd,SAAS,EAAE,SAAS;QACpB,OAAO,EAAE,OAAO;KACjB,CAAC,CAAA;IAEF,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,EAAE,CAAA;QACtD,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACjB,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,OAAO,CAAC,CAAA;IAC3C,CAAC;IACD,MAAM,CAAC,KAAK,CACV;QACE,IAAI,EAAE,
|
|
1
|
+
{"version":3,"file":"get-logs.js","sourceRoot":"","sources":["../../src/rpc/get-logs.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAE9C,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAOpC;IACC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,IAAI,CAAA;IAEtE,MAAM,QAAQ,GAAG,UAAU,EAAE,CAAA;IAE7B,MAAM,WAAW,GAAG,IAAI,GAAG,EAAkD,CAAA;IAC7E,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC;QAChC,OAAO,EAAE,SAAS;QAClB,MAAM,EAAE,MAAM;QACd,SAAS,EAAE,SAAS;QACpB,OAAO,EAAE,OAAO;KACjB,CAAC,CAAA;IAEF,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,EAAE,CAAA;QACtD,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACjB,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,OAAO,CAAC,CAAA;IAC3C,CAAC;IACD,MAAM,CAAC,KAAK,CACV;QACE,IAAI,EAAE,IAAI,CAAC,MAAM;QACjB,QAAQ,EAAE,QAAQ,EAAE;KACrB,EACD,UAAU,CACX,CAAA;IACD,OAAO,WAAW,CAAA;AACpB,CAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -19,4 +19,6 @@ export type EncodedTransaction = Schema['transactions']['$inferInsert'];
|
|
|
19
19
|
export type EncodedBlockWithTransactions = Simplify<EncodedBlock & {
|
|
20
20
|
transactions: EncodedTransaction[];
|
|
21
21
|
}>;
|
|
22
|
+
export type TransactionsMap = Map<`0x${string}`, EncodedTransaction>;
|
|
23
|
+
export type BlocksMap = Map<bigint, EncodedBlock>;
|
|
22
24
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,MAAM,CAAA;AAE9C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAC/C;;GAEG;AACH,MAAM,MAAM,WAAW,CAAC,UAAU,GAAG,OAAO,EAAE,SAAS,GAAG,KAAK,IAC3D;IACE,KAAK,EAAE,SAAS,CAAA;IAChB,MAAM,CAAC,EAAE,SAAS,CAAA;CACnB,GACD;IACE,MAAM,EAAE,UAAU,CAAA;IAClB,KAAK,CAAC,EAAE,SAAS,CAAA;CAClB,CAAA;AAEL,MAAM,MAAM,aAAa,GAAG,WAAW,CAAC,OAAO,CAAC,CAAA;AAEhD,MAAM,MAAM,gBAAgB,GAAG,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,CAAA;AACjE,MAAM,MAAM,UAAU,GAAG,KAAK,CAC5B,MAAM,EACN,IAAI,EACJ,QAAQ,GAAG,MAAM,GAAG,WAAW,EAC/B,gBAAgB,CACjB,CAAA;AACD,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,cAAc,CAAC,CAAA;AAC3D,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC,cAAc,CAAC,CAAA;AACvE,MAAM,MAAM,4BAA4B,GAAG,QAAQ,CACjD,YAAY,GAAG;IACb,YAAY,EAAE,kBAAkB,EAAE,CAAA;CACnC,CACF,CAAA"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,MAAM,CAAA;AAE9C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAC/C;;GAEG;AACH,MAAM,MAAM,WAAW,CAAC,UAAU,GAAG,OAAO,EAAE,SAAS,GAAG,KAAK,IAC3D;IACE,KAAK,EAAE,SAAS,CAAA;IAChB,MAAM,CAAC,EAAE,SAAS,CAAA;CACnB,GACD;IACE,MAAM,EAAE,UAAU,CAAA;IAClB,KAAK,CAAC,EAAE,SAAS,CAAA;CAClB,CAAA;AAEL,MAAM,MAAM,aAAa,GAAG,WAAW,CAAC,OAAO,CAAC,CAAA;AAEhD,MAAM,MAAM,gBAAgB,GAAG,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,CAAA;AACjE,MAAM,MAAM,UAAU,GAAG,KAAK,CAC5B,MAAM,EACN,IAAI,EACJ,QAAQ,GAAG,MAAM,GAAG,WAAW,EAC/B,gBAAgB,CACjB,CAAA;AACD,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,cAAc,CAAC,CAAA;AAC3D,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC,cAAc,CAAC,CAAA;AACvE,MAAM,MAAM,4BAA4B,GAAG,QAAQ,CACjD,YAAY,GAAG;IACb,YAAY,EAAE,kBAAkB,EAAE,CAAA;CACnC,CACF,CAAA;AACD,MAAM,MAAM,eAAe,GAAG,GAAG,CAAC,KAAK,MAAM,EAAE,EAAE,kBAAkB,CAAC,CAAA;AACpE,MAAM,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hugomrdias/foxer",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Foxer is a all-in-one application server for Filecoin.",
|
|
5
5
|
"license": "Apache-2.0 OR MIT",
|
|
6
6
|
"author": "Hugo Dias <hugomrdias@gmail.com>",
|
|
@@ -45,28 +45,25 @@
|
|
|
45
45
|
"access": "public",
|
|
46
46
|
"provenance": true
|
|
47
47
|
},
|
|
48
|
-
"scripts": {
|
|
49
|
-
"check": "tsc --noEmit && biome check .",
|
|
50
|
-
"build": "tsc -b",
|
|
51
|
-
"prepublishOnly": "bun run build"
|
|
52
|
-
},
|
|
53
48
|
"dependencies": {
|
|
54
|
-
"@bluwy/giget-core": "^0.1.
|
|
49
|
+
"@bluwy/giget-core": "^0.1.7",
|
|
55
50
|
"@clack/prompts": "^1.1.0",
|
|
56
|
-
"@electric-sql/pglite": "^0.
|
|
51
|
+
"@electric-sql/pglite": "^0.4.1",
|
|
57
52
|
"@hono/node-server": "^1.19.11",
|
|
58
53
|
"@libpg-query/parser": "^17.6.3",
|
|
59
54
|
"@pgsql/traverse": "^17.2.4",
|
|
60
55
|
"abitype": "^1.2.3",
|
|
61
56
|
"cleye": "^2.3.0",
|
|
62
57
|
"dotenv": "^17.2.3",
|
|
63
|
-
"drizzle-orm": "1.0.0-beta.
|
|
58
|
+
"drizzle-orm": "1.0.0-beta.17-67b1795",
|
|
64
59
|
"exit-hook": "^5.1.0",
|
|
65
|
-
"hono": "^4.12.
|
|
60
|
+
"hono": "^4.12.9",
|
|
66
61
|
"hono-pino": "^0.10.3",
|
|
67
62
|
"http-shutdown": "^1.2.2",
|
|
63
|
+
"iso-base": "^4.3.1",
|
|
68
64
|
"p-queue": "^9.1.0",
|
|
69
65
|
"pg": "^8.20.0",
|
|
66
|
+
"pgserve": "^1.1.6",
|
|
70
67
|
"picocolors": "^1.1.1",
|
|
71
68
|
"pino": "^10.3.1",
|
|
72
69
|
"postgres": "^3.4.8",
|
|
@@ -77,12 +74,16 @@
|
|
|
77
74
|
"devDependencies": {
|
|
78
75
|
"@pgsql/types": "^17.6.2",
|
|
79
76
|
"@types/node": "^25.5.0",
|
|
80
|
-
"@types/pg": "^8.
|
|
81
|
-
"type-fest": "^5.
|
|
77
|
+
"@types/pg": "^8.20.0",
|
|
78
|
+
"type-fest": "^5.5.0",
|
|
82
79
|
"typescript": "^5.9.2"
|
|
83
80
|
},
|
|
84
81
|
"peerDependencies": {
|
|
85
|
-
"hono": ">=4.
|
|
86
|
-
"viem": "2.
|
|
82
|
+
"hono": ">=4.12.9",
|
|
83
|
+
"viem": "2.47.6"
|
|
84
|
+
},
|
|
85
|
+
"scripts": {
|
|
86
|
+
"check": "tsc --noEmit && biome check .",
|
|
87
|
+
"build": "tsc -b"
|
|
87
88
|
}
|
|
88
|
-
}
|
|
89
|
+
}
|
package/src/bin/create.ts
CHANGED
|
@@ -149,6 +149,7 @@ export const create: Command = command(
|
|
|
149
149
|
mkdirSync(root, { recursive: true })
|
|
150
150
|
p.log.step(`Scaffolding project in ${root}...`)
|
|
151
151
|
|
|
152
|
+
// copy package.json
|
|
152
153
|
const pkg = JSON.parse(
|
|
153
154
|
readFileSync(
|
|
154
155
|
resolve(__dirname, `../../template/package.json.tpl`),
|
|
@@ -163,6 +164,7 @@ export const create: Command = command(
|
|
|
163
164
|
`${JSON.stringify(pkg, null, 2)}\n`
|
|
164
165
|
)
|
|
165
166
|
|
|
167
|
+
// copy pnpm-workspace.yaml
|
|
166
168
|
if (pm === 'pnpm') {
|
|
167
169
|
copy(
|
|
168
170
|
resolve(__dirname, `../../template/pnpm-workspace.yaml.tpl`),
|
|
@@ -170,14 +172,26 @@ export const create: Command = command(
|
|
|
170
172
|
)
|
|
171
173
|
}
|
|
172
174
|
|
|
175
|
+
// copy .gitignore
|
|
173
176
|
copy(
|
|
174
|
-
resolve(__dirname, `../../template
|
|
175
|
-
resolve(root, '
|
|
177
|
+
resolve(__dirname, `../../template/.gitignore.tpl`),
|
|
178
|
+
resolve(root, '.gitignore')
|
|
179
|
+
)
|
|
180
|
+
// copy biome.json
|
|
181
|
+
copy(
|
|
182
|
+
resolve(__dirname, `../../template/biome.json.tpl`),
|
|
183
|
+
resolve(root, 'biome.json')
|
|
176
184
|
)
|
|
185
|
+
// copy tsconfig.json
|
|
177
186
|
copy(
|
|
178
187
|
resolve(__dirname, `../../template/tsconfig.json.tpl`),
|
|
179
188
|
resolve(root, 'tsconfig.json')
|
|
180
189
|
)
|
|
190
|
+
// copy turbo.json
|
|
191
|
+
copy(
|
|
192
|
+
resolve(__dirname, `../../template/turbo.json.tpl`),
|
|
193
|
+
resolve(root, 'turbo.json')
|
|
194
|
+
)
|
|
181
195
|
|
|
182
196
|
// copy apps/foc-api
|
|
183
197
|
await downloadTemplate('hugomrdias/foxer/examples/api', {
|
package/src/config/env.ts
CHANGED
|
@@ -17,7 +17,7 @@ const envSchema = z.object({
|
|
|
17
17
|
LOG_MODE: z.enum(['pretty', 'json']).default('pretty'),
|
|
18
18
|
})
|
|
19
19
|
|
|
20
|
-
export function createEnv(
|
|
20
|
+
export function createEnv(_logger: Logger) {
|
|
21
21
|
const parsed = envSchema.safeParse(process.env)
|
|
22
22
|
|
|
23
23
|
if (!parsed.success) {
|
|
@@ -25,6 +25,6 @@ export function createEnv(logger: Logger) {
|
|
|
25
25
|
`Failed to parse environment variables: \n ${z.prettifyError(parsed.error)}`
|
|
26
26
|
)
|
|
27
27
|
}
|
|
28
|
-
logger.debug({ env: parsed.data }, 'env parsed')
|
|
28
|
+
// logger.debug({ env: parsed.data }, 'env parsed')
|
|
29
29
|
return parsed.data
|
|
30
30
|
}
|
package/src/db/actions/blocks.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** biome-ignore-all lint/style/noNonNullAssertion: its ok */
|
|
2
2
|
|
|
3
|
-
import { gte } from 'drizzle-orm'
|
|
3
|
+
import { and, gte, inArray } from 'drizzle-orm'
|
|
4
4
|
import {
|
|
5
5
|
getTableConfig,
|
|
6
6
|
type PgAsyncTransaction,
|
|
@@ -8,14 +8,15 @@ import {
|
|
|
8
8
|
type PgQueryResultHKT,
|
|
9
9
|
type PgTable,
|
|
10
10
|
} from 'drizzle-orm/pg-core'
|
|
11
|
-
import type { PublicClient } from 'viem'
|
|
11
|
+
import type { Hash, PublicClient } from 'viem'
|
|
12
12
|
|
|
13
|
-
import type { FilteredContracts } from '../../config/config.ts'
|
|
14
13
|
import { MAX_QUERY_PARAMS } from '../../contants.ts'
|
|
15
14
|
import { safeGetBlock } from '../../rpc/get-block.ts'
|
|
16
15
|
import type {
|
|
17
|
-
|
|
16
|
+
BlocksMap,
|
|
17
|
+
EncodedBlock,
|
|
18
18
|
EncodedTransaction,
|
|
19
|
+
TransactionsMap,
|
|
19
20
|
} from '../../types.ts'
|
|
20
21
|
import type { Logger } from '../../utils/logger.ts'
|
|
21
22
|
import { startClock } from '../../utils/timer.ts'
|
|
@@ -73,19 +74,20 @@ function getTablesWithBlockNumberColumn(fullSchema: Record<string, unknown>) {
|
|
|
73
74
|
*/
|
|
74
75
|
export async function cacheBlockAndTransactions(args: {
|
|
75
76
|
db: Database<typeof schema, typeof relations>
|
|
76
|
-
|
|
77
|
+
blocks: EncodedBlock[]
|
|
78
|
+
transactions: EncodedTransaction[]
|
|
77
79
|
logger: Logger
|
|
78
80
|
}): Promise<void> {
|
|
79
|
-
const { db,
|
|
81
|
+
const { db, blocks, transactions } = args
|
|
80
82
|
|
|
81
83
|
await db.transaction(async (tx) => {
|
|
82
84
|
await insertBlocksInChunks({
|
|
83
85
|
db: tx,
|
|
84
|
-
blocks
|
|
86
|
+
blocks,
|
|
85
87
|
})
|
|
86
88
|
await insertTransactionsInChunks({
|
|
87
89
|
db: tx,
|
|
88
|
-
transactions
|
|
90
|
+
transactions,
|
|
89
91
|
})
|
|
90
92
|
})
|
|
91
93
|
}
|
|
@@ -105,8 +107,8 @@ export async function getBlocksInRange(
|
|
|
105
107
|
db: Database<typeof schema, typeof relations>,
|
|
106
108
|
blockNumbers: bigint[],
|
|
107
109
|
client: PublicClient,
|
|
108
|
-
|
|
109
|
-
): Promise<
|
|
110
|
+
logsTxs: Hash[]
|
|
111
|
+
): Promise<{ blocks: BlocksMap; transactions: TransactionsMap }> {
|
|
110
112
|
const endClock = startClock()
|
|
111
113
|
const firstBlockNumber = blockNumbers[0]!
|
|
112
114
|
const lastBlockNumber = blockNumbers[blockNumbers.length - 1]!
|
|
@@ -117,74 +119,72 @@ export async function getBlocksInRange(
|
|
|
117
119
|
// contractAddresses: contracts.addresses,
|
|
118
120
|
// })
|
|
119
121
|
|
|
120
|
-
const
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
{
|
|
128
|
-
to: {
|
|
129
|
-
in: contracts.addresses,
|
|
130
|
-
},
|
|
131
|
-
},
|
|
132
|
-
],
|
|
133
|
-
},
|
|
122
|
+
const [blocks, txs] = await Promise.all([
|
|
123
|
+
db.query.blocks.findMany({
|
|
124
|
+
where: {
|
|
125
|
+
AND: [
|
|
126
|
+
{ number: { gte: firstBlockNumber } },
|
|
127
|
+
{ number: { lte: lastBlockNumber } },
|
|
128
|
+
],
|
|
134
129
|
},
|
|
135
|
-
},
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
})
|
|
130
|
+
}),
|
|
131
|
+
db
|
|
132
|
+
.select()
|
|
133
|
+
.from(schema.transactions)
|
|
134
|
+
.where(and(inArray(schema.transactions.hash, logsTxs))),
|
|
135
|
+
])
|
|
136
|
+
|
|
137
|
+
const transactionByHash = new Map<`0x${string}`, EncodedTransaction>()
|
|
138
|
+
for (const tx of txs) {
|
|
139
|
+
transactionByHash.set(tx.hash, tx)
|
|
140
|
+
}
|
|
143
141
|
|
|
144
|
-
const blocksByNumber = new Map<bigint,
|
|
142
|
+
const blocksByNumber = new Map<bigint, EncodedBlock>()
|
|
145
143
|
const missing = new Set(blockNumbers)
|
|
146
144
|
|
|
147
|
-
for (const block of
|
|
145
|
+
for (const block of blocks) {
|
|
148
146
|
blocksByNumber.set(block.number, block)
|
|
149
147
|
missing.delete(block.number)
|
|
150
148
|
}
|
|
151
149
|
|
|
152
150
|
const missingBlockNumbers = [...missing]
|
|
153
|
-
const newBlocks:
|
|
151
|
+
const newBlocks: EncodedBlock[] = []
|
|
154
152
|
const newTransactions: EncodedTransaction[] = []
|
|
155
153
|
|
|
156
154
|
await Promise.all(
|
|
157
155
|
missingBlockNumbers.map(async (blockNumber) => {
|
|
158
156
|
const block = await safeGetBlock({ client, blockNumber, db })
|
|
159
|
-
const transactions = block.transactions
|
|
160
157
|
blocksByNumber.set(blockNumber, block)
|
|
161
|
-
|
|
158
|
+
const { transactions, ..._block } = block
|
|
159
|
+
newBlocks.push(_block)
|
|
160
|
+
|
|
162
161
|
if (transactions.length > 0) {
|
|
163
162
|
newTransactions.push(...transactions)
|
|
164
163
|
}
|
|
164
|
+
for (const tx of transactions) {
|
|
165
|
+
transactionByHash.set(tx.hash, tx)
|
|
166
|
+
}
|
|
165
167
|
})
|
|
166
168
|
)
|
|
167
169
|
|
|
168
|
-
await
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
await insertTransactionsInChunks({
|
|
174
|
-
db: tx,
|
|
175
|
-
transactions: newTransactions,
|
|
176
|
-
})
|
|
170
|
+
await cacheBlockAndTransactions({
|
|
171
|
+
db,
|
|
172
|
+
blocks: newBlocks,
|
|
173
|
+
transactions: newTransactions,
|
|
174
|
+
logger,
|
|
177
175
|
})
|
|
178
176
|
|
|
179
177
|
logger.trace(
|
|
180
178
|
{
|
|
181
|
-
blocks:
|
|
182
|
-
|
|
179
|
+
blocks: blocks.length,
|
|
180
|
+
txs: txs.length,
|
|
181
|
+
newBlocks: newBlocks.length,
|
|
182
|
+
newTxs: newTransactions.length,
|
|
183
183
|
duration: endClock(),
|
|
184
184
|
},
|
|
185
|
-
'get blocks'
|
|
185
|
+
'get blocks and txs'
|
|
186
186
|
)
|
|
187
|
-
return blocksByNumber
|
|
187
|
+
return { blocks: blocksByNumber, transactions: transactionByHash }
|
|
188
188
|
}
|
|
189
189
|
|
|
190
190
|
/**
|
|
@@ -192,7 +192,7 @@ export async function getBlocksInRange(
|
|
|
192
192
|
*/
|
|
193
193
|
export async function insertBlocksInChunks(args: {
|
|
194
194
|
db: PgAsyncTransaction<PgQueryResultHKT, typeof schema>
|
|
195
|
-
blocks:
|
|
195
|
+
blocks: EncodedBlock[]
|
|
196
196
|
}): Promise<void> {
|
|
197
197
|
const { db, blocks } = args
|
|
198
198
|
if (blocks.length === 0) return
|
package/src/db/client.ts
CHANGED
|
@@ -84,8 +84,12 @@ export function createDatabase<
|
|
|
84
84
|
// Postgres
|
|
85
85
|
if (driver === 'postgres' && url) {
|
|
86
86
|
const pool = new Pool({
|
|
87
|
-
|
|
87
|
+
application_name: 'foxer',
|
|
88
|
+
connectionTimeoutMillis: 5_000,
|
|
89
|
+
idleTimeoutMillis: 30_000,
|
|
90
|
+
max: 10,
|
|
88
91
|
connectionString: url,
|
|
92
|
+
...options,
|
|
89
93
|
})
|
|
90
94
|
const db = drizzleNodePostgres({
|
|
91
95
|
client: pool,
|