mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-05-05 01:10:21 +02:00
lncli: add coin selection strategy option to on-chain rpc commands
In this commit we add coin selection strategy option to the following on-chain rpc commands `fundpsbt`, `fundtemplatepsbt`, `batchopenchannel`, `estimatefee`, `sendcoins`, and `sendmany`.
This commit is contained in:
parent
7c2c0dcf98
commit
a0b0e7aa62
@ -817,6 +817,7 @@ var batchOpenChannelCommand = cli.Command{
|
|||||||
"transaction when storing it to the local " +
|
"transaction when storing it to the local " +
|
||||||
"wallet after publishing it",
|
"wallet after publishing it",
|
||||||
},
|
},
|
||||||
|
coinSelectionStrategyFlag,
|
||||||
},
|
},
|
||||||
Action: actionDecorator(batchOpenChannel),
|
Action: actionDecorator(batchOpenChannel),
|
||||||
}
|
}
|
||||||
@ -845,13 +846,19 @@ func batchOpenChannel(ctx *cli.Context) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
coinSelectionStrategy, err := parseCoinSelectionStrategy(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
minConfs := int32(ctx.Uint64("min_confs"))
|
minConfs := int32(ctx.Uint64("min_confs"))
|
||||||
req := &lnrpc.BatchOpenChannelRequest{
|
req := &lnrpc.BatchOpenChannelRequest{
|
||||||
TargetConf: int32(ctx.Int64("conf_target")),
|
TargetConf: int32(ctx.Int64("conf_target")),
|
||||||
SatPerVbyte: int64(ctx.Uint64("sat_per_vbyte")),
|
SatPerVbyte: int64(ctx.Uint64("sat_per_vbyte")),
|
||||||
MinConfs: minConfs,
|
MinConfs: minConfs,
|
||||||
SpendUnconfirmed: minConfs == 0,
|
SpendUnconfirmed: minConfs == 0,
|
||||||
Label: ctx.String("label"),
|
Label: ctx.String("label"),
|
||||||
|
CoinSelectionStrategy: coinSelectionStrategy,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Let's try and parse the JSON part of the CLI now. Fortunately we can
|
// Let's try and parse the JSON part of the CLI now. Fortunately we can
|
||||||
|
@ -200,6 +200,16 @@ func newAddress(ctx *cli.Context) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var coinSelectionStrategyFlag = cli.StringFlag{
|
||||||
|
Name: "coin_selection_strategy",
|
||||||
|
Usage: "(optional) the strategy to use for selecting " +
|
||||||
|
"coins. Possible values are 'largest', 'random', or " +
|
||||||
|
"'global-config'. If either 'largest' or 'random' is " +
|
||||||
|
"specified, it will override the globally configured " +
|
||||||
|
"strategy in lnd.conf",
|
||||||
|
Value: "global-config",
|
||||||
|
}
|
||||||
|
|
||||||
var estimateFeeCommand = cli.Command{
|
var estimateFeeCommand = cli.Command{
|
||||||
Name: "estimatefee",
|
Name: "estimatefee",
|
||||||
Category: "On-chain",
|
Category: "On-chain",
|
||||||
@ -215,9 +225,10 @@ var estimateFeeCommand = cli.Command{
|
|||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.Int64Flag{
|
cli.Int64Flag{
|
||||||
Name: "conf_target",
|
Name: "conf_target",
|
||||||
Usage: "(optional) the number of blocks that the transaction *should* " +
|
Usage: "(optional) the number of blocks that the " +
|
||||||
"confirm in",
|
"transaction *should* confirm in",
|
||||||
},
|
},
|
||||||
|
coinSelectionStrategyFlag,
|
||||||
},
|
},
|
||||||
Action: actionDecorator(estimateFees),
|
Action: actionDecorator(estimateFees),
|
||||||
}
|
}
|
||||||
@ -231,12 +242,18 @@ func estimateFees(ctx *cli.Context) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
coinSelectionStrategy, err := parseCoinSelectionStrategy(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
client, cleanUp := getClient(ctx)
|
client, cleanUp := getClient(ctx)
|
||||||
defer cleanUp()
|
defer cleanUp()
|
||||||
|
|
||||||
resp, err := client.EstimateFee(ctxc, &lnrpc.EstimateFeeRequest{
|
resp, err := client.EstimateFee(ctxc, &lnrpc.EstimateFeeRequest{
|
||||||
AddrToAmount: amountToAddr,
|
AddrToAmount: amountToAddr,
|
||||||
TargetConf: int32(ctx.Int64("conf_target")),
|
TargetConf: int32(ctx.Int64("conf_target")),
|
||||||
|
CoinSelectionStrategy: coinSelectionStrategy,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -313,6 +330,7 @@ var sendCoinsCommand = cli.Command{
|
|||||||
"terminal avoid breaking existing shell " +
|
"terminal avoid breaking existing shell " +
|
||||||
"scripts",
|
"scripts",
|
||||||
},
|
},
|
||||||
|
coinSelectionStrategyFlag,
|
||||||
txLabelFlag,
|
txLabelFlag,
|
||||||
},
|
},
|
||||||
Action: actionDecorator(sendCoins),
|
Action: actionDecorator(sendCoins),
|
||||||
@ -375,6 +393,11 @@ func sendCoins(ctx *cli.Context) error {
|
|||||||
"sweep all coins out of the wallet")
|
"sweep all coins out of the wallet")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
coinSelectionStrategy, err := parseCoinSelectionStrategy(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
client, cleanUp := getClient(ctx)
|
client, cleanUp := getClient(ctx)
|
||||||
defer cleanUp()
|
defer cleanUp()
|
||||||
minConfs := int32(ctx.Uint64("min_confs"))
|
minConfs := int32(ctx.Uint64("min_confs"))
|
||||||
@ -409,14 +432,15 @@ func sendCoins(ctx *cli.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
req := &lnrpc.SendCoinsRequest{
|
req := &lnrpc.SendCoinsRequest{
|
||||||
Addr: addr,
|
Addr: addr,
|
||||||
Amount: amt,
|
Amount: amt,
|
||||||
TargetConf: int32(ctx.Int64("conf_target")),
|
TargetConf: int32(ctx.Int64("conf_target")),
|
||||||
SatPerVbyte: ctx.Uint64(feeRateFlag),
|
SatPerVbyte: ctx.Uint64(feeRateFlag),
|
||||||
SendAll: ctx.Bool("sweepall"),
|
SendAll: ctx.Bool("sweepall"),
|
||||||
Label: ctx.String(txLabelFlag.Name),
|
Label: ctx.String(txLabelFlag.Name),
|
||||||
MinConfs: minConfs,
|
MinConfs: minConfs,
|
||||||
SpendUnconfirmed: minConfs == 0,
|
SpendUnconfirmed: minConfs == 0,
|
||||||
|
CoinSelectionStrategy: coinSelectionStrategy,
|
||||||
}
|
}
|
||||||
txid, err := client.SendCoins(ctxc, req)
|
txid, err := client.SendCoins(ctxc, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -585,6 +609,7 @@ var sendManyCommand = cli.Command{
|
|||||||
"must satisfy",
|
"must satisfy",
|
||||||
Value: defaultUtxoMinConf,
|
Value: defaultUtxoMinConf,
|
||||||
},
|
},
|
||||||
|
coinSelectionStrategyFlag,
|
||||||
txLabelFlag,
|
txLabelFlag,
|
||||||
},
|
},
|
||||||
Action: actionDecorator(sendMany),
|
Action: actionDecorator(sendMany),
|
||||||
@ -615,17 +640,23 @@ func sendMany(ctx *cli.Context) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
coinSelectionStrategy, err := parseCoinSelectionStrategy(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
client, cleanUp := getClient(ctx)
|
client, cleanUp := getClient(ctx)
|
||||||
defer cleanUp()
|
defer cleanUp()
|
||||||
|
|
||||||
minConfs := int32(ctx.Uint64("min_confs"))
|
minConfs := int32(ctx.Uint64("min_confs"))
|
||||||
txid, err := client.SendMany(ctxc, &lnrpc.SendManyRequest{
|
txid, err := client.SendMany(ctxc, &lnrpc.SendManyRequest{
|
||||||
AddrToAmount: amountToAddr,
|
AddrToAmount: amountToAddr,
|
||||||
TargetConf: int32(ctx.Int64("conf_target")),
|
TargetConf: int32(ctx.Int64("conf_target")),
|
||||||
SatPerVbyte: ctx.Uint64(feeRateFlag),
|
SatPerVbyte: ctx.Uint64(feeRateFlag),
|
||||||
Label: ctx.String(txLabelFlag.Name),
|
Label: ctx.String(txLabelFlag.Name),
|
||||||
MinConfs: minConfs,
|
MinConfs: minConfs,
|
||||||
SpendUnconfirmed: minConfs == 0,
|
SpendUnconfirmed: minConfs == 0,
|
||||||
|
CoinSelectionStrategy: coinSelectionStrategy,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -564,3 +564,31 @@ func networkParams(ctx *cli.Context) (*chaincfg.Params, error) {
|
|||||||
return nil, fmt.Errorf("unknown network: %v", network)
|
return nil, fmt.Errorf("unknown network: %v", network)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// parseCoinSelectionStrategy parses a coin selection strategy string
|
||||||
|
// from the CLI to its lnrpc.CoinSelectionStrategy counterpart proto type.
|
||||||
|
func parseCoinSelectionStrategy(ctx *cli.Context) (
|
||||||
|
lnrpc.CoinSelectionStrategy, error) {
|
||||||
|
|
||||||
|
strategy := ctx.String(coinSelectionStrategyFlag.Name)
|
||||||
|
if !ctx.IsSet(coinSelectionStrategyFlag.Name) {
|
||||||
|
return lnrpc.CoinSelectionStrategy_STRATEGY_USE_GLOBAL_CONFIG,
|
||||||
|
nil
|
||||||
|
}
|
||||||
|
|
||||||
|
switch strategy {
|
||||||
|
case "global-config":
|
||||||
|
return lnrpc.CoinSelectionStrategy_STRATEGY_USE_GLOBAL_CONFIG,
|
||||||
|
nil
|
||||||
|
|
||||||
|
case "largest":
|
||||||
|
return lnrpc.CoinSelectionStrategy_STRATEGY_LARGEST, nil
|
||||||
|
|
||||||
|
case "random":
|
||||||
|
return lnrpc.CoinSelectionStrategy_STRATEGY_RANDOM, nil
|
||||||
|
|
||||||
|
default:
|
||||||
|
return 0, fmt.Errorf("unknown coin selection strategy "+
|
||||||
|
"%v", strategy)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -849,6 +849,7 @@ var fundTemplatePsbtCommand = cli.Command{
|
|||||||
"if required",
|
"if required",
|
||||||
Value: -1,
|
Value: -1,
|
||||||
},
|
},
|
||||||
|
coinSelectionStrategyFlag,
|
||||||
},
|
},
|
||||||
Action: actionDecorator(fundTemplatePsbt),
|
Action: actionDecorator(fundTemplatePsbt),
|
||||||
}
|
}
|
||||||
@ -997,6 +998,11 @@ func fundTemplatePsbt(ctx *cli.Context) error {
|
|||||||
"inputs/outputs flag")
|
"inputs/outputs flag")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
coinSelectionStrategy, err := parseCoinSelectionStrategy(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
minConfs := int32(ctx.Uint64("min_confs"))
|
minConfs := int32(ctx.Uint64("min_confs"))
|
||||||
req := &walletrpc.FundPsbtRequest{
|
req := &walletrpc.FundPsbtRequest{
|
||||||
Account: ctx.String("account"),
|
Account: ctx.String("account"),
|
||||||
@ -1005,6 +1011,7 @@ func fundTemplatePsbt(ctx *cli.Context) error {
|
|||||||
Template: &walletrpc.FundPsbtRequest_CoinSelect{
|
Template: &walletrpc.FundPsbtRequest_CoinSelect{
|
||||||
CoinSelect: coinSelect,
|
CoinSelect: coinSelect,
|
||||||
},
|
},
|
||||||
|
CoinSelectionStrategy: coinSelectionStrategy,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse fee flags.
|
// Parse fee flags.
|
||||||
@ -1167,6 +1174,7 @@ var fundPsbtCommand = cli.Command{
|
|||||||
"transaction must satisfy",
|
"transaction must satisfy",
|
||||||
Value: defaultUtxoMinConf,
|
Value: defaultUtxoMinConf,
|
||||||
},
|
},
|
||||||
|
coinSelectionStrategyFlag,
|
||||||
},
|
},
|
||||||
Action: actionDecorator(fundPsbt),
|
Action: actionDecorator(fundPsbt),
|
||||||
}
|
}
|
||||||
@ -1180,11 +1188,17 @@ func fundPsbt(ctx *cli.Context) error {
|
|||||||
return cli.ShowCommandHelp(ctx, "fund")
|
return cli.ShowCommandHelp(ctx, "fund")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
coinSelectionStrategy, err := parseCoinSelectionStrategy(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
minConfs := int32(ctx.Uint64("min_confs"))
|
minConfs := int32(ctx.Uint64("min_confs"))
|
||||||
req := &walletrpc.FundPsbtRequest{
|
req := &walletrpc.FundPsbtRequest{
|
||||||
Account: ctx.String("account"),
|
Account: ctx.String("account"),
|
||||||
MinConfs: minConfs,
|
MinConfs: minConfs,
|
||||||
SpendUnconfirmed: minConfs == 0,
|
SpendUnconfirmed: minConfs == 0,
|
||||||
|
CoinSelectionStrategy: coinSelectionStrategy,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse template flags.
|
// Parse template flags.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user