balanceofsatoshis 13.3.6 → 13.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,13 @@
1
1
  # Versions
2
2
 
3
+ ## 13.4.0
4
+
5
+ - `rebalance`: Add `--avoid-high-fee-routes` to ignore routes over max fee rate
6
+
7
+ ## 13.3.7
8
+
9
+ - `fund`: Fix failure using the MAX amount to fund an address to the max
10
+
3
11
  ## 13.3.6
4
12
 
5
13
  - Add support for LND 0.15.4
package/bos CHANGED
@@ -1478,6 +1478,7 @@ prog
1478
1478
  .help('--out increases the inbound liquidity with a specific peer/tag')
1479
1479
  .option('--amount <amount>', 'Maximum amount to rebalance')
1480
1480
  .option('--avoid <pubkey_or_chanid>', 'Avoid forwarding through', REPEATABLE)
1481
+ .option('--avoid-high-fee-routes', 'Avoid trying routes above max-fee-rate')
1481
1482
  .option('--in <pubkey_or_alias>', 'Route in through a specific peer')
1482
1483
  .option('--in-filter <in_filter>', 'Filter inbound tag nodes', REPEATABLE)
1483
1484
  .option('--in-target-outbound <amt>', 'Balance up to outbound amount')
@@ -1499,6 +1500,7 @@ prog
1499
1500
  in_filters: flatten([options.inFilter].filter(n => !!n)),
1500
1501
  in_outbound: options.inTargetOutbound || undefined,
1501
1502
  in_through: options.in || undefined,
1503
+ is_strict_max_fee_rate: options.avoidHighFeeRoutes || undefined,
1502
1504
  lnd: (await lndForNode(logger, options.node)).lnd,
1503
1505
  max_fee: options.maxFee,
1504
1506
  max_fee_rate: options.maxFeeRate,
@@ -30,6 +30,7 @@ const tokensAsMillitokens = tok => (BigInt(tok) * BigInt(1e3)).toString();
30
30
  lnd: <Authenticated LND API Object>
31
31
  logger: <Winston Logger Object>
32
32
  [max_fee]: <Maximum Fee Tokens Number>
33
+ [max_fee_mtokens]: <Maximum Fee Millitokens Number String>
33
34
  [max_timeout_height]: <Maximum Timeout Height Number>
