mirror of
https://github.com/alexbosworth/balanceofsatoshis.git
synced 2026-08-13 12:33:37 +02:00
switch to probing subscription, fix swap recovery
This commit is contained in:
parent
e62a39bd90
commit
46f77e64d7
15 changed files with 405 additions and 161 deletions
|
|
@ -1,5 +1,10 @@
|
|||
# Versions
|
||||
|
||||
## Version 5.41.4
|
||||
|
||||
- `increase-inbound-liquidity`: Fix `--recovery` option
|
||||
- `probe`: Rework `--find-max` methodology
|
||||
|
||||
## Version 5.41.3
|
||||
|
||||
- `increase-inbound-liquidity`: Support longer swap timeouts
|
||||
|
|
|
|||
117
display/describe_route.js
Normal file
117
display/describe_route.js
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
const asyncAuto = require('async/auto');
|
||||
const asyncMap = require('async/map');
|
||||
const {getNode} = require('ln-service');
|
||||
const {green} = require('colorette');
|
||||
const {returnResult} = require('asyncjs-util');
|
||||
|
||||
const describeConfidence = require('./describe_confidence');
|
||||
const formatFeeRate = require('./format_fee_rate');
|
||||
|
||||
const effectiveFeeRate = (n, m) => Number(BigInt(1e6) * BigInt(n) / BigInt(m));
|
||||
const flatten = arr => [].concat(...arr);
|
||||
|
||||
/** Describe a route
|
||||
|
||||
{
|
||||
lnd: <Authenticated LND API Object>
|
||||
route: {
|
||||
[confidence]: <Route Confidence Score Out Of One Million Number>
|
||||
fee: <Total Fee Tokens To Pay Number>
|
||||
fee_mtokens: <Total Fee Millitokens To Pay String>
|
||||
hops: [{
|
||||
channel: <Standard Format Channel Id String>
|
||||
channel_capacity: <Channel Capacity Tokens Number>
|
||||
fee: <Fee Number>
|
||||
fee_mtokens: <Fee Millitokens String>
|
||||
forward: <Forward Tokens Number>
|
||||
forward_mtokens: <Forward Millitokens String>
|
||||
public_key: <Public Key Hex String>
|
||||
timeout: <Timeout Block Height Number>
|
||||
}]
|
||||
[messages]: [{
|
||||
type: <Message Type Number String>
|
||||
value: <Message Raw Value Hex Encoded String>
|
||||
}]
|
||||
mtokens: <Total Millitokens To Pay String>
|
||||
[payment]: <Payment Identifier Hex String>
|
||||
safe_fee: <Payment Forwarding Fee Rounded Up Tokens Number>
|
||||
safe_tokens: <Payment Sent Tokens Rounded Up Number>
|
||||
timeout: <Expiration Block Height Number>
|
||||
tokens: <Total Tokens To Pay Number>
|
||||
[total_mtokens]: <Total Millitokens String>
|
||||
}
|
||||
}
|
||||
|
||||
@returns via cbk or Promise
|
||||
{
|
||||
description: [<Hop Description String>]
|
||||
}
|
||||
*/
|
||||
module.exports = ({lnd, route}, cbk) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
return asyncAuto({
|
||||
// Check arguments
|
||||
validate: cbk => {
|
||||
if (!lnd) {
|
||||
return cbk([400, 'ExpectedLndObjectToGenerateRouteDescription']);
|
||||
}
|
||||
|
||||
if (!route) {
|
||||
return cbk([400, 'ExpectedRouteToGenerateRouteDescriptionFor']);
|
||||
}
|
||||
|
||||
return cbk();
|
||||
},
|
||||
|
||||
// Get the node aliases
|
||||
getAliases: ['validate', ({}, cbk) => {
|
||||
return asyncMap(route.hops, (hop, cbk) => {
|
||||
return getNode({
|
||||
lnd,
|
||||
is_omitting_channels: true,
|
||||
public_key: hop.public_key,
|
||||
},
|
||||
(err, res) => {
|
||||
if (!!err) {
|
||||
return cbk(null, {alias: Strig(), id: hop.public_key});
|
||||
}
|
||||
|
||||
return cbk(null, {alias: res.alias, id: hop.public_key});
|
||||
});
|
||||
},
|
||||
cbk);
|
||||
}],
|
||||
|
||||
// Assemble the description
|
||||
description: ['getAliases', ({getAliases}, cbk) => {
|
||||
const {confidence} = route;
|
||||
|
||||
const {description} = describeConfidence({confidence});
|
||||
|
||||
const path = route.hops.map((hop, i, hops) => {
|
||||
const {alias} = getAliases.find(n => n.id === hop.public_key);
|
||||
|
||||
const feeMtokens = !i ? hop.fee_mtokens : hops[i - 1].fee_mtokens;
|
||||
const forwarder = `${alias} ${hop.public_key}`.trim();
|
||||
|
||||
const feeRate = effectiveFeeRate(feeMtokens, hop.forward_mtokens);
|
||||
|
||||
const rate = formatFeeRate({rate: feeRate}).display;
|
||||
|
||||
const forward = `${green(forwarder)}. Hop fee rate ${rate}`;
|
||||
|
||||
if (!i) {
|
||||
return [`${hop.channel} ${description || String()}`, forward];
|
||||
} else if (i === hops.length - [i].length) {
|
||||
return [`${hop.channel}`];
|
||||
} else {
|
||||
return [`${hop.channel}`, forward];
|
||||
}
|
||||
});
|
||||
|
||||
return cbk(null, {description: flatten(path)});
|
||||
}],
|
||||
},
|
||||
returnResult({reject, resolve, of: 'description'}, cbk));
|
||||
});
|
||||
};
|
||||
80
display/describe_routing_failure.js
Normal file
80
display/describe_routing_failure.js
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
const asyncAuto = require('async/auto');
|
||||
const {getNode} = require('ln-service');
|
||||
const {returnResult} = require('asyncjs-util');
|
||||
|
||||
/** Get a description for a routing failure
|
||||
|
||||
{
|
||||
index: <Failure Index Number>
|
||||
lnd: <Authenticated LND API Object>
|
||||
reason: <Failure Reason Code String>
|
||||
route: {
|
||||
hops: [{
|
||||
channel: <Standard Format Channel Id String>
|
||||
public_key: <Public Key Hex String>
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
||||
@returns via cbk or Promise
|
||||
{
|
||||
description: <Failure Description String>
|
||||
}
|
||||
*/
|
||||
module.exports = ({index, lnd, reason, route}, cbk) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
return asyncAuto({
|
||||
// Check arguments
|
||||
validate: cbk => {
|
||||
if (index === undefined) {
|
||||
return cbk([400, 'ExpectedIndexToDescribeRoutingFailure']);
|
||||
}
|
||||
|
||||
if (!lnd) {
|
||||
return cbk([400, 'ExpectedLndApiObjectToDescribeRoutingFailure']);
|
||||
}
|
||||
|
||||
if (!reason) {
|
||||
return cbk([400, 'ExpectedFailureReasonToDescribeRoutingFailure']);
|
||||
}
|
||||
|
||||
if (!route) {
|
||||
return cbk([400, 'ExpectedFailedRouteToDescribeRoutingFailure']);
|
||||
}
|
||||
|
||||
return cbk();
|
||||
},
|
||||
|
||||
// Get node alias
|
||||
getAlias: ['validate', ({}, cbk) => {
|
||||
const source = route.hops[index - [index].length];
|
||||
|
||||
if (!source) {
|
||||
return cbk();
|
||||
}
|
||||
|
||||
return getNode({
|
||||
lnd,
|
||||
is_omitting_channels: true,
|
||||
public_key: source.public_key,
|
||||
},
|
||||
(err, res) => {
|
||||
if (!!err) {
|
||||
return cbk(null, source.public_key);
|
||||
}
|
||||
|
||||
return cbk(null, res.alias || source.public_key);
|
||||
});
|
||||
}],
|
||||
|
||||
// Describe the routing failure
|
||||
description: ['getAlias', ({getAlias}, cbk) => {
|
||||
const at = `at ${route.hops[index].channel}`;
|
||||
const from = !getAlias ? '' : `from ${getAlias}`;
|
||||
|
||||
return cbk(null, {description: `${reason} ${at} ${from}`});
|
||||
}],
|
||||
},
|
||||
returnResult({reject, resolve, of: 'description'}, cbk));
|
||||
});
|
||||
};
|
||||
|
|
@ -1,6 +1,17 @@
|
|||
const describeConfidence = require('./describe_confidence');
|
||||
const describeRoute = require('./describe_route');
|
||||
const describeRoutingFailure = require('./describe_routing_failure');
|
||||
const formatFeeRate = require('./format_fee_rate');
|
||||
const formatTokens = require('./format_tokens');
|
||||
const segmentMeasure = require('./segment_measure');
|
||||
const sumsForSegment = require('./sums_for_segment');
|
||||
|
||||
module.exports = {formatFeeRate, formatTokens, segmentMeasure, sumsForSegment};
|
||||
module.exports = {
|
||||
describeConfidence,
|
||||
describeRoute,
|
||||
describeRoutingFailure,
|
||||
formatFeeRate,
|
||||
formatTokens,
|
||||
segmentMeasure,
|
||||
sumsForSegment,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ const {returnResult} = require('asyncjs-util');
|
|||
const {subscribeToProbe} = require('ln-service');
|
||||
const {subscribeToProbeForRoute} = require('ln-service');
|
||||
|
||||
const {describeConfidence} = require('./../routing');
|
||||
const {describeConfidence} = require('./../display');
|
||||
|
||||
const {now} = Date;
|
||||
const minutesAsMs = minutes => 1000 * 60 * minutes;
|
||||
|
|
|
|||
176
network/probe.js
176
network/probe.js
|
|
@ -2,16 +2,23 @@ const asyncAuto = require('async/auto');
|
|||
const asyncMap = require('async/map');
|
||||
const asyncWhilst = require('async/whilst');
|
||||
const {getChannel} = require('ln-service');
|
||||
const {getNode} = require('ln-service');
|
||||
const {getWalletInfo} = require('ln-service');
|
||||
const {getWalletVersion} = require('ln-service');
|
||||
const {parsePaymentRequest} = require('ln-service');
|
||||
const {payViaRoutes} = require('ln-service');
|
||||
const {returnResult} = require('asyncjs-util');
|
||||
const {subscribeToMultiPathProbe} = require('probing');
|
||||
|
||||
const {describeRoute} = require('./../display');
|
||||
const {describeRoutingFailure} = require('./../display');
|
||||
const multiPathProbe = require('./multi_path_probe');
|
||||
const probeDestination = require('./probe_destination');
|
||||
|
||||
const defaultFinalCltvDelta = 144;
|
||||
const defaultMaxPaths = 5;
|
||||
const flatten = arr => [].concat(...arr);
|
||||
const pathTimeoutMs = 1000 * 60 * 5;
|
||||
const uniq = arr => Array.from(new Set(arr));
|
||||
|
||||
/** Probe a destination, looking for multiple non-overlapping paths
|
||||
|
|
@ -53,6 +60,14 @@ module.exports = (args, cbk) => {
|
|||
return cbk([400, 'ExpectedLoggerObjectToStartProbe']);
|
||||
}
|
||||
|
||||
if (!!args.request) {
|
||||
try {
|
||||
parsePaymentRequest({request: args.request});
|
||||
} catch (err) {
|
||||
return cbk([400, 'ExpectedValidPaymentRequestToProbe', {err}]);
|
||||
}
|
||||
}
|
||||
|
||||
return cbk();
|
||||
},
|
||||
|
||||
|
|
@ -72,86 +87,107 @@ module.exports = (args, cbk) => {
|
|||
});
|
||||
}],
|
||||
|
||||
// Probe iteratively through multiple paths
|
||||
multiProbe: ['checkLegacy', ({}, cbk) => {
|
||||
// Decode payment request
|
||||
decodeRequest: ['validate', ({}, cbk) => {
|
||||
// Exit early and only single probe when not finding maximum
|
||||
if (!args.find_max) {
|
||||
return cbk();
|
||||
}
|
||||
|
||||
let error;
|
||||
const probes = [];
|
||||
if (!args.request) {
|
||||
return cbk(null, {});
|
||||
}
|
||||
|
||||
return asyncWhilst(
|
||||
cbk => {
|
||||
if ((args.max_paths || defaultMaxPaths) === probes.length) {
|
||||
return cbk(null, false);
|
||||
}
|
||||
const decoded = parsePaymentRequest({request: args.request});
|
||||
|
||||
return cbk(null, !error);
|
||||
},
|
||||
cbk => {
|
||||
return multiPathProbe({
|
||||
destination: args.destination,
|
||||
find_max: args.find_max,
|
||||
ignore: args.ignore,
|
||||
in_through: args.in_through,
|
||||
lnd: args.lnd,
|
||||
logger: args.logger,
|
||||
out_through: args.out_through,
|
||||
probes: probes.filter(n => !!n),
|
||||
request: args.request,
|
||||
timeout_minutes: args.timeout_minutes,
|
||||
tokens: args.tokens,
|
||||
},
|
||||
(err, res) => {
|
||||
if (!!err) {
|
||||
return cbk(err);
|
||||
}
|
||||
return cbk(null, {
|
||||
cltv_delta: decodeRequest.cltv_delta,
|
||||
destination: decodeRequest.destination,
|
||||
features: decodeRequest.features,
|
||||
routes: decodeRequest.routes,
|
||||
});
|
||||
}],
|
||||
|
||||
if (!!res.error) {
|
||||
error = res.error;
|
||||
} else {
|
||||
probes.push(res.probe || null);
|
||||
}
|
||||
// Get probe destination name
|
||||
getDestination: ['decodeRequest', ({decodeRequest}, cbk) => {
|
||||
const publicKey = decodeRequest.destination || args.destination;
|
||||
|
||||
return cbk();
|
||||
});
|
||||
},
|
||||
err => {
|
||||
if (!!err) {
|
||||
return cbk(err);
|
||||
}
|
||||
|
||||
const completed = probes.filter(n => !!n);
|
||||
|
||||
if (!completed.length) {
|
||||
return cbk(error);
|
||||
}
|
||||
|
||||
const latencyMs = completed
|
||||
.map(n => n.latency_ms)
|
||||
.filter(n => !!n)
|
||||
.reduce((sum, n) => sum + n, Number());
|
||||
|
||||
const max = completed
|
||||
.map(n => n.route_maximum || Number())
|
||||
.reduce((sum, n) => sum + n, Number());
|
||||
|
||||
return cbk(null, {
|
||||
latency_ms: latencyMs,
|
||||
probes: completed.map(probe => {
|
||||
return {
|
||||
channels: probe.success,
|
||||
fee: probe.fee,
|
||||
liquidity: probe.route_maximum,
|
||||
relays: probe.relays,
|
||||
};
|
||||
}),
|
||||
routes_max: max,
|
||||
});
|
||||
return getNode({
|
||||
is_omitting_channels: true,
|
||||
lnd: args.lnd,
|
||||
public_key: publicKey,
|
||||
},
|
||||
(err, res) => {
|
||||
if (!!err) {
|
||||
return cbk(null, publicKey);
|
||||
}
|
||||
);
|
||||
|
||||
return cbk(null, `${res.alias} ${publicKey}`.trim());
|
||||
});
|
||||
}],
|
||||
|
||||
// Probe iteratively through multiple paths
|
||||
multiProbe: [
|
||||
'checkLegacy',
|
||||
'decodeRequest',
|
||||
'getDestination',
|
||||
({decodeRequest, getDestination}, cbk) =>
|
||||
{
|
||||
// Exit early and only single probe when not finding maximum
|
||||
if (!args.find_max) {
|
||||
return cbk();
|
||||
}
|
||||
|
||||
if (!!args.out_through) {
|
||||
return cbk([501, 'FindMaxThroughOutPeerNotSupported']);
|
||||
}
|
||||
|
||||
args.logger.info({probing: getDestination});
|
||||
|
||||
const sub = subscribeToMultiPathProbe({
|
||||
cltv_delta: decodeRequest.cltv_delta || defaultFinalCltvDelta,
|
||||
destination: decodeRequest.destination || args.destination,
|
||||
features: decodeRequest.features,
|
||||
ignore: args.ignore,
|
||||
incoming_peer: args.in_through,
|
||||
lnd: args.lnd,
|
||||
max_paths: args.max_paths,
|
||||
path_timeout_ms: pathTimeoutMs,
|
||||
routes: decodeRequest.routes,
|
||||
});
|
||||
|
||||
sub.on('error', err => cbk(err));
|
||||
|
||||
sub.on('evaluating', ({tokens}) => {
|
||||
return args.logger.info({evaluating: tokens});
|
||||
});
|
||||
|
||||
sub.on('failure', () => {
|
||||
return cbk([503, 'FailedToFindAnyPathsToDestination']);
|
||||
});
|
||||
|
||||
sub.on('probing', async ({route}) => {
|
||||
const {description} = await describeRoute({route, lnd: args.lnd});
|
||||
|
||||
return args.logger.info({probing: description});
|
||||
});
|
||||
|
||||
sub.on('routing_failure', async failure => {
|
||||
const {description} = await describeRoutingFailure({
|
||||
index: failure.index,
|
||||
lnd: args.lnd,
|
||||
reason: failure.reason,
|
||||
route: failure.route,
|
||||
});
|
||||
|
||||
return args.logger.info({failure: description});
|
||||
});
|
||||
|
||||
sub.on('success', ({paths}) => {
|
||||
return args.logger.info({paths});
|
||||
});
|
||||
|
||||
return;
|
||||
}],
|
||||
|
||||
// Probe just through a single path
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ const {returnResult} = require('asyncjs-util');
|
|||
const {signBytes} = require('ln-service');
|
||||
const {subscribeToFindMaxPayable} = require('probing');
|
||||
|
||||
const {authenticatedLnd} = require('./../lnd');
|
||||
const executeProbe = require('./execute_probe');
|
||||
const {getInboundPath} = require('./../routing');
|
||||
const {sortBy} = require('./../arrays');
|
||||
|
|
|
|||
148
package-lock.json
generated
148
package-lock.json
generated
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "balanceofsatoshis",
|
||||
"version": "5.41.3",
|
||||
"version": "5.41.4",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
|
@ -1930,9 +1930,9 @@
|
|||
"integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
|
||||
},
|
||||
"asciichart": {
|
||||
"version": "1.5.23",
|
||||
"resolved": "https://registry.npmjs.org/asciichart/-/asciichart-1.5.23.tgz",
|
||||
"integrity": "sha512-osTjxKgD3NrnzGNP1ePWTssJQxCir4r2D8Xkg9IaRBuePWOK2hHodWxJ5SejW0VKD92Cf5IKglJ0N4WWgBOEcg=="
|
||||
"version": "1.5.24",
|
||||
"resolved": "https://registry.npmjs.org/asciichart/-/asciichart-1.5.24.tgz",
|
||||
"integrity": "sha512-ZvIF1uIvSsRnIygcjq9NnMUoZKGONF9bowhmHr7N/qkR34lkvEDWc/HEzmYp4osVC4/dkGEAHEAiqB2uJs+a+w=="
|
||||
},
|
||||
"ascli": {
|
||||
"version": "1.0.1",
|
||||
|
|
@ -3310,18 +3310,18 @@
|
|||
"dev": true
|
||||
},
|
||||
"flow-parser": {
|
||||
"version": "0.129.0",
|
||||
"resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.129.0.tgz",
|
||||
"integrity": "sha512-kzxyoEl8vG0JF0/h/u0UjALXmsGvwU2NBfKczCSNO/It2fKb8hz1gMt05OuZAlMLYXcvgjntWJadIABeKGPK4g==",
|
||||
"version": "0.130.0",
|
||||
"resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.130.0.tgz",
|
||||
"integrity": "sha512-h9NATB7QsKhj2ucgEH2XzB7p+5ubk8IZX5u/qHkN+oyQoECi1diq6mYfIuYBOyL35f3AhJf/YDkBYQBTqqYK+w==",
|
||||
"dev": true
|
||||
},
|
||||
"flow-remove-types": {
|
||||
"version": "2.129.0",
|
||||
"resolved": "https://registry.npmjs.org/flow-remove-types/-/flow-remove-types-2.129.0.tgz",
|
||||
"integrity": "sha512-ucESHZUDQvEFzjRKstZMFBVIciRvXtKpVyPsJT+poIyOIxuPoCLiU/8HHnMBN9XHDWSJ2YJ91mv97n17NmI1Bg==",
|
||||
"version": "2.130.0",
|
||||
"resolved": "https://registry.npmjs.org/flow-remove-types/-/flow-remove-types-2.130.0.tgz",
|
||||
"integrity": "sha512-x48wARPzBge8aRd0ZI3lQi59afHwVk7DymUIFf423bUfa3u1GJWOfpdHggPkN1f4R16oUH+YO4KldBz8Ce2ldg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"flow-parser": "^0.129.0",
|
||||
"flow-parser": "^0.130.0",
|
||||
"pirates": "^3.0.2",
|
||||
"vlq": "^0.2.1"
|
||||
}
|
||||
|
|
@ -3504,6 +3504,28 @@
|
|||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.2.tgz",
|
||||
"integrity": "sha512-40rZaf3bUNKTVYu9sIeeEGOg7g14Yvnj9kH7b50EiwX0Q7A6umbvfI5tvHaOERH0XigqKkfLkFQxzb4e6CIXnA=="
|
||||
},
|
||||
"ln-service": {
|
||||
"version": "49.4.0",
|
||||
"resolved": "https://registry.npmjs.org/ln-service/-/ln-service-49.4.0.tgz",
|
||||
"integrity": "sha512-juevEKbdDBZOFq5MtmsUULecy8AUTogEGisoWDm4H0mtoaz8uS3TtJUsZR88g+KKfvgD++OpwMMngV3VRW7kvQ==",
|
||||
"requires": {
|
||||
"@datastructures-js/priority-queue": "4.1.1",
|
||||
"async": "3.2.0",
|
||||
"asyncjs-util": "1.2.3",
|
||||
"bitcoinjs-lib": "5.1.10",
|
||||
"bn.js": "5.1.2",
|
||||
"bolt07": "1.5.2",
|
||||
"bolt09": "0.1.1",
|
||||
"cors": "2.8.5",
|
||||
"express": "4.17.1",
|
||||
"invoices": "1.1.1",
|
||||
"is-base64": "1.1.0",
|
||||
"lightning": "2.0.29",
|
||||
"macaroon": "3.0.4",
|
||||
"morgan": "1.10.0",
|
||||
"ws": "7.3.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -3764,9 +3786,9 @@
|
|||
"integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw=="
|
||||
},
|
||||
"inquirer": {
|
||||
"version": "7.3.2",
|
||||
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.2.tgz",
|
||||
"integrity": "sha512-DF4osh1FM6l0RJc5YWYhSDB6TawiBRlbV9Cox8MWlidU218Tb7fm3lQTULyUJDfJ0tjbzl0W4q651mrCCEM55w==",
|
||||
"version": "7.3.3",
|
||||
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz",
|
||||
"integrity": "sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==",
|
||||
"requires": {
|
||||
"ansi-escapes": "^4.2.1",
|
||||
"chalk": "^4.1.0",
|
||||
|
|
@ -3774,7 +3796,7 @@
|
|||
"cli-width": "^3.0.0",
|
||||
"external-editor": "^3.0.3",
|
||||
"figures": "^3.0.0",
|
||||
"lodash": "^4.17.16",
|
||||
"lodash": "^4.17.19",
|
||||
"mute-stream": "0.0.8",
|
||||
"run-async": "^2.4.0",
|
||||
"rxjs": "^6.6.0",
|
||||
|
|
@ -4623,9 +4645,9 @@
|
|||
}
|
||||
},
|
||||
"ln-service": {
|
||||
"version": "49.4.0",
|
||||
"resolved": "https://registry.npmjs.org/ln-service/-/ln-service-49.4.0.tgz",
|
||||
"integrity": "sha512-juevEKbdDBZOFq5MtmsUULecy8AUTogEGisoWDm4H0mtoaz8uS3TtJUsZR88g+KKfvgD++OpwMMngV3VRW7kvQ==",
|
||||
"version": "49.4.1",
|
||||
"resolved": "https://registry.npmjs.org/ln-service/-/ln-service-49.4.1.tgz",
|
||||
"integrity": "sha512-u3Ej2xVQGkkH98XfVmk8utjJVtpuZ0QtpZMFey8XwQqdopFpBjpgRGeSrGSrx52TxblCTEUznhB4Ou9+8bRtPg==",
|
||||
"requires": {
|
||||
"@datastructures-js/priority-queue": "4.1.1",
|
||||
"async": "3.2.0",
|
||||
|
|
@ -4638,7 +4660,7 @@
|
|||
"express": "4.17.1",
|
||||
"invoices": "1.1.1",
|
||||
"is-base64": "1.1.0",
|
||||
"lightning": "2.0.29",
|
||||
"lightning": "2.0.30",
|
||||
"macaroon": "3.0.4",
|
||||
"morgan": "1.10.0",
|
||||
"ws": "7.3.1"
|
||||
|
|
@ -4648,6 +4670,25 @@
|
|||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.2.tgz",
|
||||
"integrity": "sha512-40rZaf3bUNKTVYu9sIeeEGOg7g14Yvnj9kH7b50EiwX0Q7A6umbvfI5tvHaOERH0XigqKkfLkFQxzb4e6CIXnA=="
|
||||
},
|
||||
"lightning": {
|
||||
"version": "2.0.30",
|
||||
"resolved": "https://registry.npmjs.org/lightning/-/lightning-2.0.30.tgz",
|
||||
"integrity": "sha512-XZFefXdOE4kPa/C533MwnTpgfidwM6M9s0Mtg7U0jmDA5dRB9VmMU8zssBAeo+cZ46fXEx7fz4lXLGQ6V7opUw==",
|
||||
"requires": {
|
||||
"@grpc/proto-loader": "0.5.5",
|
||||
"async": "3.2.0",
|
||||
"asyncjs-util": "1.2.3",
|
||||
"bitcoinjs-lib": "5.1.10",
|
||||
"bn.js": "5.1.2",
|
||||
"body-parser": "1.19.0",
|
||||
"bolt07": "1.5.2",
|
||||
"bolt09": "0.1.1",
|
||||
"cbor": "5.0.2",
|
||||
"express": "4.17.1",
|
||||
"grpc": "1.24.3",
|
||||
"invoices": "1.1.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -5798,62 +5839,15 @@
|
|||
}
|
||||
},
|
||||
"probing": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/probing/-/probing-1.0.1.tgz",
|
||||
"integrity": "sha512-llIRWvdX7I3PLDXDrUjYCSwYFuMKqHX3qFYA58qba8CRJt9FRfucPcpI84MdVS9NzpehRibKAvDm89+xzhfBLg==",
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/probing/-/probing-1.1.0.tgz",
|
||||
"integrity": "sha512-TPks2aMOIkB1o2OOOISkQLlQjqYDWj7X9A5f2Fh1gFJxu2NOUpRXyJImd54EkuewQ+sEWFSUryE7q2iorpjC3w==",
|
||||
"requires": {
|
||||
"async": "3.2.0",
|
||||
"asyncjs-util": "1.2.3",
|
||||
"bolt07": "1.5.2",
|
||||
"invoices": "1.1.1",
|
||||
"ln-service": "49.3.7"
|
||||
},
|
||||
"dependencies": {
|
||||
"bn.js": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.2.tgz",
|
||||
"integrity": "sha512-40rZaf3bUNKTVYu9sIeeEGOg7g14Yvnj9kH7b50EiwX0Q7A6umbvfI5tvHaOERH0XigqKkfLkFQxzb4e6CIXnA=="
|
||||
},
|
||||
"lightning": {
|
||||
"version": "2.0.28",
|
||||
"resolved": "https://registry.npmjs.org/lightning/-/lightning-2.0.28.tgz",
|
||||
"integrity": "sha512-nx3HPpJncS/c8BnvCwX8jEbePFzrj+gVk47VZtuYYWKTrZPn2PHqTOBnCVbHM9rkjeJjJuT3074n4pmSWpTAcw==",
|
||||
"requires": {
|
||||
"@grpc/proto-loader": "0.5.5",
|
||||
"async": "3.2.0",
|
||||
"asyncjs-util": "1.2.3",
|
||||
"bitcoinjs-lib": "5.1.10",
|
||||
"bn.js": "5.1.2",
|
||||
"body-parser": "1.19.0",
|
||||
"bolt07": "1.5.2",
|
||||
"bolt09": "0.1.1",
|
||||
"cbor": "5.0.2",
|
||||
"express": "4.17.1",
|
||||
"grpc": "1.24.3",
|
||||
"invoices": "1.1.1"
|
||||
}
|
||||
},
|
||||
"ln-service": {
|
||||
"version": "49.3.7",
|
||||
"resolved": "https://registry.npmjs.org/ln-service/-/ln-service-49.3.7.tgz",
|
||||
"integrity": "sha512-UPWF9oJowvU6GQLkXQTM7c7Og3N1BipK+Brd4vImqXONHZTE9514UKawqpi+JU8FwNlzB75A3PgqFFbiTZriUQ==",
|
||||
"requires": {
|
||||
"@datastructures-js/priority-queue": "4.1.1",
|
||||
"async": "3.2.0",
|
||||
"asyncjs-util": "1.2.3",
|
||||
"bitcoinjs-lib": "5.1.10",
|
||||
"bn.js": "5.1.2",
|
||||
"bolt07": "1.5.2",
|
||||
"bolt09": "0.1.1",
|
||||
"cors": "2.8.5",
|
||||
"express": "4.17.1",
|
||||
"invoices": "1.1.1",
|
||||
"is-base64": "1.1.0",
|
||||
"lightning": "2.0.28",
|
||||
"macaroon": "3.0.4",
|
||||
"morgan": "1.10.0",
|
||||
"ws": "7.3.1"
|
||||
}
|
||||
}
|
||||
"ln-service": "49.4.1"
|
||||
}
|
||||
},
|
||||
"process-nextick-args": {
|
||||
|
|
@ -5893,9 +5887,9 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@types/node": {
|
||||
"version": "13.13.14",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.14.tgz",
|
||||
"integrity": "sha512-Az3QsOt1U/K1pbCQ0TXGELTuTkPLOiFIQf3ILzbOyo0FqgV9SxRnxbxM5QlAveERZMHpZY+7u3Jz2tKyl+yg6g=="
|
||||
"version": "13.13.15",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.15.tgz",
|
||||
"integrity": "sha512-kwbcs0jySLxzLsa2nWUAGOd/s21WU1jebrEdtzhsj1D4Yps1EOuyI1Qcu+FD56dL7NRNIJtDDjcqIG22NwkgLw=="
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -6750,9 +6744,9 @@
|
|||
}
|
||||
},
|
||||
"tap-parser": {
|
||||
"version": "10.0.1",
|
||||
"resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-10.0.1.tgz",
|
||||
"integrity": "sha512-qdT15H0DoJIi7zOqVXDn9X0gSM68JjNy1w3VemwTJlDnETjbi6SutnqmBfjDJAwkFS79NJ97gZKqie00ZCGmzg==",
|
||||
"version": "10.1.0",
|
||||
"resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-10.1.0.tgz",
|
||||
"integrity": "sha512-FujQeciDaOiOvaIVGS1Rpb0v4R6XkOjvWCWowlz5oKuhPkEJ8U6pxgqt38xuzYhPt8dWEnfHn2jqpZdJEkW7pA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"events-to-array": "^1.0.1",
|
||||
|
|
|
|||
12
package.json
12
package.json
|
|
@ -12,7 +12,7 @@
|
|||
"dependencies": {
|
||||
"@alexbosworth/html2unicode": "1.1.5",
|
||||
"@alexbosworth/request": "2.88.3",
|
||||
"asciichart": "1.5.23",
|
||||
"asciichart": "1.5.24",
|
||||
"async": "3.2.0",
|
||||
"asyncjs-util": "1.2.3",
|
||||
"bitcoin-ops": "1.4.1",
|
||||
|
|
@ -27,12 +27,12 @@
|
|||
"csv-parse": "4.11.1",
|
||||
"goldengate": "6.0.0",
|
||||
"ini": "1.3.5",
|
||||
"inquirer": "7.3.2",
|
||||
"inquirer": "7.3.3",
|
||||
"ln-accounting": "4.1.7",
|
||||
"ln-service": "49.4.0",
|
||||
"ln-service": "49.4.1",
|
||||
"ln-sync": "0.0.9",
|
||||
"moment": "2.27.0",
|
||||
"probing": "1.0.1",
|
||||
"probing": "1.1.0",
|
||||
"psbt": "1.1.4",
|
||||
"qrcode-terminal": "0.12.0",
|
||||
"sanitize-filename": "1.6.3",
|
||||
|
|
@ -65,7 +65,7 @@
|
|||
"url": "https://github.com/alexbosworth/balanceofsatoshis.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "tap test/arrays/*.js test/balances/*.js test/chain/*.js test/encryption/*.js test/fiat/*.js test/lnd/*.js test/network/*.js test/nodes/*.js test/responses/*.js test/routing/*.js test/swaps/*.js test/telegram/*.js test/wallets/*.js"
|
||||
"test": "tap test/arrays/*.js test/balances/*.js test/chain/*.js test/display/*.js test/encryption/*.js test/fiat/*.js test/lnd/*.js test/network/*.js test/nodes/*.js test/responses/*.js test/routing/*.js test/swaps/*.js test/telegram/*.js test/wallets/*.js"
|
||||
},
|
||||
"version": "5.41.3"
|
||||
"version": "5.41.4"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,6 +70,10 @@ module.exports = ({channels, lnd, query}, cbk) => {
|
|||
return cbk();
|
||||
}
|
||||
|
||||
if (!query.toLowerCase) {
|
||||
return cbk([400, 'InvalidEmptyQuerySpecifiedForMatchSearchQuery']);
|
||||
}
|
||||
|
||||
const keys = uniq(getChannels.channels.map(n => n.partner_public_key));
|
||||
const q = query.toLowerCase();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
const adjustFees = require('./adjust_fees');
|
||||
const channelForGift = require('./channel_for_gift');
|
||||
const channelsFromHints = require('./channels_from_hints');
|
||||
const describeConfidence = require('./describe_confidence');
|
||||
const getFeesChart = require('./get_fees_chart');
|
||||
const getFeesPaid = require('./get_fees_paid');
|
||||
const getInboundPath = require('./get_inbound_path');
|
||||
|
|
@ -13,7 +12,6 @@ module.exports = {
|
|||
adjustFees,
|
||||
channelForGift,
|
||||
channelsFromHints,
|
||||
describeConfidence,
|
||||
getFeesChart,
|
||||
getFeesPaid,
|
||||
getInboundPath,
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ module.exports = (args, cbk) => {
|
|||
const rate = getUpdated.policies.find(n => n.public_key === args.from);
|
||||
|
||||
if (rate.fee_rate !== args.fee_rate) {
|
||||
return cbk([503, 'FailedToUpdateChannelPolicyToNewFeeRate']);
|
||||
return cbk([503, 'FailedToUpdateChannelPolicyToNewFeeRate', {rate}]);
|
||||
}
|
||||
|
||||
return cbk();
|
||||
|
|
|
|||
|
|
@ -397,7 +397,7 @@ module.exports = (args, cbk) => {
|
|||
({getLimits, startHeight}, cbk) =>
|
||||
{
|
||||
// Exit early when the swap is already started
|
||||
if (!!args.recover) {
|
||||
if (!!args.recovery) {
|
||||
return cbk();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
const {test} = require('@alexbosworth/tap');
|
||||
|
||||
const {describeConfidence} = require('./../../routing');
|
||||
const {describeConfidence} = require('./../../display');
|
||||
|
||||
const tests = [
|
||||
{
|
||||
Loading…
Add table
Add a link
Reference in a new issue