lightning 5.5.0 → 5.6.3

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,9 @@
1
1
  # Versions
2
2
 
3
+ ## 5.6.3
4
+
5
+ - `payViaRoutes`, `subscribeToPayViaRoutes`: Add support for relay messages
6
+
3
7
  ## 5.5.0
4
8
 
5
9
  - `partiallySignPsbt`: Add method to partially sign a PSBT
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
 
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');
@@ -186,6 +187,7 @@ module.exports = {
186
187
  getInvoice,
187
188
  getInvoices,
188
189
  getLockedUtxos,
190
+ getMasterPublicKeys,
189
191
  getMethods,
190
192
  getNetworkCentrality,
191
193
  getNetworkGraph,
@@ -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');
@@ -180,6 +181,7 @@ module.exports = {
180
181
  getInvoice,
181
182
  getInvoices,
182
183
  getLockedUtxos,
184
+ getMasterPublicKeys,
183
185
  getMethods,
184
186
  getNetworkCentrality,
185
187
  getNetworkGraph,
@@ -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"
@@ -27,6 +27,12 @@ export type PayViaRoutesArgs = AuthenticatedLightningArgs<{
27
27
  forward: number;
28
28
  /** Forward Millitokens */
29
29
  forward_mtokens: string;
30
+ messages?: {
31
+ /** Message Type number */
32
+ type: string;
33
+ /** Message Raw Value Hex Encoded */
34
+ value: string;
35
+ }[];
30
36
  /** Public Key Hex */
31
37
  public_key?: string;
32
38
  /** Timeout Block Height */
@@ -29,6 +29,10 @@ const notFound = -1;
29
29
  fee_mtokens: <Fee Millitokens String>
30
30
  forward: <Forward Tokens Number>
31
31
  forward_mtokens: <Forward Millitokens String>
32
+ [messages]: [{
33
+ type: <Message Type Number String>
34
+ value: <Message Raw Value Hex Encoded String>
35
+ }]
32
36
  [public_key]: <Public Key Hex String>
33
37
  timeout: <Timeout Block Height Number>
34
38
  }]
@@ -43,6 +43,10 @@ const unknownWireError = 'unknown wire error';
43
43
  fee_mtokens: <Fee Millitokens String>
44
44
  forward: <Forward Tokens Number>
45
45
  forward_mtokens: <Forward Millitokens String>
46
+ [messages]: [{
47
+ type: <Message Type Number String>
48
+ value: <Message Raw Value Hex Encoded String>
49
+ }]
46
50
  public_key: <Public Key Hex String>
47
51
  timeout: <Timeout Block Height Number>
48
52
  }]
@@ -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,
@@ -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>
@@ -1,5 +1,6 @@
1
1
  const {chanNumber} = require('bolt07');
2
2
 
3
+ const hexAsBuffer = hex => Buffer.from(hex, 'hex');
3
4
  const isNumber = n => !isNaN(n);
4
5
  const millitokensAsTokens = n => Number(BigInt(n) / BigInt(1e3));
5
6
 
@@ -12,6 +13,10 @@ const millitokensAsTokens = n => Number(BigInt(n) / BigInt(1e3));
12
13
  fee_mtokens: <Fee Millitokens String>
13
14
  forward: <Forward Tokens Number>
14
15
  forward_mtokens: <Forward Millitokens String>
16
+ [messages]: [{
17
+ type: <Message Type Number String>
18
+ value: <Message Raw Value Hex Encoded String>
19
+ }]
15
20
  [public_key]: <Forward Edge Public Key Hex String>
16
21
  timeout: <Timeout Block Height Number>
17
22
  }
@@ -25,10 +30,12 @@ const millitokensAsTokens = n => Number(BigInt(n) / BigInt(1e3));
25
30
  amt_to_forward_msat: <Millitokens to Forward String>
26
31
  chan_id: <Numeric Format Channel Id String>
27
32
  chan_capacity: <Channel Capacity Number>
33
+ [custom_records]: {<TLV Type Number String>: <TLV Value Buffer Object>}
28
34
  expiry: <Timeout Chain Height Number>
29
35
  fee: <Fee in Tokens Number>
30
36
  fee_msat: <Fee in Millitokens String>
31
37
  [pub_key]: <Next Hop Public Key Hex String>
38
+ [tlv_payload]: <Has Extra TLV Data Bool>
32
39
  }
33
40
  */
