Skip to content

Commit

Permalink
Merge pull request #8955 from yyforyongyu/cr-8516-240729-sendcoins
Browse files Browse the repository at this point in the history
Allow selecting coins in `sendcoins`
  • Loading branch information
guggero authored Aug 7, 2024
2 parents b63e5de + dcd8269 commit d776174
Show file tree
Hide file tree
Showing 20 changed files with 3,524 additions and 3,090 deletions.
20 changes: 1 addition & 19 deletions cmd/lncli/cmd_open_channel.go
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ func openChannel(ctx *cli.Context) error {
if ctx.IsSet("utxo") {
utxos := ctx.StringSlice("utxo")

outpoints, err := utxosToOutpoints(utxos)
outpoints, err := UtxosToOutpoints(utxos)
if err != nil {
return fmt.Errorf("unable to decode utxos: %w", err)
}
Expand Down Expand Up @@ -1141,21 +1141,3 @@ func decodePsbt(psbt string) ([]byte, error) {
return nil, fmt.Errorf("not a PSBT")
}
}

// parseUtxos parses a comma separated list of utxos into outpoints that are
// passed to the server.
func utxosToOutpoints(utxos []string) ([]*lnrpc.OutPoint, error) {
var outpoints []*lnrpc.OutPoint
if len(utxos) == 0 {
return nil, fmt.Errorf("no utxos specified")
}
for _, utxo := range utxos {
outpoint, err := NewProtoOutPoint(utxo)
if err != nil {
return nil, err
}
outpoints = append(outpoints, outpoint)
}

return outpoints, nil
}
37 changes: 30 additions & 7 deletions cmd/lncli/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -288,10 +288,11 @@ var sendCoinsCommand = cli.Command{
},
cli.BoolFlag{
Name: "sweepall",
Usage: "if set, then the amount field will be ignored, " +
"and the wallet will attempt to sweep all " +
"outputs within the wallet to the target " +
"address",
Usage: "if set, then the amount field should be " +
"unset. This indicates that the wallet will " +
"attempt to sweep all outputs within the " +
"wallet or all funds in select utxos (when " +
"supplied) to the target address",
},
cli.Int64Flag{
Name: "amt",
Expand Down Expand Up @@ -330,16 +331,28 @@ var sendCoinsCommand = cli.Command{
"scripts",
},
coinSelectionStrategyFlag,
cli.StringSliceFlag{
Name: "utxo",
Usage: "a utxo specified as outpoint(tx:idx) which " +
"will be used as input for the transaction. " +
"This flag can be repeatedly used to specify " +
"multiple utxos as inputs. The selected " +
"utxos can either be entirely spent by " +
"specifying the sweepall flag or a specified " +
"amount can be spent in the utxos through " +
"the amt flag",
},
txLabelFlag,
},
Action: actionDecorator(sendCoins),
}

func sendCoins(ctx *cli.Context) error {
var (
addr string
amt int64
err error
addr string
amt int64
err error
outpoints []*lnrpc.OutPoint
)
ctxc := getContext()
args := ctx.Args()
Expand Down Expand Up @@ -417,6 +430,15 @@ func sendCoins(ctx *cli.Context) error {
displayAmt = balanceResponse.GetConfirmedBalance()
}

if ctx.IsSet("utxo") {
utxos := ctx.StringSlice("utxo")

outpoints, err = UtxosToOutpoints(utxos)
if err != nil {
return fmt.Errorf("unable to decode utxos: %w", err)
}
}

// Ask for confirmation if we're on an actual terminal and the output is
// not being redirected to another command. This prevents existing shell
// scripts from breaking.
Expand All @@ -440,6 +462,7 @@ func sendCoins(ctx *cli.Context) error {
MinConfs: minConfs,
SpendUnconfirmed: minConfs == 0,
CoinSelectionStrategy: coinSelectionStrategy,
Outpoints: outpoints,
}
txid, err := client.SendCoins(ctxc, req)
if err != nil {
Expand Down
19 changes: 19 additions & 0 deletions cmd/lncli/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,22 @@ func NewFailedUpdateFromProto(update *lnrpc.FailedUpdate) *FailedUpdate {
UpdateError: update.UpdateError,
}
}

// UtxosToOutpoints converts a slice of UTXO strings into a slice of OutPoint
// protobuf objects. It returns an error if no UTXOs are specified or if any
// UTXO string cannot be parsed into an OutPoint.
func UtxosToOutpoints(utxos []string) ([]*lnrpc.OutPoint, error) {
var outpoints []*lnrpc.OutPoint
if len(utxos) == 0 {
return nil, fmt.Errorf("no utxos specified")
}
for _, utxo := range utxos {
outpoint, err := NewProtoOutPoint(utxo)
if err != nil {
return nil, err
}
outpoints = append(outpoints, outpoint)
}

return outpoints, nil
}
42 changes: 42 additions & 0 deletions docs/release-notes/release-notes-0.18.3.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,36 @@ commitment when the channel was force closed.
send payment stream context, or automatically at the end of the timeout period
if the user provided `timeout_seconds`.

* The [SendCoinsRequest](https://github.com/lightningnetwork/lnd/pull/8955) now
takes an optional param `Outpoints`, which is a list of `*lnrpc.OutPoint`
that specifies the coins from the wallet to be spent in this RPC call. To
send selected coins to a given address with a given amount,
```go
req := &lnrpc.SendCoinsRequest{
Addr: ...,
Amount: ...,
Outpoints: []*lnrpc.OutPoint{
selected_wallet_utxo_1,
selected_wallet_utxo_2,
},
}

SendCoins(req)
```
To send selected coins to a given address without change output,
```go
req := &lnrpc.SendCoinsRequest{
Addr: ...,
SendAll: true,
Outpoints: []*lnrpc.OutPoint{
selected_wallet_utxo_1,
selected_wallet_utxo_2,
},
}
SendCoins(req)
```

## lncli Additions

* [Added](https://github.com/lightningnetwork/lnd/pull/8491) the `cltv_expiry`
Expand All @@ -68,6 +98,18 @@ commitment when the channel was force closed.
command returns the fee rate estimate for on-chain transactions in sat/kw and
sat/vb to achieve a given confirmation target.

* [`sendcoins` now takes an optional utxo
flag](https://github.com/lightningnetwork/lnd/pull/8955). This allows users
to specify the coins that they want to use as inputs for the transaction. To
send selected coins to a given address with a given amount,
```sh
sendcoins --addr YOUR_ADDR --amt YOUR_AMT --utxo selected_wallet_utxo1 --utxo selected_wallet_utxo2
```
To send selected coins to a given address without change output,
```sh
sendcoins --addr YOUR_ADDR --utxo selected_wallet_utxo1 --utxo selected_wallet_utxo2 --sweepall
```

# Improvements
## Functional Updates

Expand Down
12 changes: 10 additions & 2 deletions itest/list_on_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,16 @@ var allTestCases = []*lntest.TestCase{
TestFunc: testDataLossProtection,
},
{
Name: "sweep coins",
TestFunc: testSweepAllCoins,
Name: "send all coins",
TestFunc: testSendAllCoins,
},
{
Name: "send selected coins",
TestFunc: testSendSelectedCoins,
},
{
Name: "send selected coins channel reserve",
TestFunc: testSendSelectedCoinsChannelReserve,
},
{
Name: "disconnecting target peer",
Expand Down
Loading

0 comments on commit d776174

Please sign in to comment.