@secondlayer/shared 6.41.3 → 7.0.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.
@@ -63,6 +63,13 @@ interface BlockResponse {
63
63
  declare class StacksNodeClient {
64
64
  private rpcUrl;
65
65
  constructor(rpcUrl?: string);
66
+ /**
67
+ * A stacks-backed client for the given call's original timeout, with no
68
+ * retries — matches every method's prior single-attempt fetch semantics
69
+ * (in particular `getInfo`'s fast-fail timing, which `isHealthy()` and its
70
+ * callers depend on).
71
+ */
72
+ private client;
66
73
  getInfo(): Promise<NodeInfo>;
67
74
  getBlock(height: number): Promise<BlockResponse | null>;
68
75
  /**
@@ -83,8 +90,6 @@ declare class StacksNodeClient {
83
90
  getRewardSet(cycle: number): Promise<RewardSet | null>;
84
91
  isHealthy(): Promise<boolean>;
85
92
  getContractAbi(contractId: string): Promise<unknown>;
86
- /** Fetch a contract's Clarity source — used to parse declared `impl-trait`s. */
87
- getContractSource(contractId: string): Promise<string | null>;
88
93
  getRpcUrl(): string;
89
94
  }
90
95
  export { StacksNodeClient, NodeInfo, BlockResponse };
@@ -163,30 +163,26 @@ async function fetchNakamotoBlock(opts) {
163
163
  }
164
164
 
165
165
  // src/node/client.ts
166
+ import { http, createPublicClient } from "@secondlayer/stacks";
167
+ import { getContractAbi, getRawBlock } from "@secondlayer/stacks/actions";
166
168
  class StacksNodeClient {
167
169
  rpcUrl;
168
170
  constructor(rpcUrl) {
169
171
  this.rpcUrl = rpcUrl || process.env.STACKS_NODE_RPC_URL || "http://localhost:20443";
170
172
  }
173
+ client(timeoutMs) {
174
+ return createPublicClient({
175
+ transport: http(this.rpcUrl, { retryCount: 0, timeout: timeoutMs })
176
+ });
177
+ }
171
178
  async getInfo() {
172
- const res = await fetch(`${this.rpcUrl}/v2/info`, {
173
- signal: AbortSignal.timeout(1e4)
179
+ const data = await this.client(1e4).request("/v2/info", {
180
+ method: "GET"
174
181
  });
175
- if (!res.ok) {
176
- throw new Error(`Node RPC /v2/info returned ${res.status}`);
177
- }
178
- return res.json();
182
+ return data;
179
183
  }
180
184
  async getBlock(height) {
181
- const res = await fetch(`${this.rpcUrl}/v2/blocks/${height}`, {
182
- signal: AbortSignal.timeout(30000)
183
- });
184
- if (res.status === 404)
185
- return null;
186
- if (!res.ok) {
187
- throw new Error(`Node RPC /v2/blocks/${height} returned ${res.status}`);
188
- }
189
- return res.json();
185
+ return getRawBlock(this.client(30000), { height });
190
186
  }
191
187
  async getNakamotoBlock(blockId) {
192
188
  const id = blockId.startsWith("0x") ? blockId.slice(2) : blockId;
@@ -236,26 +232,7 @@ class StacksNodeClient {
236
232
  }
237
233
  }
238
234
  async getContractAbi(contractId) {
239
- const dotIdx = contractId.indexOf(".");
240
- const address = contractId.slice(0, dotIdx);
241
- const name = contractId.slice(dotIdx + 1);
242
- const res = await fetch(`${this.rpcUrl}/v2/contracts/interface/${address}/${name}`, {
243
- signal: AbortSignal.timeout(30000)
244
- });
245
- if (!res.ok) {
246
- throw new Error(`Node RPC /v2/contracts/interface/${address}/${name} returned ${res.status}`);
247
- }
248
- return res.json();
249
- }
250
- async getContractSource(contractId) {
251
- const dotIdx = contractId.indexOf(".");
252
- const address = contractId.slice(0, dotIdx);
253
- const name = contractId.slice(dotIdx + 1);
254
- const res = await fetch(`${this.rpcUrl}/v2/contracts/source/${address}/${name}`, { signal: AbortSignal.timeout(30000) });
255
- if (!res.ok)
256
- return null;
257
- const body = await res.json();
258
- return body.source ?? null;
235
+ return getContractAbi(this.client(30000), { contract: contractId });
259
236
  }
260
237
  getRpcUrl() {
261
238
  return this.rpcUrl;
@@ -265,5 +242,5 @@ export {
265
242
  StacksNodeClient
266
243
  };
267
244
 
268
- //# debugId=26D700D33629603864756E2164756E21
245
+ //# debugId=6FECB3B2F9B1896F64756E2164756E21
269
246
  //# sourceMappingURL=client.js.map
@@ -3,9 +3,9 @@
3
3
  "sources": ["../src/node/nakamoto.ts", "../src/node/client.ts"],
4
4
  "sourcesContent": [
5
5
  "import { createHash } from \"node:crypto\";\n\n/**\n * Nakamoto block-header parsing + consensus hashing for trustless verification.\n *\n * Every constant here is verified bit-exact against mainnet `stacks-node\n * 3.4.0.0.3` (see docs/design/trustless-verification-proofs.md, Appendix). This\n * Building block for transaction-inclusion / block-canonicity proofs: fetch a\n * raw `/v3/blocks/{id}` body, parse the header, and recompute the block_hash,\n * index_block_hash, and tx_merkle_root the chain itself commits to.\n */\n\n/** SHA-512/256 — the hash Stacks uses everywhere (NOT truncated SHA-512). */\nexport function sha512_256(bytes: Uint8Array): Uint8Array {\n\treturn createHash(\"sha512-256\").update(bytes).digest();\n}\n\nconst toHex = (b: Uint8Array): string => Buffer.from(b).toString(\"hex\");\nconst fromHex = (h: string): Uint8Array =>\n\tUint8Array.from(Buffer.from(h.startsWith(\"0x\") ? h.slice(2) : h, \"hex\"));\n\n// Fixed-size header prefix: version..miner_signature, before signer_signature.\nconst PREFIX_LEN = 206;\nconst CONSENSUS_HASH_OFF = 17;\nconst TX_MERKLE_ROOT_OFF = 69;\nconst STATE_INDEX_ROOT_OFF = 101;\nconst TIMESTAMP_OFF = 133;\nconst MINER_SIG_OFF = 141;\nconst SIGNER_VEC_OFF = 206; // u32 count, then 65 bytes per signer\nconst SIG_LEN = 65;\n\nexport interface NakamotoBlockHeader {\n\tversion: number;\n\tchainLength: bigint;\n\tburnSpent: bigint;\n\t/** 20-byte consensus hash (hex). */\n\tconsensusHash: string;\n\t/** 32-byte parent StacksBlockId (hex). */\n\tparentBlockId: string;\n\t/** 32-byte SHA512/256 merkle root over the block's txids (hex). */\n\ttxMerkleRoot: string;\n\t/** 32-byte MARF root after applying this block (hex). */\n\tstateIndexRoot: string;\n\ttimestamp: bigint;\n\t/** 65-byte recoverable ECDSA miner signature (hex). */\n\tminerSignature: string;\n\t/** Per-signer recoverable ECDSA signatures, reward-set order (hex, 65B each). */\n\tsignerSignatures: string[];\n\t/** Full serialized pox_treatment BitVec bytes (u16 bits ‖ u32 len ‖ data). */\n\tpoxTreatment: Uint8Array;\n\t/**\n\t * Exact bytes whose SHA512/256 IS the block_hash / signer_signature_hash:\n\t * the header with the signer_signature vector omitted (header[0:206] ‖ pox).\n\t */\n\tsignerSignatureHashPreimage: Uint8Array;\n\t/** Offset at which the tx `Vec` begins (= total header byte length). */\n\theaderByteLength: number;\n}\n\nfunction u32(b: Uint8Array, off: number): number {\n\treturn new DataView(b.buffer, b.byteOffset, b.byteLength).getUint32(off);\n}\nfunction u64(b: Uint8Array, off: number): bigint {\n\treturn new DataView(b.buffer, b.byteOffset, b.byteLength).getBigUint64(off);\n}\n\n/** Parse the Nakamoto block header from the raw `/v3/blocks` body. */\nexport function parseNakamotoBlockHeader(raw: Uint8Array): NakamotoBlockHeader {\n\tif (raw.length < PREFIX_LEN + 4) {\n\t\tthrow new Error(\"raw block too short for a Nakamoto header\");\n\t}\n\tconst signerCount = u32(raw, SIGNER_VEC_OFF);\n\tconst sigsStart = SIGNER_VEC_OFF + 4;\n\tconst signerSignatures: string[] = [];\n\tfor (let i = 0; i < signerCount; i++) {\n\t\tconst off = sigsStart + i * SIG_LEN;\n\t\tsignerSignatures.push(toHex(raw.subarray(off, off + SIG_LEN)));\n\t}\n\t// pox_treatment: u16 num_bits ‖ u32 data_len ‖ data[data_len].\n\tconst poxOff = sigsStart + signerCount * SIG_LEN;\n\tconst poxDataLen = u32(raw, poxOff + 2);\n\tconst poxEnd = poxOff + 6 + poxDataLen;\n\tconst poxTreatment = raw.subarray(poxOff, poxEnd);\n\n\t// block_hash preimage = header minus signer_signature = prefix[0:206] ‖ pox.\n\tconst preimage = new Uint8Array(PREFIX_LEN + poxTreatment.length);\n\tpreimage.set(raw.subarray(0, PREFIX_LEN), 0);\n\tpreimage.set(poxTreatment, PREFIX_LEN);\n\n\treturn {\n\t\tversion: raw[0],\n\t\tchainLength: u64(raw, 1),\n\t\tburnSpent: u64(raw, 9),\n\t\tconsensusHash: toHex(\n\t\t\traw.subarray(CONSENSUS_HASH_OFF, CONSENSUS_HASH_OFF + 20),\n\t\t),\n\t\tparentBlockId: toHex(raw.subarray(37, 69)),\n\t\ttxMerkleRoot: toHex(\n\t\t\traw.subarray(TX_MERKLE_ROOT_OFF, TX_MERKLE_ROOT_OFF + 32),\n\t\t),\n\t\tstateIndexRoot: toHex(\n\t\t\traw.subarray(STATE_INDEX_ROOT_OFF, STATE_INDEX_ROOT_OFF + 32),\n\t\t),\n\t\ttimestamp: u64(raw, TIMESTAMP_OFF),\n\t\tminerSignature: toHex(raw.subarray(MINER_SIG_OFF, MINER_SIG_OFF + SIG_LEN)),\n\t\tsignerSignatures,\n\t\tpoxTreatment,\n\t\tsignerSignatureHashPreimage: preimage,\n\t\theaderByteLength: poxEnd,\n\t};\n}\n\n/**\n * block_hash (== signer_signature_hash): SHA512/256 over the header with the\n * signer_signature vector omitted. This is what each signer signs.\n */\nexport function nakamotoBlockHash(header: NakamotoBlockHeader): string {\n\treturn toHex(sha512_256(header.signerSignatureHashPreimage));\n}\n\n/** index_block_hash (StacksBlockId) = SHA512/256(block_hash ‖ consensus_hash). */\nexport function nakamotoBlockId(\n\tblockHashHex: string,\n\tconsensusHashHex: string,\n): string {\n\tconst a = fromHex(blockHashHex);\n\tconst b = fromHex(consensusHashHex);\n\tconst buf = new Uint8Array(a.length + b.length);\n\tbuf.set(a, 0);\n\tbuf.set(b, a.length);\n\treturn toHex(sha512_256(buf));\n}\n\n/** A Stacks txid = SHA512/256 of the transaction's consensus serialization. */\nexport function stacksTxid(rawTx: Uint8Array): string {\n\treturn toHex(sha512_256(rawTx));\n}\n\nconst LEAF_TAG = 0x00;\nconst NODE_TAG = 0x01;\n\nfunction tagged(tag: number, ...parts: Uint8Array[]): Uint8Array {\n\tconst len = parts.reduce((n, p) => n + p.length, 1);\n\tconst buf = new Uint8Array(len);\n\tbuf[0] = tag;\n\tlet o = 1;\n\tfor (const p of parts) {\n\t\tbuf.set(p, o);\n\t\to += p.length;\n\t}\n\treturn sha512_256(buf);\n}\n\n/**\n * tx_merkle_root over the block's txids (hex), reproducing the consensus rule:\n * leaf = H(0x00 ‖ txid), node = H(0x01 ‖ left ‖ right), odd level duplicates the\n * last node. Returns the root hex; throws on an empty tx list.\n */\nexport function txMerkleRoot(txidsHex: string[]): string {\n\tif (txidsHex.length === 0) throw new Error(\"no transactions\");\n\tlet level = txidsHex.map((t) => tagged(LEAF_TAG, fromHex(t)));\n\twhile (level.length > 1) {\n\t\tif (level.length % 2 === 1) level.push(level[level.length - 1]);\n\t\tconst next: Uint8Array[] = [];\n\t\tfor (let i = 0; i < level.length; i += 2) {\n\t\t\tnext.push(tagged(NODE_TAG, level[i], level[i + 1]));\n\t\t}\n\t\tlevel = next;\n\t}\n\treturn toHex(level[0]);\n}\n\n/** One authentication-path step: the sibling hash and which side it's on. */\nexport interface MerkleProofStep {\n\t/** Side the SIBLING is on relative to the accumulator. */\n\tposition: \"left\" | \"right\";\n\t/** Sibling node hash (hex). */\n\thash: string;\n}\n\n/**\n * Build the tx-inclusion authentication path for the tx at `index` in a block,\n * reproducing the consensus merkle tree (incl. duplicate-last-on-odd). The path\n * lets a verifier recompute `tx_merkle_root` from just the target txid.\n */\nexport function txMerkleProof(\n\ttxidsHex: string[],\n\tindex: number,\n): MerkleProofStep[] {\n\tif (index < 0 || index >= txidsHex.length) {\n\t\tthrow new Error(\"index out of range\");\n\t}\n\tlet level = txidsHex.map((t) => tagged(LEAF_TAG, fromHex(t)));\n\tlet idx = index;\n\tconst path: MerkleProofStep[] = [];\n\twhile (level.length > 1) {\n\t\tif (level.length % 2 === 1) level.push(level[level.length - 1]);\n\t\tconst siblingIdx = idx % 2 === 0 ? idx + 1 : idx - 1;\n\t\tpath.push({\n\t\t\tposition: idx % 2 === 0 ? \"right\" : \"left\",\n\t\t\thash: toHex(level[siblingIdx]),\n\t\t});\n\t\tconst next: Uint8Array[] = [];\n\t\tfor (let i = 0; i < level.length; i += 2) {\n\t\t\tnext.push(tagged(NODE_TAG, level[i], level[i + 1]));\n\t\t}\n\t\tlevel = next;\n\t\tidx = Math.floor(idx / 2);\n\t}\n\treturn path;\n}\n\n/**\n * Verify a tx-inclusion proof: fold the target `txid` (hex) up through `path`\n * and check it equals `txMerkleRoot` (hex). The verifier recomputes the txid\n * itself from the raw tx bytes, so nothing here is trusted.\n */\nexport function verifyTxMerkleProof(\n\ttxidHex: string,\n\tpath: MerkleProofStep[],\n\ttxMerkleRootHex: string,\n): boolean {\n\tlet acc = tagged(LEAF_TAG, fromHex(txidHex));\n\tfor (const step of path) {\n\t\tconst sib = fromHex(step.hash);\n\t\tacc =\n\t\t\tstep.position === \"right\"\n\t\t\t\t? tagged(NODE_TAG, acc, sib)\n\t\t\t\t: tagged(NODE_TAG, sib, acc);\n\t}\n\tconst root = txMerkleRootHex.startsWith(\"0x\")\n\t\t? txMerkleRootHex.slice(2)\n\t\t: txMerkleRootHex;\n\treturn toHex(acc) === root;\n}\n\n/**\n * Fetch and parse a Nakamoto block from a stacks-node. `blockId` is the\n * index_block_hash (with or without 0x). Returns the raw bytes + parsed header +\n * the recomputed block_hash / index_block_hash so a caller can cross-check.\n */\nexport async function fetchNakamotoBlock(opts: {\n\tnodeUrl: string;\n\tblockId: string;\n\tfetchImpl?: typeof fetch;\n}): Promise<{\n\traw: Uint8Array;\n\theader: NakamotoBlockHeader;\n\tblockHash: string;\n\tindexBlockHash: string;\n}> {\n\tconst id = opts.blockId.startsWith(\"0x\")\n\t\t? opts.blockId.slice(2)\n\t\t: opts.blockId;\n\tconst f = opts.fetchImpl ?? fetch;\n\tconst res = await f(`${opts.nodeUrl.replace(/\\/+$/, \"\")}/v3/blocks/${id}`);\n\tif (!res.ok) {\n\t\tthrow new Error(`/v3/blocks/${id} returned ${res.status}`);\n\t}\n\tconst raw = new Uint8Array(await res.arrayBuffer());\n\tconst header = parseNakamotoBlockHeader(raw);\n\tconst blockHash = nakamotoBlockHash(header);\n\treturn {\n\t\traw,\n\t\theader,\n\t\tblockHash,\n\t\tindexBlockHash: nakamotoBlockId(blockHash, header.consensusHash),\n\t};\n}\n",
6
- "import type { RewardSet } from \"./consensus.ts\";\nimport {\n\ttype NakamotoBlockHeader,\n\tnakamotoBlockHash,\n\tnakamotoBlockId,\n\tparseNakamotoBlockHeader,\n} from \"./nakamoto.ts\";\n\nexport interface NodeInfo {\n\tpeer_version: number;\n\tpox_consensus: string;\n\tburn_block_height: number;\n\tstable_pox_consensus: string;\n\tstable_burn_block_height: number;\n\tserver_version: string;\n\tnetwork_id: number;\n\tparent_network_id: number;\n\tstacks_tip_height: number;\n\tstacks_tip: string;\n\tstacks_tip_consensus_hash: string;\n\tgenesis_chainstate_hash: string;\n}\n\nexport interface BlockResponse {\n\thash: string;\n\theight: number;\n\tparent_block_hash: string;\n\tburn_block_height: number;\n\tburn_block_hash: string;\n\tburn_block_time: number;\n\tindex_block_hash: string;\n\tparent_index_block_hash: string;\n\tminer_txid: string;\n\ttxs: string[];\n\t// Full block data varies by endpoint — kept minimal for fetch use case\n}\n\nexport class StacksNodeClient {\n\tprivate rpcUrl: string;\n\n\tconstructor(rpcUrl?: string) {\n\t\tthis.rpcUrl =\n\t\t\trpcUrl || process.env.STACKS_NODE_RPC_URL || \"http://localhost:20443\";\n\t}\n\n\tasync getInfo(): Promise<NodeInfo> {\n\t\tconst res = await fetch(`${this.rpcUrl}/v2/info`, {\n\t\t\tsignal: AbortSignal.timeout(10_000),\n\t\t});\n\t\tif (!res.ok) {\n\t\t\tthrow new Error(`Node RPC /v2/info returned ${res.status}`);\n\t\t}\n\t\treturn res.json() as Promise<NodeInfo>;\n\t}\n\n\tasync getBlock(height: number): Promise<BlockResponse | null> {\n\t\t// Stacks API v2 block-by-height endpoint\n\t\tconst res = await fetch(`${this.rpcUrl}/v2/blocks/${height}`, {\n\t\t\tsignal: AbortSignal.timeout(30_000),\n\t\t});\n\t\tif (res.status === 404) return null;\n\t\tif (!res.ok) {\n\t\t\tthrow new Error(`Node RPC /v2/blocks/${height} returned ${res.status}`);\n\t\t}\n\t\treturn res.json() as Promise<BlockResponse>;\n\t}\n\n\t/**\n\t * Fetch + parse a Nakamoto block by its index_block_hash. Returns the raw\n\t * bytes, the parsed header, and the recomputed block_hash / index_block_hash\n\t * (so a caller can cross-check the node's answer). Null on 404.\n\t */\n\tasync getNakamotoBlock(blockId: string): Promise<{\n\t\traw: Uint8Array;\n\t\theader: NakamotoBlockHeader;\n\t\tblockHash: string;\n\t\tindexBlockHash: string;\n\t} | null> {\n\t\tconst id = blockId.startsWith(\"0x\") ? blockId.slice(2) : blockId;\n\t\tconst res = await fetch(`${this.rpcUrl}/v3/blocks/${id}`, {\n\t\t\tsignal: AbortSignal.timeout(30_000),\n\t\t});\n\t\tif (res.status === 404) return null;\n\t\tif (!res.ok) {\n\t\t\tthrow new Error(`Node RPC /v3/blocks/${id} returned ${res.status}`);\n\t\t}\n\t\tconst raw = new Uint8Array(await res.arrayBuffer());\n\t\tconst header = parseNakamotoBlockHeader(raw);\n\t\tconst blockHash = nakamotoBlockHash(header);\n\t\treturn {\n\t\t\traw,\n\t\t\theader,\n\t\t\tblockHash,\n\t\t\tindexBlockHash: nakamotoBlockId(blockHash, header.consensusHash),\n\t\t};\n\t}\n\n\t/**\n\t * Fetch the reward set (signer keys + weights) for a reward cycle from\n\t * `/v3/stacker_set/{cycle}`. Null on 404 (cycle not yet computed).\n\t */\n\tasync getRewardSet(cycle: number): Promise<RewardSet | null> {\n\t\tconst res = await fetch(`${this.rpcUrl}/v3/stacker_set/${cycle}`, {\n\t\t\tsignal: AbortSignal.timeout(15_000),\n\t\t});\n\t\tif (res.status === 404) return null;\n\t\tif (!res.ok) {\n\t\t\tthrow new Error(\n\t\t\t\t`Node RPC /v3/stacker_set/${cycle} returned ${res.status}`,\n\t\t\t);\n\t\t}\n\t\tconst body = (await res.json()) as {\n\t\t\tstacker_set: { signers: { signing_key: string; weight: number }[] };\n\t\t};\n\t\tconst signers = body.stacker_set.signers.map((s) => ({\n\t\t\tsigning_key: s.signing_key.startsWith(\"0x\")\n\t\t\t\t? s.signing_key.slice(2)\n\t\t\t\t: s.signing_key,\n\t\t\tweight: s.weight,\n\t\t}));\n\t\treturn {\n\t\t\tsigners,\n\t\t\ttotal_weight: signers.reduce((sum, s) => sum + s.weight, 0),\n\t\t};\n\t}\n\n\tasync isHealthy(): Promise<boolean> {\n\t\ttry {\n\t\t\tconst info = await this.getInfo();\n\t\t\treturn info.stacks_tip_height > 0;\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tasync getContractAbi(contractId: string): Promise<unknown> {\n\t\tconst dotIdx = contractId.indexOf(\".\");\n\t\tconst address = contractId.slice(0, dotIdx);\n\t\tconst name = contractId.slice(dotIdx + 1);\n\t\tconst res = await fetch(\n\t\t\t`${this.rpcUrl}/v2/contracts/interface/${address}/${name}`,\n\t\t\t{\n\t\t\t\tsignal: AbortSignal.timeout(30_000),\n\t\t\t},\n\t\t);\n\t\tif (!res.ok) {\n\t\t\tthrow new Error(\n\t\t\t\t`Node RPC /v2/contracts/interface/${address}/${name} returned ${res.status}`,\n\t\t\t);\n\t\t}\n\t\treturn res.json();\n\t}\n\n\t/** Fetch a contract's Clarity source — used to parse declared `impl-trait`s. */\n\tasync getContractSource(contractId: string): Promise<string | null> {\n\t\tconst dotIdx = contractId.indexOf(\".\");\n\t\tconst address = contractId.slice(0, dotIdx);\n\t\tconst name = contractId.slice(dotIdx + 1);\n\t\tconst res = await fetch(\n\t\t\t`${this.rpcUrl}/v2/contracts/source/${address}/${name}`,\n\t\t\t{ signal: AbortSignal.timeout(30_000) },\n\t\t);\n\t\tif (!res.ok) return null;\n\t\tconst body = (await res.json()) as { source?: string };\n\t\treturn body.source ?? null;\n\t}\n\n\tgetRpcUrl(): string {\n\t\treturn this.rpcUrl;\n\t}\n}\n"
6
+ "import { http, createPublicClient } from \"@secondlayer/stacks\";\nimport { getContractAbi, getRawBlock } from \"@secondlayer/stacks/actions\";\nimport type { RewardSet } from \"./consensus.ts\";\nimport {\n\ttype NakamotoBlockHeader,\n\tnakamotoBlockHash,\n\tnakamotoBlockId,\n\tparseNakamotoBlockHeader,\n} from \"./nakamoto.ts\";\n\nexport interface NodeInfo {\n\tpeer_version: number;\n\tpox_consensus: string;\n\tburn_block_height: number;\n\tstable_pox_consensus: string;\n\tstable_burn_block_height: number;\n\tserver_version: string;\n\tnetwork_id: number;\n\tparent_network_id: number;\n\tstacks_tip_height: number;\n\tstacks_tip: string;\n\tstacks_tip_consensus_hash: string;\n\tgenesis_chainstate_hash: string;\n}\n\nexport interface BlockResponse {\n\thash: string;\n\theight: number;\n\tparent_block_hash: string;\n\tburn_block_height: number;\n\tburn_block_hash: string;\n\tburn_block_time: number;\n\tindex_block_hash: string;\n\tparent_index_block_hash: string;\n\tminer_txid: string;\n\ttxs: string[];\n\t// Full block data varies by endpoint — kept minimal for fetch use case\n}\n\nexport class StacksNodeClient {\n\tprivate rpcUrl: string;\n\n\tconstructor(rpcUrl?: string) {\n\t\tthis.rpcUrl =\n\t\t\trpcUrl || process.env.STACKS_NODE_RPC_URL || \"http://localhost:20443\";\n\t}\n\n\t/**\n\t * A stacks-backed client for the given call's original timeout, with no\n\t * retries — matches every method's prior single-attempt fetch semantics\n\t * (in particular `getInfo`'s fast-fail timing, which `isHealthy()` and its\n\t * callers depend on).\n\t */\n\tprivate client(timeoutMs: number) {\n\t\treturn createPublicClient({\n\t\t\ttransport: http(this.rpcUrl, { retryCount: 0, timeout: timeoutMs }),\n\t\t});\n\t}\n\n\tasync getInfo(): Promise<NodeInfo> {\n\t\tconst data = await this.client(10_000).request(\"/v2/info\", {\n\t\t\tmethod: \"GET\",\n\t\t});\n\t\treturn data as NodeInfo;\n\t}\n\n\tasync getBlock(height: number): Promise<BlockResponse | null> {\n\t\treturn getRawBlock(this.client(30_000), { height });\n\t}\n\n\t/**\n\t * Fetch + parse a Nakamoto block by its index_block_hash. Returns the raw\n\t * bytes, the parsed header, and the recomputed block_hash / index_block_hash\n\t * (so a caller can cross-check the node's answer). Null on 404.\n\t */\n\tasync getNakamotoBlock(blockId: string): Promise<{\n\t\traw: Uint8Array;\n\t\theader: NakamotoBlockHeader;\n\t\tblockHash: string;\n\t\tindexBlockHash: string;\n\t} | null> {\n\t\tconst id = blockId.startsWith(\"0x\") ? blockId.slice(2) : blockId;\n\t\tconst res = await fetch(`${this.rpcUrl}/v3/blocks/${id}`, {\n\t\t\tsignal: AbortSignal.timeout(30_000),\n\t\t});\n\t\tif (res.status === 404) return null;\n\t\tif (!res.ok) {\n\t\t\tthrow new Error(`Node RPC /v3/blocks/${id} returned ${res.status}`);\n\t\t}\n\t\tconst raw = new Uint8Array(await res.arrayBuffer());\n\t\tconst header = parseNakamotoBlockHeader(raw);\n\t\tconst blockHash = nakamotoBlockHash(header);\n\t\treturn {\n\t\t\traw,\n\t\t\theader,\n\t\t\tblockHash,\n\t\t\tindexBlockHash: nakamotoBlockId(blockHash, header.consensusHash),\n\t\t};\n\t}\n\n\t/**\n\t * Fetch the reward set (signer keys + weights) for a reward cycle from\n\t * `/v3/stacker_set/{cycle}`. Null on 404 (cycle not yet computed).\n\t */\n\tasync getRewardSet(cycle: number): Promise<RewardSet | null> {\n\t\tconst res = await fetch(`${this.rpcUrl}/v3/stacker_set/${cycle}`, {\n\t\t\tsignal: AbortSignal.timeout(15_000),\n\t\t});\n\t\tif (res.status === 404) return null;\n\t\tif (!res.ok) {\n\t\t\tthrow new Error(\n\t\t\t\t`Node RPC /v3/stacker_set/${cycle} returned ${res.status}`,\n\t\t\t);\n\t\t}\n\t\tconst body = (await res.json()) as {\n\t\t\tstacker_set: { signers: { signing_key: string; weight: number }[] };\n\t\t};\n\t\tconst signers = body.stacker_set.signers.map((s) => ({\n\t\t\tsigning_key: s.signing_key.startsWith(\"0x\")\n\t\t\t\t? s.signing_key.slice(2)\n\t\t\t\t: s.signing_key,\n\t\t\tweight: s.weight,\n\t\t}));\n\t\treturn {\n\t\t\tsigners,\n\t\t\ttotal_weight: signers.reduce((sum, s) => sum + s.weight, 0),\n\t\t};\n\t}\n\n\tasync isHealthy(): Promise<boolean> {\n\t\ttry {\n\t\t\tconst info = await this.getInfo();\n\t\t\treturn info.stacks_tip_height > 0;\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tasync getContractAbi(contractId: string): Promise<unknown> {\n\t\treturn getContractAbi(this.client(30_000), { contract: contractId });\n\t}\n\n\tgetRpcUrl(): string {\n\t\treturn this.rpcUrl;\n\t}\n}\n"
7
7
  ],
8
- "mappings": "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",
9
- "debugId": "26D700D33629603864756E2164756E21",
8
+ "mappings": "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",
9
+ "debugId": "6FECB3B2F9B1896F64756E2164756E21",
10
10
  "names": []
11
11
  }
@@ -21,14 +21,6 @@ interface HiroBlockTxsResponse {
21
21
  total: number;
22
22
  results: HiroTxResponse[];
23
23
  }
24
- /** Minimal shape returned by `HiroClient.getTransaction` (extended `/v1/tx`). */
25
- interface HiroTransaction {
26
- tx_id: string;
27
- tx_status: string;
28
- block_height: number | null;
29
- canonical?: boolean;
30
- is_unanchored?: boolean;
31
- }
32
24
  interface HiroTxResponse {
33
25
  tx_id: string;
34
26
  tx_type: string;
@@ -181,12 +173,6 @@ declare class HiroClient {
181
173
  /** Fetch with retry on 429/5xx using exponential backoff */
182
174
  private fetchWithRetry;
183
175
  /**
184
- * Fetch a single transaction's status by txid (Hiro extended `/v1/tx`).
185
- * Used by the x402 reconciler to advance/revert ledger rows. Returns null on
186
- * 404 (unknown/not-yet-indexed tx).
187
- */
188
- getTransaction(txId: string): Promise<HiroTransaction | null>;
189
- /**
190
176
  * Fetch a complete block by height, including all transactions and events,
191
177
  * transformed into the NewBlockPayload format our indexer expects.
192
178
  *
@@ -205,9 +191,6 @@ declare class HiroClient {
205
191
  fetchRawTx(txId: string): Promise<string | null>;
206
192
  /** Fetch raw_tx for multiple transactions with bounded concurrency */
207
193
  fetchRawTxBatch(txIds: string[], concurrency?: number): Promise<Map<string, string>>;
208
- /** Fetch current chain tip height from Hiro API status endpoint */
209
- fetchChainTip(): Promise<number>;
210
- isHealthy(): Promise<boolean>;
211
194
  getApiUrl(): string;
212
195
  }
213
- export { NewBlockPayload, HiroTxResponse, HiroTransaction, HiroEventsResponse, HiroEvent, HiroClient, HiroBlockTxsResponse, HiroBlockResponse, GetBlockOptions };
196
+ export { NewBlockPayload, HiroTxResponse, HiroEventsResponse, HiroEvent, HiroClient, HiroBlockTxsResponse, HiroBlockResponse, GetBlockOptions };
@@ -177,15 +177,6 @@ class HiroClient {
177
177
  signal: AbortSignal.timeout(timeoutMs)
178
178
  });
179
179
  }
180
- async getTransaction(txId) {
181
- const res = await this.fetchWithRetry(`${this.apiUrl}/extended/v1/tx/${txId}`);
182
- if (res.status === 404)
183
- return null;
184
- if (!res.ok) {
185
- throw new Error(`Hiro getTransaction ${txId} failed: ${res.status}`);
186
- }
187
- return await res.json();
188
- }
189
180
  async getBlockForIndexer(height, options) {
190
181
  let block = await this.fetchBlock(height);
191
182
  const fallbackUrl = this.fallbackUrl;
@@ -332,24 +323,6 @@ class HiroClient {
332
323
  }
333
324
  return results;
334
325
  }
335
- async fetchChainTip() {
336
- const res = await this.fetchWithRetry(`${this.apiUrl}/extended/v1/status`);
337
- if (!res.ok)
338
- throw new Error(`Hiro API /status returned ${res.status}`);
339
- const data = await res.json();
340
- return data.chain_tip?.block_height ?? data.stacks_tip_height ?? 0;
341
- }
342
- async isHealthy() {
343
- try {
344
- const res = await fetch(`${this.apiUrl}/extended/v1/status`, {
345
- headers: this.headers,
346
- signal: AbortSignal.timeout(1e4)
347
- });
348
- return res.ok || res.status === 429;
349
- } catch {
350
- return false;
351
- }
352
- }
353
326
  getApiUrl() {
354
327
  return this.apiUrl;
355
328
  }
@@ -525,5 +498,5 @@ export {
525
498
  HiroClient
526
499
  };
527
500
 
528
- //# debugId=679094A893C0896364756E2164756E21
501
+ //# debugId=1FB15B4363B2E96864756E2164756E21
529
502
  //# sourceMappingURL=hiro-client.js.map
@@ -4,9 +4,9 @@
4
4
  "sourcesContent": [
5
5
  "import { z } from \"zod/v4\";\n\n// Parse comma-separated networks\nconst networksSchema = z.string().transform((val) => {\n\tconst networks = val\n\t\t.split(\",\")\n\t\t.map((n) => n.trim())\n\t\t.filter(Boolean);\n\tconst valid = [\"mainnet\", \"testnet\"];\n\tfor (const n of networks) {\n\t\tif (!valid.includes(n)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Invalid network: ${n}. Must be one of: ${valid.join(\", \")}`,\n\t\t\t);\n\t\t}\n\t}\n\treturn networks as (\"mainnet\" | \"testnet\")[];\n});\n\ninterface EnvSchemaOutput {\n\tDATABASE_URL?: string;\n\t/**\n\t * Shared indexer DB (blocks/txs/events). Falls back to DATABASE_URL.\n\t * Set this alongside TARGET_DATABASE_URL to enable dual-DB mode.\n\t */\n\tSOURCE_DATABASE_URL?: string;\n\t/**\n\t * Tenant DB (subgraph schemas + subgraphs table). Falls back to DATABASE_URL.\n\t * Set this alongside SOURCE_DATABASE_URL to enable dual-DB mode.\n\t */\n\tTARGET_DATABASE_URL?: string;\n\tNETWORK?: \"mainnet\" | \"testnet\";\n\tNETWORKS?: (\"mainnet\" | \"testnet\")[];\n\tLOG_LEVEL: \"debug\" | \"info\" | \"warn\" | \"error\";\n\tNODE_ENV: \"development\" | \"production\" | \"test\";\n}\n\n// Cast needed: z.preprocess / z.default create different _input vs _output types\n// that z.ZodType<T> can't represent without explicit input type param\nconst envSchema: z.ZodType<EnvSchemaOutput> = z.object({\n\tDATABASE_URL: z.preprocess(\n\t\t(val) => (typeof val === \"string\" && val.length === 0 ? undefined : val),\n\t\tz.string().url().optional(),\n\t),\n\tSOURCE_DATABASE_URL: z.preprocess(\n\t\t(val) => (typeof val === \"string\" && val.length === 0 ? undefined : val),\n\t\tz.string().url().optional(),\n\t),\n\tTARGET_DATABASE_URL: z.preprocess(\n\t\t(val) => (typeof val === \"string\" && val.length === 0 ? undefined : val),\n\t\tz.string().url().optional(),\n\t),\n\tNETWORK: z.enum([\"mainnet\", \"testnet\"]).optional(),\n\tNETWORKS: networksSchema.optional(),\n\tLOG_LEVEL: z.enum([\"debug\", \"info\", \"warn\", \"error\"]).default(\"info\"),\n\tNODE_ENV: z\n\t\t.enum([\"development\", \"production\", \"test\"])\n\t\t.default(\"development\"),\n}) as unknown as z.ZodType<EnvSchemaOutput>;\n\nexport type Env = EnvSchemaOutput & {\n\tenabledNetworks: (\"mainnet\" | \"testnet\")[];\n};\n\nlet cachedEnv: Env | null = null;\n\nexport function getEnv(): Env {\n\tif (cachedEnv) {\n\t\treturn cachedEnv;\n\t}\n\n\tconst result = envSchema.safeParse(process.env);\n\n\tif (!result.success) {\n\t\tconsole.error(\"❌ Invalid environment configuration:\");\n\t\tconsole.error(z.treeifyError(result.error));\n\t\tthrow new Error(\"Invalid environment configuration\");\n\t}\n\n\t// Compute enabled networks from NETWORKS or NETWORK\n\tlet enabledNetworks: (\"mainnet\" | \"testnet\")[];\n\tif (result.data.NETWORKS && result.data.NETWORKS.length > 0) {\n\t\tenabledNetworks = result.data.NETWORKS;\n\t} else if (result.data.NETWORK) {\n\t\tenabledNetworks = [result.data.NETWORK];\n\t} else {\n\t\tenabledNetworks = [\"mainnet\"]; // Default\n\t}\n\n\tcachedEnv = { ...result.data, enabledNetworks };\n\treturn cachedEnv;\n}\n\n/**\n * True when `NODE_ENV=production`, read at RUNTIME — the single source of truth\n * for prod-vs-dev branching in this package.\n *\n * Why a helper instead of inlining `process.env.NODE_ENV === \"production\"`:\n * bunup/esbuild constant-folds the dot-access `process.env.NODE_ENV` to its\n * BUILD-time value. `@secondlayer/shared` is consumed by other services as its\n * built `dist`, so an inlined check freezes to a literal in the shipped bundle\n * (e.g. `const isProd = false`) and silently ignores the container's real\n * NODE_ENV. The bracket access below is NOT folded, so it stays a runtime read.\n * Route every prod check through here so the footgun lives in exactly one place.\n */\nexport function isProductionEnv(): boolean {\n\t// biome-ignore lint/complexity/useLiteralKeys: bracket access is deliberate — dot-access gets constant-folded by the bundler, freezing this to a build-time literal in the shipped dist.\n\treturn process.env[\"NODE_ENV\"] === \"production\";\n}\n\n/**\n * PoX-4 stacking decoder is ON by default — `/v1/index/stacking` is part of the\n * public surface, so the decoder that fills `pox4_calls` runs unless explicitly\n * opted out with `POX4_DECODER_ENABLED=false` (mirrors the sBTC decoder policy).\n */\nexport function isPox4DecoderEnabled(): boolean {\n\treturn process.env.POX4_DECODER_ENABLED !== \"false\";\n}\n\n// Export for testing\nexport { envSchema };\n",
6
6
  "import { getEnv } from \"./env.ts\";\n\ntype LogLevel = \"debug\" | \"info\" | \"warn\" | \"error\";\n\nconst LOG_LEVELS: Record<LogLevel, number> = {\n\tdebug: 0,\n\tinfo: 1,\n\twarn: 2,\n\terror: 3,\n};\n\nclass Logger {\n\tprivate _level?: LogLevel;\n\tprivate _isProduction?: boolean;\n\tprivate _initialized = false;\n\n\tprivate init() {\n\t\tif (this._initialized) return;\n\t\tthis._initialized = true;\n\t\ttry {\n\t\t\tconst env = getEnv();\n\t\t\tthis._level = env.LOG_LEVEL;\n\t\t\tthis._isProduction = env.NODE_ENV === \"production\";\n\t\t} catch {\n\t\t\t// Fallback when env is unavailable (e.g. tests without DATABASE_URL)\n\t\t\tthis._level = \"info\";\n\t\t\tthis._isProduction = false;\n\t\t}\n\t}\n\n\tprivate get level(): LogLevel {\n\t\tthis.init();\n\t\t// biome-ignore lint/style/noNonNullAssertion: value is non-null after preceding check or by construction; TS narrowing limitation\n\t\treturn this._level!;\n\t}\n\n\tprivate get isProduction(): boolean {\n\t\tthis.init();\n\t\t// biome-ignore lint/style/noNonNullAssertion: value is non-null after preceding check or by construction; TS narrowing limitation\n\t\treturn this._isProduction!;\n\t}\n\n\tprivate shouldLog(level: LogLevel): boolean {\n\t\treturn LOG_LEVELS[level] >= LOG_LEVELS[this.level];\n\t}\n\n\tprivate formatMessage(\n\t\tlevel: LogLevel,\n\t\tmessage: string,\n\t\t// biome-ignore lint/suspicious/noExplicitAny: interop boundary or dynamic-shape value where typing adds friction without runtime safety\n\t\tmeta?: Record<string, any>,\n\t) {\n\t\tconst timestamp = new Date().toISOString();\n\n\t\tif (this.isProduction) {\n\t\t\t// JSON output for production\n\t\t\treturn JSON.stringify({\n\t\t\t\ttimestamp,\n\t\t\t\tlevel,\n\t\t\t\tmessage,\n\t\t\t\t...meta,\n\t\t\t});\n\t\t}\n\n\t\t// Human-readable output for development\n\t\tconst metaStr = meta ? ` ${JSON.stringify(meta)}` : \"\";\n\t\treturn `[${timestamp}] ${level.toUpperCase()}: ${message}${metaStr}`;\n\t}\n\n\t// biome-ignore lint/suspicious/noExplicitAny: interop boundary or dynamic-shape value where typing adds friction without runtime safety\n\tdebug(message: string, meta?: Record<string, any>): void {\n\t\tif (this.shouldLog(\"debug\")) {\n\t\t\tconsole.debug(this.formatMessage(\"debug\", message, meta));\n\t\t}\n\t}\n\n\t// biome-ignore lint/suspicious/noExplicitAny: interop boundary or dynamic-shape value where typing adds friction without runtime safety\n\tinfo(message: string, meta?: Record<string, any>): void {\n\t\tif (this.shouldLog(\"info\")) {\n\t\t\tconsole.info(this.formatMessage(\"info\", message, meta));\n\t\t}\n\t}\n\n\t// biome-ignore lint/suspicious/noExplicitAny: interop boundary or dynamic-shape value where typing adds friction without runtime safety\n\twarn(message: string, meta?: Record<string, any>): void {\n\t\tif (this.shouldLog(\"warn\")) {\n\t\t\tconsole.warn(this.formatMessage(\"warn\", message, meta));\n\t\t}\n\t}\n\n\t// biome-ignore lint/suspicious/noExplicitAny: interop boundary or dynamic-shape value where typing adds friction without runtime safety\n\terror(message: string, meta?: Record<string, any>): void {\n\t\tif (this.shouldLog(\"error\")) {\n\t\t\tconsole.error(this.formatMessage(\"error\", message, meta));\n\t\t}\n\t}\n}\n\n// Export singleton instance\nexport const logger: Logger = new Logger();\n",
7
- "/**\n * Hiro public API client for backfilling historical block data.\n *\n * The stacks-node RPC `/v2/blocks/{height}` only returns block headers + tx IDs,\n * not full transaction data or events. The Hiro API serves complete block data\n * that we can transform into the NewBlockPayload format our indexer expects.\n */\n\nimport { logger } from \"../logger.ts\";\n\nconst DEFAULT_HIRO_API_URL = \"https://api.mainnet.hiro.so\";\n\n/** v2 /extended/v2/blocks/{height} response */\nexport interface HiroBlockResponse {\n\tcanonical: boolean;\n\theight: number;\n\thash: string;\n\tblock_time: number;\n\tblock_time_iso: string;\n\tindex_block_hash: string;\n\tparent_block_hash: string;\n\tparent_index_block_hash: string;\n\tburn_block_hash: string;\n\tburn_block_height: number;\n\tburn_block_time: number;\n\tminer_txid: string;\n\ttx_count: number;\n}\n\n/** v2 /extended/v2/blocks/{height}/transactions response */\nexport interface HiroBlockTxsResponse {\n\tlimit: number;\n\toffset: number;\n\ttotal: number;\n\tresults: HiroTxResponse[];\n}\n\n/** Minimal shape returned by `HiroClient.getTransaction` (extended `/v1/tx`). */\nexport interface HiroTransaction {\n\ttx_id: string;\n\ttx_status: string;\n\tblock_height: number | null;\n\tcanonical?: boolean;\n\tis_unanchored?: boolean;\n}\n\nexport interface HiroTxResponse {\n\ttx_id: string;\n\ttx_type: string;\n\ttx_status: string;\n\tsender_address: string;\n\tfee_rate: string;\n\tnonce: number;\n\tblock_hash: string;\n\tblock_height: number;\n\tburn_block_height: number;\n\ttx_index: number;\n\tevent_count: number;\n\ttoken_transfer?: {\n\t\trecipient_address: string;\n\t\tamount: string;\n\t\tmemo: string;\n\t};\n\tcontract_call?: {\n\t\tcontract_id: string;\n\t\tfunction_name: string;\n\t\tfunction_args: unknown[];\n\t};\n\tsmart_contract?: {\n\t\tcontract_id: string;\n\t\tsource_code: string;\n\t};\n}\n\nexport interface HiroEvent {\n\tevent_index: number;\n\tevent_type: string; // \"stx_asset\" | \"fungible_token_asset\" | \"non_fungible_token_asset\" | \"smart_contract_log\"\n\ttx_id: string;\n\tasset?: {\n\t\tasset_event_type: string; // \"transfer\" | \"mint\" | \"burn\"\n\t\tsender?: string;\n\t\trecipient?: string;\n\t\tamount?: string;\n\t\tmemo?: string;\n\t\tasset_id?: string;\n\t\tvalue?: unknown;\n\t};\n\tcontract_log?: {\n\t\tcontract_id: string;\n\t\ttopic: string;\n\t\tvalue: unknown;\n\t};\n}\n\nexport interface HiroEventsResponse {\n\tlimit: number;\n\toffset: number;\n\tevents: HiroEvent[];\n}\n\n/** Shape our indexer expects at POST /new_block */\nexport interface NewBlockPayload {\n\tblock_hash: string;\n\tblock_height: number;\n\tindex_block_hash: string;\n\tparent_block_hash: string;\n\tparent_index_block_hash: string;\n\tburn_block_hash: string;\n\tburn_block_height: number;\n\tburn_block_timestamp: number;\n\tminer_txid: string;\n\ttimestamp: number;\n\ttransactions: TransactionPayload[];\n\tevents: TransactionEventPayload[];\n}\n\ninterface TransactionPayload {\n\ttxid: string;\n\traw_tx: string;\n\tstatus: string;\n\ttx_index: number;\n\ttx_type?: string;\n\tsender_address?: string;\n}\n\ninterface TransactionEventPayload {\n\ttxid: string;\n\tevent_index: number;\n\tcommitted: boolean;\n\ttype: string;\n\tstx_transfer_event?: {\n\t\tsender: string;\n\t\trecipient: string;\n\t\tamount: string;\n\t\tmemo?: string;\n\t};\n\tstx_mint_event?: { recipient: string; amount: string };\n\tstx_burn_event?: { sender: string; amount: string };\n\tstx_lock_event?: {\n\t\tlocked_amount: string;\n\t\tunlock_height: string;\n\t\tlocked_address: string;\n\t};\n\tft_transfer_event?: {\n\t\tasset_identifier: string;\n\t\tsender: string;\n\t\trecipient: string;\n\t\tamount: string;\n\t};\n\tft_mint_event?: {\n\t\tasset_identifier: string;\n\t\trecipient: string;\n\t\tamount: string;\n\t};\n\tft_burn_event?: { asset_identifier: string; sender: string; amount: string };\n\tnft_transfer_event?: {\n\t\tasset_identifier: string;\n\t\tsender: string;\n\t\trecipient: string;\n\t\tvalue: unknown;\n\t};\n\tnft_mint_event?: {\n\t\tasset_identifier: string;\n\t\trecipient: string;\n\t\tvalue: unknown;\n\t};\n\tnft_burn_event?: { asset_identifier: string; sender: string; value: unknown };\n\tsmart_contract_event?: {\n\t\tcontract_identifier: string;\n\t\ttopic: string;\n\t\tvalue: unknown;\n\t};\n}\n\nexport interface GetBlockOptions {\n\t/** Fetch actual raw_tx hex for each transaction (instead of \"0x00\" placeholder) */\n\tincludeRawTx?: boolean;\n\t/** Max concurrent raw_tx fetches per block (default: 10) */\n\trawTxConcurrency?: number;\n}\n\nexport class HiroClient {\n\tprivate apiUrl: string;\n\tprivate fallbackUrl: string | undefined;\n\tprivate apiKey: string | undefined;\n\tprivate maxRetries: number;\n\n\tconstructor(apiUrl?: string, maxRetries = 5) {\n\t\tthis.apiUrl = apiUrl || process.env.HIRO_API_URL || DEFAULT_HIRO_API_URL;\n\t\tthis.fallbackUrl = process.env.HIRO_FALLBACK_URL;\n\t\tthis.apiKey = process.env.HIRO_API_KEY;\n\t\tthis.maxRetries = maxRetries;\n\t}\n\n\tprivate get headers(): Record<string, string> {\n\t\treturn this.apiKey ? { \"x-hiro-api-key\": this.apiKey } : {};\n\t}\n\n\t/** Fetch with retry on 429/5xx using exponential backoff */\n\tprivate async fetchWithRetry(\n\t\turl: string,\n\t\ttimeoutMs = 120_000,\n\t): Promise<Response> {\n\t\tfor (let attempt = 0; attempt < this.maxRetries; attempt++) {\n\t\t\tconst res = await fetch(url, {\n\t\t\t\theaders: this.headers,\n\t\t\t\tsignal: AbortSignal.timeout(timeoutMs),\n\t\t\t});\n\n\t\t\tif (res.ok || res.status === 404) return res;\n\n\t\t\tif (res.status === 429 || res.status >= 500) {\n\t\t\t\tconst delay = Math.min(1000 * 2 ** attempt, 10_000);\n\t\t\t\tlogger.info(\"Rate limited, retrying\", {\n\t\t\t\t\turl: url.split(\"/\").slice(-2).join(\"/\"),\n\t\t\t\t\tattempt,\n\t\t\t\t\tdelay,\n\t\t\t\t});\n\t\t\t\tawait new Promise((r) => setTimeout(r, delay));\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// 4xx (not 404/429) — don't retry\n\t\t\treturn res;\n\t\t}\n\n\t\t// Final attempt\n\t\treturn fetch(url, {\n\t\t\theaders: this.headers,\n\t\t\tsignal: AbortSignal.timeout(timeoutMs),\n\t\t});\n\t}\n\n\t/**\n\t * Fetch a single transaction's status by txid (Hiro extended `/v1/tx`).\n\t * Used by the x402 reconciler to advance/revert ledger rows. Returns null on\n\t * 404 (unknown/not-yet-indexed tx).\n\t */\n\tasync getTransaction(txId: string): Promise<HiroTransaction | null> {\n\t\tconst res = await this.fetchWithRetry(\n\t\t\t`${this.apiUrl}/extended/v1/tx/${txId}`,\n\t\t);\n\t\tif (res.status === 404) return null;\n\t\tif (!res.ok) {\n\t\t\tthrow new Error(`Hiro getTransaction ${txId} failed: ${res.status}`);\n\t\t}\n\t\treturn (await res.json()) as HiroTransaction;\n\t}\n\n\t/**\n\t * Fetch a complete block by height, including all transactions and events,\n\t * transformed into the NewBlockPayload format our indexer expects.\n\t *\n\t * Uses 3-step approach:\n\t * 1. GET /extended/v2/blocks/{height} — block metadata\n\t * 2. GET /extended/v2/blocks/{height}/transactions — all txs (paginated)\n\t * 3. GET /extended/v1/tx/events?tx_id={txId} — events per tx (only for txs with events)\n\t */\n\tasync getBlockForIndexer(\n\t\theight: number,\n\t\toptions?: GetBlockOptions,\n\t): Promise<NewBlockPayload | null> {\n\t\t// 1. Fetch block metadata (try primary, fallback on 404)\n\t\tlet block = await this.fetchBlock(height);\n\t\tconst fallbackUrl = this.fallbackUrl;\n\t\tlet usingFallback = false;\n\t\tif (!block && fallbackUrl) {\n\t\t\tblock = await this.fetchBlock(height, fallbackUrl);\n\t\t\tif (block) usingFallback = true;\n\t\t}\n\t\tif (!block) return null;\n\n\t\t// 2. Fetch all transactions via v2 block/transactions endpoint\n\t\tconst baseUrl = usingFallback && fallbackUrl ? fallbackUrl : this.apiUrl;\n\t\tconst hiroTxs = await this.fetchBlockTransactions(height, baseUrl);\n\n\t\tconst txPayloads: TransactionPayload[] = [];\n\t\tconst eventPayloads: TransactionEventPayload[] = [];\n\n\t\tfor (const hiroTx of hiroTxs) {\n\t\t\ttxPayloads.push({\n\t\t\t\ttxid: hiroTx.tx_id,\n\t\t\t\traw_tx: \"0x00\",\n\t\t\t\tstatus: mapTxStatus(hiroTx.tx_status),\n\t\t\t\ttx_index: hiroTx.tx_index ?? 0,\n\t\t\t\ttx_type: mapTxType(hiroTx.tx_type),\n\t\t\t\tsender_address: hiroTx.sender_address,\n\t\t\t});\n\n\t\t\t// 3. Fetch events only for txs that have them\n\t\t\tif (hiroTx.event_count > 0) {\n\t\t\t\tif (hiroTx.event_count > 1000) {\n\t\t\t\t\tlogger.info(\"Fetching large event set\", {\n\t\t\t\t\t\ttxId: hiroTx.tx_id,\n\t\t\t\t\t\teventCount: hiroTx.event_count,\n\t\t\t\t\t\theight,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tconst events = await this.fetchAllEvents(hiroTx.tx_id, baseUrl);\n\t\t\t\t\teventPayloads.push(...events);\n\t\t\t\t} catch (err) {\n\t\t\t\t\tlogger.warn(\"Failed to fetch events for backfill\", {\n\t\t\t\t\t\ttxId: hiroTx.tx_id,\n\t\t\t\t\t\terror: String(err),\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// 4. Optionally fetch raw_tx for all transactions\n\t\tif (options?.includeRawTx && txPayloads.length > 0) {\n\t\t\tconst txIds = txPayloads.map((t) => t.txid);\n\t\t\tconst rawTxMap = await this.fetchRawTxBatch(\n\t\t\t\ttxIds,\n\t\t\t\toptions.rawTxConcurrency,\n\t\t\t);\n\t\t\tfor (const txPayload of txPayloads) {\n\t\t\t\tconst raw = rawTxMap.get(txPayload.txid);\n\t\t\t\tif (raw) txPayload.raw_tx = raw;\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tblock_hash: block.hash,\n\t\t\tblock_height: block.height,\n\t\t\tindex_block_hash: block.index_block_hash,\n\t\t\tparent_block_hash: block.parent_block_hash,\n\t\t\tparent_index_block_hash: block.parent_index_block_hash,\n\t\t\tburn_block_hash: block.burn_block_hash,\n\t\t\tburn_block_height: block.burn_block_height,\n\t\t\tburn_block_timestamp: block.burn_block_time,\n\t\t\tminer_txid: block.miner_txid,\n\t\t\ttimestamp: block.block_time,\n\t\t\ttransactions: txPayloads,\n\t\t\tevents: eventPayloads,\n\t\t};\n\t}\n\n\t/** v2 block metadata */\n\tprivate async fetchBlock(\n\t\theight: number,\n\t\tbaseUrl?: string,\n\t): Promise<HiroBlockResponse | null> {\n\t\tconst url = baseUrl || this.apiUrl;\n\t\tconst res = await this.fetchWithRetry(\n\t\t\t`${url}/extended/v2/blocks/${height}`,\n\t\t);\n\t\tif (res.status === 404) return null;\n\t\tif (!res.ok)\n\t\t\tthrow new Error(`Hiro API block/${height} returned ${res.status}`);\n\t\treturn res.json() as Promise<HiroBlockResponse>;\n\t}\n\n\t/** v2 block transactions (paginated) */\n\tprivate async fetchBlockTransactions(\n\t\theight: number,\n\t\tbaseUrl?: string,\n\t): Promise<HiroTxResponse[]> {\n\t\tconst url = baseUrl || this.apiUrl;\n\t\tconst txs: HiroTxResponse[] = [];\n\t\tlet offset = 0;\n\t\tconst limit = 50;\n\n\t\twhile (true) {\n\t\t\tconst res = await this.fetchWithRetry(\n\t\t\t\t`${url}/extended/v2/blocks/${height}/transactions?limit=${limit}&offset=${offset}`,\n\t\t\t);\n\t\t\tif (!res.ok)\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Hiro API block/${height}/transactions returned ${res.status}`,\n\t\t\t\t);\n\n\t\t\tconst data = (await res.json()) as HiroBlockTxsResponse;\n\t\t\ttxs.push(...data.results);\n\n\t\t\tif (txs.length >= data.total || data.results.length < limit) break;\n\t\t\toffset += limit;\n\t\t}\n\n\t\treturn txs;\n\t}\n\n\tprivate async fetchAllEvents(\n\t\ttxId: string,\n\t\tbaseUrl?: string,\n\t\t_maxEvents?: number,\n\t): Promise<TransactionEventPayload[]> {\n\t\tconst url = baseUrl || this.apiUrl;\n\t\tconst events: TransactionEventPayload[] = [];\n\t\tlet offset = 0;\n\t\tconst limit = 100;\n\n\t\twhile (true) {\n\t\t\tconst res = await this.fetchWithRetry(\n\t\t\t\t`${url}/extended/v1/tx/events?tx_id=${txId}&limit=${limit}&offset=${offset}`,\n\t\t\t);\n\t\t\tif (!res.ok) {\n\t\t\t\tlogger.warn(\"Failed to fetch events from Hiro\", {\n\t\t\t\t\ttxId,\n\t\t\t\t\tstatus: res.status,\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tconst data = (await res.json()) as HiroEventsResponse;\n\t\t\tfor (const hEvent of data.events) {\n\t\t\t\tconst converted = convertHiroEvent(hEvent);\n\t\t\t\tif (converted) events.push(converted);\n\t\t\t}\n\n\t\t\tif (data.events.length < limit) break;\n\t\t\toffset += limit;\n\t\t}\n\n\t\treturn events;\n\t}\n\n\t/** Fetch raw_tx hex for a single transaction */\n\tasync fetchRawTx(txId: string): Promise<string | null> {\n\t\ttry {\n\t\t\tconst res = await this.fetchWithRetry(\n\t\t\t\t`${this.apiUrl}/extended/v1/tx/${txId}/raw`,\n\t\t\t\t10_000,\n\t\t\t);\n\t\t\tif (!res.ok) return null;\n\t\t\tconst data = (await res.json()) as { raw_tx: string };\n\t\t\treturn data.raw_tx || null;\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t/** Fetch raw_tx for multiple transactions with bounded concurrency */\n\tasync fetchRawTxBatch(\n\t\ttxIds: string[],\n\t\tconcurrency = 10,\n\t): Promise<Map<string, string>> {\n\t\tconst results = new Map<string, string>();\n\t\tfor (let i = 0; i < txIds.length; i += concurrency) {\n\t\t\tconst chunk = txIds.slice(i, i + concurrency);\n\t\t\tconst settled = await Promise.allSettled(\n\t\t\t\tchunk.map(async (txId) => {\n\t\t\t\t\tconst raw = await this.fetchRawTx(txId);\n\t\t\t\t\treturn { txId, raw };\n\t\t\t\t}),\n\t\t\t);\n\t\t\tfor (const result of settled) {\n\t\t\t\tif (result.status === \"fulfilled\" && result.value.raw) {\n\t\t\t\t\tresults.set(result.value.txId, result.value.raw);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn results;\n\t}\n\n\t/** Fetch current chain tip height from Hiro API status endpoint */\n\tasync fetchChainTip(): Promise<number> {\n\t\tconst res = await this.fetchWithRetry(`${this.apiUrl}/extended/v1/status`);\n\t\tif (!res.ok) throw new Error(`Hiro API /status returned ${res.status}`);\n\t\tconst data = (await res.json()) as {\n\t\t\tchain_tip?: { block_height: number };\n\t\t\tstacks_tip_height?: number;\n\t\t};\n\t\treturn data.chain_tip?.block_height ?? data.stacks_tip_height ?? 0;\n\t}\n\n\tasync isHealthy(): Promise<boolean> {\n\t\ttry {\n\t\t\tconst res = await fetch(`${this.apiUrl}/extended/v1/status`, {\n\t\t\t\theaders: this.headers,\n\t\t\t\tsignal: AbortSignal.timeout(10_000),\n\t\t\t});\n\t\t\t// 429 = rate limited but reachable\n\t\t\treturn res.ok || res.status === 429;\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tgetApiUrl(): string {\n\t\treturn this.apiUrl;\n\t}\n}\n\n/** Map Hiro tx_status to our indexer's expected format */\nfunction mapTxStatus(status: string): string {\n\tswitch (status) {\n\t\tcase \"success\":\n\t\t\treturn \"success\";\n\t\tcase \"abort_by_response\":\n\t\tcase \"abort_by_post_condition\":\n\t\t\treturn status;\n\t\tdefault:\n\t\t\treturn \"success\";\n\t}\n}\n\n/** Map Hiro tx_type to node event tx_type */\nfunction mapTxType(type: string): string {\n\tswitch (type) {\n\t\tcase \"token_transfer\":\n\t\t\treturn \"token_transfer\";\n\t\tcase \"contract_call\":\n\t\t\treturn \"contract_call\";\n\t\tcase \"smart_contract\":\n\t\t\treturn \"smart_contract\";\n\t\tcase \"coinbase\":\n\t\t\treturn \"coinbase\";\n\t\tcase \"tenure_change\":\n\t\t\treturn \"tenure_change\";\n\t\tcase \"poison_microblock\":\n\t\t\treturn \"poison_microblock\";\n\t\tdefault:\n\t\t\treturn type;\n\t}\n}\n\n/**\n * Convert a Hiro API event to our indexer's TransactionEvent format.\n *\n * Hiro uses:\n * event_type: \"stx_asset\" | \"fungible_token_asset\" | \"non_fungible_token_asset\" | \"smart_contract_log\"\n * asset.asset_event_type: \"transfer\" | \"mint\" | \"burn\" | \"lock\"\n *\n * Our indexer expects:\n * type: \"stx_transfer_event\" | \"stx_mint_event\" | \"ft_transfer_event\" | \"smart_contract_event\" | ...\n */\nfunction convertHiroEvent(hEvent: HiroEvent): TransactionEventPayload | null {\n\tconst base = {\n\t\ttxid: hEvent.tx_id,\n\t\tevent_index: hEvent.event_index,\n\t\tcommitted: true,\n\t};\n\n\tif (hEvent.event_type === \"stx_asset\" && hEvent.asset) {\n\t\tconst a = hEvent.asset;\n\t\tswitch (a.asset_event_type) {\n\t\t\tcase \"transfer\":\n\t\t\t\treturn {\n\t\t\t\t\t...base,\n\t\t\t\t\ttype: \"stx_transfer_event\",\n\t\t\t\t\tstx_transfer_event: {\n\t\t\t\t\t\tsender: a.sender ?? \"\",\n\t\t\t\t\t\trecipient: a.recipient ?? \"\",\n\t\t\t\t\t\tamount: a.amount ?? \"0\",\n\t\t\t\t\t\tmemo: a.memo,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\tcase \"mint\":\n\t\t\t\treturn {\n\t\t\t\t\t...base,\n\t\t\t\t\ttype: \"stx_mint_event\",\n\t\t\t\t\tstx_mint_event: {\n\t\t\t\t\t\trecipient: a.recipient ?? \"\",\n\t\t\t\t\t\tamount: a.amount ?? \"0\",\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\tcase \"burn\":\n\t\t\t\treturn {\n\t\t\t\t\t...base,\n\t\t\t\t\ttype: \"stx_burn_event\",\n\t\t\t\t\tstx_burn_event: { sender: a.sender ?? \"\", amount: a.amount ?? \"0\" },\n\t\t\t\t};\n\t\t\tcase \"lock\":\n\t\t\t\treturn {\n\t\t\t\t\t...base,\n\t\t\t\t\ttype: \"stx_lock_event\",\n\t\t\t\t\tstx_lock_event: {\n\t\t\t\t\t\tlocked_amount: a.amount ?? \"0\",\n\t\t\t\t\t\tunlock_height: \"0\",\n\t\t\t\t\t\tlocked_address: a.sender ?? \"\",\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t}\n\t}\n\n\tif (hEvent.event_type === \"fungible_token_asset\" && hEvent.asset) {\n\t\tconst a = hEvent.asset;\n\t\tconst assetId = a.asset_id || \"\";\n\t\tswitch (a.asset_event_type) {\n\t\t\tcase \"transfer\":\n\t\t\t\treturn {\n\t\t\t\t\t...base,\n\t\t\t\t\ttype: \"ft_transfer_event\",\n\t\t\t\t\tft_transfer_event: {\n\t\t\t\t\t\tasset_identifier: assetId,\n\t\t\t\t\t\tsender: a.sender ?? \"\",\n\t\t\t\t\t\trecipient: a.recipient ?? \"\",\n\t\t\t\t\t\tamount: a.amount ?? \"0\",\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\tcase \"mint\":\n\t\t\t\treturn {\n\t\t\t\t\t...base,\n\t\t\t\t\ttype: \"ft_mint_event\",\n\t\t\t\t\tft_mint_event: {\n\t\t\t\t\t\tasset_identifier: assetId,\n\t\t\t\t\t\trecipient: a.recipient ?? \"\",\n\t\t\t\t\t\tamount: a.amount ?? \"0\",\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\tcase \"burn\":\n\t\t\t\treturn {\n\t\t\t\t\t...base,\n\t\t\t\t\ttype: \"ft_burn_event\",\n\t\t\t\t\tft_burn_event: {\n\t\t\t\t\t\tasset_identifier: assetId,\n\t\t\t\t\t\tsender: a.sender ?? \"\",\n\t\t\t\t\t\tamount: a.amount ?? \"0\",\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t}\n\t}\n\n\tif (hEvent.event_type === \"non_fungible_token_asset\" && hEvent.asset) {\n\t\tconst a = hEvent.asset;\n\t\tconst assetId = a.asset_id || \"\";\n\t\tswitch (a.asset_event_type) {\n\t\t\tcase \"transfer\":\n\t\t\t\treturn {\n\t\t\t\t\t...base,\n\t\t\t\t\ttype: \"nft_transfer_event\",\n\t\t\t\t\tnft_transfer_event: {\n\t\t\t\t\t\tasset_identifier: assetId,\n\t\t\t\t\t\tsender: a.sender ?? \"\",\n\t\t\t\t\t\trecipient: a.recipient ?? \"\",\n\t\t\t\t\t\tvalue: a.value,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\tcase \"mint\":\n\t\t\t\treturn {\n\t\t\t\t\t...base,\n\t\t\t\t\ttype: \"nft_mint_event\",\n\t\t\t\t\tnft_mint_event: {\n\t\t\t\t\t\tasset_identifier: assetId,\n\t\t\t\t\t\trecipient: a.recipient ?? \"\",\n\t\t\t\t\t\tvalue: a.value,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\tcase \"burn\":\n\t\t\t\treturn {\n\t\t\t\t\t...base,\n\t\t\t\t\ttype: \"nft_burn_event\",\n\t\t\t\t\tnft_burn_event: {\n\t\t\t\t\t\tasset_identifier: assetId,\n\t\t\t\t\t\tsender: a.sender ?? \"\",\n\t\t\t\t\t\tvalue: a.value,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t}\n\t}\n\n\tif (hEvent.event_type === \"smart_contract_log\" && hEvent.contract_log) {\n\t\treturn {\n\t\t\t...base,\n\t\t\ttype: \"smart_contract_event\",\n\t\t\tsmart_contract_event: {\n\t\t\t\tcontract_identifier: hEvent.contract_log.contract_id,\n\t\t\t\ttopic: hEvent.contract_log.topic,\n\t\t\t\tvalue: hEvent.contract_log.value,\n\t\t\t},\n\t\t};\n\t}\n\n\tlogger.debug(\"Unknown Hiro event type, skipping\", {\n\t\teventType: hEvent.event_type,\n\t\ttxId: hEvent.tx_id,\n\t});\n\treturn null;\n}\n"
7
+ "/**\n * Hiro public API client for backfilling historical block data.\n *\n * The stacks-node RPC `/v2/blocks/{height}` only returns block headers + tx IDs,\n * not full transaction data or events. The Hiro API serves complete block data\n * that we can transform into the NewBlockPayload format our indexer expects.\n */\n\nimport { logger } from \"../logger.ts\";\n\nconst DEFAULT_HIRO_API_URL = \"https://api.mainnet.hiro.so\";\n\n/** v2 /extended/v2/blocks/{height} response */\nexport interface HiroBlockResponse {\n\tcanonical: boolean;\n\theight: number;\n\thash: string;\n\tblock_time: number;\n\tblock_time_iso: string;\n\tindex_block_hash: string;\n\tparent_block_hash: string;\n\tparent_index_block_hash: string;\n\tburn_block_hash: string;\n\tburn_block_height: number;\n\tburn_block_time: number;\n\tminer_txid: string;\n\ttx_count: number;\n}\n\n/** v2 /extended/v2/blocks/{height}/transactions response */\nexport interface HiroBlockTxsResponse {\n\tlimit: number;\n\toffset: number;\n\ttotal: number;\n\tresults: HiroTxResponse[];\n}\n\nexport interface HiroTxResponse {\n\ttx_id: string;\n\ttx_type: string;\n\ttx_status: string;\n\tsender_address: string;\n\tfee_rate: string;\n\tnonce: number;\n\tblock_hash: string;\n\tblock_height: number;\n\tburn_block_height: number;\n\ttx_index: number;\n\tevent_count: number;\n\ttoken_transfer?: {\n\t\trecipient_address: string;\n\t\tamount: string;\n\t\tmemo: string;\n\t};\n\tcontract_call?: {\n\t\tcontract_id: string;\n\t\tfunction_name: string;\n\t\tfunction_args: unknown[];\n\t};\n\tsmart_contract?: {\n\t\tcontract_id: string;\n\t\tsource_code: string;\n\t};\n}\n\nexport interface HiroEvent {\n\tevent_index: number;\n\tevent_type: string; // \"stx_asset\" | \"fungible_token_asset\" | \"non_fungible_token_asset\" | \"smart_contract_log\"\n\ttx_id: string;\n\tasset?: {\n\t\tasset_event_type: string; // \"transfer\" | \"mint\" | \"burn\"\n\t\tsender?: string;\n\t\trecipient?: string;\n\t\tamount?: string;\n\t\tmemo?: string;\n\t\tasset_id?: string;\n\t\tvalue?: unknown;\n\t};\n\tcontract_log?: {\n\t\tcontract_id: string;\n\t\ttopic: string;\n\t\tvalue: unknown;\n\t};\n}\n\nexport interface HiroEventsResponse {\n\tlimit: number;\n\toffset: number;\n\tevents: HiroEvent[];\n}\n\n/** Shape our indexer expects at POST /new_block */\nexport interface NewBlockPayload {\n\tblock_hash: string;\n\tblock_height: number;\n\tindex_block_hash: string;\n\tparent_block_hash: string;\n\tparent_index_block_hash: string;\n\tburn_block_hash: string;\n\tburn_block_height: number;\n\tburn_block_timestamp: number;\n\tminer_txid: string;\n\ttimestamp: number;\n\ttransactions: TransactionPayload[];\n\tevents: TransactionEventPayload[];\n}\n\ninterface TransactionPayload {\n\ttxid: string;\n\traw_tx: string;\n\tstatus: string;\n\ttx_index: number;\n\ttx_type?: string;\n\tsender_address?: string;\n}\n\ninterface TransactionEventPayload {\n\ttxid: string;\n\tevent_index: number;\n\tcommitted: boolean;\n\ttype: string;\n\tstx_transfer_event?: {\n\t\tsender: string;\n\t\trecipient: string;\n\t\tamount: string;\n\t\tmemo?: string;\n\t};\n\tstx_mint_event?: { recipient: string; amount: string };\n\tstx_burn_event?: { sender: string; amount: string };\n\tstx_lock_event?: {\n\t\tlocked_amount: string;\n\t\tunlock_height: string;\n\t\tlocked_address: string;\n\t};\n\tft_transfer_event?: {\n\t\tasset_identifier: string;\n\t\tsender: string;\n\t\trecipient: string;\n\t\tamount: string;\n\t};\n\tft_mint_event?: {\n\t\tasset_identifier: string;\n\t\trecipient: string;\n\t\tamount: string;\n\t};\n\tft_burn_event?: { asset_identifier: string; sender: string; amount: string };\n\tnft_transfer_event?: {\n\t\tasset_identifier: string;\n\t\tsender: string;\n\t\trecipient: string;\n\t\tvalue: unknown;\n\t};\n\tnft_mint_event?: {\n\t\tasset_identifier: string;\n\t\trecipient: string;\n\t\tvalue: unknown;\n\t};\n\tnft_burn_event?: { asset_identifier: string; sender: string; value: unknown };\n\tsmart_contract_event?: {\n\t\tcontract_identifier: string;\n\t\ttopic: string;\n\t\tvalue: unknown;\n\t};\n}\n\nexport interface GetBlockOptions {\n\t/** Fetch actual raw_tx hex for each transaction (instead of \"0x00\" placeholder) */\n\tincludeRawTx?: boolean;\n\t/** Max concurrent raw_tx fetches per block (default: 10) */\n\trawTxConcurrency?: number;\n}\n\nexport class HiroClient {\n\tprivate apiUrl: string;\n\tprivate fallbackUrl: string | undefined;\n\tprivate apiKey: string | undefined;\n\tprivate maxRetries: number;\n\n\tconstructor(apiUrl?: string, maxRetries = 5) {\n\t\tthis.apiUrl = apiUrl || process.env.HIRO_API_URL || DEFAULT_HIRO_API_URL;\n\t\tthis.fallbackUrl = process.env.HIRO_FALLBACK_URL;\n\t\tthis.apiKey = process.env.HIRO_API_KEY;\n\t\tthis.maxRetries = maxRetries;\n\t}\n\n\tprivate get headers(): Record<string, string> {\n\t\treturn this.apiKey ? { \"x-hiro-api-key\": this.apiKey } : {};\n\t}\n\n\t/** Fetch with retry on 429/5xx using exponential backoff */\n\tprivate async fetchWithRetry(\n\t\turl: string,\n\t\ttimeoutMs = 120_000,\n\t): Promise<Response> {\n\t\tfor (let attempt = 0; attempt < this.maxRetries; attempt++) {\n\t\t\tconst res = await fetch(url, {\n\t\t\t\theaders: this.headers,\n\t\t\t\tsignal: AbortSignal.timeout(timeoutMs),\n\t\t\t});\n\n\t\t\tif (res.ok || res.status === 404) return res;\n\n\t\t\tif (res.status === 429 || res.status >= 500) {\n\t\t\t\tconst delay = Math.min(1000 * 2 ** attempt, 10_000);\n\t\t\t\tlogger.info(\"Rate limited, retrying\", {\n\t\t\t\t\turl: url.split(\"/\").slice(-2).join(\"/\"),\n\t\t\t\t\tattempt,\n\t\t\t\t\tdelay,\n\t\t\t\t});\n\t\t\t\tawait new Promise((r) => setTimeout(r, delay));\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// 4xx (not 404/429) — don't retry\n\t\t\treturn res;\n\t\t}\n\n\t\t// Final attempt\n\t\treturn fetch(url, {\n\t\t\theaders: this.headers,\n\t\t\tsignal: AbortSignal.timeout(timeoutMs),\n\t\t});\n\t}\n\n\t/**\n\t * Fetch a complete block by height, including all transactions and events,\n\t * transformed into the NewBlockPayload format our indexer expects.\n\t *\n\t * Uses 3-step approach:\n\t * 1. GET /extended/v2/blocks/{height} — block metadata\n\t * 2. GET /extended/v2/blocks/{height}/transactions — all txs (paginated)\n\t * 3. GET /extended/v1/tx/events?tx_id={txId} — events per tx (only for txs with events)\n\t */\n\tasync getBlockForIndexer(\n\t\theight: number,\n\t\toptions?: GetBlockOptions,\n\t): Promise<NewBlockPayload | null> {\n\t\t// 1. Fetch block metadata (try primary, fallback on 404)\n\t\tlet block = await this.fetchBlock(height);\n\t\tconst fallbackUrl = this.fallbackUrl;\n\t\tlet usingFallback = false;\n\t\tif (!block && fallbackUrl) {\n\t\t\tblock = await this.fetchBlock(height, fallbackUrl);\n\t\t\tif (block) usingFallback = true;\n\t\t}\n\t\tif (!block) return null;\n\n\t\t// 2. Fetch all transactions via v2 block/transactions endpoint\n\t\tconst baseUrl = usingFallback && fallbackUrl ? fallbackUrl : this.apiUrl;\n\t\tconst hiroTxs = await this.fetchBlockTransactions(height, baseUrl);\n\n\t\tconst txPayloads: TransactionPayload[] = [];\n\t\tconst eventPayloads: TransactionEventPayload[] = [];\n\n\t\tfor (const hiroTx of hiroTxs) {\n\t\t\ttxPayloads.push({\n\t\t\t\ttxid: hiroTx.tx_id,\n\t\t\t\traw_tx: \"0x00\",\n\t\t\t\tstatus: mapTxStatus(hiroTx.tx_status),\n\t\t\t\ttx_index: hiroTx.tx_index ?? 0,\n\t\t\t\ttx_type: mapTxType(hiroTx.tx_type),\n\t\t\t\tsender_address: hiroTx.sender_address,\n\t\t\t});\n\n\t\t\t// 3. Fetch events only for txs that have them\n\t\t\tif (hiroTx.event_count > 0) {\n\t\t\t\tif (hiroTx.event_count > 1000) {\n\t\t\t\t\tlogger.info(\"Fetching large event set\", {\n\t\t\t\t\t\ttxId: hiroTx.tx_id,\n\t\t\t\t\t\teventCount: hiroTx.event_count,\n\t\t\t\t\t\theight,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tconst events = await this.fetchAllEvents(hiroTx.tx_id, baseUrl);\n\t\t\t\t\teventPayloads.push(...events);\n\t\t\t\t} catch (err) {\n\t\t\t\t\tlogger.warn(\"Failed to fetch events for backfill\", {\n\t\t\t\t\t\ttxId: hiroTx.tx_id,\n\t\t\t\t\t\terror: String(err),\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// 4. Optionally fetch raw_tx for all transactions\n\t\tif (options?.includeRawTx && txPayloads.length > 0) {\n\t\t\tconst txIds = txPayloads.map((t) => t.txid);\n\t\t\tconst rawTxMap = await this.fetchRawTxBatch(\n\t\t\t\ttxIds,\n\t\t\t\toptions.rawTxConcurrency,\n\t\t\t);\n\t\t\tfor (const txPayload of txPayloads) {\n\t\t\t\tconst raw = rawTxMap.get(txPayload.txid);\n\t\t\t\tif (raw) txPayload.raw_tx = raw;\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tblock_hash: block.hash,\n\t\t\tblock_height: block.height,\n\t\t\tindex_block_hash: block.index_block_hash,\n\t\t\tparent_block_hash: block.parent_block_hash,\n\t\t\tparent_index_block_hash: block.parent_index_block_hash,\n\t\t\tburn_block_hash: block.burn_block_hash,\n\t\t\tburn_block_height: block.burn_block_height,\n\t\t\tburn_block_timestamp: block.burn_block_time,\n\t\t\tminer_txid: block.miner_txid,\n\t\t\ttimestamp: block.block_time,\n\t\t\ttransactions: txPayloads,\n\t\t\tevents: eventPayloads,\n\t\t};\n\t}\n\n\t/** v2 block metadata */\n\tprivate async fetchBlock(\n\t\theight: number,\n\t\tbaseUrl?: string,\n\t): Promise<HiroBlockResponse | null> {\n\t\tconst url = baseUrl || this.apiUrl;\n\t\tconst res = await this.fetchWithRetry(\n\t\t\t`${url}/extended/v2/blocks/${height}`,\n\t\t);\n\t\tif (res.status === 404) return null;\n\t\tif (!res.ok)\n\t\t\tthrow new Error(`Hiro API block/${height} returned ${res.status}`);\n\t\treturn res.json() as Promise<HiroBlockResponse>;\n\t}\n\n\t/** v2 block transactions (paginated) */\n\tprivate async fetchBlockTransactions(\n\t\theight: number,\n\t\tbaseUrl?: string,\n\t): Promise<HiroTxResponse[]> {\n\t\tconst url = baseUrl || this.apiUrl;\n\t\tconst txs: HiroTxResponse[] = [];\n\t\tlet offset = 0;\n\t\tconst limit = 50;\n\n\t\twhile (true) {\n\t\t\tconst res = await this.fetchWithRetry(\n\t\t\t\t`${url}/extended/v2/blocks/${height}/transactions?limit=${limit}&offset=${offset}`,\n\t\t\t);\n\t\t\tif (!res.ok)\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Hiro API block/${height}/transactions returned ${res.status}`,\n\t\t\t\t);\n\n\t\t\tconst data = (await res.json()) as HiroBlockTxsResponse;\n\t\t\ttxs.push(...data.results);\n\n\t\t\tif (txs.length >= data.total || data.results.length < limit) break;\n\t\t\toffset += limit;\n\t\t}\n\n\t\treturn txs;\n\t}\n\n\tprivate async fetchAllEvents(\n\t\ttxId: string,\n\t\tbaseUrl?: string,\n\t\t_maxEvents?: number,\n\t): Promise<TransactionEventPayload[]> {\n\t\tconst url = baseUrl || this.apiUrl;\n\t\tconst events: TransactionEventPayload[] = [];\n\t\tlet offset = 0;\n\t\tconst limit = 100;\n\n\t\twhile (true) {\n\t\t\tconst res = await this.fetchWithRetry(\n\t\t\t\t`${url}/extended/v1/tx/events?tx_id=${txId}&limit=${limit}&offset=${offset}`,\n\t\t\t);\n\t\t\tif (!res.ok) {\n\t\t\t\tlogger.warn(\"Failed to fetch events from Hiro\", {\n\t\t\t\t\ttxId,\n\t\t\t\t\tstatus: res.status,\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tconst data = (await res.json()) as HiroEventsResponse;\n\t\t\tfor (const hEvent of data.events) {\n\t\t\t\tconst converted = convertHiroEvent(hEvent);\n\t\t\t\tif (converted) events.push(converted);\n\t\t\t}\n\n\t\t\tif (data.events.length < limit) break;\n\t\t\toffset += limit;\n\t\t}\n\n\t\treturn events;\n\t}\n\n\t/** Fetch raw_tx hex for a single transaction */\n\tasync fetchRawTx(txId: string): Promise<string | null> {\n\t\ttry {\n\t\t\tconst res = await this.fetchWithRetry(\n\t\t\t\t`${this.apiUrl}/extended/v1/tx/${txId}/raw`,\n\t\t\t\t10_000,\n\t\t\t);\n\t\t\tif (!res.ok) return null;\n\t\t\tconst data = (await res.json()) as { raw_tx: string };\n\t\t\treturn data.raw_tx || null;\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t/** Fetch raw_tx for multiple transactions with bounded concurrency */\n\tasync fetchRawTxBatch(\n\t\ttxIds: string[],\n\t\tconcurrency = 10,\n\t): Promise<Map<string, string>> {\n\t\tconst results = new Map<string, string>();\n\t\tfor (let i = 0; i < txIds.length; i += concurrency) {\n\t\t\tconst chunk = txIds.slice(i, i + concurrency);\n\t\t\tconst settled = await Promise.allSettled(\n\t\t\t\tchunk.map(async (txId) => {\n\t\t\t\t\tconst raw = await this.fetchRawTx(txId);\n\t\t\t\t\treturn { txId, raw };\n\t\t\t\t}),\n\t\t\t);\n\t\t\tfor (const result of settled) {\n\t\t\t\tif (result.status === \"fulfilled\" && result.value.raw) {\n\t\t\t\t\tresults.set(result.value.txId, result.value.raw);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn results;\n\t}\n\n\tgetApiUrl(): string {\n\t\treturn this.apiUrl;\n\t}\n}\n\n/** Map Hiro tx_status to our indexer's expected format */\nfunction mapTxStatus(status: string): string {\n\tswitch (status) {\n\t\tcase \"success\":\n\t\t\treturn \"success\";\n\t\tcase \"abort_by_response\":\n\t\tcase \"abort_by_post_condition\":\n\t\t\treturn status;\n\t\tdefault:\n\t\t\treturn \"success\";\n\t}\n}\n\n/** Map Hiro tx_type to node event tx_type */\nfunction mapTxType(type: string): string {\n\tswitch (type) {\n\t\tcase \"token_transfer\":\n\t\t\treturn \"token_transfer\";\n\t\tcase \"contract_call\":\n\t\t\treturn \"contract_call\";\n\t\tcase \"smart_contract\":\n\t\t\treturn \"smart_contract\";\n\t\tcase \"coinbase\":\n\t\t\treturn \"coinbase\";\n\t\tcase \"tenure_change\":\n\t\t\treturn \"tenure_change\";\n\t\tcase \"poison_microblock\":\n\t\t\treturn \"poison_microblock\";\n\t\tdefault:\n\t\t\treturn type;\n\t}\n}\n\n/**\n * Convert a Hiro API event to our indexer's TransactionEvent format.\n *\n * Hiro uses:\n * event_type: \"stx_asset\" | \"fungible_token_asset\" | \"non_fungible_token_asset\" | \"smart_contract_log\"\n * asset.asset_event_type: \"transfer\" | \"mint\" | \"burn\" | \"lock\"\n *\n * Our indexer expects:\n * type: \"stx_transfer_event\" | \"stx_mint_event\" | \"ft_transfer_event\" | \"smart_contract_event\" | ...\n */\nfunction convertHiroEvent(hEvent: HiroEvent): TransactionEventPayload | null {\n\tconst base = {\n\t\ttxid: hEvent.tx_id,\n\t\tevent_index: hEvent.event_index,\n\t\tcommitted: true,\n\t};\n\n\tif (hEvent.event_type === \"stx_asset\" && hEvent.asset) {\n\t\tconst a = hEvent.asset;\n\t\tswitch (a.asset_event_type) {\n\t\t\tcase \"transfer\":\n\t\t\t\treturn {\n\t\t\t\t\t...base,\n\t\t\t\t\ttype: \"stx_transfer_event\",\n\t\t\t\t\tstx_transfer_event: {\n\t\t\t\t\t\tsender: a.sender ?? \"\",\n\t\t\t\t\t\trecipient: a.recipient ?? \"\",\n\t\t\t\t\t\tamount: a.amount ?? \"0\",\n\t\t\t\t\t\tmemo: a.memo,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\tcase \"mint\":\n\t\t\t\treturn {\n\t\t\t\t\t...base,\n\t\t\t\t\ttype: \"stx_mint_event\",\n\t\t\t\t\tstx_mint_event: {\n\t\t\t\t\t\trecipient: a.recipient ?? \"\",\n\t\t\t\t\t\tamount: a.amount ?? \"0\",\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\tcase \"burn\":\n\t\t\t\treturn {\n\t\t\t\t\t...base,\n\t\t\t\t\ttype: \"stx_burn_event\",\n\t\t\t\t\tstx_burn_event: { sender: a.sender ?? \"\", amount: a.amount ?? \"0\" },\n\t\t\t\t};\n\t\t\tcase \"lock\":\n\t\t\t\treturn {\n\t\t\t\t\t...base,\n\t\t\t\t\ttype: \"stx_lock_event\",\n\t\t\t\t\tstx_lock_event: {\n\t\t\t\t\t\tlocked_amount: a.amount ?? \"0\",\n\t\t\t\t\t\tunlock_height: \"0\",\n\t\t\t\t\t\tlocked_address: a.sender ?? \"\",\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t}\n\t}\n\n\tif (hEvent.event_type === \"fungible_token_asset\" && hEvent.asset) {\n\t\tconst a = hEvent.asset;\n\t\tconst assetId = a.asset_id || \"\";\n\t\tswitch (a.asset_event_type) {\n\t\t\tcase \"transfer\":\n\t\t\t\treturn {\n\t\t\t\t\t...base,\n\t\t\t\t\ttype: \"ft_transfer_event\",\n\t\t\t\t\tft_transfer_event: {\n\t\t\t\t\t\tasset_identifier: assetId,\n\t\t\t\t\t\tsender: a.sender ?? \"\",\n\t\t\t\t\t\trecipient: a.recipient ?? \"\",\n\t\t\t\t\t\tamount: a.amount ?? \"0\",\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\tcase \"mint\":\n\t\t\t\treturn {\n\t\t\t\t\t...base,\n\t\t\t\t\ttype: \"ft_mint_event\",\n\t\t\t\t\tft_mint_event: {\n\t\t\t\t\t\tasset_identifier: assetId,\n\t\t\t\t\t\trecipient: a.recipient ?? \"\",\n\t\t\t\t\t\tamount: a.amount ?? \"0\",\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\tcase \"burn\":\n\t\t\t\treturn {\n\t\t\t\t\t...base,\n\t\t\t\t\ttype: \"ft_burn_event\",\n\t\t\t\t\tft_burn_event: {\n\t\t\t\t\t\tasset_identifier: assetId,\n\t\t\t\t\t\tsender: a.sender ?? \"\",\n\t\t\t\t\t\tamount: a.amount ?? \"0\",\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t}\n\t}\n\n\tif (hEvent.event_type === \"non_fungible_token_asset\" && hEvent.asset) {\n\t\tconst a = hEvent.asset;\n\t\tconst assetId = a.asset_id || \"\";\n\t\tswitch (a.asset_event_type) {\n\t\t\tcase \"transfer\":\n\t\t\t\treturn {\n\t\t\t\t\t...base,\n\t\t\t\t\ttype: \"nft_transfer_event\",\n\t\t\t\t\tnft_transfer_event: {\n\t\t\t\t\t\tasset_identifier: assetId,\n\t\t\t\t\t\tsender: a.sender ?? \"\",\n\t\t\t\t\t\trecipient: a.recipient ?? \"\",\n\t\t\t\t\t\tvalue: a.value,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\tcase \"mint\":\n\t\t\t\treturn {\n\t\t\t\t\t...base,\n\t\t\t\t\ttype: \"nft_mint_event\",\n\t\t\t\t\tnft_mint_event: {\n\t\t\t\t\t\tasset_identifier: assetId,\n\t\t\t\t\t\trecipient: a.recipient ?? \"\",\n\t\t\t\t\t\tvalue: a.value,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\tcase \"burn\":\n\t\t\t\treturn {\n\t\t\t\t\t...base,\n\t\t\t\t\ttype: \"nft_burn_event\",\n\t\t\t\t\tnft_burn_event: {\n\t\t\t\t\t\tasset_identifier: assetId,\n\t\t\t\t\t\tsender: a.sender ?? \"\",\n\t\t\t\t\t\tvalue: a.value,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t}\n\t}\n\n\tif (hEvent.event_type === \"smart_contract_log\" && hEvent.contract_log) {\n\t\treturn {\n\t\t\t...base,\n\t\t\ttype: \"smart_contract_event\",\n\t\t\tsmart_contract_event: {\n\t\t\t\tcontract_identifier: hEvent.contract_log.contract_id,\n\t\t\t\ttopic: hEvent.contract_log.topic,\n\t\t\t\tvalue: hEvent.contract_log.value,\n\t\t\t},\n\t\t};\n\t}\n\n\tlogger.debug(\"Unknown Hiro event type, skipping\", {\n\t\teventType: hEvent.event_type,\n\t\ttxId: hEvent.tx_id,\n\t});\n\treturn null;\n}\n"
8
8
  ],
9
- "mappings": "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",
10
- "debugId": "679094A893C0896364756E2164756E21",
9
+ "mappings": "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",
10
+ "debugId": "1FB15B4363B2E96864756E2164756E21",
11
11
  "names": []
12
12
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@secondlayer/shared",
3
- "version": "6.41.3",
3
+ "version": "7.0.0",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -167,7 +167,7 @@
167
167
  "prepublishOnly": "bun run build"
168
168
  },
169
169
  "dependencies": {
170
- "@secondlayer/stacks": "^2.11.0",
170
+ "@secondlayer/stacks": "^2.14.1",
171
171
  "kysely": "0.28.15",
172
172
  "kysely-postgres-js": "3.0.0",
173
173
  "postgres": "^3.4.6",