Shrike 2.5.5-blake2b.13 - only services that adopted the fork, and watch only wallets opt in
Shrike signing with the unified opt-in signature hash as Bitcoin Knots v29.4.1.knots20260508rc4 defines it, on upstream Sparrow 2.5.5.
Only services that have adopted the fork are offered
Shrike follows the fork, but it was still shipping services that have not adopted it. Past the activation height such a service holds neither this chain's blocks nor its mempool, so it does not merely lag: it answers about somewhere else.
Transaction broadcast is the one that mattered. With a Tor proxy configured, that path replaces the connected node rather than supplementing it, and every source it could use, blockstream.info, mempool.space and mempool.emzy.de alike, had not adopted the fork. An opted-in transaction is refused there, but a legacy one relays, which is the replay this wallet exists to prevent.
Fee rates were quietly wrong. Seven places fell back to mempool.space when no source had been chosen, which is the state a new install starts in. Two of them are the fee estimates, so an unconfigured wallet priced transactions against a mempool it never broadcasts into. Nobody reported it, because a wrong fee looks like a fee.
Public Electrum servers are withdrawn entirely. None of them have adopted the fork, and connecting to one shows blocks and balances that diverge from these past the activation height, which is the worst of these failures rather than the mildest. A config that named one from before is corrected when it is read, because the connection is made at startup, long before a settings screen could intervene. Connect a Knots node, or your own Electrum server indexing one.
Fee rates, block explorer links and broadcast now use mempool.guide, which runs the same API on this chain. Exchange rates still offer mempool.space, deliberately: that is a fiat price feed carrying no chain data, and mempool.guide's price endpoint returns nothing.
The update check is gone rather than disabled. Its only feed is Sparrow's, signed with Sparrow's key, and the status bar link it drove read "Sparrow x.y.z available" pointing at sparrowwallet.com/download. It could only ever advertise the wallet that has not adopted the fork.
A watch only wallet can opt in
The Replay protection control was drawn only for hardware keystores, so a watch only wallet signed by a patched device could never opt in, and the remedy offered was to re-import it as an airgapped wallet: rebuild your wallet to change one boolean.
The reasoning was that such a keystore signs nothing, so marking it changes nothing. True of this wallet signing and beside the point. The wallet is not deciding what it signs; it is deciding which hash type to declare in a PSBT it hands to something else, which is exactly what a marked airgapped keystore does. It cannot verify either claim, and the owner is the only one who knows.
The control is now drawn for a watch only keystore too, naming the signer rather than a device. It stays off by default and is never inferred: a signer that does not understand 0x21 may sign the legacy message against a PSBT declaring the new one and produce a signature invalid under both rule sets. A mark that turns out to be wrong is not believed either, because the send screen counts what was actually signed rather than repeating the declaration back.
A payment code keystore went the other way. It holds a BIP47 extended private key and signs in process like a software seed, so it needs no mark. It was being refused one, which meant BIP47 child wallets never opted in at all.
Upgrading
.7 through .11 all declared Debian version 2.5.5-1, so apt compared them as equal and reported no upgrade. From .12 the revision carries the release number. If you are on .11 or earlier, this one still needs dpkg:
sudo dpkg -i shrike_2.5.5-13_amd64.deb
/opt/shrike/bin/Shrike --version # expect Shrike 2.5.5-blake2b.13Wallets and configuration in ~/.shrike are untouched.
Verified
A wallet holding no key at all, proven against nodes. Both chains are built from one shared history so the same coins exist on each:
1. marked watch only wallet declared All + Unified, signed 0x21
by a wallet holding no key
2. post-fork node accepted and mined it
3. pre-fork node rejected:
mempool-script-verify-flag-failed
(Signature opts in to the hardfork, which is not active here)
4. the same wallet left unmarked declared All, signed 0x01,
and the pre-fork node accepted it
Step 4 is the control: the mark is the only difference between a spend that cannot be replayed and one that can.
The terminal and the headless shrikeserver are driven through a pty and read back, which they were not before. That check exists because withdrawing public servers guarded the graphical screen but not the terminal's own, whose dialog reads the server list by index and would have thrown on an empty one.
Each behavior above was checked by reverting the code that implements it and confirming the test covering it fails, then restoring. 364 wallet and 611 drongo unit tests, nine end to end suites.
Reproducible: this commit built locally with Eclipse Temurin 25.0.2 produces an application tree whose 171 paths, every file and symlink, hash identically to the tree CI published in shrike-2.5.5-x86_64.tar.gz. Only the Linux x86_64 build was reproduced; the archive contents are compared rather than the installers.
Also fixed
Verifying a download named the wrong signer. The first user id on a key was taken with no check, so a key that has rotated an address showed the old one. Verifying a Shrike release reported a revoked address rather than the one the release names, which reads as tampering. The verifier also looked for Sparrow's release and manifest filenames, so picking a downloaded release never found its signature beside it.
The welcome flow no longer offers a connection this build cannot make. It is Introduction, Bitcoin Knots node, private Electrum server, each demonstrating a state it can actually reach. The terminal titles itself Shrike rather than Sparrow.
Downloads
| Platform | File |
|---|---|
| Windows | Shrike-2.5.5.msi, or .zip for a portable copy |
| macOS | Shrike-2.5.5-arm64-unsigned.dmg, or -x86_64-unsigned.dmg for Intel |
| Linux x86_64 | shrike_2.5.5-13_amd64.deb, or -x86_64.tar.gz |
| Linux aarch64 | shrike_2.5.5-13_arm64.deb, or -aarch64.tar.gz |
| Headless | the shrikeserver-* files |
Verify before running:
gpg --import privkeyio-signing-key.asc
gpg --verify SHA256SUMS.asc SHA256SUMS
sha256sum --ignore-missing -c SHA256SUMSSigned by Kyle Santiago kyle@privkey.io, key A47D99B6DB0D715D40C59A2023AE8A8EA7E24E38.
The macOS builds are not code signed or notarized, so macOS reports the app as damaged or from an unidentified developer on first launch. That means it is unsigned, not that the download is bad:
xattr -dr com.apple.quarantine /Applications/Shrike.app
Verify SHA256SUMS first, because clearing quarantine removes the check that would otherwise stop a tampered download. The Windows installer is not Authenticode signed either, and SmartScreen will warn accordingly.
No warranty
This is unofficial, unaudited software provided as is, with no warranty and no liability, under the same Apache 2.0 license it inherits. It is not a Sparrow release and is neither affiliated with nor supported by the Sparrow project. Using it is entirely at your own risk, and you alone bear any loss of funds.