add import zkey
This commit is contained in:
@@ -65,6 +65,82 @@ void ConnectionLoader::loadConnection()
|
|||||||
d->exec();
|
d->exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ConnectionLoader::loadProgress()
|
||||||
|
{
|
||||||
|
QTimer::singleShot(1, [=]() { this->ShowProgress(); });
|
||||||
|
if (!Settings::getInstance()->isHeadless())
|
||||||
|
d->exec();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConnectionLoader::ShowProgress()
|
||||||
|
{
|
||||||
|
|
||||||
|
auto config = std::shared_ptr<ConnectionConfig>(new ConnectionConfig());
|
||||||
|
config->dangerous = false;
|
||||||
|
config->server = Settings::getInstance()->getSettings().server;
|
||||||
|
auto connection = makeConnection(config);
|
||||||
|
auto me = this;
|
||||||
|
|
||||||
|
// After the lib is initialized, try to do get info
|
||||||
|
connection->doRPC("info", "", [=](auto reply) {
|
||||||
|
// If success, set the connection
|
||||||
|
main->logger->write("Connection is online.");
|
||||||
|
connection->setInfo(reply);
|
||||||
|
main->logger->write("getting Connection reply");
|
||||||
|
isSyncing = new QAtomicInteger<bool>();
|
||||||
|
isSyncing->store(true);
|
||||||
|
main->logger->write("isSyncing");
|
||||||
|
|
||||||
|
// Do a sync at startup
|
||||||
|
syncTimer = new QTimer(main);
|
||||||
|
main->logger->write("Beginning sync");
|
||||||
|
connection->doRPCWithDefaultErrorHandling("sync", "", [=](auto) {
|
||||||
|
isSyncing->store(false);
|
||||||
|
// Cancel the timer
|
||||||
|
syncTimer->deleteLater();
|
||||||
|
// When sync is done, set the connection
|
||||||
|
this->doRPCSetConnection(connection);
|
||||||
|
});
|
||||||
|
|
||||||
|
// While it is syncing, we'll show the status updates while it is alive.
|
||||||
|
QObject::connect(syncTimer, &QTimer::timeout, [=]() {
|
||||||
|
// Check the sync status
|
||||||
|
if (isSyncing != nullptr && isSyncing->load()) {
|
||||||
|
// Get the sync status
|
||||||
|
|
||||||
|
try {
|
||||||
|
connection->doRPC("syncstatus", "", [=](json reply) {
|
||||||
|
if (isSyncing != nullptr && reply.find("synced_blocks") != reply.end())
|
||||||
|
|
||||||
|
{
|
||||||
|
qint64 synced = reply["synced_blocks"].get<json::number_unsigned_t>();
|
||||||
|
qint64 total = reply["total_blocks"].get<json::number_unsigned_t>();
|
||||||
|
me->showInformation(
|
||||||
|
"Synced " + QString::number(synced) + " / " + QString::number(total)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[=](QString err) {
|
||||||
|
qDebug() << "Sync error" << err;
|
||||||
|
});
|
||||||
|
}catch (...)
|
||||||
|
{
|
||||||
|
main->logger->write("catch sync progress reply");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
syncTimer->setInterval(1* 1000);
|
||||||
|
syncTimer->start();
|
||||||
|
main->logger->write("Start sync timer");
|
||||||
|
|
||||||
|
}, [=](QString err) {
|
||||||
|
showError(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void ConnectionLoader::doAutoConnect()
|
void ConnectionLoader::doAutoConnect()
|
||||||
{
|
{
|
||||||
qDebug() << "Doing autoconnect";
|
qDebug() << "Doing autoconnect";
|
||||||
@@ -109,14 +185,14 @@ void ConnectionLoader::doAutoConnect()
|
|||||||
connection->setInfo(reply);
|
connection->setInfo(reply);
|
||||||
main->logger->write("getting Connection reply");
|
main->logger->write("getting Connection reply");
|
||||||
isSyncing = new QAtomicInteger<bool>();
|
isSyncing = new QAtomicInteger<bool>();
|
||||||
isSyncing->storeRelaxed(true);
|
isSyncing->store(true);
|
||||||
main->logger->write("isSyncing");
|
main->logger->write("isSyncing");
|
||||||
|
|
||||||
// Do a sync at startup
|
// Do a sync at startup
|
||||||
syncTimer = new QTimer(main);
|
syncTimer = new QTimer(main);
|
||||||
main->logger->write("Beginning sync");
|
main->logger->write("Beginning sync");
|
||||||
connection->doRPCWithDefaultErrorHandling("sync", "", [=](auto) {
|
connection->doRPCWithDefaultErrorHandling("sync", "", [=](auto) {
|
||||||
isSyncing->storeRelaxed(false);
|
isSyncing->store(false);
|
||||||
// Cancel the timer
|
// Cancel the timer
|
||||||
syncTimer->deleteLater();
|
syncTimer->deleteLater();
|
||||||
// When sync is done, set the connection
|
// When sync is done, set the connection
|
||||||
@@ -126,7 +202,7 @@ void ConnectionLoader::doAutoConnect()
|
|||||||
// While it is syncing, we'll show the status updates while it is alive.
|
// While it is syncing, we'll show the status updates while it is alive.
|
||||||
QObject::connect(syncTimer, &QTimer::timeout, [=]() {
|
QObject::connect(syncTimer, &QTimer::timeout, [=]() {
|
||||||
// Check the sync status
|
// Check the sync status
|
||||||
if (isSyncing != nullptr && isSyncing->loadRelaxed()) {
|
if (isSyncing != nullptr && isSyncing->load()) {
|
||||||
// Get the sync status
|
// Get the sync status
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -255,7 +331,6 @@ void Executor::run()
|
|||||||
emit responseReady(parsed);
|
emit responseReady(parsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Callback::processRPCCallback(json resp)
|
void Callback::processRPCCallback(json resp)
|
||||||
{
|
{
|
||||||
this->cb(resp);
|
this->cb(resp);
|
||||||
@@ -284,7 +359,10 @@ void Connection::doRPC(const QString cmd, const QString args, const std::functio
|
|||||||
// Ignoring RPC because shutdown in progress
|
// Ignoring RPC because shutdown in progress
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//qDebug() << "Doing RPC: " << cmd;
|
qDebug() << "Doing RPC: " << cmd;
|
||||||
|
qDebug() << "Args :"<< args;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Create a runner.
|
// Create a runner.
|
||||||
auto runner = new Executor(cmd, args);
|
auto runner = new Executor(cmd, args);
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ public:
|
|||||||
~ConnectionLoader();
|
~ConnectionLoader();
|
||||||
|
|
||||||
void loadConnection();
|
void loadConnection();
|
||||||
|
void loadProgress();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<ConnectionConfig> autoDetecthushConf();
|
std::shared_ptr<ConnectionConfig> autoDetecthushConf();
|
||||||
@@ -32,6 +33,7 @@ private:
|
|||||||
Connection* makeConnection(std::shared_ptr<ConnectionConfig> config);
|
Connection* makeConnection(std::shared_ptr<ConnectionConfig> config);
|
||||||
|
|
||||||
void doAutoConnect();
|
void doAutoConnect();
|
||||||
|
void ShowProgress();
|
||||||
|
|
||||||
void createOrRestore(bool dangerous, QString server);
|
void createOrRestore(bool dangerous, QString server);
|
||||||
|
|
||||||
@@ -83,6 +85,7 @@ public:
|
|||||||
Executor(QString cmd, QString args) {
|
Executor(QString cmd, QString args) {
|
||||||
this->cmd = cmd;
|
this->cmd = cmd;
|
||||||
this->args = args;
|
this->args = args;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
~Executor() = default;
|
~Executor() = default;
|
||||||
@@ -118,7 +121,9 @@ public:
|
|||||||
|
|
||||||
void doRPC(const QString cmd, const QString args, const std::function<void(json)>& cb,
|
void doRPC(const QString cmd, const QString args, const std::function<void(json)>& cb,
|
||||||
const std::function<void(QString)>& errCb);
|
const std::function<void(QString)>& errCb);
|
||||||
|
|
||||||
void doRPCWithDefaultErrorHandling(const QString cmd, const QString args, const std::function<void(json)>& cb);
|
void doRPCWithDefaultErrorHandling(const QString cmd, const QString args, const std::function<void(json)>& cb);
|
||||||
|
|
||||||
void doRPCIgnoreError(const QString cmd, const QString args, const std::function<void(json)>& cb) ;
|
void doRPCIgnoreError(const QString cmd, const QString args, const std::function<void(json)>& cb) ;
|
||||||
|
|
||||||
void showTxError(const QString& error);
|
void showTxError(const QString& error);
|
||||||
|
|||||||
@@ -154,9 +154,13 @@ public:
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void importZPrivKey(QString addr,const std::function<void(json)>& cb) {
|
||||||
// void importZPrivKey(QString addr, bool rescan, const std::function<void(json)>& cb) { zrpc->importZPrivKey(addr, rescan, cb); }
|
unlockIfEncrypted([=] () {
|
||||||
// void importTPrivKey(QString addr, bool rescan, const std::function<void(json)>& cb) { zrpc->importTPrivKey(addr, rescan, cb); }
|
zrpc->importZPrivKey(addr,cb);
|
||||||
|
}, [=](){});
|
||||||
|
}
|
||||||
|
void importZPrivKey(QString addr, const std::function<void(json)>& cb,const std::function<void(QString)>& err) { zrpc->importZPrivKey(addr, cb, ""); }
|
||||||
|
// void importTPrivKey(QString addr,bool rescan, const std::function<void(json)>& cb) { zrpc->importTPrivKey(addr,rescan, cb); }
|
||||||
|
|
||||||
QString getDefaultSaplingAddress();
|
QString getDefaultSaplingAddress();
|
||||||
QString getDefaultTAddress();
|
QString getDefaultTAddress();
|
||||||
|
|||||||
@@ -27,6 +27,33 @@ void LiteInterface::fetchAddresses(const std::function<void(json)>& cb) {
|
|||||||
conn->doRPCWithDefaultErrorHandling("addresses", "", cb);
|
conn->doRPCWithDefaultErrorHandling("addresses", "", cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LiteInterface::importZPrivKey(QString addr, const std::function<void(json)>& cb) {
|
||||||
|
if (conn == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// QString params = addr % QString(" ");
|
||||||
|
// params.append(birthday);
|
||||||
|
qDebug()<<addr;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
conn->doRPCWithDefaultErrorHandling("import", addr, cb);
|
||||||
|
// conn->doRPC("import", params, cb, err);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*void LiteInterface::importTPrivKey(QString addr, bool rescan, const std::function<void(json)>& cb) {
|
||||||
|
if (conn == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// conn->doRPCWithDefaultErrorHandling("import", addr, cb);
|
||||||
|
|
||||||
|
// conn->doRPC("import", addr, 0, cb);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
|
||||||
void LiteInterface::fetchUnspent(const std::function<void(json)>& cb) {
|
void LiteInterface::fetchUnspent(const std::function<void(json)>& cb) {
|
||||||
if (conn == nullptr)
|
if (conn == nullptr)
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ public:
|
|||||||
void unlockWallet(QString password, const std::function<void(json)>& cb);
|
void unlockWallet(QString password, const std::function<void(json)>& cb);
|
||||||
void removeWalletEncryption(QString password, const std::function<void(json)>& cb);
|
void removeWalletEncryption(QString password, const std::function<void(json)>& cb);
|
||||||
|
|
||||||
//void importZPrivKey(QString addr, bool rescan, const std::function<void(json)>& cb);
|
void importZPrivKey(QString addr, const std::function<void(json)>& cb);
|
||||||
//void importTPrivKey(QString addr, bool rescan, const std::function<void(json)>& cb);
|
//void importTPrivKey(QString addr, bool rescan, const std::function<void(json)>& cb);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -280,6 +280,8 @@ MainWindow::MainWindow(QWidget *parent) :
|
|||||||
dialog.exec();
|
dialog.exec();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Import Privkey
|
||||||
|
QObject::connect(ui->actionImport_Privatkey, &QAction::triggered, this, &MainWindow::importPrivKey);
|
||||||
// Address Book
|
// Address Book
|
||||||
QObject::connect(ui->action_Address_Book, &QAction::triggered, this, &MainWindow::addressBook);
|
QObject::connect(ui->action_Address_Book, &QAction::triggered, this, &MainWindow::addressBook);
|
||||||
|
|
||||||
@@ -930,30 +932,39 @@ void MainWindow::donate() {
|
|||||||
ui->tabWidget->setCurrentIndex(1);
|
ui->tabWidget->setCurrentIndex(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// void MainWindow::doImport(QList<QString>* keys) {
|
void MainWindow::doImport(QList<QString>* keys) {
|
||||||
// if (rpc->getConnection() == nullptr) {
|
if (rpc->getConnection() == nullptr) {
|
||||||
// // No connection, just return
|
// No connection, just return
|
||||||
// return;
|
return;
|
||||||
// }
|
}
|
||||||
|
|
||||||
// if (keys->isEmpty()) {
|
if (keys->isEmpty()) {
|
||||||
// delete keys;
|
delete keys;
|
||||||
// ui->statusBar->showMessage(tr("Private key import rescan finished"));
|
ui->statusBar->showMessage(tr("Private key import rescan finished"));
|
||||||
// return;
|
return;
|
||||||
// }
|
}
|
||||||
|
|
||||||
// // Pop the first key
|
// Pop the first key
|
||||||
// QString key = keys->first();
|
|
||||||
// keys->pop_front();
|
|
||||||
// bool rescan = keys->isEmpty();
|
|
||||||
|
|
||||||
// if (key.startsWith("SK") ||
|
QString key = keys->first();
|
||||||
// key.startsWith("secret")) { // Z key
|
QString key1 = key + QString(" ") + QString("0");
|
||||||
// rpc->importZPrivKey(key, rescan, [=] (auto) { this->doImport(keys); });
|
keys->pop_front();
|
||||||
// } else {
|
bool rescan = keys->isEmpty();
|
||||||
// rpc->importTPrivKey(key, rescan, [=] (auto) { this->doImport(keys); });
|
|
||||||
// }
|
|
||||||
// }
|
if (key.startsWith("SK") ||
|
||||||
|
key.startsWith("secret")) { // Z key
|
||||||
|
|
||||||
|
rpc->importZPrivKey(key, [=] (auto) { this->doImport(keys); });
|
||||||
|
|
||||||
|
// Then reload the connection. The ConnectionLoader deletes itself.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
rpc->importTPrivKey(key, rescan, [=] (auto) { this->doImport(keys); });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Callback invoked when the RPC has finished loading all the balances, and the UI
|
// Callback invoked when the RPC has finished loading all the balances, and the UI
|
||||||
@@ -1041,51 +1052,56 @@ void MainWindow::payhushURI(QString uri, QString myAddr) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::importPrivKey() {
|
||||||
|
QDialog d(this);
|
||||||
|
Ui_PrivKey pui;
|
||||||
|
pui.setupUi(&d);
|
||||||
|
Settings::saveRestore(&d);
|
||||||
|
|
||||||
// void MainWindow::importPrivKey() {
|
pui.buttonBox->button(QDialogButtonBox::Save)->setVisible(true);
|
||||||
// QDialog d(this);
|
pui.helpLbl->setText(QString() %
|
||||||
// Ui_PrivKey pui;
|
tr("Please paste your private key(z-Addr) here, one per import") % ".\n" %
|
||||||
// pui.setupUi(&d);
|
tr("Caution: These key will be NOT inlcude in your Seed. Please send them direct to a Seed zaddr") % ".\n" %
|
||||||
// Settings::saveRestore(&d);
|
tr("The import of your Privatkey will take some time.")
|
||||||
|
);
|
||||||
|
|
||||||
// pui.buttonBox->button(QDialogButtonBox::Save)->setVisible(false);
|
if (d.exec() == QDialog::Accepted && !pui.privKeyTxt->toPlainText().trimmed().isEmpty()) {
|
||||||
// pui.helpLbl->setText(QString() %
|
auto rawkeys = pui.privKeyTxt->toPlainText().trimmed().split("\n");
|
||||||
// tr("Please paste your private keys (z-Addr or t-Addr) here, one per line") % ".\n" %
|
|
||||||
// tr("The keys will be imported into your connected hushd node"));
|
|
||||||
|
|
||||||
// if (d.exec() == QDialog::Accepted && !pui.privKeyTxt->toPlainText().trimmed().isEmpty()) {
|
QList<QString> keysTmp;
|
||||||
// auto rawkeys = pui.privKeyTxt->toPlainText().trimmed().split("\n");
|
// Filter out all the empty keys.
|
||||||
|
std::copy_if(rawkeys.begin(), rawkeys.end(), std::back_inserter(keysTmp), [=] (auto key) {
|
||||||
|
return !key.startsWith("#") && !key.trimmed().isEmpty();
|
||||||
|
});
|
||||||
|
|
||||||
// QList<QString> keysTmp;
|
auto keys = new QList<QString>();
|
||||||
// // Filter out all the empty keys.
|
std::transform(keysTmp.begin(), keysTmp.end(), std::back_inserter(*keys), [=](auto key) {
|
||||||
// std::copy_if(rawkeys.begin(), rawkeys.end(), std::back_inserter(keysTmp), [=] (auto key) {
|
return key.trimmed().split(" ")[0];
|
||||||
// return !key.startsWith("#") && !key.trimmed().isEmpty();
|
});
|
||||||
// });
|
|
||||||
|
|
||||||
// auto keys = new QList<QString>();
|
// Special case.
|
||||||
// std::transform(keysTmp.begin(), keysTmp.end(), std::back_inserter(*keys), [=](auto key) {
|
// Sometimes, when importing from a paperwallet or such, the key is split by newlines, and might have
|
||||||
// return key.trimmed().split(" ")[0];
|
// been pasted like that. So check to see if the whole thing is one big private key
|
||||||
// });
|
if (Settings::getInstance()->isValidSaplingPrivateKey(keys->join(""))) {
|
||||||
|
auto multiline = keys;
|
||||||
|
keys = new QList<QString>();
|
||||||
|
keys->append(multiline->join(""));
|
||||||
|
delete multiline;
|
||||||
|
}
|
||||||
|
|
||||||
// // Special case.
|
// Start the import. The function takes ownership of keys
|
||||||
// // Sometimes, when importing from a paperwallet or such, the key is split by newlines, and might have
|
QTimer::singleShot(1, [=]() {doImport(keys);});
|
||||||
// // been pasted like that. So check to see if the whole thing is one big private key
|
|
||||||
// if (Settings::getInstance()->isValidSaplingPrivateKey(keys->join(""))) {
|
|
||||||
// auto multiline = keys;
|
|
||||||
// keys = new QList<QString>();
|
|
||||||
// keys->append(multiline->join(""));
|
|
||||||
// delete multiline;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Start the import. The function takes ownership of keys
|
auto cl = new ConnectionLoader(this, rpc);
|
||||||
// QTimer::singleShot(1, [=]() {doImport(keys);});
|
QTimer::singleShot(1, [=]() { cl->loadProgress(); });
|
||||||
|
|
||||||
// // Show the dialog that keys will be imported.
|
|
||||||
// QMessageBox::information(this,
|
// Show the dialog that keys will be imported.
|
||||||
// "Imported", tr("The keys were imported. It may take several minutes to rescan the blockchain. Until then, functionality may be limited"),
|
// QMessageBox::information(this,
|
||||||
// QMessageBox::Ok);
|
// "Imported", tr("The keys were imported. It may take several minutes to rescan the blockchain. Until then, functionality may be limited"),
|
||||||
// }
|
// QMessageBox::Ok);
|
||||||
// }
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Export transaction history into a CSV file
|
* Export transaction history into a CSV file
|
||||||
|
|||||||
@@ -1894,6 +1894,7 @@
|
|||||||
<addaction name="actionRemove_Wallet_Encryption"/>
|
<addaction name="actionRemove_Wallet_Encryption"/>
|
||||||
<addaction name="separator"/>
|
<addaction name="separator"/>
|
||||||
<addaction name="actionRescan"/>
|
<addaction name="actionRescan"/>
|
||||||
|
<addaction name="actionImport_Privatkey"/>
|
||||||
</widget>
|
</widget>
|
||||||
<addaction name="menuFile"/>
|
<addaction name="menuFile"/>
|
||||||
<addaction name="menu_Edit"/>
|
<addaction name="menu_Edit"/>
|
||||||
@@ -2005,6 +2006,11 @@
|
|||||||
<string>Rescan</string>
|
<string>Rescan</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="actionImport_Privatkey">
|
||||||
|
<property name="text">
|
||||||
|
<string>Import Privatkey</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<layoutdefault spacing="6" margin="11"/>
|
<layoutdefault spacing="6" margin="11"/>
|
||||||
<customwidgets>
|
<customwidgets>
|
||||||
|
|||||||
Reference in New Issue
Block a user