lightning 6.6.0 → 6.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md
CHANGED
|
@@ -6,8 +6,9 @@ const {isLnd} = require('./../../lnd_requests');
|
|
|
6
6
|
const bufferAsHex = buffer => buffer.toString('hex');
|
|
7
7
|
const errorNotFound = '-5: Block not found';
|
|
8
8
|
const errorUnknownMethod = 'unknown service chainrpc.ChainKit';
|
|
9
|
-
const
|
|
9
|
+
const hexAsReversedBuffer = hex => Buffer.from(hex, 'hex').reverse();
|
|
10
10
|
const {isBuffer} = Buffer;
|
|
11
|
+
const isNumber = n => !isNaN(n);
|
|
11
12
|
const isHash = n => /^[0-9A-F]{64}$/i.test(n);
|
|
12
13
|
const method = 'getBlock';
|
|
13
14
|
const type = 'blocks';
|
|
@@ -21,7 +22,8 @@ const type = 'blocks';
|
|
|
21
22
|
This method is not supported on LND 0.15.5 and below
|
|
22
23
|
|
|
23
24
|
{
|
|
24
|
-
|
|
25
|
+
[height]: <Block Height Number>
|
|
26
|
+
[id]: <Block Hash Hex String>
|
|
25
27
|
lnd: <Authenticated LND API Object>
|
|
26
28
|
}
|
|
27
29
|
|
|
@@ -30,15 +32,23 @@ const type = 'blocks';
|
|
|
30
32
|
block: <Raw Block Bytes Hex String>
|
|
31
33
|
}
|
|
32
34
|
*/
|
|
33
|
-
module.exports = ({id, lnd}, cbk) => {
|
|
35
|
+
module.exports = ({height, id, lnd}, cbk) => {
|
|
34
36
|
return new Promise((resolve, reject) => {
|
|
35
37
|
return asyncAuto({
|
|
36
38
|
// Check arguments
|
|
37
39
|
validate: cbk => {
|
|
38
|
-
if (!
|
|
40
|
+
if (height !== undefined && !isNumber(height)) {
|
|
41
|
+
return cbk([400, 'ExpectedNumericBlockHeightOfBlockToRetrieve']);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (!!id && !isHash(id)) {
|
|
39
45
|
return cbk([400, 'ExpectedIdentifyingBlockHashOfBlockToRetrieve']);
|
|
40
46
|
}
|
|
41
47
|
|
|
48
|
+
if (height !== undefined && !!id) {
|
|
49
|
+
return cbk([400, 'ExpectedEitherHeightOrIdNotBoth']);
|
|
50
|
+
}
|
|
51
|
+
|
|
42
52
|
if (!isLnd({lnd, method, type})) {
|
|
43
53
|
return cbk([400, 'ExpectedAuthenticatedLndToRetrieveBlock']);
|
|
44
54
|
}
|
|
@@ -46,9 +56,70 @@ module.exports = ({id, lnd}, cbk) => {
|
|
|
46
56
|
return cbk();
|
|
47
57
|
},
|
|
48
58
|
|
|
59
|
+
// Get the best block in the chain to find the default block hash
|
|
60
|
+
getTip: ['validate', ({}, cbk) => {
|
|
61
|
+
// Exit early when a specific block is requested
|
|
62
|
+
if (height !== undefined || !!id) {
|
|
63
|
+
return cbk();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return lnd[type].getBestBlock({}, (err, res) => {
|
|
67
|
+
if (!!err && err.details === errorUnknownMethod) {
|
|
68
|
+
return cbk([501, 'GetBestBlockMethodNotSupported']);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (!!err) {
|
|
72
|
+
return cbk([503, 'UnexpectedErrorGettingBestBlock', {err}]);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (!res) {
|
|
76
|
+
return cbk([503, 'ExpectedResponseForBestBlockRequest']);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (!isBuffer(res.block_hash)) {
|
|
80
|
+
return cbk([503, 'ExpectedChainTipInfoInGetBestBlockResponse']);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return cbk(null, res.block_hash);
|
|
84
|
+
});
|
|
85
|
+
}],
|
|
86
|
+
|
|
87
|
+
// Get the hash of the block to fetch
|
|
88
|
+
getHash: ['getTip', ({getTip}, cbk) => {
|
|
89
|
+
// Exit early when the hash to get is specified
|
|
90
|
+
if (!!id) {
|
|
91
|
+
return cbk(null, hexAsReversedBuffer(id));
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Exit early when the hash comes from the chain tip
|
|
95
|
+
if (!!getTip) {
|
|
96
|
+
return cbk(null, getTip);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return lnd[type].getBlockHash({block_height: height}, (err, res) => {
|
|
100
|
+
if (!!err && err.details === errorUnknownMethod) {
|
|
101
|
+
return cbk([501, 'GetBlockHashMethodNotSupported']);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (!!err) {
|
|
105
|
+
return cbk([503, 'UnexpectedErrorGettingBlockHash', {err}]);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (!res) {
|
|
109
|
+
return cbk([503, 'ExpectedResponseForGetBlockHashRequest']);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (!isBuffer(res.block_hash)) {
|
|
113
|
+
return cbk([503, 'ExpectedBlockHashInGetBlockHashResponse']);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return cbk(null, res.block_hash);
|
|
117
|
+
});
|
|
118
|
+
}],
|
|
119
|
+
|
|
49
120
|
// Get the block
|
|
50
|
-
getBlock: ['
|
|
51
|
-
return lnd[type][method]({block_hash:
|
|
121
|
+
getBlock: ['getHash', ({getHash}, cbk) => {
|
|
122
|
+
return lnd[type][method]({block_hash: getHash}, (err, res) => {
|
|
52
123
|
if (!!err && err.details === errorNotFound) {
|
|
53
124
|
return cbk([404, 'BlockNotFound']);
|
|
54
125
|
}
|
package/package.json
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"@grpc/grpc-js": "1.8.0",
|
|
11
11
|
"@grpc/proto-loader": "0.7.4",
|
|
12
12
|
"@types/express": "4.17.15",
|
|
13
|
-
"@types/node": "18.11.
|
|
13
|
+
"@types/node": "18.11.16",
|
|
14
14
|
"@types/request": "2.48.8",
|
|
15
15
|
"@types/ws": "8.5.3",
|
|
16
16
|
"async": "3.2.4",
|
|
@@ -59,5 +59,5 @@
|
|
|
59
59
|
"directory": "test/typescript"
|
|
60
60
|
},
|
|
61
61
|
"types": "index.d.ts",
|
|
62
|
-
"version": "6.
|
|
62
|
+
"version": "6.7.0"
|
|
63
63
|
}
|
|
@@ -4,15 +4,129 @@ const {getBlock} = require('./../../../lnd_methods');
|
|
|
4
4
|
|
|
5
5
|
const tests = [
|
|
6
6
|
{
|
|
7
|
-
args: {},
|
|
8
|
-
description: '
|
|
7
|
+
args: {height: 'invalid'},
|
|
8
|
+
description: 'A valid height is expected to get a block',
|
|
9
|
+
error: [400, 'ExpectedNumericBlockHeightOfBlockToRetrieve'],
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
args: {id: 'invalid'},
|
|
13
|
+
description: 'A valid id is expected to get a block',
|
|
9
14
|
error: [400, 'ExpectedIdentifyingBlockHashOfBlockToRetrieve'],
|
|
10
15
|
},
|
|
16
|
+
{
|
|
17
|
+
args: {height: 1, id: Buffer.alloc(32).toString('hex')},
|
|
18
|
+
description: 'Only a height or an id is required',
|
|
19
|
+
error: [400, 'ExpectedEitherHeightOrIdNotBoth'],
|
|
20
|
+
},
|
|
11
21
|
{
|
|
12
22
|
args: {id: Buffer.alloc(32).toString('hex')},
|
|
13
23
|
description: 'An lnd object is required to get a block',
|
|
14
24
|
error: [400, 'ExpectedAuthenticatedLndToRetrieveBlock'],
|
|
15
25
|
},
|
|
26
|
+
{
|
|
27
|
+
args: {
|
|
28
|
+
lnd: {
|
|
29
|
+
blocks: {
|
|
30
|
+
getBestBlock: ({}, cbk) => cbk({
|
|
31
|
+
details: 'unknown service chainrpc.ChainKit',
|
|
32
|
+
}),
|
|
33
|
+
getBlock: ({}, cbk) => cbk('err'),
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
description: 'An unsupported error is returned',
|
|
38
|
+
error: [501, 'GetBestBlockMethodNotSupported'],
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
args: {
|
|
42
|
+
lnd: {
|
|
43
|
+
blocks: {
|
|
44
|
+
getBestBlock: ({}, cbk) => cbk('err'),
|
|
45
|
+
getBlock: ({}, cbk) => cbk('getBlockErr'),
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
description: 'An error is returned',
|
|
50
|
+
error: [503, 'UnexpectedErrorGettingBestBlock', {err: 'err'}],
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
args: {
|
|
54
|
+
lnd: {
|
|
55
|
+
blocks: {
|
|
56
|
+
getBestBlock: ({}, cbk) => cbk(),
|
|
57
|
+
getBlock: ({}, cbk) => cbk(),
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
description: 'An error is returned when there is no best block result',
|
|
62
|
+
error: [503, 'ExpectedResponseForBestBlockRequest'],
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
args: {
|
|
66
|
+
lnd: {
|
|
67
|
+
blocks: {
|
|
68
|
+
getBestBlock: ({}, cbk) => cbk(null, {}),
|
|
69
|
+
getBlock: ({}, cbk) => cbk(),
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
description: 'An error is returned when there is no result info',
|
|
74
|
+
error: [503, 'ExpectedChainTipInfoInGetBestBlockResponse'],
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
args: {
|
|
78
|
+
height: 1,
|
|
79
|
+
lnd: {
|
|
80
|
+
blocks: {
|
|
81
|
+
getBlock: ({}, cbk) => cbk(),
|
|
82
|
+
getBlockHash: ({}, cbk) => cbk({
|
|
83
|
+
details: 'unknown service chainrpc.ChainKit',
|
|
84
|
+
}),
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
description: 'An error is returned when get hash for height unsupported',
|
|
89
|
+
error: [501, 'GetBlockHashMethodNotSupported'],
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
args: {
|
|
93
|
+
height: 1,
|
|
94
|
+
lnd: {
|
|
95
|
+
blocks: {
|
|
96
|
+
getBlock: ({}, cbk) => cbk(),
|
|
97
|
+
getBlockHash: ({}, cbk) => cbk('err'),
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
description: 'An unexpected error for getting block hash is returned',
|
|
102
|
+
error: [503, 'UnexpectedErrorGettingBlockHash', {err: 'err'}],
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
args: {
|
|
106
|
+
height: 1,
|
|
107
|
+
lnd: {
|
|
108
|
+
blocks: {
|
|
109
|
+
getBlock: ({}, cbk) => cbk(),
|
|
110
|
+
getBlockHash: ({}, cbk) => cbk(),
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
description: 'A result is expected for getting a block hash',
|
|
115
|
+
error: [503, 'ExpectedResponseForGetBlockHashRequest'],
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
args: {
|
|
119
|
+
height: 1,
|
|
120
|
+
lnd: {
|
|
121
|
+
blocks: {
|
|
122
|
+
getBlock: ({}, cbk) => cbk(),
|
|
123
|
+
getBlockHash: ({}, cbk) => cbk(null, {}),
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
description: 'A result hash is expected for getting a block hash',
|
|
128
|
+
error: [503, 'ExpectedBlockHashInGetBlockHashResponse'],
|
|
129
|
+
},
|
|
16
130
|
{
|
|
17
131
|
args: {
|
|
18
132
|
id: Buffer.alloc(32).toString('hex'),
|
|
@@ -63,6 +177,31 @@ const tests = [
|
|
|
63
177
|
description: 'A resulting block is expected',
|
|
64
178
|
error: [503, 'ExpectedRawBlockInChainBlockResponse'],
|
|
65
179
|
},
|
|
180
|
+
{
|
|
181
|
+
args: {
|
|
182
|
+
lnd: {
|
|
183
|
+
blocks: {
|
|
184
|
+
getBestBlock: ({}, cbk) => cbk(null, {block_hash: Buffer.alloc(1)}),
|
|
185
|
+
getBlock: ({}, cbk) => cbk(null, {raw_block: Buffer.alloc(1)}),
|
|
186
|
+
},
|
|
187
|
+
},
|
|
188
|
+
},
|
|
189
|
+
description: 'The chain tip block is returned',
|
|
190
|
+
expected: {block: '00'},
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
args: {
|
|
194
|
+
height: 1,
|
|
195
|
+
lnd: {
|
|
196
|
+
blocks: {
|
|
197
|
+
getBlock: ({}, cbk) => cbk(null, {raw_block: Buffer.alloc(1)}),
|
|
198
|
+
getBlockHash: ({}, cbk) => cbk(null, {block_hash: Buffer.alloc(1)}),
|
|
199
|
+
},
|
|
200
|
+
},
|
|
201
|
+
},
|
|
202
|
+
description: 'A block at a height is returned',
|
|
203
|
+
expected: {block: '00'},
|
|
204
|
+
},
|
|
66
205
|
{
|
|
67
206
|
args: {
|
|
68
207
|
id: Buffer.alloc(32).toString('hex'),
|