@hiero-ledger/sdk 2.73.2 → 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.
Files changed (125) hide show
  1. package/dist/umd.js +368 -202
  2. package/dist/umd.min.js +3 -3
  3. package/lib/MirrorNode.cjs +46 -0
  4. package/lib/MirrorNode.d.ts +16 -0
  5. package/lib/MirrorNode.js +1 -1
  6. package/lib/MirrorNode.js.map +1 -1
  7. package/lib/account/AccountAllowanceApproveTransaction.cjs +11 -5
  8. package/lib/account/AccountAllowanceApproveTransaction.d.ts +4 -5
  9. package/lib/account/AccountAllowanceApproveTransaction.js +1 -1
  10. package/lib/account/AccountAllowanceApproveTransaction.js.map +1 -1
  11. package/lib/account/TokenAllowance.cjs +4 -2
  12. package/lib/account/TokenAllowance.d.ts +4 -2
  13. package/lib/account/TokenAllowance.js +1 -1
  14. package/lib/account/TokenAllowance.js.map +1 -1
  15. package/lib/account/TokenTransferMap.cjs +7 -2
  16. package/lib/account/TokenTransferMap.d.ts +6 -2
  17. package/lib/account/TokenTransferMap.js +1 -1
  18. package/lib/account/TokenTransferMap.js.map +1 -1
  19. package/lib/client/Client.cjs +13 -44
  20. package/lib/client/Client.d.ts +12 -12
  21. package/lib/client/Client.js +1 -1
  22. package/lib/client/Client.js.map +1 -1
  23. package/lib/client/MirrorNetwork.cjs +16 -0
  24. package/lib/client/MirrorNetwork.d.ts +7 -0
  25. package/lib/client/MirrorNetwork.js +1 -1
  26. package/lib/client/MirrorNetwork.js.map +1 -1
  27. package/lib/client/addressbooks/mainnet.cjs +1 -1
  28. package/lib/client/addressbooks/mainnet.d.ts +1 -1
  29. package/lib/client/addressbooks/mainnet.js +1 -1
  30. package/lib/client/addressbooks/mainnet.js.map +1 -1
  31. package/lib/client/addressbooks/previewnet.cjs +1 -1
  32. package/lib/client/addressbooks/previewnet.d.ts +1 -1
  33. package/lib/client/addressbooks/previewnet.js +1 -1
  34. package/lib/client/addressbooks/previewnet.js.map +1 -1
  35. package/lib/client/addressbooks/testnet.cjs +1 -1
  36. package/lib/client/addressbooks/testnet.d.ts +1 -1
  37. package/lib/client/addressbooks/testnet.js +1 -1
  38. package/lib/client/addressbooks/testnet.js.map +1 -1
  39. package/lib/constants/ClientConstants.cjs +4 -1
  40. package/lib/constants/ClientConstants.d.ts +2 -0
  41. package/lib/constants/ClientConstants.js +1 -1
  42. package/lib/constants/ClientConstants.js.map +1 -1
  43. package/lib/contract/ContractId.cjs +2 -5
  44. package/lib/contract/ContractId.js +1 -1
  45. package/lib/contract/ContractId.js.map +1 -1
  46. package/lib/network/AddressBookQueryWeb.cjs +88 -60
  47. package/lib/network/AddressBookQueryWeb.d.ts +7 -37
  48. package/lib/network/AddressBookQueryWeb.js +1 -1
  49. package/lib/network/AddressBookQueryWeb.js.map +1 -1
  50. package/lib/query/MirrorNodeContractQuery.cjs +2 -1
  51. package/lib/query/MirrorNodeContractQuery.js.map +1 -1
  52. package/lib/token/AbstractTokenTransferTransaction.cjs +12 -8
  53. package/lib/token/AbstractTokenTransferTransaction.d.ts +14 -11
  54. package/lib/token/AbstractTokenTransferTransaction.js +1 -1
  55. package/lib/token/AbstractTokenTransferTransaction.js.map +1 -1
  56. package/lib/token/AssessedCustomFee.cjs +8 -4
  57. package/lib/token/AssessedCustomFee.d.ts +8 -5
  58. package/lib/token/AssessedCustomFee.js +1 -1
  59. package/lib/token/AssessedCustomFee.js.map +1 -1
  60. package/lib/token/CustomFixedFee.cjs +8 -4
  61. package/lib/token/CustomFixedFee.d.ts +8 -5
  62. package/lib/token/CustomFixedFee.js +1 -1
  63. package/lib/token/CustomFixedFee.js.map +1 -1
  64. package/lib/token/PendingAirdropRecord.cjs +7 -2
  65. package/lib/token/PendingAirdropRecord.d.ts +6 -2
  66. package/lib/token/PendingAirdropRecord.js +1 -1
  67. package/lib/token/PendingAirdropRecord.js.map +1 -1
  68. package/lib/token/TokenAirdropTransaction.cjs +2 -1
  69. package/lib/token/TokenAirdropTransaction.d.ts +4 -2
  70. package/lib/token/TokenAirdropTransaction.js.map +1 -1
  71. package/lib/token/TokenBurnTransaction.cjs +5 -3
  72. package/lib/token/TokenBurnTransaction.d.ts +6 -4
  73. package/lib/token/TokenBurnTransaction.js +1 -1
  74. package/lib/token/TokenBurnTransaction.js.map +1 -1
  75. package/lib/token/TokenCreateTransaction.cjs +7 -6
  76. package/lib/token/TokenCreateTransaction.d.ts +8 -8
  77. package/lib/token/TokenCreateTransaction.js +1 -1
  78. package/lib/token/TokenCreateTransaction.js.map +1 -1
  79. package/lib/token/TokenMintTransaction.cjs +5 -4
  80. package/lib/token/TokenMintTransaction.d.ts +6 -5
  81. package/lib/token/TokenMintTransaction.js +1 -1
  82. package/lib/token/TokenMintTransaction.js.map +1 -1
  83. package/lib/token/TokenTransfer.cjs +3 -2
  84. package/lib/token/TokenTransfer.d.ts +2 -2
  85. package/lib/token/TokenTransfer.js +1 -1
  86. package/lib/token/TokenTransfer.js.map +1 -1
  87. package/lib/token/TokenWipeTransaction.cjs +5 -3
  88. package/lib/token/TokenWipeTransaction.d.ts +6 -4
  89. package/lib/token/TokenWipeTransaction.js +1 -1
  90. package/lib/token/TokenWipeTransaction.js.map +1 -1
  91. package/lib/transaction/Transaction.cjs +54 -0
  92. package/lib/transaction/Transaction.d.ts +10 -0
  93. package/lib/transaction/Transaction.js +1 -1
  94. package/lib/transaction/Transaction.js.map +1 -1
  95. package/lib/util.cjs +25 -0
  96. package/lib/util.d.ts +8 -0
  97. package/lib/util.js +1 -1
  98. package/lib/util.js.map +1 -1
  99. package/lib/version.js +1 -1
  100. package/package.json +16 -12
  101. package/src/MirrorNode.js +49 -0
  102. package/src/account/AccountAllowanceApproveTransaction.js +11 -11
  103. package/src/account/TokenAllowance.js +5 -2
  104. package/src/account/TokenTransferMap.js +7 -2
  105. package/src/client/Client.js +13 -51
  106. package/src/client/MirrorNetwork.js +18 -0
  107. package/src/client/addressbooks/mainnet.js +1 -1
  108. package/src/client/addressbooks/previewnet.js +1 -1
  109. package/src/client/addressbooks/testnet.js +1 -1
  110. package/src/constants/ClientConstants.js +3 -0
  111. package/src/contract/ContractId.js +2 -10
  112. package/src/network/AddressBookQueryWeb.js +122 -91
  113. package/src/query/MirrorNodeContractQuery.js +2 -1
  114. package/src/token/AbstractTokenTransferTransaction.js +12 -8
  115. package/src/token/AssessedCustomFee.js +8 -5
  116. package/src/token/CustomFixedFee.js +8 -5
  117. package/src/token/PendingAirdropRecord.js +7 -2
  118. package/src/token/TokenAirdropTransaction.js +2 -1
  119. package/src/token/TokenBurnTransaction.js +5 -3
  120. package/src/token/TokenCreateTransaction.js +7 -9
  121. package/src/token/TokenMintTransaction.js +5 -4
  122. package/src/token/TokenTransfer.js +3 -2
  123. package/src/token/TokenWipeTransaction.js +5 -3
  124. package/src/transaction/Transaction.js +63 -0
  125. package/src/util.js +26 -0
@@ -51,8 +51,15 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e
51
51
  * description: string,
52
52
  * stake: number
53
53
  * }>} nodes
54
+ * @property {?{next: ?string}} links - Links object containing pagination information
54
55
  */
55
56
 
57
+ /**
58
+ * Default page size limit for optimal pagination performance
59
+ * @constant {number}
60
+ */
61
+ const DEFAULT_PAGE_SIZE = 25;
62
+
56
63
  /**
57
64
  * Web-compatible query to get a list of Hedera network node addresses from a mirror node.
58
65
  * Uses fetch API instead of gRPC for web environments.
@@ -67,7 +74,7 @@ class AddressBookQueryWeb extends _Query.default {
67
74
  /**
68
75
  * @param {object} props
69
76
  * @param {FileId | string} [props.fileId]
70
- * @param {number} [props.limit]
77
+ * @param {number} [props.limit] - Page size limit (defaults to 25 for optimal performance)
71
78
  */
