diff --git a/package.json b/package.json index 719bdc1..988b0a4 100644 --- a/package.json +++ b/package.json @@ -67,6 +67,7 @@ "async": "^2.0.1", "bs58": "^3.0.0", "cb-http-client": "^0.2.0", + "coinselect": "^3.1.1", "httpify": "^3.0.0", "minimaldata": "^1.0.0", "mocha": "^3.1.0", diff --git a/test/integration/_blockchain.js b/test/integration/_blockchain.js index 1265f37..5d0f91b 100644 --- a/test/integration/_blockchain.js +++ b/test/integration/_blockchain.js @@ -1,43 +1,57 @@ -var async = require('async') +var bitcoin = require('../../') var Blockchain = require('cb-http-client') -var httpify = require('httpify') - var BLOCKTRAIL_API_KEY = process.env.BLOCKTRAIL_API_KEY || 'c0bd8155c66e3fb148bb1664adc1e4dacd872548' +var coinSelect = require('coinselect') +var typeforce = require('typeforce') +var types = require('../../src/types') var mainnet = new Blockchain('https://api.blocktrail.com/cb/v0.2.1/BTC', { api_key: BLOCKTRAIL_API_KEY }) var testnet = 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(process.env.BITCOINJS_TESTNET_WIF, kpNetwork) +var kpAddress = keyPair.getAddress() + +function fundAddress (unspents, address, amount, callback) { + var result = coinSelect(unspents, [{ + address: address, + value: amount + }], 10) + + if (!result.inputs) return callback(new Error('Faucet empty')) + + var txb = new bitcoin.TransactionBuilder(kpNetwork) + result.inputs.forEach(function (x) { + txb.addInput(x.txId, x.vout) + }) + + result.outputs.forEach(function (x) { + txb.addOutput(x.address || kpAddress, x.value) + }) + + result.inputs.forEach(function (x, i) { + txb.sign(i, keyPair) + }) + + var tx = txb.build() + testnet.transactions.propagate(tx.toHex(), function (err) { + callback(err, { + txId: tx.getId(), + vout: 0 + }, 0) + }) +} + testnet.faucet = function faucet (address, amount, done) { - httpify({ - method: 'POST', - url: 'https://api.blocktrail.com/v1/tBTC/faucet/withdrawl?api_key=' + BLOCKTRAIL_API_KEY, - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ - address: address, - amount: amount - }) - }, function (err, result) { + testnet.addresses.unspents(kpAddress, function (err, unspents) { if (err) return done(err) + typeforce([{ + txId: types.Hex, + vout: types.UInt32, + value: types.Satoshi + }], unspents) - if (result.body.code === 401) { - return done(new Error('Hit faucet rate limit; ' + result.body.msg)) - } - - // allow for TX to be processed - async.retry(5, function (callback) { - setTimeout(function () { - testnet.addresses.unspents(address, function (err, result) { - if (err) return callback(err) - - var unspent = result.filter(function (unspent) { - return unspent.value >= amount - }).pop() - - if (!unspent) return callback(new Error('No unspent given')) - callback(null, unspent) - }) - }, 600) - }, done) + fundAddress(unspents, address, amount, done) }) } diff --git a/test/integration/basic.js b/test/integration/basic.js index 927d030..b8b2561 100644 --- a/test/integration/basic.js +++ b/test/integration/basic.js @@ -77,8 +77,8 @@ describe('bitcoinjs-lib (basic)', function () { var tx = new bitcoin.TransactionBuilder(network) tx.addInput(unspentA.txId, unspentA.vout) tx.addInput(unspentB.txId, unspentB.vout) - tx.addOutput('mrCDrCybB6J1vRfbwM5hemdJz73FwDBC8r', 1e4) - tx.addOutput('2NByiBUaEXrhmqAsg7BbLpcQSAQs1EDwt5w', 1e4) + tx.addOutput('n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi', 1e4) + tx.addOutput('mvGVHWi6gbkBZZPaqBVRcxvKVPYd9r3fp7', 1e4) tx.sign(0, alice) tx.sign(1, bob) diff --git a/test/integration/cltv.js b/test/integration/cltv.js index e1b98dd..8009bb8 100644 --- a/test/integration/cltv.js +++ b/test/integration/cltv.js @@ -49,7 +49,7 @@ describe('bitcoinjs-lib (CLTV)', function () { var tx = new bitcoin.TransactionBuilder(network) tx.setLockTime(timeUtc) tx.addInput(unspent.txId, 0, 0xfffffffe) - tx.addOutput(alice.getAddress(), 1000) + tx.addOutput('n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi', 1e4) var txRaw = tx.buildIncomplete() var signatureHash = txRaw.hashForSignature(0, redeemScript, hashType) @@ -82,7 +82,7 @@ describe('bitcoinjs-lib (CLTV)', function () { var tx = new bitcoin.TransactionBuilder(network) tx.addInput(unspent.txId, 0, 0xfffffffe) - tx.addOutput(alice.getAddress(), 1000) + tx.addOutput('n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi', 1e4) var txRaw = tx.buildIncomplete() var signatureHash = txRaw.hashForSignature(0, redeemScript, hashType) @@ -115,7 +115,7 @@ describe('bitcoinjs-lib (CLTV)', function () { var tx = new bitcoin.TransactionBuilder(network) tx.setLockTime(timeUtc) tx.addInput(unspent.txId, 0, 0xfffffffe) - tx.addOutput(alice.getAddress(), 1000) + tx.addOutput('n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi', 1e4) var txRaw = tx.buildIncomplete() var signatureHash = txRaw.hashForSignature(0, redeemScript, hashType) diff --git a/test/integration/multisig.js b/test/integration/multisig.js index 6775bd8..5f27e4e 100644 --- a/test/integration/multisig.js +++ b/test/integration/multisig.js @@ -41,17 +41,9 @@ describe('bitcoinjs-lib (multisig)', function () { blockchain.t.faucet(address, 2e4, function (err, unspent) { if (err) return done(err) - var fee = 1e4 - var targetValue = unspent.value - fee - - // make a random destination address - var targetAddress = bitcoin.ECPair.makeRandom({ - network: bitcoin.networks.testnet - }).getAddress() - var txb = new bitcoin.TransactionBuilder(bitcoin.networks.testnet) txb.addInput(unspent.txId, unspent.vout) - txb.addOutput(targetAddress, targetValue) + txb.addOutput('n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi', 1e4) // sign with 1st and 3rd key txb.sign(0, keyPairs[0], redeemScript) @@ -64,18 +56,16 @@ describe('bitcoinjs-lib (multisig)', function () { blockchain.t.transactions.propagate(tx.toHex(), function (err) { if (err) return done(err) - // allow for TX to be processed + // wait for TX to be accepted async.retry(5, function (callback) { setTimeout(function () { // check that the above transaction included the intended address - blockchain.t.addresses.unspents(targetAddress, function (err, unspents) { + blockchain.t.addresses.unspents('n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi', function (err, unspents) { if (err) return callback(err) + if (!unspents.some(function (unspent) { + return unspent.txId === txId && unspent.value === 1e4 + })) return callback(new Error('Could not find unspent after broadcast')) - var unspentFound = unspents.some(function (unspent) { - return unspent.txId === txId && unspent.value === targetValue - }) - - if (!unspentFound) return callback(new Error('Could not find unspent after propagate')) callback() }) }, 600)