From 1f8a3d3f5a5d3e8ccc38c47076bb362378f8cb31 Mon Sep 17 00:00:00 2001 From: Sale Djenic Date: Mon, 21 Aug 2023 17:41:03 +0200 Subject: [PATCH] feat: endpoint `MakePartiallyOperableAccoutsFullyOperable` added --- multiaccounts/accounts/database.go | 20 +++++++++++++++++ services/accounts/accounts.go | 35 ++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/multiaccounts/accounts/database.go b/multiaccounts/accounts/database.go index 88f5aabbb..bd298dc25 100644 --- a/multiaccounts/accounts/database.go +++ b/multiaccounts/accounts/database.go @@ -1181,6 +1181,21 @@ func (db *Database) GetWalletAddress() (rst types.Address, err error) { return } +func (db *Database) GetProfileKeypair() (*Keypair, error) { + keypairs, err := db.getKeypairs(nil, "", false) + if err != nil { + return nil, err + } + + for _, kp := range keypairs { + if kp.Type == KeypairTypeProfile { + return kp, nil + } + } + + panic("no profile keypair among known keypairs") +} + func (db *Database) GetWalletAddresses() (rst []types.Address, err error) { rows, err := db.db.Query("SELECT address FROM keypairs_accounts WHERE chat = 0 AND removed = 0 ORDER BY created_at") if err != nil { @@ -1303,6 +1318,11 @@ func (db *Database) MarkKeypairFullyOperable(keyUID string, clock uint64) (err e return db.updateKeypairClock(tx, keyUID, clock) } +func (db *Database) MarkAccountFullyOperable(address types.Address) (err error) { + _, err = db.db.Exec(`UPDATE keypairs_accounts SET operable = ? WHERE address = ?`, AccountFullyOperable, address) + return err +} + // This function should not update the clock, cause it marks a keypair locally. func (db *Database) SetKeypairSyncedFrom(address types.Address, operable AccountOperable) (err error) { tx, err := db.db.Begin() diff --git a/services/accounts/accounts.go b/services/accounts/accounts.go index 33c9562d3..b5d26be1f 100644 --- a/services/accounts/accounts.go +++ b/services/accounts/accounts.go @@ -340,6 +340,41 @@ func (api *API) MakePrivateKeyKeypairFullyOperable(ctx context.Context, privateK return (*api.messenger).MarkKeypairFullyOperable(info.KeyUID) } +func (api *API) MakePartiallyOperableAccoutsFullyOperable(ctx context.Context, password string) (addresses []types.Address, err error) { + profileKeypair, err := api.db.GetProfileKeypair() + if err != nil { + return + } + + if len(profileKeypair.Keycards) == 0 && !api.VerifyPassword(password) { + err = errors.New("wrong password provided") + return + } + + keypairs, err := api.db.GetActiveKeypairs() + if err != nil { + return + } + + for _, kp := range keypairs { + for _, acc := range kp.Accounts { + if acc.Operable != accounts.AccountPartiallyOperable { + continue + } + err = api.createKeystoreFileForAccount(kp.DerivedFrom, password, acc) + if err != nil { + return + } + err = api.db.MarkAccountFullyOperable(acc.Address) + if err != nil { + return + } + addresses = append(addresses, acc.Address) + } + } + return +} + // Imports a new mnemonic and creates local keystore file. func (api *API) ImportMnemonic(ctx context.Context, mnemonic string, password string) error { mnemonicNoExtraSpaces := strings.Join(strings.Fields(mnemonic), " ")