> For the complete documentation index, see [llms.txt](https://raiden-4.gitbook.io/raiden.wtf.docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://raiden-4.gitbook.io/raiden.wtf.docs/geyser-grpc-vortex/getting-started.md).

# Getting Started

Point your existing Geyser client at Raiden Vortex

## 1. Get Access

→ [dashboard](https://raiden.wtf/dashboard/vortex)

## 2. Get Your Endpoint

| Region  | Endpoint                              |
| ------- | ------------------------------------- |
| **FRA** | `http://fra.vortex.raiden.wtf:10001/` |
| **AMS** | `http://ams.vortex.raiden.wtf:10001/` |
| **NYC** | `http://nyc.vortex.raiden.wtf:10001/` |
| **LND** | `http://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

{% hint style="warning" %}
`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.
{% endhint %}

## 5. Connect

### Rust (yellowstone-grpc-client)

```rust
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:

```python
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`)

```ts
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`:

| Field              | Purpose                                           |
| ------------------ | ------------------------------------------------- |
| `account_required` | Transaction **must** touch every listed account   |
| `account_include`  | Transaction **may** touch any listed account      |
| `account_exclude`  | Transaction **must not** touch any listed account |
| `vote`             | Include or exclude vote transactions              |
| `failed`           | Include or exclude failed transactions            |

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

## 7. Limits

| Limit                      | Value                  |
| -------------------------- | ---------------------- |
| **Concurrent connections** | 20                     |
| **Named filters**          | 35 per connection      |
| **Account filters**        | 5,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](/raiden.wtf.docs/infrastructure/pricing.md).

{% hint style="info" %}
Payment in **USDC on Solana** via the dashboard.
{% endhint %}
