@k256/sdk 0.3.2 → 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.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- export { BlockStatsMessage, BlockhashMessage, CloseCode, CloseCodeValue, ConnectionState, DecodedMessage, ErrorMessage, FeeMarketMessage, HeartbeatMessage, K256ErrorCode, K256WebSocketClient, K256WebSocketClientConfig, K256WebSocketError, MessageType, MessageTypeValue, PongMessage, PoolUpdateMessage, QuoteMessage, QuoteSubscribedMessage, SubscribeOptions, SubscribeQuoteOptions, SubscribedMessage, decodeMessage, decodePoolUpdateBatch } from './ws/index.cjs';
1
+ export { BlockStatsMessage, BlockhashMessage, CloseCode, CloseCodeValue, ConnectionState, DecodedMessage, ErrorMessage, FeeMarketMessage, HeartbeatMessage, K256ErrorCode, K256WebSocketClient, K256WebSocketClientConfig, K256WebSocketError, MessageType, MessageTypeValue, PongMessage, PoolUpdateMessage, PriceBatchMessage, PriceEntry, PriceSnapshotMessage, PriceUpdateMessage, QuoteMessage, QuoteSubscribedMessage, SubscribeOptions, SubscribePriceOptions, SubscribeQuoteOptions, SubscribedMessage, decodeMessage, decodePoolUpdateBatch, decodePriceEntries } from './ws/index.cjs';
2
2
  export { ALL_LEADER_CHANNELS, GossipDiffMessage, GossipPeer, GossipSnapshotMessage, IpChangeMessage, LeaderChannel, LeaderChannelValue, ConnectionState as LeaderConnectionState, LeaderDecodedMessage, LeaderErrorCode, LeaderErrorMessage, LeaderHeartbeatMessage, LeaderMessageTag, LeaderScheduleMessage, LeaderSubscribedMessage, LeaderWebSocketClient, LeaderWebSocketClientConfig, LeaderWebSocketError, MessageKind, MessageSchemaEntry, RoutingHealthMessage, SkipEventMessage, SlotUpdateMessage, decodeLeaderMessage } from './leader-ws/index.cjs';
3
3
  export { AccountFee, BlockMiniStats, BlockStats, Blockhash, FeeMarket, Heartbeat, NetworkState, OrderLevel, Pool, PoolUpdate, Quote, RoutePlanStep, SubscribeQuoteRequest, SubscribeRequest, Token, TrendDirection } from './types/index.cjs';
4
4
  export { base58Decode, base58Encode, isValidPubkey } from './utils/index.cjs';
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { BlockStatsMessage, BlockhashMessage, CloseCode, CloseCodeValue, ConnectionState, DecodedMessage, ErrorMessage, FeeMarketMessage, HeartbeatMessage, K256ErrorCode, K256WebSocketClient, K256WebSocketClientConfig, K256WebSocketError, MessageType, MessageTypeValue, PongMessage, PoolUpdateMessage, QuoteMessage, QuoteSubscribedMessage, SubscribeOptions, SubscribeQuoteOptions, SubscribedMessage, decodeMessage, decodePoolUpdateBatch } from './ws/index.js';
1
+ export { BlockStatsMessage, BlockhashMessage, CloseCode, CloseCodeValue, ConnectionState, DecodedMessage, ErrorMessage, FeeMarketMessage, HeartbeatMessage, K256ErrorCode, K256WebSocketClient, K256WebSocketClientConfig, K256WebSocketError, MessageType, MessageTypeValue, PongMessage, PoolUpdateMessage, PriceBatchMessage, PriceEntry, PriceSnapshotMessage, PriceUpdateMessage, QuoteMessage, QuoteSubscribedMessage, SubscribeOptions, SubscribePriceOptions, SubscribeQuoteOptions, SubscribedMessage, decodeMessage, decodePoolUpdateBatch, decodePriceEntries } from './ws/index.js';
2
2
  export { ALL_LEADER_CHANNELS, GossipDiffMessage, GossipPeer, GossipSnapshotMessage, IpChangeMessage, LeaderChannel, LeaderChannelValue, ConnectionState as LeaderConnectionState, LeaderDecodedMessage, LeaderErrorCode, LeaderErrorMessage, LeaderHeartbeatMessage, LeaderMessageTag, LeaderScheduleMessage, LeaderSubscribedMessage, LeaderWebSocketClient, LeaderWebSocketClientConfig, LeaderWebSocketError, MessageKind, MessageSchemaEntry, RoutingHealthMessage, SkipEventMessage, SlotUpdateMessage, decodeLeaderMessage } from './leader-ws/index.js';
3
3
  export { AccountFee, BlockMiniStats, BlockStats, Blockhash, FeeMarket, Heartbeat, NetworkState, OrderLevel, Pool, PoolUpdate, Quote, RoutePlanStep, SubscribeQuoteRequest, SubscribeRequest, Token, TrendDirection } from './types/index.js';
