@secondlayer/shared 0.5.0 → 0.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.
Files changed (39) hide show
  1. package/dist/src/crypto/hmac.d.ts +1 -1
  2. package/dist/src/crypto/hmac.js.map +1 -1
  3. package/dist/src/db/index.d.ts +2 -2
  4. package/dist/src/db/queries/accounts.d.ts +2 -2
  5. package/dist/src/db/queries/integrity.d.ts +2 -2
  6. package/dist/src/db/queries/metrics.d.ts +2 -2
  7. package/dist/src/db/queries/subgraphs.d.ts +2 -2
  8. package/dist/src/db/queries/usage.d.ts +2 -2
  9. package/dist/src/db/schema.d.ts +2 -2
  10. package/dist/src/env.d.ts +1 -1
  11. package/dist/src/env.js +3 -3
  12. package/dist/src/env.js.map +3 -3
  13. package/dist/src/errors.d.ts +3 -3
  14. package/dist/src/errors.js +4 -4
  15. package/dist/src/errors.js.map +3 -3
  16. package/dist/src/index.d.ts +15 -15
  17. package/dist/src/index.js +16 -16
  18. package/dist/src/index.js.map +8 -8
  19. package/dist/src/logger.js +3 -3
  20. package/dist/src/logger.js.map +3 -3
  21. package/dist/src/node/hiro-client.js +4 -4
  22. package/dist/src/node/hiro-client.js.map +4 -4
  23. package/dist/src/node/hiro-pg-client.d.ts +21 -0
  24. package/dist/src/node/hiro-pg-client.js +439 -0
  25. package/dist/src/node/hiro-pg-client.js.map +10 -0
  26. package/dist/src/node/local-client.d.ts +2 -2
  27. package/dist/src/node/local-client.js.map +1 -1
  28. package/dist/src/schemas/filters.d.ts +1 -1
  29. package/dist/src/schemas/filters.js +2 -2
  30. package/dist/src/schemas/filters.js.map +2 -2
  31. package/dist/src/schemas/index.d.ts +10 -10
  32. package/dist/src/schemas/index.js +11 -11
  33. package/dist/src/schemas/index.js.map +5 -5
  34. package/dist/src/schemas/subgraphs.d.ts +1 -1
  35. package/dist/src/schemas/subgraphs.js +3 -3
  36. package/dist/src/schemas/subgraphs.js.map +3 -3
  37. package/dist/src/types.d.ts +2 -2
  38. package/migrations/0016_rename_webhook_to_endpoint.ts +12 -0
  39. package/package.json +7 -3
