rooms-kit / test / vectors / generate-orbit-address.mjs
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
/**
 * The one interop invariant this kit cannot get wrong: the OrbitDB address.
 *
 * PROTOCOL.md §5 — "every member independently computes the same address" — the
 * CID of the manifest {name, type, accessController}, a pure function of the
 * secret-derived dbName and the (hardened) IPFS access controller. Nothing is
 * exchanged to agree on it. If the port derived a different dbName, or the
 * hardened controller's manifest drifted from the vanilla one, the bot would
 * silently open a DIFFERENT database from every browser in the room: no error,
 * no missing message, just two disjoint histories.
 *
 * That address is not reachable from any pure function — it needs a real libp2p,
 * a real Helia and a real @orbitdb/core open (helia's `isLibp2p` check refuses a
 * stub). So this generator boots the v1.0.0 TypeScript build, materialised out of
 * git history, against an unroutable relay and records the addresses it produces.
 * `test/orbit-address.test.mjs` boots the ClojureScript dist the same way and
 * demands the same strings.
 *
 *   node test/vectors/generate-orbit-address.mjs [<git-ref-with-the-TS-dist>]
 *
 * Default ref is the last TypeScript commit. The TS dist is copied under
 * node_modules/ so its bare npm specifiers still resolve.
 *
 * IMPORT ORDER MATTERS: helia's module graph eagerly pulls
 * @ipshipyard/libp2p-auto-tls -> acme-client -> axios, and axios reads
 * `window.location.href` at module init. `installBrowserGlobals()` sets a
 * `window` with no `location`, so every module must be imported BEFORE the shims
 * are installed. Both builds hoist their own helia import above any join(), so
 * this only ever bites a harness like this one.
 */
import { execFileSync } from "node:child_process";
import { mkdirSync, mkdtempSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { dirname, join } from "node:path";
import { fileURLToPath, pathToFileURL } from "node:url";
import { addressCases, openAddressCase } from "../helpers/orbit-address.mjs";

const OUT = dirname(fileURLToPath(import.meta.url));
const ROOT = join(OUT, "..", "..");
const REF = process.argv[2] ?? "813d897";
const STAGE = join(ROOT, "node_modules", ".rooms-kit-ts-dist");

const TS_FILES = [
  "dist/lib/crypto.js", "dist/lib/encryption.js", "dist/lib/access.js", "dist/lib/log.js",
  "dist/lib/net.js", "dist/lib/turn.js", "dist/lib/orbit-identity.js", "dist/node/env.js",
  "dist/vendor/id/index.js", "dist/vendor/id/crypto.js", "dist/vendor/id/identity.js",
  "dist/vendor/id/profile.js",
];

for (const f of TS_FILES) {
  const bytes = execFileSync("git", ["-C", ROOT, "show", `${REF}:${f}`]);
  const target = join(STAGE, f);
  mkdirSync(dirname(target), { recursive: true });
  writeFileSync(target, bytes);
}
console.log(`materialised the v1.0.0 TypeScript dist from ${REF}`);

const load = (rel) => import(pathToFileURL(join(STAGE, rel)).href);
const mods = {
  crypto: await load("dist/lib/crypto.js"),
  log: await load("dist/lib/log.js"),
  net: await load("dist/lib/net.js"),
  turn: await load("dist/lib/turn.js"),
  env: await load("dist/node/env.js"),
  id: await load("dist/vendor/id/index.js"),
};

const out = [];
for (const c of addressCases) {
  const dir = mkdtempSync(join(tmpdir(), "rooms-addr-"));
  out.push(await openAddressCase(mods, c, dir));
  console.log(`${c.appSalt} identity=${c.withIdentity}: ${out.at(-1).address}`);
}

writeFileSync(join(OUT, "orbit-address.json"), `${JSON.stringify(out, null, 2)}\n`);
console.log("wrote orbit-address.json");
process.exit(0);

static mirror of HEAD · about · clone: git clone https://git.ardegazu.ro/rooms-kit.git