4
4
  export { base58Decode, base58Encode, isValidPubkey } from './utils/index.js';
package/dist/index.js CHANGED
@@ -109,6 +109,16 @@ var MessageType = {
109
109
  PoolUpdateBatch: 14,
110
110
  /** Block-level statistics (v3) */
111
111
  BlockStats: 15,
112
+ /** Subscribe to price updates (JSON) - Client → Server */
113
+ SubscribePrice: 16,
114
+ /** Single price update (bincode 56B) - Server → Client */
115
+ PriceUpdate: 17,
116
+ /** Batched price updates (bincode [u16 count][entries...]) - Server → Client */
117
+ PriceBatch: 18,
118
+ /** Initial price snapshot (same binary format as PriceBatch) - Server → Client */
119
+ PriceSnapshot: 19,
120
+ /** Unsubscribe from prices (no payload) - Client → Server */
121
+ UnsubscribePrice: 20,
112
122
  /** Error message (UTF-8 string) */
113
123
  Error: 255
114
124
  };
@@ -307,10 +317,48 @@ function decodeMessage(data) {
307
317
  receivedAt: Date.now()
308
318
  };
309
319
  }
320
+ case MessageType.PriceUpdate: {
321
+ if (payload.byteLength < 56) return null;
322
+ const mintBytes = new Uint8Array(payload, 0, 32);
323
+ return {
324
+ type: "price_update",
325
+ data: {
326
+ mint: base58Encode(mintBytes),
327
+ usdPrice: Number(payloadView.getBigUint64(32, true)) / 1e12,
328
+ slot: Number(payloadView.getBigUint64(40, true)),
329
+ timestampMs: Number(payloadView.getBigUint64(48, true))
330
+ }
331
+ };
332
+ }
333
+ case MessageType.PriceBatch:
334
+ case MessageType.PriceSnapshot: {
335
+ if (payload.byteLength < 2) return null;
336
+ const entries = decodePriceEntries(payload);
337
+ const priceType = msgType === MessageType.PriceSnapshot ? "price_snapshot" : "price_batch";
338
+ return { type: priceType, data: entries };
339
+ }
310
340
  default:
311
341
  return null;
312
342
  }
313
343
  }
