refactor(@desktop/cpp): improve cpp code

Good coding practices applied only,
architecture and logic were not altered.
This commit is contained in:
Patryk Osmaczko 2022-02-22 09:02:34 +01:00 committed by osmaczko
parent d2d57036b5
commit c0024ec6b1
57 changed files with 455 additions and 500 deletions

View File

@ -16,5 +16,9 @@ AnalyzeTemporaryDtors: false
FormatStyle: none FormatStyle: none
CheckOptions: CheckOptions:
- key: cppcoreguidelines-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic - key: cppcoreguidelines-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic
value: 'true' value: true
- key: modernize-pass-by-value.ValuesOnly
value: true
- key: readability-implicit-bool-conversion.AllowPointerConditions
value: true
... ...

View File

@ -108,8 +108,16 @@ add_custom_command(
COMMENT "Building resources.rcc" COMMENT "Building resources.rcc"
COMMAND ${CMAKE_COMMAND} -E rm -f ${CMAKE_CURRENT_SOURCE_DIR}/resources.rcc COMMAND ${CMAKE_COMMAND} -E rm -f ${CMAKE_CURRENT_SOURCE_DIR}/resources.rcc
COMMAND ${CMAKE_COMMAND} -E rm -f ${CMAKE_CURRENT_SOURCE_DIR}/ui/resources.qrc COMMAND ${CMAKE_COMMAND} -E rm -f ${CMAKE_CURRENT_SOURCE_DIR}/ui/resources.qrc
COMMAND go run ${CMAKE_CURRENT_SOURCE_DIR}/ui/generate-rcc.go -source=${CMAKE_CURRENT_SOURCE_DIR}/ui -output=${CMAKE_CURRENT_SOURCE_DIR}/ui/resources.qrc COMMAND go run
COMMAND rcc $<$<CONFIG:Debug>:"-binary --no-compress">$<$<CONFIG:Release>:-binary> ${CMAKE_CURRENT_SOURCE_DIR}/ui/resources.qrc ${CMAKE_CURRENT_SOURCE_DIR}/resources/resources.qrc -o ${CMAKE_CURRENT_SOURCE_DIR}/resources.rcc ${CMAKE_CURRENT_SOURCE_DIR}/ui/generate-rcc.go
-source=${CMAKE_CURRENT_SOURCE_DIR}/ui
-output=${CMAKE_CURRENT_SOURCE_DIR}/ui/resources.qrc
COMMAND rcc
--binary
$<$<CONFIG:Debug>:--no-compress>
${CMAKE_CURRENT_SOURCE_DIR}/ui/resources.qrc
${CMAKE_CURRENT_SOURCE_DIR}/resources/resources.qrc
-o ${CMAKE_CURRENT_SOURCE_DIR}/resources.rcc
VERBATIM VERBATIM
USES_TERMINAL USES_TERMINAL
) )

View File

@ -26,6 +26,8 @@ AppController::AppController()
// result.osNotificationService = os_notification_service.newService(statusFoundation.status.events) // result.osNotificationService = os_notification_service.newService(statusFoundation.status.events)
// result.keychainService = keychain_service.newService(statusFoundation.status.events) // result.keychainService = keychain_service.newService(statusFoundation.status.events)
// result.ethService = eth_service.newService() // result.ethService = eth_service.newService()
// FIXME: it should be done in constructor member initializer list
m_accountsService = new Accounts::Service(); m_accountsService = new Accounts::Service();
m_walletServicePtr = std::make_shared<Wallets::Service>(); m_walletServicePtr = std::make_shared<Wallets::Service>();
// result.networkService = network_service.newService() // result.networkService = network_service.newService()
@ -68,6 +70,8 @@ AppController::AppController()
// result.settingsService, result.nodeConfigurationService, statusFoundation.fleetConfiguration) // result.settingsService, result.nodeConfigurationService, statusFoundation.fleetConfiguration)
// # Modules // # Modules
// FIXME: it should be done in constructor member initializer list
m_startupModule = new Modules::Startup::Module(this, /*keychainService,*/ m_accountsService); m_startupModule = new Modules::Startup::Module(this, /*keychainService,*/ m_accountsService);
m_mainModulePtr = new Modules::Main::Module(m_walletServicePtr, this); m_mainModulePtr = new Modules::Main::Module(m_walletServicePtr, this);
@ -104,6 +108,7 @@ AppController::AppController()
AppController::~AppController() AppController::~AppController()
{ {
// FIXME: `delete` should never be used, use RAII
delete m_startupModule; delete m_startupModule;
delete m_accountsService; delete m_accountsService;
} }
@ -113,6 +118,8 @@ void AppController::connect()
// self.statusFoundation.status.events.once("nodeStopped") do(a: Args): // self.statusFoundation.status.events.once("nodeStopped") do(a: Args):
// TODO: remove this once accounts are not tracked in the AccountsModel // TODO: remove this once accounts are not tracked in the AccountsModel
// self.statusFoundation.status.reset() // self.statusFoundation.status.reset()
// FIXME: use PointerToMember approach
QObject::connect(dynamic_cast<QObject*>(m_mainModulePtr), SIGNAL(loaded()), this, SLOT(mainDidLoad())); QObject::connect(dynamic_cast<QObject*>(m_mainModulePtr), SIGNAL(loaded()), this, SLOT(mainDidLoad()));
} }

View File

@ -1,5 +1,4 @@
#ifndef APP_CONTROLLER_H #pragma once
#define APP_CONTROLLER_H
#include <QObject> #include <QObject>
@ -23,6 +22,7 @@ class AppController : public QObject, AppControllerDelegate
//globalUtilsVariant: QVariant //globalUtilsVariant: QVariant
// Services // Services
// FIXME: don't use raw pointers
Accounts::Service* m_accountsService; Accounts::Service* m_accountsService;
std::shared_ptr<Wallets::Service> m_walletServicePtr; std::shared_ptr<Wallets::Service> m_walletServicePtr;
@ -33,8 +33,9 @@ class AppController : public QObject, AppControllerDelegate
public: public:
AppController(); AppController();
~AppController(); ~AppController() override;
void start(); void start();
public slots: public slots:
void mainDidLoad(); void mainDidLoad();
@ -46,5 +47,3 @@ private:
void buildAndRegisterLocalAccountSensitiveSettings(); void buildAndRegisterLocalAccountSensitiveSettings();
void buildAndRegisterUserProfile(); void buildAndRegisterUserProfile();
}; };
#endif // APP_CONTROLLER_H

View File

@ -9,12 +9,10 @@
namespace Signals namespace Signals
{ {
Manager* Manager::theInstance;
Manager* Manager::instance() Manager* Manager::instance()
{ {
if(theInstance == 0) theInstance = new Manager(); static auto manager = new Manager();
return theInstance; return manager;
} }
std::map<QString, SignalType> Manager::signalMap; std::map<QString, SignalType> Manager::signalMap;

View File

@ -1,5 +1,4 @@
#ifndef APPSECTION_CONFIG_H #pragma once
#define APPSECTION_CONFIG_H
// To Do: Currently this gets added to eahc file that its imported into need to create as enums in calss when some works on this potentially // To Do: Currently this gets added to eahc file that its imported into need to create as enums in calss when some works on this potentially
#include <QString> #include <QString>
@ -23,5 +22,3 @@ const QString NODEMANAGEMENT_SECTION_ICON = "node";
const QString SETTINGS_SECTION_ID = "profileSettings"; const QString SETTINGS_SECTION_ID = "profileSettings";
const QString SETTINGS_SECTION_NAME = "Settings"; const QString SETTINGS_SECTION_NAME = "Settings";
const QString SETTINGS_SECTION_ICON = "settings"; const QString SETTINGS_SECTION_ICON = "settings";
#endif // APPSECTION_CONFIG_H

View File

@ -3,21 +3,14 @@
namespace Global namespace Global
{ {
Singleton* Singleton::theInstance;
Singleton* Singleton::instance() Singleton* Singleton::instance()
{ {
if(theInstance == 0) theInstance = new Singleton(); static auto singleton = new Singleton();
return theInstance; return singleton;
}
Singleton::Singleton()
{
m_engine = new QQmlApplicationEngine();
} }
QQmlApplicationEngine* Singleton::engine() QQmlApplicationEngine* Singleton::engine()
{ {
return m_engine; return &m_engine;
} }
} // namespace Global } // namespace Global

View File

@ -48,7 +48,6 @@ signals:
void nodeCrashed(NodeSignal signal); void nodeCrashed(NodeSignal signal);
private: private:
static Manager* theInstance;
explicit Manager(QObject* parent = nullptr); explicit Manager(QObject* parent = nullptr);
static std::map<QString, SignalType> signalMap; static std::map<QString, SignalType> signalMap;
static void signalCallback(const char* data); static void signalCallback(const char* data);

View File

@ -8,13 +8,14 @@ namespace Global
class Singleton class Singleton
{ {
public: public:
// FIXME: should return reference
QQmlApplicationEngine* engine(); QQmlApplicationEngine* engine();
// FIXME: should return reference
static Singleton* instance(); static Singleton* instance();
private: private:
static Singleton* theInstance; Singleton() = default;
explicit Singleton(); QQmlApplicationEngine m_engine;
QQmlApplicationEngine* m_engine;
}; };
} // namespace Global } // namespace Global

View File

@ -4,10 +4,6 @@
namespace Modules::Main namespace Modules::Main
{ {
Controller::Controller(QObject* parent)
: QObject(parent)
{ }
void Controller::init() { } void Controller::init() { }
} // namespace Modules::Main } // namespace Modules::Main

View File

@ -1,5 +1,4 @@
#ifndef CONTROLLER_H #pragma once
#define CONTROLLER_H
#include <QObject> #include <QObject>
@ -12,12 +11,9 @@ namespace Modules::Main
class Controller : public QObject, public IController class Controller : public QObject, public IController
{ {
public: public:
explicit Controller(QObject* parent = nullptr); using QObject::QObject;
~Controller() = default;
void init() override; void init() override;
}; };
} // namespace Modules::Main } // namespace Modules::Main
#endif // CONTROLLER_H

View File

@ -1,5 +1,4 @@
#ifndef ICONTROLLER_H #pragma once
#define ICONTROLLER_H
namespace Modules::Main namespace Modules::Main
{ {
@ -8,7 +7,6 @@ class IController
{ {
public: public:
virtual void init() = 0; virtual void init() = 0;
virtual ~IController() = default;
}; };
} // namespace Modules::Main } // namespace Modules::Main
#endif // ICONTROLLER_H

View File

@ -1,5 +1,4 @@
#ifndef IMODULEACCESS_H #pragma once
#define IMODULEACCESS_H
#include <QObject> #include <QObject>
@ -10,11 +9,11 @@ class IModuleAccess
public: public:
virtual void load() = 0; virtual void load() = 0;
virtual bool isLoaded() = 0; virtual bool isLoaded() = 0;
virtual ~IModuleAccess() = default;
// FIXME: signals shouldn't be used in a class that is not QObject
signals: signals:
virtual void loaded() = 0; virtual void loaded() = 0;
}; };
} // namespace Modules::Main } // namespace Modules::Main
Q_DECLARE_INTERFACE(Modules::Main::IModuleAccess, "Modules::Main::IModuleAccess");
#endif // IMODULEACCESS_H

View File

