From 684d892121aee61e19907e9ee2b080444377006b Mon Sep 17 00:00:00 2001 From: Matthew Fosse Date: Tue, 18 Mar 2025 13:44:06 -0700 Subject: [PATCH 1/3] add mweb block explorer --- .../transaction_details_view_model.dart | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/lib/view_model/transaction_details_view_model.dart b/lib/view_model/transaction_details_view_model.dart index 2dc6478f91..2a3bdf093f 100644 --- a/lib/view_model/transaction_details_view_model.dart +++ b/lib/view_model/transaction_details_view_model.dart @@ -57,6 +57,7 @@ abstract class TransactionDetailsViewModelBase with Store { if (!canReplaceByFee) _checkForRBF(tx); break; case WalletType.litecoin: + _addLitecoinListItems(tx, dateFormat); case WalletType.bitcoinCash: _addElectrumListItems(tx, dateFormat); break; @@ -332,6 +333,30 @@ abstract class TransactionDetailsViewModelBase with Store { items.addAll(_items); } + void _addLitecoinListItems(TransactionInfo tx, DateFormat dateFormat) { + _addElectrumListItems(tx, dateFormat); + + bool isMweb = bitcoin!.txIsMweb(tx); + + final _items = [ + if (isMweb) + BlockExplorerListItem( + title: S.current.view_in_block_explorer, + value: S.current.view_transaction_on + 'mwebexplorer.com', + onTap: () async { + try { + final uri = Uri.parse('https://www.mwebexplorer.com/blocks/block/${tx.height}'); + if (await canLaunchUrl(uri)) + await launchUrl(uri, mode: LaunchMode.externalApplication); + } catch (e) {} + }, + key: ValueKey('block_explorer_list_item_mweb_wallet_type_key'), + ), + ]; + + items.addAll(_items); + } + void _addHavenListItems(TransactionInfo tx, DateFormat dateFormat) { items.addAll([ StandartListItem( From c15cdddee8d8078e15125a6a157739caee66b3b0 Mon Sep 17 00:00:00 2001 From: Matthew Fosse Date: Tue, 18 Mar 2025 18:15:56 -0700 Subject: [PATCH 2/3] potential fix for #2 --- cw_bitcoin/lib/electrum_wallet.dart | 8 +++++ cw_bitcoin/lib/litecoin_wallet.dart | 33 ++++++++++++------- cw_bitcoin/lib/litecoin_wallet_addresses.dart | 2 +- .../lib/pending_bitcoin_transaction.dart | 6 ++-- 4 files changed, 34 insertions(+), 15 deletions(-) diff --git a/cw_bitcoin/lib/electrum_wallet.dart b/cw_bitcoin/lib/electrum_wallet.dart index fd778571f3..504560abb9 100644 --- a/cw_bitcoin/lib/electrum_wallet.dart +++ b/cw_bitcoin/lib/electrum_wallet.dart @@ -806,6 +806,14 @@ abstract class ElectrumWalletBase throw BitcoinTransactionNoDustException(); } + // if mweb isn't enabled, don't consider spending mweb coins: + if (this is LitecoinWallet) { + var mwebEnabled = (this as LitecoinWallet).mwebEnabled; + if (!mwebEnabled) { + coinTypeToSpendFrom = UnspentCoinType.nonMweb; + } + } + final utxoDetails = _createUTXOS( sendAll: false, credentialsAmount: credentialsAmount, diff --git a/cw_bitcoin/lib/litecoin_wallet.dart b/cw_bitcoin/lib/litecoin_wallet.dart index 5e71bfd6d5..781ed898e7 100644 --- a/cw_bitcoin/lib/litecoin_wallet.dart +++ b/cw_bitcoin/lib/litecoin_wallet.dart @@ -843,6 +843,8 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store { if (unspent.vout == 0) { unspent.isChange = true; } + + // printV("unspent: $unspent ${unspent.vout} ${utxo.value}"); mwebUnspentCoins.add(unspent); }); @@ -1056,13 +1058,20 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store { @override Future createTransaction(Object credentials) async { try { - var tx = await super.createTransaction(credentials) as PendingBitcoinTransaction; - tx.isMweb = mwebEnabled; + var creds; + if (!mwebEnabled) { + creds = (credentials as BitcoinTransactionCredentials); + creds.coinTypeToSpendFrom = UnspentCoinType.nonMweb; + } else { + creds = credentials; + } + var tx = await super.createTransaction(creds as Object) as PendingBitcoinTransaction; + tx.useMwebToSubmit = mwebEnabled; if (!mwebEnabled) { - tx.changeAddressOverride = - (await (walletAddresses as LitecoinWalletAddresses).getChangeAddress(coinTypeToSpendFrom: UnspentCoinType.nonMweb)) - .address; + tx.changeAddressOverride = (await (walletAddresses as LitecoinWalletAddresses) + .getChangeAddress(coinTypeToSpendFrom: UnspentCoinType.nonMweb)) + .address; return tx; } await waitForMwebAddresses(); @@ -1086,17 +1095,17 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store { final address = output.address.toLowerCase(); final extractedAddress = output.extractedAddress?.toLowerCase(); - if (address.contains("mweb")) { + if (address.startsWith("ltcmweb")) { hasMwebOutput = true; } - if (!address.contains("mweb")) { + if (!address.startsWith("ltcmweb")) { hasRegularOutput = true; } if (extractedAddress != null && extractedAddress.isNotEmpty) { - if (extractedAddress.contains("mweb")) { + if (extractedAddress.startsWith("ltcmweb")) { hasMwebOutput = true; } - if (!extractedAddress.contains("mweb")) { + if (!extractedAddress.startsWith("ltcmweb")) { hasRegularOutput = true; } } @@ -1115,10 +1124,12 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store { bool isRegular = !hasMwebInput && !hasMwebOutput; bool shouldNotUseMwebChange = isPegIn || isRegular || !hasMwebInput; tx.changeAddressOverride = (await (walletAddresses as LitecoinWalletAddresses) - .getChangeAddress(coinTypeToSpendFrom: shouldNotUseMwebChange ? UnspentCoinType.nonMweb : UnspentCoinType.any)) + .getChangeAddress( + coinTypeToSpendFrom: + shouldNotUseMwebChange ? UnspentCoinType.nonMweb : UnspentCoinType.any)) .address; if (isRegular) { - tx.isMweb = false; + tx.useMwebToSubmit = false; return tx; } diff --git a/cw_bitcoin/lib/litecoin_wallet_addresses.dart b/cw_bitcoin/lib/litecoin_wallet_addresses.dart index bbb987766e..dc444d15c5 100644 --- a/cw_bitcoin/lib/litecoin_wallet_addresses.dart +++ b/cw_bitcoin/lib/litecoin_wallet_addresses.dart @@ -175,7 +175,7 @@ abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses with if (!element.isSending || element.isFrozen) { return; } - if (element.address.contains("mweb")) { + if (element.address.startsWith("ltcmweb")) { comesFromMweb = true; } }); diff --git a/cw_bitcoin/lib/pending_bitcoin_transaction.dart b/cw_bitcoin/lib/pending_bitcoin_transaction.dart index 411c7de16a..241ce9c46b 100644 --- a/cw_bitcoin/lib/pending_bitcoin_transaction.dart +++ b/cw_bitcoin/lib/pending_bitcoin_transaction.dart @@ -23,7 +23,7 @@ class PendingBitcoinTransaction with PendingTransaction { required this.hasChange, this.isSendAll = false, this.hasTaprootInputs = false, - this.isMweb = false, + this.useMwebToSubmit = false, this.utxos = const [], }) : _listeners = []; @@ -38,7 +38,7 @@ class PendingBitcoinTransaction with PendingTransaction { final bool hasChange; final bool hasTaprootInputs; List utxos; - bool isMweb; + bool useMwebToSubmit; String? changeAddressOverride; String? idOverride; String? hexOverride; @@ -129,7 +129,7 @@ class PendingBitcoinTransaction with PendingTransaction { @override Future commit() async { - if (isMweb) { + if (useMwebToSubmit) { await _ltcCommit(); } else { await _commit(); From 062edc1035b1841948e43d827b2470dc9c4cb84e Mon Sep 17 00:00:00 2001 From: Matthew Fosse Date: Tue, 29 Apr 2025 19:19:20 -0700 Subject: [PATCH 3/3] fix spending when mweb is disabled --- cw_bitcoin/lib/litecoin_wallet.dart | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/cw_bitcoin/lib/litecoin_wallet.dart b/cw_bitcoin/lib/litecoin_wallet.dart index bf14b3f556..804019aa7f 100644 --- a/cw_bitcoin/lib/litecoin_wallet.dart +++ b/cw_bitcoin/lib/litecoin_wallet.dart @@ -1062,8 +1062,14 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store { try { var creds; if (!mwebEnabled) { - creds = (credentials as BitcoinTransactionCredentials); - creds.coinTypeToSpendFrom = UnspentCoinType.nonMweb; + BitcoinTransactionCredentials btcCreds = (credentials as BitcoinTransactionCredentials); + // sets unspent coin type to nonMweb: + creds = BitcoinTransactionCredentials( + btcCreds.outputs, + priority: btcCreds.priority, + feeRate: btcCreds.feeRate, + coinTypeToSpendFrom: UnspentCoinType.nonMweb, + ); } else { creds = credentials; }