@layerzerolabs/protocol-stellar-v2 0.2.8 → 0.2.10

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 (239) hide show
  1. package/.turbo/turbo-build.log +443 -302
  2. package/.turbo/turbo-lint.log +118 -96
  3. package/.turbo/turbo-test.log +853 -731
  4. package/Cargo.lock +120 -37
  5. package/Cargo.toml +8 -5
  6. package/contracts/common-macros/src/contract_impl.rs +44 -0
  7. package/contracts/common-macros/src/lib.rs +86 -40
  8. package/contracts/common-macros/src/ownable.rs +24 -32
  9. package/contracts/common-macros/src/storage.rs +95 -120
  10. package/contracts/common-macros/src/tests/contract_impl.rs +289 -0
  11. package/contracts/common-macros/src/tests/mod.rs +9 -0
  12. package/contracts/common-macros/src/tests/ownable.rs +151 -0
  13. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__contract_impl__snapshot_generated_contract_impl_code.snap +85 -0
  14. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__ownable__snapshot_generated_ownable_code.snap +30 -0
  15. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__ownable__snapshot_only_owner_preserves_function_signature.snap +9 -0
  16. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__storage__snapshot_generated_storage_code.snap +1072 -0
  17. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__ttl_configurable__snapshot_generated_ttl_configurable_code.snap +45 -0
  18. package/contracts/common-macros/src/tests/storage.rs +485 -0
  19. package/contracts/common-macros/src/tests/test_helpers.rs +93 -0
  20. package/contracts/common-macros/src/tests/ttl_configurable.rs +34 -0
  21. package/contracts/common-macros/src/ttl_configurable.rs +31 -14
  22. package/contracts/common-macros/src/utils.rs +27 -0
  23. package/contracts/endpoint-v2/ARCHITECTURE.md +4 -4
  24. package/contracts/endpoint-v2/src/endpoint_v2.rs +18 -15
  25. package/contracts/endpoint-v2/src/interfaces/message_lib.rs +2 -3
  26. package/contracts/endpoint-v2/src/interfaces/message_lib_manager.rs +5 -3
  27. package/contracts/endpoint-v2/src/interfaces/messaging_channel.rs +2 -2
  28. package/contracts/endpoint-v2/src/interfaces/messaging_composer.rs +2 -2
  29. package/contracts/endpoint-v2/src/interfaces/send_lib.rs +4 -4
  30. package/contracts/endpoint-v2/src/lib.rs +6 -5
  31. package/contracts/endpoint-v2/src/message_lib_manager.rs +14 -6
  32. package/contracts/endpoint-v2/src/messaging_channel.rs +6 -2
  33. package/contracts/endpoint-v2/src/messaging_composer.rs +6 -2
  34. package/contracts/endpoint-v2/src/storage.rs +10 -7
  35. package/contracts/endpoint-v2/src/tests/endpoint_v2/pay_messaging_fees.rs +16 -16
  36. package/contracts/endpoint-v2/src/tests/endpoint_v2/ttl_config.rs +46 -46
  37. package/contracts/endpoint-v2/src/tests/mock.rs +2 -2
  38. package/contracts/endpoint-v2/src/util.rs +8 -2
  39. package/contracts/message-libs/block-message-lib/Cargo.toml +1 -0
  40. package/contracts/message-libs/block-message-lib/src/lib.rs +5 -5
  41. package/contracts/message-libs/message-lib-common/src/errors.rs +8 -8
  42. package/contracts/message-libs/message-lib-common/src/interfaces/dvn.rs +0 -1
  43. package/contracts/message-libs/message-lib-common/src/interfaces/mod.rs +3 -3
  44. package/contracts/message-libs/message-lib-common/src/lib.rs +0 -2
  45. package/contracts/message-libs/message-lib-common/src/packet_codec_v1.rs +4 -6
  46. package/contracts/message-libs/message-lib-common/src/tests/packet_codec_v1.rs +2 -2
  47. package/contracts/message-libs/message-lib-common/src/tests/worker_options.rs +11 -11
  48. package/contracts/message-libs/message-lib-common/src/worker_options.rs +10 -16
  49. package/contracts/message-libs/simple-message-lib/src/errors.rs +0 -4
  50. package/contracts/message-libs/simple-message-lib/src/simple_message_lib.rs +49 -34
  51. package/contracts/message-libs/simple-message-lib/src/storage.rs +3 -7
  52. package/contracts/message-libs/simple-message-lib/src/test.rs +3 -3
  53. package/contracts/message-libs/treasury/src/storage.rs +1 -2
  54. package/contracts/message-libs/treasury/src/tests/setup.rs +3 -2
  55. package/contracts/message-libs/treasury/src/tests/treasury_tests.rs +0 -13
  56. package/contracts/message-libs/treasury/src/treasury.rs +18 -21
  57. package/contracts/message-libs/uln-302/Cargo.toml +1 -0
  58. package/contracts/message-libs/uln-302/src/interfaces/mod.rs +4 -4
  59. package/contracts/message-libs/uln-302/src/interfaces/{receive.rs → receive_uln.rs} +3 -3
  60. package/contracts/message-libs/uln-302/src/interfaces/{send.rs → send_uln.rs} +8 -80
  61. package/contracts/message-libs/uln-302/src/lib.rs +5 -4
  62. package/contracts/message-libs/uln-302/src/{receive.rs → receive_uln.rs} +20 -12
  63. package/contracts/message-libs/uln-302/src/{send.rs → send_uln.rs} +19 -13
  64. package/contracts/message-libs/uln-302/src/storage.rs +1 -2
  65. package/contracts/message-libs/uln-302/src/tests/config/uln_config.rs +3 -2
  66. package/contracts/message-libs/uln-302/src/tests/send_uln302/send.rs +30 -30
  67. package/contracts/message-libs/uln-302/src/tests/setup.rs +12 -11
  68. package/contracts/message-libs/uln-302/src/tests/uln302/set_config.rs +1 -1
  69. package/contracts/message-libs/uln-302/src/{config_validation.rs → types.rs} +79 -11
  70. package/contracts/message-libs/uln-302/src/uln302.rs +15 -10
  71. package/contracts/oapp-macros/Cargo.toml +2 -8
  72. package/contracts/oapp-macros/src/lib.rs +57 -311
  73. package/contracts/oapp-macros/src/oapp_core.rs +23 -32
  74. package/contracts/oapp-macros/src/oapp_full.rs +8 -2
  75. package/contracts/oapp-macros/src/oapp_options_type3.rs +21 -36
  76. package/contracts/oapp-macros/src/oapp_receiver.rs +38 -57
  77. package/contracts/oapp-macros/src/oapp_sender.rs +12 -14
  78. package/contracts/oapp-macros/src/util.rs +14 -10
  79. package/contracts/oapps/counter/Cargo.toml +2 -1
  80. package/contracts/oapps/counter/integration_tests/utils.rs +4 -4
  81. package/contracts/oapps/counter/src/codec.rs +8 -9
  82. package/contracts/oapps/counter/src/counter.rs +156 -147
  83. package/contracts/oapps/counter/src/storage.rs +1 -2
  84. package/contracts/oapps/counter/src/tests/test_codec.rs +5 -5
  85. package/contracts/oapps/counter/src/tests/test_counter.rs +11 -13
  86. package/contracts/oapps/oapp/Cargo.toml +1 -0
  87. package/contracts/oapps/oapp/src/errors.rs +1 -1
  88. package/contracts/oapps/oapp/src/lib.rs +3 -0
  89. package/contracts/oapps/oapp/src/macro_tests/mod.rs +1 -0
  90. package/contracts/oapps/oapp/src/macro_tests/test_macros.rs +312 -0
  91. package/contracts/oapps/oapp/src/oapp_core.rs +52 -53
  92. package/contracts/oapps/oapp/src/oapp_options_type3.rs +18 -28
  93. package/contracts/oapps/oapp/src/oapp_receiver.rs +82 -31
  94. package/contracts/oapps/oapp/src/oapp_sender.rs +55 -13
  95. package/contracts/oapps/oapp/src/tests/test_oapp_core.rs +16 -3
  96. package/contracts/oapps/oapp/src/tests/test_oapp_options_type3.rs +33 -8
  97. package/contracts/oapps/oapp/src/tests/test_oapp_receiver.rs +6 -9
  98. package/contracts/oapps/oapp/src/tests/test_oapp_sender.rs +28 -15
  99. package/contracts/oapps/oft/Cargo.toml +27 -0
  100. package/contracts/oapps/oft/integration-tests/mod.rs +3 -0
  101. package/contracts/oapps/oft/integration-tests/setup.rs +320 -0
  102. package/contracts/oapps/oft/integration-tests/test_with_sml.rs +155 -0
  103. package/contracts/oapps/oft/integration-tests/utils.rs +201 -0
  104. package/contracts/oapps/oft/src/codec/mod.rs +2 -0
  105. package/contracts/oapps/oft/src/codec/oft_compose_msg_codec.rs +55 -0
  106. package/contracts/oapps/oft/src/codec/oft_msg_codec.rs +62 -0
  107. package/contracts/oapps/oft/src/constants.rs +5 -0
  108. package/contracts/oapps/oft/src/errors.rs +8 -0
  109. package/contracts/oapps/oft/src/events.rs +19 -0
  110. package/contracts/oapps/oft/src/interfaces/mint_burn_token.rs +23 -0
  111. package/contracts/oapps/oft/src/interfaces/mod.rs +3 -0
  112. package/contracts/oapps/oft/src/lib.rs +22 -0
  113. package/contracts/oapps/oft/src/macro_tests/mod.rs +2 -0
  114. package/contracts/oapps/oft/src/macro_tests/test_all_default.rs +41 -0
  115. package/contracts/oapps/oft/src/macro_tests/test_override.rs +83 -0
  116. package/contracts/oapps/oft/src/oft.rs +320 -0
  117. package/contracts/oapps/oft/src/oft_types/lock_unlock.rs +50 -0
  118. package/contracts/oapps/oft/src/oft_types/mint_burn.rs +50 -0
  119. package/contracts/oapps/oft/src/oft_types/mod.rs +10 -0
  120. package/contracts/oapps/oft/src/storage.rs +11 -0
  121. package/contracts/oapps/oft/src/tests/mod.rs +13 -0
  122. package/contracts/oapps/oft/src/tests/test_decimals.rs +89 -0
  123. package/contracts/oapps/oft/src/tests/test_lz_receive.rs +282 -0
  124. package/contracts/oapps/oft/src/tests/test_oft_compose_msg_codec.rs +68 -0
  125. package/contracts/oapps/oft/src/tests/test_oft_msg_codec.rs +136 -0
  126. package/contracts/oapps/oft/src/tests/test_oft_version.rs +13 -0
  127. package/contracts/oapps/oft/src/tests/test_quote_oft.rs +159 -0
  128. package/contracts/oapps/oft/src/tests/test_quote_send.rs +195 -0
  129. package/contracts/oapps/oft/src/tests/test_resolve_address.rs +37 -0
  130. package/contracts/oapps/oft/src/tests/test_send.rs +915 -0
  131. package/contracts/oapps/oft/src/tests/test_token.rs +47 -0
  132. package/contracts/oapps/oft/src/tests/test_utils.rs +789 -0
  133. package/contracts/oapps/oft/src/types.rs +38 -0
  134. package/contracts/oapps/oft/src/utils.rs +67 -0
  135. package/contracts/oapps/oft-mint-burn/Cargo.toml +26 -0
  136. package/contracts/oapps/oft-mint-burn/src/lib.rs +3 -0
  137. package/contracts/oapps/oft-mint-burn/src/oft.rs +28 -0
  138. package/contracts/oapps/oft-mint-burn/src/tests/mod.rs +1 -0
  139. package/contracts/utils/src/buffer_reader.rs +8 -9
  140. package/contracts/utils/src/buffer_writer.rs +11 -5
  141. package/contracts/utils/src/errors.rs +5 -5
  142. package/contracts/utils/src/ownable.rs +14 -6
  143. package/contracts/utils/src/testing_utils.rs +11 -1
  144. package/contracts/utils/src/tests/buffer_reader.rs +491 -730
  145. package/contracts/utils/src/tests/buffer_writer.rs +336 -148
  146. package/contracts/utils/src/tests/bytes_ext.rs +125 -40
  147. package/contracts/utils/src/tests/mod.rs +3 -0
  148. package/contracts/utils/src/tests/ownable.rs +379 -27
  149. package/contracts/utils/src/tests/test_helper.rs +47 -0
  150. package/contracts/utils/src/tests/testing_utils.rs +555 -0
  151. package/contracts/utils/src/tests/ttl.rs +421 -0
  152. package/contracts/utils/src/ttl.rs +29 -89
  153. package/contracts/workers/dvn/Cargo.toml +31 -0
  154. package/contracts/workers/dvn/src/auth.rs +66 -0
  155. package/contracts/workers/dvn/src/dvn.rs +143 -0
  156. package/contracts/workers/dvn/src/errors.rs +21 -0
  157. package/contracts/workers/dvn/src/events.rs +19 -0
  158. package/contracts/workers/dvn/src/interfaces/dvn.rs +12 -0
  159. package/contracts/workers/dvn/src/interfaces/mod.rs +5 -0
  160. package/contracts/workers/dvn/src/interfaces/multisig.rs +15 -0
  161. package/contracts/workers/dvn/src/lib.rs +24 -0
  162. package/contracts/workers/dvn/src/multisig.rs +127 -0
  163. package/contracts/workers/dvn/src/storage.rs +35 -0
  164. package/contracts/workers/dvn/src/tests/auth.rs +237 -0
  165. package/contracts/workers/dvn/src/tests/dvn.rs +349 -0
  166. package/contracts/workers/dvn/src/tests/key_pair.rs +66 -0
  167. package/contracts/workers/dvn/src/tests/mod.rs +5 -0
  168. package/contracts/workers/dvn/src/tests/multisig/mod.rs +3 -0
  169. package/contracts/workers/dvn/src/tests/multisig/set_signer.rs +133 -0
  170. package/contracts/workers/dvn/src/tests/multisig/set_threshold.rs +108 -0
  171. package/contracts/workers/dvn/src/tests/multisig/verify_signatures.rs +109 -0
  172. package/contracts/workers/dvn/src/tests/setup.rs +109 -0
  173. package/contracts/workers/dvn/src/types.rs +26 -0
  174. package/contracts/workers/dvn-fee-lib/Cargo.toml +24 -0
  175. package/contracts/workers/dvn-fee-lib/src/dvn_fee_lib.rs +113 -0
  176. package/contracts/workers/dvn-fee-lib/src/errors.rs +8 -0
  177. package/contracts/workers/dvn-fee-lib/src/lib.rs +17 -0
  178. package/contracts/workers/dvn-fee-lib/src/tests/dvn_fee_lib.rs +282 -0
  179. package/contracts/workers/dvn-fee-lib/src/tests/mod.rs +1 -0
  180. package/contracts/workers/executor/Cargo.toml +10 -7
  181. package/contracts/workers/executor/src/errors.rs +8 -0
  182. package/contracts/workers/executor/src/events.rs +4 -7
  183. package/contracts/workers/executor/src/interfaces/executor.rs +72 -22
  184. package/contracts/workers/executor/src/interfaces/mod.rs +0 -2
  185. package/contracts/workers/executor/src/lib.rs +16 -7
  186. package/contracts/workers/executor/src/lz_executor.rs +308 -0
  187. package/contracts/workers/executor/src/storage.rs +24 -16
  188. package/contracts/workers/executor-fee-lib/Cargo.toml +22 -0
  189. package/contracts/workers/executor-fee-lib/src/errors.rs +15 -0
  190. package/contracts/workers/executor-fee-lib/src/executor_fee_lib.rs +215 -0
  191. package/contracts/workers/executor-fee-lib/src/executor_option.rs +203 -0
  192. package/contracts/workers/executor-fee-lib/src/lib.rs +7 -0
  193. package/contracts/workers/executor-helper/Cargo.toml +29 -0
  194. package/contracts/workers/executor-helper/src/executor_helper.rs +161 -0
  195. package/contracts/workers/executor-helper/src/lib.rs +11 -0
  196. package/contracts/workers/{worker-common → worker}/Cargo.toml +1 -4
  197. package/contracts/workers/worker/src/errors.rs +24 -0
  198. package/contracts/workers/worker/src/events.rs +62 -0
  199. package/contracts/workers/worker/src/interfaces/dvn_fee_lib.rs +75 -0
  200. package/contracts/workers/worker/src/interfaces/executor_fee_lib.rs +84 -0
  201. package/contracts/workers/{worker-common → worker}/src/interfaces/mod.rs +2 -2
  202. package/contracts/workers/worker/src/interfaces/price_feed.rs +85 -0
  203. package/contracts/workers/worker/src/lib.rs +14 -0
  204. package/contracts/workers/worker/src/storage.rs +63 -0
  205. package/contracts/workers/worker/src/worker.rs +459 -0
  206. package/package.json +3 -3
  207. package/sdk/dist/generated/bml.d.ts +88 -17
  208. package/sdk/dist/generated/bml.js +62 -16
  209. package/sdk/dist/generated/counter.d.ts +281 -102
  210. package/sdk/dist/generated/counter.js +93 -41
  211. package/sdk/dist/generated/endpoint.d.ts +128 -105
  212. package/sdk/dist/generated/endpoint.js +47 -45
  213. package/sdk/dist/generated/sml.d.ts +212 -69
  214. package/sdk/dist/generated/sml.js +103 -53
  215. package/sdk/dist/generated/uln302.d.ts +270 -173
  216. package/sdk/dist/generated/uln302.js +112 -64
  217. package/sdk/package.json +11 -11
  218. package/sdk/test/index.test.ts +147 -42
  219. package/sdk/test/suites/constants.ts +7 -3
  220. package/sdk/test/suites/deploy.ts +65 -42
  221. package/sdk/test/suites/localnet.ts +2 -2
  222. package/sdk/test/suites/scan.ts +28 -25
  223. package/sdk/test/utils.ts +199 -0
  224. package/sdk/tsconfig.json +93 -95
  225. package/tools/ts-bindings-gen/src/main.rs +2 -0
  226. package/contracts/common-macros/src/snapshots/common_macros__tests__tests__snapshot_generated_storage_code.snap +0 -310
  227. package/contracts/common-macros/src/tests.rs +0 -287
  228. package/contracts/oapp-macros/tests/test_macros.rs +0 -522
  229. package/contracts/workers/executor/src/executor.rs +0 -347
  230. package/contracts/workers/executor/src/interfaces/types.rs +0 -51
  231. package/contracts/workers/worker-common/src/constants.rs +0 -17
  232. package/contracts/workers/worker-common/src/errors.rs +0 -6
  233. package/contracts/workers/worker-common/src/events.rs +0 -34
  234. package/contracts/workers/worker-common/src/interfaces/executor_fee_lib.rs +0 -35
  235. package/contracts/workers/worker-common/src/interfaces/price_feed.rs +0 -40
  236. package/contracts/workers/worker-common/src/interfaces/worker.rs +0 -60
  237. package/contracts/workers/worker-common/src/lib.rs +0 -19
  238. package/contracts/workers/worker-common/src/storage.rs +0 -32
  239. package/contracts/workers/worker-common/src/worker_common.rs +0 -166
