@dignetwork/dig-sdk 0.0.1-alpha.17 → 0.0.1-alpha.171

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 (87) hide show
  1. package/dist/DataIntegrityTree/DataIntegrityTree.d.ts +10 -1
  2. package/dist/DataIntegrityTree/DataIntegrityTree.d.ts.map +1 -1
  3. package/dist/DataIntegrityTree/DataIntegrityTree.js +77 -10
  4. package/dist/DigNetwork/ContentServer.d.ts +24 -5
  5. package/dist/DigNetwork/ContentServer.d.ts.map +1 -1
  6. package/dist/DigNetwork/ContentServer.js +237 -27
  7. package/dist/DigNetwork/DigNetwork.d.ts +15 -9
  8. package/dist/DigNetwork/DigNetwork.d.ts.map +1 -1
  9. package/dist/DigNetwork/DigNetwork.js +129 -189
  10. package/dist/DigNetwork/DigPeer.d.ts +8 -3
  11. package/dist/DigNetwork/DigPeer.d.ts.map +1 -1
  12. package/dist/DigNetwork/DigPeer.js +72 -115
  13. package/dist/DigNetwork/IncentiveServer.d.ts.map +1 -1
  14. package/dist/DigNetwork/IncentiveServer.js +6 -5
  15. package/dist/DigNetwork/PropagationServer.d.ts +88 -33
  16. package/dist/DigNetwork/PropagationServer.d.ts.map +1 -1
  17. package/dist/DigNetwork/PropagationServer.js +635 -358
  18. package/dist/blockchain/DataStore.d.ts +25 -7
  19. package/dist/blockchain/DataStore.d.ts.map +1 -1
  20. package/dist/blockchain/DataStore.js +114 -159
  21. package/dist/blockchain/DataStoreSerializer.d.ts +1 -1
  22. package/dist/blockchain/DataStoreSerializer.d.ts.map +1 -1
  23. package/dist/blockchain/FullNodePeer.d.ts +95 -10
  24. package/dist/blockchain/FullNodePeer.d.ts.map +1 -1
  25. package/dist/blockchain/FullNodePeer.js +325 -115
  26. package/dist/blockchain/ServerCoin.d.ts +13 -5
  27. package/dist/blockchain/ServerCoin.d.ts.map +1 -1
  28. package/dist/blockchain/ServerCoin.js +88 -28
  29. package/dist/blockchain/StoreMonitorRegistry.d.ts +85 -0
  30. package/dist/blockchain/StoreMonitorRegistry.d.ts.map +1 -0
  31. package/dist/blockchain/StoreMonitorRegistry.js +238 -0
  32. package/dist/blockchain/Wallet.d.ts +2 -2
  33. package/dist/blockchain/Wallet.d.ts.map +1 -1
  34. package/dist/blockchain/Wallet.js +50 -18
  35. package/dist/blockchain/coins.d.ts +1 -2
  36. package/dist/blockchain/coins.d.ts.map +1 -1
  37. package/dist/blockchain/coins.js +1 -55
  38. package/dist/blockchain/index.d.ts +1 -0
  39. package/dist/blockchain/index.d.ts.map +1 -1
  40. package/dist/blockchain/index.js +1 -0
  41. package/dist/types.d.ts +2 -0
  42. package/dist/types.d.ts.map +1 -1
  43. package/dist/utils/ContentScanner.d.ts +63 -0
  44. package/dist/utils/ContentScanner.d.ts.map +1 -0
  45. package/dist/utils/ContentScanner.js +175 -0
  46. package/dist/utils/DigCache.d.ts +38 -0
  47. package/dist/utils/DigCache.d.ts.map +1 -0
  48. package/dist/utils/DigCache.js +231 -0
  49. package/dist/utils/Environment.d.ts +21 -0
  50. package/dist/utils/Environment.d.ts.map +1 -0
  51. package/dist/utils/Environment.js +93 -0
  52. package/dist/utils/FileCache.d.ts +1 -1
  53. package/dist/utils/FileCache.d.ts.map +1 -1
  54. package/dist/utils/FileCache.js +2 -2
  55. package/dist/utils/FileTransfer.d.ts +47 -0
  56. package/dist/utils/FileTransfer.d.ts.map +1 -0
  57. package/dist/utils/FileTransfer.js +209 -0
  58. package/dist/utils/NconfManager.js +2 -1
  59. package/dist/utils/PeerRanker.d.ts +55 -0
  60. package/dist/utils/PeerRanker.d.ts.map +1 -0
  61. package/dist/utils/PeerRanker.js +186 -0
  62. package/dist/utils/StoreArchiveManager.d.ts +45 -0
  63. package/dist/utils/StoreArchiveManager.d.ts.map +1 -0
  64. package/dist/utils/StoreArchiveManager.js +153 -0
  65. package/dist/utils/config.d.ts +4 -3
  66. package/dist/utils/config.d.ts.map +1 -1
  67. package/dist/utils/config.js +13 -8
  68. package/dist/utils/directoryUtils.d.ts +16 -0
  69. package/dist/utils/directoryUtils.d.ts.map +1 -1
  70. package/dist/utils/directoryUtils.js +66 -0
  71. package/dist/utils/index.d.ts +4 -1
  72. package/dist/utils/index.d.ts.map +1 -1
  73. package/dist/utils/index.js +4 -1
  74. package/dist/utils/merkle.d.ts +2 -0
  75. package/dist/utils/merkle.d.ts.map +1 -0
  76. package/dist/utils/merkle.js +28 -0
  77. package/dist/utils/network.d.ts +2 -1
  78. package/dist/utils/network.d.ts.map +1 -1
  79. package/dist/utils/network.js +40 -15
  80. package/dist/utils/promiseUtils.d.ts +27 -0
  81. package/dist/utils/promiseUtils.d.ts.map +1 -0
  82. package/dist/utils/promiseUtils.js +69 -0
  83. package/dist/utils/ssl.js +2 -2
  84. package/package.json +19 -5
  85. package/dist/utils/deltaUtils.d.ts +0 -2
  86. package/dist/utils/deltaUtils.d.ts.map +0 -1
  87. package/dist/utils/deltaUtils.js +0 -83
