2020-10-15 22:31:52 +00:00
|
|
|
package accounts
|
2020-07-15 04:05:21 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2021-01-12 16:52:01 +00:00
|
|
|
"encoding/json"
|
2020-07-15 04:05:21 +00:00
|
|
|
|
|
|
|
"github.com/pkg/errors"
|
2023-03-17 18:52:56 +00:00
|
|
|
"github.com/prysmaticlabs/prysm/v4/validator/accounts/iface"
|
|
|
|
"github.com/prysmaticlabs/prysm/v4/validator/accounts/wallet"
|
|
|
|
"github.com/prysmaticlabs/prysm/v4/validator/keymanager"
|
|
|
|
"github.com/prysmaticlabs/prysm/v4/validator/keymanager/derived"
|
|
|
|
"github.com/prysmaticlabs/prysm/v4/validator/keymanager/local"
|
2020-07-15 04:05:21 +00:00
|
|
|
)
|
|
|
|
|
2022-09-12 14:03:20 +00:00
|
|
|
// WalletCreate creates wallet specified by configuration options.
|
2022-09-02 14:56:47 +00:00
|
|
|
func (acm *AccountsCLIManager) WalletCreate(ctx context.Context) (*wallet.Wallet, error) {
|
2020-09-23 08:59:49 +00:00
|
|
|
w := wallet.New(&wallet.Config{
|
2022-09-02 14:56:47 +00:00
|
|
|
WalletDir: acm.walletDir,
|
|
|
|
KeymanagerKind: acm.keymanagerKind,
|
|
|
|
WalletPassword: acm.walletPassword,
|
2020-09-17 01:34:42 +00:00
|
|
|
})
|
2020-08-31 19:46:45 +00:00
|
|
|
var err error
|
2020-07-22 04:49:04 +00:00
|
|
|
switch w.KeymanagerKind() {
|
2022-02-01 19:54:19 +00:00
|
|
|
case keymanager.Local:
|
2022-06-16 14:14:03 +00:00
|
|
|
if err = CreateLocalKeymanagerWallet(ctx, w); err != nil {
|
2020-11-16 22:26:04 +00:00
|
|
|
return nil, errors.Wrap(err, "could not initialize wallet")
|
2020-07-15 04:05:21 +00:00
|
|
|
}
|
2022-01-31 16:44:17 +00:00
|
|
|
// TODO(#9883) - Remove this when we have a better way to handle this. should be safe to use for now.
|
2021-02-24 18:05:46 +00:00
|
|
|
km, err := w.InitializeKeymanager(ctx, iface.InitKeymanagerConfig{ListenForChanges: false})
|
2021-01-12 16:52:01 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, errors.Wrap(err, ErrCouldNotInitializeKeymanager)
|
|
|
|
}
|
2022-02-01 19:54:19 +00:00
|
|
|
localKm, ok := km.(*local.Keymanager)
|
2021-01-12 16:52:01 +00:00
|
|
|
if !ok {
|
|
|
|
return nil, errors.Wrap(err, ErrCouldNotInitializeKeymanager)
|
|
|
|
}
|
2022-02-01 19:54:19 +00:00
|
|
|
accountsKeystore, err := localKm.CreateAccountsKeystore(ctx, make([][]byte, 0), make([][]byte, 0))
|
2021-01-12 16:52:01 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
encodedAccounts, err := json.MarshalIndent(accountsKeystore, "", "\t")
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2022-02-01 19:54:19 +00:00
|
|
|
if err = w.WriteFileAtPath(ctx, local.AccountsPath, local.AccountsKeystoreFileName, encodedAccounts); err != nil {
|
2021-01-12 16:52:01 +00:00
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2022-09-02 14:56:47 +00:00
|
|
|
log.WithField("--wallet-dir", acm.walletDir).Info(
|
2020-11-16 22:26:04 +00:00
|
|
|
"Successfully created wallet with ability to import keystores",
|
2020-07-15 04:05:21 +00:00
|
|
|
)
|
2020-10-15 22:31:52 +00:00
|
|
|
case keymanager.Derived:
|
2020-11-16 22:26:04 +00:00
|
|
|
if err = createDerivedKeymanagerWallet(
|
|
|
|
ctx,
|
|
|
|
w,
|
2022-09-02 14:56:47 +00:00
|
|
|
acm.mnemonic25thWord,
|
2022-10-26 21:04:00 +00:00
|
|
|
acm.mnemonicLanguage,
|
2022-09-02 14:56:47 +00:00
|
|
|
acm.skipMnemonicConfirm,
|
|
|
|
acm.numAccounts,
|
2020-11-16 22:26:04 +00:00
|
|
|
); err != nil {
|
|
|
|
return nil, errors.Wrap(err, "could not initialize wallet")
|
2020-07-21 02:05:23 +00:00
|
|
|
}
|
2022-09-02 14:56:47 +00:00
|
|
|
log.WithField("--wallet-dir", acm.walletDir).Info(
|
2020-11-16 22:26:04 +00:00
|
|
|
"Successfully created HD wallet from mnemonic and regenerated accounts",
|
2020-07-21 02:05:23 +00:00
|
|
|
)
|
2022-01-31 16:44:17 +00:00
|
|
|
case keymanager.Web3Signer:
|
|
|
|
return nil, errors.New("web3signer keymanager does not require persistent wallets.")
|
2020-07-15 04:05:21 +00:00
|
|
|
default:
|
2021-01-22 20:21:34 +00:00
|
|
|
return nil, errors.Wrapf(err, errKeymanagerNotSupported, w.KeymanagerKind())
|
2020-07-15 04:05:21 +00:00
|
|
|
}
|
2020-07-29 01:20:13 +00:00
|
|
|
return w, nil
|
2020-07-15 04:05:21 +00:00
|
|
|
}
|
|
|
|
|
2022-06-16 14:14:03 +00:00
|
|
|
func CreateLocalKeymanagerWallet(_ context.Context, wallet *wallet.Wallet) error {
|
2020-08-04 22:53:34 +00:00
|
|
|
if wallet == nil {
|
|
|
|
return errors.New("nil wallet")
|
|
|
|
}
|
2020-07-24 00:43:01 +00:00
|
|
|
if err := wallet.SaveWallet(); err != nil {
|
|
|
|
return errors.Wrap(err, "could not save wallet to disk")
|
|
|
|
}
|
2020-07-15 04:05:21 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-10-27 20:51:29 +00:00
|
|
|
func createDerivedKeymanagerWallet(
|
|
|
|
ctx context.Context,
|
|
|
|
wallet *wallet.Wallet,
|
|
|
|
mnemonicPassphrase string,
|
2022-10-26 21:04:00 +00:00
|
|
|
mnemonicLanguage string,
|
2020-11-16 22:26:04 +00:00
|
|
|
skipMnemonicConfirm bool,
|
|
|
|
numAccounts int,
|
2020-10-27 20:51:29 +00:00
|
|
|
) error {
|
2020-11-16 22:26:04 +00:00
|
|
|
if wallet == nil {
|
|
|
|
return errors.New("nil wallet")
|
2020-07-21 02:05:23 +00:00
|
|
|
}
|
2020-07-24 00:43:01 +00:00
|
|
|
if err := wallet.SaveWallet(); err != nil {
|
|
|
|
return errors.Wrap(err, "could not save wallet to disk")
|
|
|
|
}
|
2020-11-16 22:26:04 +00:00
|
|
|
km, err := derived.NewKeymanager(ctx, &derived.SetupConfig{
|
2021-02-24 18:05:46 +00:00
|
|
|
Wallet: wallet,
|
|
|
|
ListenForChanges: true,
|
2020-10-27 20:51:29 +00:00
|
|
|
})
|
2020-08-25 19:30:26 +00:00
|
|
|
if err != nil {
|
2020-11-16 22:26:04 +00:00
|
|
|
return errors.Wrap(err, "could not initialize HD keymanager")
|
|
|
|
}
|
2022-10-26 21:04:00 +00:00
|
|
|
mnemonic, err := derived.GenerateAndConfirmMnemonic(mnemonicLanguage, skipMnemonicConfirm)
|
2020-11-16 22:26:04 +00:00
|
|
|
if err != nil {
|
|
|
|
return errors.Wrap(err, "could not confirm mnemonic")
|
|
|
|
}
|
2022-10-26 21:04:00 +00:00
|
|
|
if err := km.RecoverAccountsFromMnemonic(ctx, mnemonic, mnemonicLanguage, mnemonicPassphrase, numAccounts); err != nil {
|
2020-11-16 22:26:04 +00:00
|
|
|
return errors.Wrap(err, "could not recover accounts from mnemonic")
|
2020-08-25 19:30:26 +00:00
|
|
|
}
|
2020-07-21 02:05:23 +00:00
|
|
|
return nil
|
|
|
|
}
|