@k256/sdk 0.4.0 → 0.5.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.cjs CHANGED
@@ -111,6 +111,16 @@ var MessageType = {
111
111
  PoolUpdateBatch: 14,
112
112
  /** Block-level statistics (v3) */
113
113
  BlockStats: 15,
114
+ /** Subscribe to price updates (JSON) - Client → Server */
115
+ SubscribePrice: 16,
116
+ /** Single price update (bincode 56B) - Server → Client */
117
+ PriceUpdate: 17,
118
+ /** Batched price updates (bincode [u16 count][entries...]) - Server → Client */
119
+ PriceBatch: 18,
120
+ /** Initial price snapshot (same binary format as PriceBatch) - Server → Client */
121
+ PriceSnapshot: 19,
122
+ /** Unsubscribe from prices (no payload) - Client → Server */
123
+ UnsubscribePrice: 20,
114
124
  /** Error message (UTF-8 string) */
115
125
  Error: 255
116
126
  };
@@ -309,10 +319,48 @@ function decodeMessage(data) {
309
319
  receivedAt: Date.now()
310
320
  };
311
321
  }
322
+ case MessageType.PriceUpdate: {
323
+ if (payload.byteLength < 56) return null;
324
+ const mintBytes = new Uint8Array(payload, 0, 32);
325
+ return {
326
+ type: "price_update",
327
+ data: {
328
+ mint: base58Encode(mintBytes),
329
+ usdPrice: Number(payloadView.getBigUint64(32, true)) / 1e12,
330
+ slot: Number(payloadView.getBigUint64(40, true)),
331
+ timestampMs: Number(payloadView.getBigUint64(48, true))
332
+ }
333
+ };
334
+ }
335
+ case MessageType.PriceBatch:
336
+ case MessageType.PriceSnapshot: {
337
+ if (payload.byteLength < 2) return null;
338
+ const entries = decodePriceEntries(payload);
339
+ const priceType = msgType === MessageType.PriceSnapshot ? "price_snapshot" : "price_batch";
340
+ return { type: priceType, data: entries };
341
+ }
312
342
  default:
313
343
  return null;
314
344
  }
315
345
  }
346
+ function decodePriceEntries(payload) {
347
+ const view = new DataView(payload);
348
+ if (payload.byteLength < 2) return [];
349
+ const count = view.getUint16(0, true);
350
+ const entries = [];
351
+ let offset = 2;
352
+ for (let i = 0; i < count && offset + 56 <= payload.byteLength; i++) {
353
+ const mintBytes = new Uint8Array(payload, offset, 32);
354
+ entries.push({
355
+ mint: base58Encode(mintBytes),
356
+ usdPrice: Number(view.getBigUint64(offset + 32, true)) / 1e12,
357
+ slot: Number(view.getBigUint64(offset + 40, true)),
358
+ timestampMs: Number(view.getBigUint64(offset + 48, true))
359
+ });
360
+ offset += 56;
361
+ }
362
+ return entries;
363
+ }
316
364
  function decodePoolUpdateBatch(payload) {
317
365
  const view = new DataView(payload);
318
366
  if (payload.byteLength < 2) return [];
@@ -535,6 +583,7 @@ var K256WebSocketClient = class {
535
583
  lastHeartbeatTime = 0;
536
584
  pendingSubscription = null;
537
585
  pendingQuoteSubscription = null;
586
+ pendingPriceSubscription = null;
538
587
  isIntentionallyClosed = false;
539
588
  /** Current connection state */
540
589
  get state() {
@@ -624,12 +673,33 @@ var K256WebSocketClient = class {
624
673
  const msg = JSON.stringify({ type: "unsubscribe_quote", topicId });
625
674
  this.ws?.send(msg);
626
675
  }
676
+ /**
677
+ * Subscribe to real-time price updates
678
+ * @param options - Token mints and threshold configuration
679
+ */
680
+ subscribePrices(options) {
681
+ this.pendingPriceSubscription = options;
682
+ if (!this.isConnected) {
683
+ return;
684
+ }
685
+ this.sendPriceSubscription(options);
686
+ }
687
+ /**
688
+ * Unsubscribe from price updates
689
+ */
690
+ unsubscribePrices() {
691
+ this.pendingPriceSubscription = null;
692
+ if (!this.isConnected) return;
693
+ const buf = new Uint8Array([MessageType.UnsubscribePrice]);
694
+ this.ws?.send(buf);
695
+ }
627
696
  /**
628
697
  * Unsubscribe from all channels
629
698
  */
630
699
  unsubscribe() {
631
700
  this.pendingSubscription = null;
632
701
  this.pendingQuoteSubscription = null;
702
+ this.pendingPriceSubscription = null;
633
703
  if (!this.isConnected) return;
634
704
  this.ws?.send(JSON.stringify({ type: "unsubscribe" }));
635
705
  }
@@ -680,6 +750,9 @@ var K256WebSocketClient = class {
680
750
  if (this.pendingQuoteSubscription) {
681
751
  this.sendQuoteSubscription(this.pendingQuoteSubscription);
682
752
  }
753
+ if (this.pendingPriceSubscription) {
754
+ this.sendPriceSubscription(this.pendingPriceSubscription);
755
+ }
683
756
  this.config.onConnect?.();
684
757
  resolve();
685
758
  };
@@ -779,6 +852,21 @@ var K256WebSocketClient = class {
779
852
  case "quote_subscribed":
780
853
  this.config.onQuoteSubscribed?.(decoded);
781
854
  break;
855
+ case "price_update":
856
+ this.config.onPriceUpdate?.(decoded);
857
+ break;
858
+ case "price_batch":
859
+ this.config.onPriceBatch?.(decoded);
860
+ for (const entry of decoded.data) {
861
+ this.config.onPriceUpdate?.({ type: "price_update", data: entry });
862
+ }
863
+ break;
864
+ case "price_snapshot":
865
+ this.config.onPriceSnapshot?.(decoded);
866
+ for (const entry of decoded.data) {
867
+ this.config.onPriceUpdate?.({ type: "price_update", data: entry });
868
+ }
869
+ break;
782
870
  case "heartbeat":
783
871
  this.lastHeartbeatTime = Date.now();
784
872
  this.resetHeartbeatTimeout();
@@ -839,6 +927,18 @@ var K256WebSocketClient = class {
839
927
  };
840
928
  this.ws?.send(JSON.stringify(msg));
841
929
  }
930
+ sendPriceSubscription(options) {
931
+ const json = JSON.stringify({
932
+ tokens: options.tokens,
933
+ thresholdBps: options.thresholdBps ?? 10
934
+ });
935
+ const encoder = new TextEncoder();
936
+ const jsonBytes = encoder.encode(json);
937
+ const buf = new Uint8Array(1 + jsonBytes.length);
938
+ buf[0] = MessageType.SubscribePrice;
939
+ buf.set(jsonBytes, 1);
940
+ this.ws?.send(buf);
941
+ }
842
942
  setState(state) {
843
943
  if (this._state !== state) {
844
944
  const prevState = this._state;
@@ -1512,6 +1612,7 @@ exports.base58Encode = base58Encode;
1512
1612
  exports.decodeLeaderMessage = decodeLeaderMessage;
1513
1613
  exports.decodeMessage = decodeMessage;
1514
1614
  exports.decodePoolUpdateBatch = decodePoolUpdateBatch;
1615
+ exports.decodePriceEntries = decodePriceEntries;
1515
1616
  exports.isValidPubkey = isValidPubkey;
1516
1617
  //# sourceMappingURL=index.cjs.map
1517
1618
  //# sourceMappingURL=index.cjs.map