edge-currency-plugins 3.11.0 → 3.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/android/src/main/assets/edge-currency-plugins/edge-currency-plugins.js +48 -47
  2. package/lib/common/plugin/types.js +6 -0
  3. package/lib/common/utxobased/engine/ServerStates.js +196 -95
  4. package/lib/common/utxobased/engine/UtxoEngine.js +17 -4
  5. package/lib/common/utxobased/engine/UtxoWalletTools.js +15 -2
  6. package/lib/common/utxobased/engine/types.js +7 -1
  7. package/lib/common/utxobased/info/bitcoin.js +3 -3
  8. package/lib/common/utxobased/info/bitcoincash.js +1 -1
  9. package/lib/common/utxobased/info/bitcoingold.js +1 -1
  10. package/lib/common/utxobased/info/bitcoingoldtestnet.js +1 -1
  11. package/lib/common/utxobased/info/dash.js +3 -2
  12. package/lib/common/utxobased/info/digibyte.js +2 -2
  13. package/lib/common/utxobased/info/dogecoin.js +2 -2
  14. package/lib/common/utxobased/info/ecash.js +1 -1
  15. package/lib/common/utxobased/info/feathercoin.js +1 -1
  16. package/lib/common/utxobased/info/litecoin.js +4 -4
  17. package/lib/common/utxobased/info/pivx.js +3 -2
  18. package/lib/common/utxobased/info/qtum.js +2 -2
  19. package/lib/common/utxobased/info/ravencoin.js +1 -1
  20. package/lib/common/utxobased/info/smartcash.js +1 -1
  21. package/lib/common/utxobased/info/ufo.js +1 -1
  22. package/lib/common/utxobased/info/vertcoin.js +2 -1
  23. package/lib/common/utxobased/info/zcoin.js +2 -2
  24. package/lib/common/utxobased/keymanager/keymanager.js +56 -2
  25. package/lib/common/utxobased/keymanager/types.js +28 -1
  26. package/lib/common/utxobased/network/Blockbook.js +10 -2
  27. package/lib/src/common/plugin/types.d.ts +7 -1
  28. package/lib/src/common/utxobased/engine/ServerStates.d.ts +21 -0
  29. package/lib/src/common/utxobased/engine/UtxoWalletTools.d.ts +2 -0
  30. package/lib/src/common/utxobased/engine/types.d.ts +1 -0
  31. package/lib/src/common/utxobased/keymanager/keymanager.d.ts +3 -2
  32. package/lib/src/common/utxobased/keymanager/types.d.ts +19 -0
  33. package/lib/test/common/utxobased/engine/ServerStates.spec.d.ts +1 -0
  34. package/lib/test/common/utxobased/keymanager/coins/altcointestfixtures.d.ts +5 -0
  35. package/lib/test/common/utxobased/keymanager/messagePrefix.spec.d.ts +1 -0
  36. package/package.json +1 -1
@@ -313,6 +313,12 @@ var _types3 = require('../utxobased/db/types');
313
313
 
314
314
 
315
315
 
316
+
317
+
318
+
319
+
320
+
321
+
316
322
 
317
323
 
318
324
 
@@ -91,6 +91,47 @@ var _constants = require('./constants');
91
91
 
92
92
 
93
93
 
94
+
95
+
96
+
97
+
98
+
99
+
100
+ /**
101
+ * How long broadcastTx gives the first wave (our sockets and Edge's own HTTP
102
+ * servers) before it also sends the transaction to the NOWNodes HTTP servers.
103
+ * NOWNodes is a third party, so it should only see a transaction when our own
104
+ * infrastructure has not already carried it. A first wave that fails outright
105
+ * does not wait this long; the second wave fires as soon as it has all failed.
106
+ */
107
+ const NOWNODES_BROADCAST_DELAY_MS = 2000; exports.NOWNODES_BROADCAST_DELAY_MS = NOWNODES_BROADCAST_DELAY_MS
108
+
109
+ /**
110
+ * Every broadcast attempt is counted toward "all attempts failed", so every
111
+ * attempt must settle. Sockets already expire a request after 30 seconds
112
+ * (Socket.ts); HTTP has no such bound of its own, and a server that accepts
113
+ * the connection and never answers would otherwise hold the whole broadcast
114
+ * open. This mirrors the socket figure.
115
+ */
116
+ const BROADCAST_ATTEMPT_TIMEOUT_MS = 30000; exports.BROADCAST_ATTEMPT_TIMEOUT_MS = BROADCAST_ATTEMPT_TIMEOUT_MS
117
+
118
+ const withTimeout = async (
119
+ promise,
120
+ ms,
121
+ message
122
+ ) => {
123
+ let timer
124
+ const timeout = new Promise((resolve, reject) => {
125
+ timer = setTimeout(() => {
126
+ reject(new Error(message))
127
+ }, ms)
128
+ })
129
+ try {
130
+ return await Promise.race([promise, timeout])
131
+ } finally {
132
+ if (timer != null) clearTimeout(timer)
133
+ }
134
+ }
94
135
 