@ -8,14 +8,14 @@
namespace Modules::Main namespace Modules::Main
{ {
Module::Module(std::shared_ptr<Wallets::ServiceInterface> walletsService, QObject* parent) Module::Module(std::shared_ptr<Wallets::ServiceInterface> walletService, QObject* parent)
: QObject(parent) : QObject(parent)
{ {
m_controllerPtr = new Controller(this); m_controllerPtr = new Controller(this);
m_viewPtr = new View(this); m_viewPtr = new View(this);
// Submodules // Submodules
m_walletModulePtr = new Modules::Main::Wallet::Module(walletsService, this); m_walletModulePtr = new Modules::Main::Wallet::Module(walletService, this);
m_moduleLoaded = false; m_moduleLoaded = false;
connect(); connect();
@ -24,6 +24,7 @@ Module::Module(std::shared_ptr<Wallets::ServiceInterface> walletsService, QObjec
void Module::connect() void Module::connect()
{ {
QObject::connect(m_viewPtr, &View::viewLoaded, this, &Module::viewDidLoad); QObject::connect(m_viewPtr, &View::viewLoaded, this, &Module::viewDidLoad);
// FIXME: use PointerToMember approach
QObject::connect(dynamic_cast<QObject*>(m_walletModulePtr), SIGNAL(loaded()), this, SLOT(walletDidLoad())); QObject::connect(dynamic_cast<QObject*>(m_walletModulePtr), SIGNAL(loaded()), this, SLOT(walletDidLoad()));
} }

View File

@ -1,5 +1,4 @@
#ifndef MODULE_H #pragma once
#define MODULE_H
#include <QObject> #include <QObject>
#include <QPointer> #include <QPointer>
@ -12,14 +11,12 @@
namespace Modules::Main namespace Modules::Main
{ {
class Module : public QObject, virtual public IModuleAccess class Module : public QObject, public IModuleAccess
{ {
Q_OBJECT Q_OBJECT
Q_INTERFACES(Modules::Main::IModuleAccess)
public: public:
explicit Module(std::shared_ptr<Wallets::ServiceInterface> walletService, QObject* parent = nullptr); explicit Module(std::shared_ptr<Wallets::ServiceInterface> walletService, QObject* parent = nullptr);
~Module() = default;
void load() override; void load() override;
bool isLoaded() override; bool isLoaded() override;
@ -35,13 +32,11 @@ private:
void connect(); void connect();
void checkIfModuleDidLoad(); void checkIfModuleDidLoad();
private: // FIXME: don't use raw pointers
// (should be either plain member, reference or smart pointer, depending on ownerhip)
View* m_viewPtr; View* m_viewPtr;
Controller* m_controllerPtr; Controller* m_controllerPtr;
Modules::Main::IModuleAccess* m_walletModulePtr; Modules::Main::IModuleAccess* m_walletModulePtr;
bool m_moduleLoaded; bool m_moduleLoaded;
}; };
} // namespace Modules::Main } // namespace Modules::Main
#endif // MODULE_H

View File

@ -3,12 +3,6 @@
namespace Modules::Main namespace Modules::Main
{ {
View::View(QObject* parent)
: QObject(parent)
{
m_sectionModelPtr = new Shared::Models::SectionModel(this);
}
void View::load() void View::load()
{ {
// Add Wallet Section to Sections model // Add Wallet Section to Sections model
@ -30,25 +24,25 @@ void View::load()
void View::addItem(Shared::Models::SectionItem* item) void View::addItem(Shared::Models::SectionItem* item)
{ {
m_sectionModelPtr->addItem(item); m_sectionModel.addItem(item);
emit sectionsModelChanged(); // emit sectionsModelChanged(); // FIXME: that's wrong, sectionModel* property didn't change
} }
Shared::Models::SectionModel* View::getSectionsModel() const Shared::Models::SectionModel* View::getSectionsModel()
{ {
return m_sectionModelPtr; return &m_sectionModel;
} }
Shared::Models::SectionItem* View::getActiveSection() const Shared::Models::SectionItem* View::getActiveSection() const
{ {
return m_sectionModelPtr->getActiveItem(); return m_sectionModel.getActiveItem();
} }
void View::setActiveSection(const QString& Id) void View::setActiveSection(const QString& Id)
{ {
if(m_sectionModelPtr->getActiveItem().isNull() || (m_sectionModelPtr->getActiveItem()->getId() != Id)) if(m_sectionModel.getActiveItem().isNull() || (m_sectionModel.getActiveItem()->getId() != Id))
{ {
m_sectionModelPtr->setActiveSection(Id); m_sectionModel.setActiveSection(Id);
activeSectionChanged(); activeSectionChanged();
} }
} }

View File

@ -1,5 +1,4 @@
#ifndef VIEW_H #pragma once
#define VIEW_H
#include <QObject> #include <QObject>
#include <memory> #include <memory>
@ -15,14 +14,12 @@ class View : public QObject
Q_PROPERTY(Shared::Models::SectionItem* activeSection READ getActiveSection NOTIFY activeSectionChanged) Q_PROPERTY(Shared::Models::SectionItem* activeSection READ getActiveSection NOTIFY activeSectionChanged)
public: public:
explicit View(QObject* parent = nullptr); using QObject::QObject;
~View() = default;
void load(); void load();
void addItem(Shared::Models::SectionItem* item); void addItem(Shared::Models::SectionItem* item);
Shared::Models::SectionModel* getSectionsModel() const;
Shared::Models::SectionItem* getActiveSection() const;
void setActiveSection(const QString& Id); void setActiveSection(const QString& Id);
signals: signals:
@ -31,8 +28,9 @@ signals:
void activeSectionChanged(); void activeSectionChanged();
private: private:
Shared::Models::SectionModel* m_sectionModelPtr; Shared::Models::SectionModel* getSectionsModel();
Shared::Models::SectionItem* getActiveSection() const;
Shared::Models::SectionModel m_sectionModel;
}; };
} // namespace Modules::Main } // namespace Modules::Main
#endif // VIEW_H

View File

@ -1,5 +1,4 @@
#ifndef WALLET_ACCOUNT_CONTROLLER_H #pragma once
#define WALLET_ACCOUNT_CONTROLLER_H
#include <QObject> #include <QObject>
@ -16,20 +15,23 @@ class Controller : public QObject, public IController
public: public:
explicit Controller(std::shared_ptr<Wallets::ServiceInterface> walletService, QObject* parent = nullptr); explicit Controller(std::shared_ptr<Wallets::ServiceInterface> walletService, QObject* parent = nullptr);
~Controller() = default;
void init() override; void init() override;
QList<Wallets::WalletAccountDto> getWalletAccounts(); QList<Wallets::WalletAccountDto> getWalletAccounts();
QString generateNewAccount(const QString& password, const QString& accountName, const QString& color); QString generateNewAccount(const QString& password, const QString& accountName, const QString& color);
QString addAccountsFromPrivateKey(const QString& privateKey, const QString& password, const QString& accountName, const QString& color); QString addAccountsFromPrivateKey(const QString& privateKey,
QString addAccountsFromSeed(const QString& seedPhrase, const QString& password, const QString& accountName, const QString& color); const QString& password,
QString addWatchOnlyAccount(const QString& address, const QString& accountName , const QString& color); const QString& accountName,
const QString& color);
QString addAccountsFromSeed(const QString& seedPhrase,
const QString& password,
const QString& accountName,
const QString& color);
QString addWatchOnlyAccount(const QString& address, const QString& accountName, const QString& color);
void deleteAccount(const QString& address); void deleteAccount(const QString& address);
private: private:
std::shared_ptr<Wallets::ServiceInterface> m_walletServicePtr; std::shared_ptr<Wallets::ServiceInterface> m_walletServicePtr;
}; };
} // namespace Modules::Main::Wallet::Accounts } // namespace Modules::Main::Wallet::Accounts
#endif // WALLET_ACCOUNT_CONTROLLER_H

View File

@ -1,12 +1,11 @@
#ifndef WALLET_ACCOUNT_ITEM_H #pragma once
#define WALLET_ACCOUNT_ITEM_H
#include <QObject> #include <QObject>
#include <QString> #include <QString>
namespace Modules::Main::Wallet::Accounts namespace Modules::Main::Wallet::Accounts
{ {
class Item: public QObject class Item : public QObject
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY(QString name READ getName NOTIFY nameChanged); Q_PROPERTY(QString name READ getName NOTIFY nameChanged);
@ -30,7 +29,6 @@ public:
bool isWallet = false, bool isWallet = false,
bool isChat = false, bool isChat = false,
float currencyBalance = 0); float currencyBalance = 0);
~Item() = default;
const QString& getName() const; const QString& getName() const;
const QString& getAddress() const; const QString& getAddress() const;
@ -41,7 +39,7 @@ public:
bool getIsWallet() const; bool getIsWallet() const;
bool getIsChat() const; bool getIsChat() const;
float getCurrencyBalance() const; float getCurrencyBalance() const;
void setData(Item *item); void setData(Item* item);
signals: signals:
void nameChanged(); void nameChanged();
@ -64,8 +62,5 @@ private:
bool m_isWallet; bool m_isWallet;
bool m_isChat; bool m_isChat;
float m_currencyBalance; float m_currencyBalance;
}; };
} // namespace Modules::Main::Wallet::Accounts } // namespace Modules::Main::Wallet::Accounts
#endif // WALLET_ACCOUNT_ITEM_H

View File

@ -1,5 +1,4 @@
#ifndef WALLET_ACCOUNT_MODEL_H #pragma once
#define WALLET_ACCOUNT_MODEL_H
#include <QAbstractListModel> #include <QAbstractListModel>
#include <QHash> #include <QHash>
@ -29,7 +28,6 @@ public:
}; };
explicit Model(QObject* parent = nullptr); explicit Model(QObject* parent = nullptr);
~Model() = default;
QHash<int, QByteArray> roleNames() const override; QHash<int, QByteArray> roleNames() const override;
int rowCount(const QModelIndex&) const override; int rowCount(const QModelIndex&) const override;
@ -41,5 +39,3 @@ private:
QVector<Item*> m_items; QVector<Item*> m_items;
}; };
} // namespace Modules::Main::Wallet::Accounts } // namespace Modules::Main::Wallet::Accounts
#endif // WALLET_ACCOUNT_MODEL_H

View File

@ -1,5 +1,4 @@
#ifndef WALLET_ACCOUNT_MODULE_H #pragma once
#define WALLET_ACCOUNT_MODULE_H
#include <QObject> #include <QObject>
@ -13,10 +12,8 @@ namespace Modules::Main::Wallet::Accounts
class Module : public QObject, virtual public IModuleAccess class Module : public QObject, virtual public IModuleAccess
{ {
Q_OBJECT Q_OBJECT
Q_INTERFACES(Modules::Main::IModuleAccess)
public: public:
explicit Module(std::shared_ptr<Wallets::ServiceInterface> walletsService, QObject* parent); explicit Module(std::shared_ptr<Wallets::ServiceInterface> walletsService, QObject* parent = nullptr);
~Module() = default;
void load() override; void load() override;
bool isLoaded() override; bool isLoaded() override;
@ -30,12 +27,9 @@ signals:
private: private:
void connect(); void connect();
private:
View* m_viewPtr; View* m_viewPtr;
Controller* m_controllerPtr; Controller* m_controllerPtr;
bool m_moduleLoaded; bool m_moduleLoaded;
}; };
} // namespace Modules::Main::Wallet::Accounts } // namespace Modules::Main::Wallet::Accounts
#endif // WALLET_ACCOUNT_MODULE_H

View File

