@secondlayer/sdk 6.18.0 → 6.19.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/dist/index.d.ts CHANGED
@@ -232,6 +232,13 @@ declare class Contracts extends BaseClient {
232
232
  constructor(options?: Partial<SecondLayerOptions>);
233
233
  /** Find contracts conforming to `trait`. `trait` is required (server 400s without it). */
234
234
  list(params: ContractsListParams): Promise<ContractsEnvelope>;
235
+ /**
236
+ * Fetch a single contract from the registry by id (the prod-safe ABI source).
237
+ * Pass `{ includeAbi: true }` for the full ABI blob. Resolves null on 404.
238
+ */
239
+ get(contractId: string, opts?: {
240
+ includeAbi?: boolean
241
+ }): Promise<ContractSummary | null>;
235
242
  }
236
243
  /**
237
244
  * Typed client for the Foundation Datasets REST API (`/v1/datasets/*`).
@@ -382,6 +389,85 @@ declare class Datasets extends BaseClient {
382
389
  private paramsToQuery;
383
390
  private cursorDataset;
384
391
  }
392
+ import { RewardSet } from "@secondlayer/shared/node/consensus";
393
+ import { MerkleProofStep } from "@secondlayer/shared/node/nakamoto";
394
+ /**
395
+ * Trustless transaction-inclusion proof verification.
396
+ *
397
+ * Given a proof from `GET /v1/index/transactions/:txid/proof`, the consumer
398
+ * re-derives everything itself — it does NOT trust any value Secondlayer
399
+ * computed. Anchored level: (1) recompute the txid from the raw tx bytes, (2)
400
+ * fold it up the merkle path to the header's `tx_merkle_root`, (3) recompute the
401
+ * header's `block_hash` and `index_block_hash` from the raw header — "this tx is
402
+ * included in a header any node can corroborate". Consensus level (when the proof
403
+ * carries a `consensus` field, or a `rewardSet` is passed): additionally recover
404
+ * the header's signer signatures and confirm ≥70% of reward-set signer weight
405
+ * signed the block.
406
+ *
407
+ * Note: uses Node's crypto via `@secondlayer/shared` (same as the Streams
408
+ * signature verify); intended for Node/server verification.
409
+ */
410
+ interface TransactionProof {
411
+ txid: string;
412
+ index_block_hash: string;
413
+ block_height: number;
414
+ tx_index: number;
415
+ /** Raw consensus-serialized transaction bytes (hex). */
416
+ raw_tx: string;
417
+ /** Raw Nakamoto block-header bytes (hex) — parsed + re-hashed by the verifier. */
418
+ raw_header: string;
419
+ /** Authentication path from the tx leaf to `tx_merkle_root`. */
420
+ tx_merkle_path: MerkleProofStep[];
421
+ /** Present when consensus-level verification is available: the reward cycle and
422
+ * its signer set, against which the header's signer signatures are checked. */
423
+ consensus?: {
424
+ reward_cycle: number
425
+ reward_set: RewardSet
426
+ };
427
+ }
428
+ interface TransactionProofVerifyResult {
429
+ /** Highest level actually verified. "consensus" requires the proof's
430
+ * `consensus` field and a met signer-weight threshold. */
431
+ level: "anchored" | "consensus";
432
+ /** Recomputed txid === proof.txid. */
433
+ txidMatches: boolean;
434
+ /** Merkle path folds the txid to the header's tx_merkle_root. */
435
+ includedInHeader: boolean;
436
+ /** Recomputed block_hash + index_block_hash match the header / proof. */
437
+ headerSelfConsistent: boolean;
438
+ /** Basis points (0–10000) of reward-set signer weight that signed the block.
439
+ * Only set when the proof carries a `consensus` field. */
440
+ signerWeightBps?: number;
441
+ /** ≥70% of signer weight signed. Only set with a `consensus` field. */
442
+ thresholdMet?: boolean;
443
+ /** Which reward set the signer check used: "provided" (caller-resolved →
444
+ * fully trustless) or "embedded" (the one Secondlayer put in the proof). */
445
+ rewardSetSource?: "provided" | "embedded";
446
+ /** All applicable checks passed (incl. the threshold when consensus is present). */
447
+ ok: boolean;
448
+ errors: string[];
449
+ }
450
+ /**
451
+ * Resolve a reward set directly from a stacks-node (`/v3/stacker_set/{cycle}`),
452
+ * so a caller can verify the consensus layer against a node IT trusts rather than
453
+ * the reward set Secondlayer embedded in the proof. Pass the result as
454
+ * `verifyTransactionProof(proof, { rewardSet })`.
455
+ */
456
+ declare function fetchRewardSet(opts: {
457
+ nodeUrl: string
458
+ cycle: number
459
+ fetchImpl?: typeof fetch
460
+ }): Promise<RewardSet | null>;
461
+ /**
462
+ * Verify a transaction-inclusion proof. Every check is recomputed client-side,
463
+ * so a `true` result does not rely on trusting Secondlayer. Pass
464
+ * `{ rewardSet }` (resolved via {@link fetchRewardSet} from your own node) to
465
+ * verify the consensus layer against a reward set you trust rather than the one
466
+ * embedded in the proof.
467
+ */
468
+ declare function verifyTransactionProof(proof: TransactionProof, opts?: {
469
+ rewardSet?: RewardSet
470
+ }): TransactionProofVerifyResult;
385
471
  type IndexTip = {
386
472
  block_height: number
387
473
  lag_seconds: number
@@ -941,6 +1027,7 @@ declare class Index extends BaseClient {
941
1027
  list: (params?: TransactionsListParams) => Promise<TransactionsEnvelope>
942
1028
  walk: (params?: TransactionsWalkParams) => AsyncIterable<IndexTransaction>
943
1029
  get: (txId: string) => Promise<TransactionEnvelope | null>
1030
+ getProof: (txId: string) => Promise<TransactionProof | null>
944
1031
  };
945
1032
  /** Decoded PoX-4 stacking actions. Empty (with a `notes` hint) when the
946
1033
  * platform's PoX-4 decoder is disabled. */
@@ -970,6 +1057,11 @@ declare class Index extends BaseClient {
970
1057
  private walkBlocks;
971
1058
  private listTransactions;
972
1059
  private getTransaction;
1060
+ /** Fetch the inclusion proof for a tx (raw tx + Nakamoto header + merkle path)
1061
+ * to verify client-side with `verifyTransactionProof`. 404 → null. A 503
1062
+ * (`PROOF_TX_SET_INCOMPLETE` / `PROOF_NODE_UNAVAILABLE`) surfaces as an
1063
+ * ApiError — the proof can't be assembled on this deployment right now. */
1064
+ private getTransactionProof;
973
1065
  private walkTransactions;
974
1066
  private listStacking;
975
1067
  private walkStacking;
@@ -2026,85 +2118,6 @@ declare function verifyWebhookSignature(rawBody: string, headers: WebhookHeaderI
2026
2118
  * ```
2027
2119
  */
2028
2120
  declare function verifySecondlayerSignature(rawBody: string, headers: WebhookHeaderInput, publicKeyPem: string): boolean;
2029
- import { RewardSet } from "@secondlayer/shared/node/consensus";
2030
- import { MerkleProofStep } from "@secondlayer/shared/node/nakamoto";
2031
- /**
2032
- * Trustless transaction-inclusion proof verification.
2033
- *
2034
- * Given a proof from `GET /v1/index/transactions/:txid/proof`, the consumer
2035
- * re-derives everything itself — it does NOT trust any value Secondlayer
2036
- * computed. Anchored level: (1) recompute the txid from the raw tx bytes, (2)
2037
- * fold it up the merkle path to the header's `tx_merkle_root`, (3) recompute the
2038
- * header's `block_hash` and `index_block_hash` from the raw header — "this tx is
2039
- * included in a header any node can corroborate". Consensus level (when the proof
2040
- * carries a `consensus` field, or a `rewardSet` is passed): additionally recover
2041
- * the header's signer signatures and confirm ≥70% of reward-set signer weight
2042
- * signed the block.
2043
- *
2044
- * Note: uses Node's crypto via `@secondlayer/shared` (same as the Streams
2045
- * signature verify); intended for Node/server verification.
2046
- */
2047
- interface TransactionProof {
2048
- txid: string;
2049
- index_block_hash: string;
2050
- block_height: number;
2051
- tx_index: number;
2052
- /** Raw consensus-serialized transaction bytes (hex). */
2053
- raw_tx: string;
2054
- /** Raw Nakamoto block-header bytes (hex) — parsed + re-hashed by the verifier. */
2055
- raw_header: string;
2056
- /** Authentication path from the tx leaf to `tx_merkle_root`. */
2057
- tx_merkle_path: MerkleProofStep[];
2058
- /** Present when consensus-level verification is available: the reward cycle and
2059
- * its signer set, against which the header's signer signatures are checked. */
2060
- consensus?: {
2061
- reward_cycle: number
2062
- reward_set: RewardSet
2063
- };
2064
- }
2065
- interface TransactionProofVerifyResult {
2066
- /** Highest level actually verified. "consensus" requires the proof's
2067
- * `consensus` field and a met signer-weight threshold. */
2068
- level: "anchored" | "consensus";
2069
- /** Recomputed txid === proof.txid. */
2070
- txidMatches: boolean;
2071
- /** Merkle path folds the txid to the header's tx_merkle_root. */
2072
- includedInHeader: boolean;
2073
- /** Recomputed block_hash + index_block_hash match the header / proof. */
2074
- headerSelfConsistent: boolean;
2075
- /** Basis points (0–10000) of reward-set signer weight that signed the block.
2076
- * Only set when the proof carries a `consensus` field. */
2077
- signerWeightBps?: number;
2078
- /** ≥70% of signer weight signed. Only set with a `consensus` field. */
2079
- thresholdMet?: boolean;
2080
- /** Which reward set the signer check used: "provided" (caller-resolved →
2081
- * fully trustless) or "embedded" (the one Secondlayer put in the proof). */
2082
- rewardSetSource?: "provided" | "embedded";
2083
- /** All applicable checks passed (incl. the threshold when consensus is present). */
2084
- ok: boolean;
2085
- errors: string[];
2086
- }
2087
- /**
2088
- * Resolve a reward set directly from a stacks-node (`/v3/stacker_set/{cycle}`),
2089
- * so a caller can verify the consensus layer against a node IT trusts rather than
2090
- * the reward set Secondlayer embedded in the proof. Pass the result as
2091
- * `verifyTransactionProof(proof, { rewardSet })`.
2092
- */
2093
- declare function fetchRewardSet(opts: {
2094
- nodeUrl: string
2095
- cycle: number
2096
- fetchImpl?: typeof fetch
2097
- }): Promise<RewardSet | null>;
2098
- /**
2099
- * Verify a transaction-inclusion proof. Every check is recomputed client-side,
2100
- * so a `true` result does not rely on trusting Secondlayer. Pass
2101
- * `{ rewardSet }` (resolved via {@link fetchRewardSet} from your own node) to
2102
- * verify the consensus layer against a reward set you trust rather than the one
2103
- * embedded in the proof.
2104
- */
2105
- declare function verifyTransactionProof(proof: TransactionProof, opts?: {
2106
- rewardSet?: RewardSet
2107
- }): TransactionProofVerifyResult;
2108
2121
  import { RewardSet as RewardSet2 } from "@secondlayer/shared/node/consensus";
2109
2122
  /** Make a cvToValue result JSON-serializable: Clarity (u)ints decode to bigint,
2110
2123
  * which JSON.stringify can't handle — convert recursively to strings. */
package/dist/index.js CHANGED
@@ -417,6 +417,16 @@ class Contracts extends BaseClient {
417
417
  cursor: params.cursor
418
418
  })}`);
419
419
  }
420
+ async get(contractId, opts = {}) {
421
+ try {
422
+ const { contract } = await this.request("GET", `/v1/contracts/${encodeURIComponent(contractId)}${opts.includeAbi ? "?include=abi" : ""}`);
423
+ return contract;
424
+ } catch (err) {
425
+ if (err instanceof ApiError && err.status === 404)
426
+ return null;
427
+ throw err;
428
+ }
429
+ }
420
430
  }
