< template >
< section id = "Content" class = "p-6 pb-24 max-w-3xl mx-auto" >
<!-- Breadcrumb -- >
< div id = "ViewBreadcrumb" class = "mb-8" >
< h1 class = "text-lg text-center font-light relative px-7" >
<!-- Cancel -- >
< button
@ click = "$router.go(-1)"
class = "text-lg text-center px-2 py-1 absolute -left-2 -top-1"
>
< fa icon = "chevron-left" > < / fa >
< / button >
Import Existing Identifier
< / h1 >
< / div >
<!-- Import Account Form -- >
< p class = "text-center text-xl mb-4 font-light" >
Enter your seed phrase below to import your identifier on this device .
< / p >
<!-- id used by puppeteer test script -- >
< textarea
id = "seed-input"
type = "text"
placeholder = "Seed Phrase"
class = "block w-full rounded border border-slate-400 mb-4 px-3 py-2"
v - model = "mnemonic"
/ >
< h3
class = "text-sm uppercase font-semibold mb-3"
@ click = "showAdvanced = !showAdvanced"
>
Advanced
< / h3 >
< div v-if ="showAdvanced" >
Enter a custom derivation path
< input
type = "text"
class = "block w-full rounded border border-slate-400 mb-2 px-3 py-2"
v - model = "derivationPath"
/ >
< span class = "ml-4" >
For previous uPort or Endorser users ,
< a
@ click = "derivationPath = UPORT_DERIVATION_PATH"
class = "text-blue-500"
>
click here to use that value .
< / a >
< / span >
< div class = "mt-4" v-if ="numAccounts == 1" >
< input type = "checkbox" class = "mr-2" v -model = " shouldErase " / >
< label > Erase the previous identifier . < / label >
< / div >
< div v-if ="isNotProdServer()" class="mt-4 text-blue-500" >
<!-- if they click this , fill in the mnemonic seed - input with the test mnemonic -- >
< button @ click = "mnemonic = TEST_USER_0_MNEMONIC" >
Use mnemonic for Test User # 0
< / button >
< / div >
< / div >
< div class = "mt-8" >
< div class = "grid grid-cols-1 sm:grid-cols-2 gap-2" >
< button
@ click = "fromMnemonic()"
class = "block w-full text-center text-lg font-bold uppercase bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-2 py-3 rounded-md"
>
Import
< / button >
< button
@ click = "onCancelClick()"
type = "button"
class = "block w-full text-center text-md uppercase bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-1.5 py-2 rounded-md"
>
Cancel
< / button >
< / div >
< / div >
< / section >
< / template >
< script lang = "ts" >
import { Component , Vue } from "vue-facing-decorator" ;
import { Router } from "vue-router" ;
import { AppString , NotificationIface } from "@/constants/app" ;
import { accountsDB , db , retrieveSettingsForActiveAccount } from "@/db/index" ;
import { MASTER_SETTINGS_KEY } from "@/db/tables/settings" ;
import {
DEFAULT_ROOT_DERIVATION_PATH ,
deriveAddress ,
newIdentifier ,
} from "@/libs/crypto" ;
@ Component ( {
components : { } ,
} )
export default class ImportAccountView extends Vue {
TEST_USER_0_MNEMONIC =
"rigid shrug mobile smart veteran half all pond toilet brave review universe ship congress found yard skate elite apology jar uniform subway slender luggage" ;
UPORT_DERIVATION_PATH = "m/7696500'/0'/0'/0'" ; // for legacy imports, likely never used
AppString = AppString ;
$notify ! : ( notification : NotificationIface , timeout ? : number ) => void ;
apiServer = "" ;
address = "" ;
derivationPath = DEFAULT_ROOT_DERIVATION_PATH ;
mnemonic = "" ;
numAccounts = 0 ;
privateHex = "" ;
publicHex = "" ;
showAdvanced = false ;
shouldErase = false ;
async created ( ) {
await accountsDB . open ( ) ;
this . numAccounts = await accountsDB . accounts . count ( ) ;
// get the server, to help with import on the test server
const settings = await retrieveSettingsForActiveAccount ( ) ;
this . apiServer = settings . apiServer || "" ;
}
public onCancelClick ( ) {
( this . $router as Router ) . back ( ) ;
}
public isNotProdServer ( ) {
return this . apiServer !== AppString . PROD_ENDORSER_API_SERVER ;
}
public async fromMnemonic ( ) {
const mne : string = this . mnemonic . trim ( ) . toLowerCase ( ) ;
try {
[ this . address , this . privateHex , this . publicHex ] = deriveAddress (
mne ,
this . derivationPath ,
) ;
const newId = newIdentifier (
this . address ,
this . publicHex ,
this . privateHex ,
this . derivationPath ,
) ;
await accountsDB . open ( ) ;
if ( this . shouldErase ) {
await accountsDB . accounts . clear ( ) ;
}
await accountsDB . accounts . add ( {
dateCreated : new Date ( ) . toISOString ( ) ,
derivationPath : this . derivationPath ,
did : newId . did ,
identity : JSON . stringify ( newId ) ,
mnemonic : mne ,
publicKeyHex : newId . keys [ 0 ] . publicKeyHex ,
} ) ;
// record that as the active DID
await db . open ( ) ;
await db . settings . update ( MASTER_SETTINGS_KEY , {
activeDid : newId . did ,
} ) ;
( this . $router as Router ) . push ( { name : "account" } ) ;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch ( err : any ) {
console . error ( "Error saving mnemonic & updating settings:" , err ) ;
if ( err == "Error: invalid mnemonic" ) {
this . $notify (
{
group : "alert" ,
type : "danger" ,
title : "Invalid Mnemonic" ,
text : "Please check your mnemonic and try again." ,
} ,
- 1 ,
) ;
} else {
this . $notify (
{
group : "alert" ,
type : "danger" ,
title : "Error" ,
text : "Got an error creating that identifier." ,
} ,
- 1 ,
) ;
}
}
}
}
< / script >