Skip to content
ggBlazePublic

About

Autonomous BSC trading agent. You sign once, it runs solo, you can kill it with one button. CoinMarketCap x402 data ($0.01/call), Trust Wallet signed txs (keys never leave the host), BNB Chain ERC-8004 identity + ERC-8183 escrow. 3 sleeves + 3-LLM safety team.

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

Β 

History

184 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

BNB Agent β€” an autonomous AI trading team

πŸ€– BNB Agent

You sign once. The agent runs for a week. You can kill it with one button.

An autonomous AI trading team on BNB Smart Chain β€” funding carry + DEX momentum + mean-reversion, gated by a single EIP-191-signed policy.

Built for the BNB HACK 2026 (CoinMarketCap Γ— Trust Wallet Γ— BNB Chain β€” $36K prize pool).

By Blaze Β· MIT License

CoinMarketCap Trust Wallet BNB Chain Python 3.10+ License: MIT Tests CI


What you get

🟑 CoinMarketCap Agent Hub β€” data layer

Real-time market data via x402 microcharges at $0.01 USDC per call (EIP-3009 transferWithAuthorization on Base). 3-tier selector β€” CMC Pro β†’ x402 β†’ Binance fallback β€” switchable from the dashboard Config pane. Daily cap with an amber banner at 80%.

  • Visible evidence: live CMC ledger on the dashboard, every cost line deep-linked to BaseScan.

🟣 Trust Wallet Agent Kit (TWAK) β€” signing layer

Self-custody local signing. AES-256-GCM keystore + PBKDF2 200k iters at ~/.twak/wallet.json. Every BSC transaction is signed locally β€” keys never leave the host.

  • Visible evidence: live TWAK-signed tx list on the dashboard with BscScan deep links.

🟠 BNB Chain AI Agent SDK β€” on-chain layer

BSC mainnet, PancakeSwap v3 swaps, plus two on-chain standards:

  • ERC-8004 identity NFT β€” agent wallet, tokenId, IPFS metadata, traits.
  • ERC-8183 job escrow β€” PnL deliverables as jobs (Open β†’ Funded β†’ Submitted β†’ Completed).
  • Visible evidence: live identity panel + jobs lifecycle on the dashboard.

βš™οΈ Three strategies, one risk envelope, one sign

Sleeve Capital Strategy Target
A β€” Funding carry 70% Long spot + short perp on PCS v3 Ξ”-neutral, ~+0.5% APR
B β€” DEX momentum 20% CMC volume-spike + 4h breakout Capped at 1% per trade
C β€” Mean reversion 10% Fades 1h drops >2.0Οƒ Capped at 0.5% per trade
  • 5% daily loss circuit breaker (vs 30% contest disqualification = 6Γ— safer)
  • 1% per-trade risk cap Β· 2Γ— max leverage Β· 15% max single position
  • 3-layer LLM safety team (advisor + reviewer + chat) β€” they can only tighten your policy, never loosen it
  • Kill switch in the right rail β€” halts all new orders instantly
  • 149 BEP-20 eligible tokens pinned to the BNB HACK Track 1 list
  • You sign once. The agent runs for a week. You can kill it with one button.

πŸš€ One install command, one run command

bash install.sh      # creates venv, installs deps, signs a dev policy
bash bnbagent        # starts agent + dashboard on http://localhost:8000

BNB Agent is an autonomous BSC trading agent plus a 3-layer LLM agent team (advisor / reviewer / chat) plus a Token Module (deploy + landing-page generator) plus a Skills registry plus an MCP server exposing all of the above to other agents.

It runs three strategies in parallel on BNB Smart Chain, pays for its own market data with USDC via x402, signs its own transactions with Trust Wallet's Agent Kit (TWAK), registers its own identity NFT via ERC-8004, and escrows its own PnL deliverables via ERC-8183 jobs β€” all gated by a single user-signed policy.


Table of contents

  1. Quick start
  2. What it does
  3. Architecture
  4. The 3-LLM agent team
  5. Sponsor integration
  6. Token Module
  7. Skills registry
  8. MCP server
  9. Risk engine
  10. Dashboard
  11. Configuration
  12. Environment variables
  13. Repository layout
  14. Documentation
  15. Testing
  16. Security model
  17. Deployment
  18. Contributing
  19. License

1. Quick start

git clone <your-private-repo> bnbagent && cd bnbagent
bash install.sh                       # one command β€” venv, deps, signed dev policy
export OPENROUTER_API_KEY=sk-or-...   # any one of 5 supported providers (optional)
bash bnbagent                         # agent + dashboard on http://localhost:8000

That's it. The dashboard auto-loads; first-time users land in the Setup wizard (Network β†’ Wallet β†’ Sign Policy β†’ Data source β†’ Ready). After the wizard, the dashboard switches to the Live pane. The Setup wizard has a new 'Data source' step (CMC Pro / x402 / Binance).

v2.1.1: the wizard writes your choices to config/local.yaml (gitignored), not the tracked config/config.yaml. The shipped defaults file stays clean; your CMC Pro API key and custom RPCs never accidentally land in a commit. See core/config_paths.py for the merge semantics.

v2.1.2: every runtime write lands in a gitignored file. The operator-signed config/policy.yaml, the Token Module's agents/token_module.yaml, and the TWAK keystore at ~/.twak/ are all gitignored. The repo state is reproducible from git clone β€” the only thing that varies between operators is the local.yaml shadow and the runtime state in ~/.bnbagent/. The contract is pinned by tests/unit/test_repo_cleanliness.py (36 tests).

v2.1.3: dashboard UI gaps closed. The Config pane now has an LLM API key section (Set + Test buttons, writes to .env, restart-to-apply) and a Personas section listing all 4 personas (View / Edit / Reset). The Token Module has inline name + symbol form fields (replacing the old window.prompt() dialogs) plus a prominent network notice (green for testnet, red for mainnet) that updates when you change the dropdown.

v2.1.4: BNB HACK 2026 compliance. The contest page publishes a fixed 149-BEP-20 eligible list, requires on-chain registration before June 22, and demands 1 trade/day for 7 days. This release pins the eligible list (data/eligible_tokens.json), filters every trade universe against it (sleeves + risk engine), wraps npx twak compete register as a script + MCP tool + dashboard button, and adds a daily trade floor that fires a 0.1%-of-equity rebalance at 23:30 UTC if no sleeve traded that day. 47 new tests, full audit at docs/compliance.md.

