fix(openwrt): close TollGate free-access gap, mint URL bug, and payout config #155

Closed
ssmithx wants to merge 3 commits from fix/tollgate-provisioning-gaps into main
Collaborator

Summary

  • Free-access gap: the upstream tollgate-module-basic-go installer's own default AP (wireless.default_radioN, rebranded "TollGate-") was left bound to network=lan — wide open, unmetered, sharing the router's admin LAN — because install_ipk() runs the package's own uci-defaults scripts but nothing reconciled that AP with the separate tollgate network/bridge/firewall this project's own provision_ssid() sets up. Fixed by folding any default_radioN section still on lan onto the tollgate network right after it's created.
  • Mint URL rejection: a caller-supplied mint_url with a trailing slash was written byte-for-byte into accepted_mints[0].url, which tollgate-wrt string-compares exactly against a token's embedded (slash-less) mint URL — rejecting every valid token as an "untrusted mint". Fixed by trimming trailing slashes before use.
  • Sweep bugs documented: tollgate_sweep.rs's automated ecash sweep has never actually worked — tollgate wallet drain cashu blocks on an interactive y/N prompt that a non-PTY SSH exec can never answer (exits 0 regardless, so the failure is invisible). The obvious fix (--json, which does skip the prompt) is worse: confirmed live that on a wallet with a stale duplicate per-mint registry entry, it completes a real swap then discards the resulting token entirely when a different mint entry fails, reporting "success": false with no recovery path. Documented in detail so nobody wires in --json before upstream fixes the data loss.
  • Payout address now configurable: Archipelago never touched /etc/tollgate/identities.json — the "owner" payout identity was whatever the router's TollGate install defaulted to (confirmed: an unmodified upstream placeholder). Adds TollGateConfig.payout_address (opt-in), merges it into the owner entry without disturbing the merchant keypair or other profit-share identities, and exposes it as a field in the OpenWrt Gateway UI's reconfigure form.

All of the above (except the payout-address UI, which is type-checked/built but not yet exercised live) was found and verified live against a real GL.iNet GL-MT3000 router (archy-x250-pa3) — see commit messages for exact repro details, log excerpts, and dates.

Test plan

  • cargo build -p archipelago-openwrt -p archipelago — clean
  • vue-tsc -b && vite build (neode-ui) — clean; new payout_address field confirmed present in the built bundle
  • Wifi/mint fixes verified live: TollGate-3458 re-gated onto br-tollgate, real Cashu payment succeeded end-to-end (Receive completed, amount=50, err=<nil>), NoDogSplash shows State: Authenticated with real traffic
  • Payout-address UI field not yet exercised against a live router from the UI itself (only type-checked/built)

🤖 Generated with Claude Code