@@ -0,0 +1,55 @@
1
+ export interface PeerMetrics {
2
+ ip: string;
3
+ latency: number;
4
+ bandwidth: number;
5
+ }
6
+ /**
7
+ * Utility class to rank peers based on latency and upload bandwidth using HTTPS with mTLS.
8
+ */
9
+ export declare class PeerRanker {
10
+ private ipAddresses;
11
+ private static certPath;
12
+ private static keyPath;
13
+ private timeout;
14
+ private uploadTestSize;
15
+ private sortedPeers;
16
+ private currentIndex;
17
+ /**
18
+ * Constructs a PeerRanker instance.
19
+ * @param ipAddresses - Array of IP addresses to rank.
20
+ */
21
+ constructor(ipAddresses: string[], timeout?: number, uploadTestSize?: number);
22
+ /**
23
+ * Measures the latency of a given IP address using an HTTPS request.
24
+ * Tries HEAD first, then falls back to GET if HEAD is not supported.
25
+ * If the latency is cached, returns the cached value.
26
+ * @param ip - The IP address of the peer.
27
+ * @returns Promise resolving to the latency in milliseconds or rejecting if the peer fails.
28
+ */
29
+ private measureLatency;
30
+ /**
31
+ * Measures the upload bandwidth of a given IP address by sending random data.
32
+ * If the bandwidth is cached, returns the cached value.
33
+ * @param ip - The IP address of the peer.
34
+ * @returns Promise resolving to the upload bandwidth in bytes per second or rejecting if the peer fails.
35
+ */
36
+ private measureBandwidth;
37
+ /**
38
+ * Ranks the peers based on measured latency and upload bandwidth.
39
+ * Unresponsive peers are excluded from the final ranking.
40
+ * @param cooldown - Cooldown time in milliseconds between batches.
41
+ * @returns Promise resolving to an array of PeerMetrics sorted by latency and bandwidth.
42
+ */
43
+ rankPeers(cooldown?: number): Promise<PeerMetrics[]>;
44
+ /**
45
+ * Returns the next best peer based on the ranking.
46
+ * Cycles through the list, resetting to the beginning once the end is reached.
47
+ * @returns The next PeerMetrics object or null if no peers are available.
48
+ */
49
+ GetNextBestPeer(): PeerMetrics | null;
50
+ /**
51
+ * Resets the internal iterator to start from the beginning of the sorted list.
52
+ */
53
+ resetIterator(): void;
54
+ }
55
+ //# sourceMappingURL=PeerRanker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PeerRanker.d.ts","sourceRoot":"","sources":["../../src/utils/PeerRanker.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,WAAW,CAAW;IAC9B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAS;IAChC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAS;IAC/B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,cAAc,CAAS;IAG/B,OAAO,CAAC,WAAW,CAAqB;IACxC,OAAO,CAAC,YAAY,CAAa;IAEjC;;;OAGG;gBACS,WAAW,EAAE,MAAM,EAAE,EAAE,OAAO,GAAE,MAAa,EAAE,cAAc,GAAE,MAAoB;IAW/F;;;;;;OAMG;YACW,cAAc;IAkD5B;;;;;OAKG;YACW,gBAAgB;IA2C9B;;;;;OAKG;IACU,SAAS,CAAC,QAAQ,GAAE,MAAY,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAmCtE;;;;OAIG;IACI,eAAe,IAAI,WAAW,GAAG,IAAI;IAW5C;;OAEG;IACI,aAAa,IAAI,IAAI;CAG7B"}
@@ -0,0 +1,186 @@
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.PeerRanker = void 0;
7
+ const axios_1 = __importDefault(require("axios"));
8
+ const fs_1 = __importDefault(require("fs"));
9
+ const https_1 = __importDefault(require("https"));
10
+ const DigCache_1 = require("./DigCache");
11
+ const ssl_1 = require("./ssl");
12
+ const promiseUtils_1 = require("./promiseUtils");
13
+ // Cache with TTL of 1 day (86400 seconds)
14
+ const peerCache = new DigCache_1.DigCache({ stdTTL: 86400 });
15
+ /**
16
+ * Utility class to rank peers based on latency and upload bandwidth using HTTPS with mTLS.
17
+ */
18
+ class PeerRanker {
19
+ /**
20
+ * Constructs a PeerRanker instance.
21
+ * @param ipAddresses - Array of IP addresses to rank.
22
+ */
23
+ constructor(ipAddresses, timeout = 5000, uploadTestSize = 1024 * 1024) {
24
+ // Internal properties for iteration
25
+ this.sortedPeers = [];
26
+ this.currentIndex = 0;
27
+ this.ipAddresses = ipAddresses;
28
+ this.timeout = timeout; // Allow customizable timeout
29
+ this.uploadTestSize = uploadTestSize; // Default upload size: 1MB
30
+ // Fetch the SSL certificates used for mTLS.
31
+ const { certPath, keyPath } = (0, ssl_1.getOrCreateSSLCerts)();
32
+ PeerRanker.certPath = certPath;
33
+ PeerRanker.keyPath = keyPath;
34
+ }
35
+ /**
36
+ * Measures the latency of a given IP address using an HTTPS request.
37
+ * Tries HEAD first, then falls back to GET if HEAD is not supported.
38
+ * If the latency is cached, returns the cached value.
39
+ * @param ip - The IP address of the peer.
40
+ * @returns Promise resolving to the latency in milliseconds or rejecting if the peer fails.
41
+ */
42
+ async measureLatency(ip) {
43
+ const cachedMetrics = await peerCache.get(ip);
44
+ if (cachedMetrics && cachedMetrics.latency) {
45
+ return cachedMetrics.latency;
46
+ }
47
+ const url = `https://${ip}:4159/diagnostics/ping`;
48
+ const configHead = {
49
+ url: url,
50
+ method: 'HEAD',
51
+ httpsAgent: new https_1.default.Agent({
52
+ cert: fs_1.default.readFileSync(PeerRanker.certPath),
53
+ key: fs_1.default.readFileSync(PeerRanker.keyPath),
54
+ rejectUnauthorized: false,
55
+ }),
56
+ timeout: this.timeout,
57
+ validateStatus: (status) => status < 500,
58
+ };
59
+ const startTime = Date.now();
60
+ try {
61
+ const response = await (0, axios_1.default)(configHead);
62
+ if (response.status === 405) {
63
+ const configGet = {
64
+ url: url,
65
+ method: 'GET',
66
+ httpsAgent: new https_1.default.Agent({
67
+ cert: fs_1.default.readFileSync(PeerRanker.certPath),
68
+ key: fs_1.default.readFileSync(PeerRanker.keyPath),
69
+ rejectUnauthorized: false,
70
+ }),
71
+ timeout: this.timeout,
72
+ headers: {
73
+ 'Range': 'bytes=0-0',
74
+ },
75
+ validateStatus: (status) => status < 500,
76
+ };
77
+ await (0, axios_1.default)(configGet);
78
+ }
79
+ const latency = Date.now() - startTime;
80
+ // Cache the latency for the IP
81
+ peerCache.set(ip, { ...cachedMetrics, latency });
82
+ return latency;
83
+ }
84
+ catch (error) {
85
+ throw new Error(`Latency measurement failed for IP ${ip}`);
86
+ }
87
+ }
88
+ /**
89
+ * Measures the upload bandwidth of a given IP address by sending random data.
90
+ * If the bandwidth is cached, returns the cached value.
91
+ * @param ip - The IP address of the peer.
92
+ * @returns Promise resolving to the upload bandwidth in bytes per second or rejecting if the peer fails.
93
+ */
94
+ async measureBandwidth(ip) {
95
+ const cachedMetrics = await peerCache.get(ip);
96
+ if (cachedMetrics && cachedMetrics.bandwidth) {
97
+ return cachedMetrics.bandwidth;
98
+ }
99
+ const url = `https://${ip}:4159/diagnostics/bandwidth`;
100
+ const randomData = Buffer.alloc(this.uploadTestSize, 'a');
101
+ const config = {
102
+ url: url,
103
+ method: 'POST',
104
+ data: randomData,
105
+ headers: {
106
+ 'Content-Type': 'application/octet-stream',
107
+ 'Content-Length': this.uploadTestSize,
108
+ },
109
+ httpsAgent: new https_1.default.Agent({
110
+ cert: fs_1.default.readFileSync(PeerRanker.certPath),
111
+ key: fs_1.default.readFileSync(PeerRanker.keyPath),
112
+ rejectUnauthorized: false,
113
+ }),
114
+ timeout: this.timeout,
115
+ maxContentLength: Infinity,
116
+ maxBodyLength: Infinity,
117
+ };
118
+ const startTime = Date.now();
119
+ try {
120
+ await (0, axios_1.default)(config);
121
+ const timeElapsed = (Date.now() - startTime) / 1000;
122
+ const bandwidth = this.uploadTestSize / timeElapsed;
123
+ // Cache the bandwidth for the IP
124
+ peerCache.set(ip, { ...cachedMetrics, bandwidth });
125
+ return bandwidth;
126
+ }
127
+ catch (error) {
128
+ throw new Error(`Bandwidth measurement failed for IP ${ip}`);
129
+ }
130
+ }
131
+ /**
132
+ * Ranks the peers based on measured latency and upload bandwidth.
133
+ * Unresponsive peers are excluded from the final ranking.
134
+ * @param cooldown - Cooldown time in milliseconds between batches.
135
+ * @returns Promise resolving to an array of PeerMetrics sorted by latency and bandwidth.
136
+ */
137
+ async rankPeers(cooldown = 500) {
138
+ const limit = 5; // Limit to 5 parallel requests at a time
139
+ const iteratorFn = async (ip) => {
140
+ try {
141
+ const [latency, bandwidth] = await Promise.all([
142
+ this.measureLatency(ip),
143
+ this.measureBandwidth(ip),
144
+ ]);
145
+ return { ip, latency, bandwidth };
146
+ }
147
+ catch (error) {
148
+ // Peer failed, skip it by returning null
149
+ return null;
150
+ }
151
+ };
152
+ // Process all peers with a concurrency limit and cooldown between batches
153
+ const peerMetrics = (await (0, promiseUtils_1.asyncPool)(limit, this.ipAddresses, iteratorFn, cooldown)).filter((metrics) => metrics !== null); // Use a type guard
154
+ // Sort by lowest latency first, then by highest bandwidth
155
+ peerMetrics.sort((a, b) => {
156
+ if (a.latency === b.latency) {
157
+ return b.bandwidth - a.bandwidth; // Higher bandwidth is better
158
+ }
159
+ return a.latency - b.latency; // Lower latency is better
160
+ });
161
+ this.sortedPeers = peerMetrics;
162
+ this.currentIndex = 0;
163
+ return peerMetrics;
164
+ }
165
+ /**
166
+ * Returns the next best peer based on the ranking.
167
+ * Cycles through the list, resetting to the beginning once the end is reached.
168
+ * @returns The next PeerMetrics object or null if no peers are available.
169
+ */
170
+ GetNextBestPeer() {
171
+ if (this.sortedPeers.length === 0) {
172
+ console.warn('Peer list is empty. Please run rankPeers() first.');
173
+ return null;
174
+ }
175
+ const peer = this.sortedPeers[this.currentIndex];
176
+ this.currentIndex = (this.currentIndex + 1) % this.sortedPeers.length;
177
+ return peer;
178
+ }
179
+ /**
180
+ * Resets the internal iterator to start from the beginning of the sorted list.
181
+ */
182
+ resetIterator() {
183
+ this.currentIndex = 0;
184
+ }
185
+ }
186
+ exports.PeerRanker = PeerRanker;
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Class for managing file archiving, extraction, and working with the 'data' folder.
3
+ */
4
+ declare class StoreArchiveManager {
5
+ private archivePath;
6
+ private outputStream;
7
+ /**
8
+ * Constructor that initializes the FileArchiveManager with a given path.
9
+ * @param archivePath - The path where the archive will be created.
10
+ */
11
+ constructor(archivePath: string);
12
+ /**
13
+ * Creates the archive at the specified path.
14
+ * @returns Promise<void>
15
+ */
16
+ createArchive(): Promise<void>;
17
+ /**
18
+ * Streams a file into the archive.
19
+ * @param filePath - The file to add to the archive.
20
+ * @param fileNameInArchive - The name the file should have inside the archive.
21
+ * @returns Promise<void>
22
+ */
23
+ addFileToArchive(filePath: string, fileNameInArchive: string): Promise<void>;
24
+ /**
25
+ * Extracts a file from the archive to a specified directory.
26
+ * @param extractToPath - The path where the file should be extracted.
27
+ * @returns Promise<void>
28
+ */
29
+ extractArchive(extractToPath: string): Promise<void>;
30
+ /**
31
+ * Merges another archive into the current one.
32
+ * Extracts files from the given archive and adds them into the current archive.
33
+ * @param archiveToMergePath - The path of the archive to be merged.
34
+ * @returns Promise<void>
35
+ */
36
+ mergeArchive(archiveToMergePath: string): Promise<void>;
37
+ /**
38
+ * Adds extracted files to the current archive.
39
+ * @param extractedFolderPath - The path of the folder containing extracted files.
40
+ * @returns Promise<void>
41
+ */
42
+ private addExtractedFilesToArchive;
43
+ }
44
+ export default StoreArchiveManager;
45
+ //# sourceMappingURL=StoreArchiveManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StoreArchiveManager.d.ts","sourceRoot":"","sources":["../../src/utils/StoreArchiveManager.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,cAAM,mBAAmB;IACrB,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,YAAY,CAAwB;IAE5C;;;OAGG;gBACS,WAAW,EAAE,MAAM;IAK/B;;;OAGG;IACU,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAsB3C;;;;;OAKG;IACU,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBzF;;;;OAIG;IACU,cAAc,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASjE;;;;;OAKG;IACU,YAAY,CAAC,kBAAkB,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiCpE;;;;OAIG;YACW,0BAA0B;CAkB3C;AAED,eAAe,mBAAmB,CAAC"}
@@ -0,0 +1,153 @@
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
+ const fs = __importStar(require("fs"));
27
+ const path = __importStar(require("path"));
28
+ const archiver = __importStar(require("archiver"));
29
+ const unzipper = __importStar(require("unzipper"));
30
+ /**
31
+ * Class for managing file archiving, extraction, and working with the 'data' folder.
32
+ */
33
+ class StoreArchiveManager {
34
+ /**
35
+ * Constructor that initializes the FileArchiveManager with a given path.
36
+ * @param archivePath - The path where the archive will be created.
37
+ */
38
+ constructor(archivePath) {
39
+ this.archivePath = archivePath;
40
+ this.outputStream = null;
41
+ }
42
+ /**
43
+ * Creates the archive at the specified path.
44
+ * @returns Promise<void>
45
+ */
46
+ async createArchive() {
47
+ return new Promise((resolve, reject) => {
48
+ this.outputStream = fs.createWriteStream(this.archivePath);
49
+ // @ts-ignore
50
+ const archive = archiver('zip', {
51
+ zlib: { level: 9 }
52
+ });
53
+ this.outputStream.on('close', () => {
54
+ console.log(`${archive.pointer()} total bytes`);
55
+ console.log('Archive has been finalized and output file descriptor has closed.');
56
+ resolve();
57
+ });
58
+ archive.on('error', (err) => {
59
+ reject(err);
60
+ });
61
+ archive.pipe(this.outputStream);
62
+ });
63
+ }
64
+ /**
65
+ * Streams a file into the archive.
66
+ * @param filePath - The file to add to the archive.
67
+ * @param fileNameInArchive - The name the file should have inside the archive.
68
+ * @returns Promise<void>
69
+ */
70
+ async addFileToArchive(filePath, fileNameInArchive) {
71
+ if (!this.outputStream) {
72
+ throw new Error('Archive not yet created.');
73
+ }
74
+ return new Promise((resolve, reject) => {
75
+ // @ts-ignore
76
+ const archive = archiver('zip', { zlib: { level: 9 } });
77
+ const fileStream = fs.createReadStream(filePath);
78
+ archive.append(fileStream, { name: fileNameInArchive });
79
+ archive.finalize();
80
+ archive.on('finish', resolve);
81
+ archive.on('error', reject);
82
+ });
83
+ }
84
+ /**
85
+ * Extracts a file from the archive to a specified directory.
86
+ * @param extractToPath - The path where the file should be extracted.
87
+ * @returns Promise<void>
88
+ */
89
+ async extractArchive(extractToPath) {
90
+ return new Promise((resolve, reject) => {
91
+ fs.createReadStream(this.archivePath)
92
+ .pipe(unzipper.Extract({ path: extractToPath }))
93
+ .on('close', resolve)
94
+ .on('error', reject);
95
+ });
96
+ }
97
+ /**
98
+ * Merges another archive into the current one.
99
+ * Extracts files from the given archive and adds them into the current archive.
100
+ * @param archiveToMergePath - The path of the archive to be merged.
101
+ * @returns Promise<void>
102
+ */
103
+ async mergeArchive(archiveToMergePath) {
104
+ if (!this.outputStream) {
105
+ throw new Error('Archive not yet created.');
106
+ }
107
+ return new Promise((resolve, reject) => {
108
+ const tempExtractPath = path.join(__dirname, 'tempExtract');
109
+ // Ensure the temp directory exists
110
+ if (!fs.existsSync(tempExtractPath)) {
111
+ fs.mkdirSync(tempExtractPath);
112
+ }
113
+ // Step 1: Extract the contents of the archive to be merged
114
+ fs.createReadStream(archiveToMergePath)
115
+ .pipe(unzipper.Extract({ path: tempExtractPath }))
116
+ .on('close', async () => {
117
+ try {
118
+ // Step 2: Read the extracted files and add them to the current archive
119
+ await this.addExtractedFilesToArchive(tempExtractPath);
120
+ // Clean up: Delete the temporary directory
121
+ fs.rmSync(tempExtractPath, { recursive: true, force: true });
122
+ resolve();
123
+ }
124
+ catch (error) {
125
+ reject(error);
126
+ }
127
+ })
128
+ .on('error', reject);
129
+ });
130
+ }
131
+ /**
132
+ * Adds extracted files to the current archive.
133
+ * @param extractedFolderPath - The path of the folder containing extracted files.
134
+ * @returns Promise<void>
135
+ */
136
+ async addExtractedFilesToArchive(extractedFolderPath) {
137
+ const files = fs.readdirSync(extractedFolderPath);
138
+ for (const file of files) {
139
+ const fullFilePath = path.join(extractedFolderPath, file);
140
+ const stat = fs.statSync(fullFilePath);
141
+ if (stat.isFile()) {
142
+ const relativePath = path.relative(extractedFolderPath, fullFilePath);
143
+ // Add the file into the current archive
144
+ await this.addFileToArchive(fullFilePath, relativePath);
145
+ }
146
+ else if (stat.isDirectory()) {
147
+ // Recursively add files from nested directories
148
+ await this.addExtractedFilesToArchive(fullFilePath);
149
+ }
150
+ }
151
+ }
152
+ }
153
+ exports.default = StoreArchiveManager;
@@ -1,12 +1,12 @@
1
1
  import { DigConfig } from "../types";
