Back to list

Development Update — July 30

The throughline today is the browser dmsg edge. A reachability campaign run down over the last stretch culminates in a fix to the deepest issue: a wss-only browser client was silently falling back to raw TCP it can’t dial, dead-ending connections that should have rendezvoused over WebSocket to the next server. That fix comes with a two-tier headless test harness so the browser edge — which the compile lane can’t cover — is finally regression-gated, plus an operator-run health probe that would have auto-caught the day’s real wss outage. The wallet also stopped shipping an 11MB copied tree and now serves straight from the vendored skycoin module, and the manager UI’s dependabot backlog was cleared in one batch. It was also the biggest Skycoin day in the window: all three Angular front-ends — the desktop wallet, skycoin-web, and the explorer — moved to Angular 22 and had strict TypeScript with strictTemplates turned on, new wallets began defaulting to bip44 (HD, multicoin), and a round of gnet and untrusted-input hardening landed underneath.

Skywire: The Browser Never Falls Back to TCP

3632 fix(wasm/dmsg): robust on-demand rendezvous — browser never falls back to TCP (+ live server discovery) fixes the core reachability bug. dmsg is a rendezvous network: a visor holds a few sessions and reaches a peer by opening an on-demand session to one of that peer’s delegated servers, DialStream trying the next on failure. But a browser/wss-only client fell back to raw TCP in two places a tab can never satisfy — the per-carrier dial-failure fallbacks (gated on Address=="" under the false assumption that js entries carry no TCP address, when discovery-resolved entries do), and pickCarrier’s final fallback — so a failed wss dial became a futile dial tcp …:30082: connection refused that dead-ended the attempt as dmsg error 202. The fix gates every TCP/QUIC fallback on hasCarrier(), so a wss-only client that can’t reach a server fails cleanly and the rendezvous moves on to the peer’s next server over wss; native clients keep the historic QUIC→TCP default. It also makes the seeded discovery client answer AllServers from the live discovery rather than the seed-only client, so a browser edge learns the whole deployment. 3634 fix(dmsg): browser client never falls back to TCP — robust on-demand rendezvous re-applies the rendezvous half of that work, which was orphaned when #3632 auto-merged its first commit before this one caught up — verified as the real fix, with live futile dial tcp attempts dropping 3→0. As a side effect, the honest wss errors it now surfaces (instead of masking them as TCP refusals) exposed the actual server-side breakage: two stale DNS records pointing at a dead shared proxy and one failed cert issuance.

Skywire: A Headless Test Harness for the Browser Edge

3637 test(dmsg,wasmhv): Tier A headless browser-edge regression gate + mdisc check wss health probe locks the reachability fixes in place with the browser profile — a wss-only dmsg client — exercised headlessly against real in-process dmsg servers as ordinary CI-gating go test: four e2e regressions on the on-demand rendezvous model, including the explicit “never fall back to a live, dialable tcp-only server” case that was the capability violation. It also adds skywire cli mdisc check, the operator-requested probe that would have auto-caught the day’s wss breakage — for every discovery server’s advertised AddressWS it DNS-cross-checks and does a plain HTTP/1.1 GET expecting 426 Upgrade Required, exiting nonzero when an advertised front doesn’t serve — wired into a 6-hourly scheduled workflow. 3638 test(wasm): Tier B headless smoke — run the REAL wasm-visor blob under Node (no browser) adds the runtime tier: a self-contained loopback dmsg server plus a Node harness that runs the actual compiled js/wasm binary via wasm_exec.js and asserts boot → ws dmsg session → in-wasm hypervisor /api answering — catching boot-glue, carrier-selection, and dispatch regressions the compile lane can’t. 3639 fix(wasm): populate SelfSummary mirror fields, flag host-stats N/A, serve empty app-logs cleans up three mirror-struct leftovers where a healthy browser visor rendered as broken: a long-running tab showing “0s uptime” (now stamps a real uptime and states its honest edge values), host-stats reporting fake 0% gauges (now flags available:false so the resources page shows N/A), and app-logs 404ing into an error dialog (now serves a valid empty result so the panel renders “no logs”). 3633 fix(wasm): mirror the subsystem log firehose into the node Logs page (/runtime-logs) closes a dual-surface divergence where the desktop log window read the full subsystem firehose while the Angular Logs page read only sparse step markers all hard-coded to “info”; a logrus hook now mirrors every subsystem line into the ring at its real level, taking /runtime-logs from a handful of markers to 78 mixed-level entries.

Skywire: The Wallet Serves From Vendor

