},
backup: {
title: '备份',
- button: '备份'
+ button: '备份',
+ mnemonic:'备份助记词',
+ keystore:'备份Keystore',
+ mnemonicHint:'请抄写助记词,并妥善保管',
+ ok:'已完成'
},
protocol: {
title: 'Bytom Chrome Wallet服务协议',
<figure :class="active('HOME')" v-on:click="toggleTab('HOME')"><i class="iconfont iconhome_filled"></i></figure>
<figure v-on:click=""><i class="iconfont iconbapp_filled"></i></figure>
<figure v-on:click=""><i class="iconfont iconwallet_filled"></i></figure>
- <figure v-on:click=""><i class="iconfont iconbackup_filled"></i></figure>
+ <figure :class="active('BACKUP')" v-on:click="toggleTab('BACKUP')"><i class="iconfont iconbackup_filled"></i></figure>
</section>
<figure class="setting" :class="active('SETTINGS')" v-on:click="toggleTab('SETTINGS')">
<i class="iconfont iconSetting_fiiled" ></i>
RouteNames.SETTINGS_LANG,
RouteNames.SETTINGS_DELETE,
]
+
+ const backup_tab = [
+ RouteNames.BACKUP,
+ RouteNames.BACKUP_MNEMONIC,
+ ]
switch(name){
case 'HOME':{
if(home_tab.includes(this.$route.name)){
}
break;
}
+ case 'BACKUP':{
+ if(backup_tab.includes(this.$route.name)){
+ return "active";
+ }
+ break;
+ }
default:
return ""
return bytom.keys.isValidKeystore(keystore)
}
-
+account.decryptMnemonic = function(vault,password, context) {
+ const keystore = context.bytom.currentAccount.keystore;
+ return bytom.keys.decryptMnemonic(vault, password, keystore)
+}
export default account
// NETWORKS:'networks',
// NETWORK:'network',
// CHANGE_PASSWORD:'changePassword',
- // BACKUP:'backup',
+ BACKUP:'backup',
+ BACKUP_MNEMONIC:'backup-mnemonic',
// DESTROY:'destroy',
// AUTO_LOCK:'autoLock',
// LANGUAGE:'language',
}
},
{
- path: '/menu/backup',
- name: 'menu-backup',
- meta: { title: '备份' },
- component: resolve => {
- require(['@/views/sideMenu/menuBackup.vue'], resolve)
- }
- },
- {
path: '/menu/help',
name: 'menu-help',
meta: { title: '帮助' },
]
},
{
+ path: '/backup',
+ name: RouteNames.BACKUP,
+ meta: { title: '备份' },
+ component: resolve => {
+ require(['@/views/backup/backup.vue'], resolve)
+ },
+ children: [
+ {
+ path: '/backup/mnemonic',
+ name: 'backup-mnemonic',
+ meta: { title: '备份助记词' },
+ component: resolve => {
+ require(['@/views/backup/backupMnemonic.vue'], resolve)
+ }
+ }
+ ]
+ },
+
+ {
path: '/settings',
name: RouteNames.SETTINGS,
meta: { title: '设置' },
[Actions.SET_BYTOM]:({commit}, bytom) => commit(Actions.SET_BYTOM, bytom),
[Actions.SET_LIST_VOTE]:({commit}, listVote) => commit(Actions.SET_LIST_VOTE, listVote),
[Actions.SET_CURRENT_ASSET]:({commit}, currentAsset) => commit(Actions.SET_CURRENT_ASSET, currentAsset),
+ [Actions.SET_MNEMONIC]:({commit}, mnemonic) => commit(Actions.SET_MNEMONIC, mnemonic),
[Actions.SET_SELECTED_VOTE]:({commit}, selectVote) => commit(Actions.SET_SELECTED_VOTE, selectVote),
export const SET_AUTO_LOCK = 'setAutoLock';
export const SET_LIST_VOTE = 'setListVote';
export const SET_CURRENT_ASSET = 'setCurrentAsset';
+export const SET_MNEMONIC = 'setMnemonic';
export const SET_SELECTED_VOTE = 'setSelectVote';
export const LOCK = 'lock';
export const DESTROY = 'destroy';
[Mutations.SET_LIST_VOTE]:(state, listVote) => state.listVote = listVote,
[Mutations.SET_SELECTED_VOTE]:(state, selectVote) => state.selectVote = selectVote,
[Mutations.SET_CURRENT_ASSET]:(state, currentAsset) => state.currentAsset = currentAsset,
+ [Mutations.SET_MNEMONIC]:(state, mnemonic) => state.mnemonic = mnemonic,
// [Mutations.SET_AUTO_LOCK]:(state, inactivityInterval) =>
// state.bytom.settings.inactivityInterval = TimingHelpers.minutes(inactivityInterval),
listVote:[],
selectVote: null,
currentAsset: null,
+ mnemonic:null,
};
const getters = {
--- /dev/null
+<style lang="scss" scoped >
+ .item-block{
+ display: flex;
+ align-items: center;
+ font-weight: 600;
+ font-size: 15px;
+ letter-spacing: 0.2px;
+ i{
+ width: 24px;
+ height: 24px;
+ background: #F5F5F5;
+ font-weight: normal;
+ border-radius: 24px;
+ text-align: center;
+ padding: 10px;
+ }
+ }
+
+ .disable{
+ cursor: not-allowed;
+ color: grey;
+ pointer-events: none;
+
+ &:hover{
+ border:none;
+ padding:14px;
+ }
+ }
+
+
+</style>
+
+<template>
+ <div class="warp-menu bg-grey">
+ <div class="list menu-list">
+ <div :class="['list-item', {disable: !vault}]" @click="$refs.modalPasswd.open()" >
+ <div class="item-block">
+ <i class="iconfont iconbackup_line"></i>{{ $t('backup.mnemonic') }}
+ </div>
+ </div>
+ <div class="list-item" @click="backupKeystore">
+ <div class="item-block">
+ <i class="iconfont iconbackup_line"></i>{{ $t('backup.keystore') }}
+ </div>
+ </div>
+ </div>
+
+ <modal-passwd ref="modalPasswd" @confirm="openMnemonicView"></modal-passwd>
+ <!-- child menu -->
+ <router-view></router-view>
+ </div>
+</template>
+
+
+<script>
+import account from "@/models/account";
+import FileSaver from "file-saver";
+import { mapActions, mapGetters, mapState } from 'vuex'
+import * as Actions from '@/store/constants';
+import {RouteNames} from '@/router'
+
+export default {
+ name: "",
+ data() {
+ return {};
+ },
+ computed: {
+ vault(){
+ if(this.currentAccount){
+ return this.currentAccount.vault;
+ }
+ return undefined;
+ },
+ ...mapState([
+ 'bytom'
+ ]),
+ ...mapGetters([
+ 'currentAccount'
+ ])
+ },
+ methods: {
+ openMnemonicView(password){
+ try{
+ const mnemonic = account.decryptMnemonic(this.vault, password, this)
+ this[Actions.SET_MNEMONIC](mnemonic).then(()=>{
+ this.$router.push({ name: RouteNames.BACKUP_MNEMONIC })
+ })
+ }
+ catch (e){
+ this.$toast.error(
+ e.message || e
+ );
+ }
+
+ },
+ backupKeystore() {
+ const keystore = JSON.stringify(this.currentAccount.keystore)
+ var blob = new Blob([keystore], {
+ type: "text/plain;charset=utf-8"
+ });
+ FileSaver.saveAs(blob, `byone_backup_${+new Date()}.dat`);
+ },
+ ...mapActions([
+ Actions.SET_MNEMONIC
+ ])
+ }
+};
+</script>
--- /dev/null
+<style scoped>
+.mnemonic{
+ font-size: 16px;
+ width: 33%;
+ display: inline-block;
+ font-family: Roboto;
+ font-style: normal;
+ font-weight: 500;
+ text-align: center;
+ color: rgba(0, 0, 0, 0.88);
+ margin: 10px 0;
+ }
+
+ .mnemnonic-box{
+ background: #FAFAFA;
+ border: 2px solid #EBEBEB;
+ box-sizing: border-box;
+ border-radius: 8px;
+ word-break: break-all;
+ padding: 10px;
+ margin:12px 0;
+ }
+ .header{
+ display: flex;
+ }
+ .welcome-title{
+ margin-left: 10px;
+ }
+ .hint{
+ font-size: 14px;
+ letter-spacing: 0.2px;
+ color: rgba(0, 0, 0, 0.64);
+ margin-bottom: 20px;
+ }
+</style>
+
+<template>
+ <div class="warp-child bg-grey">
+ <section class="header">
+ <BackButton :small="true" />
+ <h1 class="color-black">
+ <div class="welcome-title">{{ $t("backup.mnemonic") }}</div>
+ </h1>
+ </section>
+ <section >
+ <div class="mnemnonic-box">
+ <span class="mnemonic" v-for="n in inputMnemonic">{{ n }} </span>
+ </div>
+ <p class="hint">{{ $t('backup.mnemonicHint') }}</p>
+ <button class="btn btn-primary">{{ $t("backup.ok") }}</button>
+ </section>
+ </div>
+</template>
+
+<script>
+
+import { mapActions, mapGetters, mapState } from 'vuex'
+import * as Actions from '@/store/constants';
+import {RouteNames} from '@/router'
+
+export default {
+ name: "",
+ data() {
+ return {};
+ },
+ computed: {
+ inputMnemonic: function () {
+ return this.mnemonic? this.mnemonic.split(' ') :null
+ },
+ ...mapState([
+ 'mnemonic'
+ ])
+ },
+ methods: {
+ ...mapActions([
+ Actions.SET_MNEMONIC
+ ])
+ },
+ mounted() {
+ if (!this.mnemonic){
+ this.$router.push({ name: RouteNames.BACKUP })
+ }
+ },
+ beforeDestroy() {
+ if(this.mnemonic){
+ this[Actions.SET_MNEMONIC](null)
+ }
+ }
+};
+</script>
},
computed: {
currentLanguage(){
- if(this.language === 'cn'){
+ if(this.language === 'cn' || this.language === 'zh'){
return '中文'
}else{
return 'English'
+++ /dev/null
-<style scoped>
-</style>
-
-<template>
- <MenuPage :title="$t('backup.title')">
- <div style="text-align: center">
- <div class="btn btn-primary" @click="backup">{{ $t('backup.button') }}</div>
- </div>
- </MenuPage>
-</template>
-
-<script>
-import account from "@/models/account";
-import FileSaver from "file-saver";
-export default {
- name: "",
- data() {
- return {};
- },
- methods: {
- backup() {
- account.backup().then(txt => {
- var blob = new Blob([txt], {
- type: "text/plain;charset=utf-8"
- });
- FileSaver.saveAs(blob, "bytom_chrome_wallet_backup.txt");
- });
- }
- }
-};
-</script>