This is the public API reference for the Financial Policy Engine. It focuses on the API surface users are expected to call directly.
Common imports from src/omniclaw/init.py:
from omniclaw import (
OmniClaw,
Network,
FeeLevel,
PaymentMethod,
PaymentStatus,
PaymentIntentStatus,
quick_setup,
validate_entity_secret,
)Required:
CIRCLE_API_KEY=...
OMNICLAW_NETWORK=ETH-SEPOLIA
# Direct-key mode (recommended for agents / nanopayments)
OMNICLAW_PRIVATE_KEY=0x...If you are using Circle developer-controlled wallets directly, provide:
ENTITY_SECRET=...
Optional:
OMNICLAW_DEFAULT_WALLET=wallet-id
OMNICLAW_LOG_LEVEL=INFO
OMNICLAW_ENV=development
OMNICLAW_RPC_URL=https://...
OMNICLAW_STORAGE_BACKEND=memory
OMNICLAW_REDIS_URL=redis://localhost:6379
OMNICLAW_DAILY_BUDGET=100.00
OMNICLAW_HOURLY_BUDGET=20.00
OMNICLAW_TX_LIMIT=50.00
OMNICLAW_RATE_LIMIT_PER_MIN=5
OMNICLAW_WHITELISTED_RECIPIENTS=0xabc,0xdef
OMNICLAW_CONFIRM_ALWAYS=false
OMNICLAW_CONFIRM_THRESHOLD=500.00Defined in onboarding.py.
One-time onboarding helper that writes a local env file and syncs OmniClaw's managed credential store.
If entity_secret is provided, OmniClaw treats it as the existing Circle Entity Secret for that API key and does not try to register a replacement. Circle only allows one active Entity Secret per account/API key.
If entity_secret is omitted, OmniClaw generates and registers a new Entity Secret, then saves the recovery file in the secure config directory.
The helper currently defaults to ARC-TESTNET, so pass an explicit network if you want the generated env file to target ETH-SEPOLIA, BASE-SEPOLIA, or another supported network.
Public examples in the docs usually show ETH-SEPOLIA or BASE-SEPOLIA, but the SDK still supports other configured networks such as ARC-TESTNET when selected explicitly.
Returns a 64-character hex entity secret (manual setup only).
Validates that an existing Circle Entity Secret is a 64-character hex value before it is written to env or managed config.
Registers a new entity secret with Circle and downloads the recovery file (manual setup only). Do not call this for an API key/account that already has an Entity Secret; set ENTITY_SECRET directly instead.
create_env_file(api_key, entity_secret, env_path=".env", network="ARC-TESTNET", overwrite=False) (optional)
Writes the basic OmniClaw env file (manual setup only).
Returns a readiness summary for the local environment.
Returns a diagnostic summary covering:
- Circle SDK availability
- API key presence
- environment entity secret presence
- managed config entity secret presence
- recovery-file presence
Prints the same diagnostic state in a human-readable format.
Defined in client.py.
OmniClaw(
circle_api_key: str | None = None,
entity_secret: str | None = None,
network: Network = Network.ARC_TESTNET,
log_level: int | str | None = None,
trust_policy: TrustPolicy | str | None = None,
rpc_url: str | None = None,
)configwalletguardstrustintentintentsledgerwebhooksnanopayment_adapter— NanopaymentAdapter for buyer-side nanopayments
await client.create_wallet(
blockchain=None,
wallet_set_id=None,
account_type=AccountType.EOA,
name=None,
)
await client.create_agent_wallet(
agent_name,
blockchain=None,
apply_default_guards=True,
)
await client.create_wallet_set(name=None)
await client.list_wallets(wallet_set_id=None)
await client.list_wallet_sets()
await client.get_wallet(wallet_id)
await client.get_wallet_set(wallet_set_id)
await client.get_balance(wallet_id)
await client.list_transactions(wallet_id=None, blockchain=None)await client.pay(
wallet_id,
recipient,
amount,
destination_chain=None,
wallet_set_id=None,
purpose=None,
idempotency_key=None,
fee_level=FeeLevel.MEDIUM,
strategy=PaymentStrategy.RETRY_THEN_FAIL,
skip_guards=False,
check_trust=None,
consume_intent_id=None,
metadata=None,
wait_for_completion=False,
timeout_seconds=None,
**kwargs,
)For x402 URL payments, pass the HTTP request context through kwargs:
await client.pay(
wallet_id=wallet.id,
recipient="https://seller.example.com/premium",
amount="0.25",
method="POST",
request_body='{"job":"prime-count","size":70000}',
request_headers={"x-request-id": "job-123"},
)Buyer routing is requirement-driven:
- seller advertises
GatewayWalletBatchedand the buyer is Gateway-ready -> OmniClaw can use the Gateway nanopayment path - seller advertises standard x402
exact-> OmniClaw uses the upstream x402 SDK path - seller advertises both and the buyer is not Gateway-ready -> OmniClaw uses
exact
When the seller is exact-only, OmniClaw routes directly to exact instead of attempting Gateway first.
await client.simulate(
wallet_id,
recipient,
amount,
wallet_set_id=None,
check_trust=None,
skip_guards=False,
**kwargs,
)Other helpers:
client.can_pay(recipient)
client.detect_method(recipient)
await client.batch_pay(requests, concurrency=5)
await client.sync_transaction(entry_id)await client.create_payment_intent(
wallet_id,
recipient,
amount,
purpose=None,
expires_in=None,
idempotency_key=None,
skip_guards=False,
check_trust=None,
**kwargs,
)
await client.confirm_payment_intent(intent_id)
await client.get_payment_intent(intent_id)
await client.cancel_payment_intent(intent_id, reason=None)await client.add_budget_guard(wallet_id, daily_limit=None, hourly_limit=None, total_limit=None, name="budget")
await client.add_budget_guard_for_set(wallet_set_id, daily_limit=None, hourly_limit=None, total_limit=None, name="budget")
await client.add_single_tx_guard(wallet_id, max_amount=None, min_amount=None, name="single_tx")
await client.add_recipient_guard(wallet_id, mode="whitelist", addresses=None, patterns=None, domains=None, name="recipient")
await client.add_recipient_guard_for_set(wallet_set_id, mode="whitelist", addresses=None, patterns=None, domains=None, name="recipient")
await client.add_rate_limit_guard(wallet_id, max_per_minute=None, max_per_hour=None, max_per_day=None, name="rate_limit")
await client.add_rate_limit_guard_for_set(wallet_set_id, max_per_minute=None, max_per_hour=None, max_per_day=None, name="rate_limit")
await client.add_confirm_guard(wallet_id, threshold=None, always_confirm=False, name="confirm")
await client.add_confirm_guard_for_set(wallet_set_id, threshold=None, always_confirm=False, name="confirm")
await client.list_guards(wallet_id)
await client.list_guards_for_set(wallet_set_id)Nanopayments use EIP-3009 for gas-free USDC transfers on Circle Gateway. They work alongside regular payments — micro-transactions route through the gateway while larger payments use standard transfers.
# Get the GatewayMiddleware for protecting endpoints
await client.gateway() # -> GatewayMiddleware
# Dependency factory for marking paid FastAPI routes
client.sell(price: str) # -> FastAPI Depends() object
# Get current payment info inside a @sell() decorated route
client.current_payment() # -> PaymentInfo(payer, amount, network, transaction)Example (FastAPI seller):
@app.get("/premium")
async def premium(payment=omniclaw.sell("$0.001")):
payment_info = omniclaw.current_payment()
return {"data": "paid content", "paid_by": payment_info.payer}# Execute a nanopayment to a seller's address
await client.pay(
wallet_id=wallet.id,
recipient="0xSellerAddress",
amount="0.001", # Small amount - uses gateway nanopayment
)
# Routes to Circle Gateway nanopayment if amount < nanopayments_micro_threshold# Get gateway balance
await client.get_gateway_balance(wallet_id="wallet-id")
# -> GatewayBalance(total, available, formatted_total, formatted_available)
# Deposit USDC to gateway wallet (enables receiving nanopayments)
await client.deposit_to_gateway(
wallet_id="wallet-id",
amount_usdc="10.00",
)
# Withdraw USDC from gateway wallet
await client.withdraw_from_gateway(
wallet_id="wallet-id",
amount_usdc="5.00",
destination_chain=None, # Optional: withdraw to another chain
recipient="0xDestination", # Optional: specific recipient
)
# Configure auto-topup for gateway balance
client.configure_nanopayments(
auto_topup_enabled=True,
auto_topup_threshold="1.00",
auto_topup_amount="10.00",
wallet_manager=gateway_wallet_manager,
)# Create an agent wallet
agent_wallet = await client.create_agent(
agent_name="data-agent",
)OMNICLAW_NANOPAYMENTS_ENABLED=true
OMNICLAW_NANOPAYMENTS_ENVIRONMENT=testnet # or "mainnet"
OMNICLAW_NANOPAYMENTS_MICRO_THRESHOLD=1.00
OMNICLAW_NANOPAYMENTS_AUTO_TOPUP=true
OMNICLAW_NANOPAYMENTS_TOPUP_THRESHOLD=1.00
OMNICLAW_NANOPAYMENTS_TOPUP_AMOUNT=10.00
# Nanopayments network is derived from OMNICLAW_NETWORK (EVM chain)Accessible through client.wallet.
Use it when you want direct wallet operations instead of the higher-level client helpers.
Primary methods:
create_wallet_set(name)
list_wallet_sets()
get_wallet_set(wallet_set_id)
create_wallet(wallet_set_id, blockchain=None, account_type=AccountType.EOA)
create_wallets(wallet_set_id, count, blockchain=None, account_type=AccountType.EOA)
setup_agent_wallet(agent_name, blockchain=None)
get_wallet(wallet_id)
list_wallets(wallet_set_id=None, blockchain=None)
list_transactions(wallet_id=None, blockchain=None)
get_balances(wallet_id)
get_usdc_balance(wallet_id)
get_usdc_balance_amount(wallet_id)
transfer(
wallet_id,
destination_address,
amount,
fee_level=FeeLevel.MEDIUM,
idempotency_key=None,
check_balance=True,
wait_for_completion=False,
timeout_seconds=None,
)Accessible through client.webhooks.
Primary methods:
WebhookParser(verification_key=None)
verify_signature(payload, headers)
handle(payload, headers)When verification is enabled, pass raw payload data and headers so signature verification happens before JSON parsing.
pay()andsimulate()are async.- Wallet creation helpers on
OmniClaware async. - Wallet-service methods are mixed: some are sync, some are async; prefer
OmniClawunless you need lower-level access. - Explicit trust checking requires a real
OMNICLAW_RPC_URL. - Redis configuration uses
OMNICLAW_REDIS_URLonly. OmniClawnow syncs the active entity secret into the managed config store when possible.- Managed config lives under the platform-specific OmniClaw config directory, such as
~/.config/omniclaw/on Linux.
Important exported exceptions:
ConfigurationErrorWalletErrorPaymentErrorGuardErrorProtocolErrorInsufficientBalanceErrorNetworkErrorX402ErrorValidationErrorNanopaymentNotInitializedErrorInsufficientBalanceErrorSettlementErrorNoDefaultKeyError