Aegis Python SDK
The runtime-check, typed lifecycle, and local explanation APIs documented here
require SDK 0.2.0 or newer. Verify the installed package with
python -c "import aegis_sdk; print(aegis_sdk.__version__)"; before 0.2.0 is
published, install this repository checkout for implementation testing.
The released SDK is published as aegis-smart-accounts.
It requires Python 3.10 or newer. Install it in an isolated environment:
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install aegis-smart-accounts
For repository development instead, use python -m pip install -e sdk/python.
aegis init records only public identifiers and addresses in a mode-0600 state
file so an interrupted setup can resume. Before its first write it records an
operation marker, which lets a retry rediscover an agent or policy whose HTTP
response was lost. Account deployment, policy activation, and permission mint
also reconcile their durable transaction records instead of broadcasting a
second nondeterministic resource. Exit code 2 means an on-chain operation is
still pending and the same command/state file should be resumed. PrivateKeySigner is a development
adapter that holds its key in the running process; production agents should
use CallbackSigner with a wallet, HSM, secret manager, or other signing
service.
export AEGIS_API_KEY=aegissa_...
aegis init --name my-agent --owner 0x... --signer 0x... \
--chain-id 11155111 --policy-file /path/to/policy.json
aegis doctor AGENT_UUID --permission-id PERMISSION_UUID --asset native
# Equivalent flag form:
aegis doctor --agent-id AGENT_UUID --permission-id PERMISSION_UUID --asset native
The shell command aegis doctor is distinct from the MCP tool
aegis_doctor; use the latter only through the configured MCP server.
Doctor may use an expiring AEGIS_RUNTIME_API_KEY with agent:read scope.
Issued runtime credentials use the aegisrt_ prefix; the SDK rejects a
management-format key placed in that variable, because renaming a key does not
narrow its authority.
Provisioning commands still require the wallet-scoped management key and must
run in a trusted control-plane environment. Legacy erc8004_ management keys
remain accepted during the migration.
For a bounded, API-key-free policy explanation, use
explain_action_locally(request, rpc_url=..., capability=...). The capability
must explicitly identify the account generation, policy-only mode, bound
EntryPoint/enforcer/resolver addresses, all dependency runtime hashes, and the
normalized smart-account executable profile. Use
load_local_capability(chain_id, generation=...) to load this data from the
same generated registry consumed by the backend and MCP package. The SDK
re-reads and pins that tuple at one block before evaluating resolver-derived
calldata. Exact verdicts also require a capability promoted by the repository's
versioned conformance-evidence input; the packaged registry keeps untested
tuples unpromoted. Missing, unpromoted, or mismatched
capability data, resolver/read failures, and unknown generations remain
policyDecision: "unknown"; a policy pass never means that funding, target
execution, or the submission route is ready. The local lane never signs or
submits a UserOperation.
The API key is sent in the X-API-Key header. Authorization: Bearer is for
JWTs, not Aegis API keys. Keep the key in secure runtime storage and do not put
it in an agent prompt or checked-in configuration.
A minimal Sepolia policy example is available in the repository at
examples/minimal-sepolia-policy.json.
Use an explicit policy file that matches the account and chain you intend to
operate on.
Use permission_calldata(permission_id, calldata) to create the exact Aegis
permission envelope. Never select a permission by “newest”; pass the permission
UUID or on-chain bytes32 ID explicitly and run doctor immediately before use.
The authenticated client intentionally exposes only routes registered by the
API. It does not invent /limits, /quota, or /usage endpoints. Use
RuntimeChecker and ChainReader for authoritative typed on-chain reads of
the account binding, permission, per-asset limits, shared usage, quota, reset
time, EntryPoint state, and bundler capabilities. A configured zero daily or
transaction-count limit is unbounded even though the corresponding on-chain
quota return is zero. Usage is shared across permissions for the same on-chain
agent and asset and resets at the fixed UTC-day boundary anchored by the first
recorded spend.
build_execute and build_execute_batch encode policy-only account calls.
sign_userop uses the EIP-191 encoding expected by the account. The preferred
SafeUserOperation/UserOperationLifecycle path signs for estimation, forces
a fresh signature after gas fields are returned, and defaults to no submission.
The legacy estimate_userop and submit_userop helpers remain for compatible
low-level integrations, but emit deprecation warnings because they cannot
prove signature freshness. Both reject an unsigned operation before RPC.
Use wait_for_userop_receipt after submission. It reads the mined transaction
hash from the nested receipt.transactionHash field and exposes it as
tx_hash; the top-level userOpHash is not an EVM transaction hash.
The SDK is the execution helper, not a hosted bundler. The safe SDK lane uses a bundler route; self-submit is not silently inferred from a missing URL. For the full operator handoff, see the Aegis Quick Start and Agent Golden Path.
The required UserOperation sequence is build → sign → estimate → re-sign with the returned gas fields → submit. Any changed hashed field requires a fresh signature.
The CLI exposes that same lifecycle for aegis.action-request.v1. Prefer the
normal calls form: provide the exact target, value, target calldata, and
permission ID. The CLI reads the EntryPoint nonce and route fees, wraps the
call exactly once, signs for estimation, and replaces the estimated gas fields
before requiring a fresh submission signature. Advanced callers can still
provide a complete raw UserOperation. The command dry-runs by default and
prints a redacted, correlated result; submission is a separate explicit
command:
{
"schemaVersion": "aegis.action-request.v1",
"chainId": 8453,
"account": "0x1111111111111111111111111111111111111111",
"permissionId": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"calls": [{
"target": "0x2222222222222222222222222222222222222222",
"value": "0",
"data": "0x"
}],
"route": { "mode": "bundler", "bundlerUrlRef": "selected-runtime-route" }
}
aegis action run \
--env-file /absolute/path/agent.runtime.env \
--request-file /absolute/path/first-action.json \
--readiness-report-file /absolute/path/first-action.readiness.json
# Only after reviewing the exact explanation and successful estimate:
aegis action run \
--env-file /absolute/path/agent.runtime.env \
--request-file /absolute/path/first-action.json \
--execute
The optional readiness file is written atomically with owner-only permissions.
It contains no private key or management credential. Its EIP-191 proof binds
the local report to account.signer() so the dashboard can detect tampering;
the dashboard still verifies the live signer, current account/permission
binding, freshness, and owner recovery before showing the handoff as ready.
A calls-form request needs no custom UserOperation construction on supported
routes. Routes whose gas estimator merely echoes supplied limits remain
fail-closed and require promoted measured limits before this automatic path is
enabled. An exact denial always blocks. Unknown or unpromoted capability
support also blocks before signing; the deliberately named
--unsafe-allow-unknown option is for expert beta diagnostics and cannot
override a denial. No capability should be promoted until its checked-in live
conformance evidence passes the repository release gate.
Advanced programmatic dry-run-first execution shape:
from aegis_sdk import PrivateKeySigner, SafeUserOperation, build_execute
call_data = build_execute(TARGET, 0, TARGET_CALLDATA, PERMISSION_ID)
userop = {
"sender": SMART_ACCOUNT,
"nonce": "0x0", # resolve the real nonce first
"initCode": "0x",
"callData": call_data,
"callGasLimit": "0x0",
"verificationGasLimit": "0x0",
"preVerificationGas": "0x0",
"maxFeePerGas": MAX_FEE,
"maxPriorityFeePerGas": MAX_PRIORITY_FEE,
"paymasterAndData": "0x",
}
# dry_run signs only for estimation and never submits.
operation = SafeUserOperation.from_userop(userop, ENTRYPOINT, CHAIN_ID)
operation.dry_run(PrivateKeySigner(BOT_PRIVATE_KEY), BUNDLER_URL)
# Submission is a separate, explicit decision after reviewing the dry run.
userop_hash = operation.submit(PrivateKeySigner(BOT_PRIVATE_KEY), BUNDLER_URL, execute=True)
receipt = operation.lifecycle.wait_for_receipt(BUNDLER_URL, timeout=180)
CallbackSigner(address, callback) passes the 32-byte ERC-4337
UserOperation hash to callback; the callback must return the account's
EIP-191/personal-sign signature. Its user_presence_required metadata defaults
to True. Set it to False only for a non-interactive signer such as an HSM.
PrivateKeySigner.user_presence_required is False because it signs locally.
Runtime handoff from the dashboard
The downloaded runtime descriptor is intentionally non-secret. It contains an
explicit AEGIS_SIGNER_SECRET_FILE reference but no private key or management
API key. Store the descriptor and the separate signer backup outside the
repository, replace the placeholder with the absolute signer-backup path, and
restrict both files before checking them:
chmod 600 /absolute/path/agent.runtime.env /absolute/path/signer-backup.env
# Edit agent.runtime.env so AEGIS_SIGNER_SECRET_FILE points to signer-backup.env.
AEGIS_BUNDLER_URL='https://your-secret-managed-bundler-route' \
aegis runtime check --env-file /absolute/path/agent.runtime.env --json
The selected --env-file remains authoritative for chain, agent, account,
permission, and route identity. The explicit signer file contributes only a
supported signer key or signer endpoint; public address lines are ignored and
backend credential fields are rejected. The checker never scans a directory or
loads another env file, never prints the signer path or secret, and performs
read-only RPC/bundler probes only. Account, EntryPoint, enforcer, and resolver
addresses and runtime code hashes from the dashboard descriptor are compared
with live reads pinned to one block; a mismatch fails readiness rather than
silently substituting the current deployment. A relative signer path is resolved only
relative to the selected runtime descriptor; use an absolute path for clarity.
build_execute only wraps already-encoded target calldata with the Aegis
policy envelope. It does not encode a Uniswap, Aerodrome, or other DEX call;
construct that calldata from the exact router ABI for the target chain, then
run Aegis preflight and target-level gas estimation before submission.
When checking an intended token, pass --asset <address> (or native) to
Doctor. Doctor's normal asset rows describe the permission's configured asset
list; an account holding a token does not by itself mean that token is allowed
by the permission.
Robinhood Chain Testnet (46630) metadata is available through
get_chain_profile(46630) and its SDK profile is marked pending. The v15
contracts are deployed and verified, but Aegis API/provisioning support for this
chain is not enabled for normal onboarding yet, so do not target it through the
API. The SDK deliberately does not publish placeholder contract or test-token
addresses.
Release files for aegis-smart-accounts 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| aegis_smart_accounts-0.2.0.tar.gz | 90.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| aegis_smart_accounts-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 170.0 kB
Release files / aegis_smart_accounts-0.2.0.tar.gz
| Download URL | aegis_smart_accounts-0.2.0.tar.gz |
|---|---|
| Size | 90.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
dcbc101fc8dd5e1ea744f6024e7f7e9e93aa1bf65bf47d8e1737f5a71d28eff0
|
|
BLAKE2b-256 checksum How to use checksums |
d0ef7daad3c3f66b8382b00516e2e880ab444bf1470bdc83c5d6c73cce5e9c21
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 18, 2026.
Transparency logRelease files / aegis_smart_accounts-0.2.0-py3-none-any.whl
| Download URL | aegis_smart_accounts-0.2.0-py3-none-any.whl |
|---|---|
| Size | 79.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0ae38fcf2ed4dae441bcc3aafb06c013b561531c3825be53debaac1b0c711b15
|
|
BLAKE2b-256 checksum How to use checksums |
f7bc031a05eeb2184cc9f722e4d8b076fac5b6aa687d08cbc4088bd1236fe181
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 18, 2026.
Transparency log