Skip to content

feat: test a member's relay from outside when the host asks (K2) - #622

Merged
TheCryptoDonkey merged 3 commits into
mainfrom
feat/relay-outside-test
Oct 29, 2026
Merged

TheCryptoDonkey merged 3 commits into
mainfrom
feat/relay-outside-test

Conversation

@TheCryptoDonkey

Copy link
Copy Markdown
Member

Stage K2 of the built-in relay: a host asks one member device to test its relay from outside its network, and gets an encrypted pass or fail back. No UI: the host button is K5.

  • Two new SignalBody types on the existing pairwise signal wrap (NIP-44 to one device, device-signed, NIP-40 expiration 60 s): relay-test {id, endpoint} and relay-test-result {id, endpoint, ok, stage?, sameNetwork?: true}. Closed shapes; no address, credential or name in either. No new kind or storage key.
  • Admitted from roster devices only, with a separate budget of 8 per sender per 20 s.
  • Tester: silent unless the sender is the one publisher of that endpoint and the tester holds its standard offer; answers declined when busy, within 60 s of the last test for that device, or when Hide my IP forbids that host (no dialog); redeems a login on demand that is never applied to its calls; runs a relay-only peer against a STUN-only peer with a data-channel echo, and checks the selected pairs' stats.
  • Stages declined, credentials, allocate, stun, inbound; sameNetwork when the tester's addresses include the relay's IP. The host may say reachable only for ok without sameNetwork.
  • src/relay-test.ts, app/src/relay-outside-test.ts, docs/protocol.md section, vectors/relay-outside-test-v1.json (12 requests, 22 results, 17 verdicts, 9 wraps).
  • e2e test/relay-outside-test.spec.ts (npm run test:relay-outside-test, not in CI, like K1's): on one machine spry-turn refuses peers on its own IP in mapped mode, so it asserts ok:false, stage:'inbound', sameNetwork:true. A real pass needs the separate-network tests in design section 6.2; the pass path is unit-tested with a fake peer connection. Host trigger exists only in builds with VITE_E2E_RELAY_OUTSIDE_TEST=true.

Tests (M4): typecheck; npm test 8549 passed; new e2e 1/1; K1 e2e 3/3.

https://claude.ai/code/session_01P4tkjt9pRAySng1JJnHn9t

A host sharing a built-in call relay can ask one room device to test it
from outside. Two new SignalBody types ride the existing kind 21059/20462
envelope: relay-test (id, endpoint) from the host and relay-test-result
(id, endpoint, ok, stage, sameNetwork) back to the host alone. Both bodies
are closed and carry no address, credential, name or time. The mesh admits
them from roster devices without a media connection, on a budget of their
own. relayTestVerdict and relayTestFinding fix how a tester judges what its
two peers saw and what a host may call reachable; a pass from the host's
own network is a hint only.

Pinned by vectors/relay-outside-test-v1.json, assembled by hand.
The tester's app answers only the member who offers that built-in relay in
the room, and only for a standard offer it holds. It declines while a test
runs, within a minute of the last one for that host, or while Hide my IP
address forbids that host's relay; otherwise it takes a relay login that is
never applied to its calls, runs peer A relay-only on the relay and peer B
with the relay's listener as its only STUN server, and sends the verdict to
the host's device alone.

No screen offers the host's trigger yet; the built-in relay's own settings
add it. Acceptance builds expose it as a hook for the new loopback spec,
which reuses the supervised spry-node fixture.
A relay with mapped ports refuses peers on its own addresses other than its
allocations, so a tester whose host candidate is the relay's address never
passes and learns no outside address. It was reported as a STUN failure;
it is now inbound with sameNetwork, a hint rather than a finding. The
loopback acceptance spec asserts that outcome, which is the honest one on a
single machine.
@TheCryptoDonkey
TheCryptoDonkey merged commit 2e159e4 into main Oct 29, 2026
48 checks passed
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