lightning 4.3.0 → 4.6.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.
Files changed (59) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/grpc/protos/lightning.proto +115 -1
  3. package/grpc/protos/stateservice.proto +3 -0
  4. package/index.js +2 -0
  5. package/lnd_methods/index.js +2 -0
  6. package/lnd_methods/offchain/delete_failed_pay_attempts.js +25 -4
  7. package/lnd_methods/offchain/delete_payment.js +58 -0
  8. package/lnd_methods/offchain/emit_payment.d.ts +3 -3
  9. package/lnd_methods/offchain/finished_payment.js +3 -0
  10. package/lnd_methods/offchain/get_payment.d.ts +4 -0
  11. package/lnd_methods/offchain/get_payment.js +2 -0
  12. package/lnd_methods/offchain/get_payments.d.ts +4 -0
  13. package/lnd_methods/offchain/get_payments.js +2 -0
  14. package/lnd_methods/offchain/get_pending_channels.d.ts +4 -0
  15. package/lnd_methods/offchain/index.d.ts +1 -0
  16. package/lnd_methods/offchain/index.js +2 -0
  17. package/lnd_methods/offchain/pay.d.ts +2 -0
  18. package/lnd_methods/offchain/pay.js +2 -0
  19. package/lnd_methods/offchain/pay_via_payment_details.d.ts +2 -0
  20. package/lnd_methods/offchain/pay_via_payment_details.js +1 -0
  21. package/lnd_methods/offchain/pay_via_payment_request.d.ts +2 -0
  22. package/lnd_methods/offchain/pay_via_payment_request.js +1 -0
  23. package/lnd_methods/offchain/pay_via_routes.d.ts +2 -0
  24. package/lnd_methods/offchain/pay_via_routes.js +2 -0
  25. package/lnd_methods/offchain/subscribe_to_past_payment.d.ts +6 -0
  26. package/lnd_methods/offchain/subscribe_to_past_payment.js +2 -0
  27. package/lnd_methods/offchain/subscribe_to_past_payments.d.ts +70 -0
  28. package/lnd_methods/offchain/subscribe_to_past_payments.js +2 -0
  29. package/lnd_methods/offchain/subscribe_to_pay.js +1 -0
  30. package/lnd_methods/offchain/subscribe_to_pay_via_details.d.ts +2 -0
  31. package/lnd_methods/offchain/subscribe_to_pay_via_details.js +1 -0
  32. package/lnd_methods/offchain/subscribe_to_pay_via_request.d.ts +2 -0
  33. package/lnd_methods/offchain/subscribe_to_pay_via_request.js +1 -0
  34. package/lnd_methods/offchain/subscribe_to_pay_via_routes.d.ts +2 -0
  35. package/lnd_methods/offchain/subscribe_to_pay_via_routes.js +11 -1
  36. package/lnd_methods/offchain/subscribe_to_probe_for_route.d.ts +1 -1
  37. package/lnd_methods/unauthenticated/get_wallet_status.d.ts +3 -0
  38. package/lnd_methods/unauthenticated/get_wallet_status.js +3 -0
  39. package/lnd_methods/unauthenticated/subscribe_to_wallet_status.d.ts +4 -1
  40. package/lnd_methods/unauthenticated/subscribe_to_wallet_status.js +9 -0
  41. package/lnd_responses/confirmed_from_payment.js +7 -0
  42. package/lnd_responses/rpc_attempt_htlc_as_attempt.js +8 -27
  43. package/lnd_responses/rpc_payment_as_payment.js +3 -0
  44. package/lnd_responses/rpc_wallet_state_as_state.js +5 -0
  45. package/package.json +2 -2
  46. package/test/lnd_methods/offchain/test_delete_failed_pay_attempts.js +18 -0
  47. package/test/lnd_methods/offchain/test_delete_payment.js +51 -0
  48. package/test/lnd_methods/offchain/test_delete_payments.js +1 -1
  49. package/test/lnd_methods/offchain/test_finished_payment.js +2 -0
  50. package/test/lnd_methods/offchain/test_get_payments.js +4 -2
  51. package/test/lnd_methods/offchain/test_subscribe_to_past_payments.js +2 -0
  52. package/test/lnd_methods/offchain/test_subscribe_to_pay_via_routes.js +1 -0
  53. package/test/lnd_responses/test_confirmed_from_payment.js +2 -0
  54. package/test/lnd_responses/test_rpc_attempt_htlc_as_attempt.js +35 -21
  55. package/test/lnd_responses/test_rpc_payment_as_payment.js +4 -0
  56. package/test/lnd_responses/test_rpc_wallet_state_as_state.js +5 -0
  57. package/test/protos/protos.json +1 -1
  58. package/test/typescript/subscribe_to_past_payments.test-d.ts +11 -0
  59. package/typescript/shared.d.ts +3 -1
