* feat: improvements covering solana nfts(send, ownership badge, persistent imports etc), closing emptied token accounts and other fixes from patch
* feat: more improvements for nfts including security hardening
* fix: display error in full
* fix android CI
* fix: address book wallet contacts tab not updating after wallet changes
* feat: add page open listener for contact list and handle concurrent calls to fetch contact list
The Windows lane already runs on the machine that physically holds the Sectigo
EV code-signing token, but the runner there is NT SERVICE\act_runner, which
cannot use it: SafeNet holds the token login per user and an operator
establishes that login interactively. So the build queues the launcher for the
signing broker that Fleet installs (such-fleet roles/windows_code_signing) and
waits for it to come back signed.
CI never holds the private key -- it is non-exportable on FIPS 140-2 Level 2
hardware -- and never holds the token password. Sectigo allows three
consecutive failed password attempts before the token needs vendor unlocking,
and a job that never supplies a password cannot spend one.
Only HashWallet.exe is signed. The bundled MSVC runtime DLLs are already
Microsoft-signed and must not be re-signed, and the plugin DLLs are loaded by
an already-trusted process; it is the launcher the user double-clicks that
SmartScreen judges.
The signature, its RFC 3161 timestamp and the expected signer are verified on
the exe that actually goes into the zip, and any of the three failing fails the
build. If the broker's circuit breaker is tripped the job says so and stops
rather than shipping an unsigned binary.
Procedure: docs platform/windows-hardware-token-signing.md.
- res/pictures/balance_card_icons/wownero.svg had an opaque background rect
(+#FFF5FD fill), so the ChainIcon's srcIn colorFilter flooded the whole
circle solid grey. Replaced with a clean alpha glyph (white W-in-circle on
transparent, like monero.svg) so the dark bg shows through the negative
space. Source in res/pictures → compile_graphics.sh regenerates the .vec.
- dark theme surface #0B1F14 → #10281B (a bit less dark, per feedback)
Bundles wownerod (aarch64-linux-android, built via monero depends) as
jniLibs libwownerod.so; EmbeddedNode.java execs it from nativeLibraryDir
(the exec-exempt path), binds RPC on 127.0.0.1:34568 for the wallet, pruned
mode by default, capped concurrency for phone thermals. Dart EmbeddedNode
service (start/stop/status/waitUntilReady) drives it over a method channel.
Verified: builds into the APK (binary bundled, arm64), and the daemon
executes on real hardware (moto g stylus) — inits core, binds RPC, connects
peers, and syncs blocks. UI toggle + foreground-service lifecycle are the
next layer; binary is provisioned like the wallet libs (gitignored).
package:yaml (used by the app) throws 'Duplicate mapping key' on the two
useSSL entries; PyYAML tolerated it so it slipped through. Adds a test that
parses every bundled YAML asset with package:yaml to prevent regression.
- validate legacy-decoded wallet passwords are real generateKey() output
(696 chars, base64 of 512-byte key + 8-byte iv) so a wrong AES key that
unpads to printable bytes can't be re-saved as a bogus password
- test/legacy_decode_test.dart: proves 1.0.0->1.0.2 recovers PIN+password
and 16k wrong keys yield zero false-accepts
CI ran tool/generate_new_secrets.dart unpinned, so every release binary
shipped different AES keys/salts for the stored PIN and wallet passwords.
Updating the app then failed to decrypt what the previous build stored:
'Invalid or corrupted pad block' at PIN entry and the 'Corrupted seeds'
dialog, with wallet files fully intact.
- entities/encrypt.dart: legacy-key fallback decode for PIN and wallet
password blobs (candidate sets recovered from the shipped 1.0.1 binary;
output validated to reject PKCS7 false positives)
- key_service/auth_service: on successful legacy decode, re-encrypt under
the pinned key — installs self-heal at first unlock
- all build workflows: inject the eight pinned CRYPTO_* repo secrets after
secret generation and hard-fail if any is missing, so crypto salts can
never silently rotate again (values pinned via
~keys/set-gitea-crypto-secrets.sh)
- bump 1.0.2+12
App Store Connect warning 90068 on the last two uploads: from Spring
2027 all iOS apps must set MinimumOSVersion 15.0 or later. Raising from
13.0 costs almost no devices (iOS 15 still covers iPhone 6s and SE 1).
Rides the next iOS build.
* fix android CI
* fix: harden walletconnect auth so a connected session won't transfer on dApp when wallet is switched within the app
* refactor: improve session mgmt and better error handling, also added a loader to the listing page
* feat: switch to newer id for solana dapps connections and fix requests not triggering
* fix android CI
* fix: duplicate outgoing tx for jup swaps and stuck pending state
* fix solana security risk by handling duplicate token symbols in wallet transactions
* feat: implement additional cost handling for pending transactions in Solana wallet.
* fix: Items on security audit list for solana wallet
* refactor: streamline fee payer index handling and improve error logging
* fix: verifySignature for solana and handle wrong mint on default token
* fix: token decimals defaulting to zero and breaking amount parsing in solana
* fix: use token mask in tx history
* refactor: apply lint to modified code
* fix: merge conflicts
* fix: use Money and mint decimals when parsing sol swaps
* test: add unit tests for SPL token amount handling and parsing
* test: add more tests
* fix: update decimal handling for fetched token and remove unused fields
The unchecked background resolved to colorScheme.surfaceContainerHighest,
which is pure white in LightTheme, so the unselected checkbox was an
invisible white disc on near-white list rows. In light brightness use
onSurfaceVariant with alpha 80 instead; dark themes are unchanged.