v2.1.5: test infra + Sharpe annualization fix. Two cleanups ahead of submission. (1) tests/conftest.py now auto-generates a dev-signed config/policy.yaml (via policy.policy_sign --dev) if the file is missing at the start of a test session, and cleans it up afterward. This is a belt-and-suspenders for the canonical bash install.sh path β€” fresh clones and CI can run pytest directly without manually copying the example. (2) Backtest Sharpe / Sortino were annualized with the default 365*24*60 (minute samples) even though the replay equity curve has only ~200 points across 7 days (~36k samples/year, not 525k). The previous replay_bull.json Sharpe of 41 was real arithmetic, just annualizing the wrong sample frequency β€” Sharpe now reflects the actual sample count and is reported in the JSON's samples_per_year field for transparency. The same fix is applied to core/portfolio.py:sharpe() (the live-path version) which now accepts an explicit samples_per_year parameter.

Command What it does
bash bnbagent start the agent + dashboard, Ctrl+C stops both
bash bnbagent --replay run a 7-day synthetic replay; HTML report at data/reports/replay.html
bash bnbagent --repl open a Python REPL with p = boot(...) pre-loaded
bash scripts/mcp_serve.sh opt-in β€” run the MCP server (stdio, for Claude Code / Goose) as a separate process
bash scripts/mcp_serve_sse.sh opt-in β€” run the MCP server (SSE, port 8765) for remote agents

Reproducibility / judges: the backtest table in docs/demo-script.md is generated by python -m scripts.run_both_regimes (3 regimes Γ— 2 tape intervals, equity=1000). bash bnbagent --replay runs a single 7-day synthetic regime with the default equity=100 β€” useful as a quick smoke test, but its numbers won't match the table (different position sizing β†’ different trade count β†’ different Sharpe). To audit the math, open the JSON in data/reports/ and check the samples_per_year field β€” that's the actual annualization denominator (v2.1.5: was hardcoded to 525,600, now computed from the tape duration / equity-curve length).

Requires Python 3.10+ and (optionally) Node 18+ for the TWAK CLI fallback. The dashboard works offline; the only required network access is to BSC RPCs and (if LLM is enabled) to your LLM provider.


2. What it does

Strategy β€” three sleeves composed for the PnL-replay judging axes

Sleeve Capital Strategy Expected PnL Drawdown
A β€” Funding carry 70% Long spot on PancakeSwap v3 + short perp on a BSC venue. Delta-neutral. Collects funding every 8h. +0.5% APR baseline very low
B β€” DEX momentum 20% CMC signals (volume spike + 4h breakout) β†’ 1–4h long with ATR stop and 3% TP. Quarter-Kelly sizing. positive alpha capped at 1%/trade
C β€” Mean reversion 10% Fades 1h drops >2.5Οƒ on top-20 BSC tokens. 2% stop, 1% target. positive alpha capped at 0.5%/trade

70% of capital is hedged (delta-neutral carry), with a 5% daily circuit breaker + 1% per-trade cap + 2Γ— leverage cap. The agent is designed for low drawdown β€” see data/reports/replay_{bull,bear,chop}.json for the honest backtest (max DD < 2% in all three synthetic regimes).

Hard risk controls (the only UX prompt the user sees)

  • Daily loss circuit breaker: 3%
  • Per-trade risk cap: 1%
  • Max gross leverage: 2Γ—
  • Max single position: 15%
  • Curated token allowlist (top-50 CMC + vetted BSC DEX list)
  • Per-symbol post-loss cool-off (4h for momentum, 6h for mean-rev) to prevent revenge trades
  • Signed User Policy β€” policy.yaml is the only file the user signs (EIP-191). Every order is checked against it via circuit_breaker_check() before going on-chain.
  • Dashboard kill switch β€” halts all new orders, leaves open positions to TP/stop themselves

Audited

A 10-item trading-logic audit pass before the live window, all fixes applied. See docs/audit-2026-06-05.md.


3. Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  USER  signs policy.yaml ONCE  (EIP-191)                                    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                         β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  BNB AGENT  (Python, asyncio)                                                β”‚
β”‚                                                                              β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚ Sleeve A    β”‚  β”‚ Sleeve B    β”‚  β”‚ Sleeve C    β”‚  β”‚  AI Agent Team     β”‚   β”‚
β”‚  β”‚ 70% carry   β”‚  β”‚ 20% momentumβ”‚  β”‚ 10% meanrev β”‚  β”‚  (3 LLM layers)    β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜             β”‚              β”‚
β”‚                           β–Ό                                β”‚              β”‚
β”‚         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”      β”‚
β”‚         β”‚      core/risk.py                    β”‚   β”‚  Advisor       β”‚      β”‚
β”‚         β”‚      circuit_breaker_check()        β”‚   β”‚  (5-min loop,  β”‚      β”‚
β”‚         β”‚   + Agent.review_trade()  L2        β”‚   β”‚   can only     β”‚      β”‚
β”‚         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚   TIGHTEN)     β”‚      β”‚
β”‚                        β”‚                           β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€      β”‚
β”‚         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚  Reviewer      β”‚      β”‚
β”‚         β”‚       core/portfolio.py             β”‚   β”‚  (per-trade,   β”‚      β”‚
β”‚         β”‚       equity, peak, PnL, DD         β”‚   β”‚   can only     β”‚      β”‚
β”‚         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚   VETO)        β”‚      β”‚
β”‚                        β”‚                           β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€      β”‚
β”‚                        β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”‚  Chat          β”‚      β”‚
β”‚                        β”‚   β”‚  Token Module    │◄────  (conversationalβ”‚    β”‚
β”‚                        β”‚   β”‚  + Token Website β”‚    β”‚   + 9 tools)   β”‚      β”‚
β”‚                        β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β”‚
β”‚                        β”‚                           β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”‚
β”‚                        β”‚                           β”‚  Skills Reg.   β”‚      β”‚
β”‚                        β”‚                           β”‚  (6 built-ins) β”‚      β”‚
β”‚                        β”‚                           β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β”‚
β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
     β”‚                   β”‚                   β”‚
