1
0

register distinction between address and script for SPK type payment identifiers and allow zero amount for

script destinations.

This is mainly to support OP_RETURN outputs, which typically have a zero amount output value,
but as we don't special case OP_RETURN, this is currently done for all non-address scripts

Also, it's probably good to add a warning popup for OP_RETURN outputs with a non-zero output value, but this
would also need special casing for OP_RETURN.

Saving of script output payment identifiers is disabled for now, as reading the script from the stored invoice
back into human-readable form is currently not implemented, and currently only lightning invoices or address output
is supported.
This commit is contained in:
Sander van Grieken
2023-09-04 20:00:40 +02:00
parent 0d96bc1dbd
commit 307cf25fd4
2 changed files with 42 additions and 25 deletions

View File

@@ -120,6 +120,7 @@ class PaymentIdentifier(Logger):
self.bolt11 = None # type: Optional[Invoice]
self.bip21 = None
self.spk = None
self.spk_is_address = False
#
self.emaillike = None
self.domainlike = None
@@ -258,9 +259,11 @@ class PaymentIdentifier(Logger):
except InvoiceError as e:
self.logger.debug(self._get_error_from_invoiceerror(e))
self.set_state(PaymentIdentifierState.AVAILABLE)
elif scriptpubkey := self.parse_output(text):
elif self.parse_output(text)[0]:
scriptpubkey, is_address = self.parse_output(text)
self._type = PaymentIdentifierType.SPK
self.spk = scriptpubkey
self.spk_is_address = is_address
self.set_state(PaymentIdentifierState.AVAILABLE)
elif self.contacts and (contact := self.contacts.by_name(text)):
if contact['type'] == 'address':
@@ -464,7 +467,8 @@ class PaymentIdentifier(Logger):
return [PartialTxOutput(scriptpubkey=self.spk, value=amount)]
elif self.bip21:
address = self.bip21.get('address')
scriptpubkey = self.parse_output(address)
scriptpubkey, is_address = self.parse_output(address)
assert is_address # unlikely, but make sure it is an address, not a script
return [PartialTxOutput(scriptpubkey=scriptpubkey, value=amount)]
else:
raise Exception('not onchain')
@@ -499,25 +503,25 @@ class PaymentIdentifier(Logger):
x, y = line.split(',')
except ValueError:
raise Exception("expected two comma-separated values: (address, amount)") from None
scriptpubkey = self.parse_output(x)
scriptpubkey, is_address = self.parse_output(x)
if not scriptpubkey:
raise Exception('Invalid address')
amount = self.parse_amount(y)
return PartialTxOutput(scriptpubkey=scriptpubkey, value=amount)
def parse_output(self, x: str) -> bytes:
def parse_output(self, x: str) -> Tuple[bytes, bool]:
try:
address = self.parse_address(x)
return bytes.fromhex(bitcoin.address_to_script(address))
return bytes.fromhex(bitcoin.address_to_script(address)), True
except Exception as e:
pass
try:
script = self.parse_script(x)
return bytes.fromhex(script)
return bytes.fromhex(script), False
except Exception as e:
pass
# raise Exception("Invalid address or script.")
return None, False
def parse_script(self, x: str):
script = ''