1use hiero_sdk_proto::services;
4use tonic::transport::Channel;
5
6use super::chunked::ChunkInfo;
7use super::{
8 TransactionData,
9 TransactionExecuteChunked,
10};
11use crate::custom_fee_limit::CustomFeeLimit;
12use crate::downcast::DowncastOwned;
13use crate::entity_id::ValidateChecksums;
14use crate::ledger_id::RefLedgerId;
15use crate::protobuf::FromProtobuf;
16use crate::transaction::{
17 ToTransactionDataProtobuf,
18 TransactionBody,
19 TransactionExecute,
20};
21use crate::{
22 AccountId,
23 BoxGrpcFuture,
24 Error,
25 Hbar,
26 Transaction,
27 TransactionId,
28};
29
30mod data {
31 pub(super) use crate::account::{
32 AccountAllowanceApproveTransactionData as AccountAllowanceApprove,
33 AccountAllowanceDeleteTransactionData as AccountAllowanceDelete,
34 AccountCreateTransactionData as AccountCreate,
35 AccountDeleteTransactionData as AccountDelete,
36 AccountUpdateTransactionData as AccountUpdate,
37 };
38 pub(super) use crate::address_book::{
39 NodeCreateTransactionData as NodeCreate,
40 NodeDeleteTransactionData as NodeDelete,
41 NodeUpdateTransactionData as NodeUpdate,
42 };
43 pub(super) use crate::batch_transaction::BatchTransactionData as Batch;
44 pub(super) use crate::contract::{
45 ContractCreateTransactionData as ContractCreate,
46 ContractDeleteTransactionData as ContractDelete,
47 ContractExecuteTransactionData as ContractExecute,
48 ContractUpdateTransactionData as ContractUpdate,
49 };
50 pub(super) use crate::ethereum::EthereumTransactionData as Ethereum;
51 pub(super) use crate::file::{
52 FileAppendTransactionData as FileAppend,
53 FileCreateTransactionData as FileCreate,
54 FileDeleteTransactionData as FileDelete,
55 FileUpdateTransactionData as FileUpdate,
56 };
57 pub(super) use crate::hooks::HookStoreTransactionData as HookStore;
58 pub(super) use crate::prng_transaction::PrngTransactionData as Prng;
59 pub(super) use crate::schedule::{
60 ScheduleCreateTransactionData as ScheduleCreate,
61 ScheduleDeleteTransactionData as ScheduleDelete,
62 ScheduleSignTransactionData as ScheduleSign,
63 };
64 pub(super) use crate::system::{
65 FreezeTransactionData as Freeze,
66 SystemDeleteTransactionData as SystemDelete,
67 SystemUndeleteTransactionData as SystemUndelete,
68 };
69 pub(super) use crate::token::{
70 TokenAirdropTransactionData as TokenAirdrop,
71 TokenAssociateTransactionData as TokenAssociate,
72 TokenBurnTransactionData as TokenBurn,
73 TokenCancelAirdropTransactionData as TokenCancelAirdrop,
74 TokenClaimAirdropTransactionData as TokenClaimAirdrop,
75 TokenCreateTransactionData as TokenCreate,
76 TokenDeleteTransactionData as TokenDelete,
77 TokenDissociateTransactionData as TokenDissociate,
78 TokenFeeScheduleUpdateTransactionData as TokenFeeScheduleUpdate,
79 TokenFreezeTransactionData as TokenFreeze,
80 TokenGrantKycTransactionData as TokenGrantKyc,
81 TokenMintTransactionData as TokenMint,
82 TokenPauseTransactionData as TokenPause,
83 TokenRejectTransactionData as TokenReject,
84 TokenRevokeKycTransactionData as TokenRevokeKyc,
85 TokenUnfreezeTransactionData as TokenUnfreeze,
86 TokenUnpauseTransactionData as TokenUnpause,
87 TokenUpdateNftsTransactionData as TokenUpdateNfts,
88 TokenUpdateTransactionData as TokenUpdate,
89 TokenWipeTransactionData as TokenWipe,
90 };
91 pub(super) use crate::topic::{
92 TopicCreateTransactionData as TopicCreate,
93 TopicDeleteTransactionData as TopicDelete,
94 TopicMessageSubmitTransactionData as TopicMessageSubmit,
95 TopicUpdateTransactionData as TopicUpdate,
96 };
97 pub(super) use crate::transfer_transaction::TransferTransactionData as Transfer;
98}
99
100pub type AnyTransaction = Transaction<AnyTransactionData>;
102
103#[derive(Debug, Clone)]
104#[non_exhaustive]
105pub enum AnyTransactionData {
106 AccountCreate(data::AccountCreate),
107 AccountUpdate(data::AccountUpdate),
108 AccountDelete(data::AccountDelete),
109 AccountAllowanceApprove(data::AccountAllowanceApprove),
110 AccountAllowanceDelete(data::AccountAllowanceDelete),
111 ContractCreate(data::ContractCreate),
112 ContractUpdate(data::ContractUpdate),
113 ContractDelete(data::ContractDelete),
114 ContractExecute(data::ContractExecute),
115 Transfer(data::Transfer),
116 TopicCreate(data::TopicCreate),
117 TopicUpdate(data::TopicUpdate),
118 TopicDelete(data::TopicDelete),
119 TopicMessageSubmit(data::TopicMessageSubmit),
120 FileAppend(data::FileAppend),
121 FileCreate(data::FileCreate),
122 FileUpdate(data::FileUpdate),
123 FileDelete(data::FileDelete),
124 Prng(data::Prng),
125 ScheduleCreate(data::ScheduleCreate),
126 ScheduleSign(data::ScheduleSign),
127 ScheduleDelete(data::ScheduleDelete),
128 TokenAssociate(data::TokenAssociate),
129 TokenBurn(data::TokenBurn),
130 TokenCreate(data::TokenCreate),
131 TokenDelete(data::TokenDelete),
132 TokenDissociate(data::TokenDissociate),
133 TokenFeeScheduleUpdate(data::TokenFeeScheduleUpdate),
134 TokenFreeze(data::TokenFreeze),
135 TokenGrantKyc(data::TokenGrantKyc),
136 TokenMint(data::TokenMint),
137 TokenPause(data::TokenPause),
138 TokenRevokeKyc(data::TokenRevokeKyc),
139 TokenUnfreeze(data::TokenUnfreeze),
140 TokenUnpause(data::TokenUnpause),
141 TokenUpdate(data::TokenUpdate),
142 TokenWipe(data::TokenWipe),
143 SystemDelete(data::SystemDelete),
144 SystemUndelete(data::SystemUndelete),
145 Freeze(data::Freeze),
146 Ethereum(data::Ethereum),
147 TokenUpdateNfts(data::TokenUpdateNfts),
148 NodeCreate(data::NodeCreate),
149 NodeUpdate(data::NodeUpdate),
150 NodeDelete(data::NodeDelete),
151 TokenReject(data::TokenReject),
152 TokenAirdrop(data::TokenAirdrop),
153 TokenClaimAirdrop(data::TokenClaimAirdrop),
154 TokenCancelAirdrop(data::TokenCancelAirdrop),
155 Batch(data::Batch),
156 HookStore(data::HookStore),
157}
158
159impl ToTransactionDataProtobuf for AnyTransactionData {
160 #[allow(clippy::too_many_lines)]
162 fn to_transaction_data_protobuf(
163 &self,
164 chunk_info: &ChunkInfo,
165 ) -> services::transaction_body::Data {
166 match self {
167 Self::Transfer(transaction) => transaction.to_transaction_data_protobuf(chunk_info),
168
169 Self::AccountCreate(transaction) => {
170 transaction.to_transaction_data_protobuf(chunk_info)
171 }
172
173 Self::AccountUpdate(transaction) => {
174 transaction.to_transaction_data_protobuf(chunk_info)
175 }
176
177 Self::AccountDelete(transaction) => {
178 transaction.to_transaction_data_protobuf(chunk_info)
179 }
180
181 Self::AccountAllowanceApprove(transaction) => {
182 transaction.to_transaction_data_protobuf(chunk_info)
183 }
184
185 Self::AccountAllowanceDelete(transaction) => {
186 transaction.to_transaction_data_protobuf(chunk_info)
187 }
188
189 Self::ContractCreate(transaction) => {
190 transaction.to_transaction_data_protobuf(chunk_info)
191 }
192
193 Self::ContractUpdate(transaction) => {
194 transaction.to_transaction_data_protobuf(chunk_info)
195 }
196
197 Self::ContractDelete(transaction) => {
198 transaction.to_transaction_data_protobuf(chunk_info)
199 }
200
201 Self::ContractExecute(transaction) => {
202 transaction.to_transaction_data_protobuf(chunk_info)
203 }
204
205 Self::FileAppend(transaction) => transaction.to_transaction_data_protobuf(chunk_info),
206
207 Self::FileCreate(transaction) => transaction.to_transaction_data_protobuf(chunk_info),
208
209 Self::FileUpdate(transaction) => transaction.to_transaction_data_protobuf(chunk_info),
210
211 Self::FileDelete(transaction) => transaction.to_transaction_data_protobuf(chunk_info),
212
213 Self::Prng(transaction) => transaction.to_transaction_data_protobuf(chunk_info),
214
215 Self::TokenAssociate(transaction) => {
216 transaction.to_transaction_data_protobuf(chunk_info)
217 }
218
219 Self::TokenBurn(transaction) => transaction.to_transaction_data_protobuf(chunk_info),
220
221 Self::TokenCreate(transaction) => transaction.to_transaction_data_protobuf(chunk_info),
222
223 Self::TokenDelete(transaction) => transaction.to_transaction_data_protobuf(chunk_info),
224
225 Self::TokenDissociate(transaction) => {
226 transaction.to_transaction_data_protobuf(chunk_info)
227 }
228
229 Self::TokenFeeScheduleUpdate(transaction) => {
230 transaction.to_transaction_data_protobuf(chunk_info)
231 }
232
233 Self::TokenFreeze(transaction) => transaction.to_transaction_data_protobuf(chunk_info),
234
235 Self::TokenGrantKyc(transaction) => {
236 transaction.to_transaction_data_protobuf(chunk_info)
237 }
238
239 Self::TokenMint(transaction) => transaction.to_transaction_data_protobuf(chunk_info),
240
241 Self::TokenPause(transaction) => transaction.to_transaction_data_protobuf(chunk_info),
242
243 Self::TokenRevokeKyc(transaction) => {
244 transaction.to_transaction_data_protobuf(chunk_info)
245 }
246
247 Self::TokenUnfreeze(transaction) => {
248 transaction.to_transaction_data_protobuf(chunk_info)
249 }
250
251 Self::TokenUnpause(transaction) => transaction.to_transaction_data_protobuf(chunk_info),
252
253 Self::TokenUpdate(transaction) => transaction.to_transaction_data_protobuf(chunk_info),
254
255 Self::TokenWipe(transaction) => transaction.to_transaction_data_protobuf(chunk_info),
256
257 Self::TopicCreate(transaction) => transaction.to_transaction_data_protobuf(chunk_info),
258
259 Self::TopicUpdate(transaction) => transaction.to_transaction_data_protobuf(chunk_info),
260
261 Self::TopicDelete(transaction) => transaction.to_transaction_data_protobuf(chunk_info),
262
263 Self::TokenReject(transaction) => transaction.to_transaction_data_protobuf(chunk_info),
264
265 Self::TopicMessageSubmit(transaction) => {
266 transaction.to_transaction_data_protobuf(chunk_info)
267 }
268
269 Self::SystemDelete(transaction) => transaction.to_transaction_data_protobuf(chunk_info),
270
271 Self::SystemUndelete(transaction) => {
272 transaction.to_transaction_data_protobuf(chunk_info)
273 }
274
275 Self::Freeze(transaction) => transaction.to_transaction_data_protobuf(chunk_info),
276
277 Self::ScheduleCreate(transaction) => {
278 transaction.to_transaction_data_protobuf(chunk_info)
279 }
280
281 Self::ScheduleSign(transaction) => transaction.to_transaction_data_protobuf(chunk_info),
282
283 Self::ScheduleDelete(transaction) => {
284 transaction.to_transaction_data_protobuf(chunk_info)
285 }
286
287 Self::Ethereum(transaction) => transaction.to_transaction_data_protobuf(chunk_info),
288
289 Self::TokenUpdateNfts(transaction) => {
290 transaction.to_transaction_data_protobuf(chunk_info)
291 }
292
293 Self::NodeCreate(transaction) => transaction.to_transaction_data_protobuf(chunk_info),
294
295 Self::NodeUpdate(transaction) => transaction.to_transaction_data_protobuf(chunk_info),
296
297 Self::NodeDelete(transaction) => transaction.to_transaction_data_protobuf(chunk_info),
298
299 Self::TokenAirdrop(transaction) => transaction.to_transaction_data_protobuf(chunk_info),
300
301 Self::TokenClaimAirdrop(transaction) => {
302 transaction.to_transaction_data_protobuf(chunk_info)
303 }
304 Self::TokenCancelAirdrop(transaction) => {
305 transaction.to_transaction_data_protobuf(chunk_info)
306 }
307 Self::Batch(transaction) => transaction.to_transaction_data_protobuf(chunk_info),
308 Self::HookStore(transaction) => transaction.to_transaction_data_protobuf(chunk_info),
309 }
310 }
311}
312
313impl TransactionData for AnyTransactionData {
314 fn default_max_transaction_fee(&self) -> Hbar {
315 match self {
316 Self::Transfer(transaction) => transaction.default_max_transaction_fee(),
317 Self::AccountCreate(transaction) => transaction.default_max_transaction_fee(),
318 Self::AccountUpdate(transaction) => transaction.default_max_transaction_fee(),
319 Self::AccountDelete(transaction) => transaction.default_max_transaction_fee(),
320 Self::AccountAllowanceApprove(transaction) => transaction.default_max_transaction_fee(),
321 Self::AccountAllowanceDelete(transaction) => transaction.default_max_transaction_fee(),
322 Self::ContractCreate(transaction) => transaction.default_max_transaction_fee(),
323 Self::ContractUpdate(transaction) => transaction.default_max_transaction_fee(),
324 Self::ContractDelete(transaction) => transaction.default_max_transaction_fee(),
325 Self::ContractExecute(transaction) => transaction.default_max_transaction_fee(),
326 Self::FileAppend(transaction) => transaction.default_max_transaction_fee(),
327 Self::FileCreate(transaction) => transaction.default_max_transaction_fee(),
328 Self::FileUpdate(transaction) => transaction.default_max_transaction_fee(),
329 Self::FileDelete(transaction) => transaction.default_max_transaction_fee(),
330 Self::Prng(transaction) => transaction.default_max_transaction_fee(),
331 Self::TokenAssociate(transaction) => transaction.default_max_transaction_fee(),
332 Self::TokenBurn(transaction) => transaction.default_max_transaction_fee(),
333 Self::TokenCreate(transaction) => transaction.default_max_transaction_fee(),
334 Self::TokenDelete(transaction) => transaction.default_max_transaction_fee(),
335 Self::TokenDissociate(transaction) => transaction.default_max_transaction_fee(),
336 Self::TokenFeeScheduleUpdate(transaction) => transaction.default_max_transaction_fee(),
337 Self::TokenFreeze(transaction) => transaction.default_max_transaction_fee(),
338 Self::TokenGrantKyc(transaction) => transaction.default_max_transaction_fee(),
339 Self::TokenMint(transaction) => transaction.default_max_transaction_fee(),
340 Self::TokenPause(transaction) => transaction.default_max_transaction_fee(),
341 Self::TokenRevokeKyc(transaction) => transaction.default_max_transaction_fee(),
342 Self::TokenUnfreeze(transaction) => transaction.default_max_transaction_fee(),
343 Self::TokenUnpause(transaction) => transaction.default_max_transaction_fee(),
344 Self::TokenUpdate(transaction) => transaction.default_max_transaction_fee(),
345 Self::TokenWipe(transaction) => transaction.default_max_transaction_fee(),
346 Self::TopicCreate(transaction) => transaction.default_max_transaction_fee(),
347 Self::TopicUpdate(transaction) => transaction.default_max_transaction_fee(),
348 Self::TopicDelete(transaction) => transaction.default_max_transaction_fee(),
349 Self::TopicMessageSubmit(transaction) => transaction.default_max_transaction_fee(),
350 Self::SystemDelete(transaction) => transaction.default_max_transaction_fee(),
351 Self::SystemUndelete(transaction) => transaction.default_max_transaction_fee(),
352 Self::Freeze(transaction) => transaction.default_max_transaction_fee(),
353 Self::ScheduleCreate(transaction) => transaction.default_max_transaction_fee(),
354 Self::ScheduleSign(transaction) => transaction.default_max_transaction_fee(),
355 Self::ScheduleDelete(transaction) => transaction.default_max_transaction_fee(),
356 Self::Ethereum(transaction) => transaction.default_max_transaction_fee(),
357 Self::TokenUpdateNfts(transaction) => transaction.default_max_transaction_fee(),
358 Self::NodeCreate(transaction) => transaction.default_max_transaction_fee(),
359 Self::NodeUpdate(transaction) => transaction.default_max_transaction_fee(),
360 Self::NodeDelete(transaction) => transaction.default_max_transaction_fee(),
361 Self::TokenReject(transaction) => transaction.default_max_transaction_fee(),
362 Self::TokenAirdrop(transaction) => transaction.default_max_transaction_fee(),
363 Self::TokenClaimAirdrop(transaction) => transaction.default_max_transaction_fee(),
364 Self::TokenCancelAirdrop(transaction) => transaction.default_max_transaction_fee(),
365 Self::Batch(transaction) => transaction.default_max_transaction_fee(),
366 Self::HookStore(transaction) => transaction.default_max_transaction_fee(),
367 }
368 }
369
370 fn maybe_chunk_data(&self) -> Option<&super::ChunkData> {
371 match self {
372 Self::AccountCreate(it) => it.maybe_chunk_data(),
373 Self::AccountUpdate(it) => it.maybe_chunk_data(),
374 Self::AccountDelete(it) => it.maybe_chunk_data(),
375 Self::AccountAllowanceApprove(it) => it.maybe_chunk_data(),
376 Self::AccountAllowanceDelete(it) => it.maybe_chunk_data(),
377 Self::ContractCreate(it) => it.maybe_chunk_data(),
378 Self::ContractUpdate(it) => it.maybe_chunk_data(),
379 Self::ContractDelete(it) => it.maybe_chunk_data(),
380 Self::ContractExecute(it) => it.maybe_chunk_data(),
381 Self::Transfer(it) => it.maybe_chunk_data(),
382 Self::TopicCreate(it) => it.maybe_chunk_data(),
383 Self::TopicUpdate(it) => it.maybe_chunk_data(),
384 Self::TopicDelete(it) => it.maybe_chunk_data(),
385 Self::TopicMessageSubmit(it) => it.maybe_chunk_data(),
386 Self::FileAppend(it) => it.maybe_chunk_data(),
387 Self::FileCreate(it) => it.maybe_chunk_data(),
388 Self::FileUpdate(it) => it.maybe_chunk_data(),
389 Self::FileDelete(it) => it.maybe_chunk_data(),
390 Self::Prng(it) => it.maybe_chunk_data(),
391 Self::TokenAssociate(it) => it.maybe_chunk_data(),
392 Self::TokenBurn(it) => it.maybe_chunk_data(),
393 Self::TokenCreate(it) => it.maybe_chunk_data(),
394 Self::TokenDelete(it) => it.maybe_chunk_data(),
395 Self::TokenDissociate(it) => it.maybe_chunk_data(),
396 Self::TokenFeeScheduleUpdate(it) => it.maybe_chunk_data(),
397 Self::TokenFreeze(it) => it.maybe_chunk_data(),
398 Self::TokenGrantKyc(it) => it.maybe_chunk_data(),
399 Self::TokenMint(it) => it.maybe_chunk_data(),
400 Self::TokenPause(it) => it.maybe_chunk_data(),
401 Self::TokenRevokeKyc(it) => it.maybe_chunk_data(),
402 Self::TokenUnfreeze(it) => it.maybe_chunk_data(),
403 Self::TokenUnpause(it) => it.maybe_chunk_data(),
404 Self::TokenUpdate(it) => it.maybe_chunk_data(),
405 Self::TokenWipe(it) => it.maybe_chunk_data(),
406 Self::SystemDelete(it) => it.maybe_chunk_data(),
407 Self::SystemUndelete(it) => it.maybe_chunk_data(),
408 Self::Freeze(it) => it.maybe_chunk_data(),
409 Self::ScheduleCreate(it) => it.maybe_chunk_data(),
410 Self::ScheduleSign(it) => it.maybe_chunk_data(),
411 Self::ScheduleDelete(it) => it.maybe_chunk_data(),
412 Self::Ethereum(it) => it.maybe_chunk_data(),
413 Self::TokenUpdateNfts(it) => it.maybe_chunk_data(),
414 Self::NodeCreate(it) => it.maybe_chunk_data(),
415 Self::NodeUpdate(it) => it.maybe_chunk_data(),
416 Self::NodeDelete(it) => it.maybe_chunk_data(),
417 Self::TokenReject(it) => it.maybe_chunk_data(),
418 Self::TokenAirdrop(it) => it.maybe_chunk_data(),
419 Self::TokenClaimAirdrop(it) => it.maybe_chunk_data(),
420 Self::TokenCancelAirdrop(it) => it.maybe_chunk_data(),
421 Self::Batch(it) => it.maybe_chunk_data(),
422 Self::HookStore(it) => it.maybe_chunk_data(),
423 }
424 }
425
426 fn wait_for_receipt(&self) -> bool {
427 match self {
428 Self::AccountCreate(it) => it.wait_for_receipt(),
429 Self::AccountUpdate(it) => it.wait_for_receipt(),
430 Self::AccountDelete(it) => it.wait_for_receipt(),
431 Self::AccountAllowanceApprove(it) => it.wait_for_receipt(),
432 Self::AccountAllowanceDelete(it) => it.wait_for_receipt(),
433 Self::ContractCreate(it) => it.wait_for_receipt(),
434 Self::ContractUpdate(it) => it.wait_for_receipt(),
435 Self::ContractDelete(it) => it.wait_for_receipt(),
436 Self::ContractExecute(it) => it.wait_for_receipt(),
437 Self::Transfer(it) => it.wait_for_receipt(),
438 Self::TopicCreate(it) => it.wait_for_receipt(),
439 Self::TopicUpdate(it) => it.wait_for_receipt(),
440 Self::TopicDelete(it) => it.wait_for_receipt(),
441 Self::TopicMessageSubmit(it) => it.wait_for_receipt(),
442 Self::FileAppend(it) => it.wait_for_receipt(),
443 Self::FileCreate(it) => it.wait_for_receipt(),
444 Self::FileUpdate(it) => it.wait_for_receipt(),
445 Self::FileDelete(it) => it.wait_for_receipt(),
446 Self::Prng(it) => it.wait_for_receipt(),
447 Self::TokenAssociate(it) => it.wait_for_receipt(),
448 Self::TokenBurn(it) => it.wait_for_receipt(),
449 Self::TokenCreate(it) => it.wait_for_receipt(),
450 Self::TokenDelete(it) => it.wait_for_receipt(),
451 Self::TokenDissociate(it) => it.wait_for_receipt(),
452 Self::TokenFeeScheduleUpdate(it) => it.wait_for_receipt(),
453 Self::TokenFreeze(it) => it.wait_for_receipt(),
454 Self::TokenGrantKyc(it) => it.wait_for_receipt(),
455 Self::TokenMint(it) => it.wait_for_receipt(),
456 Self::TokenPause(it) => it.wait_for_receipt(),
457 Self::TokenRevokeKyc(it) => it.wait_for_receipt(),
458 Self::TokenUnfreeze(it) => it.wait_for_receipt(),
459 Self::TokenUnpause(it) => it.wait_for_receipt(),
460 Self::TokenUpdate(it) => it.wait_for_receipt(),
461 Self::TokenWipe(it) => it.wait_for_receipt(),
462 Self::SystemDelete(it) => it.wait_for_receipt(),
463 Self::SystemUndelete(it) => it.wait_for_receipt(),
464 Self::Freeze(it) => it.wait_for_receipt(),
465 Self::ScheduleCreate(it) => it.wait_for_receipt(),
466 Self::ScheduleSign(it) => it.wait_for_receipt(),
467 Self::ScheduleDelete(it) => it.wait_for_receipt(),
468 Self::Ethereum(it) => it.wait_for_receipt(),
469 Self::TokenUpdateNfts(it) => it.wait_for_receipt(),
470 Self::NodeCreate(it) => it.wait_for_receipt(),
471 Self::NodeUpdate(it) => it.wait_for_receipt(),
472 Self::NodeDelete(it) => it.wait_for_receipt(),
473 Self::TokenReject(it) => it.wait_for_receipt(),
474 Self::TokenAirdrop(it) => it.wait_for_receipt(),
475 Self::TokenClaimAirdrop(it) => it.wait_for_receipt(),
476 Self::TokenCancelAirdrop(it) => it.wait_for_receipt(),
477 Self::Batch(it) => it.wait_for_receipt(),
478 Self::HookStore(it) => it.wait_for_receipt(),
479 }
480 }
481}
482
483impl TransactionExecute for AnyTransactionData {
484 fn execute(
485 &self,
486 channel: Channel,
487 request: services::Transaction,
488 ) -> BoxGrpcFuture<'_, services::TransactionResponse> {
489 match self {
490 Self::Transfer(transaction) => transaction.execute(channel, request),
491 Self::AccountCreate(transaction) => transaction.execute(channel, request),
492 Self::AccountUpdate(transaction) => transaction.execute(channel, request),
493 Self::AccountDelete(transaction) => transaction.execute(channel, request),
494 Self::AccountAllowanceApprove(transaction) => transaction.execute(channel, request),
495 Self::AccountAllowanceDelete(transaction) => transaction.execute(channel, request),
496 Self::ContractCreate(transaction) => transaction.execute(channel, request),
497 Self::ContractUpdate(transaction) => transaction.execute(channel, request),
498 Self::ContractDelete(transaction) => transaction.execute(channel, request),
499 Self::ContractExecute(transaction) => transaction.execute(channel, request),
500 Self::FileAppend(transaction) => transaction.execute(channel, request),
501 Self::FileCreate(transaction) => transaction.execute(channel, request),
502 Self::FileUpdate(transaction) => transaction.execute(channel, request),
503 Self::FileDelete(transaction) => transaction.execute(channel, request),
504 Self::Prng(transaction) => transaction.execute(channel, request),
505 Self::TokenAssociate(transaction) => transaction.execute(channel, request),
506 Self::TokenBurn(transaction) => transaction.execute(channel, request),
507 Self::TokenCreate(transaction) => transaction.execute(channel, request),
508 Self::TokenDelete(transaction) => transaction.execute(channel, request),
509 Self::TokenDissociate(transaction) => transaction.execute(channel, request),
510 Self::TokenFeeScheduleUpdate(transaction) => transaction.execute(channel, request),
511 Self::TokenFreeze(transaction) => transaction.execute(channel, request),
512 Self::TokenGrantKyc(transaction) => transaction.execute(channel, request),
513 Self::TokenMint(transaction) => transaction.execute(channel, request),
514 Self::TokenPause(transaction) => transaction.execute(channel, request),
515 Self::TokenRevokeKyc(transaction) => transaction.execute(channel, request),
516 Self::TokenUnfreeze(transaction) => transaction.execute(channel, request),
517 Self::TokenUnpause(transaction) => transaction.execute(channel, request),
518 Self::TokenUpdate(transaction) => transaction.execute(channel, request),
519 Self::TokenWipe(transaction) => transaction.execute(channel, request),
520 Self::TopicCreate(transaction) => transaction.execute(channel, request),
521 Self::TopicUpdate(transaction) => transaction.execute(channel, request),
522 Self::TopicDelete(transaction) => transaction.execute(channel, request),
523 Self::TopicMessageSubmit(transaction) => transaction.execute(channel, request),
524 Self::SystemDelete(transaction) => transaction.execute(channel, request),
525 Self::SystemUndelete(transaction) => transaction.execute(channel, request),
526 Self::Freeze(transaction) => transaction.execute(channel, request),
527 Self::ScheduleCreate(transaction) => transaction.execute(channel, request),
528 Self::ScheduleSign(transaction) => transaction.execute(channel, request),
529 Self::ScheduleDelete(transaction) => transaction.execute(channel, request),
530 Self::Ethereum(transaction) => transaction.execute(channel, request),
531 Self::TokenUpdateNfts(transaction) => transaction.execute(channel, request),
532 Self::NodeCreate(transaction) => transaction.execute(channel, request),
533 Self::NodeUpdate(transaction) => transaction.execute(channel, request),
534 Self::NodeDelete(transaction) => transaction.execute(channel, request),
535 Self::TokenReject(transaction) => transaction.execute(channel, request),
536 Self::TokenAirdrop(transaction) => transaction.execute(channel, request),
537 Self::TokenClaimAirdrop(transaction) => transaction.execute(channel, request),
538 Self::TokenCancelAirdrop(transaction) => transaction.execute(channel, request),
539 Self::Batch(transaction) => transaction.execute(channel, request),
540 Self::HookStore(transaction) => transaction.execute(channel, request),
541 }
542 }
543}
544
545impl TransactionExecuteChunked for AnyTransactionData {}
546
547impl ValidateChecksums for AnyTransactionData {
548 fn validate_checksums(&self, ledger_id: &RefLedgerId) -> Result<(), Error> {
549 match self {
550 Self::AccountCreate(transaction) => transaction.validate_checksums(ledger_id),
551 Self::AccountUpdate(transaction) => transaction.validate_checksums(ledger_id),
552 Self::AccountDelete(transaction) => transaction.validate_checksums(ledger_id),
553 Self::AccountAllowanceApprove(transaction) => transaction.validate_checksums(ledger_id),
554 Self::AccountAllowanceDelete(transaction) => transaction.validate_checksums(ledger_id),
555 Self::ContractCreate(transaction) => transaction.validate_checksums(ledger_id),
556 Self::ContractUpdate(transaction) => transaction.validate_checksums(ledger_id),
557 Self::ContractDelete(transaction) => transaction.validate_checksums(ledger_id),
558 Self::ContractExecute(transaction) => transaction.validate_checksums(ledger_id),
559 Self::Transfer(transaction) => transaction.validate_checksums(ledger_id),
560 Self::TopicCreate(transaction) => transaction.validate_checksums(ledger_id),
561 Self::TopicUpdate(transaction) => transaction.validate_checksums(ledger_id),
562 Self::TopicDelete(transaction) => transaction.validate_checksums(ledger_id),
563 Self::TopicMessageSubmit(transaction) => transaction.validate_checksums(ledger_id),
564 Self::FileAppend(transaction) => transaction.validate_checksums(ledger_id),
565 Self::FileCreate(transaction) => transaction.validate_checksums(ledger_id),
566 Self::FileUpdate(transaction) => transaction.validate_checksums(ledger_id),
567 Self::FileDelete(transaction) => transaction.validate_checksums(ledger_id),
568 Self::Prng(transaction) => transaction.validate_checksums(ledger_id),
569 Self::ScheduleCreate(transaction) => transaction.validate_checksums(ledger_id),
570 Self::ScheduleSign(transaction) => transaction.validate_checksums(ledger_id),
571 Self::ScheduleDelete(transaction) => transaction.validate_checksums(ledger_id),
572 Self::TokenAssociate(transaction) => transaction.validate_checksums(ledger_id),
573 Self::TokenBurn(transaction) => transaction.validate_checksums(ledger_id),
574 Self::TokenCreate(transaction) => transaction.validate_checksums(ledger_id),
575 Self::TokenDelete(transaction) => transaction.validate_checksums(ledger_id),
576 Self::TokenDissociate(transaction) => transaction.validate_checksums(ledger_id),
577 Self::TokenFeeScheduleUpdate(transaction) => transaction.validate_checksums(ledger_id),
578 Self::TokenFreeze(transaction) => transaction.validate_checksums(ledger_id),
579 Self::TokenGrantKyc(transaction) => transaction.validate_checksums(ledger_id),
580 Self::TokenMint(transaction) => transaction.validate_checksums(ledger_id),
581 Self::TokenPause(transaction) => transaction.validate_checksums(ledger_id),
582 Self::TokenRevokeKyc(transaction) => transaction.validate_checksums(ledger_id),
583 Self::TokenUnfreeze(transaction) => transaction.validate_checksums(ledger_id),
584 Self::TokenUnpause(transaction) => transaction.validate_checksums(ledger_id),
585 Self::TokenUpdate(transaction) => transaction.validate_checksums(ledger_id),
586 Self::TokenWipe(transaction) => transaction.validate_checksums(ledger_id),
587 Self::SystemDelete(transaction) => transaction.validate_checksums(ledger_id),
588 Self::SystemUndelete(transaction) => transaction.validate_checksums(ledger_id),
589 Self::Freeze(transaction) => transaction.validate_checksums(ledger_id),
590 Self::Ethereum(transaction) => transaction.validate_checksums(ledger_id),
591 Self::TokenUpdateNfts(transaction) => transaction.validate_checksums(ledger_id),
592 Self::NodeCreate(transaction) => transaction.validate_checksums(ledger_id),
593 Self::NodeUpdate(transaction) => transaction.validate_checksums(ledger_id),
594 Self::NodeDelete(transaction) => transaction.validate_checksums(ledger_id),
595 Self::TokenReject(transaction) => transaction.validate_checksums(ledger_id),
596 Self::TokenAirdrop(transaction) => transaction.validate_checksums(ledger_id),
597 Self::TokenClaimAirdrop(transaction) => transaction.validate_checksums(ledger_id),
598 Self::TokenCancelAirdrop(transaction) => transaction.validate_checksums(ledger_id),
599 Self::Batch(transaction) => transaction.validate_checksums(ledger_id),
600 Self::HookStore(transaction) => transaction.validate_checksums(ledger_id),
601 }
602 }
603}
604
605impl FromProtobuf<services::transaction_body::Data> for AnyTransactionData {
606 fn from_protobuf(pb: services::transaction_body::Data) -> crate::Result<Self>
607 where
608 Self: Sized,
609 {
610 use services::transaction_body::Data;
611 let data = match pb {
612 Data::ContractCall(pb) => data::ContractExecute::from_protobuf(pb)?.into(),
613 Data::ContractCreateInstance(pb) => data::ContractCreate::from_protobuf(pb)?.into(),
614 Data::ContractUpdateInstance(pb) => data::ContractUpdate::from_protobuf(pb)?.into(),
615 Data::ContractDeleteInstance(pb) => data::ContractDelete::from_protobuf(pb)?.into(),
616 Data::EthereumTransaction(pb) => data::Ethereum::from_protobuf(pb)?.into(),
617 Data::CryptoApproveAllowance(pb) => {
618 data::AccountAllowanceApprove::from_protobuf(pb)?.into()
619 }
620 Data::CryptoDeleteAllowance(pb) => {
621 data::AccountAllowanceDelete::from_protobuf(pb)?.into()
622 }
623 Data::CryptoCreateAccount(pb) => data::AccountCreate::from_protobuf(pb)?.into(),
624 Data::CryptoDelete(pb) => data::AccountDelete::from_protobuf(pb)?.into(),
625 Data::CryptoTransfer(pb) => data::Transfer::from_protobuf(pb)?.into(),
626 Data::CryptoUpdateAccount(pb) => data::AccountUpdate::from_protobuf(pb)?.into(),
627 Data::FileAppend(pb) => data::FileAppend::from_protobuf(pb)?.into(),
628 Data::FileCreate(pb) => data::FileCreate::from_protobuf(pb)?.into(),
629 Data::FileDelete(pb) => data::FileDelete::from_protobuf(pb)?.into(),
630 Data::FileUpdate(pb) => data::FileUpdate::from_protobuf(pb)?.into(),
631 Data::UtilPrng(pb) => data::Prng::from_protobuf(pb)?.into(),
632 Data::SystemDelete(pb) => data::SystemDelete::from_protobuf(pb)?.into(),
633 Data::SystemUndelete(pb) => data::SystemUndelete::from_protobuf(pb)?.into(),
634 Data::Freeze(pb) => data::Freeze::from_protobuf(pb)?.into(),
635 Data::ConsensusCreateTopic(pb) => data::TopicCreate::from_protobuf(pb)?.into(),
636 Data::ConsensusUpdateTopic(pb) => data::TopicUpdate::from_protobuf(pb)?.into(),
637 Data::ConsensusDeleteTopic(pb) => data::TopicDelete::from_protobuf(pb)?.into(),
638 Data::ConsensusSubmitMessage(pb) => data::TopicMessageSubmit::from_protobuf(pb)?.into(),
639 Data::TokenCreation(pb) => data::TokenCreate::from_protobuf(pb)?.into(),
640 Data::TokenFreeze(pb) => data::TokenFreeze::from_protobuf(pb)?.into(),
641 Data::TokenUnfreeze(pb) => data::TokenUnfreeze::from_protobuf(pb)?.into(),
642 Data::TokenGrantKyc(pb) => data::TokenGrantKyc::from_protobuf(pb)?.into(),
643 Data::TokenRevokeKyc(pb) => data::TokenRevokeKyc::from_protobuf(pb)?.into(),
644 Data::TokenDeletion(pb) => data::TokenDelete::from_protobuf(pb)?.into(),
645 Data::TokenUpdate(pb) => data::TokenUpdate::from_protobuf(pb)?.into(),
646 Data::TokenMint(pb) => data::TokenMint::from_protobuf(pb)?.into(),
647 Data::TokenBurn(pb) => data::TokenBurn::from_protobuf(pb)?.into(),
648 Data::TokenWipe(pb) => data::TokenWipe::from_protobuf(pb)?.into(),
649 Data::TokenAssociate(pb) => data::TokenAssociate::from_protobuf(pb)?.into(),
650 Data::TokenDissociate(pb) => data::TokenDissociate::from_protobuf(pb)?.into(),
651 Data::TokenFeeScheduleUpdate(pb) => {
652 data::TokenFeeScheduleUpdate::from_protobuf(pb)?.into()
653 }
654 Data::TokenPause(pb) => data::TokenPause::from_protobuf(pb)?.into(),
655 Data::TokenUnpause(pb) => data::TokenUnpause::from_protobuf(pb)?.into(),
656 Data::TokenReject(pb) => data::TokenReject::from_protobuf(pb)?.into(),
657 Data::ScheduleCreate(pb) => data::ScheduleCreate::from_protobuf(pb)?.into(),
658 Data::ScheduleDelete(pb) => data::ScheduleDelete::from_protobuf(pb)?.into(),
659 Data::ScheduleSign(pb) => data::ScheduleSign::from_protobuf(pb)?.into(),
660 Data::TokenUpdateNfts(pb) => data::TokenUpdateNfts::from_protobuf(pb)?.into(),
661 Data::NodeCreate(pb) => data::NodeCreate::from_protobuf(pb)?.into(),
662 Data::NodeUpdate(pb) => data::NodeUpdate::from_protobuf(pb)?.into(),
663 Data::NodeDelete(pb) => data::NodeDelete::from_protobuf(pb)?.into(),
664 Data::TokenAirdrop(pb) => data::TokenAirdrop::from_protobuf(pb)?.into(),
665 Data::TokenClaimAirdrop(pb) => data::TokenClaimAirdrop::from_protobuf(pb)?.into(),
666 Data::TokenCancelAirdrop(pb) => data::TokenCancelAirdrop::from_protobuf(pb)?.into(),
667 Data::CryptoAddLiveHash(_) => {
668 return Err(Error::from_protobuf(
669 "unsupported transaction `AddLiveHashTransaction`",
670 ))
671 }
672 Data::CryptoDeleteLiveHash(_) => {
673 return Err(Error::from_protobuf(
674 "unsupported transaction `DeleteLiveHashTransaction`",
675 ))
676 }
677 Data::UncheckedSubmit(_) => {
678 return Err(Error::from_protobuf(
679 "unsupported transaction `UncheckedSubmitTransaction`",
680 ))
681 }
682 Data::NodeStakeUpdate(_) => {
683 return Err(Error::from_protobuf(
684 "unsupported transaction `NodeStakeUpdateTransaction`",
685 ))
686 }
687 Data::HookStore(pb) => data::HookStore::from_protobuf(pb)?.into(),
688 Data::HookDispatch(_) => {
689 return Err(Error::from_protobuf(
690 "unsupported transaction `HookDispatchTransaction`",
691 ))
692 }
693 Data::AtomicBatch(_) => {
694 return Err(Error::from_protobuf(
695 "unsupported transaction `AtomicBatchTransaction`",
696 ))
697 }
698 Data::LedgerIdPublication(_) => {
699 return Err(Error::from_protobuf(
700 "unsupported transaction `LedgerIdPublicationTransaction`",
701 ))
702 }
703 Data::RegisteredNodeCreate(_) => {
704 return Err(Error::from_protobuf(
705 "unsupported transaction `RegisteredNodeCreateTransaction`",
706 ))
707 }
708 Data::RegisteredNodeUpdate(_) => {
709 return Err(Error::from_protobuf(
710 "unsupported transaction `RegisteredNodeUpdateTransaction`",
711 ))
712 }
713 Data::RegisteredNodeDelete(_) => {
714 return Err(Error::from_protobuf(
715 "unsupported transaction `RegisteredNodeDeleteTransaction`",
716 ))
717 }
718 };
719
720 Ok(data)
721 }
722}
723
724impl AnyTransactionData {
725 #[allow(clippy::too_many_lines)]
727 fn from_protobuf(data_chunks: ServicesTransactionDataList) -> crate::Result<Self> {
728 fn try_into_only_element<T>(v: Vec<T>) -> crate::Result<T> {
729 match <[T; 1]>::try_from(v) {
730 Ok([element]) => Ok(element),
731 _ => Err(Error::from_protobuf("chunks in non chunkable transaction")),
732 }
733 }
734
735 let data = match data_chunks {
736 ServicesTransactionDataList::AccountCreate(v) => {
737 data::AccountCreate::from_protobuf(try_into_only_element(v)?)?.into()
738 }
739 ServicesTransactionDataList::AccountUpdate(v) => {
740 data::AccountUpdate::from_protobuf(try_into_only_element(v)?)?.into()
741 }
742 ServicesTransactionDataList::AccountDelete(v) => {
743 data::AccountDelete::from_protobuf(try_into_only_element(v)?)?.into()
744 }
745 ServicesTransactionDataList::AccountAllowanceApprove(v) => {
746 data::AccountAllowanceApprove::from_protobuf(try_into_only_element(v)?)?.into()
747 }
748 ServicesTransactionDataList::AccountAllowanceDelete(v) => {
749 data::AccountAllowanceDelete::from_protobuf(try_into_only_element(v)?)?.into()
750 }
751 ServicesTransactionDataList::ContractCreate(v) => {
752 data::ContractCreate::from_protobuf(try_into_only_element(v)?)?.into()
753 }
754 ServicesTransactionDataList::ContractUpdate(v) => {
755 data::ContractUpdate::from_protobuf(try_into_only_element(v)?)?.into()
756 }
757 ServicesTransactionDataList::ContractDelete(v) => {
758 data::ContractDelete::from_protobuf(try_into_only_element(v)?)?.into()
759 }
760 ServicesTransactionDataList::ContractExecute(v) => {
761 data::ContractExecute::from_protobuf(try_into_only_element(v)?)?.into()
762 }
763 ServicesTransactionDataList::Transfer(v) => {
764 data::Transfer::from_protobuf(try_into_only_element(v)?)?.into()
765 }
766 ServicesTransactionDataList::TopicCreate(v) => {
767 data::TopicCreate::from_protobuf(try_into_only_element(v)?)?.into()
768 }
769 ServicesTransactionDataList::TopicUpdate(v) => {
770 data::TopicUpdate::from_protobuf(try_into_only_element(v)?)?.into()
771 }
772 ServicesTransactionDataList::TopicDelete(v) => {
773 data::TopicDelete::from_protobuf(try_into_only_element(v)?)?.into()
774 }
775 ServicesTransactionDataList::TopicMessageSubmit(v) => {
776 data::TopicMessageSubmit::from_protobuf(v)?.into()
777 }
778 ServicesTransactionDataList::FileAppend(v) => {
779 data::FileAppend::from_protobuf(v)?.into()
780 }
781 ServicesTransactionDataList::FileCreate(v) => {
782 data::FileCreate::from_protobuf(try_into_only_element(v)?)?.into()
783 }
784 ServicesTransactionDataList::FileUpdate(v) => {
785 data::FileUpdate::from_protobuf(try_into_only_element(v)?)?.into()
786 }
787 ServicesTransactionDataList::FileDelete(v) => {
788 data::FileDelete::from_protobuf(try_into_only_element(v)?)?.into()
789 }
790 ServicesTransactionDataList::TokenAssociate(v) => {
791 data::TokenAssociate::from_protobuf(try_into_only_element(v)?)?.into()
792 }
793 ServicesTransactionDataList::TokenBurn(v) => {
794 data::TokenBurn::from_protobuf(try_into_only_element(v)?)?.into()
795 }
796 ServicesTransactionDataList::TokenCreate(v) => {
797 data::TokenCreate::from_protobuf(try_into_only_element(v)?)?.into()
798 }
799 ServicesTransactionDataList::TokenDelete(v) => {
800 data::TokenDelete::from_protobuf(try_into_only_element(v)?)?.into()
801 }
802 ServicesTransactionDataList::TokenDissociate(v) => {
803 data::TokenDissociate::from_protobuf(try_into_only_element(v)?)?.into()
804 }
805 ServicesTransactionDataList::TokenFeeScheduleUpdate(v) => {
806 data::TokenFeeScheduleUpdate::from_protobuf(try_into_only_element(v)?)?.into()
807 }
808 ServicesTransactionDataList::TokenFreeze(v) => {
809 data::TokenFreeze::from_protobuf(try_into_only_element(v)?)?.into()
810 }
811 ServicesTransactionDataList::TokenGrantKyc(v) => {
812 data::TokenGrantKyc::from_protobuf(try_into_only_element(v)?)?.into()
813 }
814 ServicesTransactionDataList::TokenMint(v) => {
815 data::TokenMint::from_protobuf(try_into_only_element(v)?)?.into()
816 }
817 ServicesTransactionDataList::TokenPause(v) => {
818 data::TokenPause::from_protobuf(try_into_only_element(v)?)?.into()
819 }
820 ServicesTransactionDataList::TokenRevokeKyc(v) => {
821 data::TokenRevokeKyc::from_protobuf(try_into_only_element(v)?)?.into()
822 }
823 ServicesTransactionDataList::TokenUnfreeze(v) => {
824 data::TokenUnfreeze::from_protobuf(try_into_only_element(v)?)?.into()
825 }
826 ServicesTransactionDataList::TokenUnpause(v) => {
827 data::TokenUnpause::from_protobuf(try_into_only_element(v)?)?.into()
828 }
829 ServicesTransactionDataList::TokenUpdate(v) => {
830 data::TokenUpdate::from_protobuf(try_into_only_element(v)?)?.into()
831 }
832 ServicesTransactionDataList::TokenWipe(v) => {
833 data::TokenWipe::from_protobuf(try_into_only_element(v)?)?.into()
834 }
835 ServicesTransactionDataList::SystemDelete(v) => {
836 data::SystemDelete::from_protobuf(try_into_only_element(v)?)?.into()
837 }
838 ServicesTransactionDataList::SystemUndelete(v) => {
839 data::SystemUndelete::from_protobuf(try_into_only_element(v)?)?.into()
840 }
841 ServicesTransactionDataList::Freeze(v) => {
842 data::Freeze::from_protobuf(try_into_only_element(v)?)?.into()
843 }
844 ServicesTransactionDataList::ScheduleCreate(v) => {
845 data::ScheduleCreate::from_protobuf(try_into_only_element(v)?)?.into()
846 }
847 ServicesTransactionDataList::ScheduleSign(v) => {
848 data::ScheduleSign::from_protobuf(try_into_only_element(v)?)?.into()
849 }
850 ServicesTransactionDataList::ScheduleDelete(v) => {
851 data::ScheduleDelete::from_protobuf(try_into_only_element(v)?)?.into()
852 }
853 ServicesTransactionDataList::Ethereum(v) => {
854 data::Ethereum::from_protobuf(try_into_only_element(v)?)?.into()
855 }
856 ServicesTransactionDataList::UtilPrng(v) => {
857 data::Prng::from_protobuf(try_into_only_element(v)?)?.into()
858 }
859 ServicesTransactionDataList::TokenUpdateNfts(v) => {
860 data::TokenUpdateNfts::from_protobuf(try_into_only_element(v)?)?.into()
861 }
862 ServicesTransactionDataList::TokenReject(v) => {
863 data::TokenReject::from_protobuf(try_into_only_element(v)?)?.into()
864 }
865 ServicesTransactionDataList::NodeCreate(v) => {
866 data::NodeCreate::from_protobuf(try_into_only_element(v)?)?.into()
867 }
868 ServicesTransactionDataList::NodeUpdate(v) => {
869 data::NodeUpdate::from_protobuf(try_into_only_element(v)?)?.into()
870 }
871 ServicesTransactionDataList::NodeDelete(v) => {
872 data::NodeDelete::from_protobuf(try_into_only_element(v)?)?.into()
873 }
874 ServicesTransactionDataList::TokenAirdrop(v) => {
875 data::TokenAirdrop::from_protobuf(try_into_only_element(v)?)?.into()
876 }
877 ServicesTransactionDataList::TokenClaimAirdrop(v) => {
878 data::TokenClaimAirdrop::from_protobuf(try_into_only_element(v)?)?.into()
879 }
880 ServicesTransactionDataList::TokenCancelAirdrop(v) => {
881 data::TokenCancelAirdrop::from_protobuf(try_into_only_element(v)?)?.into()
882 }
883 ServicesTransactionDataList::AtomicBatch(v) => {
884 data::Batch::from_protobuf(try_into_only_element(v)?)?.into()
885 }
886 };
887
888 Ok(data)
889 }
890}
891
892impl AnyTransaction {
893 pub(super) fn from_protobuf(
894 first_body: services::TransactionBody,
895 data_chunks: Vec<services::transaction_body::Data>,
896 ) -> crate::Result<Self> {
897 let transaction_id: Option<TransactionId> = match first_body.transaction_id {
898 Some(id) => match TransactionId::from_protobuf(id) {
899 Ok(id) => Some(id),
900 Err(_) => None, },
902 None => None,
903 };
904
905 let node_account_ids = match first_body.node_account_id {
906 Some(id) => match AccountId::from_protobuf(id) {
907 Ok(id) => Some(vec![id]),
908 Err(_) => None, },
910 None => None,
911 };
912
913 let transaction_fee = Hbar::from_tinybars(first_body.transaction_fee as i64);
915
916 if data_chunks.is_empty() {
918 return Err(Error::from_protobuf("Transaction data is missing"));
919 }
920
921 let transaction_data = match AnyTransactionData::from_protobuf(
922 ServicesTransactionDataList::from_protobuf(data_chunks)?,
923 ) {
924 Ok(data) => data,
925 Err(e) => return Err(e),
926 };
927
928 Ok(Transaction {
929 body: TransactionBody {
930 data: transaction_data,
931 transaction_memo: first_body.memo,
932 node_account_ids,
933 transaction_valid_duration: first_body.transaction_valid_duration.map(Into::into),
934 max_transaction_fee: Some(transaction_fee),
935 transaction_id,
936 operator: None,
937 is_frozen: false,
938 regenerate_transaction_id: Some(false),
939 custom_fee_limits: first_body
940 .max_custom_fees
941 .into_iter()
942 .map(CustomFeeLimit::from_protobuf)
943 .collect::<Result<Vec<_>, _>>()?,
944 batch_key: first_body
945 .batch_key
946 .map(|key| crate::protobuf::FromProtobuf::from_protobuf(key).unwrap()),
947 high_volume: first_body.high_volume,
948 },
949 signers: Vec::new(),
950 sources: None,
951 grpc_deadline: None,
952 request_timeout: None,
953 })
954 }
955}
956
957#[derive(Debug)]
959enum ServicesTransactionDataList {
960 AccountCreate(Vec<services::CryptoCreateTransactionBody>),
961 AccountUpdate(Vec<services::CryptoUpdateTransactionBody>),
962 AccountDelete(Vec<services::CryptoDeleteTransactionBody>),
963 AccountAllowanceApprove(Vec<services::CryptoApproveAllowanceTransactionBody>),
964 AccountAllowanceDelete(Vec<services::CryptoDeleteAllowanceTransactionBody>),
965 ContractCreate(Vec<services::ContractCreateTransactionBody>),
966 ContractUpdate(Vec<services::ContractUpdateTransactionBody>),
967 ContractDelete(Vec<services::ContractDeleteTransactionBody>),
968 ContractExecute(Vec<services::ContractCallTransactionBody>),
969 Transfer(Vec<services::CryptoTransferTransactionBody>),
970 TopicCreate(Vec<services::ConsensusCreateTopicTransactionBody>),
971 TopicUpdate(Vec<services::ConsensusUpdateTopicTransactionBody>),
972 TopicDelete(Vec<services::ConsensusDeleteTopicTransactionBody>),
973 TopicMessageSubmit(Vec<services::ConsensusSubmitMessageTransactionBody>),
974 FileAppend(Vec<services::FileAppendTransactionBody>),
975 FileCreate(Vec<services::FileCreateTransactionBody>),
976 FileUpdate(Vec<services::FileUpdateTransactionBody>),
977 FileDelete(Vec<services::FileDeleteTransactionBody>),
978 TokenAssociate(Vec<services::TokenAssociateTransactionBody>),
979 TokenBurn(Vec<services::TokenBurnTransactionBody>),
980 TokenCreate(Vec<services::TokenCreateTransactionBody>),
981 TokenDelete(Vec<services::TokenDeleteTransactionBody>),
982 TokenDissociate(Vec<services::TokenDissociateTransactionBody>),
983 TokenFeeScheduleUpdate(Vec<services::TokenFeeScheduleUpdateTransactionBody>),
984 TokenFreeze(Vec<services::TokenFreezeAccountTransactionBody>),
985 TokenGrantKyc(Vec<services::TokenGrantKycTransactionBody>),
986 TokenMint(Vec<services::TokenMintTransactionBody>),
987 TokenPause(Vec<services::TokenPauseTransactionBody>),
988 TokenRevokeKyc(Vec<services::TokenRevokeKycTransactionBody>),
989 TokenUnfreeze(Vec<services::TokenUnfreezeAccountTransactionBody>),
990 TokenUnpause(Vec<services::TokenUnpauseTransactionBody>),
991 TokenUpdate(Vec<services::TokenUpdateTransactionBody>),
992 TokenWipe(Vec<services::TokenWipeAccountTransactionBody>),
993 TokenUpdateNfts(Vec<services::TokenUpdateNftsTransactionBody>),
994 TokenReject(Vec<services::TokenRejectTransactionBody>),
995 SystemDelete(Vec<services::SystemDeleteTransactionBody>),
996 SystemUndelete(Vec<services::SystemUndeleteTransactionBody>),
997 Freeze(Vec<services::FreezeTransactionBody>),
998 ScheduleCreate(Vec<services::ScheduleCreateTransactionBody>),
999 ScheduleSign(Vec<services::ScheduleSignTransactionBody>),
1000 ScheduleDelete(Vec<services::ScheduleDeleteTransactionBody>),
1001 Ethereum(Vec<services::EthereumTransactionBody>),
1002 UtilPrng(Vec<services::UtilPrngTransactionBody>),
1003 NodeCreate(Vec<services::NodeCreateTransactionBody>),
1004 NodeUpdate(Vec<services::NodeUpdateTransactionBody>),
1005 NodeDelete(Vec<services::NodeDeleteTransactionBody>),
1006 TokenAirdrop(Vec<services::TokenAirdropTransactionBody>),
1007 TokenClaimAirdrop(Vec<services::TokenClaimAirdropTransactionBody>),
1008 TokenCancelAirdrop(Vec<services::TokenCancelAirdropTransactionBody>),
1009 AtomicBatch(Vec<services::AtomicBatchTransactionBody>),
1010}
1011
1012impl FromProtobuf<Vec<services::transaction_body::Data>> for ServicesTransactionDataList {
1013 fn from_protobuf(pb: Vec<services::transaction_body::Data>) -> crate::Result<Self> {
1014 use services::transaction_body::Data;
1015
1016 fn make_vec<T>(first: T, cap: usize) -> Vec<T> {
1017 let mut v = Vec::with_capacity(cap);
1018 v.push(first);
1019 v
1020 }
1021
1022 let len = pb.len();
1023
1024 let mut iter = pb.into_iter();
1025
1026 let first = iter
1027 .next()
1028 .expect("empty transaction data list (should be handled earlier up the pipeline)");
1029
1030 let mut value = match first {
1032 Data::ContractCall(it) => Self::ContractExecute(make_vec(it, len)),
1033 Data::ContractCreateInstance(it) => Self::ContractCreate(make_vec(it, len)),
1034 Data::ContractUpdateInstance(it) => Self::ContractUpdate(make_vec(it, len)),
1035 Data::ContractDeleteInstance(it) => Self::ContractDelete(make_vec(it, len)),
1036 Data::EthereumTransaction(it) => Self::Ethereum(make_vec(it, len)),
1037 Data::CryptoApproveAllowance(it) => Self::AccountAllowanceApprove(make_vec(it, len)),
1038 Data::CryptoDeleteAllowance(it) => Self::AccountAllowanceDelete(make_vec(it, len)),
1039 Data::CryptoCreateAccount(it) => Self::AccountCreate(make_vec(it, len)),
1040 Data::CryptoDelete(it) => Self::AccountDelete(make_vec(it, len)),
1041 Data::CryptoTransfer(it) => Self::Transfer(make_vec(it, len)),
1042 Data::CryptoUpdateAccount(it) => Self::AccountUpdate(make_vec(it, len)),
1043 Data::FileAppend(it) => Self::FileAppend(make_vec(it, len)),
1044 Data::FileCreate(it) => Self::FileCreate(make_vec(it, len)),
1045 Data::FileDelete(it) => Self::FileDelete(make_vec(it, len)),
1046 Data::FileUpdate(it) => Self::FileUpdate(make_vec(it, len)),
1047 Data::SystemDelete(it) => Self::SystemDelete(make_vec(it, len)),
1048 Data::SystemUndelete(it) => Self::SystemUndelete(make_vec(it, len)),
1049 Data::Freeze(it) => Self::Freeze(make_vec(it, len)),
1050 Data::ConsensusCreateTopic(it) => Self::TopicCreate(make_vec(it, len)),
1051 Data::ConsensusUpdateTopic(it) => Self::TopicUpdate(make_vec(it, len)),
1052 Data::ConsensusDeleteTopic(it) => Self::TopicDelete(make_vec(it, len)),
1053 Data::ConsensusSubmitMessage(it) => Self::TopicMessageSubmit(make_vec(it, len)),
1054 Data::TokenCreation(it) => Self::TokenCreate(make_vec(it, len)),
1055 Data::TokenFreeze(it) => Self::TokenFreeze(make_vec(it, len)),
1056 Data::TokenUnfreeze(it) => Self::TokenUnfreeze(make_vec(it, len)),
1057 Data::TokenGrantKyc(it) => Self::TokenGrantKyc(make_vec(it, len)),
1058 Data::TokenRevokeKyc(it) => Self::TokenRevokeKyc(make_vec(it, len)),
1059 Data::TokenDeletion(it) => Self::TokenDelete(make_vec(it, len)),
1060 Data::TokenUpdate(it) => Self::TokenUpdate(make_vec(it, len)),
1061 Data::TokenMint(it) => Self::TokenMint(make_vec(it, len)),
1062 Data::TokenBurn(it) => Self::TokenBurn(make_vec(it, len)),
1063 Data::TokenWipe(it) => Self::TokenWipe(make_vec(it, len)),
1064 Data::TokenAssociate(it) => Self::TokenAssociate(make_vec(it, len)),
1065 Data::TokenDissociate(it) => Self::TokenDissociate(make_vec(it, len)),
1066 Data::TokenFeeScheduleUpdate(it) => Self::TokenFeeScheduleUpdate(make_vec(it, len)),
1067 Data::TokenPause(it) => Self::TokenPause(make_vec(it, len)),
1068 Data::TokenUnpause(it) => Self::TokenUnpause(make_vec(it, len)),
1069 Data::TokenReject(it) => Self::TokenReject(make_vec(it, len)),
1070 Data::ScheduleCreate(it) => Self::ScheduleCreate(make_vec(it, len)),
1071 Data::ScheduleDelete(it) => Self::ScheduleDelete(make_vec(it, len)),
1072 Data::ScheduleSign(it) => Self::ScheduleSign(make_vec(it, len)),
1073 Data::UtilPrng(it) => Self::UtilPrng(make_vec(it, len)),
1074 Data::TokenUpdateNfts(it) => Self::TokenUpdateNfts(make_vec(it, len)),
1075 Data::NodeCreate(it) => Self::NodeCreate(make_vec(it, len)),
1076 Data::NodeUpdate(it) => Self::NodeUpdate(make_vec(it, len)),
1077 Data::NodeDelete(it) => Self::NodeDelete(make_vec(it, len)),
1078 Data::TokenAirdrop(it) => Self::TokenAirdrop(make_vec(it, len)),
1079 Data::TokenClaimAirdrop(it) => Self::TokenClaimAirdrop(make_vec(it, len)),
1080 Data::TokenCancelAirdrop(it) => Self::TokenCancelAirdrop(make_vec(it, len)),
1081 Data::CryptoAddLiveHash(_) => {
1082 return Err(Error::from_protobuf(
1083 "unsupported transaction `AddLiveHashTransaction`",
1084 ))
1085 }
1086 Data::CryptoDeleteLiveHash(_) => {
1087 return Err(Error::from_protobuf(
1088 "unsupported transaction `DeleteLiveHashTransaction`",
1089 ))
1090 }
1091
1092 Data::UncheckedSubmit(_) => {
1093 return Err(Error::from_protobuf(
1094 "unsupported transaction `UncheckedSubmitTransaction`",
1095 ))
1096 }
1097 Data::NodeStakeUpdate(_) => {
1098 return Err(Error::from_protobuf(
1099 "unsupported transaction `NodeStakeUpdateTransaction`",
1100 ))
1101 }
1102 Data::HookStore(_) => {
1103 return Err(Error::from_protobuf("HookStore transactions cannot be chunked"))
1104 }
1105 Data::HookDispatch(_) => {
1106 return Err(Error::from_protobuf("HookDispatch transactions are not supported"))
1107 }
1108 Data::AtomicBatch(_) => {
1109 return Err(Error::from_protobuf("AtomicBatch transactions are not supported"))
1110 }
1111 Data::LedgerIdPublication(_) => {
1112 return Err(Error::from_protobuf(
1113 "LedgerIdPublication transactions are not supported",
1114 ))
1115 }
1116 Data::RegisteredNodeCreate(_) => {
1117 return Err(Error::from_protobuf(
1118 "RegisteredNodeCreate transactions are not supported",
1119 ))
1120 }
1121 Data::RegisteredNodeUpdate(_) => {
1122 return Err(Error::from_protobuf(
1123 "RegisteredNodeUpdate transactions are not supported",
1124 ))
1125 }
1126 Data::RegisteredNodeDelete(_) => {
1127 return Err(Error::from_protobuf(
1128 "RegisteredNodeDelete transactions are not supported",
1129 ))
1130 }
1131 };
1132
1133 for transaction in iter {
1134 match (&mut value, transaction) {
1135 (Self::AccountCreate(v), Data::CryptoCreateAccount(element)) => v.push(element),
1136 (Self::AccountUpdate(v), Data::CryptoUpdateAccount(element)) => v.push(element),
1137 (Self::AccountDelete(v), Data::CryptoDelete(element)) => v.push(element),
1138 (Self::AccountAllowanceApprove(v), Data::CryptoApproveAllowance(element)) => {
1139 v.push(element);
1140 }
1141 (Self::AccountAllowanceDelete(v), Data::CryptoDeleteAllowance(element)) => {
1142 v.push(element);
1143 }
1144 (Self::ContractCreate(v), Data::ContractCreateInstance(element)) => v.push(element),
1145 (Self::ContractUpdate(v), Data::ContractUpdateInstance(element)) => v.push(element),
1146 (Self::ContractDelete(v), Data::ContractDeleteInstance(element)) => v.push(element),
1147 (Self::ContractExecute(v), Data::ContractCall(element)) => v.push(element),
1148 (Self::Transfer(v), Data::CryptoTransfer(element)) => v.push(element),
1149 (Self::TopicCreate(v), Data::ConsensusCreateTopic(element)) => v.push(element),
1150 (Self::TopicUpdate(v), Data::ConsensusUpdateTopic(element)) => v.push(element),
1151 (Self::TopicDelete(v), Data::ConsensusDeleteTopic(element)) => v.push(element),
1152 (Self::TopicMessageSubmit(v), Data::ConsensusSubmitMessage(element)) => {
1153 v.push(element);
1154 }
1155 (Self::FileAppend(v), Data::FileAppend(element)) => v.push(element),
1156 (Self::FileCreate(v), Data::FileCreate(element)) => v.push(element),
1157 (Self::FileUpdate(v), Data::FileUpdate(element)) => v.push(element),
1158 (Self::FileDelete(v), Data::FileDelete(element)) => v.push(element),
1159 (Self::TokenAssociate(v), Data::TokenAssociate(element)) => v.push(element),
1160 (Self::TokenBurn(v), Data::TokenBurn(element)) => v.push(element),
1161 (Self::TokenCreate(v), Data::TokenCreation(element)) => v.push(element),
1162 (Self::TokenDelete(v), Data::TokenDeletion(element)) => v.push(element),
1163 (Self::TokenDissociate(v), Data::TokenDissociate(element)) => v.push(element),
1164 (Self::TokenFeeScheduleUpdate(v), Data::TokenFeeScheduleUpdate(element)) => {
1165 v.push(element);
1166 }
1167 (Self::TokenFreeze(v), Data::TokenFreeze(element)) => v.push(element),
1168 (Self::TokenGrantKyc(v), Data::TokenGrantKyc(element)) => v.push(element),
1169 (Self::TokenMint(v), Data::TokenMint(element)) => v.push(element),
1170 (Self::TokenPause(v), Data::TokenPause(element)) => v.push(element),
1171 (Self::TokenRevokeKyc(v), Data::TokenRevokeKyc(element)) => v.push(element),
1172 (Self::TokenUnfreeze(v), Data::TokenUnfreeze(element)) => v.push(element),
1173 (Self::TokenUnpause(v), Data::TokenUnpause(element)) => v.push(element),
1174 (Self::TokenUpdate(v), Data::TokenUpdate(element)) => v.push(element),
1175 (Self::TokenWipe(v), Data::TokenWipe(element)) => v.push(element),
1176 (Self::SystemDelete(v), Data::SystemDelete(element)) => v.push(element),
1177 (Self::SystemUndelete(v), Data::SystemUndelete(element)) => v.push(element),
1178 (Self::Freeze(v), Data::Freeze(element)) => v.push(element),
1179 (Self::ScheduleCreate(v), Data::ScheduleCreate(element)) => v.push(element),
1180 (Self::ScheduleSign(v), Data::ScheduleSign(element)) => v.push(element),
1181 (Self::ScheduleDelete(v), Data::ScheduleDelete(element)) => v.push(element),
1182 (Self::Ethereum(v), Data::EthereumTransaction(element)) => v.push(element),
1183 (Self::UtilPrng(v), Data::UtilPrng(element)) => v.push(element),
1184 (Self::TokenAirdrop(v), Data::TokenAirdrop(element)) => v.push(element),
1185 (Self::TokenClaimAirdrop(v), Data::TokenClaimAirdrop(element)) => v.push(element),
1186 (Self::TokenCancelAirdrop(v), Data::TokenCancelAirdrop(element)) => v.push(element),
1187 (Self::AtomicBatch(v), Data::AtomicBatch(element)) => v.push(element),
1188 _ => return Err(Error::from_protobuf("mismatched transaction types")),
1189 }
1190 }
1191
1192 Ok(value)
1193 }
1194}
1195
1196impl AnyTransaction {
1197 pub fn downcast<D>(self) -> Result<D, Self>
1202 where
1203 Self: DowncastOwned<D>,
1204 {
1205 self.downcast_owned()
1206 }
1207}
1208
1209macro_rules! impl_cast_any {
1214 ($($id:ident),+$(,)?) => {
1215 $(
1216 impl $crate::downcast::DowncastOwned<data::$id> for AnyTransactionData {
1217 fn downcast_owned(self) -> Result<data::$id, Self> {
1218 let Self::$id(data) = self else {
1219 return Err(self)
1220 };
1221
1222 Ok(data)
1223 }
1224 }
1225
1226 impl From<Transaction<data::$id>> for AnyTransaction {
1227 fn from(transaction: Transaction<data::$id>) -> Self {
1228 Self {
1229 body: TransactionBody {
1230 data: transaction.body.data.into(),
1231 node_account_ids: transaction.body.node_account_ids,
1232 transaction_valid_duration: transaction.body.transaction_valid_duration,
1233 max_transaction_fee: transaction.body.max_transaction_fee,
1234 transaction_memo: transaction.body.transaction_memo,
1235 transaction_id: transaction.body.transaction_id,
1236 operator: transaction.body.operator,
1237 is_frozen: transaction.body.is_frozen,
1238 regenerate_transaction_id: transaction.body.regenerate_transaction_id,
1239 custom_fee_limits: transaction.body.custom_fee_limits,
1240 batch_key: transaction.body.batch_key,
1241 high_volume: transaction.body.high_volume,
1242 },
1243 signers: transaction.signers,
1244 sources: transaction.sources,
1245 grpc_deadline: transaction.grpc_deadline,
1246 request_timeout: transaction.request_timeout,
1247 }
1248 }
1249 }
1250 )*
1251
1252 #[allow(non_snake_case)]
1253 mod ___private_impl_cast_any {
1254 use super::AnyTransactionData;
1255 fn _assert_exhaustive(d: AnyTransactionData)
1257 {
1258 match d {
1259 $(AnyTransactionData::$id(_) => {},)+
1260 }
1261 }
1262 }
1263 };
1264}
1265
1266impl_cast_any! {
1267 AccountCreate,
1268 AccountUpdate,
1269 AccountDelete,
1270 AccountAllowanceApprove,
1271 AccountAllowanceDelete,
1272 ContractCreate,
1273 ContractUpdate,
1274 ContractDelete,
1275 ContractExecute,
1276 Transfer,
1277 TopicCreate,
1278 TopicUpdate,
1279 TopicDelete,
1280 TopicMessageSubmit,
1281 FileAppend,
1282 FileCreate,
1283 FileUpdate,
1284 FileDelete,
1285 Prng,
1286 ScheduleCreate,
1287 ScheduleSign,
1288 ScheduleDelete,
1289 TokenAssociate,
1290 TokenBurn,
1291 TokenCreate,
1292 TokenDelete,
1293 TokenDissociate,
1294 TokenFeeScheduleUpdate,
1295 TokenFreeze,
1296 TokenGrantKyc,
1297 TokenMint,
1298 TokenPause,
1299 TokenRevokeKyc,
1300 TokenUnfreeze,
1301 TokenUnpause,
1302 TokenUpdate,
1303 TokenWipe,
1304 SystemDelete,
1305 SystemUndelete,
1306 Freeze,
1307 Ethereum,
1308 TokenUpdateNfts,
1309 NodeCreate,
1310 NodeUpdate,
1311 NodeDelete,
1312 TokenReject,
1313 TokenAirdrop,
1314 TokenClaimAirdrop,
1315 TokenCancelAirdrop,
1316 Batch,
1317 HookStore
1318}