@secondlayer/sdk 6.0.0 → 6.2.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.
@@ -1,7 +1,205 @@
1
1
  // src/streams/client.ts
2
2
  import { ed25519 } from "@secondlayer/shared";
3
3
 
4
+ // src/errors.ts
5
+ class ApiError extends Error {
6
+ status;
7
+ body;
8
+ code;
9
+ constructor(status, message, body, code) {
10
+ super(message);
11
+ this.status = status;
12
+ this.body = body;
13
+ this.code = code;
14
+ this.name = "ApiError";
15
+ }
16
+ }
17
+
18
+ class VersionConflictError extends ApiError {
19
+ currentVersion;
20
+ expectedVersion;
21
+ constructor(currentVersion, expectedVersion, message = `Version conflict: expected ${expectedVersion}, current ${currentVersion}`) {
22
+ super(409, message, { currentVersion, expectedVersion });
23
+ this.currentVersion = currentVersion;
24
+ this.expectedVersion = expectedVersion;
25
+ this.name = "VersionConflictError";
26
+ }
27
+ }
28
+
29
+ // src/base.ts
30
+ var DEFAULT_BASE_URL = "https://api.secondlayer.tools";
31
+ function buildQuery(params) {
32
+ const search = new URLSearchParams;
33
+ for (const [name, value] of Object.entries(params)) {
34
+ if (value === undefined || value === null)
35
+ continue;
36
+ const serialized = Array.isArray(value) ? value.join(",") : String(value);
37
+ if (serialized.length === 0)
38
+ continue;
39
+ search.set(name, serialized);
40
+ }
41
+ const query = search.toString();
42
+ return query ? `?${query}` : "";
43
+ }
44
+
45
+ class BaseClient {
46
+ baseUrl;
47
+ apiKey;
48
+ origin;
49
+ constructor(options = {}) {
50
+ this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
51
+ this.apiKey = options.apiKey;
52
+ this.origin = options.origin ?? "cli";
53
+ }
54
+ static authHeaders(apiKey) {
55
+ const headers = {
56
+ "Content-Type": "application/json"
57
+ };
58
+ if (apiKey) {
59
+ headers.Authorization = `Bearer ${apiKey}`;
60
+ }
61
+ return headers;
62
+ }
63
+ async request(method, path, body) {
64
+ const response = await this.fetchResponse(method, path, body);
65
+ if (response.status === 204) {
66
+ return;
67
+ }
68
+ return response.json();
69
+ }
70
+ async requestText(method, path, body) {
71
+ const response = await this.fetchResponse(method, path, body);
72
+ return response.text();
73
+ }
74
+ async fetchResponse(method, path, body) {
75
+ const url = `${this.baseUrl}${path}`;
76
+ const headers = BaseClient.authHeaders(this.apiKey);
77
+ headers["x-sl-origin"] = this.origin;
78
+ let serializedBody;
79
+ if (body !== undefined && body !== null) {
80
+ try {
81
+ serializedBody = JSON.stringify(body, (_key, value) => typeof value === "bigint" ? value.toString() : value);
82
+ } catch (err) {
83
+ const detail = err instanceof Error ? err.message : String(err);
84
+ throw new ApiError(0, `Failed to serialize request body: ${detail}`);
85
+ }
86
+ }
87
+ let response;
88
+ try {
89
+ response = await fetch(url, {
90
+ method,
91
+ headers,
92
+ body: serializedBody
93
+ });
94
+ } catch {
95
+ throw new ApiError(0, `Cannot reach API at ${this.baseUrl}. Check your connection or try again.`);
96
+ }
97
+ if (!response.ok) {
98
+ if (response.status === 401) {
99
+ throw new ApiError(401, "API key invalid or expired.");
100
+ }
101
+ if (response.status === 429) {
102
+ const retryAfter = response.headers.get("Retry-After");
103
+ const msg = retryAfter ? `Rate limited. Wait ${retryAfter} seconds.` : "Rate limited. Try again later.";
104
+ throw new ApiError(429, msg);
105
+ }
106
+ if (response.status >= 500) {
107
+ throw new ApiError(response.status, `Server error. Try again or check status at ${this.baseUrl}/health`);
108
+ }
109
+ const errorBody = await response.text();
110
+ let message = `HTTP ${response.status}`;
111
+ let parsedBody = errorBody;
112
+ let code;
113
+ try {
114
+ const json = JSON.parse(errorBody);
115
+ parsedBody = json;
116
+ const err = json.error ?? json.message;
117
+ if (typeof err === "string") {
118
+ message = err;
119
+ } else if (err && typeof err === "object") {
120
+ message = JSON.stringify(err);
121
+ }
122
+ if (typeof json.code === "string") {
123
+ code = json.code;
124
+ }
125
+ } catch {
126
+ if (errorBody)
127
+ message = errorBody;
128
+ }
129
+ throw new ApiError(response.status, message, parsedBody, code);
130
+ }
131
+ return response;
132
+ }
133
+ }
134
+
135
+ // src/streams/errors.ts
136
+ class AuthError extends Error {
137
+ status = 401;
138
+ constructor(message = "API key invalid or expired.") {
139
+ super(message);
140
+ this.name = "AuthError";
141
+ }
142
+ }
143
+
144
+ class RateLimitError extends Error {
145
+ retryAfter;
146
+ status = 429;
147
+ constructor(message = "Rate limited. Try again later.", retryAfter) {
148
+ super(message);
149
+ this.retryAfter = retryAfter;
150
+ this.name = "RateLimitError";
151
+ }
152
+ }
153
+
154
+ class ValidationError extends Error {
155
+ status;
156
+ body;
157
+ constructor(message, status, body) {
158
+ super(message);
159
+ this.status = status;
160
+ this.body = body;
161
+ this.name = "ValidationError";
162
+ }
163
+ }
164
+
165
+ class StreamsServerError extends Error {
166
+ status;
167
+ body;
168
+ constructor(message, status, body) {
169
+ super(message);
170
+ this.status = status;
171
+ this.body = body;
172
+ this.name = "StreamsServerError";
173
+ }
174
+ }
175
+
176
+ class StreamsSignatureError extends Error {
177
+ constructor(message = "Streams response signature verification failed.") {
178
+ super(message);
179
+ this.name = "StreamsSignatureError";
180
+ }
181
+ }
182
+
183
+ // src/streams/cursor.ts
184
+ var Cursor = {
185
+ atHeight(height) {
186
+ return `${height}:0`;
187
+ },
188
+ parse(cursor) {
189
+ const parts = cursor.split(":");
190
+ const blockHeight = Number(parts[0]);
191
+ const eventIndex = Number(parts[1]);
192
+ if (parts.length !== 2 || !Number.isInteger(blockHeight) || !Number.isInteger(eventIndex)) {
193
+ throw new ValidationError(`Invalid stream cursor "${cursor}"; expected "<block>:<index>" (e.g. "951475:3").`, 400);
194
+ }
195
+ return { blockHeight, eventIndex };
196
+ }
197
+ };
198
+
4
199
  // src/streams/consumer.ts
