@secondlayer/subgraphs 4.3.4 → 4.4.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.
Files changed (42) hide show
  1. package/dist/src/index.d.ts +63 -4
  2. package/dist/src/index.js +307 -28
  3. package/dist/src/index.js.map +14 -14
  4. package/dist/src/runtime/block-processor.d.ts +24 -2
  5. package/dist/src/runtime/block-processor.js +252 -21
  6. package/dist/src/runtime/block-processor.js.map +10 -10
  7. package/dist/src/runtime/catchup.d.ts +18 -1
  8. package/dist/src/runtime/catchup.js +253 -22
  9. package/dist/src/runtime/catchup.js.map +11 -11
  10. package/dist/src/runtime/context.js +20 -3
  11. package/dist/src/runtime/context.js.map +3 -3
  12. package/dist/src/runtime/processor.js +254 -23
  13. package/dist/src/runtime/processor.js.map +12 -12
  14. package/dist/src/runtime/reindex.d.ts +28 -1
  15. package/dist/src/runtime/reindex.js +254 -23
  16. package/dist/src/runtime/reindex.js.map +12 -12
  17. package/dist/src/runtime/reorg.d.ts +18 -1
  18. package/dist/src/runtime/reorg.js +253 -22
  19. package/dist/src/runtime/reorg.js.map +11 -11
  20. package/dist/src/runtime/replay.d.ts +10 -0
  21. package/dist/src/runtime/replay.js +184 -20
  22. package/dist/src/runtime/replay.js.map +9 -9
  23. package/dist/src/runtime/runner.d.ts +21 -1
  24. package/dist/src/runtime/runner.js +121 -5
  25. package/dist/src/runtime/runner.js.map +4 -4
  26. package/dist/src/runtime/source-matcher.d.ts +22 -2
  27. package/dist/src/runtime/source-matcher.js +61 -4
  28. package/dist/src/runtime/source-matcher.js.map +3 -3
  29. package/dist/src/schema/index.d.ts +18 -1
  30. package/dist/src/schema/index.js +73 -8
  31. package/dist/src/schema/index.js.map +5 -5
  32. package/dist/src/service.js +254 -23
  33. package/dist/src/service.js.map +12 -12
  34. package/dist/src/testing/index.d.ts +64 -2
  35. package/dist/src/testing/index.js +176 -7
  36. package/dist/src/testing/index.js.map +6 -6
  37. package/dist/src/triggers/index.d.ts +18 -1
  38. package/dist/src/types.d.ts +19 -2
  39. package/dist/src/validate.d.ts +19 -2
  40. package/dist/src/validate.js +44 -2
  41. package/dist/src/validate.js.map +3 -3
  42. package/package.json +3 -3
@@ -219,6 +219,23 @@ interface ContractDeployFilter {
219
219
  deployer?: string;
220
220
  contractName?: string;
221
221
  }
222
+ interface NestedContractCallFilter extends TraitScope, FactoryScope {
223
+ type: "nested_contract_call";
224
+ contractId?: string | readonly string[];
225
+ functionName?: string;
226
+ caller?: string;
227
+ sender?: string;
228
+ }
229
+ interface VarSetFilter extends TraitScope, FactoryScope {
230
+ type: "var_set";
231
+ contractId?: string | readonly string[];
232
+ varName?: string;
233
+ }
234
+ interface MapWriteFilter extends TraitScope, FactoryScope {
235
+ type: "map_set" | "map_insert" | "map_delete";
236
+ contractId?: string | readonly string[];
237
+ map?: string;
238
+ }
222
239
  /**
223
240
  * One declared field of a print payload.
224
241
  *
@@ -306,7 +323,7 @@ type UnpinnedPrintEventFilter = PrintEventFields & {
306
323
  */
307
324
  type PrintEventFilter = PinnedPrintEventFilter | TraitPrintEventFilter | UnpinnedPrintEventFilter;
308
325
  /** All subgraph filter types — discriminated on `type` */
