lightning 5.6.0 → 5.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,20 @@
1
+ name: "Unit test"
2
+
3
+ on:
4
+ pull_request:
5
+ branches: [ master ]
6
+
7
+ jobs:
8
+ unit-test:
9
+ name: Node ${{ matrix.node }} unit test on ${{ matrix.os }}
10
+ runs-on: ${{ matrix.os }}
11
+ strategy:
12
+ matrix:
13
+ os: [ubuntu-latest]
14
+ node: ['12', '14', '16']
15
+ steps:
16
+ - uses: actions/checkout@v2
17
+ - uses: actions/setup-node@v2
18
+ - run: npm install
19
+ - name: Run unit tests
20
+ run: npm test
package/CHANGELOG.md CHANGED
@@ -1,6 +1,10 @@
1
1
  # Versions
2
2
 
3
- ## 5.6.0
3
+ ## 5.7.0
4
+
5
+ - `getPendingPayments`: Add method to get a list of in-flight payments
6
+
7
+ ## 5.6.3
4
8
 
5
9
  - `payViaRoutes`, `subscribeToPayViaRoutes`: Add support for relay messages
6
10
 
package/README.md CHANGED
@@ -42,8 +42,8 @@ Run `base64` on the tls.cert and admin.macaroon files to get the encoded
42
42
  authentication data to create the LND connection. You can find these files in
43
43
  the LND directory. (~/.lnd or ~/Library/Application Support/Lnd)
44
44
 
45
- base64 ~/.lnd/tls.cert | tr -d '\n'
46
- base64 ~/.lnd/data/chain/bitcoin/mainnet/admin.macaroon | tr -d '\n'
45
+ base64 -w0 ~/.lnd/tls.cert
46
+ base64 -w0 ~/.lnd/data/chain/bitcoin/mainnet/admin.macaroon
47
47
 
48
48
  You can then use these to interact with your LND node directly:
49
49
 
@@ -178,6 +178,8 @@ To access unauthenticated methods like the wallet unlocker, use
178
178
  Calculate the unconfirmed on-chain balance.
