@@ -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}
@@ -635,13 +638,22 @@ func (s *loopOutSwap) payInvoices(ctx context.Context) {
635638 s .log .Infof ("Server recommended routing plugin: %v" , pluginType )
636639 }
637640
641+ if s .AssetId != nil {
642+ s .waitForRfqCompletedChan = make (chan interface {})
643+ }
644+
638645 // Use the recommended routing plugin.
639646 s .swapPaymentChan = s .payInvoice (
640647 ctx , s .SwapInvoice , s .MaxSwapRoutingFee ,
641648 s .LoopOutContract .OutgoingChanSet ,
642649 s .LoopOutContract .PaymentTimeout , pluginType , true ,
643650 )
644651
652+ // We'll nee
653+ if s .AssetId != nil {
654+ <- s .waitForRfqCompletedChan
655+ }
656+
645657 // Pay the prepay invoice. Won't use the routing plugin here as the
646658 // prepay is trivially small and shouldn't normally need any help. We
647659 // are sending it over the same channel as the loop out payment.
@@ -718,13 +730,75 @@ func (s *loopOutSwap) payInvoice(ctx context.Context, invoice string,
718730 return resultChan
719731}
720732
733+ func (s * loopOutSwap ) payInvoiceWithAssetClient (ctx context.Context ,
734+ invoice string ) (* lndclient.PaymentStatus , error ) {
735+
736+ totalPaymentTimeout := s .executeConfig .totalPaymentTimeout
737+
738+ sendReq := & routerrpc.SendPaymentRequest {
739+ PaymentRequest : invoice ,
740+ TimeoutSeconds : int32 (totalPaymentTimeout .Seconds ()),
741+ FeeLimitMsat : 1_000_000 ,
742+ }
743+
744+ paymentStream , err := s .assets .SendPayment (
745+ ctx , & tapchannelrpc.SendPaymentRequest {
746+ AssetId : s .AssetId ,
747+ PeerPubkey : s .AssetEdgeNode ,
748+ PaymentRequest : sendReq ,
749+ })
750+ if err != nil {
751+ return nil , err
752+ }
753+
754+ // We want to receive the accepted quote message first, so we know how
755+ // many assets we're going to pay.
756+ for {
757+ select {
758+ case <- ctx .Done ():
759+ return nil , ctx .Err ()
760+ default :
761+ msg , err := paymentStream .Recv ()
762+ if err != nil {
763+ return nil , err
764+ }
765+
766+ switch msg .GetResult ().(type ) {
767+ case * tapchannelrpc.SendPaymentResponse_AcceptedSellOrder :
768+ quote := msg .GetAcceptedSellOrder ()
769+ log .Infof ("Accepted quote: %v" , quote .AssetAmount )
770+ if s .waitForRfqCompletedChan != nil {
771+ close (s .waitForRfqCompletedChan )
772+ s .waitForRfqCompletedChan = nil
773+ }
774+
775+ case * tapchannelrpc.SendPaymentResponse_PaymentResult :
776+ payRes := msg .GetPaymentResult ()
777+ if payRes .Status == lnrpc .Payment_SUCCEEDED ||
778+ payRes .Status == lnrpc .Payment_FAILED {
779+
780+ return & lndclient.PaymentStatus {
781+ State : payRes .Status ,
782+ }, nil
783+ }
784+ }
785+ }
786+ }
787+ }
788+
721789// payInvoiceAsync is the asynchronously executed part of paying an invoice.
722790func (s * loopOutSwap ) payInvoiceAsync (ctx context.Context ,
723791 invoice string , maxFee btcutil.Amount ,
724792 outgoingChanIds loopdb.ChannelSet , paymentTimeout time.Duration ,
725793 pluginType RoutingPluginType , reportPluginResult bool ) (
726794 * lndclient.PaymentStatus , error ) {
727795
796+ // If we want to use an asset for the payment, we need to use the asset
797+ // client.
798+ if s .AssetId != nil {
799+ return s .payInvoiceWithAssetClient (ctx , invoice )
800+ }
801+
728802 // Extract hash from payment request. Unfortunately the request
729803 // components aren't available directly.
730804 chainParams := s .lnd .ChainParams
0 commit comments