committed by
GitHub
9 changed files with 319 additions and 313 deletions
@ -1,3 +0,0 @@ |
|||||
var Blockchain = require('cb-http-client') |
|
||||
var BLOCKTRAIL_API_KEY = process.env.BLOCKTRAIL_API_KEY || 'c0bd8155c66e3fb148bb1664adc1e4dacd872548' |
|
||||
module.exports = new Blockchain('https://api.blocktrail.com/cb/v0.2.1/BTC', { api_key: BLOCKTRAIL_API_KEY }) |
|
@ -0,0 +1,87 @@ |
|||||
|
var assert = require('assert') |
||||
|
var bitcoin = require('../../') |
||||
|
var dhttp = require('dhttp/200') |
||||
|
|
||||
|
var APIPASS = process.env.APIPASS || 'satoshi' |
||||
|
var APIURL = 'https://api.dcousens.cloud/1' |
||||
|
|
||||
|
function broadcast (txHex, callback) { |
||||
|
dhttp({ |
||||
|
method: 'PUT', |
||||
|
url: APIURL + '/t/push', |
||||
|
body: txHex |
||||
|
}, callback) |
||||
|
} |
||||
|
|
||||
|
function mine (count, callback) { |
||||
|
dhttp({ |
||||
|
method: 'POST', |
||||
|
url: APIURL + '/r/generate?count=' + count + '&key=' + APIPASS |
||||
|
}, callback) |
||||
|
} |
||||
|
|
||||
|
function height (callback) { |
||||
|
dhttp({ |
||||
|
method: 'GET', |
||||
|
url: APIURL + '/b/best/height' |
||||
|
}, callback) |
||||
|
} |
||||
|
|
||||
|
function faucet (address, value, callback) { |
||||
|
dhttp({ |
||||
|
method: 'POST', |
||||
|
url: APIURL + '/r/faucet?address=' + address + '&value=' + value + '&key=' + APIPASS |
||||
|
}, function (err, txId) { |
||||
|
if (err) return callback(err) |
||||
|
|
||||
|
unspents(address, function (err, results) { |
||||
|
if (err) return callback(err) |
||||
|
|
||||
|
callback(null, results.filter(x => x.txId === txId).pop()) |
||||
|
}) |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
function fetch (txId, callback) { |
||||
|
dhttp({ |
||||
|
method: 'GET', |
||||
|
url: APIURL + '/t/' + txId + '/json' |
||||
|
}, callback) |
||||
|
} |
||||
|
|
||||
|
function unspents (address, callback) { |
||||
|
dhttp({ |
||||
|
method: 'GET', |
||||
|
url: APIURL + '/a/' + address + '/unspents' |
||||
|
}, callback) |
||||
|
} |
||||
|
|
||||
|
function verify (txo, callback) { |
||||
|
fetch(txo.txId, function (err, tx) { |
||||
|
if (err) return callback(err) |
||||
|
|
||||
|
var txoActual = tx.outs[txo.vout] |
||||
|
if (txo.address) assert.strictEqual(txoActual.address, txo.address) |
||||
|
if (txo.value) assert.strictEqual(txoActual.value, txo.value) |
||||
|
callback() |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
function randomAddress () { |
||||
|
return bitcoin.ECPair.makeRandom({ |
||||
|
network: bitcoin.networks.testnet |
||||
|
}).getAddress() |
||||
|
} |
||||
|
|
||||
|
module.exports = { |
||||
|
broadcast: broadcast, |
||||
|
faucet: faucet, |
||||
|
fetch: fetch, |
||||
|
height: height, |
||||
|
mine: mine, |
||||
|
network: bitcoin.networks.testnet, |
||||
|
unspents: unspents, |
||||
|
verify: verify, |
||||
|
randomAddress: randomAddress, |
||||
|
RANDOM_ADDRESS: randomAddress() |
||||
|
} |
@ -1,99 +0,0 @@ |
|||||
var async = require('async') |
|
||||
var bitcoin = require('../../') |
|
||||
var Blockchain = require('cb-http-client') |
|
||||
var coinSelect = require('coinselect') |
|
||||
var dhttp = require('dhttp/200') |
|
||||
var typeforce = require('typeforce') |
|
||||
var types = require('../../src/types') |
|
||||
|
|
||||
var BLOCKTRAIL_API_KEY = process.env.BLOCKTRAIL_API_KEY || 'c0bd8155c66e3fb148bb1664adc1e4dacd872548' |
|
||||
var blockchain = new Blockchain('https://api.blocktrail.com/cb/v0.2.1/tBTC', { api_key: BLOCKTRAIL_API_KEY }) |
|
||||
var kpNetwork = bitcoin.networks.testnet |
|
||||
var keyPair = bitcoin.ECPair.fromWIF('cQqjeq2rxqwnqwMewJhkNtJDixtX8ctA4bYoWHdxY4xRPVvAEjmk', kpNetwork) |
|
||||
var kpAddress = keyPair.getAddress() |
|
||||
var conflicts = {} |
|
||||
|
|
||||
function fundAddress (unspents, outputs, callback) { |
|
||||
// avoid too-long-mempool-chain
|
|
||||
unspents = unspents.filter(function (x) { |
|
||||
return x.confirmations > 0 && !conflicts[x.txId + x.vout] |
|
||||
}) |
|
||||
|
|
||||
var result = coinSelect(unspents, outputs, 10) |
|
||||
if (!result.inputs) return callback(new Error('Faucet empty')) |
|
||||
|
|
||||
var txb = new bitcoin.TransactionBuilder(kpNetwork) |
|
||||
result.inputs.forEach(function (x) { |
|
||||
conflicts[x.txId + x.vout] = true |
|
||||
txb.addInput(x.txId, x.vout) |
|
||||
}) |
|
||||
|
|
||||
result.outputs.forEach(function (x) { |
|
||||
if (x.address) console.warn('funding ' + x.address + ' w/ ' + x.value) |
|
||||
txb.addOutput(x.address || kpAddress, x.value) |
|
||||
}) |
|
||||
|
|
||||
result.inputs.forEach(function (_, i) { |
|
||||
txb.sign(i, keyPair) |
|
||||
}) |
|
||||
|
|
||||
var tx = txb.build() |
|
||||
|
|
||||
blockchain.transactions.propagate(tx.toHex(), function (err) { |
|
||||
if (err) return callback(err) |
|
||||
|
|
||||
var txId = tx.getId() |
|
||||
callback(null, outputs.map(function (x, i) { |
|
||||
return { txId: txId, vout: i, value: x.value } |
|
||||
})) |
|
||||
}) |
|
||||
} |
|
||||
|
|
||||
blockchain.faucetMany = function faucetMany (outputs, callback) { |
|
||||
blockchain.addresses.unspents(kpAddress, function (err, unspents) { |
|
||||
if (err) return callback(err) |
|
||||
|
|
||||
typeforce([{ |
|
||||
txId: types.Hex, |
|
||||
vout: types.UInt32, |
|
||||
value: types.Satoshi |
|
||||
}], unspents) |
|
||||
|
|
||||
fundAddress(unspents, outputs, callback) |
|
||||
}) |
|
||||
} |
|
||||
|
|
||||
blockchain.faucet = function faucet (address, value, callback) { |
|
||||
blockchain.faucetMany([{ address: address, value: value }], function (err, unspents) { |
|
||||
callback(err, unspents && unspents[0]) |
|
||||
}) |
|
||||
} |
|
||||
|
|
||||
// verify TX was accepted
|
|
||||
blockchain.verify = function verify (address, txId, value, done) { |
|
||||
async.retry(5, function (callback) { |
|
||||
setTimeout(function () { |
|
||||
// check that the above transaction included the intended address
|
|
||||
dhttp({ |
|
||||
method: 'POST', |
|
||||
url: 'https://api.ei8ht.com.au:9443/3/txs', |
|
||||
body: [txId] |
|
||||
}, function (err, result) { |
|
||||
if (err) return callback(err) |
|
||||
if (!result[txId]) return callback(new Error('Could not find ' + txId)) |
|
||||
callback() |
|
||||
}) |
|
||||
}, 400) |
|
||||
}, done) |
|
||||
} |
|
||||
|
|
||||
blockchain.transactions.propagate = function broadcast (txHex, callback) { |
|
||||
dhttp({ |
|
||||
method: 'POST', |
|
||||
url: 'https://api.ei8ht.com.au:9443/3/pushtx', |
|
||||
body: txHex |
|
||||
}, callback) |
|
||||
} |
|
||||
|
|
||||
blockchain.RETURN_ADDRESS = kpAddress |
|
||||
module.exports = blockchain |
|
Loading…
Reference in new issue