balanceofsatoshis 12.3.0 → 12.4.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Versions
2
2
 
3
+ ## 12.4.0
4
+
5
+ - `chart-fees-paid`: Allow using aliases when specifying --in and --out peers
6
+
3
7
  ## 12.3.0
4
8
 
5
9
  - `lnurl`: Add support for the `auth` function to authenticate with a node key
@@ -67,7 +71,7 @@ For `peers` and `remove-peer` commands:
67
71
 
68
72
  ## 11.59.4
69
73
 
70
- - `telegram`: Fix oepn trade-secret serving
74
+ - `telegram`: Fix open trade-secret serving
71
75
  - `telegram`: Fix `/stop` command to require confirmation before termination
72
76
 
73
77
  ## 11.59.2
package/bos CHANGED
@@ -398,12 +398,12 @@ prog
398
398
  .help('Show the routing fees paid to forwarding nodes')
399
399
  .help('--rebalances can return results much more quickly')
400
400
  .option('--days <days>', 'Chart fees over the past number of days', INT, 60)
401
- .option('--in <public_key>', 'Fees paid on routes in node with public key')
401
+ .option('--in <key_or_alias>', 'Fees paid on routes in node with peer')
402
402
  .option('--most-fees', 'View table of fees paid per node')
403
403
  .option('--most-forwarded', 'View table of forwarded per node')
404
404
  .option('--network', 'Show only non-peers in table view')
405
405
  .option('--node <node_name>', 'Get fees chart for saved node(s)', REPEATABLE)
406
- .option('--out <public_key>', 'Fees paid on routes out peer with public key')
406
+ .option('--out <key_or_alias>', 'Fees paid on routes out node with peer')
407
407
  .option('--peers', 'Show only peers in table view')
408
408
  .option('--rebalances', 'Only consider fees paid in self-to-self transfers')
409
409
  .action((args, options, logger) => {
@@ -43,4 +43,4 @@ module.exports = ({ecp, hostname, k1, seed}) => {
43
43
  public_key: bufferAsHex(linkingKey.publicKey),
44
44
  signature: derEncodeSignature({signature}).encoded,
45
45
  };
46
- };
46
+ };
package/package.json CHANGED
@@ -36,7 +36,7 @@
36
36
  "ini": "3.0.0",
37
37
  "inquirer": "8.2.2",
38
38
  "ln-accounting": "5.0.6",
39
- "ln-service": "53.11.0",
39
+ "ln-service": "53.12.0",
40
40
  "ln-sync": "3.12.0",
41
41
  "ln-telegram": "3.21.1",
42
42
  "moment": "2.29.3",
@@ -45,7 +45,7 @@
45
45
  "psbt": "2.0.1",
46
46
  "qrcode-terminal": "0.12.0",
47
47
  "sanitize-filename": "1.6.3",
48
- "socks-proxy-agent": "6.2.0-beta.0",
48
+ "socks-proxy-agent": "6.2.0",
49
49
  "table": "6.8.0",
50
50
  "tiny-secp256k1": "2.2.1",
51
51
  "update-notifier": "5.1.0",
@@ -55,7 +55,7 @@
55
55
  "devDependencies": {
56
56
  "@alexbosworth/tap": "15.0.11",
57
57
  "invoices": "2.0.6",
58
- "ln-docker-daemons": "2.2.7",
58
+ "ln-docker-daemons": "2.2.8",
59
59
  "mock-lnd": "1.4.1",
60
60
  "tiny-secp256k1": "2.2.1"
61
61
  },
@@ -84,5 +84,5 @@
84
84
  "postpublish": "docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 -t alexbosworth/balanceofsatoshis --push .",
85
85
  "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/telegram/*.js test/wallets/*.js"
86
86
  },
87
- "version": "12.3.0"
87
+ "version": "12.4.0"
88
88
  }
@@ -1,5 +1,6 @@
1
1
  const asyncAuto = require('async/auto');
2
2
  const asyncMap = require('async/map');
3
+ const {findKey} = require('ln-sync');
3
4
  const {getNode} = require('ln-service');
4
5
  const {getNodeAlias} = require('ln-sync');
