Skip to content

Commit 0dd9748

Browse files
committed
Added export seed button
- Created export wallet modals - Updated settings page
1 parent 07eef90 commit 0dd9748

File tree

5 files changed

+121
-3
lines changed

5 files changed

+121
-3
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<div class="modal modal-export-wallet" tabindex="-1" role="dialog">
2+
<div class="modal-dialog" role="document">
3+
<div class="modal-content">
4+
<div class="modal-header">
5+
<h5 class="modal-title">Export wallet seed</h5>
6+
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
7+
<span aria-hidden="true">&times;</span>
8+
</button>
9+
</div>
10+
<div class="modal-body">
11+
<p><strong class="wallet-name"></strong> seed is encrypted. Please enter its password to continue.</p>
12+
<form>
13+
<div class="form-group">
14+
<label>Wallet password</label>
15+
<input type="password" name="passphrase" class="form-control" required>
16+
<div class="invalid-feedback">Input password is not correct</div>
17+
</div>
18+
</form>
19+
</div>
20+
<div class="modal-footer">
21+
<button type="button" class="btn btn-outline-danger" data-dismiss="modal">Cancel</button>
22+
<button type="button" class="btn btn-primary btn-continue">Export wallet</button>
23+
</div>
24+
</div>
25+
</div>
26+
</div>

src/components/modals/view-seed.html

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<div class="modal modal-view-seed" tabindex="-1" role="dialog">
2+
<div class="modal-dialog" role="document">
3+
<div class="modal-content">
4+
<div class="modal-header">
5+
<h5 class="modal-title">Export wallet seed</h5>
6+
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
7+
<span aria-hidden="true">&times;</span>
8+
</button>
9+
</div>
10+
<div class="modal-body">
11+
<table class="seed-table mb-3"></table>
12+
<input type="text" class="form-control seed-input" readonly>
13+
</div>
14+
<div class="modal-footer">
15+
<button type="button" class="btn btn-primary" data-dismiss="modal">Close</button>
16+
</div>
17+
</div>
18+
</div>
19+
</div>

src/index.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,9 @@ <h1 class="navbar-title d-none d-md-block">
6060
<%= require('html-loader!./components/modals/new-wallet.html').default %>
6161
<%= require('html-loader!./components/modals/import-wallet.html').default %>
6262
<%= require('html-loader!./components/modals/edit-wallet.html').default %>
63+
<%= require('html-loader!./components/modals/export-wallet.html').default %>
6364
<%= require('html-loader!./components/modals/delete-wallet.html').default %>
6465
<%= require('html-loader!./components/modals/delete-all-data.html').default %>
66+
<%= require('html-loader!./components/modals/view-seed.html').default %>
6567
</body>
6668
</html>

src/js/ui/walletListRenderer.js

Lines changed: 73 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,11 @@
1919
import $ from 'jquery'
2020
import { attachBusyListener } from './../iotaClient'
2121
import {
22+
decrypt,
2223
getWallets,
2324
walletExists,
2425
isValidSeed,
2526
addWallet,
26-
editWallet,
2727
updateWallet,
2828
deleteWallet
2929
} from './../walletManager'
@@ -32,7 +32,9 @@ const $page = $('section[data-page="settings"]')
3232
const $newWalletModal = $('.modal-new-wallet')
3333
const $importWalletModal = $('.modal-import-wallet')
3434
const $editWalletModal = $('.modal-edit-wallet')
35+
const $exportWalletModal = $('.modal-export-wallet')
3536
const $deleteWalletModal = $('.modal-delete-wallet')
37+
const $viewSeedModal = $('.modal-view-seed')
3638

3739

3840
/**
@@ -42,6 +44,7 @@ function renderWalletList() {
4244
const wallets = getWallets()
4345
let colRight = '<div class="col-auto align-self-center">'
4446
colRight += '<button type="button" class="btn btn-outline-primary btn-sm mr-1 btn-edit-wallet">Edit</button>'
47+
colRight += '<button type="button" class="btn btn-outline-secondary btn-sm mr-1 btn-export-wallet">Export</button>'
4548
colRight += '<button type="button" class="btn btn-outline-danger btn-sm btn-delete-wallet">Delete</button>'
4649
colRight += '</div>'
4750

@@ -94,14 +97,37 @@ function regenerateSeedTable() {
9497
for (let i in numbers) seed += dict[numbers[i] % dict.length]
9598

9699
// Generate table HTML
100+
const tHTML = getSeedTableHTML(seed)
101+
$newWalletModal.find('.seed-table').html(tHTML).data('seed', seed)
102+
}
103+
104+
105+
/**
106+
* Get seed table HTML
107+
* @param {string} seed Decrypted seed
108+
* @return {string} Seed table HTML
109+
*/
110+
function getSeedTableHTML(seed) {
97111
let tHTML = ''
98112
const dim = 9
99113
for (let col=0; col<dim; col++) {
100114
tHTML += '<tr>'
101115
for (let row=0; row<dim; row++) tHTML += '<td>' + seed[col*dim+row] + '</td>'
102116
tHTML += '</tr>'
103117
}
104-
$newWalletModal.find('.seed-table').html(tHTML).data('seed', seed)
118+
return tHTML
119+
}
120+
121+
122+
/**
123+
* Show seed dialog
124+
* @param {string} seed Decrypted seed
125+
*/
126+
function showSeedDialog(seed) {
127+
const tHTML = getSeedTableHTML(seed)
128+
$viewSeedModal.find('.seed-table').html(tHTML)
129+
$viewSeedModal.find('.seed-input').val(seed)
130+
$viewSeedModal.modal('show')
105131
}
106132

