2020-10-15 22:31:52 +00:00
|
|
|
package accounts
|
2020-07-22 02:41:39 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/pkg/errors"
|
2023-03-17 18:52:56 +00:00
|
|
|
"github.com/prysmaticlabs/prysm/v4/validator/accounts/wallet"
|
|
|
|
"github.com/prysmaticlabs/prysm/v4/validator/keymanager"
|
|
|
|
"github.com/prysmaticlabs/prysm/v4/validator/keymanager/derived"
|
2020-07-22 02:41:39 +00:00
|
|
|
)
|
|
|
|
|
2020-10-27 20:51:29 +00:00
|
|
|
const (
|
2021-08-15 15:24:13 +00:00
|
|
|
phraseWordCount = 24
|
2020-10-27 20:51:29 +00:00
|
|
|
)
|
2020-07-22 02:41:39 +00:00
|
|
|
|
2022-03-13 23:30:11 +00:00
|
|
|
var (
|
|
|
|
ErrIncorrectWordNumber = errors.New("incorrect number of words provided")
|
|
|
|
ErrEmptyMnemonic = errors.New("phrase cannot be empty")
|
|
|
|
)
|
|
|
|
|
2022-08-24 16:57:03 +00:00
|
|
|
// WalletRecover uses a menmonic seed phrase to recover a wallet into the path provided.
|
|
|
|
func (acm *AccountsCLIManager) WalletRecover(ctx context.Context) (*wallet.Wallet, error) {
|
2020-09-30 14:13:37 +00:00
|
|
|
// Ensure that the wallet directory does not contain a wallet already
|
2022-08-24 16:57:03 +00:00
|
|
|
dirExists, err := wallet.Exists(acm.walletDir)
|
2020-09-30 14:13:37 +00:00
|
|
|
if err != nil {
|
2020-11-16 22:26:04 +00:00
|
|
|
return nil, err
|
2020-09-30 14:13:37 +00:00
|
|
|
}
|
|
|
|
if dirExists {
|
2020-11-16 22:26:04 +00:00
|
|
|
return nil, errors.New("a wallet already exists at this location. Please input an" +
|
2020-09-30 14:13:37 +00:00
|
|
|
" alternative location for the new wallet or remove the current wallet")
|
|
|
|
}
|
2020-09-23 08:59:49 +00:00
|
|
|
w := wallet.New(&wallet.Config{
|
2022-08-24 16:57:03 +00:00
|
|
|
WalletDir: acm.walletDir,
|
2020-10-15 22:31:52 +00:00
|
|
|
KeymanagerKind: keymanager.Derived,
|
2022-08-24 16:57:03 +00:00
|
|
|
WalletPassword: acm.walletPassword,
|
2020-09-17 01:34:42 +00:00
|
|
|
})
|
|
|
|
if err := w.SaveWallet(); err != nil {
|
2020-11-16 22:26:04 +00:00
|
|
|
return nil, errors.Wrap(err, "could not save wallet to disk")
|
2020-09-03 15:11:17 +00:00
|
|
|
}
|
2020-11-16 22:26:04 +00:00
|
|
|
km, err := derived.NewKeymanager(ctx, &derived.SetupConfig{
|
2021-02-24 18:05:46 +00:00
|
|
|
Wallet: w,
|
|
|
|
ListenForChanges: false,
|
2020-08-31 19:46:45 +00:00
|
|
|
})
|
2020-07-27 14:03:30 +00:00
|
|
|
if err != nil {
|
2020-11-16 22:26:04 +00:00
|
|
|
return nil, errors.Wrap(err, "could not make keymanager for given phrase")
|
2020-08-31 19:46:45 +00:00
|
|
|
}
|
2022-10-26 21:04:00 +00:00
|
|
|
if err := km.RecoverAccountsFromMnemonic(ctx, acm.mnemonic, acm.mnemonicLanguage, acm.mnemonic25thWord, acm.numAccounts); err != nil {
|
2020-11-16 22:26:04 +00:00
|
|
|
return nil, err
|
2020-08-31 19:46:45 +00:00
|
|
|
}
|
2020-09-17 01:34:42 +00:00
|
|
|
log.WithField("wallet-path", w.AccountsDir()).Infof(
|
2020-12-17 13:37:06 +00:00
|
|
|
"Successfully recovered HD wallet with %d accounts. Please use `accounts list` to view details for your accounts",
|
2022-08-24 16:57:03 +00:00
|
|
|
acm.numAccounts,
|
2020-07-22 04:49:04 +00:00
|
|
|
)
|
2020-11-16 22:26:04 +00:00
|
|
|
return w, nil
|
2020-07-22 02:41:39 +00:00
|
|
|
}
|
|
|
|
|
2021-04-05 20:42:03 +00:00
|
|
|
// ValidateMnemonic ensures that it is not empty and that the count of the words are
|
|
|
|
// as specified(currently 24).
|
|
|
|
func ValidateMnemonic(mnemonic string) error {
|
2020-07-22 02:41:39 +00:00
|
|
|
if strings.Trim(mnemonic, " ") == "" {
|
2022-03-13 23:30:11 +00:00
|
|
|
return ErrEmptyMnemonic
|
2020-07-22 02:41:39 +00:00
|
|
|
}
|
|
|
|
words := strings.Split(mnemonic, " ")
|
2022-03-13 23:30:11 +00:00
|
|
|
validWordCount := 0
|
|
|
|
for _, word := range words {
|
2020-07-22 02:41:39 +00:00
|
|
|
if strings.Trim(word, " ") == "" {
|
2022-03-13 23:30:11 +00:00
|
|
|
continue
|
2020-07-22 02:41:39 +00:00
|
|
|
}
|
2022-03-13 23:30:11 +00:00
|
|
|
validWordCount += 1
|
2020-07-22 02:41:39 +00:00
|
|
|
}
|
2022-03-13 23:30:11 +00:00
|
|
|
if validWordCount != phraseWordCount {
|
|
|
|
return errors.Wrapf(ErrIncorrectWordNumber, "phrase must be %d words, entered %d", phraseWordCount, validWordCount)
|
2020-07-22 02:41:39 +00:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|