lightning 5.1.1 → 5.3.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 CHANGED
@@ -1,5 +1,13 @@
1
1
  # Versions
2
2
 
3
+ ## 5.3.1
4
+
5
+ - `getInvoices`: Add `is_unconfirmed` to filter out canceled/settled invoices
6
+
7
+ ## 5.2.1
8
+
9
+ - `getPendingChannels`: Add support for channel `capacity`
10
+
3
11
  ## 5.1.1
4
12
 
5
13
  - `openChannels`: Fix `cooperative_close_address` not being set on channels
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2019-2021 Alex Bosworth
3
+ Copyright (c) 2019-2022 Alex Bosworth
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -15,6 +15,7 @@ Methods for working with the Lightning Network
15
15
  - [Thunderhub](https://www.thunderhub.io/) - https://github.com/apotdevin/thunderhub
16
16
  - [Lightning Roulette](https://lightning-roulette.com/) - https://github.com/igreshev/lightning-roulette
17
17
  - [Lightning Poker](https://lightning-poker.com/) - https://github.com/igreshev/lightning-poker
18
+ - [p2plnbot](https://telegram.me/lnp2pbot) - https://github.com/grunch/p2plnbot
18
19
  - [rekr](https://rekr.app/) - https://github.com/ryan-lingle/rekr
19
20
  - [Suredbits API](https://suredbits.com/) - https://github.com/Suredbits/sb-api-lnd
20
21
 
package/index.js CHANGED
@@ -17,6 +17,7 @@ const {deleteFailedPayments} = require('./lnd_methods');
17
17
  const {deleteForwardingReputations} = require('./lnd_methods');
18
18
  const {deletePayment} = require('./lnd_methods');
19
19
  const {deletePayments} = require('./lnd_methods');
20
+ const {deletePendingChannel} = require('./lnd_methods');
20
21
  const {diffieHellmanComputeSecret} = require('./lnd_methods');
21
22
  const {disableChannel} = require('./lnd_methods');
22
23
  const {disconnectWatchtower} = require('./lnd_methods');
@@ -153,6 +154,7 @@ module.exports = {
153
154
  deleteForwardingReputations,
154
155
  deletePayment,
155
156
  deletePayments,
157
+ deletePendingChannel,
156
158
  disableChannel,
157
159
  disconnectWatchtower,
158
160
  enableChannel,
@@ -16,6 +16,7 @@ const {deleteFailedPayments} = require('./offchain');
16
16
  const {deleteForwardingReputations} = require('./offchain');
17
17
  const {deletePayment} = require('./offchain');
18
18
  const {deletePayments} = require('./offchain');
19
+ const {deletePendingChannel} = require('./offchain');
19
20
  const {diffieHellmanComputeSecret} = require('./signer');
20
21
  const {disableChannel} = require('./offchain');
21
22
  const {disconnectWatchtower} = require('./offchain');
@@ -148,6 +149,7 @@ module.exports = {
148
149
  deleteForwardingReputations,
149
150
  deletePayment,
150
151
  deletePayments,
152
+ deletePendingChannel,
151
153
  diffieHellmanComputeSecret,
152
154
  disableChannel,
153
155
  disconnectWatchtower,
@@ -28,6 +28,7 @@ const type = 'default';
28
28
  Invoice `payment` is not supported on LND 0.11.1 and below
29
29
 
30
30
  {
31
+ [is_unconfirmed]: <Omit Canceled and Settled Invoices Bool>
31
32
  [limit]: <Page Result Limit Number>
32
33
  lnd: <Authenticated LND API Object>
33
34
  [token]: <Opaque Paging Token String>
@@ -87,16 +88,16 @@ const type = 'default';
87
88
  [next]: <Next Opaque Paging Token String>
88
89
  }
89
90
  */
90
- module.exports = ({limit, lnd, token}, cbk) => {
91
+ module.exports = (args, cbk) => {
91
92
  return new Promise((resolve, reject) => {
92
93
  return asyncAuto({
93
94
  // Validate arguments
94
95
  validate: cbk => {
95
- if (!!limit && !!token) {
96
+ if (!!args.limit && !!args.token) {
96
97
  return cbk([400, 'UnexpectedLimitWhenPagingInvoicesWithToken']);
97
98
  }
98
99
 
99
- if (!isLnd({lnd, method, type})) {
100
+ if (!isLnd({method, type, lnd: args.lnd})) {
100
101
  return cbk([400, 'ExpectedLndForInvoiceListing']);
101
102
  }
102
103
 
@@ -106,12 +107,12 @@ module.exports = ({limit, lnd, token}, cbk) => {
106
107
  // Get the list of invoices
107
108
  listInvoices: ['validate', ({}, cbk) => {
108
109
  let offset;
109
- let resultsLimit = limit || defaultLimit;
110
+ let resultsLimit = args.limit || defaultLimit;
110
111
 
111
112
  // When there is a token, parse it out into an offset and a limit
112
- if (!!token) {
113
+ if (!!args.token) {
113
114
  try {
114
- const pagingToken = parse(token);
115
+ const pagingToken = parse(args.token);
115
116
 
116
117
  offset = pagingToken.offset;
117
118
  resultsLimit = pagingToken.limit;
@@ -121,9 +122,10 @@ module.exports = ({limit, lnd, token}, cbk) => {
121
122
  }
122
123
 
123
124
  return asyncRetry({}, cbk => {
124
- return lnd[type][method]({
125
+ return args.lnd[type][method]({
125
126
  index_offset: offset || Number(),
126
127
  num_max_invoices: resultsLimit,
128
+ pending_only: args.is_unconfirmed === true || undefined,
127
129
  reversed: true,
128
130
  },
129
131
  (err, res) => {
@@ -63,6 +63,10 @@
63
63
  "method": "DeleteAllPayments",
64
64
  "type": "default"
65
65
  },
66
+ "deletePendingChannel": {
67
+ "method": "AbandonChannel",
68
+ "type": "default"
69
+ },
66
70
  "diffieHellmanComputeSecret": {
67
71
  "method": "DeriveSharedKey",
68
72
  "type": "signer"
@@ -0,0 +1,109 @@
1
+ const asyncAuto = require('async/auto');
2
+ const {returnResult} = require('asyncjs-util');
3
+ const {Transaction} = require('bitcoinjs-lib');
4
+
5
+ const {fromHex} = Transaction;
6
+ const method = 'abandonChannel';
7
+ const txIdAsHash = id => Buffer.from(id, 'hex').reverse();
8
+ const type = 'default';
9
+
10
+ /** Delete a pending channel
11
+
12
+ Pass the confirmed conflicting transaction that spends the same input to
13
+ make sure that no funds are being deleted.
14
+
15
+ This method is not supported on LND 0.13.3 and below
16
+
17
+ {
18
+ confirmed_transaction: <Hex Encoded Conflicting Transaction String>
19
+ lnd: <Authenticated LND API Object>
20
+ pending_transaction: <Hex Encoded Pending Transaction String>
21
+ pending_transaction_vout: <Pending Channel Output Index Number>
22
+ }
23
+
24
+ @returns via cbk or Promise
25
+ */
26
+ module.exports = (args, cbk) => {
27
+ return new Promise((resolve, reject) => {
28
+ return asyncAuto({
29
+ // Check arguments
30
+ validate: cbk => {
31
+ if (!args.confirmed_transaction) {
32
+ return cbk([400, 'ExpectedConfirmedConflictingTxToDeleteChannel']);
33
+ }
34
+
35
+ try {
36
+ fromHex(args.confirmed_transaction);
37
+ } catch (err) {
38
+ return cbk([400, 'ExpectedValidConfirmedTxToDeleteChannel']);
39
+ }
40
+
41
+ if (args.confirmed_transaction === args.pending_transaction) {
42
+ return cbk([400, 'ExpectedConflictingTransactionToDeleteChannel']);
43
+ }
44
+
45
+ if (!args.lnd) {
46
+ return cbk([400, 'ExpectedAuthenticatedLndToDeleteChannel']);
47
+ }
48
+
49
+ if (!args.pending_transaction) {
50
+ return cbk([400, 'ExpectedPendingTransactionToDeleteChannel']);
51
+ }
52
+
53
+ try {
54
+ fromHex(args.pending_transaction);
55
+ } catch (err) {
56
+ return cbk([400, 'ExpectedValidPendingTxToDeleteChannel']);
57
+ }
58
+
59
+ if (args.pending_transaction_vout === undefined) {
60
+ return cbk([400, 'ExpectedPendingChannelTxVoutToDeleteChannel']);
61
+ }
62
+
63
+ return cbk();
64
+ },
65
+
66
+ // Check for a conflicting input between the confirmed and pending txs
67
+ transactionId: ['validate', ({}, cbk) => {
68
+ const confirmedInputs = fromHex(args.confirmed_transaction).ins;
69
+ const pending = fromHex(args.pending_transaction);
70
+
71
+ const conflictingInput = pending.ins.find(pendingInput => {
72
+ return confirmedInputs.find(confirmedInput => {
73
+ if (!confirmedInput.hash.equals(pendingInput.hash)) {
74
+ return false;
75
+ }
76
+
77
+ return confirmedInput.index === pendingInput.index;
78
+ });
79
+ });
80
+
81
+ if (!conflictingInput) {
82
+ return cbk([400, 'FailedToFindConflictingInputInConfirmedTx']);
83
+ }
84
+
85
+ // The pending transaction conflicts with the confirmed transaction
86
+ return cbk(null, pending.getId());
87
+ }],
88
+
89
+ // Delete the channel
90
+ abandonChannel: ['transactionId', ({transactionId}, cbk) => {
91
+ return args.lnd[type][method]({
92
+ channel_point: {
93
+ funding_txid_bytes: txIdAsHash(transactionId),
94
+ output_index: args.pending_transaction_vout,
95
+ },
96
+ i_know_what_i_am_doing: true,
97
+ },
98
+ err => {
99
+ if (!!err) {
100
+ return cbk([503, 'UnexpectedErrorDeletingPendingChannel', {err}]);
101
+ }
102
+
103
+ return cbk();
104
+ });
105
+ }],
106
+ },
107
+ returnResult({reject, resolve}, cbk));
108
+ });
109
+ };
@@ -3,6 +3,8 @@ import {AuthenticatedLnd} from '../../lnd_grpc';
3
3
 
4
4
  export type GetPendingChannelsResult = {
5
5
  pending_channels: {
6
+ /** Channel Capacity Tokens */
7
+ capacity: number;
6
8
  /** Channel Closing Transaction Id */
7
9
  close_transaction_id?: string;
8
10
  /** Channel Is Active */
@@ -25,6 +25,7 @@ const type = 'default';
25
25
  @returns via cbk or Promise
26
26
  {
27
27
  pending_channels: [{
28
+ capacity: <Channel Capacity Tokens Number>
28
29
  [close_transaction_id]: <Channel Closing Transaction Id String>
29
30
  is_active: <Channel Is Active Bool>
30
31
  is_closing: <Channel Is Closing Bool>
@@ -68,6 +69,7 @@ module.exports = ({lnd}, cbk) => {
68
69
  return cbk();
69
70
  },
70
71
 
72
+ // Get pending channels
71
73
  getPending: ['validate', ({}, cbk) => {
72
74
  return lnd[type][method]({}, (err, res) => {
73
75
  if (!!err) {
@@ -5,6 +5,7 @@ const deleteFailedPayments = require('./delete_failed_payments');
5
5
  const deleteForwardingReputations = require('./delete_forwarding_reputations');
6
6
  const deletePayment = require('./delete_payment');
7
7
  const deletePayments = require('./delete_payments');
8
+ const deletePendingChannel = require('./delete_pending_channel');
8
9
  const disableChannel = require('./disable_channel');
9
10
  const disconnectWatchtower = require('./disconnect_watchtower');
10
11
  const enableChannel = require('./enable_channel');
@@ -59,6 +60,7 @@ module.exports = {
59
60
  deleteForwardingReputations,
60
61
  deletePayment,
61
62
  deletePayments,
63
+ deletePendingChannel,
62
64
  disableChannel,
63
65
  disconnectWatchtower,
64
66
  enableChannel,
@@ -26,11 +26,11 @@ const type = 'default';
26
26
  [give_tokens]: <Tokens to Gift To Partner Number> // Defaults to zero
27
27
  [is_private]: <Channel is Private Bool> // Defaults to false
28
28
  lnd: <Authenticated LND API Object>
29
- local_tokens: <Local Tokens Number>
29
+ local_tokens: <Total Channel Capacity Tokens Number>
30
30
  [min_confirmations]: <Spend UTXOs With Minimum Confirmations Number>
31
31
  [min_htlc_mtokens]: <Minimum HTLC Millitokens String>
32
- partner_public_key: <Public Key Hex String>
33
32
  [partner_csv_delay]: <Peer Output CSV Delay Number>
33
+ partner_public_key: <Public Key Hex String>
34
34
  [partner_socket]: <Peer Connection Host:Port String>
35
35
  }
36
36
 
@@ -19,8 +19,6 @@ export type OpenChannelsArgs = AuthenticatedLightningArgs<{
19
19
  partner_public_key: string;
20
20
  /** Peer Output CSV Delay */
21
21
  partner_csv_delay?: number;
22
- /** Peer Connection Host:Port */
23
- partner_socket?: string;
24
22
  }[];
25
23
  /** Do not broadcast any channel funding transactions */
26
24
  is_avoiding_broadcast?: boolean;
@@ -39,9 +39,8 @@ const type = 'default';
39
39
  [give_tokens]: <Tokens to Gift To Partner Number> // Defaults to zero
40
40
  [is_private]: <Channel is Private Bool> // Defaults to false
41
41
  [min_htlc_mtokens]: <Minimum HTLC Millitokens String>
42
- partner_public_key: <Public Key Hex String>
43
42
  [partner_csv_delay]: <Peer Output CSV Delay Number>
44
- [partner_socket]: <Peer Connection Host:Port String>
43
+ partner_public_key: <Public Key Hex String>
45
44
  }]
46
45
  [is_avoiding_broadcast]: <Avoid Broadcast of All Channels Bool>
47
46
  lnd: <Authenticated LND API Object>
@@ -95,7 +94,6 @@ module.exports = (args, cbk) => {
95
94
  min_htlc_mtokens: channel.min_htlc_mtokens,
96
95
  partner_public_key: channel.partner_public_key,
97
96
  partner_csv_delay: channel.partner_csv_delay,
98
- partner_socket: channel.partner_socket,
99
97
  })));
100
98
  }],
101
99
 
@@ -80,6 +80,7 @@ const outpointSeparator = ':';
80
80
  @returns
81
81
  {
82
82
  pending_channels: [{
83
+ capacity: <Channel Capacity Tokens Number>
83
84
  [close_transaction_id]: <Channel Closing Transaction Id String>
84
85
  is_active: <Channel Is Active Bool>
85
86
  is_closing: <Channel Is Closing Bool>
@@ -285,6 +286,7 @@ module.exports = args => {
285
286
  const pendingTokens = wait.pending_balance || forced.pending_balance;
286
287
 
287
288
  return {
289
+ capacity: Number(channel.capacity),
288
290
  close_transaction_id: endTx || undefined,
289
291
  is_active: false,
290
292
  is_closing: !chanOpen,
package/package.json CHANGED
@@ -7,32 +7,32 @@
7
7
  "url": "https://github.com/alexbosworth/lightning/issues"
8
8
  },
9
9
  "dependencies": {
10
- "@grpc/grpc-js": "1.4.4",
11
- "@grpc/proto-loader": "0.6.7",
10
+ "@grpc/grpc-js": "1.5.0",
11
+ "@grpc/proto-loader": "0.6.9",
12
12
  "@types/express": "4.17.13",
13
- "@types/node": "16.11.11",
14
- "@types/request": "2.48.7",
15
- "@types/ws": "8.2.1",
16
- "async": "3.2.2",
13
+ "@types/node": "17.0.8",
14
+ "@types/request": "2.48.8",
15
+ "@types/ws": "8.2.2",
16
+ "async": "3.2.3",
17
17
  "asyncjs-util": "1.2.7",
18
18
  "bitcoinjs-lib": "6.0.1",
19
19
  "bn.js": "5.2.0",
20
- "body-parser": "1.19.0",
21
- "bolt07": "1.7.4",
20
+ "body-parser": "1.19.1",
21
+ "bolt07": "1.8.0",
22
22
  "bolt09": "0.2.0",
23
23
  "cbor": "8.1.0",
24
- "express": "4.17.1",
24
+ "express": "4.17.2",
25
25
  "invoices": "2.0.2",
26
26
  "psbt": "1.1.10",
27
- "type-fest": "2.8.0"
27
+ "type-fest": "2.9.0"
28
28
  },
29
29
  "description": "Lightning Network client library",
30
30
  "devDependencies": {
31
31
  "@alexbosworth/node-fetch": "2.6.2",
32
32
  "@alexbosworth/tap": "15.0.10",
33
- "tsd": "0.19.0",
34
- "typescript": "4.5.2",
35
- "ws": "8.3.0"
33
+ "tsd": "0.19.1",
34
+ "typescript": "4.5.4",
35
+ "ws": "8.4.0"
36
36
  },
37
37
  "engines": {
38
38
  "node": ">=12.20"
@@ -57,5 +57,5 @@
57
57
  "directory": "test/typescript"
58
58
  },
59
59
  "types": "index.d.ts",
60
- "version": "5.1.1"
60
+ "version": "5.3.1"
61
61
  }
@@ -0,0 +1,91 @@
1
+ const {test} = require('@alexbosworth/tap');
2
+ const {Transaction} = require('bitcoinjs-lib');
3
+
4
+ const {deletePendingChannel} = require('./../../../lnd_methods');
5
+
6
+ const tx1 = new Transaction();
7
+ const tx2 = new Transaction();
8
+ const tx3 = new Transaction();
9
+
10
+ tx1.addInput(Buffer.alloc(32, 0), 0);
11
+ tx2.addInput(Buffer.alloc(32, 0), 0);
12
+ tx2.addInput(Buffer.alloc(32, 1), 0);
13
+ tx2.addOutput(Buffer.alloc(10), 1);
14
+ tx3.addInput(Buffer.alloc(32, 2), 0);
15
+
16
+ const makeArgs = overrides => {
17
+ const args = {
18
+ confirmed_transaction: tx1.toHex(),
19
+ lnd: {default: {abandonChannel: ({}, cbk) => cbk()}},
20
+ pending_transaction: tx2.toHex(),
21
+ pending_transaction_vout: 0,
22
+ };
23
+
24
+ Object.keys(overrides).forEach(k => args[k] = overrides[k]);
25
+
26
+ return args;
27
+ };
28
+
29
+ const tests = [
30
+ {
31
+ args: makeArgs({confirmed_transaction: undefined}),
32
+ description: 'A conflicting confirmed tx is required',
33
+ error: [400, 'ExpectedConfirmedConflictingTxToDeleteChannel'],
34
+ },
35
+ {
36
+ args: makeArgs({confirmed_transaction: 'confirmed transaction'}),
37
+ description: 'A valid conflicting confirmed tx is required',
38
+ error: [400, 'ExpectedValidConfirmedTxToDeleteChannel'],
39
+ },
40
+ {
41
+ args: makeArgs({confirmed_transaction: tx2.toHex()}),
42
+ description: 'Pending transaction must be different from confirmed tx',
43
+ error: [400, 'ExpectedConflictingTransactionToDeleteChannel'],
44
+ },
45
+ {
46
+ args: makeArgs({lnd: undefined}),
47
+ description: 'Lnd is required',
48
+ error: [400, 'ExpectedAuthenticatedLndToDeleteChannel'],
49
+ },
50
+ {
51
+ args: makeArgs({pending_transaction: undefined}),
52
+ description: 'A pending tx is required',
53
+ error: [400, 'ExpectedPendingTransactionToDeleteChannel'],
54
+ },
55
+ {
56
+ args: makeArgs({pending_transaction: 'pending transaction'}),
57
+ description: 'A valid pending tx is required',
58
+ error: [400, 'ExpectedValidPendingTxToDeleteChannel'],
59
+ },
60
+ {
61
+ args: makeArgs({pending_transaction_vout: undefined}),
62
+ description: 'A pending tx output index is required',
63
+ error: [400, 'ExpectedPendingChannelTxVoutToDeleteChannel'],
64
+ },
65
+ {
66
+ args: makeArgs({confirmed_transaction: tx3.toHex()}),
67
+ description: 'A conflicting tx is required',
68
+ error: [400, 'FailedToFindConflictingInputInConfirmedTx'],
69
+ },
70
+ {
71
+ args: makeArgs({lnd: {default: {abandonChannel: ({}, cbk) => cbk('er')}}}),
72
+ description: 'A server error is passed back',
73
+ error: [503, 'UnexpectedErrorDeletingPendingChannel', {err: 'er'}],
74
+ },
75
+ {
76
+ args: makeArgs({}),
77
+ description: 'A pending channel is deleted',
78
+ },
79
+ ];
80
+
81
+ tests.forEach(({args, description, error, expected}) => {
82
+ return test(description, async ({deepEqual, end, equal, rejects}) => {
83
+ if (!!error) {
84
+ await rejects(() => deletePendingChannel(args), error, 'Got error');
85
+ } else {
86
+ await deletePendingChannel(args);
87
+ }
88
+
89
+ return end();
90
+ });
91
+ });
@@ -99,6 +99,7 @@ const makeArgs = overrides => {
99
99
 
100
100
  const makeExpectedPending = overrides => {
101
101
  const res = {
102
+ capacity: 1,
102
103
  close_transaction_id: Buffer.alloc(32).toString('hex'),
103
104
  is_active: false,
104
105
  is_closing: true,