Merges a parallel session's work with the multi-source BNS story from 0.0.7.
The dApp side (parallel session)
--------------------------------
* bcnr-preload.js — installs `window.bcnr` on every page via contextBridge.
Read-only surface: resolveName(name), isRegistered(name), getBcnrTlds(),
getRecordVersion(name), plus getPermissionOrigin() for diagnostics. All
Promises; a missing name returns null (not throw). No signing, no wallet
unlock — that surface is designed but deliberately out of scope for 0.0.8
(see TheseusNavigator/DESIGN-integrated-wallet.md).
* bcnr-origin.js — pure function that computes the eTLD+1 permission origin
for a URL. ICANN suffixes via `psl` (same PSL Chromium uses, handles
.co.uk / .github.io / etc); BNS names key off the on-chain TLD list so
foo.wallet becomes a public suffix as soon as `wallet` appears there.
Match browser cookie / MetaMask semantics: a grant on pay.merchant.com
covers account.merchant.com but not evil.com.
* dev/bcnr-selftest.js, dev/origin-selftest.mjs — self-tests, no I/O.
* main.js wires bcnr-preload.js into session.defaultSession.setPreloads() so
it runs BEFORE per-WebContentsView preloads; adds bcnr:* IPC handlers.
* preload.js + chrome.html — small hooks so the shell picks up window.bcnr
the same way regular content does.
* package.json — psl dep, bcnr-preload.js/bcnr-origin.js in `files`.
Also included
-------------
* AriadneResolver/mobile/.../UpdateCheck.java — in-app update-check for the
Android app; already active in the shipped 0.11 APK (build.ps1 -Recurse
picked it up), formalising the source now.
* TheseusNavigator/snapshots/bns-name-snapshot.json — refreshed bundled
starter (73 beacon txs, root c37b8596…c54e414ba).
* Site pages + manifest updated to point at 0.0.8.
TheseusNavigator-Setup-0.0.8.exe 95.4 MB
21939743eafdfe8742a6b7c4b987bd2782384d7bc41289cb80a7e08019dc9f02
TheseusNavigator-0.0.8-portable.exe 92.7 MB
2aa429fe39dc0fa4ac040fc6d6eb31b0f890c8a83175c49fcb50f052c480d39d
68 lines
3.8 KiB
JavaScript
68 lines
3.8 KiB
JavaScript
// bcnr-selftest.js — end-to-end proof that `window.bcnr` from
|
|
// bcnr-preload.js reaches the main-process handlers over IPC and returns
|
|
// what the resolver sees. Mirrors dev/selftest.js style: sets
|
|
// THESEUS_NO_AUTOSTART=1, imports main.js, then wires the minimum bits
|
|
// (session preload + resolver warm-up) itself so the harness stays fast
|
|
// and hermetic.
|
|
//
|
|
// Usage: npx electron dev/bcnr-selftest.js <name>
|
|
// ^ optional; defaults to silentmode.bch
|
|
process.env.THESEUS_NO_AUTOSTART = "1";
|
|
const path = require("path");
|
|
const { app, BrowserWindow, session } = require("electron");
|
|
// main.js exports resolveHost etc. for tests; importing it also registers
|
|
// the ipcMain.handle("bcnr:...") handlers at module load.
|
|
require("../main.js");
|
|
|
|
app.disableHardwareAcceleration();
|
|
app.commandLine.appendSwitch("disable-gpu");
|
|
app.commandLine.appendSwitch("no-sandbox");
|
|
|
|
const name = (process.argv[2] || "silentmode.bch").toLowerCase();
|
|
const watchdog = setTimeout(() => { console.log("WATCHDOG"); try { app.exit(3); } catch {} }, 60000);
|
|
|
|
app.whenReady().then(async () => {
|
|
// Install the same session-wide preload the shipped app installs.
|
|
session.defaultSession.setPreloads([path.join(__dirname, "..", "bcnr-preload.js")]);
|
|
|
|
// No explicit warm-up: the first resolveName() call flows into
|
|
// resolveHost() which lazily runs ensureIndex() itself. Cold start can
|
|
// take a while (electrum handshake + full walk); the watchdog covers it.
|
|
const win = new BrowserWindow({ width: 800, height: 600, show: false, webPreferences: { offscreen: true } });
|
|
const wc = win.webContents;
|
|
await wc.loadURL("about:blank");
|
|
|
|
const report = { name };
|
|
try {
|
|
report.hasBridge = await wc.executeJavaScript("typeof window.bcnr === 'object'");
|
|
report.methods = await wc.executeJavaScript("Object.keys(window.bcnr || {}).sort()");
|
|
report.getBcnrTlds = await wc.executeJavaScript("window.bcnr.getBcnrTlds()");
|
|
report.isRegistered = await wc.executeJavaScript(`window.bcnr.isRegistered(${JSON.stringify(name)})`);
|
|
report.getRecordVersion = await wc.executeJavaScript(`window.bcnr.getRecordVersion(${JSON.stringify(name)})`);
|
|
report.resolveName = await wc.executeJavaScript(`window.bcnr.resolveName(${JSON.stringify(name)})`);
|
|
// B.2b — the caller's eTLD+1 origin as Theseus sees it. From about:blank
|
|
// this must be "about:blank"; a data: URL would be null; a real dApp
|
|
// page would be its registrable domain. Full origin logic is unit-tested
|
|
// in dev/origin-selftest.mjs; this proves the IPC wiring uses it.
|
|
report.origin_aboutBlank = await wc.executeJavaScript("window.bcnr.getOrigin()");
|
|
} catch (e) { report.error = e.message; }
|
|
|
|
console.log("\n===== BCNR SELFTEST =====");
|
|
console.log(JSON.stringify(report, null, 2));
|
|
|
|
// Verdict: bridge present, four methods, TLD list non-empty, and either
|
|
// the name resolved OR it plausibly doesn't exist (isRegistered === false
|
|
// + resolveName === null is a valid pass — resolver worked, name just
|
|
// isn't on chain).
|
|
const bridgeOk = report.hasBridge === true
|
|
&& Array.isArray(report.methods)
|
|
&& ["getBcnrTlds", "getOrigin", "getRecordVersion", "isRegistered", "resolveName"].every((m) => report.methods.includes(m));
|
|
const tldsOk = Array.isArray(report.getBcnrTlds) && report.getBcnrTlds.length > 0;
|
|
const shapeOk = (report.isRegistered === true && report.resolveName && report.resolveName.name === name)
|
|
|| (report.isRegistered === false && report.resolveName === null);
|
|
const originOk = report.origin_aboutBlank === "about:blank";
|
|
report.verdict = bridgeOk && tldsOk && shapeOk && originOk ? "PASS" : "FAIL";
|
|
console.log("verdict:", report.verdict);
|
|
clearTimeout(watchdog);
|
|
try { app.exit(report.verdict === "PASS" ? 0 : 1); } catch {}
|
|
});
|