mirror of
https://github.com/lightninglabs/loop.git
synced 2026-08-13 12:33:03 +02:00
cmd: prettify loop quote in/out responses
This commit is contained in:
parent
c4d46a24a0
commit
82401ff1ba
5 changed files with 128 additions and 76 deletions
|
|
@ -4,7 +4,6 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/btcsuite/btcutil"
|
||||
"github.com/lightninglabs/loop"
|
||||
"github.com/lightninglabs/loop/labels"
|
||||
"github.com/lightninglabs/loop/looprpc"
|
||||
|
|
@ -61,6 +60,7 @@ var (
|
|||
confTargetFlag,
|
||||
lastHopFlag,
|
||||
labelFlag,
|
||||
verboseFlag,
|
||||
},
|
||||
Action: loopIn,
|
||||
}
|
||||
|
|
@ -109,14 +109,12 @@ func loopIn(ctx *cli.Context) error {
|
|||
return err
|
||||
}
|
||||
|
||||
quote, err := client.GetLoopInQuote(
|
||||
context.Background(),
|
||||
&looprpc.QuoteRequest{
|
||||
Amt: int64(amt),
|
||||
ConfTarget: htlcConfTarget,
|
||||
ExternalHtlc: external,
|
||||
},
|
||||
)
|
||||
quoteReq := &looprpc.QuoteRequest{
|
||||
Amt: int64(amt),
|
||||
ConfTarget: htlcConfTarget,
|
||||
ExternalHtlc: external,
|
||||
}
|
||||
quote, err := client.GetLoopInQuote(context.Background(), quoteReq)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -136,9 +134,7 @@ func loopIn(ctx *cli.Context) error {
|
|||
}
|
||||
|
||||
limits := getInLimits(quote)
|
||||
err = displayInLimits(
|
||||
amt, btcutil.Amount(quote.HtlcPublishFeeSat), limits, external,
|
||||
)
|
||||
err = displayInDetails(quoteReq, quote, ctx.Bool("verbose"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@ var loopOutCommand = cli.Command{
|
|||
"result in a lower swap fee.",
|
||||
},
|
||||
labelFlag,
|
||||
verboseFlag,
|
||||
},
|
||||
Action: loopOut,
|
||||
}
|
||||
|
|
@ -175,8 +176,8 @@ func loopOut(ctx *cli.Context) error {
|
|||
ctx.Int64("max_swap_routing_fee"),
|
||||
)
|
||||
}
|
||||
err = displayOutLimits(
|
||||
amt, btcutil.Amount(quote.HtlcSweepFeeSat), limits, warning,
|
||||
err = displayOutDetails(
|
||||
limits, warning, quoteReq, quote, ctx.Bool("verbose"),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
|||
104
cmd/loop/main.go
104
cmd/loop/main.go
|
|
@ -74,6 +74,27 @@ var (
|
|||
Usage: "path to macaroon file",
|
||||
Value: loopd.DefaultMacaroonPath,
|
||||
}
|
||||
verboseFlag = cli.BoolFlag{
|
||||
Name: "verbose, v",
|
||||
Usage: "show expanded details",
|
||||
}
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
// satAmtFmt formats a satoshi value into a one line string, intended to
|
||||
// prettify the terminal output. For Instance,
|
||||
// fmt.Printf(f, "Estimated on-chain fee:", fee)
|
||||
// prints out as,
|
||||
// Estimated on-chain fee: 7262 sat
|
||||
satAmtFmt = "%-36s %12d sat\n"
|
||||
|
||||
// blkFmt formats the number of blocks into a one line string, intended
|
||||
// to prettify the terminal output. For Instance,
|
||||
// fmt.Printf(f, "Conf target", target)
|
||||
// prints out as,
|
||||
// Conf target: 9 block
|
||||
blkFmt = "%-36s %12d block\n"
|
||||
)
|
||||
|
||||
func printJSON(resp interface{}) {
|
||||
|
|
@ -246,89 +267,56 @@ func getOutLimits(amt btcutil.Amount,
|
|||
}
|
||||
}
|
||||
|
||||
func displayInLimits(amt, minerFees btcutil.Amount, l *inLimits,
|
||||
externalHtlc bool) error {
|
||||
func displayInDetails(req *looprpc.QuoteRequest,
|
||||
resp *looprpc.InQuoteResponse, verbose bool) error {
|
||||
|
||||
totalSuccessMax := l.maxMinerFee + l.maxSwapFee
|
||||
|
||||
if externalHtlc {
|
||||
if req.ExternalHtlc {
|
||||
fmt.Printf("On-chain fee for external loop in is not " +
|
||||
"included.\nSufficient fees will need to be paid " +
|
||||
"when constructing the transaction in the external " +
|
||||
"wallet.\n\n")
|
||||
}
|
||||
|
||||
fmt.Printf("Max swap fees for %d sat Loop %v: %d sat\n", amt, swap.TypeIn,
|
||||
totalSuccessMax)
|
||||
printQuoteInResp(req, resp, verbose)
|
||||
|
||||
fmt.Printf("CONTINUE SWAP? (y/n), expand fee detail (x): ")
|
||||
fmt.Printf("\nCONTINUE SWAP? (y/n): ")
|
||||
|
||||
var answer string
|
||||
fmt.Scanln(&answer)
|
||||
|
||||
switch answer {
|
||||
case "y":
|
||||
if answer == "y" {
|
||||
return nil
|
||||
case "x":
|
||||
fmt.Println()
|
||||
f := "%-36s %d sat\n"
|
||||
|
||||
if !externalHtlc {
|
||||
fmt.Printf(f, "Estimated on-chain HTLC fee:",
|
||||
minerFees)
|
||||
}
|
||||
|
||||
fmt.Printf(f, "Max swap fee:", l.maxSwapFee)
|
||||
|
||||
fmt.Printf("CONTINUE SWAP? (y/n): ")
|
||||
fmt.Scanln(&answer)
|
||||
if answer == "y" {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return errors.New("swap canceled")
|
||||
}
|
||||
|
||||
func displayOutLimits(amt, minerFees btcutil.Amount, l *outLimits,
|
||||
warning string) error {
|
||||
func displayOutDetails(l *outLimits, warning string, req *looprpc.QuoteRequest,
|
||||
resp *looprpc.OutQuoteResponse, verbose bool) error {
|
||||
|
||||
totalSuccessMax := l.maxMinerFee + l.maxSwapFee + l.maxSwapRoutingFee +
|
||||
l.maxPrepayRoutingFee
|
||||
printQuoteOutResp(req, resp, verbose)
|
||||
|
||||
fmt.Printf("Max swap fees for %d sat Loop %v: %d sat\n", amt, swap.TypeOut,
|
||||
totalSuccessMax)
|
||||
|
||||
if warning != "" {
|
||||
fmt.Println(warning)
|
||||
// Display fee limits.
|
||||
if verbose {
|
||||
fmt.Println()
|
||||
fmt.Printf(satAmtFmt, "Max on-chain fee:", l.maxMinerFee)
|
||||
fmt.Printf(satAmtFmt,
|
||||
"Max off-chain swap routing fee:", l.maxSwapRoutingFee,
|
||||
)
|
||||
fmt.Printf(satAmtFmt, "Max off-chain prepay routing fee:",
|
||||
l.maxPrepayRoutingFee)
|
||||
}
|
||||
|
||||
fmt.Printf("CONTINUE SWAP? (y/n), expand fee detail (x): ")
|
||||
// show warning
|
||||
if warning != "" {
|
||||
fmt.Printf("\n%s\n\n", warning)
|
||||
}
|
||||
|
||||
fmt.Printf("CONTINUE SWAP? (y/n): ")
|
||||
|
||||
var answer string
|
||||
fmt.Scanln(&answer)
|
||||
|
||||
switch answer {
|
||||
case "y":
|
||||
if answer == "y" {
|
||||
return nil
|
||||
case "x":
|
||||
fmt.Println()
|
||||
f := "%-36s %d sat\n"
|
||||
|
||||
fmt.Printf(f, "Estimated on-chain sweep fee:", minerFees)
|
||||
fmt.Printf(f, "Max on-chain sweep fee:", l.maxMinerFee)
|
||||
fmt.Printf(f, "Max off-chain swap routing fee:",
|
||||
l.maxSwapRoutingFee)
|
||||
fmt.Printf(f, "Max no show penalty (prepay):", l.maxPrepayAmt)
|
||||
fmt.Printf(f, "Max off-chain prepay routing fee:",
|
||||
l.maxPrepayRoutingFee)
|
||||
fmt.Printf(f, "Max swap fee:", l.maxSwapFee)
|
||||
|
||||
fmt.Printf("CONTINUE SWAP? (y/n): ")
|
||||
fmt.Scanln(&answer)
|
||||
if answer == "y" {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return errors.New("swap canceled")
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ var quoteInCommand = cli.Command{
|
|||
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",
|
||||
Flags: []cli.Flag{confTargetFlag},
|
||||
Flags: []cli.Flag{confTargetFlag, verboseFlag},
|
||||
Action: quoteIn,
|
||||
}
|
||||
|
||||
|
|
@ -66,7 +66,7 @@ func quoteIn(ctx *cli.Context) error {
|
|||
"amount.\n")
|
||||
}
|
||||
|
||||
printRespJSON(quoteResp)
|
||||
printQuoteInResp(quoteReq, quoteResp, ctx.Bool("verbose"))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -93,6 +93,7 @@ var quoteOutCommand = cli.Command{
|
|||
"setting this flag might result in a lower " +
|
||||
"swap fee.",
|
||||
},
|
||||
verboseFlag,
|
||||
},
|
||||
Action: quoteOut,
|
||||
}
|
||||
|
|
@ -132,6 +133,68 @@ func quoteOut(ctx *cli.Context) error {
|
|||
return err
|
||||
}
|
||||
|
||||
printRespJSON(quoteResp)
|
||||
printQuoteOutResp(quoteReq, quoteResp, ctx.Bool("verbose"))
|
||||
return nil
|
||||
}
|
||||
|
||||
func printQuoteInResp(req *looprpc.QuoteRequest,
|
||||
resp *looprpc.InQuoteResponse, verbose bool) {
|
||||
|
||||
totalFee := resp.HtlcPublishFeeSat + resp.SwapFeeSat
|
||||
|
||||
fmt.Printf(satAmtFmt, "Send on-chain:", req.Amt)
|
||||
fmt.Printf(satAmtFmt, "Receive off-chain:", req.Amt-totalFee)
|
||||
|
||||
switch {
|
||||
case req.ExternalHtlc && !verbose:
|
||||
// If it's external then we don't know the miner fee hence the
|
||||
// total cost.
|
||||
fmt.Printf(satAmtFmt, "Loop service fee:", resp.SwapFeeSat)
|
||||
|
||||
case req.ExternalHtlc && verbose:
|
||||
fmt.Printf(satAmtFmt, "Loop service fee:", resp.SwapFeeSat)
|
||||
fmt.Println()
|
||||
fmt.Printf(blkFmt, "CLTV expiry delta:", resp.CltvDelta)
|
||||
|
||||
case verbose:
|
||||
fmt.Println()
|
||||
fmt.Printf(
|
||||
satAmtFmt, "Estimated on-chain fee:",
|
||||
resp.HtlcPublishFeeSat,
|
||||
)
|
||||
fmt.Printf(satAmtFmt, "Loop service fee:", resp.SwapFeeSat)
|
||||
fmt.Printf(satAmtFmt, "Estimated total fee:", totalFee)
|
||||
fmt.Println()
|
||||
fmt.Printf(blkFmt, "Conf target:", resp.ConfTarget)
|
||||
fmt.Printf(blkFmt, "CLTV expiry delta:", resp.CltvDelta)
|
||||
default:
|
||||
fmt.Printf(satAmtFmt, "Estimated total fee:", totalFee)
|
||||
}
|
||||
}
|
||||
|
||||
func printQuoteOutResp(req *looprpc.QuoteRequest,
|
||||
resp *looprpc.OutQuoteResponse, verbose bool) {
|
||||
|
||||
totalFee := resp.HtlcSweepFeeSat + resp.SwapFeeSat
|
||||
|
||||
fmt.Printf(satAmtFmt, "Send off-chain:", req.Amt)
|
||||
fmt.Printf(satAmtFmt, "Receive on-chain:", req.Amt-totalFee)
|
||||
|
||||
if !verbose {
|
||||
fmt.Printf(satAmtFmt, "Estimated total fee:", totalFee)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println()
|
||||
fmt.Printf(satAmtFmt, "Estimated on-chain fee:", resp.HtlcSweepFeeSat)
|
||||
fmt.Printf(satAmtFmt, "Loop service fee:", resp.SwapFeeSat)
|
||||
fmt.Printf(satAmtFmt, "Estimated total fee:", totalFee)
|
||||
fmt.Println()
|
||||
fmt.Printf(satAmtFmt, "No show penalty (prepay):", resp.PrepayAmtSat)
|
||||
fmt.Printf(blkFmt, "Conf target:", resp.ConfTarget)
|
||||
fmt.Printf(blkFmt, "CLTV expiry delta:", resp.CltvDelta)
|
||||
fmt.Printf("%-38s %s\n",
|
||||
"Publication deadline:",
|
||||
time.Unix(int64(req.SwapPublicationDeadline), 0),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,11 @@ This file tracks release notes for the loop client.
|
|||
## Next release
|
||||
|
||||
#### New Features
|
||||
|
||||
* A new flag, `--verbose`, or `-v`, is added to `loop in`, `loop out` and
|
||||
`loop quote`. Responses from these commands are also updated to provide more
|
||||
verbose info, giving users a more intuitive view about money paid
|
||||
on/off-chain and fees incurred. Use `loop in -v`, `loop out -v`,
|
||||
`loop quote in -v` or `loop quote out -v` to view the details.
|
||||
|
||||
#### Breaking Changes
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue