balanceofsatoshis 10.16.2 → 10.19.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 +27 -0
- package/README.md +19 -3
- package/balances/detailed_balances.js +5 -1
- package/balances/get_balance.js +1 -1
- package/balances/get_detailed_balance.js +49 -1
- package/balances/get_liquidity.js +2 -2
- package/bos +8 -2
- package/commands/api.json +140 -10
- package/commands/call_raw_api.js +37 -3
- package/network/get_peers.js +9 -1
- package/network/probe_destination.js +6 -2
- package/network/push_payment.js +6 -0
- package/package.json +6 -6
- package/peers/open_channels.js +10 -2
- package/routing/get_fees_paid.js +34 -7
- package/routing/get_ignores.js +19 -1
- package/services/service_paid_requests.js +19 -1
- package/services/use_paid_service.js +4 -4
- package/telegram/start_telegram_bot.js +18 -2
- package/test/balances/test_detailed_balance.js +5 -2
- package/test/routing/test_update_channel_fee.js +1 -1
- package/wallets/get_received_chart.js +1 -1
- package/wallets/index.js +1 -2
- package/routing/get_rebalance_payments.js +0 -162
- package/wallets/get_all_invoices.js +0 -125
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,32 @@
|
|
|
1
1
|
# Versions
|
|
2
2
|
|
|
3
|
+
## Version 10.19.0
|
|
4
|
+
|
|
5
|
+
- `balance`: Included locked UTXO value as on-chain value in `--detailed` balance output
|
|
6
|
+
- `increase-inbound-liquidity|pay|probe|rebalance|send`: Add `AGE` to avoid formulas
|
|
7
|
+
- `peers`: Avoid errors when network name is unknown
|
|
8
|
+
- `push`: Add `--message-omit-from-key` to send messages without including "from" key
|
|
9
|
+
|
|
10
|
+
## Version 10.18.1
|
|
11
|
+
|
|
12
|
+
- `open`: In final tx id indication use original external tx id when available
|
|
13
|
+
|
|
14
|
+
## Version 10.18.0
|
|
15
|
+
|
|
16
|
+
- `call`: Add support for `broadcastChainTransaction`, `cancelHodlInvoice`
|
|
17
|
+
`cancelPendingChannel`, `createChainAddress`, `createHodlInvoice`, `deletePayments`,
|
|
18
|
+
`settleHodlInvoice`, `subscribeToBackups`, `subscribeToBlocks`,
|
|
19
|
+
`subscribeToChannels`, `subscribeToForwards`, `subscribeToGraph`,
|
|
20
|
+
`subscribeToInvoice`, `subscribeToInvoices`, `subscribeToPeers`,
|
|
21
|
+
`subscribeToTransactions`.
|
|
22
|
+
- `services`: Add service `--invoice` to create invoices on request
|
|
23
|
+
- `services`: Automatically retry on `relay` service if destination payment fails
|
|
24
|
+
|
|
25
|
+
## Version 10.17.0
|
|
26
|
+
|
|
27
|
+
- `chart-fees-paid`: Add tag icons to nodes in table view
|
|
28
|
+
- `telegram`: Add `/costs` command to report rebalance and chain fees
|
|
29
|
+
|
|
3
30
|
## Version 10.16.2
|
|
4
31
|
|
|
5
32
|
- `chart-chain-fees`: Add mempool space chain fee lookup redundancy
|
package/README.md
CHANGED
|
@@ -12,8 +12,8 @@ Commands for working with LND balances.
|
|
|
12
12
|
If you want to try out any command without npm install, you can also do `npx
|
|
13
13
|
balanceofsatoshis` to run a command directly.
|
|
14
14
|
|
|
15
|
-
If you have [Docker](https://docs.docker.com/get-docker/) installed
|
|
16
|
-
[run through Docker](#docker) instead.
|
|
15
|
+
If you have [Docker](https://docs.docker.com/get-docker/) installed or are using a Docker based
|
|
16
|
+
platform like Umbrel or BTCPayServer, you can [run through Docker](#docker) instead.
|
|
17
17
|
|
|
18
18
|
```shell
|
|
19
19
|
npm install -g balanceofsatoshis
|
|
@@ -227,7 +227,12 @@ Use any shorthand you'd like when choosing this profile node name
|
|
|
227
227
|
|
|
228
228
|
#### Umbrel Saved Node
|
|
229
229
|
|
|
230
|
-
Note: Umbrel is not FOSS software, use at your own risk
|
|
230
|
+
*Note: Umbrel is not FOSS software, use at your own risk.*
|
|
231
|
+
|
|
232
|
+
If you are using Umbrel and you have already installed but you get an error like
|
|
233
|
+
`Name resolution failed for target dns:umbrel.local:10009` then try adding umbrel.local
|
|
234
|
+
to your `/etc/hosts` file, like `sudo nano /etc/hosts` and add a line
|
|
235
|
+
`127.0.0.1 umbrel.local`
|
|
231
236
|
|
|
232
237
|
1. Identify your Umbrel home dir, like /home/umbrel/umbrel
|
|
233
238
|
2. Look in the .env file in that dir for the `LND_IP` to use as the socket to connect to
|
|
@@ -446,6 +451,17 @@ Or on Linux:
|
|
|
446
451
|
--network="host" -v $HOME/.lnd:/home/node/.lnd:ro
|
|
447
452
|
```
|
|
448
453
|
|
|
454
|
+
On BTCpayServer:
|
|
455
|
+
|
|
456
|
+
Create the credential.json file as explained in the saved nodes section, and for socket put:
|
|
457
|
+
`"socket": "lnd_bitcoin:10009"`
|
|
458
|
+
|
|
459
|
+
For Docker network use the Docker bridged network:
|
|
460
|
+
|
|
461
|
+
```
|
|
462
|
+
docker run -it --rm --network="generated_default" -v $HOME/.bos:/home/node/.bos alexbosworth/balanceofsatoshis balance --node SAVEDNODENAME
|
|
463
|
+
```
|
|
464
|
+
|
|
449
465
|
On Umbrel this would be:
|
|
450
466
|
|
|
451
467
|
```
|
|
@@ -31,6 +31,9 @@ const witnessSizeCounterVByteLength = 0.25;
|
|
|
31
31
|
tokens: <Payment Size Tokens Number>
|
|
32
32
|
}]
|
|
33
33
|
}]
|
|
34
|
+
locked: [{
|
|
35
|
+
tokens: <Unspent Tokens Number>
|
|
36
|
+
}]
|
|
34
37
|
pending: [{
|
|
35
38
|
is_opening: <Channel is Pending Bool>
|
|
36
39
|
is_partner_initiated: <Partner Responsible For Chain Fees Bool>
|
|
@@ -64,7 +67,7 @@ const witnessSizeCounterVByteLength = 0.25;
|
|
|
64
67
|
onchain_vbytes: <Estimated Virtual Bytes to Spend On-Chain Funds Number>
|
|
65
68
|
}
|
|
66
69
|
*/
|
|
67
|
-
module.exports = ({channels, pending, transactions, utxos}) => {
|
|
70
|
+
module.exports = ({channels, locked, pending, transactions, utxos}) => {
|
|
68
71
|
const channelBalances = channels.map(n => n.local_balance);
|
|
69
72
|
const confirmedUtxos = utxos.filter(n => !!n.confirmation_count);
|
|
70
73
|
|
|
@@ -115,6 +118,7 @@ module.exports = ({channels, pending, transactions, utxos}) => {
|
|
|
115
118
|
const chainBalance = sumOf([]
|
|
116
119
|
.concat(confirmedUtxos)
|
|
117
120
|
.concat(changeUtxos)
|
|
121
|
+
.concat(locked)
|
|
118
122
|
.map(n => n.tokens)
|
|
119
123
|
);
|
|
120
124
|
|
package/balances/get_balance.js
CHANGED
|
@@ -2,12 +2,16 @@ const asyncAuto = require('async/auto');
|
|
|
2
2
|
const {formatTokens} = require('ln-sync');
|
|
3
3
|
const {getChainTransactions} = require('ln-service');
|
|
4
4
|
const {getChannels} = require('ln-service');
|
|
5
|
+
const {getLockedUtxos} = require('ln-service');
|
|
5
6
|
const {getPendingChannels} = require('ln-service');
|
|
6
7
|
const {getUtxos} = require('ln-service');
|
|
7
8
|
const {returnResult} = require('asyncjs-util');
|
|
9
|
+
const {Transaction} = require('bitcoinjs-lib');
|
|
8
10
|
|
|
9
11
|
const detailedBalances = require('./detailed_balances');
|
|
10
12
|
|
|
13
|
+
const {fromHex} = Transaction;
|
|
14
|
+
|
|
11
15
|
/** Get a detailed balance that categorizes balance of tokens on the node
|
|
12
16
|
|
|
13
17
|
{
|
|
@@ -39,6 +43,18 @@ module.exports = (args, cbk) => {
|
|
|
39
43
|
return getChannels({lnd: args.lnd}, cbk);
|
|
40
44
|
}],
|
|
41
45
|
|
|
46
|
+
// Get locked UTXOs
|
|
47
|
+
getLocked: ['validate', ({}, cbk) => {
|
|
48
|
+
return getLockedUtxos({lnd: args.lnd}, (err, res) => {
|
|
49
|
+
// Ignore errors
|
|
50
|
+
if (!!err) {
|
|
51
|
+
return cbk(null, []);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return cbk(null, res.utxos);
|
|
55
|
+
});
|
|
56
|
+
}],
|
|
57
|
+
|
|
42
58
|
// Get pending channels
|
|
43
59
|
getPending: ['validate', ({}, cbk) => {
|
|
44
60
|
return getPendingChannels({lnd: args.lnd}, cbk);
|
|
@@ -52,17 +68,49 @@ module.exports = (args, cbk) => {
|
|
|
52
68
|
// Get the UTXOs
|
|
53
69
|
getUtxos: ['validate', ({}, cbk) => getUtxos({lnd: args.lnd}, cbk)],
|
|
54
70
|
|
|
71
|
+
// Cross reference locked transactions to UTXO data
|
|
72
|
+
locked: ['getLocked', 'getTx', ({getLocked, getTx}, cbk) => {
|
|
73
|
+
const {transactions} = getTx;
|
|
74
|
+
|
|
75
|
+
const utxos = getLocked.map(locked => {
|
|
76
|
+
// Exit early when the lock is expired
|
|
77
|
+
if (locked.lock_expires_at < new Date().toISOString()) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const tx = transactions.find(n => n.id === locked.transaction_id);
|
|
82
|
+
|
|
83
|
+
// Exit early when there is no related confirmed transaction
|
|
84
|
+
if (!tx || !tx.transaction || !tx.confirmation_count) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const output = fromHex(tx.transaction).outs[locked.transaction_vout];
|
|
89
|
+
|
|
90
|
+
// Exit early when the output is not found in the transaction
|
|
91
|
+
if (!output) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return {tokens: output.value};
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
return cbk(null, utxos.filter(n => !!n));
|
|
99
|
+
}],
|
|
100
|
+
|
|
55
101
|
// Calculate balance
|
|
56
102
|
balance: [
|
|
57
103
|
'getChannels',
|
|
58
104
|
'getPending',
|
|
59
105
|
'getTx',
|
|
60
106
|
'getUtxos',
|
|
61
|
-
|
|
107
|
+
'locked',
|
|
108
|
+
({getChannels, getPending, getTx, getUtxos, locked}, cbk) =>
|
|
62
109
|
{
|
|
63
110
|
const format = tokens => formatTokens({tokens}).display.trim();
|
|
64
111
|
|
|
65
112
|
const balances = detailedBalances({
|
|
113
|
+
locked,
|
|
66
114
|
channels: getChannels.channels,
|
|
67
115
|
pending: getPending.pending_channels,
|
|
68
116
|
transactions: getTx.transactions,
|
|
@@ -21,14 +21,14 @@ const topPercentile = 0.9;
|
|
|
21
21
|
[below]: <Tokens Below Tokens Number>
|
|
22
22
|
[is_outbound]: <Return Outbound Liquidity Bool>
|
|
23
23
|
[is_top]: <Return Top Liquidity Bool>
|
|
24
|
-
lnd: <Authenticated LND
|
|
24
|
+
lnd: <Authenticated LND API Object>
|
|
25
25
|
[min_node_score]: <Minimum Node Score Number>
|
|
26
26
|
[max_fee_rate]: <Max Inbound Fee Rate Parts Per Million Number>
|
|
27
27
|
[request]: <Request Function>
|
|
28
28
|
[with]: <Liquidity With Specific Node Public Key Hex String>
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
@returns via cbk
|
|
31
|
+
@returns via cbk or Promise
|
|
32
32
|
{
|
|
33
33
|
balance: <Liquid Tokens Number>
|
|
34
34
|
}
|
package/bos
CHANGED
|
@@ -216,6 +216,7 @@ prog
|
|
|
216
216
|
return new Promise(async (resolve, reject) => {
|
|
217
217
|
try {
|
|
218
218
|
return commands.callRawApi({
|
|
219
|
+
logger,
|
|
219
220
|
ask: (n, cbk) => inquirer.prompt([n]).then(n => cbk(null, n)),
|
|
220
221
|
lnd: (await lndForNode(logger, options.node)).lnd,
|
|
221
222
|
method: args.method,
|
|
@@ -358,6 +359,7 @@ prog
|
|
|
358
359
|
try {
|
|
359
360
|
return routing.getFeesPaid({
|
|
360
361
|
days: options.days,
|
|
362
|
+
fs: {getFile: readFile},
|
|
361
363
|
is_most_fees_table: options.mostFees,
|
|
362
364
|
is_most_forwarded_table: options.mostForwarded,
|
|
363
365
|
is_network: options.network,
|
|
@@ -950,7 +952,7 @@ prog
|
|
|
950
952
|
|
|
951
953
|
// Open channels
|
|
952
954
|
.command('open', 'Open channels, optionally using an external wallet')
|
|
953
|
-
.help('
|
|
955
|
+
.help('When creating channels from an external wallet do not self-broadcast')
|
|
954
956
|
.argument('<peer_public_keys...>', 'With nodes with public keys')
|
|
955
957
|
.option('--amount <channel_capacity>', 'Capacities to open', REPEATABLE)
|
|
956
958
|
.option('--external-funding', 'Use external funds for the channel open')
|
|
@@ -1189,7 +1191,7 @@ prog
|
|
|
1189
1191
|
.help('--avoid can take a channel id or a public key to avoid')
|
|
1190
1192
|
.help('--avoid can take a public_key/public_key to avoid a directed pair')
|
|
1191
1193
|
.help('--avoid can take a FORMULA/public_key to avoid inbound peers')
|
|
1192
|
-
.help('--avoid FORMULA variables: FEE_RATE, BASE_FEE, HEIGHT')
|
|
1194
|
+
.help('--avoid FORMULA variables: FEE_RATE, BASE_FEE, HEIGHT, AGE')
|
|
1193
1195
|
.help('--in decreases the inbound liquidity with a specific peer/tag')
|
|
1194
1196
|
.help('--out increases the inbound liquidity with a specific peer/tag')
|
|
1195
1197
|
.option('--amount <amount>', 'Maximum amount to rebalance')
|
|
@@ -1346,6 +1348,7 @@ prog
|
|
|
1346
1348
|
.option('--in <pubkey_or_alias>', 'Route in through a specific node')
|
|
1347
1349
|
.option('--max-fee <fee>', 'Maximum fee tokens', INT, 1337)
|
|
1348
1350
|
.option('--message <message>', 'Message to include with payment')
|
|
1351
|
+
.option('--message-omit-from-key', 'Leave out the from key on messages')
|
|
1349
1352
|
.option('--no-color', 'Mute all colors')
|
|
1350
1353
|
.option('--node <name>', 'Node to send funds from')
|
|
1351
1354
|
.option('--out <pubkey_or_alias>', 'Route out through a specific peer')
|
|
@@ -1366,6 +1369,7 @@ prog
|
|
|
1366
1369
|
fs: {getFile: readFile},
|
|
1367
1370
|
in_through: options.in,
|
|
1368
1371
|
is_dry_run: options.dryrun,
|
|
1372
|
+
is_omitting_message_from: options.messageOmitFromKey,
|
|
1369
1373
|
max_fee: options.maxFee,
|
|
1370
1374
|
message: options.message,
|
|
1371
1375
|
quiz_answers: flatten([options.quiz].filter(n => !!n)),
|
|
@@ -1393,6 +1397,7 @@ prog
|
|
|
1393
1397
|
.option('--inbox-sms-to', 'Inbox service sms to number')
|
|
1394
1398
|
.option('--inbox-sms-twilio-sid', 'Inbox service Twilio account sid')
|
|
1395
1399
|
.option('--inbox-sms-twilio-auth', 'Inbox service Twilio auth token')
|
|
1400
|
+
.option('--invoice', 'Enable creating custom invoices on demand')
|
|
1396
1401
|
.option('--node <node_name>', 'Saved node')
|
|
1397
1402
|
.option('--payer <pay_with_node_name>', 'Node to pay request responses with')
|
|
1398
1403
|
.option('--profile <profile>', 'Share a profile with info about your node')
|
|
@@ -1416,6 +1421,7 @@ prog
|
|
|
1416
1421
|
inbox_twilio_account_sid: options.inboxSmsTwilioSid,
|
|
1417
1422
|
inbox_twilio_auth_token: options.inboxSmsTwilioAuth,
|
|
1418
1423
|
is_connect_enabled: !!options.connect || undefined,
|
|
1424
|
+
is_invoice_enabled: !!options.invoice || undefined,
|
|
1419
1425
|
is_relay_enabled: !!options.relay || undefined,
|
|
1420
1426
|
network_nodes: flatten([options.network].filter(n => !!n)),
|
|
1421
1427
|
node: options.node,
|
package/commands/api.json
CHANGED
|
@@ -14,6 +14,40 @@
|
|
|
14
14
|
],
|
|
15
15
|
"method": "addPeer"
|
|
16
16
|
},
|
|
17
|
+
{
|
|
18
|
+
"arguments": [
|
|
19
|
+
{
|
|
20
|
+
"description": "Raw hex encoded signed raw transaction",
|
|
21
|
+
"named": "transaction"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"description": "Transaction description label",
|
|
25
|
+
"named": "description",
|
|
26
|
+
"optional": true
|
|
27
|
+
}
|
|
28
|
+
],
|
|
29
|
+
"method": "broadcastChainTransaction"
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"arguments": [
|
|
33
|
+
{
|
|
34
|
+
"description": "Id of invoice to cancel",
|
|
35
|
+
"named": "id",
|
|
36
|
+
"type": "hash"
|
|
37
|
+
}
|
|
38
|
+
],
|
|
39
|
+
"method": "cancelHodlInvoice"
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"arguments": [
|
|
43
|
+
{
|
|
44
|
+
"description": "Id of pending channel to cancel",
|
|
45
|
+
"named": "id",
|
|
46
|
+
"type": "hash"
|
|
47
|
+
}
|
|
48
|
+
],
|
|
49
|
+
"method": "cancelPendingChannel"
|
|
50
|
+
},
|
|
17
51
|
{
|
|
18
52
|
"arguments": [
|
|
19
53
|
{
|
|
@@ -34,6 +68,42 @@
|
|
|
34
68
|
],
|
|
35
69
|
"method": "closeChannel"
|
|
36
70
|
},
|
|
71
|
+
{
|
|
72
|
+
"arguments": [
|
|
73
|
+
{
|
|
74
|
+
"description": "Chain address format, np2wpkh or p2wpkh",
|
|
75
|
+
"named": "format"
|
|
76
|
+
}
|
|
77
|
+
],
|
|
78
|
+
"method": "createChainAddress"
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"arguments": [
|
|
82
|
+
{
|
|
83
|
+
"description": "Final CLTV delta",
|
|
84
|
+
"named": "cltv_delta",
|
|
85
|
+
"optional": true,
|
|
86
|
+
"type": "number"
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
"description": "Description",
|
|
90
|
+
"named": "description",
|
|
91
|
+
"optional": true
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
"description": "Hash",
|
|
95
|
+
"named": "id",
|
|
96
|
+
"optional": true,
|
|
97
|
+
"type": "hash"
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"description": "Millitokens to request",
|
|
101
|
+
"named": "mtokens",
|
|
102
|
+
"optional": true
|
|
103
|
+
}
|
|
104
|
+
],
|
|
105
|
+
"method": "createHodlInvoice"
|
|
106
|
+
},
|
|
37
107
|
{
|
|
38
108
|
"arguments": [
|
|
39
109
|
{
|
|
@@ -72,6 +142,9 @@
|
|
|
72
142
|
{
|
|
73
143
|
"method": "deleteForwardingReputations"
|
|
74
144
|
},
|
|
145
|
+
{
|
|
146
|
+
"method": "deletePayments"
|
|
147
|
+
},
|
|
75
148
|
{
|
|
76
149
|
"arguments": [
|
|
77
150
|
{
|
|
@@ -250,6 +323,16 @@
|
|
|
250
323
|
{
|
|
251
324
|
"method": "getIdentity"
|
|
252
325
|
},
|
|
326
|
+
{
|
|
327
|
+
"arguments": [
|
|
328
|
+
{
|
|
329
|
+
"description": "Invoice hex encoded payment hash",
|
|
330
|
+
"named": "id",
|
|
331
|
+
"type": "hash"
|
|
332
|
+
}
|
|
333
|
+
],
|
|
334
|
+
"method": "getInvoice"
|
|
335
|
+
},
|
|
253
336
|
{
|
|
254
337
|
"arguments": [
|
|
255
338
|
{
|
|
@@ -266,16 +349,6 @@
|
|
|
266
349
|
],
|
|
267
350
|
"method": "getInvoices"
|
|
268
351
|
},
|
|
269
|
-
{
|
|
270
|
-
"arguments": [
|
|
271
|
-
{
|
|
272
|
-
"description": "Invoice hex encoded payment hash",
|
|
273
|
-
"named": "id",
|
|
274
|
-
"type": "hash"
|
|
275
|
-
}
|
|
276
|
-
],
|
|
277
|
-
"method": "getInvoice"
|
|
278
|
-
},
|
|
279
352
|
{
|
|
280
353
|
"method": "getLockedUtxos"
|
|
281
354
|
},
|
|
@@ -476,6 +549,15 @@
|
|
|
476
549
|
],
|
|
477
550
|
"method": "requestChainFeeIncrease"
|
|
478
551
|
},
|
|
552
|
+
{
|
|
553
|
+
"arguments": [
|
|
554
|
+
{
|
|
555
|
+
"description": "Hex encoded secret preimage",
|
|
556
|
+
"named": "secret"
|
|
557
|
+
}
|
|
558
|
+
],
|
|
559
|
+
"method": "settleHodlInvoice"
|
|
560
|
+
},
|
|
479
561
|
{
|
|
480
562
|
"arguments": [{
|
|
481
563
|
"description": "Message to sign",
|
|
@@ -486,6 +568,54 @@
|
|
|
486
568
|
{
|
|
487
569
|
"method": "stopDaemon"
|
|
488
570
|
},
|
|
571
|
+
{
|
|
572
|
+
"events": ["backup"],
|
|
573
|
+
"method": "subscribeToBackups"
|
|
574
|
+
},
|
|
575
|
+
{
|
|
576
|
+
"events": ["block"],
|
|
577
|
+
"method": "subscribeToBlocks"
|
|
578
|
+
},
|
|
579
|
+
{
|
|
580
|
+
"events": [
|
|
581
|
+
"channel_active_changed",
|
|
582
|
+
"channel_closed",
|
|
583
|
+
"channel_opened",
|
|
584
|
+
"channel_opening"
|
|
585
|
+
],
|
|
586
|
+
"method": "subscribeToChannels"
|
|
587
|
+
},
|
|
588
|
+
{
|
|
589
|
+
"events": ["forward"],
|
|
590
|
+
"method": "subscribeToForwards"
|
|
591
|
+
},
|
|
592
|
+
{
|
|
593
|
+
"events": ["channel_closed", "channel_updated", "node_updated"],
|
|
594
|
+
"method": "subscribeToGraph"
|
|
595
|
+
},
|
|
596
|
+
{
|
|
597
|
+
"arguments": [
|
|
598
|
+
{
|
|
599
|
+
"description": "Invoice preimage hash hex encoded",
|
|
600
|
+
"named": "id",
|
|
601
|
+
"type": "hash"
|
|
602
|
+
}
|
|
603
|
+
],
|
|
604
|
+
"events": ["invoice_updated"],
|
|
605
|
+
"method": "subscribeToInvoice"
|
|
606
|
+
},
|
|
607
|
+
{
|
|
608
|
+
"events": ["invoice_updated"],
|
|
609
|
+
"method": "subscribeToInvoices"
|
|
610
|
+
},
|
|
611
|
+
{
|
|
612
|
+
"events": ["connected", "disconnected"],
|
|
613
|
+
"method": "subscribeToPeers"
|
|
614
|
+
},
|
|
615
|
+
{
|
|
616
|
+
"events": ["chain_transaction"],
|
|
617
|
+
"method": "subscribeToTransactions"
|
|
618
|
+
},
|
|
489
619
|
{
|
|
490
620
|
"arguments": [
|
|
491
621
|
{
|
package/commands/call_raw_api.js
CHANGED
|
@@ -10,19 +10,21 @@ const isHash = n => !!n && /^[0-9A-F]{64}$/i.test(n);
|
|
|
10
10
|
const isPublicKey = n => !!n && /^0[2-3][0-9A-F]{64}$/i.test(n);
|
|
11
11
|
const {keys} = Object;
|
|
12
12
|
const lower = n => n.toLowerCase();
|
|
13
|
+
const methodDetails = (calls, method) => calls.find(n => n.method === method);
|
|
13
14
|
|
|
14
15
|
/** Call the raw API
|
|
15
16
|
|
|
16
17
|
{
|
|
17
18
|
ask: <Inquirer Function> ({message, name, type}, cbk) => {}
|
|
18
19
|
lnd: <Authenticated LND API Object>
|
|
20
|
+
logger: <Winston Logger Object>
|
|
19
21
|
[method]: <Method to Call String>
|
|
20
22
|
}
|
|
21
23
|
|
|
22
24
|
@returns via cbk or Promise
|
|
23
25
|
<Result Object>
|
|
24
26
|
*/
|
|
25
|
-
module.exports = ({ask, lnd, method}, cbk) => {
|
|
27
|
+
module.exports = ({ask, lnd, logger, method}, cbk) => {
|
|
26
28
|
return new Promise((resolve, reject) => {
|
|
27
29
|
return asyncAuto({
|
|
28
30
|
// Check arguments
|
|
@@ -35,6 +37,10 @@ module.exports = ({ask, lnd, method}, cbk) => {
|
|
|
35
37
|
return cbk([400, 'ExpectedAuthenticatedLndToCallApi']);
|
|
36
38
|
}
|
|
37
39
|
|
|
40
|
+
if (!logger) {
|
|
41
|
+
return cbk([400, 'ExpectedLoggerToCallApi']);
|
|
42
|
+
}
|
|
43
|
+
|
|
38
44
|
if (!!method && !calls.find(n => lower(n.method) === lower(method))) {
|
|
39
45
|
return cbk([404, 'UnrecognizedMethod']);
|
|
40
46
|
}
|
|
@@ -118,8 +124,8 @@ module.exports = ({ask, lnd, method}, cbk) => {
|
|
|
118
124
|
cbk);
|
|
119
125
|
}],
|
|
120
126
|
|
|
121
|
-
//
|
|
122
|
-
|
|
127
|
+
// Derive arguments
|
|
128
|
+
arguments: ['getArguments', ({getArguments}, cbk) => {
|
|
123
129
|
const arguments = getArguments.reduce((sum, answer) => {
|
|
124
130
|
keys(answer).forEach(key => {
|
|
125
131
|
if (answer[key] === Number()) {
|
|
@@ -133,6 +139,34 @@ module.exports = ({ask, lnd, method}, cbk) => {
|
|
|
133
139
|
},
|
|
134
140
|
{lnd});
|
|
135
141
|
|
|
142
|
+
return cbk(null, arguments);
|
|
143
|
+
}],
|
|
144
|
+
|
|
145
|
+
// Set up subscription
|
|
146
|
+
subscribe: ['arguments', 'getMethod', ({arguments, getMethod}, cbk) => {
|
|
147
|
+
// Exit early when this is a request/response API
|
|
148
|
+
if (!methodDetails(calls, getMethod.method).events) {
|
|
149
|
+
return cbk();
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const sub = lnService[getMethod.method](arguments);
|
|
153
|
+
|
|
154
|
+
sub.on('error', err => cbk([503, 'ApiSubscriptionError', {err}]));
|
|
155
|
+
|
|
156
|
+
const {events} = methodDetails(calls, getMethod.method);
|
|
157
|
+
|
|
158
|
+
logger.info({listening_for: events});
|
|
159
|
+
|
|
160
|
+
events.forEach(n => sub.on(n, data => logger.info({[n]: data})));
|
|
161
|
+
}],
|
|
162
|
+
|
|
163
|
+
// Call API
|
|
164
|
+
call: ['arguments', 'getMethod', ({arguments, getMethod}, cbk) => {
|
|
165
|
+
// Exit early when this is an event-based API
|
|
166
|
+
if (!!methodDetails(calls, getMethod.method).events) {
|
|
167
|
+
return cbk();
|
|
168
|
+
}
|
|
169
|
+
|
|
136
170
|
return lnService[getMethod.method](arguments, cbk);
|
|
137
171
|
}],
|
|
138
172
|
},
|
package/network/get_peers.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const asyncAuto = require('async/auto');
|
|
2
2
|
const asyncMap = require('async/map');
|
|
3
|
+
const asyncReflect = require('async/reflect');
|
|
3
4
|
const asyncUntil = require('async/until');
|
|
4
5
|
const {bold} = require('colorette');
|
|
5
6
|
const {decodeChanId} = require('bolt07');
|
|
@@ -191,6 +192,11 @@ module.exports = (args, cbk) => {
|
|
|
191
192
|
);
|
|
192
193
|
}],
|
|
193
194
|
|
|
195
|
+
// Get the network name
|
|
196
|
+
getNetwork: ['validate', asyncReflect(({}, cbk) => {
|
|
197
|
+
return getNetwork({lnd: args.lnd}, cbk);
|
|
198
|
+
})],
|
|
199
|
+
|
|
194
200
|
// Get payments
|
|
195
201
|
getPayments: ['validate', ({}, cbk) => {
|
|
196
202
|
// Exit early and skip long payments lookup when idle days not needed
|
|
@@ -330,6 +336,7 @@ module.exports = (args, cbk) => {
|
|
|
330
336
|
'forwards',
|
|
331
337
|
'getChannels',
|
|
332
338
|
'getInvoices',
|
|
339
|
+
'getNetwork',
|
|
333
340
|
'getPayments',
|
|
334
341
|
'getPeers',
|
|
335
342
|
'getPending',
|
|
@@ -339,6 +346,7 @@ module.exports = (args, cbk) => {
|
|
|
339
346
|
forwards,
|
|
340
347
|
getChannels,
|
|
341
348
|
getInvoices,
|
|
349
|
+
getNetwork,
|
|
342
350
|
getPayments,
|
|
343
351
|
getPeers,
|
|
344
352
|
getPending,
|
|
@@ -400,7 +408,7 @@ module.exports = (args, cbk) => {
|
|
|
400
408
|
|
|
401
409
|
const maxInbound = args.inbound_liquidity_below;
|
|
402
410
|
const maxOutbound = args.outbound_liquidity_below;
|
|
403
|
-
const {network} =
|
|
411
|
+
const {network} = getNetwork.value || {};
|
|
404
412
|
const peerKeys = getChannels.channels.map(n => n.partner_public_key);
|
|
405
413
|
const wallet = await getHeight({lnd: args.lnd});
|
|
406
414
|
|
|
@@ -53,6 +53,7 @@ const tokAsMtok = tokens => (BigInt(tokens || 0) * BigInt(1e3)).toString();
|
|
|
53
53
|
[to_public_key]: <Avoid Routing To Node With Public Key Hex String>
|
|
54
54
|
}]
|
|
55
55
|
[in_through]: <Pay In Through Public Key Hex String>
|
|
56
|
+
[is_omitting_message_from]: <Omit Message From Fields Bool>
|
|
56
57
|
[is_push]: <Is Push Payment Bool>
|
|
57
58
|
[is_real_payment]: <Pay the Request after Probing Bool> // default: false
|
|
58
59
|
[is_strict_max_fee]: <Avoid Probing Too-High Fee Routes Bool>
|
|
@@ -238,14 +239,17 @@ module.exports = (args, cbk) => {
|
|
|
238
239
|
|
|
239
240
|
date.writeUIntBE(now(), Number(), datePrecisionLength);
|
|
240
241
|
|
|
242
|
+
// Add message
|
|
241
243
|
if (!!args.message) {
|
|
242
|
-
messages.push({type: dateType, value: date.toString('hex')});
|
|
243
|
-
|
|
244
244
|
messages.push({
|
|
245
245
|
type: messageType,
|
|
246
246
|
value: Buffer.from(args.message).toString('hex'),
|
|
247
247
|
});
|
|
248
|
+
}
|
|
248
249
|
|
|
250
|
+
// Add message from fields
|
|
251
|
+
if (!!args.message && !args.is_omitting_message_from) {
|
|
252
|
+
messages.push({type: dateType, value: date.toString('hex')});
|
|
249
253
|
messages.push({type: fromKeyType, value: getIdentity.public_key});
|
|
250
254
|
|
|
251
255
|
const preimage = Buffer.concat([
|
package/network/push_payment.js
CHANGED
|
@@ -39,6 +39,7 @@ const utf8AsHex = n => Buffer.from(n, 'utf8').toString('hex');
|
|
|
39
39
|
}
|
|
40
40
|
[in_through]: <Pay In Through Peer String>
|
|
41
41
|
[is_dry_run]: <Do Not Push Payment Bool>
|
|
42
|
+
[is_omitting_message_from]: <Do Not Include From Key In Message Bool>
|
|
42
43
|
lnd: <Authenticated LND API Object>
|
|
43
44
|
logger: <Winston Logger Object>
|
|
44
45
|
max_fee: <Maximum Fee Tokens Number>
|
|
@@ -74,6 +75,10 @@ module.exports = (args, cbk) => {
|
|
|
74
75
|
return cbk([400, 'MultipleInboundPeersNotSupported']);
|
|
75
76
|
}
|
|
76
77
|
|
|
78
|
+
if (!!args.is_omitting_message_from && !args.message) {
|
|
79
|
+
return cbk([400, 'ExpectedMessageToSendWhenSpecifyingOmitFromKey']);
|
|
80
|
+
}
|
|
81
|
+
|
|
77
82
|
if (!args.lnd) {
|
|
78
83
|
return cbk([400, 'ExpectedAuthenticatedLndToPushPayment']);
|
|
79
84
|
}
|
|
@@ -365,6 +370,7 @@ module.exports = (args, cbk) => {
|
|
|
365
370
|
lnd: args.lnd,
|
|
366
371
|
logger: args.logger,
|
|
367
372
|
in_through: getInKey,
|
|
373
|
+
is_omitting_message_from: args.is_omitting_message_from,
|
|
368
374
|
is_push: true,
|
|
369
375
|
is_real_payment: true,
|
|
370
376
|
max_fee: args.max_fee,
|