chore(CPP): remove C++ clone of the nim-based architecture

The module based C++ code, will be refactored as qml modules

Updates #5676
This commit is contained in:
Stefan 2022-06-01 11:14:31 +02:00 committed by Stefan Dunca
parent 1e8c851283
commit 5a1f0a3d3a
122 changed files with 0 additions and 6273 deletions

View File

@ -1,51 +0,0 @@
add_library(app
include/signals.h
boot/app_controller.cpp
core/signals/signals.cpp
global/singleton.cpp
modules/shared/section_item.cpp
modules/shared/section_model.cpp
modules/startup/controller.cpp
modules/startup/module.cpp
modules/startup/view.cpp
modules/startup/onboarding/controller.cpp
modules/startup/onboarding/item.cpp
modules/startup/onboarding/model.cpp
modules/startup/onboarding/module.cpp
modules/startup/onboarding/view.cpp
modules/startup/login/controller.cpp
modules/startup/login/item.cpp
modules/startup/login/model.cpp
modules/startup/login/module.cpp
modules/startup/login/view.cpp
modules/startup/login/selected_account.cpp
modules/main/controller.cpp
modules/main/module.cpp
modules/main/view.cpp
modules/main/wallet/controller.cpp
modules/main/wallet/module.cpp
modules/main/wallet/view.cpp
modules/main/wallet/accounts/controller.cpp
modules/main/wallet/accounts/module.cpp
modules/main/wallet/accounts/view.cpp
modules/main/wallet/accounts/model.cpp
modules/main/wallet/accounts/item.cpp
)
target_include_directories(app
PUBLIC
./include/
./boot/
./modules/shared
./modules/main
./modules/startup
)
target_link_libraries(app
PRIVATE
app_service
statusgo_shared
Qt${QT_VERSION_MAJOR}::Concurrent
Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Quick
)

View File

@ -1,248 +0,0 @@
#include <QDebug>
#include <QQmlContext>
#include "app_controller.h"
#include "modules/main/module.h"
#include "modules/startup/module.h"
#include "singleton.h"
AppController::AppController()
{
// To-do remove when transition to c++ is complete
Global::Singleton::instance()->engine()->rootContext()->setContextProperty("cppApp", true);
// result.statusFoundation = statusFoundation
// # Global
// result.localAppSettingsVariant = newQVariant(singletonInstance.localAppSettings)
// result.localAccountSettingsVariant = newQVariant(singletonInstance.localAccountSettings)
// result.localAccountSensitiveSettingsVariant = newQVariant(singletonInstance.localAccountSensitiveSettings)
// result.userProfileVariant = newQVariant(singletonInstance.userProfile)
// result.globalUtilsVariant = newQVariant(singletonInstance.utils)
// # Services
// result.settingsService = settings_service.newService()
// result.nodeConfigurationService = node_configuration_service.newService(statusFoundation.fleetConfiguration,
// result.settingsService)
// 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()
// result.contactsService = contacts_service.newService(statusFoundation.status.events, statusFoundation.threadpool)
// result.chatService = chat_service.newService(statusFoundation.status.events, result.contactsService)
// result.communityService = community_service.newService(statusFoundation.status.events)
// result.messageService = message_service.newService(statusFoundation.status.events, statusFoundation.threadpool)
// result.activityCenterService = activity_center_service.newService(statusFoundation.status.events,
// statusFoundation.threadpool, result.chatService)
// result.tokenService = token_service.newService(statusFoundation.status.events, statusFoundation.threadpool,
// result.settingsService)
// result.collectibleService = collectible_service.newService(result.settingsService)
// result.walletAccountService = wallet_account_service.newService(statusFoundation.status.events, result.settingsService,
// result.accountsService, result.tokenService)
// result.transactionService = transaction_service.newService(statusFoundation.status.events, statusFoundation.threadpool,
// result.walletAccountService)
// result.bookmarkService = bookmark_service.newService()
// result.profileService = profile_service.newService()
// result.stickersService = stickers_service.newService(
// statusFoundation.status.events,
// statusFoundation.threadpool,
// result.ethService,
// result.settingsService,
// result.walletAccountService,
// result.transactionService,
// result.networkService,
// result.chatService
// )
// result.aboutService = about_service.newService(statusFoundation.status.events, statusFoundation.threadpool,
// result.settingsService)
// result.dappPermissionsService = dapp_permissions_service.newService()
// result.languageService = language_service.newService()
// # result.mnemonicService = mnemonic_service.newService()
// result.privacyService = privacy_service.newService(statusFoundation.status.events, result.settingsService,
// result.accountsService)
// result.providerService = provider_service.newService(result.dappPermissionsService, result.settingsService)
// result.savedAddressService = saved_address_service.newService(statusFoundation.status.events)
// result.devicesService = devices_service.newService(statusFoundation.status.events, result.settingsService)
// result.mailserversService = mailservers_service.newService(statusFoundation.status.events, statusFoundation.marathon,
// 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);
// statusFoundation.status.events,
// result.keychainService,
// result.accountsService,
// result.chatService,
// result.communityService,
// result.messageService,
// result.tokenService,
// result.transactionService,
// result.collectibleService,
// result.walletAccountService,
// result.bookmarkService,
// result.profileService,
// result.settingsService,
// result.contactsService,
// result.aboutService,
// result.dappPermissionsService,
// result.languageService,
// # result.mnemonicService,
// result.privacyService,
// result.providerService,
// result.stickersService,
// result.activityCenterService,
// result.savedAddressService,
// result.nodeConfigurationService,
// result.devicesService,
// result.mailserversService
// # Do connections
connect();
}
AppController::~AppController()
{
// FIXME: `delete` should never be used, use RAII
delete m_startupModule;
delete m_accountsService;
}
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()));
}
void AppController::startupDidLoad()
{
// singletonInstance.engine.setRootContextProperty("localAppSettings", self.localAppSettingsVariant)
// singletonInstance.engine.setRootContextProperty("localAccountSettings", self.localAccountSettingsVariant)
// singletonInstance.engine.load(newQUrl("qrc:///main.qml"))
// We need to init a language service once qml is loaded
// self.languageService.init()
}
void AppController::mainDidLoad()
{
//self.statusFoundation.onLoggedIn()
m_startupModule->moveToAppState();
//self.mainModule.checkForStoringPassword()
}
void AppController::start()
{
// self.ethService.init()
m_accountsService->init();
m_startupModule->load();
}
void AppController::load()
{
qWarning() << "TODO: init services and load main module";
m_walletServicePtr->init();
// self.settingsService.init()
// self.nodeConfigurationService.init()
// self.contactsService.init()
// self.chatService.init()
// self.messageService.init()
// self.communityService.init()
// self.bookmarkService.init()
// self.tokenService.init()
// self.dappPermissionsService.init()
// self.providerService.init()
// self.walletAccountService.init()
// self.transactionService.init()
// self.stickersService.init()
// self.networkService.init()
// self.activityCenterService.init()
// self.savedAddressService.init()
// self.aboutService.init()
// self.devicesService.init()
// self.mailserversService.init()
// let pubKey = self.settingsService.getPublicKey()
// singletonInstance.localAccountSensitiveSettings.setFileName(pubKey)
// singletonInstance.engine.setRootContextProperty("localAccountSensitiveSettings", self.localAccountSensitiveSettingsVariant)
// singletonInstance.engine.setRootContextProperty("globalUtils", self.globalUtilsVariant)
// # other global instances
// self.buildAndRegisterLocalAccountSensitiveSettings()
// self.buildAndRegisterUserProfile()
// # load main module
m_mainModulePtr->load(
// self.statusFoundation.status.events,
// self.settingsService,
// self.contactsService,
// self.chatService,
// self.communityService,
// self.messageService
);
}
void AppController::userLoggedIn()
{
//self.statusFoundation.status.startMessenger()
AppController::load();
// Once user is logged in and main module is loaded we need to check if it gets here importing mnemonic or not
// and delete mnemonic in the first case.
auto importedAccount = m_accountsService->getImportedAccount();
if(importedAccount.isValid())
{
// self.privacyService.removeMnemonic();
}
}
void AppController::buildAndRegisterLocalAccountSensitiveSettings()
{
// var pubKey = self.settingsService.getPublicKey()
// singletonInstance.localAccountSensitiveSettings.setFileName(pubKey)
// singletonInstance.engine.setRootContextProperty("localAccountSensitiveSettings", self.localAccountSensitiveSettingsVariant)
}
void AppController::buildAndRegisterUserProfile()
{
// let pubKey = self.settingsService.getPublicKey()
// let preferredName = self.settingsService.getPreferredName()
// let ensUsernames = self.settingsService.getEnsUsernames()
// let firstEnsName = if (ensUsernames.len > 0): ensUsernames[0] else: ""
// let sendUserStatus = self.settingsService.getSendStatusUpdates()
// // This is still not in use. Read a comment in UserProfile.
// // let currentUserStatus = self.settingsService.getCurrentUserStatus()
// let loggedInAccount = self.accountsService.getLoggedInAccount()
// var thumbnail, large: string
// for img in loggedInAccount.images:
// if(img.imgType == "large"):
// large = img.uri
// elif(img.imgType == "thumbnail"):
// thumbnail = img.uri
// let meAsContact = self.contactsService.getContactById(pubKey)
// singletonInstance.userProfile.setFixedData(loggedInAccount.name, loggedInAccount.keyUid, loggedInAccount.identicon,
// pubKey)
// singletonInstance.userProfile.setPreferredName(preferredName)
// singletonInstance.userProfile.setEnsName(meAsContact.name)
// singletonInstance.userProfile.setFirstEnsName(firstEnsName)
// singletonInstance.userProfile.setThumbnailImage(thumbnail)
// singletonInstance.userProfile.setLargeImage(large)
// singletonInstance.userProfile.setUserStatus(sendUserStatus)
// singletonInstance.engine.setRootContextProperty("userProfile", self.userProfileVariant)
}

View File

@ -1,49 +0,0 @@
#pragma once
#include <QObject>
#include "../modules/main/interfaces/module_access_interface.h"
#include "../modules/startup/module_access_interface.h"
#include "accounts/service.h"
#include "app_controller_delegate.h"
#include "app_service.h"
#include "wallet_accounts/service.h"
class AppController : public QObject, AppControllerDelegate
{
Q_OBJECT
//statusFoundation: StatusFoundation
// Global
//localAppSettingsVariant: QVariant
//localAccountSettingsVariant: QVariant
//localAccountSensitiveSettingsVariant: QVariant
//userProfileVariant: QVariant
//globalUtilsVariant: QVariant
// Services
// FIXME: don't use raw pointers
Accounts::Service* m_accountsService;
std::shared_ptr<Wallets::Service> m_walletServicePtr;
// Modules
// To-Do make this a shared pointer and remove circular dependency.
Modules::Startup::ModuleAccessInterface* m_startupModule;
Modules::Main::IModuleAccess* m_mainModulePtr;
public:
AppController();
~AppController() override;
void start();
public slots:
void mainDidLoad();
private:
void connect();
void startupDidLoad() override;
void load();
void userLoggedIn() override;
void buildAndRegisterLocalAccountSensitiveSettings();
void buildAndRegisterUserProfile();
};

View File

@ -1,9 +0,0 @@
#pragma once
class AppControllerDelegate
{
public:
virtual void startupDidLoad() = 0;
virtual void userLoggedIn() = 0;
};

View File

@ -1,89 +0,0 @@
#include "signals.h"
#include "libstatus.h"
#include <QDebug>
#include <QJsonDocument>
#include <QJsonObject>
#include <QObject>
#include <QtConcurrent>
namespace Signals
{
Manager* Manager::instance()
{
static auto manager = new Manager();
return manager;
}
std::map<QString, SignalType> Manager::signalMap;
Manager::Manager(QObject* parent)
: QObject(parent)
{
SetSignalEventCallback((void*)&Manager::signalCallback);
signalMap = {{"node.ready", SignalType::NodeReady},
{"node.started", SignalType::NodeStarted},
{"node.stopped", SignalType::NodeStopped},
{"node.login", SignalType::NodeLogin},
{"node.crashed", SignalType::NodeCrashed}};
}
void Manager::processSignal(QString statusSignal)
{
try
{
QJsonParseError json_error;
const QJsonDocument signalEventDoc(QJsonDocument::fromJson(statusSignal.toUtf8(), &json_error));
if(json_error.error != QJsonParseError::NoError)
{
qWarning() << "Invalid signal received";
return;
}
decode(signalEventDoc.object());
}
catch(const std::exception& e)
{
qWarning() << "Error decoding signal, err: ", e.what();
return;
}
}
void Manager::decode(const QJsonObject& signalEvent)
{
SignalType signalType(Unknown);
if(!signalMap.count(signalEvent["type"].toString()))
{
qWarning() << "Unknown signal received: " << signalEvent["type"].toString();
return;
}
signalType = signalMap[signalEvent["type"].toString()];
switch(signalType)
{
// TODO: create extractor functions like in nim
case NodeLogin: emit instance()->nodeLogin(NodeSignal{signalType, signalEvent["event"]["error"].toString()}); break;
case NodeReady: emit instance()->nodeReady(NodeSignal{signalType, signalEvent["event"]["error"].toString()}); break;
case NodeStarted:
emit instance()->nodeStarted(NodeSignal{signalType, signalEvent["event"]["error"].toString()});
break;
case NodeStopped:
emit instance()->nodeStopped(NodeSignal{signalType, signalEvent["event"]["error"].toString()});
break;
case NodeCrashed: {
auto signal = NodeSignal{signalType, signalEvent["event"]["error"].toString()};
qWarning() << "node.crashed, error: " << signal.error;
emit instance()->nodeCrashed(signal);
break;
}
default: qWarning() << "Signal decoding not implemented: " << signalEvent; break;
}
}
void Manager::signalCallback(const char* data)
{
QtConcurrent::run(instance(), &Manager::processSignal, QString(data));
}
} // namespace Signals

View File

@ -1,23 +0,0 @@
#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>
const QString CHAT_SECTION_NAME = "Chat";
const QString CHAT_SECTION_ICON = "chat";
const QString WALLET_SECTION_ID = "wallet";
const QString WALLET_SECTION_NAME = "Wallet";
const QString WALLET_SECTION_ICON = "wallet";
const QString BROWSER_SECTION_ID = "browser";
const QString BROWSER_SECTION_NAME = "Browser";
const QString BROWSER_SECTION_ICON = "browser";
const QString NODEMANAGEMENT_SECTION_ID = "nodeManagement";
const QString NODEMANAGEMENT_SECTION_NAME = "Node Management";
const QString NODEMANAGEMENT_SECTION_ICON = "node";
const QString SETTINGS_SECTION_ID = "profileSettings";
const QString SETTINGS_SECTION_NAME = "Settings";
const QString SETTINGS_SECTION_ICON = "settings";

View File

@ -1,16 +0,0 @@
#include "singleton.h"
#include <QQmlApplicationEngine>
namespace Global
{
Singleton* Singleton::instance()
{
static auto singleton = new Singleton();
return singleton;
}
QQmlApplicationEngine* Singleton::engine()
{
return &m_engine;
}
} // namespace Global

View File

@ -1,61 +0,0 @@
#pragma once
#include <QObject>
#include <QString>
#include <QVariant>
#include <QVariantList>
namespace Signals
{
Q_NAMESPACE
enum SignalType
{
Unknown,
NodeLogin,
NodeReady,
NodeStarted,
NodeStopped,
NodeCrashed
};
Q_ENUM_NS(SignalType)
struct Signal
{
SignalType signalType;
};
struct NodeSignal : Signal
{
QString error;
};
class Manager : public QObject
{
Q_OBJECT
public:
static Manager* instance();
signals:
void signal(SignalType signal);
void nodeReady(NodeSignal signal);
void nodeStarted(NodeSignal signal);
void nodeStopped(NodeSignal signal);
void nodeLogin(NodeSignal signal);
void nodeCrashed(NodeSignal signal);
private:
explicit Manager(QObject* parent = nullptr);
static std::map<QString, SignalType> signalMap;
static void signalCallback(const char* data);
void processSignal(QString ev);
void decode(const QJsonObject& signalEvent);
};
} // namespace Signals
Q_DECLARE_METATYPE(Signals::Signal)
Q_DECLARE_METATYPE(Signals::NodeSignal)

