neura-agent — the agent client for NEURA Compute (Python)
OpenAI-compatible inference where the agent pays for itself.
- Automatic HTTP 402 handling — when NEURA says payment required it answers with an x402 envelope. The client settles it from the agent's own wallet on Base (USDC, 1 credit = $1), submits the tx hash, waits for the credit, and retries. No human, no card.
- Wallet-only onboarding (SIWE / EIP-4361) — an agent holding only a wallet key creates its account and self-provisions an API key. If the very first request is anonymous, the client does this itself before paying.
pip install neura-agent
With the official OpenAI SDK
import os
from openai import OpenAI
from neura_agent import NeuraAgent
neura = NeuraAgent(
wallet_key=os.environ["AGENT_WALLET_KEY"], # a hot wallet holding a little USDC on Base
auto_fund=True, # 402 -> (login) -> pay USDC -> credited -> retry
max_usdc_per_fund=5, # hard cap per payment
)
client = OpenAI(
base_url=neura.base_url + "/v1",
api_key="wallet", # placeholder — the client injects the key it provisions
http_client=neura.http_client(), # 402s handled transparently
)
r = client.chat.completions.create(
model="openai/gpt-oss-120b",
messages=[{"role": "user", "content": "Hello!"}],
)
Already have an API key? Pass api_key= and the wallet is only used to pay.
With LangChain
from langchain_openai import ChatOpenAI
from neura_agent import NeuraAgent
neura = NeuraAgent(wallet_key=os.environ["AGENT_WALLET_KEY"], auto_fund=True)
llm = ChatOpenAI(
model="openai/gpt-oss-120b",
base_url=neura.base_url + "/v1",
api_key="wallet",
http_client=neura.http_client(),
)
print(llm.invoke("Who pays for this call?").content)
With CrewAI
CrewAI routes through LiteLLM, which does not take a custom http client, so pre-fund before the crew runs and give it the provisioned key:
from crewai import LLM
from neura_agent import NeuraAgent
neura = NeuraAgent(wallet_key=os.environ["AGENT_WALLET_KEY"], auto_fund=True)
neura.login_with_wallet()
if neura.credit_balance() < 2:
neura.fund(neura.discovery(), credits=2) # 2 USDC -> 2 credits
llm = LLM(model="openai/openai/gpt-oss-120b", base_url=neura.base_url + "/v1", api_key=neura.api_key)
See examples/ for runnable versions of all three.
What the platform sends, and what the client does with it
A 402 carries an x402 v1 envelope. Production today:
{
"code": "PAYMENT_REQUIRED",
"x402Version": 1,
"accepts": [{
"scheme": "exact", "network": "base",
"maxAmountRequired": "1000000",
"payTo": "0x404f4E91Fc8Bf0c5fcfC71b4C06E2c0faACdb2c5",
"asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"extra": { "settlement": "transfer", "assetSymbol": "USDC", "decimals": 6,
"creditEndpoint": "/api/depin/credits/topup-usdc" }
}],
"authenticate": { "scheme": "EIP-4361", "nonce": "/api/auth/wallet/nonce", "verify": "/api/auth/wallet" }
}
choose_offer(body) picks the rail: the USDC exact offer whenever present;
a neura-burn offer only when advertised with a live rate. If the platform
offers nothing the client can settle, it raises instead of guessing.
Safety model
- Nothing moves on-chain unless you pass
wallet_keyandauto_fund=True(or callfund()yourself). max_usdc_per_fund(default 5) caps any single payment;max_neura_per_burn(default 100) caps any burn.pin_pay_torefuses to send USDC to any receiver other than the one you pin.- On 402 without auto-funding,
PaymentRequiredErrorcarriesremediation,x402and the fullbodyso your own logic can decide. - Use a dedicated hot wallet with a small balance — never a treasury key.
API
| Member | Purpose |
|---|---|
NeuraAgent(...) |
api_key, base_url, wallet_key, auto_fund, credits_per_fund, max_usdc_per_fund, max_neura_per_burn, confirmations, rpc_url, pin_pay_to |
agent.http_client() |
An httpx.Client whose send settles 402s — pass to OpenAI / LangChain |
agent.chat(model, messages, **params) |
Plain chat completion with the same 402 handling |
agent.login_with_wallet() |
SIWE login → {tenantId, address, apiKey} |
agent.fund(body, credits=None) |
Settle a 402 body (or a single offer) on the rail it advertises |
agent.fund_usdc(offer, credits) / agent.fund_burn(remediation) |
The rails individually |
agent.credit_balance() |
Current credits (1 = $1) |
agent.discovery() |
/.well-known/neura.json |
choose_offer(body) |
Which rail a 402 lets the client settle |
PaymentRequiredError |
Raised on unhandled 402 — carries remediation, x402, body |
Develop / publish
cd packages/neura-agent-py
pip install -e ".[test]"
pytest
python -m build && twine upload dist/*
Metadata
Release files for neura-agent 0.1.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 | |
|---|---|---|---|
| neura_agent-0.1.0.tar.gz | 12.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| neura_agent-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 23.1 kB
Release files / neura_agent-0.1.0.tar.gz
| Download URL | neura_agent-0.1.0.tar.gz |
|---|---|
| Size | 12.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b336d019f44f1b3e7d804b0ee8ff1011480b1d71b18e59068d7769fd0653de78
|
|
BLAKE2b-256 checksum How to use checksums |
24398ae9255f4961d977d5d708f7fc13176b6300e65e2704a6bbe8ee5655f396
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.11
|
Release files / neura_agent-0.1.0-py3-none-any.whl
| Download URL | neura_agent-0.1.0-py3-none-any.whl |
|---|---|
| Size | 10.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
435b3454912798e79266cb6db159e82f9ddd25d85d0c239b35357b347a3bd004
|
|
BLAKE2b-256 checksum How to use checksums |
4b85561206e090b9363cab0fb58cd3e9c1e5183cc93b34bd333c7299fcab3acb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.11
|