diff --git a/CHANGELOG.md b/CHANGELOG.md index dd03aa3..7b9d92f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,20 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +### [0.0.1-alpha.68](https://github.com/DIG-Network/dig-chia-sdk/compare/v0.0.1-alpha.67...v0.0.1-alpha.68) (2024-09-23) + + +### Features + +* add download from propagation server methods ([e2e482a](https://github.com/DIG-Network/dig-chia-sdk/commit/e2e482a9b4544d91545e76850fbf36f655f2ef78)) + +### [0.0.1-alpha.67](https://github.com/DIG-Network/dig-chia-sdk/compare/v0.0.1-alpha.66...v0.0.1-alpha.67) (2024-09-23) + + +### Features + +* add download from propagation server methods ([9153256](https://github.com/DIG-Network/dig-chia-sdk/commit/9153256feb368f131e6f05bd965944b80f843b66)) + ### [0.0.1-alpha.66](https://github.com/DIG-Network/dig-chia-sdk/compare/v0.0.1-alpha.65...v0.0.1-alpha.66) (2024-09-23) diff --git a/package-lock.json b/package-lock.json index 516ca16..a55cc8d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@dignetwork/dig-sdk", - "version": "0.0.1-alpha.66", + "version": "0.0.1-alpha.68", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@dignetwork/dig-sdk", - "version": "0.0.1-alpha.66", + "version": "0.0.1-alpha.68", "license": "ISC", "dependencies": { "@dignetwork/datalayer-driver": "^0.1.24", diff --git a/package.json b/package.json index d776240..9e3256d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@dignetwork/dig-sdk", - "version": "0.0.1-alpha.66", + "version": "0.0.1-alpha.68", "description": "", "type": "commonjs", "main": "./dist/index.js", diff --git a/src/DigNetwork/ContentServer.ts b/src/DigNetwork/ContentServer.ts index 166af1c..ef9f132 100644 --- a/src/DigNetwork/ContentServer.ts +++ b/src/DigNetwork/ContentServer.ts @@ -73,16 +73,29 @@ export class ContentServer { } // Method to get the index of keys in a store - public async getKeysIndex(): Promise { - const url = `https://${this.ipAddress}:${ContentServer.port}/${this.storeId}`; + public async getKeysIndex(rootHash?: string): Promise { + let udi = `chia.${this.storeId}`; + + if (rootHash) { + udi += `.${rootHash}`; + } + + const url = `https://${this.ipAddress}:${ContentServer.port}/${udi}`; return this.fetchJson(url); } // Method to check if a specific key exists (HEAD request) public async headKey( - key: string + key: string, + rootHash?: string ): Promise<{ success: boolean; headers?: http.IncomingHttpHeaders }> { - const url = `https://${this.ipAddress}:${ContentServer.port}/${this.storeId}/${key}`; + let udi = `chia.${this.storeId}`; + + if (rootHash) { + udi += `.${rootHash}`; + } + + const url = `https://${this.ipAddress}:${ContentServer.port}/${udi}/${key}`; return this.head(url); } @@ -91,7 +104,7 @@ export class ContentServer { success: boolean; headers?: http.IncomingHttpHeaders; }> { - let url = `https://${this.ipAddress}:${ContentServer.port}/${this.storeId}`; + let url = `https://${this.ipAddress}:${ContentServer.port}/chia.${this.storeId}`; if (options?.hasRootHash) { url += `?hasRootHash=${options.hasRootHash}`; @@ -110,9 +123,15 @@ export class ContentServer { return false; } - public streamKey(key: string): Promise { + public streamKey(key: string, rootHash?: string): Promise { + let udi = `chia.${this.storeId}`; + + if (rootHash) { + udi += `.${rootHash}`; + } + return new Promise((resolve, reject) => { - const url = `https://${this.ipAddress}:${ContentServer.port}/${this.storeId}/${key}`; + const url = `https://${this.ipAddress}:${ContentServer.port}/${udi}/${key}`; const urlObj = new URL(url); const requestOptions = { diff --git a/src/DigNetwork/DigNetwork.ts b/src/DigNetwork/DigNetwork.ts index c306e24..64c3586 100644 --- a/src/DigNetwork/DigNetwork.ts +++ b/src/DigNetwork/DigNetwork.ts @@ -59,12 +59,12 @@ export class DigNetwork { const digPeer = new DigPeer(peerIp, storeId); // Try to fetch the head store information - const storeResponse = await digPeer.contentServer.headStore({ - hasRootHash: rootHash, - }); + const { storeExists, rootHashExists} = await digPeer.propagationServer.checkStoreExists( + rootHash + ); // If the peer has the correct root hash, check if key is required - if (storeResponse.headers?.["x-has-roothash"] === "true") { + if (storeExists && rootHashExists) { console.log( `Found Peer at ${peerIp} for storeId: ${storeId}, root hash ${rootHash}` ); @@ -75,7 +75,7 @@ export class DigNetwork { } // If key is provided, check if the peer has it - const keyResponse = await digPeer.contentServer.headKey(key); + const keyResponse = await digPeer.contentServer.headKey(key, rootHash); if (keyResponse.headers?.["x-key-exists"] === "true") { return digPeer; } diff --git a/src/DigNetwork/PropagationServer.ts b/src/DigNetwork/PropagationServer.ts index 2c1e56a..669b431 100644 --- a/src/DigNetwork/PropagationServer.ts +++ b/src/DigNetwork/PropagationServer.ts @@ -457,6 +457,44 @@ export class PropagationServer { } } + /** + * Get details of a file, including whether it exists and its size. + * Makes a HEAD request to the server and checks the response headers. + * + * @param {string} dataPath - The path of the file within the DataStore. + * @param {string} rootHash - The root hash associated with the DataStore. + * @returns {Promise<{ exists: boolean; size: number }>} - An object containing file existence and size information. + */ + async getFileDetails( + dataPath: string, + rootHash: string + ): Promise<{ exists: boolean; size: number }> { + try { + const config: AxiosRequestConfig = { + httpsAgent: this.createHttpsAgent(), + }; + + // Construct the URL for the HEAD request to check file details + const url = `https://${this.ipAddress}:${PropagationServer.port}/store/${this.storeId}/${rootHash}/${dataPath}`; + const response = await axios.head(url, config); + + // Check the headers for file existence and size + const fileExists = response.headers["x-file-exists"] === "true"; + const fileSize = parseInt(response.headers["x-file-size"], 10); + + return { + exists: fileExists, + size: fileExists ? fileSize : 0, // Return 0 size if file doesn't exist + }; + } catch (error: any) { + console.error( + red(`✖ Error checking file details for ${dataPath}:`), + error.message + ); + throw error; + } + } + /** * Download a file from the server by sending a GET request. * Logs progress using cli-progress. @@ -543,8 +581,8 @@ export class PropagationServer { await propagationServer.initializeWallet(); // Check if the store exists - const storeExists = await propagationServer.checkStoreExists(); - if (!storeExists) { + const { storeExists, rootHashExists} = await propagationServer.checkStoreExists(rootHash); + if (!storeExists || !rootHashExists) { throw new Error(`Store ${storeId} does not exist.`); }