@secondlayer/subgraphs 4.3.5 → 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 (40) hide show
  1. package/dist/src/index.d.ts +63 -4
  2. package/dist/src/index.js +278 -22
  3. package/dist/src/index.js.map +12 -12
  4. package/dist/src/runtime/block-processor.d.ts +24 -2
  5. package/dist/src/runtime/block-processor.js +233 -19
  6. package/dist/src/runtime/block-processor.js.map +9 -9
  7. package/dist/src/runtime/catchup.d.ts +18 -1
  8. package/dist/src/runtime/catchup.js +234 -20
  9. package/dist/src/runtime/catchup.js.map +10 -10
  10. package/dist/src/runtime/processor.js +235 -21
  11. package/dist/src/runtime/processor.js.map +11 -11
  12. package/dist/src/runtime/reindex.d.ts +28 -1
  13. package/dist/src/runtime/reindex.js +235 -21
  14. package/dist/src/runtime/reindex.js.map +11 -11
  15. package/dist/src/runtime/reorg.d.ts +18 -1
  16. package/dist/src/runtime/reorg.js +234 -20
  17. package/dist/src/runtime/reorg.js.map +10 -10
  18. package/dist/src/runtime/replay.d.ts +10 -0
  19. package/dist/src/runtime/replay.js +184 -20
  20. package/dist/src/runtime/replay.js.map +9 -9
  21. package/dist/src/runtime/runner.d.ts +21 -1
  22. package/dist/src/runtime/runner.js +121 -5
  23. package/dist/src/runtime/runner.js.map +4 -4
  24. package/dist/src/runtime/source-matcher.d.ts +22 -2
  25. package/dist/src/runtime/source-matcher.js +61 -4
  26. package/dist/src/runtime/source-matcher.js.map +3 -3
  27. package/dist/src/schema/index.d.ts +18 -1
  28. package/dist/src/schema/index.js +44 -2
  29. package/dist/src/schema/index.js.map +3 -3
  30. package/dist/src/service.js +235 -21
  31. package/dist/src/service.js.map +11 -11
  32. package/dist/src/testing/index.d.ts +64 -2
  33. package/dist/src/testing/index.js +157 -5
  34. package/dist/src/testing/index.js.map +5 -5
  35. package/dist/src/triggers/index.d.ts +18 -1
  36. package/dist/src/types.d.ts +19 -2
  37. package/dist/src/validate.d.ts +19 -2
  38. package/dist/src/validate.js +44 -2
  39. package/dist/src/validate.js.map +3 -3
  40. 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;
@@ -410,8 +427,11 @@ type EventRecord = {
410
427
  id: string
411
428
  tx_id: string
412
429
  type: string
430
+ /** Classic `event_index`, or `ordinal` when `clock === "vm"`. */
413
431
  event_index: number
414
432
  data: unknown
433
+ /** Set on opt-in `vm_events` rows. Two clocks never sort or dedupe together. */
434
+ clock?: "vm"
415
435
  };
416
436
  import { Database as Database2 } from "@secondlayer/shared/db";
417
437
  import { Kysely as Kysely2, Transaction } from "kysely";
@@ -446,7 +466,7 @@ declare function invalidateSubgraphRoute(subgraphName: string): void;
446
466
  * being height-stamped so a reorg can roll it back — were asserted only by
447
467
  * comment until now.
448
468
  */
