argus/setup/install.ps1

438 lines
25 KiB
PowerShell
Raw Normal View History

# BNS resolver daemon installer -- run from an ELEVATED PowerShell.
# .\setup\install.ps1 # surgical: NRPT rule routes only .bch to the daemon
# .\setup\install.ps1 -Mode full # universal: adapter DNS -> 127.0.0.1, daemon forwards the rest
param(
[ValidateSet("nrpt", "full")] [string]$Mode = "nrpt",
[string]$Upstream = "1.1.1.1",
Ariadne c5efae43: tlds.bch-driven install + BNS_POLICY, doc-aligned Three doc-alignment changes shipping in AriadneResolver-Setup-0.1.0.exe sha256 c5efae43af6cc163f468f1dc73d08939db32a9a6db52298ba18b2d9a2aee1292: 1. install.ps1 fetches the activated TLD list from the on-chain root TLD certificate (tlds.bch, per START-HERE §1) via resolver-web.js fetchBcnrTlds(), then: - regenerates the CA's nameConstraints extension from that list (rotates the CA when the on-chain set changes so leaves for the newly-activated TLDs actually validate) - adds one NRPT rule per activated TLD in surgical mode - falls back to bootstrap ["bch"] if the chain is unreachable Result: adding a TLD on-chain is picked up by re-running the installer, no code release needed. 2. bnsd.js honors --policy / BNS_POLICY (bcnr-first | icann-first, alias bns-first) per START-HERE §4b. bcnr-first is default and preserves prior behavior. icann-first forwards to upstream first and only substitutes a BCNR answer on NXDOMAIN. install.ps1 accepts -Policy and passes it into the scheduled task action. 3. ca.js loadOrCreateRootCA() now accepts a runtime TLD list; the old callers still work (fall back to PERMITTED_TLDS from tlds.js). Doc: RESOLVER-PACKAGING-PROMPT.md rewritten to reflect current shipping reality; original 2026-07-26 packaging brief preserved in the "Archival" section. Deployed to dl.silentmode.st (nginx serves from /opt/silent-mode/dl/) and mirrored to Sia bns/silentmode/. VPS bns-indexer.service reports tlds.bch currently activates: bch p2p deviant nav sia dgb nt sm lm.
2026-08-01 02:06:48 +02:00
# Collision policy the daemon should run under (docs: START-HERE.md 4b).
# bcnr-first (default): BCNR wins, ICANN fallback on miss.
# icann-first : ICANN wins, BCNR fallback on NXDOMAIN.
# bns-first is accepted as an alias for bcnr-first.
[ValidateSet("bcnr-first", "icann-first", "bns-first")] [string]$Policy = "bcnr-first",
Ariadne 0.1.2: install.ps1 no longer dies on PS 5.1 stderr quirk; layered TLD-source cascade install.ps1 root-cause fix - Every `& $node ... 2>&1` had been tripping PS 5.1's "$ErrorActionPreference=Stop + native-command stderr = terminating error" quirk. Trap-and-log added in 0.1.1 EXPOSED the bug (0.1.0 died at the exact same line -- silently). 0.1.2 routes both node calls through a new Invoke-NodeCapture helper that uses Start-Process -RedirectStandardOutput/Error to file, so PS 5.1 never touches the streams. Multi-source TLD cascade with on-disk cache - -Indexer now accepts a comma-separated list; default "https://navigate.st,https://silentmode.st". - Cascade (first hit wins): indexer[s] HTTPS -> local cache (C:\ProgramData\Ariadne\tlds-cache.json) -> electrum WSS (fetchTldList / legacy fetchBcnrTlds) -> bundled ariadne.config.json snapshot -> bootstrap [bch]. - Authoritative fetches (indexer or electrum) refresh the cache. Second install on a machine that has ever succeeded before is instant + always works offline. - Per-source deadlines kept tight (5s for indexer HTTPS) so a slow source can't stall the install. Upgrade over live install - .iss CurStepChanged(ssInstall) stops "BNS Resolver Daemon" + "BNS Sia Bridge" via schtasks + 1.5s pause before file replacement. Fixes "DeleteFile failed; code 5. Access is denied" on runtime\node.exe when upgrading a machine where the daemon is currently running. CA import - Switched Import-Certificate -CertStoreLocation Cert:\... to direct X509Store('Root', 'LocalMachine').Add(). Cert: PSDrive is not always loaded in -NoProfile elevated shells, which had broken the standalone unblock scripts. Verified end-to-end on this box: silent install -> exit 0, clean install.log, BNS Resolver Daemon running, 127.0.0.1:53 open, 9 NRPT rules (all TLDs including .bch), coinspectrum.bch resolves system-wide, tlds-cache.json populated. Deployed - dl.silentmode.st/AriadneResolver-Setup-0.1.2.exe - s3://bns/silentmode/dl/AriadneResolver-Setup-0.1.2.exe - silentmode.st + navigate.st/bns/silentmode.bch manifests advertise 0.1.2 - sha256 5a2c9e4f3c5e1a162008641019f5ffc35968751c0440f94d3c5fe67aafb8cc5e Local Dev <noreply@localhost>
2026-09-09 22:57:06 +02:00
# BNS indexer(s) for the primary TLD discovery source. Comma-separated list
# so we can fall over between mirrors -- HTTPS beats WSS-electrum from a
# silent-install context (no Node subprocess, no ws dependency, DPI-friendly).
# The first indexer that answers within its per-source deadline wins.
[string]$Indexer = "https://navigate.st,https://silentmode.st",
# Opt-in: turn off Firefox DNS-over-HTTPS. Only needed to resolve names that
# ALSO exist in ICANN (a reclaimed .de) via BCNR in Firefox -- BCNR-only names
# (all .bch, etc.) already work with DoH on, because DoH returns NXDOMAIN and
# Firefox falls back to the local resolver. Trade-off: Firefox's other DNS then
# goes through the system resolver instead of encrypted to Cloudflare.
[switch]$FirefoxNoDoH,
# Opt-in: force-close a running Firefox so it reloads the new root CA + policy
# immediately (Firefox only reads them at startup). Off by default because it
# discards the user's open tabs/unsaved data.
[switch]$CloseFirefox
)
$ErrorActionPreference = "Stop"
Ariadne 0.1.1 + Theseus fetches it from silentmode.st (no more bundling) Ariadne 0.1.1 - install.ps1 primary TLD source: HTTPS $Indexer/api/tlds -> advertised[] (electrum fetchTldList / legacy fetchBcnrTlds / ariadne.config.json / bootstrap kept as fallbacks in that order). Silent installs no longer stall when WSS is blocked. - Persistent transcript at C:\ProgramData\Ariadne\install.log; separate install-error.log on any uncaught exception. Top-level trap logs the full stack, then exit 1 so Inno/NSIS silent-install callers see a real failure. - .iss: SetupLogging=yes; DeinitializeSetup() copies Inno's log to C:\ProgramData\Ariadne\inno-setup.log on every exit path. - Version bumped to 0.1.1. sha256=be1fa8841919b321841d90f8147abe1b1d7604fe7fff6c2e271dc47c4c24a2b6 Theseus decoupled from Ariadne - Removed nsis/installer.nsh (custom Ariadne chain-install page). - Removed extraResources entry for AriadneResolver-Setup-*.exe. - Removed build.nsis.include from package.json. - Settings > System-wide resolver panel now fetches the .exe from https://silentmode.st/releases-manifest.json, streams the download while hashing, refuses to spawn on SHA-256 mismatch. 30-min in-memory manifest cache so opening Settings doesn't spam the endpoint. Offline gracefully degrades to installedVersion-only / canUpdate:false. - "bundledVersion" IPC field kept for renderer compatibility; it now carries "latest advertised by the site's manifest". Deployed to silentmode.st: - dl.silentmode.st/AriadneResolver-Setup-0.1.1.exe (25 MB) - silentmode.st/releases-manifest.json (schema/2, updated 2026-09-08) - silentmode.st/releases/ + silentmode.st/tools/ show 0.1.1 Local Dev <noreply@localhost>
2026-09-08 01:27:51 +02:00
# ---- persistent install log --------------------------------------------------
# Silent-install callers (Theseus's NSIS chain-install, `.exe /VERYSILENT`, Inno
# `runhidden`) discard our stdout/stderr, so historically any failure between
# "files copied" and "scheduled task registered" was invisible. This appends a
# timestamped transcript to a well-known path so a broken install always leaves
# forensics behind. Errors starting the transcript are non-fatal: an unloggable
# install must still complete or fail visibly.
$LogDir = Join-Path $env:ProgramData 'Ariadne'
try { New-Item -ItemType Directory -Force -Path $LogDir | Out-Null } catch {}
$LogFile = Join-Path $LogDir 'install.log'
$ErrFile = Join-Path $LogDir 'install-error.log'
Ariadne 0.1.7: system-wide collision policy is runtime-switchable Feature. The daemon now hot-reloads C:\ProgramData\Ariadne\policy.json every 5 s (fs.stat mtime check, only opens the file when it actually changed) and flips its DNS collision policy between bcnr-first and icann-first in place. Every browser on the machine follows within seconds -- no daemon restart, no reinstall, no UAC. The next Ariadne panel in Theseus will edit this file directly; a text editor works too. install.ps1 seeds the file with the current -Policy default on FIRST install only (an upgrade never clobbers a user's later flip) and grants BUILTIN\Users Modify on it so an unprivileged app can rewrite it. Invalid values keep the last good policy (logged). File deleted -> daemon falls back to the CLI policy the scheduled task was registered with. Also fixes an intermittent "config unreadable" on daemon startup when ariadne.config.json had a UTF-8 BOM -- same class of PS-writes-BOM bug 0.1.6 fixed in the TLD-sync path, this time in bnsd.js's own config loader. Verified live on this box with a second daemon running on port 15353: bnsd policy: bcnr-first -> icann-first (from C:\ProgramData\Ariadne\policy.json) bnsd policy: icann-first -> bcnr-first (from C:\ProgramData\Ariadne\policy.json) bnsd policy: ... has invalid policy 'cash-first' -- keeping bcnr-first ACL check: BUILTIN\Users has Modify on policy.json, non-elevated write succeeds. Deployed - dl.silentmode.st/AriadneResolver-Setup-0.1.7.exe - s3://bns/silentmode/dl/AriadneResolver-Setup-0.1.7.exe - silentmode.st manifest advertises 0.1.7 - sha256 742f8005c2dfb47929287c009cddf7738f0d12bd56fb8f8a837df3e9b435f47f Theseus UI wiring for this file NOT touched -- settings-preload.js has 31 lines of uncommitted work from another session; a Theseus panel selector belongs in that session's next commit so it doesn't collide.
2026-09-28 01:18:47 +02:00
# Collision-policy override, hot-reloaded by the daemon and edited from the
# Ariadne's Thread panel in Theseus. Seed with the -Policy install-time choice
# ONLY on first install so an upgrade doesn't clobber a user's later flip;
# grant BUILTIN\Users Modify so Theseus can rewrite it without a UAC prompt.
$PolicyFile = Join-Path $LogDir 'policy.json'
if (-not (Test-Path $PolicyFile)) {
$seed = if ($Policy -eq 'bns-first') { 'bcnr-first' } else { $Policy }
ConvertTo-Json @{ policy = $seed } | Set-Content -Path $PolicyFile -Encoding utf8
}
try {
$acl = Get-Acl $PolicyFile
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule(
[System.Security.Principal.SecurityIdentifier]::new('S-1-5-32-545'), # BUILTIN\Users
'Modify','Allow')
$acl.SetAccessRule($rule)
Set-Acl -Path $PolicyFile -AclObject $acl
} catch {}
Ariadne 0.1.1 + Theseus fetches it from silentmode.st (no more bundling) Ariadne 0.1.1 - install.ps1 primary TLD source: HTTPS $Indexer/api/tlds -> advertised[] (electrum fetchTldList / legacy fetchBcnrTlds / ariadne.config.json / bootstrap kept as fallbacks in that order). Silent installs no longer stall when WSS is blocked. - Persistent transcript at C:\ProgramData\Ariadne\install.log; separate install-error.log on any uncaught exception. Top-level trap logs the full stack, then exit 1 so Inno/NSIS silent-install callers see a real failure. - .iss: SetupLogging=yes; DeinitializeSetup() copies Inno's log to C:\ProgramData\Ariadne\inno-setup.log on every exit path. - Version bumped to 0.1.1. sha256=be1fa8841919b321841d90f8147abe1b1d7604fe7fff6c2e271dc47c4c24a2b6 Theseus decoupled from Ariadne - Removed nsis/installer.nsh (custom Ariadne chain-install page). - Removed extraResources entry for AriadneResolver-Setup-*.exe. - Removed build.nsis.include from package.json. - Settings > System-wide resolver panel now fetches the .exe from https://silentmode.st/releases-manifest.json, streams the download while hashing, refuses to spawn on SHA-256 mismatch. 30-min in-memory manifest cache so opening Settings doesn't spam the endpoint. Offline gracefully degrades to installedVersion-only / canUpdate:false. - "bundledVersion" IPC field kept for renderer compatibility; it now carries "latest advertised by the site's manifest". Deployed to silentmode.st: - dl.silentmode.st/AriadneResolver-Setup-0.1.1.exe (25 MB) - silentmode.st/releases-manifest.json (schema/2, updated 2026-09-08) - silentmode.st/releases/ + silentmode.st/tools/ show 0.1.1 Local Dev <noreply@localhost>
2026-09-08 01:27:51 +02:00
try { Start-Transcript -Path $LogFile -Append -Force -IncludeInvocationHeader | Out-Null } catch {}
Write-Host ""
Write-Host ("==== install.ps1 " + (Get-Date -Format 's') + " Mode=$Mode Policy=$Policy Indexer=$Indexer ====")
# Script-scope trap: any uncaught exception is written to install-error.log
# (separate file so a post-mortem doesn't have to grep through the whole
# transcript), the transcript is closed cleanly, then the exception is
# re-thrown so the caller (Inno's [Run], NSIS's ExecWait, or the user's PS)
# still sees a non-zero exit code and can act on it.
trap {
try {
$stamp = Get-Date -Format 's'
$msg = "[FATAL $stamp] $($_ | Out-String)`nScriptStack:`n$($_.ScriptStackTrace)`n"
Add-Content -Path $ErrFile -Value $msg -ErrorAction SilentlyContinue
Write-Host $msg -ForegroundColor Red
} catch {}
try { Stop-Transcript | Out-Null } catch {}
exit 1
}
if (-not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()
).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
Ariadne 0.1.1 + Theseus fetches it from silentmode.st (no more bundling) Ariadne 0.1.1 - install.ps1 primary TLD source: HTTPS $Indexer/api/tlds -> advertised[] (electrum fetchTldList / legacy fetchBcnrTlds / ariadne.config.json / bootstrap kept as fallbacks in that order). Silent installs no longer stall when WSS is blocked. - Persistent transcript at C:\ProgramData\Ariadne\install.log; separate install-error.log on any uncaught exception. Top-level trap logs the full stack, then exit 1 so Inno/NSIS silent-install callers see a real failure. - .iss: SetupLogging=yes; DeinitializeSetup() copies Inno's log to C:\ProgramData\Ariadne\inno-setup.log on every exit path. - Version bumped to 0.1.1. sha256=be1fa8841919b321841d90f8147abe1b1d7604fe7fff6c2e271dc47c4c24a2b6 Theseus decoupled from Ariadne - Removed nsis/installer.nsh (custom Ariadne chain-install page). - Removed extraResources entry for AriadneResolver-Setup-*.exe. - Removed build.nsis.include from package.json. - Settings > System-wide resolver panel now fetches the .exe from https://silentmode.st/releases-manifest.json, streams the download while hashing, refuses to spawn on SHA-256 mismatch. 30-min in-memory manifest cache so opening Settings doesn't spam the endpoint. Offline gracefully degrades to installedVersion-only / canUpdate:false. - "bundledVersion" IPC field kept for renderer compatibility; it now carries "latest advertised by the site's manifest". Deployed to silentmode.st: - dl.silentmode.st/AriadneResolver-Setup-0.1.1.exe (25 MB) - silentmode.st/releases-manifest.json (schema/2, updated 2026-09-08) - silentmode.st/releases/ + silentmode.st/tools/ show 0.1.1 Local Dev <noreply@localhost>
2026-09-08 01:27:51 +02:00
try { Stop-Transcript | Out-Null } catch {}
throw "Run this from an elevated (Administrator) PowerShell."
}
$root = Split-Path -Parent $PSScriptRoot
# Prefer a bundled Node runtime (distributable installer ships runtime\node.exe);
# fall back to a Node on PATH for running straight from the dev repo.
$node = Join-Path $root "runtime\node.exe"
if (-not (Test-Path $node)) {
$onPath = Get-Command node -ErrorAction SilentlyContinue
if (-not $onPath) { throw "No Node runtime found: expected runtime\node.exe (bundle) or node on PATH (dev repo)." }
$node = $onPath.Source
}
$daemon = Join-Path $root "src\daemon\bnsd.js"
$stateFile = Join-Path $PSScriptRoot "install-state.json"
Ariadne 0.1.2: install.ps1 no longer dies on PS 5.1 stderr quirk; layered TLD-source cascade install.ps1 root-cause fix - Every `& $node ... 2>&1` had been tripping PS 5.1's "$ErrorActionPreference=Stop + native-command stderr = terminating error" quirk. Trap-and-log added in 0.1.1 EXPOSED the bug (0.1.0 died at the exact same line -- silently). 0.1.2 routes both node calls through a new Invoke-NodeCapture helper that uses Start-Process -RedirectStandardOutput/Error to file, so PS 5.1 never touches the streams. Multi-source TLD cascade with on-disk cache - -Indexer now accepts a comma-separated list; default "https://navigate.st,https://silentmode.st". - Cascade (first hit wins): indexer[s] HTTPS -> local cache (C:\ProgramData\Ariadne\tlds-cache.json) -> electrum WSS (fetchTldList / legacy fetchBcnrTlds) -> bundled ariadne.config.json snapshot -> bootstrap [bch]. - Authoritative fetches (indexer or electrum) refresh the cache. Second install on a machine that has ever succeeded before is instant + always works offline. - Per-source deadlines kept tight (5s for indexer HTTPS) so a slow source can't stall the install. Upgrade over live install - .iss CurStepChanged(ssInstall) stops "BNS Resolver Daemon" + "BNS Sia Bridge" via schtasks + 1.5s pause before file replacement. Fixes "DeleteFile failed; code 5. Access is denied" on runtime\node.exe when upgrading a machine where the daemon is currently running. CA import - Switched Import-Certificate -CertStoreLocation Cert:\... to direct X509Store('Root', 'LocalMachine').Add(). Cert: PSDrive is not always loaded in -NoProfile elevated shells, which had broken the standalone unblock scripts. Verified end-to-end on this box: silent install -> exit 0, clean install.log, BNS Resolver Daemon running, 127.0.0.1:53 open, 9 NRPT rules (all TLDs including .bch), coinspectrum.bch resolves system-wide, tlds-cache.json populated. Deployed - dl.silentmode.st/AriadneResolver-Setup-0.1.2.exe - s3://bns/silentmode/dl/AriadneResolver-Setup-0.1.2.exe - silentmode.st + navigate.st/bns/silentmode.bch manifests advertise 0.1.2 - sha256 5a2c9e4f3c5e1a162008641019f5ffc35968751c0440f94d3c5fe67aafb8cc5e Local Dev <noreply@localhost>
2026-09-09 22:57:06 +02:00
# TLS 1.2 (PS 5.1 defaults to 1.0/1.1 on older boxes and Invoke-RestMethod fails
# against modern servers).
try { [Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12 } catch {}
Ariadne 0.1.1 + Theseus fetches it from silentmode.st (no more bundling) Ariadne 0.1.1 - install.ps1 primary TLD source: HTTPS $Indexer/api/tlds -> advertised[] (electrum fetchTldList / legacy fetchBcnrTlds / ariadne.config.json / bootstrap kept as fallbacks in that order). Silent installs no longer stall when WSS is blocked. - Persistent transcript at C:\ProgramData\Ariadne\install.log; separate install-error.log on any uncaught exception. Top-level trap logs the full stack, then exit 1 so Inno/NSIS silent-install callers see a real failure. - .iss: SetupLogging=yes; DeinitializeSetup() copies Inno's log to C:\ProgramData\Ariadne\inno-setup.log on every exit path. - Version bumped to 0.1.1. sha256=be1fa8841919b321841d90f8147abe1b1d7604fe7fff6c2e271dc47c4c24a2b6 Theseus decoupled from Ariadne - Removed nsis/installer.nsh (custom Ariadne chain-install page). - Removed extraResources entry for AriadneResolver-Setup-*.exe. - Removed build.nsis.include from package.json. - Settings > System-wide resolver panel now fetches the .exe from https://silentmode.st/releases-manifest.json, streams the download while hashing, refuses to spawn on SHA-256 mismatch. 30-min in-memory manifest cache so opening Settings doesn't spam the endpoint. Offline gracefully degrades to installedVersion-only / canUpdate:false. - "bundledVersion" IPC field kept for renderer compatibility; it now carries "latest advertised by the site's manifest". Deployed to silentmode.st: - dl.silentmode.st/AriadneResolver-Setup-0.1.1.exe (25 MB) - silentmode.st/releases-manifest.json (schema/2, updated 2026-09-08) - silentmode.st/releases/ + silentmode.st/tools/ show 0.1.1 Local Dev <noreply@localhost>
2026-09-08 01:27:51 +02:00
Ariadne 0.1.2: install.ps1 no longer dies on PS 5.1 stderr quirk; layered TLD-source cascade install.ps1 root-cause fix - Every `& $node ... 2>&1` had been tripping PS 5.1's "$ErrorActionPreference=Stop + native-command stderr = terminating error" quirk. Trap-and-log added in 0.1.1 EXPOSED the bug (0.1.0 died at the exact same line -- silently). 0.1.2 routes both node calls through a new Invoke-NodeCapture helper that uses Start-Process -RedirectStandardOutput/Error to file, so PS 5.1 never touches the streams. Multi-source TLD cascade with on-disk cache - -Indexer now accepts a comma-separated list; default "https://navigate.st,https://silentmode.st". - Cascade (first hit wins): indexer[s] HTTPS -> local cache (C:\ProgramData\Ariadne\tlds-cache.json) -> electrum WSS (fetchTldList / legacy fetchBcnrTlds) -> bundled ariadne.config.json snapshot -> bootstrap [bch]. - Authoritative fetches (indexer or electrum) refresh the cache. Second install on a machine that has ever succeeded before is instant + always works offline. - Per-source deadlines kept tight (5s for indexer HTTPS) so a slow source can't stall the install. Upgrade over live install - .iss CurStepChanged(ssInstall) stops "BNS Resolver Daemon" + "BNS Sia Bridge" via schtasks + 1.5s pause before file replacement. Fixes "DeleteFile failed; code 5. Access is denied" on runtime\node.exe when upgrading a machine where the daemon is currently running. CA import - Switched Import-Certificate -CertStoreLocation Cert:\... to direct X509Store('Root', 'LocalMachine').Add(). Cert: PSDrive is not always loaded in -NoProfile elevated shells, which had broken the standalone unblock scripts. Verified end-to-end on this box: silent install -> exit 0, clean install.log, BNS Resolver Daemon running, 127.0.0.1:53 open, 9 NRPT rules (all TLDs including .bch), coinspectrum.bch resolves system-wide, tlds-cache.json populated. Deployed - dl.silentmode.st/AriadneResolver-Setup-0.1.2.exe - s3://bns/silentmode/dl/AriadneResolver-Setup-0.1.2.exe - silentmode.st + navigate.st/bns/silentmode.bch manifests advertise 0.1.2 - sha256 5a2c9e4f3c5e1a162008641019f5ffc35968751c0440f94d3c5fe67aafb8cc5e Local Dev <noreply@localhost>
2026-09-09 22:57:06 +02:00
# --- helper: run `node --input-type=module -e "<script>"` and capture output
# via Windows-level stream redirection so PS 5.1's "$ErrorActionPreference=Stop
# + native stderr = NativeCommandError" quirk cannot kill us. That quirk is
# what silently broke 0.1.0/0.1.1 install.ps1 at the CA-rotation probe.
function Invoke-NodeCapture([string]$Script) {
$tempOut = [System.IO.Path]::GetTempFileName()
$tempErr = [System.IO.Path]::GetTempFileName()
try {
$p = Start-Process -FilePath $node -ArgumentList @('--input-type=module','-e', $Script) `
-WorkingDirectory $root -Wait -PassThru -NoNewWindow `
-RedirectStandardOutput $tempOut -RedirectStandardError $tempErr
return [pscustomobject]@{
ExitCode = $p.ExitCode
StdOut = if (Test-Path $tempOut) { Get-Content $tempOut -Raw } else { "" }
StdErr = if (Test-Path $tempErr) { Get-Content $tempErr -Raw } else { "" }
}
} finally {
Remove-Item $tempOut, $tempErr -Force -ErrorAction SilentlyContinue
Ariadne 0.1.1 + Theseus fetches it from silentmode.st (no more bundling) Ariadne 0.1.1 - install.ps1 primary TLD source: HTTPS $Indexer/api/tlds -> advertised[] (electrum fetchTldList / legacy fetchBcnrTlds / ariadne.config.json / bootstrap kept as fallbacks in that order). Silent installs no longer stall when WSS is blocked. - Persistent transcript at C:\ProgramData\Ariadne\install.log; separate install-error.log on any uncaught exception. Top-level trap logs the full stack, then exit 1 so Inno/NSIS silent-install callers see a real failure. - .iss: SetupLogging=yes; DeinitializeSetup() copies Inno's log to C:\ProgramData\Ariadne\inno-setup.log on every exit path. - Version bumped to 0.1.1. sha256=be1fa8841919b321841d90f8147abe1b1d7604fe7fff6c2e271dc47c4c24a2b6 Theseus decoupled from Ariadne - Removed nsis/installer.nsh (custom Ariadne chain-install page). - Removed extraResources entry for AriadneResolver-Setup-*.exe. - Removed build.nsis.include from package.json. - Settings > System-wide resolver panel now fetches the .exe from https://silentmode.st/releases-manifest.json, streams the download while hashing, refuses to spawn on SHA-256 mismatch. 30-min in-memory manifest cache so opening Settings doesn't spam the endpoint. Offline gracefully degrades to installedVersion-only / canUpdate:false. - "bundledVersion" IPC field kept for renderer compatibility; it now carries "latest advertised by the site's manifest". Deployed to silentmode.st: - dl.silentmode.st/AriadneResolver-Setup-0.1.1.exe (25 MB) - silentmode.st/releases-manifest.json (schema/2, updated 2026-09-08) - silentmode.st/releases/ + silentmode.st/tools/ show 0.1.1 Local Dev <noreply@localhost>
2026-09-08 01:27:51 +02:00
}
}
Ariadne 0.1.2: install.ps1 no longer dies on PS 5.1 stderr quirk; layered TLD-source cascade install.ps1 root-cause fix - Every `& $node ... 2>&1` had been tripping PS 5.1's "$ErrorActionPreference=Stop + native-command stderr = terminating error" quirk. Trap-and-log added in 0.1.1 EXPOSED the bug (0.1.0 died at the exact same line -- silently). 0.1.2 routes both node calls through a new Invoke-NodeCapture helper that uses Start-Process -RedirectStandardOutput/Error to file, so PS 5.1 never touches the streams. Multi-source TLD cascade with on-disk cache - -Indexer now accepts a comma-separated list; default "https://navigate.st,https://silentmode.st". - Cascade (first hit wins): indexer[s] HTTPS -> local cache (C:\ProgramData\Ariadne\tlds-cache.json) -> electrum WSS (fetchTldList / legacy fetchBcnrTlds) -> bundled ariadne.config.json snapshot -> bootstrap [bch]. - Authoritative fetches (indexer or electrum) refresh the cache. Second install on a machine that has ever succeeded before is instant + always works offline. - Per-source deadlines kept tight (5s for indexer HTTPS) so a slow source can't stall the install. Upgrade over live install - .iss CurStepChanged(ssInstall) stops "BNS Resolver Daemon" + "BNS Sia Bridge" via schtasks + 1.5s pause before file replacement. Fixes "DeleteFile failed; code 5. Access is denied" on runtime\node.exe when upgrading a machine where the daemon is currently running. CA import - Switched Import-Certificate -CertStoreLocation Cert:\... to direct X509Store('Root', 'LocalMachine').Add(). Cert: PSDrive is not always loaded in -NoProfile elevated shells, which had broken the standalone unblock scripts. Verified end-to-end on this box: silent install -> exit 0, clean install.log, BNS Resolver Daemon running, 127.0.0.1:53 open, 9 NRPT rules (all TLDs including .bch), coinspectrum.bch resolves system-wide, tlds-cache.json populated. Deployed - dl.silentmode.st/AriadneResolver-Setup-0.1.2.exe - s3://bns/silentmode/dl/AriadneResolver-Setup-0.1.2.exe - silentmode.st + navigate.st/bns/silentmode.bch manifests advertise 0.1.2 - sha256 5a2c9e4f3c5e1a162008641019f5ffc35968751c0440f94d3c5fe67aafb8cc5e Local Dev <noreply@localhost>
2026-09-09 22:57:06 +02:00
# Discover the set of currently activated BCNR TLDs. Sources, in order of
# preference (first hit wins, tight per-source deadline):
# 1) BNS indexer(s) HTTPS GET <indexer>/api/tlds -> {advertised:[...]}
# Fast + reliable when up; -Indexer takes a comma-separated list so the
# installer can fall over between mirrors (default: navigate.st and
# silentmode.st, both live on the same VPS today; add your own to widen).
# 2) Local cache from a previous successful indexer/electrum fetch
# (C:\ProgramData\Ariadne\tlds-cache.json). Instant; always right on any
# machine that has ever successfully installed before. May be stale --
# won't have TLDs added since last install -- but never wrong.
# 3) On-chain via electrum WSS (per-TLD beacon fetchTldList; legacy
# fetchBcnrTlds as sub-fallback). Slower + WSS-fragile.
# 4) Bundled ariadne.config.json snapshot (frozen at installer build time).
# 5) Bootstrap set [bch] -- last resort so the daemon still starts.
# Cache is refreshed whenever an authoritative source (indexer or electrum)
# succeeds. This drives both the CA's nameConstraints extension and the
# surgical-mode NRPT rules below; adding a new TLD on-chain is picked up by
# re-running this installer (no code release).
$tldCachePath = Join-Path $LogDir 'tlds-cache.json'
Ariadne 0.1.1 + Theseus fetches it from silentmode.st (no more bundling) Ariadne 0.1.1 - install.ps1 primary TLD source: HTTPS $Indexer/api/tlds -> advertised[] (electrum fetchTldList / legacy fetchBcnrTlds / ariadne.config.json / bootstrap kept as fallbacks in that order). Silent installs no longer stall when WSS is blocked. - Persistent transcript at C:\ProgramData\Ariadne\install.log; separate install-error.log on any uncaught exception. Top-level trap logs the full stack, then exit 1 so Inno/NSIS silent-install callers see a real failure. - .iss: SetupLogging=yes; DeinitializeSetup() copies Inno's log to C:\ProgramData\Ariadne\inno-setup.log on every exit path. - Version bumped to 0.1.1. sha256=be1fa8841919b321841d90f8147abe1b1d7604fe7fff6c2e271dc47c4c24a2b6 Theseus decoupled from Ariadne - Removed nsis/installer.nsh (custom Ariadne chain-install page). - Removed extraResources entry for AriadneResolver-Setup-*.exe. - Removed build.nsis.include from package.json. - Settings > System-wide resolver panel now fetches the .exe from https://silentmode.st/releases-manifest.json, streams the download while hashing, refuses to spawn on SHA-256 mismatch. 30-min in-memory manifest cache so opening Settings doesn't spam the endpoint. Offline gracefully degrades to installedVersion-only / canUpdate:false. - "bundledVersion" IPC field kept for renderer compatibility; it now carries "latest advertised by the site's manifest". Deployed to silentmode.st: - dl.silentmode.st/AriadneResolver-Setup-0.1.1.exe (25 MB) - silentmode.st/releases-manifest.json (schema/2, updated 2026-09-08) - silentmode.st/releases/ + silentmode.st/tools/ show 0.1.1 Local Dev <noreply@localhost>
2026-09-08 01:27:51 +02:00
Ariadne 0.1.2: install.ps1 no longer dies on PS 5.1 stderr quirk; layered TLD-source cascade install.ps1 root-cause fix - Every `& $node ... 2>&1` had been tripping PS 5.1's "$ErrorActionPreference=Stop + native-command stderr = terminating error" quirk. Trap-and-log added in 0.1.1 EXPOSED the bug (0.1.0 died at the exact same line -- silently). 0.1.2 routes both node calls through a new Invoke-NodeCapture helper that uses Start-Process -RedirectStandardOutput/Error to file, so PS 5.1 never touches the streams. Multi-source TLD cascade with on-disk cache - -Indexer now accepts a comma-separated list; default "https://navigate.st,https://silentmode.st". - Cascade (first hit wins): indexer[s] HTTPS -> local cache (C:\ProgramData\Ariadne\tlds-cache.json) -> electrum WSS (fetchTldList / legacy fetchBcnrTlds) -> bundled ariadne.config.json snapshot -> bootstrap [bch]. - Authoritative fetches (indexer or electrum) refresh the cache. Second install on a machine that has ever succeeded before is instant + always works offline. - Per-source deadlines kept tight (5s for indexer HTTPS) so a slow source can't stall the install. Upgrade over live install - .iss CurStepChanged(ssInstall) stops "BNS Resolver Daemon" + "BNS Sia Bridge" via schtasks + 1.5s pause before file replacement. Fixes "DeleteFile failed; code 5. Access is denied" on runtime\node.exe when upgrading a machine where the daemon is currently running. CA import - Switched Import-Certificate -CertStoreLocation Cert:\... to direct X509Store('Root', 'LocalMachine').Add(). Cert: PSDrive is not always loaded in -NoProfile elevated shells, which had broken the standalone unblock scripts. Verified end-to-end on this box: silent install -> exit 0, clean install.log, BNS Resolver Daemon running, 127.0.0.1:53 open, 9 NRPT rules (all TLDs including .bch), coinspectrum.bch resolves system-wide, tlds-cache.json populated. Deployed - dl.silentmode.st/AriadneResolver-Setup-0.1.2.exe - s3://bns/silentmode/dl/AriadneResolver-Setup-0.1.2.exe - silentmode.st + navigate.st/bns/silentmode.bch manifests advertise 0.1.2 - sha256 5a2c9e4f3c5e1a162008641019f5ffc35968751c0440f94d3c5fe67aafb8cc5e Local Dev <noreply@localhost>
2026-09-09 22:57:06 +02:00
function Fetch-TldsFromIndexer([string]$IndexerUrl) {
try {
$url = $IndexerUrl.TrimEnd('/') + "/api/tlds"
Write-Host "[..] indexer: $url"
$r = Invoke-RestMethod -Uri $url -TimeoutSec 5 -UseBasicParsing -Headers @{ 'User-Agent' = 'AriadneResolverInstaller/1' }
# Prefer the registry's routable list (every live per-TLD NFT plus the
# legacy advertised set); fall back to assembling it from tlds[] + advertised
# for a gateway that predates the field; last resort: advertised alone (the
# legacy tlds.bch record — nine TLDs, which is how 0.1.4 missed .x).
if ($r -and $r.routable -and $r.routable.Count -gt 0) {
return @{ tlds = @($r.routable | ForEach-Object { [string]$_ }); source = "indexer($IndexerUrl)" }
}
if ($r -and $r.tlds -and $r.tlds.Count -gt 0) {
$live = @($r.tlds | Where-Object { -not $_.hidden } | ForEach-Object { [string]$_.tld })
$adv = @(); if ($r.advertised) { $adv = @($r.advertised | ForEach-Object { [string]$_ }) }
$u = @($live + $adv | Where-Object { $_ } | Select-Object -Unique)
if ($u.Count -gt 0) { return @{ tlds = $u; source = "indexer($IndexerUrl)" } }
}
Ariadne 0.1.2: install.ps1 no longer dies on PS 5.1 stderr quirk; layered TLD-source cascade install.ps1 root-cause fix - Every `& $node ... 2>&1` had been tripping PS 5.1's "$ErrorActionPreference=Stop + native-command stderr = terminating error" quirk. Trap-and-log added in 0.1.1 EXPOSED the bug (0.1.0 died at the exact same line -- silently). 0.1.2 routes both node calls through a new Invoke-NodeCapture helper that uses Start-Process -RedirectStandardOutput/Error to file, so PS 5.1 never touches the streams. Multi-source TLD cascade with on-disk cache - -Indexer now accepts a comma-separated list; default "https://navigate.st,https://silentmode.st". - Cascade (first hit wins): indexer[s] HTTPS -> local cache (C:\ProgramData\Ariadne\tlds-cache.json) -> electrum WSS (fetchTldList / legacy fetchBcnrTlds) -> bundled ariadne.config.json snapshot -> bootstrap [bch]. - Authoritative fetches (indexer or electrum) refresh the cache. Second install on a machine that has ever succeeded before is instant + always works offline. - Per-source deadlines kept tight (5s for indexer HTTPS) so a slow source can't stall the install. Upgrade over live install - .iss CurStepChanged(ssInstall) stops "BNS Resolver Daemon" + "BNS Sia Bridge" via schtasks + 1.5s pause before file replacement. Fixes "DeleteFile failed; code 5. Access is denied" on runtime\node.exe when upgrading a machine where the daemon is currently running. CA import - Switched Import-Certificate -CertStoreLocation Cert:\... to direct X509Store('Root', 'LocalMachine').Add(). Cert: PSDrive is not always loaded in -NoProfile elevated shells, which had broken the standalone unblock scripts. Verified end-to-end on this box: silent install -> exit 0, clean install.log, BNS Resolver Daemon running, 127.0.0.1:53 open, 9 NRPT rules (all TLDs including .bch), coinspectrum.bch resolves system-wide, tlds-cache.json populated. Deployed - dl.silentmode.st/AriadneResolver-Setup-0.1.2.exe - s3://bns/silentmode/dl/AriadneResolver-Setup-0.1.2.exe - silentmode.st + navigate.st/bns/silentmode.bch manifests advertise 0.1.2 - sha256 5a2c9e4f3c5e1a162008641019f5ffc35968751c0440f94d3c5fe67aafb8cc5e Local Dev <noreply@localhost>
2026-09-09 22:57:06 +02:00
if ($r -and $r.advertised -and $r.advertised.Count -gt 0) {
return @{ tlds = @($r.advertised | ForEach-Object { [string]$_ }); source = "indexer($IndexerUrl)" }
}
} catch { Write-Host " [!] $IndexerUrl -> $($_.Exception.Message)" -ForegroundColor Yellow }
return $null
}
function Fetch-TldsFromCache([string]$Path) {
if (-not (Test-Path $Path)) { return $null }
BNS: per-TLD on-chain registry, multi-beacon indexer, enforcement gate Per-TLD certificates on a distinct TLD beacon supersede the legacy list-in-one-NFT model. TLD label is the NFT commitment; TREG/TUPD payloads on the TLD beacon mirror REG/UPD on the name beacon. Chipnet TLD beacon: bchtest:qzc4c76vtw9nd49g6x8nmvc0jz62uvk4dc7hmpmerh scripthash c85db10e106606273422b2733b2a6fb8b35a4d0e7dbfb20cf59bdb0833c008b8 * config.js, resolver-web.{js,d.ts} — TLD_BEACON + TLD_BEACON_SCRIPTHASH * bns.js — KNOWN_OPS { REG, UPD, TREG, TUPD }, registerTld/updateTld/normalizeTld * bns.js + resolver-web.js — buildIndex({enforceTld:false}) drops name REGs whose TLD lacks a live TLD cert at their block height (mempool-friendly). Lockstep across both files. * lib/tld-index.js — buildTldSnapshot({history,txs}) → deterministic root over canonicalised tlds[]. Pure, importable, and stable across insertion order. * indexer/bns-indexer.js — BeaconIndex is multi-beacon; ws handler dispatches by scripthash; new HTTP endpoint GET /tld-list.json + /health behind BNS_HTTP_PORT; state file v1 → v2 migrates in fromJSON. * publish-tld-mirror.mjs — S3 (floating + immutable content-addressed) plus NIP-33 kind 30078 d:bns-tld-list to Nostr relays, signed via nostr-tools (libauth's Schnorr differs from BIP-340 and relays reject it). * seed-tld-beacon.mjs — idempotent chipnet seed. Current set on the beacon: bch p2p bit nav test x asm neo gt sc sia com dex cex nt (15). `.com` is held by the operator: cert on-chain, excluded from public registrar UI. Design + docs: * Decentralized.DNS/DESIGN-tld-registry.md — schema, enforcement, operator-countersig gate, USD-tiered pricing floors, fee splits, tracker/mirror mechanics, migration/grandfathering. * INSTRUCTIONS.md §3 rewritten for the 4-step flow (TREG → UI → deploy → republish snapshot). * site/tlds/ — public docs page listing current TLDs + verification paths. * site/sirius/register.html — dropdown removed; parallel search across every TLD in the TLDS array, sorted available → taken → not-on-registry. Config: * ariadne.config.json tlds → [bch, p2p, bit, nav, test, x] (CA constraints; on-chain registry is now the authoritative source, config is fallback). * setup/install.ps1 — reads TLD list via fetchTldList (per-TLD registry) with fallback to fetchBcnrTlds (legacy tls.bch list-NFT) then config. Tests: * test/tld-index.test.mjs — 30 self-contained checks (multi-beacon dispatch, state migration, ws routing, snapshot shape + root recomputability). * test/tld-enforcement.test.mjs — synthetic + live chipnet integration (with-gate correctly drops all pre-seed names).
2026-08-29 17:11:02 +02:00
try {
Ariadne 0.1.2: install.ps1 no longer dies on PS 5.1 stderr quirk; layered TLD-source cascade install.ps1 root-cause fix - Every `& $node ... 2>&1` had been tripping PS 5.1's "$ErrorActionPreference=Stop + native-command stderr = terminating error" quirk. Trap-and-log added in 0.1.1 EXPOSED the bug (0.1.0 died at the exact same line -- silently). 0.1.2 routes both node calls through a new Invoke-NodeCapture helper that uses Start-Process -RedirectStandardOutput/Error to file, so PS 5.1 never touches the streams. Multi-source TLD cascade with on-disk cache - -Indexer now accepts a comma-separated list; default "https://navigate.st,https://silentmode.st". - Cascade (first hit wins): indexer[s] HTTPS -> local cache (C:\ProgramData\Ariadne\tlds-cache.json) -> electrum WSS (fetchTldList / legacy fetchBcnrTlds) -> bundled ariadne.config.json snapshot -> bootstrap [bch]. - Authoritative fetches (indexer or electrum) refresh the cache. Second install on a machine that has ever succeeded before is instant + always works offline. - Per-source deadlines kept tight (5s for indexer HTTPS) so a slow source can't stall the install. Upgrade over live install - .iss CurStepChanged(ssInstall) stops "BNS Resolver Daemon" + "BNS Sia Bridge" via schtasks + 1.5s pause before file replacement. Fixes "DeleteFile failed; code 5. Access is denied" on runtime\node.exe when upgrading a machine where the daemon is currently running. CA import - Switched Import-Certificate -CertStoreLocation Cert:\... to direct X509Store('Root', 'LocalMachine').Add(). Cert: PSDrive is not always loaded in -NoProfile elevated shells, which had broken the standalone unblock scripts. Verified end-to-end on this box: silent install -> exit 0, clean install.log, BNS Resolver Daemon running, 127.0.0.1:53 open, 9 NRPT rules (all TLDs including .bch), coinspectrum.bch resolves system-wide, tlds-cache.json populated. Deployed - dl.silentmode.st/AriadneResolver-Setup-0.1.2.exe - s3://bns/silentmode/dl/AriadneResolver-Setup-0.1.2.exe - silentmode.st + navigate.st/bns/silentmode.bch manifests advertise 0.1.2 - sha256 5a2c9e4f3c5e1a162008641019f5ffc35968751c0440f94d3c5fe67aafb8cc5e Local Dev <noreply@localhost>
2026-09-09 22:57:06 +02:00
$c = Get-Content $Path -Raw | ConvertFrom-Json
if ($c.tlds -and $c.tlds.Count -gt 0) {
$age = try { [int]((Get-Date) - (Get-Date $c.savedAt)).TotalDays } catch { -1 }
return @{ tlds = @($c.tlds | ForEach-Object { [string]$_ }); source = "cache(age=${age}d)" }
BNS: per-TLD on-chain registry, multi-beacon indexer, enforcement gate Per-TLD certificates on a distinct TLD beacon supersede the legacy list-in-one-NFT model. TLD label is the NFT commitment; TREG/TUPD payloads on the TLD beacon mirror REG/UPD on the name beacon. Chipnet TLD beacon: bchtest:qzc4c76vtw9nd49g6x8nmvc0jz62uvk4dc7hmpmerh scripthash c85db10e106606273422b2733b2a6fb8b35a4d0e7dbfb20cf59bdb0833c008b8 * config.js, resolver-web.{js,d.ts} — TLD_BEACON + TLD_BEACON_SCRIPTHASH * bns.js — KNOWN_OPS { REG, UPD, TREG, TUPD }, registerTld/updateTld/normalizeTld * bns.js + resolver-web.js — buildIndex({enforceTld:false}) drops name REGs whose TLD lacks a live TLD cert at their block height (mempool-friendly). Lockstep across both files. * lib/tld-index.js — buildTldSnapshot({history,txs}) → deterministic root over canonicalised tlds[]. Pure, importable, and stable across insertion order. * indexer/bns-indexer.js — BeaconIndex is multi-beacon; ws handler dispatches by scripthash; new HTTP endpoint GET /tld-list.json + /health behind BNS_HTTP_PORT; state file v1 → v2 migrates in fromJSON. * publish-tld-mirror.mjs — S3 (floating + immutable content-addressed) plus NIP-33 kind 30078 d:bns-tld-list to Nostr relays, signed via nostr-tools (libauth's Schnorr differs from BIP-340 and relays reject it). * seed-tld-beacon.mjs — idempotent chipnet seed. Current set on the beacon: bch p2p bit nav test x asm neo gt sc sia com dex cex nt (15). `.com` is held by the operator: cert on-chain, excluded from public registrar UI. Design + docs: * Decentralized.DNS/DESIGN-tld-registry.md — schema, enforcement, operator-countersig gate, USD-tiered pricing floors, fee splits, tracker/mirror mechanics, migration/grandfathering. * INSTRUCTIONS.md §3 rewritten for the 4-step flow (TREG → UI → deploy → republish snapshot). * site/tlds/ — public docs page listing current TLDs + verification paths. * site/sirius/register.html — dropdown removed; parallel search across every TLD in the TLDS array, sorted available → taken → not-on-registry. Config: * ariadne.config.json tlds → [bch, p2p, bit, nav, test, x] (CA constraints; on-chain registry is now the authoritative source, config is fallback). * setup/install.ps1 — reads TLD list via fetchTldList (per-TLD registry) with fallback to fetchBcnrTlds (legacy tls.bch list-NFT) then config. Tests: * test/tld-index.test.mjs — 30 self-contained checks (multi-beacon dispatch, state migration, ws routing, snapshot shape + root recomputability). * test/tld-enforcement.test.mjs — synthetic + live chipnet integration (with-gate correctly drops all pre-seed names).
2026-08-29 17:11:02 +02:00
}
} catch {}
Ariadne 0.1.2: install.ps1 no longer dies on PS 5.1 stderr quirk; layered TLD-source cascade install.ps1 root-cause fix - Every `& $node ... 2>&1` had been tripping PS 5.1's "$ErrorActionPreference=Stop + native-command stderr = terminating error" quirk. Trap-and-log added in 0.1.1 EXPOSED the bug (0.1.0 died at the exact same line -- silently). 0.1.2 routes both node calls through a new Invoke-NodeCapture helper that uses Start-Process -RedirectStandardOutput/Error to file, so PS 5.1 never touches the streams. Multi-source TLD cascade with on-disk cache - -Indexer now accepts a comma-separated list; default "https://navigate.st,https://silentmode.st". - Cascade (first hit wins): indexer[s] HTTPS -> local cache (C:\ProgramData\Ariadne\tlds-cache.json) -> electrum WSS (fetchTldList / legacy fetchBcnrTlds) -> bundled ariadne.config.json snapshot -> bootstrap [bch]. - Authoritative fetches (indexer or electrum) refresh the cache. Second install on a machine that has ever succeeded before is instant + always works offline. - Per-source deadlines kept tight (5s for indexer HTTPS) so a slow source can't stall the install. Upgrade over live install - .iss CurStepChanged(ssInstall) stops "BNS Resolver Daemon" + "BNS Sia Bridge" via schtasks + 1.5s pause before file replacement. Fixes "DeleteFile failed; code 5. Access is denied" on runtime\node.exe when upgrading a machine where the daemon is currently running. CA import - Switched Import-Certificate -CertStoreLocation Cert:\... to direct X509Store('Root', 'LocalMachine').Add(). Cert: PSDrive is not always loaded in -NoProfile elevated shells, which had broken the standalone unblock scripts. Verified end-to-end on this box: silent install -> exit 0, clean install.log, BNS Resolver Daemon running, 127.0.0.1:53 open, 9 NRPT rules (all TLDs including .bch), coinspectrum.bch resolves system-wide, tlds-cache.json populated. Deployed - dl.silentmode.st/AriadneResolver-Setup-0.1.2.exe - s3://bns/silentmode/dl/AriadneResolver-Setup-0.1.2.exe - silentmode.st + navigate.st/bns/silentmode.bch manifests advertise 0.1.2 - sha256 5a2c9e4f3c5e1a162008641019f5ffc35968751c0440f94d3c5fe67aafb8cc5e Local Dev <noreply@localhost>
2026-09-09 22:57:06 +02:00
return $null
}
function Fetch-TldsFromElectrum {
$js = "import('./src/lib/resolver-web.js').then(async m=>{const ws=(await import('ws')).default;try{const list=await m.fetchTldList({WebSocket:ws});if(list&&list.length&&!(list.length===1&&list[0]==='bch')){console.log(JSON.stringify(list));return}}catch(e){}try{const legacy=await m.fetchBcnrTlds({WebSocket:ws});console.log(JSON.stringify(legacy||[]))}catch(e){console.log('[]')}}).catch(e=>console.log('[]'))"
$r = Invoke-NodeCapture $js
try {
$arr = $r.StdOut.Trim() | ConvertFrom-Json
if ($arr -and $arr.Count -gt 0) { return @{ tlds = @($arr | ForEach-Object { [string]$_ }); source = "electrum" } }
} catch {}
return $null
Ariadne c5efae43: tlds.bch-driven install + BNS_POLICY, doc-aligned Three doc-alignment changes shipping in AriadneResolver-Setup-0.1.0.exe sha256 c5efae43af6cc163f468f1dc73d08939db32a9a6db52298ba18b2d9a2aee1292: 1. install.ps1 fetches the activated TLD list from the on-chain root TLD certificate (tlds.bch, per START-HERE §1) via resolver-web.js fetchBcnrTlds(), then: - regenerates the CA's nameConstraints extension from that list (rotates the CA when the on-chain set changes so leaves for the newly-activated TLDs actually validate) - adds one NRPT rule per activated TLD in surgical mode - falls back to bootstrap ["bch"] if the chain is unreachable Result: adding a TLD on-chain is picked up by re-running the installer, no code release needed. 2. bnsd.js honors --policy / BNS_POLICY (bcnr-first | icann-first, alias bns-first) per START-HERE §4b. bcnr-first is default and preserves prior behavior. icann-first forwards to upstream first and only substitutes a BCNR answer on NXDOMAIN. install.ps1 accepts -Policy and passes it into the scheduled task action. 3. ca.js loadOrCreateRootCA() now accepts a runtime TLD list; the old callers still work (fall back to PERMITTED_TLDS from tlds.js). Doc: RESOLVER-PACKAGING-PROMPT.md rewritten to reflect current shipping reality; original 2026-07-26 packaging brief preserved in the "Archival" section. Deployed to dl.silentmode.st (nginx serves from /opt/silent-mode/dl/) and mirrored to Sia bns/silentmode/. VPS bns-indexer.service reports tlds.bch currently activates: bch p2p deviant nav sia dgb nt sm lm.
2026-08-01 02:06:48 +02:00
}
Ariadne 0.1.2: install.ps1 no longer dies on PS 5.1 stderr quirk; layered TLD-source cascade install.ps1 root-cause fix - Every `& $node ... 2>&1` had been tripping PS 5.1's "$ErrorActionPreference=Stop + native-command stderr = terminating error" quirk. Trap-and-log added in 0.1.1 EXPOSED the bug (0.1.0 died at the exact same line -- silently). 0.1.2 routes both node calls through a new Invoke-NodeCapture helper that uses Start-Process -RedirectStandardOutput/Error to file, so PS 5.1 never touches the streams. Multi-source TLD cascade with on-disk cache - -Indexer now accepts a comma-separated list; default "https://navigate.st,https://silentmode.st". - Cascade (first hit wins): indexer[s] HTTPS -> local cache (C:\ProgramData\Ariadne\tlds-cache.json) -> electrum WSS (fetchTldList / legacy fetchBcnrTlds) -> bundled ariadne.config.json snapshot -> bootstrap [bch]. - Authoritative fetches (indexer or electrum) refresh the cache. Second install on a machine that has ever succeeded before is instant + always works offline. - Per-source deadlines kept tight (5s for indexer HTTPS) so a slow source can't stall the install. Upgrade over live install - .iss CurStepChanged(ssInstall) stops "BNS Resolver Daemon" + "BNS Sia Bridge" via schtasks + 1.5s pause before file replacement. Fixes "DeleteFile failed; code 5. Access is denied" on runtime\node.exe when upgrading a machine where the daemon is currently running. CA import - Switched Import-Certificate -CertStoreLocation Cert:\... to direct X509Store('Root', 'LocalMachine').Add(). Cert: PSDrive is not always loaded in -NoProfile elevated shells, which had broken the standalone unblock scripts. Verified end-to-end on this box: silent install -> exit 0, clean install.log, BNS Resolver Daemon running, 127.0.0.1:53 open, 9 NRPT rules (all TLDs including .bch), coinspectrum.bch resolves system-wide, tlds-cache.json populated. Deployed - dl.silentmode.st/AriadneResolver-Setup-0.1.2.exe - s3://bns/silentmode/dl/AriadneResolver-Setup-0.1.2.exe - silentmode.st + navigate.st/bns/silentmode.bch manifests advertise 0.1.2 - sha256 5a2c9e4f3c5e1a162008641019f5ffc35968751c0440f94d3c5fe67aafb8cc5e Local Dev <noreply@localhost>
2026-09-09 22:57:06 +02:00
function Fetch-TldsFromConfig([string]$CfgPath) {
try {
$c = Get-Content $CfgPath -Raw | ConvertFrom-Json
if ($c.tlds -and $c.tlds.Count -gt 0) {
return @{ tlds = @($c.tlds | ForEach-Object { [string]$_ }); source = "ariadne.config.json" }
}
} catch {}
return $null
}
$result = $null
foreach ($ix in ($Indexer -split ',' | ForEach-Object { $_.Trim() } | Where-Object { $_ })) {
$result = Fetch-TldsFromIndexer $ix
if ($result) { break }
}
if (-not $result) { $result = Fetch-TldsFromCache $tldCachePath; if ($result) { Write-Host "[!] no indexer reachable -- using $($result.source)" -ForegroundColor Yellow } }
if (-not $result) { $result = Fetch-TldsFromElectrum; if ($result) { Write-Host "[ok] resolved via electrum WSS" } }
if (-not $result) { $result = Fetch-TldsFromConfig (Join-Path $root "ariadne.config.json"); if ($result) { Write-Host "[!] falling back to bundled snapshot" -ForegroundColor Yellow } }
if (-not $result) { Write-Host "[!] no TLD source available -- bootstrap [bch]" -ForegroundColor Yellow; $result = @{ tlds = @('bch'); source = 'bootstrap' } }
Ariadne c5efae43: tlds.bch-driven install + BNS_POLICY, doc-aligned Three doc-alignment changes shipping in AriadneResolver-Setup-0.1.0.exe sha256 c5efae43af6cc163f468f1dc73d08939db32a9a6db52298ba18b2d9a2aee1292: 1. install.ps1 fetches the activated TLD list from the on-chain root TLD certificate (tlds.bch, per START-HERE §1) via resolver-web.js fetchBcnrTlds(), then: - regenerates the CA's nameConstraints extension from that list (rotates the CA when the on-chain set changes so leaves for the newly-activated TLDs actually validate) - adds one NRPT rule per activated TLD in surgical mode - falls back to bootstrap ["bch"] if the chain is unreachable Result: adding a TLD on-chain is picked up by re-running the installer, no code release needed. 2. bnsd.js honors --policy / BNS_POLICY (bcnr-first | icann-first, alias bns-first) per START-HERE §4b. bcnr-first is default and preserves prior behavior. icann-first forwards to upstream first and only substitutes a BCNR answer on NXDOMAIN. install.ps1 accepts -Policy and passes it into the scheduled task action. 3. ca.js loadOrCreateRootCA() now accepts a runtime TLD list; the old callers still work (fall back to PERMITTED_TLDS from tlds.js). Doc: RESOLVER-PACKAGING-PROMPT.md rewritten to reflect current shipping reality; original 2026-07-26 packaging brief preserved in the "Archival" section. Deployed to dl.silentmode.st (nginx serves from /opt/silent-mode/dl/) and mirrored to Sia bns/silentmode/. VPS bns-indexer.service reports tlds.bch currently activates: bch p2p deviant nav sia dgb nt sm lm.
2026-08-01 02:06:48 +02:00
Ariadne 0.1.2: install.ps1 no longer dies on PS 5.1 stderr quirk; layered TLD-source cascade install.ps1 root-cause fix - Every `& $node ... 2>&1` had been tripping PS 5.1's "$ErrorActionPreference=Stop + native-command stderr = terminating error" quirk. Trap-and-log added in 0.1.1 EXPOSED the bug (0.1.0 died at the exact same line -- silently). 0.1.2 routes both node calls through a new Invoke-NodeCapture helper that uses Start-Process -RedirectStandardOutput/Error to file, so PS 5.1 never touches the streams. Multi-source TLD cascade with on-disk cache - -Indexer now accepts a comma-separated list; default "https://navigate.st,https://silentmode.st". - Cascade (first hit wins): indexer[s] HTTPS -> local cache (C:\ProgramData\Ariadne\tlds-cache.json) -> electrum WSS (fetchTldList / legacy fetchBcnrTlds) -> bundled ariadne.config.json snapshot -> bootstrap [bch]. - Authoritative fetches (indexer or electrum) refresh the cache. Second install on a machine that has ever succeeded before is instant + always works offline. - Per-source deadlines kept tight (5s for indexer HTTPS) so a slow source can't stall the install. Upgrade over live install - .iss CurStepChanged(ssInstall) stops "BNS Resolver Daemon" + "BNS Sia Bridge" via schtasks + 1.5s pause before file replacement. Fixes "DeleteFile failed; code 5. Access is denied" on runtime\node.exe when upgrading a machine where the daemon is currently running. CA import - Switched Import-Certificate -CertStoreLocation Cert:\... to direct X509Store('Root', 'LocalMachine').Add(). Cert: PSDrive is not always loaded in -NoProfile elevated shells, which had broken the standalone unblock scripts. Verified end-to-end on this box: silent install -> exit 0, clean install.log, BNS Resolver Daemon running, 127.0.0.1:53 open, 9 NRPT rules (all TLDs including .bch), coinspectrum.bch resolves system-wide, tlds-cache.json populated. Deployed - dl.silentmode.st/AriadneResolver-Setup-0.1.2.exe - s3://bns/silentmode/dl/AriadneResolver-Setup-0.1.2.exe - silentmode.st + navigate.st/bns/silentmode.bch manifests advertise 0.1.2 - sha256 5a2c9e4f3c5e1a162008641019f5ffc35968751c0440f94d3c5fe67aafb8cc5e Local Dev <noreply@localhost>
2026-09-09 22:57:06 +02:00
$ACTIVATED_TLDS = $result.tlds
Write-Host "[ok] activated TLDs (source: $($result.source)): $($ACTIVATED_TLDS -join ', ')"
# Persist cache on any authoritative fetch. Cache and bootstrap don't refresh
# themselves; only network sources do.
if ($result.source -like 'indexer(*)' -or $result.source -eq 'electrum') {
try {
@{ tlds = $ACTIVATED_TLDS; savedAt = (Get-Date -Format 's'); source = $result.source } |
ConvertTo-Json | Set-Content -Path $tldCachePath -Encoding utf8
Write-Host "[ok] cached TLD list to $tldCachePath"
} catch { Write-Host "[!] could not write cache: $($_.Exception.Message)" -ForegroundColor Yellow }
}
# Split the activated set: TLDs that ICANN has delegated (.cash, .gt, .sc are
# registered in BNS on purpose as collision tests) are neither routed to the
# daemon nor certified by the local CA — the daemon's upstream forwarding has
# an open EDNS/AAAA concern, and a CA constrained to a real internet TLD could
# vouch for real sites. The IANA root-zone list is fetched live (8 s) and falls
# back to the snapshot bundled next to this script. "bcnr" is always certified:
# the daemon's default certificate is issued for gateway.bcnr.
$ianaList = @()
try {
$ianaText = (Invoke-WebRequest -Uri 'https://data.iana.org/TLD/tlds-alpha-by-domain.txt' -TimeoutSec 8 -UseBasicParsing).Content
$ianaList = @($ianaText -split "`n" | ForEach-Object { $_.Trim().ToLower() } | Where-Object { $_ -and -not $_.StartsWith('#') })
Write-Host "[ok] IANA root zone: $($ianaList.Count) delegated TLDs (live)"
} catch {
$snap = Join-Path $PSScriptRoot 'iana-tlds.txt'
if (Test-Path $snap) { $ianaList = @(Get-Content $snap | ForEach-Object { $_.Trim().ToLower() } | Where-Object { $_ }); Write-Host "[!] IANA list from bundled snapshot ($($ianaList.Count) TLDs)" -ForegroundColor Yellow }
else { Write-Host "[!] no IANA list available -- routing every activated TLD" -ForegroundColor Yellow }
}
$ianaSet = @{}; foreach ($t in $ianaList) { $ianaSet[$t] = $true }
$COLLISION_TLDS = @($ACTIVATED_TLDS | Where-Object { $ianaSet.ContainsKey($_.ToLower()) })
$ROUTE_TLDS = @($ACTIVATED_TLDS | Where-Object { -not $ianaSet.ContainsKey($_.ToLower()) })
if ($ROUTE_TLDS.Count -eq 0) { $ROUTE_TLDS = @('bch') }
$CA_TLDS = @($ROUTE_TLDS + 'bcnr' | Select-Object -Unique)
if ($COLLISION_TLDS.Count -gt 0) { Write-Host "[info] left to ICANN (delegated, resolved by the upstream): $($COLLISION_TLDS -join ', ')" }
Write-Host "[ok] routing + certifying: $($ROUTE_TLDS -join ', ')"
Ariadne 0.1.2: install.ps1 no longer dies on PS 5.1 stderr quirk; layered TLD-source cascade install.ps1 root-cause fix - Every `& $node ... 2>&1` had been tripping PS 5.1's "$ErrorActionPreference=Stop + native-command stderr = terminating error" quirk. Trap-and-log added in 0.1.1 EXPOSED the bug (0.1.0 died at the exact same line -- silently). 0.1.2 routes both node calls through a new Invoke-NodeCapture helper that uses Start-Process -RedirectStandardOutput/Error to file, so PS 5.1 never touches the streams. Multi-source TLD cascade with on-disk cache - -Indexer now accepts a comma-separated list; default "https://navigate.st,https://silentmode.st". - Cascade (first hit wins): indexer[s] HTTPS -> local cache (C:\ProgramData\Ariadne\tlds-cache.json) -> electrum WSS (fetchTldList / legacy fetchBcnrTlds) -> bundled ariadne.config.json snapshot -> bootstrap [bch]. - Authoritative fetches (indexer or electrum) refresh the cache. Second install on a machine that has ever succeeded before is instant + always works offline. - Per-source deadlines kept tight (5s for indexer HTTPS) so a slow source can't stall the install. Upgrade over live install - .iss CurStepChanged(ssInstall) stops "BNS Resolver Daemon" + "BNS Sia Bridge" via schtasks + 1.5s pause before file replacement. Fixes "DeleteFile failed; code 5. Access is denied" on runtime\node.exe when upgrading a machine where the daemon is currently running. CA import - Switched Import-Certificate -CertStoreLocation Cert:\... to direct X509Store('Root', 'LocalMachine').Add(). Cert: PSDrive is not always loaded in -NoProfile elevated shells, which had broken the standalone unblock scripts. Verified end-to-end on this box: silent install -> exit 0, clean install.log, BNS Resolver Daemon running, 127.0.0.1:53 open, 9 NRPT rules (all TLDs including .bch), coinspectrum.bch resolves system-wide, tlds-cache.json populated. Deployed - dl.silentmode.st/AriadneResolver-Setup-0.1.2.exe - s3://bns/silentmode/dl/AriadneResolver-Setup-0.1.2.exe - silentmode.st + navigate.st/bns/silentmode.bch manifests advertise 0.1.2 - sha256 5a2c9e4f3c5e1a162008641019f5ffc35968751c0440f94d3c5fe67aafb8cc5e Local Dev <noreply@localhost>
2026-09-09 22:57:06 +02:00
# Generate the name-constrained local root CA now (on THIS machine; the key
# never ships). If ca/ exists but its permitted-TLD set no longer matches, we
# rotate: delete the stale CA so loadOrCreateRootCA writes a fresh one with
# current constraints. Otherwise clients would reject leaves for any
# newly-added TLD.
Ariadne c5efae43: tlds.bch-driven install + BNS_POLICY, doc-aligned Three doc-alignment changes shipping in AriadneResolver-Setup-0.1.0.exe sha256 c5efae43af6cc163f468f1dc73d08939db32a9a6db52298ba18b2d9a2aee1292: 1. install.ps1 fetches the activated TLD list from the on-chain root TLD certificate (tlds.bch, per START-HERE §1) via resolver-web.js fetchBcnrTlds(), then: - regenerates the CA's nameConstraints extension from that list (rotates the CA when the on-chain set changes so leaves for the newly-activated TLDs actually validate) - adds one NRPT rule per activated TLD in surgical mode - falls back to bootstrap ["bch"] if the chain is unreachable Result: adding a TLD on-chain is picked up by re-running the installer, no code release needed. 2. bnsd.js honors --policy / BNS_POLICY (bcnr-first | icann-first, alias bns-first) per START-HERE §4b. bcnr-first is default and preserves prior behavior. icann-first forwards to upstream first and only substitutes a BCNR answer on NXDOMAIN. install.ps1 accepts -Policy and passes it into the scheduled task action. 3. ca.js loadOrCreateRootCA() now accepts a runtime TLD list; the old callers still work (fall back to PERMITTED_TLDS from tlds.js). Doc: RESOLVER-PACKAGING-PROMPT.md rewritten to reflect current shipping reality; original 2026-07-26 packaging brief preserved in the "Archival" section. Deployed to dl.silentmode.st (nginx serves from /opt/silent-mode/dl/) and mirrored to Sia bns/silentmode/. VPS bns-indexer.service reports tlds.bch currently activates: bch p2p deviant nav sia dgb nt sm lm.
2026-08-01 02:06:48 +02:00
$caCrt = Join-Path $root "ca\root-ca.crt"
$caKey = Join-Path $root "ca\root-ca.key"
$tldsArg = ($CA_TLDS | ForEach-Object { "'" + ($_ -replace "'","''") + "'" }) -join ","
Ariadne 0.1.2: install.ps1 no longer dies on PS 5.1 stderr quirk; layered TLD-source cascade install.ps1 root-cause fix - Every `& $node ... 2>&1` had been tripping PS 5.1's "$ErrorActionPreference=Stop + native-command stderr = terminating error" quirk. Trap-and-log added in 0.1.1 EXPOSED the bug (0.1.0 died at the exact same line -- silently). 0.1.2 routes both node calls through a new Invoke-NodeCapture helper that uses Start-Process -RedirectStandardOutput/Error to file, so PS 5.1 never touches the streams. Multi-source TLD cascade with on-disk cache - -Indexer now accepts a comma-separated list; default "https://navigate.st,https://silentmode.st". - Cascade (first hit wins): indexer[s] HTTPS -> local cache (C:\ProgramData\Ariadne\tlds-cache.json) -> electrum WSS (fetchTldList / legacy fetchBcnrTlds) -> bundled ariadne.config.json snapshot -> bootstrap [bch]. - Authoritative fetches (indexer or electrum) refresh the cache. Second install on a machine that has ever succeeded before is instant + always works offline. - Per-source deadlines kept tight (5s for indexer HTTPS) so a slow source can't stall the install. Upgrade over live install - .iss CurStepChanged(ssInstall) stops "BNS Resolver Daemon" + "BNS Sia Bridge" via schtasks + 1.5s pause before file replacement. Fixes "DeleteFile failed; code 5. Access is denied" on runtime\node.exe when upgrading a machine where the daemon is currently running. CA import - Switched Import-Certificate -CertStoreLocation Cert:\... to direct X509Store('Root', 'LocalMachine').Add(). Cert: PSDrive is not always loaded in -NoProfile elevated shells, which had broken the standalone unblock scripts. Verified end-to-end on this box: silent install -> exit 0, clean install.log, BNS Resolver Daemon running, 127.0.0.1:53 open, 9 NRPT rules (all TLDs including .bch), coinspectrum.bch resolves system-wide, tlds-cache.json populated. Deployed - dl.silentmode.st/AriadneResolver-Setup-0.1.2.exe - s3://bns/silentmode/dl/AriadneResolver-Setup-0.1.2.exe - silentmode.st + navigate.st/bns/silentmode.bch manifests advertise 0.1.2 - sha256 5a2c9e4f3c5e1a162008641019f5ffc35968751c0440f94d3c5fe67aafb8cc5e Local Dev <noreply@localhost>
2026-09-09 22:57:06 +02:00
Ariadne c5efae43: tlds.bch-driven install + BNS_POLICY, doc-aligned Three doc-alignment changes shipping in AriadneResolver-Setup-0.1.0.exe sha256 c5efae43af6cc163f468f1dc73d08939db32a9a6db52298ba18b2d9a2aee1292: 1. install.ps1 fetches the activated TLD list from the on-chain root TLD certificate (tlds.bch, per START-HERE §1) via resolver-web.js fetchBcnrTlds(), then: - regenerates the CA's nameConstraints extension from that list (rotates the CA when the on-chain set changes so leaves for the newly-activated TLDs actually validate) - adds one NRPT rule per activated TLD in surgical mode - falls back to bootstrap ["bch"] if the chain is unreachable Result: adding a TLD on-chain is picked up by re-running the installer, no code release needed. 2. bnsd.js honors --policy / BNS_POLICY (bcnr-first | icann-first, alias bns-first) per START-HERE §4b. bcnr-first is default and preserves prior behavior. icann-first forwards to upstream first and only substitutes a BCNR answer on NXDOMAIN. install.ps1 accepts -Policy and passes it into the scheduled task action. 3. ca.js loadOrCreateRootCA() now accepts a runtime TLD list; the old callers still work (fall back to PERMITTED_TLDS from tlds.js). Doc: RESOLVER-PACKAGING-PROMPT.md rewritten to reflect current shipping reality; original 2026-07-26 packaging brief preserved in the "Archival" section. Deployed to dl.silentmode.st (nginx serves from /opt/silent-mode/dl/) and mirrored to Sia bns/silentmode/. VPS bns-indexer.service reports tlds.bch currently activates: bch p2p deviant nav sia dgb nt sm lm.
2026-08-01 02:06:48 +02:00
if (Test-Path $caCrt) {
Ariadne 0.1.2: install.ps1 no longer dies on PS 5.1 stderr quirk; layered TLD-source cascade install.ps1 root-cause fix - Every `& $node ... 2>&1` had been tripping PS 5.1's "$ErrorActionPreference=Stop + native-command stderr = terminating error" quirk. Trap-and-log added in 0.1.1 EXPOSED the bug (0.1.0 died at the exact same line -- silently). 0.1.2 routes both node calls through a new Invoke-NodeCapture helper that uses Start-Process -RedirectStandardOutput/Error to file, so PS 5.1 never touches the streams. Multi-source TLD cascade with on-disk cache - -Indexer now accepts a comma-separated list; default "https://navigate.st,https://silentmode.st". - Cascade (first hit wins): indexer[s] HTTPS -> local cache (C:\ProgramData\Ariadne\tlds-cache.json) -> electrum WSS (fetchTldList / legacy fetchBcnrTlds) -> bundled ariadne.config.json snapshot -> bootstrap [bch]. - Authoritative fetches (indexer or electrum) refresh the cache. Second install on a machine that has ever succeeded before is instant + always works offline. - Per-source deadlines kept tight (5s for indexer HTTPS) so a slow source can't stall the install. Upgrade over live install - .iss CurStepChanged(ssInstall) stops "BNS Resolver Daemon" + "BNS Sia Bridge" via schtasks + 1.5s pause before file replacement. Fixes "DeleteFile failed; code 5. Access is denied" on runtime\node.exe when upgrading a machine where the daemon is currently running. CA import - Switched Import-Certificate -CertStoreLocation Cert:\... to direct X509Store('Root', 'LocalMachine').Add(). Cert: PSDrive is not always loaded in -NoProfile elevated shells, which had broken the standalone unblock scripts. Verified end-to-end on this box: silent install -> exit 0, clean install.log, BNS Resolver Daemon running, 127.0.0.1:53 open, 9 NRPT rules (all TLDs including .bch), coinspectrum.bch resolves system-wide, tlds-cache.json populated. Deployed - dl.silentmode.st/AriadneResolver-Setup-0.1.2.exe - s3://bns/silentmode/dl/AriadneResolver-Setup-0.1.2.exe - silentmode.st + navigate.st/bns/silentmode.bch manifests advertise 0.1.2 - sha256 5a2c9e4f3c5e1a162008641019f5ffc35968751c0440f94d3c5fe67aafb8cc5e Local Dev <noreply@localhost>
2026-09-09 22:57:06 +02:00
$r = Invoke-NodeCapture "import('./src/lib/ca.js').then(m=>{try{m.loadOrCreateRootCA([$tldsArg]);console.log('ok')}catch(e){console.log('err')}}).catch(e=>console.log('err'))"
# ca.js prints the constraint-mismatch phrase to stderr; we grep StdErr here
# instead of merging streams (which is what tripped PS 5.1 before).
if ($r.StdErr -match 'is constrained to \[.*\] but the requested TLD list is') {
Write-Host "[ok] rotating CA to match current TLD set"
Ariadne c5efae43: tlds.bch-driven install + BNS_POLICY, doc-aligned Three doc-alignment changes shipping in AriadneResolver-Setup-0.1.0.exe sha256 c5efae43af6cc163f468f1dc73d08939db32a9a6db52298ba18b2d9a2aee1292: 1. install.ps1 fetches the activated TLD list from the on-chain root TLD certificate (tlds.bch, per START-HERE §1) via resolver-web.js fetchBcnrTlds(), then: - regenerates the CA's nameConstraints extension from that list (rotates the CA when the on-chain set changes so leaves for the newly-activated TLDs actually validate) - adds one NRPT rule per activated TLD in surgical mode - falls back to bootstrap ["bch"] if the chain is unreachable Result: adding a TLD on-chain is picked up by re-running the installer, no code release needed. 2. bnsd.js honors --policy / BNS_POLICY (bcnr-first | icann-first, alias bns-first) per START-HERE §4b. bcnr-first is default and preserves prior behavior. icann-first forwards to upstream first and only substitutes a BCNR answer on NXDOMAIN. install.ps1 accepts -Policy and passes it into the scheduled task action. 3. ca.js loadOrCreateRootCA() now accepts a runtime TLD list; the old callers still work (fall back to PERMITTED_TLDS from tlds.js). Doc: RESOLVER-PACKAGING-PROMPT.md rewritten to reflect current shipping reality; original 2026-07-26 packaging brief preserved in the "Archival" section. Deployed to dl.silentmode.st (nginx serves from /opt/silent-mode/dl/) and mirrored to Sia bns/silentmode/. VPS bns-indexer.service reports tlds.bch currently activates: bch p2p deviant nav sia dgb nt sm lm.
2026-08-01 02:06:48 +02:00
Remove-Item -Path $caCrt, $caKey -Force -ErrorAction SilentlyContinue
}
}
Ariadne 0.1.2: install.ps1 no longer dies on PS 5.1 stderr quirk; layered TLD-source cascade install.ps1 root-cause fix - Every `& $node ... 2>&1` had been tripping PS 5.1's "$ErrorActionPreference=Stop + native-command stderr = terminating error" quirk. Trap-and-log added in 0.1.1 EXPOSED the bug (0.1.0 died at the exact same line -- silently). 0.1.2 routes both node calls through a new Invoke-NodeCapture helper that uses Start-Process -RedirectStandardOutput/Error to file, so PS 5.1 never touches the streams. Multi-source TLD cascade with on-disk cache - -Indexer now accepts a comma-separated list; default "https://navigate.st,https://silentmode.st". - Cascade (first hit wins): indexer[s] HTTPS -> local cache (C:\ProgramData\Ariadne\tlds-cache.json) -> electrum WSS (fetchTldList / legacy fetchBcnrTlds) -> bundled ariadne.config.json snapshot -> bootstrap [bch]. - Authoritative fetches (indexer or electrum) refresh the cache. Second install on a machine that has ever succeeded before is instant + always works offline. - Per-source deadlines kept tight (5s for indexer HTTPS) so a slow source can't stall the install. Upgrade over live install - .iss CurStepChanged(ssInstall) stops "BNS Resolver Daemon" + "BNS Sia Bridge" via schtasks + 1.5s pause before file replacement. Fixes "DeleteFile failed; code 5. Access is denied" on runtime\node.exe when upgrading a machine where the daemon is currently running. CA import - Switched Import-Certificate -CertStoreLocation Cert:\... to direct X509Store('Root', 'LocalMachine').Add(). Cert: PSDrive is not always loaded in -NoProfile elevated shells, which had broken the standalone unblock scripts. Verified end-to-end on this box: silent install -> exit 0, clean install.log, BNS Resolver Daemon running, 127.0.0.1:53 open, 9 NRPT rules (all TLDs including .bch), coinspectrum.bch resolves system-wide, tlds-cache.json populated. Deployed - dl.silentmode.st/AriadneResolver-Setup-0.1.2.exe - s3://bns/silentmode/dl/AriadneResolver-Setup-0.1.2.exe - silentmode.st + navigate.st/bns/silentmode.bch manifests advertise 0.1.2 - sha256 5a2c9e4f3c5e1a162008641019f5ffc35968751c0440f94d3c5fe67aafb8cc5e Local Dev <noreply@localhost>
2026-09-09 22:57:06 +02:00
$r = Invoke-NodeCapture "import('./src/lib/ca.js').then(m=>m.loadOrCreateRootCA([$tldsArg])).catch(e=>{console.error(String(e));process.exit(1)})"
if ($r.ExitCode -ne 0) {
if ($r.StdErr) { Write-Host $r.StdErr -ForegroundColor Red }
throw "CA generation failed (node exit $($r.ExitCode))"
}
if (-not (Test-Path $caCrt)) { throw "CA generation produced no root-ca.crt" }
Write-Host "[ok] CA at $caCrt"
# The daemon reads its permitted-TLD list from ariadne.config.json (and, since
# 0.1.5, from the CA's own constraints); write the same list the CA was minted
# with so the two can never drift apart again.
$cfgPath = Join-Path $root 'ariadne.config.json'
try {
$cfg = Get-Content $cfgPath -Raw | ConvertFrom-Json
$cfg.tlds = @($CA_TLDS)
$cfg | ConvertTo-Json -Depth 10 | Set-Content -Path $cfgPath -Encoding utf8
Write-Host "[ok] ariadne.config.json tlds = $($CA_TLDS -join ', ')"
} catch { Write-Host "[!] could not update ariadne.config.json tlds: $($_.Exception.Message)" -ForegroundColor Yellow }
Ariadne c5efae43: tlds.bch-driven install + BNS_POLICY, doc-aligned Three doc-alignment changes shipping in AriadneResolver-Setup-0.1.0.exe sha256 c5efae43af6cc163f468f1dc73d08939db32a9a6db52298ba18b2d9a2aee1292: 1. install.ps1 fetches the activated TLD list from the on-chain root TLD certificate (tlds.bch, per START-HERE §1) via resolver-web.js fetchBcnrTlds(), then: - regenerates the CA's nameConstraints extension from that list (rotates the CA when the on-chain set changes so leaves for the newly-activated TLDs actually validate) - adds one NRPT rule per activated TLD in surgical mode - falls back to bootstrap ["bch"] if the chain is unreachable Result: adding a TLD on-chain is picked up by re-running the installer, no code release needed. 2. bnsd.js honors --policy / BNS_POLICY (bcnr-first | icann-first, alias bns-first) per START-HERE §4b. bcnr-first is default and preserves prior behavior. icann-first forwards to upstream first and only substitutes a BCNR answer on NXDOMAIN. install.ps1 accepts -Policy and passes it into the scheduled task action. 3. ca.js loadOrCreateRootCA() now accepts a runtime TLD list; the old callers still work (fall back to PERMITTED_TLDS from tlds.js). Doc: RESOLVER-PACKAGING-PROMPT.md rewritten to reflect current shipping reality; original 2026-07-26 packaging brief preserved in the "Archival" section. Deployed to dl.silentmode.st (nginx serves from /opt/silent-mode/dl/) and mirrored to Sia bns/silentmode/. VPS bns-indexer.service reports tlds.bch currently activates: bch p2p deviant nav sia dgb nt sm lm.
2026-08-01 02:06:48 +02:00
# 0) Idempotency: clear every previous NRPT rule we own (any TLD).
Get-DnsClientNrptRule | Where-Object { $_.Comment -like 'BNS *resolver' } | ForEach-Object {
Remove-DnsClientNrptRule -Name $_.Name -Force
}
try { Stop-ScheduledTask -TaskName "BNS Resolver Daemon" -ErrorAction Stop } catch {}
try { Stop-ScheduledTask -TaskName "BNS Sia Bridge" -ErrorAction Stop } catch {}
# 1) Scheduled task: run the daemon at boot as SYSTEM (survives logoff, binds port 53/80/443)
Ariadne c5efae43: tlds.bch-driven install + BNS_POLICY, doc-aligned Three doc-alignment changes shipping in AriadneResolver-Setup-0.1.0.exe sha256 c5efae43af6cc163f468f1dc73d08939db32a9a6db52298ba18b2d9a2aee1292: 1. install.ps1 fetches the activated TLD list from the on-chain root TLD certificate (tlds.bch, per START-HERE §1) via resolver-web.js fetchBcnrTlds(), then: - regenerates the CA's nameConstraints extension from that list (rotates the CA when the on-chain set changes so leaves for the newly-activated TLDs actually validate) - adds one NRPT rule per activated TLD in surgical mode - falls back to bootstrap ["bch"] if the chain is unreachable Result: adding a TLD on-chain is picked up by re-running the installer, no code release needed. 2. bnsd.js honors --policy / BNS_POLICY (bcnr-first | icann-first, alias bns-first) per START-HERE §4b. bcnr-first is default and preserves prior behavior. icann-first forwards to upstream first and only substitutes a BCNR answer on NXDOMAIN. install.ps1 accepts -Policy and passes it into the scheduled task action. 3. ca.js loadOrCreateRootCA() now accepts a runtime TLD list; the old callers still work (fall back to PERMITTED_TLDS from tlds.js). Doc: RESOLVER-PACKAGING-PROMPT.md rewritten to reflect current shipping reality; original 2026-07-26 packaging brief preserved in the "Archival" section. Deployed to dl.silentmode.st (nginx serves from /opt/silent-mode/dl/) and mirrored to Sia bns/silentmode/. VPS bns-indexer.service reports tlds.bch currently activates: bch p2p deviant nav sia dgb nt sm lm.
2026-08-01 02:06:48 +02:00
# Pass --policy so bnsd.js applies the chosen collision mode (docs: 4b).
$action = New-ScheduledTaskAction -Execute $node -Argument "`"$daemon`" --upstream $Upstream --policy $Policy" -WorkingDirectory $root
$trigger = New-ScheduledTaskTrigger -AtStartup
$settings = New-ScheduledTaskSettingsSet -RestartCount 5 -RestartInterval (New-TimeSpan -Minutes 1) -ExecutionTimeLimit (New-TimeSpan -Days 3650)
Register-ScheduledTask -TaskName "BNS Resolver Daemon" -Action $action -Trigger $trigger -Settings $settings `
-User "SYSTEM" -RunLevel Highest -Force | Out-Null
Start-ScheduledTask -TaskName "BNS Resolver Daemon"
Write-Host "[ok] daemon installed as scheduled task 'BNS Resolver Daemon' and started"
# 1b) Sia bridge (optional): serves "s3" records from the Sia network
$s3d = Join-Path $root "tools\s3d.exe"
if (Test-Path $s3d) {
# runs as the logged-on user (s3d's login state lives in the user's APPDATA)
$s3dAction = New-ScheduledTaskAction -Execute $s3d -WorkingDirectory $root
$s3dTrigger = New-ScheduledTaskTrigger -AtLogOn -User $env:USERNAME
$s3dPrincipal = New-ScheduledTaskPrincipal -UserId $env:USERNAME -LogonType Interactive
Register-ScheduledTask -TaskName "BNS Sia Bridge" -Action $s3dAction -Trigger $s3dTrigger `
-Settings $settings -Principal $s3dPrincipal -Force | Out-Null
Start-ScheduledTask -TaskName "BNS Sia Bridge"
Write-Host "[ok] s3d Sia bridge installed (runs at your logon) and started"
}
# 2) Route queries to it
$state = @{ mode = $Mode; adapters = @() }
if ($Mode -eq "nrpt") {
Ariadne c5efae43: tlds.bch-driven install + BNS_POLICY, doc-aligned Three doc-alignment changes shipping in AriadneResolver-Setup-0.1.0.exe sha256 c5efae43af6cc163f468f1dc73d08939db32a9a6db52298ba18b2d9a2aee1292: 1. install.ps1 fetches the activated TLD list from the on-chain root TLD certificate (tlds.bch, per START-HERE §1) via resolver-web.js fetchBcnrTlds(), then: - regenerates the CA's nameConstraints extension from that list (rotates the CA when the on-chain set changes so leaves for the newly-activated TLDs actually validate) - adds one NRPT rule per activated TLD in surgical mode - falls back to bootstrap ["bch"] if the chain is unreachable Result: adding a TLD on-chain is picked up by re-running the installer, no code release needed. 2. bnsd.js honors --policy / BNS_POLICY (bcnr-first | icann-first, alias bns-first) per START-HERE §4b. bcnr-first is default and preserves prior behavior. icann-first forwards to upstream first and only substitutes a BCNR answer on NXDOMAIN. install.ps1 accepts -Policy and passes it into the scheduled task action. 3. ca.js loadOrCreateRootCA() now accepts a runtime TLD list; the old callers still work (fall back to PERMITTED_TLDS from tlds.js). Doc: RESOLVER-PACKAGING-PROMPT.md rewritten to reflect current shipping reality; original 2026-07-26 packaging brief preserved in the "Archival" section. Deployed to dl.silentmode.st (nginx serves from /opt/silent-mode/dl/) and mirrored to Sia bns/silentmode/. VPS bns-indexer.service reports tlds.bch currently activates: bch p2p deviant nav sia dgb nt sm lm.
2026-08-01 02:06:48 +02:00
# Surgical mode: one NRPT rule per TLD that tlds.bch has activated on-chain.
# BCNR-native TLDs are declared there and only there; a re-install after a new
# TLD is activated picks it up with no code release. Dual TLDs that collide
# with ICANN are still safe to route because the daemon falls through to
# UPSTREAM on any BCNR miss.
foreach ($tld in $ROUTE_TLDS) {
Ariadne c5efae43: tlds.bch-driven install + BNS_POLICY, doc-aligned Three doc-alignment changes shipping in AriadneResolver-Setup-0.1.0.exe sha256 c5efae43af6cc163f468f1dc73d08939db32a9a6db52298ba18b2d9a2aee1292: 1. install.ps1 fetches the activated TLD list from the on-chain root TLD certificate (tlds.bch, per START-HERE §1) via resolver-web.js fetchBcnrTlds(), then: - regenerates the CA's nameConstraints extension from that list (rotates the CA when the on-chain set changes so leaves for the newly-activated TLDs actually validate) - adds one NRPT rule per activated TLD in surgical mode - falls back to bootstrap ["bch"] if the chain is unreachable Result: adding a TLD on-chain is picked up by re-running the installer, no code release needed. 2. bnsd.js honors --policy / BNS_POLICY (bcnr-first | icann-first, alias bns-first) per START-HERE §4b. bcnr-first is default and preserves prior behavior. icann-first forwards to upstream first and only substitutes a BCNR answer on NXDOMAIN. install.ps1 accepts -Policy and passes it into the scheduled task action. 3. ca.js loadOrCreateRootCA() now accepts a runtime TLD list; the old callers still work (fall back to PERMITTED_TLDS from tlds.js). Doc: RESOLVER-PACKAGING-PROMPT.md rewritten to reflect current shipping reality; original 2026-07-26 packaging brief preserved in the "Archival" section. Deployed to dl.silentmode.st (nginx serves from /opt/silent-mode/dl/) and mirrored to Sia bns/silentmode/. VPS bns-indexer.service reports tlds.bch currently activates: bch p2p deviant nav sia dgb nt sm lm.
2026-08-01 02:06:48 +02:00
$ns = ".$tld"
# Idempotent: clean any pre-existing rule for this namespace first.
Get-DnsClientNrptRule | Where-Object { $_.Namespace -contains $ns -and $_.Comment -like 'BNS *' } | ForEach-Object {
Remove-DnsClientNrptRule -Name $_.Name -Force
}
Add-DnsClientNrptRule -Namespace $ns -NameServers "127.0.0.1" -Comment "BNS $ns resolver"
Write-Host "[ok] NRPT rule added: $ns -> 127.0.0.1"
}
Write-Host "[ok] all other DNS untouched"
} else {
# Reinstall-safe backup: if the machine is ALREADY pointed at us (127.0.0.1) from a
# prior install, the "current" servers are a useless restore target. Reuse the last
# good backup if we have one, else fall back to DHCP. NEVER record loopback as the
# original -- that's exactly what left a past uninstall pointing DNS at a dead daemon.
$prior = @{}
if (Test-Path $stateFile) {
try { (Get-Content $stateFile | ConvertFrom-Json).adapters | ForEach-Object { $prior[$_.alias] = $_ } } catch {}
}
foreach ($if in Get-DnsClientServerAddress -AddressFamily IPv4 |
Where-Object { $_.InterfaceAlias -notmatch "Loopback" -and $_.ServerAddresses.Count -gt 0 }) {
$orig = @($if.ServerAddresses | Where-Object { $_ -ne '127.0.0.1' -and $_ -ne '::1' })
if ($orig.Count -eq 0 -and $prior.ContainsKey($if.InterfaceAlias)) {
$orig = @($prior[$if.InterfaceAlias].servers | Where-Object { $_ -and $_ -ne '127.0.0.1' -and $_ -ne '::1' })
}
$state.adapters += @{ alias = $if.InterfaceAlias; servers = $orig; resetToDhcp = ($orig.Count -eq 0) }
Set-DnsClientServerAddress -InterfaceAlias $if.InterfaceAlias -ServerAddresses 127.0.0.1
$restoreTo = if ($orig.Count) { $orig -join ', ' } else { 'DHCP (automatic)' }
Write-Host "[ok] adapter '$($if.InterfaceAlias)' DNS -> 127.0.0.1 (restore target: $restoreTo)"
}
}
# 3) TLS trust anchor: BNS Local Root CA into the machine store, and tell
# Firefox (which keeps its own store) to honor Windows enterprise roots.
$caCert = Join-Path $root "ca\root-ca.crt"
if (Test-Path $caCert) {
# Refuse to trust a root that can vouch for the whole internet. Roots generated
# before 2026-07-26 carry no name constraints; installing one means anyone who
# can read ca\root-ca.key can forge a trusted certificate for any domain on this
# machine. Constrained roots are limited to the TLDs in src\lib\tlds.js.
$ncOid = "2.5.29.30"
$parsed = [System.Security.Cryptography.X509Certificates.X509Certificate2]::new($caCert)
$hasConstraints = @($parsed.Extensions | Where-Object { $_.Oid.Value -eq $ncOid }).Count -gt 0
$parsed.Dispose()
if (-not $hasConstraints) {
Write-Host ""
Write-Host "[STOP] ca\root-ca.crt has NO X.509 name constraints." -ForegroundColor Red
Write-Host " Trusting it would let anyone who reads ca\root-ca.key forge a" -ForegroundColor Red
Write-Host " certificate for ANY domain on this machine, not just BNS names." -ForegroundColor Red
Write-Host " Rotate the CA, then re-run this installer:" -ForegroundColor Red
Write-Host " setup\uninstall.ps1 (removes the old root from the store)" -ForegroundColor Red
Write-Host " Remove-Item -Recurse $($root)\ca"
Write-Host " setup\install.ps1 (generates a constrained root)" -ForegroundColor Red
Write-Host ""
throw "refusing to install an unconstrained root CA"
}
Ariadne 0.1.2: install.ps1 no longer dies on PS 5.1 stderr quirk; layered TLD-source cascade install.ps1 root-cause fix - Every `& $node ... 2>&1` had been tripping PS 5.1's "$ErrorActionPreference=Stop + native-command stderr = terminating error" quirk. Trap-and-log added in 0.1.1 EXPOSED the bug (0.1.0 died at the exact same line -- silently). 0.1.2 routes both node calls through a new Invoke-NodeCapture helper that uses Start-Process -RedirectStandardOutput/Error to file, so PS 5.1 never touches the streams. Multi-source TLD cascade with on-disk cache - -Indexer now accepts a comma-separated list; default "https://navigate.st,https://silentmode.st". - Cascade (first hit wins): indexer[s] HTTPS -> local cache (C:\ProgramData\Ariadne\tlds-cache.json) -> electrum WSS (fetchTldList / legacy fetchBcnrTlds) -> bundled ariadne.config.json snapshot -> bootstrap [bch]. - Authoritative fetches (indexer or electrum) refresh the cache. Second install on a machine that has ever succeeded before is instant + always works offline. - Per-source deadlines kept tight (5s for indexer HTTPS) so a slow source can't stall the install. Upgrade over live install - .iss CurStepChanged(ssInstall) stops "BNS Resolver Daemon" + "BNS Sia Bridge" via schtasks + 1.5s pause before file replacement. Fixes "DeleteFile failed; code 5. Access is denied" on runtime\node.exe when upgrading a machine where the daemon is currently running. CA import - Switched Import-Certificate -CertStoreLocation Cert:\... to direct X509Store('Root', 'LocalMachine').Add(). Cert: PSDrive is not always loaded in -NoProfile elevated shells, which had broken the standalone unblock scripts. Verified end-to-end on this box: silent install -> exit 0, clean install.log, BNS Resolver Daemon running, 127.0.0.1:53 open, 9 NRPT rules (all TLDs including .bch), coinspectrum.bch resolves system-wide, tlds-cache.json populated. Deployed - dl.silentmode.st/AriadneResolver-Setup-0.1.2.exe - s3://bns/silentmode/dl/AriadneResolver-Setup-0.1.2.exe - silentmode.st + navigate.st/bns/silentmode.bch manifests advertise 0.1.2 - sha256 5a2c9e4f3c5e1a162008641019f5ffc35968751c0440f94d3c5fe67aafb8cc5e Local Dev <noreply@localhost>
2026-09-09 22:57:06 +02:00
# .NET direct -- Import-Certificate depends on the Cert: PSDrive which is
# not always loaded in -NoProfile elevated shells (Inno's [Run] context, for
# example). Adding to X509Store('Root','LocalMachine') is idempotent.
$store = New-Object System.Security.Cryptography.X509Certificates.X509Store('Root','LocalMachine')
$store.Open('ReadWrite')
$imported = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($caCert)
Ariadne 0.1.4: sweep stale BNS root CAs so browsers stop failing after upgrades Symptom: on any machine that had been through a series of installs, one or more older "BNS Local Root CA" certs from earlier builds could accumulate in LocalMachine\Root -- an unconstrained root from before 2026-07, or a rotated one -- and every install added the current constrained root ALONGSIDE the stale ones. Two certs with the same Subject-DN defeat browser chain-builders: Chromium/Edge/Firefox pick one candidate and refuse to try the others, so every .bch site failed with ERR_CERT_AUTHORITY_INVALID / SEC_ERROR_BAD_SIGNATURE in every browser EXCEPT Theseus (which trusts the on-chain tls fingerprint directly, not the machine store). Reproduced on the dev box: two BNS Local Root CAs present (thumbprints EB5DBE98... constrained + 23538FD7... unconstrained), DNS answered correctly, strict Invoke-WebRequest to https://coinspectrum.bch/ failed. Removing the stale one and re-running the chain-build restored HTTPS 200. Fix (install.ps1): - Before Add(imported), enumerate the store and $store.Remove() every "BNS Local Root CA" whose thumbprint differs from the one we're about to trust. Post-condition: exactly one BNS root remains after install. Fix (uninstall.ps1): - Switched from `Get-ChildItem Cert:\LocalMachine\Root` to X509Store direct. The Cert: PSDrive is not always loaded in Inno's [UninstallRun] -NoProfile context, so uninstall could silently leave the CA behind on the store side even while it removed everything else. Verified end-to-end on this box: 0.1.4 upgrade over 0.1.3 finished cleanly, BNS Resolver Daemon Running, 127.0.0.1:53 open, exactly one BNS Local Root CA in the machine store, strict HTTPS to https://coinspectrum.bch/ returned 200 (506,997 bytes) with X509Chain.Build ok=true leaf -> BNS root. Deployed - dl.silentmode.st/AriadneResolver-Setup-0.1.4.exe - s3://bns/silentmode/dl/AriadneResolver-Setup-0.1.4.exe - silentmode.st manifest advertises 0.1.4 - sha256 30ed5e3bb6d6da5325f854c97976410b4fc63067ed52c810a55e9d2e1bdc4e17
2026-09-27 22:04:00 +02:00
# Sweep any prior "BNS Local Root CA" whose thumbprint differs from the one
# we're about to trust. Two roots with the same Subject-DN confuse browsers'
# chain-builders (Chromium/Edge/Firefox all pick one candidate and refuse to
# try others), which manifests as "resolver installed and DNS answers, but
# every .bch site fails with SEC_ERROR_BAD_SIGNATURE / ERR_CERT_AUTHORITY_INVALID
# in every browser except Theseus". A stale unconstrained root left over from
# an early build is enough to trigger it -- and there's no way to detect it
# without walking the store, because both roots claim the same identity.
# Post-condition: exactly one "BNS Local Root CA" remains after this block.
foreach ($c in @($store.Certificates | Where-Object { $_.Subject -match 'BNS Local Root CA' -and $_.Thumbprint -ne $imported.Thumbprint })) {
Write-Host "[ok] removing stale BNS root CA ($($c.Thumbprint), NotAfter $($c.NotAfter))"
$store.Remove($c)
}
Ariadne 0.1.2: install.ps1 no longer dies on PS 5.1 stderr quirk; layered TLD-source cascade install.ps1 root-cause fix - Every `& $node ... 2>&1` had been tripping PS 5.1's "$ErrorActionPreference=Stop + native-command stderr = terminating error" quirk. Trap-and-log added in 0.1.1 EXPOSED the bug (0.1.0 died at the exact same line -- silently). 0.1.2 routes both node calls through a new Invoke-NodeCapture helper that uses Start-Process -RedirectStandardOutput/Error to file, so PS 5.1 never touches the streams. Multi-source TLD cascade with on-disk cache - -Indexer now accepts a comma-separated list; default "https://navigate.st,https://silentmode.st". - Cascade (first hit wins): indexer[s] HTTPS -> local cache (C:\ProgramData\Ariadne\tlds-cache.json) -> electrum WSS (fetchTldList / legacy fetchBcnrTlds) -> bundled ariadne.config.json snapshot -> bootstrap [bch]. - Authoritative fetches (indexer or electrum) refresh the cache. Second install on a machine that has ever succeeded before is instant + always works offline. - Per-source deadlines kept tight (5s for indexer HTTPS) so a slow source can't stall the install. Upgrade over live install - .iss CurStepChanged(ssInstall) stops "BNS Resolver Daemon" + "BNS Sia Bridge" via schtasks + 1.5s pause before file replacement. Fixes "DeleteFile failed; code 5. Access is denied" on runtime\node.exe when upgrading a machine where the daemon is currently running. CA import - Switched Import-Certificate -CertStoreLocation Cert:\... to direct X509Store('Root', 'LocalMachine').Add(). Cert: PSDrive is not always loaded in -NoProfile elevated shells, which had broken the standalone unblock scripts. Verified end-to-end on this box: silent install -> exit 0, clean install.log, BNS Resolver Daemon running, 127.0.0.1:53 open, 9 NRPT rules (all TLDs including .bch), coinspectrum.bch resolves system-wide, tlds-cache.json populated. Deployed - dl.silentmode.st/AriadneResolver-Setup-0.1.2.exe - s3://bns/silentmode/dl/AriadneResolver-Setup-0.1.2.exe - silentmode.st + navigate.st/bns/silentmode.bch manifests advertise 0.1.2 - sha256 5a2c9e4f3c5e1a162008641019f5ffc35968751c0440f94d3c5fe67aafb8cc5e Local Dev <noreply@localhost>
2026-09-09 22:57:06 +02:00
$store.Add($imported)
$store.Close()
$state.caThumbprint = $imported.Thumbprint
New-Item -Path "HKLM:\SOFTWARE\Policies\Mozilla\Firefox\Certificates" -Force | Out-Null
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Mozilla\Firefox\Certificates" `
-Name "ImportEnterpriseRoots" -Value 1 -Type DWord
# Also install our specific root into Firefox's own store (works even if the
# user disabled enterprise-roots). Both policies are applied at Firefox startup.
New-Item -Path "HKLM:\SOFTWARE\Policies\Mozilla\Firefox\Certificates\Install" -Force | Out-Null
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Mozilla\Firefox\Certificates\Install" -Name "1" -Value $caCert -Type String
Write-Host "[ok] BNS Local Root CA trusted (machine store + Firefox enterprise-roots & install policies)"
# Firefox only loads the enterprise-roots policy + new root at startup, so a
# running Firefox keeps rejecting .bch until it is restarted.
$ff = Get-Process firefox -ErrorAction SilentlyContinue
if ($ff) {
if ($CloseFirefox) {
$ff | Stop-Process -Force
Write-Host "[ok] Firefox was closed -- reopen it and .bch certificates will be trusted"
} else {
Write-Host "[!] Firefox is open -- fully QUIT and reopen it so it trusts .bch (or re-run with -CloseFirefox)." -ForegroundColor Yellow
}
}
} else {
Write-Host "[skip] no ca\root-ca.crt found -- https for .bch not enabled"
}
# 3b) Firefox DNS-over-HTTPS. BCNR-only names (all .bch, etc.) already work in
# Firefox with DoH ON -- DoH returns NXDOMAIN and Firefox falls back to the
# system resolver (us). Only names that ALSO exist in ICANN (a reclaimed .de)
# lose to the real record. Turning DoH off fixes those but sends Firefox's
# other DNS through the system resolver instead of encrypted to Cloudflare --
# so it's opt-in (-FirefoxNoDoH) and left unlocked so the user can re-enable.
if ($FirefoxNoDoH) {
New-Item -Path "HKLM:\SOFTWARE\Policies\Mozilla\Firefox\DNSOverHTTPS" -Force | Out-Null
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Mozilla\Firefox\DNSOverHTTPS" -Name "Enabled" -Value 0 -Type DWord
Write-Host "[ok] Firefox DNS-over-HTTPS disabled (opt-in) -- ICANN-conflicting names now resolve via BCNR in Firefox too"
} else {
Write-Host "[info] Firefox DoH left on (BCNR-only names work anyway). To also reclaim names that exist in ICANN, re-run with -FirefoxNoDoH"
}
$state | ConvertTo-Json -Depth 5 | Set-Content $stateFile
Clear-DnsClientCache
Write-Host "[done] try: https://hello.bch (uninstall: .\setup\uninstall.ps1)"
Ariadne 0.1.1 + Theseus fetches it from silentmode.st (no more bundling) Ariadne 0.1.1 - install.ps1 primary TLD source: HTTPS $Indexer/api/tlds -> advertised[] (electrum fetchTldList / legacy fetchBcnrTlds / ariadne.config.json / bootstrap kept as fallbacks in that order). Silent installs no longer stall when WSS is blocked. - Persistent transcript at C:\ProgramData\Ariadne\install.log; separate install-error.log on any uncaught exception. Top-level trap logs the full stack, then exit 1 so Inno/NSIS silent-install callers see a real failure. - .iss: SetupLogging=yes; DeinitializeSetup() copies Inno's log to C:\ProgramData\Ariadne\inno-setup.log on every exit path. - Version bumped to 0.1.1. sha256=be1fa8841919b321841d90f8147abe1b1d7604fe7fff6c2e271dc47c4c24a2b6 Theseus decoupled from Ariadne - Removed nsis/installer.nsh (custom Ariadne chain-install page). - Removed extraResources entry for AriadneResolver-Setup-*.exe. - Removed build.nsis.include from package.json. - Settings > System-wide resolver panel now fetches the .exe from https://silentmode.st/releases-manifest.json, streams the download while hashing, refuses to spawn on SHA-256 mismatch. 30-min in-memory manifest cache so opening Settings doesn't spam the endpoint. Offline gracefully degrades to installedVersion-only / canUpdate:false. - "bundledVersion" IPC field kept for renderer compatibility; it now carries "latest advertised by the site's manifest". Deployed to silentmode.st: - dl.silentmode.st/AriadneResolver-Setup-0.1.1.exe (25 MB) - silentmode.st/releases-manifest.json (schema/2, updated 2026-09-08) - silentmode.st/releases/ + silentmode.st/tools/ show 0.1.1 Local Dev <noreply@localhost>
2026-09-08 01:27:51 +02:00
try { Stop-Transcript | Out-Null } catch {}