@@ -5,14 +5,14 @@ import (
5
5
"context"
6
6
"crypto/rand"
7
7
"encoding/hex"
8
- "errors"
9
8
"fmt"
10
9
"time"
11
10
12
11
"github.com/lightninglabs/taproot-assets/rfq"
13
12
"github.com/lightninglabs/taproot-assets/rfqmath"
14
13
"github.com/lightninglabs/taproot-assets/rpcutils"
15
14
"github.com/lightninglabs/taproot-assets/taprpc"
15
+ "github.com/lightninglabs/taproot-assets/taprpc/rfqrpc"
16
16
tchrpc "github.com/lightninglabs/taproot-assets/taprpc/tapchannelrpc"
17
17
"github.com/lightningnetwork/lnd/cmd/commands"
18
18
"github.com/lightningnetwork/lnd/lnrpc"
@@ -210,9 +210,8 @@ var (
210
210
rfqPeerPubKeyFlag = cli.StringFlag {
211
211
Name : "rfq_peer_pubkey" ,
212
212
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" ,
216
215
}
217
216
218
217
allowOverpayFlag = cli.BoolFlag {
@@ -237,74 +236,73 @@ type resultStreamWrapper struct {
237
236
//
238
237
// NOTE: This method is part of the PaymentResultStream interface.
239
238
func (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 {
251
241
rpcRate := quote .BidAssetRate
252
242
rate , err := rpcutils .UnmarshalRfqFixedPoint (rpcRate )
253
243
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 )
256
246
}
257
247
258
248
amountMsat := lnwire .MilliSatoshi (w .amountMsat )
259
249
milliSatsFP := rfqmath .MilliSatoshiToUnits (amountMsat , * rate )
260
250
numUnits := milliSatsFP .ScaleTo (0 ).ToUint64 ()
261
-
262
- // If the calculated number of units is 0 then the asset rate
263
- // was not sufficient to represent the value of this payment.
264
- 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 )
282
- }
283
-
284
251
msatPerUnit := uint64 (w .amountMsat ) / numUnits
285
252
286
253
fmt .Printf ("Got quote for %v asset units at %v msat/unit from " +
287
- "peer %s with SCID %d\n " , numUnits , msatPerUnit ,
254
+ " peer %s with SCID %d\n " , numUnits , msatPerUnit ,
288
255
quote .Peer , quote .Scid )
289
256
290
- resp , err = w .stream .Recv ()
257
+ return nil
258
+ }
259
+
260
+ // A boolean to indicate whether the first quote was printed via the
261
+ // legacy single-rfq response field.
262
+ legacyFirstPrint := false
263
+
264
+ for {
265
+ resp , err := w .stream .Recv ()
291
266
if err != nil {
292
267
return nil , err
293
268
}
294
269
295
- if resp == nil || resp .Result == nil ||
296
- resp .GetPaymentResult () == nil {
270
+ res := resp .Result
297
271
298
- return nil , errors .New ("unexpected nil result" )
299
- }
272
+ switch r := res .(type ) {
273
+ case * tchrpc.SendPaymentResponse_AcceptedSellOrder :
274
+ err := printQuote (r .AcceptedSellOrder )
275
+ if err != nil {
276
+ return nil , err
277
+ }
300
278
301
- return resp . GetPaymentResult (), nil
279
+ legacyFirstPrint = true
302
280
303
- case * tchrpc.SendPaymentResponse_PaymentResult :
304
- return r . PaymentResult , nil
281
+ case * tchrpc.SendPaymentResponse_AcceptedSellOrders :
282
+ quotes := r . AcceptedSellOrders . AcceptedSellOrders
305
283
306
- default :
307
- return nil , fmt .Errorf ("unexpected response type: %T" , r )
284
+ for _ , quote := range quotes {
285
+ // If the first item was returned via the legacy
286
+ // field then skip printing it again here. This
287
+ // skip only applies to the first element.
288
+ if legacyFirstPrint {
289
+ legacyFirstPrint = false
290
+ continue
291
+ }
292
+
293
+ err := printQuote (quote )
294
+ if err != nil {
295
+ return nil , err
296
+ }
297
+ }
298
+
299
+ case * tchrpc.SendPaymentResponse_PaymentResult :
300
+ return r .PaymentResult , nil
301
+
302
+ default :
303
+ return nil , fmt .Errorf ("unexpected response type: %T" ,
304
+ r )
305
+ }
308
306
}
309
307
}
310
308
0 commit comments