rpm/blackbeard-wallet.spec is the house prebuilt-binary spec: the bare
binary from the release, the desktop entry rendered from the same
template Tauri's bundlers use, AppStream metadata and four hicolor icons;
no strip, no debuginfo; validators run where they exist; every rpmlint
warning that stands is explained at the top. The release workflow gains a
package job on the rpm runner (changelog entry from the tag through
actions/rpm-changelog, rpmbuild with dist .fc44, rpmlint) and a publish
job under the shared rpm-publish concurrency group that signs with the
repository key, rsyncs as gitea_ci to oolon, runs createrepo_c and
regenerates packages.json, exactly as cichlid does. rpm/rpmmacros and
script/generate-packages-json.py are cichlid's.
Built here from the local release binary: blackbeard-wallet-0.1.0-1.fc44
installs /usr/bin/blackbeard-wallet, the desktop entry, the metainfo and
the icons. The publish job needs RPM_SIGNING_KEY, RPM_SIGNING_KEY_ID and
RSYNC_SSH_KEY on this repository, which only the operator can add; until
then a tag builds and attaches the release but stops at publish.
Refs #33
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014ftBXYuba8ARhQeF74oUgW
Pushing vX.Y.Z runs .gitea/workflows/release.yaml on rust-gtk3: it
refuses a tag that disagrees with the workspace version
(script/stamp-version.sh, which also stamps tauri.conf.json and
ui/package.json from Cargo.toml), builds the webview and the deb, rpm and
AppImage bundles through the npm Tauri CLI, checks the binary answers
--version with the tag, and attaches the bundles, the bare binary and
SHA256SUMS to a Gitea release for the tag using the repository's own
Actions token.
The product is now `blackbeard-wallet`, no space: that name is the
binary, the rpm and deb package, and every release asset, so
`dnf install blackbeard-wallet` reads right. The window title and the
desktop entry keep "blackbeard wallet" through a desktop template. The
binary answers --version and --help before touching the display.
Bundled locally on Fedora 44: deb, rpm (name, license and URL right,
desktop entry installed) and a 114 MB AppImage that prints
"blackbeard-wallet 0.1.0". The AppImage step needs librsvg2-devel for
linuxdeploy's GTK plugin, which the rust-gtk3 runner image does not carry
yet; that is a one-line change in gongfoo, without which the workflow's
bundle step fails on the AppImage.
Refs #32
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014ftBXYuba8ARhQeF74oUgW
Three routes under /onboarding, reachable from the lock screen and from
the shell, since a second wallet is the same flow as the first. Create
picks a scheme (ML-DSA-65 by default), shows the 24 words once, and
stands the backup challenge between seeing them and having a wallet; a
failed challenge drops the phrase on the Rust side and starts over.
Restore takes a phrase and a scheme, with a note that the same phrase
gives a different account under each. Import opens a native file chooser
through tauri-plugin-dialog, the first plugin, granted only
dialog:allow-open with its reason in the capability file; the path goes
to Rust, which reads the file. Every path ends unlocked on the accounts
page.
Driven through the WebKit inspector against the dev node: create wrote
onboard_test.json and unlocked; restoring the same phrase under a new
name produced the same address; importing a fixture file with the right
password opened it and with a wrong one mapped to wrong_password. The
chooser itself is a Wayland window nothing here can type into, so the
permission is verified by the open promise staying pending rather than
rejecting; CLAUDE.md and the inspector script now say so.
Closes#26
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014ftBXYuba8ARhQeF74oUgW
Running the shell for the first time showed a blank white window and no
error anywhere: Vite's dev page injects an inline React Refresh preamble,
the production CSP forbids inline scripts, and every component module then
throws on `$RefreshReg$` before React mounts. `tauri.conf.json` now carries
a `devCsp` for the dev server's origin; the production CSP is unchanged.
`WALLET_DATA_DIR` relocates wallets, settings and profile overrides
together, so a dev run lives in a throwaway directory instead of the real
app data; `WALLET_KEYSTORE_DIR` still moves only the wallets, for sharing
them with quantus-cli in place.
Verified end to end against the local dev node by driving the webview
through WebKitGTK's remote inspector (`script/webview-inspect.py`, kept
with the reason in CLAUDE.md): the lock screen lists both dev accounts;
unlocking crystal_alice shows 99,957.786510548 DEV at block 1832, 100 from
final, with the status bar on ws://127.0.0.1:9944 at spec 152; the block
number advances on its own; a settings change lands in settings.json; the
idle rule locks the UI without a click after the configured minute and the
Rust log says so; the Lock button locks; the console shows nothing but
Vite connecting. GNOME refuses D-Bus screenshots and ImageMagick captures
WebKit's GPU surface as flat grey, so the DOM was the evidence.
Refs #25
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014ftBXYuba8ARhQeF74oUgW
`script/dev-node.sh` fetches the v1.0.1 release binary once into `.cache/`,
checks it against the sha256 the release publishes, and runs
`quantus-node --dev` on a throwaway base path. The workflow starts it in
the background, waits for `system_chain` to answer `Quantus DevNet`, and
runs every ignored test whose name says `dev_node`: the send, reverse,
cancel and named-failure path, and the scheme-by-era probe that found the
mortality bug. Public-node tests stay ignored in CI.
Rehearsed locally on a second node on port 9955: both tests pass in 15 s.
Closes#24
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014ftBXYuba8ARhQeF74oUgW