107133

@@ -125,6 +151,9 @@ $newWalletModal.find('.btn-continue').click(function() {
125151
showImportWalletModal()
126152
$('.modal-import-wallet [name="seed"]').val(seed)
127153
})
154+
$newWalletModal.on('hidden.bs.modal', function() {
155+
$newWalletModal.find('.seed-table').data('seed', '').html('')
156+
})
128157

129158
$importWalletModal.find('.btn-import').click(function() {
130159
const $form = $importWalletModal.find('form')
@@ -154,6 +183,12 @@ $importWalletModal.find('.btn-import').click(function() {
154183
$importWalletModal.modal('hide')
155184
}
156185
})
186+
$importWalletModal.find('.btn-new-wallet').click(function(e) {
187+
e.preventDefault()
188+
regenerateSeedTable()
189+
$importWalletModal.modal('hide')
190+
$newWalletModal.modal('show')
191+
})
157192

158193

159194
/* EDIT AND DELETE WALLET LISTENERS */
@@ -164,6 +199,17 @@ $page.find('.wallet-list').on('click', '.btn-edit-wallet', function() {
164199
.val($row.find('.wallet-name').text())
165200
.data('index', $row.data('index'))
166201
$editWalletModal.modal('show')
202+
}).on('click', '.btn-export-wallet', function() {
203+
const $row = $(this).closest('.row')
204+
const wallet = getWallets()[$row.data('index')]
205+
const seed = decrypt(wallet.seed, '')
206+
if (seed === null) {
207+
$exportWalletModal.find('.wallet-name').text($row.find('.wallet-name').text())
208+
$exportWalletModal.data('index', $row.data('index'))
209+
$exportWalletModal.modal('show')
210+
} else {
211+
showSeedDialog(seed)
212+
}
167213
}).on('click', '.btn-delete-wallet', function() {
168214
const $row = $(this).closest('.row')
169215
$deleteWalletModal.find('.wallet-name')
@@ -189,12 +235,37 @@ $editWalletModal.find('.btn-continue').click(function() {
189235
$editWalletModal.modal('hide')
190236
})
191237

238+
$exportWalletModal.find('.btn-continue').click(function() {
239+
const $pass = $exportWalletModal.find('input[name="passphrase"]')
240+
const index = $exportWalletModal.data('index')
241+
242+
// Try to decrypt seed
243+
const wallet = getWallets()[index]
244+
const seed = decrypt(wallet.seed, $pass.val())
245+
if (seed === null) {
246+
$pass.addClass('is-invalid')
247+
return
248+
}
249+
250+
// Show wallet seed
251+
$exportWalletModal.modal('hide')
252+
showSeedDialog(seed)
253+
})
254+
$exportWalletModal.on('hidden.bs.modal', function() {
255+
$exportWalletModal.find('input[name="passphrase"]').val('')
256+
})
257+
192258
$deleteWalletModal.find('.btn-continue').click(function() {
193259
deleteWallet($deleteWalletModal.find('.wallet-name').data('index'))
194260
renderWalletList()
195261
$deleteWalletModal.modal('hide')
196262
})
197263

264+
$viewSeedModal.on('hidden.bs.modal', function() {
265+
$viewSeedModal.find('.seed-table').html('')
266+
$viewSeedModal.find('.seed-input').val('')
267+
})
268+
198269

199270
/* BUSY LISTENER */
200271
attachBusyListener(function(isBusy) {

src/js/walletManager.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ function encrypt(payload, pass) {
6565
* @param {string} pass Passphrase
6666
* @return {string} Decrypted text
6767
*/
68-
function decrypt(encrypted, pass) {
68+
export function decrypt(encrypted, pass) {
6969
try {
7070
let res = CryptoJS.AES.decrypt(encrypted, pass).toString(CryptoJS.enc.Utf8)
7171
return isValidSeed(res) ? res : null

0 commit comments

Comments
 (0)