@secondlayer/sdk 6.35.0 → 6.36.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
@@ -29,6 +29,7 @@ declare abstract class BaseClient {
29
29
  protected baseUrl: string;
30
30
  protected apiKey?: string;
31
31
  protected origin: "cli" | "mcp" | "session";
32
+ protected fetchImpl: FetchLike;
32
33
  constructor(options?: Partial<SecondLayerOptions>);
33
34
  static authHeaders(apiKey?: string): Record<string, string>;
34
35
  protected request<T>(method: string, path: string, body?: unknown): Promise<T>;
package/dist/index.js CHANGED
@@ -66,10 +66,12 @@ class BaseClient {
66
66
  baseUrl;
67
67
  apiKey;
68
68
  origin;
69
+ fetchImpl;
69
70
  constructor(options = {}) {
70
71
  this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
71
72
  this.apiKey = resolveApiKey(options.apiKey);
72
73
  this.origin = options.origin ?? "cli";
74
+ this.fetchImpl = options.fetchImpl ?? ((...args) => fetch(...args));
73
75
  }
74
76
  static authHeaders(apiKey) {
75
77
  const headers = {
@@ -115,7 +117,7 @@ class BaseClient {
115
117
  }
116
118
  let response;
117
119
  try {
118
- response = await fetch(url, {
120
+ response = await this.fetchImpl(url, {
119
121
  method,
120
122
  headers,
121
123
  body: serializedBody
@@ -494,6 +496,19 @@ var Cursor = {
494
496
  function reorgKey(reorg) {
495
497
  return `${reorg.detected_at}|${reorg.fork_point_height}|${reorg.new_canonical_tip}`;
496
498
  }
499
+ function assertFinalizedCheckpoint(returned, checkpoint) {
500
+ if (returned === null || returned === undefined)
501
+ return;
502
+ if (returned === checkpoint)
503
+ return;
504
+ const r = Cursor.parse(returned);
505
+ const c = checkpoint === null ? null : Cursor.parse(checkpoint);
506
+ const above = c === null || r.blockHeight > c.blockHeight || r.blockHeight === c.blockHeight && r.eventIndex > c.eventIndex;
507
+ if (above) {
508
+ const boundary = c ? ` ("${checkpoint}")` : " (none delivered yet)";
509
+ throw new ValidationError(`onBatch returned cursor "${returned}", above the last delivered finalized event${boundary}. With finalizedOnly, events past that point were filtered out and will be re-read once finalized — committing beyond it skips them permanently. Return ctx.cursor (or nothing); never envelope.next_cursor.`, 400);
510
+ }
511
+ }
497
512
  function batchContext(cursor, height, tipHeight) {
498
513
  return {
499
514
  cursor,
@@ -558,6 +573,8 @@ async function consumeStreamsEvents(opts) {
558
573
  const checkpoint = finalizedOnly ? emitted.at(-1)?.cursor ?? cursor : envelope.next_cursor;
559
574
  height = emitted.at(-1)?.block_height ?? height;
560
575
  const returnedCursor = await opts.onBatch(emitted, envelope, batchContext(checkpoint, height, envelope.tip.block_height));
576
+ if (finalizedOnly)
577
+ assertFinalizedCheckpoint(returnedCursor, checkpoint);
561
578
  const nextCursor = returnedCursor ?? checkpoint;
562
579
  if (nextCursor && nextCursor !== cursor) {
563
580
  cursor = nextCursor;
@@ -691,6 +708,8 @@ async function consumeIndexFeed(opts) {
691
708
  const checkpoint = finalizedOnly ? emitted.at(-1)?.cursor ?? cursor : envelope.next_cursor;
692
709
  height = emitted.at(-1)?.block_height ?? height;
693
710
  const returnedCursor = await opts.onBatch(emitted, envelope, batchContext(checkpoint, height, envelope.tip.block_height));
711
+ if (finalizedOnly)
712
+ assertFinalizedCheckpoint(returnedCursor, checkpoint);
694
713
  const nextCursor = returnedCursor ?? checkpoint;
695
714
  if (nextCursor && nextCursor !== cursor) {
696
715
  cursor = nextCursor;
@@ -2094,11 +2113,17 @@ class X402SpendGuardError extends Error {
2094
2113
  }
2095
2114
  }
2096
2115
  function b64encode(value) {
2097
- return Buffer.from(JSON.stringify(value), "utf8").toString("base64");
2116
+ const utf8 = new TextEncoder().encode(JSON.stringify(value));
2117
+ let binary = "";
2118
+ for (const byte of utf8)
2119
+ binary += String.fromCharCode(byte);
2120
+ return btoa(binary);
2098
2121
  }
2099
2122
  function b64decodeJson(value) {
2100
2123
  try {
2101
- return JSON.parse(Buffer.from(value, "base64").toString("utf8"));
2124
+ const binary = atob(value);
2125
+ const utf8 = Uint8Array.from(binary, (ch) => ch.charCodeAt(0));
2126
+ return JSON.parse(new TextDecoder().decode(utf8));
2102
2127
  } catch {
2103
2128
  return null;
2104
2129
  }
@@ -2368,8 +2393,9 @@ import {
2368
2393
  stacksTxid,
2369
2394
  verifyTxMerkleProof
2370
2395
  } from "@secondlayer/shared/node/nakamoto";
2396
+ import { hexToBytes } from "@secondlayer/stacks/utils";
2371
2397
  var strip = (h) => h.startsWith("0x") ? h.slice(2) : h;
2372
- var bytes = (h) => Uint8Array.from(Buffer.from(strip(h), "hex"));
2398
+ var bytes = (h) => hexToBytes(h);
2373
2399
  async function fetchRewardSet(opts) {
2374
2400
  const f = opts.fetchImpl ?? fetch;
2375
2401
  const res = await f(`${opts.nodeUrl.replace(/\/+$/, "")}/v3/stacker_set/${opts.cycle}`);
@@ -2496,5 +2522,5 @@ export {
2496
2522
  ApiError
2497
2523
  };
2498
2524
 
2499
- //# debugId=D5B171025CDFC80A64756E2164756E21
2525
+ //# debugId=7D05343D5E23B9E764756E2164756E21
2500
2526
  //# sourceMappingURL=index.js.map