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.0.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.0.0-py3-none-any.whl (18.2 kB view details)

Uploaded Python 3

File details

Details for the file sbo3l_sdk-1.0.0.tar.gz.

File metadata

  • Download URL: sbo3l_sdk-1.0.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.0.0.tar.gz
Algorithm Hash digest
SHA256 d481ce1fecc23c2fed56404258a611203f5c90e3e0c4ac3e6d808274a53c1069
MD5 ffda087b78f6e32268e8dcebcffe9c35
BLAKE2b-256 fb3fee2589baba8a1925efb80a10e8f54e2419e644e707c9cf2781e38482ebe5

See more details on using hashes here.

Provenance

The following attestation bundles were made for sbo3l_sdk-1.0.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.0.0-py3-none-any.whl.

File metadata

  • Download URL: sbo3l_sdk-1.0.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.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a047d66946c89093a4bfae4cc16acc354b5b545961376bb0534d7d9b0564259f
MD5 2d81f21c47d49ea4e3b39570b6619a98
BLAKE2b-256 fb4f16821ccd6ce04e5460e25e641e29ce192a8154f5f6fcec4d38bfb53f00e5

See more details on using hashes here.

Provenance

The following attestation bundles were made for sbo3l_sdk-1.0.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