Client-side wallet embedded in the xe binary, served as part of the embedded web UI (xe node --ui — wallet pages are on by default). Private keys never leave the browser. Zero JavaScript dependencies.
Security
- Seeds encrypted with AES-GCM via Web Crypto API
- Keys derived via PBKDF2 (600,000 iterations, SHA-256)
- Fresh random IV per encryption
- Unlock lasts a hard 30 minutes from unlock (checked lazily on use) — there is no idle timer; lock explicitly or close the tab to end it sooner
- Seeds stored in localStorage as encrypted ciphertext only
- Private keys never leave the browser
- No JS dependencies — uses native Web Crypto
Warning: after unlock, the raw passphrase is cached in
sessionStorageunderxe.session.unlockfor up to 30 minutes so page navigations don't re-prompt. Any code running in the same origin can read it — roughly equivalent in risk to holding the decrypted seed in JS memory. The vault on disk stays encrypted regardless. Use the lock button on shared machines.
Features
- Multi-wallet management — create, import, rename, delete wallets
- Send/Receive — transfer XE between accounts; pending sends are claimed with a per-item receive button (there is no auto-receive polling)
- Faucet — request testnet XE; the button appears when the node is started with a faucet target
- P2P Chat — real-time delivery, ed25519 signed envelopes
- Provider dashboard — read-only view of providers; creating leases and VM/SSH access are CLI-only
- DAO governance — draft, sign, submit state chain blocks
- State inspector — browse state chain blocks and KV entries
- Client-side signing — blocks are signed in the browser, but not offline: the node supplies the frontier, balance, network ID, and PoW parameters, and the same call submits the block
Enabling
xe node --ui # embedded UI, wallet pages included (default)
xe node --ui --wallet=false # UI without wallet (explorer only)Wallet pages are enabled by default whenever the UI is on; --wallet=false
makes the node serve 404 for /wallet/*. Because keys stay client-side this is
a containment convenience, not the security boundary — the UI binds to
--ui-bind (default 127.0.0.1), so exposing it publicly is an explicit choice
that should go through a reverse proxy.
Technology
Plain HTML + ES modules + Web Crypto. Embedded in the Go binary via //go:embed. No build step, no framework, no bundler. Signing requires Web Crypto Ed25519: Chrome 113+, Firefox 130+, Safari 17+.