diff --git a/lnd.go b/lnd.go index 295a277d..d88affda 100644 --- a/lnd.go +++ b/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") }