34
41
  module.exports = args => {
@@ -44,7 +51,7 @@ module.exports = args => {
44
51
  throw new Error('ExpectedFeeMillitokensToMapRpcHopFromHop');
45
52
  }
46
53
 
47
- return {
54
+ const hop = {
48
55
  amt_to_forward: millitokensAsTokens(args.forward_mtokens).toString(),
49
56
  amt_to_forward_msat: args.forward_mtokens,
50
57
  chan_id: chanNumber({channel: args.channel}).number,
@@ -54,4 +61,21 @@ module.exports = args => {
54
61
  fee_msat: args.fee_mtokens,
55
62
  pub_key: args.public_key,
56
63
  };
64
+
65
+ // Exit early when there are no messages to encode in this hop
66
+ if (!args.messages || !args.messages.length) {
67
+ return hop;
68
+ }
69
+
70
+ // Set custom TLV payload records for this hop
71
+ hop.tlv_payload = true;
72
+
73
+ hop.custom_records = args.messages.reduce((tlv, n) => {
74
+ tlv[n.type] = hexAsBuffer(n.value);
75
+
76
+ return tlv;
77
+ },
78
+ {});
79
+
80
+ return hop;
57
81
  };
@@ -14,6 +14,10 @@ const isNumber = n => !isNaN(n);
14
14
  fee_mtokens: <Fee Millitokens String>
15
15
  forward: <Forward Tokens Number>
16
16
  forward_mtokens: <Forward Millitokens String>
17
+ [messages]: [{
18
+ type: <Message Type Number String>
19
+ value: <Message Raw Value Hex Encoded String>
20
+ }]
17
21
  [public_key]: <Forward Edge Public Key Hex String>
18
22
  timeout: <Timeout Block Height Number>
19
23
  }]
@@ -38,6 +42,7 @@ const isNumber = n => !isNaN(n);
38
42
  amt_to_forward_msat: <Millitokens to Forward String>
39
43
  chan_id: <Numeric Format Channel Id String>
40
44
  chan_capacity: <Channel Capacity Number>
45
+ [custom_records]: {<TLV Type Number String>: <TLV Value Buffer Object>}
41
46
  expiry: <Timeout Chain Height Number>
42
47
  fee: <Fee in Tokens Number>
43
48
  fee_msat: <Fee in Millitokens Number>
@@ -79,7 +84,7 @@ module.exports = args => {
79
84
  };
80
85
  }
81
86
 
82
- // Set custom TLV payload records
87
+ // Set custom TLV payload records on the final hop
83
88
  if (!!args.messages && !!args.messages.length) {
84
89
  hops[finalHopIndex].tlv_payload = true;
85
90
 
@@ -88,7 +93,7 @@ module.exports = args => {
88
93
 
89
94
  return tlv;
90
95
  },
91
- {});
96
+ hops[finalHopIndex].custom_records || {});
92
97
  }
93
98
 
94
99
  return {
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.3",
10
+ "@grpc/grpc-js": "1.5.4",
11
11
  "@grpc/proto-loader": "0.6.9",
12
12
  "@types/express": "4.17.13",
13
- "@types/node": "17.0.13",
13
+ "@types/node": "17.0.16",
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.0"
26
+ "invoices": "2.0.4",
27
+ "psbt": "2.0.0",
28
+ "tiny-secp256k1": "2.2.0",
29
+ "type-fest": "2.11.1"
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.5.0"
62
+ "version": "5.6.3"
61
63
  }
@@ -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
+ });
@@ -41,6 +41,32 @@ const tests = [
41
41
  pub_key: 'public_key',
42
42
  },
43
43
  },
44
+ {
45
+ args: {
46
+ channel: '0x0x1',
47
+ channel_capacity: 1,
48
+ fee: 1,
49
+ fee_mtokens: '1000',
50
+ forward: '1',
51
+ forward_mtokens: '1000',
52
+ messages: [{type: '12', value: '34'}],
53
+ public_key: 'public_key',
54
+ timeout: 1,
55
+ },
56
+ description: 'Hop is mapped to RPC hop',
57
+ expected: {
58
+ amt_to_forward: '1',
59
+ amt_to_forward_msat: '1000',
60
+ chan_id: '1',
61
+ chan_capacity: '1',
62
+ custom_records: {'12': Buffer.from('34', 'hex')},
63
+ expiry: 1,
64
+ fee: '1',
65
+ fee_msat: '1000',
66
+ pub_key: 'public_key',
67
+ tlv_payload: true,
68
+ },
69
+ },
44
70
  ];
45
71
 
46
72
  tests.forEach(({args, description, error, expected}) => {