72
79
  constructor(props = {}) {
73
80
  super();
@@ -215,74 +222,95 @@ class AddressBookQueryWeb extends _Query.default {
215
222
  if (port) {
216
223
  baseUrl = `${baseUrl}:${port}`;
217
224
  }
218
- const url = new URL(`${baseUrl}/api/v1/network/nodes`);
225
+
226
+ // Initialize aggregated results
227
+ this._addresses = [];
228
+ let nextUrl = null;
229
+ let isLastPage = false;
230
+
231
+ // Build initial URL
232
+ const initialUrl = new URL(`${baseUrl}/api/v1/network/nodes`);
219
233
  if (this._fileId != null) {
220
- url.searchParams.append("file.id", this._fileId.toString());
221
- }
222
- if (this._limit != null) {
223
- url.searchParams.append("limit", this._limit.toString());
234
+ initialUrl.searchParams.append("file.id", this._fileId.toString());
224
235
  }
225
- for (let attempt = 0; attempt <= this._maxAttempts; attempt++) {
226
- try {
227
- // eslint-disable-next-line n/no-unsupported-features/node-builtins
228
- const response = await fetch(url.toString(), {
229
- method: "GET",
230
- headers: {
231
- Accept: "application/json"
232
- },
233
- signal: requestTimeout ? AbortSignal.timeout(requestTimeout) : undefined
234
- });
235
- if (!response.ok) {
236
- throw new Error(`HTTP error! status: ${response.status}`);
237
- }
238
236
 
239
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
240
- const data = /** @type {AddressBookQueryWebResponse} */
241
- await response.json();
242
- const nodes = data.nodes || [];
243
-
244
- // eslint-disable-next-line ie11/no-loop-func
245
- this._addresses = nodes.map(node => _NodeAddress.default.fromJSON({
246
- nodeId: node.node_id.toString(),
247
- accountId: node.node_account_id,
248
- addresses: this._handleAddressesFromGrpcProxyEndpoint(node, client),
249
- certHash: node.node_cert_hash,
250
- publicKey: node.public_key,
251
- description: node.description,
252
- stake: node.stake.toString()
253
- }));
254
- const addressBook = new _NodeAddressBook.default({
255
- nodeAddresses: this._addresses
256
- });
257
- resolve(addressBook);
258
- return;
259
- } catch (error) {
260
- console.error("Error in _makeFetchRequest:", error);
261
- const message = error instanceof Error ? error.message : String(error);
262
-
263
- // Check if we should retry
264
- if (attempt < this._maxAttempts && !client.isClientShutDown && this._retryHandler(/** @type {MirrorError | Error | null} */error)) {
265
- const delay = Math.min(250 * 2 ** attempt, this._maxBackoff);
266
- if (this._logger) {
267
- this._logger.debug(`Error getting nodes from mirror for file ${this._fileId != null ? this._fileId.toString() : "UNKNOWN"} during attempt ${attempt + 1}. Waiting ${delay} ms before next attempt: ${message}`);
237
+ // Use the specified limit, or default to DEFAULT_PAGE_SIZE for optimal pagination performance
238
+ const effectiveLimit = this._limit != null ? this._limit : DEFAULT_PAGE_SIZE;
239
+ initialUrl.searchParams.append("limit", effectiveLimit.toString());
240
+
241
+ // Fetch all pages
242
+ while (!isLastPage) {
243
+ const currentUrl = nextUrl ? new URL(nextUrl, baseUrl) : initialUrl;
244
+ for (let attempt = 0; attempt <= this._maxAttempts; attempt++) {
245
+ try {
246
+ // eslint-disable-next-line n/no-unsupported-features/node-builtins
247
+ const response = await fetch(currentUrl.toString(), {
248
+ method: "GET",
249
+ headers: {
250
+ Accept: "application/json"
251
+ },
252
+ signal: requestTimeout ? AbortSignal.timeout(requestTimeout) : undefined
253
+ });
254
+ if (!response.ok) {
255
+ throw new Error(`HTTP error! status: ${response.status}`);
268
256
  }
269
257
 
270
- // Wait before next attempt
271
- // eslint-disable-next-line ie11/no-loop-func
272
- await new Promise(resolve => setTimeout(resolve, delay));
273
- continue;
274
- }
258
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
259
+ const data = /** @type {AddressBookQueryWebResponse} */
260
+ await response.json();
261
+ const nodes = data.nodes || [];
275
262
 
276
- // If we shouldn't retry or have exhausted attempts, reject
277
- const maxAttemptsReached = attempt >= this._maxAttempts;
278
- const errorMessage = maxAttemptsReached ? `Failed to query address book after ${this._maxAttempts + 1} attempts. Last error: ${message}` : `Failed to query address book: ${message}`;
279
- reject(new Error(errorMessage));
280
- return;
263
+ // Aggregate nodes from this page
264
+ const pageNodes = nodes.map(node => _NodeAddress.default.fromJSON({
265
+ nodeId: node.node_id.toString(),
266
+ accountId: node.node_account_id,
267
+ addresses: this._handleAddressesFromGrpcProxyEndpoint(node, client),
268
+ certHash: node.node_cert_hash,
269
+ publicKey: node.public_key,
270
+ description: node.description,
271
+ stake: node.stake.toString()
272
+ }));
273
+ this._addresses.push(...pageNodes);
274
+ nextUrl = data.links?.next || null;
275
+
276
+ // If no more pages, set flag to exit loop
277
+ if (!nextUrl) {
278
+ isLastPage = true;
279
+ }
280
+
281
+ // Move to next page
282
+ break;
283
+ } catch (error) {
284
+ console.error("Error in _makeFetchRequest:", error);
285
+ const message = error instanceof Error ? error.message : String(error);
286
+
287
+ // Check if we should retry
288
+ if (attempt < this._maxAttempts && !client.isClientShutDown && this._retryHandler(/** @type {MirrorError | Error | null} */error)) {
289
+ const delay = Math.min(250 * 2 ** attempt, this._maxBackoff);
290
+ if (this._logger) {
291
+ this._logger.debug(`Error getting nodes from mirror for file ${this._fileId != null ? this._fileId.toString() : "UNKNOWN"} during attempt ${attempt + 1}. Waiting ${delay} ms before next attempt: ${message}`);
292
+ }
293
+
294
+ // Wait before next attempt
295
+ // eslint-disable-next-line ie11/no-loop-func
296
+ await new Promise(resolve => setTimeout(resolve, delay));
297
+ continue;
298
+ }
299
+
300
+ // If we shouldn't retry or have exhausted attempts, reject
301
+ const maxAttemptsReached = attempt >= this._maxAttempts;
302
+ const errorMessage = maxAttemptsReached ? `Failed to query address book after ${this._maxAttempts + 1} attempts. Last error: ${message}` : `Failed to query address book: ${message}`;
303
+ reject(new Error(errorMessage));
304
+ return;
305
+ }
281
306
  }
282
307
  }
283
308
 
284
- // This should never be reached, but just in case
285
- reject(new Error("failed to query address book"));
309
+ // Return the aggregated results
310
+ const addressBook = new _NodeAddressBook.default({
311
+ nodeAddresses: this._addresses
312
+ });
313
+ resolve(addressBook);
286
314
  }
287
315
 
288
316
  /**
@@ -1,39 +1,3 @@
1
- /**
2
- * @typedef {import("../channel/Channel.js").default} Channel
3
- * @typedef {import("../channel/MirrorChannel.js").default} MirrorChannel
4
- * @typedef {import("../channel/MirrorChannel.js").MirrorError} MirrorError
5
- */
6
- /**
7
- * @template {Channel} ChannelT
8
- * @typedef {import("../client/Client.js").default<ChannelT, MirrorChannel>} Client<ChannelT, MirrorChannel>
9
- */
10
- /**
11
- * @typedef {object} EndpointWebResponse
12
- * @property {string} domain_name
13
- * @property {string} ip_address_v4
14
- * @property {number} port
15
- */
16
- /**
17
- * @typedef {object} AddressBookQueryWebResponse
18
- * @property {Array<{
19
- * admin_key: {
20
- * key: string,
21
- * _type: string,
22
- * },
23
- * decline_reward: boolean,
24
- * grpc_proxy_endpoint: EndpointWebResponse,
25
- * file_id: string,
26
- * memo: string,
27
- * public_key: string,
28
- * node_id: number,
29
- * node_account_id: string,
30
- * node_cert_hash: string,
31
- * address: string,
32
- * service_endpoints: EndpointWebResponse[],
33
- * description: string,
34
- * stake: number
35
- * }>} nodes
36
- */
37
1
  /**
38
2
  * Web-compatible query to get a list of Hedera network node addresses from a mirror node.
39
3
  * Uses fetch API instead of gRPC for web environments.
@@ -48,7 +12,7 @@ export default class AddressBookQueryWeb extends Query<NodeAddressBook> {
48
12
  /**
49
13
  * @param {object} props
50
14
  * @param {FileId | string} [props.fileId]
51
- * @param {number} [props.limit]
15
+ * @param {number} [props.limit] - Page size limit (defaults to 25 for optimal performance)
52
16
  */
53
17
  constructor(props?: {
54
18
  fileId?: string | FileId | undefined;
@@ -158,6 +122,12 @@ export type AddressBookQueryWebResponse = {
158
122
  description: string;
159
123
  stake: number;
160
124
  }>;
125
+ /**
126
+ * - Links object containing pagination information
127
+ */
128
+ links: {
129
+ next: string | null;
130
+ } | null;
161
131
  };
162
132
  import NodeAddressBook from "../address_book/NodeAddressBook.js";
163
133
  import Query from "../query/Query.js";
@@ -1,2 +1,2 @@
1
- import t from"../query/Query.js";import e from"../address_book/NodeAddressBook.js";import r from"../file/FileId.js";import{RST_STREAM as s}from"../Executable.js";import i from"../address_book/NodeAddress.js";import{MAINNET as o,WEB_TESTNET as n,WEB_PREVIEWNET as d}from"../constants/ClientConstants.js";class a extends t{constructor(t={}){super(),this._fileId=null,null!=t.fileId&&this.setFileId(t.fileId),this._limit=null,null!=t.limit&&this.setLimit(t.limit),this._retryHandler=t=>{if(null!=t){if(t instanceof Error)return!0;switch(t.code){case 13:return s.test(t.details.toString());case 5:case 8:case 14:case 17:return!0;default:return!1}}return!1},this._addresses=[]}get fileId(){return this._fileId}setFileId(t){return this._fileId="string"==typeof t?r.fromString(t):t.clone(),this}get limit(){return this._limit}setLimit(t){return this._limit=t,this}setMaxAttempts(t){return this._maxAttempts=t,this}setMaxBackoff(t){return this._maxBackoff=t,this}execute(t,e){if(0===t._network._network.size&&!t._timer)throw new Error("The client's network update period is required. Please set it using the setNetworkUpdatePeriod method.");return new Promise((r,s)=>{this._makeFetchRequest(t,r,s,e)})}async _makeFetchRequest(t,r,s,o){const{port:n,address:d}=t._mirrorNetwork.getNextMirrorNode().address;let a=`${d.includes("127.0.0.1")||d.includes("localhost")?"http":"https"}://${d}`;n&&(a=`${a}:${n}`);const l=new URL(`${a}/api/v1/network/nodes`);null!=this._fileId&&l.searchParams.append("file.id",this._fileId.toString()),null!=this._limit&&l.searchParams.append("limit",this._limit.toString());for(let n=0;n<=this._maxAttempts;n++)try{const s=await fetch(l.toString(),{method:"GET",headers:{Accept:"application/json"},signal:o?AbortSignal.timeout(o):void 0});if(!s.ok)throw new Error(`HTTP error! status: ${s.status}`);const n=(await s.json()).nodes||[];this._addresses=n.map(e=>i.fromJSON({nodeId:e.node_id.toString(),accountId:e.node_account_id,addresses:this._handleAddressesFromGrpcProxyEndpoint(e,t),certHash:e.node_cert_hash,publicKey:e.public_key,description:e.description,stake:e.stake.toString()}));return void r(new e({nodeAddresses:this._addresses}))}catch(e){console.error("Error in _makeFetchRequest:",e);const r=e instanceof Error?e.message:String(e);if(n<this._maxAttempts&&!t.isClientShutDown&&this._retryHandler(e)){const t=Math.min(250*2**n,this._maxBackoff);this._logger&&this._logger.debug(`Error getting nodes from mirror for file ${null!=this._fileId?this._fileId.toString():"UNKNOWN"} during attempt ${n+1}. Waiting ${t} ms before next attempt: ${r}`),await new Promise(e=>setTimeout(e,t));continue}const i=n>=this._maxAttempts?`Failed to query address book after ${this._maxAttempts+1} attempts. Last error: ${r}`:`Failed to query address book: ${r}`;return void s(new Error(i))}s(new Error("failed to query address book"))}_handleAddressesFromGrpcProxyEndpoint(t,e){const r=t.grpc_proxy_endpoint;if(r&&r.domain_name&&r.port)return[{address:r.domain_name,port:r.port.toString()}];let s;const i=e._network.ledgerId;if(i&&i.isMainnet())s=o;else if(i&&i.isTestnet())s=n;else{if(!i||!i.isPreviewnet())return[];s=d}const a=t.node_account_id;for(const[t,e]of Object.entries(s))if(e.toString()===a){const[e,r]=t.split(":");return[{address:e,port:r}]}return[]}}export{a as default};
1
+ import t from"../query/Query.js";import e from"../address_book/NodeAddressBook.js";import s from"../file/FileId.js";import{RST_STREAM as r}from"../Executable.js";import i from"../address_book/NodeAddress.js";import{MAINNET as o,WEB_TESTNET as n,WEB_PREVIEWNET as d}from"../constants/ClientConstants.js";class a extends t{constructor(t={}){super(),this._fileId=null,null!=t.fileId&&this.setFileId(t.fileId),this._limit=null,null!=t.limit&&this.setLimit(t.limit),this._retryHandler=t=>{if(null!=t){if(t instanceof Error)return!0;switch(t.code){case 13:return r.test(t.details.toString());case 5:case 8:case 14:case 17:return!0;default:return!1}}return!1},this._addresses=[]}get fileId(){return this._fileId}setFileId(t){return this._fileId="string"==typeof t?s.fromString(t):t.clone(),this}get limit(){return this._limit}setLimit(t){return this._limit=t,this}setMaxAttempts(t){return this._maxAttempts=t,this}setMaxBackoff(t){return this._maxBackoff=t,this}execute(t,e){if(0===t._network._network.size&&!t._timer)throw new Error("The client's network update period is required. Please set it using the setNetworkUpdatePeriod method.");return new Promise((s,r)=>{this._makeFetchRequest(t,s,r,e)})}async _makeFetchRequest(t,s,r,o){const{port:n,address:d}=t._mirrorNetwork.getNextMirrorNode().address;let a=`${d.includes("127.0.0.1")||d.includes("localhost")?"http":"https"}://${d}`;n&&(a=`${a}:${n}`),this._addresses=[];let l=null,c=!1;const m=new URL(`${a}/api/v1/network/nodes`);null!=this._fileId&&m.searchParams.append("file.id",this._fileId.toString());const h=null!=this._limit?this._limit:25;for(m.searchParams.append("limit",h.toString());!c;){const e=l?new URL(l,a):m;for(let s=0;s<=this._maxAttempts;s++)try{const s=await fetch(e.toString(),{method:"GET",headers:{Accept:"application/json"},signal:o?AbortSignal.timeout(o):void 0});if(!s.ok)throw new Error(`HTTP error! status: ${s.status}`);const r=await s.json(),n=(r.nodes||[]).map(e=>i.fromJSON({nodeId:e.node_id.toString(),accountId:e.node_account_id,addresses:this._handleAddressesFromGrpcProxyEndpoint(e,t),certHash:e.node_cert_hash,publicKey:e.public_key,description:e.description,stake:e.stake.toString()}));this._addresses.push(...n),l=r.links?.next||null,l||(c=!0);break}catch(e){console.error("Error in _makeFetchRequest:",e);const i=e instanceof Error?e.message:String(e);if(s<this._maxAttempts&&!t.isClientShutDown&&this._retryHandler(e)){const t=Math.min(250*2**s,this._maxBackoff);this._logger&&this._logger.debug(`Error getting nodes from mirror for file ${null!=this._fileId?this._fileId.toString():"UNKNOWN"} during attempt ${s+1}. Waiting ${t} ms before next attempt: ${i}`),await new Promise(e=>setTimeout(e,t));continue}const o=s>=this._maxAttempts?`Failed to query address book after ${this._maxAttempts+1} attempts. Last error: ${i}`:`Failed to query address book: ${i}`;return void r(new Error(o))}}s(new e({nodeAddresses:this._addresses}))}_handleAddressesFromGrpcProxyEndpoint(t,e){const s=t.grpc_proxy_endpoint;if(s&&s.domain_name&&s.port)return[{address:s.domain_name,port:s.port.toString()}];let r;const i=e._network.ledgerId;if(i&&i.isMainnet())r=o;else if(i&&i.isTestnet())r=n;else{if(!i||!i.isPreviewnet())return[];r=d}const a=t.node_account_id;for(const[t,e]of Object.entries(r))if(e.toString()===a){const[e,s]=t.split(":");return[{address:e,port:s}]}return[]}}export{a as default};
2
2
  //# sourceMappingURL=AddressBookQueryWeb.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AddressBookQueryWeb.js","sources":["../../src/network/AddressBookQueryWeb.js"],"sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\nimport Query from \"../query/Query.js\";\nimport NodeAddressBook from \"../address_book/NodeAddressBook.js\";\nimport FileId from \"../file/FileId.js\";\nimport { RST_STREAM } from \"../Executable.js\";\nimport NodeAddress from \"../address_book/NodeAddress.js\";\nimport {\n MAINNET,\n WEB_TESTNET,\n WEB_PREVIEWNET,\n} from \"../constants/ClientConstants.js\";\n\n/**\n * @typedef {import(\"../channel/Channel.js\").default} Channel\n * @typedef {import(\"../channel/MirrorChannel.js\").default} MirrorChannel\n * @typedef {import(\"../channel/MirrorChannel.js\").MirrorError} MirrorError\n */\n\n/**\n * @template {Channel} ChannelT\n * @typedef {import(\"../client/Client.js\").default<ChannelT, MirrorChannel>} Client<ChannelT, MirrorChannel>\n */\n\n/**\n * @typedef {object} EndpointWebResponse\n * @property {string} domain_name\n * @property {string} ip_address_v4\n * @property {number} port\n */\n\n/**\n * @typedef {object} AddressBookQueryWebResponse\n * @property {Array<{\n * admin_key: {\n * key: string,\n * _type: string,\n * },\n * decline_reward: boolean,\n * grpc_proxy_endpoint: EndpointWebResponse,\n * file_id: string,\n * memo: string,\n * public_key: string,\n * node_id: number,\n * node_account_id: string,\n * node_cert_hash: string,\n * address: string,\n * service_endpoints: EndpointWebResponse[],\n * description: string,\n * stake: number\n * }>} nodes\n */\n\n/**\n * Web-compatible query to get a list of Hedera network node addresses from a mirror node.\n * Uses fetch API instead of gRPC for web environments.\n *\n * This query can be used to retrieve node addresses either from a specific file ID\n * or from the most recent address book if no file ID is specified. The response\n * contains node metadata including IP addresses and ports for both node and mirror\n * node services.\n * @augments {Query<NodeAddressBook>}\n */\nexport default class AddressBookQueryWeb extends Query {\n /**\n * @param {object} props\n * @param {FileId | string} [props.fileId]\n * @param {number} [props.limit]\n */\n constructor(props = {}) {\n super();\n\n /**\n * @private\n * @type {?FileId}\n */\n this._fileId = null;\n if (props.fileId != null) {\n this.setFileId(props.fileId);\n }\n\n /**\n * Page limit for the query\n * @private\n * @type {?number}\n */\n this._limit = null;\n if (props.limit != null) {\n this.setLimit(props.limit);\n }\n\n /**\n * @private\n * @type {(error: MirrorError | Error | null) => boolean}\n */\n this._retryHandler = (error) => {\n if (error != null) {\n if (error instanceof Error) {\n // Retry on all errors which are not `MirrorError` because they're\n // likely lower level HTTP errors\n return true;\n } else {\n // Retry on `NOT_FOUND`, `RESOURCE_EXHAUSTED`, `UNAVAILABLE`, and conditionally on `INTERNAL`\n // if the message matches the right regex.\n switch (error.code) {\n // INTERNAL\n // eslint-disable-next-line no-fallthrough\n case 13:\n return RST_STREAM.test(error.details.toString());\n // NOT_FOUND\n // eslint-disable-next-line no-fallthrough\n case 5:\n // RESOURCE_EXHAUSTED\n // eslint-disable-next-line no-fallthrough\n case 8:\n // UNAVAILABLE\n // eslint-disable-next-line no-fallthrough\n case 14:\n case 17:\n return true;\n default:\n return false;\n }\n }\n }\n\n return false;\n };\n\n /** @type {NodeAddress[]} */\n this._addresses = [];\n }\n\n /**\n * @returns {?FileId}\n */\n get fileId() {\n return this._fileId;\n }\n\n /**\n * @param {FileId | string} fileId\n * @returns {AddressBookQueryWeb}\n */\n setFileId(fileId) {\n this._fileId =\n typeof fileId === \"string\"\n ? FileId.fromString(fileId)\n : fileId.clone();\n\n return this;\n }\n\n /**\n * Page limit for the query\n * @returns {?number}\n */\n get limit() {\n return this._limit;\n }\n\n /**\n * Set the page limit for the query\n * @param {number} limit\n * @returns {AddressBookQueryWeb}\n */\n setLimit(limit) {\n this._limit = limit;\n\n return this;\n }\n\n /**\n * @param {number} attempts\n * @returns {this}\n */\n setMaxAttempts(attempts) {\n this._maxAttempts = attempts;\n return this;\n }\n\n /**\n * @param {number} backoff\n * @returns {this}\n */\n setMaxBackoff(backoff) {\n this._maxBackoff = backoff;\n return this;\n }\n\n /**\n * @param {Client<Channel>} client\n * @param {number=} requestTimeout\n * @returns {Promise<NodeAddressBook>}\n */\n execute(client, requestTimeout) {\n // Extra validation when initializing the client with only a mirror network\n if (client._network._network.size === 0 && !client._timer) {\n throw new Error(\n \"The client's network update period is required. Please set it using the setNetworkUpdatePeriod method.\",\n );\n }\n\n return new Promise((resolve, reject) => {\n void this._makeFetchRequest(\n client,\n resolve,\n reject,\n requestTimeout,\n );\n });\n }\n\n /**\n * @private\n * @param {Client<Channel>} client\n * @param {(value: NodeAddressBook) => void} resolve\n * @param {(error: Error) => void} reject\n * @param {number=} requestTimeout\n */\n async _makeFetchRequest(client, resolve, reject, requestTimeout) {\n const { port, address } =\n client._mirrorNetwork.getNextMirrorNode().address;\n\n let baseUrl = `${\n address.includes(\"127.0.0.1\") || address.includes(\"localhost\")\n ? \"http\"\n : \"https\"\n }://${address}`;\n\n if (port) {\n baseUrl = `${baseUrl}:${port}`;\n }\n\n const url = new URL(`${baseUrl}/api/v1/network/nodes`);\n\n if (this._fileId != null) {\n url.searchParams.append(\"file.id\", this._fileId.toString());\n }\n if (this._limit != null) {\n url.searchParams.append(\"limit\", this._limit.toString());\n }\n\n for (let attempt = 0; attempt <= this._maxAttempts; attempt++) {\n try {\n // eslint-disable-next-line n/no-unsupported-features/node-builtins\n const response = await fetch(url.toString(), {\n method: \"GET\",\n headers: {\n Accept: \"application/json\",\n },\n signal: requestTimeout\n ? AbortSignal.timeout(requestTimeout)\n : undefined,\n });\n\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const data = /** @type {AddressBookQueryWebResponse} */ (\n await response.json()\n );\n\n const nodes = data.nodes || [];\n\n // eslint-disable-next-line ie11/no-loop-func\n this._addresses = nodes.map((node) =>\n NodeAddress.fromJSON({\n nodeId: node.node_id.toString(),\n accountId: node.node_account_id,\n addresses: this._handleAddressesFromGrpcProxyEndpoint(\n node,\n client,\n ),\n certHash: node.node_cert_hash,\n publicKey: node.public_key,\n description: node.description,\n stake: node.stake.toString(),\n }),\n );\n\n const addressBook = new NodeAddressBook({\n nodeAddresses: this._addresses,\n });\n\n resolve(addressBook);\n return;\n } catch (error) {\n console.error(\"Error in _makeFetchRequest:\", error);\n const message =\n error instanceof Error ? error.message : String(error);\n\n // Check if we should retry\n if (\n attempt < this._maxAttempts &&\n !client.isClientShutDown &&\n this._retryHandler(\n /** @type {MirrorError | Error | null} */ (error),\n )\n ) {\n const delay = Math.min(\n 250 * 2 ** attempt,\n this._maxBackoff,\n );\n\n if (this._logger) {\n this._logger.debug(\n `Error getting nodes from mirror for file ${\n this._fileId != null\n ? this._fileId.toString()\n : \"UNKNOWN\"\n } during attempt ${\n attempt + 1\n }. Waiting ${delay} ms before next attempt: ${message}`,\n );\n }\n\n // Wait before next attempt\n // eslint-disable-next-line ie11/no-loop-func\n await new Promise((resolve) => setTimeout(resolve, delay));\n continue;\n }\n\n // If we shouldn't retry or have exhausted attempts, reject\n const maxAttemptsReached = attempt >= this._maxAttempts;\n const errorMessage = maxAttemptsReached\n ? `Failed to query address book after ${\n this._maxAttempts + 1\n } attempts. Last error: ${message}`\n : `Failed to query address book: ${message}`;\n reject(new Error(errorMessage));\n return;\n }\n }\n\n // This should never be reached, but just in case\n reject(new Error(\"failed to query address book\"));\n }\n\n /**\n * Handles the grpc_proxy_endpoint fallback logic for a node.\n * @param {AddressBookQueryWebResponse['nodes'][number]} node - The node object from the mirror node response.\n * @param {Client<Channel>} client - The client instance.\n * @returns {Array<{address: string, port: string}>}\n */\n _handleAddressesFromGrpcProxyEndpoint(node, client) {\n const grpcProxyEndpoint = node.grpc_proxy_endpoint;\n\n if (\n grpcProxyEndpoint &&\n grpcProxyEndpoint.domain_name &&\n grpcProxyEndpoint.port\n ) {\n return [\n {\n address: grpcProxyEndpoint.domain_name,\n port: grpcProxyEndpoint.port.toString(),\n },\n ];\n }\n\n let networkConstant;\n const ledgerId = client._network.ledgerId;\n\n if (ledgerId && ledgerId.isMainnet()) {\n networkConstant = MAINNET;\n } else if (ledgerId && ledgerId.isTestnet()) {\n networkConstant = WEB_TESTNET;\n } else if (ledgerId && ledgerId.isPreviewnet()) {\n networkConstant = WEB_PREVIEWNET;\n } else {\n return [];\n }\n\n const nodeAccountId = node.node_account_id;\n\n for (const [address, accountIdObj] of Object.entries(networkConstant)) {\n if (accountIdObj.toString() === nodeAccountId) {\n const [domain_name, port] = address.split(\":\");\n\n return [\n {\n address: domain_name,\n port,\n },\n ];\n }\n }\n\n return [];\n }\n}\n"],"names":["AddressBookQueryWeb","Query","constructor","props","super","this","_fileId","fileId","setFileId","_limit","limit","setLimit","_retryHandler","error","Error","code","RST_STREAM","test","details","toString","_addresses","FileId","fromString","clone","setMaxAttempts","attempts","_maxAttempts","setMaxBackoff","backoff","_maxBackoff","execute","client","requestTimeout","_network","size","_timer","Promise","resolve","reject","_makeFetchRequest","port","address","_mirrorNetwork","getNextMirrorNode","baseUrl","includes","url","URL","searchParams","append","attempt","response","fetch","method","headers","Accept","signal","AbortSignal","timeout","undefined","ok","status","nodes","json","map","node","NodeAddress","fromJSON","nodeId","node_id","accountId","node_account_id","addresses","_handleAddressesFromGrpcProxyEndpoint","certHash","node_cert_hash","publicKey","public_key","description","stake","NodeAddressBook","nodeAddresses","console","message","String","isClientShutDown","delay","Math","min","_logger","debug","setTimeout","errorMessage","grpcProxyEndpoint","grpc_proxy_endpoint","domain_name","networkConstant","ledgerId","isMainnet","MAINNET","isTestnet","WEB_TESTNET","isPreviewnet","WEB_PREVIEWNET","nodeAccountId","accountIdObj","Object","entries","split"],"mappings":"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"}
1
+ {"version":3,"file":"AddressBookQueryWeb.js","sources":["../../src/network/AddressBookQueryWeb.js"],"sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\nimport Query from \"../query/Query.js\";\nimport NodeAddressBook from \"../address_book/NodeAddressBook.js\";\nimport FileId from \"../file/FileId.js\";\nimport { RST_STREAM } from \"../Executable.js\";\nimport NodeAddress from \"../address_book/NodeAddress.js\";\nimport {\n MAINNET,\n WEB_TESTNET,\n WEB_PREVIEWNET,\n} from \"../constants/ClientConstants.js\";\n\n/**\n * @typedef {import(\"../channel/Channel.js\").default} Channel\n * @typedef {import(\"../channel/MirrorChannel.js\").default} MirrorChannel\n * @typedef {import(\"../channel/MirrorChannel.js\").MirrorError} MirrorError\n */\n\n/**\n * @template {Channel} ChannelT\n * @typedef {import(\"../client/Client.js\").default<ChannelT, MirrorChannel>} Client<ChannelT, MirrorChannel>\n */\n\n/**\n * @typedef {object} EndpointWebResponse\n * @property {string} domain_name\n * @property {string} ip_address_v4\n * @property {number} port\n */\n\n/**\n * @typedef {object} AddressBookQueryWebResponse\n * @property {Array<{\n * admin_key: {\n * key: string,\n * _type: string,\n * },\n * decline_reward: boolean,\n * grpc_proxy_endpoint: EndpointWebResponse,\n * file_id: string,\n * memo: string,\n * public_key: string,\n * node_id: number,\n * node_account_id: string,\n * node_cert_hash: string,\n * address: string,\n * service_endpoints: EndpointWebResponse[],\n * description: string,\n * stake: number\n * }>} nodes\n * @property {?{next: ?string}} links - Links object containing pagination information\n */\n\n/**\n * Default page size limit for optimal pagination performance\n * @constant {number}\n */\nconst DEFAULT_PAGE_SIZE = 25;\n\n/**\n * Web-compatible query to get a list of Hedera network node addresses from a mirror node.\n * Uses fetch API instead of gRPC for web environments.\n *\n * This query can be used to retrieve node addresses either from a specific file ID\n * or from the most recent address book if no file ID is specified. The response\n * contains node metadata including IP addresses and ports for both node and mirror\n * node services.\n * @augments {Query<NodeAddressBook>}\n */\nexport default class AddressBookQueryWeb extends Query {\n /**\n * @param {object} props\n * @param {FileId | string} [props.fileId]\n * @param {number} [props.limit] - Page size limit (defaults to 25 for optimal performance)\n */\n constructor(props = {}) {\n super();\n\n /**\n * @private\n * @type {?FileId}\n */\n this._fileId = null;\n if (props.fileId != null) {\n this.setFileId(props.fileId);\n }\n\n /**\n * Page limit for the query\n * @private\n * @type {?number}\n */\n this._limit = null;\n if (props.limit != null) {\n this.setLimit(props.limit);\n }\n\n /**\n * @private\n * @type {(error: MirrorError | Error | null) => boolean}\n */\n this._retryHandler = (error) => {\n if (error != null) {\n if (error instanceof Error) {\n // Retry on all errors which are not `MirrorError` because they're\n // likely lower level HTTP errors\n return true;\n } else {\n // Retry on `NOT_FOUND`, `RESOURCE_EXHAUSTED`, `UNAVAILABLE`, and conditionally on `INTERNAL`\n // if the message matches the right regex.\n switch (error.code) {\n // INTERNAL\n // eslint-disable-next-line no-fallthrough\n case 13:\n return RST_STREAM.test(error.details.toString());\n // NOT_FOUND\n // eslint-disable-next-line no-fallthrough\n case 5:\n // RESOURCE_EXHAUSTED\n // eslint-disable-next-line no-fallthrough\n case 8:\n // UNAVAILABLE\n // eslint-disable-next-line no-fallthrough\n case 14:\n case 17:\n return true;\n default:\n return false;\n }\n }\n }\n\n return false;\n };\n\n /** @type {NodeAddress[]} */\n this._addresses = [];\n }\n\n /**\n * @returns {?FileId}\n */\n get fileId() {\n return this._fileId;\n }\n\n /**\n * @param {FileId | string} fileId\n * @returns {AddressBookQueryWeb}\n */\n setFileId(fileId) {\n this._fileId =\n typeof fileId === \"string\"\n ? FileId.fromString(fileId)\n : fileId.clone();\n\n return this;\n }\n\n /**\n * Page limit for the query\n * @returns {?number}\n */\n get limit() {\n return this._limit;\n }\n\n /**\n * Set the page limit for the query\n * @param {number} limit\n * @returns {AddressBookQueryWeb}\n */\n setLimit(limit) {\n this._limit = limit;\n\n return this;\n }\n\n /**\n * @param {number} attempts\n * @returns {this}\n */\n setMaxAttempts(attempts) {\n this._maxAttempts = attempts;\n return this;\n }\n\n /**\n * @param {number} backoff\n * @returns {this}\n */\n setMaxBackoff(backoff) {\n this._maxBackoff = backoff;\n return this;\n }\n\n /**\n * @param {Client<Channel>} client\n * @param {number=} requestTimeout\n * @returns {Promise<NodeAddressBook>}\n */\n execute(client, requestTimeout) {\n // Extra validation when initializing the client with only a mirror network\n if (client._network._network.size === 0 && !client._timer) {\n throw new Error(\n \"The client's network update period is required. Please set it using the setNetworkUpdatePeriod method.\",\n );\n }\n\n return new Promise((resolve, reject) => {\n void this._makeFetchRequest(\n client,\n resolve,\n reject,\n requestTimeout,\n );\n });\n }\n\n /**\n * @private\n * @param {Client<Channel>} client\n * @param {(value: NodeAddressBook) => void} resolve\n * @param {(error: Error) => void} reject\n * @param {number=} requestTimeout\n */\n async _makeFetchRequest(client, resolve, reject, requestTimeout) {\n const { port, address } =\n client._mirrorNetwork.getNextMirrorNode().address;\n\n let baseUrl = `${\n address.includes(\"127.0.0.1\") || address.includes(\"localhost\")\n ? \"http\"\n : \"https\"\n }://${address}`;\n\n if (port) {\n baseUrl = `${baseUrl}:${port}`;\n }\n\n // Initialize aggregated results\n this._addresses = [];\n let nextUrl = null;\n let isLastPage = false;\n\n // Build initial URL\n const initialUrl = new URL(`${baseUrl}/api/v1/network/nodes`);\n if (this._fileId != null) {\n initialUrl.searchParams.append(\"file.id\", this._fileId.toString());\n }\n\n // Use the specified limit, or default to DEFAULT_PAGE_SIZE for optimal pagination performance\n const effectiveLimit =\n this._limit != null ? this._limit : DEFAULT_PAGE_SIZE;\n initialUrl.searchParams.append(\"limit\", effectiveLimit.toString());\n\n // Fetch all pages\n while (!isLastPage) {\n const currentUrl = nextUrl ? new URL(nextUrl, baseUrl) : initialUrl;\n\n for (let attempt = 0; attempt <= this._maxAttempts; attempt++) {\n try {\n // eslint-disable-next-line n/no-unsupported-features/node-builtins\n const response = await fetch(currentUrl.toString(), {\n method: \"GET\",\n headers: {\n Accept: \"application/json\",\n },\n signal: requestTimeout\n ? AbortSignal.timeout(requestTimeout)\n : undefined,\n });\n\n if (!response.ok) {\n throw new Error(\n `HTTP error! status: ${response.status}`,\n );\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const data = /** @type {AddressBookQueryWebResponse} */ (\n await response.json()\n );\n\n const nodes = data.nodes || [];\n\n // Aggregate nodes from this page\n const pageNodes = nodes.map((node) =>\n NodeAddress.fromJSON({\n nodeId: node.node_id.toString(),\n accountId: node.node_account_id,\n addresses:\n this._handleAddressesFromGrpcProxyEndpoint(\n node,\n client,\n ),\n certHash: node.node_cert_hash,\n publicKey: node.public_key,\n description: node.description,\n stake: node.stake.toString(),\n }),\n );\n\n this._addresses.push(...pageNodes);\n nextUrl = data.links?.next || null;\n\n // If no more pages, set flag to exit loop\n if (!nextUrl) {\n isLastPage = true;\n }\n\n // Move to next page\n break;\n } catch (error) {\n console.error(\"Error in _makeFetchRequest:\", error);\n const message =\n error instanceof Error ? error.message : String(error);\n\n // Check if we should retry\n if (\n attempt < this._maxAttempts &&\n !client.isClientShutDown &&\n this._retryHandler(\n /** @type {MirrorError | Error | null} */ (error),\n )\n ) {\n const delay = Math.min(\n 250 * 2 ** attempt,\n this._maxBackoff,\n );\n\n if (this._logger) {\n this._logger.debug(\n `Error getting nodes from mirror for file ${\n this._fileId != null\n ? this._fileId.toString()\n : \"UNKNOWN\"\n } during attempt ${\n attempt + 1\n }. Waiting ${delay} ms before next attempt: ${message}`,\n );\n }\n\n // Wait before next attempt\n // eslint-disable-next-line ie11/no-loop-func\n await new Promise((resolve) =>\n setTimeout(resolve, delay),\n );\n continue;\n }\n\n // If we shouldn't retry or have exhausted attempts, reject\n const maxAttemptsReached = attempt >= this._maxAttempts;\n const errorMessage = maxAttemptsReached\n ? `Failed to query address book after ${\n this._maxAttempts + 1\n } attempts. Last error: ${message}`\n : `Failed to query address book: ${message}`;\n reject(new Error(errorMessage));\n return;\n }\n }\n }\n\n // Return the aggregated results\n const addressBook = new NodeAddressBook({\n nodeAddresses: this._addresses,\n });\n resolve(addressBook);\n }\n\n /**\n * Handles the grpc_proxy_endpoint fallback logic for a node.\n * @param {AddressBookQueryWebResponse['nodes'][number]} node - The node object from the mirror node response.\n * @param {Client<Channel>} client - The client instance.\n * @returns {Array<{address: string, port: string}>}\n */\n _handleAddressesFromGrpcProxyEndpoint(node, client) {\n const grpcProxyEndpoint = node.grpc_proxy_endpoint;\n\n if (\n grpcProxyEndpoint &&\n grpcProxyEndpoint.domain_name &&\n grpcProxyEndpoint.port\n ) {\n return [\n {\n address: grpcProxyEndpoint.domain_name,\n port: grpcProxyEndpoint.port.toString(),\n },\n ];\n }\n\n let networkConstant;\n const ledgerId = client._network.ledgerId;\n\n if (ledgerId && ledgerId.isMainnet()) {\n networkConstant = MAINNET;\n } else if (ledgerId && ledgerId.isTestnet()) {\n networkConstant = WEB_TESTNET;\n } else if (ledgerId && ledgerId.isPreviewnet()) {\n networkConstant = WEB_PREVIEWNET;\n } else {\n return [];\n }\n\n const nodeAccountId = node.node_account_id;\n\n for (const [address, accountIdObj] of Object.entries(networkConstant)) {\n if (accountIdObj.toString() === nodeAccountId) {\n const [domain_name, port] = address.split(\":\");\n\n return [\n {\n address: domain_name,\n port,\n },\n ];\n }\n }\n\n return [];\n }\n}\n"],"names":["AddressBookQueryWeb","Query","constructor","props","super","this","_fileId","fileId","setFileId","_limit","limit","setLimit","_retryHandler","error","Error","code","RST_STREAM","test","details","toString","_addresses","FileId","fromString","clone","setMaxAttempts","attempts","_maxAttempts","setMaxBackoff","backoff","_maxBackoff","execute","client","requestTimeout","_network","size","_timer","Promise","resolve","reject","_makeFetchRequest","port","address","_mirrorNetwork","getNextMirrorNode","baseUrl","includes","nextUrl","isLastPage","initialUrl","URL","searchParams","append","effectiveLimit","currentUrl","attempt","response","fetch","method","headers","Accept","signal","AbortSignal","timeout","undefined","ok","status","data","json","pageNodes","nodes","map","node","NodeAddress","fromJSON","nodeId","node_id","accountId","node_account_id","addresses","_handleAddressesFromGrpcProxyEndpoint","certHash","node_cert_hash","publicKey","public_key","description","stake","push","links","next","console","message","String","isClientShutDown","delay","Math","min","_logger","debug","setTimeout","errorMessage","NodeAddressBook","nodeAddresses","grpcProxyEndpoint","grpc_proxy_endpoint","domain_name","networkConstant","ledgerId","isMainnet","MAINNET","isTestnet","WEB_TESTNET","isPreviewnet","WEB_PREVIEWNET","nodeAccountId","accountIdObj","Object","entries","split"],"mappings":"+SAsEe,MAAMA,UAA4BC,EAM7C,WAAAC,CAAYC,EAAQ,IAChBC,QAMAC,KAAKC,QAAU,KACK,MAAhBH,EAAMI,QACNF,KAAKG,UAAUL,EAAMI,QAQzBF,KAAKI,OAAS,KACK,MAAfN,EAAMO,OACNL,KAAKM,SAASR,EAAMO,OAOxBL,KAAKO,cAAiBC,IAClB,GAAa,MAATA,EAAe,CACf,GAAIA,aAAiBC,MAGjB,OAAO,EAIP,OAAQD,EAAME,MAGV,KAAK,GACD,OAAOC,EAAWC,KAAKJ,EAAMK,QAAQC,YAGzC,KAAK,EAGL,KAAK,EAGL,KAAK,GACL,KAAK,GACD,OAAO,EACX,QACI,OAAO,EAGnC,CAEY,OAAO,GAIXd,KAAKe,WAAa,EAC1B,CAKI,UAAIb,GACA,OAAOF,KAAKC,OACpB,CAMI,SAAAE,CAAUD,GAMN,OALAF,KAAKC,QACiB,iBAAXC,EACDc,EAAOC,WAAWf,GAClBA,EAAOgB,QAEVlB,IACf,CAMI,SAAIK,GACA,OAAOL,KAAKI,MACpB,CAOI,QAAAE,CAASD,GAGL,OAFAL,KAAKI,OAASC,EAEPL,IACf,CAMI,cAAAmB,CAAeC,GAEX,OADApB,KAAKqB,aAAeD,EACbpB,IACf,CAMI,aAAAsB,CAAcC,GAEV,OADAvB,KAAKwB,YAAcD,EACZvB,IACf,CAOI,OAAAyB,CAAQC,EAAQC,GAEZ,GAAsC,IAAlCD,EAAOE,SAASA,SAASC,OAAeH,EAAOI,OAC/C,MAAM,IAAIrB,MACN,0GAIR,OAAO,IAAIsB,QAAQ,CAACC,EAASC,KACpBjC,KAAKkC,kBACNR,EACAM,EACAC,EACAN,IAGhB,CASI,uBAAMO,CAAkBR,EAAQM,EAASC,EAAQN,GAC7C,MAAMQ,KAAEA,EAAIC,QAAEA,GACVV,EAAOW,eAAeC,oBAAoBF,QAE9C,IAAIG,EAAU,GACVH,EAAQI,SAAS,cAAgBJ,EAAQI,SAAS,aAC5C,OACA,aACJJ,IAEFD,IACAI,EAAU,GAAGA,KAAWJ,KAI5BnC,KAAKe,WAAa,GAClB,IAAI0B,EAAU,KACVC,GAAa,EAGjB,MAAMC,EAAa,IAAIC,IAAI,GAAGL,0BACV,MAAhBvC,KAAKC,SACL0C,EAAWE,aAAaC,OAAO,UAAW9C,KAAKC,QAAQa,YAI3D,MAAMiC,EACa,MAAf/C,KAAKI,OAAiBJ,KAAKI,OApMb,GAwMlB,IAHAuC,EAAWE,aAAaC,OAAO,QAASC,EAAejC,aAG/C4B,GAAY,CAChB,MAAMM,EAAaP,EAAU,IAAIG,IAAIH,EAASF,GAAWI,EAEzD,IAAK,IAAIM,EAAU,EAAGA,GAAWjD,KAAKqB,aAAc4B,IAChD,IAEI,MAAMC,QAAiBC,MAAMH,EAAWlC,WAAY,CAChDsC,OAAQ,MACRC,QAAS,CACLC,OAAQ,oBAEZC,OAAQ5B,EACF6B,YAAYC,QAAQ9B,QACpB+B,IAGV,IAAKR,EAASS,GACV,MAAM,IAAIlD,MACN,uBAAuByC,EAASU,UAKxC,MAAMC,QACIX,EAASY,OAMbC,GAHQF,EAAKG,OAAS,IAGJC,IAAKC,GACzBC,EAAYC,SAAS,CACjBC,OAAQH,EAAKI,QAAQxD,WACrByD,UAAWL,EAAKM,gBAChBC,UACIzE,KAAK0E,sCACDR,EACAxC,GAERiD,SAAUT,EAAKU,eACfC,UAAWX,EAAKY,WAChBC,YAAab,EAAKa,YAClBC,MAAOd,EAAKc,MAAMlE,cAI1Bd,KAAKe,WAAWkE,QAAQlB,GACxBtB,EAAUoB,EAAKqB,OAAOC,MAAQ,KAGzB1C,IACDC,GAAa,GAIjB,KACH,CAAC,MAAOlC,GACL4E,QAAQ5E,MAAM,8BAA+BA,GAC7C,MAAM6E,EACF7E,aAAiBC,MAAQD,EAAM6E,QAAUC,OAAO9E,GAGpD,GACIyC,EAAUjD,KAAKqB,eACdK,EAAO6D,kBACRvF,KAAKO,cAC7B,GAEsB,CACE,MAAMiF,EAAQC,KAAKC,IACf,IAAM,GAAKzC,EACXjD,KAAKwB,aAGLxB,KAAK2F,SACL3F,KAAK2F,QAAQC,MACT,4CACoB,MAAhB5F,KAAKC,QACCD,KAAKC,QAAQa,WACb,4BAENmC,EAAU,cACDuC,6BAAiCH,WAMhD,IAAItD,QAASC,GACf6D,WAAW7D,EAASwD,IAExB,QACxB,CAGoB,MACMM,EADqB7C,GAAWjD,KAAKqB,aAErC,sCACIrB,KAAKqB,aAAe,2BACEgE,IAC1B,iCAAiCA,IAEvC,YADApD,EAAO,IAAIxB,MAAMqF,GAErC,CAEA,CAMQ9D,EAHoB,IAAI+D,EAAgB,CACpCC,cAAehG,KAAKe,aAGhC,CAQI,qCAAA2D,CAAsCR,EAAMxC,GACxC,MAAMuE,EAAoB/B,EAAKgC,oBAE/B,GACID,GACAA,EAAkBE,aAClBF,EAAkB9D,KAElB,MAAO,CACH,CACIC,QAAS6D,EAAkBE,YAC3BhE,KAAM8D,EAAkB9D,KAAKrB,aAKzC,IAAIsF,EACJ,MAAMC,EAAW3E,EAAOE,SAASyE,SAEjC,GAAIA,GAAYA,EAASC,YACrBF,EAAkBG,OACf,GAAIF,GAAYA,EAASG,YAC5BJ,EAAkBK,MACf,KAAIJ,IAAYA,EAASK,eAG5B,MAAO,GAFPN,EAAkBO,CAG9B,CAEQ,MAAMC,EAAgB1C,EAAKM,gBAE3B,IAAK,MAAOpC,EAASyE,KAAiBC,OAAOC,QAAQX,GACjD,GAAIS,EAAa/F,aAAe8F,EAAe,CAC3C,MAAOT,EAAahE,GAAQC,EAAQ4E,MAAM,KAE1C,MAAO,CACH,CACI5E,QAAS+D,EACThE,QAGxB,CAGQ,MAAO,EACf"}
@@ -227,7 +227,8 @@ class MirrorNodeContractQuery {
227
227
  const host = mirrorNode.address.address;
228
228
  const isLocalEnvironment = host === "localhost" || host === "127.0.0.1";
229
229
  if (isLocalEnvironment) {
230
- // For local environments, use HTTP scheme and port 8545
230
+ // For local environments, use HTTP scheme and port 8545 for contract calls
231
+ // (different from general mirror node REST API port 5551)
231
232
  const url = new URL(mirrorRestApiBaseUrl);
232
233
  url.protocol = "http:";
233
234
  url.port = "8545";
@@ -1 +1 @@
1
- {"version":3,"file":"MirrorNodeContractQuery.js","sources":["../../src/query/MirrorNodeContractQuery.js"],"sourcesContent":["import ContractFunctionParameters from \"../contract/ContractFunctionParameters.js\";\n\n/**\n * @typedef {import(\"../contract/ContractId\").default} ContractId\n * @typedef {import(\"../account/AccountId\").default} AccountId\n * @typedef {import(\"../client/Client.js\").default<*, *>} Client\n *\n */\n\n/**\n * @typedef {object} MirrorNodeResponse\n * @property {string} result\n * @property {string} [error]\n * @property {string} [gasUsed]\n * @property {string} [contractAddress]\n * @property {string} [status]\n */\n\n/**\n * MirrorNodeContractQuery returns a result from EVM execution such as cost-free execution of read-only smart contract\n * queries, gas estimation, and transient simulation of read-write operations.\n * When working with sender that has ECDSA key with alias, you MUST:\n * 1. Retrieve the account's EVM address from the Mirror Node API first\n * 2. Use setSenderEvmAddress() instead of setSender()\n *\n * This is because EVM addresses for accounts with ECDSA keys and aliases cannot be automatically\n * derived and must be fetched from the Mirror Node. Example:\n *\n * ```javascript\n * // For accounts with ECDSA keys and aliases:\n * const evmAddress = // ... fetch from Mirror Node API ...\n * query.setSenderEvmAddress(evmAddress);\n * ```\n */\nexport default class MirrorNodeContractQuery {\n constructor() {\n this._contractId = null;\n this._contractEvmAddress = null;\n this._sender = null;\n this._senderEvmAddress = null;\n this._functionName = null;\n this._functionParameters = null;\n this._value = null;\n this._gasLimit = null;\n this._gasPrice = null;\n this._blockNumber = null;\n }\n\n /**\n *\n * @param {ContractId} contractId\n * @description Sets the contract instance to call.\n * @returns {this}\n */\n setContractId(contractId) {\n this._contractId = contractId;\n return this;\n }\n\n /**\n * @param {AccountId} sender\n * @description Sets the sender of the transaction simulation.\n * @returns {this}\n */\n setSender(sender) {\n this._sender = sender;\n return this;\n }\n\n /**\n * @param {string} sender\n * @description Set the 20-byte EVM address of the sender.\n * This method must be used explicitly when working with accounts that have ECDSA keys with aliases,\n * as their EVM addresses cannot be automatically derived and must be retrieved from the Mirror Node API.\n * The EVM address can be filled using `accountId.populateAccountEvmAddress(client)`\n * @returns {this}\n */\n setSenderEvmAddress(sender) {\n this._senderEvmAddress = sender;\n return this;\n }\n\n /**\n *\n * @param {string} name\n * @param {ContractFunctionParameters} functionParameters\n * @description Sets the function to call, and the parameters to pass to the function\n * @returns {this}\n */\n setFunction(name, functionParameters) {\n this._functionParameters =\n functionParameters != null\n ? functionParameters._build(name)\n : new ContractFunctionParameters()._build(name);\n\n return this;\n }\n\n /**\n * @param {Long} value\n * @description Sets the amount of value (in tinybars or wei) to be sent to the contract in the transaction.\n * Use this to specify an amount for a payable function call.\n * @returns {this}\n */\n setValue(value) {\n this._value = value;\n return this;\n }\n\n /**\n * @param {Long} gasLimit\n * @description Sets the gas limit for the contract call.\n * This specifies the maximum amount of gas that the transaction can consume.\n * @returns {this}\n */\n setGasLimit(gasLimit) {\n this._gasLimit = gasLimit;\n return this;\n }\n\n /**\n * @param {Long} gasPrice\n * @description Sets the gas price to be used for the contract call. This specifies the price of each unit of gas used in the transaction.\n * @returns {this}\n */\n setGasPrice(gasPrice) {\n this._gasPrice = gasPrice;\n return this;\n }\n\n /**\n * @param {Long} blockNumber\n * @description Sets the block number for the simulation of the contract call.\n * The block number determines the context of the contract call simulation within the blockchain.\n * @returns {this}\n */\n setBlockNumber(blockNumber) {\n this._blockNumber = blockNumber;\n return this;\n }\n\n /**\n * @returns {ContractId?}\n */\n get contractId() {\n return this._contractId;\n }\n\n /**\n * @returns {string}\n */\n get contractEvmAddress() {\n const solidityAddress = this._contractId?.toEvmAddress();\n if (solidityAddress == null) {\n throw new Error(\"Contract ID is not set\");\n }\n return solidityAddress;\n }\n\n /**\n * @returns {AccountId?}\n */\n get sender() {\n return this._sender;\n }\n\n /**\n * @returns {string | null }\n */\n get senderEvmAddress() {\n return this._senderEvmAddress;\n }\n\n /**\n * @returns {Uint8Array | null | undefined}\n */\n get callData() {\n return this._functionParameters;\n }\n\n /**\n * @returns {Long?}\n */\n get value() {\n return this._value;\n }\n\n /**\n * @returns {Long?}\n */\n get gasLimit() {\n return this._gasLimit;\n }\n\n /**\n * @returns {Long?}\n */\n get gasPrice() {\n return this._gasPrice;\n }\n\n /**\n * @returns {Long?}\n */\n get blockNumber() {\n return this._blockNumber;\n }\n\n /**\n *\n * @param {Client} client\n * @param {object} jsonPayload\n * @returns {Promise<MirrorNodeResponse>}\n */\n async performMirrorNodeRequest(client, jsonPayload) {\n if (this.contractId == null) {\n throw new Error(\"Contract ID is not set\");\n }\n this._fillEvmAddress();\n let mirrorRestApiBaseUrl = client.mirrorRestApiBaseUrl;\n const contractCallEndpointPath = \"/contracts/call\";\n\n // Check if this is a local environment (localhost or 127.0.0.1)\n const mirrorNode = client._mirrorNetwork.getNextMirrorNode();\n const host = mirrorNode.address.address;\n const isLocalEnvironment = host === \"localhost\" || host === \"127.0.0.1\";\n\n if (isLocalEnvironment) {\n // For local environments, use HTTP scheme and port 8545\n const url = new URL(mirrorRestApiBaseUrl);\n url.protocol = \"http:\";\n url.port = \"8545\";\n mirrorRestApiBaseUrl = url.toString();\n }\n\n const contractCallEndpointUrl = `${mirrorRestApiBaseUrl}${contractCallEndpointPath}`;\n\n // eslint-disable-next-line n/no-unsupported-features/node-builtins\n const response = await fetch(contractCallEndpointUrl, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(jsonPayload),\n });\n\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const data = /** @type {MirrorNodeResponse} */ (await response.json());\n return data;\n }\n\n _fillEvmAddress() {\n if (this.senderEvmAddress == null && this.sender != null) {\n this._senderEvmAddress = this.sender.toEvmAddress();\n }\n }\n // eslint-disable-next-line jsdoc/require-returns-check\n /**\n * @returns {object}\n */\n get JSONPayload() {\n throw new Error(\n \"JSONPayload getter is not implemented. Please implement this method in the subclass.\",\n );\n }\n}\n"],"names":["MirrorNodeContractQuery","constructor","this","_contractId","_contractEvmAddress","_sender","_senderEvmAddress","_functionName","_functionParameters","_value","_gasLimit","_gasPrice","_blockNumber","setContractId","contractId","setSender","sender","setSenderEvmAddress","setFunction","name","functionParameters","_build","ContractFunctionParameters","setValue","value","setGasLimit","gasLimit","setGasPrice","gasPrice","setBlockNumber","blockNumber","contractEvmAddress","solidityAddress","toEvmAddress","Error","senderEvmAddress","callData","performMirrorNodeRequest","client","jsonPayload","_fillEvmAddress","mirrorRestApiBaseUrl","host","_mirrorNetwork","getNextMirrorNode","address","url","URL","protocol","port","toString","contractCallEndpointUrl","response","fetch","method","headers","body","JSON","stringify","ok","status","json","JSONPayload"],"mappings":"yDAkCe,MAAMA,EACjB,WAAAC,GACIC,KAAKC,YAAc,KACnBD,KAAKE,oBAAsB,KAC3BF,KAAKG,QAAU,KACfH,KAAKI,kBAAoB,KACzBJ,KAAKK,cAAgB,KACrBL,KAAKM,oBAAsB,KAC3BN,KAAKO,OAAS,KACdP,KAAKQ,UAAY,KACjBR,KAAKS,UAAY,KACjBT,KAAKU,aAAe,IAC5B,CAQI,aAAAC,CAAcC,GAEV,OADAZ,KAAKC,YAAcW,EACZZ,IACf,CAOI,SAAAa,CAAUC,GAEN,OADAd,KAAKG,QAAUW,EACRd,IACf,CAUI,mBAAAe,CAAoBD,GAEhB,OADAd,KAAKI,kBAAoBU,EAClBd,IACf,CASI,WAAAgB,CAAYC,EAAMC,GAMd,OALAlB,KAAKM,oBACqB,MAAtBY,EACMA,EAAmBC,OAAOF,IAC1B,IAAIG,GAA6BD,OAAOF,GAE3CjB,IACf,CAQI,QAAAqB,CAASC,GAEL,OADAtB,KAAKO,OAASe,EACPtB,IACf,CAQI,WAAAuB,CAAYC,GAER,OADAxB,KAAKQ,UAAYgB,EACVxB,IACf,CAOI,WAAAyB,CAAYC,GAER,OADA1B,KAAKS,UAAYiB,EACV1B,IACf,CAQI,cAAA2B,CAAeC,GAEX,OADA5B,KAAKU,aAAekB,EACb5B,IACf,CAKI,cAAIY,GACA,OAAOZ,KAAKC,WACpB,CAKI,sBAAI4B,GACA,MAAMC,EAAkB9B,KAAKC,aAAa8B,eAC1C,GAAuB,MAAnBD,EACA,MAAM,IAAIE,MAAM,0BAEpB,OAAOF,CACf,CAKI,UAAIhB,GACA,OAAOd,KAAKG,OACpB,CAKI,oBAAI8B,GACA,OAAOjC,KAAKI,iBACpB,CAKI,YAAI8B,GACA,OAAOlC,KAAKM,mBACpB,CAKI,SAAIgB,GACA,OAAOtB,KAAKO,MACpB,CAKI,YAAIiB,GACA,OAAOxB,KAAKQ,SACpB,CAKI,YAAIkB,GACA,OAAO1B,KAAKS,SACpB,CAKI,eAAImB,GACA,OAAO5B,KAAKU,YACpB,CAQI,8BAAMyB,CAAyBC,EAAQC,GACnC,GAAuB,MAAnBrC,KAAKY,WACL,MAAM,IAAIoB,MAAM,0BAEpBhC,KAAKsC,kBACL,IAAIC,EAAuBH,EAAOG,qBAClC,MAIMC,EADaJ,EAAOK,eAAeC,oBACjBC,QAAQA,QAGhC,GAFoC,cAATH,GAAiC,cAATA,EAE3B,CAEpB,MAAMI,EAAM,IAAIC,IAAIN,GACpBK,EAAIE,SAAW,QACfF,EAAIG,KAAO,OACXR,EAAuBK,EAAII,UACvC,CAEQ,MAAMC,EAA0B,GAAGV,mBAG7BW,QAAiBC,MAAMF,EAAyB,CAClDG,OAAQ,OACRC,QAAS,CACL,eAAgB,oBAEpBC,KAAMC,KAAKC,UAAUnB,KAGzB,IAAKa,EAASO,GACV,MAAM,IAAIzB,MAAM,uBAAuBkB,EAASQ,UAKpD,aADsDR,EAASS,MAEvE,CAEI,eAAArB,GACiC,MAAzBtC,KAAKiC,kBAA2C,MAAfjC,KAAKc,SACtCd,KAAKI,kBAAoBJ,KAAKc,OAAOiB,eAEjD,CAKI,eAAI6B,GACA,MAAM,IAAI5B,MACN,uFAEZ"}
1
+ {"version":3,"file":"MirrorNodeContractQuery.js","sources":["../../src/query/MirrorNodeContractQuery.js"],"sourcesContent":["import ContractFunctionParameters from \"../contract/ContractFunctionParameters.js\";\n\n/**\n * @typedef {import(\"../contract/ContractId\").default} ContractId\n * @typedef {import(\"../account/AccountId\").default} AccountId\n * @typedef {import(\"../client/Client.js\").default<*, *>} Client\n *\n */\n\n/**\n * @typedef {object} MirrorNodeResponse\n * @property {string} result\n * @property {string} [error]\n * @property {string} [gasUsed]\n * @property {string} [contractAddress]\n * @property {string} [status]\n */\n\n/**\n * MirrorNodeContractQuery returns a result from EVM execution such as cost-free execution of read-only smart contract\n * queries, gas estimation, and transient simulation of read-write operations.\n * When working with sender that has ECDSA key with alias, you MUST:\n * 1. Retrieve the account's EVM address from the Mirror Node API first\n * 2. Use setSenderEvmAddress() instead of setSender()\n *\n * This is because EVM addresses for accounts with ECDSA keys and aliases cannot be automatically\n * derived and must be fetched from the Mirror Node. Example:\n *\n * ```javascript\n * // For accounts with ECDSA keys and aliases:\n * const evmAddress = // ... fetch from Mirror Node API ...\n * query.setSenderEvmAddress(evmAddress);\n * ```\n */\nexport default class MirrorNodeContractQuery {\n constructor() {\n this._contractId = null;\n this._contractEvmAddress = null;\n this._sender = null;\n this._senderEvmAddress = null;\n this._functionName = null;\n this._functionParameters = null;\n this._value = null;\n this._gasLimit = null;\n this._gasPrice = null;\n this._blockNumber = null;\n }\n\n /**\n *\n * @param {ContractId} contractId\n * @description Sets the contract instance to call.\n * @returns {this}\n */\n setContractId(contractId) {\n this._contractId = contractId;\n return this;\n }\n\n /**\n * @param {AccountId} sender\n * @description Sets the sender of the transaction simulation.\n * @returns {this}\n */\n setSender(sender) {\n this._sender = sender;\n return this;\n }\n\n /**\n * @param {string} sender\n * @description Set the 20-byte EVM address of the sender.\n * This method must be used explicitly when working with accounts that have ECDSA keys with aliases,\n * as their EVM addresses cannot be automatically derived and must be retrieved from the Mirror Node API.\n * The EVM address can be filled using `accountId.populateAccountEvmAddress(client)`\n * @returns {this}\n */\n setSenderEvmAddress(sender) {\n this._senderEvmAddress = sender;\n return this;\n }\n\n /**\n *\n * @param {string} name\n * @param {ContractFunctionParameters} functionParameters\n * @description Sets the function to call, and the parameters to pass to the function\n * @returns {this}\n */\n setFunction(name, functionParameters) {\n this._functionParameters =\n functionParameters != null\n ? functionParameters._build(name)\n : new ContractFunctionParameters()._build(name);\n\n return this;\n }\n\n /**\n * @param {Long} value\n * @description Sets the amount of value (in tinybars or wei) to be sent to the contract in the transaction.\n * Use this to specify an amount for a payable function call.\n * @returns {this}\n */\n setValue(value) {\n this._value = value;\n return this;\n }\n\n /**\n * @param {Long} gasLimit\n * @description Sets the gas limit for the contract call.\n * This specifies the maximum amount of gas that the transaction can consume.\n * @returns {this}\n */\n setGasLimit(gasLimit) {\n this._gasLimit = gasLimit;\n return this;\n }\n\n /**\n * @param {Long} gasPrice\n * @description Sets the gas price to be used for the contract call. This specifies the price of each unit of gas used in the transaction.\n * @returns {this}\n */\n setGasPrice(gasPrice) {\n this._gasPrice = gasPrice;\n return this;\n }\n\n /**\n * @param {Long} blockNumber\n * @description Sets the block number for the simulation of the contract call.\n * The block number determines the context of the contract call simulation within the blockchain.\n * @returns {this}\n */\n setBlockNumber(blockNumber) {\n this._blockNumber = blockNumber;\n return this;\n }\n\n /**\n * @returns {ContractId?}\n */\n get contractId() {\n return this._contractId;\n }\n\n /**\n * @returns {string}\n */\n get contractEvmAddress() {\n const solidityAddress = this._contractId?.toEvmAddress();\n if (solidityAddress == null) {\n throw new Error(\"Contract ID is not set\");\n }\n return solidityAddress;\n }\n\n /**\n * @returns {AccountId?}\n */\n get sender() {\n return this._sender;\n }\n\n /**\n * @returns {string | null }\n */\n get senderEvmAddress() {\n return this._senderEvmAddress;\n }\n\n /**\n * @returns {Uint8Array | null | undefined}\n */\n get callData() {\n return this._functionParameters;\n }\n\n /**\n * @returns {Long?}\n */\n get value() {\n return this._value;\n }\n\n /**\n * @returns {Long?}\n */\n get gasLimit() {\n return this._gasLimit;\n }\n\n /**\n * @returns {Long?}\n */\n get gasPrice() {\n return this._gasPrice;\n }\n\n /**\n * @returns {Long?}\n */\n get blockNumber() {\n return this._blockNumber;\n }\n\n /**\n *\n * @param {Client} client\n * @param {object} jsonPayload\n * @returns {Promise<MirrorNodeResponse>}\n */\n async performMirrorNodeRequest(client, jsonPayload) {\n if (this.contractId == null) {\n throw new Error(\"Contract ID is not set\");\n }\n this._fillEvmAddress();\n let mirrorRestApiBaseUrl = client.mirrorRestApiBaseUrl;\n const contractCallEndpointPath = \"/contracts/call\";\n\n // Check if this is a local environment (localhost or 127.0.0.1)\n const mirrorNode = client._mirrorNetwork.getNextMirrorNode();\n const host = mirrorNode.address.address;\n const isLocalEnvironment = host === \"localhost\" || host === \"127.0.0.1\";\n\n if (isLocalEnvironment) {\n // For local environments, use HTTP scheme and port 8545 for contract calls\n // (different from general mirror node REST API port 5551)\n const url = new URL(mirrorRestApiBaseUrl);\n url.protocol = \"http:\";\n url.port = \"8545\";\n mirrorRestApiBaseUrl = url.toString();\n }\n\n const contractCallEndpointUrl = `${mirrorRestApiBaseUrl}${contractCallEndpointPath}`;\n\n // eslint-disable-next-line n/no-unsupported-features/node-builtins\n const response = await fetch(contractCallEndpointUrl, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(jsonPayload),\n });\n\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const data = /** @type {MirrorNodeResponse} */ (await response.json());\n return data;\n }\n\n _fillEvmAddress() {\n if (this.senderEvmAddress == null && this.sender != null) {\n this._senderEvmAddress = this.sender.toEvmAddress();\n }\n }\n // eslint-disable-next-line jsdoc/require-returns-check\n /**\n * @returns {object}\n */\n get JSONPayload() {\n throw new Error(\n \"JSONPayload getter is not implemented. Please implement this method in the subclass.\",\n );\n }\n}\n"],"names":["MirrorNodeContractQuery","constructor","this","_contractId","_contractEvmAddress","_sender","_senderEvmAddress","_functionName","_functionParameters","_value","_gasLimit","_gasPrice","_blockNumber","setContractId","contractId","setSender","sender","setSenderEvmAddress","setFunction","name","functionParameters","_build","ContractFunctionParameters","setValue","value","setGasLimit","gasLimit","setGasPrice","gasPrice","setBlockNumber","blockNumber","contractEvmAddress","solidityAddress","toEvmAddress","Error","senderEvmAddress","callData","performMirrorNodeRequest","client","jsonPayload","_fillEvmAddress","mirrorRestApiBaseUrl","host","_mirrorNetwork","getNextMirrorNode","address","url","URL","protocol","port","toString","contractCallEndpointUrl","response","fetch","method","headers","body","JSON","stringify","ok","status","json","JSONPayload"],"mappings":"yDAkCe,MAAMA,EACjB,WAAAC,GACIC,KAAKC,YAAc,KACnBD,KAAKE,oBAAsB,KAC3BF,KAAKG,QAAU,KACfH,KAAKI,kBAAoB,KACzBJ,KAAKK,cAAgB,KACrBL,KAAKM,oBAAsB,KAC3BN,KAAKO,OAAS,KACdP,KAAKQ,UAAY,KACjBR,KAAKS,UAAY,KACjBT,KAAKU,aAAe,IAC5B,CAQI,aAAAC,CAAcC,GAEV,OADAZ,KAAKC,YAAcW,EACZZ,IACf,CAOI,SAAAa,CAAUC,GAEN,OADAd,KAAKG,QAAUW,EACRd,IACf,CAUI,mBAAAe,CAAoBD,GAEhB,OADAd,KAAKI,kBAAoBU,EAClBd,IACf,CASI,WAAAgB,CAAYC,EAAMC,GAMd,OALAlB,KAAKM,oBACqB,MAAtBY,EACMA,EAAmBC,OAAOF,IAC1B,IAAIG,GAA6BD,OAAOF,GAE3CjB,IACf,CAQI,QAAAqB,CAASC,GAEL,OADAtB,KAAKO,OAASe,EACPtB,IACf,CAQI,WAAAuB,CAAYC,GAER,OADAxB,KAAKQ,UAAYgB,EACVxB,IACf,CAOI,WAAAyB,CAAYC,GAER,OADA1B,KAAKS,UAAYiB,EACV1B,IACf,CAQI,cAAA2B,CAAeC,GAEX,OADA5B,KAAKU,aAAekB,EACb5B,IACf,CAKI,cAAIY,GACA,OAAOZ,KAAKC,WACpB,CAKI,sBAAI4B,GACA,MAAMC,EAAkB9B,KAAKC,aAAa8B,eAC1C,GAAuB,MAAnBD,EACA,MAAM,IAAIE,MAAM,0BAEpB,OAAOF,CACf,CAKI,UAAIhB,GACA,OAAOd,KAAKG,OACpB,CAKI,oBAAI8B,GACA,OAAOjC,KAAKI,iBACpB,CAKI,YAAI8B,GACA,OAAOlC,KAAKM,mBACpB,CAKI,SAAIgB,GACA,OAAOtB,KAAKO,MACpB,CAKI,YAAIiB,GACA,OAAOxB,KAAKQ,SACpB,CAKI,YAAIkB,GACA,OAAO1B,KAAKS,SACpB,CAKI,eAAImB,GACA,OAAO5B,KAAKU,YACpB,CAQI,8BAAMyB,CAAyBC,EAAQC,GACnC,GAAuB,MAAnBrC,KAAKY,WACL,MAAM,IAAIoB,MAAM,0BAEpBhC,KAAKsC,kBACL,IAAIC,EAAuBH,EAAOG,qBAClC,MAIMC,EADaJ,EAAOK,eAAeC,oBACjBC,QAAQA,QAGhC,GAFoC,cAATH,GAAiC,cAATA,EAE3B,CAGpB,MAAMI,EAAM,IAAIC,IAAIN,GACpBK,EAAIE,SAAW,QACfF,EAAIG,KAAO,OACXR,EAAuBK,EAAII,UACvC,CAEQ,MAAMC,EAA0B,GAAGV,mBAG7BW,QAAiBC,MAAMF,EAAyB,CAClDG,OAAQ,OACRC,QAAS,CACL,eAAgB,oBAEpBC,KAAMC,KAAKC,UAAUnB,KAGzB,IAAKa,EAASO,GACV,MAAM,IAAIzB,MAAM,uBAAuBkB,EAASQ,UAKpD,aADsDR,EAASS,MAEvE,CAEI,eAAArB,GACiC,MAAzBtC,KAAKiC,kBAA2C,MAAfjC,KAAKc,SACtCd,KAAKI,kBAAoBJ,KAAKc,OAAOiB,eAEjD,CAKI,eAAI6B,GACA,MAAM,IAAI5B,MACN,uFAEZ"}
@@ -10,14 +10,18 @@ var _TokenId = _interopRequireDefault(require("./TokenId.cjs"));
10
10
  var _NftId = _interopRequireDefault(require("./NftId.cjs"));
11
11
  var _AccountId = _interopRequireDefault(require("../account/AccountId.cjs"));
12
12
  var _Transaction = _interopRequireDefault(require("../transaction/Transaction.cjs"));
13
- var _long = _interopRequireDefault(require("long"));
14
13
  var _NullableTokenDecimalMap = _interopRequireDefault(require("../account/NullableTokenDecimalMap.cjs"));
15
14
  var _TokenNftTransferMap = _interopRequireDefault(require("../account/TokenNftTransferMap.cjs"));
16
15
  var _TokenTransferMap = _interopRequireDefault(require("../account/TokenTransferMap.cjs"));
17
16
  var _TokenTransferAccountMap = _interopRequireDefault(require("../account/TokenTransferAccountMap.cjs"));
17
+ var _util = require("../util.cjs");
18
18
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
19
19
  // SPDX-License-Identifier: Apache-2.0
20
20
 
21
+ /**
22
+ * @typedef {import("bignumber.js").default} BigNumber
23
+ */
24
+
21
25
  /**
22
26
  * @namespace proto
23
27
  * @typedef {import("@hashgraph/proto").proto.ITokenAirdropTransactionBody} HieroProto.proto.ITokenAirdropTransactionBody
@@ -27,7 +31,7 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e
27
31
  * @typedef {object} TransferTokensInput
28
32
  * @property {TokenId | string} tokenId
29
33
  * @property {AccountId | string} accountId
30
- * @property {Long | number} amount
34
+ * @property {Long | number | BigNumber | bigint} amount
31
35
  */
32
36
 
33
37
  /**
@@ -80,7 +84,7 @@ class AbstractTokenTransferTransaction extends _Transaction.default {
80
84
  /**
81
85
  * @param {TokenId | string} tokenId
82
86
  * @param {AccountId | string} accountId
83
- * @param {number | Long} amount
87
+ * @param {number | Long | BigNumber | bigint} amount
84
88
  * @param {boolean} isApproved
85
89
  * @param {number | null} expectedDecimals
86
90
  * @returns {this}
@@ -89,7 +93,7 @@ class AbstractTokenTransferTransaction extends _Transaction.default {
89
93
  this._requireNotFrozen();
90
94
  const token = tokenId instanceof _TokenId.default ? tokenId : _TokenId.default.fromString(tokenId);
91
95
  const account = accountId instanceof _AccountId.default ? accountId : _AccountId.default.fromString(accountId);
92
- const value = amount instanceof _long.default ? amount : _long.default.fromNumber(amount);
96
+ const value = (0, _util.convertAmountToLong)(amount);
93
97
  for (const tokenTransfer of this._tokenTransfers) {
94
98
  if (tokenTransfer.tokenId.compare(token) === 0 && tokenTransfer.accountId.compare(account) === 0) {
95
99
  tokenTransfer.amount = tokenTransfer.amount.add(value);
@@ -110,7 +114,7 @@ class AbstractTokenTransferTransaction extends _Transaction.default {
110
114
  /**
111
115
  * @param {TokenId | string} tokenId
112
116
  * @param {AccountId | string} accountId
113
- * @param {number | Long} amount
117
+ * @param {number | Long | BigNumber | bigint} amount
114
118
  * @returns {this}
115
119
  */
116
120
  addTokenTransfer(tokenId, accountId, amount) {
@@ -186,7 +190,7 @@ class AbstractTokenTransferTransaction extends _Transaction.default {
186
190
  /**
187
191
  * @param {TokenId | string} tokenId
188
192
  * @param {AccountId | string} accountId
189
- * @param {number | Long} amount
193
+ * @param {number | Long | BigNumber | bigint} amount
190
194
  * @returns {this}
191
195
  */
192
196
  addApprovedTokenTransfer(tokenId, accountId, amount) {
@@ -196,7 +200,7 @@ class AbstractTokenTransferTransaction extends _Transaction.default {
196
200
  /**
197
201
  * @param {TokenId | string} tokenId
198
202
  * @param {AccountId | string} accountId
199
- * @param {number | Long} amount
203
+ * @param {number | Long | BigNumber | bigint} amount
200
204
  * @param {number} decimals
201
205
  * @returns {this}
202
206
  */
@@ -204,7 +208,7 @@ class AbstractTokenTransferTransaction extends _Transaction.default {
204
208
  this._requireNotFrozen();
205
209
  const token = tokenId instanceof _TokenId.default ? tokenId : _TokenId.default.fromString(tokenId);
206
210
  const account = accountId instanceof _AccountId.default ? accountId : _AccountId.default.fromString(accountId);
207
- const value = amount instanceof _long.default ? amount : _long.default.fromNumber(amount);
211
+ const value = (0, _util.convertAmountToLong)(amount);
208
212
  let found = false;
209
213
  for (const tokenTransfer of this._tokenTransfers) {
210
214
  if (tokenTransfer.tokenId.compare(token) === 0) {
@@ -1,3 +1,6 @@
1
+ /**
2
+ * @typedef {import("bignumber.js").default} BigNumber
3
+ */
1
4
  /**
2
5
  * @namespace proto
3
6
  * @typedef {import("@hashgraph/proto").proto.ITokenAirdropTransactionBody} HieroProto.proto.ITokenAirdropTransactionBody
@@ -6,7 +9,7 @@
6
9
  * @typedef {object} TransferTokensInput
7
10
  * @property {TokenId | string} tokenId
8
11
  * @property {AccountId | string} accountId
9
- * @property {Long | number} amount
12
+ * @property {Long | number | BigNumber | bigint} amount
10
13
  */
11
14
  /**
12
15
  * @typedef {object} TransferNftInput
@@ -46,19 +49,19 @@ export default class AbstractTokenTransferTransaction extends Transaction {
46
49
  /**
47
50
  * @param {TokenId | string} tokenId
48
51
  * @param {AccountId | string} accountId
49
- * @param {number | Long} amount
52
+ * @param {number | Long | BigNumber | bigint} amount
50
53
  * @param {boolean} isApproved
51
54
  * @param {number | null} expectedDecimals
52
55
  * @returns {this}
53
56
  */
54
- _addTokenTransfer(tokenId: TokenId | string, accountId: AccountId | string, amount: number | Long, isApproved: boolean, expectedDecimals: number | null): this;
57
+ _addTokenTransfer(tokenId: TokenId | string, accountId: AccountId | string, amount: number | Long | BigNumber | bigint, isApproved: boolean, expectedDecimals: number | null): this;
55
58
  /**
56
59
  * @param {TokenId | string} tokenId
57
60
  * @param {AccountId | string} accountId
58
- * @param {number | Long} amount
61
+ * @param {number | Long | BigNumber | bigint} amount
59
62
  * @returns {this}
60
63
  */
61
- addTokenTransfer(tokenId: TokenId | string, accountId: AccountId | string, amount: number | Long): this;
64
+ addTokenTransfer(tokenId: TokenId | string, accountId: AccountId | string, amount: number | Long | BigNumber | bigint): this;
62
65
  /**
63
66
  * @param {boolean} isApproved
64
67
  * @param {NftId | TokenId | string} tokenIdOrNftId
@@ -79,18 +82,18 @@ export default class AbstractTokenTransferTransaction extends Transaction {
79
82
  /**
80
83
  * @param {TokenId | string} tokenId
81
84
  * @param {AccountId | string} accountId
82
- * @param {number | Long} amount
85
+ * @param {number | Long | BigNumber | bigint} amount
83
86
  * @returns {this}
84
87
  */
85
- addApprovedTokenTransfer(tokenId: TokenId | string, accountId: AccountId | string, amount: number | Long): this;
88
+ addApprovedTokenTransfer(tokenId: TokenId | string, accountId: AccountId | string, amount: number | Long | BigNumber | bigint): this;
86
89
  /**
87
90
  * @param {TokenId | string} tokenId
88
91
  * @param {AccountId | string} accountId
89
- * @param {number | Long} amount
92
+ * @param {number | Long | BigNumber | bigint} amount
90
93
  * @param {number} decimals
91
94
  * @returns {this}
92
95
  */
93
- addTokenTransferWithDecimals(tokenId: TokenId | string, accountId: AccountId | string, amount: number | Long, decimals: number): this;
96
+ addTokenTransferWithDecimals(tokenId: TokenId | string, accountId: AccountId | string, amount: number | Long | BigNumber | bigint, decimals: number): this;
94
97
  /**
95
98
  * @returns {NullableTokenDecimalMap}
96
99
  */
@@ -110,6 +113,7 @@ export default class AbstractTokenTransferTransaction extends Transaction {
110
113
  */
111
114
  protected override _makeTransactionData(): HieroProto.proto.ITokenAirdropTransactionBody;
112
115
  }
116
+ export type BigNumber = import("bignumber.js").default;
113
117
  export namespace HieroProto {
114
118
  namespace proto {
115
119
  type ITokenAirdropTransactionBody = import("@hashgraph/proto").proto.ITokenAirdropTransactionBody;
@@ -118,7 +122,7 @@ export namespace HieroProto {
118
122
  export type TransferTokensInput = {
119
123
  tokenId: TokenId | string;
120
124
  accountId: AccountId | string;
121
- amount: Long | number;
125
+ amount: Long | number | BigNumber | bigint;
122
126
  };
123
127
  export type TransferNftInput = {
124
128
  tokenId: TokenId | string;
@@ -132,7 +136,6 @@ import TokenNftTransfer from "../token/TokenNftTransfer.js";
132
136
  import NftId from "./NftId.js";
133
137
  import TokenId from "./TokenId.js";
134
138
  import AccountId from "../account/AccountId.js";
135
- import Long from "long";
136
139
  import NullableTokenDecimalMap from "../account/NullableTokenDecimalMap.js";
137
140
  import TokenNftTransferMap from "../account/TokenNftTransferMap.js";
138
141
  import TokenTransferMap from "../account/TokenTransferMap.js";
@@ -1,2 +1,2 @@
1
- import e from"./TokenTransfer.js";import n from"./TokenNftTransfer.js";import t from"./TokenId.js";import r from"./NftId.js";import s from"../account/AccountId.js";import o from"../transaction/Transaction.js";import a from"long";import f from"../account/NullableTokenDecimalMap.js";import c from"../account/TokenNftTransferMap.js";import i from"../account/TokenTransferMap.js";import d from"../account/TokenTransferAccountMap.js";class u extends o{constructor(e={}){super(),this._tokenTransfers=[],this._nftTransfers=[];for(const n of null!=e.tokenTransfers?e.tokenTransfers:[])this.addTokenTransfer(n.tokenId,n.accountId,n.amount);for(const n of null!=e.nftTransfers?e.nftTransfers:[])this.addNftTransfer(n.tokenId,n.serial,n.sender,n.recipient)}addNftTransfer(e,n,t,r){return this._addNftTransfer(!1,e,n,t,r)}_addTokenTransfer(n,r,o,f,c){this._requireNotFrozen();const i=n instanceof t?n:t.fromString(n),d=r instanceof s?r:s.fromString(r),u=o instanceof a?o:a.fromNumber(o);for(const e of this._tokenTransfers)if(0===e.tokenId.compare(i)&&0===e.accountId.compare(d))return e.amount=e.amount.add(u),e.expectedDecimals=c,this;return this._tokenTransfers.push(new e({tokenId:n,accountId:r,expectedDecimals:c,amount:o,isApproved:f})),this}addTokenTransfer(e,n,t){return this._addTokenTransfer(e,n,t,!1,null)}_addNftTransfer(e,o,a,f,c){let i,d,u;if(this._requireNotFrozen(),o instanceof r)i=o,d="string"==typeof a?s.fromString(a):a,u="string"==typeof f?s.fromString(f):f;else if(o instanceof t)i=new r(o,a),d="string"==typeof f?s.fromString(f):f,u="string"==typeof c?s.fromString(c):c;else try{i=r.fromString(o),d="string"==typeof a?s.fromString(a):a,u="string"==typeof f?s.fromString(f):f}catch(e){const n=t.fromString(o);i=new r(n,a),d="string"==typeof f?s.fromString(f):f,u="string"==typeof c?s.fromString(c):c}for(const e of this._nftTransfers)if(0===e.tokenId.compare(i.tokenId)&&0===e.serialNumber.compare(i.serial))return e.senderAccountId=d,e.receiverAccountId=u,this;return this._nftTransfers.push(new n({tokenId:i.tokenId,serialNumber:i.serial,senderAccountId:d,receiverAccountId:u,isApproved:e})),this}addApprovedNftTransfer(e,n,t,r){return this._addNftTransfer(!0,e,n,t,r)}addApprovedTokenTransfer(e,n,t){return this._addTokenTransfer(e,n,t,!0,null)}addTokenTransferWithDecimals(n,r,o,f){this._requireNotFrozen();const c=n instanceof t?n:t.fromString(n),i=r instanceof s?r:s.fromString(r),d=o instanceof a?o:a.fromNumber(o);let u=!1;for(const e of this._tokenTransfers)if(0===e.tokenId.compare(c)){if(null!=e.expectedDecimals&&e.expectedDecimals!==f)throw new Error("expected decimals mis-match");e.expectedDecimals=f,0===e.accountId.compare(i)&&(e.amount=e.amount.add(d),e.expectedDecimals=f,u=!0)}return u||this._tokenTransfers.push(new e({tokenId:n,accountId:r,expectedDecimals:f,amount:o,isApproved:!1})),this}get tokenIdDecimals(){const e=new f;for(const n of this._tokenTransfers)e._set(n.tokenId,n.expectedDecimals);return e}get nftTransfers(){const e=new c;for(const n of this._nftTransfers){const t=e.get(n.tokenId),r={sender:n.senderAccountId,recipient:n.receiverAccountId,serial:n.serialNumber,isApproved:n.isApproved};null!=t?t.push(r):e._set(n.tokenId,[r])}return e}get tokenTransfers(){const e=new i;for(const n of this._tokenTransfers){let t=e.get(n.tokenId);null!=t?t._set(n.accountId,n.amount):(t=new d,t._set(n.accountId,n.amount),e._set(n.tokenId,t))}return e}_makeTransactionData(){const e=[];this._tokenTransfers.sort((e,n)=>{const t=e.tokenId.compare(n.tokenId);return 0!==t?t:e.accountId.compare(n.accountId)}),this._nftTransfers.sort((e,n)=>{const t=e.senderAccountId.compare(n.senderAccountId);if(0!=t)return t;const r=e.receiverAccountId.compare(n.receiverAccountId);return 0!=r?r:e.serialNumber.compare(n.serialNumber)});let n=0,t=0;for(;n<this._tokenTransfers.length||t<this._nftTransfers.length;)if(n<this._tokenTransfers.length&&t<this._nftTransfers.length){const r=this._tokenTransfers[n].tokenId,s=this._nftTransfers[t].tokenId,o=e.length>0?e[e.length-1]:null,a=null!=o?o.tokenId:null;if(null!=o&&null!=a&&0===a.compare(r)){o.transfers.push(this._tokenTransfers[n++]);continue}if(null!=o&&null!=a&&0===a.compare(s)){o.nftTransfers.push(this._nftTransfers[t++]);continue}const f=r.compare(s);0===f?e.push({tokenId:r,expectedDecimals:this._tokenTransfers[n].expectedDecimals,transfers:[this._tokenTransfers[n++]],nftTransfers:[this._nftTransfers[t++]]}):f<0?e.push({tokenId:r,expectedDecimals:this._tokenTransfers[n].expectedDecimals,transfers:[this._tokenTransfers[n++]],nftTransfers:[]}):e.push({tokenId:s,expectedDecimals:null,transfers:[],nftTransfers:[this._nftTransfers[t++]]})}else if(n<this._tokenTransfers.length){const t=this._tokenTransfers[n].tokenId;let r;for(const n of e)0===n.tokenId.compare(t)&&(r=n);const s=null!=r?r.tokenId:null;if(null!=r&&null!=s&&0===s.compare(t)){r.transfers.push(this._tokenTransfers[n++]);continue}e.push({tokenId:t,expectedDecimals:this._tokenTransfers[n].expectedDecimals,transfers:[this._tokenTransfers[n++]],nftTransfers:[]})}else if(t<this._nftTransfers.length){const n=this._nftTransfers[t].tokenId;let r;for(const t of e)0===t.tokenId.compare(n)&&(r=t);const s=null!=r?r.tokenId:null;if(null!=r&&null!=s&&0===s.compare(n)){r.nftTransfers.push(this._nftTransfers[t++]);continue}e.push({tokenId:n,expectedDecimals:null,transfers:[],nftTransfers:[this._nftTransfers[t++]]})}return{tokenTransfers:e.map(e=>({token:e.tokenId._toProtobuf(),expectedDecimals:null!=e.expectedDecimals?{value:e.expectedDecimals}:null,transfers:e.transfers.map(e=>e._toProtobuf()),nftTransfers:e.nftTransfers.map(e=>e._toProtobuf())}))}}}export{u as default};
1
+ import e from"./TokenTransfer.js";import n from"./TokenNftTransfer.js";import t from"./TokenId.js";import r from"./NftId.js";import s from"../account/AccountId.js";import o from"../transaction/Transaction.js";import a from"../account/NullableTokenDecimalMap.js";import f from"../account/TokenNftTransferMap.js";import c from"../account/TokenTransferMap.js";import i from"../account/TokenTransferAccountMap.js";import{convertAmountToLong as d}from"../util.js";class u extends o{constructor(e={}){super(),this._tokenTransfers=[],this._nftTransfers=[];for(const n of null!=e.tokenTransfers?e.tokenTransfers:[])this.addTokenTransfer(n.tokenId,n.accountId,n.amount);for(const n of null!=e.nftTransfers?e.nftTransfers:[])this.addNftTransfer(n.tokenId,n.serial,n.sender,n.recipient)}addNftTransfer(e,n,t,r){return this._addNftTransfer(!1,e,n,t,r)}_addTokenTransfer(n,r,o,a,f){this._requireNotFrozen();const c=n instanceof t?n:t.fromString(n),i=r instanceof s?r:s.fromString(r),u=d(o);for(const e of this._tokenTransfers)if(0===e.tokenId.compare(c)&&0===e.accountId.compare(i))return e.amount=e.amount.add(u),e.expectedDecimals=f,this;return this._tokenTransfers.push(new e({tokenId:n,accountId:r,expectedDecimals:f,amount:o,isApproved:a})),this}addTokenTransfer(e,n,t){return this._addTokenTransfer(e,n,t,!1,null)}_addNftTransfer(e,o,a,f,c){let i,d,u;if(this._requireNotFrozen(),o instanceof r)i=o,d="string"==typeof a?s.fromString(a):a,u="string"==typeof f?s.fromString(f):f;else if(o instanceof t)i=new r(o,a),d="string"==typeof f?s.fromString(f):f,u="string"==typeof c?s.fromString(c):c;else try{i=r.fromString(o),d="string"==typeof a?s.fromString(a):a,u="string"==typeof f?s.fromString(f):f}catch(e){const n=t.fromString(o);i=new r(n,a),d="string"==typeof f?s.fromString(f):f,u="string"==typeof c?s.fromString(c):c}for(const e of this._nftTransfers)if(0===e.tokenId.compare(i.tokenId)&&0===e.serialNumber.compare(i.serial))return e.senderAccountId=d,e.receiverAccountId=u,this;return this._nftTransfers.push(new n({tokenId:i.tokenId,serialNumber:i.serial,senderAccountId:d,receiverAccountId:u,isApproved:e})),this}addApprovedNftTransfer(e,n,t,r){return this._addNftTransfer(!0,e,n,t,r)}addApprovedTokenTransfer(e,n,t){return this._addTokenTransfer(e,n,t,!0,null)}addTokenTransferWithDecimals(n,r,o,a){this._requireNotFrozen();const f=n instanceof t?n:t.fromString(n),c=r instanceof s?r:s.fromString(r),i=d(o);let u=!1;for(const e of this._tokenTransfers)if(0===e.tokenId.compare(f)){if(null!=e.expectedDecimals&&e.expectedDecimals!==a)throw new Error("expected decimals mis-match");e.expectedDecimals=a,0===e.accountId.compare(c)&&(e.amount=e.amount.add(i),e.expectedDecimals=a,u=!0)}return u||this._tokenTransfers.push(new e({tokenId:n,accountId:r,expectedDecimals:a,amount:o,isApproved:!1})),this}get tokenIdDecimals(){const e=new a;for(const n of this._tokenTransfers)e._set(n.tokenId,n.expectedDecimals);return e}get nftTransfers(){const e=new f;for(const n of this._nftTransfers){const t=e.get(n.tokenId),r={sender:n.senderAccountId,recipient:n.receiverAccountId,serial:n.serialNumber,isApproved:n.isApproved};null!=t?t.push(r):e._set(n.tokenId,[r])}return e}get tokenTransfers(){const e=new c;for(const n of this._tokenTransfers){let t=e.get(n.tokenId);null!=t?t._set(n.accountId,n.amount):(t=new i,t._set(n.accountId,n.amount),e._set(n.tokenId,t))}return e}_makeTransactionData(){const e=[];this._tokenTransfers.sort((e,n)=>{const t=e.tokenId.compare(n.tokenId);return 0!==t?t:e.accountId.compare(n.accountId)}),this._nftTransfers.sort((e,n)=>{const t=e.senderAccountId.compare(n.senderAccountId);if(0!=t)return t;const r=e.receiverAccountId.compare(n.receiverAccountId);return 0!=r?r:e.serialNumber.compare(n.serialNumber)});let n=0,t=0;for(;n<this._tokenTransfers.length||t<this._nftTransfers.length;)if(n<this._tokenTransfers.length&&t<this._nftTransfers.length){const r=this._tokenTransfers[n].tokenId,s=this._nftTransfers[t].tokenId,o=e.length>0?e[e.length-1]:null,a=null!=o?o.tokenId:null;if(null!=o&&null!=a&&0===a.compare(r)){o.transfers.push(this._tokenTransfers[n++]);continue}if(null!=o&&null!=a&&0===a.compare(s)){o.nftTransfers.push(this._nftTransfers[t++]);continue}const f=r.compare(s);0===f?e.push({tokenId:r,expectedDecimals:this._tokenTransfers[n].expectedDecimals,transfers:[this._tokenTransfers[n++]],nftTransfers:[this._nftTransfers[t++]]}):f<0?e.push({tokenId:r,expectedDecimals:this._tokenTransfers[n].expectedDecimals,transfers:[this._tokenTransfers[n++]],nftTransfers:[]}):e.push({tokenId:s,expectedDecimals:null,transfers:[],nftTransfers:[this._nftTransfers[t++]]})}else if(n<this._tokenTransfers.length){const t=this._tokenTransfers[n].tokenId;let r;for(const n of e)0===n.tokenId.compare(t)&&(r=n);const s=null!=r?r.tokenId:null;if(null!=r&&null!=s&&0===s.compare(t)){r.transfers.push(this._tokenTransfers[n++]);continue}e.push({tokenId:t,expectedDecimals:this._tokenTransfers[n].expectedDecimals,transfers:[this._tokenTransfers[n++]],nftTransfers:[]})}else if(t<this._nftTransfers.length){const n=this._nftTransfers[t].tokenId;let r;for(const t of e)0===t.tokenId.compare(n)&&(r=t);const s=null!=r?r.tokenId:null;if(null!=r&&null!=s&&0===s.compare(n)){r.nftTransfers.push(this._nftTransfers[t++]);continue}e.push({tokenId:n,expectedDecimals:null,transfers:[],nftTransfers:[this._nftTransfers[t++]]})}return{tokenTransfers:e.map(e=>({token:e.tokenId._toProtobuf(),expectedDecimals:null!=e.expectedDecimals?{value:e.expectedDecimals}:null,transfers:e.transfers.map(e=>e._toProtobuf()),nftTransfers:e.nftTransfers.map(e=>e._toProtobuf())}))}}}export{u as default};
2
2
  //# sourceMappingURL=AbstractTokenTransferTransaction.js.map