@dignetwork/dig-sdk 0.0.1-alpha.15 → 0.0.1-alpha.150

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/dist/DataIntegrityTree/DataIntegrityTree.d.ts +11 -2
  2. package/dist/DataIntegrityTree/DataIntegrityTree.d.ts.map +1 -1
  3. package/dist/DataIntegrityTree/DataIntegrityTree.js +117 -58
  4. package/dist/DigNetwork/ContentServer.d.ts +12 -5
  5. package/dist/DigNetwork/ContentServer.d.ts.map +1 -1
  6. package/dist/DigNetwork/ContentServer.js +172 -24
  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 +146 -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 +68 -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 +83 -33
  16. package/dist/DigNetwork/PropagationServer.d.ts.map +1 -1
  17. package/dist/DigNetwork/PropagationServer.js +605 -356
  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 +94 -10
  24. package/dist/blockchain/FullNodePeer.d.ts.map +1 -1
  25. package/dist/blockchain/FullNodePeer.js +325 -100
  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 +90 -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 +241 -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/Environment.d.ts +21 -0
  47. package/dist/utils/Environment.d.ts.map +1 -0
  48. package/dist/utils/Environment.js +92 -0
  49. package/dist/utils/FileCache.d.ts +1 -1
  50. package/dist/utils/FileCache.d.ts.map +1 -1
  51. package/dist/utils/FileCache.js +2 -2
  52. package/dist/utils/FileTransfer.d.ts +47 -0
  53. package/dist/utils/FileTransfer.d.ts.map +1 -0
  54. package/dist/utils/FileTransfer.js +209 -0
  55. package/dist/utils/NconfManager.js +2 -1
  56. package/dist/utils/PeerRanker.d.ts +53 -0
  57. package/dist/utils/PeerRanker.d.ts.map +1 -0
  58. package/dist/utils/PeerRanker.js +171 -0
  59. package/dist/utils/StoreArchiveManager.d.ts +45 -0
  60. package/dist/utils/StoreArchiveManager.d.ts.map +1 -0
  61. package/dist/utils/StoreArchiveManager.js +153 -0
  62. package/dist/utils/config.d.ts +4 -3
  63. package/dist/utils/config.d.ts.map +1 -1
  64. package/dist/utils/config.js +12 -7
  65. package/dist/utils/directoryUtils.d.ts.map +1 -1
  66. package/dist/utils/directoryUtils.js +9 -12
  67. package/dist/utils/index.d.ts +3 -1
  68. package/dist/utils/index.d.ts.map +1 -1
  69. package/dist/utils/index.js +3 -1
  70. package/dist/utils/merkle.d.ts +2 -0
  71. package/dist/utils/merkle.d.ts.map +1 -0
  72. package/dist/utils/merkle.js +28 -0
  73. package/dist/utils/network.d.ts +1 -0
  74. package/dist/utils/network.d.ts.map +1 -1
  75. package/dist/utils/network.js +38 -11
  76. package/dist/utils/promiseUtils.d.ts +19 -0
  77. package/dist/utils/promiseUtils.d.ts.map +1 -0
  78. package/dist/utils/promiseUtils.js +43 -0
  79. package/dist/utils/ssl.js +2 -2
  80. package/package.json +17 -5
  81. package/dist/utils/deltaUtils.d.ts +0 -2
  82. package/dist/utils/deltaUtils.d.ts.map +0 -1
  83. package/dist/utils/deltaUtils.js +0 -83
