V4.20.0 rc2 (#1727)

* version 4.20.0 * update build numbers * UI updates and script fix for ios bundle identifier * disable mweb for desktop * change hardcoded ltc server ip address electrum connection enhancement * MWEB enhancements 2.0 (#1735) * additional logging and minor fixes * additional logging and minor fixes * addresses pt.1 * Allow Wallet Group Names to be the same as Wallet Names (#1730) * fix: Issues with imaging * fix: Allow group names to be the same as wallet names * fix: Bug with wallet grouping when a wallet is minimized * fix: Bug with wallet grouping when a wallet is minimized * logs of fixes and experimental changes, close wallet before opening next * save * fix icon * fixes * [skip ci] updates * [skip ci] updates * updates * minor optimizations * fix for when switching between wallets * [skip ci] updates * [skip ci] updates * Update cw_bitcoin/lib/litecoin_wallet.dart Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com> * Update cw_bitcoin/lib/litecoin_wallet.dart Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com> * mobx * mostly logging * stream fix pt.1 [skip ci] * updates * some fixes and enhancements * [skip ci] minor * potential partial fix for streamsink closed * fix stream sink closed errors * fix mweb logo colors * save * minor enhancements [skip ci] * save * experimental * minor * minor [skip ci] --------- Co-authored-by: David Adegoke <64401859+Blazebrain@users.noreply.github.com> Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com> * fix menu list removing from original list --------- Co-authored-by: Matthew Fosse <matt@fosse.co> Co-authored-by: David Adegoke <64401859+Blazebrain@users.noreply.github.com>

Omar Hatem committed Oct 13, 2024 at 02:13 UTC 380f7653b2e39f468d722424b8e4d7f0f0eb910f
80 files changed +572 -329
assets/text/Monerocom_Release_Notes.txt
+4 -2
@@ -1,2 +1,4 @@
1 -Enhance auto-address generation for Monero
2 -Bug fixes and enhancements
\ No newline at end of file
1 +Monero enhancements for sending and address generation
2 +StealthEx
3 +LetsExchange
4 +Visual enhancements and bug fixes
\ No newline at end of file
assets/text/Release_Notes.txt
+9 -4
@@ -1,4 +1,9 @@
1 -Enable BIP39 by default for wallet creation also on Bitcoin/Litecoin (Electrum seed type is still accessible through advanced settings page)
2 -Improve fee calculation for Bitcoin to protect against overpaying or underpaying
3 -Enhance auto-address generation for Monero
4 -Bug fixes and enhancements
\ No newline at end of file
1 +Add Litecoin MWEB
2 +Wallet groups (same seed, multiple wallets)
3 +Silent Payments enhancements
4 +Monero enhancements for sending and address generation
5 +StealthEx
6 +LetsExchange
7 +Replace-By-Fee improvements
8 +ERC20 tokens potential scam detection
9 +Visual enhancements and bug fixes
\ No newline at end of file
cw_bitcoin/lib/bitcoin_receive_page_option.dart
+1 -1
@@ -30,7 +30,7 @@ class BitcoinReceivePageOption implements ReceivePageOption {
30
31 static const allLitecoin = [
32 BitcoinReceivePageOption.p2wpkh,
33 - BitcoinReceivePageOption.mweb
33 + BitcoinReceivePageOption.mweb,
34 ];
35
36 BitcoinAddressType toType() {
cw_bitcoin/lib/electrum.dart
+7 -6
@@ -116,7 +116,7 @@ class ElectrumClient {
116 _parseResponse(message);
117 }
118 } catch (e) {
119 - print(e.toString());
119 + print("socket.listen: $e");
120 }
121 },
122 onError: (Object error) {
@@ -125,14 +125,15 @@ class ElectrumClient {
125 unterminatedString = '';
126 },
127 onDone: () {
128 + print("SOCKET CLOSED!!!!!");
129 unterminatedString = '';
130 try {
131 if (host == socket?.address.host) {
131 - socket?.destroy();
132 _setConnectionStatus(ConnectionStatus.disconnected);
133 + socket?.destroy();
134 }
135 } catch (e) {
135 - print(e.toString());
136 + print("onDone: $e");
137 }
138 },
139 cancelOnError: true,
@@ -421,7 +422,7 @@ class ElectrumClient {
422 BehaviorSubject<T>? subscribe<T>(
423 {required String id, required String method, List<Object> params = const []}) {
424 try {
424 - if (socket == null) {
425 + if (socket == null || !isConnected) {
426 return null;
427 }
428 final subscription = BehaviorSubject<T>();
@@ -437,7 +438,7 @@ class ElectrumClient {
438
439 Future<dynamic> call(
440 {required String method, List<Object> params = const [], Function(int)? idCallback}) async {
440 - if (socket == null) {
441 + if (socket == null || !isConnected) {
442 return null;
443 }
444 final completer = Completer<dynamic>();
@@ -453,7 +454,7 @@ class ElectrumClient {
454 Future<dynamic> callWithTimeout(
455 {required String method, List<Object> params = const [], int timeout = 5000}) async {
456 try {
456 - if (socket == null) {
457 + if (socket == null || !isConnected) {
458 return null;
459 }
460 final completer = Completer<dynamic>();
cw_bitcoin/lib/electrum_wallet.dart
+21 -9
@@ -4,7 +4,6 @@ import 'dart:io';
4 import 'dart:isolate';
5
6 import 'package:bitcoin_base/bitcoin_base.dart';
7 -import 'package:cw_bitcoin/litecoin_wallet_addresses.dart';
7 import 'package:shared_preferences/shared_preferences.dart';
8 import 'package:cw_core/encryption_file_utils.dart';
9 import 'package:blockchain_utils/blockchain_utils.dart';
@@ -23,7 +22,6 @@ import 'package:cw_bitcoin/electrum_transaction_history.dart';
22 import 'package:cw_bitcoin/electrum_transaction_info.dart';
23 import 'package:cw_bitcoin/electrum_wallet_addresses.dart';
24 import 'package:cw_bitcoin/exceptions.dart';
26 -import 'package:cw_bitcoin/litecoin_wallet.dart';
25 import 'package:cw_bitcoin/pending_bitcoin_transaction.dart';
26 import 'package:cw_bitcoin/utils.dart';
27 import 'package:cw_core/crypto_currency.dart';
@@ -168,7 +166,10 @@ abstract class ElectrumWalletBase
166 @observable
167 SyncStatus syncStatus;
168
171 - Set<String> get addressesSet => walletAddresses.allAddresses.map((addr) => addr.address).toSet();
169 + Set<String> get addressesSet => walletAddresses.allAddresses
170 + .where((element) => element.type != SegwitAddresType.mweb)
171 + .map((addr) => addr.address)
172 + .toSet();
173
174 List<String> get scriptHashes => walletAddresses.addressesByReceiveType
175 .where((addr) => RegexUtils.addressTypeFromStr(addr.address, network) is! MwebAddress)
@@ -1174,6 +1175,7 @@ abstract class ElectrumWalletBase
1175 'silent_addresses': walletAddresses.silentAddresses.map((addr) => addr.toJSON()).toList(),
1176 'silent_address_index': walletAddresses.currentSilentAddressIndex.toString(),
1177 'mweb_addresses': walletAddresses.mwebAddresses.map((addr) => addr.toJSON()).toList(),
1178 + 'alwaysScan': alwaysScan,
1179 });
1180
1181 int feeRate(TransactionPriority priority) {
@@ -1291,7 +1293,7 @@ abstract class ElectrumWalletBase
1293 }
1294
1295 @override
1294 - Future<void> close() async {
1296 + Future<void> close({required bool shouldCleanup}) async {
1297 try {
1298 await _receiveStream?.cancel();
1299 await electrumClient.close();
@@ -1314,11 +1316,15 @@ abstract class ElectrumWalletBase
1316 }
1317
1318 // Set the balance of all non-silent payment addresses to 0 before updating
1317 - walletAddresses.allAddresses.forEach((addr) {
1319 + walletAddresses.allAddresses
1320 + .where((element) => element.type != SegwitAddresType.mweb)
1321 + .forEach((addr) {
1322 if (addr is! BitcoinSilentPaymentAddressRecord) addr.balance = 0;
1323 });
1324
1321 - await Future.wait(walletAddresses.allAddresses.map((address) async {
1325 + await Future.wait(walletAddresses.allAddresses
1326 + .where((element) => element.type != SegwitAddresType.mweb)
1327 + .map((address) async {
1328 updatedUnspentCoins.addAll(await fetchUnspent(address));
1329 }));
1330
@@ -1878,6 +1884,7 @@ abstract class ElectrumWalletBase
1884 }
1885
1886 Future<void> updateTransactions() async {
1887 + print("updateTransactions() called!");
1888 try {
1889 if (_isTransactionUpdating) {
1890 return;
@@ -1903,12 +1910,16 @@ abstract class ElectrumWalletBase
1910
1911 Future<void> subscribeForUpdates() async {
1912 final unsubscribedScriptHashes = walletAddresses.allAddresses.where(
1906 - (address) => !_scripthashesUpdateSubject.containsKey(address.getScriptHash(network)),
1913 + (address) =>
1914 + !_scripthashesUpdateSubject.containsKey(address.getScriptHash(network)) &&
1915 + address.type != SegwitAddresType.mweb,
1916 );
1917
1918 await Future.wait(unsubscribedScriptHashes.map((address) async {
1919 final sh = address.getScriptHash(network);
1911 - await _scripthashesUpdateSubject[sh]?.close();
1920 + if (!(_scripthashesUpdateSubject[sh]?.isClosed ?? true)) {
1921 + await _scripthashesUpdateSubject[sh]?.close();
1922 + }
1923 _scripthashesUpdateSubject[sh] = await electrumClient.scripthashUpdate(sh);
1924 _scripthashesUpdateSubject[sh]?.listen((event) async {
1925 try {
@@ -1918,7 +1929,7 @@ abstract class ElectrumWalletBase
1929
1930 await _fetchAddressHistory(address, await getCurrentChainTip());
1931 } catch (e, s) {
1921 - print(e.toString());
1932 + print("sub error: $e");
1933 _onError?.call(FlutterErrorDetails(
1934 exception: e,
1935 stack: s,
@@ -1996,6 +2007,7 @@ abstract class ElectrumWalletBase
2007 }
2008
2009 Future<void> updateBalance() async {
2010 + print("updateBalance() called!");
2011 balance[currency] = await fetchBalances();
2012 await save();
2013 }
cw_bitcoin/lib/electrum_wallet_addresses.dart
+5 -1
@@ -1,3 +1,5 @@
1 +import 'dart:io' show Platform;
2 +
3 import 'package:bitcoin_base/bitcoin_base.dart';
4 import 'package:blockchain_utils/blockchain_utils.dart';
5 import 'package:cw_bitcoin/bitcoin_address_record.dart';
@@ -238,7 +240,9 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
240 await _generateInitialAddresses(type: P2pkhAddressType.p2pkh);
241 } else if (walletInfo.type == WalletType.litecoin) {
242 await _generateInitialAddresses(type: SegwitAddresType.p2wpkh);
241 - await _generateInitialAddresses(type: SegwitAddresType.mweb);
243 + if (Platform.isAndroid || Platform.isIOS) {
244 + await _generateInitialAddresses(type: SegwitAddresType.mweb);
245 + }
246 } else if (walletInfo.type == WalletType.bitcoin) {
247 await _generateInitialAddresses();
248 await _generateInitialAddresses(type: P2pkhAddressType.p2pkh);
cw_bitcoin/lib/electrum_wallet_snapshot.dart
+8 -3
@@ -24,6 +24,7 @@ class ElectrumWalletSnapshot {
24 required this.silentAddresses,
25 required this.silentAddressIndex,
26 required this.mwebAddresses,
27 + required this.alwaysScan,
28 this.passphrase,
29 this.derivationType,
30 this.derivationPath,
@@ -46,6 +47,7 @@ class ElectrumWalletSnapshot {
47 List<BitcoinAddressRecord> addresses;
48 List<BitcoinSilentPaymentAddressRecord> silentAddresses;
49 List<BitcoinAddressRecord> mwebAddresses;
50 + bool alwaysScan;
51
52 ElectrumBalance balance;
53 Map<String, int> regularAddressIndex;
@@ -54,15 +56,15 @@ class ElectrumWalletSnapshot {
56 DerivationType? derivationType;
57 String? derivationPath;
58
57 - static Future<ElectrumWalletSnapshot> load(
58 - EncryptionFileUtils encryptionFileUtils, String name, WalletType type, String password, BasedUtxoNetwork network) async {
59 + static Future<ElectrumWalletSnapshot> load(EncryptionFileUtils encryptionFileUtils, String name,
60 + WalletType type, String password, BasedUtxoNetwork network) async {
61 final path = await pathForWallet(name: name, type: type);
62 final jsonSource = await encryptionFileUtils.read(path: path, password: password);
63 final data = json.decode(jsonSource) as Map;
64 final mnemonic = data['mnemonic'] as String?;
65 final xpub = data['xpub'] as String?;
66 final passphrase = data['passphrase'] as String? ?? '';
65 -
67 +
68 final addressesTmp = data['addresses'] as List? ?? <Object>[];
69 final addresses = addressesTmp
70 .whereType<String>()
@@ -81,6 +83,8 @@ class ElectrumWalletSnapshot {
83 .map((addr) => BitcoinAddressRecord.fromJSON(addr, network: network))
84 .toList();
85
86 + final alwaysScan = data['alwaysScan'] as bool? ?? false;
87 +
88 final balance = ElectrumBalance.fromJSON(data['balance'] as String?) ??
89 ElectrumBalance(confirmed: 0, unconfirmed: 0, frozen: 0);
90 var regularAddressIndexByType = {SegwitAddresType.p2wpkh.toString(): 0};
@@ -124,6 +128,7 @@ class ElectrumWalletSnapshot {
128 silentAddresses: silentAddresses,
129 silentAddressIndex: silentAddressIndex,
130 mwebAddresses: mwebAddresses,
131 + alwaysScan: alwaysScan,
132 );
133 }
134 }
cw_bitcoin/lib/litecoin_wallet.dart
+30 -30
@@ -76,6 +76,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
76 seedBytes: seedBytes,
77 encryptionFileUtils: encryptionFileUtils,
78 currency: CryptoCurrency.ltc,
79 + alwaysScan: alwaysScan,
80 ) {
81 mwebHd = Bip32Slip10Secp256k1.fromSeed(seedBytes).derivePath("m/1000'") as Bip32Slip10Secp256k1;
82 mwebEnabled = alwaysScan ?? false;
@@ -101,7 +102,6 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
102 Timer? _feeRatesTimer;
103 Timer? _processingTimer;
104 StreamSubscription<Utxo>? _utxoStream;
104 - late RpcClient _stub;
105 late bool mwebEnabled;
106 bool processingUtxos = false;
107
@@ -229,18 +229,14 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
229 initialRegularAddressIndex: snp?.regularAddressIndex,
230 initialChangeAddressIndex: snp?.changeAddressIndex,
231 addressPageType: snp?.addressPageType,
232 - alwaysScan: alwaysScan,
232 + alwaysScan: snp?.alwaysScan,
233 );
234 }
235
236 Future<void> waitForMwebAddresses() async {
237 + print("waitForMwebAddresses() called!");
238 // ensure that we have the full 1000 mweb addresses generated before continuing:
239 // should no longer be needed, but leaving here just in case
239 - // final mwebAddrs = (walletAddresses as LitecoinWalletAddresses).mwebAddrs;
240 - // while (mwebAddrs.length < 1000) {
241 - // print("waiting for mweb addresses to finish generating...");
242 - // await Future.delayed(const Duration(milliseconds: 1000));
243 - // }
240 await (walletAddresses as LitecoinWalletAddresses).ensureMwebAddressUpToIndexExists(1020);
241 }
242
@@ -252,16 +248,20 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
248 return;
249 }
250 print("STARTING SYNC - MWEB ENABLED: $mwebEnabled");
251 + _syncTimer?.cancel();
252 try {
253 syncStatus = SyncronizingSyncStatus();
254 await subscribeForUpdates();
255 updateFeeRates();
259 -
256 _feeRatesTimer?.cancel();
257 _feeRatesTimer =
258 Timer.periodic(const Duration(minutes: 1), (timer) async => await updateFeeRates());
259
260 if (!mwebEnabled) {
261 + try {
262 + // in case we're switching from a litecoin wallet that had mweb enabled
263 + CwMweb.stop();
264 + } catch (_) {}
265 try {
266 await updateAllUnspents();
267 await updateTransactions();
@@ -276,23 +276,19 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
276 }
277
278 await waitForMwebAddresses();
279 - await getStub();
279 await processMwebUtxos();
280 await updateTransactions();
281 await updateUnspent();
282 await updateBalance();
283 } catch (e) {
284 print("failed to start mweb sync: $e");
286 - syncStatus = FailedSyncStatus();
285 + syncStatus = FailedSyncStatus(error: "failed to start");
286 return;
287 }
288
290 - _syncTimer?.cancel();
291 - _syncTimer = Timer.periodic(const Duration(milliseconds: 1500), (timer) async {
289 + _syncTimer = Timer.periodic(const Duration(milliseconds: 3000), (timer) async {
290 if (syncStatus is FailedSyncStatus) return;
291
294 - print("SYNCING....");
295 -
292 final nodeHeight =
293 await electrumClient.getCurrentBlockChainTip() ?? 0; // current block height of our node
294
@@ -350,10 +346,12 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
346 @action
347 @override
348 Future<void> stopSync() async {
349 + print("stopSync() called!");
350 _syncTimer?.cancel();
351 _utxoStream?.cancel();
352 _feeRatesTimer?.cancel();
353 await CwMweb.stop();
354 + print("stopped syncing!");
355 }
356
357 Future<void> initMwebUtxosBox() async {
@@ -425,9 +423,9 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
423 await initMwebUtxosBox();
424 }
425
428 - Future<void> handleIncoming(MwebUtxo utxo, RpcClient stub) async {
426 + Future<void> handleIncoming(MwebUtxo utxo) async {
427 print("handleIncoming() called!");
430 - final status = await stub.status(StatusRequest());
428 + final status = await CwMweb.status(StatusRequest());
429 var date = DateTime.now();
430 var confirmations = 0;
431 if (utxo.height > 0) {
@@ -493,6 +491,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
491 }
492
493 Future<void> processMwebUtxos() async {
494 + print("processMwebUtxos() called!");
495 if (!mwebEnabled) {
496 return;
497 }
@@ -502,7 +501,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
501 final req = UtxosRequest(scanSecret: scanSecret, fromHeight: restoreHeight);
502
503 // process new utxos as they come in:
505 - _utxoStream?.cancel();
504 + await _utxoStream?.cancel();
505 ResponseStream<Utxo>? responseStream = await CwMweb.utxos(req);
506 if (responseStream == null) {
507 throw Exception("failed to get utxos stream!");
@@ -544,7 +543,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
543
544 await mwebUtxosBox.put(utxo.outputId, utxo);
545
547 - await handleIncoming(utxo, _stub);
546 + await handleIncoming(utxo);
547 });
548 }
549
@@ -662,6 +661,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
661 }
662
663 Future<void> updateUnspent() async {
664 + print("updateUnspent() called!");
665 await checkMwebUtxosSpent();
666 await updateAllUnspents();
667 }
@@ -675,7 +675,6 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
675 if (!mwebEnabled) {
676 return;
677 }
678 - await getStub();
678
679 // add the mweb unspents to the list:
680 List<BitcoinUnspent> mwebUnspentCoins = [];
@@ -718,7 +717,6 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
717 if (!mwebEnabled) {
718 return balance;
719 }
721 - await getStub();
720
721 // update unspent balances:
722 await updateUnspent();
@@ -891,7 +889,6 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
889 return tx;
890 }
891 await waitForMwebAddresses();
894 - await getStub();
892
893 final resp = await CwMweb.create(CreateRequest(
894 rawTx: hex.decode(tx.hex),
@@ -1000,13 +997,17 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
997 }
998
999 @override
1003 - Future<void> close() async {
1000 + Future<void> close({required bool shouldCleanup}) async {
1001 _utxoStream?.cancel();
1002 _feeRatesTimer?.cancel();
1003 _syncTimer?.cancel();
1004 _processingTimer?.cancel();
1008 - await stopSync();
1009 - await super.close();
1005 + if (shouldCleanup) {
1006 + try {
1007 + await stopSync();
1008 + } catch (_) {}
1009 + }
1010 + await super.close(shouldCleanup: shouldCleanup);
1011 }
1012
1013 Future<void> setMwebEnabled(bool enabled) async {
@@ -1014,17 +1015,16 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
1015 return;
1016 }
1017
1018 + alwaysScan = enabled;
1019 mwebEnabled = enabled;
1020 (walletAddresses as LitecoinWalletAddresses).mwebEnabled = enabled;
1019 - await stopSync();
1021 + await save();
1022 + try {
1023 + await stopSync();
1024 + } catch (_) {}
1025 await startSync();
1026 }
1027
1023 - Future<RpcClient> getStub() async {
1024 - _stub = await CwMweb.stub();
1025 - return _stub;
1026 - }
1027 -
1028 Future<StatusResponse> getStatusRequest() async {
1029 final resp = await CwMweb.status(StatusRequest());
1030 return resp;
cw_bitcoin/lib/litecoin_wallet_addresses.dart
+31 -24
@@ -1,4 +1,5 @@
1 import 'dart:async';
2 +import 'dart:io' show Platform;
3 import 'dart:typed_data';
4
5 import 'package:bitcoin_base/bitcoin_base.dart';
@@ -39,8 +40,10 @@ abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses with
40 bool mwebEnabled;
41 int mwebTopUpIndex = 1000;
42 List<String> mwebAddrs = [];
43 + bool generating = false;
44
45 List<int> get scanSecret => mwebHd.childKey(Bip32KeyIndex(0x80000000)).privateKey.privKey.raw;
46 +
47 List<int> get spendPubkey =>
48 mwebHd.childKey(Bip32KeyIndex(0x80000001)).publicKey.pubKey.compressed;
49
@@ -57,20 +60,38 @@ abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses with
60 }
61
62 Future<void> ensureMwebAddressUpToIndexExists(int index) async {
63 + if (Platform.isLinux || Platform.isMacOS || Platform.isWindows) {
64 + return null;
65 + }
66 +
67 Uint8List scan = Uint8List.fromList(scanSecret);
68 Uint8List spend = Uint8List.fromList(spendPubkey);
62 - int count = 0;
63 - while (mwebAddrs.length <= (index + 1)) {
64 - final address = await CwMweb.address(scan, spend, mwebAddrs.length);
65 - mwebAddrs.add(address!);
66 - count++;
67 - // sleep for a bit to avoid making the main thread unresponsive:
68 - if (count > 50) {
69 - count = 0;
70 - await Future.delayed(Duration(milliseconds: 100));
71 - }
69 +
70 + if (index < mwebAddresses.length && index < mwebAddrs.length) {
71 + return;
72 + }
73 +
74 + while (generating) {
75 + print("generating.....");
76 + // this function was called multiple times in multiple places:
77 + await Future.delayed(const Duration(milliseconds: 100));
78 }
79
80 + print("Generating MWEB addresses up to index $index");
81 + generating = true;
82 + try {
83 + while (mwebAddrs.length <= (index + 1)) {
84 + final addresses =
85 + await CwMweb.addresses(scan, spend, mwebAddrs.length, mwebAddrs.length + 50);
86 + print("generated up to index ${mwebAddrs.length}");
87 + // sleep for a bit to avoid making the main thread unresponsive:
88 + await Future.delayed(Duration(milliseconds: 200));
89 + mwebAddrs.addAll(addresses!);
90 + }
91 + } catch (_) {}
92 + generating = false;
93 + print("Done generating MWEB addresses len: ${mwebAddrs.length}");
94 +
95 // ensure mweb addresses are up to date:
96 if (mwebAddresses.length < mwebAddrs.length) {
97 List<BitcoinAddressRecord> addressRecords = mwebAddrs
@@ -90,21 +111,7 @@ abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses with
111
112 Future<void> initMwebAddresses() async {
113 if (mwebAddrs.length < 1000) {
93 - print("Generating MWEB addresses...");
114 await ensureMwebAddressUpToIndexExists(20);
95 - print("done generating MWEB addresses");
96 - // List<BitcoinAddressRecord> addressRecords = mwebAddrs
97 - // .asMap()
98 - // .entries
99 - // .map((e) => BitcoinAddressRecord(
100 - // e.value,
101 - // index: e.key,
102 - // type: SegwitAddresType.mweb,
103 - // network: network,
104 - // ))
105 - // .toList();
106 - // addMwebAddresses(addressRecords);
107 - // print("added ${addressRecords.length} mweb addresses");
115 return;
116 }
117 }
cw_bitcoin/lib/pending_bitcoin_transaction.dart
+2
@@ -117,6 +117,8 @@ class PendingBitcoinTransaction with PendingTransaction {
117 idOverride = resp.txid;
118 } on GrpcError catch (e) {
119 throw BitcoinTransactionCommitFailed(errorMessage: e.message);
120 + } catch (e) {
121 + throw BitcoinTransactionCommitFailed(errorMessage: "Unknown error: ${e.toString()}");
122 }
123 }
124
cw_core/lib/wallet_base.dart
+1 -1
@@ -83,7 +83,7 @@ abstract class WalletBase<BalanceType extends Balance, HistoryType extends Trans
83
84 Future<void> rescan({required int height});
85
86 - void close();
86 + Future<void> close({required bool shouldCleanup});
87
88 Future<void> changePassword(String password);
89
cw_evm/lib/evm_chain_wallet.dart
+1 -1
@@ -264,7 +264,7 @@ abstract class EVMChainWalletBase
264 }
265
266 @override
267 - void close() {
267 + Future<void> close({required bool shouldCleanup}) async {
268 _client.stop();
269 _transactionsUpdateTimer?.cancel();
270 _updateFeesTimer?.cancel();
cw_haven/lib/haven_wallet.dart
+1 -1
@@ -106,7 +106,7 @@ abstract class HavenWalletBase
106 Future<void>? updateBalance() => null;
107
108 @override
109 - void close() {
109 + Future<void> close({required bool shouldCleanup}) async {
110 _listener?.stop();
111 _onAccountChangeReaction?.reaction.dispose();
112 _autoSaveTimer?.cancel();
cw_haven/lib/haven_wallet_service.dart
+1 -1
@@ -116,7 +116,7 @@ class HavenWalletService extends WalletService<
116
117 if (!isValid) {
118 await restoreOrResetWalletFiles(name);
119 - wallet.close();
119 + wallet.close(shouldCleanup: false);
120 return openWallet(name, password);
121 }
122
cw_monero/lib/monero_wallet.dart
+1 -1
@@ -170,7 +170,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
170 Future<void>? updateBalance() => null;
171
172 @override
173 - void close() async {
173 + Future<void> close({required bool shouldCleanup}) async {
174 _listener?.stop();
175 _onAccountChangeReaction?.reaction.dispose();
176 _onTxHistoryChangeReaction?.reaction.dispose();
cw_monero/lib/monero_wallet_service.dart
+1 -1
@@ -137,7 +137,7 @@ class MoneroWalletService extends WalletService<
137
138 if (!isValid) {
139 await restoreOrResetWalletFiles(name);
140 - wallet.close();
140 + wallet.close(shouldCleanup: false);
141 return openWallet(name, password);
142 }
143
cw_mweb/android/src/main/kotlin/com/cakewallet/mweb/CwMwebPlugin.kt
+9 -2
@@ -40,10 +40,17 @@ class CwMwebPlugin: FlutterPlugin, MethodCallHandler {
40 port = null
41 result.success(null)
42 } else if (call.method == "address") {
43 + // val scanSecret: ByteArray = call.argument<ByteArray>("scanSecret") ?: ByteArray(0)
44 + // val spendPub: ByteArray = call.argument<ByteArray>("spendPub") ?: ByteArray(0)
45 + // val index: Int = call.argument<Int>("index") ?: 0
46 + // val res = Mwebd.address(scanSecret, spendPub, index)
47 + // result.success(res)
48 + } else if (call.method == "addresses") {
49 val scanSecret: ByteArray = call.argument<ByteArray>("scanSecret") ?: ByteArray(0)
50 val spendPub: ByteArray = call.argument<ByteArray>("spendPub") ?: ByteArray(0)
45 - val index: Int = call.argument<Int>("index") ?: 0
46 - val res = Mwebd.address(scanSecret, spendPub, index)
51 + val fromIndex: Int = call.argument<Int>("fromIndex") ?: 0
52 + val toIndex: Int = call.argument<Int>("toIndex") ?: 0
53 + val res = Mwebd.addresses(scanSecret, spendPub, fromIndex, toIndex)
54 result.success(res)
55 } else {
56 result.notImplemented()
cw_mweb/ios/Classes/CwMwebPlugin.swift
+14 -3
@@ -32,15 +32,26 @@ public static func register(with registrar: FlutterPluginRegistrar) {
32 stopServer()
33 result(nil)
34 break
35 - case "address":
35 + // case "address":
36 + // let args = call.arguments as! [String: Any]
37 + // let scanSecret = args["scanSecret"] as! FlutterStandardTypedData
38 + // let spendPub = args["spendPub"] as! FlutterStandardTypedData
39 + // let index = args["index"] as! Int32
40 +
41 + // let scanSecretData = scanSecret.data
42 + // let spendPubData = spendPub.data
43 + // result(MwebdAddress(scanSecretData, spendPubData, index))
44 + // break
45 + case "addresses":
46 let args = call.arguments as! [String: Any]
47 let scanSecret = args["scanSecret"] as! FlutterStandardTypedData
48 let spendPub = args["spendPub"] as! FlutterStandardTypedData
39 - let index = args["index"] as! Int32
49 + let fromIndex = args["fromIndex"] as! Int32
50 + let toIndex = args["toIndex"] as! Int32
51
52 let scanSecretData = scanSecret.data
53 let spendPubData = spendPub.data
43 - result(MwebdAddress(scanSecretData, spendPubData, index))
54 + result(MwebdAddresses(scanSecretData, spendPubData, fromIndex, toIndex))
55 break
56 default:
57 result(FlutterMethodNotImplemented)
cw_mweb/lib/cw_mweb.dart
+98 -35
@@ -1,3 +1,7 @@
1 +import 'dart:async';
2 +import 'dart:convert';
3 +import 'dart:developer';
4 +import 'dart:io';
5 import 'dart:typed_data';
6
7 import 'package:grpc/grpc.dart';
@@ -10,25 +14,51 @@ class CwMweb {
14 static ClientChannel? _clientChannel;
15 static int? _port;
16 static const TIMEOUT_DURATION = Duration(seconds: 5);
17 + static Timer? logTimer;
18
14 - static Future<void> _initializeClient() async {
15 - await stop();
16 - // wait a few seconds to make sure the server is stopped
17 - await Future.delayed(const Duration(seconds: 5));
19 + static void readFileWithTimer(String filePath) {
20 + final file = File(filePath);
21 + int lastLength = 0;
22 +
23 + logTimer?.cancel();
24 + logTimer = Timer.periodic(const Duration(seconds: 1), (timer) async {
25 + try {
26 + final currentLength = await file.length();
27 +
28 + if (currentLength != lastLength) {
29 + final fileStream = file.openRead(lastLength, currentLength);
30 + final newLines = await fileStream.transform(utf8.decoder).join();
31 + lastLength = currentLength;
32 + log(newLines);
33 + }
34 + } on GrpcError catch (e) {
35 + log('Caught grpc error: ${e.message}');
36 + } catch (e) {
37 + log('The mwebd debug log probably is not initialized yet.');
38 + }
39 + });
40 + }
41
42 + static Future<void> _initializeClient() async {
43 + print("initialize client called!");
44 final appDir = await getApplicationSupportDirectory();
20 - const ltcNodeUri = "45.79.13.180:9333";
45 + const ltcNodeUri = "ltc-electrum.cakewallet.com:9333";
46 +
47 + String debugLogPath = "${appDir.path}/logs/debug.log";
48 + readFileWithTimer(debugLogPath);
49 +
50 _port = await CwMwebPlatform.instance.start(appDir.path, ltcNodeUri);
51 if (_port == null || _port == 0) {
52 throw Exception("Failed to start server");
53 }
25 - print("Attempting to connect to server on port: $_port");
54 + log("Attempting to connect to server on port: $_port");
55
56 // wait for the server to finish starting up before we try to connect to it:
57 await Future.delayed(const Duration(seconds: 5));
58
59 _clientChannel = ClientChannel('127.0.0.1', port: _port!, channelShutdownHandler: () {
31 - print("Channel is shutting down!");
60 + _rpcClient = null;
61 + log("Channel is shutting down!");
62 },
63 options: const ChannelOptions(
64 credentials: ChannelCredentials.insecure(),
@@ -49,9 +79,15 @@ class CwMweb {
79 throw Exception("blockTime shouldn't be 0! (this connection is likely broken)");
80 }
81 return _rpcClient!;
82 + } on GrpcError catch (e) {
83 + log("Attempt $i failed: $e");
84 + log('Caught grpc error: ${e.message}');
85 + _rpcClient = null;
86 + await Future.delayed(const Duration(seconds: 3));
87 } catch (e) {
53 - print("Attempt $i failed: $e");
88 + log("Attempt $i failed: $e");
89 _rpcClient = null;
90 + await Future.delayed(const Duration(seconds: 3));
91 }
92 }
93 throw Exception("Failed to connect after $maxRetries attempts");
@@ -61,22 +97,43 @@ class CwMweb {
97 try {
98 await CwMwebPlatform.instance.stop();
99 await cleanup();
100 + } on GrpcError catch (e) {
101 + log('Caught grpc error: ${e.message}');
102 } catch (e) {
65 - print("Error stopping server: $e");
103 + log("Error stopping server: $e");
104 }
105 }
106
107 static Future<String?> address(Uint8List scanSecret, Uint8List spendPub, int index) async {
108 try {
71 - return CwMwebPlatform.instance.address(scanSecret, spendPub, index);
109 + return (await CwMwebPlatform.instance.addresses(scanSecret, spendPub, index, index + 1))
110 + ?.split(',')
111 + .first;
112 + } on GrpcError catch (e) {
113 + log('Caught grpc error: ${e.message}');
114 + } catch (e) {
115 + log("Error getting address: $e");
116 + }
117 + return null;
118 + }
119 +
120 + static Future<List<String>?> addresses(
121 + Uint8List scanSecret, Uint8List spendPub, int fromIndex, int toIndex) async {
122 + try {
123 + return (await CwMwebPlatform.instance.addresses(scanSecret, spendPub, fromIndex, toIndex))
124 + ?.split(',');
125 + } on GrpcError catch (e) {
126 + log('Caught grpc error: ${e.message}');
127 } catch (e) {
73 - print("Error getting address: $e");
74 - return null;
128 + log("Error getting addresses: $e");
129 }
130 + return null;
131 }
132
133 static Future<void> cleanup() async {
79 - await _clientChannel?.terminate();
134 + try {
135 + await _clientChannel?.terminate();
136 + } catch (_) {}
137 _rpcClient = null;
138 _clientChannel = null;
139 _port = null;
@@ -84,51 +141,57 @@ class CwMweb {
141
142 // wrappers that handle the connection issues:
143 static Future<SpentResponse> spent(SpentRequest request) async {
144 + log("mweb.spent() called");
145 try {
88 - if (_rpcClient == null) {
89 - await _initializeClient();
90 - }
146 + _rpcClient = await stub();
147 return await _rpcClient!.spent(request, options: CallOptions(timeout: TIMEOUT_DURATION));
148 + } on GrpcError catch (e) {
149 + log('Caught grpc error: ${e.message}');
150 } catch (e) {
93 - print("Error getting spent: $e");
94 - return SpentResponse();
151 + log("Error getting spent: $e");
152 }
153 + return SpentResponse();
154 }
155
156 static Future<StatusResponse> status(StatusRequest request) async {
157 + log("mweb.status() called");
158 try {
100 - if (_rpcClient == null) {
101 - await _initializeClient();
102 - }
159 + _rpcClient = await stub();
160 return await _rpcClient!.status(request, options: CallOptions(timeout: TIMEOUT_DURATION));
161 + } on GrpcError catch (e) {
162 + log('Caught grpc error: ${e.message}');
163 } catch (e) {
105 - print("Error getting status: $e");
106 - return StatusResponse();
164 + log("Error getting status: $e");
165 }
166 + return StatusResponse();
167 }
168
169 static Future<CreateResponse> create(CreateRequest request) async {
170 + log("mweb.create() called");
171 try {
112 - if (_rpcClient == null) {
113 - await _initializeClient();
114 - }
172 + _rpcClient = await stub();
173 return await _rpcClient!.create(request, options: CallOptions(timeout: TIMEOUT_DURATION));
174 + } on GrpcError catch (e) {
175 + log('Caught grpc error: ${e.message}');
176 } catch (e) {
117 - print("Error getting create: $e");
118 - return CreateResponse();
177 + log("Error getting create: $e");
178 }
179 + return CreateResponse();
180 }
181
182 static Future<ResponseStream<Utxo>?> utxos(UtxosRequest request) async {
183 + log("mweb.utxos() called");
184 try {
124 - if (_rpcClient == null) {
125 - await _initializeClient();
126 - }
127 - // this is a stream, so we should have an effectively infinite timeout:
128 - return _rpcClient!.utxos(request, options: CallOptions(timeout: const Duration(days: 1000 * 365)));
185 + _rpcClient = await stub();
186 + final resp = _rpcClient!
187 + .utxos(request, options: CallOptions(timeout: const Duration(days: 1000 * 365)));
188 + log("got utxo stream");
189 + return resp;
190 + } on GrpcError catch (e) {
191 + log('Caught grpc error: ${e.message}');
192 } catch (e) {
130 - print("Error getting utxos: $e");
131 - return null;
193 + log("Error getting utxos: $e");
194 }
195 + return null;
196 }
197 }
cw_mweb/lib/cw_mweb_method_channel.dart
+25
@@ -1,3 +1,5 @@
1 +import 'dart:io' show Platform;
2 +
3 import 'package:flutter/foundation.dart';
4 import 'package:flutter/services.dart';
5
@@ -11,6 +13,9 @@ class MethodChannelCwMweb extends CwMwebPlatform {
13
14 @override
15 Future<int?> start(String dataDir, String nodeUri) async {
16 + if (Platform.isLinux || Platform.isMacOS || Platform.isWindows) {
17 + return null;
18 + }
19 final result =
20 await methodChannel.invokeMethod<int>('start', {'dataDir': dataDir, 'nodeUri': nodeUri});
21 return result;
@@ -18,11 +23,17 @@ class MethodChannelCwMweb extends CwMwebPlatform {
23
24 @override
25 Future<void> stop() async {
26 + if (Platform.isLinux || Platform.isMacOS || Platform.isWindows) {
27 + return;
28 + }
29 await methodChannel.invokeMethod<void>('stop');
30 }
31
32 @override
33 Future<String?> address(Uint8List scanSecret, Uint8List spendPub, int index) async {
34 + if (Platform.isLinux || Platform.isMacOS || Platform.isWindows) {
35 + return null;
36 + }
37 final result = await methodChannel.invokeMethod<String>('address', {
38 'scanSecret': scanSecret,
39 'spendPub': spendPub,
@@ -30,4 +41,18 @@ class MethodChannelCwMweb extends CwMwebPlatform {
41 });
42 return result;
43 }
44 +
45 + @override
46 + Future<String?> addresses(Uint8List scanSecret, Uint8List spendPub, int fromIndex, int toIndex) async {
47 + if (Platform.isLinux || Platform.isMacOS || Platform.isWindows) {
48 + return null;
49 + }
50 + final result = await methodChannel.invokeMethod<String>('addresses', {
51 + 'scanSecret': scanSecret,
52 + 'spendPub': spendPub,
53 + 'fromIndex': fromIndex,
54 + 'toIndex': toIndex,
55 + });
56 + return result;
57 + }
58 }
cw_mweb/lib/cw_mweb_platform_interface.dart
+4
@@ -36,4 +36,8 @@ abstract class CwMwebPlatform extends PlatformInterface {
36 Future<String?> address(Uint8List scanSecret, Uint8List spendPub, int index) {
37 throw UnimplementedError('address(int) has not been implemented.');
38 }
39 +
40 + Future<String?> addresses(Uint8List scanSecret, Uint8List spendPub, int fromIndex, int toIndex) {
41 + throw UnimplementedError('addresses has not been implemented.');
42 + }
43 }
cw_nano/lib/nano_wallet.dart
+1 -1
@@ -149,7 +149,7 @@ abstract class NanoWalletBase
149 Future<void> changePassword(String password) => throw UnimplementedError("changePassword");
150
151 @override
152 - void close() {
152 + Future<void> close({required bool shouldCleanup}) async {
153 _client.stop();
154 _receiveTimer?.cancel();
155 }
cw_nano/pubspec.lock
+2 -2
@@ -117,10 +117,10 @@ packages:
117 dependency: "direct overridden"
118 description:
119 name: build_runner_core
120 - sha256: "14febe0f5bac5ae474117a36099b4de6f1dbc52df6c5e55534b3da9591bf4292"
120 + sha256: "0671ad4162ed510b70d0eb4ad6354c249f8429cab4ae7a4cec86bbc2886eb76e"
121 url: "https://pub.dev"
122 source: hosted
123 - version: "7.2.7"
123 + version: "7.2.7+1"
124 built_collection:
125 dependency: transitive
126 description:
cw_solana/lib/solana_wallet.dart
+1 -1
@@ -179,7 +179,7 @@ abstract class SolanaWalletBase
179 Future<void> changePassword(String password) => throw UnimplementedError("changePassword");
180
181 @override
182 - void close() {
182 + Future<void> close({required bool shouldCleanup}) async {
183 _client.stop();
184 _transactionsUpdateTimer?.cancel();
185 }
cw_tron/lib/tron_wallet.dart
+1 -1
@@ -217,7 +217,7 @@ abstract class TronWalletBase
217 Future<void> changePassword(String password) => throw UnimplementedError("changePassword");
218
219 @override
220 - void close() => _transactionsUpdateTimer?.cancel();
220 + Future<void> close({required bool shouldCleanup}) async => _transactionsUpdateTimer?.cancel();
221
222 @action
223 @override
cw_wownero/lib/wownero_wallet.dart
+1 -1
@@ -160,7 +160,7 @@ abstract class WowneroWalletBase
160 Future<void>? updateBalance() => null;
161
162 @override
163 - void close() async {
163 + Future<void> close({required bool shouldCleanup}) async {
164 _listener?.stop();
165 _onAccountChangeReaction?.reaction.dispose();
166 _onTxHistoryChangeReaction?.reaction.dispose();
cw_wownero/lib/wownero_wallet_service.dart
+1 -1
@@ -134,7 +134,7 @@ class WowneroWalletService extends WalletService<
134
135 if (!isValid) {
136 await restoreOrResetWalletFiles(name);
137 - wallet.close();
137 + wallet.close(shouldCleanup: false);
138 return openWallet(name, password);
139 }
140
ios/Podfile.lock
+41 -5
@@ -7,7 +7,38 @@ PODS:
7 - Flutter
8 - ReachabilitySwift
9 - CryptoSwift (1.8.2)
10 + - cw_haven (0.0.1):
11 + - cw_haven/Boost (= 0.0.1)
12 + - cw_haven/Haven (= 0.0.1)
13 + - cw_haven/OpenSSL (= 0.0.1)
14 + - cw_haven/Sodium (= 0.0.1)
15 + - cw_shared_external
16 + - Flutter
17 + - cw_haven/Boost (0.0.1):
18 + - cw_shared_external
19 + - Flutter
20 + - cw_haven/Haven (0.0.1):
21 + - cw_shared_external
22 + - Flutter
23 + - cw_haven/OpenSSL (0.0.1):
24 + - cw_shared_external
25 + - Flutter
26 + - cw_haven/Sodium (0.0.1):
27 + - cw_shared_external
28 + - Flutter
29 - cw_mweb (0.0.1):
30 + - Flutter
31 + - cw_shared_external (0.0.1):
32 + - cw_shared_external/Boost (= 0.0.1)
33 + - cw_shared_external/OpenSSL (= 0.0.1)
34 + - cw_shared_external/Sodium (= 0.0.1)
35 + - Flutter
36 + - cw_shared_external/Boost (0.0.1):
37 + - Flutter
38 + - cw_shared_external/OpenSSL (0.0.1):
39 + - Flutter
40 + - cw_shared_external/Sodium (0.0.1):
41 + - Flutter
42 - device_display_brightness (0.0.1):
43 - Flutter
44 - device_info_plus (0.0.1):
@@ -96,7 +127,7 @@ PODS:
127 - FlutterMacOS
128 - sp_scanner (0.0.1):
129 - Flutter
99 - - SwiftProtobuf (1.26.0)
130 + - SwiftProtobuf (1.27.1)
131 - SwiftyGif (5.4.5)
132 - Toast (4.1.1)
133 - uni_links (0.0.1):
@@ -112,7 +143,9 @@ DEPENDENCIES:
143 - barcode_scan2 (from `.symlinks/plugins/barcode_scan2/ios`)
144 - connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`)
145 - CryptoSwift
146 + - cw_haven (from `.symlinks/plugins/cw_haven/ios`)
147 - cw_mweb (from `.symlinks/plugins/cw_mweb/ios`)
148 + - cw_shared_external (from `.symlinks/plugins/cw_shared_external/ios`)
149 - device_display_brightness (from `.symlinks/plugins/device_display_brightness/ios`)
150 - device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
151 - devicelocale (from `.symlinks/plugins/devicelocale/ios`)
@@ -125,7 +158,6 @@ DEPENDENCIES:
158 - fluttertoast (from `.symlinks/plugins/fluttertoast/ios`)
159 - in_app_review (from `.symlinks/plugins/in_app_review/ios`)
160 - integration_test (from `.symlinks/plugins/integration_test/ios`)
128 - - package_info (from `.symlinks/plugins/package_info/ios`)
161 - package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
162 - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
163 - permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
@@ -158,8 +190,12 @@ EXTERNAL SOURCES:
190 :path: ".symlinks/plugins/barcode_scan2/ios"
191 connectivity_plus:
192 :path: ".symlinks/plugins/connectivity_plus/ios"
193 + cw_haven:
194 + :path: ".symlinks/plugins/cw_haven/ios"
195 cw_mweb:
196 :path: ".symlinks/plugins/cw_mweb/ios"
197 + cw_shared_external:
198 + :path: ".symlinks/plugins/cw_shared_external/ios"
199 device_display_brightness:
200 :path: ".symlinks/plugins/device_display_brightness/ios"
201 device_info_plus:
@@ -184,8 +220,6 @@ EXTERNAL SOURCES:
220 :path: ".symlinks/plugins/in_app_review/ios"
221 integration_test:
222 :path: ".symlinks/plugins/integration_test/ios"
187 - package_info:
188 - :path: ".symlinks/plugins/package_info/ios"
223 package_info_plus:
224 :path: ".symlinks/plugins/package_info_plus/ios"
225 path_provider_foundation:
@@ -215,7 +249,9 @@ SPEC CHECKSUMS:
249 barcode_scan2: 0af2bb63c81b4565aab6cd78278e4c0fa136dbb0
250 connectivity_plus: bf0076dd84a130856aa636df1c71ccaff908fa1d
251 CryptoSwift: c63a805d8bb5e5538e88af4e44bb537776af11ea
252 + cw_haven: b3e54e1fbe7b8e6fda57a93206bc38f8e89b898a
253 cw_mweb: 87af74f9659fed0c1a2cbfb44413f1070e79e3ae
254 + cw_shared_external: 2972d872b8917603478117c9957dfca611845a92
255 device_display_brightness: 1510e72c567a1f6ce6ffe393dcd9afd1426034f7
256 device_info_plus: c6fb39579d0f423935b0c9ce7ee2f44b71b9fce6
257 devicelocale: b22617f40038496deffba44747101255cee005b0
@@ -243,7 +279,7 @@ SPEC CHECKSUMS:
279 share_plus: 8875f4f2500512ea181eef553c3e27dba5135aad
280 shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78
281 sp_scanner: eaa617fa827396b967116b7f1f43549ca62e9a12
246 - SwiftProtobuf: 5e8349171e7c2f88f5b9e683cb3cb79d1dc780b3
282 + SwiftProtobuf: b109bd17979d7993a84da14b1e1fdd8b0ded934a
283 SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4
284 Toast: 1f5ea13423a1e6674c4abdac5be53587ae481c4e
285 uni_links: d97da20c7701486ba192624d99bffaaffcfc298a
ios/Runner.xcodeproj/project.pbxproj
+27 -27
@@ -14,12 +14,12 @@
14 2193F104374FA2746CE8945B /* ResourceHelper.swift in Resources */ = {isa = PBXBuildFile; fileRef = 78D25C60B94E9D9E48D52E5E /* ResourceHelper.swift */; settings = {ASSET_TAGS = (BreezSDK, ); }; };
15 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
16 495FEFF9B395392FED3425DE /* TaskProtocol.swift in Resources */ = {isa = PBXBuildFile; fileRef = 0F42D8065219E0653321EE2B /* TaskProtocol.swift */; settings = {ASSET_TAGS = (BreezSDK, ); }; };
17 - 4DFD1BB54A3A50573E19A583 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3C663361C56EBB242598F609 /* Pods_Runner.framework */; };
17 525A2200C6C2A43EDC5C8FC5 /* BreezSDKConnector.swift in Resources */ = {isa = PBXBuildFile; fileRef = 1FB06A93B13D606F06B3924D /* BreezSDKConnector.swift */; settings = {ASSET_TAGS = (BreezSDK, ); }; };
18 6909E1D79C9986ADF2DE41E9 /* LnurlPayInvoice.swift in Resources */ = {isa = PBXBuildFile; fileRef = DCEA540E3586164FB47AD13E /* LnurlPayInvoice.swift */; settings = {ASSET_TAGS = (BreezSDK, ); }; };
19 724FDA327BF191BC29DCAA2E /* Constants.swift in Resources */ = {isa = PBXBuildFile; fileRef = 0CCA7ADAD6FF9185EBBB2BCA /* Constants.swift */; settings = {ASSET_TAGS = (BreezSDK, ); }; };
20 73138617307FA4F838D21D62 /* ServiceLogger.swift in Resources */ = {isa = PBXBuildFile; fileRef = F42258C3697CFE3C8C8D1933 /* ServiceLogger.swift */; settings = {ASSET_TAGS = (BreezSDK, ); }; };
21 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
22 + 8B1F4FCAA5EB9F3A83D32D5F /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D7CD6B6020744E8FA471915D /* Pods_Runner.framework */; };
23 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
24 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
25 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
@@ -50,6 +50,7 @@
50 /* End PBXCopyFilesBuildPhase section */
51
52 /* Begin PBXFileReference section */
53 + 014D7E4DBCFD76DDE652A4D9 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
54 0C400E0F25B21ABB0025E469 /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = "<group>"; };
55 0C44A7192518EF8000B570ED /* decrypt.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = decrypt.swift; sourceTree = "<group>"; };
56 0C50DFB82BF3CB56002B0EB3 /* MoneroWallet.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = MoneroWallet.framework; sourceTree = "<group>"; };
@@ -57,13 +58,11 @@
58 0C9D68C8264854B60011B691 /* secRandom.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = secRandom.swift; sourceTree = "<group>"; };
59 0CCA7ADAD6FF9185EBBB2BCA /* Constants.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Constants.swift; path = "../.symlinks/plugins/breez_sdk/ios/bindings-swift/Sources/BreezSDK/Constants.swift"; sourceTree = "<group>"; };
60 0F42D8065219E0653321EE2B /* TaskProtocol.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TaskProtocol.swift; path = "../.symlinks/plugins/breez_sdk/ios/bindings-swift/Sources/BreezSDK/TaskProtocol.swift"; sourceTree = "<group>"; };
60 - 11F9FC13F9EE2A705B213FA9 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
61 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
62 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
63 - 1F083F2041D1F553F2AF8B62 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
63 1FB06A93B13D606F06B3924D /* BreezSDKConnector.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BreezSDKConnector.swift; path = "../.symlinks/plugins/breez_sdk/ios/bindings-swift/Sources/BreezSDK/BreezSDKConnector.swift"; sourceTree = "<group>"; };
64 + 28F61114229803070973270D /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
65 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
66 - 3C663361C56EBB242598F609 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
66 41102141140E57B1DC27FBA1 /* SDKNotificationService.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SDKNotificationService.swift; path = "../.symlinks/plugins/breez_sdk/ios/bindings-swift/Sources/BreezSDK/SDKNotificationService.swift"; sourceTree = "<group>"; };
67 58C22CBD8C22B9D6023D59F8 /* LnurlPayInfo.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = LnurlPayInfo.swift; path = "../.symlinks/plugins/breez_sdk/ios/bindings-swift/Sources/BreezSDK/Task/LnurlPayInfo.swift"; sourceTree = "<group>"; };
68 5AFFEBFC279AD49C00F906A4 /* wakeLock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = wakeLock.swift; sourceTree = "<group>"; };
@@ -83,11 +82,12 @@
82 9D2F2C9F2555316C95EE7EA3 /* RedeemSwap.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RedeemSwap.swift; path = "../.symlinks/plugins/breez_sdk/ios/bindings-swift/Sources/BreezSDK/Task/RedeemSwap.swift"; sourceTree = "<group>"; };
83 9F46EE5D2BC11178009318F5 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
84 ABD6FCBB0F4244B090459128 /* BreezSDK.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BreezSDK.swift; path = "../.symlinks/plugins/breez_sdk/ios/bindings-swift/Sources/BreezSDK/BreezSDK.swift"; sourceTree = "<group>"; };
86 - AD0937B0140D5A4C24E73BEA /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
85 B3D5E78267F5F18D882FDC3B /* ServiceConfig.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ServiceConfig.swift; path = "../.symlinks/plugins/breez_sdk/ios/bindings-swift/Sources/BreezSDK/ServiceConfig.swift"; sourceTree = "<group>"; };
86 C58D93382C00FAC6004BCF69 /* libresolv.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libresolv.tbd; path = usr/lib/libresolv.tbd; sourceTree = SDKROOT; };
87 CE291CFD2C15DB9A00B9F709 /* WowneroWallet.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = WowneroWallet.framework; sourceTree = "<group>"; };
88 CEAFE49D2C539250009FF3AD /* Mwebd.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = Mwebd.xcframework; sourceTree = "<group>"; };
89 + D139E30AEB36740C21C00A9E /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
90 + D7CD6B6020744E8FA471915D /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
91 DCEA540E3586164FB47AD13E /* LnurlPayInvoice.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = LnurlPayInvoice.swift; path = "../.symlinks/plugins/breez_sdk/ios/bindings-swift/Sources/BreezSDK/Task/LnurlPayInvoice.swift"; sourceTree = "<group>"; };
92 F42258C3697CFE3C8C8D1933 /* ServiceLogger.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ServiceLogger.swift; path = "../.symlinks/plugins/breez_sdk/ios/bindings-swift/Sources/BreezSDK/ServiceLogger.swift"; sourceTree = "<group>"; };
93 /* End PBXFileReference section */
@@ -97,8 +97,8 @@
97 isa = PBXFrameworksBuildPhase;
98 buildActionMask = 2147483647;
99 files = (
100 - 4DFD1BB54A3A50573E19A583 /* Pods_Runner.framework in Frameworks */,
100 CEAFE4A02C53926F009FF3AD /* libresolv.tbd in Frameworks */,
101 + 8B1F4FCAA5EB9F3A83D32D5F /* Pods_Runner.framework in Frameworks */,
102 );
103 runOnlyForDeploymentPostprocessing = 0;
104 };
@@ -111,7 +111,7 @@
111 CEAFE49D2C539250009FF3AD /* Mwebd.xcframework */,
112 C58D93382C00FAC6004BCF69 /* libresolv.tbd */,
113 0C9986A3251A932F00D566FD /* CryptoSwift.framework */,
114 - 3C663361C56EBB242598F609 /* Pods_Runner.framework */,
114 + D7CD6B6020744E8FA471915D /* Pods_Runner.framework */,
115 );
116 name = Frameworks;
117 sourceTree = "<group>";
@@ -137,10 +137,10 @@
137 84389F1A05D5860790D82820 /* Pods */ = {
138 isa = PBXGroup;
139 children = (
140 - 11F9FC13F9EE2A705B213FA9 /* Pods-Runner.debug.xcconfig */,
141 - 1F083F2041D1F553F2AF8B62 /* Pods-Runner.release.xcconfig */,
142 - AD0937B0140D5A4C24E73BEA /* Pods-Runner.profile.xcconfig */,
140 0B80439B9064C9708DDB0ADA /* breez_sdk-OnDemandResources */,
141 + 014D7E4DBCFD76DDE652A4D9 /* Pods-Runner.debug.xcconfig */,
142 + 28F61114229803070973270D /* Pods-Runner.release.xcconfig */,
143 + D139E30AEB36740C21C00A9E /* Pods-Runner.profile.xcconfig */,
144 );
145 path = Pods;
146 sourceTree = "<group>";
@@ -222,14 +222,14 @@
222 isa = PBXNativeTarget;
223 buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
224 buildPhases = (
225 - B91154210ADCED81FBF06A85 /* [CP] Check Pods Manifest.lock */,
225 + 11278EDF4D5DB437B3FDB787 /* [CP] Check Pods Manifest.lock */,
226 CE5E8A222BEE19C700608EA1 /* CopyFiles */,
227 9740EEB61CF901F6004384FC /* Run Script */,
228 97C146EA1CF9000F007C117D /* Sources */,
229 97C146EB1CF9000F007C117D /* Frameworks */,
230 97C146EC1CF9000F007C117D /* Resources */,
231 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
232 - 32D0076A9969C0C38D68AF62 /* [CP] Embed Pods Frameworks */,
232 + F6F67323547956BC4F7B67F1 /* [CP] Embed Pods Frameworks */,
233 );
234 buildRules = (
235 );
@@ -305,21 +305,26 @@
305 /* End PBXResourcesBuildPhase section */
306
307 /* Begin PBXShellScriptBuildPhase section */
308 - 32D0076A9969C0C38D68AF62 /* [CP] Embed Pods Frameworks */ = {
308 + 11278EDF4D5DB437B3FDB787 /* [CP] Check Pods Manifest.lock */ = {
309 isa = PBXShellScriptBuildPhase;
310 buildActionMask = 2147483647;
311 files = (
312 );
313 inputFileListPaths = (
314 - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
314 );
316 - name = "[CP] Embed Pods Frameworks";
315 + inputPaths = (
316 + "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
317 + "${PODS_ROOT}/Manifest.lock",
318 + );
319 + name = "[CP] Check Pods Manifest.lock";
320 outputFileListPaths = (
318 - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
321 + );
322 + outputPaths = (
323 + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
324 );
325 runOnlyForDeploymentPostprocessing = 0;
326 shellPath = /bin/sh;
322 - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
327 + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
328 showEnvVarsInLog = 0;
329 };
330 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
@@ -353,26 +358,21 @@
358 shellPath = /bin/sh;
359 shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build\n";
360 };
356 - B91154210ADCED81FBF06A85 /* [CP] Check Pods Manifest.lock */ = {
361 + F6F67323547956BC4F7B67F1 /* [CP] Embed Pods Frameworks */ = {
362 isa = PBXShellScriptBuildPhase;
363 buildActionMask = 2147483647;
364 files = (
365 );
366 inputFileListPaths = (
367 + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
368 );
363 - inputPaths = (
364 - "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
365 - "${PODS_ROOT}/Manifest.lock",
366 - );
367 - name = "[CP] Check Pods Manifest.lock";
369 + name = "[CP] Embed Pods Frameworks";
370 outputFileListPaths = (
369 - );
370 - outputPaths = (
371 - "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
371 + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
372 );
373 runOnlyForDeploymentPostprocessing = 0;
374 shellPath = /bin/sh;
375 - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
375 + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
376 showEnvVarsInLog = 0;
377 };
378 /* End PBXShellScriptBuildPhase section */
lib/bitcoin/cw_bitcoin.dart
+11 -4
@@ -262,7 +262,14 @@ class CWBitcoin extends Bitcoin {
262 List<ReceivePageOption> getBitcoinReceivePageOptions() => BitcoinReceivePageOption.all;
263
264 @override
265 - List<ReceivePageOption> getLitecoinReceivePageOptions() => BitcoinReceivePageOption.allLitecoin;
265 + List<ReceivePageOption> getLitecoinReceivePageOptions() {
266 + if (Platform.isLinux || Platform.isMacOS || Platform.isWindows) {
267 + return BitcoinReceivePageOption.allLitecoin
268 + .where((element) => element != BitcoinReceivePageOption.mweb)
269 + .toList();
270 + }
271 + return BitcoinReceivePageOption.allLitecoin;
272 + }
273
274 @override
275 BitcoinAddressType getBitcoinAddressType(ReceivePageOption option) {
@@ -608,7 +615,7 @@ class CWBitcoin extends Bitcoin {
615
616 final updatedOutputs = outputs.map((output) {
617 try {
611 - final pendingOut = pendingTx!.outputs[outputs.indexOf(output)];
618 + final pendingOut = pendingTx.outputs[outputs.indexOf(output)];
619 final updatedOutput = output;
620
621 updatedOutput.stealthAddress = P2trAddress.fromScriptPubkey(script: pendingOut.scriptPubKey)
@@ -658,8 +665,8 @@ class CWBitcoin extends Bitcoin {
665 String? getUnusedMwebAddress(Object wallet) {
666 try {
667 final electrumWallet = wallet as ElectrumWallet;
661 - final walletAddresses = electrumWallet.walletAddresses as ElectrumWalletAddresses;
662 - final mwebAddress = walletAddresses.mwebAddresses.firstWhere((element) => !element.isUsed);
668 + final mwebAddress =
669 + electrumWallet.walletAddresses.mwebAddresses.firstWhere((element) => !element.isUsed);
670 return mwebAddress.address;
671 } catch (_) {
672 return null;
lib/src/screens/dashboard/pages/balance_page.dart
+57 -64
@@ -6,7 +6,6 @@ import 'package:cake_wallet/generated/i18n.dart';
6 import 'package:cake_wallet/reactions/wallet_connect.dart';
7 import 'package:cake_wallet/routes.dart';
8 import 'package:cake_wallet/src/screens/dashboard/pages/nft_listing_page.dart';
9 -import 'package:cake_wallet/src/screens/dashboard/widgets/action_button.dart';
9 import 'package:cake_wallet/src/screens/dashboard/widgets/home_screen_account_widget.dart';
10 import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
11 import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
@@ -20,12 +19,11 @@ import 'package:cake_wallet/themes/extensions/balance_page_theme.dart';
19 import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
20 import 'package:cake_wallet/themes/extensions/sync_indicator_theme.dart';
21 import 'package:cake_wallet/utils/feature_flag.dart';
23 -import 'package:cake_wallet/utils/payment_request.dart';
22 import 'package:cake_wallet/utils/show_pop_up.dart';
23 import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
24 import 'package:cake_wallet/view_model/dashboard/nft_view_model.dart';
27 -import 'package:cw_bitcoin/bitcoin_receive_page_option.dart';
25 import 'package:cw_core/crypto_currency.dart';
26 +import 'package:flutter/cupertino.dart';
27 import 'package:flutter/material.dart';
28 import 'package:flutter_mobx/flutter_mobx.dart';
29 import 'package:url_launcher/url_launcher.dart';
@@ -382,18 +380,10 @@ class CryptoBalanceWidget extends StatelessWidget {
380 child: DashBoardRoundedCardWidget(
381 customBorder: 30,
382 title: S.of(context).litecoin_mweb,
385 - subTitle: '',
383 + subTitle: S.of(context).litecoin_mweb_description,
384 hint: Column(
385 + crossAxisAlignment: CrossAxisAlignment.start,
386 children: [
388 - Text(
389 - S.of(context).litecoin_mweb_description,
390 - style: TextStyle(
391 - color: Colors.white,
392 - fontSize: 14,
393 - ),
394 - textAlign: TextAlign.center,
395 - ),
396 - SizedBox(height: 8),
387 GestureDetector(
388 behavior: HitTestBehavior.opaque,
389 onTap: () => launchUrl(
@@ -401,53 +391,64 @@ class CryptoBalanceWidget extends StatelessWidget {
391 "https://guides.cakewallet.com/docs/cryptos/litecoin/#mweb"),
392 mode: LaunchMode.externalApplication,
393 ),
404 - child: Center(
405 - child: Text(
406 - S.of(context).learn_more,
407 - style: TextStyle(
408 - fontSize: 12,
409 - fontFamily: 'Lato',
410 - fontWeight: FontWeight.w400,
411 - color: Theme.of(context)
412 - .extension<BalancePageTheme>()!
413 - .labelTextColor,
414 - height: 1,
415 - ),
416 - softWrap: true,
394 + child: Text(
395 + S.of(context).learn_more,
396 + style: TextStyle(
397 + fontSize: 12,
398 + fontFamily: 'Lato',
399 + fontWeight: FontWeight.w400,
400 + color: Theme.of(context)
401 + .extension<BalancePageTheme>()!
402 + .labelTextColor,
403 + height: 1,
404 ),
405 + softWrap: true,
406 ),
407 ),
420 - SizedBox(height: 24),
408 + SizedBox(height: 8),
409 Row(
422 - mainAxisAlignment: MainAxisAlignment.spaceEvenly,
410 children: [
424 - ElevatedButton(
425 - onPressed: () => _dismissMweb(context),
426 - style: ElevatedButton.styleFrom(
427 - backgroundColor: Theme.of(context).primaryColor,
428 - shape: RoundedRectangleBorder(
429 - borderRadius: BorderRadius.circular(50),
411 + Expanded(
412 + child: ElevatedButton(
413 + onPressed: () => _dismissMweb(context),
414 + style: ElevatedButton.styleFrom(
415 + backgroundColor: Theme.of(context).primaryColor,
416 + ),
417 + child: Text(
418 + S.of(context).litecoin_mweb_dismiss,
419 + style: TextStyle(color: Colors.white),
420 ),
431 - ),
432 - child: Text(
433 - S.of(context).litecoin_mweb_dismiss,
434 - style: TextStyle(color: Colors.white),
421 ),
422 ),
437 - ElevatedButton(
438 - onPressed: () => _enableMweb(context),
439 - child: Text(S.of(context).litecoin_enable_mweb_sync),
423 + const SizedBox(width: 8),
424 + Expanded(
425 + child: ElevatedButton(
426 + onPressed: () => _enableMweb(context),
427 + style: ElevatedButton.styleFrom(
428 + backgroundColor: Colors.white,
429 + foregroundColor: Colors.black,
430 + ),
431 + child: Text(
432 + S.of(context).enable,
433 + maxLines: 1,
434 + ),
435 + ),
436 ),
437 ],
438 ),
439 ],
440 ),
441 onTap: () => {},
446 - icon: ImageIcon(
447 - AssetImage('assets/images/mweb_logo.png'),
448 - color:
449 - Theme.of(context).extension<DashboardPageTheme>()!.pageTitleTextColor,
450 - size: 50,
442 + icon: Container(
443 + decoration: BoxDecoration(
444 + color: Colors.white,
445 + shape: BoxShape.circle,
446 + ),
447 + child: ImageIcon(
448 + AssetImage('assets/images/mweb_logo.png'),
449 + color: Color.fromARGB(255, 11, 70, 129),
450 + size: 40,
451 + ),
452 ),
453 ),
454 ),
@@ -505,7 +506,7 @@ class CryptoBalanceWidget extends StatelessWidget {
506 },
507 ));
508 }
508 - dashboardViewModel.setMwebScanningActive();
509 + dashboardViewModel.setMwebEnabled();
510 }
511
512 Future<void> _dismissMweb(BuildContext context) async {
@@ -850,23 +851,15 @@ class BalanceRowWidget extends StatelessWidget {
851 padding: EdgeInsets.only(right: 16, top: 16),
852 child: Column(
853 children: [
853 - CakeImageWidget(
854 - imageUrl: 'assets/images/mweb_logo.png',
855 - height: 40,
856 - width: 40,
857 - displayOnError: Container(
858 - height: 30.0,
859 - width: 30.0,
860 - child: Center(
861 - child: Text(
862 - currency.title.substring(0, min(currency.title.length, 2)),
863 - style: TextStyle(fontSize: 11),
864 - ),
865 - ),
866 - decoration: BoxDecoration(
867 - shape: BoxShape.circle,
868 - color: Colors.grey.shade400,
869 - ),
854 + Container(
855 + decoration: BoxDecoration(
856 + color: Colors.white,
857 + shape: BoxShape.circle,
858 + ),
859 + child: ImageIcon(
860 + AssetImage('assets/images/mweb_logo.png'),
861 + color: Color.fromARGB(255, 11, 70, 129),
862 + size: 40,
863 ),
864 ),
865 const SizedBox(height: 10),
lib/src/screens/dashboard/widgets/menu_widget.dart
+4 -10
@@ -97,14 +97,13 @@ class MenuWidgetState extends State<MenuWidget> {
97
98 @override
99 Widget build(BuildContext context) {
100 - List<SettingActions> items = SettingActions.all;
100 + List<SettingActions> items = List.of(SettingActions.all);
101 if (!widget.dashboardViewModel.hasSilentPayments) {
102 items.removeWhere((element) => element.name(context) == S.of(context).silent_payments_settings);
103 }
104 - // if (!widget.dashboardViewModel.hasMweb) {
105 - // itemCount--;
106 - // items.removeWhere((element) => element.name(context) == S.of(context).litecoin_mweb_settings);
107 - // }
104 + if (!widget.dashboardViewModel.hasMweb) {
105 + items.removeWhere((element) => element.name(context) == S.of(context).litecoin_mweb_settings);
106 + }
107 int itemCount = items.length;
108
109 moneroIcon = Image.asset('assets/images/monero_menu.png',
@@ -191,11 +190,6 @@ class MenuWidgetState extends State<MenuWidget> {
190
191 final item = items[index];
192
194 - if (!widget.dashboardViewModel.hasMweb &&
195 - item.name(context) == S.of(context).litecoin_mweb_settings) {
196 - return const SizedBox();
197 - }
198 -
193 final isLastTile = index == itemCount - 1;
194
195 return SettingActionButton(
lib/src/screens/root/root.dart
-7
@@ -135,10 +135,6 @@ class RootState extends State<Root> with WidgetsBindingObserver {
135 setState(() => _setInactive(true));
136 }
137
138 - if (widget.appStore.wallet?.type == WalletType.litecoin) {
139 - widget.appStore.wallet?.stopSync();
140 - }
141 -
138 break;
139 case AppLifecycleState.resumed:
140 widget.authService.requireAuth().then((value) {
@@ -148,9 +144,6 @@ class RootState extends State<Root> with WidgetsBindingObserver {
144 });
145 }
146 });
151 - if (widget.appStore.wallet?.type == WalletType.litecoin) {
152 - widget.appStore.wallet?.startSync();
153 - }
147 break;
148 default:
149 break;
lib/src/screens/settings/mweb_settings.dart
+2 -3
@@ -4,7 +4,6 @@ import 'package:cake_wallet/src/screens/base_page.dart';
4 import 'package:cake_wallet/src/screens/settings/widgets/settings_cell_with_arrow.dart';
5 import 'package:cake_wallet/src/screens/settings/widgets/settings_switcher_cell.dart';
6 import 'package:cake_wallet/view_model/settings/mweb_settings_view_model.dart';
7 -import 'package:cake_wallet/view_model/settings/silent_payments_settings_view_model.dart';
7 import 'package:flutter/material.dart';
8 import 'package:flutter_mobx/flutter_mobx.dart';
9
@@ -33,9 +32,9 @@ class MwebSettingsPage extends BasePage {
32 ),
33 SettingsSwitcherCell(
34 title: S.current.litecoin_mweb_always_scan,
36 - value: _mwebSettingsViewModel.mwebAlwaysScan,
35 + value: _mwebSettingsViewModel.mwebEnabled,
36 onValueChange: (_, bool value) {
38 - _mwebSettingsViewModel.setMwebAlwaysScan(value);
37 + _mwebSettingsViewModel.setMwebEnabled(value);
38 },
39 ),
40 SettingsCellWithArrow(
lib/src/widgets/setting_actions.dart
+1 -2
@@ -31,7 +31,6 @@ class SettingActions {
31 walletSettingAction,
32 addressBookSettingAction,
33 silentPaymentsSettingAction,
34 - litecoinMwebSettingAction,
34 securityBackupSettingAction,
35 privacySettingAction,
36 displaySettingAction,
@@ -50,7 +49,7 @@ class SettingActions {
49
50 static SettingActions litecoinMwebSettingAction = SettingActions._(
51 name: (context) => S.of(context).litecoin_mweb_settings,
53 - image: 'assets/images/bitcoin_menu.png',
52 + image: 'assets/images/litecoin_menu.png',
53 onTap: (BuildContext context) {
54 Navigator.pop(context);
55 Navigator.of(context).pushNamed(Routes.mwebSettings);
lib/store/app_store.dart
+2 -1
@@ -37,7 +37,8 @@ abstract class AppStoreBase with Store {
37 @action
38 Future<void> changeCurrentWallet(
39 WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo> wallet) async {
40 - this.wallet?.close();
40 + bool changingToSameWalletType = this.wallet?.type == wallet.type;
41 + this.wallet?.close(shouldCleanup: !changingToSameWalletType);
42 this.wallet = wallet;
43 this.wallet!.setExceptionHandler(ExceptionHandler.onError);
44
lib/view_model/dashboard/balance_view_model.dart
+30 -7
@@ -1,3 +1,4 @@
1 +import 'package:cake_wallet/bitcoin/bitcoin.dart';
2 import 'package:cake_wallet/entities/fiat_api_mode.dart';
3 import 'package:cake_wallet/entities/sort_balance_types.dart';
4 import 'package:cake_wallet/reactions/wallet_connect.dart';
@@ -31,6 +32,7 @@ class BalanceRecord {
32 required this.fiatSecondAdditionalBalance,
33 required this.asset,
34 required this.formattedAssetTitle});
35 +
36 final String fiatAdditionalBalance;
37 final String fiatAvailableBalance;
38 final String fiatFrozenBalance;
@@ -53,7 +55,22 @@ abstract class BalanceViewModelBase with Store {
55 : isReversing = false,
56 isShowCard = appStore.wallet!.walletInfo.isShowIntroCakePayCard,
57 wallet = appStore.wallet! {
56 - reaction((_) => appStore.wallet, _onWalletChange);
58 + reaction((_) => appStore.wallet, (wallet) {
59 + _onWalletChange(wallet);
60 + _checkMweb();
61 + });
62 +
63 + _checkMweb();
64 +
65 + reaction((_) => settingsStore.mwebAlwaysScan, (bool value) {
66 + _checkMweb();
67 + });
68 + }
69 +
70 + void _checkMweb() {
71 + if (wallet.type == WalletType.litecoin) {
72 + mwebEnabled = bitcoin!.getMwebEnabled(wallet);
73 + }
74 }
75
76 final AppStore appStore;
@@ -336,14 +353,19 @@ abstract class BalanceViewModelBase with Store {
353 });
354 }
355
356 + @observable
357 + bool mwebEnabled = false;
358 +
359 @computed
360 bool get hasAdditionalBalance => _hasAdditionalBalanceForWalletType(wallet.type);
361
362 @computed
343 - bool get hasSecondAdditionalBalance => _hasSecondAdditionalBalanceForWalletType(wallet.type);
363 + bool get hasSecondAdditionalBalance =>
364 + mwebEnabled && _hasSecondAdditionalBalanceForWalletType(wallet.type);
365
366 @computed
346 - bool get hasSecondAvailableBalance => _hasSecondAvailableBalanceForWalletType(wallet.type);
367 + bool get hasSecondAvailableBalance =>
368 + mwebEnabled && _hasSecondAvailableBalanceForWalletType(wallet.type);
369
370 bool _hasAdditionalBalanceForWalletType(WalletType type) {
371 switch (type) {
@@ -358,15 +380,16 @@ abstract class BalanceViewModelBase with Store {
380 }
381
382 bool _hasSecondAdditionalBalanceForWalletType(WalletType type) {
361 - if (wallet.type == WalletType.litecoin && settingsStore.mwebAlwaysScan) {
362 - // if ((wallet.balance[CryptoCurrency.ltc]?.secondAdditional ?? 0) > 0)
363 - return true;
383 + if (wallet.type == WalletType.litecoin) {
384 + if ((wallet.balance[CryptoCurrency.ltc]?.secondAdditional ?? 0) > 0) {
385 + return true;
386 + }
387 }
388 return false;
389 }
390
391 bool _hasSecondAvailableBalanceForWalletType(WalletType type) {
369 - if (wallet.type == WalletType.litecoin && settingsStore.mwebAlwaysScan) {
392 + if (wallet.type == WalletType.litecoin) {
393 return true;
394 }
395 return false;
lib/view_model/dashboard/dashboard_view_model.dart
+23 -16
@@ -1,4 +1,6 @@
1 +import 'dart:async';
2 import 'dart:convert';
3 +import 'dart:io' show Platform;
4
5 import 'package:cake_wallet/.secrets.g.dart' as secrets;
6 import 'package:cake_wallet/bitcoin/bitcoin.dart';
@@ -222,7 +224,10 @@ abstract class DashboardViewModelBase with Store {
224 // subname = nano!.getCurrentAccount(_wallet).label;
225 // }
226
225 - reaction((_) => appStore.wallet, _onWalletChange);
227 + reaction((_) => appStore.wallet, (wallet) {
228 + _onWalletChange(wallet);
229 + _checkMweb();
230 + });
231
232 connectMapToListWithTransform(
233 appStore.wallet!.transactionHistory.transactions,
@@ -256,16 +261,16 @@ abstract class DashboardViewModelBase with Store {
261 });
262 }
263
264 + _checkMweb();
265 + reaction((_) => settingsStore.mwebAlwaysScan, (bool value) {
266 + _checkMweb();
267 + });
268 + }
269 +
270 + void _checkMweb() {
271 if (hasMweb) {
260 - mwebScanningActive = bitcoin!.getMwebEnabled(wallet);
261 - settingsStore.mwebEnabled = mwebScanningActive;
262 - reaction((_) => settingsStore.mwebAlwaysScan, (bool alwaysScan) {
263 - if (alwaysScan) {
264 - mwebScanningActive = true;
265 - } else {
266 - mwebScanningActive = false;
267 - }
268 - });
272 + mwebEnabled = bitcoin!.getMwebEnabled(wallet);
273 + balanceViewModel.mwebEnabled = mwebEnabled;
274 }
275 }
276
@@ -430,34 +435,36 @@ abstract class DashboardViewModelBase with Store {
435 }
436
437 @computed
433 - bool get hasMweb => wallet.type == WalletType.litecoin;
438 + bool get hasMweb => wallet.type == WalletType.litecoin && (Platform.isIOS || Platform.isAndroid);
439
440 @computed
436 - bool get showMwebCard => hasMweb && settingsStore.mwebCardDisplay && !mwebScanningActive;
441 + bool get showMwebCard => hasMweb && settingsStore.mwebCardDisplay && !mwebEnabled;
442
443 @observable
439 - bool mwebScanningActive = false;
444 + bool mwebEnabled = false;
445
446 @computed
447 bool get hasEnabledMwebBefore => settingsStore.hasEnabledMwebBefore;
448
449 @action
445 - void setMwebScanningActive() {
450 + void setMwebEnabled() {
451 if (!hasMweb) {
452 return;
453 }
454
455 settingsStore.hasEnabledMwebBefore = true;
451 - mwebScanningActive = true;
456 + mwebEnabled = true;
457 bitcoin!.setMwebEnabled(wallet, true);
458 + balanceViewModel.mwebEnabled = true;
459 settingsStore.mwebAlwaysScan = true;
460 }
461
462 @action
463 void dismissMweb() {
464 settingsStore.mwebCardDisplay = false;
465 + balanceViewModel.mwebEnabled = false;
466 settingsStore.mwebAlwaysScan = false;
460 - mwebScanningActive = false;
467 + mwebEnabled = false;
468 bitcoin!.setMwebEnabled(wallet, false);
469 }
470
lib/view_model/settings/mweb_settings_view_model.dart
+9 -5
@@ -8,7 +8,10 @@ part 'mweb_settings_view_model.g.dart';
8 class MwebSettingsViewModel = MwebSettingsViewModelBase with _$MwebSettingsViewModel;
9
10 abstract class MwebSettingsViewModelBase with Store {
11 - MwebSettingsViewModelBase(this._settingsStore, this._wallet);
11 + MwebSettingsViewModelBase(this._settingsStore, this._wallet) {
12 + mwebEnabled = bitcoin!.getMwebEnabled(_wallet);
13 + _settingsStore.mwebAlwaysScan = mwebEnabled;
14 + }
15
16 final SettingsStore _settingsStore;
17 final WalletBase _wallet;
@@ -16,8 +19,8 @@ abstract class MwebSettingsViewModelBase with Store {
19 @computed
20 bool get mwebCardDisplay => _settingsStore.mwebCardDisplay;
21
19 - @computed
20 - bool get mwebAlwaysScan => _settingsStore.mwebAlwaysScan;
22 + @observable
23 + late bool mwebEnabled;
24
25 @action
26 void setMwebCardDisplay(bool value) {
@@ -25,8 +28,9 @@ abstract class MwebSettingsViewModelBase with Store {
28 }
29
30 @action
28 - void setMwebAlwaysScan(bool value) {
29 - _settingsStore.mwebAlwaysScan = value;
31 + void setMwebEnabled(bool value) {
32 + mwebEnabled = value;
33 bitcoin!.setMwebEnabled(_wallet, value);
34 + _settingsStore.mwebAlwaysScan = value;
35 }
36 }
lib/view_model/wallet_creation_vm.dart
+26 -24
@@ -188,36 +188,38 @@ abstract class WalletCreationVMBase with Store {
188 }
189 }
190
191 - Future<List<DerivationInfo>> getDerivationInfoFromQRCredentials(RestoredWallet restoreWallet) async {
192 - var list = <DerivationInfo>[];
193 - final walletType = restoreWallet.type;
194 - var appStore = getIt.get<AppStore>();
195 - var node = appStore.settingsStore.getCurrentNode(walletType);
196 -
197 - switch (walletType) {
198 - case WalletType.bitcoin:
199 - case WalletType.litecoin:
200 - return bitcoin!.getDerivationsFromMnemonic(
201 - mnemonic: restoreWallet.mnemonicSeed!,
202 - node: node,
203 - passphrase: restoreWallet.passphrase,
204 - );
205 - case WalletType.nano:
206 - return nanoUtil!.getDerivationsFromMnemonic(
207 - mnemonic: restoreWallet.mnemonicSeed!,
208 - node: node,
209 - );
210 - default:
211 - break;
212 - }
213 - return list;
191 + Future<List<DerivationInfo>> getDerivationInfoFromQRCredentials(
192 + RestoredWallet restoreWallet) async {
193 + var list = <DerivationInfo>[];
194 + final walletType = restoreWallet.type;
195 + var appStore = getIt.get<AppStore>();
196 + var node = appStore.settingsStore.getCurrentNode(walletType);
197 +
198 + switch (walletType) {
199 + case WalletType.bitcoin:
200 + case WalletType.litecoin:
201 + return bitcoin!.getDerivationsFromMnemonic(
202 + mnemonic: restoreWallet.mnemonicSeed!,
203 + node: node,
204 + passphrase: restoreWallet.passphrase,
205 + );
206 + case WalletType.nano:
207 + return nanoUtil!.getDerivationsFromMnemonic(
208 + mnemonic: restoreWallet.mnemonicSeed!,
209 + node: node,
210 + );
211 + default:
212 + break;
213 }
214 + return list;
215 + }
216
217 WalletCredentials getCredentials(dynamic options) => throw UnimplementedError();
218
219 Future<WalletBase> process(WalletCredentials credentials) => throw UnimplementedError();
220
220 - Future<WalletCredentials> getWalletCredentialsFromQRCredentials(RestoredWallet restoreWallet) async =>
221 + Future<WalletCredentials> getWalletCredentialsFromQRCredentials(
222 + RestoredWallet restoreWallet) async =>
223 throw UnimplementedError();
224
225 Future<WalletBase> processFromRestoredWallet(
lib/view_model/wallet_list/wallet_list_view_model.dart
+2
@@ -70,6 +70,8 @@ abstract class WalletListViewModelBase with Store {
70
71 @action
72 Future<void> loadWallet(WalletListItem walletItem) async {
73 + // bool switchingToSameWalletType = walletItem.type == _appStore.wallet?.type;
74 + // await _appStore.wallet?.close(shouldCleanup: !switchingToSameWalletType);
75 final wallet = await _walletLoadingService.load(walletItem.type, walletItem.name);
76 await _appStore.changeCurrentWallet(wallet);
77 }
macos/Podfile.lock
+7 -1
@@ -2,6 +2,8 @@ PODS:
2 - connectivity_plus (0.0.1):
3 - FlutterMacOS
4 - ReachabilitySwift
5 + - cw_mweb (0.0.1):
6 + - FlutterMacOS
7 - device_info_plus (0.0.1):
8 - FlutterMacOS
9 - devicelocale (0.0.1):
@@ -37,6 +39,7 @@ PODS:
39
40 DEPENDENCIES:
41 - connectivity_plus (from `Flutter/ephemeral/.symlinks/plugins/connectivity_plus/macos`)
42 + - cw_mweb (from `Flutter/ephemeral/.symlinks/plugins/cw_mweb/macos`)
43 - device_info_plus (from `Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos`)
44 - devicelocale (from `Flutter/ephemeral/.symlinks/plugins/devicelocale/macos`)
45 - flutter_inappwebview_macos (from `Flutter/ephemeral/.symlinks/plugins/flutter_inappwebview_macos/macos`)
@@ -60,6 +63,8 @@ SPEC REPOS:
63 EXTERNAL SOURCES:
64 connectivity_plus:
65 :path: Flutter/ephemeral/.symlinks/plugins/connectivity_plus/macos
66 + cw_mweb:
67 + :path: Flutter/ephemeral/.symlinks/plugins/cw_mweb/macos
68 device_info_plus:
69 :path: Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos
70 devicelocale:
@@ -91,6 +96,7 @@ EXTERNAL SOURCES:
96
97 SPEC CHECKSUMS:
98 connectivity_plus: 18d3c32514c886e046de60e9c13895109866c747
99 + cw_mweb: 7440b12ead811dda972a9918442ea2a458e8742c
100 device_info_plus: 5401765fde0b8d062a2f8eb65510fb17e77cf07f
101 devicelocale: 9f0f36ac651cabae2c33f32dcff4f32b61c38225
102 flutter_inappwebview_macos: 9600c9df9fdb346aaa8933812009f8d94304203d
@@ -105,7 +111,7 @@ SPEC CHECKSUMS:
111 share_plus: 36537c04ce0c3e3f5bd297ce4318b6d5ee5fd6cf
112 shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78
113 sp_scanner: 269d96e0ec3173e69156be7239b95182be3b8303
108 - url_launcher_macos: 5f437abeda8c85500ceb03f5c1938a8c5a705399
114 + url_launcher_macos: c82c93949963e55b228a30115bd219499a6fe404
115 wakelock_plus: 4783562c9a43d209c458cb9b30692134af456269
116
117 PODFILE CHECKSUM: 65ec1541137fb5b35d00490dec1bb48d4d9586bb
res/values/strings_ar.arb
+1
@@ -235,6 +235,7 @@
235 "edit_token": "تحرير الرمز المميز",
236 "electrum_address_disclaimer": "نقوم بإنشاء عناوين جديدة في كل مرة تستخدم فيها عنوانًا ، لكن العناوين السابقة تستمر في العمل",
237 "email_address": "عنوان البريد الالكترونى",
238 + "enable": "يُمكَِن",
239 "enable_mempool_api": "MEMPOOL API للحصول على رسوم وتواريخ دقيقة",
240 "enable_replace_by_fee": "تمكين الاستبدال",
241 "enable_silent_payments_scanning": "ابدأ في مسح المدفوعات الصامتة ، حتى يتم الوصول إلى الطرف",
res/values/strings_bg.arb
+1
@@ -235,6 +235,7 @@
235 "edit_token": "Редактиране на токена",
236 "electrum_address_disclaimer": "Нови адреси се генерират всеки път, когато използвате този, но и предишните продължават да работят",
237 "email_address": "Имейл адрес",
238 + "enable": "Активиране",
239 "enable_mempool_api": "Mempool API за точни такси и дати",
240 "enable_replace_by_fee": "Активиране на замяна по забрана",
241 "enable_silent_payments_scanning": "Започнете да сканирате безшумните плащания, докато се достигне съветът",
res/values/strings_cs.arb
+1
@@ -235,6 +235,7 @@
235 "edit_token": "Upravit token",
236 "electrum_address_disclaimer": "Po každém použití je generována nová adresa, ale předchozí adresy také stále fungují",
237 "email_address": "E-mailová adresa",
238 + "enable": "Umožnit",
239 "enable_mempool_api": "Mempool API pro přesné poplatky a data",
240 "enable_replace_by_fee": "Povolit výměnu podle poplatku",
241 "enable_silent_payments_scanning": "Začněte skenovat tiché platby, dokud není dosaženo špičky",
res/values/strings_de.arb
+1
@@ -235,6 +235,7 @@
235 "edit_token": "Token bearbeiten",
236 "electrum_address_disclaimer": "Wir generieren jedes Mal neue Adressen, wenn Sie eine verwenden, aber vorherige Adressen funktionieren weiterhin",
237 "email_address": "E-Mail-Adresse",
238 + "enable": "Aktivieren",
239 "enable_mempool_api": "Mempool -API für genaue Gebühren und Daten",
240 "enable_replace_by_fee": "Aktivieren Sie Ersatz für Fee",
241 "enable_silent_payments_scanning": "Scannen Sie stille Zahlungen, bis die Spitze erreicht ist",
res/values/strings_en.arb
+2 -1
@@ -235,6 +235,7 @@
235 "edit_token": "Edit token",
236 "electrum_address_disclaimer": "We generate new addresses each time you use one, but previous addresses continue to work",
237 "email_address": "Email Address",
238 + "enable": "Enable",
239 "enable_mempool_api": "Mempool API for accurate fees and dates",
240 "enable_replace_by_fee": "Enable Replace-By-Fee",
241 "enable_silent_payments_scanning": "Start scanning for transactions sent to your Silent Payment address.",
@@ -940,4 +941,4 @@
941 "you_will_get": "Convert to",
942 "you_will_send": "Convert from",
943 "yy": "YY"
943 -}
944 +}
\ No newline at end of file
res/values/strings_es.arb
+1
@@ -235,6 +235,7 @@
235 "edit_token": "Editar token",
236 "electrum_address_disclaimer": "Generamos nuevas direcciones cada vez que usa una, pero las direcciones anteriores siguen funcionando",
237 "email_address": "Dirección de correo electrónico",
238 + "enable": "Permitir",
239 "enable_mempool_api": "API de Mempool para tarifas y fechas precisas",
240 "enable_replace_by_fee": "Habilitar reemplazar por tarea",
241 "enable_silent_payments_scanning": "Comience a escanear pagos silenciosos, hasta que se alcance la punta",
res/values/strings_fr.arb
+1
@@ -235,6 +235,7 @@
235 "edit_token": "Modifier le token",
236 "electrum_address_disclaimer": "Nous générons de nouvelles adresses à chaque fois que vous en utilisez une, mais les adresses précédentes continuent à fonctionner",
237 "email_address": "Adresse e-mail",
238 + "enable": "Activer",
239 "enable_mempool_api": "API Mempool pour les frais et dates précis",
240 "enable_replace_by_fee": "Activer Remplace-by-Fee",
241 "enable_silent_payments_scanning": "Commencez à scanner les paiements silencieux, jusqu'à ce que la pointe soit atteinte",
res/values/strings_ha.arb
+1
@@ -235,6 +235,7 @@
235 "edit_token": "Gyara alamar",
236 "electrum_address_disclaimer": "Muna samar da sababbin adireshi duk lokacin da kuka yi amfani da ɗaya, amma adiresoshin da suka gabata suna ci gaba da aiki",
237 "email_address": "Adireshin i-mel",
238 + "enable": "Ba dama",
239 "enable_mempool_api": "Mampool API don ingantattun kudade da kwanakin",
240 "enable_replace_by_fee": "Ba da damar maye gurbin-by-kudin",
241 "enable_silent_payments_scanning": "Fara bincika biya na shiru, har sai tip ɗin ya kai",
res/values/strings_hi.arb
+1
@@ -235,6 +235,7 @@
235 "edit_token": "टोकन संपादित करें",
236 "electrum_address_disclaimer": "हर बार जब आप एक का उपयोग करते हैं तो हम नए पते उत्पन्न करते हैं, लेकिन पिछले पते काम करना जारी रखते हैं",
237 "email_address": "ईमेल पता",
238 + "enable": "सक्षम",
239 "enable_mempool_api": "सटीक शुल्क और तिथियों के लिए मेमपूल एपीआई",
240 "enable_replace_by_fee": "प्रतिस्थापित-दर-शुल्क सक्षम करें",
241 "enable_silent_payments_scanning": "मूक भुगतान स्कैनिंग सक्षम करें",
res/values/strings_hr.arb
+1
@@ -235,6 +235,7 @@
235 "edit_token": "Uredi token",
236 "electrum_address_disclaimer": "Minden egyes alkalommal új címeket generálunk, de a korábbi címek továbbra is működnek",
237 "email_address": "Adresa e-pošte",
238 + "enable": "Omogućiti",
239 "enable_mempool_api": "Mempool API za točne naknade i datume",
240 "enable_replace_by_fee": "Omogući zamjenu",
241 "enable_silent_payments_scanning": "Započnite skeniranje tihih plaćanja, dok se ne postigne savjet",
res/values/strings_hy.arb
+1
@@ -235,6 +235,7 @@
235 "edit_token": "Փոփոխել տոկեն",
236 "electrum_address_disclaimer": "Մենք ստեղծում ենք նոր հասցե ամեն անգամ, երբ դուք օգտագործում եք այն, բայց նախորդ հասցեները շարունակում են աշխատել",
237 "email_address": "Էլ. փոստի հասցե",
238 + "enable": "Միացնել",
239 "enable_mempool_api": "Mempool API ճշգրիտ վճարների եւ ամսաթվերի համար",
240 "enable_replace_by_fee": "Միացնել փոխարինումը միջնորդավճարով",
241 "enable_silent_payments_scanning": "Միացնել Լուռ Վճարումների սկանավորումը",
res/values/strings_id.arb
+1
@@ -235,6 +235,7 @@
235 "edit_token": "Mengedit token",
236 "electrum_address_disclaimer": "Kami menghasilkan alamat baru setiap kali Anda menggunakan satu, tetapi alamat sebelumnya tetap berfungsi",
237 "email_address": "Alamat Email",
238 + "enable": "Memungkinkan",
239 "enable_mempool_api": "API Mempool untuk biaya dan tanggal yang akurat",
240 "enable_replace_by_fee": "Aktifkan ganti-by-fee",
241 "enable_silent_payments_scanning": "Mulailah memindai pembayaran diam, sampai ujung tercapai",
res/values/strings_it.arb
+1
@@ -236,6 +236,7 @@
236 "edit_token": "Modifica token",
237 "electrum_address_disclaimer": "Generiamo nuovi indirizzi ogni volta che ne utilizzi uno, ma gli indirizzi precedenti continuano a funzionare",
238 "email_address": "Indirizzo e-mail",
239 + "enable": "Abilitare",
240 "enable_mempool_api": "API di Mempool per commissioni e date accurate",
241 "enable_replace_by_fee": "Abilita sostituzione per fee",
242 "enable_silent_payments_scanning": "Inizia a scansionare i pagamenti silenziosi, fino a raggiungere la punta",
res/values/strings_ja.arb
+1
@@ -235,6 +235,7 @@
235 "edit_token": "トークンの編集",
236 "electrum_address_disclaimer": "使用するたびに新しいアドレスが生成されますが、以前のアドレスは引き続き機能します",
237 "email_address": "メールアドレス",
238 + "enable": "有効にする",
239 "enable_mempool_api": "正確な料金と日付のMempool API",
240 "enable_replace_by_fee": "交換ごとに有効にします",
241 "enable_silent_payments_scanning": "先端に達するまで、サイレント決済のスキャンを開始します",
res/values/strings_ko.arb
+1
@@ -235,6 +235,7 @@
235 "edit_token": "토큰 편집",
236 "electrum_address_disclaimer": "사용할 때마다 새 주소가 생성되지만 이전 주소는 계속 작동합니다.",
237 "email_address": "이메일 주소",
238 + "enable": "할 수 있게 하다",
239 "enable_mempool_api": "정확한 수수료 및 날짜에 대한 Mempool API",
240 "enable_replace_by_fee": "대체별로 활성화하십시오",
241 "enable_silent_payments_scanning": "팁에 도달 할 때까지 사일런트 지불을 스캔하기 시작합니다.",
res/values/strings_my.arb
+1
@@ -235,6 +235,7 @@
235 "edit_token": "တိုကင်ကို တည်းဖြတ်ပါ။",
236 "electrum_address_disclaimer": "သင်အသုံးပြုသည့်အချိန်တိုင်းတွင် ကျွန်ုပ်တို့သည် လိပ်စာအသစ်များကို ထုတ်ပေးသော်လည်း ယခင်လိပ်စာများသည် ဆက်လက်အလုပ်လုပ်နေပါသည်။",
237 "email_address": "အီးမေးလ်လိပ်စာ",
238 + "enable": "စွမ်းဆောင်နိုင်စေ",
239 "enable_mempool_api": "Mempool API တိကျသောအခကြေးငွေနှင့်ရက်စွဲများအတွက်",
240 "enable_replace_by_fee": "အစားထိုး - by- အခကြေးငွေ enable",
241 "enable_silent_payments_scanning": "အစွန်အဖျားသို့ရောက်ရှိသည်အထိအသံတိတ်ငွေပေးချေမှုကိုစကင်ဖတ်စစ်ဆေးပါ",
res/values/strings_nl.arb
+1
@@ -235,6 +235,7 @@
235 "edit_token": "Token bewerken",
236 "electrum_address_disclaimer": "We genereren nieuwe adressen elke keer dat u er een gebruikt, maar eerdere adressen blijven werken",
237 "email_address": "E-mailadres",
238 + "enable": "Inschakelen",
239 "enable_mempool_api": "Mempool API voor nauwkeurige kosten en datums",
240 "enable_replace_by_fee": "Schakel vervangen door een fee",
241 "enable_silent_payments_scanning": "Begin met het scannen van stille betalingen, totdat de tip is bereikt",
res/values/strings_pl.arb
+1
@@ -235,6 +235,7 @@
235 "edit_token": "Edytuj token",
236 "electrum_address_disclaimer": "Za każdym razem, gdy wykorzystasz adres, dla wiekszej prywatności generujemy nowy, ale poprzednie adresy nadal działają, i moga odbierać środki",
237 "email_address": "Adres e-mail",
238 + "enable": "Włączać",
239 "enable_mempool_api": "Mempool API dla dokładnych opłat i dat",
240 "enable_replace_by_fee": "Włącz wymianę po lewej",
241 "enable_silent_payments_scanning": "Zacznij skanować ciche płatności, aż do osiągnięcia wskazówki",
res/values/strings_pt.arb
+1
@@ -235,6 +235,7 @@
235 "edit_token": "Editar símbolo",
236 "electrum_address_disclaimer": "Geramos novos endereços cada vez que você usa um, mas os endereços anteriores continuam funcionando",
237 "email_address": "Endereço de e-mail",
238 + "enable": "Habilitar",
239 "enable_mempool_api": "Mempool API para taxas e datas precisas",
240 "enable_replace_by_fee": "Habilite substituir por taxa",
241 "enable_silent_payments_scanning": "Comece a escanear pagamentos silenciosos, até que o topo seja alcançada",
res/values/strings_ru.arb
+1
@@ -235,6 +235,7 @@
235 "edit_token": "Изменить токен",
236 "electrum_address_disclaimer": "Мы генерируем новые адреса каждый раз, когда вы их используете, но предыдущие адреса продолжают работать.",
237 "email_address": "Адрес электронной почты",
238 + "enable": "Давать возможность",
239 "enable_mempool_api": "Mempool API за точные сборы и даты",
240 "enable_replace_by_fee": "Включить замену за пикой",
241 "enable_silent_payments_scanning": "Начните сканировать безмолвные платежи, пока не будет достигнут наконечник",
res/values/strings_th.arb
+1
@@ -235,6 +235,7 @@
235 "edit_token": "แก้ไขโทเค็น",
236 "electrum_address_disclaimer": "เราสร้างที่อยู่ใหม่ทุกครั้งที่คุณใช้หนึ่งอย่าง แต่ที่อยู่เก่ายังสามารถใช้ได้ต่อไป",
237 "email_address": "ที่อยู่อีเมล",
238 + "enable": "เปิดใช้งาน",
239 "enable_mempool_api": "Mempool API สำหรับค่าธรรมเนียมและวันที่ที่ถูกต้อง",
240 "enable_replace_by_fee": "เปิดใช้งานการเปลี่ยนโดยค่าธรรมเนียม",
241 "enable_silent_payments_scanning": "เริ่มสแกนการชำระเงินแบบเงียบจนกว่าจะถึงปลาย",
res/values/strings_tl.arb
+1
@@ -235,6 +235,7 @@
235 "edit_token": "I-edit ang token",
236 "electrum_address_disclaimer": "Bumubuo kami ng mga bagong address sa tuwing gagamit ka ng isa, ngunit ang mga nakaraang address ay patuloy na gumagana",
237 "email_address": "Email Address",
238 + "enable": "Paganahin",
239 "enable_mempool_api": "Mempool API para sa tumpak na bayad at mga petsa",
240 "enable_replace_by_fee": "Paganahin ang Replace-By-Fee",
241 "enable_silent_payments_scanning": "Simulan ang pag -scan ng tahimik na pagbabayad, hanggang sa maabot ang tip",
res/values/strings_tr.arb
+1
@@ -235,6 +235,7 @@
235 "edit_token": "Belirteci düzenle",
236 "electrum_address_disclaimer": "Adresini her kullandığında yeni adres oluşturuyoruz, ancak önceki adresler de çalışmaya devam eder",
237 "email_address": "E-posta Adresi",
238 + "enable": "Olanak vermek",
239 "enable_mempool_api": "Doğru ücretler ve tarihler için Mempool API'si",
240 "enable_replace_by_fee": "Farklı Değiştir'i Etkinleştir",
241 "enable_silent_payments_scanning": "Bahşiş ulaşılıncaya kadar sessiz ödemeleri taramaya başlayın",
res/values/strings_uk.arb
+1
@@ -235,6 +235,7 @@
235 "edit_token": "Редагувати маркер",
236 "electrum_address_disclaimer": "Ми створюємо нові адреси щоразу, коли ви використовуєте їх, але попередні адреси продовжують працювати",
237 "email_address": "Адреса електронної пошти",
238 + "enable": "Ввімкнути",
239 "enable_mempool_api": "API Mempool для точних зборів та дат",
240 "enable_replace_by_fee": "Увімкнути заміну з комісією",
241 "enable_silent_payments_scanning": "Почніть сканувати мовчазні платежі, поки не буде досягнуто наконечника",
res/values/strings_ur.arb
+1
@@ -235,6 +235,7 @@
235 "edit_token": "ٹوکن میں ترمیم کریں۔",
236 "electrum_address_disclaimer": "جب بھی آپ ایک کا استعمال کرتے ہیں تو ہم نئے پتے تیار کرتے ہیں، لیکن پچھلے پتے کام کرتے رہتے ہیں۔",
237 "email_address": "ای میل اڈریس",
238 + "enable": "قابل بنائیں",
239 "enable_mempool_api": "درست فیسوں اور تاریخوں کے لئے میمپول API",
240 "enable_replace_by_fee": "فی فیس کو تبدیل کریں",
241 "enable_silent_payments_scanning": "خاموش ادائیگیوں کو اسکین کرنا شروع کریں ، جب تک کہ نوک نہ پہنچ جائے",
res/values/strings_vi.arb
+1
@@ -236,6 +236,7 @@
236 "edit_token": "Chỉnh sửa token",
237 "electrum_address_disclaimer": "Chúng tôi tạo địa chỉ mới mỗi khi bạn sử dụng, nhưng các địa chỉ cũ vẫn tiếp tục hoạt động",
238 "email_address": "Địa chỉ Email",
239 + "enable": "Cho phép",
240 "enable_mempool_api": "API Mempool cho các khoản phí và ngày chính xác",
241 "enable_replace_by_fee": "Bật Thay thế Bằng Phí",
242 "enable_silent_payments_scanning": "Bật quét thanh toán im lặng",
res/values/strings_yo.arb
+1
@@ -236,6 +236,7 @@
236 "edit_token": "Ṣatunkọ àmi",
237 "electrum_address_disclaimer": "A dá àwọn àdírẹ́sì títun ní gbogbo àwọn ìgbà t'ẹ́ lo ó kan ṣùgbọ́n ẹ lè tẹ̀síwájú lo àwọn àdírẹ́sì tẹ́lẹ̀tẹ́lẹ̀.",
238 "email_address": "Àdírẹ́sì ímeèlì",
239 + "enable": "Mu ṣiṣẹ",
240 "enable_mempool_api": "Mempool API fun awọn owo deede ati awọn ọjọ",
241 "enable_replace_by_fee": "Mu ki o rọpo",
242 "enable_silent_payments_scanning": "Bẹrẹ awọn sisanwo ipalọlọ, titi ti o fi de opin",
res/values/strings_zh.arb
+1
@@ -235,6 +235,7 @@
235 "edit_token": "编辑令牌",
236 "electrum_address_disclaimer": "每次您使用一个地址时,我们都会生成新地址,但之前的地址仍然有效",
237 "email_address": "电子邮件地址",
238 + "enable": "使能够",
239 "enable_mempool_api": "Mempool API获得准确的费用和日期",
240 "enable_replace_by_fee": "启用by-Fee替换",
241 "enable_silent_payments_scanning": "开始扫描无声付款,直到达到提示",
scripts/android/app_env.sh
+4 -4
@@ -15,15 +15,15 @@ TYPES=($MONERO_COM $CAKEWALLET $HAVEN)
15 APP_ANDROID_TYPE=$1
16
17 MONERO_COM_NAME="Monero.com"
18 -MONERO_COM_VERSION="1.16.5"
19 -MONERO_COM_BUILD_NUMBER=100
18 +MONERO_COM_VERSION="1.17.0"
19 +MONERO_COM_BUILD_NUMBER=102
20 MONERO_COM_BUNDLE_ID="com.monero.app"
21 MONERO_COM_PACKAGE="com.monero.app"
22 MONERO_COM_SCHEME="monero.com"
23
24 CAKEWALLET_NAME="Cake Wallet"
25 -CAKEWALLET_VERSION="4.19.5"
26 -CAKEWALLET_BUILD_NUMBER=227
25 +CAKEWALLET_VERSION="4.20.0"
26 +CAKEWALLET_BUILD_NUMBER=230
27 CAKEWALLET_BUNDLE_ID="com.cakewallet.cake_wallet"
28 CAKEWALLET_PACKAGE="com.cakewallet.cake_wallet"
29 CAKEWALLET_SCHEME="cakewallet"
scripts/android/build_mwebd.sh
+1 -1
@@ -13,7 +13,7 @@ fi
13 # build mwebd:
14 git clone https://github.com/ltcmweb/mwebd
15 cd mwebd
16 -git reset --hard f6ea8a9e3d348b01bb44f03a1cc4ad65b0abe935
16 +git reset --hard 555349415f76a42ec5c76152b64c4ab9aabc448f
17 gomobile bind -target=android -androidapi 21 .
18 mkdir -p ../../../cw_mweb/android/libs/
19 mv ./mwebd.aar $_
scripts/ios/app_config.sh
+1 -1
@@ -22,7 +22,7 @@ cp -rf ./ios/Runner/InfoBase.plist ./ios/Runner/Info.plist
22 /usr/libexec/PlistBuddy -c "Add :CFBundleURLTypes:1:CFBundleURLName string ${APP_IOS_TYPE}" ./ios/Runner/Info.plist
23 /usr/libexec/PlistBuddy -c "Add :CFBundleURLTypes:1:CFBundleURLSchemes array" ./ios/Runner/Info.plist
24 /usr/libexec/PlistBuddy -c "Add :CFBundleURLTypes:1:CFBundleURLSchemes: string ${APP_IOS_TYPE}" ./ios/Runner/Info.plist
25 -sed -i '' "s/\${PRODUCT_BUNDLE_IDENTIFIER}/${APP_IOS_BUNDLE_ID}/g" ./ios/Runner.xcodeproj/project.pbxproj
25 +sed -i '' "s/PRODUCT_BUNDLE_IDENTIFIER = .*;/PRODUCT_BUNDLE_IDENTIFIER = $APP_IOS_BUNDLE_ID;/g" ./ios/Runner.xcodeproj/project.pbxproj
26
27 CONFIG_ARGS=""
28
scripts/ios/app_env.sh
+4 -4
@@ -13,13 +13,13 @@ TYPES=($MONERO_COM $CAKEWALLET $HAVEN)
13 APP_IOS_TYPE=$1
14
15 MONERO_COM_NAME="Monero.com"
16 -MONERO_COM_VERSION="1.16.5"
17 -MONERO_COM_BUILD_NUMBER=98
16 +MONERO_COM_VERSION="1.17.0"
17 +MONERO_COM_BUILD_NUMBER=100
18 MONERO_COM_BUNDLE_ID="com.cakewallet.monero"
19
20 CAKEWALLET_NAME="Cake Wallet"
21 -CAKEWALLET_VERSION="4.19.5"
22 -CAKEWALLET_BUILD_NUMBER=266
21 +CAKEWALLET_VERSION="4.20.0"
22 +CAKEWALLET_BUILD_NUMBER=269
23 CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet"
24
25 HAVEN_NAME="Haven"
scripts/ios/build_mwebd.sh
+1 -1
@@ -12,7 +12,7 @@ fi
12 # build mwebd:
13 git clone https://github.com/ltcmweb/mwebd
14 cd mwebd
15 -git reset --hard f6ea8a9e3d348b01bb44f03a1cc4ad65b0abe935
15 +git reset --hard 555349415f76a42ec5c76152b64c4ab9aabc448f
16 gomobile bind -target=ios .
17 mv -fn ./Mwebd.xcframework ../../../ios/
18 # cleanup:
scripts/linux/app_env.sh
+2 -2
@@ -14,8 +14,8 @@ if [ -n "$1" ]; then
14 fi
15
16 CAKEWALLET_NAME="Cake Wallet"
17 -CAKEWALLET_VERSION="1.9.5"
18 -CAKEWALLET_BUILD_NUMBER=33
17 +CAKEWALLET_VERSION="1.10.0"
18 +CAKEWALLET_BUILD_NUMBER=35
19
20 if ! [[ " ${TYPES[*]} " =~ " ${APP_LINUX_TYPE} " ]]; then
21 echo "Wrong app type."
scripts/macos/app_config.sh
+1 -1
@@ -28,7 +28,7 @@ sed -i '' "s/\${BUNDLE_ID}/${APP_MACOS_BUNDLE_ID}/g" ./macos/Runner/DebugProfile
28 sed -i '' "s/\${BUNDLE_ID}/${APP_MACOS_BUNDLE_ID}/g" ./macos/Runner/Release.entitlements
29 sed -i '' "s/\${BUNDLE_ID}/${APP_MACOS_BUNDLE_ID}/g" ./macos/Runner/Runner.entitlements
30 sed -i '' "s/\${PRODUCT_NAME}/${APP_MACOS_NAME}/g" ./macos/Runner/Configs/AppInfo.xcconfig
31 -sed -i '' "s/\${PRODUCT_BUNDLE_IDENTIFIER}/${APP_MACOS_BUNDLE_ID}/g" ./macos/Runner/Configs/AppInfo.xcconfig
31 +sed -i '' "s/PRODUCT_BUNDLE_IDENTIFIER = .*;/PRODUCT_BUNDLE_IDENTIFIER = $APP_MACOS_BUNDLE_ID;/g" ./macos/Runner/Configs/AppInfo.xcconfig
32 CONFIG_ARGS=""
33
34 case $APP_MACOS_TYPE in
scripts/macos/app_env.sh
+4 -4
@@ -16,13 +16,13 @@ if [ -n "$1" ]; then
16 fi
17
18 MONERO_COM_NAME="Monero.com"
19 -MONERO_COM_VERSION="1.6.5"
20 -MONERO_COM_BUILD_NUMBER=31
19 +MONERO_COM_VERSION="1.7.0"
20 +MONERO_COM_BUILD_NUMBER=33
21 MONERO_COM_BUNDLE_ID="com.cakewallet.monero"
22
23 CAKEWALLET_NAME="Cake Wallet"
24 -CAKEWALLET_VERSION="1.12.5"
25 -CAKEWALLET_BUILD_NUMBER=88
24 +CAKEWALLET_VERSION="1.13.0"
25 +CAKEWALLET_BUILD_NUMBER=90
26 CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet"
27
28 if ! [[ " ${TYPES[*]} " =~ " ${APP_MACOS_TYPE} " ]]; then
scripts/windows/build_exe_installer.iss
+1 -1
@@ -1,5 +1,5 @@
1 #define MyAppName "Cake Wallet"
2 -#define MyAppVersion "0.0.6"
2 +#define MyAppVersion "0.1.0"
3 #define MyAppPublisher "Cake Labs LLC"
4 #define MyAppURL "https://cakewallet.com/"
5 #define MyAppExeName "CakeWallet.exe"
tool/configure.dart
+1
@@ -75,6 +75,7 @@ Future<void> main(List<String> args) async {
75 Future<void> generateBitcoin(bool hasImplementation) async {
76 final outputFile = File(bitcoinOutputPath);
77 const bitcoinCommonHeaders = """
78 +import 'dart:io' show Platform;
79 import 'dart:typed_data';
80 import 'package:bitcoin_base/bitcoin_base.dart';
81 import 'package:cake_wallet/view_model/hardware_wallet/ledger_view_model.dart';