Open jbesraa opened 7 months ago
Which of the parts should live in ldk-node/ldk/payjoin/separate crate. This question is raised because while we doing this in LDK-node, maybe we could also enable other node implementations who uses ldk to leverage Payjoin.
Indeed, IMO it would be nice to have as much common logic in a separate crate as possible.
We need to get a hold on the PSBT after the FundingSigned msg exchange and and send it back to the Payjoin sender, ie we dont wanna broadcast it ourselves even tho its an outbound channel. The question is how we want to allow that or is it possible already?
Not sure I understand this - once we have built the funding tx cooperatively with our payjoin partner, we should be good to go to broadcast, no? Not sure I understand why LDK can't be in control of when the tx gets broadcasted.
Which of the parts should live in ldk-node/ldk/payjoin/separate crate. This question is raised because while we doing this in LDK-node, maybe we could also enable other node implementations who uses ldk to leverage Payjoin.
Indeed, IMO it would be nice to have as much common logic in a separate crate as possible.
We need to get a hold on the PSBT after the FundingSigned msg exchange and and send it back to the Payjoin sender, ie we dont wanna broadcast it ourselves even tho its an outbound channel. The question is how we want to allow that or is it possible already?
Not sure I understand this - once we have built the funding tx cooperatively with our payjoin partner, we should be good to go to broadcast, no? Not sure I understand why LDK can't be in control of when the tx gets broadcasted.
In the payjoin protocol, the "payjoin sender" is the party responsible for broadcasting the transaction and in our use case we will be the "payjoin receiver". See the diagram here https://github.com/lightningdevkit/ldk-node/pull/257#issuecomment-1957680040. If we run a lightning node A and we want to open a channel with node B, we can schedule a channel that will be created once we receive a payjoin request into our node(A). So node A is the "payjoin receiver". The reason we cannot broadcast the transaction is we still need the "payjoin sender" to sign the PSBT after we are done with the channel negotiation(ie got PSBT after FundingSigned
).
I thought about adding a flag to ChannelContext
called broadcast_manually: Option<()>
and work my way around the functions to return the PSBT to the user(the node runner) after FundingSigned
if the flag is set.
Why not just run the payjoin protocol after accept_channel
but before funding_generated
/signing?
Why not just run the payjoin protocol after
accept_channel
but beforefunding_generated
/signing?
Yes, this was also my first question. To quote myself from a previous conversation, where I had proposed the following flow:
1)
create_channel
(initiating open/accept handshake) 2) GetFundingGenerationReady
, queue first PJ request to sender with aPayjoinManager
object or similar, return from event handling 3) Once the response from the Sender is received, callfunding_transaction_generated
, initiatingfunding_created/signed
handshake 4) Catch the broadcast via aPayjoinBroadcaster
implementation that broadcasts in cooperation with the Sender. Need to figure out how to handle rebroadcasts though, i.e., what to intercept and what not to intercept.
However, IIUC, the PJ sender provides a PSBT the funder needs to know/use, so it has to run before open_channel
. Is this correct, @jbesraa?
I think coupling both processes (or doing payjoin in the middle) can be tricky in the following scenarios:
1) If we want to open multiple channels from a single payjoin transaction 2) Open a channel from a payjoin transaction without predefined channel size(I run a store and receive payjoin onchain tx, I want to configure the node to open a channel if I received a a payment bigger than X)
I think in general we would want some ChannelScheduler
where the node runner can schedule multiple channels to be open when funds transferred to the node wallet via payjoin tx.
So the node wallet gets notified about an incoming payjoin tx, we loops through the scheduled channels and try to batch them in the same tx
What kind of limitations do we have once we got accept_channel
msg from our peer? are we expected to exchange the following msgs ~instantly?
Why do you prefer the payjoin process to happen after accept_channel
?
To meet the payjoin protcol spec, after we are done changing the PSBT outputs and maybe add inputs, we are expected to send whats called payjoin_proposal
to the payjoin sender, who then re-verify the tx and re-sign their inputs & broadcast. But at that point we have all the OutPoints
we need so we could start some chain monitor to track them.
If we want to open multiple channels from a single payjoin transaction
I don't see why that changes things? You can just wait until all channels are ready for funding and do the payjoin then. Worse, I'm really scared of letting users manually handle broadcast of batch channels, there's a lot that can go wrong.
Open a channel from a payjoin transaction without predefined channel size(I run a store and receive payjoin onchain tx, I want to configure the node to open a channel if I received a a payment bigger than X)
Not quite sure I understand this one - lightning nodes expect to know the channel size after open/accept_channel
, it cannot change after that, so after the funding is created its much too late to change that.
One general note, in LDK you can intercept the broadcast and handle it yourself, if you really want - the broadcast goes out via the BroadcasterInterface
and you can simply wait until you see the funding tx get broadcasted and then go do whatever you need to finish signing it (you can even let the tx go out normally - presumably if you haven't run the payjoin step its not fully signed so the broadcast will fail anyway). Obviously that's not a great API if payjoin needs to go this way, just mentioning it for completeness.
Why not just run the payjoin protocol after
accept_channel
but beforefunding_generated
/signing?
I think we could probably run the payjoin protocol in different stages(It will make it tricky but manageable with channel amount) but we cant respond back to the payjoin sender before we receive FundingSigned as that could put the funds in risk because the payjoin sender have the tx and they could broadcast it but we never receive the FundingSigned
Right, that seems like it wouldn't require any LDK changes, I think, and generally be the same implementation complexity on the payjoin side, AFAICT - either way you have to not finish the payjoin protocol until the lightning side advances, you might as well just let the lightning side actually do the broadcast, right?
Regarding the broadcasting, we should abide by the payjoin rules, which goes by the following:
1) Initiatior sends a payjoin transaction containing the original psbt
2) Receiver accepts the transaction(http request) and responds back with payjoin_proposal
3) Initiator validates the payjoin_proposal
and broadcast the tx
Also I am not sure if we can sign and broadcast the psbt after we made changes to it and we dont own the inputs?
Currently what I am doing is the following:
channel_accept
messageoriginal_psbt
to point to output_script
returned from FundingGeneartionReady
event.
2.2 call funding_transaction_generated
on channel_manager
2.3 wait in the tx_broadcaster
for the tx to come in(= FundingSigned
)
2.4 return payjoin_proposal
to payjoin initiatorThis will probably change once I go further in the PR..
I'm still confused why it needs to happen this way. Here's what I had in mind:
We're a node that wants to send payment(s) via payjoin, and in doing so open an outbound channel with some unrelated channel counterparty. This seems like the most sensible case to focus on because its the case of a "client" wallet - if we're receiving payments we probably want to receive channels too.
When we get to the point where we want to do this (ie we're ready to open a channel to the counterparty), we start by doing an open_channel
/accept_channel
handshake. Once we get the FundingGenerationReady
event we start the payjoin protocol - we now have the script we want to pay and how much we need to pay it. Once we get back the payjoin_proposal
from the payment recipient we should have a transaction and associated signatures and can feed that back into LDK and let it handle the rest.
Where did we differ - it wasn't entirely clear from your above which side we're talking about in each protocol.
A Payjoin integration with
ldk-node
started here https://github.com/lightningdevkit/ldk-node/pull/257 and there are a couple of things I discussed with tnull and we thought it would be good to bring the discussion up to here to see what everyone thinks.Our goal of integrating Payjoin with lightning is to allow users to create a channel with funds that live outside the node wallet.
In order to achieve the above goal, we need to implement the following functionality:
1) Allow a lightning node to act as a Payjoin receiver (you can look at the top of this file to understand what does it mean to be Payjoin receiver https://github.com/payjoin/rust-payjoin/blob/master/payjoin/src/receive/mod.rs#L1) 2) Allow a lightning node runner to schedule a channel for future opening (ie channel scheduler) 3) Negotiate channel opening with a peer based on the incoming Payjoin request and respond to the Payjoin sender after the negotiating reached the
Funding Signed
phase.You can find a detailed diagram of the desired flow here https://github.com/lightningdevkit/ldk-node/pull/257#issuecomment-1957680040
Two questions were raised in offline discussions:
1) Which of the parts should live in ldk-node/ldk/payjoin/separate crate. This question is raised because while we doing this in LDK-node, maybe we could also enable other node implementations who uses ldk to leverage Payjoin. 2) We need to get a hold on the PSBT after the
FundingSigned
msg exchange and and send it back to the Payjoin sender, ie we dont wanna broadcast it ourselves even tho its an outbound channel. The question is how we want to allow that or is it possible already?cc @DanGould