@@ -2,6 +2,8 @@ const {attemptStates} = require('./constants');
2
2
 
3
3
  const rpcRouteAsRoute = require('./rpc_route_as_route');
4
4
 
5
+ const nsAsMs = ns => Number(BigInt(ns) / BigInt(1e6));
6
+
5
7
  /** Payment attempt details from RPC HTLCAttempt message
6
8
 
7
9
  {
@@ -59,36 +61,10 @@ const rpcRouteAsRoute = require('./rpc_route_as_route');
59
61
 
60
62
  @returns
61
63
  {
64
+ confirmed_at: <Payment Succeeded At ISO 8601 Date String>
62
65
  is_confirmed: <Payment Attempt Succeeded Bool>
63
66
  is_failed: <Payment Attempt Failed Bool>
64
67
  is_pending: <Payment Attempt is Waiting For Resolution Bool>
65
- [failure]: {
66
- code: <Error Type Code Number>
67
- [details]: {
68
- [channel]: <Standard Format Channel Id String>
69
- [height]: <Error Associated Block Height Number>
70
- [index]: <Failed Hop Index Number>
71
- [mtokens]: <Error Millitokens String>
72
- [policy]: {
73
- base_fee_mtokens: <Base Fee Millitokens String>
74
- cltv_delta: <Locktime Delta Number>
75
- fee_rate: <Fees Charged in Millitokens Per Million Number>
76
- [is_disabled]: <Channel is Disabled Bool>
77
- max_htlc_mtokens: <Maximum HLTC Millitokens Value String>
78
- min_htlc_mtokens: <Minimum HTLC Millitokens Value String>
79
- updated_at: <Updated At ISO 8601 Date String>
80
- }
81
- [timeout_height]: <Error CLTV Timeout Height Number>
82
- [update]: {
83
- chain: <Chain Id Hex String>
84
- channel_flags: <Channel Flags Number>
85
- extra_opaque_data: <Extra Opaque Data Hex String>
86
- message_flags: <Message Flags Number>
87
- signature: <Channel Update Signature Hex String>
88
- }
89
- }
90
- message: <Error Message String>
91
- }
92
68
  route: {
93
69
  fee: <Route Fee Tokens Number>
94
70
  fee_mtokens: <Route Fee Millitokens String>
@@ -115,6 +91,10 @@ module.exports = attempt => {
115
91
  throw new Error('ExpectedRpcAttemptDetailsToDeriveAttempt');
116
92
  }
117
93
 
94
+ if (!attempt.resolve_time_ns) {
95
+ throw new Error('ExpectedRpcAttemptResolveTimeNs');
96
+ }
97
+
118
98
  if (!attempt.route) {
119
99
  throw new Error('ExpectedRouteAttemptedInRpcAttemptDetails');
120
100
  }
@@ -124,6 +104,7 @@ module.exports = attempt => {
124
104
  }
125
105
 
126
106
  return {
107
+ confirmed_at: new Date(nsAsMs(attempt.resolve_time_ns)).toISOString(),
127
108
  is_confirmed: attempt.status === attemptStates.confirmed,
128
109
  is_failed: attempt.status === attemptStates.failed,
129
110
  is_pending: attempt.status === attemptStates.pending,
@@ -194,8 +194,10 @@ module.exports = payment => {
194
194
 
195
195
  const hasPath = !!payment.path.length;
196
196
  const [attempt] = attempts;
197
+ const successes = attempts.filter(n => n.is_confirmed);
197
198
 
198
199
  const path = !hasPath ? routePublicKeys(attempt.route) : payment.path;
200
+ const [confirmedAt] = successes.map(n => n.confirmed_at).sort().reverse();
199
201
 
200
202
  const [destination, ...hops] = path.reverse();
201
203
 
@@ -211,6 +213,7 @@ module.exports = payment => {
211
213
  return {
212
214
  destination,
213
215
  attempts: payment.htlcs.map(htlc => rpcAttemptHtlcAsAttempt(htlc)),
216
+ confirmed_at: confirmedAt || undefined,
214
217
  created_at: new Date(creationDateEpochMs).toISOString(),
215
218
  fee: safeTokens({mtokens: payment.fee_msat}).tokens,
216
219
  fee_mtokens: payment.fee_msat,
@@ -1,6 +1,7 @@
1
1
  const stateAbsent = 'NON_EXISTING';
2
2
  const stateActive = 'RPC_ACTIVE';
3
3
  const stateLocked = 'LOCKED';
4
+ const stateReady = 'SERVER_ACTIVE';
4
5
  const stateStarting = 'UNLOCKED';
5
6
  const stateWaiting = 'WAITING_TO_START';
6
7
 
@@ -15,6 +16,7 @@ const stateWaiting = 'WAITING_TO_START';
15
16
  [is_absent]: <Wallet Not Created Bool>
16
17
  [is_active]: <Wallet Is Active Bool>
17
18
  [is_locked]: <Wallet File Encrypted And Wallet Not Active Bool>
19
+ [is_ready]: <Wallet Is Ready For All RPC Calls Bool>
18
20
  [is_starting]: <Wallet Is Starting Up Bool>
19
21
  [is_waiting]: <Wallet Is Waiting To Start Bool>
20
22
  }
@@ -38,6 +40,9 @@ module.exports = args => {
38
40
  case stateLocked:
39
41
  return {is_locked: true};
40
42
 
43
+ case stateReady:
44
+ return {is_active: true, is_ready: true};
45
+
41
46
  case stateStarting:
42
47
  return {is_starting: true};
43
48
 
package/package.json CHANGED
@@ -8,7 +8,7 @@
8
8
  },
9
9
  "dependencies": {
10
10
  "@grpc/grpc-js": "1.3.7",
11
- "@grpc/proto-loader": "0.6.4",
11
+ "@grpc/proto-loader": "0.6.5",
12
12
  "@types/express": "4.17.13",
13
13
  "@types/node": "16.9.1",
14
14
  "@types/request": "2.48.7",
@@ -56,5 +56,5 @@
56
56
  "directory": "test/typescript"
57
57
  },
58
58
  "types": "index.d.ts",
59
- "version": "4.3.0"
59
+ "version": "4.6.0"
60
60
  }
@@ -8,6 +8,24 @@ const tests = [
8
8
  description: 'LND object is required',
9
9
  error: [400, 'ExpectedAuthenticatedLndToDeleteFailedAttempts'],
10
10
  },
11
+ {
12
+ args: {id: 1},
13
+ description: 'A payment id is expected to be a hash',
14
+ error: [400, 'ExpectedPaymentHashToDeleteFailedPayAttempts'],
15
+ },
16
+ {
17
+ args: {
18
+ id: Buffer.alloc(32).toString('hex'),
19
+ lnd: {
20
+ default: {
21
+ deleteAllPayments: ({}, cbk) => cbk(),
22
+ deletePayment: ({}, cbk) => cbk({details: 'unknown'}),
23
+ },
24
+ },
25
+ },
26
+ description: 'An unsupported error is returned',
27
+ error: [501, 'DeleteFailedPaymentAttemptsMethodNotSupported'],
28
+ },
11
29
  {
12
30
  args: {lnd: {default: {deleteAllPayments: ({}, cbk) => cbk('err')}}},
13
31
  description: 'An unexpected error is returned',
@@ -0,0 +1,51 @@
1
+ const {test} = require('@alexbosworth/tap');
2
+
3
+ const {deletePayment} = require('./../../../lnd_methods');
4
+
5
+ const tests = [
6
+ {
7
+ args: {},
8
+ description: 'An id is required',
9
+ error: [400, 'ExpectedPaymentHashToDeletePaymentRecord'],
10
+ },
11
+ {
12
+ args: {id: Buffer.alloc(32).toString('hex')},
13
+ description: 'LND object is required',
14
+ error: [400, 'ExpectedAuthenticatedLndToDeletePayment'],
15
+ },
16
+ {
17
+ args: {
18
+ id: Buffer.alloc(32).toString('hex'),
19
+ lnd: {default: {deletePayment: ({}, cbk) => cbk({details: 'unknown'})}},
20
+ },
21
+ description: 'An unexpected error is returned',
22
+ error: [501, 'DeletePaymentMethodNotSupported'],
23
+ },
24
+ {
25
+ args: {
26
+ id: Buffer.alloc(32).toString('hex'),
27
+ lnd: {default: {deletePayment: ({}, cbk) => cbk('err')}},
28
+ },
29
+ description: 'An unexpected error is returned',
30
+ error: [503, 'UnexpectedErrorDeletingPayment', {err: 'err'}],
31
+ },
32
+ {
33
+ args: {
34
+ id: Buffer.alloc(32).toString('hex'),
35
+ lnd: {default: {deletePayment: ({}, cbk) => cbk()}},
36
+ },
37
+ description: 'Payments are deleted',
38
+ },
39
+ ];
40
+
41
+ tests.forEach(({args, description, error, expected}) => {
42
+ return test(description, async ({deepEqual, end, equal, rejects}) => {
43
+ if (!!error) {
44
+ await rejects(deletePayment(args), error, 'Got expected error');
45
+ } else {
46
+ await deletePayment(args);
47
+ }
48
+
49
+ return end();
50
+ });
51
+ });
@@ -15,7 +15,7 @@ const tests = [
15
15
  },
16
16
  {
17
17
  args: {lnd: {default: {deleteAllPayments: ({}, cbk) => cbk()}}},
18
- description: 'Payments are deleted',
18
+ description: 'Payment is deleted',
19
19
  },
20
20
  ];
21
21
 
@@ -5,6 +5,7 @@ const method = require('./../../../lnd_methods/offchain/finished_payment');
5
5
  const makeArgs = overrides => {
6
6
  const args = {
7
7
  confirmed: {
8
+ confirmed_at: new Date(1).toISOString(),
8
9
  fee: 1,
9
10
  fee_mtokens: '1000',
10
11
  hops: [{
@@ -91,6 +92,7 @@ const tests = [
91
92
  args: makeArgs({}),
92
93
  description: 'Successful payment details are returned',
93
94
  expected: {
95
+ confirmed_at: '1970-01-01T00:00:00.001Z',
94
96
  fee: 1,
95
97
  fee_mtokens: '1000',
96
98
  hops: [{
@@ -34,7 +34,7 @@ const makeLnd = args => {
34
34
  total_fees_msat: '1000',
35
35
  total_time_lock: 1,
36
36
  },
37
- status: 'SETTLED',
37
+ status: 'SUCCEEDED',
38
38
  }],
39
39
  path: [Buffer.alloc(33, 2).toString('hex')],
40
40
  payment_hash: Buffer.alloc(32).toString('hex'),
@@ -64,7 +64,8 @@ const makeExpectedPayment = ({}) => {
64
64
  return {
65
65
  destination: '020202020202020202020202020202020202020202020202020202020202020202',
66
66
  attempts: [{
67
- is_confirmed: false,
67
+ confirmed_at: '1970-01-01T00:00:00.000Z',
68
+ is_confirmed: true,
68
69
  is_failed: false,
69
70
  is_pending: false,
70
71
  route: {
@@ -87,6 +88,7 @@ const makeExpectedPayment = ({}) => {
87
88
  total_mtokens: undefined
88
89
  },
89
90
  }],
91
+ confirmed_at: '1970-01-01T00:00:00.000Z',
90
92
  created_at: '1970-01-01T00:00:00.000Z',
91
93
  fee: 1,
92
94
  fee_mtokens: '1000',
@@ -203,6 +203,8 @@ const tests = [
203
203
  },
204
204
  description: 'A past payment is emitted',
205
205
  expected: {
206
+ confirmed_at: '1970-01-01T00:00:00.000Z',
207
+ destination: '000000000000000000000000000000000000000000000000000000000000000000',
206
208
  fee: 1,
207
209
  fee_mtokens: '1000',
208
210
  hops: [
@@ -126,6 +126,7 @@ const tests = [
126
126
  failures: [],
127
127
  success: {
128
128
  route,
129
+ confirmed_at: undefined,
129
130
  fee: route.fee,
130
131
  fee_mtokens: route.fee_mtokens,
131
132
  hops: route.hops,
@@ -53,6 +53,8 @@ const makeArgs = overrides => {
53
53
 
54
54
  const makeExpected = overrides => {
55
55
  const expected = {
56
+ confirmed_at: '1970-01-01T00:00:00.000Z',
57
+ destination: Buffer.alloc(33).toString('hex'),
56
58
  fee: 1,
57
59
  fee_mtokens: '1000',
58
60
  hops: [{
@@ -2,8 +2,33 @@ const {test} = require('@alexbosworth/tap');
2
2
 
3
3
  const {rpcAttemptHtlcAsAttempt} = require('./../../lnd_responses');
4
4
 
5
+ const route = {
6
+ hops: [{
7
+ amt_to_forward_msat: '1000',
8
+ chan_id: '1',
9
+ chan_capacity: 1,
10
+ expiry: 1,
11
+ fee_msat: '1000',
12
+ mpp_record: {payment_addr: Buffer.alloc(1), total_amt_msat: '1'},
13
+ pub_key: 'a',
14
+ tlv_payload: true,
15
+ }],
16
+ total_amt_msat: '1000',
17
+ total_fees_msat: '1000',
18
+ total_time_lock: 1,
19
+ };
20
+
21
+ const makeArgs = overrides => {
22
+ const args = {route, resolve_time_ns: '1', status: 'IN_FLIGHT'};
23
+
24
+ Object.keys(overrides).forEach(k => args[k] = overrides[k]);
25
+
26
+ return args;
27
+ };
28
+
5
29
  const makeExpected = overrides => {
6
30
  const attempt = {
31
+ confirmed_at: '1970-01-01T00:00:00.000Z',
7
32
  is_confirmed: false,
8
33
  is_failed: false,
9
34
  is_pending: false,
@@ -33,22 +58,6 @@ const makeExpected = overrides => {
33
58
  return {attempt};
34
59
  };
35
60
 
36
- const route = {
37
- hops: [{
38
- amt_to_forward_msat: '1000',
39
- chan_id: '1',
40
- chan_capacity: 1,
41
- expiry: 1,
42
- fee_msat: '1000',
43
- mpp_record: {payment_addr: Buffer.alloc(1), total_amt_msat: '1'},
44
- pub_key: 'a',
45
- tlv_payload: true,
46
- }],
47
- total_amt_msat: '1000',
48
- total_fees_msat: '1000',
49
- total_time_lock: 1,
50
- };
51
-
52
61
  const tests = [
53
62
  {
54
63
  args: null,
@@ -56,27 +65,32 @@ const tests = [
56
65
  error: 'ExpectedRpcAttemptDetailsToDeriveAttempt',
57
66
  },
58
67
  {
59
- args: {},
68
+ args: makeArgs({resolve_time_ns: undefined}),
69
+ description: 'Expected resolve time in rpc attempt details',
70
+ error: 'ExpectedRpcAttemptResolveTimeNs',
71
+ },
72
+ {
73
+ args: makeArgs({route: undefined}),
60
74
  description: 'Expected route in rpc attempt details',
61
75
  error: 'ExpectedRouteAttemptedInRpcAttemptDetails',
62
76
  },
63
77
  {
64
- args: {route: {}},
78
+ args: makeArgs({status: undefined}),
65
79
  description: 'A status code is expected',
66
80
  error: 'ExpectedAttemptStatusInRpcAttemptDetails',
67
81
  },
68
82
  {
69
- args: {route, status: 'IN_FLIGHT'},
83
+ args: makeArgs({}),
70
84
  description: 'An in flight rpc attempt is mapped to an attempt',
71
85
  expected: makeExpected({is_pending: true}),
72
86
  },
73
87
  {
74
- args: {route, status: 'SUCCEEDED'},
88
+ args: makeArgs({status: 'SUCCEEDED'}),
75
89
  description: 'An rpc attempt is mapped to an attempt',
76
90
  expected: makeExpected({is_confirmed: true}),
77
91
  },
78
92
  {
79
- args: {route, status: 'FAILED'},
93
+ args: makeArgs({status: 'FAILED'}),
80
94
  description: 'An rpc attempt is mapped to an attempt',
81
95
  expected: makeExpected({is_failed: true}),
82
96
  },
@@ -73,6 +73,7 @@ const makeArgs = overrides => {
73
73
  const makeExpected = overrides => {
74
74
  const expected = {
75
75
  attempts: [{
76
+ confirmed_at: '1970-01-01T00:00:00.001Z',
76
77
  is_confirmed: false,
77
78
  is_failed: true,
78
79
  is_pending: false,
@@ -96,6 +97,7 @@ const makeExpected = overrides => {
96
97
  total_mtokens: '1000',
97
98
  },
98
99
  }],
100
+ confirmed_at: undefined,
99
101
  created_at: '1970-01-01T00:00:01.000Z',
100
102
  destination: Buffer.alloc(33).toString('hex'),
101
103
  fee: 1,
@@ -234,6 +236,7 @@ const tests = [
234
236
  description: 'A realistic successful payment is mapped to a payment',
235
237
  expected: makeExpected({
236
238
  attempts: [{
239
+ confirmed_at: '2020-04-20T19:17:16.160Z',
237
240
  is_confirmed: true,
238
241
  is_failed: false,
239
242
  is_pending: false,
@@ -257,6 +260,7 @@ const tests = [
257
260
  total_mtokens: '100000',
258
261
  },
259
262
  }],
263
+ confirmed_at: '2020-04-20T19:17:16.160Z',
260
264
  created_at: '2020-04-20T19:17:15.356Z',
261
265
  destination: '029860f8550e29316ee97460c79228d939b18d2a51dbef407f410e265c79b19073',
262
266
  fee: 0,
@@ -30,6 +30,11 @@ const tests = [
30
30
  description: 'Wallet is ready',
31
31
  expected: makeExpected({is_active: true}),
32
32
  },
33
+ {
34
+ args: {state: 'SERVER_ACTIVE'},
35
+ description: 'Server is ready',
36
+ expected: makeExpected({is_active: true, is_ready: true}),
37
+ },
33
38
  {
34
39
  args: {state: 'LOCKED'},
35
40
  description: 'Wallet file is encrypted',
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "overrides": [
3
- ["lightning", 3229],
3
+ ["lightning", 3330],
4
4
  ["router", 100, 171],
5
5
  ["walletkit", 3],
6
6
  ["walletunlocker", 2]
@@ -0,0 +1,11 @@
1
+ import * as events from 'events';
2
+ import {expectError, expectType} from 'tsd';
3
+ import {AuthenticatedLnd} from '../../lnd_grpc';
4
+ import {subscribeToPastPayments} from '../../lnd_methods';
5
+
6
+ const lnd = {} as AuthenticatedLnd;
7
+
8
+ expectError(subscribeToPastPayments());
9
+ expectError(subscribeToPastPayments({}));
10
+
11
+ expectType<events.EventEmitter>(subscribeToPastPayments({lnd}));