2
2
  export declare const NETWORK_AGG_SIG_DATA = "ccd5bb71183532bff220ba46c268991a3ff07eb358e8255a65c30a2dce0e5fbb";
3
+ export declare const MAIN_NET_GENISES_CHALLENGE = "ccd5bb71183532bff220ba46c268991a3ff07eb358e8255a65c30a2dce0e5fbb";
3
4
  export declare const MIN_HEIGHT = 5777842;
4
5
  export declare const MIN_HEIGHT_HEADER_HASH = "b29a4daac2434fd17a36e15ba1aac5d65012d4a66f99bed0bf2b5342e92e562c";
5
6
  export declare const DIG_FOLDER_PATH: string;
6
7
  export declare const STORE_PATH: string;
7
8
  export declare const USER_DIR_PATH: string;
8
9
  export declare const CONFIG_FILE_PATH: string;
9
- export declare const getManifestFilePath: (storeId: string) => string;
10
10
  export declare const getHeightFilePath: (storeId: string) => string;
11
11
  export declare const createInitialConfig: () => void;
12
12
  export declare const setRemote: (remote: string) => void;
@@ -20,9 +20,10 @@ export declare const getCoinState: (storeId: string) => {
20
20
  };
21
21
  };
22
22
  /**
23
- * Retrieves a list of valid store folders (64-character hexadecimal names) in the DIG folder.
23
+ * Retrieves the list of valid store folders.
24
+ * If the STORE_PATH directory does not exist, it is created.
24
25
  *
25
- * @returns {string[]} An array of valid folder names.
26
+ * @returns {string[]} An array of valid store folder names.
26
27
  */
