@layerzerolabs/protocol-stellar-v2 0.2.15 → 0.2.18

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 (257) hide show
  1. package/.turbo/turbo-build.log +350 -309
  2. package/.turbo/turbo-lint.log +146 -108
  3. package/.turbo/turbo-test.log +1423 -1238
  4. package/Cargo.lock +12 -0
  5. package/Cargo.toml +3 -0
  6. package/contracts/ERROR_SPEC.md +44 -0
  7. package/contracts/common-macros/src/auth.rs +113 -0
  8. package/contracts/common-macros/src/contract_ttl.rs +84 -0
  9. package/contracts/common-macros/src/lib.rs +181 -30
  10. package/contracts/common-macros/src/lz_contract.rs +83 -0
  11. package/contracts/common-macros/src/tests/{ownable.rs → auth.rs} +48 -15
  12. package/contracts/common-macros/src/tests/contract_ttl.rs +662 -0
  13. package/contracts/common-macros/src/tests/mod.rs +2 -2
  14. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__auth__snapshot_generated_multisig_code.snap +20 -0
  15. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__auth__snapshot_generated_ownable_code.snap +24 -0
  16. package/contracts/common-macros/src/tests/snapshots/{common_macros__tests__ownable__snapshot_only_owner_preserves_function_signature.snap → common_macros__tests__auth__snapshot_only_auth_preserves_function_signature.snap} +4 -4
  17. package/contracts/common-macros/src/tests/snapshots/{common_macros__tests__contract_impl__snapshot_generated_contract_impl_code.snap → common_macros__tests__contract_ttl__snapshot_generated_contractimpl_code.snap} +3 -3
  18. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__contract_ttl__snapshot_generated_contracttrait_code.snap +69 -0
  19. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__ttl_configurable__snapshot_generated_ttl_configurable_code.snap +7 -21
  20. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__upgradeable__snapshot_generated_upgradeable_code.snap +2 -2
  21. package/contracts/common-macros/src/ttl_configurable.rs +19 -34
  22. package/contracts/common-macros/src/ttl_extendable.rs +36 -0
  23. package/contracts/common-macros/src/upgradeable.rs +5 -5
  24. package/contracts/common-macros/src/utils.rs +9 -0
  25. package/contracts/endpoint-v2/src/constants.rs +4 -4
  26. package/contracts/endpoint-v2/src/endpoint_v2.rs +38 -40
  27. package/contracts/endpoint-v2/src/errors.rs +4 -3
  28. package/contracts/endpoint-v2/src/events.rs +1 -1
  29. package/contracts/endpoint-v2/src/message_lib_manager.rs +18 -5
  30. package/contracts/endpoint-v2/src/messaging_channel.rs +11 -1
  31. package/contracts/endpoint-v2/src/messaging_composer.rs +11 -1
  32. package/contracts/endpoint-v2/src/storage.rs +1 -1
  33. package/contracts/endpoint-v2/src/tests/endpoint_v2/pay_messaging_fees.rs +3 -3
  34. package/contracts/endpoint-v2/src/tests/endpoint_v2/quote.rs +1 -1
  35. package/contracts/endpoint-v2/src/tests/endpoint_v2/require_oapp_auth.rs +2 -2
  36. package/contracts/endpoint-v2/src/tests/endpoint_v2/send.rs +3 -3
  37. package/contracts/endpoint-v2/src/tests/endpoint_v2/set_zro.rs +4 -4
  38. package/contracts/endpoint-v2/src/tests/message_lib_manager/require_receive_lib_for_eid.rs +3 -3
  39. package/contracts/endpoint-v2/src/tests/message_lib_manager/require_registered.rs +1 -1
  40. package/contracts/endpoint-v2/src/tests/message_lib_manager/require_send_lib_for_eid.rs +3 -3
  41. package/contracts/endpoint-v2/src/tests/message_lib_manager/require_supported_eid.rs +1 -1
  42. package/contracts/endpoint-v2/src/tests/messaging_channel/clear_payload.rs +4 -4
  43. package/contracts/endpoint-v2/src/tests/messaging_channel/inbound.rs +1 -1
  44. package/contracts/layerzero-views/src/layerzero_view.rs +3 -6
  45. package/contracts/macro-integration-tests/tests/runtime/ownable/mod.rs +2 -2
  46. package/contracts/macro-integration-tests/tests/runtime/ownable/{only_owner_guard.rs → only_auth_guard.rs} +1 -1
  47. package/contracts/macro-integration-tests/tests/runtime/ttl_configurable/configuration.rs +1 -1
  48. package/contracts/macro-integration-tests/tests/runtime/ttl_configurable/freeze.rs +1 -1
  49. package/contracts/macro-integration-tests/tests/runtime/ttl_configurable/mod.rs +0 -1
  50. package/contracts/macro-integration-tests/tests/ui/ownable/fail/{only_owner_missing_env.rs → only_auth_missing_env.rs} +3 -3
  51. package/contracts/macro-integration-tests/tests/ui/ownable/fail/{only_owner_missing_env.stderr → only_auth_missing_env.stderr} +4 -4
  52. package/contracts/macro-integration-tests/tests/ui/ownable/pass/namespacing_and_imports.rs +2 -3
  53. package/contracts/macro-integration-tests/tests/ui/ownable/pass/{only_owner_env_param_variants.rs → only_auth_env_param_variants.rs} +9 -9
  54. package/contracts/macro-integration-tests/tests/ui/ttl_configurable/pass/minimal_contract.rs +6 -6
  55. package/contracts/message-libs/message-lib-common/src/errors.rs +7 -2
  56. package/contracts/message-libs/message-lib-common/src/tests/packet_codec_v1/decode_packet_header.rs +3 -3
  57. package/contracts/message-libs/message-lib-common/src/tests/worker_options/append_lz_receive_option.rs +1 -2
  58. package/contracts/message-libs/message-lib-common/src/tests/worker_options/append_native_drop_option.rs +1 -2
  59. package/contracts/message-libs/message-lib-common/src/tests/worker_options/convert_legacy_options.rs +9 -9
  60. package/contracts/message-libs/message-lib-common/src/tests/worker_options/extract_type_3_options.rs +1 -1
  61. package/contracts/message-libs/message-lib-common/src/tests/worker_options/left_pad_to_bytes32.rs +1 -1
  62. package/contracts/message-libs/message-lib-common/src/tests/worker_options/split_worker_options.rs +2 -2
  63. package/contracts/message-libs/simple-message-lib/src/simple_message_lib.rs +7 -9
  64. package/contracts/message-libs/treasury/src/errors.rs +2 -2
  65. package/contracts/message-libs/treasury/src/events.rs +1 -1
  66. package/contracts/message-libs/treasury/src/interfaces/zro_fee_lib.rs +2 -2
  67. package/contracts/message-libs/treasury/src/storage.rs +1 -1
  68. package/contracts/message-libs/treasury/src/tests/treasury_tests.rs +1 -1
  69. package/contracts/message-libs/treasury/src/treasury.rs +14 -16
  70. package/contracts/message-libs/uln-302/src/receive_uln.rs +13 -2
  71. package/contracts/message-libs/uln-302/src/send_uln.rs +23 -3
  72. package/contracts/message-libs/uln-302/src/uln302.rs +6 -24
  73. package/contracts/oapps/counter/Cargo.toml +14 -1
  74. package/contracts/oapps/counter/integration_tests/mod.rs +4 -1
  75. package/contracts/oapps/counter/integration_tests/{setup.rs → setup_sml.rs} +48 -80
  76. package/contracts/oapps/counter/integration_tests/setup_uln.rs +997 -0
  77. package/contracts/oapps/counter/integration_tests/signing.rs +62 -0
  78. package/contracts/oapps/counter/integration_tests/test_with_sml.rs +24 -55
  79. package/contracts/oapps/counter/integration_tests/test_with_uln.rs +314 -0
  80. package/contracts/oapps/counter/integration_tests/utils.rs +196 -53
  81. package/contracts/oapps/counter/src/counter.rs +67 -43
  82. package/contracts/oapps/counter/src/tests/mod.rs +0 -13
  83. package/contracts/oapps/counter/src/tests/test_counter.rs +5 -7
  84. package/contracts/oapps/oapp/src/errors.rs +5 -1
  85. package/contracts/oapps/oapp/src/macro_tests/test_macros.rs +93 -78
  86. package/contracts/oapps/oapp/src/oapp_core.rs +36 -21
  87. package/contracts/oapps/oapp/src/oapp_options_type3.rs +48 -12
  88. package/contracts/oapps/oapp/src/oapp_receiver.rs +106 -41
  89. package/contracts/oapps/oapp/src/oapp_sender.rs +26 -34
  90. package/contracts/oapps/oapp/src/tests/test_oapp_core.rs +9 -8
  91. package/contracts/oapps/oapp/src/tests/test_oapp_options_type3.rs +25 -17
  92. package/contracts/oapps/oapp/src/tests/test_oapp_receiver.rs +7 -7
  93. package/contracts/oapps/oapp/src/tests/test_oapp_sender.rs +14 -15
  94. package/contracts/oapps/oapp-macros/src/generators.rs +128 -0
  95. package/contracts/oapps/oapp-macros/src/lib.rs +113 -56
  96. package/contracts/oapps/oft/integration-tests/setup.rs +25 -7
  97. package/contracts/oapps/oft/src/errors.rs +6 -1
  98. package/contracts/oapps/oft/src/extensions/oft_fee.rs +8 -8
  99. package/contracts/oapps/oft/src/extensions/pausable.rs +4 -4
  100. package/contracts/oapps/oft/src/extensions/rate_limiter.rs +5 -5
  101. package/contracts/oapps/oft/src/lib.rs +4 -2
  102. package/contracts/oapps/oft/src/oft.rs +24 -64
  103. package/contracts/oapps/oft/src/oft_impl.rs +201 -0
  104. package/contracts/oapps/oft/src/oft_types/lock_unlock.rs +1 -3
  105. package/contracts/oapps/oft/src/oft_types/mint_burn.rs +1 -4
  106. package/contracts/oapps/oft/src/storage.rs +2 -0
  107. package/contracts/oapps/oft/src/tests/extensions/setup.rs +36 -22
  108. package/contracts/oapps/oft/src/tests/extensions/test_oft_fee.rs +5 -3
  109. package/contracts/oapps/oft/src/tests/extensions/test_pausable.rs +5 -3
  110. package/contracts/oapps/oft/src/tests/extensions/test_rate_limiter.rs +5 -3
  111. package/contracts/oapps/oft/src/tests/test_decimals.rs +2 -2
  112. package/contracts/oapps/oft/src/tests/test_oft_msg_codec.rs +1 -2
  113. package/contracts/oapps/oft/src/tests/test_utils.rs +45 -23
  114. package/contracts/oapps/oft/src/types.rs +20 -0
  115. package/contracts/oapps/oft-std/integration-tests/setup.rs +4 -2
  116. package/contracts/oapps/oft-std/src/oft.rs +24 -6
  117. package/contracts/upgrader/src/lib.rs +4 -4
  118. package/contracts/utils/src/auth.rs +44 -0
  119. package/contracts/utils/src/errors.rs +27 -5
  120. package/contracts/utils/src/lib.rs +3 -0
  121. package/contracts/utils/src/multisig.rs +211 -0
  122. package/contracts/utils/src/ownable.rs +12 -10
  123. package/contracts/utils/src/tests/buffer_reader.rs +6 -6
  124. package/contracts/utils/src/tests/buffer_writer.rs +6 -6
  125. package/contracts/utils/src/tests/bytes_ext.rs +2 -4
  126. package/contracts/utils/src/tests/mod.rs +1 -0
  127. package/contracts/utils/src/tests/multisig.rs +731 -0
  128. package/contracts/utils/src/tests/option_ext.rs +2 -5
  129. package/contracts/utils/src/tests/ownable.rs +16 -5
  130. package/contracts/utils/src/tests/ttl_configurable.rs +27 -16
  131. package/contracts/utils/src/tests/upgradeable.rs +4 -2
  132. package/contracts/utils/src/ttl_configurable.rs +23 -8
  133. package/contracts/utils/src/ttl_extendable.rs +27 -0
  134. package/contracts/utils/src/upgradeable.rs +2 -0
  135. package/contracts/workers/dvn/Cargo.toml +1 -1
  136. package/contracts/workers/dvn/src/auth.rs +7 -7
  137. package/contracts/workers/dvn/src/dvn.rs +10 -38
  138. package/contracts/workers/dvn/src/errors.rs +0 -7
  139. package/contracts/workers/dvn/src/events.rs +1 -14
  140. package/contracts/workers/dvn/src/interfaces/dvn.rs +2 -2
  141. package/contracts/workers/dvn/src/interfaces/mod.rs +0 -2
  142. package/contracts/workers/dvn/src/storage.rs +3 -13
  143. package/contracts/workers/dvn/src/tests/auth.rs +4 -4
  144. package/contracts/workers/dvn/src/tests/dvn.rs +1 -2
  145. package/contracts/workers/dvn/src/tests/multisig/set_signer.rs +7 -8
  146. package/contracts/workers/dvn/src/tests/multisig/set_threshold.rs +11 -8
  147. package/contracts/workers/dvn/src/tests/multisig/verify_signatures.rs +11 -12
  148. package/contracts/workers/dvn/src/tests/setup.rs +5 -5
  149. package/contracts/workers/dvn-fee-lib/Cargo.toml +1 -1
  150. package/contracts/workers/dvn-fee-lib/src/dvn_fee_lib.rs +3 -6
  151. package/contracts/workers/executor/src/auth.rs +80 -16
  152. package/contracts/workers/executor/src/executor.rs +5 -31
  153. package/contracts/workers/executor/src/storage.rs +2 -9
  154. package/contracts/workers/executor-fee-lib/Cargo.toml +1 -1
  155. package/contracts/workers/executor-fee-lib/src/executor_fee_lib.rs +3 -6
  156. package/contracts/workers/executor-helper/Cargo.toml +1 -1
  157. package/contracts/workers/executor-helper/src/executor_helper.rs +53 -73
  158. package/contracts/workers/price-feed/Cargo.toml +1 -1
  159. package/contracts/workers/price-feed/src/price_feed.rs +7 -10
  160. package/contracts/workers/worker/src/errors.rs +4 -0
  161. package/contracts/workers/worker/src/tests/worker.rs +7 -6
  162. package/contracts/workers/worker/src/worker.rs +20 -16
  163. package/package.json +8 -5
  164. package/sdk/.turbo/turbo-build.log +1 -0
  165. package/sdk/.turbo/turbo-test.log +1009 -0
  166. package/sdk/dist/generated/bml.d.ts +65 -8
  167. package/sdk/dist/generated/bml.js +70 -34
  168. package/sdk/dist/generated/counter.d.ts +167 -42
  169. package/sdk/dist/generated/counter.js +86 -45
  170. package/sdk/dist/generated/dvn.d.ts +282 -229
  171. package/sdk/dist/generated/dvn.js +119 -81
  172. package/sdk/dist/generated/dvn_fee_lib.d.ts +142 -67
  173. package/sdk/dist/generated/dvn_fee_lib.js +64 -24
  174. package/sdk/dist/generated/endpoint.d.ts +97 -22
  175. package/sdk/dist/generated/endpoint.js +75 -37
  176. package/sdk/dist/generated/executor.d.ts +117 -85
  177. package/sdk/dist/generated/executor.js +102 -59
  178. package/sdk/dist/generated/executor_fee_lib.d.ts +162 -78
  179. package/sdk/dist/generated/executor_fee_lib.js +104 -57
  180. package/sdk/dist/generated/executor_helper.d.ts +133 -21
  181. package/sdk/dist/generated/executor_helper.js +99 -50
  182. package/sdk/dist/generated/oft_std.d.ts +233 -55
  183. package/sdk/dist/generated/oft_std.js +99 -54
  184. package/sdk/dist/generated/price_feed.d.ts +142 -67
  185. package/sdk/dist/generated/price_feed.js +64 -24
  186. package/sdk/dist/generated/sml.d.ts +113 -32
  187. package/sdk/dist/generated/sml.js +93 -49
  188. package/sdk/dist/generated/treasury.d.ts +896 -0
  189. package/sdk/dist/generated/treasury.js +219 -0
  190. package/sdk/dist/generated/uln302.d.ts +113 -32
  191. package/sdk/dist/generated/uln302.js +93 -49
  192. package/sdk/dist/generated/upgrader.d.ts +2 -2
  193. package/sdk/dist/generated/upgrader.js +1 -1
  194. package/sdk/dist/index.d.ts +2 -0
  195. package/sdk/dist/index.js +3 -0
  196. package/sdk/dist/wasm/blocked-message-lib.d.ts +1 -0
  197. package/sdk/dist/wasm/blocked-message-lib.js +2 -0
  198. package/sdk/dist/wasm/counter.d.ts +1 -0
  199. package/sdk/dist/wasm/counter.js +2 -0
  200. package/sdk/dist/wasm/dvn-fee-lib.d.ts +1 -0
  201. package/sdk/dist/wasm/dvn-fee-lib.js +2 -0
  202. package/sdk/dist/wasm/dvn.d.ts +1 -0
  203. package/sdk/dist/wasm/dvn.js +2 -0
  204. package/sdk/dist/wasm/endpoint-v2.d.ts +1 -0
  205. package/sdk/dist/wasm/endpoint-v2.js +2 -0
  206. package/sdk/dist/wasm/executor-fee-lib.d.ts +1 -0
  207. package/sdk/dist/wasm/executor-fee-lib.js +2 -0
  208. package/sdk/dist/wasm/executor-helper.d.ts +1 -0
  209. package/sdk/dist/wasm/executor-helper.js +2 -0
  210. package/sdk/dist/wasm/executor.d.ts +1 -0
  211. package/sdk/dist/wasm/executor.js +2 -0
  212. package/sdk/dist/wasm/layerzero-views.d.ts +1 -0
  213. package/sdk/dist/wasm/layerzero-views.js +2 -0
  214. package/sdk/dist/wasm/oft-std.d.ts +1 -0
  215. package/sdk/dist/wasm/oft-std.js +2 -0
  216. package/sdk/dist/wasm/price-feed.d.ts +1 -0
  217. package/sdk/dist/wasm/price-feed.js +2 -0
  218. package/sdk/dist/wasm/simple-message-lib.d.ts +1 -0
  219. package/sdk/dist/wasm/simple-message-lib.js +2 -0
  220. package/sdk/dist/wasm/treasury.d.ts +1 -0
  221. package/sdk/dist/wasm/treasury.js +2 -0
  222. package/sdk/dist/wasm/uln302.d.ts +1 -0
  223. package/sdk/dist/wasm/uln302.js +2 -0
  224. package/sdk/dist/wasm/upgrader.d.ts +1 -0
  225. package/sdk/dist/wasm/upgrader.js +2 -0
  226. package/sdk/dist/wasm.d.ts +15 -0
  227. package/sdk/dist/wasm.js +15 -0
  228. package/sdk/package.json +4 -2
  229. package/sdk/src/index.ts +4 -0
  230. package/sdk/test/counter-sml.test.ts +376 -0
  231. package/sdk/test/counter-uln.test.ts +493 -0
  232. package/sdk/test/{oft.test.ts → oft-sml.test.ts} +185 -310
  233. package/sdk/test/suites/constants.ts +22 -2
  234. package/sdk/test/suites/globalSetup.ts +450 -0
  235. package/sdk/test/suites/localnet.ts +23 -6
  236. package/sdk/test/upgrader.test.ts +7 -16
  237. package/sdk/test/utils.ts +558 -85
  238. package/sdk/vitest.config.ts +21 -0
  239. package/tools/ts-bindings-gen/src/main.rs +1 -0
  240. package/turbo.json +2 -0
  241. package/contracts/common-macros/src/contract_impl.rs +0 -52
  242. package/contracts/common-macros/src/ownable.rs +0 -41
  243. package/contracts/common-macros/src/tests/contract_impl.rs +0 -386
  244. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__ownable__snapshot_generated_ownable_code.snap +0 -12
  245. package/contracts/macro-integration-tests/tests/runtime/ttl_configurable/extend_instance_ttl.rs +0 -50
  246. package/contracts/oapps/oapp-macros/src/oapp_core.rs +0 -41
  247. package/contracts/oapps/oapp-macros/src/oapp_full.rs +0 -21
  248. package/contracts/oapps/oapp-macros/src/oapp_options_type3.rs +0 -31
  249. package/contracts/oapps/oapp-macros/src/oapp_receiver.rs +0 -48
  250. package/contracts/oapps/oapp-macros/src/oapp_sender.rs +0 -21
  251. package/contracts/oapps/oapp-macros/src/util.rs +0 -107
  252. package/contracts/oapps/oft/src/constants.rs +0 -5
  253. package/contracts/oapps/oft/src/default_oft_impl.rs +0 -152
  254. package/contracts/workers/dvn/src/interfaces/multisig.rs +0 -56
  255. package/contracts/workers/dvn/src/multisig.rs +0 -157
  256. package/sdk/test/index.test.ts +0 -375
  257. /package/sdk/test/suites/{testUpgradeable.ts → dummyContractClient.ts} +0 -0
