Skip to content

Commit 29751db

Browse files
Merge pull request #23 from keep-network/path-api-key
Support URL path in WebSocket connections
2 parents d12d429 + d07d089 commit 29751db

8 files changed

Lines changed: 96 additions & 90 deletions

File tree

.github/workflows/node.yml

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ jobs:
1111
lint:
1212
runs-on: ubuntu-latest
1313
steps:
14-
- uses: actions/checkout@v2
14+
- uses: actions/checkout@v4
1515

16-
- uses: actions/setup-node@v2
16+
- uses: actions/setup-node@v4
1717
with:
18-
node-version: "14.x"
18+
node-version: "20.x"
1919
cache: "npm"
2020

2121
- name: Install dependencies
@@ -27,15 +27,17 @@ jobs:
2727
test:
2828
runs-on: ubuntu-latest
2929
steps:
30-
- uses: actions/checkout@v2
30+
- uses: actions/checkout@v4
3131

32-
- uses: actions/setup-node@v2
32+
- uses: actions/setup-node@v4
3333
with:
34-
node-version: "14.x"
34+
node-version: "20.x"
3535
cache: "npm"
3636

3737
- name: Install dependencies
3838
run: npm install
3939

4040
- name: Run tests
4141
run: npm test
42+
env:
43+
ELECTRUM_API_KEY: ${{ secrets.ELECTRUM_API_KEY }}

