Auto shielding for t Addresses
This commit is contained in:
@@ -387,6 +387,9 @@ void MainWindow::setupSettingsModal() {
|
|||||||
// Custom fees
|
// Custom fees
|
||||||
settings.chkCustomFees->setChecked(Settings::getInstance()->getAllowCustomFees());
|
settings.chkCustomFees->setChecked(Settings::getInstance()->getAllowCustomFees());
|
||||||
|
|
||||||
|
// Auto shielding
|
||||||
|
settings.chkAutoShield->setChecked(Settings::getInstance()->getAutoShield());
|
||||||
|
|
||||||
// Connection Settings
|
// Connection Settings
|
||||||
QIntValidator validator(0, 65535);
|
QIntValidator validator(0, 65535);
|
||||||
settings.port->setValidator(&validator);
|
settings.port->setValidator(&validator);
|
||||||
@@ -426,6 +429,9 @@ void MainWindow::setupSettingsModal() {
|
|||||||
if (!customFees)
|
if (!customFees)
|
||||||
ui->minerFeeAmt->setText(Settings::getDecimalString(Settings::getMinerFee()));
|
ui->minerFeeAmt->setText(Settings::getDecimalString(Settings::getMinerFee()));
|
||||||
|
|
||||||
|
// Auto shield
|
||||||
|
Settings::getInstance()->setAutoShield(settings.chkAutoShield->isChecked());
|
||||||
|
|
||||||
if (zcashConfLocation.isEmpty()) {
|
if (zcashConfLocation.isEmpty()) {
|
||||||
// Save settings
|
// Save settings
|
||||||
Settings::getInstance()->saveSettings(
|
Settings::getInstance()->saveSettings(
|
||||||
@@ -567,6 +573,7 @@ void MainWindow::postToZBoard() {
|
|||||||
auto toAddr = topics[zb.topicsList->currentText()];
|
auto toAddr = topics[zb.topicsList->currentText()];
|
||||||
tx.toAddrs.push_back(ToFields{ toAddr, Settings::getZboardAmount(), memo, memo.toUtf8().toHex() });
|
tx.toAddrs.push_back(ToFields{ toAddr, Settings::getZboardAmount(), memo, memo.toUtf8().toHex() });
|
||||||
tx.fee = Settings::getMinerFee();
|
tx.fee = Settings::getMinerFee();
|
||||||
|
tx.sendChangeToSapling = false;
|
||||||
|
|
||||||
json params = json::array();
|
json params = json::array();
|
||||||
rpc->fillTxJsonParams(params, tx);
|
rpc->fillTxJsonParams(params, tx);
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ struct Tx {
|
|||||||
QString fromAddr;
|
QString fromAddr;
|
||||||
QList<ToFields> toAddrs;
|
QList<ToFields> toAddrs;
|
||||||
double fee;
|
double fee;
|
||||||
|
bool sendChangeToSapling;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
|
|||||||
@@ -363,17 +363,26 @@ void MainWindow::maxAmountChecked(int checked) {
|
|||||||
// Create a Tx from the current state of the send page.
|
// Create a Tx from the current state of the send page.
|
||||||
Tx MainWindow::createTxFromSendPage() {
|
Tx MainWindow::createTxFromSendPage() {
|
||||||
Tx tx;
|
Tx tx;
|
||||||
|
|
||||||
|
bool sendChangeToSapling = Settings::getInstance()->getAutoShield();
|
||||||
|
|
||||||
// Gather the from / to addresses
|
// Gather the from / to addresses
|
||||||
tx.fromAddr = ui->inputsCombo->currentText();
|
tx.fromAddr = ui->inputsCombo->currentText();
|
||||||
|
sendChangeToSapling = sendChangeToSapling && Settings::isTAddress(tx.fromAddr);
|
||||||
|
|
||||||
// For each addr/amt in the sendTo tab
|
// For each addr/amt in the sendTo tab
|
||||||
int totalItems = ui->sendToWidgets->children().size() - 2; // The last one is a spacer, so ignore that
|
int totalItems = ui->sendToWidgets->children().size() - 2; // The last one is a spacer, so ignore that
|
||||||
|
double totalAmt = 0;
|
||||||
for (int i=0; i < totalItems; i++) {
|
for (int i=0; i < totalItems; i++) {
|
||||||
QString addr = ui->sendToWidgets->findChild<QLineEdit*>(QString("Address") % QString::number(i+1))->text().trimmed();
|
QString addr = ui->sendToWidgets->findChild<QLineEdit*>(QString("Address") % QString::number(i+1))->text().trimmed();
|
||||||
// Remove label if it exists
|
// Remove label if it exists
|
||||||
addr = AddressBook::addressFromAddressLabel(addr);
|
addr = AddressBook::addressFromAddressLabel(addr);
|
||||||
|
|
||||||
|
// If address is sprout, then we can't send change to sapling, because of turnstile.
|
||||||
|
sendChangeToSapling = sendChangeToSapling && !Settings::getInstance()->isSproutAddress(addr);
|
||||||
|
|
||||||
double amt = ui->sendToWidgets->findChild<QLineEdit*>(QString("Amount") % QString::number(i+1))->text().trimmed().toDouble();
|
double amt = ui->sendToWidgets->findChild<QLineEdit*>(QString("Amount") % QString::number(i+1))->text().trimmed().toDouble();
|
||||||
|
totalAmt += amt;
|
||||||
QString memo = ui->sendToWidgets->findChild<QLabel*>(QString("MemoTxt") % QString::number(i+1))->text().trimmed();
|
QString memo = ui->sendToWidgets->findChild<QLabel*>(QString("MemoTxt") % QString::number(i+1))->text().trimmed();
|
||||||
|
|
||||||
tx.toAddrs.push_back( ToFields{addr, amt, memo, memo.toUtf8().toHex()} );
|
tx.toAddrs.push_back( ToFields{addr, amt, memo, memo.toUtf8().toHex()} );
|
||||||
@@ -381,10 +390,34 @@ Tx MainWindow::createTxFromSendPage() {
|
|||||||
|
|
||||||
if (Settings::getInstance()->getAllowCustomFees()) {
|
if (Settings::getInstance()->getAllowCustomFees()) {
|
||||||
tx.fee = ui->minerFeeAmt->text().toDouble();
|
tx.fee = ui->minerFeeAmt->text().toDouble();
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
tx.fee = Settings::getMinerFee();
|
tx.fee = Settings::getMinerFee();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sendChangeToSapling) {
|
||||||
|
auto saplingAddr = std::find_if(rpc->getAllZAddresses()->begin(), rpc->getAllZAddresses()->end(), [=](auto i) -> bool {
|
||||||
|
// We're finding a sapling address that is not one of the To addresses, because zcash doesn't allow duplicated addresses
|
||||||
|
bool isSapling = Settings::getInstance()->isSaplingAddress(i);
|
||||||
|
if (!isSapling) return false;
|
||||||
|
|
||||||
|
// Also check all the To addresses
|
||||||
|
for (auto t : tx.toAddrs) {
|
||||||
|
if (t.addr == i)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
if (saplingAddr != rpc->getAllZAddresses()->end()) {
|
||||||
|
tx.sendChangeToSapling = sendChangeToSapling;
|
||||||
|
double change = rpc->getAllBalances()->value(tx.fromAddr) - totalAmt - tx.fee;
|
||||||
|
|
||||||
|
QString changeMemo = "change from " + tx.fromAddr;
|
||||||
|
tx.toAddrs.push_back( ToFields{*saplingAddr, change, changeMemo, changeMemo.toUtf8().toHex()} );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return tx;
|
return tx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -66,6 +66,10 @@ bool Settings::isZAddress(QString addr) {
|
|||||||
return addr.startsWith("z");
|
return addr.startsWith("z");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Settings::isTAddress(QString addr) {
|
||||||
|
return addr.startsWith("t");
|
||||||
|
}
|
||||||
|
|
||||||
bool Settings::isSyncing() {
|
bool Settings::isSyncing() {
|
||||||
return _isSyncing;
|
return _isSyncing;
|
||||||
}
|
}
|
||||||
@@ -91,6 +95,14 @@ double Settings::getZECPrice() {
|
|||||||
return zecPrice;
|
return zecPrice;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Settings::getAutoShield() {
|
||||||
|
// Load from Qt settings
|
||||||
|
return QSettings().value("options/autoshield", false).toBool();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Settings::setAutoShield(bool allow) {
|
||||||
|
QSettings().setValue("options/autoshield", allow);
|
||||||
|
}
|
||||||
|
|
||||||
bool Settings::getAllowCustomFees() {
|
bool Settings::getAllowCustomFees() {
|
||||||
// Load from the QT Settings.
|
// Load from the QT Settings.
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ public:
|
|||||||
|
|
||||||
bool isSaplingAddress(QString addr);
|
bool isSaplingAddress(QString addr);
|
||||||
bool isSproutAddress(QString addr);
|
bool isSproutAddress(QString addr);
|
||||||
bool isZAddress(QString addr);
|
|
||||||
|
|
||||||
bool isSyncing();
|
bool isSyncing();
|
||||||
void setSyncing(bool syncing);
|
void setSyncing(bool syncing);
|
||||||
@@ -40,7 +39,10 @@ public:
|
|||||||
|
|
||||||
bool getSaveZtxs();
|
bool getSaveZtxs();
|
||||||
void setSaveZtxs(bool save);
|
void setSaveZtxs(bool save);
|
||||||
|
|
||||||
|
bool getAutoShield();
|
||||||
|
void setAutoShield(bool allow);
|
||||||
|
|
||||||
bool getAllowCustomFees();
|
bool getAllowCustomFees();
|
||||||
void setAllowCustomFees(bool allow);
|
void setAllowCustomFees(bool allow);
|
||||||
|
|
||||||
@@ -57,6 +59,9 @@ public:
|
|||||||
|
|
||||||
static void saveRestore(QDialog* d);
|
static void saveRestore(QDialog* d);
|
||||||
|
|
||||||
|
static bool isZAddress(QString addr);
|
||||||
|
static bool isTAddress(QString addr);
|
||||||
|
|
||||||
static QString getDecimalString(double amt);
|
static QString getDecimalString(double amt);
|
||||||
static QString getUSDFormat(double bal);
|
static QString getUSDFormat(double bal);
|
||||||
static QString getZECDisplayFormat(double bal);
|
static QString getZECDisplayFormat(double bal);
|
||||||
|
|||||||
@@ -139,19 +139,6 @@
|
|||||||
<string>Options</string>
|
<string>Options</string>
|
||||||
</attribute>
|
</attribute>
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
<item row="2" column="0">
|
|
||||||
<spacer name="horizontalSpacer">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0" colspan="2">
|
<item row="1" column="0" colspan="2">
|
||||||
<widget class="QLabel" name="label_5">
|
<widget class="QLabel" name="label_5">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@@ -169,6 +156,19 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<spacer name="horizontalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
<item row="0" column="0" colspan="2">
|
<item row="0" column="0" colspan="2">
|
||||||
<widget class="QCheckBox" name="chkSaveTxs">
|
<widget class="QCheckBox" name="chkSaveTxs">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@@ -176,7 +176,14 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="6" column="0" colspan="2">
|
<item row="8" column="0" colspan="2">
|
||||||
|
<widget class="Line" name="line_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="9" column="0" colspan="2">
|
||||||
<spacer name="verticalSpacer_2">
|
<spacer name="verticalSpacer_2">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Vertical</enum>
|
<enum>Qt::Vertical</enum>
|
||||||
@@ -189,13 +196,6 @@
|
|||||||
</property>
|
</property>
|
||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
<item row="5" column="0" colspan="2">
|
|
||||||
<widget class="Line" name="line_2">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="0">
|
<item row="3" column="0">
|
||||||
<widget class="QCheckBox" name="chkCustomFees">
|
<widget class="QCheckBox" name="chkCustomFees">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@@ -213,6 +213,30 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="7" column="0" colspan="2">
|
||||||
|
<widget class="QLabel" name="label_7">
|
||||||
|
<property name="text">
|
||||||
|
<string>Normally, change from t-Addresses goes to another t-Address. Checking this option will send the change to your shielded Sapling address instead. Check this option to increase your privacy.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="6" column="0" colspan="2">
|
||||||
|
<widget class="QCheckBox" name="chkAutoShield">
|
||||||
|
<property name="text">
|
||||||
|
<string>Shield change from t-Addresses to your Sapling addresses</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="0">
|
||||||
|
<widget class="QLabel" name="label_8">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
|
|||||||
@@ -304,7 +304,7 @@ void Turnstile::executeMigrationStep() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create the Tx
|
// Create the Tx
|
||||||
auto tx = Tx{ nextStep->fromAddr, { to }, Settings::getMinerFee() };
|
auto tx = Tx{ nextStep->fromAddr, { to }, Settings::getMinerFee(), false };
|
||||||
|
|
||||||
// And send it
|
// And send it
|
||||||
doSendTx(tx, [=] () {
|
doSendTx(tx, [=] () {
|
||||||
@@ -339,7 +339,7 @@ void Turnstile::executeMigrationStep() {
|
|||||||
QList<ToFields> to = { ToFields{ nextStep->destAddr, sendAmt, "", "" } };
|
QList<ToFields> to = { ToFields{ nextStep->destAddr, sendAmt, "", "" } };
|
||||||
|
|
||||||
// Create the Tx
|
// Create the Tx
|
||||||
auto tx = Tx{ nextStep->intTAddr, to, Settings::getMinerFee() };
|
auto tx = Tx{ nextStep->intTAddr, to, Settings::getMinerFee(), false };
|
||||||
|
|
||||||
// And send it
|
// And send it
|
||||||
doSendTx(tx, [=] () {
|
doSendTx(tx, [=] () {
|
||||||
|
|||||||
Reference in New Issue
Block a user