Python SDK for Agentium Network - DID and Verifiable Credentials.
pip install agentium-sdk- Python: 3.10 or higher
- For end users: No additional dependencies (prebuilt wheels available for supported platforms)
- For development/building from source:
- Rust toolchain (1.70+) - Install Rust
- Maturin build tool:
pip install maturin
Prebuilt wheels are available for the following platforms:
| Platform | Architecture | Wheel Available |
|---|---|---|
| Linux | x86_64 | ✅ |
| Linux | aarch64 (ARM64) | ❌ (build from source) |
| macOS | x86_64 (Intel) | ✅ |
| macOS | aarch64 (Apple Silicon) | ✅ |
| Windows | x86_64 | ✅ |
For platforms without prebuilt wheels (e.g., Linux aarch64/ARM64), pip will automatically attempt to build from the source distribution. This requires:
-
Rust toolchain (1.70+):
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
-
Install the SDK (pip will compile from source):
pip install agentium-sdk
The build process may take a few minutes as it compiles the native Rust code.
import agentium_sdk
# Connect with Google Sign-In (async)
wallet_address, did = await agentium_sdk.connect_google(google_id_token)
# Or use the sync version
wallet_address, did = agentium_sdk.connect_google_sync(google_id_token)Note: The google_id_token is obtained from Google's OAuth 2.0 authentication flow. See Google Identity documentation for implementation details.
import agentium_sdk
import os
# Connect with wallet using local signing (async)
# Uses Base mainnet (eip155:8453) by default
wallet_address, did = await agentium_sdk.connect_wallet(
address="0x742d35Cc6634C0532925a3b844Bc9e7595f1b2b7",
private_key=os.getenv("WALLET_PRIVATE_KEY"), # hex string or bytes
)
# Or specify a different chain (e.g., testnet) using Caip2
from agentium_sdk import Caip2
wallet_address, did = await agentium_sdk.connect_wallet(
address="0x742d35Cc6634C0532925a3b844Bc9e7595f1b2b7",
private_key=os.getenv("WALLET_PRIVATE_KEY"),
chain_id=Caip2.BASE_SEPOLIA, # or "eip155:84532" for testnet
)
# Sync version available
wallet_address, did = agentium_sdk.connect_wallet_sync(address, private_key)Security Warning: Never hardcode private keys in your source code. Always use environment variables, secure key management systems, or hardware wallets in production.
The AgentiumClient is the main interface for API interactions.
from agentium_sdk import AgentiumClient
# Default: connects to https://api.agentium.network
async with AgentiumClient() as client:
pass
# Custom endpoint
async with AgentiumClient(base_url="https://custom.endpoint") as client:
passConnect a Google identity to create/retrieve a DID.
response = await client.connect_google_identity(google_id_token)
print(response.did) # did:pkh:eip155:1:0x...
print(response.access_token) # JWT for authenticated calls
print(response.is_new) # True if newly createdExchange an API key for JWT tokens (M2M authentication).
response = await client.exchange_api_key(api_key)
print(response.access_token)
print(response.refresh_token)Refresh an expired access token.
response = await client.refresh_token(old_refresh_token)Fetch a membership credential JWT.
credential_jwt = await client.fetch_membership_credential(access_token)Fetch the issuer's DID document from /.well-known/did.json.
did_document = await client.fetch_issuer_did_document()
print(did_document["id"]) # did:web:api.agentium.networkVerify a credential against the issuer's public key (fetches DID document automatically).
result = await client.verify_credential(credential_jwt)
if result.valid:
print(result.claims) # dict with JWT claimsrequest_wallet_challenge(address: str, chain_id: Caip2 | str = Caip2.BASE_MAINNET) -> WalletChallengeResponse
Request a SIWE challenge message for wallet sign-in.
# Uses Base mainnet by default
challenge = await client.request_wallet_challenge(
address="0x742d35Cc6634C0532925a3b844Bc9e7595f1b2b7",
)
print(challenge.message) # SIWE message to sign
print(challenge.nonce) # Unique nonce for replay protection
# Or specify testnet explicitly
from agentium_sdk import Caip2
challenge = await client.request_wallet_challenge(
address="0x742d35Cc6634C0532925a3b844Bc9e7595f1b2b7",
chain_id=Caip2.BASE_SEPOLIA, # or "eip155:84532" for testnet
)Verify a signed challenge and obtain JWT tokens.
response = await client.verify_wallet_signature(challenge.message, signature)
print(response.access_token)
print(response.refresh_token)connect_wallet(address: str, private_key: bytes | str, chain_id: Caip2 | str = Caip2.BASE_MAINNET) -> ConnectIdentityResponse
Full wallet sign-in flow with local signing (challenge → sign → verify).
import os
# Uses Base mainnet by default
response = await client.connect_wallet(
address="0x742d35Cc6634C0532925a3b844Bc9e7595f1b2b7",
private_key=os.getenv("WALLET_PRIVATE_KEY"), # hex string or bytes
)
print(response.did) # did:pkh:eip155:8453:0x...
print(response.access_token) # JWT for authenticated calls
print(response.is_new) # True if newly created
# Or specify testnet explicitly
from agentium_sdk import Caip2
response = await client.connect_wallet(
address="0x742d35Cc6634C0532925a3b844Bc9e7595f1b2b7",
private_key=os.getenv("WALLET_PRIVATE_KEY"),
chain_id=Caip2.BASE_SEPOLIA, # for testnet
)Security Note: Use secure key management practices. Never commit private keys to version control.
Low-level cryptographic operations powered by Rust.
Verify a JWT signature against a public key.
from agentium_sdk import verify_jwt
result = verify_jwt(jwt_string, public_key_jwk_json)
if result.valid:
print(result.claims) # dict[str, Any]
else:
print(result.error.code) # e.g., "JWT_EXPIRED"
print(result.error.message)Parse JWT header without verification.
from agentium_sdk import parse_jwt_header
header = parse_jwt_header(jwt_string)
print(header.alg) # "EdDSA"
print(header.kid) # Key ID for DID document lookupExtract a public key from a DID document.
from agentium_sdk import extract_public_key_jwk
public_key_jwk = extract_public_key_jwk(did_doc_json, kid="#key-1")Generate a new Ed25519 key pair.
from agentium_sdk import generate_keypair
keypair = generate_keypair()
print(keypair.public_key_jwk) # Safe to share
print(keypair.private_key_jwk) # Keep secret!Derive public key from a private key.
from agentium_sdk import get_public_key
public_jwk = get_public_key(private_key_jwk_json)Sign a wallet authentication challenge message.
from agentium_sdk import sign_challenge
import os
# Load private key securely from environment
private_key = bytes.fromhex(os.getenv("WALLET_PRIVATE_KEY"))
signature = sign_challenge(
message=challenge_message.encode("utf-8"),
chain_id="eip155:84532",
private_key=private_key,
)
print(signature) # 0x-prefixed hex signatureValidate a CAIP-2 chain identifier format.
from agentium_sdk import validate_caip2
if validate_caip2("eip155:84532"):
print("Valid chain ID")Enable structured tracing with a custom callback.
from agentium_sdk import init_tracing
def telemetry_handler(event: dict):
"""Receives events with: kind, level, target, name, fields, ts_ms"""
print(f"[{event['level']}] {event['target']}: {event['fields']}")
# Initialize once per process
init_tracing(telemetry_handler, "debug") # filter: "info", "debug", "agentium=trace"Note: init_tracing can only be called once. Subsequent calls are ignored.
| Type | Description |
|---|---|
ConnectIdentityResponse |
DID, tokens, badge status, is_new flag |
OAuthTokenResponse |
access_token, refresh_token, expires_in, scope |
WalletChallengeResponse |
message, nonce for wallet sign-in challenge |
Caip2 |
Parsed CAIP-2 chain identifier with namespace and reference. Constants: Caip2.BASE_SEPOLIA, Caip2.BASE_MAINNET |
VerificationResult |
valid, claims (dict), error |
VerificationError |
code, message |
JwtHeader |
alg, typ, kid |
GeneratedKeyPair |
private_key_jwk, public_key_jwk |
Badge |
status |
Raised on API failures.
from agentium_sdk import AgentiumApiError
try:
await client.connect_google_identity(invalid_token)
except AgentiumApiError as e:
print(e.message)
print(e.status_code) # 401, 403, etc.Raised when CAIP-2 chain identifier parsing fails.
from agentium_sdk import Caip2, Caip2Error
try:
caip2 = Caip2.parse("invalid-chain-id")
except Caip2Error as e:
print(e) # CAIP-2 identifier must contain a colon separatorThis SDK is a Python binding to native Rust code, providing high-performance cryptographic operations. Building from source requires the Rust toolchain.
# Install Rust toolchain (if not already installed)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Install Maturin (build tool for Rust-based Python packages)
pip install maturin
# Build and install in development mode
# This compiles the Rust code and creates a Python package
maturin develop
# Install development dependencies
pip install -e ".[dev]"
# Run tests
pytestMaturin is the build tool that bridges Rust and Python, compiling the native Rust extensions and packaging them as a Python wheel. The maturin develop command builds the Rust code in debug mode and installs it in your current Python environment.
Note: This section is for SDK contributors who want to build and preview the documentation locally.
To build and serve docs:
# From the repository root, navigate to the Python SDK directory
cd packages/agentium-native/python
# Install documentation dependencies
pip install -e ".[docs]"
# Build the SDK first (required - mkdocstrings needs to import the package)
maturin develop
# Serve docs locally with hot-reload at http://127.0.0.1:8000
mkdocs serve
# Or build static site to site/ directory
mkdocs buildThe documentation uses MkDocs with the mkdocstrings plugin to auto-generate API docs from Python docstrings and type hints.
This project is licensed under the Business Source License 1.1. See the LICENSE file for details.