lightning 4.4.0 → 4.7.1

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 (39) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/grpc/protos/lightning.proto +134 -2
  3. package/grpc/protos/stateservice.proto +3 -0
  4. package/index.js +4 -0
  5. package/lnd_methods/index.js +4 -0
  6. package/lnd_methods/macaroon/index.js +2 -1
  7. package/lnd_methods/macaroon/verify_access.js +85 -0
  8. package/lnd_methods/offchain/delete_failed_pay_attempts.js +25 -4
  9. package/lnd_methods/offchain/delete_payment.d.ts +18 -0
  10. package/lnd_methods/offchain/delete_payment.js +58 -0
  11. package/lnd_methods/offchain/emit_payment.d.ts +3 -3
  12. package/lnd_methods/offchain/get_payment.d.ts +6 -0
  13. package/lnd_methods/offchain/get_payment.js +3 -0
  14. package/lnd_methods/offchain/index.d.ts +2 -0
  15. package/lnd_methods/offchain/index.js +2 -0
  16. package/lnd_methods/offchain/subscribe_to_past_payment.d.ts +6 -0
  17. package/lnd_methods/offchain/subscribe_to_past_payment.js +3 -0
  18. package/lnd_methods/offchain/subscribe_to_past_payments.d.ts +74 -0
  19. package/lnd_methods/offchain/subscribe_to_past_payments.js +3 -0
  20. package/lnd_methods/offchain/subscribe_to_probe_for_route.d.ts +1 -1
  21. package/lnd_methods/unauthenticated/get_wallet_status.d.ts +3 -0
  22. package/lnd_methods/unauthenticated/get_wallet_status.js +3 -0
  23. package/lnd_methods/unauthenticated/subscribe_to_wallet_status.d.ts +4 -1
  24. package/lnd_methods/unauthenticated/subscribe_to_wallet_status.js +9 -0
  25. package/lnd_responses/confirmed_from_payment.js +13 -0
  26. package/lnd_responses/rpc_wallet_state_as_state.js +5 -0
  27. package/package.json +4 -4
  28. package/test/lnd_methods/macaroon/test_verify_access.js +101 -0
  29. package/test/lnd_methods/offchain/test_delete_failed_pay_attempts.js +18 -0
  30. package/test/lnd_methods/offchain/test_delete_payment.js +51 -0
  31. package/test/lnd_methods/offchain/test_delete_payments.js +1 -1
  32. package/test/lnd_methods/offchain/test_pay_via_payment_details.js +1 -1
  33. package/test/lnd_methods/offchain/test_subscribe_to_past_payments.js +3 -0
  34. package/test/lnd_responses/test_confirmed_from_payment.js +3 -0
  35. package/test/lnd_responses/test_rpc_wallet_state_as_state.js +5 -0
  36. package/test/protos/protos.json +1 -1
  37. package/test/typescript/delete_payment.test-d.ts +15 -0
  38. package/test/typescript/subscribe_to_past_payments.test-d.ts +11 -0
  39. package/typescript/shared.d.ts +3 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,27 @@
1
1
  # Versions
2
2
 
3
+ ## 4.7.1
4
+
5
+ - `getPayment`: Add `created_at` to indicate the creation date of the payment
6
+ - `getPayment`: Add `request` to indicate serialized payment request
7
+ - `subscribeToPastPayment`: Add `created_at` to indicate the creation date of the payment
8
+ - `subscribeToPastPayment`: Add `request` to indicate serialized payment request
9
+ - `subscribeToPastPayments`: Add `created_at` to indicate the creation date of the payment
10
+ - `subscribeToPastPayments`: Add `request` to indicate serialized payment request
11
+
12
+ ## 4.6.0
13
+
14
+ - `getPayment`: Add `destination` to indicate the destination of the payment
15
+ - `subscribeToPastPayment`: Add `destination` to indicate the destination of the payment
16
+ - `subscribeToPastPayments`: Add `destination` to indicate the destination of the payment
17
+
18
+ ## 4.5.0
19
+
20
+ - `deletePayment`: Add method to delete a single payment
21
+ - `deleteFailedPayAttempts`: Add `id` argument to delete failed attempts for a payment
22
+ - `getWalletStatus`: `is_ready`: Add wallet server ready status
23
+ - `subscribeToWalletStatus`: Add `ready` event to indicate server ready status
24
+
3
25
  ## 4.4.0
4
26
 
5
27
  - `getPayment`: Add `confirmed_at` to indicate when payment resolved successfully
