edge-currency-plugins 3.2.0 → 3.3.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 (47) hide show
  1. package/android/src/main/assets/edge-currency-plugins/edge-currency-plugins.js +41 -41
  2. package/lib/common/plugin/PluginState.js +73 -43
  3. package/lib/common/plugin/ServerScores.js +11 -0
  4. package/lib/common/plugin/types.js +1 -1
  5. package/lib/common/utxobased/db/{Processor.js → DataLayer.js} +15 -11
  6. package/lib/common/utxobased/db/Models/{ProcessorTransaction.js → TransactionData.js} +4 -6
  7. package/lib/common/utxobased/db/types.js +4 -4
  8. package/lib/common/utxobased/db/util/utxo.js +8 -8
  9. package/lib/common/utxobased/engine/ServerStates.js +324 -298
  10. package/lib/common/utxobased/engine/UtxoEngine.js +58 -55
  11. package/lib/common/utxobased/engine/{UtxoEngineState.js → UtxoEngineProcessor.js} +650 -714
  12. package/lib/common/utxobased/engine/types.js +4 -2
  13. package/lib/common/utxobased/engine/util/getOwnUtxosFromTx.js +4 -4
  14. package/lib/common/utxobased/info/bitcoin.js +2 -1
  15. package/lib/common/utxobased/info/bitcoincash.js +2 -1
  16. package/lib/common/utxobased/info/dash.js +2 -1
  17. package/lib/common/utxobased/info/digibyte.js +5 -1
  18. package/lib/common/utxobased/info/dogecoin.js +2 -1
  19. package/lib/common/utxobased/info/groestlcoin.js +4 -1
  20. package/lib/common/utxobased/info/litecoin.js +2 -1
  21. package/lib/common/utxobased/info/zcoin.js +4 -1
  22. package/lib/common/utxobased/network/Blockbook.js +33 -30
  23. package/lib/common/utxobased/network/BlockbookElectrum.js +79 -77
  24. package/lib/common/utxobased/network/Socket.js +84 -48
  25. package/lib/common/utxobased/network/windowWS.js +2 -2
  26. package/lib/src/common/plugin/PluginState.d.ts +4 -4
  27. package/lib/src/common/plugin/ServerScores.d.ts +1 -0
  28. package/lib/src/common/plugin/types.d.ts +4 -4
  29. package/lib/src/common/utxobased/db/{Processor.d.ts → DataLayer.d.ts} +17 -11
  30. package/lib/src/common/utxobased/db/Models/{ProcessorTransaction.d.ts → TransactionData.d.ts} +5 -5
  31. package/lib/src/common/utxobased/db/Models/baselet.d.ts +4 -4
  32. package/lib/src/common/utxobased/db/types.d.ts +9 -9
  33. package/lib/src/common/utxobased/db/util/utxo.d.ts +3 -3
  34. package/lib/src/common/utxobased/engine/ServerStates.d.ts +7 -7
  35. package/lib/src/common/utxobased/engine/{UtxoEngineState.d.ts → UtxoEngineProcessor.d.ts} +44 -42
  36. package/lib/src/common/utxobased/engine/types.d.ts +4 -4
  37. package/lib/src/common/utxobased/engine/util/getOwnUtxosFromTx.d.ts +3 -3
  38. package/lib/src/common/utxobased/engine/utils.d.ts +2 -2
  39. package/lib/src/common/utxobased/keymanager/keymanager.d.ts +3 -3
  40. package/lib/src/common/utxobased/network/Blockbook.d.ts +8 -7
  41. package/lib/src/common/utxobased/network/BlockbookElectrum.d.ts +4 -2
  42. package/lib/src/common/utxobased/network/Socket.d.ts +10 -8
  43. package/lib/src/common/utxobased/network/types.d.ts +1 -1
  44. package/lib/src/util/uriKeyParams.d.ts +4 -0
  45. package/lib/util/uriKeyParams.js +20 -0
  46. package/package.json +1 -1
  47. /package/lib/test/common/utxobased/db/{Processor.spec.d.ts → DataLayer.spec.d.ts} +0 -0
@@ -66,21 +66,26 @@ const asServerListInfo = _cleaners.asObject.call(void 0, _cleaners.asEither.call
66
66
  pluginDisklet,
67
67
  log
68
68
  } = settings
69
- const builtInServers = defaultSettings.blockbookServers
70
- let customServers = []
71
- let enableCustomServers = defaultSettings.enableCustomServers
69
+
72
70
  let engines = []
73
71
  const memlet = _memlet.makeMemlet.call(void 0, pluginDisklet)
74
72
 
75
73
  let serverCache = {
76
74
  customServers: {},
75
+ enableCustomServers: defaultSettings.enableCustomServers,
77
76
  internalServers: {}
78
77
  }
79
78
  let serverCacheDirty = false
80
- let knownServers = {}
79
+
80
+ const getSelectedServerList = () => {
81
+ const serverCacheIndex = serverCache.enableCustomServers
82
+ ? 'customServers'
83
+ : 'internalServers'
84
+ return serverCache[serverCacheIndex]
85
+ }
81
86
 
82
87
  const saveServerCache = async () => {
83
- serverScores.printServers(knownServers)
88
+ serverScores.printServers(getSelectedServerList())
84
89
  if (serverCacheDirty) {
85
90
  await memlet.setJson(SERVER_CACHE_FILE, serverCache).catch(e => {
86
91
  log(`${pluginId} - ${JSON.stringify(e.toString())}`)
@@ -133,47 +138,24 @@ const asServerListInfo = _cleaners.asObject.call(void 0, _cleaners.asEither.call
133
138
  }
134
139
  }
135
140
 
136
- const refreshServers = async () => {
137
- let newServers
138
- if (enableCustomServers) {
139
- newServers = customServers
140
- } else {
141
- const fetchedServers = await fetchServers()
142
- newServers = fetchedServers.length > 0 ? fetchedServers : builtInServers
143
- }
144
-
145
- const serverCacheIndex = enableCustomServers
146
- ? 'customServers'
147
- : 'internalServers'
148
-
149
- knownServers = serverCache[serverCacheIndex]
150
- serverScores.serverScoresLoad(knownServers, newServers)
151
- await saveServerCache()
152
-
153
- // Tell the engines about the new servers:
154
- for (const engine of engines) {
155
- engine.refillServers()
156
- }
157
- }
158
-
159
- return {
141
+ const instance = {
160
142
  /**
161
143
  * Begins notifying the engine of state changes. Used at connection time.
162
144
  */
163
- addEngine(engineState) {
164
- engines.push(engineState)
145
+ addEngine(engineProcessor) {
146
+ engines.push(engineProcessor)
165
147
  },
166
148
 
167
149
  /**
168
150
  * Stops notifying the engine of state changes. Used at disconnection time.
169
151
  */
170
- removeEngine(engineState) {
171
- engines = engines.filter(engine => engine !== engineState)
152
+ removeEngine(engineProcessor) {
153
+ engines = engines.filter(engine => engine !== engineProcessor)
172
154
  },
173
155
 
174
156
  dumpData() {
175
157
  return {
176
- 'pluginState.servers_': knownServers
158
+ 'pluginState.servers_': getSelectedServerList()
177
159
  }
178
160
  },
179
161
 
@@ -185,7 +167,7 @@ const asServerListInfo = _cleaners.asObject.call(void 0, _cleaners.asEither.call
185
167
  }
186
168
 
187
169
  // Fetch servers in the background:
188
- refreshServers().catch(e => {
170
+ instance.refreshServers().catch(e => {
189
171
  log(`${pluginId} - ${JSON.stringify(e.toString())}`)
190
172
  })
191
173
 
@@ -193,16 +175,15 @@ const asServerListInfo = _cleaners.asObject.call(void 0, _cleaners.asEither.call
193
175
  },
194
176
 
195
177
  serverScoreDown(uri) {
196
- serverScores.serverScoreDown(knownServers, uri)
178
+ serverScores.serverScoreDown(getSelectedServerList(), uri)
197
179
  },
198
180
 
199
181
  serverScoreUp(uri, score) {
200
- serverScores.serverScoreUp(knownServers, uri, score)
182
+ serverScores.serverScoreUp(getSelectedServerList(), uri, score)
201
183
  },
202
184
 
203
185
  async clearCache() {
204
186
  serverScores.clearServerScoreTimes()
205
- knownServers = {}
206
187
  serverCacheDirty = true
207
188
  await memlet.delete(SERVER_CACHE_FILE)
208
189
  },
@@ -212,18 +193,63 @@ const asServerListInfo = _cleaners.asObject.call(void 0, _cleaners.asEither.call
212
193
  includePatterns = []
213
194
  ) {
214
195
  return serverScores.getServers(
215
- knownServers,
196
+ getSelectedServerList(),
216
197
  numServersWanted,
217
198
  includePatterns
218
199
  )
219
200
  },
220
201
 
221
- refreshServers,
202
+ async refreshServers(updatedCustomServers) {
203
+ let newServers
204
+ if (serverCache.enableCustomServers) {
205
+ newServers =
206
+ // Use the updated custom servers if provided
207
+ _nullishCoalesce(_nullishCoalesce(updatedCustomServers, () => (
208
+ // Use the existing custom servers from cache
209
+ Object.keys(serverCache.customServers))), () => (
210
+ // Use the default servers from info file as final fallback
211
+ defaultSettings.blockbookServers))
212
+ } else {
213
+ const fetchedServers = await fetchServers()
214
+ newServers =
215
+ fetchedServers.length > 0
216
+ ? // Use the servers from the network query
217
+ fetchedServers
218
+ : // Use the default servers from info file as final fallback
219
+ defaultSettings.blockbookServers
220
+ }
221
+
222
+ serverScores.serverScoresLoad(getSelectedServerList(), newServers)
223
+ await saveServerCache()
224
+
225
+ // Tell the engines about the new servers:
226
+ for (const engine of engines) {
227
+ engine.refillServers()
228
+ }
229
+ },
222
230
 
223
231
  async updateServers(settings) {
224
- enableCustomServers = settings.enableCustomServers
225
- customServers = settings.blockbookServers
232
+ const hasServerListChanged = () => {
233
+ const currentCustomServers = Object.keys(serverCache.customServers)
234
+ const newServers = new Set(settings.blockbookServers)
235
+ const existingServers = new Set(currentCustomServers)
236
+ if (newServers.size !== existingServers.size) return true
237
+ for (const server of settings.blockbookServers) {
238
+ if (existingServers.has(server)) continue
239
+ return true
240
+ }
241
+ return false
242
+ }
226
243
 
244
+ // If no changes to the user settings, then exit early
245
+ if (
246
+ settings.enableCustomServers === serverCache.enableCustomServers &&
247
+ !hasServerListChanged()
248
+ ) {
249
+ return
250
+ }
251
+
252
+ // Stop all engines and clear the server list:
227
253
  const enginesToBeStarted = []
228
254
  const disconnects = []
229
255
  for (const engine of engines) {
@@ -233,18 +259,22 @@ const asServerListInfo = _cleaners.asObject.call(void 0, _cleaners.asEither.call
233
259
  }
234
260
  await Promise.all(disconnects)
235
261
  serverScores.clearServerScoreTimes()
262
+
236
263
  // We must always clear custom servers in order to enforce a policy of
237
264
  // only using the exact customServers provided.
238
265
  serverCache = {
239
266
  ...serverCache,
267
+ enableCustomServers: settings.enableCustomServers,
240
268
  customServers: {}
241
269
  }
242
270
  serverCacheDirty = true
243
271
  await saveServerCache()
244
- await refreshServers()
272
+ await instance.refreshServers(settings.blockbookServers)
245
273
  for (const engine of enginesToBeStarted) {
246
274
  await engine.start()
247
275
  }
248
276
  }
249
277
  }
278
+
279
+ return instance
250
280
  } exports.makePluginState = makePluginState;
@@ -3,6 +3,8 @@
3
3
  var _cleaners = require('cleaners');
4
4
 
5
5
 
6
+ var _uriKeyParams = require('../../util/uriKeyParams');
7
+
6
8
 
7
9
  const asServerInfo = _cleaners.asObject.call(void 0, {
8
10
  serverUrl: _cleaners.asString,
@@ -16,6 +18,7 @@ var _cleaners = require('cleaners');
16
18
 
17
19
  const asServerCache = _cleaners.asObject.call(void 0, {
18
20
  customServers: exports.asServerList,
21
+ enableCustomServers: _cleaners.asMaybe.call(void 0, _cleaners.asBoolean, false),
19
22
  internalServers: exports.asServerList
20
23
  }); exports.asServerCache = asServerCache
21
24
 
@@ -100,6 +103,14 @@ const RE_ADDED_SERVER_SCORE = -10
100
103
  knownServer.responseTime = RESPONSE_TIME_UNINITIALIZED
101
104
  }
102
105
 
106
+ const hasKeyParams = _uriKeyParams.getUriKeyParams.call(void 0, knownServerUrl).length > 0
107
+ if (hasKeyParams) {
108
+ // Lower the score on servers which require key params (e.g. NOWNodes).
109
+ // This is because public, non-authenticated nodes are more affordable.
110
+ // Decrease score by half (or decrease by 50%).
111
+ serverScore = serverScore - (MAX_SCORE + MIN_SCORE)
112
+ }
113
+
103
114
  knownServer.serverScore = serverScore
104
115
  this.onDirtyServer(knownServerUrl)
105
116
  }
@@ -50,7 +50,7 @@ var _types3 = require('../utxobased/db/types');
50
50
 
51
51
 
52
52
  const asTxOptions = _cleaners.asObject({
53
- utxos: _cleaners.asOptional.call(void 0, _cleaners.asArray.call(void 0, _types3.asIUTXO)),
53
+ utxos: _cleaners.asOptional.call(void 0, _cleaners.asArray.call(void 0, _types3.asUtxoData)),
54
54
  subtractFee: _cleaners.asOptional.call(void 0, _cleaners.asBoolean),
55
55
  CPFP: _cleaners.asOptional.call(void 0, _cleaners.asString)
56
56
  }); exports.asTxOptions = asTxOptions
@@ -113,7 +113,13 @@ const BASELET_DIR = 'tables'
113
113
 
114
114
 
115
115
 
116
- async function makeProcessor(
116
+
117
+
118
+
119
+
120
+
121
+
122
+ async function makeDataLayer(
117
123
  config
118
124
  ) {
119
125
  const disklet = _disklet.navigateDisklet.call(void 0, config.disklet, BASELET_DIR)
@@ -126,7 +132,7 @@ const BASELET_DIR = 'tables'
126
132
  /**
127
133
  * Calculates the transaction value supplied (negative) or received (positive). In order to calculate
128
134
  * a value, the `ourIns` and `ourOuts` of the object must be populated with indices.
129
- * @param tx {IProcessorTransaction} A transaction object with `ourIns` and `ourOuts` populated
135
+ * @param tx {TransactionData} A transaction object with `ourIns` and `ourOuts` populated
130
136
  */
131
137
  const calculateTxAmount = (tx) => {
132
138
 
@@ -152,7 +158,7 @@ const BASELET_DIR = 'tables'
152
158
  return ourAmount
153
159
  }
154
160
 
155
- const processor = {
161
+ const dataLayer = {
156
162
  async clearAll() {
157
163
  await memlet.onFlush.next().value
158
164
  await _baselet.clearMemletCache.call(void 0, )
@@ -261,19 +267,17 @@ const BASELET_DIR = 'tables'
261
267
  })
262
268
  },
263
269
 
264
- async saveTransaction(
265
- args
266
- ) {
270
+ async saveTransaction(args) {
267
271
  const { scriptPubkeys = [], tx } = args
268
272
  return await baselets.tx(async tables => {
269
273
  // Check if the transaction already exists
270
- const processorTx = await tables.txById
274
+ const transactionData = await tables.txById
271
275
  .query('', [tx.txid])
272
276
  .then(transactions => transactions[0])
273
277
  .catch(_ => undefined)
274
278
 
275
279
  // Use the existing transaction if it does exist.
276
- const transaction = _nullishCoalesce(processorTx, () => ( tx))
280
+ const transaction = _nullishCoalesce(transactionData, () => ( tx))
277
281
 
278
282
  // Mark the used inputs with the provided script pubkey
279
283
  for (const scriptPubkey of scriptPubkeys) {
@@ -325,7 +329,7 @@ const BASELET_DIR = 'tables'
325
329
  await tables.txById.insert('', transaction.txid, transaction)
326
330
 
327
331
  // Save index entry only for first transaction insert
328
- if (processorTx == null) {
332
+ if (transactionData == null) {
329
333
  await tables.txIdsByDate.insert('', {
330
334
  txid: tx.txid,
331
335
  date: tx.date
@@ -594,5 +598,5 @@ const BASELET_DIR = 'tables'
594
598
  })
595
599
  }
596
600
  }
597
- return processor
598
- } exports.makeProcessor = makeProcessor;
601
+ return dataLayer
602
+ } exports.makeDataLayer = makeDataLayer;
@@ -9,9 +9,7 @@ var _bnjs = require('bn.js'); var _bnjs2 = _interopRequireDefault(_bnjs);
9
9
 
10
10
 
11
11
 
12
- const fromEdgeTransaction = (
13
- tx
14
- ) => {
12
+ const fromEdgeTransaction = (tx) => {
15
13
  const otherParams = tx.otherParams
16
14
  if (otherParams == null) throw new Error('Invalid transaction data')
17
15
  if (otherParams.psbt == null)
@@ -44,7 +42,7 @@ var _bnjs = require('bn.js'); var _bnjs2 = _interopRequireDefault(_bnjs);
44
42
  inputs: inputs,
45
43
  outputs: outputs,
46
44
  // We can leave ourIns/ourOuts blank because they'll be updated by the
47
- // processor when receiving the transaction from blockbook.
45
+ // DataLayer when receiving the transaction from blockbook.
48
46
  // We may want to calculate these preemptively, but for now this will work.
49
47
  ourIns: [],
50
48
  ourOuts: [],
@@ -63,12 +61,12 @@ var _bnjs = require('bn.js'); var _bnjs2 = _interopRequireDefault(_bnjs);
63
61
  const toEdgeTransaction = async (
64
62
  args
65
63
  ) => {
66
- const { tx, processor, walletTools, pluginInfo, walletId } = args
64
+ const { tx, dataLayer, walletTools, pluginInfo, walletId } = args
67
65
  const { currencyInfo } = pluginInfo
68
66
  const ourReceiveAddresses = []
69
67
  for (const out of tx.ourOuts) {
70
68
  const { scriptPubkey } = tx.outputs[parseInt(out)]
71
- const address = await processor.fetchAddress(scriptPubkey)
69
+ const address = await dataLayer.fetchAddress(scriptPubkey)
72
70
 
73
71
  if (_optionalChain([address, 'optionalAccess', _ => _.path]) != null) {
74
72
  const { address: addrStr } = walletTools.scriptPubkeyToAddress({
@@ -15,7 +15,7 @@ var _keymanager = require('../keymanager/keymanager');
15
15
 
16
16
 
17
17
 
18
- const makeIAddress = (
18
+ const makeAddressData = (
19
19
  addressFields
20
20
  ) => {
21
21
  const { scriptPubkey, used = false, ...rest } = addressFields
@@ -28,7 +28,7 @@ var _keymanager = require('../keymanager/keymanager');
28
28
  lastTouched: 0,
29
29
  ...rest
30
30
  }
31
- }; exports.makeIAddress = makeIAddress
31
+ }; exports.makeAddressData = makeAddressData
32
32
 
33
33
 
34
34
 
@@ -42,7 +42,7 @@ var _keymanager = require('../keymanager/keymanager');
42
42
 
43
43
 
44
44
 
45
- const asIUTXO = _cleaners.asObject({
45
+ const asUtxoData = _cleaners.asObject({
46
46
  id: _cleaners.asString,
47
47
  txid: _cleaners.asString,
48
48
  vout: _cleaners.asNumber,
@@ -53,7 +53,7 @@ var _keymanager = require('../keymanager/keymanager');
53
53
  scriptType: _keymanager.asScriptTypeEnum,
54
54
  blockHeight: _cleaners.asNumber,
55
55
  spent: _cleaners.asBoolean
56
- }); exports.asIUTXO = asIUTXO
56
+ }); exports.asUtxoData = asUtxoData
57
57
 
58
58
 
59
59
 
@@ -6,14 +6,14 @@ var _keymanager = require('../../keymanager/keymanager');
6
6
 
7
7
 
8
8
 
9
- const utxoFromProcessorTransactionInput = async (
10
- processor,
11
- processorTransaction,
9
+ const utxoFromTransactionDataInput = async (
10
+ dataLayer,
11
+ transactionData,
12
12
  inputIndex
13
13
  ) => {
14
- const input = processorTransaction.inputs[inputIndex]
14
+ const input = transactionData.inputs[inputIndex]
15
15
  const { scriptPubkey } = input
16
- const address = await processor.fetchAddress(scriptPubkey)
16
+ const address = await dataLayer.fetchAddress(scriptPubkey)
17
17
 
18
18
  if (address == null)
19
19
  throw new Error(`Cannot find address for ${scriptPubkey}`)
@@ -34,7 +34,7 @@ var _keymanager = require('../../keymanager/keymanager');
34
34
  case _keymanager.BIP43PurposeTypeEnum.Airbitz:
35
35
  case _keymanager.BIP43PurposeTypeEnum.Legacy: {
36
36
  return {
37
- script: processorTransaction.hex,
37
+ script: transactionData.hex,
38
38
  scriptType:
39
39
  redeemScript != null ? _keymanager.ScriptTypeEnum.p2sh : _keymanager.ScriptTypeEnum.p2pkh
40
40
  }
@@ -64,7 +64,7 @@ var _keymanager = require('../../keymanager/keymanager');
64
64
  script,
65
65
  redeemScript,
66
66
  scriptType,
67
- blockHeight: processorTransaction.blockHeight,
67
+ blockHeight: transactionData.blockHeight,
68
68
  spent: true
69
69
  }
70
- }; exports.utxoFromProcessorTransactionInput = utxoFromProcessorTransactionInput
70
+ }; exports.utxoFromTransactionDataInput = utxoFromTransactionDataInput