ln-service 57.13.3 → 57.14.1
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
CHANGED
package/README.md
CHANGED
|
@@ -1883,14 +1883,23 @@ const balanceInChannels = (await getChannelBalance({lnd})).channel_balance;
|
|
|
1883
1883
|
|
|
1884
1884
|
Get graph information about a channel on the network
|
|
1885
1885
|
|
|
1886
|
+
Either channel `id` or a `transaction_id` and `transaction_vout` is required
|
|
1887
|
+
|
|
1886
1888
|
Requires `info:read` permission
|
|
1887
1889
|
|
|
1888
1890
|
`inbound_base_discount_mtokens` is not supported on LND 0.17.5 and below
|
|
1891
|
+
|
|
1889
1892
|
`inbound_rate_discount` is not supported on LND 0.17.5 and below
|
|
1890
1893
|
|
|
1894
|
+
`transaction_id` is not supported on LND 0.18.0 and below
|
|
1895
|
+
|
|
1896
|
+
`transaction_vout` is not supported on LND 0.18.0 and below
|
|
1897
|
+
|
|
1891
1898
|
{
|
|
1892
|
-
id: <Standard Format Channel Id String>
|
|
1899
|
+
[id]: <Standard Format Channel Id String>
|
|
1893
1900
|
lnd: <Authenticated LND API Object>
|
|
1901
|
+
[transaction_id]: <Funding Outpoint Transaction Id Hex String>
|
|
1902
|
+
[transaction_vout]: <Funding Outpoint Transaction Output Index Number>
|
|
1894
1903
|
}
|
|
1895
1904
|
|
|
1896
1905
|
@returns via cbk or Promise
|
|
@@ -1900,18 +1909,18 @@ Requires `info:read` permission
|
|
|
1900
1909
|
policies: [{
|
|
1901
1910
|
[base_fee_mtokens]: <Base Fee Millitokens String>
|
|
1902
1911
|
[cltv_delta]: <Locktime Delta Number>
|
|
1903
|
-
[fee_rate]: <Fees Charged Per Million
|
|
1912
|
+
[fee_rate]: <Fees Charged in Millitokens Per Million Number>
|
|
1904
1913
|
[inbound_base_discount_mtokens]: <Source Based Base Fee Reduction String>
|
|
1905
1914
|
[inbound_rate_discount]: <Source Based Per Million Rate Reduction Number>
|
|
1906
1915
|
[is_disabled]: <Channel Is Disabled Bool>
|
|
1907
1916
|
[max_htlc_mtokens]: <Maximum HTLC Millitokens Value String>
|
|
1908
1917
|
[min_htlc_mtokens]: <Minimum HTLC Millitokens Value String>
|
|
1909
1918
|
public_key: <Node Public Key String>
|
|
1910
|
-
[updated_at]: <
|
|
1919
|
+
[updated_at]: <Edge Last Updated At ISO 8601 Date String>
|
|
1911
1920
|
}]
|
|
1912
1921
|
transaction_id: <Transaction Id Hex String>
|
|
1913
1922
|
transaction_vout: <Transaction Output Index Number>
|
|
1914
|
-
[updated_at]: <Last
|
|
1923
|
+
[updated_at]: <Channel Last Updated At ISO 8601 Date String>
|
|
1915
1924
|
}
|
|
1916
1925
|
|
|
1917
1926
|
Example:
|
package/package.json
CHANGED
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
"url": "https://github.com/alexbosworth/ln-service/issues"
|
|
8
8
|
},
|
|
9
9
|
"dependencies": {
|
|
10
|
-
"bolt07": "1.9.
|
|
10
|
+
"bolt07": "1.9.3",
|
|
11
11
|
"invoices": "3.0.0",
|
|
12
|
-
"lightning": "10.
|
|
12
|
+
"lightning": "10.14.0",
|
|
13
13
|
"macaroon": "3.0.4"
|
|
14
14
|
},
|
|
15
15
|
"description": "Interaction helper for your Lightning Network daemon",
|
|
@@ -20,18 +20,18 @@
|
|
|
20
20
|
"asyncjs-util": "1.2.12",
|
|
21
21
|
"bip32": "4.0.0",
|
|
22
22
|
"bip66": "1.1.5",
|
|
23
|
-
"bitcoinjs-lib": "6.1.
|
|
23
|
+
"bitcoinjs-lib": "6.1.6",
|
|
24
24
|
"bn.js": "5.2.1",
|
|
25
25
|
"bs58check": "3.0.1",
|
|
26
26
|
"ecpair": "2.1.0",
|
|
27
|
-
"ln-docker-daemons": "6.0.
|
|
27
|
+
"ln-docker-daemons": "6.0.18",
|
|
28
28
|
"p2tr": "2.0.0",
|
|
29
29
|
"portfinder": "1.0.32",
|
|
30
30
|
"psbt": "3.0.0",
|
|
31
31
|
"rimraf": "5.0.7",
|
|
32
32
|
"secp256k1": "5.0.0",
|
|
33
33
|
"tiny-secp256k1": "2.2.3",
|
|
34
|
-
"uuid": "
|
|
34
|
+
"uuid": "10.0.0",
|
|
35
35
|
"varuint-bitcoin": "1.1.2"
|
|
36
36
|
},
|
|
37
37
|
"engines": {
|
|
@@ -72,5 +72,5 @@
|
|
|
72
72
|
"integration-test-0.14.4": "DOCKER_LND_VERSION=v0.14.4-beta npm run test",
|
|
73
73
|
"test": "echo $DOCKER_LND_VERSION && node test/runner"
|
|
74
74
|
},
|
|
75
|
-
"version": "57.
|
|
75
|
+
"version": "57.14.1"
|
|
76
76
|
}
|
|
@@ -43,6 +43,21 @@ test(`Get channel`, async () => {
|
|
|
43
43
|
|
|
44
44
|
strictEqual(Date.now()-new Date(details.updated_at) < 1e5, true, 'Updated');
|
|
45
45
|
|
|
46
|
+
try {
|
|
47
|
+
const details = await getChannel({
|
|
48
|
+
lnd,
|
|
49
|
+
transaction_id: channel.transaction_id,
|
|
50
|
+
transaction_vout: channel.transaction_vout,
|
|
51
|
+
});
|
|
52
|
+
} catch (err) {
|
|
53
|
+
const [code] = err;
|
|
54
|
+
|
|
55
|
+
// On LND 0.18.0 and below a transaction id and vout is not supported
|
|
56
|
+
if (code !== 404) {
|
|
57
|
+
throw err;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
46
61
|
await kill({});
|
|
47
62
|
|
|
48
63
|
return;
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
const {equal} = require('node:assert').strict;
|
|
2
|
+
const test = require('node:test');
|
|
3
|
+
|
|
4
|
+
const asyncRetry = require('async/retry');
|
|
5
|
+
const {setupChannel} = require('ln-docker-daemons');
|
|
6
|
+
const {spawnLightningCluster} = require('ln-docker-daemons');
|
|
7
|
+
|
|
8
|
+
const {addPeer} = require('./../../');
|
|
9
|
+
const {createInvoice} = require('./../../');
|
|
10
|
+
const {decodePaymentRequest} = require('./../../');
|
|
11
|
+
const {getHeight} = require('./../../');
|
|
12
|
+
const {getChannel} = require('./../../');
|
|
13
|
+
const {getRouteThroughHops} = require('./../../');
|
|
14
|
+
const {getRouteToDestination} = require('./../../');
|
|
15
|
+
const {getWalletInfo} = require('./../../');
|
|
16
|
+
const {payViaRoutes} = require('./../../');
|
|
17
|
+
const {routeFromChannels} = require('./../../');
|
|
18
|
+
const {updateRoutingFees} = require('./../../');
|
|
19
|
+
const {waitForRoute} = require('./../macros');
|
|
20
|
+
|
|
21
|
+
const baseFee = '1000';
|
|
22
|
+
const confirmationCount = 6;
|
|
23
|
+
const discount = '1000';
|
|
24
|
+
const interval = 10;
|
|
25
|
+
const size = 3;
|
|
26
|
+
const times = 1000;
|
|
27
|
+
const tokens = 100;
|
|
28
|
+
|
|
29
|
+
// Calculating a route from channels should result in a route
|
|
30
|
+
test(`Get route through hops`, async () => {
|
|
31
|
+
const {kill, nodes} = await spawnLightningCluster({size});
|
|
32
|
+
|
|
33
|
+
const [{generate, lnd}, target, remote] = nodes;
|
|
34
|
+
|
|
35
|
+
const controlToTargetChan = await setupChannel({generate, lnd, to: target});
|
|
36
|
+
|
|
37
|
+
await generate({});
|
|
38
|
+
|
|
39
|
+
const targetRemoteChannel = await asyncRetry({interval, times}, async () => {
|
|
40
|
+
await generate({});
|
|
41
|
+
|
|
42
|
+
await addPeer({
|
|
43
|
+
lnd: target.lnd,
|
|
44
|
+
public_key: remote.id,
|
|
45
|
+
socket: remote.socket,
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
return await setupChannel({
|
|
49
|
+
generate: target.generate,
|
|
50
|
+
lnd: target.lnd,
|
|
51
|
+
to: remote,
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
await target.generate({count: confirmationCount});
|
|
56
|
+
|
|
57
|
+
await asyncRetry({interval, times}, async () => {
|
|
58
|
+
const wallet = await getWalletInfo({lnd: remote.lnd});
|
|
59
|
+
|
|
60
|
+
await addPeer({lnd, public_key: remote.id, socket: remote.socket});
|
|
61
|
+
|
|
62
|
+
if (!wallet.is_synced_to_chain) {
|
|
63
|
+
throw new Error('ExpectedWalletSyncedToChain');
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
const invoice = await createInvoice({tokens, lnd: remote.lnd});
|
|
68
|
+
|
|
69
|
+
const {id} = invoice;
|
|
70
|
+
const {request} = invoice;
|
|
71
|
+
|
|
72
|
+
const decodedRequest = await decodePaymentRequest({lnd, request});
|
|
73
|
+
|
|
74
|
+
await waitForRoute({lnd, destination: remote.id, tokens: invoice.tokens});
|
|
75
|
+
|
|
76
|
+
const {route} = await asyncRetry({interval, times}, async () => {
|
|
77
|
+
return await getRouteToDestination({
|
|
78
|
+
lnd,
|
|
79
|
+
cltv_delta: decodedRequest.cltv_delta,
|
|
80
|
+
destination: decodedRequest.destination,
|
|
81
|
+
tokens: invoice.tokens,
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
const policyAStart = await getChannel({lnd, id: controlToTargetChan.id});
|
|
86
|
+
|
|
87
|
+
// Target gives a discount to traffic coming from control
|
|
88
|
+
await updateRoutingFees({
|
|
89
|
+
inbound_base_discount_mtokens: discount,
|
|
90
|
+
lnd: target.lnd,
|
|
91
|
+
transaction_id: controlToTargetChan.transaction_id,
|
|
92
|
+
transaction_vout: controlToTargetChan.transaction_vout,
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
// Wait for policy to be updated
|
|
96
|
+
const policyA = await asyncRetry({interval, times}, async () => {
|
|
97
|
+
const policy = await getChannel({lnd, id: controlToTargetChan.id});
|
|
98
|
+
|
|
99
|
+
if (policy.updated_at === policyAStart.updated_at) {
|
|
100
|
+
throw new Error('PolicyNotUpdatedYet');
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return policy;
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
// A discount should be set for traffic from control to remote
|
|
107
|
+
const discountFee = policyA.policies.find(n => n.public_key === target.id);
|
|
108
|
+
|
|
109
|
+
// Get the routing policy of target to remote to calculate the route
|
|
110
|
+
const policyB = await getChannel({
|
|
111
|
+
id: targetRemoteChannel.id,
|
|
112
|
+
lnd: target.lnd,
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
const channelsRoute = routeFromChannels({
|
|
116
|
+
channels: [policyA, policyB],
|
|
117
|
+
cltv_delta: decodedRequest.cltv_delta + confirmationCount,
|
|
118
|
+
destination: decodedRequest.destination,
|
|
119
|
+
height: (await getHeight({lnd})).current_block_height,
|
|
120
|
+
mtokens: decodedRequest.mtokens,
|
|
121
|
+
payment: decodedRequest.payment,
|
|
122
|
+
total_mtokens: decodedRequest.mtokens,
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
const discounted = BigInt(discountFee.inbound_base_discount_mtokens);
|
|
126
|
+
|
|
127
|
+
const gotTotalFee = BigInt(channelsRoute.route.fee_mtokens);
|
|
128
|
+
|
|
129
|
+
await payViaRoutes({lnd, id: invoice.id, routes: [channelsRoute.route]});
|
|
130
|
+
|
|
131
|
+
await kill({});
|
|
132
|
+
|
|
133
|
+
equal(gotTotalFee, BigInt(baseFee) - discounted, 'Got expected discount');
|
|
134
|
+
|
|
135
|
+
return;
|
|
136
|
+
});
|