paid-services 3.20.0 → 3.20.3
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,17 @@
|
|
|
1
1
|
# Versions
|
|
2
2
|
|
|
3
|
+
## Version 3.20.3
|
|
4
|
+
|
|
5
|
+
- `manageGroupJoin`: Allow coordinating pair when funds are below the capacity
|
|
6
|
+
|
|
7
|
+
## Version 3.20.2
|
|
8
|
+
|
|
9
|
+
- `manageGroupJoin`: Allow opening a pair channel when funds are below capacity
|
|
10
|
+
|
|
11
|
+
## Version 3.20.1
|
|
12
|
+
|
|
13
|
+
- `manageTrades`: Fix seller connection when not peered
|
|
14
|
+
|
|
3
15
|
## Version 3.20.0
|
|
4
16
|
|
|
5
17
|
- `manageGroupJoin`: Add support for 2 person groups
|
|
@@ -6,6 +6,7 @@ const {returnResult} = require('asyncjs-util');
|
|
|
6
6
|
const defaultChannelCapacity = 5e6;
|
|
7
7
|
const defaultGroupSize = 3;
|
|
8
8
|
const {floor} = Math;
|
|
9
|
+
const halfOf = input => Number(input) / 2;
|
|
9
10
|
const isNumber = n => !isNaN(n);
|
|
10
11
|
const isOdd = n => !!(n % 2);
|
|
11
12
|
const maxChannelSize = 21e14;
|
|
@@ -47,76 +48,87 @@ module.exports = ({ask, lnd}, cbk) => {
|
|
|
47
48
|
// Get the wallet balance to make sure there are enough funds to join
|
|
48
49
|
getBalance: ['validate', ({}, cbk) => getChainBalance({lnd}, cbk)],
|
|
49
50
|
|
|
50
|
-
//
|
|
51
|
-
|
|
51
|
+
// Get the chain fee rate to use for a default in the chain fee query
|
|
52
|
+
getFeeRate: ['validate', ({}, cbk) => getChainFeeRate({lnd}, cbk)],
|
|
53
|
+
|
|
54
|
+
// Ask for how many group members there should be
|
|
55
|
+
askForCount: ['validate', ({}, cbk) => {
|
|
52
56
|
return ask({
|
|
53
|
-
default:
|
|
54
|
-
name: '
|
|
55
|
-
message: '
|
|
57
|
+
default: defaultGroupSize,
|
|
58
|
+
name: 'size',
|
|
59
|
+
message: 'Total number of group members?',
|
|
56
60
|
validate: input => {
|
|
57
61
|
if (!input || !isNumber(input)) {
|
|
58
62
|
return false;
|
|
59
63
|
}
|
|
60
64
|
|
|
65
|
+
// Do not allow fractional members
|
|
61
66
|
if (round(Number(input)) !== Number(input)) {
|
|
62
67
|
return false;
|
|
63
68
|
}
|
|
64
69
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
if (Number(input) < minChannelSize) {
|
|
70
|
-
return `Minimum channel size is ${minChannelSize}`;
|
|
70
|
+
// Do not allow too many members
|
|
71
|
+
if (Number(input) > maxGroupSize) {
|
|
72
|
+
return `The maximum group size is ${maxGroupSize}`;
|
|
71
73
|
}
|
|
72
74
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
+
// Do not allow too few members
|
|
76
|
+
if (Number(input) < minGroupSize) {
|
|
77
|
+
return `The minimum group size is ${minGroupSize}`;
|
|
75
78
|
}
|
|
76
79
|
|
|
77
80
|
return true;
|
|
78
81
|
},
|
|
79
82
|
},
|
|
80
|
-
({
|
|
83
|
+
({size}) => cbk(null, Number(size)));
|
|
81
84
|
}],
|
|
82
85
|
|
|
83
|
-
//
|
|
84
|
-
|
|
86
|
+
// Ask for how big the channels should be
|
|
87
|
+
askForCapacity: [
|
|
88
|
+
'askForCount',
|
|
89
|
+
'getBalance',
|
|
90
|
+
({askForCount, getBalance}, cbk) =>
|
|
91
|
+
{
|
|
92
|
+
const isPair = askForCount === minGroupSize;
|
|
85
93
|
|
|
86
|
-
// Ask for how many group members there should be
|
|
87
|
-
askForCount: ['askForCapacity', ({askForCapacity}, cbk) => {
|
|
88
94
|
return ask({
|
|
89
|
-
default:
|
|
90
|
-
name: '
|
|
91
|
-
message: '
|
|
95
|
+
default: defaultChannelCapacity,
|
|
96
|
+
name: 'capacity',
|
|
97
|
+
message: 'Channel capacity?',
|
|
92
98
|
validate: input => {
|
|
93
99
|
if (!input || !isNumber(input)) {
|
|
94
100
|
return false;
|
|
95
101
|
}
|
|
96
102
|
|
|
97
|
-
// Do not allow fractional members
|
|
98
103
|
if (round(Number(input)) !== Number(input)) {
|
|
99
104
|
return false;
|
|
100
105
|
}
|
|
101
106
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
return `The maximum group size is ${maxGroupSize}`;
|
|
107
|
+
if (!isPair && Number(input) > getBalance.chain_balance) {
|
|
108
|
+
return `Current chain balance is ${getBalance.chain_balance}`;
|
|
105
109
|
}
|
|
106
110
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
111
|
+
if (isPair && halfOf(input) > getBalance.chain_balance) {
|
|
112
|
+
return `Current chain balance is ${getBalance.chain_balance}`;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (Number(input) < minChannelSize) {
|
|
116
|
+
return `Minimum channel size is ${minChannelSize}`;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (isOdd(Number(input))) {
|
|
120
|
+
return 'Channel capacity must be even';
|
|
110
121
|
}
|
|
111
122
|
|
|
112
123
|
return true;
|
|
113
124
|
},
|
|
114
125
|
},
|
|
115
|
-
({
|
|
126
|
+
({capacity}) => cbk(null, Number(capacity)));
|
|
116
127
|
}],
|
|
117
128
|
|
|
118
129
|
// Ask for a chain fee rate
|
|
119
130
|
askForFeeRate: [
|
|
131
|
+
'askForCapacity',
|
|
120
132
|
'askForCount',
|
|
121
133
|
'getFeeRate',
|
|
122
134
|
({askForCount, getFeeRate}, cbk) =>
|
|
@@ -105,7 +105,7 @@ module.exports = ({ask, lnd}, cbk) => {
|
|
|
105
105
|
({getAlias, getBalance, getDetails}, cbk) =>
|
|
106
106
|
{
|
|
107
107
|
// Check to make sure that there are on chain funds for this group
|
|
108
|
-
if (getBalance.chain_balance < getDetails.
|
|
108
|
+
if (getBalance.chain_balance < getDetails.funding) {
|
|
109
109
|
return cbk([
|
|
110
110
|
400,
|
|
111
111
|
'InsufficientChainFundsAvailableToJoinGroup',
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
const {decodeBigSize} = require('bolt01');
|
|
2
2
|
|
|
3
3
|
const findRecord = (records, type) => records.find(n => n.type === type);
|
|
4
|
+
const funding = (capacity, count) => count === 2 ? capacity / 2 : capacity;
|
|
4
5
|
const {isArray} = Array;
|
|
5
6
|
const isOdd = n => !!(n % 2);
|
|
6
7
|
const maxCapacityTokens = BigInt(7e14);
|
|
7
8
|
const maxMembersCount = BigInt(650);
|
|
8
9
|
const maxFeeRate = BigInt(1e5);
|
|
10
|
+
const minMembersCount = BigInt(2);
|
|
9
11
|
const typeCapacity = '1';
|
|
10
12
|
const typeCount = '2';
|
|
11
13
|
const typeRate = '3';
|
|
@@ -28,6 +30,7 @@ const version = '1';
|
|
|
28
30
|
{
|
|
29
31
|
capacity: <Channel Capacity Tokens Number>
|
|
30
32
|
count: <Target Members Count Number>
|
|
33
|
+
funding: <Amount Of Funding Required Tokens Number>
|
|
31
34
|
rate: <Chain Fee Rate Number>
|
|
32
35
|
}
|
|
33
36
|
*/
|
|
@@ -88,6 +91,10 @@ module.exports = ({records}) => {
|
|
|
88
91
|
throw new Error('UnexpectedValueForCountInGroupRecords');
|
|
89
92
|
}
|
|
90
93
|
|
|
94
|
+
if (BigInt(count) < minMembersCount) {
|
|
95
|
+
throw new Error('ExpectedHigherMembersCountInGroupDetails');
|
|
96
|
+
}
|
|
97
|
+
|
|
91
98
|
const rateRecord = findRecord(records, typeRate);
|
|
92
99
|
|
|
93
100
|
try {
|
|
@@ -105,6 +112,7 @@ module.exports = ({records}) => {
|
|
|
105
112
|
return {
|
|
106
113
|
capacity: Number(capacity),
|
|
107
114
|
count: Number(count),
|
|
115
|
+
funding: funding(Number(capacity), Number(count)),
|
|
108
116
|
rate: Number(rate),
|
|
109
117
|
};
|
|
110
118
|
};
|
package/package.json
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"ecpair": "2.0.1",
|
|
17
17
|
"goldengate": "11.2.3",
|
|
18
18
|
"invoices": "2.1.0",
|
|
19
|
-
"ln-service": "53.
|
|
19
|
+
"ln-service": "53.20.0",
|
|
20
20
|
"ln-sync": "3.13.1",
|
|
21
21
|
"psbt": "2.7.1",
|
|
22
22
|
"p2tr": "1.3.1",
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
"description": "Lightning Paid Services library",
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"@alexbosworth/tap": "15.0.11",
|
|
28
|
-
"ln-docker-daemons": "2.3.
|
|
29
|
-
"mock-lnd": "1.4.
|
|
28
|
+
"ln-docker-daemons": "2.3.4",
|
|
29
|
+
"mock-lnd": "1.4.3",
|
|
30
30
|
"secp256k1": "4.0.3"
|
|
31
31
|
},
|
|
32
32
|
"engines": {
|
|
@@ -47,5 +47,5 @@
|
|
|
47
47
|
"integration-tests": "tap -j 2 --branches=1 --functions=1 --lines=1 --statements=1 -t 180 test/integration/*.js",
|
|
48
48
|
"test": "tap --branches=1 --functions=1 --lines=1 --statements=1 -t 60 test/actions/*.js test/balanced/*.js test/capacity/*.js test/client/*.js test/config/*.js test/p2p/*.js test/records/*.js test/respond/*.js test/server/*.js test/server/*.js test/services/*.js test/trades/*.js"
|
|
49
49
|
},
|
|
50
|
-
"version": "3.20.
|
|
50
|
+
"version": "3.20.3"
|
|
51
51
|
}
|
|
@@ -66,6 +66,9 @@ module.exports = ({lnd, logger, nodes}, cbk) => {
|
|
|
66
66
|
// Derive the self public key
|
|
67
67
|
getIdentity: ['validate', ({}, cbk) => getIdentity({lnd}, cbk)],
|
|
68
68
|
|
|
69
|
+
// Get the actively connected peers
|
|
70
|
+
getPeered: ['validate', ({}, cbk) => getPeers({lnd}, cbk)],
|
|
71
|
+
|
|
69
72
|
// Find node connect info to connect to
|
|
70
73
|
getNodes: ['getIdentity', ({getIdentity}, cbk) => {
|
|
71
74
|
return asyncMap(nodes, (connect, cbk) => {
|
|
@@ -144,7 +147,8 @@ module.exports = ({lnd, logger, nodes}, cbk) => {
|
|
|
144
147
|
removePeer: [
|
|
145
148
|
'getChannels',
|
|
146
149
|
'getNodes',
|
|
147
|
-
|
|
150
|
+
'getPeered',
|
|
151
|
+
({getChannels, getNodes, getPeered}, cbk) =>
|
|
148
152
|
{
|
|
149
153
|
const ids = getChannels.channels.map(n => n.partner_public_key);
|
|
150
154
|
|
|
@@ -154,6 +158,11 @@ module.exports = ({lnd, logger, nodes}, cbk) => {
|
|
|
154
158
|
return cbk();
|
|
155
159
|
}
|
|
156
160
|
|
|
161
|
+
// Exit early when already not peered
|
|
162
|
+
if (!getPeered.peers.map(n => n.public_key).includes(node.id)) {
|
|
163
|
+
return cbk();
|
|
164
|
+
}
|
|
165
|
+
|
|
157
166
|
return removePeer({lnd, public_key: node.id}, (err, res) => {
|
|
158
167
|
if (!!err) {
|
|
159
168
|
return cbk(err);
|
|
@@ -181,7 +190,7 @@ module.exports = ({lnd, logger, nodes}, cbk) => {
|
|
|
181
190
|
}],
|
|
182
191
|
|
|
183
192
|
// Get the list of connected peers
|
|
184
|
-
getPeers: ['
|
|
193
|
+
getPeers: ['validate', ({}, cbk) => getPeers({lnd}, cbk)],
|
|
185
194
|
|
|
186
195
|
// Try and connect to a node in order to do p2p messaging
|
|
187
196
|
connect: [
|