coinselect
Advanced tools
Comparing version 0.3.1 to 1.0.0
27
index.js
// TODO: integrate privacy calculations, group by address, avoid linking multiple addresses together | ||
// XXX: There may be better optimization techniques available here, may, be. | ||
// TODO: integrate priority calculations | ||
// var COIN = 100000000 | ||
// var freeThreshold = COIN * 144 / 250 | ||
// var isFree = inputs.reduce(function (accum, input) { return accum + priority(input) }, 0) > freeThreshold | ||
// | ||
// function priority(unspent) { | ||
// // unlike bitcoind, we assume priority is calculated for _right_ now | ||
// // not the next block | ||
// return unspent.value * unspent.confirmations | ||
// } | ||
// XXX: these are based on pubKeyHash estimates, the information is ignored so pre-calculated placeholders are used to improve performance | ||
// XXX: these are based on pubKeyHash estimates, used to improve performance | ||
var TX_EMPTY_SIZE = 8 | ||
var TX_PUBKEYHASH_INPUT = 40 + 2 + 106 | ||
var TX_PUBKEYHASH_OUTPUT = 8 + 2 + 25 | ||
var TX_INPUT_BASE = 40 + 2 | ||
var TX_INPUT_PUBKEYHASH = 106 | ||
var TX_OUTPUT_BASE = 8 + 1 | ||
var TX_OUTPUT_PUBKEYHASH = 25 | ||
function estimateRelayFee (byteLength, feePerKb) { | ||
return Math.ceil(byteLength / 1000) * feePerKb | ||
return (byteLength / 1000) * feePerKb | ||
} | ||
@@ -33,3 +24,3 @@ | ||
outputs.forEach(function (output) { | ||
byteLength += output.script ? output.script.length : TX_PUBKEYHASH_OUTPUT | ||
byteLength += TX_OUTPUT_BASE + (output.script ? output.script.length : TX_OUTPUT_PUBKEYHASH) | ||
target += output.value | ||
@@ -44,3 +35,3 @@ }) | ||
// TODO: an estimate is used because of missing signature data | ||
byteLength += TX_PUBKEYHASH_INPUT | ||
byteLength += TX_INPUT_BASE + TX_INPUT_PUBKEYHASH | ||
accum += unspent.value | ||
@@ -58,3 +49,3 @@ | ||
var feeWithChange = estimateRelayFee(byteLength + TX_PUBKEYHASH_OUTPUT, feePerKb) | ||
var feeWithChange = estimateRelayFee(byteLength + TX_OUTPUT_BASE + TX_OUTPUT_PUBKEYHASH, feePerKb) | ||
var totalWithChange = target + feeWithChange | ||
@@ -61,0 +52,0 @@ |
{ | ||
"name": "coinselect", | ||
"version": "0.3.1", | ||
"version": "1.0.0", | ||
"description": "A fee optimizing bitcoin input selection module", | ||
@@ -5,0 +5,0 @@ "main": "./index.js", |
@@ -6,6 +6,6 @@ [ | ||
"outputs": [100000], | ||
"unspents": [30000, 110000], | ||
"unspents": [102000], | ||
"expected": { | ||
"fee": 10000, | ||
"inputs": [1], | ||
"fee": 2000, | ||
"inputs": [0], | ||
"remainder": 0 | ||
@@ -17,8 +17,8 @@ } | ||
"feePerKb": 10000, | ||
"outputs": [90000], | ||
"unspents": [30000, 110000], | ||
"outputs": [100000], | ||
"unspents": [106000], | ||
"expected": { | ||
"fee": 10000, | ||
"inputs": [1], | ||
"remainder": 10000 | ||
"fee": 2240, | ||
"inputs": [0], | ||
"remainder": 3760 | ||
} | ||
@@ -30,5 +30,5 @@ }, | ||
"outputs": [60000], | ||
"unspents": [10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000], | ||
"unspents": [10000, 10000, 10000, 10000, 10000, 10000, 10000, 2600], | ||
"expected": { | ||
"fee": 20000, | ||
"fee": 12600, | ||
"inputs": [0, 1, 2, 3, 4, 5, 6, 7], | ||
@@ -41,8 +41,8 @@ "remainder": 0 | ||
"feePerKb": 10000, | ||
"outputs": [55000], | ||
"unspents": [10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000], | ||
"outputs": [60000], | ||
"unspents": [10000, 10000, 10000, 10000, 10000, 10000, 10000, 2601], | ||
"expected": { | ||
"fee": 20000, | ||
"fee": 12600, | ||
"inputs": [0, 1, 2, 3, 4, 5, 6, 7], | ||
"remainder": 5000 | ||
"remainder": 1 | ||
} | ||
@@ -54,5 +54,5 @@ }, | ||
"outputs": [35000, 5000, 5000, 1000], | ||
"unspents": [30000, 16000, 10000], | ||
"unspents": [30000, 12220, 10000], | ||
"expected": { | ||
"fee": 10000, | ||
"fee": 6220, | ||
"inputs": [0, 1, 2], | ||
@@ -65,28 +65,28 @@ "remainder": 0 | ||
"feePerKb": 10000, | ||
"outputs": [35000, 5000, 2000, 1000], | ||
"unspents": [30000, 16000, 10000], | ||
"outputs": [35000, 5000, 5000, 1000], | ||
"unspents": [30000, 12220, 10001], | ||
"expected": { | ||
"fee": 10000, | ||
"fee": 6220, | ||
"inputs": [0, 1, 2], | ||
"remainder": 3000 | ||
"remainder": 1 | ||
} | ||
}, | ||
{ | ||
"description": "multiple outputs, base fee, remainder expected", | ||
"feePerKb": 1000, | ||
"description": "singular output, no fee, remainder expected", | ||
"feePerKb": 0, | ||
"unspents": [5000, 5000, 5000, 5000, 5000, 5000], | ||
"outputs": [28000, 1000], | ||
"outputs": [28000], | ||
"expected": { | ||
"fee": 1000, | ||
"fee": 0, | ||
"inputs": [0, 1, 2, 3, 4, 5], | ||
"remainder": 0 | ||
"remainder": 2000 | ||
} | ||
}, | ||
{ | ||
"description": "multiple outputs, change fee, remainder exists", | ||
"feePerKb": 1000, | ||
"unspents": [7000, 5000, 5000, 5000, 5000, 5000], | ||
"description": "multiple outputs, no fee, remainder expected", | ||
"feePerKb": 0, | ||
"unspents": [5000, 5000, 5000, 5000, 5000, 5000], | ||
"outputs": [28000, 1000], | ||
"expected": { | ||
"fee": 2000, | ||
"fee": 0, | ||
"inputs": [0, 1, 2, 3, 4, 5], | ||
@@ -97,10 +97,21 @@ "remainder": 1000 | ||
{ | ||
"description": "no outputs, no remainder", | ||
"feePerKb": 10000, | ||
"outputs": [], | ||
"unspents": [1900], | ||
"expected": { | ||
"fee": 1900, | ||
"inputs": [0], | ||
"remainder": 0 | ||
} | ||
}, | ||
{ | ||
"description": "no outputs, remainder expected", | ||
"feePerKb": 10000, | ||
"outputs": [], | ||
"unspents": [30000, 16000, 10000], | ||
"unspents": [2000], | ||
"expected": { | ||
"fee": 10000, | ||
"fee": 1900, | ||
"inputs": [0], | ||
"remainder": 20000 | ||
"remainder": 100 | ||
} | ||
@@ -114,3 +125,3 @@ }, | ||
"expected": { | ||
"fee": 10000, | ||
"fee": 1900, | ||
"inputs": null | ||
@@ -125,3 +136,3 @@ } | ||
"expected": { | ||
"fee": 10000, | ||
"fee": 1900, | ||
"inputs": null | ||
@@ -136,3 +147,3 @@ } | ||
"expected": { | ||
"fee": 20000, | ||
"fee": 12260, | ||
"inputs": null | ||
@@ -147,3 +158,3 @@ } | ||
"expected": { | ||
"fee": 10000, | ||
"fee": 80, | ||
"inputs": null | ||
@@ -158,3 +169,3 @@ } | ||
"expected": { | ||
"fee": 20000, | ||
"fee": 9940, | ||
"inputs": null | ||
@@ -161,0 +172,0 @@ } |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
240
0
10120