@validators-dao/solana-stream-sdk 0.8.0 ā 0.10.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 +40 -90
- package/dist/index.d.ts +1 -175
- package/dist/index.js +10 -1317
- package/dist/index.js.map +1 -1
- package/package.json +4 -15
package/README.md
CHANGED
|
@@ -210,94 +210,56 @@ Here's how to use the SDK to subscribe to Solana Shreds and decode entries:
|
|
|
210
210
|
|
|
211
211
|
```typescript
|
|
212
212
|
import {
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
ShredsSubscribeEntriesRequestFns,
|
|
217
|
-
decodeSolanaEntries,
|
|
218
|
-
bs58,
|
|
213
|
+
ShredsClient,
|
|
214
|
+
ShredsClientCommitmentLevel,
|
|
215
|
+
// decodeSolanaEntries,
|
|
219
216
|
} from '@validators-dao/solana-stream-sdk'
|
|
220
217
|
import 'dotenv/config'
|
|
218
|
+
// import { logDecodedEntries } from '@/utils/logDecodedEntries'
|
|
221
219
|
|
|
222
|
-
|
|
220
|
+
import { receivedSlots, startLatencyCheck } from '@/utils/checkLatency'
|
|
223
221
|
|
|
224
|
-
const
|
|
222
|
+
const endpoint = process.env.SHREDS_ENDPOINT!
|
|
225
223
|
|
|
226
|
-
const
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
filters: [],
|
|
232
|
-
},
|
|
233
|
-
},
|
|
224
|
+
const client = new ShredsClient(endpoint)
|
|
225
|
+
|
|
226
|
+
// The filter is experimental
|
|
227
|
+
const request = {
|
|
228
|
+
accounts: {},
|
|
234
229
|
transactions: {},
|
|
235
230
|
slots: {},
|
|
236
|
-
commitment:
|
|
237
|
-
}
|
|
231
|
+
commitment: ShredsClientCommitmentLevel.Processed,
|
|
232
|
+
}
|
|
238
233
|
|
|
239
|
-
const connect =
|
|
234
|
+
const connect = () => {
|
|
240
235
|
console.log('Connecting to:', endpoint)
|
|
241
236
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
entry.transactions.forEach((tx, txIdx) => {
|
|
262
|
-
console.log(`\nš Transaction #${txIdx + 1}`)
|
|
263
|
-
const signaturesBase58 = tx.signatures
|
|
264
|
-
.slice(1)
|
|
265
|
-
.map((sig) => bs58.encode(Buffer.from(sig)))
|
|
266
|
-
console.log(` - Signatures:`, signaturesBase58)
|
|
267
|
-
|
|
268
|
-
const message = tx.message[0]
|
|
269
|
-
if (message) {
|
|
270
|
-
message.accountKeys.forEach((key, idx) => {
|
|
271
|
-
console.log(` [${idx}] ${bs58.encode(Buffer.from(key))}`)
|
|
272
|
-
})
|
|
273
|
-
|
|
274
|
-
message.instructions.forEach((inst, instIdx) => {
|
|
275
|
-
console.log(` [${instIdx}]`)
|
|
276
|
-
console.log(` - Program ID Index: ${inst.programIdIndex}`)
|
|
277
|
-
console.log(` - Accounts: ${inst.accounts.join(', ')}`)
|
|
278
|
-
console.log(` - Data: ${bs58.encode(Buffer.from(inst.data))}`)
|
|
279
|
-
})
|
|
280
|
-
|
|
281
|
-
console.log(
|
|
282
|
-
` š Recent Blockhash: ${bs58.encode(Buffer.from(message.recentBlockhash))}`,
|
|
283
|
-
)
|
|
237
|
+
client.subscribeEntries(
|
|
238
|
+
JSON.stringify(request),
|
|
239
|
+
(_error: any, buffer: any) => {
|
|
240
|
+
const receivedAt = new Date()
|
|
241
|
+
if (buffer) {
|
|
242
|
+
const {
|
|
243
|
+
slot,
|
|
244
|
+
// entries
|
|
245
|
+
} = JSON.parse(buffer)
|
|
246
|
+
|
|
247
|
+
// You can decode entries as needed
|
|
248
|
+
// const decodedEntries = decodeSolanaEntries(new Uint8Array(entries))
|
|
249
|
+
// logDecodedEntries(decodedEntries)
|
|
250
|
+
|
|
251
|
+
if (!receivedSlots.has(slot)) {
|
|
252
|
+
receivedSlots.set(slot, [{ receivedAt }])
|
|
253
|
+
} else {
|
|
254
|
+
receivedSlots.get(slot)!.push({ receivedAt })
|
|
284
255
|
}
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
stream.on('error', (err) => {
|
|
290
|
-
console.error('šØ Stream error:', err)
|
|
291
|
-
setTimeout(connect, 5000)
|
|
292
|
-
})
|
|
293
|
-
|
|
294
|
-
stream.on('end', () => {
|
|
295
|
-
console.log('š Stream ended, reconnecting...')
|
|
296
|
-
setTimeout(connect, 5000)
|
|
297
|
-
})
|
|
256
|
+
}
|
|
257
|
+
},
|
|
258
|
+
)
|
|
298
259
|
}
|
|
299
260
|
|
|
300
261
|
connect()
|
|
262
|
+
startLatencyCheck()
|
|
301
263
|
```
|
|
302
264
|
|
|
303
265
|
Ensure the environment variable `SHREDS_ENDPOINT` is set correctly.
|
|
@@ -325,33 +287,21 @@ Ensure the environment variable `SHREDS_ENDPOINT` is set correctly.
|
|
|
325
287
|
- `SubscribeRequestAccountsDataSlice`: Data slice configuration for account subscriptions.
|
|
326
288
|
- `bs58`: Base58 encoding/decoding utilities for Solana addresses and data.
|
|
327
289
|
|
|
328
|
-
### Shredstream Client
|
|
329
|
-
|
|
330
|
-
- `ShredstreamProxyClient`: Client for streaming Solana shreds through proxy endpoints.
|
|
331
|
-
- `ShredstreamClient`: Direct client for streaming Solana shreds.
|
|
332
|
-
- `ShredsCommitmentLevel`: Commitment levels specifically for Shredstream data.
|
|
333
|
-
- `ShredsSubscribeEntriesRequestFns`: Functions to construct entry subscription requests.
|
|
334
|
-
- `ShredsEntryFns`: Utilities and functions for handling shred entries.
|
|
335
|
-
|
|
336
|
-
### Shredstream Exported Type Definitions
|
|
290
|
+
### Shredstream Client
|
|
337
291
|
|
|
338
|
-
- `
|
|
339
|
-
- `
|
|
340
|
-
- `ShredsSubscribeRequestFilterTransactions`: Transaction filter type for shred subscriptions.
|
|
341
|
-
- `ShredsSubscribeRequestFilterSlots`: Slot filter type for shred subscriptions.
|
|
342
|
-
- `ShredsEntry`: Entry type definition representing Solana shred entries.
|
|
292
|
+
- `ShredsClient`: Client for streaming Solana shreds through shreds endpoints.
|
|
293
|
+
- `ShredsClientCommitmentLevel`: Solana commitment levels (e.g., processed, confirmed, finalized).
|
|
343
294
|
|
|
344
295
|
### Utility Exports
|
|
345
296
|
|
|
346
297
|
- `decodeSolanaEntries`: Function to decode raw Solana shred entry data into structured, human-readable formats.
|
|
347
|
-
- `credentials`, `Metadata`: gRPC credentials and metadata utilities.
|
|
348
298
|
|
|
349
299
|
## Dependencies
|
|
350
300
|
|
|
351
301
|
- `@triton-one/yellowstone-grpc`: For gRPC streaming capabilities
|
|
352
302
|
- `bs58`: For base58 encoding/decoding
|
|
353
|
-
- `@grpc/grpc-js`
|
|
354
303
|
- `@validators-dao/solana-entry-decoder`: Utility for decoding Solana shred entries.
|
|
304
|
+
- `@validators-dao/solana-shreds-client`: Solana Shreds Client for Scale. (NAPI-RS)
|
|
355
305
|
|
|
356
306
|
## ā ļø Experimental Filtering Feature Notice
|
|
357
307
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,179 +1,5 @@
|
|
|
1
1
|
export { CommitmentLevel, default as GeyserClient, SubscribeRequestAccountsDataSlice, SubscribeRequestFilterAccounts, SubscribeRequestFilterBlocks, SubscribeRequestFilterBlocksMeta, SubscribeRequestFilterEntry, SubscribeRequestFilterSlots, SubscribeRequestFilterTransactions } from '@triton-one/yellowstone-grpc';
|
|
2
2
|
export { default as bs58 } from 'bs58';
|
|
3
|
-
import { BinaryWriter, BinaryReader } from '@bufbuild/protobuf/wire';
|
|
4
|
-
import { Client, CallOptions, ClientReadableStream, Metadata, ChannelCredentials, ClientOptions, ServiceError, ClientUnaryCall } from '@grpc/grpc-js';
|
|
5
|
-
export { Metadata, credentials } from '@grpc/grpc-js';
|
|
6
|
-
|
|
7
|
-
interface Socket {
|
|
8
|
-
ip: string;
|
|
9
|
-
port: number;
|
|
10
|
-
}
|
|
11
|
-
declare const Socket: MessageFns$1<Socket>;
|
|
12
|
-
type Builtin$1 = Date | Function | Uint8Array | string | number | boolean | undefined;
|
|
13
|
-
type DeepPartial$1<T> = T extends Builtin$1 ? T : T extends globalThis.Array<infer U> ? globalThis.Array<DeepPartial$1<U>> : T extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial$1<U>> : T extends {} ? {
|
|
14
|
-
[K in keyof T]?: DeepPartial$1<T[K]>;
|
|
15
|
-
} : Partial<T>;
|
|
16
|
-
type KeysOfUnion$1<T> = T extends T ? keyof T : never;
|
|
17
|
-
type Exact$1<P, I extends P> = P extends Builtin$1 ? P : P & {
|
|
18
|
-
[K in keyof P]: Exact$1<P[K], I[K]>;
|
|
19
|
-
} & {
|
|
20
|
-
[K in Exclude<keyof I, KeysOfUnion$1<P>>]: never;
|
|
21
|
-
};
|
|
22
|
-
interface MessageFns$1<T> {
|
|
23
|
-
encode(message: T, writer?: BinaryWriter): BinaryWriter;
|
|
24
|
-
decode(input: BinaryReader | Uint8Array, length?: number): T;
|
|
25
|
-
fromJSON(object: any): T;
|
|
26
|
-
toJSON(message: T): unknown;
|
|
27
|
-
create<I extends Exact$1<DeepPartial$1<T>, I>>(base?: I): T;
|
|
28
|
-
fromPartial<I extends Exact$1<DeepPartial$1<T>, I>>(object: I): T;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
declare enum CommitmentLevel {
|
|
32
|
-
PROCESSED = 0,
|
|
33
|
-
CONFIRMED = 1,
|
|
34
|
-
FINALIZED = 2,
|
|
35
|
-
UNRECOGNIZED = -1
|
|
36
|
-
}
|
|
37
|
-
interface Heartbeat {
|
|
38
|
-
/**
|
|
39
|
-
* don't trust IP:PORT from tcp header since it can be tampered over the wire
|
|
40
|
-
* `socket.ip` must match incoming packet's ip. this prevents spamming an unwitting destination
|
|
41
|
-
*/
|
|
42
|
-
socket: Socket | undefined;
|
|
43
|
-
/**
|
|
44
|
-
* regions for shredstream proxy to receive shreds from
|
|
45
|
-
* list of valid regions: https://docs.jito.wtf/lowlatencytxnsend/#api
|
|
46
|
-
*/
|
|
47
|
-
regions: string[];
|
|
48
|
-
}
|
|
49
|
-
declare const Heartbeat: MessageFns<Heartbeat>;
|
|
50
|
-
interface HeartbeatResponse {
|
|
51
|
-
/** client must respond within `ttl_ms` to keep stream alive */
|
|
52
|
-
ttlMs: number;
|
|
53
|
-
}
|
|
54
|
-
declare const HeartbeatResponse: MessageFns<HeartbeatResponse>;
|
|
55
|
-
interface SubscribeEntriesRequest {
|
|
56
|
-
accounts: {
|
|
57
|
-
[key: string]: SubscribeRequestFilterAccounts;
|
|
58
|
-
};
|
|
59
|
-
transactions: {
|
|
60
|
-
[key: string]: SubscribeRequestFilterTransactions;
|
|
61
|
-
};
|
|
62
|
-
slots: {
|
|
63
|
-
[key: string]: SubscribeRequestFilterSlots;
|
|
64
|
-
};
|
|
65
|
-
commitment?: CommitmentLevel | undefined;
|
|
66
|
-
}
|
|
67
|
-
declare const SubscribeEntriesRequest: MessageFns<SubscribeEntriesRequest>;
|
|
68
|
-
interface SubscribeRequestFilterAccounts {
|
|
69
|
-
account: string[];
|
|
70
|
-
owner: string[];
|
|
71
|
-
filters: SubscribeRequestFilterAccountsFilter[];
|
|
72
|
-
nonemptyTxnSignature?: boolean | undefined;
|
|
73
|
-
}
|
|
74
|
-
declare const SubscribeRequestFilterAccounts: MessageFns<SubscribeRequestFilterAccounts>;
|
|
75
|
-
interface SubscribeRequestFilterAccountsFilter {
|
|
76
|
-
memcmp?: SubscribeRequestFilterAccountsFilterMemcmp | undefined;
|
|
77
|
-
datasize?: number | undefined;
|
|
78
|
-
tokenAccountState?: boolean | undefined;
|
|
79
|
-
lamports?: SubscribeRequestFilterAccountsFilterLamports | undefined;
|
|
80
|
-
}
|
|
81
|
-
declare const SubscribeRequestFilterAccountsFilter: MessageFns<SubscribeRequestFilterAccountsFilter>;
|
|
82
|
-
interface SubscribeRequestFilterAccountsFilterMemcmp {
|
|
83
|
-
offset: number;
|
|
84
|
-
bytes?: Uint8Array | undefined;
|
|
85
|
-
base58?: string | undefined;
|
|
86
|
-
base64?: string | undefined;
|
|
87
|
-
}
|
|
88
|
-
declare const SubscribeRequestFilterAccountsFilterMemcmp: MessageFns<SubscribeRequestFilterAccountsFilterMemcmp>;
|
|
89
|
-
interface SubscribeRequestFilterAccountsFilterLamports {
|
|
90
|
-
eq?: number | undefined;
|
|
91
|
-
ne?: number | undefined;
|
|
92
|
-
lt?: number | undefined;
|
|
93
|
-
gt?: number | undefined;
|
|
94
|
-
}
|
|
95
|
-
declare const SubscribeRequestFilterAccountsFilterLamports: MessageFns<SubscribeRequestFilterAccountsFilterLamports>;
|
|
96
|
-
interface SubscribeRequestFilterSlots {
|
|
97
|
-
filterByCommitment?: boolean | undefined;
|
|
98
|
-
interslotUpdates?: boolean | undefined;
|
|
99
|
-
}
|
|
100
|
-
declare const SubscribeRequestFilterSlots: MessageFns<SubscribeRequestFilterSlots>;
|
|
101
|
-
interface SubscribeRequestFilterTransactions {
|
|
102
|
-
accountInclude: string[];
|
|
103
|
-
accountExclude: string[];
|
|
104
|
-
accountRequired: string[];
|
|
105
|
-
}
|
|
106
|
-
declare const SubscribeRequestFilterTransactions: MessageFns<SubscribeRequestFilterTransactions>;
|
|
107
|
-
interface Entry {
|
|
108
|
-
/** the slot that the entry is from */
|
|
109
|
-
slot: number;
|
|
110
|
-
/** Serialized bytes of Vec<Entry>: https://docs.rs/solana-entry/latest/solana_entry/entry/struct.Entry.html */
|
|
111
|
-
entries: Uint8Array;
|
|
112
|
-
}
|
|
113
|
-
declare const Entry: MessageFns<Entry>;
|
|
114
|
-
type ShredstreamService = typeof ShredstreamService;
|
|
115
|
-
declare const ShredstreamService: {
|
|
116
|
-
/** RPC endpoint to send heartbeats to keep shreds flowing */
|
|
117
|
-
readonly sendHeartbeat: {
|
|
118
|
-
readonly path: "/shredstream.Shredstream/SendHeartbeat";
|
|
119
|
-
readonly requestStream: false;
|
|
120
|
-
readonly responseStream: false;
|
|
121
|
-
readonly requestSerialize: (value: Heartbeat) => Buffer<ArrayBuffer>;
|
|
122
|
-
readonly requestDeserialize: (value: Buffer) => Heartbeat;
|
|
123
|
-
readonly responseSerialize: (value: HeartbeatResponse) => Buffer<ArrayBuffer>;
|
|
124
|
-
readonly responseDeserialize: (value: Buffer) => HeartbeatResponse;
|
|
125
|
-
};
|
|
126
|
-
};
|
|
127
|
-
interface ShredstreamClient extends Client {
|
|
128
|
-
/** RPC endpoint to send heartbeats to keep shreds flowing */
|
|
129
|
-
sendHeartbeat(request: Heartbeat, callback: (error: ServiceError | null, response: HeartbeatResponse) => void): ClientUnaryCall;
|
|
130
|
-
sendHeartbeat(request: Heartbeat, metadata: Metadata, callback: (error: ServiceError | null, response: HeartbeatResponse) => void): ClientUnaryCall;
|
|
131
|
-
sendHeartbeat(request: Heartbeat, metadata: Metadata, options: Partial<CallOptions>, callback: (error: ServiceError | null, response: HeartbeatResponse) => void): ClientUnaryCall;
|
|
132
|
-
}
|
|
133
|
-
declare const ShredstreamClient: {
|
|
134
|
-
new (address: string, credentials: ChannelCredentials, options?: Partial<ClientOptions>): ShredstreamClient;
|
|
135
|
-
service: typeof ShredstreamService;
|
|
136
|
-
serviceName: string;
|
|
137
|
-
};
|
|
138
|
-
type ShredstreamProxyService = typeof ShredstreamProxyService;
|
|
139
|
-
declare const ShredstreamProxyService: {
|
|
140
|
-
readonly subscribeEntries: {
|
|
141
|
-
readonly path: "/shredstream.ShredstreamProxy/SubscribeEntries";
|
|
142
|
-
readonly requestStream: false;
|
|
143
|
-
readonly responseStream: true;
|
|
144
|
-
readonly requestSerialize: (value: SubscribeEntriesRequest) => Buffer<ArrayBuffer>;
|
|
145
|
-
readonly requestDeserialize: (value: Buffer) => SubscribeEntriesRequest;
|
|
146
|
-
readonly responseSerialize: (value: Entry) => Buffer<ArrayBuffer>;
|
|
147
|
-
readonly responseDeserialize: (value: Buffer) => Entry;
|
|
148
|
-
};
|
|
149
|
-
};
|
|
150
|
-
interface ShredstreamProxyClient extends Client {
|
|
151
|
-
subscribeEntries(request: SubscribeEntriesRequest, options?: Partial<CallOptions>): ClientReadableStream<Entry>;
|
|
152
|
-
subscribeEntries(request: SubscribeEntriesRequest, metadata?: Metadata, options?: Partial<CallOptions>): ClientReadableStream<Entry>;
|
|
153
|
-
}
|
|
154
|
-
declare const ShredstreamProxyClient: {
|
|
155
|
-
new (address: string, credentials: ChannelCredentials, options?: Partial<ClientOptions>): ShredstreamProxyClient;
|
|
156
|
-
service: typeof ShredstreamProxyService;
|
|
157
|
-
serviceName: string;
|
|
158
|
-
};
|
|
159
|
-
type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined;
|
|
160
|
-
type DeepPartial<T> = T extends Builtin ? T : T extends globalThis.Array<infer U> ? globalThis.Array<DeepPartial<U>> : T extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial<U>> : T extends {} ? {
|
|
161
|
-
[K in keyof T]?: DeepPartial<T[K]>;
|
|
162
|
-
} : Partial<T>;
|
|
163
|
-
type KeysOfUnion<T> = T extends T ? keyof T : never;
|
|
164
|
-
type Exact<P, I extends P> = P extends Builtin ? P : P & {
|
|
165
|
-
[K in keyof P]: Exact<P[K], I[K]>;
|
|
166
|
-
} & {
|
|
167
|
-
[K in Exclude<keyof I, KeysOfUnion<P>>]: never;
|
|
168
|
-
};
|
|
169
|
-
interface MessageFns<T> {
|
|
170
|
-
encode(message: T, writer?: BinaryWriter): BinaryWriter;
|
|
171
|
-
decode(input: BinaryReader | Uint8Array, length?: number): T;
|
|
172
|
-
fromJSON(object: any): T;
|
|
173
|
-
toJSON(message: T): unknown;
|
|
174
|
-
create<I extends Exact<DeepPartial<T>, I>>(base?: I): T;
|
|
175
|
-
fromPartial<I extends Exact<DeepPartial<T>, I>>(object: I): T;
|
|
176
|
-
}
|
|
177
3
|
|
|
178
4
|
declare const decodeSolanaEntries: any;
|
|
179
5
|
declare const ShredsClient: any;
|
|
@@ -183,4 +9,4 @@ declare enum ShredsClientCommitmentLevel {
|
|
|
183
9
|
Confirmed = "Confirmed"
|
|
184
10
|
}
|
|
185
11
|
|
|
186
|
-
export { ShredsClient, ShredsClientCommitmentLevel,
|
|
12
|
+
export { ShredsClient, ShredsClientCommitmentLevel, decodeSolanaEntries };
|