@hackerhouse/xpub-scan 1.0.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.
Files changed (83) hide show
  1. package/.claude/settings.local.json +8 -0
  2. package/CONTRIBUTING.md +130 -0
  3. package/LICENSE +23 -0
  4. package/README.md +215 -0
  5. package/__tests__/checkAddresses/checkBitcoinAddressesNegative.test.ts +75 -0
  6. package/__tests__/checkAddresses/checkBitcoinAddressesPositive.test.ts +87 -0
  7. package/__tests__/checkAddresses/checkDogeAddressesPositive.test.ts +43 -0
  8. package/__tests__/checkAddresses/checkLitecoinAddressesNegative.test.ts +75 -0
  9. package/__tests__/checkAddresses/checkLitecoinAddressesPositive.test.ts +87 -0
  10. package/__tests__/checkModels/address.test.ts +183 -0
  11. package/__tests__/checkModels/fakeRawTransactions.json +182 -0
  12. package/__tests__/deriveAddresses/deriveBitcoinAddresses.test.ts +207 -0
  13. package/__tests__/deriveAddresses/deriveBitcoinCashAddresses.test copy.ts +79 -0
  14. package/__tests__/deriveAddresses/deriveDogecoinAddresses.test.ts +43 -0
  15. package/__tests__/deriveAddresses/deriveEthereumAddresses.test.ts +26 -0
  16. package/__tests__/deriveAddresses/deriveLitecoinAddresses.test.ts +110 -0
  17. package/__tests__/helpers.test.ts +274 -0
  18. package/__tests__/test-utils.ts +3 -0
  19. package/babel.config.js +6 -0
  20. package/jest.config.ts +5 -0
  21. package/ledgerhq-xpub-scan-1.0.4.tgz +0 -0
  22. package/lib/actions/checkAddress.d.ts +29 -0
  23. package/lib/actions/checkAddress.js +122 -0
  24. package/lib/actions/checkBalance.d.ts +20 -0
  25. package/lib/actions/checkBalance.js +300 -0
  26. package/lib/actions/deriveAddresses.d.ts +17 -0
  27. package/lib/actions/deriveAddresses.js +239 -0
  28. package/lib/actions/processTransactions.d.ts +29 -0
  29. package/lib/actions/processTransactions.js +289 -0
  30. package/lib/actions/saveAnalysis.d.ts +2 -0
  31. package/lib/actions/saveAnalysis.js +800 -0
  32. package/lib/actions/scanner.d.ts +15 -0
  33. package/lib/actions/scanner.js +152 -0
  34. package/lib/api/customProvider.d.ts +19 -0
  35. package/lib/api/customProvider.js +434 -0
  36. package/lib/api/defaultProvider.d.ts +23 -0
  37. package/lib/api/defaultProvider.js +275 -0
  38. package/lib/comparison/compareOperations.d.ts +13 -0
  39. package/lib/comparison/compareOperations.js +500 -0
  40. package/lib/comparison/diffs.d.ts +18 -0
  41. package/lib/comparison/diffs.js +70 -0
  42. package/lib/configuration/currencies.d.ts +55 -0
  43. package/lib/configuration/currencies.js +72 -0
  44. package/lib/configuration/settings.d.ts +51 -0
  45. package/lib/configuration/settings.js +113 -0
  46. package/lib/display.d.ts +12 -0
  47. package/lib/display.js +251 -0
  48. package/lib/helpers.d.ts +27 -0
  49. package/lib/helpers.js +255 -0
  50. package/lib/input/args.d.ts +6 -0
  51. package/lib/input/args.js +129 -0
  52. package/lib/input/check.d.ts +6 -0
  53. package/lib/input/check.js +217 -0
  54. package/lib/input/importOperations.d.ts +11 -0
  55. package/lib/input/importOperations.js +406 -0
  56. package/lib/models/address.d.ts +40 -0
  57. package/lib/models/address.js +101 -0
  58. package/lib/models/comparison.d.ts +8 -0
  59. package/lib/models/comparison.js +6 -0
  60. package/lib/models/currency.d.ts +11 -0
  61. package/lib/models/currency.js +6 -0
  62. package/lib/models/operation.d.ts +33 -0
  63. package/lib/models/operation.js +80 -0
  64. package/lib/models/ownAddresses.d.ts +11 -0
  65. package/lib/models/ownAddresses.js +31 -0
  66. package/lib/models/scanLimits.d.ts +7 -0
  67. package/lib/models/scanLimits.js +6 -0
  68. package/lib/models/stats.d.ts +7 -0
  69. package/lib/models/stats.js +6 -0
  70. package/lib/models/transaction.d.ts +10 -0
  71. package/lib/models/transaction.js +13 -0
  72. package/lib/scan.d.ts +2 -0
  73. package/lib/scan.js +31 -0
  74. package/lib/templates/logos.base64.d.ts +2 -0
  75. package/lib/templates/logos.base64.js +9 -0
  76. package/lib/templates/report.html.d.ts +1 -0
  77. package/lib/templates/report.html.js +393 -0
  78. package/lib/tsconfig.tsbuildinfo +1 -0
  79. package/lib/types.d.ts +55 -0
  80. package/lib/types.js +2 -0
  81. package/npm-shrinkwrap.json +12323 -0
  82. package/package.json +81 -0
  83. package/sonar-project.properties +15 -0
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.currencies = exports.DerivationMode = void 0;
7
+ const coininfo_1 = __importDefault(require("coininfo"));
8
+ var DerivationMode;
9
+ (function (DerivationMode) {
10
+ DerivationMode["LEGACY"] = "Legacy";
11
+ DerivationMode["NATIVE"] = "Native SegWit";
12
+ DerivationMode["SEGWIT"] = "SegWit";
13
+ DerivationMode["TAPROOT"] = "Taproot";
14
+ DerivationMode["BCH"] = "Bitcoin Cash";
15
+ DerivationMode["ETHEREUM"] = "Ethereum";
16
+ DerivationMode["DOGECOIN"] = "Dogecoin";
17
+ DerivationMode["UNKNOWN"] = "Unknown";
18
+ })(DerivationMode || (exports.DerivationMode = DerivationMode = {}));
19
+ exports.currencies = {
20
+ btc: {
21
+ name: "Bitcoin",
22
+ symbol: "BTC",
23
+ network_mainnet: coininfo_1.default.bitcoin.main.toBitcoinJS(),
24
+ network_testnet: coininfo_1.default.bitcoin.test.toBitcoinJS(),
25
+ derivationModes: [
26
+ DerivationMode.NATIVE,
27
+ DerivationMode.TAPROOT,
28
+ DerivationMode.SEGWIT,
29
+ DerivationMode.LEGACY,
30
+ ],
31
+ precision: Math.pow(10, 8),
32
+ utxo_based: true,
33
+ },
34
+ bch: {
35
+ name: "Bitcoin Cash",
36
+ symbol: "BCH",
37
+ network_mainnet: coininfo_1.default.bitcoincash.main.toBitcoinJS(),
38
+ network_testnet: coininfo_1.default.bitcoincash.test.toBitcoinJS(),
39
+ derivationModes: [DerivationMode.BCH],
40
+ precision: Math.pow(10, 8),
41
+ utxo_based: true,
42
+ },
43
+ ltc: {
44
+ name: "Litecoin",
45
+ symbol: "LTC",
46
+ network_mainnet: coininfo_1.default.litecoin.main.toBitcoinJS(),
47
+ network_testnet: coininfo_1.default.litecoin.test.toBitcoinJS(),
48
+ derivationModes: [
49
+ DerivationMode.NATIVE,
50
+ DerivationMode.SEGWIT,
51
+ DerivationMode.LEGACY,
52
+ ],
53
+ precision: Math.pow(10, 8),
54
+ utxo_based: true,
55
+ },
56
+ eth: {
57
+ name: "Ethereum",
58
+ symbol: "ETH",
59
+ precision: Math.pow(10, 18),
60
+ utxo_based: false,
61
+ derivationModes: [DerivationMode.ETHEREUM],
62
+ },
63
+ doge: {
64
+ name: "Dogecoin",
65
+ symbol: "DOGE",
66
+ network_mainnet: coininfo_1.default.dogecoin.main.toBitcoinJS(),
67
+ network_testnet: coininfo_1.default.dogecoin.test.toBitcoinJS(),
68
+ precision: Math.pow(10, 8),
69
+ utxo_based: true,
70
+ derivationModes: [DerivationMode.DOGECOIN],
71
+ },
72
+ };
@@ -0,0 +1,51 @@
1
+ import { Currency } from "../models/currency";
2
+ declare const VERBOSE = false;
3
+ declare const ETH_FIXED_PRECISION = 10;
4
+ declare const DEFAULT_API_URLS: {
5
+ general: string;
6
+ bch: string;
7
+ eth: string;
8
+ };
9
+ declare const CRYPTOAPIS_URL = "https://rest.cryptoapis.io/v2/blockchain-data/{currency}/{network}";
10
+ declare const DERIVATION_SCOPE: {
11
+ quick_search: {
12
+ account: {
13
+ min: number;
14
+ max: number;
15
+ };
16
+ index: {
17
+ min: number;
18
+ max: number;
19
+ };
20
+ };
21
+ deep_search: {
22
+ account: {
23
+ min: number;
24
+ max: number;
25
+ };
26
+ index: {
27
+ min: number;
28
+ max: number;
29
+ };
30
+ };
31
+ };
32
+ declare const EXTERNAL_EXPLORERS_URLS: {
33
+ general: string;
34
+ bch: string;
35
+ eth: string;
36
+ };
37
+ export declare const configuration: {
38
+ currency: Currency;
39
+ testnet: boolean;
40
+ specificDerivationMode: string;
41
+ externalProviderURL: string;
42
+ APIKey: string | undefined;
43
+ providerType: string;
44
+ silent: boolean;
45
+ quiet: boolean;
46
+ commandLineMode: boolean;
47
+ gap_limit: string | number;
48
+ augmentedImport: boolean;
49
+ blockHeightUpperLimit: number;
50
+ };
51
+ export { DEFAULT_API_URLS, CRYPTOAPIS_URL, VERBOSE, ETH_FIXED_PRECISION, DERIVATION_SCOPE, EXTERNAL_EXPLORERS_URLS, };
@@ -0,0 +1,113 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.EXTERNAL_EXPLORERS_URLS = exports.DERIVATION_SCOPE = exports.ETH_FIXED_PRECISION = exports.VERBOSE = exports.CRYPTOAPIS_URL = exports.DEFAULT_API_URLS = exports.configuration = void 0;
27
+ const dotenv = __importStar(require("dotenv"));
28
+ const currency_1 = require("../models/currency");
29
+ // ┏━━━━━━━━━┓
30
+ // ┃ GENERAL ┃
31
+ // ┗━━━━━━━━━┛
32
+ const VERBOSE = false;
33
+ exports.VERBOSE = VERBOSE;
34
+ const ETH_FIXED_PRECISION = 10; // Decimal places for ETH (recommended for Crypto APIs provider: 10)
35
+ exports.ETH_FIXED_PRECISION = ETH_FIXED_PRECISION;
36
+ // max number of addresses to probe when checking a possible gap between derivation indices
37
+ // (that is: range of indices not used for derivation)
38
+ const DEFAULT_GAP_LIMIT = 20;
39
+ // ┏━━━━━━━━━━━┓
40
+ // ┃ PROVIDERS ┃
41
+ // ┗━━━━━━━━━━━┛
42
+ // use {currency} and {address} as placeholders for the currency name and the address;
43
+ // {type} for the transaction type, and {item} for either an address or a transaction
44
+ const DEFAULT_API_URLS = {
45
+ general: "https://blockstream.info/{network}/api/address/{address}",
46
+ bch: "https://rest.bitcoin.com/v2/address/{type}/bitcoincash:{address}",
47
+ eth: "https://api.blockcypher.com/v1/eth/main/{type}/{item}",
48
+ };
49
+ exports.DEFAULT_API_URLS = DEFAULT_API_URLS;
50
+ // use {currency} and {network} as placeholders for the currency name and the network (mainnet v. testnet)
51
+ const CRYPTOAPIS_URL = "https://rest.cryptoapis.io/v2/blockchain-data/{currency}/{network}";
52
+ exports.CRYPTOAPIS_URL = CRYPTOAPIS_URL;
53
+ // ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
54
+ // ┃ XPUB <=> ADDRESS COMPARISON ┃
55
+ // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
56
+ // scope of the derivation for the comparison
57
+ // only concerning xpub-search
58
+ const DERIVATION_SCOPE = {
59
+ // _quick search_
60
+ // the common range from which addresses
61
+ // are generally derived
62
+ quick_search: {
63
+ account: {
64
+ min: 0,
65
+ max: 4,
66
+ },
67
+ index: {
68
+ min: 0,
69
+ max: 1000,
70
+ },
71
+ },
72
+ // _deep search_
73
+ // an extended range for a deeper analysis,
74
+ // initiated when quick search fails
75
+ deep_search: {
76
+ account: {
77
+ min: 0,
78
+ max: 1000,
79
+ },
80
+ index: {
81
+ min: 0,
82
+ max: 100000,
83
+ },
84
+ },
85
+ };
86
+ exports.DERIVATION_SCOPE = DERIVATION_SCOPE;
87
+ // ┏━━━━━━━━━━━━━┓
88
+ // ┃ HTML REPORT ┃
89
+ // ┗━━━━━━━━━━━━━┛
90
+ const EXTERNAL_EXPLORERS_URLS = {
91
+ general: "https://live.blockcypher.com/{currency}/{type}/{item}",
92
+ bch: "https://blockchair.com/{currency}/{type}/{item}",
93
+ eth: "https://etherscan.io/{type}/{item}",
94
+ };
95
+ exports.EXTERNAL_EXPLORERS_URLS = EXTERNAL_EXPLORERS_URLS;
96
+ // ┏━━━━━━━━━━━━━━━━━━━━━━┓
97
+ // ┃ CONFIGURATION OBJECT ┃
98
+ // ┗━━━━━━━━━━━━━━━━━━━━━━┛
99
+ dotenv.config();
100
+ exports.configuration = {
101
+ currency: new currency_1.Currency(),
102
+ testnet: false,
103
+ specificDerivationMode: "",
104
+ externalProviderURL: "",
105
+ APIKey: process.env.XPUB_SCAN_CUSTOM_API_KEY_V2,
106
+ providerType: "default",
107
+ silent: false,
108
+ quiet: false,
109
+ commandLineMode: false,
110
+ gap_limit: process.env.GAP_LIMIT || DEFAULT_GAP_LIMIT,
111
+ augmentedImport: false,
112
+ blockHeightUpperLimit: 0, // comparison mode: block height limit
113
+ };
@@ -0,0 +1,12 @@
1
+ import { Address } from "./models/address";
2
+ import { Operation } from "./models/operation";
3
+ import { Summary } from "./types";
4
+ import { DerivationMode } from "./configuration/currencies";
5
+ import BigNumber from "bignumber.js";
6
+ declare function updateAddressDetails(address: Address): void;
7
+ declare function showSortedOperations(sortedOperations: Array<Operation>): void;
8
+ declare function showSummary(derivationMode: DerivationMode, totalBalance: BigNumber): void;
9
+ declare function logStatus(status: string): void;
10
+ declare function transientLine(message?: string): void;
11
+ declare function showResults(sortedUTXOs: Array<Address>, sortedOperations: Array<Operation>, summary: Array<Summary>, balanceOnly: boolean): void;
12
+ export { showSummary, logStatus, updateAddressDetails, showSortedOperations, transientLine, showResults, };
package/lib/display.js ADDED
@@ -0,0 +1,251 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.showResults = exports.transientLine = exports.showSortedOperations = exports.updateAddressDetails = exports.logStatus = exports.showSummary = void 0;
7
+ const readline_1 = __importDefault(require("readline"));
8
+ const chalk_1 = __importDefault(require("chalk"));
9
+ const settings_1 = require("./configuration/settings");
10
+ const bignumber_js_1 = __importDefault(require("bignumber.js"));
11
+ function renderAmount(amount) {
12
+ // Currently, this function does not convert the amounts
13
+ // into relevant units. But in the future, if the API
14
+ // changes, it would allow to change the unit
15
+ // depending on the network.
16
+ // For example:
17
+ // if (configuration.currency.symbol === currencies.btc.symbol) {
18
+ // return sb.toAccountUnit(amount);
19
+ // }
20
+ if (amount.isZero()) {
21
+ return String(amount);
22
+ }
23
+ else {
24
+ // 8 digital places max without trailing 0s
25
+ return amount.toFixed(8);
26
+ }
27
+ }
28
+ // display the active/probed address with its stats
29
+ function updateAddressDetails(address) {
30
+ // silent mode: do not display anything
31
+ if (settings_1.configuration.silent) {
32
+ return;
33
+ }
34
+ // quiet mode: only display full information, once
35
+ if (settings_1.configuration.quiet && typeof address.getStats() === "undefined") {
36
+ return;
37
+ }
38
+ const derivationMode = address.getDerivationMode();
39
+ const account = address.getDerivation().account;
40
+ const index = address.getDerivation().index;
41
+ const derivationPath = "m/"
42
+ .concat(String(account))
43
+ .concat("/")
44
+ .concat(String(index));
45
+ const addressStats = address.getStats();
46
+ // _type_ path address ...
47
+ let stats = "";
48
+ if (settings_1.configuration.currency.utxo_based) {
49
+ // _{derivation mode}_ {derivation path} {address} [{cash address}]...
50
+ stats = stats
51
+ .concat(chalk_1.default.italic(derivationMode.padEnd(16, " ")))
52
+ .concat(derivationPath.padEnd(12, " "));
53
+ }
54
+ else {
55
+ stats = stats.concat("\t");
56
+ }
57
+ const cashAddress = address.asCashAddress();
58
+ if (typeof cashAddress !== "undefined") {
59
+ stats = stats
60
+ .concat(address.toString().padEnd(36, " "))
61
+ .concat(cashAddress.padEnd(46, " "));
62
+ }
63
+ else {
64
+ stats = stats.concat(address.toString().padEnd(46, " "));
65
+ }
66
+ if (typeof address.getStats() === "undefined") {
67
+ // if no stats, display just half of the line
68
+ if (settings_1.configuration.commandLineMode) {
69
+ process.stdout.write(stats);
70
+ }
71
+ return;
72
+ }
73
+ else {
74
+ // else, display the full line
75
+ const balance = address.getBalance();
76
+ const fundedSum = renderAmount(addressStats.funded);
77
+ transientLine( /* delete line to display complete info */);
78
+ // ... +{total funded} ←
79
+ stats = stats
80
+ .concat(balance.toString().padEnd(16, " "))
81
+ .concat("+")
82
+ .concat(fundedSum.padEnd(14, " ")) // an active address has necessarily been funded,
83
+ .concat(" ←"); // thus this information is mandatory
84
+ }
85
+ // optional: spent sum
86
+ if (typeof addressStats.spent !== "undefined") {
87
+ const spentSum = renderAmount(addressStats.spent);
88
+ // ... -{total spent} →
89
+ stats = stats.concat("\t-").concat(spentSum.padEnd(14, " ")).concat(" →");
90
+ }
91
+ console.log(stats);
92
+ }
93
+ exports.updateAddressDetails = updateAddressDetails;
94
+ // display the list of UTXOs sorted by date (reverse chronological order)
95
+ function showSortedUTXOs(sortedUTXOs) {
96
+ if (settings_1.configuration.silent || !settings_1.configuration.currency.utxo_based) {
97
+ return;
98
+ }
99
+ console.log(chalk_1.default.bold("\nUTXOs\n"));
100
+ if (sortedUTXOs.length === 0) {
101
+ console.log(chalk_1.default.gray("(no UTXO)"));
102
+ return;
103
+ }
104
+ sortedUTXOs.forEach((utxo) => {
105
+ updateAddressDetails(utxo);
106
+ });
107
+ }
108
+ // display the list of operations sorted by date (reverse chronological order)
109
+ function showSortedOperations(sortedOperations) {
110
+ if (settings_1.configuration.silent) {
111
+ return;
112
+ }
113
+ process.stdout.write(chalk_1.default.bold("\nOperations History"));
114
+ if (typeof settings_1.configuration.APIKey === "undefined") {
115
+ // warning related to the limitations of the default provider
116
+ process.stdout.write(chalk_1.default.redBright(" (only the last ~50 operations by address are displayed)\n"));
117
+ }
118
+ else {
119
+ process.stdout.write("\n");
120
+ }
121
+ const header = "\ndate\t\t\tblock\t\taddress\t\t\t\t\t\treceived (←) [as change from non-sibling (c)] | sent (→) to self (⮂) or sibling (↺)";
122
+ console.log(chalk_1.default.grey(header));
123
+ sortedOperations.forEach((op) => {
124
+ const amount = renderAmount(op.amount).padEnd(12, " ");
125
+ // {date} {block} {address} [{cash address}]
126
+ let status = op.date
127
+ .padEnd(20, " ")
128
+ .concat("\t")
129
+ .concat(String(op.block).padEnd(8, " "));
130
+ const address = op.address;
131
+ const cashAddress = op.cashAddress;
132
+ if (typeof cashAddress !== "undefined") {
133
+ status = status
134
+ .concat(address.padEnd(36, " "))
135
+ .concat(cashAddress.padEnd(46, " "));
136
+ }
137
+ else {
138
+ status = status.concat("\t").concat(address.padEnd(42, " ")).concat("\t");
139
+ }
140
+ if (op.operationType.includes("Received")) {
141
+ // ... +{amount} ←
142
+ status = status.concat("+").concat(amount.padEnd(14, " ")).concat(" ←");
143
+ if (op.operationType === "Received (non-sibling to change)") {
144
+ status = status.concat(" c");
145
+ }
146
+ }
147
+ else {
148
+ // ... -{amount} →|⮂|↺
149
+ status = status.concat("-").concat(amount.padEnd(14, " "));
150
+ const operationType = op.getOperationType();
151
+ if (operationType === "Sent to self") {
152
+ // case 1. Sent to the same address
153
+ status = status.concat(" ⮂");
154
+ }
155
+ else if (operationType === "Sent to sibling") {
156
+ // case 2. Sent to a sibling address
157
+ // (different non-change address belonging to same xpub)
158
+ status = status.concat(" ↺");
159
+ }
160
+ else if (operationType === "Failed to send") {
161
+ // case 3. Failed to send (Ethereum)
162
+ status = status.concat(" x");
163
+ }
164
+ else {
165
+ // case 4. Sent to external address
166
+ status = status.concat(" →");
167
+ }
168
+ }
169
+ if (op.operationType.includes("token")) {
170
+ // Token (Ethereum)
171
+ status = status.concat(" token");
172
+ }
173
+ if (op.operationType.includes("dapp")) {
174
+ // Token (Ethereum)
175
+ status = status.concat(" dapp");
176
+ }
177
+ if (op.operationType.includes("Swapped")) {
178
+ // Swapped (Ethereum)
179
+ status = status.concat(" Swapped");
180
+ }
181
+ if (op.operationType.includes("SCI")) {
182
+ // SCI (Ethereum)
183
+ status = status.concat(" sci");
184
+ }
185
+ console.log(status);
186
+ });
187
+ console.log(chalk_1.default.bold("\nNumber of transactions\n"));
188
+ console.log(chalk_1.default.whiteBright(sortedOperations.length));
189
+ }
190
+ exports.showSortedOperations = showSortedOperations;
191
+ // display the summary: total balance by address type
192
+ function showSummary(derivationMode, totalBalance) {
193
+ if (settings_1.configuration.silent) {
194
+ return;
195
+ }
196
+ const derivation = derivationMode.toString();
197
+ const balance = renderAmount(new bignumber_js_1.default(totalBalance));
198
+ if (balance === "0") {
199
+ console.log(chalk_1.default.grey(derivation.padEnd(16, " ").concat(balance.padEnd(12, " "))));
200
+ }
201
+ else {
202
+ console.log(chalk_1.default
203
+ .whiteBright(derivation.padEnd(16, " "))
204
+ .concat(chalk_1.default.greenBright(balance.padEnd(12, " "))));
205
+ }
206
+ }
207
+ exports.showSummary = showSummary;
208
+ function logStatus(status) {
209
+ if (settings_1.configuration.silent) {
210
+ return;
211
+ }
212
+ console.log(chalk_1.default.dim(status));
213
+ }
214
+ exports.logStatus = logStatus;
215
+ // overwrite last displayed line
216
+ // (no message: delete the line)
217
+ //
218
+ // note: if this implementation is modified,
219
+ // always check the resulting behavior in
220
+ // Docker
221
+ function transientLine(message) {
222
+ if (settings_1.configuration.silent || settings_1.configuration.quiet) {
223
+ return;
224
+ }
225
+ readline_1.default.cursorTo(process.stdout, 0);
226
+ if (typeof message !== "undefined") {
227
+ process.stdout.write(message);
228
+ }
229
+ else {
230
+ // blank line
231
+ // ! solution implemented this way to be
232
+ // ! compatible with Docker
233
+ process.stdout.write("".padEnd(140, " "));
234
+ readline_1.default.cursorTo(process.stdout, 0);
235
+ }
236
+ }
237
+ exports.transientLine = transientLine;
238
+ function showResults(sortedUTXOs, sortedOperations, summary, balanceOnly) {
239
+ if (settings_1.configuration.silent) {
240
+ return;
241
+ }
242
+ showSortedUTXOs(sortedUTXOs);
243
+ if (!balanceOnly) {
244
+ showSortedOperations(sortedOperations);
245
+ }
246
+ console.log(chalk_1.default.bold("\nSummary\n"));
247
+ for (const total of summary) {
248
+ showSummary(total.derivationMode, total.balance);
249
+ }
250
+ }
251
+ exports.showResults = showResults;
@@ -0,0 +1,27 @@
1
+ import BigNumber from "bignumber.js";
2
+ declare function getJSON<T>(url: string, APIKey?: string, { retries, retryDelayMS }?: {
3
+ retries?: number;
4
+ retryDelayMS?: number;
5
+ }): Promise<T>;
6
+ declare function retry<T>(job: () => Promise<T>, { retries, retryDelayMS }?: {
7
+ retries?: number | undefined;
8
+ retryDelayMS?: number | undefined;
9
+ }): Promise<T>;
10
+ declare function setNetwork(xpub: string, currency?: string, testnet?: boolean): void;
11
+ declare function init(xpub: string, silent?: boolean, quiet?: boolean, currency?: string, testnet?: boolean, derivationMode?: string): void;
12
+ declare function toUnprefixedCashAddress(address: string): string | undefined;
13
+ /**
14
+ * Convert from unit of account to base unit (e.g. bitcoins to satoshis)
15
+ * @param amount the amount (in unit of account) to convert
16
+ * @returns the converted amount, in base unit
17
+ */
18
+ declare function toBaseUnit(amount: BigNumber): string;
19
+ /**
20
+ * Convert from base unit to unit of account (e.g. satoshis to bitcoins)
21
+ * @param amount the amount (in base unit) to convert
22
+ * @param decimalPlaces (optional) decimal precision
23
+ * @returns the converted amount, in unit of account
24
+ */
25
+ declare function toAccountUnit(amount: BigNumber, decimalPlaces?: number): string;
26
+ declare function getNetworkLabel(): "ropsten" | "testnet" | "mainnet";
27
+ export { init, getJSON, getNetworkLabel, retry, setNetwork, toUnprefixedCashAddress, toBaseUnit, toAccountUnit, };