@@ -17,9 +17,15 @@ var cluster = require('cluster');
17
17
var child_process = require ( 'child_process' ) ;
18
18
var Path = require ( 'path' ) ;
19
19
20
- var ledger = require ( 'ledgerco' )
21
- var LedgerArk = require ( './src/LedgerArk.js' ) ;
22
- var ledgerWorker = child_process . fork ( Path . resolve ( __dirname , './ledger-worker' ) ) ;
20
+ var ledgerSupported = true ;
21
+ try {
22
+ var ledger = require ( 'ledgerco' ) ;
23
+ var LedgerArk = require ( './src/LedgerArk.js' ) ;
24
+ var ledgerWorker = child_process . fork ( Path . resolve ( __dirname , './ledger-worker' ) ) ;
25
+ } catch ( USBError ) {
26
+ ledgerSupported = false ;
27
+ vorpal . log ( colors . yellow ( "Warning: Ark-Client is running on a server or virtual machine: No Ledger support available." ) ) ;
28
+ }
23
29
24
30
var blessed = require ( 'blessed' ) ;
25
31
var contrib = require ( 'blessed-contrib' ) ;
@@ -43,7 +49,8 @@ var networks = {
43
49
"167.114.29.53:4002" ,
44
50
"167.114.29.54:4002" ,
45
51
"167.114.29.55:4002"
46
- ]
52
+ ] ,
53
+ ledgerpath : "44'/1'/"
47
54
} ,
48
55
mainnet : {
49
56
nethash : "6e84d08bd299ed97c212c886c98a57e36545c8f5d645ca7eeae63a8bd62d8988" ,
@@ -94,7 +101,8 @@ var networks = {
94
101
"193.70.72.88:4001" ,
95
102
"193.70.72.89:4001" ,
96
103
"193.70.72.90:4001"
97
- ]
104
+ ] ,
105
+ ledgerpath : "44'/111'/"
98
106
}
99
107
} ;
100
108
@@ -156,35 +164,39 @@ function postTransaction(container, transaction, cb){
156
164
157
165
let senderAddress = arkjs . crypto . getAddress ( transaction . senderPublicKey ) ;
158
166
getFromNode ( 'http://' + server + '/api/accounts?address=' + senderAddress , function ( err , response , body ) {
159
- if ( ! body ) {
160
- performPost ( ) ;
161
- } else {
162
- body = JSON . parse ( body ) ;
163
- if ( body . account . secondSignature ) {
164
- container . prompt ( {
165
- type : 'password' ,
166
- name : 'passphrase' ,
167
- message : 'Second passphrase: ' ,
168
- } , function ( result ) {
169
- if ( result . passphrase ) {
170
- var secondKeys = arkjs . crypto . getKeys ( result . passphrase ) ;
171
- arkjs . crypto . secondSign ( transaction , secondKeys ) ;
172
- transaction . id = arkjs . crypto . getId ( transaction ) ;
173
- performPost ( ) ;
174
- } else {
175
- vorpal . log ( 'No second passphrase given. Trying without.' ) ;
176
- performPost ( ) ;
177
- }
178
- } ) ;
179
- } else {
180
- performPost ( ) ;
181
- }
182
- }
167
+
168
+ if ( ! err && body ) {
169
+ try {
170
+ body = JSON . parse ( body ) ;
171
+ if ( ! body . hasOwnProperty ( 'success' ) || body . success === false ) {
172
+ // The account does not yet exist on the connected node.
173
+ throw "Failed: " + body . error ;
174
+ }
175
+ if ( body . hasOwnProperty ( 'account' ) && body . account . secondSignature ) {
176
+ container . prompt ( {
177
+ type : 'password' ,
178
+ name : 'passphrase' ,
179
+ message : 'Second passphrase: ' ,
180
+ } , function ( result ) {
181
+ if ( result . passphrase ) {
182
+ var secondKeys = arkjs . crypto . getKeys ( result . passphrase ) ;
183
+ arkjs . crypto . secondSign ( transaction , secondKeys ) ;
184
+ transaction . id = arkjs . crypto . getId ( transaction ) ;
185
+ } else {
186
+ vorpal . log ( 'No second passphrase given. Trying without.' ) ;
187
+ }
188
+ } ) ;
189
+ }
190
+ } catch ( error ) {
191
+ vorpal . log ( colors . red ( error ) ) ;
192
+ }
193
+ } // if(body)
194
+ performPost ( ) ;
183
195
} ) ;
184
196
}
185
197
186
198
function getFromNode ( url , cb ) {
187
- nethash = network ?network . nethash :"" ;
199
+ let nethash = network ?network . nethash :"" ;
188
200
request (
189
201
{
190
202
url : url ,
@@ -221,7 +233,7 @@ function getAccount(container, seriesCb) {
221
233
}
222
234
} ) ;
223
235
}
224
- if ( ledgerAccounts . length ) {
236
+ if ( ledgerSupported && ledgerAccounts . length ) {
225
237
var message = 'We have found the following Ledgers: \n' ;
226
238
ledgerAccounts . forEach ( function ( ledger , index ) {
227
239
var balance = network . config . symbol + ( ledger . data . accountData . balance / 100000000 ) ;
@@ -252,14 +264,23 @@ function getAccount(container, seriesCb) {
252
264
}
253
265
}
254
266
267
+ function resetLedger ( ) {
268
+ ledgerAccounts = [ ] ;
269
+ ledgerBridge = null ;
270
+ if ( ledgerComm !== null ) {
271
+ ledgerComm . close_async ( ) ;
272
+ ledgerComm = null ;
273
+ }
274
+ }
275
+
255
276
async function populateLedgerAccounts ( ) {
256
- if ( ! ledgerBridge ) {
277
+ if ( ! ledgerSupported || ! ledgerBridge ) {
257
278
return ;
258
279
}
259
280
ledgerAccounts = [ ] ;
260
281
var accounts = [ ] ;
261
282
var account_index = 0 ;
262
- var path = "44'/111'/" ;
283
+ var path = network . hasOwnProperty ( 'ledgerpath' ) ? network . ledgerpath : "44'/111'/" ;
263
284
var empty = false ;
264
285
265
286
while ( ! empty ) {
@@ -287,11 +308,22 @@ async function populateLedgerAccounts() {
287
308
( body ) => { accountData = body }
288
309
) ;
289
310
if ( ! accountData || accountData . success === false ) {
311
+ // Add an empty available account when 0 transactions have been made.
290
312
empty = true ;
291
- result = null ;
313
+ result . accountData = {
314
+ address : result . address ,
315
+ unconfirmedBalance : "0" ,
316
+ balance : "0" ,
317
+ publicKey : result . publicKey ,
318
+ unconfirmedSignature : 0 ,
319
+ secondSignature : 0 ,
320
+ secondPublicKey : null ,
321
+ multisignatures : [ ] ,
322
+ u_multisignatures : [ ]
323
+ } ;
292
324
} else {
293
325
result . accountData = accountData . account ;
294
- }
326
+ }
295
327
}
296
328
} catch ( e ) {
297
329
console . log ( 'no request:' , e ) ;
@@ -314,7 +346,7 @@ async function populateLedgerAccounts() {
314
346
}
315
347
316
348
async function ledgerSignTransaction ( seriesCb , transaction , account , callback ) {
317
- if ( ! account . publicKey || ! account . path ) {
349
+ if ( ! ledgerSupported || ! account . publicKey || ! account . path ) {
318
350
return callback ( transaction ) ;
319
351
}
320
352
@@ -343,27 +375,33 @@ async function ledgerSignTransaction(seriesCb, transaction, account, callback) {
343
375
callback ( transaction ) ;
344
376
}
345
377
378
+ if ( ledgerSupported ) {
346
379
ledgerWorker . on ( 'message' , function ( message ) {
347
380
if ( message . connected && network && ( ! ledgerComm || ! ledgerAccounts . length ) ) {
348
381
ledger . comm_node . create_async ( ) . then ( ( comm ) => {
349
382
ledgerComm = comm ;
350
383
ledgerBridge = new LedgerArk ( ledgerComm ) ;
351
384
populateLedgerAccounts ( ) ;
352
385
} ) . fail ( ( error ) => {
353
- //console .log('ledger error: ', error);
386
+ //vorpal .log(colors.red( 'ledger error: ' + error) );
354
387
} ) ;
355
388
} else if ( ! message . connected && ledgerComm ) {
356
389
vorpal . log ( 'Ledger App Disconnected' ) ;
357
- ledgerComm . close_async ( ) ;
358
- ledgerComm = null ;
359
- ledgerBridge = null ;
360
- ledgerAccounts = [ ] ;
390
+ resetLedger ( ) ;
361
391
} ;
362
392
} ) ;
393
+ }
363
394
364
395
vorpal
365
396
. command ( 'connect <network>' , 'Connect to network. Network is devnet or mainnet' )
366
397
. action ( function ( args , callback ) {
398
+ // reset an existing connection first
399
+ if ( server ) {
400
+ server = null ;
401
+ network = null ;
402
+ resetLedger ( ) ;
403
+ }
404
+
367
405
var self = this ;
368
406
network = networks [ args . network ] ;
369
407
@@ -406,6 +444,13 @@ function connect2network(n, callback){
406
444
vorpal
407
445
. command ( 'connect node <url>' , 'Connect to a server. For example "connect node 5.39.9.251:4000"' )
408
446
. action ( function ( args , callback ) {
447
+ // reset an existing connection first
448
+ if ( server ) {
449
+ server = null ;
450
+ network = null ;
451
+ resetLedger ( ) ;
452
+ }
453
+
409
454
var self = this ;
410
455
server = args . url ;
411
456
getFromNode ( 'http://' + server + '/api/blocks/getNethash' , function ( err , response , body ) {
@@ -458,6 +503,8 @@ vorpal
458
503
server = null ;
459
504
network = null ;
460
505
connected = false ;
506
+
507
+ resetLedger ( ) ;
461
508
callback ( ) ;
462
509
} ) ;
463
510
@@ -653,7 +700,11 @@ vorpal
653
700
} , function ( result ) {
654
701
if ( result . continue ) {
655
702
if ( currentVote ) {
656
- var unvoteTransaction = arkjs . vote . createVote ( passphrase , [ '-' + currentVote . publicKey ] ) ;
703
+ try {
704
+ var unvoteTransaction = arkjs . vote . createVote ( passphrase , [ '-' + currentVote . publicKey ] ) ;
705
+ } catch ( error ) {
706
+ return seriesCb ( 'Failed: ' + error ) ;
707
+ }
657
708
ledgerSignTransaction ( seriesCb , unvoteTransaction , account , function ( unvoteTransaction ) {
658
709
if ( ! unvoteTransaction ) {
659
710
return seriesCb ( 'Failed to sign unvote transaction with ledger' ) ;
@@ -674,7 +725,11 @@ vorpal
674
725
return seriesCb ( 'Failed to fetch unconfirmed transaction: ' + body . error ) ;
675
726
} else if ( body . transaction ) {
676
727
clearInterval ( checkTransactionTimerId ) ;
677
- var transaction = arkjs . vote . createVote ( passphrase , [ '+' + newDelegate . publicKey ] ) ;
728
+ try {
729
+ var transaction = arkjs . vote . createVote ( passphrase , [ '+' + newDelegate . publicKey ] ) ;
730
+ } catch ( error ) {
731
+ return seriesCb ( 'Failed: ' + error ) ;
732
+ }
678
733
ledgerSignTransaction ( seriesCb , transaction , account , function ( transaction ) {
679
734
if ( ! transaction ) {
680
735
return seriesCb ( 'Failed to sign vote transaction with ledger' ) ;
@@ -687,7 +742,11 @@ vorpal
687
742
} ) ;
688
743
} ) ;
689
744
} else {
690
- var transaction = arkjs . vote . createVote ( passphrase , [ '+' + newDelegate . publicKey ] ) ;
745
+ try {
746
+ var transaction = arkjs . vote . createVote ( passphrase , [ '+' + newDelegate . publicKey ] ) ;
747
+ } catch ( error ) {
748
+ return seriesCb ( 'Failed: ' + error ) ;
749
+ }
691
750
ledgerSignTransaction ( seriesCb , transaction , account , function ( transaction ) {
692
751
if ( ! transaction ) {
693
752
return seriesCb ( 'Failed to sign transaction with ledger' ) ;
@@ -770,7 +829,11 @@ vorpal
770
829
message : 'Removing last vote for ' + lastDelegate . username ,
771
830
} , function ( result ) {
772
831
if ( result . continue ) {
773
- var transaction = arkjs . vote . createVote ( passphrase , delegates ) ;
832
+ try {
833
+ var transaction = arkjs . vote . createVote ( passphrase , delegates ) ;
834
+ } catch ( error ) {
835
+ return seriesCb ( 'Failed: ' + error ) ;
836
+ }
774
837
ledgerSignTransaction ( seriesCb , transaction , account , function ( transaction ) {
775
838
if ( ! transaction ) {
776
839
return seriesCb ( 'Failed to sign transaction with ledger' ) ;
@@ -880,7 +943,11 @@ vorpal
880
943
message : 'Sending ' + arkAmountString + ' ' + network . config . token + ' ' + ( currency ?'(' + currency + args . amount + ') ' :'' ) + 'to ' + args . address + ' now' ,
881
944
} , function ( result ) {
882
945
if ( result . continue ) {
883
- var transaction = arkjs . transaction . createTransaction ( args . address , arkamount , null , passphrase ) ;
946
+ try {
947
+ var transaction = arkjs . transaction . createTransaction ( args . address , arkamount , null , passphrase ) ;
948
+ } catch ( error ) {
949
+ return seriesCb ( 'Failed: ' + error ) ;
950
+ }
884
951
ledgerSignTransaction ( seriesCb , transaction , account , function ( transaction ) {
885
952
if ( ! transaction ) {
886
953
return seriesCb ( 'Failed to sign transaction with ledger' ) ;
@@ -944,7 +1011,11 @@ vorpal
944
1011
} else {
945
1012
return seriesCb ( 'No public key for account' ) ;
946
1013
}
947
- var transaction = arkjs . delegate . createDelegate ( passphrase , args . username ) ;
1014
+ try {
1015
+ var transaction = arkjs . delegate . createDelegate ( passphrase , args . username ) ;
1016
+ } catch ( error ) {
1017
+ return seriesCb ( 'Failed: ' + error ) ;
1018
+ }
948
1019
ledgerSignTransaction ( seriesCb , transaction , account , function ( transaction ) {
949
1020
if ( ! transaction ) {
950
1021
return seriesCb ( 'Failed to sign transaction with ledger' ) ;
0 commit comments