mirror of
https://github.com/LBRYFoundation/LBRY-Vault.git
synced 2025-08-31 17:31:36 +00:00
ledger: support sending to OP_RETURN outputs
closes #5849 based on:ca9b432ff0
7bb27eff84
This commit is contained in:
parent
02baae10d7
commit
6b8c447eb9
2 changed files with 26 additions and 6 deletions
|
@ -188,13 +188,23 @@ def is_any_tx_output_on_change_branch(tx: PartialTransaction) -> bool:
|
|||
|
||||
|
||||
def trezor_validate_op_return_output_and_get_data(output: TxOutput) -> bytes:
|
||||
validate_op_return_output(output)
|
||||
script = output.scriptpubkey
|
||||
if not (script[0] == opcodes.OP_RETURN and
|
||||
script[1] == len(script) - 2 and script[1] <= 75):
|
||||
raise UserFacingException(_("Only OP_RETURN scripts, with one constant push, are supported."))
|
||||
return script[2:]
|
||||
|
||||
|
||||
def validate_op_return_output(output: TxOutput, *, max_size: int = None) -> None:
|
||||
script = output.scriptpubkey
|
||||
if script[0] != opcodes.OP_RETURN:
|
||||
raise UserFacingException(_("Only OP_RETURN scripts are supported."))
|
||||
if max_size is not None and len(script) > max_size:
|
||||
raise UserFacingException(_("OP_RETURN payload too large." + "\n"
|
||||
+ f"(scriptpubkey size {len(script)} > {max_size})"))
|
||||
if output.value != 0:
|
||||
raise UserFacingException(_("Amount for OP_RETURN output must be zero."))
|
||||
return script[2:]
|
||||
|
||||
|
||||
def get_xpubs_and_der_suffixes_from_txinout(tx: PartialTransaction,
|
||||
|
|
|
@ -2,6 +2,7 @@ from struct import pack, unpack
|
|||
import hashlib
|
||||
import sys
|
||||
import traceback
|
||||
from typing import Optional
|
||||
|
||||
from electrum import ecc
|
||||
from electrum import bip32
|
||||
|
@ -17,7 +18,7 @@ from electrum.base_wizard import ScriptTypeNotSupported
|
|||
from electrum.logging import get_logger
|
||||
|
||||
from ..hw_wallet import HW_PluginBase, HardwareClientBase
|
||||
from ..hw_wallet.plugin import is_any_tx_output_on_change_branch
|
||||
from ..hw_wallet.plugin import is_any_tx_output_on_change_branch, validate_op_return_output
|
||||
|
||||
|
||||
_logger = get_logger(__name__)
|
||||
|
@ -61,9 +62,10 @@ def test_pin_unlocked(func):
|
|||
|
||||
|
||||
class Ledger_Client(HardwareClientBase):
|
||||
def __init__(self, hidDevice):
|
||||
def __init__(self, hidDevice, *, is_hw1: bool = False):
|
||||
self.dongleObject = btchip(hidDevice)
|
||||
self.preflightDone = False
|
||||
self._is_hw1 = is_hw1
|
||||
|
||||
def is_pairable(self):
|
||||
return True
|
||||
|
@ -80,6 +82,9 @@ class Ledger_Client(HardwareClientBase):
|
|||
def label(self):
|
||||
return ""
|
||||
|
||||
def is_hw1(self) -> bool:
|
||||
return self._is_hw1
|
||||
|
||||
def has_usable_connection_with_device(self):
|
||||
try:
|
||||
self.dongleObject.getFirmwareVersion()
|
||||
|
@ -233,7 +238,7 @@ class Ledger_KeyStore(Hardware_KeyStore):
|
|||
def get_client(self):
|
||||
return self.plugin.get_client(self).dongleObject
|
||||
|
||||
def get_client_electrum(self):
|
||||
def get_client_electrum(self) -> Optional[Ledger_Client]:
|
||||
return self.plugin.get_client(self)
|
||||
|
||||
def give_error(self, message, clear_client = False):
|
||||
|
@ -382,7 +387,11 @@ class Ledger_KeyStore(Hardware_KeyStore):
|
|||
has_change = False
|
||||
any_output_on_change_branch = is_any_tx_output_on_change_branch(tx)
|
||||
for txout in tx.outputs():
|
||||
assert txout.address
|
||||
if not txout.address:
|
||||
if self.get_client_electrum().is_hw1():
|
||||
self.give_error(_("Only address outputs are supported by {}").format(self.device))
|
||||
# note: max_size based on https://github.com/LedgerHQ/ledger-app-btc/commit/3a78dee9c0484821df58975803e40d58fbfc2c38#diff-c61ccd96a6d8b54d48f54a3bc4dfa7e2R26
|
||||
validate_op_return_output(txout, max_size=190)
|
||||
if txout.is_mine and len(tx.outputs()) > 1 \
|
||||
and not has_change:
|
||||
# prioritise hiding outputs on the 'change' branch from user
|
||||
|
@ -570,7 +579,8 @@ class LedgerPlugin(HW_PluginBase):
|
|||
|
||||
client = self.get_btchip_device(device)
|
||||
if client is not None:
|
||||
client = Ledger_Client(client)
|
||||
is_hw1 = device.product_key[0] == 0x2581
|
||||
client = Ledger_Client(client, is_hw1=is_hw1)
|
||||
return client
|
||||
|
||||
def setup_device(self, device_info, wizard, purpose):
|
||||
|
|
Loading…
Add table
Reference in a new issue