Skip to content

Commit 674cb93

Browse files
committed
litcli: update payinvoice for multirfq
1 parent 91bc1ac commit 674cb93

File tree

1 file changed

+49
-51
lines changed

1 file changed

+49
-51
lines changed

cmd/litcli/ln.go

Lines changed: 49 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -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,73 @@ type resultStreamWrapper struct {
237236
//
238237
// NOTE: This method is part of the PaymentResultStream interface.
239238
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 {
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()
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-
284251
msatPerUnit := uint64(w.amountMsat) / numUnits
285252

286253
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,
288255
quote.Peer, quote.Scid)
289256

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()
291266
if err != nil {
292267
return nil, err
293268
}
294269

295-
if resp == nil || resp.Result == nil ||
296-
resp.GetPaymentResult() == nil {
270+
res := resp.Result
297271

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+
}
300278

301-
return resp.GetPaymentResult(), nil
279+
legacyFirstPrint = true
302280

303-
case *tchrpc.SendPaymentResponse_PaymentResult:
304-
return r.PaymentResult, nil
281+
case *tchrpc.SendPaymentResponse_AcceptedSellOrders:
282+
quotes := r.AcceptedSellOrders.AcceptedSellOrders
305283

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+
}
308306
}
309307
}
310308

0 commit comments

Comments
 (0)