@@ -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,48 +236,21 @@ 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.
264252 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 )
253+ return nil
282254 }
283255
284256 msatPerUnit := uint64 (w .amountMsat ) / numUnits
@@ -287,24 +259,55 @@ func (w *resultStreamWrapper) Recv() (*lnrpc.Payment, error) {
287259 "peer %s with SCID %d\n " , numUnits , msatPerUnit ,
288260 quote .Peer , quote .Scid )
289261
290- resp , err = w .stream .Recv ()
262+ return nil
263+ }
264+
265+ // A boolean to indicate whether the first quote was printed via the
266+ // legacy single-rfq response field.
267+ legacyFirstPrint := false
268+
269+ for {
270+ resp , err := w .stream .Recv ()
291271 if err != nil {
292272 return nil , err
293273 }
294274
295- if resp == nil || resp .Result == nil ||
296- resp .GetPaymentResult () == nil {
275+ res := resp .Result
297276
298- return nil , errors .New ("unexpected nil result" )
299- }
277+ switch r := res .(type ) {
278+ case * tchrpc.SendPaymentResponse_AcceptedSellOrder :
279+ err := printQuote (r .AcceptedSellOrder )
280+ if err != nil {
281+ return nil , err
282+ }
300283
301- return resp . GetPaymentResult (), nil
284+ legacyFirstPrint = true
302285
303- case * tchrpc.SendPaymentResponse_PaymentResult :
304- return r . PaymentResult , nil
286+ case * tchrpc.SendPaymentResponse_AcceptedSellOrders :
287+ quotes := r . AcceptedSellOrders . AcceptedSellOrders
305288
306- default :
307- return nil , fmt .Errorf ("unexpected response type: %T" , r )
289+ for _ , quote := range quotes {
290+ // If the first item was returned via the legacy
291+ // field then skip printing it again here. This
292+ // skip only applies to the first element.
293+ if legacyFirstPrint {
294+ legacyFirstPrint = false
295+ continue
296+ }
297+
298+ err := printQuote (quote )
299+ if err != nil {
300+ return nil , err
301+ }
302+ }
303+
304+ case * tchrpc.SendPaymentResponse_PaymentResult :
305+ return r .PaymentResult , nil
306+
307+ default :
308+ return nil , fmt .Errorf ("unexpected response type: %T" ,
309+ r )
310+ }
308311 }
309312}
310313
0 commit comments