multi: allow watch-only wallet creation

This commit is contained in:
Oliver Gugger 2021-10-14 15:42:55 +02:00
parent 6d339f31c0
commit ceb31f9034
No known key found for this signature in database
GPG key ID: 8E4256593F177720
5 changed files with 581 additions and 94 deletions

View file

@ -8,6 +8,7 @@ import (
"net"
"os"
"path/filepath"
"sort"
"strconv"
"strings"
"time"
@ -15,6 +16,7 @@ import (
"github.com/btcsuite/btcd/chaincfg"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btclog"
"github.com/btcsuite/btcwallet/waddrmgr"
"github.com/btcsuite/btcwallet/wallet"
"github.com/btcsuite/btcwallet/walletdb"
proxy "github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
@ -952,6 +954,7 @@ func waitForWalletPassword(cfg *Config,
password := initMsg.Passphrase
cipherSeed := initMsg.WalletSeed
extendedKey := initMsg.WalletExtendedKey
watchOnlyAccounts := initMsg.WatchOnlyAccounts
recoveryWindow := initMsg.RecoveryWindow
// Before we proceed, we'll check the internal version of the
@ -1000,6 +1003,26 @@ func waitForWalletPassword(cfg *Config,
password, password, extendedKey, birthday,
)
// Neither seed nor extended private key was given, so maybe the
// third option was chosen, the watch-only initialization. In
// this case we need to import each of the xpubs individually.
case watchOnlyAccounts != nil:
if !cfg.RemoteSigner.Enable {
return nil, fmt.Errorf("cannot initialize " +
"watch only wallet with remote " +
"signer config disabled")
}
birthday = initMsg.ExtendedKeyBirthday
newWallet, err = loader.CreateNewWatchingOnlyWallet(
password, birthday,
)
if err != nil {
break
}
err = importWatchOnlyAccounts(newWallet, initMsg)
default:
// The unlocker service made sure either the cipher seed
// or the extended key is set so, we shouldn't get here.
@ -1065,6 +1088,51 @@ func waitForWalletPassword(cfg *Config,
}
}
// importWatchOnlyAccounts imports all individual account xpubs into our wallet
// which we created as watch-only.
func importWatchOnlyAccounts(wallet *wallet.Wallet,
initMsg *walletunlocker.WalletInitMsg) error {
scopes := make([]waddrmgr.ScopedIndex, 0, len(initMsg.WatchOnlyAccounts))
for scope := range initMsg.WatchOnlyAccounts {
scopes = append(scopes, scope)
}
// We need to import the accounts in the correct order, otherwise the
// indices will be incorrect.
sort.Slice(scopes, func(i, j int) bool {
return scopes[i].Scope.Purpose < scopes[j].Scope.Purpose ||
scopes[i].Index < scopes[j].Index
})
for _, scope := range scopes {
addrSchema := waddrmgr.ScopeAddrMap[waddrmgr.KeyScopeBIP0084]
if scope.Scope.Purpose == waddrmgr.KeyScopeBIP0049Plus.Purpose {
addrSchema = waddrmgr.ScopeAddrMap[scope.Scope]
}
// We want a human-readable account name. But for the default
// on-chain wallet we actually need to call it "default" to make
// sure everything works correctly.
name := fmt.Sprintf("%s/%d'", scope.Scope.String(), scope.Index)
if scope.Index == 0 {
name = "default"
}
_, err := wallet.ImportAccountWithScope(
name, initMsg.WatchOnlyAccounts[scope],
initMsg.WatchOnlyMasterFingerprint, scope.Scope,
addrSchema,
)
if err != nil {
return fmt.Errorf("could not import account %v: %v",
name, err)
}
}
return nil
}
// initNeutrinoBackend inits a new instance of the neutrino light client
// backend given a target chain directory to store the chain state.
func initNeutrinoBackend(cfg *Config, chainDir string,

View file

@ -212,6 +212,13 @@ type InitWalletRequest struct {
//which case lnd will start scanning from the first SegWit block (481824 on
//mainnet).
ExtendedMasterKeyBirthdayTimestamp uint64 `protobuf:"varint,8,opt,name=extended_master_key_birthday_timestamp,json=extendedMasterKeyBirthdayTimestamp,proto3" json:"extended_master_key_birthday_timestamp,omitempty"`
//
//watch_only is the third option of initializing a wallet: by importing
//account xpubs only and therefore creating a watch-only wallet that does not
//contain any private keys. That means the wallet won't be able to sign for
//any of the keys and _needs_ to be run with a remote signer that has the
//corresponding private keys and can serve signing RPC requests.
WatchOnly *WatchOnly `protobuf:"bytes,9,opt,name=watch_only,json=watchOnly,proto3" json:"watch_only,omitempty"`
}
func (x *InitWalletRequest) Reset() {
@ -302,6 +309,13 @@ func (x *InitWalletRequest) GetExtendedMasterKeyBirthdayTimestamp() uint64 {
return 0
}
func (x *InitWalletRequest) GetWatchOnly() *WatchOnly {
if x != nil {
return x.WatchOnly
}
return nil
}
type InitWalletResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@ -355,6 +369,172 @@ func (x *InitWalletResponse) GetAdminMacaroon() []byte {
return nil
}
type WatchOnly struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
//
//The unix timestamp in seconds of when the master key was created. lnd will
//only start scanning for funds in blocks that are after the birthday which
//can speed up the process significantly. If the birthday is not known, this
//should be left at its default value of 0 in which case lnd will start
//scanning from the first SegWit block (481824 on mainnet).
MasterKeyBirthdayTimestamp uint64 `protobuf:"varint,1,opt,name=master_key_birthday_timestamp,json=masterKeyBirthdayTimestamp,proto3" json:"master_key_birthday_timestamp,omitempty"`
//
//The fingerprint of the root key (also known as the key with derivation path
//m/) from which the account public keys were derived from. This may be
//required by some hardware wallets for proper identification and signing. The
//bytes must be in big-endian order.
MasterKeyFingerprint []byte `protobuf:"bytes,2,opt,name=master_key_fingerprint,json=masterKeyFingerprint,proto3" json:"master_key_fingerprint,omitempty"`
//
//The list of accounts to import. There _must_ be an account for all of lnd's
//main key scopes: BIP49/BIP84 (m/49'/0'/0', m/84'/0'/0', note that the
//coin type is always 0, even for testnet/regtest) and lnd's internal key
//scope (m/1017'/<coin_type>'/<account>'), where account is the key family as
//defined in `keychain/derivation.go` (currently indices 0 to 9).
Accounts []*WatchOnlyAccount `protobuf:"bytes,3,rep,name=accounts,proto3" json:"accounts,omitempty"`
}
func (x *WatchOnly) Reset() {
*x = WatchOnly{}
if protoimpl.UnsafeEnabled {
mi := &file_walletunlocker_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *WatchOnly) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*WatchOnly) ProtoMessage() {}
func (x *WatchOnly) ProtoReflect() protoreflect.Message {
mi := &file_walletunlocker_proto_msgTypes[4]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use WatchOnly.ProtoReflect.Descriptor instead.
func (*WatchOnly) Descriptor() ([]byte, []int) {
return file_walletunlocker_proto_rawDescGZIP(), []int{4}
}
func (x *WatchOnly) GetMasterKeyBirthdayTimestamp() uint64 {
if x != nil {
return x.MasterKeyBirthdayTimestamp
}
return 0
}
func (x *WatchOnly) GetMasterKeyFingerprint() []byte {
if x != nil {
return x.MasterKeyFingerprint
}
return nil
}
func (x *WatchOnly) GetAccounts() []*WatchOnlyAccount {
if x != nil {
return x.Accounts
}
return nil
}
type WatchOnlyAccount struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
//
//Purpose is the first number in the derivation path, must be either 49, 84
//or 1017.
Purpose uint32 `protobuf:"varint,1,opt,name=purpose,proto3" json:"purpose,omitempty"`
//
//Coin type is the second number in the derivation path, this is _always_ 0
//for purposes 49 and 84. It only needs to be set to 1 for purpose 1017 on
//testnet or regtest.
CoinType uint32 `protobuf:"varint,2,opt,name=coin_type,json=coinType,proto3" json:"coin_type,omitempty"`
//
//Account is the third number in the derivation path. For purposes 49 and 84
//at least the default account (index 0) needs to be created but optional
//additional accounts are allowed. For purpose 1017 there needs to be exactly
//one account for each of the key families defined in `keychain/derivation.go`
//(currently indices 0 to 9)
Account uint32 `protobuf:"varint,3,opt,name=account,proto3" json:"account,omitempty"`
//
//The extended public key at depth 3 for the given account.
Xpub string `protobuf:"bytes,4,opt,name=xpub,proto3" json:"xpub,omitempty"`
}
func (x *WatchOnlyAccount) Reset() {
*x = WatchOnlyAccount{}
if protoimpl.UnsafeEnabled {
mi := &file_walletunlocker_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *WatchOnlyAccount) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*WatchOnlyAccount) ProtoMessage() {}
func (x *WatchOnlyAccount) ProtoReflect() protoreflect.Message {
mi := &file_walletunlocker_proto_msgTypes[5]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use WatchOnlyAccount.ProtoReflect.Descriptor instead.
func (*WatchOnlyAccount) Descriptor() ([]byte, []int) {
return file_walletunlocker_proto_rawDescGZIP(), []int{5}
}
func (x *WatchOnlyAccount) GetPurpose() uint32 {
if x != nil {
return x.Purpose
}
return 0
}
func (x *WatchOnlyAccount) GetCoinType() uint32 {
if x != nil {
return x.CoinType
}
return 0
}
func (x *WatchOnlyAccount) GetAccount() uint32 {
if x != nil {
return x.Account
}
return 0
}
func (x *WatchOnlyAccount) GetXpub() string {
if x != nil {
return x.Xpub
}
return ""
}
type UnlockWalletRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@ -389,7 +569,7 @@ type UnlockWalletRequest struct {
func (x *UnlockWalletRequest) Reset() {
*x = UnlockWalletRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_walletunlocker_proto_msgTypes[4]
mi := &file_walletunlocker_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -402,7 +582,7 @@ func (x *UnlockWalletRequest) String() string {
func (*UnlockWalletRequest) ProtoMessage() {}
func (x *UnlockWalletRequest) ProtoReflect() protoreflect.Message {
mi := &file_walletunlocker_proto_msgTypes[4]
mi := &file_walletunlocker_proto_msgTypes[6]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -415,7 +595,7 @@ func (x *UnlockWalletRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use UnlockWalletRequest.ProtoReflect.Descriptor instead.
func (*UnlockWalletRequest) Descriptor() ([]byte, []int) {
return file_walletunlocker_proto_rawDescGZIP(), []int{4}
return file_walletunlocker_proto_rawDescGZIP(), []int{6}
}
func (x *UnlockWalletRequest) GetWalletPassword() []byte {
@ -455,7 +635,7 @@ type UnlockWalletResponse struct {
func (x *UnlockWalletResponse) Reset() {
*x = UnlockWalletResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_walletunlocker_proto_msgTypes[5]
mi := &file_walletunlocker_proto_msgTypes[7]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -468,7 +648,7 @@ func (x *UnlockWalletResponse) String() string {
func (*UnlockWalletResponse) ProtoMessage() {}
func (x *UnlockWalletResponse) ProtoReflect() protoreflect.Message {
mi := &file_walletunlocker_proto_msgTypes[5]
mi := &file_walletunlocker_proto_msgTypes[7]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -481,7 +661,7 @@ func (x *UnlockWalletResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use UnlockWalletResponse.ProtoReflect.Descriptor instead.
func (*UnlockWalletResponse) Descriptor() ([]byte, []int) {
return file_walletunlocker_proto_rawDescGZIP(), []int{5}
return file_walletunlocker_proto_rawDescGZIP(), []int{7}
}
type ChangePasswordRequest struct {
@ -513,7 +693,7 @@ type ChangePasswordRequest struct {
func (x *ChangePasswordRequest) Reset() {
*x = ChangePasswordRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_walletunlocker_proto_msgTypes[6]
mi := &file_walletunlocker_proto_msgTypes[8]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -526,7 +706,7 @@ func (x *ChangePasswordRequest) String() string {
func (*ChangePasswordRequest) ProtoMessage() {}
func (x *ChangePasswordRequest) ProtoReflect() protoreflect.Message {
mi := &file_walletunlocker_proto_msgTypes[6]
mi := &file_walletunlocker_proto_msgTypes[8]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -539,7 +719,7 @@ func (x *ChangePasswordRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use ChangePasswordRequest.ProtoReflect.Descriptor instead.
func (*ChangePasswordRequest) Descriptor() ([]byte, []int) {
return file_walletunlocker_proto_rawDescGZIP(), []int{6}
return file_walletunlocker_proto_rawDescGZIP(), []int{8}
}
func (x *ChangePasswordRequest) GetCurrentPassword() []byte {
@ -588,7 +768,7 @@ type ChangePasswordResponse struct {
func (x *ChangePasswordResponse) Reset() {
*x = ChangePasswordResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_walletunlocker_proto_msgTypes[7]
mi := &file_walletunlocker_proto_msgTypes[9]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -601,7 +781,7 @@ func (x *ChangePasswordResponse) String() string {
func (*ChangePasswordResponse) ProtoMessage() {}
func (x *ChangePasswordResponse) ProtoReflect() protoreflect.Message {
mi := &file_walletunlocker_proto_msgTypes[7]
mi := &file_walletunlocker_proto_msgTypes[9]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -614,7 +794,7 @@ func (x *ChangePasswordResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use ChangePasswordResponse.ProtoReflect.Descriptor instead.
func (*ChangePasswordResponse) Descriptor() ([]byte, []int) {
return file_walletunlocker_proto_rawDescGZIP(), []int{7}
return file_walletunlocker_proto_rawDescGZIP(), []int{9}
}
func (x *ChangePasswordResponse) GetAdminMacaroon() []byte {
@ -642,7 +822,7 @@ var file_walletunlocker_proto_rawDesc = []byte{
0x09, 0x52, 0x12, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x53, 0x65, 0x65, 0x64, 0x4d, 0x6e, 0x65,
0x6d, 0x6f, 0x6e, 0x69, 0x63, 0x12, 0x27, 0x0a, 0x0f, 0x65, 0x6e, 0x63, 0x69, 0x70, 0x68, 0x65,
0x72, 0x65, 0x64, 0x5f, 0x73, 0x65, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e,
0x65, 0x6e, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x65, 0x64, 0x53, 0x65, 0x65, 0x64, 0x22, 0xb3,
0x65, 0x6e, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x65, 0x64, 0x53, 0x65, 0x65, 0x64, 0x22, 0xe4,
0x03, 0x0a, 0x11, 0x49, 0x6e, 0x69, 0x74, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x5f, 0x70,
0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x77,
@ -670,63 +850,85 @@ var file_walletunlocker_proto_rawDesc = []byte{
0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04,
0x52, 0x22, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72,
0x4b, 0x65, 0x79, 0x42, 0x69, 0x72, 0x74, 0x68, 0x64, 0x61, 0x79, 0x54, 0x69, 0x6d, 0x65, 0x73,
0x74, 0x61, 0x6d, 0x70, 0x22, 0x3b, 0x0a, 0x12, 0x49, 0x6e, 0x69, 0x74, 0x57, 0x61, 0x6c, 0x6c,
0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x61, 0x64,
0x6d, 0x69, 0x6e, 0x5f, 0x6d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01,
0x28, 0x0c, 0x52, 0x0d, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x4d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f,
0x6e, 0x22, 0xd2, 0x01, 0x0a, 0x13, 0x55, 0x6e, 0x6c, 0x6f, 0x63, 0x6b, 0x57, 0x61, 0x6c, 0x6c,
0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x77, 0x61, 0x6c,
0x6c, 0x65, 0x74, 0x5f, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x01, 0x20, 0x01,
0x28, 0x0c, 0x52, 0x0e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f,
0x72, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x72, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x5f, 0x77,
0x69, 0x6e, 0x64, 0x6f, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x72, 0x65, 0x63,
0x6f, 0x76, 0x65, 0x72, 0x79, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x12, 0x42, 0x0a, 0x0f, 0x63,
0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x73, 0x18, 0x03,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61,
0x6e, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x52,
0x0e, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x73, 0x12,
0x25, 0x0a, 0x0e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6c, 0x65, 0x73, 0x73, 0x5f, 0x69, 0x6e, 0x69,
0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6c, 0x65,
0x73, 0x73, 0x49, 0x6e, 0x69, 0x74, 0x22, 0x16, 0x0a, 0x14, 0x55, 0x6e, 0x6c, 0x6f, 0x63, 0x6b,
0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xbf,
0x01, 0x0a, 0x15, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72,
0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x29, 0x0a, 0x10, 0x63, 0x75, 0x72, 0x72,
0x65, 0x6e, 0x74, 0x5f, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x01, 0x20, 0x01,
0x28, 0x0c, 0x52, 0x0f, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x50, 0x61, 0x73, 0x73, 0x77,
0x6f, 0x72, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x6e, 0x65, 0x77, 0x5f, 0x70, 0x61, 0x73, 0x73, 0x77,
0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x6e, 0x65, 0x77, 0x50, 0x61,
0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6c,
0x65, 0x73, 0x73, 0x5f, 0x69, 0x6e, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d,
0x73, 0x74, 0x61, 0x74, 0x65, 0x6c, 0x65, 0x73, 0x73, 0x49, 0x6e, 0x69, 0x74, 0x12, 0x31, 0x0a,
0x15, 0x6e, 0x65, 0x77, 0x5f, 0x6d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x5f, 0x72, 0x6f,
0x6f, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x6e, 0x65,
0x77, 0x4d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x52, 0x6f, 0x6f, 0x74, 0x4b, 0x65, 0x79,
0x22, 0x3f, 0x0a, 0x16, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f,
0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x61, 0x64,
0x6d, 0x69, 0x6e, 0x5f, 0x6d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01,
0x28, 0x0c, 0x52, 0x0d, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x4d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f,
0x6e, 0x32, 0xa5, 0x02, 0x0a, 0x0e, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x55, 0x6e, 0x6c, 0x6f,
0x63, 0x6b, 0x65, 0x72, 0x12, 0x38, 0x0a, 0x07, 0x47, 0x65, 0x6e, 0x53, 0x65, 0x65, 0x64, 0x12,
0x15, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x6e, 0x53, 0x65, 0x65, 0x64, 0x52,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x47,
0x65, 0x6e, 0x53, 0x65, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41,
0x0a, 0x0a, 0x49, 0x6e, 0x69, 0x74, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x12, 0x18, 0x2e, 0x6c,
0x74, 0x61, 0x6d, 0x70, 0x12, 0x2f, 0x0a, 0x0a, 0x77, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x6f, 0x6e,
0x6c, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63,
0x2e, 0x57, 0x61, 0x74, 0x63, 0x68, 0x4f, 0x6e, 0x6c, 0x79, 0x52, 0x09, 0x77, 0x61, 0x74, 0x63,
0x68, 0x4f, 0x6e, 0x6c, 0x79, 0x22, 0x3b, 0x0a, 0x12, 0x49, 0x6e, 0x69, 0x74, 0x57, 0x61, 0x6c,
0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x61,
0x64, 0x6d, 0x69, 0x6e, 0x5f, 0x6d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x18, 0x01, 0x20,
0x01, 0x28, 0x0c, 0x52, 0x0d, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x4d, 0x61, 0x63, 0x61, 0x72, 0x6f,
0x6f, 0x6e, 0x22, 0xb9, 0x01, 0x0a, 0x09, 0x57, 0x61, 0x74, 0x63, 0x68, 0x4f, 0x6e, 0x6c, 0x79,
0x12, 0x41, 0x0a, 0x1d, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x62,
0x69, 0x72, 0x74, 0x68, 0x64, 0x61, 0x79, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d,
0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x1a, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b,
0x65, 0x79, 0x42, 0x69, 0x72, 0x74, 0x68, 0x64, 0x61, 0x79, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74,
0x61, 0x6d, 0x70, 0x12, 0x34, 0x0a, 0x16, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x6b, 0x65,
0x79, 0x5f, 0x66, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x18, 0x02, 0x20,
0x01, 0x28, 0x0c, 0x52, 0x14, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x46, 0x69,
0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x12, 0x33, 0x0a, 0x08, 0x61, 0x63, 0x63,
0x6f, 0x75, 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x6c, 0x6e,
0x72, 0x70, 0x63, 0x2e, 0x57, 0x61, 0x74, 0x63, 0x68, 0x4f, 0x6e, 0x6c, 0x79, 0x41, 0x63, 0x63,
0x6f, 0x75, 0x6e, 0x74, 0x52, 0x08, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x22, 0x77,
0x0a, 0x10, 0x57, 0x61, 0x74, 0x63, 0x68, 0x4f, 0x6e, 0x6c, 0x79, 0x41, 0x63, 0x63, 0x6f, 0x75,
0x6e, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x75, 0x72, 0x70, 0x6f, 0x73, 0x65, 0x18, 0x01, 0x20,
0x01, 0x28, 0x0d, 0x52, 0x07, 0x70, 0x75, 0x72, 0x70, 0x6f, 0x73, 0x65, 0x12, 0x1b, 0x0a, 0x09,
0x63, 0x6f, 0x69, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52,
0x08, 0x63, 0x6f, 0x69, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x63, 0x63,
0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x61, 0x63, 0x63, 0x6f,
0x75, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x78, 0x70, 0x75, 0x62, 0x18, 0x04, 0x20, 0x01, 0x28,
0x09, 0x52, 0x04, 0x78, 0x70, 0x75, 0x62, 0x22, 0xd2, 0x01, 0x0a, 0x13, 0x55, 0x6e, 0x6c, 0x6f,
0x63, 0x6b, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
0x27, 0x0a, 0x0f, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x5f, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f,
0x72, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74,
0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x72, 0x65, 0x63, 0x6f,
0x76, 0x65, 0x72, 0x79, 0x5f, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28,
0x05, 0x52, 0x0e, 0x72, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x57, 0x69, 0x6e, 0x64, 0x6f,
0x77, 0x12, 0x42, 0x0a, 0x0f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x62, 0x61, 0x63,
0x6b, 0x75, 0x70, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x6c, 0x6e, 0x72,
0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x53, 0x6e, 0x61,
0x70, 0x73, 0x68, 0x6f, 0x74, 0x52, 0x0e, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x42, 0x61,
0x63, 0x6b, 0x75, 0x70, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6c, 0x65,
0x73, 0x73, 0x5f, 0x69, 0x6e, 0x69, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x73,
0x74, 0x61, 0x74, 0x65, 0x6c, 0x65, 0x73, 0x73, 0x49, 0x6e, 0x69, 0x74, 0x22, 0x16, 0x0a, 0x14,
0x55, 0x6e, 0x6c, 0x6f, 0x63, 0x6b, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x22, 0xbf, 0x01, 0x0a, 0x15, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x50,
0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x29,
0x0a, 0x10, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f,
0x72, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e,
0x74, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x6e, 0x65, 0x77,
0x5f, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52,
0x0b, 0x6e, 0x65, 0x77, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x25, 0x0a, 0x0e,
0x73, 0x74, 0x61, 0x74, 0x65, 0x6c, 0x65, 0x73, 0x73, 0x5f, 0x69, 0x6e, 0x69, 0x74, 0x18, 0x03,
0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6c, 0x65, 0x73, 0x73, 0x49,
0x6e, 0x69, 0x74, 0x12, 0x31, 0x0a, 0x15, 0x6e, 0x65, 0x77, 0x5f, 0x6d, 0x61, 0x63, 0x61, 0x72,
0x6f, 0x6f, 0x6e, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x04, 0x20, 0x01,
0x28, 0x08, 0x52, 0x12, 0x6e, 0x65, 0x77, 0x4d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x52,
0x6f, 0x6f, 0x74, 0x4b, 0x65, 0x79, 0x22, 0x3f, 0x0a, 0x16, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65,
0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x12, 0x25, 0x0a, 0x0e, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x5f, 0x6d, 0x61, 0x63, 0x61, 0x72, 0x6f,
0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x4d,
0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x32, 0xa5, 0x02, 0x0a, 0x0e, 0x57, 0x61, 0x6c, 0x6c,
0x65, 0x74, 0x55, 0x6e, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x72, 0x12, 0x38, 0x0a, 0x07, 0x47, 0x65,
0x6e, 0x53, 0x65, 0x65, 0x64, 0x12, 0x15, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65,
0x6e, 0x53, 0x65, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x6c,
0x6e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x6e, 0x53, 0x65, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x0a, 0x49, 0x6e, 0x69, 0x74, 0x57, 0x61, 0x6c, 0x6c,
0x65, 0x74, 0x12, 0x18, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x57,
0x61, 0x6c, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x6c,
0x6e, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x52,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x49,
0x6e, 0x69, 0x74, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x12, 0x47, 0x0a, 0x0c, 0x55, 0x6e, 0x6c, 0x6f, 0x63, 0x6b, 0x57, 0x61, 0x6c, 0x6c, 0x65,
0x74, 0x12, 0x1a, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x6e, 0x6c, 0x6f, 0x63, 0x6b,
0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e,
0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x6e, 0x6c, 0x6f, 0x63, 0x6b, 0x57, 0x61, 0x6c, 0x6c,
0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4d, 0x0a, 0x0e, 0x43, 0x68,
0x61, 0x6e, 0x67, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x1c, 0x2e, 0x6c,
0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77,
0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x6c, 0x6e, 0x72,
0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72,
0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x27, 0x5a, 0x25, 0x67, 0x69, 0x74,
0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x6e, 0x69, 0x6e,
0x67, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6e, 0x64, 0x2f, 0x6c, 0x6e, 0x72,
0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x47, 0x0a, 0x0c, 0x55, 0x6e, 0x6c, 0x6f, 0x63,
0x6b, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x12, 0x1a, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e,
0x55, 0x6e, 0x6c, 0x6f, 0x63, 0x6b, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x6e, 0x6c, 0x6f,
0x63, 0x6b, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x12, 0x4d, 0x0a, 0x0e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f,
0x72, 0x64, 0x12, 0x1c, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67,
0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x1a, 0x1d, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x50,
0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42,
0x27, 0x5a, 0x25, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69,
0x67, 0x68, 0x74, 0x6e, 0x69, 0x6e, 0x67, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c,
0x6e, 0x64, 0x2f, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@ -741,34 +943,38 @@ func file_walletunlocker_proto_rawDescGZIP() []byte {
return file_walletunlocker_proto_rawDescData
}
var file_walletunlocker_proto_msgTypes = make([]protoimpl.MessageInfo, 8)
var file_walletunlocker_proto_msgTypes = make([]protoimpl.MessageInfo, 10)
var file_walletunlocker_proto_goTypes = []interface{}{
(*GenSeedRequest)(nil), // 0: lnrpc.GenSeedRequest
(*GenSeedResponse)(nil), // 1: lnrpc.GenSeedResponse
(*InitWalletRequest)(nil), // 2: lnrpc.InitWalletRequest
(*InitWalletResponse)(nil), // 3: lnrpc.InitWalletResponse
(*UnlockWalletRequest)(nil), // 4: lnrpc.UnlockWalletRequest
(*UnlockWalletResponse)(nil), // 5: lnrpc.UnlockWalletResponse
(*ChangePasswordRequest)(nil), // 6: lnrpc.ChangePasswordRequest
(*ChangePasswordResponse)(nil), // 7: lnrpc.ChangePasswordResponse
(*ChanBackupSnapshot)(nil), // 8: lnrpc.ChanBackupSnapshot
(*WatchOnly)(nil), // 4: lnrpc.WatchOnly
(*WatchOnlyAccount)(nil), // 5: lnrpc.WatchOnlyAccount
(*UnlockWalletRequest)(nil), // 6: lnrpc.UnlockWalletRequest
(*UnlockWalletResponse)(nil), // 7: lnrpc.UnlockWalletResponse
(*ChangePasswordRequest)(nil), // 8: lnrpc.ChangePasswordRequest
(*ChangePasswordResponse)(nil), // 9: lnrpc.ChangePasswordResponse
(*ChanBackupSnapshot)(nil), // 10: lnrpc.ChanBackupSnapshot
}
var file_walletunlocker_proto_depIdxs = []int32{
8, // 0: lnrpc.InitWalletRequest.channel_backups:type_name -> lnrpc.ChanBackupSnapshot
8, // 1: lnrpc.UnlockWalletRequest.channel_backups:type_name -> lnrpc.ChanBackupSnapshot
0, // 2: lnrpc.WalletUnlocker.GenSeed:input_type -> lnrpc.GenSeedRequest
2, // 3: lnrpc.WalletUnlocker.InitWallet:input_type -> lnrpc.InitWalletRequest
4, // 4: lnrpc.WalletUnlocker.UnlockWallet:input_type -> lnrpc.UnlockWalletRequest
6, // 5: lnrpc.WalletUnlocker.ChangePassword:input_type -> lnrpc.ChangePasswordRequest
1, // 6: lnrpc.WalletUnlocker.GenSeed:output_type -> lnrpc.GenSeedResponse
3, // 7: lnrpc.WalletUnlocker.InitWallet:output_type -> lnrpc.InitWalletResponse
5, // 8: lnrpc.WalletUnlocker.UnlockWallet:output_type -> lnrpc.UnlockWalletResponse
7, // 9: lnrpc.WalletUnlocker.ChangePassword:output_type -> lnrpc.ChangePasswordResponse
6, // [6:10] is the sub-list for method output_type
2, // [2:6] is the sub-list for method input_type
2, // [2:2] is the sub-list for extension type_name
2, // [2:2] is the sub-list for extension extendee
0, // [0:2] is the sub-list for field type_name
10, // 0: lnrpc.InitWalletRequest.channel_backups:type_name -> lnrpc.ChanBackupSnapshot
4, // 1: lnrpc.InitWalletRequest.watch_only:type_name -> lnrpc.WatchOnly
5, // 2: lnrpc.WatchOnly.accounts:type_name -> lnrpc.WatchOnlyAccount
10, // 3: lnrpc.UnlockWalletRequest.channel_backups:type_name -> lnrpc.ChanBackupSnapshot
0, // 4: lnrpc.WalletUnlocker.GenSeed:input_type -> lnrpc.GenSeedRequest
2, // 5: lnrpc.WalletUnlocker.InitWallet:input_type -> lnrpc.InitWalletRequest
6, // 6: lnrpc.WalletUnlocker.UnlockWallet:input_type -> lnrpc.UnlockWalletRequest
8, // 7: lnrpc.WalletUnlocker.ChangePassword:input_type -> lnrpc.ChangePasswordRequest
1, // 8: lnrpc.WalletUnlocker.GenSeed:output_type -> lnrpc.GenSeedResponse
3, // 9: lnrpc.WalletUnlocker.InitWallet:output_type -> lnrpc.InitWalletResponse
7, // 10: lnrpc.WalletUnlocker.UnlockWallet:output_type -> lnrpc.UnlockWalletResponse
9, // 11: lnrpc.WalletUnlocker.ChangePassword:output_type -> lnrpc.ChangePasswordResponse
8, // [8:12] is the sub-list for method output_type
4, // [4:8] is the sub-list for method input_type
4, // [4:4] is the sub-list for extension type_name
4, // [4:4] is the sub-list for extension extendee
0, // [0:4] is the sub-list for field type_name
}
func init() { file_walletunlocker_proto_init() }
@ -827,7 +1033,7 @@ func file_walletunlocker_proto_init() {
}
}
file_walletunlocker_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*UnlockWalletRequest); i {
switch v := v.(*WatchOnly); i {
case 0:
return &v.state
case 1:
@ -839,7 +1045,7 @@ func file_walletunlocker_proto_init() {
}
}
file_walletunlocker_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*UnlockWalletResponse); i {
switch v := v.(*WatchOnlyAccount); i {
case 0:
return &v.state
case 1:
@ -851,7 +1057,7 @@ func file_walletunlocker_proto_init() {
}
}
file_walletunlocker_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ChangePasswordRequest); i {
switch v := v.(*UnlockWalletRequest); i {
case 0:
return &v.state
case 1:
@ -863,6 +1069,30 @@ func file_walletunlocker_proto_init() {
}
}
file_walletunlocker_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*UnlockWalletResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_walletunlocker_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ChangePasswordRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_walletunlocker_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ChangePasswordResponse); i {
case 0:
return &v.state
@ -881,7 +1111,7 @@ func file_walletunlocker_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_walletunlocker_proto_rawDesc,
NumEnums: 0,
NumMessages: 8,
NumMessages: 10,
NumExtensions: 0,
NumServices: 1,
},

View file

@ -176,6 +176,15 @@ message InitWalletRequest {
mainnet).
*/
uint64 extended_master_key_birthday_timestamp = 8;
/*
watch_only is the third option of initializing a wallet: by importing
account xpubs only and therefore creating a watch-only wallet that does not
contain any private keys. That means the wallet won't be able to sign for
any of the keys and _needs_ to be run with a remote signer that has the
corresponding private keys and can serve signing RPC requests.
*/
WatchOnly watch_only = 9;
}
message InitWalletResponse {
/*
@ -188,6 +197,63 @@ message InitWalletResponse {
bytes admin_macaroon = 1;
}
message WatchOnly {
/*
The unix timestamp in seconds of when the master key was created. lnd will
only start scanning for funds in blocks that are after the birthday which
can speed up the process significantly. If the birthday is not known, this
should be left at its default value of 0 in which case lnd will start
scanning from the first SegWit block (481824 on mainnet).
*/
uint64 master_key_birthday_timestamp = 1;
/*
The fingerprint of the root key (also known as the key with derivation path
m/) from which the account public keys were derived from. This may be
required by some hardware wallets for proper identification and signing. The
bytes must be in big-endian order.
*/
bytes master_key_fingerprint = 2;
/*
The list of accounts to import. There _must_ be an account for all of lnd's
main key scopes: BIP49/BIP84 (m/49'/0'/0', m/84'/0'/0', note that the
coin type is always 0, even for testnet/regtest) and lnd's internal key
scope (m/1017'/<coin_type>'/<account>'), where account is the key family as
defined in `keychain/derivation.go` (currently indices 0 to 9).
*/
repeated WatchOnlyAccount accounts = 3;
}
message WatchOnlyAccount {
/*
Purpose is the first number in the derivation path, must be either 49, 84
or 1017.
*/
uint32 purpose = 1;
/*
Coin type is the second number in the derivation path, this is _always_ 0
for purposes 49 and 84. It only needs to be set to 1 for purpose 1017 on
testnet or regtest.
*/
uint32 coin_type = 2;
/*
Account is the third number in the derivation path. For purposes 49 and 84
at least the default account (index 0) needs to be created but optional
additional accounts are allowed. For purpose 1017 there needs to be exactly
one account for each of the key families defined in `keychain/derivation.go`
(currently indices 0 to 9)
*/
uint32 account = 3;
/*
The extended public key at depth 3 for the given account.
*/
string xpub = 4;
}
message UnlockWalletRequest {
/*
wallet_password should be the current valid passphrase for the daemon. This

View file

@ -309,6 +309,10 @@
"type": "string",
"format": "uint64",
"description": "extended_master_key_birthday_timestamp is the optional unix timestamp in\nseconds to use as the wallet's birthday when using an extended master key\nto restore the wallet. lnd will only start scanning for funds in blocks that\nare after the birthday which can speed up the process significantly. If the\nbirthday is not known, this should be left at its default value of 0 in\nwhich case lnd will start scanning from the first SegWit block (481824 on\nmainnet)."
},
"watch_only": {
"$ref": "#/definitions/lnrpcWatchOnly",
"description": "watch_only is the third option of initializing a wallet: by importing\naccount xpubs only and therefore creating a watch-only wallet that does not\ncontain any private keys. That means the wallet won't be able to sign for\nany of the keys and _needs_ to be run with a remote signer that has the\ncorresponding private keys and can serve signing RPC requests."
}
}
},
@ -365,6 +369,52 @@
"lnrpcUnlockWalletResponse": {
"type": "object"
},
"lnrpcWatchOnly": {
"type": "object",
"properties": {
"master_key_birthday_timestamp": {
"type": "string",
"format": "uint64",
"description": "The unix timestamp in seconds of when the master key was created. lnd will\nonly start scanning for funds in blocks that are after the birthday which\ncan speed up the process significantly. If the birthday is not known, this\nshould be left at its default value of 0 in which case lnd will start\nscanning from the first SegWit block (481824 on mainnet)."
},
"master_key_fingerprint": {
"type": "string",
"format": "byte",
"description": "The fingerprint of the root key (also known as the key with derivation path\nm/) from which the account public keys were derived from. This may be\nrequired by some hardware wallets for proper identification and signing. The\nbytes must be in big-endian order."
},
"accounts": {
"type": "array",
"items": {
"$ref": "#/definitions/lnrpcWatchOnlyAccount"
},
"description": "The list of accounts to import. There _must_ be an account for all of lnd's\nmain key scopes: BIP49/BIP84 (m/49'/0'/0', m/84'/0'/0', note that the\ncoin type is always 0, even for testnet/regtest) and lnd's internal key\nscope (m/1017'/\u003ccoin_type\u003e'/\u003caccount\u003e'), where account is the key family as\ndefined in `keychain/derivation.go` (currently indices 0 to 9)."
}
}
},
"lnrpcWatchOnlyAccount": {
"type": "object",
"properties": {
"purpose": {
"type": "integer",
"format": "int64",
"description": "Purpose is the first number in the derivation path, must be either 49, 84\nor 1017."
},
"coin_type": {
"type": "integer",
"format": "int64",
"description": "Coin type is the second number in the derivation path, this is _always_ 0\nfor purposes 49 and 84. It only needs to be set to 1 for purpose 1017 on\ntestnet or regtest."
},
"account": {
"type": "integer",
"format": "int64",
"title": "Account is the third number in the derivation path. For purposes 49 and 84\nat least the default account (index 0) needs to be created but optional\nadditional accounts are allowed. For purpose 1017 there needs to be exactly\none account for each of the key families defined in `keychain/derivation.go`\n(currently indices 0 to 9)"
},
"xpub": {
"type": "string",
"description": "The extended public key at depth 3 for the given account."
}
}
},
"protobufAny": {
"type": "object",
"properties": {

View file

@ -10,6 +10,7 @@ import (
"github.com/btcsuite/btcd/chaincfg"
"github.com/btcsuite/btcutil/hdkeychain"
"github.com/btcsuite/btcwallet/waddrmgr"
"github.com/btcsuite/btcwallet/wallet"
"github.com/lightningnetwork/lnd/aezeed"
"github.com/lightningnetwork/lnd/chanbackup"
@ -103,6 +104,18 @@ type WalletInitMsg struct {
// through an extended key instead of an aezeed.
ExtendedKeyBirthday time.Time
// WatchOnlyAccounts is a map of scoped account extended public keys
// that should be imported to create a watch-only wallet.
WatchOnlyAccounts map[waddrmgr.ScopedIndex]*hdkeychain.ExtendedKey
// WatchOnlyBirthday is the birthday of the master root key the above
// watch-only account xpubs were derived from.
WatchOnlyBirthday time.Time
// WatchOnlyMasterFingerprint is the fingerprint of the master root key
// the above watch-only account xpubs were derived from.
WatchOnlyMasterFingerprint uint32
// RecoveryWindow is the address look-ahead used when restoring a seed
// with existing funds. A recovery window zero indicates that no
// recovery should be attempted, such as after the wallet's initial
@ -495,6 +508,66 @@ func (u *UnlockerService) InitWallet(ctx context.Context,
initMsg.WalletExtendedKey = extendedKey
// The third option for creating a wallet is the watch-only mode:
// Instead of providing the master root key directly, each individual
// account is passed as an extended public key only. Because of the
// hardened derivation path up to the account (depth 3), it is not
// possible to create a master root extended _public_ key. Therefore, an
// xpub must be derived and passed into the unlocker for _every_ account
// lnd expects.
case in.WatchOnly != nil && len(in.WatchOnly.Accounts) > 0:
initMsg.WatchOnlyAccounts = make(
map[waddrmgr.ScopedIndex]*hdkeychain.ExtendedKey,
len(in.WatchOnly.Accounts),
)
for _, acct := range in.WatchOnly.Accounts {
scopedIndex := waddrmgr.ScopedIndex{
Scope: waddrmgr.KeyScope{
Purpose: acct.Purpose,
Coin: acct.CoinType,
},
Index: acct.Account,
}
acctKey, err := hdkeychain.NewKeyFromString(acct.Xpub)
if err != nil {
return nil, fmt.Errorf("error parsing xpub "+
"%v: %v", acct.Xpub, err)
}
// Just to make sure the user is doing the right thing,
// we expect the public key to be at derivation depth
// three (which is the account level) and the key not to
// contain any private key material.
if acctKey.Depth() != 3 {
return nil, fmt.Errorf("xpub must be at " +
"depth 3")
}
if acctKey.IsPrivate() {
return nil, fmt.Errorf("xpub is not really " +
"an xpub, contains private key")
}
initMsg.WatchOnlyAccounts[scopedIndex] = acctKey
}
// When importing a wallet from its extended public keys we
// don't know the birthday as that information is not encoded in
// that format. We therefore must set an arbitrary date to start
// rescanning at if the user doesn't provide an explicit value
// for it. Since lnd only uses SegWit addresses, we pick the
// date of the first block that contained SegWit transactions
// (481824).
initMsg.WatchOnlyBirthday = time.Date(
2017, time.August, 24, 1, 57, 37, 0, time.UTC,
)
if in.WatchOnly.MasterKeyBirthdayTimestamp != 0 {
initMsg.WatchOnlyBirthday = time.Unix(
int64(in.WatchOnly.MasterKeyBirthdayTimestamp),
0,
)
}
// No key material was set, no wallet can be created.
default:
return nil, fmt.Errorf("must either specify cipher seed " +