@secondlayer/sdk 6.11.0 → 6.13.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.
package/README.md CHANGED
@@ -215,6 +215,75 @@ for await (const transfer of sl.index.ftTransfers.walk({
215
215
  }
216
216
  ```
217
217
 
218
+ ## Transaction-inclusion proofs
219
+
220
+ Verify — **without trusting Second Layer** — that a transaction is included in a
221
+ Stacks (Nakamoto) block, and that ≥70% of the reward cycle's signer weight
222
+ attested to that block. `verifyTransactionProof` recomputes everything
223
+ client-side and trusts nothing the API returned.
224
+
225
+ > Verification uses Node's crypto via `@secondlayer/shared` — Node/server-side use.
226
+
227
+ ```typescript
228
+ import { verifyTransactionProof, fetchRewardSet } from "@secondlayer/sdk";
229
+
230
+ const proof = await fetch(
231
+ `https://api.secondlayer.tools/v1/index/transactions/${txid}/proof`,
232
+ ).then((r) => r.json());
233
+
234
+ const result = verifyTransactionProof(proof); // anchored + consensus (embedded set)
235
+ // result.ok, result.level === "consensus", result.signerWeightBps
236
+
237
+ // Fully trustless — resolve the reward set from your own node:
238
+ const rewardSet = await fetchRewardSet({
239
+ nodeUrl: "https://your-stacks-node:20443",
240
+ cycle: proof.consensus.reward_cycle,
241
+ });
242
+ const trustless = verifyTransactionProof(proof, { rewardSet }); // rewardSetSource: "provided"
243
+ ```
244
+
245
+ Two trust levels:
246
+
247
+ - **Anchored** — recompute the txid from `raw_tx`, fold `tx_merkle_path` up to the
248
+ header's `tx_merkle_root`, and recompute `block_hash` + `index_block_hash` from
249
+ `raw_header`. The tx is in a header any node can corroborate.
250
+ - **Consensus** — additionally recover the header's signer signatures and confirm
251
+ ≥70% of the reward cycle's signer weight signed the block. Fully trustless when
252
+ you pass a `rewardSet` resolved yourself via `fetchRewardSet`
253
+ (`rewardSetSource: "provided"`); otherwise it uses the proof's embedded set
254
+ (`rewardSetSource: "embedded"`).
255
+
256
+ ```typescript
257
+ verifyTransactionProof(
258
+ proof: TransactionProof,
259
+ opts?: { rewardSet?: RewardSet },
260
+ ): TransactionProofVerifyResult;
261
+
262
+ fetchRewardSet(opts: {
263
+ nodeUrl: string; // your own stacks-node
264
+ cycle: number; // reward cycle — proof.consensus.reward_cycle
265
+ fetchImpl?: typeof fetch;
266
+ }): Promise<RewardSet | null>; // reads /v3/stacker_set/{cycle}
267
+ ```
268
+
269
+ `verifyTransactionProof` returns a `TransactionProofVerifyResult`:
270
+
271
+ ```typescript
272
+ {
273
+ level: "anchored" | "consensus";
274
+ txidMatches: boolean;
275
+ includedInHeader: boolean;
276
+ headerSelfConsistent: boolean;
277
+ signerWeightBps?: number; // consensus only
278
+ thresholdMet?: boolean; // consensus only — ≥70% (7000 bps)
279
+ rewardSetSource?: "provided" | "embedded";
280
+ ok: boolean;
281
+ errors: string[];
282
+ }
283
+ ```
284
+
285
+ Exported types: `TransactionProof`, `TransactionProofVerifyResult`, `RewardSet`.
286
+
218
287
  ## Stacks Subgraphs
219
288
 
220
289
  Deploy and query app-specific L3 tables.
package/dist/index.d.ts CHANGED
@@ -337,6 +337,27 @@ type IndexTip = {
337
337
  block_height: number
338
338
  lag_seconds: number
339
339
  };
340
+ /**
341
+ * A chain reorg overlapping a returned page's height range. Height-keyed feeds
342
+ * (`/transactions`, `/contract-calls`, `/stacking`) populate this so a consumer
343
+ * can reconcile: roll back the rows whose `block_height:tx_index` cursor falls in
344
+ * `orphaned_range`, then re-fetch from `new_canonical_tip`. Empty when the page
345
+ * spans no reorg.
346
+ */
347
+ type IndexReorg = {
348
+ id: string
349
+ detected_at: string
350
+ fork_point_height: number
351
+ old_index_block_hash: string | null
352
+ new_index_block_hash: string | null
353
+ /** Orphaned cursor span `<block_height>:<tx_index>`, inclusive. */
354
+ orphaned_range: {
355
+ from: string
356
+ to: string
357
+ }
358
+ /** New canonical tip cursor to resume from. */
359
+ new_canonical_tip: string
360
+ };
340
361
  type IndexUsage = {
341
362
  product: "index"
342
363
  tier: string
@@ -365,7 +386,7 @@ type FtTransfersEnvelope = {
365
386
  events: FtTransfer[]
366
387
  next_cursor: string | null
367
388
  tip: IndexTip
368
- reorgs: never[]
389
+ reorgs: IndexReorg[]
369
390
  };
370
391
  type FtTransfersListParams = {
371
392
  cursor?: string | null
@@ -398,7 +419,7 @@ type NftTransfersEnvelope = {
398
419
  events: NftTransfer[]
399
420
  next_cursor: string | null
400
421
  tip: IndexTip
401
- reorgs: never[]
422
+ reorgs: IndexReorg[]
402
423
  };
403
424
  type NftTransfersListParams = {
404
425
  cursor?: string | null
@@ -502,7 +523,7 @@ type EventsEnvelope = {
502
523
  events: IndexEvent[]
503
524
  next_cursor: string | null
504
525
  tip: IndexTip
505
- reorgs: never[]
526
+ reorgs: IndexReorg[]
506
527
  };
507
528
  type EventsListParams = {
508
529
  /** Required. One of the decoded event types. */
@@ -539,7 +560,7 @@ type ContractCallsEnvelope = {
539
560
  contract_calls: IndexContractCall[]
540
561
  next_cursor: string | null
541
562
  tip: IndexTip
542
- reorgs: never[]
563
+ reorgs: IndexReorg[]
543
564
  };
544
565
  type ContractCallsListParams = {
545
566
  cursor?: string | null
@@ -682,7 +703,7 @@ type TransactionsEnvelope = {
682
703
  transactions: IndexTransaction[]
683
704
  next_cursor: string | null
684
705
  tip: IndexTip
685
- reorgs: never[]
706
+ reorgs: IndexReorg[]
686
707
  };
687
708
  type TransactionEnvelope = {
688
709
  transaction: IndexTransaction
@@ -731,7 +752,7 @@ type StackingEnvelope = {
731
752
  stacking: IndexStackingAction[]
732
753
  next_cursor: string | null
733
754
  tip: IndexTip
734
- reorgs: never[]
755
+ reorgs: IndexReorg[]
735
756
  /** Present only when the PoX-4 decoder is disabled, explaining an empty feed. */
736
757
  notes?: string
737
758
  };
@@ -1807,10 +1828,90 @@ declare function verifyWebhookSignature(rawBody: string, headers: WebhookHeaderI
1807
1828
  * ```
1808
1829
  */
1809
1830
  declare function verifySecondlayerSignature(rawBody: string, headers: WebhookHeaderInput, publicKeyPem: string): boolean;
1831
+ import { RewardSet } from "@secondlayer/shared/node/consensus";
1832
+ import { MerkleProofStep } from "@secondlayer/shared/node/nakamoto";
1833
+ /**
1834
+ * Trustless transaction-inclusion proof verification.
1835
+ *
1836
+ * Given a proof from `GET /v1/index/transactions/:txid/proof`, the consumer
1837
+ * re-derives everything itself — it does NOT trust any value Secondlayer
1838
+ * computed. Anchored level: (1) recompute the txid from the raw tx bytes, (2)
1839
+ * fold it up the merkle path to the header's `tx_merkle_root`, (3) recompute the
1840
+ * header's `block_hash` and `index_block_hash` from the raw header — "this tx is
1841
+ * included in a header any node can corroborate". Consensus level (when the proof
1842
+ * carries a `consensus` field, or a `rewardSet` is passed): additionally recover
1843
+ * the header's signer signatures and confirm ≥70% of reward-set signer weight
1844
+ * signed the block.
1845
+ *
1846
+ * Note: uses Node's crypto via `@secondlayer/shared` (same as the Streams
1847
+ * signature verify); intended for Node/server verification.
1848
+ */
1849
+ interface TransactionProof {
1850
+ txid: string;
1851
+ index_block_hash: string;
1852
+ block_height: number;
1853
+ tx_index: number;
1854
+ /** Raw consensus-serialized transaction bytes (hex). */
1855
+ raw_tx: string;
1856
+ /** Raw Nakamoto block-header bytes (hex) — parsed + re-hashed by the verifier. */
1857
+ raw_header: string;
1858
+ /** Authentication path from the tx leaf to `tx_merkle_root`. */
1859
+ tx_merkle_path: MerkleProofStep[];
1860
+ /** Present when consensus-level verification is available: the reward cycle and
1861
+ * its signer set, against which the header's signer signatures are checked. */
1862
+ consensus?: {
1863
+ reward_cycle: number
1864
+ reward_set: RewardSet
1865
+ };
1866
+ }
1867
+ interface TransactionProofVerifyResult {
1868
+ /** Highest level actually verified. "consensus" requires the proof's
1869
+ * `consensus` field and a met signer-weight threshold. */
1870
+ level: "anchored" | "consensus";
1871
+ /** Recomputed txid === proof.txid. */
1872
+ txidMatches: boolean;
1873
+ /** Merkle path folds the txid to the header's tx_merkle_root. */
1874
+ includedInHeader: boolean;
1875
+ /** Recomputed block_hash + index_block_hash match the header / proof. */
1876
+ headerSelfConsistent: boolean;
1877
+ /** Basis points (0–10000) of reward-set signer weight that signed the block.
1878
+ * Only set when the proof carries a `consensus` field. */
1879
+ signerWeightBps?: number;
1880
+ /** ≥70% of signer weight signed. Only set with a `consensus` field. */
1881
+ thresholdMet?: boolean;
1882
+ /** Which reward set the signer check used: "provided" (caller-resolved →
1883
+ * fully trustless) or "embedded" (the one Secondlayer put in the proof). */
1884
+ rewardSetSource?: "provided" | "embedded";
1885
+ /** All applicable checks passed (incl. the threshold when consensus is present). */
1886
+ ok: boolean;
1887
+ errors: string[];
1888
+ }
1889
+ /**
1890
+ * Resolve a reward set directly from a stacks-node (`/v3/stacker_set/{cycle}`),
1891
+ * so a caller can verify the consensus layer against a node IT trusts rather than
1892
+ * the reward set Secondlayer embedded in the proof. Pass the result as
1893
+ * `verifyTransactionProof(proof, { rewardSet })`.
1894
+ */
1895
+ declare function fetchRewardSet(opts: {
1896
+ nodeUrl: string
1897
+ cycle: number
1898
+ fetchImpl?: typeof fetch
1899
+ }): Promise<RewardSet | null>;
1900
+ /**
1901
+ * Verify a transaction-inclusion proof. Every check is recomputed client-side,
1902
+ * so a `true` result does not rely on trusting Secondlayer. Pass
1903
+ * `{ rewardSet }` (resolved via {@link fetchRewardSet} from your own node) to
1904
+ * verify the consensus layer against a reward set you trust rather than the one
1905
+ * embedded in the proof.
1906
+ */
1907
+ declare function verifyTransactionProof(proof: TransactionProof, opts?: {
1908
+ rewardSet?: RewardSet
1909
+ }): TransactionProofVerifyResult;
1910
+ import { RewardSet as RewardSet2 } from "@secondlayer/shared/node/consensus";
1810
1911
  /** Make a cvToValue result JSON-serializable: Clarity (u)ints decode to bigint,
1811
1912
  * which JSON.stringify can't handle — convert recursively to strings. */
1812
1913
  declare function toJsonSafe(value: unknown): unknown;
1813
1914
  /** Decode a hex-encoded Clarity value to JSON-safe JS (uints as strings,
1814
1915
  * buffers as `0x…` hex, tuples as objects). Returns the input hex on failure. */
1815
1916
  declare function decodeClarityValue(hex: string): unknown;
1816
- export { verifyWebhookSignature, verifySecondlayerSignature, trigger, toJsonSafe, isStxTransfer, isStxMint, isStxLock, isStxBurn, isPrint, isNftTransfer, isNftMint, isNftBurn, isFtTransfer, isFtMint, isFtBurn, getSubgraph, decodeStxTransfer, decodeStxMint, decodeStxLock, decodeStxBurn, decodePrint, decodeNftTransfer, decodeNftMint, decodeNftBurn, decodeFtTransfer, decodeFtMint, decodeFtBurn, decodeClarityValue, createStreamsClient, VersionConflictError, ValidationError, UpdateSubscriptionRequest2 as UpdateSubscriptionRequest, TransactionsWalkParams, TransactionsListParams, TransactionsEnvelope, TransactionEnvelope, Subscriptions, SubscriptionSummary2 as SubscriptionSummary, SubscriptionStatus, SubscriptionRuntime, SubscriptionKind, SubscriptionFormat, SubscriptionDetail2 as SubscriptionDetail, Subgraphs, SubgraphSpecOptions3 as SubgraphSpecOptions, SubgraphSpecFormat2 as SubgraphSpecFormat, SubgraphOperationStatus, SubgraphAgentSchema3 as SubgraphAgentSchema, StreamsUsage, StreamsTip, StreamsSignatureError, StreamsServerError, StreamsReorgsListParams, StreamsReorgsListEnvelope, StreamsReorgContext, StreamsReorg, StreamsEventsSubscribeParams, StreamsEventsStreamParams, StreamsEventsListParams, StreamsEventsListEnvelope, StreamsEventsEnvelope, StreamsEventsConsumeResult, StreamsEventsConsumeParams, StreamsEventType, StreamsEventPayload, StreamsEvent, StreamsDumpsManifest, StreamsDumps, StreamsDumpFile, StreamsClient, StreamsCanonicalBlock, StreamsBatchContext, StackingWalkParams, StackingListParams, StackingEnvelope, SecondLayerOptions, SecondLayer, ScopedKeyProduct, RotateSecretResponse2 as RotateSecretResponse, ReplayResult2 as ReplayResult, RateLimitError, Pox4CallsParams, NftTransfersWalkParams, NftTransfersListParams, NftTransfersEnvelope, NftTransferPayload, NftTransferEvent, NftTransfer, MempoolWalkParams, MempoolTransactionEnvelope, MempoolListParams, MempoolEnvelope, IndexUsage, IndexTransaction, IndexTip, IndexStackingAction, IndexPostCondition, IndexMempoolTransaction, IndexEventType, IndexEvent, IndexContractCall, IndexCanonicalBlock, IndexBlock, Index, FtTransfersWalkParams, FtTransfersListParams, FtTransfersEnvelope, FtTransferPayload, FtTransferEvent, FtTransfer, FetchLike2 as FetchLike, EventsWalkParams, EventsListParams, EventsEnvelope, DeliveryRow2 as DeliveryRow, DecodedStxTransferPayload, DecodedStxTransfer, DecodedStxMintPayload, DecodedStxMint, DecodedStxLockPayload, DecodedStxLock, DecodedStxBurnPayload, DecodedStxBurn, DecodedPrintValue, DecodedPrintPayload, DecodedPrint, DecodedNftTransferPayload, DecodedNftTransfer, DecodedNftMintPayload, DecodedNftMint, DecodedNftBurnPayload, DecodedNftBurn, DecodedFtTransferPayload, DecodedFtTransfer, DecodedFtMintPayload, DecodedFtMint, DecodedFtBurnPayload, DecodedFtBurn, DecodedEventRow, DecodedEventColumns, DeadRow2 as DeadRow, Datasets, DatasetRow, CursorListParams, CursorEnvelope, Cursor, CreateSubscriptionResponse2 as CreateSubscriptionResponse, CreateSubscriptionRequest2 as CreateSubscriptionRequest, CreateApiKeyResponse, CreateApiKeyParams, ContractsListParams, ContractsEnvelope, Contracts, ContractSummary, ContractConformance, ContractCallsWalkParams, ContractCallsListParams, ContractCallsEnvelope, ContextSnapshot, ContextAccount, ChainTriggerType, ChainTrigger, CanonicalWalkParams, CanonicalListParams, CanonicalEnvelope, CURSOR_SLUGS, BlocksWalkParams, BlocksListParams, BlocksEnvelope, BlockEnvelope, AuthError, ApiKeys, ApiError, ActiveSubgraphOperation };
1917
+ export { verifyWebhookSignature, verifyTransactionProof, verifySecondlayerSignature, trigger, toJsonSafe, isStxTransfer, isStxMint, isStxLock, isStxBurn, isPrint, isNftTransfer, isNftMint, isNftBurn, isFtTransfer, isFtMint, isFtBurn, getSubgraph, fetchRewardSet, decodeStxTransfer, decodeStxMint, decodeStxLock, decodeStxBurn, decodePrint, decodeNftTransfer, decodeNftMint, decodeNftBurn, decodeFtTransfer, decodeFtMint, decodeFtBurn, decodeClarityValue, createStreamsClient, VersionConflictError, ValidationError, UpdateSubscriptionRequest2 as UpdateSubscriptionRequest, TransactionsWalkParams, TransactionsListParams, TransactionsEnvelope, TransactionProofVerifyResult, TransactionProof, TransactionEnvelope, Subscriptions, SubscriptionSummary2 as SubscriptionSummary, SubscriptionStatus, SubscriptionRuntime, SubscriptionKind, SubscriptionFormat, SubscriptionDetail2 as SubscriptionDetail, Subgraphs, SubgraphSpecOptions3 as SubgraphSpecOptions, SubgraphSpecFormat2 as SubgraphSpecFormat, SubgraphOperationStatus, SubgraphAgentSchema3 as SubgraphAgentSchema, StreamsUsage, StreamsTip, StreamsSignatureError, StreamsServerError, StreamsReorgsListParams, StreamsReorgsListEnvelope, StreamsReorgContext, StreamsReorg, StreamsEventsSubscribeParams, StreamsEventsStreamParams, StreamsEventsListParams, StreamsEventsListEnvelope, StreamsEventsEnvelope, StreamsEventsConsumeResult, StreamsEventsConsumeParams, StreamsEventType, StreamsEventPayload, StreamsEvent, StreamsDumpsManifest, StreamsDumps, StreamsDumpFile, StreamsClient, StreamsCanonicalBlock, StreamsBatchContext, StackingWalkParams, StackingListParams, StackingEnvelope, SecondLayerOptions, SecondLayer, ScopedKeyProduct, RotateSecretResponse2 as RotateSecretResponse, RewardSet2 as RewardSet, ReplayResult2 as ReplayResult, RateLimitError, Pox4CallsParams, NftTransfersWalkParams, NftTransfersListParams, NftTransfersEnvelope, NftTransferPayload, NftTransferEvent, NftTransfer, MempoolWalkParams, MempoolTransactionEnvelope, MempoolListParams, MempoolEnvelope, IndexUsage, IndexTransaction, IndexTip, IndexStackingAction, IndexReorg, IndexPostCondition, IndexMempoolTransaction, IndexEventType, IndexEvent, IndexContractCall, IndexCanonicalBlock, IndexBlock, Index, FtTransfersWalkParams, FtTransfersListParams, FtTransfersEnvelope, FtTransferPayload, FtTransferEvent, FtTransfer, FetchLike2 as FetchLike, EventsWalkParams, EventsListParams, EventsEnvelope, DeliveryRow2 as DeliveryRow, DecodedStxTransferPayload, DecodedStxTransfer, DecodedStxMintPayload, DecodedStxMint, DecodedStxLockPayload, DecodedStxLock, DecodedStxBurnPayload, DecodedStxBurn, DecodedPrintValue, DecodedPrintPayload, DecodedPrint, DecodedNftTransferPayload, DecodedNftTransfer, DecodedNftMintPayload, DecodedNftMint, DecodedNftBurnPayload, DecodedNftBurn, DecodedFtTransferPayload, DecodedFtTransfer, DecodedFtMintPayload, DecodedFtMint, DecodedFtBurnPayload, DecodedFtBurn, DecodedEventRow, DecodedEventColumns, DeadRow2 as DeadRow, Datasets, DatasetRow, CursorListParams, CursorEnvelope, Cursor, CreateSubscriptionResponse2 as CreateSubscriptionResponse, CreateSubscriptionRequest2 as CreateSubscriptionRequest, CreateApiKeyResponse, CreateApiKeyParams, ContractsListParams, ContractsEnvelope, Contracts, ContractSummary, ContractConformance, ContractCallsWalkParams, ContractCallsListParams, ContractCallsEnvelope, ContextSnapshot, ContextAccount, ChainTriggerType, ChainTrigger, CanonicalWalkParams, CanonicalListParams, CanonicalEnvelope, CURSOR_SLUGS, BlocksWalkParams, BlocksListParams, BlocksEnvelope, BlockEnvelope, AuthError, ApiKeys, ApiError, ActiveSubgraphOperation };
package/dist/index.js CHANGED
@@ -1965,8 +1965,84 @@ function verifySecondlayerSignature(rawBody, headers, publicKeyPem) {
1965
1965
  const signature = pickHeader(headers, "x-secondlayer-signature");
1966
1966
  return verifySecondlayerSignatureValues(rawBody, id, signature, publicKeyPem);
1967
1967
  }
1968
+ // src/proofs.ts
1969
+ import {
1970
+ verifySignerSignatures
1971
+ } from "@secondlayer/shared/node/consensus";
1972
+ import {
1973
+ nakamotoBlockHash,
1974
+ nakamotoBlockId,
1975
+ parseNakamotoBlockHeader,
1976
+ stacksTxid,
1977
+ verifyTxMerkleProof
1978
+ } from "@secondlayer/shared/node/nakamoto";
1979
+ var strip = (h) => h.startsWith("0x") ? h.slice(2) : h;
1980
+ var bytes = (h) => Uint8Array.from(Buffer.from(strip(h), "hex"));
1981
+ async function fetchRewardSet(opts) {
1982
+ const f = opts.fetchImpl ?? fetch;
1983
+ const res = await f(`${opts.nodeUrl.replace(/\/+$/, "")}/v3/stacker_set/${opts.cycle}`);
1984
+ if (res.status === 404)
1985
+ return null;
1986
+ if (!res.ok) {
1987
+ throw new Error(`/v3/stacker_set/${opts.cycle} returned ${res.status}`);
1988
+ }
1989
+ const body = await res.json();
1990
+ const signers = body.stacker_set.signers.map((s) => ({
1991
+ signing_key: strip(s.signing_key),
1992
+ weight: s.weight
1993
+ }));
1994
+ return {
1995
+ signers,
1996
+ total_weight: signers.reduce((sum, s) => sum + s.weight, 0)
1997
+ };
1998
+ }
1999
+ function verifyTransactionProof(proof, opts) {
2000
+ const errors = [];
2001
+ const computedTxid = stacksTxid(bytes(proof.raw_tx));
2002
+ const txidMatches = computedTxid === strip(proof.txid);
2003
+ if (!txidMatches)
2004
+ errors.push("txid does not match raw_tx");
2005
+ const header = parseNakamotoBlockHeader(bytes(proof.raw_header));
2006
+ const includedInHeader = verifyTxMerkleProof(computedTxid, proof.tx_merkle_path, header.txMerkleRoot);
2007
+ if (!includedInHeader)
2008
+ errors.push("merkle path does not reach tx_merkle_root");
2009
+ const blockHash = nakamotoBlockHash(header);
2010
+ const indexBlockHash = nakamotoBlockId(blockHash, header.consensusHash);
2011
+ const headerSelfConsistent = indexBlockHash === strip(proof.index_block_hash);
2012
+ if (!headerSelfConsistent) {
2013
+ errors.push("recomputed index_block_hash does not match proof");
2014
+ }
2015
+ const anchoredOk = txidMatches && includedInHeader && headerSelfConsistent;
2016
+ const rewardSet = opts?.rewardSet ?? proof.consensus?.reward_set;
2017
+ let level = "anchored";
2018
+ let signerWeightBps;
2019
+ let thresholdMet;
2020
+ let rewardSetSource;
2021
+ if (rewardSet) {
2022
+ const v = verifySignerSignatures(blockHash, header.signerSignatures, rewardSet);
2023
+ signerWeightBps = v.totalWeight > 0 ? Math.round(v.signedWeight / v.totalWeight * 1e4) : 0;
2024
+ thresholdMet = v.thresholdMet;
2025
+ rewardSetSource = opts?.rewardSet ? "provided" : "embedded";
2026
+ if (!thresholdMet)
2027
+ errors.push("signer weight below the 70% threshold");
2028
+ if (anchoredOk && thresholdMet)
2029
+ level = "consensus";
2030
+ }
2031
+ return {
2032
+ level,
2033
+ txidMatches,
2034
+ includedInHeader,
2035
+ headerSelfConsistent,
2036
+ signerWeightBps,
2037
+ thresholdMet,
2038
+ rewardSetSource,
2039
+ ok: anchoredOk && (rewardSet ? thresholdMet === true : true),
2040
+ errors
2041
+ };
2042
+ }
1968
2043
  export {
1969
2044
  verifyWebhookSignature,
2045
+ verifyTransactionProof,
1970
2046
  verifySecondlayerSignature,
1971
2047
  trigger,
1972
2048
  toJsonSafe,
@@ -1982,6 +2058,7 @@ export {
1982
2058
  isFtMint,
1983
2059
  isFtBurn,
1984
2060
  getSubgraph,
2061
+ fetchRewardSet,
1985
2062
  decodeStxTransfer,
1986
2063
  decodeStxMint,
1987
2064
  decodeStxLock,
@@ -2013,5 +2090,5 @@ export {
2013
2090
  ApiError
2014
2091
  };
2015
2092
 
2016
- //# debugId=7E891A303DCCD65B64756E2164756E21
2093
+ //# debugId=5E490BEDE2791EFC64756E2164756E21
2017
2094
  //# sourceMappingURL=index.js.map