/
account-import-view.js
113 lines (107 loc) · 4.27 KB
/
account-import-view.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import React, {useState, useRef, useEffect} from 'react'
import {StrKey} from '@stellar/stellar-base'
import {Button} from '@stellar-expert/ui-framework'
import {navigation} from '@stellar-expert/navigation'
import {mnemonicWordsList, validateMnemonic, mnemonicToSecret} from '../../util/mnemonic'
import SoloLayoutView from '../layout/solo-layout-view'
import SignupView from '../signup/signup-view'
function processImportedKey(value) {
value = (value || '').trim()
const words = value.toLowerCase().split(/\s+/g)
if (words.length > 20 && words.length < 26) {
const res = {
type: 'passphrase'
}
if (words.length !== 24) {
res.error = 'Account passphrase backup must consist of 24 words'
return res
}
for (const word of words)
if (!mnemonicWordsList.includes(word)) {
res.error = `Invalid word "${word}"`
return res
}
if (!validateMnemonic(value)) {
res.error = 'Invalid backup phrase – check the order of words'
return res
}
//looks like it's all good
res.value = words.join(' ')
res.secret = mnemonicToSecret(value)
return res
}
if (/^S\w{52,58}/.test(value)) {
value = value.toUpperCase()
const res = {
type: 'account secret'
}
if (value.length !== 56) {
res.error = 'Secret key must contain exactly 56 characters'
return res
}
if (!StrKey.isValidEd25519SecretSeed(value)) {
res.error = 'Invalid secret key – check all characters'
return res
}
//looks good
res.value = res.secret = value
return res
}
return {
type: 'unknown'
}
}
export default function AccountImportView({onSuccess}) {
const [pastedValue, pasteValue] = useState('')
const [error, setError] = useState(null)
const [secretToImport, setSecret] = useState(null)
const inputRef = useRef(null)
useEffect(() => inputRef.current && inputRef.current.focus(), [])
function submit(value) {
const {type, secret, error} = processImportedKey(value || pastedValue)
if (secret) return setSecret(secret)
setError({type, details: error})
}
if (secretToImport)
return <SignupView secret={secretToImport} skipOnboarding skipSecretBackup/>
return <SoloLayoutView title="Import Account">
<div className="segment text-small">
<p>
<i className="icon-warning"/>{' '}
Before starting the import process, do not forget to double-check the URL (the domain should
be <code>albedo.link</code>) and SSL validity(a small lock icon on the left of the address bar).
</p>
<p>
Use this tool to import keys from any Stellar wallet or transfer your Albedo account to another
browser/device.
</p>
<p>Copy-paste your key below:</p>
<div className="space">
<textarea value={pastedValue} className="condensed" style={{height: '5.2em'}} ref={c => inputRef.current = c}
onChange={e => {
pasteValue(e.target.value)
setError(null)
}}/>
</div>
<div className="text-tiny dimmed space">
Supported formats:<br/>
- 24-word Albedo account passphrase backup<br/>
- Stellar account secret key (starts with "S…")
</div>
</div>
<div className="row space">
<div className="column column-50">
<Button block onClick={() => submit()}>Next</Button>
</div>
<div className="column column-50">
<Button block outline onClick={() => navigation.navigate('/')}>Cancel</Button>
</div>
</div>
{error && <div className="segment segment-inline error space text-small">
{error.type === 'unknown' ? 'Invalid key format. Use either 24-word passphrase or Stellar secret key.' : <>
Auto-detected import type: <b>{error.type}</b><br/>
Error: {error.details}
</>}
</div>}
</SoloLayoutView>
}