1use super::*;
2use radix_common::prelude::*;
3
4use radix_engine_interface::blueprints::access_controller::*;
5use radix_engine_interface::blueprints::account::*;
6use radix_engine_interface::blueprints::consensus_manager::*;
7use radix_engine_interface::blueprints::identity::*;
8use radix_engine_interface::blueprints::locker::*;
9use radix_engine_interface::blueprints::package::*;
10use radix_engine_interface::blueprints::pool::*;
11use radix_engine_interface::blueprints::resource::*;
12use radix_engine_interface::blueprints::transaction_tracker::*;
13use radix_engine_interface::object_modules::metadata::*;
14use radix_engine_interface::object_modules::role_assignment::*;
15use radix_engine_interface::object_modules::royalty::*;
16
17pub trait StaticInvocationResourcesOutput
18where
19 Self: ManifestEncode + ManifestDecode,
20{
21 fn output(
22 &self,
23 details: InvocationDetails,
24 ) -> Result<TrackedResources, StaticResourceMovementsError>;
25}
26
27pub struct InvocationDetails<'a> {
28 pub receiver: InvocationReceiver,
29 pub sent_resources: &'a TrackedResources,
30 pub source: ChangeSource,
31}
32
33#[derive(Debug)]
34pub enum InvocationReceiver {
35 GlobalMethod(ResolvedDynamicAddress<GlobalAddress>),
36 DirectAccess(InternalAddress),
37 BlueprintFunction(BlueprintId),
38}
39
40macro_rules! no_output_static_invocation_resources_output_impl {
41 (
42 $(
43 $output_ident: ident
44 ),* $(,)?
45 ) => {
46 $(
47 impl StaticInvocationResourcesOutput for $output_ident {
48 fn output(
49 &self,
50 _details: InvocationDetails
51 ) -> Result<TrackedResources, StaticResourceMovementsError> {
52 Ok(TrackedResources::new_empty())
53 }
54 }
55 )*
56 };
57}
58
59macro_rules! handle_single_unknown_output_static_invocation_resources_output_impl {
60 ($input_ty: ty) => {
61 impl StaticInvocationResourcesOutput for $input_ty {
62 fn output(
63 &self,
64 details: InvocationDetails,
65 ) -> Result<TrackedResources, StaticResourceMovementsError> {
66 Ok(
67 TrackedResources::new_with_possible_balance_of_unspecified_resources([
68 details.source
69 ]),
70 )
71 }
72 }
73 };
74 (no_resource_inputs_returned: $input_ty: ty) => {
75 impl StaticInvocationResourcesOutput for $input_ty {
76 fn output(
77 &self,
78 details: InvocationDetails,
79 ) -> Result<TrackedResources, StaticResourceMovementsError> {
80 let mut tracked_resources =
81 TrackedResources::new_with_possible_balance_of_unspecified_resources([
82 details.source
83 ]);
84 for resource_address in details.sent_resources.specified_resources().keys() {
85 tracked_resources.handle_resource_assertion(
86 *resource_address,
87 ResourceBounds::zero(),
88 details.source,
89 )?;
90 }
91
92 Ok(tracked_resources)
93 }
94 }
95 };
96}
97
98macro_rules! unknown_output_static_invocation_resources_output_impl {
99 (
100 $(
101 $([$modifier: ident]:)? $input_ty: ident
102 ),* $(,)?
103 ) => {
104 $(
105 handle_single_unknown_output_static_invocation_resources_output_impl!(
106 $($modifier:)? $input_ty
107 );
108 )*
109 };
110}
111
112no_output_static_invocation_resources_output_impl![
113 AccessControllerCreateManifestInput,
115 AccessControllerCreateProofManifestInput,
116 AccessControllerInitiateRecoveryAsPrimaryManifestInput,
117 AccessControllerInitiateRecoveryAsRecoveryManifestInput,
118 AccessControllerQuickConfirmPrimaryRoleRecoveryProposalManifestInput,
119 AccessControllerQuickConfirmRecoveryRoleRecoveryProposalManifestInput,
120 AccessControllerTimedConfirmRecoveryManifestInput,
121 AccessControllerCancelPrimaryRoleRecoveryProposalManifestInput,
122 AccessControllerCancelRecoveryRoleRecoveryProposalManifestInput,
123 AccessControllerLockPrimaryRoleManifestInput,
124 AccessControllerUnlockPrimaryRoleManifestInput,
125 AccessControllerStopTimedRecoveryManifestInput,
126 AccessControllerInitiateBadgeWithdrawAttemptAsPrimaryManifestInput,
127 AccessControllerInitiateBadgeWithdrawAttemptAsRecoveryManifestInput,
128 AccessControllerCancelPrimaryRoleBadgeWithdrawAttemptManifestInput,
129 AccessControllerCancelRecoveryRoleBadgeWithdrawAttemptManifestInput,
130 AccessControllerLockRecoveryFeeManifestInput,
131 AccessControllerContributeRecoveryFeeManifestInput,
132 AccountCreateAdvancedManifestInput,
134 AccountLockFeeManifestInput,
135 AccountLockContingentFeeManifestInput,
136 AccountDepositManifestInput,
137 AccountDepositBatchManifestInput,
138 AccountBurnManifestInput,
139 AccountBurnNonFungiblesManifestInput,
140 AccountCreateProofOfAmountManifestInput,
141 AccountCreateProofOfNonFungiblesManifestInput,
142 AccountSetDefaultDepositRuleManifestInput,
143 AccountSetResourcePreferenceManifestInput,
144 AccountRemoveResourcePreferenceManifestInput,
145 AccountTryDepositOrAbortManifestInput,
146 AccountTryDepositBatchOrAbortManifestInput,
147 AccountAddAuthorizedDepositorManifestInput,
148 AccountRemoveAuthorizedDepositorManifestInput,
149 AccountBalanceManifestInput,
150 AccountNonFungibleLocalIdsManifestInput,
151 AccountHasNonFungibleManifestInput,
152 ConsensusManagerCreateManifestInput,
154 ConsensusManagerGetCurrentEpochManifestInput,
155 ConsensusManagerStartManifestInput,
156 ConsensusManagerGetCurrentTimeManifestInputV1,
157 ConsensusManagerGetCurrentTimeManifestInputV2,
158 ConsensusManagerCompareCurrentTimeManifestInputV1,
159 ConsensusManagerCompareCurrentTimeManifestInputV2,
160 ConsensusManagerNextRoundManifestInput,
161 ValidatorRegisterManifestInput,
163 ValidatorUnregisterManifestInput,
164 ValidatorUpdateKeyManifestInput,
165 ValidatorUpdateFeeManifestInput,
166 ValidatorUpdateAcceptDelegatedStakeManifestInput,
167 ValidatorAcceptsDelegatedStakeManifestInput,
168 ValidatorTotalStakeXrdAmountManifestInput,
169 ValidatorTotalStakeUnitSupplyManifestInput,
170 ValidatorGetRedemptionValueManifestInput,
171 ValidatorSignalProtocolUpdateReadinessManifestInput,
172 ValidatorGetProtocolUpdateReadinessManifestInput,
173 ValidatorLockOwnerStakeUnitsManifestInput,
174 ValidatorStartUnlockOwnerStakeUnitsManifestInput,
175 ValidatorApplyEmissionManifestInput,
176 ValidatorApplyRewardManifestInput,
177 IdentityCreateAdvancedManifestInput,
179 AccountLockerInstantiateManifestInput,
181 AccountLockerStoreManifestInput,
182 AccountLockerGetAmountManifestInput,
183 AccountLockerGetNonFungibleLocalIdsManifestInput,
184 PackagePublishWasmAdvancedManifestInput,
186 PackagePublishNativeManifestInput,
187 OneResourcePoolInstantiateManifestInput,
189 OneResourcePoolProtectedDepositManifestInput,
190 OneResourcePoolGetRedemptionValueManifestInput,
191 OneResourcePoolGetVaultAmountManifestInput,
192 TwoResourcePoolInstantiateManifestInput,
194 TwoResourcePoolProtectedDepositManifestInput,
195 TwoResourcePoolGetRedemptionValueManifestInput,
196 TwoResourcePoolGetVaultAmountsManifestInput,
197 MultiResourcePoolInstantiateManifestInput,
199 MultiResourcePoolProtectedDepositManifestInput,
200 MultiResourcePoolGetRedemptionValueManifestInput,
201 MultiResourcePoolGetVaultAmountsManifestInput,
202 ResourceManagerBurnManifestInput,
204 ResourceManagerPackageBurnManifestInput,
205 ResourceManagerGetTotalSupplyManifestInput,
206 ResourceManagerGetResourceTypeManifestInput,
207 ResourceManagerCreateEmptyVaultManifestInput,
208 ResourceManagerGetAmountForWithdrawalManifestInput,
209 ResourceManagerDropEmptyBucketManifestInput,
210 FungibleResourceManagerCreateManifestInput,
212 NonFungibleResourceManagerCreateManifestInput,
214 NonFungibleResourceManagerGetNonFungibleManifestInput,
215 NonFungibleResourceManagerUpdateDataManifestInput,
216 NonFungibleResourceManagerExistsManifestInput,
217 VaultGetAmountManifestInput,
219 VaultFreezeManifestInput,
220 VaultUnfreezeManifestInput,
221 VaultBurnManifestInput,
222 VaultPutManifestInput,
223 FungibleVaultLockFeeManifestInput,
225 FungibleVaultCreateProofOfAmountManifestInput,
226 FungibleVaultLockFungibleAmountManifestInput,
227 FungibleVaultUnlockFungibleAmountManifestInput,
228 NonFungibleVaultGetNonFungibleLocalIdsManifestInput,
230 NonFungibleVaultContainsNonFungibleManifestInput,
231 NonFungibleVaultCreateProofOfNonFungiblesManifestInput,
232 NonFungibleVaultLockNonFungiblesManifestInput,
233 NonFungibleVaultUnlockNonFungiblesManifestInput,
234 NonFungibleVaultBurnNonFungiblesManifestInput,
235 TransactionTrackerCreateManifestInput,
237 MetadataCreateManifestInput,
239 MetadataCreateWithDataManifestInput,
240 MetadataSetManifestInput,
241 MetadataLockManifestInput,
242 MetadataGetManifestInput,
243 MetadataRemoveManifestInput,
244 RoleAssignmentCreateManifestInput,
246 RoleAssignmentSetOwnerManifestInput,
247 RoleAssignmentLockOwnerManifestInput,
248 RoleAssignmentSetManifestInput,
249 RoleAssignmentGetManifestInput,
250 RoleAssignmentGetOwnerRoleManifestInput,
251 ComponentRoyaltyCreateManifestInput,
253 ComponentRoyaltySetManifestInput,
254 ComponentRoyaltyLockManifestInput,
255];
256
257unknown_output_static_invocation_resources_output_impl![
258 AccessControllerQuickConfirmPrimaryRoleBadgeWithdrawAttemptManifestInput,
261 AccessControllerQuickConfirmRecoveryRoleBadgeWithdrawAttemptManifestInput,
263 AccessControllerMintRecoveryBadgesManifestInput,
265 [no_resource_inputs_returned]: ValidatorStakeAsOwnerManifestInput,
268 [no_resource_inputs_returned]: ValidatorStakeManifestInput,
270 [no_resource_inputs_returned]: ValidatorUnstakeManifestInput,
272 [no_resource_inputs_returned]: ValidatorFinishUnlockOwnerStakeUnitsManifestInput,
274 AccountLockerInstantiateSimpleManifestInput,
277 [no_resource_inputs_returned]: OneResourcePoolContributeManifestInput,
280 [no_resource_inputs_returned]: OneResourcePoolRedeemManifestInput,
282 OneResourcePoolProtectedWithdrawManifestInput,
284 TwoResourcePoolContributeManifestInput,
287 [no_resource_inputs_returned]: TwoResourcePoolRedeemManifestInput,
289 MultiResourcePoolContributeManifestInput,
292 [no_resource_inputs_returned]: MultiResourcePoolRedeemManifestInput,
294 FungibleResourceManagerCreateWithInitialSupplyManifestInput,
298 NonFungibleResourceManagerCreateWithInitialSupplyManifestInput,
302 NonFungibleResourceManagerCreateRuidWithInitialSupplyManifestInput,
305 VaultTakeManifestInput,
309 VaultTakeAdvancedManifestInput,
312 VaultRecallManifestInput,
315 NonFungibleVaultTakeNonFungiblesManifestInput,
319 NonFungibleVaultRecallNonFungiblesManifestInput,
322];
323
324impl StaticInvocationResourcesOutput for TypedManifestNativeInvocation {
326 fn output(
327 &self,
328 details: InvocationDetails,
329 ) -> Result<TrackedResources, StaticResourceMovementsError> {
330 uniform_match_on_manifest_typed_invocation!(self => (input) => input.output(details))
331 }
332}
333impl StaticInvocationResourcesOutput for AccessControllerWithdrawRecoveryFeeManifestInput {
337 fn output(
338 &self,
339 details: InvocationDetails,
340 ) -> Result<TrackedResources, StaticResourceMovementsError> {
341 TrackedResources::new_empty().add_resource(
342 XRD,
343 TrackedResource::exact_amount(self.amount, [details.source])?,
344 )
345 }
346}
347impl StaticInvocationResourcesOutput for AccountCreateManifestInput {
351 fn output(
352 &self,
353 details: InvocationDetails,
354 ) -> Result<TrackedResources, StaticResourceMovementsError> {
355 TrackedResources::new_empty().add_resource(
356 ACCOUNT_OWNER_BADGE,
357 TrackedResource::exact_amount(1, [details.source])?,
358 )
359 }
360}
361
362impl StaticInvocationResourcesOutput for AccountSecurifyManifestInput {
363 fn output(
364 &self,
365 details: InvocationDetails,
366 ) -> Result<TrackedResources, StaticResourceMovementsError> {
367 match details.receiver {
368 InvocationReceiver::GlobalMethod(ResolvedDynamicAddress::StaticAddress(
369 global_address,
370 )) => {
371 let local_id = NonFungibleLocalId::bytes(global_address.as_bytes()).unwrap();
372 TrackedResources::new_empty().add_resource(
373 ACCOUNT_OWNER_BADGE,
374 TrackedResource::exact_non_fungibles([local_id], [details.source]),
375 )
376 }
377 InvocationReceiver::GlobalMethod(
378 ResolvedDynamicAddress::BlueprintResolvedFromNamedAddress(_),
379 ) => TrackedResources::new_empty().add_resource(
380 ACCOUNT_OWNER_BADGE,
381 TrackedResource::exact_amount(1, [details.source])?,
382 ),
383 InvocationReceiver::DirectAccess(_) | InvocationReceiver::BlueprintFunction(_) => {
384 unreachable!()
385 }
386 }
387 }
388}
389
390impl StaticInvocationResourcesOutput for AccountWithdrawManifestInput {
391 fn output(
392 &self,
393 details: InvocationDetails,
394 ) -> Result<TrackedResources, StaticResourceMovementsError> {
395 let ManifestResourceAddress::Static(resource_address) = self.resource_address else {
396 return Ok(
397 TrackedResources::new_with_possible_balance_of_unspecified_resources([
398 details.source
399 ]),
400 );
401 };
402 TrackedResources::new_empty().add_resource(
403 resource_address,
404 TrackedResource::exact_amount(self.amount, [details.source])?,
405 )
406 }
407}
408
409impl StaticInvocationResourcesOutput for AccountWithdrawNonFungiblesManifestInput {
410 fn output(
411 &self,
412 details: InvocationDetails,
413 ) -> Result<TrackedResources, StaticResourceMovementsError> {
414 let ManifestResourceAddress::Static(resource_address) = self.resource_address else {
415 return Ok(
416 TrackedResources::new_with_possible_balance_of_unspecified_resources([
417 details.source
418 ]),
419 );
420 };
421 TrackedResources::new_empty().add_resource(
422 resource_address,
423 TrackedResource::exact_non_fungibles(self.ids.clone(), [details.source]),
424 )
425 }
426}
427
428impl StaticInvocationResourcesOutput for AccountLockFeeAndWithdrawManifestInput {
429 fn output(
430 &self,
431 details: InvocationDetails,
432 ) -> Result<TrackedResources, StaticResourceMovementsError> {
433 let ManifestResourceAddress::Static(resource_address) = self.resource_address else {
434 return Ok(
435 TrackedResources::new_with_possible_balance_of_unspecified_resources([
436 details.source
437 ]),
438 );
439 };
440 TrackedResources::new_empty().add_resource(
441 resource_address,
442 TrackedResource::exact_amount(self.amount, [details.source])?,
443 )
444 }
445}
446
447impl StaticInvocationResourcesOutput for AccountLockFeeAndWithdrawNonFungiblesManifestInput {
448 fn output(
449 &self,
450 details: InvocationDetails,
451 ) -> Result<TrackedResources, StaticResourceMovementsError> {
452 let ManifestResourceAddress::Static(resource_address) = self.resource_address else {
453 return Ok(
454 TrackedResources::new_with_possible_balance_of_unspecified_resources([
455 details.source
456 ]),
457 );
458 };
459 TrackedResources::new_empty().add_resource(
460 resource_address,
461 TrackedResource::exact_non_fungibles(self.ids.clone(), [details.source]),
462 )
463 }
464}
465
466impl StaticInvocationResourcesOutput for AccountTryDepositOrRefundManifestInput {
467 fn output(
468 &self,
469 details: InvocationDetails,
470 ) -> Result<TrackedResources, StaticResourceMovementsError> {
471 handle_possible_refund(details)
472 }
473}
474
475impl StaticInvocationResourcesOutput for AccountTryDepositBatchOrRefundManifestInput {
476 fn output(
477 &self,
478 details: InvocationDetails,
479 ) -> Result<TrackedResources, StaticResourceMovementsError> {
480 handle_possible_refund(details)
481 }
482}
483
484fn handle_possible_refund(
485 details: InvocationDetails,
486) -> Result<TrackedResources, StaticResourceMovementsError> {
487 let mut sent_resources = details.sent_resources.clone();
488 let mut refunded_resources = TrackedResources::new_empty();
489
490 let known_resources = sent_resources
492 .specified_resources()
493 .keys()
494 .cloned()
495 .collect::<Vec<_>>();
496 for known_resource in known_resources {
497 let attempted_deposit = sent_resources.mut_take_resource(
498 known_resource,
499 ResourceTakeAmount::All,
500 details.source,
501 )?;
502 let (bounds, _history) = attempted_deposit.deconstruct();
503 let refunded_amount = bounds.replace_lower_bounds_with_zero();
506 refunded_resources.mut_add_resource(
507 known_resource,
508 TrackedResource::general(refunded_amount, [details.source]),
509 )?;
510 }
511 if sent_resources.unspecified_resources().may_be_present() {
513 refunded_resources.mut_add_unspecified_resources([details.source]);
514 }
515
516 Ok(refunded_resources)
517}
518impl StaticInvocationResourcesOutput for ConsensusManagerCreateValidatorManifestInput {
522 fn output(
523 &self,
524 details: InvocationDetails,
525 ) -> Result<TrackedResources, StaticResourceMovementsError> {
526 TrackedResources::new_empty().add_resource(
527 VALIDATOR_OWNER_BADGE,
528 TrackedResource::exact_amount(1, [details.source])?,
529 )
530 }
531}
532impl StaticInvocationResourcesOutput for ValidatorClaimXrdManifestInput {
536 fn output(
537 &self,
538 details: InvocationDetails,
539 ) -> Result<TrackedResources, StaticResourceMovementsError> {
540 TrackedResources::new_empty()
541 .add_resource(XRD, TrackedResource::zero_or_more([details.source]))
542 }
543}
544impl StaticInvocationResourcesOutput for IdentityCreateManifestInput {
548 fn output(
549 &self,
550 details: InvocationDetails,
551 ) -> Result<TrackedResources, StaticResourceMovementsError> {
552 TrackedResources::new_empty().add_resource(
553 IDENTITY_OWNER_BADGE,
554 TrackedResource::exact_amount(1, [details.source])?,
555 )
556 }
557}
558
559impl StaticInvocationResourcesOutput for IdentitySecurifyToSingleBadgeManifestInput {
560 fn output(
561 &self,
562 details: InvocationDetails,
563 ) -> Result<TrackedResources, StaticResourceMovementsError> {
564 Ok(match details.receiver {
565 InvocationReceiver::GlobalMethod(ResolvedDynamicAddress::StaticAddress(
566 global_address,
567 )) => {
568 let local_id = NonFungibleLocalId::bytes(global_address.as_bytes()).unwrap();
569 TrackedResources::new_empty().add_resource(
570 IDENTITY_OWNER_BADGE,
571 TrackedResource::exact_non_fungibles([local_id], [details.source]),
572 )?
573 }
574 InvocationReceiver::GlobalMethod(
575 ResolvedDynamicAddress::BlueprintResolvedFromNamedAddress(_),
576 ) => TrackedResources::new_empty().add_resource(
577 IDENTITY_OWNER_BADGE,
578 TrackedResource::exact_amount(1, [details.source])?,
579 )?,
580 InvocationReceiver::DirectAccess(_) | InvocationReceiver::BlueprintFunction(_) => {
581 unreachable!()
582 }
583 })
584 }
585}
586impl StaticInvocationResourcesOutput for AccountLockerAirdropManifestInput {
590 fn output(
591 &self,
592 details: InvocationDetails,
593 ) -> Result<TrackedResources, StaticResourceMovementsError> {
594 handle_possible_refund(details)
598 }
599}
600
601impl StaticInvocationResourcesOutput for AccountLockerRecoverManifestInput {
602 fn output(
603 &self,
604 details: InvocationDetails,
605 ) -> Result<TrackedResources, StaticResourceMovementsError> {
606 let ManifestResourceAddress::Static(resource_address) = self.resource_address else {
607 return Ok(
608 TrackedResources::new_with_possible_balance_of_unspecified_resources([
609 details.source
610 ]),
611 );
612 };
613 TrackedResources::new_empty().add_resource(
614 resource_address,
615 TrackedResource::exact_amount(self.amount, [details.source])?,
616 )
617 }
618}
619
620impl StaticInvocationResourcesOutput for AccountLockerRecoverNonFungiblesManifestInput {
621 fn output(
622 &self,
623 details: InvocationDetails,
624 ) -> Result<TrackedResources, StaticResourceMovementsError> {
625 let ManifestResourceAddress::Static(resource_address) = self.resource_address else {
626 return Ok(
627 TrackedResources::new_with_possible_balance_of_unspecified_resources([
628 details.source
629 ]),
630 );
631 };
632 TrackedResources::new_empty().add_resource(
633 resource_address,
634 TrackedResource::exact_non_fungibles(self.ids.clone(), [details.source]),
635 )
636 }
637}
638
639impl StaticInvocationResourcesOutput for AccountLockerClaimManifestInput {
640 fn output(
641 &self,
642 details: InvocationDetails,
643 ) -> Result<TrackedResources, StaticResourceMovementsError> {
644 let ManifestResourceAddress::Static(resource_address) = self.resource_address else {
645 return Ok(
646 TrackedResources::new_with_possible_balance_of_unspecified_resources([
647 details.source
648 ]),
649 );
650 };
651 TrackedResources::new_empty().add_resource(
652 resource_address,
653 TrackedResource::exact_amount(self.amount, [details.source])?,
654 )
655 }
656}
657
658impl StaticInvocationResourcesOutput for AccountLockerClaimNonFungiblesManifestInput {
659 fn output(
660 &self,
661 details: InvocationDetails,
662 ) -> Result<TrackedResources, StaticResourceMovementsError> {
663 let ManifestResourceAddress::Static(resource_address) = self.resource_address else {
664 return Ok(
665 TrackedResources::new_with_possible_balance_of_unspecified_resources([
666 details.source
667 ]),
668 );
669 };
670 TrackedResources::new_empty().add_resource(
671 resource_address,
672 TrackedResource::exact_non_fungibles(self.ids.clone(), [details.source]),
673 )
674 }
675}
676impl StaticInvocationResourcesOutput for PackagePublishWasmManifestInput {
680 fn output(
681 &self,
682 details: InvocationDetails,
683 ) -> Result<TrackedResources, StaticResourceMovementsError> {
684 TrackedResources::new_empty().add_resource(
685 PACKAGE_OWNER_BADGE,
686 TrackedResource::exact_amount(1, [details.source])?,
687 )
688 }
689}
690
691impl StaticInvocationResourcesOutput for PackageClaimRoyaltiesManifestInput {
692 fn output(
693 &self,
694 details: InvocationDetails,
695 ) -> Result<TrackedResources, StaticResourceMovementsError> {
696 TrackedResources::new_empty()
697 .add_resource(XRD, TrackedResource::zero_or_more([details.source]))
698 }
699}
700impl StaticInvocationResourcesOutput for TwoResourcePoolProtectedWithdrawManifestInput {
704 fn output(
705 &self,
706 details: InvocationDetails,
707 ) -> Result<TrackedResources, StaticResourceMovementsError> {
708 let ManifestResourceAddress::Static(resource_address) = self.resource_address else {
709 return Ok(
710 TrackedResources::new_with_possible_balance_of_unspecified_resources([
711 details.source
712 ]),
713 );
714 };
715 TrackedResources::new_empty().add_resource(
716 resource_address,
717 TrackedResource::exact_amount(self.amount, [details.source])?,
718 )
719 }
720}
721impl StaticInvocationResourcesOutput for MultiResourcePoolProtectedWithdrawManifestInput {
725 fn output(
726 &self,
727 details: InvocationDetails,
728 ) -> Result<TrackedResources, StaticResourceMovementsError> {
729 let ManifestResourceAddress::Static(resource_address) = self.resource_address else {
730 return Ok(
731 TrackedResources::new_with_possible_balance_of_unspecified_resources([
732 details.source
733 ]),
734 );
735 };
736 TrackedResources::new_empty().add_resource(
737 resource_address,
738 TrackedResource::exact_amount(self.amount, [details.source])?,
739 )
740 }
741}
742impl StaticInvocationResourcesOutput for FungibleResourceManagerMintManifestInput {
746 fn output(
747 &self,
748 details: InvocationDetails,
749 ) -> Result<TrackedResources, StaticResourceMovementsError> {
750 match details.receiver {
753 InvocationReceiver::GlobalMethod(ResolvedDynamicAddress::StaticAddress(
754 global_address,
755 )) => {
756 if let Ok(resource_address) = ResourceAddress::try_from(global_address) {
758 TrackedResources::new_empty().add_resource(
759 resource_address,
760 TrackedResource::exact_amount(self.amount, [details.source])?,
761 )
762 } else {
763 Err(StaticResourceMovementsError::NotAResourceAddress(
764 global_address,
765 ))
766 }
767 }
768 InvocationReceiver::GlobalMethod(
769 ResolvedDynamicAddress::BlueprintResolvedFromNamedAddress(_),
770 )
771 | InvocationReceiver::DirectAccess(_)
772 | InvocationReceiver::BlueprintFunction(_) => Ok(
773 TrackedResources::new_with_possible_balance_of_unspecified_resources([
774 details.source
775 ]),
776 ),
777 }
778 }
779}
780
781impl StaticInvocationResourcesOutput for ResourceManagerCreateEmptyBucketInput {
782 fn output(
783 &self,
784 _: InvocationDetails,
785 ) -> Result<TrackedResources, StaticResourceMovementsError> {
786 Ok(TrackedResources::new_empty())
793 }
794}
795impl StaticInvocationResourcesOutput for NonFungibleResourceManagerMintManifestInput {
799 fn output(
800 &self,
801 details: InvocationDetails,
802 ) -> Result<TrackedResources, StaticResourceMovementsError> {
803 match details.receiver {
806 InvocationReceiver::GlobalMethod(ResolvedDynamicAddress::StaticAddress(
807 global_address,
808 )) => {
809 if let Ok(resource_address) = ResourceAddress::try_from(global_address) {
811 TrackedResources::new_empty().add_resource(
812 resource_address,
813 TrackedResource::exact_non_fungibles(
814 self.entries.keys().cloned(),
815 [details.source],
816 ),
817 )
818 } else {
819 Err(StaticResourceMovementsError::NotAResourceAddress(
820 global_address,
821 ))
822 }
823 }
824 InvocationReceiver::GlobalMethod(
825 ResolvedDynamicAddress::BlueprintResolvedFromNamedAddress(_),
826 )
827 | InvocationReceiver::DirectAccess(_)
828 | InvocationReceiver::BlueprintFunction(_) => Ok(
829 TrackedResources::new_with_possible_balance_of_unspecified_resources([
830 details.source
831 ]),
832 ),
833 }
834 }
835}
836
837impl StaticInvocationResourcesOutput for NonFungibleResourceManagerMintRuidManifestInput {
838 fn output(
839 &self,
840 details: InvocationDetails,
841 ) -> Result<TrackedResources, StaticResourceMovementsError> {
842 match details.receiver {
845 InvocationReceiver::GlobalMethod(ResolvedDynamicAddress::StaticAddress(
846 global_address,
847 )) => {
848 if let Ok(resource_address) = ResourceAddress::try_from(global_address) {
850 TrackedResources::new_empty().add_resource(
851 resource_address,
852 TrackedResource::exact_amount(self.entries.len(), [details.source])?,
853 )
854 } else {
855 Err(StaticResourceMovementsError::NotAResourceAddress(
856 global_address,
857 ))
858 }
859 }
860 InvocationReceiver::GlobalMethod(
861 ResolvedDynamicAddress::BlueprintResolvedFromNamedAddress(_),
862 )
863 | InvocationReceiver::DirectAccess(_)
864 | InvocationReceiver::BlueprintFunction(_) => Ok(
865 TrackedResources::new_with_possible_balance_of_unspecified_resources([
866 details.source
867 ]),
868 ),
869 }
870 }
871}
872
873impl StaticInvocationResourcesOutput for NonFungibleResourceManagerMintSingleRuidManifestInput {
874 fn output(
875 &self,
876 details: InvocationDetails,
877 ) -> Result<TrackedResources, StaticResourceMovementsError> {
878 match details.receiver {
881 InvocationReceiver::GlobalMethod(ResolvedDynamicAddress::StaticAddress(
882 global_address,
883 )) => {
884 if let Ok(resource_address) = ResourceAddress::try_from(global_address) {
886 TrackedResources::new_empty().add_resource(
887 resource_address,
888 TrackedResource::exact_amount(Decimal::ONE, [details.source])?,
889 )
890 } else {
891 Err(StaticResourceMovementsError::NotAResourceAddress(
892 global_address,
893 ))
894 }
895 }
896 InvocationReceiver::GlobalMethod(
897 ResolvedDynamicAddress::BlueprintResolvedFromNamedAddress(_),
898 )
899 | InvocationReceiver::DirectAccess(_)
900 | InvocationReceiver::BlueprintFunction(_) => Ok(
901 TrackedResources::new_with_possible_balance_of_unspecified_resources([
902 details.source
903 ]),
904 ),
905 }
906 }
907}
908impl StaticInvocationResourcesOutput for ComponentClaimRoyaltiesManifestInput {
912 fn output(
913 &self,
914 details: InvocationDetails,
915 ) -> Result<TrackedResources, StaticResourceMovementsError> {
916 TrackedResources::new_empty()
917 .add_resource(XRD, TrackedResource::zero_or_more([details.source]))
918 }
919}
920