> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dexploit.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# gRPC: PriceStream

> Real-time protocol price feed at grpc.dexploit.dev. Typed DexTransaction price updates across every supported Solana DEX.

The `dexploit.v1.PriceStream` gRPC service streams real-time price updates (`DexTransaction`) for every swap on the protocols you subscribe to. Use it for high-throughput price pipelines and strongly-typed clients in any language.

<Note>
  For the **raw swap feed** with rich server-side filtering (tokens / traders / pools / SOL amount / direction / wallet tags), use [gRPC: SwapStream](/streaming/grpc-swaps) instead. `PriceStream` is protocol-scoped price updates; `SwapStream` is filtered `UnifiedSwap` records.
</Note>

## When to use gRPC over WebSocket

* You need binary efficiency at high message rates.
* You want auto-generated clients for Go, Rust, Python, Kotlin, etc.
* Your runtime supports HTTP/2 and bidirectional streaming.

## Endpoint and auth

* Host: `grpc.dexploit.dev:443` (TLS)
* Service: `dexploit.v1.PriceStream`
* Proto: [`price_stream.proto`](https://github.com/DexploitV1/Dexploit-Swaps/blob/main/crates/swaps-streamer/proto/price_stream.proto)

TLS is required. Authenticate via gRPC metadata — `x-api-key` or `authorization: Bearer`:

```
x-api-key: ohlcv_live_sk_<your_key>
```

Server reflection is enabled, so `grpcurl grpc.dexploit.dev:443 list` resolves the service set (`dexploit.v1.PriceStream`, `dexploit.v1.SwapStream`) without the `.proto`.

## Service definition

`PriceStream` has a single server-streaming RPC, `Subscribe`. The request selects which protocols to receive; an empty list streams all of them.

```proto theme={null}
syntax = "proto3";
package dexploit.v1;

service PriceStream {
  // Stream of DexTransaction price updates, filtered by protocol.
  rpc Subscribe(SubscribeRequest) returns (stream DexTransaction);
}

message SubscribeRequest {
  // "pumpfun" | "pumpswap" | "clmm" | "cpmm" | "amm"
  // Empty list = all protocols.
  repeated string protocols = 1;
}

message DexTransaction {
  string signature      = 1;
  string pair_id        = 2;   // pool / bonding-curve address
  string token_address  = 3;   // base token (the token being priced)
  string mint           = 4;   // quote currency (SOL or stablecoin)
  double price          = 5;   // quote per base token
  double token_balance  = 6;   // base reserve, decimal-adjusted
  double sol_balance    = 7;   // quote reserve, decimal-adjusted
  optional double liquidity = 8;   // TVL; CLMM/CPMM/AMM only
  optional string creator   = 9;   // PumpFun only
  ProtocolType protocol     = 10;
  uint32 schema_version     = 11;
}

enum ProtocolType {
  PROTOCOL_UNSPECIFIED = 0;
  PROTOCOL_PUMPFUN     = 1;
  PROTOCOL_PUMPSWAP    = 2;
  PROTOCOL_CLMM        = 3;
  PROTOCOL_CPMM        = 4;
  PROTOCOL_AMM         = 5;
}
```

`price`, `token_balance`, and `sol_balance` are already decimal-adjusted doubles (not raw lamports/atomic units). `liquidity` and `creator` are protocol-specific and absent on some venues.

## Complete TypeScript client

Install:

```bash theme={null}
npm i @grpc/grpc-js @grpc/proto-loader
```

Save the proto above as `./proto/price_stream.proto`, then:

```typescript theme={null}
import * as grpc from '@grpc/grpc-js';
import * as protoLoader from '@grpc/proto-loader';
import path from 'path';

const ENDPOINT = 'grpc.dexploit.dev:443';
const API_KEY  = 'ohlcv_live_sk_<your_key>';

const PROTO_PATH = path.join(__dirname, 'proto', 'price_stream.proto');
const def = protoLoader.loadSync(PROTO_PATH, {
  keepCase: true,
  longs: String,
  enums: String,
  defaults: true,
  oneofs: true,
});
const proto = grpc.loadPackageDefinition(def) as any;

const creds = grpc.credentials.combineChannelCredentials(
  grpc.credentials.createSsl(),
  grpc.credentials.createFromMetadataGenerator((_params, cb) => {
    const md = new grpc.Metadata();
    md.add('x-api-key', API_KEY);
    cb(null, md);
  })
);

const client = new proto.dexploit.v1.PriceStream(ENDPOINT, creds, {
  // Mandatory — without these, half-open TCP hangs look like a stalled stream.
  'grpc.keepalive_time_ms': 30_000,
  'grpc.keepalive_timeout_ms': 10_000,
  'grpc.keepalive_permit_without_calls': 1,
});

// Empty protocols = every protocol. Or e.g. { protocols: ['clmm', 'cpmm'] }.
const call = client.Subscribe({ protocols: [] });

call.on('data', (tx: any) => {
  console.log(
    `${tx.protocol} ${tx.token_address.slice(0, 8)}… ` +
    `price=${tx.price.toExponential(3)} tvl=${tx.sol_balance.toFixed(2)} SOL ` +
    `(${tx.signature.slice(0, 8)}…)`
  );
});

call.on('error', (err: Error) => console.error('stream error:', err.message));
call.on('end',   ()           => console.warn('stream ended'));
```

The keepalive options are not optional — see [Reconnect & backpressure](/streaming/reconnect-backpressure) for why and what to do when the stream drops.

## Other languages

Run `protoc` against the proto to generate clients for any language gRPC supports. Idiomatic examples for Rust (`tonic`), Python (`grpcio`), and TypeScript live in [DexploitV1/Dexploit-Examples](https://github.com/DexploitV1/Dexploit-Examples).
