@hiero-ledger/sdk 2.80.0 → 2.81.0-beta.1

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 (182) hide show
  1. package/README.md +34 -7
  2. package/dist/umd.js +2213 -318
  3. package/dist/umd.js.map +1 -0
  4. package/dist/umd.min.js +6 -5
  5. package/dist/umd.min.js.map +1 -0
  6. package/lib/Executable.cjs +7 -4
  7. package/lib/Executable.js +1 -1
  8. package/lib/Executable.js.map +1 -1
  9. package/lib/PublicKey.cjs +45 -26
  10. package/lib/PublicKey.d.ts +12 -0
  11. package/lib/PublicKey.js +1 -1
  12. package/lib/PublicKey.js.map +1 -1
  13. package/lib/RequestType.cjs +19 -1
  14. package/lib/RequestType.d.ts +2 -0
  15. package/lib/RequestType.js +1 -1
  16. package/lib/RequestType.js.map +1 -1
  17. package/lib/Status.cjs +203 -252
  18. package/lib/Status.d.ts +8 -6
  19. package/lib/Status.js +1 -1
  20. package/lib/Status.js.map +1 -1
  21. package/lib/Transfer.cjs +25 -2
  22. package/lib/Transfer.d.ts +4 -0
  23. package/lib/Transfer.js +1 -1
  24. package/lib/Transfer.js.map +1 -1
  25. package/lib/account/AccountCreateTransaction.cjs +38 -0
  26. package/lib/account/AccountCreateTransaction.d.ts +21 -0
  27. package/lib/account/AccountCreateTransaction.js +1 -1
  28. package/lib/account/AccountCreateTransaction.js.map +1 -1
  29. package/lib/account/AccountUpdateTransaction.cjs +74 -1
  30. package/lib/account/AccountUpdateTransaction.d.ts +43 -0
  31. package/lib/account/AccountUpdateTransaction.js +1 -1
  32. package/lib/account/AccountUpdateTransaction.js.map +1 -1
  33. package/lib/account/TransferTransaction.cjs +57 -9
  34. package/lib/account/TransferTransaction.d.ts +31 -1
  35. package/lib/account/TransferTransaction.js +1 -1
  36. package/lib/account/TransferTransaction.js.map +1 -1
  37. package/lib/browser.js +1 -1
  38. package/lib/client/Client.cjs +38 -0
  39. package/lib/client/Client.d.ts +30 -0
  40. package/lib/client/Client.js +1 -1
  41. package/lib/client/Client.js.map +1 -1
  42. package/lib/client/addressbooks/mainnet.cjs +1 -1
  43. package/lib/client/addressbooks/mainnet.d.ts +1 -1
  44. package/lib/client/addressbooks/mainnet.js +1 -1
  45. package/lib/client/addressbooks/mainnet.js.map +1 -1
  46. package/lib/client/addressbooks/previewnet.cjs +1 -1
  47. package/lib/client/addressbooks/previewnet.d.ts +1 -1
  48. package/lib/client/addressbooks/previewnet.js +1 -1
  49. package/lib/client/addressbooks/previewnet.js.map +1 -1
  50. package/lib/client/addressbooks/testnet.cjs +1 -1
  51. package/lib/client/addressbooks/testnet.d.ts +1 -1
  52. package/lib/client/addressbooks/testnet.js +1 -1
  53. package/lib/client/addressbooks/testnet.js.map +1 -1
  54. package/lib/contract/ContractCreateTransaction.cjs +37 -1
  55. package/lib/contract/ContractCreateTransaction.d.ts +21 -0
  56. package/lib/contract/ContractCreateTransaction.js +1 -1
  57. package/lib/contract/ContractCreateTransaction.js.map +1 -1
  58. package/lib/contract/ContractUpdateTransaction.cjs +74 -1
  59. package/lib/contract/ContractUpdateTransaction.d.ts +43 -0
  60. package/lib/contract/ContractUpdateTransaction.js +1 -1
  61. package/lib/contract/ContractUpdateTransaction.js.map +1 -1
  62. package/lib/exports.cjs +103 -0
  63. package/lib/exports.d.ts +13 -0
  64. package/lib/exports.js +1 -1
  65. package/lib/exports.js.map +1 -1
  66. package/lib/hooks/EvmHook.cjs +84 -0
  67. package/lib/hooks/EvmHook.d.ts +51 -0
  68. package/lib/hooks/EvmHook.js +2 -0
  69. package/lib/hooks/EvmHook.js.map +1 -0
  70. package/lib/hooks/EvmHookCall.cjs +103 -0
  71. package/lib/hooks/EvmHookCall.d.ts +69 -0
  72. package/lib/hooks/EvmHookCall.js +2 -0
  73. package/lib/hooks/EvmHookCall.js.map +1 -0
  74. package/lib/hooks/EvmHookMappingEntry.cjs +135 -0
  75. package/lib/hooks/EvmHookMappingEntry.d.ts +84 -0
  76. package/lib/hooks/EvmHookMappingEntry.js +2 -0
  77. package/lib/hooks/EvmHookMappingEntry.js.map +1 -0
  78. package/lib/hooks/EvmHookStorageUpdate.cjs +238 -0
  79. package/lib/hooks/EvmHookStorageUpdate.d.ts +144 -0
  80. package/lib/hooks/EvmHookStorageUpdate.js +2 -0
  81. package/lib/hooks/EvmHookStorageUpdate.js.map +1 -0
  82. package/lib/hooks/FungibleHookCall.cjs +67 -0
  83. package/lib/hooks/FungibleHookCall.d.ts +50 -0
  84. package/lib/hooks/FungibleHookCall.js +2 -0
  85. package/lib/hooks/FungibleHookCall.js.map +1 -0
  86. package/lib/hooks/FungibleHookType.cjs +11 -0
  87. package/lib/hooks/FungibleHookType.d.ts +5 -0
  88. package/lib/hooks/FungibleHookType.js +2 -0
  89. package/lib/hooks/FungibleHookType.js.map +1 -0
  90. package/lib/hooks/HookCall.cjs +99 -0
  91. package/lib/hooks/HookCall.d.ts +64 -0
  92. package/lib/hooks/HookCall.js +2 -0
  93. package/lib/hooks/HookCall.js.map +1 -0
  94. package/lib/hooks/HookCreationDetails.cjs +149 -0
  95. package/lib/hooks/HookCreationDetails.d.ts +91 -0
  96. package/lib/hooks/HookCreationDetails.js +2 -0
  97. package/lib/hooks/HookCreationDetails.js.map +1 -0
  98. package/lib/hooks/HookEntityId.cjs +67 -0
  99. package/lib/hooks/HookEntityId.d.ts +41 -0
  100. package/lib/hooks/HookEntityId.js +2 -0
  101. package/lib/hooks/HookEntityId.js.map +1 -0
  102. package/lib/hooks/HookExtensionPoint.cjs +31 -0
  103. package/lib/hooks/HookExtensionPoint.d.ts +16 -0
  104. package/lib/hooks/HookExtensionPoint.js +2 -0
  105. package/lib/hooks/HookExtensionPoint.js.map +1 -0
  106. package/lib/hooks/HookId.cjs +101 -0
  107. package/lib/hooks/HookId.d.ts +63 -0
  108. package/lib/hooks/HookId.js +2 -0
  109. package/lib/hooks/HookId.js.map +1 -0
  110. package/lib/hooks/HookStoreTransaction.cjs +157 -0
  111. package/lib/hooks/HookStoreTransaction.d.ts +77 -0
  112. package/lib/hooks/HookStoreTransaction.js +2 -0
  113. package/lib/hooks/HookStoreTransaction.js.map +1 -0
  114. package/lib/hooks/NftHookCall.cjs +67 -0
  115. package/lib/hooks/NftHookCall.d.ts +50 -0
  116. package/lib/hooks/NftHookCall.js +2 -0
  117. package/lib/hooks/NftHookCall.js.map +1 -0
  118. package/lib/hooks/NftHookType.cjs +13 -0
  119. package/lib/hooks/NftHookType.d.ts +7 -0
  120. package/lib/hooks/NftHookType.js +2 -0
  121. package/lib/hooks/NftHookType.js.map +1 -0
  122. package/lib/index.js +1 -1
  123. package/lib/native.js +1 -1
  124. package/lib/token/AbstractTokenTransferTransaction.cjs +17 -5
  125. package/lib/token/AbstractTokenTransferTransaction.d.ts +13 -2
  126. package/lib/token/AbstractTokenTransferTransaction.js +1 -1
  127. package/lib/token/AbstractTokenTransferTransaction.js.map +1 -1
  128. package/lib/token/TokenAirdropTransaction.cjs +1 -1
  129. package/lib/token/TokenAirdropTransaction.js +1 -1
  130. package/lib/token/TokenAirdropTransaction.js.map +1 -1
  131. package/lib/token/TokenNftTransfer.cjs +51 -2
  132. package/lib/token/TokenNftTransfer.d.ts +7 -0
  133. package/lib/token/TokenNftTransfer.js +1 -1
  134. package/lib/token/TokenNftTransfer.js.map +1 -1
  135. package/lib/token/TokenTransfer.cjs +26 -2
  136. package/lib/token/TokenTransfer.d.ts +4 -0
  137. package/lib/token/TokenTransfer.js +1 -1
  138. package/lib/token/TokenTransfer.js.map +1 -1
  139. package/lib/transaction/Transaction.cjs +2 -1
  140. package/lib/transaction/Transaction.js +1 -1
  141. package/lib/transaction/Transaction.js.map +1 -1
  142. package/lib/transaction/TransactionResponse.cjs +82 -9
  143. package/lib/transaction/TransactionResponse.d.ts +33 -2
  144. package/lib/transaction/TransactionResponse.js +1 -1
  145. package/lib/transaction/TransactionResponse.js.map +1 -1
  146. package/lib/version.js +1 -1
  147. package/package.json +15 -13
  148. package/src/Executable.js +10 -7
  149. package/src/PublicKey.js +53 -36
  150. package/src/RequestType.js +18 -0
  151. package/src/Status.js +201 -252
  152. package/src/Transfer.js +33 -1
  153. package/src/account/AccountCreateTransaction.js +39 -0
  154. package/src/account/AccountUpdateTransaction.js +78 -0
  155. package/src/account/TransferTransaction.js +84 -8
  156. package/src/client/Client.js +38 -0
  157. package/src/client/addressbooks/mainnet.js +1 -1
  158. package/src/client/addressbooks/previewnet.js +1 -1
  159. package/src/client/addressbooks/testnet.js +1 -1
  160. package/src/contract/ContractCreateTransaction.js +37 -0
  161. package/src/contract/ContractUpdateTransaction.js +80 -0
  162. package/src/exports.js +17 -0
  163. package/src/hooks/EvmHook.js +83 -0
  164. package/src/hooks/EvmHookCall.js +100 -0
  165. package/src/hooks/EvmHookMappingEntry.js +140 -0
  166. package/src/hooks/EvmHookStorageUpdate.js +257 -0
  167. package/src/hooks/FungibleHookCall.js +65 -0
  168. package/src/hooks/FungibleHookType.js +6 -0
  169. package/src/hooks/HookCall.js +97 -0
  170. package/src/hooks/HookCreationDetails.js +155 -0
  171. package/src/hooks/HookEntityId.js +67 -0
  172. package/src/hooks/HookExtensionPoint.js +25 -0
  173. package/src/hooks/HookId.js +102 -0
  174. package/src/hooks/HookStoreTransaction.js +185 -0
  175. package/src/hooks/NftHookCall.js +64 -0
  176. package/src/hooks/NftHookType.js +8 -0
  177. package/src/token/AbstractTokenTransferTransaction.js +16 -1
  178. package/src/token/TokenAirdropTransaction.js +1 -0
  179. package/src/token/TokenNftTransfer.js +68 -1
  180. package/src/token/TokenTransfer.js +34 -1
  181. package/src/transaction/Transaction.js +3 -0
  182. package/src/transaction/TransactionResponse.js +98 -13
