Compare commits

..

38 Commits

Author SHA1 Message Date
softsimon
b6eaefd223
Adding new methods. 2021-07-13 18:40:05 +03:00
softsimon
c097b9c81e * adding new mempool methods
* promisify
2020-12-20 17:40:55 +07:00
Sean Lavine
cb6e5c811b
readme: update link to bitcoin-core 2018-05-13 13:35:57 -07:00
Sean Lavine
e969b3844f
readme: make unmaintained explicit 2018-05-13 13:35:11 -07:00
Sean Lavine
07d320d630 readme: new features in bitcoin-core 2016-03-19 17:48:52 -07:00
Sean Lavine
7b739e8eb9 readme: recommend bitcoin-core 2016-03-16 20:00:27 -07:00
Sean Lavine
e956310d43 3.0.1 2015-10-25 21:32:10 -07:00
Sean Lavine
b444d23f00 update changelog 2015-10-25 21:32:02 -07:00
Sean Lavine
fe1ab3fc52 coding style: standard 2015-10-25 21:26:44 -07:00
Sean Lavine
33d4ff9079 readme: add mention of bitcoin-promise module 2015-10-25 20:38:42 -07:00
Sean Lavine
b9a2a749d8 3.0.0 2015-10-18 21:15:53 -07:00
Sean Lavine
b136254de9 update changelog 2015-10-18 21:15:44 -07:00
Sean Lavine
bfedefd8c4 upgrade dev dependencies 2015-10-18 21:07:25 -07:00
Sean Lavine
12860e83de add public domain license
See jb55/node-bitcoin#4
2015-10-18 21:01:07 -07:00
Sean Lavine
2a067655c5 add bitcoind v0.11 command: generate 2015-10-18 20:51:26 -07:00
Sean Lavine
b93026db3a travis: specify node_js as language 2015-10-18 20:48:53 -07:00
Sean Lavine
1d76ea1e14 new command in bitcoind v0.11: verifyTxOutProof 2015-10-18 20:45:26 -07:00
Sean Lavine
16f07d9a7a gethashespersec removed in bitcoind v0.11 2015-10-18 20:43:10 -07:00
Sean Lavine
990d5c472a travis: use docker to run tests 2015-10-18 20:32:22 -07:00
Sean Lavine
41818121ae upgrade testnet-box 2015-10-18 20:15:23 -07:00
Sean Lavine
67e6545d88 2.4.0 2015-07-16 09:18:18 -07:00
Sean Lavine
43e1412066 prepare changelog for release 2015-07-16 09:18:13 -07:00
Sean Lavine
12d8fd898a update changelog 2015-07-12 09:44:26 -07:00
Sean Lavine
a245166a65 don't lazy-load http/https modules 2015-07-12 09:40:43 -07:00
Sean Lavine
d25098240b add command getTxOutProof 2015-07-12 09:39:50 -07:00
Sean Lavine
0ef43d8555 clean up Dockerfile 2015-06-26 17:51:29 -07:00
Sean Lavine
a83c454525 2.3.2 2015-06-26 14:41:55 -07:00
Sean Lavine
bd63966e43 update changelog 2015-06-26 14:27:16 -07:00
Sean Lavine
6973183179 add Dockerfile for running tests 2015-06-26 14:26:50 -07:00
Sean Lavine
4328a49b63 add missing commands 2015-06-26 14:26:36 -07:00
Sean Lavine
2e56677ab9 fix missing cmds not being found in tests 2015-06-26 14:12:56 -07:00
Sean Lavine
69393ae38c 2.3.1 2015-06-24 08:56:35 -07:00
Sean Lavine
4e0851d859 update changelog 2015-06-24 08:56:29 -07:00
Sean Lavine
4f47030c53 Merge pull request #27 from challengerdeep/mempoolinfo
Add getmempoolinfo command
2015-06-24 08:53:42 -07:00
Vincent de Lagabbe
2e4c46cc41 Add getmempoolinfo command
added in bitcoind v0.10
2015-06-24 14:57:49 +02:00
Sean Lavine
00047173d5 travis: add node v0.12 and iojs 2015-03-24 18:39:50 -07:00
Sean Lavine
cb95f56e9c skip non-cmd lines in help output 2015-03-24 18:39:50 -07:00
Sean Lavine
bb8d05e556 remove test for getWork()
This was removed in bitcoind v0.10.0
2015-03-24 18:39:49 -07:00
14 changed files with 671 additions and 585 deletions

View File

@ -3,3 +3,4 @@ test/
.project
.gitmodules
.travis.yml
Dockerfile

View File

@ -1,12 +1,18 @@
# need sudo for docker
sudo: required
language: node_js
node_js:
- "0.10"
# skip install step (npm install)
# See http://docs.travis-ci.com/user/customizing-the-build/#Skipping-the-Installation-Step
install: true
before_install:
- sudo add-apt-repository --yes ppa:bitcoin/bitcoin
- sudo apt-get update
- sudo apt-get install bitcoind
services:
- docker
after_install:
before_script:
- git submodule update --init
- docker build -t node-bitcoin .
script:
- docker run node-bitcoin

View File

@ -1,5 +1,30 @@
# node-bitcoin changelog
## v3.0.1 (2015/10/25)
* fix redefinition of already defined variable (does not actually affect behavior)
## v3.0.0 (2015/10/18)
* make public domain license explicit
* remove commands dropped in bitcoind v0.11
* `getHashesPerSecond`
* `getHashesPerSec`
* add missing commands for bitcoind v0.11
* `generate`
* `verifyTxOutProof`
## v2.4.0 (2015/07/16)
* don't lazy-load http/https modules
* add command for bitcoind v0.11.0: `getTxOutProof`
## v2.3.2 (2015/06/26)
* fix bug in test suite that was supposed to detect missing commands
* add missing commands
* `prioritiseTransaction`
* `importWallet`
## v2.3.1 (2015/06/24)
* add missing `getMempoolInfo` for bitcoind v0.10
## v2.3.0 (2015/02/04)
* drop node v0.8.x support
* update testnet-box

21
Dockerfile Normal file
View File

@ -0,0 +1,21 @@
# Dockerfile for running node-bitcoin tests
FROM freewil/bitcoin-testnet-box
MAINTAINER Sean Lavine <lavis88@gmail.com>
# install node.js
USER root
RUN apt-get install --yes curl
RUN curl --silent --location https://deb.nodesource.com/setup_0.12 | bash -
RUN apt-get install --yes nodejs
# set permissions for tester user on project
ADD . /home/tester/node-bitcoin
RUN chown --recursive tester:tester /home/tester/node-bitcoin
# install module dependencies
USER tester
WORKDIR /home/tester/node-bitcoin
RUN npm install
# run test suite
CMD ["npm", "test"]

24
LICENSE Normal file
View File

@ -0,0 +1,24 @@
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <http://unlicense.org/>

View File