@ -1,12 +1,11 @@
#ifndef WALLET_ACCOUNT_VIEW_H #pragma once
#define WALLET_ACCOUNT_VIEW_H
#include <QObject> #include <QObject>
#include <memory> #include <memory>
#include "model.h"
#include "controller.h" #include "controller.h"
#include "item.h" #include "item.h"
#include "model.h"
namespace Modules::Main::Wallet::Accounts namespace Modules::Main::Wallet::Accounts
{ {
@ -18,7 +17,6 @@ class View : public QObject
public: public:
explicit View(Controller* controller, QObject* parent = nullptr); explicit View(Controller* controller, QObject* parent = nullptr);
~View() = default;
void load(); void load();
void setModelItems(const QVector<Item*>& accounts); void setModelItems(const QVector<Item*>& accounts);
@ -26,9 +24,15 @@ public:
Item* getCurrentAccount() const; Item* getCurrentAccount() const;
Q_INVOKABLE QString generateNewAccount(const QString& password, const QString& accountName, const QString& color); Q_INVOKABLE QString generateNewAccount(const QString& password, const QString& accountName, const QString& color);
Q_INVOKABLE QString addAccountsFromPrivateKey(const QString& privateKey, const QString& password, const QString& accountName, const QString& color); Q_INVOKABLE QString addAccountsFromPrivateKey(const QString& privateKey,
Q_INVOKABLE QString addAccountsFromSeed(const QString& seedPhrase, const QString& password, const QString& accountName, const QString& color); const QString& password,
Q_INVOKABLE QString addWatchOnlyAccount(const QString& address, const QString& accountName , const QString& color); const QString& accountName,
const QString& color);
Q_INVOKABLE QString addAccountsFromSeed(const QString& seedPhrase,
const QString& password,
const QString& accountName,
const QString& color);
Q_INVOKABLE QString addWatchOnlyAccount(const QString& address, const QString& accountName, const QString& color);
Q_INVOKABLE void deleteAccount(const QString& address); Q_INVOKABLE void deleteAccount(const QString& address);
Q_INVOKABLE void switchAccount(int index); Q_INVOKABLE void switchAccount(int index);
@ -40,11 +44,8 @@ signals:
private: private:
void refreshWalletAccounts(); void refreshWalletAccounts();
private:
Model* m_modelPtr; Model* m_modelPtr;
Controller* m_controllerPtr; Controller* m_controllerPtr;
Item* m_currentAccountPtr; Item* m_currentAccountPtr;
}; };
} // namespace Modules::Main::Wallet::Accounts } // namespace Modules::Main::Wallet::Accounts
#endif // WALLET_ACCOUNT_VIEW_H

View File

@ -1,5 +1,4 @@
#ifndef WALLET_CONTROLLER_H #pragma once
#define WALLET_CONTROLLER_H
#include <QObject> #include <QObject>
@ -15,12 +14,9 @@ class Controller : public QObject, public IController
public: public:
explicit Controller(std::shared_ptr<Wallets::ServiceInterface> walletService, QObject* parent = nullptr); explicit Controller(std::shared_ptr<Wallets::ServiceInterface> walletService, QObject* parent = nullptr);
~Controller() = default;
void init() override; void init() override;
private: private:
std::shared_ptr<Wallets::ServiceInterface> m_walletService; std::shared_ptr<Wallets::ServiceInterface> m_walletService;
}; };
} // namespace Modules::Main::Wallet } // namespace Modules::Main::Wallet
#endif // WALLET_CONTROLLER_H

View File

@ -1,5 +1,4 @@
#ifndef WALLET_MODULE_H #pragma once
#define WALLET_MODULE_H
#include <QObject> #include <QObject>
@ -14,11 +13,9 @@ namespace Modules::Main::Wallet
class Module : public QObject, virtual public IModuleAccess class Module : public QObject, virtual public IModuleAccess
{ {
Q_OBJECT Q_OBJECT
Q_INTERFACES(Modules::Main::IModuleAccess)
public: public:
explicit Module(std::shared_ptr<Wallets::ServiceInterface> walletsService, QObject* parent); explicit Module(std::shared_ptr<Wallets::ServiceInterface> walletsService, QObject* parent);
~Module() = default;
void load() override; void load() override;
bool isLoaded() override; bool isLoaded() override;
@ -35,12 +32,9 @@ signals:
private: private:
void connect(); void connect();
private:
View* m_viewPtr; View* m_viewPtr;
Controller* m_controllerPtr; Controller* m_controllerPtr;
IModuleAccess* m_accountsModulePtr; IModuleAccess* m_accountsModulePtr;
bool m_moduleLoaded; bool m_moduleLoaded;
}; };
} // namespace Modules::Main::Wallet } // namespace Modules::Main::Wallet
#endif // WALLET_MODULE_H

View File

@ -1,5 +1,4 @@
#ifndef WALLET_VIEW_H #pragma once
#define WALLET_VIEW_H
#include <QObject> #include <QObject>
@ -11,7 +10,6 @@ class View : public QObject
public: public:
explicit View(QObject* parent = nullptr); explicit View(QObject* parent = nullptr);
~View() = default;
void load(); void load();
@ -19,5 +17,3 @@ signals:
void viewLoaded(); void viewLoaded();
}; };
} // namespace Modules::Main::Wallet } // namespace Modules::Main::Wallet
#endif // WALLET_VIEW_H

View File

@ -1,5 +1,4 @@
#ifndef SECTION_ITEM_H #pragma once
#define SECTION_ITEM_H
#include <QObject> #include <QObject>
#include <QString> #include <QString>
@ -16,11 +15,12 @@ enum SectionType
ProfileSettings, ProfileSettings,
NodeManagement NodeManagement
}; };
class SectionItem : public QObject class SectionItem : public QObject
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY(QString id READ getId) Q_PROPERTY(QString id READ getId)
Q_PROPERTY(int sectionType READ getSectionType) Q_PROPERTY(int sectionType READ getSectionType) // FIXME: use enum instead of int
Q_PROPERTY(QString name READ getName) Q_PROPERTY(QString name READ getName)
Q_PROPERTY(bool amISectionAdmin READ getAmISectionAdmin) Q_PROPERTY(bool amISectionAdmin READ getAmISectionAdmin)
Q_PROPERTY(QString description READ getDescription) Q_PROPERTY(QString description READ getDescription)
@ -40,6 +40,9 @@ class SectionItem : public QObject
Q_PROPERTY(bool ensOnly READ getIsEnsOnly) Q_PROPERTY(bool ensOnly READ getIsEnsOnly)
public: public:
// FIXME: very long constructor, consider only list of necessary parameters (id, parent)?
// others could be altered by setters
// FIXME: Qt's convention is to put parent at the end of parameters list
SectionItem(QObject* parent = nullptr, SectionItem(QObject* parent = nullptr,
const QString& id = "", const QString& id = "",
SectionType sectionType = SectionType::Unkown, SectionType sectionType = SectionType::Unkown,
@ -113,5 +116,3 @@ private:
// pendingRequestsToJoinModel: PendingRequestModel // pendingRequestsToJoinModel: PendingRequestModel
}; };
} // namespace Shared::Models } // namespace Shared::Models
#endif // SECTION_ITEM_H

View File

@ -73,7 +73,8 @@ QVariant SectionModel::data(const QModelIndex& index, int role) const
case CanManageUsers: return item->getCanManageUsers(); case CanManageUsers: return item->getCanManageUsers();
case CanRequestAccess: return item->getCanRequestAccess(); case CanRequestAccess: return item->getCanRequestAccess();
case Access: return item->getAccess(); case Access: return item->getAccess();
case EnsOnly: return item->getIsEnsOnly(); case EnsOnly:
return item->getIsEnsOnly();
// To Do // To Do
case MembersModel: return QVariant(); case MembersModel: return QVariant();
case PendingRequestsToJoinModel: return QVariant(); case PendingRequestsToJoinModel: return QVariant();
@ -108,7 +109,7 @@ void SectionModel::setActiveSection(const QString& Id)
} }
} }
QPointer<SectionItem> SectionModel::getActiveItem() QPointer<SectionItem> SectionModel::getActiveItem() const
{ {
SectionItem* activeItem = nullptr; SectionItem* activeItem = nullptr;
for(auto item : m_items) for(auto item : m_items)

View File

@ -1,5 +1,4 @@
#ifndef SECTION_MODEL_H #pragma once
#define SECTION_MODEL_H
#include <QAbstractListModel> #include <QAbstractListModel>
#include <QHash> #include <QHash>
@ -50,7 +49,7 @@ public:
void addItem(SectionItem* item); void addItem(SectionItem* item);
void setActiveSection(const QString& Id); void setActiveSection(const QString& Id);
QPointer<SectionItem> getActiveItem(); QPointer<SectionItem> getActiveItem() const;
// To add other api's later as needed // To add other api's later as needed
@ -59,5 +58,3 @@ private:
}; };
} // namespace Shared::Models } // namespace Shared::Models
#endif // SECTION_MODEL_H

View File

@ -1,4 +1,5 @@
#include "constants.h" #include "constants.h"
#include <QDir> #include <QDir>
#include <QFileInfo> #include <QFileInfo>
#include <QStandardPaths> #include <QStandardPaths>
@ -6,17 +7,17 @@
// TODO: merge with constants from backend/ // TODO: merge with constants from backend/
QString Constants::applicationPath(QString path) QString Constants::applicationPath(const QString& path)
{ {
return QFileInfo(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + path).absoluteFilePath(); return QFileInfo(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + path).absoluteFilePath();
} }
QString Constants::tmpPath(QString path) QString Constants::tmpPath(const QString& path)
{ {
return QFileInfo(QStandardPaths::writableLocation(QStandardPaths::TempLocation) + path).absoluteFilePath(); return QFileInfo(QStandardPaths::writableLocation(QStandardPaths::TempLocation) + path).absoluteFilePath();
} }
QString Constants::cachePath(QString path) QString Constants::cachePath(const QString& path)
{ {
return QFileInfo(QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + path).absoluteFilePath(); return QFileInfo(QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + path).absoluteFilePath();
} }

View File

@ -28,10 +28,10 @@ public:
QString keyUid; QString keyUid;
QVector<Image> images; QVector<Image> images;
bool isValid(); bool isValid() const;
}; };
Image toImage(const QJsonValue jsonObj); Image toImage(const QJsonValue& jsonObj);
AccountDto toAccountDto(const QJsonValue jsonObj); AccountDto toAccountDto(const QJsonValue& jsonObj);
} // namespace Accounts } // namespace Accounts

View File

@ -36,12 +36,12 @@ public:
QString alias; QString alias;
QString identicon; QString identicon;
bool isValid(); bool isValid() const;
}; };
DerivedAccountDetails toDerivedAccountDetails(const QJsonValue jsonObj, QString derivationPath); DerivedAccountDetails toDerivedAccountDetails(const QJsonValue& jsonObj, const QString& derivationPath);
DerivedAccounts toDerivedAccounts(const QJsonObject jsonObj); DerivedAccounts toDerivedAccounts(const QJsonObject& jsonObj);
GeneratedAccountDto toGeneratedAccountDto(const QJsonValue jsonObj); GeneratedAccountDto toGeneratedAccountDto(const QJsonValue& jsonObj);
} // namespace Accounts } // namespace Accounts

View File