449
- declare function resolveFactoryContracts(subgraph: SubgraphDefinition, blockHeight: number, schemaName: string, db: Kysely2<Database2>, txs: TxRecord[], evts: EventRecord[]): Promise<{
469
+ declare function resolveFactoryContracts(subgraph: SubgraphDefinition, blockHeight: number, schemaName: string, db: Kysely2<Database2>, txs: TxRecord[], evts: EventRecord[], vmEvts?: EventRecord[]): Promise<{
450
470
  resolved: Map<string, ReadonlySet<string>>
451
471
  discovered: Array<{
452
472
  sourceName: string
@@ -480,6 +500,8 @@ interface PreloadedBlockData {
480
500
  block: import("@secondlayer/shared/db").Block;
481
501
  txs: import("@secondlayer/shared/db").Transaction[];
482
502
  events: import("@secondlayer/shared/db").Event[];
503
+ /** Opt-in `vm_events` rows on the vm clock; see `BlockData.vmEvents`. */
504
+ vmEvents?: import("./batch-loader.ts").RuntimeEvent[];
483
505
  }
484
506
  interface ProcessBlockOptions {
485
507
  /** Skip updating last_processed_block in DB (reindex batches this externally). */
@@ -1009,7 +1009,7 @@ function printContractId(data) {
1009
1009
  const id = (typeof data.contract_identifier === "string" ? data.contract_identifier : undefined) ?? (typeof data.contract_id === "string" ? data.contract_id : undefined);
1010
1010
  return id || undefined;
1011
1011
  }
1012
- function matchFilter(filter, transactions, eventsByTx, traitContracts, factoryContracts = new Map) {
1012
+ function matchFilter(filter, transactions, eventsByTx, traitContracts, factoryContracts = new Map, vmEventsByTx = new Map) {
1013
1013
  const results = [];
1014
1014
  switch (filter.type) {
1015
1015
  case "stx_transfer":
@@ -1174,6 +1174,57 @@ function matchFilter(filter, transactions, eventsByTx, traitContracts, factoryCo
1174
1174
  }
1175
1175
  break;
1176
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
+ }
1177
1228
  case "print_event": {
1178
1229
  for (const tx of transactions) {
1179
1230
  const txEvents = eventsByTx.get(tx.tx_id) ?? [];
@@ -1205,17 +1256,23 @@ function matchFilter(filter, transactions, eventsByTx, traitContracts, factoryCo
1205
1256
  }
1206
1257
  return results;
1207
1258
  }
1208
- function matchSources(sources, transactions, events, traitContracts = new Map, factoryContracts = new Map) {
1259
+ function matchSources(sources, transactions, events, traitContracts = new Map, factoryContracts = new Map, vmEvents = []) {
1209
1260
  const eventsByTx = new Map;
1210
1261
  for (const event of events) {
1211
1262
  const list = eventsByTx.get(event.tx_id) ?? [];
1212
1263
  list.push(event);
1213
1264
  eventsByTx.set(event.tx_id, list);
1214
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
+ }
1215
1272
  const seen = new Set;
1216
1273
  const results = [];
1217
1274
  for (const [sourceName, filter] of Object.entries(sources)) {
1218
- const matches = matchFilter(filter, transactions, eventsByTx, traitContracts, factoryContracts);
1275
+ const matches = matchFilter(filter, transactions, eventsByTx, traitContracts, factoryContracts, vmEventsByTx);
1219
1276
  for (const match of matches) {
1220
1277
  const dedupeKey = `${match.tx.tx_id}:${sourceName}`;
1221
1278
  if (!seen.has(dedupeKey)) {
@@ -1790,6 +1847,12 @@ function decodeRawResult(raw) {
1790
1847
  }
1791
1848
  return null;
1792
1849
  }
1850
+ function decodeRawHex(hex) {
1851
+ if (hex.startsWith("0x") && hex.length > 2) {
1852
+ return decodeClarityValue(hex);
1853
+ }
1854
+ return hex;
1855
+ }
1793
1856
  function safeBigInt(val) {
1794
1857
  if (typeof val === "bigint")
1795
1858
  return val;
@@ -1983,6 +2046,58 @@ function buildEventPayload(filter, tx, event) {
1983
2046
  deployer: tx.sender,
1984
2047
  tx: txMeta
1985
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
+ }
1986
2101
  default:
1987
2102
  return {
1988
2103
  ...decoded,
@@ -2011,7 +2126,8 @@ async function runHandlers(subgraph, matched, ctx, opts) {
2011
2126
  units.push({ tx, sourceName, event });
2012
2127
  }
2013
2128
  }
2014
- 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));
2015
2131
  for (const { tx, event, sourceName } of units) {
2016
2132
  if (errors >= threshold) {
2017
2133
  logger4.error("Subgraph error threshold reached, skipping remaining events", {
@@ -2157,11 +2273,15 @@ import {
2157
2273
  import { logger as logger5 } from "@secondlayer/shared/logger";
2158
2274
 
2159
2275
  // src/runtime/batch-loader.ts
2276
+ function vmEventId(txId, vmEventIndex) {
2277
+ return `${txId}#vm:${vmEventIndex}`;
2278
+ }
2160
2279
  async function loadBlockRange(db, fromHeight, toHeight) {
2161
- const [blocks, txs, events] = await Promise.all([
2280
+ const [blocks, txs, events, vmRows] = await Promise.all([
2162
2281
  db.selectFrom("blocks").selectAll().where("height", ">=", fromHeight).where("height", "<=", toHeight).where("canonical", "=", true).execute(),
2163
2282
  db.selectFrom("transactions").selectAll().where("block_height", ">=", fromHeight).where("block_height", "<=", toHeight).execute(),
2164
- 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()
2165
2285
  ]);
2166
2286
  const txsByHeight = new Map;
2167
2287
  for (const tx of txs) {
@@ -2177,13 +2297,30 @@ async function loadBlockRange(db, fromHeight, toHeight) {
2177
2297
  list.push(evt);
2178
2298
  eventsByHeight.set(h, list);
2179
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
+ }
2180
2316
  const result = new Map;
2181
2317
  for (const block of blocks) {
2182
2318
  const h = Number(block.height);
2183
2319
  result.set(h, {
2184
2320
  block,
2185
2321
  txs: txsByHeight.get(h) ?? [],
2186
- events: eventsByHeight.get(h) ?? []
2322
+ events: eventsByHeight.get(h) ?? [],
2323
+ vmEvents: vmByHeight.get(h) ?? []
2187
2324
  });
2188
2325
  }
2189
2326
  return result;
@@ -2199,6 +2336,9 @@ function avgEventsPerBlock(batch) {
2199
2336
  }
2200
2337
 
2201
2338
  // src/runtime/observer-http-source.ts
2339
+ import {
2340
+ VM_NODE_TO_STORED_TYPE
2341
+ } from "@secondlayer/shared";
2202
2342
  var OBSERVER_HTTP_EXPORT_PATH = "/internal/observer-events";
2203
2343
  function stripTrailingSlash(url) {
2204
2344
  return url.replace(/\/+$/, "");
@@ -2276,7 +2416,29 @@ function mapNewBlockPayloadToBlockData(payload) {
2276
2416
  created_at: new Date(0)
2277
2417
  };
2278
2418
  });
2279
- 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 };
2280
2442
  }
2281
2443
 
2282
2444
  class ObserverHttpBlockSource {
@@ -2479,6 +2641,30 @@ function reconstructEvent(e) {
2479
2641
  raw_value: e.payload.raw_value
2480
2642
  }
2481
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
+ };
2482
2668
  }
2483
2669
  }
2484
2670
 
@@ -2525,12 +2711,24 @@ var EVENT_FILTER_TO_INDEX_TYPE = {
2525
2711
  nft_transfer: "nft_transfer",
2526
2712
  nft_mint: "nft_mint",
2527
2713
  nft_burn: "nft_burn",
2528
- 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"
2529
2720
  };
2530
2721
  var TX_SOURCE_TYPES = new Set(["contract_call", "contract_deploy"]);
2531
- 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 = [
2532
2730
  ...new Set(Object.values(EVENT_FILTER_TO_INDEX_TYPE))
2533
- ];
2731
+ ].filter((t) => !VM_INDEX_EVENT_TYPES.has(t));
2534
2732
  function sourceFilters(subgraph) {
2535
2733
  const sources = subgraph.sources;
2536
2734
  return Array.isArray(sources) ? sources : Object.values(sources);
@@ -2547,10 +2745,11 @@ function synthesizeTxsFromEvents(events) {
2547
2745
  return [...byId.values()];
2548
2746
  }
2549
2747
  function indexEventTypesForFilterTypes(filterTypes) {
2748
+ const types = new Set;
2550
2749
  if (filterTypes.some((t) => TX_SOURCE_TYPES.has(t))) {
2551
- return ALL_INDEX_EVENT_TYPES;
2750
+ for (const t of CLASSIC_INDEX_EVENT_TYPES)
2751
+ types.add(t);
2552
2752
  }
2553
- const types = new Set;
2554
2753
  for (const t of filterTypes) {
2555
2754
  const indexType = EVENT_FILTER_TO_INDEX_TYPE[t];
2556
2755
  if (indexType)
@@ -2596,6 +2795,9 @@ class PublicApiBlockSource {
2596
2795
  return found.length ? Math.min(...found) : null;
2597
2796
  }
2598
2797
  getTip() {
2798
+ if (this.eventTypes.some((t) => VM_INDEX_EVENT_TYPES.has(t))) {
2799
+ return this.http.getIndexSourceTip();
2800
+ }
2599
2801
  return this.http.getIndexTip();
2600
2802
  }
2601
2803
  async loadBlockRange(fromHeight, toHeight) {
@@ -2619,12 +2821,21 @@ class PublicApiBlockSource {
2619
2821
  }
2620
2822
  for (const list of eventLists) {
2621
2823
  for (const e of list) {
2622
- 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
+ }
2623
2833
  }
2624
2834
  }
2625
2835
  for (const bd of map.values()) {
2626
2836
  bd.txs.sort((a, b) => a.tx_index - b.tx_index);
2627
2837
  bd.events.sort((a, b) => a.event_index - b.event_index);
2838
+ bd.vmEvents?.sort((a, b) => a.event_index - b.event_index);
2628
2839
  }
2629
2840
  return map;
2630
2841
  }
@@ -3262,7 +3473,7 @@ function invalidateSubgraphRoute(subgraphName) {
3262
3473
  routeCache.delete(subgraphName);
3263
3474
  evictSandboxWorker(subgraphName);
3264
3475
  }
3265
- async function resolveFactoryContracts(subgraph, blockHeight, schemaName, db, txs, evts) {
3476
+ async function resolveFactoryContracts(subgraph, blockHeight, schemaName, db, txs, evts, vmEvts = []) {
3266
3477
  const factories = new Map;
3267
3478
  for (const source of Object.values(subgraph.sources)) {
3268
3479
  const factory = source.factory;
@@ -3285,7 +3496,7 @@ async function resolveFactoryContracts(subgraph, blockHeight, schemaName, db, tx
3285
3496
  } catch {}
3286
3497
  const discovering = subgraph.sources[factory.from];
3287
3498
  if (discovering) {
3288
- 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);
3289
3500
  for (const match of matches) {
3290
3501
  for (const event of match.events ?? []) {
3291
3502
  const payload = buildEventPayload(discovering, match.tx, event);
@@ -3391,10 +3602,12 @@ async function processBlock(subgraph, subgraphName, blockHeight, opts) {
3391
3602
  let block;
3392
3603
  let txs;
3393
3604
  let evts;
3605
+ let vmEvts;
3394
3606
  if (opts?.preloaded) {
3395
3607
  block = opts.preloaded.block;
3396
3608
  txs = opts.preloaded.txs;
3397
3609
  evts = opts.preloaded.events;
3610
+ vmEvts = opts.preloaded.vmEvents ?? [];
3398
3611
  } else {
3399
3612
  const data = (await resolveBlockSource(subgraph).loadBlockRange(blockHeight, blockHeight)).get(blockHeight);
3400
3613
  if (!data) {
@@ -3408,12 +3621,13 @@ async function processBlock(subgraph, subgraphName, blockHeight, opts) {
3408
3621
  block = data.block;
3409
3622
  txs = data.txs;
3410
3623
  evts = data.events;
3624
+ vmEvts = data.vmEvents ?? [];
3411
3625
  }
3412
3626
  const route = await resolveRoute(subgraphName, targetDb);
3413
3627
  const schemaName = route.schemaName;
3414
3628
  const traitContracts = await resolveTraitContracts(subgraph, blockHeight, targetDb);
3415
- const { resolved: factoryContracts, discovered } = await resolveFactoryContracts(subgraph, blockHeight, schemaName, targetDb, txs, evts);
3416
- 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);
3417
3631
  result.matched = matched.length;
3418
3632
  if (matched.length === 0) {
3419
3633
  if (!opts?.skipProgressUpdate) {
@@ -3592,5 +3806,5 @@ export {
3592
3806
  BLOCK_RETRY_DELAYS_MS
3593
3807
  };
3594
3808
 
3595
- //# debugId=1AF27637D3849E1964756E2164756E21
3809
+ //# debugId=7C0EFDD5F3DC65D364756E2164756E21
3596
3810
  //# sourceMappingURL=block-processor.js.map