200
+ function reorgKey(reorg) {
201
+ return `${reorg.detected_at}|${reorg.fork_point_height}|${reorg.new_canonical_tip}`;
202
+ }
5
203
  async function defaultSleep(ms, signal) {
6
204
  if (signal?.aborted)
7
205
  return;
@@ -18,10 +216,12 @@ async function defaultSleep(ms, signal) {
18
216
  async function consumeStreamsEvents(opts) {
19
217
  const sleep = opts.sleep ?? defaultSleep;
20
218
  const mode = opts.mode ?? "tail";
219
+ const finalizedOnly = opts.finalizedOnly ?? false;
21
220
  const emptyBackoffMs = opts.emptyBackoffMs ?? 500;
22
221
  const maxPages = opts.maxPages ?? Number.POSITIVE_INFINITY;
23
222
  const maxEmptyPolls = opts.maxEmptyPolls ?? Number.POSITIVE_INFINITY;
24
223
  let cursor = opts.fromCursor ?? null;
224
+ const handledReorgs = new Set;
25
225
  let pages = 0;
26
226
  let emptyPolls = 0;
27
227
  while (pages < maxPages && emptyPolls < maxEmptyPolls && !opts.signal?.aborted) {
@@ -36,14 +236,32 @@ async function consumeStreamsEvents(opts) {
36
236
  assetIdentifier: opts.assetIdentifier
37
237
  });
38
238
  pages++;
39
- const returnedCursor = await opts.onBatch(envelope.events, envelope);
40
- const nextCursor = returnedCursor ?? envelope.next_cursor;
239
+ if (!finalizedOnly && opts.onReorg) {
240
+ const fresh = envelope.reorgs.filter((reorg) => !handledReorgs.has(reorgKey(reorg))).sort((a, b) => a.fork_point_height - b.fork_point_height);
241
+ if (fresh.length > 0) {
242
+ const forkPoint = Math.min(...fresh.map((reorg) => reorg.fork_point_height));
243
+ const rewind = Cursor.atHeight(forkPoint);
244
+ for (const reorg of fresh) {
245
+ await opts.onReorg(reorg, { cursor: rewind });
246
+ handledReorgs.add(reorgKey(reorg));
247
+ }
248
+ cursor = rewind;
249
+ emptyPolls = 0;
250
+ continue;
251
+ }
252
+ }
253
+ const emitted = finalizedOnly ? envelope.events.filter((event) => event.finalized) : envelope.events;
254
+ const checkpoint = finalizedOnly ? emitted.at(-1)?.cursor ?? cursor : envelope.next_cursor;
255
+ const returnedCursor = await opts.onBatch(emitted, envelope, {
256
+ cursor: checkpoint
257
+ });
258
+ const nextCursor = returnedCursor ?? checkpoint;
41
259
  if (nextCursor && nextCursor !== cursor) {
42
260
  cursor = nextCursor;
43
261
  emptyPolls = 0;
44
262
  continue;
45
263
  }
46
- if (envelope.events.length === 0) {
264
+ if (emitted.length === 0) {
47
265
  emptyPolls++;
48
266
  if (mode === "bounded") {
49
267
  return { cursor, pages, emptyPolls };
@@ -99,56 +317,6 @@ async function* streamStreamsEvents(opts) {
99
317
 
100
318
  // src/streams/dumps.ts
101
319
  import { createHash } from "node:crypto";
102
-
103
- // src/streams/errors.ts
104
- class AuthError extends Error {
105
- status = 401;
106
- constructor(message = "API key invalid or expired.") {
107
- super(message);
108
- this.name = "AuthError";
109
- }
110
- }
111
-
112
- class RateLimitError extends Error {
113
- retryAfter;
114
- status = 429;
115
- constructor(message = "Rate limited. Try again later.", retryAfter) {
116
- super(message);
117
- this.retryAfter = retryAfter;
118
- this.name = "RateLimitError";
119
- }
120
- }
121
-
122
- class ValidationError extends Error {
123
- status;
124
- body;
125
- constructor(message, status, body) {
126
- super(message);
127
- this.status = status;
128
- this.body = body;
129
- this.name = "ValidationError";
130
- }
131
- }
132
-
133
- class StreamsServerError extends Error {
134
- status;
135
- body;
136
- constructor(message, status, body) {
137
- super(message);
138
- this.status = status;
139
- this.body = body;
140
- this.name = "StreamsServerError";
141
- }
142
- }
143
-
144
- class StreamsSignatureError extends Error {
145
- constructor(message = "Streams response signature verification failed.") {
146
- super(message);
147
- this.name = "StreamsSignatureError";
148
- }
149
- }
150
-
151
- // src/streams/dumps.ts
152
320
  function createStreamsDumps(opts) {
153
321
  const baseUrl = opts.baseUrl?.replace(/\/+$/, "");
154
322
  function requireBaseUrl() {
@@ -187,8 +355,12 @@ function createStreamsDumps(opts) {
187
355
  function cursorTuple(cursor) {
188
356
  if (!cursor)
189
357
  return [-1, -1];
190
- const [block, index] = cursor.split(":");
191
- return [Number(block), Number(index)];
358
+ const parts = cursor.split(":");
359
+ const [block, index] = parts.map(Number);
360
+ if (parts.length !== 2 || !Number.isInteger(block) || !Number.isInteger(index)) {
361
+ throw new ValidationError(`Invalid stream cursor "${cursor}"; expected "<block>:<index>" (e.g. "951475:3").`, 400);
362
+ }
363
+ return [block, index];
192
364
  }
193
365
  function maxCursor(a, b) {
194
366
  const [ah, ai] = cursorTuple(a);
@@ -199,18 +371,6 @@ var DEFAULT_STREAMS_BASE_URL = "https://api.secondlayer.tools";
199
371
  function normalizeBaseUrl(baseUrl) {
200
372
  return baseUrl.replace(/\/+$/, "");
201
373
  }
202
- function appendSearchParam(params, name, value) {
203
- if (value === undefined || value === null)
204
- return;
205
- params.set(name, String(value));
206
- }
207
- function appendListParam(params, name, value) {
208
- if (value === undefined || value === null)
209
- return;
210
- const joined = Array.isArray(value) ? value.join(",") : value;
211
- if (joined.length > 0)
212
- params.set(name, joined);
213
- }
214
374
  async function responseBody(response) {
215
375
  const text = await response.text();
216
376
  if (text.length === 0)
@@ -332,23 +492,18 @@ function createStreamsClient(options) {
332
492
  });
333
493
  };
334
494
  async function listEvents(params = {}) {
335
- const searchParams = new URLSearchParams;
336
- appendSearchParam(searchParams, "cursor", params.cursor);
337
- appendSearchParam(searchParams, "from_height", params.fromHeight);
338
- appendSearchParam(searchParams, "to_height", params.toHeight);
339
- appendSearchParam(searchParams, "limit", params.limit);
340
- appendListParam(searchParams, "contract_id", params.contractId);
341
- appendListParam(searchParams, "sender", params.sender);
342
- appendListParam(searchParams, "recipient", params.recipient);
343
- appendSearchParam(searchParams, "asset_identifier", params.assetIdentifier);
344
- if (params.types?.length) {
345
- searchParams.set("types", params.types.join(","));
346
- }
347
- if (params.notTypes?.length) {
348
- searchParams.set("not_types", params.notTypes.join(","));
349
- }
350
- const query = searchParams.toString();
351
- return request(`/v1/streams/events${query ? `?${query}` : ""}`);
495
+ return request(`/v1/streams/events${buildQuery({
496
+ cursor: params.cursor,
497
+ from_height: params.fromHeight,
498
+ to_height: params.toHeight,
499
+ limit: params.limit,
500
+ contract_id: params.contractId,
501
+ sender: params.sender,
502
+ recipient: params.recipient,
503
+ asset_identifier: params.assetIdentifier,
504
+ types: params.types,
505
+ not_types: params.notTypes
506
+ })}`);
352
507
  }
353
508
  return {
354
509
  events: {
@@ -360,6 +515,7 @@ function createStreamsClient(options) {
360
515
  return consumeStreamsEvents({
361
516
  fromCursor: params.fromCursor,
362
517
  mode: params.mode,
518
+ finalizedOnly: params.finalizedOnly,
363
519
  types: params.types,
364
520
  notTypes: params.notTypes,
365
521
  contractId: params.contractId,
@@ -369,6 +525,7 @@ function createStreamsClient(options) {
369
525
  batchSize: params.batchSize ?? 100,
370
526
  fetchEvents,
371
527
  onBatch: params.onBatch,
528
+ onReorg: params.onReorg,
372
529
  emptyBackoffMs: params.emptyBackoffMs,
373
530
  maxPages: params.maxPages,
374
531
  maxEmptyPolls: params.maxEmptyPolls,
@@ -423,11 +580,10 @@ function createStreamsClient(options) {
423
580
  },
424
581
  reorgs: {
425
582
  list(params) {
426
- const searchParams = new URLSearchParams;
427
- appendSearchParam(searchParams, "since", params.since);
428
- appendSearchParam(searchParams, "limit", params.limit);
429
- const query = searchParams.toString();
430
- return request(`/v1/streams/reorgs${query ? `?${query}` : ""}`);
583
+ return request(`/v1/streams/reorgs${buildQuery({
584
+ since: params.since,
585
+ limit: params.limit
586
+ })}`);
431
587
  }
432
588
  },
433
589
  dumps,
@@ -439,127 +595,8 @@ function createStreamsClient(options) {
439
595
  }
440
596
  };
441
597
  }
442
- // src/streams/ft-transfer.ts
443
- function requireString(payload, field) {
444
- const value = payload[field];
445
- if (typeof value !== "string" || value.length === 0) {
446
- throw new Error(`ft_transfer payload missing ${field}`);
447
- }
448
- return value;
449
- }
450
- function parseAssetIdentifier(assetIdentifier) {
451
- const [contractId, tokenName] = assetIdentifier.split("::");
452
- if (!contractId) {
453
- throw new Error("ft_transfer payload has malformed asset_identifier");
454
- }
455
- return {
456
- contract_id: contractId,
457
- token_name: tokenName && tokenName.length > 0 ? tokenName : null
458
- };
459
- }
460
- function isFtTransfer(event) {
461
- return event.event_type === "ft_transfer";
462
- }
463
- function decodeFtTransfer(event) {
464
- if (!isFtTransfer(event)) {
465
- throw new Error(`Expected ft_transfer event, got ${event.event_type}`);
466
- }
467
- const payload = event.payload;
468
- const assetIdentifier = requireString(payload, "asset_identifier");
469
- const sender = requireString(payload, "sender");
470
- const recipient = requireString(payload, "recipient");
471
- const amount = requireString(payload, "amount");
472
- if (!/^(0|[1-9]\d*)$/.test(amount)) {
473
- throw new Error("ft_transfer payload has malformed amount");
474
- }
475
- const { contract_id, token_name } = parseAssetIdentifier(assetIdentifier);
476
- return {
477
- cursor: event.cursor,
478
- block_height: event.block_height,
479
- tx_id: event.tx_id,
480
- tx_index: event.tx_index,
481
- event_index: event.event_index,
482
- event_type: event.event_type,
483
- decoded_payload: {
484
- asset_identifier: assetIdentifier,
485
- contract_id: event.contract_id ?? contract_id,
486
- token_name,
487
- sender,
488
- recipient,
489
- amount
490
- },
491
- source_cursor: event.cursor
492
- };
493
- }
494
- // src/streams/nft-transfer.ts
495
- function requireString2(payload, field) {
496
- const value = payload[field];
497
- if (typeof value !== "string" || value.length === 0) {
498
- throw new Error(`nft_transfer payload missing ${field}`);
499
- }
500
- return value;
501
- }
502
- function requireHexValue(payload) {
503
- const rawValue = payload.raw_value;
504
- if (typeof rawValue === "string") {
505
- if (!/^0x[0-9a-fA-F]*$/.test(rawValue)) {
506
- throw new Error("nft_transfer payload has malformed value");
507
- }
508
- return rawValue;
509
- }
510
- const value = payload.value;
511
- const hex = typeof value === "string" ? value : value && typeof value === "object" && typeof value.hex === "string" ? value.hex : null;
512
- if (!hex) {
513
- throw new Error("nft_transfer payload missing value");
514
- }
515
- if (!/^0x[0-9a-fA-F]*$/.test(hex)) {
516
- throw new Error("nft_transfer payload has malformed value");
517
- }
518
- return hex;
519
- }
520
- function parseAssetIdentifier2(assetIdentifier) {
521
- const [contractId, tokenName] = assetIdentifier.split("::");
522
- if (!contractId) {
523
- throw new Error("nft_transfer payload has malformed asset_identifier");
524
- }
525
- return {
526
- contract_id: contractId,
527
- token_name: tokenName && tokenName.length > 0 ? tokenName : null
528
- };
529
- }
530
- function isNftTransfer(event) {
531
- return event.event_type === "nft_transfer";
532
- }
533
- function decodeNftTransfer(event) {
534
- if (!isNftTransfer(event)) {
535
- throw new Error(`Expected nft_transfer event, got ${event.event_type}`);
536
- }
537
- const payload = event.payload;
538
- const assetIdentifier = requireString2(payload, "asset_identifier");
539
- const sender = requireString2(payload, "sender");
540
- const recipient = requireString2(payload, "recipient");
541
- const value = requireHexValue(payload);
542
- const { contract_id, token_name } = parseAssetIdentifier2(assetIdentifier);
543
- return {
544
- cursor: event.cursor,
545
- block_height: event.block_height,
546
- tx_id: event.tx_id,
547
- tx_index: event.tx_index,
548
- event_index: event.event_index,
549
- event_type: event.event_type,
550
- decoded_payload: {
551
- asset_identifier: assetIdentifier,
552
- contract_id: event.contract_id ?? contract_id,
553
- token_name,
554
- sender,
555
- recipient,
556
- value
557
- },
558
- source_cursor: event.cursor
559
- };
560
- }
561
598
  // src/streams/_payload.ts
562
- function requireString3(payload, field, eventType) {
599
+ function requireString(payload, field, eventType) {
563
600
  const value = payload[field];
564
601
  if (typeof value !== "string" || value.length === 0) {
565
602
  throw new Error(`${eventType} payload missing ${field}`);
@@ -570,7 +607,7 @@ function optionalString(value) {
570
607
  return typeof value === "string" && value.length > 0 ? value : null;
571
608
  }
572
609
  function requireAmountField(payload, field, eventType) {
573
- const amount = requireString3(payload, field, eventType);
610
+ const amount = requireString(payload, field, eventType);
574
611
  if (!/^(0|[1-9]\d*)$/.test(amount)) {
575
612
  throw new Error(`${eventType} payload has malformed ${field}`);
576
613
  }
@@ -579,7 +616,7 @@ function requireAmountField(payload, field, eventType) {
579
616
  function requireAmount(payload, eventType) {
580
617
  return requireAmountField(payload, "amount", eventType);
581
618
  }
582
- function parseAssetIdentifier3(assetIdentifier, eventType) {
619
+ function parseAssetIdentifier(assetIdentifier, eventType) {
583
620
  const [contractId, tokenName] = assetIdentifier.split("::");
584
621
  if (!contractId) {
585
622
  throw new Error(`${eventType} payload has malformed asset_identifier`);
@@ -589,7 +626,7 @@ function parseAssetIdentifier3(assetIdentifier, eventType) {
589
626
  token_name: tokenName && tokenName.length > 0 ? tokenName : null
590
627
  };
591
628
  }
592
- function requireHexValue2(payload, eventType) {
629
+ function requireHexValue(payload, eventType) {
593
630
  const rawValue = payload.raw_value;
594
631
  if (typeof rawValue === "string") {
595
632
  if (!/^0x[0-9a-fA-F]*$/.test(rawValue)) {
@@ -620,6 +657,52 @@ function decodedRow(event, eventType, decoded_payload) {
620
657
  };
621
658
  }
622
659
 
660
+ // src/streams/ft-transfer.ts
661
+ function isFtTransfer(event) {
662
+ return event.event_type === "ft_transfer";
663
+ }
664
+ function decodeFtTransfer(event) {
665
+ if (!isFtTransfer(event)) {
666
+ throw new Error(`Expected ft_transfer event, got ${event.event_type}`);
667
+ }
668
+ const payload = event.payload;
669
+ const assetIdentifier = requireString(payload, "asset_identifier", "ft_transfer");
670
+ const sender = requireString(payload, "sender", "ft_transfer");
671
+ const recipient = requireString(payload, "recipient", "ft_transfer");
672
+ const amount = requireAmount(payload, "ft_transfer");
673
+ const { contract_id, token_name } = parseAssetIdentifier(assetIdentifier, "ft_transfer");
674
+ return decodedRow(event, "ft_transfer", {
675
+ asset_identifier: assetIdentifier,
676
+ contract_id: event.contract_id ?? contract_id,
677
+ token_name,
678
+ sender,
679
+ recipient,
680
+ amount
681
+ });
682
+ }
683
+ // src/streams/nft-transfer.ts
684
+ function isNftTransfer(event) {
685
+ return event.event_type === "nft_transfer";
686
+ }
687
+ function decodeNftTransfer(event) {
688
+ if (!isNftTransfer(event)) {
689
+ throw new Error(`Expected nft_transfer event, got ${event.event_type}`);
690
+ }
691
+ const payload = event.payload;
692
+ const assetIdentifier = requireString(payload, "asset_identifier", "nft_transfer");
693
+ const sender = requireString(payload, "sender", "nft_transfer");
694
+ const recipient = requireString(payload, "recipient", "nft_transfer");
695
+ const value = requireHexValue(payload, "nft_transfer");
696
+ const { contract_id, token_name } = parseAssetIdentifier(assetIdentifier, "nft_transfer");
697
+ return decodedRow(event, "nft_transfer", {
698
+ asset_identifier: assetIdentifier,
699
+ contract_id: event.contract_id ?? contract_id,
700
+ token_name,
701
+ sender,
702
+ recipient,
703
+ value
704
+ });
705
+ }
623
706
  // src/streams/stx-events.ts
624
707
  function isStxTransfer(event) {
625
708
  return event.event_type === "stx_transfer";
@@ -630,8 +713,8 @@ function decodeStxTransfer(event) {
630
713
  }
631
714
  const payload = event.payload;
632
715
  return decodedRow(event, "stx_transfer", {
633
- sender: requireString3(payload, "sender", "stx_transfer"),
634
- recipient: requireString3(payload, "recipient", "stx_transfer"),
716
+ sender: requireString(payload, "sender", "stx_transfer"),
717
+ recipient: requireString(payload, "recipient", "stx_transfer"),
635
718
  amount: requireAmount(payload, "stx_transfer"),
636
719
  memo: optionalString(payload.memo)
637
720
  });
@@ -645,7 +728,7 @@ function decodeStxMint(event) {
645
728
  }
646
729
  const payload = event.payload;
647
730
  return decodedRow(event, "stx_mint", {
648
- recipient: requireString3(payload, "recipient", "stx_mint"),
731
+ recipient: requireString(payload, "recipient", "stx_mint"),
649
732
  amount: requireAmount(payload, "stx_mint")
650
733
  });
651
734
  }
@@ -658,7 +741,7 @@ function decodeStxBurn(event) {
658
741
  }
659
742
  const payload = event.payload;
660
743
  return decodedRow(event, "stx_burn", {
661
- sender: requireString3(payload, "sender", "stx_burn"),
744
+ sender: requireString(payload, "sender", "stx_burn"),
662
745
  amount: requireAmount(payload, "stx_burn")
663
746
  });
664
747
  }
@@ -671,15 +754,15 @@ function decodeStxLock(event) {
671
754
  }
672
755
  const payload = event.payload;
673
756
  return decodedRow(event, "stx_lock", {
674
- sender: requireString3(payload, "locked_address", "stx_lock"),
757
+ sender: requireString(payload, "locked_address", "stx_lock"),
675
758
  amount: requireAmountField(payload, "locked_amount", "stx_lock"),
676
759
  payload: { unlock_height: optionalString(payload.unlock_height) }
677
760
  });
678
761
  }
679
762
  // src/streams/token-mint-burn.ts
680
763
  function assetFields(event, eventType) {
681
- const assetIdentifier = requireString3(event.payload, "asset_identifier", eventType);
682
- const { contract_id, token_name } = parseAssetIdentifier3(assetIdentifier, eventType);
764
+ const assetIdentifier = requireString(event.payload, "asset_identifier", eventType);
765
+ const { contract_id, token_name } = parseAssetIdentifier(assetIdentifier, eventType);
683
766
  return {
684
767
  asset_identifier: assetIdentifier,
685
768
  contract_id: event.contract_id ?? contract_id,
@@ -695,7 +778,7 @@ function decodeFtMint(event) {
695
778
  }
696
779
  return decodedRow(event, "ft_mint", {
697
780
  ...assetFields(event, "ft_mint"),
698
- recipient: requireString3(event.payload, "recipient", "ft_mint"),
781
+ recipient: requireString(event.payload, "recipient", "ft_mint"),
699
782
  amount: requireAmount(event.payload, "ft_mint")
700
783
  });
701
784
  }
@@ -708,7 +791,7 @@ function decodeFtBurn(event) {
708
791
  }
709
792
  return decodedRow(event, "ft_burn", {
710
793
  ...assetFields(event, "ft_burn"),
711
- sender: requireString3(event.payload, "sender", "ft_burn"),
794
+ sender: requireString(event.payload, "sender", "ft_burn"),
712
795
  amount: requireAmount(event.payload, "ft_burn")
713
796
  });
714
797
  }
@@ -721,8 +804,8 @@ function decodeNftMint(event) {
721
804
  }
722
805
  return decodedRow(event, "nft_mint", {
723
806
  ...assetFields(event, "nft_mint"),
724
- recipient: requireString3(event.payload, "recipient", "nft_mint"),
725
- value: requireHexValue2(event.payload, "nft_mint")
807
+ recipient: requireString(event.payload, "recipient", "nft_mint"),
808
+ value: requireHexValue(event.payload, "nft_mint")
726
809
  });
727
810
  }
728
811
  function isNftBurn(event) {
@@ -734,8 +817,8 @@ function decodeNftBurn(event) {
734
817
  }
735
818
  return decodedRow(event, "nft_burn", {
736
819
  ...assetFields(event, "nft_burn"),
737
- sender: requireString3(event.payload, "sender", "nft_burn"),
738
- value: requireHexValue2(event.payload, "nft_burn")
820
+ sender: requireString(event.payload, "sender", "nft_burn"),
821
+ value: requireHexValue(event.payload, "nft_burn")
739
822
  });
740
823
  }
741
824
  // src/clarity.ts
@@ -834,8 +917,9 @@ export {
834
917
  StreamsServerError,
835
918
  STREAMS_EVENT_TYPES,
836
919
  RateLimitError,
920
+ Cursor,
837
921
  AuthError
838
922
  };
839
923
 
840
- //# debugId=E556011474C772DE64756E2164756E21
924
+ //# debugId=CA2A679BA194AF3B64756E2164756E21
841
925
  //# sourceMappingURL=index.js.map