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
CheckOptions:
- 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"
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 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 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
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 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
USES_TERMINAL
)

View File

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

View File

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

View File

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

View File

@ -1,5 +1,4 @@
#ifndef APPSECTION_CONFIG_H
#define APPSECTION_CONFIG_H
#pragma once
// 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>
@ -23,5 +22,3 @@ const QString NODEMANAGEMENT_SECTION_ICON = "node";
const QString SETTINGS_SECTION_ID = "profileSettings";
const QString SETTINGS_SECTION_NAME = "Settings";
const QString SETTINGS_SECTION_ICON = "settings";
#endif // APPSECTION_CONFIG_H

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -8,14 +8,14 @@
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)
{
m_controllerPtr = new Controller(this);
m_viewPtr = new View(this);
// Submodules
m_walletModulePtr = new Modules::Main::Wallet::Module(walletsService, this);
m_walletModulePtr = new Modules::Main::Wallet::Module(walletService, this);
m_moduleLoaded = false;
connect();
@ -24,6 +24,7 @@ Module::Module(std::shared_ptr<Wallets::ServiceInterface> walletsService, QObjec
void Module::connect()
{
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()));
}

View File

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

View File

@ -3,12 +3,6 @@
namespace Modules::Main
{
View::View(QObject* parent)
: QObject(parent)
{
m_sectionModelPtr = new Shared::Models::SectionModel(this);
}
void View::load()
{
// Add Wallet Section to Sections model
@ -30,25 +24,25 @@ void View::load()
void View::addItem(Shared::Models::SectionItem* item)
{
m_sectionModelPtr->addItem(item);
emit sectionsModelChanged();
m_sectionModel.addItem(item);
// 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
{
return m_sectionModelPtr->getActiveItem();
return m_sectionModel.getActiveItem();
}
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();
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,5 +1,4 @@
#ifndef SECTION_ITEM_H
#define SECTION_ITEM_H
#pragma once
#include <QObject>
#include <QString>
@ -16,11 +15,12 @@ enum SectionType
ProfileSettings,
NodeManagement
};
class SectionItem : public QObject
{
Q_OBJECT
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(bool amISectionAdmin READ getAmISectionAdmin)
Q_PROPERTY(QString description READ getDescription)
@ -40,6 +40,9 @@ class SectionItem : public QObject
Q_PROPERTY(bool ensOnly READ getIsEnsOnly)
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,
const QString& id = "",
SectionType sectionType = SectionType::Unkown,
@ -113,5 +116,3 @@ private:
// pendingRequestsToJoinModel: PendingRequestModel
};
} // 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 CanRequestAccess: return item->getCanRequestAccess();
case Access: return item->getAccess();
case EnsOnly: return item->getIsEnsOnly();
case EnsOnly:
return item->getIsEnsOnly();
// To Do
case MembersModel: 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;
for(auto item : m_items)

View File

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

View File

@ -1,4 +1,5 @@
#include "constants.h"
#include <QDir>
#include <QFileInfo>
#include <QStandardPaths>
@ -6,17 +7,17 @@
// 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();
}
QString Constants::tmpPath(QString path)
QString Constants::tmpPath(const QString& path)
{
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();
}

View File

@ -28,10 +28,10 @@ public:
QString keyUid;
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

View File

@ -36,12 +36,12 @@ public:
QString alias;
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

View File

@ -3,31 +3,29 @@
#include "account.h"
#include "generated_account.h"
#include "service_interface.h"
#include <QString>
#include <QVector>
namespace Accounts
{
class Service : public ServiceInterface
{
private:
QVector<GeneratedAccountDto> m_generatedAccounts;
bool m_isFirstTimeAccountLogin;
bool m_isFirstTimeAccountLogin = false;
AccountDto m_loggedInAccount;
GeneratedAccountDto m_importedAccount;
public:
Service();
void init() override;
virtual QVector<AccountDto> openedAccounts() override;
QVector<AccountDto> openedAccounts() override;
QVector<GeneratedAccountDto> generatedAccounts() override;
bool setupAccount(QString accountId, QString password) override;
bool setupAccount(const QString& accountId, const QString& password) override;
AccountDto getLoggedInAccount() override;
@ -35,38 +33,34 @@ public:
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;
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);
QJsonObject prepareAccountJsonObject(const GeneratedAccountDto account);
QJsonArray prepareSubaccountJsonObject(GeneratedAccountDto account);
QJsonObject prepareAccountSettingsJsonObject(const GeneratedAccountDto account, QString installationId);
AccountDto saveAccountAndLogin(
QString hashedPassword, QJsonObject account, QJsonArray subaccounts, QJsonObject settings, QJsonObject config);
AccountDto saveAccountAndLogin(const QString& hashedPassword,
const QJsonObject& account,
const QJsonArray& subaccounts,
const QJsonObject& settings,
const QJsonObject& config);
};
} // namespace Accounts

