paid-services 10.3.1 → 10.3.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 +1 -1
- package/config/bech32_prefixes.json +7 -0
- package/config/index.js +2 -0
- package/groups/assemble_channel_group.js +2 -3
- package/groups/estimate_fee_rate.js +20 -8
- package/groups/fanout/join_fanout.js +3 -4
- package/groups/funding/propose_group_channel.js +14 -9
- package/groups/funding/sign_and_fund_group_channel.js +5 -4
- package/groups/join_channel_group.js +8 -8
- package/groups/messages/decode_utxos_record.js +2 -3
- package/groups/p2p/register_fanout_proposal.js +8 -12
- package/groups/p2p/register_pending_open.js +8 -12
- package/groups/transaction_fee_rate.js +5 -5
- package/package.json +4 -4
- package/swaps/complete_off_to_on_swap.js +36 -22
- package/swaps/complete_on_to_off_swap.js +40 -24
- package/swaps/constants.json +16 -0
- package/swaps/manage_swap.js +3 -6
- package/swaps/request_swap_out.js +11 -4
- package/swaps/start_off_to_on_swap.js +4 -6
- package/swaps/start_on_to_off_swap.js +4 -6
- package/swaps/output_script_for_address.js +0 -55
package/CHANGELOG.md
CHANGED
package/config/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const bech32Prefixes = require('./bech32_prefixes');
|
|
1
2
|
const invoiceNetwork = require('./invoice_network');
|
|
2
3
|
const isActivityEnabled = require('./is_activity_enabled');
|
|
3
4
|
const isConnectEnabled = require('./is_connect_enabled');
|
|
@@ -8,6 +9,7 @@ const isSmsConfigured = require('./is_sms_configured');
|
|
|
8
9
|
const validateServerConfig = require('./validate_server_config');
|
|
9
10
|
|
|
10
11
|
module.exports = {
|
|
12
|
+
bech32Prefixes,
|
|
11
13
|
invoiceNetwork,
|
|
12
14
|
isActivityEnabled,
|
|
13
15
|
isConnectEnabled,
|
|
@@ -6,7 +6,7 @@ const {combinePsbts} = require('psbt');
|
|
|
6
6
|
const {decodePsbt} = require('psbt');
|
|
7
7
|
const {extractTransaction} = require('psbt');
|
|
8
8
|
const {finalizePsbt} = require('psbt');
|
|
9
|
-
const {
|
|
9
|
+
const {idForTransaction} = require('@alexbosworth/blockchain');
|
|
10
10
|
|
|
11
11
|
const {confirmIncomingChannel} = require('./funding');
|
|
12
12
|
const {coordinateGroup} = require('./assemble');
|
|
@@ -15,7 +15,6 @@ const {proposeGroupChannel} = require('./funding');
|
|
|
15
15
|
const {signAndFundGroupChannel} = require('./funding');
|
|
16
16
|
const transactionFeeRate = require('./transaction_fee_rate');
|
|
17
17
|
|
|
18
|
-
const {fromHex} = Transaction;
|
|
19
18
|
const interval = 500;
|
|
20
19
|
const minGroupCount = 2;
|
|
21
20
|
const times = 2 * 60 * 10;
|
|
@@ -176,7 +175,7 @@ module.exports = ({capacity, count, identity, lnd, members, rate}) => {
|
|
|
176
175
|
capacity,
|
|
177
176
|
lnd,
|
|
178
177
|
from: coordinator.partners(identity).inbound,
|
|
179
|
-
id:
|
|
178
|
+
id: idForTransaction({transaction: basePsbt.unsigned_transaction}).id,
|
|
180
179
|
to: coordinator.partners(identity).outbound || undefined,
|
|
181
180
|
});
|
|
182
181
|
});
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
const {
|
|
1
|
+
const {componentsOfTransaction} = require('@alexbosworth/blockchain');
|
|
2
|
+
const {sizeOfTransaction} = require('@alexbosworth/blockchain');
|
|
3
|
+
const {transactionFromComponents} = require('@alexbosworth/blockchain');
|
|
2
4
|
|
|
3
|
-
const
|
|
5
|
+
const bufferAsHex = buffer => buffer.toString('hex');
|
|
4
6
|
const isUtxoP2wpkh = utxo => utxo.witness_utxo.script_pub.startsWith('0014');
|
|
5
7
|
const sumTokens = arr => arr.reduce((sum, n) => sum + n.tokens, 0);
|
|
6
|
-
const dummyP2wpkh = [Buffer.alloc(33), Buffer.alloc(72)];
|
|
7
|
-
const dummyP2tr = [Buffer.alloc(64)];
|
|
8
|
+
const dummyP2wpkh = [Buffer.alloc(33), Buffer.alloc(72)].map(bufferAsHex);
|
|
9
|
+
const dummyP2tr = [Buffer.alloc(64)].map(bufferAsHex);
|
|
8
10
|
|
|
9
11
|
/** Assuming large ECDSA signatures, determine a chain fee rate for a PSBT
|
|
10
12
|
|
|
@@ -28,11 +30,21 @@ const dummyP2tr = [Buffer.alloc(64)];
|
|
|
28
30
|
*/
|
|
29
31
|
module.exports = ({inputs, outputs, unsigned}) => {
|
|
30
32
|
const fee = sumTokens(inputs.map(n => n.witness_utxo)) - sumTokens(outputs);
|
|
31
|
-
const tx =
|
|
33
|
+
const tx = componentsOfTransaction({transaction: unsigned});
|
|
32
34
|
|
|
33
|
-
inputs
|
|
34
|
-
|
|
35
|
+
// Add dummy witnesses to the inputs to estimate the final signed size
|
|
36
|
+
const {transaction} = transactionFromComponents({
|
|
37
|
+
inputs: tx.inputs.map((input, index) => ({
|
|
38
|
+
id: input.id,
|
|
39
|
+
script: input.script,
|
|
40
|
+
sequence: input.sequence,
|
|
41
|
+
vout: input.vout,
|
|
42
|
+
witness: isUtxoP2wpkh(inputs[index]) ? dummyP2wpkh : dummyP2tr,
|
|
43
|
+
})),
|
|
44
|
+
locktime: tx.locktime,
|
|
45
|
+
outputs: tx.outputs,
|
|
46
|
+
version: tx.version,
|
|
35
47
|
});
|
|
36
48
|
|
|
37
|
-
return {rate: fee /
|
|
49
|
+
return {rate: fee / sizeOfTransaction({transaction}).vsize};
|
|
38
50
|
};
|
|
@@ -2,14 +2,13 @@ const EventEmitter = require('events');
|
|
|
2
2
|
|
|
3
3
|
const asyncAuto = require('async/auto');
|
|
4
4
|
const {decodePsbt} = require('psbt');
|
|
5
|
-
const {
|
|
5
|
+
const {idForTransaction} = require('@alexbosworth/blockchain');
|
|
6
6
|
|
|
7
7
|
const getFanoutFunding = require('./get_fanout_funding');
|
|
8
8
|
const {registerGroupConnected} = require('./../p2p');
|
|
9
9
|
const {registerFanoutProposal} = require('./../p2p');
|
|
10
10
|
const {registerFanoutSigned} = require('./../p2p');
|
|
11
11
|
|
|
12
|
-
const {fromHex} = Transaction;
|
|
13
12
|
const {isArray} = Array;
|
|
14
13
|
const isNumber = n => !isNaN(n);
|
|
15
14
|
|
|
@@ -128,9 +127,9 @@ module.exports = (args, cbk) => {
|
|
|
128
127
|
transaction: ['register', ({register}, cbk) => {
|
|
129
128
|
const psbt = decodePsbt({psbt: register.psbt});
|
|
130
129
|
|
|
131
|
-
const
|
|
130
|
+
const {id} = idForTransaction({transaction: psbt.unsigned_transaction});
|
|
132
131
|
|
|
133
|
-
return cbk(null, {id
|
|
132
|
+
return cbk(null, {id, raw: psbt.unsigned_transaction});
|
|
134
133
|
}],
|
|
135
134
|
|
|
136
135
|
// Publish the partial funding signatures to coordinator
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
const asyncAuto = require('async/auto');
|
|
2
2
|
const asyncEach = require('async/each');
|
|
3
3
|
const {connectPeer} = require('ln-sync');
|
|
4
|
+
const {encodeBech32Address} = require('@alexbosworth/blockchain');
|
|
4
5
|
const {fundPsbtDisallowingInputs} = require('ln-sync');
|
|
5
6
|
const {getNetwork} = require('ln-sync');
|
|
6
7
|
const {getUtxos} = require('ln-service');
|
|
7
8
|
const {openChannels} = require('ln-service');
|
|
8
|
-
const {
|
|
9
|
-
const {payments} = require('bitcoinjs-lib');
|
|
9
|
+
const {p2msScript} = require('@alexbosworth/blockchain');
|
|
10
10
|
const {returnResult} = require('asyncjs-util');
|
|
11
11
|
const {unlockUtxo} = require('ln-service');
|
|
12
12
|
|
|
13
|
+
const {bech32Prefixes} = require('./../../config');
|
|
14
|
+
|
|
13
15
|
const dummyKeys = () => ([Buffer.alloc(33, 2), Buffer.alloc(33, 3)]);
|
|
14
16
|
const fuzzSize = 1;
|
|
15
17
|
const halfOf = n => n / 2;
|
|
@@ -17,6 +19,7 @@ const isEven = n => !(n % 2);
|
|
|
17
19
|
const minGroupCount = 2;
|
|
18
20
|
const nestedSegWitAddressFormat = 'np2wpkh';
|
|
19
21
|
const nestedSegWitPath = "m/49'/";
|
|
22
|
+
const witnessVersionSegWit = 0;
|
|
20
23
|
|
|
21
24
|
/** Fund and propose a group channel to a peer
|
|
22
25
|
|
|
@@ -101,13 +104,15 @@ module.exports = ({capacity, count, lnd, rate, to}, cbk) => {
|
|
|
101
104
|
|
|
102
105
|
// Exit early when there is a shared proposal due to a pair group
|
|
103
106
|
if (!to) {
|
|
104
|
-
const {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
107
|
+
const {hash} = p2msScript({
|
|
108
|
+
keys: dummyKeys(),
|
|
109
|
+
required: dummyKeys().length,
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
const {address} = encodeBech32Address({
|
|
113
|
+
prefix: bech32Prefixes[getNetwork.network],
|
|
114
|
+
program: hash,
|
|
115
|
+
version: witnessVersionSegWit,
|
|
111
116
|
});
|
|
112
117
|
|
|
113
118
|
// Pretend we are opening a channel when there is no outbound target
|
|
@@ -3,11 +3,10 @@ const asyncRetry = require('async/retry');
|
|
|
3
3
|
const {decodePsbt} = require('psbt');
|
|
4
4
|
const {fundPendingChannels} = require('ln-service');
|
|
5
5
|
const {getPendingChannels} = require('ln-service');
|
|
6
|
+
const {idForTransaction} = require('@alexbosworth/blockchain');
|
|
6
7
|
const {returnResult} = require('asyncjs-util');
|
|
7
8
|
const {signAndFundPsbt} = require('ln-sync');
|
|
8
|
-
const {Transaction} = require('bitcoinjs-lib');
|
|
9
9
|
|
|
10
|
-
const {fromHex} = Transaction;
|
|
11
10
|
const interval = 10;
|
|
12
11
|
const {isArray} = Array;
|
|
13
12
|
const times = 500;
|
|
@@ -88,7 +87,9 @@ module.exports = ({id, lnd, psbt, utxos}, cbk) => {
|
|
|
88
87
|
return cbk();
|
|
89
88
|
}
|
|
90
89
|
|
|
91
|
-
const
|
|
90
|
+
const unsigned = decodePsbt({psbt}).unsigned_transaction;
|
|
91
|
+
|
|
92
|
+
const txId = idForTransaction({transaction: unsigned}).id;
|
|
92
93
|
|
|
93
94
|
// Wait for the outgoing pending channel to be present
|
|
94
95
|
return asyncRetry({interval, times}, cbk => {
|
|
@@ -99,7 +100,7 @@ module.exports = ({id, lnd, psbt, utxos}, cbk) => {
|
|
|
99
100
|
|
|
100
101
|
const ids = res.pending_channels.map(n => n.transaction_id);
|
|
101
102
|
|
|
102
|
-
if (!ids.includes(
|
|
103
|
+
if (!ids.includes(txId)) {
|
|
103
104
|
return cbk([503, 'FailedToFindPendingChannelForGroupOpen']);
|
|
104
105
|
}
|
|
105
106
|
|
|
@@ -3,9 +3,10 @@ const EventEmitter = require('events');
|
|
|
3
3
|
const asyncAuto = require('async/auto');
|
|
4
4
|
const asyncReflect = require('async/reflect');
|
|
5
5
|
const asyncRetry = require('async/retry');
|
|
6
|
+
const {componentsOfTransaction} = require('@alexbosworth/blockchain');
|
|
6
7
|
const {decodePsbt} = require('psbt');
|
|
7
8
|
const {deletePendingChannel} = require('ln-service');
|
|
8
|
-
const {
|
|
9
|
+
const {idForTransaction} = require('@alexbosworth/blockchain');
|
|
9
10
|
|
|
10
11
|
const {confirmIncomingChannel} = require('./funding');
|
|
11
12
|
const {findGroupPartners} = require('./p2p');
|
|
@@ -15,8 +16,6 @@ const {registerGroupConnected} = require('./p2p');
|
|
|
15
16
|
const {registerPendingOpen} = require('./p2p');
|
|
16
17
|
const {registerSignedOpen} = require('./p2p');
|
|
17
18
|
|
|
18
|
-
const {fromHex} = Transaction;
|
|
19
|
-
const hexAsBuffer = hex => Buffer.from(hex, 'hex');
|
|
20
19
|
const interval = 1000;
|
|
21
20
|
const times = 60 * 10;
|
|
22
21
|
|
|
@@ -148,15 +147,16 @@ module.exports = ({capacity, coordinator, count, id, lnd, rate}, cbk) => {
|
|
|
148
147
|
'register',
|
|
149
148
|
({propose, register}, cbk) =>
|
|
150
149
|
{
|
|
151
|
-
const funding = hexAsBuffer(propose.funding);
|
|
152
150
|
const psbt = decodePsbt({psbt: register.psbt});
|
|
153
151
|
|
|
154
|
-
const
|
|
152
|
+
const transaction = psbt.unsigned_transaction;
|
|
153
|
+
|
|
154
|
+
const {outputs} = componentsOfTransaction({transaction});
|
|
155
155
|
|
|
156
156
|
return cbk(null, {
|
|
157
|
-
id:
|
|
158
|
-
raw:
|
|
159
|
-
vout:
|
|
157
|
+
id: idForTransaction({transaction}).id,
|
|
158
|
+
raw: transaction,
|
|
159
|
+
vout: outputs.findIndex(n => n.script === propose.funding),
|
|
160
160
|
});
|
|
161
161
|
}],
|
|
162
162
|
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
+
const {componentsOfTransaction} = require('@alexbosworth/blockchain');
|
|
1
2
|
const {decodeBigSize} = require('bolt01');
|
|
2
3
|
const {decodeTlvStream} = require('bolt01');
|
|
3
|
-
const {Transaction} = require('bitcoinjs-lib');
|
|
4
4
|
|
|
5
5
|
const findRecord = (records, type) => records.find(n => n.type === type);
|
|
6
|
-
const {fromHex} = Transaction;
|
|
7
6
|
|
|
8
7
|
const expectedTxIdHexLength = 64;
|
|
9
8
|
const isP2tr = n => n.startsWith('5120') && n.length === 68;
|
|
@@ -61,7 +60,7 @@ module.exports = ({encoded}) => {
|
|
|
61
60
|
|
|
62
61
|
if (!!nonWitnessUtxo) {
|
|
63
62
|
try {
|
|
64
|
-
|
|
63
|
+
componentsOfTransaction({transaction: nonWitnessUtxo.value});
|
|
65
64
|
} catch (err) {
|
|
66
65
|
throw new Error('ExpectedValidTransactionInPendingWitnessUtxo');
|
|
67
66
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
const asyncAuto = require('async/auto');
|
|
2
2
|
const asyncReflect = require('async/reflect');
|
|
3
3
|
const asyncRetry = require('async/retry');
|
|
4
|
+
const {componentsOfTransaction} = require('@alexbosworth/blockchain');
|
|
4
5
|
const {connectPeer} = require('ln-sync');
|
|
5
6
|
const {decodePsbt} = require('psbt');
|
|
6
7
|
const {returnResult} = require('asyncjs-util');
|
|
7
8
|
const {signAndFundPsbt} = require('ln-sync');
|
|
8
|
-
const {Transaction} = require('bitcoinjs-lib');
|
|
9
9
|
|
|
10
10
|
const {decodeUnsignedFunding} = require('./../messages');
|
|
11
11
|
const {encodeFanoutProposal} = require('./../messages');
|
|
@@ -13,12 +13,9 @@ const estimateFeeRate = require('./../estimate_fee_rate');
|
|
|
13
13
|
const {makePeerRequest} = require('./../../p2p');
|
|
14
14
|
const {serviceTypeRegisterPendingFanout} = require('./../../service_types')
|
|
15
15
|
|
|
16
|
-
const bufferAsHex = buffer => buffer.toString('hex');
|
|
17
16
|
const defaultIntervalMs = 500;
|
|
18
17
|
const defaultPollTimes = 2 * 60 * 30;
|
|
19
18
|
const defaultRequestTimeoutMs = 1000 * 60;
|
|
20
|
-
const {fromHex} = Transaction;
|
|
21
|
-
const hexAsBuffer = hex => Buffer.from(hex, 'hex');
|
|
22
19
|
const {isArray} = Array;
|
|
23
20
|
const missingGroupPartners = 'NoGroupPartnersFound';
|
|
24
21
|
|
|
@@ -159,11 +156,13 @@ module.exports = (args, cbk) => {
|
|
|
159
156
|
return cbk([503, 'ExpectedAllFanoutInputsSpendingWitnessUtxos']);
|
|
160
157
|
}
|
|
161
158
|
|
|
162
|
-
const tx =
|
|
159
|
+
const tx = componentsOfTransaction({
|
|
160
|
+
transaction: psbt.unsigned_transaction,
|
|
161
|
+
});
|
|
163
162
|
|
|
164
163
|
const estimated = estimateFeeRate({
|
|
165
164
|
inputs: psbt.inputs,
|
|
166
|
-
outputs: tx.
|
|
165
|
+
outputs: tx.outputs.map(n => ({tokens: n.tokens})),
|
|
167
166
|
unsigned: psbt.unsigned_transaction,
|
|
168
167
|
});
|
|
169
168
|
|
|
@@ -173,20 +172,17 @@ module.exports = (args, cbk) => {
|
|
|
173
172
|
|
|
174
173
|
// All the specified utxos should be represented in the PSBT
|
|
175
174
|
const missingInput = args.utxos.find(utxo => {
|
|
176
|
-
const
|
|
175
|
+
const id = utxo.transaction_id;
|
|
177
176
|
const vout = utxo.transaction_vout;
|
|
178
177
|
|
|
179
|
-
return !tx.
|
|
178
|
+
return !tx.inputs.find(n => n.id === id && n.vout === vout);
|
|
180
179
|
});
|
|
181
180
|
|
|
182
181
|
if (!!missingInput) {
|
|
183
182
|
return cbk([503, 'ExpectedAllInputsRepresentedInFanoutGroupPsbt']);
|
|
184
183
|
}
|
|
185
184
|
|
|
186
|
-
const outputs = tx
|
|
187
|
-
script: bufferAsHex(script),
|
|
188
|
-
tokens: value,
|
|
189
|
-
}));
|
|
185
|
+
const {outputs} = tx;
|
|
190
186
|
|
|
191
187
|
const change = outputs.find(n => n.script === args.change);
|
|
192
188
|
const funding = outputs.filter(n => args.funding.includes(n.script));
|
|
@@ -2,10 +2,10 @@ const asyncAuto = require('async/auto');
|
|
|
2
2
|
const asyncReflect = require('async/reflect');
|
|
3
3
|
const asyncRetry = require('async/retry');
|
|
4
4
|
const {cancelPendingChannel} = require('ln-service');
|
|
5
|
+
const {componentsOfTransaction} = require('@alexbosworth/blockchain');
|
|
5
6
|
const {connectPeer} = require('ln-sync');
|
|
6
7
|
const {decodePsbt} = require('psbt');
|
|
7
8
|
const {returnResult} = require('asyncjs-util');
|
|
8
|
-
const {Transaction} = require('bitcoinjs-lib');
|
|
9
9
|
|
|
10
10
|
const {decodeUnsignedFunding} = require('./../messages');
|
|
11
11
|
const {encodePendingProposal} = require('./../messages');
|
|
@@ -14,12 +14,9 @@ const {makePeerRequest} = require('./../../p2p');
|
|
|
14
14
|
const {serviceTypeRegisterPendingOpen} = require('./../../service_types');
|
|
15
15
|
const {signAndFundGroupChannel} = require('./../funding');
|
|
16
16
|
|
|
17
|
-
const bufferAsHex = buffer => buffer.toString('hex');
|
|
18
17
|
const defaultIntervalMs = 500;
|
|
19
18
|
const defaultPollTimes = 2 * 60 * 30;
|
|
20
19
|
const defaultRequestTimeoutMs = 1000 * 60;
|
|
21
|
-
const {fromHex} = Transaction;
|
|
22
|
-
const hexAsBuffer = hex => Buffer.from(hex, 'hex');
|
|
23
20
|
const {isArray} = Array;
|
|
24
21
|
const missingGroupPartners = 'NoGroupPartnersFound';
|
|
25
22
|
|
|
@@ -183,30 +180,29 @@ module.exports = (args, cbk) => {
|
|
|
183
180
|
return cbk([503, 'ExpectedAllGroupInputsSpendingWitnessUtxos']);
|
|
184
181
|
}
|
|
185
182
|
|
|
186
|
-
const tx =
|
|
183
|
+
const tx = componentsOfTransaction({
|
|
184
|
+
transaction: psbt.unsigned_transaction,
|
|
185
|
+
});
|
|
187
186
|
|
|
188
187
|
const estimated = estimateFeeRate({
|
|
189
188
|
inputs: psbt.inputs,
|
|
190
|
-
outputs: tx.
|
|
189
|
+
outputs: tx.outputs.map(n => ({tokens: n.tokens})),
|
|
191
190
|
unsigned: psbt.unsigned_transaction,
|
|
192
191
|
});
|
|
193
192
|
|
|
194
193
|
// The utxos should be represented in the PSBT
|
|
195
194
|
const missing = args.utxos.find(utxo => {
|
|
196
|
-
const
|
|
195
|
+
const id = utxo.transaction_id;
|
|
197
196
|
const vout = utxo.transaction_vout;
|
|
198
197
|
|
|
199
|
-
return !tx.
|
|
198
|
+
return !tx.inputs.find(n => n.id === id && n.vout === vout);
|
|
200
199
|
});
|
|
201
200
|
|
|
202
201
|
if (!!missing) {
|
|
203
202
|
return cbk([503, 'ExpectedAllInputsRepresentedInGroupChannelPsbt']);
|
|
204
203
|
}
|
|
205
204
|
|
|
206
|
-
const outputs = tx
|
|
207
|
-
script: bufferAsHex(script),
|
|
208
|
-
tokens: value,
|
|
209
|
-
}));
|
|
205
|
+
const {outputs} = tx;
|
|
210
206
|
|
|
211
207
|
const change = outputs.find(n => n.script === args.change);
|
|
212
208
|
const funding = outputs.find(n => n.script === args.funding);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
const {
|
|
1
|
+
const {componentsOfTransaction} = require('@alexbosworth/blockchain');
|
|
2
|
+
const {sizeOfTransaction} = require('@alexbosworth/blockchain');
|
|
2
3
|
|
|
3
|
-
const {fromHex} = Transaction;
|
|
4
4
|
const sumOf = arr => arr.reduce((sum, n) => sum + n, 0);
|
|
5
5
|
|
|
6
6
|
/** Given a transaction and inputs metadata, derive transaction chain fee rate
|
|
@@ -21,9 +21,9 @@ const sumOf = arr => arr.reduce((sum, n) => sum + n, 0);
|
|
|
21
21
|
*/
|
|
22
22
|
module.exports = ({inputs, transaction}) => {
|
|
23
23
|
const inputsValue = sumOf(inputs.map(n => n.witness_utxo.tokens));
|
|
24
|
-
const
|
|
24
|
+
const {outputs} = componentsOfTransaction({transaction});
|
|
25
25
|
|
|
26
|
-
const fee = inputsValue - sumOf(
|
|
26
|
+
const fee = inputsValue - sumOf(outputs.map(n => n.tokens));
|
|
27
27
|
|
|
28
|
-
return {rate: fee /
|
|
28
|
+
return {rate: fee / sizeOfTransaction({transaction}).vsize};
|
|
29
29
|
};
|
package/package.json
CHANGED
|
@@ -22,15 +22,15 @@
|
|
|
22
22
|
"goldengate": "16.0.9",
|
|
23
23
|
"invoices": "6.3.0",
|
|
24
24
|
"ln-service": "60.1.6",
|
|
25
|
-
"ln-sync": "8.0.
|
|
25
|
+
"ln-sync": "8.0.9",
|
|
26
26
|
"psbt": "7.0.0",
|
|
27
27
|
"p2tr": "3.0.0",
|
|
28
28
|
"tiny-secp256k1": "2.2.4"
|
|
29
29
|
},
|
|
30
30
|
"description": "Lightning Paid Services library",
|
|
31
31
|
"devDependencies": {
|
|
32
|
-
"ln-docker-daemons": "8.1.
|
|
33
|
-
"mock-lnd": "4.0.
|
|
32
|
+
"ln-docker-daemons": "8.1.3",
|
|
33
|
+
"mock-lnd": "4.0.1"
|
|
34
34
|
},
|
|
35
35
|
"engines": {
|
|
36
36
|
"node": ">=22"
|
|
@@ -72,5 +72,5 @@
|
|
|
72
72
|
"integration-tests": "node test/integration",
|
|
73
73
|
"test": "node --experimental-test-coverage --test test/actions/*.js test/balanced/*.js test/client/*.js test/config/*.js test/network/*.js test/offers/*.js test/p2p/*.js test/records/*.js test/respond/*.js test/server/*.js test/service_records/*.js test/swaps/*.js test/services/*.js test/support/*.js test/trades/*.js"
|
|
74
74
|
},
|
|
75
|
-
"version": "10.3.
|
|
75
|
+
"version": "10.3.3"
|
|
76
76
|
}
|
|
@@ -10,6 +10,7 @@ const asyncTimeout = require('async/timeout');
|
|
|
10
10
|
const {beginGroupSigningSession} = require('ln-service');
|
|
11
11
|
const {broadcastChainTransaction} = require('ln-service');
|
|
12
12
|
const {cancelSwapOut} = require('goldengate');
|
|
13
|
+
const {componentsOfTransaction} = require('@alexbosworth/blockchain');
|
|
13
14
|
const {confirmationFee} = require('goldengate');
|
|
14
15
|
const {controlBlock} = require('p2tr');
|
|
15
16
|
const {createChainAddress} = require('ln-service');
|
|
@@ -25,9 +26,9 @@ const {getNetwork} = require('ln-sync');
|
|
|
25
26
|
const {getPayment} = require('ln-service');
|
|
26
27
|
const {getPublicKey} = require('ln-service');
|
|
27
28
|
const {hashForTree} = require('p2tr');
|
|
29
|
+
const {idForTransaction} = require('@alexbosworth/blockchain');
|
|
28
30
|
const {lightningLabsSwapAuth} = require('goldengate');
|
|
29
31
|
const {lightningLabsSwapService} = require('goldengate');
|
|
30
|
-
const {networks} = require('bitcoinjs-lib');
|
|
31
32
|
const {parsePaymentRequest} = require('ln-service');
|
|
32
33
|
const {pay} = require('ln-service');
|
|
33
34
|
const {payViaPaymentDetails} = require('ln-service');
|
|
@@ -36,25 +37,28 @@ const {pointFromScalar} = require('tiny-secp256k1');
|
|
|
36
37
|
const {privateAdd} = require('tiny-secp256k1');
|
|
37
38
|
const {releaseSwapOutSecret} = require('goldengate');
|
|
38
39
|
const {returnResult} = require('asyncjs-util');
|
|
39
|
-
const {
|
|
40
|
+
const {scriptAsScriptElements} = require('@alexbosworth/blockchain');
|
|
40
41
|
const {signTransaction} = require('ln-service');
|
|
42
|
+
const {sizeOfTransaction} = require('@alexbosworth/blockchain');
|
|
41
43
|
const {subscribeToBlocks} = require('ln-service');
|
|
42
44
|
const {subscribeToPastPayment} = require('ln-service');
|
|
43
45
|
const {subscribeToSpend} = require('goldengate');
|
|
44
46
|
const {swapScriptBranches} = require('goldengate');
|
|
45
47
|
const {taprootClaimTransaction} = require('goldengate');
|
|
46
48
|
const {taprootCoopTransaction} = require('goldengate');
|
|
47
|
-
const {
|
|
49
|
+
const {transactionFromComponents} = require('@alexbosworth/blockchain');
|
|
48
50
|
const {v1OutputScript} = require('p2tr');
|
|
49
51
|
|
|
52
|
+
const {bech32Prefixes} = require('./../config');
|
|
50
53
|
const decodeLoopResponse = require('./decode_loop_response');
|
|
51
54
|
const decodeOffToOnRecovery = require('./decode_off_to_on_recovery');
|
|
52
55
|
const decodeOffToOnResponse = require('./decode_off_to_on_response');
|
|
56
|
+
const {invoiceNetworks} = require('./constants');
|
|
53
57
|
const {typePayMetadata} = require('./swap_field_types');
|
|
54
58
|
|
|
55
59
|
const bufferAsHex = buffer => buffer.toString('hex');
|
|
56
60
|
const {ceil} = Math;
|
|
57
|
-
const
|
|
61
|
+
const decompileScript = script => scriptAsScriptElements({script}).elements;
|
|
58
62
|
const defaultConfsCount = 1;
|
|
59
63
|
const defaultDepositSettleTimeoutMs = 1000 * 60 * 10;
|
|
60
64
|
const defaultMaxFeeMultiplier = 1000;
|
|
@@ -66,7 +70,6 @@ const family = 805;
|
|
|
66
70
|
const {floor} = Math;
|
|
67
71
|
const format = 'p2tr';
|
|
68
72
|
const {from} = Buffer;
|
|
69
|
-
const {fromHex} = Transaction;
|
|
70
73
|
const fuzzBlocks = 100;
|
|
71
74
|
const fuzzTimelock = 1;
|
|
72
75
|
const getLoopCoopSignedTransaction = asyncTimeout(getCoopSignedTx, 1000 * 30);
|
|
@@ -86,7 +89,7 @@ const pubKeyAsInternalKey = key => Buffer.from(key).slice(1).toString('hex');
|
|
|
86
89
|
const publicKeyFor = key => Buffer.from(pointFromScalar(key, isCompressed));
|
|
87
90
|
const pushSecret = asyncTimeout(releaseSwapOutSecret, 1000 * 30);
|
|
88
91
|
const sha256 = preimage => createHash('sha256').update(preimage).digest('hex');
|
|
89
|
-
const
|
|
92
|
+
const sighashDefault = 0;
|
|
90
93
|
const slowConfs = 144 * 7;
|
|
91
94
|
const sumOf = arr => arr.reduce((sum, n) => sum + n, 0);
|
|
92
95
|
const sweepInputIndex = 0;
|
|
@@ -220,7 +223,7 @@ module.exports = (args, cbk) => {
|
|
|
220
223
|
if (!!args.is_loop_service) {
|
|
221
224
|
try {
|
|
222
225
|
const details = decodeLoopResponse({
|
|
223
|
-
network: getNetwork.
|
|
226
|
+
network: invoiceNetworks[getNetwork.network],
|
|
224
227
|
response: args.response,
|
|
225
228
|
});
|
|
226
229
|
|
|
@@ -243,7 +246,7 @@ module.exports = (args, cbk) => {
|
|
|
243
246
|
try {
|
|
244
247
|
// Decode the response
|
|
245
248
|
const decoded = decodeOffToOnResponse({
|
|
246
|
-
network: getNetwork.
|
|
249
|
+
network: invoiceNetworks[getNetwork.network],
|
|
247
250
|
response: args.response,
|
|
248
251
|
});
|
|
249
252
|
|
|
@@ -680,9 +683,9 @@ module.exports = (args, cbk) => {
|
|
|
680
683
|
'swap',
|
|
681
684
|
({deadline, getNetwork, requestDetails, startHeight, swap}, cbk) =>
|
|
682
685
|
{
|
|
683
|
-
const [, key] =
|
|
686
|
+
const [, key] = decompileScript(swap.output_script);
|
|
684
687
|
const outputScript = swap.output_script;
|
|
685
|
-
const prefix =
|
|
688
|
+
const prefix = bech32Prefixes[getNetwork.network];
|
|
686
689
|
|
|
687
690
|
const {address} = encodeBech32Address({
|
|
688
691
|
prefix,
|
|
@@ -840,11 +843,11 @@ module.exports = (args, cbk) => {
|
|
|
840
843
|
return signTransaction({
|
|
841
844
|
transaction,
|
|
842
845
|
inputs: [{
|
|
843
|
-
sighash,
|
|
844
846
|
key_family: family,
|
|
845
847
|
key_index: requestDetails.key_index,
|
|
846
848
|
output_script: swap.output_script,
|
|
847
849
|
output_tokens: requestDetails.tokens,
|
|
850
|
+
sighash: sighashDefault,
|
|
848
851
|
vin: sweepInputIndex,
|
|
849
852
|
witness_script: swap.claim_script,
|
|
850
853
|
}],
|
|
@@ -871,14 +874,23 @@ module.exports = (args, cbk) => {
|
|
|
871
874
|
block,
|
|
872
875
|
];
|
|
873
876
|
|
|
874
|
-
const tx =
|
|
877
|
+
const tx = componentsOfTransaction({transaction});
|
|
875
878
|
|
|
876
879
|
// Add the signature to the sweep
|
|
877
|
-
|
|
878
|
-
|
|
880
|
+
const signed = transactionFromComponents({
|
|
881
|
+
inputs: tx.inputs.map(input => ({
|
|
882
|
+
witness,
|
|
883
|
+
id: input.id,
|
|
884
|
+
script: input.script,
|
|
885
|
+
sequence: input.sequence,
|
|
886
|
+
vout: input.vout,
|
|
887
|
+
})),
|
|
888
|
+
locktime: tx.locktime,
|
|
889
|
+
outputs: tx.outputs,
|
|
890
|
+
version: tx.version,
|
|
879
891
|
});
|
|
880
892
|
|
|
881
|
-
return cbk(null, {height, transaction:
|
|
893
|
+
return cbk(null, {height, transaction: signed.transaction});
|
|
882
894
|
});
|
|
883
895
|
},
|
|
884
896
|
cbk);
|
|
@@ -1229,15 +1241,15 @@ module.exports = (args, cbk) => {
|
|
|
1229
1241
|
|
|
1230
1242
|
const [{transaction}] = broadcast.reverse();
|
|
1231
1243
|
|
|
1232
|
-
const
|
|
1244
|
+
const {outputs} = componentsOfTransaction({transaction});
|
|
1233
1245
|
|
|
1234
|
-
const fee = requestDetails.tokens - sumOf(
|
|
1246
|
+
const fee = requestDetails.tokens - sumOf(outputs.map(n => n.tokens));
|
|
1235
1247
|
|
|
1236
1248
|
args.emitter.emit('update', {
|
|
1237
1249
|
blocks_until_potential_funds_forfeit: swap.timeout - block.height,
|
|
1238
|
-
broadcasting_fee_rate: fee /
|
|
1250
|
+
broadcasting_fee_rate: fee / sizeOfTransaction({transaction}).vsize,
|
|
1239
1251
|
broadcasting_tx_to_resolve_swap: transaction,
|
|
1240
|
-
broadcasting_tx_id:
|
|
1252
|
+
broadcasting_tx_id: idForTransaction({transaction}).id,
|
|
1241
1253
|
});
|
|
1242
1254
|
|
|
1243
1255
|
return broadcastChainTransaction({
|
|
@@ -1251,11 +1263,13 @@ module.exports = (args, cbk) => {
|
|
|
1251
1263
|
|
|
1252
1264
|
// Look for the sweep to confirm
|
|
1253
1265
|
subSpend.on('confirmation', ({transaction}) => {
|
|
1254
|
-
const
|
|
1266
|
+
const {outputs} = componentsOfTransaction({transaction});
|
|
1255
1267
|
|
|
1256
|
-
const fee = requestDetails.tokens - sumOf(
|
|
1268
|
+
const fee = requestDetails.tokens - sumOf(outputs.map(n => n.tokens));
|
|
1257
1269
|
|
|
1258
|
-
|
|
1270
|
+
const {vsize} = sizeOfTransaction({transaction});
|
|
1271
|
+
|
|
1272
|
+
return done(null, {fee: fee, rate: fee / vsize});
|
|
1259
1273
|
});
|
|
1260
1274
|
|
|
1261
1275
|
subSpend.on('error', err => done(err));
|
|
@@ -5,6 +5,7 @@ const asyncMap = require('async/map');
|
|
|
5
5
|
const asyncReflect = require('async/reflect');
|
|
6
6
|
const {broadcastChainTransaction} = require('ln-service');
|
|
7
7
|
const {cancelHodlInvoice} = require('ln-service');
|
|
8
|
+
const {componentsOfTransaction} = require('@alexbosworth/blockchain');
|
|
8
9
|
const {confirmationFee} = require('goldengate');
|
|
9
10
|
const {controlBlock} = require('p2tr');
|
|
10
11
|
const {createChainAddress} = require('ln-service');
|
|
@@ -21,6 +22,7 @@ const {getInvoice} = require('ln-service');
|
|
|
21
22
|
const {getNetwork} = require('ln-sync');
|
|
22
23
|
const {getPublicKey} = require('ln-service');
|
|
23
24
|
const {hashForTree} = require('p2tr');
|
|
25
|
+
const {idForTransaction} = require('@alexbosworth/blockchain');
|
|
24
26
|
const {pointAdd} = require('tiny-secp256k1');
|
|
25
27
|
const {pointFromScalar} = require('tiny-secp256k1');
|
|
26
28
|
const {returnResult} = require('asyncjs-util');
|
|
@@ -33,7 +35,7 @@ const {subscribeToInvoice} = require('ln-service');
|
|
|
33
35
|
const {subscribeToSpend} = require('goldengate');
|
|
34
36
|
const {swapScriptBranches} = require('goldengate');
|
|
35
37
|
const {taprootRefundTransaction} = require('goldengate');
|
|
36
|
-
const {
|
|
38
|
+
const {transactionFromComponents} = require('@alexbosworth/blockchain');
|
|
37
39
|
const {v1OutputScript} = require('p2tr');
|
|
38
40
|
|
|
39
41
|
const decodeOnToOffRecovery = require('./decode_on_to_off_recovery');
|
|
@@ -48,13 +50,13 @@ const flatten = arr => [].concat(...arr);
|
|
|
48
50
|
const {floor} = Math;
|
|
49
51
|
const format = 'p2tr';
|
|
50
52
|
const {from} = Buffer;
|
|
51
|
-
const {fromHex} = Transaction;
|
|
52
53
|
const fuzzBlocks = 100;
|
|
53
54
|
const hexAsBase64 = hex => Buffer.from(hex, 'hex').toString('base64');
|
|
54
55
|
const hexAsBuffer = hex => Buffer.from(hex, 'hex');
|
|
55
56
|
const historicBlocksRange = 144 * 30;
|
|
56
|
-
const isAnnex = element => element
|
|
57
|
+
const isAnnex = element => element.startsWith('50');
|
|
57
58
|
const isCompressed = true;
|
|
59
|
+
const locktimeOf = tx => componentsOfTransaction({transaction: tx}).locktime;
|
|
58
60
|
const maxRefundMultiple = (r, t) => Math.min(100, ((1000 + t) / 150) / r);
|
|
59
61
|
const {min} = Math;
|
|
60
62
|
const minBlocks = 50;
|
|
@@ -64,7 +66,7 @@ const pubKeyAsSecret = hexPublicKey => hexPublicKey.slice(2);
|
|
|
64
66
|
const publicKeyFor = key => Buffer.from(pointFromScalar(key, isCompressed));
|
|
65
67
|
const removeAnnex = stack => stack.slice(0, -1);
|
|
66
68
|
const sha256 = preimage => createHash('sha256').update(preimage).digest('hex');
|
|
67
|
-
const
|
|
69
|
+
const sighashDefault = 0;
|
|
68
70
|
const slowTarget = 144 * 7;
|
|
69
71
|
const sweepInputIndex = 0;
|
|
70
72
|
const times = n => Array(n).fill(null).map((_, i) => i);
|
|
@@ -404,11 +406,11 @@ module.exports = (args, cbk) => {
|
|
|
404
406
|
return signTransaction({
|
|
405
407
|
transaction,
|
|
406
408
|
inputs: [{
|
|
407
|
-
sighash,
|
|
408
409
|
key_family: family,
|
|
409
410
|
key_index: recoveryDetails.key_index,
|
|
410
411
|
output_script: swap.output_script,
|
|
411
412
|
output_tokens: recoveryDetails.tokens,
|
|
413
|
+
sighash: sighashDefault,
|
|
412
414
|
vin: sweepInputIndex,
|
|
413
415
|
witness_script: swap.refund_script,
|
|
414
416
|
}],
|
|
@@ -430,14 +432,23 @@ module.exports = (args, cbk) => {
|
|
|
430
432
|
|
|
431
433
|
const witness = [signature, swap.refund_script, block];
|
|
432
434
|
|
|
433
|
-
const tx =
|
|
435
|
+
const tx = componentsOfTransaction({transaction});
|
|
434
436
|
|
|
435
437
|
// Add the signature to the sweep
|
|
436
|
-
|
|
437
|
-
|
|
438
|
+
const signed = transactionFromComponents({
|
|
439
|
+
inputs: tx.inputs.map(input => ({
|
|
440
|
+
witness,
|
|
441
|
+
id: input.id,
|
|
442
|
+
script: input.script,
|
|
443
|
+
sequence: input.sequence,
|
|
444
|
+
vout: input.vout,
|
|
445
|
+
})),
|
|
446
|
+
locktime: tx.locktime,
|
|
447
|
+
outputs: tx.outputs,
|
|
448
|
+
version: tx.version,
|
|
438
449
|
});
|
|
439
450
|
|
|
440
|
-
return cbk(null,
|
|
451
|
+
return cbk(null, signed.transaction);
|
|
441
452
|
});
|
|
442
453
|
},
|
|
443
454
|
cbk);
|
|
@@ -525,12 +536,18 @@ module.exports = (args, cbk) => {
|
|
|
525
536
|
({getTransactions, swap}, cbk) =>
|
|
526
537
|
{
|
|
527
538
|
const tx = getTransactions.transactions.find(({transaction}) => {
|
|
528
|
-
|
|
529
|
-
|
|
539
|
+
if (!transaction) {
|
|
540
|
+
return false;
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
const {outputs} = componentsOfTransaction({transaction});
|
|
544
|
+
|
|
545
|
+
return !!outputs.find(output => {
|
|
546
|
+
if (output.tokens !== swap.tokens) {
|
|
530
547
|
return false;
|
|
531
548
|
}
|
|
532
549
|
|
|
533
|
-
return
|
|
550
|
+
return output.script === swap.output_script;
|
|
534
551
|
});
|
|
535
552
|
});
|
|
536
553
|
|
|
@@ -567,11 +584,12 @@ module.exports = (args, cbk) => {
|
|
|
567
584
|
|
|
568
585
|
// Output funding the swap on chain
|
|
569
586
|
outpoint: ['signFunding', 'swap', ({signFunding, swap}, cbk) => {
|
|
570
|
-
const
|
|
571
|
-
|
|
587
|
+
const {transaction} = signFunding;
|
|
588
|
+
|
|
589
|
+
const {outputs} = componentsOfTransaction({transaction});
|
|
572
590
|
|
|
573
|
-
const id =
|
|
574
|
-
const vout =
|
|
591
|
+
const {id} = idForTransaction({transaction});
|
|
592
|
+
const vout = outputs.findIndex(n => n.script === swap.output_script);
|
|
575
593
|
|
|
576
594
|
args.emitter.emit('update', {
|
|
577
595
|
funding_transaction: signFunding.transaction,
|
|
@@ -592,7 +610,7 @@ module.exports = (args, cbk) => {
|
|
|
592
610
|
|
|
593
611
|
args.emitter.emit('update', {
|
|
594
612
|
refund_transaction: refund,
|
|
595
|
-
refund_valid_at:
|
|
613
|
+
refund_valid_at: locktimeOf(refund),
|
|
596
614
|
});
|
|
597
615
|
|
|
598
616
|
// Exit early when the transaction was already published
|
|
@@ -682,12 +700,10 @@ module.exports = (args, cbk) => {
|
|
|
682
700
|
|
|
683
701
|
// Look for the preimage to be used on-chain in a sweep
|
|
684
702
|
subSpend.on('confirmation', ({transaction}) => {
|
|
685
|
-
const
|
|
686
|
-
if (!input.hash.equals(hexAsBuffer(outpoint.id).reverse())) {
|
|
687
|
-
return false;
|
|
688
|
-
}
|
|
703
|
+
const {inputs} = componentsOfTransaction({transaction});
|
|
689
704
|
|
|
690
|
-
|
|
705
|
+
const spend = inputs.find(input => {
|
|
706
|
+
return input.id === outpoint.id && input.vout === outpoint.vout;
|
|
691
707
|
});
|
|
692
708
|
|
|
693
709
|
const [lastElement, nextToLast] = spend.witness.slice().reverse();
|
|
@@ -722,7 +738,7 @@ module.exports = (args, cbk) => {
|
|
|
722
738
|
|
|
723
739
|
const [secret] = stack;
|
|
724
740
|
|
|
725
|
-
return done(null, {secret
|
|
741
|
+
return done(null, {secret});
|
|
726
742
|
});
|
|
727
743
|
|
|
728
744
|
subSpend.on('error', err => done(err));
|
|
@@ -739,7 +755,7 @@ module.exports = (args, cbk) => {
|
|
|
739
755
|
// Find the latest valid refund transaction
|
|
740
756
|
const [transaction] = signRefunds
|
|
741
757
|
.filter(transaction => {
|
|
742
|
-
return
|
|
758
|
+
return locktimeOf(transaction) <= block.height;
|
|
743
759
|
})
|
|
744
760
|
.reverse();
|
|
745
761
|
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"invoiceNetworks": {
|
|
3
|
+
"btc": "bitcoin",
|
|
4
|
+
"btcregtest": "regtest",
|
|
5
|
+
"btcsignet": "signet",
|
|
6
|
+
"btctestnet": "testnet",
|
|
7
|
+
"btctestnet4": "testnet"
|
|
8
|
+
},
|
|
9
|
+
"minConfirmations": {
|
|
10
|
+
"btc": 2,
|
|
11
|
+
"btcregtest": 3,
|
|
12
|
+
"btcsignet": 1,
|
|
13
|
+
"btctestnet": 1,
|
|
14
|
+
"btctestnet4": 1
|
|
15
|
+
}
|
|
16
|
+
}
|
package/swaps/manage_swap.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
const {address} = require('bitcoinjs-lib');
|
|
2
1
|
const asyncAuto = require('async/auto');
|
|
3
2
|
const asyncMap = require('async/map');
|
|
4
3
|
const {findKey} = require('ln-sync');
|
|
@@ -7,13 +6,13 @@ const {getAllInvoices} = require('ln-sync');
|
|
|
7
6
|
const {getInvoice} = require('ln-service');
|
|
8
7
|
const {getNetwork} = require('ln-sync');
|
|
9
8
|
const {getNodeAlias} = require('ln-sync');
|
|
10
|
-
const {
|
|
9
|
+
const {outputScriptForAddress} = require('@alexbosworth/blockchain');
|
|
11
10
|
const {returnResult} = require('asyncjs-util');
|
|
12
11
|
|
|
13
12
|
const decodeOffToOnRequest = require('./decode_off_to_on_request');
|
|
14
13
|
const decodeOffToOnRestart = require('./decode_off_to_on_restart');
|
|
15
14
|
const {decodeTrade} = require('./../trades');
|
|
16
|
-
const
|
|
15
|
+
const {minConfirmations} = require('./constants');
|
|
17
16
|
const recoverResponseToSwapOut = require('./recover_response_to_swap_out');
|
|
18
17
|
const requestSwapOut = require('./request_swap_out');
|
|
19
18
|
const respondToSwapOutRequest = require('./respond_to_swap_out_request');
|
|
@@ -24,14 +23,12 @@ const actionRestartRequest = 'restart-request';
|
|
|
24
23
|
const allowedNetwork = 'btctestnet';
|
|
25
24
|
const bip86Path = `m/86'/0'/0'`;
|
|
26
25
|
const flatten = arr => [].concat(...arr);
|
|
27
|
-
const minConfirmations = {btc: 2, btcregtest: 3, btctestnet: 1};
|
|
28
26
|
const niceId = id => id.substring(0, 8);
|
|
29
27
|
const niceName = node => `${node.alias} ${node.id.substring(0, 8)}`.trim();
|
|
30
28
|
const pushesReceivedAfter = () => new Date(Date.now() - 1000 * 60 * 60 * 24);
|
|
31
29
|
const recoverRespondAction = 'recover-response';
|
|
32
30
|
const requestAction = 'request';
|
|
33
31
|
const respondAction = 'respond';
|
|
34
|
-
const {toOutputScript} = address;
|
|
35
32
|
const tokensAsBigUnit = tokens => (tokens / 1e8).toFixed(8);
|
|
36
33
|
const typeKeySendTrade = '805805';
|
|
37
34
|
|
|
@@ -314,7 +311,7 @@ module.exports = (args, cbk) => {
|
|
|
314
311
|
try {
|
|
315
312
|
return !!outputScriptForAddress({
|
|
316
313
|
address: input,
|
|
317
|
-
network: getNetwork.
|
|
314
|
+
network: getNetwork.network,
|
|
318
315
|
});
|
|
319
316
|
} catch (err) {
|
|
320
317
|
return 'Unsupported on-chain address format';
|
|
@@ -20,6 +20,7 @@ const decodeOffToOnRequest = require('./decode_off_to_on_request');
|
|
|
20
20
|
const decodeOffToOnResponse = require('./decode_off_to_on_response');
|
|
21
21
|
const encodeOffToOnRestart = require('./encode_off_to_on_restart');
|
|
22
22
|
const {encodeTrade} = require('./../trades');
|
|
23
|
+
const {invoiceNetworks} = require('./constants');
|
|
23
24
|
const makeRequest = require('./start_off_to_on_swap');
|
|
24
25
|
const {pushTypes} = require('./swap_field_types');
|
|
25
26
|
const requestLoopOut = require('./request_loop_out');
|
|
@@ -251,7 +252,10 @@ module.exports = (args, cbk) => {
|
|
|
251
252
|
|
|
252
253
|
// Check the swap response is valid
|
|
253
254
|
try {
|
|
254
|
-
decodeOffToOnResponse({
|
|
255
|
+
decodeOffToOnResponse({
|
|
256
|
+
response,
|
|
257
|
+
network: invoiceNetworks[getNetwork.network],
|
|
258
|
+
});
|
|
255
259
|
} catch (err) {
|
|
256
260
|
return res.failure([400, err.message]);
|
|
257
261
|
}
|
|
@@ -373,7 +377,10 @@ module.exports = (args, cbk) => {
|
|
|
373
377
|
}
|
|
374
378
|
|
|
375
379
|
try {
|
|
376
|
-
decodeOffToOnResponse({
|
|
380
|
+
decodeOffToOnResponse({
|
|
381
|
+
response,
|
|
382
|
+
network: invoiceNetworks[getNetwork.network],
|
|
383
|
+
});
|
|
377
384
|
} catch (err) {
|
|
378
385
|
return 'Failed parse this response, check input?';
|
|
379
386
|
}
|
|
@@ -395,7 +402,7 @@ module.exports = (args, cbk) => {
|
|
|
395
402
|
// Exit early when the request is to Lightning Loop
|
|
396
403
|
if (!!args.is_loop_service) {
|
|
397
404
|
const details = decodeLoopResponse({
|
|
398
|
-
network: getNetwork.
|
|
405
|
+
network: invoiceNetworks[getNetwork.network],
|
|
399
406
|
response: getResponse,
|
|
400
407
|
});
|
|
401
408
|
|
|
@@ -414,7 +421,7 @@ module.exports = (args, cbk) => {
|
|
|
414
421
|
}
|
|
415
422
|
|
|
416
423
|
const response = decodeOffToOnResponse({
|
|
417
|
-
network: getNetwork.
|
|
424
|
+
network: invoiceNetworks[getNetwork.network],
|
|
418
425
|
response: getResponse,
|
|
419
426
|
});
|
|
420
427
|
|
|
@@ -6,11 +6,11 @@ const {diffieHellmanComputeSecret} = require('ln-service');
|
|
|
6
6
|
const {getIdentity} = require('ln-service');
|
|
7
7
|
const {getNetwork} = require('ln-sync');
|
|
8
8
|
const {getPublicKey} = require('ln-service');
|
|
9
|
-
const {networks} = require('bitcoinjs-lib');
|
|
10
9
|
const {pointFromScalar} = require('tiny-secp256k1');
|
|
11
10
|
const {returnResult} = require('asyncjs-util');
|
|
12
11
|
|
|
13
12
|
const encodeOffToOnRequest = require('./encode_off_to_on_request');
|
|
13
|
+
const {invoiceNetworks} = require('./constants');
|
|
14
14
|
const makePrivateKey = require('./make_private_key');
|
|
15
15
|
|
|
16
16
|
const bufferAsHex = buffer => buffer.toString('hex');
|
|
@@ -77,15 +77,13 @@ module.exports = (args, cbk) => {
|
|
|
77
77
|
// Get the network name for creating the private key
|
|
78
78
|
getNetwork: ['validate', ({}, cbk) => getNetwork({lnd: args.lnd}, cbk)],
|
|
79
79
|
|
|
80
|
-
//
|
|
80
|
+
// Check that the network is supported
|
|
81
81
|
network: ['getNetwork', ({getNetwork}, cbk) => {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
if (!network) {
|
|
82
|
+
if (!invoiceNetworks[getNetwork.network]) {
|
|
85
83
|
return cbk([400, 'UnsupportedNetworkToStartOffToOnSwapOn']);
|
|
86
84
|
}
|
|
87
85
|
|
|
88
|
-
return cbk(null, network);
|
|
86
|
+
return cbk(null, getNetwork.network);
|
|
89
87
|
}],
|
|
90
88
|
|
|
91
89
|
// Generate the claim coop key
|
|
@@ -7,13 +7,13 @@ const {getHeight} = require('ln-service');
|
|
|
7
7
|
const {getIdentity} = require('ln-service');
|
|
8
8
|
const {getNetwork} = require('ln-sync');
|
|
9
9
|
const {getPublicKey} = require('ln-service');
|
|
10
|
-
const {networks} = require('bitcoinjs-lib');
|
|
11
10
|
const {parsePaymentRequest} = require('ln-service');
|
|
12
11
|
const {pointFromScalar} = require('tiny-secp256k1');
|
|
13
12
|
const {returnResult} = require('asyncjs-util');
|
|
14
13
|
|
|
15
14
|
const decodeOffToOnRequest = require('./decode_off_to_on_request');
|
|
16
15
|
const encodeOffToOnResponse = require('./encode_off_to_on_response');
|
|
16
|
+
const {invoiceNetworks} = require('./constants');
|
|
17
17
|
const makePrivateKey = require('./make_private_key');
|
|
18
18
|
|
|
19
19
|
const bufferAsHex = buffer => buffer.toString('hex');
|
|
@@ -107,15 +107,13 @@ module.exports = (args, cbk) => {
|
|
|
107
107
|
});
|
|
108
108
|
}],
|
|
109
109
|
|
|
110
|
-
//
|
|
110
|
+
// Check that the network is supported
|
|
111
111
|
network: ['getNetwork', ({getNetwork}, cbk) => {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
if (!network) {
|
|
112
|
+
if (!invoiceNetworks[getNetwork.network]) {
|
|
115
113
|
return cbk([400, 'UnsupportedNetworkForOnToOffSwap']);
|
|
116
114
|
}
|
|
117
115
|
|
|
118
|
-
return cbk(null, network);
|
|
116
|
+
return cbk(null, getNetwork.network);
|
|
119
117
|
}],
|
|
120
118
|
|
|
121
119
|
// Generate the refund coop key
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
const {address} = require('bitcoinjs-lib');
|
|
2
|
-
const {networks} = require('bitcoinjs-lib');
|
|
3
|
-
|
|
4
|
-
const bufferAsHex = buffer => buffer.toString('hex');
|
|
5
|
-
const byteLengthForP2tr = 32;
|
|
6
|
-
const {fromBech32} = address;
|
|
7
|
-
const prefixForP2tr = '5120';
|
|
8
|
-
const toOutputScript = (a, n) => address.toOutputScript(a, n).toString('hex');
|
|
9
|
-
const versionTaproot = 1;
|
|
10
|
-
|
|
11
|
-
/** Get the output script for an address
|
|
12
|
-
|
|
13
|
-
{
|
|
14
|
-
address: <Address String>
|
|
15
|
-
network: <BitcoinJs Network Name String>
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
@throws
|
|
19
|
-
<Error>
|
|
20
|
-
|
|
21
|
-
@returns
|
|
22
|
-
{
|
|
23
|
-
script: <Output Script Hex String>
|
|
24
|
-
}
|
|
25
|
-
*/
|
|
26
|
-
module.exports = ({address, network}) => {
|
|
27
|
-
try {
|
|
28
|
-
return {
|
|
29
|
-
script: bufferAsHex(toOutputScript(address, networks[network])),
|
|
30
|
-
};
|
|
31
|
-
} catch (err) {
|
|
32
|
-
// Exit early when this is not a bech32 address
|
|
33
|
-
try {
|
|
34
|
-
fromBech32(address);
|
|
35
|
-
} catch (_) {
|
|
36
|
-
throw err;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
const {data, prefix, version} = fromBech32(address);
|
|
40
|
-
|
|
41
|
-
if (prefix !== networks[network].bech32) {
|
|
42
|
-
throw new Error('InvalidNetworkToConvertAddressToOutputScript');
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
if (version !== versionTaproot) {
|
|
46
|
-
throw new Error('UnexpectedVersionOfAddressToConverToOutputScript');
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
if (data.length !== byteLengthForP2tr) {
|
|
50
|
-
throw new Error('UnexpectedByteLengthForPayToTaprootAddress');
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
return {script: `${prefixForP2tr}${bufferAsHex(data)}`};
|
|
54
|
-
}
|
|
55
|
-
};
|