@ -3,31 +3,29 @@
#include "account.h" #include "account.h"
#include "generated_account.h" #include "generated_account.h"
#include "service_interface.h" #include "service_interface.h"
#include <QString> #include <QString>
#include <QVector> #include <QVector>
namespace Accounts namespace Accounts
{ {
class Service : public ServiceInterface class Service : public ServiceInterface
{ {
private: private:
QVector<GeneratedAccountDto> m_generatedAccounts; QVector<GeneratedAccountDto> m_generatedAccounts;
bool m_isFirstTimeAccountLogin; bool m_isFirstTimeAccountLogin = false;
AccountDto m_loggedInAccount; AccountDto m_loggedInAccount;
GeneratedAccountDto m_importedAccount; GeneratedAccountDto m_importedAccount;
public: public:
Service();
void init() override; void init() override;
virtual QVector<AccountDto> openedAccounts() override; QVector<AccountDto> openedAccounts() override;
QVector<GeneratedAccountDto> generatedAccounts() override; QVector<GeneratedAccountDto> generatedAccounts() override;
bool setupAccount(QString accountId, QString password) override; bool setupAccount(const QString& accountId, const QString& password) override;
AccountDto getLoggedInAccount() override; AccountDto getLoggedInAccount() override;
@ -35,38 +33,34 @@ public:
bool isFirstTimeAccountLogin() override; bool isFirstTimeAccountLogin() override;
QString validateMnemonic(QString mnemonic) override; QString validateMnemonic(const QString& mnemonic) override;
bool importMnemonic(QString mnemonic) override; bool importMnemonic(const QString& mnemonic) override;
QString login(AccountDto account, QString password) override; QString login(const AccountDto& account, const QString& password) override;
void clear() override; void clear() override;
QString generateAlias(QString publicKey) override; QString generateAlias(const QString& publicKey) override;
QString generateIdenticon(QString publicKey) override; QString generateIdenticon(const QString& publicKey) override;
bool verifyAccountPassword(QString account, QString password) override; bool verifyAccountPassword(const QString& account, const QString& password) override;
DerivedAccounts storeDerivedAccounts(QString accountId, QString hashedPassword, QVector<QString> paths); DerivedAccounts
storeDerivedAccounts(const QString& accountId, const QString& hashedPassword, const QVector<QString>& paths);
QJsonObject getAccountDataForAccountId(QString accountId); QJsonObject getAccountDataForAccountId(const QString& accountId);
QJsonArray getSubaccountDataForAccountId(QString accountId); QJsonArray getSubaccountDataForAccountId(const QString& accountId);
QJsonObject getAccountSettings(QString accountId, QString installationId); QJsonObject getAccountSettings(const QString& accountId, const QString& installationId);
QJsonObject getDefaultNodeConfig(QString installationId); AccountDto saveAccountAndLogin(const QString& hashedPassword,
const QJsonObject& account,
QJsonObject prepareAccountJsonObject(const GeneratedAccountDto account); const QJsonArray& subaccounts,
const QJsonObject& settings,
QJsonArray prepareSubaccountJsonObject(GeneratedAccountDto account); const QJsonObject& config);
QJsonObject prepareAccountSettingsJsonObject(const GeneratedAccountDto account, QString installationId);
AccountDto saveAccountAndLogin(
QString hashedPassword, QJsonObject account, QJsonArray subaccounts, QJsonObject settings, QJsonObject config);
}; };
} // namespace Accounts } // namespace Accounts

View File

@ -17,7 +17,7 @@ public:
virtual QVector<GeneratedAccountDto> generatedAccounts() = 0; virtual QVector<GeneratedAccountDto> generatedAccounts() = 0;
virtual bool setupAccount(QString accountId, QString password) = 0; virtual bool setupAccount(const QString& accountId, const QString& password) = 0;
virtual AccountDto getLoggedInAccount() = 0; virtual AccountDto getLoggedInAccount() = 0;
@ -25,19 +25,19 @@ public:
virtual bool isFirstTimeAccountLogin() = 0; virtual bool isFirstTimeAccountLogin() = 0;
virtual QString validateMnemonic(QString mnemonic) = 0; virtual QString validateMnemonic(const QString& mnemonic) = 0;
virtual bool importMnemonic(QString mnemonic) = 0; virtual bool importMnemonic(const QString& mnemonic) = 0;
virtual QString login(AccountDto account, QString password) = 0; virtual QString login(const AccountDto& account, const QString& password) = 0;
virtual void clear() = 0; virtual void clear() = 0;
virtual QString generateAlias(QString publicKey) = 0; virtual QString generateAlias(const QString& publicKey) = 0;
virtual QString generateIdenticon(QString publicKey) = 0; virtual QString generateIdenticon(const QString& publicKey) = 0;
virtual bool verifyAccountPassword(QString account, QString password) = 0; virtual bool verifyAccountPassword(const QString& account, const QString& password) = 0;
}; };
} // namespace Accounts } // namespace Accounts

View File

@ -4,4 +4,5 @@ class AppService
{ {
public: public:
virtual void init() = 0; virtual void init() = 0;
virtual ~AppService() = default;
}; };

View File

@ -31,8 +31,8 @@ const QString DefaultNetworkName = "mainnet_rpc";
const QString DataDir = "/data"; const QString DataDir = "/data";
const QString Keystore = "/data/keystore"; const QString Keystore = "/data/keystore";
QString applicationPath(QString path = ""); QString applicationPath(const QString& path = "");
QString tmpPath(QString path = ""); QString tmpPath(const QString& path = "");
QString cachePath(QString path = ""); QString cachePath(const QString& path = "");
} // namespace Constants } // namespace Constants

View File

@ -1,17 +1,16 @@
#ifndef WALLETACCOUNTSSERVICE_H #pragma once
#define WALLETACCOUNTSSERVICE_H
#include <QString> #include <QString>
#include <QMap> #include <QMap>
#include <QObject> #include <QObject>
#include "wallet_account.h"
#include "service_interface.h" #include "service_interface.h"
#include "wallet_account.h"
namespace Wallets namespace Wallets
{ {
class Service : public ServiceInterface, public QObject class Service : public QObject, public ServiceInterface
{ {
private: private:
void fetchAccounts(); void fetchAccounts();
@ -20,9 +19,6 @@ private:
QMap<QString, WalletAccountDto> m_walletAccounts; QMap<QString, WalletAccountDto> m_walletAccounts;
public: public:
Service();
~Service() = default;
void init() override; void init() override;
QList<WalletAccountDto> getWalletAccounts() override; QList<WalletAccountDto> getWalletAccounts() override;
@ -34,5 +30,3 @@ public:
}; };
} // namespace Wallets } // namespace Wallets
#endif // WALLETACCOUNTSERVICE_H

View File

@ -1,16 +1,15 @@
#ifndef WALLETACCOUNTSSERVICEINTERFACE_H #pragma once
#define WALLETACCOUNTSSERVICEINTERFACE_H
#include <QJsonValue>
#include <QList>
#include <memory>
#include "../app_service.h" #include "../app_service.h"
#include "wallet_account.h" #include "wallet_account.h"
#include <memory>
#include <QJsonValue>
#include <QList>
namespace Wallets namespace Wallets
{ {
class ServiceInterface : public AppService class ServiceInterface : public AppService
{ {
public: public:
@ -23,5 +22,3 @@ public:
}; };
} // namespace Wallets } // namespace Wallets
#endif // WALLETACCOUNTSSERVICEINTERFACE_H

View File

@ -1,7 +1,7 @@
#ifndef WALLETACCOUNTDTO_H #pragma once
#define WALLETACCOUNTDTO_H
#include "wallet_token.h" #include "wallet_token.h"
#include <QJsonValue> #include <QJsonValue>
#include <QString> #include <QString>
#include <QVector> #include <QVector>
@ -22,11 +22,6 @@ public:
QVector<WalletTokenDto> tokens; QVector<WalletTokenDto> tokens;
}; };
WalletAccountDto toWalletAccountDto(const QJsonValue jsonObj); WalletAccountDto toWalletAccountDto(const QJsonValue& jsonObj);
//WalletAccountDto getCurrencyBalance*(): float =
// return self.tokens.map(t => t.currencyBalance).foldl(a + b, 0.0)
} // namespace Wallets } // namespace Wallets
#endif // WALLETACCOUNTDTO_H

View File

@ -1,5 +1,4 @@
#ifndef WALLETTOKENDTO_H #pragma once
#define WALLETTOKENDTO_H
#include <QJsonValue> #include <QJsonValue>
#include <QString> #include <QString>
@ -22,5 +21,3 @@ public:
}; };
} // namespace Wallets } // namespace Wallets
#endif // WALLETTOKENDTO_H

View File

