linux fixes (#3262)

* linux fixes

fix: use ints instead of bools in SQLite to prevent crashes on linux
fix: disable lightning if it's unsupported
ui: start linux app in portrait mode instead of landscape so it looks
nicer

* minor cleanup

---------

Co-authored-by: Omar <omarh.ismail1@gmail.com>
This commit is contained in:
cyan
2026-05-28 17:10:48 +02:00
committed by GitHub
co-authored by Omar
parent 2f5757deab
commit 8979811de7
5 changed files with 47 additions and 34 deletions
+9 -2
View File
@@ -4,6 +4,7 @@ import 'dart:io';
import 'dart:isolate';
import 'package:bitcoin_base/bitcoin_base.dart';
import 'package:cw_bitcoin/lightning/lightning_wallet.dart';
import 'package:cw_core/hardware/hardware_wallet_service.dart';
import 'package:cw_core/root_dir.dart';
import 'package:cw_core/utils/proxy_wrapper.dart';
@@ -76,7 +77,7 @@ abstract class ElectrumWalletBase
ElectrumBalance? initialBalance,
CryptoCurrency? currency,
bool? alwaysScan,
this.useLightning = true,
bool useLightning = true,
}) : _masterHD = getMasterHD(seedBytes, network, walletInfo.hardwareWalletType),
accountHD = getAccountHDWallet(
currency, network, seedBytes, xpub, derivationInfo, walletInfo.hardwareWalletType),
@@ -102,6 +103,7 @@ abstract class ElectrumWalletBase
this.unspentCoinsInfo = unspentCoinsInfo,
this.isTestnet = !network.isMainnet,
this._mnemonic = mnemonic,
_useLightning = useLightning,
super(walletInfo, derivationInfo) {
this.electrumClient = electrumClient ?? electrum.ElectrumClient();
this.walletInfo = walletInfo;
@@ -305,8 +307,13 @@ abstract class ElectrumWalletBase
@observable
bool? alwaysScan;
@computed
bool get useLightning => _useLightning && LightningWallet.isAvailable;
set useLightning(bool val) => _useLightning = val && LightningWallet.isAvailable;
@observable
bool useLightning;
bool _useLightning;
final Bip32Slip10Secp256k1? _masterHD;
final Bip32Slip10Secp256k1 accountHD;
+35 -25
View File
@@ -92,15 +92,25 @@ class Node {
login = map['login'] as String?,
label = map['label'] as String?,
password = map['password'] as String?,
isPow = (map["isPow"] != null && map['isPow'] != 0) as bool? ?? false,
useSSL = (map['useSSL'] != 0) as bool?,
isPow = _getBoolFromDB(map['isPow']),
useSSL = _getBoolFromDB(map['useSSL']),
typeRaw = (map["typeRaw"] ?? 0) as int,
trusted = (map['trusted'] != 0) as bool? ?? false,
trusted = _getBoolFromDB(map['trusted']),
socksProxyAddress = map['socksProxyAddress'] as String?,
isEnabledForAutoSwitching = (map['isEnabledForAutoSwitching'] != 0) as bool? ?? false,
isOfficial = (map['isOfficial'] != 0) as bool? ?? false,
isBuiltin = (map['isBuiltin'] != 0) as bool? ?? false,
isDefault = (map['isDefault'] != 0) as bool? ?? false;
isEnabledForAutoSwitching = _getBoolFromDB(map['isEnabledForAutoSwitching']),
isOfficial = _getBoolFromDB(map['isOfficial']),
isBuiltin = _getBoolFromDB(map['isBuiltin']),
isDefault = _getBoolFromDB(map['isDefault']);
static bool _getBoolFromDB(value, {bool? defaultValue}) {
if (value is bool) {
return value;
} else if (value is int) {
return value == 1;
} else {
return defaultValue ?? false;
}
}
Map<String, dynamic> toMap() {
return {
@@ -110,15 +120,15 @@ class Node {
'login': login,
"label": label,
'password': password,
"isPow": isPow,
'useSSL': useSSL,
"isPow": isPow ? 1 : 0,
'useSSL': (useSSL??false) ? 1 : 0,
"typeRaw": typeRaw,
'trusted': trusted,
'trusted': trusted ? 1 : 0,
'socksProxyAddress': socksProxyAddress,
'isEnabledForAutoSwitching': isEnabledForAutoSwitching,
"isOfficial": isOfficial,
"isBuiltin": isBuiltin,
"isDefault": isDefault
'isEnabledForAutoSwitching': isEnabledForAutoSwitching ? 1 : 0,
"isOfficial": isOfficial ? 1 : 0,
"isBuiltin": isBuiltin ? 1 : 0,
"isDefault": isDefault ? 1 : 0
};
}
@@ -127,11 +137,11 @@ class Node {
}
static Future<int> deleteAll() async {
return await db!.delete(tableName, where: "isPow = ?", whereArgs: [false]);
return await db!.delete(tableName, where: "isPow = ?", whereArgs: [0]);
}
static Future<int> deleteAllPow() async {
return await db!.delete(tableName, where: "isPow = ?", whereArgs: [true]);
return await db!.delete(tableName, where: "isPow = ?", whereArgs: [1]);
}
Future<int> save() async {
@@ -173,35 +183,35 @@ class Node {
static Future<List<Node>> getAll() async {
return selectList("isPow = ?", [false]);
return selectList("isPow = ?", [0]);
}
static Future<List<Node>> getAllBuiltin() async {
return selectList("isPow = ? AND isBuiltin = ?", [false, true]);
return selectList("isPow = ? AND isBuiltin = ?", [0, 1]);
}
static Future<List<Node>> getAllPowBuiltin() async {
return selectList("isPow = ? AND isBuiltin = ?", [true, true]);
return selectList("isPow = ? AND isBuiltin = ?", [1, 1]);
}
static Future<List<Node>> getAllForWalletType(WalletType type) async {
return selectList("typeRaw = ? AND isPow = ?", [serializeToInt(type), false]);
return selectList("typeRaw = ? AND isPow = ?", [serializeToInt(type), 0]);
}
static Future<Node?> getDefaultForWalletType(WalletType type) async {
return (await selectList("typeRaw = ? AND isPow = ? AND isDefault = ?", [serializeToInt(type), false, true])).firstOrNull;
return (await selectList("typeRaw = ? AND isPow = ? AND isDefault = ?", [serializeToInt(type), 0, 1])).firstOrNull;
}
static Future<Node?> getDefaultPowForWalletType(WalletType type) async {
return (await selectList("typeRaw = ? AND isPow = ? AND isDefault = ?", [serializeToInt(type), true, true])).firstOrNull;
return (await selectList("typeRaw = ? AND isPow = ? AND isDefault = ?", [serializeToInt(type), 1, 1])).firstOrNull;
}
static Future<List<Node>> getAllForWalletTypePow(WalletType type) async {
return selectList("typeRaw = ? AND isPow = ?", [serializeToInt(type), true]);
return selectList("typeRaw = ? AND isPow = ?", [serializeToInt(type), 1]);
}
static Future<List<Node>> getAllPow() async {
return selectList("isPow = ?", [true]);
return selectList("isPow = ?", [1]);
}
static Future<Node?> get(int id) async {
@@ -475,7 +485,7 @@ class Node {
},
),
);
final data = jsonDecode(response.body);
if (response.statusCode != 200 ||
data["error"] != null ||
+1 -1
View File
@@ -342,7 +342,7 @@ class _NewReceivePageState extends State<NewReceivePage> {
setState(() {
_addressItemWithLabel = widget.addressListViewModel.forceRecomputeItems.firstWhereOrNull(
(item) => (item is WalletAddressListItem && item.address == newAddress.address))
as WalletAddressListItem;
as WalletAddressListItem?;
});
}
}
+1 -1
View File
@@ -972,7 +972,7 @@ class _NewSendPageState extends State<NewSendPage> {
onNext: (PaymentFlowResult newResult) {
final selectedChainId = newResult.chainId;
final isCompatible =
selectedChainId == evm!.getSelectedChainId(widget.sendViewModel.wallet);
selectedChainId == evm?.getSelectedChainId(widget.sendViewModel.wallet);
if (isCompatible) {
widget.sendViewModel.setSelectedCryptoCurrency(
+1 -5
View File
@@ -46,11 +46,7 @@ static void my_application_activate(GApplication* application) {
} else {
gtk_window_set_title(window, "Cake Wallet");
}
if (getenv("DESKTOP_FORCE_MOBILE")) {
gtk_window_set_default_size(window, 720, 1280);
} else {
gtk_window_set_default_size(window, 1280, 720);
}
gtk_window_set_default_size(window, 480, 800);
gtk_widget_show(GTK_WIDGET(window));
g_autoptr(FlDartProject) project = fl_dart_project_new();