344
+ function decodePriceEntries(payload) {
345
+ const view = new DataView(payload);
346
+ if (payload.byteLength < 2) return [];
347
+ const count = view.getUint16(0, true);
348
+ const entries = [];
349
+ let offset = 2;
350
+ for (let i = 0; i < count && offset + 56 <= payload.byteLength; i++) {
351
+ const mintBytes = new Uint8Array(payload, offset, 32);
352
+ entries.push({
353
+ mint: base58Encode(mintBytes),
354
+ usdPrice: Number(view.getBigUint64(offset + 32, true)) / 1e12,
355
+ slot: Number(view.getBigUint64(offset + 40, true)),
356
+ timestampMs: Number(view.getBigUint64(offset + 48, true))
357
+ });
358
+ offset += 56;
359
+ }
360
+ return entries;
361
+ }
314
362
  function decodePoolUpdateBatch(payload) {
315
363
  const view = new DataView(payload);
316
364
  if (payload.byteLength < 2) return [];
@@ -533,6 +581,7 @@ var K256WebSocketClient = class {
533
581
  lastHeartbeatTime = 0;
534
582
  pendingSubscription = null;
535
583
  pendingQuoteSubscription = null;
584
+ pendingPriceSubscription = null;
536
585
  isIntentionallyClosed = false;
537
586
  /** Current connection state */
538
587
  get state() {
@@ -622,12 +671,33 @@ var K256WebSocketClient = class {
622
671
  const msg = JSON.stringify({ type: "unsubscribe_quote", topicId });
623
672
  this.ws?.send(msg);
624
673
  }
674
+ /**
675
+ * Subscribe to real-time price updates
676
+ * @param options - Token mints and threshold configuration
677
+ */
678
+ subscribePrices(options) {
679
+ this.pendingPriceSubscription = options;
680
+ if (!this.isConnected) {
681
+ return;
682
+ }
683
+ this.sendPriceSubscription(options);
684
+ }
685
+ /**
686
+ * Unsubscribe from price updates
687
+ */
688
+ unsubscribePrices() {
689
+ this.pendingPriceSubscription = null;
690
+ if (!this.isConnected) return;
691
+ const buf = new Uint8Array([MessageType.UnsubscribePrice]);
692
+ this.ws?.send(buf);
693
+ }
625
694
  /**
626
695
  * Unsubscribe from all channels
627
696
  */
628
697
  unsubscribe() {
629
698
  this.pendingSubscription = null;
630
699
  this.pendingQuoteSubscription = null;
700
+ this.pendingPriceSubscription = null;
631
701
  if (!this.isConnected) return;
632
702
  this.ws?.send(JSON.stringify({ type: "unsubscribe" }));
633
703
  }
@@ -678,6 +748,9 @@ var K256WebSocketClient = class {
678
748
  if (this.pendingQuoteSubscription) {
679
749
  this.sendQuoteSubscription(this.pendingQuoteSubscription);
680
750
  }
751
+ if (this.pendingPriceSubscription) {
752
+ this.sendPriceSubscription(this.pendingPriceSubscription);
753
+ }
681
754
  this.config.onConnect?.();
682
755
  resolve();
683
756
  };
@@ -777,6 +850,21 @@ var K256WebSocketClient = class {
777
850
  case "quote_subscribed":
778
851
  this.config.onQuoteSubscribed?.(decoded);
779
852
  break;
853
+ case "price_update":
854
+ this.config.onPriceUpdate?.(decoded);
855
+ break;
856
+ case "price_batch":
857
+ this.config.onPriceBatch?.(decoded);
858
+ for (const entry of decoded.data) {
859
+ this.config.onPriceUpdate?.({ type: "price_update", data: entry });
860
+ }
861
+ break;
862
+ case "price_snapshot":
863
+ this.config.onPriceSnapshot?.(decoded);
864
+ for (const entry of decoded.data) {
865
+ this.config.onPriceUpdate?.({ type: "price_update", data: entry });
866
+ }
867
+ break;
780
868
  case "heartbeat":
781
869
  this.lastHeartbeatTime = Date.now();
782
870
  this.resetHeartbeatTimeout();
@@ -837,6 +925,18 @@ var K256WebSocketClient = class {
837
925
  };
838
926
  this.ws?.send(JSON.stringify(msg));
839
927
  }
928
+ sendPriceSubscription(options) {
929
+ const json = JSON.stringify({
930
+ tokens: options.tokens,
931
+ thresholdBps: options.thresholdBps ?? 10
932
+ });
933
+ const encoder = new TextEncoder();
934
+ const jsonBytes = encoder.encode(json);
935
+ const buf = new Uint8Array(1 + jsonBytes.length);
936
+ buf[0] = MessageType.SubscribePrice;
937
+ buf.set(jsonBytes, 1);
938
+ this.ws?.send(buf);
939
+ }
840
940
  setState(state) {
841
941
  if (this._state !== state) {
842
942
  const prevState = this._state;
@@ -1007,6 +1107,11 @@ function readU16(view, o) {
1007
1107
  o.v += 2;
1008
1108
  return val;
1009
1109
  }
1110
+ function readF64(view, o) {
1111
+ const val = view.getFloat64(o.v, true);
1112
+ o.v += 8;
1113
+ return val;
1114
+ }
1010
1115
  function readU8(view, o) {
1011
1116
  const val = view.getUint8(o.v);
1012
1117
  o.v += 1;
@@ -1065,12 +1170,16 @@ function readGossipPeer(view, data, o) {
1065
1170
  lastVote: readU64(view, o),
1066
1171
  rootSlot: readU64(view, o),
1067
1172
  wallclock: readU64(view, o),
1068
- // Geo/ASN enrichment from IPinfo Lite MMDB (server-side)
1173
+ // Geo/ASN enrichment from MaxMind GeoLite2 (server-side)
1069
1174
  countryCode: readVecU8AsString(view, data, o),
1070
1175
  continentCode: readVecU8AsString(view, data, o),
1071
1176
  asn: readVecU8AsString(view, data, o),
1072
1177
  asName: readVecU8AsString(view, data, o),
1073
- asDomain: readVecU8AsString(view, data, o)
1178
+ city: readVecU8AsString(view, data, o),
1179
+ region: readVecU8AsString(view, data, o),
1180
+ latitude: readF64(view, o),
1181
+ longitude: readF64(view, o),
1182
+ timezone: readVecU8AsString(view, data, o)
1074
1183
  };
1075
1184
  }
1076
1185
  function readGossipPeerVec(view, data, o) {
@@ -1486,6 +1595,6 @@ var NetworkState = /* @__PURE__ */ ((NetworkState2) => {
1486
1595
  return NetworkState2;
1487
1596
  })(NetworkState || {});
1488
1597
 
1489
- export { ALL_LEADER_CHANNELS, CloseCode, K256WebSocketClient, K256WebSocketError, LeaderChannel, LeaderMessageTag, LeaderWebSocketClient, LeaderWebSocketError, MessageType, NetworkState, base58Decode, base58Encode, decodeLeaderMessage, decodeMessage, decodePoolUpdateBatch, isValidPubkey };
1598
+ export { ALL_LEADER_CHANNELS, CloseCode, K256WebSocketClient, K256WebSocketError, LeaderChannel, LeaderMessageTag, LeaderWebSocketClient, LeaderWebSocketError, MessageType, NetworkState, base58Decode, base58Encode, decodeLeaderMessage, decodeMessage, decodePoolUpdateBatch, decodePriceEntries, isValidPubkey };
1490
1599
  //# sourceMappingURL=index.js.map
1491
1600
  //# sourceMappingURL=index.js.map