Browse Source

refactor payjoin to support non-command line

master
Adam Gibson 5 years ago
parent
commit
aeba4cae59
No known key found for this signature in database
GPG Key ID: 141001A1AF77F20B
  1. 31
      jmclient/jmclient/payjoin.py

31
jmclient/jmclient/payjoin.py

@ -76,7 +76,8 @@ class JMPayjoinManager(object):
pj_state = JM_PJ_NONE pj_state = JM_PJ_NONE
def __init__(self, wallet_service, mixdepth, destination, def __init__(self, wallet_service, mixdepth, destination,
amount, server, disable_output_substitution=False): amount, server, disable_output_substitution=False,
mode="command-line"):
assert isinstance(wallet_service, WalletService) assert isinstance(wallet_service, WalletService)
# payjoin is not supported for non-segwit wallets: # payjoin is not supported for non-segwit wallets:
assert isinstance(wallet_service.wallet, assert isinstance(wallet_service.wallet,
@ -103,6 +104,13 @@ class JMPayjoinManager(object):
# in case there is no change: # in case there is no change:
self.change_out = None self.change_out = None
self.change_out_index = None self.change_out_index = None
# payment mode is "command-line" for one-shot
# processing, shutting down on completion.
self.mode = mode
# to be able to cancel the timeout fallback broadcast
# in case of success:
self.timeout_fallback_dc = None
def set_payment_tx_and_psbt(self, in_psbt): def set_payment_tx_and_psbt(self, in_psbt):
assert isinstance(in_psbt, btc.PartiallySignedTransaction) assert isinstance(in_psbt, btc.PartiallySignedTransaction)
@ -373,7 +381,7 @@ class JMPayjoinManager(object):
else: else:
return reportdict return reportdict
def parse_payjoin_setup(bip21_uri, wallet_service, mixdepth): def parse_payjoin_setup(bip21_uri, wallet_service, mixdepth, mode="command-line"):
""" Takes the payment request data from the uri and returns a """ Takes the payment request data from the uri and returns a
JMPayjoinManager object initialised for that payment. JMPayjoinManager object initialised for that payment.
""" """
@ -393,7 +401,8 @@ def parse_payjoin_setup(bip21_uri, wallet_service, mixdepth):
if "pjos" in decoded and decoded["pjos"] == "0": if "pjos" in decoded and decoded["pjos"] == "0":
disable_output_substitution = True disable_output_substitution = True
return JMPayjoinManager(wallet_service, mixdepth, destaddr, amount, server, return JMPayjoinManager(wallet_service, mixdepth, destaddr, amount, server,
disable_output_substitution=disable_output_substitution) disable_output_substitution=disable_output_substitution,
mode=mode)
def get_max_additional_fee_contribution(manager): def get_max_additional_fee_contribution(manager):
""" See definition of maxadditionalfeecontribution in BIP 78. """ See definition of maxadditionalfeecontribution in BIP 78.
@ -450,7 +459,8 @@ def send_payjoin(manager, accept_callback=None,
manager.set_payment_tx_and_psbt(payment_psbt) manager.set_payment_tx_and_psbt(payment_psbt)
# add delayed call to broadcast this after 1 minute # add delayed call to broadcast this after 1 minute
reactor.callLater(60, fallback_nonpayjoin_broadcast, manager, b"timeout") manager.timeout_fallback_dc = reactor.callLater(60, fallback_nonpayjoin_broadcast,
manager, b"timeout")
# Now we send the request to the server, with the encoded # Now we send the request to the server, with the encoded
# payment PSBT # payment PSBT
@ -538,9 +548,10 @@ def fallback_nonpayjoin_broadcast(manager, err):
""" """
assert isinstance(manager, JMPayjoinManager) assert isinstance(manager, JMPayjoinManager)
def quit(): def quit():
for dc in reactor.getDelayedCalls(): if manager.mode == "command-line" and reactor.running:
dc.cancel() for dc in reactor.getDelayedCalls():
reactor.stop() dc.cancel()
reactor.stop()
log.warn("Payjoin did not succeed, falling back to non-payjoin payment.") log.warn("Payjoin did not succeed, falling back to non-payjoin payment.")
log.warn("Error message was: " + err.decode("utf-8")) log.warn("Error message was: " + err.decode("utf-8"))
original_tx = manager.initial_psbt.extract_transaction() original_tx = manager.initial_psbt.extract_transaction()
@ -616,4 +627,8 @@ def process_payjoin_proposal_from_server(response_body, manager):
log.info("The above transaction failed to broadcast.") log.info("The above transaction failed to broadcast.")
else: else:
log.info("Payjoin transaction broadcast successfully.") log.info("Payjoin transaction broadcast successfully.")
reactor.stop() # if transaction is succesfully broadcast, remove the
# timeout fallback to avoid confusing error messages:
manager.timeout_fallback_dc.cancel()
if manager.mode == "command-line" and reactor.running:
reactor.stop()

Loading…
Cancel
Save