diff --git a/src-electron/main-process/modules/backend.js b/src-electron/main-process/modules/backend.js index 336b7552..5c12c2eb 100644 --- a/src-electron/main-process/modules/backend.js +++ b/src-electron/main-process/modules/backend.js @@ -493,7 +493,6 @@ export class Backend { fs.mkdirpSync(log_dir); } - console.log("About to init the logger with log_dir: " + log_dir); this.initLogger(log_dir); this.daemon = new Daemon(this); diff --git a/src-electron/main-process/modules/wallet-rpc.js b/src-electron/main-process/modules/wallet-rpc.js index a180d915..d0af1187 100644 --- a/src-electron/main-process/modules/wallet-rpc.js +++ b/src-electron/main-process/modules/wallet-rpc.js @@ -336,7 +336,8 @@ export class WalletRPC { params.amount, params.address, params.payment_id, - params.priority + params.priority, + !!params.isSweepAll ); break; case "relay_tx": @@ -344,7 +345,8 @@ export class WalletRPC { params.metadataList, params.isBlink, params.addressSave, - params.note + params.note, + !!params.isSweepAll ); break; case "purchase_lns": @@ -1348,8 +1350,17 @@ export class WalletRPC { } // submits the transaction to the blockchain, irreversible from here - async relayTransaction(metadataList, isBlink, addressSave, note) { - const { address, payment_id, address_book } = addressSave; + async relayTransaction(metadataList, isBlink, addressSave, note, isSweepAll) { + // for a sweep these don't exist + let address = ""; + let payment_id = ""; + let address_book = ""; + if (addressSave) { + address = addressSave.address; + payment_id = addressSave.payment_id; + address_book = addressSave.address_book; + } + let failed = false; let errorMessage = "Failed to relay transaction"; @@ -1383,8 +1394,13 @@ export class WalletRPC { } } + // for updating state on the correct page + const gatewayEndpoint = isSweepAll + ? "set_sweep_all_status" + : "set_tx_status"; + if (!failed) { - this.sendGateway("set_tx_status", { + this.sendGateway(gatewayEndpoint, { code: 0, i18n: "notification.positive.sendSuccess", sending: false @@ -1401,7 +1417,7 @@ export class WalletRPC { return; } - this.sendGateway("set_tx_status", { + this.sendGateway(gatewayEndpoint, { code: -1, message: errorMessage, sending: false @@ -1410,7 +1426,8 @@ export class WalletRPC { // prepares params and provides a "confirm" popup to allow the user to check // send address and tx fees before sending - transfer(password, amount, address, payment_id, priority) { + // isSweepAll refers to if it's the sweep from service nodes page + transfer(password, amount, address, payment_id, priority, isSweepAll) { const cryptoCallback = (err, password_hash) => { if (err) { this.sendGateway("set_tx_status", { @@ -1434,10 +1451,10 @@ export class WalletRPC { // if sending "All" the funds, then we need to send all - fee (sweep_all) // To be amended after the hardfork, v8. // https://github.com/loki-project/loki-electron-gui-wallet/issues/181 - const isSweepAll = amount == this.wallet_state.unlocked_balance; - const rpc_endpoint = isSweepAll ? "sweep_all" : "transfer_split"; + const isSweepAllRPC = amount == this.wallet_state.unlocked_balance; + const rpc_endpoint = isSweepAllRPC ? "sweep_all" : "transfer_split"; - const rpcSpecificParams = isSweepAll + const rpcSpecificParams = isSweepAllRPC ? { address, account_index: 0 @@ -1456,6 +1473,11 @@ export class WalletRPC { params.payment_id = payment_id; } + // for updating state on the correct page + const gatewayEndpoint = isSweepAll + ? "set_sweep_all_status" + : "set_tx_status"; + this.sendRPC(rpc_endpoint, params) .then(data => { if (data.hasOwnProperty("error") || !data.hasOwnProperty("result")) { @@ -1467,7 +1489,7 @@ export class WalletRPC { } else { error = `Incorrect result from ${rpc_endpoint} RPC call`; } - this.sendGateway("set_tx_status", { + this.sendGateway(gatewayEndpoint, { code: -1, message: error, sending: false @@ -1476,14 +1498,14 @@ export class WalletRPC { } // update state to show a confirm popup - this.sendGateway("set_tx_status", { + this.sendGateway(gatewayEndpoint, { code: 1, i18n: "strings.awaitingConfirmation", sending: false, txData: { // target address for a sweep all address: data.params.address, - isSweepAll: isSweepAll, + isSweepAll: isSweepAllRPC, amountList: data.result.amount_list, metadataList: data.result.tx_metadata_list, feeList: data.result.fee_list, @@ -1494,7 +1516,7 @@ export class WalletRPC { }); }) .catch(err => { - this.sendGateway("set_tx_status", { + this.sendGateway(gatewayEndpoint, { code: -1, message: err.message, sending: false diff --git a/src/components/service_node/service_node_staking.vue b/src/components/service_node/service_node_staking.vue index 743445aa..3709047f 100644 --- a/src/components/service_node/service_node_staking.vue +++ b/src/components/service_node/service_node_staking.vue @@ -73,8 +73,17 @@ class="contribute" @contribute="fillStakingFields" /> + @@ -92,15 +101,16 @@ import WalletPassword from "src/mixins/wallet_password"; import ConfirmDialogMixin from "src/mixins/confirm_dialog_mixin"; import ServiceNodeContribute from "./service_node_contribute"; import ServiceNodeMixin from "src/mixins/service_node_mixin"; +import ConfirmTransactionDialog from "components/confirm_tx_dialog"; -// the case for doing nothing on a tx_status update const DO_NOTHING = 10; export default { name: "ServiceNodeStaking", components: { LokiField, - ServiceNodeContribute + ServiceNodeContribute, + ConfirmTransactionDialog }, mixins: [WalletPassword, ConfirmDialogMixin, ServiceNodeMixin], data() { @@ -112,6 +122,13 @@ export default { // start at min/max for the wallet minStakeAmount: 0, maxStakeAmount: this.unlocked_balance / 1e9 + }, + confirmFields: { + metadataList: [], + isBlink: false, + totalAmount: -1, + destination: "", + totalFees: 0 } }; }, @@ -120,8 +137,9 @@ export default { unlocked_balance: state => state.gateway.wallet.info.unlocked_balance, info: state => state.gateway.wallet.info, stake_status: state => state.gateway.service_node_status.stake, - tx_status: state => state.gateway.tx_status, + sweep_all_status: state => state.gateway.sweep_all_status, award_address: state => state.gateway.wallet.info.address, + confirmSweepAll: state => state.gateway.sweep_all_status.code === 1, is_ready() { return this.$store.getters["gateway/isReady"]; }, @@ -215,6 +233,50 @@ export default { } }, deep: true + }, + sweep_all_status: { + handler(val, old) { + if (val.code == old.code) return; + const { code, message } = val; + switch (code) { + // the "nothing", so we can update state without doing anything + // in particular + case DO_NOTHING: + break; + case 1: + this.buildDialogFieldsSweepAll(val); + break; + case 0: + this.$q.notify({ + type: "positive", + timeout: 1000, + message + }); + this.$v.$reset(); + this.newTx = { + amount: 0, + address: "", + payment_id: "", + // blink + priority: 5, + address_book: { + save: false, + name: "", + description: "" + }, + note: "" + }; + break; + case -1: + this.$q.notify({ + type: "negative", + timeout: 3000, + message + }); + break; + } + }, + deep: true } }, methods: { @@ -256,6 +318,33 @@ export default { return nodeOfKey; } }, + onConfirmTransaction() { + // put the loading spinner up + this.$store.commit("gateway/set_sweep_all_status", { + code: DO_NOTHING, + message: "Getting sweep all tx information", + sending: true + }); + + const metadataList = this.confirmFields.metadataList; + const isBlink = this.confirmFields.isBlink; + + const relayTxData = { + metadataList, + isBlink, + isSweepAll: true + }; + + // Commit the transaction + this.$gateway.send("wallet", "relay_tx", relayTxData); + }, + onCancelTransaction() { + this.$store.commit("gateway/set_sweep_all_status", { + code: DO_NOTHING, + message: "Cancel the transaction from confirm dialog", + sending: false + }); + }, sweepAllWarning() { this.$q .dialog({ @@ -278,6 +367,9 @@ export default { .onDismiss(() => {}) .onCancel(() => {}); }, + buildDialogFieldsSweepAll(txData) { + this.confirmFields = this.buildDialogFields(txData); + }, areButtonsEnabled() { // if we can find the service node key in the list of service nodes const key = this.service_node.key; @@ -307,12 +399,15 @@ export default { passwordDialog .onOk(password => { password = password || ""; - this.$store.commit("gateway/set_tx_status", { + this.$store.commit("gateway/set_sweep_all_status", { code: DO_NOTHING, message: "Sweeping all", sending: true }); - const newTx = objectAssignDeep.noMutate(tx, { password }); + const newTx = objectAssignDeep.noMutate(tx, { + password, + isSweepAll: true + }); this.$gateway.send("wallet", "transfer", newTx); }) .onDismiss(() => {}) diff --git a/src/css/app.styl b/src/css/app.styl index 41e8b79f..c8597198 100644 --- a/src/css/app.styl +++ b/src/css/app.styl @@ -373,6 +373,35 @@ footer, color: white; } } +.confirm-tx-card { + color: "primary"; + width: 450px; + max-width: 450x; + + .confirm-list { + .q-item { + max-height: 100%; + margin-top: 0; + margin-bottom: 4px; + padding-top: 0; + padding-bottom: 0; + } + } + + .label { + color: #cecece; + padding-right: 6px; + } + .address-value { + word-break: break-word; + } + + .confirm-send-btn { + color: white; + background: $positive; + } +} + .header-popover { background: $primary; diff --git a/src/gateway/gateway.js b/src/gateway/gateway.js index f0c24902..3c40ec22 100644 --- a/src/gateway/gateway.js +++ b/src/gateway/gateway.js @@ -13,10 +13,14 @@ export class Gateway extends EventEmitter { this.scee = new SCEE(); // Set the initial language - let language = LocalStorage.has("language") ? LocalStorage.getItem("language") : "en-us"; + let language = LocalStorage.has("language") + ? LocalStorage.getItem("language") + : "en-us"; this.setLanguage(language); - let theme = LocalStorage.has("theme") ? LocalStorage.getItem("theme") : "dark"; + let theme = LocalStorage.has("theme") + ? LocalStorage.getItem("theme") + : "dark"; this.app.store.commit("gateway/set_app_data", { config: { appearance: { @@ -90,7 +94,10 @@ export class Gateway extends EventEmitter { cancel: { flat: true, label: i18n.t("dialog.buttons.cancel"), - color: this.app.store.state.gateway.app.config.appearance.theme === "dark" ? "white" : "dark" + color: + this.app.store.state.gateway.app.config.appearance.theme === "dark" + ? "white" + : "dark" }, dark: this.app.store.state.gateway.app.config.appearance.theme === "dark" }) @@ -111,7 +118,10 @@ export class Gateway extends EventEmitter { method, data }; - let encrypted_data = this.scee.encryptString(JSON.stringify(message), this.token); + let encrypted_data = this.scee.encryptString( + JSON.stringify(message), + this.token + ); this.ws.send(encrypted_data); } @@ -122,7 +132,9 @@ export class Gateway extends EventEmitter { receive(message) { // should wrap this in a try catch, and if fail redirect to error screen // shouldn't happen outside of dev environment - let decrypted_data = JSON.parse(this.scee.decryptString(message, this.token)); + let decrypted_data = JSON.parse( + this.scee.decryptString(message, this.token) + ); if ( typeof decrypted_data !== "object" || @@ -173,6 +185,15 @@ export class Gateway extends EventEmitter { break; } + case "set_sweep_all_status": { + const data = { ...decrypted_data.data }; + if (data.i18n) { + data.message = this.geti18n(data.i18n); + } + this.app.store.commit("gateway/set_sweep_all_status", data); + break; + } + case "set_lns_status": { const data = { ...decrypted_data.data }; if (data.i18n) { @@ -217,7 +238,10 @@ export class Gateway extends EventEmitter { break; } case "set_old_gui_import_status": - this.app.store.commit("gateway/set_old_gui_import_status", decrypted_data.data); + this.app.store.commit( + "gateway/set_old_gui_import_status", + decrypted_data.data + ); break; case "wallet_list": @@ -260,7 +284,10 @@ export class Gateway extends EventEmitter { break; case "set_update_required": - this.app.store.commit("gateway/set_update_required", decrypted_data.data); + this.app.store.commit( + "gateway/set_update_required", + decrypted_data.data + ); break; } } diff --git a/src/pages/wallet/send.vue b/src/pages/wallet/send.vue index 8f84960a..9aa59c8d 100644 --- a/src/pages/wallet/send.vue +++ b/src/pages/wallet/send.vue @@ -446,35 +446,6 @@ export default {