Skip to content

stoka Python client (stoka-agent)

Python client for the stoka x402 API: per-request paid store / retrieve / update plus wallet-signed DELETE, GET /v1/me/usage, and POST /v1/profile.

Canonical package name: stoka-agent (import stoka_agent).

Two client classes

X402Client — paid object CRUD

Pay-per-request via the X-PAYMENT header. Because signing a Soroban auth entry is outside pure-Python's scope, the signer is pluggable:

python
from stoka_agent import X402Client, CallbackPaymentSigner

def sign(req):
    # req: PaymentRequirements (scheme, network, maxAmountRequired, payTo, asset, …)
    # Return a dict; the client JSON-encodes + base64-encodes it into the
    # X-PAYMENT header.
    #
    # In production: call the TS `x402-stellar` package via subprocess or
    # an RPC microservice, or a future Python Soroban signer.
    return {
        "x402Version": 2,
        "scheme": req.scheme,
        "network": req.network,
        "payload": {"transaction": "...base64 XDR..."},
    }

c = X402Client(base_url="https://stoka.example", signer=CallbackPaymentSigner(sign))
c.store("my/key", b"<ciphertext>")
c.retrieve("my/key", owner_hint="GABC…")  # optional hint → exact 402 quote
c.update("my/key", b"<new ciphertext>")

If you construct X402Client(signer=None) you can still introspect 402 challenges — the first paid call raises stoka_agent.PaymentRequired with a populated .requirements field (price, pay_to, asset, resource).

IdentityClient — wallet-signed identity

python
from stoka_agent import IdentityClient, StellarSigner

c = IdentityClient(signer=StellarSigner.from_secret("S…"))
c.bind_email("me@example.com")
c.usage(days=7)
c.delete("my/key")  # idempotent, free

All three endpoints use a short-lived, single-use challenge audience (profile-bind / me-usage / object-delete). A signature minted for one audience cannot be replayed against another.

MCP server

Ship stoka-mcp as an MCP server exposing the same calls:

  • stoka_discover
  • stoka_store / stoka_update / stoka_retrieve (honor $X_PAYMENT_CMD for signing)
  • stoka_delete / stoka_usage / stoka_profile_bind (honor $STELLAR_SECRET)

Environment

VariablePurpose
STOKA_ENVtesthttps://test.api.stoka.space, prod (default) → https://api.stoka.space.
STOKA_BASE_URLExplicit URL override — escape hatch for self-hosters / CI. Wins over STOKA_ENV.
STELLAR_SECRETStellar S… secret for wallet-signed tools.
X_PAYMENT_CMDShell command invoked per-402 to produce an X-PAYMENT header. Receives the PaymentRequirements JSON on stdin, writes base64 X-PAYMENT on stdout. Typically wraps x402-stellar (npm) or a custom signer.

Errors

ClassWhen
PaymentRequired402 with .requirements populated; raised when the signer is None or refused to sign.
StokaErrorAny non-2xx the client cannot retry. .status and .body hold the server response.

Pricing

Amounts are USDC atomic units (7 decimals on Stellar, so 1 USDC = 10_000_000 atomic units). The server returns full pricing config on GET /.well-known/stoka.json; X402Client.well_known() fetches it.

MIT Licensed.