edge-currency-plugins 2.4.1 → 2.5.1

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,211 @@ var _utils = require('./utils');
129
140
  })
130
141
 
131
142
  const engine = {
143
+ async accelerate(edgeTx) {
144
+ const { canReplaceByFee = false } = currencyInfo
145
+ if (!canReplaceByFee) return null
146
+
147
+ // Get the replaced transaction from the processor:
148
+ const replacedTxid = edgeTx.txid
149
+ const [replacedTx] = await processor.fetchTransactions({
150
+ txId: replacedTxid
151
+ })
152
+
153
+ // Transaction checks:
154
+ // The transaction must be found and not confirmed or dropped.
155
+ if (replacedTx == null) return null
156
+ if (replacedTx.blockHeight !== 0) return null
157
+
158
+ // Double the fee used for the RBF transaction:
159
+ const vBytes = _utils.transactionSizeFromHex.call(void 0, replacedTx.hex)
160
+ const newFeeRate = Math.round((parseInt(replacedTx.fees) / vBytes) * 2)
161
+
162
+ const replacedTxInputs = replacedTx.inputs
163
+ // Recreate UTXOs from processor transaction and mark them as unspent:
164
+ const replacedTxUtxos = await Promise.all(
165
+ replacedTxInputs.map(async (_, index) => {
166
+ const utxo = await _utxo.utxoFromProcessorTransactionInput.call(void 0,
167
+ processor,
168
+ replacedTx,
169
+ index
170
+ )
171
+ // Mark as unspent because we're going to reuse replaced tx's UTXOs
172
+ utxo.spent = false
173
+ return utxo
174
+ })
175
+ )
176
+ // Get the largest input from the transaction to re-use:
177
+ const replacedTxMaxUtxo = replacedTxUtxos.reduce((maxUtxo, utxo) => {
178
+ if (utxo.value > maxUtxo.value) return utxo
179
+ return maxUtxo
180
+ })
181
+
182
+ const targets = []
183
+ const newOurReceiveAddresses = []
184
+ let foundChangeAddress
185
+ for (const output of replacedTx.outputs) {
186
+ // Fetch address by output's scriptPubkey to determine output ownership
187
+ const ourAddress = await processor.fetchAddress(output.scriptPubkey)
188
+
189
+ // This isn't our output, so include it as a target
190
+ if (ourAddress == null) {
191
+ targets.push({
192
+ scriptPubkey: output.scriptPubkey,
193
+ value: parseInt(output.amount)
194
+ })
195
+ continue
196
+ }
197
+
198
+ // Addresses from database should include a path; this is a type assert
199
+ if (ourAddress.path == null)
200
+ throw new Error('Expecting path for address')
201
+
202
+ // The output is ours:
203
+ const purposeType = _utils3.pathToPurposeType.call(void 0,
204
+ ourAddress.path,
205
+ engineInfo.scriptTemplates
206
+ )
207
+ const addressType = _utils3.getAddressTypeFromPurposeType.call(void 0, purposeType)
208
+ const { address } = _keymanager.scriptPubkeyToAddress.call(void 0, {
209
+ scriptPubkey: ourAddress.scriptPubkey,
210
+ addressType,
211
+ coin: coinInfo.name,
212
+ redeemScript: ourAddress.redeemScript
213
+ })
214
+
215
+ newOurReceiveAddresses.push(address)
216
+
217
+ // Detect if it's the change address:
218
+ if (ourAddress.path.changeIndex === 1) {
219
+ foundChangeAddress = address
220
+ } else {
221
+ // This isn't our change address, so include it as a target.
222
+ // The transaction must have been a spend-to-self.
223
+ targets.push({
224
+ scriptPubkey: output.scriptPubkey,
225
+ value: parseInt(output.amount)
226
+ })
227
+ }
228
+ }
229
+
230
+ // Use the found change address or generate a new one:
231
+ const freshAddress =
232
+ foundChangeAddress == null
233
+ ? await engineState.getFreshAddress({ branch: 1 })
234
+ : { publicAddress: foundChangeAddress }
235
+ const freshChangeAddress =
236
+ _nullishCoalesce(freshAddress.segwitAddress, () => ( freshAddress.publicAddress))
237
+
238
+ // Get all current UTXOs:
239
+ const currentUtxos = _filterUndefined.filterUndefined.call(void 0,
240
+ await processor.fetchUtxos({
241
+ utxoIds: []
242
+ })
243
+ )
244
+ // Exclude all UTXOs which are from the replaced tx, because
245
+ // they wont be valid.
246
+ .filter(utxo => utxo.txid !== replacedTxid)
247
+
248
+ // Combine replaced transaction's inputs as UTXOs with the current UTXO set
249
+ const utxos = [...replacedTxUtxos, ...currentUtxos]
250
+
251
+ // New transaction to be the replacement transaction
252
+ const makeTxArgs = {
253
+ utxos,
254
+ forceUseUtxo: [replacedTxMaxUtxo],
255
+ targets,
256
+ memos: edgeTx.memos,
257
+ feeRate: newFeeRate,
258
+ coin: coinInfo.name,
259
+ currencyCode: currencyInfo.currencyCode,
260
+ enableRbf: true,
261
+ freshChangeAddress,
262
+ subtractFee: false,
263
+ log,
264
+ outputSort: 'bip69'
265
+ }
266
+ const newTx = (() => {
267
+ try {
268
+ return _keymanager.makeTx.call(void 0, makeTxArgs)
269
+ } catch (error) {
270
+ const cleanError = _types5.asMaybeInsufficientFundsErrorPlus.call(void 0, error)
271
+ if (_optionalChain([cleanError, 'optionalAccess', _2 => _2.networkFeeShortage]) != null) {
272
+ let feeDelta = parseInt(cleanError.networkFeeShortage)
273
+ // Adjust target values until we diminish the fee delta completely
274
+ for (const target of targets) {
275
+ if (target.value == null) continue
276
+ // The term is how much value to subtract from the target's value.
277
+ // The term's maximum value is the target's value.
278
+ // The term's minimum value is the fee delta.
279
+ const term = Math.min(target.value, feeDelta)
280
+ target.value -= term // Either decrement or zero out
281
+ feeDelta -= term // Ether decrement or zero out
282
+ }
283
+ // Retry making the transaction
284
+ return _keymanager.makeTx.call(void 0, makeTxArgs)
285
+ }
286
+ throw error
287
+ }
288
+ })()
289
+
290
+ if (newTx.changeUsed) {
291
+ newOurReceiveAddresses.push(freshChangeAddress)
292
+ }
293
+
294
+ // Generate new tracking of our scripts:
295
+ const newOurScriptPubkeys = newTx.inputs.map(input =>
296
+ input.scriptPubkey.toString('hex')
297
+ )
298
+
299
+ // Calculate transaction spend amount:
300
+ let nativeAmount = '0'
301
+ for (const output of newTx.outputs) {
302
+ const scriptPubkey = output.scriptPubkey.toString('hex')
303
+ const own = await processor.fetchAddress(scriptPubkey)
304
+ if (own == null) {
305
+ // Not our output
306
+ nativeAmount = bs.sub(nativeAmount, output.value.toString())
307
+ } else {
308
+ // Our output
309
+ newOurScriptPubkeys.push(scriptPubkey)
310
+ }
311
+ }
312
+
313
+ const networkFee = newTx.fee.toString()
314
+ nativeAmount = bs.sub(nativeAmount, networkFee)
315
+
316
+ const newTxOtherParams = {
317
+ unsignedTx: newTx.hex,
318
+ psbt: {
319
+ base64: newTx.psbtBase64,
320
+ inputs: newTx.inputs,
321
+ outputs: newTx.outputs
322
+ },
323
+ ourScriptPubkeys: newOurScriptPubkeys,
324
+ replacedTxid: replacedTxid
325
+ }
326
+
327
+ // Return a EdgeTransaction object with the updates
328
+ return {
329
+ ...edgeTx,
330
+ blockHeight: 0,
331
+ currencyCode: currencyInfo.currencyCode,
332
+ date: _unixTime.unixTime.call(void 0, ),
333
+ feeRateUsed: {
334
+ satPerVByte: newFeeRate
335
+ },
336
+ isSend: true,
337
+ nativeAmount,
338
+ networkFee,
339
+ otherParams: newTxOtherParams,
340
+ ourReceiveAddresses: newOurReceiveAddresses,
341
+ parentNetworkFee: undefined,
342
+ signedTx: '',
343
+ txid: '',
344
+ walletId: walletInfo.id
345
+ }
346
+ },
347
+
132
348
  async startEngine() {
133
349
  emitter.emit(
134
350
  _makeEngineEmitter.EngineEvent.WALLET_BALANCE_CHANGED,
@@ -166,8 +382,8 @@ var _utils = require('./utils');
166
382
  async broadcastTx(transaction) {
167
383
  const { otherParams } = transaction
168
384
  if (
169
- _optionalChain([otherParams, 'optionalAccess', _ => _.paymentProtocolInfo, 'optionalAccess', _2 => _2.payment]) != null &&
170
- _optionalChain([otherParams, 'optionalAccess', _3 => _3.paymentProtocolInfo, 'optionalAccess', _4 => _4.paymentUrl]) != null
385
+ _optionalChain([otherParams, 'optionalAccess', _3 => _3.paymentProtocolInfo, 'optionalAccess', _4 => _4.payment]) != null &&
386
+ _optionalChain([otherParams, 'optionalAccess', _5 => _5.paymentProtocolInfo, 'optionalAccess', _6 => _6.paymentUrl]) != null
171
387
  ) {
172
388
  const paymentAck = await _paymentRequest.sendPayment.call(void 0,
173
389
  io.fetch,
@@ -193,7 +409,7 @@ var _utils = require('./utils');
193
409
  },
194
410
 
195
411
  async changeUserSettings(userSettings) {
196
- await pluginState.updateServers(_types5.asUtxoUserSettings.call(void 0, userSettings))
412
+ await pluginState.updateServers(_types7.asUtxoUserSettings.call(void 0, userSettings))
197
413
  },
198
414
 
199
415
  async disableTokens(_tokens) {
@@ -236,10 +452,6 @@ var _utils = require('./utils');
236
452
  .join('\n')
237
453
  },
238
454
 
239
- async getEnabledTokens() {
240
- return await Promise.resolve([])
241
- },
242
-
243
455
  async getFreshAddress(
244
456
  opts
245
457
  ) {
@@ -261,10 +473,6 @@ var _utils = require('./utils');
261
473
  )
262
474
  },
263
475
 
264
- getTokenStatus(_token) {
265
- return false
266
- },
267
-
268
476
  async getTransactions(
269
477
  options
270
478
  ) {
@@ -295,17 +503,22 @@ var _utils = require('./utils');
295
503
  async makeSpend(edgeSpendInfo) {
296
504
  edgeSpendInfo = _upgradeMemos.upgradeMemos.call(void 0, edgeSpendInfo, currencyInfo)
297
505
  const { memos = [], spendTargets } = edgeSpendInfo
298
- const txOptions =
299
- _optionalChain([edgeSpendInfo, 'access', _5 => _5.otherParams, 'optionalAccess', _6 => _6.txOptions])
300
- const { outputSort = 'bip69', utxoSourceAddress, forceChangeAddress } =
506
+ const spendInfoOtherParams = _types7.asUtxoSpendInfoOtherParams.call(void 0,
301
507
  _nullishCoalesce(edgeSpendInfo.otherParams, () => ( {}))
508
+ )
509
+ const txOptions = _nullishCoalesce(spendInfoOtherParams.txOptions, () => ( {}))
510
+ const {
511
+ outputSort,
512
+ utxoSourceAddress,
513
+ forceChangeAddress
514
+ } = spendInfoOtherParams
302
515
 
303
516
  let utxoScriptPubkey
304
517
  if (utxoSourceAddress != null) {
305
518
  utxoScriptPubkey = walletTools.addressToScriptPubkey(utxoSourceAddress)
306
519
  }
307
520
 
308
- if (_optionalChain([txOptions, 'optionalAccess', _7 => _7.CPFP]) == null && spendTargets.length < 1) {
521
+ if (txOptions.CPFP == null && spendTargets.length < 1) {
309
522
  throw new Error('Need to provide Spend Targets')
310
523
  }
311
524
  // Calculate the total amount to send
@@ -314,7 +527,7 @@ var _utils = require('./utils');
314
527
  '0'
315
528
  )
316
529
  const utxos =
317
- await _asyncNullishCoalesce(await _asyncOptionalChain([txOptions, 'optionalAccess', async _8 => _8.utxos]), async () => (
530
+ await _asyncNullishCoalesce(txOptions.utxos, async () => (
318
531
  _filterUndefined.filterUndefined.call(void 0,
319
532
  (await processor.fetchUtxos({
320
533
  scriptPubkey: utxoScriptPubkey,
@@ -323,7 +536,7 @@ var _utils = require('./utils');
323
536
  )))
324
537
 
325
538
  if (
326
- bs.gt(totalAmountToSend, `${_utils.sumUtxos.call(void 0, utxos)}`) ||
539
+ bs.gt(totalAmountToSend, `${_utils3.sumUtxos.call(void 0, utxos)}`) ||
327
540
  utxos.length === 0
328
541
  ) {
329
542
  throw new (0, _edgecorejs.InsufficientFundsError)(currencyInfo.currencyCode)
@@ -337,7 +550,7 @@ var _utils = require('./utils');
337
550
  }
338
551
 
339
552
  // if script exists construct address from script
340
- if (_optionalChain([target, 'access', _9 => _9.otherParams, 'optionalAccess', _10 => _10.script]) != null) {
553
+ if (_optionalChain([target, 'access', _7 => _7.otherParams, 'optionalAccess', _8 => _8.script]) != null) {
341
554
  const { script } = target.otherParams
342
555
  if (script.type === 'replayProtection') {
343
556
  // construct a replay protection p2sh address
@@ -357,7 +570,7 @@ var _utils = require('./utils');
357
570
  const scriptPubkey = walletTools.addressToScriptPubkey(
358
571
  target.publicAddress
359
572
  )
360
- if (processor.fetchAddress(scriptPubkey) != null) {
573
+ if ((await processor.fetchAddress(scriptPubkey)) != null) {
361
574
  ourReceiveAddresses.push(target.publicAddress)
362
575
  }
363
576
  }
@@ -381,31 +594,12 @@ var _utils = require('./utils');
381
594
  freshAddress.segwitAddress)), () => (
382
595
  freshAddress.publicAddress))
383
596
 
384
- const setRBF = _nullishCoalesce(_optionalChain([txOptions, 'optionalAccess', _11 => _11.setRBF]), () => ( false))
385
- const rbfTxid = edgeSpendInfo.rbfTxid
597
+ const feeRate = parseInt(await fees.getRate(edgeSpendInfo))
598
+
386
599
  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) {
600
+ if (txOptions.CPFP != null) {
407
601
  const [childTx] = await processor.fetchTransactions({
408
- txId: _optionalChain([txOptions, 'optionalAccess', _13 => _13.CPFP])
602
+ txId: txOptions.CPFP
409
603
  })
410
604
  if (childTx == null) throw new Error('transaction not found')
411
605
  const utxos = []
@@ -417,9 +611,10 @@ var _utils = require('./utils');
417
611
  // cpfp just sends to change, no target addresses are required
418
612
  targets = []
419
613
  }
614
+
420
615
  log.warn(`spend: Using fee rate ${feeRate} sat/B`)
421
616
  const subtractFee =
422
- _optionalChain([txOptions, 'optionalAccess', _14 => _14.subtractFee]) != null ? txOptions.subtractFee : false
617
+ txOptions.subtractFee != null ? txOptions.subtractFee : false
423
618
  const tx = _keymanager.makeTx.call(void 0, {
424
619
  utxos,
425
620
  forceUseUtxo: maxUtxo != null ? [maxUtxo] : [],
@@ -428,7 +623,10 @@ var _utils = require('./utils');
428
623
  feeRate,
429
624
  coin: coinInfo.name,
430
625
  currencyCode: currencyInfo.currencyCode,
431
- setRBF,
626
+ enableRbf:
627
+ _nullishCoalesce(_nullishCoalesce(spendInfoOtherParams.enableRbf, () => (
628
+ currencyInfo.canReplaceByFee)), () => (
629
+ false)),
432
630
  freshChangeAddress,
433
631
  subtractFee,
434
632
  log,
@@ -507,6 +705,26 @@ var _utils = require('./utils');
507
705
  },
508
706
 
509
707
  async saveTx(edgeTx) {
708
+ // If the transaction being saved replaces a transaction, update it.
709
+ const replacedTxid = _optionalChain([edgeTx, 'access', _9 => _9.otherParams, 'optionalAccess', _10 => _10.replacedTxid])
710
+ if (replacedTxid != null) {
711
+ // Get the replaced transaction using the replacedTxid
712
+ const [rbfTx] = await processor.fetchTransactions({
713
+ txId: replacedTxid
714
+ })
715
+ if (rbfTx != null) {
716
+ rbfTx.blockHeight = -1
717
+ await _makeUtxoEngineState.transactionChanged.call(void 0, {
718
+ walletId: walletInfo.id,
719
+ tx: rbfTx,
720
+ pluginInfo,
721
+ emitter,
722
+ walletTools,
723
+ processor
724
+ })
725
+ }
726
+ }
727
+
510
728
  const tx = _ProcessorTransaction.fromEdgeTransaction.call(void 0, edgeTx)
511
729
  await _makeUtxoEngineState.transactionChanged.call(void 0, {
512
730
  walletId: walletInfo.id,
@@ -518,7 +736,7 @@ var _utils = require('./utils');
518
736
  })
519
737
  await processor.saveTransaction({
520
738
  tx,
521
- scriptPubkeys: _optionalChain([edgeTx, 'access', _15 => _15.otherParams, 'optionalAccess', _16 => _16.ourScriptPubkeys])
739
+ scriptPubkeys: _optionalChain([edgeTx, 'access', _11 => _11.otherParams, 'optionalAccess', _12 => _12.ourScriptPubkeys])
522
740
  })
523
741
 
524
742
  /*
@@ -533,11 +751,11 @@ var _utils = require('./utils');
533
751
  privateKeys,
534
752
  opts
535
753
  ) {
536
- const otherParams = _types5.asUtxoSignMessageOtherParams.call(void 0, opts.otherParams)
754
+ const otherParams = _types7.asUtxoSignMessageOtherParams.call(void 0, opts.otherParams)
537
755
  const { publicAddress } = otherParams
538
756
  const scriptPubkey = walletTools.addressToScriptPubkey(publicAddress)
539
757
  const processorAddress = await processor.fetchAddress(scriptPubkey)
540
- if (_optionalChain([processorAddress, 'optionalAccess', _17 => _17.path]) == null) {
758
+ if (_optionalChain([processorAddress, 'optionalAccess', _13 => _13.path]) == null) {
541
759
  throw new Error('Missing address to sign with')
542
760
  }
543
761
  const privateKey = asMaybeCurrencyPrivateKey(privateKeys)
@@ -546,14 +764,14 @@ var _utils = require('./utils');
546
764
  throw new Error('Cannot sign a message for a read-only wallet')
547
765
 
548
766
  // Derive the xprivs on the fly, since we do not persist them
549
- const xprivKeys = await _utils.fetchOrDeriveXprivFromKeys.call(void 0, {
767
+ const xprivKeys = await _utils3.fetchOrDeriveXprivFromKeys.call(void 0, {
550
768
  privateKey,
551
769
  walletLocalEncryptedDisklet,
552
770
  coin: coinInfo.name
553
771
  })
554
772
 
555
773
  const signature = await walletTools.signMessageBase64({
556
- path: _optionalChain([processorAddress, 'optionalAccess', _18 => _18.path]),
774
+ path: _optionalChain([processorAddress, 'optionalAccess', _14 => _14.path]),
557
775
  message,
558
776
  xprivKeys
559
777
  })
@@ -568,8 +786,7 @@ var _utils = require('./utils');
568
786
  if (otherParams == null) throw new Error('Invalid transaction data')
569
787
 
570
788
  const { psbt, edgeSpendInfo } = otherParams
571
- if (psbt == null || edgeSpendInfo == null)
572
- throw new Error('Invalid transaction data')
789
+ if (psbt == null) throw new Error('Invalid transaction data')
573
790
 
574
791
  const privateKey = asMaybeCurrencyPrivateKey(privateKeys)
575
792
 
@@ -577,7 +794,7 @@ var _utils = require('./utils');
577
794
  throw new Error('Cannot sign a transaction for a read-only wallet')
578
795
 
579
796
  // Derive the xprivs on the fly, since we do not persist them
580
- const xprivKeys = await _utils.fetchOrDeriveXprivFromKeys.call(void 0, {
797
+ const xprivKeys = await _utils3.fetchOrDeriveXprivFromKeys.call(void 0, {
581
798
  privateKey,
582
799
  walletLocalEncryptedDisklet,
583
800
  coin: coinInfo.name
@@ -588,24 +805,34 @@ var _utils = require('./utils');
588
805
  const privateKeyEncodings = await (async (
589
806
 
590
807
  ) => {
591
- if (edgeSpendInfo.privateKeys != null) {
808
+ if (_optionalChain([edgeSpendInfo, 'optionalAccess', _15 => _15.privateKeys]) != null) {
592
809
  return edgeSpendInfo.privateKeys.map(wif =>
593
810
  walletTools.getPrivateKeyEncodingFromWif(wif)
594
811
  )
595
812
  } else {
596
813
  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}`
814
+ psbt.inputs.map(async ({ hash, index: vout }) => {
815
+ const txId = Buffer.from(hash).reverse().toString('hex')
600
816
 
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)
817
+ const [transaction] = await processor.fetchTransactions({ txId })
818
+ if (transaction == null)
819
+ throw new Error(
820
+ 'Unable to find previous transaction data for input'
821
+ )
822
+ const prevout = transaction.outputs.find(
823
+ input => input.n === vout
824
+ )
825
+ if (prevout == null)
826
+ throw new Error('Unable to find prevout in transaction')
827
+ const { scriptPubkey } = prevout
828
+
829
+ // Use the scriptPubkey to find the private key from the address
830
+ // derivation path
831
+ const address = await processor.fetchAddress(scriptPubkey)
607
832
  if (address == null) {
608
- throw new Error(`Address for UTXO ${utxoId} not found`)
833
+ throw new Error(
834
+ `Address for scriptPubkey '${scriptPubkey}' not found`
835
+ )
609
836
  }
610
837
  if (address.path == null)
611
838
  throw new Error(
@@ -634,7 +861,7 @@ var _utils = require('./utils');
634
861
  transaction.signedTx = signedTx.hex
635
862
 
636
863
  const { paymentProtocolInfo } =
637
- _nullishCoalesce(_optionalChain([transaction, 'access', _19 => _19.otherParams, 'optionalAccess', _20 => _20.edgeSpendInfo, 'optionalAccess', _21 => _21.otherParams]), () => ( {}))
864
+ _nullishCoalesce(_optionalChain([transaction, 'access', _16 => _16.otherParams, 'optionalAccess', _17 => _17.edgeSpendInfo, 'optionalAccess', _18 => _18.otherParams]), () => ( {}))
638
865
  if (paymentProtocolInfo != null) {
639
866
  const payment = _paymentRequest.createPayment.call(void 0,
640
867
  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
@@ -27,7 +27,7 @@ var _commonInfo = require('./commonInfo');
27
27
  ],
28
28
  enableCustomServers: false
29
29
  },
30
- canReplaceByFee: true,
30
+ canReplaceByFee: false,
31
31
  customFeeTemplate: [
32
32
  {
33
33
  type: 'nativeAmount',
@@ -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.1",
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",