View File

@ -1,21 +0,0 @@
#pragma once
#include <QQmlApplicationEngine>
namespace Global
{
class Singleton
{
public:
// FIXME: should return reference
QQmlApplicationEngine* engine();
// FIXME: should return reference
static Singleton* instance();
private:
Singleton() = default;
QQmlApplicationEngine m_engine;
};
} // namespace Global

View File

@ -1,9 +0,0 @@
#include <QDebug>
#include "controller.h"
namespace Modules::Main
{
void Controller::init() { }
} // namespace Modules::Main

View File

@ -1,19 +0,0 @@
#pragma once
#include <QObject>
#include "interfaces/controller_interface.h"
#include "signals.h"
namespace Modules::Main
{
class Controller : public QObject, public IController
{
public:
using QObject::QObject;
void init() override;
};
} // namespace Modules::Main

View File

@ -1,12 +0,0 @@
#pragma once
namespace Modules::Main
{
// Abstract class for any input/interaction with this module.
class IController
{
public:
virtual void init() = 0;
virtual ~IController() = default;
};
} // namespace Modules::Main

View File

@ -1,19 +0,0 @@
#pragma once
#include <QObject>
namespace Modules::Main
{
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

View File

@ -1,64 +0,0 @@
#include <QDebug>
#include <QQmlContext>
#include "../shared/section_item.h"
#include "module.h"
#include "modules/main/wallet/module.h"
#include "singleton.h"
namespace Modules::Main
{
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(walletService, this);
m_moduleLoaded = false;
connect();
}
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()));
}
void Module::load()
{
Global::Singleton::instance()->engine()->rootContext()->setContextProperty("mainModule", m_viewPtr);
m_controllerPtr->init();
m_viewPtr->load();
m_walletModulePtr->load();
}
void Module::checkIfModuleDidLoad()
{
if(!m_walletModulePtr->isLoaded())
{
return;
}
m_moduleLoaded = true;
emit loaded();
}
void Module::viewDidLoad()
{
Module::checkIfModuleDidLoad();
}
void Module::walletDidLoad()
{
Module::checkIfModuleDidLoad();
}
bool Module::isLoaded()
{
return m_moduleLoaded;
}
} // namespace Modules::Main

View File