View File

@ -17,7 +17,7 @@ public:
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;
@ -25,19 +25,19 @@ public:
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 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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -5,12 +5,12 @@
#include <QJsonValue>
#include <QStringList>
bool Accounts::AccountDto::isValid()
bool Accounts::AccountDto::isValid() const
{
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();
@ -25,7 +25,7 @@ Accounts::Image Accounts::toImage(const QJsonValue jsonObj)
return result;
}
Accounts::AccountDto Accounts::toAccountDto(const QJsonValue jsonObj)
Accounts::AccountDto Accounts::toAccountDto(const QJsonValue& jsonObj)
{
auto result = Accounts::AccountDto();

View File

@ -1,17 +1,19 @@
#include "accounts/generated_account.h"
#include "backend/accounts.h"
#include <QDebug>
#include <QJsonArray>
#include <QJsonObject>
#include <QJsonValue>
#include <QStringList>
bool Accounts::GeneratedAccountDto::isValid()
bool Accounts::GeneratedAccountDto::isValid() const
{
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
// handle it a bit different.
@ -24,25 +26,25 @@ Accounts::DerivedAccountDetails Accounts::toDerivedAccountDetails(const QJsonVal
return result;
}
Accounts::DerivedAccounts Accounts::toDerivedAccounts(const QJsonObject jsonObj)
Accounts::DerivedAccounts Accounts::toDerivedAccounts(const QJsonObject& jsonObj)
{
auto result = Accounts::DerivedAccounts();
foreach(const QString& derivationPath, jsonObj.keys())
{
QJsonValue derivedObj = jsonObj.value(derivationPath);
if(derivationPath == Backend::Accounts::PATH_WHISPER)
if(derivationPath == Backend::Accounts::PathWhisper)
{
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);
}
else if(derivationPath == Backend::Accounts::PATH_DEFAULT_WALLET)
else if(derivationPath == Backend::Accounts::PathDefaultWallet)
{
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);
}
@ -51,7 +53,7 @@ Accounts::DerivedAccounts Accounts::toDerivedAccounts(const QJsonObject jsonObj)
return result;
}
Accounts::GeneratedAccountDto Accounts::toGeneratedAccountDto(const QJsonValue jsonObj)
Accounts::GeneratedAccountDto Accounts::toGeneratedAccountDto(const QJsonValue& jsonObj)
{
auto result = GeneratedAccountDto();

View File

@ -1,4 +1,5 @@
#include "accounts/service.h"
#include "accounts/account.h"
#include "accounts/generated_account.h"
#include "accounts/service_interface.h"
@ -7,28 +8,142 @@
#include "backend/utils.h"
#include "constants.h"
#include "signing-phrases.h"
#include <QDebug>
#include <QFile>
#include <QJsonArray>
#include <QJsonObject>
#include <QRandomGenerator>
#include <QStringList>
#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
{
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()
{
auto response = Backend::Accounts::generateAddresses(Accounts::PATHS);
auto response = Backend::Accounts::generateAddresses(Paths);
foreach(QJsonValue generatedAddressJson, response.m_result)
{
auto gAcc = toGeneratedAccountDto(generatedAddressJson);
@ -56,7 +171,7 @@ QVector<AccountDto> Service::openedAccounts()
catch(Backend::RpcException& e)
{
qWarning() << "error: methodName=openedAccounts, errDescription=" << e.what();
return QVector<AccountDto>();
return {};
}
}
@ -64,34 +179,34 @@ QVector<GeneratedAccountDto> Service::generatedAccounts()
{
if(m_generatedAccounts.length() == 0)
{
qWarning("There was some issue initiating account service");
return QVector<GeneratedAccountDto>();
qWarning() << "There was some issue initiating account service";
return {};
}
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
try
{
QString installationId(QUuid::createUuid().toString(QUuid::WithoutBraces));
QJsonObject accountData(Service::getAccountDataForAccountId(accountId));
QJsonArray subAccountData(Service::getSubaccountDataForAccountId(accountId));
QJsonObject settings(Service::getAccountSettings(accountId, installationId));
QJsonObject nodeConfig(Service::getDefaultNodeConfig(installationId));
const QString installationId(QUuid::createUuid().toString(QUuid::WithoutBraces));
const QJsonObject accountData(Service::getAccountDataForAccountId(accountId));
const QJsonArray subAccountData(Service::getSubaccountDataForAccountId(accountId));
const QJsonObject settings(Service::getAccountSettings(accountId, 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 =
Service::saveAccountAndLogin(hashedPassword, accountData, subAccountData, settings, nodeConfig);
return Service::getLoggedInAccount().isValid();
}
catch(exception& e)
catch(std::exception& e)
{
qWarning() << "error: methodName=setupAccount, errDescription=" << e.what();
return false;
@ -113,19 +228,19 @@ bool Service::isFirstTimeAccountLogin()
return m_isFirstTimeAccountLogin;
}
QString Service::validateMnemonic(QString mnemonic)
QString Service::validateMnemonic(const QString& mnemonic)
{
// TODO:
return "";
}
bool Service::importMnemonic(QString mnemonic)
bool Service::importMnemonic(const QString& mnemonic)
{
// TODO:
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
try
@ -157,7 +272,7 @@ QString Service::login(AccountDto account, QString password)
return "";
}
catch(exception& e)
catch(std::exception& e)
{
qWarning() << "error: methodName=login, errDescription=" << e.what();
return e.what();
@ -172,23 +287,24 @@ void Service::clear()
m_isFirstTimeAccountLogin = false;
}
QString Service::generateAlias(QString publicKey)
QString Service::generateAlias(const QString& publicKey)
{
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;
}
bool Service::verifyAccountPassword(QString account, QString password)
bool Service::verifyAccountPassword(const QString& account, const QString& password)
{
// TODO:
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
{
@ -198,12 +314,15 @@ DerivedAccounts Service::storeDerivedAccounts(QString accountId, QString hashedP
catch(Backend::RpcException& e)
{
qWarning() << e.what();
return DerivedAccounts(); // TODO: should it return empty?
return {}; // TODO: should it return empty?
}
}
Accounts::AccountDto Service::saveAccountAndLogin(
QString hashedPassword, QJsonObject account, QJsonArray subaccounts, QJsonObject settings, QJsonObject config)
Accounts::AccountDto Service::saveAccountAndLogin(const QString& hashedPassword,
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
try
@ -213,31 +332,21 @@ Accounts::AccountDto Service::saveAccountAndLogin(
m_isFirstTimeAccountLogin = true;
return toAccountDto(account);
}
catch(exception& e)
catch(std::exception& e)
{
qWarning() << "error: methodName=saveAccountAndLogin, errDescription=" << e.what();
return Accounts::AccountDto();
return {};
}
}
QJsonObject Service::prepareAccountJsonObject(const GeneratedAccountDto account)
{
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)
QJsonObject Service::getAccountDataForAccountId(const QString& accountId)
{
foreach(const GeneratedAccountDto& acc, m_generatedAccounts)
{
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)
{
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");
}
QJsonArray Service::prepareSubaccountJsonObject(GeneratedAccountDto account)
{
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)
QJsonArray Service::getSubaccountDataForAccountId(const QString& accountId)
{
foreach(const GeneratedAccountDto& acc, m_generatedAccounts)
{
@ -290,60 +383,20 @@ QJsonArray Service::getSubaccountDataForAccountId(QString accountId)
throw std::runtime_error("account not found");
}
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 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)
QJsonObject Service::getAccountSettings(const QString& accountId, const QString& installationId)
{
foreach(const GeneratedAccountDto& acc, m_generatedAccounts)
if(acc.id == accountId)
{
return Service::prepareAccountSettingsJsonObject(acc, installationId);
return prepareAccountSettingsJsonObject(acc, installationId);
}
if(m_importedAccount.isValid())
{
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");
}
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

View File

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

View File

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

View File

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

View File

@ -1,23 +1,24 @@
#pragma once
#include "backend/types.h"
#include <QJsonArray>
#include <QString>
#include <QVector>
namespace Backend
namespace Backend::Accounts
{
namespace Accounts
{
const QString ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
const QString ZeroAddress = "0x0000000000000000000000000000000000000000";
const QString PathWalletRoot = "m/44'/60'/0'/0";
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
const QString PATH_EIP_1581 = "m/43'/60'/1581'";
const QString PathEIP1581 = "m/43'/60'/1581'";
// 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
const QString PATH_WHISPER = PATH_EIP_1581 + "/0'/0";
const QString PathWhisper = PathEIP1581 + "/0'/0";
RpcResponse<QJsonArray> generateAddresses(QVector<QString> paths);
@ -34,6 +35,4 @@ RpcResponse<QJsonArray> openAccounts(QString path);
RpcResponse<QJsonObject>
login(QString name, QString keyUid, QString hashedPassword, QString identicon, QString thumbnail, QString large);
} // namespace Accounts
} // namespace Backend
} // namespace Backend::Accounts

View File

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

View File

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

View File

@ -1,5 +1,4 @@
#ifndef WALLETACCOUNT_BACKEND_H
#define WALLETACCOUNT_BACKEND_H
#pragma once
#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> deleteAccount(const QString& address);
} // namespace Backend::Wallet::Accounts
#endif // WALLETACCOUNT_BACKEND_H

View File

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

View File

@ -12,17 +12,19 @@ QJsonArray Backend::Utils::toJsonArray(const QVector<QString>& value)
{
QJsonArray array;
for(auto& v : value)
{
array << v;
}
return array;
}
QString Backend::Utils::jsonToStr(QJsonObject obj)
QString Backend::Utils::jsonToStr(const QJsonObject& obj)
{
QJsonDocument doc(obj);
return QString::fromUtf8(doc.toJson());
}
QString Backend::Utils::jsonToStr(QJsonArray arr)
QString Backend::Utils::jsonToStr(const QJsonArray& arr)
{
QJsonDocument doc(arr);
return QString::fromUtf8(doc.toJson());
@ -38,12 +40,12 @@ QVector<QString> Backend::Utils::toStringVector(const QJsonArray& arr)
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());
}
void Backend::Utils::throwOnError(QJsonObject response)
void Backend::Utils::throwOnError(const QJsonObject& response)
{
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 obj = QJsonDocument::fromJson(result).object();
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)
@ -25,40 +25,54 @@ RpcResponse<QString> generateNewAccount(const QString& password, const QString&
QJsonObject inputJSON{{"jsonrpc", "2.0"}, {"method", "accounts_generateAccount"}, {"params", payload}};
auto result = CallPrivateRPC(Utils::jsonToStr(inputJSON).toUtf8().data());
auto response = QJsonDocument::fromJson(result);
return RpcResponse<QString>(result,response["result"].toString(),
RpcError(response["error"]["code"].toDouble(), response["error"]["message"].toString()));
return RpcResponse<QString>(
result,
response["result"].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));
QJsonArray payload = {privateKey, hashedPassword, accountName, color};
QJsonObject inputJSON{{"jsonrpc", "2.0"}, {"method", "accounts_addAccountWithMnemonic"}, {"params", payload}};
auto result = CallPrivateRPC(Utils::jsonToStr(inputJSON).toUtf8().data());
auto response = QJsonDocument::fromJson(result);
return RpcResponse<QString>(result,response["result"].toString(),
RpcError(response["error"]["code"].toDouble(), response["error"]["message"].toString()));
return RpcResponse<QString>(
result,
response["result"].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));
QJsonArray payload = {seedPhrase, hashedPassword, accountName, color};
QJsonObject inputJSON{{"jsonrpc", "2.0"}, {"method", "accounts_addAccountWithPrivateKey"}, {"params", payload}};
auto result = CallPrivateRPC(Utils::jsonToStr(inputJSON).toUtf8().data());
auto response = QJsonDocument::fromJson(result);
return RpcResponse<QString>(result,response["result"].toString(),
RpcError(response["error"]["code"].toDouble(), response["error"]["message"].toString()));
return RpcResponse<QString>(
result,
response["result"].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};
QJsonObject inputJSON{{"jsonrpc", "2.0"}, {"method", "accounts_addAccountWatch"}, {"params", payload}};
auto result = CallPrivateRPC(Utils::jsonToStr(inputJSON).toUtf8().data());
auto response = QJsonDocument::fromJson(result);
return RpcResponse<QString>(result,response["result"].toString(),
RpcError(response["error"]["code"].toDouble(), response["error"]["message"].toString()));
return RpcResponse<QString>(
result,
response["result"].toString(),
RpcError(response["error"]["code"].toDouble(), response["error"]["message"].toString()));
}
RpcResponse<QString> deleteAccount(const QString& address)
@ -67,8 +81,10 @@ RpcResponse<QString> deleteAccount(const QString& address)
QJsonObject inputJSON{{"jsonrpc", "2.0"}, {"method", "accounts_deleteAccount"}, {"params", payload}};
auto result = CallPrivateRPC(Utils::jsonToStr(inputJSON).toUtf8().data());
auto response = QJsonDocument::fromJson(result);
return RpcResponse<QString>(result,response["result"].toString(),
RpcError(response["error"]["code"].toDouble(), response["error"]["message"].toString()));
return RpcResponse<QString>(
result,
response["result"].toString(),
RpcError(response["error"]["code"].toDouble(), response["error"]["message"].toString()));
}
} // namespace Backend::Wallet::Accounts

View File

@ -7,17 +7,17 @@
// 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();
}
QString Constants::tmpPath(QString path)
QString Constants::tmpPath(const QString& path)
{
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();
}

View File

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

View File

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

View File

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

View File

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