payperbyte-sdk 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- payperbyte_sdk-0.1.0/PKG-INFO +167 -0
- payperbyte_sdk-0.1.0/README.md +147 -0
- payperbyte_sdk-0.1.0/byte/__init__.py +53 -0
- payperbyte_sdk-0.1.0/byte/abis/DataRegistry.json +341 -0
- payperbyte_sdk-0.1.0/byte/abis/DataStream.json +773 -0
- payperbyte_sdk-0.1.0/byte/abis/SchemaRegistry.json +432 -0
- payperbyte_sdk-0.1.0/byte/canonical.py +42 -0
- payperbyte_sdk-0.1.0/byte/client.py +64 -0
- payperbyte_sdk-0.1.0/byte/gateway.py +267 -0
- payperbyte_sdk-0.1.0/byte/mercat.py +40 -0
- payperbyte_sdk-0.1.0/byte/networks.py +62 -0
- payperbyte_sdk-0.1.0/byte/publisher.py +174 -0
- payperbyte_sdk-0.1.0/byte/subscriber.py +167 -0
- payperbyte_sdk-0.1.0/byte/verify.py +157 -0
- payperbyte_sdk-0.1.0/payperbyte_sdk.egg-info/PKG-INFO +167 -0
- payperbyte_sdk-0.1.0/payperbyte_sdk.egg-info/SOURCES.txt +19 -0
- payperbyte_sdk-0.1.0/payperbyte_sdk.egg-info/dependency_links.txt +1 -0
- payperbyte_sdk-0.1.0/payperbyte_sdk.egg-info/requires.txt +8 -0
- payperbyte_sdk-0.1.0/payperbyte_sdk.egg-info/top_level.txt +1 -0
- payperbyte_sdk-0.1.0/setup.cfg +4 -0
- payperbyte_sdk-0.1.0/setup.py +32 -0
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: payperbyte-sdk
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Python SDK for PayPerByte — verified, provenance-first data for AI agents. No token; direct-allowance USDC settlement on Arbitrum.
|
|
5
|
+
Requires-Python: >=3.10
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
Requires-Dist: web3>=6.0
|
|
8
|
+
Requires-Dist: aiohttp>=3.9
|
|
9
|
+
Provides-Extra: x402
|
|
10
|
+
Requires-Dist: x402[evm,requests]==2.12.0; extra == "x402"
|
|
11
|
+
Requires-Dist: eth-account==0.13.7; extra == "x402"
|
|
12
|
+
Requires-Dist: web3==7.16.0; extra == "x402"
|
|
13
|
+
Requires-Dist: requests==2.34.2; extra == "x402"
|
|
14
|
+
Dynamic: description
|
|
15
|
+
Dynamic: description-content-type
|
|
16
|
+
Dynamic: provides-extra
|
|
17
|
+
Dynamic: requires-dist
|
|
18
|
+
Dynamic: requires-python
|
|
19
|
+
Dynamic: summary
|
|
20
|
+
|
|
21
|
+
# payperbyte-sdk — PayPerByte Python SDK
|
|
22
|
+
|
|
23
|
+
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.
|
|
24
|
+
|
|
25
|
+
## Installation
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
pip install payperbyte-sdk
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Keyless x402 pay-per-call support (the `GatewayClient`) needs the optional x402 stack:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
pip install "payperbyte-sdk[x402]"
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Quick Start
|
|
38
|
+
|
|
39
|
+
```python
|
|
40
|
+
from eth_account import Account
|
|
41
|
+
from byte import (
|
|
42
|
+
Publisher,
|
|
43
|
+
Subscriber,
|
|
44
|
+
Mercat,
|
|
45
|
+
GatewayClient,
|
|
46
|
+
verify_payload,
|
|
47
|
+
HashMismatchError,
|
|
48
|
+
ARBITRUM_SEPOLIA,
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
# 1. Discover — browse first-party feeds via the keyless x402 gateway catalog.
|
|
52
|
+
gw = GatewayClient(account=Account.from_key("0x...")) # a wallet, NOT an API key
|
|
53
|
+
catalog = gw.discover() # GET /feeds
|
|
54
|
+
for feed in catalog["feeds"]:
|
|
55
|
+
print(feed["id"], feed["price"], feed["provenance"])
|
|
56
|
+
|
|
57
|
+
# Or discover publishers via the indexer (Mercat).
|
|
58
|
+
mercat = Mercat(ARBITRUM_SEPOLIA.indexer_url)
|
|
59
|
+
publishers = await mercat.search(topic="eth-price")
|
|
60
|
+
|
|
61
|
+
# 2. Subscribe — register in the social registry and approve DataStream to pull
|
|
62
|
+
# per-message fees directly. No escrow, no deposit: your USDC stays in your
|
|
63
|
+
# wallet until a message is actually settled. allowance_usdc is a 6-decimal
|
|
64
|
+
# spend ceiling sized to cover the fees you expect to pay.
|
|
65
|
+
subscriber = Subscriber("0x...private_key...", ARBITRUM_SEPOLIA)
|
|
66
|
+
subscriber.subscribe(publishers[0]["address"], allowance_usdc=10.0)
|
|
67
|
+
|
|
68
|
+
# 3. Stream — receive payload events as the publisher broadcasts.
|
|
69
|
+
async for msg in subscriber.stream():
|
|
70
|
+
payload = fetch_from_my_archive(msg["payload_hash"])
|
|
71
|
+
|
|
72
|
+
# 4. Verify — keccak256(canonical bytes) vs the on-chain attested hash.
|
|
73
|
+
# Throws HashMismatchError if the bytes don't match what was attested.
|
|
74
|
+
try:
|
|
75
|
+
verify_payload(payload, msg["payload_hash"])
|
|
76
|
+
except HashMismatchError:
|
|
77
|
+
continue # do NOT consume mismatched bytes
|
|
78
|
+
consume(payload)
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Keyless x402 (pay-per-call)
|
|
82
|
+
|
|
83
|
+
The `GatewayClient` mirrors the BYTE x402 gateway. It is **keyless**: a wallet signs the
|
|
84
|
+
payment (EIP-3009 `transferWithAuthorization`, gasless — the facilitator broadcasts and
|
|
85
|
+
pays gas). There is **no API key** anywhere.
|
|
86
|
+
|
|
87
|
+
```python
|
|
88
|
+
from eth_account import Account
|
|
89
|
+
from byte import GatewayClient
|
|
90
|
+
|
|
91
|
+
gw = GatewayClient(account=Account.from_key("0x...")) # defaults to https://x402.payperbyte.io
|
|
92
|
+
result = gw.fetch_feed("crypto-top100") # GET -> 402 -> sign USDC -> retry -> data
|
|
93
|
+
print(result["data"])
|
|
94
|
+
print(result["settlement"]) # {"success", "payer", "transaction"} (on-chain settle tx) or None
|
|
95
|
+
print(result["disclaimerCategory"])
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
POST oracle feeds (`fact-oracle`, `evidence-pack`, `usc-statute`) take a JSON body:
|
|
99
|
+
|
|
100
|
+
```python
|
|
101
|
+
result = gw.fetch_feed("fact-oracle", body={
|
|
102
|
+
"question": "What is the current US federal funds rate?",
|
|
103
|
+
"subscriber_address": "0x...", # REQUIRED — must already be registered on-chain with a DataStream USDC allowance
|
|
104
|
+
})
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
> **Two distinct USDC flows.** The on-chain settlement leg (Subscriber.subscribe →
|
|
108
|
+
> register in DataRegistry + approve DataStream as a direct USDC spender) is
|
|
109
|
+
> independent of the x402 gateway payment (GatewayClient → EIP-3009 at fetch time).
|
|
110
|
+
> For `fact-oracle`, the subscriber must already be registered with a DataStream
|
|
111
|
+
> allowance *before* the x402 POST succeeds.
|
|
112
|
+
|
|
113
|
+
## Features
|
|
114
|
+
|
|
115
|
+
- **Feed discovery** — browse the x402 gateway catalog (`GatewayClient.discover`) or search publishers via the indexer (`Mercat`)
|
|
116
|
+
- **Subscription management** — subscribe, unsubscribe, check status (direct-allowance USDC settlement; the SDK approves DataStream as a direct spender)
|
|
117
|
+
- **Data streaming** — publish and receive payloads via DataStream
|
|
118
|
+
- **Payload verification** — every payload carries an EIP-712 PayloadAttestation; verify `keccak256(canonical bytes)` against the on-chain hash before acting on the data
|
|
119
|
+
- **Keyless x402** — pay-per-call feed access with a wallet (EIP-3009), no API key
|
|
120
|
+
- **Provenance** — read publisher status, subscriber/message counts, and revenue from the on-chain registry
|
|
121
|
+
|
|
122
|
+
## Network Support
|
|
123
|
+
|
|
124
|
+
| Network | Chain ID | Status |
|
|
125
|
+
|---------|----------|--------|
|
|
126
|
+
| Arbitrum Sepolia | 421614 | Live (testnet) |
|
|
127
|
+
| Arbitrum One | 42161 | Planned (mainnet, audit-gated) |
|
|
128
|
+
|
|
129
|
+
## PayPerByte contracts
|
|
130
|
+
|
|
131
|
+
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.
|
|
132
|
+
|
|
133
|
+
| Contract | Role |
|
|
134
|
+
|----------|------|
|
|
135
|
+
| DataRegistry | Publisher registration; subscriber social registry (`subscribe` / `unsubscribe` / `isSubscribed`) |
|
|
136
|
+
| DataStream | Per-message payload settlement; pulls fees via direct USDC allowance |
|
|
137
|
+
| SchemaRegistry | Feed schema + methodology references |
|
|
138
|
+
|
|
139
|
+
Contract and settlement-USDC addresses are resolved per-network by the SDK (`ARBITRUM_SEPOLIA`, `LOCAL_ANVIL`).
|
|
140
|
+
|
|
141
|
+
## Canonical payload bytes
|
|
142
|
+
|
|
143
|
+
Publish-side and verify-side hashing both use the same canonical form (`byte.canonical`):
|
|
144
|
+
UTF-8 of JSON with recursively lexicographically-sorted object keys and no insignificant
|
|
145
|
+
whitespace. This guarantees `keccak256` parity across the publish/verify boundary **and**
|
|
146
|
+
between the Python and TypeScript SDKs. Keep payload values to strings, bools, and integers
|
|
147
|
+
that round-trip identically across languages (or pre-stringify floats); full RFC-8785/JCS
|
|
148
|
+
float/large-integer normalization is out of scope.
|
|
149
|
+
|
|
150
|
+
## Modules
|
|
151
|
+
|
|
152
|
+
- `ByteClient` — low-level client holding the web3 contract instances (used by `Publisher`/`Subscriber`)
|
|
153
|
+
- `Publisher` — register a feed, publish data, sign EIP-712 PayloadAttestations
|
|
154
|
+
- `Subscriber` — subscribe (register in DataRegistry + approve DataStream as a direct USDC spender), receive payloads, stream events
|
|
155
|
+
- `GatewayClient` — keyless x402 pay-per-call client (a wallet, not an API key)
|
|
156
|
+
- `verify_payload` / `verify_event_payload` / `fetch_and_verify` — subscriber-side payload verification against on-chain attestations
|
|
157
|
+
- `Mercat` — feed search and discovery (connects to the indexer API)
|
|
158
|
+
|
|
159
|
+
## Related
|
|
160
|
+
|
|
161
|
+
- [byte-mcp-server](https://github.com/0rkz/byte-mcp-server) — MCP server for AI agent integration
|
|
162
|
+
- [byte-x402-gateway](https://github.com/0rkz/byte-x402-gateway) — keyless x402 payment gateway (a wallet, not an API key)
|
|
163
|
+
- [byte-discovery-api](https://github.com/0rkz/byte-discovery-api) — agent discovery endpoint
|
|
164
|
+
|
|
165
|
+
## License
|
|
166
|
+
|
|
167
|
+
MIT
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# payperbyte-sdk — PayPerByte Python SDK
|
|
2
|
+
|
|
3
|
+
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.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install payperbyte-sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Keyless x402 pay-per-call support (the `GatewayClient`) needs the optional x402 stack:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
pip install "payperbyte-sdk[x402]"
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Quick Start
|
|
18
|
+
|
|
19
|
+
```python
|
|
20
|
+
from eth_account import Account
|
|
21
|
+
from byte import (
|
|
22
|
+
Publisher,
|
|
23
|
+
Subscriber,
|
|
24
|
+
Mercat,
|
|
25
|
+
GatewayClient,
|
|
26
|
+
verify_payload,
|
|
27
|
+
HashMismatchError,
|
|
28
|
+
ARBITRUM_SEPOLIA,
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
# 1. Discover — browse first-party feeds via the keyless x402 gateway catalog.
|
|
32
|
+
gw = GatewayClient(account=Account.from_key("0x...")) # a wallet, NOT an API key
|
|
33
|
+
catalog = gw.discover() # GET /feeds
|
|
34
|
+
for feed in catalog["feeds"]:
|
|
35
|
+
print(feed["id"], feed["price"], feed["provenance"])
|
|
36
|
+
|
|
37
|
+
# Or discover publishers via the indexer (Mercat).
|
|
38
|
+
mercat = Mercat(ARBITRUM_SEPOLIA.indexer_url)
|
|
39
|
+
publishers = await mercat.search(topic="eth-price")
|
|
40
|
+
|
|
41
|
+
# 2. Subscribe — register in the social registry and approve DataStream to pull
|
|
42
|
+
# per-message fees directly. No escrow, no deposit: your USDC stays in your
|
|
43
|
+
# wallet until a message is actually settled. allowance_usdc is a 6-decimal
|
|
44
|
+
# spend ceiling sized to cover the fees you expect to pay.
|
|
45
|
+
subscriber = Subscriber("0x...private_key...", ARBITRUM_SEPOLIA)
|
|
46
|
+
subscriber.subscribe(publishers[0]["address"], allowance_usdc=10.0)
|
|
47
|
+
|
|
48
|
+
# 3. Stream — receive payload events as the publisher broadcasts.
|
|
49
|
+
async for msg in subscriber.stream():
|
|
50
|
+
payload = fetch_from_my_archive(msg["payload_hash"])
|
|
51
|
+
|
|
52
|
+
# 4. Verify — keccak256(canonical bytes) vs the on-chain attested hash.
|
|
53
|
+
# Throws HashMismatchError if the bytes don't match what was attested.
|
|
54
|
+
try:
|
|
55
|
+
verify_payload(payload, msg["payload_hash"])
|
|
56
|
+
except HashMismatchError:
|
|
57
|
+
continue # do NOT consume mismatched bytes
|
|
58
|
+
consume(payload)
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Keyless x402 (pay-per-call)
|
|
62
|
+
|
|
63
|
+
The `GatewayClient` mirrors the BYTE x402 gateway. It is **keyless**: a wallet signs the
|
|
64
|
+
payment (EIP-3009 `transferWithAuthorization`, gasless — the facilitator broadcasts and
|
|
65
|
+
pays gas). There is **no API key** anywhere.
|
|
66
|
+
|
|
67
|
+
```python
|
|
68
|
+
from eth_account import Account
|
|
69
|
+
from byte import GatewayClient
|
|
70
|
+
|
|
71
|
+
gw = GatewayClient(account=Account.from_key("0x...")) # defaults to https://x402.payperbyte.io
|
|
72
|
+
result = gw.fetch_feed("crypto-top100") # GET -> 402 -> sign USDC -> retry -> data
|
|
73
|
+
print(result["data"])
|
|
74
|
+
print(result["settlement"]) # {"success", "payer", "transaction"} (on-chain settle tx) or None
|
|
75
|
+
print(result["disclaimerCategory"])
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
POST oracle feeds (`fact-oracle`, `evidence-pack`, `usc-statute`) take a JSON body:
|
|
79
|
+
|
|
80
|
+
```python
|
|
81
|
+
result = gw.fetch_feed("fact-oracle", body={
|
|
82
|
+
"question": "What is the current US federal funds rate?",
|
|
83
|
+
"subscriber_address": "0x...", # REQUIRED — must already be registered on-chain with a DataStream USDC allowance
|
|
84
|
+
})
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
> **Two distinct USDC flows.** The on-chain settlement leg (Subscriber.subscribe →
|
|
88
|
+
> register in DataRegistry + approve DataStream as a direct USDC spender) is
|
|
89
|
+
> independent of the x402 gateway payment (GatewayClient → EIP-3009 at fetch time).
|
|
90
|
+
> For `fact-oracle`, the subscriber must already be registered with a DataStream
|
|
91
|
+
> allowance *before* the x402 POST succeeds.
|
|
92
|
+
|
|
93
|
+
## Features
|
|
94
|
+
|
|
95
|
+
- **Feed discovery** — browse the x402 gateway catalog (`GatewayClient.discover`) or search publishers via the indexer (`Mercat`)
|
|
96
|
+
- **Subscription management** — subscribe, unsubscribe, check status (direct-allowance USDC settlement; the SDK approves DataStream as a direct spender)
|
|
97
|
+
- **Data streaming** — publish and receive payloads via DataStream
|
|
98
|
+
- **Payload verification** — every payload carries an EIP-712 PayloadAttestation; verify `keccak256(canonical bytes)` against the on-chain hash before acting on the data
|
|
99
|
+
- **Keyless x402** — pay-per-call feed access with a wallet (EIP-3009), no API key
|
|
100
|
+
- **Provenance** — read publisher status, subscriber/message counts, and revenue from the on-chain registry
|
|
101
|
+
|
|
102
|
+
## Network Support
|
|
103
|
+
|
|
104
|
+
| Network | Chain ID | Status |
|
|
105
|
+
|---------|----------|--------|
|
|
106
|
+
| Arbitrum Sepolia | 421614 | Live (testnet) |
|
|
107
|
+
| Arbitrum One | 42161 | Planned (mainnet, audit-gated) |
|
|
108
|
+
|
|
109
|
+
## PayPerByte contracts
|
|
110
|
+
|
|
111
|
+
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.
|
|
112
|
+
|
|
113
|
+
| Contract | Role |
|
|
114
|
+
|----------|------|
|
|
115
|
+
| DataRegistry | Publisher registration; subscriber social registry (`subscribe` / `unsubscribe` / `isSubscribed`) |
|
|
116
|
+
| DataStream | Per-message payload settlement; pulls fees via direct USDC allowance |
|
|
117
|
+
| SchemaRegistry | Feed schema + methodology references |
|
|
118
|
+
|
|
119
|
+
Contract and settlement-USDC addresses are resolved per-network by the SDK (`ARBITRUM_SEPOLIA`, `LOCAL_ANVIL`).
|
|
120
|
+
|
|
121
|
+
## Canonical payload bytes
|
|
122
|
+
|
|
123
|
+
Publish-side and verify-side hashing both use the same canonical form (`byte.canonical`):
|
|
124
|
+
UTF-8 of JSON with recursively lexicographically-sorted object keys and no insignificant
|
|
125
|
+
whitespace. This guarantees `keccak256` parity across the publish/verify boundary **and**
|
|
126
|
+
between the Python and TypeScript SDKs. Keep payload values to strings, bools, and integers
|
|
127
|
+
that round-trip identically across languages (or pre-stringify floats); full RFC-8785/JCS
|
|
128
|
+
float/large-integer normalization is out of scope.
|
|
129
|
+
|
|
130
|
+
## Modules
|
|
131
|
+
|
|
132
|
+
- `ByteClient` — low-level client holding the web3 contract instances (used by `Publisher`/`Subscriber`)
|
|
133
|
+
- `Publisher` — register a feed, publish data, sign EIP-712 PayloadAttestations
|
|
134
|
+
- `Subscriber` — subscribe (register in DataRegistry + approve DataStream as a direct USDC spender), receive payloads, stream events
|
|
135
|
+
- `GatewayClient` — keyless x402 pay-per-call client (a wallet, not an API key)
|
|
136
|
+
- `verify_payload` / `verify_event_payload` / `fetch_and_verify` — subscriber-side payload verification against on-chain attestations
|
|
137
|
+
- `Mercat` — feed search and discovery (connects to the indexer API)
|
|
138
|
+
|
|
139
|
+
## Related
|
|
140
|
+
|
|
141
|
+
- [byte-mcp-server](https://github.com/0rkz/byte-mcp-server) — MCP server for AI agent integration
|
|
142
|
+
- [byte-x402-gateway](https://github.com/0rkz/byte-x402-gateway) — keyless x402 payment gateway (a wallet, not an API key)
|
|
143
|
+
- [byte-discovery-api](https://github.com/0rkz/byte-discovery-api) — agent discovery endpoint
|
|
144
|
+
|
|
145
|
+
## License
|
|
146
|
+
|
|
147
|
+
MIT
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"""
|
|
2
|
+
payperbyte-sdk — Python SDK for PayPerByte (the BYTE Library data layer).
|
|
3
|
+
|
|
4
|
+
Verified, provenance-first data for AI agents. No token; settlement is in
|
|
5
|
+
external USDC on Arbitrum. Three on-chain contracts: DataRegistry (publisher /
|
|
6
|
+
subscriber social registry), SchemaRegistry (feed schemas), and DataStream
|
|
7
|
+
(per-message settlement). Subscribers approve DataStream as a direct USDC
|
|
8
|
+
spender — there is no escrow contract. Keyless x402 payments (a wallet, not an
|
|
9
|
+
API key) for pay-per-call feed access via the gateway.
|
|
10
|
+
|
|
11
|
+
Usage:
|
|
12
|
+
from byte import (
|
|
13
|
+
Publisher, Subscriber, GatewayClient,
|
|
14
|
+
verify_payload, HashMismatchError, ARBITRUM_SEPOLIA,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
# Publisher: register a schema + publisher (no token stake), then publish.
|
|
18
|
+
publisher = Publisher(private_key, ARBITRUM_SEPOLIA)
|
|
19
|
+
publisher.register("eth-price", schema)
|
|
20
|
+
publisher.publish(subscriber_addr, {"signal": "short"})
|
|
21
|
+
|
|
22
|
+
# Subscriber: register in the social registry + approve DataStream to pull
|
|
23
|
+
# per-message fees directly (no escrow / no deposit), then stream payloads.
|
|
24
|
+
subscriber = Subscriber(private_key, ARBITRUM_SEPOLIA)
|
|
25
|
+
subscriber.subscribe(publisher_addr, allowance_usdc=10.0)
|
|
26
|
+
async for msg in subscriber.stream():
|
|
27
|
+
payload = fetch_from_archive(msg["payload_hash"])
|
|
28
|
+
try:
|
|
29
|
+
verify_payload(payload, msg["payload_hash"]) # keccak256 vs attested hash
|
|
30
|
+
except HashMismatchError:
|
|
31
|
+
continue # do NOT consume mismatched bytes
|
|
32
|
+
consume(payload)
|
|
33
|
+
|
|
34
|
+
# Gateway: keyless x402 pay-per-call (a wallet signs EIP-3009; no API key).
|
|
35
|
+
from eth_account import Account
|
|
36
|
+
gw = GatewayClient(account=Account.from_key(private_key))
|
|
37
|
+
result = gw.fetch_feed("crypto-top100")
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
from byte.publisher import Publisher
|
|
41
|
+
from byte.subscriber import Subscriber
|
|
42
|
+
from byte.mercat import Mercat
|
|
43
|
+
from byte.client import ByteClient
|
|
44
|
+
from byte.gateway import GatewayClient
|
|
45
|
+
from byte.networks import ARBITRUM_SEPOLIA, ARBITRUM_ONE, LOCAL_ANVIL
|
|
46
|
+
from byte.verify import (
|
|
47
|
+
verify_payload, verify_event_payload, fetch_and_verify, HashMismatchError,
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
__all__ = ["Publisher", "Subscriber", "Mercat", "ByteClient", "GatewayClient",
|
|
51
|
+
"ARBITRUM_SEPOLIA", "ARBITRUM_ONE", "LOCAL_ANVIL",
|
|
52
|
+
"verify_payload", "verify_event_payload", "fetch_and_verify",
|
|
53
|
+
"HashMismatchError"]
|