Skip to content

Commit 95d212a

Browse files
committed
Improve client usage and deprecate old features
1 parent 1735261 commit 95d212a

15 files changed

+213
-568
lines changed

README.md

Lines changed: 9 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -23,59 +23,16 @@ npm install bitcoin-core --save
2323
## Usage
2424
### Client(...args)
2525
#### Arguments
26-
1. `[agentOptions]` _(Object)_: Optional `agent` [options](https://github.com/request/request#using-optionsagentoptions) to configure SSL/TLS.
27-
2. `[headers=false]` _(boolean)_: Whether to return the response headers.
28-
3. `[host=localhost]` _(string)_: The host to connect to.
29-
4. `[logger=debugnyan('bitcoin-core')]` _(Function)_: Custom logger (by default, `debugnyan`).
30-
5. `[network=mainnet]` _(string)_: The network
31-
6. `[password]` _(string)_: The RPC server user password.
32-
7. `[port=[network]]` _(string)_: The RPC server port.
33-
8. `[ssl]` _(boolean|Object)_: Whether to use SSL/TLS with strict checking (_boolean_) or an expanded config (_Object_).
34-
9. `[ssl.enabled]` _(boolean)_: Whether to use SSL/TLS.
35-
10. `[ssl.strict]` _(boolean)_: Whether to do strict SSL/TLS checking (certificate must match host).
36-
11. `[timeout=30000]` _(number)_: How long until the request times out (ms).
37-
12. `[username]` _(number)_: The RPC server user name.
38-
13. `[version]` _(string)_: Which version to check methods for ([read more](#versionchecking)).
39-
14. `[wallet]` _(string)_: Which wallet to manage ([read more](#multiwallet)).
26+
1. `[headers={}]` _(object)_: Custom request headers.
27+
2. `[host=http://localhost:8332]` _(string)_: The host to connect to.
28+
3. `[logger=debugnyan('bitcoin-core')]` _(Function)_: Custom logger (by default, `debugnyan`).
29+
4. `[password]` _(string)_: The RPC server user password.
30+
5. `[timeout=30000]` _(number)_: How long until the request times out (ms).
31+
6. `[username]` _(number)_: The RPC server user name.
32+
7. `[version]` _(string)_: Which version to check methods for ([read more](#versionchecking)).
33+
8. `[wallet]` _(string)_: Which wallet to manage ([read more](#multiwallet)).
4034

4135
### Examples
42-
#### Using network mode
43-
The `network` will automatically determine the port to connect to, just like the `bitcoind` and `bitcoin-cli` commands.
44-
45-
```js
46-
const Client = require('bitcoin-core');
47-
const client = new Client({ network: 'regtest' });
48-
```
49-
50-
##### Setting a custom port
51-
52-
```js
53-
const client = new Client({ port: 28332 });
54-
```
55-
56-
#### Connecting to an SSL/TLS server with strict checking enabled
57-
By default, when `ssl` is enabled, strict checking is implicitly enabled.
58-
59-
```js
60-
const fs = require('fs');
61-
const client = new Client({
62-
agentOptions: {
63-
ca: fs.readFileSync('/etc/ssl/bitcoind/cert.pem')
64-
},
65-
ssl: true
66-
});
67-
```
68-
69-
#### Connecting to an SSL/TLS server without strict checking enabled
70-
71-
```js
72-
const client = new Client({
73-
ssl: {
74-
enabled: true,
75-
strict: false
76-
}
77-
});
78-
```
7936

8037
#### Using promises to process the response
8138

@@ -91,19 +48,6 @@ Callback support was removed. Since every method returns a `Promise`, [callbacki
9148
util.callbackify(() => client.getInfo())((error, help) => console.log(help));
9249
```
9350

94-
#### Returning headers in the response
95-
For compatibility with other Bitcoin Core clients.
96-
97-
```js
98-
const client = new Client({ headers: true });
99-
100-
// Promise style with headers enabled:
101-
client.getInfo().then(([body, headers]) => console.log(body, headers));
102-
103-
// Await style based on promises with headers enabled:
104-
const [body, headers] = await client.getInfo();
105-
```
106-
10751
## Named parameters
10852

10953
Since version v0.14.0, it is possible to send commands via the JSON-RPC interface using named parameters instead of positional ones. This comes with the advantage of making the order of arguments irrelevant. It also helps improving the readability of certain function calls when leaving out arguments for their default value.
@@ -223,8 +167,6 @@ docker run --rm -it ruimarinho/bitcoin-core:0.12-alpine -printtoconsole -rpcuser
223167

224168
These configuration values may also be set on the `bitcoin.conf` file of your platform installation.
225169

226-
By default, port `8332` is used to listen for requests in `mainnet` mode, or `18332` in `testnet` and `regtest` modes (the regtest change will be changed to `18443` in [0.16](https://github.com/bitcoin/bitcoin/pull/10825)). Use the `network` property to initialize the client on the desired mode and automatically set the respective default port. You can optionally set a custom port of your choice too.
227-
228170
The RPC services binds to the localhost loopback network interface, so use `rpcbind` to change where to bind to and `rpcallowip` to whitelist source IP access.
229171

230172
#### Methods
@@ -386,58 +328,8 @@ client.getUnspentTransactionOutputs([{
386328
}], { extension: 'json' })
387329
```
388330

389-
### SSL
390-
This client supports SSL out of the box. Simply pass the SSL public certificate to the client and optionally disable strict SSL checking which will bypass SSL validation (the connection is still encrypted but the server it is connecting to may not be trusted). This is, of course, discouraged unless for testing purposes when using something like self-signed certificates.
391-
392-
#### Generating a self-signed certificates for testing purposes
393-
Please note that the following procedure should only be used for testing purposes.
394-
395-
Generate an self-signed certificate together with an unprotected private key:
396-
397-
```sh
398-
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 3650 -nodes
399-
```
400-
401331
#### Connecting via SSL
402-
On Bitcoin Core <0.12, you can start the `bitcoind` RPC server directly with SSL:
403-
404-
```sh
405-
docker run --rm -it -v $(PWD)/ssl:/etc/ssl ruimarinho/bitcoin-core:0.11-alpine -printtoconsole -rpcuser=foo -rpcpassword=bar -rpcssl -rpcsslcertificatechainfile=/etc/ssl/bitcoind/cert.pem -rpcsslprivatekeyfile=/etc/ssl/bitcoind/key.pem -server
406-
```
407-
408-
On Bitcoin Core >0.12, use must use `stunnel` (`brew install stunnel` or `sudo apt-get install stunnel4`) or an HTTPS reverse proxy to configure SSL since the built-in support for SSL has been removed. The trade off with `stunnel` is performance and simplicity versus features, as it lacks more powerful capacities such as Basic Authentication and caching which are standard in reverse proxies.
409-
410-
You can use `stunnel` by configuring `stunnel.conf` with the following service requirements:
411-
412-
```
413-
[bitcoin]
414-
accept = 28332
415-
connect = 18332
416-
cert = /etc/ssl/bitcoind/cert.pem
417-
key = /etc/ssl/bitcoind/key.pem
418-
```
419-
420-
The `key` option may be omitted if you concatenating your private and public certificates into a single `stunnel.pem` file.
421-
422-
On some versions of `stunnel` it is also possible to start a service using command line arguments. The equivalent would be:
423-
424-
```sh
425-
stunnel -d 28332 -r 127.0.0.1:18332 -p stunnel.pem -P ''
426-
```
427-
428-
Then pass the public certificate to the client:
429-
430-
```js
431-
const Client = require('bitcoin-core');
432-
const fs = require('fs');
433-
const client = new Client({
434-
agentOptions: {
435-
ca: fs.readFileSync('/etc/ssl/bitcoind/cert.pem')
436-
},
437-
port: 28332,
438-
ssl: true
439-
});
440-
```
332+
Deprecated since release 0.5.0.
441333

442334
## Logging
443335

docker-compose.yml

Lines changed: 13 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -2,38 +2,44 @@ version: '3.4'
22

33
services:
44
bitcoin-core:
5-
image: ruimarinho/bitcoin-core:0.17
5+
image: ruimarinho/bitcoin-core:24.0.1
66
command:
7+
-fallbackfee=0.0002
78
-printtoconsole
89
-regtest=1
910
-rest
10-
-rpcallowip=::/0
11+
-rpcallowip=0.0.0.0/0
12+
-rpcbind=0.0.0.0
1113
-rpcpassword=bar
1214
-rpcport=18443
1315
-rpcuser=foo
16+
-txindex=1
1417
-server
1518
ports:
16-
- 18443:18443
19+
- 18443:18443
1720
healthcheck:
18-
test: curl --fail "http://foo@localhost:18443/rest/chaininfo.json" || exit 1
21+
test: curl --fail "http://foo@bitcoin-core:18443/rest/chaininfo.json" || exit 1
1922
interval: 2s
2023
retries: 100
2124
start_period: 2s
2225
timeout: 2s
2326

2427
bitcoin-core-multi-wallet:
25-
image: ruimarinho/bitcoin-core:0.17
28+
image: ruimarinho/bitcoin-core:24.0.1
2629
command:
30+
-fallbackfee=0.0002
2731
-printtoconsole
2832
-regtest=1
2933
-rest
30-
-rpcallowip=::/0
34+
-rpcallowip=0.0.0.0/0
35+
-rpcbind=0.0.0.0
3136
-rpcpassword=bar
32-
-wallet
37+
-wallet=wallet
3338
-wallet=wallet1
3439
-wallet=wallet2
3540
-rpcport=18443
3641
-rpcuser=foo
42+
-txindex=1
3743
-server
3844
ports:
3945
- 18453:18443
@@ -43,47 +49,3 @@ services:
4349
retries: 100
4450
start_period: 2s
4551
timeout: 2s
46-
47-
bitcoin-core-ssl:
48-
image: ruimarinho/bitcoin-core:0.11
49-
command:
50-
-printtoconsole
51-
-regtest=1
52-
-rest
53-
-rpcallowip=::/0
54-
-rpcpassword=bar
55-
-rpcport=18443
56-
-rpcssl
57-
-rpcsslcertificatechainfile=/etc/ssl/bitcoind/cert.pem
58-
-rpcsslprivatekeyfile=/etc/ssl/bitcoind/key.pem
59-
-rpcuser=foo
60-
-server
61-
volumes:
62-
- ./test/config/ssl:/etc/ssl/bitcoind
63-
ports:
64-
- 18463:18443
65-
healthcheck:
66-
test: curl --fail -k "https://foo@localhost:18443/rest/chaininfo.json" || exit 1
67-
interval: 2s
68-
retries: 100
69-
start_period: 2s
70-
timeout: 2s
71-
72-
bitcoin-core-username-only:
73-
image: ruimarinho/bitcoin-core:0.11
74-
command:
75-
-printtoconsole
76-
-regtest=1
77-
-rest
78-
-rpcallowip=::/0
79-
-rpcport=18443
80-
-rpcuser=foo
81-
-server
82-
ports:
83-
- 18473:18443
84-
healthcheck:
85-
test: curl --fail "http://foo@localhost:18443/rest/chaininfo.json" || exit 1
86-
interval: 2s
87-
retries: 100
88-
start_period: 2s
89-
timeout: 2s

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
"scripts": {
2626
"changelog": "github_changelog_generator --project bitcoin-core --user ruimarinho --no-issues --header-label='# Changelog' --future-release=$npm_config_future_release && sed -i '' -e :a -e '$d;N;2,4ba' -e 'P;D' CHANGELOG.md",
2727
"cover": "nyc --reporter=html --reporter=text npm test",
28-
"dependencies": "docker-compose up -d bitcoind bitcoind-ssl bitcoind-username-only",
28+
"dependencies": "docker-compose up -d bitcoind bitcoind-username-only",
2929
"lint": "eslint src test",
3030
"test": "NODE_ENV=test mocha $npm_package_options_mocha",
3131
"testdocker": "docker-compose run --rm sut",

src/index.js

Lines changed: 15 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,6 @@ const methods = require('./methods');
1111
const requestLogger = require('./logging/request-logger');
1212
const semver = require('semver');
1313

14-
/**
15-
* List of networks and their default port mapping.
16-
*/
17-
18-
const networks = {
19-
mainnet: 8332,
20-
regtest: 18332,
21-
testnet: 18332
22-
};
23-
2414
/**
2515
* Promisify helper.
2616
*/
@@ -43,36 +33,20 @@ const promisify = fn => (...args) => new Promise((resolve, reject) => {
4333

4434
class Client {
4535
constructor({
46-
agentOptions,
47-
allowDefaultWallet = false,
48-
headers = false,
49-
host = 'localhost',
36+
headers = {},
37+
host = 'http://localhost:8332',
5038
logger = debugnyan('bitcoin-core'),
51-
network = 'mainnet',
5239
password,
53-
port,
54-
ssl = false,
5540
timeout = 30000,
5641
username,
5742
version,
5843
wallet
5944
} = {}) {
60-
if (!_.has(networks, network)) {
61-
throw new Error(`Invalid network name "${network}"`, { network });
62-
}
63-
64-
this.agentOptions = agentOptions;
65-
this.allowDefaultWallet = allowDefaultWallet;
6645
this.auth = (password || username) && { pass: password, user: username };
6746
this.hasNamedParametersSupport = false;
6847
this.headers = headers;
6948
this.host = host;
7049
this.password = password;
71-
this.port = port || networks[network];
72-
this.ssl = {
73-
enabled: _.get(ssl, 'enabled', ssl),
74-
strict: _.get(ssl, 'strict', _.get(ssl, 'enabled', ssl))
75-
};
7650
this.timeout = timeout;
7751
this.wallet = wallet;
7852

@@ -106,15 +80,14 @@ class Client {
10680
const request = requestLogger(logger);
10781

10882
this.request = request.defaults({
109-
agentOptions: this.agentOptions,
110-
baseUrl: `${this.ssl.enabled ? 'https' : 'http'}://${this.host}:${this.port}`,
111-
strictSSL: this.ssl.strict,
83+
baseUrl: this.host,
84+
headers: this.headers,
11285
timeout: this.timeout
11386
});
11487
this.request.getAsync = promisify(this.request.get);
11588
this.request.postAsync = promisify(this.request.post);
11689
this.requester = new Requester({ methods: this.methods, version });
117-
this.parser = new Parser({ headers: this.headers });
90+
this.parser = new Parser();
11891
}
11992

12093
/**
@@ -154,9 +127,18 @@ class Client {
154127
uri = '/wallet/';
155128
}
156129

130+
if (this.auth) {
131+
return this.parser.rpc(await this.request.postAsync({
132+
auth: _.pickBy(this.auth, _.identity),
133+
body: JSON.stringify(body),
134+
followRedirect: true,
135+
uri
136+
}));
137+
}
138+
157139
return this.parser.rpc(await this.request.postAsync({
158-
auth: _.pickBy(this.auth, _.identity),
159140
body: JSON.stringify(body),
141+
followRedirect: true,
160142
uri
161143
}));
162144
}

0 commit comments

Comments
 (0)