95
136
  function makeServerStates(config) {
96
137
  const {
@@ -103,6 +144,7 @@ var _constants = require('./constants');
103
144
  walletInfo
104
145
  } = config
105
146
  const { serverConfigs = [] } = pluginInfo.engineInfo
147
+ const { broadcastTimeoutMs = exports.BROADCAST_ATTEMPT_TIMEOUT_MS } = config
106
148
  log('Making server states')
107
149
 
108
150
  const serverStatesCache = {}
@@ -366,112 +408,171 @@ var _constants = require('./constants');
366
408
  }
367
409
 
368
410
  const instance = {
411
+ /**
412
+ * Broadcast in two waves:
413
+ *
414
+ * 1. Immediately: every blockbook in the connection cache (whether or not
415
+ * its socket has finished connecting; a queued request transmits as
416
+ * soon as the socket opens, and times out otherwise) and every
417
+ * `blockbook` HTTP server, which are Edge's own.
418
+ * 2. After NOWNODES_BROADCAST_DELAY_MS, or as soon as every first-wave
419
+ * attempt has failed, whichever comes first: the `blockbook-nownode`
420
+ * HTTP servers. These are a third party and only see the transaction
421
+ * when our own infrastructure has not already carried it.
422
+ *
423
+ * The first success wins. The promise rejects only after every attempt
424
+ * has failed. Earlier versions only used HTTP when no socket was
425
+ * connected, so a single socket that looked connected but never answered
426
+ * could fail the whole broadcast without any HTTP attempt.
427
+ */
369
428
  async broadcastTx(transaction) {
370
429
  return await new Promise((resolve, reject) => {
371
- let resolved = false
372
- let bad = 0
373
-
374
- const wsUris = Object.keys(serverStatesCache).filter(
375
- uri => serverStatesCache[uri].blockbook != null
376
- )
377
-
378
- // Determine if there are any connected blockbook instances
379
- const isAnyBlockbookConnected = wsUris.some(
380
- uri => serverStatesCache[uri].blockbook.isConnected
381
- )
382
-
383
- if (isAnyBlockbookConnected) {
384
- for (const uri of wsUris) {
385
- const { blockbook } = serverStatesCache[uri]
386
- if (blockbook == null) continue
387
- blockbook
388
- .broadcastTx(transaction)
389
- .then(response => {
390
- if (!resolved) {
391
- resolved = true
392
- resolve(response.result)
393
- }
394
- })
395
- .catch((e) => {
396
- if (++bad === wsUris.length) {
397
- const msg = e != null ? `With error ${e.message}` : ''
398
- log.error(
399
- `broadcastTx fail: ${JSON.stringify(transaction)}\n${msg}`
400
- )
401
- reject(e)
402
- }
403
- })
430
+
431
+
432
+
433
+
434
+
435
+ const httpAttempt = (
436
+ uri,
437
+ headers
438
+ ) => ({
439
+ uri,
440
+ run: async () => {
441
+ const response = await io.fetchCors(`${uri}/api/v2/sendtx/`, {
442
+ method: 'POST',
443
+ headers,
444
+ body: transaction.signedTx
445
+ })
446
+ if (!response.ok) {
447
+ throw new Error(
448
+ `Failed to broadcast transaction via Blockbook: HTTP ${response.status}`
449
+ )
450
+ }
451
+ const json = await response.json()
452
+ return _blockbookApi.asBlockbookResponse.call(void 0, (0, _blockbookApi.asBroadcastTxResponse))(json).result
404
453
  }
454
+ })
455
+
456
+ //
457
+ // Build both waves up front, so `attempts` is the full count and an
458
+ // all-fail first wave cannot reject before the second has run.
459
+ //
460
+ const firstWave = []
461
+ const secondWave = []
462
+
463
+ for (const uri of Object.keys(serverStatesCache)) {
464
+ const { blockbook } = serverStatesCache[uri]
465
+ if (blockbook == null) continue
466
+ firstWave.push({
467
+ uri,
468
+ run: async () => (await blockbook.broadcastTx(transaction)).result
469
+ })
405
470
  }
406
471
 
407
- // Broadcast through any HTTP URI that may be configured, only if no
408
- // blockbook instances are connected.
409
- if (!isAnyBlockbookConnected) {
410
- // This is for the future when we want to get HTTP servers from the user
411
- // settings:
412
- // const httpUris = pluginState.getLocalServers(Infinity, [
413
- // /^http(?:s)?:/i
414
- // ])
415
-
416
- const { nowNodesApiKey } = initOptions
417
- const nowNodeUris = serverConfigs
418
- .filter(config => config.type === 'blockbook-nownode')
419
- .map(config => config.uris)
420
- .flat(1)
421
-
422
- // If there are no HTTP servers, reject the promise
423
- if (nowNodeUris.length < 1) {
424
- // If no HTTP servers are available, and we had no connected blockbook
425
- // instances, reject the promise with a message indicating no
426
- // available connections.
472
+ // This is for the future when we want to get HTTP servers from the user
473
+ // settings:
474
+ // const httpUris = pluginState.getLocalServers(Infinity, [
475
+ // /^http(?:s)?:/i
476
+ // ])
477
+ const { nowNodesApiKey } = initOptions
478
+ for (const config of serverConfigs) {
479
+ if (config.type === 'blockbook-nownode') {
480
+ // NOWNodes requires the key, and the key must not go anywhere else:
481
+ if (nowNodesApiKey == null) {
482
+ log.warn(
483
+ 'broadcastTx: skipping NOWNodes HTTP servers (no nowNodesApiKey)'
484
+ )
485
+ continue
486
+ }
487
+ for (const uri of config.uris) {
488
+ secondWave.push(httpAttempt(uri, { 'api-key': nowNodesApiKey }))
489
+ }
490
+ } else {
491
+ for (const uri of config.uris) {
492
+ firstWave.push(httpAttempt(uri, {}))
493
+ }
494
+ }
495
+ }
496
+
497
+ const attempts = firstWave.length + secondWave.length
498
+ if (attempts === 0) {
499
+ reject(
500
+ new Error('No available connections. Check your internet signal.')
501
+ )
502
+ return
503
+ }
504
+
505
+ let resolved = false
506
+ let failures = 0
507
+ const failureMessages = []
508
+ let secondWaveFired = false
509
+ let secondWaveTimer
510
+
511
+ const onSuccess = (uri, txid) => {
512
+ if (resolved) return
513
+ resolved = true
514
+ if (secondWaveTimer != null) clearTimeout(secondWaveTimer)
515
+ log(`broadcastTx succeeded via ${uri}: ${txid}`)
516
+ resolve(txid)
517
+ }
518
+ const onFailure = (uri, error) => {
519
+ const message = error instanceof Error ? error.message : String(error)
520
+ failureMessages.push(`${uri}: ${message}`)
521
+ log.warn(`broadcastTx attempt failed for ${uri}: ${message}`)
522
+ failures++
523
+ if (resolved) return
524
+ if (failures === attempts) {
525
+ log.error(
526
+ `broadcastTx fail: ${JSON.stringify(
527
+ transaction
528
+ )}\n${failureMessages.join('\n')}`
529
+ )
427
530
  reject(
428
- new Error('No available connections. Check your internet signal.')
531
+ error instanceof Error
532
+ ? error
533
+ : new Error(`Broadcast failed: ${failureMessages.join('; ')}`)
429
534
  )
430
535
  return
431
536
  }
432
-
433
- // If there is no key for the NowNode servers:
434
- if (nowNodesApiKey == null) {
435
- reject(new Error('Missing connection key for fallback servers.'))
436
- return
537
+ // Every first-wave attempt has failed, so there is nothing left to
538
+ // wait for. Fire the second wave now rather than sit out the delay.
539
+ if (!secondWaveFired && failures >= firstWave.length) {
540
+ fireSecondWave()
437
541
  }
438
-
439
- for (const uri of nowNodeUris) {
440
- log.warn('Falling back to NOWNode server broadcast over HTTP:', uri)
441
-
442
- // HTTP Fallback
443
- io.fetchCors(`${uri}/api/v2/sendtx/`, {
444
- method: 'POST',
445
- headers: {
446
- 'api-key': nowNodesApiKey
447
- },
448
- body: transaction.signedTx
542
+ }
543
+ const fire = (attempt) => {
544
+ withTimeout(
545
+ attempt.run(),
546
+ broadcastTimeoutMs,
547
+ `Timeout for broadcast to ${attempt.uri}`
548
+ )
549
+ .then(txid => {
550
+ onSuccess(attempt.uri, txid)
449
551
  })
450
- .then(async response => {
451
- if (!response.ok) {
452
- throw new Error(
453
- `Failed to broadcast transaction via Blockbook: HTTP ${response.status}`
454
- )
455
- }
456
- const json = await response.json()
457
- return _blockbookApi.asBlockbookResponse.call(void 0, (0, _blockbookApi.asBroadcastTxResponse))(json)
458
- })
459
- .then(response => {
460
- if (!resolved) {
461
- resolved = true
462
- resolve(response.result)
463
- }
464
- })
465
- .catch((e) => {
466
- if (++bad === nowNodeUris.length) {
467
- const msg = e != null ? `With error ${e.message}` : ''
468
- log.error(
469
- `broadcastTx fail: ${JSON.stringify(transaction)}\n${msg}`
470
- )
471
- reject(e)
472
- }
473
- })
474
- }
552
+ .catch((error) => {
553
+ onFailure(attempt.uri, error)
554
+ })
555
+ }
556
+ const fireSecondWave = () => {
557
+ if (secondWaveFired) return
558
+ secondWaveFired = true
559
+ if (secondWaveTimer != null) clearTimeout(secondWaveTimer)
560
+ if (secondWave.length === 0) return
561
+ log.warn(
562
+ 'broadcastTx: first wave has not resolved, trying NOWNodes servers'
563
+ )
564
+ for (const attempt of secondWave) fire(attempt)
565
+ }
566
+
567
+ for (const attempt of firstWave) fire(attempt)
568
+ if (firstWave.length === 0) {
569
+ // Nothing of our own to try first:
570
+ fireSecondWave()
571
+ } else if (secondWave.length > 0) {
572
+ secondWaveTimer = setTimeout(
573
+ fireSecondWave,
574
+ exports.NOWNODES_BROADCAST_DELAY_MS
575
+ )
475
576
  }
476
577
  })
477
578
  },
@@ -45,6 +45,9 @@ var _cleaners3 = require('../keymanager/cleaners');
45
45
 
46
46
 
47
47
  var _keymanager = require('../keymanager/keymanager');
48
+
49
+
50
+
48
51
  var _types5 = require('../keymanager/types');
49
52
  var _utils = require('../keymanager/utxopicker/utils');
50
53
  var _paymentRequest = require('./paymentRequest');
@@ -797,11 +800,20 @@ var _UtxoWalletTools = require('./UtxoWalletTools');
797
800
  opts
798
801
  ) {
799
802
  const otherParams = _types7.asUtxoSignMessageOtherParams.call(void 0, opts.otherParams)
800
- const { publicAddress } = otherParams
801
- const scriptPubkey = walletTools.addressToScriptPubkey(publicAddress)
803
+ const { publicAddress, signatureFormat } = otherParams
804
+ // An address the wallet cannot sign for reaches us two ways: it parses
805
+ // but is not ours, or it is not an address of this chain at all and
806
+ // `addressToScriptPubkey` throws. Both are the same thing to a caller,
807
+ // so give them one named error rather than assorted parser prose.
808
+ let scriptPubkey
809
+ try {
810
+ scriptPubkey = walletTools.addressToScriptPubkey(publicAddress)
811
+ } catch (e2) {
812
+ throw new (0, _types5.AddressNotOwnedError)()
813
+ }
802
814
  const addressData = await dataLayer.fetchAddress(scriptPubkey)
803
815
  if (_optionalChain([addressData, 'optionalAccess', _13 => _13.path]) == null) {
804
- throw new Error('Missing data-layer address to sign with')
816
+ throw new (0, _types5.AddressNotOwnedError)()
805
817
  }
806
818
  const privateKey = asMaybeCurrencyPrivateKey(privateKeys)
807
819
 
@@ -818,7 +830,8 @@ var _UtxoWalletTools = require('./UtxoWalletTools');
818
830
  const signature = await walletTools.signMessageBase64({
819
831
  path: _optionalChain([addressData, 'optionalAccess', _14 => _14.path]),
820
832
  message,
821
- xprivKeys
833
+ xprivKeys,
834
+ signatureFormat
822
835
  })
823
836
  return signature
824
837
  },
@@ -25,6 +25,7 @@ var _keymanager = require('../keymanager/keymanager');
25
25
 
26
26
 
27
27
 
28
+
28
29
  var _utils = require('./utils');
29
30
 
30
31
 
@@ -92,6 +93,7 @@ var _utils = require('./utils');
92
93
 
93
94
 
94
95
 
96
+
95
97
 
96
98
 
97
99
  function makeUtxoWalletTools(
@@ -236,12 +238,23 @@ var _utils = require('./utils');
236
238
  return { address, scriptPubkey, redeemScript }
237
239
  },
238
240
 
239
- signMessageBase64({ path, message, xprivKeys }) {
241
+ signMessageBase64({
242
+ path,
243
+ message,
244
+ xprivKeys,
245
+ signatureFormat
246
+ }) {
240
247
  const privKey = fns.getPrivateKey({
241
248
  path,
242
249
  xprivKeys
243
250
  })
244
- return _keymanager.signMessageBase64.call(void 0, message, privKey)
251
+ return _keymanager.signMessageBase64.call(void 0,
252
+ message,
253
+ privKey,
254
+ path.format,
255
+ coin,
256
+ signatureFormat
257
+ )
245
258
  }
246
259
  }
247
260
 
@@ -11,6 +11,7 @@ var _cleaners = require('cleaners');
11
11
 
12
12
 
13
13
  var _types3 = require('../../plugin/types');
14
+ var _types5 = require('../keymanager/types');
14
15
 
15
16
 
16
17
 
@@ -42,7 +43,12 @@ var _types3 = require('../../plugin/types');
42
43
 
43
44
 
44
45
  const asUtxoSignMessageOtherParams = _cleaners.asObject.call(void 0, {
45
- publicAddress: _cleaners.asString
46
+ publicAddress: _cleaners.asString,
47
+ // Defaults to the legacy Electrum encoding so existing callers keep the
48
+ // format they already produce. BIP-137 is opt-in, since emitting a BIP-137
49
+ // header to a verifier expecting the legacy one is just as broken as the
50
+ // reverse.
51
+ signatureFormat: _cleaners.asMaybe.call(void 0, _types5.asUtxoSignatureFormat, 'electrum')
46
52
  }); exports.asUtxoSignMessageOtherParams = asUtxoSignMessageOtherParams
47
53
 
48
54
  const asOutputSort = _cleaners.asValue.call(void 0, 'bip69', 'targets')
@@ -20,8 +20,8 @@ const currencyInfo = {
20
20
 
21
21
  // Explorers:
22
22
  blockExplorer: 'https://blockchair.com/bitcoin/block/%s',
23
- addressExplorer: 'https://blockchair.com/bitcoin/address/%s',
24
- transactionExplorer: 'https://blockchair.com/bitcoin/transaction/%s',
23
+ addressExplorer: 'https://mempool.space/address/%s',
24
+ transactionExplorer: 'https://mempool.space/tx/%s',
25
25
 
26
26
  denominations: [
27
27
  { name: 'BTC', multiplier: '100000000', symbol: '₿' },
@@ -53,7 +53,7 @@ const currencyInfo = {
53
53
  const engineInfo = {
54
54
  serverConfigs: [
55
55
  {
56
- type: 'blockbook-nownode',
56
+ type: 'blockbook',
57
57
  uris: ['https://btc-wusa1.edge.app', 'https://btc-eu1.edge.app']
58
58
  },
59
59
  {
@@ -53,7 +53,7 @@ const currencyInfo = {
53
53
  const engineInfo = {
54
54
  serverConfigs: [
55
55
  {
56
- type: 'blockbook-nownode',
56
+ type: 'blockbook',
57
57
  uris: ['https://bch-eusa1.edge.app']
58
58
  },
59
59
  {
@@ -73,7 +73,7 @@ const engineInfo = {
73
73
  coinType: 156,
74
74
 
75
75
  prefixes: {
76
- messagePrefix: ['\x18Bitcoin Gold Signed Message:\n'],
76
+ messagePrefix: ['\x1dBitcoin Gold Signed Message:\n'],
77
77
  wif: [0x80],
78
78
  legacyXPriv: [0x0488ade4],
79
79
  legacyXPub: [0x0488b21e],
@@ -65,7 +65,7 @@ const engineInfo = {
65
65
  coinType: 1,
66
66
 
67
67
  prefixes: {
68
- messagePrefix: ['\x18Bitcoin Gold Signed Message:\n'],
68
+ messagePrefix: ['\x1dBitcoin Gold Signed Message:\n'],
69
69
  wif: [0xef],
70
70
  legacyXPriv: [0x04358394],
71
71
  legacyXPub: [0x043587cf],
@@ -52,7 +52,7 @@ const currencyInfo = {
52
52
  const engineInfo = {
53
53
  serverConfigs: [
54
54
  {
55
- type: 'blockbook-nownode',
55
+ type: 'blockbook',
56
56
  uris: ['https://dash-wusa1.edge.app']
57
57
  },
58
58
  {
@@ -99,7 +99,8 @@ const engineInfo = {
99
99
  segwit: false,
100
100
  coinType: 5,
101
101
  prefixes: {
102
- messagePrefix: ['unused'],
102
+ // Dash kept its pre-rebrand DarkCoin magic; not a typo.
103
+ messagePrefix: ['\x19DarkCoin Signed Message:\n'],
103
104
  wif: [0xcc],
104
105
  legacyXPriv: [0x02fe52f8],
105
106
  legacyXPub: [0x02fe52cc],
@@ -46,7 +46,7 @@ const currencyInfo = {
46
46
  const engineInfo = {
47
47
  serverConfigs: [
48
48
  {
49
- type: 'blockbook-nownode',
49
+ type: 'blockbook',
50
50
  uris: ['https://dgb-eu1.edge.app']
51
51
  },
52
52
  {
@@ -79,7 +79,7 @@ const engineInfo = {
79
79
  segwit: true,
80
80
  coinType: 20,
81
81
  prefixes: {
82
- messagePrefix: ['\x18Digibyte Signed Message:\n'],
82
+ messagePrefix: ['\x19DigiByte Signed Message:\n'],
83
83
  wif: [0x80, 0x9e],
84
84
  legacyXPriv: [0x0488ade4],
85
85
  legacyXPub: [0x0488b21e],
@@ -48,7 +48,7 @@ const currencyInfo = {
48
48
  const engineInfo = {
49
49
  serverConfigs: [
50
50
  {
51
- type: 'blockbook-nownode',
51
+ type: 'blockbook',
52
52
  uris: ['https://doge-eusa1.edge.app']
53
53
  },
54
54
  {
@@ -81,7 +81,7 @@ const engineInfo = {
81
81
  coinType: 3,
82
82
  utxoPicker: _dogeUtxoPicker.makeDogeUtxoPicker.call(void 0, ),
83
83
  prefixes: {
84
- messagePrefix: ['\x18Dogecoin Signed Message:\n'],
84
+ messagePrefix: ['\x19Dogecoin Signed Message:\n'],
85
85
  wif: [0x9e],
86
86
  legacyXPriv: [0x02fac398],
87
87
  legacyXPub: [0x02facafd],
@@ -80,7 +80,7 @@ const engineInfo = {
80
80
  includeCashaddrPrefix: true,
81
81
 
82
82
  prefixes: {
83
- messagePrefix: ['\x18Bitcoin Signed Message::\n'],
83
+ messagePrefix: ['\x16eCash Signed Message:\n'],
84
84
  wif: [0x80],
85
85
  legacyXPriv: [0x0488ade4],
86
86
  legacyXPub: [0x0488b21e],
@@ -63,7 +63,7 @@ var _commonInfo = require('./commonInfo');
63
63
  segwit: true,
64
64
  coinType: 8,
65
65
  prefixes: {
66
- messagePrefix: ['\x18Feathercoin Signed Message:\n'],
66
+ messagePrefix: ['\x1cFeathercoin Signed Message:\n'],
67
67
  wif: [0x8e],
68
68
  legacyXPriv: [0x0488daee],
69
69
  legacyXPub: [0x0488bc26],
@@ -20,8 +20,8 @@ var _commonInfo = require('./commonInfo');
20
20
 
21
21
  // Explorers:
22
22
  blockExplorer: 'https://blockchair.com/litecoin/block/%s',
23
- addressExplorer: 'https://blockchair.com/litecoin/address/%s',
24
- transactionExplorer: 'https://blockchair.com/litecoin/transaction/%s',
23
+ addressExplorer: 'https://litecoinspace.org/address/%s',
24
+ transactionExplorer: 'https://litecoinspace.org/tx/%s',
25
25
 
26
26
  denominations: [
27
27
  { name: 'LTC', multiplier: '100000000', symbol: 'Ł' },
@@ -50,7 +50,7 @@ var _commonInfo = require('./commonInfo');
50
50
  const engineInfo = {
51
51
  serverConfigs: [
52
52
  {
53
- type: 'blockbook-nownode',
53
+ type: 'blockbook',
54
54
  uris: ['https://ltc-wusa1.edge.app']
55
55
  },
56
56
  {
@@ -83,7 +83,7 @@ var _commonInfo = require('./commonInfo');
83
83
  segwit: true,
84
84
  coinType: 2,
85
85
  prefixes: {
86
- messagePrefix: ['\x18Litecoin Signed Message:\n'],
86
+ messagePrefix: ['\x19Litecoin Signed Message:\n'],
87
87
  wif: [0xb0],
88
88
  legacyXPriv: [0x0488ade4],
89
89
  legacyXPub: [0x0488b21e],
@@ -44,7 +44,7 @@ const currencyInfo = {
44
44
  const engineInfo = {
45
45
  serverConfigs: [
46
46
  {
47
- type: 'blockbook-nownode',
47
+ type: 'blockbook',
48
48
  uris: ['https://pivx-wusa1.edge.app']
49
49
  },
50
50
  {
@@ -79,7 +79,8 @@ const engineInfo = {
79
79
  /*
80
80
  [Prefix reference](https://github.com/PIVX-Project/PIVX/blob/b89a9fc04e9e31bb3fd009df0506c957a00ad536/src/chainparams.cpp#L329)
81
81
  */
82
- messagePrefix: ['PIVX Signed Message:\n'],
82
+ // PIVX inherited DarkNet from its Dash fork ancestry; not a typo.
83
+ messagePrefix: ['\x18DarkNet Signed Message:\n'],
83
84
  wif: [0xd4],
84
85
  legacyXPriv: [0x0221312b],
85
86
  legacyXPub: [0x022d2533],
@@ -42,7 +42,7 @@ const currencyInfo = {
42
42
  const engineInfo = {
43
43
  serverConfigs: [
44
44
  {
45
- type: 'blockbook-nownode',
45
+ type: 'blockbook',
46
46
  uris: ['https://qtum-wusa1.edge.app']
47
47
  }
48
48
  ],
@@ -70,7 +70,7 @@ const engineInfo = {
70
70
  segwit: false,
71
71
  coinType: 2301,
72
72
  prefixes: {
73
- messagePrefix: ['\x18Bitcoin Signed Message:\n'],
73
+ messagePrefix: ['\x15Qtum Signed Message:\n'],
74
74
  wif: [0x80],
75
75
  legacyXPriv: [0x0488ade4],
76
76
  legacyXPub: [0x0488b21e],
@@ -60,7 +60,7 @@ const engineInfo = {
60
60
  segwit: false,
61
61
  coinType: 175,
62
62
  prefixes: {
63
- messagePrefix: ['\x18Bitcoin Signed Message:\n'],
63
+ messagePrefix: ['\x16Raven Signed Message:\n'],
64
64
  wif: [0x80],
65
65
  legacyXPriv: [0x0488ade4],
66
66
  legacyXPub: [0x0488b21e],
@@ -71,7 +71,7 @@ const engineInfo = {
71
71
  bs58EncodeFunc: base58smart.encode,
72
72
  wifEncodeFunc: wifsmart.encode,
73
73
  prefixes: {
74
- messagePrefix: ['\x18Bitcoin Signed Message:\n'],
74
+ messagePrefix: ['\x1aSmartCash Signed Message:\n'],
75
75
  wif: [0xbf],
76
76
  legacyXPriv: [0x0488ade4],
77
77
  legacyXPub: [0x0488b21e],