The daemon that proves your device is real. It signs every payment with a hardware-backed key so no one can impersonate your agent.
up2d is a lightweight background service that runs on your machine. When your AI agent makes a payment through UP², the daemon signs the request with a private key that never leaves your device.
The UP² server verifies that signature before processing any payment. No valid signature, no payment. It's that simple.
Sends payment request to localhost:8003/pay
Signs the request with your device's private key
Verifies signature against your registered public key
Only after cryptographic proof passes
Why does this matter? Without the daemon, someone who steals your API key could make payments from any machine. With it, payments only work from devices you've registered.
The daemon runs on Node. Check with node --version
Sign up at dashboard.up2.cash and complete onboarding
Create a wallet in your dashboard under the Agent tab to get an API key
Platform support: Linux (TPM 2.0), Windows (DPAPI), macOS (Keychain). The daemon automatically uses the strongest key protection available on your system.
Run the interactive setup. It will ask for your UP² email and password.
npx up2-daemon
Press c in the menu and give your agent a name. This generates a
keypair and registers your device with UP².
Your Identities (0): Commands: c - Create new identity d - Delete an identity s - Start daemon (background) q - Quit > c Agent name: my-trading-bot Trust engine: TPM 2.0 Extracting platform endorsement key... Creating signing keys... Identity Created ────────────────────────────── ID: ident_a3f8b2c901e7d4k2 Name: my-trading-bot Fingerprint: hw_9c3a7f2b1e8d5a40
Press s to start in the background. It will survive terminal close.
Your agent can now reach it at localhost:8003.
# Or start directly from the command line: npx up2-daemon start Daemon started in background (PID 48291) Logs: ~/.up2d/daemon.log Stop: npx up2-daemon stop
Your agent sends a POST to the daemon's local endpoint. The daemon signs the request and routes it through UP².
# Your agent code — any language, just POST to localhost import requests result = requests.post("http://localhost:8003/pay", json={ "invoice_id": "inv_abc123", "api_key": "ak_live_your_key_here", }).json() print(result) # {"status": "success", "receipt": "inv_abc123", "paid_via": "card"}
const res = await fetch("http://localhost:8003/pay", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ invoice_id: "inv_abc123", api_key: "ak_live_your_key_here", }), }); const data = await res.json(); // { status: "success", receipt: "inv_abc123", paid_via: "card" }
curl -X POST http://localhost:8003/pay \ -H "Content-Type: application/json" \ -d '{ "invoice_id": "inv_abc123", "api_key": "ak_live_your_key_here" }'
Multiple agents? If you have two agents on the same machine, create a
separate identity for each. Pass "identity_id": "ident_xxx" in the request
body to specify which identity signs the payment.
| Command | Description |
|---|---|
| npx up2-daemon | Interactive menu — login, create identities, start daemon |
| npx up2-daemon start | Start daemon in the background (detached) |
| npx up2-daemon start --fg | Start in foreground (attached to terminal) |
| npx up2-daemon stop | Stop the background daemon |
| npx up2-daemon status | Check if daemon is running and show connected identities |
| npx up2-daemon logs | Tail the last 50 lines of the daemon log |
| Endpoint | Description |
|---|---|
| POST /pay | Submit a payment — requires invoice_id and api_key |
| GET /health | Daemon status, PID, and connected identities |
| GET /identities | List all registered identities and connection state |
Private key is created inside the TPM chip and cannot be extracted. Signing happens in hardware. This is the strongest protection available.
Private key is encrypted with your Windows user credentials via the Data Protection API. Only your user account can decrypt it.
Private key is stored in the system Keychain, protected by your login credentials and the Secure Enclave on Apple Silicon.
Never share your ~/.up2d directory. It contains your private
keys and auth tokens. If you suspect a compromise, delete the identity from
the interactive menu and create a new one.
Anti-clone protection: Each identity is bound to your machine's hardware fingerprint. Copying the key files to another machine will fail — the server checks hardware signatures on every connection.
The daemon isn't running or lost its WebSocket connection.
Run npx up2-daemon status to check, then npx up2-daemon start to restart.
Your wallet has Identity mode enabled in the dashboard. Make sure the daemon is running and the identity ID is added to your wallet's allowed list.
You moved the identity files to a different machine. Delete the identity and create a new one on the current machine.
Another instance is running, or another app is using the port.
Run npx up2-daemon stop first, or set a custom port:
UP2D_PORT=8004 npx up2-daemon start