fix: Restrict Windows platform from using Zcash and Lightning features; update Lightning availability checks. (#3220)
What changed, and why it matters
This commit disables Zcash and Bitcoin Lightning features on the Windows version of Cake Wallet. It also pins a specific version of a Windows secure-storage library. The changes look like a compatibility or stability fix rather than a response to an active security breach, but the commit message and diff do not explain the underlying reason.
Treat as a routine platform-compatibility/stability patch unless the vendor publishes a security advisory. Users on Windows should ensure they are on the latest version and monitor Cake Wallet release notes for any follow-up security explanation.
Security signals we found
Platform-restricted feature availability (Windows excluded from Zcash and Lightning)
Dependency version pin for flutter_secure_storage_windows
No explicit security rationale or CVE referenced in commit
Changes touch cryptographic wallet initialization paths
Evidence from the diff
The patch adds platform guards so Zcash database unlocking and Bitcoin Lightning wallet creation are skipped on Windows. It introduces LightningWallet.isAvailable (iOS/Android/macOS only) and updates canUseLightning to exclude Windows. It also adds a dependency override for flutter_secure_storage_windows 3.1.2 and updates the Windows build batch file to include cw_zcash and drop several EVM packages. No vulnerability details, CVE, or researcher attribution are present in the commit or supplied references.
Changed components
Windows build of Cake Wallet / Monero.comcw_bitcoin Lightning wallet initializationZcash database unlock flow in lib/main.dartPrivacy settings Lightning availability logicflutter_secure_storage_windows dependencyInspect captured patch +18 / −10
diff --git a/cakewallet.bat b/cakewallet.bat
index 60b562c0..5bb41128 100644
--- a/cakewallet.bat
+++ b/cakewallet.bat
@@ -24,7 +24,7 @@ IF NOT EXIST "%secrets_file_path%" (
) ELSE (echo === Using previously/already generated secrets file: %secrets_file_path% ===)
echo === Generating mobx models ===
-for /d %%i in (cw_core cw_monero cw_bitcoin cw_ethereum cw_evm cw_polygon cw_nano cw_bitcoin_cash cw_solana cw_tron cw_base cw_arbitrum.) do (
+for /d %%i in (cw_core cw_monero cw_bitcoin cw_evm cw_nano cw_bitcoin_cash cw_solana cw_tron cw_zcash.) do (
cd %%i
call flutter pub get > nul
call dart run build_runner build --delete-conflicting-outputs > nul
diff --git a/cw_bitcoin/lib/bitcoin_wallet.dart b/cw_bitcoin/lib/bitcoin_wallet.dart
index 84758a1c..144c2eaf 100644
--- a/cw_bitcoin/lib/bitcoin_wallet.dart
+++ b/cw_bitcoin/lib/bitcoin_wallet.dart
@@ -100,7 +100,7 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
// String sideDerivationPath = derivationPath.substring(0, derivationPath.length - 1) + "1";
// final hd = bitcoin.HDWallet.fromSeed(seedBytes, network: networkType);
- if (mnemonic != null && this.useLightning) {
+ if (mnemonic != null && this.useLightning && LightningWallet.isAvailable) {
try {
lightningWallet = LightningWallet(
mnemonic: mnemonic,
@@ -142,7 +142,7 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
});
reaction((_) => this.useLightning, (bool useLightning) {
- if (useLightning) {
+ if (useLightning && LightningWallet.isAvailable) {
if (mnemonic != null) {
lightningWallet = LightningWallet(
mnemonic: mnemonic,
diff --git a/cw_bitcoin/lib/lightning/lightning_wallet.dart b/cw_bitcoin/lib/lightning/lightning_wallet.dart
index a386d529..91890d20 100644
--- a/cw_bitcoin/lib/lightning/lightning_wallet.dart
+++ b/cw_bitcoin/lib/lightning/lightning_wallet.dart
@@ -33,9 +33,11 @@ class LightningWallet {
required this.apiKey,
required this.lnurlDomain,
this.network = Network.mainnet,
- this.cachedAddress
+ this.cachedAddress,
});
+ static bool get isAvailable => Platform.isIOS || Platform.isAndroid || Platform.isMacOS;
+
StreamSubscription<SdkEvent>? _eventSubscription;
Stream<SdkEvent>? _eventStream;
diff --git a/lib/main.dart b/lib/main.dart
index 8a4690d5..44bc8ed1 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -165,12 +165,17 @@ Future<void> runAppWithZone({Key? topLevelKey}) async {
if (FeatureFlag.hasDevOptions) {
ProxyWrapper.logger = MemoryProxyLogger();
}
- var zcashPassword = await secureStorageShared.read(key: "com.cakewallet.cw_zcash/zec.db");
- if (zcashPassword == null || zcashPassword.isEmpty) {
- zcashPassword = generateKey().substring(0, 32);
- secureStorageShared.write(key: "com.cakewallet.cw_zcash/zec.db", value: zcashPassword);
+
+ if (!Platform.isWindows) {
+ var zcashPassword = await secureStorageShared.read(
+ key: "com.cakewallet.cw_zcash/zec.db");
+ if (zcashPassword == null || zcashPassword.isEmpty) {
+ zcashPassword = generateKey().substring(0, 32);
+ secureStorageShared.write(
+ key: "com.cakewallet.cw_zcash/zec.db", value: zcashPassword);
+ }
+ zcash?.unlockDatabase(zcashPassword);
}
- zcash?.unlockDatabase(zcashPassword);
// Basically when we're running a test
if (topLevelKey != null) {
diff --git a/lib/view_model/settings/privacy_settings_view_model.dart b/lib/view_model/settings/privacy_settings_view_model.dart
index 54b5b56b..eceedf99 100644
--- a/lib/view_model/settings/privacy_settings_view_model.dart
+++ b/lib/view_model/settings/privacy_settings_view_model.dart
@@ -109,7 +109,7 @@ abstract class PrivacySettingsViewModelBase with Store {
bool get canUsePayjoin => _wallet.type == WalletType.bitcoin && DeviceInfo.instance.isMobile;
@computed
- bool get canUseLightning => _wallet.type == WalletType.bitcoin;
+ bool get canUseLightning => _wallet.type == WalletType.bitcoin && !Platform.isWindows;
@computed
bool get useLightning => _wallet.type == WalletType.bitcoin && bitcoin!.useLightning(_wallet);
diff --git a/pubspec_base.yaml b/pubspec_base.yaml
index ff54ecaa..e64a60ba 100644
--- a/pubspec_base.yaml
+++ b/pubspec_base.yaml
@@ -226,6 +226,7 @@ dependency_overrides:
ref: c414574bc5ac349450f601e7f72c7b9f31b4d087
decimal: ^2.3.3
flutter_rust_bridge: 2.11.1
+ flutter_secure_storage_windows: 3.1.2
flutter_icons:
image_path: "assets/images/app_logo.png"
Why this scored 32/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.