@ -5,12 +5,12 @@
#include <QJsonValue> #include <QJsonValue>
#include <QStringList> #include <QStringList>
bool Accounts::AccountDto::isValid() bool Accounts::AccountDto::isValid() const
{ {
return name.length() > 0 && keyUid.length() > 0; return name.length() > 0 && keyUid.length() > 0;
} }
Accounts::Image Accounts::toImage(const QJsonValue jsonObj) Accounts::Image Accounts::toImage(const QJsonValue& jsonObj)
{ {
auto result = Accounts::Image(); auto result = Accounts::Image();
@ -25,7 +25,7 @@ Accounts::Image Accounts::toImage(const QJsonValue jsonObj)
return result; return result;
} }
Accounts::AccountDto Accounts::toAccountDto(const QJsonValue jsonObj) Accounts::AccountDto Accounts::toAccountDto(const QJsonValue& jsonObj)
{ {
auto result = Accounts::AccountDto(); auto result = Accounts::AccountDto();

View File

@ -1,17 +1,19 @@
#include "accounts/generated_account.h" #include "accounts/generated_account.h"
#include "backend/accounts.h" #include "backend/accounts.h"
#include <QDebug> #include <QDebug>
#include <QJsonArray> #include <QJsonArray>
#include <QJsonObject> #include <QJsonObject>
#include <QJsonValue> #include <QJsonValue>
#include <QStringList> #include <QStringList>
bool Accounts::GeneratedAccountDto::isValid() bool Accounts::GeneratedAccountDto::isValid() const
{ {
return id.length() > 0 && publicKey.length() > 0 && address.length() > 0 && keyUid.length() > 0; return id.length() > 0 && publicKey.length() > 0 && address.length() > 0 && keyUid.length() > 0;
} }
Accounts::DerivedAccountDetails Accounts::toDerivedAccountDetails(const QJsonValue jsonObj, QString derivationPath) Accounts::DerivedAccountDetails Accounts::toDerivedAccountDetails(const QJsonValue& jsonObj,
const QString& derivationPath)
{ {
// Mapping this DTO is not strightforward since only keys are used for id. We // Mapping this DTO is not strightforward since only keys are used for id. We
// handle it a bit different. // handle it a bit different.
@ -24,25 +26,25 @@ Accounts::DerivedAccountDetails Accounts::toDerivedAccountDetails(const QJsonVal
return result; return result;
} }
Accounts::DerivedAccounts Accounts::toDerivedAccounts(const QJsonObject jsonObj) Accounts::DerivedAccounts Accounts::toDerivedAccounts(const QJsonObject& jsonObj)
{ {
auto result = Accounts::DerivedAccounts(); auto result = Accounts::DerivedAccounts();
foreach(const QString& derivationPath, jsonObj.keys()) foreach(const QString& derivationPath, jsonObj.keys())
{ {
QJsonValue derivedObj = jsonObj.value(derivationPath); QJsonValue derivedObj = jsonObj.value(derivationPath);
if(derivationPath == Backend::Accounts::PATH_WHISPER) if(derivationPath == Backend::Accounts::PathWhisper)
{ {
result.whisper = Accounts::toDerivedAccountDetails(derivedObj, derivationPath); result.whisper = Accounts::toDerivedAccountDetails(derivedObj, derivationPath);
} }
else if(derivationPath == Backend::Accounts::PATH_WALLET_ROOT) else if(derivationPath == Backend::Accounts::PathWalletRoot)
{ {
result.walletRoot = Accounts::toDerivedAccountDetails(derivedObj, derivationPath); result.walletRoot = Accounts::toDerivedAccountDetails(derivedObj, derivationPath);
} }
else if(derivationPath == Backend::Accounts::PATH_DEFAULT_WALLET) else if(derivationPath == Backend::Accounts::PathDefaultWallet)
{ {
result.defaultWallet = Accounts::toDerivedAccountDetails(derivedObj, derivationPath); result.defaultWallet = Accounts::toDerivedAccountDetails(derivedObj, derivationPath);
} }
else if(derivationPath == Backend::Accounts::PATH_EIP_1581) else if(derivationPath == Backend::Accounts::PathEIP1581)
{ {
result.eip1581 = Accounts::toDerivedAccountDetails(derivedObj, derivationPath); result.eip1581 = Accounts::toDerivedAccountDetails(derivedObj, derivationPath);
} }
@ -51,7 +53,7 @@ Accounts::DerivedAccounts Accounts::toDerivedAccounts(const QJsonObject jsonObj)
return result; return result;
} }
Accounts::GeneratedAccountDto Accounts::toGeneratedAccountDto(const QJsonValue jsonObj) Accounts::GeneratedAccountDto Accounts::toGeneratedAccountDto(const QJsonValue& jsonObj)
{ {
auto result = GeneratedAccountDto(); auto result = GeneratedAccountDto();

View File

@ -1,4 +1,5 @@
#include "accounts/service.h" #include "accounts/service.h"
#include "accounts/account.h" #include "accounts/account.h"
#include "accounts/generated_account.h" #include "accounts/generated_account.h"
#include "accounts/service_interface.h" #include "accounts/service_interface.h"
@ -7,28 +8,142 @@
#include "backend/utils.h" #include "backend/utils.h"
#include "constants.h" #include "constants.h"
#include "signing-phrases.h" #include "signing-phrases.h"
#include <QDebug> #include <QDebug>
#include <QFile> #include <QFile>
#include <QJsonArray> #include <QJsonArray>
#include <QJsonObject> #include <QJsonObject>
#include <QRandomGenerator> #include <QRandomGenerator>
#include <QStringList>
#include <QUuid> #include <QUuid>
namespace
{
const QVector<QString> Paths{Backend::Accounts::PathWalletRoot,
Backend::Accounts::PathEIP1581,
Backend::Accounts::PathWhisper,
Backend::Accounts::PathDefaultWallet};
QString generateSigningPhrase(int count)
{
QStringList words;
for(int i = 0; i < count; i++)
{
words.append(phrases[QRandomGenerator::global()->bounded(static_cast<int>(phrases.size()))]);
}
return words.join(" ");
}
QJsonObject prepareAccountJsonObject(const Accounts::GeneratedAccountDto& account)
{
return {{"name", account.alias},
{"address", account.address},
{"photo-path", account.identicon},
{"identicon", account.identicon},
{"key-uid", account.keyUid},
{"keycard-pairing", QJsonValue()}};
}
QJsonArray prepareSubaccountJsonObject(Accounts::GeneratedAccountDto account)
{
return {QJsonObject{{"public-key", account.derivedAccounts.defaultWallet.publicKey},
{"address", account.derivedAccounts.defaultWallet.address},
{"color", "#4360df"},
{"wallet", true},
{"path", Backend::Accounts::PathDefaultWallet},
{"name", "Status account"}},
QJsonObject{{"public-key", account.derivedAccounts.whisper.publicKey},
{"address", account.derivedAccounts.whisper.address},
{"path", Backend::Accounts::PathWhisper},
{"name", account.alias},
{"identicon", account.identicon},
{"chat", true}}};
}
QJsonObject prepareAccountSettingsJsonObject(const Accounts::GeneratedAccountDto& account, QString installationId)
{
auto defaultNetworks = QFile{":/resources/default-networks.json"};
defaultNetworks.open(QIODevice::ReadOnly);
QString defaultNetworksContent = defaultNetworks.readAll().replace("%INFURA_KEY%", INFURA_KEY);
QJsonArray defaultNetworksJson = QJsonDocument::fromJson(defaultNetworksContent.toUtf8()).array();
return {{"key-uid", account.keyUid},
{"mnemonic", account.mnemonic},
{"public-key", account.derivedAccounts.whisper.publicKey},
{"name", account.alias},
{"address", account.address},
{"eip1581-address", account.derivedAccounts.eip1581.address},
{"dapps-address", account.derivedAccounts.defaultWallet.address},
{"wallet-root-address", account.derivedAccounts.walletRoot.address},
{"preview-privacy?", true},
{"signing-phrase", generateSigningPhrase(3)},
{"log-level", "INFO"},
{"latest-derived-path", 0},
{"networks/networks", defaultNetworksJson},
{"currency", "usd"},
{"identicon", account.identicon},
{"waku-enabled", true},
{"wallet/visible-tokens", {{Constants::DefaultNetworkName, QJsonArray{"SNT"}}}},
{"appearance", 0},
{"networks/current-network", Constants::DefaultNetworkName},
{"installation-id", installationId}};
}
QJsonArray getNodes(const QJsonObject& fleet, const QString& nodeType)
{
auto nodes = fleet[nodeType].toObject();
QJsonArray result;
for(const auto& node : nodes)
{
result << node;
}
return result;
}
QJsonObject getDefaultNodeConfig(const QString& installationId)
{
auto nodeConfig = QFile{":/resources/node-config.json"};
nodeConfig.open(QIODevice::ReadOnly);
QString nodeConfigContent = nodeConfig.readAll();
nodeConfigContent = nodeConfigContent.replace("%INSTALLATIONID%", installationId);
nodeConfigContent = nodeConfigContent.replace("%INFURA_KEY%", INFURA_KEY);
QJsonObject nodeConfigJson = QJsonDocument::fromJson(nodeConfigContent.toUtf8()).object();
auto fleets = QFile{":/resources/fleets.json"};
fleets.open(QIODevice::ReadOnly);
QJsonObject fleetsJson = QJsonDocument::fromJson(fleets.readAll()).object()["fleets"].toObject();
auto fleet = fleetsJson[Constants::Fleet::Prod].toObject();
QJsonObject clusterConfig = nodeConfigJson["ClusterConfig"].toObject();
clusterConfig["Fleet"] = Constants::Fleet::Prod;
clusterConfig["BootNodes"] = getNodes(fleet, Constants::FleetNodes::Bootnodes);
clusterConfig["TrustedMailServers"] = getNodes(fleet, Constants::FleetNodes::Mailservers);
clusterConfig["StaticNodes"] = getNodes(fleet, Constants::FleetNodes::Whisper);
clusterConfig["RendezvousNodes"] = getNodes(fleet, Constants::FleetNodes::Rendezvous);
clusterConfig["RelayNodes"] = getNodes(fleet, Constants::FleetNodes::Waku);
clusterConfig["StoreNodes"] = getNodes(fleet, Constants::FleetNodes::Waku);
clusterConfig["FilterNodes"] = getNodes(fleet, Constants::FleetNodes::Waku);
clusterConfig["LightpushNodes"] = getNodes(fleet, Constants::FleetNodes::Waku);
nodeConfigJson["ClusterConfig"] = clusterConfig;
return nodeConfigJson;
}
} // namespace
namespace Accounts namespace Accounts
{ {
Service::Service()
: m_isFirstTimeAccountLogin(false)
{ }
const QVector<QString> PATHS{Backend::Accounts::PATH_WALLET_ROOT,
Backend::Accounts::PATH_EIP_1581,
Backend::Accounts::PATH_WHISPER,
Backend::Accounts::PATH_DEFAULT_WALLET};
void Service::init() void Service::init()
{ {
auto response = Backend::Accounts::generateAddresses(Accounts::PATHS); auto response = Backend::Accounts::generateAddresses(Paths);
foreach(QJsonValue generatedAddressJson, response.m_result) foreach(QJsonValue generatedAddressJson, response.m_result)
{ {
auto gAcc = toGeneratedAccountDto(generatedAddressJson); auto gAcc = toGeneratedAccountDto(generatedAddressJson);
@ -56,7 +171,7 @@ QVector<AccountDto> Service::openedAccounts()
catch(Backend::RpcException& e) catch(Backend::RpcException& e)
{ {
qWarning() << "error: methodName=openedAccounts, errDescription=" << e.what(); qWarning() << "error: methodName=openedAccounts, errDescription=" << e.what();
return QVector<AccountDto>(); return {};
} }
} }
@ -64,34 +179,34 @@ QVector<GeneratedAccountDto> Service::generatedAccounts()
{ {
if(m_generatedAccounts.length() == 0) if(m_generatedAccounts.length() == 0)
{ {
qWarning("There was some issue initiating account service"); qWarning() << "There was some issue initiating account service";
return QVector<GeneratedAccountDto>(); return {};
} }
return m_generatedAccounts; return m_generatedAccounts;
} }
bool Service::setupAccount(QString accountId, QString password) bool Service::setupAccount(const QString& accountId, const QString& password)
{ {
// TODO: would it make sense to use std::expected or std::optional or boost outcome https://www.boost.org/doc/libs/1_75_0/libs/outcome/doc/html/index.html // TODO: would it make sense to use std::expected or std::optional or boost outcome https://www.boost.org/doc/libs/1_75_0/libs/outcome/doc/html/index.html
try try
{ {
QString installationId(QUuid::createUuid().toString(QUuid::WithoutBraces)); const QString installationId(QUuid::createUuid().toString(QUuid::WithoutBraces));
QJsonObject accountData(Service::getAccountDataForAccountId(accountId)); const QJsonObject accountData(Service::getAccountDataForAccountId(accountId));
QJsonArray subAccountData(Service::getSubaccountDataForAccountId(accountId)); const QJsonArray subAccountData(Service::getSubaccountDataForAccountId(accountId));
QJsonObject settings(Service::getAccountSettings(accountId, installationId)); const QJsonObject settings(Service::getAccountSettings(accountId, installationId));
QJsonObject nodeConfig(Service::getDefaultNodeConfig(installationId)); const QJsonObject nodeConfig(getDefaultNodeConfig(installationId));
QString hashedPassword(Backend::Utils::hashString(password)); const QString hashedPassword(Backend::Utils::hashString(password));
Service::storeDerivedAccounts(accountId, hashedPassword, PATHS); Service::storeDerivedAccounts(accountId, hashedPassword, Paths);
m_loggedInAccount = m_loggedInAccount =
Service::saveAccountAndLogin(hashedPassword, accountData, subAccountData, settings, nodeConfig); Service::saveAccountAndLogin(hashedPassword, accountData, subAccountData, settings, nodeConfig);
return Service::getLoggedInAccount().isValid(); return Service::getLoggedInAccount().isValid();
} }
catch(exception& e) catch(std::exception& e)
{ {
qWarning() << "error: methodName=setupAccount, errDescription=" << e.what(); qWarning() << "error: methodName=setupAccount, errDescription=" << e.what();
return false; return false;
@ -113,19 +228,19 @@ bool Service::isFirstTimeAccountLogin()
return m_isFirstTimeAccountLogin; return m_isFirstTimeAccountLogin;
} }
QString Service::validateMnemonic(QString mnemonic) QString Service::validateMnemonic(const QString& mnemonic)
{ {
// TODO: // TODO:
return ""; return "";
} }
bool Service::importMnemonic(QString mnemonic) bool Service::importMnemonic(const QString& mnemonic)
{ {
// TODO: // TODO:
return false; return false;
} }
QString Service::login(AccountDto account, QString password) QString Service::login(const AccountDto& account, const QString& password)
{ {
// TODO: would it make sense to use std::expected or std::optional or boost outcome https://www.boost.org/doc/libs/1_75_0/libs/outcome/doc/html/index.html // TODO: would it make sense to use std::expected or std::optional or boost outcome https://www.boost.org/doc/libs/1_75_0/libs/outcome/doc/html/index.html
try try
@ -157,7 +272,7 @@ QString Service::login(AccountDto account, QString password)
return ""; return "";
} }
catch(exception& e) catch(std::exception& e)
{ {
qWarning() << "error: methodName=login, errDescription=" << e.what(); qWarning() << "error: methodName=login, errDescription=" << e.what();
return e.what(); return e.what();
@ -172,23 +287,24 @@ void Service::clear()
m_isFirstTimeAccountLogin = false; m_isFirstTimeAccountLogin = false;
} }
QString Service::generateAlias(QString publicKey) QString Service::generateAlias(const QString& publicKey)
{ {
return Backend::Accounts::generateAlias(publicKey).m_result; return Backend::Accounts::generateAlias(publicKey).m_result;
} }
QString Service::generateIdenticon(QString publicKey) QString Service::generateIdenticon(const QString& publicKey)
{ {
return Backend::Accounts::generateIdenticon(publicKey).m_result; return Backend::Accounts::generateIdenticon(publicKey).m_result;
} }
bool Service::verifyAccountPassword(QString account, QString password) bool Service::verifyAccountPassword(const QString& account, const QString& password)
{ {
// TODO: // TODO:
return false; return false;
} }
DerivedAccounts Service::storeDerivedAccounts(QString accountId, QString hashedPassword, QVector<QString> paths) DerivedAccounts
Service::storeDerivedAccounts(const QString& accountId, const QString& hashedPassword, const QVector<QString>& paths)
{ {
try try
{ {
@ -198,12 +314,15 @@ DerivedAccounts Service::storeDerivedAccounts(QString accountId, QString hashedP
catch(Backend::RpcException& e) catch(Backend::RpcException& e)
{ {
qWarning() << e.what(); qWarning() << e.what();
return DerivedAccounts(); // TODO: should it return empty? return {}; // TODO: should it return empty?
} }
} }
Accounts::AccountDto Service::saveAccountAndLogin( Accounts::AccountDto Service::saveAccountAndLogin(const QString& hashedPassword,
QString hashedPassword, QJsonObject account, QJsonArray subaccounts, QJsonObject settings, QJsonObject config) const QJsonObject& account,
const QJsonArray& subaccounts,
const QJsonObject& settings,
const QJsonObject& config)
{ {
// TODO: would it make sense to use std::expected or std::optional or boost outcome https://www.boost.org/doc/libs/1_75_0/libs/outcome/doc/html/index.html // TODO: would it make sense to use std::expected or std::optional or boost outcome https://www.boost.org/doc/libs/1_75_0/libs/outcome/doc/html/index.html
try try
@ -213,31 +332,21 @@ Accounts::AccountDto Service::saveAccountAndLogin(
m_isFirstTimeAccountLogin = true; m_isFirstTimeAccountLogin = true;
return toAccountDto(account); return toAccountDto(account);
} }
catch(exception& e) catch(std::exception& e)
{ {
qWarning() << "error: methodName=saveAccountAndLogin, errDescription=" << e.what(); qWarning() << "error: methodName=saveAccountAndLogin, errDescription=" << e.what();
return Accounts::AccountDto(); return {};
} }
} }
QJsonObject Service::prepareAccountJsonObject(const GeneratedAccountDto account) QJsonObject Service::getAccountDataForAccountId(const QString& accountId)
{
return QJsonObject{{"name", account.alias},
{"address", account.address},
{"photo-path", account.identicon},
{"identicon", account.identicon},
{"key-uid", account.keyUid},
{"keycard-pairing", QJsonValue()}};
}
QJsonObject Service::getAccountDataForAccountId(QString accountId)
{ {
foreach(const GeneratedAccountDto& acc, m_generatedAccounts) foreach(const GeneratedAccountDto& acc, m_generatedAccounts)
{ {
if(acc.id == accountId) if(acc.id == accountId)
{ {
return Service::prepareAccountJsonObject(acc); return prepareAccountJsonObject(acc);
} }
} }
@ -245,7 +354,7 @@ QJsonObject Service::getAccountDataForAccountId(QString accountId)
{ {
if(m_importedAccount.id == accountId) if(m_importedAccount.id == accountId)
{ {
return Service::prepareAccountJsonObject(m_importedAccount); return prepareAccountJsonObject(m_importedAccount);
} }
} }
@ -253,23 +362,7 @@ QJsonObject Service::getAccountDataForAccountId(QString accountId)
throw std::runtime_error("account not found"); throw std::runtime_error("account not found");
} }
QJsonArray Service::prepareSubaccountJsonObject(GeneratedAccountDto account) QJsonArray Service::getSubaccountDataForAccountId(const QString& accountId)
{
return QJsonArray{QJsonObject{{"public-key", account.derivedAccounts.defaultWallet.publicKey},
{"address", account.derivedAccounts.defaultWallet.address},
{"color", "#4360df"},
{"wallet", true},
{"path", Backend::Accounts::PATH_DEFAULT_WALLET},
{"name", "Status account"}},
QJsonObject{{"public-key", account.derivedAccounts.whisper.publicKey},
{"address", account.derivedAccounts.whisper.address},
{"path", Backend::Accounts::PATH_WHISPER},
{"name", account.alias},
{"identicon", account.identicon},
{"chat", true}}};
}
QJsonArray Service::getSubaccountDataForAccountId(QString accountId)
{ {
foreach(const GeneratedAccountDto& acc, m_generatedAccounts) foreach(const GeneratedAccountDto& acc, m_generatedAccounts)
{ {
@ -290,60 +383,20 @@ QJsonArray Service::getSubaccountDataForAccountId(QString accountId)
throw std::runtime_error("account not found"); throw std::runtime_error("account not found");
} }
QString generateSigningPhrase(int count) QJsonObject Service::getAccountSettings(const QString& accountId, const QString& installationId)
{
QStringList words;
for(int i = 0; i < count; i++)
{
words.append(phrases[QRandomGenerator::global()->bounded(static_cast<int>(phrases.size()))]);
}
return words.join(" ");
}
QJsonObject Service::prepareAccountSettingsJsonObject(const GeneratedAccountDto account, QString installationId)
{
QFile defaultNetworks(":/resources/default-networks.json");
defaultNetworks.open(QIODevice::ReadOnly);
QString defaultNetworksContent = defaultNetworks.readAll().replace("%INFURA_KEY%", INFURA_KEY);
QJsonArray defaultNetworksJson = QJsonDocument::fromJson(defaultNetworksContent.toUtf8()).array();
return QJsonObject{{"key-uid", account.keyUid},
{"mnemonic", account.mnemonic},
{"public-key", account.derivedAccounts.whisper.publicKey},
{"name", account.alias},
{"address", account.address},
{"eip1581-address", account.derivedAccounts.eip1581.address},
{"dapps-address", account.derivedAccounts.defaultWallet.address},
{"wallet-root-address", account.derivedAccounts.walletRoot.address},
{"preview-privacy?", true},
{"signing-phrase", generateSigningPhrase(3)},
{"log-level", "INFO"},
{"latest-derived-path", 0},
{"networks/networks", defaultNetworksJson},
{"currency", "usd"},
{"identicon", account.identicon},
{"waku-enabled", true},
{"wallet/visible-tokens", {{Constants::DefaultNetworkName, QJsonArray{"SNT"}}}},
{"appearance", 0},
{"networks/current-network", Constants::DefaultNetworkName},
{"installation-id", installationId}};
}
QJsonObject Service::getAccountSettings(QString accountId, QString installationId)
{ {
foreach(const GeneratedAccountDto& acc, m_generatedAccounts) foreach(const GeneratedAccountDto& acc, m_generatedAccounts)
if(acc.id == accountId) if(acc.id == accountId)
{ {
return Service::prepareAccountSettingsJsonObject(acc, installationId); return prepareAccountSettingsJsonObject(acc, installationId);
} }
if(m_importedAccount.isValid()) if(m_importedAccount.isValid())
{ {
if(m_importedAccount.id == accountId) if(m_importedAccount.id == accountId)
{ {
return Service::prepareAccountSettingsJsonObject(m_importedAccount, installationId); return prepareAccountSettingsJsonObject(m_importedAccount, installationId);
} }
} }
@ -351,47 +404,4 @@ QJsonObject Service::getAccountSettings(QString accountId, QString installationI
throw std::runtime_error("account not found"); throw std::runtime_error("account not found");
} }
QJsonArray getNodes(const QJsonObject fleet, QString nodeType)
{
auto nodes = fleet[nodeType].toObject();
QJsonArray result;
for(auto it = nodes.begin(); it != nodes.end(); ++it)
result << *it;
return result;
}
QJsonObject Service::getDefaultNodeConfig(QString installationId)
{
QFile nodeConfig(":/resources/node-config.json");
nodeConfig.open(QIODevice::ReadOnly);
QString nodeConfigContent = nodeConfig.readAll();
nodeConfigContent = nodeConfigContent.replace("%INSTALLATIONID%", installationId);
nodeConfigContent = nodeConfigContent.replace("%INFURA_KEY%", INFURA_KEY);
QJsonObject nodeConfigJson = QJsonDocument::fromJson(nodeConfigContent.toUtf8()).object();
QFile fleets(":/resources/fleets.json");
fleets.open(QIODevice::ReadOnly);
QJsonObject fleetsJson = QJsonDocument::fromJson(fleets.readAll()).object()["fleets"].toObject();
auto fleet = fleetsJson[Constants::Fleet::Prod].toObject();
QJsonObject clusterConfig = nodeConfigJson["ClusterConfig"].toObject();
clusterConfig["Fleet"] = Constants::Fleet::Prod;
clusterConfig["BootNodes"] = getNodes(fleet, Constants::FleetNodes::Bootnodes);
clusterConfig["TrustedMailServers"] = getNodes(fleet, Constants::FleetNodes::Mailservers);
clusterConfig["StaticNodes"] = getNodes(fleet, Constants::FleetNodes::Whisper);
clusterConfig["RendezvousNodes"] = getNodes(fleet, Constants::FleetNodes::Rendezvous);
clusterConfig["RelayNodes"] = getNodes(fleet, Constants::FleetNodes::Waku);
clusterConfig["StoreNodes"] = getNodes(fleet, Constants::FleetNodes::Waku);
clusterConfig["FilterNodes"] = getNodes(fleet, Constants::FleetNodes::Waku);
clusterConfig["LightpushNodes"] = getNodes(fleet, Constants::FleetNodes::Waku);
nodeConfigJson["ClusterConfig"] = clusterConfig;
return nodeConfigJson;
}
} // namespace Accounts } // namespace Accounts

View File

@ -1,11 +1,11 @@
#include "wallet_accounts/wallet_account.h" #include "wallet_accounts/wallet_account.h"
//#include "backend/accounts.h"
#include <QJsonArray> #include <QJsonArray>
#include <QJsonObject> #include <QJsonObject>
#include <QJsonValue> #include <QJsonValue>
#include <QStringList> #include <QStringList>
Wallets::WalletAccountDto Wallets::toWalletAccountDto(const QJsonValue jsonObj) Wallets::WalletAccountDto Wallets::toWalletAccountDto(const QJsonValue& jsonObj)
{ {
auto result = Wallets::WalletAccountDto(); auto result = Wallets::WalletAccountDto();
result.name = jsonObj["name"].toString(); result.name = jsonObj["name"].toString();

View File

@ -6,12 +6,6 @@
namespace Wallets namespace Wallets
{ {
Service::Service()
{
// do nothing
}
void Service::init() void Service::init()
{ {
fetchAccounts(); fetchAccounts();
@ -27,7 +21,10 @@ void Service::fetchAccounts()
foreach(const QJsonValue& value, response.m_result) foreach(const QJsonValue& value, response.m_result)
{ {
auto account = toWalletAccountDto(value); auto account = toWalletAccountDto(value);
if(!account.isChat) m_walletAccounts[account.address] = account; if(!account.isChat)
{
m_walletAccounts[account.address] = account;
}
} }
} }
catch(Backend::RpcException& e) catch(Backend::RpcException& e)

View File

@ -2,6 +2,7 @@
#include "backend/types.h" #include "backend/types.h"
#include "backend/utils.h" #include "backend/utils.h"
#include "libstatus.h" #include "libstatus.h"
#include <QDebug> #include <QDebug>
#include <QJsonArray> #include <QJsonArray>
#include <QJsonDocument> #include <QJsonDocument>
@ -9,19 +10,22 @@
#include <QString> #include <QString>
#include <QVector> #include <QVector>
const int NUMBER_OF_ADDRESSES_TO_GENERATE = 5; namespace
const int MNEMONIC_PHRASE_LENGTH = 12; {
constexpr auto NumberOfAddressesToGenerate = 5;
constexpr auto MnemonicPhraseLength = 12;
} // namespace
Backend::RpcResponse<QJsonArray> Backend::Accounts::generateAddresses(QVector<QString> paths) Backend::RpcResponse<QJsonArray> Backend::Accounts::generateAddresses(QVector<QString> paths)
{ {
QJsonObject payload{{"n", NUMBER_OF_ADDRESSES_TO_GENERATE}, QJsonObject payload{{"n", NumberOfAddressesToGenerate},
{"mnemonicPhraseLength", MNEMONIC_PHRASE_LENGTH}, {"mnemonicPhraseLength", MnemonicPhraseLength},
{"bip32Passphrase", ""}, {"bip32Passphrase", ""},
{"paths", Utils::toJsonArray(paths)} {"paths", Utils::toJsonArray(paths)}
}; };
const char* result = MultiAccountGenerateAndDeriveAddresses(Utils::jsonToStr(payload).toUtf8().data()); const char* result = MultiAccountGenerateAndDeriveAddresses(Utils::jsonToStr(payload).toUtf8().data());
return Backend::RpcResponse<QJsonArray>(result, QJsonDocument::fromJson(result).array()); return {result, QJsonDocument::fromJson(result).array()};
} }
Backend::RpcResponse<QString> Backend::Accounts::generateIdenticon(QString publicKey) Backend::RpcResponse<QString> Backend::Accounts::generateIdenticon(QString publicKey)
@ -29,12 +33,10 @@ Backend::RpcResponse<QString> Backend::Accounts::generateIdenticon(QString publi
if(!publicKey.isEmpty()) if(!publicKey.isEmpty())
{ {
auto identicon = QString(Identicon(publicKey.toUtf8().data())); auto identicon = QString(Identicon(publicKey.toUtf8().data()));
return Backend::RpcResponse<QString>(identicon, identicon); return {identicon, identicon};
} }
else
{
throw Backend::RpcException("publicKey can't be empty1"); throw Backend::RpcException("publicKey can't be empty1");
}
} }
Backend::RpcResponse<QString> Backend::Accounts::generateAlias(QString publicKey) Backend::RpcResponse<QString> Backend::Accounts::generateAlias(QString publicKey)
@ -42,12 +44,10 @@ Backend::RpcResponse<QString> Backend::Accounts::generateAlias(QString publicKey
if(!publicKey.isEmpty()) if(!publicKey.isEmpty())
{ {
auto alias = QString(GenerateAlias(publicKey.toUtf8().data())); auto alias = QString(GenerateAlias(publicKey.toUtf8().data()));
return Backend::RpcResponse<QString>(alias, alias); return {alias, alias};
} }
else
{
throw Backend::RpcException("publicKey can't be empty2"); throw Backend::RpcException("publicKey can't be empty2");
}
} }
Backend::RpcResponse<QJsonObject> Backend::RpcResponse<QJsonObject>
@ -57,7 +57,8 @@ Backend::Accounts::storeDerivedAccounts(QString id, QString hashedPassword, QVec
auto result = MultiAccountStoreDerivedAccounts(Utils::jsonToStr(payload).toUtf8().data()); auto result = MultiAccountStoreDerivedAccounts(Utils::jsonToStr(payload).toUtf8().data());
auto obj = QJsonDocument::fromJson(result).object(); auto obj = QJsonDocument::fromJson(result).object();
Backend::Utils::throwOnError(obj); Backend::Utils::throwOnError(obj);
return Backend::RpcResponse<QJsonObject>(result, obj);
return {result, obj};
} }
Backend::RpcResponse<QJsonObject> Backend::Accounts::saveAccountAndLogin( Backend::RpcResponse<QJsonObject> Backend::Accounts::saveAccountAndLogin(
@ -70,7 +71,8 @@ Backend::RpcResponse<QJsonObject> Backend::Accounts::saveAccountAndLogin(
Utils::jsonToStr(subaccounts).toUtf8().data()); Utils::jsonToStr(subaccounts).toUtf8().data());
auto obj = QJsonDocument::fromJson(result).object(); auto obj = QJsonDocument::fromJson(result).object();
Backend::Utils::throwOnError(obj); Backend::Utils::throwOnError(obj);
return Backend::RpcResponse<QJsonObject>(result, obj);
return {result, obj};
} }
Backend::RpcResponse<QJsonArray> Backend::Accounts::openAccounts(QString path) Backend::RpcResponse<QJsonArray> Backend::Accounts::openAccounts(QString path)
@ -93,5 +95,6 @@ Backend::RpcResponse<QJsonObject> Backend::Accounts::login(
auto result = Login(Utils::jsonToStr(payload).toUtf8().data(), hashedPassword.toUtf8().data()); auto result = Login(Utils::jsonToStr(payload).toUtf8().data(), hashedPassword.toUtf8().data());
auto obj = QJsonDocument::fromJson(result).object(); auto obj = QJsonDocument::fromJson(result).object();
Backend::Utils::throwOnError(obj); Backend::Utils::throwOnError(obj);
return Backend::RpcResponse<QJsonObject>(result, obj);
return {result, obj};
} }

View File

@ -1,23 +1,24 @@
#pragma once #pragma once
#include "backend/types.h" #include "backend/types.h"
#include <QJsonArray> #include <QJsonArray>
#include <QString> #include <QString>
#include <QVector> #include <QVector>
namespace Backend namespace Backend::Accounts
{ {
namespace Accounts const QString ZeroAddress = "0x0000000000000000000000000000000000000000";
{ const QString PathWalletRoot = "m/44'/60'/0'/0";
const QString ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
const QString PATH_WALLET_ROOT = "m/44'/60'/0'/0";
// EIP1581 Root Key, the extended key from which any whisper key/encryption key can be derived // EIP1581 Root Key, the extended key from which any whisper key/encryption key can be derived
const QString PATH_EIP_1581 = "m/43'/60'/1581'"; const QString PathEIP1581 = "m/43'/60'/1581'";
// BIP44-0 Wallet key, the default wallet key // BIP44-0 Wallet key, the default wallet key
const QString PATH_DEFAULT_WALLET = PATH_WALLET_ROOT + "/0"; const QString PathDefaultWallet = PathWalletRoot + "/0";
// EIP1581 Chat Key 0, the default whisper key // EIP1581 Chat Key 0, the default whisper key
const QString PATH_WHISPER = PATH_EIP_1581 + "/0'/0"; const QString PathWhisper = PathEIP1581 + "/0'/0";
RpcResponse<QJsonArray> generateAddresses(QVector<QString> paths); RpcResponse<QJsonArray> generateAddresses(QVector<QString> paths);
@ -34,6 +35,4 @@ RpcResponse<QJsonArray> openAccounts(QString path);
RpcResponse<QJsonObject> RpcResponse<QJsonObject>
login(QString name, QString keyUid, QString hashedPassword, QString identicon, QString thumbnail, QString large); login(QString name, QString keyUid, QString hashedPassword, QString identicon, QString thumbnail, QString large);
} // namespace Backend::Accounts
} // namespace Accounts
} // namespace Backend

View File

@ -2,16 +2,9 @@
#include <QString> #include <QString>
#include <iostream> #include <iostream>
using namespace std;
namespace Backend namespace Backend
{ {
const QString GENERATED = "generated";
const QString SEED = "seed";
const QString KEY = "key";
const QString WATCH = "watch";
struct RpcException : public std::exception struct RpcException : public std::exception
{ {
private: private:
@ -19,18 +12,22 @@ private:
public: public:
explicit RpcException(const std::string& message); explicit RpcException(const std::string& message);
const char* what() const throw(); const char* what() const noexcept override;
}; };
class RpcError class RpcError
{ {
public: public:
double m_code; double m_code{};
QString m_message; QString m_message;
friend ostream& operator<<(ostream& os, Backend::RpcError& r);
RpcError() = default; RpcError() = default;
RpcError(double code, QString message); RpcError(double code, const QString& message)
: m_code(code)
, m_message(message)
{ }
friend std::ostream& operator<<(std::ostream& os, Backend::RpcError& r);
}; };
template <typename T> template <typename T>
@ -40,20 +37,18 @@ class RpcResponse
public: public:
QString m_jsonrpc; QString m_jsonrpc;
T m_result; T m_result;
int m_id; int m_id{};
RpcError m_error; RpcError m_error;
public: RpcResponse(const QString& jsonrpc, T result)
RpcResponse(QString jsonrpc, T result)
: m_jsonrpc(jsonrpc) : m_jsonrpc(jsonrpc)
, m_result(result) , m_result(result)
{ } { }
RpcResponse(QString jsonrpc, T result, RpcError error) RpcResponse(const QString& jsonrpc, T result, const RpcError& error)
: m_jsonrpc(jsonrpc) : m_jsonrpc(jsonrpc)
, m_result(result) , m_result(result)
, m_error(error) , m_error(error)
{ } { }
}; };
} // namespace Backend } // namespace Backend

View File

@ -10,11 +10,11 @@ namespace Backend
class Utils class Utils
{ {
public: public:
static QString hashString(QString str); static QString hashString(const QString& str);
static QString jsonToStr(QJsonObject obj); static QString jsonToStr(const QJsonObject& obj);
static QString jsonToStr(QJsonArray arr); static QString jsonToStr(const QJsonArray& arr);
static QJsonArray toJsonArray(const QVector<QString>& value); static QJsonArray toJsonArray(const QVector<QString>& value);
static QVector<QString> toStringVector(const QJsonArray& arr); static QVector<QString> toStringVector(const QJsonArray& arr);
static void throwOnError(QJsonObject response); static void throwOnError(const QJsonObject& response);
}; };
} // namespace Backend } // namespace Backend

View File

@ -1,5 +1,4 @@
#ifndef WALLETACCOUNT_BACKEND_H #pragma once
#define WALLETACCOUNT_BACKEND_H
#include <QJsonArray> #include <QJsonArray>
@ -14,5 +13,3 @@ Backend::RpcResponse<QString> addAccountsFromSeed(const QString& seedPhrase, con
Backend::RpcResponse<QString> addWatchOnlyAccount(const QString& address, const QString& accountName , const QString& color); Backend::RpcResponse<QString> addWatchOnlyAccount(const QString& address, const QString& accountName , const QString& color);
Backend::RpcResponse<QString> deleteAccount(const QString& address); Backend::RpcResponse<QString> deleteAccount(const QString& address);
} // namespace Backend::Wallet::Accounts } // namespace Backend::Wallet::Accounts
#endif // WALLETACCOUNT_BACKEND_H

View File

@ -1,24 +1,18 @@
#include "backend/types.h" #include "backend/types.h"
#include <QString> #include <QString>
using namespace std; std::ostream& operator<<(std::ostream& os, const Backend::RpcError& r)
ostream& operator<<(ostream& os, const Backend::RpcError& r)
{ {
return (os << "RpcError(\n code: " << r.m_code << "\n message: " << r.m_message.toStdString() << "\n)" return (os << "RpcError(\n code: " << r.m_code << "\n message: " << r.m_message.toStdString() << "\n)"
<< std::endl); << std::endl);
} }
Backend::RpcError::RpcError(double code, QString message):
m_code(code),
m_message(message)
{}
Backend::RpcException::RpcException(const std::string& message) Backend::RpcException::RpcException(const std::string& message)
: m_message(message) : m_message(message)
{ } { }
const char* Backend::RpcException::what() const throw() const char* Backend::RpcException::what() const noexcept
{ {
return m_message.c_str(); return m_message.c_str();
} }

View File

@ -12,17 +12,19 @@ QJsonArray Backend::Utils::toJsonArray(const QVector<QString>& value)
{ {
QJsonArray array; QJsonArray array;
for(auto& v : value) for(auto& v : value)
{
array << v; array << v;
}
return array; return array;
} }
QString Backend::Utils::jsonToStr(QJsonObject obj) QString Backend::Utils::jsonToStr(const QJsonObject& obj)
{ {
QJsonDocument doc(obj); QJsonDocument doc(obj);
return QString::fromUtf8(doc.toJson()); return QString::fromUtf8(doc.toJson());
} }
QString Backend::Utils::jsonToStr(QJsonArray arr) QString Backend::Utils::jsonToStr(const QJsonArray& arr)
{ {
QJsonDocument doc(arr); QJsonDocument doc(arr);
return QString::fromUtf8(doc.toJson()); return QString::fromUtf8(doc.toJson());
@ -38,12 +40,12 @@ QVector<QString> Backend::Utils::toStringVector(const QJsonArray& arr)
return result; return result;
} }
QString Backend::Utils::hashString(QString str) QString Backend::Utils::hashString(const QString& str)
{ {
return "0x" + QString::fromUtf8(QCryptographicHash::hash(str.toUtf8(), QCryptographicHash::Keccak_256).toHex()); return "0x" + QString::fromUtf8(QCryptographicHash::hash(str.toUtf8(), QCryptographicHash::Keccak_256).toHex());
} }
void Backend::Utils::throwOnError(QJsonObject response) void Backend::Utils::throwOnError(const QJsonObject& response)
{ {
if(!response["error"].isUndefined() && !response["error"].toString().isEmpty()) if(!response["error"].isUndefined() && !response["error"].toString().isEmpty())
{ {

View File

@ -15,7 +15,7 @@ RpcResponse<QJsonArray> getAccounts()
auto result = CallPrivateRPC(Utils::jsonToStr(inputJSON).toUtf8().data()); auto result = CallPrivateRPC(Utils::jsonToStr(inputJSON).toUtf8().data());
auto obj = QJsonDocument::fromJson(result).object(); auto obj = QJsonDocument::fromJson(result).object();
Backend::Utils::throwOnError(obj); Backend::Utils::throwOnError(obj);
return RpcResponse<QJsonArray>(result, obj["result"].toArray(), RpcError(-1, QJsonDocument::fromJson(result)["error"].toString())); return {result, obj["result"].toArray(), RpcError(-1, QJsonDocument::fromJson(result)["error"].toString())};
} }
RpcResponse<QString> generateNewAccount(const QString& password, const QString& accountName, const QString& color) RpcResponse<QString> generateNewAccount(const QString& password, const QString& accountName, const QString& color)
@ -25,39 +25,53 @@ RpcResponse<QString> generateNewAccount(const QString& password, const QString&
QJsonObject inputJSON{{"jsonrpc", "2.0"}, {"method", "accounts_generateAccount"}, {"params", payload}}; QJsonObject inputJSON{{"jsonrpc", "2.0"}, {"method", "accounts_generateAccount"}, {"params", payload}};
auto result = CallPrivateRPC(Utils::jsonToStr(inputJSON).toUtf8().data()); auto result = CallPrivateRPC(Utils::jsonToStr(inputJSON).toUtf8().data());
auto response = QJsonDocument::fromJson(result); auto response = QJsonDocument::fromJson(result);
return RpcResponse<QString>(result,response["result"].toString(), return RpcResponse<QString>(
result,
response["result"].toString(),
RpcError(response["error"]["code"].toDouble(), response["error"]["message"].toString())); RpcError(response["error"]["code"].toDouble(), response["error"]["message"].toString()));
} }
RpcResponse<QString> addAccountsFromPrivateKey(const QString& privateKey, const QString& password, const QString& accountName, const QString& color) RpcResponse<QString> addAccountsFromPrivateKey(const QString& privateKey,
const QString& password,
const QString& accountName,
const QString& color)
{ {
QString hashedPassword(Backend::Utils::hashString(password)); QString hashedPassword(Backend::Utils::hashString(password));
QJsonArray payload = {privateKey, hashedPassword, accountName, color}; QJsonArray payload = {privateKey, hashedPassword, accountName, color};
QJsonObject inputJSON{{"jsonrpc", "2.0"}, {"method", "accounts_addAccountWithMnemonic"}, {"params", payload}}; QJsonObject inputJSON{{"jsonrpc", "2.0"}, {"method", "accounts_addAccountWithMnemonic"}, {"params", payload}};
auto result = CallPrivateRPC(Utils::jsonToStr(inputJSON).toUtf8().data()); auto result = CallPrivateRPC(Utils::jsonToStr(inputJSON).toUtf8().data());
auto response = QJsonDocument::fromJson(result); auto response = QJsonDocument::fromJson(result);
return RpcResponse<QString>(result,response["result"].toString(), return RpcResponse<QString>(
result,
response["result"].toString(),
RpcError(response["error"]["code"].toDouble(), response["error"]["message"].toString())); RpcError(response["error"]["code"].toDouble(), response["error"]["message"].toString()));
} }
RpcResponse<QString> addAccountsFromSeed(const QString& seedPhrase, const QString& password, const QString& accountName, const QString& color) RpcResponse<QString> addAccountsFromSeed(const QString& seedPhrase,
const QString& password,
const QString& accountName,
const QString& color)
{ {
QString hashedPassword(Backend::Utils::hashString(password)); QString hashedPassword(Backend::Utils::hashString(password));
QJsonArray payload = {seedPhrase, hashedPassword, accountName, color}; QJsonArray payload = {seedPhrase, hashedPassword, accountName, color};
QJsonObject inputJSON{{"jsonrpc", "2.0"}, {"method", "accounts_addAccountWithPrivateKey"}, {"params", payload}}; QJsonObject inputJSON{{"jsonrpc", "2.0"}, {"method", "accounts_addAccountWithPrivateKey"}, {"params", payload}};
auto result = CallPrivateRPC(Utils::jsonToStr(inputJSON).toUtf8().data()); auto result = CallPrivateRPC(Utils::jsonToStr(inputJSON).toUtf8().data());
auto response = QJsonDocument::fromJson(result); auto response = QJsonDocument::fromJson(result);
return RpcResponse<QString>(result,response["result"].toString(), return RpcResponse<QString>(
result,
response["result"].toString(),
RpcError(response["error"]["code"].toDouble(), response["error"]["message"].toString())); RpcError(response["error"]["code"].toDouble(), response["error"]["message"].toString()));
} }
RpcResponse<QString> addWatchOnlyAccount(const QString& address, const QString& accountName , const QString& color) RpcResponse<QString> addWatchOnlyAccount(const QString& address, const QString& accountName, const QString& color)
{ {
QJsonArray payload = {address, accountName, color}; QJsonArray payload = {address, accountName, color};
QJsonObject inputJSON{{"jsonrpc", "2.0"}, {"method", "accounts_addAccountWatch"}, {"params", payload}}; QJsonObject inputJSON{{"jsonrpc", "2.0"}, {"method", "accounts_addAccountWatch"}, {"params", payload}};
auto result = CallPrivateRPC(Utils::jsonToStr(inputJSON).toUtf8().data()); auto result = CallPrivateRPC(Utils::jsonToStr(inputJSON).toUtf8().data());
auto response = QJsonDocument::fromJson(result); auto response = QJsonDocument::fromJson(result);
return RpcResponse<QString>(result,response["result"].toString(), return RpcResponse<QString>(
result,
response["result"].toString(),
RpcError(response["error"]["code"].toDouble(), response["error"]["message"].toString())); RpcError(response["error"]["code"].toDouble(), response["error"]["message"].toString()));
} }
@ -67,7 +81,9 @@ RpcResponse<QString> deleteAccount(const QString& address)
QJsonObject inputJSON{{"jsonrpc", "2.0"}, {"method", "accounts_deleteAccount"}, {"params", payload}}; QJsonObject inputJSON{{"jsonrpc", "2.0"}, {"method", "accounts_deleteAccount"}, {"params", payload}};
auto result = CallPrivateRPC(Utils::jsonToStr(inputJSON).toUtf8().data()); auto result = CallPrivateRPC(Utils::jsonToStr(inputJSON).toUtf8().data());
auto response = QJsonDocument::fromJson(result); auto response = QJsonDocument::fromJson(result);
return RpcResponse<QString>(result,response["result"].toString(), return RpcResponse<QString>(
result,
response["result"].toString(),
RpcError(response["error"]["code"].toDouble(), response["error"]["message"].toString())); RpcError(response["error"]["code"].toDouble(), response["error"]["message"].toString()));
} }

View File

@ -7,17 +7,17 @@
// TODO: merge with constants from backend/ // TODO: merge with constants from backend/
QString Constants::applicationPath(QString path) QString Constants::applicationPath(const QString& path)
{ {
return QFileInfo(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + path).absoluteFilePath(); return QFileInfo(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + path).absoluteFilePath();
} }
QString Constants::tmpPath(QString path) QString Constants::tmpPath(const QString& path)
{ {
return QFileInfo(QStandardPaths::writableLocation(QStandardPaths::TempLocation) + path).absoluteFilePath(); return QFileInfo(QStandardPaths::writableLocation(QStandardPaths::TempLocation) + path).absoluteFilePath();
} }
QString Constants::cachePath(QString path) QString Constants::cachePath(const QString& path)
{ {
return QFileInfo(QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + path).absoluteFilePath(); return QFileInfo(QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + path).absoluteFilePath();
} }

View File

@ -4,12 +4,11 @@
namespace Constants namespace Constants
{ {
const QString DataDir = "/data"; inline constexpr auto DataDir = "/data";
const QString Keystore = "/data/keystore"; inline constexpr auto Keystore = "/data/keystore";
QString applicationPath(QString path = ""); QString applicationPath(const QString& path = "");
QString tmpPath(QString path = ""); QString tmpPath(const QString& path = "");
QString cachePath(QString path = ""); QString cachePath(const QString& path = "");
bool ensureDirectories(); bool ensureDirectories();
} // namespace Constants } // namespace Constants

View File

@ -1,5 +1,4 @@
#ifndef SINGLEINSTANCE_H #pragma once
#define SINGLEINSTANCE_H
#include <QObject> #include <QObject>
@ -27,5 +26,3 @@ private slots:
private: private:
QLocalServer* m_localServer; QLocalServer* m_localServer;
}; };
#endif // SINGLEINSTANCE_H

View File

@ -1,4 +1,5 @@
#pragma once #pragma once
#include <QDateTime> #include <QDateTime>
#include <QDebug> #include <QDebug>
#include <QString> #include <QString>

View File

@ -5,6 +5,7 @@
#include "logs.h" #include "logs.h"
#include "signals.h" #include "signals.h"
#include "singleton.h" #include "singleton.h"
#include <QGuiApplication> #include <QGuiApplication>
#include <QJsonDocument> #include <QJsonDocument>
#include <QJsonObject> #include <QJsonObject>
@ -25,11 +26,14 @@ int main(int argc, char* argv[])
#endif #endif
QGuiApplication app(argc, argv); QGuiApplication app(argc, argv);
app.setOrganizationName("Status"); QGuiApplication::setOrganizationName("Status");
app.setOrganizationDomain("status.im"); QGuiApplication::setOrganizationDomain("status.im");
app.setApplicationName("Status Desktop"); QGuiApplication::setApplicationName("Status Desktop");
if(!Constants::ensureDirectories()) return 1; if(!Constants::ensureDirectories())
{
return 1;
}
// Init keystore // Init keystore
const char* initKeystoreResult = InitKeystore(Constants::applicationPath(Constants::Keystore).toUtf8().data()); const char* initKeystoreResult = InitKeystore(Constants::applicationPath(Constants::Keystore).toUtf8().data());
@ -66,12 +70,16 @@ int main(int argc, char* argv[])
&QQmlApplicationEngine::objectCreated, &QQmlApplicationEngine::objectCreated,
&app, &app,
[url](QObject* obj, const QUrl& objUrl) { [url](QObject* obj, const QUrl& objUrl) {
if(!obj && url == objUrl) QCoreApplication::exit(-1); if(!obj && url == objUrl)
{
QCoreApplication::exit(-1);
}
}, },
Qt::QueuedConnection); Qt::QueuedConnection);
Global::Singleton::instance()->engine()->load(url); Global::Singleton::instance()->engine()->load(url);
qInfo("starting application..."); qInfo("starting application...");
return app.exec();
return QGuiApplication::exec();
} }