mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-03-26 01:33:02 +01:00
Add listunspent RPC call
Returns a brief json summary of each utxo found by calling ListUnspentWitness in the wallet. The two arguments are the minimum and maximum number of conrfirmations (0=include unconfirmed)
This commit is contained in:
parent
71444e74ac
commit
9bb2a26948
@ -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)
|
||||
@ -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")
|
||||
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",
|
||||
|
@ -256,6 +256,7 @@ func main() {
|
||||
newAddressCommand,
|
||||
sendManyCommand,
|
||||
sendCoinsCommand,
|
||||
listUnspentCommand,
|
||||
connectCommand,
|
||||
disconnectCommand,
|
||||
openChannelCommand,
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
1236
lnrpc/rpc.pb.go
1236
lnrpc/rpc.pb.go
File diff suppressed because it is too large
Load Diff
@ -124,6 +124,23 @@ func request_Lightning_SendCoins_0(ctx context.Context, marshaler runtime.Marsha
|
||||
|
||||
}
|
||||
|
||||
var (
|
||||
filter_Lightning_ListUnspent_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
|
||||
)
|
||||
|
||||
func request_Lightning_ListUnspent_0(ctx context.Context, marshaler runtime.Marshaler, client LightningClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq ListUnspentRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
if err := runtime.PopulateQueryParameters(&protoReq, req.URL.Query(), filter_Lightning_ListUnspent_0); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
msg, err := client.ListUnspent(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
var (
|
||||
filter_Lightning_NewAddress_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
|
||||
)
|
||||
@ -1018,6 +1035,35 @@ func RegisterLightningHandler(ctx context.Context, mux *runtime.ServeMux, conn *
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_Lightning_ListUnspent_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
defer cancel()
|
||||
if cn, ok := w.(http.CloseNotifier); ok {
|
||||
go func(done <-chan struct{}, closed <-chan bool) {
|
||||
select {
|
||||
case <-done:
|
||||
case <-closed:
|
||||
cancel()
|
||||
}
|
||||
}(ctx.Done(), cn.CloseNotify())
|
||||
}
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_Lightning_ListUnspent_0(rctx, inboundMarshaler, client, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_Lightning_ListUnspent_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_Lightning_NewAddress_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
defer cancel()
|
||||
@ -1900,6 +1946,8 @@ var (
|
||||
|
||||
pattern_Lightning_SendCoins_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "transactions"}, ""))
|
||||
|
||||
pattern_Lightning_ListUnspent_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "utxos"}, ""))
|
||||
|
||||
pattern_Lightning_NewAddress_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "newaddress"}, ""))
|
||||
|
||||
pattern_Lightning_SignMessage_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "signmessage"}, ""))
|
||||
@ -1970,6 +2018,8 @@ var (
|
||||
|
||||
forward_Lightning_SendCoins_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_Lightning_ListUnspent_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_Lightning_NewAddress_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_Lightning_SignMessage_0 = runtime.ForwardResponseMessage
|
||||
|
@ -231,6 +231,16 @@ service Lightning {
|
||||
};
|
||||
}
|
||||
|
||||
/** lncli: `listunspent`
|
||||
ListUnspent returns a list of all utxos spendable by the wallet with a
|
||||
number of confirmations between the specified minimum and maximum.
|
||||
*/
|
||||
rpc ListUnspent (ListUnspentRequest) returns (ListUnspentResponse) {
|
||||
option (google.api.http) = {
|
||||
get: "/v1/utxos"
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
SubscribeTransactions creates a uni-directional stream from the server to
|
||||
the client in which any newly discovered transactions relevant to the
|
||||
@ -657,6 +667,28 @@ service Lightning {
|
||||
};
|
||||
}
|
||||
|
||||
message Utxo {
|
||||
/// The type of address
|
||||
AddressType type = 1 [json_name = "address_type"];
|
||||
|
||||
/// The address
|
||||
string address = 2 [json_name = "address"];
|
||||
|
||||
/// The value of the unspent coin in satoshis
|
||||
int64 amount_sat = 3 [json_name = "amount_sat"];
|
||||
|
||||
/// The scriptpubkey in hex
|
||||
string script_pubkey = 4 [json_name = "script_pubkey"];
|
||||
|
||||
/// The outpoint in format txid:n
|
||||
/// Note that this reuses the `ChannelPoint` message but
|
||||
/// is not actually a channel related outpoint, of course
|
||||
ChannelPoint outpoint = 5 [json_name = "outpoint"];
|
||||
|
||||
/// The number of confirmations for the Utxo
|
||||
int64 confirmations = 6 [json_name = "confirmations"];
|
||||
}
|
||||
|
||||
message Transaction {
|
||||
/// The transaction hash
|
||||
string tx_hash = 1 [ json_name = "tx_hash" ];
|
||||
@ -808,18 +840,31 @@ message SendCoinsResponse {
|
||||
string txid = 1 [json_name = "txid"];
|
||||
}
|
||||
|
||||
message ListUnspentRequest {
|
||||
/// The minimum number of confirmations to be included.
|
||||
int32 min_confs = 1;
|
||||
|
||||
/// The maximum number of confirmations to be included.
|
||||
int32 max_confs = 2;
|
||||
}
|
||||
message ListUnspentResponse {
|
||||
/// A list of utxos
|
||||
repeated Utxo utxos = 1 [json_name = "utxos"];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
`AddressType` has to be one of:
|
||||
|
||||
- `p2wkh`: Pay to witness key hash (`WITNESS_PUBKEY_HASH` = 0)
|
||||
- `np2wkh`: Pay to nested witness key hash (`NESTED_PUBKEY_HASH` = 1)
|
||||
*/
|
||||
message NewAddressRequest {
|
||||
enum AddressType {
|
||||
enum AddressType {
|
||||
WITNESS_PUBKEY_HASH = 0;
|
||||
NESTED_PUBKEY_HASH = 1;
|
||||
}
|
||||
}
|
||||
|
||||
message NewAddressRequest {
|
||||
/// The address type
|
||||
AddressType type = 1;
|
||||
}
|
||||
|
@ -1051,6 +1051,41 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"/v1/utxos": {
|
||||
"get": {
|
||||
"summary": "* lncli: `listunspent`\nListUnspent returns a list of all utxos spendable by the wallet with a\nnumber of confirmations between the specified minimum and maximum.",
|
||||
"operationId": "ListUnspent",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/lnrpcListUnspentResponse"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "min_confs",
|
||||
"description": "/ The minimum number of confirmations to be included.",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
{
|
||||
"name": "max_confs",
|
||||
"description": "/ The maximum number of confirmations to be included.",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"Lightning"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/v1/verifymessage": {
|
||||
"post": {
|
||||
"summary": "* lncli: `verifymessage`\nVerifyMessage verifies a signature over a msg. The signature must be\nzbase32 encoded and signed by an active node in the resident node's\nchannel database. In addition to returning the validity of the signature,\nVerifyMessage also returns the recovered pubkey from the signature.",
|
||||
@ -1231,6 +1266,16 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"lnrpcAddressType": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"WITNESS_PUBKEY_HASH",
|
||||
"NESTED_PUBKEY_HASH"
|
||||
],
|
||||
"default": "WITNESS_PUBKEY_HASH",
|
||||
"description": "- `p2wkh`: Pay to witness key hash (`WITNESS_PUBKEY_HASH` = 0)\n- `np2wkh`: Pay to nested witness key hash (`NESTED_PUBKEY_HASH` = 1)",
|
||||
"title": "* \n`AddressType` has to be one of:"
|
||||
},
|
||||
"lnrpcChangePasswordRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@ -2194,6 +2239,18 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"lnrpcListUnspentResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"utxos": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/lnrpcUtxo"
|
||||
},
|
||||
"title": "/ A list of utxos"
|
||||
}
|
||||
}
|
||||
},
|
||||
"lnrpcNetworkInfo": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@ -2919,6 +2976,37 @@
|
||||
"lnrpcUnlockWalletResponse": {
|
||||
"type": "object"
|
||||
},
|
||||
"lnrpcUtxo": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": {
|
||||
"$ref": "#/definitions/lnrpcAddressType",
|
||||
"title": "/ The type of address"
|
||||
},
|
||||
"address": {
|
||||
"type": "string",
|
||||
"title": "/ The address"
|
||||
},
|
||||
"amount_sat": {
|
||||
"type": "string",
|
||||
"format": "int64",
|
||||
"title": "/ The value of the unspent coin in satoshis"
|
||||
},
|
||||
"script_pubkey": {
|
||||
"type": "string",
|
||||
"title": "/ The scriptpubkey in hex"
|
||||
},
|
||||
"outpoint": {
|
||||
"$ref": "#/definitions/lnrpcChannelPoint",
|
||||
"title": "/ The outpoint in format txid:n\n/ Note that this reuses the `ChannelPoint` message but\n/ is not actually a channel related outpoint, of course"
|
||||
},
|
||||
"confirmations": {
|
||||
"type": "string",
|
||||
"format": "int64",
|
||||
"title": "/ The number of confirmations for the Utxo"
|
||||
}
|
||||
}
|
||||
},
|
||||
"lnrpcVerifyMessageRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
@ -173,7 +173,7 @@ func (n *NetworkHarness) SetUp(lndArgs []string) error {
|
||||
// each.
|
||||
ctxb := context.Background()
|
||||
addrReq := &lnrpc.NewAddressRequest{
|
||||
Type: lnrpc.NewAddressRequest_WITNESS_PUBKEY_HASH,
|
||||
Type: lnrpc.AddressType_WITNESS_PUBKEY_HASH,
|
||||
}
|
||||
clients := []lnrpc.LightningClient{n.Alice, n.Bob}
|
||||
for _, client := range clients {
|
||||
@ -1200,7 +1200,7 @@ func (n *NetworkHarness) SendCoins(ctx context.Context, amt btcutil.Amount,
|
||||
target *HarnessNode) error {
|
||||
|
||||
return n.sendCoins(
|
||||
ctx, amt, target, lnrpc.NewAddressRequest_WITNESS_PUBKEY_HASH,
|
||||
ctx, amt, target, lnrpc.AddressType_WITNESS_PUBKEY_HASH,
|
||||
true,
|
||||
)
|
||||
}
|
||||
@ -1212,7 +1212,7 @@ func (n *NetworkHarness) SendCoinsUnconfirmed(ctx context.Context,
|
||||
amt btcutil.Amount, target *HarnessNode) error {
|
||||
|
||||
return n.sendCoins(
|
||||
ctx, amt, target, lnrpc.NewAddressRequest_WITNESS_PUBKEY_HASH,
|
||||
ctx, amt, target, lnrpc.AddressType_WITNESS_PUBKEY_HASH,
|
||||
false,
|
||||
)
|
||||
}
|
||||
@ -1223,7 +1223,7 @@ func (n *NetworkHarness) SendCoinsNP2WKH(ctx context.Context,
|
||||
amt btcutil.Amount, target *HarnessNode) error {
|
||||
|
||||
return n.sendCoins(
|
||||
ctx, amt, target, lnrpc.NewAddressRequest_NESTED_PUBKEY_HASH,
|
||||
ctx, amt, target, lnrpc.AddressType_NESTED_PUBKEY_HASH,
|
||||
true,
|
||||
)
|
||||
}
|
||||
@ -1232,7 +1232,7 @@ func (n *NetworkHarness) SendCoinsNP2WKH(ctx context.Context,
|
||||
// targeted lightning node. The confirmed boolean indicates whether the
|
||||
// transaction that pays to the target should confirm.
|
||||
func (n *NetworkHarness) sendCoins(ctx context.Context, amt btcutil.Amount,
|
||||
target *HarnessNode, addrType lnrpc.NewAddressRequest_AddressType,
|
||||
target *HarnessNode, addrType lnrpc.AddressType,
|
||||
confirmed bool) error {
|
||||
|
||||
balReq := &lnrpc.WalletBalanceRequest{}
|
||||
|
@ -349,6 +349,7 @@ func (b *BtcWallet) ListUnspentWitness(minConfs, maxConfs int32) (
|
||||
Hash: *txid,
|
||||
Index: output.Vout,
|
||||
},
|
||||
Confirmations: output.Confirmations,
|
||||
}
|
||||
witnessOutputs = append(witnessOutputs, utxo)
|
||||
}
|
||||
|
@ -52,6 +52,7 @@ var (
|
||||
type Utxo struct {
|
||||
AddressType AddressType
|
||||
Value btcutil.Amount
|
||||
Confirmations int64
|
||||
PkScript []byte
|
||||
RedeemScript []byte
|
||||
WitnessScript []byte
|
||||
|
89
rpcserver.go
89
rpcserver.go
@ -163,6 +163,10 @@ var (
|
||||
Entity: "onchain",
|
||||
Action: "write",
|
||||
}},
|
||||
"/lnrpc.Lightning/ListUnspent": {{
|
||||
Entity: "onchain",
|
||||
Action: "read",
|
||||
}},
|
||||
"/lnrpc.Lightning/SendMany": {{
|
||||
Entity: "onchain",
|
||||
Action: "write",
|
||||
@ -680,6 +684,87 @@ func determineFeePerKw(feeEstimator lnwallet.FeeEstimator, targetConf int32,
|
||||
}
|
||||
}
|
||||
|
||||
// ListUnspent returns useful information about each unspent output
|
||||
// owned by the wallet, as reported by the underlying `ListUnspentWitness`;
|
||||
// the information returned is: outpoint, amount in satoshis, address,
|
||||
// address type, scriptPubKey in hex and number of confirmations.
|
||||
// The result is filtered to contain outputs whose number of confirmations
|
||||
// is between a minimum and maximum number of confirmations specified by the
|
||||
// user, with 0 meaning unconfirmed.
|
||||
func (r *rpcServer) ListUnspent(ctx context.Context,
|
||||
in *lnrpc.ListUnspentRequest) (*lnrpc.ListUnspentResponse, error) {
|
||||
minConfs := in.MinConfs
|
||||
maxConfs := in.MaxConfs
|
||||
|
||||
if minConfs < 0 {
|
||||
return nil, fmt.Errorf("min confirmations must be >= 0")
|
||||
}
|
||||
if minConfs > maxConfs {
|
||||
return nil, fmt.Errorf("max confirmations must be >= min " +
|
||||
"confirmations")
|
||||
}
|
||||
|
||||
utxos, err := r.server.cc.wallet.ListUnspentWitness(minConfs, maxConfs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp := &lnrpc.ListUnspentResponse{Utxos: []*lnrpc.Utxo{}}
|
||||
for _, utxo := range utxos {
|
||||
// Translate lnwallet address type to gRPC proto address type:
|
||||
var addrType lnrpc.AddressType
|
||||
switch utxo.AddressType {
|
||||
case lnwallet.WitnessPubKey:
|
||||
addrType = lnrpc.AddressType_WITNESS_PUBKEY_HASH
|
||||
case lnwallet.NestedWitnessPubKey:
|
||||
addrType = lnrpc.AddressType_NESTED_PUBKEY_HASH
|
||||
case lnwallet.UnknownAddressType:
|
||||
rpcsLog.Warnf("[listunspent] utxo with address of unknown "+
|
||||
"type ignored: %v", utxo.OutPoint.String())
|
||||
continue
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid utxo address type")
|
||||
}
|
||||
|
||||
outpoint := &lnrpc.ChannelPoint{
|
||||
FundingTxid: &lnrpc.ChannelPoint_FundingTxidStr{
|
||||
FundingTxidStr: utxo.OutPoint.Hash.String(),
|
||||
},
|
||||
OutputIndex: utxo.OutPoint.Index,
|
||||
}
|
||||
|
||||
utxoResp := lnrpc.Utxo{
|
||||
Type: addrType,
|
||||
AmountSat: int64(utxo.Value),
|
||||
ScriptPubkey: hex.EncodeToString(utxo.PkScript),
|
||||
Outpoint: outpoint,
|
||||
Confirmations: utxo.Confirmations,
|
||||
}
|
||||
|
||||
_, outAddresses, _, err := txscript.ExtractPkScriptAddrs(
|
||||
utxo.PkScript, activeNetParams.Params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(outAddresses) != 1 {
|
||||
return nil, fmt.Errorf("an output was unexpectedly multisig")
|
||||
}
|
||||
|
||||
utxoResp.Address = outAddresses[0].String()
|
||||
resp.Utxos = append(resp.Utxos, &utxoResp)
|
||||
}
|
||||
|
||||
maxStr := ""
|
||||
if maxConfs != math.MaxInt32 {
|
||||
maxStr = " max=" + fmt.Sprintf("%d", maxConfs)
|
||||
}
|
||||
rpcsLog.Debugf("[listunspent] min=%v%v, generated utxos: %v",
|
||||
minConfs, maxStr, utxos)
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// SendCoins executes a request to send coins to a particular address. Unlike
|
||||
// SendMany, this RPC call only allows creating a single output at a time.
|
||||
func (r *rpcServer) SendCoins(ctx context.Context,
|
||||
@ -743,9 +828,9 @@ func (r *rpcServer) NewAddress(ctx context.Context,
|
||||
// available address types.
|
||||
var addrType lnwallet.AddressType
|
||||
switch in.Type {
|
||||
case lnrpc.NewAddressRequest_WITNESS_PUBKEY_HASH:
|
||||
case lnrpc.AddressType_WITNESS_PUBKEY_HASH:
|
||||
addrType = lnwallet.WitnessPubKey
|
||||
case lnrpc.NewAddressRequest_NESTED_PUBKEY_HASH:
|
||||
case lnrpc.AddressType_NESTED_PUBKEY_HASH:
|
||||
addrType = lnwallet.NestedWitnessPubKey
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user