mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-03-28 02:33:22 +01:00
lnrpc: revamp the WalletUnlocker service to have a two-stage init
In this commit, we revamp the WalletUnlocker service to now have a two-stage init process. The first (optional) is for the user instantiating a new lnd instance to call the GenSeed method with an optional aezeed passphrase. The response to this will be a freshly generated aezeed mnemonic along with the original enciphered seed. The second step will be the actual wallet initaliztion. By separating this step from seed generation, UI's will be able to ensure that the user has written down the seed, before proceeding and committing the seed to the internal wallet. The new method InitWallet accepts a wallet passphrase, the aezeed mnemonic, and the optional passphrase.
This commit is contained in:
parent
9d34fa8c1e
commit
7f953bf0b9
1069
lnrpc/rpc.pb.go
1069
lnrpc/rpc.pb.go
File diff suppressed because it is too large
Load Diff
@ -28,15 +28,32 @@ var _ status.Status
|
||||
var _ = runtime.String
|
||||
var _ = utilities.NewDoubleArray
|
||||
|
||||
func request_WalletUnlocker_CreateWallet_0(ctx context.Context, marshaler runtime.Marshaler, client WalletUnlockerClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq CreateWalletRequest
|
||||
var (
|
||||
filter_WalletUnlocker_GenSeed_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
|
||||
)
|
||||
|
||||
func request_WalletUnlocker_GenSeed_0(ctx context.Context, marshaler runtime.Marshaler, client WalletUnlockerClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq GenSeedRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
if err := runtime.PopulateQueryParameters(&protoReq, req.URL.Query(), filter_WalletUnlocker_GenSeed_0); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
msg, err := client.GenSeed(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func request_WalletUnlocker_InitWallet_0(ctx context.Context, marshaler runtime.Marshaler, client WalletUnlockerClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq InitWalletRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
msg, err := client.CreateWallet(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
msg, err := client.InitWallet(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
@ -564,7 +581,7 @@ func RegisterWalletUnlockerHandlerFromEndpoint(ctx context.Context, mux *runtime
|
||||
func RegisterWalletUnlockerHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
|
||||
client := NewWalletUnlockerClient(conn)
|
||||
|
||||
mux.Handle("POST", pattern_WalletUnlocker_CreateWallet_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
mux.Handle("GET", pattern_WalletUnlocker_GenSeed_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 {
|
||||
@ -582,14 +599,43 @@ func RegisterWalletUnlockerHandler(ctx context.Context, mux *runtime.ServeMux, c
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_WalletUnlocker_CreateWallet_0(rctx, inboundMarshaler, client, req, pathParams)
|
||||
resp, md, err := request_WalletUnlocker_GenSeed_0(rctx, inboundMarshaler, client, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_WalletUnlocker_CreateWallet_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
forward_WalletUnlocker_GenSeed_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("POST", pattern_WalletUnlocker_InitWallet_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_WalletUnlocker_InitWallet_0(rctx, inboundMarshaler, client, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_WalletUnlocker_InitWallet_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
@ -626,13 +672,17 @@ func RegisterWalletUnlockerHandler(ctx context.Context, mux *runtime.ServeMux, c
|
||||
}
|
||||
|
||||
var (
|
||||
pattern_WalletUnlocker_CreateWallet_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "createwallet"}, ""))
|
||||
pattern_WalletUnlocker_GenSeed_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "genseed"}, ""))
|
||||
|
||||
pattern_WalletUnlocker_InitWallet_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "initwallet"}, ""))
|
||||
|
||||
pattern_WalletUnlocker_UnlockWallet_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "unlockwallet"}, ""))
|
||||
)
|
||||
|
||||
var (
|
||||
forward_WalletUnlocker_CreateWallet_0 = runtime.ForwardResponseMessage
|
||||
forward_WalletUnlocker_GenSeed_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_WalletUnlocker_InitWallet_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_WalletUnlocker_UnlockWallet_0 = runtime.ForwardResponseMessage
|
||||
)
|
||||
|
102
lnrpc/rpc.proto
102
lnrpc/rpc.proto
@ -28,13 +28,39 @@ package lnrpc;
|
||||
// The WalletUnlocker service is used to set up a wallet password for
|
||||
// lnd at first startup, and unlock a previously set up wallet.
|
||||
service WalletUnlocker {
|
||||
/** lncli: `create`
|
||||
CreateWallet is used at lnd startup to set the encryption password for
|
||||
the wallet database.
|
||||
/**
|
||||
GenSeed is the first method that should be used to instantiate a new lnd
|
||||
instance. This method allows a caller to generate a new aezeed cipher seed
|
||||
given an optional passphrase. If provided, the passphrase will be necessary
|
||||
to decrypt the cipherseed to expose the internal wallet seed.
|
||||
|
||||
Once the cipherseed is obtained and verified by the user, the InitWallet
|
||||
method should be used to commit the newly generated seed, and create the
|
||||
wallet.
|
||||
*/
|
||||
rpc CreateWallet(CreateWalletRequest) returns (CreateWalletResponse) {
|
||||
rpc GenSeed(GenSeedRequest) returns (GenSeedResponse) {
|
||||
option (google.api.http) = {
|
||||
post: "/v1/createwallet"
|
||||
get: "/v1/genseed"
|
||||
};
|
||||
}
|
||||
|
||||
/** lncli: `init`
|
||||
InitWallet is used when lnd is starting up for the first time to fully
|
||||
initialize the daemon and its internal wallet. At the very least a wallet
|
||||
password must be provided. This will be used to encrypt sensitive material
|
||||
on disk.
|
||||
|
||||
In the case of a recovery scenario, the user can also specify their aezeed
|
||||
mnemonic and passphrase. If set, then the daemon will use this prior state
|
||||
to initialize its internal wallet.
|
||||
|
||||
Alternatively, this can be used along with the GenSeed RPC to obtain a
|
||||
seed, then present it to the user. Once it has been verified by the user,
|
||||
the seed can be fed into this RPC in order to commit the new wallet.
|
||||
*/
|
||||
rpc InitWallet(InitWalletRequest) returns (InitWalletResponse) {
|
||||
option (google.api.http) = {
|
||||
post: "/v1/initwallet"
|
||||
body: "*"
|
||||
};
|
||||
}
|
||||
@ -51,20 +77,74 @@ service WalletUnlocker {
|
||||
}
|
||||
}
|
||||
|
||||
message CreateWalletRequest {
|
||||
bytes password = 1;
|
||||
}
|
||||
message CreateWalletResponse {}
|
||||
message GenSeedRequest {
|
||||
/**
|
||||
aezeed_passphrase is an optional user provided passphrase that will be used
|
||||
to encrypt the generated aezeed cipher seed.
|
||||
*/
|
||||
bytes aezeed_passphrase = 1;
|
||||
|
||||
/**
|
||||
seed_entropy is an optional 16-bytes generated via CSPRNG. If not
|
||||
specified, then a fresh set of randomness will be used to create the seed.
|
||||
*/
|
||||
bytes seed_entropy = 2;
|
||||
}
|
||||
message GenSeedResponse {
|
||||
/**
|
||||
cipher_seed_mnemonic is a 24-word mnemonic that encodes a prior aezeed
|
||||
cipher seed obtained by the user. This field is optional, as if not
|
||||
provided, then the daemon will generate a new cipher seed for the user.
|
||||
Otherwise, then the daemon will attempt to recover the wallet state linked
|
||||
to this cipher seed.
|
||||
*/
|
||||
repeated string cipher_seed_mnemonic = 1;
|
||||
|
||||
/**
|
||||
enciphered_seed are the raw aezeed cipher seed bytes. This is the raw
|
||||
cipher text before run through our mnemonic encoding scheme.
|
||||
*/
|
||||
bytes enciphered_seed = 2;
|
||||
}
|
||||
|
||||
message InitWalletRequest {
|
||||
/**
|
||||
wallet_password is the passphrase that should be used to encrypt the
|
||||
wallet. This MUST be at least 8 chars in length. After creation, this
|
||||
password is required to unlock the daemon.
|
||||
*/
|
||||
bytes wallet_password = 1;
|
||||
|
||||
/**
|
||||
cipher_seed_mnemonic is a 24-word mnemonic that encodes a prior aezeed
|
||||
cipher seed obtained by the user. This may have been generated by the
|
||||
GenSeed method, or be an existing seed.
|
||||
*/
|
||||
repeated string cipher_seed_mnemonic = 2;
|
||||
|
||||
/**
|
||||
aezeed_passphrase is an optional user provided passphrase that will be used
|
||||
to encrypt the generated aezeed cipher seed.
|
||||
*/
|
||||
bytes aezeed_passphrase = 3;
|
||||
}
|
||||
message InitWalletResponse {
|
||||
}
|
||||
|
||||
message UnlockWalletRequest {
|
||||
bytes password = 1;
|
||||
/**
|
||||
wallet_password should be the current valid passphrase for the daemon. This
|
||||
will be required to decrypt on-disk material that the daemon requires to
|
||||
function properly.
|
||||
*/
|
||||
bytes wallet_password = 1;
|
||||
}
|
||||
message UnlockWalletResponse {}
|
||||
|
||||
service Lightning {
|
||||
/** lncli: `walletbalance`
|
||||
WalletBalance returns total unspent outputs(confirmed and unconfirmed), all confirmed unspent outputs and all unconfirmed unspent outputs under control
|
||||
WalletBalance returns total unspent outputs(confirmed and unconfirmed), all
|
||||
confirmed unspent outputs and all unconfirmed unspent outputs under control
|
||||
by the wallet. This method can be modified by having the request specify
|
||||
only witness outputs should be factored into the final output sum.
|
||||
*/
|
||||
|
@ -17,7 +17,7 @@
|
||||
"paths": {
|
||||
"/v1/balance/blockchain": {
|
||||
"get": {
|
||||
"summary": "* lncli: `walletbalance`\nWalletBalance returns total unspent outputs(confirmed and unconfirmed), all confirmed unspent outputs and all unconfirmed unspent outputs under control\nby the wallet. This method can be modified by having the request specify\nonly witness outputs should be factored into the final output sum.",
|
||||
"summary": "* lncli: `walletbalance`\nWalletBalance returns total unspent outputs(confirmed and unconfirmed), all\nconfirmed unspent outputs and all unconfirmed unspent outputs under control\nby the wallet. This method can be modified by having the request specify\nonly witness outputs should be factored into the final output sum.",
|
||||
"operationId": "WalletBalance",
|
||||
"responses": {
|
||||
"200": {
|
||||
@ -204,33 +204,6 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"/v1/createwallet": {
|
||||
"post": {
|
||||
"summary": "* lncli: `create`\nCreateWallet is used at lnd startup to set the encryption password for\nthe wallet database.",
|
||||
"operationId": "CreateWallet",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/lnrpcCreateWalletResponse"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/lnrpcCreateWalletRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"WalletUnlocker"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/v1/fees": {
|
||||
"get": {
|
||||
"summary": "* lncli: `feereport`\nFeeReport allows the caller to obtain a report detailing the current fee\nschedule enforced by the node globally for each channel.",
|
||||
@ -248,6 +221,42 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"/v1/genseed": {
|
||||
"get": {
|
||||
"summary": "*\nGenSeed is the first method that should be used to instantiate a new lnd\ninstance. This method allows a caller to generate a new aezeed cipher seed\ngiven an optional passphrase. If provided, the passphrase will be necessary\nto decrypt the cipherseed to expose the internal wallet seed.",
|
||||
"description": "Once the cipherseed is obtained and verified by the user, the InitWallet\nmethod should be used to commit the newly generated seed, and create the\nwallet.",
|
||||
"operationId": "GenSeed",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/lnrpcGenSeedResponse"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "aezeed_passphrase",
|
||||
"description": "*\naezeed_passphrase is an optional user provided passphrase that will be used\nto encrypt the generated aezeed cipher seed.",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"type": "string",
|
||||
"format": "byte"
|
||||
},
|
||||
{
|
||||
"name": "seed_entropy",
|
||||
"description": "*\nseed_entropy is an optional 16-bytes generated via CSPRNG. If not\nspecified, then a fresh set of randomness will be used to create the seed.",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"type": "string",
|
||||
"format": "byte"
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"WalletUnlocker"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/v1/getinfo": {
|
||||
"get": {
|
||||
"summary": "* lncli: `getinfo`\nGetInfo returns general information concerning the lightning node including\nit's identity pubkey, alias, the chains it is connected to, and information\nconcerning the number of open+pending channels.",
|
||||
@ -390,6 +399,34 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"/v1/initwallet": {
|
||||
"post": {
|
||||
"summary": "* lncli: `init`\nInitWallet is used when lnd is starting up for the first time to fully\ninitialize the daemon and its internal wallet. At the very least a wallet\npassword must be provided. This will be used to encrypt sensitive material\non disk.",
|
||||
"description": "In the case of a recovery scenario, the user can also specify their aezeed\nmnemonic and passphrase. If set, then the daemon will use this prior state\nto initialize its internal wallet.\n\nAlternatively, this can be used along with the GenSeed RPC to obtain a\nseed, then present it to the user. Once it has been verified by the user,\nthe seed can be fed into this RPC in order to commit the new wallet.",
|
||||
"operationId": "InitWallet",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/lnrpcInitWalletResponse"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/lnrpcInitWalletRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"WalletUnlocker"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/v1/invoice/{r_hash_str}": {
|
||||
"get": {
|
||||
"summary": "* lncli: `lookupinvoice`\nLookupInvoice attempts to look up an invoice according to its payment hash.\nThe passed payment hash *must* be exactly 32 bytes, if not, an error is\nreturned.",
|
||||
@ -1129,18 +1166,6 @@
|
||||
"lnrpcConnectPeerResponse": {
|
||||
"type": "object"
|
||||
},
|
||||
"lnrpcCreateWalletRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"password": {
|
||||
"type": "string",
|
||||
"format": "byte"
|
||||
}
|
||||
}
|
||||
},
|
||||
"lnrpcCreateWalletResponse": {
|
||||
"type": "object"
|
||||
},
|
||||
"lnrpcDebugLevelResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@ -1167,6 +1192,23 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"lnrpcGenSeedResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"cipher_seed_mnemonic": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "*\ncipher_seed_mnemonic is a 24-word mnemonic that encodes a prior aezeed\ncipher seed obtained by the user. This field is optional, as if not\nprovided, then the daemon will generate a new cipher seed for the user.\nOtherwise, then the daemon will attempt to recover the wallet state linked\nto this cipher seed."
|
||||
},
|
||||
"enciphered_seed": {
|
||||
"type": "string",
|
||||
"format": "byte",
|
||||
"description": "*\nenciphered_seed are the raw aezeed cipher seed bytes. This is the raw\ncipher text before run through our mnemonic encoding scheme."
|
||||
}
|
||||
}
|
||||
},
|
||||
"lnrpcGetInfoResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@ -1303,6 +1345,31 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"lnrpcInitWalletRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"wallet_password": {
|
||||
"type": "string",
|
||||
"format": "byte",
|
||||
"description": "*\nwallet_password is the passphrase that should be used to encrypt the\nwallet. This MUST be at least 8 chars in length. After creation, this\npassword is required to unlock the daemon."
|
||||
},
|
||||
"cipher_seed_mnemonic": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "*\ncipher_seed_mnemonic is a 24-word mnemonic that encodes a prior aezeed\ncipher seed obtained by the user. This may have been generated by the\nGenSeed method, or be an existing seed."
|
||||
},
|
||||
"aezeed_passphrase": {
|
||||
"type": "string",
|
||||
"format": "byte",
|
||||
"description": "*\naezeed_passphrase is an optional user provided passphrase that will be used\nto encrypt the generated aezeed cipher seed."
|
||||
}
|
||||
}
|
||||
},
|
||||
"lnrpcInitWalletResponse": {
|
||||
"type": "object"
|
||||
},
|
||||
"lnrpcInvoice": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@ -2062,9 +2129,10 @@
|
||||
"lnrpcUnlockWalletRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"password": {
|
||||
"wallet_password": {
|
||||
"type": "string",
|
||||
"format": "byte"
|
||||
"format": "byte",
|
||||
"description": "*\nwallet_password should be the current valid passphrase for the daemon. This\nwill be required to decrypt on-disk material that the daemon requires to\nfunction properly."
|
||||
}
|
||||
}
|
||||
},
|
||||
|
Loading…
x
Reference in New Issue
Block a user