421
431
 
422
432
  // src/datasets/client.ts
@@ -624,7 +634,8 @@ class Index extends BaseClient {
624
634
  transactions = {
625
635
  list: (params = {}) => this.listTransactions(params),
626
636
  walk: (params = {}) => this.walkTransactions(params),
627
- get: (txId) => this.getTransaction(txId)
637
+ get: (txId) => this.getTransaction(txId),
638
+ getProof: (txId) => this.getTransactionProof(txId)
628
639
  };
629
640
  stacking = {
630
641
  list: (params = {}) => this.listStacking(params),
@@ -886,6 +897,15 @@ class Index extends BaseClient {
886
897
  throw err;
887
898
  }
888
899
  }
900
+ async getTransactionProof(txId) {
901
+ try {
902
+ return await this.request("GET", `/v1/index/transactions/${encodeURIComponent(txId)}/proof`);
903
+ } catch (err) {
904
+ if (err instanceof ApiError && err.status === 404)
905
+ return null;
906
+ throw err;
907
+ }
908
+ }
889
909
  async* walkTransactions(params = {}) {
890
910
  const batchSize = params.batchSize ?? 200;
891
911
  let cursor = params.cursor ?? params.fromCursor ?? null;
@@ -2249,5 +2269,5 @@ export {
2249
2269
  ApiError
2250
2270
  };
2251
2271
 
2252
- //# debugId=DBAA238399806ED364756E2164756E21
2272
+ //# debugId=AD881ECDD1B046B864756E2164756E21
2253
2273
  //# sourceMappingURL=index.js.map