Skip to content

docs(manual-test)(#218): full two-peer + daemon + IPFS-only recovery walkthrough#222

Merged
vrogojin merged 4 commits into
integration/all-fixesfrom
docs/issue-218-full-recovery-manual-test
May 23, 2026
Merged

docs(manual-test)(#218): full two-peer + daemon + IPFS-only recovery walkthrough#222
vrogojin merged 4 commits into
integration/all-fixesfrom
docs/issue-218-full-recovery-manual-test

Conversation

@vrogojin
Copy link
Copy Markdown
Contributor

Summary

Closes #218. Adds manual-test-full-recovery.md as a companion to
manual-test-drain-fix.md, covering the §A–§E scenarios called out in
the issue:

  • §A Second profile instance per wallet (peer2-alice, peer2-bob in separate CWDs) — verifies per-instance OrbitDB / IPFS sync for the same identity.
  • §B Long-running foreground sphere daemon listeners on peer2 — documents the exact --event / --action quick-mode flags and the per-CWD daemon PID collision gotcha.
  • §C Bidirectional invoice flow (11 UCT) with daemons running — asserts peer2 sees the new state without a manual sphere payments sync.
  • §D Wipe-and-recover BOTH profiles on BOTH peers using sphere init --no-nostr --mnemonic — proves the published CARs survive without faucet or live Nostr input.
  • §E Recovery preserves the invoice ledger — sphere invoice list --state COVERED diffed pre/post wipe must be empty.

Why a sibling doc (vs. extending in-place)

The issue's acceptance section explicitly allows both. The existing
243-line drain-fix doc is tightly focused on the PR #127 follow-up
(sync() drain). Extending it would balloon it to ~700 lines and dilute
its narrative. The sibling cross-references §0 of the drain-fix doc for
prereqs and matches its style (numbered sections, "what you're looking
for" assertions, gotchas, command cheat sheet).

Layout decision

Three CWDs under ~/sphere-full-test/:

peer1/         ← primary; both alice + bob via `sphere wallet use`
peer2-alice/   ← secondary instance of alice (own daemon)
peer2-bob/     ← secondary instance of bob   (own daemon)

Rationale: ./.sphere-cli/{config.json,daemon.pid,daemon.log} are
CWD-relative and not profile-scoped. Two daemons in one CWD collide on
PID without explicit --pid/--log overrides. Per-peer-wallet CWDs
sidestep the collision and keep the daemon commands simple.

Test plan

  • Operator follows §0–§E on a fresh testnet checkout, all five
    assertions pass.
  • §A's peer1↔peer2 balance diff is empty after init --mnemonic + sync.
  • §B daemons report Daemon running. Waiting for events... with no
    PID-collision error.
  • §C.4 peer2 balance reflects the 11 UCT invoice payment without a
    manual sphere payments sync (auto-receive worked).
  • §D.5 — all four diff outputs empty after --no-nostr recovery on
    both peers.
  • §E — invoice list --state COVERED diff pre/post wipe is empty;
    the §C invoice spot-check shows COVERED with the same memo.

Out of scope

Per the issue: scripted automation lives separately in tests/e2e/*.test.ts
(profile-multi-device-sync.test.ts, ipfs-multi-device-sync.test.ts,
two-device-local-mint-convergence.test.ts). This walkthrough is meant
to be human-runnable on testnet.

Refs

…ery walkthrough

Companion to manual-test-drain-fix.md covering the sections the drain-fix
doc cannot reach:

  §A Second profile instance per wallet (peer2-alice, peer2-bob in separate
     CWDs) — verifies per-instance OrbitDB / IPFS sync works across distinct
     DATA_DIRs for the same identity (same mnemonic).
  §B Long-running foreground `sphere daemon` listeners on peer2 — documents
     the exact --event / --action quick-mode flags and calls out the
     ./.sphere-cli/daemon.pid collision when two daemons share a CWD.
  §C Bidirectional invoice flow (11 UCT alice → bob → alice) with daemons
     running — asserts peer2 balances + invoice state reflect the §C
     payment WITHOUT a manual `sphere payments sync` (auto-receive did it).
  §D Wipe-and-recover BOTH profiles on BOTH peers from IPFS only — uses
     `sphere init --no-nostr --mnemonic` to install a no-op transport,
     proving the published CARs survived without faucet or live Nostr
     input.
  §E Recovery preserves the invoice ledger — `sphere invoice list
     --state COVERED` diffed pre/post wipe must be empty.

The new doc references manual-test-drain-fix.md §0 for CLI prerequisites
instead of duplicating them, and matches the existing doc's structure
(numbered sections, "what you're looking for" assertions, gotchas, command
cheat sheet).

Layout uses three CWDs (~/sphere-full-test/{peer1,peer2-alice,peer2-bob})
because `./.sphere-cli/{config.json,daemon.pid,daemon.log}` are
CWD-relative and not profile-scoped — running two daemons from one CWD
collides without explicit --pid/--log overrides.
…m live run

Add `manual-test-full-recovery.sh` — the automated re-run companion to
the walkthrough markdown landed in d2b4436. Mirrors every CLI command
from the doc so operators can re-validate end-to-end without retyping.
Creates a clean workspace, tears it down on EXIT (KEEP=1 to skip).

Three fixes landed during live testnet validation:

1. **Mnemonic extraction.** Original regex used `\b...\b` boundary
   matching for 24-word mnemonics, but: (a) the CLI default is now
   12-word, and (b) the SDK emits a deprecation warning whose text
   contains a 12-word lowercase span ("provider remains functional for
   backward compatibility but is no longer the recommended") that the
   `\b...\b` regex matched BEFORE the real mnemonic. Anchored to full
   lines (`^...$`) and added 12-word fallback. The real mnemonic
   always appears on a line by itself, so `^...$` is the correct
   discriminator.

2. **Nametag suffix length.** Default `epoch-pid` suffix (e.g.
   `1779456738-1932107`) pushed `alice-full-${SUFFIX}` past the 20-char
   Unicity ID limit, failing `sphere init --nametag` with "Invalid
   Unicity ID format". Trimmed to 8 chars (`alice-${SUFFIX}` = 14
   chars).

3. **Bob pre-pay sync.** Added explicit `payments sync` +
   `payments receive --finalize` for bob between §C.1 invoice mint
   and §C.2 invoice pay. The script's §B daemon path is currently
   unreliable on testnet (stale PID after `--detach`), so without
   explicit sync bob's local invoice ledger is empty when he tries
   to pay. (Even with the sync, bob doesn't currently auto-discover
   the invoice — that's a separate SDK invoice-discovery gap, see
   the @NameTag CLI nametag fix posted to sphere-cli for the other
   half of today's testnet validation.)

Known limitations (NOT addressed in this commit, separate work):
- §B daemon start: `sphere daemon start --detach` exits between
  PID-file write and the next check; manifests as "Daemon is not
  running (stale PID file)".
- §C.2 invoice pay: bob's local ledger doesn't see invoices
  targeting his address even after explicit sync. Likely needs
  either (a) per-invoice DM delivery, (b) cross-profile OrbitDB
  lookup, or (c) IPFS-pinned invoice-by-target index. Out of scope
  for this PR.

The script is still useful as-is: it validates everything up through
§C.1 invoice create (which DOES work end-to-end on live testnet) and
provides the harness for further iteration.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@vrogojin
Copy link
Copy Markdown
Contributor Author

Updated with live-testnet companion script + 3 fixes

Pushed commit 108e9ac adding manual-test-full-recovery.sh — the automated re-run companion that mirrors every CLI command from the walkthrough. Three fixes from live testnet validation:

  1. Mnemonic extraction: original \b...\b regex matched a 12-word lowercase span inside the SDK's deprecation-warning text before the real mnemonic. Anchored to full lines (^...$) and added 12-word fallback alongside the existing 24-word path.
  2. Nametag suffix length: default epoch-pid suffix pushed alice-full-${SUFFIX} past the 20-char Unicity ID limit. Trimmed to 8 chars.
  3. Bob pre-pay sync: added explicit payments sync + payments receive --finalize for bob between §C.1 invoice mint and §C.2 invoice pay.

What the script validates end-to-end on live testnet

Section Status
§0 Prereqs
§1 Peer1 setup (alice + bob init, faucet 7 coins, sync, balance)
§A.1 Peer2-alice (mnemonic recovery → sync → receive 7 coins)
§A.2 Peer2-bob (mnemonic recovery → sync → balance)
§C.1 Invoice create with @bob-... target ✓ (after the CLI nametag fix below)
§B Daemon start ❌ known gap
§C.2 Invoice pay ❌ known gap

The §A.1 cross-process recovery (peer2-alice receiving all 7 faucet coins from peer1-alice) exercises the same fetchCarFromIpfs block-walk path that #223 (PR #225, merged) fixed — successfully ingesting tokens via IPFS: +7 added on the receive side. This is independent live-testnet validation of #223 via the CLI surface.

Known gaps not addressed in this PR (separate work)

  • §B daemon startsphere daemon start --detach exits between PID-file write and the next check; manifests as "Daemon is not running (stale PID file)". Separate sphere-cli issue.
  • §C.2 invoice pay — bob's local ledger doesn't see invoices targeting his address even after explicit sync. Likely needs either (a) per-invoice DM delivery, (b) cross-profile OrbitDB lookup, or (c) IPFS-pinned invoice-by-target index. Separate SDK work.

Companion CLI fix

The §C.1 invoice nametag fix lives in sphere-cli: unicity-sphere/sphere-cli#17 (fix(invoice): accept @nametag as --target). That PR + this one together are what got §C.1 working on testnet.

vrogojin added 2 commits May 22, 2026 23:51
#226 landed on integration/all-fixes (commit 90a5cc3) and decouples
invoice creation from delivery — `sphere invoice create` no longer
auto-ships the invoice to its targets. The §C round-trip therefore
needs an explicit `sphere invoice deliver $INV` step between the mint
(§C.1) and Bob's pay (§C.2); without it Bob's wallet still has no
path to discover the invoice and `invoice pay` errors with "No invoice
found matching prefix: ...".

Changes:
 - manual-test-full-recovery.sh §C: new §C.1b that runs
   `sphere invoice deliver $INV` and logs the per-recipient outcome,
   plus an `sleep 5` in §C.2 to let Bob's relay subscription ingest
   the `invoice_delivery:` DM before the pay. Trimmed the obsolete
   commentary that called out the missing-discovery gap as known
   blocker — it's no longer blocked.
 - manual-test-full-recovery.md §C: companion narrative insertion of
   §C.1b describing the new explicit-delivery step and what the
   expected JSON outcome looks like.

Companion sphere-cli change adds the `sphere invoice deliver` command
(feat/invoice-deliver-226 branch in sphere-cli).
…ceed

Without this, Bob has 0 UCT and `sphere invoice pay $INV` errors with
"Insufficient balance" — even though §C.1b deliver (#226 SDK fix)
successfully puts the invoice in Bob's local ledger. The script's prior
limitation was that it only faucets Alice; symmetric faucet for Bob is
necessary for the §C round-trip to actually settle a payment.

Validated against live testnet 2026-05-23 (log /tmp/manual-cli-test-226-
v6.log): §C.1 mint + §C.1b deliver + §C.2 pay all complete with
Payment status='submitted' before the script hits the known §C.3/§C.4
daemon --detach limitations.
@vrogojin
Copy link
Copy Markdown
Contributor Author

Update — §C round-trip validated end-to-end against testnet (2026-05-23)

Two follow-up commits push the §C section past the prior "Bob can't discover invoice" + "Bob has no UCT" limitations:

Live testnet run (/tmp/manual-cli-test-226-v6.log):

Step Outcome
§C.1 — Alice mints invoice (0000422124..., 68-char imprint form) ✓ Invoice created
§C.1b — sphere invoice deliver → inline uxf-car DM { sent: 1, failed: 0, recipients: [{ success: true, shape: "inline" }] }
§C.2 — Bob pays ✓ Payment status: "submitted"

§C.3/§C.4 (peer2 daemon events) still hit the pre-existing --detach stale-PID limitation that this PR's original commit message already calls out — out of scope for this PR.

Dependencies that needed to land first:

@vrogojin vrogojin merged commit 52613c2 into integration/all-fixes May 23, 2026
@vrogojin vrogojin deleted the docs/issue-218-full-recovery-manual-test branch May 23, 2026 10:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant