diff --git a/quasar.conf.js b/quasar.conf.js index eabf426..06426a5 100644 --- a/quasar.conf.js +++ b/quasar.conf.js @@ -86,7 +86,8 @@ module.exports = function (ctx) { "QCollapsible", "QCheckbox", "QInnerLoading", - "QInfiniteScroll" + "QInfiniteScroll", + "QDatetime" ], directives: [ "Ripple", diff --git a/src-electron/main-process/modules/daemon.js b/src-electron/main-process/modules/daemon.js index a823631..e827833 100644 --- a/src-electron/main-process/modules/daemon.js +++ b/src-electron/main-process/modules/daemon.js @@ -186,6 +186,81 @@ export class Daemon { } + timestampToHeight(timestamp, pivot=null, recursion_limit=null) { + + return new Promise((resolve, reject) => { + + if(timestamp > 999999999999) { + // We have got a JS ms timestamp, convert + timestamp = Math.floor(timestamp / 1000) + } + + pivot = pivot || [137500, 1528073506] + recursion_limit = recursion_limit || 0; + + let diff = Math.floor((timestamp - pivot[1]) / 240) + let estimated_height = pivot[0] + diff + + if(estimated_height <= 0) { + return resolve(0) + } + + if(recursion_limit > 10) { + return resolve(pivot[0]) + } + + this.getRPC("block_header_by_height", {height: estimated_height}).then((data) => { + + if(data.hasOwnProperty("error") || !data.hasOwnProperty("result")) { + if(data.error.code == -2) { // Too big height + + this.getRPC("last_block_header").then((data) => { + if(data.hasOwnProperty("error") || !data.hasOwnProperty("result")) { + return reject() + } + + let new_pivot = [data.result.block_header.height, data.result.block_header.timestamp] + + // If we are within an hour that is good enough + // If for some reason there is a > 1h gap between blocks + // the recursion limit will take care of infinite loop + if(Math.abs(timestamp - new_pivot[1]) < 3600) { + return resolve(new_pivot[0]) + } + + // Continue recursion with new pivot + resolve(new_pivot) + }) + return + } else { + return reject() + } + } + + let new_pivot = [data.result.block_header.height, data.result.block_header.timestamp] + + // If we are within an hour that is good enough + // If for some reason there is a > 1h gap between blocks + // the recursion limit will take care of infinite loop + if(Math.abs(timestamp - new_pivot[1]) < 3600) { + return resolve(new_pivot[0]) + } + + // Continue recursion with new pivot + resolve(new_pivot) + + }) + }).then((pivot_or_height) => { + + return Array.isArray(pivot_or_height) + ? this.timestampToHeight(timestamp, pivot_or_height, recursion_limit + 1) + : pivot_or_height + + }).catch(error => { + return false + }) + } + startHeartbeat() { clearInterval(this.heartbeat) this.heartbeat = setInterval(() => { diff --git a/src-electron/main-process/modules/wallet-rpc.js b/src-electron/main-process/modules/wallet-rpc.js index ebf55c8..ed59536 100644 --- a/src-electron/main-process/modules/wallet-rpc.js +++ b/src-electron/main-process/modules/wallet-rpc.js @@ -167,11 +167,13 @@ export class WalletRPC { break case "restore_wallet": - this.restoreWallet(params.name, params.password, params.seed, params.refresh_start_height) + this.restoreWallet(params.name, params.password, params.seed, + params.refresh_type, params.refresh_type=="date" ? params.refresh_start_date : params.refresh_start_height) break case "restore_view_wallet": - this.restoreViewWallet(params.name, params.password, params.address, params.viewkey, params.refresh_start_height) + this.restoreViewWallet(params.name, params.password, params.address, params.viewkey, + params.refresh_type, params.refresh_type=="date" ? params.refresh_start_date : params.refresh_start_height) break case "import_wallet": @@ -261,7 +263,19 @@ export class WalletRPC { } - restoreWallet(filename, password, seed, refresh_start_height=0) { + restoreWallet(filename, password, seed, refresh_type, refresh_start_timestamp_or_height) { + + if(refresh_type == "date") { + this.backend.daemon.timestampToHeight(refresh_start_timestamp_or_height).then((height) => { + if(height === false) + this.sendGateway("set_wallet_error", {status:{code: -1, message: "Invalid restore date"}}) + else + this.restoreWallet(filename, password, seed, "height", height) + }) + return + } + + let refresh_start_height = refresh_start_timestamp_or_height if(!Number.isInteger(refresh_start_height)) { refresh_start_height = 0 @@ -302,7 +316,19 @@ export class WalletRPC { }); } - restoreViewWallet(filename, password, address, viewkey, refresh_start_height=0) { + restoreViewWallet(filename, password, address, viewkey, refresh_type, refresh_start_timestamp_or_height) { + + if(refresh_type == "date") { + this.backend.daemon.timestampToHeight(refresh_start_timestamp_or_height).then((height) => { + if(height === false) + this.sendGateway("set_wallet_error", {status:{code: -1, message: "Invalid restore date"}}) + else + this.restoreViewWallet(filename, password, address, viewkey, "height", height) + }) + return + } + + let refresh_start_height = refresh_start_timestamp_or_height if(!Number.isInteger(refresh_start_height)) { refresh_start_height = 0 @@ -723,7 +749,6 @@ export class WalletRPC { wallet.secret[n.params.key_type] = n.result.key } - console.log("send secrets") this.sendGateway("set_wallet_data", wallet) }) @@ -1117,7 +1142,6 @@ export class WalletRPC { } this.sendRPC("change_wallet_password", {old_password, new_password}).then((data) => { - console.log(data) if(data.hasOwnProperty("error") || !data.hasOwnProperty("result")) { this.sendGateway("show_notification", {type: "negative", message: "Error changing password", timeout: 2000}) return diff --git a/src/pages/wallet-select/import-view-only.vue b/src/pages/wallet-select/import-view-only.vue index 9901d93..53c6b0e 100644 --- a/src/pages/wallet-select/import-view-only.vue +++ b/src/pages/wallet-select/import-view-only.vue @@ -32,12 +32,43 @@ - +
+
+ + +
+
+ + +
+
@@ -65,7 +96,9 @@ export default { name: "", address: "", viewkey: "", + refresh_type: "date", refresh_start_height: 0, + refresh_start_date: 1492486495000, // timestamp of block 1 password: "", password_confirm: "" }, diff --git a/src/pages/wallet-select/restore.vue b/src/pages/wallet-select/restore.vue index e92a6e4..1bff36d 100644 --- a/src/pages/wallet-select/restore.vue +++ b/src/pages/wallet-select/restore.vue @@ -23,12 +23,43 @@ - +
+
+ + +
+
+ + +
+
@@ -54,7 +85,9 @@ export default { wallet: { name: "", seed: "", + refresh_type: "date", refresh_start_height: 0, + refresh_start_date: 1492486495000, // timestamp of block 1 password: "", password_confirm: "" },