27
28
  export declare const getStoresList: () => string[];
28
29
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAKrC,eAAO,MAAM,oBAAoB,qEACmC,CAAC;AAErE,eAAO,MAAM,UAAU,UAAU,CAAC;AAClC,eAAO,MAAM,sBAAsB,qEACiC,CAAC;AAErE,eAAO,MAAM,eAAe,QACqC,CAAC;AAElE,eAAO,MAAM,UAAU,QAAuC,CAAC;AAE/D,eAAO,MAAM,aAAa,QAAkC,CAAC;AAC7D,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAE9E,eAAO,MAAM,mBAAmB,YAAa,MAAM,KAAG,MACN,CAAC;AAEjD,eAAO,MAAM,iBAAiB,YAAa,MAAM,KAAG,MACL,CAAC;AAEhD,eAAO,MAAM,mBAAmB,QAAO,IAItC,CAAC;AAEF,eAAO,MAAM,SAAS,WAAY,MAAM,KAAG,IAQ1C,CAAC;AAEF,eAAO,MAAM,cAAc,YAAa,MAAM,KAAG,IAQhD,CAAC;AAqBF,eAAO,MAAM,YAAY,YACd,MAAM,KACd;IACD,QAAQ,EAAE;QACR,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;CAYH,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,aAAa,QAAO,MAAM,EAOtC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,QAAa,OAAO,CAAC,MAAM,GAAG,IAAI,CAkC9D,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,YAAa,MAAM,KAAG,SAS/C,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,YAAa,MAAM,KAAG,SAoBjD,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,YACjB,MAAM,OACV,MAAM,SACJ,GAAG,KACT,IAMF,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,YAAa,MAAM,OAAO,MAAM,KAAG,IAcjE,CAAC"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAMrC,eAAO,MAAM,oBAAoB,qEACmC,CAAC;AAErE,eAAO,MAAM,0BAA0B,qEAAuB,CAAC;AAE/D,eAAO,MAAM,UAAU,UAAU,CAAC;AAClC,eAAO,MAAM,sBAAsB,qEACiC,CAAC;AAErE,eAAO,MAAM,eAAe,QACqC,CAAC;AAElE,eAAO,MAAM,UAAU,QAAuC,CAAC;AAE/D,eAAO,MAAM,aAAa,QAAkC,CAAC;AAC7D,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAE9E,eAAO,MAAM,iBAAiB,YAAa,MAAM,KAAG,MACL,CAAC;AAEhD,eAAO,MAAM,mBAAmB,QAAO,IAItC,CAAC;AAEF,eAAO,MAAM,SAAS,WAAY,MAAM,KAAG,IAQ1C,CAAC;AAEF,eAAO,MAAM,cAAc,YAAa,MAAM,KAAG,IAQhD,CAAC;AAqBF,eAAO,MAAM,YAAY,YACd,MAAM,KACd;IACD,QAAQ,EAAE;QACR,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;CAYH,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,aAAa,QAAO,MAAM,EAYtC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,QAAa,OAAO,CAAC,MAAM,GAAG,IAAI,CAkC9D,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,YAAa,MAAM,KAAG,SAS/C,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,YAAa,MAAM,KAAG,SAoBjD,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,YACjB,MAAM,OACV,MAAM,SACJ,GAAG,KACT,IAMF,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,YAAa,MAAM,OAAO,MAAM,KAAG,IAcjE,CAAC"}
@@ -26,20 +26,20 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
26
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
- exports.deleteDigConfigKey = exports.setDigConfigKey = exports.ensureDigConfig = exports.loadDigConfig = exports.getActiveStoreId = exports.getStoresList = exports.getCoinState = exports.setActiveStore = exports.setRemote = exports.createInitialConfig = exports.getHeightFilePath = exports.getManifestFilePath = exports.CONFIG_FILE_PATH = exports.USER_DIR_PATH = exports.STORE_PATH = exports.DIG_FOLDER_PATH = exports.MIN_HEIGHT_HEADER_HASH = exports.MIN_HEIGHT = exports.NETWORK_AGG_SIG_DATA = void 0;
29
+ exports.deleteDigConfigKey = exports.setDigConfigKey = exports.ensureDigConfig = exports.loadDigConfig = exports.getActiveStoreId = exports.getStoresList = exports.getCoinState = exports.setActiveStore = exports.setRemote = exports.createInitialConfig = exports.getHeightFilePath = exports.CONFIG_FILE_PATH = exports.USER_DIR_PATH = exports.STORE_PATH = exports.DIG_FOLDER_PATH = exports.MIN_HEIGHT_HEADER_HASH = exports.MIN_HEIGHT = exports.MAIN_NET_GENISES_CHALLENGE = exports.NETWORK_AGG_SIG_DATA = void 0;
30
30
  const fs = __importStar(require("fs"));
