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.
- package/CHANGELOG.md +22 -0
- package/grpc/protos/lightning.proto +134 -2
- package/grpc/protos/stateservice.proto +3 -0
- package/index.js +4 -0
- package/lnd_methods/index.js +4 -0
- package/lnd_methods/macaroon/index.js +2 -1
- package/lnd_methods/macaroon/verify_access.js +85 -0
- package/lnd_methods/offchain/delete_failed_pay_attempts.js +25 -4
- package/lnd_methods/offchain/delete_payment.d.ts +18 -0
- package/lnd_methods/offchain/delete_payment.js +58 -0
- package/lnd_methods/offchain/emit_payment.d.ts +3 -3
- package/lnd_methods/offchain/get_payment.d.ts +6 -0
- package/lnd_methods/offchain/get_payment.js +3 -0
- package/lnd_methods/offchain/index.d.ts +2 -0
- package/lnd_methods/offchain/index.js +2 -0
- package/lnd_methods/offchain/subscribe_to_past_payment.d.ts +6 -0
- package/lnd_methods/offchain/subscribe_to_past_payment.js +3 -0
- package/lnd_methods/offchain/subscribe_to_past_payments.d.ts +74 -0
- package/lnd_methods/offchain/subscribe_to_past_payments.js +3 -0
- package/lnd_methods/offchain/subscribe_to_probe_for_route.d.ts +1 -1
- package/lnd_methods/unauthenticated/get_wallet_status.d.ts +3 -0
- package/lnd_methods/unauthenticated/get_wallet_status.js +3 -0
- package/lnd_methods/unauthenticated/subscribe_to_wallet_status.d.ts +4 -1
- package/lnd_methods/unauthenticated/subscribe_to_wallet_status.js +9 -0
- package/lnd_responses/confirmed_from_payment.js +13 -0
- package/lnd_responses/rpc_wallet_state_as_state.js +5 -0
- package/package.json +4 -4
- package/test/lnd_methods/macaroon/test_verify_access.js +101 -0
- package/test/lnd_methods/offchain/test_delete_failed_pay_attempts.js +18 -0
- package/test/lnd_methods/offchain/test_delete_payment.js +51 -0
- package/test/lnd_methods/offchain/test_delete_payments.js +1 -1
- package/test/lnd_methods/offchain/test_pay_via_payment_details.js +1 -1
- package/test/lnd_methods/offchain/test_subscribe_to_past_payments.js +3 -0
- package/test/lnd_responses/test_confirmed_from_payment.js +3 -0
- package/test/lnd_responses/test_rpc_wallet_state_as_state.js +5 -0
- package/test/protos/protos.json +1 -1
- package/test/typescript/delete_payment.test-d.ts +15 -0
- package/test/typescript/subscribe_to_past_payments.test-d.ts +11 -0
- 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
|
-
|
|
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
|
+
}
|
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,
|
package/lnd_methods/index.js
CHANGED
|
@@ -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
|
|
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 (!
|
|
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
|
-
|
|
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 =
|
|
17
|
+
export type EmitPaymentPayingEvent = EmptyObject;
|
|
18
18
|
|
|
19
|
-
export type EmitPaymentError = LightningError<
|
|
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<
|
|
66
|
+
export type SubscribeToProbeForRouteErrorEvent = LightningError<undefined>;
|
|
67
67
|
|
|
68
68
|
export type SubscribeToProbeForRouteProbeSuccessEvent = {
|
|
69
69
|
route: {
|
|
@@ -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
|
|
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.
|
|
11
|
+
"@grpc/proto-loader": "0.6.5",
|
|
12
12
|
"@types/express": "4.17.13",
|
|
13
|
-
"@types/node": "16.9.
|
|
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.
|
|
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.
|
|
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
|
+
});
|
|
@@ -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, '
|
|
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',
|
package/test/protos/protos.json
CHANGED
|
@@ -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}));
|
package/typescript/shared.d.ts
CHANGED
|
@@ -13,7 +13,9 @@ export type UnauthenticatedLightningArgs<TArgs = undefined> =
|
|
|
13
13
|
? {lnd: UnauthenticatedLnd}
|
|
14
14
|
: TArgs & {lnd: UnauthenticatedLnd};
|
|
15
15
|
|
|
16
|
-
export type LightningError<
|
|
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,
|