Commit Graph
100 Commits
Author SHA1 Message Date
jwinterm 142b79ee27 fix(depends): tell the consuming build where the host Qt is
A cross Qt carrying qtdeclarative makes find_package(Qt6) demand a host Qt,
because QML needs host-side tools: qmlcachegen, qmlimportscanner and
qmltyperegistrar. depends already builds one. native_qt installs it to
native/qt-host, and qt.mk passes that path to the cross Qt's own configure.

What nobody passed it to was wowlet. Qt6Config re-runs the host-path setup when
our project calls find_package, finds nothing, and stops with "To use a
cross-compiled Qt, please set the QT_HOST_PATH cache variable". The Windows
cross build has failed that way on every tag since qtdeclarative landed in
June, which is why 5.1.4 shipped macOS and Linux but no exe.

Stating it in the toolchain rather than in the workflow fixes every cross
target and anyone building locally through depends, and the built-cache key
already hashes this file, so the stale mingw tree is rebuilt rather than
restored without the host Qt.
2026-09-13 18:06:55 -04:00
jwinterm a43e9fe122 fix(ci): publish tag builds to the release, where they can be fetched back
Run artifacts upload fine, but this Gitea reports zero artifacts for every run
through its REST API, and the web download route answers "Not found." under
token, bearer and basic auth alike. A signed build was therefore unreachable
from anywhere except the browser session that produced it.

Release assets do work: create, upload, list and download all round-trip with
an ordinary token, so tag builds now attach their output to the tag's release
as well as to the run. Retrieval must use browser_download_url; the asset-id
API path returns the asset's JSON metadata even when asked for octet-stream.

The step is fail-safe on purpose. With no token, no resolvable release, or a
non-201 upload it explains itself and exits 0 rather than turning a green
build red. The macOS upload also gains if-no-files-found, without which an
empty publish passes silently.
2026-09-13 13:18:22 -04:00
jwinterm ce84b1d062 fix(ci): scope the embed extracts to the run, not to a shared /tmp
ubuntu-latest and windows-latest both resolve to the same host in host mode,
and both jobs began with `rm -rf /tmp/wownerod-embed`. Dispatched together for
5.1.4, the Windows fetch deleted the Linux job's binary in the eight seconds
between its own `ls` showing the file present and cmake configuring, so the
Linux build died on "WOWNEROD_DIR was specified but the wownerod binary could
not be found" while the identical workflow had passed minutes earlier when it
ran alone.

Both jobs now extract under /tmp/wowlet-$GITHUB_RUN_ID, so concurrent runs stop
sharing state. macOS is left alone: it runs on its own host, it never rm -rf's
the directory, and it is the one platform currently building green.
2026-09-13 13:13:35 -04:00
jwinterm 0e6113729d chore(release): 5.1.4
Carries the binary rename: the shipped executable, the macOS bundle and the
Linux desktop entry are all wowlet now, where 5.1.3 still shipped feather.
2026-09-13 13:03:50 -04:00
jwinterm ea9c73826b fix(build): ship the binary as wowlet, not feather
The CMake target keeps its upstream name so the twenty-odd target_* calls stay
put, but OUTPUT_NAME now produces build/bin/wowlet, and on macOS a wowlet.app
whose CFBundleExecutable matches it.

Linux and Windows already renamed the artifact as they copied it, so their cp
lines just move to the new path. macOS copied the whole bundle instead, so it
shipped Contents/MacOS/feather with a Feather name in the Info.plist, which is
what anyone installing it actually saw. The Linux install rules had the same
problem one level down: they installed feather.desktop, which sets Exec=feather
and Name=Feather Wallet, while the correct wowlet.desktop sat unused beside it.

CFBundleIdentifier moves to org.wownero.wowlet. Nothing in signing or
notarization reads it, but macOS keys per-app state by bundle id, so an existing
install starts with fresh window state.
2026-09-13 10:49:00 -04:00
jwinterm 5a9605c87b release: wowlet 5.1.3
Carries the macOS QML bundling fix, so the mining tab loads on mac instead of
painting grey, and the mining offer restricted to a node that is ours.
2026-09-12 20:57:13 -04:00
jwinterm db151c2920 fix(ci/macos): bundle the QML modules the app actually imports
5.1.2 shipped a grey mining tab on macOS while Linux was fine. The app said
why: 'qrc:/qml/mining.qml:2:1: module "QtQuick.Layouts" is not installed',
and Contents/Resources held only appicon.icns and qt.conf, with no qml
directory at all. macdeployqt cannot scan .qrc resources, and it was called
without -qmldir, so the bundle shipped no QML modules; scene.qml survived only
because it imports nothing beyond QtQuick.

Pass -qmldir, then blanket-copy the QtQuick and QtQml trees as the AppImage
build already does, because qmlimportscanner does not follow a module's own
qmldir depends chain. Both happen before the dylib passes so new plugin deps
resolve, and before signing, which already sweeps every non-framework Mach-O.
A guard fails the build when a module is missing, because an absent QML module
is invisible until someone opens the tab.
2026-09-12 20:49:23 -04:00
jwinterm c7fca31653 fix(mining): only offer to mine on a node that is ours
Start Mining was live regardless of which daemon the wallet was talking
to. It is a `start_mining` RPC to the connected node, so on a remote one
it is either refused — the button appearing to do nothing — or, if the
operator left the RPC open, it sets someone else's machine mining to our
address. Neither is a thing a wallet should offer.

The axe now greys out unless `Nodes::connection().isLocal()`, hovering it
explains why, and clicking anyway flashes the same notice rather than
silently doing nothing. `onStartMining` refuses too: the QML disables the
control, but a signal is not a promise.

isLocal() counts localhost, .local, 127/8 and the RFC1918 ranges, so the
embedded node and a daemon on the LAN both qualify.

Claude-Session: https://claude.ai/code/session_01VLQ5DsgKv23osGANoFT3zF
2026-09-04 05:36:45 -04:00
jwinterm 081c01ada9 release: wowlet 5.1.2
Claude-Session: https://claude.ai/code/session_01VLQ5DsgKv23osGANoFT3zF
2026-09-03 15:12:27 -04:00
jwinterm 613d4e7f61 Merge scene work for 5.1.2
The ambient scene grows up: the hidden-tab bug that rained +1s out of an
empty sky is fixed at both ends, the wipeout is a skid rather than a
stunt, clearing a field says WIN, and each tab gets its own amount of
scene — History runs, Receive sits, Send is money going past.

