diff --git a/assets/text/Monerocom_Release_Notes.txt b/assets/text/Monerocom_Release_Notes.txt index 90fcd2a75..e6aab2dda 100644 --- a/assets/text/Monerocom_Release_Notes.txt +++ b/assets/text/Monerocom_Release_Notes.txt @@ -1,4 +1,2 @@ -Monero enhancements -In-App live status page for the app services -Add Exolix exchange provider -Bug fixes and enhancements \ No newline at end of file +Exchange flow enhancements and fixes +Generic enhancements and bug fixes \ No newline at end of file diff --git a/assets/text/Release_Notes.txt b/assets/text/Release_Notes.txt index 83e18c18e..b32cd539d 100644 --- a/assets/text/Release_Notes.txt +++ b/assets/text/Release_Notes.txt @@ -1 +1,6 @@ -Bug fixes and enhancements \ No newline at end of file +Exchange flow enhancements and fixes +Add MoonPay to Buy options +Add THORChain to Exchange providers +Improve Bitcoin fee calculations +Fixes and enhancements for Solana +Generic enhancements and bug fixes \ No newline at end of file diff --git a/cw_bitcoin/lib/electrum_wallet.dart b/cw_bitcoin/lib/electrum_wallet.dart index ffd8b5d52..9c144ac74 100644 --- a/cw_bitcoin/lib/electrum_wallet.dart +++ b/cw_bitcoin/lib/electrum_wallet.dart @@ -544,6 +544,8 @@ abstract class ElectrumWalletBase ); } + bool hasTaprootInputs = false; + final transaction = txb.buildTransaction((txDigest, utxo, publicKey, sighash) { final key = estimatedTx.privateKeys .firstWhereOrNull((element) => element.getPublic().toHex() == publicKey); @@ -553,21 +555,25 @@ abstract class ElectrumWalletBase } if (utxo.utxo.isP2tr()) { + hasTaprootInputs = true; return key.signTapRoot(txDigest, sighash: sighash); } else { return key.signInput(txDigest, sigHash: sighash); } }); - return PendingBitcoinTransaction(transaction, type, - electrumClient: electrumClient, - amount: estimatedTx.amount, - fee: estimatedTx.fee, - feeRate: feeRateInt.toString(), - network: network, - hasChange: estimatedTx.hasChange, - isSendAll: estimatedTx.isSendAll) - ..addListener((transaction) async { + return PendingBitcoinTransaction( + transaction, + type, + electrumClient: electrumClient, + amount: estimatedTx.amount, + fee: estimatedTx.fee, + feeRate: feeRateInt.toString(), + network: network, + hasChange: estimatedTx.hasChange, + isSendAll: estimatedTx.isSendAll, + hasTaprootInputs: hasTaprootInputs, + )..addListener((transaction) async { transactionHistory.addOne(transaction); await updateBalance(); }); diff --git a/cw_bitcoin/lib/pending_bitcoin_transaction.dart b/cw_bitcoin/lib/pending_bitcoin_transaction.dart index ada39a8f7..eb4274e78 100644 --- a/cw_bitcoin/lib/pending_bitcoin_transaction.dart +++ b/cw_bitcoin/lib/pending_bitcoin_transaction.dart @@ -8,15 +8,18 @@ import 'package:cw_core/transaction_direction.dart'; import 'package:cw_core/wallet_type.dart'; class PendingBitcoinTransaction with PendingTransaction { - PendingBitcoinTransaction(this._tx, this.type, - {required this.electrumClient, - required this.amount, - required this.fee, - required this.feeRate, - this.network, - required this.hasChange, - required this.isSendAll}) - : _listeners = []; + PendingBitcoinTransaction( + this._tx, + this.type, { + required this.electrumClient, + required this.amount, + required this.fee, + required this.feeRate, + this.network, + required this.hasChange, + required this.isSendAll, + this.hasTaprootInputs = false, + }) : _listeners = []; final WalletType type; final BtcTransaction _tx; @@ -27,6 +30,7 @@ class PendingBitcoinTransaction with PendingTransaction { final BasedUtxoNetwork? network; final bool hasChange; final bool isSendAll; + final bool hasTaprootInputs; @override String get id => _tx.txId(); diff --git a/cw_polygon/lib/polygon_client.dart b/cw_polygon/lib/polygon_client.dart index 42fdd2e25..d55ee2269 100644 --- a/cw_polygon/lib/polygon_client.dart +++ b/cw_polygon/lib/polygon_client.dart @@ -13,6 +13,7 @@ class PolygonClient extends EVMChainClient { required EthereumAddress to, required EtherAmount amount, EtherAmount? maxPriorityFeePerGas, + Uint8List? data, }) { return Transaction( from: from, diff --git a/lib/bitcoin/cw_bitcoin.dart b/lib/bitcoin/cw_bitcoin.dart index c9649a2e3..882facf39 100644 --- a/lib/bitcoin/cw_bitcoin.dart +++ b/lib/bitcoin/cw_bitcoin.dart @@ -239,4 +239,9 @@ class CWBitcoin extends Bitcoin { return SegwitAddresType.p2wpkh; } } + + @override + bool hasTaprootInput(PendingTransaction pendingTransaction) { + return (pendingTransaction as PendingBitcoinTransaction).hasTaprootInputs; + } } diff --git a/lib/view_model/send/send_view_model.dart b/lib/view_model/send/send_view_model.dart index a631cde02..df1c75def 100644 --- a/lib/view_model/send/send_view_model.dart +++ b/lib/view_model/send/send_view_model.dart @@ -308,13 +308,19 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor pendingTransaction = await wallet.createTransaction(_credentials()); if (provider is ThorChainExchangeProvider) { final outputCount = pendingTransaction?.outputCount ?? 0; - if (outputCount > 10) throw Exception("ThorChain does not support more than 10 outputs"); + if (outputCount > 10) { + throw Exception("ThorChain does not support more than 10 outputs"); + } + if (_hasTaprootInput(pendingTransaction)) { + throw Exception("ThorChain does not support Taproot addresses"); + } } state = ExecutedSuccessfullyState(); return pendingTransaction; } catch (e) { state = FailureState(translateErrorMessage(e, wallet.type, wallet.currency)); } + return null; } @action @@ -512,4 +518,12 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor return errorMessage; } + + bool _hasTaprootInput(PendingTransaction? pendingTransaction) { + if (walletType == WalletType.bitcoin && pendingTransaction != null) { + return bitcoin!.hasTaprootInput(pendingTransaction); + } + + return false; + } } diff --git a/scripts/android/app_env.sh b/scripts/android/app_env.sh index ed2b67de5..8387c1d1f 100644 --- a/scripts/android/app_env.sh +++ b/scripts/android/app_env.sh @@ -15,15 +15,15 @@ TYPES=($MONERO_COM $CAKEWALLET $HAVEN) APP_ANDROID_TYPE=$1 MONERO_COM_NAME="Monero.com" -MONERO_COM_VERSION="1.12.0" -MONERO_COM_BUILD_NUMBER=79 +MONERO_COM_VERSION="1.12.1" +MONERO_COM_BUILD_NUMBER=80 MONERO_COM_BUNDLE_ID="com.monero.app" MONERO_COM_PACKAGE="com.monero.app" MONERO_COM_SCHEME="monero.com" CAKEWALLET_NAME="Cake Wallet" -CAKEWALLET_VERSION="4.15.2" -CAKEWALLET_BUILD_NUMBER=200 +CAKEWALLET_VERSION="4.15.3" +CAKEWALLET_BUILD_NUMBER=202 CAKEWALLET_BUNDLE_ID="com.cakewallet.cake_wallet" CAKEWALLET_PACKAGE="com.cakewallet.cake_wallet" CAKEWALLET_SCHEME="cakewallet" diff --git a/scripts/ios/app_env.sh b/scripts/ios/app_env.sh index 53514b39b..7e4f214ab 100644 --- a/scripts/ios/app_env.sh +++ b/scripts/ios/app_env.sh @@ -13,13 +13,13 @@ TYPES=($MONERO_COM $CAKEWALLET $HAVEN) APP_IOS_TYPE=$1 MONERO_COM_NAME="Monero.com" -MONERO_COM_VERSION="1.12.0" +MONERO_COM_VERSION="1.12.1" MONERO_COM_BUILD_NUMBER=77 MONERO_COM_BUNDLE_ID="com.cakewallet.monero" CAKEWALLET_NAME="Cake Wallet" -CAKEWALLET_VERSION="4.15.2" -CAKEWALLET_BUILD_NUMBER=219 +CAKEWALLET_VERSION="4.15.3" +CAKEWALLET_BUILD_NUMBER=221 CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet" HAVEN_NAME="Haven" diff --git a/scripts/macos/app_env.sh b/scripts/macos/app_env.sh index 1654a022a..1242945a6 100755 --- a/scripts/macos/app_env.sh +++ b/scripts/macos/app_env.sh @@ -16,13 +16,13 @@ if [ -n "$1" ]; then fi MONERO_COM_NAME="Monero.com" -MONERO_COM_VERSION="1.2.0" -MONERO_COM_BUILD_NUMBER=10 +MONERO_COM_VERSION="1.2.1" +MONERO_COM_BUILD_NUMBER=11 MONERO_COM_BUNDLE_ID="com.cakewallet.monero" CAKEWALLET_NAME="Cake Wallet" -CAKEWALLET_VERSION="1.8.2" -CAKEWALLET_BUILD_NUMBER=59 +CAKEWALLET_VERSION="1.8.3" +CAKEWALLET_BUILD_NUMBER=61 CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet" if ! [[ " ${TYPES[*]} " =~ " ${APP_MACOS_TYPE} " ]]; then diff --git a/tool/configure.dart b/tool/configure.dart index 30123c45e..b3aa44feb 100644 --- a/tool/configure.dart +++ b/tool/configure.dart @@ -61,6 +61,7 @@ Future main(List args) async { Future generateBitcoin(bool hasImplementation) async { final outputFile = File(bitcoinOutputPath); const bitcoinCommonHeaders = """ +import 'package:cw_core/pending_transaction.dart'; import 'package:cw_core/receive_page_option.dart'; import 'package:cw_core/unspent_transaction_output.dart'; import 'package:cw_core/wallet_credentials.dart'; @@ -74,6 +75,7 @@ import 'package:cake_wallet/view_model/send/output.dart'; import 'package:hive/hive.dart'; import 'package:bitcoin_base/bitcoin_base.dart';"""; const bitcoinCWHeaders = """ +import 'package:cw_bitcoin/pending_bitcoin_transaction.dart'; import 'package:cw_bitcoin/bitcoin_receive_page_option.dart'; import 'package:cw_bitcoin/electrum_wallet.dart'; import 'package:cw_bitcoin/bitcoin_unspent.dart'; @@ -148,6 +150,7 @@ abstract class Bitcoin { ReceivePageOption getSelectedAddressType(Object wallet); List getBitcoinReceivePageOptions(); BitcoinAddressType getBitcoinAddressType(ReceivePageOption option); + bool hasTaprootInput(PendingTransaction pendingTransaction); } """;