Skip to content

Commit 95aae0e

Browse files
committed
loopout/asset: add asset rate
1 parent fddad8a commit 95aae0e

File tree

6 files changed

+632
-380
lines changed

6 files changed

+632
-380
lines changed

client.go

Lines changed: 77 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"github.com/lightninglabs/loop/sweep"
2121
"github.com/lightninglabs/loop/sweepbatcher"
2222
"github.com/lightninglabs/loop/utils"
23+
"github.com/lightninglabs/taproot-assets/taprpc/rfqrpc"
2324
"github.com/lightningnetwork/lnd/lntypes"
2425
"github.com/lightningnetwork/lnd/routing/route"
2526
"google.golang.org/grpc"
@@ -661,54 +662,12 @@ func (s *Client) LoopOutQuote(ctx context.Context,
661662
// If we use an Asset we'll rfq to get the asset amounts to use for
662663
// the swap.
663664
if request.AssetRFQRequest != nil {
664-
rfqReq := request.AssetRFQRequest
665-
if rfqReq.Expiry == 0 {
666-
rfqReq.Expiry = time.Now().Add(defaultRFQExpiry).Unix()
667-
}
668-
669-
if rfqReq.MaxLimitMultiplier == 0 {
670-
rfqReq.MaxLimitMultiplier = defaultRFQMaxLimitMultiplier
671-
}
672-
673-
// First we'll get the prepay rfq.
674-
prepayRfq, err := s.assetClient.GetRfqForAsset(
675-
ctx, quote.PrepayAmount, rfqReq.AssetId,
676-
rfqReq.AssetEdgeNode, rfqReq.Expiry,
677-
rfqReq.MaxLimitMultiplier,
678-
)
679-
if err != nil {
680-
return nil, err
681-
}
682-
683-
// The actual invoice swap amount is the requested amount plus
684-
// the swap fee minus the prepay amount.
685-
invoiceAmt := request.Amount + quote.SwapFee -
686-
quote.PrepayAmount
687-
688-
swapRfq, err := s.assetClient.GetRfqForAsset(
689-
ctx, invoiceAmt, rfqReq.AssetId,
690-
rfqReq.AssetEdgeNode, rfqReq.Expiry,
691-
rfqReq.MaxLimitMultiplier,
692-
)
665+
rfq, err := s.getAssetRfq(ctx, loopOutQuote, request)
693666
if err != nil {
694667
return nil, err
695668
}
696669

697-
// We'll also want the asset name to verify for the client.
698-
assetName, err := s.assetClient.GetAssetName(
699-
ctx, rfqReq.AssetId,
700-
)
701-
if err != nil {
702-
return nil, err
703-
}
704-
705-
loopOutQuote.LoopOutRfq = &LoopOutRfq{
706-
PrepayRfqId: prepayRfq.Id,
707-
MaxPrepayAssetAmt: prepayRfq.AssetAmount,
708-
SwapRfqId: swapRfq.Id,
709-
MaxSwapAssetAmt: swapRfq.AssetAmount,
710-
AssetName: assetName,
711-
}
670+
loopOutQuote.LoopOutRfq = rfq
712671
}
713672

714673
return loopOutQuote, nil
@@ -1000,3 +959,77 @@ func (s *Client) AbandonSwap(ctx context.Context,
1000959

1001960
return nil
1002961
}
962+
963+
// getAssetRfq returns a prepay and swap rfq for the asset swap.
964+
func (s *Client) getAssetRfq(ctx context.Context, quote *LoopOutQuote,
965+
request *LoopOutQuoteRequest) (*LoopOutRfq, error) {
966+
967+
if s.assetClient == nil {
968+
return nil, errors.New("asset client must be set " +
969+
"when trying to loop out with an asset")
970+
}
971+
rfqReq := request.AssetRFQRequest
972+
if rfqReq.Expiry == 0 {
973+
rfqReq.Expiry = time.Now().Add(defaultRFQExpiry).Unix()
974+
}
975+
976+
if rfqReq.MaxLimitMultiplier == 0 {
977+
rfqReq.MaxLimitMultiplier = defaultRFQMaxLimitMultiplier
978+
}
979+
980+
// First we'll get the prepay rfq.
981+
prepayRfq, err := s.assetClient.GetRfqForAsset(
982+
ctx, quote.PrepayAmount, rfqReq.AssetId,
983+
rfqReq.AssetEdgeNode, rfqReq.Expiry,
984+
rfqReq.MaxLimitMultiplier,
985+
)
986+
if err != nil {
987+
return nil, err
988+
}
989+
990+
prepayAssetRate, err := rfqrpc.UnmarshalFixedPoint(
991+
prepayRfq.BidAssetRate,
992+
)
993+
if err != nil {
994+
return nil, err
995+
}
996+
997+
// The actual invoice swap amount is the requested amount plus
998+
// the swap fee minus the prepay amount.
999+
invoiceAmt := request.Amount + quote.SwapFee -
1000+
quote.PrepayAmount
1001+
1002+
swapRfq, err := s.assetClient.GetRfqForAsset(
1003+
ctx, invoiceAmt, rfqReq.AssetId,
1004+
rfqReq.AssetEdgeNode, rfqReq.Expiry,
1005+
rfqReq.MaxLimitMultiplier,
1006+
)
1007+
if err != nil {
1008+
return nil, err
1009+
}
1010+
1011+
swapAssetRate, err := rfqrpc.UnmarshalFixedPoint(
1012+
swapRfq.BidAssetRate,
1013+
)
1014+
if err != nil {
1015+
return nil, err
1016+
}
1017+
1018+
// We'll also want the asset name to verify for the client.
1019+
assetName, err := s.assetClient.GetAssetName(
1020+
ctx, rfqReq.AssetId,
1021+
)
1022+
if err != nil {
1023+
return nil, err
1024+
}
1025+
1026+
return &LoopOutRfq{
1027+
PrepayRfqId: prepayRfq.Id,
1028+
MaxPrepayAssetAmt: prepayRfq.AssetAmount,
1029+
PrepayAssetRate: prepayAssetRate,
1030+
SwapRfqId: swapRfq.Id,
1031+
MaxSwapAssetAmt: swapRfq.AssetAmount,
1032+
SwapAssetRate: swapAssetRate,
1033+
AssetName: assetName,
1034+
}, nil
1035+
}

interface.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"github.com/btcsuite/btcd/btcutil"
77
"github.com/lightninglabs/loop/loopdb"
88
"github.com/lightninglabs/loop/swap"
9+
"github.com/lightninglabs/taproot-assets/rfqmath"
910
"github.com/lightningnetwork/lnd/lntypes"
1011
"github.com/lightningnetwork/lnd/routing/route"
1112
"github.com/lightningnetwork/lnd/zpay32"
@@ -228,13 +229,20 @@ type LoopOutRfq struct {
228229
// used to pay for the prepay invoice.
229230
MaxPrepayAssetAmt uint64
230231

232+
// PrepayAssetRate is the rate at which the asset is exchanged for
233+
// bitcoin.
234+
PrepayAssetRate *rfqmath.BigIntFixedPoint
235+
231236
// SwapRfqId is the ID of the swap RFQ.
232237
SwapRfqId []byte
233238

234239
// MaxSwapAssetAmt is the maximum amount of the asset that will be used
235240
// to pay for the swap invoice.
236241
MaxSwapAssetAmt uint64
237242

243+
// SwapAssetRate is the rate at which the asset is exchanged for bitcoin.
244+
SwapAssetRate *rfqmath.BigIntFixedPoint
245+
238246
// AssetName is the human readable name of the asset.
239247
AssetName string
240248
}

loopd/swapclient_server.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import (
3333
"github.com/lightninglabs/loop/staticaddr/withdraw"
3434
"github.com/lightninglabs/loop/swap"
3535
"github.com/lightninglabs/loop/swapserverrpc"
36+
"github.com/lightninglabs/taproot-assets/rfqmath"
3637
"github.com/lightningnetwork/lnd/lnrpc/walletrpc"
3738
"github.com/lightningnetwork/lnd/lntypes"
3839
"github.com/lightningnetwork/lnd/queue"
@@ -804,8 +805,14 @@ func (s *swapClientServer) LoopOutQuote(ctx context.Context,
804805
response.AssetRfqInfo = &looprpc.AssetRfqInfo{
805806
PrepayRfqId: quote.LoopOutRfq.PrepayRfqId,
806807
MaxPrepayAssetAmt: quote.LoopOutRfq.MaxPrepayAssetAmt,
808+
PrepayAssetRate: marshalFixedPoint(
809+
quote.LoopOutRfq.PrepayAssetRate,
810+
),
807811
SwapRfqId: quote.LoopOutRfq.SwapRfqId,
808812
MaxSwapAssetAmt: quote.LoopOutRfq.MaxSwapAssetAmt,
813+
SwapAssetRate: marshalFixedPoint(
814+
quote.LoopOutRfq.SwapAssetRate,
815+
),
809816
AssetName: quote.LoopOutRfq.AssetName,
810817
}
811818
}
@@ -2319,3 +2326,14 @@ func toClientReservation(
23192326
Expiry: res.Expiry,
23202327
}
23212328
}
2329+
2330+
// marshalFixedpoint marshals a fixed point from the tap rfqmath package to the
2331+
// looprpc package.
2332+
func marshalFixedPoint(bigIntFixedPoint *rfqmath.BigIntFixedPoint,
2333+
) *looprpc.FixedPoint {
2334+
2335+
return &looprpc.FixedPoint{
2336+
Coefficient: bigIntFixedPoint.Coefficient.String(),
2337+
Scale: uint32(bigIntFixedPoint.Scale),
2338+
}
2339+
}

0 commit comments

Comments
 (0)