lightning 5.21.2 → 6.1.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 +10 -0
- package/README.md +2 -0
- package/grpc/protos/lightning.proto +10 -1
- package/grpc/protos/router.proto +19 -1
- package/grpc/protos/stateservice.proto +11 -0
- package/index.js +2 -0
- package/lnd_methods/index.js +2 -0
- package/lnd_methods/macaroon/methods.json +4 -0
- package/lnd_methods/offchain/index.js +2 -0
- package/lnd_methods/offchain/subscribe_to_payments.js +119 -0
- package/lnd_responses/pending_from_payment.js +0 -1
- package/lnd_responses/rpc_payment_as_payment.js +1 -15
- package/package.json +8 -8
- package/test/lnd_methods/offchain/test_get_payments.js +2 -2
- package/test/lnd_methods/offchain/test_subscribe_to_payments.js +167 -0
- package/test/lnd_responses/test_rpc_payment_as_payment.js +50 -34
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Versions
|
|
2
2
|
|
|
3
|
+
## 6.1.0
|
|
4
|
+
|
|
5
|
+
- `subscribeToPayments`: Add method to listen to all outgoing payments
|
|
6
|
+
|
|
7
|
+
## 6.0.0
|
|
8
|
+
|
|
9
|
+
### Breaking Changes
|
|
10
|
+
|
|
11
|
+
- Node.js version 14 or higher is now required
|
|
12
|
+
|
|
3
13
|
## 5.21.2
|
|
4
14
|
|
|
5
15
|
- `getChainFeeEstimate`: Add support for specifying min `utxo_confirmations`
|
package/README.md
CHANGED
|
@@ -315,6 +315,8 @@ variables set:
|
|
|
315
315
|
Make an off-chain payment using a payment request and subscribe to the payment status.
|
|
316
316
|
- [subscribeToPayViaRoutes](https://github.com/alexbosworth/ln-service#subscribetopayviaroutes):
|
|
317
317
|
Start an off-chain payment using specific payment routes and subscribe to the payment result.
|
|
318
|
+
- [subscribeToPayments](https://github.com/alexbosworth/ln-service#subscribetopayments):
|
|
319
|
+
Subscribe to off-chain payments going out and being resolved
|
|
318
320
|
- [subscribeToPeerMessages](https://github.com/alexbosworth/ln-service#subscribetopeermessages):
|
|
319
321
|
Listen for incoming peer messages.
|
|
320
322
|
- [subscribeToPeers](https://github.com/alexbosworth/ln-service#subscribetopeers): Listen to peer
|
|
@@ -637,6 +637,7 @@ enum OutputScriptType {
|
|
|
637
637
|
SCRIPT_TYPE_NULLDATA = 6;
|
|
638
638
|
SCRIPT_TYPE_NON_STANDARD = 7;
|
|
639
639
|
SCRIPT_TYPE_WITNESS_UNKNOWN = 8;
|
|
640
|
+
SCRIPT_TYPE_WITNESS_V1_TAPROOT = 9;
|
|
640
641
|
}
|
|
641
642
|
|
|
642
643
|
message OutputDetail {
|
|
@@ -2563,9 +2564,17 @@ message PendingChannelsResponse {
|
|
|
2563
2564
|
|
|
2564
2565
|
repeated PendingHTLC pending_htlcs = 8;
|
|
2565
2566
|
|
|
2567
|
+
/*
|
|
2568
|
+
There are three resolution states for the anchor:
|
|
2569
|
+
limbo, lost and recovered. Derive the current state
|
|
2570
|
+
from the limbo and recovered balances.
|
|
2571
|
+
*/
|
|
2566
2572
|
enum AnchorState {
|
|
2573
|
+
// The recovered_balance is zero and limbo_balance is non-zero.
|
|
2567
2574
|
LIMBO = 0;
|
|
2575
|
+
// The recovered_balance is non-zero.
|
|
2568
2576
|
RECOVERED = 1;
|
|
2577
|
+
// A state that is neither LIMBO nor RECOVERED.
|
|
2569
2578
|
LOST = 2;
|
|
2570
2579
|
}
|
|
2571
2580
|
|
|
@@ -3646,7 +3655,7 @@ message Payment {
|
|
|
3646
3655
|
// Deprecated, use creation_time_ns
|
|
3647
3656
|
int64 creation_date = 3 [deprecated = true];
|
|
3648
3657
|
|
|
3649
|
-
|
|
3658
|
+
reserved 4;
|
|
3650
3659
|
|
|
3651
3660
|
// Deprecated, use fee_sat or fee_msat.
|
|
3652
3661
|
int64 fee = 5 [deprecated = true];
|
package/grpc/protos/router.proto
CHANGED
|
@@ -22,6 +22,16 @@ service Router {
|
|
|
22
22
|
*/
|
|
23
23
|
rpc TrackPaymentV2 (TrackPaymentRequest) returns (stream lnrpc.Payment);
|
|
24
24
|
|
|
25
|
+
/*
|
|
26
|
+
TrackPayments returns an update stream for every payment that is not in a
|
|
27
|
+
terminal state. Note that if payments are in-flight while starting a new
|
|
28
|
+
subscription, the start of the payment stream could produce out-of-order
|
|
29
|
+
and/or duplicate events. In order to get updates for every in-flight
|
|
30
|
+
payment attempt make sure to subscribe to this method before initiating any
|
|
31
|
+
payments.
|
|
32
|
+
*/
|
|
33
|
+
rpc TrackPayments (TrackPaymentsRequest) returns (stream lnrpc.Payment);
|
|
34
|
+
|
|
25
35
|
/*
|
|
26
36
|
EstimateRouteFee allows callers to obtain a lower bound w.r.t how much it
|
|
27
37
|
may cost to send an HTLC to the target end destination.
|
|
@@ -303,6 +313,14 @@ message TrackPaymentRequest {
|
|
|
303
313
|
bool no_inflight_updates = 2;
|
|
304
314
|
}
|
|
305
315
|
|
|
316
|
+
message TrackPaymentsRequest {
|
|
317
|
+
/*
|
|
318
|
+
If set, only the final payment updates are streamed back. Intermediate
|
|
319
|
+
updates that show which htlcs are still in flight are suppressed.
|
|
320
|
+
*/
|
|
321
|
+
bool no_inflight_updates = 1;
|
|
322
|
+
}
|
|
323
|
+
|
|
306
324
|
message RouteFeeRequest {
|
|
307
325
|
/*
|
|
308
326
|
The destination once wishes to obtain a routing fee quote to.
|
|
@@ -697,7 +715,7 @@ enum PaymentState {
|
|
|
697
715
|
FAILED_NO_ROUTE = 3;
|
|
698
716
|
|
|
699
717
|
/*
|
|
700
|
-
A non-recoverable error has
|
|
718
|
+
A non-recoverable error has occurred.
|
|
701
719
|
*/
|
|
702
720
|
FAILED_ERROR = 4;
|
|
703
721
|
|
|
@@ -36,14 +36,25 @@ service State {
|
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
enum WalletState {
|
|
39
|
+
// NON_EXISTING means that the wallet has not yet been initialized.
|
|
39
40
|
NON_EXISTING = 0;
|
|
41
|
+
|
|
42
|
+
// LOCKED means that the wallet is locked and requires a password to unlock.
|
|
40
43
|
LOCKED = 1;
|
|
44
|
+
|
|
45
|
+
// UNLOCKED means that the wallet was unlocked successfully, but RPC server
|
|
46
|
+
// isn't ready.
|
|
41
47
|
UNLOCKED = 2;
|
|
48
|
+
|
|
49
|
+
// RPC_ACTIVE means that the lnd server is active but not fully ready for
|
|
50
|
+
// calls.
|
|
42
51
|
RPC_ACTIVE = 3;
|
|
43
52
|
|
|
44
53
|
// SERVER_ACTIVE means that the lnd server is ready to accept calls.
|
|
45
54
|
SERVER_ACTIVE = 4;
|
|
46
55
|
|
|
56
|
+
// WAITING_TO_START means that node is waiting to become the leader in a
|
|
57
|
+
// cluster and is not started yet.
|
|
47
58
|
WAITING_TO_START = 255;
|
|
48
59
|
}
|
|
49
60
|
|
package/index.js
CHANGED
|
@@ -123,6 +123,7 @@ const {subscribeToPastPayments} = require('./lnd_methods');
|
|
|
123
123
|
const {subscribeToPayViaDetails} = require('./lnd_methods');
|
|
124
124
|
const {subscribeToPayViaRequest} = require('./lnd_methods');
|
|
125
125
|
const {subscribeToPayViaRoutes} = require('./lnd_methods');
|
|
126
|
+
const {subscribeToPayments} = require('./lnd_methods');
|
|
126
127
|
const {subscribeToPeerMessages} = require('./lnd_methods');
|
|
127
128
|
const {subscribeToPeers} = require('./lnd_methods');
|
|
128
129
|
const {subscribeToProbeForRoute} = require('./lnd_methods');
|
|
@@ -271,6 +272,7 @@ module.exports = {
|
|
|
271
272
|
subscribeToPayViaDetails,
|
|
272
273
|
subscribeToPayViaRequest,
|
|
273
274
|
subscribeToPayViaRoutes,
|
|
275
|
+
subscribeToPayments,
|
|
274
276
|
subscribeToPeerMessages,
|
|
275
277
|
subscribeToPeers,
|
|
276
278
|
subscribeToProbeForRoute,
|
package/lnd_methods/index.js
CHANGED
|
@@ -120,6 +120,7 @@ const {subscribeToPastPayments} = require('./offchain');
|
|
|
120
120
|
const {subscribeToPayViaDetails} = require('./offchain');
|
|
121
121
|
const {subscribeToPayViaRequest} = require('./offchain');
|
|
122
122
|
const {subscribeToPayViaRoutes} = require('./offchain');
|
|
123
|
+
const {subscribeToPayments} = require('./offchain');
|
|
123
124
|
const {subscribeToPeerMessages} = require('./offchain');
|
|
124
125
|
const {subscribeToPeers} = require('./peers');
|
|
125
126
|
const {subscribeToProbeForRoute} = require('./offchain');
|
|
@@ -264,6 +265,7 @@ module.exports = {
|
|
|
264
265
|
subscribeToPayViaDetails,
|
|
265
266
|
subscribeToPayViaRequest,
|
|
266
267
|
subscribeToPayViaRoutes,
|
|
268
|
+
subscribeToPayments,
|
|
267
269
|
subscribeToPeerMessages,
|
|
268
270
|
subscribeToPeers,
|
|
269
271
|
subscribeToProbeForRoute,
|
|
@@ -46,6 +46,7 @@ const subscribeToPastPayments = require('./subscribe_to_past_payments');
|
|
|
46
46
|
const subscribeToPayViaDetails = require('./subscribe_to_pay_via_details');
|
|
47
47
|
const subscribeToPayViaRequest = require('./subscribe_to_pay_via_request');
|
|
48
48
|
const subscribeToPayViaRoutes = require('./subscribe_to_pay_via_routes');
|
|
49
|
+
const subscribeToPayments = require('./subscribe_to_payments');
|
|
49
50
|
const subscribeToPeerMessages = require('./subscribe_to_peer_messages');
|
|
50
51
|
const subscribeToProbeForRoute = require('./subscribe_to_probe_for_route');
|
|
51
52
|
const updateConnectedWatchtower = require('./update_connected_watchtower');
|
|
@@ -103,6 +104,7 @@ module.exports = {
|
|
|
103
104
|
subscribeToPayViaDetails,
|
|
104
105
|
subscribeToPayViaRequest,
|
|
105
106
|
subscribeToPayViaRoutes,
|
|
107
|
+
subscribeToPayments,
|
|
106
108
|
subscribeToPeerMessages,
|
|
107
109
|
subscribeToProbeForRoute,
|
|
108
110
|
updateConnectedWatchtower,
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
const EventEmitter = require('events');
|
|
2
|
+
|
|
3
|
+
const emitPayment = require('./emit_payment');
|
|
4
|
+
const {emitSubscriptionError} = require('./../../grpc');
|
|
5
|
+
const {handleRemoveListener} = require('./../../grpc');
|
|
6
|
+
const {isLnd} = require('./../../lnd_requests');
|
|
7
|
+
|
|
8
|
+
const events = ['confirmed', 'failed', 'paying'];
|
|
9
|
+
const method = 'trackPayments';
|
|
10
|
+
const type = 'router';
|
|
11
|
+
|
|
12
|
+
/** Subscribe to outgoing payments
|
|
13
|
+
|
|
14
|
+
Requires `offchain:read` permission
|
|
15
|
+
|
|
16
|
+
Note: Method not supported on LND 0.15.2 and below
|
|
17
|
+
|
|
18
|
+
{
|
|
19
|
+
lnd: <Authenticated LND API Object>
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
@throws
|
|
23
|
+
<Error>
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@returns
|
|
27
|
+
<Subscription EventEmitter Object>
|
|
28
|
+
|
|
29
|
+
@event 'confirmed'
|
|
30
|
+
{
|
|
31
|
+
confirmed_at: <Payment Confirmed At ISO 8601 Date String>
|
|
32
|
+
created_at: <Payment Created At ISO 8601 Date String>
|
|
33
|
+
destination: <Payment Destination Hex String>
|
|
34
|
+
fee: <Total Fee Tokens Paid Rounded Down Number>
|
|
35
|
+
fee_mtokens: <Total Fee Millitokens Paid String>
|
|
36
|
+
id: <Payment Hash Hex String>
|
|
37
|
+
mtokens: <Total Millitokens Paid String>
|
|
38
|
+
paths: [{
|
|
39
|
+
fee: <Total Fee Tokens Paid Number>
|
|
40
|
+
fee_mtokens: <Total Fee Millitokens Paid String>
|
|
41
|
+
hops: [{
|
|
42
|
+
channel: <Standard Format Channel Id String>
|
|
43
|
+
channel_capacity: <Channel Capacity Tokens Number>
|
|
44
|
+
fee: <Fee Tokens Rounded Down Number>
|
|
45
|
+
fee_mtokens: <Fee Millitokens String>
|
|
46
|
+
forward: <Forward Tokens Number>
|
|
47
|
+
forward_mtokens: <Forward Millitokens String>
|
|
48
|
+
public_key: <Public Key Hex String>
|
|
49
|
+
timeout: <Timeout Block Height Number>
|
|
50
|
+
}]
|
|
51
|
+
mtokens: <Total Millitokens Paid String>
|
|
52
|
+
safe_fee: <Total Fee Tokens Paid Rounded Up Number>
|
|
53
|
+
safe_tokens: <Total Tokens Paid, Rounded Up Number>
|
|
54
|
+
timeout: <Expiration Block Height Number>
|
|
55
|
+
}]
|
|
56
|
+
[request]: <BOLT 11 Encoded Payment Request String>
|
|
57
|
+
safe_fee: <Total Fee Tokens Paid Rounded Up Number>
|
|
58
|
+
safe_tokens: <Total Tokens Paid, Rounded Up Number>
|
|
59
|
+
secret: <Payment Preimage Hex String>
|
|
60
|
+
timeout: <Expiration Block Height Number>
|
|
61
|
+
tokens: <Total Tokens Paid Rounded Down Number>
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
@event 'failed'
|
|
65
|
+
{
|
|
66
|
+
is_insufficient_balance: <Failed Due To Lack of Balance Bool>
|
|
67
|
+
is_invalid_payment: <Failed Due to Payment Rejected At Destination Bool>
|
|
68
|
+
is_pathfinding_timeout: <Failed Due to Pathfinding Timeout Bool>
|
|
69
|
+
is_route_not_found: <Failed Due to Absence of Path Through Graph Bool>
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
@event 'paying'
|
|
73
|
+
{
|
|
74
|
+
created_at: <Payment Created At ISO 8601 Date String>
|
|
75
|
+
destination: <Payment Destination Hex String>
|
|
76
|
+
id: <Payment Hash Hex String>
|
|
77
|
+
mtokens: <Total Millitokens Pending String>
|
|
78
|
+
paths: [{
|
|
79
|
+
fee: <Total Fee Tokens Pending Number>
|
|
80
|
+
fee_mtokens: <Total Fee Millitokens Pending String>
|
|
81
|
+
hops: [{
|
|
82
|
+
channel: <Standard Format Channel Id String>
|
|
83
|
+
channel_capacity: <Channel Capacity Tokens Number>
|
|
84
|
+
fee: <Fee Tokens Rounded Down Number>
|
|
85
|
+
fee_mtokens: <Fee Millitokens String>
|
|
86
|
+
forward: <Forward Tokens Number>
|
|
87
|
+
forward_mtokens: <Forward Millitokens String>
|
|
88
|
+
public_key: <Public Key Hex String>
|
|
89
|
+
timeout: <Timeout Block Height Number>
|
|
90
|
+
}]
|
|
91
|
+
mtokens: <Total Millitokens Pending String>
|
|
92
|
+
safe_fee: <Total Fee Tokens Pending Rounded Up Number>
|
|
93
|
+
safe_tokens: <Total Tokens Pending, Rounded Up Number>
|
|
94
|
+
timeout: <Expiration Block Height Number>
|
|
95
|
+
}]
|
|
96
|
+
[request]: <BOLT 11 Encoded Payment Request String>
|
|
97
|
+
safe_tokens: <Total Tokens Pending, Rounded Up Number>
|
|
98
|
+
[timeout]: <Expiration Block Height Number>
|
|
99
|
+
tokens: <Total Tokens Pending Rounded Down Number>
|
|
100
|
+
}
|
|
101
|
+
*/
|
|
102
|
+
module.exports = ({lnd}) => {
|
|
103
|
+
if (!isLnd({lnd, method, type})) {
|
|
104
|
+
throw new Error('ExpectedAuthenticatedLndToSubscribeToCurrentPayments');
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const emitter = new EventEmitter();
|
|
108
|
+
const sub = lnd[type][method]({});
|
|
109
|
+
|
|
110
|
+
const emitErr = emitSubscriptionError({emitter, subscription: sub});
|
|
111
|
+
|
|
112
|
+
// Terminate subscription when all listeners are removed
|
|
113
|
+
handleRemoveListener({emitter, events, subscription: sub});
|
|
114
|
+
|
|
115
|
+
sub.on('data', data => emitPayment({data, emitter}));
|
|
116
|
+
sub.on('error', err => emitErr([503, 'UnexpectedPaymentsSubErr', {err}]));
|
|
117
|
+
|
|
118
|
+
return emitter;
|
|
119
|
+
};
|
|
@@ -49,7 +49,6 @@ const nsAsDate = ns => new Date(Number(BigInt(ns) / BigInt(1e6)));
|
|
|
49
49
|
}
|
|
50
50
|
status: <HTLC Status String>
|
|
51
51
|
}]
|
|
52
|
-
path: [<Hop Public Key Hex String>]
|
|
53
52
|
payment_hash: <Preimage SHA256 Hash Hex String>
|
|
54
53
|
payment_index: <Payment Index String>
|
|
55
54
|
payment_preimage: <Payment Secret Preimage Hex String>
|
|
@@ -64,7 +64,6 @@ const routePublicKeys = route => route.hops.map(n => n.public_key);
|
|
|
64
64
|
}
|
|
65
65
|
status: <HTLC Status String>
|
|
66
66
|
}]
|
|
67
|
-
path: [<Hop Public Key Hex String>]
|
|
68
67
|
payment_hash: <Preimage SHA256 Hash Hex String>
|
|
69
68
|
payment_index: <Payment Index String>
|
|
70
69
|
payment_preimage: <Payment Secret Preimage Hex String>
|
|
@@ -171,18 +170,6 @@ module.exports = payment => {
|
|
|
171
170
|
throw new Error('ExpectedHtlcsArrayInRpcPaymentDetails');
|
|
172
171
|
}
|
|
173
172
|
|
|
174
|
-
if (!isArray(payment.path)) {
|
|
175
|
-
throw new Error('ExpectedPaymentPathInRpcPaymentDetails');
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
payment.path.forEach(key => {
|
|
179
|
-
if (!key) {
|
|
180
|
-
throw new Error('ExpectedPathHopKeyInRpcPaymentDetails');
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
return;
|
|
184
|
-
});
|
|
185
|
-
|
|
186
173
|
if (!payment.payment_hash) {
|
|
187
174
|
throw new Error('ExpectedPaymentHashInRpcPaymentDetails');
|
|
188
175
|
}
|
|
@@ -233,13 +220,12 @@ module.exports = payment => {
|
|
|
233
220
|
};
|
|
234
221
|
}
|
|
235
222
|
|
|
236
|
-
const hasPath = !!payment.path.length;
|
|
237
223
|
const hasPreimage = payment.payment_preimage !== emptyHash;
|
|
238
224
|
const [attempt] = attempts;
|
|
239
225
|
const successes = attempts.filter(n => n.is_confirmed);
|
|
240
226
|
|
|
241
|
-
const path = !hasPath ? routePublicKeys(attempt.route) : payment.path;
|
|
242
227
|
const [confirmedAt] = successes.map(n => n.confirmed_at).sort().reverse();
|
|
228
|
+
const path = routePublicKeys(attempt.route);
|
|
243
229
|
|
|
244
230
|
const [destination, ...hops] = path.reverse();
|
|
245
231
|
|
package/package.json
CHANGED
|
@@ -7,10 +7,10 @@
|
|
|
7
7
|
"url": "https://github.com/alexbosworth/lightning/issues"
|
|
8
8
|
},
|
|
9
9
|
"dependencies": {
|
|
10
|
-
"@grpc/grpc-js": "1.7.
|
|
11
|
-
"@grpc/proto-loader": "0.7.
|
|
10
|
+
"@grpc/grpc-js": "1.7.1",
|
|
11
|
+
"@grpc/proto-loader": "0.7.3",
|
|
12
12
|
"@types/express": "4.17.14",
|
|
13
|
-
"@types/node": "18.7.
|
|
13
|
+
"@types/node": "18.7.23",
|
|
14
14
|
"@types/request": "2.48.8",
|
|
15
15
|
"@types/ws": "8.5.3",
|
|
16
16
|
"async": "3.2.4",
|
|
@@ -21,12 +21,12 @@
|
|
|
21
21
|
"bolt07": "1.8.2",
|
|
22
22
|
"bolt09": "0.2.3",
|
|
23
23
|
"cbor": "8.1.0",
|
|
24
|
-
"ecpair": "2.0
|
|
24
|
+
"ecpair": "2.1.0",
|
|
25
25
|
"express": "4.18.1",
|
|
26
26
|
"invoices": "2.2.0",
|
|
27
27
|
"psbt": "2.7.1",
|
|
28
28
|
"tiny-secp256k1": "2.2.1",
|
|
29
|
-
"type-fest": "
|
|
29
|
+
"type-fest": "3.0.0"
|
|
30
30
|
},
|
|
31
31
|
"description": "Lightning Network client library",
|
|
32
32
|
"devDependencies": {
|
|
@@ -34,10 +34,10 @@
|
|
|
34
34
|
"@alexbosworth/tap": "15.0.11",
|
|
35
35
|
"tsd": "0.24.1",
|
|
36
36
|
"typescript": "4.8.3",
|
|
37
|
-
"ws": "8.
|
|
37
|
+
"ws": "8.9.0"
|
|
38
38
|
},
|
|
39
39
|
"engines": {
|
|
40
|
-
"node": ">=
|
|
40
|
+
"node": ">=14"
|
|
41
41
|
},
|
|
42
42
|
"keywords": [
|
|
43
43
|
"grpc",
|
|
@@ -59,5 +59,5 @@
|
|
|
59
59
|
"directory": "test/typescript"
|
|
60
60
|
},
|
|
61
61
|
"types": "index.d.ts",
|
|
62
|
-
"version": "
|
|
62
|
+
"version": "6.1.0"
|
|
63
63
|
}
|
|
@@ -25,7 +25,7 @@ const makeLnd = args => {
|
|
|
25
25
|
expiry: 1,
|
|
26
26
|
fee: 1,
|
|
27
27
|
fee_msat: '1000',
|
|
28
|
-
pub_key: Buffer.alloc(33).toString('hex'),
|
|
28
|
+
pub_key: Buffer.alloc(33, 2).toString('hex'),
|
|
29
29
|
tlv_payload: false,
|
|
30
30
|
}],
|
|
31
31
|
total_amt: '1',
|
|
@@ -80,7 +80,7 @@ const makeExpectedPayment = ({}) => {
|
|
|
80
80
|
fee_mtokens: '1000',
|
|
81
81
|
forward: 1,
|
|
82
82
|
forward_mtokens: '1000',
|
|
83
|
-
public_key: '
|
|
83
|
+
public_key: Buffer.alloc(33, 2).toString('hex'),
|
|
84
84
|
timeout: 1,
|
|
85
85
|
}],
|
|
86
86
|
mtokens: '1000',
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
const EventEmitter = require('events');
|
|
2
|
+
|
|
3
|
+
const {test} = require('@alexbosworth/tap');
|
|
4
|
+
|
|
5
|
+
const {subscribeToPayments} = require('./../../../');
|
|
6
|
+
|
|
7
|
+
const tick = () => new Promise(resolve => process.nextTick(resolve));
|
|
8
|
+
|
|
9
|
+
const tests = [
|
|
10
|
+
{
|
|
11
|
+
args: {},
|
|
12
|
+
description: 'LND is required',
|
|
13
|
+
error: 'ExpectedAuthenticatedLndToSubscribeToCurrentPayments',
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
args: {
|
|
17
|
+
lnd: {
|
|
18
|
+
router: {
|
|
19
|
+
trackPayments: () => {
|
|
20
|
+
const emitter = new EventEmitter();
|
|
21
|
+
|
|
22
|
+
emitter.cancel = () => {};
|
|
23
|
+
|
|
24
|
+
process.nextTick(() => emitter.emit('error', 'error'));
|
|
25
|
+
|
|
26
|
+
return emitter;
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
description: 'An error is emitted',
|
|
32
|
+
expected: {
|
|
33
|
+
confirmed: [],
|
|
34
|
+
errors: [[503, 'UnexpectedPaymentsSubErr', {err: 'error'}]],
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
args: {
|
|
39
|
+
lnd: {
|
|
40
|
+
router: {
|
|
41
|
+
trackPayments: () => {
|
|
42
|
+
const emitter = new EventEmitter();
|
|
43
|
+
|
|
44
|
+
emitter.cancel = () => {};
|
|
45
|
+
|
|
46
|
+
process.nextTick(() => emitter.emit('data', {
|
|
47
|
+
creation_date: '1',
|
|
48
|
+
creation_time_ns: '1',
|
|
49
|
+
failure_reason: 'FAILURE_REASON_NONE',
|
|
50
|
+
fee: '1',
|
|
51
|
+
fee_msat: '1000',
|
|
52
|
+
fee_sat: '1',
|
|
53
|
+
htlcs: [{
|
|
54
|
+
attempt_time_ns: '1',
|
|
55
|
+
status: 'SUCCEEDED',
|
|
56
|
+
resolve_time_ns: '1',
|
|
57
|
+
route: {
|
|
58
|
+
hops: [{
|
|
59
|
+
amt_to_forward: '1',
|
|
60
|
+
amt_to_forward_msat: '1000',
|
|
61
|
+
chan_capacity: '1',
|
|
62
|
+
chan_id: '1',
|
|
63
|
+
custom_records: {'1': Buffer.alloc(1)},
|
|
64
|
+
expiry: 1,
|
|
65
|
+
fee: '1',
|
|
66
|
+
fee_msat: '1000',
|
|
67
|
+
mpp_record: {payment_addr: Buffer.alloc(32), total_amt_msat: '1000'},
|
|
68
|
+
pub_key: Buffer.alloc(33).toString('hex'),
|
|
69
|
+
tlv_payload: true,
|
|
70
|
+
}],
|
|
71
|
+
total_amt: '1',
|
|
72
|
+
total_amt_msat: '1000',
|
|
73
|
+
total_time_lock: 1,
|
|
74
|
+
total_fees: '1',
|
|
75
|
+
total_fees_msat: '1000',
|
|
76
|
+
},
|
|
77
|
+
}],
|
|
78
|
+
path: [Buffer.alloc(33).toString('hex')],
|
|
79
|
+
payment_hash: Buffer.alloc(32).toString('hex'),
|
|
80
|
+
payment_index: '1',
|
|
81
|
+
payment_preimage: Buffer.alloc(32).toString('hex'),
|
|
82
|
+
payment_request: '',
|
|
83
|
+
status: 'SUCCEEDED',
|
|
84
|
+
value: '1',
|
|
85
|
+
value_msat: '1000',
|
|
86
|
+
value_sat: '1',
|
|
87
|
+
}));
|
|
88
|
+
|
|
89
|
+
return emitter;
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
description: 'A payment is made',
|
|
95
|
+
expected: {
|
|
96
|
+
confirmed: [{
|
|
97
|
+
confirmed_at: '1970-01-01T00:00:00.000Z',
|
|
98
|
+
created_at: '1970-01-01T00:00:00.000Z',
|
|
99
|
+
destination: Buffer.alloc(33).toString('hex'),
|
|
100
|
+
fee: 1,
|
|
101
|
+
fee_mtokens: '1000',
|
|
102
|
+
hops: [{
|
|
103
|
+
channel: '0x0x1',
|
|
104
|
+
channel_capacity: 1,
|
|
105
|
+
fee: 1,
|
|
106
|
+
fee_mtokens: '1000',
|
|
107
|
+
forward: 1,
|
|
108
|
+
forward_mtokens: '1000',
|
|
109
|
+
public_key: Buffer.alloc(33).toString('hex'),
|
|
110
|
+
timeout: 1,
|
|
111
|
+
}],
|
|
112
|
+
id: Buffer.alloc(32).toString('hex'),
|
|
113
|
+
mtokens: '2000',
|
|
114
|
+
paths: [{
|
|
115
|
+
fee: 1,
|
|
116
|
+
fee_mtokens: '1000',
|
|
117
|
+
hops: [{
|
|
118
|
+
channel: '0x0x1',
|
|
119
|
+
channel_capacity: 1,
|
|
120
|
+
fee: 1,
|
|
121
|
+
fee_mtokens: '1000',
|
|
122
|
+
forward: 1,
|
|
123
|
+
forward_mtokens: '1000',
|
|
124
|
+
public_key: Buffer.alloc(33).toString('hex'),
|
|
125
|
+
timeout: 1,
|
|
126
|
+
}],
|
|
127
|
+
mtokens: '1000',
|
|
128
|
+
payment: '0000000000000000000000000000000000000000000000000000000000000000',
|
|
129
|
+
timeout: 1,
|
|
130
|
+
tokens: 1,
|
|
131
|
+
total_mtokens: '1000',
|
|
132
|
+
}],
|
|
133
|
+
request: undefined,
|
|
134
|
+
safe_fee: 1,
|
|
135
|
+
safe_tokens: 2,
|
|
136
|
+
secret: Buffer.alloc(32).toString('hex'),
|
|
137
|
+
timeout: 1,
|
|
138
|
+
tokens: 2,
|
|
139
|
+
}],
|
|
140
|
+
errors: [],
|
|
141
|
+
},
|
|
142
|
+
},
|
|
143
|
+
];
|
|
144
|
+
|
|
145
|
+
tests.forEach(({args, description, error, expected}) => {
|
|
146
|
+
return test(description, async ({end, strictSame, throws}) => {
|
|
147
|
+
if (!!error) {
|
|
148
|
+
throws(() => subscribeToPayments(args), new Error(error), 'Got err');
|
|
149
|
+
} else {
|
|
150
|
+
const sub = subscribeToPayments(args);
|
|
151
|
+
|
|
152
|
+
const confirmed = [];
|
|
153
|
+
const errors = [];
|
|
154
|
+
|
|
155
|
+
sub.on('confirmed', payment => confirmed.push(payment));
|
|
156
|
+
sub.on('error', err => errors.push(err));
|
|
157
|
+
|
|
158
|
+
await tick();
|
|
159
|
+
await tick();
|
|
160
|
+
|
|
161
|
+
strictSame(confirmed, expected.confirmed, 'Got expected payments');
|
|
162
|
+
strictSame(errors, expected.errors, 'Got expected errors');
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return end();
|
|
166
|
+
});
|
|
167
|
+
});
|
|
@@ -33,19 +33,34 @@ const makeArgs = overrides => {
|
|
|
33
33
|
},
|
|
34
34
|
resolve_time_ns: '1000000',
|
|
35
35
|
route: {
|
|
36
|
-
hops: [
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
36
|
+
hops: [
|
|
37
|
+
{
|
|
38
|
+
amt_to_forward_msat: '1000',
|
|
39
|
+
chan_id: '1',
|
|
40
|
+
chan_capacity: 1,
|
|
41
|
+
expiry: 1,
|
|
42
|
+
fee_msat: '1000',
|
|
43
|
+
mpp_record: {
|
|
44
|
+
payment_addr: Buffer.alloc(32),
|
|
45
|
+
total_amt_msat: '1000',
|
|
46
|
+
},
|
|
47
|
+
pub_key: Buffer.alloc(33).toString('hex'),
|
|
48
|
+
tlv_payload: true,
|
|
45
49
|
},
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
50
|
+
{
|
|
51
|
+
amt_to_forward_msat: '1000',
|
|
52
|
+
chan_id: '1',
|
|
53
|
+
chan_capacity: 1,
|
|
54
|
+
expiry: 1,
|
|
55
|
+
fee_msat: '1000',
|
|
56
|
+
mpp_record: {
|
|
57
|
+
payment_addr: Buffer.alloc(32),
|
|
58
|
+
total_amt_msat: '1000',
|
|
59
|
+
},
|
|
60
|
+
pub_key: Buffer.alloc(33).toString('hex'),
|
|
61
|
+
tlv_payload: true,
|
|
62
|
+
},
|
|
63
|
+
],
|
|
49
64
|
total_amt: '1',
|
|
50
65
|
total_amt_msat: '1000',
|
|
51
66
|
total_fees: '1',
|
|
@@ -54,7 +69,6 @@ const makeArgs = overrides => {
|
|
|
54
69
|
},
|
|
55
70
|
status: 'FAILED',
|
|
56
71
|
}],
|
|
57
|
-
path: [Buffer.alloc(33).toString('hex'), Buffer.alloc(33).toString('hex')],
|
|
58
72
|
payment_hash: Buffer.alloc(32).toString('hex'),
|
|
59
73
|
payment_index: '1',
|
|
60
74
|
payment_preimage: Buffer.alloc(32, 1).toString('hex'),
|
|
@@ -82,16 +96,28 @@ const makeExpected = overrides => {
|
|
|
82
96
|
route: {
|
|
83
97
|
fee: 1,
|
|
84
98
|
fee_mtokens: '1000',
|
|
85
|
-
hops: [
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
99
|
+
hops: [
|
|
100
|
+
{
|
|
101
|
+
channel: '0x0x1',
|
|
102
|
+
channel_capacity: 1,
|
|
103
|
+
fee: 1,
|
|
104
|
+
fee_mtokens: '1000',
|
|
105
|
+
forward: 1,
|
|
106
|
+
forward_mtokens: '1000',
|
|
107
|
+
public_key: Buffer.alloc(33).toString('hex'),
|
|
108
|
+
timeout: 1,
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
channel: '0x0x1',
|
|
112
|
+
channel_capacity: 1,
|
|
113
|
+
fee: 1,
|
|
114
|
+
fee_mtokens: '1000',
|
|
115
|
+
forward: 1,
|
|
116
|
+
forward_mtokens: '1000',
|
|
117
|
+
public_key: Buffer.alloc(33).toString('hex'),
|
|
118
|
+
timeout: 1,
|
|
119
|
+
},
|
|
120
|
+
],
|
|
95
121
|
mtokens: '1000',
|
|
96
122
|
payment: Buffer.alloc(32).toString('hex'),
|
|
97
123
|
timeout: 1,
|
|
@@ -143,16 +169,6 @@ const tests = [
|
|
|
143
169
|
description: 'HTLC array is expected to be present',
|
|
144
170
|
error: 'ExpectedHtlcsArrayInRpcPaymentDetails',
|
|
145
171
|
},
|
|
146
|
-
{
|
|
147
|
-
args: makeArgs({path: undefined}),
|
|
148
|
-
description: 'A path is expected to be present',
|
|
149
|
-
error: 'ExpectedPaymentPathInRpcPaymentDetails',
|
|
150
|
-
},
|
|
151
|
-
{
|
|
152
|
-
args: makeArgs({path: [null]}),
|
|
153
|
-
description: 'Hops are expected to have elements',
|
|
154
|
-
error: 'ExpectedPathHopKeyInRpcPaymentDetails',
|
|
155
|
-
},
|
|
156
172
|
{
|
|
157
173
|
args: makeArgs({payment_hash: undefined}),
|
|
158
174
|
description: 'A payment hash is expected',
|
|
@@ -175,7 +191,7 @@ const tests = [
|
|
|
175
191
|
},
|
|
176
192
|
{
|
|
177
193
|
args: makeArgs({creation_time_ns: '1000000'}),
|
|
178
|
-
description: 'RPC Payment is mapped to payment details',
|
|
194
|
+
description: 'RPC Payment with date is mapped to payment details',
|
|
179
195
|
expected: makeExpected({created_at: '1970-01-01T00:00:00.001Z'}),
|
|
180
196
|
},
|
|
181
197
|
{
|