From 90ac77a6e5a62737de1d0f58ef77bece3fe02af9 Mon Sep 17 00:00:00 2001 From: Michael Taylor Date: Thu, 26 Sep 2024 17:29:36 -0400 Subject: [PATCH 1/2] feat: support ip6 on content server, propagation server and incentive server --- src/DigNetwork/ContentServer.ts | 17 +++++++++-------- src/DigNetwork/IncentiveServer.ts | 11 ++++++----- src/DigNetwork/PropagationServer.ts | 17 +++++++++-------- src/utils/network.ts | 13 +++++++++++++ 4 files changed, 37 insertions(+), 21 deletions(-) diff --git a/src/DigNetwork/ContentServer.ts b/src/DigNetwork/ContentServer.ts index 8241c81..83b4e04 100644 --- a/src/DigNetwork/ContentServer.ts +++ b/src/DigNetwork/ContentServer.ts @@ -3,6 +3,7 @@ import http from "http"; import { URL } from "url"; import { Readable } from "stream"; import { getOrCreateSSLCerts } from "../utils/ssl"; +import { formatHost } from "../utils/network"; export class ContentServer { private ipAddress: string; @@ -29,7 +30,7 @@ export class ContentServer { challengeHex?: string ): Promise { // Construct the base URL - let url = `https://${this.ipAddress}:${ContentServer.port}/chia.${this.storeId}.${rootHash}/${key}`; + let url = `https://${formatHost(this.ipAddress)}:${ContentServer.port}/chia.${this.storeId}.${rootHash}/${key}`; // If a challenge is provided, append it as a query parameter if (challengeHex) { @@ -56,19 +57,19 @@ export class ContentServer { // Method to get the .well-known information public async getWellKnown(): Promise { - const url = `https://${this.ipAddress}:${ContentServer.port}/.well-known`; + const url = `https://${formatHost(this.ipAddress)}:${ContentServer.port}/.well-known`; return this.fetchJson(url); } // Method to get the list of known stores public async getKnownStores(): Promise { - const url = `https://${this.ipAddress}:${ContentServer.port}/.well-known/stores`; + const url = `https://${formatHost(this.ipAddress)}:${ContentServer.port}/.well-known/stores`; return this.fetchJson(url); } // Method to get the index of all stores public async getStoresIndex(): Promise { - const url = `https://${this.ipAddress}:${ContentServer.port}/`; + const url = `https://${formatHost(this.ipAddress)}:${ContentServer.port}/`; return this.fetchJson(url); } @@ -80,7 +81,7 @@ export class ContentServer { udi += `.${rootHash}`; } - const url = `https://${this.ipAddress}:${ContentServer.port}/${udi}`; + const url = `https://${formatHost(this.ipAddress)}:${ContentServer.port}/${udi}`; return this.fetchJson(url); } @@ -95,7 +96,7 @@ export class ContentServer { udi += `.${rootHash}`; } - const url = `https://${this.ipAddress}:${ContentServer.port}/${udi}/${key}`; + const url = `https://${formatHost(this.ipAddress)}:${ContentServer.port}/${udi}/${key}`; return this.head(url); } @@ -104,7 +105,7 @@ export class ContentServer { success: boolean; headers?: http.IncomingHttpHeaders; }> { - let url = `https://${this.ipAddress}:${ContentServer.port}/chia.${this.storeId}`; + let url = `https://${formatHost(this.ipAddress)}:${ContentServer.port}/chia.${this.storeId}`; if (options?.hasRootHash) { url += `?hasRootHash=${options.hasRootHash}`; @@ -131,7 +132,7 @@ export class ContentServer { } return new Promise((resolve, reject) => { - const url = `https://${this.ipAddress}:${ContentServer.port}/${udi}/${key}`; + const url = `https://${formatHost(this.ipAddress)}:${ContentServer.port}/${udi}/${key}`; const urlObj = new URL(url); const requestOptions = { diff --git a/src/DigNetwork/IncentiveServer.ts b/src/DigNetwork/IncentiveServer.ts index 8d96de9..e0e7af1 100644 --- a/src/DigNetwork/IncentiveServer.ts +++ b/src/DigNetwork/IncentiveServer.ts @@ -1,6 +1,7 @@ import https from "https"; import { URL } from "url"; import { IncentiveProgramData } from "../types"; +import { formatHost } from "../utils/network"; export class IncentiveServer { private ipAddress: string; @@ -12,35 +13,35 @@ export class IncentiveServer { // Method to create a new incentive program public async createIncentiveProgram(data: IncentiveProgramData): Promise { - const url = `https://${this.ipAddress}:${this.port}/incentive`; + const url = `https://${formatHost(this.ipAddress)}:${this.port}/incentive`; await this.makeRequest(url, "POST", data); } // Method to update an existing incentive program public async updateIncentiveProgram(data: IncentiveProgramData): Promise { - const url = `https://${this.ipAddress}:${this.port}/incentive`; + const url = `https://${formatHost(this.ipAddress)}:${this.port}/incentive`; await this.makeRequest(url, "PUT", data); } // Method to delete an incentive program by storeId public async deleteIncentiveProgram(storeId: string): Promise { - const url = `https://${this.ipAddress}:${this.port}/incentive`; + const url = `https://${formatHost(this.ipAddress)}:${this.port}/incentive`; await this.makeRequest(url, "DELETE", { storeId }); } // Method to get all incentive programs public async getAllIncentivePrograms(): Promise { - const url = `https://${this.ipAddress}:${this.port}/incentive`; + const url = `https://${formatHost(this.ipAddress)}:${this.port}/incentive`; return this.makeRequest(url, "GET"); } // Method to get a specific incentive program by storeId public async getIncentiveProgram(storeId: string): Promise { - const url = `https://${this.ipAddress}:${this.port}/incentive/${storeId}`; + const url = `https://${formatHost(this.ipAddress)}:${this.port}/incentive/${storeId}`; return this.makeRequest(url, "GET"); } diff --git a/src/DigNetwork/PropagationServer.ts b/src/DigNetwork/PropagationServer.ts index 891aa62..014ffbe 100644 --- a/src/DigNetwork/PropagationServer.ts +++ b/src/DigNetwork/PropagationServer.ts @@ -18,6 +18,7 @@ import { PassThrough } from "stream"; import { promptCredentials } from "../utils/credentialsUtils"; import { STORE_PATH } from "../utils/config"; import { Wallet, DataStore } from "../blockchain"; +import { formatHost } from '../utils/network'; // Helper function to trim long filenames with ellipsis and ensure consistent padding function formatFilename(filename: string | undefined, maxLength = 30): string { @@ -120,7 +121,7 @@ export class PropagationServer { httpsAgent: this.createHttpsAgent(), }; - let url = `https://${this.ipAddress}:${PropagationServer.port}/${this.storeId}`; + let url = `https://${formatHost(this.ipAddress)}:${PropagationServer.port}/${this.storeId}`; if (rootHash) { url += `?hasRootHash=${rootHash}`; } @@ -193,7 +194,7 @@ export class PropagationServer { }; } - const url = `https://${this.ipAddress}:${PropagationServer.port}/upload/${this.storeId}?roothash=${rootHash}`; + const url = `https://${formatHost(this.ipAddress)}:${PropagationServer.port}/upload/${this.storeId}?roothash=${rootHash}`; const response = await axios.post(url, formData, config); this.sessionId = response.data.sessionId; @@ -222,7 +223,7 @@ export class PropagationServer { httpsAgent: this.createHttpsAgent(), }; - const url = `https://${this.ipAddress}:${PropagationServer.port}/upload/${this.storeId}/${this.sessionId}/${filename}`; + const url = `https://${formatHost(this.ipAddress)}:${PropagationServer.port}/upload/${this.storeId}/${this.sessionId}/${filename}`; const response = await axios.head(url, config); // Check for 'x-file-exists' header @@ -326,7 +327,7 @@ export class PropagationServer { maxBodyLength: Infinity, }; - const url = `https://${this.ipAddress}:${PropagationServer.port}/upload/${this.storeId}/${this.sessionId}/${dataPath}`; + const url = `https://${formatHost(this.ipAddress)}:${PropagationServer.port}/upload/${this.storeId}/${this.sessionId}/${dataPath}`; // Create a promise that resolves when the progress stream ends const progressPromise = new Promise((resolve, reject) => { @@ -368,7 +369,7 @@ export class PropagationServer { : undefined, }; - const url = `https://${this.ipAddress}:${PropagationServer.port}/commit/${this.storeId}/${this.sessionId}`; + const url = `https://${formatHost(this.ipAddress)}:${PropagationServer.port}/commit/${this.storeId}/${this.sessionId}`; const response = await axios.post(url, {}, config); spinner.success({ @@ -453,7 +454,7 @@ export class PropagationServer { * Logs progress using a local cli-progress bar. */ async fetchFile(dataPath: string): Promise { - const url = `https://${this.ipAddress}:${PropagationServer.port}/fetch/${this.storeId}/${dataPath}`; + const url = `https://${formatHost(this.ipAddress)}:${PropagationServer.port}/fetch/${this.storeId}/${dataPath}`; const config: AxiosRequestConfig = { responseType: "stream", httpsAgent: this.createHttpsAgent(), @@ -544,7 +545,7 @@ export class PropagationServer { httpsAgent: this.createHttpsAgent(), }; - const url = `https://${this.ipAddress}:${PropagationServer.port}/store/${this.storeId}/${rootHash}/${dataPath}`; + const url = `https://${formatHost(this.ipAddress)}:${PropagationServer.port}/store/${this.storeId}/${rootHash}/${dataPath}`; const response = await axios.head(url, config); // Check the headers for file existence and size @@ -574,7 +575,7 @@ export class PropagationServer { rootHash: string, baseDir: string ) { - const url = `https://${this.ipAddress}:${PropagationServer.port}/fetch/${this.storeId}/${dataPath}`; + const url = `https://${formatHost(this.ipAddress)}:${PropagationServer.port}/fetch/${this.storeId}/${dataPath}`; let downloadPath = path.join(baseDir, dataPath); // Ensure that the directory for the file exists diff --git a/src/utils/network.ts b/src/utils/network.ts index 3caa444..047c121 100644 --- a/src/utils/network.ts +++ b/src/utils/network.ts @@ -64,3 +64,16 @@ export const getPublicIpAddress = async (): Promise => { } } }; + +// Helper function to wrap IPv6 addresses in brackets +export const formatHost = (host: string): string => { + const ipv6Pattern = /^[a-fA-F0-9:]+$/; // Simple regex to match raw IPv6 addresses (without brackets) + const hasBrackets = /^\[.*\]$/; // Regex to check if the address already has brackets + + // If it's an IPv6 address without brackets, add them + if (ipv6Pattern.test(host) && !hasBrackets.test(host)) { + return `[${host}]`; + } + + return host; // Return the host as is (IPv4, hostname, or already bracketed IPv6) +}; From 72237aebf58b7a12424fe2d565cbe065ba5fe350 Mon Sep 17 00:00:00 2001 From: Michael Taylor Date: Thu, 26 Sep 2024 17:30:10 -0400 Subject: [PATCH 2/2] chore(release): 0.0.1-alpha.102 --- CHANGELOG.md | 7 +++++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2355f4e..b07a54d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ 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.102](https://github.com/DIG-Network/dig-chia-sdk/compare/v0.0.1-alpha.101...v0.0.1-alpha.102) (2024-09-26) + + +### Features + +* support ip6 on content server, propagation server and incentive server ([90ac77a](https://github.com/DIG-Network/dig-chia-sdk/commit/90ac77a6e5a62737de1d0f58ef77bece3fe02af9)) + ### [0.0.1-alpha.101](https://github.com/DIG-Network/dig-chia-sdk/compare/v0.0.1-alpha.100...v0.0.1-alpha.101) (2024-09-26) diff --git a/package-lock.json b/package-lock.json index 8ebaabd..c3721a4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@dignetwork/dig-sdk", - "version": "0.0.1-alpha.101", + "version": "0.0.1-alpha.102", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@dignetwork/dig-sdk", - "version": "0.0.1-alpha.101", + "version": "0.0.1-alpha.102", "license": "ISC", "dependencies": { "@dignetwork/datalayer-driver": "^0.1.25", diff --git a/package.json b/package.json index 36efbd5..50e566a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@dignetwork/dig-sdk", - "version": "0.0.1-alpha.101", + "version": "0.0.1-alpha.102", "description": "", "type": "commonjs", "main": "./dist/index.js",