@@ -200,6 +200,16 @@ service Lightning {
200
200
  */
201
201
  rpc OpenChannel (OpenChannelRequest) returns (stream OpenStatusUpdate);
202
202
 
203
+ /* lncli: `batchopenchannel`
204
+ BatchOpenChannel attempts to open multiple single-funded channels in a
205
+ single transaction in an atomic way. This means either all channel open
206
+ requests succeed at once or all attempts are aborted if any of them fail.
207
+ This is the safer variant of using PSBTs to manually fund a batch of
208
+ channels through the OpenChannel RPC.
209
+ */
210
+ rpc BatchOpenChannel (BatchOpenChannelRequest)
211
+ returns (BatchOpenChannelResponse);
212
+
203
213
  /*
204
214
  FundingStateStep is an advanced funding related call that allows the caller
205
215
  to either execute some preparatory steps for a funding workflow, or
@@ -330,7 +340,14 @@ service Lightning {
330
340
  rpc ListPayments (ListPaymentsRequest) returns (ListPaymentsResponse);
331
341
 
332
342
  /*
333
- DeleteAllPayments deletes all outgoing payments from DB.
343
+ DeletePayment deletes an outgoing payment from DB. Note that it will not
344
+ attempt to delete an In-Flight payment, since that would be unsafe.
345
+ */
346
+ rpc DeletePayment (DeletePaymentRequest) returns (DeletePaymentResponse);
347
+
348
+ /*
349
+ DeleteAllPayments deletes all outgoing payments from DB. Note that it will
350
+ not attempt to delete In-Flight payments, since that would be unsafe.
334
351
  */
335
352
  rpc DeleteAllPayments (DeleteAllPaymentsRequest)
336
353
  returns (DeleteAllPaymentsResponse);
@@ -515,6 +532,14 @@ service Lightning {
515
532
  */
516
533
  rpc ListPermissions (ListPermissionsRequest)
517
534
  returns (ListPermissionsResponse);
535
+
536
+ /*
537
+ CheckMacaroonPermissions checks whether a request follows the constraints
538
+ imposed on the macaroon and that the macaroon is authorized to follow the
539
+ provided permissions.
540
+ */
541
+ rpc CheckMacaroonPermissions (CheckMacPermRequest)
542
+ returns (CheckMacPermResponse);
518
543
  }
519
544
 
520
545
  message Utxo {
@@ -1776,6 +1801,84 @@ message ReadyForPsbtFunding {
1776
1801
  bytes psbt = 3;
1777
1802
  }
1778
1803
 
1804
+ message BatchOpenChannelRequest {
1805
+ // The list of channels to open.
1806
+ repeated BatchOpenChannel channels = 1;
1807
+
1808
+ // The target number of blocks that the funding transaction should be
1809
+ // confirmed by.
1810
+ int32 target_conf = 2;
1811
+
1812
+ // A manual fee rate set in sat/vByte that should be used when crafting the
1813
+ // funding transaction.
1814
+ int64 sat_per_vbyte = 3;
1815
+
1816
+ // The minimum number of confirmations each one of your outputs used for
1817
+ // the funding transaction must satisfy.
1818
+ int32 min_confs = 4;
1819
+
1820
+ // Whether unconfirmed outputs should be used as inputs for the funding
1821
+ // transaction.
1822
+ bool spend_unconfirmed = 5;
1823
+
1824
+ // An optional label for the batch transaction, limited to 500 characters.
1825
+ string label = 6;
1826
+ }
1827
+
1828
+ message BatchOpenChannel {
1829
+ // The pubkey of the node to open a channel with. When using REST, this
1830
+ // field must be encoded as base64.
1831
+ bytes node_pubkey = 1;
1832
+
1833
+ // The number of satoshis the wallet should commit to the channel.
1834
+ int64 local_funding_amount = 2;
1835
+
1836
+ // The number of satoshis to push to the remote side as part of the initial
1837
+ // commitment state.
1838
+ int64 push_sat = 3;
1839
+
1840
+ // Whether this channel should be private, not announced to the greater
1841
+ // network.
1842
+ bool private = 4;
1843
+
1844
+ // The minimum value in millisatoshi we will require for incoming HTLCs on
1845
+ // the channel.
1846
+ int64 min_htlc_msat = 5;
1847
+
1848
+ // The delay we require on the remote's commitment transaction. If this is
1849
+ // not set, it will be scaled automatically with the channel size.
1850
+ uint32 remote_csv_delay = 6;
1851
+
1852
+ /*
1853
+ Close address is an optional address which specifies the address to which
1854
+ funds should be paid out to upon cooperative close. This field may only be
1855
+ set if the peer supports the option upfront feature bit (call listpeers
1856
+ to check). The remote peer will only accept cooperative closes to this
1857
+ address if it is set.
1858
+
1859
+ Note: If this value is set on channel creation, you will *not* be able to
1860
+ cooperatively close out to a different address.
1861
+ */
1862
+ string close_address = 7;
1863
+
1864
+ /*
1865
+ An optional, unique identifier of 32 random bytes that will be used as the
1866
+ pending channel ID to identify the channel while it is in the pre-pending
1867
+ state.
1868
+ */
1869
+ bytes pending_chan_id = 8;
1870
+
1871
+ /*
1872
+ The explicit commitment type to use. Note this field will only be used if
1873
+ the remote peer supports explicit channel negotiation.
1874
+ */
1875
+ CommitmentType commitment_type = 9;
1876
+ }
1877
+
1878
+ message BatchOpenChannelResponse {
1879
+ repeated PendingUpdate pending_channels = 1;
1880
+ }
1881
+
1779
1882
  message OpenChannelRequest {
1780
1883
  // A manual fee rate set in sat/vbyte that should be used when crafting the
1781
1884
  // funding transaction.
@@ -1867,6 +1970,12 @@ message OpenChannelRequest {
1867
1970
  transaction.
1868
1971
  */
1869
1972
  uint32 max_local_csv = 17;
1973
+
1974
+ /*
1975
+ The explicit commitment type to use. Note this field will only be used if
1976
+ the remote peer supports explicit channel negotiation.
1977
+ */
1978
+ CommitmentType commitment_type = 18;
1870
1979
  }
1871
1980
  message OpenStatusUpdate {
1872
1981
  oneof update {
@@ -3354,6 +3463,16 @@ message ListPaymentsResponse {
3354
3463
  uint64 last_index_offset = 3;
3355
3464
  }
3356
3465
 
3466
+ message DeletePaymentRequest {
3467
+ // Payment hash to delete.
3468
+ bytes payment_hash = 1;
3469
+
3470
+ /*
3471
+ Only delete failed HTLCs from the payment, not the payment itself.
3472
+ */
3473
+ bool failed_htlcs_only = 2;
3474
+ }
3475
+
3357
3476
  message DeleteAllPaymentsRequest {
3358
3477
  // Only delete failed payments.
3359
3478
  bool failed_payments_only = 1;
@@ -3364,6 +3483,9 @@ message DeleteAllPaymentsRequest {
3364
3483
  bool failed_htlcs_only = 2;
3365
3484
  }
3366
3485
 
3486
+ message DeletePaymentResponse {
3487
+ }
3488
+
3367
3489
  message DeleteAllPaymentsResponse {
3368
3490
  }
3369
3491
 
@@ -3891,4 +4013,14 @@ message MacaroonId {
3891
4013
  message Op {
3892
4014
  string entity = 1;
3893
4015
  repeated string actions = 2;
3894
- }
4016
+ }
4017
+
4018
+ message CheckMacPermRequest {
4019
+ bytes macaroon = 1;
4020
+ repeated MacaroonPermission permissions = 2;
4021
+ string fullMethod = 3;
4022
+ }
4023
+
4024
+ message CheckMacPermResponse {
4025
+ bool valid = 1;
4026
+ }
@@ -41,6 +41,9 @@ enum WalletState {
41
41
  UNLOCKED = 2;
42
42
  RPC_ACTIVE = 3;
43
43
 
44
+ // SERVER_ACTIVE means that the lnd server is ready to accept calls.
45
+ SERVER_ACTIVE = 4;
46
+
44
47
  WAITING_TO_START = 255;
45
48
  }
46
49
 
package/index.js CHANGED
@@ -15,6 +15,7 @@ const {decodePaymentRequest} = require('./lnd_methods');
15
15
  const {deleteFailedPayAttempts} = require('./lnd_methods');
16
16
  const {deleteFailedPayments} = require('./lnd_methods');
17
17
  const {deleteForwardingReputations} = require('./lnd_methods');
18
+ const {deletePayment} = require('./lnd_methods');
18
19
  const {deletePayments} = require('./lnd_methods');
19
20
  const {diffieHellmanComputeSecret} = require('./lnd_methods');
20
21
  const {disableChannel} = require('./lnd_methods');
@@ -107,6 +108,7 @@ const {subscribeToInvoice} = require('./lnd_methods');
107
108
  const {subscribeToInvoices} = require('./lnd_methods');
108
109
  const {subscribeToOpenRequests} = require('./lnd_methods');
109
110
  const {subscribeToPastPayment} = require('./lnd_methods');
111
+ const {subscribeToPastPayments} = require('./lnd_methods');
110
112
  const {subscribeToPayViaDetails} = require('./lnd_methods');
111
113
  const {subscribeToPayViaRequest} = require('./lnd_methods');
112
114
  const {subscribeToPayViaRoutes} = require('./lnd_methods');
@@ -144,6 +146,7 @@ module.exports = {
144
146
  deleteFailedPayAttempts,
145
147
  deleteFailedPayments,
146
148
  deleteForwardingReputations,
149
+ deletePayment,
147
150
  deletePayments,
148
151
  disableChannel,
149
152
  disconnectWatchtower,
@@ -236,6 +239,7 @@ module.exports = {
236
239
  subscribeToInvoices,
237
240
  subscribeToOpenRequests,
238
241
  subscribeToPastPayment,
242
+ subscribeToPastPayments,
239
243
  subscribeToPayViaDetails,
240
244
  subscribeToPayViaRequest,
241
245
  subscribeToPayViaRoutes,
@@ -14,6 +14,7 @@ const {decodePaymentRequest} = require('./offchain');
14
14
  const {deleteFailedPayAttempts} = require('./offchain');
15
15
  const {deleteFailedPayments} = require('./offchain');
16
16
  const {deleteForwardingReputations} = require('./offchain');
17
+ const {deletePayment} = require('./offchain');
17
18
  const {deletePayments} = require('./offchain');
18
19
  const {diffieHellmanComputeSecret} = require('./signer');
19
20
  const {disableChannel} = require('./offchain');
@@ -118,6 +119,7 @@ const {updateChainTransaction} = require('./onchain');
118
119
  const {updateConnectedWatchtower} = require('./offchain');
119
120
  const {updatePathfindingSettings} = require('./offchain');
120
121
  const {updateRoutingFees} = require('./offchain');
122
+ const {verifyAccess} = require('./macaroon');
121
123
  const {verifyBackup} = require('./offchain');
122
124
  const {verifyBackups} = require('./offchain');
123
125
  const {verifyBytesSignature} = require('./signer');
@@ -140,6 +142,7 @@ module.exports = {
140
142
  deleteFailedPayAttempts,
141
143
  deleteFailedPayments,
142
144
  deleteForwardingReputations,
145
+ deletePayment,
143
146
  deletePayments,
144
147
  diffieHellmanComputeSecret,
145
148
  disableChannel,
@@ -244,6 +247,7 @@ module.exports = {
244
247
  updateConnectedWatchtower,
245
248
  updatePathfindingSettings,
246
249
  updateRoutingFees,
250
+ verifyAccess,
247
251
  verifyBackup,
248
252
  verifyBackups,
249
253
  verifyBytesSignature,
@@ -1,5 +1,6 @@
1
1
  const getAccessIds = require('./get_access_ids');
2
2
  const grantAccess = require('./grant_access');
3
3
  const revokeAccess = require('./revoke_access');
4
+ const verifyAccess = require('./verify_access');
4
5
 
5
- module.exports = {getAccessIds, grantAccess, revokeAccess};
6
+ module.exports = {getAccessIds, grantAccess, revokeAccess, verifyAccess};
@@ -0,0 +1,85 @@
1
+ const asyncAuto = require('async/auto');
2
+ const {returnResult} = require('asyncjs-util');
3
+
4
+ const {isLnd} = require('./../../lnd_requests');
5
+
6
+ const accessDeniedMessage = 'permission denied';
7
+ const asPermission = n => ({action: n.split(':')[1], entity: n.split(':')[0]});
8
+ const base64AsBuffer = base64 => Buffer.from(base64, 'base64');
9
+ const {isArray} = Array;
10
+ const isBoolean = n => n === false || n === true;
11
+ const method = 'checkMacaroonPermissions';
12
+ const notSupported = /unknown/;
13
+ const type = 'default';
14
+
15
+ /** Verify an access token has a given set of permissions
16
+
17
+ Note: this method is not supported in LND versions 0.13.1 and below
18
+
19
+ Requires `macaroon:read` permission
20
+
21
+ {
22
+ lnd: <Authenticated LND API Object>
23
+ macaroon: <Base64 Encoded Macaroon String>
24
+ permissions: [<Entity:Action String>]
25
+ }
26
+
27
+ @returns via cbk or Promise
28
+ {
29
+ is_valid: <Access Token is Valid For Described Permissions Bool>
30
+ }
31
+ */
32
+ module.exports = ({lnd, macaroon, permissions}, cbk) => {
33
+ return new Promise((resolve, reject) => {
34
+ return asyncAuto({
35
+ // Check arguments
36
+ validate: cbk => {
37
+ if (!isLnd({lnd, method, type})) {
38
+ return cbk([400, 'ExpectedAuthenticatedLndApiObjectToVerifyAccess']);
39
+ }
40
+
41
+ if (!macaroon) {
42
+ return cbk([400, 'ExpectedMacaroonToVerifyAccess']);
43
+ }
44
+
45
+ if (!isArray(permissions)) {
46
+ return cbk([400, 'ExpectedPermissionsArrayToVerifyAccess']);
47
+ }
48
+
49
+ return cbk();
50
+ },
51
+
52
+ // Check macaroon access
53
+ check: ['validate', ({}, cbk) => {
54
+ return lnd[type][method]({
55
+ macaroon: base64AsBuffer(macaroon),
56
+ permissions: permissions.map(permission => asPermission(permission)),
57
+ },
58
+ (err, res) => {
59
+ if (!!err && notSupported.test(err.details)) {
60
+ return cbk([501, 'VerifyAccessMethodNotSupported']);
61
+ }
62
+
63
+ if (!!err && err.details === accessDeniedMessage) {
64
+ return cbk(null, {is_valid: false});
65
+ }
66
+
67
+ if (!!err) {
68
+ return cbk([503, 'UnexpectedErrorFromCheckMacaroonMethod', {err}]);
69
+ }
70
+
71
+ if (!res) {
72
+ return cbk([503, 'ExpectedResponseFromCheckMacaroonRequest']);
73
+ }
74
+
75
+ if (!isBoolean(res.valid)) {
76
+ return cbk([503, 'ExpectedValidIndicatorInCheckMacaroonResponse']);
77
+ }
78
+
79
+ return cbk(null, {is_valid: res.valid});
80
+ });
81
+ }],
82
+ },
83
+ returnResult({reject, resolve, of: 'check'}, cbk));
84
+ });
85
+ };
@@ -3,7 +3,11 @@ const {returnResult} = require('asyncjs-util');
3
3
 
4
4
  const {isLnd} = require('./../../lnd_requests');
5
5
 
6
- const method = 'deleteAllPayments';
6
+ const deleteAllMethod = 'deleteAllPayments';
7
+ const deleteOneMethod = 'deletePayment';
8
+ const hexAsBuffer = hex => Buffer.from(hex, 'hex');
9
+ const isHash = n => /^[0-9A-F]{64}$/i.test(n);
10
+ const notSupported = /unknown/;
7
11
  const type = 'default';
8
12
 
9
13
  /** Delete failed payment attempt records
@@ -12,18 +16,25 @@ const type = 'default';
12
16
 
13
17
  Method not supported on LND 0.12.1 or below
14
18
 
19
+ `id` is not supported on LND 0.13.1 or below
20
+
15
21
  {
22
+ [id]: <Delete Only Failed Attempt Records For Payment With Hash Hex String>
16
23
  lnd: <Authenticated LND API Object>
17
24
  }
18
25
 
19
26
  @returns via cbk or Promise
20
27
  */
21
- module.exports = ({lnd}, cbk) => {
28
+ module.exports = ({id, lnd}, cbk) => {
22
29
  return new Promise((resolve, reject) => {
23
30
  return asyncAuto({
24
31
  // Check arguments
25
32
  validate: cbk => {
26
- if (!isLnd({lnd, method, type})) {
33
+ if (!!id && !isHash(id)) {
34
+ return cbk([400, 'ExpectedPaymentHashToDeleteFailedPayAttempts']);
35
+ }
36
+
37
+ if (!isLnd({lnd, type, method: deleteAllMethod})) {
27
38
  return cbk([400, 'ExpectedAuthenticatedLndToDeleteFailedAttempts']);
28
39
  }
29
40
 
@@ -32,7 +43,17 @@ module.exports = ({lnd}, cbk) => {
32
43
 
33
44
  // Delete failed payments
34
45
  deletePayments: ['validate', ({}, cbk) => {
35
- return lnd[type][method]({failed_htlcs_only: true}, err => {
46
+ const method = !id ? deleteAllMethod : deleteOneMethod;
47
+
48
+ return lnd[type][method]({
49
+ failed_htlcs_only: true,
50
+ id: !!id ? hexAsBuffer(id) : undefined,
51
+ },
52
+ err => {
53
+ if (!!err && notSupported.test(err.details)) {
54
+ return cbk([501, 'DeleteFailedPaymentAttemptsMethodNotSupported']);
55
+ }
56
+
36
57
  if (!!err) {
37
58
  return cbk([503, 'UnexpectedErrorDeletingFailedAttempts', {err}]);
38
59
  }
@@ -0,0 +1,18 @@
1
+ import {
2
+ AuthenticatedLightningArgs,
3
+ AuthenticatedLightningMethod,
4
+ } from '../../typescript';
5
+
6
+ export type DeletePaymentArgs = AuthenticatedLightningArgs<{
7
+ /** Payment Preimage Hash Hex String */
8
+ id: string;
9
+ }>;
10
+
11
+ /**
12
+ * Delete a payment record
13
+ *
14
+ * Requires `offchain:write` permission
15
+ *
16
+ * Note: this method is not supported on LND 0.13.1 and below
17
+ */
18
+ export const deletePayment: AuthenticatedLightningMethod<DeletePaymentArgs>;
@@ -0,0 +1,58 @@
1
+ const asyncAuto = require('async/auto');
2
+ const {returnResult} = require('asyncjs-util');
3
+
4
+ const {isLnd} = require('./../../lnd_requests');
5
+
6
+ const hexAsBytes = hex => Buffer.from(hex, 'hex');
7
+ const isHash = n => !!n && /^[0-9A-F]{64}$/i.test(n);
8
+ const method = 'deletePayment';
9
+ const notSupported = /unknown/;
10
+ const type = 'default';
11
+
12
+ /** Delete a payment record
13
+
14
+ Requires `offchain:write` permission
15
+
16
+ Note: this method is not supported on LND 0.13.1 and below
17
+
18
+ {
19
+ id: <Payment Preimage Hash Hex String>
20
+ lnd: <Authenticated LND API Object>
21
+ }
22
+
23
+ @returns via cbk or Promise
24
+ */
25
+ module.exports = ({id, lnd}, cbk) => {
26
+ return new Promise((resolve, reject) => {
27
+ return asyncAuto({
28
+ // Check arguments
29
+ validate: cbk => {
30
+ if (!isHash(id)) {
31
+ return cbk([400, 'ExpectedPaymentHashToDeletePaymentRecord']);
32
+ }
33
+
34
+ if (!isLnd({lnd, method, type})) {
35
+ return cbk([400, 'ExpectedAuthenticatedLndToDeletePayment']);
36
+ }
37
+
38
+ return cbk();
39
+ },
40
+
41
+ // Delete all payments
42
+ deletePayments: ['validate', ({}, cbk) => {
43
+ return lnd[type][method]({payment_hash: hexAsBytes(id)}, err => {
44
+ if (!!err && notSupported.test(err.details)) {
45
+ return cbk([501, 'DeletePaymentMethodNotSupported']);
46
+ }
47
+
48
+ if (!!err) {
49
+ return cbk([503, 'UnexpectedErrorDeletingPayment', {err}]);
50
+ }
51
+
52
+ return cbk();
53
+ });
54
+ }],
55
+ },
56
+ returnResult({reject, resolve}, cbk));
57
+ });
58
+ };
@@ -1,7 +1,7 @@
1
1
  import * as events from 'events';
2
2
  import {ConfirmedFromPaymentResult} from '../../lnd_responses/confirmed_from_payment';
3
3
  import {FailureFromPaymentResult} from '../../lnd_responses/failure_from_payment';
4
- import {LightningError, PaymentState} from '../../typescript';
4
+ import {EmptyObject, LightningError, PaymentState} from '../../typescript';
5
5
 
6
6
  export type EmitPaymentArgs = {
7
7
  data: {
@@ -14,8 +14,8 @@ export type EmitPaymentConfirmedEvent = ConfirmedFromPaymentResult;
14
14
 
15
15
  export type EmitPaymentFailedEvent = FailureFromPaymentResult;
16
16
 
17
- export type EmitPaymentPayingEvent = {[key: string]: never};
17
+ export type EmitPaymentPayingEvent = EmptyObject;
18
18
 
19
- export type EmitPaymentError = LightningError<never>;
19
+ export type EmitPaymentError = LightningError<undefined>;
20
20
 
21
21
  export const emitPayment: (args: EmitPaymentArgs) => boolean | undefined;
@@ -28,6 +28,10 @@ export type GetPaymentResult = {
28
28
  payment?: {
29
29
  /** Confirmed at ISO-8601 Date */
30
30
  confirmed_at: string;
31
+ /** Created at ISO-8601 Date */
32
+ created_at: string;
33
+ /** Payment Destination Public Key Hex */
34
+ destination: string;
31
35
  /** Total Fee Millitokens To Pay */
32
36
  fee_mtokens: string;
33
37
  hops: {
@@ -52,6 +56,8 @@ export type GetPaymentResult = {
52
56
  id: string;
53
57
  /** Total Millitokens Paid */
54
58
  mtokens: string;
59
+ /** BOLT 11 Payment Request */
60
+ request?: string;
55
61
  /** Payment Forwarding Fee Rounded Up Tokens */
56
62
  safe_fee: number;
57
63
  /** Payment Tokens Rounded Up */
@@ -30,6 +30,8 @@ const type = 'router';
30
30
  [is_pending]: <Payment Is Pending Bool>
31
31
  [payment]: {
32
32
  confirmed_at: <Payment Confirmed At ISO 8601 Date String>
33
+ created_at: <Payment Created At ISO 8601 Date String>
34
+ destination: <Payment Destination Hex String>
33
35
  fee: <Total Fees Paid Rounded Down Number>
34
36
  fee_mtokens: <Total Fee Millitokens Paid String>
35
37
  hops: [{
@@ -57,6 +59,7 @@ const type = 'router';
57
59
  }]
58
60
  mtokens: <Total Millitokens Paid String>
59
61
  }]
62
+ [request]: <BOLT 11 Encoded Payment Request String>
60
63
  safe_fee: <Payment Forwarding Fee Rounded Up Tokens Number>
61
64
  safe_tokens: <Payment Tokens Rounded Up Number>
62
65
  secret: <Payment Preimage Hex String>
@@ -3,6 +3,7 @@ export * from './decode_payment_request';
3
3
  export * from './delete_failed_pay_attempts';
4
4
  export * from './delete_failed_payments';
5
5
  export * from './delete_forwarding_reputations';
6
+ export * from './delete_payment';
6
7
  export * from './delete_payments';
7
8
  export * from './disable_channel';
8
9
  export * from './disconnect_watchtower';
@@ -36,6 +37,7 @@ export * from './subscribe_to_forward_requests';
36
37
  export * from './subscribe_to_forwards';
37
38
  export * from './subscribe_to_open_requests';
38
39
  export * from './subscribe_to_past_payment';
40
+ export * from './subscribe_to_past_payments';
39
41
  export * from './subscribe_to_pay_via_details';
40
42
  export * from './subscribe_to_pay_via_request';
41
43
  export * from './subscribe_to_pay_via_routes';
@@ -3,6 +3,7 @@ const decodePaymentRequest = require('./decode_payment_request');
3
3
  const deleteFailedPayAttempts = require('./delete_failed_pay_attempts');
4
4
  const deleteFailedPayments = require('./delete_failed_payments');
5
5
  const deleteForwardingReputations = require('./delete_forwarding_reputations');
6
+ const deletePayment = require('./delete_payment');
6
7
  const deletePayments = require('./delete_payments');
7
8
  const disableChannel = require('./disable_channel');
8
9
  const disconnectWatchtower = require('./disconnect_watchtower');
@@ -53,6 +54,7 @@ module.exports = {
53
54
  deleteFailedPayAttempts,
54
55
  deleteFailedPayments,
55
56
  deleteForwardingReputations,
57
+ deletePayment,
56
58
  deletePayments,
57
59
  disableChannel,
58
60
  disconnectWatchtower,
@@ -11,6 +11,10 @@ export type SubscribeToPastPaymentArgs = AuthenticatedLightningArgs<{
11
11
  export type SubscribeToPastPaymentConfirmedEvent = {
12
12
  /** Confirmed at ISO-8601 Date */
13
13
  confirmed: string;
14
+ /** Created at ISO-8601 Date */
15
+ created_at: string;
16
+ /** Payment Destination Public Key Hex */
17
+ destination: string;
14
18
  /** Payment Forwarding Fee Rounded Down Tokens */
15
19
  fee: number;
16
20
  /** Total Fee Millitokens To Pay */
@@ -37,6 +41,8 @@ export type SubscribeToPastPaymentConfirmedEvent = {
37
41
  id: string;
38
42
  /** Total Millitokens Paid */
39
43
  mtokens: string;
44
+ /** BOLT 11 Payment Request */
45
+ request?: string;
40
46
  /** Payment Forwarding Fee Rounded Up Tokens */
41
47
  safe_fee: number;
42
48
  /** Payment Tokens Rounded Up */
@@ -41,6 +41,8 @@ const unknownServiceErr = 'unknown service verrpc.Versioner';
41
41
  @event 'confirmed'
42
42
  {
43
43
  confirmed_at: <Payment Confirmed At ISO 8601 Date String>
44
+ created_at: <Payment Created At ISO 8601 Date String>
45
+ destination: <Payment Destination Hex String>
44
46
  fee: <Total Fee Tokens Paid Rounded Down Number>
45
47
  fee_mtokens: <Total Fee Millitokens Paid String>
46
48
  id: <Payment Hash Hex String>
@@ -63,6 +65,7 @@ const unknownServiceErr = 'unknown service verrpc.Versioner';
63
65
  safe_tokens: <Total Tokens Paid, Rounded Up Number>
64
66
  timeout: <Expiration Block Height Number>
65
67
  }]
68
+ [request]: <BOLT 11 Encoded Payment Request String>
66
69
  safe_fee: <Total Fee Tokens Paid Rounded Up Number>
67
70
  safe_tokens: <Total Tokens Paid, Rounded Up Number>
68
71
  secret: <Payment Preimage Hex String>
@@ -0,0 +1,74 @@
1
+ import {
2
+ AuthenticatedLightningArgs,
3
+ AuthenticatedLightningSubscription,
4
+ EmptyObject,
5
+ LightningError,
6
+ } from '../../typescript';
7
+
8
+ export type SubscribeToPastPaymentsArgs = AuthenticatedLightningArgs;
9
+
10
+ export type SubscribeToPastPaymentsErrorEvent = LightningError;
11
+
12
+ export type SubscribeToPastPaymentsPaymentEvent = {
13
+ /** Payment Confirmed At ISO 8601 Date String */
14
+ confirmed_at: string;
15
+ /** Created at ISO-8601 Date */
16
+ created_at: string;
17
+ /** Payment Destination Public Key Hex */
18
+ destination: string;
19
+ /** Paid Routing Fee Rounded Down Tokens Number */
20
+ fee: number;
21
+ /** Paid Routing Fee in Millitokens String */
22
+ fee_mtokens: string;
23
+ /** Payment Preimage Hash String */
24
+ id: string;
25
+ /** Millitokens Sent to Destination String */
26
+ mtokens: string;
27
+ paths: [
28
+ {
29
+ /** Total Fee Millitokens Paid String */
30
+ fee_mtokens: string;
31
+ hops: [
32
+ {
33
+ /** Standard Format Channel Id String */
34
+ channel: string;
35
+ /** Channel Capacity Tokens Number */
36
+ channel_capacity: number;
37
+ /** Fee Tokens Rounded Down Number */
38
+ fee: number;
39
+ /** Fee Millitokens String */
40
+ fee_mtokens: string;
41
+ /** Forward Millitokens String */
42
+ forward_mtokens: string;
43
+ /** Public Key Hex String */
44
+ public_key: string;
45
+ /** Timeout Block Height Number */
46
+ timeout: number;
47
+ }
48
+ ];
49
+ /** Total Millitokens Paid String */
50
+ mtokens: string;
51
+ }
52
+ ];
53
+ /** BOLT 11 Payment Request */
54
+ request?: string;
55
+ /** Total Fee Tokens Paid Rounded Up Number */
56
+ safe_fee: number;
57
+ /** Total Tokens Paid, Rounded Up Number */
58
+ safe_tokens: number;
59
+ /** Payment Preimage Hex String */
60
+ secret: string;
61
+ /** Expiration Block Height Number */
62
+ timeout: number;
63
+ /** Total Tokens Paid Rounded Down Number */
64
+ tokens: number;
65
+ };
66
+
67
+ /**
68
+ * Subscribe to successful outgoing payments
69
+ *
70
+ * Requires `offchain:read` permission
71
+ *
72
+ * Note: Method not supported on LND 0.13.1 and below
73
+ */
74
+ export const subscribeToPastPayments: AuthenticatedLightningSubscription<SubscribeToPastPaymentsArgs>;
@@ -41,6 +41,8 @@ const unknownFailureMessage = '2 UNKNOWN: unknown failure detail type: <nil>';
41
41
  @event 'payment'
42
42
  {
43
43
  confirmed_at: <Payment Confirmed At ISO 8601 Date String>
44
+ created_at: <Payment Created At ISO 8601 Date String>
45
+ destination: <Payment Destination Hex String>
44
46
  fee: <Paid Routing Fee Rounded Down Tokens Number>
45
47
  fee_mtokens: <Paid Routing Fee in Millitokens String>
46
48
  id: <Payment Preimage Hash String>
@@ -58,6 +60,7 @@ const unknownFailureMessage = '2 UNKNOWN: unknown failure detail type: <nil>';
58
60
  }]
59
61
  mtokens: <Total Millitokens Paid String>
60
62
  }]
63
+ [request]: <BOLT 11 Encoded Payment Request String>
61
64
  safe_fee: <Total Fee Tokens Paid Rounded Up Number>
62
65
  safe_tokens: <Total Tokens Paid, Rounded Up Number>
63
66
  secret: <Payment Preimage Hex String>
@@ -63,7 +63,7 @@ export type SubscribeToProbeForRouteArgs = AuthenticatedLightningArgs<{
63
63
  total_mtokens?: string;
64
64
  }>;
65
65
 
66
- export type SubscribeToProbeForRouteErrorEvent = LightningError<never>;
66
+ export type SubscribeToProbeForRouteErrorEvent = LightningError<undefined>;
67
67
 
68
68
  export type SubscribeToProbeForRouteProbeSuccessEvent = {
69
69
  route: {
@@ -11,6 +11,9 @@ export type GetWalletStatusResult = {
11
11
  /** Is Wallet File Encrypted */
12
12
  is_locked?: boolean;
13
13
 
14
+ /** Is Wallet Ready For All RPC Calls */
15
+ is_ready?: boolean;
16
+
14
17
  /** Is Wallet Starting Up */
15
18
  is_starting?: boolean;
16
19
 
@@ -14,6 +14,8 @@ const unsupportedMessage = 'unknown service lnrpc.State';
14
14
 
15
15
  This method is not supported on LND 0.12.1 and below
16
16
 
17
+ `is_ready` is not supported on LND 0.13.1 and below
18
+
17
19
  {
18
20
  lnd: <Unauthenticated LND API Object>
19
21
  }
@@ -23,6 +25,7 @@ const unsupportedMessage = 'unknown service lnrpc.State';
23
25
  [is_absent]: <Wallet Not Created Bool>
24
26
  [is_active]: <Wallet Is Active Bool>
25
27
  [is_locked]: <Wallet File Encrypted And Wallet Not Active Bool>
28
+ [is_ready]: <Wallet Is Ready For RPC Calls Bool>
26
29
  [is_starting]: <Wallet Is Starting Up Bool>
27
30
  [is_waiting]: <Wallet Is Waiting To Start Bool>
28
31
  }
@@ -6,7 +6,7 @@ import {
6
6
  /** The wallet has yet to be created */
7
7
  export type SubscribeToWalletStatusAbsentEvent = EmptyObject;
8
8
 
9
- /** The wallet is activated and ready for all requests */
9
+ /** The wallet is activated and has started working */
10
10
  export type SubscribeToWalletStatusActiveEvent = EmptyObject;
11
11
 
12
12
  export type SubscribeToWalletStatusErrorEvent = Error;
@@ -14,6 +14,9 @@ export type SubscribeToWalletStatusErrorEvent = Error;
14
14
  /** The wallet is inactive because it is locked */
15
15
  export type SubscribeToWalletStatusLockedEvent = EmptyObject;
16
16
 
17
+ /** The wallet is ready for all RPC requests */
18
+ export type SubscribeToWalletStatusReadyEvent = EmptyObject;
19
+
17
20
  /** The wallet is in the process of starting */
18
21
  export type SubscribeToWalletStatusStartingEvent = EmptyObject;
19
22
 
@@ -8,6 +8,7 @@ const method = 'subscribeState';
8
8
  const stateAbsent = 'NON_EXISTING';
9
9
  const stateActive = 'RPC_ACTIVE';
10
10
  const stateLocked = 'LOCKED';
11
+ const stateReady = 'SERVER_ACTIVE';
11
12
  const stateStarting = 'UNLOCKED';
12
13
  const stateWaiting = 'WAITING_TO_START';
13
14
  const sumOf = arr => arr.reduce((sum, n) => sum + n, Number());
@@ -17,6 +18,8 @@ const type = 'status';
17
18
 
18
19
  This method is not supported on LND 0.12.1 and below
19
20
 
21
+ `ready` is not supported on LND 0.13.1 and below
22
+
20
23
  {
21
24
  lnd: <Unauthenticated LND API Object>
22
25
  }
@@ -40,6 +43,9 @@ const type = 'status';
40
43
  // The wallet is inactive because it is locked
41
44
  @event 'locked'
42
45
 
46
+ // The wallet is ready for all RPC server requests
47
+ @event 'ready'
48
+
43
49
  // The wallet is in the process of starting
44
50
  @event 'starting'
45
51
 
@@ -98,6 +104,9 @@ module.exports = ({lnd}) => {
98
104
  case stateLocked:
99
105
  return emitter.emit('locked', {});
100
106
 
107
+ case stateReady:
108
+ return emitter.emit('ready', {});
109
+
101
110
  case stateStarting:
102
111
  return emitter.emit('starting', {});
103
112
 
@@ -6,6 +6,7 @@ const {isArray} = Array;
6
6
  const is256Hex = n => !!n && /^[0-9A-F]{64}$/i.test(n);
7
7
  const {max} = Math;
8
8
  const mtokensAsTokens = mtokens => safeTokens({mtokens}).tokens;
9
+ const nsAsDate = ns => new Date(Number(BigInt(ns) / BigInt(1e6)));
9
10
 
10
11
  /** Calculate total payment details from RPC payment HTLC elements
11
12
 
@@ -65,6 +66,8 @@ const mtokensAsTokens = mtokens => safeTokens({mtokens}).tokens;
65
66
  @returns
66
67
  {
67
68
  confirmed_at: <Payment Confirmed At ISO 8601 Date String>
69
+ created_at: <Payment Created At ISO 8601 Date String>
70
+ destination: <Payment Destination Public Key Hex String>
68
71
  fee: <Total Fee Tokens Paid Rounded Down Number>
69
72
  fee_mtokens: <Total Fee Millitokens Paid String>
70
73
  hops: [{
@@ -97,6 +100,7 @@ const mtokensAsTokens = mtokens => safeTokens({mtokens}).tokens;
97
100
  safe_tokens: <Total Tokens Paid, Rounded Up Number>
98
101
  timeout: <Expiration Block Height Number>
99
102
  }]
103
+ [request]: <BOLT 11 Encoded Payment Request String>
100
104
  safe_fee: <Total Fee Tokens Paid Rounded Up Number>
101
105
  safe_tokens: <Total Tokens Paid, Rounded Up Number>
102
106
  secret: <Payment Preimage Hex String>
@@ -109,6 +113,10 @@ module.exports = payment => {
109
113
  throw new Error('ExpectedConfirmedPaymentToDeriveConfirmationDetails');
110
114
  }
111
115
 
116
+ if (!payment.creation_time_ns) {
117
+ throw new Error('ExpectedPaymentCreationDateToDerivePaymentDetails');
118
+ }
119
+
112
120
  if (!payment.fee_msat) {
113
121
  throw new Error('ExpectedPaymentFeeMillitokensAmountForPayment');
114
122
  }
@@ -141,14 +149,19 @@ module.exports = payment => {
141
149
  const [confirmedAt] = successes.map(n => n.confirmed_at).sort().reverse();
142
150
  const [success] = successes;
143
151
 
152
+ const [destination] = success.route.hops.map(n => n.public_key).reverse();
153
+
144
154
  return {
155
+ destination,
145
156
  confirmed_at: confirmedAt,
157
+ created_at: nsAsDate(payment.creation_time_ns).toISOString(),
146
158
  fee: safeTokens({mtokens: payment.fee_msat}).tokens,
147
159
  fee_mtokens: payment.fee_msat,
148
160
  hops: success.route.hops,
149
161
  id: payment.payment_hash,
150
162
  mtokens: mtokens.toString(),
151
163
  paths: successes.map(n => n.route),
164
+ request: payment.payment_request || undefined,
152
165
  safe_fee: safeTokens({mtokens: payment.fee_msat}).safe,
153
166
  safe_tokens: safeTokens({mtokens: mtokens.toString()}).safe,
154
167
  secret: payment.payment_preimage,
@@ -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,9 +8,9 @@
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
- "@types/node": "16.9.1",
13
+ "@types/node": "16.9.6",
14
14
  "@types/request": "2.48.7",
15
15
  "@types/ws": "7.4.7",
16
16
  "async": "3.2.1",
@@ -19,7 +19,7 @@
19
19
  "bn.js": "5.2.0",
20
20
  "body-parser": "1.19.0",
21
21
  "bolt07": "1.7.3",
22
- "bolt09": "0.1.5",
22
+ "bolt09": "0.2.0",
23
23
  "cbor": "8.0.0",
24
24
  "express": "4.17.1",
25
25
  "invoices": "2.0.0",
@@ -56,5 +56,5 @@
56
56
  "directory": "test/typescript"
57
57
  },
58
58
  "types": "index.d.ts",
59
- "version": "4.4.0"
59
+ "version": "4.7.1"
60
60
  }
@@ -0,0 +1,101 @@
1
+ const {test} = require('@alexbosworth/tap');
2
+
3
+ const {verifyAccess} = require('./../../../lnd_methods');
4
+
5
+ const makeArgs = overrides => {
6
+ const args = {
7
+ lnd: {
8
+ default: {
9
+ checkMacaroonPermissions: ({}, cbk) => cbk(null, {valid: true}),
10
+ },
11
+ },
12
+ macaroon: Buffer.from('macaroon').toString('base64'),
13
+ permissions: ['entity:action'],
14
+ };
15
+
16
+ Object.keys(overrides).forEach(k => args[k] = overrides[k]);
17
+
18
+ return args;
19
+ };
20
+
21
+ const tests = [
22
+ {
23
+ args: makeArgs({lnd: undefined}),
24
+ description: 'LND is required to verify access',
25
+ error: [400, 'ExpectedAuthenticatedLndApiObjectToVerifyAccess'],
26
+ },
27
+ {
28
+ args: makeArgs({macaroon: undefined}),
29
+ description: 'A macaroon is required',
30
+ error: [400, 'ExpectedMacaroonToVerifyAccess'],
31
+ },
32
+ {
33
+ args: makeArgs({permissions: undefined}),
34
+ description: 'Permissions to check are required',
35
+ error: [400, 'ExpectedPermissionsArrayToVerifyAccess'],
36
+ },
37
+ {
38
+ args: makeArgs({
39
+ lnd: {
40
+ default: {
41
+ checkMacaroonPermissions: ({}, cbk) => cbk({details: 'unknown ser'}),
42
+ },
43
+ },
44
+ }),
45
+ description: 'Method not supported error returned',
46
+ error: [501, 'VerifyAccessMethodNotSupported'],
47
+ },
48
+ {
49
+ args: makeArgs({
50
+ lnd: {
51
+ default: {
52
+ checkMacaroonPermissions: ({}, cbk) => cbk({
53
+ details: 'permission denied',
54
+ }),
55
+ },
56
+ },
57
+ }),
58
+ description: 'Method not supported error returned',
59
+ expected: {is_valid: false},
60
+ },
61
+ {
62
+ args: makeArgs({
63
+ lnd: {default: {checkMacaroonPermissions: ({}, cbk) => cbk('err')}},
64
+ }),
65
+ description: 'Errors are passed back',
66
+ error: [503, 'UnexpectedErrorFromCheckMacaroonMethod', {err: 'err'}],
67
+ },
68
+ {
69
+ args: makeArgs({
70
+ lnd: {default: {checkMacaroonPermissions: ({}, cbk) => cbk()}},
71
+ }),
72
+ description: 'A response is expected',
73
+ error: [503, 'ExpectedResponseFromCheckMacaroonRequest'],
74
+ },
75
+ {
76
+ args: makeArgs({
77
+ lnd: {default: {checkMacaroonPermissions: ({}, cbk) => cbk(null, {})}},
78
+ }),
79
+ description: 'A valid attribute is expected',
80
+ error: [503, 'ExpectedValidIndicatorInCheckMacaroonResponse'],
81
+ },
82
+ {
83
+ args: makeArgs({}),
84
+ description: 'Validity is returned',
85
+ expected: {is_valid: true},
86
+ },
87
+ ];
88
+
89
+ tests.forEach(({args, description, error, expected}) => {
90
+ return test(description, async ({end, rejects, strictSame}) => {
91
+ if (!!error) {
92
+ await rejects(() => verifyAccess(args), error, 'Got expected error');
93
+ } else {
94
+ const res = await verifyAccess(args);
95
+
96
+ strictSame(res, expected, 'Got expected result');
97
+ }
98
+
99
+ return end();
100
+ });
101
+ });
@@ -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
 
@@ -306,7 +306,7 @@ const tests = [
306
306
  {
307
307
  args: makeArgs({lnd: makeLnd({data: {status: 'SUCCEEDED'}})}),
308
308
  description: 'A payment attempt is in flight',
309
- error: [503, 'ExpectedPaymentFeeMillitokensAmountForPayment'],
309
+ error: [503, 'ExpectedPaymentCreationDateToDerivePaymentDetails'],
310
310
  },
311
311
  ];
312
312
 
@@ -204,6 +204,8 @@ const tests = [
204
204
  description: 'A past payment is emitted',
205
205
  expected: {
206
206
  confirmed_at: '1970-01-01T00:00:00.000Z',
207
+ created_at: '1970-01-01T00:00:00.000Z',
208
+ destination: '000000000000000000000000000000000000000000000000000000000000000000',
207
209
  fee: 1,
208
210
  fee_mtokens: '1000',
209
211
  hops: [
@@ -243,6 +245,7 @@ const tests = [
243
245
  total_mtokens: '1000',
244
246
  }
245
247
  ],
248
+ request: undefined,
246
249
  safe_fee: 1,
247
250
  safe_tokens: 2,
248
251
  secret: '0000000000000000000000000000000000000000000000000000000000000000',
@@ -54,6 +54,8 @@ const makeArgs = overrides => {
54
54
  const makeExpected = overrides => {
55
55
  const expected = {
56
56
  confirmed_at: '1970-01-01T00:00:00.000Z',
57
+ created_at: '1970-01-01T00:00:00.000Z',
58
+ destination: Buffer.alloc(33).toString('hex'),
57
59
  fee: 1,
58
60
  fee_mtokens: '1000',
59
61
  hops: [{
@@ -87,6 +89,7 @@ const makeExpected = overrides => {
87
89
  tokens: 1,
88
90
  total_mtokens: '1000',
89
91
  }],
92
+ request: undefined,
90
93
  safe_fee: 1,
91
94
  safe_tokens: 2,
92
95
  secret: Buffer.alloc(32).toString('hex'),
@@ -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,15 @@
1
+ import {expectError, expectType} from 'tsd';
2
+ import {AuthenticatedLnd} from '../../lnd_grpc';
3
+ import {deletePayment} from '../../lnd_methods';
4
+
5
+ const lnd = {} as AuthenticatedLnd;
6
+ const id = '0';
7
+
8
+ expectError(deletePayment());
9
+ expectError(deletePayment({}));
10
+ expectError(deletePayment({lnd}));
11
+ expectError(deletePayment({id}));
12
+
13
+ expectType<void>(await deletePayment({lnd, id}));
14
+
15
+ expectType<void>(deletePayment({lnd, id}, () => {}));
@@ -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}));
@@ -13,7 +13,9 @@ export type UnauthenticatedLightningArgs<TArgs = undefined> =
13
13
  ? {lnd: UnauthenticatedLnd}
14
14
  : TArgs & {lnd: UnauthenticatedLnd};
15
15
 
16
- export type LightningError<TDetails = any> = [number, string, TDetails];
16
+ export type LightningError<TError = {err: Error}> = TError extends undefined
17
+ ? [number, string]
18
+ : [number, string, TError];
17
19
 
18
20
  export type LightningCallback<TResult = void, TErrorDetails = any> = (
19
21
  error: LightningError<TErrorDetails> | undefined | null,