Skip to content

Commit 2e7f1e5

Browse files
committed
loopout: use asset client for payment
1 parent a25753c commit 2e7f1e5

File tree

1 file changed

+76
-2
lines changed

1 file changed

+76
-2
lines changed

loopout.go

Lines changed: 76 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,11 @@ import (
2020
"github.com/lightninglabs/loop/sweep"
2121
"github.com/lightninglabs/loop/sweepbatcher"
2222
"github.com/lightninglabs/loop/utils"
23+
"github.com/lightninglabs/taproot-assets/taprpc/tapchannelrpc"
2324
"github.com/lightningnetwork/lnd/chainntnfs"
2425
"github.com/lightningnetwork/lnd/channeldb"
2526
"github.com/lightningnetwork/lnd/lnrpc"
27+
"github.com/lightningnetwork/lnd/lnrpc/routerrpc"
2628
"github.com/lightningnetwork/lnd/lntypes"
2729
)
2830

@@ -87,8 +89,9 @@ type loopOutSwap struct {
8789
// to calculate the total cost of the swap.
8890
prepayAmount btcutil.Amount
8991

90-
swapPaymentChan chan paymentResult
91-
prePaymentChan chan paymentResult
92+
swapPaymentChan chan paymentResult
93+
prePaymentChan chan paymentResult
94+
waitForRfqCompletedChan chan interface{}
9295

9396
wg sync.WaitGroup
9497
}
@@ -634,13 +637,22 @@ func (s *loopOutSwap) payInvoices(ctx context.Context) {
634637
s.log.Infof("Server recommended routing plugin: %v", pluginType)
635638
}
636639

640+
if s.AssetId != nil {
641+
s.waitForRfqCompletedChan = make(chan interface{})
642+
}
643+
637644
// Use the recommended routing plugin.
638645
s.swapPaymentChan = s.payInvoice(
639646
ctx, s.SwapInvoice, s.MaxSwapRoutingFee,
640647
s.LoopOutContract.OutgoingChanSet,
641648
s.LoopOutContract.PaymentTimeout, pluginType, true,
642649
)
643650

651+
// We'll nee
652+
if s.AssetId != nil {
653+
<-s.waitForRfqCompletedChan
654+
}
655+
644656
// Pay the prepay invoice. Won't use the routing plugin here as the
645657
// prepay is trivially small and shouldn't normally need any help. We
646658
// are sending it over the same channel as the loop out payment.
@@ -717,13 +729,75 @@ func (s *loopOutSwap) payInvoice(ctx context.Context, invoice string,
717729
return resultChan
718730
}
719731

732+
func (s *loopOutSwap) payInvoiceWithAssetClient(ctx context.Context,
733+
invoice string) (*lndclient.PaymentStatus, error) {
734+
735+
totalPaymentTimeout := s.executeConfig.totalPaymentTimeout
736+
737+
sendReq := &routerrpc.SendPaymentRequest{
738+
PaymentRequest: invoice,
739+
TimeoutSeconds: int32(totalPaymentTimeout.Seconds()),
740+
FeeLimitMsat: 1_000_000,
741+
}
742+
743+
paymentStream, err := s.assets.SendPayment(
744+
ctx, &tapchannelrpc.SendPaymentRequest{
745+
AssetId: s.AssetId,
746+
PeerPubkey: s.AssetEdgeNode,
747+
PaymentRequest: sendReq,
748+
})
749+
if err != nil {
750+
return nil, err
751+
}
752+
753+
// We want to receive the accepted quote message first, so we know how
754+
// many assets we're going to pay.
755+
for {
756+
select {
757+
case <-ctx.Done():
758+
return nil, ctx.Err()
759+
default:
760+
msg, err := paymentStream.Recv()
761+
if err != nil {
762+
return nil, err
763+
}
764+
765+
switch msg.GetResult().(type) {
766+
case *tapchannelrpc.SendPaymentResponse_AcceptedSellOrder:
767+
quote := msg.GetAcceptedSellOrder()
768+
log.Infof("Accepted quote: %v", quote.AssetAmount)
769+
if s.waitForRfqCompletedChan != nil {
770+
close(s.waitForRfqCompletedChan)
771+
s.waitForRfqCompletedChan = nil
772+
}
773+
774+
case *tapchannelrpc.SendPaymentResponse_PaymentResult:
775+
payRes := msg.GetPaymentResult()
776+
if payRes.Status == lnrpc.Payment_SUCCEEDED ||
777+
payRes.Status == lnrpc.Payment_FAILED {
778+
779+
return &lndclient.PaymentStatus{
780+
State: payRes.Status,
781+
}, nil
782+
}
783+
}
784+
}
785+
}
786+
}
787+
720788
// payInvoiceAsync is the asynchronously executed part of paying an invoice.
721789
func (s *loopOutSwap) payInvoiceAsync(ctx context.Context,
722790
invoice string, maxFee btcutil.Amount,
723791
outgoingChanIds loopdb.ChannelSet, paymentTimeout time.Duration,
724792
pluginType RoutingPluginType, reportPluginResult bool) (
725793
*lndclient.PaymentStatus, error) {
726794

795+
// If we want to use an asset for the payment, we need to use the asset
796+
// client.
797+
if s.AssetId != nil {
798+
return s.payInvoiceWithAssetClient(ctx, invoice)
799+
}
800+
727801
// Extract hash from payment request. Unfortunately the request
728802
// components aren't available directly.
729803
chainParams := s.lnd.ChainParams

0 commit comments

Comments
 (0)