@ -1,42 +0,0 @@
#pragma once
#include <QObject>
#include <QPointer>
#include "interfaces/module_access_interface.h"
#include "wallet_accounts/service_interface.h"
#include "controller.h"
#include "view.h"
namespace Modules::Main
{
class Module : public QObject, public IModuleAccess
{
Q_OBJECT
public:
explicit Module(std::shared_ptr<Wallets::ServiceInterface> walletService, QObject* parent = nullptr);
void load() override;
bool isLoaded() override;
public slots:
void viewDidLoad();
void walletDidLoad();
signals:
void loaded() override;
private:
void connect();
void checkIfModuleDidLoad();
// 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

View File

@ -1,50 +0,0 @@
#include "view.h"
#include "../global/app_sections_config.h"
namespace Modules::Main
{
void View::load()
{
// Add Wallet Section to Sections model
auto walletSectionItem = new Shared::Models::SectionItem(this,
WALLET_SECTION_ID,
Shared::Models::SectionType::Wallet,
WALLET_SECTION_NAME,
"",
"",
WALLET_SECTION_ICON,
"",
false,
true);
addItem(walletSectionItem);
setActiveSection(WALLET_SECTION_ID);
emit viewLoaded();
}
void View::addItem(Shared::Models::SectionItem* item)
{
m_sectionModel.addItem(item);
// emit sectionsModelChanged(); // FIXME: that's wrong, sectionModel* property didn't change
}
Shared::Models::SectionModel* View::getSectionsModel()
{
return &m_sectionModel;
}
Shared::Models::SectionItem* View::getActiveSection() const
{
return m_sectionModel.getActiveItem();
}
void View::setActiveSection(const QString& Id)
{
if(m_sectionModel.getActiveItem().isNull() || (m_sectionModel.getActiveItem()->getId() != Id))
{
m_sectionModel.setActiveSection(Id);
activeSectionChanged();
}
}
} // namespace Modules::Main

View File

@ -1,36 +0,0 @@
#pragma once
#include <QObject>
#include <memory>
#include "../shared/section_model.h"
namespace Modules::Main
{
class View : public QObject
{
Q_OBJECT
Q_PROPERTY(Shared::Models::SectionModel* sectionsModel READ getSectionsModel NOTIFY sectionsModelChanged)
Q_PROPERTY(Shared::Models::SectionItem* activeSection READ getActiveSection NOTIFY activeSectionChanged)
public:
using QObject::QObject;
void load();
void addItem(Shared::Models::SectionItem* item);
void setActiveSection(const QString& Id);
signals:
void viewLoaded();
void sectionsModelChanged();
void activeSectionChanged();
private:
Shared::Models::SectionModel* getSectionsModel();
Shared::Models::SectionItem* getActiveSection() const;
Shared::Models::SectionModel m_sectionModel;
};
} // namespace Modules::Main

View File

@ -1,76 +0,0 @@
#include <QDebug>
#include "controller.h"
const QString WALLETSERVICE_NULL_ERROR = "wallet service pointer is null";
namespace Modules::Main::Wallet::Accounts
{
Controller::Controller(std::shared_ptr<Wallets::ServiceInterface> walletService,
QObject* parent)
: QObject(parent),
m_walletServicePtr(walletService)
{ }
void Controller::init() { }
QList<Wallets::WalletAccountDto> Controller::getWalletAccounts()
{
QList<Wallets::WalletAccountDto> wallet_accounts;
if(m_walletServicePtr)
{
wallet_accounts = m_walletServicePtr->getWalletAccounts();
}
return wallet_accounts;
}
QString Controller::generateNewAccount(const QString& password, const QString& accountName, const QString& color)
{
QString error = WALLETSERVICE_NULL_ERROR;
if(m_walletServicePtr)
{
error = m_walletServicePtr->generateNewAccount(password, accountName, color);
}
return error;
}
QString Controller::addAccountsFromPrivateKey(const QString& privateKey, const QString& password, const QString& accountName, const QString& color)
{
QString error = WALLETSERVICE_NULL_ERROR;
if(m_walletServicePtr)
{
error = m_walletServicePtr->addAccountsFromPrivateKey(privateKey, password, accountName, color);
}
return error;
}
QString Controller::addAccountsFromSeed(const QString& seedPhrase, const QString& password, const QString& accountName, const QString& color)
{
QString error = WALLETSERVICE_NULL_ERROR;
if(m_walletServicePtr)
{
error = m_walletServicePtr->addAccountsFromSeed(seedPhrase, password, accountName, color);
}
return error;
}
QString Controller::addWatchOnlyAccount(const QString& address, const QString& accountName, const QString& color)
{
QString error = WALLETSERVICE_NULL_ERROR;
if(m_walletServicePtr)
{
error = m_walletServicePtr->addWatchOnlyAccount(address, accountName, color);
}
return error;
}
void Controller::deleteAccount(const QString& address)
{
if(m_walletServicePtr)
{
m_walletServicePtr->deleteAccount(address);
}
}
} // namespace Modules::Main::Wallet::Accounts

View File

@ -1,37 +0,0 @@
#pragma once
#include <QObject>
#include "interfaces/controller_interface.h"
#include "signals.h"
#include "wallet_accounts/service_interface.h"
#include "wallet_accounts/wallet_account.h"
namespace Modules::Main::Wallet::Accounts
{
class Controller : public QObject, public IController
{
Q_OBJECT
public:
explicit Controller(std::shared_ptr<Wallets::ServiceInterface> walletService, QObject* parent = nullptr);
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);
void deleteAccount(const QString& address);
private:
std::shared_ptr<Wallets::ServiceInterface> m_walletServicePtr;
};
} // namespace Modules::Main::Wallet::Accounts

View File

@ -1,98 +0,0 @@
#include "item.h"
namespace Modules::Main::Wallet::Accounts
{
Item::Item(QObject* parent,
const QString& name,
const QString& address,
const QString& path,
const QString& color,
const QString& publicKey,
const QString& walletType,
bool isWallet,
bool isChat,
float currencyBalance)
: QObject(parent)
, m_name(name)
, m_address(address)
, m_path(path)
, m_color(color)
, m_publicKey(publicKey)
, m_walletType(walletType)
, m_isWallet(isWallet)
, m_isChat(isChat)
, m_currencyBalance(currencyBalance)
{ }
const QString& Item::getName() const
{
return m_name;
}
const QString& Item::getAddress() const
{
return m_address;
}
const QString& Item::getPath() const
{
return m_path;
}
const QString& Item::getColor() const
{
return m_color;
}
const QString& Item::getPublicKey() const
{
return m_publicKey;
}
const QString& Item::getWalletType() const
{
return m_walletType;
}
bool Item::getIsWallet() const
{
return m_isWallet;
}
bool Item::getIsChat() const
{
return m_isChat;
}
float Item::getCurrencyBalance() const
{
return m_currencyBalance;
}
void Item::setData(Item* item)
{
if(item)
{
m_name = item->getName();
emit nameChanged();
m_address = item->getAddress();
emit addressChanged();
m_path = item->getPath();
emit pathChanged();
m_color = item->getColor();
emit colorChanged();
m_publicKey = item->getPublicKey();
emit publicKeyChanged();
m_walletType = item->getWalletType();
emit walletTypeChanged();
m_isWallet = item->getIsWallet();
emit isWalletChanged();
m_isChat = item->getIsChat();
emit isChatChanged();
m_currencyBalance = item->getCurrencyBalance();
emit currencyBalanceChanged();
}
}
} // namespace Modules::Main::Wallet::Accounts

View File

@ -1,66 +0,0 @@
#pragma once
#include <QObject>
#include <QString>
namespace Modules::Main::Wallet::Accounts
{
class Item : public QObject
{
Q_OBJECT
Q_PROPERTY(QString name READ getName NOTIFY nameChanged);
Q_PROPERTY(QString address READ getAddress NOTIFY addressChanged);
Q_PROPERTY(QString path READ getPath NOTIFY pathChanged);
Q_PROPERTY(QString color READ getColor NOTIFY colorChanged);
Q_PROPERTY(QString publicKey READ getPublicKey NOTIFY publicKeyChanged);
Q_PROPERTY(QString walletType READ getWalletType NOTIFY walletTypeChanged);
Q_PROPERTY(bool isWallet READ getIsWallet NOTIFY isWalletChanged);
Q_PROPERTY(bool isChat READ getIsChat NOTIFY isChatChanged);
Q_PROPERTY(float currencyBalance READ getCurrencyBalance NOTIFY currencyBalanceChanged);
public:
Item(QObject* parent = nullptr,
const QString& name = "",
const QString& address = "",
const QString& path = "",
const QString& color = "",
const QString& publicKey = "",
const QString& walletType = "",
bool isWallet = false,
bool isChat = false,
float currencyBalance = 0);
const QString& getName() const;
const QString& getAddress() const;
const QString& getPath() const;
const QString& getColor() const;
const QString& getPublicKey() const;
const QString& getWalletType() const;
bool getIsWallet() const;
bool getIsChat() const;
float getCurrencyBalance() const;
void setData(Item* item);
signals:
void nameChanged();
void addressChanged();
void pathChanged();
void colorChanged();
void publicKeyChanged();
void walletTypeChanged();
void isWalletChanged();
void isChatChanged();
void currencyBalanceChanged();
private:
QString m_name;
QString m_address;
QString m_path;
QString m_color;
QString m_publicKey;
QString m_walletType;
bool m_isWallet;
bool m_isChat;
float m_currencyBalance;
};
} // namespace Modules::Main::Wallet::Accounts

View File

@ -1,78 +0,0 @@
#include "model.h"
namespace Modules::Main::Wallet::Accounts
{
Model::Model(QObject* parent)
: QAbstractListModel(parent)
{ }
QHash<int, QByteArray> Model::roleNames() const
{
QHash<int, QByteArray> roles;
roles[Name] = "name";
roles[Address] = "address";
roles[Path] = "path";
roles[Color] = "color";
roles[PublicKey] = "publicKey";
roles[WalletType] = "walletType";
roles[IsWallet] = "isWallet";
roles[IsChat] = "isChat";
roles[Assets] = "assets";
roles[CurrencyBalance] = "currencyBalance";
return roles;
}
int Model::rowCount(const QModelIndex& parent = QModelIndex()) const
{
return m_items.size();
}
QVariant Model::data(const QModelIndex& index, int role) const
{
if(!index.isValid())
{
return QVariant();
}
if(index.row() < 0 || index.row() >= m_items.size())
{
return QVariant();
}
const Item* item = m_items.at(index.row());
switch(role)
{
case Name: return item->getName();
case Address: return item->getAddress();
case Path: return item->getPath();
case Color: return item->getColor();
case PublicKey: return item->getPublicKey();
case WalletType: return item->getWalletType();
case IsWallet: return item->getIsWallet();
case IsChat: return item->getIsChat();
// case Assets: return QVariant(item.ge());
case CurrencyBalance: return item->getCurrencyBalance();
}
return QVariant();
}
void Model::setItems(const QVector<Item*>& items)
{
beginResetModel();
m_items = items;
endResetModel();
}
Item* Model::getItemByIndex(int index) const
{
Item* returnItemPtr = nullptr;
if((index > 0) && (index < m_items.size()))
{
returnItemPtr = m_items.at(index);
}
return returnItemPtr;
}
} // namespace Modules::Main::Wallet::Accounts

View File

@ -1,41 +0,0 @@
#pragma once
#include <QAbstractListModel>
#include <QHash>
#include <QVector>
#include "item.h"
namespace Modules::Main::Wallet::Accounts
{
class Model : public QAbstractListModel
{
Q_OBJECT
public:
enum ModelRole
{
Name = Qt::UserRole + 1,
Address,
Path,
Color,
PublicKey,
WalletType,
IsWallet,
IsChat,
Assets,
CurrencyBalance
};
explicit Model(QObject* parent = nullptr);
QHash<int, QByteArray> roleNames() const override;
int rowCount(const QModelIndex&) const override;
QVariant data(const QModelIndex& index, int role) const override;
void setItems(const QVector<Item*>& items);
Item* getItemByIndex(int index) const;
private:
QVector<Item*> m_items;
};
} // namespace Modules::Main::Wallet::Accounts

View File

@ -1,43 +0,0 @@
#include <QDebug>
#include <QQmlContext>
#include "module.h"
#include "singleton.h"
namespace Modules::Main::Wallet::Accounts
{
Module::Module(std::shared_ptr<Wallets::ServiceInterface> walletsService, QObject* parent)
: QObject(parent)
{
m_controllerPtr = new Controller(walletsService, this);
m_viewPtr = new View(m_controllerPtr, this);
m_moduleLoaded = false;
connect();
}
void Module::connect()
{
QObject::connect(m_viewPtr, &View::viewLoaded, this, &Module::viewDidLoad);
}
void Module::load()
{
Global::Singleton::instance()->engine()->rootContext()->setContextProperty("walletSectionAccounts", m_viewPtr);
m_controllerPtr->init();
m_viewPtr->load();
}
bool Module::isLoaded()
{
return m_moduleLoaded;
}
void Module::viewDidLoad()
{
m_moduleLoaded = true;
emit loaded();
}
} // namespace Modules::Main::Wallet::Accounts

View File

@ -1,35 +0,0 @@
#pragma once
#include <QObject>
#include "controller.h"
#include "interfaces/module_access_interface.h"
#include "view.h"
#include "wallet_accounts/service_interface.h"
namespace Modules::Main::Wallet::Accounts
{
class Module : public QObject, virtual public IModuleAccess
{
Q_OBJECT
public:
explicit Module(std::shared_ptr<Wallets::ServiceInterface> walletsService, QObject* parent = nullptr);
void load() override;
bool isLoaded() override;
public slots:
void viewDidLoad();
signals:
void loaded() override;
private:
void connect();
View* m_viewPtr;
Controller* m_controllerPtr;
bool m_moduleLoaded;
};
} // namespace Modules::Main::Wallet::Accounts

View File

@ -1,146 +0,0 @@
#include <QDebug>
#include "view.h"
namespace Modules::Main::Wallet::Accounts
{
View::View(Controller *controller, QObject* parent)
: QObject(parent),
m_controllerPtr(controller)
{
m_modelPtr = new Model(this);
m_currentAccountPtr = new Item(this);
}
void View::load()
{
refreshWalletAccounts();
emit viewLoaded();
}
Model* View::getModel() const
{
return m_modelPtr;
}
void View::setModelItems(const QVector<Item*>& accounts) {
m_modelPtr->setItems(accounts);
m_currentAccountPtr->setData(accounts.at(0));
modelChanged();
}
void View::refreshWalletAccounts()
{
auto walletAccounts = m_controllerPtr->getWalletAccounts();
if(walletAccounts.size() > 0)
{
QVector<Item*> items;
foreach(const auto& acc, walletAccounts)
{
items << new Item(this, acc.name, acc.address, acc.path, acc.color, acc.publicKey, acc.walletType, acc.isWallet, acc.isChat, 0);
}
setModelItems(items);
}
else
{
qWarning()<<"No accounts found!";
}
}
QString View::generateNewAccount(const QString& password, const QString& accountName, const QString& color)
{
QString error = "";
if(m_controllerPtr)
{
error = m_controllerPtr->generateNewAccount(password, accountName, color);
if(error.isEmpty())
{
refreshWalletAccounts();
}
}
else {
error = "controller pointer is null";
}
return error;
}
QString View::addAccountsFromPrivateKey(const QString& privateKey, const QString& password, const QString& accountName, const QString& color)
{
QString error = "";
if(m_controllerPtr)
{
error = m_controllerPtr->addAccountsFromPrivateKey(privateKey, password, accountName, color);
if(error.isEmpty())
{
refreshWalletAccounts();
}
}
else {
error = "controller pointer is null";
}
return error;
}
QString View::addAccountsFromSeed(const QString& seedPhrase, const QString& password, const QString& accountName, const QString& color)
{
QString error = "";
if(m_controllerPtr)
{
error = m_controllerPtr->addAccountsFromSeed(seedPhrase, password, accountName, color);
if(error.isEmpty())
{
refreshWalletAccounts();
}
}
else {
error = "controller pointer is null";
}
return error;
}
QString View::addWatchOnlyAccount(const QString& address, const QString& accountName , const QString& color)
{
QString error = "";
if(m_controllerPtr)
{
error = m_controllerPtr->addWatchOnlyAccount(address, accountName, color);
if(error.isEmpty())
{
refreshWalletAccounts();
}
}
else {
error = "controller pointer is null";
}
return error;
}
void View::deleteAccount(const QString& address)
{
if(m_controllerPtr)
{
m_controllerPtr->deleteAccount(address);
refreshWalletAccounts();
}
else {
qWarning()<<"controller pointer is null";
}
}
void View::switchAccount(int index)
{
auto itemAtIndex = m_modelPtr->getItemByIndex(index);
if(itemAtIndex)
{
m_currentAccountPtr->setData(itemAtIndex);
emit currentAccountChanged();
}
}
Item* View::getCurrentAccount() const
{
return m_currentAccountPtr;
}
} // namespace Modules::Main::Wallet::Accounts

View File

@ -1,51 +0,0 @@
#pragma once
#include <QObject>
#include <memory>
#include "controller.h"
#include "item.h"
#include "model.h"
namespace Modules::Main::Wallet::Accounts
{
class View : public QObject
{
Q_OBJECT
Q_PROPERTY(Model* model READ getModel NOTIFY modelChanged)
Q_PROPERTY(Item* currentAccount READ getCurrentAccount NOTIFY currentAccountChanged)
public:
explicit View(Controller* controller, QObject* parent = nullptr);
void load();
void setModelItems(const QVector<Item*>& accounts);
Model* getModel() const;
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 void deleteAccount(const QString& address);
Q_INVOKABLE void switchAccount(int index);
signals:
void viewLoaded();
void modelChanged();
void currentAccountChanged();
private:
void refreshWalletAccounts();
Model* m_modelPtr;
Controller* m_controllerPtr;
Item* m_currentAccountPtr;
};
} // namespace Modules::Main::Wallet::Accounts

View File

@ -1,13 +0,0 @@
#include <QDebug>
#include "controller.h"
namespace Modules::Main::Wallet
{
Controller::Controller(std::shared_ptr<Wallets::ServiceInterface> walletService, QObject* parent)
: QObject(parent),
m_walletService(walletService)
{ }
void Controller::init() { }
} // namespace Modules::Main::Wallet

View File

@ -1,22 +0,0 @@
#pragma once
#include <QObject>
#include "interfaces/controller_interface.h"
#include "signals.h"
#include "wallet_accounts/service_interface.h"
namespace Modules::Main::Wallet
{
class Controller : public QObject, public IController
{
Q_OBJECT
public:
explicit Controller(std::shared_ptr<Wallets::ServiceInterface> walletService, QObject* parent = nullptr);
void init() override;
private:
std::shared_ptr<Wallets::ServiceInterface> m_walletService;
};
} // namespace Modules::Main::Wallet

View File

@ -1,62 +0,0 @@
#include <QDebug>
#include <QQmlContext>
#include "accounts/module.h"
#include "module.h"
#include "singleton.h"
namespace Modules::Main::Wallet
{
Module::Module(std::shared_ptr<Wallets::ServiceInterface> walletsService, QObject* parent)
: QObject(parent)
{
m_controllerPtr = new Controller(walletsService, this);
m_viewPtr = new View(this);
// Sub-Modules
m_accountsModulePtr = new Modules::Main::Wallet::Accounts::Module(walletsService, this);
m_moduleLoaded = false;
connect();
}
void Module::connect()
{
QObject::connect(m_viewPtr, SIGNAL(viewLoaded()), this, SLOT(viewDidLoad()));
QObject::connect(dynamic_cast<QObject*>(m_accountsModulePtr), SIGNAL(loaded()), this, SLOT(accountsDidLoad()));
}
void Module::load()
{
Global::Singleton::instance()->engine()->rootContext()->setContextProperty("walletSection", m_viewPtr);
m_controllerPtr->init();
m_viewPtr->load();
m_accountsModulePtr->load();
}
bool Module::isLoaded()
{
return m_moduleLoaded;
}
void Module::checkIfModuleDidLoad()
{
if(!m_accountsModulePtr->isLoaded())
{
return;
}
m_moduleLoaded = true;
emit loaded();
}
void Module::viewDidLoad()
{
checkIfModuleDidLoad();
}
void Module::accountsDidLoad()
{
checkIfModuleDidLoad();
}
} // namespace Modules::Main::Wallet

View File

@ -1,40 +0,0 @@
#pragma once
#include <QObject>
#include "wallet_accounts/service_interface.h"
#include "../interfaces/module_access_interface.h"
#include "controller.h"
#include "view.h"
namespace Modules::Main::Wallet
{
class Module : public QObject, virtual public IModuleAccess
{
Q_OBJECT
public:
explicit Module(std::shared_ptr<Wallets::ServiceInterface> walletsService, QObject* parent);
void load() override;
bool isLoaded() override;
void checkIfModuleDidLoad();
public slots:
void viewDidLoad();
void accountsDidLoad();
signals:
void loaded() override;
private:
void connect();
View* m_viewPtr;
Controller* m_controllerPtr;
IModuleAccess* m_accountsModulePtr;
bool m_moduleLoaded;
};
} // namespace Modules::Main::Wallet

View File

@ -1,16 +0,0 @@
#include <QDebug>
#include "view.h"
namespace Modules::Main::Wallet
{
View::View(QObject* parent)
: QObject(parent)
{ }
void View::load()
{
emit viewLoaded();
}
} // namespace Modules::Main::Wallet

View File

@ -1,19 +0,0 @@
#pragma once
#include <QObject>
namespace Modules::Main::Wallet
{
class View : public QObject
{
Q_OBJECT
public:
explicit View(QObject* parent = nullptr);
void load();
signals:
void viewLoaded();
};
} // namespace Modules::Main::Wallet

View File

@ -1,153 +0,0 @@
#include <QDebug>
#include "section_item.h"
namespace Shared::Models
{
SectionItem::SectionItem(QObject* parent,
const QString& id,
SectionType sectionType,
const QString& name,
const QString& description,
const QString& image,
const QString& icon,
const QString& color,
bool active,
bool enabled,
bool amISectionAdmin,
bool hasNotification,
int notificationsCount,
bool isMember,
bool joined,
bool canJoin,
bool canManageUsers,
bool canRequestAccess,
int access,
bool ensOnly)
: QObject(parent)
, m_id(id)
, m_sectionType(sectionType)
, m_name(name)
, m_amISectionAdmin(amISectionAdmin)
, m_description(description)
, m_image(image)
, m_icon(icon)
, m_color(color)
, m_hasNotification(hasNotification)
, m_notificationsCount(notificationsCount)
, m_active(active)
, m_enabled(enabled)
, m_isMember(isMember)
, m_joined(joined)
, m_canJoin(canJoin)
, m_canManageUsers(canManageUsers)
, m_canRequestAccess(canRequestAccess)
, m_access(access)
, m_ensOnly(ensOnly)
{ }
SectionType SectionItem::getSectionType() const
{
return m_sectionType;
}
const QString& SectionItem::getId() const
{
return m_id;
}
const QString& SectionItem::getName() const
{
return m_name;
}
bool SectionItem::getAmISectionAdmin() const
{
return m_amISectionAdmin;
}
const QString& SectionItem::getDescription() const
{
return m_description;
}
const QString& SectionItem::getImage() const
{
return m_image;
}
const QString& SectionItem::getIcon() const
{
return m_icon;
}
const QString& SectionItem::getColor() const
{
return m_color;
}
bool SectionItem::getHasNotification() const
{
return m_hasNotification;
}
int SectionItem::getNotificationsCount() const
{
return m_notificationsCount;
}
bool SectionItem::getIsActive() const
{
return m_active;
}
bool SectionItem::getIsEnabled() const
{
return m_enabled;
}
bool SectionItem::getIsMember() const
{
return m_isMember;
}
bool SectionItem::getHasJoined() const
{
return m_joined;
}
bool SectionItem::getCanJoin() const
{
return m_canJoin;
}
bool SectionItem::getCanManageUsers() const
{
return m_canManageUsers;
}
bool SectionItem::getCanRequestAccess() const
{
return m_canRequestAccess;
}
int SectionItem::getAccess() const
{
return m_access;
}
bool SectionItem::getIsEnsOnly() const
{
return m_ensOnly;
}
void SectionItem::setIsActive(bool isActive)
{
if(m_active != isActive)
{
m_active = isActive;
activeChanged();
}
}
} // namespace Shared::Models

View File

@ -1,118 +0,0 @@
#pragma once
#include <QObject>
#include <QString>
namespace Shared::Models
{
enum SectionType
{
Unkown = -1,
Chat,
Community,
Wallet,
Browser,
ProfileSettings,
NodeManagement
};
class SectionItem : public QObject
{
Q_OBJECT
Q_PROPERTY(QString id READ getId)
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)
Q_PROPERTY(QString image READ getImage)
Q_PROPERTY(QString icon READ getIcon)
Q_PROPERTY(QString color READ getColor)
Q_PROPERTY(bool hasNotification READ getHasNotification)
Q_PROPERTY(int notificationsCount READ getNotificationsCount)
Q_PROPERTY(bool active READ getIsActive NOTIFY activeChanged)
Q_PROPERTY(bool enabled READ getIsEnabled)
Q_PROPERTY(bool joined READ getHasJoined)
Q_PROPERTY(bool isMember READ getIsMember)
Q_PROPERTY(bool canJoin READ getCanJoin)
Q_PROPERTY(bool canManageUsers READ getCanManageUsers)
Q_PROPERTY(bool canRequestAccess READ getCanRequestAccess)
Q_PROPERTY(int access READ getAccess)
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,
const QString& name = "",
const QString& description = "",
const QString& image = "",
const QString& icon = "",
const QString& color = "",
bool active = false,
bool enabled = false,
bool amISectionAdmin = false,
bool hasNotification = false,
int notificationsCount = 0,
bool isMember = false,
bool joined = false,
bool canJoin = false,
bool canManageUsers = false,
bool canRequestAccess = false,
int access = 0,
bool ensOnly = false);
~SectionItem() = default;
// Getters
SectionType getSectionType() const;
const QString& getId() const;
const QString& getName() const;
bool getAmISectionAdmin() const;
const QString& getDescription() const;
const QString& getImage() const;
const QString& getIcon() const;
const QString& getColor() const;
bool getHasNotification() const;
int getNotificationsCount() const;
bool getIsActive() const;
bool getIsEnabled() const;
bool getIsMember() const;
bool getHasJoined() const;
bool getCanJoin() const;
bool getCanManageUsers() const;
bool getCanRequestAccess() const;
int getAccess() const;
bool getIsEnsOnly() const;
// Setters
void setIsActive(bool isActive);
signals:
void activeChanged();
private:
SectionType m_sectionType;
QString m_id;
QString m_name;
bool m_amISectionAdmin;
QString m_description;
QString m_image;
QString m_icon;
QString m_color;
bool m_hasNotification;
int m_notificationsCount;
bool m_active;
bool m_enabled;
bool m_isMember;
bool m_joined;
bool m_canJoin;
bool m_canManageUsers;
bool m_canRequestAccess;
int m_access;
bool m_ensOnly;
// membersModel: user_model.Model
// pendingRequestsToJoinModel: PendingRequestModel
};
} // namespace Shared::Models

View File