@@ -1,67 +1,48 @@
1
- use crate::{oapp_core, util::ManualImplConfig};
1
+ use heck::ToSnakeCase;
2
2
  use proc_macro2::TokenStream;
3
3
  use quote::quote;
4
- use syn::{Ident, ItemStruct};
4
+ use syn::Ident;
5
5
 
6
- pub fn generate_impl(name: &Ident) -> TokenStream {
7
- quote! {
8
- use endpoint_v2::ILayerZeroReceiver as _;
9
- use oapp::oapp_receiver::OAppReceiver as _;
10
-
11
- #[soroban_sdk::contractimpl]
12
- impl endpoint_v2::ILayerZeroReceiver for #name
13
- {
14
- fn allow_initialize_path(
15
- env: &soroban_sdk::Env,
16
- origin: &endpoint_v2::Origin,
17
- ) -> bool {
18
- <Self as oapp::oapp_receiver::OAppReceiverOverrides>::__allow_initialize_path(env, origin)
19
- }
20
-
21
- fn next_nonce(
22
- env: &soroban_sdk::Env,
23
- src_eid: u32,
24
- sender: &soroban_sdk::BytesN<32>,
25
- ) -> u64 {
26
- <Self as oapp::oapp_receiver::OAppReceiverOverrides>::__next_nonce(env, src_eid, sender)
27
- }
6
+ /// Generates the `OAppReceiver` trait implementation.
7
+ ///
8
+ /// When `manual_impl_receiver` is false, generates `lz_receive` that calls
9
+ /// `verify_and_clear_payload` then delegates to the user's `__lz_receive` method.
10
+ pub fn generate_impl(name: &Ident, manual_impl_receiver: bool) -> TokenStream {
11
+ // Use a distinct module name to avoid conflicts with oapp_core's module
12
+ let impl_mod = syn::Ident::new(&format!("__oapp_receiver_impl_{}", name.to_string().to_snake_case()), name.span());
28
13
 
29
- fn lz_receive(
30
- env: &soroban_sdk::Env,
31
- executor: &soroban_sdk::Address,
32
- origin: &endpoint_v2::Origin,
33
- guid: &soroban_sdk::BytesN<32>,
34
- message: &soroban_sdk::Bytes,
35
- extra_data: &soroban_sdk::Bytes,
36
- value: i128,
37
- ) {
38
- oapp::oapp_receiver::verify_and_clear_payload::<Self>(env, executor, origin, guid, message);
14
+ let receiver_impl = (!manual_impl_receiver).then(|| {
15
+ quote! {
16
+ // OAppReceiver implementation
17
+ // This generates contract entry points that are callable via LayerZeroReceiverClient
18
+ // because the function names match ILayerZeroReceiver's interface.
19
+ #[doc(hidden)]
20
+ mod #impl_mod {
21
+ use super::*;
22
+ use soroban_sdk::{Address, Bytes, BytesN, Env};
23
+ use endpoint_v2::Origin;
24
+ use oapp::oapp_receiver::OAppReceiver;
39
25
 
40
- <Self as oapp::oapp_receiver::OAppReceiverOverrides>::__lz_receive(
41
- env,
42
- executor,
43
- origin,
44
- guid,
45
- message,
46
- extra_data,
47
- value,
48
- )
26
+ #[soroban_sdk::contractimpl(contracttrait)]
27
+ impl OAppReceiver for #name {
28
+ fn lz_receive(
29
+ env: &soroban_sdk::Env,
30
+ executor: &soroban_sdk::Address,
31
+ origin: &endpoint_v2::Origin,
32
+ guid: &soroban_sdk::BytesN<32>,
33
+ message: &soroban_sdk::Bytes,
34
+ extra_data: &soroban_sdk::Bytes,
35
+ value: i128,
36
+ ) {
37
+ oapp::oapp_receiver::verify_and_clear_payload::<Self>(env, executor, origin, guid, message, value);
38
+ Self::__lz_receive(env, executor, origin, guid, message, extra_data, value)
39
+ }
40
+ }
49
41
  }
50
42
  }
43
+ });
51
44
 
52
- #[soroban_sdk::contractimpl]
53
- impl oapp::oapp_receiver::OAppReceiver for #name
54
- {
55
- fn is_compose_msg_sender(env: &soroban_sdk::Env, origin: &endpoint_v2::Origin, message: &soroban_sdk::Bytes, sender: &soroban_sdk::Address) -> bool {
56
- <Self as oapp::oapp_receiver::OAppReceiverOverrides>::__is_compose_msg_sender(env, origin, message, sender)
57
- }
58
- }
45
+ quote! {
46
+ #receiver_impl
59
47
  }
60
48
  }
61
-
62
- pub fn generate_impl_with_core(name: &Ident, item: ItemStruct, manual_impl_config: ManualImplConfig) -> TokenStream {
63
- let mut oapp_core_impl = oapp_core::generate_impl(name, item, manual_impl_config.core);
64
- let receiver_impl = generate_impl(name);
65
- oapp_core_impl.extend(receiver_impl);
66
- oapp_core_impl
67
- }
@@ -1,23 +1,21 @@
1
- use crate::{oapp_core, util::ManualImplConfig};
2
1
  use proc_macro2::TokenStream;
3
2
  use quote::quote;
4
- use syn::{Ident, ItemStruct};
3
+ use syn::Ident;
5
4
 
5
+ /// Generates the `OAppSender` trait implementation.
6
+ ///
7
+ /// When `manual_impl_sender` is false, generates an empty `impl OAppSender`
8
+ /// that uses the trait's default implementations for `lz_quote` and `lz_send`...
6
9
  pub fn generate_impl(name: &Ident, manual_impl_sender: bool) -> TokenStream {
7
- if manual_impl_sender {
8
- quote! {}
9
- } else {
10
+ let sender_impl = (!manual_impl_sender).then(|| {
10
11
  quote! {
11
- use oapp::oapp_sender::OAppSenderOverrides as _;
12
+ use oapp::oapp_sender::OAppSender as _;
12
13
 
13
- impl oapp::oapp_sender::OAppSenderOverrides for #name {}
14
+ impl oapp::oapp_sender::OAppSender for #name {}
14
15
  }
15
- }
16
- }
16
+ });
17
17
 
18
- pub fn generate_impl_with_core(name: &Ident, item: ItemStruct, manual_impl_config: ManualImplConfig) -> TokenStream {
19
- let mut oapp_core_impl = oapp_core::generate_impl(name, item, manual_impl_config.core);
20
- let sender_impl = generate_impl(name, manual_impl_config.sender);
21
- oapp_core_impl.extend(sender_impl);
22
- oapp_core_impl
18
+ quote! {
19
+ #sender_impl
20
+ }
23
21
  }
@@ -12,26 +12,29 @@ use syn::{
12
12
  /// which default trait implementations are generated by the macros.
13
13
  ///
14
14
  /// # Fields
15
- /// * `core` - If `true`, the user must manually implement `OAppCoreOverrides`
16
- /// * `sender` - If `true`, the user must manually implement `OAppSenderOverrides`
17
- /// * `options_type3` - If `true`, the user must manually implement `OAppOptionsType3Overrides`
15
+ /// * `core` - If `true`, the user must manually implement `OAppCore`
16
+ /// * `sender` - If `true`, the user must manually implement `OAppSender`
17
+ /// * `receiver` - If `true`, the user must manually implement `OAppReceiver` trait entirely
18
+ /// * `options_type3` - If `true`, the user must manually implement `OAppOptionsType3`
18
19
  ///
19
- /// # Note on Receiver
20
- /// There is intentionally **no** `receiver` field in this config because the receiver
21
- /// always requires manual implementation. The `OAppReceiverOverrides::__lz_receive` method
22
- /// has no default implementation, so users must always provide their own implementation
23
- /// of the message handling logic.
20
+ /// # Receiver Manual Implementation
21
+ /// When `receiver` is `true`, the macro will NOT generate `impl OAppReceiver`. The user
22
+ /// must manually implement the entire `OAppReceiver` trait, including `lz_receive`,
23
+ /// `next_nonce`, `allow_initialize_path`, and `is_compose_msg_sender`.
24
+ ///
25
+ /// This is useful when you need to customize methods like `next_nonce` (e.g., for ordered delivery).
24
26
  #[derive(Debug, Clone, Copy, Default)]
25
27
  pub struct ManualImplConfig {
26
28
  pub core: bool,
27
29
  pub sender: bool,
30
+ pub receiver: bool,
28
31
  pub options_type3: bool,
29
32
  }
30
33
 
31
34
  impl ManualImplConfig {
32
35
  /// Parses configuration from the `#[oapp_manual_impl(...)]` attribute arguments.
33
36
  ///
34
- /// Accepts a comma-separated list of identifiers: `core`, `sender`, `options_type3`.
37
+ /// Accepts a comma-separated list of identifiers: `core`, `sender`, `receiver`, `options_type3`.
35
38
  /// Returns an error if any invalid identifier is provided.
36
39
  fn from_attr(input: ParseStream) -> syn::Result<Self> {
37
40
  let idents = Punctuated::<syn::Ident, Token![,]>::parse_terminated(input)?;
@@ -42,11 +45,12 @@ impl ManualImplConfig {
42
45
  match ident.to_string().as_str() {
43
46
  "core" => cfg.core = true,
44
47
  "sender" => cfg.sender = true,
48
+ "receiver" => cfg.receiver = true,
45
49
  "options_type3" => cfg.options_type3 = true,
46
50
  _ => {
47
51
  return Err(Error::new(
48
52
  ident.span(),
49
- "invalid value for oapp_manual_impl: expected one of `core`, `sender`, `options_type3`",
53
+ "invalid value for oapp_manual_impl: expected one of `core`, `sender`, `receiver`, `options_type3`",
50
54
  ));
51
55
  }
52
56
  }
@@ -21,4 +21,5 @@ soroban-sdk = { workspace = true, features = ["testutils"] }
21
21
  assert_unordered = "0.3.5"
22
22
  simple-message-lib = { workspace = true }
23
23
  message-lib-common = { workspace = true, features = ["testutils"] }
24
- endpoint-v2 = { workspace = true, features = ["testutils"] }
24
+ endpoint-v2 = { workspace = true, features = ["testutils"] }
25
+ executor = { workspace = true, features = ["testutils"] }
@@ -59,11 +59,11 @@ pub fn validate_packet(env: &Env, chain: &ChainSetup<'_>, packet_event: &(Bytes,
59
59
  invoke: &MockAuthInvoke {
60
60
  contract: &chain.sml.address,
61
61
  fn_name: "validate_packet",
62
- args: (&chain.owner, &encoded_header, &payload_hash).into_val(env),
62
+ args: (&encoded_header, &payload_hash).into_val(env),
63
63
  sub_invokes: &[],
64
64
  },
65
65
  }]);
66
- chain.sml.validate_packet(&chain.owner, &encoded_header, &payload_hash);
66
+ chain.sml.validate_packet(&encoded_header, &payload_hash);
67
67
  }
68
68
 
69
69
  pub fn lz_receive(
@@ -78,8 +78,8 @@ pub fn lz_receive(
78
78
 
79
79
  let sub_invokes_with_transfer = [MockAuthInvoke {
80
80
  contract: &chain.native_token,
81
- fn_name: "transfer_from",
82
- args: (executor, executor, &chain.counter.address, &value).into_val(env),
81
+ fn_name: "transfer",
82
+ args: (executor, &chain.counter.address, &value).into_val(env),
83
83
  sub_invokes: &[],
84
84
  }];
85
85
 
@@ -1,4 +1,7 @@
1
1
  use soroban_sdk::{Bytes, Env, U256};
2
+ use utils::option_ext::OptionExt;
3
+
4
+ use crate::{errors::CounterError, u256_ext::U256Ext};
2
5
 
3
6
  #[derive(Debug, Clone, Copy, PartialEq, Eq)]
4
7
  #[repr(u8)]
@@ -36,10 +39,9 @@ pub fn encode(env: &Env, msg_type: MsgType, src_eid: u32) -> Bytes {
36
39
  data
37
40
  }
38
41
 
39
- pub fn encode_with_value(env: &Env, msg_type: MsgType, src_eid: u32, value: U256) -> Bytes {
42
+ pub fn encode_with_value(env: &Env, msg_type: MsgType, src_eid: u32, value: u32) -> Bytes {
40
43
  let mut data = encode(env, msg_type, src_eid);
41
- data.append(&value.to_be_bytes());
42
-
44
+ data.append(&U256::from_u32(env, value).to_be_bytes());
43
45
  data
44
46
  }
45
47
 
@@ -53,11 +55,8 @@ pub fn src_eid(data: &Bytes) -> u32 {
53
55
  u32::from_be_bytes(src_eid_bytes)
54
56
  }
55
57
 
56
- pub fn value(env: &Env, data: &Bytes) -> U256 {
58
+ pub fn value(env: &Env, data: &Bytes) -> i128 {
57
59
  let slice = data.slice((VALUE_OFFSET as u32)..data.len());
58
- if slice.is_empty() {
59
- U256::from_u32(env, 0)
60
- } else {
61
- U256::from_be_bytes(env, &slice)
62
- }
60
+ let value = if slice.is_empty() { U256::from_u32(env, 0) } else { U256::from_be_bytes(env, &slice) };
61
+ value.to_i128().unwrap_or_panic(env, CounterError::InvalidMsgValue)
63
62
  }
@@ -1,129 +1,58 @@
1
1
  use crate::{
2
2
  codec::{self, MsgType},
3
3
  errors::CounterError,
4
- options, storage,
5
- u256_ext::U256Ext,
4
+ options,
5
+ storage::CounterStorage,
6
6
  };
7
- use common_macros::only_owner;
7
+ use common_macros::{contract_impl, only_owner};
8
8
  use endpoint_v2::{
9
- ILayerZeroComposer, ILayerZeroReceiver, LayerZeroEndpointV2Client, MessagingChannelClient, MessagingComposerClient,
10
- MessagingFee, Origin,
9
+ ILayerZeroComposer, LayerZeroEndpointV2Client, MessagingChannelClient, MessagingComposerClient, MessagingFee,
10
+ Origin,
11
11
  };
12
- use oapp::{oapp_core::OAppCoreOverrides, oapp_receiver::OAppReceiverOverrides};
13
- use oapp_macros::oapp;
14
- use soroban_sdk::{
15
- assert_with_error, contractimpl, panic_with_error, token::TokenClient, Address, Bytes, BytesN, Env, U256,
12
+ use oapp::{
13
+ oapp_core::{oapp_initialize, OAppCore},
14
+ oapp_receiver::{self, OAppReceiver},
15
+ oapp_sender::OAppSender,
16
16
  };
17
- use utils::{option_ext::OptionExt, ownable::Ownable};
17
+ use oapp_macros::{oapp, oapp_manual_impl};
18
+ use soroban_sdk::{assert_with_error, panic_with_error, token::TokenClient, Address, Bytes, BytesN, Env};
19
+ use utils::ownable::Ownable;
18
20
 
19
21
  #[oapp]
22
+ #[oapp_manual_impl(receiver)]
20
23
  pub struct Counter;
21
24
 
22
- impl OAppReceiverOverrides for Counter {
23
- fn __next_nonce(env: &Env, src_eid: u32, sender: &BytesN<32>) -> u64 {
24
- if storage::CounterStorage::ordered_nonce(env) {
25
- storage::CounterStorage::max_received_nonce(env, src_eid, sender) + 1
26
- } else {
27
- 0
28
- }
29
- }
30
-
31
- fn __lz_receive(
32
- env: &Env,
33
- executor: &Address,
34
- origin: &Origin,
35
- guid: &BytesN<32>,
36
- message: &Bytes,
37
- _extra_data: &Bytes,
38
- value: i128,
39
- ) {
40
- let endpoint_address = Self::endpoint(env);
41
- let endpoint = LayerZeroEndpointV2Client::new(env, &endpoint_address);
42
- let contract_address = env.current_contract_address();
43
- if value > 0 {
44
- let native_token = endpoint.native_token();
45
- let token_client = TokenClient::new(env, &native_token);
46
- token_client.transfer_from(executor, executor, &contract_address, &value);
47
- }
48
-
49
- // handle the message
50
- Self::__accept_nonce(env, origin.src_eid, &origin.sender, origin.nonce);
51
- let count = Self::count(env);
52
- let inbound_count = Self::inbound_count(env, origin.src_eid);
53
- let outbound_count = Self::outbound_count(env, origin.src_eid);
54
- match codec::msg_type(message) {
55
- MsgType::Vanilla => {
56
- storage::CounterStorage::set_count(env, &(count + 1));
57
-
58
- let expected_msg_value =
59
- codec::value(env, message).to_i128().unwrap_or_panic(env, CounterError::InvalidMsgValue);
60
-
61
- assert_with_error!(env, value >= expected_msg_value, CounterError::InsufficientValue);
62
-
63
- storage::CounterStorage::set_inbound_count(env, origin.src_eid, &(inbound_count + 1));
64
- }
65
- MsgType::Composed | MsgType::ComposedABA => {
66
- storage::CounterStorage::set_count(env, &(count + 1));
67
- storage::CounterStorage::set_inbound_count(env, origin.src_eid, &(inbound_count + 1));
68
-
69
- let endpoint_address = Self::endpoint(env);
70
- let endpoint: MessagingComposerClient<'_> = MessagingComposerClient::new(env, &endpoint_address);
71
- endpoint.send_compose(&contract_address, &contract_address, guid, &0, message);
72
- }
73
- MsgType::ABA => {
74
- storage::CounterStorage::set_count(env, &(count + 1));
75
- storage::CounterStorage::set_inbound_count(env, origin.src_eid, &(inbound_count + 1));
76
- storage::CounterStorage::set_outbound_count(env, origin.src_eid, &(outbound_count + 1));
77
-
78
- let options = options::executor_lz_receive_option(env, 200000, 10);
79
- Self::__lz_send(
80
- env,
81
- &contract_address,
82
- origin.src_eid,
83
- &codec::encode_with_value(env, MsgType::Vanilla, origin.src_eid, U256::from_u32(env, 10)),
84
- &options,
85
- &MessagingFee { native_fee: value, zro_fee: 0 },
86
- &contract_address,
87
- );
88
- }
89
- }
90
- }
91
- }
92
-
93
- #[contractimpl]
25
+ #[contract_impl]
94
26
  impl Counter {
95
27
  pub fn __constructor(env: &Env, owner: &Address, endpoint: &Address, delegate: &Address) {
96
- Self::__init_owner(env, owner);
97
- Self::__oapp_initialize(env, endpoint, &Some(delegate.clone()));
28
+ oapp_initialize::<Self>(env, owner, endpoint, &Some(delegate.clone()));
98
29
  let endpoint_client = LayerZeroEndpointV2Client::new(env, endpoint);
99
- storage::CounterStorage::set_eid(env, &endpoint_client.eid());
30
+ CounterStorage::set_eid(env, &endpoint_client.eid());
100
31
  }
101
32
 
102
33
  pub fn quote(env: &Env, dst_eid: u32, msg_type: u32, options: &Bytes, pay_in_zro: bool) -> MessagingFee {
103
- Self::__quote(env, dst_eid, &codec::encode(env, (msg_type as u8).into(), Self::eid(env)), options, pay_in_zro)
34
+ Self::lz_quote(env, dst_eid, &codec::encode(env, (msg_type as u8).into(), Self::eid(env)), options, pay_in_zro)
104
35
  }
105
36
 
106
- pub fn increment(env: &Env, sender: &Address, dst_eid: u32, msg_type: u32, options: &Bytes, fee: &MessagingFee) {
107
- sender.require_auth();
108
-
109
- Self::__lz_send(
110
- env,
111
- sender,
112
- dst_eid,
113
- &codec::encode(env, (msg_type as u8).into(), Self::eid(env)),
114
- options,
115
- fee,
116
- sender,
117
- );
37
+ pub fn increment(env: &Env, caller: &Address, dst_eid: u32, msg_type: u32, options: &Bytes, fee: &MessagingFee) {
38
+ caller.require_auth();
39
+
40
+ // Increment the outbound count
118
41
  let outbound_count = Self::outbound_count(env, dst_eid);
119
- storage::CounterStorage::set_outbound_count(env, dst_eid, &(outbound_count + 1));
42
+ CounterStorage::set_outbound_count(env, dst_eid, &(outbound_count + 1));
43
+
44
+ // Send the message
45
+ let message = codec::encode(env, (msg_type as u8).into(), Self::eid(env));
46
+ Self::lz_send(env, caller, dst_eid, &message, options, fee, caller);
120
47
  }
121
48
 
122
- // === Owner functions ===
49
+ // ============================================================================================
50
+ // Owner functions
51
+ // ============================================================================================
123
52
 
124
53
  #[only_owner]
125
54
  pub fn set_ordered_nonce(env: &Env, ordered_nonce: bool) {
126
- storage::CounterStorage::set_ordered_nonce(env, &ordered_nonce);
55
+ CounterStorage::set_ordered_nonce(env, &ordered_nonce);
127
56
  }
128
57
 
129
58
  #[only_owner]
@@ -134,102 +63,182 @@ impl Counter {
134
63
  let endpoint = MessagingChannelClient::new(env, &endpoint_address);
135
64
  endpoint.skip(&contract_address, &contract_address, &src_eid, sender, &nonce);
136
65
 
137
- if storage::CounterStorage::ordered_nonce(env) {
138
- let max_received_nonce = storage::CounterStorage::max_received_nonce(env, src_eid, sender);
139
- storage::CounterStorage::set_max_received_nonce(env, src_eid, sender, &(max_received_nonce + 1));
66
+ if CounterStorage::ordered_nonce(env) {
67
+ let max_received_nonce = CounterStorage::max_received_nonce(env, src_eid, sender);
68
+ CounterStorage::set_max_received_nonce(env, src_eid, sender, &(max_received_nonce + 1));
140
69
  }
141
70
  }
142
71
 
143
- // === view functions ===
72
+ // ============================================================================================
73
+ // View functions
74
+ // ============================================================================================
144
75
 
145
76
  pub fn eid(env: &Env) -> u32 {
146
- storage::CounterStorage::eid(env).unwrap()
77
+ CounterStorage::eid(env).unwrap()
147
78
  }
148
79
 
149
80
  pub fn count(env: &Env) -> u64 {
150
- storage::CounterStorage::count(env)
81
+ CounterStorage::count(env)
151
82
  }
152
83
 
153
84
  pub fn composed_count(env: &Env) -> u64 {
154
- storage::CounterStorage::composed_count(env)
85
+ CounterStorage::composed_count(env)
155
86
  }
156
87
 
157
88
  pub fn inbound_count(env: &Env, eid: u32) -> u64 {
158
- storage::CounterStorage::inbound_count(env, eid)
89
+ CounterStorage::inbound_count(env, eid)
159
90
  }
160
91
 
161
92
  pub fn outbound_count(env: &Env, eid: u32) -> u64 {
162
- storage::CounterStorage::outbound_count(env, eid)
93
+ CounterStorage::outbound_count(env, eid)
163
94
  }
164
95
 
165
- // === Internal functions ===
96
+ // ============================================================================================
97
+ // Internal Functions
98
+ // ============================================================================================
166
99
 
167
100
  fn __accept_nonce(env: &Env, src_eid: u32, sender: &BytesN<32>, nonce: u64) {
168
- let current_nonce = storage::CounterStorage::max_received_nonce(env, src_eid, sender);
169
- if storage::CounterStorage::ordered_nonce(env) {
101
+ let current_nonce = CounterStorage::max_received_nonce(env, src_eid, sender);
102
+ if CounterStorage::ordered_nonce(env) {
170
103
  assert_with_error!(env, nonce == current_nonce + 1, CounterError::OAppInvalidNonce);
171
104
  }
172
-
105
+ // Update the max nonce anyway. once the ordered mode is turned on, missing early nonces will be rejected
173
106
  if nonce > current_nonce {
174
- storage::CounterStorage::set_max_received_nonce(env, src_eid, sender, &nonce);
107
+ CounterStorage::set_max_received_nonce(env, src_eid, sender, &nonce);
175
108
  }
176
109
  }
177
110
  }
178
111
 
179
- #[contractimpl]
180
- impl ILayerZeroComposer for Counter {
181
- fn lz_compose(
112
+ // ============================================================================================
113
+ // OAppReceiver implementation
114
+ // ============================================================================================
115
+
116
+ #[contract_impl(contracttrait)]
117
+ impl OAppReceiver for Counter {
118
+ fn next_nonce(env: &Env, src_eid: u32, sender: &BytesN<32>) -> u64 {
119
+ if CounterStorage::ordered_nonce(env) {
120
+ CounterStorage::max_received_nonce(env, src_eid, sender) + 1
121
+ } else {
122
+ 0
123
+ }
124
+ }
125
+
126
+ fn lz_receive(
182
127
  env: &Env,
183
128
  executor: &Address,
184
- from: &Address,
129
+ origin: &Origin,
185
130
  guid: &BytesN<32>,
186
- index: u32,
187
131
  message: &Bytes,
188
132
  _extra_data: &Bytes,
189
133
  value: i128,
190
134
  ) {
191
- executor.require_auth();
192
- let contract_address = env.current_contract_address();
193
- let endpoint_address = Self::endpoint(env);
135
+ oapp_receiver::verify_and_clear_payload::<Self>(env, executor, origin, guid, message, value);
194
136
 
195
- // Transfer value from executor to contract for lz_send
196
- if value > 0 {
197
- let endpoint = LayerZeroEndpointV2Client::new(env, &endpoint_address);
198
- let native_token = endpoint.native_token();
199
- let token_client = TokenClient::new(env, &native_token);
200
- token_client.transfer_from(executor, executor, &contract_address, &value);
201
- }
137
+ // handle the message
138
+ Self::__accept_nonce(env, origin.src_eid, &origin.sender, origin.nonce);
202
139
 
203
- let endpoint = MessagingComposerClient::new(env, &endpoint_address);
204
- // try clear the compose first
205
- endpoint.clear_compose(&contract_address, from, guid, &index, message);
140
+ let contract_address = env.current_contract_address();
206
141
 
207
- // handle the message
208
- let composed_count = Self::composed_count(env);
142
+ // Increment the count and inbound count
143
+ let count = Self::count(env);
144
+ let inbound_count = Self::inbound_count(env, origin.src_eid);
145
+ CounterStorage::set_count(env, &(count + 1));
146
+ CounterStorage::set_inbound_count(env, origin.src_eid, &(inbound_count + 1));
147
+
148
+ let assert_received_value = || {
149
+ let expected_msg_value = codec::value(env, message);
150
+ assert_with_error!(env, value >= expected_msg_value, CounterError::InsufficientValue);
151
+ };
209
152
 
210
153
  match codec::msg_type(message) {
211
- MsgType::Composed => {
212
- storage::CounterStorage::set_composed_count(env, &(composed_count + 1));
154
+ MsgType::Vanilla => {
155
+ assert_received_value();
156
+ }
157
+ MsgType::Composed | MsgType::ComposedABA => {
158
+ let endpoint: MessagingComposerClient<'_> = MessagingComposerClient::new(env, &Self::endpoint(env));
159
+ endpoint.send_compose(&contract_address, &contract_address, guid, &0, message);
213
160
  }
214
- MsgType::ComposedABA => {
215
- storage::CounterStorage::set_composed_count(env, &(composed_count + 1));
161
+ MsgType::ABA => {
162
+ assert_received_value();
216
163
 
217
- let src_eid = codec::src_eid(message);
218
- let outbound_count = Self::outbound_count(env, src_eid);
219
- storage::CounterStorage::set_outbound_count(env, src_eid, &(outbound_count + 1));
164
+ // Increment the outbound count
165
+ let outbound_count = Self::outbound_count(env, origin.src_eid);
166
+ CounterStorage::set_outbound_count(env, origin.src_eid, &(outbound_count + 1));
220
167
 
221
- let options = options::executor_lz_receive_option(env, 200000, 0);
222
- Self::__lz_send(
168
+ // Send the response message
169
+ let options = options::executor_lz_receive_option(env, 200000, 10);
170
+ Self::lz_send(
223
171
  env,
224
172
  &contract_address,
225
- src_eid,
226
- &codec::encode(env, MsgType::Vanilla, Self::eid(env)),
173
+ origin.src_eid,
174
+ &codec::encode_with_value(env, MsgType::Vanilla, Self::eid(env), 10),
227
175
  &options,
228
176
  &MessagingFee { native_fee: value, zro_fee: 0 },
229
177
  &contract_address,
230
178
  );
231
179
  }
232
- _ => panic_with_error!(env, CounterError::InvalidMsgType),
180
+ }
181
+ }
182
+ }
183
+
184
+ // ============================================================================================
185
+ // ILayerZeroComposer implementation
186
+ // ============================================================================================
187
+
188
+ #[contract_impl]
189
+ impl ILayerZeroComposer for Counter {
190
+ fn lz_compose(
191
+ env: &Env,
192
+ executor: &Address,
193
+ from: &Address,
194
+ guid: &BytesN<32>,
195
+ index: u32,
196
+ message: &Bytes,
197
+ _extra_data: &Bytes,
198
+ value: i128,
199
+ ) {
200
+ executor.require_auth();
201
+
202
+ let msg_type = codec::msg_type(message);
203
+ if msg_type != MsgType::Composed && msg_type != MsgType::ComposedABA {
204
+ panic_with_error!(env, CounterError::InvalidMsgType);
205
+ }
206
+
207
+ let curr_address = env.current_contract_address();
208
+ let endpoint_address = Self::endpoint(env);
209
+
210
+ // Transfer value from executor to current contract
211
+ if value > 0 {
212
+ let native_token = LayerZeroEndpointV2Client::new(env, &endpoint_address).native_token();
213
+ TokenClient::new(env, &native_token).transfer_from(executor, executor, &curr_address, &value);
214
+ }
215
+ // Assert the value is sufficient
216
+ let expected_msg_value = codec::value(env, message);
217
+ assert_with_error!(env, value >= expected_msg_value, CounterError::InsufficientValue);
218
+
219
+ // Clear the compose message
220
+ MessagingComposerClient::new(env, &endpoint_address).clear_compose(&curr_address, from, guid, &index, message);
221
+
222
+ // Increment the composed count
223
+ CounterStorage::set_composed_count(env, &(Self::composed_count(env) + 1));
224
+
225
+ // Handle ComposedABA: send response message back to source
226
+ if msg_type == MsgType::ComposedABA {
227
+ let src_eid = codec::src_eid(message);
228
+
229
+ // Increment the outbound count
230
+ CounterStorage::set_outbound_count(env, src_eid, &(Self::outbound_count(env, src_eid) + 1));
231
+
232
+ // Send the response message
233
+ Self::lz_send(
234
+ env,
235
+ &curr_address,
236
+ src_eid,
237
+ &codec::encode(env, MsgType::Vanilla, Self::eid(env)),
238
+ &options::executor_lz_receive_option(env, 200000, 0),
239
+ &MessagingFee { native_fee: value, zro_fee: 0 },
240
+ &curr_address,
241
+ );
233
242
  }
234
243
  }
235
244
  }