balanceofsatoshis 11.43.0 → 11.46.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 +12 -0
- package/CONTRIBUTING.md +72 -0
- package/bos +7 -4
- package/network/push_payment.js +16 -2
- package/package.json +4 -4
- package/telegram/start_telegram_bot.js +22 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Versions
|
|
2
2
|
|
|
3
|
+
## 11.46.0
|
|
4
|
+
|
|
5
|
+
- `telegram`: Add `/stop` command to terminate the running bot
|
|
6
|
+
|
|
7
|
+
## 11.45.1
|
|
8
|
+
|
|
9
|
+
- `increase-inbound-liquidity`: Add support for formulas in `--amount`
|
|
10
|
+
|
|
11
|
+
## 11.44.0
|
|
12
|
+
|
|
13
|
+
- `send`: Add support for `--max-fee-rate` to limit fees paid via PPM measure
|
|
14
|
+
|
|
3
15
|
## 11.43.0
|
|
4
16
|
|
|
5
17
|
- `limit-forwards`: Add `--min-channel-confirmations` for custom channel ages
|
package/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Contribution Guidelines
|
|
2
|
+
|
|
3
|
+
- Feel free to open issues or pull requests
|
|
4
|
+
- They may not be addressed or merged
|
|
5
|
+
- You can ignore coding styles if you want
|
|
6
|
+
|
|
7
|
+
## Coding Style
|
|
8
|
+
|
|
9
|
+
If you want to help with style, here are some rough guidelines on style ideas:
|
|
10
|
+
|
|
11
|
+
### Formatting
|
|
12
|
+
|
|
13
|
+
- Spaces not tabs, 2 spaces
|
|
14
|
+
- Arguments to methods are snake_case
|
|
15
|
+
- Regular variables are camelCase
|
|
16
|
+
- Returned attributes are snake_case
|
|
17
|
+
- Minimize function nesting, make new files if nesting is required
|
|
18
|
+
- No extraneous whitespace
|
|
19
|
+
- A single newline should appear at the end of a file
|
|
20
|
+
- Don't bother with () in functions when not needed: `const a = b => c`
|
|
21
|
+
- If there are multiple things together, alphabetize them
|
|
22
|
+
- Don't split up long strings over multiple lines
|
|
23
|
+
- Lines should be terminated by explicit semicolons
|
|
24
|
+
- Logic like ternary operators should not extend beyond a single line
|
|
25
|
+
- Don't let any lines linger when they don't do anything
|
|
26
|
+
- Tightly space objects, like `{attribute: value}` not `{ attribute : value }`
|
|
27
|
+
- Use single '' quotes not double "" quotes, except when `` is required
|
|
28
|
+
- If conditions should avoid spanning multiple lines
|
|
29
|
+
- Avoid double specifying an attribute and value, `{type: type}` vs `{type}`
|
|
30
|
+
|
|
31
|
+
### Control Flow
|
|
32
|
+
|
|
33
|
+
- Async functions should support both cbk and Promise style
|
|
34
|
+
- Use async.js methods for asynchronous control flow
|
|
35
|
+
- Try to exit early from functions when possible, and note this exit in comment
|
|
36
|
+
- Prefer cbk over Promise style, aside from in tests or in Promise libs
|
|
37
|
+
- Use `asyncAuto` for asynchronous control flow dependency management
|
|
38
|
+
- Callbacks should generally be named cbk even when redefinining in inner scope
|
|
39
|
+
- Avoid mixing non-async complex logic and async control flows in the same file
|
|
40
|
+
- Minimize async nesting in returned attributes and in method arguments
|
|
41
|
+
- Methods should always document their arguments and their output
|
|
42
|
+
|
|
43
|
+
### Variables
|
|
44
|
+
|
|
45
|
+
- Generally use undefined rather than null when defining nil types
|
|
46
|
+
- Prefer variable assignments on new lines rather than on a single line
|
|
47
|
+
- Reduce the usage of . property access, like isArray instead of Array.isArray
|
|
48
|
+
- When there is a newline in an object, always put a comma at the end of a line
|
|
49
|
+
- Short properties always go first in objects: `{short, longer: type}`
|
|
50
|
+
- If a statement relies on a statement above it, it should have a newline above
|
|
51
|
+
- Avoid including scalar values such as strings or numbers in the code itself
|
|
52
|
+
|
|
53
|
+
### JS Features
|
|
54
|
+
|
|
55
|
+
- Limit usage of `let` and never use `var`, prefer `const`
|
|
56
|
+
- Limit use of npm dependencies when possible, only use good dependencies
|
|
57
|
+
- Target support of the oldest node.js LTS release still being supported
|
|
58
|
+
- Never use class or prototype
|
|
59
|
+
- Do not import more methods from an import than you actually use
|
|
60
|
+
- Try to avoid passing objects in arguments as much as possible
|
|
61
|
+
- Prefer using function iteration like map and forEach over for and while
|
|
62
|
+
- Use arrow functions and not `function` functions whenever possible
|
|
63
|
+
|
|
64
|
+
### Errors
|
|
65
|
+
|
|
66
|
+
- Never ignore an error case, always deal with it as soon as possible
|
|
67
|
+
- In the case of errors, do include the error string in the code
|
|
68
|
+
- Add simple validations to help target simple calling mistakes
|
|
69
|
+
- When throwing or returning error messages, use PascalCase for the message
|
|
70
|
+
- Use HTTP status codes as a guideline: 4** is a local issue, 5** is remote
|
|
71
|
+
- Return async errors as arrays: `[typeNumber, errorMsgString, extraDetails]`
|
|
72
|
+
- Try to be very specific with error messages and try to not repeat one
|
package/bos
CHANGED
|
@@ -25,6 +25,7 @@ const {accountingCategories} = commandConstants;
|
|
|
25
25
|
const balances = importLazy('./balances');
|
|
26
26
|
const chain = importLazy('./chain');
|
|
27
27
|
const commands = importLazy('./commands');
|
|
28
|
+
const display = importLazy('./display');
|
|
28
29
|
const encryption = importLazy('./encryption');
|
|
29
30
|
const lnd = importLazy('./lnd');
|
|
30
31
|
const network = importLazy('./network');
|
|
@@ -54,7 +55,6 @@ const months = [...Array(12).keys()].map(n => ++n);
|
|
|
54
55
|
const {REPEATABLE} = prog;
|
|
55
56
|
const {STRING} = prog;
|
|
56
57
|
const yearMatch = /^\d{4}$/;
|
|
57
|
-
|
|
58
58
|
prog
|
|
59
59
|
.version(version)
|
|
60
60
|
|
|
@@ -884,10 +884,11 @@ prog
|
|
|
884
884
|
.command('increase-inbound-liquidity', 'Increase node inbound liquidity')
|
|
885
885
|
.help('Spend down a channel to get inbound. Fee is an estimate, may be more')
|
|
886
886
|
.help('If you want to control chain fee increases, use show-raw-recoveries')
|
|
887
|
+
.help('Formulas supported for --amount like 5*m or 0.05*BTC for 5 million')
|
|
887
888
|
.option('--address <out_address>', 'Out chain address to send funds out to')
|
|
888
889
|
.option('--api-key <api_key>', 'Pre-paid API key to use')
|
|
890
|
+
.option('--amount <amount>', 'Amount to increase inbound', STRING, '500*k')
|
|
889
891
|
.option('--avoid <pubkey/chan/tag>', 'Avoid forwarding through', REPEATABLE)
|
|
890
|
-
.option('--amount <amount>', 'Amount to increase liquidity', INT, 5e5)
|
|
891
892
|
.option('--confs <confs>', 'Confs to consider reorg safe', INT, 1)
|
|
892
893
|
.option('--dryrun', 'Only show cost estimate for increase')
|
|
893
894
|
.option('--fast', 'Request swap server avoid batching delay')
|
|
@@ -930,11 +931,11 @@ prog
|
|
|
930
931
|
spend_address: options.spendAddress || undefined,
|
|
931
932
|
spend_tokens: options.spendAmount || undefined,
|
|
932
933
|
timeout: 1000 * 60 * 60 * 10,
|
|
933
|
-
tokens: options.amount,
|
|
934
|
+
tokens: display.parseAmount({amount: options.amount}).tokens,
|
|
934
935
|
},
|
|
935
936
|
responses.returnObject({exit, logger, reject, resolve}));
|
|
936
937
|
} catch (err) {
|
|
937
|
-
return reject(err);
|
|
938
|
+
return reject(logger.error({err}));
|
|
938
939
|
}
|
|
939
940
|
});
|
|
940
941
|
})
|
|
@@ -1464,6 +1465,7 @@ prog
|
|
|
1464
1465
|
.option('--dryrun', 'Avoid actually sending funds')
|
|
1465
1466
|
.option('--in <pubkey_or_alias>', 'Route in through a specific node')
|
|
1466
1467
|
.option('--max-fee <fee>', 'Maximum fee tokens', INT, 1337)
|
|
1468
|
+
.option('--max-fee-rate <max_fee_rate>', 'Max fee rate in PPM to pay', INT)
|
|
1467
1469
|
.option('--message <message>', 'Message to include with payment')
|
|
1468
1470
|
.option('--message-omit-from-key', 'Leave out the from key on messages')
|
|
1469
1471
|
.option('--no-color', 'Mute all colors')
|
|
@@ -1484,6 +1486,7 @@ prog
|
|
|
1484
1486
|
is_omitting_message_from: options.messageOmitFromKey,
|
|
1485
1487
|
lnd: (await lndForNode(logger, options.node)).lnd,
|
|
1486
1488
|
max_fee: options.maxFee,
|
|
1489
|
+
max_fee_rate: options.maxFeeRate,
|
|
1487
1490
|
message: options.message,
|
|
1488
1491
|
quiz_answers: flatten([options.quiz].filter(n => !!n)),
|
|
1489
1492
|
out_through: options.out,
|
package/network/push_payment.js
CHANGED
|
@@ -16,6 +16,7 @@ const probeDestination = require('./probe_destination');
|
|
|
16
16
|
|
|
17
17
|
const coins = ['BTC', 'LTC'];
|
|
18
18
|
const defaultFiatRateProvider = 'coingecko';
|
|
19
|
+
const feeTokensForFeeRate = (tokens, rate) => Math.floor(rate * tokens / 1e6);
|
|
19
20
|
const fiats = ['EUR', 'USD'];
|
|
20
21
|
const hasFiat = n => /(eur|usd)/gim.test(n);
|
|
21
22
|
const {isArray} = Array;
|
|
@@ -23,6 +24,7 @@ const isPublicKey = n => /^[0-9A-F]{66}$/i.test(n);
|
|
|
23
24
|
const maxQuizLength = 10;
|
|
24
25
|
const rateAsTokens = rate => 1e8 / rate;
|
|
25
26
|
const sumOf = arr => arr.reduce((sum, n) => sum + n, Number());
|
|
27
|
+
const {min} = Math;
|
|
26
28
|
const minQuiz = 2;
|
|
27
29
|
const minTokens = 1;
|
|
28
30
|
const networks = {btc: 'BTC', btctestnet: 'BTC', ltc: 'LTC'};
|
|
@@ -45,6 +47,7 @@ const utf8AsHex = n => Buffer.from(n, 'utf8').toString('hex');
|
|
|
45
47
|
lnd: <Authenticated LND API Object>
|
|
46
48
|
logger: <Winston Logger Object>
|
|
47
49
|
max_fee: <Maximum Fee Tokens Number>
|
|
50
|
+
[max_fee_rate]: <Max Fee Rate Tokens Per Million Number>
|
|
48
51
|
[message]: <Message to Include With Payment String>
|
|
49
52
|
[out_through]: <Pay Out Through Peer String>
|
|
50
53
|
quiz_answers: [<Quiz Answer String>]
|
|
@@ -346,7 +349,18 @@ module.exports = (args, cbk) => {
|
|
|
346
349
|
};
|
|
347
350
|
|
|
348
351
|
try {
|
|
349
|
-
|
|
352
|
+
const {tokens} = parseAmount({variables, amount: args.amount});
|
|
353
|
+
|
|
354
|
+
// Exit early when there is no max fee rate to compute max fee for
|
|
355
|
+
if (!!args.max_fee_rate === undefined) {
|
|
356
|
+
return cbk(null, {tokens, max_fee: args.mage_fee});
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
// Compute the max potential fee given the max fee rate constraint
|
|
360
|
+
const maxFeeByRate = feeTokensForFeeRate(tokens, args.max_fee_rate);
|
|
361
|
+
|
|
362
|
+
// The maximum fee to pay is the lower of the fee limit, fee by rate
|
|
363
|
+
return cbk(null, {tokens, max_fee: min(args.max_fee, maxFeeByRate)});
|
|
350
364
|
} catch (err) {
|
|
351
365
|
return cbk([400, 'FailedToParsePushAmount', err]);
|
|
352
366
|
}
|
|
@@ -384,7 +398,7 @@ module.exports = (args, cbk) => {
|
|
|
384
398
|
is_omitting_message_from: args.is_omitting_message_from,
|
|
385
399
|
is_push: payment.is_push,
|
|
386
400
|
is_real_payment: true,
|
|
387
|
-
max_fee:
|
|
401
|
+
max_fee: parseAmount.max_fee,
|
|
388
402
|
message: args.message,
|
|
389
403
|
messages: args.quiz_answers.map((answer, i) => ({
|
|
390
404
|
type: (quizStart + i).toString(),
|
package/package.json
CHANGED
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"crypto-js": "4.1.1",
|
|
29
29
|
"csv-parse": "5.0.4",
|
|
30
30
|
"goldengate": "11.0.0",
|
|
31
|
-
"grammy": "1.
|
|
31
|
+
"grammy": "1.7.0",
|
|
32
32
|
"hot-formula-parser": "4.0.0",
|
|
33
33
|
"import-lazy": "4.0.0",
|
|
34
34
|
"ini": "2.0.0",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"ln-accounting": "5.0.5",
|
|
38
38
|
"ln-service": "53.6.0",
|
|
39
39
|
"ln-sync": "3.9.0",
|
|
40
|
-
"ln-telegram": "3.
|
|
40
|
+
"ln-telegram": "3.13.0",
|
|
41
41
|
"moment": "2.29.1",
|
|
42
42
|
"paid-services": "3.11.0",
|
|
43
43
|
"probing": "2.0.2",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"description": "Lightning balance CLI",
|
|
53
53
|
"devDependencies": {
|
|
54
54
|
"@alexbosworth/tap": "15.0.10",
|
|
55
|
-
"ln-docker-daemons": "2.2.
|
|
55
|
+
"ln-docker-daemons": "2.2.3",
|
|
56
56
|
"mock-lnd": "1.4.1",
|
|
57
57
|
"secp256k1": "4.0.3"
|
|
58
58
|
},
|
|
@@ -81,5 +81,5 @@
|
|
|
81
81
|
"postpublish": "docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 -t alexbosworth/balanceofsatoshis --push .",
|
|
82
82
|
"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"
|
|
83
83
|
},
|
|
84
|
-
"version": "11.
|
|
84
|
+
"version": "11.46.0"
|
|
85
85
|
}
|
|
@@ -25,6 +25,7 @@ const {handleMempoolCommand} = require('ln-telegram');
|
|
|
25
25
|
const {handlePayCommand} = require('ln-telegram');
|
|
26
26
|
const {handlePendingCommand} = require('ln-telegram');
|
|
27
27
|
const {handleStartCommand} = require('ln-telegram');
|
|
28
|
+
const {handleStopCommand} = require('ln-telegram');
|
|
28
29
|
const {handleVersionCommand} = require('ln-telegram');
|
|
29
30
|
const {InputFile} = require('grammy');
|
|
30
31
|
const inquirer = require('inquirer');
|
|
@@ -272,6 +273,7 @@ module.exports = (args, cbk) => {
|
|
|
272
273
|
{command: 'mempool', description: 'Get info about the mempool'},
|
|
273
274
|
{command: 'pay', description: 'Pay a payment request'},
|
|
274
275
|
{command: 'pending', description: 'Get pending forwards, channels'},
|
|
276
|
+
{command: 'stop', description: 'Stop the bot'},
|
|
275
277
|
{command: 'version', description: 'View current bot version'},
|
|
276
278
|
]);
|
|
277
279
|
|
|
@@ -457,6 +459,22 @@ module.exports = (args, cbk) => {
|
|
|
457
459
|
});
|
|
458
460
|
});
|
|
459
461
|
|
|
462
|
+
// Terminate the running bot
|
|
463
|
+
bot.command('stop', async ctx => {
|
|
464
|
+
try {
|
|
465
|
+
await handleStopCommand({
|
|
466
|
+
from: ctx.message.from.id,
|
|
467
|
+
id: connectedId,
|
|
468
|
+
quit: () => bot.stop(),
|
|
469
|
+
reply: (msg, mode) => ctx.reply(msg, mode),
|
|
470
|
+
});
|
|
471
|
+
|
|
472
|
+
process.exit();
|
|
473
|
+
} catch (err) {
|
|
474
|
+
logger.error({err});
|
|
475
|
+
}
|
|
476
|
+
});
|
|
477
|
+
|
|
460
478
|
bot.command('version', async ctx => {
|
|
461
479
|
try {
|
|
462
480
|
await handleVersionCommand({
|
|
@@ -481,6 +499,7 @@ module.exports = (args, cbk) => {
|
|
|
481
499
|
'/mempool - BTC mempool report',
|
|
482
500
|
'/pay - Pay an invoice',
|
|
483
501
|
'/pending - View pending channels, probes, and forwards',
|
|
502
|
+
'/stop - Stop bot',
|
|
484
503
|
'/version - View the current bot version',
|
|
485
504
|
];
|
|
486
505
|
|
|
@@ -599,15 +618,14 @@ module.exports = (args, cbk) => {
|
|
|
599
618
|
return postClosedMessage({
|
|
600
619
|
from,
|
|
601
620
|
lnd,
|
|
602
|
-
request,
|
|
603
621
|
capacity: update.capacity,
|
|
604
622
|
id: connectedId,
|
|
605
623
|
is_breach_close: update.is_breach_close,
|
|
606
624
|
is_cooperative_close: update.is_cooperative_close,
|
|
607
625
|
is_local_force_close: update.is_local_force_close,
|
|
608
626
|
is_remote_force_close: update.is_remote_force_close,
|
|
609
|
-
key: apiKey.key,
|
|
610
627
|
partner_public_key: update.partner_public_key,
|
|
628
|
+
send: (id, message) => bot.api.sendMessage(id, message, markdown),
|
|
611
629
|
},
|
|
612
630
|
err => !!err ? logger.error({node: from, closed_err: err}) : null);
|
|
613
631
|
});
|
|
@@ -616,13 +634,12 @@ module.exports = (args, cbk) => {
|
|
|
616
634
|
return postOpenMessage({
|
|
617
635
|
from,
|
|
618
636
|
lnd,
|
|
619
|
-
request,
|
|
620
637
|
capacity: update.capacity,
|
|
621
638
|
id: connectedId,
|
|
622
639
|
is_partner_initiated: update.is_partner_initiated,
|
|
623
640
|
is_private: update.is_private,
|
|
624
|
-
key: apiKey.key,
|
|
625
641
|
partner_public_key: update.partner_public_key,
|
|
642
|
+
send: (id, message) => bot.api.sendMessage(id, message, markdown),
|
|
626
643
|
},
|
|
627
644
|
err => !!err ? logger.error({open_err: err}) : null);
|
|
628
645
|
});
|
|
@@ -899,10 +916,9 @@ module.exports = (args, cbk) => {
|
|
|
899
916
|
|
|
900
917
|
return await postChainTransaction({
|
|
901
918
|
from,
|
|
902
|
-
request,
|
|
903
919
|
confirmed: transaction.is_confirmed,
|
|
904
920
|
id: connectedId,
|
|
905
|
-
|
|
921
|
+
send: (id, message) => bot.api.sendMessage(id, message, markdown),
|
|
906
922
|
transaction: record,
|
|
907
923
|
});
|
|
908
924
|
} catch (err) {
|