@ -1,125 +0,0 @@
#include "section_model.h"
namespace Shared::Models
{
SectionModel::SectionModel(QObject* parent)
: QAbstractListModel(parent)
{ }
QHash<int, QByteArray> SectionModel::roleNames() const
{
QHash<int, QByteArray> roles;
roles[Id] = "id";
roles[SectionType] = "sectionType";
roles[Name] = "name";
roles[AmISectionAdmin] = "amISectionAdmin";
roles[Description] = "description";
roles[Image] = "image";
roles[Icon] = "icon";
roles[Color] = "color";
roles[HasNotification] = "hasNotification";
roles[NotificationsCount] = "notificationsCount";
roles[Active] = "active";
roles[Enabled] = "enabled";
roles[Joined] = "joined";
roles[IsMember] = "isMember";
roles[CanJoin] = "canJoin";
roles[CanManageUsers] = "canManageUsers";
roles[CanRequestAccess] = "canRequestAccess";
roles[Access] = "access";
roles[EnsOnly] = "ensOnly";
roles[MembersModel] = "members";
roles[PendingRequestsToJoinModel] = "pendingRequestsToJoin";
return roles;
}
int SectionModel::rowCount(const QModelIndex& parent = QModelIndex()) const
{
return m_items.size();
}
QVariant SectionModel::data(const QModelIndex& index, int role) const
{
if(!index.isValid())
{
return QVariant();
}
if(index.row() < 0 || index.row() >= m_items.size())
{
return QVariant();
}
SectionItem* item = m_items.at(index.row());
switch(role)
{
case Id: return item->getId();
case SectionType: return item->getSectionType();
case Name: return item->getName();
case AmISectionAdmin: return item->getAmISectionAdmin();
case Description: return item->getDescription();
case Image: return item->getImage();
case Icon: return item->getIcon();
case Color: return item->getColor();
case HasNotification: return item->getHasNotification();
case NotificationsCount: return item->getNotificationsCount();
case Active: return item->getIsActive();
case Enabled: return item->getIsEnabled();
case Joined: return item->getHasJoined();
case IsMember: return item->getIsMember();
case CanJoin: return item->getCanJoin();
case CanManageUsers: return item->getCanManageUsers();
case CanRequestAccess: return item->getCanRequestAccess();
case Access: return item->getAccess();
case EnsOnly:
return item->getIsEnsOnly();
// To Do
case MembersModel: return QVariant();
case PendingRequestsToJoinModel: return QVariant();
}
return QVariant();
}
void SectionModel::addItem(SectionItem* item)
{
beginInsertRows(QModelIndex(), m_items.size(), m_items.size());
m_items.append(item);
endInsertRows();
}
void SectionModel::setActiveSection(const QString& Id)
{
for(int i = 0; i < m_items.size(); ++i)
{
auto newIndex = createIndex(i, 0, nullptr);
if(m_items.at(i)->getIsActive())
{
m_items.at(i)->setIsActive(false);
dataChanged(newIndex, newIndex, QVector<int>(ModelRole::Active));
}
if(m_items.at(i)->getId() == Id)
{
m_items.at(i)->setIsActive(true);
dataChanged(newIndex, newIndex, QVector<int>(ModelRole::Active));
}
}
}
QPointer<SectionItem> SectionModel::getActiveItem() const
{
SectionItem* activeItem = nullptr;
for(auto item : m_items)
{
if(item->getIsActive())
{
activeItem = item;
break;
}
}
return activeItem;
}
} // namespace Shared::Models

View File

@ -1,60 +0,0 @@
#pragma once
#include <QAbstractListModel>
#include <QHash>
#include <QPointer>
#include <QVector>
#include <memory>
#include "section_item.h"
namespace Shared::Models
{
class SectionModel : public QAbstractListModel
{
Q_OBJECT
public:
enum ModelRole
{
Id = Qt::UserRole + 1,
SectionType,
Name,
AmISectionAdmin,
Description,
Image,
Icon,
Color,
HasNotification,
NotificationsCount,
Active,
Enabled,
Joined,
IsMember,
CanJoin,
CanManageUsers,
CanRequestAccess,
Access,
EnsOnly,
MembersModel,
PendingRequestsToJoinModel
};
explicit SectionModel(QObject* parent = nullptr);
~SectionModel() = default;
QHash<int, QByteArray> roleNames() const override;
int rowCount(const QModelIndex&) const override;
QVariant data(const QModelIndex& index, int role) const override;
void addItem(SectionItem* item);
void setActiveSection(const QString& Id);
QPointer<SectionItem> getActiveItem() const;
// To add other api's later as needed
private:
QVector<SectionItem*> m_items;
};
} // namespace Shared::Models

View File

@ -1,55 +0,0 @@
#include "controller.h"
#include "accounts/service_interface.h"
#include "interfaces/module_controller_delegate_interface.h"
#include "signals.h"
#include <QDebug>
namespace Modules
{
namespace Startup
{
Controller::Controller(ModuleControllerDelegateInterface* delegate,
Accounts::ServiceInterface* accountsService,
QObject* parent)
: QObject(parent)
, m_accountsService(accountsService)
, m_delegate(delegate)
{ }
void Controller::init()
{
QObject::connect(Signals::Manager::instance(), &Signals::Manager::nodeLogin, this, &Controller::onLogin);
QObject::connect(Signals::Manager::instance(), &Signals::Manager::nodeStopped, this, &Controller::onNodeStopped);
QObject::connect(Signals::Manager::instance(), &Signals::Manager::nodeReady, this, &Controller::onNodeReady);
}
void Controller::onLogin(Signals::NodeSignal signal)
{
if(signal.error.isEmpty())
{
m_delegate->userLoggedIn();
}
else
{
qWarning() << "error: methodName=init, errDescription=login error " << signal.error;
}
}
void Controller::onNodeStopped(Signals::NodeSignal signal)
{
// self.events.emit("nodeStopped", Args())
m_accountsService->clear();
m_delegate->emitLogOut();
}
void Controller::onNodeReady(Signals::NodeSignal signal)
{
// self.events.emit("nodeReady", Args())
}
bool Controller::shouldStartWithOnboardingScreen()
{
return m_accountsService->openedAccounts().size() == 0;
}
} // namespace Startup
} // namespace Modules

View File

@ -1,32 +0,0 @@
#pragma once
#include "accounts/service_interface.h"
#include "controller_interface.h"
#include "interfaces/module_controller_delegate_interface.h"
#include "signals.h"
#include <QObject>
namespace Modules
{
namespace Startup
{
class Controller : public QObject, ControllerInterface
{
public:
Controller(ModuleControllerDelegateInterface* delegate,
Accounts::ServiceInterface* accountsService,
QObject* parent = nullptr);
void init() override;
bool shouldStartWithOnboardingScreen() override;
void onLogin(Signals::NodeSignal signal);
void onNodeStopped(Signals::NodeSignal signal);
void onNodeReady(Signals::NodeSignal signal);
private:
Accounts::ServiceInterface* m_accountsService;
ModuleControllerDelegateInterface* m_delegate;
};
} // namespace Startup
} // namespace Modules

View File

@ -1,18 +0,0 @@
#pragma once
namespace Modules
{
namespace Startup
{
// Abstract class for any input/interaction with this module.
class ControllerInterface
{
public:
virtual void init() = 0;
virtual bool shouldStartWithOnboardingScreen() = 0;
};
} // namespace Startup
} // namespace Modules

View File

@ -1,15 +0,0 @@
#pragma once
namespace Modules
{
namespace Startup
{
class ModuleControllerDelegateInterface
{
public:
virtual void userLoggedIn() = 0;
virtual void emitLogOut() = 0;
};
}; // namespace Startup
}; // namespace Modules

View File

@ -1,13 +0,0 @@
#pragma once
namespace Modules
{
namespace Startup
{
class ModuleLoginDelegateInterface
{
public:
virtual void loginDidLoad() = 0;
};
}; // namespace Startup
}; // namespace Modules

View File

@ -1,13 +0,0 @@
#pragma once
namespace Modules
{
namespace Startup
{
class ModuleOnboardingDelegateInterface
{
public:
virtual void onboardingDidLoad() = 0;
};
}; // namespace Startup
}; // namespace Modules

View File

@ -1,13 +0,0 @@
#pragma once
namespace Modules
{
namespace Startup
{
class ModuleViewDelegateInterface
{
public:
virtual void viewDidLoad() = 0;
};
}; // namespace Startup
}; // namespace Modules

View File

@ -1,90 +0,0 @@
#include "controller.h"
#include "accounts/account.h"
#include "accounts/service_interface.h"
#include "interfaces/module_controller_delegate_interface.h"
#include "signals.h"
#include <QDebug>
#include <QString>
#include <QVector>
namespace Modules
{
namespace Startup
{
namespace Login
{
Controller::Controller(ModuleControllerDelegateInterface* delegate,
// keychainService
Accounts::ServiceInterface* accountsService,
QObject* parent)
: QObject(parent)
, m_accountsService(accountsService)
, m_delegate(delegate)
{ }
void Controller::init()
{
QObject::connect(Signals::Manager::instance(), &Signals::Manager::nodeLogin, this, &Controller::onLogin);
// keychainServiceSuccess see src-cpp/app/modules/startup/login/controller.nim line 43
// keychainServiceError see src-cpp/app/modules/startup/login/controller.nim line 47
}
void Controller::onLogin(Signals::NodeSignal signal)
{
if(!signal.error.isEmpty())
{
m_delegate->emitAccountLoginError(signal.error);
}
}
QVector<Accounts::AccountDto> Controller::getOpenedAccounts()
{
return m_accountsService->openedAccounts();
}
Accounts::AccountDto Controller::getSelectedAccount()
{
auto openedAccounts = Controller::getOpenedAccounts();
foreach(const Accounts::AccountDto& acc, openedAccounts)
{
if(acc.keyUid == m_selectedAccountKeyUid)
{
return acc;
}
}
// TODO: For situations like this, should be better to return a std::optional instead?
return Accounts::AccountDto();
}
void Controller::setSelectedAccountKeyUid(QString keyUid)
{
m_selectedAccountKeyUid = keyUid;
// Dealing with Keychain is the MacOS only feature
// if(not defined(macosx)):
// return
// let selectedAccount = self.getSelectedAccount()
// singletonInstance.localAccountSettings.setFileName(selectedAccount.name)
// let value = singletonInstance.localAccountSettings.getStoreToKeychainValue()
// if (value != LS_VALUE_STORE):
// return
// self.keychainService.tryToObtainPassword(selectedAccount.name)
}
void Controller::login(QString password)
{
auto selectedAccount = Controller::getSelectedAccount();
auto error = m_accountsService->login(selectedAccount, password);
if(!error.isEmpty())
{
m_delegate->emitAccountLoginError(error);
}
}
} // namespace Login
} // namespace Startup
} // namespace Modules

View File

@ -1,41 +0,0 @@
#pragma once
#include "accounts/account.h"
#include "accounts/service_interface.h"
#include "controller_interface.h"
#include "interfaces/module_controller_delegate_interface.h"
#include "signals.h"
#include <QObject>
#include <QString>
namespace Modules
{
namespace Startup
{
namespace Login
{
class Controller : public QObject, ControllerInterface
{
Q_OBJECT
public:
Controller(ModuleControllerDelegateInterface* delegate,
// keychainService,
Accounts::ServiceInterface* accountsService,
QObject* parent = nullptr);
void init() override;
QVector<Accounts::AccountDto> getOpenedAccounts() override;
Accounts::AccountDto getSelectedAccount();
void setSelectedAccountKeyUid(QString keyUid) override;
void login(QString password) override;
void onLogin(Signals::NodeSignal signal);
private:
// Keychain::m_keychainService
Accounts::ServiceInterface* m_accountsService;
ModuleControllerDelegateInterface* m_delegate;
QString m_selectedAccountKeyUid;
};
} // namespace Login
} // namespace Startup
} // namespace Modules

View File

@ -1,27 +0,0 @@
#pragma once
#include "accounts/account.h"
namespace Modules
{
namespace Startup
{
namespace Login
{
// Abstract class for any input/interaction with this module.
class ControllerInterface
{
public:
virtual void init() = 0;
virtual QVector<Accounts::AccountDto> getOpenedAccounts() = 0;
virtual void setSelectedAccountKeyUid(QString keyUid) = 0;
virtual void login(QString password) = 0;
};
} // namespace Login
} // namespace Startup
} // namespace Modules

View File

@ -1,20 +0,0 @@
#pragma once
namespace Modules
{
namespace Startup
{
namespace Login
{
class ModuleControllerDelegateInterface
{
public:
virtual void emitAccountLoginError(QString error) = 0;
virtual void emitObtainingPasswordError(QString errorDescription) = 0;
virtual void emitObtainingPasswordSuccess(QString password) = 0;
};
}; // namespace Login
}; // namespace Startup
}; // namespace Modules

View File

@ -1,22 +0,0 @@
#pragma once
#include "../item.h"
#include <QString>
namespace Modules
{
namespace Startup
{
namespace Login
{
class ModuleViewDelegateInterface
{
public:
virtual void viewDidLoad() = 0;
virtual void setSelectedAccount(Item item) = 0;
virtual void login(QString password) = 0;
};
}; // namespace Login
}; // namespace Startup
}; // namespace Modules

View File

@ -1,41 +0,0 @@
#include "item.h"
#include <QString>
namespace Modules
{
namespace Startup
{
namespace Login
{
Item::Item() { }
Item::Item(QString name, QString identicon, QString thumbnailImage, QString largeImage, QString keyUid)
: m_name(name)
, m_identicon(identicon)
, m_thumbnailImage(thumbnailImage)
, m_largeImage(largeImage)
, m_keyUid(keyUid)
{ }
QString Item::getName()
{
return m_name;
}
QString Item::getIdenticon()
{
return m_identicon;
}
QString Item::getThumbnailImage()
{
return m_thumbnailImage;
}
QString Item::getLargeImage()
{
return m_largeImage;
}
QString Item::getKeyUid()
{
return m_keyUid;
}
} // namespace Login
} // namespace Startup
} // namespace Modules

View File

@ -1,31 +0,0 @@
#pragma once
#include <QString>
namespace Modules
{
namespace Startup
{
namespace Login
{
class Item
{
private:
QString m_name;
QString m_identicon;
QString m_thumbnailImage;
QString m_largeImage;
QString m_keyUid;
public:
Item();
Item(QString name, QString identicon, QString thumbnailImage, QString largeImage, QString keyUid);
QString getName();
QString getIdenticon();
QString getThumbnailImage();
QString getLargeImage();
QString getKeyUid();
};
} // namespace Login
} // namespace Startup
} // namespace Modules

View File

@ -1,75 +0,0 @@
#include "model.h"
#include <QAbstractListModel>
#include <QDebug>
namespace Modules
{
namespace Startup
{
namespace Login
{
Model::Model(QObject* parent)
: QAbstractListModel(parent)
{ }
QHash<int, QByteArray> Model::roleNames() const
{
QHash<int, QByteArray> roles;
roles[Name] = "username";
roles[Identicon] = "identicon";
roles[ThumbnailImage] = "thumbnailImage";
roles[LargeImage] = "largeImage";
roles[KeyUid] = "keyUid";
return roles;
}
int Model::rowCount(const QModelIndex& parent = QModelIndex()) const
{
return m_items.size();
}
QVariant Model::data(const QModelIndex& index, int role) const
{
if(!index.isValid())
{
return QVariant();
}
if(index.row() < 0 || index.row() > m_items.size())
{
return QVariant();
}
Item item = m_items[index.row()];
switch(role)
{
case Name: return QVariant(item.getName());
case Identicon: return QVariant(item.getIdenticon());
case ThumbnailImage: return QVariant(item.getThumbnailImage());
case LargeImage: return QVariant(item.getLargeImage());
case KeyUid: return QVariant(item.getKeyUid());
}
return QVariant();
}
void Model::setItems(QVector<Item> items)
{
beginResetModel();
m_items = items;
endResetModel();
}
Item Model::getItemAtIndex(int index)
{
if(index < 0 || index >= m_items.size())
{
return Item();
}
return m_items[index];
}
} // namespace Login
} // namespace Startup
} // namespace Modules

View File

@ -1,41 +0,0 @@
#pragma once
#include "item.h"
#include <QAbstractListModel>
#include <QHash>
#include <QVector>
namespace Modules
{
namespace Startup
{
namespace Login
{
class Model : public QAbstractListModel
{
Q_OBJECT
public:
enum ModelRole
{
Name = Qt::UserRole + 1,
Identicon = Qt::UserRole + 2,
ThumbnailImage = Qt::UserRole + 3,
LargeImage = Qt::UserRole + 4,
KeyUid = Qt::UserRole + 5
};
explicit Model(QObject* parent = nullptr);
QHash<int, QByteArray> roleNames() const;
virtual int rowCount(const QModelIndex&) const;
virtual QVariant data(const QModelIndex& index, int role) const;
void setItems(QVector<Item> items);
Item getItemAtIndex(int index);
private:
QVector<Item> m_items;
};
} // namespace Login
} // namespace Startup
} // namespace Modules

View File

