edge-currency-plugins 1.1.0 → 1.1.3
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.
- package/lib/common/plugin/makeCurrencyTools.js +5 -0
- package/lib/common/plugin/pluginState.js +13 -16
- package/lib/common/utxobased/engine/makeServerStates.js +1 -1
- package/lib/common/utxobased/engine/makeUtxoEngine.js +29 -13
- package/lib/common/utxobased/engine/makeUtxoEngineState.js +80 -32
- package/lib/common/utxobased/engine/util/getOwnUtxosFromTx.js +26 -3
- package/lib/common/utxobased/engine/utils.js +17 -1
- package/lib/common/utxobased/info/feathercoin.js +1 -1
- package/lib/common/utxobased/keymanager/keymanager.js +34 -11
- package/lib/src/common/utxobased/engine/makeUtxoEngineState.d.ts +1 -1
- package/lib/src/common/utxobased/engine/types.d.ts +1 -3
- package/lib/src/common/utxobased/engine/utils.d.ts +2 -1
- package/lib/src/common/utxobased/keymanager/keymanager.d.ts +5 -3
- package/package.json +2 -1
|
@@ -9,6 +9,7 @@ var _cleaners = require('cleaners');
|
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
|
|
12
|
+
|
|
12
13
|
var _urijs = require('uri-js'); var uri = _interopRequireWildcard(_urijs);
|
|
13
14
|
var _urlparse = require('url-parse'); var _urlparse2 = _interopRequireDefault(_urlparse);
|
|
14
15
|
|
|
@@ -80,6 +81,10 @@ var _utils3 = require('./utils');
|
|
|
80
81
|
return wasCurrencyPrivateKey(privateKey)
|
|
81
82
|
},
|
|
82
83
|
|
|
84
|
+
async validateMemo(memo) {
|
|
85
|
+
return _utils.validateMemo.call(void 0, memo)
|
|
86
|
+
},
|
|
87
|
+
|
|
83
88
|
async derivePublicKey(walletInfo) {
|
|
84
89
|
const numbWalletInfo = asCurrencyNumbWalletInfo(walletInfo)
|
|
85
90
|
return numbWalletInfo.keys.publicKey
|
|
@@ -116,24 +116,21 @@ const asServerListInfo = _cleaners.asObject.call(void 0, _cleaners.asEither.call
|
|
|
116
116
|
const fetchServers = async () => {
|
|
117
117
|
log(`${pluginId} - GET ${serverListInfoUrl}`)
|
|
118
118
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
return await response.json()
|
|
124
|
-
}
|
|
125
|
-
log(
|
|
126
|
-
`${pluginId} - Fetching ${serverListInfoUrl} failed with status ${response.status}`
|
|
127
|
-
)
|
|
128
|
-
} catch (err) {
|
|
129
|
-
log(`${pluginId} - Fetching ${serverListInfoUrl} failed: ${err}`)
|
|
119
|
+
try {
|
|
120
|
+
const response = await io.fetch(serverListInfoUrl)
|
|
121
|
+
if (!response.ok) {
|
|
122
|
+
throw new Error(`Failed with status ${response.status}`)
|
|
130
123
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
const serverListInfo = asServerListInfo(responseBody)
|
|
124
|
+
const responseBody = await response.json()
|
|
125
|
+
const serverListInfo = asServerListInfo(responseBody)
|
|
135
126
|
|
|
136
|
-
|
|
127
|
+
return _nullishCoalesce(serverListInfo[currencyCode], () => ( []))
|
|
128
|
+
} catch (error) {
|
|
129
|
+
log.warn(
|
|
130
|
+
`${pluginId} - GET ${serverListInfoUrl} failed: ${error.toString()}`
|
|
131
|
+
)
|
|
132
|
+
return []
|
|
133
|
+
}
|
|
137
134
|
}
|
|
138
135
|
|
|
139
136
|
const refreshServers = async () => {
|
|
@@ -371,7 +371,7 @@ var _constants = require('./constants');
|
|
|
371
371
|
pluginState.serverScoreDown(uri)
|
|
372
372
|
_optionalChain([deferredAddressSub, 'optionalAccess', _3 => _3.reject, 'call', _4 => _4()])
|
|
373
373
|
})
|
|
374
|
-
blockbook.watchAddresses(Array.from(addresses), deferred)
|
|
374
|
+
blockbook.watchAddresses(Array.from(serverState.addresses), deferred)
|
|
375
375
|
}
|
|
376
376
|
|
|
377
377
|
const watchBlocks = (uri) => {
|
|
@@ -66,7 +66,9 @@ var _utils = require('./utils');
|
|
|
66
66
|
// each with a different list of custom servers.
|
|
67
67
|
// The Edge UI only allows for one active login, though,
|
|
68
68
|
// so this is OK for now:
|
|
69
|
-
|
|
69
|
+
pluginState.updateServers(userSettings).catch(err => {
|
|
70
|
+
log.error(err)
|
|
71
|
+
})
|
|
70
72
|
|
|
71
73
|
const asCurrencyPrivateKey = _cleaners3.asPrivateKey.call(void 0, coinInfo.name, coinInfo.coinType)
|
|
72
74
|
// Private key may be missing for watch-only wallets
|
|
@@ -295,7 +297,10 @@ var _utils = require('./utils');
|
|
|
295
297
|
let targets = []
|
|
296
298
|
const ourReceiveAddresses = []
|
|
297
299
|
for (const target of spendTargets) {
|
|
298
|
-
if (
|
|
300
|
+
if (
|
|
301
|
+
target.memo == null &&
|
|
302
|
+
(target.publicAddress == null || target.nativeAmount == null)
|
|
303
|
+
) {
|
|
299
304
|
throw new Error('Invalid spend target')
|
|
300
305
|
}
|
|
301
306
|
|
|
@@ -309,19 +314,29 @@ var _utils = require('./utils');
|
|
|
309
314
|
)
|
|
310
315
|
targets.push({
|
|
311
316
|
address: publicAddress,
|
|
312
|
-
value:
|
|
317
|
+
value:
|
|
318
|
+
target.nativeAmount == null
|
|
319
|
+
? undefined
|
|
320
|
+
: parseInt(target.nativeAmount),
|
|
321
|
+
memo: target.memo
|
|
313
322
|
})
|
|
314
323
|
}
|
|
315
324
|
} else {
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
325
|
+
if (target.publicAddress != null) {
|
|
326
|
+
const scriptPubkey = walletTools.addressToScriptPubkey(
|
|
327
|
+
target.publicAddress
|
|
328
|
+
)
|
|
329
|
+
if (processor.fetchAddress(scriptPubkey) != null) {
|
|
330
|
+
ourReceiveAddresses.push(target.publicAddress)
|
|
331
|
+
}
|
|
321
332
|
}
|
|
322
333
|
targets.push({
|
|
323
334
|
address: target.publicAddress,
|
|
324
|
-
value:
|
|
335
|
+
value:
|
|
336
|
+
target.nativeAmount == null
|
|
337
|
+
? undefined
|
|
338
|
+
: parseInt(target.nativeAmount),
|
|
339
|
+
memo: target.memo
|
|
325
340
|
})
|
|
326
341
|
}
|
|
327
342
|
}
|
|
@@ -372,12 +387,13 @@ var _utils = require('./utils');
|
|
|
372
387
|
log.warn(`spend: Using fee rate ${feeRate} sat/B`)
|
|
373
388
|
const subtractFee =
|
|
374
389
|
_optionalChain([options, 'optionalAccess', _12 => _12.subtractFee]) != null ? options.subtractFee : false
|
|
375
|
-
const tx =
|
|
390
|
+
const tx = _keymanager.makeTx.call(void 0, {
|
|
376
391
|
utxos,
|
|
377
392
|
forceUseUtxo: maxUtxo != null ? [maxUtxo] : [],
|
|
378
393
|
targets,
|
|
379
394
|
feeRate,
|
|
380
395
|
coin: coinInfo.name,
|
|
396
|
+
currencyCode: currencyInfo.currencyCode,
|
|
381
397
|
setRBF,
|
|
382
398
|
freshChangeAddress,
|
|
383
399
|
subtractFee
|
|
@@ -406,7 +422,7 @@ var _utils = require('./utils');
|
|
|
406
422
|
nativeAmount = bs.sub(nativeAmount, networkFee)
|
|
407
423
|
|
|
408
424
|
const otherParams = {
|
|
409
|
-
|
|
425
|
+
unsignedTx: tx.hex,
|
|
410
426
|
psbt: {
|
|
411
427
|
base64: tx.psbtBase64,
|
|
412
428
|
inputs: tx.inputs,
|
|
@@ -468,8 +484,8 @@ var _utils = require('./utils');
|
|
|
468
484
|
/*
|
|
469
485
|
Get the wallet's UTXOs from the new transaction and save them to the processsor.
|
|
470
486
|
*/
|
|
471
|
-
const
|
|
472
|
-
await engineState.processUtxos(
|
|
487
|
+
const ownUtxos = await _getOwnUtxosFromTx.getOwnUtxosFromTx.call(void 0, engineInfo, processor, tx)
|
|
488
|
+
await engineState.processUtxos(ownUtxos)
|
|
473
489
|
},
|
|
474
490
|
|
|
475
491
|
async signTx(transaction) {
|
|
@@ -40,7 +40,6 @@ var _keymanager = require('../keymanager/keymanager');
|
|
|
40
40
|
|
|
41
41
|
|
|
42
42
|
|
|
43
|
-
|
|
44
43
|
var _BlockBookAPI = require('../network/BlockBookAPI');
|
|
45
44
|
var _Deferred = require('../network/Deferred'); var _Deferred2 = _interopRequireDefault(_Deferred);
|
|
46
45
|
|
|
@@ -386,22 +385,6 @@ var _utils3 = require('./utils');
|
|
|
386
385
|
async broadcastTx(transaction) {
|
|
387
386
|
const txId = await serverStates.broadcastTx(transaction)
|
|
388
387
|
|
|
389
|
-
/*
|
|
390
|
-
After successfully broadcasting the tx, we must mark each UTXO, used as
|
|
391
|
-
an input for the tx, as spent so we don't try to reuse the UTXO.
|
|
392
|
-
*/
|
|
393
|
-
const txInputs = _nullishCoalesce(_optionalChain([transaction, 'access', _ => _.otherParams, 'optionalAccess', _2 => _2.psbt, 'access', _3 => _3.inputs]), () => ( []))
|
|
394
|
-
for (const input of txInputs) {
|
|
395
|
-
const scriptPubkey = Buffer.from(input.scriptPubkey).toString('hex')
|
|
396
|
-
const [utxo] = await processor.fetchUtxos({
|
|
397
|
-
scriptPubkey
|
|
398
|
-
})
|
|
399
|
-
if (utxo != null) {
|
|
400
|
-
utxo.spent = true
|
|
401
|
-
await processor.saveUtxo(utxo)
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
|
|
405
388
|
return txId
|
|
406
389
|
},
|
|
407
390
|
refillServers() {
|
|
@@ -447,18 +430,37 @@ var _utils3 = require('./utils');
|
|
|
447
430
|
}
|
|
448
431
|
},
|
|
449
432
|
async processUtxos(utxos) {
|
|
433
|
+
// Map of scriptPubkey to IUTXOs
|
|
450
434
|
const utxoMap = new Map()
|
|
435
|
+
const utxoIds = new Set()
|
|
436
|
+
|
|
437
|
+
// Map updated utxos
|
|
451
438
|
for (const utxo of utxos) {
|
|
452
|
-
const utxoSet = _nullishCoalesce(utxoMap.get(utxo.scriptPubkey), () => (
|
|
439
|
+
const utxoSet = _nullishCoalesce(utxoMap.get(utxo.scriptPubkey), () => ( []))
|
|
453
440
|
if (!utxoMap.has(utxo.scriptPubkey))
|
|
454
441
|
utxoMap.set(utxo.scriptPubkey, utxoSet)
|
|
455
|
-
|
|
442
|
+
// Add utxo to set for scriptPubkey
|
|
443
|
+
utxoSet.push(utxo)
|
|
444
|
+
// Add UTXO ID set
|
|
445
|
+
utxoIds.add(utxo.id)
|
|
456
446
|
}
|
|
447
|
+
|
|
448
|
+
// Process UTXO sets for each scriptPubkey in map
|
|
457
449
|
for (const [scriptPubkey, utxos] of utxoMap.entries()) {
|
|
450
|
+
// Get saved utxo set
|
|
451
|
+
const savedUtxos = await processor.fetchUtxos({ scriptPubkey })
|
|
452
|
+
// Filter UTXOs to de-duplicate (and undefined utxo as a type assert)
|
|
453
|
+
const filteredUtxos = savedUtxos.filter(
|
|
454
|
+
utxo => utxo != null && !utxoIds.has(_optionalChain([utxo, 'optionalAccess', _ => _.id]))
|
|
455
|
+
)
|
|
456
|
+
|
|
457
|
+
// Add updated utxos to utxo set
|
|
458
|
+
const combinedUtxos = [...filteredUtxos, ...utxos]
|
|
459
|
+
|
|
458
460
|
await processProcessorUtxos({
|
|
459
461
|
...commonArgs,
|
|
460
462
|
scriptPubkey,
|
|
461
|
-
utxos
|
|
463
|
+
utxos: combinedUtxos
|
|
462
464
|
})
|
|
463
465
|
}
|
|
464
466
|
}
|
|
@@ -1221,25 +1223,71 @@ const processProcessorUtxos = async (
|
|
|
1221
1223
|
pluginInfo: { currencyInfo }
|
|
1222
1224
|
} = args
|
|
1223
1225
|
|
|
1226
|
+
const updatedUtxos = Object.fromEntries(
|
|
1227
|
+
[...utxos].map(utxo => [utxo.id, utxo])
|
|
1228
|
+
)
|
|
1229
|
+
const utxoIdsToRemove = []
|
|
1224
1230
|
const currentUtxos = await processor.fetchUtxos({ scriptPubkey })
|
|
1225
|
-
|
|
1231
|
+
|
|
1232
|
+
//
|
|
1233
|
+
// Modify existing UTXO set
|
|
1234
|
+
//
|
|
1235
|
+
|
|
1226
1236
|
let oldBalance = '0'
|
|
1227
1237
|
for (const utxo of currentUtxos) {
|
|
1228
1238
|
if (utxo == null)
|
|
1229
1239
|
throw new Error(
|
|
1230
1240
|
'Unexpected undefined utxo when processing unspent transactions'
|
|
1231
1241
|
)
|
|
1232
|
-
|
|
1233
|
-
|
|
1242
|
+
if (!utxo.spent) {
|
|
1243
|
+
// Accumulate over the current address balance
|
|
1244
|
+
oldBalance = _biggystring.add.call(void 0, utxo.value, oldBalance)
|
|
1245
|
+
}
|
|
1246
|
+
|
|
1247
|
+
// If the UTXO isn't present in the update UTXO set, then it is spent.
|
|
1248
|
+
if (updatedUtxos[utxo.id] == null) {
|
|
1249
|
+
if (utxo.blockHeight > 0) {
|
|
1250
|
+
// Delete the UTXO from the database if it's spent and confirmed
|
|
1251
|
+
utxoIdsToRemove.push(utxo.id)
|
|
1252
|
+
} else {
|
|
1253
|
+
// Otherwise just mark it as spent.
|
|
1254
|
+
updatedUtxos[utxo.id] = { ...utxo, spent: true }
|
|
1255
|
+
}
|
|
1256
|
+
} else {
|
|
1257
|
+
/*
|
|
1258
|
+
If the UTXO is present in the updated UTXO set, enforce that the UTXO
|
|
1259
|
+
remains spent in the new UTXO set. This means, we will never mark a UTXO
|
|
1260
|
+
as unspent again. UTXOs only become unspent again if the tx is dropped
|
|
1261
|
+
which shall be affected by another routine.
|
|
1262
|
+
*/
|
|
1263
|
+
// TODO: To fix this logic for dropped-tx, add a condition which uses the
|
|
1264
|
+
// network's block-height to determine whether to set it back as unspend
|
|
1265
|
+
updatedUtxos[utxo.id].spent = utxo.spent || updatedUtxos[utxo.id].spent
|
|
1266
|
+
}
|
|
1234
1267
|
}
|
|
1235
|
-
|
|
1268
|
+
|
|
1269
|
+
// Remove any spent UTXOs that have confirmations
|
|
1270
|
+
await processor.removeUtxos(utxoIdsToRemove)
|
|
1271
|
+
|
|
1272
|
+
//
|
|
1273
|
+
// Save updated UTXO set
|
|
1274
|
+
//
|
|
1236
1275
|
|
|
1237
1276
|
let newBalance = '0'
|
|
1238
|
-
for (const utxo of
|
|
1239
|
-
|
|
1277
|
+
for (const utxo of Object.values(updatedUtxos)) {
|
|
1278
|
+
if (!utxo.spent) {
|
|
1279
|
+
// Accumulate over the new address balance
|
|
1280
|
+
newBalance = _biggystring.add.call(void 0, utxo.value, newBalance)
|
|
1281
|
+
}
|
|
1282
|
+
// Save new UTXOs
|
|
1240
1283
|
await processor.saveUtxo(utxo)
|
|
1241
1284
|
}
|
|
1242
1285
|
|
|
1286
|
+
//
|
|
1287
|
+
// Balance update
|
|
1288
|
+
//
|
|
1289
|
+
|
|
1290
|
+
// Address balance and emit address balance change event
|
|
1243
1291
|
const diff = _biggystring.sub.call(void 0, newBalance, oldBalance)
|
|
1244
1292
|
if (diff !== '0') {
|
|
1245
1293
|
log('balance changed:', { scriptPubkey, diff })
|
|
@@ -1392,19 +1440,19 @@ const processRawUtxo = async (
|
|
|
1392
1440
|
}
|
|
1393
1441
|
|
|
1394
1442
|
const addToProcessorUtxoCache = (
|
|
1395
|
-
|
|
1443
|
+
processorUtxoCache,
|
|
1396
1444
|
path,
|
|
1397
1445
|
scriptPubkey,
|
|
1398
1446
|
requiredCount,
|
|
1399
1447
|
utxo
|
|
1400
1448
|
) => {
|
|
1401
|
-
const processorUtxos = _nullishCoalesce(
|
|
1402
|
-
utxos:
|
|
1449
|
+
const processorUtxos = _nullishCoalesce(processorUtxoCache[scriptPubkey], () => ( {
|
|
1450
|
+
utxos: [],
|
|
1403
1451
|
processing: false,
|
|
1404
1452
|
path,
|
|
1405
1453
|
full: false
|
|
1406
1454
|
}))
|
|
1407
|
-
if (utxo != null) processorUtxos.utxos.
|
|
1408
|
-
|
|
1409
|
-
processorUtxos.full = processorUtxos.utxos.
|
|
1455
|
+
if (utxo != null) processorUtxos.utxos.push(utxo)
|
|
1456
|
+
processorUtxoCache[scriptPubkey] = processorUtxos
|
|
1457
|
+
processorUtxos.full = processorUtxos.utxos.length >= requiredCount
|
|
1410
1458
|
}
|
|
@@ -12,7 +12,29 @@ var _utils = require('../utils');
|
|
|
12
12
|
processor,
|
|
13
13
|
tx
|
|
14
14
|
) => {
|
|
15
|
-
const
|
|
15
|
+
const ownUtxos = []
|
|
16
|
+
|
|
17
|
+
//
|
|
18
|
+
// Spent UTXOs (Inputs)
|
|
19
|
+
//
|
|
20
|
+
|
|
21
|
+
const inputUtxoIds = tx.inputs.map(
|
|
22
|
+
input => `${input.txId}_${input.outputIndex}`
|
|
23
|
+
)
|
|
24
|
+
const inputUtxos = await processor.fetchUtxos({
|
|
25
|
+
utxoIds: inputUtxoIds
|
|
26
|
+
})
|
|
27
|
+
for (const utxo of inputUtxos) {
|
|
28
|
+
if (utxo == null) continue
|
|
29
|
+
// Must create a new IUTXO object when mutating processor objects because
|
|
30
|
+
// memlet may keep a reference in memory.
|
|
31
|
+
ownUtxos.push({ ...utxo, spent: true })
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
//
|
|
35
|
+
// Unspent UTXOs (Outputs)
|
|
36
|
+
//
|
|
37
|
+
|
|
16
38
|
for (const output of tx.outputs) {
|
|
17
39
|
const scriptPubkey = output.scriptPubkey
|
|
18
40
|
const address = await processor.fetchAddress(scriptPubkey)
|
|
@@ -46,9 +68,10 @@ var _utils = require('../utils');
|
|
|
46
68
|
blockHeight: tx.blockHeight,
|
|
47
69
|
spent: false
|
|
48
70
|
}
|
|
49
|
-
|
|
71
|
+
ownUtxos.push(utxo)
|
|
50
72
|
}
|
|
51
73
|
}
|
|
52
74
|
}
|
|
53
|
-
|
|
75
|
+
|
|
76
|
+
return ownUtxos
|
|
54
77
|
}; exports.getOwnUtxosFromTx = getOwnUtxosFromTx
|
|
@@ -35,6 +35,19 @@ var _keymanager = require('../keymanager/keymanager');
|
|
|
35
35
|
}
|
|
36
36
|
}; exports.getCurrencyFormatFromPurposeType = getCurrencyFormatFromPurposeType
|
|
37
37
|
|
|
38
|
+
// Expect memo to be a hex string
|
|
39
|
+
const validateMemo = (memo) => {
|
|
40
|
+
const result = {
|
|
41
|
+
passed: true,
|
|
42
|
+
tooLarge: false
|
|
43
|
+
}
|
|
44
|
+
if (Math.ceil(memo.length / 2) > 80) {
|
|
45
|
+
result.passed = false
|
|
46
|
+
result.tooLarge = true
|
|
47
|
+
}
|
|
48
|
+
return result
|
|
49
|
+
}; exports.validateMemo = validateMemo
|
|
50
|
+
|
|
38
51
|
const getAddressTypeFromKeys = (
|
|
39
52
|
privateKey
|
|
40
53
|
) => {
|
|
@@ -236,4 +249,7 @@ var _keymanager = require('../keymanager/keymanager');
|
|
|
236
249
|
}; exports.parsePathname = parsePathname
|
|
237
250
|
|
|
238
251
|
const sumUtxos = (utxos) =>
|
|
239
|
-
utxos.reduce(
|
|
252
|
+
utxos.reduce(
|
|
253
|
+
(sum, { spent, value }) => (spent ? sum : bs.add(sum, value)),
|
|
254
|
+
'0'
|
|
255
|
+
); exports.sumUtxos = sumUtxos
|
|
@@ -16,7 +16,7 @@ var _constants = require('../../constants');
|
|
|
16
16
|
// Configuration options:
|
|
17
17
|
defaultSettings: {
|
|
18
18
|
customFeeSettings: ['satPerByte'],
|
|
19
|
-
blockbookServers: [],
|
|
19
|
+
blockbookServers: ['wss://blockbook.feathercoin.com'],
|
|
20
20
|
enableCustomServers: false
|
|
21
21
|
},
|
|
22
22
|
customFeeTemplate: [
|
|
@@ -10,6 +10,7 @@ var _indexAtProtected = require('../../../util/indexAtProtected');
|
|
|
10
10
|
var _undefinedIfEmptyString = require('../../../util/undefinedIfEmptyString');
|
|
11
11
|
|
|
12
12
|
|
|
13
|
+
var _utils = require('../engine/utils');
|
|
13
14
|
|
|
14
15
|
var _bip69 = require('./bip69');
|
|
15
16
|
|
|
@@ -228,6 +229,8 @@ var VerifyAddressEnum; (function (VerifyAddressEnum) {
|
|
|
228
229
|
|
|
229
230
|
|
|
230
231
|
|
|
232
|
+
|
|
233
|
+
|
|
231
234
|
|
|
232
235
|
|
|
233
236
|
|
|
@@ -824,7 +827,7 @@ const wifToPrivateKeyInternal = (
|
|
|
824
827
|
.toString('base64')
|
|
825
828
|
} exports.signMessageBase64 = signMessageBase64;
|
|
826
829
|
|
|
827
|
-
|
|
830
|
+
function makeTx(args) {
|
|
828
831
|
let sequence = 0xffffffff
|
|
829
832
|
if (args.setRBF) {
|
|
830
833
|
sequence -= 2
|
|
@@ -902,16 +905,36 @@ const wifToPrivateKeyInternal = (
|
|
|
902
905
|
if (!forceUsage) mappedUtxos.push(input)
|
|
903
906
|
}
|
|
904
907
|
|
|
905
|
-
const targets =
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
908
|
+
const targets = []
|
|
909
|
+
for (const target of args.targets) {
|
|
910
|
+
if (target.address != null && target.value != null) {
|
|
911
|
+
const script = exports.addressToScriptPubkey.call(void 0, {
|
|
912
|
+
address: target.address,
|
|
913
|
+
coin: coin.name
|
|
914
|
+
})
|
|
915
|
+
targets.push({
|
|
916
|
+
script,
|
|
917
|
+
value: target.value
|
|
918
|
+
})
|
|
913
919
|
}
|
|
914
|
-
|
|
920
|
+
|
|
921
|
+
if (target.memo != null) {
|
|
922
|
+
const memoHex = Buffer.from(target.memo, 'utf8').toString('hex')
|
|
923
|
+
// check if hex string is within 80 bytes
|
|
924
|
+
const validatedMemo = _utils.validateMemo.call(void 0, memoHex)
|
|
925
|
+
if (!validatedMemo.passed) {
|
|
926
|
+
throw new Error('Memo size exceeds 80 bytes')
|
|
927
|
+
}
|
|
928
|
+
const script = bitcoin.script
|
|
929
|
+
.compile([bitcoin.opcodes.OP_RETURN, Buffer.from(target.memo, 'utf8')])
|
|
930
|
+
.toString('hex')
|
|
931
|
+
targets.push({
|
|
932
|
+
script,
|
|
933
|
+
value: 0
|
|
934
|
+
})
|
|
935
|
+
}
|
|
936
|
+
}
|
|
937
|
+
|
|
915
938
|
const changeScript = exports.addressToScriptPubkey.call(void 0, {
|
|
916
939
|
address: args.freshChangeAddress,
|
|
917
940
|
coin: coin.name
|
|
@@ -933,7 +956,7 @@ const wifToPrivateKeyInternal = (
|
|
|
933
956
|
changeScript
|
|
934
957
|
})
|
|
935
958
|
if (result.inputs == null || result.outputs == null) {
|
|
936
|
-
throw new (0, _types.InsufficientFundsError)(args.
|
|
959
|
+
throw new (0, _types.InsufficientFundsError)(args.currencyCode)
|
|
937
960
|
}
|
|
938
961
|
|
|
939
962
|
const sortedInputs = _bip69.sortInputs.call(void 0, result.inputs)
|
|
@@ -6,9 +6,7 @@ export declare const asUtxoUserSettings: import("cleaners").ObjectCleaner<{
|
|
|
6
6
|
}>;
|
|
7
7
|
export declare type UtxoUserSettings = ReturnType<typeof asUtxoUserSettings>;
|
|
8
8
|
export interface UtxoTxOtherParams {
|
|
9
|
-
|
|
10
|
-
hex?: string;
|
|
11
|
-
};
|
|
9
|
+
unsignedTx: string;
|
|
12
10
|
psbt?: {
|
|
13
11
|
base64: string;
|
|
14
12
|
inputs: Input[];
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { Disklet } from 'disklet';
|
|
2
|
-
import { EdgeParsedUri } from 'edge-core-js/types';
|
|
2
|
+
import { EdgeMemoRules, EdgeParsedUri } from 'edge-core-js/types';
|
|
3
3
|
import { CurrencyFormat } from '../../plugin/types';
|
|
4
4
|
import { IUTXO } from '../db/types';
|
|
5
5
|
import { ScriptTemplates } from '../info/scriptTemplates/types';
|
|
6
6
|
import { PrivateKey } from '../keymanager/cleaners';
|
|
7
7
|
import { AddressTypeEnum, BIP43PurposeTypeEnum, ScriptTypeEnum } from '../keymanager/keymanager';
|
|
8
8
|
export declare const getCurrencyFormatFromPurposeType: (purpose: BIP43PurposeTypeEnum) => CurrencyFormat;
|
|
9
|
+
export declare const validateMemo: (memo: string) => EdgeMemoRules;
|
|
9
10
|
export declare const getAddressTypeFromKeys: (privateKey: PrivateKey) => AddressTypeEnum;
|
|
10
11
|
export declare const getAddressTypeFromPurposeType: (purpose: BIP43PurposeTypeEnum) => AddressTypeEnum;
|
|
11
12
|
export declare const getScriptTypeFromPurposeType: (purpose: BIP43PurposeTypeEnum, redeemScript?: string | undefined, scriptTemplates?: ScriptTemplates | undefined) => ScriptTypeEnum;
|
|
@@ -128,12 +128,14 @@ export interface MakeTxArgs {
|
|
|
128
128
|
feeRate: number;
|
|
129
129
|
setRBF: boolean;
|
|
130
130
|
coin: string;
|
|
131
|
+
currencyCode: string;
|
|
131
132
|
freshChangeAddress: string;
|
|
132
133
|
subtractFee?: boolean;
|
|
133
134
|
}
|
|
134
135
|
export interface MakeTxTarget {
|
|
135
|
-
address
|
|
136
|
-
value
|
|
136
|
+
address?: string;
|
|
137
|
+
value?: number;
|
|
138
|
+
memo?: string | null;
|
|
137
139
|
}
|
|
138
140
|
interface MakeTxReturn extends Required<utxopicker.UtxoPickerResult> {
|
|
139
141
|
hex: string;
|
|
@@ -193,6 +195,6 @@ export declare function privateKeyToWIF(args: PrivateKeyToWIFArgs): string;
|
|
|
193
195
|
export declare const wifToPrivateKey: (args: WIFToPrivateKeyArgs) => string;
|
|
194
196
|
export declare function privateKeyToPubkey(privateKey: string): string;
|
|
195
197
|
export declare function signMessageBase64(message: string, privateKey: string): string;
|
|
196
|
-
export declare function makeTx(args: MakeTxArgs):
|
|
198
|
+
export declare function makeTx(args: MakeTxArgs): MakeTxReturn;
|
|
197
199
|
export declare function signTx(args: SignTxArgs): Promise<SignTxReturn>;
|
|
198
200
|
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "edge-currency-plugins",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.3",
|
|
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",
|
|
@@ -49,6 +49,7 @@
|
|
|
49
49
|
"cleaners": "^0.3.12",
|
|
50
50
|
"disklet": "^0.4.5",
|
|
51
51
|
"edge-core-js": "^0.19.20",
|
|
52
|
+
"edge-sync-client": "^0.2.7",
|
|
52
53
|
"memlet": "^0.1.6",
|
|
53
54
|
"uri-js": "^4.4.0",
|
|
54
55
|
"url-parse": "^1.5.2",
|