Back to list
Skywire Development Update — October 2, 2026
The second of October was the day the Skycoin wallet stopped being a separately served page framed inside the dashboard and became one of the dashboard’s own routes, compiled directly from the wallet project’s own source and sharing its cipher with the rest of the hypervisor. Getting there took eight separate changes to the wallet codebase itself, turning a standalone application into a module any host can mount, ahead of four more on the skywire side that wired it into place and then deleted the old framed page entirely. Alongside that, a single shared HTTP client for dmsg finally started reusing its own connections instead of paying a fresh relay negotiation for every request, which had been serializing the wallet’s own node queries behind each other badly enough to time out in a browser tab. A retained post-quantum key that should have been discarded the moment a handshake finished was found and cleared, and a folded dmsg server’s QUIC side was found leaking a goroutine per client once that client’s concurrent stream count passed quic-go’s own unannounced default limit.
Skywire: The Wallet Becomes a Page of the Dashboard
Eight changes to the wallet’s own codebase turned it from a standalone application into something another app can mount directly. skycoin#3073 moved every page, service and route into one self-contained module behind a new shell component that took over what the standalone app’s root component used to do — starting the cipher, showing node status, hosting the page outlet — with all nineteen of the wallet’s internal absolute links rewritten to resolve against a configurable base path rather than assuming it owns the whole origin. skycoin#3074 moved the wallet’s own images and fonts under a dedicated asset path so a host application can serve them without colliding with its own, and scoped every one of the wallet’s styles under one CSS class that adds no specificity of its own, verified pixel-identical against the standalone build before and after. skycoin#3075 dropped two Angular packages the framework itself had stopped publishing, swapping the wallet’s animation handling to the mechanism Material’s newer version actually wants.
skycoin#3076 turned on the same strict compiler flags the dashboard itself already compiles under, so that embedding the wallet’s source directly as dashboard routes wouldn’t immediately fail to build. skycoin#3077 found a dozen translation keys the wallet’s own templates referenced but which were simply missing from the English strings file, rendering as the raw key name instead of real text on the add-wallet button and the hardware-wallet dialogs. skycoin#3078 fixed the wallet’s text inheriting its color from whatever page hosts it, which read as white text on a light background the instant the wallet moved inside a dashboard that sets white text on its own body by default.
skycoin#3079 fixed the wallet’s cipher initialization returning nothing on a second call, which threw an exception and left the page blank the moment a dashboard visitor left the wallet route and came back to it, since a standalone wallet never has to handle being created twice in the same page load. skycoin#3080 removed a confirmation prompt that fired on every single page reload while a wallet was open, which dates from when wallets lived only in memory; they are saved to local storage as they change now, so a reload loses nothing but the unlocked state, and the prompt was blocking a reload of the entire host dashboard, not just the wallet.
5340 then compiled that wallet module directly into the dashboard as its own #/wallet route, synced automatically from whichever skycoin module version the dashboard’s own go.mod requires, so bumping that dependency is the entire wallet update going forward; an interceptor redirects the wallet’s own node API calls to existing hypervisor routes rather than a separate backend, and the hypervisor serves a dramatically smaller cipher build specifically for it.
5341 made that smaller cipher build possible in the first place: linking the wallet’s existing TinyGo-compiled cipher directly into the visor package had been exactly the kind of cross-module dependency an existing guard test forbids, so skywire’s own standalone skycoin web command now serves that same small TinyGo build directly — 1.35 megabytes rather than the roughly thirty-seven the full module would have cost, and it works in a plain source build with no module embedded at all.
5342 then retired the separately served wallet page entirely, now that the dashboard route replaces it outright, dropping the standalone serving flag, its config option, and the larger cipher role the desk no longer needs — shrinking the browser’s own wasm module by 3.2 megabytes in the process — while leaving the old address as a redirect for anyone who still has it bookmarked. 5343 fixed a run of dashboard asset paths that had been written as absolute from the site root, which is exactly wrong once the dashboard is served from a nested path inside the desk rather than its own origin; every font, background image and API path now resolves relative to the page itself, so nothing escapes the tab’s own virtual network trying to reach a path that doesn’t exist there.
Skywire: DmsgHTTP Reuses Its Connections
5344 found the shared dmsg HTTP client building an entirely fresh connection for every single request, which over a relayed path meant a fresh transport-discovery query for candidate relays, up to eight parallel relay dials, and a fresh handshake, paid again for every one of a dozen queries to the identical peer — in a browser tab specifically, those discovery queries were sent one at a time and simply queued behind each other until the later ones blew past the browser’s own timeout, which a goroutine dump during one such wallet session confirmed directly: sixteen of eighteen pending wallet requests sitting on the same client’s lock waiting their turn. The client now holds one reusable, keep-alive connection per destination visor and caches relay candidates for thirty seconds with concurrent lookups sharing a single query, which took twenty parallel wallet node requests from as long as five seconds, and the occasional outright timeout, down to well under a second.
5345 found the reward system specifically missing from the list of deployment services the visor already knows to reach directly rather than treating as an ordinary unseeded peer, so every dial to it tried and waited out a relay path it could never actually reach, past the hypervisor’s own ten-second response deadline — adding it to the list that both the native visor and the browser edge already share brought the rewards page from an empty reply to answering in about a second and a half. 5346 extended the resolving proxy’s own dmsg reach to try the visor’s existing skynet transports first, exactly the order DmsgHTTP itself now follows, falling back to a plain dmsg relay only when no such transport exists — available specifically to a resolver running under the visor’s own key, since those are the only transports it actually has standing permission to use.
Skywire: A Retained Key, and a Server That Ran Out of Streams
5337 found a post-quantum key that is supposed to be used exactly once, to decapsulate the other side’s handshake response, being kept alive on the connection’s own state for its entire lifetime instead of being discarded the moment the handshake that needed it finished — a heap profile of one board holding around twenty-four hundred live connections found a hundred and seventeen megabytes pinned by exactly that key, and a key retained that way lets anyone who can read the process’s memory recompute a supposedly-forward-secret session’s post-quantum secret from a ciphertext they captured earlier, defeating the entire point of generating a fresh key per handshake in the first place. The key is now dropped the instant the handshake completes, on both the post-quantum and the classical fallback path.
5335 found a folded dmsg server’s host sitting at up to two hundred percent CPU, nearly all of it garbage collection over a 1.7-gigabyte heap and ninety-five thousand goroutines, eighty thousand of which were blocked trying to open a QUIC stream to one specific client — that client had simply hit quic-go’s own unannounced default of a hundred concurrent streams per connection, a ceiling the older yamux-based carrier never imposed, and every request past that ceiling left a goroutine parked forever with no timeout at all. Both the limit and the open itself now carry sensible bounds, sixteen thousand four hundred and eighty-four concurrent streams and a ten-second timeout on opening one.
Skywire: Reporting a Desk That Never Starts
5347 gave the desk a way to describe its own failure to a server that would otherwise never know, specifically for the case of a phone nobody can plug a debugger into: until its own boot overlay is dismissed, the page now reports script errors, failed resource loads, and a boot that either rejected outright or simply never finished within two minutes, each report carrying the boot’s own status line, recent console output, the served version, and what the browser actually supports. 5349 fixed the very first report that reporter produced turning out to be a false alarm — an element with a genuinely empty src attribute, which resolves to the page’s own URL and fails for reasons that have nothing to do with anything actually being broken; such elements are no longer reported at all, and a real load failure now names the specific tag that failed.
5350 used the new reporting to diagnose and fix an actual stuck boot found through it: a page that loaded while the server it came from was mid-restart for an update could have its module download aborted partway through with no way to recover, since nothing had ever retried a failed spawn; it now retries with a short exponential backoff, refetching each time since a failed compile is never cached. 5348 re-staged the compiled command module from a clean tree so every one of today’s desk-facing changes — the wallet, the connection reuse, the boot reporter among them — actually reaches a source build’s own served desk rather than sitting unused in the repository until the next release rebuilds it automatically.
Skywire: Tours in Markdown, and a Dashboard Build With No Warnings
5336 moved both guided tours’ own wording out of source code and into plain Markdown files beside it, one step per heading, so editing a tour’s text no longer means touching the code that wires it to the page — a pair of tests still fail if a step referenced in the prose and a step wired in the code ever disagree with each other. 5338 and 5339 cleared out the dashboard’s build output entirely, converting every stylesheet off a deprecated import syntax and two now-removed Angular packages onto their current equivalents, verified by confirming the resulting compiled stylesheet is byte-for-byte identical to what the deprecated syntax had been producing all along.