Recipe: Grok Bot#
Connect Grok Bot (xAI) to the Torii Wallet door and walk the mandate path. English only. Testnet (Base Sepolia, chain 84532).
Verified on 2026-10-12 against API ab5ce5943 (fixture server through a temporary tunnel). Grok Bot connected to the fixture API from scripts/tw_recipe_claude_probe.py --serve (in-memory store, TW_DOOR_ENABLED=1, permissive fixture receipt) through a temporary Cloudflare quick tunnel, and walked the mandate path end to end. Not verified: see the list at the end.
What the bot needs#
- The API host, for example
https://<api-host>. The door must be open there:GET /torii/dooranswers402. A404means the host has not opened it. - An agent key.
POST /auth/agent/connectwith{"agent_name":"my-bot"}returns anapi_key. It goes in the headerX-NW-User-Key. Do not paste a real key into a shared chat or a repository. - Your agent id:
GET /torii/agents/mewith that key. The owner needs it for the owner step below. - No exchange key and no wallet key. The vault enforces the mandate; you can never withdraw.
Add the server#
In the walk, setup was done in Grok Bot's chat, not a settings screen. The owner typed "I want to add an MCP" and pasted two lines:
URL: https://<api-host>/mcp?profile=full
Header: X-NW-User-Key: <your agent key>
Grok Bot replied that the server was connected with 73 tools (59 NightWatch and 14 wallet tools). The header was accepted as sent. If a client cannot send a custom header, it cannot use this door yet; say so rather than working around it.
Prompt used in the walk#
Read
<BASE>/torii/skill.md. You are agent 21. List your mandate offers, accept the first one, report one buy event of 5 USDC with a fake tx hash, read the mandate back, then report a refusal with reason OverPerTxCap. Print each tool result.
The first tool calls#
mandate_offerswith no arguments. Lists the mandates your owner designated to you once they have signed.mandate_acceptwithmandate_id. Changes nothing else and is idempotent.mandate_report_eventfor what you did on chain,mandate_getto read the record back,mandate_report_refusalfor a call the vault reverted.
mandate_propose (a draft for your owner, no money moves) is the other way in. Details: Offers and accept, Reporting events. Same calls as in Claude.
What the owner does#
The owner opens /tw/start?agent=<your agent id> on their side, sets the limits, reviews the terms and signs. The owner's session and signature are theirs; the bot's key cannot do this step. The owner must have opted the agent in first (accepts_mandates: true, see Offers and accept). The owner can stop the mandate at any time; the bot's next write is then refused with wrong_status.
A note for owners: a bot may explore tools on its own. Before it touched any mandate tool, Grok Bot called get_price twice (SMSN, then BTC) without being asked. Read-only tools are harmless, but expect a bot to try what it can see.
When a call is refused#
Branch on reason. The catalogue is Refusals; the vault's own reverts are listed in Connect.
Verified sequence#
Server log of the walk (fixture values, tunnel host redacted):
get_price (x2) -> SMSN, BTC (the bot looked at prices first, unprompted)
mandate_offers -> 1 offer, m_efsxvln4zd
mandate_accept -> accepted, agent 21
mandate_report_event -> buy, 5 USDC, tx 0x1111... (fake hash)
mandate_report_refusal -> reason=OverPerTxCap, tx 0x2222...
mandate_get -> the record read back
WALK COMPLETE for agent 21
The bot reported the refusal before reading the mandate back; the prompt asked for the reverse. Both orders are fine.
Not verified#
- A real deployed host. The walk ran against a fixture server through a temporary tunnel.
- Real chain receipts. The fixture receipt was permissive; no chain was read and there was no real database.
- The Grok Bot settings screen. Only the chat path was used.
- Grok Bot's permission prompts for consequential actions. None were observed in this walk.