Skip to main content

Decoded ShredStream — Python client

Python client for the Decoded ShredStream of ShredStream.com: pre-execution Solana transactions, decoded from shreds — the serialized VersionedTransaction, its signatures and its slot, delivered over gRPC or UDP push the moment they propagate.

Before execution — transactions carry no status, logs, balance changes or inner instructions, and some will fail on-chain. Use a post-execution source to confirm.

The client is synchronous and blocking: iterating it returns one transaction at a time on the calling thread.

pip install decoded-shredstream
from decoded_shredstream import Client, Filter, GrpcConfig

with Client.grpc(GrpcConfig(endpoint=endpoint, token=token,
                            filters={"all": Filter()})) as client:
    for update in client:
        print(update.slot, update.signature)

Requirements — Python 3.10 or later, and a Decoded ShredStream subscription on ShredStream.com. Extras: solana for parse(), fast for a Rust base58.

With the extras:

pip install "decoded-shredstream[solana,fast]"

🔑 Access

Decoded ShredStream is a subscription product, available from ShredStream.com. One subscription covers both transports, and you can move from one to the other whenever you need to.

  • gRPC — you receive an endpoint and an access token. Use the endpoint exactly as issued.
  • UDP — you register your server's IP and port; datagrams are pushed to it.

Choosing a transport

Both carry the same data; they differ on what the protocol guarantees.

gRPC UDP
Latency higher lowest
Delivery ordered, retransmitted best-effort, no retransmission
Server-side filters yes no — you receive the full stream

⚡ Quickstart — gRPC

from decoded_shredstream import Client, Filter, GrpcConfig

with Client.grpc(
    GrpcConfig(
        endpoint="your-endpoint.shredstream.com:PORT",
        token="YOUR_TOKEN",
        filters={"all": Filter()},
    )
) as client:
    for update in client:
        print(update.slot, len(update.data), list(update.filters))

Client.grpc connects and subscribes before returning.

📡 Quickstart — UDP

from decoded_shredstream import Client, UdpConfig

with Client.udp(UdpConfig(port=8002)) as client:
    print("listening on", client.local_addr)
    for update in client:
        print(update.slot, len(update.data), update.signature.hex())

8002 is only an example: bind whichever port you registered in your account.

🔍 Transaction parsing

Every transaction exposes update.data, in the standard Solana wire format, and its signatures without any decoding:

import base58

update.signature                              # first signature, raw 64 bytes
update.signatures                             # every signature
base58.b58encode(update.signature).decode()   # to display one

Everything else is available through parse(), which returns a solders.transaction.VersionedTransaction and requires the solana extra:

for update in client:
    message = update.parse().message
    keys = message.account_keys
    programs = {str(keys[ix.program_id_index]) for ix in message.instructions}
    print(update.slot, keys[0], len(message.instructions), sorted(programs))

Without the solana extra, parse() raises ImportError.

🎯 Filters

Filters exist on the gRPC transport only. They are evaluated by the server; the client never filters locally. UDP delivers the full stream.

A subscription carries a map of named filters. Each response is tagged with the names that matched it, exposed as update.filters.

from decoded_shredstream import Client, Filter, GrpcConfig

client = Client.grpc(
    GrpcConfig(
        endpoint=endpoint,
        token=token,
        filters={
            "watched": Filter(include=[account]),
            "everything": Filter(),
        },
    )
)

Semantics

A Filter holds three lists of base58 account keys, matched against the accounts a transaction touches. The three conditions are ANDed, and an empty list adds no constraint — Filter() matches every transaction.

List Matches when the transaction
include touches at least one of the accounts
exclude touches none of the accounts
required touches all of the accounts

Matching uses the account keys carried in the transaction, signers included. Addresses resolved through an Address Lookup Table cannot be filtered on. A transaction matching several filters is delivered once.

Replacing filters mid-stream

update_filters replaces the whole map atomically. The server applies it without a reconnect and without a gap in the data, and the new map is the one any later reconnection re-sends.

client.update_filters({"watched": Filter(include=[account])})

🔄 Errors & reconnection

Recoverable interruptions never reach you: the client reconnects on its own and re-sends the current filter map. Only a refused token, a session closed by the server and a rejected filter map end the stream, raised once by the iteration:

from decoded_shredstream import StreamError

try:
    for update in client:
        ...
except StreamError as e:
    print("stream ended:", e)

Every exception, the backoff policy and the telemetry notices are in docs/errors.md.

📖 Documentation

This README is what you need to receive transactions. The rest lives beside it:

Document Contents
docs/api.md Every type and method: clients, configuration, filters, updates, UDP codec, performance notes and counters
docs/errors.md Error types, reconnection policy, telemetry notices

💡 Examples

The examples/ directory contains runnable programs; each reads its configuration from the environment.

File Shows
udp_quickstart.py binding the registered port and printing transactions
grpc_quickstart.py connecting, subscribing to everything, printing transactions
grpc_filters.py named filters and replacing the map mid-stream
parse_transaction.py full parsing with solders
raw_bytes_pipeline.py forwarding update.data without parsing
low_latency.py the shape of a minimal consumption loop
DECODED_SHREDSTREAM_UDP_PORT=8002 python examples/udp_quickstart.py
DECODED_SHREDSTREAM_ENDPOINT=your-endpoint.shredstream.com:PORT DECODED_SHREDSTREAM_TOKEN=... python examples/grpc_quickstart.py
DECODED_SHREDSTREAM_ENDPOINT=your-endpoint.shredstream.com:PORT DECODED_SHREDSTREAM_TOKEN=... ACCOUNT=<base58> python examples/grpc_filters.py

⚖️ License

Apache-2.0. See LICENSE.

Release files for decoded-shredstream 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for decoded-shredstream 0.1.1
File Size Uploaded
decoded_shredstream-0.1.1.tar.gz 26.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for decoded-shredstream 0.1.1
File Interpreter ABI Platform
decoded_shredstream-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 55.3 kB

Release files / decoded_shredstream-0.1.1.tar.gz

Download URL decoded_shredstream-0.1.1.tar.gz
Size 26.8 kB
Tags Source
SHA-256 checksum
How to use checksums
0ffc866b2dad9db1c3d3197839c0a53b8f87ba207ded86c8c5d8a0992347b98c
BLAKE2b-256 checksum
How to use checksums
d5c47fb0d71d532aec887feadb2317e61c498f9202cc86e3ccef9fe4c98540de
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.9

Release files / decoded_shredstream-0.1.1-py3-none-any.whl

Download URL decoded_shredstream-0.1.1-py3-none-any.whl
Size 28.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
da6a2c73f033bc7ae00444971dbe5b220812a9cae87fc4a7af8ebc504f1ce390
BLAKE2b-256 checksum
How to use checksums
7f805960b4b0edef712cbdae06cdf6194b1685167baa3d93c84aafc6635f5822
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.9

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page