diff --git a/.github/workflows/pr_test_build_android.yml b/.github/workflows/pr_test_build_android.yml index 2253cc551..3cc67e53a 100644 --- a/.github/workflows/pr_test_build_android.yml +++ b/.github/workflows/pr_test_build_android.yml @@ -109,16 +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 - 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 --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 50acdce94..f00584345 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 --dont-install - 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.dart b/cw_bitcoin/lib/electrum.dart index ec4a7d45c..b3aa19bd7 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 ea99c6cd8..b04ee382f 100644 --- a/cw_bitcoin/lib/electrum_wallet.dart +++ b/cw_bitcoin/lib/electrum_wallet.dart @@ -1689,12 +1689,14 @@ 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 fetchTransactionsForAddressType(historiesWithDetails, P2pkhAddressType.p2pkh); + await Future.wait(BITCOIN_CASH_ADDRESS_TYPES + .map((type) => fetchTransactionsForAddressType(historiesWithDetails, type))); } 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 { @@ -2064,9 +2066,8 @@ abstract class ElectrumWalletBase _isTryingToConnect = true; - Timer(Duration(seconds: 10), () { - if (this.syncStatus is NotConnectedSyncStatus || - this.syncStatus is LostConnectionSyncStatus) { + Timer(Duration(seconds: 5), () { + if (this.syncStatus is NotConnectedSyncStatus || this.syncStatus is LostConnectionSyncStatus) { this.electrumClient.connectToUri( node!.uri, useSSL: node!.useSSL ?? false, 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.dart b/cw_bitcoin/lib/litecoin_wallet.dart index 38ccfd3bd..c4f3b862e 100644 --- a/cw_bitcoin/lib/litecoin_wallet.dart +++ b/cw_bitcoin/lib/litecoin_wallet.dart @@ -319,11 +319,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); } @@ -777,6 +778,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; @@ -892,18 +894,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); - } - 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..26a18df00 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; @@ -73,24 +62,13 @@ 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); } - @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/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 524b00f93..6ea77d959 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; @@ -554,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/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: 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/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/lib/store/settings_store.dart b/lib/store/settings_store.dart index 78c8dd03d..1598664ee 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; 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..90dbc4c20 100755 --- a/scripts/android/build_mwebd.sh +++ b/scripts/android/build_mwebd.sh @@ -1,10 +1,15 @@ -# 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" == "--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 + 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..f0fa64605 100755 --- a/scripts/ios/build_mwebd.sh +++ b/scripts/ios/build_mwebd.sh @@ -1,9 +1,14 @@ #!/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" == "--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 + 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 ab89dd5a2..1fcbc4974 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); @@ -224,7 +225,7 @@ abstract class Bitcoin { Future> getHardwareWalletAccounts(LedgerViewModel ledgerVM, {int index = 0, int limit = 5}); dynamic getStatusRequest(Object wallet); - void setMwebEnabled(Object wallet, bool enabled); + Future setMwebEnabled(Object wallet, bool enabled); bool getMwebEnabled(Object wallet); } """;