3635 feat(wallet): serve skycoin-web straight from the vendored module (drop the copied tree) + vendor skycoin@1bb47440 does two things best landed together. It vendors skycoin at develop head, carrying two freshly-merged wallet PRs — a known-servers dropdown in Settings → Nodes, and new wallets defaulting to bip44 (HD, multicoin). And it stops keeping an 11MB copy of the built wallet at pkg/visor/static/wallet, synced by make embed-wallet: skycoin already exports its built wallet as an embedded FS, so visor.WalletUIFS() now serves it directly from the vendored module, the copy is deleted, and the embed-wallet target is removed — from now on a skycoin vendor bump is the wallet update, eliminating the “forgot to re-embed” staleness class and the build-ui wipe-and-restore dance. 3636 chore(deps): batch the open dependabot npm bumps for the manager UI clears all seven open dependabot PRs in one lockfile update — all transitive build-time deps of the manager UI, with the built bundle verified byte-identical — avoiding seven sequential rebase cycles.

Skycoin: The Angular Front-Ends Move to Angular 22

2976 build(deps): upgrade the Angular UIs to Angular 22 is the day’s foundation, and it deliberately doesn’t just merge Dependabot’s toolchain PRs. Those bumped @angular-devkit/build-angular to 22 while leaving @angular/core at 21 — a peer-broken, non-building upgrade — so this PR does the whole framework in lockstep instead: gui/static and skycoin-web go 21 → 22, the explorer 22.0 → 22.1, driven by ng update @angular/core@22 @angular/cli@22 @angular/material@22 (which ran the migration schematics and pulled TypeScript to 6). The hand fixes are the interesting part of a major bump: namespace imports (moment, Base58) become default imports because namespaces aren’t callable under TS6 module resolution, a MatTooltip directive moves to inject-based construction for Material 22, and strict is held off so the apps build — with a strict migration filed as the explicit follow-up. 2974 skycoin-web: fix the production build pins webpack to build-angular’s version so the wallet’s custom-webpack build resolves cleanly, and 2971 ui: rebuild embedded production bundles regenerates the checked-in dist bundles (this repo commits its built front-ends). A companion commit brought the explorer up to build under its Angular 22 dependencies.

Skycoin: Strict TypeScript, Everywhere

With the framework on 22, the strict migration deferred from #2976 landed across all three apps. 2970 explorer: enable strict TypeScript went first and fixed the resulting type errors; 2978 gui/static and 2979 skycoin-web then each enabled strict TypeScript plus strictTemplates — the compiler now type-checks template bindings, so a [isLoading]="'a string'" mistake fails the production build instead of surfacing at runtime — and fixed the errors that flushed out. This is the strict-typing baseline the following week’s shared-toolchain work would formalize.

Skycoin: Wallet Defaults and a CLI Underflow

2964 feat(wallet): default new wallets to bip44 makes the HD, multicoin-capable, xpub-exposing wallet type the default wherever it’s genuinely honored — Bitcoin (already bip44/native-segwit) plus the server-managed coins whose node does real bip44 derivation — while pure client-side non-Bitcoin coins like the in-browser Skycoin wallet stay deterministic, because their create path can only produce a deterministic wallet and a bip44 default there would mislead. A small defaultTypeForCoin() helper keyed on isBitcoin() || serverWallets drives it at both form init and coin-selection change. 2960 feat(wallet): known-servers dropdown adds a curated, coin-aware dropdown to Settings → Nodes → Change URL, so when a coin’s built-in default node is unreachable the user has a working fallback in one click — BTC offers a few public ssl:// Electrum servers — rather than a dead-end “leave empty for default” free-text field; the field stays editable and custom mesh URLs still work. A CLI fix closed a uint64 underflow when generating addresses for collection wallets.

Skycoin: gnet and Untrusted-Input Hardening

Three gnet fixes tightened the networking layer: 2977 fixes a data race in TestProcessConnectionBuffers, 2975 stops sendLoop busy-spinning on a closed WriteQueue, and a follow-up commit checks the write error in the closed-connection test case. 2973 harden untrusted-input handling turns a class of panic/log.Panic/unbounded-allocation paths on attacker-controlled input into bounded, error-returning ones with no behavior change for valid input: a compressed pubkey with X ≥ the field prime no longer panics secp256k1.PubkeyIsValid (reachable via wallet/xpub import), the scrypt-chacha20poly1305 decrypt bounds its metadata N/r/p so a crafted blob can’t force a 16–64 GB allocation before authentication, malformed wallet files error instead of panicking on reload, /api/v1/blocks bounds its range the way /last_blocks already did to avoid materializing the whole chain, and the CSRF signature is compared in constant time. 2965 chore(deps): batch #3 swept the remaining in-range Dependabot updates (skydex react19/vite8, explorer, go sqlite) to close the day.