## Summary - **Free-access gap**: the upstream `tollgate-module-basic-go` installer's own default AP (`wireless.default_radioN`, rebranded "TollGate-<serial>") was left bound to `network=lan` — wide open, unmetered, sharing the router's admin LAN — because `install_ipk()` runs the package's own `uci-defaults` scripts but nothing reconciled that AP with the separate `tollgate` network/bridge/firewall this project's own `provision_ssid()` sets up. Fixed by folding any `default_radioN` section still on `lan` onto the `tollgate` network right after it's created. - **Mint URL rejection**: a caller-supplied `mint_url` with a trailing slash was written byte-for-byte into `accepted_mints[0].url`, which `tollgate-wrt` string-compares exactly against a token's embedded (slash-less) mint URL — rejecting every valid token as an "untrusted mint". Fixed by trimming trailing slashes before use. - **Sweep bugs documented**: `tollgate_sweep.rs`'s automated ecash sweep has never actually worked — `tollgate wallet drain cashu` blocks on an interactive y/N prompt that a non-PTY SSH exec can never answer (exits 0 regardless, so the failure is invisible). The obvious fix (`--json`, which does skip the prompt) is worse: confirmed live that on a wallet with a stale duplicate per-mint registry entry, it completes a real swap then discards the resulting token entirely when a *different* mint entry fails, reporting `"success": false` with no recovery path. Documented in detail so nobody wires in `--json` before upstream fixes the data loss. - **Payout address now configurable**: Archipelago never touched `/etc/tollgate/identities.json` — the "owner" payout identity was whatever the router's TollGate install defaulted to (confirmed: an unmodified upstream placeholder). Adds `TollGateConfig.payout_address` (opt-in), merges it into the `owner` entry without disturbing the merchant keypair or other profit-share identities, and exposes it as a field in the OpenWrt Gateway UI's reconfigure form. All of the above (except the payout-address UI, which is type-checked/built but not yet exercised live) was found and verified live against a real GL.iNet GL-MT3000 router (archy-x250-pa3) — see commit messages for exact repro details, log excerpts, and dates. ## Test plan - [x] `cargo build -p archipelago-openwrt -p archipelago` — clean - [x] `vue-tsc -b && vite build` (neode-ui) — clean; new `payout_address` field confirmed present in the built bundle - [x] Wifi/mint fixes verified live: TollGate-3458 re-gated onto `br-tollgate`, real Cashu payment succeeded end-to-end (`Receive completed, amount=50, err=<nil>`), NoDogSplash shows `State: Authenticated` with real traffic - [ ] Payout-address UI field not yet exercised against a live router from the UI itself (only type-checked/built) 🤖 Generated with [Claude Code](https://claude.com/claude-code)
ssmithx added 3 commits 2026-09-07 20:41:47 +00:00
Two bugs found live against archy-x250-pa3: TollGate-3458 (the upstream
tollgate-module-basic-go installer's own default AP, rebranded from
OpenWrt's factory default wireless.default_radioN sections) was left
bound to `network=lan` — wide open, unmetered, and sharing the router's
admin LAN — because install_ipk() runs the upstream package's own
uci-defaults scripts but nothing reconciled the AP they create with the
separate `tollgate` network/bridge/firewall this project's own
provision_ssid() sets up for the "archipelago" SSID. Fixed by folding any
default_radioN section left on `lan` onto the `tollgate` network right
after it's created.

Separately, a caller-supplied mint_url with a trailing slash
(https://mint.minibits.cash/Bitcoin/) got written byte-for-byte into
accepted_mints[0].url, which tollgate-wrt string-compares exactly against
a token's embedded (slash-less) mint URL — rejecting every otherwise-valid
token as an "untrusted mint". Fixed by trimming trailing slashes before
the value is used anywhere.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KTdMfVJChCwCCYF1ZTRQLc
sweep_once() has never actually swept anything: `tollgate wallet drain
cashu` (no flags) blocks on an interactive y/N confirmation that Router::run
can never answer over a non-PTY SSH exec (empty stdin -> EOF -> defaults to
N -> "Operation cancelled." with exit code 0), so the drain_code != 0 check
can't catch it and every tick silently no-ops.

The obvious fix isn't safe either: `--json` skips the prompt, but confirmed
live against archy-x250-pa3 that on a wallet.db with a stale duplicate
per-mint entry (trailing-slash leftover from before the mint_url fix), it
completes a real swap against the good entry, then aborts on the second
(empty, stale) entry and reports "success": false without ever printing or
persisting the resulting token anywhere. 50 sats went from spendable balance
to gone in that one call. Documented so nobody "fixes" this by wiring in
--json before upstream fixes the partial-failure data loss.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KTdMfVJChCwCCYF1ZTRQLc
Archipelago never touched /etc/tollgate/identities.json — the "owner"
payout identity was whatever the router's TollGate install happened to
default to. Confirmed live against archy-x250-pa3: an unmodified upstream
placeholder (tollgate@minibits.cash), meaning 79% of every customer payment
would auto-payout to an address the operator never chose and doesn't
control.

Adds TollGateConfig.payout_address (opt-in — None leaves the router
untouched), config::apply_payout_identity() to merge it into the "owner"
entry of identities.json without disturbing the merchant keypair or the
other profit-share identities, an RPC param on openwrt.provision-tollgate,
and a status field + reconfigure-form input in the OpenWrt Gateway panel.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KTdMfVJChCwCCYF1ZTRQLc
chaum closed this pull request 2026-09-12 13:37:16 +00:00
Collaborator

Closed at maintainer request pending a fresh review/requirements pass. The branch remains available for reference.

Closed at maintainer request pending a fresh review/requirements pass. The branch remains available for reference.

Pull request closed

This pull request cannot be reopened because the branch was deleted.
Sign in to join this conversation.