@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 +101 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +101 -1
- package/dist/index.js.map +1 -1
- package/dist/ws/index.cjs +101 -0
- package/dist/ws/index.cjs.map +1 -1
- package/dist/ws/index.d.cts +76 -2
- package/dist/ws/index.d.ts +76 -2
- package/dist/ws/index.js +101 -1
- package/dist/ws/index.js.map +1 -1
- package/package.json +1 -1
- package/src/ws/client.ts +78 -3
- package/src/ws/decoder.ts +56 -1
- package/src/ws/index.ts +6 -1
- package/src/ws/types.ts +49 -0
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
|