@triton-one/yellowstone-grpc
v5.0.9
Published
Yellowstone gRPC Geyser Node.js Client
Downloads
132,042
Keywords
Readme
Yellowstone Node.js gRPC client
This library implements a client for streaming account updates for backend applications.
You can find more information and documentation on the Triton One website.
Prerequisites
You need to have the latest version of protoc installed.
Please refer to the installation guide on the Protobuf website.
Usage
Install required dependencies by running
npm installBuild the project (this will generate the gRPC client and compile TypeScript):
npm run buildPlease refer to examples/typescript for some usage examples.
Auto reconnect
Standard subscribe streams can opt into the native Rust client's reconnect,
backfill, and deduplication layer by passing reconnect options as the fourth
constructor argument:
const client = new Client(endpoint, xToken, channelOptions, {
backoff: {
initialIntervalMs: 100,
multiplier: 2,
maxRetries: 10,
},
slotRetention: 250,
});
await client.connect();
const stream = await client.subscribe(request);Omit the fourth argument, or pass { enabled: false }, to keep the previous
no-reconnect behavior. Deshred subscriptions are unchanged.
Compressed account filters
For large account sets, use CompressedAccountFilterSet to send a compact
cuckoo filter instead of a full explicit account list. The local set keeps exact
membership for false-positive filtering.
import Client, {
CompressedAccountFilterSet,
SubscribeRequest,
} from "@triton-one/yellowstone-grpc";
const accounts = new CompressedAccountFilterSet(2_000_000);
for (const pubkey of trackedPubkeys) {
accounts.insert(pubkey); // base58 string, Buffer, or Uint8Array
}
const request: SubscribeRequest = {
accounts: {},
slots: {},
transactions: {},
transactionsStatus: {},
blocks: {},
blocksMeta: {},
entry: {},
accountsDataSlice: [],
};
accounts.insertIntoSubscribeRequest(request, "tracked");
const stream = await client.subscribe(request);
stream.on("data", (update) => {
const pubkey = update.account?.account?.pubkey;
if (pubkey && accounts.contains(pubkey)) {
// exact local match
}
});
accounts.insert(newPubkey);
accounts.remove(oldPubkey);
accounts.insertIntoSubscribeRequest(request, "tracked");
stream.write(request);Use insertIntoBlockSubscribeRequest(request, name) when filtering account
includes inside block subscriptions.
Troubleshooting
For macOS:
You might have to run npm run build with RUSTFLAGS="-Clink-arg=-undefined -Clink-arg=dynamic_lookup" to skip the strict linkers from failing the build step and resolve dylibs via runtime.
RUSTFLAGS="-Clink-arg=-undefined -Clink-arg=dynamic_lookup" npm run buildWorking
Since the start, the @triton-one/yellowstone-grpc package has used the @grpc/grpc-js lib for gRPC types enforcement, connection and subscription management. This hit a bottleneck, described in this blog
From v5.0.0 the napi-rs framework is used for gRPC connection and subscription management. It's described into this blog
These changes are internal to the SDK and do not have any breaking changes for client code. If you face any issues, please open an issue
The napi-rs based implementation is inspired from the implemenation of the LaserStream SDK
Type Compatibility
The public SDK always returns the generated protobuf-compatible types from
src/grpc/geyser.ts.
- Unary methods return generated response objects (for example
PongResponse,GetSlotResponse,GetVersionResponse) instead of raw N-API wrapper shapes. - Subscription stream updates are normalized to
SubscribeUpdatewith top-level oneof fields (account,slot,transaction, etc). - The internal N-API
Js...objects are an implementation detail and are converted automatically by the SDK wrapper.
This allows existing user code typed against the generated src/grpc types to
remain stable while using the N-API backend.
Development
Local Testing
When building for local testing at the root of the project where the Makefile resides, you must:
Clean build artifacts if any with
make cleanNavigate to the SDK (where this README resides) and install dependencies with
npm installandnpm run build:dev. Make sure to usebuild:devto reflect local changes in your test runs and NOTbuild.Navigate to
examples/typescriptfolder and install dependencies withnpm install.Run
client.tswith an example subscription request below:tsx examples/typescript/src/client.ts --endpoint <ENDPOINT> --x-token <X-TOKEN> --commitment processed subscribe --transactions TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA
