diff --git a/programs/light_client/CMakeLists.txt b/programs/light_client/CMakeLists.txt index 6a35f279..36608db3 100644 --- a/programs/light_client/CMakeLists.txt +++ b/programs/light_client/CMakeLists.txt @@ -18,7 +18,16 @@ if (NOT CMAKE_BUILD_TYPE STREQUAL "Debug") qt5_add_resources(QML_QRC qml/qml.qrc) endif() -add_executable(light_client ChainDataModel.cpp Operations.cpp GrapheneApplication.cpp GrapheneObject.cpp Asset.cpp Account.cpp Balance.cpp main.cpp ${QML_QRC} ${QML}) +add_executable(light_client + Wallet.cpp + ChainDataModel.cpp + Operations.cpp + GrapheneApplication.cpp + GrapheneObject.cpp + Asset.cpp + Account.cpp + Balance.cpp + main.cpp ${QML_QRC} ${QML}) if (CMAKE_VERSION VERSION_LESS 3.0) add_dependencies(light_client gen_qrc) diff --git a/programs/light_client/Wallet.cpp b/programs/light_client/Wallet.cpp new file mode 100644 index 00000000..9fd4e43c --- /dev/null +++ b/programs/light_client/Wallet.cpp @@ -0,0 +1,139 @@ +#include "Wallet.hpp" + +Wallet::Wallet() +{ +} + +Wallet::~Wallet() +{ + close(); +} + +bool Wallet::open( QString file_path ) +{ + return false; +} + +bool Wallet::close() +{ + save(); + return false; +} + +bool Wallet::save() +{ + return false; +} + +bool Wallet::saveAs( QString file_path ) +{ + return false; +} + +bool Wallet::create( QString file_path, QString brain_key ) +{ + return false; +} + +bool Wallet::loadBrainKey( QString brain_key ) +{ + return false; +} + +bool Wallet::purgeBrainKey() +{ + return false; +} + +bool Wallet::hasBrainKey()const +{ + return false; +} + +QString Wallet::getBrainKey()const +{ + return QString(); +} + +bool Wallet::isLocked()const +{ + return false; +} +QString Wallet::unlock( QString password ) +{ + return QString(); +} + +bool Wallet::lock() +{ + return false; +} +bool Wallet::changePassword( QString new_password ) +{ + return false; +} + +QString Wallet::getActivePrivateKey( QString owner_pub_key, uint32_t seq ) +{ + return QString(); +} + +QString Wallet::getOwnerPrivateKey( uint32_t seq ) +{ + return QString(); +} + + +QString Wallet::getKeyLabel( QString pubkey ) +{ + return QString(); +} + +QString Wallet::getPublicKey( QString label ) +{ + return QString(); +} + +/** imports a public key and assigns it a label */ +bool Wallet::importPublicKey( QString pubkey, QString label) +{ + return false; +} + +/** + * @param wifkey a private key in (WIF) Wallet Import Format + * @pre !isLocked() + **/ +bool Wallet::importPrivateKey( QString wifkey, QString label ) +{ + return false; +} + +/** removes the key, its lablel and its private key */ +bool Wallet::removePublicKey( QString pubkey ) +{ + return false; +} + +/** removes only the private key, keeping the public key and label */ +bool Wallet::removePrivateKey( QString pubkey ) +{ + return false; +} + +/** + * @pre !isLocked() + */ +vector Wallet::signDigest( const digest_type& d, + const set& keys )const +{ + vector result; + return result; +} + +const flat_set& Wallet::getAvailablePrivateKeys()const +{ + return _available_private_keys; +} + + diff --git a/programs/light_client/Wallet.hpp b/programs/light_client/Wallet.hpp new file mode 100644 index 00000000..3c229365 --- /dev/null +++ b/programs/light_client/Wallet.hpp @@ -0,0 +1,121 @@ +#pragma once +#pragma GCC diagnostic ignored "-Wunknown-pragmas" + +#include +#include + +using std::string; +using std::vector; +using std::set; +using fc::flat_set; +using std::map; +using graphene::chain::public_key_type; +using graphene::chain::digest_type; +using graphene::chain::signature_type; +using fc::optional; + +struct key_data +{ + string label; /** unique label assigned to this key */ + vector encrypted_private_key; +}; +FC_REFLECT( key_data, (label)(encrypted_private_key) ); + +struct wallet_file +{ + optional> encrypted_brain_key; + optional> encrypted_master_key; + map encrypted_private_keys; +}; + +FC_REFLECT( wallet_file, + (encrypted_brain_key) + (encrypted_master_key) + (encrypted_private_keys) + ); + + +/** + * @class Wallet + * @brief Securely maintains a set of labeled public and private keys + */ +class Wallet : public QObject +{ + public: + Q_OBJECT + + Wallet(); + ~Wallet(); + + Q_INVOKABLE bool open( QString file_path ); + Q_INVOKABLE bool close(); + Q_INVOKABLE bool save(); + Q_INVOKABLE bool saveAs( QString file_path ); + Q_INVOKABLE bool create( QString file_path, QString brain_key = QString() ); + + /** required to generate new owner keys */ + Q_INVOKABLE bool loadBrainKey( QString brain_key ); + + /** removes brain key to secure owner keys */ + Q_INVOKABLE bool purgeBrainKey(); + Q_INVOKABLE bool hasBrainKey()const; + + /** @pre hasBrainKey() */ + Q_INVOKABLE QString getBrainKey()const; + + Q_INVOKABLE bool isLocked()const; + Q_INVOKABLE QString unlock( QString password ); + Q_INVOKABLE bool lock(); + Q_INVOKABLE bool changePassword( QString new_password ); + + /** + * @pre !isLocked(); + * @post save() + * @return WIF private key + */ + Q_INVOKABLE QString getActivePrivateKey( QString owner_public_key, uint32_t sequence ); + + /** + * @pre !isLocked(); + * @pre hasBrainKey(); + * @post save() + * @return WIF private key + */ + Q_INVOKABLE QString getOwnerPrivateKey( uint32_t sequence ); + + Q_INVOKABLE QString getKeyLabel( QString pubkey ); + Q_INVOKABLE QString getPublicKey( QString label ); + + /** imports a public key and assigns it a label */ + Q_INVOKABLE bool importPublicKey( QString pubkey, QString label = QString() ); + + /** + * @param wifkey a private key in (WIF) Wallet Import Format + * @pre !isLocked() + **/ + Q_INVOKABLE bool importPrivateKey( QString wifkey, QString label = QString() ); + + /** removes the key, its lablel and its private key */ + Q_INVOKABLE bool removePublicKey( QString pubkey ); + + /** removes only the private key, keeping the public key and label */ + Q_INVOKABLE bool removePrivateKey( QString pubkey ); + + + /** + * @pre !isLocked() + */ + vector signDigest( const digest_type& d, + const set& keys )const; + + const flat_set& getAvailablePrivateKeys()const; + + private: + fc::path _wallet_file_path; + wallet_file _data; + fc::sha512 _decrypted_master_key; + flat_set _available_private_keys; + map _label_to_key; +}; + +