@@ -0,0 +1,439 @@
1
+ import { createRequire } from "node:module";
2
+ var __defProp = Object.defineProperty;
3
+ var __returnValue = (v) => v;
4
+ function __exportSetter(name, newValue) {
5
+ this[name] = __returnValue.bind(null, newValue);
6
+ }
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, {
10
+ get: all[name],
11
+ enumerable: true,
12
+ configurable: true,
13
+ set: __exportSetter.bind(all, name)
14
+ });
15
+ };
16
+
17
+ // src/node/hiro-pg-client.ts
18
+ import postgres from "postgres";
19
+ var SCHEMA = "stacks_blockchain_api";
20
+ function toHex(buf) {
21
+ if (!buf)
22
+ return "0x";
23
+ return "0x" + Buffer.from(buf).toString("hex");
24
+ }
25
+ function stxEventType(assetTypeId) {
26
+ switch (assetTypeId) {
27
+ case 1:
28
+ return "stx_transfer_event";
29
+ case 2:
30
+ return "stx_mint_event";
31
+ case 3:
32
+ return "stx_burn_event";
33
+ default:
34
+ return "stx_transfer_event";
35
+ }
36
+ }
37
+ function ftEventType(assetTypeId) {
38
+ switch (assetTypeId) {
39
+ case 1:
40
+ return "ft_transfer_event";
41
+ case 2:
42
+ return "ft_mint_event";
43
+ case 3:
44
+ return "ft_burn_event";
45
+ default:
46
+ return "ft_transfer_event";
47
+ }
48
+ }
49
+ function nftEventType(assetTypeId) {
50
+ switch (assetTypeId) {
51
+ case 1:
52
+ return "nft_transfer_event";
53
+ case 2:
54
+ return "nft_mint_event";
55
+ case 3:
56
+ return "nft_burn_event";
57
+ default:
58
+ return "nft_transfer_event";
59
+ }
60
+ }
61
+ function mapTxTypeId(typeId) {
62
+ switch (typeId) {
63
+ case 0:
64
+ return "token_transfer";
65
+ case 1:
66
+ return "smart_contract";
67
+ case 2:
68
+ return "contract_call";
69
+ case 3:
70
+ return "poison_microblock";
71
+ case 4:
72
+ return "coinbase";
73
+ case 5:
74
+ return "coinbase";
75
+ case 6:
76
+ return "smart_contract";
77
+ case 7:
78
+ return "tenure_change";
79
+ case 8:
80
+ return "coinbase";
81
+ default:
82
+ return "token_transfer";
83
+ }
84
+ }
85
+ function mapTxStatus(status) {
86
+ switch (status) {
87
+ case 1:
88
+ return "success";
89
+ case 0:
90
+ return "abort_by_response";
91
+ default:
92
+ return "abort_by_post_condition";
93
+ }
94
+ }
95
+
96
+ class HiroPgClient {
97
+ sql;
98
+ constructor(connectionUrl) {
99
+ const url = connectionUrl || process.env.HIRO_PG_URL;
100
+ if (!url)
101
+ throw new Error("HIRO_PG_URL is required for HiroPgClient");
102
+ this.sql = postgres(url, {
103
+ max: 10,
104
+ idle_timeout: 30,
105
+ types: { bigint: postgres.BigInt }
106
+ });
107
+ }
108
+ async getChainTip() {
109
+ const rows = await this.sql`
110
+ SELECT MAX(block_height) as tip FROM ${this.sql(SCHEMA)}.blocks WHERE canonical = true
111
+ `;
112
+ return Number(rows[0]?.tip ?? 0);
113
+ }
114
+ async getBlockForIndexer(height, options) {
115
+ const blocks = await this.sql`
116
+ SELECT block_hash, block_height, index_block_hash, parent_block_hash,
117
+ parent_index_block_hash, burn_block_hash, burn_block_height,
118
+ burn_block_time, block_time, miner_txid
119
+ FROM ${this.sql(SCHEMA)}.blocks
120
+ WHERE block_height = ${height} AND canonical = true
121
+ LIMIT 1
122
+ `;
123
+ if (blocks.length === 0)
124
+ return null;
125
+ const block = blocks[0];
126
+ const txs = await this.sql`
127
+ SELECT tx_id, tx_index, type_id, status, sender_address, raw_tx, event_count,
128
+ contract_call_contract_id, contract_call_function_name, smart_contract_contract_id
129
+ FROM ${this.sql(SCHEMA)}.txs
130
+ WHERE block_height = ${height} AND canonical = true AND microblock_canonical = true
131
+ ORDER BY tx_index
132
+ `;
133
+ const transactions = txs.map((tx) => {
134
+ const txType = mapTxTypeId(tx.type_id);
135
+ const entry = {
136
+ txid: toHex(tx.tx_id),
137
+ raw_tx: options?.includeRawTx ? toHex(tx.raw_tx) : "0x00",
138
+ status: mapTxStatus(tx.status),
139
+ tx_index: tx.tx_index,
140
+ tx_type: txType,
141
+ sender_address: tx.sender_address
142
+ };
143
+ if (txType === "contract_call" && tx.contract_call_contract_id) {
144
+ entry.contract_call = {
145
+ contract_id: tx.contract_call_contract_id,
146
+ function_name: tx.contract_call_function_name || ""
147
+ };
148
+ } else if (txType === "smart_contract" && tx.smart_contract_contract_id) {
149
+ entry.smart_contract = {
150
+ contract_id: tx.smart_contract_contract_id
151
+ };
152
+ }
153
+ return entry;
154
+ });
155
+ const events = [];
156
+ const stxEvents = await this.sql`
157
+ SELECT tx_id, event_index, asset_event_type_id, amount, sender, recipient, memo
158
+ FROM ${this.sql(SCHEMA)}.stx_events
159
+ WHERE block_height = ${height} AND canonical = true AND microblock_canonical = true
160
+ ORDER BY event_index
161
+ `;
162
+ for (const e of stxEvents) {
163
+ const type = stxEventType(e.asset_event_type_id);
164
+ const evt = { txid: toHex(e.tx_id), event_index: e.event_index, committed: true, type };
165
+ if (type === "stx_transfer_event") {
166
+ evt.stx_transfer_event = {
167
+ sender: e.sender || "",
168
+ recipient: e.recipient || "",
169
+ amount: String(e.amount),
170
+ ...e.memo ? { memo: toHex(e.memo) } : {}
171
+ };
172
+ } else if (type === "stx_mint_event") {
173
+ evt.stx_mint_event = { recipient: e.recipient || "", amount: String(e.amount) };
174
+ } else if (type === "stx_burn_event") {
175
+ evt.stx_burn_event = { sender: e.sender || "", amount: String(e.amount) };
176
+ }
177
+ events.push(evt);
178
+ }
179
+ const lockEvents = await this.sql`
180
+ SELECT tx_id, event_index, locked_amount, unlock_height, locked_address
181
+ FROM ${this.sql(SCHEMA)}.stx_lock_events
182
+ WHERE block_height = ${height} AND canonical = true AND microblock_canonical = true
183
+ ORDER BY event_index
184
+ `;
185
+ for (const e of lockEvents) {
186
+ events.push({
187
+ txid: toHex(e.tx_id),
188
+ event_index: e.event_index,
189
+ committed: true,
190
+ type: "stx_lock_event",
191
+ stx_lock_event: {
192
+ locked_amount: String(e.locked_amount),
193
+ unlock_height: String(e.unlock_height),
194
+ locked_address: e.locked_address
195
+ }
196
+ });
197
+ }
198
+ const ftEvents = await this.sql`
199
+ SELECT tx_id, event_index, asset_event_type_id, asset_identifier, amount, sender, recipient
200
+ FROM ${this.sql(SCHEMA)}.ft_events
201
+ WHERE block_height = ${height} AND canonical = true AND microblock_canonical = true
202
+ ORDER BY event_index
203
+ `;
204
+ for (const e of ftEvents) {
205
+ const type = ftEventType(e.asset_event_type_id);
206
+ const evt = { txid: toHex(e.tx_id), event_index: e.event_index, committed: true, type };
207
+ if (type === "ft_transfer_event") {
208
+ evt.ft_transfer_event = {
209
+ asset_identifier: e.asset_identifier,
210
+ sender: e.sender || "",
211
+ recipient: e.recipient || "",
212
+ amount: String(e.amount)
213
+ };
214
+ } else if (type === "ft_mint_event") {
215
+ evt.ft_mint_event = { asset_identifier: e.asset_identifier, recipient: e.recipient || "", amount: String(e.amount) };
216
+ } else if (type === "ft_burn_event") {
217
+ evt.ft_burn_event = { asset_identifier: e.asset_identifier, sender: e.sender || "", amount: String(e.amount) };
218
+ }
219
+ events.push(evt);
220
+ }
221
+ const nftEvents = await this.sql`
222
+ SELECT tx_id, event_index, asset_event_type_id, asset_identifier, value, sender, recipient
223
+ FROM ${this.sql(SCHEMA)}.nft_events
224
+ WHERE block_height = ${height} AND canonical = true AND microblock_canonical = true
225
+ ORDER BY event_index
226
+ `;
227
+ for (const e of nftEvents) {
228
+ const type = nftEventType(e.asset_event_type_id);
229
+ const evt = { txid: toHex(e.tx_id), event_index: e.event_index, committed: true, type };
230
+ const val = toHex(e.value);
231
+ if (type === "nft_transfer_event") {
232
+ evt.nft_transfer_event = { asset_identifier: e.asset_identifier, sender: e.sender || "", recipient: e.recipient || "", value: val };
233
+ } else if (type === "nft_mint_event") {
234
+ evt.nft_mint_event = { asset_identifier: e.asset_identifier, recipient: e.recipient || "", value: val };
235
+ } else if (type === "nft_burn_event") {
236
+ evt.nft_burn_event = { asset_identifier: e.asset_identifier, sender: e.sender || "", value: val };
237
+ }
238
+ events.push(evt);
239
+ }
240
+ const logEvents = await this.sql`
241
+ SELECT tx_id, event_index, contract_identifier, topic, value
242
+ FROM ${this.sql(SCHEMA)}.contract_logs
243
+ WHERE block_height = ${height} AND canonical = true AND microblock_canonical = true
244
+ ORDER BY event_index
245
+ `;
246
+ for (const e of logEvents) {
247
+ events.push({
248
+ txid: toHex(e.tx_id),
249
+ event_index: e.event_index,
250
+ committed: true,
251
+ type: "smart_contract_event",
252
+ smart_contract_event: {
253
+ contract_identifier: e.contract_identifier,
254
+ topic: e.topic,
255
+ value: toHex(e.value)
256
+ }
257
+ });
258
+ }
259
+ return {
260
+ block_hash: toHex(block.block_hash),
261
+ block_height: block.block_height,
262
+ index_block_hash: toHex(block.index_block_hash),
263
+ parent_block_hash: toHex(block.parent_block_hash),
264
+ parent_index_block_hash: toHex(block.parent_index_block_hash),
265
+ burn_block_hash: toHex(block.burn_block_hash),
266
+ burn_block_height: block.burn_block_height,
267
+ burn_block_timestamp: block.burn_block_time,
268
+ miner_txid: toHex(block.miner_txid),
269
+ timestamp: block.block_time,
270
+ transactions,
271
+ events
272
+ };
273
+ }
274
+ async getBlockBatch(heights, options) {
275
+ if (heights.length === 0)
276
+ return [];
277
+ const blocks = await this.sql`
278
+ SELECT block_hash, block_height, index_block_hash, parent_block_hash,
279
+ parent_index_block_hash, burn_block_hash, burn_block_height,
280
+ burn_block_time, block_time, miner_txid
281
+ FROM ${this.sql(SCHEMA)}.blocks
282
+ WHERE block_height = ANY(${heights}) AND canonical = true
283
+ `;
284
+ if (blocks.length === 0)
285
+ return [];
286
+ const blockMap = new Map;
287
+ for (const b of blocks) {
288
+ blockMap.set(b.block_height, { ...b, transactions: [], events: [] });
289
+ }
290
+ const txs = await this.sql`
291
+ SELECT tx_id, tx_index, type_id, status, sender_address, raw_tx, event_count, block_height,
292
+ contract_call_contract_id, contract_call_function_name, smart_contract_contract_id
293
+ FROM ${this.sql(SCHEMA)}.txs
294
+ WHERE block_height = ANY(${heights}) AND canonical = true AND microblock_canonical = true
295
+ ORDER BY block_height, tx_index
296
+ `;
297
+ for (const tx of txs) {
298
+ const block = blockMap.get(tx.block_height);
299
+ if (!block)
300
+ continue;
301
+ const txType = mapTxTypeId(tx.type_id);
302
+ const entry = {
303
+ txid: toHex(tx.tx_id),
304
+ raw_tx: options?.includeRawTx ? toHex(tx.raw_tx) : "0x00",
305
+ status: mapTxStatus(tx.status),
306
+ tx_index: tx.tx_index,
307
+ tx_type: txType,
308
+ sender_address: tx.sender_address
309
+ };
310
+ if (txType === "contract_call" && tx.contract_call_contract_id) {
311
+ entry.contract_call = { contract_id: tx.contract_call_contract_id, function_name: tx.contract_call_function_name || "" };
312
+ } else if (txType === "smart_contract" && tx.smart_contract_contract_id) {
313
+ entry.smart_contract = { contract_id: tx.smart_contract_contract_id };
314
+ }
315
+ block.transactions.push(entry);
316
+ }
317
+ const stxEvents = await this.sql`
318
+ SELECT tx_id, event_index, asset_event_type_id, amount, sender, recipient, memo, block_height
319
+ FROM ${this.sql(SCHEMA)}.stx_events
320
+ WHERE block_height = ANY(${heights}) AND canonical = true AND microblock_canonical = true
321
+ `;
322
+ for (const e of stxEvents) {
323
+ const block = blockMap.get(e.block_height);
324
+ if (!block)
325
+ continue;
326
+ const type = stxEventType(e.asset_event_type_id);
327
+ const evt = { txid: toHex(e.tx_id), event_index: e.event_index, committed: true, type };
328
+ if (type === "stx_transfer_event") {
329
+ evt.stx_transfer_event = { sender: e.sender || "", recipient: e.recipient || "", amount: String(e.amount), ...e.memo ? { memo: toHex(e.memo) } : {} };
330
+ } else if (type === "stx_mint_event") {
331
+ evt.stx_mint_event = { recipient: e.recipient || "", amount: String(e.amount) };
332
+ } else if (type === "stx_burn_event") {
333
+ evt.stx_burn_event = { sender: e.sender || "", amount: String(e.amount) };
334
+ }
335
+ block.events.push(evt);
336
+ }
337
+ const lockEvents = await this.sql`
338
+ SELECT tx_id, event_index, locked_amount, unlock_height, locked_address, block_height
339
+ FROM ${this.sql(SCHEMA)}.stx_lock_events
340
+ WHERE block_height = ANY(${heights}) AND canonical = true AND microblock_canonical = true
341
+ `;
342
+ for (const e of lockEvents) {
343
+ const block = blockMap.get(e.block_height);
344
+ if (!block)
345
+ continue;
346
+ block.events.push({
347
+ txid: toHex(e.tx_id),
348
+ event_index: e.event_index,
349
+ committed: true,
350
+ type: "stx_lock_event",
351
+ stx_lock_event: { locked_amount: String(e.locked_amount), unlock_height: String(e.unlock_height), locked_address: e.locked_address }
352
+ });
353
+ }
354
+ const ftEvents = await this.sql`
355
+ SELECT tx_id, event_index, asset_event_type_id, asset_identifier, amount, sender, recipient, block_height
356
+ FROM ${this.sql(SCHEMA)}.ft_events
357
+ WHERE block_height = ANY(${heights}) AND canonical = true AND microblock_canonical = true
358
+ `;
359
+ for (const e of ftEvents) {
360
+ const block = blockMap.get(e.block_height);
361
+ if (!block)
362
+ continue;
363
+ const type = ftEventType(e.asset_event_type_id);
364
+ const evt = { txid: toHex(e.tx_id), event_index: e.event_index, committed: true, type };
365
+ if (type === "ft_transfer_event") {
366
+ evt.ft_transfer_event = { asset_identifier: e.asset_identifier, sender: e.sender || "", recipient: e.recipient || "", amount: String(e.amount) };
367
+ } else if (type === "ft_mint_event") {
368
+ evt.ft_mint_event = { asset_identifier: e.asset_identifier, recipient: e.recipient || "", amount: String(e.amount) };
369
+ } else if (type === "ft_burn_event") {
370
+ evt.ft_burn_event = { asset_identifier: e.asset_identifier, sender: e.sender || "", amount: String(e.amount) };
371
+ }
372
+ block.events.push(evt);
373
+ }
374
+ const nftEvents = await this.sql`
375
+ SELECT tx_id, event_index, asset_event_type_id, asset_identifier, value, sender, recipient, block_height
376
+ FROM ${this.sql(SCHEMA)}.nft_events
377
+ WHERE block_height = ANY(${heights}) AND canonical = true AND microblock_canonical = true
378
+ `;
379
+ for (const e of nftEvents) {
380
+ const block = blockMap.get(e.block_height);
381
+ if (!block)
382
+ continue;
383
+ const type = nftEventType(e.asset_event_type_id);
384
+ const evt = { txid: toHex(e.tx_id), event_index: e.event_index, committed: true, type };
385
+ const val = toHex(e.value);
386
+ if (type === "nft_transfer_event") {
387
+ evt.nft_transfer_event = { asset_identifier: e.asset_identifier, sender: e.sender || "", recipient: e.recipient || "", value: val };
388
+ } else if (type === "nft_mint_event") {
389
+ evt.nft_mint_event = { asset_identifier: e.asset_identifier, recipient: e.recipient || "", value: val };
390
+ } else if (type === "nft_burn_event") {
391
+ evt.nft_burn_event = { asset_identifier: e.asset_identifier, sender: e.sender || "", value: val };
392
+ }
393
+ block.events.push(evt);
394
+ }
395
+ const logEvents = await this.sql`
396
+ SELECT tx_id, event_index, contract_identifier, topic, value, block_height
397
+ FROM ${this.sql(SCHEMA)}.contract_logs
398
+ WHERE block_height = ANY(${heights}) AND canonical = true AND microblock_canonical = true
399
+ `;
400
+ for (const e of logEvents) {
401
+ const block = blockMap.get(e.block_height);
402
+ if (!block)
403
+ continue;
404
+ block.events.push({
405
+ txid: toHex(e.tx_id),
406
+ event_index: e.event_index,
407
+ committed: true,
408
+ type: "smart_contract_event",
409
+ smart_contract_event: { contract_identifier: e.contract_identifier, topic: e.topic, value: toHex(e.value) }
410
+ });
411
+ }
412
+ return heights.filter((h) => blockMap.has(h)).map((h) => {
413
+ const b = blockMap.get(h);
414
+ return {
415
+ block_hash: toHex(b.block_hash),
416
+ block_height: b.block_height,
417
+ index_block_hash: toHex(b.index_block_hash),
418
+ parent_block_hash: toHex(b.parent_block_hash),
419
+ parent_index_block_hash: toHex(b.parent_index_block_hash),
420
+ burn_block_hash: toHex(b.burn_block_hash),
421
+ burn_block_height: b.burn_block_height,
422
+ burn_block_timestamp: b.burn_block_time,
423
+ miner_txid: toHex(b.miner_txid),
424
+ timestamp: b.block_time,
425
+ transactions: b.transactions,
426
+ events: b.events
427
+ };
428
+ });
429
+ }
430
+ async close() {
431
+ await this.sql.end();
432
+ }
433
+ }
434
+ export {
435
+ HiroPgClient
436
+ };
437
+
438
+ //# debugId=F4751CE743F3BF9964756E2164756E21
439
+ //# sourceMappingURL=hiro-pg-client.js.map
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/node/hiro-pg-client.ts"],
4
+ "sourcesContent": [
5
+ "/**\n * Direct Postgres client for reading from a local Hiro API database.\n *\n * Bypasses the Hiro HTTP API entirely — queries the stacks_blockchain_api\n * schema directly. Orders of magnitude faster for bulk backfill since we\n * avoid per-tx HTTP round-trips and the API's slow UNION event queries.\n *\n * Expects HIRO_PG_URL env var pointing to the Hiro API database, e.g.:\n * postgres://secondlayer:pass@localhost:5432/stacks_blockchain_api\n */\n\nimport postgres from \"postgres\";\nimport { logger } from \"../logger.ts\";\n\nconst SCHEMA = \"stacks_blockchain_api\";\n\n// Hiro DB stores bytea; we need 0x-prefixed hex strings\nfunction toHex(buf: Buffer | Uint8Array | null): string {\n if (!buf) return \"0x\";\n return \"0x\" + Buffer.from(buf).toString(\"hex\");\n}\n\n// asset_event_type_id mapping: 1=transfer, 2=mint, 3=burn\nfunction stxEventType(assetTypeId: number): string {\n switch (assetTypeId) {\n case 1: return \"stx_transfer_event\";\n case 2: return \"stx_mint_event\";\n case 3: return \"stx_burn_event\";\n default: return \"stx_transfer_event\";\n }\n}\n\nfunction ftEventType(assetTypeId: number): string {\n switch (assetTypeId) {\n case 1: return \"ft_transfer_event\";\n case 2: return \"ft_mint_event\";\n case 3: return \"ft_burn_event\";\n default: return \"ft_transfer_event\";\n }\n}\n\nfunction nftEventType(assetTypeId: number): string {\n switch (assetTypeId) {\n case 1: return \"nft_transfer_event\";\n case 2: return \"nft_mint_event\";\n case 3: return \"nft_burn_event\";\n default: return \"nft_transfer_event\";\n }\n}\n\n// Hiro tx type_id mapping\nfunction mapTxTypeId(typeId: number): string {\n switch (typeId) {\n case 0: return \"token_transfer\";\n case 1: return \"smart_contract\";\n case 2: return \"contract_call\";\n case 3: return \"poison_microblock\";\n case 4: return \"coinbase\";\n case 5: return \"coinbase\"; // coinbase-pay-to-alt\n case 6: return \"smart_contract\"; // versioned\n case 7: return \"tenure_change\";\n case 8: return \"coinbase\"; // nakamoto coinbase\n default: return \"token_transfer\";\n }\n}\n\n// Hiro tx status mapping\nfunction mapTxStatus(status: number): string {\n switch (status) {\n case 1: return \"success\";\n case 0: return \"abort_by_response\";\n default: return \"abort_by_post_condition\";\n }\n}\n\ninterface BlockRow {\n block_hash: Buffer;\n block_height: number;\n index_block_hash: Buffer;\n parent_block_hash: Buffer;\n parent_index_block_hash: Buffer;\n burn_block_hash: Buffer;\n burn_block_height: number;\n burn_block_time: number;\n block_time: number;\n miner_txid: Buffer;\n}\n\ninterface TxRow {\n tx_id: Buffer;\n tx_index: number;\n type_id: number;\n status: number;\n sender_address: string;\n raw_tx: Buffer;\n event_count: number;\n contract_call_contract_id: string | null;\n contract_call_function_name: string | null;\n smart_contract_contract_id: string | null;\n}\n\nexport class HiroPgClient {\n private sql: ReturnType<typeof postgres>;\n\n constructor(connectionUrl?: string) {\n const url = connectionUrl || process.env.HIRO_PG_URL;\n if (!url) throw new Error(\"HIRO_PG_URL is required for HiroPgClient\");\n this.sql = postgres(url, {\n max: 10,\n idle_timeout: 30,\n types: { bigint: postgres.BigInt },\n });\n }\n\n async getChainTip(): Promise<number> {\n const rows = await this.sql`\n SELECT MAX(block_height) as tip FROM ${this.sql(SCHEMA)}.blocks WHERE canonical = true\n `;\n return Number(rows[0]?.tip ?? 0);\n }\n\n /**\n * Fetch a complete block by height directly from PG.\n * Returns data in the same NewBlockPayload shape the backfill expects.\n */\n async getBlockForIndexer(height: number, options?: { includeRawTx?: boolean }): Promise<any | null> {\n // 1. Block metadata\n const blocks = await this.sql<BlockRow[]>`\n SELECT block_hash, block_height, index_block_hash, parent_block_hash,\n parent_index_block_hash, burn_block_hash, burn_block_height,\n burn_block_time, block_time, miner_txid\n FROM ${this.sql(SCHEMA)}.blocks\n WHERE block_height = ${height} AND canonical = true\n LIMIT 1\n `;\n if (blocks.length === 0) return null;\n const block = blocks[0];\n\n // 2. Transactions\n const txs = await this.sql<TxRow[]>`\n SELECT tx_id, tx_index, type_id, status, sender_address, raw_tx, event_count,\n contract_call_contract_id, contract_call_function_name, smart_contract_contract_id\n FROM ${this.sql(SCHEMA)}.txs\n WHERE block_height = ${height} AND canonical = true AND microblock_canonical = true\n ORDER BY tx_index\n `;\n\n const transactions = txs.map((tx) => {\n const txType = mapTxTypeId(tx.type_id);\n const entry: any = {\n txid: toHex(tx.tx_id),\n raw_tx: options?.includeRawTx ? toHex(tx.raw_tx) : \"0x00\",\n status: mapTxStatus(tx.status),\n tx_index: tx.tx_index,\n tx_type: txType,\n sender_address: tx.sender_address,\n };\n if (txType === \"contract_call\" && tx.contract_call_contract_id) {\n entry.contract_call = {\n contract_id: tx.contract_call_contract_id,\n function_name: tx.contract_call_function_name || \"\",\n };\n } else if (txType === \"smart_contract\" && tx.smart_contract_contract_id) {\n entry.smart_contract = {\n contract_id: tx.smart_contract_contract_id,\n };\n }\n return entry;\n });\n\n // 3. Events — query all event tables by block_height (fast, indexed)\n const events: any[] = [];\n\n // STX events\n const stxEvents = await this.sql`\n SELECT tx_id, event_index, asset_event_type_id, amount, sender, recipient, memo\n FROM ${this.sql(SCHEMA)}.stx_events\n WHERE block_height = ${height} AND canonical = true AND microblock_canonical = true\n ORDER BY event_index\n `;\n for (const e of stxEvents) {\n const type = stxEventType(e.asset_event_type_id);\n const evt: any = { txid: toHex(e.tx_id), event_index: e.event_index, committed: true, type };\n if (type === \"stx_transfer_event\") {\n evt.stx_transfer_event = {\n sender: e.sender || \"\",\n recipient: e.recipient || \"\",\n amount: String(e.amount),\n ...(e.memo ? { memo: toHex(e.memo) } : {}),\n };\n } else if (type === \"stx_mint_event\") {\n evt.stx_mint_event = { recipient: e.recipient || \"\", amount: String(e.amount) };\n } else if (type === \"stx_burn_event\") {\n evt.stx_burn_event = { sender: e.sender || \"\", amount: String(e.amount) };\n }\n events.push(evt);\n }\n\n // STX lock events\n const lockEvents = await this.sql`\n SELECT tx_id, event_index, locked_amount, unlock_height, locked_address\n FROM ${this.sql(SCHEMA)}.stx_lock_events\n WHERE block_height = ${height} AND canonical = true AND microblock_canonical = true\n ORDER BY event_index\n `;\n for (const e of lockEvents) {\n events.push({\n txid: toHex(e.tx_id),\n event_index: e.event_index,\n committed: true,\n type: \"stx_lock_event\",\n stx_lock_event: {\n locked_amount: String(e.locked_amount),\n unlock_height: String(e.unlock_height),\n locked_address: e.locked_address,\n },\n });\n }\n\n // FT events\n const ftEvents = await this.sql`\n SELECT tx_id, event_index, asset_event_type_id, asset_identifier, amount, sender, recipient\n FROM ${this.sql(SCHEMA)}.ft_events\n WHERE block_height = ${height} AND canonical = true AND microblock_canonical = true\n ORDER BY event_index\n `;\n for (const e of ftEvents) {\n const type = ftEventType(e.asset_event_type_id);\n const evt: any = { txid: toHex(e.tx_id), event_index: e.event_index, committed: true, type };\n if (type === \"ft_transfer_event\") {\n evt.ft_transfer_event = {\n asset_identifier: e.asset_identifier,\n sender: e.sender || \"\",\n recipient: e.recipient || \"\",\n amount: String(e.amount),\n };\n } else if (type === \"ft_mint_event\") {\n evt.ft_mint_event = { asset_identifier: e.asset_identifier, recipient: e.recipient || \"\", amount: String(e.amount) };\n } else if (type === \"ft_burn_event\") {\n evt.ft_burn_event = { asset_identifier: e.asset_identifier, sender: e.sender || \"\", amount: String(e.amount) };\n }\n events.push(evt);\n }\n\n // NFT events\n const nftEvents = await this.sql`\n SELECT tx_id, event_index, asset_event_type_id, asset_identifier, value, sender, recipient\n FROM ${this.sql(SCHEMA)}.nft_events\n WHERE block_height = ${height} AND canonical = true AND microblock_canonical = true\n ORDER BY event_index\n `;\n for (const e of nftEvents) {\n const type = nftEventType(e.asset_event_type_id);\n const evt: any = { txid: toHex(e.tx_id), event_index: e.event_index, committed: true, type };\n const val = toHex(e.value);\n if (type === \"nft_transfer_event\") {\n evt.nft_transfer_event = { asset_identifier: e.asset_identifier, sender: e.sender || \"\", recipient: e.recipient || \"\", value: val };\n } else if (type === \"nft_mint_event\") {\n evt.nft_mint_event = { asset_identifier: e.asset_identifier, recipient: e.recipient || \"\", value: val };\n } else if (type === \"nft_burn_event\") {\n evt.nft_burn_event = { asset_identifier: e.asset_identifier, sender: e.sender || \"\", value: val };\n }\n events.push(evt);\n }\n\n // Contract log events\n const logEvents = await this.sql`\n SELECT tx_id, event_index, contract_identifier, topic, value\n FROM ${this.sql(SCHEMA)}.contract_logs\n WHERE block_height = ${height} AND canonical = true AND microblock_canonical = true\n ORDER BY event_index\n `;\n for (const e of logEvents) {\n events.push({\n txid: toHex(e.tx_id),\n event_index: e.event_index,\n committed: true,\n type: \"smart_contract_event\",\n smart_contract_event: {\n contract_identifier: e.contract_identifier,\n topic: e.topic,\n value: toHex(e.value),\n },\n });\n }\n\n return {\n block_hash: toHex(block.block_hash),\n block_height: block.block_height,\n index_block_hash: toHex(block.index_block_hash),\n parent_block_hash: toHex(block.parent_block_hash),\n parent_index_block_hash: toHex(block.parent_index_block_hash),\n burn_block_hash: toHex(block.burn_block_hash),\n burn_block_height: block.burn_block_height,\n burn_block_timestamp: block.burn_block_time,\n miner_txid: toHex(block.miner_txid),\n timestamp: block.block_time,\n transactions,\n events,\n };\n }\n\n /**\n * Fetch multiple blocks in bulk — 6 queries total instead of 6 per block.\n * Returns array of NewBlockPayload in height order.\n */\n async getBlockBatch(heights: number[], options?: { includeRawTx?: boolean }): Promise<any[]> {\n if (heights.length === 0) return [];\n\n // 1. All blocks in range\n const blocks = await this.sql`\n SELECT block_hash, block_height, index_block_hash, parent_block_hash,\n parent_index_block_hash, burn_block_hash, burn_block_height,\n burn_block_time, block_time, miner_txid\n FROM ${this.sql(SCHEMA)}.blocks\n WHERE block_height = ANY(${heights}) AND canonical = true\n `;\n\n if (blocks.length === 0) return [];\n const blockMap = new Map<number, any>();\n for (const b of blocks) {\n blockMap.set(b.block_height, { ...b, transactions: [], events: [] });\n }\n\n // 2. All transactions\n const txs = await this.sql`\n SELECT tx_id, tx_index, type_id, status, sender_address, raw_tx, event_count, block_height,\n contract_call_contract_id, contract_call_function_name, smart_contract_contract_id\n FROM ${this.sql(SCHEMA)}.txs\n WHERE block_height = ANY(${heights}) AND canonical = true AND microblock_canonical = true\n ORDER BY block_height, tx_index\n `;\n for (const tx of txs) {\n const block = blockMap.get(tx.block_height);\n if (!block) continue;\n const txType = mapTxTypeId(tx.type_id);\n const entry: any = {\n txid: toHex(tx.tx_id),\n raw_tx: options?.includeRawTx ? toHex(tx.raw_tx) : \"0x00\",\n status: mapTxStatus(tx.status),\n tx_index: tx.tx_index,\n tx_type: txType,\n sender_address: tx.sender_address,\n };\n if (txType === \"contract_call\" && tx.contract_call_contract_id) {\n entry.contract_call = { contract_id: tx.contract_call_contract_id, function_name: tx.contract_call_function_name || \"\" };\n } else if (txType === \"smart_contract\" && tx.smart_contract_contract_id) {\n entry.smart_contract = { contract_id: tx.smart_contract_contract_id };\n }\n block.transactions.push(entry);\n }\n\n // 3. STX events\n const stxEvents = await this.sql`\n SELECT tx_id, event_index, asset_event_type_id, amount, sender, recipient, memo, block_height\n FROM ${this.sql(SCHEMA)}.stx_events\n WHERE block_height = ANY(${heights}) AND canonical = true AND microblock_canonical = true\n `;\n for (const e of stxEvents) {\n const block = blockMap.get(e.block_height);\n if (!block) continue;\n const type = stxEventType(e.asset_event_type_id);\n const evt: any = { txid: toHex(e.tx_id), event_index: e.event_index, committed: true, type };\n if (type === \"stx_transfer_event\") {\n evt.stx_transfer_event = { sender: e.sender || \"\", recipient: e.recipient || \"\", amount: String(e.amount), ...(e.memo ? { memo: toHex(e.memo) } : {}) };\n } else if (type === \"stx_mint_event\") {\n evt.stx_mint_event = { recipient: e.recipient || \"\", amount: String(e.amount) };\n } else if (type === \"stx_burn_event\") {\n evt.stx_burn_event = { sender: e.sender || \"\", amount: String(e.amount) };\n }\n block.events.push(evt);\n }\n\n // 4. STX lock events\n const lockEvents = await this.sql`\n SELECT tx_id, event_index, locked_amount, unlock_height, locked_address, block_height\n FROM ${this.sql(SCHEMA)}.stx_lock_events\n WHERE block_height = ANY(${heights}) AND canonical = true AND microblock_canonical = true\n `;\n for (const e of lockEvents) {\n const block = blockMap.get(e.block_height);\n if (!block) continue;\n block.events.push({\n txid: toHex(e.tx_id), event_index: e.event_index, committed: true, type: \"stx_lock_event\",\n stx_lock_event: { locked_amount: String(e.locked_amount), unlock_height: String(e.unlock_height), locked_address: e.locked_address },\n });\n }\n\n // 5. FT events\n const ftEvents = await this.sql`\n SELECT tx_id, event_index, asset_event_type_id, asset_identifier, amount, sender, recipient, block_height\n FROM ${this.sql(SCHEMA)}.ft_events\n WHERE block_height = ANY(${heights}) AND canonical = true AND microblock_canonical = true\n `;\n for (const e of ftEvents) {\n const block = blockMap.get(e.block_height);\n if (!block) continue;\n const type = ftEventType(e.asset_event_type_id);\n const evt: any = { txid: toHex(e.tx_id), event_index: e.event_index, committed: true, type };\n if (type === \"ft_transfer_event\") {\n evt.ft_transfer_event = { asset_identifier: e.asset_identifier, sender: e.sender || \"\", recipient: e.recipient || \"\", amount: String(e.amount) };\n } else if (type === \"ft_mint_event\") {\n evt.ft_mint_event = { asset_identifier: e.asset_identifier, recipient: e.recipient || \"\", amount: String(e.amount) };\n } else if (type === \"ft_burn_event\") {\n evt.ft_burn_event = { asset_identifier: e.asset_identifier, sender: e.sender || \"\", amount: String(e.amount) };\n }\n block.events.push(evt);\n }\n\n // 6. NFT events\n const nftEvents = await this.sql`\n SELECT tx_id, event_index, asset_event_type_id, asset_identifier, value, sender, recipient, block_height\n FROM ${this.sql(SCHEMA)}.nft_events\n WHERE block_height = ANY(${heights}) AND canonical = true AND microblock_canonical = true\n `;\n for (const e of nftEvents) {\n const block = blockMap.get(e.block_height);\n if (!block) continue;\n const type = nftEventType(e.asset_event_type_id);\n const evt: any = { txid: toHex(e.tx_id), event_index: e.event_index, committed: true, type };\n const val = toHex(e.value);\n if (type === \"nft_transfer_event\") {\n evt.nft_transfer_event = { asset_identifier: e.asset_identifier, sender: e.sender || \"\", recipient: e.recipient || \"\", value: val };\n } else if (type === \"nft_mint_event\") {\n evt.nft_mint_event = { asset_identifier: e.asset_identifier, recipient: e.recipient || \"\", value: val };\n } else if (type === \"nft_burn_event\") {\n evt.nft_burn_event = { asset_identifier: e.asset_identifier, sender: e.sender || \"\", value: val };\n }\n block.events.push(evt);\n }\n\n // 7. Contract log events\n const logEvents = await this.sql`\n SELECT tx_id, event_index, contract_identifier, topic, value, block_height\n FROM ${this.sql(SCHEMA)}.contract_logs\n WHERE block_height = ANY(${heights}) AND canonical = true AND microblock_canonical = true\n `;\n for (const e of logEvents) {\n const block = blockMap.get(e.block_height);\n if (!block) continue;\n block.events.push({\n txid: toHex(e.tx_id), event_index: e.event_index, committed: true, type: \"smart_contract_event\",\n smart_contract_event: { contract_identifier: e.contract_identifier, topic: e.topic, value: toHex(e.value) },\n });\n }\n\n // Build results in height order\n return heights\n .filter((h) => blockMap.has(h))\n .map((h) => {\n const b = blockMap.get(h)!;\n return {\n block_hash: toHex(b.block_hash),\n block_height: b.block_height,\n index_block_hash: toHex(b.index_block_hash),\n parent_block_hash: toHex(b.parent_block_hash),\n parent_index_block_hash: toHex(b.parent_index_block_hash),\n burn_block_hash: toHex(b.burn_block_hash),\n burn_block_height: b.burn_block_height,\n burn_block_timestamp: b.burn_block_time,\n miner_txid: toHex(b.miner_txid),\n timestamp: b.block_time,\n transactions: b.transactions,\n events: b.events,\n };\n });\n }\n\n async close(): Promise<void> {\n await this.sql.end();\n }\n}\n"
6
+ ],
7
+ "mappings": "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",
8
+ "debugId": "F4751CE743F3BF9964756E2164756E21",
9
+ "names": []
10
+ }
@@ -36,8 +36,8 @@ interface StreamsTable {
36
36
  status: Generated<string>;
37
37
  filters: unknown;
38
38
  options: Generated<unknown>;
39
- webhook_url: string;
40
- webhook_secret: string | null;
39
+ endpoint_url: string;
40
+ signing_secret: string | null;
41
41
  api_key_id: string | null;
42
42
  created_at: Generated<Date>;
43
43
  updated_at: Generated<Date>;
@@ -2,7 +2,7 @@
2
2
  "version": 3,
3
3
  "sources": ["../src/node/local-client.ts"],
4
4
  "sourcesContent": [
5
- "/**\n * Local replay client — reconstructs NewBlockPayload from our own Postgres.\n *\n * Used for re-orgs, reprocessing, and self-serve replay after genesis sync.\n * Eliminates need for self-hosted Hiro API for blocks already in our DB.\n */\n\nimport type { Kysely } from \"kysely\";\nimport type { Database } from \"../db/types.ts\";\n\n/** Matches the NewBlockPayload shape expected by the indexer's /new_block endpoint */\nexport interface ReplayBlockPayload {\n block_hash: string;\n block_height: number;\n index_block_hash: string;\n parent_block_hash: string;\n parent_index_block_hash: string;\n burn_block_hash: string;\n burn_block_height: number;\n burn_block_timestamp: number;\n miner_txid: string;\n timestamp: number;\n transactions: ReplayTransactionPayload[];\n events: ReplayEventPayload[];\n}\n\ninterface ReplayTransactionPayload {\n txid: string;\n raw_tx: string;\n status: string;\n tx_index: number;\n tx_type?: string;\n sender_address?: string;\n}\n\ninterface ReplayEventPayload {\n txid: string;\n event_index: number;\n committed: boolean;\n type: string;\n [key: string]: unknown;\n}\n\nexport class LocalClient {\n /**\n * Reconstruct a NewBlockPayload from local DB for replay.\n * Returns null if block not found.\n */\n async getBlockForReplay(db: Kysely<Database>, height: number): Promise<ReplayBlockPayload | null> {\n const block = await db\n .selectFrom(\"blocks\")\n .selectAll()\n .where(\"height\", \"=\", height)\n .where(\"canonical\", \"=\", true)\n .executeTakeFirst();\n\n if (!block) return null;\n\n const transactions = await db\n .selectFrom(\"transactions\")\n .selectAll()\n .where(\"block_height\", \"=\", height)\n .orderBy(\"tx_index\", \"asc\")\n .execute();\n\n const events = await db\n .selectFrom(\"events\")\n .selectAll()\n .where(\"block_height\", \"=\", height)\n .orderBy(\"event_index\", \"asc\")\n .execute();\n\n return {\n block_hash: block.hash,\n block_height: block.height,\n // Not stored in our DB — not needed by parser/webhooks\n index_block_hash: \"\",\n parent_block_hash: block.parent_hash,\n parent_index_block_hash: \"\",\n burn_block_hash: \"\",\n burn_block_height: block.burn_block_height,\n burn_block_timestamp: block.timestamp,\n miner_txid: \"\",\n timestamp: block.timestamp,\n transactions: transactions.map((tx) => ({\n txid: tx.tx_id,\n raw_tx: tx.raw_tx,\n status: tx.status,\n tx_index: tx.tx_index,\n tx_type: tx.type,\n sender_address: tx.sender,\n })),\n events: events.map((evt) => {\n const data = (evt.data ?? {}) as Record<string, unknown>;\n const eventType = evt.type;\n\n // Reconstruct the flat event structure the indexer expects:\n // { txid, event_index, committed, type, [type_key]: data }\n const payload: ReplayEventPayload = {\n txid: evt.tx_id,\n event_index: evt.event_index,\n committed: true,\n type: eventType,\n };\n\n // Attach event-specific data under the correct key\n if (eventType && data) {\n payload[eventType] = data;\n }\n\n return payload;\n }),\n };\n }\n\n /** Get highest block height in local DB */\n async getChainTip(db: Kysely<Database>): Promise<number> {\n const row = await db\n .selectFrom(\"blocks\")\n .select((eb) => eb.fn.max(\"height\").as(\"max_height\"))\n .where(\"canonical\", \"=\", true)\n .executeTakeFirst();\n return Number(row?.max_height ?? 0);\n }\n\n /** Check if a specific block height exists in local DB */\n async hasBlock(db: Kysely<Database>, height: number): Promise<boolean> {\n const row = await db\n .selectFrom(\"blocks\")\n .select(\"height\")\n .where(\"height\", \"=\", height)\n .where(\"canonical\", \"=\", true)\n .executeTakeFirst();\n return !!row;\n }\n}\n"
5
+ "/**\n * Local replay client — reconstructs NewBlockPayload from our own Postgres.\n *\n * Used for re-orgs, reprocessing, and self-serve replay after genesis sync.\n * Eliminates need for self-hosted Hiro API for blocks already in our DB.\n */\n\nimport type { Kysely } from \"kysely\";\nimport type { Database } from \"../db/types.ts\";\n\n/** Matches the NewBlockPayload shape expected by the indexer's /new_block endpoint */\nexport interface ReplayBlockPayload {\n block_hash: string;\n block_height: number;\n index_block_hash: string;\n parent_block_hash: string;\n parent_index_block_hash: string;\n burn_block_hash: string;\n burn_block_height: number;\n burn_block_timestamp: number;\n miner_txid: string;\n timestamp: number;\n transactions: ReplayTransactionPayload[];\n events: ReplayEventPayload[];\n}\n\ninterface ReplayTransactionPayload {\n txid: string;\n raw_tx: string;\n status: string;\n tx_index: number;\n tx_type?: string;\n sender_address?: string;\n}\n\ninterface ReplayEventPayload {\n txid: string;\n event_index: number;\n committed: boolean;\n type: string;\n [key: string]: unknown;\n}\n\nexport class LocalClient {\n /**\n * Reconstruct a NewBlockPayload from local DB for replay.\n * Returns null if block not found.\n */\n async getBlockForReplay(db: Kysely<Database>, height: number): Promise<ReplayBlockPayload | null> {\n const block = await db\n .selectFrom(\"blocks\")\n .selectAll()\n .where(\"height\", \"=\", height)\n .where(\"canonical\", \"=\", true)\n .executeTakeFirst();\n\n if (!block) return null;\n\n const transactions = await db\n .selectFrom(\"transactions\")\n .selectAll()\n .where(\"block_height\", \"=\", height)\n .orderBy(\"tx_index\", \"asc\")\n .execute();\n\n const events = await db\n .selectFrom(\"events\")\n .selectAll()\n .where(\"block_height\", \"=\", height)\n .orderBy(\"event_index\", \"asc\")\n .execute();\n\n return {\n block_hash: block.hash,\n block_height: block.height,\n // Not stored in our DB — not needed by parser/deliveries\n index_block_hash: \"\",\n parent_block_hash: block.parent_hash,\n parent_index_block_hash: \"\",\n burn_block_hash: \"\",\n burn_block_height: block.burn_block_height,\n burn_block_timestamp: block.timestamp,\n miner_txid: \"\",\n timestamp: block.timestamp,\n transactions: transactions.map((tx) => ({\n txid: tx.tx_id,\n raw_tx: tx.raw_tx,\n status: tx.status,\n tx_index: tx.tx_index,\n tx_type: tx.type,\n sender_address: tx.sender,\n })),\n events: events.map((evt) => {\n const data = (evt.data ?? {}) as Record<string, unknown>;\n const eventType = evt.type;\n\n // Reconstruct the flat event structure the indexer expects:\n // { txid, event_index, committed, type, [type_key]: data }\n const payload: ReplayEventPayload = {\n txid: evt.tx_id,\n event_index: evt.event_index,\n committed: true,\n type: eventType,\n };\n\n // Attach event-specific data under the correct key\n if (eventType && data) {\n payload[eventType] = data;\n }\n\n return payload;\n }),\n };\n }\n\n /** Get highest block height in local DB */\n async getChainTip(db: Kysely<Database>): Promise<number> {\n const row = await db\n .selectFrom(\"blocks\")\n .select((eb) => eb.fn.max(\"height\").as(\"max_height\"))\n .where(\"canonical\", \"=\", true)\n .executeTakeFirst();\n return Number(row?.max_height ?? 0);\n }\n\n /** Check if a specific block height exists in local DB */\n async hasBlock(db: Kysely<Database>, height: number): Promise<boolean> {\n const row = await db\n .selectFrom(\"blocks\")\n .select(\"height\")\n .where(\"height\", \"=\", height)\n .where(\"canonical\", \"=\", true)\n .executeTakeFirst();\n return !!row;\n }\n}\n"
6
6
  ],
7
7
  "mappings": ";;;;;;;;;;;;;;;;;AA2CO,MAAM,YAAY;AAAA,OAKjB,kBAAiB,CAAC,IAAsB,QAAoD;AAAA,IAChG,MAAM,QAAQ,MAAM,GACjB,WAAW,QAAQ,EACnB,UAAU,EACV,MAAM,UAAU,KAAK,MAAM,EAC3B,MAAM,aAAa,KAAK,IAAI,EAC5B,iBAAiB;AAAA,IAEpB,IAAI,CAAC;AAAA,MAAO,OAAO;AAAA,IAEnB,MAAM,eAAe,MAAM,GACxB,WAAW,cAAc,EACzB,UAAU,EACV,MAAM,gBAAgB,KAAK,MAAM,EACjC,QAAQ,YAAY,KAAK,EACzB,QAAQ;AAAA,IAEX,MAAM,SAAS,MAAM,GAClB,WAAW,QAAQ,EACnB,UAAU,EACV,MAAM,gBAAgB,KAAK,MAAM,EACjC,QAAQ,eAAe,KAAK,EAC5B,QAAQ;AAAA,IAEX,OAAO;AAAA,MACL,YAAY,MAAM;AAAA,MAClB,cAAc,MAAM;AAAA,MAEpB,kBAAkB;AAAA,MAClB,mBAAmB,MAAM;AAAA,MACzB,yBAAyB;AAAA,MACzB,iBAAiB;AAAA,MACjB,mBAAmB,MAAM;AAAA,MACzB,sBAAsB,MAAM;AAAA,MAC5B,YAAY;AAAA,MACZ,WAAW,MAAM;AAAA,MACjB,cAAc,aAAa,IAAI,CAAC,QAAQ;AAAA,QACtC,MAAM,GAAG;AAAA,QACT,QAAQ,GAAG;AAAA,QACX,QAAQ,GAAG;AAAA,QACX,UAAU,GAAG;AAAA,QACb,SAAS,GAAG;AAAA,QACZ,gBAAgB,GAAG;AAAA,MACrB,EAAE;AAAA,MACF,QAAQ,OAAO,IAAI,CAAC,QAAQ;AAAA,QAC1B,MAAM,OAAQ,IAAI,QAAQ,CAAC;AAAA,QAC3B,MAAM,YAAY,IAAI;AAAA,QAItB,MAAM,UAA8B;AAAA,UAClC,MAAM,IAAI;AAAA,UACV,aAAa,IAAI;AAAA,UACjB,WAAW;AAAA,UACX,MAAM;AAAA,QACR;AAAA,QAGA,IAAI,aAAa,MAAM;AAAA,UACrB,QAAQ,aAAa;AAAA,QACvB;AAAA,QAEA,OAAO;AAAA,OACR;AAAA,IACH;AAAA;AAAA,OAII,YAAW,CAAC,IAAuC;AAAA,IACvD,MAAM,MAAM,MAAM,GACf,WAAW,QAAQ,EACnB,OAAO,CAAC,OAAO,GAAG,GAAG,IAAI,QAAQ,EAAE,GAAG,YAAY,CAAC,EACnD,MAAM,aAAa,KAAK,IAAI,EAC5B,iBAAiB;AAAA,IACpB,OAAO,OAAO,KAAK,cAAc,CAAC;AAAA;AAAA,OAI9B,SAAQ,CAAC,IAAsB,QAAkC;AAAA,IACrE,MAAM,MAAM,MAAM,GACf,WAAW,QAAQ,EACnB,OAAO,QAAQ,EACf,MAAM,UAAU,KAAK,MAAM,EAC3B,MAAM,aAAa,KAAK,IAAI,EAC5B,iBAAiB;AAAA,IACpB,OAAO,CAAC,CAAC;AAAA;AAEb;",
8
8
  "debugId": "DE87E3DF563DF80464756E2164756E21",
@@ -1,4 +1,4 @@
1
- import { z } from "zod";
1
+ import { z } from "zod/v4";
2
2
  interface StxTransferFilter {
3
3
  type: "stx_transfer";
4
4
  sender?: string;
@@ -15,7 +15,7 @@ var __export = (target, all) => {
15
15
  };
16
16
 
17
17
  // src/schemas/filters.ts
18
- import { z } from "zod";
18
+ import { z } from "zod/v4";
19
19
  import { isValidAddress as _isValidAddress } from "@secondlayer/stacks";
20
20
  var isValidAddress = _isValidAddress;
21
21
  var stacksPrincipal = z.string().refine((val) => {
@@ -134,5 +134,5 @@ export {
134
134
  ContractCallFilterSchema
135
135
  };
136
136
 
137
- //# debugId=B04556256345C38264756E2164756E21
137
+ //# debugId=9BF41B1F9FD47F8764756E2164756E21
138
138
  //# sourceMappingURL=filters.js.map
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../src/schemas/filters.ts"],
4
4
  "sourcesContent": [
5
- "import { z } from \"zod\";\nimport { isValidAddress as _isValidAddress } from \"@secondlayer/stacks\";\n\nconst isValidAddress = _isValidAddress as (addr: string) => boolean;\n\n/** Validate a Stacks principal (standard or contract, e.g. SP2J...ABC or SP2J...ABC.contract-name) */\nconst stacksPrincipal = z.string().refine((val) => {\n const parts = val.split(\".\");\n if (parts.length > 2) return false;\n return isValidAddress(parts[0]!);\n}, \"Invalid Stacks principal address\");\n\n// Base filter with common fields\nconst baseFilter = {\n // Optional: filter by sender\n sender: stacksPrincipal.optional(),\n // Optional: filter by recipient\n recipient: stacksPrincipal.optional(),\n};\n\n// Type exports — defined first so they can annotate schemas\nexport interface StxTransferFilter {\n type: \"stx_transfer\";\n sender?: string;\n recipient?: string;\n minAmount?: number;\n maxAmount?: number;\n}\n\nexport interface StxMintFilter {\n type: \"stx_mint\";\n recipient?: string;\n minAmount?: number;\n}\n\nexport interface StxBurnFilter {\n type: \"stx_burn\";\n sender?: string;\n minAmount?: number;\n}\n\nexport interface StxLockFilter {\n type: \"stx_lock\";\n lockedAddress?: string;\n minAmount?: number;\n}\n\nexport interface FtTransferFilter {\n type: \"ft_transfer\";\n sender?: string;\n recipient?: string;\n assetIdentifier?: string;\n minAmount?: number;\n}\n\nexport interface FtMintFilter {\n type: \"ft_mint\";\n recipient?: string;\n assetIdentifier?: string;\n minAmount?: number;\n}\n\nexport interface FtBurnFilter {\n type: \"ft_burn\";\n sender?: string;\n assetIdentifier?: string;\n minAmount?: number;\n}\n\nexport interface NftTransferFilter {\n type: \"nft_transfer\";\n sender?: string;\n recipient?: string;\n assetIdentifier?: string;\n tokenId?: string;\n}\n\nexport interface NftMintFilter {\n type: \"nft_mint\";\n recipient?: string;\n assetIdentifier?: string;\n tokenId?: string;\n}\n\nexport interface NftBurnFilter {\n type: \"nft_burn\";\n sender?: string;\n assetIdentifier?: string;\n tokenId?: string;\n}\n\nexport interface ContractCallFilter {\n type: \"contract_call\";\n contractId?: string;\n functionName?: string;\n caller?: string;\n}\n\nexport interface ContractDeployFilter {\n type: \"contract_deploy\";\n deployer?: string;\n contractName?: string;\n}\n\nexport interface PrintEventFilter {\n type: \"print_event\";\n contractId?: string;\n topic?: string;\n contains?: string;\n}\n\nexport type StreamFilter =\n | StxTransferFilter\n | StxMintFilter\n | StxBurnFilter\n | StxLockFilter\n | FtTransferFilter\n | FtMintFilter\n | FtBurnFilter\n | NftTransferFilter\n | NftMintFilter\n | NftBurnFilter\n | ContractCallFilter\n | ContractDeployFilter\n | PrintEventFilter;\n\n// STX Transfer Filter\nexport const StxTransferFilterSchema: z.ZodType<StxTransferFilter> = z.object({\n type: z.literal(\"stx_transfer\"),\n ...baseFilter,\n // Optional: minimum amount in microSTX\n minAmount: z.coerce.number().int().positive().optional(),\n // Optional: maximum amount in microSTX\n maxAmount: z.coerce.number().int().positive().optional(),\n});\n\n// STX Mint Filter\nexport const StxMintFilterSchema: z.ZodType<StxMintFilter> = z.object({\n type: z.literal(\"stx_mint\"),\n recipient: stacksPrincipal.optional(),\n minAmount: z.coerce.number().int().positive().optional(),\n});\n\n// STX Burn Filter\nexport const StxBurnFilterSchema: z.ZodType<StxBurnFilter> = z.object({\n type: z.literal(\"stx_burn\"),\n sender: stacksPrincipal.optional(),\n minAmount: z.coerce.number().int().positive().optional(),\n});\n\n// STX Lock Filter\nexport const StxLockFilterSchema: z.ZodType<StxLockFilter> = z.object({\n type: z.literal(\"stx_lock\"),\n lockedAddress: stacksPrincipal.optional(),\n minAmount: z.coerce.number().int().positive().optional(),\n});\n\n// FT Transfer Filter\nexport const FtTransferFilterSchema: z.ZodType<FtTransferFilter> = z.object({\n type: z.literal(\"ft_transfer\"),\n ...baseFilter,\n // Contract that defines the token (e.g., SP3K8BC0PPEVCV7NZ6QSRWPQ2JE9E5B6N3PA0KBR9.token-wstx)\n assetIdentifier: z.string().optional(),\n minAmount: z.coerce.number().int().positive().optional(),\n});\n\n// FT Mint Filter\nexport const FtMintFilterSchema: z.ZodType<FtMintFilter> = z.object({\n type: z.literal(\"ft_mint\"),\n recipient: stacksPrincipal.optional(),\n assetIdentifier: z.string().optional(),\n minAmount: z.coerce.number().int().positive().optional(),\n});\n\n// FT Burn Filter\nexport const FtBurnFilterSchema: z.ZodType<FtBurnFilter> = z.object({\n type: z.literal(\"ft_burn\"),\n sender: stacksPrincipal.optional(),\n assetIdentifier: z.string().optional(),\n minAmount: z.coerce.number().int().positive().optional(),\n});\n\n// NFT Transfer Filter\nexport const NftTransferFilterSchema: z.ZodType<NftTransferFilter> = z.object({\n type: z.literal(\"nft_transfer\"),\n ...baseFilter,\n assetIdentifier: z.string().optional(),\n // Optional: filter by specific token ID (Clarity value as hex)\n tokenId: z.string().optional(),\n});\n\n// NFT Mint Filter\nexport const NftMintFilterSchema: z.ZodType<NftMintFilter> = z.object({\n type: z.literal(\"nft_mint\"),\n recipient: stacksPrincipal.optional(),\n assetIdentifier: z.string().optional(),\n tokenId: z.string().optional(),\n});\n\n// NFT Burn Filter\nexport const NftBurnFilterSchema: z.ZodType<NftBurnFilter> = z.object({\n type: z.literal(\"nft_burn\"),\n sender: stacksPrincipal.optional(),\n assetIdentifier: z.string().optional(),\n tokenId: z.string().optional(),\n});\n\n// Contract Call Filter\nexport const ContractCallFilterSchema: z.ZodType<ContractCallFilter> = z.object({\n type: z.literal(\"contract_call\"),\n // Contract being called\n contractId: stacksPrincipal.optional(),\n // Function name (supports wildcards with *)\n functionName: z.string().optional(),\n // Caller address\n caller: stacksPrincipal.optional(),\n});\n\n// Contract Deploy Filter\nexport const ContractDeployFilterSchema: z.ZodType<ContractDeployFilter> = z.object({\n type: z.literal(\"contract_deploy\"),\n // Deployer address\n deployer: stacksPrincipal.optional(),\n // Contract name pattern (supports wildcards)\n contractName: z.string().optional(),\n});\n\n// Print Event Filter (smart contract events)\nexport const PrintEventFilterSchema: z.ZodType<PrintEventFilter> = z.object({\n type: z.literal(\"print_event\"),\n // Contract emitting the event\n contractId: stacksPrincipal.optional(),\n // Topic/name of the event\n topic: z.string().optional(),\n // Search for substring in event data\n contains: z.string().optional(),\n});\n\n// Union of all filter types\nexport const StreamFilterSchema: z.ZodType<StreamFilter> = z.discriminatedUnion(\"type\", [\n StxTransferFilterSchema as z.ZodType<StxTransferFilter> & z.ZodTypeDef as any,\n StxMintFilterSchema as any,\n StxBurnFilterSchema as any,\n StxLockFilterSchema as any,\n FtTransferFilterSchema as any,\n FtMintFilterSchema as any,\n FtBurnFilterSchema as any,\n NftTransferFilterSchema as any,\n NftMintFilterSchema as any,\n NftBurnFilterSchema as any,\n ContractCallFilterSchema as any,\n ContractDeployFilterSchema as any,\n PrintEventFilterSchema as any,\n]);\n"
5
+ "import { z } from \"zod/v4\";\nimport { isValidAddress as _isValidAddress } from \"@secondlayer/stacks\";\n\nconst isValidAddress = _isValidAddress as (addr: string) => boolean;\n\n/** Validate a Stacks principal (standard or contract, e.g. SP2J...ABC or SP2J...ABC.contract-name) */\nconst stacksPrincipal = z.string().refine((val) => {\n const parts = val.split(\".\");\n if (parts.length > 2) return false;\n return isValidAddress(parts[0]!);\n}, \"Invalid Stacks principal address\");\n\n// Base filter with common fields\nconst baseFilter = {\n // Optional: filter by sender\n sender: stacksPrincipal.optional(),\n // Optional: filter by recipient\n recipient: stacksPrincipal.optional(),\n};\n\n// Type exports — defined first so they can annotate schemas\nexport interface StxTransferFilter {\n type: \"stx_transfer\";\n sender?: string;\n recipient?: string;\n minAmount?: number;\n maxAmount?: number;\n}\n\nexport interface StxMintFilter {\n type: \"stx_mint\";\n recipient?: string;\n minAmount?: number;\n}\n\nexport interface StxBurnFilter {\n type: \"stx_burn\";\n sender?: string;\n minAmount?: number;\n}\n\nexport interface StxLockFilter {\n type: \"stx_lock\";\n lockedAddress?: string;\n minAmount?: number;\n}\n\nexport interface FtTransferFilter {\n type: \"ft_transfer\";\n sender?: string;\n recipient?: string;\n assetIdentifier?: string;\n minAmount?: number;\n}\n\nexport interface FtMintFilter {\n type: \"ft_mint\";\n recipient?: string;\n assetIdentifier?: string;\n minAmount?: number;\n}\n\nexport interface FtBurnFilter {\n type: \"ft_burn\";\n sender?: string;\n assetIdentifier?: string;\n minAmount?: number;\n}\n\nexport interface NftTransferFilter {\n type: \"nft_transfer\";\n sender?: string;\n recipient?: string;\n assetIdentifier?: string;\n tokenId?: string;\n}\n\nexport interface NftMintFilter {\n type: \"nft_mint\";\n recipient?: string;\n assetIdentifier?: string;\n tokenId?: string;\n}\n\nexport interface NftBurnFilter {\n type: \"nft_burn\";\n sender?: string;\n assetIdentifier?: string;\n tokenId?: string;\n}\n\nexport interface ContractCallFilter {\n type: \"contract_call\";\n contractId?: string;\n functionName?: string;\n caller?: string;\n}\n\nexport interface ContractDeployFilter {\n type: \"contract_deploy\";\n deployer?: string;\n contractName?: string;\n}\n\nexport interface PrintEventFilter {\n type: \"print_event\";\n contractId?: string;\n topic?: string;\n contains?: string;\n}\n\nexport type StreamFilter =\n | StxTransferFilter\n | StxMintFilter\n | StxBurnFilter\n | StxLockFilter\n | FtTransferFilter\n | FtMintFilter\n | FtBurnFilter\n | NftTransferFilter\n | NftMintFilter\n | NftBurnFilter\n | ContractCallFilter\n | ContractDeployFilter\n | PrintEventFilter;\n\n// STX Transfer Filter\nexport const StxTransferFilterSchema: z.ZodType<StxTransferFilter> = z.object({\n type: z.literal(\"stx_transfer\"),\n ...baseFilter,\n // Optional: minimum amount in microSTX\n minAmount: z.coerce.number().int().positive().optional(),\n // Optional: maximum amount in microSTX\n maxAmount: z.coerce.number().int().positive().optional(),\n});\n\n// STX Mint Filter\nexport const StxMintFilterSchema: z.ZodType<StxMintFilter> = z.object({\n type: z.literal(\"stx_mint\"),\n recipient: stacksPrincipal.optional(),\n minAmount: z.coerce.number().int().positive().optional(),\n});\n\n// STX Burn Filter\nexport const StxBurnFilterSchema: z.ZodType<StxBurnFilter> = z.object({\n type: z.literal(\"stx_burn\"),\n sender: stacksPrincipal.optional(),\n minAmount: z.coerce.number().int().positive().optional(),\n});\n\n// STX Lock Filter\nexport const StxLockFilterSchema: z.ZodType<StxLockFilter> = z.object({\n type: z.literal(\"stx_lock\"),\n lockedAddress: stacksPrincipal.optional(),\n minAmount: z.coerce.number().int().positive().optional(),\n});\n\n// FT Transfer Filter\nexport const FtTransferFilterSchema: z.ZodType<FtTransferFilter> = z.object({\n type: z.literal(\"ft_transfer\"),\n ...baseFilter,\n // Contract that defines the token (e.g., SP3K8BC0PPEVCV7NZ6QSRWPQ2JE9E5B6N3PA0KBR9.token-wstx)\n assetIdentifier: z.string().optional(),\n minAmount: z.coerce.number().int().positive().optional(),\n});\n\n// FT Mint Filter\nexport const FtMintFilterSchema: z.ZodType<FtMintFilter> = z.object({\n type: z.literal(\"ft_mint\"),\n recipient: stacksPrincipal.optional(),\n assetIdentifier: z.string().optional(),\n minAmount: z.coerce.number().int().positive().optional(),\n});\n\n// FT Burn Filter\nexport const FtBurnFilterSchema: z.ZodType<FtBurnFilter> = z.object({\n type: z.literal(\"ft_burn\"),\n sender: stacksPrincipal.optional(),\n assetIdentifier: z.string().optional(),\n minAmount: z.coerce.number().int().positive().optional(),\n});\n\n// NFT Transfer Filter\nexport const NftTransferFilterSchema: z.ZodType<NftTransferFilter> = z.object({\n type: z.literal(\"nft_transfer\"),\n ...baseFilter,\n assetIdentifier: z.string().optional(),\n // Optional: filter by specific token ID (Clarity value as hex)\n tokenId: z.string().optional(),\n});\n\n// NFT Mint Filter\nexport const NftMintFilterSchema: z.ZodType<NftMintFilter> = z.object({\n type: z.literal(\"nft_mint\"),\n recipient: stacksPrincipal.optional(),\n assetIdentifier: z.string().optional(),\n tokenId: z.string().optional(),\n});\n\n// NFT Burn Filter\nexport const NftBurnFilterSchema: z.ZodType<NftBurnFilter> = z.object({\n type: z.literal(\"nft_burn\"),\n sender: stacksPrincipal.optional(),\n assetIdentifier: z.string().optional(),\n tokenId: z.string().optional(),\n});\n\n// Contract Call Filter\nexport const ContractCallFilterSchema: z.ZodType<ContractCallFilter> = z.object({\n type: z.literal(\"contract_call\"),\n // Contract being called\n contractId: stacksPrincipal.optional(),\n // Function name (supports wildcards with *)\n functionName: z.string().optional(),\n // Caller address\n caller: stacksPrincipal.optional(),\n});\n\n// Contract Deploy Filter\nexport const ContractDeployFilterSchema: z.ZodType<ContractDeployFilter> = z.object({\n type: z.literal(\"contract_deploy\"),\n // Deployer address\n deployer: stacksPrincipal.optional(),\n // Contract name pattern (supports wildcards)\n contractName: z.string().optional(),\n});\n\n// Print Event Filter (smart contract events)\nexport const PrintEventFilterSchema: z.ZodType<PrintEventFilter> = z.object({\n type: z.literal(\"print_event\"),\n // Contract emitting the event\n contractId: stacksPrincipal.optional(),\n // Topic/name of the event\n topic: z.string().optional(),\n // Search for substring in event data\n contains: z.string().optional(),\n});\n\n// Union of all filter types\nexport const StreamFilterSchema: z.ZodType<StreamFilter> = z.discriminatedUnion(\"type\", [\n StxTransferFilterSchema as any,\n StxMintFilterSchema as any,\n StxBurnFilterSchema as any,\n StxLockFilterSchema as any,\n FtTransferFilterSchema as any,\n FtMintFilterSchema as any,\n FtBurnFilterSchema as any,\n NftTransferFilterSchema as any,\n NftMintFilterSchema as any,\n NftBurnFilterSchema as any,\n ContractCallFilterSchema as any,\n ContractDeployFilterSchema as any,\n PrintEventFilterSchema as any,\n]);\n"
6
6
  ],
7
7
  "mappings": "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",
8
- "debugId": "B04556256345C38264756E2164756E21",
8
+ "debugId": "9BF41B1F9FD47F8764756E2164756E21",
9
9
  "names": []
10
10
  }