@@ -0,0 +1,64 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+
3
+ import HookCall from "./HookCall.js";
4
+ import EvmHookCall from "./EvmHookCall.js";
5
+ import NftHookType from "./NftHookType.js";
6
+ /**
7
+ * @namespace proto
8
+ * @typedef {import("@hiero-ledger/proto").proto.IHookCall} HieroProto.proto.IHookCall
9
+ */
10
+
11
+ /**
12
+ * @typedef {typeof NftHookType[keyof typeof NftHookType]} NftHookTypeValue
13
+ */
14
+
15
+ /**
16
+ * A typed hook call for NFT transfers.
17
+ */
18
+ class NftHookCall extends HookCall {
19
+ /**
20
+ * @param {object} props
21
+ * @param {Long} [props.hookId]
22
+ * @param {import("../hooks/EvmHookCall.js").default} [props.evmHookCall]
23
+ * @param {NftHookTypeValue} props.type - One of NftHookType (PRE_HOOK_SENDER, PRE_POST_HOOK_SENDER, PRE_HOOK_RECEIVER, PRE_POST_HOOK_RECEIVER)
24
+ */
25
+ constructor(props) {
26
+ super(props);
27
+
28
+ if (props.type == null) {
29
+ throw new Error("type cannot be null");
30
+ }
31
+
32
+ /**
33
+ * The type of NFT hook
34
+ * @private
35
+ * @type {number}
36
+ */
37
+ this._type = props.type;
38
+ }
39
+
40
+ /**
41
+ * @returns {number}
42
+ */
43
+ get type() {
44
+ return this._type;
45
+ }
46
+
47
+ /**
48
+ * @internal
49
+ * @param {HieroProto.proto.IHookCall} hookCall
50
+ * @param {NftHookTypeValue} type
51
+ * @returns {NftHookCall}
52
+ */
53
+ static _fromProtobufWithType(hookCall, type) {
54
+ return new NftHookCall({
55
+ hookId: hookCall.hookId != null ? hookCall.hookId : undefined,
56
+ evmHookCall: hookCall.evmHookCall
57
+ ? EvmHookCall._fromProtobuf(hookCall.evmHookCall)
58
+ : undefined,
59
+ type,
60
+ });
61
+ }
62
+ }
63
+
64
+ export default NftHookCall;
@@ -0,0 +1,8 @@
1
+ const NftHookType = Object.freeze({
2
+ PRE_HOOK_SENDER: 0,
3
+ PRE_POST_HOOK_SENDER: 1,
4
+ PRE_HOOK_RECEIVER: 2,
5
+ PRE_POST_HOOK_RECEIVER: 3,
6
+ });
7
+
8
+ export default NftHookType;
@@ -20,6 +20,12 @@ import { convertAmountToLong } from "../util.js";
20
20
  * @typedef {import("@hiero-ledger/proto").proto.ITokenAirdropTransactionBody} HieroProto.proto.ITokenAirdropTransactionBody
