diff --git a/api/backend_test.go b/api/backend_test.go index 4d8509a8e..3d70c1949 100644 --- a/api/backend_test.go +++ b/api/backend_test.go @@ -849,7 +849,7 @@ func TestLoginAccount(t *testing.T) { } } - _, err := b.CreateAccountAndLogin(createAccountRequest) + acc, err := b.CreateAccountAndLogin(createAccountRequest) require.NoError(t, err) require.Equal(t, nameserver, b.config.WakuV2Config.Nameserver) @@ -861,6 +861,9 @@ func TestLoginAccount(t *testing.T) { require.NoError(t, err) require.Len(t, accounts, 1) + require.NotEmpty(t, accounts[0].KeyUID) + require.Equal(t, acc.KeyUID, accounts[0].KeyUID) + loginAccountRequest := &requests.Login{ KeyUID: accounts[0].KeyUID, Password: password, @@ -1380,6 +1383,10 @@ func TestCreateWallet(t *testing.T) { tmpdir := t.TempDir() b := NewGethStatusBackend() + defer func() { + require.NoError(t, b.StopNode()) + }() + createAccountRequest := &requests.CreateAccount{ DisplayName: "some-display-name", CustomizationColor: "#ffffff", diff --git a/api/geth_backend.go b/api/geth_backend.go index c198b01cb..08ab57f37 100644 --- a/api/geth_backend.go +++ b/api/geth_backend.go @@ -1289,7 +1289,18 @@ func (b *GethStatusBackend) RestoreAccountAndLogin(request *requests.RestoreAcco return nil, err } - return b.generateOrImportAccount(request.Mnemonic, 0, request.FetchBackup, &request.CreateAccount) + account, settings, nodeConfig, subAccounts, err := b.generateOrImportAccount(request.Mnemonic, 0, request.FetchBackup, &request.CreateAccount) + if err != nil { + return nil, err + } + + err = b.StartNodeWithAccountAndInitialConfig(*account, request.Password, *settings, nodeConfig, subAccounts) + if err != nil { + b.log.Error("start node", err) + return nil, err + } + + return account, nil } func (b *GethStatusBackend) GetKeyUIDByMnemonic(mnemonic string) (string, error) { @@ -1303,19 +1314,59 @@ func (b *GethStatusBackend) GetKeyUIDByMnemonic(mnemonic string) (string, error) return info.KeyUID, nil } -func (b *GethStatusBackend) generateOrImportAccount(mnemonic string, customizationColorClock uint64, fetchBackup bool, request *requests.CreateAccount, opts ...params.Option) (*multiaccounts.Account, error) { - keystoreDir := keystoreRelativePath - - b.UpdateRootDataDir(request.BackupDisabledDataDir) - err := b.OpenAccounts() +func (b *GethStatusBackend) generateOrImportAccount(mnemonic string, customizationColorClock uint64, fetchBackup bool, request *requests.CreateAccount, opts ...params.Option) (*multiaccounts.Account, *settings.Settings, *params.NodeConfig, []*accounts.Account, error) { + info, err := b.generateAccountInfo(mnemonic) if err != nil { - b.log.Error("failed open accounts", err) - return nil, err + return nil, nil, nil, nil, err } + keyStoreDir, err := b.initKeyStoreDirWithAccount(request.BackupDisabledDataDir, info.KeyUID) + if err != nil { + return nil, nil, nil, nil, err + } + + account, info, err := b.generateAccount(*info, customizationColorClock, request) + if err != nil { + return nil, nil, nil, nil, err + } + + derivedAddresses, err := b.getDerivedAddresses(info.ID) + if err != nil { + return nil, nil, nil, nil, err + } + + settings, err := b.prepareSettings(*info, derivedAddresses, request) + if err != nil { + return nil, nil, nil, nil, err + } + + processBackedupMessages := mnemonic != "" && fetchBackup + nodeConfig, err := b.prepareConfig(processBackedupMessages, account.KeyUID, keyStoreDir, request, opts...) + if err != nil { + return nil, nil, nil, nil, err + } + + subAccounts, err := b.prepareSubAccounts(mnemonic, account.KeyUID, derivedAddresses, request) + if err != nil { + return nil, nil, nil, nil, err + } + + return account, settings, nodeConfig, subAccounts, nil +} + +func (b *GethStatusBackend) initKeyStoreDirWithAccount(backupDisabledDataDir, keyUID string) (string, error) { + b.UpdateRootDataDir(backupDisabledDataDir) + keystoreDir := keystoreRelativePath + userKeyStoreDir := filepath.Join(keystoreDir, keyUID) + // Initialize keystore dir with account + return userKeyStoreDir, b.accountManager.InitKeystore(filepath.Join(b.rootDataDir, userKeyStoreDir)) +} + +func (b *GethStatusBackend) generateAccountInfo(mnemonic string) (*generator.GeneratedAccountInfo, error) { accountGenerator := b.accountManager.AccountsGenerator() var info generator.GeneratedAccountInfo + var err error if mnemonic == "" { // generate 1(n) account with default mnemonic length and no passphrase generatedAccountInfos, err := accountGenerator.Generate(defaultMnemonicLength, 1, "") @@ -1332,25 +1383,26 @@ func (b *GethStatusBackend) generateOrImportAccount(mnemonic string, customizati } } - derivedAddresses, err := accountGenerator.DeriveAddresses(info.ID, paths) + return &info, nil +} + +func (b *GethStatusBackend) generateAccount(info generator.GeneratedAccountInfo, customizationColorClock uint64, request *requests.CreateAccount) (*multiaccounts.Account, *generator.GeneratedAccountInfo, error) { + err := b.OpenAccounts() if err != nil { - return nil, err + b.log.Error("failed open accounts", "err", err) + return nil, nil, err } - userKeyStoreDir := filepath.Join(keystoreDir, info.KeyUID) - // Initialize keystore dir with account - if err := b.accountManager.InitKeystore(filepath.Join(b.rootDataDir, userKeyStoreDir)); err != nil { - return nil, err - } + accountGenerator := b.accountManager.AccountsGenerator() _, err = accountGenerator.StoreAccount(info.ID, request.Password) if err != nil { - return nil, err + return nil, nil, err } _, err = accountGenerator.StoreDerivedAccounts(info.ID, request.Password, paths) if err != nil { - return nil, err + return nil, nil, err } account := multiaccounts.Account{ @@ -1382,11 +1434,15 @@ func (b *GethStatusBackend) generateOrImportAccount(mnemonic string, customizati imageCropRectangle.Ax, imageCropRectangle.Ay, imageCropRectangle.Bx, imageCropRectangle.By) if err != nil { - return nil, err + return nil, nil, err } account.Images = iis } + return &account, &info, nil +} + +func (b *GethStatusBackend) prepareSettings(info generator.GeneratedAccountInfo, derivedAddresses map[string]generator.AccountInfo, request *requests.CreateAccount) (*settings.Settings, error) { settings, err := defaultSettings(info, derivedAddresses, nil) if err != nil { return nil, err @@ -1399,7 +1455,7 @@ func (b *GethStatusBackend) generateOrImportAccount(mnemonic string, customizati settings.TestNetworksEnabled = request.TestNetworksEnabled // If restoring an account, we don't set the mnemonic - if mnemonic == "" { + if info.Mnemonic == "" { settings.Mnemonic = &info.Mnemonic settings.OmitTransfersHistoryScan = true // TODO(rasom): uncomment it as soon as address will be properly @@ -1407,22 +1463,28 @@ func (b *GethStatusBackend) generateOrImportAccount(mnemonic string, customizati //settings.MnemonicWasNotShown = true } - nodeConfig, err := defaultNodeConfig(settings.InstallationID, request, opts...) + return settings, nil +} + +func (b *GethStatusBackend) prepareConfig(processBackedupMessages bool, installationID string, userKeyStoreDir string, request *requests.CreateAccount, opts ...params.Option) (*params.NodeConfig, error) { + nodeConfig, err := defaultNodeConfig(installationID, request, opts...) if err != nil { return nil, err } - if mnemonic != "" && fetchBackup { - nodeConfig.ProcessBackedupMessages = true - } + nodeConfig.ProcessBackedupMessages = processBackedupMessages // when we set nodeConfig.KeyStoreDir, value of nodeConfig.KeyStoreDir should not contain the rootDataDir // loadNodeConfig will add rootDataDir to nodeConfig.KeyStoreDir nodeConfig.KeyStoreDir = userKeyStoreDir + return nodeConfig, nil +} + +func (b *GethStatusBackend) prepareSubAccounts(mnemonic, keyUID string, derivedAddresses map[string]generator.AccountInfo, request *requests.CreateAccount) ([]*accounts.Account, error) { walletDerivedAccount := derivedAddresses[pathDefaultWallet] walletAccount := &accounts.Account{ PublicKey: types.Hex2Bytes(walletDerivedAccount.PublicKey), - KeyUID: info.KeyUID, + KeyUID: keyUID, Address: types.HexToAddress(walletDerivedAccount.Address), ColorID: multiacccommon.CustomizationColor(request.CustomizationColor), Emoji: request.Emoji, @@ -1438,21 +1500,24 @@ func (b *GethStatusBackend) generateOrImportAccount(mnemonic string, customizati chatDerivedAccount := derivedAddresses[pathDefaultChat] chatAccount := &accounts.Account{ PublicKey: types.Hex2Bytes(chatDerivedAccount.PublicKey), - KeyUID: info.KeyUID, + KeyUID: keyUID, Address: types.HexToAddress(chatDerivedAccount.Address), Name: request.DisplayName, Chat: true, Path: pathDefaultChat, } - subAccounts := []*accounts.Account{walletAccount, chatAccount} - err = b.StartNodeWithAccountAndInitialConfig(account, request.Password, *settings, nodeConfig, subAccounts) + return []*accounts.Account{walletAccount, chatAccount}, nil +} + +func (b *GethStatusBackend) getDerivedAddresses(id string) (map[string]generator.AccountInfo, error) { + accountGenerator := b.accountManager.AccountsGenerator() + derivedAddresses, err := accountGenerator.DeriveAddresses(id, paths) if err != nil { - b.log.Error("start node", err) return nil, err } - return &account, nil + return derivedAddresses, nil } // CreateAccountAndLogin creates a new account and logs in with it. @@ -1464,7 +1529,19 @@ func (b *GethStatusBackend) CreateAccountAndLogin(request *requests.CreateAccoun if err := request.Validate(validation); err != nil { return nil, err } - return b.generateOrImportAccount("", 1, false, request, opts...) + + account, settings, nodeConfig, subAccounts, err := b.generateOrImportAccount("", 1, false, request, opts...) + if err != nil { + return nil, err + } + + err = b.StartNodeWithAccountAndInitialConfig(*account, request.Password, *settings, nodeConfig, subAccounts) + if err != nil { + b.log.Error("start node", err) + return nil, err + } + + return account, nil } func (b *GethStatusBackend) ConvertToRegularAccount(mnemonic string, currPassword string, newPassword string) error {