|
| 1 | +const { get } = require('axios') |
| 2 | + |
| 3 | +const bcInfoHost = "https://blockchain.info" |
| 4 | +const unspentUrl = (address) => `${bcInfoHost}/unspent?active=${address}&format=json&cors=true` |
| 5 | + |
| 6 | +// convert from blockchain.info format to bitcore-lib utxo format |
| 7 | +const convertUTXO = (utxo) => ( |
| 8 | + { |
| 9 | + txId: utxo.tx_hash_big_endian, |
| 10 | + vout: utxo.tx_output_n, |
| 11 | + script: utxo.script, |
| 12 | + satoshis: utxo.value, |
| 13 | + } |
| 14 | +) |
| 15 | + |
| 16 | +const getUnspentOutputs = async ({ address }) => { |
| 17 | + const url = unspentUrl(address) |
| 18 | + const resp = await get(url) |
| 19 | + const data = resp.data |
| 20 | + if (data == "No free outputs to spend") return [] |
| 21 | + if (data == "Invalid Bitcoin Address") throw Error(`Bitcoin address is not valid - address: ${address}`) |
| 22 | + return data.unspent_outputs |
| 23 | +} |
| 24 | + |
| 25 | +// raise an error if there are no spendable outputs |
| 26 | +const checkUTXOs = ({ utxos, address }) => { |
| 27 | + utxos = utxos.filter(utxo => utxo.confirmations > 0) |
| 28 | + utxos = utxos.filter(utxo => utxo.value > 1000) |
| 29 | + if (utxos.length == 0) throw Error(`No spendable outputs were found, please fund the address or wait for transactions to confirm - address: ${address}`) |
| 30 | +} |
| 31 | + |
| 32 | +const getUTXOs = async ({ address }) => { |
| 33 | + let utxos = await getUnspentOutputs({ address }) |
| 34 | + checkUTXOs({ utxos, address }) |
| 35 | + utxos = utxos.map(convertUTXO) |
| 36 | + return utxos |
| 37 | +} |
| 38 | + |
| 39 | +module.exports = getUTXOs |
0 commit comments