# Quick Start

Get streaming Solana data in under 5 minutes.

## Prerequisites

* Authentication token (contact [ThorLabs Discord](https://discord.gg/thorlabs))
* Server address check [Node Locations and Access](/introduction/node-locations-and-access.md)

## Choose Your Language

{% tabs %}
{% tab title="Go" %}
**Installation**

{% code title="Install" %}

```bash
go get github.com/thorlabsDev/ThorStreamer/sdks/go@v0.1.0
```

{% endcode %}

**Stream Transactions**

{% code title="main.go" %}

```go
package main

import (
    "context"
    "log"
    "os"
    "time"

    "github.com/joho/godotenv"
    thorclient "github.com/thorlabsDev/ThorStreamer/sdks/go/client"
)

func main() {
    godotenv.Load()

    client, err := thorclient.NewClient(thorclient.Config{
        ServerAddr:     os.Getenv("SERVER_ADDRESS"),
        Token:          os.Getenv("AUTH_TOKEN"),
        DefaultTimeout: 30 * time.Second,
    })
    if err != nil {
        log.Fatal(err)
    }
    defer client.Close()

    stream, err := client.SubscribeToTransactions(context.Background())
    if err != nil {
        log.Fatal(err)
    }

    for {
        msg, err := stream.Recv()
        if err != nil {
            break
        }
        if tx := msg.GetTransaction(); tx != nil {
            log.Printf("Transaction: slot=%d", tx.Transaction.Slot)
        }
    }
}
```

{% endcode %}
{% endtab %}

{% tab title="Rust" %}
**Installation**

{% code title="Cargo.toml" %}

```toml
[dependencies]
thor-grpc-client = "0.1.0"
tokio = { version = "1", features = ["full"] }
```

{% endcode %}

**Stream Transactions**

{% code title="main.rs" %}

```rust
use thor_grpc_client::{ClientConfig, ThorClient, parse_message};
use thor_grpc_client::proto::thor_streamer::types::message_wrapper::EventMessage;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let config = ClientConfig {
        server_addr: std::env::var("SERVER_ADDRESS")?,
        token: std::env::var("AUTH_TOKEN")?,
        ..Default::default()
    };

    let mut client = ThorClient::new(config).await?;
    let mut stream = client.subscribe_to_transactions().await?;

    while let Some(response) = stream.message().await? {
        let msg = parse_message(&response.data)?;
        if let Some(EventMessage::Transaction(tx_wrapper)) = msg.event_message {
            if let Some(tx) = tx_wrapper.transaction {
                println!("Transaction: slot={}", tx.slot);
            }
        }
    }
    Ok(())
}
```

{% endcode %}
{% endtab %}

{% tab title="TypeScript" %}
**Installation**

{% code title="Install" %}

```bash
npm install @grpc/grpc-js google-protobuf
```

{% endcode %}

**Stream Transactions**

{% code title="index.ts" %}

```typescript
import * as grpc from '@grpc/grpc-js';
import { Empty } from 'google-protobuf/google/protobuf/empty_pb';
import { EventPublisherClient } from './proto/publisher_grpc_pb';

const client = new EventPublisherClient(
    process.env.SERVER_ADDRESS!,
    grpc.credentials.createInsecure()
);

const metadata = new grpc.Metadata();
metadata.set('authorization', process.env.AUTH_TOKEN!);

const stream = client.subscribeToTransactions(new Empty(), metadata);

stream.on('data', (response) => {
    console.log('Transaction received:', response.getData().length, 'bytes');
});

stream.on('error', (err) => {
    console.error('Stream error:', err);
});
```

{% endcode %}
{% endtab %}

{% tab title="Python" %}
**Installation**

{% code title="Install" %}

```bash
pip install grpcio grpcio-tools
```

{% endcode %}

**Stream Transactions**

{% code title="stream.py" %}

```python
import grpc
import asyncio
from google.protobuf.empty_pb2 import Empty

# Generate proto files first:

# python -m grpc_tools.protoc -I./proto --python_out=. --grpc_python_out=. proto/*.proto

from proto import publisher_pb2_grpc

async def main():
    metadata = [('authorization', 'your-token')]

    async with grpc.aio.insecure_channel('your-server:50051') as channel:
        stub = publisher_pb2_grpc.EventPublisherStub(channel)
        stream = stub.SubscribeToTransactions(Empty(), metadata=metadata)

        async for response in stream:
            print(f"Transaction: {len(response.data)} bytes")

asyncio.run(main())
```

{% endcode %}
{% endtab %}
{% endtabs %}

## Environment Setup

Create a `.env` file:

{% code title=".env" %}

```bash
SERVER_ADDRESS=your-server:50051
AUTH_TOKEN=your-auth-token
```

{% endcode %}

## Next Steps

* [API Reference](/infrastructure/thorstreamer-grpc/api-reference.md) — Explore all available methods
* [SDK Documentation](/infrastructure/thorstreamer-grpc/sdks.md) — Detailed guides for each language
* Error Handling — Handle errors gracefully


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.thornode.io/infrastructure/thorstreamer-grpc/quick-start.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