5
6
  const {getChannels} = require('ln-service');
@@ -19,14 +20,17 @@ const flatten = arr => [].concat(...arr);
19
20
  const {floor} = Math;
20
21
  const heading = [['Node', 'Public Key', 'Fees Paid', 'Forwarded']];
21
22
  const hoursPerDay = 24;
23
+ const isAmbiguous = n => n[1] === 'AmbiguousAliasSpecified';
22
24
  const {isArray} = Array;
23
25
  const {keys} = Object;
24
26
  const minChartDays = 4;
25
27
  const maxChartDays = 90;
26
28
  const mtokensAsBigUnit = n => (Number(n / BigInt(1e3)) / 1e8).toFixed(8);
27
29
  const mtokensAsTokens = mtokens => Number(mtokens / BigInt(1e3));
30
+ const niceAlias = n => `${(n.alias || n.id).trim()} ${n.id.substring(0, 8)}`;
28
31
  const title = 'Routing fees paid';
29
32
  const tokensAsBigUnit = tokens => (tokens / 1e8).toFixed(8);
33
+ const uniq = arr => Array.from(new Set(arr));
30
34
 
31
35
  /** Get routing fees paid
32
36
 
@@ -35,11 +39,13 @@ const tokensAsBigUnit = tokens => (tokens / 1e8).toFixed(8);
35
39
  fs: {
36
40
  getFile: <Read File Contents Function> (path, cbk) => {}
37
41
  }
42
+ [in]: <In Node Public Key or Alias String>
38
43
  [is_most_fees_table]: <Is Most Fees Table Bool>
39
44
  [is_most_forwarded_table]: <Is Most Forwarded Bool>
40
45
  [is_network]: <Show Only Non-Peers In Table Bool>
41
46
  [is_peer]: <Show Only Peers In Table Bool>
42
47
  lnds: [<Authenticated LND API Object>]
48
+ [out]: <Out Node Public Key or Alias String>
43
49
  }
44
50
 
45
51
  @returns via cbk or Promise
@@ -90,6 +96,88 @@ module.exports = (args, cbk) => {
90
96
  // Get node icons
91
97
  getIcons: ['validate', ({}, cbk) => getIcons({fs: args.fs}, cbk)],
92
98
 
99
+ // Determine the in public key to use
100
+ getInKey: ['validate', ({}, cbk) => {
101
+ // Exit early when no in query is specified
102
+ if (!args.in) {
103
+ return cbk();
104
+ }
105
+
106
+ return asyncMap(args.lnds, (lnd, cbk) => {
107
+ return findKey({lnd, query: args.in}, (err, res) => {
108
+ // Exit for ambiguous queries
109
+ if (!!err && isAmbiguous(err)) {
110
+ return cbk(err);
111
+ }
112
+
113
+ // Ignore all other errors, since a peer may not exist on all nodes
114
+ if (!!err) {
115
+ return cbk();
116
+ }
117
+
118
+ return cbk(null, res.public_key);
119
+ });
120
+ },
121
+ (err, res) => {
122
+ if (!!err) {
123
+ return cbk(err);
124
+ }
125
+
126
+ const [key, otherKey] = uniq(res.filter(n => !!n));
127
+
128
+ if (!key) {
129
+ return cbk([400, 'FailedToFindMatchesForInQueryAlias']);
130
+ }
131
+
132
+ if (!!otherKey) {
133
+ return cbk([400, 'MultipleMatchesForInQueryAlias']);
134
+ }
135
+
136
+ return cbk(null, key);
137
+ });
138
+ }],
139
+
140
+ // Determine the out public key to use
141
+ getOutKey: ['validate', ({}, cbk) => {
142
+ // Exit early when no out query is specified
143
+ if (!args.out) {
144
+ return cbk();
145
+ }
146
+
147
+ return asyncMap(args.lnds, (lnd, cbk) => {
148
+ return findKey({lnd, query: args.out}, (err, res) => {
149
+ // Exit for ambiguous queries
150
+ if (!!err && isAmbiguous(err)) {
151
+ return cbk(err);
152
+ }
153
+
154
+ // Ignore all other errors, since a peer may not exist on all nodes
155
+ if (!!err) {
156
+ return cbk();
157
+ }
158
+
159
+ return cbk(null, res.public_key);
160
+ });
161
+ },
162
+ (err, res) => {
163
+ if (!!err) {
164
+ return cbk(err);
165
+ }
166
+
167
+ const [key, otherKey] = uniq(res.filter(n => !!n));
168
+
169
+ if (!key) {
170
+ return cbk([400, 'FailedToFindMatchesForOutQueryAlias']);
171
+ }
172
+
173
+ if (!!otherKey) {
174
+ return cbk([400, 'MultipleMatchesForOutQueryAlias']);
175
+ }
176
+
177
+ return cbk(null, key);
178
+ });
179
+ }],
180
+
93
181
  // Segment measure
94
182
  measure: ['validate', ({}, cbk) => {
95
183
  if (args.days > maxChartDays) {
@@ -141,7 +229,13 @@ module.exports = (args, cbk) => {
141
229
  }],
142
230
 
143
231
  // Filter the payments
144
- forwards: ['getPayments', 'start', ({getPayments, start}, cbk) => {
232
+ forwards: [
233
+ 'getInKey',
234
+ 'getOutKey',
235
+ 'getPayments',
236
+ 'start',
237
+ ({getInKey, getOutKey, getPayments, start}, cbk) =>
238
+ {
145
239
  const payments = getPayments
146
240
  .filter(payment => payment.is_confirmed !== false)
147
241
  .filter(payment => payment.confirmed_at > start.toISOString())
@@ -163,7 +257,7 @@ module.exports = (args, cbk) => {
163
257
  }
164
258
 
165
259
  // Ignore attempts that do not include the specified out hop
166
- if (!!args.out && outHop !== args.out) {
260
+ if (!!args.out && outHop !== getOutKey) {
167
261
  return false;
168
262
  }
169
263
 
@@ -172,7 +266,7 @@ module.exports = (args, cbk) => {
172
266
  }
173
267
 
174
268
  // Ignore attempts that do not include the specified in hop
175
- if (!!args.in && inHop !== args.in) {
269
+ if (!!args.in && inHop !== getInKey) {
176
270
  return false;
177
271
  }
178
272
 
@@ -375,14 +469,19 @@ module.exports = (args, cbk) => {
375
469
  }],
376
470
 
377
471
  // Title for fees paid
378
- title: ['validate', async ({}) => {
472
+ title: [
473
+ 'validate',
474
+ 'getInKey',
475
+ 'getOutKey',
476
+ async ({getInKey, getOutKey}) =>
477
+ {
379
478
  const [lnd] = args.lnds;
380
479
 
381
- const into = !args.in ? null : await getNodeAlias({lnd, id: args.in});
382
- const out = !args.out ? null : await getNodeAlias({lnd, id: args.out});
480
+ const into = !args.in ? {} : await getNodeAlias({lnd, id: getInKey});
481
+ const out = !args.out ? {} : await getNodeAlias({lnd, id: getOutKey});
383
482
 
384
- const inPeer = !!args.in ? `in ${into.alias || into.id}` : '';
385
- const outPeer = !!args.out ? `out ${out.alias || out.id}` : '';
483
+ const inPeer = !!args.in ? `in ${niceAlias(into)}` : '';
484
+ const outPeer = !!args.out ? `out ${niceAlias(out)}` : '';
386
485
 
387
486
  return [title, outPeer, inPeer].filter(n => !!n).join(' ');
388
487
  }],
@@ -395,6 +494,13 @@ module.exports = (args, cbk) => {
395
494
  'title',
396
495
  ({description, rows, sum, title}, cbk) =>
397
496
  {
497
+ const isRows = args.is_most_fees_table || args.is_most_forwarded_table;
498
+
499
+ // Add a title row when there is a restriction involved
500
+ if (!!isRows && (!!args.in || !!args.out)) {
501
+ rows.unshift([String(), title, String(), String()]);
502
+ }
503
+
398
504
  return cbk(null, {description, rows, title, data: sum.fees});
399
505
  }],
400
506
  },