ln-accounting 6.0.0 → 6.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -0
- package/README.md +19 -0
- package/index.js +7 -1
- package/package.json +4 -3
- package/records/get_all_invoices.js +27 -5
- package/report/get_accounting_report.js +8 -3
- package/report/index.js +2 -1
- package/report/parse_amount.js +76 -0
- package/test/report/test_parse_amount.js +55 -0
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -119,6 +119,25 @@ Get chain transactions, including sweep fees
|
|
|
119
119
|
}]
|
|
120
120
|
}
|
|
121
121
|
|
|
122
|
+
## parseAmount
|
|
123
|
+
|
|
124
|
+
Parse a described amount into tokens
|
|
125
|
+
|
|
126
|
+
{
|
|
127
|
+
amount: <Amount String>
|
|
128
|
+
[variables]: {
|
|
129
|
+
<Name String>: <Amount Number>
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
@throws
|
|
134
|
+
<Error>
|
|
135
|
+
|
|
136
|
+
@returns
|
|
137
|
+
{
|
|
138
|
+
tokens: <Tokens Number>
|
|
139
|
+
}
|
|
140
|
+
|
|
122
141
|
## rateProviders
|
|
123
142
|
|
|
124
143
|
Rate provider source options
|
package/index.js
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
const {getAccountingReport} = require('./report');
|
|
2
2
|
const {getChainTransactions} = require('./records');
|
|
3
|
+
const {parseAmount} = require('./report');
|
|
3
4
|
const {rateProviders} = require('./fiat');
|
|
4
5
|
|
|
5
|
-
module.exports = {
|
|
6
|
+
module.exports = {
|
|
7
|
+
getAccountingReport,
|
|
8
|
+
getChainTransactions,
|
|
9
|
+
parseAmount,
|
|
10
|
+
rateProviders,
|
|
11
|
+
};
|
package/package.json
CHANGED
|
@@ -11,8 +11,9 @@
|
|
|
11
11
|
"asyncjs-util": "1.2.10",
|
|
12
12
|
"bitcoinjs-lib": "6.0.2",
|
|
13
13
|
"goldengate": "11.4.0",
|
|
14
|
+
"hot-formula-parser": "4.0.0",
|
|
14
15
|
"json2csv": "5.0.7",
|
|
15
|
-
"ln-service": "54.2.
|
|
16
|
+
"ln-service": "54.2.6"
|
|
16
17
|
},
|
|
17
18
|
"description": "lnd accounting reports",
|
|
18
19
|
"devDependencies": {
|
|
@@ -33,7 +34,7 @@
|
|
|
33
34
|
"url": "https://github.com/alexbosworth/ln-accounting.git"
|
|
34
35
|
},
|
|
35
36
|
"scripts": {
|
|
36
|
-
"test": "tap --branches=1 --functions=1 --lines=1 --statements=1 test/blockstream/*.js test/fiat/*.js test/harmony/*.js test/records/*.js"
|
|
37
|
+
"test": "tap --branches=1 --functions=1 --lines=1 --statements=1 test/blockstream/*.js test/fiat/*.js test/harmony/*.js test/records/*.js test/report/*.js"
|
|
37
38
|
},
|
|
38
|
-
"version": "6.
|
|
39
|
+
"version": "6.1.1"
|
|
39
40
|
}
|
|
@@ -3,10 +3,14 @@ const asyncUntil = require('async/until');
|
|
|
3
3
|
const {getInvoices} = require('ln-service');
|
|
4
4
|
const {returnResult} = require('asyncjs-util');
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
const limit = 1000;
|
|
7
|
+
|
|
8
|
+
/** Get all confirmed invoices
|
|
7
9
|
|
|
8
10
|
{
|
|
9
|
-
|
|
11
|
+
[after]: <Invoices Confirmed After ISO 8601 Date String>
|
|
12
|
+
[before]: <Invoices Confirmed Before ISO 8601 Date String>
|
|
13
|
+
lnd: <Authenticated LND API Object>
|
|
10
14
|
}
|
|
11
15
|
|
|
12
16
|
@returns via cbk or Promise
|
|
@@ -39,7 +43,7 @@ const {returnResult} = require('asyncjs-util');
|
|
|
39
43
|
}]
|
|
40
44
|
}
|
|
41
45
|
*/
|
|
42
|
-
module.exports = ({lnd}, cbk) => {
|
|
46
|
+
module.exports = ({after, before, lnd}, cbk) => {
|
|
43
47
|
return new Promise((resolve, reject) => {
|
|
44
48
|
return asyncAuto({
|
|
45
49
|
// Check arguments
|
|
@@ -60,14 +64,32 @@ module.exports = ({lnd}, cbk) => {
|
|
|
60
64
|
return asyncUntil(
|
|
61
65
|
cbk => cbk(null, token === false),
|
|
62
66
|
cbk => {
|
|
63
|
-
return getInvoices({
|
|
67
|
+
return getInvoices({
|
|
68
|
+
lnd,
|
|
69
|
+
token,
|
|
70
|
+
limit: !token ? limit : undefined,
|
|
71
|
+
},
|
|
72
|
+
(err, res) => {
|
|
64
73
|
if (!!err) {
|
|
65
74
|
return cbk(err);
|
|
66
75
|
}
|
|
67
76
|
|
|
68
77
|
token = res.next || false;
|
|
69
78
|
|
|
70
|
-
res.invoices
|
|
79
|
+
res.invoices
|
|
80
|
+
.filter(n => !!n.confirmed_at && !!n.is_confirmed)
|
|
81
|
+
.filter(invoice => {
|
|
82
|
+
if (!!after && invoice.confirmed_at <= after) {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (!!before && invoice.confirmed_at > before) {
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return true;
|
|
91
|
+
})
|
|
92
|
+
.forEach(invoice => invoices.push(invoice));
|
|
71
93
|
|
|
72
94
|
return cbk(null, invoices);
|
|
73
95
|
});
|
|
@@ -34,8 +34,8 @@ const times = 10;
|
|
|
34
34
|
Note: Chain fees does not include chain fees paid to close channels
|
|
35
35
|
|
|
36
36
|
{
|
|
37
|
-
[after]: <Records Created After ISO 8601 Date>
|
|
38
|
-
[before]: <Records Created Before ISO 8601 Date>
|
|
37
|
+
[after]: <Records Created After ISO 8601 Date String>
|
|
38
|
+
[before]: <Records Created Before ISO 8601 Date String>
|
|
39
39
|
[category]: <Category Filter String>
|
|
40
40
|
currency: <Base Currency Type String>
|
|
41
41
|
[fiat]: <Fiat Currency Type String>
|
|
@@ -191,7 +191,12 @@ module.exports = (args, cbk) => {
|
|
|
191
191
|
}
|
|
192
192
|
|
|
193
193
|
// Since there is no way to page by settle date, get all the invoices
|
|
194
|
-
return getAllInvoices({
|
|
194
|
+
return getAllInvoices({
|
|
195
|
+
after: args.after,
|
|
196
|
+
before: args.before,
|
|
197
|
+
lnd: args.lnd,
|
|
198
|
+
},
|
|
199
|
+
cbk);
|
|
195
200
|
}],
|
|
196
201
|
|
|
197
202
|
// Get payments
|
package/report/index.js
CHANGED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
const {Parser} = require('hot-formula-parser');
|
|
2
|
+
|
|
3
|
+
const {ceil} = Math;
|
|
4
|
+
const {isArray} = Array;
|
|
5
|
+
const {keys} = Object;
|
|
6
|
+
const {round} = Math;
|
|
7
|
+
|
|
8
|
+
/** Parse a described amount into tokens
|
|
9
|
+
|
|
10
|
+
{
|
|
11
|
+
amount: <Amount String>
|
|
12
|
+
[variables]: {
|
|
13
|
+
<Name String>: <Amount Number>
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
@throws
|
|
18
|
+
<Error>
|
|
19
|
+
|
|
20
|
+
@returns
|
|
21
|
+
{
|
|
22
|
+
tokens: <Tokens Number>
|
|
23
|
+
}
|
|
24
|
+
*/
|
|
25
|
+
module.exports = ({amount, variables}) => {
|
|
26
|
+
if (isArray(amount)) {
|
|
27
|
+
throw new Error('CannotParseMultipleAmounts');
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const parser = new Parser();
|
|
31
|
+
|
|
32
|
+
keys(variables || {}).forEach(key => {
|
|
33
|
+
parser.setVariable(key.toLowerCase(), variables[key]);
|
|
34
|
+
parser.setVariable(key.toUpperCase(), variables[key]);
|
|
35
|
+
|
|
36
|
+
return;
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
parser.setVariable('BTC', 1e8);
|
|
40
|
+
parser.setVariable('btc', 1e8);
|
|
41
|
+
parser.setVariable('m', 1e6);
|
|
42
|
+
parser.setVariable('M', 1e6);
|
|
43
|
+
parser.setVariable('mm', 1e6);
|
|
44
|
+
parser.setVariable('MM', 1e6);
|
|
45
|
+
parser.setVariable('k', 1e3);
|
|
46
|
+
parser.setVariable('K', 1e3);
|
|
47
|
+
|
|
48
|
+
const parsed = parser.parse(amount);
|
|
49
|
+
|
|
50
|
+
switch (parsed.error) {
|
|
51
|
+
case '#DIV/0!':
|
|
52
|
+
throw new Error('CannotDivideByZeroInSpecifiedAmount');
|
|
53
|
+
|
|
54
|
+
case '#ERROR!':
|
|
55
|
+
throw new Error('FailedToParseSpecifiedAmount');
|
|
56
|
+
|
|
57
|
+
case '#N/A':
|
|
58
|
+
case '#NAME?':
|
|
59
|
+
throw new Error('UnrecognizedVariableOrFunctionInSpecifiedAmount');
|
|
60
|
+
|
|
61
|
+
case '#NUM!':
|
|
62
|
+
throw new Error('InvalidNumberFoundInSpecifiedAmount');
|
|
63
|
+
|
|
64
|
+
case '#VALUE!':
|
|
65
|
+
throw new Error('UnexpectedValueTypeInSpecifiedAmount');
|
|
66
|
+
|
|
67
|
+
default:
|
|
68
|
+
break;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (!!parsed.error) {
|
|
72
|
+
throw new Error(parsed.error);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return {tokens: round(parsed.result)};
|
|
76
|
+
};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
const {test} = require('@alexbosworth/tap');
|
|
2
|
+
|
|
3
|
+
const {parseAmount} = require('./../../');
|
|
4
|
+
|
|
5
|
+
const tests = [
|
|
6
|
+
{
|
|
7
|
+
args: {amount: 'amount'},
|
|
8
|
+
description: 'A value is required',
|
|
9
|
+
error: 'UnrecognizedVariableOrFunctionInSpecifiedAmount',
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
args: {amount: '1/0'},
|
|
13
|
+
description: 'Dividing by zero is not allowed',
|
|
14
|
+
error: 'CannotDivideByZeroInSpecifiedAmount',
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
args: {amount: '0.0.0'},
|
|
18
|
+
description: 'A generic invalid amount is rejected',
|
|
19
|
+
error: 'FailedToParseSpecifiedAmount',
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
args: {amount: 'OCT2DEC()'},
|
|
23
|
+
description: 'Invalid numbers are rejected',
|
|
24
|
+
error: 'InvalidNumberFoundInSpecifiedAmount',
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
args: {amount: '"string" + 1'},
|
|
28
|
+
description: 'Invalid formulas are rejected',
|
|
29
|
+
error: 'UnexpectedValueTypeInSpecifiedAmount',
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
args: {amount: '1.20969468*btc', variables: {variable: 'value'}},
|
|
33
|
+
description: 'A long precision BTC value is parsed',
|
|
34
|
+
expected: {tokens: 120969468},
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
args: {amount: '1.20969465*btc'},
|
|
38
|
+
description: 'A long precision BTC value that rounds down is parsed',
|
|
39
|
+
expected: {tokens: 120969465},
|
|
40
|
+
},
|
|
41
|
+
];
|
|
42
|
+
|
|
43
|
+
tests.forEach(({args, description, error, expected}) => {
|
|
44
|
+
return test(description, ({end, equal, throws}) => {
|
|
45
|
+
if (!!error) {
|
|
46
|
+
throws(() => parseAmount(args), new Error(error), 'Got expected error');
|
|
47
|
+
} else {
|
|
48
|
+
const {tokens} = parseAmount(args);
|
|
49
|
+
|
|
50
|
+
equal(tokens, expected.tokens, 'Got expected output');
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return end();
|
|
54
|
+
});
|
|
55
|
+
});
|