Qubic Agent Wallet
README.md
# Qubic Agent Wallet
**Let AI agents pay in QU, under rules a human sets and the agent cannot change.**
Qubic Agent Wallet is an open-source [MCP](https://modelcontextprotocol.io) server. It gives assistants such as Claude, Cursor or Copilot a wallet on the [Qubic](https://qubic.org) network. They can pay [x402](https://useqpay.com/docs/x402) endpoints and send QU, but only within spending caps, allowlists and human approvals that you control.
- **Non-custodial.** The seed stays in your OS keychain, on your machine. No server, ours included, ever holds a key or signs anything.
- **Guardrails enforced in code, outside the AI.** Caps, allowlists and the pause are checked before anything is signed. No agent tool can approve a payment, change the policy or lift the pause.
- **Human approval** from the terminal (with a passphrase) or from Telegram (Approve / Deny / Pause buttons).
- **Never pays twice, never loses track.** Every transaction is journaled before it is sent and settled from the chain afterwards.
> **Status: alpha.** It works end to end, and real mainnet payments went through on 2026-10-30 (paid by the agent on its own, then after a Telegram approval), but no independent audit has been done. Fund the wallet only with what you are ready to lose, and keep the default low limits.
Built by PrimeQubic on top of [Q+Pay](https://useqpay.com)'s `x402-qubic`.
---
## How it works
```
AI assistant ──MCP──▶ qubic-agent-wallet (on your machine)
├─ Policy: caps, allowlists, pause (signed, the agent can't edit it)
├─ Approval queue ──▶ Telegram / terminal (you)
├─ Guarded signer: signs once, only what was authorized
├─ x402 client (official @x402/core + x402-qubic)
└─ Local journal (SQLite) + reconciliation from the chain
```
1. The agent calls `pay_x402` (or `send_qu`).
2. The wallet reads the price from the `402 Payment Required` answer and checks your policy. The payment is then authorized, sent to you for approval, or refused.
3. If authorized, it signs **one** Qubic transaction for the exact amount, to the QPAY contract (or the approved recipient). It journals the transaction id, sends the transaction, waits for its tick and returns the resource to the agent.
4. If anything is uncertain (a network timeout, a crash), the wallet does not guess. It reads the outcome from the chain once the transaction's target tick has passed. A Qubic transaction can only execute at that tick.
## Requirements
- Node.js **22.16+**
- macOS, Windows, or Linux with a Secret Service keychain (GNOME Keyring, KWallet). Headless Linux, such as a Raspberry Pi without a desktop, is not supported yet: see [Known limitations](#known-limitations).
## Install
```bash
git clone https://github.com/PrimeQubic-Labs/qubic-agent-wallet.git
cd qubic-agent-wallet
npm install
npm run build
```
## Quick start
Run these commands **yourself, in a real terminal**. Approval and policy commands refuse to run without one, so an agent cannot run them for you.
```bash
# Sandbox (fake QU) is the default. For real QU: export QAW_NETWORK=mainnet
node dist/cli/main.js passphrase set # 12+ characters, never typed anywhere else
node dist/cli/main.js policy init # low default limits
node dist/cli/main.js policy allow-host useqpay.com # allowlist an x402 seller
node dist/cli/main.js wallet create # shows the seed ONCE: write it on paper
```
Then send a small amount of QU to the address `wallet create` printed.
### Connect it to your assistant
**Claude Desktop**: add this to `claude_desktop_config.json`:
```json
{
"mcpServers": {
"qubic-agent-wallet": {
"command": "node",
"args": ["/absolute/path/to/qubic-agent-wallet/dist/mcp/main.js"],
"env": { "QAW_NETWORK": "mainnet" }
}
}
}
```
**Claude Code**:
```bash
claude mcp add qubic-agent-wallet -e QAW_NETWORK=mainnet -- node /absolute/path/to/qubic-agent-wallet/dist/mcp/main.js
```
Any MCP client that can start a stdio server works the same way.
### Approve from your phone (optional)
1. In Telegram, open **@BotFather**, send `/newbot`, and copy the token it gives you.
2. Run `node dist/cli/main.js telegram setup`, then paste the token and send the bot the 8-digit code that is shown.
Approval requests then arrive on Telegram while the MCP server runs, or while you run `telegram listen`. Only your Telegram account is obeyed. Resuming after a pause is terminal-only.
## Tools the agent gets
| Tool | What it does |
|---|---|
| `wallet_status` | Network, pause state, what the policy still allows today, pending approvals |
| `get_policy` | Read-only view of your limits |
| `pay_x402` | Fetch a resource and pay its x402 price in QU if your policy allows it. After an approval, call it again with `payment_id`: a fresh price is requested, and nothing is paid if the price or the seller changed. Approval requests show the seller. Uses a prepaid channel on its own when one with credit is open; pays a channel deposit only if the agent passes `channel_max_deposit` |
| `send_qu` | Send QU to a Qubic identity, under the same policy |
| `get_payment`, `list_payments` | Status and history |
There is no tool to approve, deny, change the policy, resume or export a key, and the tests check that none exists.
## Commands (for you, not the agent)
```
passphrase set | change Approval passphrase
pending Payments waiting for approval
approve <id> | deny <id> [why] Decide (approve needs the passphrase)
history [limit] Recent payments
channels Prepaid channels: deposits, vouchers, credit left
unblock <host|seller> Allow payments again to a seller that took QU without delivering (passphrase)
journal check Check that the journal was not changed outside the wallet
journal seal Accept the journal as it is now, after checking it (passphrase)
policy init | show Create / show the policy
policy set <field> <value> Change a limit (passphrase)
policy allow-recipient <id> Allowlist a recipient (passphrase)
policy allow-host <host> Allowlist an x402 host (passphrase)
policy remove-recipient | remove-host
pause Block every payment now (anyone, even the agent, may pause)
resume Lift the pause (passphrase)
wallet create | import | address Wallet key (seed in the keychain only)
telegram setup | status | off | listen
reconcile Settle payments left in doubt, from the chain
```
Default policy, in QU: 100,000 per payment, 1,000,000 per day, 500,000 per day per recipient or host, human approval above 20,000. Unknown recipients and hosts need approval. The first x402 payment or channel deposit to a seller always needs approval, even on an allowlisted host; once that seller has delivered, later payments follow the policy. Q+Pay charges 0.75% per x402 payment, with a 100 QU minimum.
## Security model
| Agent | Protection |
|---|---|
| Only has the MCP tools (Claude Desktop, chat) | Full. It can only *ask*: the code applies the rules |
| Has a shell and was tricked by a prompt injection | Good. Approving needs a real terminal and your passphrase, and a policy edited by hand is detected and blocks everything |
| Has a shell **and actively tries to get around the wallet** under your OS account | **Limited.** It can read what the wallet reads, keychain included. Run the wallet under a separate OS user or on another device ([Known limitations](#known-limitations)) |
Other guarantees:
- **One signature per payment**, even across processes: a payment is claimed in the database before signing.
- **Budget accounting.** The budget is released only when the chain proves nothing moved. In doubt, it stays reserved and the agent is told not to pay again.
- **New sellers.** The first payment to a seller always needs your approval, even on an allowlisted host such as a marketplace. A seller that took QU without delivering gets nothing more until you `unblock` it.
- **Tamper-evident journal.** The journal's digest is kept in the keychain. If anything edits the journal file behind the wallet's back (to free budget or lift a block), every payment stops until you check it and run `journal seal`.
- **No requests to your own network.** `pay_x402` refuses local and private addresses, including names that resolve to one, checked at connection time.
- **Third-party content.** What a paid resource returns is handed to the agent as data, and the tool description tells it never to follow instructions found there.
## Known limitations
- **Headless devices** (Raspberry Pi, servers): no OS keychain. An encrypted-file key store is planned.
- **Remote mode**: the agent and the wallet must run on the same machine today. A network transport with authentication, so the wallet can live on a separate, always-on device, is planned. It is also the strongest isolation.
- **Prepaid channels have no refund in the protocol.** A deposit belongs to the seller once paid; unused credit comes back only if the seller refunds it. Keep `maxChannelDeposit` modest. Credit is counted only from deposits the seller accepted.
- **No independent audit.** The author's own [internal security review](docs/security-audit.md) lists what was checked and fixed; no third party has reviewed the code.
## Taxes
In many countries, including France, **paying for a service with crypto is a taxable disposal**, so each payment your agent makes may count. This wallet does not compute taxes. [QubicFlow](https://github.com/AndyQus/qubic-flow), by AndyQus, tracks any Qubic address and exports to CoinTracking, Koinly and Blockpit.
## Upgrading
```bash
git pull && npm install && npm run build
```
If you installed before the journal was sealed (2026-11-03), run `node dist/cli/main.js journal seal` once. Until then, every payment is refused. A new install seals itself.
## Development
```bash
npm test # Vitest
npm run typecheck
```
The tests run the real `@x402/core` client and the real `x402-qubic` scheme against fake sellers and a fake chain. A sandbox is available at `sandbox.useqpay.com` (`QAW_NETWORK=sandbox`, the default).
## Licenses
- This project: [MIT](LICENSE).
- It depends on [`@qubic-lib/qubic-ts-library`](https://github.com/qubic/ts-library) for signing. That library uses the **Qubic Anti-Military License**: MIT-like, but it forbids any military use. You must respect that restriction.
- Other dependencies (`x402-qubic`, `@x402/core`, `@modelcontextprotocol/sdk`, `@napi-rs/keyring`, `undici`, `zod`) are MIT or Apache-2.0.
## Disclaimer
This software moves real money and comes with **no warranty** (see [LICENSE](LICENSE)). It is a personal, non-custodial tool, not a financial service. You are responsible for your keys, your limits and what your agent buys.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessSyncing