edge-currency-plugins 2.4.1 → 2.5.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.
@@ -8,9 +8,10 @@
8
8
 
9
9
 
10
10
 
11
- var _cleaners = require('cleaners');
12
11
 
13
12
 
13
+ var _cleaners = require('cleaners');
14
+
14
15
 
15
16
 
16
17
 
@@ -21,6 +22,7 @@ var _cleaners = require('cleaners');
21
22
 
22
23
 
23
24
 
25
+ var _types3 = require('../utxobased/db/types');
24
26
 
25
27
 
26
28
 
@@ -46,7 +48,11 @@ var _cleaners = require('cleaners');
46
48
 
47
49
 
48
50
 
49
-
51
+ const asTxOptions = _cleaners.asObject({
52
+ utxos: _cleaners.asOptional.call(void 0, _cleaners.asArray.call(void 0, _types3.asIUTXO)),
53
+ subtractFee: _cleaners.asOptional.call(void 0, _cleaners.asBoolean),
54
+ CPFP: _cleaners.asOptional.call(void 0, _cleaners.asString)
55
+ }); exports.asTxOptions = asTxOptions
50
56
 
51
57
 
52
58
 
@@ -78,8 +78,7 @@ var _bnjs = require('bn.js'); var _bnjs2 = _interopRequireDefault(_bnjs);
78
78
  }
79
79
  }
80
80
 
81
- const feeRes = {}
82
-
81
+ let feeRateUsed
83
82
  try {
84
83
  const altcoinTx = _altcoinjs.Transaction.fromHex(tx.hex)
85
84
  const vBytes = altcoinTx.virtualSize()
@@ -87,12 +86,10 @@ var _bnjs = require('bn.js'); var _bnjs2 = _interopRequireDefault(_bnjs);
87
86
  const feeRate = new (0, _bnjs2.default)(tx.fees, 10)
88
87
  .div(new (0, _bnjs2.default)(vBytes, 10))
89
88
  .toNumber()
90
- Object.assign(feeRes, {
91
- feeRateUsed: {
92
- // GUI repo uses satPerVByte rather than satPerByte defined in customFeeTemplate
93
- satPerVByte: feeRate
94
- }
95
- })
89
+ feeRateUsed = {
90
+ // GUI repo uses satPerVByte rather than satPerByte defined in customFeeTemplate
91
+ satPerVByte: feeRate
92
+ }
96
93
  } catch (e) {}
97
94
 
98
95
  return {
@@ -108,6 +105,6 @@ var _bnjs = require('bn.js'); var _bnjs2 = _interopRequireDefault(_bnjs);
108
105
  signedTx: tx.hex,
109
106
  txid: tx.txid,
110
107
  walletId,
111
- ...feeRes
108
+ feeRateUsed
112
109
  }
113
110
  }; exports.toEdgeTransaction = toEdgeTransaction
@@ -1,7 +1,9 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true});
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});var _cleaners = require('cleaners');
2
2
 
3
3
 
4
4
 
5
+ var _keymanager = require('../keymanager/keymanager');
6
+
5
7
 
6
8
 
7
9
 
@@ -40,6 +42,18 @@
40
42
 
41
43
 
42
44
 
45
+ const asIUTXO = _cleaners.asObject({
46
+ id: _cleaners.asString,
47
+ txid: _cleaners.asString,
48
+ vout: _cleaners.asNumber,
49
+ value: _cleaners.asString,
50
+ scriptPubkey: _cleaners.asString,
51
+ script: _cleaners.asString,
52
+ redeemScript: _cleaners.asOptional.call(void 0, _cleaners.asString),
53
+ scriptType: _keymanager.asScriptTypeEnum,
54
+ blockHeight: _cleaners.asNumber,
55
+ spent: _cleaners.asBoolean
56
+ }); exports.asIUTXO = asIUTXO
43
57
 
44
58
 
45
59
 
@@ -0,0 +1,70 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});var _utils = require('../../engine/utils');
2
+
3
+
4
+
5
+ var _keymanager = require('../../keymanager/keymanager');
6
+
7
+
8
+
9
+ const utxoFromProcessorTransactionInput = async (
10
+ processor,
11
+ processorTransaction,
12
+ inputIndex
13
+ ) => {
14
+ const input = processorTransaction.inputs[inputIndex]
15
+ const { scriptPubkey } = input
16
+ const address = await processor.fetchAddress(scriptPubkey)
17
+
18
+ if (address == null)
19
+ throw new Error(`Cannot find address for ${scriptPubkey}`)
20
+ if (address.path == null)
21
+ throw new Error(`Address has no derivation path information`)
22
+
23
+ // Optional redeemScript for "our addresses"
24
+ const redeemScript = address.redeemScript
25
+
26
+ const purposeType = _utils.currencyFormatToPurposeType.call(void 0, address.path.format)
27
+ const getScripts = async (
28
+ scriptPubkey
29
+
30
+
31
+
32
+ ) => {
33
+ switch (purposeType) {
34
+ case _keymanager.BIP43PurposeTypeEnum.Airbitz:
35
+ case _keymanager.BIP43PurposeTypeEnum.Legacy: {
36
+ return {
37
+ script: processorTransaction.hex,
38
+ scriptType:
39
+ redeemScript != null ? _keymanager.ScriptTypeEnum.p2sh : _keymanager.ScriptTypeEnum.p2pkh
40
+ }
41
+ }
42
+ case _keymanager.BIP43PurposeTypeEnum.WrappedSegwit:
43
+ return {
44
+ script: scriptPubkey,
45
+ scriptType: _keymanager.ScriptTypeEnum.p2wpkhp2sh
46
+ }
47
+ case _keymanager.BIP43PurposeTypeEnum.Segwit:
48
+ return {
49
+ script: scriptPubkey,
50
+ scriptType: _keymanager.ScriptTypeEnum.p2wpkh
51
+ }
52
+ default:
53
+ throw new Error(`Unknown purpose type ${purposeType}`)
54
+ }
55
+ }
56
+ const { script, scriptType } = await getScripts(scriptPubkey)
57
+
58
+ return {
59
+ id: `${input.txId}_${input.outputIndex}`,
60
+ txid: input.txId,
61
+ vout: input.outputIndex,
62
+ value: input.amount,
63
+ scriptPubkey,
64
+ script,
65
+ redeemScript,
66
+ scriptType,
67
+ blockHeight: processorTransaction.blockHeight,
68
+ spent: true
69
+ }
70
+ }; exports.utxoFromProcessorTransactionInput = utxoFromProcessorTransactionInput
@@ -1,4 +1,4 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } async function _asyncNullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return await rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } async function _asyncOptionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = await fn(value); } else if (op === 'call' || op === 'optionalCall') { value = await fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }var _biggystring = require('biggystring'); var bs = _interopRequireWildcard(_biggystring);
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } async function _asyncNullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return await rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }var _biggystring = require('biggystring'); var bs = _interopRequireWildcard(_biggystring);
2
2
  var _cleaners = require('cleaners');
3
3
  var _disklet = require('disklet');
4
4
 
@@ -31,6 +31,7 @@ var _makeProcessor = require('../db/makeProcessor');
31
31
 
32
32
  var _ProcessorTransaction = require('../db/Models/ProcessorTransaction');
33
33
 
34
+ var _utxo = require('../db/util/utxo');
34
35
 
35
36
 
36
37
 
@@ -41,7 +42,11 @@ var _cleaners3 = require('../keymanager/cleaners');
41
42
 
42
43
 
43
44
 
45
+
46
+
44
47
  var _keymanager = require('../keymanager/keymanager');
48
+ var _types5 = require('../keymanager/types');
49
+ var _utils = require('../keymanager/utxopicker/utils');
45
50
  var _makeUtxoEngineState = require('./makeUtxoEngineState');
46
51
  var _makeUtxoWalletTools = require('./makeUtxoWalletTools');
47
52
  var _paymentRequest = require('./paymentRequest');
@@ -49,9 +54,15 @@ var _paymentRequest = require('./paymentRequest');
49
54
 
50
55
 
51
56
 
52
- var _types5 = require('./types');
57
+
58
+ var _types7 = require('./types');
53
59
  var _getOwnUtxosFromTx = require('./util/getOwnUtxosFromTx');
54
- var _utils = require('./utils');
60
+
61
+
62
+
63
+
64
+
65
+ var _utils3 = require('./utils');
55
66
 
56
67
  async function makeUtxoEngine(
57
68
  config
@@ -71,7 +82,7 @@ var _utils = require('./utils');
71
82
  log
72
83
  } = options
73
84
  const { currencyInfo, engineInfo, coinInfo } = pluginInfo
74
- const userSettings = _types5.asUtxoUserSettings.call(void 0, options.userSettings)
85
+ const userSettings = _types7.asUtxoUserSettings.call(void 0, options.userSettings)
75
86
 
76
87
  // We should move the active server list to the engine state,
77
88
  // since multiple accounts can be logged in at once,
@@ -129,6 +140,208 @@ var _utils = require('./utils');
129
140
  })
130
141
 
131
142
  const engine = {
143
+ async accelerate(edgeTx) {
144
+ // Get the replaced transaction from the processor:
145
+ const replacedTxid = edgeTx.txid
146
+ const [replacedTx] = await processor.fetchTransactions({
147
+ txId: replacedTxid
148
+ })
149
+
150
+ // Transaction checks:
151
+ // The transaction must be found and not confirmed or dropped.
152
+ if (replacedTx == null) return null
153
+ if (replacedTx.blockHeight !== 0) return null
154
+
155
+ // Double the fee used for the RBF transaction:
156
+ const vBytes = _utils.transactionSizeFromHex.call(void 0, replacedTx.hex)
157
+ const newFeeRate = Math.round((parseInt(replacedTx.fees) / vBytes) * 2)
158
+
159
+ const replacedTxInputs = replacedTx.inputs
160
+ // Recreate UTXOs from processor transaction and mark them as unspent:
161
+ const replacedTxUtxos = await Promise.all(
162
+ replacedTxInputs.map(async (_, index) => {
163
+ const utxo = await _utxo.utxoFromProcessorTransactionInput.call(void 0,
164
+ processor,
165
+ replacedTx,
166
+ index
167
+ )
168
+ // Mark as unspent because we're going to reuse replaced tx's UTXOs
169
+ utxo.spent = false
170
+ return utxo
171
+ })
172
+ )
173
+ // Get the largest input from the transaction to re-use:
174
+ const replacedTxMaxUtxo = replacedTxUtxos.reduce((maxUtxo, utxo) => {
175
+ if (utxo.value > maxUtxo.value) return utxo
176
+ return maxUtxo
177
+ })
178
+
179
+ const targets = []
180
+ const newOurReceiveAddresses = []
181
+ let foundChangeAddress
182
+ for (const output of replacedTx.outputs) {
183
+ // Fetch address by output's scriptPubkey to determine output ownership
184
+ const ourAddress = await processor.fetchAddress(output.scriptPubkey)
185
+
186
+ // This isn't our output, so include it as a target
187
+ if (ourAddress == null) {
188
+ targets.push({
189
+ scriptPubkey: output.scriptPubkey,
190
+ value: parseInt(output.amount)
191
+ })
192
+ continue
193
+ }
194
+
195
+ // Addresses from database should include a path; this is a type assert
196
+ if (ourAddress.path == null)
197
+ throw new Error('Expecting path for address')
198
+
199
+ // The output is ours:
200
+ const purposeType = _utils3.pathToPurposeType.call(void 0,
201
+ ourAddress.path,
202
+ engineInfo.scriptTemplates
203
+ )
204
+ const addressType = _utils3.getAddressTypeFromPurposeType.call(void 0, purposeType)
205
+ const { address } = _keymanager.scriptPubkeyToAddress.call(void 0, {
206
+ scriptPubkey: ourAddress.scriptPubkey,
207
+ addressType,
208
+ coin: coinInfo.name,
209
+ redeemScript: ourAddress.redeemScript
210
+ })
211
+
212
+ newOurReceiveAddresses.push(address)
213
+
214
+ // Detect if it's the change address:
215
+ if (ourAddress.path.changeIndex === 1) {
216
+ foundChangeAddress = address
217
+ } else {
218
+ // This isn't our change address, so include it as a target.
219
+ // The transaction must have been a spend-to-self.
220
+ targets.push({
221
+ scriptPubkey: output.scriptPubkey,
222
+ value: parseInt(output.amount)
223
+ })
224
+ }
225
+ }
226
+
227
+ // Use the found change address or generate a new one:
228
+ const freshAddress =
229
+ foundChangeAddress == null
230
+ ? await engineState.getFreshAddress({ branch: 1 })
231
+ : { publicAddress: foundChangeAddress }
232
+ const freshChangeAddress =
233
+ _nullishCoalesce(freshAddress.segwitAddress, () => ( freshAddress.publicAddress))
234
+
235
+ // Get all current UTXOs:
236
+ const currentUtxos = _filterUndefined.filterUndefined.call(void 0,
237
+ await processor.fetchUtxos({
238
+ utxoIds: []
239
+ })
240
+ )
241
+ // Exclude all UTXOs which are from the replaced tx, because
242
+ // they wont be valid.
243
+ .filter(utxo => utxo.txid !== replacedTxid)
244
+
245
+ // Combine replaced transaction's inputs as UTXOs with the current UTXO set
246
+ const utxos = [...replacedTxUtxos, ...currentUtxos]
247
+
248
+ // New transaction to be the replacement transaction
249
+ const makeTxArgs = {
250
+ utxos,
251
+ forceUseUtxo: [replacedTxMaxUtxo],
252
+ targets,
253
+ memos: edgeTx.memos,
254
+ feeRate: newFeeRate,
255
+ coin: coinInfo.name,
256
+ currencyCode: currencyInfo.currencyCode,
257
+ enableRbf: true,
258
+ freshChangeAddress,
259
+ subtractFee: false,
260
+ log,
261
+ outputSort: 'bip69'
262
+ }
263
+ const newTx = (() => {
264
+ try {
265
+ return _keymanager.makeTx.call(void 0, makeTxArgs)
266
+ } catch (error) {
267
+ const cleanError = _types5.asMaybeInsufficientFundsErrorPlus.call(void 0, error)
268
+ if (_optionalChain([cleanError, 'optionalAccess', _2 => _2.networkFeeShortage]) != null) {
269
+ let feeDelta = parseInt(cleanError.networkFeeShortage)
270
+ // Adjust target values until we diminish the fee delta completely
271
+ for (const target of targets) {
272
+ if (target.value == null) continue
273
+ // The term is how much value to subtract from the target's value.
274
+ // The term's maximum value is the target's value.
275
+ // The term's minimum value is the fee delta.
276
+ const term = Math.min(target.value, feeDelta)
277
+ target.value -= term // Either decrement or zero out
278
+ feeDelta -= term // Ether decrement or zero out
279
+ }
280
+ // Retry making the transaction
281
+ return _keymanager.makeTx.call(void 0, makeTxArgs)
282
+ }
283
+ throw error
284
+ }
285
+ })()
286
+
287
+ if (newTx.changeUsed) {
288
+ newOurReceiveAddresses.push(freshChangeAddress)
289
+ }
290
+
291
+ // Generate new tracking of our scripts:
292
+ const newOurScriptPubkeys = newTx.inputs.map(input =>
293
+ input.scriptPubkey.toString('hex')
294
+ )
295
+
296
+ // Calculate transaction spend amount:
297
+ let nativeAmount = '0'
298
+ for (const output of newTx.outputs) {
299
+ const scriptPubkey = output.scriptPubkey.toString('hex')
300
+ const own = await processor.fetchAddress(scriptPubkey)
301
+ if (own == null) {
302
+ // Not our output
303
+ nativeAmount = bs.sub(nativeAmount, output.value.toString())
304
+ } else {
305
+ // Our output
306
+ newOurScriptPubkeys.push(scriptPubkey)
307
+ }
308
+ }
309
+
310
+ const networkFee = newTx.fee.toString()
311
+ nativeAmount = bs.sub(nativeAmount, networkFee)
312
+
313
+ const newTxOtherParams = {
314
+ unsignedTx: newTx.hex,
315
+ psbt: {
316
+ base64: newTx.psbtBase64,
317
+ inputs: newTx.inputs,
318
+ outputs: newTx.outputs
319
+ },
320
+ ourScriptPubkeys: newOurScriptPubkeys,
321
+ replacedTxid: replacedTxid
322
+ }
323
+
324
+ // Return a EdgeTransaction object with the updates
325
+ return {
326
+ ...edgeTx,
327
+ blockHeight: 0,
328
+ currencyCode: currencyInfo.currencyCode,
329
+ date: _unixTime.unixTime.call(void 0, ),
330
+ feeRateUsed: {
331
+ satPerVByte: newFeeRate
332
+ },
333
+ isSend: true,
334
+ nativeAmount,
335
+ networkFee,
336
+ otherParams: newTxOtherParams,
337
+ ourReceiveAddresses: newOurReceiveAddresses,
338
+ parentNetworkFee: undefined,
339
+ signedTx: '',
340
+ txid: '',
341
+ walletId: walletInfo.id
342
+ }
343
+ },
344
+
132
345
  async startEngine() {
133
346
  emitter.emit(
134
347
  _makeEngineEmitter.EngineEvent.WALLET_BALANCE_CHANGED,
@@ -166,8 +379,8 @@ var _utils = require('./utils');
166
379
  async broadcastTx(transaction) {
167
380
  const { otherParams } = transaction
168
381
  if (
169
- _optionalChain([otherParams, 'optionalAccess', _ => _.paymentProtocolInfo, 'optionalAccess', _2 => _2.payment]) != null &&
170
- _optionalChain([otherParams, 'optionalAccess', _3 => _3.paymentProtocolInfo, 'optionalAccess', _4 => _4.paymentUrl]) != null
382
+ _optionalChain([otherParams, 'optionalAccess', _3 => _3.paymentProtocolInfo, 'optionalAccess', _4 => _4.payment]) != null &&
383
+ _optionalChain([otherParams, 'optionalAccess', _5 => _5.paymentProtocolInfo, 'optionalAccess', _6 => _6.paymentUrl]) != null
171
384
  ) {
172
385
  const paymentAck = await _paymentRequest.sendPayment.call(void 0,
173
386
  io.fetch,
@@ -193,7 +406,7 @@ var _utils = require('./utils');
193
406
  },
194
407
 
195
408
  async changeUserSettings(userSettings) {
196
- await pluginState.updateServers(_types5.asUtxoUserSettings.call(void 0, userSettings))
409
+ await pluginState.updateServers(_types7.asUtxoUserSettings.call(void 0, userSettings))
197
410
  },
198
411
 
199
412
  async disableTokens(_tokens) {
@@ -236,10 +449,6 @@ var _utils = require('./utils');
236
449
  .join('\n')
237
450
  },
238
451
 
239
- async getEnabledTokens() {
240
- return await Promise.resolve([])
241
- },
242
-
243
452
  async getFreshAddress(
244
453
  opts
245
454
  ) {
@@ -261,10 +470,6 @@ var _utils = require('./utils');
261
470
  )
262
471
  },
263
472
 
264
- getTokenStatus(_token) {
265
- return false
266
- },
267
-
268
473
  async getTransactions(
269
474
  options
270
475
  ) {
@@ -295,17 +500,22 @@ var _utils = require('./utils');
295
500
  async makeSpend(edgeSpendInfo) {
296
501
  edgeSpendInfo = _upgradeMemos.upgradeMemos.call(void 0, edgeSpendInfo, currencyInfo)
297
502
  const { memos = [], spendTargets } = edgeSpendInfo
298
- const txOptions =
299
- _optionalChain([edgeSpendInfo, 'access', _5 => _5.otherParams, 'optionalAccess', _6 => _6.txOptions])
300
- const { outputSort = 'bip69', utxoSourceAddress, forceChangeAddress } =
503
+ const spendInfoOtherParams = _types7.asUtxoSpendInfoOtherParams.call(void 0,
301
504
  _nullishCoalesce(edgeSpendInfo.otherParams, () => ( {}))
505
+ )
506
+ const txOptions = _nullishCoalesce(spendInfoOtherParams.txOptions, () => ( {}))
507
+ const {
508
+ outputSort,
509
+ utxoSourceAddress,
510
+ forceChangeAddress
511
+ } = spendInfoOtherParams
302
512
 
303
513
  let utxoScriptPubkey
304
514
  if (utxoSourceAddress != null) {
305
515
  utxoScriptPubkey = walletTools.addressToScriptPubkey(utxoSourceAddress)
306
516
  }
307
517
 
308
- if (_optionalChain([txOptions, 'optionalAccess', _7 => _7.CPFP]) == null && spendTargets.length < 1) {
518
+ if (txOptions.CPFP == null && spendTargets.length < 1) {
309
519
  throw new Error('Need to provide Spend Targets')
310
520
  }
311
521
  // Calculate the total amount to send
@@ -314,7 +524,7 @@ var _utils = require('./utils');
314
524
  '0'
315
525
  )
316
526
  const utxos =
317
- await _asyncNullishCoalesce(await _asyncOptionalChain([txOptions, 'optionalAccess', async _8 => _8.utxos]), async () => (
527
+ await _asyncNullishCoalesce(txOptions.utxos, async () => (
318
528
  _filterUndefined.filterUndefined.call(void 0,
319
529
  (await processor.fetchUtxos({
320
530
  scriptPubkey: utxoScriptPubkey,
@@ -323,7 +533,7 @@ var _utils = require('./utils');
323
533
  )))
324
534
 
325
535
  if (
326
- bs.gt(totalAmountToSend, `${_utils.sumUtxos.call(void 0, utxos)}`) ||
536
+ bs.gt(totalAmountToSend, `${_utils3.sumUtxos.call(void 0, utxos)}`) ||
327
537
  utxos.length === 0
328
538
  ) {
329
539
  throw new (0, _edgecorejs.InsufficientFundsError)(currencyInfo.currencyCode)
@@ -337,7 +547,7 @@ var _utils = require('./utils');
337
547
  }
338
548
 
339
549
  // if script exists construct address from script
340
- if (_optionalChain([target, 'access', _9 => _9.otherParams, 'optionalAccess', _10 => _10.script]) != null) {
550
+ if (_optionalChain([target, 'access', _7 => _7.otherParams, 'optionalAccess', _8 => _8.script]) != null) {
341
551
  const { script } = target.otherParams
342
552
  if (script.type === 'replayProtection') {
343
553
  // construct a replay protection p2sh address
@@ -357,7 +567,7 @@ var _utils = require('./utils');
357
567
  const scriptPubkey = walletTools.addressToScriptPubkey(
358
568
  target.publicAddress
359
569
  )
360
- if (processor.fetchAddress(scriptPubkey) != null) {
570
+ if ((await processor.fetchAddress(scriptPubkey)) != null) {
361
571
  ourReceiveAddresses.push(target.publicAddress)
362
572
  }
363
573
  }
@@ -381,31 +591,12 @@ var _utils = require('./utils');
381
591
  freshAddress.segwitAddress)), () => (
382
592
  freshAddress.publicAddress))
383
593
 
384
- const setRBF = _nullishCoalesce(_optionalChain([txOptions, 'optionalAccess', _11 => _11.setRBF]), () => ( false))
385
- const rbfTxid = edgeSpendInfo.rbfTxid
594
+ const feeRate = parseInt(await fees.getRate(edgeSpendInfo))
595
+
386
596
  let maxUtxo
387
- let feeRate = parseInt(await fees.getRate(edgeSpendInfo))
388
- if (rbfTxid != null) {
389
- const [rbfTx] = await processor.fetchTransactions({ txId: rbfTxid })
390
- if (rbfTx == null) throw new Error('transaction not found')
391
- // double the fee used for the RBF transaction
392
- feeRate *= 2
393
- const rbfInputs = rbfTx.inputs
394
- const maxInput = rbfInputs.reduce((a, b) =>
395
- bs.gt(a.amount, b.amount) ? a : b
396
- )
397
- const maxId = `${maxInput.txId}_${maxInput.outputIndex}`
398
- maxUtxo = (await processor.fetchUtxos({ utxoIds: [maxId] }))[0]
399
- if (maxUtxo == null) {
400
- log.error('transaction to be replaced found, but not its input utxos')
401
- throw new Error(
402
- 'transaction to be replaced found, but not its input utxos'
403
- )
404
- }
405
- }
406
- if (_optionalChain([txOptions, 'optionalAccess', _12 => _12.CPFP]) != null) {
597
+ if (txOptions.CPFP != null) {
407
598
  const [childTx] = await processor.fetchTransactions({
408
- txId: _optionalChain([txOptions, 'optionalAccess', _13 => _13.CPFP])
599
+ txId: txOptions.CPFP
409
600
  })
410
601
  if (childTx == null) throw new Error('transaction not found')
411
602
  const utxos = []
@@ -417,9 +608,10 @@ var _utils = require('./utils');
417
608
  // cpfp just sends to change, no target addresses are required
418
609
  targets = []
419
610
  }
611
+
420
612
  log.warn(`spend: Using fee rate ${feeRate} sat/B`)
421
613
  const subtractFee =
422
- _optionalChain([txOptions, 'optionalAccess', _14 => _14.subtractFee]) != null ? txOptions.subtractFee : false
614
+ txOptions.subtractFee != null ? txOptions.subtractFee : false
423
615
  const tx = _keymanager.makeTx.call(void 0, {
424
616
  utxos,
425
617
  forceUseUtxo: maxUtxo != null ? [maxUtxo] : [],
@@ -428,7 +620,10 @@ var _utils = require('./utils');
428
620
  feeRate,
429
621
  coin: coinInfo.name,
430
622
  currencyCode: currencyInfo.currencyCode,
431
- setRBF,
623
+ enableRbf:
624
+ _nullishCoalesce(_nullishCoalesce(spendInfoOtherParams.enableRbf, () => (
625
+ currencyInfo.canReplaceByFee)), () => (
626
+ false)),
432
627
  freshChangeAddress,
433
628
  subtractFee,
434
629
  log,
@@ -507,6 +702,26 @@ var _utils = require('./utils');
507
702
  },
508
703
 
509
704
  async saveTx(edgeTx) {
705
+ // If the transaction being saved replaces a transaction, update it.
706
+ const replacedTxid = _optionalChain([edgeTx, 'access', _9 => _9.otherParams, 'optionalAccess', _10 => _10.replacedTxid])
707
+ if (replacedTxid != null) {
708
+ // Get the replaced transaction using the replacedTxid
709
+ const [rbfTx] = await processor.fetchTransactions({
710
+ txId: replacedTxid
711
+ })
712
+ if (rbfTx != null) {
713
+ rbfTx.blockHeight = -1
714
+ await _makeUtxoEngineState.transactionChanged.call(void 0, {
715
+ walletId: walletInfo.id,
716
+ tx: rbfTx,
717
+ pluginInfo,
718
+ emitter,
719
+ walletTools,
720
+ processor
721
+ })
722
+ }
723
+ }
724
+
510
725
  const tx = _ProcessorTransaction.fromEdgeTransaction.call(void 0, edgeTx)
511
726
  await _makeUtxoEngineState.transactionChanged.call(void 0, {
512
727
  walletId: walletInfo.id,
@@ -518,7 +733,7 @@ var _utils = require('./utils');
518
733
  })
519
734
  await processor.saveTransaction({
520
735
  tx,
521
- scriptPubkeys: _optionalChain([edgeTx, 'access', _15 => _15.otherParams, 'optionalAccess', _16 => _16.ourScriptPubkeys])
736
+ scriptPubkeys: _optionalChain([edgeTx, 'access', _11 => _11.otherParams, 'optionalAccess', _12 => _12.ourScriptPubkeys])
522
737
  })
523
738
 
524
739
  /*
@@ -533,11 +748,11 @@ var _utils = require('./utils');
533
748
  privateKeys,
534
749
  opts
535
750
  ) {
536
- const otherParams = _types5.asUtxoSignMessageOtherParams.call(void 0, opts.otherParams)
751
+ const otherParams = _types7.asUtxoSignMessageOtherParams.call(void 0, opts.otherParams)
537
752
  const { publicAddress } = otherParams
538
753
  const scriptPubkey = walletTools.addressToScriptPubkey(publicAddress)
539
754
  const processorAddress = await processor.fetchAddress(scriptPubkey)
540
- if (_optionalChain([processorAddress, 'optionalAccess', _17 => _17.path]) == null) {
755
+ if (_optionalChain([processorAddress, 'optionalAccess', _13 => _13.path]) == null) {
541
756
  throw new Error('Missing address to sign with')
542
757
  }
543
758
  const privateKey = asMaybeCurrencyPrivateKey(privateKeys)
@@ -546,14 +761,14 @@ var _utils = require('./utils');
546
761
  throw new Error('Cannot sign a message for a read-only wallet')
547
762
 
548
763
  // Derive the xprivs on the fly, since we do not persist them
549
- const xprivKeys = await _utils.fetchOrDeriveXprivFromKeys.call(void 0, {
764
+ const xprivKeys = await _utils3.fetchOrDeriveXprivFromKeys.call(void 0, {
550
765
  privateKey,
551
766
  walletLocalEncryptedDisklet,
552
767
  coin: coinInfo.name
553
768
  })
554
769
 
555
770
  const signature = await walletTools.signMessageBase64({
556
- path: _optionalChain([processorAddress, 'optionalAccess', _18 => _18.path]),
771
+ path: _optionalChain([processorAddress, 'optionalAccess', _14 => _14.path]),
557
772
  message,
558
773
  xprivKeys
559
774
  })
@@ -568,8 +783,7 @@ var _utils = require('./utils');
568
783
  if (otherParams == null) throw new Error('Invalid transaction data')
569
784
 
570
785
  const { psbt, edgeSpendInfo } = otherParams
571
- if (psbt == null || edgeSpendInfo == null)
572
- throw new Error('Invalid transaction data')
786
+ if (psbt == null) throw new Error('Invalid transaction data')
573
787
 
574
788
  const privateKey = asMaybeCurrencyPrivateKey(privateKeys)
575
789
 
@@ -577,7 +791,7 @@ var _utils = require('./utils');
577
791
  throw new Error('Cannot sign a transaction for a read-only wallet')
578
792
 
579
793
  // Derive the xprivs on the fly, since we do not persist them
580
- const xprivKeys = await _utils.fetchOrDeriveXprivFromKeys.call(void 0, {
794
+ const xprivKeys = await _utils3.fetchOrDeriveXprivFromKeys.call(void 0, {
581
795
  privateKey,
582
796
  walletLocalEncryptedDisklet,
583
797
  coin: coinInfo.name
@@ -588,24 +802,34 @@ var _utils = require('./utils');
588
802
  const privateKeyEncodings = await (async (
589
803
 
590
804
  ) => {
591
- if (edgeSpendInfo.privateKeys != null) {
805
+ if (_optionalChain([edgeSpendInfo, 'optionalAccess', _15 => _15.privateKeys]) != null) {
592
806
  return edgeSpendInfo.privateKeys.map(wif =>
593
807
  walletTools.getPrivateKeyEncodingFromWif(wif)
594
808
  )
595
809
  } else {
596
810
  return await Promise.all(
597
- psbt.inputs.map(async ({ hash, index }) => {
598
- const txid = Buffer.from(hash).reverse().toString('hex')
599
- const utxoId = `${txid}_${index}`
811
+ psbt.inputs.map(async ({ hash, index: vout }) => {
812
+ const txId = Buffer.from(hash).reverse().toString('hex')
600
813
 
601
- const [utxo] = await processor.fetchUtxos({
602
- utxoIds: [utxoId]
603
- })
604
- if (utxo == null) throw new Error('Invalid UTXO')
605
-
606
- const address = await processor.fetchAddress(utxo.scriptPubkey)
814
+ const [transaction] = await processor.fetchTransactions({ txId })
815
+ if (transaction == null)
816
+ throw new Error(
817
+ 'Unable to find previous transaction data for input'
818
+ )
819
+ const prevout = transaction.outputs.find(
820
+ input => input.n === vout
821
+ )
822
+ if (prevout == null)
823
+ throw new Error('Unable to find prevout in transaction')
824
+ const { scriptPubkey } = prevout
825
+
826
+ // Use the scriptPubkey to find the private key from the address
827
+ // derivation path
828
+ const address = await processor.fetchAddress(scriptPubkey)
607
829
  if (address == null) {
608
- throw new Error(`Address for UTXO ${utxoId} not found`)
830
+ throw new Error(
831
+ `Address for scriptPubkey '${scriptPubkey}' not found`
832
+ )
609
833
  }
610
834
  if (address.path == null)
611
835
  throw new Error(
@@ -634,7 +858,7 @@ var _utils = require('./utils');
634
858
  transaction.signedTx = signedTx.hex
635
859
 
636
860
  const { paymentProtocolInfo } =
637
- _nullishCoalesce(_optionalChain([transaction, 'access', _19 => _19.otherParams, 'optionalAccess', _20 => _20.edgeSpendInfo, 'optionalAccess', _21 => _21.otherParams]), () => ( {}))
861
+ _nullishCoalesce(_optionalChain([transaction, 'access', _16 => _16.otherParams, 'optionalAccess', _17 => _17.edgeSpendInfo, 'optionalAccess', _18 => _18.otherParams]), () => ( {}))
638
862
  if (paymentProtocolInfo != null) {
639
863
  const payment = _paymentRequest.createPayment.call(void 0,
640
864
  transaction.signedTx,
@@ -1569,25 +1569,27 @@ const processRawUtxo = async (
1569
1569
  let redeemScript
1570
1570
 
1571
1571
  // Function to call once we are finished
1572
- const done = () =>
1572
+ const done = () => {
1573
+ const processorUtxo = {
1574
+ id,
1575
+ txid: utxo.txid,
1576
+ vout: utxo.vout,
1577
+ value: utxo.value,
1578
+ scriptPubkey: address.scriptPubkey,
1579
+ script,
1580
+ redeemScript,
1581
+ scriptType,
1582
+ blockHeight: _nullishCoalesce(utxo.height, () => ( -1)),
1583
+ spent: false
1584
+ }
1573
1585
  addToProcessorUtxoCache(
1574
1586
  processorUtxoCache,
1575
1587
  path,
1576
1588
  address.scriptPubkey,
1577
1589
  requiredCount,
1578
- {
1579
- id,
1580
- txid: utxo.txid,
1581
- vout: utxo.vout,
1582
- value: utxo.value,
1583
- scriptPubkey: address.scriptPubkey,
1584
- script,
1585
- redeemScript,
1586
- scriptType,
1587
- blockHeight: _nullishCoalesce(utxo.height, () => ( -1)),
1588
- spent: false
1589
- }
1590
+ processorUtxo
1590
1591
  )
1592
+ }
1591
1593
 
1592
1594
  switch (purposeType) {
1593
1595
  case _keymanager.BIP43PurposeTypeEnum.Airbitz:
@@ -1,8 +1,17 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true});var _cleaners = require('cleaners');
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
2
 
3
3
 
4
4
 
5
5
 
6
+
7
+
8
+
9
+ var _cleaners = require('cleaners');
10
+
11
+
12
+ var _types3 = require('../../plugin/types');
13
+
14
+
6
15
  const asUtxoUserSettings = _cleaners.asObject.call(void 0, {
7
16
  blockbookServers: _cleaners.asMaybe.call(void 0, _cleaners.asArray.call(void 0, _cleaners.asString), []),
8
17
  enableCustomServers: _cleaners.asMaybe.call(void 0, _cleaners.asBoolean, false)
@@ -23,6 +32,18 @@
23
32
 
24
33
 
25
34
 
35
+
26
36
  const asUtxoSignMessageOtherParams = _cleaners.asObject.call(void 0, {
27
37
  publicAddress: _cleaners.asString
28
38
  }); exports.asUtxoSignMessageOtherParams = asUtxoSignMessageOtherParams
39
+
40
+
41
+
42
+
43
+ const asUtxoSpendInfoOtherParams = _cleaners.asObject.call(void 0, {
44
+ enableRbf: _cleaners.asOptional.call(void 0, _cleaners.asBoolean),
45
+ forceChangeAddress: _cleaners.asOptional.call(void 0, _cleaners.asString),
46
+ outputSort: _cleaners.asOptional.call(void 0, _cleaners.asValue.call(void 0, 'bip69', 'targets'), 'bip69'),
47
+ txOptions: _cleaners.asOptional.call(void 0, _types3.asTxOptions),
48
+ utxoSourceAddress: _cleaners.asOptional.call(void 0, _cleaners.asString)
49
+ }); exports.asUtxoSpendInfoOtherParams = asUtxoSpendInfoOtherParams
@@ -12,8 +12,9 @@ var _biggystring = require('biggystring');
12
12
  var _bip32 = require('bip32'); var bip32 = _interopRequireWildcard(_bip32);
13
13
  var _bip39 = require('bip39'); var bip39 = _interopRequireWildcard(_bip39);
14
14
  var _bitcoinjsmessage = require('bitcoinjs-message'); var _bitcoinjsmessage2 = _interopRequireDefault(_bitcoinjsmessage);
15
+ var _cleaners = require('cleaners');
15
16
  var _ecpair = require('ecpair');
16
- var _types = require('edge-core-js/types');
17
+
17
18
 
18
19
  var _indexAtProtected = require('../../../util/indexAtProtected');
19
20
  var _undefinedIfEmptyString = require('../../../util/undefinedIfEmptyString');
@@ -27,7 +28,9 @@ var _bip69 = require('./bip69');
27
28
 
28
29
  var _cashAddress = require('./bitcoincashUtils/cashAddress');
29
30
  var _coinmapper = require('./coinmapper');
31
+ var _types9 = require('./types');
30
32
  var _utxopicker = require('./utxopicker'); var utxopicker = _interopRequireWildcard(_utxopicker);
33
+ var _utils = require('./utxopicker/utils'); var pickerUtils = _interopRequireWildcard(_utils);
31
34
 
32
35
  let ECPair
33
36
 
@@ -73,6 +76,17 @@ var ScriptTypeEnum; (function (ScriptTypeEnum) {
73
76
  const replayProtection = 'replayprotection'; ScriptTypeEnum["replayProtection"] = replayProtection;
74
77
  const replayProtectionP2SH = 'replayprotectionp2sh'; ScriptTypeEnum["replayProtectionP2SH"] = replayProtectionP2SH;
75
78
  })(ScriptTypeEnum || (exports.ScriptTypeEnum = ScriptTypeEnum = {}));
79
+ const asScriptTypeEnum = _cleaners.asValue.call(void 0,
80
+ 'p2wpkh' ,
81
+ 'p2wpkhp2sh' ,
82
+ 'p2wsh' ,
83
+ 'p2pk' ,
84
+ 'p2pkh' ,
85
+ 'p2sh' ,
86
+ 'p2tr' ,
87
+ 'replayprotection' ,
88
+ 'replayprotectionp2sh'
89
+ ); exports.asScriptTypeEnum = asScriptTypeEnum
76
90
 
77
91
  // A transaction input is either legacy or segwit. This is used for transaction creation and passed per input
78
92
  var TransactionInputTypeEnum; (function (TransactionInputTypeEnum) {
@@ -257,6 +271,7 @@ var VerifyAddressEnum; (function (VerifyAddressEnum) {
257
271
 
258
272
 
259
273
 
274
+
260
275
 
261
276
 
262
277
  function bip43PurposeNumberToTypeEnum(
@@ -928,7 +943,7 @@ const wifToPrivateKeyEncodingInternal = (
928
943
  function makeTx(args) {
929
944
  const { log, outputSort, memos } = args
930
945
  let sequence = 0xffffffff
931
- if (args.setRBF) {
946
+ if (args.enableRbf) {
932
947
  sequence -= 2
933
948
  }
934
949
 
@@ -1006,16 +1021,22 @@ const wifToPrivateKeyEncodingInternal = (
1006
1021
 
1007
1022
  const targets = []
1008
1023
  for (const target of args.targets) {
1009
- if (target.address != null && target.value != null) {
1010
- const script = exports.addressToScriptPubkey.call(void 0, {
1011
- address: target.address,
1012
- coin: coin.name
1013
- })
1014
- targets.push({
1015
- script,
1016
- value: target.value
1017
- })
1018
- }
1024
+ if (target.value == null) continue
1025
+
1026
+ const scriptPubkey =
1027
+ target.address == null
1028
+ ? target.scriptPubkey
1029
+ : exports.addressToScriptPubkey.call(void 0, {
1030
+ address: target.address,
1031
+ coin: coin.name
1032
+ })
1033
+
1034
+ if (scriptPubkey == null) continue
1035
+
1036
+ targets.push({
1037
+ script: scriptPubkey,
1038
+ value: target.value
1039
+ })
1019
1040
  }
1020
1041
  for (const memo of memos) {
1021
1042
  const memoData =
@@ -1051,8 +1072,16 @@ const wifToPrivateKeyEncodingInternal = (
1051
1072
  feeRate: args.feeRate,
1052
1073
  changeScript
1053
1074
  })
1054
- if (result.inputs == null || result.outputs == null) {
1055
- throw new (0, _types.InsufficientFundsError)(args.currencyCode)
1075
+ if (result.outputs == null) {
1076
+ const targetsValue = pickerUtils.sumOrNaN(targets)
1077
+ const inputsValue = pickerUtils.sumOrNaN(result.inputs)
1078
+ // This is how much fee is needed to validate the spend
1079
+ const feeDelta = result.fee - (inputsValue - targetsValue)
1080
+ throw new (0, _types9.InsufficientFundsErrorPlus)({
1081
+ currencyCode: args.currencyCode,
1082
+ networkFee: result.fee.toString(),
1083
+ networkFeeShortage: feeDelta.toString()
1084
+ })
1056
1085
  }
1057
1086
 
1058
1087
  const sortedInputs = _bip69.sortInputs.call(void 0, result.inputs)
@@ -0,0 +1,33 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
+ var _types = require('edge-core-js/types');
3
+
4
+
5
+
6
+
7
+
8
+
9
+
10
+
11
+ class InsufficientFundsErrorPlus extends _types.InsufficientFundsError {
12
+
13
+ constructor(opts = {}) {
14
+ super(opts)
15
+ const { networkFeeShortage } = opts
16
+ this.networkFeeShortage = networkFeeShortage
17
+ }
18
+ } exports.InsufficientFundsErrorPlus = InsufficientFundsErrorPlus;
19
+
20
+ function asMaybeError(name) {
21
+ return function asError(raw) {
22
+ if (raw instanceof Error && raw.name === name) {
23
+ const typeHack = raw
24
+ return typeHack
25
+ }
26
+ }
27
+ }
28
+
29
+ const asMaybeInsufficientFundsErrorPlus = asMaybeError(
30
+ // Share the same name because this error type is a subtype of
31
+ // InsufficientFundsError and therefore backwards compatible
32
+ 'InsufficientFundsError'
33
+ ); exports.asMaybeInsufficientFundsErrorPlus = asMaybeInsufficientFundsErrorPlus
@@ -47,6 +47,7 @@ var _utils = require('./utils'); var utils = _interopRequireWildcard(_utils);
47
47
 
48
48
  return {
49
49
  changeUsed: false,
50
- fee: Math.ceil(feeRate * utils.transactionBytes(inputs, outputs))
50
+ fee: Math.ceil(feeRate * utils.transactionBytes(inputs, outputs)),
51
+ inputs
51
52
  }
52
53
  } exports.accumulative = accumulative;
@@ -54,6 +54,7 @@ var _utils = require('./utils'); var utils = _interopRequireWildcard(_utils);
54
54
 
55
55
  return {
56
56
  changeUsed: false,
57
- fee: Math.ceil(feeRate * utils.transactionBytes(inputs, outputs))
57
+ fee: Math.ceil(feeRate * utils.transactionBytes(inputs, outputs)),
58
+ inputs
58
59
  }
59
60
  } exports.forceUseUtxo = forceUseUtxo;
@@ -1,4 +1,6 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true});var _keymanager = require('../keymanager');
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } }var _altcoinjs = require('altcoin-js'); var bitcoin = _interopRequireWildcard(_altcoinjs);
2
+
3
+ var _keymanager = require('../keymanager');
2
4
 
3
5
 
4
6
  /*
@@ -108,6 +110,11 @@ function witnessCount(inputs) {
108
110
  return overhead + inputsSize + outputsSize
109
111
  } exports.transactionBytes = transactionBytes;
110
112
 
113
+ const transactionSizeFromHex = (hex) => {
114
+ const transaction = bitcoin.Transaction.fromHex(hex)
115
+ return transaction.virtualSize()
116
+ }; exports.transactionSizeFromHex = transactionSizeFromHex
117
+
111
118
  function uintOrNaN(v) {
112
119
  if (!isFinite(v)) return NaN
113
120
  if (Math.floor(v) !== v) return NaN
@@ -90,7 +90,7 @@ var _cleaners = require('cleaners');
90
90
  txid: _cleaners.asString,
91
91
  sequence: _cleaners.asOptional.call(void 0, _cleaners.asNumber),
92
92
  n: _cleaners.asNumber,
93
- vout: _cleaners.asOptional.call(void 0, _cleaners.asNumber, -1),
93
+ vout: _cleaners.asOptional.call(void 0, _cleaners.asNumber, 0), // If Blockbook doesn't provide vout, assume 0 (empirically observed)
94
94
  addresses: _cleaners.asArray.call(void 0, asAddress),
95
95
  isAddress: _cleaners.asBoolean,
96
96
  value: _cleaners.asString,
@@ -24,9 +24,9 @@ export interface AddressPath {
24
24
  export interface TxOptions {
25
25
  utxos?: IUTXO[];
26
26
  subtractFee?: boolean;
27
- setRBF?: boolean;
28
27
  CPFP?: string;
29
28
  }
29
+ export declare const asTxOptions: import("cleaners").ObjectCleaner<TxOptions>;
30
30
  export interface PluginInfo {
31
31
  currencyInfo: EdgeCurrencyInfo;
32
32
  engineInfo: EngineInfo;
@@ -24,6 +24,7 @@ export interface IUTXO {
24
24
  blockHeight: number;
25
25
  spent: boolean;
26
26
  }
27
+ export declare const asIUTXO: import("cleaners").ObjectCleaner<IUTXO>;
27
28
  export interface IProcessorTransaction {
28
29
  txid: string;
29
30
  hex: string;
@@ -0,0 +1,3 @@
1
+ import { Processor } from '../makeProcessor';
2
+ import { IProcessorTransaction, IUTXO } from '../types';
3
+ export declare const utxoFromProcessorTransactionInput: (processor: Processor, processorTransaction: IProcessorTransaction, inputIndex: number) => Promise<IUTXO>;
@@ -14,8 +14,17 @@ export interface UtxoTxOtherParams {
14
14
  };
15
15
  edgeSpendInfo?: EdgeSpendInfo;
16
16
  ourScriptPubkeys: string[];
17
+ replacedTxid?: string;
17
18
  }
18
19
  export declare type UtxoSignMessageOtherParams = ReturnType<typeof asUtxoSignMessageOtherParams>;
19
20
  export declare const asUtxoSignMessageOtherParams: import("cleaners").ObjectCleaner<{
20
21
  publicAddress: string;
21
22
  }>;
23
+ export declare type UtxoSpendInfoOtherParams = ReturnType<typeof asUtxoSpendInfoOtherParams>;
24
+ export declare const asUtxoSpendInfoOtherParams: import("cleaners").ObjectCleaner<{
25
+ enableRbf: boolean | undefined;
26
+ forceChangeAddress: string | undefined;
27
+ outputSort: "targets" | "bip69";
28
+ txOptions: import("../../plugin/types").TxOptions | undefined;
29
+ utxoSourceAddress: string | undefined;
30
+ }>;
@@ -28,6 +28,7 @@ export declare enum ScriptTypeEnum {
28
28
  replayProtection = "replayprotection",
29
29
  replayProtectionP2SH = "replayprotectionp2sh"
30
30
  }
31
+ export declare const asScriptTypeEnum: import("cleaners").Cleaner<ScriptTypeEnum>;
31
32
  export declare enum TransactionInputTypeEnum {
32
33
  Legacy = "legacy",
33
34
  Segwit = "segwit"
@@ -136,7 +137,7 @@ export interface MakeTxArgs {
136
137
  targets: MakeTxTarget[];
137
138
  memos: EdgeMemo[];
138
139
  feeRate: number;
139
- setRBF: boolean;
140
+ enableRbf: boolean;
140
141
  coin: string;
141
142
  currencyCode: string;
142
143
  freshChangeAddress: string;
@@ -146,9 +147,10 @@ export interface MakeTxArgs {
146
147
  }
147
148
  export interface MakeTxTarget {
148
149
  address?: string;
150
+ scriptPubkey?: string;
149
151
  value?: number;
150
152
  }
151
- interface MakeTxReturn extends Required<utxopicker.UtxoPickerResult> {
153
+ export interface MakeTxReturn extends Required<utxopicker.UtxoPickerResult> {
152
154
  hex: string;
153
155
  psbtBase64: string;
154
156
  }
@@ -0,0 +1,13 @@
1
+ import { Cleaner } from 'cleaners';
2
+ import { InsufficientFundsError } from 'edge-core-js/types';
3
+ interface InsufficientFundsErrorOptsPlus {
4
+ currencyCode?: string;
5
+ networkFee?: string;
6
+ networkFeeShortage?: string;
7
+ }
8
+ export declare class InsufficientFundsErrorPlus extends InsufficientFundsError {
9
+ networkFeeShortage?: string;
10
+ constructor(opts?: InsufficientFundsErrorOptsPlus);
11
+ }
12
+ export declare const asMaybeInsufficientFundsErrorPlus: Cleaner<InsufficientFundsErrorPlus | undefined>;
13
+ export {};
@@ -28,7 +28,7 @@ export interface UtxoPickerArgs {
28
28
  changeScript: string;
29
29
  }
30
30
  export interface UtxoPickerResult {
31
- inputs?: Input[];
31
+ inputs: Input[];
32
32
  outputs?: Output[];
33
33
  changeUsed: boolean;
34
34
  fee: number;
@@ -5,6 +5,7 @@ export declare function inputBytes(input: UTXO): number;
5
5
  export declare function outputBytes(output: Output): number;
6
6
  export declare function dustThreshold(output: Output, feeRate: number): number;
7
7
  export declare function transactionBytes(inputs: UTXO[], outputs: Output[]): number;
8
+ export declare const transactionSizeFromHex: (hex: string) => number;
8
9
  export declare function uintOrNaN(v: number): number;
9
10
  export declare function sumForgiving(range: Array<{
10
11
  value: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "edge-currency-plugins",
3
- "version": "2.4.1",
3
+ "version": "2.5.0",
4
4
  "description": "Edge currency plugins to fetch and process wallet accounts, balances and transactions.",
5
5
  "repository": "https://github.com/EdgeApp/edge-currency-plugins",
6
6
  "license": "MIT",