Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 52 additions & 47 deletions cmd/litcli/ln.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ import (
"context"
"crypto/rand"
"encoding/hex"
"errors"
"fmt"
"time"

"github.com/lightninglabs/taproot-assets/rfq"
"github.com/lightninglabs/taproot-assets/rfqmath"
"github.com/lightninglabs/taproot-assets/rpcutils"
"github.com/lightninglabs/taproot-assets/taprpc"
"github.com/lightninglabs/taproot-assets/taprpc/rfqrpc"
tchrpc "github.com/lightninglabs/taproot-assets/taprpc/tapchannelrpc"
"github.com/lightningnetwork/lnd/cmd/commands"
"github.com/lightningnetwork/lnd/lnrpc"
Expand Down Expand Up @@ -210,9 +210,8 @@ var (
rfqPeerPubKeyFlag = cli.StringFlag{
Name: "rfq_peer_pubkey",
Usage: "(optional) the public key of the peer to ask for a " +
"quote when converting from assets to sats; must be " +
"set if there are multiple channels with the same " +
"asset ID present",
"quote when converting from assets to sats; if left " +
"unset then rfq peers will be picked automatically",
}

allowOverpayFlag = cli.BoolFlag{
Expand All @@ -237,74 +236,80 @@ type resultStreamWrapper struct {
//
// NOTE: This method is part of the PaymentResultStream interface.
func (w *resultStreamWrapper) Recv() (*lnrpc.Payment, error) {
resp, err := w.stream.Recv()
if err != nil {
return nil, err
}

res := resp.Result
switch r := res.(type) {
// The very first response might be an accepted sell order, which we
// just print out.
case *tchrpc.SendPaymentResponse_AcceptedSellOrder:
quote := r.AcceptedSellOrder
// printQuote unmarshals and prints an accepted quote.
printQuote := func(quote *rfqrpc.PeerAcceptedSellQuote) error {
rpcRate := quote.BidAssetRate
rate, err := rpcutils.UnmarshalRfqFixedPoint(rpcRate)
if err != nil {
return nil, fmt.Errorf("unable to unmarshal fixed "+
"point: %w", err)
return fmt.Errorf("unable to unmarshal fixed point: %w",
err)
}

amountMsat := lnwire.MilliSatoshi(w.amountMsat)
milliSatsFP := rfqmath.MilliSatoshiToUnits(amountMsat, *rate)
numUnits := milliSatsFP.ScaleTo(0).ToUint64()

// If the calculated number of units is 0 then the asset rate
// was not sufficient to represent the value of this payment.
// The purpose of this function is just to print, so let's avoid

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should not be a comment in the code (since it references deleted code), it's more like a remark on the PR or a commit description.

// dividing by zero or reporting an invalid msat/unit rate.
if numUnits == 0 {
// We will calculate the minimum amount that can be
// effectively sent with this asset by calculating the
// value of a single asset unit, based on the provided
// asset rate.

// We create the single unit.
unit := rfqmath.FixedPointFromUint64[rfqmath.BigInt](
1, 0,
)

// We derive the minimum amount.
minAmt := rfqmath.UnitsToMilliSatoshi(unit, *rate)

// We return the error to the user.
return nil, fmt.Errorf("smallest payment with asset "+
"rate %v is %v, cannot send %v",
rate.ToUint64(), minAmt, amountMsat)
return nil
}

msatPerUnit := uint64(w.amountMsat) / numUnits

fmt.Printf("Got quote for %v asset units at %v msat/unit from "+
"peer %s with SCID %d\n", numUnits, msatPerUnit,
" peer %s with SCID %d\n", numUnits, msatPerUnit,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

double space?

Suggested change
" peer %s with SCID %d\n", numUnits, msatPerUnit,
"peer %s with SCID %d\n", numUnits, msatPerUnit,

quote.Peer, quote.Scid)

resp, err = w.stream.Recv()
return nil
}

// A boolean to indicate whether the first quote was printed via the
// legacy single-rfq response field.
legacyFirstPrint := false

for {
resp, err := w.stream.Recv()
if err != nil {
return nil, err
}

if resp == nil || resp.Result == nil ||
resp.GetPaymentResult() == nil {
res := resp.Result

return nil, errors.New("unexpected nil result")
}
switch r := res.(type) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Switching over type feels strange to me but I have little context on litd.
I'm surprised we need to differentiate between deprecated AcceptSellOrder and the new AcceptedSellOrders. If the litd version supporting multi-rfq is released after the tapd version that adds the new AcceptedSellOrders, it seems reasonable that litd should simply not support the deprecated type. This is backwards compatibility squared.

Otherwise might be worth adding a comment explaining when the support for legacy can be dropped because there is no direct correlation between dropping support in tapd and litd.

case *tchrpc.SendPaymentResponse_AcceptedSellOrder:
err := printQuote(r.AcceptedSellOrder)
if err != nil {
return nil, err
}

return resp.GetPaymentResult(), nil
legacyFirstPrint = true

case *tchrpc.SendPaymentResponse_PaymentResult:
return r.PaymentResult, nil
case *tchrpc.SendPaymentResponse_AcceptedSellOrders:
quotes := r.AcceptedSellOrders.AcceptedSellOrders

default:
return nil, fmt.Errorf("unexpected response type: %T", r)
for _, quote := range quotes {
// If the first item was returned via the legacy
// field then skip printing it again here. This
// skip only applies to the first element.
if legacyFirstPrint {
legacyFirstPrint = false
continue
}

err := printQuote(quote)
if err != nil {
return nil, err
}
}

case *tchrpc.SendPaymentResponse_PaymentResult:
return r.PaymentResult, nil

default:
return nil, fmt.Errorf("unexpected response type: %T",
r)
}
}
}

Expand Down
4 changes: 4 additions & 0 deletions docs/release-notes/release-notes-0.16.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@
### Technical and Architectural Updates

## RPC Updates
- [Updated litcli](https://github.com/lightninglabs/lightning-terminal/pull/1125)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The actual impact in litcli could be clearer? Like:

"rfq_peer_pubkey is now optional in all contexts"

or something.

to support sending an asset payment without specifying a single peer. This will
use the new multi-rfq feature of taproot-assets which will automatically pick
the rfq peers for you.

## Integrated Binary Updates

Expand Down
Loading