self-custody · MCP · three trust levels

Give your agent
a wallet of its own.

Self-custody Ethereum wallet for AI agents. One local Docker image, keys never leave your machine — and you choose how much control the agent gets.

rustoktrust_ladder

One wallet. Three trust levels.

Same self-custody core, same MCP tools — the difference is who holds the key and who presses approve. Start hot, upgrade as the stakes grow.

full autonomy

rung 1 · Agent edition

key: lives with the agent

The agent signs and sends on its own. For agents you talk to remotely — Telegram and the like — where pressing a button isn't an option.

⚠ Hot by design: no spending limits, no approval step. Fund it like a hot wallet.
Install →
human-approved

rung 2 · Console edition

key: local container — approval: yours

Every transaction that moves funds waits for your y/N in a separate console on your machine — PIN for high-risk approvals.

Install →
keys on your phone

rung 3 · Mobile

key: your phone — agent: keyless

The agent proposes, your phone re-derives and signs. Approve from anywhere. The endgame: an agent that never touches a key.

In development — follows the same core.
Read the thesis →

Moving up a rung means a new wallet: spin up the next edition, then move your funds on-chain. Recovery phrases import into any standard wallet — nothing is locked in.

rustokinstall

Pick a rung, set up in minutes.

i To install — a container engine, nothing else. Engine specifics per edition below. To transact — an Ethereum RPC URL (an Alchemy key URL is best; a public RPC works for testing); you add it later, when you connect the wallet to an agent — not before installing.
Agent edition rung 1 · full autonomy
Docker or Podman running.
01
Create your wallet
Prints an address + 12 words — visible only in your terminal. The keyring password goes in as a secret, never inline.
read -r -s -p "Keyring password: " pw && printf '%s' "$pw" | podman secret create rustok-keyring - && unset pw
podman run -it --rm -v rustok-wallet:/data \
  --secret rustok-keyring,type=env,target=RUSTOK_KEYRING_PASSWORD \
  ghcr.io/rustok-org/rustok-wallet:latest create-wallet
On docker (no secret store): keep the password in a 0600 file and pass its path — -v ~/.rustok-keyring-pass:/run/keyring-pass:ro -e RUSTOK_KEYRING_PASSWORD_FILE=/run/keyring-pass. Recovery = the 12 words (importable into any standard wallet, e.g. MetaMask) or the Docker volume + password.
02
Add the MCP server config
Drop this into your MCP client — the password never enters this file.
{
"mcpServers": {
"rustok-wallet": {
"command": "podman",
"args": ["run","-i","--rm","--init",
"-v","rustok-wallet:/data",
"--secret","rustok-keyring,type=env,target=RUSTOK_KEYRING_PASSWORD",
"-e","RUSTOK_ALLOWED_CHAINS=1,8453",
"-e","RUSTOK_RPC_URLS_1",
"ghcr.io/rustok-org/rustok-wallet:latest"],
"env": {
"RUSTOK_RPC_URLS_1": "https://your-rpc"
}
    }
  }
}
On docker, swap the --secret arg for -v /home/you/.rustok-keyring-pass:/run/keyring-pass:ro -e RUSTOK_KEYRING_PASSWORD_FILE=/run/keyring-pass (your real absolute path). Read-only agent? Set RUSTOK_MCP_CAPABILITIES=read_wallet.
Console edition rung 2 · human-approved
podman (recommended) or Docker · openclaw for the one-liner below, or install without it from the skill page · cosign optional, for provenance · Linux amd64 today (Windows via WSL2), macOS on the roadmap.
01
Install the rustok command
One command, and it always fetches the current release — the version lives on the skill page, not on this one. The image is pulled by digest — you get exactly those bytes or nothing — and if cosign is on your machine the installer also verifies who built it. It never touches a secret or your keys.
# pulled by digest; signature checked too when cosign is available
openclaw skills install @rustok/wallet
No OpenClaw, or prefer to read the installer first? The skill page carries the full command for the current release, and the script to read before you run it. The console image is published by version only — there is no latest tag to pull, on purpose: the installer pins the exact digest of the release it ships with.
02
Create your wallet
Run it in a terminal the agent cannot see — it refuses to run without one. You choose a 6-digit approval PIN; it prints the 12-word recovery phrase, exactly once. No password to remember: the keystore's own is generated and kept in the engine's secret store.
rustok init
Back up the 12 words offline — they are the one backup — then fund the address. Forgot the PIN? rustok set-pin. Lost the machine? rustok restoreTROUBLESHOOTING.
03
Connect your agent
Registers the wallet as an MCP server: launched by label, and the keyring password stays out of configs and argv — no hand-written JSON.
rustok connect claude # or: cursor / hermes
rustok doctor tells you what's missing. Rather not pipe a script into a shell? The full by-hand setup lives in INSTALL.md.
Then: approvals happen in a second terminal
When a transaction is pending, open a window the agent can't drive — y/N per transaction, PIN for high-risk approvals.
rustok console
rustoktools --list

Every tool, both editions. Nothing hidden.

Capability gating is fail-closed — scope a session to read only, prepare only, or execute. And on the console edition, execute waits for a human.

tool
capability
agent
console
what it does
get_wallet_context
read_wallet
active address, per-chain balances, allowed chains
get_balances
read_wallet
token balances for the active wallet
get_positions
read_wallet
DeFi positions — Aave v3 + ERC-4626 vaults
preview_send
preview_tx
preview an ETH send → preview_id, gas, risk level
preview_transaction
preview_tx
preview a transaction → decoded call, simulation, gas, risk level
execute_send
execute_tx
broadcast a previewed send → tx_hash
execute_transaction
execute_tx
queue a previewed transaction — waits for your console approval
get_execution_status
execute_tx
poll a queued transaction — executed / denied / expired
sign_message
execute_tx
sign a message (EIP-191) — a signature can authorise approvals that drain the wallet, and needs no console approval. The console edition refuses signing outright, in every mode.
rustoksafety

The agent proposes. You decide.

On the console and mobile rungs, nothing moves without you. On the agent rung, you trade that for full autonomy — knowingly.

Self-custody
Keys live only in the local core and never leave it. Encrypted at rest with Argon2id + AES-256-GCM.
Capability gating
read / preview / execute — fail-closed, nothing more than you grant.
txguard
Every transaction is parsed and risk-flagged before you sign — scam-address and risky-approval checks.
Your approval channel
Nobody on rung 1, your console on rung 2, your phone on rung 3. The rung is the choice.
Self-custody means your risk: the agent edition has no spending limits and no approval step — txguard flags risky transactions, it does not block them. That's what the ladder is for.
txguard.log
rustokchains

Mainnet, first-class L2s, and your own RPC.

Ethereum mainnet, plus first-class L2s — Arbitrum One, Base, and Optimism. Sepolia testnet for development. Any other EVM chain works with your own RPC URL.

RUSTOK_ALLOWED_CHAINS  ·  default ships 1,8453
Ethereum1 Arbitrum42161 Base8453 Optimism10 Sepolia11155111
// why rustok
Rustok gives an AI agent a wallet of its own — self-custody, no middleman — so agents can take part in the economy directly: paying for the compute, data, and tools they rely on.

The endgame is an agent with no keys at all — proposing transactions your phone signs.

Give your agent a wallet.

support  0xA713e7145F0060A35E92a928e997B42481c0FfEE