mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-03-04 09:48:19 +01:00
walletrpc: expose wallet import related RPCs
This commit is contained in:
parent
2d163b788b
commit
5301c7e83f
6 changed files with 1601 additions and 146 deletions
|
@ -275,6 +275,9 @@ http:
|
|||
- selector: walletrpc.WalletKit.DeriveKey
|
||||
post: "/v2/wallet/key"
|
||||
body: "*"
|
||||
- selector: walletrpc.WalletKit.ImportPublicKey
|
||||
post: "/v2/wallet/key/import"
|
||||
body: "*"
|
||||
- selector: walletrpc.WalletKit.NextAddr
|
||||
post: "/v2/wallet/address/next"
|
||||
body: "*"
|
||||
|
@ -302,6 +305,11 @@ http:
|
|||
- selector: walletrpc.WalletKit.FinalizePsbt
|
||||
post: "/v2/wallet/psbt/finalize"
|
||||
body: "*"
|
||||
- selector: walletrpc.WalletKit.ListAccounts
|
||||
get: "/v2/wallet/accounts"
|
||||
- selector: walletrpc.WalletKit.ImportAccount
|
||||
post: "/v2/wallet/accounts/import"
|
||||
body: "*"
|
||||
|
||||
# watchtowerrpc/watchtower.proto
|
||||
- selector: watchtowerrpc.Watchtower.GetInfo
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -253,6 +253,107 @@ func local_request_WalletKit_NextAddr_0(ctx context.Context, marshaler runtime.M
|
|||
|
||||
}
|
||||
|
||||
var (
|
||||
filter_WalletKit_ListAccounts_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
|
||||
)
|
||||
|
||||
func request_WalletKit_ListAccounts_0(ctx context.Context, marshaler runtime.Marshaler, client WalletKitClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq ListAccountsRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
if err := req.ParseForm(); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_WalletKit_ListAccounts_0); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
msg, err := client.ListAccounts(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func local_request_WalletKit_ListAccounts_0(ctx context.Context, marshaler runtime.Marshaler, server WalletKitServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq ListAccountsRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
if err := runtime.PopulateQueryParameters(&protoReq, req.URL.Query(), filter_WalletKit_ListAccounts_0); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
msg, err := server.ListAccounts(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func request_WalletKit_ImportAccount_0(ctx context.Context, marshaler runtime.Marshaler, client WalletKitClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq ImportAccountRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
newReader, berr := utilities.IOReaderFactory(req.Body)
|
||||
if berr != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
|
||||
}
|
||||
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
msg, err := client.ImportAccount(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func local_request_WalletKit_ImportAccount_0(ctx context.Context, marshaler runtime.Marshaler, server WalletKitServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq ImportAccountRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
newReader, berr := utilities.IOReaderFactory(req.Body)
|
||||
if berr != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
|
||||
}
|
||||
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
msg, err := server.ImportAccount(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func request_WalletKit_ImportPublicKey_0(ctx context.Context, marshaler runtime.Marshaler, client WalletKitClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq ImportPublicKeyRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
newReader, berr := utilities.IOReaderFactory(req.Body)
|
||||
if berr != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
|
||||
}
|
||||
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
msg, err := client.ImportPublicKey(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func local_request_WalletKit_ImportPublicKey_0(ctx context.Context, marshaler runtime.Marshaler, server WalletKitServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq ImportPublicKeyRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
newReader, berr := utilities.IOReaderFactory(req.Body)
|
||||
if berr != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
|
||||
}
|
||||
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
msg, err := server.ImportPublicKey(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func request_WalletKit_PublishTransaction_0(ctx context.Context, marshaler runtime.Marshaler, client WalletKitClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq Transaction
|
||||
var metadata runtime.ServerMetadata
|
||||
|
@ -707,6 +808,66 @@ func RegisterWalletKitHandlerServer(ctx context.Context, mux *runtime.ServeMux,
|
|||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_WalletKit_ListAccounts_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_WalletKit_ListAccounts_0(rctx, inboundMarshaler, server, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_WalletKit_ListAccounts_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("POST", pattern_WalletKit_ImportAccount_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_WalletKit_ImportAccount_0(rctx, inboundMarshaler, server, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_WalletKit_ImportAccount_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("POST", pattern_WalletKit_ImportPublicKey_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_WalletKit_ImportPublicKey_0(rctx, inboundMarshaler, server, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_WalletKit_ImportPublicKey_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("POST", pattern_WalletKit_PublishTransaction_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
|
@ -1068,6 +1229,66 @@ func RegisterWalletKitHandlerClient(ctx context.Context, mux *runtime.ServeMux,
|
|||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_WalletKit_ListAccounts_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
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_WalletKit_ListAccounts_0(rctx, inboundMarshaler, client, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_WalletKit_ListAccounts_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("POST", pattern_WalletKit_ImportAccount_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
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_WalletKit_ImportAccount_0(rctx, inboundMarshaler, client, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_WalletKit_ImportAccount_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("POST", pattern_WalletKit_ImportPublicKey_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
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_WalletKit_ImportPublicKey_0(rctx, inboundMarshaler, client, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_WalletKit_ImportPublicKey_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("POST", pattern_WalletKit_PublishTransaction_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
|
@ -1266,6 +1487,12 @@ var (
|
|||
|
||||
pattern_WalletKit_NextAddr_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v2", "wallet", "address", "next"}, "", runtime.AssumeColonVerbOpt(true)))
|
||||
|
||||
pattern_WalletKit_ListAccounts_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v2", "wallet", "accounts"}, "", runtime.AssumeColonVerbOpt(true)))
|
||||
|
||||
pattern_WalletKit_ImportAccount_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v2", "wallet", "accounts", "import"}, "", runtime.AssumeColonVerbOpt(true)))
|
||||
|
||||
pattern_WalletKit_ImportPublicKey_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v2", "wallet", "key", "import"}, "", runtime.AssumeColonVerbOpt(true)))
|
||||
|
||||
pattern_WalletKit_PublishTransaction_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v2", "wallet", "tx"}, "", runtime.AssumeColonVerbOpt(true)))
|
||||
|
||||
pattern_WalletKit_SendOutputs_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v2", "wallet", "send"}, "", runtime.AssumeColonVerbOpt(true)))
|
||||
|
@ -1300,6 +1527,12 @@ var (
|
|||
|
||||
forward_WalletKit_NextAddr_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_WalletKit_ListAccounts_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_WalletKit_ImportAccount_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_WalletKit_ImportPublicKey_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_WalletKit_PublishTransaction_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_WalletKit_SendOutputs_0 = runtime.ForwardResponseMessage
|
||||
|
|
|
@ -55,6 +55,50 @@ service WalletKit {
|
|||
*/
|
||||
rpc NextAddr (AddrRequest) returns (AddrResponse);
|
||||
|
||||
/*
|
||||
ListAccounts retrieves all accounts belonging to the wallet by default. A
|
||||
name and key scope filter can be provided to filter through all of the
|
||||
wallet accounts and return only those matching.
|
||||
*/
|
||||
rpc ListAccounts (ListAccountsRequest) returns (ListAccountsResponse);
|
||||
|
||||
/*
|
||||
ImportAccount imports an account backed by an account extended public key.
|
||||
The master key fingerprint denotes the fingerprint of the root key
|
||||
corresponding to the account public key (also known as the key with
|
||||
derivation path m/). This may be required by some hardware wallets for
|
||||
proper identification and signing.
|
||||
|
||||
The address type can usually be inferred from the key's version, but may be
|
||||
required for certain keys to map them into the proper scope.
|
||||
|
||||
For BIP-0044 keys, an address type must be specified as we intend to not
|
||||
support importing BIP-0044 keys into the wallet using the legacy
|
||||
pay-to-pubkey-hash (P2PKH) scheme. A nested witness address type will force
|
||||
the standard BIP-0049 derivation scheme, while a witness address type will
|
||||
force the standard BIP-0084 derivation scheme.
|
||||
|
||||
For BIP-0049 keys, an address type must also be specified to make a
|
||||
distinction between the standard BIP-0049 address schema (nested witness
|
||||
pubkeys everywhere) and our own BIP-0049Plus address schema (nested pubkeys
|
||||
externally, witness pubkeys internally).
|
||||
|
||||
NOTE: Events (deposits/spends) for keys derived from an account will only be
|
||||
detected by lnd if they happen after the import. Rescans to detect past
|
||||
events will be supported later on.
|
||||
*/
|
||||
rpc ImportAccount (ImportAccountRequest) returns (ImportAccountResponse);
|
||||
|
||||
/*
|
||||
ImportPublicKey imports a public key as watch-only into the wallet.
|
||||
|
||||
NOTE: Events (deposits/spends) for a key will only be detected by lnd if
|
||||
they happen after the import. Rescans to detect past events will be
|
||||
supported later on.
|
||||
*/
|
||||
rpc ImportPublicKey (ImportPublicKeyRequest)
|
||||
returns (ImportPublicKeyResponse);
|
||||
|
||||
/*
|
||||
PublishTransaction attempts to publish the passed transaction to the
|
||||
network. Once this returns without an error, the wallet will continually
|
||||
|
@ -250,6 +294,113 @@ message AddrResponse {
|
|||
string addr = 1;
|
||||
}
|
||||
|
||||
enum AddressType {
|
||||
UNKNOWN = 0;
|
||||
WITNESS_PUBKEY_HASH = 1;
|
||||
NESTED_WITNESS_PUBKEY_HASH = 2;
|
||||
HYBRID_NESTED_WITNESS_PUBKEY_HASH = 3;
|
||||
}
|
||||
message Account {
|
||||
// The name used to identify the account.
|
||||
string name = 1;
|
||||
|
||||
/*
|
||||
The type of addresses the account supports.
|
||||
AddressType | External Branch | Internal Branch
|
||||
---------------------------------------------------------------------
|
||||
WITNESS_PUBKEY_HASH | P2WPKH | P2WPKH
|
||||
NESTED_WITNESS_PUBKEY_HASH | NP2WPKH | NP2WPKH
|
||||
HYBRID_NESTED_WITNESS_PUBKEY_HASH | NP2WPKH | P2WPKH
|
||||
*/
|
||||
AddressType address_type = 2;
|
||||
|
||||
/*
|
||||
The public key backing the account that all keys are derived from
|
||||
represented as an extended key. This will always be empty for the default
|
||||
imported account in which single public keys are imported into.
|
||||
*/
|
||||
string extended_public_key = 3;
|
||||
|
||||
/*
|
||||
The fingerprint of the root key from which the account public key was
|
||||
derived from. This will always be zero for the default imported account in
|
||||
which single public keys are imported into.
|
||||
*/
|
||||
uint32 master_key_fingerprint = 4;
|
||||
|
||||
/*
|
||||
The derivation path corresponding to the account public key. This will
|
||||
always be empty for the default imported account in which single public keys
|
||||
are imported into.
|
||||
*/
|
||||
string derivation_path = 5;
|
||||
|
||||
/*
|
||||
The number of keys derived from the external branch of the account public
|
||||
key. This will always be zero for the default imported account in which
|
||||
single public keys are imported into.
|
||||
*/
|
||||
uint32 external_key_count = 6;
|
||||
|
||||
/*
|
||||
The number of keys derived from the internal branch of the account public
|
||||
key. This will always be zero for the default imported account in which
|
||||
single public keys are imported into.
|
||||
*/
|
||||
uint32 internal_key_count = 7;
|
||||
|
||||
// Whether the wallet stores private keys for the account.
|
||||
bool watch_only = 8;
|
||||
}
|
||||
message ListAccountsRequest {
|
||||
// An optional filter to only return accounts matching this name.
|
||||
string name = 1;
|
||||
|
||||
// An optional filter to only return accounts matching this address type.
|
||||
AddressType address_type = 2;
|
||||
}
|
||||
message ListAccountsResponse {
|
||||
repeated Account accounts = 1;
|
||||
}
|
||||
|
||||
message ImportAccountRequest {
|
||||
// A name to identify the account with.
|
||||
string name = 1;
|
||||
|
||||
/*
|
||||
A public key that corresponds to a wallet account represented as an extended
|
||||
key. It must conform to a derivation path of the form
|
||||
m/purpose'/coin_type'/account'.
|
||||
*/
|
||||
string extended_public_key = 2;
|
||||
|
||||
/*
|
||||
The fingerprint of the root key (also known as the key with derivation path
|
||||
m/) from which the account public key was derived from. This may be required
|
||||
by some hardware wallets for proper identification and signing.
|
||||
*/
|
||||
uint32 master_key_fingerprint = 3;
|
||||
|
||||
/*
|
||||
An address type is only required when the extended account public key has a
|
||||
legacy version (xpub, tpub, etc.), such that the wallet cannot detect what
|
||||
address scheme it belongs to.
|
||||
*/
|
||||
AddressType address_type = 4;
|
||||
}
|
||||
message ImportAccountResponse {
|
||||
}
|
||||
|
||||
message ImportPublicKeyRequest {
|
||||
// A compressed public key represented as raw bytes.
|
||||
bytes public_key = 1;
|
||||
|
||||
// The type of address that will be generated from the public key.
|
||||
AddressType address_type = 2;
|
||||
}
|
||||
message ImportPublicKeyResponse {
|
||||
}
|
||||
|
||||
message Transaction {
|
||||
/*
|
||||
The raw serialized transaction.
|
||||
|
|
|
@ -11,6 +11,86 @@
|
|||
"application/json"
|
||||
],
|
||||
"paths": {
|
||||
"/v2/wallet/accounts": {
|
||||
"get": {
|
||||
"summary": "ListAccounts retrieves all accounts belonging to the wallet by default. A\nname and key scope filter can be provided to filter through all of the\nwallet accounts and return only those matching.",
|
||||
"operationId": "ListAccounts",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/walletrpcListAccountsResponse"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/runtimeError"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "name",
|
||||
"description": "An optional filter to only return accounts matching this name.",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "address_type",
|
||||
"description": "An optional filter to only return accounts matching this address type.",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"UNKNOWN",
|
||||
"WITNESS_PUBKEY_HASH",
|
||||
"NESTED_WITNESS_PUBKEY_HASH",
|
||||
"HYBRID_NESTED_WITNESS_PUBKEY_HASH"
|
||||
],
|
||||
"default": "UNKNOWN"
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"WalletKit"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/v2/wallet/accounts/import": {
|
||||
"post": {
|
||||
"summary": "ImportAccount imports an account backed by an account extended public key.\nThe master key fingerprint denotes the fingerprint of the root key\ncorresponding to the account public key (also known as the key with\nderivation path m/). This may be required by some hardware wallets for\nproper identification and signing.",
|
||||
"description": "The address type can usually be inferred from the key's version, but may be\nrequired for certain keys to map them into the proper scope.\n\nFor BIP-0044 keys, an address type must be specified as we intend to not\nsupport importing BIP-0044 keys into the wallet using the legacy\npay-to-pubkey-hash (P2PKH) scheme. A nested witness address type will force\nthe standard BIP-0049 derivation scheme, while a witness address type will\nforce the standard BIP-0084 derivation scheme.\n\nFor BIP-0049 keys, an address type must also be specified to make a\ndistinction between the standard BIP-0049 address schema (nested witness\npubkeys everywhere) and our own BIP-0049Plus address schema (nested pubkeys\nexternally, witness pubkeys internally).\n\nNOTE: Events (deposits/spends) for keys derived from an account will only be\ndetected by lnd if they happen after the import. Rescans to detect past\nevents will be supported later on.",
|
||||
"operationId": "ImportAccount",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/walletrpcImportAccountResponse"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/runtimeError"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/walletrpcImportAccountRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"WalletKit"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/v2/wallet/address/next": {
|
||||
"post": {
|
||||
"summary": "NextAddr returns the next unused address within the wallet.",
|
||||
|
@ -144,6 +224,40 @@
|
|||
]
|
||||
}
|
||||
},
|
||||
"/v2/wallet/key/import": {
|
||||
"post": {
|
||||
"summary": "ImportPublicKey imports a public key as watch-only into the wallet.",
|
||||
"description": "NOTE: Events (deposits/spends) for a key will only be detected by lnd if\nthey happen after the import. Rescans to detect past events will be\nsupported later on.",
|
||||
"operationId": "ImportPublicKey",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/walletrpcImportPublicKeyResponse"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/runtimeError"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/walletrpcImportPublicKeyRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"WalletKit"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/v2/wallet/key/next": {
|
||||
"post": {
|
||||
"summary": "DeriveNextKey attempts to derive the *next* key within the key family\n(account in BIP43) specified. This method should return the next external\nchild within this branch.",
|
||||
|
@ -731,6 +845,47 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"walletrpcAccount": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "The name used to identify the account."
|
||||
},
|
||||
"address_type": {
|
||||
"$ref": "#/definitions/walletrpcAddressType",
|
||||
"title": "The type of addresses the account supports.\nAddressType | External Branch | Internal Branch\n---------------------------------------------------------------------\nWITNESS_PUBKEY_HASH | P2WPKH | P2WPKH\nNESTED_WITNESS_PUBKEY_HASH | NP2WPKH | NP2WPKH\nHYBRID_NESTED_WITNESS_PUBKEY_HASH | NP2WPKH | P2WPKH"
|
||||
},
|
||||
"extended_public_key": {
|
||||
"type": "string",
|
||||
"description": "The public key backing the account that all keys are derived from\nrepresented as an extended key. This will always be empty for the default\nimported account in which single public keys are imported into."
|
||||
},
|
||||
"master_key_fingerprint": {
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"description": "The fingerprint of the root key from which the account public key was\nderived from. This will always be zero for the default imported account in\nwhich single public keys are imported into."
|
||||
},
|
||||
"derivation_path": {
|
||||
"type": "string",
|
||||
"description": "The derivation path corresponding to the account public key. This will\nalways be empty for the default imported account in which single public keys\nare imported into."
|
||||
},
|
||||
"external_key_count": {
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"description": "The number of keys derived from the external branch of the account public\nkey. This will always be zero for the default imported account in which\nsingle public keys are imported into."
|
||||
},
|
||||
"internal_key_count": {
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"description": "The number of keys derived from the internal branch of the account public\nkey. This will always be zero for the default imported account in which\nsingle public keys are imported into."
|
||||
},
|
||||
"watch_only": {
|
||||
"type": "boolean",
|
||||
"format": "boolean",
|
||||
"description": "Whether the wallet stores private keys for the account."
|
||||
}
|
||||
}
|
||||
},
|
||||
"walletrpcAddrRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
@ -749,6 +904,16 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"walletrpcAddressType": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"UNKNOWN",
|
||||
"WITNESS_PUBKEY_HASH",
|
||||
"NESTED_WITNESS_PUBKEY_HASH",
|
||||
"HYBRID_NESTED_WITNESS_PUBKEY_HASH"
|
||||
],
|
||||
"default": "UNKNOWN"
|
||||
},
|
||||
"walletrpcBumpFeeRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
@ -870,6 +1035,48 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"walletrpcImportAccountRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "A name to identify the account with."
|
||||
},
|
||||
"extended_public_key": {
|
||||
"type": "string",
|
||||
"description": "A public key that corresponds to a wallet account represented as an extended\nkey. It must conform to a derivation path of the form\nm/purpose'/coin_type'/account'."
|
||||
},
|
||||
"master_key_fingerprint": {
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"description": "The fingerprint of the root key (also known as the key with derivation path\nm/) from which the account public key was derived from. This may be required\nby some hardware wallets for proper identification and signing."
|
||||
},
|
||||
"address_type": {
|
||||
"$ref": "#/definitions/walletrpcAddressType",
|
||||
"description": "An address type is only required when the extended account public key has a\nlegacy version (xpub, tpub, etc.), such that the wallet cannot detect what\naddress scheme it belongs to."
|
||||
}
|
||||
}
|
||||
},
|
||||
"walletrpcImportAccountResponse": {
|
||||
"type": "object"
|
||||
},
|
||||
"walletrpcImportPublicKeyRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"public_key": {
|
||||
"type": "string",
|
||||
"format": "byte",
|
||||
"description": "A compressed public key represented as raw bytes."
|
||||
},
|
||||
"address_type": {
|
||||
"$ref": "#/definitions/walletrpcAddressType",
|
||||
"description": "The type of address that will be generated from the public key."
|
||||
}
|
||||
}
|
||||
},
|
||||
"walletrpcImportPublicKeyResponse": {
|
||||
"type": "object"
|
||||
},
|
||||
"walletrpcKeyReq": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
@ -936,6 +1143,17 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"walletrpcListAccountsResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"accounts": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/walletrpcAccount"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"walletrpcListLeasesResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
|
|
@ -12,11 +12,14 @@ import (
|
|||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/btcsuite/btcd/btcec"
|
||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||
"github.com/btcsuite/btcd/txscript"
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/btcsuite/btcutil"
|
||||
"github.com/btcsuite/btcutil/hdkeychain"
|
||||
"github.com/btcsuite/btcutil/psbt"
|
||||
"github.com/btcsuite/btcwallet/waddrmgr"
|
||||
"github.com/btcsuite/btcwallet/wtxmgr"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/runtime"
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
|
@ -128,6 +131,18 @@ var (
|
|||
Entity: "onchain",
|
||||
Action: "write",
|
||||
}},
|
||||
"/walletrpc.WalletKit/ListAccounts": {{
|
||||
Entity: "onchain",
|
||||
Action: "read",
|
||||
}},
|
||||
"/walletrpc.WalletKit/ImportAccount": {{
|
||||
Entity: "onchain",
|
||||
Action: "write",
|
||||
}},
|
||||
"/walletrpc.WalletKit/ImportPublicKey": {{
|
||||
Entity: "onchain",
|
||||
Action: "write",
|
||||
}},
|
||||
}
|
||||
|
||||
// DefaultWalletKitMacFilename is the default name of the wallet kit
|
||||
|
@ -1215,3 +1230,198 @@ func (w *WalletKit) FinalizePsbt(_ context.Context,
|
|||
RawFinalTx: finalTxBytes.Bytes(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// marshalWalletAccount converts the properties of an account into its RPC
|
||||
// representation.
|
||||
func marshalWalletAccount(account *waddrmgr.AccountProperties) (*Account, error) {
|
||||
var addrType AddressType
|
||||
switch account.KeyScope {
|
||||
case waddrmgr.KeyScopeBIP0049Plus:
|
||||
// No address schema present represents the traditional BIP-0049
|
||||
// address derivation scheme.
|
||||
if account.AddrSchema == nil {
|
||||
addrType = AddressType_HYBRID_NESTED_WITNESS_PUBKEY_HASH
|
||||
break
|
||||
}
|
||||
|
||||
switch account.AddrSchema {
|
||||
case &waddrmgr.KeyScopeBIP0049AddrSchema:
|
||||
addrType = AddressType_NESTED_WITNESS_PUBKEY_HASH
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported address schema %v",
|
||||
*account.AddrSchema)
|
||||
}
|
||||
|
||||
case waddrmgr.KeyScopeBIP0084:
|
||||
addrType = AddressType_WITNESS_PUBKEY_HASH
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("account %v has unsupported "+
|
||||
"key scope %v", account.AccountName, account.KeyScope)
|
||||
}
|
||||
|
||||
rpcAccount := &Account{
|
||||
Name: account.AccountName,
|
||||
AddressType: addrType,
|
||||
ExternalKeyCount: account.ExternalKeyCount,
|
||||
InternalKeyCount: account.InternalKeyCount,
|
||||
WatchOnly: account.IsWatchOnly,
|
||||
}
|
||||
|
||||
// The remaining fields can only be done on accounts other than the
|
||||
// default imported one existing within each key scope.
|
||||
if account.AccountName != waddrmgr.ImportedAddrAccountName {
|
||||
nonHardenedIndex := account.AccountPubKey.ChildIndex() -
|
||||
hdkeychain.HardenedKeyStart
|
||||
rpcAccount.ExtendedPublicKey = account.AccountPubKey.String()
|
||||
rpcAccount.MasterKeyFingerprint = account.MasterKeyFingerprint
|
||||
rpcAccount.DerivationPath = fmt.Sprintf("%v/%v'",
|
||||
account.KeyScope, nonHardenedIndex)
|
||||
}
|
||||
|
||||
return rpcAccount, nil
|
||||
}
|
||||
|
||||
// ListAccounts retrieves all accounts belonging to the wallet by default. A
|
||||
// name and key scope filter can be provided to filter through all of the wallet
|
||||
// accounts and return only those matching.
|
||||
func (w *WalletKit) ListAccounts(ctx context.Context,
|
||||
req *ListAccountsRequest) (*ListAccountsResponse, error) {
|
||||
|
||||
// Map the supported address types into their corresponding key scope.
|
||||
var keyScopeFilter *waddrmgr.KeyScope
|
||||
switch req.AddressType {
|
||||
case AddressType_UNKNOWN:
|
||||
break
|
||||
|
||||
case AddressType_WITNESS_PUBKEY_HASH:
|
||||
keyScope := waddrmgr.KeyScopeBIP0084
|
||||
keyScopeFilter = &keyScope
|
||||
|
||||
case AddressType_NESTED_WITNESS_PUBKEY_HASH,
|
||||
AddressType_HYBRID_NESTED_WITNESS_PUBKEY_HASH:
|
||||
|
||||
keyScope := waddrmgr.KeyScopeBIP0049Plus
|
||||
keyScopeFilter = &keyScope
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("unhandled address type %v", req.AddressType)
|
||||
}
|
||||
|
||||
accounts, err := w.cfg.Wallet.ListAccounts(req.Name, keyScopeFilter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rpcAccounts := make([]*Account, 0, len(accounts))
|
||||
for _, account := range accounts {
|
||||
// Don't include the default imported accounts created by the
|
||||
// wallet in the response if they don't have any keys imported.
|
||||
if account.AccountName == waddrmgr.ImportedAddrAccountName &&
|
||||
account.ImportedKeyCount == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
rpcAccount, err := marshalWalletAccount(account)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rpcAccounts = append(rpcAccounts, rpcAccount)
|
||||
}
|
||||
|
||||
return &ListAccountsResponse{Accounts: rpcAccounts}, nil
|
||||
}
|
||||
|
||||
// parseAddrType parses an address type from its RPC representation to a
|
||||
// *waddrmgr.AddressType.
|
||||
func parseAddrType(addrType AddressType,
|
||||
required bool) (*waddrmgr.AddressType, error) {
|
||||
|
||||
switch addrType {
|
||||
case AddressType_UNKNOWN:
|
||||
if required {
|
||||
return nil, errors.New("an address type must be specified")
|
||||
}
|
||||
return nil, nil
|
||||
|
||||
case AddressType_WITNESS_PUBKEY_HASH:
|
||||
addrTyp := waddrmgr.WitnessPubKey
|
||||
return &addrTyp, nil
|
||||
|
||||
case AddressType_NESTED_WITNESS_PUBKEY_HASH:
|
||||
addrTyp := waddrmgr.NestedWitnessPubKey
|
||||
return &addrTyp, nil
|
||||
|
||||
case AddressType_HYBRID_NESTED_WITNESS_PUBKEY_HASH:
|
||||
addrTyp := waddrmgr.WitnessPubKey
|
||||
return &addrTyp, nil
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("unhandled address type %v", addrType)
|
||||
}
|
||||
}
|
||||
|
||||
// ImportAccount imports an account backed by an account extended public key.
|
||||
// The master key fingerprint denotes the fingerprint of the root key
|
||||
// corresponding to the account public key (also known as the key with
|
||||
// derivation path m/). This may be required by some hardware wallets for proper
|
||||
// identification and signing.
|
||||
//
|
||||
// The address type can usually be inferred from the key's version, but may be
|
||||
// required for certain keys to map them into the proper scope.
|
||||
//
|
||||
// For BIP-0044 keys, an address type must be specified as we intend to not
|
||||
// support importing BIP-0044 keys into the wallet using the legacy
|
||||
// pay-to-pubkey-hash (P2PKH) scheme. A nested witness address type will force
|
||||
// the standard BIP-0049 derivation scheme, while a witness address type will
|
||||
// force the standard BIP-0084 derivation scheme.
|
||||
//
|
||||
// For BIP-0049 keys, an address type must also be specified to make a
|
||||
// distinction between the standard BIP-0049 address schema (nested witness
|
||||
// pubkeys everywhere) and our own BIP-0049Plus address schema (nested pubkeys
|
||||
// externally, witness pubkeys internally).
|
||||
func (w *WalletKit) ImportAccount(ctx context.Context,
|
||||
req *ImportAccountRequest) (*ImportAccountResponse, error) {
|
||||
|
||||
accountPubKey, err := hdkeychain.NewKeyFromString(req.ExtendedPublicKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
addrType, err := parseAddrType(req.AddressType, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = w.cfg.Wallet.ImportAccount(
|
||||
req.Name, accountPubKey, req.MasterKeyFingerprint, addrType,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &ImportAccountResponse{}, nil
|
||||
}
|
||||
|
||||
// ImportPublicKey imports a single derived public key into the wallet. The
|
||||
// address type can usually be inferred from the key's version, but in the case
|
||||
// of legacy versions (xpub, tpub), an address type must be specified as we
|
||||
// intend to not support importing BIP-44 keys into the wallet using the legacy
|
||||
// pay-to-pubkey-hash (P2PKH) scheme.
|
||||
func (w *WalletKit) ImportPublicKey(ctx context.Context,
|
||||
req *ImportPublicKeyRequest) (*ImportPublicKeyResponse, error) {
|
||||
|
||||
pubKey, err := btcec.ParsePubKey(req.PublicKey, btcec.S256())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
addrType, err := parseAddrType(req.AddressType, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := w.cfg.Wallet.ImportPublicKey(pubKey, *addrType); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &ImportPublicKeyResponse{}, nil
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue