QALS Wiki · the qalarc network⌂ qalarc.com/projects/qals
generated 2026-09-16 · qalcode autonomous research

Phones + computers + tokens — the 10-minute founder test · content/testkit.md

Testkit — the founder's 10-minute multi-device walkthrough

Mission: "test messaging systems on different computers and phones with a number of tokens."

One command sets up a party (or three), funds it with paper-mode test cents (paper-phase QALS, not real money), and prints a READY CARD with everything each device needs:

bash scripts/testkit.sh <party-name> [cents]   # one party, default 2000c = AU$20
bash scripts/testkit.sh --demo                 # alice + bob + carol, live traffic, test script

Idempotent — re-run any time. Existing identities are kept (keys are just republished to both relays); the topup adds more tokens.

The 3-device map

Device Role Talks to
📱 Redmi phone bridge web UI (reads/sends as mcp-bot) http://100.73.134.20:8837 (superlocal, tailscale-only)
🖥 superlocal (this machine) identities, wallet, CLI, loopd money local relay 127.0.0.1:8830, loopd 127.0.0.1:8823
💻 cachyos-x8664 (100.111.199.12) 2nd computer, fresh identity fleet relay http://100.111.199.12:8840

Relay truth: superlocal's relay binds loopback — the fleet relay on cachyos-x8664 is the only cross-machine post office. The demo deliberately sends fleet-first to prove the cross-device path.

0:00 — set the board (superlocal)

bash scripts/testkit.sh --demo

What you see: alice/bob/carol funded (+2000c each), then live proof:

Then three READY CARDS: handle, qoll-code (qoll-xxxx-xx), balance, QR.

2:00 — the Redmi phone

  1. Tailscale ON on the phone.
  2. Scan the alice card's QR (or type the URL): the format is

http://100.73.134.20:8837/phone?t=<token>

The token is the one file: qalbridge/data/.token on superlocal. First hit mints a cookie and strips ?t= from the address bar — then bookmark the clean URL. 3. Chats ▸ alice — the seeded line ("founder — reply to alice from the Redmi 📱") is already there. Type a reply.

Success: on superlocal, python3 qalchat/qalchat.py recv --as alice prints [mcp-bot → me] #… hello from the Redmi.

4:00 — desktop on superlocal

# the CLI chat (or cargo tauri dev in wallet-app/src-tauri for the wallet UI)
python3 qalchat/qalchat.py chat bob --as alice \
  --relays "http://127.0.0.1:8830,http://100.111.199.12:8840"
# type two lines, watch bob's card on the phone afterwards (Chats ▸ bob)
python3 qalchat/qalchat.py pay bob 250 "latte" --as alice   # ⚡ 2.50 B-QALS

Success: the phone transcript shows your lines and a gold ⚡ payment card with the amount; the CLI printed transfer ok: r_xxxx 250c (2.50 B-QALS) → bob.

6:00 — the second computer (cachyos-x8664, relay #2 read path)

Follow any card's ANOTHER COMPUTER block — identities are per-device by design (new keys there), messaging is handle→handle:

rsync -a [email protected]:projects/GLM_projects/crypto_currency/ ./crypto_currency/
cd crypto_currency
python3 qalchat/qalchat.py init alice-2nd --relays http://100.111.199.12:8840
python3 qalchat/qalchat.py recv --as alice-2nd --relays http://100.111.199.12:8840
python3 qalchat/qalchat.py send alice "hello from cachyos" --as alice-2nd \
  --relays http://100.111.199.12:8840

Success: back on superlocal, recv --as alice shows the cachyos line. Note: loopd (payments) is loopback on superlocal — money moves from the desktop/phone side; the 2nd machine chats.

8:00 — money trail + conversation anchor

curl -s http://127.0.0.1:8823/receipts | python3 -m json.tool | tail -20   # transfer receipts
python3 qalchat/qalchat.py anchor bob --as alice    # Merkle root → Qalnet, prints tx/object id
python3 qalchat/qalchat.py verify-convo bob --as alice

Troubleshooting

Symptom Fix
Fleet relay curl hangs / times out DERP flap — warm the tunnel: tailscale ping cachyos-x8664 until it reports a direct/pong path, then retry. First packet after idle often rides DERP.
Phone shows 401 / empty page Token mismatch — read cat qalbridge/data/.token on superlocal, re-open http://100.73.134.20:8837/phone?t=<that>. (The systemd unit's QALBRIDGE_TOKEN must match this file.)
Phone URL doesn't resolve at all Tailscale down on the phone, or bridge down: systemctl --user start qal-bridge (health: curl 127.0.0.1:8837/health).
could not publish pubkey on a relay Re-run the testkit line for that party — it republishes keys to both relays.
recv: … rejected / chain gap Envelopes expire after 24 h on the relay. If a device skipped mail, just send fresh messages via testkit — old gaps are past TTL.
Payment refuses from the 2nd computer Expected — loopd is superlocal-local. Pay from the desktop card's line.
program cap reached on topup The Phase-0 finite-supply cap (the issuer wallet running out) — that's policy, not a bug.

What testkit touches (and never touches)

Reads: loopd/data/.admin_key (X-Admin on /topup only), qalbridge/data/.token. Writes: new identity under qalchat/data/identities/, loopd balances. Never edits service code, unit files, or relay state.