Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add listunspent RPC call #1984

Merged
merged 1 commit into from Dec 12, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
101 changes: 98 additions & 3 deletions cmd/lncli/commands.go
Expand Up @@ -120,12 +120,12 @@ func newAddress(ctx *cli.Context) error {

// Map the string encoded address type, to the concrete typed address
// type enum. An unrecognized address type will result in an error.
var addrType lnrpc.NewAddressRequest_AddressType
var addrType lnrpc.AddressType
switch stringAddrType { // TODO(roasbeef): make them ints on the cli?
case "p2wkh":
addrType = lnrpc.NewAddressRequest_WITNESS_PUBKEY_HASH
addrType = lnrpc.AddressType_WITNESS_PUBKEY_HASH
case "np2wkh":
addrType = lnrpc.NewAddressRequest_NESTED_PUBKEY_HASH
addrType = lnrpc.AddressType_NESTED_PUBKEY_HASH
default:
return fmt.Errorf("invalid address type %v, support address type "+
"are: p2wkh and np2wkh", stringAddrType)
Expand Down Expand Up @@ -242,6 +242,101 @@ func sendCoins(ctx *cli.Context) error {
return nil
}

var listUnspentCommand = cli.Command{
Name: "listunspent",
Category: "On-chain",
Usage: "List utxos available for spending.",
ArgsUsage: "min-confs max-confs",
Description: `
For each spendable utxo currently in the wallet, with at least min_confs
confirmations, and at most max_confs confirmations, lists the txid, index,
amount, address, address type, scriptPubkey and number of confirmations.
Use --min_confs=0 to include unconfirmed coins. To list all coins
with at least min_confs confirmations, omit the second argument or flag
'--max_confs'.
`,
Flags: []cli.Flag{
cli.Int64Flag{
Name: "min_confs",
Usage: "the minimum number of confirmations for a utxo",
},
cli.Int64Flag{
Name: "max_confs",
Usage: "the maximum number of confirmations for a utxo",
},
},
Action: actionDecorator(listUnspent),
}

func listUnspent(ctx *cli.Context) error {
var (
minConfirms int64
maxConfirms int64
err error
)
args := ctx.Args()

if ctx.NArg() == 0 && ctx.NumFlags() == 0 {
cli.ShowCommandHelp(ctx, "listunspent")
return nil
}

if ctx.IsSet("max_confs") && !ctx.IsSet("min_confs") {
return fmt.Errorf("max_confs cannot be set without " +
"min_confs being set")
}

switch {
case ctx.IsSet("min_confs"):
minConfirms = ctx.Int64("min_confs")
case args.Present():
minConfirms, err = strconv.ParseInt(args.First(), 10, 64)
if err != nil {
cli.ShowCommandHelp(ctx, "listunspent")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

return nil
}
args = args.Tail()
default:
return fmt.Errorf("minimum confirmations argument missing")
}

switch {
case ctx.IsSet("max_confs"):
maxConfirms = ctx.Int64("max_confs")
case args.Present():
maxConfirms, err = strconv.ParseInt(args.First(), 10, 64)
if err != nil {
cli.ShowCommandHelp(ctx, "listunspent")
return nil
}
args = args.Tail()
default:
// No maxconfs was specified; we use max as flag;
// the default for ctx.Int64 (0) is *not* appropriate here.
maxConfirms = math.MaxInt32
}

if minConfirms < 0 || maxConfirms < minConfirms {
return fmt.Errorf("maximum confirmations must be greater or " +
"equal to minimum confirmations")
}

ctxb := context.Background()
client, cleanUp := getClient(ctx)
defer cleanUp()

req := &lnrpc.ListUnspentRequest{
MinConfs: int32(minConfirms),
MaxConfs: int32(maxConfirms),
}
jsonResponse, err := client.ListUnspent(ctxb, req)
if err != nil {
return err
}
printRespJSON(jsonResponse)
return nil
}

var sendManyCommand = cli.Command{
Name: "sendmany",
Category: "On-chain",
Expand Down
1 change: 1 addition & 0 deletions cmd/lncli/main.go
Expand Up @@ -256,6 +256,7 @@ func main() {
newAddressCommand,
sendManyCommand,
sendCoinsCommand,
listUnspentCommand,
connectCommand,
disconnectCommand,
openChannelCommand,
Expand Down
4 changes: 2 additions & 2 deletions lnd_test.go
Expand Up @@ -599,8 +599,8 @@ func getChanInfo(ctx context.Context, node *lntest.HarnessNode) (
}

const (
AddrTypeWitnessPubkeyHash = lnrpc.NewAddressRequest_WITNESS_PUBKEY_HASH
AddrTypeNestedPubkeyHash = lnrpc.NewAddressRequest_NESTED_PUBKEY_HASH
AddrTypeWitnessPubkeyHash = lnrpc.AddressType_WITNESS_PUBKEY_HASH
AddrTypeNestedPubkeyHash = lnrpc.AddressType_NESTED_PUBKEY_HASH
)

// testOnchainFundRecovery checks lnd's ability to rescan for onchain outputs
Expand Down
2 changes: 2 additions & 0 deletions lnrpc/README.md
Expand Up @@ -29,6 +29,8 @@ description):
`lnd`.
* SendCoins
* Sends an amount of satoshis to a specific address.
* ListUnspent
* Lists available utxos within a range of confirmations.
* SubscribeTransactions
* Returns a stream which sends async notifications each time a transaction
is created or one is received that pays to us.
Expand Down