@dignetwork/dig-sdk 0.0.1-alpha.97 → 0.0.1-alpha.99

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.
@@ -1,11 +1,10 @@
1
- import http from "http";
2
- import { Readable } from "stream";
3
1
  export declare class ContentServer {
4
2
  private ipAddress;
5
3
  private storeId;
6
4
  private static certPath;
7
5
  private static keyPath;
8
6
  private static readonly port;
7
+ private static readonly inactivityTimeout;
9
8
  constructor(ipAddress: string, storeId: string);
10
9
  getKey(key: string, rootHash: string, challengeHex?: string): Promise<string>;
11
10
  getPaymentAddress(): Promise<string | null>;
@@ -15,19 +14,18 @@ export declare class ContentServer {
15
14
  getKeysIndex(rootHash?: string): Promise<any>;
16
15
  headKey(key: string, rootHash?: string): Promise<{
17
16
  success: boolean;
18
- headers?: http.IncomingHttpHeaders;
17
+ headers?: any;
19
18
  }>;
20
19
  headStore(options?: {
21
20
  hasRootHash: string;
22
21
  }): Promise<{
23
22
  success: boolean;
24
- headers?: http.IncomingHttpHeaders;
23
+ headers?: any;
25
24
  }>;
26
25
  hasRootHash(rootHash: string): Promise<boolean>;
27
- streamKey(key: string, rootHash?: string): Promise<Readable>;
28
26
  private head;
29
27
  private fetchJson;
30
- private fetchWithRetries;
31
28
  private fetch;
29
+ private getAxiosConfig;
32
30
  }
33
31
  //# sourceMappingURL=ContentServer.d.ts.map
@@ -1 +1 @@
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;AAGlC,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;IAaL,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;CA6GpB"}
1
+ {"version":3,"file":"ContentServer.d.ts","sourceRoot":"","sources":["../../src/DigNetwork/ContentServer.ts"],"names":[],"mappings":"AAMA,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;IACpC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAQ;gBAErC,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;IAWL,iBAAiB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAc3C,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;IAU7C,OAAO,CAClB,GAAG,EAAE,MAAM,EACX,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IAUlC,SAAS,CAAC,OAAO,CAAC,EAAE;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QACjE,OAAO,EAAE,OAAO,CAAC;QACjB,OAAO,CAAC,EAAE,GAAG,CAAC;KACf,CAAC;IAQW,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;YAW9C,IAAI;YAcJ,SAAS;YAMT,KAAK;IA+DnB,OAAO,CAAC,cAAc;CAUvB"}
@@ -4,9 +4,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.ContentServer = void 0;
7
+ const axios_1 = __importDefault(require("axios"));
7
8
  const fs_1 = __importDefault(require("fs"));
8
- const http_1 = __importDefault(require("http"));
9
- const url_1 = require("url");
9
+ const https_1 = __importDefault(require("https"));
10
10
  const ssl_1 = require("../utils/ssl");
11
11
  class ContentServer {
12
12
  constructor(ipAddress, storeId) {
@@ -20,13 +20,11 @@ class ContentServer {
20
20
  }
21
21
  // Method to get the content of a specified key from the peer, with optional challenge query
22
22
  async getKey(key, rootHash, challengeHex) {
23
- // Construct the base URL
24
23
  let url = `https://${this.ipAddress}:${ContentServer.port}/chia.${this.storeId}.${rootHash}/${key}`;
25
- // If a challenge is provided, append it as a query parameter
26
24
  if (challengeHex) {
27
25
  url += `?challenge=${challengeHex}`;
28
26
  }
29
- return this.fetchWithRetries(url);
27
+ return this.fetch(url);
30
28
  }
31
29
  // Method to get the payment address from the peer
32
30
  async getPaymentAddress() {
@@ -90,219 +88,89 @@ class ContentServer {
90
88
  }
91
89
  return false;
92
90
  }
93
- streamKey(key, rootHash) {
94
- let udi = `chia.${this.storeId}`;
95
- if (rootHash) {
96
- udi += `.${rootHash}`;
97
- }
98
- return new Promise((resolve, reject) => {
99
- const url = `https://${this.ipAddress}:${ContentServer.port}/${udi}/${key}`;
100
- const urlObj = new url_1.URL(url);
101
- const requestOptions = {
102
- hostname: urlObj.hostname,
103
- port: urlObj.port || ContentServer.port,
104
- path: urlObj.pathname + urlObj.search,
105
- method: "GET",
91
+ // Helper method to perform HEAD requests using axios
92
+ async head(url) {
93
+ try {
94
+ const config = this.getAxiosConfig();
95
+ const response = await axios_1.default.head(url, config);
96
+ return {
97
+ success: response.status >= 200 && response.status < 300,
98
+ headers: response.headers,
106
99
  };
107
- const request = http_1.default.request(requestOptions, (response) => {
108
- if (response.statusCode === 200) {
109
- resolve(response); // Resolve with the readable stream
110
- }
111
- else if (response.statusCode === 301 || response.statusCode === 302) {
112
- // Handle redirects
113
- const redirectUrl = response.headers.location;
114
- if (redirectUrl) {
115
- this.streamKey(redirectUrl).then(resolve).catch(reject);
116
- }
117
- else {
118
- reject(new Error("Redirected without a location header"));
119
- }
120
- }
121
- else {
122
- reject(new Error(`Failed to retrieve data from ${url}. Status code: ${response.statusCode}`));
123
- }
124
- });
125
- request.on("error", (error) => {
126
- console.error(`GET Request error for ${url}:`, error);
127
- reject(error);
128
- });
129
- request.end();
130
- });
131
- }
132
- // Helper method to perform HEAD requests
133
- async head(url, maxRedirects = 5) {
134
- return new Promise((resolve, reject) => {
135
- try {
136
- // Parse the input URL
137
- const urlObj = new url_1.URL(url);
138
- const requestOptions = {
139
- hostname: urlObj.hostname,
140
- port: urlObj.port ||
141
- (urlObj.protocol === "http:" ? 80 : ContentServer.port),
142
- path: urlObj.pathname + urlObj.search,
143
- method: "HEAD",
144
- key: fs_1.default.readFileSync(ContentServer.keyPath),
145
- cert: fs_1.default.readFileSync(ContentServer.certPath),
146
- rejectUnauthorized: false,
147
- };
148
- const request = http_1.default.request(requestOptions, (response) => {
149
- const { statusCode, headers } = response;
150
- // If status code is 2xx, return success
151
- if (statusCode && statusCode >= 200 && statusCode < 300) {
152
- resolve({ success: true, headers });
153
- }
154
- // Handle 3xx redirection
155
- else if (statusCode &&
156
- statusCode >= 300 &&
157
- statusCode < 400 &&
158
- headers.location) {
159
- if (maxRedirects > 0) {
160
- let redirectUrl = headers.location;
161
- // Check if the redirect URL is relative
162
- if (!/^https?:\/\//i.test(redirectUrl)) {
163
- // Resolve the relative URL based on the original URL
164
- redirectUrl = new url_1.URL(redirectUrl, url).toString();
165
- console.log(`Resolved relative redirect to: ${redirectUrl}`);
166
- }
167
- else {
168
- console.log(`Redirecting to: ${redirectUrl}`);
169
- }
170
- // Recursively follow the redirection
171
- this.head(redirectUrl, maxRedirects - 1)
172
- .then(resolve)
173
- .catch(reject);
174
- }
175
- else {
176
- reject({ success: false, message: "Too many redirects" });
177
- }
178
- }
179
- else {
180
- // For other status codes, consider it a failure
181
- resolve({ success: false });
182
- }
183
- });
184
- request.on("error", (error) => {
185
- console.error(`HEAD ${url}:`, error.message);
186
- reject({ success: false });
187
- });
188
- request.end();
189
- }
190
- catch (err) {
191
- console.error(`Invalid URL: ${url}`, err);
192
- reject({ success: false, message: "Invalid URL" });
193
- }
194
- });
100
+ }
101
+ catch (error) {
102
+ return { success: false };
103
+ }
195
104
  }
196
105
  // Helper method to fetch JSON data from a URL
197
106
  async fetchJson(url) {
198
- const response = await this.fetchWithRetries(url);
107
+ const response = await this.fetch(url);
199
108
  return JSON.parse(response);
200
109
  }
201
- // Helper method to fetch content with retries and redirection handling
202
- async fetchWithRetries(url) {
203
- let attempt = 0;
204
- const maxRetries = 1;
205
- const initialDelay = 2000; // 2 seconds
206
- const maxDelay = 10000; // 10 seconds
207
- const delayMultiplier = 1.5;
208
- let delay = initialDelay;
209
- while (attempt < maxRetries) {
210
- try {
211
- return await this.fetch(url);
212
- }
213
- catch (error) {
214
- if (attempt < maxRetries - 1) {
215
- console.warn(`Attempt ${attempt + 1} failed: ${error.message}. Retrying in ${delay / 1000} seconds...`);
216
- await new Promise((resolve) => setTimeout(resolve, delay));
217
- delay = Math.min(maxDelay, delay * delayMultiplier);
218
- }
219
- else {
220
- console.error(`Failed to retrieve data from ${url}. Aborting.`);
221
- throw new Error(`Failed to retrieve data: ${error.message}`);
222
- }
223
- }
224
- attempt++;
225
- }
226
- throw new Error(`Failed to retrieve data from ${url} after ${maxRetries} attempts.`);
227
- }
228
- // Core method to fetch content from a URL with a 5-second inactivity timeout
229
- async fetch(url, maxRedirects = 5) {
110
+ // Core method to fetch content from a URL with a 5-second inactivity timeout, handling redirects
111
+ async fetch(url) {
112
+ const config = this.getAxiosConfig();
113
+ // Create a cancel token for the inactivity timeout
114
+ const source = axios_1.default.CancelToken.source();
230
115
  return new Promise((resolve, reject) => {
231
- const urlObj = new url_1.URL(url);
232
- const timeoutDuration = 5000; // 5 seconds
233
- let timeout = null; // Initialize timeout
234
- const requestOptions = {
235
- hostname: urlObj.hostname,
236
- port: urlObj.port || ContentServer.port,
237
- path: urlObj.pathname + urlObj.search, // Include query params
238
- method: "GET",
239
- key: fs_1.default.readFileSync(ContentServer.keyPath),
240
- cert: fs_1.default.readFileSync(ContentServer.certPath),
241
- rejectUnauthorized: false,
116
+ let timeout = null;
117
+ const resetTimeout = () => {
118
+ if (timeout) {
119
+ clearTimeout(timeout);
120
+ }
121
+ timeout = setTimeout(() => {
122
+ source.cancel(`Request timed out after ${ContentServer.inactivityTimeout / 1000} seconds of inactivity`);
123
+ }, ContentServer.inactivityTimeout);
242
124
  };
243
- const request = http_1.default.request(requestOptions, (response) => {
125
+ axios_1.default
126
+ .get(url, {
127
+ ...config,
128
+ cancelToken: source.token,
129
+ responseType: "stream", // Use stream to track data transfer
130
+ maxRedirects: 5, // Axios follows up to 5 redirects by default
131
+ })
132
+ .then((response) => {
244
133
  let data = "";
245
- // Set timeout for inactivity
246
- timeout = setTimeout(() => {
247
- console.error(`Request timeout: No data received for ${timeoutDuration / 1000} seconds.`);
248
- request.destroy(); // Use destroy instead of abort
249
- reject(new Error(`Request timed out after ${timeoutDuration / 1000} seconds of inactivity`));
250
- }, timeoutDuration);
251
- const resetTimeout = () => {
134
+ response.data.on("data", (chunk) => {
135
+ data += chunk;
136
+ resetTimeout(); // Reset the timeout when data is received
137
+ });
138
+ response.data.on("end", () => {
252
139
  if (timeout) {
253
- clearTimeout(timeout);
254
- }
255
- timeout = setTimeout(() => {
256
- console.error(`Request timeout: No data received for ${timeoutDuration / 1000} seconds.`);
257
- request.destroy(); // Use destroy instead of abort
258
- reject(new Error(`Request timed out after ${timeoutDuration / 1000} seconds of inactivity`));
259
- }, timeoutDuration);
260
- };
261
- if (response.statusCode === 200) {
262
- response.on("data", (chunk) => {
263
- data += chunk;
264
- resetTimeout(); // Reset the timeout every time data is received
265
- });
266
- response.on("end", () => {
267
- if (timeout) {
268
- clearTimeout(timeout);
269
- }
270
- resolve(data);
271
- });
272
- }
273
- else if ((response.statusCode === 301 || response.statusCode === 302) &&
274
- response.headers.location) {
275
- // Handle redirects
276
- if (maxRedirects > 0) {
277
- const redirectUrl = new url_1.URL(response.headers.location, url); // Resolve relative URLs based on the original URL
278
- if (timeout) {
279
- clearTimeout(timeout);
280
- }
281
- this.fetch(redirectUrl.toString(), maxRedirects - 1)
282
- .then(resolve)
283
- .catch(reject);
284
- }
285
- else {
286
- reject(new Error("Too many redirects"));
140
+ clearTimeout(timeout); // Clear timeout on stream end
287
141
  }
288
- }
289
- else {
142
+ resolve(data);
143
+ });
144
+ response.data.on("error", (error) => {
290
145
  if (timeout) {
291
146
  clearTimeout(timeout);
292
147
  }
293
- reject(new Error(`Failed to retrieve data from ${url}. Status code: ${response.statusCode}`));
148
+ reject(error);
149
+ });
150
+ })
151
+ .catch((error) => {
152
+ if (axios_1.default.isCancel(error)) {
153
+ console.error("Request canceled:", error.message);
294
154
  }
295
- });
296
- request.on("error", (error) => {
297
- if (timeout) {
298
- clearTimeout(timeout);
155
+ else {
156
+ console.error(`Failed to retrieve data from ${url}:`, error.message);
299
157
  }
300
- console.error(`GET ${url}:`, error.message);
301
158
  reject(error);
302
159
  });
303
- request.end();
304
160
  });
305
161
  }
162
+ // Helper method to configure axios with HTTPS settings
163
+ getAxiosConfig() {
164
+ return {
165
+ httpsAgent: new https_1.default.Agent({
166
+ cert: fs_1.default.readFileSync(ContentServer.certPath),
167
+ key: fs_1.default.readFileSync(ContentServer.keyPath),
168
+ rejectUnauthorized: false,
169
+ }),
170
+ timeout: 0, // Disable axios timeout (we're using inactivity timeout)
171
+ };
172
+ }
306
173
  }
307
174
  exports.ContentServer = ContentServer;
308
175
  ContentServer.port = 4161;
176
+ ContentServer.inactivityTimeout = 5000; // Inactivity timeout in milliseconds (5 seconds)
@@ -1,4 +1,5 @@
1
1
  import https from "https";
2
+ import { PassThrough } from "stream";
2
3
  export declare class PropagationServer {
3
4
  storeId: string;
4
5
  sessionId: string;
@@ -10,6 +11,7 @@ export declare class PropagationServer {
10
11
  username: string | undefined;
11
12
  password: string | undefined;
12
13
  private static readonly port;
14
+ private static readonly inactivityTimeout;
13
15
  constructor(ipAddress: string, storeId: string);
14
16
  /**
15
17
  * Initialize the Wallet instance.
@@ -19,6 +21,10 @@ export declare class PropagationServer {
19
21
  * Create an Axios HTTPS Agent with self-signed certificate allowance.
20
22
  */
21
23
  createHttpsAgent(): https.Agent;
24
+ /**
25
+ * Adds a custom inactivity timeout for large file transfers.
26
+ */
27
+ addInactivityTimeout(stream: PassThrough, timeoutMs: number): PassThrough;
22
28
  /**
23
29
  * Check if the store and optional root hash exist by making a HEAD request.
24
30
  */
@@ -1 +1 @@
1
- {"version":3,"file":"PropagationServer.d.ts","sourceRoot":"","sources":["../../src/DigNetwork/PropagationServer.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,MAAM,OAAO,CAAC;AAyB1B,qBAAa,iBAAiB;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,GAAG,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAE7B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAQ;gBAExB,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;IAY9C;;OAEG;IACG,gBAAgB;IAOtB;;OAEG;IACH,gBAAgB;IAQhB;;OAEG;IACG,gBAAgB,CACpB,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC;QAAE,WAAW,EAAE,OAAO,CAAC;QAAC,cAAc,EAAE,OAAO,CAAA;KAAE,CAAC;IA0C7D;;OAEG;IACG,kBAAkB,CAAC,QAAQ,EAAE,MAAM;IAuDzC;;OAEG;IACG,YAAY,CAChB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,OAAO,CAAA;KAAE,CAAC;IAyBlD;;;OAGG;IACG,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;IAoGhD;;OAEG;IACG,mBAAmB;IAgCzB;;OAEG;WACU,WAAW,CACtB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM;IA2DnB;;;OAGG;IACG,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IA0ElD;;OAEG;IACG,cAAc,CAClB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;QAAE,MAAM,EAAE,OAAO,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IA0B7C;;;OAGG;IACG,YAAY,CAChB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM;IA+FjB;;OAEG;WACU,aAAa,CACxB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM;CA2FpB"}
1
+ {"version":3,"file":"PropagationServer.d.ts","sourceRoot":"","sources":["../../src/DigNetwork/PropagationServer.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,MAAM,OAAO,CAAC;AAW1B,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAiBrC,qBAAa,iBAAiB;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,GAAG,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAE7B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAQ;IACpC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAQ;gBAErC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;IAY9C;;OAEG;IACG,gBAAgB;IAOtB;;OAEG;IACH,gBAAgB;IAQhB;;OAEG;IACH,oBAAoB,CAAC,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM;IAyB3D;;OAEG;IACG,gBAAgB,CACpB,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC;QAAE,WAAW,EAAE,OAAO,CAAC;QAAC,cAAc,EAAE,OAAO,CAAA;KAAE,CAAC;IA0C7D;;OAEG;IACG,kBAAkB,CAAC,QAAQ,EAAE,MAAM;IAuDzC;;OAEG;IACG,YAAY,CAChB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,OAAO,CAAA;KAAE,CAAC;IAyBlD;;;OAGG;IACG,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;IAuGhD;;OAEG;IACG,mBAAmB;IAgCzB;;OAEG;WACU,WAAW,CACtB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM;IA2DnB;;;OAGG;IACG,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAgFlD;;OAEG;IACG,cAAc,CAClB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;QAAE,MAAM,EAAE,OAAO,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IA0B7C;;;OAGG;IACG,YAAY,CAChB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM;IAwGjB;;OAEG;WACU,aAAa,CACxB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM;CA2FpB"}
@@ -4,26 +4,25 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.PropagationServer = void 0;
7
- // Import necessary modules and dependencies
8
7
  const axios_1 = __importDefault(require("axios"));
9
- const fs_1 = __importDefault(require("fs"));
10
- const path_1 = __importDefault(require("path"));
8
+ const cli_progress_1 = __importDefault(require("cli-progress"));
11
9
  const form_data_1 = __importDefault(require("form-data"));
12
- const blockchain_1 = require("../blockchain");
13
- const ssl_1 = require("../utils/ssl");
14
- const credentialsUtils_1 = require("../utils/credentialsUtils");
10
+ const fs_1 = __importDefault(require("fs"));
11
+ const fs_extra_1 = __importDefault(require("fs-extra"));
15
12
  const https_1 = __importDefault(require("https"));
16
- const cli_progress_1 = __importDefault(require("cli-progress"));
17
- const colorette_1 = require("colorette");
18
- const config_1 = require("../utils/config");
19
- const hashUtils_1 = require("../utils/hashUtils");
20
- const nanospinner_1 = require("nanospinner");
13
+ const os_1 = __importDefault(require("os"));
14
+ const path_1 = __importDefault(require("path"));
21
15
  const progress_stream_1 = __importDefault(require("progress-stream"));
22
- const stream_1 = require("stream");
23
16
  const asyncPool_1 = require("../utils/asyncPool");
24
- const fs_extra_1 = __importDefault(require("fs-extra"));
25
- const os_1 = __importDefault(require("os"));
17
+ const nanospinner_1 = require("nanospinner");
18
+ const hashUtils_1 = require("../utils/hashUtils");
19
+ const ssl_1 = require("../utils/ssl");
20
+ const colorette_1 = require("colorette");
26
21
  const merkle_1 = require("../utils/merkle");
22
+ const stream_1 = require("stream");
23
+ const credentialsUtils_1 = require("../utils/credentialsUtils");
24
+ const config_1 = require("../utils/config");
25
+ const blockchain_1 = require("../blockchain");
27
26
  // Helper function to trim long filenames with ellipsis and ensure consistent padding
28
27
  function formatFilename(filename, maxLength = 30) {
29
28
  if (!filename) {
@@ -62,6 +61,26 @@ class PropagationServer {
62
61
  rejectUnauthorized: false,
63
62
  });
64
63
  }
64
+ /**
65
+ * Adds a custom inactivity timeout for large file transfers.
66
+ */
67
+ addInactivityTimeout(stream, timeoutMs) {
68
+ let timeoutId;
69
+ const resetTimeout = () => {
70
+ clearTimeout(timeoutId);
71
+ timeoutId = setTimeout(() => {
72
+ stream.destroy(new Error(`Inactivity timeout after ${timeoutMs / 1000} seconds`));
73
+ }, timeoutMs);
74
+ };
75
+ // Reset timeout every time data is received
76
+ stream.on("data", resetTimeout);
77
+ // Set the initial timeout
78
+ resetTimeout();
79
+ // Clear the timeout when the stream ends
80
+ stream.on("end", () => clearTimeout(timeoutId));
81
+ stream.on("error", () => clearTimeout(timeoutId)); // Handle errors
82
+ return stream;
83
+ }
65
84
  /**
66
85
  * Check if the store and optional root hash exist by making a HEAD request.
67
86
  */
@@ -201,8 +220,8 @@ class PropagationServer {
201
220
  progressStream.on("progress", (progress) => {
202
221
  progressBar.update(progress.transferred);
203
222
  });
204
- // Create a PassThrough stream
205
- const passThroughStream = new stream_1.PassThrough();
223
+ // Add inactivity timeout to the progress stream
224
+ const passThroughStream = this.addInactivityTimeout(new stream_1.PassThrough(), PropagationServer.inactivityTimeout);
206
225
  // Pipe the read stream through the progress stream into the PassThrough stream
207
226
  fileReadStream.pipe(progressStream).pipe(passThroughStream);
208
227
  // Use form-data to construct the request body
@@ -348,7 +367,9 @@ class PropagationServer {
348
367
  progressStream.on("progress", (progress) => {
349
368
  progressBar.update(progress.transferred);
350
369
  });
351
- response.data.pipe(progressStream);
370
+ // Add inactivity timeout to the progress stream
371
+ const passThroughStream = this.addInactivityTimeout(new stream_1.PassThrough(), PropagationServer.inactivityTimeout);
372
+ response.data.pipe(progressStream).pipe(passThroughStream);
352
373
  progressStream.on("data", (chunk) => {
353
374
  dataBuffers.push(chunk);
354
375
  });
@@ -436,7 +457,12 @@ class PropagationServer {
436
457
  progressStream.on("progress", (progress) => {
437
458
  progressBar.update(progress.transferred);
438
459
  });
439
- response.data.pipe(progressStream).pipe(fileWriteStream);
460
+ // Add inactivity timeout to the progress stream
461
+ const passThroughStream = this.addInactivityTimeout(new stream_1.PassThrough(), PropagationServer.inactivityTimeout);
462
+ response.data
463
+ .pipe(progressStream)
464
+ .pipe(passThroughStream)
465
+ .pipe(fileWriteStream);
440
466
  // Wait for both the file write stream and the progress stream to finish
441
467
  await Promise.all([
442
468
  new Promise((resolve, reject) => {
@@ -534,3 +560,4 @@ class PropagationServer {
534
560
  }
535
561
  exports.PropagationServer = PropagationServer;
536
562
  PropagationServer.port = 4159; // Static port used for all requests
563
+ PropagationServer.inactivityTimeout = 5000; // Inactivity timeout in milliseconds (5 seconds)
@@ -5,7 +5,13 @@ export declare class FullNodePeer {
5
5
  private peer;
6
6
  private static deprioritizedIps;
7
7
  private constructor();
8
- static connect(): Promise<Peer>;
8
+ /**
9
+ * Connect to the best peer, optionally using custom certificate and key file paths.
10
+ * @param {string} [certFilePath] - Optional custom certificate file path.
11
+ * @param {string} [keyFilePath] - Optional custom key file path.
12
+ * @returns {Promise<Peer>} The connected peer.
13
+ */
14
+ static connect(certFilePath?: string, keyFilePath?: string): Promise<Peer>;
9
15
  private static isPortReachable;
10
16
  private static isValidIpAddress;
11
17
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"FullNodePeer.d.ts","sourceRoot":"","sources":["../../src/blockchain/FullNodePeer.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,IAAI,EAAE,MAAM,8BAA8B,CAAC;AAqBpD,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAC,UAAU,CAAkD;IAC3E,OAAO,CAAC,MAAM,CAAC,uBAAuB,CAA0B;IAChE,OAAO,CAAC,IAAI,CAAO;IACnB,OAAO,CAAC,MAAM,CAAC,gBAAgB,CAA0B;IAMzD,OAAO;WAIa,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAK5C,OAAO,CAAC,MAAM,CAAC,eAAe;IAiB9B,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAM/B;;;;;OAKG;IACH,OAAO,CAAC,MAAM,CAAC,kBAAkB;mBASZ,eAAe;mBA2Df,UAAU;IA2B/B,OAAO,CAAC,MAAM,CAAC,eAAe;mBAkDT,WAAW;IAuGzB,OAAO,IAAI,IAAI;WAIF,mBAAmB,CACrC,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,OAAO,CAAC;CAwBpB"}
1
+ {"version":3,"file":"FullNodePeer.d.ts","sourceRoot":"","sources":["../../src/blockchain/FullNodePeer.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,IAAI,EAAE,MAAM,8BAA8B,CAAC;AAqBpD,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAC,UAAU,CAAkD;IAC3E,OAAO,CAAC,MAAM,CAAC,uBAAuB,CAA0B;IAChE,OAAO,CAAC,IAAI,CAAO;IACnB,OAAO,CAAC,MAAM,CAAC,gBAAgB,CAA0B;IAQzD,OAAO;IAIP;;;;;OAKG;WACiB,OAAO,CACzB,YAAY,CAAC,EAAE,MAAM,EACrB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC;IAKhB,OAAO,CAAC,MAAM,CAAC,eAAe;IAiB9B,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAM/B;;;;;OAKG;IACH,OAAO,CAAC,MAAM,CAAC,kBAAkB;mBASZ,eAAe;mBA6Df,UAAU;IA2B/B,OAAO,CAAC,MAAM,CAAC,eAAe;mBAyDT,WAAW;IA+HzB,OAAO,IAAI,IAAI;WAIF,mBAAmB,CACrC,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,OAAO,CAAC;CAwBpB"}
@@ -30,8 +30,14 @@ class FullNodePeer {
30
30
  constructor(peer) {
31
31
  this.peer = peer;
32
32
  }
33
- static async connect() {
34
- const peer = await FullNodePeer.getBestPeer();
33
+ /**
34
+ * Connect to the best peer, optionally using custom certificate and key file paths.
35
+ * @param {string} [certFilePath] - Optional custom certificate file path.
36
+ * @param {string} [keyFilePath] - Optional custom key file path.
37
+ * @returns {Promise<Peer>} The connected peer.
38
+ */
39
+ static async connect(certFilePath, keyFilePath) {
40
+ const peer = await FullNodePeer.getBestPeer(certFilePath, keyFilePath);
35
41
  return new FullNodePeer(peer).peer;
36
42
  }
37
43
  static isPortReachable(host, port, timeout = CONNECTION_TIMEOUT) {
@@ -158,7 +164,8 @@ class FullNodePeer {
158
164
  }
159
165
  catch (error) {
160
166
  // If the error is WebSocket-related or timeout, reset the peer
161
- if (error.message.includes("WebSocket") || error.message.includes("Operation timed out")) {
167
+ if (error.message.includes("WebSocket") ||
168
+ error.message.includes("Operation timed out")) {
162
169
  FullNodePeer.cachedPeer = null;
163
170
  // @ts-ignore
164
171
  FullNodePeer.memoizedFetchNewPeerIPs.cache.clear();
@@ -175,17 +182,33 @@ class FullNodePeer {
175
182
  },
176
183
  });
177
184
  }
178
- static async getBestPeer() {
185
+ static async getBestPeer(certFilePath, keyFilePath) {
179
186
  const now = Date.now();
180
187
  if (FullNodePeer.cachedPeer &&
181
188
  now - FullNodePeer.cachedPeer.timestamp < CACHE_DURATION) {
182
189
  return FullNodePeer.cachedPeer.peer;
183
190
  }
184
- const sslFolder = path_1.default.resolve(os_1.default.homedir(), ".dig", "ssl");
185
- const certFile = path_1.default.join(sslFolder, "public_dig.crt");
186
- const keyFile = path_1.default.join(sslFolder, "public_dig.key");
187
- if (!fs_1.default.existsSync(sslFolder)) {
188
- fs_1.default.mkdirSync(sslFolder, { recursive: true });
191
+ let certFile;
192
+ let keyFile;
193
+ // If certFilePath or keyFilePath is provided, ensure both are provided
194
+ if (certFilePath && keyFilePath) {
195
+ certFile = certFilePath;
196
+ keyFile = keyFilePath;
197
+ if (!fs_1.default.existsSync(certFile)) {
198
+ throw new Error(`Certificate file not found: ${certFile}`);
199
+ }
200
+ if (!fs_1.default.existsSync(keyFile)) {
201
+ throw new Error(`Key file not found: ${keyFile}`);
202
+ }
203
+ }
204
+ else {
205
+ // Use default paths if no custom paths are provided
206
+ const sslFolder = path_1.default.resolve(os_1.default.homedir(), ".dig", "ssl");
207
+ certFile = path_1.default.join(sslFolder, "public_dig.crt");
208
+ keyFile = path_1.default.join(sslFolder, "public_dig.key");
209
+ if (!fs_1.default.existsSync(sslFolder)) {
210
+ throw new Error(`SSL folder not found: ${sslFolder}`);
211
+ }
189
212
  }
190
213
  new chia_server_coin_1.Tls(certFile, keyFile);
191
214
  const peerIPs = await FullNodePeer.getPeerIPs();
@@ -230,7 +253,9 @@ class FullNodePeer {
230
253
  // Prioritize LOCALHOST, TRUSTED_NODE_IP, and CHIA_NODES_HOST if they have the highest peak height
231
254
  let bestPeerIndex = validHeights.findIndex((height, index) => height === highestPeak &&
232
255
  !FullNodePeer.deprioritizedIps.has(peerIPs[index]) && // Exclude deprioritized IPs
233
- (peerIPs[index] === LOCALHOST || peerIPs[index] === trustedNodeIp || peerIPs[index] === CHIA_NODES_HOST));
256
+ (peerIPs[index] === LOCALHOST ||
257
+ peerIPs[index] === trustedNodeIp ||
258
+ peerIPs[index] === CHIA_NODES_HOST));
234
259
  // If LOCALHOST, TRUSTED_NODE_IP, or CHIA_NODES_HOST don't have the highest peak, select any peer with the highest peak
235
260
  if (bestPeerIndex === -1) {
236
261
  bestPeerIndex = validHeights.findIndex((height) => height === highestPeak);
@@ -1 +1 @@
1
- {"version":3,"file":"ServerCoin.d.ts","sourceRoot":"","sources":["../../src/blockchain/ServerCoin.ts"],"names":[],"mappings":"AACA,OAAO,EAML,UAAU,IAAI,gBAAgB,EAE/B,MAAM,8BAA8B,CAAC;AAItC,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAYrD,qBAAa,UAAU;IACrB,OAAO,CAAC,OAAO,CAAS;IACxB,gBAAuB,iBAAiB,eAEtC;gBAEU,OAAO,EAAE,MAAM;IAKd,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IA4D3E,kBAAkB,CAC7B,UAAU,EAAE,gBAAgB,EAC5B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC;IAsBH,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAoDjD,oBAAoB;IAerB,gBAAgB,CAC3B,KAAK,EAAE,MAAM,EACb,SAAS,GAAE,MAAM,EAAO,GACvB,OAAO,CAAC,MAAM,EAAE,CAAC;IAgDP,mBAAmB,CAC9B,SAAS,GAAE,MAAM,EAAO,GACvB,OAAO,CAAC,MAAM,EAAE,CAAC;IAMP,kBAAkB,CAC7B,UAAU,GAAE,MAAU,EACtB,SAAS,GAAE,MAAM,EAAO,GACvB,OAAO,CAAC,MAAM,EAAE,CAAC;IAMP,wBAAwB,CACnC,KAAK,EAAE,MAAM,EACb,UAAU,GAAE,MAAU,EACtB,SAAS,GAAE,MAAM,EAAO,GACvB,OAAO,CAAC,MAAM,EAAE,CAAC;WAeN,eAAe,IAAI;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE;IAKpD,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiFrD,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;WA+B1C,uBAAuB;YAkE7B,sBAAsB;IAWvB,uBAAuB,CAClC,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,OAAO,CAAC;WAuBL,sBAAsB,CAAC,mBAAmB,EAAE,IAAI,GAAG;QAC/D,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC;KACf;CA2BF"}
1
+ {"version":3,"file":"ServerCoin.d.ts","sourceRoot":"","sources":["../../src/blockchain/ServerCoin.ts"],"names":[],"mappings":"AACA,OAAO,EAML,UAAU,IAAI,gBAAgB,EAE/B,MAAM,8BAA8B,CAAC;AAItC,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAYrD,qBAAa,UAAU;IACrB,OAAO,CAAC,OAAO,CAAS;IACxB,gBAAuB,iBAAiB,eAEtC;gBAEU,OAAO,EAAE,MAAM;IAKd,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IA4D3E,kBAAkB,CAC7B,UAAU,EAAE,gBAAgB,EAC5B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC;IAsBH,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAoDjD,oBAAoB;IAerB,gBAAgB,CAC3B,KAAK,EAAE,MAAM,EACb,SAAS,GAAE,MAAM,EAAO,GACvB,OAAO,CAAC,MAAM,EAAE,CAAC;IAoDP,mBAAmB,CAC9B,SAAS,GAAE,MAAM,EAAO,GACvB,OAAO,CAAC,MAAM,EAAE,CAAC;IAMP,kBAAkB,CAC7B,UAAU,GAAE,MAAU,EACtB,SAAS,GAAE,MAAM,EAAO,GACvB,OAAO,CAAC,MAAM,EAAE,CAAC;IAMP,wBAAwB,CACnC,KAAK,EAAE,MAAM,EACb,UAAU,GAAE,MAAU,EACtB,SAAS,GAAE,MAAM,EAAO,GACvB,OAAO,CAAC,MAAM,EAAE,CAAC;WAeN,eAAe,IAAI;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE;IAKpD,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiFrD,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;WA+B1C,uBAAuB;YAkE7B,sBAAsB;IAWvB,uBAAuB,CAClC,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,OAAO,CAAC;WAuBL,sBAAsB,CAAC,mBAAmB,EAAE,IAAI,GAAG;QAC/D,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC;KACf;CA2BF"}
@@ -30,7 +30,7 @@ class ServerCoin {
30
30
  const serverCoinCreationCoins = await (0, coins_1.selectUnspentCoins)(peer, BigInt(serverCoinCollateral), BigInt(1000000));
31
31
  const { epoch: currentEpoch } = ServerCoin.getCurrentEpoch();
32
32
  const epochBasedHint = (0, datalayer_driver_1.morphLauncherId)(Buffer.from(this.storeId, "hex"), BigInt(currentEpoch));
33
- const newServerCoin = (0, datalayer_driver_1.createServerCoin)(publicSyntheticKey, serverCoinCreationCoins, epochBasedHint, [peerIp], BigInt(serverCoinCollateral), BigInt(1000000));
33
+ const newServerCoin = (0, datalayer_driver_1.createServerCoin)(publicSyntheticKey, serverCoinCreationCoins, epochBasedHint, [peerIp, publicSyntheticKey.toString("hex")], BigInt(serverCoinCollateral), BigInt(1000000));
34
34
  const combinedCoinSpends = [...newServerCoin.coinSpends];
35
35
  const sig = (0, datalayer_driver_1.signCoinSpends)(combinedCoinSpends, [await wallet.getPrivateSyntheticKey()], false);
36
36
  const err = await peer.broadcastSpend(combinedCoinSpends, [sig]);
@@ -117,6 +117,9 @@ class ServerCoin {
117
117
  for (const coinState of filteredCoinStates) {
118
118
  const serverCoin = await peer.fetchServerCoin(coinState, maxClvmCost);
119
119
  const peerUrl = serverCoin.memoUrls[0];
120
+ // The second memo URL is the public key
121
+ // We will utilize this for future features
122
+ const publicKey = serverCoin.memoUrls[1];
120
123
  if (!blacklist.includes(peerUrl)) {
121
124
  serverCoinPeers.add(peerUrl);
122
125
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dignetwork/dig-sdk",
3
- "version": "0.0.1-alpha.97",
3
+ "version": "0.0.1-alpha.99",
4
4
  "description": "",
5
5
  "type": "commonjs",
6
6
  "main": "./dist/index.js",