@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,8 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(npm run build:*)",
5
+ "Bash(npm test:*)"
6
+ ]
7
+ }
8
+ }
@@ -0,0 +1,130 @@
1
+ # Welcome!
2
+
3
+ Thank you for investing your time in contributing to Xpub Scan!
4
+
5
+ In this guide, you will get an overview of its core principles as well as the contribution workflow.
6
+
7
+ # Core Principles
8
+
9
+ Xpub Scan is based on four core principles that are expected to be reflected in each incremental development.
10
+
11
+ - It is product agnostic
12
+ - It works out of the box
13
+ - It is stateless
14
+ - It is privacy-focused
15
+
16
+ ## 1. Product Agnostic
17
+
18
+ One consequence of this principle is that Xpub Scan is required to work with Live and LES (Ledger Enterprise Solutions) products when using the comparison feature.
19
+
20
+ To help enforce this principle, the regression tests are targeting both the Live (Live-common, Live Desktop) and the LES components.
21
+
22
+ Rationale: Xpub Scan is used by both business-to-consumer and business-to-business teams.
23
+
24
+ ## 2. Works Out the Box
25
+
26
+ Anyone should be able to just clone, build, and run Xpub Scan. It should just work without additional configuration.
27
+
28
+ Advanced users should also be able to customize the tool to use robust external providers.
29
+
30
+ As a consequence, Xpub Scan uses two categories of providers: free providers (referred to by the `DEFAULT_API_URLS` variable in `src/configuration/settings.ts`) and a paid providers (CryptoAPIs: `CRYPTOAPIS_URL`).
31
+
32
+ In the code, the free providers are labeled as _default_ providers while CryptoAPIs is labeled as the _custom_ provider.
33
+
34
+ The free providers are not as reliable as the paid provider. Consequently, Xpub Scan has to display a warning message when the free provider is being used to inform the user about such limitations. The current warning message is: “_(only the last ~50 operations by address are displayed)_". This is a hard requirement.
35
+
36
+ Rationale: Xpub Scan is used outside Ledger and should not depend on one provider.
37
+
38
+ ## 3. Stateless
39
+
40
+ Xpub Scan is not a wallet: there is no need to maintain an internal state.
41
+
42
+ Using a database would complexify the tool, notably by implementing a mechanism ensuring the correct synchronization of such a database.
43
+
44
+ ## 4. Privacy-Focused
45
+
46
+ Xpub Scan should _never_ send xpubs to external providers and only fetch the minimum information (transactions per address that it derives itself).
47
+
48
+ # Setting up the development environment
49
+
50
+ Use Node **LTS**. The most recent versions of Node may trigger [OpenSSL-related errors](https://github.com/webpack/webpack/issues/14532)).
51
+
52
+ At the root of the project, a `.env` file, containing a valid [CryptoAPIs API v2 key](https://developers.cryptoapis.io/technical-documentation/general-information/overview), is required to enable the custom provider.
53
+
54
+ ```
55
+ XPUB_SCAN_CUSTOM_API_KEY_V2=<your key>
56
+ ```
57
+
58
+ # Implementing
59
+
60
+ ## Properly Format the Code
61
+
62
+ Your code has to be correctly formatted. To this effect, a set of rules are defined in `.prettierrc.json` and automatically enforced with this command:
63
+
64
+ ```
65
+ $ npm run prettier
66
+ ```
67
+
68
+ ## Add Unit Tests
69
+
70
+ When implementing a new feature, please add corresponding unit tests.
71
+
72
+ You can also contribute to the project by enhancing the current code coverage.
73
+
74
+ The general idea is to progressively reach near 100% coverage.
75
+
76
+ # Testing
77
+
78
+ Once your fix or feature has been implemented, you can locally ensure that the project will pass the tests in the CI.
79
+
80
+ (Note: you can run all tests at once: `$ npm run dev:test:all`).
81
+
82
+ ## Up-to-date Requirements
83
+
84
+ For security reasons, the dependencies have to be up-to-date and strictly pinpointed.
85
+
86
+ To this effect, a dedicated command verifies the dependencies:
87
+
88
+ ```
89
+ $ npm run check:dep
90
+ ```
91
+
92
+ If this command reveals that dependencies are outdated, update them in `package.json` **using strict versioning**:
93
+
94
+ - `1.2.3` ✅
95
+ - `^1.2.3` ❌
96
+ - `~1.2.3` ❌
97
+
98
+ Run `check:dep` again and, if the check passes, run the subsequent tests to ensure that the newest dependencies do not break anything.
99
+
100
+ ## Unit Tests
101
+
102
+ To run the unit tests, do:
103
+
104
+ ```
105
+ $ npm run ci
106
+ ```
107
+
108
+ To generate the coverage (prerequisites: `jest` and `ts-node`, run:
109
+
110
+ ```
111
+ $ jest --collect-coverage
112
+ ```
113
+
114
+ An HTML report will be generated in `./coverage/lcov-report/`.
115
+
116
+ ## Regression Tests
117
+
118
+ Regression tests are essential to ensure that the core logic of Xpub Scan is not negatively affected by new features and/or fixes. They consist of scanning ad hoc xpubs and performing comparisons using products exports (see: `.github/workflows/regression_tests/datasets.json`). Both positive and negative tests are running: positive tests ensure that Xpub Scan does not detect erroneous discrepancies; negative tests ensure that Xpub Scan can detect fake discrepancies, injected for testing purposes into the exports of the products.
119
+
120
+ To run the regression tests locally, use the following command:
121
+
122
+ ```
123
+ $ npm run regression
124
+ ```
125
+
126
+ (Important: the tests will fail if no CryptoAPIs API v2 key is provided).
127
+
128
+ # Any contributions you make will be under the MIT Software License
129
+
130
+ In short, when you submit code changes, your submissions are understood to be under the same [MIT License](https://github.com/LedgerHQ/xpub-scan/blob/main/LICENSE) that covers the project.
package/LICENSE ADDED
@@ -0,0 +1,23 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2021—2022 Ledger
4
+
5
+ (Creator and main contributor: Guillaume Lethuillier)
6
+
7
+ Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ of this software and associated documentation files (the "Software"), to deal
9
+ in the Software without restriction, including without limitation the rights
10
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ copies of the Software, and to permit persons to whom the Software is
12
+ furnished to do so, subject to the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be included in all
15
+ copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,215 @@
1
+ # Xpub Scan
2
+
3
+ ![XPUB](./doc/logo.png)
4
+
5
+ Blockchain test oracle and forensics tool.
6
+
7
+ Given an extended public key (xpub, Ltub, _etc._), get the balances of its derived active addresses and the associated list of operations, or check whether an address has been derived from it.
8
+
9
+ ![Xpub Scan demo](./doc/demo.gif)
10
+
11
+ ## Features
12
+
13
+ - Privacy Friendly: master public keys are never sent over the Internet: only their derived addresses are
14
+ - Derives specific addresses (by account+index) or all active ones
15
+ - Searches if a given address has been derived from a given master public key (perfect and partial match)
16
+ - Supports legacy, SegWit, and Native SegWit
17
+ - Automatically checks supported CSV or JSON files containing operations history
18
+
19
+ ## Prerequisites
20
+
21
+ - Node.js **LTS** (note: using Node v17 may trigger [this OpenSSL-related error](https://github.com/webpack/webpack/issues/14532))
22
+ - Docker (if you want to use the docker image)
23
+
24
+ ## Install
25
+
26
+ ```
27
+ $ npm i -g @ledgerhq/xpub-scan
28
+ ```
29
+
30
+ ## Usage
31
+
32
+ ### Bitcoin, Litecoin
33
+
34
+ ```
35
+ $ xpub-scan <xpub> [options]
36
+ ```
37
+
38
+ ### Ethereum
39
+
40
+ ```
41
+ $ xpub-scan <address> --currency eth [options]
42
+ ```
43
+
44
+ Running programmatically example:
45
+
46
+ ```
47
+ import { Scanner } from "../src/actions/scanner";
48
+
49
+ const scanResult = async (xpub: string) => {
50
+ await new Scanner({ itemToScan: xpub }).scan();
51
+ };
52
+
53
+ scanResult("your_xpub");
54
+ ```
55
+
56
+ ## Development
57
+
58
+ Install dependencies:
59
+
60
+ ```
61
+ $ npm run ci
62
+ ```
63
+
64
+ Build the project
65
+
66
+ ```
67
+ $ npm run build
68
+ ```
69
+
70
+ Run the built version:
71
+
72
+ ```
73
+ $ node ./lib/scan.js [options] <xpub>
74
+ ```
75
+
76
+ _Alternatively, if you want to use the locally-built version of xpub-scan with just `xpub-scan` command, you can:_
77
+
78
+ ```
79
+ $ npm link
80
+ ```
81
+
82
+ ### Currencies
83
+
84
+ By default, Bitcoin xpubs and Litecoin ltubs are automatically detected.
85
+
86
+ To scan Bitcoin Cash xpubs, use the `--currency bch` argument:
87
+
88
+ `$ xpub-scan --currency bch <xpub> …`
89
+
90
+ To scan Litecoin xpubs, use the `--currency ltc` argument:
91
+
92
+ `$ xpub-scan --currency ltc <xpub> …`
93
+
94
+ ## Usage 1. Check Balances
95
+
96
+ _In the following instructions, the generic `xpub` term is used to designate a master public key. It can be substituted with another type of supported public key, such as `Ltub` (Litecoin)._
97
+
98
+ ### Scan for a Specific Account and an Index
99
+
100
+ `$ xpub-scan <xpub> --account <account> --index <index>`
101
+
102
+ Example:
103
+ `$ xpub-scan xpub6C...44dXs7p -a 0 -i 10` [addresses at account `0`, index `10`]
104
+
105
+ ### ScanLimits Scan | Scan Addresses Derived From Index A to Index B
106
+
107
+ `$ xpub-scan <xpub> --account <account> --from-index <index A> [--to-index <index B>]`
108
+
109
+ Example 1:
110
+ `$ xpub-scan xpub6C...44dXs7p -a 0 --from-index 0 --to-index 100` [addresses at account `0`, from index `0` to index `100`, included]
111
+
112
+ Example 2:
113
+ `$ xpub-scan xpub6C...44dXs7p -a 1 --from-index 29` [addresses at account `0`, from index `29` until no active address]
114
+
115
+ Note: in order to perform the analysis in this context, Xpub Scan needs to pre-derive addresses. By default, it derives 2,000 addresses per account number. If needed, this number of addresses can be adjusted using the `--pre-derivation-size` option (useful with xpub associated with a large number of addresses).
116
+
117
+ ### Full Scan | Scan All Active Addresses
118
+
119
+ `$ xpub-scan <xpub>`
120
+
121
+ Example:
122
+ `$ xpub-scan xpub6C...44dXs7p`
123
+
124
+ ### Compare Imported Data With Actual Data
125
+
126
+ **Balance `--balance <balance>`**
127
+
128
+ `$ xpub-scan <xpub> --balance <balance (in base unit such as satoshis)>`
129
+
130
+ **Addresses `--addresses <filepath>`**
131
+
132
+ _(Not implemented yet)_
133
+
134
+ `$ xpub-scan <xpub> --addresses <file path>`
135
+
136
+ **UTXOs `--utxos <filepath>`**
137
+
138
+ _(Not implemented yet)_
139
+
140
+ `$ xpub-scan <xpub> --utxos <file path>`
141
+
142
+ **Operations `--operations <filepath>`**
143
+
144
+ `$ xpub-scan <xpub> --operations <file path>`
145
+
146
+ Example:
147
+ `$ xpub-scan xpub6C...44dXs7p --operations /Users/Test/Downloads/export.csv`
148
+
149
+ **General Example**
150
+
151
+ `$ xpub-scan xpub6C...44dXs7p --operations /Users/Test/Downloads/export.csv --balance 12345 --diff` displays at the end of the analysis the results of the comparison between the `12345` satoshis balance and the actual one, as well as the potential mismatches between the imported operations and the actual ones.
152
+
153
+ ### Generate JSON and HTML Reports (Scan Only)
154
+
155
+ `$ xpub-scan <xpub> [args...] --save <directory>`
156
+
157
+ The files are saved as `<xpub>.json` and `<xpub>.html`.
158
+
159
+ Note: `--save stdout` can be used to display the JSON instead of saving the files. Furthermore, the `--quiet` option does not display the analysis progress while the `--silent` option does not display the progress _nor the results_.
160
+
161
+ ### Comparisons-Related Option
162
+
163
+ - `--diff` displays the mismatches (if any) between the imported and actual operations.
164
+
165
+ ## Usage 2. Check Address Against Xpub
166
+
167
+ _Check if an address has been derived from a master public key._
168
+
169
+ ### Perfect Match
170
+
171
+ `$ xpub-scan <xpub> --address <address>`
172
+
173
+ ### Partial Match
174
+
175
+ Add `?` where there is uncertainty about a character in the address. For instance: `1MYaYeZhDp?m3YtvqBMXQQN??YCz?7NqgF`
176
+
177
+ ## Docker
178
+
179
+ Build: `$ docker build -t xpubscan .`
180
+
181
+ Run: `$ docker run xpubscan <xpub> [optional: <args>]`
182
+
183
+ ## Interface
184
+
185
+ ### Check Balance
186
+
187
+ When an analysis is performed, 3 elements are displayed in the following order:
188
+
189
+ - The analysis of each derived active address (type, path, address, current balance, total in `←`, total out `→`)
190
+ - The transactions ordered by date (date, block number, address, in `←` | out `→` | sent to self `⮂` | sent to sibling `↺` | received as change from non-sibling `c`)
191
+ - A summary: total number of transactions and total balance by address type
192
+
193
+ ### Xpub and Address Comparison
194
+
195
+ The derived addresses are displayed during the analysis. Perfect matches are displayed in green (with the corresponding derivation path). Partial matches are displayed in blue (also with the derivation path). No matches are rendered in red.
196
+
197
+ ## Configure
198
+
199
+ ### Change Settings
200
+
201
+ 1. Modify `./src/settings.ts`
202
+ 2. rebuild the tool: `$ npm run build`
203
+ 3. Re-run it: `$ node ./lib/scan.js <xpub> …`
204
+
205
+ ### Change External Provider
206
+
207
+ **It is strongly encouraged to use the custom provider for reliable results.**
208
+
209
+ [Crypto APIs](https://cryptoapis.io/) can be used as a custom provider. In this context, a valid [v2 API key](https://dashboard.cryptoapis.io/account/api-keys) is required.
210
+
211
+ 1. At the root of the project, rename `.env.template` to `.env`
212
+ 2. In `.env`, set the `XPUB_SCAN_CUSTOM_API_KEY_V2` (corresponding to your Crypto APIs v2 API key—e.g.: `XPUB_SCAN_CUSTOM_API_KEY_V2=abcd6eacca264f7530eb2f7025a84f8`)
213
+ 3. rebuild the tool: `$ npm run build`
214
+ 4. Re-run it: `$ node ./lib/scan.js <xpub> …`
215
+ 5. Ensure that, when running the tool, it shows that the _custom_ provider is being used
@@ -0,0 +1,75 @@
1
+ import { _private } from "../../src/actions/checkAddress";
2
+ import { DERIVATION_SCOPE } from "../../src/configuration/settings";
3
+
4
+ const testSearchFunction = (xpub: string, providedAddress: string) => {
5
+ return _private.search(
6
+ xpub,
7
+ providedAddress,
8
+ DERIVATION_SCOPE.quick_search,
9
+ "quick search",
10
+ );
11
+ };
12
+
13
+ describe("check whether addresses belong or not to xpubs", () => {
14
+ /* eslint-disable */
15
+ console.log = function () {};
16
+
17
+ const xpub =
18
+ "xpub6C9vKwUFiBLbQKS6mhEAtEYhS24sVz8MkvMjxQSECTZVCnFmy675zojLthvXVuQf15RT6ggmt7PTgLBV2tLHHdJenoEkNWe5VPBETncxf2q";
19
+
20
+ describe("addresses NOT belonging to the xpub", () => {
21
+ it("complete legacy address", () => {
22
+ const providedAddress = "1C3DK2BwhPRZ7e14V7pHj1jDWbTrP3qFnA";
23
+ const expectedResult = {};
24
+
25
+ const match = testSearchFunction(xpub, providedAddress);
26
+
27
+ expect(match).toEqual(expectedResult);
28
+ });
29
+
30
+ it("partial legacy address", () => {
31
+ const providedAddress = "1C3DK2BwhPRZ7e?4V7pHj1jDWbTrP3qF?A";
32
+ const expectedResult = {};
33
+
34
+ const match = testSearchFunction(xpub, providedAddress);
35
+
36
+ expect(match).toEqual(expectedResult);
37
+ });
38
+
39
+ it("complete SegWit address", () => {
40
+ const providedAddress = "3Bb1aYVQXiwowamm5kZDweK5KxVnzNKABA";
41
+ const expectedResult = {};
42
+
43
+ const match = testSearchFunction(xpub, providedAddress);
44
+
45
+ expect(match).toEqual(expectedResult);
46
+ });
47
+
48
+ it("partial SegWit address", () => {
49
+ const providedAddress = "3Bb1aY??Xiwowamm5kZDweK5KxVnzNKA?A";
50
+ const expectedResult = {};
51
+
52
+ const match = testSearchFunction(xpub, providedAddress);
53
+
54
+ expect(match).toEqual(expectedResult);
55
+ });
56
+
57
+ it("complete native SegWit address", () => {
58
+ const providedAddress = "bc1qxrkzds606tun4qghc8e6c5z4vuk3c0692cy0fA";
59
+ const expectedResult = {};
60
+
61
+ const match = testSearchFunction(xpub, providedAddress);
62
+
63
+ expect(match).toEqual(expectedResult);
64
+ });
65
+
66
+ it("partial native SegWit address", () => {
67
+ const providedAddress = "bc1qxrkzds???tun4qghc8e6c5z4vuk3c0692cy0fA";
68
+ const expectedResult = {};
69
+
70
+ const match = testSearchFunction(xpub, providedAddress);
71
+
72
+ expect(match).toEqual(expectedResult);
73
+ });
74
+ });
75
+ });
@@ -0,0 +1,87 @@
1
+ import { _private } from "../../src/actions/checkAddress";
2
+ import { DERIVATION_SCOPE } from "../../src/configuration/settings";
3
+
4
+ const testSearchFunction = (xpub: string, providedAddress: string) => {
5
+ return _private.search(
6
+ xpub,
7
+ providedAddress,
8
+ DERIVATION_SCOPE.quick_search,
9
+ "quick search",
10
+ );
11
+ };
12
+
13
+ describe("check whether addresses belong or not to xpubs", () => {
14
+ /* eslint-disable */
15
+ console.log = function () {};
16
+
17
+ const xpub =
18
+ "xpub6C9vKwUFiBLbQKS6mhEAtEYhS24sVz8MkvMjxQSECTZVCnFmy675zojLthvXVuQf15RT6ggmt7PTgLBV2tLHHdJenoEkNWe5VPBETncxf2q";
19
+
20
+ describe("addresses belonging to the xpub", () => {
21
+ it("complete legacy address — m/2/588", () => {
22
+ const providedAddress = "1C3DK2BwhPRZ7e14V7pHj1jDWbTrP3qFnt";
23
+ const expectedResult = { account: 2, index: 588 };
24
+
25
+ const match = testSearchFunction(xpub, providedAddress);
26
+
27
+ expect(match).toEqual(expectedResult);
28
+ });
29
+
30
+ it("partial legacy address — m/2/588", () => {
31
+ const providedAddress = "1C3DK?BwhPRZ7e14V7?Hj1jDWbTrP3?Fnt";
32
+ const expectedResult = {
33
+ account: 2,
34
+ index: 588,
35
+ partial: "1C3DK2BwhPRZ7e14V7pHj1jDWbTrP3qFnt",
36
+ };
37
+
38
+ const match = testSearchFunction(xpub, providedAddress);
39
+
40
+ expect(match).toEqual(expectedResult);
41
+ });
42
+
43
+ it("complete SegWit address — m/3/999", () => {
44
+ const providedAddress = "3Bb1aYVQXiwowamm5kZDweK5KxVnzNKABp";
45
+ const expectedResult = { account: 3, index: 999 };
46
+
47
+ const match = testSearchFunction(xpub, providedAddress);
48
+
49
+ expect(match).toEqual(expectedResult);
50
+ });
51
+
52
+ it("partial SegWit address — m/3/999", () => {
53
+ const providedAddress = "3Bb1aYVQ??wowamm5kZDweK5KxVnzNKA??";
54
+ const expectedResult = {
55
+ account: 3,
56
+ index: 999,
57
+ partial: "3Bb1aYVQXiwowamm5kZDweK5KxVnzNKABp",
58
+ };
59
+
60
+ const match = testSearchFunction(xpub, providedAddress);
61
+
62
+ expect(match).toEqual(expectedResult);
63
+ });
64
+
65
+ it("complete native SegWit address — m/2/278", () => {
66
+ const providedAddress = "bc1qxrkzds606tun4qghc8e6c5z4vuk3c0692cy0fl";
67
+ const expectedResult = { account: 2, index: 278 };
68
+
69
+ const match = testSearchFunction(xpub, providedAddress);
70
+
71
+ expect(match).toEqual(expectedResult);
72
+ });
73
+
74
+ it("partial native SegWit address — m/2/278", () => {
75
+ const providedAddress = "bc1qxrkzds?06tun4qghc8e6c5z4vuk3c0692cy0??";
76
+ const expectedResult = {
77
+ account: 2,
78
+ index: 278,
79
+ partial: "bc1qxrkzds606tun4qghc8e6c5z4vuk3c0692cy0fl",
80
+ };
81
+
82
+ const match = testSearchFunction(xpub, providedAddress);
83
+
84
+ expect(match).toEqual(expectedResult);
85
+ });
86
+ });
87
+ });
@@ -0,0 +1,43 @@
1
+ import { _private } from "../../src/actions/checkAddress";
2
+ import { DERIVATION_SCOPE } from "../../src/configuration/settings";
3
+
4
+ const testSearchFunction = (xpub: string, providedAddress: string) => {
5
+ return _private.search(
6
+ xpub,
7
+ providedAddress,
8
+ DERIVATION_SCOPE.quick_search,
9
+ "quick search",
10
+ );
11
+ };
12
+
13
+ describe("check whether addresses belong or not to xpubs", () => {
14
+ /* eslint-disable */
15
+ console.log = function () {};
16
+
17
+ const xpub =
18
+ "dgub8rDzyFqzw35B8zSqrW9sHDivXL2YmcGEVKyRMhPh8SoeUmkGozD5YzNyEkSH1T9zhvy9iQzns7igxrhQkg4jETWna4X1AUC4MT3YgHenTMB";
19
+
20
+ describe("addresses belonging to the xpub", () => {
21
+ it("complete address — m/1/640", () => {
22
+ const providedAddress = "DSZsASgFRbGVhRnPE9bmeyd8s9izatDRXL";
23
+ const expectedResult = { account: 1, index: 640 };
24
+
25
+ const match = testSearchFunction(xpub, providedAddress);
26
+
27
+ expect(match).toEqual(expectedResult);
28
+ });
29
+
30
+ it("partial address — m/1/640", () => {
31
+ const providedAddress = "DSZsASgFR??VhRnPE9bmeyd8s9izatDR?L";
32
+ const expectedResult = {
33
+ account: 1,
34
+ index: 640,
35
+ partial: "DSZsASgFRbGVhRnPE9bmeyd8s9izatDRXL",
36
+ };
37
+
38
+ const match = testSearchFunction(xpub, providedAddress);
39
+
40
+ expect(match).toEqual(expectedResult);
41
+ });
42
+ });
43
+ });
@@ -0,0 +1,75 @@
1
+ import { _private } from "../../src/actions/checkAddress";
2
+ import { DERIVATION_SCOPE } from "../../src/configuration/settings";
3
+
4
+ const testSearchFunction = (xpub: string, providedAddress: string) => {
5
+ return _private.search(
6
+ xpub,
7
+ providedAddress,
8
+ DERIVATION_SCOPE.quick_search,
9
+ "quick search",
10
+ );
11
+ };
12
+
13
+ describe("check whether addresses belong or not to xpubs", () => {
14
+ /* eslint-disable */
15
+ console.log = function () {};
16
+
17
+ const xpub =
18
+ "Ltub2ZoLFXBt7mLeb4out9duUxMmqCSX9mqi73NcQ8nyjQsJEm76JP1poExdj9rRCFfHyuUVKgj5t2B2EBsmFvKivKzVpmKKZ4XiAVx65s3WZ8j";
19
+
20
+ describe("addresses NOT belonging to the xpub", () => {
21
+ it("complete legacy address", () => {
22
+ const providedAddress = "LXSUUS8Phpm4zGsdfA7pFsDN17yyK8N2KA";
23
+ const expectedResult = {};
24
+
25
+ const match = testSearchFunction(xpub, providedAddress);
26
+
27
+ expect(match).toEqual(expectedResult);
28
+ });
29
+
30
+ it("partial legacy address", () => {
31
+ const providedAddress = "LXSUUS8Ph?m4zGsdfA7pFsDN17yyK8N2?A";
32
+ const expectedResult = {};
33
+
34
+ const match = testSearchFunction(xpub, providedAddress);
35
+
36
+ expect(match).toEqual(expectedResult);
37
+ });
38
+
39
+ it("complete SegWit address", () => {
40
+ const providedAddress = "MNY33b2fP4zLQ7W9oBGgw9TfFAm2TxWPAA";
41
+ const expectedResult = {};
42
+
43
+ const match = testSearchFunction(xpub, providedAddress);
44
+
45
+ expect(match).toEqual(expectedResult);
46
+ });
47
+
48
+ it("partial SegWit address", () => {
49
+ const providedAddress = "MNY33b2fP4z?Q7W9oBGgw9TfFAm2T??PAA";
50
+ const expectedResult = {};
51
+
52
+ const match = testSearchFunction(xpub, providedAddress);
53
+
54
+ expect(match).toEqual(expectedResult);
55
+ });
56
+
57
+ it("complete native SegWit address", () => {
58
+ const providedAddress = "bc1qxrkzds606tun4qghc8e6c5z4vuk3c0692cy0AA";
59
+ const expectedResult = {};
60
+
61
+ const match = testSearchFunction(xpub, providedAddress);
62
+
63
+ expect(match).toEqual(expectedResult);
64
+ });
65
+
66
+ it("partial native SegWit address", () => {
67
+ const providedAddress = "bc1qxrkzds606tun?qghc8e6c5z4vuk3c0692cy0A?";
68
+ const expectedResult = {};
69
+
70
+ const match = testSearchFunction(xpub, providedAddress);
71
+
72
+ expect(match).toEqual(expectedResult);
73
+ });
74
+ });
75
+ });