Keystone Hardware Wallet
NozyWallet supports Keystone as an air-gapped hardware signer for Zcash mainnet Orchard sends. Keystone holds spend authority; NozyWallet builds proved transactions (PCZT), shows QR codes for signing, and broadcasts the signed result.
Network: Keystone integration is mainnet only. Testnet wallets cannot enable Keystone pairing or PCZT sends.
Where to find it in NozyWallet
| Surface | Location |
|---|---|
| Desktop | Settings → Keystone — pair UFVK, enable signing |
| Desktop sends | Send tab — when Keystone is enabled, uses prepare → sign → broadcast |
| Mobile (companion API) | Keystone screen from dashboard — same PCZT flow via nozywallet-api |
| API | GET/POST /api/keystone/* on localhost companion — see API endpoints below |
What Keystone does (and does not do)
| Keystone role | Details |
|---|---|
| Signs spends | Adds Orchard spend authorization to a proved PCZT |
| Can hold seed | Typical setup: mnemonic generated or imported on Keystone |
| View-only pairing | UFVK import lets Nozy sync balance and build unsigned PCZTs |
| Not supported | Details |
|---|---|
Transparent (t1) sends | Orchard shielded only — recipients must be u1… unified addresses |
| Testnet | Mainnet config and mainnet Keystone device required |
| In-wallet QR scan (desktop) | Paste signed PCZT / UR frames, or scan on Keystone device |
| On-chain multisig | This is PCZT co-signing, not Bitcoin-style m-of-n |
Prerequisites
- Zcash mainnet wallet in NozyWallet (
network: mainnetin config — default). - Zebrad + sync — wallet synced to tip before sending (Zebra Node Setup).
- Keystone device set to Zcash mainnet with firmware that supports Zcash PCZT (
zcash-pcztUR type). - Matching keys — Keystone must control the same Orchard account as NozyWallet (see setup paths below).
Setup (pairing)
Path A — Seed on Keystone (recommended)
- Create or restore your Zcash wallet on Keystone (mainnet).
- On Keystone, export the UFVK (unified full viewing key).
- In NozyWallet, import or restore the same mnemonic so sync and PCZT building work locally.
Alternatively, store only the UFVK in Nozy config for watch-only sync if your workflow uses Keystone as the sole signer — spending still requires the seed on Keystone. - Settings → Keystone → Export UFVK (or confirm stored UFVK matches Keystone). Mainnet UFVKs start with
uview1. - Import that UFVK on Keystone if not already paired; confirm the same unified receive address (
u1…) on both devices. - Enable Keystone.
Path B — Seed in NozyWallet first
- Create or restore wallet in NozyWallet (mainnet).
- Settings → Keystone → Export UFVK → import on Keystone.
- Import the same mnemonic into Keystone so it can sign PCZTs.
- Confirm matching
u1…receive address. - Enable Keystone.
UFVK is read-only. It can reveal shielded activity to whoever holds it. It cannot spend funds. See Private Key Management.
Sending with Keystone (desktop)
- Ensure Settings → Keystone shows Enabled and mainnet.
- Open Send — you should see Keystone signing enabled (mainnet).
- Enter recipient (
u1…), amount, optional memo → Review & prepare. - Prepare for Keystone — proving may take several minutes on first send.
- Scan the PCZT QR on Keystone (multiple UR frames if shown — scan all).
- Sign on Keystone.
- Paste signed PCZT hex or UR frames back into NozyWallet.
- Broadcast signed tx — transaction is submitted via your Zebrad node.
Success shows a txid and a link to mainnet.zcashexplorer.app.
Sending with Keystone (mobile + API)
When using the mobile app with nozywallet-api:
- Open Keystone from the dashboard.
- Enable Keystone and export UFVK for pairing (same as desktop).
- Prepare for Keystone → scan UR on device → paste signed data → Broadcast signed tx.
API calls mirror the desktop Tauri commands — useful for automation or custom frontends.
Receiving ZEC
- Into NozyWallet: Share your Nozy Receive address (
u1…). Anyone (including Keystone) can send shielded ZEC to it. - From Keystone to NozyWallet: Use Keystone’s send UI with your Nozy receive address, or use the PCZT flow above with Nozy as the builder/broadcaster.
If Keystone and Nozy share the same wallet, synced balance appears in Nozy after compact sync — no separate “receive from Keystone” step.
API endpoints
Local companion only (nozywallet-api, default http://127.0.0.1:3000):
| Method | Path | Purpose |
|---|---|---|
GET | /api/keystone/status | Enabled, UFVK paired, pending send, network |
POST | /api/keystone/enable | Enable/disable Keystone |
POST | /api/keystone/export-ufvk | Export and store Orchard UFVK |
POST | /api/keystone/prepare-send | Build proved PCZT + UR frames |
POST | /api/keystone/complete-send | Decode signed PCZT, broadcast |
See API Server Setup for running the companion.
Troubleshooting
| Problem | What to check |
|---|---|
| “Keystone requires mainnet” | Set network to mainnet in wallet config; disable testnet. |
| Invalid recipient | Use mainnet Orchard unified address (u1…), not t1 or Sapling-only. |
| Keystone won’t sign | Seed must match UFVK; device on Zcash mainnet; scan all UR frames. |
| Broadcast fails | Sync to tip; Zebrad reachable; signed PCZT not expired (re-prepare if needed). |
| UFVK mismatch | Re-export from the wallet that holds the seed; confirm uview1 on mainnet. |
| Balance zero after pair | Run sync; UFVK alone does not import notes without scan. |
More: Common Issues, Desktop Troubleshooting.
Security notes
- Treat UFVK export like sharing a read-only copy of your shielded history.
- Verify recipient and amount on Keystone’s screen before signing.
- Air-gapped signing reduces hot-wallet exposure; proving still runs on the Nozy machine.
- Back up your mnemonic — Keystone and/or Nozy depending on where the seed lives (Backup Strategies).