β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ CoinMarketCapβ”‚  β”‚  Trust      β”‚  β”‚  BNB AI Agent    β”‚  β”‚  Agent MCP        β”‚
β”‚  Agent Hub   β”‚  β”‚  Wallet     β”‚  β”‚  SDK (bnbagent-  β”‚  β”‚  Server           β”‚
β”‚  Data API +  β”‚  β”‚  Agent Kit  β”‚  β”‚  sdk)            β”‚  β”‚  (stdio + SSE)    β”‚
β”‚  x402 ($0.01)β”‚  β”‚  (TWAK)     β”‚  β”‚  BSC + PCS v3    β”‚  β”‚  11 MCP tools     β”‚
β”‚  + Skills    β”‚  β”‚  AES-256-   β”‚  β”‚  + perps         β”‚  β”‚  for other agents β”‚
β”‚              β”‚  β”‚  GCM        β”‚  β”‚  + ERC-8004      β”‚  β”‚  (Claude Code,   β”‚
β”‚              β”‚  β”‚  + PBKDF2   β”‚  β”‚  + ERC-8183      β”‚  β”‚  Goose, Cursor)  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

The 3 sponsor layers are deeply integrated:

Layer Sponsor What BNB Agent uses it for Visible evidence
L1 CoinMarketCap Agent Hub Data API + Data MCP + Skills + x402 ($0.01 USDC/request via EIP-3009 transferWithAuthorization) Live x402 microcharge ledger on the dashboard, every cost line, BscScan-deep-linked
L2 Trust Wallet Agent Kit (TWAK) Self-custody local signing, AES-256-GCM keystore, PBKDF2 200k iters, at ~/.twak/wallet.json Live TWAK-signed tx list with BscScan deep links; "keys never left the host"
L3 BNB AI Agent SDK BSC mainnet, PancakeSwap v3, BSC perps, ERC-8004 identity NFT, ERC-8183 job escrow, x402 finality <200ms Live identity panel (tokenId + IPFS metadata + 8004scan link) and jobs lifecycle (Open β†’ Funded β†’ Submitted β†’ Completed)

4. The 3-LLM agent team

BNB Agent runs an LLM in three distinct roles. Each is strictly constrained so the LLM is pure additive value on top of the deterministic trading engine.

Layer Role Loop Can do Cannot do
1 β€” Advisor Recommends TIGHTENING risk changes based on recent state every 5 min Lower risk caps, disable sleeves, all in core.control.write_control (same audit path as dashboard) Loosen any cap, raise per-trade risk, enable a disabled sleeve
2 β€” Reviewer Vetoes a trade before it goes on-chain per-trade, 0.5s timeout Veto, falls back to heuristic in <1ms Raise risk, override circuit-breaker, bypass the policy
3 β€” Chat Conversational interface for the operator on user input Read state, dispatch 9 tools, recommend policy changes Apply any policy change β€” user must re-sign in Setup wizard

Hard safety envelope (all enforced in code, never delegated to the LLM):

  • The advisor's _apply() compares new < old for every numeric cap. Even a hostile LLM cannot raise a cap.
  • The reviewer's _heuristic_veto always runs after the LLM and checks: sleeve drawdown > 50% of cap, win-rate < 20%, post-loss cooldown active.
  • The chat's recommend_risk_change returns a recommendation and a UI prompt to the Setup wizard β€” it never writes to the policy or the control file.

Provider-agnostic

agents/providers.yaml (5 adapters, no third-party SDKs):

