235 lines
14 KiB
Markdown
235 lines
14 KiB
Markdown
# DGB backend — local or VPS
|
||
|
||
## Production layout (digibyte.x, as deployed)
|
||
|
||
What actually runs today on the coinspectrum VPS, and the only thing the
|
||
web wallet needs:
|
||
|
||
| Piece | Where | Notes |
|
||
|---|---|---|
|
||
| vhost (Angie) | `/etc/angie/http.d/digibyte-x.conf` — served by **Angie** since 2026-09-16 (`systemctl reload angie`; `nginx.service` is inactive and `/etc/nginx/sites-enabled/digibyte-x` is a stale copy) — mirrored in [`nginx-digibyte-x.conf`](nginx-digibyte-x.conf) | SNI-selected on `digibyte.x`, self-signed cert pinned on-chain via the BNS `tls` record. Serves `/web/` (wallet), proxies `/p2p/*` → daemon and `/blockbook/*` → a public DGB Blockbook (Atomic Wallet's since 2026-10-11; NOWNodes before that, API key injected server-side from `/etc/dgb-core/nownodes.env` — switch with [`blockbook-upstream.sh`](blockbook-upstream.sh)), strict Content-Security-Policy on `/web/`. |
|
||
| `dgb-daemon.service` | `/opt/dgb-wallet`, runs `packages/p2p/bin/dgb-daemon.ts` via tsx, binds `127.0.0.1:5174` | The wallet's only server-side component: header sync with reorg handling, BIP157/158 filter cache (packed 1000/file under `/var/lib/dgb-wallet/.dgb-wallet/p2p/packs/`), incremental balance scans remembered in `scans.json`, Dandelion++ broadcast with relay-echo verification. |
|
||
| **No DigiByte Core, no Fulcrum** | — | Removed 2026-09-06. A full node with indexes needs ≥40 GB disk and ≥4 GB RAM; the VPS has neither, and the daemon does not use it. |
|
||
|
||
Routine deploy from the dev box: **[`push.sh`](push.sh)** — `ops/push.sh` (web + daemon), `ops/push.sh web`, `ops/push.sh daemon`. It builds, ships, swaps atomically, restarts the daemon, verifies the served bundle hash and warns if the CSP hash for the inline script drifted.
|
||
|
||
---
|
||
|
||
Deployment shapes documented below (the first two describe an optional DigiByte Core backend for `@dgb-wallet/rpc`; **not used by the web wallet**):
|
||
|
||
- **[Local install on Windows](#local-install-windows-desktop)** — fastest to get running; DGB Core lives on your desktop under `D:\Program Files\DigiByte\`, RPC on `http://127.0.0.1:14022`. Best for development.
|
||
- **[Turnkey RPC VPS install](#turnkey-vps-install)** — pruned DGB Core behind Caddy for the `@dgb-wallet/rpc` client, TLS-pinned via BCH BNS. Best when the wallet needs its own backend.
|
||
- **[Wallet-site VPS install](#wallet-site-vps-install)** — hosts the built web wallet at a `.x`/`.dgb` name AND reverse-proxies `/p2p/` to the daemon, so visitors get Balance/Send without a local daemon. See `deploy-wallet.sh` + `Caddyfile.wallet` + `dgb-daemon.service`.
|
||
- **[Wallet-subpath install](#wallet-subpath-install)** — same idea as above but mounts the wallet at `/web/` on an existing site (e.g. `digibyte.x/web`), leaving the site's `/` alone. See `deploy-wallet-web.sh` + `Caddyfile.wallet-web-snippet` + `dgb-daemon.service`.
|
||
|
||
Both use the same `@dgb-wallet/rpc` client. Only the transport differs.
|
||
|
||
---
|
||
|
||
## Local install (Windows desktop)
|
||
|
||
Requires: Windows 10/11, ~60 GB free disk (for pruned; grows slowly), 2+ GB RAM available for the Core process, an elevated PowerShell for the one-time Defender exclusion step.
|
||
|
||
```powershell
|
||
cd "D:\Dev\SilentCode\Digibyte\ops"
|
||
Set-ExecutionPolicy -Scope Process Bypass
|
||
.\setup-local.ps1
|
||
```
|
||
|
||
The script:
|
||
|
||
1. Downloads DGB Core `v8.26.2` for Windows, verifies SHA-256 against the release's `SHA256SUMS`
|
||
2. Installs binaries to `D:\Program Files\DigiByte\bin\`
|
||
3. Creates `D:\Program Files\DigiByte\data\` (chain data) and writes `digibyte.conf` with pruned settings, `disablewallet=1`, random 40-char RPC password
|
||
4. Adds `data\` to Windows Defender exclusions (real 3x sync speedup)
|
||
5. Creates a Startup shortcut so Core auto-starts at logon
|
||
6. Launches Core immediately for the initial sync
|
||
|
||
At the end, prints:
|
||
|
||
```
|
||
RPC endpoint: http://127.0.0.1:14022
|
||
Username: dgb_xxxxxxxx
|
||
Password: <40-char base64>
|
||
```
|
||
|
||
Paste those into your wallet's env for the RPC demo:
|
||
|
||
```powershell
|
||
$env:DGB_RPC_URL='http://127.0.0.1:14022'
|
||
$env:DGB_RPC_USER='dgb_xxxxxxxx'
|
||
$env:DGB_RPC_PASSWORD='<paste>'
|
||
npm run demo -w @dgb-wallet/rpc
|
||
```
|
||
|
||
Initial pruned sync takes ~4–8 hours on a 16 GB / SSD desktop. Monitor with:
|
||
|
||
```powershell
|
||
& "D:\Program Files\DigiByte\bin\digibyte-cli.exe" -conf="D:\Program Files\DigiByte\digibyte.conf" getblockchaininfo | Select-Object -First 20
|
||
```
|
||
|
||
**Uninstall:** kill `digibyted.exe`, delete `D:\Program Files\DigiByte`, remove the Startup shortcut from `shell:startup`, and (optionally) remove the Defender exclusion via Windows Security settings.
|
||
|
||
**Flags:**
|
||
- `-InstallDir "E:\dgb"` — install somewhere else
|
||
- `-Version "8.26.2"` — pin a different Core release
|
||
- `-SkipDefenderExclusion` — don't touch Defender (script will run without admin)
|
||
- `-SkipStartup` — don't create the auto-start shortcut
|
||
|
||
---
|
||
|
||
## Turnkey VPS install
|
||
|
||
Runs a pruned DigiByte Core node with wallet functionality disabled, behind Caddy for HTTPS + rate limiting. Total footprint: ~600 MB disk, 1 GB RAM, one CPU core. Fits comfortably on a €4/month VPS.
|
||
|
||
## What you get
|
||
|
||
- **Chain state:** current UTXO set (~500 MB), always in sync
|
||
- **Chain-state RPC methods available over HTTPS + basic auth:**
|
||
- `scantxoutset` — the workhorse; scan UTXO set for descriptors/xpubs
|
||
- `sendrawtransaction` — broadcast signed transactions
|
||
- `estimatesmartfee` — fee estimation
|
||
- `getblockchaininfo`, `getnetworkinfo`, `getrawmempool`
|
||
- **Wallet functionality disabled** (`disablewallet=1`) — the node holds no keys, so RPC compromise leaks chain metadata at worst, never funds
|
||
|
||
## Fresh-VPS quickstart (Debian 12 / Ubuntu 24.04)
|
||
|
||
Provision a VPS with public IPv4/IPv6. SSH in as root (or a sudo user). Then:
|
||
|
||
```bash
|
||
# Fetch and run the setup script
|
||
wget https://raw.githubusercontent.com/<TBD>/main/ops/setup.sh
|
||
chmod +x setup.sh
|
||
sudo ./setup.sh your-domain.example.com
|
||
```
|
||
|
||
The script:
|
||
|
||
1. Creates unprivileged `digibyte` user
|
||
2. Downloads DGB Core `v8.26.2`, verifies SHA-256 against the release's `SHA256SUMS`
|
||
3. Writes `digibyte.conf` (pruned, wallet disabled, RPC bound to localhost, random 40-char password)
|
||
4. Installs the systemd unit and starts `digibyted`
|
||
5. Installs Caddy, configures it for your domain with automatic Let's Encrypt TLS
|
||
6. Opens firewall ports 22 (SSH), 443 (HTTPS), 12024 (DGB P2P)
|
||
7. Prints the generated RPC credentials for you to paste into your wallet
|
||
|
||
Expected total time: ~20 min including the initial pruned sync.
|
||
|
||
## Manual step-by-step
|
||
|
||
If you'd rather understand each piece, see [MANUAL.md](MANUAL.md) — same steps as `setup.sh`, done by hand.
|
||
|
||
## Files in this directory
|
||
|
||
| File | Purpose |
|
||
|---|---|
|
||
| `push.sh` | **Routine deploy from the dev box** — build, ship web bundle and/or daemon sources, restart, verify (see Production layout) |
|
||
| `nginx-digibyte-x.conf` | Mirror of the live nginx vhost for digibyte.x (`@NOWNODES_API_KEY@` placeholder; render with `sed` as the file header shows) |
|
||
| `blockbook-upstream.sh` / `.ps1` | `atomic` or `nownodes` — repoint the live `/blockbook/` proxy, test, reload, verify (`.ps1` from PowerShell, where `bash` is the WSL launcher; both pipe `blockbook-upstream.remote.sh` over ssh) |
|
||
| `setup.sh` | RPC-VPS bootstrap (Core + Caddy in front of it) — optional Core backend, not deployed |
|
||
| `deploy-wallet.sh` | Wallet-site VPS bootstrap (web bundle at `/` + P2P daemon reverse-proxy) |
|
||
| `deploy-wallet-web.sh` | Wallet-subpath bootstrap — plain production build (relative `./` base), ships bundle to `<SITE_ROOT>/web/`, renders Caddy import snippet |
|
||
| `digibyte.conf` | Sample Core config; script substitutes the domain and password |
|
||
| `digibyte.service` | systemd unit for `digibyted` |
|
||
| `dgb-daemon.service` | systemd unit for `@dgb-wallet/p2p`'s HTTP daemon |
|
||
| `Caddyfile` | Caddy reverse-proxy config for the RPC-VPS shape (Core over HTTPS + basic auth) |
|
||
| `Caddyfile.bns` | Same as `Caddyfile` but with a pinned self-signed cert (no ACME) |
|
||
| `Caddyfile.wallet` | Serves `dist/` at `/` and proxies `/p2p/*` to `dgb-daemon` |
|
||
| `Caddyfile.wallet-web-snippet` | Imported into an existing site's Caddyfile — adds `/web/*` (static) and `/p2p/*` (reverse-proxy) handlers |
|
||
|
||
---
|
||
|
||
## Wallet-site VPS install
|
||
|
||
Hosts the built `@dgb-wallet/web-ui` bundle under a `.x`/`.dgb` BNS name, plus reverse-proxies `/p2p/*` to a local `dgb-daemon` so Balance and Send work without visitors running a daemon locally.
|
||
|
||
Prereqs on the VPS: Debian 12 / Ubuntu 24.04, ≥2 GB RAM (8 GB heap ceiling for the daemon), public IPv4, ports 22/443 reachable, 12024 outbound for DGB P2P.
|
||
|
||
```bash
|
||
# On your dev box — push the checkout to the VPS:
|
||
scp -r D:\Dev\SilentCode\Digibyte user@vps:/opt/dgb-wallet
|
||
|
||
# On the VPS:
|
||
sudo /opt/dgb-wallet/ops/deploy-wallet.sh digibyte.x
|
||
```
|
||
|
||
The script installs Caddy + Node 20, `npm install`s the monorepo, builds the web bundle to `/var/www/dgb-wallet/`, generates a self-signed cert with CN=`digibyte.x`, wires the daemon into systemd, and prints the exact BCH BNS UPD payload:
|
||
|
||
```bash
|
||
# On your BCH-wallet host (has D:\Dev\NameCoin):
|
||
cd D:\Dev\NameCoin
|
||
node src/update.js digibyte.x '{
|
||
"ip": "<VPS IPv4>",
|
||
"tls": "<SHA-256 fingerprint>",
|
||
"u": "https://digibyte.x"
|
||
}'
|
||
```
|
||
|
||
After 1–2 BCH confirmations, `resolveEndpoint('digibyte.x')` returns the pinned pair and any wallet-aware client validates the TLS handshake against the fingerprint. Balance/Send tabs in the deployed bundle POST to `/p2p/balance` and `/p2p/broadcast`, transparently proxied to the daemon.
|
||
|
||
---
|
||
|
||
## Wallet-subpath install
|
||
|
||
Use this when the target host already serves other content at `/` and the wallet lives at `/web/` — e.g. the current `digibyte.x/web` layout, where the apex hosts existing pages and only the wallet section is added.
|
||
|
||
Difference from the previous section: `deploy-wallet.sh` overwrites `/etc/caddy/Caddyfile` and manages its own TLS cert. `deploy-wallet-web.sh` does neither — it renders an import snippet, optionally wires it into an existing Caddyfile between sentinel markers, and inherits whatever TLS the host already has configured.
|
||
|
||
```bash
|
||
# On your dev box:
|
||
scp -r D:\Dev\SilentCode\Digibyte user@vps:/opt/dgb-wallet
|
||
|
||
# On the VPS — automatic wiring:
|
||
sudo /opt/dgb-wallet/ops/deploy-wallet-web.sh --merge /etc/caddy/Caddyfile
|
||
|
||
# …or, manual wiring — script prints the exact three lines to paste
|
||
# inside your existing :443 { } block:
|
||
sudo /opt/dgb-wallet/ops/deploy-wallet-web.sh
|
||
```
|
||
|
||
The script:
|
||
|
||
1. Installs Caddy + Node 20 if missing.
|
||
2. `npm install`s the monorepo and runs a plain `npm run build -w @dgb-wallet/web-ui`. Production builds use a relative `./` asset base; `index.html` carries an inline script that re-anchors a `<base href>` at `<origin>…/web/` at runtime, so one bundle serves both `https://digibyte.x/web/` and the `navigate.st/bns/digibyte.x/web/` gateway. The script refuses to run if `DGB_UI_BASE` is set, and aborts if `dist/index.html` lacks `./assets/…` references or the runtime `<base>` script.
|
||
3. Rsyncs `packages/web-ui/dist/` → `<SITE_ROOT>/web/` (default `/var/www/dgb-wallet/web/`).
|
||
4. Creates the `dgb-wallet` system user and installs `dgb-daemon.service` (systemd) bound to `127.0.0.1:5174`.
|
||
5. Renders `Caddyfile.wallet-web-snippet` with `@SITE_ROOT@` substituted to `/etc/caddy/snippets/dgb-wallet.caddyfile`.
|
||
6. With `--merge <path>`: idempotently inserts (or replaces between `# --- START DGB WALLET IMPORT ---` / `# --- END DGB WALLET IMPORT ---`) an `import` line inside the last `:443 { }` block in the target Caddyfile, then `caddy validate` and reload. Without `--merge`: prints the three-line insert for the operator to paste by hand.
|
||
7. Prints the final wallet URLs (`/web/`, `/p2p/health`, `/p2p/balance`, `/p2p/broadcast`) and the redeploy one-liner.
|
||
|
||
Flags:
|
||
- `--merge <path>` — Caddyfile to inject the import line into.
|
||
- `--site-root <path>` — override the `/var/www/dgb-wallet` default. The bundle always lands under `<SITE_ROOT>/web/`.
|
||
|
||
Rollback: remove the three sentinel lines from the host Caddyfile and `systemctl reload caddy`. `systemctl disable --now dgb-daemon` stops the P2P daemon. `<SITE_ROOT>/web/` can be `rm -rf`'d without touching anything else the site serves.
|
||
|
||
## Wallet-side
|
||
|
||
Point `@dgb-wallet/rpc` at `https://your-domain.example.com` with the credentials `setup.sh` printed. See [../packages/rpc/README.md](../packages/rpc/README.md) for the demo.
|
||
|
||
## Security notes
|
||
|
||
Web wallet (nginx + daemon):
|
||
|
||
- **Strict CSP on `/web/`.** `script-src 'self'` plus the sha256 of the one inline script (the runtime `<base>` fix). Recompute with `node packages/web-ui/scripts/csp-hash.mjs` after editing `packages/web-ui/index.html`; `push.sh` warns on drift. Built asset tags carry `integrity=` (SRI) so a tampered asset file fails to load.
|
||
- **No keys on the server.** The daemon only ever sees xpubs / scripts to scan and signed transaction bytes to broadcast.
|
||
- **Blockbook is opt-in** and proxied so the upstream sees the VPS's IP, not the user's; the API key never reaches the browser.
|
||
|
||
Optional Core backend (`setup.sh` shape):
|
||
|
||
- **Wallet is disabled on the node.** Even a full RPC compromise cannot spend funds — there are no keys on the server.
|
||
- **RPC is not exposed on port 14022.** Core binds RPC to `127.0.0.1` only. All external access goes through Caddy on 443 with TLS + basic auth.
|
||
- **Rate limiting.** Caddy config limits any single IP to 60 requests/minute per endpoint (`scantxoutset` is cheap on a pruned node but not free).
|
||
- **Keep the RPC password strong.** The setup script generates a 40-char random one; don't shorten it. If you lose it, regenerate on the VPS and rewrite `digibyte.conf`.
|
||
- **No wallet method whitelist yet.** With `disablewallet=1` there's nothing sensitive to whitelist against; future hardening could restrict to only the six methods listed above. Low priority given the disabled-wallet posture.
|
||
|
||
## What's next
|
||
|
||
Once this is running, `@dgb-wallet/rpc` connects to it in seconds. Recovery flow becomes:
|
||
|
||
```
|
||
seed → derive addresses (offline) → scantxoutset via VPS → real balances
|
||
→ sign PSBT (offline) → broadcast via VPS
|
||
```
|
||
|
||
Whole loop, real chain data, no local Core install, no third-party service. Full self-sovereignty as soon as the VPS is yours.
|