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
@@ -1,5 +1,10 @@
1
1
  # Versions
2
2
 
3
+ ## 57.14.1
4
+
5
+ - `getChannel`: Add support for specifying `transaction_id` and
6
+ `transaction_vout` instead of `id`
7
+
3
8
  ## 57.13.3
4
9
 
5
10
  - `getWalletInfo`: Add support for LND 0.18.0
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 Millitokens Number>
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]: <Policy Last Updated At ISO 8601 Date String>
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 Update Epoch ISO 8601 Date String>
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.2",
10
+ "bolt07": "1.9.3",
11
11
  "invoices": "3.0.0",
12
- "lightning": "10.13.1",
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.5",
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.17",
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": "9.0.1",
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.13.3"
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
+ });