@@ -17,6 +17,7 @@ declare class DataIntegrityTree {
17
17
  files: Map<string, {
18
18
  hash: string;
19
19
  sha256: string;
20
+ bytes: string;
20
21
  }>;
21
22
  private tree;
22
23
  constructor(storeId: string, options?: DataIntegrityTreeOptions);
@@ -78,6 +79,9 @@ declare class DataIntegrityTree {
78
79
  * @returns The serialized Merkle tree.
79
80
  */
80
81
  serialize(rootHash?: string | null): object;
82
+ static getRootOfForeignTree(treeData: {
83
+ leaves: string[];
84
+ }): string;
81
85
  /**
82
86
  * Deserialize a JSON object to a Merkle tree.
83
87
  * @param rootHash - The root hash of the tree.
@@ -106,7 +110,7 @@ declare class DataIntegrityTree {
106
110
  * @param rootHash - The root hash of the tree. Defaults to the latest root hash.
107
111
  * @returns The readable stream for the file.
108
112
  */
109
- getValueStream(hexKey: string, rootHash?: string | null): Readable;
113
+ getValueStream(hexKey: string, rootHash?: string | null, byteOffset?: number | null, length?: number | null): Readable;
110
114
  /**
111
115
  * Delete all leaves from the Merkle tree.
112
116
  */
@@ -152,9 +156,14 @@ declare class DataIntegrityTree {
152
156
  * @param sha256 - The SHA-256 hash of the file.
153
157
  * @param serializedTree - The foreign serialized Merkle tree.
154
158
  * @param expectedRootHash - The expected root hash of the Merkle tree.
159
+ * @param dataDir - The directory where the data is stored.
160
+ * @param verifiedSha256 - A boolean indicating if the SHA-256 hash has already been verified.
155
161
  * @returns A boolean indicating if the SHA-256 is present in the foreign tree and the root hash matches.
156
162
  */
157
- static validateKeyIntegrityWithForeignTree(key: string, sha256: string, serializedTree: object, expectedRootHash: string): boolean;
163
+ static validateKeyIntegrityWithForeignTree(hexkey: string, sha256: string, serializedTree: object, expectedRootHash: string, dataDir: string, verifiedSha256?: boolean): Promise<boolean>;
164
+ private static verifyFileHash;
165
+ private static deserializeAndVerifyTree;
166
+ private static checkHashInTree;
158
167
  }
159
168
  export { DataIntegrityTree };
160
169
  //# sourceMappingURL=DataIntegrityTree.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"DataIntegrityTree.d.ts","sourceRoot":"","sources":["../../src/DataIntegrityTree/DataIntegrityTree.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"DataIntegrityTree.d.ts","sourceRoot":"","sources":["../../src/DataIntegrityTree/DataIntegrityTree.ts"],"names":[],"mappings":"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"}
@@ -94,8 +94,7 @@ class DataIntegrityTree {
94
94
  }
95
95
  this.files = new Map();
96
96
  if (options.rootHash) {
97
- const manifest = this._loadManifest();
98
- if (manifest.includes(options.rootHash)) {
97
+ if (fs.existsSync(path.join(this.storeDir, `${options.rootHash}.dat`))) {
99
98
  this.tree = this.deserializeTree(options.rootHash);
100
99
  }
101
100
  else {
@@ -111,7 +110,10 @@ class DataIntegrityTree {
111
110
  }
112
111
  }
113
112
  static from(storeId, options) {
114
- return new DataIntegrityTree(storeId, { ...options, disableInitialize: true });
113
+ return new DataIntegrityTree(storeId, {
114
+ ...options,
115
+ disableInitialize: true,
116
+ });
115
117
  }
116
118
  /**
117
119
  * Load the manifest file.
@@ -132,7 +134,10 @@ class DataIntegrityTree {
132
134
  const manifest = this._loadManifest();
133
135
  if (manifest.length > 0) {
134
136
  const latestRootHash = manifest[manifest.length - 1];
135
- return this.deserializeTree(latestRootHash);
137
+ if (latestRootHash && isHexString(latestRootHash)) {
138
+ return this.deserializeTree(latestRootHash);
139
+ }
140
+ return new merkletreejs_1.MerkleTree([], crypto_js_1.SHA256, { sortPairs: true });
136
141
  }
137
142
  else {
138
143
  return new merkletreejs_1.MerkleTree([], crypto_js_1.SHA256, { sortPairs: true });
@@ -186,83 +191,62 @@ class DataIntegrityTree {
186
191
  fs.mkdirSync(tempDir, { recursive: true });
187
192
  }
188
193
  const tempFilePath = path.join(tempDir, `${crypto.randomUUID()}.gz`);
194
+ let totalBytes = 0;
189
195
  return new Promise((resolve, reject) => {
190
196
  const tempWriteStream = fs.createWriteStream(tempFilePath);
191
- // Update the hash with the original data
192
197
  readStream.on("data", (chunk) => {
193
198
  uncompressedHash.update(chunk);
194
199
  });
195
- // Pipe the read stream through gzip into the temporary write stream
200
+ // Now listen to the gzip stream for compressed data size
201
+ gzip.on("data", (chunk) => {
202
+ totalBytes += chunk.length; // This counts compressed bytes
203
+ });
196
204
  readStream.pipe(gzip).pipe(tempWriteStream);
197
205
  tempWriteStream.on("finish", async () => {
198
- let finalWriteStream;
206
+ sha256 = uncompressedHash.digest("hex");
207
+ const finalWriteStream = this._createWriteStream(sha256);
208
+ const finalPath = finalWriteStream.path;
209
+ // Ensure the directory exists before copying the file
210
+ const finalDir = path.dirname(finalPath);
211
+ if (!fs.existsSync(finalDir)) {
212
+ fs.mkdirSync(finalDir, { recursive: true });
213
+ }
199
214
  try {
200
- sha256 = uncompressedHash.digest("hex");
201
- finalWriteStream = this._createWriteStream(sha256);
202
- const finalPath = finalWriteStream.path;
203
- // Ensure the directory exists
204
- const finalDir = path.dirname(finalPath);
205
- if (!fs.existsSync(finalDir)) {
206
- fs.mkdirSync(finalDir, { recursive: true });
207
- }
208
- // Copy the temporary gzipped file to the final destination
209
215
  await this._streamFile(tempFilePath, finalPath);
210
- await unlink(tempFilePath); // Clean up the temporary file
216
+ await unlink(tempFilePath);
211
217
  const combinedHash = crypto
212
218
  .createHash("sha256")
213
219
  .update(`${key}/${sha256}`)
214
220
  .digest("hex");
215
- // Check if the key already exists with the same hash
216
221
  if (Array.from(this.files.values()).some((file) => file.hash === combinedHash)) {
217
222
  console.log(`No changes detected for key: ${key}`);
218
223
  return resolve();
219
224
  }
220
- // Delete existing key if present
221
225
  if (this.files.has(key)) {
222
226
  this.deleteKey(key);
223
227
  }
224
- // Insert the new key with the hash
225
228
  console.log(`Inserted key: ${key}`);
226
229
  this.files.set(key, {
227
230
  hash: combinedHash,
228
231
  sha256: sha256,
232
+ bytes: totalBytes.toString(),
229
233
  });
234
+ await new Promise((resolve) => setTimeout(resolve, 100));
230
235
  this._rebuildTree();
236
+ await new Promise((resolve) => setTimeout(resolve, 100));
231
237
  resolve();
232
238
  }
233
239
  catch (err) {
234
- // On error, cleanup the temporary file and reject
235
- await unlink(tempFilePath).catch(() => { });
236
240
  reject(err);
237
241
  }
238
- finally {
239
- // Always close the final write stream if it exists
240
- if (finalWriteStream) {
241
- finalWriteStream.end();
242
- }
243
- }
244
- });
245
- tempWriteStream.on("error", async (err) => {
246
- // Close streams and clean up in case of error
247
- tempWriteStream.destroy();
248
- gzip.destroy();
249
- readStream.destroy();
250
- await unlink(tempFilePath).catch(() => { }); // Clean up the temp file
251
- reject(err);
242
+ tempWriteStream.end();
243
+ finalWriteStream.end();
252
244
  });
253
- readStream.on("error", async (err) => {
254
- // Close streams and clean up in case of error
255
- tempWriteStream.destroy();
256
- gzip.destroy();
257
- readStream.destroy();
258
- await unlink(tempFilePath).catch(() => { }); // Clean up the temp file
245
+ tempWriteStream.on("error", (err) => {
246
+ tempWriteStream.end();
259
247
  reject(err);
260
248
  });
261
- gzip.on("error", (err) => {
262
- // Handle errors in the gzip stream
263
- tempWriteStream.destroy();
264
- gzip.destroy();
265
- readStream.destroy();
249
+ readStream.on("error", (err) => {
266
250
  reject(err);
267
251
  });
268
252
  });
@@ -337,6 +321,11 @@ class DataIntegrityTree {
337
321
  files: Object.fromEntries(this.files),
338
322
  };
339
323
  }
324
+ static getRootOfForeignTree(treeData) {
325
+ const leaves = treeData.leaves.map((leaf) => Buffer.from(leaf, "hex"));
326
+ const tree = new merkletreejs_1.MerkleTree(leaves, crypto_js_1.SHA256, { sortPairs: true });
327
+ return tree.getRoot().toString("hex");
328
+ }
340
329
  /**
341
330
  * Deserialize a JSON object to a Merkle tree.
342
331
  * @param rootHash - The root hash of the tree.
@@ -369,7 +358,9 @@ class DataIntegrityTree {
369
358
  ? fs.readFileSync(manifestPath, "utf-8").trim().split("\n")
370
359
  : [];
371
360
  // Check if the last entry is the same as the rootHash to avoid duplicates
372
- const latestRootHash = manifestContent.length > 0 ? manifestContent[manifestContent.length - 1] : null;
361
+ const latestRootHash = manifestContent.length > 0
362
+ ? manifestContent[manifestContent.length - 1]
363
+ : null;
373
364
  if (latestRootHash !== rootHash) {
374
365
  // Append the new rootHash if it is not the same as the last one
375
366
  fs.appendFileSync(manifestPath, `${rootHash}\n`);
@@ -445,7 +436,7 @@ class DataIntegrityTree {
445
436
  * @param rootHash - The root hash of the tree. Defaults to the latest root hash.
446
437
  * @returns The readable stream for the file.
447
438
  */
448
- getValueStream(hexKey, rootHash = null) {
439
+ getValueStream(hexKey, rootHash = null, byteOffset = null, length = null) {
449
440
  if (!isHexString(hexKey)) {
450
441
  throw new Error("key must be a valid hex string");
451
442
  }
@@ -468,8 +459,22 @@ class DataIntegrityTree {
468
459
  if (!fs.existsSync(filePath)) {
469
460
  throw new Error(`File at path ${filePath} does not exist`);
470
461
  }
471
- // Create a read stream and pipe it through a decompression stream using the same algorithm (gzip)
472
- const readStream = fs.createReadStream(filePath);
462
+ const fileSize = fs.statSync(filePath).size;
463
+ // Validate offset and length
464
+ if (byteOffset !== null && length !== null) {
465
+ if (byteOffset + length > fileSize) {
466
+ throw new Error(`Offset (${byteOffset}) and length (${length}) exceed the file size (${fileSize}).`);
467
+ }
468
+ }
469
+ // Create the read stream with optional byte range
470
+ const options = {};
471
+ if (byteOffset !== null) {
472
+ options.start = byteOffset;
473
+ }
474
+ if (length !== null && byteOffset !== null) {
475
+ options.end = byteOffset + length - 1; // `end` is inclusive, hence `byteOffset + length - 1`
476
+ }
477
+ const readStream = fs.createReadStream(filePath, options);
473
478
  const decompressStream = zlib.createGunzip();
474
479
  // Return the combined stream as a generic Readable stream
475
480
  return readStream.pipe(decompressStream);
@@ -611,14 +616,13 @@ class DataIntegrityTree {
611
616
  decompressStream.on("end", () => {
612
617
  const uncompressedSha256 = hash.digest("hex");
613
618
  const isValid = uncompressedSha256 === sha256;
614
- console.log(`SHA-256 of uncompressed file: ${uncompressedSha256}`);
615
619
  if (!isValid) {
616
620
  return resolve(false);
617
621
  }
618
622
  const tree = this.deserializeTree(rootHash);
619
623
  const combinedHash = crypto
620
624
  .createHash("sha256")
621
- .update(`${toHex(sha256)}/${sha256}`)
625
+ .update(sha256)
622
626
  .digest("hex");
623
627
  const leaf = Buffer.from(combinedHash, "hex");
624
628
  const isInTree = tree.getLeafIndex(leaf) !== -1;
@@ -640,10 +644,12 @@ class DataIntegrityTree {
640
644
  * @param sha256 - The SHA-256 hash of the file.
641
645
  * @param serializedTree - The foreign serialized Merkle tree.
642
646
  * @param expectedRootHash - The expected root hash of the Merkle tree.
647
+ * @param dataDir - The directory where the data is stored.
648
+ * @param verifiedSha256 - A boolean indicating if the SHA-256 hash has already been verified.
643
649
  * @returns A boolean indicating if the SHA-256 is present in the foreign tree and the root hash matches.
644
650
  */
645
- static validateKeyIntegrityWithForeignTree(key, sha256, serializedTree, expectedRootHash) {
646
- if (!isHexString(key)) {
651
+ static async validateKeyIntegrityWithForeignTree(hexkey, sha256, serializedTree, expectedRootHash, dataDir, verifiedSha256 = false) {
652
+ if (!isHexString(hexkey)) {
647
653
  throw new Error("key must be a valid hex string");
648
654
  }
649
655
  if (!isHexString(sha256)) {
@@ -652,6 +658,56 @@ class DataIntegrityTree {
652
658
  if (!isHexString(expectedRootHash)) {
653
659
  throw new Error("expectedRootHash must be a valid hex string");
654
660
  }
661
+ if (!verifiedSha256) {
662
+ // Verify the file's SHA-256 hash
663
+ const isFileValid = await this.verifyFileHash(sha256, dataDir);
664
+ if (!isFileValid) {
665
+ return false;
666
+ }
667
+ }
668
+ // Deserialize and verify the tree
669
+ const tree = this.deserializeAndVerifyTree(serializedTree, expectedRootHash);
670
+ if (!tree) {
671
+ return false;
672
+ }
673
+ // Check if the combined hash exists in the foreign tree's leaves
674
+ const isInTree = this.checkHashInTree(tree, hexkey, sha256);
675
+ return isInTree;
676
+ }
677
+ // Function to verify the file's SHA-256 hash
678
+ static async verifyFileHash(sha256, dataDir) {
679
+ const filePath = path.join(dataDir, sha256.match(/.{1,2}/g).join("/"));
680
+ // Check if the file exists
681
+ if (!fs.existsSync(filePath)) {
682
+ throw new Error(`File at path ${filePath} does not exist`);
683
+ }
684
+ const compressedReadStream = fs.createReadStream(filePath);
685
+ const decompressStream = zlib.createGunzip();
686
+ const hash = crypto.createHash("sha256");
687
+ // Process file decompression and hash comparison
688
+ return new Promise((resolve, reject) => {
689
+ compressedReadStream.pipe(decompressStream);
690
+ decompressStream.on("data", (chunk) => {
691
+ hash.update(chunk);
692
+ });
693
+ decompressStream.on("end", () => {
694
+ const uncompressedSha256 = hash.digest("hex");
695
+ if (uncompressedSha256 !== sha256) {
696
+ console.warn(`File hash mismatch. Expected: ${sha256}, got: ${uncompressedSha256}`);
697
+ return resolve(false);
698
+ }
699
+ resolve(true);
700
+ });
701
+ decompressStream.on("error", (err) => {
702
+ reject(err);
703
+ });
704
+ compressedReadStream.on("error", (err) => {
705
+ reject(err);
706
+ });
707
+ });
708
+ }
709
+ // Function to deserialize and verify the tree
710
+ static deserializeAndVerifyTree(serializedTree, expectedRootHash) {
655
711
  // Deserialize the foreign tree
656
712
  const leaves = serializedTree.leaves.map((leaf) => Buffer.from(leaf, "hex"));
657
713
  const tree = new merkletreejs_1.MerkleTree(leaves, crypto_js_1.SHA256, { sortPairs: true });
@@ -659,7 +715,7 @@ class DataIntegrityTree {
659
715
  const treeRootHash = tree.getRoot().toString("hex");
660
716
  if (treeRootHash !== expectedRootHash) {
661
717
  console.warn(`Expected root hash ${expectedRootHash}, but got ${treeRootHash}`);
662
- return false;
718
+ return null;
663
719
  }
664
720
  // Rebuild the files map from the serialized tree
665
721
  // @ts-ignore
@@ -667,10 +723,13 @@ class DataIntegrityTree {
667
723
  key,
668
724
  { hash: value.hash, sha256: value.sha256 },
669
725
  ]));
670
- // Check if the SHA-256 exists in the foreign tree's files
726
+ return tree;
727
+ }
728
+ // Function to check if the combined hash exists in the tree
729
+ static checkHashInTree(tree, hexkey, sha256) {
671
730
  const combinedHash = crypto
672
731
  .createHash("sha256")
673
- .update(`${toHex(key)}/${sha256}`)
732
+ .update(`${hexkey}/${sha256}`)
674
733
  .digest("hex");
675
734
  const leaf = Buffer.from(combinedHash, "hex");
676
735
  const isInTree = tree.getLeafIndex(leaf) !== -1;
@@ -3,26 +3,33 @@ import { Readable } from "stream";
3
3
  export declare class ContentServer {
4
4
  private ipAddress;
5
5
  private storeId;
6
+ private static certPath;
7
+ private static keyPath;
6
8
  private static readonly port;
7
9
  constructor(ipAddress: string, storeId: string);
8
10
  getKey(key: string, rootHash: string, challengeHex?: string): Promise<string>;
9
- getPaymentAddress(): Promise<string>;
11
+ getKeyChunk(key: string, rootHash: string): Promise<Buffer>;
12
+ getPaymentAddress(): Promise<string | null>;
10
13
  getWellKnown(): Promise<any>;
11
14
  getKnownStores(): Promise<any>;
12
15
  getStoresIndex(): Promise<any>;
13
- getKeysIndex(): Promise<any>;
14
- headKey(key: string): Promise<{
16
+ getKeysIndex(rootHash?: string): Promise<any>;
17
+ headKey(key: string, rootHash?: string): Promise<{
15
18
  success: boolean;
16
19
  headers?: http.IncomingHttpHeaders;
17
20
  }>;
18
- headStore(): Promise<{
21
+ headStore(options?: {
22
+ hasRootHash: string;
23
+ }): Promise<{
19
24
  success: boolean;
20
25
  headers?: http.IncomingHttpHeaders;
21
26
  }>;
22
- streamKey(key: string): Promise<Readable>;
27
+ hasRootHash(rootHash: string): Promise<boolean>;
28
+ streamKey(key: string, rootHash?: string): Promise<Readable>;
23
29
  private head;
24
30
  private fetchJson;
25
31
  private fetchWithRetries;
26
32
  private fetch;
33
+ private fetchFirstChunk;
27
34
  }
28
35
  //# sourceMappingURL=ContentServer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ContentServer.d.ts","sourceRoot":"","sources":["../../src/DigNetwork/ContentServer.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAGlC,qBAAa,aAAa;IACxB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAM;gBAEtB,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;IAMjC,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAa7E,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC;IAepC,YAAY,IAAI,OAAO,CAAC,GAAG,CAAC;IAM5B,cAAc,IAAI,OAAO,CAAC,GAAG,CAAC;IAM9B,cAAc,IAAI,OAAO,CAAC,GAAG,CAAC;IAM9B,YAAY,IAAI,OAAO,CAAC,GAAG,CAAC;IAM5B,OAAO,CAClB,GAAG,EAAE,MAAM,GACV,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,IAAI,CAAC,mBAAmB,CAAA;KAAE,CAAC;IAMvD,SAAS,IAAI,OAAO,CAAC;QAChC,OAAO,EAAE,OAAO,CAAC;QACjB,OAAO,CAAC,EAAE,IAAI,CAAC,mBAAmB,CAAC;KACpC,CAAC;IAMK,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;YA0ClC,IAAI;YAuEJ,SAAS;YAMT,gBAAgB;YAiChB,KAAK;CAuDpB"}
1
+ {"version":3,"file":"ContentServer.d.ts","sourceRoot":"","sources":["../../src/DigNetwork/ContentServer.ts"],"names":[],"mappings":"AACA,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAIlC,qBAAa,aAAa;IACxB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAS;IAChC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAS;IAC/B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAQ;gBAExB,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;IAYjC,MAAM,CACjB,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAChB,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,MAAM,CAAC;IAaJ,WAAW,CACvB,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC;IAOL,iBAAiB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAe3C,YAAY,IAAI,OAAO,CAAC,GAAG,CAAC;IAM5B,cAAc,IAAI,OAAO,CAAC,GAAG,CAAC;IAM9B,cAAc,IAAI,OAAO,CAAC,GAAG,CAAC;IAM9B,YAAY,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IAY7C,OAAO,CAClB,GAAG,EAAE,MAAM,EACX,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,IAAI,CAAC,mBAAmB,CAAA;KAAE,CAAC;IAYvD,SAAS,CAAC,OAAO,CAAC,EAAE;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QACjE,OAAO,EAAE,OAAO,CAAC;QACjB,OAAO,CAAC,EAAE,IAAI,CAAC,mBAAmB,CAAC;KACpC,CAAC;IAUW,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAUrD,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;YAgDrD,IAAI;YA0EJ,SAAS;YAMT,gBAAgB;YAiChB,KAAK;YA+GL,eAAe;CA2G9B"}