Skip to Content
Geyser gRPC (Vortex)Getting Started

Getting Started with Vortex

Point your existing Geyser client at Raiden Vortex

1. Get Access

→ dashboard 

2. Get Your Endpoint

RegionEndpoint
FRAhttp://fra.vortex.raiden.wtf:10001/
AMShttp://ams.vortex.raiden.wtf:10001/
NYChttp://nyc.vortex.raiden.wtf:10001/
LNDhttp://lnd.vortex.raiden.wtf:10001/

Each region requires a separate subscription.

3. Authorisation

Vortex authorises by source IP. The IP you register on the dashboard is whitelisted on that region’s gateway, and connections from it are accepted without a per-request token.

Two consequences worth knowing before you connect:

  • Connect from the registered IP, not through a NAT or proxy that changes it.
  • One subscription is one IP. Serving several machines means either routing them through the registered address or taking a subscription per address.

You can change the registered IP from the dashboard. There is a short cooldown between changes.

4. Protocol

Vortex speaks the Geyser gRPC protocol — the same geyser.proto used by Yellowstone and Dragon’s Mouth clients. If your stack already integrates one of those, no code changes are needed.

  • Service: Geyser
  • RPC: Subscribe — bidirectional streaming
  • Request: SubscribeRequest with named filter maps per method
  • Payload: SubscribeUpdate, one variant per subscription method

blocks, blocks_meta and entry are not available. Vortex serves accounts, transactions and slots.

Leave the other three out of your SubscribeRequest: a client that subscribes to every method by default will need them removed.

5. Connect

Rust (yellowstone-grpc-client)

use futures::{sink::SinkExt, stream::StreamExt}; use std::collections::HashMap; use yellowstone_grpc_client::GeyserGrpcClient; use yellowstone_grpc_proto::prelude::{ subscribe_update::UpdateOneof, CommitmentLevel, SubscribeRequest, SubscribeRequestFilterTransactions, }; #[tokio::main] async fn main() -> Result<(), Box<dyn std::error::Error>> { let mut client = GeyserGrpcClient::build_from_shared("http://fra.vortex.raiden.wtf:10001")? .connect() .await?; let mut transactions = HashMap::new(); transactions.insert( "pumpfun".to_owned(), SubscribeRequestFilterTransactions { vote: Some(false), failed: Some(false), account_include: vec!["6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P".to_owned()], account_exclude: vec![], account_required: vec![], signature: None, }, ); // blocks, blocks_meta and entry are deliberately absent: Vortex serves // accounts, transactions and slots. let request = SubscribeRequest { transactions, commitment: Some(CommitmentLevel::Processed as i32), ..Default::default() }; let (mut sink, mut stream) = client.subscribe().await?; sink.send(request).await?; while let Some(message) = stream.next().await { if let Some(UpdateOneof::Transaction(tx)) = message?.update_oneof { println!("slot {}", tx.slot); } } Ok(()) }

Python (grpcio + protobuf)

Generate bindings from geyser.proto, then:

import grpc from geyser_pb2 import SubscribeRequest, SubscribeRequestFilterTransactions from geyser_pb2_grpc import GeyserStub channel = grpc.insecure_channel("fra.vortex.raiden.wtf:10001") stub = GeyserStub(channel) def make_requests(): yield SubscribeRequest( transactions={ "pumpfun": SubscribeRequestFilterTransactions( vote=False, failed=False, account_include=["6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"], ), }, # blocks, blocks_meta and entry omitted: not served by Vortex ) for update in stub.Subscribe(make_requests()): if update.HasField("transaction"): print(f"slot {update.transaction.slot}")

TypeScript (@triton-one/yellowstone-grpc)

import Client, { CommitmentLevel } from '@triton-one/yellowstone-grpc'; const client = new Client('http://fra.vortex.raiden.wtf:10001', undefined, undefined); const stream = await client.subscribe(); stream.on('data', (update) => { if (update.transaction) { console.log(`slot ${update.transaction.slot}`); } }); stream.write({ accounts: {}, slots: {}, transactions: { pumpfun: { vote: false, failed: false, accountInclude: ['6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P'], accountExclude: [], accountRequired: [], }, }, // blocks, blocksMeta and entry omitted: not served by Vortex accountsDataSlice: [], commitment: CommitmentLevel.PROCESSED, });

6. Filtering

Each subscription method takes a map of named filters. The name is yours to choose ("pumpfun", "jupiter-swaps"), and updates arrive tagged with the filter names they matched, so one stream can serve several independent concerns.

For transactions:

FieldPurpose
account_requiredTransaction must touch every listed account
account_includeTransaction may touch any listed account
account_excludeTransaction must not touch any listed account
voteInclude or exclude vote transactions
failedInclude or exclude failed transactions

Filtering runs server-side, so what you exclude never crosses the wire.

7. Limits

LimitValue
Concurrent connections20
Named filters35 per connection
Account filters5,000 per named filter

A named filter carrying more than 5,000 accounts is rejected. If you need to watch more, split them across filters, and across connections once you pass 35.

Pricing

See Pricing.

Payment in USDC on Solana via the dashboard.

Last updated on