Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
03455bd
sqlc: static address migrations, models, queries
hieblmi Nov 9, 2023
e810825
looprpc: static address creation
hieblmi Feb 14, 2024
8c5eca4
log: static address sub logger
hieblmi Nov 9, 2023
9859215
loopdb: static address store
hieblmi Nov 9, 2023
48060a7
staticaddr: static address manager
hieblmi Nov 9, 2023
155d25e
staticaddr: static address server
hieblmi Feb 14, 2024
efd8d8a
daemon: integrate static address manager and sql store
hieblmi Nov 9, 2023
e1d8fe5
perms: static address creation permission
hieblmi Nov 9, 2023
6e7ae3c
loop: static address creation client command
hieblmi Nov 9, 2023
ca988c2
looprpc: list unspent static address
hieblmi Nov 9, 2023
2fc12ad
staticaddr: track and list spends in manager
hieblmi Oct 25, 2023
3f9a289
staticaddr: list unspent outputs in server
hieblmi Oct 25, 2023
40af24c
perms: list unspent outputs
hieblmi Oct 25, 2023
14845e8
loop: list unspent static address outputs
hieblmi Oct 25, 2023
5632898
looprpc: include static address in swap client
hieblmi Feb 26, 2024
95a2219
sqlc: deposit queries, models and migrations
hieblmi Mar 7, 2024
a4df183
staticaddr: interfaces
hieblmi Mar 7, 2024
3048cb5
staticaddr: deposit logger
hieblmi Mar 7, 2024
74fc42c
staticaddr: deposit manager and fsm
hieblmi Mar 7, 2024
5f6cb66
staticaddr: deposits for server and daemon
hieblmi Mar 7, 2024
f41eb3d
staticaddr: add swap client to cmd
hieblmi Mar 7, 2024
e130b71
unit: manager tests
hieblmi Apr 23, 2024
dfbf9d3
staticaddr: public deposit method scope
hieblmi Apr 25, 2024
b52fbdf
sqlc: withdrawal address for deposits
hieblmi May 6, 2024
a154fc9
looprpc: deposit withdrawal endpoint
hieblmi May 6, 2024
4a171b8
swapserverrpc: server withdrawal endpoint
hieblmi May 6, 2024
2711a22
log: unified static address logger
hieblmi May 6, 2024
dd17005
staticaddr: address and deposit adjustments for withdrawals
hieblmi May 6, 2024
5c553d1
staticaddr: withdrawal manager and interface
hieblmi May 6, 2024
84b5ad8
loopd: static address withdrawals support
hieblmi May 6, 2024
4100957
loop: static address withdrawals support
hieblmi May 6, 2024
9baca13
looprpc: static address summary
hieblmi Jun 5, 2024
dd69c8a
staticaddr: expose static address to client summary
hieblmi Jun 5, 2024
7f4df34
loopd: static address summary
hieblmi Jun 5, 2024
e9a39fe
looprpc: deposit outpoints for QuoteRequest
hieblmi Jun 6, 2024
6699a6c
swapserverrpc: number of deposits for ServerLoopInQuoteRequest
hieblmi Jun 6, 2024
4803902
loopd: quoting for static address loop-ins
hieblmi Jun 6, 2024
bda72be
cmd: quote for static address loop-ins
hieblmi Jun 6, 2024
c79b45d
looprpc: static address loop-ins
hieblmi Jul 30, 2024
87e94d3
sqlc: loop-in tables and queries
hieblmi Jul 30, 2024
0fec21f
log: static address loop-in logging
hieblmi Jul 30, 2024
484dc91
staticaddr: enable deposits for swaps
hieblmi Jul 30, 2024
1a091f1
loopin: public scope for ValidateLoopInContract
hieblmi Sep 26, 2024
349f645
interface: add StaticAddressLoopInRequest interface
hieblmi Sep 26, 2024
2c9418d
staticaddr: configurable max htlc tx fee
hieblmi Oct 17, 2024
4e76af0
staticaddr: loopin
hieblmi Oct 30, 2024
534c9b1
staticaddr: sql_store
hieblmi Oct 30, 2024
0b60d6b
staticaddr: swap manager and fsm
hieblmi Oct 24, 2024
fb2a5c5
unit: manager mocks for static address loop-in
hieblmi Jul 30, 2024
adc19ae
loopd: static address loop-in support
hieblmi Jul 30, 2024
df7544a
cmd: static address loop-in
hieblmi Jul 30, 2024
94b9d94
staticaddr: cmd listdeposits and listswaps
hieblmi Nov 5, 2024
6f74745
staticaddr: separate file for rpc service
hieblmi Nov 5, 2024
bf2800b
staticaddr: change min deposit confs from 3 to 6
hieblmi Nov 5, 2024
bbcfbfc
staticaddr: fix fsm logging
hieblmi Nov 5, 2024
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
34 changes: 28 additions & 6 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,13 @@ var (
ErrSwapAmountTooHigh = errors.New("swap amount too high")

// ErrExpiryTooFar is returned when the server proposes an expiry that
// is too soon for us.
// is too far in the future.
ErrExpiryTooFar = errors.New("swap expiry too far")

// ErrExpiryTooSoon is returned when the server proposes an expiry that
// is too soon.
ErrExpiryTooSoon = errors.New("swap expiry too soon")

// ErrInsufficientBalance indicates insufficient confirmed balance to
// publish a swap.
ErrInsufficientBalance = errors.New("insufficient confirmed balance")
Expand Down Expand Up @@ -137,6 +141,22 @@ type ClientConfig struct {
// MaxPaymentRetries is the maximum times we retry an off-chain payment
// (used in loop out).
MaxPaymentRetries int

// MaxStaticAddrHtlcFeePercentage is the percentage of the swap amount
// that we allow the server to charge for the htlc transaction.
// Although highly unlikely, this is a defense against the server
// publishing the htlc without paying the swap invoice, forcing us to
// sweep the timeout path.
MaxStaticAddrHtlcFeePercentage float64

// MaxStaticAddrHtlcBackupFeePercentage is the percentage of the swap
// amount that we allow the server to charge for the htlc backup
// transactions. This is a defense against the server publishing the
// htlc backup without paying the swap invoice, forcing us to sweep the
// timeout path. This value is elevated compared to
// MaxStaticAddrHtlcFeePercentage since it serves the server as backup
// transaction in case of fee spikes.
MaxStaticAddrHtlcBackupFeePercentage float64
}

// NewClient returns a new instance to initiate swaps with.
Expand Down Expand Up @@ -694,9 +714,9 @@ func (s *Client) LoopIn(globalCtx context.Context,
return swapInfo, nil
}

// LoopInQuote takes an amount and returns a break down of estimated
// costs for the client. Both the swap server and the on-chain fee estimator are
// queried to get to build the quote response.
// LoopInQuote takes an amount and returns a breakdown of estimated costs for
// the client. Both the swap server and the on-chain fee estimator are queried
// to get to build the quote response.
func (s *Client) LoopInQuote(ctx context.Context,
request *LoopInQuoteRequest) (*LoopInQuote, error) {

Expand Down Expand Up @@ -742,7 +762,7 @@ func (s *Client) LoopInQuote(ctx context.Context,

quote, err := s.Server.GetLoopInQuote(
ctx, request.Amount, s.lndServices.NodePubkey, request.LastHop,
request.RouteHints, request.Initiator,
request.RouteHints, request.Initiator, request.NumDeposits,
)
if err != nil {
return nil, err
Expand All @@ -752,7 +772,9 @@ func (s *Client) LoopInQuote(ctx context.Context,

// We don't calculate the on-chain fee if the HTLC is going to be
// published externally.
if request.ExternalHtlc {
// We also don't calculate the on-chain fee if the loop in is funded by
// static address deposits because we don't publish the HTLC on-chain.
if request.ExternalHtlc || request.NumDeposits > 0 {
return &LoopInQuote{
SwapFee: swapFee,
MinerFee: 0,
Expand Down
7 changes: 7 additions & 0 deletions cmd/loop/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ func main() {
setLiquidityRuleCommand, suggestSwapCommand, setParamsCommand,
getInfoCommand, abandonSwapCommand, reservationsCommands,
instantOutCommand, listInstantOutsCommand,
staticAddressCommands,
}

err := app.Run(os.Args)
Expand Down Expand Up @@ -279,6 +280,12 @@ func displayInDetails(req *looprpc.QuoteRequest,
"wallet.\n\n")
}

if req.DepositOutpoints != nil {
fmt.Printf("On-chain fees for static address loop-ins are not " +
"included.\nThey were already paid when the deposits " +
"were created.\n\n")
}

printQuoteInResp(req, resp, verbose)

fmt.Printf("\nCONTINUE SWAP? (y/n): ")
Expand Down
82 changes: 70 additions & 12 deletions cmd/loop/quote.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"os"
"time"

"github.com/btcsuite/btcd/btcutil"
"github.com/lightninglabs/loop"
"github.com/lightninglabs/loop/looprpc"
"github.com/lightningnetwork/lnd/routing/route"
Expand All @@ -19,10 +20,11 @@ var quoteCommand = cli.Command{
}

var quoteInCommand = cli.Command{
Name: "in",
Usage: "get a quote for the cost of a loop in swap",
ArgsUsage: "amt",
Description: "Allows to determine the cost of a swap up front",
Name: "in",
Usage: "get a quote for the cost of a loop in swap",
ArgsUsage: "amt",
Description: "Allows to determine the cost of a swap up front." +
"Either specify an amount or deposit outpoints.",
Flags: []cli.Flag{
cli.StringFlag{
Name: lastHopFlag.Name,
Expand All @@ -33,20 +35,38 @@ var quoteInCommand = cli.Command{
verboseFlag,
privateFlag,
routeHintsFlag,
cli.StringSliceFlag{
Name: "deposit_outpoint",
Usage: "one or more static address deposit outpoints " +
"to quote for. Deposit outpoints are not to " +
"be used in combination with an amount. Each" +
"additional outpoint can be added by " +
"specifying --deposit_outpoint tx_id:idx",
},
},
Action: quoteIn,
}

func quoteIn(ctx *cli.Context) error {
// Show command help if the incorrect number arguments was provided.
if ctx.NArg() != 1 {
if ctx.NArg() != 1 && !ctx.IsSet("deposit_outpoint") {
return cli.ShowCommandHelp(ctx, "in")
}

args := ctx.Args()
amt, err := parseAmt(args[0])
if err != nil {
return err
var (
manualAmt btcutil.Amount
depositAmt btcutil.Amount
depositOutpoints []string
err error
ctxb = context.Background()
)

if ctx.NArg() == 1 {
args := ctx.Args()
manualAmt, err = parseAmt(args[0])
if err != nil {
return err
}
}

client, cleanup, err := getClient(ctx)
Expand All @@ -62,11 +82,20 @@ func quoteIn(ctx *cli.Context) error {
return err
}

if ctx.IsSet("deposit_outpoint") {
depositOutpoints = ctx.StringSlice("deposit_outpoint")
depositAmt, err = depositAmount(ctxb, client, depositOutpoints)
if err != nil {
return err
}
}

quoteReq := &looprpc.QuoteRequest{
Amt: int64(amt),
Amt: int64(manualAmt),
ConfTarget: int32(ctx.Uint64("conf_target")),
LoopInRouteHints: hints,
Private: ctx.Bool(privateFlag.Name),
DepositOutpoints: depositOutpoints,
}

if ctx.IsSet(lastHopFlag.Name) {
Expand All @@ -80,7 +109,6 @@ func quoteIn(ctx *cli.Context) error {
quoteReq.LoopInLastHop = lastHopVertex[:]
}

ctxb := context.Background()
quoteResp, err := client.GetLoopInQuote(ctxb, quoteReq)
if err != nil {
return err
Expand All @@ -98,10 +126,36 @@ func quoteIn(ctx *cli.Context) error {
"amount.\n")
}

// If the user specified static address deposits, we quoted for their
// total value and need to display that value instead of the manually
// selected one.
if manualAmt == 0 {
quoteReq.Amt = int64(depositAmt)
}
printQuoteInResp(quoteReq, quoteResp, ctx.Bool("verbose"))
return nil
}

func depositAmount(ctx context.Context, client looprpc.SwapClientClient,
depositOutpoints []string) (btcutil.Amount, error) {

addressSummary, err := client.ListStaticAddressDeposits(
ctx, &looprpc.ListStaticAddressDepositsRequest{
Outpoints: depositOutpoints,
},
)
if err != nil {
return 0, err
}

var depositAmt btcutil.Amount
for _, deposit := range addressSummary.FilteredDeposits {
depositAmt += btcutil.Amount(deposit.Value)
}

return depositAmt, nil
}

var quoteOutCommand = cli.Command{
Name: "out",
Usage: "get a quote for the cost of a loop out swap",
Expand Down Expand Up @@ -174,7 +228,11 @@ func printQuoteInResp(req *looprpc.QuoteRequest,

totalFee := resp.HtlcPublishFeeSat + resp.SwapFeeSat

fmt.Printf(satAmtFmt, "Send on-chain:", req.Amt)
if req.DepositOutpoints != nil {
fmt.Printf(satAmtFmt, "Previously deposited on-chain:", req.Amt)
} else {
fmt.Printf(satAmtFmt, "Send on-chain:", req.Amt)
}
fmt.Printf(satAmtFmt, "Receive off-chain:", req.Amt-totalFee)

switch {
Expand Down
Loading
Loading