Claude-Session: https://claude.ai/code/session_01VLQ5DsgKv23osGANoFT3zF
2026-09-03 15:12:18 -04:00
jwinterm 79daae6796 fix(send): the scene sits in the middle of the space below the form
It was butted straight up against the Clear/Send row, so a band of night
sky touched a button and read as part of the form. Now there is a fixed
14px gap under the buttons and a stretch either side of the scene, which
centres it in whatever space the form leaves.

And the coins come in handfuls. One at a time reads as a metronome, so
Send now has three of them: usually one goes past, sometimes two, and
about one time in seven all three, staggered by a beat so they arrive
together rather than in a rank. Each rolls its own height, size, duration
and spin direction.

Claude-Session: https://claude.ai/code/session_01VLQ5DsgKv23osGANoFT3zF
2026-09-03 15:10:48 -04:00
jwinterm b1e751a6b7 fix(scene): the sitting doge belongs to Receive only
He was filling History's empty beat as well, left over from before
Receive had a scene of its own. Two tabs showing the same sitting doge
reads as one tab's scene leaking into the other, and History is meant to
be the tab where he runs.

History's opening beat is now sky, grass, clouds and the sun — the scene
breathing before the coins come out — and the sitting doge appears on
Receive and nowhere else. The per-lap idle roll goes with him.

Claude-Session: https://claude.ai/code/session_01VLQ5DsgKv23osGANoFT3zF
2026-09-03 15:04:41 -04:00
jwinterm 068e4c2aa5 fix(scene): money no longer vanishes mid-flight, and the quiet tabs have something to watch
Send's bills were being cut off halfway across. Money mode reused the
run's lap machinery, so every 9-14 seconds the cycle restarted and reset
every bill to the start of its flight — and a roll whose delay plus
duration ran past the cycle simply disappeared wherever it had got to.

Bills now keep their own clock: cross, re-roll, wait, cross again, with
the re-roll deciding afresh whether that bill flies at all. Nothing
resets them from outside, so nothing can cut them short, and the sky
thins and fills instead of carrying identical traffic for ever. 26
seconds of frames now contain no mid-screen disappearance.

Both quiet tabs get an ambient clock, because a form is a long time to
look at a dog breathing:

  * Send: a gold coin arcs across on its own trajectory now and then,
    bills tumble in proportion to their speed, and at night the odd
    shooting star.
  * Receive: a coin drops out of the sky, bounces, and settles in the
    grass beside the doge with a small sparkle burst — a coin arriving is
    the entire point of that tab — and he perks up when it lands. Birds
    fly by in daylight. It lands to one side of him and clear of the sun,
    which is where the first version put it.

Claude-Session: https://claude.ai/code/session_01VLQ5DsgKv23osGANoFT3zF
2026-09-03 14:17:54 -04:00
jwinterm f1144c483e fix(scene): the wipeout is a skid, the win says so, and each tab gets its own amount of scene
The crash launched him. Rotating 66 degrees about a pivot inside the
sprite, shearing him through the middle and scaling him about the same
point left him diagonal in mid-air, elongated, nowhere near the ground —
a stunt, not a trip.

It is now a face-plant and a skid: 26 degrees, a 21px drop so the snout
reaches the grass, and 26px of forward slide along the ground with the
dust coming up. The shear is gone entirely. The pivot is the snout at the
grass line rather than a point inside the body.

The other half of looking airborne was the frozen frame: stopping a run
cycle leaves whatever mid-stride pose the gif was on, legs extended. He
now lands on frame 4, the one with the legs tucked under him.

Clearing the field and getting across now says WIN, with the tally, the
way eating it says GAME OVER. Before, a won lap just ended and the next
one opened with a doge sitting down, which reads as nothing having
happened.

And the scene comes in three amounts, because a form should not have to
compete with a dog: History runs the whole thing, Receive is a doge
sitting in the field, Send is money blowing past and nothing else. One
QML file, gated by mode; the beat machine only runs where there is a run.

Claude-Session: https://claude.ai/code/session_01VLQ5DsgKv23osGANoFT3zF
2026-09-03 13:07:04 -04:00
jwinterm e5b8ef6a00 fix(scene): park hidden tabs, and put some weight behind the doge
The +1s raining out of an empty sky came from a scene running on a tab
that had never been shown. An unshown QQuickWidget is 0px wide, and at
0px every coin sits at x=0, so the doge "collected" the whole field in
one step; the pickup pops from that phantom lap were still mid-flight
when the tab was finally selected and the real width arrived. Their
`SequentialAnimation on opacity { running: <bound> }` was cut off by the
width change, which leaves the property wherever it stopped — so a +1
hung in the air for the rest of the lap, next to a coin nobody had
taken.

Both halves are fixed:

  * SceneWidget parks its scene on hide and starts a fresh lap on show,
    and the QML refuses to run at all until it has been laid out. A
    background tab now costs nothing, too.
  * Every one-shot flourish (+1, bark, dust, GAME OVER) is started and
    reset from an explicit handler, so an interrupted lap cannot strand
    one on screen.

The rest is the ambient scene earning its keep:

  * The face-plant has weight. He tips over his front paws — pivoting on
    the paw at the grass line, not the middle of the sprite, which used
    to swing his snout through the ground — squashes at the nose, bends
    through the body, throws dust off the impact, and lies there
    breathing. GAME OVER now lands a beat later so the crash reads on
    its own, and the lap ends shortly after instead of running out the
    clock on a wreck.
  * He has opinions: HRNMMROOF, BONK, SNOOT.EXE and friends on a
    wipeout; MUCH COIN, AMAZE, VERY WIN when he clears the field, with a
    victory hop to go with it.
  * More variety per lap: zero to three bills at their own speeds and
    heights, a 1-in-3 fat +5 coin with a halo, a doge sitting in the
    field during the empty beat, drifting clouds, a soft corona on the
    sun, blinking stars and the odd shooting star at night, birds by
    day, and a run speed that is no longer always eight seconds.

Verified by rendering scene.qml headless (qml6 + xvfb, frame grabs) at
the real widget sizes, and by driving two scenes through a QTabWidget to
watch the hidden-tab case before and after.

Claude-Session: https://claude.ai/code/session_01VLQ5DsgKv23osGANoFT3zF
2026-09-02 22:34:23 -04:00
jwinterm b200d997b0 fix(ci): write ZIP entry names with forward slashes
Compress-Archive on Windows PowerShell writes the OS path separator into entry
names, so the archives came out with "tor\tor.exe". The ZIP format mandates
forward slashes, and 5.1.0 shipped "tor/tor.exe" from `zip -X` on Linux -- this
was a regression introduced when the packaging moved to the signing host.

It is not cosmetic for this application. Extractors that take the backslash
literally produce a file named "tor\tor.exe" in the archive root rather than a
tor directory, which puts the bundled Tor somewhere wowlet does not look. The
daemon is given an exclusive --tx-proxy, so a wallet that cannot find its Tor
cannot relay a transaction at all.

