mirror of
https://github.com/monero-project/monero-gui.git
synced 2025-01-03 17:39:54 +00:00
Implement background sync when locked
This commit is contained in:
parent
e9cd4588ae
commit
da67232e0c
5 changed files with 217 additions and 12 deletions
|
@ -50,6 +50,7 @@ Item {
|
||||||
property bool passwordDialogMode
|
property bool passwordDialogMode
|
||||||
property bool passphraseDialogMode
|
property bool passphraseDialogMode
|
||||||
property bool newPasswordDialogMode
|
property bool newPasswordDialogMode
|
||||||
|
property bool backgroundSyncing
|
||||||
|
|
||||||
// same signals as Dialog has
|
// same signals as Dialog has
|
||||||
signal accepted()
|
signal accepted()
|
||||||
|
@ -77,10 +78,11 @@ Item {
|
||||||
appWindow.updateBalance();
|
appWindow.updateBalance();
|
||||||
}
|
}
|
||||||
|
|
||||||
function open(walletName, errorText, okButtonText, okButtonIcon) {
|
function open(walletName, errorText, okButtonText, okButtonIcon, backgroundSyncOn) {
|
||||||
passwordDialogMode = true;
|
passwordDialogMode = true;
|
||||||
passphraseDialogMode = false;
|
passphraseDialogMode = false;
|
||||||
newPasswordDialogMode = false;
|
newPasswordDialogMode = false;
|
||||||
|
backgroundSyncing = backgroundSyncOn || false;
|
||||||
root.okButtonText = okButtonText;
|
root.okButtonText = okButtonText;
|
||||||
root.okButtonIcon = okButtonIcon ? okButtonIcon : "";
|
root.okButtonIcon = okButtonIcon ? okButtonIcon : "";
|
||||||
_openInit(walletName, errorText);
|
_openInit(walletName, errorText);
|
||||||
|
@ -90,6 +92,7 @@ Item {
|
||||||
passwordDialogMode = false;
|
passwordDialogMode = false;
|
||||||
passphraseDialogMode = true;
|
passphraseDialogMode = true;
|
||||||
newPasswordDialogMode = false;
|
newPasswordDialogMode = false;
|
||||||
|
backgroundSyncing = false;
|
||||||
_openInit("", "");
|
_openInit("", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,6 +100,7 @@ Item {
|
||||||
passwordDialogMode = false;
|
passwordDialogMode = false;
|
||||||
passphraseDialogMode = false;
|
passphraseDialogMode = false;
|
||||||
newPasswordDialogMode = true;
|
newPasswordDialogMode = true;
|
||||||
|
backgroundSyncing = false;
|
||||||
_openInit("", "");
|
_openInit("", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -300,6 +304,18 @@ Item {
|
||||||
onClicked: onOk()
|
onClicked: onOk()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
visible: backgroundSyncing
|
||||||
|
text: qsTr("Syncing in the background...") + translationManager.emptyString;
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
font.pixelSize: 14
|
||||||
|
font.family: MoneroComponents.Style.fontLight.name
|
||||||
|
font.italic: true
|
||||||
|
|
||||||
|
color: MoneroComponents.Style.defaultFontColor
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
108
main.qml
108
main.qml
|
@ -99,6 +99,7 @@ ApplicationWindow {
|
||||||
property string prevSplashText;
|
property string prevSplashText;
|
||||||
property bool splashDisplayedBeforeButtonRequest;
|
property bool splashDisplayedBeforeButtonRequest;
|
||||||
property bool themeTransition: false
|
property bool themeTransition: false
|
||||||
|
property int backgroundSyncType: Wallet.BackgroundSync_Off;
|
||||||
|
|
||||||
// fiat price conversion
|
// fiat price conversion
|
||||||
property real fiatPrice: 0
|
property real fiatPrice: 0
|
||||||
|
@ -133,6 +134,12 @@ ApplicationWindow {
|
||||||
}
|
}
|
||||||
|
|
||||||
function lock() {
|
function lock() {
|
||||||
|
if (currentWallet && currentWallet.getBackgroundSyncType() != Wallet.BackgroundSync_Off) {
|
||||||
|
appWindow.showProcessingSplash(qsTr("Locking..."));
|
||||||
|
currentWallet.startBackgroundSync()
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
passwordDialog.onRejectedCallback = function() { appWindow.showWizard(); }
|
passwordDialog.onRejectedCallback = function() { appWindow.showWizard(); }
|
||||||
passwordDialog.onAcceptedCallback = function() {
|
passwordDialog.onAcceptedCallback = function() {
|
||||||
if(walletPassword === passwordDialog.password)
|
if(walletPassword === passwordDialog.password)
|
||||||
|
@ -288,6 +295,9 @@ ApplicationWindow {
|
||||||
currentWallet.heightRefreshed.disconnect(onHeightRefreshed);
|
currentWallet.heightRefreshed.disconnect(onHeightRefreshed);
|
||||||
currentWallet.refreshed.disconnect(onWalletRefresh)
|
currentWallet.refreshed.disconnect(onWalletRefresh)
|
||||||
currentWallet.updated.disconnect(onWalletUpdate)
|
currentWallet.updated.disconnect(onWalletUpdate)
|
||||||
|
currentWallet.backgroundSyncSetup.disconnect(onBackgroundSyncSetup)
|
||||||
|
currentWallet.backgroundSyncStarted.disconnect(onBackgroundSyncStarted)
|
||||||
|
currentWallet.backgroundSyncStopped.disconnect(onBackgroundSyncStopped)
|
||||||
currentWallet.newBlock.disconnect(onWalletNewBlock)
|
currentWallet.newBlock.disconnect(onWalletNewBlock)
|
||||||
currentWallet.moneySpent.disconnect(onWalletMoneySent)
|
currentWallet.moneySpent.disconnect(onWalletMoneySent)
|
||||||
currentWallet.moneyReceived.disconnect(onWalletMoneyReceived)
|
currentWallet.moneyReceived.disconnect(onWalletMoneyReceived)
|
||||||
|
@ -324,6 +334,7 @@ ApplicationWindow {
|
||||||
walletName = usefulName(wallet.path)
|
walletName = usefulName(wallet.path)
|
||||||
|
|
||||||
viewOnly = currentWallet.viewOnly;
|
viewOnly = currentWallet.viewOnly;
|
||||||
|
backgroundSyncType = currentWallet.getBackgroundSyncType();
|
||||||
|
|
||||||
// New wallets saves the testnet flag in keys file.
|
// New wallets saves the testnet flag in keys file.
|
||||||
if(persistentSettings.nettype != currentWallet.nettype) {
|
if(persistentSettings.nettype != currentWallet.nettype) {
|
||||||
|
@ -335,6 +346,9 @@ ApplicationWindow {
|
||||||
currentWallet.heightRefreshed.connect(onHeightRefreshed);
|
currentWallet.heightRefreshed.connect(onHeightRefreshed);
|
||||||
currentWallet.refreshed.connect(onWalletRefresh)
|
currentWallet.refreshed.connect(onWalletRefresh)
|
||||||
currentWallet.updated.connect(onWalletUpdate)
|
currentWallet.updated.connect(onWalletUpdate)
|
||||||
|
currentWallet.backgroundSyncSetup.connect(onBackgroundSyncSetup)
|
||||||
|
currentWallet.backgroundSyncStarted.connect(onBackgroundSyncStarted)
|
||||||
|
currentWallet.backgroundSyncStopped.connect(onBackgroundSyncStopped)
|
||||||
currentWallet.newBlock.connect(onWalletNewBlock)
|
currentWallet.newBlock.connect(onWalletNewBlock)
|
||||||
currentWallet.moneySpent.connect(onWalletMoneySent)
|
currentWallet.moneySpent.connect(onWalletMoneySent)
|
||||||
currentWallet.moneyReceived.connect(onWalletMoneyReceived)
|
currentWallet.moneyReceived.connect(onWalletMoneyReceived)
|
||||||
|
@ -544,6 +558,15 @@ ApplicationWindow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Don't allow opening background wallets in the GUI
|
||||||
|
if (wallet.isBackgroundWallet()) {
|
||||||
|
passwordDialog.onCancel();
|
||||||
|
appWindow.showStatusMessage(qsTr("Can't open background wallets in the GUI"),6);
|
||||||
|
console.log("closing background wallet");
|
||||||
|
closeWallet();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// wallet opened successfully, subscribing for wallet updates
|
// wallet opened successfully, subscribing for wallet updates
|
||||||
connectWallet(wallet)
|
connectWallet(wallet)
|
||||||
|
|
||||||
|
@ -585,16 +608,17 @@ ApplicationWindow {
|
||||||
devicePassphraseDialog.open(on_device)
|
devicePassphraseDialog.open(on_device)
|
||||||
}
|
}
|
||||||
|
|
||||||
function onWalletUpdate() {
|
function onWalletUpdate(stoppedBackgroundSync) {
|
||||||
if (!currentWallet)
|
if (!currentWallet)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
console.log(">>> wallet updated")
|
console.log(">>> wallet updated")
|
||||||
updateBalance();
|
updateBalance();
|
||||||
// Update history if new block found since last update
|
// Update history if new block found since last update or background sync was just stopped
|
||||||
if(foundNewBlock) {
|
if(foundNewBlock || stoppedBackgroundSync) {
|
||||||
foundNewBlock = false;
|
if (foundNewBlock)
|
||||||
console.log("New block found - updating history")
|
console.log("New block found - updating history")
|
||||||
|
foundNewBlock = false;
|
||||||
currentWallet.history.refresh(currentWallet.currentSubaddressAccount)
|
currentWallet.history.refresh(currentWallet.currentSubaddressAccount)
|
||||||
|
|
||||||
if(middlePanel.state == "History")
|
if(middlePanel.state == "History")
|
||||||
|
@ -602,6 +626,61 @@ ApplicationWindow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onBackgroundSyncSetup() {
|
||||||
|
console.log(">>> background sync setup");
|
||||||
|
hideProcessingSplash();
|
||||||
|
if (currentWallet.status !== Wallet.Status_Ok) {
|
||||||
|
console.error("Error setting up background sync: ", currentWallet.errorString);
|
||||||
|
appWindow.showStatusMessage(currentWallet.errorString, 5);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
appWindow.backgroundSyncType = currentWallet.getBackgroundSyncType();
|
||||||
|
}
|
||||||
|
|
||||||
|
function onBackgroundSyncStarted() {
|
||||||
|
console.log(">>> background sync started");
|
||||||
|
hideProcessingSplash();
|
||||||
|
var started = currentWallet.status === Wallet.Status_Ok;
|
||||||
|
if (!started) {
|
||||||
|
console.error("Error starting background sync: ", currentWallet.errorString);
|
||||||
|
appWindow.showStatusMessage(currentWallet.errorString, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
passwordDialog.onRejectedCallback = function() { appWindow.showWizard(); }
|
||||||
|
passwordDialog.onAcceptedCallback = function() {
|
||||||
|
if(walletPassword === passwordDialog.password) {
|
||||||
|
if (currentWallet && started) {
|
||||||
|
appWindow.showProcessingSplash(qsTr("Unlocking..."));
|
||||||
|
currentWallet.stopBackgroundSync(walletPassword);
|
||||||
|
} else {
|
||||||
|
passwordDialog.close();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
passwordDialog.showError(qsTr("Wrong password") + translationManager.emptyString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
passwordDialog.open(usefulName(persistentSettings.wallet_path), "", "", "", started);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onBackgroundSyncStopped() {
|
||||||
|
console.log(">>> background sync stopped");
|
||||||
|
var stopped = currentWallet.status === Wallet.Status_Ok;
|
||||||
|
if (!stopped) {
|
||||||
|
hideProcessingSplash();
|
||||||
|
console.error("Error stopping background sync: ", currentWallet.errorString);
|
||||||
|
|
||||||
|
// If there is an error stopping background sync, the spend key
|
||||||
|
// won't be loaded and the wallet will be in a broken state. Don't
|
||||||
|
// let the user continue normal wallet operations in this state.
|
||||||
|
passwordDialog.showError(qsTr("Error stopping background sync: ") + currentWallet.errorString);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
onWalletUpdate(stopped);
|
||||||
|
hideProcessingSplash();
|
||||||
|
passwordDialog.close();
|
||||||
|
}
|
||||||
|
|
||||||
function connectRemoteNode() {
|
function connectRemoteNode() {
|
||||||
console.log("connecting remote node");
|
console.log("connecting remote node");
|
||||||
|
|
||||||
|
@ -2258,6 +2337,20 @@ ApplicationWindow {
|
||||||
var inactivity = Utils.epoch() - appWindow.userLastActive;
|
var inactivity = Utils.epoch() - appWindow.userLastActive;
|
||||||
if(inactivity < (persistentSettings.lockOnUserInActivityInterval * 60)) return;
|
if(inactivity < (persistentSettings.lockOnUserInActivityInterval * 60)) return;
|
||||||
|
|
||||||
|
if (inputDialogVisible) inputDialog.close()
|
||||||
|
remoteNodeDialog.close();
|
||||||
|
informationPopup.close()
|
||||||
|
txConfirmationPopup.close()
|
||||||
|
txConfirmationPopup.clearFields()
|
||||||
|
txConfirmationPopup.rejected()
|
||||||
|
successfulTxPopup.close();
|
||||||
|
|
||||||
|
if (currentWallet && currentWallet.getBackgroundSyncType() != Wallet.BackgroundSync_Off) {
|
||||||
|
appWindow.showProcessingSplash(qsTr("Locking..."));
|
||||||
|
currentWallet.startBackgroundSync()
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
passwordDialog.onAcceptedCallback = function() {
|
passwordDialog.onAcceptedCallback = function() {
|
||||||
if(walletPassword === passwordDialog.password){
|
if(walletPassword === passwordDialog.password){
|
||||||
passwordDialog.close();
|
passwordDialog.close();
|
||||||
|
@ -2270,13 +2363,6 @@ ApplicationWindow {
|
||||||
}
|
}
|
||||||
|
|
||||||
passwordDialog.onRejectedCallback = function() { appWindow.showWizard(); }
|
passwordDialog.onRejectedCallback = function() { appWindow.showWizard(); }
|
||||||
if (inputDialogVisible) inputDialog.close()
|
|
||||||
remoteNodeDialog.close();
|
|
||||||
informationPopup.close()
|
|
||||||
txConfirmationPopup.close()
|
|
||||||
txConfirmationPopup.clearFields()
|
|
||||||
txConfirmationPopup.rejected()
|
|
||||||
successfulTxPopup.close();
|
|
||||||
passwordDialog.open();
|
passwordDialog.open();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,8 @@ import QtQuick.Layouts 1.1
|
||||||
import QtQuick.Controls 2.0
|
import QtQuick.Controls 2.0
|
||||||
import QtQuick.Dialogs 1.2
|
import QtQuick.Dialogs 1.2
|
||||||
|
|
||||||
|
import moneroComponents.Wallet 1.0
|
||||||
|
|
||||||
import "../../js/Utils.js" as Utils
|
import "../../js/Utils.js" as Utils
|
||||||
import "../../js/Windows.js" as Windows
|
import "../../js/Windows.js" as Windows
|
||||||
import "../../components" as MoneroComponents
|
import "../../components" as MoneroComponents
|
||||||
|
@ -155,6 +157,28 @@ Rectangle {
|
||||||
onMoved: persistentSettings.lockOnUserInActivityInterval = value
|
onMoved: persistentSettings.lockOnUserInActivityInterval = value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MoneroComponents.CheckBox {
|
||||||
|
id: backgroundSyncCheckbox
|
||||||
|
visible: !!currentWallet && !currentWallet.isHwBacked() && !appWindow.viewOnly
|
||||||
|
checked: appWindow.backgroundSyncType != Wallet.BackgroundSync_Off
|
||||||
|
text: qsTr("Sync in the background when locked") + translationManager.emptyString
|
||||||
|
toggleOnClick: false
|
||||||
|
onClicked: {
|
||||||
|
if (currentWallet && appWindow) {
|
||||||
|
appWindow.showProcessingSplash(qsTr("Updating settings..."))
|
||||||
|
|
||||||
|
// TODO: add support for custom background password option
|
||||||
|
var newBackgroundSyncType = Wallet.BackgroundSync_Off
|
||||||
|
if (currentWallet.getBackgroundSyncType() === Wallet.BackgroundSync_Off)
|
||||||
|
newBackgroundSyncType = Wallet.BackgroundSync_ReusePassword
|
||||||
|
|
||||||
|
// TODO: don't keep the wallet password in memory on the appWindow
|
||||||
|
// https://github.com/monero-project/monero-gui/issues/1537#issuecomment-410055329
|
||||||
|
currentWallet.setupBackgroundSync(newBackgroundSyncType, appWindow.walletPassword)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MoneroComponents.CheckBox {
|
MoneroComponents.CheckBox {
|
||||||
checked: persistentSettings.askStopLocalNode
|
checked: persistentSettings.askStopLocalNode
|
||||||
onClicked: persistentSettings.askStopLocalNode = !persistentSettings.askStopLocalNode
|
onClicked: persistentSettings.askStopLocalNode = !persistentSettings.askStopLocalNode
|
||||||
|
|
|
@ -529,6 +529,64 @@ bool Wallet::scanTransactions(const QVector<QString> &txids)
|
||||||
return m_walletImpl->scanTransactions(c);
|
return m_walletImpl->scanTransactions(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Wallet::setupBackgroundSync(const Wallet::BackgroundSyncType background_sync_type, const QString &wallet_password)
|
||||||
|
{
|
||||||
|
qDebug() << "Setting up background sync";
|
||||||
|
bool refreshEnabled = m_refreshEnabled;
|
||||||
|
pauseRefresh();
|
||||||
|
|
||||||
|
// run inside scheduler because of lag when stopping/starting refresh
|
||||||
|
m_scheduler.run([this, refreshEnabled, background_sync_type, &wallet_password] {
|
||||||
|
m_walletImpl->setupBackgroundSync(
|
||||||
|
static_cast<Monero::Wallet::BackgroundSyncType>(background_sync_type),
|
||||||
|
wallet_password.toStdString(),
|
||||||
|
Monero::optional<std::string>());
|
||||||
|
if (refreshEnabled)
|
||||||
|
startRefresh();
|
||||||
|
emit backgroundSyncSetup();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Wallet::BackgroundSyncType Wallet::getBackgroundSyncType() const
|
||||||
|
{
|
||||||
|
return static_cast<BackgroundSyncType>(m_walletImpl->getBackgroundSyncType());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Wallet::isBackgroundWallet() const
|
||||||
|
{
|
||||||
|
return m_walletImpl->isBackgroundWallet();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Wallet::startBackgroundSync()
|
||||||
|
{
|
||||||
|
qDebug() << "Starting background sync";
|
||||||
|
bool refreshEnabled = m_refreshEnabled;
|
||||||
|
pauseRefresh();
|
||||||
|
|
||||||
|
// run inside scheduler because of lag when stopping/starting refresh
|
||||||
|
m_scheduler.run([this, refreshEnabled] {
|
||||||
|
m_walletImpl->startBackgroundSync();
|
||||||
|
if (refreshEnabled)
|
||||||
|
startRefresh();
|
||||||
|
emit backgroundSyncStarted();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void Wallet::stopBackgroundSync(const QString &password)
|
||||||
|
{
|
||||||
|
qDebug() << "Stopping background sync";
|
||||||
|
bool refreshEnabled = m_refreshEnabled;
|
||||||
|
pauseRefresh();
|
||||||
|
|
||||||
|
// run inside scheduler because of lag when stopping/starting refresh
|
||||||
|
m_scheduler.run([this, password, refreshEnabled] {
|
||||||
|
m_walletImpl->stopBackgroundSync(password.toStdString());
|
||||||
|
if (refreshEnabled)
|
||||||
|
startRefresh();
|
||||||
|
emit backgroundSyncStopped();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
bool Wallet::refresh(bool historyAndSubaddresses /* = true */)
|
bool Wallet::refresh(bool historyAndSubaddresses /* = true */)
|
||||||
{
|
{
|
||||||
refreshingSet(true);
|
refreshingSet(true);
|
||||||
|
|
|
@ -112,6 +112,14 @@ public:
|
||||||
|
|
||||||
Q_ENUM(ConnectionStatus)
|
Q_ENUM(ConnectionStatus)
|
||||||
|
|
||||||
|
enum BackgroundSyncType {
|
||||||
|
BackgroundSync_Off = Monero::Wallet::BackgroundSync_Off,
|
||||||
|
BackgroundSync_ReusePassword = Monero::Wallet::BackgroundSync_ReusePassword,
|
||||||
|
BackgroundSync_CustomPassword = Monero::Wallet::BackgroundSync_CustomPassword
|
||||||
|
};
|
||||||
|
|
||||||
|
Q_ENUM(BackgroundSyncType)
|
||||||
|
|
||||||
//! returns mnemonic seed
|
//! returns mnemonic seed
|
||||||
QString getSeed() const;
|
QString getSeed() const;
|
||||||
|
|
||||||
|
@ -215,6 +223,16 @@ public:
|
||||||
//! scan transactions
|
//! scan transactions
|
||||||
Q_INVOKABLE bool scanTransactions(const QVector<QString> &txids);
|
Q_INVOKABLE bool scanTransactions(const QVector<QString> &txids);
|
||||||
|
|
||||||
|
Q_INVOKABLE void setupBackgroundSync(const BackgroundSyncType background_sync_type, const QString &wallet_password);
|
||||||
|
Q_INVOKABLE BackgroundSyncType getBackgroundSyncType() const;
|
||||||
|
Q_INVOKABLE bool isBackgroundWallet() const;
|
||||||
|
|
||||||
|
//! scan in the background with just the view key (wipe the spend key)
|
||||||
|
Q_INVOKABLE void startBackgroundSync();
|
||||||
|
|
||||||
|
//! bring the spend key back and process background synced txs
|
||||||
|
Q_INVOKABLE void stopBackgroundSync(const QString &password);
|
||||||
|
|
||||||
//! refreshes the wallet
|
//! refreshes the wallet
|
||||||
Q_INVOKABLE bool refresh(bool historyAndSubaddresses = true);
|
Q_INVOKABLE bool refresh(bool historyAndSubaddresses = true);
|
||||||
|
|
||||||
|
@ -369,6 +387,9 @@ signals:
|
||||||
void moneyReceived(const QString &txId, quint64 amount);
|
void moneyReceived(const QString &txId, quint64 amount);
|
||||||
void unconfirmedMoneyReceived(const QString &txId, quint64 amount);
|
void unconfirmedMoneyReceived(const QString &txId, quint64 amount);
|
||||||
void newBlock(quint64 height, quint64 targetHeight);
|
void newBlock(quint64 height, quint64 targetHeight);
|
||||||
|
void backgroundSyncSetup() const;
|
||||||
|
void backgroundSyncStarted() const;
|
||||||
|
void backgroundSyncStopped() const;
|
||||||
void addressBookChanged() const;
|
void addressBookChanged() const;
|
||||||
void historyModelChanged() const;
|
void historyModelChanged() const;
|
||||||
void walletCreationHeightChanged();
|
void walletCreationHeightChanged();
|
||||||
|
|
Loading…
Reference in a new issue