@@ -0,0 +1,662 @@
1
+ use proc_macro2::TokenStream;
2
+ use quote::quote;
3
+
4
+ use crate::tests::test_helpers::assert_panics_contains;
5
+
6
+ // ============================================================================
7
+ // Snapshot Tests
8
+ // ============================================================================
9
+
10
+ /// Comprehensive snapshot test for contractimpl_with_ttl macro:
11
+ /// - Inherent impl: public methods with Env (adds TTL), private/pub(crate) methods (skipped)
12
+ /// - Trait impl: all methods with Env get TTL extension
13
+ /// - Qualified Env types (soroban_sdk::Env)
14
+ /// - Env parameter not in first position
15
+ /// - Methods without Env (skipped)
16
+ #[test]
17
+ fn snapshot_generated_contractimpl_code() {
18
+ // Test inherent impl with empty attr
19
+ let empty_attr = TokenStream::new();
20
+ let inherent_input = quote! {
21
+ impl MyContract {
22
+ /// Public method with Env - should have TTL extension
23
+ pub fn public_with_env(env: Env, value: u32) -> u32 {
24
+ value * 2
25
+ }
26
+
27
+ /// Public method with qualified Env path - should have TTL extension
28
+ pub fn with_qualified_env(env: soroban_sdk::Env) -> u32 {
29
+ 42
30
+ }
31
+
32
+ /// Public method with Env not as first parameter - should have TTL extension
33
+ pub fn env_second(value: u32, env: &Env) -> u32 {
34
+ value * 2
35
+ }
36
+
37
+ /// Public method without Env - should NOT have TTL extension
38
+ pub fn public_without_env(value: u32) -> u32 {
39
+ value * 4
40
+ }
41
+
42
+ /// Private method with Env - should NOT have TTL extension (not public)
43
+ fn private_with_env(env: Env, value: u32) -> u32 {
44
+ value * 5
45
+ }
46
+
47
+ /// Pub(crate) method with Env - should NOT have TTL extension (not fully public)
48
+ pub(crate) fn pub_crate_with_env(env: Env, value: u32) -> u32 {
49
+ value * 7
50
+ }
51
+
52
+ /// Constructor method - should NOT have TTL extension
53
+ pub fn __constructor(env: &Env, value: u32) {
54
+ let _ = value * 2;
55
+ }
56
+ }
57
+ };
58
+
59
+ let inherent_result = crate::contract_ttl::contractimpl_with_ttl(empty_attr.clone(), inherent_input);
60
+ let inherent_formatted =
61
+ prettyplease::unparse(&syn::parse2::<syn::File>(inherent_result).expect("failed to parse generated code"));
62
+
63
+ // Test trait impl with empty attr
64
+ let trait_input = quote! {
65
+ impl SomeTrait for MyContract {
66
+ /// Trait method with Env - should have TTL extension
67
+ fn trait_method_with_env(env: Env, value: u32) -> u32 {
68
+ value * 2
69
+ }
70
+
71
+ /// Trait method without Env - should NOT have TTL extension
72
+ fn trait_method_without_env(value: u32) -> u32 {
73
+ value * 4
74
+ }
75
+
76
+ /// Trait method with macro attribute - should have TTL extension
77
+ #[common_macros::only_auth]
78
+ fn trait_method_with_only_auth_attribute(env: Env, value: u32) -> u32 {
79
+ value * 5
80
+ }
81
+ }
82
+ };
83
+
84
+ let trait_result = crate::contract_ttl::contractimpl_with_ttl(empty_attr, trait_input);
85
+ let trait_formatted =
86
+ prettyplease::unparse(&syn::parse2::<syn::File>(trait_result).expect("failed to parse generated code"));
87
+
88
+ // Test trait impl with contracttrait attr
89
+ let contracttrait_attr = quote! { contracttrait };
90
+ let contracttrait_input = quote! {
91
+ impl AnotherTrait for MyContract {
92
+ /// Trait method with contracttrait attr - should have TTL extension
93
+ fn contracttrait_method(env: &Env, value: u32) -> u32 {
94
+ value * 3
95
+ }
96
+ }
97
+ };
98
+
99
+ let contracttrait_result = crate::contract_ttl::contractimpl_with_ttl(contracttrait_attr, contracttrait_input);
100
+ let contracttrait_formatted =
101
+ prettyplease::unparse(&syn::parse2::<syn::File>(contracttrait_result).expect("failed to parse generated code"));
102
+
103
+ // Combine all for single snapshot
104
+ let combined = format!(
105
+ "// === Inherent Impl (no attr) ===\n\n{}\n\n// === Trait Impl (no attr) ===\n\n{}\n\n// === Trait Impl (contracttrait attr) ===\n\n{}",
106
+ inherent_formatted, trait_formatted, contracttrait_formatted
107
+ );
108
+
109
+ insta::assert_snapshot!(combined);
110
+ }
111
+
112
+ /// Comprehensive snapshot test for contracttrait_with_ttl macro:
113
+ /// - Default methods with Env (adds TTL)
114
+ /// - Abstract methods without body (skipped)
115
+ /// - Methods without Env (skipped)
116
+ /// - Qualified Env types (soroban_sdk::Env)
117
+ /// - Env parameter not in first position
118
+ #[test]
119
+ fn snapshot_generated_contracttrait_code() {
120
+ // Test trait with empty attr
121
+ let empty_attr = TokenStream::new();
122
+ let trait_input = quote! {
123
+ pub trait MyTrait: Sized {
124
+ /// Default method with Env - should have TTL extension
125
+ fn default_with_env(env: Env, value: u32) -> u32 {
126
+ value * 2
127
+ }
128
+
129
+ /// Default method with qualified Env path - should have TTL extension
130
+ fn with_qualified_env(env: soroban_sdk::Env) -> u32 {
131
+ 42
132
+ }
133
+
134
+ /// Default method with Env not as first parameter - should have TTL extension
135
+ fn env_second(value: u32, env: &Env) -> u32 {
136
+ value * 2
137
+ }
138
+
139
+ /// Default method without Env - should NOT have TTL extension
140
+ fn default_without_env(value: u32) -> u32 {
141
+ value * 4
142
+ }
143
+
144
+ /// Abstract method with Env - should NOT have TTL extension (no body)
145
+ fn abstract_with_env(env: Env, value: u32) -> u32;
146
+
147
+ /// Abstract method without Env - should NOT have TTL extension (no body)
148
+ fn abstract_without_env(value: u32) -> u32;
149
+ }
150
+ };
151
+
152
+ let trait_result = crate::contract_ttl::contracttrait_with_ttl(empty_attr.clone(), trait_input);
153
+ let trait_formatted =
154
+ prettyplease::unparse(&syn::parse2::<syn::File>(trait_result).expect("failed to parse generated code"));
155
+
156
+ // Test trait with crate attr
157
+ let crate_attr = quote! { crate = "other_sdk" };
158
+ let trait_with_attr_input = quote! {
159
+ pub trait AnotherTrait {
160
+ /// Default method with Env - should have TTL extension
161
+ fn method_with_env(env: &Env, value: u32) -> u32 {
162
+ value * 3
163
+ }
164
+ }
165
+ };
166
+
167
+ let trait_with_attr_result = crate::contract_ttl::contracttrait_with_ttl(crate_attr, trait_with_attr_input);
168
+ let trait_with_attr_formatted = prettyplease::unparse(
169
+ &syn::parse2::<syn::File>(trait_with_attr_result).expect("failed to parse generated code"),
170
+ );
171
+
172
+ // Combine all for single snapshot
173
+ let combined = format!(
174
+ "// === Trait (no attr) ===\n\n{}\n\n// === Trait (crate attr) ===\n\n{}",
175
+ trait_formatted, trait_with_attr_formatted
176
+ );
177
+
178
+ insta::assert_snapshot!(combined);
179
+ }
180
+
181
+ // ============================================================================
182
+ // Error Cases: Invalid Input
183
+ // ============================================================================
184
+
185
+ #[test]
186
+ fn test_contractimpl_non_impl_block_input() {
187
+ let invalid_inputs = vec![
188
+ (
189
+ "struct",
190
+ quote! {
191
+ struct MyStruct {
192
+ field: u32,
193
+ }
194
+ },
195
+ ),
196
+ (
197
+ "enum",
198
+ quote! {
199
+ enum MyEnum {
200
+ Variant1,
201
+ Variant2,
202
+ }
203
+ },
204
+ ),
205
+ ("function", quote! { fn a_function() {} }),
206
+ ("const item", quote! { const A_CONST: u32 = 1; }),
207
+ ("type alias", quote! { type AnAlias = u32; }),
208
+ (
209
+ "trait",
210
+ quote! {
211
+ trait ATrait {
212
+ fn method(&self);
213
+ }
214
+ },
215
+ ),
216
+ ];
217
+
218
+ for (case, input) in invalid_inputs {
219
+ assert_panics_contains(case, "failed to parse impl block", || {
220
+ crate::contract_ttl::contractimpl_with_ttl(TokenStream::new(), input.clone());
221
+ });
222
+ }
223
+ }
224
+
225
+ #[test]
226
+ fn test_contracttrait_non_trait_input() {
227
+ let invalid_inputs = vec![
228
+ (
229
+ "struct",
230
+ quote! {
231
+ struct MyStruct {
232
+ field: u32,
233
+ }
234
+ },
235
+ ),
236
+ (
237
+ "enum",
238
+ quote! {
239
+ enum MyEnum {
240
+ Variant1,
241
+ Variant2,
242
+ }
243
+ },
244
+ ),
245
+ ("function", quote! { fn a_function() {} }),
246
+ ("const item", quote! { const A_CONST: u32 = 1; }),
247
+ ("type alias", quote! { type AnAlias = u32; }),
248
+ (
249
+ "impl block",
250
+ quote! {
251
+ impl MyContract {
252
+ fn method(&self) {}
253
+ }
254
+ },
255
+ ),
256
+ ];
257
+
258
+ for (case, input) in invalid_inputs {
259
+ assert_panics_contains(case, "failed to parse trait definition", || {
260
+ crate::contract_ttl::contracttrait_with_ttl(TokenStream::new(), input.clone());
261
+ });
262
+ }
263
+ }
264
+
265
+ // ============================================================================
266
+ // Unit Tests: Attribute Handling
267
+ // ============================================================================
268
+
269
+ /// Verifies that contractimpl_with_ttl adds #[soroban_sdk::contractimpl] without parentheses when attr is empty
270
+ #[test]
271
+ fn test_contractimpl_adds_attribute_without_attr() {
272
+ let input = quote! {
273
+ impl MyContract {
274
+ pub fn my_method(env: Env) {}
275
+ }
276
+ };
277
+
278
+ let result = crate::contract_ttl::contractimpl_with_ttl(TokenStream::new(), input);
279
+ let result_str = result.to_string();
280
+
281
+ assert!(
282
+ result_str.contains("# [soroban_sdk :: contractimpl]"),
283
+ "should add #[soroban_sdk::contractimpl] attribute without parentheses when attr is empty. Got: {}",
284
+ result_str
285
+ );
286
+ assert!(
287
+ !result_str.contains("contractimpl ()"),
288
+ "should NOT have empty parentheses when attr is empty. Got: {}",
289
+ result_str
290
+ );
291
+ }
292
+
293
+ /// Verifies that contractimpl_with_ttl adds #[soroban_sdk::contractimpl(attr)] when attr is provided
294
+ #[test]
295
+ fn test_contractimpl_adds_attribute_with_attr() {
296
+ let input = quote! {
297
+ impl SomeTrait for MyContract {
298
+ fn my_method(env: Env) {}
299
+ }
300
+ };
301
+
302
+ let attr = quote! { contracttrait };
303
+ let result = crate::contract_ttl::contractimpl_with_ttl(attr, input);
304
+ let result_str = result.to_string();
305
+
306
+ assert!(
307
+ result_str.contains("contractimpl (contracttrait)"),
308
+ "should add #[soroban_sdk::contractimpl(contracttrait)] attribute. Got: {}",
309
+ result_str
310
+ );
311
+ }
312
+
313
+ /// Verifies that contracttrait_with_ttl adds #[soroban_sdk::contracttrait] without parentheses when attr is empty
314
+ #[test]
315
+ fn test_contracttrait_adds_attribute_without_attr() {
316
+ let input = quote! {
317
+ pub trait MyTrait {
318
+ fn my_method(env: Env) {}
319
+ }
320
+ };
321
+
322
+ let result = crate::contract_ttl::contracttrait_with_ttl(TokenStream::new(), input);
323
+ let result_str = result.to_string();
324
+
325
+ assert!(
326
+ result_str.contains("# [soroban_sdk :: contracttrait]"),
327
+ "should add #[soroban_sdk::contracttrait] attribute without parentheses when attr is empty. Got: {}",
328
+ result_str
329
+ );
330
+ assert!(
331
+ !result_str.contains("contracttrait ()"),
332
+ "should NOT have empty parentheses when attr is empty. Got: {}",
333
+ result_str
334
+ );
335
+ }
336
+
337
+ /// Verifies that contracttrait_with_ttl adds #[soroban_sdk::contracttrait(attr)] when attr is provided
338
+ #[test]
339
+ fn test_contracttrait_adds_attribute_with_attr() {
340
+ let input = quote! {
341
+ pub trait MyTrait {
342
+ fn my_method(env: Env) {}
343
+ }
344
+ };
345
+
346
+ let attr = quote! { crate = "my_crate" };
347
+ let result = crate::contract_ttl::contracttrait_with_ttl(attr, input);
348
+ let result_str = result.to_string();
349
+
350
+ assert!(
351
+ result_str.contains("contracttrait (crate = \"my_crate\")"),
352
+ "should add #[soroban_sdk::contracttrait(crate = \"my_crate\")] attribute. Got: {}",
353
+ result_str
354
+ );
355
+ }
356
+
357
+ // ============================================================================
358
+ // TTL Extension Test Infrastructure
359
+ // ============================================================================
360
+
361
+ /// Expected TTL extension behavior for a test case
362
+ #[derive(Clone)]
363
+ enum TtlExpectation {
364
+ /// TTL extension should NOT be inserted
365
+ None,
366
+ /// TTL extension should be inserted with the given env patterns
367
+ /// - `instance_arg`: pattern in `TtlConfigStorage::instance(...)` (e.g., "& env" for owned, "env" for ref)
368
+ /// - `storage_ident`: identifier for `.storage()` call
369
+ Present { instance_arg: &'static str, storage_ident: &'static str },
370
+ }
371
+
372
+ /// Test runner for contractimpl_with_ttl TTL behavior
373
+ struct ImplTtlTestCase {
374
+ name: &'static str,
375
+ input: TokenStream,
376
+ expectation: TtlExpectation,
377
+ }
378
+
379
+ impl ImplTtlTestCase {
380
+ fn expect_ttl(
381
+ name: &'static str,
382
+ input: TokenStream,
383
+ instance_arg: &'static str,
384
+ storage_ident: &'static str,
385
+ ) -> Self {
386
+ Self { name, input, expectation: TtlExpectation::Present { instance_arg, storage_ident } }
387
+ }
388
+
389
+ fn expect_no_ttl(name: &'static str, input: TokenStream) -> Self {
390
+ Self { name, input, expectation: TtlExpectation::None }
391
+ }
392
+
393
+ fn run(&self) {
394
+ let result = crate::contract_ttl::contractimpl_with_ttl(TokenStream::new(), self.input.clone());
395
+ let result_str = result.to_string();
396
+ assert_ttl_expectation(&self.expectation, &result_str, self.name);
397
+ }
398
+ }
399
+
400
+ /// Test runner for contracttrait_with_ttl TTL behavior
401
+ struct TraitTtlTestCase {
402
+ name: &'static str,
403
+ input: TokenStream,
404
+ expectation: TtlExpectation,
405
+ }
406
+
407
+ impl TraitTtlTestCase {
408
+ fn expect_ttl(
409
+ name: &'static str,
410
+ input: TokenStream,
411
+ instance_arg: &'static str,
412
+ storage_ident: &'static str,
413
+ ) -> Self {
414
+ Self { name, input, expectation: TtlExpectation::Present { instance_arg, storage_ident } }
415
+ }
416
+
417
+ fn expect_no_ttl(name: &'static str, input: TokenStream) -> Self {
418
+ Self { name, input, expectation: TtlExpectation::None }
419
+ }
420
+
421
+ fn run(&self) {
422
+ let result = crate::contract_ttl::contracttrait_with_ttl(TokenStream::new(), self.input.clone());
423
+ let result_str = result.to_string();
424
+ assert_ttl_expectation(&self.expectation, &result_str, self.name);
425
+ }
426
+ }
427
+
428
+ fn assert_ttl_expectation(expectation: &TtlExpectation, result_str: &str, name: &str) {
429
+ let has_ttl = result_str.contains("TtlConfigStorage :: instance");
430
+
431
+ match expectation {
432
+ TtlExpectation::None => {
433
+ assert!(!has_ttl, "{}: TTL extension should NOT be present, but was found", name);
434
+ }
435
+ TtlExpectation::Present { instance_arg, storage_ident } => {
436
+ assert!(has_ttl, "{}: TTL extension should be present, but was not found", name);
437
+ assert!(result_str.contains("extend_ttl"), "{}: should insert extend_ttl call", name);
438
+
439
+ let instance_pattern = format!("TtlConfigStorage :: instance ({})", instance_arg);
440
+ assert!(
441
+ result_str.contains(&instance_pattern),
442
+ "{}: expected '{}' in TtlConfigStorage::instance call. Got: {}",
443
+ name,
444
+ instance_arg,
445
+ result_str
446
+ );
447
+
448
+ let storage_pattern = format!("{} . storage ()", storage_ident);
449
+ assert!(result_str.contains(&storage_pattern), "{}: expected '{}.storage()' call", name, storage_ident);
450
+ }
451
+ }
452
+ }
453
+
454
+ // ============================================================================
455
+ // TTL Extension Tests: contractimpl_with_ttl
456
+ // ============================================================================
457
+
458
+ #[test]
459
+ fn test_impl_ttl_extension_with_owned_env() {
460
+ ImplTtlTestCase::expect_ttl(
461
+ "public method with owned Env",
462
+ quote! {
463
+ impl MyContract {
464
+ pub fn my_method(env: Env) { let x = 1; }
465
+ }
466
+ },
467
+ "& env", // instance takes reference
468
+ "env", // storage called on ident
469
+ )
470
+ .run();
471
+ }
472
+
473
+ #[test]
474
+ fn test_impl_ttl_extension_with_ref_env() {
475
+ ImplTtlTestCase::expect_ttl(
476
+ "public method with ref Env",
477
+ quote! {
478
+ impl MyContract {
479
+ pub fn my_method(env: &Env) { let x = 1; }
480
+ }
481
+ },
482
+ "env", // instance takes ident directly (already a ref)
483
+ "env",
484
+ )
485
+ .run();
486
+ }
487
+
488
+ #[test]
489
+ fn test_impl_ttl_extension_with_custom_env_ident_owned() {
490
+ ImplTtlTestCase::expect_ttl(
491
+ "custom Env identifier (owned)",
492
+ quote! {
493
+ impl MyContract {
494
+ pub fn my_method(my_custom_env: Env) { let x = 1; }
495
+ }
496
+ },
497
+ "& my_custom_env",
498
+ "my_custom_env",
499
+ )
500
+ .run();
501
+ }
502
+
503
+ #[test]
504
+ fn test_impl_ttl_extension_with_custom_env_ident_ref() {
505
+ ImplTtlTestCase::expect_ttl(
506
+ "custom Env identifier (ref)",
507
+ quote! {
508
+ impl MyContract {
509
+ pub fn my_method(my_custom_env: &Env) { let x = 1; }
510
+ }
511
+ },
512
+ "my_custom_env",
513
+ "my_custom_env",
514
+ )
515
+ .run();
516
+ }
517
+
518
+ #[test]
519
+ fn test_impl_ttl_extension_for_trait_impl_owned_env() {
520
+ ImplTtlTestCase::expect_ttl(
521
+ "trait impl method with owned Env",
522
+ quote! {
523
+ impl SomeTrait for MyContract {
524
+ fn trait_method(env: Env) { let x = 1; }
525
+ }
526
+ },
527
+ "& env",
528
+ "env",
529
+ )
530
+ .run();
531
+ }
532
+
533
+ #[test]
534
+ fn test_impl_ttl_extension_for_trait_impl_ref_env() {
535
+ ImplTtlTestCase::expect_ttl(
536
+ "trait impl method with ref Env",
537
+ quote! {
538
+ impl SomeTrait for MyContract {
539
+ fn trait_method(env: &Env) { let x = 1; }
540
+ }
541
+ },
542
+ "env",
543
+ "env",
544
+ )
545
+ .run();
546
+ }
547
+
548
+ #[test]
549
+ fn test_impl_no_ttl_extension_for_private_method() {
550
+ ImplTtlTestCase::expect_no_ttl(
551
+ "private method with Env",
552
+ quote! {
553
+ impl MyContract {
554
+ fn private_method(env: Env) { let x = 1; }
555
+ }
556
+ },
557
+ )
558
+ .run();
559
+ }
560
+
561
+ #[test]
562
+ fn test_impl_no_ttl_extension_without_env_param() {
563
+ ImplTtlTestCase::expect_no_ttl(
564
+ "public method without Env",
565
+ quote! {
566
+ impl MyContract {
567
+ pub fn no_env_method(value: u32) -> u32 { value }
568
+ }
569
+ },
570
+ )
571
+ .run();
572
+ }
573
+
574
+ // ============================================================================
575
+ // TTL Extension Tests: contracttrait_with_ttl
576
+ // ============================================================================
577
+
578
+ #[test]
579
+ fn test_trait_ttl_extension_with_owned_env() {
580
+ TraitTtlTestCase::expect_ttl(
581
+ "default method with owned Env",
582
+ quote! {
583
+ trait MyTrait {
584
+ fn my_method(env: Env) { let x = 1; }
585
+ }
586
+ },
587
+ "& env", // instance takes reference
588
+ "env", // storage called on ident
589
+ )
590
+ .run();
591
+ }
592
+
593
+ #[test]
594
+ fn test_trait_ttl_extension_with_ref_env() {
595
+ TraitTtlTestCase::expect_ttl(
596
+ "default method with ref Env",
597
+ quote! {
598
+ trait MyTrait {
599
+ fn my_method(env: &Env) { let x = 1; }
600
+ }
601
+ },
602
+ "env", // instance takes ident directly (already a ref)
603
+ "env",
604
+ )
605
+ .run();
606
+ }
607
+
608
+ #[test]
609
+ fn test_trait_ttl_extension_with_custom_env_ident_owned() {
610
+ TraitTtlTestCase::expect_ttl(
611
+ "custom Env identifier (owned)",
612
+ quote! {
613
+ trait MyTrait {
614
+ fn my_method(my_custom_env: Env) { let x = 1; }
615
+ }
616
+ },
617
+ "& my_custom_env",
618
+ "my_custom_env",
619
+ )
620
+ .run();
621
+ }
622
+
623
+ #[test]
624
+ fn test_trait_ttl_extension_with_custom_env_ident_ref() {
625
+ TraitTtlTestCase::expect_ttl(
626
+ "custom Env identifier (ref)",
627
+ quote! {
628
+ trait MyTrait {
629
+ fn my_method(my_custom_env: &Env) { let x = 1; }
630
+ }
631
+ },
632
+ "my_custom_env",
633
+ "my_custom_env",
634
+ )
635
+ .run();
636
+ }
637
+
638
+ #[test]
639
+ fn test_trait_no_ttl_extension_for_abstract_method() {
640
+ TraitTtlTestCase::expect_no_ttl(
641
+ "abstract method with Env (no body)",
642
+ quote! {
643
+ trait MyTrait {
644
+ fn abstract_method(env: Env) -> u32;
645
+ }
646
+ },
647
+ )
648
+ .run();
649
+ }
650
+
651
+ #[test]
652
+ fn test_trait_no_ttl_extension_without_env_param() {
653
+ TraitTtlTestCase::expect_no_ttl(
654
+ "default method without Env",
655
+ quote! {
656
+ trait MyTrait {
657
+ fn no_env_method(value: u32) -> u32 { value }
658
+ }
659
+ },
660
+ )
661
+ .run();
662
+ }
@@ -1,6 +1,6 @@
1
- mod contract_impl;
1
+ mod auth;
2
+ mod contract_ttl;
2
3
  mod error;
3
- mod ownable;
4
4
  mod storage;
5
5
  mod test_helpers;
6
6
  mod ttl_configurable;
@@ -0,0 +1,20 @@
1
+ ---
2
+ source: contracts/common-macros/src/tests/auth.rs
3
+ assertion_line: 33
4
+ expression: formatted
5
+ ---
6
+ pub struct MyContract;
7
+ use utils::{auth::Auth as _, multisig::Multisig as _};
8
+ #[doc(hidden)]
9
+ mod __multisig_impl_my_contract {
10
+ use super::*;
11
+ use utils::{auth::Auth, multisig::Multisig};
12
+ #[common_macros::contract_impl]
13
+ impl Auth for MyContract {
14
+ fn authorizer(env: &soroban_sdk::Env) -> soroban_sdk::Address {
15
+ env.current_contract_address()
16
+ }
17
+ }
18
+ #[common_macros::contract_impl(contracttrait)]
19
+ impl Multisig for MyContract {}
20
+ }