@secondlayer/subgraphs 4.2.1 → 4.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -9
- package/dist/src/index.js +11 -11
- package/dist/src/index.js.map +9 -9
- package/dist/src/runtime/block-processor.js +11 -11
- package/dist/src/runtime/block-processor.js.map +9 -9
- package/dist/src/runtime/catchup.js +11 -11
- package/dist/src/runtime/catchup.js.map +9 -9
- package/dist/src/runtime/context.d.ts +1 -1
- package/dist/src/runtime/context.js.map +1 -1
- package/dist/src/runtime/emitter.d.ts +10 -10
- package/dist/src/runtime/emitter.js +47 -46
- package/dist/src/runtime/emitter.js.map +14 -14
- package/dist/src/runtime/processor.js +19 -19
- package/dist/src/runtime/processor.js.map +13 -13
- package/dist/src/runtime/reindex.js +11 -11
- package/dist/src/runtime/reindex.js.map +9 -9
- package/dist/src/runtime/reorg.d.ts +2 -2
- package/dist/src/runtime/reorg.js +17 -17
- package/dist/src/runtime/reorg.js.map +10 -10
- package/dist/src/runtime/replay.d.ts +6 -6
- package/dist/src/runtime/replay.js +26 -26
- package/dist/src/runtime/replay.js.map +4 -4
- package/dist/src/runtime/runner.d.ts +1 -1
- package/dist/src/service.js +19 -19
- package/dist/src/service.js.map +14 -14
- package/dist/src/testing/index.js.map +1 -1
- package/dist/src/triggers/index.d.ts +2 -2
- package/dist/src/triggers/index.js.map +1 -1
- package/package.json +3 -3
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Database as Database3 } from "@secondlayer/shared/db";
|
|
2
|
-
import {
|
|
2
|
+
import { Webhook } from "@secondlayer/shared/db";
|
|
3
3
|
import { Kysely as Kysely3 } from "kysely";
|
|
4
4
|
import { Block, Event, Transaction } from "@secondlayer/shared/db";
|
|
5
5
|
interface BlockData {
|
|
@@ -26,7 +26,7 @@ interface BlockSource {
|
|
|
26
26
|
}
|
|
27
27
|
interface ReplayInput {
|
|
28
28
|
accountId: string;
|
|
29
|
-
|
|
29
|
+
webhookId: string;
|
|
30
30
|
fromBlock: number;
|
|
31
31
|
toBlock: number;
|
|
32
32
|
/** Force re-delivery by appending a unique suffix to the replay id. */
|
|
@@ -37,9 +37,9 @@ interface ReplayResult {
|
|
|
37
37
|
enqueuedCount: number;
|
|
38
38
|
scannedCount: number;
|
|
39
39
|
}
|
|
40
|
-
declare function
|
|
40
|
+
declare function replayWebhook(input: ReplayInput): Promise<ReplayResult>;
|
|
41
41
|
/**
|
|
42
|
-
* Replay a chain
|
|
42
|
+
* Replay a chain webhook by re-running the pure matcher over a historical
|
|
43
43
|
* canonical block range and emitting fresh apply rows. Unlike subgraph replay
|
|
44
44
|
* there is no processed table to scan — the matcher is range-driven, so we
|
|
45
45
|
* reload canonical blocks off the public Index/Streams clock and re-match.
|
|
@@ -48,7 +48,7 @@ declare function replaySubscription(input: ReplayInput): Promise<ReplayResult>;
|
|
|
48
48
|
* critically — this never advances `trigger_evaluator_state`: replay is
|
|
49
49
|
* historical and must not move the live forward cursor.
|
|
50
50
|
*/
|
|
51
|
-
declare function
|
|
51
|
+
declare function replayChainWebhook(db: Kysely3<Database3>, sub: Webhook, input: ReplayInput, opts?: {
|
|
52
52
|
source?: BlockSource
|
|
53
53
|
}): Promise<ReplayResult>;
|
|
54
|
-
export {
|
|
54
|
+
export { replayWebhook, replayChainWebhook, ReplayResult, ReplayInput };
|
|
@@ -272,7 +272,7 @@ function matchSources(sources, transactions, events, traitContracts = new Map, f
|
|
|
272
272
|
// src/runtime/replay.ts
|
|
273
273
|
import { createHash } from "node:crypto";
|
|
274
274
|
import { getTargetDb } from "@secondlayer/shared/db";
|
|
275
|
-
import {
|
|
275
|
+
import { getWebhook } from "@secondlayer/shared/db/queries/webhooks";
|
|
276
276
|
import { logger as logger2 } from "@secondlayer/shared/logger";
|
|
277
277
|
import { sql } from "kysely";
|
|
278
278
|
|
|
@@ -920,8 +920,8 @@ var SBTC_TRIGGER_TO_TOPIC = {
|
|
|
920
920
|
sbtc_withdrawal_accept: "withdrawal-accept",
|
|
921
921
|
sbtc_withdrawal_reject: "withdrawal-reject"
|
|
922
922
|
};
|
|
923
|
-
function sourceKey(
|
|
924
|
-
return `${
|
|
923
|
+
function sourceKey(webhookId, triggerIndex) {
|
|
924
|
+
return `${webhookId}#${triggerIndex}`;
|
|
925
925
|
}
|
|
926
926
|
function toAmount(v) {
|
|
927
927
|
return v === undefined ? undefined : BigInt(v);
|
|
@@ -950,7 +950,7 @@ function buildSourcesMap(chainSubs) {
|
|
|
950
950
|
const key = sourceKey(sub.id, triggerIndex);
|
|
951
951
|
sources[key] = chainTriggerToFilter(trigger);
|
|
952
952
|
keyMeta.set(key, {
|
|
953
|
-
|
|
953
|
+
webhookId: sub.id,
|
|
954
954
|
triggerIndex,
|
|
955
955
|
triggerType: trigger.type
|
|
956
956
|
});
|
|
@@ -991,8 +991,8 @@ async function buildTraitContracts(chainSubs, asOfBlock, opts) {
|
|
|
991
991
|
function evaluateBlock(block, sources, traitContracts) {
|
|
992
992
|
return matchSources(sources, block.txs, block.events, traitContracts);
|
|
993
993
|
}
|
|
994
|
-
function chainDedupKey(
|
|
995
|
-
const base = `chain:${
|
|
994
|
+
function chainDedupKey(webhookId, txId, eventIndex, blockHash, replayId) {
|
|
995
|
+
const base = `chain:${webhookId}:${txId}:${eventIndex}:${blockHash}`;
|
|
996
996
|
return replayId ? `replay:${replayId}:${base}` : base;
|
|
997
997
|
}
|
|
998
998
|
function applyRow(meta, blockHeight, blockHash, txId, eventIndex, event, replayId) {
|
|
@@ -1006,7 +1006,7 @@ function applyRow(meta, blockHeight, blockHash, txId, eventIndex, event, replayI
|
|
|
1006
1006
|
event
|
|
1007
1007
|
};
|
|
1008
1008
|
return {
|
|
1009
|
-
|
|
1009
|
+
webhook_id: meta.webhookId,
|
|
1010
1010
|
kind: "chain",
|
|
1011
1011
|
subgraph_name: null,
|
|
1012
1012
|
table_name: null,
|
|
@@ -1015,7 +1015,7 @@ function applyRow(meta, blockHeight, blockHash, txId, eventIndex, event, replayI
|
|
|
1015
1015
|
row_pk: { tx_id: txId, event_index: eventIndex },
|
|
1016
1016
|
event_type: `chain.${meta.triggerType}.apply`,
|
|
1017
1017
|
payload,
|
|
1018
|
-
dedup_key: chainDedupKey(meta.
|
|
1018
|
+
dedup_key: chainDedupKey(meta.webhookId, txId, eventIndex, blockHash, replayId),
|
|
1019
1019
|
...replayId ? { is_replay: true } : {}
|
|
1020
1020
|
};
|
|
1021
1021
|
}
|
|
@@ -1051,7 +1051,7 @@ async function emitChainOutbox(db, matches, keyMeta, blockHeight, blockHash, opt
|
|
|
1051
1051
|
}
|
|
1052
1052
|
if (rows.length === 0)
|
|
1053
1053
|
return 0;
|
|
1054
|
-
const result = await db.insertInto("
|
|
1054
|
+
const result = await db.insertInto("webhook_outbox").values(rows).onConflict((oc) => oc.columns(["webhook_id", "dedup_key"]).doNothing()).executeTakeFirst();
|
|
1055
1055
|
return Number(result.numInsertedOrUpdatedRows ?? 0);
|
|
1056
1056
|
}
|
|
1057
1057
|
async function loadSbtcEventsForBlock(db, blockHeight, topics) {
|
|
@@ -1163,7 +1163,7 @@ async function emitSbtcOutbox(db, chainSubs, blockHeight, blockHash, opts) {
|
|
|
1163
1163
|
if (!isSbtcTriggerType(trigger.type))
|
|
1164
1164
|
return;
|
|
1165
1165
|
const meta = {
|
|
1166
|
-
|
|
1166
|
+
webhookId: sub.id,
|
|
1167
1167
|
triggerIndex,
|
|
1168
1168
|
triggerType: trigger.type
|
|
1169
1169
|
};
|
|
@@ -1177,7 +1177,7 @@ async function emitSbtcOutbox(db, chainSubs, blockHeight, blockHash, opts) {
|
|
|
1177
1177
|
}
|
|
1178
1178
|
if (outboxRows.length === 0)
|
|
1179
1179
|
return 0;
|
|
1180
|
-
const result = await db.insertInto("
|
|
1180
|
+
const result = await db.insertInto("webhook_outbox").values(outboxRows).onConflict((oc) => oc.columns(["webhook_id", "dedup_key"]).doNothing()).executeTakeFirst();
|
|
1181
1181
|
return Number(result.numInsertedOrUpdatedRows ?? 0);
|
|
1182
1182
|
}
|
|
1183
1183
|
|
|
@@ -1194,8 +1194,8 @@ function stableStringify(obj) {
|
|
|
1194
1194
|
return acc;
|
|
1195
1195
|
}, {}));
|
|
1196
1196
|
}
|
|
1197
|
-
function deterministicReplayId(
|
|
1198
|
-
const canonical = `${
|
|
1197
|
+
function deterministicReplayId(webhookId, fromBlock, toBlock, suffix) {
|
|
1198
|
+
const canonical = `${webhookId}:${fromBlock}:${toBlock}${suffix ? `:${suffix}` : ""}`;
|
|
1199
1199
|
return createHash("sha256").update(canonical).digest("hex").slice(0, 16);
|
|
1200
1200
|
}
|
|
1201
1201
|
async function resolveSchemaName(db, subgraphName) {
|
|
@@ -1205,7 +1205,7 @@ async function resolveSchemaName(db, subgraphName) {
|
|
|
1205
1205
|
}
|
|
1206
1206
|
return row.schema_name ?? pgSchemaName(subgraphName);
|
|
1207
1207
|
}
|
|
1208
|
-
async function
|
|
1208
|
+
async function replayWebhook(input) {
|
|
1209
1209
|
if (input.fromBlock > input.toBlock) {
|
|
1210
1210
|
throw new Error("fromBlock must be <= toBlock");
|
|
1211
1211
|
}
|
|
@@ -1213,16 +1213,16 @@ async function replaySubscription(input) {
|
|
|
1213
1213
|
throw new Error("replay range exceeds 100k blocks");
|
|
1214
1214
|
}
|
|
1215
1215
|
const db = getTargetDb();
|
|
1216
|
-
const sub = await
|
|
1216
|
+
const sub = await getWebhook(db, input.accountId, input.webhookId);
|
|
1217
1217
|
if (!sub)
|
|
1218
|
-
throw new Error("
|
|
1218
|
+
throw new Error("Webhook not found");
|
|
1219
1219
|
if (sub.kind === "chain") {
|
|
1220
|
-
return
|
|
1220
|
+
return replayChainWebhook(db, sub, input);
|
|
1221
1221
|
}
|
|
1222
1222
|
const subgraphName = sub.subgraph_name;
|
|
1223
1223
|
const tableName = sub.table_name;
|
|
1224
1224
|
if (sub.kind !== "subgraph" || !subgraphName || !tableName) {
|
|
1225
|
-
throw new Error("replay is only supported for subgraph or chain
|
|
1225
|
+
throw new Error("replay is only supported for subgraph or chain webhooks");
|
|
1226
1226
|
}
|
|
1227
1227
|
const schema = await resolveSchemaName(db, subgraphName);
|
|
1228
1228
|
const replayId = deterministicReplayId(sub.id, input.fromBlock, input.toBlock, input.replayIdSuffix);
|
|
@@ -1240,7 +1240,7 @@ async function replaySubscription(input) {
|
|
|
1240
1240
|
break;
|
|
1241
1241
|
scanned += rows.length;
|
|
1242
1242
|
const inserts = rows.map((row) => ({
|
|
1243
|
-
|
|
1243
|
+
webhook_id: sub.id,
|
|
1244
1244
|
subgraph_name: subgraphName,
|
|
1245
1245
|
table_name: tableName,
|
|
1246
1246
|
block_height: Number(row._block_height),
|
|
@@ -1255,14 +1255,14 @@ async function replaySubscription(input) {
|
|
|
1255
1255
|
dedup_key: replayDedupKey(subgraphName, tableName, row, replayId),
|
|
1256
1256
|
is_replay: true
|
|
1257
1257
|
}));
|
|
1258
|
-
const result = await db.insertInto("
|
|
1258
|
+
const result = await db.insertInto("webhook_outbox").values(inserts).onConflict((oc) => oc.columns(["webhook_id", "dedup_key"]).doNothing()).executeTakeFirst();
|
|
1259
1259
|
enqueued += Number(result.numInsertedOrUpdatedRows ?? 0);
|
|
1260
1260
|
lastId = BigInt(String(rows[rows.length - 1]?._id));
|
|
1261
1261
|
if (rows.length < BATCH_SIZE)
|
|
1262
1262
|
break;
|
|
1263
1263
|
}
|
|
1264
1264
|
logger2.info("Replay enqueued", {
|
|
1265
|
-
|
|
1265
|
+
webhook: sub.name,
|
|
1266
1266
|
replayId,
|
|
1267
1267
|
scanned,
|
|
1268
1268
|
enqueued,
|
|
@@ -1272,7 +1272,7 @@ async function replaySubscription(input) {
|
|
|
1272
1272
|
return { replayId, enqueuedCount: enqueued, scannedCount: scanned };
|
|
1273
1273
|
}
|
|
1274
1274
|
var CHAIN_REPLAY_BATCH = 200;
|
|
1275
|
-
async function
|
|
1275
|
+
async function replayChainWebhook(db, sub, input, opts) {
|
|
1276
1276
|
const replayId = deterministicReplayId(sub.id, input.fromBlock, input.toBlock, input.replayIdSuffix);
|
|
1277
1277
|
const { sources, keyMeta } = buildSourcesMap([sub]);
|
|
1278
1278
|
const source = opts?.source ?? new PublicApiBlockSource(buildHttpClient(), referencedEventTypes([sub]));
|
|
@@ -1299,7 +1299,7 @@ async function replayChainSubscription(db, sub, input, opts) {
|
|
|
1299
1299
|
}
|
|
1300
1300
|
}
|
|
1301
1301
|
logger2.info("Chain replay enqueued", {
|
|
1302
|
-
|
|
1302
|
+
webhook: sub.name,
|
|
1303
1303
|
replayId,
|
|
1304
1304
|
scanned,
|
|
1305
1305
|
enqueued,
|
|
@@ -1309,9 +1309,9 @@ async function replayChainSubscription(db, sub, input, opts) {
|
|
|
1309
1309
|
return { replayId, enqueuedCount: enqueued, scannedCount: scanned };
|
|
1310
1310
|
}
|
|
1311
1311
|
export {
|
|
1312
|
-
|
|
1313
|
-
|
|
1312
|
+
replayWebhook,
|
|
1313
|
+
replayChainWebhook
|
|
1314
1314
|
};
|
|
1315
1315
|
|
|
1316
|
-
//# debugId=
|
|
1316
|
+
//# debugId=74CC4063BDD4E6F864756E2164756E21
|
|
1317
1317
|
//# sourceMappingURL=replay.js.map
|