179
179
  - [getPendingChannels](https://github.com/alexbosworth/ln-service#getpendingchannels): List
180
180
  details of opening or closing channels.
181
+ - [getPendingPayments](https://github.com/alexbosworth/ln-service#getpendingpayments): List out
182
+ past pending payments.
181
183
  - [getPublicKey](https://github.com/alexbosworth/ln-service#getpublickey): Derive a public key at
182
184
  a given index.
183
185
  - [getRouteConfidence](https://github.com/alexbosworth/ln-service#getrouteconfidence): Check a
@@ -753,7 +753,8 @@ message SendRequest {
753
753
  The maximum number of satoshis that will be paid as a fee of the payment.
754
754
  This value can be represented either as a percentage of the amount being
755
755
  sent, or as a fixed amount of the maximum fee the user is willing the pay to
756
- send the payment.
756
+ send the payment. If not specified, lnd will use a default value of 100%
757
+ fees for small amounts (<=1k sat) or 5% fees for larger amounts.
757
758
  */
758
759
  FeeLimit fee_limit = 8;
759
760
 
@@ -2574,7 +2575,8 @@ message QueryRoutesRequest {
2574
2575
  The maximum number of satoshis that will be paid as a fee of the payment.
2575
2576
  This value can be represented either as a percentage of the amount being
2576
2577
  sent, or as a fixed amount of the maximum fee the user is willing the pay to
2577
- send the payment.
2578
+ send the payment. If not specified, lnd will use a default value of 100%
2579
+ fees for small amounts (<=1k sat) or 5% fees for larger amounts.
2578
2580
  */
2579
2581
  FeeLimit fee_limit = 5;
2580
2582
 
@@ -781,6 +781,21 @@ message ForwardHtlcInterceptResponse {
781
781
 
782
782
  // The preimage in case the resolve action is Settle.
783
783
  bytes preimage = 3;
784
+
785
+ // Encrypted failure message in case the resolve action is Fail.
786
+ //
787
+ // If failure_message is specified, the failure_code field must be set
788
+ // to zero.
789
+ bytes failure_message = 4;
790
+
791
+ // Return the specified failure code in case the resolve action is Fail. The
792
+ // message data fields are populated automatically.
793
+ //
794
+ // If a non-zero failure_code is specified, failure_message must not be set.
795
+ //
796
+ // For backwards-compatibility reasons, TEMPORARY_CHANNEL_FAILURE is the
797
+ // default value for this field.
798
+ lnrpc.Failure.FailureCode failure_code = 5;
784
799
  }
785
800
 
786
801
  enum ResolveHoldForwardAction {
package/index.js CHANGED
@@ -48,6 +48,7 @@ const {getIdentity} = require('./lnd_methods');
48
48
  const {getInvoice} = require('./lnd_methods');
49
49
  const {getInvoices} = require('./lnd_methods');
50
50
  const {getLockedUtxos} = require('./lnd_methods');
51
+ const {getMasterPublicKeys} = require('./lnd_methods');
51
52
  const {getMethods} = require('./lnd_methods');
52
53
  const {getNetworkCentrality} = require('./lnd_methods');
53
54
  const {getNetworkGraph} = require('./lnd_methods');
@@ -59,6 +60,7 @@ const {getPayments} = require('./lnd_methods');
59
60
  const {getPeers} = require('./lnd_methods');
60
61
  const {getPendingChainBalance} = require('./lnd_methods');
61
62
  const {getPendingChannels} = require('./lnd_methods');
63
+ const {getPendingPayments} = require('./lnd_methods');
62
64
  const {getPublicKey} = require('./lnd_methods');
63
65
  const {getRouteConfidence} = require('./lnd_methods');
64
66
  const {getRouteThroughHops} = require('./lnd_methods');
@@ -186,6 +188,7 @@ module.exports = {
186
188
  getInvoice,
187
189
  getInvoices,
188
190
  getLockedUtxos,
191
+ getMasterPublicKeys,
189
192
  getMethods,
190
193
  getNetworkCentrality,
191
194
  getNetworkGraph,
@@ -197,6 +200,7 @@ module.exports = {
197
200
  getPeers,
198
201
  getPendingChainBalance,
199
202
  getPendingChannels,
203
+ getPendingPayments,
200
204
  getPublicKey,
201
205
  getRouteConfidence,
202
206
  getRouteThroughHops,
@@ -46,6 +46,7 @@ const {getIdentity} = require('./info');
46
46
  const {getInvoice} = require('./invoices');
47
47
  const {getInvoices} = require('./invoices');
48
48
  const {getLockedUtxos} = require('./onchain');
49
+ const {getMasterPublicKeys} = require('./onchain');
49
50
  const {getMethods} = require('./info');
50
51
  const {getNetworkCentrality} = require('./info');
51
52
  const {getNetworkGraph} = require('./info');
@@ -57,6 +58,7 @@ const {getPayments} = require('./offchain');
57
58
  const {getPeers} = require('./peers');
58
59
  const {getPendingChainBalance} = require('./onchain');
59
60
  const {getPendingChannels} = require('./offchain');
61
+ const {getPendingPayments} = require('./offchain');
60
62
  const {getPublicKey} = require('./address');
61
63
  const {getRouteConfidence} = require('./generic');
62
64
  const {getRouteThroughHops} = require('./offchain');
@@ -180,6 +182,7 @@ module.exports = {
180
182
  getInvoice,
181
183
  getInvoices,
182
184
  getLockedUtxos,
185
+ getMasterPublicKeys,
183
186
  getMethods,
184
187
  getNetworkCentrality,
185
188
  getNetworkGraph,
@@ -191,6 +194,7 @@ module.exports = {
191
194
  getPeers,
192
195
  getPendingChainBalance,
193
196
  getPendingChannels,
197
+ getPendingPayments,
194
198
  getPublicKey,
195
199
  getRouteConfidence,
196
200
  getRouteThroughHops,
@@ -20,6 +20,7 @@
20
20
  "versions": {
21
21
  "0d5b0fefa4d9082f7964836f5e58c3a6bda8e471": "0.10.2-beta",
22
22
  "1a3194d302f33bb52823297d9d7f75cd37516053": "0.10.0-beta",
23
+ "1e511be523eb8e97c4e2d9c89a7a263963a3929f": "0.14.2-beta",
23
24
  "3ae46d81f4a2edad06ef778b2940d9b06386d93b": "0.11.0-beta",
24
25
  "4f567577db9d85b6f392f960b3aabddcad3cd02c": "0.13.3-beta",
25
26
  "52bb3f33707b81972c67937c7a89addcdf00991c": "0.10.1-beta",
@@ -181,6 +181,10 @@
181
181
  "method": "ListLeases",
182
182
  "type": "wallet"
183
183
  },
184
+ "getMasterPublicKeys": {
185
+ "method": "ListAccounts",
186
+ "type": "wallet"
187
+ },
184
188
  "getMethods": {
185
189
  "method": "ListPermissions",
186
190
  "type": "default"
@@ -226,6 +230,10 @@
226
230
  "method": "PendingChannels",
227
231
  "type": "default"
228
232
  },
233
+ "getPendingPayments": {
234
+ "method": "ListPayments",
235
+ "type": "default"
236
+ },
229
237
  "getPublicKey": {
230
238
  "methods": ["DeriveKey", "DeriveNextKey"],
231
239
  "type": "wallet"
@@ -0,0 +1,136 @@
1
+ import {
2
+ AuthenticatedLightningArgs,
3
+ AuthenticatedLightningMethod,
4
+ PaginationArgs,
5
+ } from '../../typescript';
6
+
7
+ export type GetPendingPaymentsArgs = AuthenticatedLightningArgs<PaginationArgs>;
8
+
9
+ export type GetPendingPaymentsResult = {
10
+ payments: {
11
+ attempts: {
12
+ failure?: {
13
+ /** Error Type Code Number */
14
+ code: number;
15
+ details?: {
16
+ /** Standard Format Channel Id String */
17
+ channel?: string;
18
+ /** Error Associated Block Height Number */
19
+ height?: number;
20
+ /** Pending Hop Index Number */
21
+ index?: number;
22
+ /** Error Millitokens String */
23
+ mtokens?: string;
24
+ policy?: {
25
+ /** Base Fee Millitokens String */
26
+ base_fee_mtokens: string;
27
+ /** Locktime Delta Number */
28
+ cltv_delta: number;
29
+ /** Fees Charged in Millitokens Per Million Number */
30
+ fee_rate: number;
31
+ /** Channel is Disabled Bool */
32
+ is_disabled?: boolean;
33
+ /** Maximum HLTC Millitokens Value String */
34
+ max_htlc_mtokens: string;
35
+ /** Minimum HTLC Millitokens Value String */
36
+ min_htlc_mtokens: string;
37
+ /** Updated At ISO 8601 Date String */
38
+ updated_at: string;
39
+ };
40
+ /** Error CLTV Timeout Height Number */
41
+ timeout_height?: number;
42
+ update?: {
43
+ /** Chain Id Hex String */
44
+ chain: string;
45
+ /** Channel Flags Number */
46
+ channel_flags: number;
47
+ /** Extra Opaque Data Hex String */
48
+ extra_opaque_data: string;
49
+ /** Message Flags Number */
50
+ message_flags: number;
51
+ /** Channel Update Signature Hex String */
52
+ signature: string;
53
+ };
54
+ };
55
+ /** Error Message String */
56
+ message: string;
57
+ };
58
+ /** Payment Add Index Number */
59
+ index?: number;
60
+ /** Payment Confirmed At ISO 8601 Date String */
61
+ confirmed_at?: string;
62
+ /** Payment Attempt Succeeded Bool */
63
+ is_confirmed: boolean;
64
+ /** Payment Attempt Pending Bool */
65
+ is_failed: boolean;
66
+ /** Payment Attempt is Waiting For Resolution Bool */
67
+ is_pending: boolean;
68
+ route: {
69
+ /** Route Fee Tokens Number */
70
+ fee: number;
71
+ /** Route Fee Millitokens String */
72
+ fee_mtokens: string;
73
+ hops: {
74
+ /** Standard Format Channel Id String */
75
+ channel: string;
76
+ /** Channel Capacity Tokens Number */
77
+ channel_capacity: number;
78
+ /** Fee Number */
79
+ fee: number;
80
+ /** Fee Millitokens String */
81
+ fee_mtokens: string;
82
+ /** Forward Tokens Number */
83
+ forward: number;
84
+ /** Forward Millitokens String */
85
+ forward_mtokens: string;
86
+ /** Forward Edge Public Key Hex String */
87
+ public_key?: string;
88
+ /** Timeout Block Height Number */
89
+ timeout?: number;
90
+ }[];
91
+ /** Total Fee-Inclusive Millitokens String */
92
+ mtokens: string;
93
+ /** Payment Identifier Hex String */
94
+ payment?: string;
95
+ /** Timeout Block Height Number */
96
+ timeout: number;
97
+ /** Total Fee-Inclusive Tokens Number */
98
+ tokens: number;
99
+ /** Total Millitokens String */
100
+ total_mtokens?: string;
101
+ };
102
+ }[];
103
+ /** Payment at ISO-8601 Date String */
104
+ created_at: string;
105
+ /** Destination Node Public Key Hex String */
106
+ destination?: string;
107
+ /** Payment Preimage Hash String */
108
+ id: string;
109
+ /** Payment Add Index Number */
110
+ index?: number;
111
+ /** Payment is Confirmed Bool */
112
+ is_confirmed: boolean;
113
+ /** Transaction Is Outgoing Bool */
114
+ is_outgoing: boolean;
115
+ /** Millitokens Attempted to Pay to Destination String */
116
+ mtokens: string;
117
+ /** BOLT 11 Payment Request String */
118
+ request?: string;
119
+ /** Payment Tokens Attempted to Pay Rounded Up Number */
120
+ safe_tokens: number;
121
+ /** Rounded Down Tokens Attempted to Pay to Destination Number */
122
+ tokens: number;
123
+ }[];
124
+ /** Next Opaque Paging Token String */
125
+ next?: string;
126
+ };
127
+
128
+ /**
129
+ * Get pending payments made through channels.
130
+ *
131
+ * Requires `offchain:read` permission
132
+ */
133
+ export const getPendingPayments: AuthenticatedLightningMethod<
134
+ GetPendingPaymentsArgs,
135
+ GetPendingPaymentsResult
136
+ >;
@@ -0,0 +1,190 @@
1
+ const asyncAuto = require('async/auto');
2
+ const {returnResult} = require('asyncjs-util');
3
+
4
+ const {isLnd} = require('./../../lnd_requests');
5
+ const {rpcPaymentAsPayment} = require('./../../lnd_responses');
6
+ const {sortBy} = require('./../../arrays');
7
+
8
+ const defaultLimit = 250;
9
+ const {isArray} = Array;
10
+ const isPending = payment => !!payment && payment.status === 'IN_FLIGHT';
11
+ const lastPageFirstIndexOffset = 1;
12
+ const method = 'listPayments';
13
+ const {parse} = JSON;
14
+ const {stringify} = JSON;
15
+ const type = 'default';
16
+
17
+ /** Get pending payments made through channels.
18
+
19
+ Requires `offchain:read` permission
20
+
21
+ {
22
+ [limit]: <Page Result Limit Number>
23
+ lnd: <Authenticated LND API Object>
24
+ [token]: <Opaque Paging Token String>
25
+ }
26
+
27
+ @returns via cbk or Promise
28
+ {
29
+ payments: [{
30
+ attempts: [{
31
+ [failure]: {
32
+ code: <Error Type Code Number>
33
+ [details]: {
34
+ [channel]: <Standard Format Channel Id String>
35
+ [height]: <Error Associated Block Height Number>
36
+ [index]: <Failed Hop Index Number>
37
+ [mtokens]: <Error Millitokens String>
38
+ [policy]: {
39
+ base_fee_mtokens: <Base Fee Millitokens String>
40
+ cltv_delta: <Locktime Delta Number>
41
+ fee_rate: <Fees Charged in Millitokens Per Million Number>
42
+ [is_disabled]: <Channel is Disabled Bool>
43
+ max_htlc_mtokens: <Maximum HLTC Millitokens Value String>
44
+ min_htlc_mtokens: <Minimum HTLC Millitokens Value String>
45
+ updated_at: <Updated At ISO 8601 Date String>
46
+ }
47
+ [timeout_height]: <Error CLTV Timeout Height Number>
48
+ [update]: {
49
+ chain: <Chain Id Hex String>
50
+ channel_flags: <Channel Flags Number>
51
+ extra_opaque_data: <Extra Opaque Data Hex String>
52
+ message_flags: <Message Flags Number>
53
+ signature: <Channel Update Signature Hex String>
54
+ }
55
+ }
56
+ message: <Error Message String>
57
+ }
58
+ [index]: <Payment Add Index Number>
59
+ [confirmed_at]: <Payment Confirmed At ISO 8601 Date String>
60
+ is_confirmed: <Payment Attempt Succeeded Bool>
61
+ is_failed: <Payment Attempt Failed Bool>
62
+ is_pending: <Payment Attempt is Waiting For Resolution Bool>
63
+ route: {
64
+ fee: <Route Fee Tokens Number>
65
+ fee_mtokens: <Route Fee Millitokens String>
66
+ hops: [{
67
+ channel: <Standard Format Channel Id String>
68
+ channel_capacity: <Channel Capacity Tokens Number>
69
+ fee: <Fee Number>
70
+ fee_mtokens: <Fee Millitokens String>
71
+ forward: <Forward Tokens Number>
72
+ forward_mtokens: <Forward Millitokens String>
73
+ [public_key]: <Forward Edge Public Key Hex String>
74
+ [timeout]: <Timeout Block Height Number>
75
+ }]
76
+ mtokens: <Total Fee-Inclusive Millitokens String>
77
+ [payment]: <Payment Identifier Hex String>
78
+ timeout: <Timeout Block Height Number>
79
+ tokens: <Total Fee-Inclusive Tokens Number>
80
+ [total_mtokens]: <Total Millitokens String>
81
+ }
82
+ }]
83
+ created_at: <Payment at ISO-8601 Date String>
84
+ [destination]: <Destination Node Public Key Hex String>
85
+ id: <Payment Preimage Hash String>
86
+ [index]: <Payment Add Index Number>
87
+ is_confirmed: <Payment is Confirmed Bool>
88
+ is_outgoing: <Transaction Is Outgoing Bool>
89
+ mtokens: <Millitokens Attempted to Pay to Destination String>
90
+ [request]: <BOLT 11 Payment Request String>
91
+ safe_tokens: <Payment Tokens Attempted to Pay Rounded Up Number>
92
+ tokens: <Rounded Down Tokens Attempted to Pay to Destination Number>
93
+ }]
94
+ [next]: <Next Opaque Paging Token String>
95
+ }
96
+ */
97
+ module.exports = ({limit, lnd, token}, cbk) => {
98
+ return new Promise((resolve, reject) => {
99
+ return asyncAuto({
100
+ // Check arguments
101
+ validate: cbk => {
102
+ if (!!limit && !!token) {
103
+ return cbk([400, 'ExpectedNoLimitPagingPendingPaymentsWithToken']);
104
+ }
105
+
106
+ if (!isLnd({lnd, method, type})) {
107
+ return cbk([400, 'ExpectedLndForGetPendingPaymentsRequest']);
108
+ }
109
+
110
+ return cbk();
111
+ },
112
+
113
+ // Get all payments
114
+ listPayments: ['validate', ({}, cbk) => {
115
+ let offset;
116
+ let resultsLimit = limit || defaultLimit;
117
+
118
+ if (!!token) {
119
+ try {
120
+ const pagingToken = parse(token);
121
+
122
+ offset = pagingToken.offset;
123
+ resultsLimit = pagingToken.limit;
124
+ } catch (err) {
125
+ return cbk([400, 'ExpectedValidPagingTokenForGetPending', {err}]);
126
+ }
127
+ }
128
+
129
+ return lnd[type][method]({
130
+ include_incomplete: true,
131
+ index_offset: offset || Number(),
132
+ max_payments: resultsLimit,
133
+ reversed: true,
134
+ },
135
+ (err, res) => {
136
+ if (!!err) {
137
+ return cbk([503, 'UnexpectedGetPendingPaymentsError', {err}]);
138
+ }
139
+
140
+ if (!res || !isArray(res.payments)) {
141
+ return cbk([503, 'ExpectedPendingPaymentsInListPaymentsResponse']);
142
+ }
143
+
144
+ if (typeof res.last_index_offset !== 'string') {
145
+ return cbk([503, 'ExpectedLastIndexOffsetWhenRequestingPending']);
146
+ }
147
+
148
+ const lastOffset = Number(res.last_index_offset);
149
+ const offset = Number(res.first_index_offset);
150
+
151
+ const token = stringify({offset, limit: resultsLimit});
152
+
153
+ return cbk(null, {
154
+ payments: res.payments.filter(isPending),
155
+ token: offset <= lastPageFirstIndexOffset ? undefined : token,
156
+ });
157
+ });
158
+ }],
159
+
160
+ // Check and map payments
161
+ foundPayments: ['listPayments', ({listPayments}, cbk) => {
162
+ try {
163
+ const payments = listPayments.payments.map(rpcPaymentAsPayment);
164
+
165
+ return cbk(null, payments);
166
+ } catch (err) {
167
+ return cbk([503, err.message]);
168
+ }
169
+ }],
170
+
171
+ // Final found pending payments
172
+ payments: [
173
+ 'foundPayments',
174
+ 'listPayments',
175
+ ({foundPayments, listPayments}, cbk) =>
176
+ {
177
+ const payments = sortBy({
178
+ array: foundPayments,
179
+ attribute: 'created_at',
180
+ });
181
+
182
+ return cbk(null, {
183
+ next: listPayments.token || undefined,
184
+ payments: payments.sorted.reverse(),
185
+ });
186
+ }],
187
+ },
188
+ returnResult({reject, resolve, of: 'payments'}, cbk));
189
+ });
190
+ };
@@ -24,6 +24,7 @@ export * from './get_pathfinding_settings';
24
24
  export * from './get_payment';
25
25
  export * from './get_payments';
26
26
  export * from './get_pending_channels';
27
+ export * from './get_pending_payments';
27
28
  export * from './get_route_through_hops';
28
29
  export * from './is_destination_payable';
29
30
  export * from './pay_via_payment_details';
@@ -24,6 +24,7 @@ const getPathfindingSettings = require('./get_pathfinding_settings');
24
24
  const getPayment = require('./get_payment');
25
25
  const getPayments = require('./get_payments');
26
26
  const getPendingChannels = require('./get_pending_channels');
27
+ const getPendingPayments = require('./get_pending_payments');
27
28
  const getRouteThroughHops = require('./get_route_through_hops');
28
29
  const isDestinationPayable = require('./is_destination_payable');
29
30
  const pay = require('./pay');
@@ -79,6 +80,7 @@ module.exports = {
79
80
  getPayment,
80
81
  getPayments,
81
82
  getPendingChannels,
83
+ getPendingPayments,
82
84
  getRouteThroughHops,
83
85
  isDestinationPayable,
84
86
  pay,
@@ -1,6 +1,7 @@
1
1
  const asyncAuto = require('async/auto');
2
2
  const {decodePsbt} = require('psbt');
3
3
  const {returnResult} = require('asyncjs-util');
4
+ const tinysecp = require('tiny-secp256k1');
4
5
  const {Transaction} = require('bitcoinjs-lib');
5
6
 
6
7
  const {isLnd} = require('./../../lnd_requests');
@@ -67,6 +68,9 @@ const txIdFromHash = hash => hash.reverse().toString('hex');
67
68
  module.exports = (args, cbk) => {
68
69
  return new Promise((resolve, reject) => {
69
70
  return asyncAuto({
71
+ // Import ECPair library
72
+ ecp: async () => (await import('ecpair')).ECPairFactory(tinysecp),
73
+
70
74
  // Check arguments
71
75
  validate: cbk => {
72
76
  if (!isLnd({method, type, lnd: args.lnd})) {
@@ -201,11 +205,11 @@ module.exports = (args, cbk) => {
201
205
  }],
202
206
 
203
207
  // Derive the raw transaction from the funded PSBT
204
- tx: ['fund', ({fund}, cbk) => {
208
+ tx: ['fund', ({ecp, fund}, cbk) => {
205
209
  const {psbt} = fund;
206
210
 
207
211
  try {
208
- const tx = fromHex(decodePsbt({psbt}).unsigned_transaction);
212
+ const tx = fromHex(decodePsbt({ecp, psbt}).unsigned_transaction);
209
213
 
210
214
  return cbk(null, tx);
211
215
  } catch (err) {
@@ -0,0 +1,83 @@
1
+ const asyncAuto = require('async/auto');
2
+ const {returnResult} = require('asyncjs-util');
3
+
4
+ const {isLnd} = require('./../../lnd_requests');
5
+
6
+ const {isArray} = Array;
7
+ const method = 'listAccounts';
8
+ const notSupported = /unknown.*walletrpc.WalletKit/;
9
+ const type = 'wallet';
10
+
11
+ /** Get the currently tracked master public keys
12
+
13
+ Requires LND compiled with `walletrpc` build tag
14
+
15
+ Requires `onchain:read` permission
16
+
17
+ This method is not supported in LND 0.13.3 and below
18
+
19
+ {
20
+ lnd: <Authenticated API LND Object>
21
+ }
22
+
23
+ @returns via cbk or Promise
24
+ {
25
+ keys: [{
26
+ derivation_path: <Key Derivation Path String>
27
+ extended_public_key: <Base58 Encoded Master Public Key String>
28
+ external_key_count: <Used External Keys Count Number>
29
+ internal_key_count: <Used Internal Keys Count Number>
30
+ is_watch_only: <Node has Master Private Key Bool>
31
+ named: <Account Name String>
32
+ }]
33
+ }
34
+ */
35
+ module.exports = ({lnd}, cbk) => {
36
+ return new Promise((resolve, reject) => {
37
+ return asyncAuto({
38
+ // Check arguments
39
+ validate: cbk => {
40
+ if (!isLnd({lnd, method, type})) {
41
+ return cbk([400, 'ExpectedAuthenticatedLndToGetMasterPublicKeys']);
42
+ }
43
+
44
+ return cbk();
45
+ },
46
+
47
+ // Get master public keys
48
+ getKeys: ['validate', ({}, cbk) => {
49
+ return lnd[type][method]({}, (err, res) => {
50
+ if (!!err && notSupported.test(err.details)) {
51
+ return cbk([501, 'GetMasterPublicKeysMethodNotSupported']);
52
+ }
53
+
54
+ if (!!err) {
55
+ return cbk([503, 'UnexpectedErrorGettingMasterPublicKeys', {err}]);
56
+ }
57
+
58
+ if (!res) {
59
+ return cbk([503, 'ExpectedResultForMasterPublicKeyListRequest']);
60
+ }
61
+
62
+ if (!isArray(res.accounts)) {
63
+ return cbk([503, 'ExpectedArrayOfAccountsInMasterPublicKeysList']);
64
+ }
65
+
66
+ const keys = res.accounts
67
+ .filter(account => !!account.extended_public_key)
68
+ .map(account => ({
69
+ derivation_path: account.derivation_path,
70
+ extended_public_key: account.extended_public_key,
71
+ external_key_count: account.external_key_count,
72
+ internal_key_count: account.internal_key_count,
73
+ is_watch_only: account.watch_only,
74
+ named: account.name,
75
+ }));
76
+
77
+ return cbk(null, {keys});
78
+ });
79
+ }],
80
+ },
81
+ returnResult({reject, resolve, of: 'getKeys'}, cbk));
82
+ });
83
+ };
@@ -8,6 +8,7 @@ const getChainFeeEstimate = require('./get_chain_fee_estimate');
8
8
  const getChainFeeRate = require('./get_chain_fee_rate');
9
9
  const getChainTransactions = require('./get_chain_transactions');
10
10
  const getLockedUtxos = require('./get_locked_utxos');
11
+ const getMasterPublicKeys = require('./get_master_public_keys');
11
12
  const getPendingChainBalance = require('./get_pending_chain_balance');
12
13
  const getSweepTransactions = require('./get_sweep_transactions');
13
14
  const getUtxos = require('./get_utxos');
@@ -41,6 +42,7 @@ module.exports = {
41
42
  getChainFeeRate,
42
43
  getChainTransactions,
43
44
  getLockedUtxos,
45
+ getMasterPublicKeys,
44
46
  getPendingChainBalance,
45
47
  getSweepTransactions,
46
48
  getUtxos,
@@ -23,8 +23,8 @@ const type = 'default';
23
23
 
24
24
  Requires `offchain:write`, `onchain:write` permissions
25
25
 
26
- After getting the addresses and tokens to fund, use `fundChannels` within ten
27
- minutes to fund the channels.
26
+ After getting the addresses and tokens to fund, use `fundPendingChannels`
27
+ within ten minutes to fund the channels.
28
28
 
29
29
  If you do not fund the channels, be sure to `cancelPendingChannel` on each
30
30
  channel that was not funded.
@@ -20,7 +20,7 @@ export type PartiallySignPsbtResult = {
20
20
  *
21
21
  * Requires LND built with `walletrpc` tag
22
22
  *
23
- * This method is not supported in LND 0.14.1 and below
23
+ * This method is not supported in LND 0.14.2 and below
24
24
  */
25
25
  export const partiallySignPsbt: AuthenticatedLightningMethod<
26
26
  PartiallySignPsbtArgs,
@@ -16,7 +16,7 @@ const type = 'wallet';
16
16
 
17
17
  Requires LND built with `walletrpc` tag
18
18
 
19
- This method is not supported in LND 0.14.1 and below
19
+ This method is not supported in LND 0.14.2 and below
20
20
 
21
21
  {
22
22
  lnd: <Authenticated LND API Object>
package/package.json CHANGED
@@ -7,10 +7,10 @@
7
7
  "url": "https://github.com/alexbosworth/lightning/issues"
8
8
  },
9
9
  "dependencies": {
10
- "@grpc/grpc-js": "1.5.4",
10
+ "@grpc/grpc-js": "1.5.5",
11
11
  "@grpc/proto-loader": "0.6.9",
12
12
  "@types/express": "4.17.13",
13
- "@types/node": "17.0.14",
13
+ "@types/node": "17.0.17",
14
14
  "@types/request": "2.48.8",
15
15
  "@types/ws": "8.2.2",
16
16
  "async": "3.2.3",
@@ -21,10 +21,12 @@
21
21
  "bolt07": "1.8.0",
22
22
  "bolt09": "0.2.1",
23
23
  "cbor": "8.1.0",
24
+ "ecpair": "2.0.1",
24
25
  "express": "4.17.2",
25
- "invoices": "2.0.3",
26
- "psbt": "1.1.11",
27
- "type-fest": "2.11.1"
26
+ "invoices": "2.0.4",
27
+ "psbt": "2.0.0",
28
+ "tiny-secp256k1": "2.2.0",
29
+ "type-fest": "2.11.2"
28
30
  },
29
31
  "description": "Lightning Network client library",
30
32
  "devDependencies": {
@@ -32,7 +34,7 @@
32
34
  "@alexbosworth/tap": "15.0.10",
33
35
  "tsd": "0.19.1",
34
36
  "typescript": "4.5.5",
35
- "ws": "8.4.2"
37
+ "ws": "8.5.0"
36
38
  },
37
39
  "engines": {
38
40
  "node": ">=12.20"
@@ -57,5 +59,5 @@
57
59
  "directory": "test/typescript"
58
60
  },
59
61
  "types": "index.d.ts",
60
- "version": "5.6.0"
62
+ "version": "5.7.0"
61
63
  }
@@ -1,6 +1,6 @@
1
1
  const {test} = require('@alexbosworth/tap');
2
2
 
3
- const {getPayments} = require('./../../../');
3
+ const {getFailedPayments} = require('./../../../');
4
4
 
5
5
  const makeLnd = args => {
6
6
  return {
@@ -64,41 +64,41 @@ const tests = [
64
64
  {
65
65
  args: makeArgs({limit: 1, token: 'token'}),
66
66
  description: 'A limit cannot be passed with a token',
67
- error: [400, 'UnexpectedLimitWhenPagingPaymentsWithToken'],
67
+ error: [400, 'ExpectedNoLimitWhenPagingPayFailuresWithToken'],
68
68
  },
69
69
  {
70
70
  args: makeArgs({lnd: undefined}),
71
71
  description: 'LND is required',
72
- error: [400, 'ExpectedLndForGetPaymentsRequest'],
72
+ error: [400, 'ExpectedLndForGetFailedPaymentsRequest'],
73
73
  },
74
74
  {
75
75
  args: makeArgs({token: 'token'}),
76
76
  description: 'A valid token is required',
77
- error: [400, 'ExpectedValidPagingTokenForPaymentReq'],
77
+ error: [400, 'ExpectedValidPagingTokenForGetFailed'],
78
78
  },
79
79
  {
80
80
  args: makeArgs({lnd: {default: {listPayments: ({}, cbk) => cbk('err')}}}),
81
81
  description: 'Errors from LND are passed back',
82
- error: [503, 'UnexpectedGetPaymentsError', {err: 'err'}],
82
+ error: [503, 'UnexpectedGetFailedPaymentsError', {err: 'err'}],
83
83
  },
84
84
  {
85
85
  args: makeArgs({lnd: {default: {listPayments: ({}, cbk) => cbk()}}}),
86
86
  description: 'A response is expected from LND',
87
- error: [503, 'ExpectedPaymentsInListPaymentsResponse'],
87
+ error: [503, 'ExpectedFailedPaymentsInListPaymentsResponse'],
88
88
  },
89
89
  {
90
90
  args: makeArgs({
91
91
  lnd: {default: {listPayments: ({}, cbk) => cbk(null, {})}},
92
92
  }),
93
93
  description: 'A response with payments is expected from LND',
94
- error: [503, 'ExpectedPaymentsInListPaymentsResponse'],
94
+ error: [503, 'ExpectedFailedPaymentsInListPaymentsResponse'],
95
95
  },
96
96
  {
97
97
  args: makeArgs({
98
98
  lnd: {default: {listPayments: ({}, cbk) => cbk(null, {payments: []})}},
99
99
  }),
100
100
  description: 'A response with payments and last index is expected',
101
- error: [503, 'ExpectedLastIndexOffsetWhenRequestingPayments'],
101
+ error: [503, 'ExpectedLastIndexOffsetWhenRequestingFailed'],
102
102
  },
103
103
  {
104
104
  args: makeArgs({
@@ -106,7 +106,7 @@ const tests = [
106
106
  default: {
107
107
  listPayments: ({}, cbk) => cbk(null, {
108
108
  last_index_offset: '1',
109
- payments: [{}],
109
+ payments: [{ status: 'FAILED' }],
110
110
  }),
111
111
  },
112
112
  },
@@ -146,9 +146,9 @@ const tests = [
146
146
  tests.forEach(({args, description, error, expected}) => {
147
147
  return test(description, async ({end, rejects, strictSame}) => {
148
148
  if (!!error) {
149
- await rejects(() => getPayments(args), error, 'Got expected error');
149
+ await rejects(() => getFailedPayments(args), error, 'Got expected error');
150
150
  } else {
151
- const {payments} = await getPayments(args);
151
+ const {payments} = await getFailedPayments(args);
152
152
 
153
153
  const [payment] = payments;
154
154
 
@@ -0,0 +1,160 @@
1
+ const {test} = require('@alexbosworth/tap');
2
+
3
+ const {getPendingPayments} = require('./../../../');
4
+
5
+ const makeLnd = args => {
6
+ return {
7
+ default: {
8
+ listPayments: ({}, cbk) => cbk(null, {
9
+ first_index_offset: args.first_index_offset || '1',
10
+ payments: [{
11
+ creation_date: '1',
12
+ creation_time_ns: '1',
13
+ failure_reason: '',
14
+ fee_msat: '1000',
15
+ fee_sat: '1',
16
+ htlcs: [],
17
+ path: [Buffer.alloc(33, 2).toString('hex')],
18
+ payment_hash: Buffer.alloc(32).toString('hex'),
19
+ payment_index: '1',
20
+ payment_preimage: Buffer.alloc(32).toString('hex'),
21
+ payment_request: '',
22
+ status: 'IN_FLIGHT',
23
+ value: '1',
24
+ value_msat: '1000',
25
+ value_sat: '1',
26
+ }],
27
+ last_index_offset: args.last_index_offset || '1',
28
+ }),
29
+ },
30
+ };
31
+ };
32
+
33
+ const makeArgs = overrides => {
34
+ const args = {lnd: makeLnd({})};
35
+
36
+ Object.keys(overrides).forEach(k => args[k] = overrides[k]);
37
+
38
+ return args;
39
+ };
40
+
41
+ const makeExpectedPayment = ({}) => {
42
+ return {
43
+ destination: undefined,
44
+ attempts: [],
45
+ confirmed_at: undefined,
46
+ created_at: '1970-01-01T00:00:00.000Z',
47
+ fee: undefined,
48
+ fee_mtokens: undefined,
49
+ hops: [],
50
+ id: '0000000000000000000000000000000000000000000000000000000000000000',
51
+ index: 1,
52
+ is_confirmed: false,
53
+ is_outgoing: true,
54
+ mtokens: '1000',
55
+ request: undefined,
56
+ secret: undefined,
57
+ safe_fee: undefined,
58
+ safe_tokens: 1,
59
+ tokens: 1,
60
+ };
61
+ };
62
+
63
+ const tests = [
64
+ {
65
+ args: makeArgs({limit: 1, token: 'token'}),
66
+ description: 'A limit cannot be passed with a token',
67
+ error: [400, 'ExpectedNoLimitPagingPendingPaymentsWithToken'],
68
+ },
69
+ {
70
+ args: makeArgs({lnd: undefined}),
71
+ description: 'LND is required',
72
+ error: [400, 'ExpectedLndForGetPendingPaymentsRequest'],
73
+ },
74
+ {
75
+ args: makeArgs({token: 'token'}),
76
+ description: 'A valid token is required',
77
+ error: [400, 'ExpectedValidPagingTokenForGetPending'],
78
+ },
79
+ {
80
+ args: makeArgs({lnd: {default: {listPayments: ({}, cbk) => cbk('err')}}}),
81
+ description: 'Errors from LND are passed back',
82
+ error: [503, 'UnexpectedGetPendingPaymentsError', {err: 'err'}],
83
+ },
84
+ {
85
+ args: makeArgs({lnd: {default: {listPayments: ({}, cbk) => cbk()}}}),
86
+ description: 'A response is expected from LND',
87
+ error: [503, 'ExpectedPendingPaymentsInListPaymentsResponse'],
88
+ },
89
+ {
90
+ args: makeArgs({
91
+ lnd: {default: {listPayments: ({}, cbk) => cbk(null, {})}},
92
+ }),
93
+ description: 'A response with payments is expected from LND',
94
+ error: [503, 'ExpectedPendingPaymentsInListPaymentsResponse'],
95
+ },
96
+ {
97
+ args: makeArgs({
98
+ lnd: {default: {listPayments: ({}, cbk) => cbk(null, {payments: []})}},
99
+ }),
100
+ description: 'A response with payments and last index is expected',
101
+ error: [503, 'ExpectedLastIndexOffsetWhenRequestingPending'],
102
+ },
103
+ {
104
+ args: makeArgs({
105
+ lnd: {
106
+ default: {
107
+ listPayments: ({}, cbk) => cbk(null, {
108
+ last_index_offset: '1',
109
+ payments: [{status: 'IN_FLIGHT'}],
110
+ }),
111
+ },
112
+ },
113
+ }),
114
+ description: 'A response with valid payments is expected',
115
+ error: [503, 'ExpectedCreationDateInRpcPaymentDetails'],
116
+ },
117
+ {
118
+ args: makeArgs({}),
119
+ description: 'A payment is returned',
120
+ expected: {payment: makeExpectedPayment({})},
121
+ },
122
+ {
123
+ args: makeArgs({
124
+ lnd: {
125
+ default: {
126
+ listPayments: ({}, cbk) => cbk(null, {
127
+ last_index_offset: '1',
128
+ payments: [],
129
+ }),
130
+ },
131
+ },
132
+ }),
133
+ description: 'No payments are returned',
134
+ expected: {},
135
+ },
136
+ {
137
+ args: makeArgs({
138
+ lnd: makeLnd({first_index_offset: '2'}),
139
+ token: JSON.stringify({limit: 1, offset: 1})
140
+ }),
141
+ description: 'A payment is returned when a token is specified',
142
+ expected: {payment: makeExpectedPayment({})},
143
+ },
144
+ ];
145
+
146
+ tests.forEach(({args, description, error, expected}) => {
147
+ return test(description, async ({end, rejects, strictSame}) => {
148
+ if (!!error) {
149
+ await rejects(() => getPendingPayments(args), error, 'Got error');
150
+ } else {
151
+ const {payments} = await getPendingPayments(args);
152
+
153
+ const [payment] = payments;
154
+
155
+ strictSame(payment, expected.payment, 'Got expected payment');
156
+ }
157
+
158
+ return end();
159
+ });
160
+ });
@@ -0,0 +1,94 @@
1
+ const {test} = require('@alexbosworth/tap');
2
+
3
+ const {getMasterPublicKeys} = require('./../../../lnd_methods');
4
+
5
+ const makeExpected = overrides => {
6
+ const res = {
7
+ derivation_path: 'derivation_path',
8
+ extended_public_key: 'extended_public_key',
9
+ external_key_count: 0,
10
+ internal_key_count: 1,
11
+ is_watch_only: true,
12
+ named: 'name',
13
+ };
14
+
15
+ Object.keys(overrides).forEach(k => res[k] = overrides[k]);
16
+
17
+ return {keys: [res]};
18
+ };
19
+
20
+ const makeLnd = overrides => {
21
+ return {
22
+ wallet: {
23
+ listAccounts: ({}, cbk) => {
24
+ const account = {
25
+ derivation_path: 'derivation_path',
26
+ extended_public_key: 'extended_public_key',
27
+ external_key_count: 0,
28
+ internal_key_count: 1,
29
+ name: 'name',
30
+ watch_only: true,
31
+ };
32
+
33
+ Object.keys(overrides).forEach(k => account[k] = overrides[k]);
34
+
35
+ return cbk(null, {accounts: [account]});
36
+ },
37
+ },
38
+ };
39
+ };
40
+
41
+ const tests = [
42
+ {
43
+ args: {},
44
+ description: 'LND Object is required to get master public keys',
45
+ error: [400, 'ExpectedAuthenticatedLndToGetMasterPublicKeys'],
46
+ },
47
+ {
48
+ args: {
49
+ lnd: {
50
+ wallet: {
51
+ listAccounts: ({}, cbk) => cbk({
52
+ details: 'unknown walletrpc.WalletKit',
53
+ }),
54
+ },
55
+ },
56
+ },
57
+ description: 'LND unsupported errors are passed back',
58
+ error: [501, 'GetMasterPublicKeysMethodNotSupported'],
59
+ },
60
+ {
61
+ args: {lnd: {wallet: {listAccounts: ({}, cbk) => cbk('err')}}},
62
+ description: 'LND errors are passed back',
63
+ error: [503, 'UnexpectedErrorGettingMasterPublicKeys', {err: 'err'}],
64
+ },
65
+ {
66
+ args: {lnd: {wallet: {listAccounts: ({}, cbk) => cbk()}}},
67
+ description: 'A response is expected',
68
+ error: [503, 'ExpectedResultForMasterPublicKeyListRequest'],
69
+ },
70
+ {
71
+ args: {lnd: {wallet: {listAccounts: ({}, cbk) => cbk(null, {})}}},
72
+ description: 'A response with accounts is expected',
73
+ error: [503, 'ExpectedArrayOfAccountsInMasterPublicKeysList'],
74
+ },
75
+ {
76
+ args: {lnd: makeLnd({})},
77
+ description: 'Get a list of master public keys',
78
+ expected: makeExpected({}),
79
+ },
80
+ ];
81
+
82
+ tests.forEach(({args, description, error, expected}) => {
83
+ return test(description, async ({end, rejects, strictSame}) => {
84
+ if (!!error) {
85
+ await rejects(() => getMasterPublicKeys(args), error, 'Got error');
86
+ } else {
87
+ const {keys} = await getMasterPublicKeys(args);
88
+
89
+ strictSame(keys, expected.keys, 'Got keys');
90
+ }
91
+
92
+ return end();
93
+ });
94
+ });
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "overrides": [
3
- ["lightning", 3468],
3
+ ["lightning", 3470],
4
4
  ["router", 100],
5
5
  ["walletkit", 3],
6
6
  ["walletunlocker", 2]
@@ -0,0 +1,31 @@
1
+ import {expectError, expectType} from 'tsd';
2
+ import {AuthenticatedLnd} from '../../lnd_grpc';
3
+ import {getPendingPayments, GetPendingPaymentsResult} from '../../lnd_methods';
4
+
5
+ const lnd = {} as AuthenticatedLnd;
6
+ const limit = 1;
7
+ const token = 'token';
8
+
9
+ expectError(getPendingPayments());
10
+ expectError(getPendingPayments({}));
11
+ expectError(getPendingPayments({lnd, limit, token})); // ExpectedNoLimitPagingPendingPaymentsWithToken
12
+
13
+ expectType<GetPendingPaymentsResult>(await getPendingPayments({lnd}));
14
+ expectType<GetPendingPaymentsResult>(await getPendingPayments({lnd, limit}));
15
+ expectType<GetPendingPaymentsResult>(await getPendingPayments({lnd, token}));
16
+
17
+ expectType<void>(
18
+ getPendingPayments({lnd}, (error, result) => {
19
+ expectType<GetPendingPaymentsResult>(result);
20
+ })
21
+ );
22
+ expectType<void>(
23
+ getPendingPayments({lnd, limit}, (error, result) => {
24
+ expectType<GetPendingPaymentsResult>(result);
25
+ })
26
+ );
27
+ expectType<void>(
28
+ getPendingPayments({lnd, token}, (error, result) => {
29
+ expectType<GetPendingPaymentsResult>(result);
30
+ })
31
+ );