lnd: move seed generation outside wallet to allow for user supplied entropy

In this commit, we extend the initial wallet creation set up case with
the goal of giving the user the ability to restore a prior wallet from
seed, or obtain the mnemonic for a newly generated wallet.

As the WalletUnlocker has been extended to allow passing a user source
of entropy, if this is detected, then we’ll use BIP39 to covert it into
an HD wallet seed. Otherwise, we’ll generate our own entropy, then
convert that into the wallet seed.

In order to make this change, we’ll now manually create the default
wallet ourselves. In the case that the user didn’t provide their own
seed, we’ll send the seed we generated back to the user. This will allow
frontends to display the newly generated seed to the end user.
This commit is contained in:
Olaoluwa Osuntokun 2018-02-01 20:49:34 -08:00
parent 428693cb6e
commit 6289a2fb84
No known key found for this signature in database
GPG Key ID: 964EA263DD637C21

45
lnd.go

@ -39,12 +39,14 @@ import (
"github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/lnrpc"
"github.com/lightningnetwork/lnd/lnwallet"
"github.com/lightningnetwork/lnd/lnwallet/btcwallet"
"github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/macaroons"
"github.com/lightningnetwork/lnd/walletunlocker"
"github.com/roasbeef/btcd/btcec"
"github.com/roasbeef/btcd/wire"
"github.com/roasbeef/btcutil"
"github.com/roasbeef/btcwallet/wallet"
)
const (
@ -820,14 +822,47 @@ func waitForWalletPassword(grpcEndpoints, restEndpoints []string,
"Use `lncli create` to create wallet, or " +
"`lncli unlock` to unlock already created wallet.")
// We currently don't distinguish between getting a password to
// be used for creation or unlocking, as a new wallet db will be
// created if none exists when creating the chain control.
// We currently don't distinguish between getting a password to be used
// for creation or unlocking, as a new wallet db will be created if
// none exists when creating the chain control.
select {
case walletPw := <-pwService.CreatePasswords:
return walletPw, walletPw, nil
// The wallet is being created for the first time, we'll check to see
// if the user provided any entropy for seed creation. If so, then
// we'll create the wallet early to load the seed.
case initMsg := <-pwService.InitMsgs:
password := initMsg.Passphrase
cipherSeed := initMsg.WalletSeed
netDir := btcwallet.NetworkDir(
chainConfig.ChainDir, activeNetParams.Params,
)
loader := wallet.NewLoader(activeNetParams.Params, netDir)
// With the seed, we can now use the wallet loader to create
// the wallet, then unload it so it can be opened shortly
// after.
//
// TODO(roasbeef): extend loader to also accept birthday
// * also check with keychain version
_, err = loader.CreateNewWallet(
password, password, cipherSeed.Entropy[:],
)
if err != nil {
return nil, nil, err
}
if err := loader.UnloadWallet(); err != nil {
return nil, nil, err
}
return password, password, nil
// The wallet has already been created in the past, and is simply being
// unlocked. So we'll just return these passphrases.
case walletPw := <-pwService.UnlockPasswords:
return walletPw, walletPw, nil
case <-shutdownChannel:
return nil, nil, fmt.Errorf("shutting down")
}