31
31
  const path = __importStar(require("path"));
32
32
  const inquirer_1 = __importDefault(require("inquirer"));
33
33
  const os_1 = __importDefault(require("os"));
34
+ const Environment_1 = require("./Environment");
34
35
  exports.NETWORK_AGG_SIG_DATA = "ccd5bb71183532bff220ba46c268991a3ff07eb358e8255a65c30a2dce0e5fbb";
36
+ exports.MAIN_NET_GENISES_CHALLENGE = exports.NETWORK_AGG_SIG_DATA;
35
37
  exports.MIN_HEIGHT = 5777842;
36
38
  exports.MIN_HEIGHT_HEADER_HASH = "b29a4daac2434fd17a36e15ba1aac5d65012d4a66f99bed0bf2b5342e92e562c";
37
- exports.DIG_FOLDER_PATH = process.env.DIG_FOLDER_PATH || path.join(process.cwd(), ".dig");
39
+ exports.DIG_FOLDER_PATH = Environment_1.Environment.DIG_FOLDER_PATH || path.join(process.cwd(), ".dig");
38
40
  exports.STORE_PATH = path.join(exports.DIG_FOLDER_PATH, "stores");
39
41
  exports.USER_DIR_PATH = path.join(os_1.default.homedir(), ".dig");
