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