@ -1,115 +0,0 @@
#include "module.h"
#include "../interfaces/module_login_delegate_interface.h"
#include "accounts/account.h"
#include "accounts/service_interface.h"
#include "controller.h"
#include "singleton.h"
#include "view.h"
#include <QDebug>
#include <QObject>
#include <QQmlContext>
#include <QVariant>
#include <iostream>
namespace Modules
{
namespace Startup
{
namespace Login
{
Module::Module(Modules::Startup::ModuleLoginDelegateInterface* delegate,
// keychainService
Accounts::ServiceInterface* accountsService)
: m_delegate(delegate)
{
m_controller = new Controller(this, accountsService);
m_view = new View(this);
m_moduleLoaded = false;
}
Module::~Module()
{
delete m_controller;
delete m_view;
}
void Module::extractImages(Accounts::AccountDto account, QString& thumbnailImage, QString& largeImage)
{
foreach(const Accounts::Image& img, account.images)
{
if(img.imgType == "thumbnail")
{
thumbnailImage = img.uri;
}
else if(img.imgType == "large")
{
largeImage = img.uri;
}
}
}
void Module::load()
{
Global::Singleton::instance()->engine()->rootContext()->setContextProperty("loginModule", m_view);
m_controller->init();
m_view->load();
QVector<Accounts::AccountDto> openedAccounts = m_controller->getOpenedAccounts();
if(openedAccounts.size() > 0)
{
QVector<Item> items;
foreach(const Accounts::AccountDto& acc, openedAccounts)
{
QString thumbnailImage;
QString largeImage;
Module::extractImages(acc, thumbnailImage, largeImage);
items << Item(acc.name, acc.identicon, thumbnailImage, largeImage, acc.keyUid);
}
m_view->setModelItems(items);
// set the first account as selected one
m_controller->setSelectedAccountKeyUid(items[0].getKeyUid());
Module::setSelectedAccount(items[0]);
}
}
bool Module::isLoaded()
{
return m_moduleLoaded;
}
void Module::viewDidLoad()
{
m_moduleLoaded = true;
m_delegate->loginDidLoad();
}
void Module::setSelectedAccount(Item item)
{
m_controller->setSelectedAccountKeyUid(item.getKeyUid());
m_view->setSelectedAccount(item);
}
void Module::login(QString password)
{
m_controller->login(password);
}
void Module::emitAccountLoginError(QString error)
{
m_view->emitAccountLoginError(error);
}
void Module::emitObtainingPasswordError(QString errorDescription)
{
m_view->emitObtainingPasswordError(errorDescription);
}
void Module::emitObtainingPasswordSuccess(QString password)
{
m_view->emitObtainingPasswordSuccess(password);
}
} // namespace Login
} // namespace Startup
} // namespace Modules

View File

@ -1,46 +0,0 @@
#pragma once
#include "../interfaces/module_login_delegate_interface.h"
#include "accounts/generated_account.h"
#include "accounts/service_interface.h"
#include "controller.h"
#include "interfaces/module_controller_delegate_interface.h"
#include "interfaces/module_view_delegate_interface.h"
#include "item.h"
#include "module_access_interface.h"
#include "view.h"
#include <QVariant>
namespace Modules
{
namespace Startup
{
namespace Login
{
class Module : public ModuleAccessInterface, ModuleControllerDelegateInterface, ModuleViewDelegateInterface
{
private:
Modules::Startup::ModuleLoginDelegateInterface* m_delegate;
View* m_view;
Controller* m_controller;
bool m_moduleLoaded;
public:
Module(Modules::Startup::ModuleLoginDelegateInterface* delegate,
// keychainService
Accounts::ServiceInterface* accountsService);
~Module();
void extractImages(Accounts::AccountDto account, QString& thumbnailImage, QString& largeImage);
void load() override;
bool isLoaded() override;
void viewDidLoad() override;
void setSelectedAccount(Item item) override;
void login(QString password) override;
void setupAccountError();
void emitAccountLoginError(QString error) override;
void emitObtainingPasswordError(QString errorDescription) override;
void emitObtainingPasswordSuccess(QString password) override;
};
}; // namespace Login
}; // namespace Startup
}; // namespace Modules

View File

@ -1,18 +0,0 @@
#pragma once
namespace Modules
{
namespace Startup
{
namespace Login
{
class ModuleAccessInterface
{
public:
virtual void load() = 0;
virtual bool isLoaded() = 0;
};
}; // namespace Login
}; // namespace Startup
}; // namespace Modules

View File

@ -1,44 +0,0 @@
#include "selected_account.h"
#include <QDebug>
#include <QObject>
namespace Modules
{
namespace Startup
{
namespace Login
{
SelectedAccount::SelectedAccount(QObject* parent)
: QObject(parent)
{ }
void SelectedAccount::setSelectedAccountData(Item item)
{
m_item = item;
}
QString SelectedAccount::getName()
{
return m_item.getName();
}
QString SelectedAccount::getIdenticon()
{
return m_item.getIdenticon();
}
QString SelectedAccount::getKeyUid()
{
return m_item.getKeyUid();
}
QString SelectedAccount::getThumbnailImage()
{
return m_item.getThumbnailImage();
}
QString SelectedAccount::getLargeImage()
{
return m_item.getLargeImage();
}
} // namespace Login
} // namespace Startup
} // namespace Modules

View File

@ -1,39 +0,0 @@
#pragma once
#include "item.h"
#include <QObject>
#include <QString>
namespace Modules
{
namespace Startup
{
namespace Login
{
class SelectedAccount : public QObject
{
Q_OBJECT
Q_PROPERTY(QString username READ getName CONSTANT)
Q_PROPERTY(QString identicon READ getIdenticon CONSTANT)
Q_PROPERTY(QString keyUid READ getKeyUid CONSTANT)
Q_PROPERTY(QString thumbnailImage READ getThumbnailImage CONSTANT)
Q_PROPERTY(QString largeImage READ getLargeImage CONSTANT)
public:
explicit SelectedAccount(QObject* parent = nullptr);
private:
Item m_item;
public slots:
void setSelectedAccountData(Item item);
QString getName();
QString getIdenticon();
QString getKeyUid();
QString getThumbnailImage();
QString getLargeImage();
};
} // namespace Login
} // namespace Startup
} // namespace Modules

View File

@ -1,83 +0,0 @@
#include "view.h"
#include "interfaces/module_view_delegate_interface.h"
#include "model.h"
#include "selected_account.h"
#include <QDebug>
#include <QObject>
namespace Modules
{
namespace Startup
{
namespace Login
{
View::View(ModuleViewDelegateInterface* delegate, QObject* parent)
: QObject(parent)
, m_delegate(delegate)
{
m_model = new Model();
m_selectedAccount = new SelectedAccount();
}
View::~View()
{
delete m_model;
delete m_selectedAccount;
}
void View::load()
{
m_delegate->viewDidLoad();
}
Model* View::getModel()
{
return m_model;
}
SelectedAccount* View::getSelectedAccount()
{
return m_selectedAccount;
}
void View::setSelectedAccount(Item item)
{
m_selectedAccount->setSelectedAccountData(item);
View::selectedAccountChanged();
}
void View::setSelectedAccountByIndex(int index)
{
Item item = m_model->getItemAtIndex(index);
m_delegate->setSelectedAccount(item);
}
void View::setModelItems(QVector<Item> accounts)
{
m_model->setItems(accounts);
View::modelChanged();
}
void View::login(QString password)
{
m_delegate->login(password);
}
void View::emitAccountLoginError(QString error)
{
emit View::accountLoginError(error);
}
void View::emitObtainingPasswordError(QString errorDescription)
{
emit View::obtainingPasswordError(errorDescription);
}
void View::emitObtainingPasswordSuccess(QString password)
{
emit View::obtainingPasswordSuccess(password);
}
} // namespace Login
} // namespace Startup
} // namespace Modules

View File

@ -1,53 +0,0 @@
#pragma once
#include "interfaces/module_view_delegate_interface.h"
#include "model.h"
#include "selected_account.h"
#include <QObject>
#include <QString>
#include <memory>
namespace Modules
{
namespace Startup
{
namespace Login
{
class View : public QObject
{
Q_OBJECT
Q_PROPERTY(SelectedAccount* selectedAccount READ getSelectedAccount NOTIFY selectedAccountChanged)
Q_PROPERTY(Model* accountsModel READ getModel NOTIFY modelChanged)
public:
explicit View(ModuleViewDelegateInterface* delegate, QObject* parent = nullptr);
~View();
void load();
signals:
void selectedAccountChanged();
void modelChanged();
void accountLoginError(QString error);
void obtainingPasswordError(QString errorDescription);
void obtainingPasswordSuccess(QString password);
private:
ModuleViewDelegateInterface* m_delegate;
Model* m_model;
SelectedAccount* m_selectedAccount;
public slots:
Model* getModel();
SelectedAccount* getSelectedAccount();
void setSelectedAccount(Item item);
void setSelectedAccountByIndex(int index);
void setModelItems(QVector<Item> accounts);
void login(QString password);
void emitAccountLoginError(QString error);
void emitObtainingPasswordError(QString errorDescription);
void emitObtainingPasswordSuccess(QString password);
};
} // namespace Login
} // namespace Startup
} // namespace Modules

View File

@ -1,101 +0,0 @@
#include "module.h"
#include "accounts/service_interface.h"
#include "controller.h"
#include "modules/startup/login/module.h"
#include "modules/startup/onboarding/module.h"
#include "singleton.h"
#include "view.h"
#include <QDebug>
#include <QObject>
#include <QQmlContext>
#include <QVariant>
namespace Modules
{
namespace Startup
{
Module::Module(AppControllerDelegate* delegate,
/*keychainService,*/
Accounts::ServiceInterface* accountsService)
: m_delegate(delegate)
{
m_controller = new Controller(this, accountsService);
m_view = new View(this);
// Submodules
m_onboardingModule = new Modules::Startup::Onboarding::Module(this, accountsService);
m_loginModule = new Modules::Startup::Login::Module(this, /*keychainService, */ accountsService);
}
Module::~Module()
{
delete m_controller;
delete m_view;
delete m_onboardingModule;
delete m_loginModule;
}
void Module::load()
{
Global::Singleton::instance()->engine()->rootContext()->setContextProperty("startupModule", m_view);
m_controller->init();
m_view->load();
AppState initialAppState(AppState::OnboardingState);
if(!m_controller->shouldStartWithOnboardingScreen())
{
initialAppState = AppState::LoginState;
}
m_view->setAppState(initialAppState);
m_onboardingModule->load();
m_loginModule->load();
}
void Module::checkIfModuleDidLoad()
{
if(!m_onboardingModule->isLoaded())
{
return;
}
if(!m_loginModule->isLoaded())
{
return;
}
m_delegate->startupDidLoad();
}
void Module::viewDidLoad()
{
Module::checkIfModuleDidLoad();
}
void Module::onboardingDidLoad()
{
Module::checkIfModuleDidLoad();
}
void Module::loginDidLoad()
{
Module::checkIfModuleDidLoad();
}
void Module::userLoggedIn()
{
m_delegate->userLoggedIn();
}
void Module::moveToAppState()
{
m_view->setAppState(AppState::MainAppState);
}
void Module::emitLogOut()
{
m_view->emitLogOut();
}
} // namespace Startup
} // namespace Modules

View File

@ -1,48 +0,0 @@
#pragma once
#include "accounts/service_interface.h"
#include "app_controller_delegate.h"
#include "controller.h"
#include "interfaces/module_controller_delegate_interface.h"
#include "interfaces/module_login_delegate_interface.h"
#include "interfaces/module_onboarding_delegate_interface.h"
#include "interfaces/module_view_delegate_interface.h"
#include "login/module_access_interface.h"
#include "module_access_interface.h"
#include "onboarding/module_access_interface.h"
#include "view.h"
#include <QVariant>
namespace Modules
{
namespace Startup
{
class Module : public ModuleAccessInterface,
ModuleOnboardingDelegateInterface,
ModuleLoginDelegateInterface,
ModuleControllerDelegateInterface,
ModuleViewDelegateInterface
{
private:
AppControllerDelegate* m_delegate;
View* m_view;
Controller* m_controller;
Modules::Startup::Onboarding::ModuleAccessInterface* m_onboardingModule;
Modules::Startup::Login::ModuleAccessInterface* m_loginModule;
public:
Module(AppControllerDelegate* delegate,
/*keychainService,*/ Accounts::ServiceInterface* accountsService);
~Module();
void load() override;
void checkIfModuleDidLoad();
void viewDidLoad() override;
void onboardingDidLoad();
void loginDidLoad();
void userLoggedIn() override;
void moveToAppState() override;
void emitLogOut() override;
};
}; // namespace Startup
}; // namespace Modules

View File

@ -1,15 +0,0 @@
#pragma once
namespace Modules
{
namespace Startup
{
class ModuleAccessInterface
{
public:
virtual void load() = 0;
virtual void moveToAppState() = 0;
};
}; // namespace Startup
}; // namespace Modules

View File

@ -1,80 +0,0 @@
#include "controller.h"
#include "accounts/generated_account.h"
#include "accounts/service_interface.h"
#include "interfaces/module_controller_delegate_interface.h"
#include "signals.h"
#include <QDebug>
#include <QString>
#include <QVector>
namespace Modules
{
namespace Startup
{
namespace Onboarding
{
Controller::Controller(ModuleControllerDelegateInterface* delegate,
Accounts::ServiceInterface* accountsService,
QObject* parent)
: QObject(parent)
, m_accountsService(accountsService)
, m_delegate(delegate)
{ }
void Controller::init()
{
QObject::connect(Signals::Manager::instance(), &Signals::Manager::nodeLogin, this, &Controller::onLogin);
}
void Controller::onLogin(Signals::NodeSignal signal)
{
if(!signal.error.isEmpty())
{
m_delegate->setupAccountError();
}
}
QVector<Accounts::GeneratedAccountDto> Controller::getGeneratedAccounts()
{
return m_accountsService->generatedAccounts();
}
Accounts::GeneratedAccountDto Controller::getImportedAccount()
{
return m_accountsService->getImportedAccount();
}
void Controller::setSelectedAccountByIndex(int index)
{
auto accounts = Controller::getGeneratedAccounts();
m_selectedAccountId = accounts[index].id;
}
void Controller::storeSelectedAccountAndLogin(QString password)
{
if(!m_accountsService->setupAccount(m_selectedAccountId, password))
{
m_delegate->setupAccountError();
}
}
QString Controller::validateMnemonic(QString mnemonic)
{
return m_accountsService->validateMnemonic(mnemonic);
}
void Controller::importMnemonic(QString mnemonic)
{
if(m_accountsService->importMnemonic(mnemonic))
{
m_selectedAccountId = Controller::getImportedAccount().id;
m_delegate->importAccountSuccess();
}
else
{
m_delegate->importAccountError();
}
}
} // namespace Onboarding
} // namespace Startup
} // namespace Modules

View File

@ -1,41 +0,0 @@
#pragma once
#include "accounts/generated_account.h"
#include "accounts/service_interface.h"
#include "controller_interface.h"
#include "interfaces/module_controller_delegate_interface.h"
#include "signals.h"
#include <QObject>
#include <QString>
namespace Modules
{
namespace Startup
{
namespace Onboarding
{
class Controller : public QObject, ControllerInterface
{
Q_OBJECT
public:
Controller(ModuleControllerDelegateInterface* delegate,
Accounts::ServiceInterface* accountsService,
QObject* parent = nullptr);
void init() override;
QVector<Accounts::GeneratedAccountDto> getGeneratedAccounts() override;
Accounts::GeneratedAccountDto getImportedAccount() override;
void setSelectedAccountByIndex(int index) override;
void storeSelectedAccountAndLogin(QString password) override;
QString validateMnemonic(QString mnemonic) override;
void importMnemonic(QString mnemonic) override;
void onLogin(Signals::NodeSignal signal);
private:
Accounts::ServiceInterface* m_accountsService;
ModuleControllerDelegateInterface* m_delegate;
QString m_selectedAccountId;
};
} // namespace Onboarding
} // namespace Startup
} // namespace Modules

