From 4b7f32ceea241b97f4fdc7faeae36c3e21e60692 Mon Sep 17 00:00:00 2001 From: lino Date: Wed, 6 Mar 2019 21:55:00 +0800 Subject: [PATCH 1/4] Improve data validation on send page. --- src/popup/account/send.vue | 7 +++++++ src/popup/account/state-watcher.js | 27 +++++++++++++++++++++++++++ src/popup/account/token/send.vue | 6 ++++++ src/popup/components/input.vue | 12 ++++++++++-- src/popup/locale/en.js | 2 ++ src/popup/locale/zh.js | 2 ++ src/popup/scss/base/_normalize.scss | 4 ++++ 7 files changed, 58 insertions(+), 2 deletions(-) diff --git a/src/popup/account/send.vue b/src/popup/account/send.vue index 62bc44b..0d28be7 100644 --- a/src/popup/account/send.vue +++ b/src/popup/account/send.vue @@ -4,21 +4,26 @@
{{ $t('account.send.fromLabel') }}
{{ activeAddress }}
+ + + +
@@ -86,6 +91,8 @@ methods: { confirmSend() { + if (!this.validateAddress(this.destAddr)) return + this.$loading(this.$t('account.send.confirmLoading')) API.send(this.network || 'testnet', this.activeAddress, this.destAddr, this.value, this.fees, this.desc) diff --git a/src/popup/account/state-watcher.js b/src/popup/account/state-watcher.js index 854ad6c..60e4919 100644 --- a/src/popup/account/state-watcher.js +++ b/src/popup/account/state-watcher.js @@ -14,6 +14,33 @@ export default { }, methods: { + validateAddress (address) { + const from = this.activeAddress || '' + const network = from[0] === 'w' ? 'testnet' : 'mainnet' + address = address || '' + + let valid = true + if (network === 'testnet') { + valid = address[0] === 'w' + } else if (network === 'mainnet') { + valid = address[0] === 'W' + } + + if (valid) { + valid = address.length === 34 + } + + if (!valid) { + this.$toast(network === 'testnet' + ? this.$t('account.send.testnetAddressInvalid') + : this.$t('account.send.addressInvalid'), { + type: 'center' + }) + } + + return valid + }, + handleNetworkChange (network) { this.network = network diff --git a/src/popup/account/token/send.vue b/src/popup/account/token/send.vue index 03da6e1..e550c2b 100644 --- a/src/popup/account/token/send.vue +++ b/src/popup/account/token/send.vue @@ -4,17 +4,21 @@
{{ $t('account.sendToken.fromLabel') }}
{{ activeAddress }}
+ + + @@ -98,6 +102,8 @@ methods: { confirmSend() { + if (!this.validateAddress(this.destAddr)) return + this.$loading(this.$t('account.sendToken.confirmLoading')) // sendToken (network, address, name, regId, destAddress, amount, fees, desc) API.sendToken(this.network || 'testnet', this.activeAddress, this.name, this.regId, this.destAddr, parseFloat(this.amount), this.fees, this.desc) diff --git a/src/popup/components/input.vue b/src/popup/components/input.vue index 466c3ac..c1d5b3b 100644 --- a/src/popup/components/input.vue +++ b/src/popup/components/input.vue @@ -10,7 +10,7 @@ :readonly="readOnly" @input="handleInput"> Date: Thu, 7 Mar 2019 00:57:30 +0800 Subject: [PATCH 2/4] Reject activate account when value equals zero. --- src/popup/account/components/coin-card.vue | 6 ++++++ src/popup/components/input.vue | 1 - src/popup/locale/en.js | 1 + src/popup/locale/zh.js | 1 + 4 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/popup/account/components/coin-card.vue b/src/popup/account/components/coin-card.vue index 02f877b..b1a139c 100644 --- a/src/popup/account/components/coin-card.vue +++ b/src/popup/account/components/coin-card.vue @@ -62,6 +62,12 @@ }, openRegisterConfirm () { + if (this.value === 0) { + this.$toast(this.$t('common.insufficientBalance'), { + type: 'center' + }) + return + } openRegisterConfirmDialog(this.address) }, diff --git a/src/popup/components/input.vue b/src/popup/components/input.vue index c1d5b3b..6625c7a 100644 --- a/src/popup/components/input.vue +++ b/src/popup/components/input.vue @@ -100,7 +100,6 @@ resize: none; font-size: 16px; line-height: 30px; - letter-spacing: 2px; height: 120px; } diff --git a/src/popup/locale/en.js b/src/popup/locale/en.js index cf0f167..a5f6243 100644 --- a/src/popup/locale/en.js +++ b/src/popup/locale/en.js @@ -6,6 +6,7 @@ export default { copySuccess: 'Copy success', passwordError: 'The password entered are incorrect', passwordInConsistent: 'The passwords entered twice are inconsistent, please check', + insufficientBalance: 'Insufficient balance', fast: 'Fast', slow: 'Slow', minerFee: 'Fee', diff --git a/src/popup/locale/zh.js b/src/popup/locale/zh.js index 5783f18..a9644a3 100644 --- a/src/popup/locale/zh.js +++ b/src/popup/locale/zh.js @@ -6,6 +6,7 @@ export default { copySuccess: '复制成功', passwordError: '密码错误', passwordInConsistent: '两次输入的密码不一致,请检查', + insufficientBalance: '余额不足', fast: '快', slow: '慢', minerFee: '矿工费', From e1067649680c99ecdc29223e3ad79632200e101e Mon Sep 17 00:00:00 2001 From: lino Date: Thu, 7 Mar 2019 01:34:30 +0800 Subject: [PATCH 3/4] Improve validation: remain user to activate account when submit transaction. --- src/backend/wallet/index.js | 110 ++++++++------------ src/backend/wallet/storage/vault-storage.js | 3 - src/popup/api/format-error.js | 12 ++- src/popup/locale/en.js | 1 + src/popup/locale/zh.js | 1 + 5 files changed, 57 insertions(+), 70 deletions(-) diff --git a/src/backend/wallet/index.js b/src/backend/wallet/index.js index a86b306..0281eb0 100644 --- a/src/backend/wallet/index.js +++ b/src/backend/wallet/index.js @@ -20,8 +20,28 @@ const getWiccApi = (network) => { return new WiccAPI(network) } -const getMnemonic = (address) => { - return vaultStorage.getMnemonic(address) +const getSignInfo = (network, address) => { + const baasApi = new BaasAPI(network) + let srcRegId = null + + return baasApi.getAccountInfo(address).then((data) => { + srcRegId = data.regID + + if (!srcRegId || !String(srcRegId).trim()) { + throw new Error('ADDRESS_NOT_ACTIVATED') + } + + return baasApi.getBlockInfo() + }).then((data) => { + const height = data.syncheight + const privateKey = vaultStorage.getPrivateKey(address) + + return { + srcRegId, + height, + privateKey + } + }) } export default { @@ -196,8 +216,8 @@ export default { vaultStorage.logout() }, - async getMnemonic ({ network, address }) { - return getMnemonic(address) + async getMnemonic ({ address }) { + return vaultStorage.getMnemonic(address) }, async getPrivateKey ({ network, address }) { @@ -243,6 +263,12 @@ export default { } }, + getTransHistory ({ network, address }) { + return transStorage.list(network, address).then((value) => { + return value || [] + }) + }, + registerAccount ({ address }) { const network = getAddressNetwork(address) const wiccApi = getWiccApi(network) @@ -264,23 +290,11 @@ export default { }) }, - getTransHistory ({ network, address }) { - return transStorage.list(network, address).then((value) => { - return value || [] - }) - }, - callContract ({ network, address, destRegId, value, fees, contract }) { const wiccApi = getWiccApi(network) const baasApi = new BaasAPI(network) - let srcRegId = null - - return baasApi.getAccountInfo(address).then((data) => { - srcRegId = data.regID - return baasApi.getBlockInfo() - }).then((data) => { - const height = data.syncheight - const privateKey = vaultStorage.getPrivateKey(address) + + return getSignInfo(network, address).then(({ srcRegId, height, privateKey }) => { return wiccApi.createContractSign(privateKey, height, srcRegId, destRegId, value, fees, contract) }).then((sign) => { return baasApi.submitOfflineTrans(sign) @@ -294,14 +308,8 @@ export default { publishContract ({ network, address, fees, script, scriptDesc }) { const wiccApi = getWiccApi(network) const baasApi = new BaasAPI(network) - let srcRegId = null - - return baasApi.getAccountInfo(address).then((data) => { - srcRegId = data.regID - return baasApi.getBlockInfo() - }).then((data) => { - const height = data.syncheight - const privateKey = vaultStorage.getPrivateKey(address) + + return getSignInfo(network, address).then(({ srcRegId, height, privateKey }) => { return wiccApi.createRegisterAppSign(privateKey, height, srcRegId, fees, script, scriptDesc) }).then((sign) => { return baasApi.submitOfflineTrans(sign) @@ -309,23 +317,14 @@ export default { transStorage.append(network, address, 5, value) return value - }).catch((error) => { - console.log('publish contract error:', error) - throw error }) }, send ({ network, address, destAddr, value, fees, desc }) { const wiccApi = getWiccApi(network) const baasApi = new BaasAPI(network) - let srcRegId = null - - return baasApi.getAccountInfo(address).then((data) => { - srcRegId = data.regID - return baasApi.getBlockInfo() - }).then((data) => { - const height = data.syncheight - const privateKey = vaultStorage.getPrivateKey(address) + + return getSignInfo(network, address).then(({ srcRegId, height, privateKey }) => { return wiccApi.createTxSign(privateKey, height, srcRegId, destAddr, value, fees) }).then((sign) => { return baasApi.submitOfflineTrans(sign) @@ -339,7 +338,6 @@ export default { async vote ({ network, address, votes, fees }) { const wiccApi = getWiccApi(network) const baasApi = new BaasAPI(network) - let srcRegId = null votes = votes || [] if (votes.length === 0) { @@ -359,12 +357,7 @@ export default { }) })) - return baasApi.getAccountInfo(address).then((data) => { - srcRegId = data.regID - return baasApi.getBlockInfo() - }).then((data) => { - const height = data.syncheight - const privateKey = vaultStorage.getPrivateKey(address) + return getSignInfo(network, address).then(({ srcRegId, height, privateKey }) => { // createDelegateTxSign (privateKey, height, srcRegId, delegateData, fees) return wiccApi.createDelegateTxSign(privateKey, height, srcRegId, delegateData, fees) }).then((sign) => { @@ -373,22 +366,15 @@ export default { transStorage.append(network, address, 6, value) return value - }).catch((error) => { - console.log('vote error:', error) - throw error }) }, getAccountInfo ({ network, address }) { - const baasApi = new BaasAPI(network) - - return baasApi.getAccountInfo(address) + return new BaasAPI(network).getAccountInfo(address) }, getTokenInfo ({ network, address, regId }) { - const baasApi = new BaasAPI(network) - - return baasApi.getTokenInfo(regId, address) + return new BaasAPI(network).getTokenInfo(regId, address) }, async addToken ({ accountId, network, name, regId, precision }) { @@ -410,14 +396,8 @@ export default { async sendToken ({ network, address, regId, destAddress, amount, fees, desc, name }) { const wiccApi = getWiccApi(network) const baasApi = new BaasAPI(network) - let srcRegId = null - - return baasApi.getAccountInfo(address).then((data) => { - srcRegId = data.regID - return baasApi.getBlockInfo() - }).then((data) => { - const height = data.syncheight - const privateKey = vaultStorage.getPrivateKey(address) + + return getSignInfo(network, address).then(({ srcRegId, height, privateKey }) => { const contract = getSendTokenContract(destAddress, amount * Math.pow(10, 8)) return wiccApi.createContractSign(privateKey, height, srcRegId, regId, 0, fees, contract) }).then((sign) => { @@ -428,9 +408,6 @@ export default { tokenTransStorage.append(network, address, name, regId, destAddress, amount, desc, txObject) return txObject - }).catch((error) => { - console.log('send token error:', error) - throw error }) }, @@ -444,7 +421,10 @@ export default { data = data || {} return new Promise((resolve, reject) => { if (typeof this[action] === 'function') { - this[action](data).then(resolve, reject) + this[action](data).then(resolve, (error) => { + console.log('action failed:', action, data, error) + reject(error) + }) } else { reject(new Error('unknown action ' + action)) } diff --git a/src/backend/wallet/storage/vault-storage.js b/src/backend/wallet/storage/vault-storage.js index ccf856d..0809a4e 100644 --- a/src/backend/wallet/storage/vault-storage.js +++ b/src/backend/wallet/storage/vault-storage.js @@ -244,9 +244,6 @@ export default { }) }, - async importWallet (password, mnemonic) { - }, - async unlock (password, vaultBlob) { state.vaultBlob = vaultBlob return passworder.decrypt(password, vaultBlob).then((value) => { diff --git a/src/popup/api/format-error.js b/src/popup/api/format-error.js index 6061cb2..bef6baf 100644 --- a/src/popup/api/format-error.js +++ b/src/popup/api/format-error.js @@ -1,8 +1,16 @@ +import i18nUtil from './i18n' +import locale from '../locale' + export default function (error) { if (!error) return '' - if (error.message) { - return error.message + const message = error.message + + if (message === 'ADDRESS_NOT_ACTIVATED') { + const language = i18nUtil.getLanguage() + return locale[language].common.accountNotActivated + } else if (message) { + return message } return JSON.stringify(error) diff --git a/src/popup/locale/en.js b/src/popup/locale/en.js index a5f6243..8875635 100644 --- a/src/popup/locale/en.js +++ b/src/popup/locale/en.js @@ -7,6 +7,7 @@ export default { passwordError: 'The password entered are incorrect', passwordInConsistent: 'The passwords entered twice are inconsistent, please check', insufficientBalance: 'Insufficient balance', + accountNotActivated: 'Please activate you wallet first', fast: 'Fast', slow: 'Slow', minerFee: 'Fee', diff --git a/src/popup/locale/zh.js b/src/popup/locale/zh.js index a9644a3..d15a1d2 100644 --- a/src/popup/locale/zh.js +++ b/src/popup/locale/zh.js @@ -7,6 +7,7 @@ export default { passwordError: '密码错误', passwordInConsistent: '两次输入的密码不一致,请检查', insufficientBalance: '余额不足', + accountNotActivated: '请先激活钱包', fast: '快', slow: '慢', minerFee: '矿工费', From 2ea41004cf8f0061c9f66396418e928b079c493c Mon Sep 17 00:00:00 2001 From: lino Date: Thu, 7 Mar 2019 02:34:01 +0800 Subject: [PATCH 4/4] Restore validate mnemonic page when creating wallet or account. --- src/backend/wallet/index.js | 2 +- src/popup/main/index.vue | 46 ------------------- src/popup/main/{welcome.vue => splash.vue} | 21 ++++++++- src/popup/router.js | 14 ++---- src/popup/wallet/create/mnemonic.js | 7 +-- .../wallet/create/step-backup-mnemonic.vue | 16 ++++--- src/popup/wallet/create/step-password.vue | 9 ++-- .../wallet/create/step-validate-mnemonic.vue | 37 +++++++++++---- 8 files changed, 70 insertions(+), 82 deletions(-) delete mode 100644 src/popup/main/index.vue rename src/popup/main/{welcome.vue => splash.vue} (78%) diff --git a/src/backend/wallet/index.js b/src/backend/wallet/index.js index 0281eb0..06bc598 100644 --- a/src/backend/wallet/index.js +++ b/src/backend/wallet/index.js @@ -229,7 +229,7 @@ export default { }, async getState () { - const state = stateStore.getState() + const state = stateStore.getState() || {} let isLocked = !!state.isLocked if (!vaultStorage.isLogin()) { isLocked = true diff --git a/src/popup/main/index.vue b/src/popup/main/index.vue deleted file mode 100644 index 5bfd271..0000000 --- a/src/popup/main/index.vue +++ /dev/null @@ -1,46 +0,0 @@ - - - - - diff --git a/src/popup/main/welcome.vue b/src/popup/main/splash.vue similarity index 78% rename from src/popup/main/welcome.vue rename to src/popup/main/splash.vue index 2fed809..eff9c92 100644 --- a/src/popup/main/welcome.vue +++ b/src/popup/main/splash.vue @@ -59,8 +59,25 @@ this.isLocked = state.isLocked this.vaultCreated = state.vaultCreated - if (!this.isLocked && this.vaultCreated) { - this.gotoMain() + if (!this.isLocked || !this.vaultCreated) { + const restoreConfigString = localStorage.getItem('WICC_RESTORE_PATH') + + if (restoreConfigString) { + try { + const restoreConfig = JSON.parse(restoreConfigString) + if (restoreConfig) { + return this.$router.push(restoreConfig) + } + } catch (error) { + console.log('parse restore config error:', error) + } finally { + localStorage.setItem('WICC_RESTORE_PATH', null) + } + } + + if (this.vaultCreated) { + this.gotoMain() + } } }, (error) => { this.loading = false diff --git a/src/popup/router.js b/src/popup/router.js index ad76e44..579bb2c 100644 --- a/src/popup/router.js +++ b/src/popup/router.js @@ -22,10 +22,9 @@ import SendToken from './account/token/send' import TokenMain from './account/token/main' /** - * Stage related page + * Splash related page */ -import Main from './main/index' -import Welcome from './main/welcome' +import Splash from './main/splash' /** * Setting Related page @@ -46,7 +45,7 @@ const router = new VueRouter({ { name: 'welcome', path: '/', - component: Welcome + component: Splash }, { @@ -133,13 +132,6 @@ const router = new VueRouter({ }] }, - { - name: 'main', - path: '/main', - component: Main, - children: [] - }, - { name: 'setting', path: '/setting', diff --git a/src/popup/wallet/create/mnemonic.js b/src/popup/wallet/create/mnemonic.js index ea8f87b..9154857 100644 --- a/src/popup/wallet/create/mnemonic.js +++ b/src/popup/wallet/create/mnemonic.js @@ -9,11 +9,12 @@ export default { if (lastSaved) { try { let status = JSON.parse(lastSaved) - if (Date.now() - status.createdAt < STORAGE_TIME) { + + if (status && (Date.now() - status.createdAt < STORAGE_TIME)) { return Promise.resolve(status.data) } - } catch (e) { - console.log('parse saved mnemonic error', e) + } catch (error) { + console.log('parse saved mnemonic error:', error) } } diff --git a/src/popup/wallet/create/step-backup-mnemonic.vue b/src/popup/wallet/create/step-backup-mnemonic.vue index e659d23..b97ef50 100644 --- a/src/popup/wallet/create/step-backup-mnemonic.vue +++ b/src/popup/wallet/create/step-backup-mnemonic.vue @@ -25,9 +25,8 @@