balanceofsatoshis 11.29.2 → 11.32.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.
@@ -0,0 +1,2 @@
1
+ bos
2
+ *.js
package/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # Versions
2
2
 
3
+ ## 11.32.1
4
+
5
+ - `change-channel-capacity`: Add support for moving a channel to a different
6
+ saved node.
7
+
8
+ ## 11.31.0
9
+
10
+ - `forwards`: Add `--sort` option to sort forwarding peers
11
+
12
+ ## 11.30.0
13
+
14
+ - `telegram`: Add support for setting the description of a created trade-secret
15
+
3
16
  ## 11.29.2
4
17
 
5
18
  - `increase-outbound-liquidity`: Change seed node backing endpoint for API EOL
package/bos CHANGED
@@ -300,10 +300,31 @@ prog
300
300
  .action((args, options, logger) => {
301
301
  return new Promise(async (resolve, reject) => {
302
302
  try {
303
+ const {lnd} = await lndForNode(logger, options.node);
304
+
305
+ const saved = await nodes.manageSavedNodes({
306
+ logger,
307
+ spawn,
308
+ ask: (n, cbk) => inquirer.prompt([n]).then(res => cbk(res)),
309
+ fs: {
310
+ writeFile,
311
+ getDirectoryFiles: readdir,
312
+ getFile: readFile,
313
+ getFileStatus: lstat,
314
+ makeDirectory: mkdir,
315
+ removeDirectory: rmdir,
316
+ removeFile: unlink,
317
+ },
318
+ is_including_lnd_api: true,
319
+ lock_credentials_to: [],
320
+ network: (await lnSync.getNetwork({lnd})).network,
321
+ });
322
+
303
323
  return paidServices.changeChannelCapacity({
324
+ lnd,
304
325
  logger,
305
326
  ask: (n, cbk) => inquirer.prompt([n]).then(res => cbk(res)),
306
- lnd: (await lnd.authenticatedLnd({logger, node: options.node})).lnd,
327
+ nodes: saved.nodes,
307
328
  },
308
329
  responses.returnObject({exit, logger, reject, resolve}));
309
330
  } catch (err) {
@@ -585,7 +606,7 @@ prog
585
606
  .option('--node <node_name>', 'Saved node (not peer to set fees on)')
586
607
  .option('--set-cltv-delta <count>', 'Set the number of blocks for CLTV', INT)
587
608
  .option('--set-fee-rate <rate>', 'Fee in parts per million or use a formula')
588
- .option('--to <peer>', 'Peer public key or alias to set fees', REPEATABLE)
609
+ .option('--to <peer>', 'Peer key/alias/tag to set fees', REPEATABLE)
589
610
  .action((args, options, logger) => {
590
611
  return new Promise(async (resolve, reject) => {
591
612
  try {
@@ -627,12 +648,14 @@ prog
627
648
  // Get forwards
628
649
  .command('forwards', 'Show recent forwarding earnings')
629
650
  .help('Peers where routing has taken place from inbound and outbound sides')
651
+ .help('Sorts: earned_in/earned_out/earned_total/inbound/liquidity/outbound')
630
652
  .option('--complete', 'Show complete set of records in non table view')
631
653
  .option('--days <days>', 'Number of past days to evaluate', INT)
632
654
  .option('--in <from>', 'Forwards that originated from a specific peer')
633
655
  .option('--no-color', 'Mute all colors')
634
656
  .option('--node <node_name>', 'Node to get forwards for')
635
657
  .option('--out <to>', 'Forwards that sent out to a specified peer')
658
+ .option('--sort <type>', 'Sort forward-active peers by earnings/liquidity')
636
659
  .action((args, options, logger) => {
637
660
  return new Promise(async (resolve, reject) => {
638
661
  try {
@@ -646,6 +669,7 @@ prog
646
669
  fs: {getFile: readFile},
647
670
  is_monochrome: !!options.noColor,
648
671
  is_table: !options.complete,
672
+ sort: options.sort || undefined,
649
673
  to: (await lnSync.findKey({lnd, query: options.out})).public_key,
650
674
  },
651
675
  responses.returnObject({logger, reject, resolve, table}));
@@ -956,7 +980,7 @@ prog
956
980
  .option('--unlock', 'Remove encryption from auth macaroon')
957
981
  .action((args, options, logger) => {
958
982
  return new Promise((resolve, reject) => {
959
- return nodes.adjustSavedNodes({
983
+ return nodes.manageSavedNodes({
960
984
  logger,
961
985
  spawn,
962
986
  ask: (n, cbk) => inquirer.prompt([n]).then(res => cbk(res)),
@@ -28,6 +28,8 @@ const {now} = Date;
28
28
  const numDays = 1;
29
29
  const {parse} = Date;
30
30
  const sort = (a, b) => a > b ? 1 : ((b > a) ? -1 : 0);
31
+ const sortsForEarning = ['earned_in', 'earned_out', 'earned_total'];
32
+ const sortsForCapital = ['inbound', 'liquidity', 'outbound'];
31
33
  const tokensAsBigTokens = tokens => !!tokens ? (tokens / 1e8).toFixed(8) : '';
32
34
  const uniq = arr => Array.from(new Set(arr));
33
35
  const wideSizeCols = 155;
@@ -41,7 +43,8 @@ const wideSizeCols = 155;
41
43
  }
42
44
  [is_monochrome]: <Mute Colors Bool>
43
45
  [is_table]: <Return Results As Table Bool>
44
- lnd: <Authenticated LND gRPC API Object>
46
+ lnd: <Authenticated LND API Object>
47
+ [sort]: <Sort By Field String>
45
48
  }
46
49
 
47
50
  @returns via cbk or Promise
@@ -71,6 +74,12 @@ module.exports = (args, cbk) => {
71
74
  return cbk([400, 'ExpectedLndToGetForwardingInformation']);
72
75
  }
73
76
 
77
+ const sorts = [].concat(sortsForCapital).concat(sortsForEarning);
78
+
79
+ if (!!args.sort && !sorts.includes(args.sort)) {
80
+ return cbk([400, 'ExpectedKnownSortToSortForwards', {sorts}]);
81
+ }
82
+
74
83
  return cbk();
75
84
  },
76
85
 
@@ -256,6 +265,36 @@ module.exports = (args, cbk) => {
256
265
 
257
266
  const sorted = peers
258
267
  .sort((a, b) => {
268
+ if (args.sort === 'earned_in') {
269
+ return a.earned_inbound_fees - b.earned_inbound_fees;
270
+ }
271
+
272
+ if (args.sort === 'earned_out') {
273
+ return a.earned_outbound_fees - b.earned_outbound_fees;
274
+ }
275
+
276
+ if (args.sort === 'earned_total') {
277
+ const aTotal = a.earned_inbound_fees + a.earned_outbound_fees;
278
+ const bTotal = b.earned_inbound_fees + b.earned_outbound_fees;
279
+
280
+ return aTotal - bTotal;
281
+ }
282
+
283
+ if (args.sort === 'inbound') {
284
+ return a.liquidity_inbound - b.liquidity_inbound;
285
+ }
286
+
287
+ if (args.sort === 'liquidity') {
288
+ const aTotal = a.liquidity_inbound + a.liquidity_outbound;
289
+ const bTotal = b.liquidity_inbound + b.liquidity_outbound;
290
+
291
+ return aTotal - bTotal;
292
+ }
293
+
294
+ if (args.sort === 'outbound') {
295
+ return a.liquidity_outbound - b.liquidity_outbound;
296
+ }
297
+
259
298
  const aEvents = [a.last_outbound_at, a.last_inbound_at];
260
299
  const bEvents = [b.last_outbound_at, b.last_inbound_at];
261
300
 
@@ -5,6 +5,7 @@ const asyncAuto = require('async/auto');
5
5
  const asyncFilter = require('async/filter');
6
6
  const asyncMap = require('async/map');
7
7
  const {authenticatedLndGrpc} = require('ln-service');
8
+ const {getNetwork} = require('ln-sync');
8
9
  const {getWalletInfo} = require('ln-service');
9
10
  const {returnResult} = require('asyncjs-util');
10
11
 
@@ -19,17 +20,20 @@ const {home} = require('./constants');
19
20
  getFile: <Read File Contents Function> (path, cbk) => {}
20
21
  getFileStatus: <File Status Function> (path, cbk) => {}
21
22
  }
23
+ [network]: <Required Network Name String>
22
24
  }
23
25
 
24
26
  @returns via cbk or Promise
25
27
  {
26
28
  nodes: [{
27
29
  [is_online]: <Node is Online Bool>
30
+ lnd: <Authenticated LND API Object>
28
31
  node_name: <Node Name String>
32
+ public_key: <Node Identity Public Key Hex String>
29
33
  }]
30
34
  }
31
35
  */
32
- module.exports = ({fs}, cbk) => {
36
+ module.exports = ({fs, network}, cbk) => {
33
37
  return new Promise((resolve, reject) => {
34
38
  return asyncAuto({
35
39
  // Check arguments
@@ -121,16 +125,39 @@ module.exports = ({fs}, cbk) => {
121
125
  }
122
126
 
123
127
  return cbk(null, {
124
- node_name: node,
128
+ lnd,
125
129
  is_online: res.is_synced_to_chain,
130
+ node_name: node,
131
+ public_key: res.public_key,
126
132
  });
127
133
  });
128
134
  },
129
135
  cbk);
130
136
  }],
131
137
 
138
+ // Filter out nodes not on the specified network
139
+ filter: ['getNodes', ({getNodes}, cbk) => {
140
+ // Exit early when no network is specified
141
+ if (!network) {
142
+ return cbk(null, getNodes);
143
+ }
144
+
145
+ const nodes = getNodes.filter(n => !!n.is_online);
146
+
147
+ return asyncFilter(nodes, ({lnd}, cbk) => {
148
+ return getNetwork({lnd}, (err, res) => {
149
+ if (!!err) {
150
+ return cbk(err);
151
+ }
152
+
153
+ return cbk(null, res.network === network);
154
+ });
155
+ },
156
+ cbk);
157
+ }],
158
+
132
159
  // Final list of nodes
133
- nodes: ['getNodes', ({getNodes}, cbk) => cbk(null, {nodes: getNodes})],
160
+ nodes: ['filter', ({filter}, cbk) => cbk(null, {nodes: filter})],
134
161
  },
135
162
  returnResult({reject, resolve, of: 'nodes'}, cbk));
136
163
  });
package/nodes/index.js CHANGED
@@ -1,11 +1,11 @@
1
- const adjustSavedNodes = require('./adjust_saved_nodes');
2
1
  const adjustTags = require('./adjust_tags');
3
2
  const getSavedCredentials = require('./get_saved_credentials');
4
3
  const getSavedNodes = require('./get_saved_nodes');
4
+ const manageSavedNodes = require('./manage_saved_nodes');
5
5
 
6
6
  module.exports = {
7
- adjustSavedNodes,
8
7
  adjustTags,
9
8
  getSavedCredentials,
10
9
  getSavedNodes,
10
+ manageSavedNodes,
11
11
  };
@@ -29,11 +29,13 @@ const {isArray} = Array;
29
29
  removeFile: <Remove File Function> (path, cbk) => {}
30
30
  writeFile: <Write File Contents Function> (path, contents, cbk) => {}
31
31
  }
32
+ [is_including_lnd_api]: <Include Node LND API Object Bool>
32
33
  [is_registering]: <Add Node Credentials Bool>
33
34
  [is_removing]: <Remove Node Credentials Bool>
34
35
  [is_unlocking]: <Change Credentials To Decrypted Copy Bool>
35
36
  lock_credentials_to: [<Encrypt Macaroon to GPG Key With Id String>]
36
37
  logger: <Winston Logger Object>
38
+ [network]: <Return Nodes On Specified Network String>
37
39
  [node]: <Node Name String>
38
40
  spawn: <Spawn Function>
39
41
  }
@@ -42,8 +44,9 @@ const {isArray} = Array;
42
44
  {
43
45
  nodes: [{
44
46
  [is_online]: <Node is Online Bool>
45
- [encrypted_to]: [<Encrypted To GPG Id String>]
47
+ [lnd]: <Authenticated LND API Object>
46
48
  node_name: <Node Name String>
49
+ public_key: <Node Identity Public Key Hex String>
47
50
  }]
48
51
  }
49
52
  */
@@ -149,7 +152,9 @@ module.exports = (args, cbk) => {
149
152
  }],
150
153
 
151
154
  // Get existing set of nodes
152
- getNodes: ['remove', ({}, cbk) => getSavedNodes({fs: args.fs}, cbk)],
155
+ getNodes: ['remove', ({}, cbk) => {
156
+ return getSavedNodes({fs: args.fs, network: args.network}, cbk);
157
+ }],
153
158
 
154
159
  // Encrypt macaroons
155
160
  lock: ['getNodes', ({getNodes}, cbk) => {
@@ -189,10 +194,26 @@ module.exports = (args, cbk) => {
189
194
  }],
190
195
 
191
196
  // Get saved nodes
192
- getSaved: ['lock', 'unlock', ({}, cbk) => {
193
- return getSavedNodes({fs: args.fs}, cbk);
197
+ getSaved: ['getNodes', 'lock', 'unlock', ({getNodes}, cbk) => {
198
+ if (!args.is_registering && !args.is_removing && !args.is_unlocking) {
199
+ return cbk(null, getNodes);
200
+ }
201
+
202
+ return getSavedNodes({fs: args.fs, network: args.network}, cbk);
203
+ }],
204
+
205
+ // Final set of saved nodes
206
+ nodes: ['getSaved', ({getSaved}, cbk) => {
207
+ const nodes = getSaved.nodes.map(node => ({
208
+ is_online: node.is_online,
209
+ lnd: !!args.is_including_lnd_api ? node.lnd : undefined,
210
+ node_name: node.node_name,
211
+ public_key: node.public_key,
212
+ }));
213
+
214
+ return cbk(null, {nodes});
194
215
  }],
195
216
  },
196
- returnResult({reject, resolve, of: 'getSaved'}, cbk));
217
+ returnResult({reject, resolve, of: 'nodes'}, cbk));
197
218
  });
198
219
  };
package/package.json CHANGED
@@ -35,11 +35,11 @@
35
35
  "inquirer": "8.2.0",
36
36
  "invoices": "2.0.3",
37
37
  "ln-accounting": "5.0.5",
38
- "ln-service": "53.5.0",
38
+ "ln-service": "53.5.1",
39
39
  "ln-sync": "3.7.0",
40
- "ln-telegram": "3.7.0",
40
+ "ln-telegram": "3.8.1",
41
41
  "moment": "2.29.1",
42
- "paid-services": "3.9.1",
42
+ "paid-services": "3.11.0",
43
43
  "probing": "2.0.2",
44
44
  "psbt": "1.1.10",
45
45
  "qrcode-terminal": "0.12.0",
@@ -80,5 +80,5 @@
80
80
  "postpublish": "docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 -t alexbosworth/balanceofsatoshis --push .",
81
81
  "test": "tap --branches=1 --functions=1 --lines=1 --statements=1 -t 60 test/arrays/*.js test/balances/*.js test/chain/*.js test/display/*.js test/encryption/*.js test/lnd/*.js test/network/*.js test/nodes/*.js test/peers/*.js test/responses/*.js test/routing/*.js test/services/*.js test/swaps/*.js test/tags/*.js test/wallets/*.js"
82
82
  },
83
- "version": "11.29.2"
83
+ "version": "11.32.1"
84
84
  }
@@ -1,6 +1,7 @@
1
1
  const {homedir} = require('os');
2
2
  const {join} = require('path');
3
3
 
4
+ const {actOnMessageReply} = require('ln-telegram');
4
5
  const asyncAuto = require('async/auto');
5
6
  const asyncEach = require('async/each');
6
7
  const asyncForever = require('async/forever');
@@ -25,7 +26,7 @@ const {handlePendingCommand} = require('ln-telegram');
25
26
  const {handleVersionCommand} = require('ln-telegram');
26
27
  const {InputFile} = require('grammy');
27
28
  const inquirer = require('inquirer');
28
- const {isMessageReplyToInvoice} = require('ln-telegram');
29
+ const {isMessageReplyAction} = require('ln-telegram');
29
30
  const {notifyOfForwards} = require('ln-telegram');
30
31
  const {postChainTransaction} = require('ln-telegram');
31
32
  const {postClosedMessage} = require('ln-telegram');
@@ -44,7 +45,6 @@ const {subscribeToChannels} = require('ln-service');
44
45
  const {subscribeToInvoices} = require('ln-service');
45
46
  const {subscribeToPastPayments} = require('ln-service');
46
47
  const {subscribeToTransactions} = require('ln-service');
47
- const {updateInvoiceFromReply} = require('ln-telegram');
48
48
 
49
49
  const interaction = require('./interaction');
50
50
  const markdown = {parse_mode: 'Markdown'};
@@ -457,10 +457,10 @@ module.exports = ({fs, id, limits, lnds, logger, payments, request}, cbk) => {
457
457
 
458
458
  // Listen for replies to created invoice messages
459
459
  bot.on('message').filter(
460
- ctx => isMessageReplyToInvoice({ctx, nodes: getNodes}),
460
+ ctx => isMessageReplyAction({ctx, nodes: getNodes}),
461
461
  async ctx => {
462
462
  try {
463
- return await updateInvoiceFromReply({
463
+ return await actOnMessageReply({
464
464
  ctx,
465
465
  api: bot.api,
466
466
  id: connectedId,