View File

@ -1,33 +0,0 @@
#pragma once
#include "accounts/generated_account.h"
namespace Modules
{
namespace Startup
{
namespace Onboarding
{
// Abstract class for any input/interaction with this module.
class ControllerInterface
{
public:
virtual void init() = 0;
virtual QVector<Accounts::GeneratedAccountDto> getGeneratedAccounts() = 0;
virtual void setSelectedAccountByIndex(int index) = 0;
virtual void storeSelectedAccountAndLogin(QString password) = 0;
virtual Accounts::GeneratedAccountDto getImportedAccount() = 0;
virtual QString validateMnemonic(QString mnemonic) = 0;
virtual void importMnemonic(QString mnemonic) = 0;
};
} // namespace Onboarding
} // namespace Startup
} // namespace Modules

View File

@ -1,20 +0,0 @@
#pragma once
namespace Modules
{
namespace Startup
{
namespace Onboarding
{
class ModuleControllerDelegateInterface
{
public:
virtual void setupAccountError() = 0;
virtual void importAccountError() = 0;
virtual void importAccountSuccess() = 0;
};
}; // namespace Onboarding
}; // namespace Startup
}; // namespace Modules

View File

@ -1,28 +0,0 @@
#pragma once
#include "accounts/generated_account.h"
#include <QString>
namespace Modules
{
namespace Startup
{
namespace Onboarding
{
class ModuleViewDelegateInterface
{
public:
virtual void viewDidLoad() = 0;
virtual void setSelectedAccountByIndex(int index) = 0;
virtual void storeSelectedAccountAndLogin(QString password) = 0;
virtual Accounts::GeneratedAccountDto getImportedAccount() = 0;
virtual QString validateMnemonic(QString mnemonic) = 0;
virtual void importMnemonic(QString mnemonic) = 0;
};
}; // namespace Onboarding
}; // namespace Startup
}; // namespace Modules

View File

@ -1,39 +0,0 @@
#include "item.h"
#include <QString>
namespace Modules
{
namespace Startup
{
namespace Onboarding
{
Item::Item(QString id, QString alias, QString identicon, QString address, QString keyUid)
: m_id(id)
, m_alias(alias)
, m_identicon(identicon)
, m_address(address)
, m_keyUid(keyUid)
{ }
QString Item::getId()
{
return m_id;
}
QString Item::getAlias()
{
return m_alias;
}
QString Item::getIdenticon()
{
return m_identicon;
}
QString Item::getAddress()
{
return m_address;
}
QString Item::getKeyUid()
{
return m_keyUid;
}
} // namespace Onboarding
} // namespace Startup
} // namespace Modules

View File

@ -1,30 +0,0 @@
#pragma once
#include <QString>
namespace Modules
{
namespace Startup
{
namespace Onboarding
{
class Item
{
private:
QString m_id;
QString m_alias;
QString m_identicon;
QString m_address;
QString m_keyUid;
public:
Item(QString id, QString alias, QString identicon, QString address, QString keyUid);
QString getId();
QString getAlias();
QString getIdenticon();
QString getAddress();
QString getKeyUid();
};
} // namespace Onboarding
} // namespace Startup
} // namespace Modules

View File

@ -1,66 +0,0 @@
#include "model.h"
#include <QAbstractListModel>
#include <QDebug>
namespace Modules
{
namespace Startup
{
namespace Onboarding
{
Model::Model(QObject* parent)
: QAbstractListModel(parent)
{ }
QHash<int, QByteArray> Model::roleNames() const
{
QHash<int, QByteArray> roles;
roles[Id] = "accountId";
roles[Alias] = "username";
roles[Identicon] = "identicon";
roles[Address] = "address";
roles[KeyUid] = "keyUid";
return roles;
}
int Model::rowCount(const QModelIndex& parent = QModelIndex()) const
{
return m_items.size();
}
QVariant Model::data(const QModelIndex& index, int role) const
{
if(!index.isValid())
{
return QVariant();
}
if(index.row() < 0 || index.row() > m_items.size())
{
return QVariant();
}
Item item = m_items[index.row()];
switch(role)
{
case Id: return QVariant(item.getId());
case Alias: return QVariant(item.getAlias());
case Identicon: return QVariant(item.getIdenticon());
case Address: return QVariant(item.getAddress());
case KeyUid: return QVariant(item.getKeyUid());
}
return QVariant();
}
void Model::setItems(QVector<Item> items)
{
beginResetModel();
m_items = items;
endResetModel();
}
} // namespace Onboarding
} // namespace Startup
} // namespace Modules

View File

@ -1,40 +0,0 @@
#pragma once
#include "item.h"
#include <QAbstractListModel>
#include <QHash>
#include <QVector>
namespace Modules
{
namespace Startup
{
namespace Onboarding
{
class Model : public QAbstractListModel
{
Q_OBJECT
public:
enum ModelRole
{
Id = Qt::UserRole + 1,
Alias = Qt::UserRole + 2,
Identicon = Qt::UserRole + 3,
Address = Qt::UserRole + 4,
KeyUid = Qt::UserRole + 5
};
explicit Model(QObject* parent = nullptr);
QHash<int, QByteArray> roleNames() const;
virtual int rowCount(const QModelIndex&) const;
virtual QVariant data(const QModelIndex& index, int role) const;
void setItems(QVector<Item> items);
private:
QVector<Item> m_items;
};
} // namespace Onboarding
} // namespace Startup
} // namespace Modules

View File

@ -1,102 +0,0 @@
#include "module.h"
#include "../interfaces/module_onboarding_delegate_interface.h"
#include "accounts/generated_account.h"
#include "accounts/service_interface.h"
#include "controller.h"
#include "singleton.h"
#include "view.h"
#include <QDebug>
#include <QObject>
#include <QQmlContext>
#include <QVariant>
#include <iostream>
namespace Modules
{
namespace Startup
{
namespace Onboarding
{
Module::Module(Modules::Startup::ModuleOnboardingDelegateInterface* delegate,
Accounts::ServiceInterface* accountsService)
: m_delegate(delegate)
{
m_controller = new Controller(this, accountsService);
m_view = new View(this);
m_moduleLoaded = false;
}
Module::~Module()
{
delete m_controller;
delete m_view;
}
void Module::load()
{
Global::Singleton::instance()->engine()->rootContext()->setContextProperty("onboardingModule", m_view);
m_controller->init();
m_view->load();
QVector<Accounts::GeneratedAccountDto> gAcc = m_controller->getGeneratedAccounts();
QVector<Item> accounts;
foreach(const Accounts::GeneratedAccountDto& acc, gAcc)
{
accounts << Item(acc.id, acc.alias, acc.identicon, acc.address, acc.keyUid);
}
m_view->setAccountList(accounts);
}
bool Module::isLoaded()
{
return m_moduleLoaded;
}
void Module::viewDidLoad()
{
m_moduleLoaded = true;
m_delegate->onboardingDidLoad();
}
void Module::setSelectedAccountByIndex(int index)
{
m_controller->setSelectedAccountByIndex(index);
}
void Module::storeSelectedAccountAndLogin(QString password)
{
m_controller->storeSelectedAccountAndLogin(password);
}
void Module::setupAccountError()
{
m_view->setupAccountError();
}
Accounts::GeneratedAccountDto Module::getImportedAccount()
{
return m_controller->getImportedAccount();
}
QString Module::validateMnemonic(QString mnemonic)
{
return m_controller->validateMnemonic(mnemonic);
}
void Module::importMnemonic(QString mnemonic)
{
m_controller->importMnemonic(mnemonic);
}
void Module::importAccountError()
{
m_view->importAccountError();
}
void Module::importAccountSuccess()
{
m_view->importAccountSuccess();
}
} // namespace Onboarding
} // namespace Startup
} // namespace Modules

View File

@ -1,44 +0,0 @@
#pragma once
#include "../interfaces/module_onboarding_delegate_interface.h"
#include "accounts/generated_account.h"
#include "accounts/service_interface.h"
#include "controller.h"
#include "interfaces/module_controller_delegate_interface.h"
#include "interfaces/module_view_delegate_interface.h"
#include "module_access_interface.h"
#include "view.h"
#include <QVariant>
namespace Modules
{
namespace Startup
{
namespace Onboarding
{
class Module : public ModuleAccessInterface, ModuleControllerDelegateInterface, ModuleViewDelegateInterface
{
private:
Modules::Startup::ModuleOnboardingDelegateInterface* m_delegate;
View* m_view;
Controller* m_controller;
bool m_moduleLoaded;
public:
Module(Modules::Startup::ModuleOnboardingDelegateInterface* delegate, Accounts::ServiceInterface* accountsService);
~Module();
void load() override;
bool isLoaded() override;
void viewDidLoad() override;
void setSelectedAccountByIndex(int index) override;
void storeSelectedAccountAndLogin(QString password) override;
void setupAccountError() override;
Accounts::GeneratedAccountDto getImportedAccount() override;
QString validateMnemonic(QString mnemonic) override;
void importMnemonic(QString mnemonic) override;
void importAccountError() override;
void importAccountSuccess() override;
};
}; // namespace Onboarding
}; // namespace Startup
}; // namespace Modules

View File

@ -1,18 +0,0 @@
#pragma once
namespace Modules
{
namespace Startup
{
namespace Onboarding
{
class ModuleAccessInterface
{
public:
virtual void load() = 0;
virtual bool isLoaded() = 0;
};
}; // namespace Onboarding
}; // namespace Startup
}; // namespace Modules

View File

@ -1,93 +0,0 @@
#include "view.h"
#include "interfaces/module_view_delegate_interface.h"
#include <QDebug>
#include <QObject>
namespace Modules
{
namespace Startup
{
namespace Onboarding
{
View::View(ModuleViewDelegateInterface* delegate, QObject* parent)
: QObject(parent)
, m_delegate(delegate)
{
m_model = new Model();
}
View::~View()
{
delete m_model;
}
void View::load()
{
m_delegate->viewDidLoad();
}
Model* View::getModel()
{
return m_model;
}
void View::setAccountList(QVector<Item> accounts)
{
m_model->setItems(accounts);
View::modelChanged();
}
QString View::getImportedAccountIdenticon()
{
return m_delegate->getImportedAccount().identicon;
}
QString View::getImportedAccountAlias()
{
return m_delegate->getImportedAccount().alias;
}
QString View::getImportedAccountAddress()
{
return m_delegate->getImportedAccount().address;
}
void View::setSelectedAccountByIndex(int index)
{
m_delegate->setSelectedAccountByIndex(index);
}
void View::storeSelectedAccountAndLogin(QString password)
{
m_delegate->storeSelectedAccountAndLogin(password);
}
void View::setupAccountError()
{
View::accountSetupError();
}
QString View::validateMnemonic(QString mnemonic)
{
return m_delegate->validateMnemonic(mnemonic);
}
void View::importMnemonic(QString mnemonic)
{
m_delegate->importMnemonic(mnemonic);
}
void View::importAccountError()
{
// In QML we can connect to this signal and notify a user
// before refactoring we didn't have this signal
View::accountImportError();
}
void View::importAccountSuccess()
{
View::importedAccountChanged();
}
} // namespace Onboarding
} // namespace Startup
} // namespace Modules

View File

@ -1,55 +0,0 @@
#pragma once
#include "interfaces/module_view_delegate_interface.h"
#include "model.h"
#include <QObject>
#include <QString>
#include <memory>
namespace Modules
{
namespace Startup
{
namespace Onboarding
{
class View : public QObject
{
Q_OBJECT
Q_PROPERTY(Model* accountsModel READ getModel NOTIFY modelChanged)
Q_PROPERTY(QString importedAccountIdenticon READ getImportedAccountIdenticon NOTIFY importedAccountChanged)
Q_PROPERTY(QString importedAccountAlias READ getImportedAccountAlias NOTIFY importedAccountChanged)
Q_PROPERTY(QString importedAccountAddress READ getImportedAccountAddress NOTIFY importedAccountChanged)
public:
explicit View(ModuleViewDelegateInterface* delegate, QObject* parent = nullptr);
~View();
void load();
signals:
void modelChanged();
void importedAccountChanged();
void accountSetupError();
void accountImportError();
private:
ModuleViewDelegateInterface* m_delegate;
Model* m_model;
public slots:
Model* getModel();
void setAccountList(QVector<Item> accounts);
QString getImportedAccountIdenticon();
QString getImportedAccountAlias();
QString getImportedAccountAddress();
void setSelectedAccountByIndex(int index);
void storeSelectedAccountAndLogin(QString password);
QString validateMnemonic(QString mnemonic);
void importMnemonic(QString mnemonic);
void importAccountError();
void setupAccountError();
void importAccountSuccess();
};
} // namespace Onboarding
} // namespace Startup
} // namespace Modules

View File

@ -1,44 +0,0 @@
#include "view.h"
#include "interfaces/module_view_delegate_interface.h"
#include <QObject>
namespace Modules
{
namespace Startup
{
View::View(ModuleViewDelegateInterface* delegate, QObject* parent)
: QObject(parent)
, m_appState(AppState::OnboardingState)
, m_delegate(delegate)
{ }
void View::load()
{
// In some point, here, we will setup some exposed main module related things.
m_delegate->viewDidLoad();
}
int View::getAppState()
{
return static_cast<int>(m_appState);
}
void View::setAppState(AppState state)
{
if(m_appState == state)
{
return;
}
m_appState = state;
appStateChanged(static_cast<int>(m_appState));
}
void View::emitLogOut()
{
logOut();
}
} // namespace Startup
} // namespace Modules

View File

@ -1,41 +0,0 @@
#pragma once
#include "interfaces/module_view_delegate_interface.h"
#include <QObject>
namespace Modules
{
namespace Startup
{
enum AppState
{
OnboardingState = 0,
LoginState = 1,
MainAppState = 2
// TODO: is Pending
};
class View : public QObject
{
Q_OBJECT
Q_PROPERTY(int appState READ getAppState NOTIFY appStateChanged)
public:
explicit View(ModuleViewDelegateInterface* delegate, QObject* parent = nullptr);
void emitLogOut();
void setAppState(AppState state);
void load();
signals:
void appStateChanged(int state);
void logOut();
private:
ModuleViewDelegateInterface* m_delegate;
AppState m_appState;
public slots:
int getAppState();
};
} // namespace Startup
} // namespace Modules

View File

@ -1,36 +0,0 @@
add_library(app_service
constants.cpp
service/accounts/dto/account.cpp
service/accounts/dto/generated_account.cpp
service/accounts/service.cpp
service/wallet_accounts/dto/wallet_account.cpp
service/wallet_accounts/service.cpp
)
target_include_directories(app_service
PUBLIC
include
)
# default token is a free-tier token with limited capabilities and usage
# limits; setup your own infura key with
# cmake -DINFURA_KEY=infura_key_goes_here ..
if( "${INFURA_KEY}" STREQUAL "")
message("-- Using default Infura key")
file (STRINGS "../../resources/infura_key" INFURA_KEY)
else()
message("-- Using custom Infura key")
endif()
# Build constants
target_compile_definitions(app_service
PRIVATE
INFURA_KEY="${INFURA_KEY}"
)
target_link_libraries(app_service
PRIVATE
Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Quick
backend
)

View File

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

View File

@ -1,37 +0,0 @@
#pragma once
#include <QJsonValue>
#include <QString>
#include <QVector>
namespace Accounts
{
class Image
{
public:
QString keyUid;
QString imgType;
QString uri;
int width;
int height;
int fileSize;
int resizeTarget;
};
class AccountDto
{
public:
QString name;
long timestamp;
QString identicon;
QString keycardPairing;
QString keyUid;
QVector<Image> images;
bool isValid() const;
};
Image toImage(const QJsonValue& jsonObj);
AccountDto toAccountDto(const QJsonValue& jsonObj);
} // namespace Accounts

