Web Wallet

Client-side wallet using Web Crypto. Private keys never leave the browser.


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 sessionStorage under xe.session.unlock for 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+.