Payment SDK for Autonomous AI Agents
Project description
PayKit
Vendor-Agnostic Payment SDK for Autonomous AI Agents
PayKit provides a unified payment infrastructure for AI agents. One SDK to handle wallets, transfers, spending controls, and cross-chain payments across multiple providers.
Why PayKit?
| Challenge | Solution |
|---|---|
| AI agents need to spend money | Programmatic USDC wallets with no private keys to manage |
| Agents can hallucinate or overspend | Safety guards with atomic enforcement |
| Different payment protocols exist | Universal routing (direct, x402, cross-chain) |
| Vendor lock-in | Provider abstraction (Circle, Coinbase, more) |
| No visibility into agent spending | Built-in ledger and transaction history |
Installation
pip install paykit
With Coinbase support:
pip install paykit[coinbase]
Quick Start
import asyncio
from decimal import Decimal
from paykit import PayKit
async def main():
# Initialize (reads CIRCLE_API_KEY from environment)
client = PayKit()
# Create a wallet for your agent
wallet_set, wallet = await client.create_agent_wallet(agent_name="my-agent")
print(f"Wallet: {wallet.address}")
# Add spending limits (safety first!)
await client.add_budget_guard(wallet.id, daily_limit=Decimal("100.00"))
# Make a payment
result = await client.pay(
wallet_id=wallet.id,
recipient="0x742d35Cc6634C0532925a3b844Bc9e7595f5e4a0",
amount=Decimal("10.00")
)
print(f"Payment: {result.status}")
asyncio.run(main())
Core Features
Wallet Management
Create and manage USDC wallets programmatically. No seed phrases or private keys.
# Create wallets for agents
wallet_set, wallet = await client.create_agent_wallet(agent_name="trading-bot")
# Check balance
balance = await client.get_balance(wallet.id)
# List all wallets
wallets = client.wallet.list_wallets()
Safety Guards
Protect against runaway spending with atomic enforcement:
# Budget limits
await client.add_budget_guard(
wallet.id,
daily_limit=Decimal("100.00"),
hourly_limit=Decimal("25.00"),
total_limit=Decimal("1000.00")
)
# Rate limits (prevent infinite loops)
await client.add_rate_limit_guard(wallet.id, max_per_minute=5, max_per_hour=20)
# Transaction size limits
await client.add_single_tx_guard(wallet.id, max_amount=Decimal("50.00"))
# Recipient whitelist
await client.add_recipient_guard(
wallet.id,
mode="whitelist",
domains=["api.openai.com", "api.anthropic.com"]
)
# Human approval for large payments
await client.add_confirm_guard(wallet.id, threshold=Decimal("500.00"))
| Guard | Purpose |
|---|---|
BudgetGuard |
Spending limits (daily/hourly/total) |
RateLimitGuard |
Transaction frequency limits |
SingleTxGuard |
Per-transaction min/max amounts |
RecipientGuard |
Whitelist or blacklist recipients |
ConfirmGuard |
Human-in-the-loop approval |
Universal Payment Routing
One pay() method handles all payment types:
# Direct USDC transfer (blockchain address)
await client.pay(wallet_id=w, recipient="0x...", amount=Decimal("10.00"))
# x402 API payment (HTTP URL)
await client.pay(wallet_id=w, recipient="https://api.example.com/data", amount=Decimal("0.10"))
# Cross-chain transfer (CCTP)
from paykit import Network
await client.pay(
wallet_id=w,
recipient="0x...",
amount=Decimal("50.00"),
destination_chain=Network.BASE
)
Payment Intents
Authorize now, execute later:
# Create authorization
intent = await client.create_payment_intent(
wallet_id=wallet.id,
recipient="0x...",
amount=Decimal("500.00")
)
# Confirm when ready
result = await client.confirm_payment_intent(intent.id)
# Or cancel
await client.cancel_payment_intent(intent.id)
Batch Payments
Execute multiple payments concurrently:
from paykit import PaymentRequest
results = await client.batch_pay([
PaymentRequest(wallet_id=w, recipient="0xA...", amount=Decimal("10.00")),
PaymentRequest(wallet_id=w, recipient="0xB...", amount=Decimal("20.00")),
PaymentRequest(wallet_id=w, recipient="0xC...", amount=Decimal("30.00")),
], concurrency=10)
print(f"Success: {results.success_count}, Failed: {results.failed_count}")
Transaction Ledger
Complete observability:
# Get transaction history
history = await client.ledger.get_history(wallet_id=wallet.id)
# Get total spent
total = await client.ledger.get_total_spent(wallet_id=wallet.id)
# Sync with blockchain
await client.sync_transaction(entry_id="...")
Multi-Provider Architecture
PayKit abstracts wallet providers. Switch providers without code changes.
Supported Providers
| Provider | Status | Install | Features |
|---|---|---|---|
| Circle | Stable | Default | CCTP, gasless transfers |
| Coinbase | Beta | pip install paykit[coinbase] |
EVM + Solana |
Provider Configuration
Circle (Default):
from paykit import PayKit
from paykit.providers import CircleProvider, CircleConfig
provider = CircleProvider(CircleConfig(
api_key="your-circle-api-key",
entity_secret="your-entity-secret", # Auto-generated if not provided
))
client = PayKit(provider=provider)
Coinbase:
from paykit.providers import CoinbaseProvider, CoinbaseConfig
provider = CoinbaseProvider(CoinbaseConfig(
api_key="your-cdp-api-key-id",
api_secret="your-cdp-api-key-secret",
wallet_secret="your-wallet-secret",
))
client = PayKit(provider=provider)
Environment Variables:
# Circle
export CIRCLE_API_KEY="..."
export ENTITY_SECRET="..." # Optional, auto-generated
# Coinbase
export CDP_API_KEY_ID="..."
export CDP_API_KEY_SECRET="..."
export CDP_WALLET_SECRET="..."
# Provider selection
export PAYKIT_PROVIDER="circle" # or "coinbase"
Direct Provider Access
from paykit.providers import get_provider, ProviderType
# Get provider
provider = get_provider(ProviderType.CIRCLE)
# Direct operations
wallet = await provider.create_wallet(wallet_set_id, "ETH-SEPOLIA")
balances = await provider.get_balances(wallet.id)
result = await provider.transfer(wallet.id, "0x...", Decimal("10.00"))
Configuration
Environment Variables
| Variable | Required | Description | Default |
|---|---|---|---|
CIRCLE_API_KEY |
Yes* | Circle API key | - |
ENTITY_SECRET |
No | Circle entity secret | Auto-generated |
PAYKIT_PROVIDER |
No | Provider: circle, coinbase |
circle |
PAYKIT_NETWORK |
No | Default network | ARC-TESTNET |
PAYKIT_STORAGE_BACKEND |
No | Storage: memory, redis |
memory |
PAYKIT_REDIS_URL |
No | Redis connection URL | redis://localhost:6379 |
PAYKIT_LOG_LEVEL |
No | Logging level | INFO |
Supported Networks
Testnets:
ARC-TESTNET(Circle Arc - recommended for testing)ETH-SEPOLIA,BASE-SEPOLIA,ARB-SEPOLIAMATIC-AMOY,AVAX-FUJISOL-DEVNET
Mainnets:
ETH,BASE,ARB,MATIC,AVAX,SOL
Error Handling
from paykit import (
PayKitError, # Base exception
GuardError, # Blocked by safety guard
InsufficientBalanceError,
WalletError,
PaymentError,
ConfigurationError,
)
try:
result = await client.pay(wallet_id=w, recipient="0x...", amount=Decimal("1000.00"))
except GuardError as e:
print(f"Blocked: {e}") # Budget exceeded, rate limited, etc.
except InsufficientBalanceError as e:
print(f"Low balance: {e}")
except PayKitError as e:
print(f"Payment failed: {e}")
Examples
See the examples/ directory:
basic_payment.py- Simple payment flowusing_guards.py- Safety guard configurationgemini_agent.py- Google Gemini integrationx402_client_demo.py- x402 protocol usageledger_tracking.py- Transaction observability
Documentation
| Document | Description |
|---|---|
| Quickstart | Get started in 5 minutes |
| API Reference | Complete API documentation |
| SDK Usage Guide | Detailed usage patterns |
| CCTP Usage | Cross-chain transfer guide |
| Gas Requirements | Network gas information |
| Architecture | Design philosophy |
Development
# Clone repository
git clone https://github.com/paykit/paykit.git
cd paykit
# Install with dev dependencies
pip install -e ".[dev]"
# Run tests
pytest
# Run tests with coverage
pytest --cov=src/paykit
# Type checking
mypy src/paykit
# Linting
ruff check src/paykit
ruff format src/paykit
Project Structure
src/paykit/
├── client.py # Main PayKit client
├── providers/ # Wallet provider implementations
│ ├── base.py # Abstract provider interface
│ ├── circle.py # Circle implementation
│ └── coinbase.py # Coinbase implementation
├── guards/ # Safety guard system
├── protocols/ # Payment protocol adapters
├── ledger/ # Transaction history
├── storage/ # Persistence backends
└── webhooks/ # Event handling
Contributing
Contributions are welcome! Please read our contributing guidelines before submitting PRs.
- Fork the repository
- Create a feature branch
- Add tests for new functionality
- Ensure all tests pass
- Submit a pull request
License
MIT License - see LICENSE for details.
Links
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 paykit-0.1.0.tar.gz.
File metadata
- Download URL: paykit-0.1.0.tar.gz
- Upload date:
- Size: 73.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ce16f8e1cd92b9f134e8ea9a3b23d7cbc8ef550b06f4cc103dd8b90080776f6e
|
|
| MD5 |
3f69c2f94d13282b9661b9e66c97510c
|
|
| BLAKE2b-256 |
b48a14a5be24eb80f8bd563a8a213a60cfbd2e801e9a2fab12c4bbf1a3ae4601
|
File details
Details for the file paykit-0.1.0-py3-none-any.whl.
File metadata
- Download URL: paykit-0.1.0-py3-none-any.whl
- Upload date:
- Size: 6.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8e6c0299d847ea1c7f21478b05ef17a80ded2e6c65a287334c12ba607d12475c
|
|
| MD5 |
25284303919c88eab551d3c76e4568ad
|
|
| BLAKE2b-256 |
8312268f7b6361824836f6ec6d747c062faceffd6c520730be6218e5d67cea93
|