21
21
  */
22
22
 
23
+ /**
24
+ * @typedef {import("../hooks/HookCall.js").default} HookCall
25
+ * @typedef {import("../hooks/FungibleHookCall.js").default} FungibleHookCall
26
+ * @typedef {import("../hooks/NftHookCall.js").default} NftHookCall
27
+ */
28
+
23
29
  /**
24
30
  * @typedef {object} TransferTokensInput
25
31
  * @property {TokenId | string} tokenId
@@ -106,6 +112,7 @@ export default class AbstractTokenTransferTransaction extends Transaction {
106
112
  * @param {number | Long | BigNumber | bigint} amount
107
113
  * @param {boolean} isApproved
108
114
  * @param {number | null} expectedDecimals
115
+ * @param {FungibleHookCall} [hookCall]
109
116
  * @returns {this}
110
117
  */
111
118
  _addTokenTransfer(
@@ -114,6 +121,7 @@ export default class AbstractTokenTransferTransaction extends Transaction {
114
121
  amount,
115
122
  isApproved,
116
123
  expectedDecimals,
124
+ hookCall,
117
125
  ) {
118
126
  this._requireNotFrozen();
119
127
 
@@ -140,9 +148,10 @@ export default class AbstractTokenTransferTransaction extends Transaction {
140
148
  new TokenTransfer({
141
149
  tokenId,
142
150
  accountId,
143
- expectedDecimals: expectedDecimals,
151
+ expectedDecimals,
144
152
  amount,
145
153
  isApproved,
154
+ hookCall,
146
155
  }),
147
156
  );
148
157
 
@@ -165,6 +174,8 @@ export default class AbstractTokenTransferTransaction extends Transaction {
165
174
  * @param {AccountId | string | Long | number} senderAccountIdOrSerialNumber
166
175
  * @param {AccountId | string} receiverAccountIdOrSenderAccountId
167
176
  * @param {(AccountId | string)=} receiver
177
+ * @param {NftHookCall=} senderHookCall
178
+ * @param {NftHookCall=} receiverHookCall
168
179
  * @returns {this}
169
180
  */
170
181
  _addNftTransfer(
@@ -173,6 +184,8 @@ export default class AbstractTokenTransferTransaction extends Transaction {
173
184
  senderAccountIdOrSerialNumber,
174
185
  receiverAccountIdOrSenderAccountId,
175
186
  receiver,
187
+ senderHookCall,
188
+ receiverHookCall,
176
189
  ) {
177
190
  this._requireNotFrozen();
178
191
 
@@ -263,6 +276,8 @@ export default class AbstractTokenTransferTransaction extends Transaction {
263
276
  senderAccountId,
264
277
  receiverAccountId,
265
278
  isApproved,
279
+ senderHookCall,
280
+ receiverHookCall,
266
281
  }),
267
282
  );
268
283
 
@@ -137,6 +137,7 @@ export default class TokenAirdropTransaction extends AbstractTokenTransferTransa
137
137
  amount,
138
138
  true,
139
139
  expectedDecimals,
140
+ undefined,
140
141
  );
141
142
  return this;
142
143
  }
@@ -3,6 +3,8 @@
3
3
  import Long from "long";
4
4
  import AccountId from "../account/AccountId.js";
5
5
  import TokenId from "./TokenId.js";
6
+ import NftHookCall from "../hooks/NftHookCall.js";
7
+ import NftHookType from "../hooks/NftHookType.js";
6
8
 
7
9
  /**
8
10
  * @namespace proto
@@ -29,6 +31,8 @@ export default class TokenNftTransfer {
29
31
  * @param {AccountId | string} props.receiverAccountId
30
32
  * @param {Long | number} props.serialNumber
31
33
  * @param {boolean} props.isApproved
34
+ * @param {NftHookCall} [props.senderHookCall]
35
+ * @param {NftHookCall} [props.receiverHookCall]
32
36
  */
33
37
  constructor(props) {
34
38
  /**
@@ -56,6 +60,8 @@ export default class TokenNftTransfer {
56
60
  : AccountId.fromString(props.receiverAccountId);
57
61
 
58
62
  this.serialNumber = Long.fromValue(props.serialNumber);
63
+ this.senderHookCall = props.senderHookCall;
64
+ this.receiverHookCall = props.receiverHookCall;
59
65
  this.isApproved = props.isApproved;
60
66
  }
61
67
 
@@ -74,6 +80,34 @@ export default class TokenNftTransfer {
74
80
  for (const transfer of tokenTransfer.nftTransfers != null
75
81
  ? tokenTransfer.nftTransfers
76
82
  : []) {
83
+ // Determine sender hook type
84
+ let senderHookCall;
85
+ if (transfer.preTxSenderAllowanceHook != null) {
86
+ senderHookCall = NftHookCall._fromProtobufWithType(
87
+ transfer.preTxSenderAllowanceHook,
88
+ NftHookType.PRE_HOOK_SENDER,
89
+ );
90
+ } else if (transfer.prePostTxSenderAllowanceHook != null) {
91
+ senderHookCall = NftHookCall._fromProtobufWithType(
92
+ transfer.prePostTxSenderAllowanceHook,
93
+ NftHookType.PRE_POST_HOOK_SENDER,
94
+ );
95
+ }
96
+
97
+ // Determine receiver hook type
98
+ let receiverHookCall;
99
+ if (transfer.preTxReceiverAllowanceHook != null) {
100
+ receiverHookCall = NftHookCall._fromProtobufWithType(
101
+ transfer.preTxReceiverAllowanceHook,
102
+ NftHookType.PRE_HOOK_RECEIVER,
103
+ );
104
+ } else if (transfer.prePostTxReceiverAllowanceHook != null) {
105
+ receiverHookCall = NftHookCall._fromProtobufWithType(
106
+ transfer.prePostTxReceiverAllowanceHook,
107
+ NftHookType.PRE_POST_HOOK_RECEIVER,
108
+ );
109
+ }
110
+
77
111
  transfers.push(
78
112
  new TokenNftTransfer({
79
113
  tokenId,
@@ -92,6 +126,8 @@ export default class TokenNftTransfer {
92
126
  ? transfer.serialNumber
93
127
  : Long.ZERO,
94
128
  isApproved: transfer.isApproval == true,
129
+ senderHookCall: senderHookCall,
130
+ receiverHookCall: receiverHookCall,
95
131
  }),
96
132
  );
97
133
  }
@@ -105,11 +141,42 @@ export default class TokenNftTransfer {
105
141
  * @returns {HieroProto.proto.INftTransfer}
106
142
  */
107
143
  _toProtobuf() {
108
- return {
144
+ /** @type {HieroProto.proto.INftTransfer} */
145
+ const result = {
109
146
  senderAccountID: this.senderAccountId._toProtobuf(),
110
147
  receiverAccountID: this.receiverAccountId._toProtobuf(),
111
148
  serialNumber: this.serialNumber,
112
149
  isApproval: this.isApproved,
113
150
  };
151
+
152
+ // Handle sender hook
153
+ if (this.senderHookCall != null) {
154
+ switch (this.senderHookCall.type) {
155
+ case NftHookType.PRE_HOOK_SENDER:
156
+ result.preTxSenderAllowanceHook =
157
+ this.senderHookCall._toProtobuf();
158
+ break;
159
+ case NftHookType.PRE_POST_HOOK_SENDER:
160
+ result.prePostTxSenderAllowanceHook =
161
+ this.senderHookCall._toProtobuf();
162
+ break;
163
+ }
164
+ }
165
+
166
+ // Handle receiver hook
167
+ if (this.receiverHookCall != null) {
168
+ switch (this.receiverHookCall.type) {
169
+ case NftHookType.PRE_HOOK_RECEIVER:
170
+ result.preTxReceiverAllowanceHook =
171
+ this.receiverHookCall._toProtobuf();
172
+ break;
173
+ case NftHookType.PRE_POST_HOOK_RECEIVER:
174
+ result.prePostTxReceiverAllowanceHook =
175
+ this.receiverHookCall._toProtobuf();
176
+ break;
177
+ }
178
+ }
179
+
180
+ return result;
114
181
  }
115
182
  }
@@ -4,6 +4,8 @@ import Long from "long";
4
4
  import AccountId from "../account/AccountId.js";
5
5
  import TokenId from "./TokenId.js";
6
6
  import { convertAmountToLong } from "../util.js";
7
+ import FungibleHookCall from "../hooks/FungibleHookCall.js";
8
+ import FungibleHookType from "../hooks/FungibleHookType.js";
7
9
 
8
10
  /**
9
11
  * @namespace proto
@@ -38,6 +40,7 @@ export default class TokenTransfer {
38
40
  * @param {number | null} props.expectedDecimals
39
41
  * @param {Long | number | BigNumber | bigint} props.amount
40
42
  * @param {boolean} props.isApproved
43
+ * @param {FungibleHookCall} [props.hookCall]
41
44
  */
42
45
  constructor(props) {
43
46
  /**
@@ -63,6 +66,7 @@ export default class TokenTransfer {
63
66
  this.expectedDecimals = props.expectedDecimals;
64
67
  this.amount = convertAmountToLong(props.amount);
65
68
  this.isApproved = props.isApproved;
69
+ this.hookCall = props.hookCall || null;
66
70
  }
67
71
 
68
72
  /**
@@ -87,6 +91,20 @@ export default class TokenTransfer {
87
91
  for (const transfer of tokenTransfer.transfers != null
88
92
  ? tokenTransfer.transfers
89
93
  : []) {
94
+ // Determine which hook type is present, if any
95
+ let hookCall = null;
96
+ if (transfer.preTxAllowanceHook != null) {
97
+ hookCall = FungibleHookCall._fromProtobufWithType(
98
+ transfer.preTxAllowanceHook,
99
+ FungibleHookType.PRE_TX_ALLOWANCE_HOOK,
100
+ );
101
+ } else if (transfer.prePostTxAllowanceHook != null) {
102
+ hookCall = FungibleHookCall._fromProtobufWithType(
103
+ transfer.prePostTxAllowanceHook,
104
+ FungibleHookType.PRE_POST_TX_ALLOWANCE_HOOK,
105
+ );
106
+ }
107
+
90
108
  transfers.push(
91
109
  new TokenTransfer({
92
110
  tokenId,
@@ -101,6 +119,7 @@ export default class TokenTransfer {
101
119
  ? transfer.amount
102
120
  : Long.ZERO,
103
121
  isApproved: transfer.isApproval == true,
122
+ hookCall: hookCall ?? undefined,
104
123
  }),
105
124
  );
106
125
  }
@@ -114,11 +133,25 @@ export default class TokenTransfer {
114
133
  * @returns {HieroProto.proto.IAccountAmount}
115
134
  */
116
135
  _toProtobuf() {
117
- return {
136
+ /** @type {HieroProto.proto.IAccountAmount} */
137
+ const result = {
118
138
  accountID: this.accountId._toProtobuf(),
119
139
  amount: this.amount,
120
140
  isApproval: this.isApproved,
121
141
  };
142
+
143
+ if (this.hookCall != null) {
144
+ switch (this.hookCall.type) {
145
+ case FungibleHookType.PRE_TX_ALLOWANCE_HOOK:
146
+ result.preTxAllowanceHook = this.hookCall._toProtobuf();
147
+ break;
148
+ case FungibleHookType.PRE_POST_TX_ALLOWANCE_HOOK:
149
+ result.prePostTxAllowanceHook = this.hookCall._toProtobuf();
150
+ break;
151
+ }
152
+ }
153
+
154
+ return result;
122
155
  }
123
156
 
124
157
  /**
@@ -2056,6 +2056,9 @@ export default class Transaction extends Executable {
2056
2056
  transactionId,
2057
2057
  transaction: this,
2058
2058
  logger: this._logger,
2059
+ transactionNodeAccountIds: !this._nodeAccountIds.isEmpty
2060
+ ? this._nodeAccountIds.list
2061
+ : undefined,
2059
2062
  });
2060
2063
  }
2061
2064
 
@@ -43,6 +43,7 @@ export default class TransactionResponse {
43
43
  * @param {TransactionId} props.transactionId
44
44
  * @param {Transaction} [props.transaction]
45
45
  * @param {Logger | null} [props.logger]
46
+ * @param {AccountId[]} [props.transactionNodeAccountIds]
46
47
  */
47
48
  constructor(props) {
48
49
  /** @readonly */
@@ -56,6 +57,14 @@ export default class TransactionResponse {
56
57
  this.transaction = props.transaction;
57
58
 
58
59
  this.logger = props.logger;
60
+
61
+ /**
62
+ * The node account IDs that were configured on the transaction.
63
+ * Used for receipt query failover when allowReceiptNodeFailover is enabled.
64
+ * @internal
65
+ * @type {AccountId[] | undefined}
66
+ */
67
+ this.transactionNodeAccountIds = props.transactionNodeAccountIds;
59
68
  }
60
69
 
61
70
  /**
@@ -77,7 +86,7 @@ export default class TransactionResponse {
77
86
  async getReceipt(client) {
78
87
  let receipt;
79
88
  try {
80
- receipt = await this.getReceiptQuery().execute(client);
89
+ receipt = await this.getReceiptQuery(client).execute(client);
81
90
  } catch (err) {
82
91
  if (
83
92
  err instanceof ReceiptStatusError &&
@@ -113,7 +122,7 @@ export default class TransactionResponse {
113
122
  async getRecord(client) {
114
123
  await this.getReceipt(client);
115
124
 
116
- return this.getRecordQuery().execute(client);
125
+ return this.getRecordQuery(client).execute(client);
117
126
  }
118
127
 
119
128
  /**
@@ -125,10 +134,10 @@ export default class TransactionResponse {
125
134
  async getVerboseRecord(client) {
126
135
  try {
127
136
  // The receipt needs to be called in order to wait for transaction to be included in the consensus. Otherwise we are going to get "DUPLICATE_TRANSACTION".
128
- await this.getReceiptQuery().execute(client);
129
- return this.getRecordQuery().execute(client);
137
+ await this.getReceiptQuery(client).execute(client);
138
+ return this.getRecordQuery(client).execute(client);
130
139
  } catch (e) {
131
- return this.getRecordQuery().execute(client);
140
+ return this.getRecordQuery(client).execute(client);
132
141
  }
133
142
  }
134
143
 
@@ -161,21 +170,97 @@ export default class TransactionResponse {
161
170
  }
162
171
 
163
172
  /**
173
+ * Create a receipt query for this transaction.
174
+ *
175
+ * By default, the query is pinned to the submitting node only. If the client has
176
+ * `allowReceiptNodeFailover` enabled, the query can fail over to other nodes while
177
+ * still starting with the submitting node first.
178
+ *
179
+ * When failover is enabled, the node list is determined by:
180
+ * 1. Transaction's configured nodes (if transaction had specific nodes set), or
181
+ * 2. Client's network nodes (as fallback)
182
+ *
183
+ * @param {Client} [client] - Optional client to enable failover behavior
164
184
  * @returns {TransactionReceiptQuery}
165
185
  */
166
- getReceiptQuery() {
167
- return new TransactionReceiptQuery()
168
- .setTransactionId(this.transactionId)
169
- .setNodeAccountIds([this.nodeId]);
186
+ getReceiptQuery(client) {
187
+ const query = new TransactionReceiptQuery().setTransactionId(
188
+ this.transactionId,
189
+ );
190
+
191
+ // If client is provided and failover is enabled, construct a node list
192
+ // that starts with the submitting node followed by other nodes
193
+ if (client != null && client.allowReceiptNodeFailover) {
194
+ // Use transaction's configured nodes if available, otherwise use client network
195
+ const availableNodes =
196
+ this.transactionNodeAccountIds != null &&
197
+ this.transactionNodeAccountIds.length > 0
198
+ ? this.transactionNodeAccountIds
199
+ : client._network.getNodeAccountIdsForExecute();
200
+
201
+ // Build node list: [submittedNode, ...otherNodes] without duplicates
202
+ const nodeList = [this.nodeId];
203
+ for (const node of availableNodes) {
204
+ // Only add if it's not the submitting node (avoid duplicates)
205
+ if (!node.equals(this.nodeId)) {
206
+ nodeList.push(node);
207
+ }
208
+ }
209
+
210
+ query.setNodeAccountIds(nodeList);
211
+ } else {
212
+ // Default behavior: pin to submitting node only
213
+ query.setNodeAccountIds([this.nodeId]);
214
+ }
215
+
216
+ return query;
170
217
  }
171
218
 
172
219
  /**
220
+ * Create a record query for this transaction.
221
+ *
222
+ * By default, the query is pinned to the submitting node only. If the client has
223
+ * `allowReceiptNodeFailover` enabled, the query can fail over to other nodes while
224
+ * still starting with the submitting node first.
225
+ *
226
+ * When failover is enabled, the node list is determined by:
227
+ * 1. Transaction's configured nodes (if transaction had specific nodes set), or
228
+ * 2. Client's network nodes (as fallback)
229
+ *
230
+ * @param {Client} [client] - Optional client to enable failover behavior
173
231
  * @returns {TransactionRecordQuery}
174
232
  */
175
- getRecordQuery() {
176
- return new TransactionRecordQuery()
177
- .setTransactionId(this.transactionId)
178
- .setNodeAccountIds([this.nodeId]);
233
+ getRecordQuery(client) {
234
+ const query = new TransactionRecordQuery().setTransactionId(
235
+ this.transactionId,
236
+ );
237
+
238
+ // If client is provided and failover is enabled, construct a node list
239
+ // that starts with the submitting node followed by other nodes
240
+ if (client != null && client.allowReceiptNodeFailover) {
241
+ // Use transaction's configured nodes if available, otherwise use client network
242
+ const availableNodes =
243
+ this.transactionNodeAccountIds != null &&
244
+ this.transactionNodeAccountIds.length > 0
245
+ ? this.transactionNodeAccountIds
246
+ : client._network.getNodeAccountIdsForExecute();
247
+
248
+ // Build node list: [submittedNode, ...otherNodes] without duplicates
249
+ const nodeList = [this.nodeId];
250
+ for (const node of availableNodes) {
251
+ // Only add if it's not the submitting node (avoid duplicates)
252
+ if (!node.equals(this.nodeId)) {
253
+ nodeList.push(node);
254
+ }
255
+ }
256
+
257
+ query.setNodeAccountIds(nodeList);
258
+ } else {
259
+ // Default behavior: pin to submitting node only
260
+ query.setNodeAccountIds([this.nodeId]);
261
+ }
262
+
263
+ return query;
179
264
  }
180
265
 
181
266
  /**