@secondlayer/subgraphs 3.4.0 → 3.6.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.
@@ -518,21 +518,21 @@ function buildEventPayload(filter, tx, event) {
518
518
  return {
519
519
  sender: decoded.sender,
520
520
  recipient: decoded.recipient,
521
- tokenId: decoded.value,
521
+ tokenId: decoded.raw_value ?? decoded.value,
522
522
  assetIdentifier: decoded.asset_identifier,
523
523
  tx: txMeta
524
524
  };
525
525
  case "nft_mint":
526
526
  return {
527
527
  recipient: decoded.recipient,
528
- tokenId: decoded.value,
528
+ tokenId: decoded.raw_value ?? decoded.value,
529
529
  assetIdentifier: decoded.asset_identifier,
530
530
  tx: txMeta
531
531
  };
532
532
  case "nft_burn":
533
533
  return {
534
534
  sender: decoded.sender,
535
- tokenId: decoded.value,
535
+ tokenId: decoded.raw_value ?? decoded.value,
536
536
  assetIdentifier: decoded.asset_identifier,
537
537
  tx: txMeta
538
538
  };
@@ -564,8 +564,8 @@ function buildEventPayload(filter, tx, event) {
564
564
  tx: txMeta
565
565
  };
566
566
  case "print_event": {
567
- const decodedRawValue = decoded.raw_value;
568
- const rawValue = decodedRawValue && typeof decodedRawValue === "object" && !Array.isArray(decodedRawValue) ? decodedRawValue : decoded.value;
567
+ const rawHex = event.data?.raw_value;
568
+ const rawValue = typeof rawHex === "string" && rawHex.startsWith("0x") ? decodeClarityValue(rawHex) : decoded.value;
569
569
  const clarityObj = rawValue && typeof rawValue === "object" && !Array.isArray(rawValue) ? rawValue : null;
570
570
  const topic = clarityObj?.topic ? String(clarityObj.topic) : decoded.topic ?? "";
571
571
  const { topic: _, ...rest } = clarityObj ?? {};
@@ -949,10 +949,7 @@ function matchSources(sources, transactions, events, traitContracts = new Map) {
949
949
  }
950
950
 
951
951
  // src/runtime/block-processor.ts
952
- import {
953
- getSourceDb,
954
- getTargetDb
955
- } from "@secondlayer/shared/db";
952
+ import { getTargetDb } from "@secondlayer/shared/db";
956
953
  import { resolveTraitContractIds } from "@secondlayer/shared/db/queries/contracts";
957
954
  import {
958
955
  isByoSubgraph,
@@ -960,15 +957,287 @@ import {
960
957
  resolveSubgraphDb,
961
958
  updateSubgraphStatus
962
959
  } from "@secondlayer/shared/db/queries/subgraphs";
963
- import { logger as logger4 } from "@secondlayer/shared/logger";
960
+ import { logger as logger5 } from "@secondlayer/shared/logger";
964
961
  import { sql as sql3 } from "kysely";
965
962
 
966
963
  // src/schema/utils.ts
967
964
  import { pgSchemaName } from "@secondlayer/shared/db/queries/subgraphs";
968
965
 
966
+ // src/runtime/block-source.ts
967
+ import { getSourceDb } from "@secondlayer/shared/db";
968
+ import { IndexHttpClient } from "@secondlayer/shared/index-http";
969
+ import { logger as logger3 } from "@secondlayer/shared/logger";
970
+
971
+ // src/runtime/batch-loader.ts
972
+ async function loadBlockRange(db, fromHeight, toHeight) {
973
+ const [blocks, txs, events] = await Promise.all([
974
+ db.selectFrom("blocks").selectAll().where("height", ">=", fromHeight).where("height", "<=", toHeight).where("canonical", "=", true).execute(),
975
+ db.selectFrom("transactions").selectAll().where("block_height", ">=", fromHeight).where("block_height", "<=", toHeight).execute(),
976
+ db.selectFrom("events").selectAll().where("block_height", ">=", fromHeight).where("block_height", "<=", toHeight).execute()
977
+ ]);
978
+ const txsByHeight = new Map;
979
+ for (const tx of txs) {
980
+ const h = Number(tx.block_height);
981
+ const list = txsByHeight.get(h) ?? [];
982
+ list.push(tx);
983
+ txsByHeight.set(h, list);
984
+ }
985
+ const eventsByHeight = new Map;
986
+ for (const evt of events) {
987
+ const h = Number(evt.block_height);
988
+ const list = eventsByHeight.get(h) ?? [];
989
+ list.push(evt);
990
+ eventsByHeight.set(h, list);
991
+ }
992
+ const result = new Map;
993
+ for (const block of blocks) {
994
+ const h = Number(block.height);
995
+ result.set(h, {
996
+ block,
997
+ txs: txsByHeight.get(h) ?? [],
998
+ events: eventsByHeight.get(h) ?? []
999
+ });
1000
+ }
1001
+ return result;
1002
+ }
1003
+ function avgEventsPerBlock(batch) {
1004
+ if (batch.size === 0)
1005
+ return 0;
1006
+ let totalEvents = 0;
1007
+ for (const data of batch.values()) {
1008
+ totalEvents += data.events.length;
1009
+ }
1010
+ return totalEvents / batch.size;
1011
+ }
1012
+
1013
+ // src/runtime/reconstruct.ts
1014
+ function isoToUnixSeconds(iso) {
1015
+ if (!iso)
1016
+ return 0;
1017
+ return Math.floor(new Date(iso).getTime() / 1000);
1018
+ }
1019
+ function reconstructBlock(b) {
1020
+ return {
1021
+ height: b.block_height,
1022
+ hash: b.block_hash,
1023
+ parent_hash: b.parent_hash,
1024
+ burn_block_height: b.burn_block_height,
1025
+ burn_block_hash: b.burn_block_hash,
1026
+ timestamp: isoToUnixSeconds(b.block_time),
1027
+ canonical: true,
1028
+ created_at: new Date(0)
1029
+ };
1030
+ }
1031
+ function reconstructTransaction(t) {
1032
+ return {
1033
+ tx_id: t.tx_id,
1034
+ block_height: t.block_height,
1035
+ tx_index: t.tx_index,
1036
+ type: t.tx_type,
1037
+ sender: t.sender,
1038
+ status: t.status,
1039
+ contract_id: t.contract_call?.contract_id ?? t.smart_contract?.contract_id ?? null,
1040
+ function_name: t.contract_call?.function_name ?? null,
1041
+ function_args: t.contract_call?.function_args_hex ?? [],
1042
+ raw_result: t.contract_call?.result_hex ?? null,
1043
+ raw_tx: "",
1044
+ created_at: new Date(0)
1045
+ };
1046
+ }
1047
+ function reconstructEvent(e) {
1048
+ const base = {
1049
+ id: `${e.tx_id}#${e.event_index}`,
1050
+ tx_id: e.tx_id,
1051
+ block_height: e.block_height,
1052
+ event_index: e.event_index,
1053
+ created_at: new Date(0)
1054
+ };
1055
+ switch (e.event_type) {
1056
+ case "ft_transfer":
1057
+ case "ft_mint":
1058
+ case "ft_burn":
1059
+ return {
1060
+ ...base,
1061
+ type: `${e.event_type}_event`,
1062
+ data: {
1063
+ asset_identifier: e.asset_identifier,
1064
+ sender: e.sender,
1065
+ recipient: e.recipient,
1066
+ amount: e.amount
1067
+ }
1068
+ };
1069
+ case "nft_transfer":
1070
+ case "nft_mint":
1071
+ case "nft_burn":
1072
+ return {
1073
+ ...base,
1074
+ type: `${e.event_type}_event`,
1075
+ data: {
1076
+ asset_identifier: e.asset_identifier,
1077
+ sender: e.sender,
1078
+ recipient: e.recipient,
1079
+ raw_value: e.value
1080
+ }
1081
+ };
1082
+ case "stx_transfer":
1083
+ case "stx_mint":
1084
+ case "stx_burn":
1085
+ return {
1086
+ ...base,
1087
+ type: `${e.event_type}_event`,
1088
+ data: {
1089
+ sender: e.sender,
1090
+ recipient: e.recipient,
1091
+ amount: e.amount,
1092
+ ..."memo" in e ? { memo: e.memo ?? undefined } : {}
1093
+ }
1094
+ };
1095
+ case "stx_lock":
1096
+ return {
1097
+ ...base,
1098
+ type: "stx_lock_event",
1099
+ data: {
1100
+ locked_address: e.sender,
1101
+ locked_amount: e.amount,
1102
+ unlock_height: e.payload.unlock_height
1103
+ }
1104
+ };
1105
+ case "print":
1106
+ return {
1107
+ ...base,
1108
+ type: "contract_event",
1109
+ data: {
1110
+ topic: e.payload.topic,
1111
+ contract_id: e.contract_id,
1112
+ contract_identifier: e.contract_id,
1113
+ value: e.payload.value,
1114
+ raw_value: e.payload.raw_value
1115
+ }
1116
+ };
1117
+ }
1118
+ }
1119
+
1120
+ // src/runtime/block-source.ts
1121
+ class PostgresBlockSource {
1122
+ async getTip() {
1123
+ const progress = await getSourceDb().selectFrom("index_progress").selectAll().where("network", "=", process.env.NETWORK ?? "mainnet").executeTakeFirst();
1124
+ return progress ? Number(progress.highest_seen_block) : 0;
1125
+ }
1126
+ loadBlockRange(fromHeight, toHeight) {
1127
+ return loadBlockRange(getSourceDb(), fromHeight, toHeight);
1128
+ }
1129
+ }
1130
+ var EVENT_FILTER_TO_INDEX_TYPE = {
1131
+ stx_transfer: "stx_transfer",
1132
+ stx_mint: "stx_mint",
1133
+ stx_burn: "stx_burn",
1134
+ stx_lock: "stx_lock",
1135
+ ft_transfer: "ft_transfer",
1136
+ ft_mint: "ft_mint",
1137
+ ft_burn: "ft_burn",
1138
+ nft_transfer: "nft_transfer",
1139
+ nft_mint: "nft_mint",
1140
+ nft_burn: "nft_burn",
1141
+ print_event: "print"
1142
+ };
1143
+ var TX_SOURCE_TYPES = new Set(["contract_call", "contract_deploy"]);
1144
+ var ALL_INDEX_EVENT_TYPES = [
1145
+ ...new Set(Object.values(EVENT_FILTER_TO_INDEX_TYPE))
1146
+ ];
1147
+ function sourceFilters(subgraph) {
1148
+ const sources = subgraph.sources;
1149
+ return Array.isArray(sources) ? sources : Object.values(sources);
1150
+ }
1151
+ function referencedIndexEventTypes(subgraph) {
1152
+ const filters = sourceFilters(subgraph);
1153
+ if (filters.some((f) => TX_SOURCE_TYPES.has(f.type))) {
1154
+ return ALL_INDEX_EVENT_TYPES;
1155
+ }
1156
+ const types = new Set;
1157
+ for (const f of filters) {
1158
+ const t = EVENT_FILTER_TO_INDEX_TYPE[f.type];
1159
+ if (t)
1160
+ types.add(t);
1161
+ }
1162
+ return [...types];
1163
+ }
1164
+ function isStreamsIndexEligible(subgraph) {
1165
+ if (Array.isArray(subgraph.sources))
1166
+ return false;
1167
+ const filters = sourceFilters(subgraph);
1168
+ if (filters.length === 0)
1169
+ return false;
1170
+ for (const f of filters) {
1171
+ const known = EVENT_FILTER_TO_INDEX_TYPE[f.type] || TX_SOURCE_TYPES.has(f.type);
1172
+ if (!known)
1173
+ return false;
1174
+ }
1175
+ return true;
1176
+ }
1177
+
1178
+ class PublicApiBlockSource {
1179
+ http;
1180
+ eventTypes;
1181
+ constructor(http, eventTypes) {
1182
+ this.http = http;
1183
+ this.eventTypes = eventTypes;
1184
+ }
1185
+ getTip() {
1186
+ return this.http.getIndexTip();
1187
+ }
1188
+ async loadBlockRange(fromHeight, toHeight) {
1189
+ const [blocks, txs, eventLists] = await Promise.all([
1190
+ this.http.walkBlocks(fromHeight, toHeight),
1191
+ this.http.walkTransactions(fromHeight, toHeight),
1192
+ Promise.all(this.eventTypes.map((t) => this.http.walkEvents(t, fromHeight, toHeight)))
1193
+ ]);
1194
+ const map = new Map;
1195
+ for (const b of blocks) {
1196
+ map.set(b.block_height, {
1197
+ block: reconstructBlock(b),
1198
+ txs: [],
1199
+ events: []
1200
+ });
1201
+ }
1202
+ for (const t of txs) {
1203
+ map.get(t.block_height)?.txs.push(reconstructTransaction(t));
1204
+ }
1205
+ for (const list of eventLists) {
1206
+ for (const e of list) {
1207
+ map.get(e.block_height)?.events.push(reconstructEvent(e));
1208
+ }
1209
+ }
1210
+ for (const bd of map.values()) {
1211
+ bd.txs.sort((a, b) => a.tx_index - b.tx_index);
1212
+ bd.events.sort((a, b) => a.event_index - b.event_index);
1213
+ }
1214
+ return map;
1215
+ }
1216
+ }
1217
+ var postgresBlockSource = new PostgresBlockSource;
1218
+ function buildHttpClient() {
1219
+ const baseUrl = process.env.SUBGRAPH_INDEX_API_URL ?? process.env.STREAMS_API_URL ?? "http://api:3800";
1220
+ return new IndexHttpClient({
1221
+ indexBaseUrl: baseUrl,
1222
+ streamsBaseUrl: baseUrl,
1223
+ streamsApiKey: process.env.STREAMS_INTERNAL_API_KEY ?? "sk-sl_streams_l2_internal"
1224
+ });
1225
+ }
1226
+ function resolveBlockSource(subgraph) {
1227
+ if (process.env.SUBGRAPH_SOURCE === "streams-index" && subgraph && isStreamsIndexEligible(subgraph)) {
1228
+ return new PublicApiBlockSource(buildHttpClient(), referencedIndexEventTypes(subgraph));
1229
+ }
1230
+ if (process.env.SUBGRAPH_SOURCE === "streams-index" && subgraph) {
1231
+ logger3.debug("Subgraph not streams-index eligible, using DB tap", {
1232
+ subgraph: subgraph.name
1233
+ });
1234
+ }
1235
+ return postgresBlockSource;
1236
+ }
1237
+
969
1238
  // src/runtime/outbox-emit.ts
970
1239
  import { createHash } from "node:crypto";
971
- import { logger as logger3 } from "@secondlayer/shared/logger";
1240
+ import { logger as logger4 } from "@secondlayer/shared/logger";
972
1241
  var loggedKillSwitch = false;
973
1242
  function isEmitOutboxEnabled() {
974
1243
  return process.env.SECONDLAYER_EMIT_OUTBOX !== "false";
@@ -987,7 +1256,7 @@ function stableStringify(obj) {
987
1256
  async function emitSubscriptionOutbox(tx, subgraphName, manifest, matcher, blockHeight) {
988
1257
  if (!isEmitOutboxEnabled()) {
989
1258
  if (!loggedKillSwitch) {
990
- logger3.warn("SECONDLAYER_EMIT_OUTBOX=false — outbox emission bypassed");
1259
+ logger4.warn("SECONDLAYER_EMIT_OUTBOX=false — outbox emission bypassed");
991
1260
  loggedKillSwitch = true;
992
1261
  }
993
1262
  return 0;
@@ -1228,7 +1497,6 @@ async function resolveTraitContracts(subgraph, blockHeight, db) {
1228
1497
  return resolved;
1229
1498
  }
1230
1499
  async function processBlock(subgraph, subgraphName, blockHeight, opts) {
1231
- const sourceDb = getSourceDb();
1232
1500
  const targetDb = getTargetDb();
1233
1501
  const blockStart = performance.now();
1234
1502
  const result = {
@@ -1246,25 +1514,18 @@ async function processBlock(subgraph, subgraphName, blockHeight, opts) {
1246
1514
  txs = opts.preloaded.txs;
1247
1515
  evts = opts.preloaded.events;
1248
1516
  } else {
1249
- block = await sourceDb.selectFrom("blocks").selectAll().where("height", "=", blockHeight).executeTakeFirst();
1250
- if (!block) {
1251
- logger4.warn("Block not found for subgraph processing", {
1252
- subgraph: subgraphName,
1253
- blockHeight
1254
- });
1255
- result.skipped = true;
1256
- return result;
1257
- }
1258
- if (!block.canonical) {
1259
- logger4.debug("Skipping non-canonical block", {
1517
+ const data = (await resolveBlockSource(subgraph).loadBlockRange(blockHeight, blockHeight)).get(blockHeight);
1518
+ if (!data) {
1519
+ logger5.debug("Block not found or non-canonical for subgraph processing", {
1260
1520
  subgraph: subgraphName,
1261
1521
  blockHeight
1262
1522
  });
1263
1523
  result.skipped = true;
1264
1524
  return result;
1265
1525
  }
1266
- txs = await sourceDb.selectFrom("transactions").selectAll().where("block_height", "=", blockHeight).execute();
1267
- evts = await sourceDb.selectFrom("events").selectAll().where("block_height", "=", blockHeight).execute();
1526
+ block = data.block;
1527
+ txs = data.txs;
1528
+ evts = data.events;
1268
1529
  }
1269
1530
  const traitContracts = await resolveTraitContracts(subgraph, blockHeight, targetDb);
1270
1531
  const matched = matchSources(subgraph.sources, txs, evts, traitContracts);
@@ -1355,7 +1616,7 @@ async function processBlock(subgraph, subgraphName, blockHeight, opts) {
1355
1616
  const { rows } = await sql3.raw(`SELECT n_live_tup AS count FROM pg_stat_user_tables WHERE schemaname = '${schemaName}' AND relname = '${table}'`).execute(route.dataDb);
1356
1617
  const count = Number(rows[0]?.count ?? 0);
1357
1618
  if (count >= 1e7) {
1358
- logger4.warn("Subgraph table exceeds 10M rows (estimate)", {
1619
+ logger5.warn("Subgraph table exceeds 10M rows (estimate)", {
1359
1620
  subgraph: subgraphName,
1360
1621
  table,
1361
1622
  count
@@ -1363,7 +1624,7 @@ async function processBlock(subgraph, subgraphName, blockHeight, opts) {
1363
1624
  }
1364
1625
  }
1365
1626
  } catch (err) {
1366
- logger4.debug("Row count sample failed", {
1627
+ logger5.debug("Row count sample failed", {
1367
1628
  subgraph: subgraphName,
1368
1629
  error: err instanceof Error ? err.message : String(err)
1369
1630
  });
@@ -1437,7 +1698,7 @@ class StatsAccumulator {
1437
1698
 
1438
1699
  // src/runtime/reindex.ts
1439
1700
  import { getErrorMessage as getErrorMessage2 } from "@secondlayer/shared";
1440
- import { getRawClient, getSourceDb as getSourceDb2, getTargetDb as getTargetDb2 } from "@secondlayer/shared/db";
1701
+ import { getRawClient, getTargetDb as getTargetDb2 } from "@secondlayer/shared/db";
1441
1702
  import {
1442
1703
  recordGapBatch,
1443
1704
  resolveGaps
@@ -1446,7 +1707,7 @@ import {
1446
1707
  recordSubgraphProcessed as recordSubgraphProcessed2,
1447
1708
  updateSubgraphStatus as updateSubgraphStatus2
1448
1709
  } from "@secondlayer/shared/db/queries/subgraphs";
1449
- import { logger as logger5 } from "@secondlayer/shared/logger";
1710
+ import { logger as logger6 } from "@secondlayer/shared/logger";
1450
1711
 
1451
1712
  // src/schema/generator.ts
1452
1713
  import { createHash as createHash2 } from "node:crypto";
@@ -1539,48 +1800,6 @@ function generateSubgraphSQL(def, schemaNameOverride) {
1539
1800
  return { statements, hash };
1540
1801
  }
1541
1802
 
1542
- // src/runtime/batch-loader.ts
1543
- async function loadBlockRange(db, fromHeight, toHeight) {
1544
- const [blocks, txs, events] = await Promise.all([
1545
- db.selectFrom("blocks").selectAll().where("height", ">=", fromHeight).where("height", "<=", toHeight).where("canonical", "=", true).execute(),
1546
- db.selectFrom("transactions").selectAll().where("block_height", ">=", fromHeight).where("block_height", "<=", toHeight).execute(),
1547
- db.selectFrom("events").selectAll().where("block_height", ">=", fromHeight).where("block_height", "<=", toHeight).execute()
1548
- ]);
1549
- const txsByHeight = new Map;
1550
- for (const tx of txs) {
1551
- const h = Number(tx.block_height);
1552
- const list = txsByHeight.get(h) ?? [];
1553
- list.push(tx);
1554
- txsByHeight.set(h, list);
1555
- }
1556
- const eventsByHeight = new Map;
1557
- for (const evt of events) {
1558
- const h = Number(evt.block_height);
1559
- const list = eventsByHeight.get(h) ?? [];
1560
- list.push(evt);
1561
- eventsByHeight.set(h, list);
1562
- }
1563
- const result = new Map;
1564
- for (const block of blocks) {
1565
- const h = Number(block.height);
1566
- result.set(h, {
1567
- block,
1568
- txs: txsByHeight.get(h) ?? [],
1569
- events: eventsByHeight.get(h) ?? []
1570
- });
1571
- }
1572
- return result;
1573
- }
1574
- function avgEventsPerBlock(batch) {
1575
- if (batch.size === 0)
1576
- return 0;
1577
- let totalEvents = 0;
1578
- for (const data of batch.values()) {
1579
- totalEvents += data.events.length;
1580
- }
1581
- return totalEvents / batch.size;
1582
- }
1583
-
1584
1803
  // src/runtime/reindex.ts
1585
1804
  var LOG_INTERVAL = 1000;
1586
1805
  var HEALTH_FLUSH_INTERVAL = 1000;
@@ -1641,7 +1860,7 @@ function coalesceFailedBlocks(blocks) {
1641
1860
  return ranges;
1642
1861
  }
1643
1862
  async function processBlockRange(def, opts) {
1644
- const sourceDb = getSourceDb2();
1863
+ const source = resolveBlockSource(def);
1645
1864
  const targetDb = getTargetDb2();
1646
1865
  const subgraphName = def.name;
1647
1866
  const { fromBlock, toBlock, status } = opts;
@@ -1671,11 +1890,11 @@ async function processBlockRange(def, opts) {
1671
1890
  lastHealthFlushAt = Date.now();
1672
1891
  };
1673
1892
  let nextBatchEnd = Math.min(currentHeight + batchSize - 1, toBlock);
1674
- let nextBatchPromise = loadBlockRange(sourceDb, currentHeight, nextBatchEnd);
1893
+ let nextBatchPromise = source.loadBlockRange(currentHeight, nextBatchEnd);
1675
1894
  while (currentHeight <= toBlock) {
1676
1895
  if (opts.signal?.aborted) {
1677
1896
  aborted = true;
1678
- logger5.info("Block processing aborted", {
1897
+ logger6.info("Block processing aborted", {
1679
1898
  subgraph: subgraphName,
1680
1899
  currentBlock: currentHeight,
1681
1900
  reason: String(opts.signal.reason ?? "unknown")
@@ -1687,7 +1906,7 @@ async function processBlockRange(def, opts) {
1687
1906
  const nextStart = batchEnd + 1;
1688
1907
  if (nextStart <= toBlock) {
1689
1908
  nextBatchEnd = Math.min(nextStart + batchSize - 1, toBlock);
1690
- nextBatchPromise = loadBlockRange(sourceDb, nextStart, nextBatchEnd);
1909
+ nextBatchPromise = source.loadBlockRange(nextStart, nextBatchEnd);
1691
1910
  }
1692
1911
  const batchFailedBlocks = [];
1693
1912
  for (let height = currentHeight;height <= batchEnd; height++) {
@@ -1705,7 +1924,7 @@ async function processBlockRange(def, opts) {
1705
1924
  });
1706
1925
  } catch (err) {
1707
1926
  const errorMsg = err instanceof Error ? err.message : String(err);
1708
- logger5.error("Block processing error", {
1927
+ logger6.error("Block processing error", {
1709
1928
  subgraph: subgraphName,
1710
1929
  blockHeight: height,
1711
1930
  error: errorMsg
@@ -1739,7 +1958,7 @@ async function processBlockRange(def, opts) {
1739
1958
  lastProgressFlushAt = now;
1740
1959
  }
1741
1960
  if (blocksProcessed % LOG_INTERVAL === 0) {
1742
- logger5.info(`${status === "reindexing" ? "Reindex" : "Backfill"} progress`, {
1961
+ logger6.info(`${status === "reindexing" ? "Reindex" : "Backfill"} progress`, {
1743
1962
  subgraph: subgraphName,
1744
1963
  processed: blocksProcessed,
1745
1964
  total: totalBlocks,
@@ -1758,7 +1977,7 @@ async function processBlockRange(def, opts) {
1758
1977
  if (batchFailedBlocks.length > 0 && opts.subgraphId) {
1759
1978
  const gaps = coalesceFailedBlocks(batchFailedBlocks);
1760
1979
  await recordGapBatch(targetDb, opts.subgraphId, subgraphName, gaps).catch((err) => {
1761
- logger5.warn("Failed to record subgraph gaps", {
1980
+ logger6.warn("Failed to record subgraph gaps", {
1762
1981
  subgraph: subgraphName,
1763
1982
  error: err instanceof Error ? err.message : String(err)
1764
1983
  });
@@ -1775,32 +1994,26 @@ async function processBlockRange(def, opts) {
1775
1994
  await flushHealth();
1776
1995
  return { blocksProcessed, totalEventsProcessed, totalErrors, aborted };
1777
1996
  }
1778
- async function resolveBlockRange(sourceDb, def, opts) {
1997
+ async function resolveBlockRange(source, def, opts) {
1779
1998
  const fromBlock = opts?.fromBlock ?? def.startBlock ?? 1;
1780
- let toBlock;
1781
- if (opts?.toBlock != null) {
1782
- toBlock = opts.toBlock;
1783
- } else {
1784
- const progress = await sourceDb.selectFrom("index_progress").selectAll().where("network", "=", process.env.NETWORK ?? "mainnet").executeTakeFirst();
1785
- toBlock = progress?.highest_seen_block ?? 0;
1786
- }
1999
+ const toBlock = opts?.toBlock != null ? opts.toBlock : await source.getTip();
1787
2000
  return { fromBlock, toBlock };
1788
2001
  }
1789
2002
  async function clearReindexMetadata(db, subgraphName) {
1790
2003
  await db.updateTable("subgraphs").set({ reindex_from_block: null, reindex_to_block: null }).where("name", "=", subgraphName).execute();
1791
2004
  }
1792
2005
  async function reindexSubgraph(def, opts) {
1793
- const sourceDb = getSourceDb2();
2006
+ const source = resolveBlockSource(def);
1794
2007
  const targetDb = getTargetDb2();
1795
2008
  const client = getRawClient("target");
1796
2009
  const subgraphName = def.name;
1797
2010
  const schemaName = opts?.schemaName ?? pgSchemaName(subgraphName);
1798
2011
  await updateSubgraphStatus2(targetDb, subgraphName, "reindexing");
1799
- logger5.info("Reindex starting", { subgraph: subgraphName });
2012
+ logger6.info("Reindex starting", { subgraph: subgraphName });
1800
2013
  try {
1801
- const { fromBlock, toBlock } = await resolveBlockRange(sourceDb, def, opts);
2014
+ const { fromBlock, toBlock } = await resolveBlockRange(source, def, opts);
1802
2015
  if (fromBlock > toBlock) {
1803
- logger5.info("No blocks to reindex", {
2016
+ logger6.info("No blocks to reindex", {
1804
2017
  subgraph: subgraphName,
1805
2018
  fromBlock,
1806
2019
  toBlock
@@ -1813,7 +2026,7 @@ async function reindexSubgraph(def, opts) {
1813
2026
  for (const stmt of statements) {
1814
2027
  await client.unsafe(stmt);
1815
2028
  }
1816
- logger5.info("Schema recreated for reindex", { subgraph: subgraphName });
2029
+ logger6.info("Schema recreated for reindex", { subgraph: subgraphName });
1817
2030
  await targetDb.updateTable("subgraphs").set({
1818
2031
  last_processed_block: initialReindexProgressBlock(fromBlock),
1819
2032
  reindex_from_block: fromBlock,
@@ -1824,7 +2037,7 @@ async function reindexSubgraph(def, opts) {
1824
2037
  last_error_at: null,
1825
2038
  updated_at: new Date
1826
2039
  }).where("name", "=", subgraphName).execute();
1827
- logger5.info("Reindexing blocks", {
2040
+ logger6.info("Reindexing blocks", {
1828
2041
  subgraph: subgraphName,
1829
2042
  fromBlock,
1830
2043
  toBlock,
@@ -1845,9 +2058,9 @@ async function reindexSubgraph(def, opts) {
1845
2058
  if (reason === "user-cancelled") {
1846
2059
  await updateSubgraphStatus2(targetDb, subgraphName, "active");
1847
2060
  await clearReindexMetadata(targetDb, subgraphName);
1848
- logger5.info("Reindex cancelled by user", { subgraph: subgraphName });
2061
+ logger6.info("Reindex cancelled by user", { subgraph: subgraphName });
1849
2062
  } else {
1850
- logger5.info("Reindex interrupted by shutdown, will resume", {
2063
+ logger6.info("Reindex interrupted by shutdown, will resume", {
1851
2064
  subgraph: subgraphName
1852
2065
  });
1853
2066
  }
@@ -1855,7 +2068,7 @@ async function reindexSubgraph(def, opts) {
1855
2068
  }
1856
2069
  await updateSubgraphStatus2(targetDb, subgraphName, "active", toBlock);
1857
2070
  await clearReindexMetadata(targetDb, subgraphName);
1858
- logger5.info("Reindex complete", {
2071
+ logger6.info("Reindex complete", {
1859
2072
  subgraph: subgraphName,
1860
2073
  blocks: result.blocksProcessed,
1861
2074
  events: result.totalEventsProcessed,
@@ -1863,7 +2076,7 @@ async function reindexSubgraph(def, opts) {
1863
2076
  });
1864
2077
  return { processed: result.blocksProcessed };
1865
2078
  } catch (err) {
1866
- logger5.error("Reindex failed", {
2079
+ logger6.error("Reindex failed", {
1867
2080
  subgraph: subgraphName,
1868
2081
  error: getErrorMessage2(err)
1869
2082
  });
@@ -1885,7 +2098,7 @@ async function resumeReindex(def, opts) {
1885
2098
  const fromBlock = resolveReindexResumeBlock(row);
1886
2099
  const toBlock = Number(row.reindex_to_block);
1887
2100
  if (fromBlock == null) {
1888
- logger5.info("No reindex metadata, starting fresh reindex", {
2101
+ logger6.info("No reindex metadata, starting fresh reindex", {
1889
2102
  subgraph: subgraphName
1890
2103
  });
1891
2104
  return reindexSubgraph(def, {
@@ -1894,12 +2107,12 @@ async function resumeReindex(def, opts) {
1894
2107
  });
1895
2108
  }
1896
2109
  if (fromBlock > toBlock) {
1897
- logger5.info("Resume: no remaining blocks", { subgraph: subgraphName });
2110
+ logger6.info("Resume: no remaining blocks", { subgraph: subgraphName });
1898
2111
  await updateSubgraphStatus2(targetDb, subgraphName, "active", toBlock);
1899
2112
  await clearReindexMetadata(targetDb, subgraphName);
1900
2113
  return { processed: 0 };
1901
2114
  }
1902
- logger5.info("Resuming reindex", {
2115
+ logger6.info("Resuming reindex", {
1903
2116
  subgraph: subgraphName,
1904
2117
  fromBlock,
1905
2118
  toBlock,
@@ -1920,9 +2133,9 @@ async function resumeReindex(def, opts) {
1920
2133
  if (reason === "user-cancelled") {
1921
2134
  await updateSubgraphStatus2(targetDb, subgraphName, "active");
1922
2135
  await clearReindexMetadata(targetDb, subgraphName);
1923
- logger5.info("Resume cancelled by user", { subgraph: subgraphName });
2136
+ logger6.info("Resume cancelled by user", { subgraph: subgraphName });
1924
2137
  } else {
1925
- logger5.info("Resume interrupted by shutdown, will resume again", {
2138
+ logger6.info("Resume interrupted by shutdown, will resume again", {
1926
2139
  subgraph: subgraphName
1927
2140
  });
1928
2141
  }
@@ -1930,13 +2143,13 @@ async function resumeReindex(def, opts) {
1930
2143
  }
1931
2144
  await updateSubgraphStatus2(targetDb, subgraphName, "active", toBlock);
1932
2145
  await clearReindexMetadata(targetDb, subgraphName);
1933
- logger5.info("Resumed reindex complete", {
2146
+ logger6.info("Resumed reindex complete", {
1934
2147
  subgraph: subgraphName,
1935
2148
  blocks: result.blocksProcessed
1936
2149
  });
1937
2150
  return { processed: result.blocksProcessed };
1938
2151
  } catch (err) {
1939
- logger5.error("Resumed reindex failed", {
2152
+ logger6.error("Resumed reindex failed", {
1940
2153
  subgraph: subgraphName,
1941
2154
  error: getErrorMessage2(err)
1942
2155
  });
@@ -1947,7 +2160,7 @@ async function resumeReindex(def, opts) {
1947
2160
  async function backfillSubgraph(def, opts) {
1948
2161
  const targetDb = getTargetDb2();
1949
2162
  const subgraphName = def.name;
1950
- logger5.info("Backfill starting", {
2163
+ logger6.info("Backfill starting", {
1951
2164
  subgraph: subgraphName,
1952
2165
  from: opts.fromBlock,
1953
2166
  to: opts.toBlock
@@ -1964,17 +2177,17 @@ async function backfillSubgraph(def, opts) {
1964
2177
  signal: opts.signal
1965
2178
  });
1966
2179
  if (result.aborted) {
1967
- logger5.info("Backfill aborted", { subgraph: subgraphName });
2180
+ logger6.info("Backfill aborted", { subgraph: subgraphName });
1968
2181
  return { processed: result.blocksProcessed };
1969
2182
  }
1970
2183
  const resolved = await resolveGaps(targetDb, subgraphName, opts.fromBlock, opts.toBlock).catch(() => 0);
1971
2184
  if (resolved > 0) {
1972
- logger5.info("Resolved subgraph gaps via backfill", {
2185
+ logger6.info("Resolved subgraph gaps via backfill", {
1973
2186
  subgraph: subgraphName,
1974
2187
  resolved
1975
2188
  });
1976
2189
  }
1977
- logger5.info("Backfill complete", {
2190
+ logger6.info("Backfill complete", {
1978
2191
  subgraph: subgraphName,
1979
2192
  blocks: result.blocksProcessed,
1980
2193
  events: result.totalEventsProcessed,
@@ -1982,7 +2195,7 @@ async function backfillSubgraph(def, opts) {
1982
2195
  });
1983
2196
  return { processed: result.blocksProcessed };
1984
2197
  } catch (err) {
1985
- logger5.error("Backfill failed", {
2198
+ logger6.error("Backfill failed", {
1986
2199
  subgraph: subgraphName,
1987
2200
  error: getErrorMessage2(err)
1988
2201
  });
@@ -1998,5 +2211,5 @@ export {
1998
2211
  backfillSubgraph
1999
2212
  };
2000
2213
 
2001
- //# debugId=C6A12A80FA03F24E64756E2164756E21
2214
+ //# debugId=5A3CD1976247568C64756E2164756E21
2002
2215
  //# sourceMappingURL=reindex.js.map