-
Notifications
You must be signed in to change notification settings - Fork 0
Architecture
Murtaza Ali Imtiaz edited this page Jun 5, 2026
·
4 revisions
┌──────────────────────────────────────────────────────────────────────────┐
│ polar-bear-rig-onchain · Polar Bear (🍨) │
│ rig-onchain-kit · SignerContext · Solana devnet │
└──────────────────────────────────────────────────────────────────────────┘
CLI Entry Point (main.rs)
--mode [full|balance|quote|signer] [--no-agent]
│
┌───────────────┴──────────────────────────────────┐
│ │
▼ --mode full ▼ --mode full --no-agent
┌─────────────────────────────────────────────┐ ┌────────────────────────────────────┐
│ rig-core Agent (claude-sonnet-4-6) │ │ Direct subsystem sequence │
│ PEV loop governance │ │ balance → quote → signer │
│ SolanaBalanceTool │ │ (no Anthropic client constructed) │
│ JupiterQuoteTool (dry-run) │ │ No ANTHROPIC_API_KEY required │
│ SignerIsolationTool │ └────────────┬───────────────────────┘
│ Requires ANTHROPIC_API_KEY │ │
└────────────────────┬────────────────────────┘ │
│ │
┌───────────┴─────────────────────────────────────────┘
│
▼
┌─────────────────────┐ ┌──────────────────────────────────────────────┐
│ onchain::signer │ │ onchain::balance onchain::jupiter │
│ tokio::task_local! │ │ │
│ LocalSolanaSigner │ │ SolanaClient JupiterClient │
│ with_signer(f) │ │ (devnet-only) (dry_run=true, always) │
│ snapshot_active() │ │ get_balance() GET /v6/quote │
│ IsolationReport │ │ → BalanceResult → JupiterQuote │
└─────────────────────┘ └──────────────────────────────────────────────┘
src/
├── lib.rs crate root; re-exports agent, config, onchain
├── main.rs binary entry; clap CLI; mode dispatch; --no-agent branch
├── config.rs Config::from_env() - infallible; anthropic_api_key: Option<String>
├── agent/
│ ├── mod.rs build() → impl Prompt; rig-core agent assembly; key validation
│ └── tools.rs SolanaBalanceTool, JupiterQuoteTool, SignerIsolationTool
└── onchain/
├── mod.rs execute_pipeline(), demo_signer(): public entry points
├── signer.rs tokio::task_local! SignerContext; with_signer; IsolationReport
├── balance.rs SolanaClient::devnet(); query_balance; BalanceResult
├── jupiter.rs JupiterClient::dry_run(); get_quote; JupiterQuote
└── types.rs Lamports newtype; conversion helpers
main()
└─ run_full(cfg, amount)
│
├─ SolanaClient::devnet() → Arc<SolanaClient>
├─ JupiterClient::dry_run() → Arc<JupiterClient>
├─ agent::build(cfg, solana, jupiter)
│ └─ cfg.anthropic_api_key.as_deref().context(...)? ← key validation here
│ └─ anthropic::Client::new(api_key)?
│ └─ client.agent("claude-sonnet-4-6").tool(...).build()
│
└─ agent.prompt(task_prompt)
│ (rig-core PEV loop)
│
├─ Tool call: solana_balance(address)
│ └─ SolanaClient::query_balance()
│ └─ solana_client RPC get_balance → BalanceResult
│
├─ Tool call: jupiter_quote(sol_amount, slippage_bps)
│ └─ JupiterClient::get_quote()
│ └─ reqwest GET /v6/quote → JupiterQuote
│
└─ Tool call: signer_isolation_log(task_id)
└─ snapshot_active()
└─ CURRENT_SIGNER.try_with() → Option<SignerSnapshot>
main()
└─ run_full_no_agent(cfg, amount)
│
├─ run_balance(cfg) → SolanaClient::query_balance()
├─ run_quote(cfg) → JupiterClient::get_quote()
└─ demo_signer(cfg) → signer::demo_signer() - 3 concurrent tasks
No agent::build() call - ANTHROPIC_API_KEY is never read.
LocalSolanaSigner::ephemeral(label)
│
with_signer(signer, || async { ... })
│
├─ CURRENT_SIGNER.scope(arc, future) ← task-local slot installed
│ │
│ [agent runs: balance → quote → isolation log]
│ │
└─ scope exits (normal / ? / panic) ← slot evicted automatically
| Layer | Technology |
|---|---|
| AI Agent Framework | rig-core ≥ 0.36 |
| On-chain bridge |
rig-onchain-kit pattern (tokio::task_local! SignerContext) |
| Async runtime | Tokio |
| Blockchain | Solana (devnet only) |
| DEX aggregator | Jupiter V6 /quote (dry-run, no transactions) |
| CLI | clap ≥ 4 |
| Logging | tracing + tracing-subscriber |
| HTTP / TLS | reqwest ≥ 0.13 + rustls |
| Error handling | anyhow + thiserror ≥ 2 |
| Env config | dotenvy |
| Serialisation | serde + serde_json |
| IDE | Zed (tasks.json · debug.json · settings.json) |
| Decision | Rationale |
|---|---|
tokio::task_local! not thread_local!
|
Tokio tasks can migrate between OS threads at await points; task_local! scopes the signer slot to the task, not the thread. |
anthropic_api_key: Option<String> |
Config::from_env() is infallible; key validation is deferred to agent::build(), which is only called for --mode full without --no-agent. |
--no-agent flag |
Enables full-pipeline smoke tests and demos without an API key; CI can verify all subsystems without injecting secrets. |
| Lib + bin targets | Integration tests are external crates that import polar_bear_rig_onchain::*; the lib target makes this possible. |
| Rust 2024 edition | Matches the rig upstream repository and polar-bear-rig-hft. |
Client::new(api_key)? |
Client::new is fallible in rig-core ≥ 0.36; ClientBuilder is the pre-0.36 API. |
Both CompletionClient + ProviderClient in scope |
Both traits must be imported for .agent() to resolve in rig-core ≥ 0.36. |
dotenvy not dotenv
|
dotenv crate is unmaintained; dotenvy is the maintained fork. |
reqwest "^0.13" + rustls feature |
rustls-tls was renamed to rustls in reqwest 0.13; the old name causes a compile error. |
#[ignore] on live tests |
Prevents CI failures when ANTHROPIC_API_KEY is absent. |
strip = "debuginfo" in release |
Reduces binary size; mirrors rig upstream release profile. |
//! not /// at file tops |
/// at file scope with no following item triggers unused_doc_comments lint. |
-
polar-bear-rig-hft: the HFT pipeline this repo extends - Rig Framework: AI agent framework by 0xPlaygrounds
- Jupiter Aggregator: DEX aggregation API
- Solana Program Library
polar-bear-rig-onchain · Polar Bear (🍨) · Technology Lead: Murtaza Ali Imtiaz · PBS License
Getting Started
Design
Reference
Development
External