Skip to main content

Python SDK for PayPerByte — verified, provenance-first data for AI agents. No token; direct-allowance USDC settlement on Arbitrum.

Project description

payperbyte-sdk — PayPerByte Python SDK

Python SDK for PayPerByte (the BYTE Library data layer) — the verified, provenance-first data layer for AI agents. Discover first-party feeds, subscribe, stream payloads, and verify every payload against its on-chain EIP-712 attestation. No token; direct-allowance USDC settlement on Arbitrum.

Installation

pip install payperbyte-sdk

Keyless x402 pay-per-call support (the GatewayClient) needs the optional x402 stack:

pip install "payperbyte-sdk[x402]"

Quick Start

from eth_account import Account
from byte import (
    Publisher,
    Subscriber,
    Mercat,
    GatewayClient,
    verify_payload,
    HashMismatchError,
    ARBITRUM_SEPOLIA,
)

# 1. Discover — browse first-party feeds via the keyless x402 gateway catalog.
gw = GatewayClient(account=Account.from_key("0x..."))   # a wallet, NOT an API key
catalog = gw.discover()                                  # GET /feeds
for feed in catalog["feeds"]:
    print(feed["id"], feed["price"], feed["provenance"])

# Or discover publishers via the indexer (Mercat).
mercat = Mercat(ARBITRUM_SEPOLIA.indexer_url)
publishers = await mercat.search(topic="eth-price")

# 2. Subscribe — register in the social registry and approve DataStream to pull
#    per-message fees directly. No escrow, no deposit: your USDC stays in your
#    wallet until a message is actually settled. allowance_usdc is a 6-decimal
#    spend ceiling sized to cover the fees you expect to pay.
subscriber = Subscriber("0x...private_key...", ARBITRUM_SEPOLIA)
subscriber.subscribe(publishers[0]["address"], allowance_usdc=10.0)

# 3. Stream — receive payload events as the publisher broadcasts.
async for msg in subscriber.stream():
    payload = fetch_from_my_archive(msg["payload_hash"])

    # 4. Verify — keccak256(canonical bytes) vs the on-chain attested hash.
    #    Throws HashMismatchError if the bytes don't match what was attested.
    try:
        verify_payload(payload, msg["payload_hash"])
    except HashMismatchError:
        continue  # do NOT consume mismatched bytes
    consume(payload)

Keyless x402 (pay-per-call)

The GatewayClient mirrors the BYTE x402 gateway. It is keyless: a wallet signs the payment (EIP-3009 transferWithAuthorization, gasless — the facilitator broadcasts and pays gas). There is no API key anywhere.

from eth_account import Account
from byte import GatewayClient

gw = GatewayClient(account=Account.from_key("0x..."))    # defaults to https://x402.payperbyte.io
result = gw.fetch_feed("crypto-top100")                  # GET -> 402 -> sign USDC -> retry -> data
print(result["data"])
print(result["settlement"])        # {"success", "payer", "transaction"} (on-chain settle tx) or None
print(result["disclaimerCategory"])

POST oracle feeds (fact-oracle, evidence-pack, usc-statute) take a JSON body:

result = gw.fetch_feed("fact-oracle", body={
    "question": "What is the current US federal funds rate?",
    "subscriber_address": "0x...",   # REQUIRED — must already be registered on-chain with a DataStream USDC allowance
})

Two distinct USDC flows. The on-chain settlement leg (Subscriber.subscribe → register in DataRegistry + approve DataStream as a direct USDC spender) is independent of the x402 gateway payment (GatewayClient → EIP-3009 at fetch time). For fact-oracle, the subscriber must already be registered with a DataStream allowance before the x402 POST succeeds.

Features

  • Feed discovery — browse the x402 gateway catalog (GatewayClient.discover) or search publishers via the indexer (Mercat)
  • Subscription management — subscribe, unsubscribe, check status (direct-allowance USDC settlement; the SDK approves DataStream as a direct spender)
  • Data streaming — publish and receive payloads via DataStream
  • Payload verification — every payload carries an EIP-712 PayloadAttestation; verify keccak256(canonical bytes) against the on-chain hash before acting on the data
  • Keyless x402 — pay-per-call feed access with a wallet (EIP-3009), no API key
  • Provenance — read publisher status, subscriber/message counts, and revenue from the on-chain registry

Network Support

Network Chain ID Status
Arbitrum Sepolia 421614 Live (testnet)
Arbitrum One 42161 Planned (mainnet, audit-gated)

PayPerByte contracts

PayPerByte is a lean 3-contract core. No token; all settlement is in external USDC. Subscriptions are a direct ERC-20 allowance — there is no escrow contract. A subscriber registers in DataRegistry and grants DataStream a USDC allowance; DataStream pulls the exact per-message fee with transferFrom at publish time, so funds stay in the subscriber's wallet until a message is settled. Each payload carries an EIP-712 PayloadAttestation so subscribers can confirm exactly what they received and from whom.

Contract Role
DataRegistry Publisher registration; subscriber social registry (subscribe / unsubscribe / isSubscribed)
DataStream Per-message payload settlement; pulls fees via direct USDC allowance
SchemaRegistry Feed schema + methodology references

Contract and settlement-USDC addresses are resolved per-network by the SDK (ARBITRUM_SEPOLIA, LOCAL_ANVIL).

Canonical payload bytes

Publish-side and verify-side hashing both use the same canonical form (byte.canonical): UTF-8 of JSON with recursively lexicographically-sorted object keys and no insignificant whitespace. This guarantees keccak256 parity across the publish/verify boundary and between the Python and TypeScript SDKs. Keep payload values to strings, bools, and integers that round-trip identically across languages (or pre-stringify floats); full RFC-8785/JCS float/large-integer normalization is out of scope.

Modules

  • ByteClient — low-level client holding the web3 contract instances (used by Publisher/Subscriber)
  • Publisher — register a feed, publish data, sign EIP-712 PayloadAttestations
  • Subscriber — subscribe (register in DataRegistry + approve DataStream as a direct USDC spender), receive payloads, stream events
  • GatewayClient — keyless x402 pay-per-call client (a wallet, not an API key)
  • verify_payload / verify_event_payload / fetch_and_verify — subscriber-side payload verification against on-chain attestations
  • Mercat — feed search and discovery (connects to the indexer API)

Related

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

payperbyte_sdk-0.1.0.tar.gz (24.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

payperbyte_sdk-0.1.0-py3-none-any.whl (25.4 kB view details)

Uploaded Python 3

File details

Details for the file payperbyte_sdk-0.1.0.tar.gz.

File metadata

  • Download URL: payperbyte_sdk-0.1.0.tar.gz
  • Upload date:
  • Size: 24.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for payperbyte_sdk-0.1.0.tar.gz
Algorithm Hash digest
SHA256 116cc32637c2bc83d862edd864c17cc4f2916c727f22b0d3327a2bd776490176
MD5 0aae9d1e5500f9b4afc81ad94591ff40
BLAKE2b-256 95dbdf2cc10c5391a705692dd9ae5d902ada80e4aaa2d2f199ebc740313b8195

See more details on using hashes here.

File details

Details for the file payperbyte_sdk-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: payperbyte_sdk-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 25.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for payperbyte_sdk-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 22ea26ded2c8e6de44de3db74ae8adadffaf2c75a2d4810782ddf9edac03aae7
MD5 d29bd2efe62e52d4d08289b554685416
BLAKE2b-256 5adc347edfdf2018b766b85a275812829270f0a5b87ddf71e3dd0d1c109cb2ac

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page