@secondlayer/subgraphs 0.8.1 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/dist/src/index.d.ts +113 -32
  2. package/dist/src/index.js +486 -99
  3. package/dist/src/index.js.map +9 -10
  4. package/dist/src/runtime/block-processor.d.ts +110 -20
  5. package/dist/src/runtime/block-processor.js +452 -90
  6. package/dist/src/runtime/block-processor.js.map +7 -8
  7. package/dist/src/runtime/catchup.d.ts +110 -20
  8. package/dist/src/runtime/catchup.js +457 -94
  9. package/dist/src/runtime/catchup.js.map +8 -9
  10. package/dist/src/runtime/clarity.js +3 -3
  11. package/dist/src/runtime/clarity.js.map +3 -3
  12. package/dist/src/runtime/context.d.ts +23 -5
  13. package/dist/src/runtime/context.js +57 -1
  14. package/dist/src/runtime/context.js.map +3 -3
  15. package/dist/src/runtime/processor.js +457 -94
  16. package/dist/src/runtime/processor.js.map +8 -9
  17. package/dist/src/runtime/reindex.d.ts +110 -20
  18. package/dist/src/runtime/reindex.js +452 -90
  19. package/dist/src/runtime/reindex.js.map +7 -8
  20. package/dist/src/runtime/reorg.d.ts +110 -20
  21. package/dist/src/runtime/reorg.js +452 -90
  22. package/dist/src/runtime/reorg.js.map +7 -8
  23. package/dist/src/runtime/runner.d.ts +152 -42
  24. package/dist/src/runtime/runner.js +226 -30
  25. package/dist/src/runtime/runner.js.map +4 -4
  26. package/dist/src/runtime/source-matcher.d.ts +88 -31
  27. package/dist/src/runtime/source-matcher.js +171 -61
  28. package/dist/src/runtime/source-matcher.js.map +4 -5
  29. package/dist/src/schema/index.d.ts +110 -20
  30. package/dist/src/schema/index.js +34 -9
  31. package/dist/src/schema/index.js.map +3 -3
  32. package/dist/src/service.js +457 -94
  33. package/dist/src/service.js.map +8 -9
  34. package/dist/src/templates.js +52 -51
  35. package/dist/src/templates.js.map +3 -3
  36. package/dist/src/types.d.ts +111 -29
  37. package/dist/src/types.js +1 -20
  38. package/dist/src/types.js.map +3 -4
  39. package/dist/src/validate.d.ts +112 -22
  40. package/dist/src/validate.js +35 -10
  41. package/dist/src/validate.js.map +3 -3
  42. package/package.json +2 -2
@@ -2,12 +2,12 @@ import { createRequire } from "node:module";
2
2
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
3
3
 
4
4
  // src/runtime/clarity.ts