34
35
  [messages]: [{
35
36
  type: <Message To Final Destination Type Number String>
@@ -114,8 +115,28 @@ module.exports = (args, cbk) => {
114
115
  return cbk(null, tokensAsMillitokens(args.tokens));
115
116
  }],
116
117
 
118
+ // Determine the strict maximum fee to use
119
+ strictMaxFee: ['validate', ({}, cbk) => {
120
+ // Exit early when there is no strict max fee to enforce in pathfinding
121
+ if (!args.is_strict_max_fee) {
122
+ return cbk();
123
+ }
124
+
125
+ // Exit early with error when there is no fee to use
126
+ if (args.max_fee === undefined && !args.max_fee_mtokens) {
127
+ return cbk([400, 'ExpectedMaxFeeValueToUseStrictly']);
128
+ }
129
+
130
+ // Exit early when there is a max fee in tokens set
131
+ if (args.max_fee !== undefined) {
132
+ return cbk(null, tokensAsMillitokens(args.max_fee));
133
+ }
134
+
135
+ return cbk(null, args.max_fee_mtokens);
136
+ }],
137
+
117
138
  // Probe
118
- probe: ['mtokens', ({mtokens}, cbk) => {
139
+ probe: ['mtokens', 'strictMaxFee', ({mtokens, strictMaxFee}, cbk) => {
119
140
  const attemptedPaths = [];
120
141
  const {features} = args;
121
142
  const start = now();
@@ -130,7 +151,7 @@ module.exports = (args, cbk) => {
130
151
  ignore: args.ignore,
131
152
  incoming_peer: args.in_through,
132
153
  lnd: args.lnd,
133
- max_fee: !args.is_strict_max_fee ? undefined : args.max_fee,
154
+ max_fee_mtokens: strictMaxFee || undefined,
134
155
  max_timeout_height: args.max_timeout_height,
135
156
  messages: args.messages,
136
157
  outgoing_channel: args.outgoing_channel,
@@ -60,6 +60,7 @@ const tokAsMtok = tokens => (BigInt(tokens || 0) * BigInt(1e3)).toString();
60
60
  lnd: <Authenticated LND gRPC API Object>
61
61
  logger: <Winston Logger Object>
62
62
  [max_fee]: <Maximum Fee Tokens Number>
63
+ [max_fee_mtokens]: <Maximum Fee Millitokens Number>
63
64
  [message]: <Message String>
64
65
  [messages]: [{
65
66
  type: <Additional Message To Final Destination Type Number String>
@@ -365,6 +366,7 @@ module.exports = (args, cbk) => {
365
366
  lnd: args.lnd,
366
367
  logger: args.logger,
367
368
  max_fee: args.max_fee,
369
+ max_fee_mtokens: args.max_fee_mtokens,
368
370
  mtokens: !BigInt(to.mtokens) ? tokAsMtok(defaultTokens) : to.mtokens,
369
371
  outgoing_channel: outgoingChannelId,
370
372
  payment: to.payment,
package/package.json CHANGED
@@ -30,17 +30,17 @@
30
30
  "csv-parse": "5.3.1",
31
31
  "ecpair": "2.1.0",
32
32
  "goldengate": "11.4.0",
33
- "grammy": "1.11.2",
33
+ "grammy": "1.12.0",
34
34
  "hot-formula-parser": "4.0.0",
35
35
  "import-lazy": "4.0.0",
36
36
  "ini": "3.0.1",
37
37
  "inquirer": "9.1.4",
38
38
  "ln-accounting": "6.1.0",
39
- "ln-service": "54.2.5",
40
- "ln-sync": "4.0.4",
39
+ "ln-service": "54.2.6",
40
+ "ln-sync": "4.0.5",
41
41
  "ln-telegram": "4.2.0",
42
42
  "moment": "2.29.4",
43
- "paid-services": "4.0.4",
43
+ "paid-services": "4.0.5",
44
44
  "probing": "3.0.0",
45
45
  "psbt": "2.7.1",
46
46
  "qrcode-terminal": "0.12.0",
@@ -83,5 +83,5 @@
83
83
  "postpublish": "docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 -t alexbosworth/balanceofsatoshis --push .",
84
84
  "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"
85
85
  },
86
- "version": "13.3.6"
86
+ "version": "13.4.0"
87
87
  }
@@ -16,6 +16,7 @@ const {isArray} = Array;
16
16
  [in_filters]: [<Inbound Filter Formula String>]
17
17
  [in_outbound]: <Inbound Target Outbound Liquidity Tokens Number>
18
18
  [in_through]: <Pay In Through Peer String>
19
+ [is_strict_max_fee_rate]: <Avoid Probing Too-High Fee Rate Routes Bool>
19
20
  lnd: <Authenticated LND API Object>
20
21
  logger: <Winston Logger Object>
21
22
  [max_fee]: <Maximum Fee Tokens Number>
@@ -91,6 +92,7 @@ module.exports = (args, cbk) => {
91
92
  in_filters: args.in_filters,
92
93
  in_outbound: args.in_outbound,
93
94
  in_through: args.in_through,
95
+ is_strict_max_fee_rate: args.is_strict_max_fee_rate,
94
96
  lnd: args.lnd,
95
97
  logger: args.logger,
96
98
  max_fee: Number(args.max_fee) || undefined,
@@ -32,6 +32,7 @@ const defaultCltvDelta = 40;
32
32
  const defaultMaxFee = 1337;
33
33
  const defaultMaxFeeRate = 250;
34
34
  const defaultMaxFeeTotal = Math.floor(5e6 * 0.0025);
35
+ const feeFromRate = (mtok, rate) => BigInt(mtok) * BigInt(rate) / BigInt(1e6);
35
36
  const flatten = arr => [].concat(...arr);
36
37
  const highInbound = 4500000;
37
38
  const initialProbeTokens = size => Math.round((Math.random() * size) + size);
@@ -54,11 +55,13 @@ const probeSizeMinimal = 1e2;
54
55
  const probeSizeRegular = 2e5
55
56
  const pubKeyHexLength = 66;
56
57
  const rateDivisor = 1e6;
58
+ const {round} = Math;
57
59
  const sample = a => !!a.length ? a[Math.floor(Math.random()*a.length)] : null;
58
60
  const sumOf = arr => arr.reduce((sum, n) => sum + n);
59
61
  const tagFilePath = () => homePath({file: 'tags.json'}).path;
60
62
  const times = 6;
61
63
  const tokAsBigTok = tokens => !tokens ? undefined : (tokens / 1e8).toFixed(8);
64
+ const tokensAsMillitokens = tok => (BigInt(tok) * BigInt(1e3)).toString();
62
65
  const topOf = arr => arr.slice(0, Math.ceil(arr.length / 2));
63
66
  const uniq = arr => Array.from(new Set(arr));
64
67
 
@@ -72,6 +75,7 @@ const uniq = arr => Array.from(new Set(arr));
72
75
  [in_filters]: [<Inbound Filter Formula String>]
73
76
  [in_outbound]: <Inbound Target Outbound Liquidity Tokens Number>
74
77
  [in_through]: <Pay In Through Peer String>
78
+ [is_strict_max_fee_rate]: <Avoid Probing Too-High Fee Rate Routes Bool>
75
79
  lnd: <Authenticated LND API Object>
76
80
  logger: <Winston Logger Object>
77
81
  [max_fee]: <Maximum Fee Tokens Number>
@@ -559,6 +563,24 @@ module.exports = (args, cbk) => {
559
563
  });
560
564
  }],
561
565
 
566
+ // Calculate a max fee to use in the intial probe
567
+ maxFeeMtokens: ['tokens', ({tokens}, cbk) => {
568
+ // Exit early when there is no strict max fee
569
+ if (!args.is_strict_max_fee_rate) {
570
+ return cbk(null, tokensAsMillitokens(defaultMaxFeeTotal));
571
+ }
572
+
573
+ // Exit early with error when there is no fee rate to use
574
+ if (args.max_fee_rate === undefined) {
575
+ return cbk([400, 'ExpectedMaxFeeRateToUseStrictly']);
576
+ }
577
+
578
+ // Convert the initial amount to probe to mtokens
579
+ const mtokens = tokensAsMillitokens(tokens);
580
+
581
+ return cbk(null, feeFromRate(mtokens, args.max_fee_rate).toString());
582
+ }],
583
+
562
584
  // Find a route to the destination
563
585
  findRoute: [
564
586
  'findInKey',
@@ -568,6 +590,7 @@ module.exports = (args, cbk) => {
568
590
  'getPublicKey',
569
591
  'ignore',
570
592
  'max',
593
+ 'maxFeeMtokens',
571
594
  'tokens',
572
595
  ({
573
596
  findInKey,
@@ -577,6 +600,7 @@ module.exports = (args, cbk) => {
577
600
  getPublicKey,
578
601
  ignore,
579
602
  max,
603
+ maxFeeMtokens,
580
604
  tokens,
581
605
  },
582
606
  cbk) =>
@@ -610,9 +634,10 @@ module.exports = (args, cbk) => {
610
634
  return ![findInKey, findOutKey].includes(n.from_public_key);
611
635
  }),
612
636
  in_through: getInbound.public_key,
637
+ is_strict_max_fee: args.is_strict_max_fee_rate || undefined,
613
638
  logger: args.logger,
614
639
  lnd: args.lnd,
615
- max_fee: defaultMaxFeeTotal,
640
+ max_fee_mtokens: maxFeeMtokens,
616
641
  out_through: getOutbound.public_key,
617
642
  timeout_minutes: args.timeout_minutes,
618
643
  },
package/swaps/swap_out.js CHANGED
@@ -125,8 +125,7 @@ const uniq = arr => Array.from(new Set(arr));
125
125
  tokens: <Tokens Number>
126
126
  }
127
127
 
128
- @returns via cbk
129
- {}
128
+ @returns via cbk or Promise
130
129
  */
131
130
  module.exports = (args, cbk) => {
132
131
  return new Promise((resolve, reject) => {
@@ -1689,7 +1688,7 @@ module.exports = (args, cbk) => {
1689
1688
 
1690
1689
  args.logger.info(resolution);
1691
1690
 
1692
- return cbk(null, {});
1691
+ return cbk();
1693
1692
  }],
1694
1693
  },
1695
1694
  returnResult({reject, resolve, of: 'summary'}, cbk));