aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--LeftPanel.qml2
-rw-r--r--MiddlePanel.qml3
-rw-r--r--main.qml75
-rw-r--r--pages/TxKey.qml233
-rw-r--r--src/libwalletqt/Wallet.cpp30
-rw-r--r--src/libwalletqt/Wallet.h3
-rw-r--r--src/libwalletqt/WalletManager.cpp10
-rw-r--r--src/libwalletqt/WalletManager.h2
8 files changed, 255 insertions, 103 deletions
diff --git a/LeftPanel.qml b/LeftPanel.qml
index e9fa7467..06881a9d 100644
--- a/LeftPanel.qml
+++ b/LeftPanel.qml
@@ -424,7 +424,7 @@ Rectangle {
id: txkeyButton
anchors.left: parent.left
anchors.right: parent.right
- text: qsTr("Check payment") + translationManager.emptyString
+ text: qsTr("Prove/check") + translationManager.emptyString
symbol: qsTr("K") + translationManager.emptyString
dotColor: "#FFD781"
under: advancedButton
diff --git a/MiddlePanel.qml b/MiddlePanel.qml
index a008a62a..25fc3170 100644
--- a/MiddlePanel.qml
+++ b/MiddlePanel.qml
@@ -65,7 +65,8 @@ Rectangle {
signal paymentClicked(string address, string paymentId, string amount, int mixinCount, int priority, string description)
signal sweepUnmixableClicked()
signal generatePaymentIdInvoked()
- signal checkPaymentClicked(string address, string txid, string txkey);
+ signal getTxProofClicked(string txid, string address, string message);
+ signal checkTxProofClicked(string txid, string address, string message, string signature);
color: "#F0EEEE"
diff --git a/main.qml b/main.qml
index ae94f86a..d9916036 100644
--- a/main.qml
+++ b/main.qml
@@ -243,7 +243,8 @@ ApplicationWindow {
currentWallet.connectionStatusChanged.disconnect(onWalletConnectionStatusChanged)
middlePanel.paymentClicked.disconnect(handlePayment);
middlePanel.sweepUnmixableClicked.disconnect(handleSweepUnmixable);
- middlePanel.checkPaymentClicked.disconnect(handleCheckPayment);
+ middlePanel.getTxProofClicked.disconnect(handleGetTxProof);
+ middlePanel.checkTxProofClicked.disconnect(handleCheckTxProof);
}
currentWallet = undefined;
@@ -275,7 +276,8 @@ ApplicationWindow {
currentWallet.connectionStatusChanged.connect(onWalletConnectionStatusChanged)
middlePanel.paymentClicked.connect(handlePayment);
middlePanel.sweepUnmixableClicked.connect(handleSweepUnmixable);
- middlePanel.checkPaymentClicked.connect(handleCheckPayment);
+ middlePanel.getTxProofClicked.connect(handleGetTxProof);
+ middlePanel.checkTxProofClicked.connect(handleCheckTxProof);
console.log("Recovering from seed: ", persistentSettings.is_recovering)
@@ -755,38 +757,54 @@ ApplicationWindow {
currentWallet.store();
}
- // called on "checkPayment"
- function handleCheckPayment(address, txid, txkey) {
- console.log("Checking payment: ")
- console.log("\taddress: ", address,
- ", txid: ", txid,
- ", txkey: ", txkey);
+ // called on "getTxProof"
+ function handleGetTxProof(txid, address, message) {
+ console.log("Getting payment proof: ")
+ console.log("\ttxid: ", txid,
+ ", address: ", address,
+ ", message: ", message);
- var result = walletManager.checkPayment(address, txid, txkey, currentDaemonAddress);
- var results = result.split("|");
- if (results.length < 4) {
- informationPopup.title = qsTr("Error") + translationManager.emptyString;
- informationPopup.text = "internal error";
- informationPopup.icon = StandardIcon.Critical
- informationPopup.onCloseCallback = null
- informationPopup.open()
- return
+ var result = currentWallet.getTxProof(txid, address, message);
+ informationPopup.title = qsTr("Payment proof") + translationManager.emptyString;
+ if (result.startsWith("error|")) {
+ var errorString = result.split("|")[1];
+ informationPopup.text = qsTr("Couldn't generate a proof because of the following reason: \n") + errorString + translationManager.emptyString;
+ informationPopup.icon = StandardIcon.Critical;
+ } else {
+ informationPopup.text = result;
+ informationPopup.icon = StandardIcon.Critical;
}
- var success = results[0] == "true";
- var received = results[1]
- var height = results[2]
- var error = results[3]
- if (success) {
- informationPopup.title = qsTr("Payment check") + translationManager.emptyString;
+ informationPopup.onCloseCallback = null
+ informationPopup.open()
+ }
+
+ // called on "checkTxProof"
+ function handleCheckTxProof(txid, address, message, signature) {
+ console.log("Checking payment proof: ")
+ console.log("\ttxid: ", txid,
+ ", address: ", address,
+ ", message: ", message,
+ ", signature: ", signature);
+
+ var result = currentWallet.checkTxProof(txid, address, message, signature);
+ var results = result.split("|");
+ if (results.length == 5 && results[0] == "true") {
+ var good = results[1] == "true";
+ var received = results[2];
+ var in_pool = results[3] == "true";
+ var confirmations = results[4];
+
+ informationPopup.title = qsTr("Payment proof check") + translationManager.emptyString;
informationPopup.icon = StandardIcon.Information
- if (received > 0) {
+ if (!good) {
+ informationPopup.text = qsTr("Bad signature");
+ informationPopup.icon = StandardIcon.Critical;
+ } else if (received > 0) {
received = received / 1e12
- if (height == 0) {
+ if (in_pool) {
informationPopup.text = qsTr("This address received %1 monero, but the transaction is not yet mined").arg(received);
}
else {
- var dCurrentBlock = currentWallet.daemonBlockChainHeight();
- var confirmations = dCurrentBlock - height
informationPopup.text = qsTr("This address received %1 monero, with %2 confirmation(s).").arg(received).arg(confirmations);
}
}
@@ -796,9 +814,10 @@ ApplicationWindow {
}
else {
informationPopup.title = qsTr("Error") + translationManager.emptyString;
- informationPopup.text = error;
+ informationPopup.text = currentWallet.errorString;
informationPopup.icon = StandardIcon.Critical
}
+ informationPopup.onCloseCallback = null
informationPopup.open()
}
diff --git a/pages/TxKey.qml b/pages/TxKey.qml
index b51feea5..5bfeaac1 100644
--- a/pages/TxKey.qml
+++ b/pages/TxKey.qml
@@ -37,9 +37,6 @@ import moneroComponents.Clipboard 1.0
Rectangle {
color: "#F0EEEE"
- property alias addressText : addressLine.text
- property alias txIdText : txIdLine.text
- property alias txKeyText : txKeyLine.text
Clipboard { id: clipboard }
@@ -47,10 +44,10 @@ Rectangle {
return walletManager.addressValid(address, testnet)
}
- function check256(str) {
- if (str.length != 64)
+ function check256(str, length) {
+ if (str.length != length)
return false;
- for (var i = 0; i < 64; ++i) {
+ for (var i = 0; i < length; ++i) {
if (str[i] >= '0' && str[i] <= '9')
continue;
if (str[i] >= 'a' && str[i] <= 'z')
@@ -63,11 +60,12 @@ Rectangle {
}
function checkTxID(txid) {
- return check256(txid)
+ return check256(txid, 64)
}
- function checkTxKey(txid) {
- return check256(txid)
+ function checkSignature(signature) {
+ return signature.startsWith("OutProofV") && check256(signature, 142) ||
+ signature.startsWith("InProofV") && check256(signature, 141)
}
/* main layout */
@@ -83,61 +81,59 @@ Rectangle {
property int editWidth: 400
property int lineEditFontSize: 12
+ Text {
+ text: qsTr("Generate a proof of your incoming/outgoing payment by supplying the transaction ID, the recipient address and an optional message:") + translationManager.emptyString
+ wrapMode: Text.Wrap
+ Layout.fillWidth: true;
+ }
+
RowLayout {
- ColumnLayout {
+ Label {
+ fontSize: 14
+ text: qsTr("Transaction ID") + translationManager.emptyString
+ width: mainLayout.labelWidth
+ }
- Text {
- text: qsTr("Verify that a third party made a payment by supplying:") + translationManager.emptyString
- wrapMode: Text.Wrap
- Layout.fillWidth: true;
- }
- Text {
- text: qsTr(" - the recipient address") + translationManager.emptyString
- wrapMode: Text.Wrap
- Layout.fillWidth: true;
- }
- Text {
- text: qsTr(" - the transaction ID") + translationManager.emptyString
- wrapMode: Text.Wrap
- Layout.fillWidth: true;
- }
- Text {
- text: qsTr(" - the secret transaction key supplied by the sender") + translationManager.emptyString
- wrapMode: Text.Wrap
- Layout.fillWidth: true;
- }
- Text {
- text: qsTr("If a payment had several transactions then each must be checked and the results combined.") + translationManager.emptyString
- wrapMode: Text.Wrap
- Layout.fillWidth: true;
+ LineEdit {
+ id: getProofTxIdLine
+ fontSize: mainLayout.lineEditFontSize
+ placeholderText: qsTr("Paste tx ID") + translationManager.emptyString
+ readOnly: false
+ width: mainLayout.editWidth
+ Layout.fillWidth: true
+
+ IconButton {
+ imageSource: "../images/copyToClipboard.png"
+ onClicked: {
+ if (getProofTxIdLine.text.length > 0) {
+ clipboard.setText(getProofTxIdLine.text)
+ }
+ }
}
+
}
}
RowLayout {
- id: addressRow
-
Label {
- id: addressLabel
fontSize: 14
text: qsTr("Address") + translationManager.emptyString
width: mainLayout.labelWidth
}
LineEdit {
- id: addressLine
+ id: getProofAddressLine
fontSize: mainLayout.lineEditFontSize
placeholderText: qsTr("Recipient's wallet address") + translationManager.emptyString;
readOnly: false
width: mainLayout.editWidth
Layout.fillWidth: true
- onTextChanged: cursorPosition = 0
IconButton {
imageSource: "../images/copyToClipboard.png"
onClicked: {
- if (addressLine.text.length > 0) {
- clipboard.setText(addressLine.text)
+ if (getProofAddressLine.text.length > 0) {
+ clipboard.setText(getProofAddressLine.text)
}
}
}
@@ -145,52 +141,154 @@ Rectangle {
}
RowLayout {
- id: txIdRow
Label {
- id: txIdLabel
fontSize: 14
- text: qsTr("Transaction ID") + translationManager.emptyString
+ text: qsTr("Message") + translationManager.emptyString
width: mainLayout.labelWidth
}
-
LineEdit {
+ id: getProofMessageLine
+ fontSize: mainLayout.lineEditFontSize
+ placeholderText: qsTr("Optional message against which the signature is signed") + translationManager.emptyString;
+ readOnly: false
+ width: mainLayout.editWidth
+ Layout.fillWidth: true
+
+ IconButton {
+ imageSource: "../images/copyToClipboard.png"
+ onClicked: {
+ if (getProofMessageLine.text.length > 0) {
+ clipboard.setText(getProofMessageLine.text)
+ }
+ }
+ }
+ }
+ }
+
+ StandardButton {
+ anchors.left: parent.left
+ anchors.topMargin: 17
+ width: 60
+ text: qsTr("Generate") + translationManager.emptyString
+ shadowReleasedColor: "#FF4304"
+ shadowPressedColor: "#B32D00"
+ releasedColor: "#FF6C3C"
+ pressedColor: "#FF4304"
+ enabled: checkTxID(getProofTxIdLine.text) && checkAddress(getProofAddressLine.text, appWindow.persistentSettings.testnet)
+ onClicked: {
+ console.log("getProof: Generate clicked: txid " + getProofTxIdLine.text + ", address " + getProofAddressLine.text + ", message: " + getProofMessageLine.text);
+ root.getProofClicked(getProofTxIdLine.text, getProofAddressLine.text, getProofMessageLine.text)
+ }
+ }
+
+ // underline
+ Rectangle {
+ height: 1
+ color: "#DBDBDB"
+ Layout.fillWidth: true
+ Layout.alignment: Qt.AlignHCenter
+ anchors.bottomMargin: 3
+
+ }
+
+ Text {
+ text: qsTr("Verify that funds were paid to an address by supplying the transaction ID, the recipient address, the message used for signing and the signature:") + translationManager.emptyString
+ wrapMode: Text.Wrap
+ Layout.fillWidth: true;
+ }
+
+ RowLayout {
+ Label {
+ fontSize: 14
+ text: qsTr("Transaction ID") + translationManager.emptyString
+ width: mainLayout.labelWidth
+ }
- id: txIdLine
+ LineEdit {
+ id: checkProofTxIdLine
fontSize: mainLayout.lineEditFontSize
placeholderText: qsTr("Paste tx ID") + translationManager.emptyString
readOnly: false
width: mainLayout.editWidth
Layout.fillWidth: true
- onTextChanged: cursorPosition = 0
+ IconButton {
+ imageSource: "../images/copyToClipboard.png"
+ onClicked: {
+ if (checkProofTxIdLine.text.length > 0) {
+ clipboard.setText(checkProofTxIdLine.text)
+ }
+ }
+ }
+
+ }
+ }
+
+ RowLayout {
+ Label {
+ fontSize: 14
+ text: qsTr("Address") + translationManager.emptyString
+ width: mainLayout.labelWidth
+ }
+
+ LineEdit {
+ id: checkProofAddressLine
+ fontSize: mainLayout.lineEditFontSize
+ placeholderText: qsTr("Recipient's wallet address") + translationManager.emptyString;
+ readOnly: false
+ width: mainLayout.editWidth
+ Layout.fillWidth: true
IconButton {
imageSource: "../images/copyToClipboard.png"
onClicked: {
- if (txIdLine.text.length > 0) {
- clipboard.setText(txIdLine.text)
+ if (checkProofAddressLine.text.length > 0) {
+ clipboard.setText(checkProofAddressLine.text)
}
}
}
+ }
+ }
+
+ RowLayout {
+ Label {
+ fontSize: 14
+ text: qsTr("Message") + translationManager.emptyString
+ width: mainLayout.labelWidth
+ }
+
+ LineEdit {
+ id: checkProofMessageLine
+ fontSize: mainLayout.lineEditFontSize
+ placeholderText: qsTr("Optional message against which the signature is signed") + translationManager.emptyString;
+ readOnly: false
+ width: mainLayout.editWidth
+ Layout.fillWidth: true
+ IconButton {
+ imageSource: "../images/copyToClipboard.png"
+ onClicked: {
+ if (checkProofMessageLine.text.length > 0) {
+ clipboard.setText(checkProofMessageLine.text)
+ }
+ }
+ }
}
}
RowLayout {
- id: txKeyRow
Label {
- id: paymentIdLabel
fontSize: 14
- text: qsTr("Transaction key") + translationManager.emptyString
+ text: qsTr("Signature") + translationManager.emptyString
width: mainLayout.labelWidth
}
LineEdit {
- id: txKeyLine
+ id: checkProofSignatureLine
fontSize: mainLayout.lineEditFontSize
- placeholderText: qsTr("Paste tx key") + translationManager.emptyString;
+ placeholderText: qsTr("Paste tx proof") + translationManager.emptyString;
readOnly: false
width: mainLayout.editWidth
@@ -199,8 +297,8 @@ Rectangle {
IconButton {
imageSource: "../images/copyToClipboard.png"
onClicked: {
- if (TxKeyLine.text.length > 0) {
- clipboard.setText(TxKeyLine.text)
+ if (checkProofSignatureLine.text.length > 0) {
+ clipboard.setText(checkProofSignatureLine.text)
}
}
}
@@ -208,9 +306,7 @@ Rectangle {
}
StandardButton {
- id: checkButton
anchors.left: parent.left
- anchors.top: txKeyRow.bottom
anchors.topMargin: 17
width: 60
text: qsTr("Check") + translationManager.emptyString
@@ -218,13 +314,28 @@ Rectangle {
shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C"
pressedColor: "#FF4304"
- enabled: checkAddress(addressLine.text, appWindow.persistentSettings.testnet) && checkTxID(txIdLine.text) && checkTxKey(txKeyLine.text)
+ enabled: checkTxID(checkProofTxIdLine.text) && checkAddress(checkProofAddressLine.text, appWindow.persistentSettings.testnet) && checkSignature(checkProofSignatureLine.text)
onClicked: {
- console.log("TxKey: Check clicked: address " + addressLine.text + ", txid " << txIdLine.text + ", tx key " + txKeyLine.text);
- root.checkPaymentClicked(addressLine.text, txIdLine.text, txKeyLine.text)
+ console.log("checkProof: Check clicked: txid " + checkProofTxIdLine.text + ", address " + checkProofAddressLine.text + ", message " + checkProofMessageLine.text + ", signature " + checkProofSignatureLine.text);
+ root.checkProofClicked(checkProofTxIdLine.text, checkProofAddressLine.text, checkProofMessageLine.text, checkProofSignatureLine.text)
}
}
+ // underline
+ Rectangle {
+ height: 1
+ color: "#DBDBDB"
+ Layout.fillWidth: true
+ Layout.alignment: Qt.AlignHCenter
+ anchors.bottomMargin: 3
+
+ }
+
+ Text {
+ text: qsTr("If a payment had several transactions then each must be checked and the results combined.") + translationManager.emptyString
+ wrapMode: Text.Wrap
+ Layout.fillWidth: true;
+ }
}
function onPageCompleted() {
diff --git a/src/libwalletqt/Wallet.cpp b/src/libwalletqt/Wallet.cpp
index e5ffef82..38702e23 100644
--- a/src/libwalletqt/Wallet.cpp
+++ b/src/libwalletqt/Wallet.cpp
@@ -494,6 +494,36 @@ QString Wallet::getTxKey(const QString &txid) const
return QString::fromStdString(m_walletImpl->getTxKey(txid.toStdString()));
}
+QString Wallet::checkTxKey(const QString &txid, const QString &tx_key, const QString &address)
+{
+ uint64_t received;
+ bool in_pool;
+ uint64_t confirmations;
+ bool success = m_walletImpl->checkTxKey(txid.toStdString(), tx_key.toStdString(), address.toStdString(), received, in_pool, confirmations);
+ std::string result = std::string(success ? "true" : "false") + "|" + QString::number(received).toStdString() + "|" + std::string(in_pool ? "true" : "false") + "|" + QString::number(confirmations).toStdString();
+ return QString::fromStdString(result);
+}
+
+QString Wallet::getTxProof(const QString &txid, const QString &address, const QString &message) const
+{
+ std::string error_str;
+ QString result = QString::fromStdString(m_walletImpl->getTxProof(txid.toStdString(), address.toStdString(), message.toStdString(), error_str));
+ if (!error_str.empty())
+ result = QString::fromStdString("error|" + error_str);
+ return result;
+}
+
+QString Wallet::checkTxProof(const QString &txid, const QString &address, const QString &message, const QString &signature)
+{
+ bool good;
+ uint64_t received;
+ bool in_pool;
+ uint64_t confirmations;
+ bool success = m_walletImpl->checkTxProof(txid.toStdString(), address.toStdString(), message.toStdString(), signature.toStdString(), good, received, in_pool, confirmations);
+ std::string result = std::string(success ? "true" : "false") + "|" + std::string(good ? "true" : "false") + "|" + QString::number(received).toStdString() + "|" + std::string(in_pool ? "true" : "false") + "|" + QString::number(confirmations).toStdString();
+ return QString::fromStdString(result);
+}
+
QString Wallet::signMessage(const QString &message, bool filename) const
{
if (filename) {
diff --git a/src/libwalletqt/Wallet.h b/src/libwalletqt/Wallet.h
index adc7d338..c653b8df 100644
--- a/src/libwalletqt/Wallet.h
+++ b/src/libwalletqt/Wallet.h
@@ -232,6 +232,9 @@ public:
Q_INVOKABLE bool setUserNote(const QString &txid, const QString &note);
Q_INVOKABLE QString getUserNote(const QString &txid) const;
Q_INVOKABLE QString getTxKey(const QString &txid) const;
+ Q_INVOKABLE QString checkTxKey(const QString &txid, const QString &tx_key, const QString &address);
+ Q_INVOKABLE QString getTxProof(const QString &txid, const QString &address, const QString &message) const;
+ Q_INVOKABLE QString checkTxProof(const QString &txid, const QString &address, const QString &message, const QString &signature);
// Rescan spent outputs
Q_INVOKABLE bool rescanSpent();
diff --git a/src/libwalletqt/WalletManager.cpp b/src/libwalletqt/WalletManager.cpp
index a8346478..3d9501ce 100644
--- a/src/libwalletqt/WalletManager.cpp
+++ b/src/libwalletqt/WalletManager.cpp
@@ -216,16 +216,6 @@ QString WalletManager::paymentIdFromAddress(const QString &address, bool testnet
return QString::fromStdString(Monero::Wallet::paymentIdFromAddress(address.toStdString(), testnet));
}
-QString WalletManager::checkPayment(const QString &address, const QString &txid, const QString &txkey, const QString &daemon_address) const
-{
- uint64_t received = 0, height = 0;
- std::string error = "";
- bool ret = m_pimpl->checkPayment(address.toStdString(), txid.toStdString(), txkey.toStdString(), daemon_address.toStdString(), received, height, error);
- // bypass qml being unable to pass structures without preposterous complexity
- std::string result = std::string(ret ? "true" : "false") + "|" + QString::number(received).toStdString() + "|" + QString::number(height).toStdString() + "|" + error;
- return QString::fromStdString(result);
-}
-
void WalletManager::setDaemonAddress(const QString &address)
{
m_pimpl->setDaemonAddress(address.toStdString());
diff --git a/src/libwalletqt/WalletManager.h b/src/libwalletqt/WalletManager.h
index 69c63b05..4598e07a 100644
--- a/src/libwalletqt/WalletManager.h
+++ b/src/libwalletqt/WalletManager.h
@@ -104,8 +104,6 @@ public:
Q_INVOKABLE QString paymentIdFromAddress(const QString &address, bool testnet) const;
- Q_INVOKABLE QString checkPayment(const QString &address, const QString &txid, const QString &txkey, const QString &daemon_address) const;
-
Q_INVOKABLE void setDaemonAddress(const QString &address);
Q_INVOKABLE bool connected() const;
Q_INVOKABLE quint64 networkDifficulty() const;