1import { describe, expect, it, vi } from "vitest";2import { generateKeyPairFromSeed } from "@stablelib/x25519";34import {5 DEFAULT_RELAY_URL,6 buildRendezvousUrl,7 bytesToHex,8 deriveMeshRendezvousSecret,9 deriveRendezvousId,10 deriveRendezvousSecret,11 dialingRendezvousIds,12 generatePairingRendezvousToken,13 normalizeRelayUrl,14 rendezvousSecretFromHex,15 rendezvousWindowIndex,16 waitingRendezvousIds,17} from "./rendezvous";1819const HANDSHAKE_HASH = rendezvousSecretFromHex(20 "0fbab8cd1782bf4b17d69beb69f5b80b0bf24d93da4924959c76ee701c32e655",21);2223describe("relay rendezvous contract", () => {24 it("derives the symmetric cross-client mesh capability vector", () => {25 const alice = generateKeyPairFromSeed(new Uint8Array(32).fill(1));26 const bob = generateKeyPairFromSeed(new Uint8Array(32).fill(2));27 const forward = deriveMeshRendezvousSecret(alice.secretKey, alice.publicKey, bob.publicKey);28 const reverse = deriveMeshRendezvousSecret(bob.secretKey, bob.publicKey, alice.publicKey);29 expect(reverse).toEqual(forward);30 });3132 it("derives the cross-platform secret and hourly id KATs", () => {33 const secret = deriveRendezvousSecret(HANDSHAKE_HASH);34 expect(bytesToHex(secret)).toBe(35 "0803691c8ac7330883c0987e33cea4a171992366ce4b06b88691e84ca689773d",36 );37 expect(deriveRendezvousId(secret, 500_000)).toBe(38 "9UY3j5AHnwYSApvymtY965su9n60rQOv8QZ2PZzHuKI",39 );40 });4142 it("uses one-hour windows with mandatory skew tolerance order", () => {43 const secret = deriveRendezvousSecret(HANDSHAKE_HASH);44 const now = 500_000 * 3600 + 3599;45 expect(rendezvousWindowIndex(now)).toBe(500_000);46 expect(waitingRendezvousIds(secret, now)).toEqual([47 deriveRendezvousId(secret, 500_000),48 deriveRendezvousId(secret, 499_999),49 ]);50 expect(dialingRendezvousIds(secret, now)).toEqual([51 deriveRendezvousId(secret, 500_000),52 deriveRendezvousId(secret, 499_999),53 deriveRendezvousId(secret, 500_001),54 ]);55 });5657 it("generates a fresh 128-bit base64url first-pair token", () => {58 vi.spyOn(crypto, "getRandomValues").mockImplementation((array) => {59 (array as Uint8Array).set(Array.from({ length: 16 }, (_, i) => i));60 return array;61 });62 expect(generatePairingRendezvousToken()).toBe("AAECAwQFBgcICQoLDA0ODw");63 });6465 it("accepts only credential-free wss relay URLs", () => {66 expect(normalizeRelayUrl(`${DEFAULT_RELAY_URL}/`)).toBe(DEFAULT_RELAY_URL);67 expect(normalizeRelayUrl("wss://relay.example.test/base/")).toBe(68 "wss://relay.example.test/base",69 );70 expect(() => normalizeRelayUrl("ws://relay.example.test")).toThrow(/wss/);71 expect(() => normalizeRelayUrl("wss://user:[email protected]")).toThrow();72 expect(() => normalizeRelayUrl("wss://relay.example.test?token=x")).toThrow();73 });7475 it("builds the relay path without exposing identity", () => {76 const id = "AAECAwQFBgcICQoLDA0ODw";77 expect(buildRendezvousUrl(DEFAULT_RELAY_URL, id)).toBe(78 `${DEFAULT_RELAY_URL}/r/${id}`,79 );80 expect(() => buildRendezvousUrl(DEFAULT_RELAY_URL, "short")).toThrow();81 });82});