follow-up prev:
- detect payment of requests both onchain or LN - create single type of requests in GUI
This commit is contained in:
@@ -913,8 +913,7 @@ class Commands:
|
|||||||
return False
|
return False
|
||||||
amount = satoshis(amount)
|
amount = satoshis(amount)
|
||||||
expiration = int(expiration) if expiration else None
|
expiration = int(expiration) if expiration else None
|
||||||
req = wallet.make_payment_request(addr, amount, memo, expiration)
|
req = wallet.create_request(amount, memo, expiration, addr, False)
|
||||||
wallet.add_payment_request(req)
|
|
||||||
return wallet.export_request(req)
|
return wallet.export_request(req)
|
||||||
|
|
||||||
@command('wnl')
|
@command('wnl')
|
||||||
|
|||||||
@@ -1151,20 +1151,12 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger):
|
|||||||
|
|
||||||
self.clear_invoice_button = QPushButton(_('Clear'))
|
self.clear_invoice_button = QPushButton(_('Clear'))
|
||||||
self.clear_invoice_button.clicked.connect(self.clear_receive_tab)
|
self.clear_invoice_button.clicked.connect(self.clear_receive_tab)
|
||||||
self.create_invoice_button = QPushButton(_('New Address'))
|
self.create_invoice_button = QPushButton(_('Create Request'))
|
||||||
self.create_invoice_button.setIcon(read_QIcon("bitcoin.png"))
|
self.create_invoice_button.clicked.connect(lambda: self.create_invoice())
|
||||||
self.create_invoice_button.setToolTip('Create on-chain request')
|
|
||||||
self.create_invoice_button.clicked.connect(lambda: self.create_invoice(False))
|
|
||||||
self.receive_buttons = buttons = QHBoxLayout()
|
self.receive_buttons = buttons = QHBoxLayout()
|
||||||
buttons.addStretch(1)
|
buttons.addStretch(1)
|
||||||
buttons.addWidget(self.clear_invoice_button)
|
buttons.addWidget(self.clear_invoice_button)
|
||||||
buttons.addWidget(self.create_invoice_button)
|
buttons.addWidget(self.create_invoice_button)
|
||||||
if self.wallet.has_lightning():
|
|
||||||
self.create_lightning_invoice_button = QPushButton(_('Lightning'))
|
|
||||||
self.create_lightning_invoice_button.setToolTip('Create lightning request')
|
|
||||||
self.create_lightning_invoice_button.setIcon(read_QIcon("lightning.png"))
|
|
||||||
self.create_lightning_invoice_button.clicked.connect(lambda: self.create_invoice(True))
|
|
||||||
buttons.addWidget(self.create_lightning_invoice_button)
|
|
||||||
grid.addLayout(buttons, 4, 0, 1, -1)
|
grid.addLayout(buttons, 4, 0, 1, -1)
|
||||||
|
|
||||||
self.receive_payreq_e = ButtonsTextEdit()
|
self.receive_payreq_e = ButtonsTextEdit()
|
||||||
@@ -1262,27 +1254,31 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger):
|
|||||||
else:
|
else:
|
||||||
return
|
return
|
||||||
|
|
||||||
def create_invoice(self, is_lightning: bool):
|
def create_invoice(self):
|
||||||
amount = self.receive_amount_e.get_amount()
|
amount_sat = self.receive_amount_e.get_amount()
|
||||||
message = self.receive_message_e.text()
|
message = self.receive_message_e.text()
|
||||||
expiry = self.config.get('request_expiry', PR_DEFAULT_EXPIRATION_WHEN_CREATING)
|
expiry = self.config.get('request_expiry', PR_DEFAULT_EXPIRATION_WHEN_CREATING)
|
||||||
|
|
||||||
|
if amount_sat and amount_sat < self.wallet.dust_threshold():
|
||||||
|
address = None
|
||||||
|
if not self.wallet.has_lightning():
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
address = self.get_bitcoin_address_for_request(amount_sat)
|
||||||
|
if not address:
|
||||||
|
return
|
||||||
|
self.address_list.update()
|
||||||
|
|
||||||
|
# generate even if we cannot receive
|
||||||
|
lightning = self.wallet.has_lightning()
|
||||||
try:
|
try:
|
||||||
if is_lightning:
|
key = self.wallet.create_request(amount_sat, message, expiry, address, lightning=lightning)
|
||||||
if not self.wallet.lnworker.channels:
|
|
||||||
self.show_error(_("You need to open a Lightning channel first."))
|
|
||||||
return
|
|
||||||
# TODO maybe show a warning if amount exceeds lnworker.num_sats_can_receive (as in kivy)
|
|
||||||
key = self.wallet.lnworker.add_request(amount, message, expiry)
|
|
||||||
else:
|
|
||||||
key = self.create_bitcoin_request(amount, message, expiry)
|
|
||||||
if not key:
|
|
||||||
return
|
|
||||||
self.address_list.refresh_all()
|
|
||||||
except InvoiceError as e:
|
except InvoiceError as e:
|
||||||
self.show_error(_('Error creating payment request') + ':\n' + str(e))
|
self.show_error(_('Error creating payment request') + ':\n' + str(e))
|
||||||
return
|
return
|
||||||
|
|
||||||
assert key is not None
|
assert key is not None
|
||||||
|
self.address_list.refresh_all()
|
||||||
self.request_list.update()
|
self.request_list.update()
|
||||||
self.request_list.select_key(key)
|
self.request_list.select_key(key)
|
||||||
# clear request fields
|
# clear request fields
|
||||||
@@ -1291,10 +1287,10 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger):
|
|||||||
# copy to clipboard
|
# copy to clipboard
|
||||||
r = self.wallet.get_request(key)
|
r = self.wallet.get_request(key)
|
||||||
content = r.lightning_invoice if r.is_lightning() else r.get_address()
|
content = r.lightning_invoice if r.is_lightning() else r.get_address()
|
||||||
title = _('Invoice') if is_lightning else _('Address')
|
title = _('Invoice') if r.is_lightning() else _('Address')
|
||||||
self.do_copy(content, title=title)
|
self.do_copy(content, title=title)
|
||||||
|
|
||||||
def create_bitcoin_request(self, amount: int, message: str, expiration: int) -> Optional[str]:
|
def get_bitcoin_address_for_request(self, amount: int) -> Optional[str]:
|
||||||
addr = self.wallet.get_unused_address()
|
addr = self.wallet.get_unused_address()
|
||||||
if addr is None:
|
if addr is None:
|
||||||
if not self.wallet.is_deterministic(): # imported wallet
|
if not self.wallet.is_deterministic(): # imported wallet
|
||||||
@@ -1311,15 +1307,6 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger):
|
|||||||
if not self.question(_("Warning: The next address will not be recovered automatically if you restore your wallet from seed; you may need to add it manually.\n\nThis occurs because you have too many unused addresses in your wallet. To avoid this situation, use the existing addresses first.\n\nCreate anyway?")):
|
if not self.question(_("Warning: The next address will not be recovered automatically if you restore your wallet from seed; you may need to add it manually.\n\nThis occurs because you have too many unused addresses in your wallet. To avoid this situation, use the existing addresses first.\n\nCreate anyway?")):
|
||||||
return
|
return
|
||||||
addr = self.wallet.create_new_address(False)
|
addr = self.wallet.create_new_address(False)
|
||||||
timestamp = int(time.time())
|
|
||||||
req = self.wallet.make_payment_request(amount, message, timestamp, expiration, address=addr)
|
|
||||||
try:
|
|
||||||
self.wallet.add_payment_request(req)
|
|
||||||
except Exception as e:
|
|
||||||
self.logger.exception('Error adding payment request')
|
|
||||||
self.show_error(_('Error adding payment request') + ':\n' + repr(e))
|
|
||||||
else:
|
|
||||||
self.sign_payment_request(addr)
|
|
||||||
return addr
|
return addr
|
||||||
|
|
||||||
def do_copy(self, content: str, *, title: str = None) -> None:
|
def do_copy(self, content: str, *, title: str = None) -> None:
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ from .util import age, InvoiceError
|
|||||||
from .lnaddr import lndecode, LnAddr
|
from .lnaddr import lndecode, LnAddr
|
||||||
from . import constants
|
from . import constants
|
||||||
from .bitcoin import COIN, TOTAL_COIN_SUPPLY_LIMIT_IN_BTC
|
from .bitcoin import COIN, TOTAL_COIN_SUPPLY_LIMIT_IN_BTC
|
||||||
|
from .bitcoin import address_to_script
|
||||||
from .transaction import PartialTxOutput
|
from .transaction import PartialTxOutput
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
@@ -116,7 +117,18 @@ class Invoice(StoredObject):
|
|||||||
|
|
||||||
def get_address(self) -> str:
|
def get_address(self) -> str:
|
||||||
"""returns the first address, to be displayed in GUI"""
|
"""returns the first address, to be displayed in GUI"""
|
||||||
return self.outputs[0].address
|
if self.is_lightning():
|
||||||
|
return self._lnaddr.get_fallback_address() or None
|
||||||
|
else:
|
||||||
|
return self.outputs[0].address
|
||||||
|
|
||||||
|
def get_outputs(self):
|
||||||
|
if self.is_lightning():
|
||||||
|
address = self.get_address()
|
||||||
|
outputs = [PartialTxOutput.from_address_and_value(address, int(self.get_amount_sat()))] if address else []
|
||||||
|
else:
|
||||||
|
outputs = self.outputs
|
||||||
|
return outputs
|
||||||
|
|
||||||
def get_expiration_date(self):
|
def get_expiration_date(self):
|
||||||
# 0 means never
|
# 0 means never
|
||||||
@@ -141,6 +153,14 @@ class Invoice(StoredObject):
|
|||||||
return None
|
return None
|
||||||
return int(amount_msat / 1000)
|
return int(amount_msat / 1000)
|
||||||
|
|
||||||
|
def get_bip21_URI(self):
|
||||||
|
from electrum.util import create_bip21_uri
|
||||||
|
addr = self.get_address()
|
||||||
|
amount = int(self.get_amount_sat())
|
||||||
|
message = self.message
|
||||||
|
uri = create_bip21_uri(addr, amount, message)
|
||||||
|
return str(uri)
|
||||||
|
|
||||||
@lightning_invoice.validator
|
@lightning_invoice.validator
|
||||||
def _validate_invoice_str(self, attribute, value):
|
def _validate_invoice_str(self, attribute, value):
|
||||||
if value is not None:
|
if value is not None:
|
||||||
|
|||||||
@@ -211,7 +211,8 @@ def lnencode(addr: 'LnAddr', privkey) -> str:
|
|||||||
route = bitstring.BitArray(pubkey) + bitstring.pack('intbe:32', feebase) + bitstring.pack('intbe:32', feerate) + bitstring.pack('intbe:16', cltv)
|
route = bitstring.BitArray(pubkey) + bitstring.pack('intbe:32', feebase) + bitstring.pack('intbe:32', feerate) + bitstring.pack('intbe:16', cltv)
|
||||||
data += tagged('t', route)
|
data += tagged('t', route)
|
||||||
elif k == 'f':
|
elif k == 'f':
|
||||||
data += encode_fallback(v, addr.net)
|
if v is not None:
|
||||||
|
data += encode_fallback(v, addr.net)
|
||||||
elif k == 'd':
|
elif k == 'd':
|
||||||
# truncate to max length: 1024*5 bits = 639 bytes
|
# truncate to max length: 1024*5 bits = 639 bytes
|
||||||
data += tagged_bytes('d', v.encode()[0:639])
|
data += tagged_bytes('d', v.encode()[0:639])
|
||||||
@@ -336,6 +337,9 @@ class LnAddr(object):
|
|||||||
def get_description(self) -> str:
|
def get_description(self) -> str:
|
||||||
return self.get_tag('d') or ''
|
return self.get_tag('d') or ''
|
||||||
|
|
||||||
|
def get_fallback_address(self) -> str:
|
||||||
|
return self.get_tag('f') or ''
|
||||||
|
|
||||||
def get_expiry(self) -> int:
|
def get_expiry(self) -> int:
|
||||||
exp = self.get_tag('x')
|
exp = self.get_tag('x')
|
||||||
if exp is None:
|
if exp is None:
|
||||||
|
|||||||
@@ -1793,18 +1793,7 @@ class LNWallet(LNWorker):
|
|||||||
expiry=expiry,
|
expiry=expiry,
|
||||||
write_to_disk=False,
|
write_to_disk=False,
|
||||||
)
|
)
|
||||||
req = self.wallet.make_payment_request(
|
return invoice
|
||||||
amount_sat,
|
|
||||||
message,
|
|
||||||
timestamp,
|
|
||||||
expiry,
|
|
||||||
address=None,
|
|
||||||
lightning_invoice=invoice
|
|
||||||
)
|
|
||||||
key = self.wallet.add_payment_request(req, write_to_disk=False)
|
|
||||||
self.wallet.set_label(key, message)
|
|
||||||
self.wallet.save_db()
|
|
||||||
return key
|
|
||||||
|
|
||||||
def save_preimage(self, payment_hash: bytes, preimage: bytes, *, write_to_disk: bool = True):
|
def save_preimage(self, payment_hash: bytes, preimage: bytes, *, write_to_disk: bool = True):
|
||||||
assert sha256(preimage) == payment_hash
|
assert sha256(preimage) == payment_hash
|
||||||
|
|||||||
@@ -278,6 +278,7 @@ class SwapManager(Logger):
|
|||||||
amount_msat=lightning_amount_sat * 1000,
|
amount_msat=lightning_amount_sat * 1000,
|
||||||
message='swap',
|
message='swap',
|
||||||
expiry=3600 * 24,
|
expiry=3600 * 24,
|
||||||
|
fallback_address=None,
|
||||||
)
|
)
|
||||||
payment_hash = lnaddr.paymenthash
|
payment_hash = lnaddr.paymenthash
|
||||||
preimage = self.lnworker.get_preimage(payment_hash)
|
preimage = self.lnworker.get_preimage(payment_hash)
|
||||||
|
|||||||
@@ -789,7 +789,7 @@ class Abstract_Wallet(AddressSynchronizer, ABC):
|
|||||||
if self.is_onchain_invoice_paid(invoice, 0):
|
if self.is_onchain_invoice_paid(invoice, 0):
|
||||||
self.logger.info("saving invoice... but it is already paid!")
|
self.logger.info("saving invoice... but it is already paid!")
|
||||||
with self.transaction_lock:
|
with self.transaction_lock:
|
||||||
for txout in invoice.outputs:
|
for txout in invoice.get_outputs():
|
||||||
self._invoices_from_scriptpubkey_map[txout.scriptpubkey].add(key)
|
self._invoices_from_scriptpubkey_map[txout.scriptpubkey].add(key)
|
||||||
self.invoices[key] = invoice
|
self.invoices[key] = invoice
|
||||||
self.save_db()
|
self.save_db()
|
||||||
@@ -854,15 +854,18 @@ class Abstract_Wallet(AddressSynchronizer, ABC):
|
|||||||
# scriptpubkey -> list(invoice_keys)
|
# scriptpubkey -> list(invoice_keys)
|
||||||
self._invoices_from_scriptpubkey_map = defaultdict(set) # type: Dict[bytes, Set[str]]
|
self._invoices_from_scriptpubkey_map = defaultdict(set) # type: Dict[bytes, Set[str]]
|
||||||
for invoice_key, invoice in self.invoices.items():
|
for invoice_key, invoice in self.invoices.items():
|
||||||
if not invoice.is_lightning():
|
if invoice.is_lightning() and not invoice.get_address():
|
||||||
for txout in invoice.outputs:
|
continue
|
||||||
self._invoices_from_scriptpubkey_map[txout.scriptpubkey].add(invoice_key)
|
for txout in invoice.get_outputs():
|
||||||
|
self._invoices_from_scriptpubkey_map[txout.scriptpubkey].add(invoice_key)
|
||||||
|
|
||||||
def _is_onchain_invoice_paid(self, invoice: Invoice, conf: int) -> Tuple[bool, Sequence[str]]:
|
def _is_onchain_invoice_paid(self, invoice: Invoice, conf: int) -> Tuple[bool, Sequence[str]]:
|
||||||
"""Returns whether on-chain invoice is satisfied, and list of relevant TXIDs."""
|
"""Returns whether on-chain invoice is satisfied, and list of relevant TXIDs."""
|
||||||
assert not invoice.is_lightning()
|
if invoice.is_lightning() and not invoice.get_address():
|
||||||
|
return False, []
|
||||||
|
outputs = invoice.get_outputs()
|
||||||
invoice_amounts = defaultdict(int) # type: Dict[bytes, int] # scriptpubkey -> value_sats
|
invoice_amounts = defaultdict(int) # type: Dict[bytes, int] # scriptpubkey -> value_sats
|
||||||
for txo in invoice.outputs: # type: PartialTxOutput
|
for txo in outputs: # type: PartialTxOutput
|
||||||
invoice_amounts[txo.scriptpubkey] += 1 if parse_max_spend(txo.value) else txo.value
|
invoice_amounts[txo.scriptpubkey] += 1 if parse_max_spend(txo.value) else txo.value
|
||||||
relevant_txs = []
|
relevant_txs = []
|
||||||
with self.lock, self.transaction_lock:
|
with self.lock, self.transaction_lock:
|
||||||
@@ -2048,6 +2051,7 @@ class Abstract_Wallet(AddressSynchronizer, ABC):
|
|||||||
def get_unused_addresses(self) -> Sequence[str]:
|
def get_unused_addresses(self) -> Sequence[str]:
|
||||||
domain = self.get_receiving_addresses()
|
domain = self.get_receiving_addresses()
|
||||||
# TODO we should index receive_requests by id
|
# TODO we should index receive_requests by id
|
||||||
|
# add lightning requests. (use as key)
|
||||||
in_use_by_request = [k for k in self.receive_requests.keys()
|
in_use_by_request = [k for k in self.receive_requests.keys()
|
||||||
if self.get_request_status(k) != PR_EXPIRED]
|
if self.get_request_status(k) != PR_EXPIRED]
|
||||||
in_use_by_request = set(in_use_by_request)
|
in_use_by_request = set(in_use_by_request)
|
||||||
@@ -2116,6 +2120,7 @@ class Abstract_Wallet(AddressSynchronizer, ABC):
|
|||||||
return False, None
|
return False, None
|
||||||
|
|
||||||
def get_request_URI(self, req: Invoice) -> str:
|
def get_request_URI(self, req: Invoice) -> str:
|
||||||
|
# todo: should be a method of invoice?
|
||||||
addr = req.get_address()
|
addr = req.get_address()
|
||||||
message = self.get_label(addr)
|
message = self.get_label(addr)
|
||||||
amount = req.get_amount_sat()
|
amount = req.get_amount_sat()
|
||||||
@@ -2139,31 +2144,34 @@ class Abstract_Wallet(AddressSynchronizer, ABC):
|
|||||||
return status
|
return status
|
||||||
|
|
||||||
def get_invoice_status(self, invoice: Invoice):
|
def get_invoice_status(self, invoice: Invoice):
|
||||||
if invoice.is_lightning():
|
# lightning invoices can be paid onchain
|
||||||
status = self.lnworker.get_invoice_status(invoice) if self.lnworker else PR_UNKNOWN
|
if invoice.is_lightning() and self.lnworker:
|
||||||
|
status = self.lnworker.get_invoice_status(invoice)
|
||||||
|
if status != PR_UNPAID:
|
||||||
|
return self.check_expired_status(invoice, status)
|
||||||
|
if self.is_onchain_invoice_paid(invoice, 1):
|
||||||
|
status = PR_PAID
|
||||||
|
elif self.is_onchain_invoice_paid(invoice, 0):
|
||||||
|
status = PR_UNCONFIRMED
|
||||||
else:
|
else:
|
||||||
if self.is_onchain_invoice_paid(invoice, 1):
|
status = PR_UNPAID
|
||||||
status =PR_PAID
|
|
||||||
elif self.is_onchain_invoice_paid(invoice, 0):
|
|
||||||
status = PR_UNCONFIRMED
|
|
||||||
else:
|
|
||||||
status = PR_UNPAID
|
|
||||||
return self.check_expired_status(invoice, status)
|
return self.check_expired_status(invoice, status)
|
||||||
|
|
||||||
def get_request_status(self, key):
|
def get_request_status(self, key):
|
||||||
r = self.get_request(key)
|
r = self.get_request(key)
|
||||||
if r is None:
|
if r is None:
|
||||||
return PR_UNKNOWN
|
return PR_UNKNOWN
|
||||||
if r.is_lightning():
|
if r.is_lightning() and self.lnworker:
|
||||||
status = self.lnworker.get_payment_status(bfh(r.rhash)) if self.lnworker else PR_UNKNOWN
|
status = self.lnworker.get_payment_status(bfh(r.rhash))
|
||||||
|
if status != PR_UNPAID:
|
||||||
|
return self.check_expired_status(r, status)
|
||||||
|
paid, conf = self.get_onchain_request_status(r)
|
||||||
|
if not paid:
|
||||||
|
status = PR_UNPAID
|
||||||
|
elif conf == 0:
|
||||||
|
status = PR_UNCONFIRMED
|
||||||
else:
|
else:
|
||||||
paid, conf = self.get_onchain_request_status(r)
|
status = PR_PAID
|
||||||
if not paid:
|
|
||||||
status = PR_UNPAID
|
|
||||||
elif conf == 0:
|
|
||||||
status = PR_UNCONFIRMED
|
|
||||||
else:
|
|
||||||
status = PR_PAID
|
|
||||||
return self.check_expired_status(r, status)
|
return self.check_expired_status(r, status)
|
||||||
|
|
||||||
def get_request(self, key):
|
def get_request(self, key):
|
||||||
@@ -2268,23 +2276,26 @@ class Abstract_Wallet(AddressSynchronizer, ABC):
|
|||||||
status = self.get_request_status(addr)
|
status = self.get_request_status(addr)
|
||||||
util.trigger_callback('request_status', self, addr, status)
|
util.trigger_callback('request_status', self, addr, status)
|
||||||
|
|
||||||
def make_payment_request(self, amount_sat, message, timestamp, expiration, address=None, lightning_invoice=None):
|
def create_request(self, amount_sat: int, message: str, exp_delay: int, address: str, lightning: bool):
|
||||||
# TODO maybe merge with wallet.create_invoice()...
|
# for receiving
|
||||||
# note that they use incompatible "id"
|
|
||||||
amount_sat = amount_sat or 0
|
amount_sat = amount_sat or 0
|
||||||
#_id = bh2u(sha256d(address + "%d"%timestamp))[0:10]
|
exp_delay = exp_delay or 0
|
||||||
expiration = expiration or 0
|
timestamp = int(time.time())
|
||||||
outputs=[PartialTxOutput.from_address_and_value(address, amount_sat)] if address else []
|
lightning_invoice = self.lnworker.add_request(amount_sat, message, exp_delay) if lightning else None
|
||||||
return Invoice(
|
outputs = [ PartialTxOutput.from_address_and_value(address, amount_sat)] if address else []
|
||||||
|
height = self.get_local_height()
|
||||||
|
req = Invoice(
|
||||||
outputs=outputs,
|
outputs=outputs,
|
||||||
message=message,
|
message=message,
|
||||||
time=timestamp,
|
time=timestamp,
|
||||||
amount_msat=amount_sat*1000,
|
amount_msat=amount_sat*1000,
|
||||||
exp=expiration,
|
exp=exp_delay,
|
||||||
height=self.get_local_height(),
|
height=height,
|
||||||
bip70=None,
|
bip70=None,
|
||||||
lightning_invoice=lightning_invoice,
|
lightning_invoice=lightning_invoice,
|
||||||
)
|
)
|
||||||
|
key = self.add_payment_request(req, write_to_disk=False)
|
||||||
|
return key
|
||||||
|
|
||||||
def sign_payment_request(self, key, alias, alias_addr, password): # FIXME this is broken
|
def sign_payment_request(self, key, alias, alias_addr, password): # FIXME this is broken
|
||||||
raise
|
raise
|
||||||
@@ -2304,11 +2315,12 @@ class Abstract_Wallet(AddressSynchronizer, ABC):
|
|||||||
if invoice.is_lightning():
|
if invoice.is_lightning():
|
||||||
key = invoice.rhash
|
key = invoice.rhash
|
||||||
else:
|
else:
|
||||||
key = bh2u(sha256d(repr(invoice.outputs) + "%d"%invoice.time))[0:10]
|
key = bh2u(sha256d(repr(invoice.get_outputs()) + "%d"%invoice.time))[0:10]
|
||||||
return key
|
return key
|
||||||
|
|
||||||
def get_key_for_receive_request(self, req: Invoice, *, sanity_checks: bool = False) -> str:
|
def get_key_for_receive_request(self, req: Invoice, *, sanity_checks: bool = False) -> str:
|
||||||
"""Return the key to use for this invoice in self.receive_requests."""
|
"""Return the key to use for this invoice in self.receive_requests."""
|
||||||
|
# FIXME: this should be a method of Invoice
|
||||||
if not req.is_lightning():
|
if not req.is_lightning():
|
||||||
addr = req.get_address()
|
addr = req.get_address()
|
||||||
if sanity_checks:
|
if sanity_checks:
|
||||||
@@ -2318,7 +2330,8 @@ class Abstract_Wallet(AddressSynchronizer, ABC):
|
|||||||
raise Exception(_('Address not in wallet.'))
|
raise Exception(_('Address not in wallet.'))
|
||||||
key = addr
|
key = addr
|
||||||
else:
|
else:
|
||||||
key = req.rhash
|
addr = req.get_address()
|
||||||
|
key = req.rhash if addr is None else addr
|
||||||
return key
|
return key
|
||||||
|
|
||||||
def add_payment_request(self, req: Invoice, *, write_to_disk: bool = True):
|
def add_payment_request(self, req: Invoice, *, write_to_disk: bool = True):
|
||||||
|
|||||||
Reference in New Issue
Block a user