Files
wownerogue/docs/DEPLOY_INSTANCES.md
T
jwinterm 703dda265b docs: tune stagenet payout caps for the ~0.38 sXMR bankroll
Lower PAYOUT_MAX_PER_GAME to 0.05 XMR (real max is 3x*0.01=0.03), add
LOW_BALANCE_THRESHOLD alert/halt, and note the bankroll + faucet-refill tip.
2026-05-31 15:14:12 -04:00

7.4 KiB

Two-instance deployment runbook

Two independent instances of the same secured codebase, behind Nginx Proxy Manager (NPM):

Instance Domain Port Network Money Payouts Leaderboards
wownerogue (existing) play.wowne.ro 3000 Wownero mainnet real WOW OFF Pleb + Hall of Champions
monerogue (new) monerogue.app 3001 Monero stagenet fake XMR ON Pleb + Hall of Champions

NPM already forwards both domains to these ports + handles TLS — no reverse-proxy work here.

⚠️ Nothing below has been executed. Run only after review. Step 0 is the urgent one (the live mainnet instance still runs pre-fix code with the underpayment exploit + payouts).

Server facts (verified): root+sudo; monerod --stagenet RPC on 127.0.0.1:38081; monero-wallet-rpc at /usr/bin; stagenet wallet …/monero-…-v0.18.4.4/test(.keys); Postgres has wownerogue,wowrace; ports 3001 and 38083 free; code at /var/www/wownerogue/app on branch main (commit 82fdcc0).


Step 0 — Get the secured branch onto the server

# Local: push the remediation branch (or merge to main first)
git push origin security/phase-0-critical-fixes

# Server (mainnet instance):
sudo -u wownerogue git -C /var/www/wownerogue/app fetch origin
sudo -u wownerogue git -C /var/www/wownerogue/app checkout security/phase-0-critical-fixes
cd /var/www/wownerogue/app/src && sudo -u wownerogue npm ci
# Migrations run automatically on boot; or apply manually with the app's runner.

Step 1 — Reconfigure the MAINNET instance: free-to-play, NO payouts

Edit /var/www/wownerogue/app/src/.env — change these keys (keep everything else):

FREE_PLAY_ENABLED=true            # offer free play as a choice (Pleb board)
PAYOUTS_ENABLED=false             # no crypto leaves the house wallet
DIRECT_PAYOUTS_ENABLED=false
CREDITS_PAYOUTS_ENABLED=false
DIRECT_REQUIRES_ADDRESS=false     # no payout = no payout address needed
CREDITS_REQUIRES_ADDRESS=false
TRUST_PROXY=true                  # we are behind NPM; read real client IP from X-Forwarded-For

Players still buy credits / pay entry (→ Hall of Champions prestige); free players → Pleb board. No payouts = not gambling.

sudo systemctl restart wownerogue.service
journalctl -u wownerogue.service -n 50 --no-pager   # verify: "Payment system: ENABLED", payouts disabled
curl -s localhost:3000/api/game-modes | jq '{freePlayEnabled, PAID_SINGLE:.PAID_SINGLE.payoutMultiplier}'

Step 2 — Stand up the MONERO STAGENET wallet-rpc

sudo cp scripts/deploy/monero-wallet-rpc.service /etc/systemd/system/
sudoedit /etc/systemd/system/monero-wallet-rpc.service   # set REPLACE_WITH_WALLET_PASSWORD
sudo systemctl daemon-reload
sudo systemctl enable --now monero-wallet-rpc.service
sudo systemctl status monero-wallet-rpc.service --no-pager
# sanity: wallet answers + is the stagenet wallet that holds the coins
curl -s http://127.0.0.1:38083/json_rpc -d '{"jsonrpc":"2.0","id":"0","method":"get_balance"}' -H 'Content-Type: application/json'

Needs the wallet password (not in the repo). Confirm …/v0.18.4.4/test is the stagenet wallet with the coins, or point --wallet-file at the right one.

Step 3 — Create the monerogue user, code checkout, and DB

sudo useradd --system --home /var/www/monerogue --shell /usr/sbin/nologin monerogue
sudo mkdir -p /var/www/monerogue && sudo chown monerogue:monerogue /var/www/monerogue
sudo -u monerogue git clone git@github.com:jwinterm/wownerogue.git /var/www/monerogue/app
sudo -u monerogue git -C /var/www/monerogue/app checkout security/phase-0-critical-fixes
cd /var/www/monerogue/app/src && sudo -u monerogue npm ci

sudo -u postgres createdb monerogue
sudo -u postgres psql -c "CREATE USER monerogue WITH PASSWORD 'CHANGE_ME';"
sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE monerogue TO monerogue;"

