@@ -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.
721789func (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