ln-accounting 10.0.8 → 10.0.9

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.
Files changed (30) hide show
  1. package/CHANGELOG.md +4 -1
  2. package/esplora/get_esplora_vout.js +0 -1
  3. package/package.json +21 -6
  4. package/report/get_accounting_report.js +4 -1
  5. package/.gitattributes +0 -1
  6. package/.tm_properties +0 -1
  7. package/.travis.yml +0 -15
  8. package/blockstream/get_blockstream_tx.js +0 -94
  9. package/blockstream/get_blockstream_vout.js +0 -80
  10. package/blockstream/index.js +0 -4
  11. package/test/blockstream/test_get_blockstream_tx.js +0 -111
  12. package/test/fiat/test_get_coincap_historic_rate.js +0 -86
  13. package/test/fiat/test_get_coindesk_historic_rate.js +0 -80
  14. package/test/fiat/test_get_coingecko_historic_rate.js +0 -152
  15. package/test/fiat/test_get_fiat_values.js +0 -74
  16. package/test/fiat/test_get_historic_rate.js +0 -77
  17. package/test/harmony/test_categorize_records.js +0 -156
  18. package/test/harmony/test_chain_fees_as_records.js +0 -40
  19. package/test/harmony/test_chain_receives_as_records.js +0 -73
  20. package/test/harmony/test_chain_sends_as_records.js +0 -55
  21. package/test/harmony/test_formatted_notes.js +0 -32
  22. package/test/harmony/test_forwards_as_records.js +0 -52
  23. package/test/harmony/test_harmonize.js +0 -24
  24. package/test/harmony/test_invoices_as_records.js +0 -77
  25. package/test/harmony/test_notes_for_chain_transaction.js +0 -43
  26. package/test/harmony/test_payments_as_records.js +0 -159
  27. package/test/harmony/test_records_with_fiat.js +0 -112
  28. package/test/records/test_get_all_invoices.js +0 -105
  29. package/test/records/test_get_all_payments.js +0 -274
  30. package/test/report/test_parse_amount.js +0 -57
package/CHANGELOG.md CHANGED
@@ -1,6 +1,9 @@
1
1
  # Versions
2
2
 
3
- ## Version 10.0.8
3
+ ## Version 10.0.9
4
+
5
+ - `getAccountingReport`: Fix channel funding and close transactions being
6
+ reported as chain sends and receives
4
7
 
5
8
  ### Breaking Changes
6
9
 
@@ -1,7 +1,6 @@
1
1
  const asyncAuto = require('async/auto');
2
2
  const {returnResult} = require('asyncjs-util');
3
3
 
4
- const dateFromEpoch = epoch => new Date(epoch * 1e3).toISOString();
5
4
  const {isArray} = Array;
6
5
  const url = (api, id) => `${api}tx/${id}`;
7
6
 
package/package.json CHANGED
@@ -1,6 +1,8 @@
1
1
  {
2
2
  "allowScripts": {
3
- "protobufjs@7.6.6": true
3
+ "protobufjs@7.6.6": true,
4
+ "cpu-features@0.0.10": true,
5
+ "ssh2@1.17.0": true
4
6
  },
5
7
  "author": {
6
8
  "name": "Alex Bosworth",
@@ -10,18 +12,30 @@
10
12
  "url": "https://github.com/alexbosworth/ln-accounting/issues"
11
13
  },
12
14
  "dependencies": {
13
- "@alexbosworth/blockchain": "4.10.0",
15
+ "@alexbosworth/blockchain": "4.11.0",
14
16
  "@alexbosworth/formulas": "1.5.0",
15
17
  "@json2csv/plainjs": "7.0.8",
16
18
  "async": "3.2.6",
17
19
  "asyncjs-util": "1.2.12",
18
- "goldengate": "16.0.8",
19
- "ln-service": "60.1.2"
20
+ "goldengate": "16.0.9",
21
+ "ln-service": "60.1.6"
20
22
  },
21
23
  "description": "lnd accounting reports",
24
+ "devDependencies": {
25
+ "ln-docker-daemons": "8.1.2"
26
+ },
22
27
  "engines": {
23
28
  "node": ">=22"
24
29
  },
30
+ "files": [
31
+ "CHANGELOG.md",
32
+ "esplora",
33
+ "fiat",
34
+ "harmony",
35
+ "index.js",
36
+ "records",
37
+ "report"
38
+ ],
25
39
  "keywords": [
26
40
  "accounting",
27
41
  "lightning-network",
@@ -34,7 +48,8 @@
34
48
  "url": "git+https://github.com/alexbosworth/ln-accounting.git"
35
49
  },
36
50
  "scripts": {
37
- "test": "node --experimental-test-coverage --test"
51
+ "integration-tests": "node --test 'test/integration/*.js'",
52
+ "test": "node --experimental-test-coverage --test-coverage-exclude='test/**' --test-coverage-branches=100 --test-coverage-functions=100 --test-coverage-lines=100 --test 'test/!(integration)/**/*.js'"
38
53
  },
39
- "version": "10.0.8"
54
+ "version": "10.0.9"
40
55
  }
