lightning 4.10.1 → 4.10.5
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 +9 -0
- package/grpc/protos/lightning.proto +20 -0
- package/grpc/protos/signer.proto +3 -0
- package/lnd_messages/close_channel_request.js +35 -0
- package/lnd_messages/index.js +5 -0
- package/lnd_messages/open_channel_request.js +51 -0
- package/lnd_messages/pay_via_route_request.js +61 -0
- package/lnd_methods/index.js +2 -0
- package/lnd_methods/macaroon/accept_rpc_request.js +44 -0
- package/lnd_methods/macaroon/handle_rpc_request_update.js +148 -0
- package/lnd_methods/macaroon/methods.json +9 -5
- package/lnd_methods/macaroon/reject_rpc_request.js +52 -0
- package/lnd_methods/macaroon/subscribe_to_rpc_requests.js +150 -49
- package/lnd_methods/macaroon/uris_for_method.js +8 -5
- package/lnd_methods/offchain/get_failed_payments.js +190 -0
- package/lnd_methods/offchain/get_payments.js +1 -3
- package/lnd_methods/offchain/index.js +2 -0
- package/lnd_methods/offchain/probe_for_route.js +5 -0
- package/lnd_responses/rpc_invoice_as_invoice.js +4 -2
- package/lnd_responses/rpc_payment_as_payment.js +71 -21
- package/package.json +3 -3
- package/test/lnd_messages/test_close_channel_request.js +72 -0
- package/test/lnd_messages/test_open_channel_request.js +87 -0
- package/test/lnd_messages/test_pay_via_route_request.js +79 -0
- package/test/lnd_methods/macaroon/test_accept_rpc_request.js +37 -0
- package/test/lnd_methods/macaroon/test_handle_rpc_request_update.js +237 -0
- package/test/lnd_methods/macaroon/test_reject_rpc_request.js +41 -0
- package/test/lnd_methods/macaroon/test_subscribe_to_rpc_requests.js +242 -0
- package/test/lnd_methods/macaroon/test_uris_for_method.js +10 -0
- package/test/lnd_methods/offchain/test_get_failed_payments.js +160 -0
- package/test/lnd_methods/offchain/test_get_payments.js +2 -2
- package/test/lnd_methods/onchain/test_close_channel.js +0 -1
- package/test/lnd_responses/test_rpc_invoice_as_invoice.js +34 -0
- package/test/lnd_responses/test_rpc_payment_as_payment.js +43 -8
- package/test/protos/protos.json +4 -4
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
const {parsePaymentRequest} = require('invoices');
|
|
2
|
+
|
|
1
3
|
const rpcAttemptHtlcAsAttempt = require('./rpc_attempt_htlc_as_attempt');
|
|
2
4
|
const {safeTokens} = require('./../bolt00');
|
|
3
5
|
|
|
6
|
+
const emptyHash = Buffer.alloc(32).toString('hex');
|
|
4
7
|
const {isArray} = Array;
|
|
5
8
|
const msPerSecond = 1e3;
|
|
6
9
|
const nanoSecsPerMillisecond = BigInt(1e6);
|
|
@@ -129,9 +132,9 @@ const routePublicKeys = route => route.hops.map(n => n.public_key);
|
|
|
129
132
|
}
|
|
130
133
|
}]
|
|
131
134
|
created_at: <Payment at ISO-8601 Date String>
|
|
132
|
-
destination: <Destination Node Public Key Hex String>
|
|
133
|
-
fee: <Paid Routing Fee Rounded Down Tokens Number>
|
|
134
|
-
fee_mtokens: <Paid Routing Fee in Millitokens String>
|
|
135
|
+
[destination]: <Destination Node Public Key Hex String>
|
|
136
|
+
[fee]: <Paid Routing Fee Rounded Down Tokens Number>
|
|
137
|
+
[fee_mtokens]: <Paid Routing Fee in Millitokens String>
|
|
135
138
|
hops: [<First Route Hop Public Key Hex String>]
|
|
136
139
|
id: <Payment Preimage Hash String>
|
|
137
140
|
[index]: <Payment Add Index Number>
|
|
@@ -139,9 +142,9 @@ const routePublicKeys = route => route.hops.map(n => n.public_key);
|
|
|
139
142
|
is_outgoing: <Transaction Is Outgoing Bool>
|
|
140
143
|
mtokens: <Millitokens Sent to Destination String>
|
|
141
144
|
[request]: <BOLT 11 Payment Request String>
|
|
142
|
-
safe_fee: <Payment Forwarding Fee Rounded Up Tokens Number>
|
|
143
|
-
safe_tokens: <Payment Tokens Rounded Up Number>
|
|
144
|
-
secret: <Payment Preimage Hex String>
|
|
145
|
+
[safe_fee]: <Payment Forwarding Fee Rounded Up Tokens Number>
|
|
146
|
+
safe_tokens: <Payment Tokens Sent to Destination Rounded Up Number>
|
|
147
|
+
[secret]: <Payment Preimage Hex String>
|
|
145
148
|
tokens: <Rounded Down Tokens Sent to Destination Number>
|
|
146
149
|
}
|
|
147
150
|
*/
|
|
@@ -186,13 +189,46 @@ module.exports = payment => {
|
|
|
186
189
|
throw new Error('ExpectedPaymentValueInRpcPaymentDetails');
|
|
187
190
|
}
|
|
188
191
|
|
|
192
|
+
const creationDateEpochMs = (() => {
|
|
193
|
+
// Exit early when creation time nanoseconds is not defined
|
|
194
|
+
if (payment.creation_time_ns === Number().toString()) {
|
|
195
|
+
return Number(payment.creation_date) * msPerSecond;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
return Number(BigInt(payment.creation_time_ns) / nanoSecsPerMillisecond);
|
|
199
|
+
})();
|
|
200
|
+
|
|
189
201
|
const attempts = payment.htlcs.map(htlc => rpcAttemptHtlcAsAttempt(htlc));
|
|
202
|
+
const index = Number(payment.payment_index) || undefined;
|
|
203
|
+
const request = payment.payment_request || undefined;
|
|
204
|
+
|
|
205
|
+
// Exit early when there were no attempts
|
|
206
|
+
if (!attempts.length) {
|
|
207
|
+
const {destination} = !!request ? parsePaymentRequest({request}) : {};
|
|
190
208
|
|
|
191
|
-
|
|
192
|
-
|
|
209
|
+
return {
|
|
210
|
+
attempts,
|
|
211
|
+
destination,
|
|
212
|
+
index,
|
|
213
|
+
request,
|
|
214
|
+
confirmed_at: undefined,
|
|
215
|
+
created_at: new Date(creationDateEpochMs).toISOString(),
|
|
216
|
+
fee: undefined,
|
|
217
|
+
fee_mtokens: undefined,
|
|
218
|
+
hops: [],
|
|
219
|
+
id: payment.payment_hash,
|
|
220
|
+
is_confirmed: false,
|
|
221
|
+
is_outgoing: true,
|
|
222
|
+
mtokens: payment.value_msat,
|
|
223
|
+
safe_fee: undefined,
|
|
224
|
+
safe_tokens: safeTokens({mtokens: payment.value_msat}).safe,
|
|
225
|
+
secret: undefined,
|
|
226
|
+
tokens: safeTokens({mtokens: payment.value_msat}).tokens,
|
|
227
|
+
};
|
|
193
228
|
}
|
|
194
229
|
|
|
195
230
|
const hasPath = !!payment.path.length;
|
|
231
|
+
const hasPreimage = payment.payment_preimage !== emptyHash;
|
|
196
232
|
const [attempt] = attempts;
|
|
197
233
|
const successes = attempts.filter(n => n.is_confirmed);
|
|
198
234
|
|
|
@@ -201,32 +237,46 @@ module.exports = payment => {
|
|
|
201
237
|
|
|
202
238
|
const [destination, ...hops] = path.reverse();
|
|
203
239
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
240
|
+
// Exit early when the payment was never settled
|
|
241
|
+
if (!hasPreimage) {
|
|
242
|
+
return {
|
|
243
|
+
attempts,
|
|
244
|
+
destination,
|
|
245
|
+
index,
|
|
246
|
+
request,
|
|
247
|
+
confirmed_at: undefined,
|
|
248
|
+
created_at: new Date(creationDateEpochMs).toISOString(),
|
|
249
|
+
fee: undefined,
|
|
250
|
+
fee_mtokens: undefined,
|
|
251
|
+
hops: hops.reverse(),
|
|
252
|
+
id: payment.payment_hash,
|
|
253
|
+
is_confirmed: false,
|
|
254
|
+
is_outgoing: true,
|
|
255
|
+
mtokens: payment.value_msat,
|
|
256
|
+
safe_fee: undefined,
|
|
257
|
+
safe_tokens: safeTokens({mtokens: payment.value_msat}).safe,
|
|
258
|
+
secret: undefined,
|
|
259
|
+
tokens: safeTokens({mtokens: payment.value_msat}).tokens,
|
|
260
|
+
};
|
|
261
|
+
}
|
|
212
262
|
|
|
213
263
|
return {
|
|
264
|
+
attempts,
|
|
214
265
|
destination,
|
|
215
|
-
|
|
266
|
+
index,
|
|
267
|
+
request,
|
|
216
268
|
confirmed_at: confirmedAt || undefined,
|
|
217
269
|
created_at: new Date(creationDateEpochMs).toISOString(),
|
|
218
270
|
fee: safeTokens({mtokens: payment.fee_msat}).tokens,
|
|
219
271
|
fee_mtokens: payment.fee_msat,
|
|
220
272
|
hops: hops.reverse(),
|
|
221
273
|
id: payment.payment_hash,
|
|
222
|
-
|
|
223
|
-
is_confirmed: payment.value_msat !== Number().toString(),
|
|
274
|
+
is_confirmed: true,
|
|
224
275
|
is_outgoing: true,
|
|
225
276
|
mtokens: payment.value_msat,
|
|
226
|
-
request: payment.payment_request || undefined,
|
|
227
|
-
secret: payment.payment_preimage,
|
|
228
277
|
safe_fee: safeTokens({mtokens: payment.fee_msat}).safe,
|
|
229
278
|
safe_tokens: safeTokens({mtokens: payment.value_msat}).safe,
|
|
279
|
+
secret: payment.payment_preimage,
|
|
230
280
|
tokens: safeTokens({mtokens: payment.value_msat}).tokens,
|
|
231
281
|
};
|
|
232
282
|
};
|
package/package.json
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"@grpc/grpc-js": "1.3.7",
|
|
11
11
|
"@grpc/proto-loader": "0.6.5",
|
|
12
12
|
"@types/express": "4.17.13",
|
|
13
|
-
"@types/node": "16.10.
|
|
13
|
+
"@types/node": "16.10.3",
|
|
14
14
|
"@types/request": "2.48.7",
|
|
15
15
|
"@types/ws": "8.2.0",
|
|
16
16
|
"async": "3.2.1",
|
|
@@ -49,12 +49,12 @@
|
|
|
49
49
|
"url": "https://github.com/alexbosworth/lightning.git"
|
|
50
50
|
},
|
|
51
51
|
"scripts": {
|
|
52
|
-
"test": "tap --branches=1 --functions=1 --lines=1 --statements=1 -t 120 test/arrays/*.js test/bolt00/*.js test/bolt02/*.js test/grpc/*.js test/lnd_gateway/*.js test/lnd_grpc/*.js test/lnd_methods/address/*.js test/lnd_methods/generic/*.js test/lnd_methods/info/*.js test/lnd_methods/invoices/*.js test/lnd_methods/macaroon/*.js test/lnd_methods/message/*.js test/lnd_methods/offchain/*.js test/lnd_methods/onchain/*.js test/lnd_methods/peers/*.js test/lnd_methods/signer/*.js test/lnd_methods/unauthenticated/*.js test/lnd_requests/*.js test/lnd_responses/*.js && npm run test:types",
|
|
52
|
+
"test": "tap --branches=1 --functions=1 --lines=1 --statements=1 -t 120 test/arrays/*.js test/bolt00/*.js test/bolt02/*.js test/grpc/*.js test/lnd_gateway/*.js test/lnd_grpc/*.js test/lnd_messages/*.js test/lnd_methods/address/*.js test/lnd_methods/generic/*.js test/lnd_methods/info/*.js test/lnd_methods/invoices/*.js test/lnd_methods/macaroon/*.js test/lnd_methods/message/*.js test/lnd_methods/offchain/*.js test/lnd_methods/onchain/*.js test/lnd_methods/peers/*.js test/lnd_methods/signer/*.js test/lnd_methods/unauthenticated/*.js test/lnd_requests/*.js test/lnd_responses/*.js && npm run test:types",
|
|
53
53
|
"test:types": "tsd"
|
|
54
54
|
},
|
|
55
55
|
"tsd": {
|
|
56
56
|
"directory": "test/typescript"
|
|
57
57
|
},
|
|
58
58
|
"types": "index.d.ts",
|
|
59
|
-
"version": "4.10.
|
|
59
|
+
"version": "4.10.5"
|
|
60
60
|
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
const {test} = require('@alexbosworth/tap');
|
|
2
|
+
|
|
3
|
+
const {closeChannelRequest} = require('./../../lnd_messages');
|
|
4
|
+
|
|
5
|
+
const makeArgs = overrides => {
|
|
6
|
+
const args = {
|
|
7
|
+
channel_point: {
|
|
8
|
+
funding_txid_bytes: Buffer.from('010203', 'hex'),
|
|
9
|
+
output_index: 0,
|
|
10
|
+
},
|
|
11
|
+
delivery_address: 'delivery_address',
|
|
12
|
+
force: true,
|
|
13
|
+
sat_per_byte: '1',
|
|
14
|
+
target_conf: 1,
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
Object.keys(overrides).forEach(k => args[k] = overrides[k]);
|
|
18
|
+
|
|
19
|
+
return args;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const makeExpected = overrides => {
|
|
23
|
+
const args = {
|
|
24
|
+
address: 'delivery_address',
|
|
25
|
+
is_force_close: true,
|
|
26
|
+
target_confirmations: 1,
|
|
27
|
+
tokens_per_vbyte: 1,
|
|
28
|
+
transaction_id: '030201',
|
|
29
|
+
transaction_vout: 0,
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
Object.keys(overrides).forEach(k => args[k] = overrides[k]);
|
|
33
|
+
|
|
34
|
+
return args;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const tests = [
|
|
38
|
+
{
|
|
39
|
+
args: makeArgs({}),
|
|
40
|
+
description: 'Close request is converted to close request details',
|
|
41
|
+
expected: makeExpected({}),
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
args: makeArgs({
|
|
45
|
+
delivery_address: '',
|
|
46
|
+
force: false,
|
|
47
|
+
sat_per_byte: '0',
|
|
48
|
+
target_conf: 0,
|
|
49
|
+
}),
|
|
50
|
+
description: 'Defaults are selected',
|
|
51
|
+
expected: makeExpected({
|
|
52
|
+
address: undefined,
|
|
53
|
+
is_force_close: undefined,
|
|
54
|
+
target_confirmations: undefined,
|
|
55
|
+
tokens_per_vbyte: undefined,
|
|
56
|
+
}),
|
|
57
|
+
},
|
|
58
|
+
];
|
|
59
|
+
|
|
60
|
+
tests.forEach(({args, description, error, expected}) => {
|
|
61
|
+
return test(description, ({end, equal, strictSame, throws}) => {
|
|
62
|
+
if (!!error) {
|
|
63
|
+
throws(() => closeChannelRequest(args), new Error(error), 'Got error');
|
|
64
|
+
} else {
|
|
65
|
+
const res = closeChannelRequest(args);
|
|
66
|
+
|
|
67
|
+
strictSame(res, expected, 'Got expected result');
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return end();
|
|
71
|
+
});
|
|
72
|
+
});
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
const {test} = require('@alexbosworth/tap');
|
|
2
|
+
|
|
3
|
+
const {openChannelRequest} = require('./../../lnd_messages');
|
|
4
|
+
|
|
5
|
+
const makeArgs = overrides => {
|
|
6
|
+
const args = {
|
|
7
|
+
close_address: 'close_address',
|
|
8
|
+
local_funding_amount: '1',
|
|
9
|
+
min_htlc_msat: '1',
|
|
10
|
+
node_pubkey: Buffer.alloc(33, 3),
|
|
11
|
+
node_pubkey_string: Buffer.alloc(33, 3).toString('hex'),
|
|
12
|
+
private: false,
|
|
13
|
+
push_sat: '1',
|
|
14
|
+
remote_csv_delay: 1,
|
|
15
|
+
sat_per_byte: '1',
|
|
16
|
+
sat_per_vbyte: '1',
|
|
17
|
+
spend_unconfirmed: true,
|
|
18
|
+
target_conf: 1,
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
Object.keys(overrides).forEach(k => args[k] = overrides[k]);
|
|
22
|
+
|
|
23
|
+
return args;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const makeExpected = overrides => {
|
|
27
|
+
const args = {
|
|
28
|
+
chain_fee_tokens_per_vbyte: 1,
|
|
29
|
+
cooperative_close_address: 'close_address',
|
|
30
|
+
give_tokens: 1,
|
|
31
|
+
is_private: undefined,
|
|
32
|
+
local_tokens: 1,
|
|
33
|
+
min_confirmations: 0,
|
|
34
|
+
min_htlc_mtokens: '1',
|
|
35
|
+
partner_public_key: Buffer.alloc(33, 3).toString('hex'),
|
|
36
|
+
partner_csv_delay: 1,
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
Object.keys(overrides).forEach(k => args[k] = overrides[k]);
|
|
40
|
+
|
|
41
|
+
return args;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const tests = [
|
|
45
|
+
{
|
|
46
|
+
args: makeArgs({}),
|
|
47
|
+
description: 'Open request is converted to open request details',
|
|
48
|
+
expected: makeExpected({}),
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
args: makeArgs({
|
|
52
|
+
close_address: undefined,
|
|
53
|
+
min_htlc_msat: '0',
|
|
54
|
+
node_pubkey: Buffer.alloc(0),
|
|
55
|
+
private: true,
|
|
56
|
+
push_sat: '0',
|
|
57
|
+
remote_csv_delay: 0,
|
|
58
|
+
sat_per_byte: '0',
|
|
59
|
+
sat_per_vbyte: '0',
|
|
60
|
+
spend_unconfirmed: false,
|
|
61
|
+
}),
|
|
62
|
+
description: 'Defaults are selected',
|
|
63
|
+
expected: makeExpected({
|
|
64
|
+
chain_fee_tokens_per_vbyte: undefined,
|
|
65
|
+
cooperative_close_address: undefined,
|
|
66
|
+
give_tokens: undefined,
|
|
67
|
+
is_private: true,
|
|
68
|
+
min_confirmations: undefined,
|
|
69
|
+
min_htlc_mtokens: undefined,
|
|
70
|
+
partner_csv_delay: undefined,
|
|
71
|
+
}),
|
|
72
|
+
},
|
|
73
|
+
];
|
|
74
|
+
|
|
75
|
+
tests.forEach(({args, description, error, expected}) => {
|
|
76
|
+
return test(description, ({end, equal, strictSame, throws}) => {
|
|
77
|
+
if (!!error) {
|
|
78
|
+
throws(() => openChannelRequest(args), new Error(error), 'Got error');
|
|
79
|
+
} else {
|
|
80
|
+
const res = openChannelRequest(args);
|
|
81
|
+
|
|
82
|
+
strictSame(res, expected, 'Got expected result');
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return end();
|
|
86
|
+
});
|
|
87
|
+
});
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
const {test} = require('@alexbosworth/tap');
|
|
2
|
+
|
|
3
|
+
const {payViaRouteRequest} = require('./../../lnd_messages');
|
|
4
|
+
|
|
5
|
+
const makeArgs = overrides => {
|
|
6
|
+
const args = {
|
|
7
|
+
payment_hash: Buffer.alloc(32),
|
|
8
|
+
route: {
|
|
9
|
+
hops: [{
|
|
10
|
+
amt_to_forward_msat: '1',
|
|
11
|
+
chan_id: '1',
|
|
12
|
+
chan_capacity: 1,
|
|
13
|
+
custom_records: {},
|
|
14
|
+
expiry: 1,
|
|
15
|
+
pub_key: Buffer.alloc(33, 3).toString('hex'),
|
|
16
|
+
fee_msat: '1',
|
|
17
|
+
tlv_payload: true,
|
|
18
|
+
}],
|
|
19
|
+
total_amt_msat: '1',
|
|
20
|
+
total_fees_msat: '1',
|
|
21
|
+
total_time_lock: 1,
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
Object.keys(overrides).forEach(k => args[k] = overrides[k]);
|
|
26
|
+
|
|
27
|
+
return args;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const makeExpected = overrides => {
|
|
31
|
+
const args = {
|
|
32
|
+
id: Buffer.alloc(32).toString('hex'),
|
|
33
|
+
route: {
|
|
34
|
+
fee: 0,
|
|
35
|
+
fee_mtokens: '1',
|
|
36
|
+
hops: [{
|
|
37
|
+
channel: '0x0x1',
|
|
38
|
+
channel_capacity: 1,
|
|
39
|
+
fee: 0,
|
|
40
|
+
fee_mtokens: '1',
|
|
41
|
+
forward: 0,
|
|
42
|
+
forward_mtokens: '1',
|
|
43
|
+
public_key: Buffer.alloc(33, 3).toString('hex'),
|
|
44
|
+
timeout: 1,
|
|
45
|
+
}],
|
|
46
|
+
mtokens: '1',
|
|
47
|
+
payment: undefined,
|
|
48
|
+
timeout: 1,
|
|
49
|
+
tokens: 0,
|
|
50
|
+
total_mtokens: undefined,
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
Object.keys(overrides).forEach(k => args[k] = overrides[k]);
|
|
55
|
+
|
|
56
|
+
return args;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const tests = [
|
|
60
|
+
{
|
|
61
|
+
args: makeArgs({}),
|
|
62
|
+
description: 'Pay via route request is converted to pay details',
|
|
63
|
+
expected: makeExpected({}),
|
|
64
|
+
},
|
|
65
|
+
];
|
|
66
|
+
|
|
67
|
+
tests.forEach(({args, description, error, expected}) => {
|
|
68
|
+
return test(description, ({end, equal, strictSame, throws}) => {
|
|
69
|
+
if (!!error) {
|
|
70
|
+
throws(() => payViaRouteRequest(args), new Error(error), 'Got error');
|
|
71
|
+
} else {
|
|
72
|
+
const res = payViaRouteRequest(args);
|
|
73
|
+
|
|
74
|
+
strictSame(res, expected, 'Got expected result');
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return end();
|
|
78
|
+
});
|
|
79
|
+
});
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
const {test} = require('@alexbosworth/tap');
|
|
2
|
+
|
|
3
|
+
const method = require('./../../../lnd_methods/macaroon/accept_rpc_request');
|
|
4
|
+
|
|
5
|
+
const tests = [
|
|
6
|
+
{
|
|
7
|
+
args: {},
|
|
8
|
+
description: 'A request id is required to accept an RPC request',
|
|
9
|
+
error: [400, 'ExpectedRequestIdToAcceptRpcRequest'],
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
args: {id: 1},
|
|
13
|
+
description: 'A subscription is required to accept an RPC request',
|
|
14
|
+
error: [400, 'ExpectedRpcSubscriptionToAcceptRpcRequest'],
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
args: {id: 1, subscription: {write: ({}, cbk) => cbk('err')}},
|
|
18
|
+
description: 'Request error passed back',
|
|
19
|
+
error: [503, 'UnexpectedErrorAcceptingRpcRequest', {err: 'err'}],
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
args: {id: 1, subscription: {write: ({}, cbk) => cbk()}},
|
|
23
|
+
description: 'Request accepted',
|
|
24
|
+
},
|
|
25
|
+
];
|
|
26
|
+
|
|
27
|
+
tests.forEach(({args, description, error, expected}) => {
|
|
28
|
+
return test(description, async ({end, equal, rejects}) => {
|
|
29
|
+
if (!!error) {
|
|
30
|
+
await rejects(() => method(args), error, 'Got expected error');
|
|
31
|
+
} else {
|
|
32
|
+
await method(args);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return end();
|
|
36
|
+
});
|
|
37
|
+
});
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
const {test} = require('@alexbosworth/tap');
|
|
2
|
+
|
|
3
|
+
const method = require('./../../../lnd_methods/macaroon/handle_rpc_request_update');
|
|
4
|
+
|
|
5
|
+
const tests = [
|
|
6
|
+
{
|
|
7
|
+
args: {
|
|
8
|
+
is_intercepting_close_channel_requests: true,
|
|
9
|
+
lnd: {
|
|
10
|
+
default: {
|
|
11
|
+
CloseChannel: {
|
|
12
|
+
requestDeserialize: () => ({
|
|
13
|
+
channel_point: {
|
|
14
|
+
funding_txid_bytes: Buffer.from('010203', 'hex'),
|
|
15
|
+
output_index: 0,
|
|
16
|
+
},
|
|
17
|
+
delivery_address: 'delivery_address',
|
|
18
|
+
force: true,
|
|
19
|
+
sat_per_byte: '1',
|
|
20
|
+
target_conf: 1,
|
|
21
|
+
}),
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
subscription: {},
|
|
26
|
+
update: {
|
|
27
|
+
request_id: '1',
|
|
28
|
+
raw_macaroon: Buffer.alloc(0),
|
|
29
|
+
custom_caveat_condition: '',
|
|
30
|
+
request: {
|
|
31
|
+
method_full_uri: '/lnrpc.Lightning/CloseChannel',
|
|
32
|
+
serialized: Buffer.alloc(0),
|
|
33
|
+
stream_rpc: false,
|
|
34
|
+
type_name: '',
|
|
35
|
+
},
|
|
36
|
+
intercept_type: 'request',
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
description: 'A RPC request update is handled',
|
|
40
|
+
expected: {
|
|
41
|
+
data: {
|
|
42
|
+
id: 1,
|
|
43
|
+
macaroon: undefined,
|
|
44
|
+
request: {
|
|
45
|
+
address: 'delivery_address',
|
|
46
|
+
is_force_close: true,
|
|
47
|
+
target_confirmations: 1,
|
|
48
|
+
tokens_per_vbyte: 1,
|
|
49
|
+
transaction_id: '030201',
|
|
50
|
+
transaction_vout: 0,
|
|
51
|
+
},
|
|
52
|
+
uri: '/lnrpc.Lightning/CloseChannel',
|
|
53
|
+
},
|
|
54
|
+
event: 'close_channel_request',
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
args: {
|
|
59
|
+
is_intercepting_open_channel_requests: true,
|
|
60
|
+
lnd: {
|
|
61
|
+
default: {
|
|
62
|
+
OpenChannel: {
|
|
63
|
+
requestDeserialize: () => ({
|
|
64
|
+
close_address: 'close_address',
|
|
65
|
+
local_funding_amount: '1',
|
|
66
|
+
min_htlc_msat: '1',
|
|
67
|
+
node_pubkey: Buffer.alloc(33, 3),
|
|
68
|
+
node_pubkey_string: Buffer.alloc(33, 3).toString('hex'),
|
|
69
|
+
private: false,
|
|
70
|
+
push_sat: '1',
|
|
71
|
+
remote_csv_delay: 1,
|
|
72
|
+
sat_per_byte: '1',
|
|
73
|
+
sat_per_vbyte: '1',
|
|
74
|
+
spend_unconfirmed: true,
|
|
75
|
+
target_conf: 1,
|
|
76
|
+
}),
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
subscription: {},
|
|
81
|
+
update: {
|
|
82
|
+
request_id: '1',
|
|
83
|
+
raw_macaroon: Buffer.alloc(0),
|
|
84
|
+
custom_caveat_condition: '',
|
|
85
|
+
request: {
|
|
86
|
+
method_full_uri: '/lnrpc.Lightning/OpenChannel',
|
|
87
|
+
serialized: Buffer.alloc(0),
|
|
88
|
+
stream_rpc: false,
|
|
89
|
+
type_name: '',
|
|
90
|
+
},
|
|
91
|
+
intercept_type: 'request',
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
description: 'A RPC request update is handled',
|
|
95
|
+
expected: {
|
|
96
|
+
data: {
|
|
97
|
+
id: 1,
|
|
98
|
+
macaroon: undefined,
|
|
99
|
+
request: {
|
|
100
|
+
chain_fee_tokens_per_vbyte: 1,
|
|
101
|
+
cooperative_close_address: 'close_address',
|
|
102
|
+
give_tokens: 1,
|
|
103
|
+
is_private: undefined,
|
|
104
|
+
local_tokens: 1,
|
|
105
|
+
min_confirmations: 0,
|
|
106
|
+
min_htlc_mtokens: '1',
|
|
107
|
+
partner_public_key: Buffer.alloc(33, 3).toString('hex'),
|
|
108
|
+
partner_csv_delay: 1,
|
|
109
|
+
},
|
|
110
|
+
uri: '/lnrpc.Lightning/OpenChannel',
|
|
111
|
+
},
|
|
112
|
+
event: 'open_channel_request',
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
args: {
|
|
117
|
+
is_intercepting_pay_via_routes_requests: true,
|
|
118
|
+
lnd: {
|
|
119
|
+
router: {
|
|
120
|
+
SendToRouteV2: {
|
|
121
|
+
requestDeserialize: () => ({
|
|
122
|
+
payment_hash: Buffer.alloc(32),
|
|
123
|
+
route: {
|
|
124
|
+
hops: [{
|
|
125
|
+
amt_to_forward_msat: '1',
|
|
126
|
+
chan_id: '1',
|
|
127
|
+
chan_capacity: 1,
|
|
128
|
+
custom_records: {},
|
|
129
|
+
expiry: 1,
|
|
130
|
+
pub_key: Buffer.alloc(33, 3).toString('hex'),
|
|
131
|
+
fee_msat: '1',
|
|
132
|
+
tlv_payload: true,
|
|
133
|
+
}],
|
|
134
|
+
total_amt_msat: '1',
|
|
135
|
+
total_fees_msat: '1',
|
|
136
|
+
total_time_lock: 1,
|
|
137
|
+
},
|
|
138
|
+
}),
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
subscription: {},
|
|
143
|
+
update: {
|
|
144
|
+
request_id: '1',
|
|
145
|
+
raw_macaroon: Buffer.alloc(0),
|
|
146
|
+
custom_caveat_condition: '',
|
|
147
|
+
request: {
|
|
148
|
+
method_full_uri: '/routerrpc.Router/SendToRouteV2',
|
|
149
|
+
serialized: Buffer.alloc(0),
|
|
150
|
+
stream_rpc: false,
|
|
151
|
+
type_name: '',
|
|
152
|
+
},
|
|
153
|
+
intercept_type: 'request',
|
|
154
|
+
},
|
|
155
|
+
},
|
|
156
|
+
description: 'A RPC request update is handled',
|
|
157
|
+
expected: {
|
|
158
|
+
data: {
|
|
159
|
+
id: 1,
|
|
160
|
+
macaroon: undefined,
|
|
161
|
+
request: {
|
|
162
|
+
id: Buffer.alloc(32).toString('hex'),
|
|
163
|
+
route: {
|
|
164
|
+
fee: 0,
|
|
165
|
+
fee_mtokens: '1',
|
|
166
|
+
hops: [{
|
|
167
|
+
channel: '0x0x1',
|
|
168
|
+
channel_capacity: 1,
|
|
169
|
+
fee: 0,
|
|
170
|
+
fee_mtokens: '1',
|
|
171
|
+
forward: 0,
|
|
172
|
+
forward_mtokens: '1',
|
|
173
|
+
public_key: Buffer.alloc(33, 3).toString('hex'),
|
|
174
|
+
timeout: 1,
|
|
175
|
+
}],
|
|
176
|
+
mtokens: '1',
|
|
177
|
+
payment: undefined,
|
|
178
|
+
timeout: 1,
|
|
179
|
+
tokens: 0,
|
|
180
|
+
total_mtokens: undefined,
|
|
181
|
+
},
|
|
182
|
+
},
|
|
183
|
+
uri: '/routerrpc.Router/SendToRouteV2',
|
|
184
|
+
},
|
|
185
|
+
event: 'pay_via_route_request',
|
|
186
|
+
},
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
args: {
|
|
190
|
+
subscription: {},
|
|
191
|
+
update: {
|
|
192
|
+
request_id: '1',
|
|
193
|
+
raw_macaroon: Buffer.alloc(0),
|
|
194
|
+
custom_caveat_condition: '',
|
|
195
|
+
stream_auth: {method_full_uri: 'method_full_uri'},
|
|
196
|
+
intercept_type: 'stream_auth',
|
|
197
|
+
},
|
|
198
|
+
},
|
|
199
|
+
description: 'A RPC request update is handled',
|
|
200
|
+
expected: {
|
|
201
|
+
data: {
|
|
202
|
+
id: 1,
|
|
203
|
+
macaroon: undefined,
|
|
204
|
+
uri: 'method_full_uri',
|
|
205
|
+
},
|
|
206
|
+
event: 'request',
|
|
207
|
+
},
|
|
208
|
+
},
|
|
209
|
+
];
|
|
210
|
+
|
|
211
|
+
tests.forEach(({args, description, error, expected}) => {
|
|
212
|
+
return test(description, async ({end, strictSame, throws}) => {
|
|
213
|
+
if (!!error) {
|
|
214
|
+
throws(() => method(args), new Error(error), 'Got expected error');
|
|
215
|
+
} else {
|
|
216
|
+
const res = method(args);
|
|
217
|
+
|
|
218
|
+
const {accept, id, macaroon, reject, request, uri} = res.data;
|
|
219
|
+
|
|
220
|
+
if (!!accept) {
|
|
221
|
+
try { await accept({}); } catch (err) {}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
if (!!reject) {
|
|
225
|
+
try { await reject({}); } catch (err) {}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
strictSame(id, expected.data.id, 'Got expected id');
|
|
229
|
+
strictSame(res.event, expected.event, 'Got expected event');
|
|
230
|
+
strictSame(macaroon, expected.data.macaroon, 'Got expected macaroon');
|
|
231
|
+
strictSame(request, expected.data.request, 'Got expected request');
|
|
232
|
+
strictSame(uri, expected.data.uri, 'Got expected uri');
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
return end();
|
|
236
|
+
});
|
|
237
|
+
});
|