Archives are now built through System.IO.Compression with entry names
normalised explicitly, and the job asserts the result: a backslash in any entry
name, or a missing tor/tor.exe, fails the build rather than shipping.

Caught by extracting the artifact and diffing it against the 5.1.0 release
before publishing.
2026-09-01 10:23:07 -04:00
jwinterm 11e8e3241c ci(gitea): move the Linux AppImage off GitHub, and ship both Windows archives
Linux: the x86_64 AppImage now builds on the Gitea runner. Unlike the Windows
lane, which builds a static toolchain of its own through contrib/depends, it
links against the host's Qt6 -- so those dependencies are owned by such-fleet
(roles/wowlet_build_host) and the job asserts them rather than apt-installing.
A workflow that installs needs sudo on a shared runner and makes the build
host's contents a property of whichever job ran last.

Windows: the lane now publishes two archives instead of one. Authenticode
mutates the exe, so a signed binary can never byte-match a build someone
reproduces from source. Shipping only the signed one quietly costs the project
its reproducibility story; shipping only the unsigned one costs every normal
user a SmartScreen warning. Both, with both hashes in the PGP-signed
hashes.txt, costs neither -- and keeps one canonical download page rather than
splitting the project across a fork.

The AppImage lane carries the packaging knowledge that a plain linuxdeploy run
does not: qmlimportscanner does not follow a module's own qmldir dependency
chain, so the QtQuick and QtQml trees are copied wholesale and each copied
plugin's Qt libraries resolved by hand, and a guard fails the build if
mining.qml ever imports QtQuick.Controls again rather than shipping a white
mining tab.
2026-08-31 18:23:46 -04:00
jwinterm f5e40ab5b2 ci(gitea): pin the artifact actions to v3
The first Gitea run built cleanly all the way through -- depends, wowlet.exe,
staging -- and then died on the last step:

  ::error::@actions/artifact v2.0.0+, upload-artifact@v4+ and
  download-artifact@v4+ are not currently supported on GHES.

Gitea Actions implements the older artifact protocol, so the v4 actions (which
use @actions/artifact v2) refuse to talk to it. Hash Bags' Windows lane already
uses v3 for the same reason.

Pinned with a comment so nobody upgrades it back and loses a 22 minute build to
the same error.
2026-08-31 18:15:46 -04:00
jwinterm 3231bc5df2 release: wowlet 5.1.1 2026-08-31 18:13:05 -04:00
jwinterm 0ce230de3c ci(gitea): move the Windows build and signing off GitHub
Gitea is master and GitHub is a mirror, but the Windows and Linux jobs still
only existed in .github/workflows, so GitHub was doing real build work. This
moves Windows.

Two jobs on two machines, which is the point rather than an accident:

  build  runs on `deb` (windows-latest:host — it carries the MinGW
         cross-compiler) and produces an unsigned wowlet.exe.
  sign   runs on desktop-iim2fs2 (windows:host), the machine with the EV
         code-signing token physically in it.

The signing job does not itself sign. Its runner is NT SERVICE\act_runner,
which cannot use the token: SafeNet holds the login per user and the login is
established interactively by an operator. So the job queues the binary for the
Fleet-installed broker (roles/windows_code_signing) and waits. CI never holds
the key and never holds the token password, so it cannot spend one of the
token's three password attempts.

Differences from the GitHub lane, all because this is a real fleet host rather
than a disposable hosted runner:

- No apt install and no sudo. Every dependency is already present on deb, and a
  first step asserts the toolchain — including that mingw is the posix
  threading variant — and fails pointing at such-fleet rather than half
  building.
- No disk-freeing or fallocated swap. Those existed to survive a hosted
  runner's 16G/14G budget; deb has 30G and 3.1T free.
- depends builds at -j4 and wowlet at -j6 rather than -j2 for the same reason.

The exe is staged unzipped between the jobs because the broker signs one PE at
a time; the published zip is assembled after signing, so the archive contains
the signed binary. The signature, its RFC 3161 timestamp and the expected
signer are all re-verified on the artifact that actually ships.

Dispatch-only: both runners are capacity 1 and shared with other lanes.
2026-08-31 17:54:02 -04:00
jwinterm 252b358baa feat(scene): per-lap variety, the occasional face-plant, and a sky per tab
Every tab was running the identical eight seconds forever. Three changes:

- Each lap rolls its own timing: 3-5s of empty field, and the money now enters
  on its own delay at its own pace instead of shadowing the doge every time.
- Roughly one lap in six the doge eats it partway down the field: he tips
  nose-first onto the grass, GAME OVER comes up, and the coins he never reached
  are still sitting there. Costs no new art — it is the running sprite pivoted
  on its own feet.
- A `variant` on SceneWidget picks the sky: dusk (History, lock screen), dawn
  (Receive), night (Send, with stars and a moon instead of the sun).

The cycle is now a timer-driven state machine rather than one SequentialAnimation.
That is not stylistic: a lap that rolls its own durations has to assign them
somewhere, and assigning a duration to a child of a *running* SequentialAnimation
makes the group recompute and re-enter its own ScriptAction until the JS stack
blows. Qt flags the binding form of the same mistake as a binding loop.

Verified by headless qml6 render: a forced trip lap, and a clean run with no QML
warnings.
2026-08-31 13:23:41 -04:00
jwinterm dd76a7c4bf chore: gitignore the generated wownerod embed
The build stages the wownerod binary into src/assets/wownerod/ and generates
src/assets_wownerod.qrc, exactly as it does for tor and docs — but only the tor
and docs paths were ignored. A `git add -A` in a build tree therefore offered a
24MB binary and a generated qrc for commit. Ignore them the same way.
2026-08-31 12:49:06 -04:00
jwinterm 9bd8cb0676 feat(send,receive): the ambient scene, as a layout item this time
Send had a large empty region under the form doing nothing, and Receive had
nothing at all. Both get the scene back — but as real layout items, not as the
overlay that painted over the forms last time.

Send: the form only ever needed the top of the tab, so the QFormLayout is now
wrapped in a vbox and the scene takes the rest. The widget's vertical size
policy was Maximum, which made it hug the form; it owns the whole tab now. The
form itself is untouched, and nothing is drawn on top of the address or amount
fields.

Receive: a short banner under the address table.

Built and smoke-tested from the AppImage lane.
2026-08-31 12:48:41 -04:00
jwinterm 48a8c36135 feat(scene): give the loop three beats — empty, coins pop in, then the run
The lap ran flat out and reset the moment the doge left the frame. It now
breathes:

  1. ~4s of empty field, nothing but sky and grass
  2. the coins pop in one at a time (320ms apart)
  3. the doge and the money cross, and the doge collects them