@@ -301,7 +301,10 @@ module.exports = (args, cbk) => {
301
301
  const closeIds = channels.map(n => n.close_transaction_id);
302
302
  const transactionIds = channels.map(n => n.transaction_id);
303
303
 
304
- const ids = [].concat(closeIds).concat(transactionIds).map(n => !!n);
304
+ const ids = []
305
+ .concat(closeIds)
306
+ .concat(transactionIds)
307
+ .filter(n => !!n);
305
308
 
306
309
  return cbk(null, ids);
307
310
  }],
package/.gitattributes DELETED
@@ -1 +0,0 @@
1
- package-lock.json binary
package/.tm_properties DELETED
@@ -1 +0,0 @@
1
- exclude = '{$exclude,node_modules,*~}'
package/.travis.yml DELETED
@@ -1,15 +0,0 @@
1
- language: node_js
2
-
3
- node_js:
4
- - 12
5
- - 10
6
-
7
- os:
8
- - linux
9
-
10
- cache:
11
- directories:
12
- - $HOME/.npm
13
-
14
- notifications:
15
- email: false
@@ -1,94 +0,0 @@
1
- const asyncAuto = require('async/auto');
2
- const {returnResult} = require('asyncjs-util');
3
-
4
- const dateFromEpoch = epoch => new Date(epoch * 1e3).toISOString();
5
- const net = network => network === 'btctestnet' ? 'testnet/' : '';
6
- const {isArray} = Array;
7
- const supportedNetworks = ['btc', 'btctestnet'];
8
- const url = (net, id) => `https://blockstream.info/${net}api/tx/${id}`;
9
-
10
- /** Get transaction details from Blockstream
11
-
12
- {
13
- id: <Transaction Id Hex String>
14
- [network]: <Network Name String>
15
- request: <Request Function>
16
- }
17
-
18
- @returns via cbk or Promise
19
- {
20
- [confirmation_height]: <Confirmed In Block At Height Number>
21
- [created_at]: <Transaction Confirmation Date ISO 8601 Date String>
22
- [block_id]: <Confirmed In Block With Hash Hex String>
23
- fee: <Transaction Fee Tokens Number>
24
- output_addresses: [<Output Address String>]
25
- }
26
- */
27
- module.exports = ({id, network, request, vout}, cbk) => {
28
- return new Promise((resolve, reject) => {
29
- return asyncAuto({
30
- // Check argument
31
- validate: cbk => {
32
- if (!id) {
33
- return cbk([400, 'ExpectedTransactionIdToGetBlockstreamTxFee']);
34
- }
35
-
36
- if (!!network && !supportedNetworks.includes(network)) {
37
- return cbk([400, 'UnsupportedNetworkToGetBlockstreamTxFee']);
38
- }
39
-
40
- if (!request) {
41
- return cbk([400, 'ExpectedRequestFunctionToGetBlockstreamTxFee']);
42
- }
43
-
44
- return cbk();
45
- },
46
-
47
- // Get tx details
48
- getDetails: ['validate', ({}, cbk) => {
49
- return request({
50
- json: true,
51
- url: url(net(network), id),
52
- },
53
- (err, r, body) => {
54
- if (!!err) {
55
- return cbk([503, 'UnexpectedErrorGettingBlockstreamTxFee', {err}]);
56
- }
57
-
58
- if (!body) {
59
- return cbk([503, 'ExpectedTxLookupResultForBlockstreamTxFee']);
60
- }
61
-
62
- if (body.fee === undefined) {
63
- return cbk([503, 'ExpectedTransactionFeeInResultFromBlockstream']);
64
- }
65
-
66
- if (!body.status) {
67
- return cbk([503, 'ExpectedStatusOfBlockstreamTransaction']);
68
- }
69
-
70
- if (!isArray(body.vout)) {
71
- return cbk([503, 'ExpectedOutputsInBlockstreamTransaction']);
72
- }
73
-
74
- // Exit early when transaction is not confirmed
75
- if (!body.status.confirmed) {
76
- return cbk(null, {
77
- fee: body.fee,
78
- output_addresses: body.vout.map(n => n.scriptpubkey_address),
79
- });
80
- }
81
-
82
- return cbk(null, {
83
- block_id: body.status.block_hash,
84
- confirmation_height: body.status.block_height,
85
- created_at: dateFromEpoch(body.status.block_time),
86
- fee: body.fee,
87
- output_addresses: body.vout.map(n => n.scriptpubkey_address),
88
- });
89
- });
90
- }],
91
- },
92
- returnResult({reject, resolve, of: 'getDetails'}, cbk));
93
- });
94
- };
@@ -1,80 +0,0 @@
1
- const asyncAuto = require('async/auto');
2
- const {returnResult} = require('asyncjs-util');
3
-
4
- const net = network => network === 'btctestnet' ? 'testnet/' : '';
5
- const {isArray} = Array;
6
- const supportedNetworks = ['btc', 'btctestnet'];
7
- const url = (net, id) => `https://blockstream.info/${net}api/tx/${id}`;
8
-
9
- /** Get tx vout details from Blockstream
10
-
11
- {
12
- id: <Transaction Id Hex String>
13
- [network]: <Network Name String>
14
- request: <Request Function>
15
- vout: <Transaction Output Index Number>
16
- }
17
-
18
- @returns via cbk or Promise
19
- {
20
- tokens: <Transaction Output Tokens Number>
21
- }
22
- */
23
- module.exports = ({id, network, request, vout}, cbk) => {
24
- return new Promise((resolve, reject) => {
25
- return asyncAuto({
26
- // Check argument
27
- validate: cbk => {
28
- if (!id) {
29
- return cbk([400, 'ExpectedTransactionIdToGetBlockstreamVout']);
30
- }
31
-
32
- if (!!network && !supportedNetworks.includes(network)) {
33
- return cbk([400, 'UnsupportedNetworkToGetBlockstreamVout']);
34
- }
35
-
36
- if (!request) {
37
- return cbk([400, 'ExpectedRequestFunctionToGetBlockstreamVout']);
38
- }
39
-
40
- if (vout === undefined) {
41
- return cbk([400, 'ExpectedTransactionOutputIndexToGetVoutDetails']);
42
- }
43
-
44
- return cbk();
45
- },
46
-
47
- // Get tx details
48
- getDetails: ['validate', ({}, cbk) => {
49
- return request({
50
- json: true,
51
- url: url(net(network), id),
52
- },
53
- (err, r, body) => {
54
- if (!!err) {
55
- return cbk([503, 'UnexpectedErrorGettingBlockstreamTx', {err}]);
56
- }
57
-
58
- if (!body) {
59
- return cbk([503, 'ExpectedTxLookupResultForBlockstreamTx']);
60
- }
61
-
62
- if (!isArray(body.vout)) {
63
- return cbk([503, 'ExpectedOutputsArrayForBlockstreamTx']);
64
- }
65
-
66
- if (!body.vout[vout]) {
67
- return cbk([503, 'ExpectedOutputInBlockstreamTxDetails']);
68
- }
69
-
70
- if (!body.vout[vout].value) {
71
- return cbk([503, 'ExpectedOutputValueInBlockstreamTxDetails']);
72
- }
73
-
74
- return cbk(null, {tokens: body.vout[vout].value});
75
- });
76
- }],
77
- },
78
- returnResult({reject, resolve, of: 'getDetails'}, cbk));
79
- });
80
- };
@@ -1,4 +0,0 @@
1
- const getBlockstreamTx = require('./get_blockstream_tx');
2
- const getBlockstreamVout = require('./get_blockstream_vout');
3
-
4
- module.exports = {getBlockstreamTx, getBlockstreamVout};
@@ -1,111 +0,0 @@
1
- const {deepEqual} = require('node:assert').strict;
2
- const {rejects} = require('node:assert').strict;
3
- const test = require('node:test');
4
-
5
- const method = require('./../../blockstream/get_blockstream_tx');
6
-
7
- const makeArgs = overrides => {
8
- const args = {
9
- id: Buffer.alloc(32).toString('hex'),
10
- network: 'btc',
11
- request: ({}, cbk) => cbk(null, null, {
12
- fee: 1,
13
- status: {
14
- block_hash: Buffer.alloc(32).toString('hex'),
15
- block_height: 1,
16
- block_time: 1,
17
- confirmed: true,
18
- },
19
- vout: [{scriptpubkey_address: 'bc1zw508d6qejxtdg4y5r3zarvaryvg6kdaj'}],
20
- }),
21
- };
22
-
23
- Object.keys(overrides).forEach(k => args[k] = overrides[k]);
24
-
25
- return args;
26
- };
27
-
28
- const tests = [
29
- {
30
- args: makeArgs({id: undefined}),
31
- description: 'An id is required',
32
- error: [400, 'ExpectedTransactionIdToGetBlockstreamTxFee'],
33
- },
34
- {
35
- args: makeArgs({network: 'network'}),
36
- description: 'A known network is required',
37
- error: [400, 'UnsupportedNetworkToGetBlockstreamTxFee'],
38
- },
39
- {
40
- args: makeArgs({request: undefined}),
41
- description: 'A request method is required',
42
- error: [400, 'ExpectedRequestFunctionToGetBlockstreamTxFee'],
43
- },
44
- {
45
- args: makeArgs({request: ({}, cbk) => cbk('err')}),
46
- description: 'Request errors are passed back',
47
- error: [503, 'UnexpectedErrorGettingBlockstreamTxFee', {err: 'err'}],
48
- },
49
- {
50
- args: makeArgs({request: ({}, cbk) => cbk()}),
51
- description: 'A response body is expected',
52
- error: [503, 'ExpectedTxLookupResultForBlockstreamTxFee'],
53
- },
54
- {
55
- args: makeArgs({request: ({}, cbk) => cbk(null, null, {})}),
56
- description: 'A transaction fee is required',
57
- error: [503, 'ExpectedTransactionFeeInResultFromBlockstream'],
58
- },
59
- {
60
- args: makeArgs({request: ({}, cbk) => cbk(null, null, {fee: 1})}),
61
- description: 'Transaction status is required',
62
- error: [503, 'ExpectedStatusOfBlockstreamTransaction'],
63
- },
64
- {
65
- args: makeArgs({
66
- request: ({}, cbk) => cbk(null, null, {fee: 1, status: {}}),
67
- }),
68
- description: 'A vout array is required',
69
- error: [503, 'ExpectedOutputsInBlockstreamTransaction'],
70
- },
71
- {
72
- args: makeArgs({
73
- network: 'btctestnet',
74
- request: ({}, cbk) => cbk(null, null, {
75
- fee: 1,
76
- status: {},
77
- vout: [{scriptpubkey_address: 'bc1zw508d6qejxtdg4y5r3zarvaryvg6kdaj'}],
78
- }),
79
- }),
80
- description: 'An unconfirmed tx is returned',
81
- expected: {
82
- fee: 1,
83
- output_addresses: ['bc1zw508d6qejxtdg4y5r3zarvaryvg6kdaj'],
84
- },
85
- },
86
- {
87
- args: makeArgs({}),
88
- description: 'Blockstream tx info is returned',
89
- expected: {
90
- confirmation_height: 1,
91
- created_at: '1970-01-01T00:00:01.000Z',
92
- block_id: Buffer.alloc(32).toString('hex'),
93
- fee: 1,
94
- output_addresses: ['bc1zw508d6qejxtdg4y5r3zarvaryvg6kdaj']
95
- },
96
- },
97
- ];
98
-
99
- tests.forEach(({args, description, error, expected}) => {
100
- return test(description, async () => {
101
- if (!!error) {
102
- await rejects(method(args), error, 'Got expected error');
103
- } else {
104
- const res = await method(args);
105
-
106
- deepEqual(res, expected, 'Got expected result');
107
- }
108
-
109
- return;
110
- });
111
- });
@@ -1,86 +0,0 @@
1
- const {equal} = require('node:assert').strict;
2
- const {rejects} = require('node:assert').strict;
3
- const test = require('node:test');
4
-
5
- const method = require('./../../fiat/get_coincap_historic_rate');
6
-
7
- const date = new Date().toISOString();
8
-
9
- const api = ({}, cbk) => cbk(null, null, {data: [{date, priceUsd: 12.3401}]});
10
-
11
- const tests = [
12
- {
13
- args: {},
14
- description: 'A currency code is required',
15
- error: [400, 'UnsupportedCurrencyForCoincapFiatRateLookup'],
16
- },
17
- {
18
- args: {currency: 'BTC'},
19
- description: 'A date is required',
20
- error: [400, 'ExpectedDateForHistoricCoincapRateLookup'],
21
- },
22
- {
23
- args: {date, currency: 'BTC'},
24
- description: 'A fiat code is required',
25
- error: [400, 'UnsupportedFiatTypeForCoincapFiatRateLookup'],
26
- },
27
- {
28
- args: {date, currency: 'BTC', fiat: 'USD'},
29
- description: 'A request function is required',
30
- error: [400, 'ExpectedRequestMethodForCoincapFiatRateLookup'],
31
- },
32
- {
33
- args: {date, currency: 'BTC', fiat: 'USD', request: ({}, cbk) => cbk('e')},
34
- description: 'A request error is returned',
35
- error: [503, 'UnexpectedErrorGettingCoincapRate', {err: 'e'}],
36
- },
37
- {
38
- args: {date, currency: 'BTC', fiat: 'USD', request: ({}, cbk) => cbk()},
39
- description: 'A body is expected',
40
- error: [503, 'UnexpectedResponseGettingCoincapRate'],
41
- },
42
- {
43
- args: {
44
- date,
45
- currency: 'BTC',
46
- fiat: 'USD',
47
- request: ({}, cbk) => cbk(null, null, {data: [{}]}),
48
- },
49
- description: 'Price details are expected',
50
- error: [503, 'ExpectedDateForPriceQuoteInCoincapResponse'],
51
- },
52
- {
53
- args: {
54
- date,
55
- currency: 'BTC',
56
- fiat: 'USD',
57
- request: ({}, cbk) => cbk(null, null, {data: [{date}]}),
58
- },
59
- description: 'Fiat price is expected in response',
60
- error: [503, 'ExpectedFiatPriceInCoincapResponse'],
61
- },
62
- {
63
- args: {
64
- date,
65
- currency: 'BTC',
66
- fiat: 'USD',
67
- request: ({}, cbk) => api({}, cbk),
68
- },
69
- description: 'Get coincap historic rate',
70
- expected: {cents: 1234},
71
- },
72
- ];
73
-
74
- tests.forEach(({args, description, error, expected}) => {
75
- return test(description, async () => {
76
- if (!!error) {
77
- await rejects(method(args), error, 'Got expected error');
78
- } else {
79
- const {cents} = await method(args);
80
-
81
- equal(cents, expected.cents, 'Cents returned');
82
- }
83
-
84
- return;
85
- });
86
- });
@@ -1,80 +0,0 @@
1
- const {equal} = require('node:assert').strict;
2
- const {rejects} = require('node:assert').strict;
3
- const test = require('node:test');
4
-
5
- const method = require('./../../fiat/get_coindesk_historic_rate');
6
-
7
- const api = ({qs}, cbk) => {
8
- const bpi = {};
9
-
10
- bpi[qs.start] = 12.34;
11
-
12
- return cbk(null, null, {bpi});
13
- };
14
-
15
- const tests = [
16
- {
17
- args: {},
18
- description: 'A currency is required',
19
- error: [400, 'UnsupportedCurrencyForCoindeskFiatRateLookup'],
20
- },
21
- {
22
- args: {currency: 'BTC'},
23
- description: 'A date is required',
24
- error: [400, 'ExpectedDateForCoindeskRateLookup'],
25
- },
26
- {
27
- args: {currency: 'BTC', date: new Date().toISOString()},
28
- description: 'A currency type is required',
29
- error: [400, 'UnsupportedFiatTypeForCoindeskFiatRateLookup'],
30
- },
31
- {
32
- args: {currency: 'BTC', date: new Date().toISOString(), fiat: 'USD'},
33
- description: 'A request method is required',
34
- error: [400, 'ExpectedRequestMethodForCoindeskFiatRateLookup'],
35
- },
36
- {
37
- args: {
38
- date: new Date().toISOString(),
39
- currency: 'BTC',
40
- fiat: 'USD',
41
- request: ({}, cbk) => cbk('err'),
42
- },
43
- description: 'Errors returned from coindesk request',
44
- error: [503, 'UnexpectedErrorGettingHistoricRate', {err: 'err'}],
45
- },
46
- {
47
- args: {
48
- date: new Date().toISOString(),
49
- currency: 'BTC',
50
- fiat: 'USD',
51
- request: ({}, cbk) => cbk(),
52
- },
53
- description: 'A body is expected in coindesk response',
54
- error: [503, 'UnexpectedResponseInHistoricRateResponse'],
55
- },
56
- {
57
- args: {
58
- date: new Date().toISOString(),
59
- currency: 'BTC',
60
- fiat: 'USD',
61
- request: ({qs}, cbk) => api({qs}, cbk),
62
- },
63
- description: 'Get coindesk historic rate',
64
- expected: {cents: 1234},
65
- },
66
- ];
67
-
68
- tests.forEach(({args, description, error, expected}) => {
69
- return test(description, async () => {
70
- if (!!error) {
71
- await rejects(method(args), error, 'Got expected error');
72
- } else {
73
- const {cents} = await method(args);
74
-
75
- equal(cents, expected.cents, 'Cents returned');
76
- }
77
-
78
- return;
79
- });
80
- });