40
42
  exports.CONFIG_FILE_PATH = path.join(exports.DIG_FOLDER_PATH, "dig.config.json");
41
- const getManifestFilePath = (storeId) => path.join(exports.STORE_PATH, storeId, "manifest.dat");
42
- exports.getManifestFilePath = getManifestFilePath;
43
43
  const getHeightFilePath = (storeId) => path.join(exports.STORE_PATH, storeId, "height.json");
44
44
  exports.getHeightFilePath = getHeightFilePath;
45
45
  const createInitialConfig = () => {
@@ -82,7 +82,7 @@ const promptUserForSelection = async (options) => {
82
82
  return answer.selectedStore;
83
83
  };
84
84
  const getCoinState = (storeId) => {
85
- const stateFile = path.join(exports.STORE_PATH, `${storeId}.json`);
85
+ const stateFile = path.join(exports.USER_DIR_PATH, `${storeId}.json`);
86
86
  if (!fs.existsSync(stateFile)) {
87
87
  return {
88
88
  metadata: { rootHash: "", bytes: "", label: "", description: "" },
@@ -94,11 +94,16 @@ const getCoinState = (storeId) => {
94
94
  };
95
95
  exports.getCoinState = getCoinState;
96
96
  /**
97
- * Retrieves a list of valid store folders (64-character hexadecimal names) in the DIG folder.
97
+ * Retrieves the list of valid store folders.
98
+ * If the STORE_PATH directory does not exist, it is created.
98
99
  *
99
- * @returns {string[]} An array of valid folder names.
100
+ * @returns {string[]} An array of valid store folder names.
100
101
  */
101
102
  const getStoresList = () => {
103
+ // Check if the STORE_PATH exists, create it if not
104
+ if (!fs.existsSync(exports.STORE_PATH)) {
105
+ fs.mkdirSync(exports.STORE_PATH, { recursive: true });
106
+ }
102
107
  const folders = fs.readdirSync(exports.STORE_PATH);
103
108
  return folders.filter((folder) => /^[a-f0-9]{64}$/.test(folder) &&
104
109
  fs.lstatSync(path.join(exports.STORE_PATH, folder)).isDirectory());
@@ -123,7 +128,7 @@ const getActiveStoreId = async () => {
123
128
  return Buffer.from(config.active_store, "hex");
124
129
  }
125
130
  const validFolders = (0, exports.getStoresList)();
126
- if (validFolders.length === 1 || process.env.REMOTE_NODE === "1") {
131
+ if (validFolders.length === 1 || Environment_1.Environment.REMOTE_NODE) {
127
132
  // If only one valid folder exists, set it as the active_store and return it
128
133
  config.active_store = validFolders[0];
129
134
  fs.writeFileSync(configFilePath, JSON.stringify(config, null, 4));
@@ -6,4 +6,20 @@ export declare const addDirectory: (datalayer: DataIntegrityTree, dirPath: strin
6
6
  * @returns The total size of the folder in bytes.
7
7
  */
8
8
  export declare const calculateFolderSize: (folderPath: string) => bigint;
9
+ /**
10
+ * Represents the result of listing files.
11
+ * - If `groupSize` is not provided, returns an array of relative file paths.
12
+ * - If `groupSize` is provided, returns an array of arrays, each containing up to `groupSize` file paths.
13
+ */
14
+ type ListFilesResult = string[] | string[][];
15
+ /**
16
+ * Recursively lists all files in a directory, excluding specified folders and respecting `.gitignore` rules.
17
+ * Optionally groups the list into batches of a specified size.
18
+ *
19
+ * @param {string} baseDir - The base directory path to start listing files from.
20
+ * @param {number} [groupSize] - Optional. The number of files per group. If provided, the result will be an array of arrays.
21
+ * @returns {ListFilesResult} - A flat list of relative file paths or grouped lists based on `groupSize`.
22
+ */
23
+ export declare function listFilesRecursively(baseDir: string, groupSize?: number): ListFilesResult;
24
+ export {};
9
25
  //# sourceMappingURL=directoryUtils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"directoryUtils.d.ts","sourceRoot":"","sources":["../../src/utils/directoryUtils.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AA+BzD,eAAO,MAAM,YAAY,cACZ,iBAAiB,WACnB,MAAM,YACN,MAAM,KACd,OAAO,CAAC,IAAI,CA4Cd,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,eAAgB,MAAM,KAAG,MAiBxD,CAAC"}
1
+ {"version":3,"file":"directoryUtils.d.ts","sourceRoot":"","sources":["../../src/utils/directoryUtils.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AA+BzD,eAAO,MAAM,YAAY,cACZ,iBAAiB,WACnB,MAAM,YACN,MAAM,KACd,OAAO,CAAC,IAAI,CA4Cd,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,eAAgB,MAAM,KAAG,MAiBxD,CAAC;AAEF;;;;GAIG;AACH,KAAK,eAAe,GAAG,MAAM,EAAE,GAAG,MAAM,EAAE,EAAE,CAAC;AAE7C;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,EACf,SAAS,CAAC,EAAE,MAAM,GACjB,eAAe,CAiEjB"}
@@ -27,6 +27,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
29
  exports.calculateFolderSize = exports.addDirectory = void 0;
30
+ exports.listFilesRecursively = listFilesRecursively;
30
31
  const path = __importStar(require("path"));
31
32
  const fs = __importStar(require("fs"));
32
33
  const ignore_1 = __importDefault(require("ignore"));
@@ -108,3 +109,68 @@ const calculateFolderSize = (folderPath) => {
108
109
  return totalSize;
109
110
  };
110
111
  exports.calculateFolderSize = calculateFolderSize;
112
+ /**
113
+ * Recursively lists all files in a directory, excluding specified folders and respecting `.gitignore` rules.
114
+ * Optionally groups the list into batches of a specified size.
115
+ *
116
+ * @param {string} baseDir - The base directory path to start listing files from.
117
+ * @param {number} [groupSize] - Optional. The number of files per group. If provided, the result will be an array of arrays.
118
+ * @returns {ListFilesResult} - A flat list of relative file paths or grouped lists based on `groupSize`.
119
+ */
120
+ function listFilesRecursively(baseDir, groupSize) {
121
+ // Initialize the ignore instance
122
+ const ig = (0, ignore_1.default)();
123
+ // Path to .gitignore
124
+ const gitignorePath = path.join(baseDir, ".gitignore");
125
+ // Load and parse .gitignore if it exists
126
+ if (fs.existsSync(gitignorePath)) {
127
+ const gitignoreContent = fs.readFileSync(gitignorePath, "utf-8");
128
+ ig.add(gitignoreContent);
129
+ }
130
+ // Initialize result containers
131
+ const allFiles = [];
132
+ let groupedFiles = [];
133
+ /**
134
+ * Recursively traverses directories to collect files.
135
+ *
136
+ * @param {string} currentDir - The current directory path being traversed.
137
+ */
138
+ function traverseDirectory(currentDir) {
139
+ let entries;
140
+ try {
141
+ entries = fs.readdirSync(currentDir, { withFileTypes: true });
142
+ }
143
+ catch (err) {
144
+ console.error(`Failed to read directory: ${currentDir}. Error: ${err.message}`);
145
+ return;
146
+ }
147
+ for (const entry of entries) {
148
+ const entryName = entry.name;
149
+ const fullPath = path.join(currentDir, entryName);
150
+ const relativePath = path.relative(baseDir, fullPath).replace(/\\/g, "/"); // Normalize to forward slashes
151
+ // Skip .git and .dig directories and any ignored paths
152
+ if (entryName === ".git" || entryName === ".dig" || ig.ignores(relativePath)) {
153
+ continue;
154
+ }
155
+ if (entry.isDirectory()) {
156
+ traverseDirectory(fullPath); // Recurse into subdirectory
157
+ }
158
+ else if (entry.isFile()) {
159
+ allFiles.push(relativePath);
160
+ }
161
+ // Optionally handle symbolic links or other types if needed
162
+ }
163
+ }
164
+ // Start traversal from the base directory
165
+ traverseDirectory(baseDir);
166
+ // If groupSize is provided and valid, group the files accordingly
167
+ if (groupSize && Number.isInteger(groupSize) && groupSize > 0) {
168
+ groupedFiles = [];
169
+ for (let i = 0; i < allFiles.length; i += groupSize) {
170
+ groupedFiles.push(allFiles.slice(i, i + groupSize));
171
+ }
172
+ return groupedFiles;
173
+ }
174
+ // Return the flat list of files if grouping is not required
175
+ return allFiles;
176
+ }
@@ -1,7 +1,6 @@
1
1
  export * from './config';
2
2
  export * from './connectionUtils';
3
3
  export * from './credentialsUtils';
4
- export * from './deltaUtils';
5
4
  export * from './directoryUtils';
6
5
  export * from './encryption';
7
6
  export * from './FileCache';
@@ -11,4 +10,8 @@ export * from './network';
11
10
  export * from './spinnerUtils';
12
11
  export * from './ssl';
13
12
  export * from './validationUtils';
13
+ export * from './Environment';
14
+ export * from './promiseUtils';
15
+ export * from './PeerRanker';
16
+ export * from './DigCache';
14
17
  //# sourceMappingURL=index.d.ts.map