lightning 10.22.3 → 10.23.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 +4 -0
- package/README.md +2 -0
- package/index.js +2 -0
- package/lnd_methods/index.js +2 -0
- package/lnd_methods/macaroon/methods.json +4 -0
- package/lnd_methods/offchain/get_routing_fee_estimate.d.ts +32 -0
- package/lnd_methods/offchain/get_routing_fee_estimate.js +86 -0
- package/lnd_methods/offchain/index.d.ts +1 -0
- package/lnd_methods/offchain/index.js +2 -0
- package/package.json +3 -3
- package/test/lnd_methods/offchain/test_get_routing_fee_estimate.js +82 -0
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -234,6 +234,8 @@ variables set:
|
|
|
234
234
|
Calculate a route through specified nodes.
|
|
235
235
|
- [getRouteToDestination](https://github.com/alexbosworth/ln-service#getroutetodestination):
|
|
236
236
|
Calculate a route through the graph to a destination.
|
|
237
|
+
- [getRoutingFeeEstimate](https://github.com/alexbosworth/ln-service#getroutingfeeestimate):
|
|
238
|
+
Make a test payment to find a working routing fee for a payment request
|
|
237
239
|
- [getSettlementStatus](https://github.com/alexbosworth/ln-service#getsettlementstatus):
|
|
238
240
|
Lookup the status of a received payment output
|
|
239
241
|
- [getSweepTransactions](https://github.com/alexbosworth/ln-service#getsweeptransactions): List
|
package/index.js
CHANGED
|
@@ -78,6 +78,7 @@ const {getPublicKey} = require('./lnd_methods');
|
|
|
78
78
|
const {getRouteConfidence} = require('./lnd_methods');
|
|
79
79
|
const {getRouteThroughHops} = require('./lnd_methods');
|
|
80
80
|
const {getRouteToDestination} = require('./lnd_methods');
|
|
81
|
+
const {getRoutingFeeEstimate} = require('./lnd_methods');
|
|
81
82
|
const {getSettlementStatus} = require('./lnd_methods');
|
|
82
83
|
const {getSweepTransactions} = require('./lnd_methods');
|
|
83
84
|
const {getTowerServerInfo} = require('./lnd_methods');
|
|
@@ -239,6 +240,7 @@ module.exports = {
|
|
|
239
240
|
getRouteConfidence,
|
|
240
241
|
getRouteThroughHops,
|
|
241
242
|
getRouteToDestination,
|
|
243
|
+
getRoutingFeeEstimate,
|
|
242
244
|
getSettlementStatus,
|
|
243
245
|
getSweepTransactions,
|
|
244
246
|
getTowerServerInfo,
|
package/lnd_methods/index.js
CHANGED
|
@@ -77,6 +77,7 @@ const {getPublicKey} = require('./address');
|
|
|
77
77
|
const {getRouteConfidence} = require('./generic');
|
|
78
78
|
const {getRouteThroughHops} = require('./offchain');
|
|
79
79
|
const {getRouteToDestination} = require('./info');
|
|
80
|
+
const {getRoutingFeeEstimate} = require('./offchain');
|
|
80
81
|
const {getSettlementStatus} = require('./offchain');
|
|
81
82
|
const {getSweepTransactions} = require('./onchain');
|
|
82
83
|
const {getTowerServerInfo} = require('./info');
|
|
@@ -237,6 +238,7 @@ module.exports = {
|
|
|
237
238
|
getRouteConfidence,
|
|
238
239
|
getRouteThroughHops,
|
|
239
240
|
getRouteToDestination,
|
|
241
|
+
getRoutingFeeEstimate,
|
|
240
242
|
getSettlementStatus,
|
|
241
243
|
getSweepTransactions,
|
|
242
244
|
getTowerServerInfo,
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import {AuthenticatedLnd} from '../../lnd_grpc';
|
|
2
|
+
import {
|
|
3
|
+
AuthenticatedLightningArgs,
|
|
4
|
+
AuthenticatedLightningMethod
|
|
5
|
+
} from '../../typescript';
|
|
6
|
+
|
|
7
|
+
export type GetRoutingFeeEstimateRequest = AuthenticatedLightningArgs<{
|
|
8
|
+
lnd: AuthenticatedLnd;
|
|
9
|
+
/** BOLT 11 Encoded Payment Request */
|
|
10
|
+
request: string;
|
|
11
|
+
/** Optional Timeout in Milliseconds */
|
|
12
|
+
timeout?: number;
|
|
13
|
+
}>;
|
|
14
|
+
|
|
15
|
+
export type GetRoutingFeeEstimateResponse = {
|
|
16
|
+
/** (Minimum Routing Fee Millitokens) */
|
|
17
|
+
fee_mtokens: string;
|
|
18
|
+
/** Timeout (Time Lock Delay) */
|
|
19
|
+
timeout: number;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Estimate routing fees based on an invoice.
|
|
24
|
+
*
|
|
25
|
+
* Requires `offchain:read` permission
|
|
26
|
+
*
|
|
27
|
+
* This method is not supported before LND 0.18.4
|
|
28
|
+
*/
|
|
29
|
+
export const getRoutingFeeEstimate: AuthenticatedLightningMethod<
|
|
30
|
+
GetRoutingFeeEstimateRequest,
|
|
31
|
+
GetRoutingFeeEstimateResponse
|
|
32
|
+
>;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
const asyncAuto = require('async/auto');
|
|
2
|
+
const {returnResult} = require('asyncjs-util');
|
|
3
|
+
|
|
4
|
+
const {isLnd} = require('./../../lnd_requests');
|
|
5
|
+
|
|
6
|
+
const defaultTimeoutSeconds = 60;
|
|
7
|
+
const method = 'estimateRouteFee';
|
|
8
|
+
const msAsSecs = ms => Math.round(ms / 1e3);
|
|
9
|
+
const type = 'router';
|
|
10
|
+
|
|
11
|
+
/** Estimate routing fees and timeout required to pay a payment request
|
|
12
|
+
|
|
13
|
+
Requires `offchain:read` permission
|
|
14
|
+
|
|
15
|
+
This method is not supported on LND 0.18.3 and below
|
|
16
|
+
|
|
17
|
+
{
|
|
18
|
+
lnd: <Authenticated LND API Object>
|
|
19
|
+
request: <BOLT 11 Payment Request String>
|
|
20
|
+
[timeout]: <Maximum Route Pathfinding Time in Milliseconds Number>
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
@returns via cbk or Promise
|
|
24
|
+
{
|
|
25
|
+
fee_mtokens: <Estimated Minimum Required Route Fee Millitokens String>
|
|
26
|
+
timeout: <Estimated Minimum Time Lock Block Height Delay Number>
|
|
27
|
+
}
|
|
28
|
+
*/
|
|
29
|
+
module.exports = ({lnd, request, timeout}, cbk) => {
|
|
30
|
+
return new Promise((resolve, reject) => {
|
|
31
|
+
return asyncAuto({
|
|
32
|
+
// Check arguments
|
|
33
|
+
validate: cbk => {
|
|
34
|
+
if (!isLnd({lnd, method, type})) {
|
|
35
|
+
return cbk([400, 'ExpectedAuthenticatedLndToGetRoutingFeeEstimate']);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (!request) {
|
|
39
|
+
return cbk([400, 'ExpectedPaymentRequestToGetRoutingFeeEstimate']);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return cbk();
|
|
43
|
+
},
|
|
44
|
+
|
|
45
|
+
// Request a probe of the request to determine a needed fee and delay
|
|
46
|
+
getEstimate: ['validate', ({}, cbk) => {
|
|
47
|
+
return lnd[type][method]({
|
|
48
|
+
payment_request: request,
|
|
49
|
+
timeout: msAsSecs(timeout) || defaultTimeoutSeconds,
|
|
50
|
+
},
|
|
51
|
+
(err, res) => {
|
|
52
|
+
if (!!err) {
|
|
53
|
+
return cbk([503, 'UnexpectedGetRoutingFeeEstimateError', {err}]);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (!res) {
|
|
57
|
+
return cbk([503, 'ExpectedGetRoutingFeeEstimateResponse']);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (!res.routing_fee_msat) {
|
|
61
|
+
return cbk([503, 'ExpectedFeeInGetRoutingFeeEstimateResponse']);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (!res.time_lock_delay) {
|
|
65
|
+
return cbk([503, 'ExpectedTimeoutInGetRouteFeeEstimateResponse']);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Exit early with error when the estimate response has failure code
|
|
69
|
+
if (res.failure_reason !== 'FAILURE_REASON_NONE') {
|
|
70
|
+
return cbk([
|
|
71
|
+
404,
|
|
72
|
+
'RouteToDestinationNotFound',
|
|
73
|
+
{failure: res.failure_reason},
|
|
74
|
+
]);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return cbk(null, {
|
|
78
|
+
fee_mtokens: res.routing_fee_msat,
|
|
79
|
+
timeout: Number(res.time_lock_delay),
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
}],
|
|
83
|
+
},
|
|
84
|
+
returnResult({reject, resolve, of: 'getEstimate'}, cbk));
|
|
85
|
+
});
|
|
86
|
+
};
|
|
@@ -27,6 +27,7 @@ export * from './get_payments';
|
|
|
27
27
|
export * from './get_pending_channels';
|
|
28
28
|
export * from './get_pending_payments';
|
|
29
29
|
export * from './get_route_through_hops';
|
|
30
|
+
export * from './get_routing_fee_estimate';
|
|
30
31
|
export * from './get_settlement_status';
|
|
31
32
|
export * from './is_destination_payable';
|
|
32
33
|
export * from './pay_via_payment_details';
|
|
@@ -27,6 +27,7 @@ const getPayments = require('./get_payments');
|
|
|
27
27
|
const getPendingChannels = require('./get_pending_channels');
|
|
28
28
|
const getPendingPayments = require('./get_pending_payments');
|
|
29
29
|
const getRouteThroughHops = require('./get_route_through_hops');
|
|
30
|
+
const getRoutingFeeEstimate = require('./get_routing_fee_estimate');
|
|
30
31
|
const getSettlementStatus = require('./get_settlement_status');
|
|
31
32
|
const isDestinationPayable = require('./is_destination_payable');
|
|
32
33
|
const pay = require('./pay');
|
|
@@ -86,6 +87,7 @@ module.exports = {
|
|
|
86
87
|
getPendingChannels,
|
|
87
88
|
getPendingPayments,
|
|
88
89
|
getRouteThroughHops,
|
|
90
|
+
getRoutingFeeEstimate,
|
|
89
91
|
getSettlementStatus,
|
|
90
92
|
isDestinationPayable,
|
|
91
93
|
pay,
|
package/package.json
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"dependencies": {
|
|
10
10
|
"@grpc/grpc-js": "1.12.5",
|
|
11
11
|
"@grpc/proto-loader": "0.7.13",
|
|
12
|
-
"@types/node": "22.10.
|
|
12
|
+
"@types/node": "22.10.5",
|
|
13
13
|
"@types/request": "2.48.12",
|
|
14
14
|
"@types/ws": "8.5.13",
|
|
15
15
|
"async": "3.2.6",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"invoices": "3.0.0",
|
|
23
23
|
"psbt": "3.0.0",
|
|
24
24
|
"tiny-secp256k1": "2.2.3",
|
|
25
|
-
"type-fest": "4.
|
|
25
|
+
"type-fest": "4.31.0"
|
|
26
26
|
},
|
|
27
27
|
"description": "Lightning Network client library",
|
|
28
28
|
"devDependencies": {
|
|
@@ -53,5 +53,5 @@
|
|
|
53
53
|
"directory": "test/typescript"
|
|
54
54
|
},
|
|
55
55
|
"types": "index.d.ts",
|
|
56
|
-
"version": "10.
|
|
56
|
+
"version": "10.23.0"
|
|
57
57
|
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
const {rejects, deepStrictEqual} = require('node:assert').strict;
|
|
2
|
+
const test = require('node:test');
|
|
3
|
+
const {getRoutingFeeEstimate} = require('../../../');
|
|
4
|
+
|
|
5
|
+
const makeLnd = ({err, res}) => {
|
|
6
|
+
const r = {
|
|
7
|
+
routing_fee_msat: '1',
|
|
8
|
+
time_lock_delay: '1',
|
|
9
|
+
failure_reason: 'FAILURE_REASON_NONE',
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
return {
|
|
13
|
+
router: {
|
|
14
|
+
estimateRouteFee: ({}, cbk) => cbk(err, res !== undefined ? res : r),
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const makeArgs = override => {
|
|
20
|
+
const args = {lnd: makeLnd({}), request: 'request'};
|
|
21
|
+
|
|
22
|
+
Object.keys(override || {}).forEach(key => args[key] = override[key]);
|
|
23
|
+
|
|
24
|
+
return args;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const tests = [
|
|
28
|
+
{
|
|
29
|
+
args: makeArgs({lnd: undefined}),
|
|
30
|
+
description: 'LND is required',
|
|
31
|
+
error: [400, 'ExpectedAuthenticatedLndToGetRoutingFeeEstimate'],
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
args: makeArgs({request: undefined}),
|
|
35
|
+
description: 'Request is required',
|
|
36
|
+
error: [400, 'ExpectedPaymentRequestToGetRoutingFeeEstimate'],
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
args: makeArgs({}),
|
|
40
|
+
description: 'A route fee estimate is returned',
|
|
41
|
+
expected: {fee_mtokens: '1', timeout: 1},
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
args: makeArgs({lnd: makeLnd({err: 'err'})}),
|
|
45
|
+
description: 'An error is not expected',
|
|
46
|
+
error: [503, 'UnexpectedGetRoutingFeeEstimateError', {err: 'err'}],
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
args: makeArgs({lnd: makeLnd({res: null})}),
|
|
50
|
+
description: 'A result is expected',
|
|
51
|
+
error: [503, 'ExpectedGetRoutingFeeEstimateResponse'],
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
args: makeArgs({lnd: makeLnd({res: {}})}),
|
|
55
|
+
description: 'A result fee is expected',
|
|
56
|
+
error: [503, 'ExpectedFeeInGetRoutingFeeEstimateResponse'],
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
args: makeArgs({lnd: makeLnd({res: {routing_fee_msat: '1'}})}),
|
|
60
|
+
description: 'A result timeout is expected',
|
|
61
|
+
error: [503, 'ExpectedTimeoutInGetRouteFeeEstimateResponse'],
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
args: makeArgs({
|
|
65
|
+
lnd: makeLnd({res: {routing_fee_msat: '1', time_lock_delay: '1'}}),
|
|
66
|
+
}),
|
|
67
|
+
description: 'A result non failure code is expected',
|
|
68
|
+
error: [404, 'RouteToDestinationNotFound', {failure: undefined}],
|
|
69
|
+
},
|
|
70
|
+
];
|
|
71
|
+
|
|
72
|
+
tests.forEach(({args, description, error, expected}) => {
|
|
73
|
+
return test(description, async () => {
|
|
74
|
+
if (!!error) {
|
|
75
|
+
await rejects(getRoutingFeeEstimate(args), error, 'Got expected error');
|
|
76
|
+
} else {
|
|
77
|
+
deepStrictEqual(await getRoutingFeeEstimate(args), expected, 'Got res');
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return;
|
|
81
|
+
});
|
|
82
|
+
});
|