Observed since 20 Oct, 21:48 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
agent-did-sdk
Python SDK for the Agent-DID Specification (RFC-001) — create, sign, resolve, verify and revoke Agent-DIDs
Python SDK for the Agent-DID Specification (RFC-001) — create, sign, resolve, verify and revoke Agent-DIDs.
Functional parity with the TypeScript SDK (@agentdid/sdk), with a dedicated Python CI pipeline and shared interoperability fixtures.
Formal parity tracking is documented in ../docs/F2-01-TS-Python-Parity-Matrix.md.
Pythonic surface conventions apply:
signer_addresssnake_caseAgentIdentitypip install agent-did-sdk
For development:
pip install -e ".[dev]"
import asyncio
from agent_did_sdk import AgentIdentity, AgentIdentityConfig, CreateAgentParams
async def main():
identity = AgentIdentity(AgentIdentityConfig(signer_address="0xYourWalletAddress"))
result = await identity.create(CreateAgentParams(
name="MyAgent",
core_model="gpt-4-turbo",
system_prompt="You are a helpful assistant.",
capabilities=["search", "code-execution"],
))
print(f"Agent DID: {result.document.id}")
print(f"Private Key: {result.agent_private_key}")
# Sign a message
signature = await identity.sign_message("Hello, World!", result.agent_private_key)
# Verify
is_valid = await AgentIdentity.verify_signature(
result.document.id, "Hello, World!", signature
)
print(f"Valid: {is_valid}")
asyncio.run(main())
| Feature | API | Status |
|---|---|---|
| Create Agent-DID document | identity.create(params) | ✅ |
| Sign messages (Ed25519) | identity.sign_message(payload, key) | ✅ |
| Sign HTTP requests (Bot Auth) | identity.sign_http_request(params) | ✅ |
| Verify message signatures | AgentIdentity.verify_signature(did, payload, sig) | ✅ |
| Verify HTTP signatures | AgentIdentity.verify_http_request_signature(params) | ✅ |
| Resolve DID → document | AgentIdentity.resolve(did) | ✅ |
| Revoke DID | AgentIdentity.revoke_did(did) | ✅ |
| Update document | AgentIdentity.update_did_document(did, patch) | ✅ |
| Rotate verification keys | AgentIdentity.rotate_verification_method(did) | ✅ |
| Document history/audit | AgentIdentity.get_document_history(did) | ✅ |
| EVM registry adapter | EvmAgentRegistry + Web3AgentRegistryContractClient | ✅ |
| Universal resolver (HTTP/RPC/IPFS) | UniversalResolverClient | ✅ |
| Module | Description |
|---|---|
core.types | Pydantic models for RFC-001 (AgentDIDDocument, etc.) |
core.identity | AgentIdentity — main class for DID lifecycle |
core.time_utils | ISO-8601 ↔ Unix timestamp utilities |
crypto.hash | SHA-256 hashing with hash:// URI format |
registry.* | Agent registry (in-memory, EVM adapter, Web3 client) |
resolver.* | DID resolver (in-memory, HTTP source, JSON-RPC source, universal) |
Connect the SDK to a real on-chain AgentRegistry contract:
from web3 import HTTPProvider, Web3
from agent_did_sdk import AgentIdentity, EvmAgentRegistry, Web3AgentRegistryContractClient
from agent_did_sdk.registry.evm_types import EvmAgentRegistryAdapterConfig
provider = Web3(HTTPProvider("http://127.0.0.1:8545"))
contract = provider.eth.contract(address=REGISTRY_ADDRESS, abi=ABI)
registry = EvmAgentRegistry(
EvmAgentRegistryAdapterConfig(
contract_client=Web3AgentRegistryContractClient(contract),
await_transaction_confirmation=True,
)
)
AgentIdentity.set_registry(registry)
See full example: examples/evm_registry_wiring.py
Configure a production-grade resolver with failover and caching:
from agent_did_sdk import AgentIdentity, ProductionHttpResolverProfileConfig
AgentIdentity.use_production_resolver_from_http(
ProductionHttpResolverProfileConfig(
registry=evm_registry,
cache_ttl_ms=60_000,
ipfs_gateways=["https://gateway.pinata.cloud", "https://ipfs.io"],
on_resolution_event=lambda event: print("Resolution:", event.stage),
)
)
Minimal did:wba example: examples/did_wba_resolution.py
Canonical local workflow:
cd sdk-python
python -m pip install -e ".[dev]"
ruff check src/ tests/ scripts/
mypy --strict src/
pytest --cov=agent_did_sdk --cov-fail-under=85 -q
Repository-level convenience wrappers are also available from the repo root:
npm run python:test
npm run python:conformance
These npm commands are only monorepo shortcuts. The canonical Python commands remain the native python, pytest, ruff, and mypy commands shown above.
cd sdk-python
pip install -e ".[dev]"
pytest --cov
RFC-001 Python conformance:
cd sdk-python
python scripts/conformance_rfc001.py
Operational smokes:
cd contracts
npm ci
cd ../sdk-python
python scripts/rpc_resolver_smoke.py
python scripts/resolver_ha_smoke.py
python scripts/revocation_policy_smoke.py
python scripts/e2e_smoke.py
The repository includes .github/workflows/publish-python-sdk.yml for PyPI Trusted Publishing.
Before the first release, create the agent-did-sdk project on PyPI and, optionally, TestPyPI, then register GitHub Trusted Publishers for:
edisonduran/agent-did.github/workflows/publish-python-sdk.ymlsdk-python-vX.Y.Z for PyPI, workflow_dispatch for TestPyPI or manual PyPI releaseIf you want GitHub environment approvals, add matching environments later and bind them in both GitHub and PyPI Trusted Publishing settings.
Release preparation:
cd sdk-python
python -m pip install -e ".[dev]"
python -m build
python -m twine check dist/*
Release flow:
version in pyproject.tomlrepository=testpypi to validate the package on TestPyPIsdk-python-vX.Y.Zmain with repository=pypiApache-2.0 — see root LICENSE.
Download counts and popularity will appear here as the collector receives them.
| Package / target | Requirement | Relationship |
|---|---|---|
pydanticEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.10",
"evaluation": "NOT_EVALUATED"
} | pydantic>=2.0 | runtime |
pynaclEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.10",
"evaluation": "NOT_EVALUATED"
} | pynacl>=1.5 | runtime |
web3Environment{
"extras": "",
"marker": null,
"requires_python": ">=3.10",
"evaluation": "NOT_EVALUATED"
} | web3>=6.0 | runtime |
httpxEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.10",
"evaluation": "NOT_EVALUATED"
} | httpx>=0.27 | runtime |
pytestEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.10",
"evaluation": "NOT_EVALUATED"
} | pytest>=8.0; extra == "dev" | runtime |
pytest-asyncioEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.10",
"evaluation": "NOT_EVALUATED"
} | pytest-asyncio>=0.23; extra == "dev" | runtime |
pytest-covEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.10",
"evaluation": "NOT_EVALUATED"
} | pytest-cov>=5.0; extra == "dev" | runtime |
ruffEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.10",
"evaluation": "NOT_EVALUATED"
} | ruff>=0.4; extra == "dev" | runtime |
mypyEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.10",
"evaluation": "NOT_EVALUATED"
} | mypy>=1.10; extra == "dev" | runtime |
bdist_wheel · 30.74 KB · Python py3
sdist · 34.56 KB · Python source
Observed since 20 Oct, 21:48 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package_version:4920efc844f8d2f6083a6df57386bf4019e1e66df556b5f42531f320d2adea5e