diff --git a/electrum/commands.py b/electrum/commands.py index cbeaf61c9..7b2a45d64 100644 --- a/electrum/commands.py +++ b/electrum/commands.py @@ -423,15 +423,27 @@ class Commands: return {'address':address, 'redeemScript':redeem_script} @command('w') - async def freeze(self, address, wallet: Abstract_Wallet = None): + async def freeze(self, address: str, wallet: Abstract_Wallet = None): """Freeze address. Freeze the funds at one of your wallet\'s addresses""" return wallet.set_frozen_state_of_addresses([address], True) @command('w') - async def unfreeze(self, address, wallet: Abstract_Wallet = None): + async def unfreeze(self, address: str, wallet: Abstract_Wallet = None): """Unfreeze address. Unfreeze the funds at one of your wallet\'s address""" return wallet.set_frozen_state_of_addresses([address], False) + @command('w') + async def freeze_utxo(self, coin: str, wallet: Abstract_Wallet = None): + """Freeze a UTXO so that the wallet will not spend it.""" + wallet.set_frozen_state_of_coins([coin], True) + return True + + @command('w') + async def unfreeze_utxo(self, coin: str, wallet: Abstract_Wallet = None): + """Unfreeze a UTXO so that the wallet might spend it.""" + wallet.set_frozen_state_of_coins([coin], False) + return True + @command('wp') async def getprivatekeys(self, address, password=None, wallet: Abstract_Wallet = None): """Get private keys of addresses. You may pass a single wallet address, or a list of wallet addresses.""" diff --git a/electrum/gui/qt/main_window.py b/electrum/gui/qt/main_window.py index f0532f49c..3e36fe582 100644 --- a/electrum/gui/qt/main_window.py +++ b/electrum/gui/qt/main_window.py @@ -1953,7 +1953,8 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger): self.utxo_list.update() def set_frozen_state_of_coins(self, utxos: Sequence[PartialTxInput], freeze: bool): - self.wallet.set_frozen_state_of_coins(utxos, freeze) + utxos_str = {utxo.prevout.to_str() for utxo in utxos} + self.wallet.set_frozen_state_of_coins(utxos_str, freeze) self.utxo_list.update() def create_list_tab(self, l, toolbar=None): diff --git a/electrum/transaction.py b/electrum/transaction.py index ccb6305d0..d399cefdc 100644 --- a/electrum/transaction.py +++ b/electrum/transaction.py @@ -176,6 +176,7 @@ class TxOutpoint(NamedTuple): @classmethod def from_str(cls, s: str) -> 'TxOutpoint': hash_str, idx_str = s.split(':') + assert len(hash_str) == 64, f"{hash_str} should be a sha256 hash" return TxOutpoint(txid=bfh(hash_str), out_idx=int(idx_str)) diff --git a/electrum/wallet.py b/electrum/wallet.py index f853000b0..687775394 100644 --- a/electrum/wallet.py +++ b/electrum/wallet.py @@ -1337,9 +1337,10 @@ class Abstract_Wallet(AddressSynchronizer, ABC): return True return False - def set_frozen_state_of_coins(self, utxos: Sequence[PartialTxInput], freeze: bool) -> None: + def set_frozen_state_of_coins(self, utxos: Sequence[str], freeze: bool) -> None: """Set frozen state of the utxos to FREEZE, True or False""" - utxos = {utxo.prevout.to_str() for utxo in utxos} + # basic sanity check that input is not garbage: (see if raises) + [TxOutpoint.from_str(utxo) for utxo in utxos] with self._freeze_lock: if freeze: self._frozen_coins |= set(utxos)