Skip to content

Commit 2dc2c48

Browse files
committed
client: Import hs-client into the project.
1 parent 6314c1a commit 2dc2c48

24 files changed

+3211
-61
lines changed

bin/hsd-cli

+264-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,267 @@
11
#!/usr/bin/env node
22

3-
'use strict';
3+
'use strict';
44

5-
require('hs-client/bin/hsd-cli');
5+
const Config = require('bcfg');
6+
const {NodeClient} = require('../lib/client');
7+
8+
// NOTE: This is part of generated `hs-client`.
9+
// Don't introduce any unnecessary dependencies to this.
10+
// This needs to be remain as is for hs-client to be simple.
11+
12+
const ports = {
13+
main: 12037,
14+
testnet: 13037,
15+
regtest: 14037,
16+
simnet: 15037
17+
};
18+
19+
const HELP = `
20+
Commands:
21+
$ block [hash/height]: View block.
22+
$ broadcast [tx-hex]: Broadcast transaction.
23+
$ coin [hash+index/address]: View coins.
24+
$ header [hash/height]: View block header.
25+
$ help: Show help message.
26+
$ info: Get server info.
27+
$ mempool: Get mempool snapshot.
28+
$ reset [height/hash]: Reset chain to desired block.
29+
$ rpc [command] [args]: Execute RPC command.
30+
$ tx [hash/address]: View transactions.
31+
32+
For additional information and a complete list of commands
33+
visit https://hsd-dev.org/api-docs/
34+
`;
35+
36+
class CLI {
37+
constructor() {
38+
this.config = new Config('hsd', {
39+
suffix: 'network',
40+
fallback: 'main',
41+
alias: {
42+
'n': 'network',
43+
'u': 'url',
44+
'uri': 'url',
45+
'k': 'api-key',
46+
's': 'ssl',
47+
'h': 'httphost',
48+
'p': 'httpport'
49+
}
50+
});
51+
52+
this.config.load({
53+
argv: true,
54+
env: true
55+
});
56+
57+
this.config.open('hsd.conf');
58+
59+
this.argv = this.config.argv;
60+
this.network = this.config.str('network', 'main');
61+
62+
this.client = new NodeClient({
63+
url: this.config.str('url'),
64+
apiKey: this.config.str('api-key'),
65+
ssl: this.config.bool('ssl'),
66+
host: this.config.str('http-host'),
67+
port: this.config.uint('http-port')
68+
|| ports[this.network]
69+
|| ports.main,
70+
timeout: this.config.uint('timeout'),
71+
limit: this.config.uint('limit')
72+
});
73+
}
74+
75+
log(json) {
76+
if (typeof json === 'string')
77+
return console.log.apply(console, arguments);
78+
return console.log(JSON.stringify(json, null, 2));
79+
}
80+
81+
async getInfo() {
82+
const info = await this.client.getInfo();
83+
this.log(info);
84+
}
85+
86+
async getTX() {
87+
const hash = this.config.str(0, '');
88+
89+
if (hash.length !== 64) {
90+
const txs = await this.client.getTXByAddress(hash);
91+
this.log(txs);
92+
return;
93+
}
94+
95+
const tx = await this.client.getTX(hash);
96+
97+
if (!tx) {
98+
this.log('TX not found.');
99+
return;
100+
}
101+
102+
this.log(tx);
103+
}
104+
105+
async getBlock() {
106+
let hash = this.config.str(0, '');
107+
108+
if (hash.length !== 64)
109+
hash = parseInt(hash, 10);
110+
111+
const block = await this.client.getBlock(hash);
112+
113+
if (!block) {
114+
this.log('Block not found.');
115+
return;
116+
}
117+
118+
this.log(block);
119+
}
120+
121+
async getBlockHeader() {
122+
let hash = this.config.str(0, '');
123+
124+
if (hash.length !== 64)
125+
hash = parseInt(hash, 10);
126+
127+
const header = await this.client.getBlockHeader(hash);
128+
129+
if (!header) {
130+
this.log('Block header not found.');
131+
return;
132+
}
133+
134+
this.log(header);
135+
}
136+
137+
async getCoin() {
138+
const hash = this.config.str(0, '');
139+
const index = this.config.uint(1);
140+
141+
if (hash.length !== 64) {
142+
const coins = await this.client.getCoinsByAddress(hash);
143+
this.log(coins);
144+
return;
145+
}
146+
147+
const coin = await this.client.getCoin(hash, index);
148+
149+
if (!coin) {
150+
this.log('Coin not found.');
151+
return;
152+
}
153+
154+
this.log(coin);
155+
}
156+
157+
async getMempool() {
158+
const txs = await this.client.getMempool();
159+
160+
this.log(txs);
161+
}
162+
163+
async broadcast() {
164+
const raw = this.config.str([0, 'tx']);
165+
const tx = await this.client.broadcast(raw);
166+
167+
this.log('Broadcasted:');
168+
this.log(tx);
169+
}
170+
171+
async reset() {
172+
let hash = this.config.str(0);
173+
174+
if (hash.length !== 64)
175+
hash = parseInt(hash, 10);
176+
177+
await this.client.reset(hash);
178+
179+
this.log('Chain has been reset.');
180+
}
181+
182+
async rpc() {
183+
const method = this.argv.shift();
184+
if (!method) {
185+
this.log('Missing RPC method');
186+
return;
187+
}
188+
189+
const params = [];
190+
191+
for (const arg of this.argv) {
192+
let param;
193+
try {
194+
param = JSON.parse(arg);
195+
} catch (e) {
196+
param = arg;
197+
}
198+
params.push(param);
199+
}
200+
201+
let result;
202+
try {
203+
result = await this.client.execute(method, params);
204+
} catch (e) {
205+
if (e.type === 'RPCError') {
206+
this.log(e.message);
207+
return;
208+
}
209+
throw e;
210+
}
211+
212+
this.log(result);
213+
}
214+
215+
async open() {
216+
switch (this.argv.shift()) {
217+
case 'block':
218+
await this.getBlock();
219+
break;
220+
case 'broadcast':
221+
await this.broadcast();
222+
break;
223+
case 'coin':
224+
await this.getCoin();
225+
break;
226+
case 'header':
227+
await this.getBlockHeader();
228+
break;
229+
case 'help':
230+
process.stdout.write(HELP + '\n');
231+
break;
232+
case 'info':
233+
await this.getInfo();
234+
break;
235+
case 'mempool':
236+
await this.getMempool();
237+
break;
238+
case 'reset':
239+
await this.reset();
240+
break;
241+
case 'rpc':
242+
await this.rpc();
243+
break;
244+
case 'tx':
245+
await this.getTX();
246+
break;
247+
default:
248+
process.stdout.write('Unrecognized command.\n');
249+
process.stdout.write(HELP + '\n');
250+
break;
251+
}
252+
}
253+
254+
async destroy() {
255+
if (this.client && this.client.opened)
256+
await this.client.close();
257+
}
258+
}
259+
260+
(async () => {
261+
const cli = new CLI();
262+
await cli.open();
263+
await cli.destroy();
264+
})().catch((err) => {
265+
console.error(err.stack);
266+
process.exit(1);
267+
});

bin/hsd-rpc

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#!/bin/sh
2+
3+
# NOTE: This is part of generated `hs-client`.
4+
5+
rl=0
6+
7+
if ! type perl > /dev/null 2>& 1; then
8+
if uname | grep -i 'darwin' > /dev/null; then
9+
echo 'hsd-rpc requires perl to start on OSX.' >& 2
10+
exit 1
11+
fi
12+
rl=1
13+
fi
14+
15+
if test $rl -eq 1; then
16+
file=$(readlink -f "$0")
17+
else
18+
file=$(perl -MCwd -e "print Cwd::realpath('$0')")
19+
fi
20+
21+
dir=$(dirname "$file")
22+
23+
exec "${dir}/hsd-cli" rpc "$@"

0 commit comments

Comments
 (0)