Both coin states stay derived from the cycle rather than tracked: a coin is out
once `coinReveal` passes its index, and collected once the doge's snout reaches
its centre. Dropping `coinReveal` to 0 and `runProgress` to 0 at the top of the
loop therefore restores the whole field with no reset bookkeeping, and parks
the doge and the money off the left edge for the empty beat at the same time.

The money now crosses with the doge instead of drifting on its own clock, a
little quicker so it leads him off screen, and it sits proportionally in the
sky so a tall scene does not pin it to the top edge.

Verified by headless qml6 render across a full cycle at 1000x200.
2026-08-31 12:48:41 -04:00
jwinterm 19c946c705 fix(mining): pin the console so Block Height / Sync Progress stay inside it
The metrics kept sliding out of the bottom of the node console. The cause was
free height, not margins: the top bar's RowLayout, its right-hand ColumnLayout
and the console RowLayout all defaulted to fillHeight, so any slack in the
window was absorbed by the console. The 102px bezel graphic stretched with it
(topright_middle is a 1px column tiled horizontally), the label/value rows —
two fillHeight halves — spread apart with it, and a full block height ended up
rendered below the panel. The three `Layout.preferredHeight: parent.height`
bindings, which asked a layout child for its own parent layout's height, made
the result depend on resolution order.

Now the top bar, its column and the console are pinned to their design heights
(128 / 128 / 102), the bezel images take the literal 102, and the metrics are a
plain anchored Row of two Columns at a fixed offset inside the console's dark
interior band (rows 7..94 of the bezel) with the value directly under its
label.

Verified by headless qml6 render at 1029x{500,597,650,720,800} with a full-width
block height ("369918/369918"): the pair sits in the same place at every height
and stays inside the panel.
2026-08-31 12:15:11 -04:00
jwinterm 1828353d52 fix(send,receive): drop the corner doge that painted over the forms
IdleDoge scaled its movie from `currentImage()` after `jumpToFrame(0)`, but the
first frame is not decoded at that point, so the size came back null, the
scaling was skipped, and the QLabel ended up at the GIF's full 500x397. Parked
at the bottom-right of the form it painted an opaque 500x397 slab of window
background over the lower half of Send and over the Receive address table.

Send is the screen where money leaves the wallet; it does not get an overlay
sitting on top of the address and amount fields at all. Receive loses it for
the same reason. SendWidget.cpp and ReceiveWidget.cpp are back to exactly their
pre-ambient state, and the widget is removed rather than left unused.

The ambient scene keeps the places where it has its own real estate: the lock
screen, the History banner, and the mining tab.
2026-08-31 12:15:00 -04:00
jwinterm 2a54663f76 fix(scene): the doge collects the coins, and no more slow first lap
Three things you spotted on the History banner:

- Slow first lap that restarted at speed. The dog and the money animated
  `to: scene.width`, and the QQuickWidget starts at a placeholder width: the
  first lap crawled across the wrong distance, then the real width arrived,
  re-bound `to`, and restarted the animation. Motion is now driven by a
  unitless 0..1 progress and mapped onto the current width each frame, so a
  resize repositions without restarting.

- Coins sat mid-sky and clipped the top border. They now rest on the grass
  with a low bob, at the doge's pickup height.

- The doge collects them. A coin is collected once the doge's snout reaches
  its centre: it pops, fades, and floats a "+1". The collected state is
  derived from the run position, so the coins simply come back when the lap
  restarts, with nothing to reset.

Reduced motion still gets a static field: doge parked at the left, every coin
present, money parked in the sky.

Verified by headless qml6 render at banner (1000x140, 620x120) and lock-screen
(900x380) sizes, motion and reduced-motion, with no QML warnings.
2026-08-31 12:14:46 -04:00
jwinterm 6942cbb459 feat: ambient silliness across the app (reduced-motion aware)
- Lock screen: full ambient scene above the unlock form (the idle 'screensaver'
  — wallet auto-locks here) instead of a thin banner.
- History ('home'): full scene as a top banner.
- Send/Receive: IdleDoge — a small click-through sitting doge in the corner,
  the 'most quiet' idle for task screens.