Step 4 — The monerogue .env

Write /var/www/monerogue/app/src/.env (owned by monerogue, chmod 600). Stagenet/fake money, so payouts are fine. Amounts are XMR atomic units (1 XMR = 1e12):

NODE_ENV=production
PORT=3001
TRUST_PROXY=true
CRYPTO_TYPE=XMR
MONERO_NETWORK=stagenet
HOSTED_BY=https://monerogue.app
DIFFICULTY_PRESET=casino

# --- payments + free play ---
PAYMENTS_ENABLED=true
PAYMENT_MODES=direct,credits
FREE_PLAY_ENABLED=true            # both boards available

# --- direct (pay per game) WITH payouts (fake stagenet money) ---
DIRECT_PAYMENT_ENABLED=true
DIRECT_GAME_PRICE=10000000000     # 0.01 XMR
DIRECT_REQUIRES_ADDRESS=true
DIRECT_PAYOUTS_ENABLED=true
DIRECT_PAYOUT_ESCAPE=2.0
DIRECT_PAYOUT_TREASURE=3.0

# --- credits WITH payouts ---
CREDITS_ENABLED=true
CREDITS_PER_GAME=1
CREDITS_REQUIRES_ADDRESS=true
CREDITS_PAYOUTS_ENABLED=true
CREDITS_PAYOUT_BASE=10000000000
CREDITS_PAYOUT_ESCAPE=2.0
CREDITS_PAYOUT_TREASURE=3.0
CREDITS_PACKAGES=[{"id":"small","credits":10,"price":"90000000000","bonus":0},{"id":"medium","credits":20,"price":"170000000000","bonus":2}]
ALLOW_MIXED_MODE=true
PREFER_CREDITS_FIRST=true

# --- payouts --- (bankroll: ~0.3797 sXMR in the "test" wallet)
PAYOUTS_ENABLED=true
PAYOUT_MIN_AMOUNT=1000000000        # 0.001 XMR
PAYOUT_MAX_PER_GAME=50000000000     # 0.05 XMR safety cap (real max is 3x*0.01 = 0.03)
PAYOUT_BATCH_INTERVAL=300
PAYOUT_MAX_RETRIES=3
LOW_BALANCE_THRESHOLD=50000000000   # alert/halt when unlocked balance drops below 0.05 XMR
# Tip: lower DIRECT_GAME_PRICE/CREDITS_PAYOUT_BASE to 0.001 XMR (1000000000) for many more
# demo plays per the small bankroll; refill from a stagenet faucet as needed.

# --- wallet RPC (monero stagenet) ---
PRIMARY_WALLET_ENDPOINT=http://127.0.0.1:38083
# wallet-rpc started with --disable-rpc-login, so no WALLET_RPC_USER/PASSWORD

# --- daemon RPC (monerod stagenet) ---
PRIMARY_RPC_ENDPOINT=http://127.0.0.1:38081
FALLBACK_RPC_ENDPOINT=http://127.0.0.1:38081
RPC_POLL_INTERVAL=2000

# --- database ---
DB_HOST=localhost
DB_PORT=5432
DB_NAME=monerogue
DB_USER=monerogue
DB_PASSWORD=CHANGE_ME

# --- admin ---
ADMIN_API_KEY=GENERATE_WITH_openssl_rand_hex_32

# --- smirk: disable for monero stagenet (Smirk doesn't support stagenet) ---
SMIRK_ENABLED=false
sudo chmod 600 /var/www/monerogue/app/src/.env
sudo chown monerogue:monerogue /var/www/monerogue/app/src/.env

Step 5 — Install + start the monerogue instance

sudo cp scripts/deploy/monerogue.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now monerogue.service
journalctl -u monerogue.service -n 60 --no-pager     # expect: listening on :3001, payments ENABLED
curl -s localhost:3001/health | jq '{network:.network, wallet:.wallet.status, mode:.gameMode}'

Step 6 — Verify end to end

  • monerogue.app loads; play.wowne.ro still healthy.
  • Stagenet: buy credits / pay entry with a stagenet wallet → game starts → win → payout arrives (this is the real wownero-wallet-rpc/monero-wallet-rpc integration test that TODO.md has always wanted — now on fake money).
  • Both boards populate: free game → Pleb, paid game → Hall of Champions, on each instance.
  • Mainnet: confirm a winning paid game does NOT send a payout (no crypto out).

Rollback

  • sudo systemctl stop monerogue monero-wallet-rpc (stagenet instance is independent; stopping it can't affect mainnet).
  • Mainnet: git checkout main && systemctl restart wownerogue to revert the reconfig.