309
- type SubgraphFilter = StxTransferFilter | StxMintFilter | StxBurnFilter | StxLockFilter | FtTransferFilter | FtMintFilter | FtBurnFilter | NftTransferFilter | NftMintFilter | NftBurnFilter | ContractCallFilter | ContractDeployFilter | PrintEventFilter;
326
+ type SubgraphFilter = StxTransferFilter | StxMintFilter | StxBurnFilter | StxLockFilter | FtTransferFilter | FtMintFilter | FtBurnFilter | NftTransferFilter | NftMintFilter | NftBurnFilter | ContractCallFilter | ContractDeployFilter | PrintEventFilter | NestedContractCallFilter | VarSetFilter | MapWriteFilter;
310
327
  /** Transaction metadata available in handlers */
311
328
  interface TxMeta {
312
329
  txId: string;
@@ -395,10 +412,20 @@ interface SubgraphDefinition {
395
412
  handlers: Record<string, SubgraphHandler>;
396
413
  }
397
414
  import { Block, Event, Transaction } from "@secondlayer/shared/db";
415
+ /** A runtime event row. `clock: "vm"` marks an opt-in `vm_events` row whose
416
+ * `event_index` is `ordinal` — a second ordinal that never sorts or
417
+ * dedupes against classic `events.event_index`. */
418
+ type RuntimeEvent = Event & {
419
+ clock?: "vm"
420
+ };
398
421
  interface BlockData {
399
422
  block: Block;
400
423
  txs: Transaction[];
424
+ /** Classic `events` rows (Streams 1.0 clock). */
401
425
  events: Event[];
426
+ /** Opt-in `vm_events` rows on their own clock. Absent/empty on `"*"`
427
+ * nodes and on archives collected without `storage`/`contract_calls`. */
428
+ vmEvents?: RuntimeEvent[];
402
429
  }
403
430
  /**
404
431
  * Where the subgraph runtime reads canonical chain data. Today it taps the
@@ -41,6 +41,24 @@ function safeIndexName(name) {
41
41
  const hash = createHash("sha256").update(name).digest("hex").slice(0, 8);
42
42
  return `${name.slice(0, MAX_IDENT_BYTES - hash.length - 1)}_${hash}`;
43
43
  }
44
+ function emitIndexedColumnIndexDDL(schemaName, tableName, colName, opts) {
45
+ const concurrently = opts?.concurrently ? " CONCURRENTLY" : "";
46
+ const qualified = `${quotePgIdent(schemaName)}.${quotePgIdent(tableName)}`;
47
+ const plain = `idx_${schemaName}_${tableName}_${colName}`;
48
+ const composite = safeIndexName(`idx_${schemaName}_${tableName}_${colName}_id`);
49
+ const col = quotePgIdent(colName);
50
+ const id = quotePgIdent("_id");
51
+ return {
52
+ create: [
53
+ `CREATE INDEX${concurrently} IF NOT EXISTS ${quotePgIdent(plain)} ON ${qualified} (${col})`,
54
+ `CREATE INDEX${concurrently} IF NOT EXISTS ${quotePgIdent(composite)} ON ${qualified} (${col}, ${id})`
55
+ ],
56
+ drop: [
57
+ `DROP INDEX${concurrently} IF EXISTS ${quotePgIdent(schemaName)}.${quotePgIdent(plain)}`,
58
+ `DROP INDEX${concurrently} IF EXISTS ${quotePgIdent(schemaName)}.${quotePgIdent(composite)}`
59
+ ]
60
+ };
61
+ }
44
62
  function escapeLiteralDefault(value) {
45
63
  if (value === null || value === undefined)
46
64
  return "NULL";
@@ -82,8 +100,7 @@ function emitTableDDL(schemaName, tableName, tableDef) {
82
100
  statements.push(`CREATE INDEX IF NOT EXISTS ${quotePgIdent(`idx_${schemaName}_${tableName}_tx_id`)} ON ${qualifiedName} (_tx_id)`);
83
101
  for (const [colName, col] of Object.entries(tableDef.columns)) {
84
102
  if (col.indexed) {
85
- statements.push(`CREATE INDEX IF NOT EXISTS ${quotePgIdent(`idx_${schemaName}_${tableName}_${colName}`)} ON ${qualifiedName} (${quotePgIdent(colName)})`);
86
- statements.push(`CREATE INDEX IF NOT EXISTS ${quotePgIdent(safeIndexName(`idx_${schemaName}_${tableName}_${colName}_id`))} ON ${qualifiedName} (${quotePgIdent(colName)}, ${quotePgIdent("_id")})`);
103
+ statements.push(...emitIndexedColumnIndexDDL(schemaName, tableName, colName).create);
87
104
  }
88
105
  }
89
106
  for (const [colName, col] of Object.entries(tableDef.columns)) {
@@ -992,7 +1009,7 @@ function printContractId(data) {
992
1009
  const id = (typeof data.contract_identifier === "string" ? data.contract_identifier : undefined) ?? (typeof data.contract_id === "string" ? data.contract_id : undefined);
993
1010
  return id || undefined;
994
1011
  }
995
- function matchFilter(filter, transactions, eventsByTx, traitContracts, factoryContracts = new Map) {
1012
+ function matchFilter(filter, transactions, eventsByTx, traitContracts, factoryContracts = new Map, vmEventsByTx = new Map) {
996
1013
  const results = [];
997
1014
  switch (filter.type) {
998
1015
  case "stx_transfer":
@@ -1157,6 +1174,57 @@ function matchFilter(filter, transactions, eventsByTx, traitContracts, factoryCo
1157
1174
  }
1158
1175
  break;
1159
1176
  }
1177
+ case "nested_contract_call":
1178
+ case "var_set":
1179
+ case "map_set":
1180
+ case "map_insert":
1181
+ case "map_delete": {
1182
+ for (const tx of transactions) {
1183
+ const txEvents = vmEventsByTx.get(tx.tx_id) ?? [];
1184
+ const matched = txEvents.filter((e) => {
1185
+ if (e.type !== filter.type)
1186
+ return false;
1187
+ const data = e.data;
1188
+ if (!data)
1189
+ return false;
1190
+ const contractId = printContractId(data);
1191
+ if ("contractId" in filter && filter.contractId) {
1192
+ if (!contractId || !matchAny(contractId, filter.contractId))
1193
+ return false;
1194
+ }
1195
+ if (!traitAllows(filter, contractId, traitContracts))
1196
+ return false;
1197
+ if (!factoryAllows(filter, contractId, factoryContracts))
1198
+ return false;
1199
+ if (filter.type === "nested_contract_call") {
1200
+ if (filter.functionName) {
1201
+ if (typeof data.function_name !== "string" || !matchPattern(data.function_name, filter.functionName))
1202
+ return false;
1203
+ }
1204
+ if (filter.caller) {
1205
+ if (typeof data.caller !== "string" || !matchPattern(data.caller, filter.caller))
1206
+ return false;
1207
+ }
1208
+ if (filter.sender) {
1209
+ if (typeof data.sender !== "string" || !matchPattern(data.sender, filter.sender))
1210
+ return false;
1211
+ }
1212
+ }
1213
+ if (filter.type === "var_set" && filter.varName) {
1214
+ if (typeof data.var_name !== "string" || !matchPattern(data.var_name, filter.varName))
1215
+ return false;
1216
+ }
1217
+ if ((filter.type === "map_set" || filter.type === "map_insert" || filter.type === "map_delete") && filter.map) {
1218
+ if (typeof data.map_name !== "string" || !matchPattern(data.map_name, filter.map))
1219
+ return false;
1220
+ }
1221
+ return true;
1222
+ });
1223
+ if (matched.length > 0)
1224
+ results.push({ tx, events: matched });
1225
+ }
1226
+ break;
1227
+ }
1160
1228
  case "print_event": {
1161
1229
  for (const tx of transactions) {
1162
1230
  const txEvents = eventsByTx.get(tx.tx_id) ?? [];
@@ -1188,17 +1256,23 @@ function matchFilter(filter, transactions, eventsByTx, traitContracts, factoryCo
1188
1256
  }
1189
1257
  return results;
1190
1258
  }
1191
- function matchSources(sources, transactions, events, traitContracts = new Map, factoryContracts = new Map) {
1259
+ function matchSources(sources, transactions, events, traitContracts = new Map, factoryContracts = new Map, vmEvents = []) {
1192
1260
  const eventsByTx = new Map;
1193
1261
  for (const event of events) {
1194
1262
  const list = eventsByTx.get(event.tx_id) ?? [];
1195
1263
  list.push(event);
1196
1264
  eventsByTx.set(event.tx_id, list);
1197
1265
  }
1266
+ const vmEventsByTx = new Map;
1267
+ for (const event of vmEvents) {
1268
+ const list = vmEventsByTx.get(event.tx_id) ?? [];
1269
+ list.push(event);
1270
+ vmEventsByTx.set(event.tx_id, list);
1271
+ }
1198
1272
  const seen = new Set;
1199
1273
  const results = [];
1200
1274
  for (const [sourceName, filter] of Object.entries(sources)) {
1201
- const matches = matchFilter(filter, transactions, eventsByTx, traitContracts, factoryContracts);
1275
+ const matches = matchFilter(filter, transactions, eventsByTx, traitContracts, factoryContracts, vmEventsByTx);
1202
1276
  for (const match of matches) {
1203
1277
  const dedupeKey = `${match.tx.tx_id}:${sourceName}`;
1204
1278
  if (!seen.has(dedupeKey)) {
@@ -1773,6 +1847,12 @@ function decodeRawResult(raw) {
1773
1847
  }
1774
1848
  return null;
1775
1849
  }
1850
+ function decodeRawHex(hex) {
1851
+ if (hex.startsWith("0x") && hex.length > 2) {
1852
+ return decodeClarityValue(hex);
1853
+ }
1854
+ return hex;
1855
+ }
1776
1856
  function safeBigInt(val) {
1777
1857
  if (typeof val === "bigint")
1778
1858
  return val;
@@ -1966,6 +2046,58 @@ function buildEventPayload(filter, tx, event) {
1966
2046
  deployer: tx.sender,
1967
2047
  tx: txMeta
1968
2048
  };
2049
+ case "nested_contract_call": {
2050
+ const data = event.data ?? {};
2051
+ const argsHex = Array.isArray(data.function_args) ? data.function_args.filter((a) => typeof a === "string") : [];
2052
+ return {
2053
+ contractId: printContractId(data) ?? "",
2054
+ sender: typeof data.sender === "string" ? data.sender : null,
2055
+ caller: typeof data.caller === "string" ? data.caller : "",
2056
+ functionName: typeof data.function_name === "string" ? data.function_name : "",
2057
+ args: decodeFunctionArgs2(argsHex),
2058
+ arguments: argsHex,
2059
+ rawResult: typeof data.raw_result === "string" ? data.raw_result : "",
2060
+ result: decodeRawResult(data.raw_result),
2061
+ tx: txMeta
2062
+ };
2063
+ }
2064
+ case "var_set": {
2065
+ const data = event.data ?? {};
2066
+ const rawValue = typeof data.raw_value === "string" ? data.raw_value : "";
2067
+ return {
2068
+ contractId: printContractId(data) ?? "",
2069
+ varName: typeof data.var_name === "string" ? data.var_name : "",
2070
+ rawValue,
2071
+ value: decodeRawHex(rawValue),
2072
+ tx: txMeta
2073
+ };
2074
+ }
2075
+ case "map_set":
2076
+ case "map_insert": {
2077
+ const data = event.data ?? {};
2078
+ const rawKey = typeof data.raw_key === "string" ? data.raw_key : "";
2079
+ const rawValue = typeof data.raw_value === "string" ? data.raw_value : "";
2080
+ return {
2081
+ contractId: printContractId(data) ?? "",
2082
+ map: typeof data.map_name === "string" ? data.map_name : "",
2083
+ rawKey,
2084
+ key: decodeRawHex(rawKey),
2085
+ rawValue,
2086
+ value: decodeRawHex(rawValue),
2087
+ tx: txMeta
2088
+ };
2089
+ }
2090
+ case "map_delete": {
2091
+ const data = event.data ?? {};
2092
+ const rawKey = typeof data.raw_key === "string" ? data.raw_key : "";
2093
+ return {
2094
+ contractId: printContractId(data) ?? "",
2095
+ map: typeof data.map_name === "string" ? data.map_name : "",
2096
+ rawKey,
2097
+ key: decodeRawHex(rawKey),
2098
+ tx: txMeta
2099
+ };
2100
+ }
1969
2101
  default:
1970
2102
  return {
1971
2103
  ...decoded,
@@ -1994,7 +2126,8 @@ async function runHandlers(subgraph, matched, ctx, opts) {
1994
2126
  units.push({ tx, sourceName, event });
1995
2127
  }
1996
2128
  }
1997
- units.sort((a, b) => (a.tx.tx_index ?? 0) - (b.tx.tx_index ?? 0) || (a.event?.event_index ?? -1) - (b.event?.event_index ?? -1));
2129
+ const clockRank = (e) => e?.clock === "vm" ? 1 : 0;
2130
+ units.sort((a, b) => (a.tx.tx_index ?? 0) - (b.tx.tx_index ?? 0) || clockRank(a.event) - clockRank(b.event) || (a.event?.event_index ?? -1) - (b.event?.event_index ?? -1));
1998
2131
  for (const { tx, event, sourceName } of units) {
1999
2132
  if (errors >= threshold) {
2000
2133
  logger4.error("Subgraph error threshold reached, skipping remaining events", {
@@ -2140,11 +2273,15 @@ import {
2140
2273
  import { logger as logger5 } from "@secondlayer/shared/logger";
2141
2274
 
2142
2275
  // src/runtime/batch-loader.ts
2276
+ function vmEventId(txId, vmEventIndex) {
2277
+ return `${txId}#vm:${vmEventIndex}`;
2278
+ }
2143
2279
  async function loadBlockRange(db, fromHeight, toHeight) {
2144
- const [blocks, txs, events] = await Promise.all([
2280
+ const [blocks, txs, events, vmRows] = await Promise.all([
2145
2281
  db.selectFrom("blocks").selectAll().where("height", ">=", fromHeight).where("height", "<=", toHeight).where("canonical", "=", true).execute(),
2146
2282
  db.selectFrom("transactions").selectAll().where("block_height", ">=", fromHeight).where("block_height", "<=", toHeight).execute(),
2147
- db.selectFrom("events").selectAll().where("block_height", ">=", fromHeight).where("block_height", "<=", toHeight).execute()
2283
+ db.selectFrom("events").selectAll().where("block_height", ">=", fromHeight).where("block_height", "<=", toHeight).execute(),
2284
+ db.selectFrom("vm_events").selectAll().where("block_height", ">=", fromHeight).where("block_height", "<=", toHeight).orderBy("ordinal", "asc").execute()
2148
2285
  ]);
2149
2286
  const txsByHeight = new Map;
2150
2287
  for (const tx of txs) {
@@ -2160,13 +2297,30 @@ async function loadBlockRange(db, fromHeight, toHeight) {
2160
2297
  list.push(evt);
2161
2298
  eventsByHeight.set(h, list);
2162
2299
  }
2300
+ const vmByHeight = new Map;
2301
+ for (const row of vmRows) {
2302
+ const h = Number(row.block_height);
2303
+ const list = vmByHeight.get(h) ?? [];
2304
+ list.push({
2305
+ id: vmEventId(row.tx_id, Number(row.ordinal)),
2306
+ tx_id: row.tx_id,
2307
+ block_height: h,
2308
+ event_index: Number(row.ordinal),
2309
+ type: row.type,
2310
+ data: row.data,
2311
+ created_at: row.created_at,
2312
+ clock: "vm"
2313
+ });
2314
+ vmByHeight.set(h, list);
2315
+ }
2163
2316
  const result = new Map;
2164
2317
  for (const block of blocks) {
2165
2318
  const h = Number(block.height);
2166
2319
  result.set(h, {
2167
2320
  block,
2168
2321
  txs: txsByHeight.get(h) ?? [],
2169
- events: eventsByHeight.get(h) ?? []
2322
+ events: eventsByHeight.get(h) ?? [],
2323
+ vmEvents: vmByHeight.get(h) ?? []
2170
2324
  });
2171
2325
  }
2172
2326
  return result;
@@ -2182,6 +2336,9 @@ function avgEventsPerBlock(batch) {
2182
2336
  }
2183
2337
 
2184
2338
  // src/runtime/observer-http-source.ts
2339
+ import {
2340
+ VM_NODE_TO_STORED_TYPE
2341
+ } from "@secondlayer/shared";
2185
2342
  var OBSERVER_HTTP_EXPORT_PATH = "/internal/observer-events";
2186
2343
  function stripTrailingSlash(url) {
2187
2344
  return url.replace(/\/+$/, "");
@@ -2259,7 +2416,29 @@ function mapNewBlockPayloadToBlockData(payload) {
2259
2416
  created_at: new Date(0)
2260
2417
  };
2261
2418
  });
2262
- return { block, txs, events };
2419
+ const vmEvents = [];
2420
+ for (const [i, trace] of (p.vm_events ?? []).entries()) {
2421
+ const nodeType = trace.type;
2422
+ if (typeof nodeType !== "string" || !(nodeType in VM_NODE_TO_STORED_TYPE))
2423
+ continue;
2424
+ const stored = VM_NODE_TO_STORED_TYPE[nodeType];
2425
+ const body = trace[nodeType];
2426
+ if (!body || typeof body !== "object")
2427
+ continue;
2428
+ const txId = trace.txid ?? "";
2429
+ const vmIndex = i;
2430
+ vmEvents.push({
2431
+ id: vmEventId(txId, vmIndex),
2432
+ tx_id: txId,
2433
+ block_height: height,
2434
+ event_index: vmIndex,
2435
+ type: stored,
2436
+ data: body,
2437
+ created_at: new Date(0),
2438
+ clock: "vm"
2439
+ });
2440
+ }
2441
+ return { block, txs, events, vmEvents };
2263
2442
  }
2264
2443
 
2265
2444
  class ObserverHttpBlockSource {
@@ -2462,6 +2641,30 @@ function reconstructEvent(e) {
2462
2641
  raw_value: e.payload.raw_value
2463
2642
  }
2464
2643
  };
2644
+ case "nested_contract_call":
2645
+ case "var_set":
2646
+ case "map_set":
2647
+ case "map_insert":
2648
+ case "map_delete":
2649
+ return {
2650
+ ...base,
2651
+ id: vmEventId(e.tx_id, e.event_index),
2652
+ clock: "vm",
2653
+ type: e.event_type,
2654
+ data: {
2655
+ contract_identifier: e.contract_id,
2656
+ ..."payload" in e && e.payload && typeof e.payload === "object" ? e.payload : {},
2657
+ sender: "sender" in e ? e.sender : undefined,
2658
+ caller: "caller" in e ? e.caller : undefined,
2659
+ function_name: "function_name" in e ? e.function_name : undefined,
2660
+ function_args: "function_args" in e ? e.function_args : undefined,
2661
+ raw_result: "raw_result" in e ? e.raw_result : undefined,
2662
+ map_name: "map" in e ? e.map : undefined,
2663
+ var_name: "var_name" in e ? e.var_name : undefined,
2664
+ raw_key: "raw_key" in e ? e.raw_key : undefined,
2665
+ raw_value: "raw_value" in e ? e.raw_value : undefined
2666
+ }
2667
+ };
2465
2668
  }
2466
2669
  }
2467
2670
 
@@ -2508,12 +2711,24 @@ var EVENT_FILTER_TO_INDEX_TYPE = {
2508
2711
  nft_transfer: "nft_transfer",
2509
2712
  nft_mint: "nft_mint",
2510
2713
  nft_burn: "nft_burn",
2511
- print_event: "print"
2714
+ print_event: "print",
2715
+ nested_contract_call: "nested_contract_call",
2716
+ var_set: "var_set",
2717
+ map_set: "map_set",
2718
+ map_insert: "map_insert",
2719
+ map_delete: "map_delete"
2512
2720
  };
2513
2721
  var TX_SOURCE_TYPES = new Set(["contract_call", "contract_deploy"]);
2514
- var ALL_INDEX_EVENT_TYPES = [
2722
+ var VM_INDEX_EVENT_TYPES = new Set([
2723
+ "nested_contract_call",
2724
+ "var_set",
2725
+ "map_set",
2726
+ "map_insert",
2727
+ "map_delete"
2728
+ ]);
2729
+ var CLASSIC_INDEX_EVENT_TYPES = [
2515
2730
  ...new Set(Object.values(EVENT_FILTER_TO_INDEX_TYPE))
2516
- ];
2731
+ ].filter((t) => !VM_INDEX_EVENT_TYPES.has(t));
2517
2732
  function sourceFilters(subgraph) {
2518
2733
  const sources = subgraph.sources;
2519
2734
  return Array.isArray(sources) ? sources : Object.values(sources);
@@ -2530,10 +2745,11 @@ function synthesizeTxsFromEvents(events) {
2530
2745
  return [...byId.values()];
2531
2746
  }
2532
2747
  function indexEventTypesForFilterTypes(filterTypes) {
2748
+ const types = new Set;
2533
2749
  if (filterTypes.some((t) => TX_SOURCE_TYPES.has(t))) {
2534
- return ALL_INDEX_EVENT_TYPES;
2750
+ for (const t of CLASSIC_INDEX_EVENT_TYPES)
2751
+ types.add(t);
2535
2752
  }
2536
- const types = new Set;
2537
2753
  for (const t of filterTypes) {
2538
2754
  const indexType = EVENT_FILTER_TO_INDEX_TYPE[t];
2539
2755
  if (indexType)
@@ -2579,6 +2795,9 @@ class PublicApiBlockSource {
2579
2795
  return found.length ? Math.min(...found) : null;
2580
2796
  }
2581
2797
  getTip() {
2798
+ if (this.eventTypes.some((t) => VM_INDEX_EVENT_TYPES.has(t))) {
2799
+ return this.http.getIndexSourceTip();
2800
+ }
2582
2801
  return this.http.getIndexTip();
2583
2802
  }
2584
2803
  async loadBlockRange(fromHeight, toHeight) {
@@ -2602,12 +2821,21 @@ class PublicApiBlockSource {
2602
2821
  }
2603
2822
  for (const list of eventLists) {
2604
2823
  for (const e of list) {
2605
- map.get(e.block_height)?.events.push(reconstructEvent(e));
2824
+ const bd = map.get(e.block_height);
2825
+ if (!bd)
2826
+ continue;
2827
+ if (VM_INDEX_EVENT_TYPES.has(e.event_type)) {
2828
+ bd.vmEvents ??= [];
2829
+ bd.vmEvents.push(reconstructEvent(e));
2830
+ } else {
2831
+ bd.events.push(reconstructEvent(e));
2832
+ }
2606
2833
  }
2607
2834
  }
2608
2835
  for (const bd of map.values()) {
2609
2836
  bd.txs.sort((a, b) => a.tx_index - b.tx_index);
2610
2837
  bd.events.sort((a, b) => a.event_index - b.event_index);
2838
+ bd.vmEvents?.sort((a, b) => a.event_index - b.event_index);
2611
2839
  }
2612
2840
  return map;
2613
2841
  }
@@ -3245,7 +3473,7 @@ function invalidateSubgraphRoute(subgraphName) {
3245
3473
  routeCache.delete(subgraphName);
3246
3474
  evictSandboxWorker(subgraphName);
3247
3475
  }
3248
- async function resolveFactoryContracts(subgraph, blockHeight, schemaName, db, txs, evts) {
3476
+ async function resolveFactoryContracts(subgraph, blockHeight, schemaName, db, txs, evts, vmEvts = []) {
3249
3477
  const factories = new Map;
3250
3478
  for (const source of Object.values(subgraph.sources)) {
3251
3479
  const factory = source.factory;
@@ -3268,7 +3496,7 @@ async function resolveFactoryContracts(subgraph, blockHeight, schemaName, db, tx
3268
3496
  } catch {}
3269
3497
  const discovering = subgraph.sources[factory.from];
3270
3498
  if (discovering) {
3271
- const matches = matchSources({ [factory.from]: discovering }, txs, evts, new Map, new Map);
3499
+ const matches = matchSources({ [factory.from]: discovering }, txs, evts, new Map, new Map, vmEvts);
3272
3500
  for (const match of matches) {
3273
3501
  for (const event of match.events ?? []) {
3274
3502
  const payload = buildEventPayload(discovering, match.tx, event);
@@ -3374,10 +3602,12 @@ async function processBlock(subgraph, subgraphName, blockHeight, opts) {
3374
3602
  let block;
3375
3603
  let txs;
3376
3604
  let evts;
3605
+ let vmEvts;
3377
3606
  if (opts?.preloaded) {
3378
3607
  block = opts.preloaded.block;
3379
3608
  txs = opts.preloaded.txs;
3380
3609
  evts = opts.preloaded.events;
3610
+ vmEvts = opts.preloaded.vmEvents ?? [];
3381
3611
  } else {
3382
3612
  const data = (await resolveBlockSource(subgraph).loadBlockRange(blockHeight, blockHeight)).get(blockHeight);
3383
3613
  if (!data) {
@@ -3391,12 +3621,13 @@ async function processBlock(subgraph, subgraphName, blockHeight, opts) {
3391
3621
  block = data.block;
3392
3622
  txs = data.txs;
3393
3623
  evts = data.events;
3624
+ vmEvts = data.vmEvents ?? [];
3394
3625
  }
3395
3626
  const route = await resolveRoute(subgraphName, targetDb);
3396
3627
  const schemaName = route.schemaName;
3397
3628
  const traitContracts = await resolveTraitContracts(subgraph, blockHeight, targetDb);
3398
- const { resolved: factoryContracts, discovered } = await resolveFactoryContracts(subgraph, blockHeight, schemaName, targetDb, txs, evts);
3399
- const matched = matchSources(subgraph.sources, txs, evts, traitContracts, factoryContracts);
3629
+ const { resolved: factoryContracts, discovered } = await resolveFactoryContracts(subgraph, blockHeight, schemaName, targetDb, txs, evts, vmEvts);
3630
+ const matched = matchSources(subgraph.sources, txs, evts, traitContracts, factoryContracts, vmEvts);
3400
3631
  result.matched = matched.length;
3401
3632
  if (matched.length === 0) {
3402
3633
  if (!opts?.skipProgressUpdate) {
@@ -3668,7 +3899,7 @@ function decoderNameForEventType(indexEventType) {
3668
3899
  return `decode.${indexEventType}.v1`;
3669
3900
  }
3670
3901
  function decoderNamesForIndexEventTypes(eventTypes) {
3671
- return eventTypes.map(decoderNameForEventType);
3902
+ return eventTypes.filter((t) => !VM_INDEX_EVENT_TYPES.has(t)).map(decoderNameForEventType);
3672
3903
  }
3673
3904
  function decoderNamesForSubgraph(subgraph) {
3674
3905
  return decoderNamesForIndexEventTypes(referencedIndexEventTypes(subgraph));
@@ -4198,7 +4429,7 @@ async function processBlockRange(def, opts) {
4198
4429
  }
4199
4430
  let result;
4200
4431
  try {
4201
- const mayWrite = blockData.txs.length > 0 || blockData.events.length > 0;
4432
+ const mayWrite = blockData.txs.length > 0 || blockData.events.length > 0 || (blockData.vmEvents?.length ?? 0) > 0;
4202
4433
  const runBlock = () => processBlockWithRetry(def, subgraphName, height, {
4203
4434
  skipProgressUpdate: true,
4204
4435
  atomicProgress,
@@ -4567,5 +4798,5 @@ export {
4567
4798
  backfillSubgraph
4568
4799
  };
4569
4800
 
4570
- //# debugId=2F4BC80D6FDD19E164756E2164756E21
4801
+ //# debugId=8D0663264E89460C64756E2164756E21
4571
4802
  //# sourceMappingURL=reindex.js.map