@@ -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
@@ -634,11 +636,16 @@ func (s *loopOutSwap) payInvoices(ctx context.Context) {
634636 s .log .Infof ("Server recommended routing plugin: %v" , pluginType )
635637 }
636638
639+ var useAssetForPayment bool
640+ if s .AssetId != nil {
641+ useAssetForPayment = true
642+ }
643+
637644 // Use the recommended routing plugin.
638645 s .swapPaymentChan = s .payInvoice (
639646 ctx , s .SwapInvoice , s .MaxSwapRoutingFee ,
640647 s .LoopOutContract .OutgoingChanSet ,
641- s .LoopOutContract .PaymentTimeout , pluginType , true ,
648+ s .LoopOutContract .PaymentTimeout , pluginType , true , useAssetForPayment ,
642649 )
643650
644651 // Pay the prepay invoice. Won't use the routing plugin here as the
@@ -648,7 +655,7 @@ func (s *loopOutSwap) payInvoices(ctx context.Context) {
648655 s .prePaymentChan = s .payInvoice (
649656 ctx , s .PrepayInvoice , s .MaxPrepayRoutingFee ,
650657 s .LoopOutContract .OutgoingChanSet ,
651- s .LoopOutContract .PaymentTimeout , RoutingPluginNone , false ,
658+ s .LoopOutContract .PaymentTimeout , RoutingPluginNone , false , false ,
652659 )
653660}
654661
@@ -677,7 +684,7 @@ func (p paymentResult) failure() error {
677684func (s * loopOutSwap ) payInvoice (ctx context.Context , invoice string ,
678685 maxFee btcutil.Amount , outgoingChanIds loopdb.ChannelSet ,
679686 paymentTimeout time.Duration , pluginType RoutingPluginType ,
680- reportPluginResult bool ) chan paymentResult {
687+ reportPluginResult bool , useAsset bool ) chan paymentResult {
681688
682689 resultChan := make (chan paymentResult )
683690 sendResult := func (result paymentResult ) {
@@ -692,7 +699,7 @@ func (s *loopOutSwap) payInvoice(ctx context.Context, invoice string,
692699
693700 status , err := s .payInvoiceAsync (
694701 ctx , invoice , maxFee , outgoingChanIds , paymentTimeout ,
695- pluginType , reportPluginResult ,
702+ pluginType , reportPluginResult , useAsset ,
696703 )
697704 if err != nil {
698705 result .err = err
@@ -717,13 +724,64 @@ func (s *loopOutSwap) payInvoice(ctx context.Context, invoice string,
717724 return resultChan
718725}
719726
727+ func (s * loopOutSwap ) payInvoiceWithAssetClient (ctx context.Context ,
728+ invoice string ) (* lndclient.PaymentStatus , error ) {
729+
730+ totalPaymentTimeout := s .executeConfig .totalPaymentTimeout
731+
732+ sendReq := & routerrpc.SendPaymentRequest {
733+ PaymentRequest : invoice ,
734+ TimeoutSeconds : int32 (totalPaymentTimeout .Seconds ()),
735+ FeeLimitMsat : 1_000_000 ,
736+ }
737+
738+ paymentStream , err := s .assets .SendPayment (
739+ ctx , & tapchannelrpc.SendPaymentRequest {
740+ AssetId : s .AssetId ,
741+ PeerPubkey : s .AssetEdgeNode ,
742+ PaymentRequest : sendReq ,
743+ })
744+ if err != nil {
745+ return nil , err
746+ }
747+
748+ // We want to receive the accepted quote message first, so we know how
749+ // many assets we're going to pay.
750+ for {
751+ select {
752+ case <- ctx .Done ():
753+ return nil , ctx .Err ()
754+ default :
755+ msg , err := paymentStream .Recv ()
756+ if err != nil {
757+ return nil , err
758+ }
759+
760+ payRes := msg .GetPaymentResult ()
761+ if payRes == nil {
762+ continue
763+ }
764+
765+ return & lndclient.PaymentStatus {
766+ State : payRes .Status ,
767+ }, nil
768+ }
769+ }
770+ }
771+
720772// payInvoiceAsync is the asynchronously executed part of paying an invoice.
721773func (s * loopOutSwap ) payInvoiceAsync (ctx context.Context ,
722774 invoice string , maxFee btcutil.Amount ,
723775 outgoingChanIds loopdb.ChannelSet , paymentTimeout time.Duration ,
724- pluginType RoutingPluginType , reportPluginResult bool ) (
776+ pluginType RoutingPluginType , reportPluginResult bool , useAsset bool ) (
725777 * lndclient.PaymentStatus , error ) {
726778
779+ // If we want to use an asset for the payment, we need to use the asset
780+ // client.
781+ if useAsset {
782+ return s .payInvoiceWithAssetClient (ctx , invoice )
783+ }
784+
727785 // Extract hash from payment request. Unfortunately the request
728786 // components aren't available directly.
729787 chainParams := s .lnd .ChainParams
0 commit comments