Generic fixes (#1454)
* Handle Bluetooth is disabled * Allow signMessage using ledger_bitcoin * Fix desktop wallet selection dropdown
Konstantin Ullrich committed
May 17, 2024 at 08:15 UTC
82391d4a5b1b96961d43ed17a3b4853e8062f219
5 files changed
+77
-44
cw_bitcoin/lib/bitcoin_wallet.dart
+30
-10
@@ -1,23 +1,24 @@
1
+import 'dart:convert';
2
+
3
+import 'package:bip39/bip39.dart' as bip39;
4
import 'package:bitcoin_base/bitcoin_base.dart';
5
+import 'package:bitcoin_flutter/bitcoin_flutter.dart' as bitcoin;
6
import 'package:convert/convert.dart';
3
-
7
+import 'package:cw_bitcoin/bitcoin_address_record.dart';
8
import 'package:cw_bitcoin/bitcoin_mnemonic.dart';
9
+import 'package:cw_bitcoin/bitcoin_wallet_addresses.dart';
10
+import 'package:cw_bitcoin/electrum_balance.dart';
11
+import 'package:cw_bitcoin/electrum_wallet.dart';
12
+import 'package:cw_bitcoin/electrum_wallet_snapshot.dart';
13
import 'package:cw_bitcoin/psbt_transaction_builder.dart';
14
import 'package:cw_core/crypto_currency.dart';
15
import 'package:cw_core/unspent_coins_info.dart';
16
+import 'package:cw_core/wallet_info.dart';
17
+import 'package:flutter/foundation.dart';
18
import 'package:hive/hive.dart';
19
import 'package:ledger_bitcoin/ledger_bitcoin.dart';
20
import 'package:ledger_flutter/ledger_flutter.dart';
21
import 'package:mobx/mobx.dart';
12
-import 'package:flutter/foundation.dart';
13
-import 'package:bitcoin_flutter/bitcoin_flutter.dart' as bitcoin;
14
-import 'package:cw_bitcoin/electrum_wallet_snapshot.dart';
15
-import 'package:cw_bitcoin/electrum_wallet.dart';
16
-import 'package:cw_core/wallet_info.dart';
17
-import 'package:cw_bitcoin/bitcoin_address_record.dart';
18
-import 'package:cw_bitcoin/electrum_balance.dart';
19
-import 'package:cw_bitcoin/bitcoin_wallet_addresses.dart';
20
-import 'package:bip39/bip39.dart' as bip39;
22
23
part 'bitcoin_wallet.g.dart';
24
@@ -215,4 +216,23 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
216
final rawHex = await _bitcoinLedgerApp!.signPsbt(_ledgerDevice!, psbt: psbt.psbt);
217
return BtcTransaction.fromRaw(hex.encode(rawHex));
218
}
219
+
220
+ @override
221
+ Future<String> signMessage(String message, {String? address = null}) async {
222
+ if (walletInfo.isHardwareWallet) {
223
+ final addressEntry = address != null
224
+ ? walletAddresses.allAddresses.firstWhere((element) => element.address == address)
225
+ : null;
226
+ final index = addressEntry?.index ?? 0;
227
+ final isChange = addressEntry?.isHidden == true ? 1 : 0;
228
+ final accountPath = walletInfo.derivationInfo?.derivationPath;
229
+ final derivationPath = accountPath != null ? "$accountPath/$isChange/$index" : null;
230
+
231
+ final signature = await _bitcoinLedgerApp!
232
+ .signMessage(_ledgerDevice!, message: ascii.encode(message), signDerivationPath: derivationPath);
233
+ return base64Encode(signature);
234
+ }
235
+
236
+ return super.signMessage(message, address: address);
237
+ }
238
}
cw_bitcoin/pubspec.lock
+3
-3
@@ -475,10 +475,10 @@ packages:
475
description:
476
path: "."
477
ref: HEAD
478
- resolved-ref: b6ed573cbeb57d5f0d39dfe4254bf9d15b620ab6
479
- url: "https://github.com/cake-tech/ledger-bitcoin.git"
478
+ resolved-ref: f819d37e235e239c315e93856abbf5e5d3b71dab
479
+ url: "https://github.com/cake-tech/ledger-bitcoin"
480
source: git
481
- version: "0.0.1"
481
+ version: "0.0.2"
482
ledger_flutter:
483
dependency: "direct main"
484
description:
cw_bitcoin/pubspec.yaml
+1
-1
@@ -38,7 +38,7 @@ dependencies:
38
ledger_flutter: ^1.0.1
39
ledger_bitcoin:
40
git:
41
- url: https://github.com/cake-tech/ledger-bitcoin.git
41
+ url: https://github.com/cake-tech/ledger-bitcoin
42
43
dev_dependencies:
44
flutter_test:
lib/src/screens/connect_device/connect_device_page.dart
+24
-14
@@ -3,6 +3,7 @@ import 'dart:io';
3
4
import 'package:cake_wallet/generated/i18n.dart';
5
import 'package:cake_wallet/src/screens/base_page.dart';
6
+// import 'package:cake_wallet/src/screens/connect_device/debug_device_page.dart';
7
import 'package:cake_wallet/src/screens/connect_device/widgets/device_tile.dart';
8
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
9
import 'package:cake_wallet/utils/responsive_layout_util.dart';
@@ -78,15 +79,13 @@ class ConnectDevicePageBodyState extends State<ConnectDevicePageBody> {
79
@override
80
void initState() {
81
super.initState();
81
- Future.delayed(
82
- Duration(seconds: 1),
83
- () => _bleRefresh = ledger.scan().listen((device) => setState(() => bleDevices.add(device))),
84
- );
85
- // _bleRefreshTimer = Timer.periodic(Duration(seconds: 1), (_) => _refreshBleDevices());
82
+ WidgetsBinding.instance.addPostFrameCallback((_) {
83
+ _bleRefreshTimer = Timer.periodic(Duration(seconds: 1), (_) => _refreshBleDevices());
84
87
- if (Platform.isAndroid) {
88
- _usbRefreshTimer = Timer.periodic(Duration(seconds: 1), (_) => _refreshUsbDevices());
89
- }
85
+ if (Platform.isAndroid) {
86
+ _usbRefreshTimer = Timer.periodic(Duration(seconds: 1), (_) => _refreshUsbDevices());
87
+ }
88
+ });
89
}
90
91
@override
@@ -103,14 +102,16 @@ class ConnectDevicePageBodyState extends State<ConnectDevicePageBody> {
102
}
103
104
Future<void> _refreshBleDevices() async {
106
- final isBleEnabled = await Permission.bluetooth.serviceStatus.isEnabled;
107
-
108
- setState(() => bleIsEnabled = isBleEnabled);
109
-
110
- if (isBleEnabled) {
111
- _bleRefresh = ledger.scan().listen((device) => setState(() => bleDevices.add(device)));
105
+ try {
106
+ _bleRefresh = ledger.scan().listen((device) => setState(() => bleDevices.add(device)))
107
+ ..onError((e) {
108
+ throw e as Exception;
109
+ });
110
+ setState(() => bleIsEnabled = true);
111
_bleRefreshTimer?.cancel();
112
_bleRefreshTimer = null;
113
+ } catch (e) {
114
+ setState(() => bleIsEnabled = false);
115
}
116
}
117
@@ -142,6 +143,15 @@ class ConnectDevicePageBodyState extends State<ConnectDevicePageBody> {
143
textAlign: TextAlign.center,
144
),
145
),
146
+ // DeviceTile(
147
+ // onPressed: () => Navigator.of(context).push(
148
+ // MaterialPageRoute<void>(
149
+ // builder: (BuildContext context) => DebugDevicePage(),
150
+ // ),
151
+ // ),
152
+ // title: "Debug Ledger",
153
+ // leading: imageLedger,
154
+ // ),
155
if (!bleIsEnabled)
156
Padding(
157
padding: EdgeInsets.only(left: 20, right: 20, bottom: 20),
lib/src/screens/dashboard/desktop_widgets/desktop_wallet_selection_dropdown.dart
+19
-16
@@ -117,22 +117,25 @@ class _DesktopWalletSelectionDropDownState extends State<DesktopWalletSelectionD
117
if (selectedWallet.isCurrent || !selectedWallet.isEnabled) {
118
return;
119
}
120
- final confirmed = await showPopUp<bool>(
121
- context: context,
122
- builder: (dialogContext) {
123
- return AlertWithTwoActions(
124
- alertTitle: S.of(context).change_wallet_alert_title,
125
- alertContent: S.of(context).change_wallet_alert_content(selectedWallet.name),
126
- leftButtonText: S.of(context).cancel,
127
- rightButtonText: S.of(context).change,
128
- actionLeftButton: () => Navigator.of(dialogContext).pop(false),
129
- actionRightButton: () => Navigator.of(dialogContext).pop(true));
130
- }) ??
131
- false;
132
-
133
- if (confirmed) {
134
- await _loadWallet(selectedWallet);
135
- }
120
+
121
+ WidgetsBinding.instance.addPostFrameCallback((_) async {
122
+ final confirmed = await showPopUp<bool>(
123
+ context: context,
124
+ builder: (dialogContext) {
125
+ return AlertWithTwoActions(
126
+ alertTitle: S.of(context).change_wallet_alert_title,
127
+ alertContent: S.of(context).change_wallet_alert_content(selectedWallet.name),
128
+ leftButtonText: S.of(context).cancel,
129
+ rightButtonText: S.of(context).change,
130
+ actionLeftButton: () => Navigator.of(dialogContext).pop(false),
131
+ actionRightButton: () => Navigator.of(dialogContext).pop(true));
132
+ }) ??
133
+ false;
134
+
135
+ if (confirmed) {
136
+ await _loadWallet(selectedWallet);
137
+ }
138
+ });
139
}
140
141
Image _imageFor({required WalletType type}) {