- Mining keeps its own scene.
All gated by Config::reducedMotion (scenes freeze, doge shows a still frame).
2026-08-31 11:10:25 -04:00
jwinterm df4711d1c1 feat: ambient scene system + unlock-screen banner (reduced-motion aware)
Reusable SceneWidget (QQuickWidget host) loads scene.qml — dusk sky, tiled
grass, running doge, bouncing WOW coins (slowed per feedback), drifting
money — and feeds it Config::reducedMotion so it freezes to a still when
that's set. First placement: a banner atop the unlock form. Scene rendered
& verified at banner + screensaver aspects via local qml6 harness. Assets
from wow-lite-wallet (friend's). Home banner / idle screensaver / per-tab
idle to follow on the same SceneWidget.
2026-08-31 10:22:47 -04:00
jwinterm 7b71f5dc9a feat: 'Prefer reduced motion' setting (accessibility / animation opt-out)
Config::reducedMotion (default false = playful animations ON). Surfaced as a
checkbox on first run (wizard PageMenu) and in Settings → Appearance —
unchecked by default, matching the OS 'Reduce Motion' convention. The mining
tab's AnimatedImages now freeze when it's set (MiningBackend exposes it to
mining.qml). Foundation for gating the ambient silliness to come.
2026-08-30 12:36:15 -04:00
jwinterm 0ed8c005c5 mining tab: tighten Block Height/Sync Progress label+value grouping
The value sat ~30px below its label (label centered in top cell, value
centered in bottom cell), so long values like the block height floated low
in the console. Anchor labels to the bottom of their cell and values to the
top of theirs so each metric reads as a tight pair. Verified via local
qml6 render.
2026-08-30 12:00:44 -04:00
jwinterm 1c81365247 feat(splash): random silly loading GIF (wow-lite-wallet tradition)
The wallet-open splash now shows a random loader from a bundled set (13
curated GIFs from wownero/wow-lite-wallet, ~2.2MB) instead of the static
key icon — auto-discovered from :/silly, aspect-scaled to 56px, falls back
to the key pixmap if none present. Assets by a friend (same Wownero family).
2026-08-30 10:56:37 -04:00
jwinterm c65c12d328 release: wowlet 5.1.0
- macOS: first native signed + notarized build (new platform → minor bump)
- fix: stuck-tx detection + rebroadcast + re-relay on daemon sync
  (resolves the 'unconfirmed for days' field report)
- mining tab: top text layout fixes
2026-08-30 06:36:44 -04:00
jwinterm 38c63088b5 Merge macOS build lane: native signed+notarized Gitea build
Brings .gitea/workflows/build-macos.yml (brew-native compile, embedded
wownerod+Tor, static boost, bundled image codecs, Developer ID sign +
notarize) and the portable cmake tor/wownerod copy fixes.
2026-08-30 06:36:23 -04:00
jwinterm 3d38fdd135 ci(macos): bundle Qt image-plugin dylib deps (webp/sharpyuv/brotli) for clean-Mac runtime
macdeployqt bundles Qt frameworks but not the plain @rpath/*.dylib brew
deps of its image plugins, so a no-Homebrew Mac couldn't load webp. Add a
Qt-safe pass that resolves @rpath/*.dylib (never @rpath/*.framework) from
brew, copies them in, rewrites load paths, and fails the build if any
remain. Sign step now re-signs by Mach-O type (not exec bit) so the
install_name_tool-modified plugins get valid signatures.
2026-08-30 05:34:04 -04:00
jwinterm f2c3ce45a0 ci(macos): link boost statically (Boost_USE_STATIC_LIBS=ON)
The 100%-linked app dynamically referenced brew's libboost_*.dylib, which
macdeployqt failed to bundle — the app would fail to launch on any Mac
without Homebrew (notarization doesn't check runtime dylib resolution).
Static boost matches how guix/depends release builds work and removes the
runtime dependency entirely.
2026-08-30 05:08:01 -04:00
jwinterm 87d5977243 ci(macos): CPATH/LIBRARY_PATH to brew prefix so feather finds boost headers
monero's static libs built fine, but the feather target includes monero
headers pulling boost/variant.hpp, and clang doesn't search
/opt/homebrew/include by default (modern BoostConfig leaves
Boost_INCLUDE_DIRS empty).
2026-08-30 04:55:20 -04:00
jwinterm 9e6d85c246 ci(macos): disable Trezor (USE_DEVICE_TREZOR=OFF)
brew's protobuf pulls Abseil headers that require C++17, breaking the
feather compile (DEVICE_TREZOR_READY gates the protobuf link). Trezor
hardware does not support Wownero, so this removes a useless dependency
rather than working around it — the Linux lane only tolerates it because
its depends system pins an old protobuf.
2026-08-30 04:42:14 -04:00
jwinterm 49b3264b0e cmake: portable tor/wownerod copies — BSD cp lacks -u (exit 64 evaded the ret==1 check, silently shipping without embedded node/tor); fail on ANY nonzero cp exit 2026-08-29 14:38:24 -04:00
jwinterm 3cf58f0313 cmake: mkdir src/assets/tor before the TOR_DIR copy (untracked dir; BSD cp usage error evades the ret==1 check) 2026-08-29 14:28:09 -04:00
jwinterm 0f6892c123 ci(macos): ad-hoc sign tor before embedding — arm64 macOS SIGKILLs unsigned binaries, including the runtime-unpacked copy on user machines 2026-08-29 14:17:26 -04:00
jwinterm 1fedbf0faa ci(macos): ship libevent dylib next to tor (@executable_path linkage) 2026-08-29 14:06:15 -04:00
jwinterm 410df0c8ff ci(macos): extract wownerod into an explicit dir — find(1) does not descend the /tmp symlink 2026-08-29 13:55:16 -04:00
jwinterm 1853ebf558 ci(macos): disable pipefail around yes|brew (SIGPIPE 141 when brew asks nothing) 2026-08-29 13:47:37 -04:00
jwinterm a2b34f5ebc ci(macos): embed tor (expert bundle 15.0) — arms daemon --tx-proxy via HAS_TOR_BIN, parity with linux lane 2026-08-29 13:44:28 -04:00
jwinterm 27f694c4bd mining tab: fix top text layout — anchor conflict on sync value, oversized fonts, bezel overflow
- Sync Progress value had both left and horizontalCenter anchors (drifted center)
- 20pt labels in 30px rows collided; now 14pt matching the top-left monitors
- hashrate/uptime/height values auto-fit their pixel-art frames (HorizontalFit)
- 'uptime' -> 'Uptime'
2026-08-29 13:43:05 -04:00
jwinterm c7333a775c Merge fix/stuck-tx-detection: broadcast-failure detection, stuck-tx warning + rebroadcast, re-relay on daemon sync 2026-08-29 13:41:32 -04:00
jwinterm 8b846a8dc0 ci(macos): pin CMAKE_PREFIX_PATH to brew qt6 (qt@5 keg coexists unlinked on the runner) 2026-08-29 13:37:41 -04:00
jwinterm dc5f940801 ci(macos): pipe yes into brew — Homebrew 6 prompts for dependency installs regardless of NONINTERACTIVE 2026-08-29 13:27:05 -04:00
jwinterm 36d878e7bf ci(macos): also skip dependent upgrades in brew install 2026-08-29 13:16:13 -04:00
jwinterm a526061d97 ci(macos): place appicon.icns into the bundle 2026-08-29 13:15:24 -04:00
jwinterm f4c5ec3c25 ci(macos): non-interactive brew 2026-08-29 13:10:03 -04:00
jwinterm 1217ce174c ci(macos): sign + notarize with Developer ID cert via desktop-lane secrets 2026-08-29 12:17:21 -04:00
jwinterm 914fa1ed32 ci: native macOS lane for the Gitea self-hosted runner
Dispatch-only workflow in .gitea/workflows (GitHub ignores the
directory): brew dependencies, native cmake build with the embedded
wownerod fetched per-arch, unsigned app bundle artifact. Runs on the
mac runner whose work dir lives on DataSSD and is outside every backup
path. Signing/notarization follows once a Developer ID Application
certificate is provisioned as repo secrets.
2026-08-29 07:04:39 -04:00
jwinterm a3509a6c3b Detect stuck outgoing transactions and re-relay after daemon restart
Field report: a send sat 'in mempool' for two days while the network had
never seen it (Tor down at send time defeats both the multi-broadcast and
the embedded daemon's exclusive --tx-proxy relay), locking the change.

Three additive changes, all strictly local (no txid is ever queried
against an external service):

- onMultiBroadcast now counts relay responses; if no node accepted the
  broadcast within 45s the user is told immediately and offered the
  existing rebroadcast path, instead of silence.
- A periodic local history scan warns once per outgoing tx that has been
  pending for more than 25 minutes, again offering rebroadcast (which
  already reconnects to a fresh node first).
- On DaemonManager::synced, still-pending outgoing txs are re-announced
  from the wallet's own tx cache; a restarted embedded node's pool has
  forgotten them.
2026-08-29 06:13:06 -04:00
jwinterm 93d13a6568 v5.0.3: harden embedded-node restart handling + version bump
On top of Lucas's #119 (--db-sync-mode safe):
- DaemonManager: age out the crash-retry budget (m_restarts) so legit node
  toggles/restarts don't trip "maximum retries exceeded" after ~4 spawns over a
  session; the cap now only bites a genuine rapid crash-loop.
- DaemonManager: clear the m_stopping latch on start(), so the crash auto-restart
  keeps working after the node has been toggled off then on (it was a one-shot
  before).
- bump version 5.0.2 -> 5.0.3.
2026-06-27 13:10:54 -04:00
jwinterm e3ba9c7bad v5.0.2: hide hardware-restore option + version bump
- wizard: hide the hardware-device wallet option (wownero has no Ledger/Trezor
  support; inherited Feather cruft).
- bump version 5.0.1 -> 5.0.2.

v5.0.2 also rebuilds the Linux AppImage in an ubuntu:24.04 container (glibc 2.39)
so it runs on Ubuntu 24.04 / Mint / Debian — v5.0.1's AppImage was built on
glibc 2.43 and would not start elsewhere. No wallet-code change: wallets created
on pre-table-fix builds carry a stale restore height (blank balance); the fix is
to re-restore from seed.
2026-06-25 09:19:19 -04:00
jwinterm 6cd7e8bad9 fix: regenerate stale restore-height table (fixes vanishing balance)
restore_heights_wownero_mainnet.txt was last updated 2023-12-15 (h587048).
For wallets created after that, RestoreHeightLookup::dateToHeight extrapolates
forward at 288 blk/day; 2.5y past the last anchor overshoots the chain tip, so
the computed restore height lands ABOVE the current height. The wallet then
skips output-scan on every real block => received funds are never recorded,
while the tx pool still shows them: coins appear pending, then vanish.

Same bug class as 8686e9bf (which fixed the block-time CONSTANT from monero's
120s/720-per-day to wownero's 300s/288); here the constant was right but the
TABLE went stale. Regenerated with contrib/generate-restore-heights/heights.py
to h849000 (2026-06-19). Verified dateToHeight < tip for all dates 2019..today.
2026-06-23 21:25:18 -04:00
jwinterm 0d5d745311 v5.0.1: Windows QtQuick crash fix + node/Tor lifecycle overhaul
Windows crash chain (exposed by the embedded-node default):
- main.cpp: force the QtQuick software renderer. The Mining tab's QQuickWidget
  drove the default RHI/GL path and faulted (0xc0000005) on broken-GL hosts
  (VirtualBox VMSVGA), crashing the app and orphaning the embedded node.
  Real hardware was unaffected.
- ChildProcessGuard + DaemonManager/TorManager: kernel-level die-with-parent
  (Windows Job Object KILL_ON_JOB_CLOSE / Linux PR_SET_PDEATHSIG) so the
  embedded wownerod and bundled tor never survive a wowlet exit or crash.
- DaemonManager: verify-before-adopt via get_info (nettype/height) instead of
  trusting a bare open RPC port, so a stale/orphan node is never adopted.

Node/Tor lifecycle + remote-node connectivity:
- config: torPrivacyLevel default -> allTorExceptNode. NEVER sync blocks over
  Tor; the wallet's node connection is always clearnet. Tor is only for tx
  broadcast, so remote nodes work with or without Tor.
- nodes: add Nodes::reconnect() (clear failure blocklist + force reconnect);
  node/Tor toggle handlers use it so a transient outage no longer strands the
  wallet at "Disconnected".
- MainWindow/SettingsDialog: reconnect on node/Tor toggle and on the async
  daemonStateChanged (closes the start() race; a freshly-toggled local node
  connects immediately).
- TorManager: reset retry/unpack state in init() so a system<->bundled Tor
  re-toggle can start again; quiesce on stop(). Linux unpackBins() rework
  (mkpath + presence-based unpack + graceful return-false), getVersion() arg
  fix, and a missing-binary start guard.
- build.yml: derive TOR_VERSION from the embedded tor binary (a hardcoded
  bundle number made unpackBins rewrite Tor every launch).
- depends/funcs.mk: confine cross-cmake find_package to the depends sysroot so
  host -dev libraries don't leak into the build.
2026-06-23 17:45:39 -04:00
jwinterm a1ae9735d5 release: bump version to 5.0.0 + defer arm64/riscv64 (continue-on-error)
v5.0.0 ships Windows x86_64 + Linux x86_64. arm64/riscv64 (Qt static-link gap) and macOS deferred to v5.0.1. continue-on-error keeps the cross job from failing the release run while I keep iterating it.
2026-06-21 21:12:20 -04:00
jwinterm 57531a9d09 depends(libxkbcommon): explicit xkb extension paths for cross + cache restore-keys
libxkbcommon 1.13.1 meson.build adds empty pkgconfig vars when xkeyboard-config is absent from the cross sysroot (XKEYBOARD_CONFIG_ROOT='') while has_extensions_directories is true -> meson hard-errors at pkgconfig.generate. Pass non-empty -Dxkb-config-(un)versioned-extensions-path.

Add restore-keys to all 4 depends cache restores: a busted exact key (any packages/* edit) now falls back to the newest prefix match, so make resumes from the partial built tree instead of rebuilding the static-Qt6 toolchain from scratch.
2026-06-21 15:09:15 -04:00
jwinterm 82bb6460a7 depends(wayland): native wayland-scanner.pc is in the multiarch pkgconfig dir
The find debug showed wayland-scanner.pc at <build_prefix>/lib/x86_64-linux-gnu/pkgconfig (multiarch layout), not lib/pkgconfig or share/pkgconfig. Add that path to the pkg-config vars so cross-meson finds the native scanner. Keeps native Wayland support (no disabling).
2026-06-21 12:34:48 -04:00
jwinterm 7e936ba968 depends(wayland): one-line config_cmds (fix recipe parse) + find debug 2026-06-21 11:13:34 -04:00
jwinterm a4e38fc712 depends(wayland): search share/pkgconfig for native wayland-scanner (+ debug find)
wayland-scanner.pc is a noarch .pc -> build_prefix/share/pkgconfig, not lib/pkgconfig, so the earlier PKG_CONFIG_PATH_FOR_BUILD missed it. Add share/pkgconfig to LIBDIR/PATH/PATH_FOR_BUILD + a find to log the real location.
2026-06-21 09:38:43 -04:00
jwinterm 1529edc432 depends(wayland): expose native wayland-scanner to cross meson
Target wayland (-Dscanner=false) resolves the host scanner via dependency(..., native: true), which uses meson's BUILD-machine pkg-config — not pointed at build_prefix. Add PKG_CONFIG_PATH_FOR_BUILD=build_prefix + a [binaries] wayland-scanner in the cross-file. Fixes 'Dependency wayland-scanner not found' on aarch64/riscv64.
2026-06-21 07:54:52 -04:00
jwinterm 97a4304add ci(linux-cross): add meson + ninja-build for native_wayland (wayland is linux-only) 2026-06-20 23:35:06 -04:00
jwinterm b353b08ba2 ci: add linux arm64 + riscv64 depends AppImage builds (matrix)
Cross-build wowlet via depends for aarch64/riscv64 (reusing the zeromq/ICU/qt/testlib fixes), embed the matching wownerod + depends-built tor, package an AppImage via contrib/AppImage/build-appimage.sh (its hardcoded /feather runtime path relativized to GITHUB_WORKSPACE). Cached per-host, save-always.
2026-06-20 23:22:59 -04:00
jwinterm b422ba383a monero: bump submodule — link ICU only when depends ships it (fixes mingw cross link) 2026-06-20 22:51:52 -04:00
jwinterm c87d807443 cmake: don't link ICU/iconv on cross-builds (vestigial without system boost)
feather.exe links ${ICU_LIBRARIES}, set by the monero submodule's static-build branch assuming depends ships ICU + libiconv. Feather's depends doesn't, and its depends boost is --without-icu, so nothing references ICU/iconv symbols — the mingw link failed on missing -licu*/-liconv. Clear ICU_LIBRARIES when CMAKE_CROSSCOMPILING; native (system boost, built with ICU) unchanged.
2026-06-20 22:20:35 -04:00
jwinterm f93b3f705e depends: add zeromq (wownero needs zmq.h) + cache depends save-always
wowlet.exe reached 27% then hit 'zmq.h: No such file' — feather strips zeromq from depends (its wallet does not use zmq) but wownero cryptonote_core/net does. Port the wownero zeromq.mk + patch, register it in packages. Also switch the depends caches to restore + save(if:always) so the completed toolchain banks even when the wowlet build fails (auto post-save is skipped on job failure).
2026-06-20 19:33:43 -04:00
jwinterm 95a0fa3a3c depends(native_qt): keep testlib enabled so the host builds qmltestrunner
Cross qtdeclarative builds tools/qmltestrunner (QtQuickTest, needs testlib) and demands a matching HOST tool; the host's -no-feature-testlib left it without one, failing 'Configuring qtdeclarative' with 'Failed to find host tool Qt6::qmltestrunner'.
2026-06-20 16:38:28 -04:00
jwinterm 6a1fc084c2 ci(windows): -j2 + 10G swap so the static Qt6 depends build fits 16G RAM
Disk fix let it run 50min (vs ~10min) before the runner lost communication again -> OOM during the parallel Qt6 compile, not disk. Drop both builds to -j2 and add a 10G swapfile for headroom. Slower but should complete + cache depends for fast future runs.
2026-06-20 15:11:26 -04:00
jwinterm 6cc92a5bc4 ci(windows): drop container + free disk so the depends build fits the runner
First run was killed mid depends build (runner lost communication = CPU/Memory/disk starvation). Inside a container we cannot reclaim the runner's pre-installed bloat, leaving the static-Qt6 build only ~14G. Run on ubuntu-latest directly, free ~25G (dotnet/android/ghc/CodeQL), sudo the apt steps.
2026-06-20 14:43:39 -04:00
jwinterm 626d1a6ab7 ci: add Windows x86_64 cross-build job (mingw depends)
Builds wowlet.exe via contrib/depends (static Qt6 + tor), embeds wownerod.exe from the wownero mingw release, packages a .zip. Caches the depends tree so only the first run pays the ~1h toolchain cost. Tor shipped loose next to the exe (TOR_INSTALLED).
2026-06-20 13:41:48 -04:00
jwinterm 3d1424869d wowlet: clearer Tor status for external Tor + lift mining stats into the dark bar
- TorInfoDialog: when wowlet reuses an already-running external/system Tor (isLocalTor), show 'Connected (using external Tor)' instead of the misleading 'Not running'.

- mining.qml: raise + tighten the Block Height / Sync Progress block so it sits in the dark header bar instead of clipping the scene art (first pass, may need a small tweak).
2026-06-20 12:09:43 -04:00
jwinterm 83a4582266 wowlet: fix tx-proxy port, add configurable node data-dir, mining sync hint
- DaemonManager --tx-proxy now uses the Tor that is actually running (torManager()->isLocalTor()) instead of the stored useLocalTor preference, which selected the wrong SOCKS port (managed 19450 vs system 9050) and silently stalled outbound tx broadcasts.

- Embedded node: nodeDataDir setting points wownerod at an existing chain (e.g. ~/.wownero) to skip a full re-sync; empty keeps the managed isolated default.

- mining.qml: tell the user mining waits until the node is synced.
2026-06-20 08:58:47 -04:00
jwinterm cae730ff27 ci: bundle Tor in the wowlet AppImage (embed tor binary + libs)
So wowlet works for users without a system Tor. The build fetches the
tor-expert-bundle (linux x86_64), patchelfs the tor binary + its libs to
$ORIGIN, and passes -DTOR_DIR/-DTOR_VERSION so cmake embeds them into
:/assets/tor and sets HAS_TOR_BIN=1. wowlet then extracts + manages its own
Tor daemon -> remote node connections route over Tor out of the box.
2026-06-20 06:23:04 -04:00
jwinterm 35af2db2ef wowlet: keep wownero clearnet nodes usable in Tor mode (fix empty remote-node list)
feather's websocket-node filter drops every non-onion node once the Tor privacy
level flips to onion-preferred (after initial sync) — it assumes an onion node
ecosystem. wownero's public nodes are clearnet, so the Settings list went empty
and autoConnect had nothing eligible -> Disconnected. Keep clearnet nodes
eligible in every proxy mode (routed over Tor's SOCKS proxy when Tor is on, so
still private); only hide onion/i2p nodes when their anonymity mode isn't active.
2026-06-20 06:05:47 -04:00
jwinterm ea22d5dbe4 wowlet: pull the live remote-node list from wownero.org/nodes
The feather websocket is disabled (no WOW backend); replace it with a Tor-routed
HTTP poll of https://wownero.org/nodes/api/nodes/wallet (the live, health-checked
node-map feed). Builds the managed node list from the feed's plain-http nodes
(skips SSL-only nodes feather can't reach), falls back to the bundled nodes.json
if the feed is unreachable, refreshes hourly. So users who don't run a local node
get a fresh, working remote-node list instead of a stale hardcoded one.
2026-06-19 22:02:53 -04:00
jwinterm 4d5805a75c wowlet: fix remote-node connect when the built-in node is off. (1) nodes.cpp loadConfig: when the websocket discovery is disabled, ignore the cached ws node list (stale / polluted with monero nodes from an early build) and use the bundled wownero list. (2) nodes.json: managed clearnet list -> the 4 current healthy wownero nodes (node2/node3.monerodevs.org, spippolatori.it, wownerod.foolsump.com) 2026-06-19 16:39:59 -04:00
jwinterm 3eab1e14fa wowlet: first-run 'be your own node' welcome + deferred startup + non-blocking node toggle. On first launch a welcome dialog lets the user choose own-node vs remote BEFORE any node starts (gated on firstRun; later launches use the saved choice); node start moved past it in WindowManager. Settings toggle now stops wownerod non-blocking (no UI freeze while it flushes LMDB). Copy: 'many recommended', no em-dash 2026-06-19 16:02:17 -04:00
jwinterm 487875ee9e wowlet: local/remote node toggle in Settings -> Network. Checkbox 'Run your own Wownero node (much recommended)' + doge-y copy on privacy/network-health; toggling live-starts/stops the embedded wownerod and reconnects (autoConnect honours runLocalNode: local when on, chosen remote when off); remote list greys out while the built-in node is active 2026-06-19 14:53:42 -04:00
jwinterm 527bcfae57 wowlet: wownero loose-string sweep + P0 send fix. Bump monero submodule -> gui@1ed9d64c (drops feather's monero-checkpoint check_rct_distribution() that made every send throw 'Output distribution size too small'). feather-src: local-node probe + wizard port 18081->34568 (Utils.cpp getDefaultRpcPort, PageNetwork.ui); confirmationsRequired + lock display 10->4 = wownero spendable age (TransactionRow, TxInfoDialog, BalanceDialog, SendWidget); amount precision 12->11 (config, SettingsDialog); tx-pool backlog x2->x5 (5-min blocks); revuo + CCS off default plugins 2026-06-19 14:10:58 -04:00
jwinterm 8686e9bfe8 fix: vanishing balance — RestoreHeightLookup used monero block time (120s/720-per-day) to extrapolate the date->height table past 2023, computing restore heights ~400k blocks INTO THE FUTURE for 2026 wallets. Restore height > chain tip => wallet skips output-scan on every real block => received funds never recorded (pool scan unaffected, hence pool-shows-then-vanishes). Use wownero 300s/288-per-day. Also: block explorers -> explore.wownero.com / explore.wowne.ro 2026-06-19 10:08:46 -04:00
jwinterm 519187b8a1 depends: build qtdeclarative (Qt Quick/QML) in cross + host Qt — required for the mining tab on every depends cross-target (upstream Feather is widgets-only; native build only worked via distro QML) 2026-06-19 08:30:28 -04:00
jwinterm 35628cc5d8 wowlet: mining tab uptime — anchor start-time on mining transition, emit HH:MM:SS via uptimeChanged (was never emitted → stuck at '-') 2026-06-19 08:30:28 -04:00
jwinterm 0544837cff fix: white mining tab — remove vestigial 'import QtQuick.Controls' (eagerly registers Calendar singleton → QtQuick.Templates plugin missing → whole QML fails to load). Also make QML bundling complete: blanket-copy QtQuick/QtQml trees + ldd-resolve plugin .so lib deps into usr/lib, guard against re-adding Controls 2026-06-19 07:41:03 -04:00
jwinterm be3de5a4ce fix: bundle QtQml.WorkerScript in AppImage — qmlimportscanner skips qmldir transitive 'depends', so copy QtQml tree in explicitly between linuxdeploy populate + appimagetool package 2026-06-19 07:04:38 -04:00
jwinterm 43f7cc4e7a fix: SIGILL on launch — pin -DARCH=x86-64 for the Linux build instead of wownero's default ARCH=native (CI runner CPU baked in instructions older user CPUs lack) 2026-06-18 20:50:18 -04:00
jwinterm feeafbfdce wowlet: broadcast txs over Tor via wownerod --tx-proxy (gated on HAS_TOR_BIN; Config::broadcastOverTor default on) — hides tx origin IP, complements embedded-node receive privacy; activates when Tor is bundled (depends build) 2026-06-18 20:34:14 -04:00
jwinterm bf2d4e39bf wowlet: fix white mining tab — AppImage now bundles QtQuick QML modules (apt qml6-module-*, QML_SOURCES_PATHS for linuxdeploy-plugin-qt) + tls backend for HTTPS prices; QML cleanup (variant→var, child-id ref) 2026-06-18 20:22:01 -04:00
jwinterm 75fba57fc5 wowlet: About dialog — codeberg.org/wownero/wowlet, Telegram (t.me/wownero), Matrix (#wownero-gen:wowne.ro) 2026-06-18 20:00:44 -04:00
jwinterm 1aa34f0d75 wowlet: fix mining-tab white screen (root anchors.fill→size), visible radio selectors (wow.qss :/wow/→:/dark/), wizard+window titles, debrand live strings (tray/tor/webcam), About+website URLs→wownero, config dir →wowlet (also fixes stale Monero wallet dir) 2026-06-18 19:50:55 -04:00
jwinterm 421f57832c wowlet: fix mining-tab QQuickItem connect; wizard overhaul — skip first-run node-picker (embedded node default), disable feather-server websocket 2026-06-18 19:13:18 -04:00
jwinterm 341be7f7e4 fix: mining methods are on WalletManager not Wallet — delegate + setDaemonAddress to embedded node (fixes red builds) 2026-06-18 18:59:27 -04:00
jwinterm e0c06d6526 wowlet: pixel-art mining tab — port mining.qml (Qt6) + 25 assets, MiningWidget/MiningBackend hosting QQuickWidget, wired to embedded-node solo miner (hashrate/sync feedback); adds Qt6 Quick 2026-06-18 18:51:05 -04:00
jwinterm ccd53f59af wowlet: branding sweep — XMR→WOW, title/dir, .ui+wizard text Feather→wowlet/Monero→Wownero, flip+recolor sidebar (M→W, pink/yellow) 2026-06-18 18:27:28 -04:00
jwinterm 640a478b1b wowlet: solo-mining toggle — Wallet startMining/stopMining (RandomWOW via embedded node) + Wallet-menu action 2026-06-18 17:06:06 -04:00
jwinterm 5206dbdf8a ci: package wowlet as a portable Linux AppImage (linuxdeploy + qt; bundles Qt6, node already embedded) 2026-06-18 16:47:37 -04:00
jwinterm 28c04e8e6a ci: upload wowlet binary as artifact (downloadable from the run) 2026-06-18 16:43:02 -04:00