@ -1,7 +1,25 @@
# node-bitcoin [![Build Status](https://travis-ci.org/freewil/node-bitcoin.svg?branch=master)](https://travis-ci.org/freewil/node-bitcoin)
# node-bitcoin
[![travis][travis-image]][travis-url]
[![npm][npm-image]][npm-url]
[![downloads][downloads-image]][downloads-url]
[![js-standard-style][standard-image]][standard-url]
[travis-image]: https://travis-ci.org/freewil/node-bitcoin.svg?branch=master
[travis-url]: https://travis-ci.org/freewil/node-bitcoin
[npm-image]: https://img.shields.io/npm/v/bitcoin.svg?style=flat
[npm-url]: https://npmjs.org/package/bitcoin
[downloads-image]: https://img.shields.io/npm/dm/bitcoin.svg?style=flat
[downloads-url]: https://npmjs.org/package/bitcoin
[standard-image]: https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat
[standard-url]: http://standardjs.com
node-bitcoin is a simple wrapper for the Bitcoin client's JSON-RPC API.
**Unmaintained, please see [bitcoin-core](https://github.com/ruimarinho/bitcoin-core)**
The API is equivalent to the API document [here](https://en.bitcoin.it/wiki/Original_Bitcoin_client/API_Calls_list).
The methods are exposed as lower camelcase methods on the `bitcoin.Client`
object, or you may call the API directly using the `cmd` method.

View File

@ -11,6 +11,7 @@ module.exports = {
encryptWallet: 'encryptwallet',
estimateFee: 'estimatefee', // bitcoind v0.10.0x
estimatePriority: 'estimatepriority', // bitcoind v0.10.0+
generate: 'generate', // bitcoind v0.11.0+
getAccount: 'getaccount',
getAccountAddress: 'getaccountaddress',
getAddedNodeInfo: 'getaddednodeinfo', // bitcoind v0.8.0+
@ -18,17 +19,23 @@ module.exports = {
getBalance: 'getbalance',
getBestBlockHash: 'getbestblockhash', // bitcoind v0.9.0+
getBlock: 'getblock',
getBlockchainInfo : 'getblockchaininfo', // bitcoind v0.9.2+
getBlockStats: 'getblockstats',
getBlockFilter: 'getblockfilter',
getBlockchainInfo: 'getblockchaininfo', // bitcoind v0.9.2+
getBlockCount: 'getblockcount',
getBlockHash: 'getblockhash',
getBlockHeader: 'getblockheader',
getBlockTemplate: 'getblocktemplate', // bitcoind v0.7.0+
getChainTips: 'getchaintips', // bitcoind v0.10.0+
getChainTxStats: 'getchaintxstats',
getConnectionCount: 'getconnectioncount',
getDifficulty: 'getdifficulty',
getGenerate: 'getgenerate',
getHashesPerSecond: 'gethashespersec',
getHashesPerSec: 'gethashespersec',
getInfo: 'getinfo',
getMempoolAncestors: 'getmempoolancestors',
getMempoolDescendants: 'getmempooldescendants',
getMempoolEntry: 'getmempoolentry',
getMempoolInfo: 'getmempoolinfo', // bitcoind v0.10+
getMiningInfo: 'getmininginfo',
getNetTotals: 'getnettotals',
getNetworkInfo: 'getnetworkinfo', // bitcoind v0.9.2+
@ -42,13 +49,14 @@ module.exports = {
getReceivedByAddress: 'getreceivedbyaddress',
getTransaction: 'gettransaction',
getTxOut: 'gettxout', // bitcoind v0.7.0+
getTxOutProof: 'gettxoutproof', // bitcoind v0.11.0+
getTxOutSetInfo: 'gettxoutsetinfo', // bitcoind v0.7.0+
getUnconfirmedBalance: 'getunconfirmedbalance', // bitcoind v0.9.0+
getWalletInfo: 'getwalletinfo', // bitcoind v0.9.2+
getWork: 'getwork',
help: 'help',
importAddress: 'importaddress', // bitcoind v0.10.0+
importPrivKey: 'importprivkey',
importWallet: 'importwallet', // bitcoind v0.9.0+
keypoolRefill: 'keypoolrefill',
keyPoolRefill: 'keypoolrefill',
listAccounts: 'listaccounts',
@ -62,6 +70,7 @@ module.exports = {
lockUnspent: 'lockunspent', // bitcoind v0.8.0+
move: 'move',
ping: 'ping', // bitcoind v0.9.0+
prioritiseTransaction: 'prioritisetransaction', // bitcoind v0.10.0+
sendFrom: 'sendfrom',
sendMany: 'sendmany',
sendRawTransaction: 'sendrawtransaction', // bitcoind v0.7.0+
@ -76,7 +85,8 @@ module.exports = {
validateAddress: 'validateaddress',
verifyChain: 'verifychain', // bitcoind v0.9.0+
verifyMessage: 'verifymessage',
verifyTxOutProof: 'verifytxoutproof', // bitcoind v0.11.0+
walletLock: 'walletlock',
walletPassphrase: 'walletpassphrase',
walletPassphraseChange: 'walletpassphrasechange'
};
}

View File

@ -1,62 +1,58 @@
var commands = require('./commands'),
rpc = require('./jsonrpc');
var commands = require('./commands')
var rpc = require('./jsonrpc')
//===----------------------------------------------------------------------===//
// ===----------------------------------------------------------------------===//
// Client
//===----------------------------------------------------------------------===//
function Client(opts) {
this.rpc = new rpc.Client(opts);
// ===----------------------------------------------------------------------===//
function Client (opts) {
this.rpc = new rpc.Client(opts)
}
//===----------------------------------------------------------------------===//
// ===----------------------------------------------------------------------===//
// cmd
//===----------------------------------------------------------------------===//
Client.prototype.cmd = function() {
var args = [].slice.call(arguments);
var cmd = args.shift();
// ===----------------------------------------------------------------------===//
Client.prototype.cmd = function () {
var args = [].slice.call(arguments)
var cmd = args.shift()
callRpc(cmd, args, this.rpc);
callRpc(cmd, args, this.rpc)
}
//===----------------------------------------------------------------------===//
// ===----------------------------------------------------------------------===//
// callRpc
//===----------------------------------------------------------------------===//
function callRpc(cmd, args, rpc) {
var fn = args[args.length-1];
// ===----------------------------------------------------------------------===//
function callRpc (cmd, args, rpc) {
var fn = args[args.length - 1]
// If the last argument is a callback, pop it from the args list
if (typeof fn === 'function') {
args.pop();
args.pop()
} else {
fn = function() {};
fn = function () {}
}
rpc.call(cmd, args, function(){
var args = [].slice.call(arguments);
args.unshift(null);
fn.apply(this, args);
}, function(err){
fn(err);
});
return rpc.call(cmd, args, function () {
var args = [].slice.call(arguments)
args.unshift(null)
fn.apply(this, args)
}, function (err) {
fn(err)
})
}
//===----------------------------------------------------------------------===//
// ===----------------------------------------------------------------------===//
// Initialize wrappers
//===----------------------------------------------------------------------===//
(function() {
// ===----------------------------------------------------------------------===//
(function () {
for (var protoFn in commands) {
(function(protoFn) {
Client.prototype[protoFn] = function() {
var args = [].slice.call(arguments);
callRpc(commands[protoFn], args, this.rpc);
};
})(protoFn);
(function (protoFn) {
Client.prototype[protoFn] = function () {
var args = [].slice.call(arguments)
return callRpc(commands[protoFn], args, this.rpc)
}
})(protoFn)
}
})();
})()
// Export!
module.exports.Client = Client;
module.exports.Client = Client

View File

@ -1,153 +1,155 @@
var Client = function(opts) {
this.opts = opts || {};
this.http = this.opts.ssl ? require('https') : require('http');
};
var http = require('http')
var https = require('https')
Client.prototype.call = function(method, params, callback, errback, path) {
var time = Date.now();
var requestJSON;
var Client = function (opts) {
this.opts = opts || {}
this.http = this.opts.ssl ? https : http
}
if (Array.isArray(method)) {
// multiple rpc batch call
requestJSON = [];
method.forEach(function(batchCall, i) {
requestJSON.push({
id: time + '-' + i,
method: batchCall.method,
params: batchCall.params
});
});
} else {
// single rpc call
requestJSON = {
id: time,
method: method,
params: params
};
}
Client.prototype.call = function (method, params) {
return new Promise((resolve, reject) => {
var time = Date.now()
var requestJSON
// First we encode the request into JSON
var requestJSON = JSON.stringify(requestJSON);
// prepare request options
var requestOptions = {
host: this.opts.host || 'localhost',
port: this.opts.port || 8332,
method: 'POST',
path: path || '/',
headers: {
'Host': this.opts.host || 'localhost',
'Content-Length': requestJSON.length
},
agent: false,
rejectUnauthorized: this.opts.ssl && this.opts.sslStrict !== false
};
if (this.opts.ssl && this.opts.sslCa) {
requestOptions.ca = this.opts.sslCa;
}
// use HTTP auth if user and password set
if (this.opts.user && this.opts.pass) {
requestOptions.auth = this.opts.user + ':' + this.opts.pass;
}
// Now we'll make a request to the server
var cbCalled = false;
var request = this.http.request(requestOptions);
// start request timeout timer
var reqTimeout = setTimeout(function() {
if (cbCalled) return;
cbCalled = true;
request.abort();
var err = new Error('ETIMEDOUT');
err.code = 'ETIMEDOUT';
errback(err);
}, this.opts.timeout || 30000);
// set additional timeout on socket in case of remote freeze after sending headers
request.setTimeout(this.opts.timeout || 30000, function() {
if (cbCalled) return;
cbCalled = true;
request.abort();
var err = new Error('ESOCKETTIMEDOUT')
err.code = 'ESOCKETTIMEDOUT'
errback(err);
});
request.on('error', function(err) {
if (cbCalled) return;
cbCalled = true;
clearTimeout(reqTimeout);
errback(err);
});
request.on('response', function(response) {
clearTimeout(reqTimeout);
// We need to buffer the response chunks in a nonblocking way.
var buffer = '';
response.on('data', function(chunk) {
buffer = buffer + chunk;
});
// When all the responses are finished, we decode the JSON and
// depending on whether it's got a result or an error, we call
// emitSuccess or emitError on the promise.
response.on('end', function() {
var err;
if (cbCalled) return;
cbCalled = true;
try {
var decoded = JSON.parse(buffer);
} catch (e) {
if (response.statusCode !== 200) {
err = new Error('Invalid params, response status code: ' + response.statusCode);
err.code = -32602;
errback(err);
} else {
err = new Error('Problem parsing JSON response from server');
err.code = -32603;
errback(err);
}
return;
if (Array.isArray(method)) {
// multiple rpc batch call
requestJSON = []
method.forEach(function (batchCall, i) {
requestJSON.push({
id: time + '-' + i,
method: batchCall.method,
params: batchCall.params
})
})
} else {
// single rpc call
requestJSON = {
id: time,
method: method,
params: params
}
}
if (!Array.isArray(decoded)) {
decoded = [decoded];
}
// First we encode the request into JSON
requestJSON = JSON.stringify(requestJSON)
// iterate over each response, normally there will be just one
// unless a batch rpc call response is being processed
decoded.forEach(function(decodedResponse, i) {
if (decodedResponse.hasOwnProperty('error') && decodedResponse.error != null) {
if (errback) {
err = new Error(decodedResponse.error.message || '');
if (decodedResponse.error.code) {
err.code = decodedResponse.error.code;
}
errback(err);
}
} else if (decodedResponse.hasOwnProperty('result')) {
if (callback) {
callback(decodedResponse.result, response.headers);
}
} else {
if (errback) {
err = new Error(decodedResponse.error.message || '');
if (decodedResponse.error.code) {
err.code = decodedResponse.error.code;
}
errback(err);
// prepare request options
var requestOptions = {
host: this.opts.host || 'localhost',
port: this.opts.port || 8332,
method: 'POST',
path: '/',
headers: {
'Host': this.opts.host || 'localhost',
'Content-Length': requestJSON.length
},
agent: false,
rejectUnauthorized: this.opts.ssl && this.opts.sslStrict !== false
}
if (this.opts.ssl && this.opts.sslCa) {
requestOptions.ca = this.opts.sslCa
}
// use HTTP auth if user and password set
if (this.opts.user && this.opts.pass) {
requestOptions.auth = this.opts.user + ':' + this.opts.pass
}
// Now we'll make a request to the server
var cbCalled = false
var request = this.http.request(requestOptions)
// start request timeout timer
var reqTimeout = setTimeout(function () {
if (cbCalled) return
cbCalled = true
request.abort()
var err = new Error('ETIMEDOUT')
err.code = 'ETIMEDOUT'
reject(err)
}, this.opts.timeout || 30000)
// set additional timeout on socket in case of remote freeze after sending headers
request.setTimeout(this.opts.timeout || 30000, function () {
if (cbCalled) return
cbCalled = true
request.abort()
var err = new Error('ESOCKETTIMEDOUT')
err.code = 'ESOCKETTIMEDOUT'
reject(err)
})
request.on('error', function (err) {
if (cbCalled) return
cbCalled = true
clearTimeout(reqTimeout)
reject(err)
})
request.on('response', function (response) {
clearTimeout(reqTimeout)
// We need to buffer the response chunks in a nonblocking way.
var buffer = ''
response.on('data', function (chunk) {
buffer = buffer + chunk
})
// When all the responses are finished, we decode the JSON and
// depending on whether it's got a result or an error, we call
// emitSuccess or emitError on the promise.
response.on('end', function () {
var err
if (cbCalled) return
cbCalled = true
try {
var decoded = JSON.parse(buffer)
} catch (e) {
if (response.statusCode !== 200) {
err = new Error('Invalid params, response status code: ' + response.statusCode)
err.code = -32602
reject(err)
} else {
err = new Error('Problem parsing JSON response from server')
err.code = -32603
reject(err)
}
return
}
});
});
if (!Array.isArray(decoded)) {
decoded = [decoded]
}
// iterate over each response, normally there will be just one
// unless a batch rpc call response is being processed
decoded.forEach(function (decodedResponse, i) {
if (decodedResponse.hasOwnProperty('error') && decodedResponse.error != null) {
if (reject) {
err = new Error(decodedResponse.error.message || '')
if (decodedResponse.error.code) {
err.code = decodedResponse.error.code
}
reject(err)
}
} else if (decodedResponse.hasOwnProperty('result')) {
resolve(decodedResponse.result, response.headers)
} else {
if (reject) {
err = new Error(decodedResponse.error.message || '')
if (decodedResponse.error.code) {
err.code = decodedResponse.error.code
}
reject(err)
}
}
})
})
})
request.end(requestJSON);
});
request.end(requestJSON);
};
}
module.exports.Client = Client;
module.exports.Client = Client

View File

@ -1,7 +1,7 @@
{
"name": "bitcoin",
"name": "@mempool/bitcoin",
"description": "Communicate with bitcoind via JSON-RPC",
"version": "2.3.0",
"version": "3.0.3",
"main": "lib/index.js",
"keywords": [
"bitcoin",
@ -13,18 +13,28 @@
],
"dependencies": {},
"devDependencies": {
"clone": "^0.1.18",
"mocha": "^2.1.0"
"clone": "^1.0.2",
"mocha": "^2.3.3",
"standard": "^5.3.1"
},
"optionalDependencies": {},
"repository": {
"type": "git",
"url": "git://github.com/freewil/node-bitcoin.git"
"url": "git://github.com/mempool/node-bitcoin.git"
},
"engines": {
"node": ">= 0.10.0"
},
"scripts": {
"pretest": "standard --verbose",
"test": "make test"
}
},
"bugs": {
"url": "https://github.com/mempool/node-bitcoin/issues"
},
"homepage": "https://github.com/mempool/node-bitcoin#readme",
"directories": {
"test": "test"
},
"license": "Unlicense"
}

View File

@ -1,317 +1,292 @@
var assert = require('assert'),
clone = require('clone'),
http = require('http'),
bitcoin = require('../'),
config = require('./config');
/* global describe, it */
var assert = require('assert')
var clone = require('clone')
var http = require('http')
var bitcoin = require('../')
var config = require('./config')
var test = {
account: 'test'
};
}
var makeClient = function makeClient() {
return new bitcoin.Client(config);
};
var makeClient = function makeClient () {
return new bitcoin.Client(config)
}
var notEmpty = function notEmpty(data) {
if (data === 0) return;
assert.ok(data);
};
var notEmpty = function notEmpty (data) {
if (data === 0) return
assert.ok(data)
}
var makeServer = function(port) {
var server = http.createServer();
server.listen(port);
return server;
};
var makeServer = function (port) {
var server = http.createServer()
server.listen(port)
return server
}
describe('Client', function() {
describe('Client', function () {
describe('getAccountAddress()', function () {
it('should be able to get an account address', function (done) {
var client = makeClient()
client.getAccountAddress(test.account, function (err, address) {
assert.ifError(err)
assert.ok(address)
client.getAccount(address, function (err, account) {
assert.ifError(err)
assert.equal(account, test.account)
done()
})
})
})
})
describe('getAccountAddress()', function() {
it('should be able to get an account address', function(done) {
var client = makeClient();
client.getAccountAddress(test.account, function(err, address) {
assert.ifError(err);
assert.ok(address);
client.getAccount(address, function(err, account) {
assert.ifError(err);
assert.equal(account, test.account);
done();
});
});
});
});
describe('listTransactions()', function () {
it('should be able to listTransactions with specific count', function (done) {
var client = makeClient()
client.listTransactions(test.account, 15, function (err, txs) {
assert.ifError(err)
assert.ok(txs)
assert.ok(Array.isArray(txs))
done()
})
})
describe('listTransactions()', function() {
it('should be able to listTransactions with specific count', function(done) {
var client = makeClient();
client.listTransactions(test.account, 15, function(err, txs) {
assert.ifError(err);
assert.ok(txs);
assert.ok(Array.isArray(txs));
done();
});
});
it('should be able to listTransactions without specific count', function (done) {
var client = makeClient()
client.listTransactions(test.account, function (err, txs) {
assert.ifError(err)
assert.ok(txs)
assert.ok(Array.isArray(txs))
done()
})
})
})
it('should be able to listTransactions without specific count', function(done) {
var client = makeClient();
client.listTransactions(test.account, function(err, txs) {
assert.ifError(err);
assert.ok(txs);
assert.ok(Array.isArray(txs));
done();
});
});
});
describe('getNewAddress()', function () {
it('should be able to get new address', function (done) {
var client = makeClient()
client.getNewAddress(test.account, function (err, address) {
assert.ifError(err)
client.getAddressesByAccount(test.account, function (err, addresses) {
assert.ifError(err)
assert.ok(addresses && addresses.length > 0)
done()
})
})
})
})
describe('getNewAddress()', function() {
it('should be able to get new address', function(done) {
var client = makeClient();
client.getNewAddress(test.account, function(err, address) {
assert.ifError(err);
client.getAddressesByAccount(test.account, function(err, addresses) {
assert.ifError(err);
assert.ok(addresses && addresses.length > 0);
done();
});
});
});
});
describe('getBalance()', function () {
it('should return balance without any args', function (done) {
var client = makeClient()
client.getBalance(function (err, balance) {
assert.ifError(err)
assert.ok(typeof balance === 'number')
done()
})
})
})
describe('getBalance()', function() {
it('should return balance without any args', function(done) {
var client = makeClient();
client.getBalance(function(err, balance) {
assert.ifError(err);
assert.ok(typeof balance === 'number');
done();
});
});
});
describe('getDifficulty()', function () {
it('should get difficulty', function (done) {
var client = makeClient()
client.getDifficulty(function (err, difficulty) {
assert.ifError(err)
assert.ok(typeof difficulty === 'number')
done()
})
})
})
describe('getDifficulty()', function() {
it('should get difficulty', function(done) {
var client = makeClient();
client.getDifficulty(function(err, difficulty) {
assert.ifError(err);
assert.ok(typeof difficulty === 'number');
done();
});
});
});
describe('getInfo()', function () {
it('should get info', function (done) {
var client = makeClient()
client.getInfo(function (err, info, headers) {
assert.ifError(err)
notEmpty(info)
assert.ok(info.errors === '')
done()
})
})
})
describe('getInfo()', function() {
it('should get info', function(done) {
var client = makeClient();
client.getInfo(function(err, info, headers) {
assert.ifError(err);
notEmpty(info);
assert.ok(info.errors === '');
done();
});
});
});
describe('help()', function () {
it('should return help', function (done) {
var client = makeClient()
client.help(function (err, help) {
assert.ifError(err)
notEmpty(help)
done()
})
})
})
describe('getHashesPerSec()', function() {
it('should get hashes per second', function(done) {
var client = makeClient();
client.getHashesPerSec(function(err, data) {
assert.ifError(err);
notEmpty(data);
assert.ok(typeof data === 'number');
done();
});
});
});
it('bitcoin related error should be an Error object', function (done) {
var client = makeClient()
client.cmd('nomethod', function (err, expectedValue) {
assert.ok(err instanceof Error)
assert.equal(err.message, 'Method not found')
assert.equal(err.code, -32601)
assert.equal(expectedValue, undefined)
done()
})
})
describe('help()', function() {
it('should return help', function(done) {
var client = makeClient();
client.help(function(err, help) {
assert.ifError(err);
notEmpty(help);
done();
});
});
});
describe('getWork()', function() {
it('should get work', function(done) {
var client = makeClient();
client.getWork(function(err, work) {
assert.ifError(err);
notEmpty(work);
done();
});
});
});
it('bitcoin related error should be an Error object', function(done) {
var client = makeClient();
client.cmd('nomethod', function(err, expectedValue) {
assert.ok(err instanceof Error);
assert.equal(err.message, 'Method not found');
assert.equal(err.code, -32601);
assert.equal(expectedValue, undefined);
done();
});
});
it('running batch of rpc calls', function(done) {
this.timeout(5000);
var batch = [];
it('running batch of rpc calls', function (done) {
this.timeout(5000)
var batch = []
for (var i = 0; i < 10; ++i) {
batch.push({
method: 'getnewaddress',
params: [test.account]
});
})
}
var client = makeClient();
var batchCallbackCount = 0;
client.cmd(batch, function(err, address) {
assert.ifError(err);
assert.ok(++batchCallbackCount <= 10);
assert.ok(address);
if (batchCallbackCount === 10) done();
});
});
var client = makeClient()
var batchCallbackCount = 0
client.cmd(batch, function (err, address) {
assert.ifError(err)
assert.ok(++batchCallbackCount <= 10)
assert.ok(address)
if (batchCallbackCount === 10) done()
})
})
describe('invalid credentials', function() {
var badCredentials = clone(config);
badCredentials.user = 'baduser';
badCredentials.pass = 'badpwd';
var client = new bitcoin.Client(badCredentials);
describe('invalid credentials', function () {
var badCredentials = clone(config)
badCredentials.user = 'baduser'
badCredentials.pass = 'badpwd'
var client = new bitcoin.Client(badCredentials)
it('should still return client object', function(done) {
assert.ok(client instanceof bitcoin.Client);
done();
});
it('should still return client object', function (done) {
assert.ok(client instanceof bitcoin.Client)
done()
})
it('should return status 401 with html', function(done) {
client.getDifficulty(function(err, difficulty) {
assert.ok(err instanceof Error);
assert.equal(err.message, 'Invalid params, response status code: 401');
assert.equal(err.code, -32602);
assert.equal(difficulty, undefined);
done();
});
});
});
it('should return status 401 with html', function (done) {
client.getDifficulty(function (err, difficulty) {
assert.ok(err instanceof Error)
assert.equal(err.message, 'Invalid params, response status code: 401')
assert.equal(err.code, -32602)
assert.equal(difficulty, undefined)
done()
})
})
})
describe('creating client on non-listening port', function() {
var badPort = clone(config);
badPort.port = 9897;
badPort.user = 'baduser';
badPort.pass = 'badpwd';
var client = new bitcoin.Client(badPort);
describe('creating client on non-listening port', function () {
var badPort = clone(config)
badPort.port = 9897
badPort.user = 'baduser'
badPort.pass = 'badpwd'
var client = new bitcoin.Client(badPort)
it('will return client object', function(done) {
assert.ok(client instanceof bitcoin.Client);
done();
});
it('will return client object', function (done) {
assert.ok(client instanceof bitcoin.Client)
done()
})
it('should not call callback more than once', function(done) {
client.listSinceBlock(function(err, result) {
assert.ok(err instanceof Error);
done();
});
});
});
it('should not call callback more than once', function (done) {
client.listSinceBlock(function (err, result) {
assert.ok(err instanceof Error)
done()
})
})
})
describe('request timeouts', function() {
it('should occur by default after 30000ms', function(done) {
this.timeout(31000);
var server = makeServer(19998);
var request;
var response;
server.on('request', function(req, res) {
request = req;
response = res;
});
describe('request timeouts', function () {
it('should occur by default after 30000ms', function (done) {
this.timeout(31000)
var server = makeServer(19998)
var request // eslint-disable-line no-unused-vars
var response
server.on('request', function (req, res) {
request = req
response = res
})
var client = new bitcoin.Client({
host: 'localhost',
port: 19998,
user: 'admin1',
pass: '123'
});
var start = Date.now();
client.getInfo(function(err, info) {
var delta = Date.now() - start;
assert.ok(err instanceof Error);
assert.ok(err.code === 'ETIMEDOUT' || err.code === 'ESOCKETTIMEDOUT');
assert.ok(delta >= 30000, 'delta should be >= 30000: ' + delta);
response.end();
server.close();
done();
});
});
})
var start = Date.now()
client.getInfo(function (err, info) {
var delta = Date.now() - start
assert.ok(err instanceof Error)
assert.ok(err.code === 'ETIMEDOUT' || err.code === 'ESOCKETTIMEDOUT')
assert.ok(delta >= 30000, 'delta should be >= 30000: ' + delta)
response.end()
server.close()
done()
})
})
it('should be customizable', function(done) {
this.timeout(4500);
var server = makeServer(19999);
var request;
var response;
server.on('request', function(req, res) {
request = req;
response = res;
});
it('should be customizable', function (done) {
this.timeout(4500)
var server = makeServer(19999)
var request // eslint-disable-line no-unused-vars
var response
server.on('request', function (req, res) {
request = req
response = res
})
var client = new bitcoin.Client({
host: 'localhost',
port: 19999,
user: 'admin1',
pass: '123',
timeout: 2500
});
var start = Date.now();
client.getInfo(function(err, info) {
var delta = Date.now() - start;
assert.ok(err instanceof Error);
assert.ok(err.code === 'ETIMEDOUT' || err.code === 'ESOCKETTIMEDOUT');
assert.ok(delta >= 2500, 'delta should be >= 2500:' + delta);
response.end();
server.close();
done();
});
});
})
var start = Date.now()
client.getInfo(function (err, info) {
var delta = Date.now() - start
assert.ok(err instanceof Error)
assert.ok(err.code === 'ETIMEDOUT' || err.code === 'ESOCKETTIMEDOUT')
assert.ok(delta >= 2500, 'delta should be >= 2500:' + delta)
response.end()
server.close()
done()
})
})
})
});
describe('response headers', function () {
var assertResHeaders = function (resHeaders) {
assert.ok(resHeaders)
assert.ok(resHeaders.server)
assert.ok(/bitcoin/.test(resHeaders.server))
}
it('should be returned for no parameter calls', function (done) {
var client = makeClient()
client.getInfo(function (err, info, resHeaders) {
assert.ifError(err)
notEmpty(info)
assert.ok(info.errors === '')
assertResHeaders(resHeaders)
done()
})
})
describe('response headers', function() {
var assertResHeaders = function(resHeaders) {
assert.ok(resHeaders);
assert.ok(resHeaders.server);
assert.ok(/bitcoin/.test(resHeaders.server));
};
it('should be returned for no parameter calls', function(done) {
var client = makeClient();
client.getInfo(function(err, info, resHeaders) {
assert.ifError(err);
notEmpty(info);
assert.ok(info.errors === '');
assertResHeaders(resHeaders);
done();
});
});
it('should be returned for 1-parameter call', function (done) {
var client = makeClient()
client.getNewAddress(test.account, function (err, address, resHeaders) {
assert.ifError(err)
assert.ok(address)
assertResHeaders(resHeaders)
done()
})
it('should be returned for 1-parameter call', function(done) {
var client = makeClient();
client.getNewAddress(test.account, function(err, address, resHeaders) {
assert.ifError(err);
assert.ok(address);
assertResHeaders(resHeaders);
done();
});
it('should be returned for 2-parameter call', function(done) {
var client = makeClient();
client.listTransactions(test.account, 15, function(err, txs, resHeaders) {
assert.ifError(err);
assert.ok(txs);
assert.ok(Array.isArray(txs));
assertResHeaders(resHeaders);
done();
});
});
});
});
});
it('should be returned for 2-parameter call', function (done) {
var client = makeClient()
client.listTransactions(test.account, 15, function (err, txs, resHeaders) {
assert.ifError(err)
assert.ok(txs)
assert.ok(Array.isArray(txs))
assertResHeaders(resHeaders)
done()
})
})
})
})
})

View File

@ -1,78 +1,75 @@
var assert = require('assert'),
bitcoin = require('../'),
config = require('./config'),
commands = require('../lib/commands');
var getHelpCommands = function(client, cb) {
var commandRegex = /^([a-z]+)/;
client.cmd('help', function(err, commandList) {
if (err) return cb(err);
var helpCommands = [];
/* global describe, it */
var assert = require('assert')
var bitcoin = require('../')
var config = require('./config')
var commands = require('../lib/commands')
var getHelpCommands = function (client, cb) {
var commandRegex = /^([a-z]+)/
client.cmd('help', function (err, commandList) {
if (err) return cb(err)
var helpCommands = []
// split up the command list by newlines
var commandListLines = commandList.split('\n');
var result;
var commandListLines = commandList.split('\n')
var result
for (var i in commandListLines) {
result = commandRegex.exec(commandListLines[i]);
if (!result) {
return cb(new Error('command list line failed to match regex: ' + commandListLines[i]));
}
helpCommands.push(result[1]);
result = commandRegex.exec(commandListLines[i])
if (!result) continue
helpCommands.push(result[1])
}
cb(null, helpCommands);
});
};
describe('Client Commands', function() {
it('should have all the commands listed by `help`', function(done) {
var client = new bitcoin.Client(config);
getHelpCommands(client, function(err, helpCommands) {
assert.ifError(err);
cb(null, helpCommands)
})
}
describe('Client Commands', function () {
it('should have all the commands listed by `help`', function (done) {
var client = new bitcoin.Client(config)
getHelpCommands(client, function (err, helpCommands) {
assert.ifError(err)
for (var i in helpCommands) {
var found = true;
var found = false
for (var j in commands) {
if (commands[j] === helpCommands[i]) {
found = true;
break;
found = true
break
}
}
assert.ok(found, 'missing command found in `help`: ' + helpCommands[i]);
assert.ok(found, 'missing command found in `help`: ' + helpCommands[i])
}
done();
});
});
it('should not have any commands not listed by `help`', function(done) {
var client = new bitcoin.Client(config);
getHelpCommands(client, function(err, helpCommands) {
assert.ifError(err);
done()
})
})
it('should not have any commands not listed by `help`', function (done) {
var client = new bitcoin.Client(config)
getHelpCommands(client, function (err, helpCommands) {
assert.ifError(err)
for (var i in commands) {
var found = false;
var found = false
for (var j in helpCommands) {
if (commands[i] === helpCommands[j]) {
found = true;
break;
found = true
break
}
}
// ignore commands not found in help because they are hidden
// if the wallet isn't encrypted
var ignore = ['walletlock', 'walletpassphrase', 'walletpassphrasechange'];
var ignore = ['walletlock', 'walletpassphrase', 'walletpassphrasechange']
if (~ignore.indexOf(commands[i])) {
assert.ok(!found, 'command found in `help`: ' + commands[i]);
assert.ok(!found, 'command found in `help`: ' + commands[i])
} else {
assert.ok(found, 'command not found in `help`: ' + commands[i]);
assert.ok(found, 'command not found in `help`: ' + commands[i])
}
}
done();
});
});
});
done()
})
})
})

View File

@ -1,62 +1,63 @@
var assert = require('assert'),
fs = require('fs'),
clone = require('clone'),
bitcoin = require('../'),
config = require('./config');
/* global describe, it */
var getInfo = function(opts, cb) {
var client = new bitcoin.Client(opts);
client.getInfo(cb);
};
var assert = require('assert')
var fs = require('fs')
var clone = require('clone')
var bitcoin = require('../')
var config = require('./config')
describe('Client SSL', function() {
it('use sslStrict by default', function(done) {
var opts = clone(config);
opts.ssl = true;
getInfo(opts, function(err, info) {
assert.ok(err instanceof Error);
var getInfo = function (opts, cb) {
var client = new bitcoin.Client(opts)
client.getInfo(cb)
}
describe('Client SSL', function () {
it('use sslStrict by default', function (done) {
var opts = clone(config)
opts.ssl = true
getInfo(opts, function (err, info) {
assert.ok(err instanceof Error)
// node v0.11 adds `code` param to this error
// and uses a user-friendly `message`
// continue using err.message for v0.8 and v0.10
assert.equal(err.code || err.message, 'DEPTH_ZERO_SELF_SIGNED_CERT');
done();
});
});
assert.equal(err.code || err.message, 'DEPTH_ZERO_SELF_SIGNED_CERT')
done()
})
})
it('strictSSL should fail with self-signed certificate', function(done) {
var opts = clone(config);
opts.ssl = true;
opts.sslStrict = true;
getInfo(opts, function(err, info) {
assert.ok(err instanceof Error);
it('strictSSL should fail with self-signed certificate', function (done) {
var opts = clone(config)
opts.ssl = true
opts.sslStrict = true
getInfo(opts, function (err, info) {
assert.ok(err instanceof Error)
// node v0.11 adds `code` param to this error
// and uses a user-friendly `message`
// continue using err.message for v0.8 and v0.10
assert.equal(err.code || err.message, 'DEPTH_ZERO_SELF_SIGNED_CERT');
done();
});
});
assert.equal(err.code || err.message, 'DEPTH_ZERO_SELF_SIGNED_CERT')
done()
})
})
it('self-signed certificate with sslStrict false', function(done) {
var opts = clone(config);
opts.ssl = true;
opts.sslStrict = false;
getInfo(opts, function(err, info) {
assert.ifError(err);
assert.ok(info);
done();
});
});
it('self-signed certificate with sslStrict false', function (done) {
var opts = clone(config)
opts.ssl = true
opts.sslStrict = false
getInfo(opts, function (err, info) {
assert.ifError(err)
assert.ok(info)
done()
})
})
it('self-signed certificate with sslStrict and CA specified', function(done) {
var opts = clone(config);
opts.ssl = true;
opts.sslCa = fs.readFileSync(__dirname + '/testnet-box/1/regtest/server.cert');
getInfo(opts, function(err, info) {
assert.ifError(err);
assert.ok(info);
done();
});
});
});
it('self-signed certificate with sslStrict and CA specified', function (done) {
var opts = clone(config)
opts.ssl = true
opts.sslCa = fs.readFileSync(__dirname + '/testnet-box/1/regtest/server.cert')
getInfo(opts, function (err, info) {
assert.ifError(err)
assert.ok(info)
done()
})
})
})

@ -1 +1 @@
Subproject commit 54e884df1f49959b21cf4e2014424a172722ed5c
Subproject commit 24f5214acfddfec498cca21dd96dac480e9b9013