feat(CPP): Backend for saved addresses section
This commit is contained in:
parent
24099e83c6
commit
8c312960cb
|
@ -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), {});
|
||||||
};
|
};
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
}
|
|
@ -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};
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue