Repository Public
1# Runbooks23## Where things run4- `sp-wallet` (API + web, Postgres db `sp_wallet`): see `mld status`. Dir `~/apps/sp-wallet`, PM2 `sp-wallet`, nightly `sp-wallet-backup`.5- `sp-wallet-signer`: dedicated node. Dir `~/apps/sp-wallet-signer` (bundle only), data `~/sp-wallet-signer-data`6 (keystore, state, policy), wrap key `~/.config/sp-wallet-signer/wrap.key`, PM2 `sp-wallet-signer`, port 8651 (LAN, API node IP only).7- The API reaches the signer by LAN IP written at deploy time. After a DHCP renumbering: `mld deploy sp-wallet-signer && mld deploy sp-wallet`.89## Emergency halt10Phone: Security → Emergency halt → type STOP. Or on the signer node: `node ~/apps/sp-wallet-signer/signer.mjs halt && pm2 restart sp-wallet-signer`.11Resume: `node ~/apps/sp-wallet-signer/signer.mjs unhalt && pm2 restart sp-wallet-signer`. Balances stay visible while halted.1213## Paper backup of the recovery phrase (do this first)14In your own Terminal (not through an assistant, no screen sharing): `ssh -t <signer-node> /opt/homebrew/bin/node apps/sp-wallet-signer/signer.mjs export-recovery`,15type `SHOW`, write the 24 words on paper, clear the terminal. The phrase restores all three chains in any BIP-39 wallet16(paths in `docs/adr/0001-custody.md`).1718## Restore on a new signer node19There is deliberately no import command yet. Quickest safe path: import the 24 words into a standard wallet app20(EVM `m/44'/60'/0'/0/0`, BTC BIP-84 account 0, Solana `m/44'/501'/0'/0'`) and move the funds; then deploy a fresh signer21(`init`), run owner setup again and deposit to the new addresses.2223## Lost passkey24On the signer node: `signer.mjs reset-passkeys`, `signer.mjs setup-token`, restart the signer; on the API node25`psql sp_wallet -c 'delete from credentials; update sessions set revoked = true'`; open the site and run setup again.2627## Changing limits28Edit `~/sp-wallet-signer-data/policy.json` on the signer node (base units; increment `version`), `pm2 restart sp-wallet-signer`.2930## After a release that adds assets (registry v5: policy version 3)31The signer writes its default limits only when `policy.json` does not exist, so limits for new assets do not appear by themselves:32a token without a limit cannot be sent or swapped (default deny). On the signer node, either move the file aside and restart33(`mv policy.json policy.json.v2 && pm2 restart sp-wallet-signer` — the signer regenerates it from the defaults of the release,34`version: 3`; re-apply any limit you had changed by hand), or add the new `"<network>:<symbol>"` keys to `perTx` and `daily`35yourself and set `version` to 3. Existing limits are unchanged in the defaults. See `docs/TOKENS.md`.3637## After the release that adds Cardano and Polkadot (policy version 4)38Same rule as above: an existing `policy.json` does not gain the new entries by itself. Either regenerate it from the defaults39(`mv policy.json policy.json.v3 && pm2 restart sp-wallet-signer`, then re-apply hand-made changes), or add by hand40`"cardano:ADA": "285000000"` / `"polkadot:DOT": "600000000000"` to `perTx`, twice those values to `daily`,41`"cardano": "500000"` / `"polkadot": "500000000"` to `maxFee`, and set `version` to 4. No existing limit changes.42The two new addresses appear after the signer restarts (same seed; the wallet key id does not change).43If Polkadot sends stop with `runtime_changed`, or Cardano sends with `protocol_changed`: `docs/chains/polkadot.md`44("Runtime upgrades") and `docs/chains/cardano.md` ("Data sources and agreement").4546## Compromise suspected47Halt, then sweep funds to a new wallet from a clean device using the recovery phrase. Treat the old keys as burned.4849## Health50`https://wallet.spboucher.ai/api/v1/health/live` (public, no detail). Detail (authenticated): Settings → RPC status, Security.5152## Signer relay (API node)53macOS denies local-network access to PM2 / LaunchAgent background processes (EHOSTUNREACH), so the API talks to54`127.0.0.1:8652`, a byte relay run as a root LaunchDaemon (`ai.spboucher.sp-wallet-signer-relay`, script copied to55`/usr/local/libexec/sp-wallet/signer-relay.mjs`, root-owned) that forwards to `m6ma.local:8651` (mDNS, survives DHCP changes).56Reinstall on a new API node: copy `scripts/signer-relay.mjs` there as root, install `infra/launchd/*.plist` in57`/Library/LaunchDaemons`, `sudo launchctl bootstrap system <plist>`. Log: `~/Library/Logs/sp-wallet-signer-relay.log`.58The signer allowlist must contain the API node LAN IP (`SPW_SIGNER_ALLOW_IPS`, rendered at deploy).59