@hiero-ledger/sdk 2.74.0 → 2.75.0
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.
- package/dist/umd.js +119 -88
- package/dist/umd.min.js +1 -1
- package/lib/client/addressbooks/mainnet.cjs +1 -1
- package/lib/client/addressbooks/mainnet.d.ts +1 -1
- package/lib/client/addressbooks/mainnet.js +1 -1
- package/lib/client/addressbooks/mainnet.js.map +1 -1
- package/lib/client/addressbooks/previewnet.cjs +1 -1
- package/lib/client/addressbooks/previewnet.d.ts +1 -1
- package/lib/client/addressbooks/previewnet.js +1 -1
- package/lib/client/addressbooks/previewnet.js.map +1 -1
- package/lib/client/addressbooks/testnet.cjs +1 -1
- package/lib/client/addressbooks/testnet.d.ts +1 -1
- package/lib/client/addressbooks/testnet.js +1 -1
- package/lib/client/addressbooks/testnet.js.map +1 -1
- package/lib/network/AddressBookQueryWeb.cjs +88 -60
- package/lib/network/AddressBookQueryWeb.d.ts +7 -37
- package/lib/network/AddressBookQueryWeb.js +1 -1
- package/lib/network/AddressBookQueryWeb.js.map +1 -1
- package/lib/version.js +1 -1
- package/package.json +7 -7
- package/src/client/addressbooks/mainnet.js +1 -1
- package/src/client/addressbooks/previewnet.js +1 -1
- package/src/client/addressbooks/testnet.js +1 -1
- package/src/network/AddressBookQueryWeb.js +122 -91
|
@@ -49,8 +49,15 @@ import {
|
|
|
49
49
|
* description: string,
|
|
50
50
|
* stake: number
|
|
51
51
|
* }>} nodes
|
|
52
|
+
* @property {?{next: ?string}} links - Links object containing pagination information
|
|
52
53
|
*/
|
|
53
54
|
|
|
55
|
+
/**
|
|
56
|
+
* Default page size limit for optimal pagination performance
|
|
57
|
+
* @constant {number}
|
|
58
|
+
*/
|
|
59
|
+
const DEFAULT_PAGE_SIZE = 25;
|
|
60
|
+
|
|
54
61
|
/**
|
|
55
62
|
* Web-compatible query to get a list of Hedera network node addresses from a mirror node.
|
|
56
63
|
* Uses fetch API instead of gRPC for web environments.
|
|
@@ -65,7 +72,7 @@ export default class AddressBookQueryWeb extends Query {
|
|
|
65
72
|
/**
|
|
66
73
|
* @param {object} props
|
|
67
74
|
* @param {FileId | string} [props.fileId]
|
|
68
|
-
* @param {number} [props.limit]
|
|
75
|
+
* @param {number} [props.limit] - Page size limit (defaults to 25 for optimal performance)
|
|
69
76
|
*/
|
|
70
77
|
constructor(props = {}) {
|
|
71
78
|
super();
|
|
@@ -232,111 +239,135 @@ export default class AddressBookQueryWeb extends Query {
|
|
|
232
239
|
baseUrl = `${baseUrl}:${port}`;
|
|
233
240
|
}
|
|
234
241
|
|
|
235
|
-
|
|
242
|
+
// Initialize aggregated results
|
|
243
|
+
this._addresses = [];
|
|
244
|
+
let nextUrl = null;
|
|
245
|
+
let isLastPage = false;
|
|
236
246
|
|
|
247
|
+
// Build initial URL
|
|
248
|
+
const initialUrl = new URL(`${baseUrl}/api/v1/network/nodes`);
|
|
237
249
|
if (this._fileId != null) {
|
|
238
|
-
|
|
239
|
-
}
|
|
240
|
-
if (this._limit != null) {
|
|
241
|
-
url.searchParams.append("limit", this._limit.toString());
|
|
250
|
+
initialUrl.searchParams.append("file.id", this._fileId.toString());
|
|
242
251
|
}
|
|
243
252
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
253
|
+
// Use the specified limit, or default to DEFAULT_PAGE_SIZE for optimal pagination performance
|
|
254
|
+
const effectiveLimit =
|
|
255
|
+
this._limit != null ? this._limit : DEFAULT_PAGE_SIZE;
|
|
256
|
+
initialUrl.searchParams.append("limit", effectiveLimit.toString());
|
|
257
|
+
|
|
258
|
+
// Fetch all pages
|
|
259
|
+
while (!isLastPage) {
|
|
260
|
+
const currentUrl = nextUrl ? new URL(nextUrl, baseUrl) : initialUrl;
|
|
261
|
+
|
|
262
|
+
for (let attempt = 0; attempt <= this._maxAttempts; attempt++) {
|
|
263
|
+
try {
|
|
264
|
+
// eslint-disable-next-line n/no-unsupported-features/node-builtins
|
|
265
|
+
const response = await fetch(currentUrl.toString(), {
|
|
266
|
+
method: "GET",
|
|
267
|
+
headers: {
|
|
268
|
+
Accept: "application/json",
|
|
269
|
+
},
|
|
270
|
+
signal: requestTimeout
|
|
271
|
+
? AbortSignal.timeout(requestTimeout)
|
|
272
|
+
: undefined,
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
if (!response.ok) {
|
|
276
|
+
throw new Error(
|
|
277
|
+
`HTTP error! status: ${response.status}`,
|
|
278
|
+
);
|
|
279
|
+
}
|
|
256
280
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
281
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
282
|
+
const data = /** @type {AddressBookQueryWebResponse} */ (
|
|
283
|
+
await response.json()
|
|
284
|
+
);
|
|
260
285
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
node,
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
publicKey: node.public_key,
|
|
279
|
-
description: node.description,
|
|
280
|
-
stake: node.stake.toString(),
|
|
281
|
-
}),
|
|
282
|
-
);
|
|
283
|
-
|
|
284
|
-
const addressBook = new NodeAddressBook({
|
|
285
|
-
nodeAddresses: this._addresses,
|
|
286
|
-
});
|
|
287
|
-
|
|
288
|
-
resolve(addressBook);
|
|
289
|
-
return;
|
|
290
|
-
} catch (error) {
|
|
291
|
-
console.error("Error in _makeFetchRequest:", error);
|
|
292
|
-
const message =
|
|
293
|
-
error instanceof Error ? error.message : String(error);
|
|
294
|
-
|
|
295
|
-
// Check if we should retry
|
|
296
|
-
if (
|
|
297
|
-
attempt < this._maxAttempts &&
|
|
298
|
-
!client.isClientShutDown &&
|
|
299
|
-
this._retryHandler(
|
|
300
|
-
/** @type {MirrorError | Error | null} */ (error),
|
|
301
|
-
)
|
|
302
|
-
) {
|
|
303
|
-
const delay = Math.min(
|
|
304
|
-
250 * 2 ** attempt,
|
|
305
|
-
this._maxBackoff,
|
|
286
|
+
const nodes = data.nodes || [];
|
|
287
|
+
|
|
288
|
+
// Aggregate nodes from this page
|
|
289
|
+
const pageNodes = nodes.map((node) =>
|
|
290
|
+
NodeAddress.fromJSON({
|
|
291
|
+
nodeId: node.node_id.toString(),
|
|
292
|
+
accountId: node.node_account_id,
|
|
293
|
+
addresses:
|
|
294
|
+
this._handleAddressesFromGrpcProxyEndpoint(
|
|
295
|
+
node,
|
|
296
|
+
client,
|
|
297
|
+
),
|
|
298
|
+
certHash: node.node_cert_hash,
|
|
299
|
+
publicKey: node.public_key,
|
|
300
|
+
description: node.description,
|
|
301
|
+
stake: node.stake.toString(),
|
|
302
|
+
}),
|
|
306
303
|
);
|
|
307
304
|
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
305
|
+
this._addresses.push(...pageNodes);
|
|
306
|
+
nextUrl = data.links?.next || null;
|
|
307
|
+
|
|
308
|
+
// If no more pages, set flag to exit loop
|
|
309
|
+
if (!nextUrl) {
|
|
310
|
+
isLastPage = true;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// Move to next page
|
|
314
|
+
break;
|
|
315
|
+
} catch (error) {
|
|
316
|
+
console.error("Error in _makeFetchRequest:", error);
|
|
317
|
+
const message =
|
|
318
|
+
error instanceof Error ? error.message : String(error);
|
|
319
|
+
|
|
320
|
+
// Check if we should retry
|
|
321
|
+
if (
|
|
322
|
+
attempt < this._maxAttempts &&
|
|
323
|
+
!client.isClientShutDown &&
|
|
324
|
+
this._retryHandler(
|
|
325
|
+
/** @type {MirrorError | Error | null} */ (error),
|
|
326
|
+
)
|
|
327
|
+
) {
|
|
328
|
+
const delay = Math.min(
|
|
329
|
+
250 * 2 ** attempt,
|
|
330
|
+
this._maxBackoff,
|
|
317
331
|
);
|
|
332
|
+
|
|
333
|
+
if (this._logger) {
|
|
334
|
+
this._logger.debug(
|
|
335
|
+
`Error getting nodes from mirror for file ${
|
|
336
|
+
this._fileId != null
|
|
337
|
+
? this._fileId.toString()
|
|
338
|
+
: "UNKNOWN"
|
|
339
|
+
} during attempt ${
|
|
340
|
+
attempt + 1
|
|
341
|
+
}. Waiting ${delay} ms before next attempt: ${message}`,
|
|
342
|
+
);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
// Wait before next attempt
|
|
346
|
+
// eslint-disable-next-line ie11/no-loop-func
|
|
347
|
+
await new Promise((resolve) =>
|
|
348
|
+
setTimeout(resolve, delay),
|
|
349
|
+
);
|
|
350
|
+
continue;
|
|
318
351
|
}
|
|
319
352
|
|
|
320
|
-
//
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
353
|
+
// If we shouldn't retry or have exhausted attempts, reject
|
|
354
|
+
const maxAttemptsReached = attempt >= this._maxAttempts;
|
|
355
|
+
const errorMessage = maxAttemptsReached
|
|
356
|
+
? `Failed to query address book after ${
|
|
357
|
+
this._maxAttempts + 1
|
|
358
|
+
} attempts. Last error: ${message}`
|
|
359
|
+
: `Failed to query address book: ${message}`;
|
|
360
|
+
reject(new Error(errorMessage));
|
|
361
|
+
return;
|
|
324
362
|
}
|
|
325
|
-
|
|
326
|
-
// If we shouldn't retry or have exhausted attempts, reject
|
|
327
|
-
const maxAttemptsReached = attempt >= this._maxAttempts;
|
|
328
|
-
const errorMessage = maxAttemptsReached
|
|
329
|
-
? `Failed to query address book after ${
|
|
330
|
-
this._maxAttempts + 1
|
|
331
|
-
} attempts. Last error: ${message}`
|
|
332
|
-
: `Failed to query address book: ${message}`;
|
|
333
|
-
reject(new Error(errorMessage));
|
|
334
|
-
return;
|
|
335
363
|
}
|
|
336
364
|
}
|
|
337
365
|
|
|
338
|
-
//
|
|
339
|
-
|
|
366
|
+
// Return the aggregated results
|
|
367
|
+
const addressBook = new NodeAddressBook({
|
|
368
|
+
nodeAddresses: this._addresses,
|
|
369
|
+
});
|
|
370
|
+
resolve(addressBook);
|
|
340
371
|
}
|
|
341
372
|
|
|
342
373
|
/**
|