feat(CPP): Backend for saved addresses section

This commit is contained in:
MishkaRogachev 2022-09-07 15:33:37 +04:00 committed by Mikhail Rogachev
parent 24099e83c6
commit 8c312960cb
10 changed files with 166 additions and 22 deletions

View File

@ -57,13 +57,17 @@ public:
return m_objects.size(); return m_objects.size();
}; };
void clear() { void reset(const ObjectContainer& objects) {
beginResetModel(); beginResetModel();
m_objects.clear(); m_objects = objects;
endResetModel(); endResetModel();
}; };
void push_back(const std::shared_ptr<T> newValue) { void clear() {
reset({});
};
void push_back(const std::shared_ptr<T>& newValue) {
beginInsertRows(QModelIndex(), m_objects.size(), m_objects.size()); beginInsertRows(QModelIndex(), m_objects.size(), m_objects.size());
m_objects.push_back(newValue); m_objects.push_back(newValue);
endInsertRows(); endInsertRows();
@ -82,7 +86,7 @@ public:
} }
}; };
void set(size_t row, const std::shared_ptr<T> newVal) { void set(size_t row, const std::shared_ptr<T>& newVal) {
m_objects.at(row) = newVal; m_objects.at(row) = newVal;
emit dataChanged(index(row), index(row), {}); emit dataChanged(index(row), index(row), {});
}; };

View File

@ -125,6 +125,7 @@ target_sources(${PROJECT_NAME}
src/StatusGo/Wallet/DerivedAddress.h src/StatusGo/Wallet/DerivedAddress.h
src/StatusGo/Wallet/NetworkConfiguration.h src/StatusGo/Wallet/NetworkConfiguration.h
src/StatusGo/Wallet/Token.h src/StatusGo/Wallet/Token.h
src/StatusGo/Wallet/SavedAddress.h
src/StatusGo/Wallet/wallet_types.h src/StatusGo/Wallet/wallet_types.h
src/StatusGo/Wallet/WalletApi.h src/StatusGo/Wallet/WalletApi.h
src/StatusGo/Wallet/WalletApi.cpp src/StatusGo/Wallet/WalletApi.cpp

View File

@ -0,0 +1,31 @@
#pragma once
#include "wallet_types.h"
#include "Accounts/accounts_types.h"
#include <Helpers/conversions.h>
#include <nlohmann/json.hpp>
#include <vector>
namespace Accounts = Status::StatusGo::Accounts;
using json = nlohmann::json;
namespace Status::StatusGo::Wallet {
/// \brief Define a saved wallet address as returned by the corresponding API
/// \note equivalent of status-go's SavedAddress@api.go
/// \see \c getSavedAddresses
struct SavedAddress
{
Accounts::EOAddress address;
QString name;
};
using SavedAddresses = std::vector<SavedAddress>;
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(SavedAddress, address, name);
}

View File

@ -34,6 +34,35 @@ DerivedAddresses getDerivedAddressesForPath(const HashedPassword &password, cons
return resultJson.get<CallPrivateRpcResponse>().result; return resultJson.get<CallPrivateRpcResponse>().result;
} }
SavedAddresses getSavedAddresses()
{
json inputJson = {
{"jsonrpc", "2.0"},
{"method", "wallet_getSavedAddresses"}
};
auto result = Utils::statusGoCallPrivateRPC(inputJson.dump().c_str());
const auto resultJson = json::parse(result);
checkPrivateRpcCallResultAndReportError(resultJson);
const auto &data = resultJson.get<CallPrivateRpcResponse>().result;
return data.is_null() ? nlohmann::json() : data;
}
void saveAddress(const Accounts::EOAddress &address, const QString &name)
{
std::vector<json> params = { SavedAddress({ address, name }) };
json inputJson = {
{"jsonrpc", "2.0"},
{"method", "wallet_addSavedAddress"},
{"params", params}
};
auto result = Utils::statusGoCallPrivateRPC(inputJson.dump().c_str());
auto resultJson = json::parse(result);
checkPrivateRpcCallResultAndReportError(resultJson);
}
NetworkConfigurations getEthereumChains(bool onlyEnabled) NetworkConfigurations getEthereumChains(bool onlyEnabled)
{ {
std::vector<json> params = {onlyEnabled}; std::vector<json> params = {onlyEnabled};

View File

@ -7,6 +7,7 @@
#include "DerivedAddress.h" #include "DerivedAddress.h"
#include "NetworkConfiguration.h" #include "NetworkConfiguration.h"
#include "Token.h" #include "Token.h"
#include "SavedAddress.h"
#include "Types.h" #include "Types.h"
@ -19,7 +20,20 @@ namespace Status::StatusGo::Wallet
/// \brief Retrieve a list of derived account addresses /// \brief Retrieve a list of derived account addresses
/// \see \c generateAccountWithDerivedPath /// \see \c generateAccountWithDerivedPath
/// \throws \c CallPrivateRpcError /// \throws \c CallPrivateRpcError
DerivedAddresses getDerivedAddressesForPath(const HashedPassword &password, const Accounts::EOAddress &derivedFrom, const Accounts::DerivationPath &path, int pageSize, int pageNumber); DerivedAddresses getDerivedAddressesForPath(const HashedPassword &password,
const Accounts::EOAddress &derivedFrom,
const Accounts::DerivationPath &path,
int pageSize, int pageNumber);
/// \brief Retrieve a list of saved wallet addresses
/// \see \c getSavedAddresses
/// \throws \c CallPrivateRpcError
SavedAddresses getSavedAddresses();
/// \brief Add a new or update existing saved wallet address
/// \see \c addSavedAddress
/// \throws \c CallPrivateRpcError
void saveAddress(const Accounts::EOAddress& address, const QString& name);
/// \note status-go's GetEthereumChains@api.go which calls /// \note status-go's GetEthereumChains@api.go which calls
/// NetworkManager@client.go -> network.Manager.get() /// NetworkManager@client.go -> network.Manager.get()

View File

@ -1,5 +1,7 @@
#pragma once #pragma once
#include <memory>
#include <QtQmlIntegration> #include <QtQmlIntegration>
namespace Status::Wallet namespace Status::Wallet
@ -23,4 +25,6 @@ private:
const QString m_address; const QString m_address;
const QString m_name; const QString m_name;
}; };
using SavedAddressPtr = std::shared_ptr<SavedAddress>;
} }

