Universal multi-chain secure signing SDK for AI agents
Project description
agent-wallet (Python)
Universal multi-chain secure signing SDK for AI agents — Python implementation.
Signing-only by design: handles key storage and signing locally, with no RPC or network dependencies. The caller builds and broadcasts transactions.
Requires Python ≥ 3.10
Python install and quick start instructions are intentionally omitted for now. The package is not currently published for direct installation.
CLI
# Initialize secrets directory with master password
agent-wallet init
# Add a wallet (interactive — choose type, enter private key)
agent-wallet add
# List all wallets
agent-wallet list
# Set active wallet (skip --wallet on subsequent commands)
agent-wallet use my-wallet
# Sign a message (uses active wallet)
agent-wallet sign msg "Hello"
# Override active wallet with explicit --wallet
agent-wallet sign msg "Hello" --wallet other
# Sign a transaction (JSON payload)
agent-wallet sign tx '{"txID": "...", "raw_data_hex": "..."}' --wallet my-wallet
# Sign EIP-712 typed data (JSON payload)
agent-wallet sign typed-data '{"domain": {...}, "types": {...}, ...}' --wallet my-wallet
Environment variables:
AGENT_WALLET_DIR— Secrets directory (default:~/.agent-wallet)AGENT_WALLET_PASSWORD— Master password (avoids interactive prompt)
API Reference
resolve_wallet_provider
from agent_wallet import resolve_wallet_provider
provider = resolve_wallet_provider(network="tron:nile")
Environment variables:
| Variable | Required | Description |
|---|---|---|
AGENT_WALLET_PASSWORD |
local mode | Enables local wallet mode |
AGENT_WALLET_DIR |
optional | Secrets directory, default ~/.agent-wallet |
AGENT_WALLET_PRIVATE_KEY |
static mode | Single-wallet private key |
AGENT_WALLET_MNEMONIC |
static mode | Single-wallet mnemonic |
AGENT_WALLET_MNEMONIC_ACCOUNT_INDEX |
optional | Address index for mnemonic derivation, default 0 |
Configuration modes:
| Mode | Required configuration | Optional configuration |
|---|---|---|
local |
AGENT_WALLET_PASSWORD |
AGENT_WALLET_DIR |
tron static |
network="tron" or network="tron:..." and exactly one of AGENT_WALLET_PRIVATE_KEY / AGENT_WALLET_MNEMONIC |
AGENT_WALLET_MNEMONIC_ACCOUNT_INDEX |
evm static |
network="eip155" or network="eip155:..." and exactly one of AGENT_WALLET_PRIVATE_KEY / AGENT_WALLET_MNEMONIC |
AGENT_WALLET_MNEMONIC_ACCOUNT_INDEX |
Network routing:
tronortron:<chain>uses the TRON adaptereip155oreip155:<chainId>uses the EVM adapter- TRON mnemonic derivation uses
m/44'/195'/0'/0/{index}
Resolution rules:
AGENT_WALLET_PASSWORDtakes precedence overAGENT_WALLET_PRIVATE_KEY/AGENT_WALLET_MNEMONIC- Set exactly one of
AGENT_WALLET_PRIVATE_KEYorAGENT_WALLET_MNEMONIC networkis required for single-wallet modeAGENT_WALLET_MNEMONIC_ACCOUNT_INDEXis only used with mnemonic mode and defaults to0
BaseWallet
All wallet adapters (EVM, TRON) implement the same interface:
class BaseWallet(ABC):
async def get_address() -> str
async def sign_raw(raw_tx: bytes) -> str
async def sign_transaction(payload: dict) -> str
async def sign_message(msg: bytes) -> str
class Eip712Capable(ABC):
async def sign_typed_data(data: dict) -> str
All signing methods return hex-encoded signature strings (no 0x prefix).
EVM Signing
wallet = await provider.get_active_wallet()
# Sign arbitrary message (EIP-191 personal sign)
sig = await wallet.sign_message(b"Hello")
# Sign EIP-712 typed data
sig = await wallet.sign_typed_data({
"types": {
"EIP712Domain": [{"name": "name", "type": "string"}, ...],
"Transfer": [{"name": "to", "type": "address"}, {"name": "amount", "type": "uint256"}],
},
"primaryType": "Transfer",
"domain": {"name": "MyDApp", "version": "1", "chainId": 1, ...},
"message": {"to": "0x...", "amount": 1000000},
})
# Sign a pre-built transaction dict
sig = await wallet.sign_transaction({"to": "0x...", "value": 0, "gas": 21000, ...})
TRON Signing
wallet = await provider.get_active_wallet()
# Sign message (keccak256 + secp256k1, no Ethereum prefix)
sig = await wallet.sign_message(b"Hello")
# Sign a pre-built unsigned transaction from TronGrid
# The caller builds the tx via TronGrid API, SDK only signs
signed_json = await wallet.sign_transaction({
"txID": "abc123...",
"raw_data_hex": "0a02...",
"raw_data": {...},
})
# Sign EIP-712 typed data (same secp256k1 curve as EVM)
sig = await wallet.sign_typed_data({...})
Error Handling
from agent_wallet import WalletNotFoundError, SigningError, DecryptionError
try:
wallet = await provider.get_active_wallet()
except WalletNotFoundError:
print("Wallet not found")
try:
sig = await wallet.sign_message(b"data")
except SigningError as e:
print(f"Signing failed: {e}")
Error hierarchy:
WalletError
├── WalletNotFoundError
├── DecryptionError
├── SigningError
├── NetworkError
├── InsufficientBalanceError
└── UnsupportedOperationError
Supported Wallet Types
| Type | Chains | Signing Library |
|---|---|---|
evm_local |
Ethereum, BSC, Polygon, Base, Arbitrum, any EVM | eth-account |
tron_local |
TRON Mainnet, Nile, Shasta | tronpy |
Examples
- tron_sign_and_broadcast.py — Build tx via TronGrid, sign with SDK, broadcast
- bsc_sign_and_broadcast.py — Build BSC testnet tx, sign with SDK, broadcast
- tron_x402_sign_typed_data.py — TRON x402 PaymentPermit signing
- bsc_x402_sign_typed_data.py — BSC/EVM x402 PaymentPermit signing
- dual_sign_typed_data_from_private_key.py — Reuse one external env input for both TRON and EVM signers
- switch_active_wallet.py — Set and switch active wallet via SDK
Security
- Keystore V3 — scrypt (N=262144, r=8, p=1) + AES-128-CTR + keccak256 MAC
- Password strength enforced — Minimum 8 characters with uppercase, lowercase, digit, and special character
- Password not retained — Discarded after provider initialization
- No network calls — All signing is pure local computation
- Sentinel verification — Master password correctness verified before key decryption
Development
# Install with all extras
pip install -e ".[all]"
# Run tests
pytest
# Run specific test file
pytest tests/test_tron_wallet.py -v
Cross-Language Compatibility
This Python SDK is fully compatible with the TypeScript implementation:
- Same keystore file format (files are interchangeable)
- Same signatures for same key + data
- Same address derivation
License
MIT — BankOfAI
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file bankofai_agent_wallet-2.2.1.tar.gz.
File metadata
- Download URL: bankofai_agent_wallet-2.2.1.tar.gz
- Upload date:
- Size: 18.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f13b3efc9ec5b52a9e6d783d91a049e3746a483b3e15ad19151404fb522f147f
|
|
| MD5 |
7c43db788804389e80be9a1fd1a80164
|
|
| BLAKE2b-256 |
2f6ef19a74e65d4b43fd16bfd0ef3d856c77ad7cca3e75306824831c33eabec5
|
File details
Details for the file bankofai_agent_wallet-2.2.1-py3-none-any.whl.
File metadata
- Download URL: bankofai_agent_wallet-2.2.1-py3-none-any.whl
- Upload date:
- Size: 24.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7eff02bd96cd06b24da6333a11ce2f5a295f4c7c36011d33f029203138978ff8
|
|
| MD5 |
d63f13d158c086f4c3f3f7284f232331
|
|
| BLAKE2b-256 |
04a93f3fc62afed7e164d95b80141d9f4ebddf39bfda08481a336687c0e7c606
|