@@ -377,7 +377,7 @@ func testCustomChannels(_ context.Context, net *NetworkHarness,
377377 // Test case 1: Send a direct keysend payment from Charlie to Dave.
378378 // ------------
379379 const keySendAmount = 100
380- sendKeySendPayment (t .t , charlie , dave , keySendAmount , assetID )
380+ sendAssetKeySendPayment (t .t , charlie , dave , keySendAmount , assetID )
381381 logBalance (t .t , nodes , assetID , "after keysend" )
382382
383383 charlieAssetBalance -= keySendAmount
@@ -386,12 +386,16 @@ func testCustomChannels(_ context.Context, net *NetworkHarness,
386386 // We should be able to send the 100 assets back immediately, because
387387 // there is enough on-chain balance on Dave's side to be able to create
388388 // an HTLC.
389- sendKeySendPayment (t .t , dave , charlie , keySendAmount , assetID )
389+ sendAssetKeySendPayment (t .t , dave , charlie , keySendAmount , assetID )
390390 logBalance (t .t , nodes , assetID , "after keysend back" )
391391
392392 charlieAssetBalance += keySendAmount
393393 daveAssetBalance -= keySendAmount
394394
395+ // We should also be able to do a non-asset (BTC only) keysend payment.
396+ sendKeySendPayment (t .t , charlie , dave , 2000 , nil )
397+ logBalance (t .t , nodes , assetID , "after BTC only keysend" )
398+
395399 // ------------
396400 // Test case 2: Pay a normal invoice from Dave by Charlie, making it
397401 // a direct channel invoice payment with no RFQ SCID present in the
@@ -405,6 +409,11 @@ func testCustomChannels(_ context.Context, net *NetworkHarness,
405409 charlieAssetBalance -= paidAssetAmount
406410 daveAssetBalance += paidAssetAmount
407411
412+ // We should also be able to do a multi-hop BTC only payment, paying an
413+ // invoice from Erin by Charlie.
414+ createAndPayNormalInvoiceWithBtc (t .t , charlie , erin , 2000 )
415+ logBalance (t .t , nodes , assetID , "after BTC only invoice" )
416+
408417 // ------------
409418 // Test case 3: Pay an asset invoice from Dave by Charlie, making it
410419 // a direct channel invoice payment with an RFQ SCID present in the
@@ -861,7 +870,7 @@ func getAssetChannelBalance(t *testing.T, node *HarnessNode, assetID []byte,
861870 return localSum , remoteSum
862871}
863872
864- func sendKeySendPayment (t * testing.T , src , dst * HarnessNode , amt uint64 ,
873+ func sendAssetKeySendPayment (t * testing.T , src , dst * HarnessNode , amt uint64 ,
865874 assetID []byte ) {
866875
867876 ctxb := context .Background ()
@@ -886,9 +895,22 @@ func sendKeySendPayment(t *testing.T, src, dst *HarnessNode, amt uint64,
886895 )
887896 require .NoError (t , err )
888897
898+ const htlcCarrierAmt = 500
899+ sendKeySendPayment (
900+ t , src , dst , htlcCarrierAmt , encodeResp .CustomRecords ,
901+ )
902+ }
903+
904+ func sendKeySendPayment (t * testing.T , src , dst * HarnessNode , amt btcutil.Amount ,
905+ firstHopCustomRecords map [uint64 ][]byte ) {
906+
907+ ctxb := context .Background ()
908+ ctxt , cancel := context .WithTimeout (ctxb , defaultTimeout )
909+ defer cancel ()
910+
889911 // Read out the custom preimage for the keysend payment.
890912 var preimage lntypes.Preimage
891- _ , err = rand .Read (preimage [:])
913+ _ , err : = rand .Read (preimage [:])
892914 require .NoError (t , err )
893915
894916 hash := preimage .Hash ()
@@ -898,12 +920,11 @@ func sendKeySendPayment(t *testing.T, src, dst *HarnessNode, amt uint64,
898920 customRecords := make (map [uint64 ][]byte )
899921 customRecords [record .KeySendType ] = preimage [:]
900922
901- const htlcCarrierAmt = 500
902923 req := & routerrpc.SendPaymentRequest {
903924 Dest : dst .PubKey [:],
904- Amt : htlcCarrierAmt ,
925+ Amt : int64 ( amt ) ,
905926 DestCustomRecords : customRecords ,
906- FirstHopCustomRecords : encodeResp . CustomRecords ,
927+ FirstHopCustomRecords : firstHopCustomRecords ,
907928 PaymentHash : hash [:],
908929 TimeoutSeconds : 3 ,
909930 }
@@ -918,6 +939,24 @@ func sendKeySendPayment(t *testing.T, src, dst *HarnessNode, amt uint64,
918939 require .Equal (t , lnrpc .Payment_SUCCEEDED , result .Status )
919940}
920941
942+ func createAndPayNormalInvoiceWithBtc (t * testing.T , src , dst * HarnessNode ,
943+ amountSat btcutil.Amount ) {
944+
945+ ctxb := context .Background ()
946+ ctxt , cancel := context .WithTimeout (ctxb , defaultTimeout )
947+ defer cancel ()
948+
949+ expirySeconds := 10
950+ invoiceResp , err := dst .AddInvoice (ctxt , & lnrpc.Invoice {
951+ Value : int64 (amountSat ),
952+ Memo : "normal invoice" ,
953+ Expiry : int64 (expirySeconds ),
954+ })
955+ require .NoError (t , err )
956+
957+ payInvoiceWithSatoshi (t , src , invoiceResp )
958+ }
959+
921960func createAndPayNormalInvoice (t * testing.T , src , rfqPeer , dst * HarnessNode ,
922961 amountSat btcutil.Amount , assetID []byte ) uint64 {
923962
0 commit comments