Skip to main content

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-requests wrapped as a typed submit() method (async-first via httpx.AsyncClient, sync mirror via httpx.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


Download files

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

Source Distribution

sbo3l_sdk-1.2.0.tar.gz (19.7 kB view details)

Uploaded Source

Built Distribution

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

sbo3l_sdk-1.2.0-py3-none-any.whl (18.2 kB view details)

Uploaded Python 3

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

Hashes for sbo3l_sdk-1.2.0.tar.gz
Algorithm Hash digest
SHA256 e52c27f59c1e1f6dd866776a4f3c14cdf94a61d29520a2b2dac3548a008d8484
MD5 48c7c70b7c6629501d42a040982ab5b4
BLAKE2b-256 8ff382e67e3a7c223b5ca4375184d284814b05dbf1881ff0a3534081c686e270

See more details on using hashes here.

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

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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

Hashes for sbo3l_sdk-1.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 727a999d4097a6b7b71306bfbd5fbcb4a9c99dd608ceb4bb7809b8fc54ff6c7d
MD5 0fcca0a60c6a9aca6ee5387f8d159468
BLAKE2b-256 9c99cf3b1b89dd3ffcea793291c4c50dc6a3eb5ac5f3ea2a8e02c8efe86437f2

See more details on using hashes here.

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

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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