@k256/sdk 0.1.6 → 0.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.
package/dist/index.js CHANGED
@@ -21,8 +21,15 @@ function base58Encode(bytes) {
21
21
  return leadingZeros + digits.reverse().map((d) => BASE58_ALPHABET[d]).join("");
22
22
  }
23
23
  function base58Decode(str) {
24
+ if (str.length === 0) {
25
+ return new Uint8Array(0);
26
+ }
27
+ let leadingZeros = 0;
28
+ for (let i = 0; i < str.length && str[i] === "1"; i++) {
29
+ leadingZeros++;
30
+ }
24
31
  const bytes = [0];
25
- for (let i = 0; i < str.length; i++) {
32
+ for (let i = leadingZeros; i < str.length; i++) {
26
33
  const char = str[i];
27
34
  const value = BASE58_ALPHABET.indexOf(char);
28
35
  if (value === -1) {
@@ -39,10 +46,19 @@ function base58Decode(str) {
39
46
  carry >>= 8;
40
47
  }
41
48
  }
42
- for (let i = 0; i < str.length && str[i] === "1"; i++) {
43
- bytes.push(0);
49
+ bytes.reverse();
50
+ if (leadingZeros > 0 && bytes.length === 1 && bytes[0] === 0) {
51
+ return new Uint8Array(leadingZeros);
52
+ }
53
+ const startIdx = bytes.length > 1 && bytes[0] === 0 ? 1 : 0;
54
+ const result = new Uint8Array(leadingZeros + bytes.length - startIdx);
55
+ for (let i = 0; i < leadingZeros; i++) {
56
+ result[i] = 0;
44
57
  }
45
- return new Uint8Array(bytes.reverse());
58
+ for (let i = startIdx; i < bytes.length; i++) {
59
+ result[leadingZeros + i - startIdx] = bytes[i];
60
+ }
61
+ return result;
46
62
  }
47
63
  function isValidPubkey(address) {
48
64
  if (address.length < 32 || address.length > 44) {
@@ -91,6 +107,8 @@ var MessageType = {
91
107
  Heartbeat: 13,
92
108
  /** Batched pool updates for high throughput */
93
109
  PoolUpdateBatch: 14,
110
+ /** Block-level statistics (v3) */
111
+ BlockStats: 15,
94
112
  /** Error message (UTF-8 string) */
95
113
  Error: 255
96
114
  };
@@ -131,55 +149,75 @@ function decodeMessage(data) {
131
149
  return { type: "error", data: { message: text } };
132
150
  }
133
151
  case MessageType.PriorityFees: {
134
- if (payload.byteLength < 24) return null;
152
+ if (payload.byteLength < 42) return null;
135
153
  const slot = Number(payloadView.getBigUint64(0, true));
136
154
  const timestampMs = Number(payloadView.getBigUint64(8, true));
137
155
  const recommended = Number(payloadView.getBigUint64(16, true));
138
- const state = payload.byteLength > 24 ? payloadView.getUint8(24) : 1;
139
- const isStale = payload.byteLength > 25 ? payloadView.getUint8(25) !== 0 : false;
140
- let swapP50 = 0, swapP75 = 0, swapP90 = 0, swapP99 = 0;
141
- if (payload.byteLength >= 58) {
142
- swapP50 = Number(payloadView.getBigUint64(26, true));
143
- swapP75 = Number(payloadView.getBigUint64(34, true));
144
- swapP90 = Number(payloadView.getBigUint64(42, true));
145
- swapP99 = Number(payloadView.getBigUint64(50, true));
156
+ const state = payloadView.getUint8(24);
157
+ const isStale = payloadView.getUint8(25) !== 0;
158
+ const blockUtilizationPct = payloadView.getFloat32(26, true);
159
+ const blocksInWindow = payloadView.getUint32(30, true);
160
+ const accountCount = Number(payloadView.getBigUint64(34, true));
161
+ const accounts = [];
162
+ let offset = 42;
163
+ for (let i = 0; i < accountCount && offset + 92 <= payload.byteLength; i++) {
164
+ const pubkeyBytes = new Uint8Array(payload, offset, 32);
165
+ const pubkey = base58Encode(pubkeyBytes);
166
+ const totalTxs = payloadView.getUint32(offset + 32, true);
167
+ const activeSlots = payloadView.getUint32(offset + 36, true);
168
+ const cuConsumed = Number(payloadView.getBigUint64(offset + 40, true));
169
+ const utilizationPct = payloadView.getFloat32(offset + 48, true);
170
+ const p25 = Number(payloadView.getBigUint64(offset + 52, true));
171
+ const p50 = Number(payloadView.getBigUint64(offset + 60, true));
172
+ const p75 = Number(payloadView.getBigUint64(offset + 68, true));
173
+ const p90 = Number(payloadView.getBigUint64(offset + 76, true));
174
+ const minNonzeroPrice = Number(payloadView.getBigUint64(offset + 84, true));
175
+ accounts.push({
176
+ pubkey,
177
+ totalTxs,
178
+ activeSlots,
179
+ cuConsumed,
180
+ utilizationPct,
181
+ p25,
182
+ p50,
183
+ p75,
184
+ p90,
185
+ minNonzeroPrice
186
+ });
187
+ offset += 92;
146
188
  }
147
- let swapSamples = 0;
148
- let landingP50Fee = 0, landingP75Fee = 0, landingP90Fee = 0, landingP99Fee = 0;
149
- let top10Fee = 0, top25Fee = 0;
150
- let spikeDetected = false, spikeFee = 0;
151
- if (payload.byteLength >= 119) {
152
- swapSamples = payloadView.getUint32(58, true);
153
- landingP50Fee = Number(payloadView.getBigUint64(62, true));
154
- landingP75Fee = Number(payloadView.getBigUint64(70, true));
155
- landingP90Fee = Number(payloadView.getBigUint64(78, true));
156
- landingP99Fee = Number(payloadView.getBigUint64(86, true));
157
- top10Fee = Number(payloadView.getBigUint64(94, true));
158
- top25Fee = Number(payloadView.getBigUint64(102, true));
159
- spikeDetected = payloadView.getUint8(110) !== 0;
160
- spikeFee = Number(payloadView.getBigUint64(111, true));
189
+ const recentBlocksCount = Number(payloadView.getBigUint64(offset, true));
190
+ offset += 8;
191
+ const recentBlocks = [];
192
+ for (let i = 0; i < recentBlocksCount; i++) {
193
+ const rbSlot = Number(payloadView.getBigUint64(offset, true));
194
+ offset += 8;
195
+ const rbCuConsumed = Number(payloadView.getBigUint64(offset, true));
196
+ offset += 8;
197
+ const rbTxCount = payloadView.getUint32(offset, true);
198
+ offset += 4;
199
+ const rbUtilizationPct = payloadView.getFloat32(offset, true);
200
+ offset += 4;
201
+ const rbAvgCuPrice = Number(payloadView.getBigUint64(offset, true));
202
+ offset += 8;
203
+ recentBlocks.push({ slot: rbSlot, cuConsumed: rbCuConsumed, txCount: rbTxCount, utilizationPct: rbUtilizationPct, avgCuPrice: rbAvgCuPrice });
161
204
  }
205
+ const trendByte = payloadView.getUint8(offset);
206
+ offset += 1;
207
+ const trend = trendByte === 0 ? "rising" : trendByte === 1 ? "falling" : "stable";
162
208
  return {
163
- type: "priority_fees",
209
+ type: "fee_market",
164
210
  data: {
165
211
  slot,
166
212
  timestampMs,
167
213
  recommended,
168
214
  state,
169
215
  isStale,
170
- swapP50,
171
- swapP75,
172
- swapP90,
173
- swapP99,
174
- swapSamples,
175
- landingP50Fee,
176
- landingP75Fee,
177
- landingP90Fee,
178
- landingP99Fee,
179
- top10Fee,
180
- top25Fee,
181
- spikeDetected,
182
- spikeFee
216
+ blockUtilizationPct,
217
+ blocksInWindow,
218
+ accounts,
219
+ recentBlocks,
220
+ trend
183
221
  }
184
222
  };
185
223
  }
@@ -224,6 +262,51 @@ function decodeMessage(data) {
224
262
  }
225
263
  };
226
264
  }
265
+ case MessageType.BlockStats: {
266
+ let offset = 0;
267
+ const slot = Number(payloadView.getBigUint64(offset, true));
268
+ offset += 8;
269
+ const cuConsumed = Number(payloadView.getBigUint64(offset, true));
270
+ offset += 8;
271
+ const executionCu = Number(payloadView.getBigUint64(offset, true));
272
+ offset += 8;
273
+ const cuLimit = Number(payloadView.getBigUint64(offset, true));
274
+ offset += 8;
275
+ const cuRemaining = Number(payloadView.getBigUint64(offset, true));
276
+ offset += 8;
277
+ const utilizationPct = payloadView.getFloat32(offset, true);
278
+ offset += 4;
279
+ const txCount = payloadView.getUint32(offset, true);
280
+ offset += 4;
281
+ const avgCuPerTx = payloadView.getUint32(offset, true);
282
+ offset += 4;
283
+ const avgCuPrice = Number(payloadView.getBigUint64(offset, true));
284
+ offset += 8;
285
+ const minCuPrice = Number(payloadView.getBigUint64(offset, true));
286
+ offset += 8;
287
+ const maxCuPrice = Number(payloadView.getBigUint64(offset, true));
288
+ offset += 8;
289
+ const timestampMs = Number(payloadView.getBigUint64(offset, true));
290
+ offset += 8;
291
+ return {
292
+ type: "block_stats",
293
+ data: {
294
+ slot,
295
+ cuConsumed,
296
+ executionCu,
297
+ cuLimit,
298
+ cuRemaining,
299
+ utilizationPct,
300
+ txCount,
301
+ avgCuPerTx,
302
+ avgCuPrice,
303
+ minCuPrice,
304
+ maxCuPrice,
305
+ timestampMs
306
+ },
307
+ receivedAt: Date.now()
308
+ };
309
+ }
227
310
  default:
228
311
  return null;
229
312
  }
@@ -305,19 +388,7 @@ function decodePoolUpdate(payload, payloadView) {
305
388
  }
306
389
  };
307
390
  } catch {
308
- return {
309
- type: "pool_update",
310
- data: {
311
- sequence: 0,
312
- slot: 0,
313
- writeVersion: 0,
314
- protocol: "unknown",
315
- poolAddress: "",
316
- tokenMints: [],
317
- tokenBalances: [],
318
- tokenDecimals: []
319
- }
320
- };
391
+ return null;
321
392
  }
322
393
  }
323
394
  function decodeQuote(payload, payloadView) {
@@ -388,25 +459,7 @@ function decodeQuote(payload, payloadView) {
388
459
  }
389
460
  };
390
461
  } catch {
391
- return {
392
- type: "quote",
393
- data: {
394
- topicId: "",
395
- timestampMs: 0,
396
- sequence: 0,
397
- inputMint: "",
398
- outputMint: "",
399
- inAmount: "0",
400
- outAmount: "0",
401
- priceImpactBps: 0,
402
- contextSlot: 0,
403
- algorithm: "",
404
- isImprovement: false,
405
- isCached: false,
406
- isStale: false,
407
- routePlan: null
408
- }
409
- };
462
+ return null;
410
463
  }
411
464
  }
412
465
 
@@ -708,8 +761,11 @@ var K256WebSocketClient = class {
708
761
  case "pool_update":
709
762
  this.config.onPoolUpdate?.(decoded);
710
763
  break;
711
- case "priority_fees":
712
- this.config.onPriorityFees?.(decoded);
764
+ case "fee_market":
765
+ this.config.onFeeMarket?.(decoded);
766
+ break;
767
+ case "block_stats":
768
+ this.config.onBlockStats?.(decoded);
713
769
  break;
714
770
  case "blockhash":
715
771
  this.config.onBlockhash?.(decoded);