default: openrouter
providers:
  anthropic:  { base: https://api.anthropic.com,  key: $ANTHROPIC_API_KEY }
  openai:     { base: https://api.openai.com,     key: $OPENAI_API_KEY }
  openrouter: { base: https://openrouter.ai/api,  key: $OPENROUTER_API_KEY }
  oai_compat: { base: $OAI_BASE,                  key: $OAI_KEY }
  local:      { base: $LOCAL_LLM_BASE,             key: "" }   # llama.cpp / ollama

agents:
  advisor:        { provider: openrouter, model: anthropic/claude-3.5-haiku,  max_tokens: 512,  temperature: 0.1 }
  reviewer:       { provider: openrouter, model: anthropic/claude-3.5-haiku,  max_tokens: 256,  temperature: 0.0 }
  chat:           { provider: openrouter, model: anthropic/claude-3.5-sonnet, max_tokens: 2048, temperature: 0.4 }
  token_module:   { provider: openrouter, model: anthropic/claude-3.5-haiku,  max_tokens: 8000, temperature: 0.7 }

All 4 agents can use different providers. The agent still runs as a deterministic bot if no provider is configured.

Personas

4 personas in markdown under agents/_pro_defaults/:

  • advisor.md β€” strict tightening-only persona
  • reviewer.md β€” strict veto-in-doubt persona
  • chat.md β€” operator-facing persona with the 9-tool list
  • token_module.md β€” token deploy + website generation

Each persona is editable from the dashboard (Chat pane β†’ "view persona" β†’ edit β†’ "save") and resettable to the pro default ("reset to pro"). The dashboard shows a "diverged" warning when the user-edited copy drifts from the pro default.

Full details: docs/agents.md.


5. Sponsor integration

L1 β€” CoinMarketCap Agent Hub (Data API + Data MCP + Skills + x402)

Every market-data call (quotes, OHLCV, listings, info) goes through x402. The agent pays for its own data with USDC stablecoins, no API key required, $0.01/request. The flow:

agent β†’ GET /v1/quotes/latest β†’ 402 Payment Required
agent β†’ EIP-3009 sign USDC transferWithAuthorization
agent β†’ X-PAYMENT header (base64) β†’ retry β†’ 200 OK

Settlement is on Base (chain 8453) via native USDC 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 with the x402 exact-EVM scheme. The retry header is PAYMENT-SIGNATURE. The dashboard shows the full microcharge ledger (/api/cmc-charges) with BaseScan-deep-linkable tx hashes. Daily spend is capped by policy.fees.x402_max_usdc_per_day (default $10).

L2 β€” Trust Wallet Agent Kit (TWAK)

Every BSC transaction is signed locally with TWAK. The keystore at ~/.twak/wallet.json is encrypted with AES-256-GCM (12-byte IV, 16-byte auth tag) and a key derived from the password with PBKDF2-HMAC-SHA256 (200k iterations). The Setup wizard in the dashboard creates/imports the wallet, encrypts it, and signs the policy with it.

The private key never leaves the host process. The dashboard never has it. The browser never sees it.

L3 β€” BNB AI Agent SDK

The agent uses the bnbagent-sdk (or its connector equivalents):

  • BSCClient β€” connection-pooled, RPC-rotating BSC client
  • PancakeV3 β€” swap + quote helpers
  • Perps β€” multi-venue funding/OI/position adapter
  • ERC8004 β€” identity NFT registration
  • ERC8183 β€” job escrow lifecycle

The agent mints its own ERC-8004 identity NFT at startup (pinned to IPFS) and opens ERC-8183 jobs per evaluation window β€” one per sleeve + an aggregator. The user is the evaluator; they sign complete() at window end. USDC releases to the agent on-chain.

Full details: docs/onchain.md, docs/x402.md, docs/architecture.md.


6. Token Module

A first-class dashboard tab (not a Skill). Deploys ERC-20 / BEP-20 / OpenZeppelin tokens on BSC, with optional single-file HTML landing-page generation.

Chat: "create a token called Mooncoin with symbol MOON and supply 1B"
  β†’ TokenModule.create_token(name, symbol, supply, ...)
  β†’ x402-pays CMC for token metadata (logged to microcharge ledger)
  β†’ TWAK-signs the contract-creation tx
  β†’ BNB SDK broadcasts; rcpt.contract_address is the new token's address
  β†’ metadata pinned to IPFS
  β†’ if create_website=true β†’ LLM generates a single-file HTML page
    (sanitized against eval/document.write, no external resources)
  β†’ returns { contract_address, tx_hash, explorer_url, website_html }

Mainnet deploy requires the user to type the token name in a confirmation dialog in the dashboard. The MCP tool also requires confirm_mainnet: true. Both are belt-and-suspenders.

Full details: docs/TOKEN_MODULE.md.


7. Skills registry

6 built-in Skills, discoverable, hot-toggled:

Skill Category Effect
telegram_alert notification DM on every trade close (TELEGRAM_BOT_TOKEN + TELEGRAM_CHAT_ID)
farcaster_post notification Auto-post PnL updates (WARPCAST_KEY, rate-limited 1/h)
webhook_dispatch notification POST every event to a user-configured URL (WEBHOOK_URL)
x_sentiment data Sentiment score for top BSC tokens (X API primary, CMC trending fallback)
cmc_global_filter data The only Skill that writes β€” pauses all sleeves on bear regime
glassnode_onchain data Stub for the contest; deterministic score for the UI

State persisted to ~/.bnbagent/skills.json. The chat can enable_skill(name) / disable_skill(name) directly. The dashboard's Skills tab lists all + their enabled state.

Full details: docs/SKILLS.md.


8. MCP server (other agents can call ours) β€” opt-in

Heads up: the MCP server is not started by bash bnbagent. It's an opt-in service for when you want other agents to call into the BNB Agent. Run it as a separate process. This is intentional β€” the default bnbagent run is a self-contained agent + dashboard, with nothing listening for outside MCP clients.

agent_mcp/mcp_server.py exposes the BNB Agent as 11 MCP tools over stdio or SSE:

Tool What it does
bnbagent_get_pnl Live portfolio stats
bnbagent_list_positions Open positions across all sleeves
bnbagent_list_trades(n) Recent closed trades
bnbagent_get_policy Current signed policy summary
bnbagent_recommend_risk_change Recommendation only β€” never writes
bnbagent_deploy_token TokenModule deploy (mainnet requires confirm_mainnet=true + confirm_symbol match)
bnbagent_chat Talk to the LLM in natural language
bnbagent_list_skills List all Skills + enabled state
bnbagent_enable_skill / bnbagent_disable_skill Toggle Skills

Run the server (separate from bnbagent):

# stdio β€” for Claude Code / Goose / Cursor (configure in their mcp_servers.json)
bash scripts/mcp_serve.sh

# SSE β€” for remote agents, port 8765 by default
bash scripts/mcp_serve_sse.sh

Integrate with any MCP client β€” the server speaks stdio, so any MCP-compatible client can drive the BNB Agent. Example configs:

Claude Code (~/.claude/mcp_servers.json):

{
  "mcpServers": {
    "bnbagent": {
      "command": "bash",
      "args": ["/home/style/bnbagent/scripts/mcp_serve.sh"],
      "env": { "PYTHONPATH": "/home/style/bnbagent" }
    }
  }
}

Goose / Cursor / Continue / any other MCP client β€” same shape: a stdio command that runs scripts/mcp_serve.sh (or directly python -m agent_mcp.mcp_server --transport stdio). Check your client's docs for the exact config-file location and JSON schema; the keys are always mcpServers.<name>.command + args + env.

Restart the client, then it will discover the 10 bnbagent tools (bnbagent_get_pnl, bnbagent_deploy_token, bnbagent_chat, etc). The integration test (tests/integration/test_mcp.py) spawns the server and calls every tool end-to-end.

Full details: docs/MCP.md.


9. Risk engine

The risk engine is the only enforcement of the signed User Policy. Every order is gated by circuit_breaker_check() in core/risk.py.

Check Refuses if Default
0. Cooldown now < day_breach_active_until 60min after a daily breach
1. Daily loss (day_start - equity) / day_start β‰₯ daily_loss_circuit_breaker_pct 3%
2. Max drawdown (peak - equity) / peak β‰₯ max_drawdown_pct 8%
3. Per-trade risk risk / equity > per_trade_risk_pct 1%
4. Single position notional / equity > max_single_position_pct 15%
5. Gross leverage gross / equity > max_gross_leverage 2Γ—
6. Allowlist symbol not in policy.allowlist.bsc_tokens top-50 CMC + BSC DEX
7. Sleeve cap notional / equity > sleeves[X].max_position_pct per-sleeve
8. Sleeve enabled sleeves[X].enabled == false β€”
9. Kill switch (added in v2.0) policy._kill_switch == true dashboard button

Layer 2 (per-trade reviewer) runs after the circuit breaker and before sign_transaction. Hard-coded timeout (0.5s) β†’ heuristic-only fallback.

Full details: docs/agents.md, docs/audit-2026-06-05.md.


10. Dashboard

Single-page app (vanilla HTML/CSS/JS, no build step, no framework, ~1800 lines) at http://localhost:8000. Mission-control aesthetic β€” Inter for display, JetBrains Mono for numerics, hand-drawn SVG equity chart with gradient fill, animated live-status pulse, acid-lime accent on near-black.

Pane Source Refresh Purpose
Setup setup files β€” First-time user wizard (Network β†’ Wallet β†’ Sign Policy β†’ Data source β†’ Ready)
Live /api/stats, /api/equity-series 1.5s Hero strip (equity, PnL, DD, Sharpe), SVG equity chart, sleeve cards, x402 ledger, TWAK txs, identity, jobs, trades
Chat /api/chat, /api/agent/advisor, /api/agent/reviewer per message Talk to the LLM; persona modal; recent decisions table
Tokens /api/tokens/* β€” Token Module config form + deploy button + result card with explorer link + website download
Config /api/control, /api/llm/status on change Sleeve toggles, risk overrides, LLM provider config
Logs /api/logs/stream (SSE) live Live agent log; color-coded by level
Replay β€” β€” Pointer to bash bnbagent --replay

Right rail (always visible):

  • System status (mode, chain, address, wallet, last update)
  • Sleeve toggles
  • Control log (advisor + dashboard edits)
  • Kill switch (red button, also in the Setup wizard)

Full details: docs/operations.md.


11. Configuration

Two config files, both externalized so the agent can be configured without code changes:

File What Who edits
config/config.yaml Network, RPCs, gas, token registry, DEX/perps endpoints, CMC, tick intervals operator (or via the Setup wizard)
config/policy.yaml The signed User Policy (EIP-191) operator (or via the Setup wizard)

A third file, agents/providers.yaml, configures the LLM provider routing. The Setup wizard writes a default; the LLM Status page in the dashboard lets you change it.

A fourth file, agents/token_module.yaml, configures the Token Module (default protocol, default supply, default network, website theme).

A fifth file, agents/mcp.yaml (auto-generated if missing), configures the MCP server transport.


12. Environment variables

See .env.example for the full list. All optional.

Var Default Notes
BNBAGENT_DASHBOARD_PORT 8000 dashboard HTTP port
BNBAGENT_EQUITY 100 starting USDC equity
BNBAGENT_LOG_LEVEL INFO agent log level
BNBAGENT_CONTROL_FILE ~/.bnbagent/control.json dashboard β†’ agent IPC
BNBAGENT_MCP_HOST 0.0.0.0 MCP SSE host
BNBAGENT_MCP_PORT 8765 MCP SSE port
TWAK_KEYSTORE β€” TWAK JSON keystore path
TWAK_PWD β€” TWAK keystore password
BNBAGENT_PRIVATE_KEY β€” dev-only fallback (do not use in prod)
OPENROUTER_API_KEY β€” easiest LLM provider (covers all 4 agents)
ANTHROPIC_API_KEY β€” direct Anthropic
OPENAI_API_KEY β€” direct OpenAI
OAI_BASE / OAI_KEY β€” generic OAI-compatible
LOCAL_LLM_BASE http://127.0.0.1:8080 llama.cpp / ollama
TELEGRAM_BOT_TOKEN / TELEGRAM_CHAT_ID β€” telegram_alert skill
WARPCAST_KEY β€” farcaster_post skill
WEBHOOK_URL β€” webhook_dispatch skill
CMC_API_KEY β€” optional Pro API key (x402 otherwise)
BASE_RPCS https://mainnet.base.org,https://base.publicnode.com,https://1rpc.io/base comma-separated Base mainnet RPC URLs (x402 funding detection polls all of them in rotation)

13. Repository layout

bnbagent/
β”œβ”€β”€ README.md                       ← you are here
β”œβ”€β”€ LICENSE                        ← MIT
β”œβ”€β”€ install.sh                     ← one-command installer
β”œβ”€β”€ bnbagent                       ← one-command runner
β”œβ”€β”€ pyproject.toml                 ← Python deps + setuptools packages
β”œβ”€β”€ package.json                   ← Node deps (@trustwallet/cli)
β”œβ”€β”€ .env.example                   ← every env var, all optional
β”‚
β”œβ”€β”€ config/                        ← externalized configs
β”‚   β”œβ”€β”€ config.yaml                ← network/RPCs/tokens/DEX/perps/CMC/ticks
β”‚   β”œβ”€β”€ policy.yaml                ← signed User Policy
β”‚   β”œβ”€β”€ policy.schema.json         ← JSON schema
β”‚   β”œβ”€β”€ allowlist.yaml             ← curated top-50 CMC + BSC DEX
β”‚   β”œβ”€β”€ perps_venues.yaml          ← Aster/KiloEx/ApolloX/MUX
β”‚   └── tokens.mainnet.yaml
β”‚
β”œβ”€β”€ core/                          ← the agent loop
β”‚   β”œβ”€β”€ boot.py                    ← load configs, init wallet, register identity
β”‚   β”œβ”€β”€ main.py                    ← entry point (3 sleeves + advisor)
β”‚   β”œβ”€β”€ portfolio.py               ← equity, peak, PnL, DD, drawdown_pct
β”‚   β”œβ”€β”€ risk.py                    ← circuit_breaker_check()
β”‚   β”œβ”€β”€ tick.py                    ← TickLoop, Agent, review_trade hook
β”‚   β”œβ”€β”€ control.py                 ← dashboard β†’ agent IPC
β”‚   β”œβ”€β”€ setup.py                   ← Setup wizard backend
β”‚   └── utils.py                   ← shared helpers
β”‚
β”œβ”€β”€ connectors/                    ← sponsor adapters
β”‚   β”œβ”€β”€ cmc.py                     ← CoinMarketCap Data API + x402
β”‚   β”œβ”€β”€ x402.py                    ← EIP-3009 transferWithAuthorization
β”‚   β”œβ”€β”€ twak.py                    ← Trust Wallet Agent Kit (signing)
β”‚   β”œβ”€β”€ bnb_sdk.py                 ← BSC + PCS v3 + Perps + ERC-8004 + ERC-8183
β”‚   β”œβ”€β”€ ipfs.py                    ← local IPFS pinning
β”‚   └── keystore.py                ← AES-256-GCM + PBKDF2 wallet encryption
β”‚
β”œβ”€β”€ strategies/                    ← the 3 sleeves
β”‚   β”œβ”€β”€ sleeve_a_carry.py
β”‚   β”œβ”€β”€ sleeve_b_momentum.py
β”‚   └── sleeve_c_meanrev.py
β”‚
β”œβ”€β”€ agents/                        ← AI Agent Team
β”‚   β”œβ”€β”€ providers.py               ← LLMClient Protocol + 5 adapters + LLMRouter
β”‚   β”œβ”€β”€ providers.yaml             ← per-agent provider+model routing
β”‚   β”œβ”€β”€ base.py                    ← PersonaLoader + llm_complete + llm_stream
β”‚   β”œβ”€β”€ advisor.py                 ← Layer 1: 5-min tightening loop
β”‚   β”œβ”€β”€ reviewer.py                ← Layer 2: per-trade veto
β”‚   β”œβ”€β”€ chat.py                    ← Layer 3: conversational + 9 tools
β”‚   β”œβ”€β”€ token_module.py            ← TokenModule (deploy + website)
β”‚   β”œβ”€β”€ _pro_defaults/             ← canonical pro personas (resettable)
β”‚   β”‚   β”œβ”€β”€ advisor.md
β”‚   β”‚   β”œβ”€β”€ reviewer.md
β”‚   β”‚   β”œβ”€β”€ chat.md
β”‚   β”‚   └── token_module.md
β”‚   β”œβ”€β”€ personas/                  ← live user-editable personas
β”‚   └── prompts/                   ← user-prompt templates
β”‚
β”œβ”€β”€ agent_mcp/                     ← MCP server (stdio + SSE)
β”‚   β”œβ”€β”€ __init__.py
β”‚   └── mcp_server.py              ← 11 MCP tools
β”‚
β”œβ”€β”€ skills/                        ← discoverable, hot-toggled modules
β”‚   β”œβ”€β”€ base.py                    ← Skill abstract base
β”‚   β”œβ”€β”€ registry.py                ← SkillRegistry (discover / enable / disable)
β”‚   β”œβ”€β”€ notification/              ← telegram_alert, farcaster_post, webhook_dispatch
β”‚   └── data/                      ← x_sentiment, cmc_global_filter, glassnode_onchain
β”‚
β”œβ”€β”€ policy/                        ← EIP-191 sign + verify + version bump
β”œβ”€β”€ identity/                      ← ERC-8004 metadata + registration
β”œβ”€β”€ jobs/                          ← ERC-8183 open / submit / finalize
β”‚
β”œβ”€β”€ dashboard/
β”‚   β”œβ”€β”€ backend/                   ← FastAPI
β”‚   β”‚   β”œβ”€β”€ main.py                ← all API endpoints (40+)
β”‚   β”‚   β”œβ”€β”€ metrics.py
β”‚   β”‚   └── stream.py
β”‚   └── frontend/                  ← single HTML file, ~1800 lines
β”‚       └── index.html
β”‚
β”œβ”€β”€ backtest/                      ← replay harness + metrics
β”‚   β”œβ”€β”€ fetch_history.py
β”‚   β”œβ”€β”€ metrics.py
β”‚   └── replay.py
β”‚
β”œβ”€β”€ tests/                         ← 683/697 passing (enforced by CI)
β”‚   β”œβ”€β”€ unit/                      ← ~13 files
β”‚   β”œβ”€β”€ integration/               ← 1 file (MCP)
β”‚   └── fixtures/                  ← llm.py, wallets.py, skills.py
β”‚
β”œβ”€β”€ scripts/                       ← the granular launchers
β”‚   β”œβ”€β”€ first_run.sh               ← 5-command sanity check
β”‚   β”œβ”€β”€ sign_policy.sh
β”‚   β”œβ”€β”€ register_agent.sh
β”‚   β”œβ”€β”€ open_window.sh
β”‚   β”œβ”€β”€ replay_week.sh
β”‚   β”œβ”€β”€ start_agent.sh
β”‚   β”œβ”€β”€ start_dashboard.sh
β”‚   β”œβ”€β”€ finalize_window.sh
β”‚   β”œβ”€β”€ mcp_serve.sh               ← MCP stdio launcher
β”‚   └── mcp_serve_sse.sh           ← MCP SSE launcher
β”‚
β”œβ”€β”€ docs/                          ← full documentation
β”‚   β”œβ”€β”€ agents.md
β”‚   β”œβ”€β”€ architecture.md
β”‚   β”œβ”€β”€ audit-2026-06-05.md
β”‚   β”œβ”€β”€ API.md                     ← every endpoint
β”‚   β”œβ”€β”€ CHANGELOG.md
β”‚   β”œβ”€β”€ CONTRIBUTING.md
β”‚   β”œβ”€β”€ demo-script.md
β”‚   β”œβ”€β”€ install.md
β”‚   β”œβ”€β”€ MCP.md
β”‚   β”œβ”€β”€ onchain.md
β”‚   β”œβ”€β”€ operations.md
β”‚   β”œβ”€β”€ PERSONAS.md
β”‚   β”œβ”€β”€ policy.md
β”‚   β”œβ”€β”€ SECURITY.md
β”‚   β”œβ”€β”€ setup-wizard.md
β”‚   β”œβ”€β”€ SKILLS.md
β”‚   β”œβ”€β”€ strategy.md
β”‚   β”œβ”€β”€ submission.md
β”‚   β”œβ”€β”€ TOKEN_MODULE.md
β”‚   └── x402.md
β”‚
└── infra/                         ← docker, systemd (optional)

14. Documentation

File Topic
docs/architecture.md Architecture diagram + data flow + key design decisions
docs/strategy.md The 3 sleeves in plain English, plus the scoring rationale
docs/onchain.md ERC-8004 identity + ERC-8183 job lifecycle
docs/x402.md x402 pay-per-request protocol, EIP-3009, daily spend cap
docs/policy.md The signed User Policy, how signing works, how verification works
docs/POLICY_CHANGELOG.md Per-version policy change log β€” every relaxation of a safety threshold with the rationale, the backtest tape, and the worst-case DD observed. v2.0.8-M1.
docs/install.md One-command install + every env var
docs/operations.md Dashboard pane reference + kill switch + control log
docs/setup-wizard.md The 5-step Setup wizard (Network β†’ Wallet β†’ Sign Policy β†’ Data source β†’ Ready)
docs/agents.md The 3-LLM agent team in depth (advisor / reviewer / chat)
docs/TOKEN_MODULE.md Token deploy + landing-page generation + mainnet guard
docs/SKILLS.md Skills registry + 6 built-ins + the cmc_global_filter pause rule
docs/MCP.md MCP server transport, 11 tools, generic MCP-client integration
docs/PERSONAS.md Persona format + reset semantics + diverged flag
docs/API.md Every HTTP endpoint (40+) with request/response examples
docs/SECURITY.md Threat model, signing, key mgmt, MCP exposure, audit trail
docs/CONTRIBUTING.md Dev setup, code style, testing, PR process
docs/CHANGELOG.md v1.0 β†’ v2.0 history
docs/audit-2026-06-05.md 10-item trading-logic audit pass + fixes
docs/submission.md Hackathon form fields pre-filled + pre-submission checklist
docs/demo-script.md 3-minute demo video script (judge-facing)
salepitch.md One-page sales pitch + feature pitch

15. Testing

pytest -q                          # 683/697 passing (~3:40 cold, ~12s unit-only)
                                   # 2 pre-existing failures: replay JSON drift (test_meta)
                                   # + IPC identity drift (test_dashboard_state_ipc) β€” non-blocking
pytest tests/unit/                 # fast unit tests
pytest tests/integration/          # MCP end-to-end
pytest tests/unit/test_risk.py -v # 1 file

Test layout:

  • tests/unit/ β€” 13 files, ~140 unit tests
  • tests/integration/ β€” 1 file (MCP subprocess + tool calls)
  • tests/fixtures/llm.py β€” FakeLLMClient (records calls, returns scripted responses)
  • tests/fixtures/wallets.py β€” shared dev wallets

Coverage of critical invariants:

  • test_advisor.py::test_cannot_loosen_with_higher_value β€” hostile LLM cannot raise per_trade_risk_pct to 5.0
  • test_reviewer.py::test_heuristic_overrides_llm β€” LLM says allow, heuristic vetoes on win_rate < 20%
  • test_reviewer.py::test_llm_timeout_falls_back_to_heuristic β€” slow LLM doesn't block the sleeve loop
  • test_chat.py::test_recommend_risk_change_does_not_write β€” chat's recommend never writes to policy
  • test_token_module.py::test_sanitize_website_strips_eval β€” generated HTML can't eval / document.write
  • test_skill_registry.py::test_enable_missing_env_blocks β€” can't enable a Skill without its API keys
  • test_mcp.py::test_deploy_token_mainnet_without_confirm_rejected β€” mainnet deploys always require explicit confirmation

16. Security model

Concern Mitigation
Private key on disk AES-256-GCM at ~/.twak/wallet.json, PBKDF2 200k iters, chmod 600. Password supplied via TWAK_PWD env var.
Private key over the wire Never. The dashboard receives only the address. The browser never sees the key. The browser POSTs the password to the dashboard, which decrypts the keystore in-process.
LLM agent team Layer 1 can only TIGHTEN. Layer 2 can only VETO. Layer 3 can only RECOMMEND. All three safety envelopes are enforced in code, never delegated to the LLM.
Mainnet token deploy Requires confirm_mainnet: true in the API. Frontend requires the user to type the token name in a dialog. Pre-flight check: policy signed, wallet set, mode == "mainnet".
x402 spend blow-up fees.x402_max_usdc_per_day (default $10) caps daily CMC spend.
Mainnet gas blow-up gas.max_gwei: 5 plus max_gas_price_gwei in policy.
Perps venue rug Daily venue re-selection ranks 4 candidates; auto-switch on OI drop or withdrawals_paused=True.
BSC RPC outage 3-RPC rotation in BSCClient; sleeves hold positions if all fail.
MCP exposure The MCP server reads core.main.DASHBOARD_STATE; it has no filesystem or network access of its own. Mainnet deploys through MCP require the same confirm_mainnet guard as the dashboard.
Skill side effects cmc_global_filter is the only Skill that writes; its writes are tagged _source: "skill:cmc_global_filter" and visible in the Control Log.
Adversarial personas Persona files are loaded into the system prompt but the BaseAgent machinery is the same regardless. Reset to pro is one click.
Replay safety The replay harness runs the strategies against a synthetic tape; no real txs are signed. The replay mode in BSCClient.broadcast returns deterministic stubs.
Token Module during contest Hard date lock: refuses to deploy before 2026-07-07 00:00 UTC. After the window, requires BNBAGENT_ALLOW_TOKEN_DEPLOY=true in env. The contest forbids launches 2026-06-03–2026-07-06; this is enforced in code (TokenModule.is_deploy_unlocked), not in docs.
Mnemonic export on the public dashboard /api/wallet/export-mnemonic returns 403 unless BNBAGENT_ALLOW_WALLET_EXPORT=true is set in the server env. Defense-in-depth: a judge who learns the admin password still cannot dump the operator's seed phrase unless they also have SSH access + restart capability.
Wallet swap on the public dashboard /api/setup/wallet/import returns 403 unless BNBAGENT_ALLOW_WALLET_IMPORT=true is set. A judge who gets the admin password still cannot replace the operator's wallet with their own (which would let them drain funds or register a fake identity).

Full details: docs/SECURITY.md.

Security review (v2.0.8)

A focused security review was performed in v2.0.8 covering the wallet keystore, BSC RPC layer, gas pricing, CMC data dependency, MCP server surface, and vol-pause logic. The review identified 0 Critical, 4 High, 7 Medium, 6 Low, 4 Info findings. All 4 Highs + 2 of the Mediums were fixed in v2.0.8 (H1–H4, M3, M4). The full review is private to the operator and is not committed to this public repo. A summary of what was fixed (and what is deferred to post-hackathon hardening) is in docs/SECURITY.md under "v2.0.8 security review".

The hardening commits are:

Commit ID What it fixes
1ea07b8 H-4 Gas-price cap from policy; refuse stuck-tx window
4973b9d H-3 resync_nonce to reconcile local cache from chain
04719cb H-2 Add pycryptodome>=3.18 to deps + hoist AES imports
a4924ec H-1 Gate BNBAGENT_PRIVATE_KEY env var behind explicit opt-in
2366d68 M-4 Vol filter fallback above pause threshold
bd9cb93 M-3 MCP SSE default bind 127.0.0.1 + optional Bearer auth

17. Deployment

Local development (no auth)

bash install.sh && bash bnbagent

BNBAGENT_AUTH_MODE defaults to disabled, so no password is required. The dashboard is open. Use this on your laptop.

3-mode auth wrapper (v2.1.5+, readonly added in v2.1.7)

One env var, BNBAGENT_AUTH_MODE, picks the mode. The legacy BNBAGENT_AUTH_ENABLED flag still works as a fallback (true β†’ password, false/unset β†’ disabled); BNBAGENT_AUTH_MODE wins when both are set.

Mode When to use Password? Mutations?
disabled (default) Local dev on your laptop No βœ… all allowed
password Coolify with operator-on-VPS Yes (judge / admin) βœ… with admin cookie
readonly Public contest URL (DoraHacks) No ❌ 403 on all POSTs

For the Coolify contest URL (recommended): set BNBAGENT_AUTH_MODE=readonly. Judges hit the URL with no password prompt, see the live agent (live state, sleeves, holdings, chat, replay), but every mutation route returns 403. The 🟒 DEMO MODE banner in the topbar makes it obvious. Defense in depth: even forging an admin cookie doesn't help in readonly mode (the cookie is bypassed entirely β€” everyone is judge).

For operator maintenance: switch to password mode temporarily (see Phase 4 of coolify_runbook.md), log in as admin, do the thing, switch back to readonly.

# Mode A: local dev (default, no env var)
# BNBAGENT_AUTH_MODE=disabled

# Mode B: contest public URL (recommended for Coolify)
BNBAGENT_AUTH_MODE=readonly

# Mode C: VPS with operator maintenance
BNBAGENT_AUTH_MODE=password
BNBAGENT_AUTH_SECRET=$(openssl rand -hex 32)   # stable across restarts
JUDGE_PASSWORD=see-the-agent-running
ADMIN_PASSWORD=operate-the-agent
BNBAGENT_AUTH_COOKIE_SECURE=true              # required when behind TLS
MINIMAX_API_KEY=sk-cp-...                     # the AI brain

Two roles are enforced by FastAPI dependency injection (in password mode):

  • judge β€” can see Live, Chat, Replay, Tokens (read), and use the chat agent. Cannot edit policy, sign, run registration, change personas, or hit the kill switch.
  • admin β€” full operator access (judge + setup + sign + register + kill switch + wallet export).

The cookie is HMAC-SHA256 signed (stdlib only, no new dep), 1-day expiry, httponly + samesite=strict. The signature uses BNBAGENT_AUTH_SECRET; if you forget to set it the dev fallback is used and you'll see a warning at startup. Sessions are invalidated on every restart without a real secret.

Coolify / docker-compose

cp .env.example .env
$EDITOR .env                                  # fill in the keys
docker compose up -d                          # builds Dockerfile, runs on :8000

The Dockerfile ships a single Python 3.12 image that runs the dashboard backend (FastAPI on :8000) + the MCP SSE server (on :8765 if BNBAGENT_MCP_PORT=8765). Healthcheck is GET /api/healthz every 30s. bnbagent_data and bnbagent_logs named volumes persist runtime state across container rebuilds.

For Coolify: point it at the repo, set the env vars in the service UI, expose port 8000. Coolify's reverse proxy handles TLS termination in front.

Reverse proxy with TLS (if not using Coolify's proxy)

Caddy:

bnbagent.example {
  reverse_proxy 127.0.0.1:8000
}

BNBAGENT_AUTH_COOKIE_SECURE=true is required when running behind TLS so the browser keeps the cookie.

Production checklist (pre-live-replay)

  • Re-signed config/policy.yaml with the production evaluator's key
  • Wallet has real BNB (gas) + real USDC (trading)
  • mode: mainnet in config/config.yaml
  • ERC-8004 identity NFT minted on mainnet
  • At least 1 ERC-8183 job in Completed state on mainnet
  • Backtest report data/reports/replay.html is committed
  • Dashboard reachable at a public URL with TLS + auth
  • BNBAGENT_AUTH_MODE=readonly set (contest URL) or password + non-default JUDGE_PASSWORD / ADMIN_PASSWORD (operator-on-VPS)
  • BNBAGENT_AUTH_SECRET set to a stable value (openssl rand -hex 32) if using password mode
  • BscScan + 8004scan deep links work

Full details: docs/operations.md.


18. Contributing

PRs welcome. See docs/CONTRIBUTING.md for:

  • Dev setup (venv, pre-commit, linting)
  • Code style (ruff, type hints, docstrings)
  • Test conventions (class-based, replay-tape fixtures, FakeLLMClient)
  • PR review process

For the contest: please open issues for any bugs you find in the live PnL-replay window. Speed matters; we'll triage and patch.


19. License

MIT β€” see LICENSE. Copyright (c) 2026 Blaze.

  __  ___
 /  |/  /  by Blaze Β· built for the BNB HACK 2026
/ /|_/ /   CoinMarketCap Γ— Trust Wallet Γ— BNB Chain
/_/  /_/   $36K prize pool Β· live PnL-replay 2026-06-22 β†’ 2026-06-28

About

Autonomous BSC trading agent. You sign once, it runs solo, you can kill it with one button. CoinMarketCap x402 data ($0.01/call), Trust Wallet signed txs (keys never leave the host), BNB Chain ERC-8004 identity + ERC-8183 escrow. 3 sleeves + 3-LLM safety team.

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages