paid-services 3.3.0 → 3.6.0
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/.prettierignore +2 -0
- package/CHANGELOG.md +17 -0
- package/capacity/accept_capacity_change.js +3 -3
- package/capacity/ask_for_change_details.js +34 -1
- package/capacity/capacity_change_requests.js +9 -0
- package/capacity/change_channel_capacity.js +7 -1
- package/capacity/encode_change_request.js +8 -1
- package/capacity/fee_for_replacement.js +1 -1
- package/capacity/get_capacity_change_requests.js +2 -1
- package/capacity/get_capacity_replacement.js +1 -1
- package/capacity/initiate_capacity_change.js +5 -5
- package/capacity/parse_capacity_change_request.js +8 -1
- package/capacity/propose_capacity_change.js +4 -1
- package/p2p/service_peer_requests.js +10 -2
- package/package.json +10 -9
- package/service_types.json +16 -0
- package/services/response_for_relay.js +0 -1
- package/test/capacity/test_capacity_change_requests.js +1 -0
- package/test/capacity/test_encode_change_request.js +5 -0
- package/test/capacity/test_parse_capacity_change_request.js +1 -0
- package/test/integration/test_accept_capacity_change.js +50 -14
- package/test/integration/test_change_channel_capacity.js +7 -1
- package/test/integration/test_decrease_channel_capacity.js +16 -7
- package/test/integration/test_increase_channel_capacity.js +4 -1
- package/test/trades/test_decode_basic_trade.js +40 -0
- package/test/trades/test_decode_open_trade.js +50 -0
- package/test/trades/test_encode_open_trade.js +35 -0
- package/test/trades/test_encode_trade.js +37 -0
- package/trades/accept_trade.js +61 -0
- package/trades/create_trade.js +149 -37
- package/trades/decode_anchored_trade.js +56 -0
- package/trades/decode_basic_trade.js +45 -0
- package/trades/decode_open_trade.js +69 -0
- package/trades/decode_trade.js +48 -66
- package/trades/decode_trade_secret.js +89 -0
- package/trades/encode_anchored_trade.js +35 -0
- package/trades/encode_open_trade.js +89 -0
- package/trades/encode_trade.js +48 -33
- package/trades/encode_trade_secret.js +50 -0
- package/trades/finalize_trade_secret.js +123 -0
- package/trades/find_trade.js +339 -0
- package/trades/manage_trade.js +61 -39
- package/trades/manage_trades.js +209 -2
- package/trades/network_from_network_record.js +3 -3
- package/trades/network_record_from_network.js +36 -0
- package/trades/network_record_from_request.js +2 -1
- package/trades/node_as_record.js +98 -0
- package/trades/record_as_node.js +113 -0
- package/trades/request_trade_by_id.js +95 -0
- package/trades/service_anchored_trades.js +181 -0
- package/trades/service_open_trade.js +172 -0
- package/trades/service_trade_requests.js +255 -0
- package/trades/trade_from_invoice.js +51 -0
- package/capacity/service_types.json +0 -6
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
const {decodeTlvStream} = require('bolt01');
|
|
2
|
+
|
|
3
|
+
const recordAsNode = require('./record_as_node');
|
|
4
|
+
|
|
5
|
+
const findIdRecord = records => records.find(n => n.type === '5');
|
|
6
|
+
const findNodesRecord = records => records.find(n => n.type === '4');
|
|
7
|
+
const {isArray} = Array;
|
|
8
|
+
|
|
9
|
+
/** Decode open trade records
|
|
10
|
+
|
|
11
|
+
An open ended trade is a pointer to a node or nodes that can create trade
|
|
12
|
+
invoices.
|
|
13
|
+
|
|
14
|
+
4: <Nodes Records>
|
|
15
|
+
[5]: <Trade Identifier>
|
|
16
|
+
|
|
17
|
+
{
|
|
18
|
+
network: <Network Name String>
|
|
19
|
+
records: [{
|
|
20
|
+
type: <Type Number String>
|
|
21
|
+
value: <Value Hex Encoded String>
|
|
22
|
+
}]
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
@throws
|
|
26
|
+
<Error>
|
|
27
|
+
|
|
28
|
+
@returns
|
|
29
|
+
{
|
|
30
|
+
[id]: <Trade Identifier Hex String>
|
|
31
|
+
network: <Network Name String>
|
|
32
|
+
nodes: [{
|
|
33
|
+
[high_channel]: <High Key Channel Id String>
|
|
34
|
+
[low_channel]: <Low Key Channel Id String>
|
|
35
|
+
[node]: {
|
|
36
|
+
id: <Node Public Key Id Hex String>
|
|
37
|
+
sockets: [<Peer Socket String>]
|
|
38
|
+
}
|
|
39
|
+
}]
|
|
40
|
+
}
|
|
41
|
+
*/
|
|
42
|
+
module.exports = ({network, records}) => {
|
|
43
|
+
if (!network) {
|
|
44
|
+
throw new Error('ExpectedNetworkNameToDecodeOpenTrade');
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (!isArray(records)) {
|
|
48
|
+
throw new Error('ExpectedArrayOfRecordsToDecodeOpenTrade');
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const idRecord = findIdRecord(records);
|
|
52
|
+
const nodesRecord = findNodesRecord(records);
|
|
53
|
+
|
|
54
|
+
if (!nodesRecord) {
|
|
55
|
+
throw new Error('ExpectedNodesRecordToDecodeOpenTradeDetails');
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const nodeRecords = decodeTlvStream({encoded: nodesRecord.value}).records;
|
|
59
|
+
|
|
60
|
+
if (!nodeRecords.length) {
|
|
61
|
+
throw new Error('ExpectedNodeRecordsForOpenTrade');
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return {
|
|
65
|
+
network,
|
|
66
|
+
id: !!idRecord ? idRecord.value : undefined,
|
|
67
|
+
nodes: nodeRecords.map(({value}) => recordAsNode({encoded: value})),
|
|
68
|
+
};
|
|
69
|
+
};
|
package/trades/decode_trade.js
CHANGED
|
@@ -1,32 +1,49 @@
|
|
|
1
|
+
const {decodeBigSize} = require('bolt01');
|
|
1
2
|
const {decodeTlvStream} = require('bolt01');
|
|
2
3
|
|
|
4
|
+
const decodeOpenTrade = require('./decode_open_trade');
|
|
5
|
+
const decodeTradeSecret = require('./decode_trade_secret');
|
|
3
6
|
const networkFromNetworkRecord = require('./network_from_network_record');
|
|
4
|
-
const {requestRecordsAsRequest} = require('./../records');
|
|
5
7
|
|
|
6
|
-
const findAuth = records => records.find(n => n.type === '1');
|
|
7
|
-
const findCipher = records => records.find(n => n.type === '0');
|
|
8
|
-
const findDetails = records => records.find(n => n.type === '3');
|
|
9
|
-
const findEncrypt = records => records.find(n => n.type === '0');
|
|
10
8
|
const findNetwork = records => records.find(n => n.type === '1');
|
|
11
|
-
const
|
|
12
|
-
const
|
|
9
|
+
const findVer = records => records.find(n => n.type === '0') || {value: '00'};
|
|
10
|
+
const findRequestRecord = records => records.find(n => n.type === '2');
|
|
13
11
|
const isTrade = trade => trade.toLowerCase().startsWith('626f73ff');
|
|
12
|
+
const isValidVersion = version => BigInt(version) <= BigInt(1);
|
|
14
13
|
const tradeData = trade => trade.slice('626f73ff'.length);
|
|
15
14
|
|
|
16
|
-
/**
|
|
15
|
+
/** Decode a trade record
|
|
16
|
+
|
|
17
|
+
[0]: <Version Record>
|
|
18
|
+
[1]: <Network Name Record>
|
|
19
|
+
[2]: <Payment Request Record>
|
|
20
|
+
[3]: <Trade Details Record
|
|
21
|
+
[4]: <Nodes Records>
|
|
22
|
+
[5]: <Trade Identifier>
|
|
17
23
|
|
|
18
24
|
{
|
|
19
|
-
trade: <
|
|
25
|
+
trade: <Trade Record Hex String>
|
|
20
26
|
}
|
|
21
27
|
|
|
22
|
-
@throws
|
|
23
|
-
<Error>
|
|
24
|
-
|
|
25
28
|
@returns
|
|
26
29
|
{
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
+
[connect]: {
|
|
31
|
+
[id]: <Reference Trade Id Hex String>
|
|
32
|
+
network: <Network Name String>
|
|
33
|
+
nodes: [{
|
|
34
|
+
[high_channel]: <High Key Channel Id String>
|
|
35
|
+
[low_channel]: <Low Key Channel Id String>
|
|
36
|
+
[node]: {
|
|
37
|
+
id: <Node Public Key Id Hex String>
|
|
38
|
+
sockets: [<Peer Socket String>]
|
|
39
|
+
}
|
|
40
|
+
}]
|
|
41
|
+
}
|
|
42
|
+
[secret]: {
|
|
43
|
+
auth: <Encrypted Payload Auth Hex String>
|
|
44
|
+
payload: <Preimage Encrypted Payload Hex String>
|
|
45
|
+
request: <BOLT 11 Payment Request String>
|
|
46
|
+
}
|
|
30
47
|
}
|
|
31
48
|
*/
|
|
32
49
|
module.exports = ({trade}) => {
|
|
@@ -45,64 +62,29 @@ module.exports = ({trade}) => {
|
|
|
45
62
|
}
|
|
46
63
|
|
|
47
64
|
// Decode the overall packet
|
|
48
|
-
const
|
|
65
|
+
const {records} = decodeTlvStream({encoded: tradeData(trade)});
|
|
49
66
|
|
|
50
67
|
// Get the trade version
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
if (!!version) {
|
|
54
|
-
throw new Error('UnexpectedVersionOfTradeData');
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// Get the network record
|
|
58
|
-
const networkRecord = findNetwork(tradeRecords) || {};
|
|
59
|
-
|
|
60
|
-
// Get the payment request record
|
|
61
|
-
const requestRecord = findRequest(tradeRecords);
|
|
62
|
-
|
|
63
|
-
if (!requestRecord) {
|
|
64
|
-
throw new Error('ExpectedRequestRecordInTradeData');
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
const {request} = requestRecordsAsRequest({
|
|
68
|
-
network: networkFromNetworkRecord({value: networkRecord.value}),
|
|
69
|
-
encoded: requestRecord.value,
|
|
70
|
-
});
|
|
68
|
+
const versionRecord = findVer(records);
|
|
71
69
|
|
|
72
|
-
//
|
|
73
|
-
const
|
|
70
|
+
// Decode the version number
|
|
71
|
+
const version = decodeBigSize({encoded: versionRecord.value}).decoded;
|
|
74
72
|
|
|
75
|
-
|
|
76
|
-
|
|
73
|
+
// Too-high versions cannot be parsed
|
|
74
|
+
if (!isValidVersion(version)) {
|
|
75
|
+
throw new Error('ExpectedKnownVersionToDecodeTrade');
|
|
77
76
|
}
|
|
78
77
|
|
|
79
|
-
//
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
// Encode the encrypted data
|
|
83
|
-
const encryptedRecord = findEncrypt(details);
|
|
84
|
-
|
|
85
|
-
if (!encryptedRecord) {
|
|
86
|
-
throw new Error('ExpectedEncryptedRecordToDecodeTrade');
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
const encrypted = decodeTlvStream({encoded: encryptedRecord.value}).records;
|
|
90
|
-
|
|
91
|
-
const encryptedDataRecord = findCipher(encrypted);
|
|
92
|
-
|
|
93
|
-
if (!encryptedDataRecord) {
|
|
94
|
-
throw new Error('ExpectedEncryptedDataRecordToDecodeTrade');
|
|
95
|
-
}
|
|
78
|
+
// Get the network record
|
|
79
|
+
const networkRecord = findNetwork(records) || {};
|
|
96
80
|
|
|
97
|
-
|
|
81
|
+
// Decode the network record
|
|
82
|
+
const {network} = networkFromNetworkRecord({value: networkRecord.value});
|
|
98
83
|
|
|
99
|
-
|
|
100
|
-
|
|
84
|
+
// A trade is either a trade secret to someone or an open trade offer
|
|
85
|
+
if (!!findRequestRecord(records)) {
|
|
86
|
+
return {secret: decodeTradeSecret({network, records})};
|
|
87
|
+
} else {
|
|
88
|
+
return {connect: decodeOpenTrade({network, records})};
|
|
101
89
|
}
|
|
102
|
-
|
|
103
|
-
return {
|
|
104
|
-
request,
|
|
105
|
-
auth: authDataRecord.value,
|
|
106
|
-
payload: encryptedDataRecord.value,
|
|
107
|
-
};
|
|
108
90
|
};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
const {decodeTlvStream} = require('bolt01');
|
|
2
|
+
|
|
3
|
+
const {requestRecordsAsRequest} = require('./../records');
|
|
4
|
+
|
|
5
|
+
const findAuth = records => records.find(n => n.type === '1');
|
|
6
|
+
const findCipher = records => records.find(n => n.type === '0');
|
|
7
|
+
const findDetails = records => records.find(n => n.type === '3');
|
|
8
|
+
const findEncrypt = records => records.find(n => n.type === '0');
|
|
9
|
+
const findRequest = records => records.find(n => n.type === '2');
|
|
10
|
+
const {isArray} = Array;
|
|
11
|
+
|
|
12
|
+
/** Decode a trade secret
|
|
13
|
+
|
|
14
|
+
2: <Payment Request Record>
|
|
15
|
+
3: <Trade Details Record
|
|
16
|
+
|
|
17
|
+
{
|
|
18
|
+
network: <Network Name String>
|
|
19
|
+
records: [{
|
|
20
|
+
type: <Type Number String>
|
|
21
|
+
value: <Hex Encoded Value String>
|
|
22
|
+
}]
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
@throws
|
|
26
|
+
<Error>
|
|
27
|
+
|
|
28
|
+
@returns
|
|
29
|
+
{
|
|
30
|
+
auth: <Encrypted Payload Auth Hex String>
|
|
31
|
+
payload: <Preimage Encrypted Payload Hex String>
|
|
32
|
+
request: <BOLT 11 Payment Request String>
|
|
33
|
+
}
|
|
34
|
+
*/
|
|
35
|
+
module.exports = ({network, records}) => {
|
|
36
|
+
if (!network) {
|
|
37
|
+
throw new Error('ExpectedNetworkNameToDecodeTradeSecret');
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (!isArray(records)) {
|
|
41
|
+
throw new Error('ExpectedArrayOfRecordsToDecodeTradeSecret');
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Get the payment request record
|
|
45
|
+
const requestRecord = findRequest(records);
|
|
46
|
+
|
|
47
|
+
if (!requestRecord) {
|
|
48
|
+
throw new Error('ExpectedRequestRecordInTradeData');
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const encoded = requestRecord.value;
|
|
52
|
+
|
|
53
|
+
// Get the trade details
|
|
54
|
+
const detailsRecord = findDetails(records);
|
|
55
|
+
|
|
56
|
+
if (!detailsRecord) {
|
|
57
|
+
throw new Error('ExpctedDetailsRecordToDecodeTrade');
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Trade details
|
|
61
|
+
const details = decodeTlvStream({encoded: detailsRecord.value}).records;
|
|
62
|
+
|
|
63
|
+
// Encode the encrypted data
|
|
64
|
+
const encryptedRecord = findEncrypt(details);
|
|
65
|
+
|
|
66
|
+
if (!encryptedRecord) {
|
|
67
|
+
throw new Error('ExpectedEncryptedRecordToDecodeTrade');
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const encrypted = decodeTlvStream({encoded: encryptedRecord.value}).records;
|
|
71
|
+
|
|
72
|
+
const encryptedDataRecord = findCipher(encrypted);
|
|
73
|
+
|
|
74
|
+
if (!encryptedDataRecord) {
|
|
75
|
+
throw new Error('ExpectedEncryptedDataRecordToDecodeTrade');
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const authDataRecord = findAuth(encrypted);
|
|
79
|
+
|
|
80
|
+
if (!authDataRecord) {
|
|
81
|
+
throw new Error('ExpectedAuthDataRecordToDecodeTrade');
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return {
|
|
85
|
+
request: requestRecordsAsRequest({encoded, network}).request,
|
|
86
|
+
auth: authDataRecord.value,
|
|
87
|
+
payload: encryptedDataRecord.value,
|
|
88
|
+
};
|
|
89
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
const {encodeTlvStream} = require('bolt01');
|
|
2
|
+
|
|
3
|
+
const anchorPrefix = 'anchor-trade-secret:';
|
|
4
|
+
const descriptionRecord = value => !!value ? ({value, type: '1'}) : undefined;
|
|
5
|
+
const secretRecord = value => ({value, type: '0'});
|
|
6
|
+
const utf8AsHex = utf8 => Buffer.from(utf8, 'utf8').toString('hex');
|
|
7
|
+
const withPrefix = (pre, v) => pre + Buffer.from(v, 'hex').toString('base64');
|
|
8
|
+
|
|
9
|
+
/** Encode a trade into an anchor blob
|
|
10
|
+
|
|
11
|
+
This will look like anchored-trade-secret:<base64-encoded-data>
|
|
12
|
+
|
|
13
|
+
The data encodes a TLV:
|
|
14
|
+
0: <Trade Secret>
|
|
15
|
+
[1]: <Trade Description>
|
|
16
|
+
|
|
17
|
+
{
|
|
18
|
+
[description]: <Open Trade Description String>
|
|
19
|
+
secret: <Open Trade Secret String>
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
@returns
|
|
23
|
+
{
|
|
24
|
+
encoded: <Encoded Anchor Trade Data Blob String>
|
|
25
|
+
}
|
|
26
|
+
*/
|
|
27
|
+
module.exports = ({description, secret}) => {
|
|
28
|
+
const records = [secretRecord(secret), descriptionRecord(description)]
|
|
29
|
+
.filter(n => !!n)
|
|
30
|
+
.map(({type, value}) => ({type, value: utf8AsHex(value)}));
|
|
31
|
+
|
|
32
|
+
const {encoded} = encodeTlvStream({records});
|
|
33
|
+
|
|
34
|
+
return {encoded: withPrefix(anchorPrefix, encoded)};
|
|
35
|
+
};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
const {encodeTlvStream} = require('bolt01');
|
|
2
|
+
|
|
3
|
+
const networkRecordFromNetwork = require('./network_record_from_network');
|
|
4
|
+
const nodeAsRecord = require('./node_as_record');
|
|
5
|
+
|
|
6
|
+
const asTrade = hex => `626f73ff${hex}`;
|
|
7
|
+
const idType = '5';
|
|
8
|
+
const {isArray} = Array;
|
|
9
|
+
const networkRecordType = '1';
|
|
10
|
+
const nodeType = '4';
|
|
11
|
+
const versionRecord = '01';
|
|
12
|
+
const versionType = '0';
|
|
13
|
+
|
|
14
|
+
/** Encode records for an open ended trade
|
|
15
|
+
|
|
16
|
+
An open ended trade is a pointer to a node or nodes that can create trade
|
|
17
|
+
invoices. At the minimum it has a pointer to a node.
|
|
18
|
+
|
|
19
|
+
0: version (v1)
|
|
20
|
+
[1]: network name
|
|
21
|
+
4: nodes records
|
|
22
|
+
[5]: trade identifier
|
|
23
|
+
|
|
24
|
+
{
|
|
25
|
+
[id]: <Trade Identifier Hex String>
|
|
26
|
+
network: <Network Name String>
|
|
27
|
+
nodes: [{
|
|
28
|
+
channels: [{
|
|
29
|
+
id: <Standard Format Channel Id String>
|
|
30
|
+
partner_public_key: <Node Public Key Hex String>
|
|
31
|
+
}]
|
|
32
|
+
id: <Node Public Key Id Hex String>
|
|
33
|
+
sockets: [<Peer Socket String>]
|
|
34
|
+
}]
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
@throws
|
|
38
|
+
<Error>
|
|
39
|
+
|
|
40
|
+
@returns
|
|
41
|
+
{
|
|
42
|
+
trade: <Encoded Open Ended Trade Hex String>
|
|
43
|
+
}
|
|
44
|
+
*/
|
|
45
|
+
module.exports = ({id, network, nodes}) => {
|
|
46
|
+
if (!network) {
|
|
47
|
+
throw new Error('ExpectedNetworkNameToEncodeOpenTrade');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (!isArray(nodes)) {
|
|
51
|
+
throw new Error('ExpectedArrayOfNodesToEncodeOpenTrade');
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (!nodes.length) {
|
|
55
|
+
throw new Error('ExpectedNodeToReferToInOpenTrade');
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Add trade version record
|
|
59
|
+
const records = [{type: versionType, value: versionRecord}];
|
|
60
|
+
|
|
61
|
+
// Add a network name record if required
|
|
62
|
+
if (!!networkRecordFromNetwork({network}).value) {
|
|
63
|
+
records.push({
|
|
64
|
+
type: networkRecordType,
|
|
65
|
+
value: networkRecordFromNetwork({network}).value,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// A trade id refers to a specific trade
|
|
70
|
+
if (!!id) {
|
|
71
|
+
records.push({type: idType, value: id});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Map the nodes to node records
|
|
75
|
+
const nodeRecords = nodes.map(({channels, id, sockets}, type) => {
|
|
76
|
+
return {
|
|
77
|
+
type: type.toString(),
|
|
78
|
+
value: nodeAsRecord({channels, id, sockets}).encoded,
|
|
79
|
+
};
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
// Add the node records to the open trade
|
|
83
|
+
records.push({
|
|
84
|
+
type: nodeType,
|
|
85
|
+
value: encodeTlvStream({records: nodeRecords}).encoded,
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
return {trade: asTrade(encodeTlvStream({records}).encoded)};
|
|
89
|
+
};
|
package/trades/encode_trade.js
CHANGED
|
@@ -1,50 +1,65 @@
|
|
|
1
|
-
const
|
|
1
|
+
const encodeOpenTrade = require('./encode_open_trade');
|
|
2
|
+
const encodeTradeSecret = require('./encode_trade_secret');
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
const {requestAsRequestRecords} = require('./../records');
|
|
4
|
+
/** Encode v1 trade records
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
A v1 trade is either a qualified trade with a request, or an open ended trade
|
|
7
|
+
with connection details.
|
|
7
8
|
|
|
8
|
-
|
|
9
|
+
0: version (v1)
|
|
10
|
+
[1]: network
|
|
11
|
+
[2]: payment request
|
|
12
|
+
[3]: trade details
|
|
13
|
+
[4]: nodes records
|
|
14
|
+
[5]: trade identifier
|
|
9
15
|
|
|
10
16
|
{
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
17
|
+
[connect]: {
|
|
18
|
+
[id]: <Reference Trade Id Hex String>
|
|
19
|
+
network: <Network Name String>
|
|
20
|
+
nodes: [{
|
|
21
|
+
channels: [<Standard Format Channel Id String>]
|
|
22
|
+
id: <Node Public Key Id Hex String>
|
|
23
|
+
[sockets]: [<Peer Socket String>]
|
|
24
|
+
}]
|
|
25
|
+
}
|
|
26
|
+
[secret]: {
|
|
27
|
+
auth: <Encrypted Payload Auth Hex String>
|
|
28
|
+
payload: <Preimage Encrypted Payload Hex String>
|
|
29
|
+
request: <BOLT 11 Payment Request String>
|
|
30
|
+
}
|
|
14
31
|
}
|
|
15
32
|
|
|
33
|
+
@throws
|
|
34
|
+
<Error>
|
|
35
|
+
|
|
16
36
|
@returns
|
|
17
37
|
{
|
|
18
38
|
trade: <Hex Encoded Trade String>
|
|
19
39
|
}
|
|
20
40
|
*/
|
|
21
|
-
module.exports = ({
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
type: '2',
|
|
25
|
-
value: requestAsRequestRecords({request}).encoded,
|
|
26
|
-
}];
|
|
27
|
-
|
|
28
|
-
// Add a network name record if required
|
|
29
|
-
if (!!networkRecordFromRequest({request}).value) {
|
|
30
|
-
tradeRecords.push({
|
|
31
|
-
type: '1',
|
|
32
|
-
value: networkRecordFromRequest({request}).value,
|
|
33
|
-
});
|
|
41
|
+
module.exports = ({connect, secret}) => {
|
|
42
|
+
if (!connect && !secret) {
|
|
43
|
+
throw new Error('ExpectedEitherConnectDetailsOrTradeSecret');
|
|
34
44
|
}
|
|
35
45
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
// Encode the details of the trade
|
|
42
|
-
const detailsRecords = encodeTlvStream({
|
|
43
|
-
records: [{type: '0', value: encryptionRecords.encoded}],
|
|
44
|
-
});
|
|
46
|
+
if (!!connect && !!secret) {
|
|
47
|
+
throw new Error('ExpectedEitherConnectDetailsOrTradeSecretNotBoth');
|
|
48
|
+
}
|
|
45
49
|
|
|
46
|
-
//
|
|
47
|
-
|
|
50
|
+
// Exit early when this is an open ended trade
|
|
51
|
+
if (!!connect) {
|
|
52
|
+
return encodeOpenTrade({
|
|
53
|
+
id: connect.id,
|
|
54
|
+
network: connect.network,
|
|
55
|
+
nodes: connect.nodes,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
48
58
|
|
|
49
|
-
|
|
59
|
+
// Encode the trade secret
|
|
60
|
+
return encodeTradeSecret({
|
|
61
|
+
auth: secret.auth,
|
|
62
|
+
payload: secret.payload,
|
|
63
|
+
request: secret.request,
|
|
64
|
+
});
|
|
50
65
|
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
const {encodeTlvStream} = require('bolt01');
|
|
2
|
+
|
|
3
|
+
const networkRecordFromRequest = require('./network_record_from_request');
|
|
4
|
+
const {requestAsRequestRecords} = require('./../records');
|
|
5
|
+
|
|
6
|
+
const asTrade = hex => `626f73ff${hex}`;
|
|
7
|
+
|
|
8
|
+
/** Encode a trade
|
|
9
|
+
|
|
10
|
+
{
|
|
11
|
+
auth: <Encrypted Payload Auth Hex String>
|
|
12
|
+
payload: <Preimage Encrypted Payload Hex String>
|
|
13
|
+
request: <BOLT 11 Payment Request String>
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
@returns
|
|
17
|
+
{
|
|
18
|
+
trade: <Hex Encoded Trade String>
|
|
19
|
+
}
|
|
20
|
+
*/
|
|
21
|
+
module.exports = ({auth, payload, request}, cbk) => {
|
|
22
|
+
// Encode the trade record
|
|
23
|
+
const tradeRecords = [{
|
|
24
|
+
type: '2',
|
|
25
|
+
value: requestAsRequestRecords({request}).encoded,
|
|
26
|
+
}];
|
|
27
|
+
|
|
28
|
+
// Add a network name record if required
|
|
29
|
+
if (!!networkRecordFromRequest({request}).value) {
|
|
30
|
+
tradeRecords.push({
|
|
31
|
+
type: '1',
|
|
32
|
+
value: networkRecordFromRequest({request}).value,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Encode the encrypted data
|
|
37
|
+
const encryptionRecords = encodeTlvStream({
|
|
38
|
+
records: [{type: '0', value: payload}, {type: '1', value: auth}],
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
// Encode the details of the trade
|
|
42
|
+
const detailsRecords = encodeTlvStream({
|
|
43
|
+
records: [{type: '0', value: encryptionRecords.encoded}],
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// Add the trade details to the trade
|
|
47
|
+
tradeRecords.push({type: '3', value: detailsRecords.encoded});
|
|
48
|
+
|
|
49
|
+
return {trade: asTrade(encodeTlvStream({records: tradeRecords}).encoded)};
|
|
50
|
+
};
|