View File

@ -21,8 +21,8 @@ public:
enum Error enum Error
{ {
NoneError, NoneError,
UnknownAddressError, SaveAddressError,
AddressAlreadyPresentError RetrieveSavedAddressesError
}; };
Q_ENUM(Error) Q_ENUM(Error)
@ -31,7 +31,7 @@ public:
QAbstractListModel* savedAddresses() const; QAbstractListModel* savedAddresses() const;
Q_INVOKABLE void saveAddress(const QString& address, const QString& name); Q_INVOKABLE void saveAddress(const QString& address, const QString& name);
// Q_INVOKABLE void removeAddress(const QString& address); Q_INVOKABLE void refresh();
signals: signals:
void error(Status::Wallet::SavedAddressesController::Error error); void error(Status::Wallet::SavedAddressesController::Error error);

View File

@ -10,18 +10,30 @@ Popup {
required property SavedAddressesController savedAddressesController required property SavedAddressesController savedAddressesController
width: 300
GridLayout { GridLayout {
anchors.fill: parent anchors.fill: parent
columns: 2 columns: 2
Label { text: qsTr("Address") ; Layout.fillWidth: true } Label {
TextField { text: qsTr("Address")
id: addressFiled Layout.fillWidth: true
}
TextField {
id: addressFiled
Layout.fillWidth: true
}
Label {
text: qsTr("Name")
Layout.fillWidth: true
} }
Label { text: qsTr("Name") ; Layout.fillWidth: true }
TextField { TextField {
id: nameFiled id: nameFiled
Layout.fillWidth: true
} }
Button { Button {
@ -29,6 +41,8 @@ Popup {
enabled: addressFiled.text.length && nameFiled.text.length enabled: addressFiled.text.length && nameFiled.text.length
onClicked: { onClicked: {
savedAddressesController.saveAddress(addressFiled.text, nameFiled.text); savedAddressesController.saveAddress(addressFiled.text, nameFiled.text);
addressFiled.clear();
nameFiled.clear();
root.close(); root.close();
} }
GridLayout.columnSpan: 2 GridLayout.columnSpan: 2

View File

@ -10,10 +10,29 @@ Item {
required property SavedAddressesController savedAddressesController required property SavedAddressesController savedAddressesController
Component.onCompleted: savedAddressesController.refresh()
ListView { ListView {
id: list id: list
anchors.fill: parent anchors.fill: parent
model: SavedAddressesController.savedAddresses model: savedAddressesController.savedAddresses
header: RowLayout {
width: list.width
spacing: 0
Label {
text: qsTr("Address")
font.bold: true
Layout.fillWidth: true
}
Label {
text: qsTr("Name")
font.bold: true
Layout.fillWidth: true
}
}
delegate: RowLayout { delegate: RowLayout {
width: list.width width: list.width
@ -39,6 +58,7 @@ Item {
AddSavedAddressesView { AddSavedAddressesView {
id: addView id: addView
x: (parent.width - width) / 2
y: parent.height - height y: parent.height - height
savedAddressesController: root.savedAddressesController savedAddressesController: root.savedAddressesController
} }

View File

@ -1,13 +1,15 @@
#include "Status/Wallet/SavedAddressesController.h" #include "Status/Wallet/SavedAddressesController.h"
#include "Helpers/helpers.h" #include "Helpers/helpers.h"
#include "Metadata/api_response.h"
#include <StatusGo/Wallet/WalletApi.h>
namespace Status::Wallet namespace Status::Wallet
{ {
SavedAddressesController::SavedAddressesController(QObject* parent) SavedAddressesController::SavedAddressesController(QObject* parent)
: QObject(parent) : QObject(parent)
, m_savedAddresses(Helpers::makeSharedQObject<SavedAddressesModel>( , m_savedAddresses(Helpers::makeSharedQObject<SavedAddressesModel>("savedAddress"))
/* TODO: std::move(getWalletAccounts()), */"savedAddress"))
{ {
} }
@ -18,14 +20,39 @@ QAbstractListModel* SavedAddressesController::savedAddresses() const
void SavedAddressesController::saveAddress(const QString &address, const QString &name) void SavedAddressesController::saveAddress(const QString &address, const QString &name)
{ {
// TODO: check present addresses try
// { {
// emit error(AddressAlreadyPresentError); StatusGo::Wallet::saveAddress(StatusGo::Accounts::EOAddress(address), name);
// return; }
// } catch(const StatusGo::CallPrivateRpcError& rpcError)
{
qWarning() << "StatusGoQt.saveAddress error: " <<
rpcError.errorResponse().error.message.c_str();
emit error(SaveAddressError);
}
auto item = Helpers::makeSharedQObject<SavedAddress>(address, name); // TODO: signal from wallet data_source
m_savedAddresses->push_back(item); this->refresh();
}
void SavedAddressesController::refresh()
{
std::vector<SavedAddressPtr> savedAddresses;
try
{
for (const StatusGo::Wallet::SavedAddress& address: StatusGo::Wallet::getSavedAddresses())
{
savedAddresses.push_back(std::make_shared<SavedAddress>(address.address.get(), address.name));
}
}
catch(const StatusGo::CallPrivateRpcError& rpcError)
{
qWarning() << "StatusGoQt.getSavedAddresses error: " <<
rpcError.errorResponse().error.message.c_str();
emit error(RetrieveSavedAddressesError);
}
m_savedAddresses->reset(savedAddresses);
} }
} // namespace Status::Wallet } // namespace Status::Wallet