Package Exports
- bitcoinselect
- bitcoinselect/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (bitcoinselect) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
bitcoinselect
An unspent transaction output (UTXO) selection module for bitcoin.
WARNING: Value units are in satoshi
s, not Bitcoin.
Algorithms
Module | Algorithm | Re-orders UTXOs? |
---|---|---|
require('bitcoinselect') |
Blackjack, with Accumulative fallback | By Descending Value |
require('bitcoinselect/accumulative') |
Accumulative - accumulates inputs until the target value (+fees) is reached, skipping detrimental inputs | - |
require('bitcoinselect/blackjack') |
Blackjack - accumulates inputs until the target value (+fees) is matched, does not accumulate inputs that go over the target value (within a threshold) | - |
require('bitcoinselect/break') |
Break - breaks the input values into equal denominations of output (as provided) |
- |
require('bitcoinselect/split') |
Split - splits the input values evenly between all outputs , any provided output with .value remains unchanged |
- |
Note: Each algorithm will add a change output if the input - output - fee
value difference is over a dust threshold.
This is calculated independently by utils.finalize
, irrespective of the algorithm chosen, for the purposes of safety.
Pro-tip: if you want to send-all inputs to an output address, bitcoinselect/split
with a partial output (.address
defined, no .value
) can be used to send-all, while leaving an appropriate amount for the fee
.
Example
let coinSelect = require('bitcoinselect')
let feeRate = 55 // satoshis per byte
let utxos = [
...,
{
txId: '...',
vout: 0,
...,
value: 10000,
// For use with PSBT:
// not needed for coinSelect, but will be passed on to inputs later
nonWitnessUtxo: Buffer.from('...full raw hex of txId tx...', 'hex'),
// OR
// if your utxo is a segwit output, you can use witnessUtxo instead
witnessUtxo: {
script: Buffer.from('... scriptPubkey hex...', 'hex'),
value: 10000 // 0.0001 BTC and is the exact same as the value above
}
}
]
let targets = [
...,
{
address: '1EHNa6Q4Jz2uvNExL497mE43ikXhwF6kZm',
value: 5000
}
]
// ...
let { inputs, outputs, fee } = coinSelect(utxos, targets, feeRate)
// the accumulated fee is always returned for analysis
console.log(fee)
// .inputs and .outputs will be undefined if no solution was found
if (!inputs || !outputs) return
let psbt = new bitcoin.Psbt()
inputs.forEach(input =>
psbt.addInput({
hash: input.txId,
index: input.vout,
nonWitnessUtxo: input.nonWitnessUtxo,
// OR (not both)
witnessUtxo: input.witnessUtxo,
})
)
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()
wallet.nextChangeAddress()
}
psbt.addOutput({
address: output.address,
value: output.value,
})
})