integrate wallet with GrapheneApplication and Account
This commit is contained in:
parent
0911bb605c
commit
36ba2e1d45
10 changed files with 144 additions and 30 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -6,6 +6,8 @@ CMakeCache.txt
|
||||||
CMakeFiles
|
CMakeFiles
|
||||||
Makefile
|
Makefile
|
||||||
compile_commands.json
|
compile_commands.json
|
||||||
|
moc_*
|
||||||
|
*.moc
|
||||||
|
|
||||||
libraries/utilities/git_revision.cpp
|
libraries/utilities/git_revision.cpp
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <graphene/chain/account_object.hpp>
|
#include <graphene/chain/account_object.hpp>
|
||||||
|
#include <graphene/chain/vesting_balance_object.hpp>
|
||||||
|
#include <graphene/chain/market_evaluator.hpp>
|
||||||
|
|
||||||
namespace graphene { namespace app {
|
namespace graphene { namespace app {
|
||||||
using namespace graphene::chain;
|
using namespace graphene::chain;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
#include "Balance.hpp"
|
#include "Balance.hpp"
|
||||||
#include "ChainDataModel.hpp"
|
#include "ChainDataModel.hpp"
|
||||||
|
#include "Wallet.hpp"
|
||||||
|
|
||||||
#include <graphene/chain/account_object.hpp>
|
#include <graphene/chain/account_object.hpp>
|
||||||
|
|
||||||
|
|
@ -15,17 +16,54 @@ QQmlListProperty<Balance> Account::balances()
|
||||||
return QQmlListProperty<Balance>(this, this, count, at);
|
return QQmlListProperty<Balance>(this, this, count, at);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double Account::getActiveControl( Wallet* w )const
|
||||||
|
{
|
||||||
|
if( m_account.active.num_auths() == 0 ) return 0;
|
||||||
|
if( m_account.active.weight_threshold == 0 ) return 0;
|
||||||
|
|
||||||
|
uint64_t weight = 0;
|
||||||
|
for( auto& key : m_account.active.key_auths )
|
||||||
|
{
|
||||||
|
if( w->hasPrivateKey( toQString(key.first) ) ) weight += key.second;
|
||||||
|
}
|
||||||
|
for( auto& acnt : m_account.active.account_auths )
|
||||||
|
{
|
||||||
|
// TODO: lookup Account, check to see if we have full control of it, and
|
||||||
|
// add its weight if we do. Be sure to limit recursion depth
|
||||||
|
}
|
||||||
|
|
||||||
|
return double(weight) / double( m_account.active.weight_threshold );
|
||||||
|
}
|
||||||
|
|
||||||
|
double Account::getOwnerControl( Wallet* w )const
|
||||||
|
{
|
||||||
|
if( m_account.owner.num_auths() == 0 ) return 0;
|
||||||
|
if( m_account.owner.weight_threshold == 0 ) return 0;
|
||||||
|
uint64_t weight = 0;
|
||||||
|
for( auto& key : m_account.owner.key_auths )
|
||||||
|
{
|
||||||
|
if( w->hasPrivateKey( toQString(key.first) ) ) weight += key.second;
|
||||||
|
}
|
||||||
|
for( auto& acnt : m_account.owner.account_auths )
|
||||||
|
{
|
||||||
|
// TODO: lookup Account, check to see if we have full *ACTIVE* control of it, and
|
||||||
|
// add its weight if we do. Be sure to limit recursion depth
|
||||||
|
}
|
||||||
|
|
||||||
|
return double(weight) / double( m_account.owner.weight_threshold );
|
||||||
|
}
|
||||||
|
|
||||||
void Account::update(const graphene::chain::account_balance_object& balance)
|
void Account::update(const graphene::chain::account_balance_object& balance)
|
||||||
{
|
{
|
||||||
auto balanceItr = std::find_if(m_balances.begin(), m_balances.end(),
|
auto balanceItr = std::find_if(m_balances.begin(), m_balances.end(),
|
||||||
[&balance](Balance* b) { return b->type()->id() == balance.asset_type.instance.value; });
|
[&balance](Balance* b) { return b->type()->id() == balance.asset_type.instance.value; });
|
||||||
|
|
||||||
if (balanceItr != m_balances.end()) {
|
if (balanceItr != m_balances.end()) {
|
||||||
ilog("Updating ${a}'s balance: ${b}", ("a", m_name.toStdString())("b", balance));
|
ilog("Updating ${a}'s balance: ${b}", ("a", name().toStdString())("b", balance));
|
||||||
(*balanceItr)->update(balance);
|
(*balanceItr)->update(balance);
|
||||||
Q_EMIT balancesChanged();
|
Q_EMIT balancesChanged();
|
||||||
} else {
|
} else {
|
||||||
ilog("Adding to ${a}'s new balance: ${b}", ("a", m_name.toStdString())("b", balance));
|
ilog("Adding to ${a}'s new balance: ${b}", ("a", name().toStdString())("b", balance));
|
||||||
Balance* newBalance = new Balance;
|
Balance* newBalance = new Balance;
|
||||||
newBalance->setParent(this);
|
newBalance->setParent(this);
|
||||||
auto model = qobject_cast<ChainDataModel*>(parent());
|
auto model = qobject_cast<ChainDataModel*>(parent());
|
||||||
|
|
|
||||||
|
|
@ -4,27 +4,42 @@
|
||||||
#include "GrapheneObject.hpp"
|
#include "GrapheneObject.hpp"
|
||||||
|
|
||||||
#include <QQmlListProperty>
|
#include <QQmlListProperty>
|
||||||
|
#include <graphene/app/full_account.hpp>
|
||||||
|
|
||||||
namespace graphene { namespace chain {
|
namespace graphene { namespace chain {
|
||||||
class account_balance_object;
|
class account_balance_object;
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
using graphene::chain::account_object;
|
||||||
|
using graphene::chain::account_balance_object;
|
||||||
|
|
||||||
class Balance;
|
class Balance;
|
||||||
|
class Wallet;
|
||||||
|
|
||||||
class Account : public GrapheneObject {
|
class Account : public GrapheneObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
Q_PROPERTY(QString name MEMBER m_name READ name NOTIFY nameChanged)
|
Q_PROPERTY(QString name READ name NOTIFY nameChanged)
|
||||||
Q_PROPERTY(QQmlListProperty<Balance> balances READ balances NOTIFY balancesChanged)
|
Q_PROPERTY(QQmlListProperty<Balance> balances READ balances NOTIFY balancesChanged)
|
||||||
|
|
||||||
QString m_name;
|
account_object m_account;
|
||||||
QList<Balance*> m_balances;
|
QList<Balance*> m_balances;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Account(ObjectId id = -1, QString name = QString(), QObject* parent = nullptr)
|
Account(ObjectId id = -1, QString name = QString(), QObject* parent = nullptr)
|
||||||
: GrapheneObject(id, parent), m_name(name)
|
: GrapheneObject(id, parent)
|
||||||
{}
|
{
|
||||||
|
m_account.name = name.toStdString();
|
||||||
|
}
|
||||||
|
void setAccountObject( const account_object& obj )
|
||||||
|
{
|
||||||
|
auto old_name = m_account.name;
|
||||||
|
m_account = obj;
|
||||||
|
if( old_name != m_account.name )
|
||||||
|
Q_EMIT nameChanged();
|
||||||
|
}
|
||||||
|
|
||||||
QString name()const { return m_name; }
|
QString name()const { return toQString(m_account.name); }
|
||||||
QQmlListProperty<Balance> balances();
|
QQmlListProperty<Balance> balances();
|
||||||
|
|
||||||
void setBalances(QList<Balance*> balances) {
|
void setBalances(QList<Balance*> balances) {
|
||||||
|
|
@ -34,7 +49,18 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void update(const graphene::chain::account_balance_object& balance);
|
void update(const account_balance_object& balance);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Anything greater than 1.0 means full authority.
|
||||||
|
* Anything between (0 and 1.0) means partial authority
|
||||||
|
* 0 means no authority.
|
||||||
|
*
|
||||||
|
* @return the percent of direct control the wallet has over the account.
|
||||||
|
*/
|
||||||
|
Q_INVOKABLE double getOwnerControl( Wallet* w )const;
|
||||||
|
Q_INVOKABLE double getActiveControl( Wallet* w )const;
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void nameChanged();
|
void nameChanged();
|
||||||
|
|
|
||||||
|
|
@ -79,21 +79,21 @@ void ChainDataModel::processUpdatedObject(const fc::variant& update)
|
||||||
auto id = update.as<variant_object>()["id"].as<object_id_type>();
|
auto id = update.as<variant_object>()["id"].as<object_id_type>();
|
||||||
if (id.space() == protocol_ids) {
|
if (id.space() == protocol_ids) {
|
||||||
switch (id.type()) {
|
switch (id.type()) {
|
||||||
default:
|
default:
|
||||||
wlog("Update procedure for ${update} is not yet implemented.", ("update", update));
|
wlog("Update procedure for ${update} is not yet implemented.", ("update", update));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else if (id.space() == implementation_ids) {
|
} else if (id.space() == implementation_ids) {
|
||||||
switch (id.type()) {
|
switch (id.type()) {
|
||||||
case impl_account_balance_object_type: {
|
case impl_account_balance_object_type: {
|
||||||
account_balance_object balance = update.as<account_balance_object>();
|
account_balance_object balance = update.as<account_balance_object>();
|
||||||
auto owner = m_accounts.find(balance.owner.instance.value);
|
auto owner = m_accounts.find(balance.owner.instance.value);
|
||||||
if (owner != m_accounts.end())
|
if (owner != m_accounts.end())
|
||||||
(*owner)->update(balance);
|
(*owner)->update(balance);
|
||||||
else
|
else
|
||||||
elog("Got unexpected balance update:\n${u}\nfor an account I don't have.",
|
elog("Got unexpected balance update:\n${u}\nfor an account I don't have.",
|
||||||
("u", update));
|
("u", update));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
@ -195,7 +195,7 @@ void ChainDataModel::getAccountImpl(QString accountIdentifier, Account* const *
|
||||||
} else {
|
} else {
|
||||||
m_accounts.modify(itr, [this,&accountPackage](Account* a){
|
m_accounts.modify(itr, [this,&accountPackage](Account* a){
|
||||||
a->setProperty("id", ObjectId(accountPackage->account.id.instance()));
|
a->setProperty("id", ObjectId(accountPackage->account.id.instance()));
|
||||||
a->setProperty("name", QString::fromStdString(accountPackage->account.name));
|
a->setAccountObject( accountPackage->account );
|
||||||
|
|
||||||
// Set balances
|
// Set balances
|
||||||
QList<Balance*> balances;
|
QList<Balance*> balances;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
#include "GrapheneApplication.hpp"
|
#include "GrapheneApplication.hpp"
|
||||||
#include "ChainDataModel.hpp"
|
#include "ChainDataModel.hpp"
|
||||||
|
#include "Wallet.hpp"
|
||||||
#include "Operations.hpp"
|
#include "Operations.hpp"
|
||||||
|
|
||||||
#include <graphene/app/api.hpp>
|
#include <graphene/app/api.hpp>
|
||||||
|
|
@ -17,6 +18,7 @@ GrapheneApplication::GrapheneApplication(QObject* parent)
|
||||||
|
|
||||||
m_model = new ChainDataModel(m_thread, this);
|
m_model = new ChainDataModel(m_thread, this);
|
||||||
m_operationBuilder = new OperationBuilder(*m_model, this);
|
m_operationBuilder = new OperationBuilder(*m_model, this);
|
||||||
|
m_wallet = new Wallet( this );
|
||||||
|
|
||||||
connect(m_model, &ChainDataModel::queueExecute,
|
connect(m_model, &ChainDataModel::queueExecute,
|
||||||
this, &GrapheneApplication::execute);
|
this, &GrapheneApplication::execute);
|
||||||
|
|
|
||||||
|
|
@ -7,24 +7,28 @@
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
|
|
||||||
namespace fc { namespace http {
|
namespace fc { namespace http {
|
||||||
class websocket_client;
|
class websocket_client;
|
||||||
}}
|
}}
|
||||||
|
|
||||||
class ChainDataModel;
|
class ChainDataModel;
|
||||||
class OperationBuilder;
|
class OperationBuilder;
|
||||||
|
class Wallet;
|
||||||
class GrapheneApplication : public QObject {
|
class GrapheneApplication : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
Q_PROPERTY(ChainDataModel* model READ model CONSTANT)
|
Q_PROPERTY(ChainDataModel* model READ model CONSTANT)
|
||||||
Q_PROPERTY(OperationBuilder* operationBuilder READ operationBuilder CONSTANT)
|
Q_PROPERTY(OperationBuilder* operationBuilder READ operationBuilder CONSTANT)
|
||||||
|
Q_PROPERTY(Wallet* wallet READ wallet CONSTANT)
|
||||||
Q_PROPERTY(bool isConnected READ isConnected NOTIFY isConnectedChanged)
|
Q_PROPERTY(bool isConnected READ isConnected NOTIFY isConnectedChanged)
|
||||||
|
|
||||||
|
|
||||||
fc::thread m_thread;
|
fc::thread m_thread;
|
||||||
ChainDataModel* m_model = nullptr;
|
ChainDataModel* m_model = nullptr;
|
||||||
|
Wallet* m_wallet = nullptr;
|
||||||
OperationBuilder* m_operationBuilder = nullptr;
|
OperationBuilder* m_operationBuilder = nullptr;
|
||||||
bool m_isConnected = false;
|
bool m_isConnected = false;
|
||||||
|
|
||||||
boost::signals2::scoped_connection m_connectionClosed;
|
boost::signals2::scoped_connection m_connectionClosed;
|
||||||
|
|
||||||
|
|
@ -40,6 +44,8 @@ public:
|
||||||
GrapheneApplication(QObject* parent = nullptr);
|
GrapheneApplication(QObject* parent = nullptr);
|
||||||
~GrapheneApplication();
|
~GrapheneApplication();
|
||||||
|
|
||||||
|
Wallet* wallet()const { return m_wallet; }
|
||||||
|
|
||||||
ChainDataModel* model() const {
|
ChainDataModel* model() const {
|
||||||
return m_model;
|
return m_model;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,8 @@
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
|
QString toQString( const std::string& s );
|
||||||
|
|
||||||
using ObjectId = qint64;
|
using ObjectId = qint64;
|
||||||
Q_DECLARE_METATYPE(ObjectId)
|
Q_DECLARE_METATYPE(ObjectId)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,8 @@
|
||||||
QString toQString( const std::string& s ) { QString result; result.fromStdString( s ); return result; }
|
QString toQString( const std::string& s ) { QString result; result.fromStdString( s ); return result; }
|
||||||
QString toQString( public_key_type k ) { return toQString( fc::variant(k).as_string() ); }
|
QString toQString( public_key_type k ) { return toQString( fc::variant(k).as_string() ); }
|
||||||
|
|
||||||
Wallet::Wallet()
|
Wallet::Wallet( QObject* parent )
|
||||||
|
:QObject(parent)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -35,6 +36,7 @@ bool Wallet::open( QString file_path )
|
||||||
}
|
}
|
||||||
_wallet_file_path = p;
|
_wallet_file_path = p;
|
||||||
|
|
||||||
|
Q_EMIT isOpenChanged( true );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -48,6 +50,7 @@ bool Wallet::close()
|
||||||
if( !isOpen() ) return false;
|
if( !isOpen() ) return false;
|
||||||
save();
|
save();
|
||||||
_wallet_file_path = fc::path();
|
_wallet_file_path = fc::path();
|
||||||
|
Q_EMIT isOpenChanged( false );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -158,6 +161,8 @@ bool Wallet::unlock( QString password )
|
||||||
_decrypted_master_key = fc::raw::unpack<fc::sha512>(plain_txt);
|
_decrypted_master_key = fc::raw::unpack<fc::sha512>(plain_txt);
|
||||||
if( _data.master_key_digest != fc::sha512::hash(_decrypted_master_key) )
|
if( _data.master_key_digest != fc::sha512::hash(_decrypted_master_key) )
|
||||||
_decrypted_master_key = fc::sha512();
|
_decrypted_master_key = fc::sha512();
|
||||||
|
|
||||||
|
Q_EMIT isLockedChanged( isLocked() );
|
||||||
return !isLocked();
|
return !isLocked();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -166,6 +171,8 @@ bool Wallet::lock()
|
||||||
if( !isOpen() ) return false;
|
if( !isOpen() ) return false;
|
||||||
_brain_key = QString();
|
_brain_key = QString();
|
||||||
_decrypted_master_key = fc::sha512();
|
_decrypted_master_key = fc::sha512();
|
||||||
|
|
||||||
|
Q_EMIT isLockedChanged( isLocked() );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool Wallet::changePassword( QString new_password )
|
bool Wallet::changePassword( QString new_password )
|
||||||
|
|
@ -181,6 +188,22 @@ bool Wallet::changePassword( QString new_password )
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
bool Wallet::hasPrivateKey( QString pubkey, bool include_with_brain_key )
|
||||||
|
{
|
||||||
|
auto pub = fc::variant( pubkey.toStdString() ).as<public_key_type>();
|
||||||
|
auto itr = _data.encrypted_private_keys.find(pub);
|
||||||
|
if( itr == _data.encrypted_private_keys.end() )
|
||||||
|
return false;
|
||||||
|
if( itr->second.encrypted_private_key.size() )
|
||||||
|
return true;
|
||||||
|
if( include_with_brain_key && itr->second.brain_sequence >= 0 )
|
||||||
|
{
|
||||||
|
if( !itr->second.owner )
|
||||||
|
return true;
|
||||||
|
return hasPrivateKey( toQString( *itr->second.owner ), include_with_brain_key );
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
QString Wallet::getPrivateKey( QString pubkey )
|
QString Wallet::getPrivateKey( QString pubkey )
|
||||||
{
|
{
|
||||||
|
|
@ -203,6 +226,7 @@ QString Wallet::getPublicKey( QString wif_private_key )const
|
||||||
if( !priv ) return QString();
|
if( !priv ) return QString();
|
||||||
|
|
||||||
auto pub = public_key_type(priv->get_public_key());
|
auto pub = public_key_type(priv->get_public_key());
|
||||||
|
|
||||||
return toQString( fc::variant( pub ).as_string() );
|
return toQString( fc::variant( pub ).as_string() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -223,6 +247,8 @@ QString Wallet::getActivePrivateKey( QString owner_pub_key, uint32_t seq )
|
||||||
|
|
||||||
public_key_type active_pub_key(priv_key->get_public_key());
|
public_key_type active_pub_key(priv_key->get_public_key());
|
||||||
_data.encrypted_private_keys[active_pub_key].encrypted_private_key = fc::aes_encrypt( _decrypted_master_key, fc::raw::pack( wif ) );
|
_data.encrypted_private_keys[active_pub_key].encrypted_private_key = fc::aes_encrypt( _decrypted_master_key, fc::raw::pack( wif ) );
|
||||||
|
_data.encrypted_private_keys[active_pub_key].owner = fc::variant( owner_pub_key.toStdString() ).as<public_key_type>();
|
||||||
|
_data.encrypted_private_keys[active_pub_key].brain_sequence = seq;
|
||||||
_available_private_keys.insert( active_pub_key );
|
_available_private_keys.insert( active_pub_key );
|
||||||
|
|
||||||
return toQString(wif);
|
return toQString(wif);
|
||||||
|
|
@ -244,6 +270,7 @@ QString Wallet::getOwnerPrivateKey( uint32_t seq )
|
||||||
|
|
||||||
public_key_type owner_pub_key(priv_key->get_public_key());
|
public_key_type owner_pub_key(priv_key->get_public_key());
|
||||||
_data.encrypted_private_keys[owner_pub_key].encrypted_private_key = fc::aes_encrypt( _decrypted_master_key, fc::raw::pack( wif ) );
|
_data.encrypted_private_keys[owner_pub_key].encrypted_private_key = fc::aes_encrypt( _decrypted_master_key, fc::raw::pack( wif ) );
|
||||||
|
_data.encrypted_private_keys[owner_pub_key].brain_sequence = seq;
|
||||||
_available_private_keys.insert( owner_pub_key );
|
_available_private_keys.insert( owner_pub_key );
|
||||||
|
|
||||||
return toQString( wif );
|
return toQString( wif );
|
||||||
|
|
|
||||||
|
|
@ -16,13 +16,18 @@ using graphene::chain::digest_type;
|
||||||
using graphene::chain::signature_type;
|
using graphene::chain::signature_type;
|
||||||
using fc::optional;
|
using fc::optional;
|
||||||
|
|
||||||
|
QString toQString( const std::string& s );
|
||||||
|
QString toQString( public_key_type k );
|
||||||
|
|
||||||
struct key_data
|
struct key_data
|
||||||
{
|
{
|
||||||
string label; /** unique label assigned to this key */
|
string label; /** unique label assigned to this key */
|
||||||
/** encrypted as a packed std::string containing a wif private key */
|
/** encrypted as a packed std::string containing a wif private key */
|
||||||
vector<char> encrypted_private_key;
|
vector<char> encrypted_private_key;
|
||||||
|
int32_t brain_sequence = -1;
|
||||||
|
optional<public_key_type> owner; /// if this key was derived from an owner key + sequence
|
||||||
};
|
};
|
||||||
FC_REFLECT( key_data, (label)(encrypted_private_key) );
|
FC_REFLECT( key_data, (label)(encrypted_private_key)(brain_sequence)(owner) );
|
||||||
|
|
||||||
struct wallet_file
|
struct wallet_file
|
||||||
{
|
{
|
||||||
|
|
@ -51,10 +56,9 @@ FC_REFLECT( wallet_file,
|
||||||
*/
|
*/
|
||||||
class Wallet : public QObject
|
class Wallet : public QObject
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
Q_OBJECT
|
Wallet( QObject* parent = nullptr );
|
||||||
|
|
||||||
Wallet();
|
|
||||||
~Wallet();
|
~Wallet();
|
||||||
|
|
||||||
Q_INVOKABLE bool open( QString file_path );
|
Q_INVOKABLE bool open( QString file_path );
|
||||||
|
|
@ -101,6 +105,7 @@ class Wallet : public QObject
|
||||||
Q_INVOKABLE bool setKeyLabel( QString pubkey, QString label );
|
Q_INVOKABLE bool setKeyLabel( QString pubkey, QString label );
|
||||||
Q_INVOKABLE QString getPublicKey( QString label );
|
Q_INVOKABLE QString getPublicKey( QString label );
|
||||||
Q_INVOKABLE QString getPrivateKey( QString pubkey );
|
Q_INVOKABLE QString getPrivateKey( QString pubkey );
|
||||||
|
Q_INVOKABLE bool hasPrivateKey( QString pubkey, bool include_with_brain_key = false );
|
||||||
|
|
||||||
/** imports a public key and assigns it a label */
|
/** imports a public key and assigns it a label */
|
||||||
Q_INVOKABLE bool importPublicKey( QString pubkey, QString label = QString() );
|
Q_INVOKABLE bool importPublicKey( QString pubkey, QString label = QString() );
|
||||||
|
|
@ -131,6 +136,10 @@ class Wallet : public QObject
|
||||||
|
|
||||||
const flat_set<public_key_type>& getAvailablePrivateKeys()const;
|
const flat_set<public_key_type>& getAvailablePrivateKeys()const;
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void isLockedChanged( bool state );
|
||||||
|
void isOpenChanged( bool state );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
fc::path _wallet_file_path;
|
fc::path _wallet_file_path;
|
||||||
wallet_file _data;
|
wallet_file _data;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue