@@ -5,14 +5,14 @@ import (
55	"context" 
66	"crypto/rand" 
77	"encoding/hex" 
8- 	"errors" 
98	"fmt" 
109	"time" 
1110
1211	"github.com/lightninglabs/taproot-assets/rfq" 
1312	"github.com/lightninglabs/taproot-assets/rfqmath" 
1413	"github.com/lightninglabs/taproot-assets/rpcutils" 
1514	"github.com/lightninglabs/taproot-assets/taprpc" 
15+ 	"github.com/lightninglabs/taproot-assets/taprpc/rfqrpc" 
1616	tchrpc "github.com/lightninglabs/taproot-assets/taprpc/tapchannelrpc" 
1717	"github.com/lightningnetwork/lnd/cmd/commands" 
1818	"github.com/lightningnetwork/lnd/lnrpc" 
@@ -210,9 +210,8 @@ var (
210210	rfqPeerPubKeyFlag  =  cli.StringFlag {
211211		Name : "rfq_peer_pubkey" ,
212212		Usage : "(optional) the public key of the peer to ask for a "  + 
213- 			"quote when converting from assets to sats; must be "  + 
214- 			"set if there are multiple channels with the same "  + 
215- 			"asset ID present" ,
213+ 			"quote when converting from assets to sats; if left "  + 
214+ 			"unset then rfq peers will be picked automatically" ,
216215	}
217216
218217	allowOverpayFlag  =  cli.BoolFlag {
@@ -237,74 +236,80 @@ type resultStreamWrapper struct {
237236// 
238237// NOTE: This method is part of the PaymentResultStream interface. 
239238func  (w  * resultStreamWrapper ) Recv () (* lnrpc.Payment , error ) {
240- 	resp , err  :=  w .stream .Recv ()
241- 	if  err  !=  nil  {
242- 		return  nil , err 
243- 	}
244- 
245- 	res  :=  resp .Result 
246- 	switch  r  :=  res .(type ) {
247- 	// The very first response might be an accepted sell order, which we 
248- 	// just print out. 
249- 	case  * tchrpc.SendPaymentResponse_AcceptedSellOrder :
250- 		quote  :=  r .AcceptedSellOrder 
239+ 	// printQuote unmarshals and prints an accepted quote. 
240+ 	printQuote  :=  func (quote  * rfqrpc.PeerAcceptedSellQuote ) error  {
251241		rpcRate  :=  quote .BidAssetRate 
252242		rate , err  :=  rpcutils .UnmarshalRfqFixedPoint (rpcRate )
253243		if  err  !=  nil  {
254- 			return  nil ,  fmt .Errorf ("unable to unmarshal fixed "  + 
255- 				"point: %w" ,  err )
244+ 			return  fmt .Errorf ("unable to unmarshal fixed point: %w"  , 
245+ 				err )
256246		}
257247
258248		amountMsat  :=  lnwire .MilliSatoshi (w .amountMsat )
259249		milliSatsFP  :=  rfqmath .MilliSatoshiToUnits (amountMsat , * rate )
260250		numUnits  :=  milliSatsFP .ScaleTo (0 ).ToUint64 ()
261251
262- 		// If the calculated number  of units  is 0 then the asset rate  
263- 		// was not sufficient to represent the value of this payment . 
252+ 		// The purpose  of this function  is just to print, so let's avoid  
253+ 		// dividing by zero or reporting an invalid msat/unit rate . 
264254		if  numUnits  ==  0  {
265- 			// We will calculate the minimum amount that can be 
266- 			// effectively sent with this asset by calculating the 
267- 			// value of a single asset unit, based on the provided 
268- 			// asset rate. 
269- 
270- 			// We create the single unit. 
271- 			unit  :=  rfqmath .FixedPointFromUint64 [rfqmath.BigInt ](
272- 				1 , 0 ,
273- 			)
274- 
275- 			// We derive the minimum amount. 
276- 			minAmt  :=  rfqmath .UnitsToMilliSatoshi (unit , * rate )
277- 
278- 			// We return the error to the user. 
279- 			return  nil , fmt .Errorf ("smallest payment with asset " + 
280- 				"rate %v is %v, cannot send %v" ,
281- 				rate .ToUint64 (), minAmt , amountMsat )
255+ 			return  nil 
282256		}
283257
284258		msatPerUnit  :=  uint64 (w .amountMsat ) /  numUnits 
285259
286260		fmt .Printf ("Got quote for %v asset units at %v msat/unit from " + 
287- 			"peer %s with SCID %d\n " , numUnits , msatPerUnit ,
261+ 			"  peer %s with SCID %d\n " , numUnits , msatPerUnit ,
288262			quote .Peer , quote .Scid )
289263
290- 		resp , err  =  w .stream .Recv ()
264+ 		return  nil 
265+ 	}
266+ 
267+ 	// A boolean to indicate whether the first quote was printed via the 
268+ 	// legacy single-rfq response field. 
269+ 	legacyFirstPrint  :=  false 
270+ 
271+ 	for  {
272+ 		resp , err  :=  w .stream .Recv ()
291273		if  err  !=  nil  {
292274			return  nil , err 
293275		}
294276
295- 		if  resp  ==  nil  ||  resp .Result  ==  nil  || 
296- 			resp .GetPaymentResult () ==  nil  {
277+ 		res  :=  resp .Result 
297278
298- 			return  nil , errors .New ("unexpected nil result" )
299- 		}
279+ 		switch  r  :=  res .(type ) {
280+ 		case  * tchrpc.SendPaymentResponse_AcceptedSellOrder :
281+ 			err  :=  printQuote (r .AcceptedSellOrder )
282+ 			if  err  !=  nil  {
283+ 				return  nil , err 
284+ 			}
300285
301- 		return   resp . GetPaymentResult (),  nil 
286+ 			 legacyFirstPrint   =   true 
302287
303- 	case  * tchrpc.SendPaymentResponse_PaymentResult :
304- 		return   r . PaymentResult ,  nil 
288+ 		 case  * tchrpc.SendPaymentResponse_AcceptedSellOrders :
289+ 			 quotes   :=   r . AcceptedSellOrders . AcceptedSellOrders 
305290
306- 	default :
307- 		return  nil , fmt .Errorf ("unexpected response type: %T" , r )
291+ 			for  _ , quote  :=  range  quotes  {
292+ 				// If the first item was returned via the legacy 
293+ 				// field then skip printing it again here. This 
294+ 				// skip only applies to the first element. 
295+ 				if  legacyFirstPrint  {
296+ 					legacyFirstPrint  =  false 
297+ 					continue 
298+ 				}
299+ 
300+ 				err  :=  printQuote (quote )
301+ 				if  err  !=  nil  {
302+ 					return  nil , err 
303+ 				}
304+ 			}
305+ 
306+ 		case  * tchrpc.SendPaymentResponse_PaymentResult :
307+ 			return  r .PaymentResult , nil 
308+ 
309+ 		default :
310+ 			return  nil , fmt .Errorf ("unexpected response type: %T" ,
311+ 				r )
312+ 		}
308313	}
309314}
310315
0 commit comments