From dfa58d490684a2877bcb608527f79c5909a4a80a Mon Sep 17 00:00:00 2001 From: sputn1ck Date: Thu, 9 Jan 2025 16:53:53 +0100 Subject: [PATCH] cmd/loopout: add asset flags --- cmd/loop/loopout.go | 49 +++++++++++++++++++++++++++++++++++++++++++++ cmd/loop/main.go | 7 +++++++ cmd/loop/quote.go | 18 +++++++++++++++-- 3 files changed, 72 insertions(+), 2 deletions(-) diff --git a/cmd/loop/loopout.go b/cmd/loop/loopout.go index 6ff24ce5..32cb3f63 100644 --- a/cmd/loop/loopout.go +++ b/cmd/loop/loopout.go @@ -2,6 +2,7 @@ package main import ( "context" + "encoding/hex" "fmt" "math" "strconv" @@ -101,6 +102,20 @@ var loopOutCommand = cli.Command{ "payment might be retried, the actual total " + "time may be longer", }, + cli.StringFlag{ + Name: "asset_id", + Usage: "the asset ID of the asset to loop out, " + + "if this is set, the loop daemon will " + + "require a connection to a taproot assets " + + "daemon", + }, + cli.StringFlag{ + Name: "asset_edge_node", + Usage: "the pubkey of the edge node of the asset to " + + "loop out, this is required if the taproot " + + "assets daemon has multiple channels of the " + + "given asset id with different edge nodes", + }, forceFlag, labelFlag, verboseFlag, @@ -134,6 +149,10 @@ func loopOut(ctx *cli.Context) error { // element. var outgoingChanSet []uint64 if ctx.IsSet("channel") { + if ctx.IsSet("asset_id") { + return fmt.Errorf("channel flag is not supported when " + + "looping out assets") + } chanStrings := strings.Split(ctx.String("channel"), ",") for _, chanString := range chanStrings { chanID, err := strconv.ParseUint(chanString, 10, 64) @@ -186,6 +205,33 @@ func loopOut(ctx *cli.Context) error { } } + var assetLoopOutInfo *looprpc.AssetLoopOutRequest + + var assetId []byte + if ctx.IsSet("asset_id") { + if !ctx.IsSet("asset_edge_node") { + return fmt.Errorf("asset edge node is required when " + + "assetid is set") + } + + assetId, err = hex.DecodeString(ctx.String("asset_id")) + if err != nil { + return err + } + + assetEdgeNode, err := hex.DecodeString( + ctx.String("asset_edge_node"), + ) + if err != nil { + return err + } + + assetLoopOutInfo = &looprpc.AssetLoopOutRequest{ + AssetId: assetId, + AssetEdgeNode: assetEdgeNode, + } + } + client, cleanup, err := getClient(ctx) if err != nil { return err @@ -210,6 +256,7 @@ func loopOut(ctx *cli.Context) error { Amt: int64(amt), ConfTarget: sweepConfTarget, SwapPublicationDeadline: uint64(swapDeadline.Unix()), + AssetInfo: assetLoopOutInfo, } quote, err := client.LoopOutQuote(context.Background(), quoteReq) if err != nil { @@ -281,6 +328,8 @@ func loopOut(ctx *cli.Context) error { Label: label, Initiator: defaultInitiator, PaymentTimeout: uint32(paymentTimeout), + AssetInfo: assetLoopOutInfo, + AssetRfqInfo: quote.AssetRfqInfo, }) if err != nil { return err diff --git a/cmd/loop/main.go b/cmd/loop/main.go index 7fa406f5..cc9e0ea4 100644 --- a/cmd/loop/main.go +++ b/cmd/loop/main.go @@ -96,6 +96,13 @@ const ( // Estimated on-chain fee: 7262 sat satAmtFmt = "%-36s %12d sat\n" + // assetAmtFormat formats a value into a one line string, intended to + // prettify the terminal output. For Instance, + // fmt.Printf(f, "Amount:", amt, "USD") + // prints out as, + // Amount: 50 USD + assetAmtFmt = "%-36s %12d %s\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) diff --git a/cmd/loop/quote.go b/cmd/loop/quote.go index 599a7fbc..2c915bef 100644 --- a/cmd/loop/quote.go +++ b/cmd/loop/quote.go @@ -267,7 +267,14 @@ func printQuoteOutResp(req *looprpc.QuoteRequest, totalFee := resp.HtlcSweepFeeSat + resp.SwapFeeSat - fmt.Printf(satAmtFmt, "Send off-chain:", req.Amt) + if resp.AssetRfqInfo != nil { + fmt.Printf(assetAmtFmt, "Send off-chain:", + resp.AssetRfqInfo.SwapAssetAmt, + resp.AssetRfqInfo.AssetName) + } else { + fmt.Printf(satAmtFmt, "Send off-chain:", req.Amt) + } + fmt.Printf(satAmtFmt, "Receive on-chain:", req.Amt-totalFee) if !verbose { @@ -280,7 +287,14 @@ func printQuoteOutResp(req *looprpc.QuoteRequest, 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) + if resp.AssetRfqInfo != nil { + fmt.Printf(assetAmtFmt, "No show penalty (prepay):", + resp.AssetRfqInfo.PrepayAssetAmt, + resp.AssetRfqInfo.AssetName) + } else { + 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",