Add sendTx to RPC
This commit is contained in:
@@ -39,6 +39,7 @@ public:
|
|||||||
|
|
||||||
void updateLabelsAutoComplete();
|
void updateLabelsAutoComplete();
|
||||||
|
|
||||||
|
QString doSendTxValidations(Tx tx);
|
||||||
void setDefaultPayFrom();
|
void setDefaultPayFrom();
|
||||||
RPC* getRPC() { return rpc; }
|
RPC* getRPC() { return rpc; }
|
||||||
|
|
||||||
@@ -85,9 +86,7 @@ private:
|
|||||||
|
|
||||||
void memoButtonClicked(int number, bool includeReplyTo = false);
|
void memoButtonClicked(int number, bool includeReplyTo = false);
|
||||||
void setMemoEnabled(int number, bool enabled);
|
void setMemoEnabled(int number, bool enabled);
|
||||||
|
|
||||||
QString doSendTxValidations(Tx tx);
|
|
||||||
|
|
||||||
void donate();
|
void donate();
|
||||||
void addressBook();
|
void addressBook();
|
||||||
void payZcashURI();
|
void payZcashURI();
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
#include "websockets.h"
|
#include "websockets.h"
|
||||||
|
|
||||||
#include "rpc.h"
|
#include "rpc.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
|
||||||
@@ -88,6 +88,9 @@ QJsonDocument AppDataServer::processMessage(QString message, MainWindow* mainWin
|
|||||||
else if (msg.object()["command"] == "getTransactions") {
|
else if (msg.object()["command"] == "getTransactions") {
|
||||||
return processGetTransactions(mainWindow);
|
return processGetTransactions(mainWindow);
|
||||||
}
|
}
|
||||||
|
else if (msg.object()["command"] == "sendTx") {
|
||||||
|
return processSendTx(msg.object()["tx"].toObject(), mainWindow);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
return QJsonDocument(QJsonObject{
|
return QJsonDocument(QJsonObject{
|
||||||
{"errorCode", -1},
|
{"errorCode", -1},
|
||||||
@@ -96,6 +99,79 @@ QJsonDocument AppDataServer::processMessage(QString message, MainWindow* mainWin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QJsonDocument AppDataServer::processSendTx(QJsonObject sendTx, MainWindow* mainwindow) {
|
||||||
|
auto error = [=](QString reason) -> QJsonDocument {
|
||||||
|
return QJsonDocument(QJsonObject{
|
||||||
|
{"errorCode", -1},
|
||||||
|
{"errorMessage", "Couldn't send Tx:" + reason}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create a Tx Object
|
||||||
|
Tx tx;
|
||||||
|
tx.fee = Settings::getMinerFee();
|
||||||
|
|
||||||
|
// Find a from address that has at least the sending amout
|
||||||
|
double amt = sendTx["amount"].toDouble();
|
||||||
|
auto allBalances = mainwindow->getRPC()->getAllBalances();
|
||||||
|
QList<QPair<QString, double>> bals;
|
||||||
|
for (auto i : allBalances->keys()) {
|
||||||
|
// Filter out sprout Txns
|
||||||
|
if (Settings::getInstance()->isSproutAddress(i))
|
||||||
|
continue;
|
||||||
|
bals.append(QPair<QString, double>(i, allBalances->value(i)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bals.isEmpty()) {
|
||||||
|
return error("No sapling or transparent addresses");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::sort(bals.begin(), bals.end(), [=](const QPair<QString, double>a, const QPair<QString, double> b) ->bool {
|
||||||
|
// If same type, sort by amount
|
||||||
|
if (a.first[0] == b.first[0]) {
|
||||||
|
return a.second > b.second;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return a > b;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (amt > bals[0].second) {
|
||||||
|
// There isn't any any address capable of sending the Tx.
|
||||||
|
return error("Amount exceeds the balance of your largest address.");
|
||||||
|
}
|
||||||
|
|
||||||
|
tx.fromAddr = bals[0].first;
|
||||||
|
tx.toAddrs = { ToFields{ sendTx["to"].toString(), amt, sendTx["memo"].toString(), sendTx["memo"].toString().toUtf8().toHex()} };
|
||||||
|
|
||||||
|
// TODO: Respect the autoshield change setting
|
||||||
|
|
||||||
|
QString validation = mainwindow->doSendTxValidations(tx);
|
||||||
|
if (!validation.isEmpty()) {
|
||||||
|
return error(validation);
|
||||||
|
}
|
||||||
|
|
||||||
|
json params = json::array();
|
||||||
|
mainwindow->getRPC()->fillTxJsonParams(params, tx);
|
||||||
|
std::cout << std::setw(2) << params << std::endl;
|
||||||
|
|
||||||
|
// And send the Tx
|
||||||
|
mainwindow->getRPC()->sendZTransaction(params, [=](const json& reply) {
|
||||||
|
QString opid = QString::fromStdString(reply.get<json::string_t>());
|
||||||
|
|
||||||
|
// And then start monitoring the transaction
|
||||||
|
mainwindow->getRPC()->addNewTxToWatch(tx, opid);
|
||||||
|
|
||||||
|
// TODO: Handle the error if the computed Tx fails.
|
||||||
|
});
|
||||||
|
|
||||||
|
return QJsonDocument(QJsonObject{
|
||||||
|
{"version", 1.0},
|
||||||
|
{"command", "sendTx"},
|
||||||
|
{"result", "success"}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
QJsonDocument AppDataServer::processGetInfo(MainWindow* mainWindow) {
|
QJsonDocument AppDataServer::processGetInfo(MainWindow* mainWindow) {
|
||||||
return QJsonDocument(QJsonObject{
|
return QJsonDocument(QJsonObject{
|
||||||
{"version", 1.0},
|
{"version", 1.0},
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ private:
|
|||||||
|
|
||||||
class AppDataServer {
|
class AppDataServer {
|
||||||
public:
|
public:
|
||||||
|
static QJsonDocument processSendTx(QJsonObject sendTx, MainWindow* mainwindow);
|
||||||
static QJsonDocument processMessage(QString message, MainWindow* mainWindow);
|
static QJsonDocument processMessage(QString message, MainWindow* mainWindow);
|
||||||
static QJsonDocument processGetInfo(MainWindow* mainWindow);
|
static QJsonDocument processGetInfo(MainWindow* mainWindow);
|
||||||
static QJsonDocument processGetTransactions(MainWindow* mainWindow);
|
static QJsonDocument processGetTransactions(MainWindow* mainWindow);
|
||||||
|
|||||||
Reference in New Issue
Block a user