ln-service 53.8.1 → 53.9.2
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 +93 -0
- package/index.js +2 -0
- package/package.json +5 -4
- package/test/integration/test_get_pending_payments.js +87 -0
- package/test/walletrpc-integration/test_fund_psbt.js +12 -26
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -170,6 +170,7 @@ for `unlocker` methods.
|
|
|
170
170
|
- [getPeers](#getpeers) - Get all connected peers
|
|
171
171
|
- [getPendingChainBalance](#getpendingchainbalance) - Get pending chain balance
|
|
172
172
|
- [getPendingChannels](#getpendingchannels) - Get channels in pending states
|
|
173
|
+
- [getPendingPayments](#getpendingpayments) - Get in-flight outgoing payments
|
|
173
174
|
- [getPublicKey](#getpublickey) - Get a public key out of the seed
|
|
174
175
|
- [getRouteConfidence](#getrouteconfidence) - Get confidence in a route
|
|
175
176
|
- [getRouteThroughHops](#getroutethroughhops) - Get a route through nodes
|
|
@@ -2662,6 +2663,98 @@ const {getPendingChannels} = require('ln-service');
|
|
|
2662
2663
|
const pendingChannels = (await getPendingChannels({lnd})).pending_channels;
|
|
2663
2664
|
```
|
|
2664
2665
|
|
|
2666
|
+
### getPendingPayments
|
|
2667
|
+
|
|
2668
|
+
Get pending payments made through channels.
|
|
2669
|
+
|
|
2670
|
+
Requires `offchain:read` permission
|
|
2671
|
+
|
|
2672
|
+
{
|
|
2673
|
+
[limit]: <Page Result Limit Number>
|
|
2674
|
+
lnd: <Authenticated LND API Object>
|
|
2675
|
+
[token]: <Opaque Paging Token String>
|
|
2676
|
+
}
|
|
2677
|
+
|
|
2678
|
+
@returns via cbk or Promise
|
|
2679
|
+
{
|
|
2680
|
+
payments: [{
|
|
2681
|
+
attempts: [{
|
|
2682
|
+
[failure]: {
|
|
2683
|
+
code: <Error Type Code Number>
|
|
2684
|
+
[details]: {
|
|
2685
|
+
[channel]: <Standard Format Channel Id String>
|
|
2686
|
+
[height]: <Error Associated Block Height Number>
|
|
2687
|
+
[index]: <Failed Hop Index Number>
|
|
2688
|
+
[mtokens]: <Error Millitokens String>
|
|
2689
|
+
[policy]: {
|
|
2690
|
+
base_fee_mtokens: <Base Fee Millitokens String>
|
|
2691
|
+
cltv_delta: <Locktime Delta Number>
|
|
2692
|
+
fee_rate: <Fees Charged in Millitokens Per Million Number>
|
|
2693
|
+
[is_disabled]: <Channel is Disabled Bool>
|
|
2694
|
+
max_htlc_mtokens: <Maximum HLTC Millitokens Value String>
|
|
2695
|
+
min_htlc_mtokens: <Minimum HTLC Millitokens Value String>
|
|
2696
|
+
updated_at: <Updated At ISO 8601 Date String>
|
|
2697
|
+
}
|
|
2698
|
+
[timeout_height]: <Error CLTV Timeout Height Number>
|
|
2699
|
+
[update]: {
|
|
2700
|
+
chain: <Chain Id Hex String>
|
|
2701
|
+
channel_flags: <Channel Flags Number>
|
|
2702
|
+
extra_opaque_data: <Extra Opaque Data Hex String>
|
|
2703
|
+
message_flags: <Message Flags Number>
|
|
2704
|
+
signature: <Channel Update Signature Hex String>
|
|
2705
|
+
}
|
|
2706
|
+
}
|
|
2707
|
+
message: <Error Message String>
|
|
2708
|
+
}
|
|
2709
|
+
[index]: <Payment Add Index Number>
|
|
2710
|
+
[confirmed_at]: <Payment Confirmed At ISO 8601 Date String>
|
|
2711
|
+
is_confirmed: <Payment Attempt Succeeded Bool>
|
|
2712
|
+
is_failed: <Payment Attempt Failed Bool>
|
|
2713
|
+
is_pending: <Payment Attempt is Waiting For Resolution Bool>
|
|
2714
|
+
route: {
|
|
2715
|
+
fee: <Route Fee Tokens Number>
|
|
2716
|
+
fee_mtokens: <Route Fee Millitokens String>
|
|
2717
|
+
hops: [{
|
|
2718
|
+
channel: <Standard Format Channel Id String>
|
|
2719
|
+
channel_capacity: <Channel Capacity Tokens Number>
|
|
2720
|
+
fee: <Fee Number>
|
|
2721
|
+
fee_mtokens: <Fee Millitokens String>
|
|
2722
|
+
forward: <Forward Tokens Number>
|
|
2723
|
+
forward_mtokens: <Forward Millitokens String>
|
|
2724
|
+
[public_key]: <Forward Edge Public Key Hex String>
|
|
2725
|
+
[timeout]: <Timeout Block Height Number>
|
|
2726
|
+
}]
|
|
2727
|
+
mtokens: <Total Fee-Inclusive Millitokens String>
|
|
2728
|
+
[payment]: <Payment Identifier Hex String>
|
|
2729
|
+
timeout: <Timeout Block Height Number>
|
|
2730
|
+
tokens: <Total Fee-Inclusive Tokens Number>
|
|
2731
|
+
[total_mtokens]: <Total Millitokens String>
|
|
2732
|
+
}
|
|
2733
|
+
}]
|
|
2734
|
+
created_at: <Payment at ISO-8601 Date String>
|
|
2735
|
+
[destination]: <Destination Node Public Key Hex String>
|
|
2736
|
+
id: <Payment Preimage Hash String>
|
|
2737
|
+
[index]: <Payment Add Index Number>
|
|
2738
|
+
is_confirmed: <Payment is Confirmed Bool>
|
|
2739
|
+
is_outgoing: <Transaction Is Outgoing Bool>
|
|
2740
|
+
mtokens: <Millitokens Attempted to Pay to Destination String>
|
|
2741
|
+
[request]: <BOLT 11 Payment Request String>
|
|
2742
|
+
safe_tokens: <Payment Tokens Attempted to Pay Rounded Up Number>
|
|
2743
|
+
tokens: <Rounded Down Tokens Attempted to Pay to Destination Number>
|
|
2744
|
+
}]
|
|
2745
|
+
[next]: <Next Opaque Paging Token String>
|
|
2746
|
+
}
|
|
2747
|
+
|
|
2748
|
+
```node
|
|
2749
|
+
const {getPendingPayments} = require('ln-service')
|
|
2750
|
+
|
|
2751
|
+
const {next, payments} = await getPendingPayments({lnd});
|
|
2752
|
+
|
|
2753
|
+
if (!next) {
|
|
2754
|
+
const inFlightPaymentsCount = payments.length;
|
|
2755
|
+
}
|
|
2756
|
+
```
|
|
2757
|
+
|
|
2665
2758
|
### getPublicKey
|
|
2666
2759
|
|
|
2667
2760
|
Get a public key in the seed
|
package/index.js
CHANGED
|
@@ -61,6 +61,7 @@ const {getPayments} = require('lightning');
|
|
|
61
61
|
const {getPeers} = require('lightning');
|
|
62
62
|
const {getPendingChainBalance} = require('lightning');
|
|
63
63
|
const {getPendingChannels} = require('lightning');
|
|
64
|
+
const {getPendingPayments} = require('lightning');
|
|
64
65
|
const {getPublicKey} = require('lightning');
|
|
65
66
|
const {getRouteConfidence} = require('lightning');
|
|
66
67
|
const {getRouteThroughHops} = require('lightning');
|
|
@@ -202,6 +203,7 @@ module.exports = {
|
|
|
202
203
|
getPeers,
|
|
203
204
|
getPendingChainBalance,
|
|
204
205
|
getPendingChannels,
|
|
206
|
+
getPendingPayments,
|
|
205
207
|
getPublicKey,
|
|
206
208
|
getRouteConfidence,
|
|
207
209
|
getRouteThroughHops,
|
package/package.json
CHANGED
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
"dependencies": {
|
|
10
10
|
"bolt07": "1.8.0",
|
|
11
11
|
"cors": "2.8.5",
|
|
12
|
-
"express": "4.17.
|
|
12
|
+
"express": "4.17.3",
|
|
13
13
|
"invoices": "2.0.4",
|
|
14
|
-
"lightning": "5.
|
|
14
|
+
"lightning": "5.8.1",
|
|
15
15
|
"macaroon": "3.0.4",
|
|
16
16
|
"morgan": "1.10.0",
|
|
17
17
|
"ws": "8.5.0"
|
|
@@ -29,11 +29,12 @@
|
|
|
29
29
|
"bs58check": "2.1.2",
|
|
30
30
|
"ecpair": "2.0.1",
|
|
31
31
|
"ln-docker-daemons": "2.2.4",
|
|
32
|
+
"p2tr": "1.2.0",
|
|
32
33
|
"portfinder": "1.0.28",
|
|
33
34
|
"psbt": "2.0.0",
|
|
34
35
|
"rimraf": "3.0.2",
|
|
35
36
|
"secp256k1": "4.0.3",
|
|
36
|
-
"tiny-secp256k1": "2.2.
|
|
37
|
+
"tiny-secp256k1": "2.2.1",
|
|
37
38
|
"uuid": "8.3.2",
|
|
38
39
|
"varuint-bitcoin": "1.1.2"
|
|
39
40
|
},
|
|
@@ -68,5 +69,5 @@
|
|
|
68
69
|
"integration-test-0.12.0": "DOCKER_LND_VERSION=v0.12.0-beta npm run test",
|
|
69
70
|
"test": "echo $DOCKER_LND_VERSION && tap -j 2 --branches=1 --functions=1 --lines=1 --statements=1 -t 200 test/autopilotrpc-integration/*.js test/chainrpc-integration/*.js test/integration/*.js test/invoicesrpc-integration/*.js test/routerrpc-integration/*.js test/signerrpc-integration/*.js test/tower_clientrpc-integration/*.js test/tower_serverrpc-integration/*.js test/walletrpc-integration/*.js"
|
|
70
71
|
},
|
|
71
|
-
"version": "53.
|
|
72
|
+
"version": "53.9.2"
|
|
72
73
|
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
const {once} = require('events');
|
|
2
|
+
|
|
3
|
+
const {spawnLightningCluster} = require('ln-docker-daemons');
|
|
4
|
+
const {test} = require('@alexbosworth/tap');
|
|
5
|
+
|
|
6
|
+
const {addPeer} = require('./../../');
|
|
7
|
+
const {createCluster} = require('./../macros');
|
|
8
|
+
const {createInvoice} = require('./../../');
|
|
9
|
+
const {deleteForwardingReputations} = require('./../../');
|
|
10
|
+
const {getHeight} = require('./../../');
|
|
11
|
+
const {getInvoice} = require('./../../');
|
|
12
|
+
const {getPayment} = require('./../../');
|
|
13
|
+
const {getPendingPayments} = require('./../../');
|
|
14
|
+
const {payViaPaymentRequest} = require('./../../');
|
|
15
|
+
const {subscribeToForwardRequests} = require('./../../');
|
|
16
|
+
const {subscribeToPayViaRequest} = require('./../../');
|
|
17
|
+
const {setupChannel} = require('./../macros');
|
|
18
|
+
const {waitForRoute} = require('./../macros');
|
|
19
|
+
|
|
20
|
+
const size = 3;
|
|
21
|
+
const tokens = 100;
|
|
22
|
+
|
|
23
|
+
// Getting pending payments should list out payments in flight
|
|
24
|
+
test(`Get pending payments`, async ({end, equal, rejects, strictSame}) => {
|
|
25
|
+
const {kill, nodes} = await spawnLightningCluster({size});
|
|
26
|
+
|
|
27
|
+
const [{generate, lnd}, target, remote] = nodes;
|
|
28
|
+
|
|
29
|
+
const channel = await setupChannel({generate, lnd, to: target});
|
|
30
|
+
|
|
31
|
+
await remote.generate({count: 100});
|
|
32
|
+
|
|
33
|
+
const remoteChan = await setupChannel({
|
|
34
|
+
lnd: target.lnd,
|
|
35
|
+
generate: target.generate,
|
|
36
|
+
to: remote,
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
await addPeer({lnd, public_key: remote.id, socket: remote.socket});
|
|
40
|
+
|
|
41
|
+
const {routes} = await waitForRoute({lnd, tokens, destination: remote.id});
|
|
42
|
+
|
|
43
|
+
let height;
|
|
44
|
+
const [route] = routes;
|
|
45
|
+
|
|
46
|
+
{
|
|
47
|
+
const invoice = await createInvoice({tokens, lnd: remote.lnd});
|
|
48
|
+
|
|
49
|
+
const sub = subscribeToForwardRequests({lnd: target.lnd});
|
|
50
|
+
|
|
51
|
+
sub.once('forward_request', async forward => {
|
|
52
|
+
const {pending} = await getPayment({lnd, id: invoice.id});
|
|
53
|
+
|
|
54
|
+
const {next, payments} = await getPendingPayments({lnd});
|
|
55
|
+
|
|
56
|
+
strictSame(next, undefined, 'No more pages');
|
|
57
|
+
strictSame(payments.length, 1, 'A single pending payment');
|
|
58
|
+
|
|
59
|
+
const [payment] = payments;
|
|
60
|
+
|
|
61
|
+
strictSame(payment.destination, remote.id, 'Paying to remote');
|
|
62
|
+
strictSame(payment.index, 1, 'First payment');
|
|
63
|
+
strictSame(payment.request, invoice.request, 'Paying invoice request');
|
|
64
|
+
strictSame(payment.confirmed_at, undefined, 'Not a confirmed payment');
|
|
65
|
+
strictSame(!!payment.created_at, true, 'Has created date');
|
|
66
|
+
strictSame(payment.fee, undefined, 'No fee yet');
|
|
67
|
+
strictSame(payment.fee_mtokens, undefined, 'No fee mtokens');
|
|
68
|
+
strictSame(payment.hops.length, 1, 'Going through hops');
|
|
69
|
+
strictSame(payment.id, invoice.id, 'Paying to the same hash');
|
|
70
|
+
strictSame(payment.is_confirmed, false, 'Payment is pending');
|
|
71
|
+
strictSame(payment.is_outgoing, true, 'Outgoing payment type');
|
|
72
|
+
strictSame(payment.mtokens, invoice.mtokens, 'Paying invoiced mtokens');
|
|
73
|
+
strictSame(payment.safe_fee, undefined, 'No fee paid yet');
|
|
74
|
+
strictSame(payment.safe_tokens, invoice.tokens, 'Paying safe tokens');
|
|
75
|
+
strictSame(payment.secret, undefined, 'Preimage not yet known');
|
|
76
|
+
strictSame(payment.tokens, invoice.tokens, 'Paying invoiced tokens');
|
|
77
|
+
|
|
78
|
+
return forward.accept();
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
await payViaPaymentRequest({lnd, request: invoice.request});
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
await kill({});
|
|
85
|
+
|
|
86
|
+
return end();
|
|
87
|
+
});
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
const asyncRetry = require('async/retry');
|
|
2
2
|
const {address} = require('bitcoinjs-lib');
|
|
3
3
|
const {createPsbt} = require('psbt');
|
|
4
|
-
const {crypto} = require('bitcoinjs-lib');
|
|
5
4
|
const {decodePsbt} = require('psbt');
|
|
6
5
|
const {networks} = require('bitcoinjs-lib');
|
|
7
|
-
const {
|
|
6
|
+
const {signHash} = require('p2tr');
|
|
8
7
|
const {spawnLightningCluster} = require('ln-docker-daemons');
|
|
9
8
|
const {test} = require('@alexbosworth/tap');
|
|
10
9
|
const tinysecp = require('tiny-secp256k1');
|
|
11
10
|
const {Transaction} = require('bitcoinjs-lib');
|
|
11
|
+
const {v1OutputScript} = require('p2tr');
|
|
12
12
|
|
|
13
13
|
const {broadcastChainTransaction} = require('./../../');
|
|
14
14
|
const {createChainAddress} = require('./../../');
|
|
@@ -20,28 +20,16 @@ const {sendToChainAddress} = require('./../../');
|
|
|
20
20
|
const {signPsbt} = require('./../../');
|
|
21
21
|
|
|
22
22
|
const chainAddressRowType = 'chain_address';
|
|
23
|
-
const {compile} = script;
|
|
24
23
|
const confirmationCount = 6;
|
|
25
24
|
const count = 100;
|
|
26
25
|
const description = 'description';
|
|
27
|
-
const extra = Buffer.alloc(32);
|
|
28
26
|
const {fromBech32} = address;
|
|
29
27
|
const {fromHex} = Transaction;
|
|
30
28
|
const {fromOutputScript} = address;
|
|
31
29
|
const hexAsBuffer = hex => Buffer.from(hex, 'hex');
|
|
32
30
|
const interval = retryCount => 10 * Math.pow(2, retryCount);
|
|
33
|
-
const isLowPublicKey = keyPair => keyPair.publicKey[0] === 2;
|
|
34
|
-
const makeTaprootKey = (k, h) => tinysecp.xOnlyPointAddTweak(k, h).xOnlyPubkey;
|
|
35
|
-
const nLess1 = 'fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140';
|
|
36
|
-
const one256BitBigEndian = '0000000000000000000000000000000000000000000000000000000000000001';
|
|
37
|
-
const OP_1 = 81;
|
|
38
|
-
const {privateAdd} = tinysecp;
|
|
39
|
-
const {privateSub} = tinysecp;
|
|
40
31
|
const regtestBech32AddressHrp = 'bcrt';
|
|
41
|
-
const shortKey = keyPair => keyPair.publicKey.slice(1, 33);
|
|
42
|
-
const {signSchnorr} = tinysecp;
|
|
43
32
|
const smallTokens = 2e5;
|
|
44
|
-
const tapHash = k => crypto.taggedHash('TapTweak', k.publicKey.slice(1, 33));
|
|
45
33
|
const times = 20;
|
|
46
34
|
const {toOutputScript} = address;
|
|
47
35
|
const tokens = 1e6;
|
|
@@ -126,10 +114,11 @@ test(`Fund PSBT`, async ({end, equal}) => {
|
|
|
126
114
|
|
|
127
115
|
const keyPair = ecp.makeRandom({network: networks.regtest});
|
|
128
116
|
|
|
129
|
-
const
|
|
130
|
-
|
|
117
|
+
const output = v1OutputScript({
|
|
118
|
+
internal_key: keyPair.publicKey.toString('hex'),
|
|
119
|
+
});
|
|
131
120
|
|
|
132
|
-
const outputScript =
|
|
121
|
+
const outputScript = hexAsBuffer(output.script);
|
|
133
122
|
|
|
134
123
|
const [utxo] = (await getUtxos({lnd})).utxos.reverse();
|
|
135
124
|
|
|
@@ -175,16 +164,13 @@ test(`Fund PSBT`, async ({end, equal}) => {
|
|
|
175
164
|
);
|
|
176
165
|
});
|
|
177
166
|
|
|
178
|
-
const
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
// Only low keys are allowed to save a leading byte on the public key
|
|
185
|
-
const lowPrivateKey = privateAdd(privateKey, tweakHash);
|
|
167
|
+
const signedInput = signHash({
|
|
168
|
+
private_key: keyPair.privateKey.toString('hex'),
|
|
169
|
+
public_key: keyPair.publicKey.toString('hex'),
|
|
170
|
+
sign_hash: hashToSign.toString('hex'),
|
|
171
|
+
});
|
|
186
172
|
|
|
187
|
-
const signature =
|
|
173
|
+
const signature = hexAsBuffer(signedInput.signature);
|
|
188
174
|
|
|
189
175
|
// Add the signature to the input
|
|
190
176
|
tx.ins.forEach((input, i) => tx.setWitness(i, [Buffer.from(signature)]));
|