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 +8 -0
- package/bos +2 -0
- package/network/execute_probe.js +23 -2
- package/network/probe_destination.js +2 -0
- package/package.json +5 -5
- package/swaps/manage_rebalance.js +2 -0
- package/swaps/rebalance.js +26 -1
- package/swaps/swap_out.js +2 -3
package/CHANGELOG.md
CHANGED
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,
|
package/network/execute_probe.js
CHANGED
|
@@ -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
|
-
|
|
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.
|
|
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.
|
|
40
|
-
"ln-sync": "4.0.
|
|
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.
|
|
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.
|
|
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,
|
package/swaps/rebalance.js
CHANGED
|
@@ -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
|
-
|
|
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(
|
|
1691
|
+
return cbk();
|
|
1693
1692
|
}],
|
|
1694
1693
|
},
|
|
1695
1694
|
returnResult({reject, resolve, of: 'summary'}, cbk));
|