Skip to content

Commit a256b83

Browse files
committed
loopout: add asset id and edge node
1 parent 5bcdeb0 commit a256b83

File tree

5 files changed

+101
-3
lines changed

5 files changed

+101
-3
lines changed

client.go

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,29 @@ func (s *Client) resumeSwaps(ctx context.Context,
506506
func (s *Client) LoopOut(globalCtx context.Context,
507507
request *OutRequest) (*LoopOutSwapInfo, error) {
508508

509+
if request.AssetId != nil {
510+
rfq, err := s.assetClient.GetRfqForAsset(
511+
globalCtx, request.AssetAmount, request.AssetId,
512+
request.AssetEdgeNode,
513+
)
514+
if err != nil {
515+
return nil, err
516+
}
517+
518+
satAmt, err := assets.GetSatAmtFromRfq(
519+
request.AssetAmount, rfq.BidAssetRate,
520+
)
521+
if err != nil {
522+
return nil, err
523+
}
524+
525+
log.Infof("LoopOut %v to %v (channels: %v) with asset %x",
526+
satAmt, request.DestAddr, request.OutgoingChanSet,
527+
request.AssetId,
528+
)
529+
request.Amount = satAmt
530+
}
531+
509532
log.Infof("LoopOut %v to %v (channels: %v)",
510533
request.Amount, request.DestAddr, request.OutgoingChanSet,
511534
)
@@ -530,6 +553,13 @@ func (s *Client) LoopOut(globalCtx context.Context,
530553

531554
// Create a new swap object for this swap.
532555
swapCfg := newSwapConfig(s.lndServices, s.Store, s.Server, s.assetClient)
556+
557+
// Verify that if we have an asset id set, we have a valid asset client
558+
// to use.
559+
if request.AssetId != nil && s.assetClient == nil {
560+
return nil, errors.New("asset id set but no asset client provided")
561+
}
562+
533563
initResult, err := newLoopOutSwap(
534564
globalCtx, swapCfg, initiationHeight, request,
535565
)
@@ -579,11 +609,31 @@ func (s *Client) LoopOutQuote(ctx context.Context,
579609
return nil, err
580610
}
581611

582-
if request.Amount < terms.MinSwapAmount {
612+
satAmount := request.Amount
613+
// If we use an Asset we'll rfq to check if the sat amount meets the
614+
// min swap amount criteria.
615+
if request.AssetId != nil {
616+
rfq, err := s.assetClient.GetRfqForAsset(
617+
ctx, request.Amount, request.AssetId,
618+
request.PeerPubkey,
619+
)
620+
if err != nil {
621+
return nil, err
622+
}
623+
624+
satAmount, err = assets.GetSatAmtFromRfq(
625+
request.Amount, rfq.BidAssetRate,
626+
)
627+
if err != nil {
628+
return nil, err
629+
}
630+
}
631+
632+
if satAmount < terms.MinSwapAmount {
583633
return nil, ErrSwapAmountTooLow
584634
}
585635

586-
if request.Amount > terms.MaxSwapAmount {
636+
if satAmount > terms.MaxSwapAmount {
587637
return nil, ErrSwapAmountTooHigh
588638
}
589639

@@ -594,7 +644,7 @@ func (s *Client) LoopOutQuote(ctx context.Context,
594644
}
595645

596646
quote, err := s.Server.GetLoopOutQuote(
597-
ctx, request.Amount, expiry, request.SwapPublicationDeadline,
647+
ctx, satAmount, expiry, request.SwapPublicationDeadline,
598648
request.Initiator,
599649
)
600650
if err != nil {
@@ -613,6 +663,7 @@ func (s *Client) LoopOutQuote(ctx context.Context,
613663
MinerFee: minerFee,
614664
PrepayAmount: quote.PrepayAmount,
615665
SwapPaymentDest: quote.SwapPaymentDest,
666+
InvoiceAmtSat: satAmount,
616667
}, nil
617668
}
618669

interface.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,20 @@ type OutRequest struct {
9898
// the configured maximum payment timeout) the total time spent may be
9999
// a multiple of this value.
100100
PaymentTimeout time.Duration
101+
102+
// AssetId is an optional asset id that can be used to specify the asset
103+
// that will be used to pay for the swap. If this is set, a connection
104+
// to a tapd server is required to pay for the asset.
105+
AssetId []byte
106+
107+
// AssetEdgeNode is an optional Parameter that is required should the
108+
// tapd server have multiple channels with different peers for the given
109+
// asset id.
110+
AssetEdgeNode []byte
111+
112+
// AssetAmount is the amount of the asset that will be used to pay for
113+
// the swap. This is only set if the asset id is set.
114+
AssetAmount btcutil.Amount
101115
}
102116

103117
// Out contains the full details of a loop out request. This includes things
@@ -145,6 +159,12 @@ type LoopOutQuoteRequest struct {
145159
// initiated the swap (loop CLI, autolooper, LiT UI and so on) and is
146160
// appended to the user agent string.
147161
Initiator string
162+
163+
// AssetId is the asset that we'll quote for.
164+
AssetId []byte
165+
166+
// PeerPubkey is the pubkey of the peer that we'll quote for.
167+
PeerPubkey []byte
148168
}
149169

150170
// LoopOutTerms are the server terms on which it executes swaps.
@@ -181,6 +201,9 @@ type LoopOutQuote struct {
181201
// SwapPaymentDest is the node pubkey where to swap payment needs to be
182202
// sent to.
183203
SwapPaymentDest [33]byte
204+
205+
// InvoiceAmtSat is the amount of the invoice in satoshis.
206+
InvoiceAmtSat btcutil.Amount
184207
}
185208

186209
// LoopInRequest contains the required parameters for the swap.

loopd/swapclient_server.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,18 @@ func (s *swapClientServer) LoopOut(ctx context.Context,
208208
PaymentTimeout: paymentTimeout,
209209
}
210210

211+
// If the asset id is set, we need to set the asset amount and asset id
212+
// in the request.
213+
if in.AssetId != nil {
214+
req.AssetAmount = btcutil.Amount(in.Amt)
215+
req.AssetId = in.AssetId
216+
req.AssetEdgeNode = in.AssetEdgeNode
217+
218+
// We'll set the sat amount to zero, as this gets set later
219+
// when we calculate the total amount to send.
220+
req.Amount = 0
221+
}
222+
211223
switch {
212224
case in.LoopOutChannel != 0 && len(in.OutgoingChanSet) > 0: // nolint:staticcheck
213225
return nil, errors.New("loop_out_channel and outgoing_" +
@@ -712,6 +724,8 @@ func (s *swapClientServer) LoopOutQuote(ctx context.Context,
712724
SweepConfTarget: confTarget,
713725
SwapPublicationDeadline: publicactionDeadline,
714726
Initiator: defaultLoopdInitiator,
727+
AssetId: req.AssetId,
728+
PeerPubkey: req.AssetEdgeNode,
715729
})
716730
if err != nil {
717731
return nil, err
@@ -723,6 +737,7 @@ func (s *swapClientServer) LoopOutQuote(ctx context.Context,
723737
SwapFeeSat: int64(quote.SwapFee),
724738
SwapPaymentDest: quote.SwapPaymentDest[:],
725739
ConfTarget: confTarget,
740+
InvoiceAmtSat: int64(quote.InvoiceAmtSat),
726741
}, nil
727742
}
728743

loopdb/loopout.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,13 @@ type LoopOutContract struct {
6565
// PaymentTimeout is the timeout for any individual off-chain payment
6666
// attempt.
6767
PaymentTimeout time.Duration
68+
69+
// AssetId is the optional asset id that is used to pay the swap invoice.
70+
AssetId []byte
71+
72+
// AssetEdgeNode is the asset edge node that is used to pay the
73+
// swap invoice.
74+
AssetEdgeNode []byte
6875
}
6976

7077
// ChannelSet stores a set of channels.

loopout.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,8 @@ func newLoopOutSwap(globalCtx context.Context, cfg *swapConfig,
206206
},
207207
OutgoingChanSet: chanSet,
208208
PaymentTimeout: request.PaymentTimeout,
209+
AssetId: request.AssetId,
210+
AssetEdgeNode: request.AssetEdgeNode,
209211
}
210212

211213
swapKit := newSwapKit(

0 commit comments

Comments
 (0)