diff --git a/cw_bitcoin/lib/electrum_wallet_addresses.dart b/cw_bitcoin/lib/electrum_wallet_addresses.dart index c21bc6c90..4d1179243 100644 --- a/cw_bitcoin/lib/electrum_wallet_addresses.dart +++ b/cw_bitcoin/lib/electrum_wallet_addresses.dart @@ -386,12 +386,31 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store { @action void updateAddress(String address, String label) { - final addressRecord = - _addresses.firstWhere((addressRecord) => addressRecord.address == address); - addressRecord.setNewName(label); - final index = _addresses.indexOf(addressRecord); - _addresses.remove(addressRecord); - _addresses.insert(index, addressRecord); + BaseBitcoinAddressRecord? foundAddress; + _addresses.forEach((addressRecord) { + if (addressRecord.address == address) { + foundAddress = addressRecord; + } + }); + silentAddresses.forEach((addressRecord) { + if (addressRecord.address == address) { + foundAddress = addressRecord; + } + }); + + if (foundAddress != null) { + foundAddress!.setNewName(label); + + if (foundAddress is BitcoinAddressRecord) { + final index = _addresses.indexOf(foundAddress); + _addresses.remove(foundAddress); + _addresses.insert(index, foundAddress as BitcoinAddressRecord); + } else { + final index = silentAddresses.indexOf(foundAddress as BitcoinSilentPaymentAddressRecord); + silentAddresses.remove(foundAddress); + silentAddresses.insert(index, foundAddress as BitcoinSilentPaymentAddressRecord); + } + } } @action @@ -537,4 +556,13 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store { bool _isAddressByType(BitcoinAddressRecord addr, BitcoinAddressType type) => addr.type == type; bool _isUnusedReceiveAddressByType(BitcoinAddressRecord addr, BitcoinAddressType type) => !addr.isHidden && !addr.isUsed && addr.type == type; + + @action + void deleteSilentPaymentAddress(String address) { + final addressRecord = silentAddresses.firstWhere((addressRecord) => + addressRecord.type == SilentPaymentsAddresType.p2sp && addressRecord.address == address); + + silentAddresses.remove(addressRecord); + updateAddressesByMatch(); + } } diff --git a/lib/bitcoin/cw_bitcoin.dart b/lib/bitcoin/cw_bitcoin.dart index db1ebcf4a..51db7c827 100644 --- a/lib/bitcoin/cw_bitcoin.dart +++ b/lib/bitcoin/cw_bitcoin.dart @@ -365,4 +365,9 @@ class CWBitcoin extends Bitcoin { return node?.uri.host == '198.58.111.154' && node?.uri.port == 50002; } + + void deleteSilentPaymentAddress(Object wallet, String address) { + final bitcoinWallet = wallet as ElectrumWallet; + bitcoinWallet.walletAddresses.deleteSilentPaymentAddress(address); + } } diff --git a/lib/src/screens/receive/receive_page.dart b/lib/src/screens/receive/receive_page.dart index 4d0c6185f..e6009d0c2 100644 --- a/lib/src/screens/receive/receive_page.dart +++ b/lib/src/screens/receive/receive_page.dart @@ -206,18 +206,23 @@ class ReceivePage extends BasePage { .extension()! .tilesTextColor; - return AddressCell.fromItem(item, - isCurrent: isCurrent, - hasBalance: addressListViewModel.isElectrumWallet, - backgroundColor: backgroundColor, - textColor: textColor, - onTap: item.isOneTimeReceiveAddress == true - ? null - : (_) => addressListViewModel.setAddress(item), - onEdit: item.isOneTimeReceiveAddress == true - ? null - : () => Navigator.of(context) - .pushNamed(Routes.newSubaddress, arguments: item)); + return AddressCell.fromItem( + item, + isCurrent: isCurrent, + hasBalance: addressListViewModel.isElectrumWallet, + backgroundColor: backgroundColor, + textColor: textColor, + onTap: item.isOneTimeReceiveAddress == true + ? null + : (_) => addressListViewModel.setAddress(item), + onEdit: item.isOneTimeReceiveAddress == true || item.isPrimary + ? null + : () => Navigator.of(context) + .pushNamed(Routes.newSubaddress, arguments: item), + onDelete: !addressListViewModel.isSilentPayments || item.isPrimary + ? null + : () => addressListViewModel.deleteAddress(item), + ); }); } diff --git a/lib/src/screens/receive/widgets/address_cell.dart b/lib/src/screens/receive/widgets/address_cell.dart index 69e011900..a7a19fb54 100644 --- a/lib/src/screens/receive/widgets/address_cell.dart +++ b/lib/src/screens/receive/widgets/address_cell.dart @@ -14,18 +14,22 @@ class AddressCell extends StatelessWidget { required this.textColor, this.onTap, this.onEdit, + this.onDelete, this.txCount, this.balance, this.isChange = false, this.hasBalance = false}); - factory AddressCell.fromItem(WalletAddressListItem item, - {required bool isCurrent, - required Color backgroundColor, - required Color textColor, - Function(String)? onTap, - bool hasBalance = false, - Function()? onEdit}) => + factory AddressCell.fromItem( + WalletAddressListItem item, { + required bool isCurrent, + required Color backgroundColor, + required Color textColor, + Function(String)? onTap, + bool hasBalance = false, + Function()? onEdit, + Function()? onDelete, + }) => AddressCell( address: item.address, name: item.name ?? '', @@ -35,6 +39,7 @@ class AddressCell extends StatelessWidget { textColor: textColor, onTap: onTap, onEdit: onEdit, + onDelete: onDelete, txCount: item.txCount, balance: item.balance, isChange: item.isChange, @@ -48,6 +53,7 @@ class AddressCell extends StatelessWidget { final Color textColor; final Function(String)? onTap; final Function()? onEdit; + final Function()? onDelete; final int? txCount; final String? balance; final bool isChange; @@ -63,7 +69,8 @@ class AddressCell extends StatelessWidget { } else { return formatIfCashAddr.substring(0, addressPreviewLength) + '...' + - formatIfCashAddr.substring(formatIfCashAddr.length - addressPreviewLength, formatIfCashAddr.length); + formatIfCashAddr.substring( + formatIfCashAddr.length - addressPreviewLength, formatIfCashAddr.length); } } @@ -175,7 +182,7 @@ class AddressCell extends StatelessWidget { ActionPane _actionPane(BuildContext context) => ActionPane( motion: const ScrollMotion(), - extentRatio: 0.3, + extentRatio: onDelete != null ? 0.4 : 0.3, children: [ SlidableAction( onPressed: (_) => onEdit?.call(), @@ -184,6 +191,14 @@ class AddressCell extends StatelessWidget { icon: Icons.edit, label: S.of(context).edit, ), + if (onDelete != null) + SlidableAction( + onPressed: (_) => onDelete!.call(), + backgroundColor: Colors.red, + foregroundColor: Colors.white, + icon: Icons.delete, + label: S.of(context).delete, + ), ], ); } diff --git a/lib/view_model/wallet_address_list/wallet_address_list_view_model.dart b/lib/view_model/wallet_address_list/wallet_address_list_view_model.dart index 9289701fc..1eae60c99 100644 --- a/lib/view_model/wallet_address_list/wallet_address_list_view_model.dart +++ b/lib/view_model/wallet_address_list/wallet_address_list_view_model.dart @@ -320,7 +320,8 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo if (isElectrumWallet) { if (bitcoin!.hasSelectedSilentPayments(wallet)) { final addressItems = bitcoin!.getSilentPaymentAddresses(wallet).map((address) { - final isPrimary = address.index == 0; + // Silent Payments index 0 is change per BIP + final isPrimary = address.index == 1; return WalletAddressListItem( id: address.index, @@ -497,4 +498,11 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo amount = ''; } } + + @action + void deleteAddress(ListItem item) { + if (wallet.type == WalletType.bitcoin && item is WalletAddressListItem) { + bitcoin!.deleteSilentPaymentAddress(wallet, item.address); + } + } }