Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

coinselect

Package Overview
Dependencies
Maintainers
1
Versions
26
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

coinselect - npm Package Compare versions

Comparing version 2.0.1 to 3.0.0

blackjack.js

106

index.js

@@ -1,74 +0,42 @@

// TODO: integrate privacy calculations, group by address, avoid linking multiple addresses together
let accumulative = require('./accum')
let blackjack = require('./blackjack')
// XXX: these are based on pubKeyHash estimates, used to improve performance
var TX_EMPTY_SIZE = 8
var TX_INPUT_BASE = 40 + 2
var TX_INPUT_PUBKEYHASH = 106
var TX_OUTPUT_BASE = 8 + 1
var TX_OUTPUT_PUBKEYHASH = 25
// TODO
// function groupByRelation (utxos) {
// let txoMap = {}
// let result = []
//
// // group by address/script
// utxos.forEach((utxo) => {
// let key = utxo.address || utxo.script
//
// // no relation known, use as is
// if (!key) return result.push(utxo)
//
// // else, append relation via key
// if (!txoMap[key]) txoMap[key] = []
// txoMap[key].push(utxo)
// })
//
// for (let key in txoMap) {
// let group = txoMap[key]
//
// // summate 'grouping' value
// group.value = group.reduce((a, x) => a + x.value, 0)
// result.push(group)
// }
//
// return result
// }
function estimateRelayFee (byteLength, feeRate) {
return byteLength * feeRate
}
module.exports = function coinSelect (utxos, outputs, feeRate) {
// order by descending value
utxos = utxos.concat().sort((a, b) => b.value - a.value)
module.exports = function coinSelect (unspents, outputs, feeRate) {
// sort by descending value
var sorted = unspents.concat().sort(function (o1, o2) {
return o2.value - o1.value
})
// attempt to use the blackjack strategy first (no change output)
let base = blackjack(utxos, outputs, feeRate)
if (base.inputs) return base
var byteLength = TX_EMPTY_SIZE
var target = 0
outputs.forEach(function (output) {
byteLength += TX_OUTPUT_BASE + (output.script ? output.script.length : TX_OUTPUT_PUBKEYHASH)
target += output.value
})
var accum = 0
for (var i = 0; i < sorted.length; ++i) {
var unspent = sorted[i]
// TODO: an estimate is used because of missing signature data
byteLength += TX_INPUT_BASE + TX_INPUT_PUBKEYHASH
accum += unspent.value
// ignore fees until we have the minimum amount
if (accum < target) continue
var baseFee = estimateRelayFee(byteLength, feeRate)
var total = target + baseFee
// continue until we can afford the base fee
if (accum < total) continue
var inputs = sorted.slice(0, i + 1)
var feeWithChange = estimateRelayFee(byteLength + TX_OUTPUT_BASE + TX_OUTPUT_PUBKEYHASH, feeRate)
var totalWithChange = target + feeWithChange
// can we afford a change output?
if (accum >= totalWithChange) {
var remainderWithChange = accum - totalWithChange
return {
fee: feeWithChange,
inputs: inputs,
remainder: remainderWithChange
}
}
var remainder = accum - total
return {
fee: baseFee + remainder,
inputs: inputs,
remainder: 0
}
}
return {
fee: estimateRelayFee(byteLength, feeRate),
inputs: null
}
// else, try the accumulative strategy
return accumulative(utxos, outputs, feeRate)
}
{
"name": "coinselect",
"version": "2.0.1",
"description": "A fee optimizing bitcoin input selection module",
"version": "3.0.0",
"description": "A transaction input selection module for bitcoin.",
"keywords": [

@@ -26,3 +26,6 @@ "coinselect",

"files": [
"index.js"
"accumulative.js",
"blackjack.js",
"index.js",
"utils.js"
],

@@ -44,4 +47,6 @@ "main": "index.js",

"standard": "*",
"tap-spec": "^4.1.1",
"tape": "^4.5.1"
}
},
"dependencies": {}
}

@@ -8,7 +8,7 @@ # coinselect

A fee-optimizing, transaction input selection module for bitcoinjs-lib.
A transaction input selection module for bitcoin.
The code is stable.
The module's interface/existence is not.
The module's interface is not.

@@ -21,8 +21,9 @@ Please let me know if you are using this package.

``` javascript
var coinSelect = require('coinselect')
var feeRate = 55 // satoshis per byte
var unspents = [
let coinSelect = require('coinselect')
let feeRate = 55 // satoshis per byte
let utxos = [
...,
{
txId: '...',
vout: 0,
...,

@@ -32,3 +33,3 @@ value: 10000

]
var outputs = [
let targets = [
...,

@@ -41,17 +42,23 @@ {

var result = coinselect(unspents, outputs, feeRate)
// ...
let { inputs, outputs, fee } = coinSelect(utxos, targets, feeRate)
// the accumulated fee is always returned
console.log(result.fee)
// the accumulated fee is always returned for analysis
console.log(fee)
// .inputs may be null if not enough funds exist
if (!result.inputs) return
// .inputs and .outputs will be undefined if no solution was found
if (!inputs || !outputs) return
// success!
var txb = new bitcoin.TransactionBuilder()
let txb = new bitcoin.TransactionBuilder()
// is a change output non-dust?
if (result.remainder > 5460) {
txb.addOutput(changeAddress, result.remainder)
}
inputs.forEach(input => txb.addInput(input.txId, input.vout))
outputs.forEach(output => {
// watch out, outputs may have been added that you need to provide
// an output address/script for
if (!output.address) {
output.address = wallet.getChangeAddress()
}
txb.addOutput(output.address, output.value)
})
```

@@ -58,0 +65,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc