Official Python SDK for SBO3L — the cryptographically verifiable trust layer for autonomous AI agents.
Project description
sbo3l-sdk
Official Python SDK for SBO3L — the cryptographically verifiable trust layer for autonomous AI agents.
Don't give your agent a wallet. Give it a mandate.
⚠ Status — DRAFT (F-10): package metadata, public API, and v2 capsule support are scaffolded against the v1 schemas. Final shape is gated on F-1 (auth middleware ✅ merged) and F-6 (capsule v2 schema, pending). Do not publish to PyPI until F-6 lands. Tracked in
docs/win-backlog/05-phase-1.md.
What it does
POST /v1/payment-requestswrapped as a typedsubmit()method (async-first viahttpx.AsyncClient, sync mirror viahttpx.Client).- Pydantic v2 strict wire types for APRP, PolicyReceipt, and the Passport capsule (v1 + v2 hooks). Strict-frozen models reject unknown fields end-to-end.
- Bearer + JWT auth helpers that match the F-1 daemon contract.
- Client-side structural verifier for Passport capsules. The
cryptographic checks live in the Rust CLI
sbo3l-cli passport verify --strict— this SDK does the structural and cross-field checks so callers can fail fast in Python before round-tripping.
Install
pip install sbo3l-sdk
Requires Python ≥ 3.10.
Quick start (async)
import asyncio
from sbo3l_sdk import SBO3LClient, bearer
async def main() -> None:
async with SBO3LClient(
"http://localhost:8730",
auth=bearer("my-bearer-token"),
) as client:
response = await client.submit({
"agent_id": "research-agent-01",
"task_id": "demo-task-1",
"intent": "purchase_api_call",
"amount": {"value": "0.05", "currency": "USD"},
"token": "USDC",
"destination": {
"type": "x402_endpoint",
"url": "https://api.example.com/v1/inference",
"method": "POST",
},
"payment_protocol": "x402",
"chain": "base",
"provider_url": "https://api.example.com",
"expiry": "2026-05-01T10:31:00Z",
"nonce": "01HTAWX5K3R8YV9NQB7C6P2DGM",
"risk_class": "low",
})
if response.decision == "allow":
print("execution_ref:", response.receipt.execution_ref)
asyncio.run(main())
Sync variant
from sbo3l_sdk import SBO3LClientSync, bearer
with SBO3LClientSync("http://localhost:8730", auth=bearer("tok")) as client:
response = client.submit(aprp_dict)
The sync client uses httpx.Client directly (no asyncio.run shim), so it's
safe to use even from within a running event loop.
JWT auth (per-agent)
from sbo3l_sdk import SBO3LClient, jwt, assert_jwt_sub_matches
token = await my_signer.sign({"sub": "research-agent-01", "iat": now()})
assert_jwt_sub_matches(token, "research-agent-01") # local sanity check
async with SBO3LClient("http://localhost:8730", auth=jwt(token)) as client:
...
The SDK never holds a private key. The sub == agent_id match is enforced
server-side (F-1); the client-side assert_jwt_sub_matches is a fail-fast
convenience.
Idempotency-safe retry
import secrets
key = secrets.token_hex(20) # 40 ASCII chars
await client.submit(aprp, idempotency_key=key) # first call
await client.submit(aprp, idempotency_key=key) # cached envelope, no side effects
Same key + different body → HTTP 409 protocol.idempotency_conflict.
Verifying a capsule client-side
import json
from sbo3l_sdk import verify
capsule = json.loads(open("capsule.json").read())
result = verify(capsule)
if not result.ok:
for f in result.failures:
print(f"[{f.code}] {f.description}: {f.detail or ''}")
For full crypto verification, use the Rust CLI:
sbo3l-cli passport verify --strict --path capsule.json
Errors
| Class | When |
|---|---|
SBO3LError |
Daemon returned a non-2xx. Carries the RFC 7807 problem-detail; .code and .status are first-class. |
SBO3LTransportError |
Network/transport failure (timeout, DNS, refused). |
PassportVerificationError |
Raised by verify_or_raise(). Carries .codes (tuple of failure codes). |
from sbo3l_sdk import SBO3LError
try:
await client.submit(aprp)
except SBO3LError as e:
if e.code == "auth.required":
# re-acquire token
...
else:
raise
Compatibility
- Python: ≥ 3.10.
- Pydantic: v2.6+ (strict mode).
- httpx: 0.27+.
- Daemon: SBO3L server
0.1.0+.
Development
python3 -m venv .venv
.venv/bin/pip install -e ".[dev]"
.venv/bin/pytest
.venv/bin/ruff check .
.venv/bin/mypy --strict sbo3l_sdk
License
MIT — see LICENSE at the repo root.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sbo3l_sdk-1.2.0.tar.gz.
File metadata
- Download URL: sbo3l_sdk-1.2.0.tar.gz
- Upload date:
- Size: 19.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e52c27f59c1e1f6dd866776a4f3c14cdf94a61d29520a2b2dac3548a008d8484
|
|
| MD5 |
48c7c70b7c6629501d42a040982ab5b4
|
|
| BLAKE2b-256 |
8ff382e67e3a7c223b5ca4375184d284814b05dbf1881ff0a3534081c686e270
|
Provenance
The following attestation bundles were made for sbo3l_sdk-1.2.0.tar.gz:
Publisher:
sdk-python.yml on B2JK-Industry/SBO3L-ethglobal-openagents-2026
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sbo3l_sdk-1.2.0.tar.gz -
Subject digest:
e52c27f59c1e1f6dd866776a4f3c14cdf94a61d29520a2b2dac3548a008d8484 - Sigstore transparency entry: 1429000703
- Sigstore integration time:
-
Permalink:
B2JK-Industry/SBO3L-ethglobal-openagents-2026@2353b521f499b87df92491bd1a57ca8d978cbd08 -
Branch / Tag:
refs/tags/sdk-py-v1.2.0 - Owner: https://github.com/B2JK-Industry
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
sdk-python.yml@2353b521f499b87df92491bd1a57ca8d978cbd08 -
Trigger Event:
push
-
Statement type:
File details
Details for the file sbo3l_sdk-1.2.0-py3-none-any.whl.
File metadata
- Download URL: sbo3l_sdk-1.2.0-py3-none-any.whl
- Upload date:
- Size: 18.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
727a999d4097a6b7b71306bfbd5fbcb4a9c99dd608ceb4bb7809b8fc54ff6c7d
|
|
| MD5 |
0fcca0a60c6a9aca6ee5387f8d159468
|
|
| BLAKE2b-256 |
9c99cf3b1b89dd3ffcea793291c4c50dc6a3eb5ac5f3ea2a8e02c8efe86437f2
|
Provenance
The following attestation bundles were made for sbo3l_sdk-1.2.0-py3-none-any.whl:
Publisher:
sdk-python.yml on B2JK-Industry/SBO3L-ethglobal-openagents-2026
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sbo3l_sdk-1.2.0-py3-none-any.whl -
Subject digest:
727a999d4097a6b7b71306bfbd5fbcb4a9c99dd608ceb4bb7809b8fc54ff6c7d - Sigstore transparency entry: 1429000708
- Sigstore integration time:
-
Permalink:
B2JK-Industry/SBO3L-ethglobal-openagents-2026@2353b521f499b87df92491bd1a57ca8d978cbd08 -
Branch / Tag:
refs/tags/sdk-py-v1.2.0 - Owner: https://github.com/B2JK-Industry
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
sdk-python.yml@2353b521f499b87df92491bd1a57ca8d978cbd08 -
Trigger Event:
push
-
Statement type: