Install
openclaw skills install rustok-walletSelf-custody Ethereum Agent Wallet. All supported chains enabled by default (Ethereum, Arbitrum, Base, Optimism, zkSync, Sepolia, Arbitrum Sepolia). User assumes all risks. Runs locally. Preview/execute ETH sends with hard policy limits, track DeFi positions. All actions are append-only audit logged.
openclaw skills install rustok-walletLicense note: This OpenClaw skill package (
skills/rustok-wallet/) is published under MIT-0 per ClawHub platform requirements. The Rustok project itself (crates/,app/,mobile/) remains under AGPL-3.0-or-later.
You are connected to an isolated Ethereum Agent Wallet via the local rustok-agent-mcp service (http://127.0.0.1:3000).
This wallet is separate from the user's main wallet. All spending limits, address blocklists, and daily budgets are enforced in code — you cannot negotiate them away. The wallet runs entirely on the user's machine; no private keys ever leave localhost.
⚠️ Beta. By default the wallet is configured for all supported chains including Ethereum mainnet (chain_id 1), Arbitrum One, Base, Optimism, zkSync Era, Sepolia, and Arbitrum Sepolia. The user assumes all risks. If you do not want mainnet access, restrict
allowed_chain_idsvia--policy-config.
One-line install (Linux, macOS, Windows with Git Bash):
curl -fsSL https://raw.githubusercontent.com/rustok-org/mcp/main/scripts/install.sh | bash
Or download manually from GitHub Releases.
For server deployment or headless operation:
docker run -p 127.0.0.1:3000:3000 \
-v ~/.rustok/agent:/data \
-e RUSTOK_AGENT_PASSWORD="your-password" \
ghcr.io/rustok-org/rustok-mcp:latest
Requires Rust toolchain:
git clone https://github.com/rustok-org/mcp.git
cd rustok
cargo build --release --bin rustok-agent-mcp
For native MCP integration via stdio (no HTTP server needed):
1. Install the binary (see Option A above).
2. Configure Claude Desktop:
Add to your Claude Desktop config:
~/Library/Application Support/Claude/claude_desktop_config.json~/.config/Claude/claude_desktop_config.json%APPDATA%\Claude\claude_desktop_config.json{
"mcpServers": {
"rustok-wallet": {
"command": "rustok-agent-mcp",
"args": ["--transport", "stdio"],
"env": {
"RUSTOK_AGENT_PASSWORD": "your-strong-password"
}
}
}
}
3. Restart Claude Desktop. The wallet tools will appear automatically.
Note: In stdio mode the wallet auto-creates on first run if missing, uses unlimited policy defaults, and disables rate limiting. You control your own funds.
curl -fsS -X POST http://127.0.0.1:3000/context | jq
curl -fsS -X POST http://127.0.0.1:3000/preview \
-H "Content-Type: application/json" \
-d '{"to":"0x0000000000000000000000000000000000000001","amount_wei":"100000000000000000","chain_id":421614}' | jq
curl -fsS -X POST http://127.0.0.1:3000/execute \
-H "Content-Type: application/json" \
-d '{"to":"0x0000000000000000000000000000000000000001","amount_wei":"100000000000000000","chain_id":421614,"preview_id":"PASTE_PREVIEW_ID_HERE"}' | jq
Returns: address, cross-chain balances, policy limits, gas estimates.
curl -fsS -X POST http://127.0.0.1:3000/context | jq
Get Aave v3 + ERC-4626 positions for an address. Omit address to use the agent wallet's own address.
curl -fsS -X POST http://127.0.0.1:3000/positions \
-H "Content-Type: application/json" \
-d '{"address":"0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B"}' | jq
Runs policy + budget checks and txguard risk analysis. Returns a preview_id that must be passed to /execute.
Body: PreviewRequest
{
"to": "0x0000000000000000000000000000000000000001",
"amount_wei": "100000000000000000",
"chain_id": 421614
}
curl -fsS -X POST http://127.0.0.1:3000/preview \
-H "Content-Type: application/json" \
-d '{"to":"0x0000000000000000000000000000000000000001","amount_wei":"100000000000000000","chain_id":421614}' | jq
Response: PreviewResponse
{
"preview_id": "550e8400-e29b-41d4-a716-446655440000",
"verdict": {
"action": "allow",
"risk_score": 15,
"findings": [],
"description": "Send 0.1 ETH to 0x0000...0001",
"simulation": {
"eth_change": -100000000000000000,
"token_changes": [],
"approval_changes": [],
"gas_used": 21000,
"reverted": false
}
},
"route": {
"chain_id": 421614,
"chain_name": "Ethereum",
"estimated_gas": 21000,
"max_fee_per_gas": "25000000000",
"max_priority_fee_per_gas": "1500000000",
"estimated_cost": "525000000000000",
"available_balance": "1000000000000000000"
},
"explanation": "Send 0.1 ETH on Ethereum. Estimated cost: 0.000525 ETH (21k gas @ 25 gwei)."
}
Requires a valid preview_id from the preceding /preview call. Re-runs policy and budget checks as defense-in-depth.
Body: ExecuteRequest
{
"to": "0x0000000000000000000000000000000000000001",
"amount_wei": "100000000000000000",
"chain_id": 421614,
"preview_id": "550e8400-e29b-41d4-a716-446655440000"
}
curl -fsS -X POST http://127.0.0.1:3000/execute \
-H "Content-Type: application/json" \
-d '{"to":"0x0000000000000000000000000000000000000001","amount_wei":"100000000000000000","chain_id":421614,"preview_id":"PASTE_PREVIEW_ID_HERE"}' | jq
Response on success: SendResult
{
"tx_hash": "0xabc123...",
"chain_id": 421614,
"chain_name": "Ethereum",
"from": "0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B",
"to": "0x0000000000000000000000000000000000000001",
"amount_wei": "100000000000000000",
"estimated_gas_cost": "525000000000000"
}
Response on policy block (HTTP 403):
policy blocked: exceeds max_single_tx_eth
Response on budget exceeded (HTTP 403):
daily budget exceeded: 0.450000 / 0.500000 ETH
Response on preview expired (HTTP 400):
preview expired
Response on preview mismatch (HTTP 400):
preview mismatch
| Guarantee | Mechanism |
|---|---|
| Spending limits | AgentPolicy — code-level checks before every tx |
| Daily budget | Rolling 24h accumulator in SQLite |
| Address blocklist | Exact match |
| Unlimited approvals blocked | block_unlimited_approvals = true rejects type(uint256).max |
| Audit immutability | Append-only agent_audit_log table |
| Wallet isolation | Separate ~/.rustok/agent/ directory |
| No prompt injection bypass | Limits are not in system prompt; they are in code |
| Local-only keys | Private keys never leave the user's machine |
/execute without a fresh /preview./context first. Before any operation, check wallet state so you do not hallucinate balances or chain availability.rustok-agent-mcp is unreachable, inform the user that the wallet service is offline.MCP_API_KEY env var.--transport http) and stdio (--transport stdio) for Claude Desktop / Cursor.--policy-config to restrict.0x495e…13653By default the wallet is active on all supported chains:
1)42161)8453)10)324)11155111)421614)To restrict chains, provide a custom policy file (--policy-config policy.json) with only the desired allowed_chain_ids.
For testing on Arbitrum Sepolia (chain_id: 421614) you need test ETH to pay gas.
Faucets (free test ETH):
Most faucets require a small mainnet ETH balance (~0.001–0.5 ETH) as anti-bot protection. This balance is not spent.
If this skill helps you, consider sending ETH to support development:
Ethereum: 0xb9d2497e5356d75d0ddd6d806cfe13cafe65f6eb
Every transaction helps improve agent wallet security. ☕