View File

@ -1,47 +0,0 @@
#pragma once
#include <QJsonDocument>
#include <QString>
namespace Accounts
{
class DerivedAccountDetails
{
public:
QString publicKey;
QString address;
QString derivationPath;
};
class DerivedAccounts
{
public:
DerivedAccountDetails whisper;
DerivedAccountDetails walletRoot;
DerivedAccountDetails defaultWallet;
DerivedAccountDetails eip1581;
};
class GeneratedAccountDto
{
public:
QString id;
QString publicKey;
QString address;
QString keyUid;
QString mnemonic;
DerivedAccounts derivedAccounts;
// The following two are set additionally.
QString alias;
QString identicon;
bool isValid() const;
};
DerivedAccountDetails toDerivedAccountDetails(const QJsonValue& jsonObj, const QString& derivationPath);
DerivedAccounts toDerivedAccounts(const QJsonObject& jsonObj);
GeneratedAccountDto toGeneratedAccountDto(const QJsonValue& jsonObj);
} // namespace Accounts

View File

@ -1,66 +0,0 @@
#pragma once
#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 = false;
AccountDto m_loggedInAccount;
GeneratedAccountDto m_importedAccount;
public:
void init() override;
QVector<AccountDto> openedAccounts() override;
QVector<GeneratedAccountDto> generatedAccounts() override;
bool setupAccount(const QString& accountId, const QString& password) override;
AccountDto getLoggedInAccount() override;
GeneratedAccountDto getImportedAccount() override;
bool isFirstTimeAccountLogin() override;
QString validateMnemonic(const QString& mnemonic) override;
bool importMnemonic(const QString& mnemonic) override;
QString login(const AccountDto& account, const QString& password) override;
void clear() override;
QString generateAlias(const QString& publicKey) override;
QString generateIdenticon(const QString& publicKey) override;
bool verifyAccountPassword(const QString& account, const QString& password) override;
DerivedAccounts
storeDerivedAccounts(const QString& accountId, const QString& hashedPassword, const QVector<QString>& paths);
QJsonObject getAccountDataForAccountId(const QString& accountId);
QJsonArray getSubaccountDataForAccountId(const QString& accountId);
QJsonObject getAccountSettings(const QString& accountId, const QString& installationId);
AccountDto saveAccountAndLogin(const QString& hashedPassword,
const QJsonObject& account,
const QJsonArray& subaccounts,
const QJsonObject& settings,
const QJsonObject& config);
};
} // namespace Accounts

View File

@ -1,43 +0,0 @@
#pragma once
#include "../app_service.h"
#include "account.h"
#include "generated_account.h"
#include <QJsonValue>
#include <QString>
#include <QVector>
namespace Accounts
{
class ServiceInterface : public AppService
{
public:
virtual QVector<AccountDto> openedAccounts() = 0;
virtual QVector<GeneratedAccountDto> generatedAccounts() = 0;
virtual bool setupAccount(const QString& accountId, const QString& password) = 0;
virtual AccountDto getLoggedInAccount() = 0;
virtual GeneratedAccountDto getImportedAccount() = 0;
virtual bool isFirstTimeAccountLogin() = 0;
virtual QString validateMnemonic(const QString& mnemonic) = 0;
virtual bool importMnemonic(const QString& mnemonic) = 0;
virtual QString login(const AccountDto& account, const QString& password) = 0;
virtual void clear() = 0;
virtual QString generateAlias(const QString& publicKey) = 0;
virtual QString generateIdenticon(const QString& publicKey) = 0;
virtual bool verifyAccountPassword(const QString& account, const QString& password) = 0;
};
} // namespace Accounts

View File

@ -1,8 +0,0 @@
#pragma once
class AppService
{
public:
virtual void init() = 0;
virtual ~AppService() = default;
};

View File

@ -1,38 +0,0 @@
#pragma once
#include <QString>
namespace Constants
{
namespace Fleet
{
const QString Prod = "eth.prod";
const QString Staging = "eth.staging";
const QString Test = "eth.test";
const QString WakuV2Prod = "wakuv2.prod";
const QString WakuV2Test = "wakuv2.test";
const QString GoWakuTest = "go-waku.test";
}; // namespace Fleet
namespace FleetNodes
{
const QString Bootnodes = "boot";
const QString Mailservers = "mail";
const QString Rendezvous = "rendezvous";
const QString Whisper = "whisper";
const QString Waku = "waku";
const QString LibP2P = "libp2p";
const QString Websocket = "websocket";
} // namespace FleetNodes
const QString DefaultNetworkName = "mainnet_rpc";
//const DEFAULT_NETWORKS_IDS* = @["mainnet_rpc", "testnet_rpc", "rinkeby_rpc", "goerli_rpc", "xdai_rpc", "poa_rpc" ]
const QString DataDir = "/data";
const QString Keystore = "/data/keystore";
QString applicationPath(const QString& path = "");
QString tmpPath(const QString& path = "");
QString cachePath(const QString& path = "");
} // namespace Constants

View File

@ -1,49 +0,0 @@
#include <QString>
#include <array>
const std::array phrases{
"area", "army", "atom", "aunt", "babe", "baby", "back", "bail", "bait", "bake", "ball", "band", "bank", "barn",
"base", "bass", "bath", "bead", "beak", "beam", "bean", "bear", "beat", "beef", "beer", "beet", "bell", "belt",
"bend", "bike", "bill", "bird", "bite", "blow", "blue", "boar", "boat", "body", "bolt", "bomb", "bone", "book",
"boot", "bore", "boss", "bowl", "brow", "bulb", "bull", "burn", "bush", "bust", "cafe", "cake", "calf", "call",
"calm", "camp", "cane", "cape", "card", "care", "carp", "cart", "case", "cash", "cast", "cave", "cell", "cent",
"chap", "chef", "chin", "chip", "chop", "chub", "chug", "city", "clam", "clef", "clip", "club", "clue", "coal",
"coat", "code", "coil", "coin", "coke", "cold", "colt", "comb", "cone", "cook", "cope", "copy", "cord", "cork",
"corn", "cost", "crab", "craw", "crew", "crib", "crop", "crow", "curl", "cyst", "dame", "dare", "dark", "dart",
"dash", "data", "date", "dead", "deal", "dear", "debt", "deck", "deep", "deer", "desk", "dhow", "diet", "dill",
"dime", "dirt", "dish", "disk", "dock", "doll", "door", "dory", "drag", "draw", "drop", "drug", "drum", "duck",
"dump", "dust", "duty", "ease", "east", "eave", "eddy", "edge", "envy", "epee", "exam", "exit", "face", "fact",
"fail", "fall", "fame", "fang", "farm", "fawn", "fear", "feed", "feel", "feet", "file", "fill", "film", "find",
"fine", "fire", "fish", "flag", "flat", "flax", "flow", "foam", "fold", "font", "food", "foot", "fork", "form",
"fort", "fowl", "frog", "fuel", "full", "gain", "gale", "galn", "game", "garb", "gate", "gear", "gene", "gift",
"girl", "give", "glad", "glen", "glue", "glut", "goal", "goat", "gold", "golf", "gong", "good", "gown", "grab",
"gram", "gray", "grey", "grip", "grit", "gyro", "hail", "hair", "half", "hall", "hand", "hang", "harm", "harp",
"hate", "hawk", "head", "heat", "heel", "hell", "helo", "help", "hemp", "herb", "hide", "high", "hill", "hire",
"hive", "hold", "hole", "home", "hood", "hoof", "hook", "hope", "hops", "horn", "hose", "host", "hour", "hunt",
"hurt", "icon", "idea", "inch", "iris", "iron", "item", "jail", "jeep", "jeff", "joey", "join", "joke", "judo",
"jump", "junk", "jury", "jute", "kale", "keep", "kick", "kill", "kilt", "kind", "king", "kiss", "kite", "knee",
"knot", "lace", "lack", "lady", "lake", "lamb", "lamp", "land", "lark", "lava", "lawn", "lead", "leaf", "leek",
"lier", "life", "lift", "lily", "limo", "line", "link", "lion", "lisa", "list", "load", "loaf", "loan", "lock",
"loft", "long", "look", "loss", "lout", "love", "luck", "lung", "lute", "lynx", "lyre", "maid", "mail", "main",
"make", "male", "mall", "manx", "many", "mare", "mark", "mask", "mass", "mate", "math", "meal", "meat", "meet",
"menu", "mess", "mice", "midi", "mile", "milk", "mime", "mind", "mine", "mini", "mint", "miss", "mist", "moat",
"mode", "mole", "mood", "moon", "most", "moth", "move", "mule", "mutt", "nail", "name", "neat", "neck", "need",
"neon", "nest", "news", "node", "nose", "note", "oboe", "okra", "open", "oval", "oven", "oxen", "pace", "pack",
"page", "pail", "pain", "pair", "palm", "pard", "park", "part", "pass", "past", "path", "peak", "pear", "peen",
"peer", "pelt", "perp", "pest", "pick", "pier", "pike", "pile", "pimp", "pine", "ping", "pink", "pint", "pipe",
"piss", "pith", "plan", "play", "plot", "plow", "poem", "poet", "pole", "polo", "pond", "pony", "poof", "pool",
"port", "post", "prow", "pull", "puma", "pump", "pupa", "push", "quit", "race", "rack", "raft", "rage", "rail",
"rain", "rake", "rank", "rate", "read", "rear", "reef", "rent", "rest", "rice", "rich", "ride", "ring", "rise",
"risk", "road", "robe", "rock", "role", "roll", "roof", "room", "root", "rope", "rose", "ruin", "rule", "rush",
"ruth", "sack", "safe", "sage", "sail", "sale", "salt", "sand", "sari", "sash", "save", "scow", "seal", "seat",
"seed", "self", "sell", "shed", "shin", "ship", "shoe", "shop", "shot", "show", "sick", "side", "sign", "silk",
"sill", "silo", "sing", "sink", "site", "size", "skin", "sled", "slip", "smog", "snob", "snow", "soap", "sock",
"soda", "sofa", "soft", "soil", "song", "soot", "sort", "soup", "spot", "spur", "stag", "star", "stay", "stem",
"step", "stew", "stop", "stud", "suck", "suit", "swan", "swim", "tail", "tale", "talk", "tank", "tard", "task",
"taxi", "team", "tear", "teen", "tell", "temp", "tent", "term", "test", "text", "thaw", "tile", "till", "time",
"tire", "toad", "toga", "togs", "tone", "tool", "toot", "tote", "tour", "town", "tram", "tray", "tree", "trim",
"trip", "tuba", "tube", "tuna", "tune", "turn", "tutu", "twig", "type", "unit", "user", "vane", "vase", "vast",
"veal", "veil", "vein", "vest", "vibe", "view", "vise", "wait", "wake", "walk", "wall", "wash", "wasp", "wave",
"wear", "weed", "week", "well", "west", "whip", "wife", "will", "wind", "wine", "wing", "wire", "wish", "wolf",
"wood", "wool", "word", "work", "worm", "wrap", "wren", "yard", "yarn", "yawl", "year", "yoga", "yoke", "yurt",
"zinc", "zone"};

View File

@ -1,32 +0,0 @@
#pragma once
#include <QString>
#include <QMap>
#include <QObject>
#include "service_interface.h"
#include "wallet_account.h"
namespace Wallets
{
class Service : public QObject, public ServiceInterface
{
private:
void fetchAccounts();
void refreshAccounts();
QMap<QString, WalletAccountDto> m_walletAccounts;
public:
void init() override;
QList<WalletAccountDto> getWalletAccounts() override;
QString generateNewAccount(const QString& password, const QString& accountName, const QString& color) override;
QString addAccountsFromPrivateKey(const QString& privateKey, const QString& password, const QString& accountName, const QString& color) override;
QString addAccountsFromSeed(const QString& seedPhrase, const QString& password, const QString& accountName, const QString& color) override;
QString addWatchOnlyAccount(const QString& address, const QString& accountName , const QString& color) override;
void deleteAccount(const QString& address) override;
};
} // namespace Wallets

View File

@ -1,24 +0,0 @@
#pragma once
#include "../app_service.h"
#include "wallet_account.h"
#include <memory>
#include <QJsonValue>
#include <QList>
namespace Wallets
{
class ServiceInterface : public AppService
{
public:
virtual QList<WalletAccountDto> getWalletAccounts() = 0;
virtual QString generateNewAccount(const QString& password, const QString& accountName, const QString& color) = 0;
virtual QString addAccountsFromPrivateKey(const QString& privateKey, const QString& password, const QString& accountName, const QString& color) = 0;
virtual QString addAccountsFromSeed(const QString& seedPhrase, const QString& password, const QString& accountName, const QString& color) = 0;
virtual QString addWatchOnlyAccount(const QString& address, const QString& accountName , const QString& color) = 0;
virtual void deleteAccount(const QString& address) = 0;
};
} // namespace Wallets

View File

@ -1,27 +0,0 @@
#pragma once
#include "wallet_token.h"
#include <QJsonValue>
#include <QString>
#include <QVector>
namespace Wallets
{
class WalletAccountDto
{
public:
QString name;
QString address;
QString path;
QString color;
QString publicKey;
QString walletType;
bool isWallet;
bool isChat;
QVector<WalletTokenDto> tokens;
};
WalletAccountDto toWalletAccountDto(const QJsonValue& jsonObj);
} // namespace Wallets

View File

@ -1,23 +0,0 @@
#pragma once
#include <QJsonValue>
#include <QString>
#include <QVector>
namespace Wallets
{
class WalletTokenDto
{
public:
QString name;
QString address;
QString symbol;
int decimals;
bool hasIcon;
QString color;
bool isCustom;
float balance;
float currencyBalance;
};
} // namespace Wallets

View File

@ -1,44 +0,0 @@
#include "accounts/account.h"
#include "backend/accounts.h"
#include <QJsonArray>
#include <QJsonObject>
#include <QJsonValue>
#include <QStringList>
bool Accounts::AccountDto::isValid() const
{
return name.length() > 0 && keyUid.length() > 0;
}
Accounts::Image Accounts::toImage(const QJsonValue& jsonObj)
{
auto result = Accounts::Image();
result.keyUid = jsonObj["keyUid"].toString();
result.imgType = jsonObj["type"].toString();
result.uri = jsonObj["uri"].toString();
result.width = jsonObj["width"].toInt();
result.height = jsonObj["height"].toInt();
result.fileSize = jsonObj["fileSize"].toInt();
result.resizeTarget = jsonObj["resizeTarget"].toInt();
return result;
}
Accounts::AccountDto Accounts::toAccountDto(const QJsonValue& jsonObj)
{
auto result = Accounts::AccountDto();
result.name = jsonObj["name"].toString();
result.timestamp = jsonObj["timestamp"].toInt();
result.identicon = jsonObj["identicon"].toString();
result.keycardPairing = jsonObj["keycard-pairing"].toString();
result.keyUid = jsonObj["key-uid"].toString();
foreach(const QJsonValue& value, jsonObj["images"].toArray())
{
result.images << Accounts::toImage(value);
}
return result;
}

View File