example/example.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ async function main() {
44
const client = new ElectrumClient(
55
'electrum.bitaroo.net',
66
50002,
7-
'ssl'
7+
'ssl',
88
)
99

1010
try {
1111
await client.connect(
1212
'electrum-client-js', // optional client name
13-
'1.4.2' // optional protocol version
13+
'1.4.2', // optional protocol version
1414
)
1515

1616
const header = await client.blockchain_headers_subscribe()

src/electrum/client.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ const util = require('./util')
44
const keepAliveInterval = 450 * 1000 // 7.5 minutes as recommended by ElectrumX SESSION_TIMEOUT
55

66
class ElectrumClient extends SocketClient {
7-
constructor(host, port, protocol, options) {
8-
super(host, port, protocol, options)
7+
constructor(host, port, protocol, options, path) {
8+
super(host, port, protocol, options, path)
99
}
1010

1111
async connect(clientName, electrumProtocolVersion, persistencePolicy = {maxRetry: 10, callback: null}) {
@@ -75,7 +75,7 @@ class ElectrumClient extends SocketClient {
7575
}
7676
},
7777
keepAliveInterval,
78-
this // pass this context as an argument to function
78+
this, // pass this context as an argument to function
7979
)
8080
}
8181
}

src/socket/socket_client.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,13 @@ const TCPSocketClient = require('./socket_client_tcp')
66
const WebSocketClient = require('./socket_client_ws')
77

88
class SocketClient {
9-
constructor(host, port, protocol, options) {
9+
constructor(host, port, protocol, options, path) {
1010
this.id = 0
1111
this.host = host
1212
this.port = port
1313
this.protocol = protocol
1414
this.options = options
15+
this.path = path || ''
1516
this.status = 0
1617
this.callback_message_queue = {}
1718
this.events = new EventEmitter()
@@ -27,7 +28,7 @@ class SocketClient {
2728
break
2829
case 'ws':
2930
case 'wss':
30-
this.client = new WebSocketClient(this, host, port, protocol, options)
31+
this.client = new WebSocketClient(this, host, port, protocol, options, path)
3132
break
3233
default:
3334
throw new Error(`invalid protocol: [${protocol}]`)

src/socket/socket_client_ws.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,18 @@
22
const W3CWebSocket = require('websocket').w3cwebsocket
33

44
class WebSocketClient {
5-
constructor(self, host, port, protocol, options) {
5+
constructor(self, host, port, protocol, options, path) {
66
this.self = self
77
this.host = host
88
this.port = port
99
this.protocol = protocol
1010
this.options = options
11+
this.path = path || ''
1112
this.client = null
1213
}
1314

1415
async connect() {
15-
const url = `${this.protocol}://${this.host}:${this.port}`
16+
const url = `${this.protocol}://${this.host}:${this.port}${this.path}`
1617

1718
// TODO: Add docs
1819
// https://github.com/theturtle32/WebSocket-Node/blob/master/docs/W3CWebSocket.md#constructor
@@ -21,7 +22,7 @@ class WebSocketClient {
2122
undefined,
2223
undefined,
2324
undefined,
24-
this.options
25+
this.options,
2526
)
2627

2728
this.client = client

test/config.js

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,32 @@
1-
const servers = {
2-
tcp: {
3-
protocol: 'tcp', port: '50001', host: 'electrum.bitaroo.net',
1+
const ELECTRUM_API_KEY = process.env.ELECTRUM_API_KEY
2+
3+
const servers = [
4+
{
5+
protocol: 'tcp',
6+
port: 50001,
7+
host: 'electrum.bitaroo.net',
48
},
5-
ssl: {
6-
protocol: 'ssl', port: '50002', host: 'electrum.bitaroo.net',
9+
{
10+
protocol: 'ssl',
11+
port: 50002,
12+
host: 'electrum.bitaroo.net',
713
},
8-
ws: {
9-
protocol: 'ws', port: '50003', host: 'electrumx-server.tbtc.svc.cluster.local',
14+
// no server available to test ws://
15+
{
16+
protocol: 'wss',
17+
port: 8443,
18+
host: 'electrumx-server.tbtc.network',
19+
// FIXME: It's a temporary workaround to get the connection working.
20+
options: {rejectUnauthorized: false},
1021
},
11-
wss: {
12-
protocol: 'wss', port: '50004', host: 'electrumx-server.tbtc.svc.cluster.local',
22+
{
23+
protocol: 'wss',
24+
port: 443,
25+
host: 'electrum.mainnet.boar.network',
26+
path: `/${ELECTRUM_API_KEY}`,
1327
},
14-
}
15-
16-
const serversArray = [
17-
servers.tcp,
18-
servers.ssl,
19-
// FIXME: WebSocket is commented out for CI, until we find public servers for this protocol.
20-
// electrumServers.ws,
21-
// electrumServers.wss,
2228
]
2329

2430
module.exports = {
2531
servers,
26-
serversArray,
2732
}

test/integration_test.js

Lines changed: 51 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -5,76 +5,73 @@ const assert = chai.assert
55

66
const fs = require('fs')
77

8-
const config = require('./config')
8+
const {servers} = require('./config')
99

1010
describe('ElectrumClient', async () => {
1111
let txData
1212

1313
before(async () => {
14-
txData = JSON.parse(await fs.readFileSync('./test/tx.json', 'utf8'))
14+
txData = JSON.parse(fs.readFileSync('./test/tx.json', 'utf8'))
1515
})
1616

17-
context('when connected', async () => {
18-
config.serversArray.forEach((server) => {
19-
describe(`for ${server.protocol} protocol`, async () => {
20-
let client
17+
describe('for all protocols', async () => {
18+
servers.forEach((server) => {
19+
const label = `${server.protocol}://${server.host}:${server.port}${server.path || ''}`
20+
describe(label, async () => {
21+
describe('when connected', async () => {
22+
let client
2123

22-
before(async () => {
23-
client = new ElectrumClient(
24-
server.host,
25-
server.port,
26-
server.protocol,
27-
server.options
28-
)
24+
before(async () => {
25+
client = new ElectrumClient(
26+
server.host,
27+
server.port,
28+
server.protocol,
29+
server.options,
30+
server.path,
31+
)
2932

30-
await client
31-
.connect('test_client' + server.protocol, '1.4.2')
32-
.catch((err) => {
33-
console.error(
34-
`failed to connect with config [${JSON.stringify(
35-
server
36-
)}]: [${err}]`
37-
)
38-
})
39-
})
33+
await client.connect('test_client' + server.protocol, '1.4.2')
34+
})
4035

41-
after(async () => {
42-
await client.close()
43-
})
36+
after(async () => {
37+
await client.close()
38+
})
4439

45-
it('request returns result', async () => {
46-
const expectedResult = txData.hex
47-
const result = await client.blockchain_transaction_get(txData.hash)
40+
it('request returns result', async () => {
41+
const expectedResult = txData.hex
42+
const result = await client.blockchain_transaction_get(txData.hash)
4843

49-
assert.equal(result, expectedResult, 'unexpected result')
44+
assert.equal(result, expectedResult, 'unexpected result')
45+
})
5046
})
51-
})
52-
})
53-
})
5447

55-
context('when not connected', async () => {
56-
before(async () => {
57-
const server = config.servers.tcp
48+
describe('when not connected', async () => {
49+
let client
5850

59-
client = new ElectrumClient(
60-
server.host,
61-
server.port,
62-
server.protocol,
63-
server.options
64-
)
65-
})
51+
before(async () => {
52+
client = new ElectrumClient(
53+
server.host,
54+
server.port,
55+
server.protocol,
56+
server.options,
57+
server.path,
58+
)
59+
})
6660

67-
it('request throws error', async () => {
68-
await client.blockchain_transaction_get(txData.hash).then(
69-
(value) => {
70-
// onFulfilled
71-
assert.fail('not failed as expected')
72-
},
73-
(reason) => {
74-
// onRejected
75-
assert.include(reason.toString(), `connection not established`)
76-
}
77-
)
61+
it('request throws error', async () => {
62+
await client.blockchain_transaction_get(txData.hash).then(
63+
(value) => {
64+
// onFulfilled
65+
assert.fail('not failed as expected')
66+
},
67+
(reason) => {
68+
// onRejected
69+
assert.include(reason.toString(), `connection not established`)
70+
},
71+
)
72+
})
73+
})
74+
})
7875
})
7976
})
8077
// TODO: Add tests

test/tx.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
{
2-
"hash": "d60033c5cf5c199208a9c656a29967810c4e428c22efb492fdd816e6a0a1e548",
3-
"hex": "010000000001011746bd867400f3494b8f44c24b83e1aa58c4f0ff25b4a61cffeffd4bc0f9ba300000000000ffffffff024897070000000000220020a4333e5612ab1a1043b25755c89b16d55184a42f81799e623e6bc39db8539c180000000000000000166a14edb1b5c2f39af0fec151732585b1049b07895211024730440220276e0ec78028582054d86614c65bc4bf85ff5710b9d3a248ca28dd311eb2fa6802202ec950dd2a8c9435ff2d400cc45d7a4854ae085f49e05cc3f503834546d410de012103732783eef3af7e04d3af444430a629b16a9261e4025f52bf4d6d026299c37c7400000000"
2+
"hash": "a000b3082c3e177a5ba2064b74a87ef830f8107f3fb9f9274dde4ed79bb93008",
3+
"hex": "02000000000103570412f893ca49eb1c42b6d22e385e8e281220eeb4b9526a77e3394a524a2bb80000000000ffffffffc7bf20bcf7643a91cb26410477a1066f1552c63b0f74175bb2a3169b2388cd2e0000000000ffffffffce1a14ab30f6e28ea6ee79469fed744b6b50c6e54583679da8ed00580bbe069f0300000000ffffffff0240420f0000000000220020f531e77ae36368687c262a7da1a89d7f22c48ab709cd83afe08e34c6db6952b90f4900000000000016001409da2b5bbfbe73460db900e09ec6745b65877c0b0248304502210095d6517ecaf5278c692ec72298088ac50f0e9f5afebd7418b4d8ad7cc59fa04202204bbb7c509344cee31982da546f01ab2cf2436425637769b1d4d9a4687ea4ff0601210387947b950113f035a5ffc732912670ebb34db4a97f6e3dd4ada2205b3994a2340248304502210090100e56b3c97b496fd9f9e83b31c26bd957be254826ff9bead8a95081e1851f02200c9d15825c4fa8ceb56828e8338b008791cb6d241f7f597e6587038aefb0aedb01210387947b950113f035a5ffc732912670ebb34db4a97f6e3dd4ada2205b3994a2340247304402204d1f7ba9de4889c9af06988de1142079f0f59ee3296b7acc5bb17cdda415260702200599898d448ee0798e9ced9eef059fc41d2a3c34b8526597d92655f64d6deacb01210387947b950113f035a5ffc732912670ebb34db4a97f6e3dd4ada2205b3994a23400000000"
44
}

0 commit comments

Comments
 (0)