From 125fdf8b624ce931e39905045d69b6312558a983 Mon Sep 17 00:00:00 2001 From: Serhii Date: Mon, 9 Sep 2024 21:08:21 +0300 Subject: [PATCH 1/9] quick fix for the reconnection issue (#1671) * Update electrum.dart * Update electrum.dart * Duration seconds: 5 [skip ci] --- cw_bitcoin/lib/electrum.dart | 10 +++++++--- cw_bitcoin/lib/electrum_wallet.dart | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/cw_bitcoin/lib/electrum.dart b/cw_bitcoin/lib/electrum.dart index bc630a4e1..8dfb8e01f 100644 --- a/cw_bitcoin/lib/electrum.dart +++ b/cw_bitcoin/lib/electrum.dart @@ -113,9 +113,13 @@ class ElectrumClient { }, onDone: () { unterminatedString = ''; - if (host == socket?.address.host) { - socket = null; - _setConnectionStatus(ConnectionStatus.disconnected); + try { + if (host == socket?.address.host) { + socket?.destroy(); + _setConnectionStatus(ConnectionStatus.disconnected); + } + } catch(e) { + print(e.toString()); } }, cancelOnError: true, diff --git a/cw_bitcoin/lib/electrum_wallet.dart b/cw_bitcoin/lib/electrum_wallet.dart index 73ae7c38f..b9bb0deb4 100644 --- a/cw_bitcoin/lib/electrum_wallet.dart +++ b/cw_bitcoin/lib/electrum_wallet.dart @@ -2058,7 +2058,7 @@ abstract class ElectrumWalletBase _isTryingToConnect = true; - Timer(Duration(seconds: 10), () { + Timer(Duration(seconds: 5), () { if (this.syncStatus is NotConnectedSyncStatus || this.syncStatus is LostConnectionSyncStatus) { this.electrumClient.connectToUri( node!.uri, From 56c505da5927794d60b8c4813fbd99f669cbc11b Mon Sep 17 00:00:00 2001 From: fossephate Date: Mon, 9 Sep 2024 12:46:53 -0700 Subject: [PATCH 2/9] review updates pt.1 --- .github/workflows/pr_test_build_android.yml | 11 +-- .github/workflows/pr_test_build_linux.yml | 11 +-- cw_bitcoin/lib/bitcoin_mnemonic.dart | 3 +- cw_bitcoin/lib/electrum_wallet.dart | 7 +- cw_bitcoin/lib/electrum_wallet_addresses.dart | 87 ++++++++++++------- cw_bitcoin/lib/litecoin_wallet_service.dart | 8 +- cw_core/lib/get_height_by_date.dart | 20 +++++ lib/bitcoin/cw_bitcoin.dart | 3 + lib/src/widgets/blockchain_height_widget.dart | 3 +- scripts/android/build_all.sh | 3 +- scripts/android/build_mwebd.sh | 17 ++-- scripts/ios/build_all.sh | 2 +- scripts/ios/build_mwebd.sh | 13 +-- tool/configure.dart | 1 + 14 files changed, 115 insertions(+), 74 deletions(-) diff --git a/.github/workflows/pr_test_build_android.yml b/.github/workflows/pr_test_build_android.yml index 2253cc551..6daeb84ee 100644 --- a/.github/workflows/pr_test_build_android.yml +++ b/.github/workflows/pr_test_build_android.yml @@ -110,15 +110,8 @@ jobs: export PATH=$PATH:/usr/local/go/bin export PATH=$PATH:~/go/bin # build mwebd: - cd /opt/android/cake_wallet - git clone https://github.com/ltcmweb/mwebd - cd /opt/android/cake_wallet/mwebd - git reset --hard f6ea8a9e3d348b01bb44f03a1cc4ad65b0abe935 - gomobile bind -target=android -androidapi 21 . - mkdir -p /opt/android/cake_wallet/cw_mweb/android/libs/ - mv ./mwebd.aar $_ - cd .. - rm -rf mwebd + cd /opt/android/cake_wallet/scripts/android/ + ./build_mwebd.sh - name: Generate KeyStore run: | diff --git a/.github/workflows/pr_test_build_linux.yml b/.github/workflows/pr_test_build_linux.yml index 50acdce94..116dc3c95 100644 --- a/.github/workflows/pr_test_build_linux.yml +++ b/.github/workflows/pr_test_build_linux.yml @@ -105,15 +105,8 @@ jobs: export PATH=$PATH:/usr/local/go/bin export PATH=$PATH:~/go/bin # build mwebd: - cd /opt/android/cake_wallet - git clone https://github.com/ltcmweb/mwebd - cd /opt/android/cake_wallet/mwebd - git reset --hard f6ea8a9e3d348b01bb44f03a1cc4ad65b0abe935 - gomobile bind -target=android -androidapi 21 . - mkdir -p /opt/android/cake_wallet/cw_mweb/android/libs/ - mv ./mwebd.aar $_ - cd .. - rm -rf mwebd + cd /opt/android/cake_wallet/scripts/android/ + ./build_mwebd.sh - name: Generate localization run: | diff --git a/cw_bitcoin/lib/bitcoin_mnemonic.dart b/cw_bitcoin/lib/bitcoin_mnemonic.dart index 0749627e9..21ff3891e 100644 --- a/cw_bitcoin/lib/bitcoin_mnemonic.dart +++ b/cw_bitcoin/lib/bitcoin_mnemonic.dart @@ -8,6 +8,7 @@ import 'package:cw_core/sec_random_native.dart'; import 'package:cw_core/utils/text_normalizer.dart'; const segwit = '100'; +const mweb = 'eb'; final wordlist = englishWordlist; double logBase(num x, num base) => log(x) / log(base); @@ -125,7 +126,7 @@ Future mnemonicToSeedBytes(String mnemonic, return Uint8List.fromList(bytes); } -bool matchesAnyPrefix(String mnemonic) => prefixMatches(mnemonic, [segwit]).any((el) => el); +bool matchesAnyPrefix(String mnemonic) => prefixMatches(mnemonic, [segwit, mweb]).any((el) => el); bool validateMnemonic(String mnemonic, {String prefix = segwit}) { try { diff --git a/cw_bitcoin/lib/electrum_wallet.dart b/cw_bitcoin/lib/electrum_wallet.dart index ea99c6cd8..222a16e91 100644 --- a/cw_bitcoin/lib/electrum_wallet.dart +++ b/cw_bitcoin/lib/electrum_wallet.dart @@ -1689,12 +1689,15 @@ abstract class ElectrumWalletBase final Map historiesWithDetails = {}; if (type == WalletType.bitcoin) { - await Future.wait(ADDRESS_TYPES + await Future.wait(BITCOIN_ADDRESS_TYPES .map((type) => fetchTransactionsForAddressType(historiesWithDetails, type))); } else if (type == WalletType.bitcoinCash) { + await Future.wait(BITCOIN_CASH_ADDRESS_TYPES + .map((type) => fetchTransactionsForAddressType(historiesWithDetails, type))); await fetchTransactionsForAddressType(historiesWithDetails, P2pkhAddressType.p2pkh); } else if (type == WalletType.litecoin) { - await fetchTransactionsForAddressType(historiesWithDetails, SegwitAddresType.p2wpkh); + await Future.wait(LITECOIN_ADDRESS_TYPES + .map((type) => fetchTransactionsForAddressType(historiesWithDetails, type))); } transactionHistory.transactions.values.forEach((tx) async { diff --git a/cw_bitcoin/lib/electrum_wallet_addresses.dart b/cw_bitcoin/lib/electrum_wallet_addresses.dart index e442a03e8..f320ef110 100644 --- a/cw_bitcoin/lib/electrum_wallet_addresses.dart +++ b/cw_bitcoin/lib/electrum_wallet_addresses.dart @@ -11,15 +11,23 @@ part 'electrum_wallet_addresses.g.dart'; class ElectrumWalletAddresses = ElectrumWalletAddressesBase with _$ElectrumWalletAddresses; -const List ADDRESS_TYPES = [ +const List BITCOIN_ADDRESS_TYPES = [ SegwitAddresType.p2wpkh, P2pkhAddressType.p2pkh, SegwitAddresType.p2tr, SegwitAddresType.p2wsh, - SegwitAddresType.mweb, P2shAddressType.p2wpkhInP2sh, ]; +const List LITECOIN_ADDRESS_TYPES = [ + SegwitAddresType.p2wpkh, + SegwitAddresType.mweb, +]; + +const List BITCOIN_CASH_ADDRESS_TYPES = [ + P2pkhAddressType.p2pkh, +]; + abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store { ElectrumWalletAddressesBase( WalletInfo walletInfo, { @@ -327,13 +335,6 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store { }) => ''; - Future getAddressAsync({ - required int index, - required Bip32Slip10Secp256k1 hd, - BitcoinAddressType? addressType, - }) async => - getAddress(index: index, hd: hd, addressType: addressType); - void addBitcoinAddressTypes() { final lastP2wpkh = _addresses .where((addressRecord) => @@ -393,6 +394,37 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store { }); } + void addLitecoinAddressTypes() { + final lastP2wpkh = _addresses + .where((addressRecord) => + _isUnusedReceiveAddressByType(addressRecord, SegwitAddresType.p2wpkh)) + .toList() + .last; + if (lastP2wpkh.address != address) { + addressesMap[lastP2wpkh.address] = 'P2WPKH'; + } else { + addressesMap[address] = 'Active - P2WPKH'; + } + + final lastMweb = _addresses.firstWhere( + (addressRecord) => _isUnusedReceiveAddressByType(addressRecord, SegwitAddresType.mweb)); + if (lastMweb.address != address) { + addressesMap[lastMweb.address] = 'MWEB'; + } else { + addressesMap[address] = 'Active - MWEB'; + } + } + + void addBitcoinCashAddressTypes() { + final lastP2pkh = _addresses.firstWhere( + (addressRecord) => _isUnusedReceiveAddressByType(addressRecord, P2pkhAddressType.p2pkh)); + if (lastP2pkh.address != address) { + addressesMap[lastP2pkh.address] = 'P2PKH'; + } else { + addressesMap[address] = 'Active - P2PKH'; + } + } + @override Future updateAddressesInBox() async { try { @@ -404,29 +436,18 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store { allAddressesMap[addressRecord.address] = addressRecord.name; }); - if (walletInfo.type == WalletType.bitcoin) { - addBitcoinAddressTypes(); - } - - if (walletInfo.type == WalletType.litecoin) { - final lastP2wpkh = _addresses - .where((addressRecord) => - _isUnusedReceiveAddressByType(addressRecord, SegwitAddresType.p2wpkh)) - .toList() - .last; - if (lastP2wpkh.address != address) { - addressesMap[lastP2wpkh.address] = 'P2WPKH'; - } else { - addressesMap[address] = 'Active - P2WPKH'; - } - - final lastMweb = _addresses.firstWhere( - (addressRecord) => _isUnusedReceiveAddressByType(addressRecord, SegwitAddresType.mweb)); - if (lastMweb.address != address) { - addressesMap[lastMweb.address] = 'MWEB'; - } else { - addressesMap[address] = 'Active - MWEB'; - } + switch (walletInfo.type) { + case WalletType.bitcoin: + addBitcoinAddressTypes(); + break; + case WalletType.litecoin: + addLitecoinAddressTypes(); + break; + case WalletType.bitcoinCash: + addBitcoinCashAddressTypes(); + break; + default: + break; } await saveAddressesInBox(); @@ -548,7 +569,7 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store { for (var i = startIndex; i < count + startIndex; i++) { final address = BitcoinAddressRecord( - await getAddressAsync(index: i, hd: _getHd(isHidden), addressType: type ?? addressPageType), + getAddress(index: i, hd: _getHd(isHidden), addressType: type ?? addressPageType), index: i, isHidden: isHidden, type: type ?? addressPageType, diff --git a/cw_bitcoin/lib/litecoin_wallet_service.dart b/cw_bitcoin/lib/litecoin_wallet_service.dart index da3602024..25438007a 100644 --- a/cw_bitcoin/lib/litecoin_wallet_service.dart +++ b/cw_bitcoin/lib/litecoin_wallet_service.dart @@ -1,10 +1,10 @@ import 'dart:io'; import 'package:cw_bitcoin/bitcoin_mnemonics_bip39.dart'; +import 'package:cw_bitcoin/mnemonic_is_incorrect_exception.dart'; import 'package:cw_core/encryption_file_utils.dart'; import 'package:cw_core/unspent_coins_info.dart'; import 'package:hive/hive.dart'; import 'package:cw_bitcoin/bitcoin_mnemonic.dart'; -import 'package:cw_bitcoin/mnemonic_is_incorrect_exception.dart'; import 'package:cw_bitcoin/bitcoin_wallet_creation_credentials.dart'; import 'package:cw_bitcoin/litecoin_wallet.dart'; import 'package:cw_core/wallet_service.dart'; @@ -150,9 +150,9 @@ class LitecoinWalletService extends WalletService< @override Future restoreFromSeed(BitcoinRestoreWalletFromSeedCredentials credentials, {bool? isTestnet}) async { - // if (!validateMnemonic(credentials.mnemonic) && !bip39.validateMnemonic(credentials.mnemonic)) { - // throw LitecoinMnemonicIsIncorrectException(); - // } + if (!validateMnemonic(credentials.mnemonic) && !bip39.validateMnemonic(credentials.mnemonic)) { + throw LitecoinMnemonicIsIncorrectException(); + } final wallet = await LitecoinWalletBase.create( password: credentials.password!, diff --git a/cw_core/lib/get_height_by_date.dart b/cw_core/lib/get_height_by_date.dart index 204f03d62..52136fdcd 100644 --- a/cw_core/lib/get_height_by_date.dart +++ b/cw_core/lib/get_height_by_date.dart @@ -267,6 +267,11 @@ const bitcoinDates = { "2023-01": 769810, }; + +const Map litecoinDates = { + // TODO: add litecoin dates +}; + int getBitcoinHeightByDate({required DateTime date}) { String dateKey = '${date.year}-${date.month.toString().padLeft(2, '0')}'; final closestKey = bitcoinDates.keys @@ -300,6 +305,21 @@ DateTime getDateByBitcoinHeight(int height) { return estimatedDate; } +int getLitecoinHeightByDate({required DateTime date}) { + String dateKey = '${date.year}-${date.month.toString().padLeft(2, '0')}'; + final closestKey = litecoinDates.keys + .firstWhere((key) => formatMapKey(key).isBefore(date), orElse: () => litecoinDates.keys.last); + final beginningBlock = litecoinDates[dateKey] ?? litecoinDates[closestKey]!; + + final startOfMonth = DateTime(date.year, date.month); + final daysDifference = date.difference(startOfMonth).inDays; + + // approximately 6 blocks per hour, 24 hours per day + int estimatedBlocksSinceStartOfMonth = (daysDifference * 24 * 6); + + return beginningBlock + estimatedBlocksSinceStartOfMonth; +} + // TODO: enhance all of this global const lists const wowDates = { "2023-12": 583048, diff --git a/lib/bitcoin/cw_bitcoin.dart b/lib/bitcoin/cw_bitcoin.dart index e6d189356..0c3e27930 100644 --- a/lib/bitcoin/cw_bitcoin.dart +++ b/lib/bitcoin/cw_bitcoin.dart @@ -529,6 +529,9 @@ class CWBitcoin extends Bitcoin { @override int getHeightByDate({required DateTime date}) => getBitcoinHeightByDate(date: date); + @override + int getLitecoinHeightByDate({required DateTime date}) => getLitecoinHeightByDate(date: date); + @override Future rescan(Object wallet, {required int height, bool? doSingleScan}) async { final bitcoinWallet = wallet as ElectrumWallet; diff --git a/lib/src/widgets/blockchain_height_widget.dart b/lib/src/widgets/blockchain_height_widget.dart index b9ab45e55..f3bcbc25c 100644 --- a/lib/src/widgets/blockchain_height_widget.dart +++ b/lib/src/widgets/blockchain_height_widget.dart @@ -168,8 +168,7 @@ class BlockchainHeightState extends State { if (date != null) { int height; if (widget.isMwebScan) { - throw UnimplementedError(); - // height = bitcoin!.getMwebHeightByDate(date: date); + height = bitcoin!.getLitecoinHeightByDate(date: date); } else if (widget.isSilentPaymentsScan) { height = bitcoin!.getHeightByDate(date: date); } else { diff --git a/scripts/android/build_all.sh b/scripts/android/build_all.sh index ec70f02a6..ad4ec984b 100755 --- a/scripts/android/build_all.sh +++ b/scripts/android/build_all.sh @@ -10,6 +10,7 @@ DIR=$(dirname "$0") case $APP_ANDROID_TYPE in "monero.com") $DIR/build_monero_all.sh ;; "cakewallet") $DIR/build_monero_all.sh - $DIR/build_haven_all.sh ;; + $DIR/build_haven_all.sh + $DIR/build_mwebd.sh ;; "haven") $DIR/build_haven_all.sh ;; esac diff --git a/scripts/android/build_mwebd.sh b/scripts/android/build_mwebd.sh index bbe436ff6..1e4f51be9 100755 --- a/scripts/android/build_mwebd.sh +++ b/scripts/android/build_mwebd.sh @@ -1,10 +1,13 @@ -# install go > 1.23: -wget https://go.dev/dl/go1.23.1.linux-amd64.tar.gz -sudo rm -rf /usr/local/go && sudo tar -C /usr/local -xzf go1.23.1.linux-amd64.tar.gz -export PATH=$PATH:/usr/local/go/bin -export PATH=$PATH:~/go/bin -go install golang.org/x/mobile/cmd/gomobile@latest -gomobile init +if [[ "$1" == "--install" ]]; then + # install go > 1.23: + wget https://go.dev/dl/go1.23.1.linux-amd64.tar.gz + sudo rm -rf /usr/local/go && sudo tar -C /usr/local -xzf go1.23.1.linux-amd64.tar.gz + export PATH=$PATH:/usr/local/go/bin + export PATH=$PATH:~/go/bin + go install golang.org/x/mobile/cmd/gomobile@latest + gomobile init +fi + # build mwebd: git clone https://github.com/ltcmweb/mwebd cd mwebd diff --git a/scripts/ios/build_all.sh b/scripts/ios/build_all.sh index 565679e2d..ba5c55a1f 100755 --- a/scripts/ios/build_all.sh +++ b/scripts/ios/build_all.sh @@ -9,6 +9,6 @@ DIR=$(dirname "$0") case $APP_IOS_TYPE in "monero.com") $DIR/build_monero_all.sh ;; - "cakewallet") $DIR/build_monero_all.sh && $DIR/build_haven.sh ;; + "cakewallet") $DIR/build_monero_all.sh && $DIR/build_haven.sh && $DIR/build_mwebd.sh ;; "haven") $DIR/build_haven_all.sh ;; esac diff --git a/scripts/ios/build_mwebd.sh b/scripts/ios/build_mwebd.sh index ee1658800..b0d67115e 100755 --- a/scripts/ios/build_mwebd.sh +++ b/scripts/ios/build_mwebd.sh @@ -1,9 +1,12 @@ #!/bin/bash -# install go > 1.23: -brew install go -export PATH=$PATH:~/go/bin -go install golang.org/x/mobile/cmd/gomobile@latest -gomobile init +if [[ "$1" == "--install" ]]; then + # install go > 1.23: + brew install go + export PATH=$PATH:~/go/bin + go install golang.org/x/mobile/cmd/gomobile@latest + gomobile init +fi + # build mwebd: git clone https://github.com/ltcmweb/mwebd cd mwebd diff --git a/tool/configure.dart b/tool/configure.dart index 326a794ba..8ac6c7694 100644 --- a/tool/configure.dart +++ b/tool/configure.dart @@ -214,6 +214,7 @@ abstract class Bitcoin { {int? outputsCount, int? size}); int feeAmountWithFeeRate(Object wallet, int feeRate, int inputsCount, int outputsCount, {int? size}); int getHeightByDate({required DateTime date}); + int getLitecoinHeightByDate({required DateTime date}); Future rescan(Object wallet, {required int height, bool? doSingleScan}); Future getNodeIsElectrsSPEnabled(Object wallet); void deleteSilentPaymentAddress(Object wallet, String address); From 0f5ee476f18381e407c642589f52eb95b26bc1cc Mon Sep 17 00:00:00 2001 From: Matthew Fosse Date: Mon, 9 Sep 2024 12:49:22 -0700 Subject: [PATCH 3/9] Update cw_bitcoin/lib/litecoin_wallet.dart Co-authored-by: Omar Hatem --- cw_bitcoin/lib/litecoin_wallet.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cw_bitcoin/lib/litecoin_wallet.dart b/cw_bitcoin/lib/litecoin_wallet.dart index b69ba59dd..e3f68888e 100644 --- a/cw_bitcoin/lib/litecoin_wallet.dart +++ b/cw_bitcoin/lib/litecoin_wallet.dart @@ -317,11 +317,12 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store { final oldBoxName = "${walletInfo.name.replaceAll(" ", "_")}_${MwebUtxo.boxName}"; final newBoxName = "${newWalletName.replaceAll(" ", "_")}_${MwebUtxo.boxName}"; - final oldBox = await Hive.openBox(oldBoxName); + final oldBox = await CakeHive.openBox(oldBoxName); mwebUtxosBox = await CakeHive.openBox(newBoxName); for (final key in oldBox.keys) { await mwebUtxosBox.put(key, oldBox.get(key)!); } + oldBox.deleteFromDisk(); await super.renameWalletFiles(newWalletName); } From 577aec0f042b8a981b7dcc59d0759ef7065e492e Mon Sep 17 00:00:00 2001 From: OmarHatem Date: Mon, 9 Sep 2024 23:24:09 +0300 Subject: [PATCH 4/9] remove non-litecoin address types regex [skip ci] --- lib/core/address_validator.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/core/address_validator.dart b/lib/core/address_validator.dart index 03d1668ee..5453ef7e6 100644 --- a/lib/core/address_validator.dart +++ b/lib/core/address_validator.dart @@ -27,9 +27,9 @@ class AddressValidator extends TextValidator { return '^[0-9a-zA-Z]{59}\$|^[0-9a-zA-Z]{92}\$|^[0-9a-zA-Z]{104}\$' '|^[0-9a-zA-Z]{105}\$|^addr1[0-9a-zA-Z]{98}\$'; case CryptoCurrency.btc: - return '^${P2pkhAddress.regex.pattern}\$|^${P2shAddress.regex.pattern}\$|^${P2wpkhAddress.regex.pattern}\$|${P2trAddress.regex.pattern}\$|^${P2wshAddress.regex.pattern}\$|^${SilentPaymentAddress.regex.pattern}\$'; + return '^${P2pkhAddress.regex.pattern}\$|^${P2shAddress.regex.pattern}\$|^${P2wpkhAddress.regex.pattern}\$|^${P2trAddress.regex.pattern}\$|^${P2wshAddress.regex.pattern}\$|^${SilentPaymentAddress.regex.pattern}\$'; case CryptoCurrency.ltc: - return '^${P2pkhAddress.regex.pattern}\$|^${P2shAddress.regex.pattern}\$|^${P2wpkhAddress.regex.pattern}\$|${P2trAddress.regex.pattern}\$|^${P2wshAddress.regex.pattern}\$|^${MwebAddress.regex.pattern}\$'; + return '^${P2wpkhAddress.regex.pattern}\$|^${MwebAddress.regex.pattern}\$'; case CryptoCurrency.nano: return '[0-9a-zA-Z_]'; case CryptoCurrency.banano: From 728a0bf4b2880be745b544b0fc839b8bc2a2f82e Mon Sep 17 00:00:00 2001 From: fossephate Date: Mon, 9 Sep 2024 13:24:50 -0700 Subject: [PATCH 5/9] more minor fixes --- cw_bitcoin/lib/litecoin_wallet.dart | 11 +++----- cw_bitcoin/lib/litecoin_wallet_addresses.dart | 25 +------------------ lib/bitcoin/cw_bitcoin.dart | 2 +- tool/configure.dart | 2 +- 4 files changed, 7 insertions(+), 33 deletions(-) diff --git a/cw_bitcoin/lib/litecoin_wallet.dart b/cw_bitcoin/lib/litecoin_wallet.dart index e3f68888e..e2010c520 100644 --- a/cw_bitcoin/lib/litecoin_wallet.dart +++ b/cw_bitcoin/lib/litecoin_wallet.dart @@ -776,6 +776,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store { script: outputs[0].toOutput.scriptPubKey, value: utxos.sumOfUtxosValue()) ]; } + // https://github.com/ltcmweb/mwebd?tab=readme-ov-file#fee-estimation final preOutputSum = outputs.fold(BigInt.zero, (acc, output) => acc + output.toOutput.amount); final fee = utxos.sumOfUtxosValue() - preOutputSum; @@ -891,19 +892,15 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store { _utxoStream?.cancel(); } - void setMwebEnabled(bool enabled) { + Future setMwebEnabled(bool enabled) async { if (mwebEnabled == enabled) { return; } mwebEnabled = enabled; (walletAddresses as LitecoinWalletAddresses).mwebEnabled = enabled; - if (enabled) { - // generate inital mweb addresses: - (walletAddresses as LitecoinWalletAddresses).topUpMweb(0); - } - stopSync(); - startSync(); + await stopSync(); + await startSync(); } Future getStub() async { diff --git a/cw_bitcoin/lib/litecoin_wallet_addresses.dart b/cw_bitcoin/lib/litecoin_wallet_addresses.dart index dcdf4ca1b..9f63f6662 100644 --- a/cw_bitcoin/lib/litecoin_wallet_addresses.dart +++ b/cw_bitcoin/lib/litecoin_wallet_addresses.dart @@ -2,20 +2,14 @@ import 'dart:typed_data'; import 'package:bech32/bech32.dart'; import 'package:bitcoin_base/bitcoin_base.dart'; -import 'package:blockchain_utils/bech32/bech32_base.dart'; import 'package:blockchain_utils/blockchain_utils.dart'; import 'package:cw_bitcoin/electrum_wallet.dart'; import 'package:cw_bitcoin/utils.dart'; import 'package:cw_bitcoin/electrum_wallet_addresses.dart'; import 'package:cw_core/wallet_info.dart'; import 'package:cw_mweb/cw_mweb.dart'; -import 'package:cw_mweb/mwebd.pb.dart'; import 'package:mobx/mobx.dart'; -// import 'dart:typed_data'; -// import 'package:bech32/bech32.dart'; -// import 'package:r_crypto/r_crypto.dart'; - part 'litecoin_wallet_addresses.g.dart'; String encodeMwebAddress(List scriptPubKey) { @@ -36,12 +30,7 @@ abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses with super.initialRegularAddressIndex, super.initialChangeAddressIndex, }) : super(walletInfo) { - if (mwebEnabled) { - // give the server a few seconds to start up before trying to get the addresses: - Future.delayed(const Duration(seconds: 5), () async { - await topUpMweb(0); - }); - } + topUpMweb(0); } final Bip32Slip10Secp256k1 mwebHd; @@ -79,18 +68,6 @@ abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses with return generateP2WPKHAddress(hd: hd, index: index, network: network); } - @override - Future getAddressAsync({ - required int index, - required Bip32Slip10Secp256k1 hd, - BitcoinAddressType? addressType, - }) async { - if (addressType == SegwitAddresType.mweb) { - await topUpMweb(index); - } - return getAddress(index: index, hd: hd, addressType: addressType); - } - @action @override Future getChangeAddress({List? outputs, UtxoDetails? utxoDetails}) async { diff --git a/lib/bitcoin/cw_bitcoin.dart b/lib/bitcoin/cw_bitcoin.dart index 0c3e27930..074398263 100644 --- a/lib/bitcoin/cw_bitcoin.dart +++ b/lib/bitcoin/cw_bitcoin.dart @@ -557,7 +557,7 @@ class CWBitcoin extends Bitcoin { } @override - void setMwebEnabled(Object wallet, bool enabled) { + Future setMwebEnabled(Object wallet, bool enabled) async { final litecoinWallet = wallet as LitecoinWallet; litecoinWallet.setMwebEnabled(enabled); } diff --git a/tool/configure.dart b/tool/configure.dart index 8ac6c7694..4605c99fc 100644 --- a/tool/configure.dart +++ b/tool/configure.dart @@ -224,7 +224,7 @@ abstract class Bitcoin { void setLedger(WalletBase wallet, Ledger ledger, LedgerDevice device); Future> getHardwareWalletAccounts(LedgerViewModel ledgerVM, {int index = 0, int limit = 5}); - void setMwebEnabled(Object wallet, bool enabled); + Future setMwebEnabled(Object wallet, bool enabled); bool getMwebEnabled(Object wallet); } """; From 18a9bdea87da2a773cec8511ce66521e6af70b15 Mon Sep 17 00:00:00 2001 From: OmarHatem Date: Mon, 9 Sep 2024 23:55:16 +0300 Subject: [PATCH 6/9] remove duplicate [skip ci] --- cw_bitcoin/lib/electrum_wallet.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/cw_bitcoin/lib/electrum_wallet.dart b/cw_bitcoin/lib/electrum_wallet.dart index 2db6eec1c..b04ee382f 100644 --- a/cw_bitcoin/lib/electrum_wallet.dart +++ b/cw_bitcoin/lib/electrum_wallet.dart @@ -1694,7 +1694,6 @@ abstract class ElectrumWalletBase } else if (type == WalletType.bitcoinCash) { await Future.wait(BITCOIN_CASH_ADDRESS_TYPES .map((type) => fetchTransactionsForAddressType(historiesWithDetails, type))); - await fetchTransactionsForAddressType(historiesWithDetails, P2pkhAddressType.p2pkh); } else if (type == WalletType.litecoin) { await Future.wait(LITECOIN_ADDRESS_TYPES .map((type) => fetchTransactionsForAddressType(historiesWithDetails, type))); From dc77dee8493d5a9a51f4ec3a9e06cf49b0dba929 Mon Sep 17 00:00:00 2001 From: Matthew Fosse Date: Mon, 9 Sep 2024 14:03:09 -0700 Subject: [PATCH 7/9] Update lib/store/settings_store.dart Co-authored-by: Omar Hatem --- lib/store/settings_store.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/store/settings_store.dart b/lib/store/settings_store.dart index 1b1536fdd..474fd6524 100644 --- a/lib/store/settings_store.dart +++ b/lib/store/settings_store.dart @@ -950,7 +950,7 @@ abstract class SettingsStoreBase with Store { sharedPreferences.getBool(PreferencesKey.silentPaymentsAlwaysScan) ?? false; final mwebAlwaysScan = sharedPreferences.getBool(PreferencesKey.mwebAlwaysScan) ?? false; final mwebCardDisplay = sharedPreferences.getBool(PreferencesKey.mwebCardDisplay) ?? true; - final mwebEnabled = sharedPreferences.getBool(PreferencesKey.hasEnabledMwebBefore) ?? false; + final mwebEnabled = sharedPreferences.getBool(PreferencesKey.mwebEnabled) ?? false; final hasEnabledMwebBefore = sharedPreferences.getBool(PreferencesKey.hasEnabledMwebBefore) ?? false; From fd578dd530d6162f267e878621b13f8f6cdf087c Mon Sep 17 00:00:00 2001 From: Matthew Fosse Date: Mon, 9 Sep 2024 14:04:49 -0700 Subject: [PATCH 8/9] script updates, swap params on createLitecoinWalletService --- .github/workflows/pr_test_build_android.yml | 3 +-- .github/workflows/pr_test_build_linux.yml | 2 +- lib/di.dart | 2 +- scripts/android/build_mwebd.sh | 4 +++- scripts/ios/build_mwebd.sh | 4 +++- 5 files changed, 9 insertions(+), 6 deletions(-) diff --git a/.github/workflows/pr_test_build_android.yml b/.github/workflows/pr_test_build_android.yml index 6daeb84ee..3cc67e53a 100644 --- a/.github/workflows/pr_test_build_android.yml +++ b/.github/workflows/pr_test_build_android.yml @@ -109,9 +109,8 @@ jobs: # paths are reset after each step, so we need to set them again: export PATH=$PATH:/usr/local/go/bin export PATH=$PATH:~/go/bin - # build mwebd: cd /opt/android/cake_wallet/scripts/android/ - ./build_mwebd.sh + ./build_mwebd.sh --dont-install - name: Generate KeyStore run: | diff --git a/.github/workflows/pr_test_build_linux.yml b/.github/workflows/pr_test_build_linux.yml index 116dc3c95..f00584345 100644 --- a/.github/workflows/pr_test_build_linux.yml +++ b/.github/workflows/pr_test_build_linux.yml @@ -106,7 +106,7 @@ jobs: export PATH=$PATH:~/go/bin # build mwebd: cd /opt/android/cake_wallet/scripts/android/ - ./build_mwebd.sh + ./build_mwebd.sh --dont-install - name: Generate localization run: | diff --git a/lib/di.dart b/lib/di.dart index 9c3c5bcb2..30727f33c 100644 --- a/lib/di.dart +++ b/lib/di.dart @@ -1000,8 +1000,8 @@ Future setup({ return bitcoin!.createLitecoinWalletService( _walletInfoSource, _unspentCoinsInfoSource, - getIt.get().mwebAlwaysScan, SettingsStoreBase.walletPasswordDirectInput, + getIt.get().mwebAlwaysScan, ); case WalletType.ethereum: return ethereum!.createEthereumWalletService( diff --git a/scripts/android/build_mwebd.sh b/scripts/android/build_mwebd.sh index 1e4f51be9..90dbc4c20 100755 --- a/scripts/android/build_mwebd.sh +++ b/scripts/android/build_mwebd.sh @@ -1,4 +1,6 @@ -if [[ "$1" == "--install" ]]; then +if [[ "$1" == "--dont-install" ]]; then + echo "Skipping Go installation as per --dont-install flag" +else # install go > 1.23: wget https://go.dev/dl/go1.23.1.linux-amd64.tar.gz sudo rm -rf /usr/local/go && sudo tar -C /usr/local -xzf go1.23.1.linux-amd64.tar.gz diff --git a/scripts/ios/build_mwebd.sh b/scripts/ios/build_mwebd.sh index b0d67115e..f0fa64605 100755 --- a/scripts/ios/build_mwebd.sh +++ b/scripts/ios/build_mwebd.sh @@ -1,5 +1,7 @@ #!/bin/bash -if [[ "$1" == "--install" ]]; then +if [[ "$1" == "--dont-install" ]]; then + echo "Skipping Go installation as per --dont-install flag" +else # install go > 1.23: brew install go export PATH=$PATH:~/go/bin From 3963233c0e84f896a8af33a298b9e18067eea4fd Mon Sep 17 00:00:00 2001 From: Matthew Fosse Date: Mon, 9 Sep 2024 15:39:19 -0700 Subject: [PATCH 9/9] topup fix --- cw_bitcoin/lib/litecoin_wallet_addresses.dart | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cw_bitcoin/lib/litecoin_wallet_addresses.dart b/cw_bitcoin/lib/litecoin_wallet_addresses.dart index 9f63f6662..26a18df00 100644 --- a/cw_bitcoin/lib/litecoin_wallet_addresses.dart +++ b/cw_bitcoin/lib/litecoin_wallet_addresses.dart @@ -62,8 +62,9 @@ abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses with BitcoinAddressType? addressType, }) { if (addressType == SegwitAddresType.mweb) { - topUpMweb(index); - return hd == sideHd ? mwebAddrs[0] : mwebAddrs[index + 1]; + topUpMweb(index).then((value) { + return hd == sideHd ? mwebAddrs[0] : mwebAddrs[index + 1]; + }); } return generateP2WPKHAddress(hd: hd, index: index, network: network); }