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 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Switch to
height select
+
+
+
+
+
+
+
+
Switch to
date select
+
+
+
+
+
@@ -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 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Switch to
height select
+
+
+
+
+
+
+
+
Switch to
date select
+
+
+
+
+
@@ -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: ""
},