@ -1,71 +0,0 @@
#include "accounts/generated_account.h"
#include "backend/accounts.h"
#include <QDebug>
#include <QJsonArray>
#include <QJsonObject>
#include <QJsonValue>
#include <QStringList>
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,
const QString& derivationPath)
{
// Mapping this DTO is not strightforward since only keys are used for id. We
// handle it a bit different.
auto result = Accounts::DerivedAccountDetails();
result.derivationPath = derivationPath;
result.publicKey = jsonObj["publicKey"].toString();
result.address = jsonObj["address"].toString();
return result;
}
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::PathWhisper)
{
result.whisper = Accounts::toDerivedAccountDetails(derivedObj, derivationPath);
}
else if(derivationPath == Backend::Accounts::PathWalletRoot)
{
result.walletRoot = Accounts::toDerivedAccountDetails(derivedObj, derivationPath);
}
else if(derivationPath == Backend::Accounts::PathDefaultWallet)
{
result.defaultWallet = Accounts::toDerivedAccountDetails(derivedObj, derivationPath);
}
else if(derivationPath == Backend::Accounts::PathEIP1581)
{
result.eip1581 = Accounts::toDerivedAccountDetails(derivedObj, derivationPath);
}
}
return result;
}
Accounts::GeneratedAccountDto Accounts::toGeneratedAccountDto(const QJsonValue& jsonObj)
{
auto result = GeneratedAccountDto();
result.id = jsonObj["id"].toString();
result.address = jsonObj["address"].toString();
result.keyUid = jsonObj["keyUid"].toString();
result.mnemonic = jsonObj["mnemonic"].toString();
result.publicKey = jsonObj["publicKey"].toString();
if(!jsonObj["derived"].isUndefined())
{
result.derivedAccounts = Accounts::toDerivedAccounts(jsonObj["derived"].toObject());
}
return result;
}

View File

@ -1,407 +0,0 @@
#include "accounts/service.h"
#include "accounts/account.h"
#include "accounts/generated_account.h"
#include "accounts/service_interface.h"
#include "app_service.h"
#include "backend/accounts.h"
#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
{
void Service::init()
{
auto response = Backend::Accounts::generateAddresses(Paths);
foreach(QJsonValue generatedAddressJson, response.m_result)
{
auto gAcc = toGeneratedAccountDto(generatedAddressJson);
gAcc.alias = generateAlias(gAcc.derivedAccounts.whisper.publicKey);
gAcc.identicon = generateIdenticon(gAcc.derivedAccounts.whisper.publicKey);
m_generatedAccounts << gAcc;
}
}
QVector<AccountDto> Service::openedAccounts()
{
// TODO: if there's an exception, should we return an empty result? or should we look into using
// std::expected or std::optional or boost outcome https://www.boost.org/doc/libs/1_75_0/libs/outcome/doc/html/index.html
try
{
auto response = Backend::Accounts::openAccounts(Constants::applicationPath(Constants::DataDir));
QJsonArray multiAccounts = response.m_result;
QVector<AccountDto> result;
foreach(const QJsonValue& value, multiAccounts)
{
result << toAccountDto(value);
}
return result;
}
catch(Backend::RpcException& e)
{
qWarning() << "error: methodName=openedAccounts, errDescription=" << e.what();
return {};
}
}
QVector<GeneratedAccountDto> Service::generatedAccounts()
{
if(m_generatedAccounts.length() == 0)
{
qWarning() << "There was some issue initiating account service";
return {};
}
return m_generatedAccounts;
}
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
{
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));
const QString hashedPassword(Backend::Utils::hashString(password));
Service::storeDerivedAccounts(accountId, hashedPassword, Paths);
m_loggedInAccount =
Service::saveAccountAndLogin(hashedPassword, accountData, subAccountData, settings, nodeConfig);
return Service::getLoggedInAccount().isValid();
}
catch(std::exception& e)
{
qWarning() << "error: methodName=setupAccount, errDescription=" << e.what();
return false;
}
}
AccountDto Service::getLoggedInAccount()
{
return m_loggedInAccount;
}
GeneratedAccountDto Service::getImportedAccount()
{
return m_importedAccount;
}
bool Service::isFirstTimeAccountLogin()
{
return m_isFirstTimeAccountLogin;
}
QString Service::validateMnemonic(const QString& mnemonic)
{
// TODO:
return "";
}
bool Service::importMnemonic(const QString& mnemonic)
{
// TODO:
return false;
}
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
{
QString hashedPassword(Backend::Utils::hashString(password));
QString thumbnailImage;
QString largeImage;
foreach(const Accounts::Image& img, account.images)
{
if(img.imgType == "thumbnail")
{
thumbnailImage = img.uri;
}
else if(img.imgType == "large")
{
largeImage = img.uri;
}
}
auto response = Backend::Accounts::login(
account.name, account.keyUid, hashedPassword, account.identicon, thumbnailImage, largeImage);
// TODO: check response for errors
qDebug() << "Account logged in";
m_loggedInAccount = account;
return "";
}
catch(std::exception& e)
{
qWarning() << "error: methodName=login, errDescription=" << e.what();
return e.what();
}
}
void Service::clear()
{
m_generatedAccounts.clear();
m_loggedInAccount = Accounts::AccountDto();
m_importedAccount = Accounts::GeneratedAccountDto();
m_isFirstTimeAccountLogin = false;
}
QString Service::generateAlias(const QString& publicKey)
{
return Backend::Accounts::generateAlias(publicKey).m_result;
}
QString Service::generateIdenticon(const QString& publicKey)
{
return Backend::Accounts::generateIdenticon(publicKey).m_result;
}
bool Service::verifyAccountPassword(const QString& account, const QString& password)
{
// TODO:
return false;
}
DerivedAccounts
Service::storeDerivedAccounts(const QString& accountId, const QString& hashedPassword, const QVector<QString>& paths)
{
try
{
auto response = Backend::Accounts::storeDerivedAccounts(accountId, hashedPassword, paths);
return toDerivedAccounts(response.m_result);
}
catch(Backend::RpcException& e)
{
qWarning() << e.what();
return {}; // TODO: should it return empty?
}
}
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
{
auto response = Backend::Accounts::saveAccountAndLogin(hashedPassword, account, subaccounts, settings, config);
m_isFirstTimeAccountLogin = true;
return toAccountDto(account);
}
catch(std::exception& e)
{
qWarning() << "error: methodName=saveAccountAndLogin, errDescription=" << e.what();
return {};
}
}
QJsonObject Service::getAccountDataForAccountId(const QString& accountId)
{
foreach(const GeneratedAccountDto& acc, m_generatedAccounts)
{
if(acc.id == accountId)
{
return prepareAccountJsonObject(acc);
}
}
if(m_importedAccount.isValid())
{
if(m_importedAccount.id == accountId)
{
return prepareAccountJsonObject(m_importedAccount);
}
}
// TODO: Should we use instead a std::optional?
throw std::runtime_error("account not found");
}
QJsonArray Service::getSubaccountDataForAccountId(const QString& accountId)
{
foreach(const GeneratedAccountDto& acc, m_generatedAccounts)
{
if(acc.id == accountId)
{
return prepareSubaccountJsonObject(acc);
}
}
if(m_importedAccount.isValid())
{
if(m_importedAccount.id == accountId)
{
return prepareSubaccountJsonObject(m_importedAccount);
}
}
// TODO: Should we use instead a std::optional?
throw std::runtime_error("account not found");
}
QJsonObject Service::getAccountSettings(const QString& accountId, const QString& installationId)
{
foreach(const GeneratedAccountDto& acc, m_generatedAccounts)
if(acc.id == accountId)
{
return prepareAccountSettingsJsonObject(acc, installationId);
}
if(m_importedAccount.isValid())
{
if(m_importedAccount.id == accountId)
{
return prepareAccountSettingsJsonObject(m_importedAccount, installationId);
}
}
// TODO: Should we use instead a std::optional?
throw std::runtime_error("account not found");
}
} // namespace Accounts

View File

@ -1,20 +0,0 @@
#include "wallet_accounts/wallet_account.h"
#include <QJsonArray>
#include <QJsonObject>
#include <QJsonValue>
#include <QStringList>
Wallets::WalletAccountDto Wallets::toWalletAccountDto(const QJsonValue& jsonObj)
{
auto result = Wallets::WalletAccountDto();
result.name = jsonObj["name"].toString();
result.address = jsonObj["address"].toString();
result.path = jsonObj["path"].toString();
result.color = jsonObj["color"].toString();
result.isWallet = jsonObj["wallet"].toBool();
result.isChat = jsonObj["chat"].toBool();
result.publicKey = jsonObj["public-key"].toString();
result.walletType = jsonObj["type"].toString();
return result;
}

View File

@ -1,97 +0,0 @@
#include <QDebug>
#include "wallet_accounts/service.h"
#include "backend/wallet_accounts.h"
namespace Wallets
{
void Service::init()
{
fetchAccounts();
}
void Service::fetchAccounts()
{
try
{
auto response = Backend::Wallet::Accounts::getAccounts();
QVector<WalletAccountDto> result;
foreach(const QJsonValue& value, response.m_result)
{
auto account = toWalletAccountDto(value);
if(!account.isChat)
{
m_walletAccounts[account.address] = account;
}
}
}
catch(Backend::RpcException& e)
{
qWarning() << e.what();
}
}
void Service::refreshAccounts()
{
fetchAccounts();
// do other thing like get balances and build token here later
}
QList<WalletAccountDto> Service::getWalletAccounts()
{
return m_walletAccounts.values();
}
QString Service::generateNewAccount(const QString& password, const QString& accountName, const QString& color)
{
auto response = Backend::Wallet::Accounts::generateNewAccount(password, accountName, color);
if(response.m_error.m_message.isEmpty())
{
refreshAccounts();
}
return response.m_error.m_message;
}
QString Service::addAccountsFromPrivateKey(const QString& privateKey, const QString& password, const QString& accountName, const QString& color)
{
auto response = Backend::Wallet::Accounts::addAccountsFromPrivateKey(privateKey, password, accountName, color);
if(response.m_error.m_message.isEmpty())
{
refreshAccounts();
}
return response.m_error.m_message;
}
QString Service::addAccountsFromSeed(const QString& seedPhrase, const QString& password, const QString& accountName, const QString& color)
{
auto response = Backend::Wallet::Accounts::addAccountsFromSeed(seedPhrase, password, accountName, color);
if(response.m_error.m_message.isEmpty())
{
refreshAccounts();
}
return response.m_error.m_message;
}
QString Service::addWatchOnlyAccount(const QString& address, const QString& accountName , const QString& color)
{
auto response = Backend::Wallet::Accounts::addWatchOnlyAccount(address, accountName, color);
if(response.m_error.m_message.isEmpty())
{
refreshAccounts();
}
return response.m_error.m_message;
}
void Service::deleteAccount(const QString& address)
{
auto response = Backend::Wallet::Accounts::deleteAccount(address);
if(response.m_error.m_message.isEmpty())
{
refreshAccounts();
}
}
} // namespace Wallets

View File

@ -1,19 +0,0 @@
add_library(backend
accounts.cpp
types.cpp
utils.cpp
wallet_accounts.cpp
)
target_include_directories(backend
PUBLIC
include/
)
target_link_libraries(backend
PRIVATE
Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Quick
statusgo_shared
)

View File

@ -1,100 +0,0 @@
#include "backend/accounts.h"
#include "backend/types.h"
#include "backend/utils.h"
#include "libstatus.h"
#include <QDebug>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QString>
#include <QVector>
namespace
{
constexpr auto NumberOfAddressesToGenerate = 5;
constexpr auto MnemonicPhraseLength = 12;
} // namespace
Backend::RpcResponse<QJsonArray> Backend::Accounts::generateAddresses(QVector<QString> paths)
{
QJsonObject payload{{"n", NumberOfAddressesToGenerate},
{"mnemonicPhraseLength", MnemonicPhraseLength},
{"bip32Passphrase", ""},
{"paths", Utils::toJsonArray(paths)}
};
const char* result = MultiAccountGenerateAndDeriveAddresses(Utils::jsonToStr(payload).toUtf8().data());
return {result, QJsonDocument::fromJson(result).array()};
}
Backend::RpcResponse<QString> Backend::Accounts::generateIdenticon(QString publicKey)
{
if(!publicKey.isEmpty())
{
auto identicon = QString(Identicon(publicKey.toUtf8().data()));
return {identicon, identicon};
}
throw Backend::RpcException("publicKey can't be empty1");
}
Backend::RpcResponse<QString> Backend::Accounts::generateAlias(QString publicKey)
{
if(!publicKey.isEmpty())
{
auto alias = QString(GenerateAlias(publicKey.toUtf8().data()));
return {alias, alias};
}
throw Backend::RpcException("publicKey can't be empty2");
}
Backend::RpcResponse<QJsonObject>
Backend::Accounts::storeDerivedAccounts(QString id, QString hashedPassword, QVector<QString> paths)
{
QJsonObject payload{{"accountID", id}, {"paths", Utils::toJsonArray(paths)}, {"password", hashedPassword}};
auto result = MultiAccountStoreDerivedAccounts(Utils::jsonToStr(payload).toUtf8().data());
auto obj = QJsonDocument::fromJson(result).object();
Backend::Utils::throwOnError(obj);
return {result, obj};
}
Backend::RpcResponse<QJsonObject> Backend::Accounts::saveAccountAndLogin(
QString hashedPassword, QJsonObject account, QJsonArray subaccounts, QJsonObject settings, QJsonObject nodeConfig)
{
auto result = SaveAccountAndLogin(Utils::jsonToStr(account).toUtf8().data(),
hashedPassword.toUtf8().data(),
Utils::jsonToStr(settings).toUtf8().data(),
Utils::jsonToStr(nodeConfig).toUtf8().data(),
Utils::jsonToStr(subaccounts).toUtf8().data());
auto obj = QJsonDocument::fromJson(result).object();
Backend::Utils::throwOnError(obj);
return {result, obj};
}
Backend::RpcResponse<QJsonArray> Backend::Accounts::openAccounts(QString path)
{
const char* result = OpenAccounts(path.toUtf8().data());
auto resp = Backend::RpcResponse<QJsonArray>(result, QJsonDocument::fromJson(result).array());
return resp;
}
Backend::RpcResponse<QJsonObject> Backend::Accounts::login(
QString name, QString keyUid, QString hashedPassword, QString identicon, QString thumbnail, QString large)
{
QJsonObject payload{{"name", name}, {"key-uid", keyUid}, {"identityImage", QJsonValue()}, {"identicon", identicon}};
if(!thumbnail.isEmpty() && !large.isEmpty())
{
payload["identityImage"] = QJsonObject{{"thumbnail", thumbnail}, {"large", large}};
}
auto result = Login(Utils::jsonToStr(payload).toUtf8().data(), hashedPassword.toUtf8().data());
auto obj = QJsonDocument::fromJson(result).object();
Backend::Utils::throwOnError(obj);
return {result, obj};
}

View File

@ -1,38 +0,0 @@
#pragma once
#include "backend/types.h"
#include <QJsonArray>
#include <QString>
#include <QVector>
namespace Backend::Accounts
{
const QString ZeroAddress = "0x0000000000000000000000000000000000000000";
const QString PathWalletRoot = "m/44'/60'/0'/0";
// EIP1581 Root Key, the extended key from which any whisper key/encryption key can be derived
const QString PathEIP1581 = "m/43'/60'/1581'";
// BIP44-0 Wallet key, the default wallet key
const QString PathDefaultWallet = PathWalletRoot + "/0";
// EIP1581 Chat Key 0, the default whisper key
const QString PathWhisper = PathEIP1581 + "/0'/0";
RpcResponse<QJsonArray> generateAddresses(QVector<QString> paths);
RpcResponse<QString> generateIdenticon(QString publicKey);
RpcResponse<QString> generateAlias(QString publicKey);
RpcResponse<QJsonObject> storeDerivedAccounts(QString accountId, QString hashedPassword, QVector<QString> paths);
RpcResponse<QJsonObject> saveAccountAndLogin(
QString hashedPassword, QJsonObject account, QJsonArray subaccounts, QJsonObject settings, QJsonObject nodeConfig);
RpcResponse<QJsonArray> openAccounts(QString path);
RpcResponse<QJsonObject>
login(QString name, QString keyUid, QString hashedPassword, QString identicon, QString thumbnail, QString large);
} // namespace Backend::Accounts

Some files were not shown because too many files have changed in this diff Show More