5
- import { cvToJSON, deserializeCV } from "@secondlayer/stacks/clarity";
5
+ import { cvToValue, deserializeCV } from "@secondlayer/stacks/clarity";
6
6
  function decodeClarityValue(hex) {
7
7
  try {
8
8
  const cleanHex = hex.startsWith("0x") ? hex.slice(2) : hex;
9
9
  const cv = deserializeCV(cleanHex);
10
- return cvToJSON(cv);
10
+ return cvToValue(cv);
11
11
  } catch {
12
12
  return hex;
13
13
  }
@@ -36,19 +36,210 @@ function decodeFunctionArgs(args) {
36
36
  import { getErrorMessage } from "@secondlayer/shared";
37
37
  import { logger } from "@secondlayer/shared/logger";
38
38
  var DEFAULT_ERROR_THRESHOLD = 50;
39
- function resolveHandler(handlers, key) {
40
- return handlers[key] ?? handlers["*"] ?? null;
39
+ function camelCase(str) {
40
+ return str.replace(/-([a-z0-9])/g, (_, c) => c.toUpperCase());
41
+ }
42
+ function camelizeKeys(obj) {
43
+ if (obj === null || obj === undefined)
44
+ return obj;
45
+ if (typeof obj !== "object")
46
+ return obj;
47
+ if (Array.isArray(obj))
48
+ return obj.map(camelizeKeys);
49
+ const result = {};
50
+ for (const [k, v] of Object.entries(obj)) {
51
+ result[camelCase(k)] = camelizeKeys(v);
52
+ }
53
+ return result;
54
+ }
55
+ function decodeFunctionArgs2(args) {
56
+ if (!Array.isArray(args))
57
+ return [];
58
+ return args.map((arg) => {
59
+ if (typeof arg === "string")
60
+ return decodeClarityValue(arg);
61
+ return arg;
62
+ });
63
+ }
64
+ function decodeRawResult(raw) {
65
+ if (typeof raw === "string" && raw.length > 2) {
66
+ return decodeClarityValue(raw);
67
+ }
68
+ return null;
69
+ }
70
+ function safeBigInt(val) {
71
+ if (typeof val === "bigint")
72
+ return val;
73
+ if (typeof val === "number")
74
+ return BigInt(val);
75
+ if (typeof val === "string") {
76
+ try {
77
+ return BigInt(val);
78
+ } catch {
79
+ return 0n;
80
+ }
81
+ }
82
+ return 0n;
83
+ }
84
+ function buildEventPayload(filter, tx, event) {
85
+ const txMeta = {
86
+ txId: tx.tx_id,
87
+ sender: tx.sender,
88
+ type: tx.type,
89
+ status: tx.status,
90
+ contractId: tx.contract_id ?? null,
91
+ functionName: tx.function_name ?? null
92
+ };
93
+ const decodedArgs = decodeFunctionArgs2(tx.function_args);
94
+ const decodedResult = decodeRawResult(tx.raw_result);
95
+ if (!event) {
96
+ switch (filter.type) {
97
+ case "contract_call":
98
+ return {
99
+ contractId: tx.contract_id ?? "",
100
+ functionName: tx.function_name ?? "",
101
+ caller: tx.sender,
102
+ args: decodedArgs,
103
+ result: decodedResult,
104
+ tx: txMeta
105
+ };
106
+ case "contract_deploy":
107
+ return {
108
+ contractId: tx.contract_id ?? "",
109
+ deployer: tx.sender,
110
+ tx: txMeta
111
+ };
112
+ default:
113
+ return { tx: txMeta };
114
+ }
115
+ }
116
+ const decoded = decodeEventData(event.data);
117
+ switch (filter.type) {
118
+ case "ft_transfer":
119
+ return {
120
+ sender: decoded.sender,
121
+ recipient: decoded.recipient,
122
+ amount: safeBigInt(decoded.amount),
123
+ assetIdentifier: decoded.asset_identifier,
124
+ tx: txMeta
125
+ };
126
+ case "ft_mint":
127
+ return {
128
+ recipient: decoded.recipient,
129
+ amount: safeBigInt(decoded.amount),
130
+ assetIdentifier: decoded.asset_identifier,
131
+ tx: txMeta
132
+ };
133
+ case "ft_burn":
134
+ return {
135
+ sender: decoded.sender,
136
+ amount: safeBigInt(decoded.amount),
137
+ assetIdentifier: decoded.asset_identifier,
138
+ tx: txMeta
139
+ };
140
+ case "nft_transfer":
141
+ return {
142
+ sender: decoded.sender,
143
+ recipient: decoded.recipient,
144
+ tokenId: decoded.value,
145
+ assetIdentifier: decoded.asset_identifier,
146
+ tx: txMeta
147
+ };
148
+ case "nft_mint":
149
+ return {
150
+ recipient: decoded.recipient,
151
+ tokenId: decoded.value,
152
+ assetIdentifier: decoded.asset_identifier,
153
+ tx: txMeta
154
+ };
155
+ case "nft_burn":
156
+ return {
157
+ sender: decoded.sender,
158
+ tokenId: decoded.value,
159
+ assetIdentifier: decoded.asset_identifier,
160
+ tx: txMeta
161
+ };
162
+ case "stx_transfer":
163
+ return {
164
+ sender: decoded.sender,
165
+ recipient: decoded.recipient,
166
+ amount: safeBigInt(decoded.amount),
167
+ memo: decoded.memo ?? "",
168
+ tx: txMeta
169
+ };
170
+ case "stx_mint":
171
+ return {
172
+ recipient: decoded.recipient,
173
+ amount: safeBigInt(decoded.amount),
174
+ tx: txMeta
175
+ };
176
+ case "stx_burn":
177
+ return {
178
+ sender: decoded.sender,
179
+ amount: safeBigInt(decoded.amount),
180
+ tx: txMeta
181
+ };
182
+ case "stx_lock":
183
+ return {
184
+ lockedAddress: decoded.locked_address,
185
+ lockedAmount: safeBigInt(decoded.locked_amount),
186
+ unlockHeight: safeBigInt(decoded.unlock_height),
187
+ tx: txMeta
188
+ };
189
+ case "print_event": {
190
+ const rawValue = decoded.value;
191
+ const clarityObj = rawValue && typeof rawValue === "object" && !Array.isArray(rawValue) ? rawValue : null;
192
+ const topic = clarityObj?.topic ? String(clarityObj.topic) : decoded.topic ?? "";
193
+ const { topic: _, ...rest } = clarityObj ?? {};
194
+ const data = Object.keys(rest).length > 0 ? camelizeKeys(rest) : rawValue && typeof rawValue !== "object" ? rawValue : {};
195
+ return {
196
+ contractId: decoded.contract_identifier ?? tx.contract_id ?? "",
197
+ topic,
198
+ data: data ?? {},
199
+ tx: txMeta
200
+ };
201
+ }
202
+ case "contract_call":
203
+ return {
204
+ ...decoded,
205
+ _eventType: event.type,
206
+ contractId: tx.contract_id ?? "",
207
+ functionName: tx.function_name ?? "",
208
+ caller: tx.sender,
209
+ args: decodedArgs,
210
+ result: decodedResult,
211
+ tx: txMeta
212
+ };
213
+ case "contract_deploy":
214
+ return {
215
+ contractId: tx.contract_id ?? "",
216
+ deployer: tx.sender,
217
+ tx: txMeta
218
+ };
219
+ default:
220
+ return {
221
+ ...decoded,
222
+ _eventType: event.type,
223
+ tx: txMeta
224
+ };
225
+ }
41
226
  }
42
227
  async function runHandlers(subgraph, matched, ctx, opts) {
43
228
  let processed = 0;
44
229
  let errors = 0;
45
230
  const threshold = opts?.errorThreshold ?? DEFAULT_ERROR_THRESHOLD;
46
- for (const { tx, events, sourceKey } of matched) {
47
- const handler = resolveHandler(subgraph.handlers, sourceKey);
231
+ const filterLookup = new Map;
232
+ if (!Array.isArray(subgraph.sources)) {
233
+ for (const [name, filter] of Object.entries(subgraph.sources)) {
234
+ filterLookup.set(name, filter);
235
+ }
236
+ }
237
+ for (const { tx, events, sourceName } of matched) {
238
+ const handler = subgraph.handlers[sourceName] ?? subgraph.handlers["*"] ?? null;
48
239
  if (!handler) {
49
- logger.warn("No handler found for source key", {
240
+ logger.warn("No handler found for source", {
50
241
  subgraph: subgraph.name,
51
- sourceKey,
242
+ sourceName,
52
243
  txId: tx.tx_id
53
244
  });
54
245
  continue;
@@ -57,11 +248,14 @@ async function runHandlers(subgraph, matched, ctx, opts) {
57
248
  txId: tx.tx_id,
58
249
  sender: tx.sender,
59
250
  type: tx.type,
60
- status: tx.status
251
+ status: tx.status,
252
+ contractId: tx.contract_id ?? null,
253
+ functionName: tx.function_name ?? null
61
254
  });
255
+ const filter = filterLookup.get(sourceName);
62
256
  if (events.length === 0) {
63
257
  try {
64
- const txPayload = {
258
+ const payload = filter ? buildEventPayload(filter, tx, null) : {
65
259
  tx: {
66
260
  txId: tx.tx_id,
67
261
  sender: tx.sender,
@@ -71,13 +265,13 @@ async function runHandlers(subgraph, matched, ctx, opts) {
71
265
  functionName: tx.function_name
72
266
  }
73
267
  };
74
- await handler(txPayload, ctx);
268
+ await handler(payload, ctx);
75
269
  processed++;
76
270
  } catch (err) {
77
271
  errors++;
78
272
  logger.error("Subgraph handler error", {
79
273
  subgraph: subgraph.name,
80
- sourceKey,
274
+ sourceName,
81
275
  txId: tx.tx_id,
82
276
  error: getErrorMessage(err)
83
277
  });
@@ -94,28 +288,30 @@ async function runHandlers(subgraph, matched, ctx, opts) {
94
288
  return { processed, errors };
95
289
  }
96
290
  try {
97
- const decoded = decodeEventData(event.data);
98
- const eventPayload = {
99
- ...decoded,
100
- _eventId: event.id,
101
- _eventType: event.type,
102
- _eventIndex: event.event_index,
103
- tx: {
104
- txId: tx.tx_id,
105
- sender: tx.sender,
106
- type: tx.type,
107
- status: tx.status,
108
- contractId: tx.contract_id,
109
- functionName: tx.function_name
110
- }
111
- };
112
- await handler(eventPayload, ctx);
291
+ const payload = filter ? buildEventPayload(filter, tx, event) : (() => {
292
+ const decoded = decodeEventData(event.data);
293
+ return {
294
+ ...decoded,
295
+ _eventId: event.id,
296
+ _eventType: event.type,
297
+ _eventIndex: event.event_index,
298
+ tx: {
299
+ txId: tx.tx_id,
300
+ sender: tx.sender,
301
+ type: tx.type,
302
+ status: tx.status,
303
+ contractId: tx.contract_id,
304
+ functionName: tx.function_name
305
+ }
306
+ };
307
+ })();
308
+ await handler(payload, ctx);
113
309
  processed++;
114
310
  } catch (err) {
115
311
  errors++;
116
312
  logger.error("Subgraph handler error", {
117
313
  subgraph: subgraph.name,
118
- sourceKey,
314
+ sourceName,
119
315
  txId: tx.tx_id,
120
316
  eventId: event.id,
121
317
  eventType: event.type,
@@ -130,5 +326,5 @@ export {
130
326
  runHandlers
131
327
  };
132
328
 
133
- //# debugId=611E9DD629D6006D64756E2164756E21
329
+ //# debugId=01230613471884DF64756E2164756E21
134
330
  //# sourceMappingURL=runner.js.map
@@ -2,10 +2,10 @@
2
2
  "version": 3,
3
3
  "sources": ["../src/runtime/clarity.ts", "../src/runtime/runner.ts"],
4
4
  "sourcesContent": [
5
- "import { cvToJSON, deserializeCV } from \"@secondlayer/stacks/clarity\";\n\n/**\n * Decode a hex-encoded Clarity value to a JS object.\n * Returns original value on failure.\n */\nexport function decodeClarityValue(hex: string): unknown {\n\ttry {\n\t\tconst cleanHex = hex.startsWith(\"0x\") ? hex.slice(2) : hex;\n\t\tconst cv = deserializeCV(cleanHex);\n\t\treturn cvToJSON(cv);\n\t} catch {\n\t\treturn hex;\n\t}\n}\n\n/**\n * Recursively decode all hex-encoded Clarity values in an object.\n * Any string starting with \"0x\" and longer than 10 chars is attempted.\n */\nexport function decodeEventData(data: unknown): unknown {\n\tif (typeof data === \"string\" && data.startsWith(\"0x\") && data.length > 10) {\n\t\treturn decodeClarityValue(data);\n\t}\n\n\tif (Array.isArray(data)) {\n\t\treturn data.map(decodeEventData);\n\t}\n\n\tif (typeof data === \"object\" && data !== null) {\n\t\tconst decoded: Record<string, unknown> = {};\n\t\tfor (const [key, value] of Object.entries(data)) {\n\t\t\tdecoded[key] = decodeEventData(value);\n\t\t}\n\t\treturn decoded;\n\t}\n\n\treturn data;\n}\n\n/**\n * Decode function args array (hex-encoded Clarity values).\n */\nexport function decodeFunctionArgs(args: string[]): unknown[] {\n\treturn args.map(decodeClarityValue);\n}\n",
6
- "import { getErrorMessage } from \"@secondlayer/shared\";\nimport { logger } from \"@secondlayer/shared/logger\";\nimport type { SubgraphDefinition } from \"../types.ts\";\nimport { decodeEventData } from \"./clarity.ts\";\nimport type { SubgraphContext } from \"./context.ts\";\nimport type { MatchedTx } from \"./source-matcher.ts\";\n\n/** Max consecutive handler errors before marking subgraph as error */\nconst DEFAULT_ERROR_THRESHOLD = 50;\n\nexport interface RunResult {\n\tprocessed: number;\n\terrors: number;\n}\n\n/**\n * Resolve the handler for a matched tx.\n * Looks up by sourceKey first, then falls back to \"*\" catch-all.\n */\nfunction resolveHandler(handlers: SubgraphDefinition[\"handlers\"], key: string) {\n\treturn handlers[key] ?? handlers[\"*\"] ?? null;\n}\n\n/**\n * Run a subgraph's keyed handlers against all matched transactions/events.\n *\n * Each MatchedTx carries a sourceKey from the matcher. The runner looks up\n * the corresponding handler in subgraph.handlers, falling back to \"*\".\n *\n * Does NOT flush — caller is responsible for flushing ctx after run.\n */\nexport async function runHandlers(\n\tsubgraph: SubgraphDefinition,\n\tmatched: MatchedTx[],\n\tctx: SubgraphContext,\n\topts?: { errorThreshold?: number },\n): Promise<RunResult> {\n\tlet processed = 0;\n\tlet errors = 0;\n\tconst threshold = opts?.errorThreshold ?? DEFAULT_ERROR_THRESHOLD;\n\n\tfor (const { tx, events, sourceKey } of matched) {\n\t\tconst handler = resolveHandler(subgraph.handlers, sourceKey);\n\t\tif (!handler) {\n\t\t\tlogger.warn(\"No handler found for source key\", {\n\t\t\t\tsubgraph: subgraph.name,\n\t\t\t\tsourceKey,\n\t\t\t\ttxId: tx.tx_id,\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\n\t\tctx.setTx({\n\t\t\ttxId: tx.tx_id,\n\t\t\tsender: tx.sender,\n\t\t\ttype: tx.type,\n\t\t\tstatus: tx.status,\n\t\t});\n\n\t\t// If no events but tx matched, call handler with tx-level data\n\t\tif (events.length === 0) {\n\t\t\ttry {\n\t\t\t\tconst txPayload: Record<string, unknown> = {\n\t\t\t\t\ttx: {\n\t\t\t\t\t\ttxId: tx.tx_id,\n\t\t\t\t\t\tsender: tx.sender,\n\t\t\t\t\t\ttype: tx.type,\n\t\t\t\t\t\tstatus: tx.status,\n\t\t\t\t\t\tcontractId: tx.contract_id,\n\t\t\t\t\t\tfunctionName: tx.function_name,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t\tawait handler(txPayload, ctx);\n\t\t\t\tprocessed++;\n\t\t\t} catch (err) {\n\t\t\t\terrors++;\n\t\t\t\tlogger.error(\"Subgraph handler error\", {\n\t\t\t\t\tsubgraph: subgraph.name,\n\t\t\t\t\tsourceKey,\n\t\t\t\t\ttxId: tx.tx_id,\n\t\t\t\t\terror: getErrorMessage(err),\n\t\t\t\t});\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tfor (const event of events) {\n\t\t\tif (errors >= threshold) {\n\t\t\t\tlogger.error(\n\t\t\t\t\t\"Subgraph error threshold reached, skipping remaining events\",\n\t\t\t\t\t{\n\t\t\t\t\t\tsubgraph: subgraph.name,\n\t\t\t\t\t\terrors,\n\t\t\t\t\t\tthreshold,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\treturn { processed, errors };\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst decoded = decodeEventData(event.data) as Record<string, unknown>;\n\t\t\t\tconst eventPayload: Record<string, unknown> = {\n\t\t\t\t\t...decoded,\n\t\t\t\t\t_eventId: event.id,\n\t\t\t\t\t_eventType: event.type,\n\t\t\t\t\t_eventIndex: event.event_index,\n\t\t\t\t\ttx: {\n\t\t\t\t\t\ttxId: tx.tx_id,\n\t\t\t\t\t\tsender: tx.sender,\n\t\t\t\t\t\ttype: tx.type,\n\t\t\t\t\t\tstatus: tx.status,\n\t\t\t\t\t\tcontractId: tx.contract_id,\n\t\t\t\t\t\tfunctionName: tx.function_name,\n\t\t\t\t\t},\n\t\t\t\t};\n\n\t\t\t\tawait handler(eventPayload, ctx);\n\t\t\t\tprocessed++;\n\t\t\t} catch (err) {\n\t\t\t\terrors++;\n\t\t\t\tlogger.error(\"Subgraph handler error\", {\n\t\t\t\t\tsubgraph: subgraph.name,\n\t\t\t\t\tsourceKey,\n\t\t\t\t\ttxId: tx.tx_id,\n\t\t\t\t\teventId: event.id,\n\t\t\t\t\teventType: event.type,\n\t\t\t\t\terror: getErrorMessage(err),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { processed, errors };\n}\n"
5
+ "import { cvToValue, deserializeCV } from \"@secondlayer/stacks/clarity\";\n\n/**\n * Decode a hex-encoded Clarity value to a JS object.\n * Returns original value on failure.\n */\nexport function decodeClarityValue(hex: string): unknown {\n\ttry {\n\t\tconst cleanHex = hex.startsWith(\"0x\") ? hex.slice(2) : hex;\n\t\tconst cv = deserializeCV(cleanHex);\n\t\treturn cvToValue(cv);\n\t} catch {\n\t\treturn hex;\n\t}\n}\n\n/**\n * Recursively decode all hex-encoded Clarity values in an object.\n * Any string starting with \"0x\" and longer than 10 chars is attempted.\n */\nexport function decodeEventData(data: unknown): unknown {\n\tif (typeof data === \"string\" && data.startsWith(\"0x\") && data.length > 10) {\n\t\treturn decodeClarityValue(data);\n\t}\n\n\tif (Array.isArray(data)) {\n\t\treturn data.map(decodeEventData);\n\t}\n\n\tif (typeof data === \"object\" && data !== null) {\n\t\tconst decoded: Record<string, unknown> = {};\n\t\tfor (const [key, value] of Object.entries(data)) {\n\t\t\tdecoded[key] = decodeEventData(value);\n\t\t}\n\t\treturn decoded;\n\t}\n\n\treturn data;\n}\n\n/**\n * Decode function args array (hex-encoded Clarity values).\n */\nexport function decodeFunctionArgs(args: string[]): unknown[] {\n\treturn args.map(decodeClarityValue);\n}\n",
6
+ "import { getErrorMessage } from \"@secondlayer/shared\";\nimport { logger } from \"@secondlayer/shared/logger\";\nimport type { SubgraphDefinition, SubgraphFilter } from \"../types.ts\";\nimport { decodeClarityValue, decodeEventData } from \"./clarity.ts\";\nimport type { SubgraphContext } from \"./context.ts\";\nimport type { MatchedTx } from \"./source-matcher.ts\";\n\n/** Max consecutive handler errors before marking subgraph as error */\nconst DEFAULT_ERROR_THRESHOLD = 50;\n\nexport interface RunResult {\n\tprocessed: number;\n\terrors: number;\n}\n\n/** Convert kebab-case to camelCase: \"bitcoin-txid\" → \"bitcoinTxid\" */\nfunction camelCase(str: string): string {\n\treturn str.replace(/-([a-z0-9])/g, (_, c) => c.toUpperCase());\n}\n\n/** Recursively camelize all object keys */\nfunction camelizeKeys(obj: unknown): unknown {\n\tif (obj === null || obj === undefined) return obj;\n\tif (typeof obj !== \"object\") return obj;\n\tif (Array.isArray(obj)) return obj.map(camelizeKeys);\n\tconst result: Record<string, unknown> = {};\n\tfor (const [k, v] of Object.entries(obj as Record<string, unknown>)) {\n\t\tresult[camelCase(k)] = camelizeKeys(v);\n\t}\n\treturn result;\n}\n\n/**\n * Decode function_args (hex-encoded ClarityValues) to an array of JS values.\n * Returns decoded values via cvToValue.\n */\nfunction decodeFunctionArgs(args: unknown): unknown[] {\n\tif (!Array.isArray(args)) return [];\n\treturn args.map((arg) => {\n\t\tif (typeof arg === \"string\") return decodeClarityValue(arg);\n\t\treturn arg;\n\t});\n}\n\n/**\n * Decode raw_result (hex-encoded Clarity return value) to JS value.\n */\nfunction decodeRawResult(raw: unknown): unknown {\n\tif (typeof raw === \"string\" && raw.length > 2) {\n\t\treturn decodeClarityValue(raw);\n\t}\n\treturn null;\n}\n\n/** Safely convert a value to BigInt. Handles string, number, bigint. Returns 0n on failure. */\nfunction safeBigInt(val: unknown): bigint {\n\tif (typeof val === \"bigint\") return val;\n\tif (typeof val === \"number\") return BigInt(val);\n\tif (typeof val === \"string\") {\n\t\ttry {\n\t\t\treturn BigInt(val);\n\t\t} catch {\n\t\t\treturn 0n;\n\t\t}\n\t}\n\treturn 0n;\n}\n\n/**\n * Build a typed event payload based on the source filter type.\n * Returns the payload the handler will receive.\n */\nfunction buildEventPayload(\n\tfilter: SubgraphFilter,\n\ttx: MatchedTx[\"tx\"],\n\tevent: MatchedTx[\"events\"][0] | null,\n): Record<string, unknown> {\n\tconst txMeta = {\n\t\ttxId: tx.tx_id,\n\t\tsender: tx.sender,\n\t\ttype: tx.type,\n\t\tstatus: tx.status,\n\t\tcontractId: tx.contract_id ?? null,\n\t\tfunctionName: tx.function_name ?? null,\n\t};\n\n\t// Decoded function args + result for contract_call payloads\n\tconst decodedArgs = decodeFunctionArgs(tx.function_args);\n\tconst decodedResult = decodeRawResult(tx.raw_result);\n\n\t// No event — tx-level match (contract_call or contract_deploy)\n\tif (!event) {\n\t\tswitch (filter.type) {\n\t\t\tcase \"contract_call\":\n\t\t\t\treturn {\n\t\t\t\t\tcontractId: tx.contract_id ?? \"\",\n\t\t\t\t\tfunctionName: tx.function_name ?? \"\",\n\t\t\t\t\tcaller: tx.sender,\n\t\t\t\t\targs: decodedArgs,\n\t\t\t\t\tresult: decodedResult,\n\t\t\t\t\ttx: txMeta,\n\t\t\t\t};\n\t\t\tcase \"contract_deploy\":\n\t\t\t\treturn {\n\t\t\t\t\tcontractId: tx.contract_id ?? \"\",\n\t\t\t\t\tdeployer: tx.sender,\n\t\t\t\t\ttx: txMeta,\n\t\t\t\t};\n\t\t\tdefault:\n\t\t\t\treturn { tx: txMeta };\n\t\t}\n\t}\n\n\t// Decode event data (Clarity values auto-unwrapped via cvToValue)\n\tconst decoded = decodeEventData(event.data) as Record<string, unknown>;\n\n\tswitch (filter.type) {\n\t\t// ── FT events ──\n\t\tcase \"ft_transfer\":\n\t\t\treturn {\n\t\t\t\tsender: decoded.sender as string,\n\t\t\t\trecipient: decoded.recipient as string,\n\t\t\t\tamount: safeBigInt(decoded.amount),\n\t\t\t\tassetIdentifier: decoded.asset_identifier as string,\n\t\t\t\ttx: txMeta,\n\t\t\t};\n\t\tcase \"ft_mint\":\n\t\t\treturn {\n\t\t\t\trecipient: decoded.recipient as string,\n\t\t\t\tamount: safeBigInt(decoded.amount),\n\t\t\t\tassetIdentifier: decoded.asset_identifier as string,\n\t\t\t\ttx: txMeta,\n\t\t\t};\n\t\tcase \"ft_burn\":\n\t\t\treturn {\n\t\t\t\tsender: decoded.sender as string,\n\t\t\t\tamount: safeBigInt(decoded.amount),\n\t\t\t\tassetIdentifier: decoded.asset_identifier as string,\n\t\t\t\ttx: txMeta,\n\t\t\t};\n\n\t\t// ── NFT events ──\n\t\tcase \"nft_transfer\":\n\t\t\treturn {\n\t\t\t\tsender: decoded.sender as string,\n\t\t\t\trecipient: decoded.recipient as string,\n\t\t\t\ttokenId: decoded.value,\n\t\t\t\tassetIdentifier: decoded.asset_identifier as string,\n\t\t\t\ttx: txMeta,\n\t\t\t};\n\t\tcase \"nft_mint\":\n\t\t\treturn {\n\t\t\t\trecipient: decoded.recipient as string,\n\t\t\t\ttokenId: decoded.value,\n\t\t\t\tassetIdentifier: decoded.asset_identifier as string,\n\t\t\t\ttx: txMeta,\n\t\t\t};\n\t\tcase \"nft_burn\":\n\t\t\treturn {\n\t\t\t\tsender: decoded.sender as string,\n\t\t\t\ttokenId: decoded.value,\n\t\t\t\tassetIdentifier: decoded.asset_identifier as string,\n\t\t\t\ttx: txMeta,\n\t\t\t};\n\n\t\t// ── STX events ──\n\t\tcase \"stx_transfer\":\n\t\t\treturn {\n\t\t\t\tsender: decoded.sender as string,\n\t\t\t\trecipient: decoded.recipient as string,\n\t\t\t\tamount: safeBigInt(decoded.amount),\n\t\t\t\tmemo: decoded.memo ?? \"\",\n\t\t\t\ttx: txMeta,\n\t\t\t};\n\t\tcase \"stx_mint\":\n\t\t\treturn {\n\t\t\t\trecipient: decoded.recipient as string,\n\t\t\t\tamount: safeBigInt(decoded.amount),\n\t\t\t\ttx: txMeta,\n\t\t\t};\n\t\tcase \"stx_burn\":\n\t\t\treturn {\n\t\t\t\tsender: decoded.sender as string,\n\t\t\t\tamount: safeBigInt(decoded.amount),\n\t\t\t\ttx: txMeta,\n\t\t\t};\n\t\tcase \"stx_lock\":\n\t\t\treturn {\n\t\t\t\tlockedAddress: decoded.locked_address as string,\n\t\t\t\tlockedAmount: safeBigInt(decoded.locked_amount),\n\t\t\t\tunlockHeight: safeBigInt(decoded.unlock_height),\n\t\t\t\ttx: txMeta,\n\t\t\t};\n\n\t\t// ── Print event ──\n\t\tcase \"print_event\": {\n\t\t\tconst rawValue = decoded.value;\n\t\t\t// Extract topic from decoded Clarity value (not raw event topic which is always \"print\")\n\t\t\tconst clarityObj =\n\t\t\t\trawValue && typeof rawValue === \"object\" && !Array.isArray(rawValue)\n\t\t\t\t\t? (rawValue as Record<string, unknown>)\n\t\t\t\t\t: null;\n\t\t\tconst topic = clarityObj?.topic\n\t\t\t\t? String(clarityObj.topic)\n\t\t\t\t: ((decoded.topic as string) ?? \"\");\n\t\t\t// Camelize remaining keys for developer convenience\n\t\t\tconst { topic: _, ...rest } = clarityObj ?? {};\n\t\t\tconst data = Object.keys(rest).length > 0\n\t\t\t\t? (camelizeKeys(rest) as Record<string, unknown>)\n\t\t\t\t: rawValue && typeof rawValue !== \"object\"\n\t\t\t\t\t? rawValue\n\t\t\t\t\t: {};\n\t\t\treturn {\n\t\t\t\tcontractId: decoded.contract_identifier as string ?? tx.contract_id ?? \"\",\n\t\t\t\ttopic,\n\t\t\t\tdata: data ?? {},\n\t\t\t\ttx: txMeta,\n\t\t\t};\n\t\t}\n\n\t\t// ── Contract call (with events) ──\n\t\tcase \"contract_call\":\n\t\t\treturn {\n\t\t\t\t...decoded,\n\t\t\t\t_eventType: event.type,\n\t\t\t\tcontractId: tx.contract_id ?? \"\",\n\t\t\t\tfunctionName: tx.function_name ?? \"\",\n\t\t\t\tcaller: tx.sender,\n\t\t\t\targs: decodedArgs,\n\t\t\t\tresult: decodedResult,\n\t\t\t\ttx: txMeta,\n\t\t\t};\n\n\t\t// ── Contract deploy ──\n\t\tcase \"contract_deploy\":\n\t\t\treturn {\n\t\t\t\tcontractId: tx.contract_id ?? \"\",\n\t\t\t\tdeployer: tx.sender,\n\t\t\t\ttx: txMeta,\n\t\t\t};\n\n\t\tdefault:\n\t\t\t// Fallback: spread decoded data with tx metadata\n\t\t\treturn {\n\t\t\t\t...decoded,\n\t\t\t\t_eventType: event.type,\n\t\t\t\ttx: txMeta,\n\t\t\t};\n\t}\n}\n\n/**\n * Run a subgraph's keyed handlers against all matched transactions/events.\n *\n * Each MatchedTx carries a sourceName from the matcher. The runner looks up\n * the corresponding handler in subgraph.handlers, falling back to \"*\".\n *\n * Does NOT flush — caller is responsible for flushing ctx after run.\n */\nexport async function runHandlers(\n\tsubgraph: SubgraphDefinition,\n\tmatched: MatchedTx[],\n\tctx: SubgraphContext,\n\topts?: { errorThreshold?: number },\n): Promise<RunResult> {\n\tlet processed = 0;\n\tlet errors = 0;\n\tconst threshold = opts?.errorThreshold ?? DEFAULT_ERROR_THRESHOLD;\n\n\t// Build filter lookup from sources (supports both array and named object)\n\tconst filterLookup = new Map<string, SubgraphFilter>();\n\tif (!Array.isArray(subgraph.sources)) {\n\t\tfor (const [name, filter] of Object.entries(\n\t\t\tsubgraph.sources as Record<string, SubgraphFilter>,\n\t\t)) {\n\t\t\tfilterLookup.set(name, filter);\n\t\t}\n\t}\n\n\tfor (const { tx, events, sourceName } of matched) {\n\t\tconst handler =\n\t\t\tsubgraph.handlers[sourceName] ?? subgraph.handlers[\"*\"] ?? null;\n\t\tif (!handler) {\n\t\t\tlogger.warn(\"No handler found for source\", {\n\t\t\t\tsubgraph: subgraph.name,\n\t\t\t\tsourceName,\n\t\t\t\ttxId: tx.tx_id,\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\n\t\tctx.setTx({\n\t\t\ttxId: tx.tx_id,\n\t\t\tsender: tx.sender,\n\t\t\ttype: tx.type,\n\t\t\tstatus: tx.status,\n\t\t\tcontractId: tx.contract_id ?? null,\n\t\t\tfunctionName: tx.function_name ?? null,\n\t\t});\n\n\t\tconst filter = filterLookup.get(sourceName);\n\n\t\t// If no events but tx matched, call handler with tx-level data\n\t\tif (events.length === 0) {\n\t\t\ttry {\n\t\t\t\tconst payload = filter\n\t\t\t\t\t? buildEventPayload(filter, tx, null)\n\t\t\t\t\t: {\n\t\t\t\t\t\t\ttx: {\n\t\t\t\t\t\t\t\ttxId: tx.tx_id,\n\t\t\t\t\t\t\t\tsender: tx.sender,\n\t\t\t\t\t\t\t\ttype: tx.type,\n\t\t\t\t\t\t\t\tstatus: tx.status,\n\t\t\t\t\t\t\t\tcontractId: tx.contract_id,\n\t\t\t\t\t\t\t\tfunctionName: tx.function_name,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t};\n\t\t\t\tawait handler(payload, ctx);\n\t\t\t\tprocessed++;\n\t\t\t} catch (err) {\n\t\t\t\terrors++;\n\t\t\t\tlogger.error(\"Subgraph handler error\", {\n\t\t\t\t\tsubgraph: subgraph.name,\n\t\t\t\t\tsourceName,\n\t\t\t\t\ttxId: tx.tx_id,\n\t\t\t\t\terror: getErrorMessage(err),\n\t\t\t\t});\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tfor (const event of events) {\n\t\t\tif (errors >= threshold) {\n\t\t\t\tlogger.error(\n\t\t\t\t\t\"Subgraph error threshold reached, skipping remaining events\",\n\t\t\t\t\t{\n\t\t\t\t\t\tsubgraph: subgraph.name,\n\t\t\t\t\t\terrors,\n\t\t\t\t\t\tthreshold,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\treturn { processed, errors };\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst payload = filter\n\t\t\t\t\t? buildEventPayload(filter, tx, event)\n\t\t\t\t\t: (() => {\n\t\t\t\t\t\t\tconst decoded = decodeEventData(event.data) as Record<\n\t\t\t\t\t\t\t\tstring,\n\t\t\t\t\t\t\t\tunknown\n\t\t\t\t\t\t\t>;\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\t...decoded,\n\t\t\t\t\t\t\t\t_eventId: event.id,\n\t\t\t\t\t\t\t\t_eventType: event.type,\n\t\t\t\t\t\t\t\t_eventIndex: event.event_index,\n\t\t\t\t\t\t\t\ttx: {\n\t\t\t\t\t\t\t\t\ttxId: tx.tx_id,\n\t\t\t\t\t\t\t\t\tsender: tx.sender,\n\t\t\t\t\t\t\t\t\ttype: tx.type,\n\t\t\t\t\t\t\t\t\tstatus: tx.status,\n\t\t\t\t\t\t\t\t\tcontractId: tx.contract_id,\n\t\t\t\t\t\t\t\t\tfunctionName: tx.function_name,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t})();\n\n\t\t\t\tawait handler(payload, ctx);\n\t\t\t\tprocessed++;\n\t\t\t} catch (err) {\n\t\t\t\terrors++;\n\t\t\t\tlogger.error(\"Subgraph handler error\", {\n\t\t\t\t\tsubgraph: subgraph.name,\n\t\t\t\t\tsourceName,\n\t\t\t\t\ttxId: tx.tx_id,\n\t\t\t\t\teventId: event.id,\n\t\t\t\t\teventType: event.type,\n\t\t\t\t\terror: getErrorMessage(err),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { processed, errors };\n}\n"
7
7
  ],
8
- "mappings": "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",
9
- "debugId": "611E9DD629D6006D64756E2164756E21",
8
+ "mappings": "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",
9
+ "debugId": "01230613471884DF64756E2164756E21",
10
10
  "names": []
11
11
  }
@@ -1,34 +1,89 @@
1
- /** Source filter for what blockchain data this subgraph processes */
2
- interface SubgraphSource {
3
- /** Contract principal (e.g., SP000...::contract-name). Supports * wildcards. */
4
- contract?: string;
5
- /** Event name/topic to filter on */
6
- event?: string;
7
- /** Function name to filter on */
8
- function?: string;
9
- /** Transaction type filter (e.g., "stx_transfer", "contract_call") */
10
- type?: string;
11
- /** Minimum amount filter (for stx_transfer sources) */
1
+ /** STX event filters */
2
+ interface StxTransferFilter {
3
+ type: "stx_transfer";
4
+ sender?: string;
5
+ recipient?: string;
12
6
  minAmount?: bigint;
7
+ maxAmount?: bigint;
13
8
  }
9
+ interface StxMintFilter {
10
+ type: "stx_mint";
11
+ recipient?: string;
12
+ minAmount?: bigint;
13
+ }
14
+ interface StxBurnFilter {
15
+ type: "stx_burn";
16
+ sender?: string;
17
+ minAmount?: bigint;
18
+ }
19
+ interface StxLockFilter {
20
+ type: "stx_lock";
21
+ lockedAddress?: string;
22
+ minAmount?: bigint;
23
+ }
24
+ /** FT event filters */
25
+ interface FtTransferFilter {
26
+ type: "ft_transfer";
27
+ assetIdentifier?: string;
28
+ sender?: string;
29
+ recipient?: string;
30
+ minAmount?: bigint;
31
+ }
32
+ interface FtMintFilter {
33
+ type: "ft_mint";
34
+ assetIdentifier?: string;
35
+ recipient?: string;
36
+ minAmount?: bigint;
37
+ }
38
+ interface FtBurnFilter {
39
+ type: "ft_burn";
40
+ assetIdentifier?: string;
41
+ sender?: string;
42
+ minAmount?: bigint;
43
+ }
44
+ /** NFT event filters */
45
+ interface NftTransferFilter {
46
+ type: "nft_transfer";
47
+ assetIdentifier?: string;
48
+ sender?: string;
49
+ recipient?: string;
50
+ }
51
+ interface NftMintFilter {
52
+ type: "nft_mint";
53
+ assetIdentifier?: string;
54
+ recipient?: string;
55
+ }
56
+ interface NftBurnFilter {
57
+ type: "nft_burn";
58
+ assetIdentifier?: string;
59
+ sender?: string;
60
+ }
61
+ /** Contract event filters */
62
+ interface ContractCallFilter {
63
+ type: "contract_call";
64
+ contractId?: string;
65
+ functionName?: string;
66
+ caller?: string;
67
+ /** ABI for typed event.args. If omitted, auto-fetched at deploy time. */
68
+ abi?: Record<string, unknown>;
69
+ }
70
+ interface ContractDeployFilter {
71
+ type: "contract_deploy";
72
+ deployer?: string;
73
+ contractName?: string;
74
+ }
75
+ interface PrintEventFilter {
76
+ type: "print_event";
77
+ contractId?: string;
78
+ topic?: string;
79
+ }
80
+ /** All subgraph filter types — discriminated on `type` */
81
+ type SubgraphFilter = StxTransferFilter | StxMintFilter | StxBurnFilter | StxLockFilter | FtTransferFilter | FtMintFilter | FtBurnFilter | NftTransferFilter | NftMintFilter | NftBurnFilter | ContractCallFilter | ContractDeployFilter | PrintEventFilter;
14
82
  interface MatchedTx {
15
- tx: {
16
- tx_id: string
17
- type: string
18
- sender: string
19
- status: string
20
- contract_id?: string | null
21
- function_name?: string | null
22
- };
23
- events: {
24
- id: string
25
- tx_id: string
26
- type: string
27
- event_index: number
28
- data: unknown
29
- }[];
30
- /** Which source produced this match — used for handler dispatch */
31
- sourceKey: string;
83
+ tx: TxRecord;
84
+ events: EventRecord[];
85
+ /** Source object key — used for handler dispatch */
86
+ sourceName: string;
32
87
  }
33
88
  type TxRecord = {
34
89
  tx_id: string
@@ -37,6 +92,8 @@ type TxRecord = {
37
92
  status: string
38
93
  contract_id?: string | null
39
94
  function_name?: string | null
95
+ function_args?: unknown | null
96
+ raw_result?: string | null
40
97
  };
41
98
  type EventRecord = {
42
99
  id: string
@@ -46,8 +103,8 @@ type EventRecord = {
46
103
  data: unknown
47
104
  };
48
105
  /**
49
- * Match all sources against a block's transactions and events.
50
- * Deduplicates by (txId, sourceKey) each handler key fires at most once per tx.
106
+ * Match named filters against a block's transactions and events.
107
+ * Returns matches with sourceName = the object key from sources.
51
108
  */
52
- declare function matchSources(sources: SubgraphSource[], transactions: TxRecord[], events: EventRecord[]): MatchedTx[];
109
+ declare function matchSources(sources: Record<string, SubgraphFilter>, transactions: TxRecord[], events: EventRecord[]): MatchedTx[];
53
110
  export { matchSources, MatchedTx };