@layerzerolabs/protocol-stellar-v2 0.2.19 → 0.2.21

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 (249) hide show
  1. package/.turbo/turbo-build.log +795 -791
  2. package/.turbo/turbo-lint.log +325 -155
  3. package/.turbo/turbo-test.log +1398 -1277
  4. package/Cargo.lock +122 -111
  5. package/Cargo.toml +32 -16
  6. package/contracts/common-macros/Cargo.toml +7 -7
  7. package/contracts/common-macros/src/auth.rs +18 -37
  8. package/contracts/common-macros/src/contract_ttl.rs +18 -7
  9. package/contracts/common-macros/src/lib.rs +31 -14
  10. package/contracts/common-macros/src/lz_contract.rs +38 -7
  11. package/contracts/common-macros/src/storage.rs +251 -292
  12. package/contracts/common-macros/src/tests/contract_ttl.rs +1 -1
  13. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__auth__snapshot_generated_multisig_code.snap +6 -12
  14. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__auth__snapshot_generated_ownable_code.snap +12 -17
  15. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__contract_ttl__snapshot_generated_contractimpl_code.snap +2 -1
  16. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__ttl_configurable__snapshot_generated_ttl_configurable_code.snap +2 -7
  17. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__upgradeable__snapshot_generated_upgradeable_code.snap +20 -14
  18. package/contracts/common-macros/src/tests/upgradeable.rs +26 -4
  19. package/contracts/common-macros/src/ttl_configurable.rs +2 -10
  20. package/contracts/common-macros/src/ttl_extendable.rs +2 -10
  21. package/contracts/common-macros/src/upgradeable.rs +61 -26
  22. package/contracts/common-macros/src/utils.rs +0 -9
  23. package/contracts/endpoint-v2/src/lib.rs +3 -2
  24. package/contracts/endpoint-v2/src/tests/endpoint_v2/clear.rs +2 -2
  25. package/contracts/endpoint-v2/src/tests/endpoint_v2/lz_receive_alert.rs +3 -3
  26. package/contracts/endpoint-v2/src/tests/endpoint_v2/send.rs +4 -4
  27. package/contracts/endpoint-v2/src/tests/endpoint_v2/set_delegate.rs +17 -5
  28. package/contracts/endpoint-v2/src/tests/endpoint_v2/set_zro.rs +4 -4
  29. package/contracts/endpoint-v2/src/tests/endpoint_v2/verify.rs +2 -2
  30. package/contracts/endpoint-v2/src/tests/message_lib_manager/register_library.rs +2 -2
  31. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_default_receive_lib_timeout.rs +6 -6
  32. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_default_receive_library.rs +67 -37
  33. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_default_send_library.rs +5 -5
  34. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_receive_library.rs +44 -54
  35. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_receive_library_timeout.rs +7 -7
  36. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_send_library.rs +8 -8
  37. package/contracts/endpoint-v2/src/tests/messaging_channel/burn.rs +3 -3
  38. package/contracts/endpoint-v2/src/tests/messaging_channel/nilify.rs +4 -4
  39. package/contracts/endpoint-v2/src/tests/messaging_channel/skip.rs +3 -3
  40. package/contracts/endpoint-v2/src/tests/messaging_composer/clear_compose.rs +2 -2
  41. package/contracts/endpoint-v2/src/tests/messaging_composer/lz_compose_alert.rs +3 -3
  42. package/contracts/endpoint-v2/src/tests/messaging_composer/send_compose.rs +2 -2
  43. package/contracts/layerzero-views/Cargo.toml +0 -1
  44. package/contracts/layerzero-views/src/layerzero_view.rs +1 -13
  45. package/contracts/macro-integration-tests/Cargo.toml +5 -15
  46. package/contracts/macro-integration-tests/tests/runtime/oapp/mod.rs +48 -0
  47. package/contracts/macro-integration-tests/tests/runtime/oapp/oapp_core.rs +170 -0
  48. package/contracts/macro-integration-tests/tests/runtime/oapp/options_type3.rs +154 -0
  49. package/contracts/macro-integration-tests/tests/runtime/oapp/receiver.rs +338 -0
  50. package/contracts/macro-integration-tests/tests/runtime/oapp/sender.rs +435 -0
  51. package/contracts/macro-integration-tests/tests/runtime.rs +1 -0
  52. package/contracts/macro-integration-tests/tests/ui/oapp/fail/custom_wrong_value.rs +8 -0
  53. package/contracts/macro-integration-tests/tests/ui/oapp/fail/custom_wrong_value.stderr +5 -0
  54. package/contracts/macro-integration-tests/tests/ui/oapp/fail/missing_lz_receive_internal.rs +8 -0
  55. package/contracts/macro-integration-tests/tests/ui/oapp/fail/missing_lz_receive_internal.stderr +71 -0
  56. package/contracts/macro-integration-tests/tests/ui/oapp/fail/non_struct_input.rs +10 -0
  57. package/contracts/macro-integration-tests/tests/ui/oapp/fail/non_struct_input.stderr +5 -0
  58. package/contracts/macro-integration-tests/tests/ui/oapp/fail/unknown_custom_option.rs +8 -0
  59. package/contracts/macro-integration-tests/tests/ui/oapp/fail/unknown_custom_option.stderr +5 -0
  60. package/contracts/macro-integration-tests/tests/ui/oapp/fail/wrong_key.rs +8 -0
  61. package/contracts/macro-integration-tests/tests/ui/oapp/fail/wrong_key.stderr +5 -0
  62. package/contracts/macro-integration-tests/tests/ui/oapp/pass/custom_all.rs +38 -0
  63. package/contracts/macro-integration-tests/tests/ui/oapp/pass/custom_single_trait.rs +96 -0
  64. package/contracts/macro-integration-tests/tests/ui/oapp/pass/minimal_contract.rs +64 -0
  65. package/contracts/macro-integration-tests/tests/ui/oapp/pass/struct_with_fields.rs +46 -0
  66. package/contracts/macro-integration-tests/tests/ui/ownable/fail/only_auth_missing_env.stderr +8 -0
  67. package/contracts/macro-integration-tests/tests/ui/ownable/pass/namespacing_and_imports.rs +1 -1
  68. package/contracts/macro-integration-tests/tests/ui/ownable/pass/only_auth_env_param_variants.rs +1 -1
  69. package/contracts/macro-integration-tests/tests/ui_oapp.rs +11 -0
  70. package/contracts/message-libs/message-lib-common/Cargo.toml +0 -1
  71. package/contracts/message-libs/message-lib-common/src/errors.rs +1 -1
  72. package/contracts/message-libs/treasury/Cargo.toml +0 -2
  73. package/contracts/message-libs/treasury/src/tests/treasury_tests.rs +2 -2
  74. package/contracts/message-libs/uln-302/src/events.rs +4 -0
  75. package/contracts/message-libs/uln-302/src/send_uln.rs +22 -6
  76. package/contracts/message-libs/uln-302/src/tests/receive_uln302/effective_receive_uln_config.rs +2 -2
  77. package/contracts/message-libs/uln-302/src/tests/receive_uln302/set_default_receive_uln_configs.rs +2 -2
  78. package/contracts/message-libs/uln-302/src/tests/receive_uln302/verify.rs +2 -2
  79. package/contracts/message-libs/uln-302/src/tests/send_uln302/effective_executor_config.rs +2 -2
  80. package/contracts/message-libs/uln-302/src/tests/send_uln302/effective_send_uln_config.rs +2 -2
  81. package/contracts/message-libs/uln-302/src/tests/send_uln302/send.rs +21 -67
  82. package/contracts/message-libs/uln-302/src/tests/send_uln302/set_default_executor_configs.rs +2 -2
  83. package/contracts/message-libs/uln-302/src/tests/send_uln302/set_default_send_uln_configs.rs +2 -2
  84. package/contracts/oapps/counter/Cargo.toml +5 -6
  85. package/contracts/oapps/counter/integration_tests/setup_uln.rs +1 -1
  86. package/contracts/oapps/counter/integration_tests/utils.rs +19 -12
  87. package/contracts/oapps/oapp/src/errors.rs +1 -1
  88. package/contracts/oapps/oapp/src/interfaces/mod.rs +3 -0
  89. package/contracts/oapps/oapp/src/interfaces/oapp_msg_inspector.rs +47 -0
  90. package/contracts/oapps/oapp/src/lib.rs +1 -0
  91. package/contracts/oapps/oapp/src/macro_tests/test_macros.rs +4 -4
  92. package/contracts/oapps/oapp/src/oapp_core.rs +5 -5
  93. package/contracts/oapps/oapp/src/oapp_options_type3.rs +12 -4
  94. package/contracts/oapps/oapp/src/oapp_receiver.rs +14 -9
  95. package/contracts/oapps/oapp/src/tests/mod.rs +4 -4
  96. package/contracts/oapps/oapp/src/tests/oapp_core.rs +223 -0
  97. package/contracts/oapps/oapp/src/tests/oapp_options_type3.rs +240 -0
  98. package/contracts/oapps/oapp/src/tests/oapp_receiver.rs +381 -0
  99. package/contracts/oapps/oapp/src/tests/oapp_sender.rs +569 -0
  100. package/contracts/oapps/oapp-macros/Cargo.toml +8 -4
  101. package/contracts/oapps/oapp-macros/src/generators.rs +9 -34
  102. package/contracts/oapps/oapp-macros/src/lib.rs +3 -0
  103. package/contracts/oapps/oapp-macros/src/tests/mod.rs +2 -0
  104. package/contracts/oapps/oapp-macros/src/tests/oapp.rs +88 -0
  105. package/contracts/oapps/oapp-macros/src/tests/parse_custom_impls.rs +86 -0
  106. package/contracts/oapps/oapp-macros/src/tests/snapshots/oapp_macros__tests__oapp__snapshot_generate_oapp.snap +103 -0
  107. package/contracts/oapps/oft/integration-tests/utils.rs +28 -8
  108. package/contracts/oapps/oft/src/extensions/oft_fee.rs +153 -75
  109. package/contracts/oapps/oft/src/extensions/pausable.rs +61 -12
  110. package/contracts/oapps/oft/src/extensions/rate_limiter.rs +198 -134
  111. package/contracts/oapps/oft/src/oft.rs +45 -50
  112. package/contracts/oapps/oft/src/oft_types/lock_unlock.rs +1 -1
  113. package/contracts/oapps/oft/src/oft_types/mint_burn.rs +4 -26
  114. package/contracts/oapps/oft-core/Cargo.toml +1 -4
  115. package/contracts/oapps/oft-core/integration-tests/setup.rs +3 -3
  116. package/contracts/oapps/oft-core/integration-tests/utils.rs +21 -3
  117. package/contracts/oapps/oft-core/src/errors.rs +3 -2
  118. package/contracts/oapps/oft-core/src/events.rs +6 -0
  119. package/contracts/oapps/oft-core/src/lib.rs +1 -1
  120. package/contracts/oapps/oft-core/src/oft_core.rs +341 -246
  121. package/contracts/oapps/oft-core/src/storage.rs +7 -3
  122. package/contracts/oapps/oft-core/src/tests/mod.rs +1 -0
  123. package/contracts/oapps/oft-core/src/tests/test_decimals.rs +37 -2
  124. package/contracts/oapps/oft-core/src/tests/test_lz_receive.rs +2 -2
  125. package/contracts/oapps/oft-core/src/tests/test_msg_inspector.rs +323 -0
  126. package/contracts/oapps/oft-core/src/tests/test_send.rs +2 -2
  127. package/contracts/oapps/oft-core/src/tests/test_utils.rs +61 -16
  128. package/contracts/upgrader/src/lib.rs +30 -57
  129. package/contracts/upgrader/src/tests/test_data/test_upgradeable_contract1.wasm +0 -0
  130. package/contracts/upgrader/src/tests/test_data/test_upgradeable_contract2.wasm +0 -0
  131. package/contracts/upgrader/src/tests/test_upgrader.rs +44 -35
  132. package/contracts/utils/Cargo.toml +0 -1
  133. package/contracts/utils/src/buffer_reader.rs +1 -0
  134. package/contracts/utils/src/errors.rs +4 -2
  135. package/contracts/utils/src/multisig.rs +17 -8
  136. package/contracts/utils/src/ownable.rs +6 -6
  137. package/contracts/utils/src/testing_utils.rs +124 -54
  138. package/contracts/utils/src/tests/multisig.rs +12 -12
  139. package/contracts/utils/src/tests/ownable.rs +6 -6
  140. package/contracts/utils/src/tests/testing_utils.rs +50 -167
  141. package/contracts/utils/src/tests/ttl_configurable.rs +5 -5
  142. package/contracts/utils/src/tests/upgradeable.rs +372 -175
  143. package/contracts/utils/src/ttl_configurable.rs +13 -7
  144. package/contracts/utils/src/upgradeable.rs +48 -23
  145. package/contracts/workers/dvn/Cargo.toml +6 -6
  146. package/contracts/workers/dvn/src/auth.rs +12 -42
  147. package/contracts/workers/dvn/src/dvn.rs +15 -40
  148. package/contracts/workers/dvn/src/errors.rs +0 -1
  149. package/contracts/workers/dvn/src/interfaces/dvn.rs +35 -0
  150. package/contracts/workers/dvn/src/lib.rs +4 -3
  151. package/contracts/workers/dvn/src/tests/auth.rs +1 -1
  152. package/contracts/workers/dvn/src/tests/dvn.rs +19 -15
  153. package/contracts/workers/dvn/src/tests/multisig/set_threshold.rs +2 -4
  154. package/contracts/workers/dvn/src/tests/multisig/verify_signatures.rs +1 -3
  155. package/contracts/workers/dvn/src/tests/setup.rs +5 -9
  156. package/contracts/workers/dvn-fee-lib/Cargo.toml +2 -2
  157. package/contracts/workers/dvn-fee-lib/src/dvn_fee_lib.rs +38 -22
  158. package/contracts/workers/dvn-fee-lib/src/lib.rs +12 -2
  159. package/contracts/workers/dvn-fee-lib/src/tests/dvn_fee_lib.rs +17 -16
  160. package/contracts/workers/executor/Cargo.toml +4 -0
  161. package/contracts/workers/executor/src/executor.rs +15 -36
  162. package/contracts/workers/executor/src/lib.rs +2 -2
  163. package/contracts/workers/executor/src/tests/auth.rs +394 -0
  164. package/contracts/workers/executor/src/tests/executor.rs +410 -0
  165. package/contracts/workers/executor/src/tests/mod.rs +3 -0
  166. package/contracts/workers/executor/src/tests/setup.rs +250 -0
  167. package/contracts/workers/executor-fee-lib/Cargo.toml +7 -1
  168. package/contracts/workers/executor-fee-lib/src/executor_fee_lib.rs +62 -15
  169. package/contracts/workers/executor-fee-lib/src/executor_option.rs +28 -1
  170. package/contracts/workers/executor-fee-lib/src/lib.rs +11 -2
  171. package/contracts/workers/executor-fee-lib/src/tests/executor_fee_lib.rs +701 -0
  172. package/contracts/workers/executor-fee-lib/src/tests/executor_option.rs +370 -0
  173. package/contracts/workers/executor-fee-lib/src/tests/mod.rs +4 -0
  174. package/contracts/workers/executor-fee-lib/src/tests/setup.rs +60 -0
  175. package/contracts/workers/executor-helper/Cargo.toml +0 -1
  176. package/contracts/workers/executor-helper/src/lib.rs +3 -0
  177. package/contracts/workers/executor-helper/src/tests/executor_helper.rs +184 -0
  178. package/contracts/workers/executor-helper/src/tests/mod.rs +2 -0
  179. package/contracts/workers/executor-helper/src/tests/setup.rs +366 -0
  180. package/contracts/workers/fee-lib-interfaces/Cargo.toml +14 -0
  181. package/contracts/workers/{worker/src/interfaces/mod.rs → fee-lib-interfaces/src/lib.rs} +4 -3
  182. package/contracts/workers/price-feed/Cargo.toml +7 -1
  183. package/contracts/workers/price-feed/src/events.rs +1 -1
  184. package/contracts/workers/price-feed/src/lib.rs +12 -4
  185. package/contracts/workers/price-feed/src/price_feed.rs +5 -21
  186. package/contracts/workers/price-feed/src/storage.rs +1 -1
  187. package/contracts/workers/price-feed/src/tests/mod.rs +2 -0
  188. package/contracts/workers/price-feed/src/tests/price_feed.rs +869 -0
  189. package/contracts/workers/price-feed/src/tests/setup.rs +70 -0
  190. package/contracts/workers/price-feed/src/types.rs +1 -1
  191. package/contracts/workers/worker/src/errors.rs +1 -4
  192. package/contracts/workers/worker/src/lib.rs +0 -2
  193. package/contracts/workers/worker/src/storage.rs +32 -29
  194. package/contracts/workers/worker/src/tests/setup.rs +2 -8
  195. package/contracts/workers/worker/src/tests/worker.rs +96 -74
  196. package/contracts/workers/worker/src/worker.rs +75 -75
  197. package/docs/error-spec.md +55 -0
  198. package/docs/layerzero-v2-on-stellar.md +447 -0
  199. package/docs/oapp-guide.md +212 -0
  200. package/docs/oft-guide.md +314 -0
  201. package/package.json +3 -3
  202. package/sdk/.turbo/turbo-test.log +268 -263
  203. package/sdk/dist/generated/bml.d.ts +12 -4
  204. package/sdk/dist/generated/bml.js +9 -7
  205. package/sdk/dist/generated/counter.d.ts +306 -298
  206. package/sdk/dist/generated/counter.js +48 -46
  207. package/sdk/dist/generated/dvn.d.ts +450 -411
  208. package/sdk/dist/generated/dvn.js +66 -64
  209. package/sdk/dist/generated/dvn_fee_lib.d.ts +294 -338
  210. package/sdk/dist/generated/dvn_fee_lib.js +33 -64
  211. package/sdk/dist/generated/endpoint.d.ts +108 -100
  212. package/sdk/dist/generated/endpoint.js +21 -19
  213. package/sdk/dist/generated/executor.d.ts +414 -370
  214. package/sdk/dist/generated/executor.js +58 -55
  215. package/sdk/dist/generated/executor_fee_lib.d.ts +333 -377
  216. package/sdk/dist/generated/executor_fee_lib.js +34 -65
  217. package/sdk/dist/generated/executor_helper.d.ts +26 -190
  218. package/sdk/dist/generated/executor_helper.js +23 -28
  219. package/sdk/dist/generated/layerzero_view.d.ts +1271 -0
  220. package/sdk/dist/generated/layerzero_view.js +294 -0
  221. package/sdk/dist/generated/oft.d.ts +408 -385
  222. package/sdk/dist/generated/oft.js +89 -92
  223. package/sdk/dist/generated/price_feed.d.ts +385 -429
  224. package/sdk/dist/generated/price_feed.js +50 -81
  225. package/sdk/dist/generated/sml.d.ts +108 -100
  226. package/sdk/dist/generated/sml.js +21 -19
  227. package/sdk/dist/generated/treasury.d.ts +108 -100
  228. package/sdk/dist/generated/treasury.js +21 -19
  229. package/sdk/dist/generated/uln302.d.ts +108 -100
  230. package/sdk/dist/generated/uln302.js +23 -21
  231. package/sdk/dist/generated/upgrader.d.ts +189 -18
  232. package/sdk/dist/generated/upgrader.js +84 -4
  233. package/sdk/dist/index.d.ts +1 -0
  234. package/sdk/dist/index.js +2 -0
  235. package/sdk/package.json +1 -1
  236. package/sdk/src/index.ts +3 -0
  237. package/sdk/test/oft-sml.test.ts +4 -4
  238. package/sdk/test/suites/localnet.ts +84 -20
  239. package/sdk/test/upgrader.test.ts +2 -3
  240. package/tools/ts-bindings-gen/src/main.rs +2 -1
  241. package/contracts/ERROR_SPEC.md +0 -44
  242. package/contracts/endpoint-v2/ARCHITECTURE.md +0 -233
  243. package/contracts/oapps/oapp/src/tests/test_oapp_core.rs +0 -175
  244. package/contracts/oapps/oapp/src/tests/test_oapp_options_type3.rs +0 -212
  245. package/contracts/oapps/oapp/src/tests/test_oapp_receiver.rs +0 -153
  246. package/contracts/oapps/oapp/src/tests/test_oapp_sender.rs +0 -294
  247. /package/contracts/workers/{worker/src/interfaces → fee-lib-interfaces/src}/dvn_fee_lib.rs +0 -0
  248. /package/contracts/workers/{worker/src/interfaces → fee-lib-interfaces/src}/executor_fee_lib.rs +0 -0
  249. /package/contracts/workers/{worker/src/interfaces → fee-lib-interfaces/src}/price_feed.rs +0 -0
@@ -0,0 +1,240 @@
1
+ use crate::{
2
+ self as oapp,
3
+ errors::OAppError,
4
+ oapp_core::OAppCore,
5
+ oapp_options_type3::{EnforcedOptionParam, EnforcedOptionSet},
6
+ oapp_receiver::{LzReceiveInternal, OAppReceiver},
7
+ };
8
+ use common_macros::contract_impl;
9
+ use soroban_sdk::{
10
+ contract, contractimpl,
11
+ testutils::{Address as _, MockAuth, MockAuthInvoke},
12
+ vec, Address, Bytes, BytesN, Env, IntoVal,
13
+ };
14
+ use utils::testing_utils::assert_eq_event;
15
+
16
+ const OPTION_TYPE_3: u32 = 3;
17
+ const REMOTE_EID_1: u32 = 100;
18
+ const REMOTE_EID_2: u32 = 200;
19
+ const MSG_TYPE_SEND: u32 = 1;
20
+ const MSG_TYPE_RECEIVE: u32 = 2;
21
+
22
+ #[contract]
23
+ pub struct DummyEndpoint;
24
+
25
+ #[contractimpl]
26
+ impl DummyEndpoint {
27
+ pub fn set_delegate(_env: Env, _oapp: &Address, _delegate: &Option<Address>) {
28
+ // do nothing
29
+ }
30
+ }
31
+
32
+ #[oapp_macros::oapp(custom = [core, sender, receiver])]
33
+ pub struct DummyOAppOptionsType3;
34
+
35
+ #[contract_impl(contracttrait)]
36
+ impl OAppCore for DummyOAppOptionsType3 {}
37
+
38
+ impl LzReceiveInternal for DummyOAppOptionsType3 {
39
+ fn __lz_receive(
40
+ _env: &Env,
41
+ _origin: &endpoint_v2::Origin,
42
+ _guid: &BytesN<32>,
43
+ _message: &Bytes,
44
+ _extra_data: &Bytes,
45
+ _executor: &Address,
46
+ _value: i128,
47
+ ) {
48
+ // Dummy implementation for testing
49
+ }
50
+ }
51
+
52
+ #[contract_impl(contracttrait)]
53
+ impl OAppReceiver for DummyOAppOptionsType3 {}
54
+
55
+ #[contract_impl]
56
+ impl DummyOAppOptionsType3 {
57
+ pub fn __constructor(env: &Env, owner: &Address, endpoint: &Address, delegate: &Option<Address>) {
58
+ oapp::oapp_core::initialize_oapp::<Self>(env, owner, endpoint, delegate);
59
+ }
60
+ }
61
+
62
+ struct TestSetup<'a> {
63
+ env: Env,
64
+ owner: Address,
65
+ oapp_client: DummyOAppOptionsType3Client<'a>,
66
+ }
67
+
68
+ fn setup<'a>() -> TestSetup<'a> {
69
+ let env = Env::default();
70
+
71
+ let owner = Address::generate(&env);
72
+ let endpoint = env.register(DummyEndpoint, ());
73
+ let delegate: Option<Address> = Some(owner.clone());
74
+ let oapp = env.register(DummyOAppOptionsType3, (&owner, &endpoint, &delegate));
75
+ let oapp_client = DummyOAppOptionsType3Client::new(&env, &oapp);
76
+
77
+ TestSetup { env, owner, oapp_client }
78
+ }
79
+
80
+ fn create_valid_options(env: &Env, data: &[u8]) -> Bytes {
81
+ let mut buffer = Bytes::from_array(env, &(OPTION_TYPE_3 as u16).to_be_bytes());
82
+ buffer.extend_from_slice(data);
83
+ buffer
84
+ }
85
+
86
+ fn set_enforced_options_with_auth(
87
+ env: &Env,
88
+ signer: &Address,
89
+ oapp_client: &DummyOAppOptionsType3Client<'_>,
90
+ enforced_params: &soroban_sdk::Vec<EnforcedOptionParam>,
91
+ ) {
92
+ env.mock_auths(&[MockAuth {
93
+ address: signer,
94
+ invoke: &MockAuthInvoke {
95
+ contract: &oapp_client.address,
96
+ fn_name: "set_enforced_options",
97
+ args: (enforced_params,).into_val(env),
98
+ sub_invokes: &[],
99
+ },
100
+ }]);
101
+ oapp_client.set_enforced_options(enforced_params);
102
+ }
103
+
104
+ #[test]
105
+ fn test_enforced_options_lifecycle() {
106
+ let TestSetup { env, owner, oapp_client, .. } = setup();
107
+
108
+ // Unset returns empty
109
+ assert_eq!(oapp_client.enforced_options(&999, &999), Bytes::new(&env));
110
+
111
+ // Set enforced options for different eid/msg_type combinations
112
+ let enforced1 = create_valid_options(&env, &[1, 2, 3, 4]);
113
+ let enforced2 = create_valid_options(&env, &[5, 6, 7, 8]);
114
+ let enforced_params = vec![
115
+ &env,
116
+ EnforcedOptionParam { eid: REMOTE_EID_1, msg_type: MSG_TYPE_SEND, options: enforced1.clone() },
117
+ EnforcedOptionParam { eid: REMOTE_EID_2, msg_type: MSG_TYPE_RECEIVE, options: enforced2.clone() },
118
+ ];
119
+ set_enforced_options_with_auth(&env, &owner, &oapp_client, &enforced_params);
120
+
121
+ // assert events
122
+ assert_eq_event(&env, &oapp_client.address, EnforcedOptionSet { enforced_option_params: enforced_params.clone() });
123
+
124
+ // Verify options were set correctly
125
+ assert_eq!(oapp_client.enforced_options(&REMOTE_EID_1, &MSG_TYPE_SEND), enforced1.clone());
126
+ assert_eq!(oapp_client.enforced_options(&REMOTE_EID_2, &MSG_TYPE_RECEIVE), enforced2.clone());
127
+
128
+ // Update enforced options for one combination
129
+ let updated = create_valid_options(&env, &[9, 8, 7, 6, 5]);
130
+ let update_params =
131
+ vec![&env, EnforcedOptionParam { eid: REMOTE_EID_1, msg_type: MSG_TYPE_SEND, options: updated.clone() }];
132
+ set_enforced_options_with_auth(&env, &owner, &oapp_client, &update_params);
133
+ assert_eq_event(&env, &oapp_client.address, EnforcedOptionSet { enforced_option_params: update_params.clone() });
134
+ assert_eq!(oapp_client.enforced_options(&REMOTE_EID_1, &MSG_TYPE_SEND), updated);
135
+ }
136
+
137
+ #[test]
138
+ fn test_combine_options() {
139
+ let TestSetup { env, owner, oapp_client, .. } = setup();
140
+
141
+ // combine_options: no enforced -> returns extra (including empty)
142
+ let extra_only = create_valid_options(&env, &[9, 10, 11]);
143
+ assert_eq!(oapp_client.combine_options(&REMOTE_EID_1, &MSG_TYPE_SEND, &extra_only), extra_only);
144
+
145
+ let empty_extra = Bytes::new(&env);
146
+ assert_eq!(oapp_client.combine_options(&REMOTE_EID_1, &MSG_TYPE_SEND, &empty_extra), empty_extra);
147
+
148
+ // Set enforced options for the combine tests
149
+ let enforced = create_valid_options(&env, &[1, 2, 3, 4]);
150
+ let enforced_params =
151
+ vec![&env, EnforcedOptionParam { eid: REMOTE_EID_1, msg_type: MSG_TYPE_SEND, options: enforced.clone() }];
152
+ set_enforced_options_with_auth(&env, &owner, &oapp_client, &enforced_params);
153
+
154
+ // combine_options: enforced present -> empty extra returns enforced
155
+ assert_eq!(oapp_client.combine_options(&REMOTE_EID_1, &MSG_TYPE_SEND, &Bytes::new(&env)), enforced.clone());
156
+
157
+ // combine_options: both present -> enforced + extra(without its 2-byte header)
158
+ let extra: Bytes = create_valid_options(&env, &[4, 5, 6]);
159
+ let combined = oapp_client.combine_options(&REMOTE_EID_1, &MSG_TYPE_SEND, &extra);
160
+ let expected_combined = create_valid_options(&env, &[1, 2, 3, 4, 4, 5, 6]);
161
+ assert_eq!(combined, expected_combined);
162
+ }
163
+
164
+ #[test]
165
+ #[should_panic(expected = "HostError: Error(Auth, InvalidAction)")]
166
+ fn test_set_enforced_options_unauthorized() {
167
+ let TestSetup { env, oapp_client, .. } = setup();
168
+
169
+ let options = create_valid_options(&env, &[1, 2, 3, 4]);
170
+ let enforced_params =
171
+ vec![&env, EnforcedOptionParam { eid: REMOTE_EID_1, msg_type: MSG_TYPE_SEND, options: options.clone() }];
172
+ oapp_client.set_enforced_options(&enforced_params);
173
+ }
174
+
175
+ #[test]
176
+ #[should_panic(expected = "HostError: Error(Auth, InvalidAction)")]
177
+ fn test_set_enforced_options_non_owner_authorized() {
178
+ let TestSetup { env, owner, oapp_client, .. } = setup();
179
+ let non_owner = Address::generate(&env);
180
+ assert!(non_owner != owner);
181
+
182
+ let options = create_valid_options(&env, &[1, 2, 3, 4]);
183
+ let enforced_params =
184
+ vec![&env, EnforcedOptionParam { eid: REMOTE_EID_1, msg_type: MSG_TYPE_SEND, options: options.clone() }];
185
+
186
+ set_enforced_options_with_auth(&env, &non_owner, &oapp_client, &enforced_params);
187
+ }
188
+
189
+ #[test]
190
+ fn test_set_enforced_options_invalid_options_returns_error() {
191
+ let TestSetup { env, owner, oapp_client, .. } = setup();
192
+
193
+ // wrong option type (not 3)
194
+ let mut invalid = Bytes::from_array(&env, &(4u16).to_be_bytes());
195
+ invalid.extend_from_slice(&[1, 2, 3]);
196
+
197
+ let enforced_params =
198
+ vec![&env, EnforcedOptionParam { eid: REMOTE_EID_1, msg_type: MSG_TYPE_SEND, options: invalid }];
199
+
200
+ env.mock_auths(&[MockAuth {
201
+ address: &owner,
202
+ invoke: &MockAuthInvoke {
203
+ contract: &oapp_client.address,
204
+ fn_name: "set_enforced_options",
205
+ args: (&enforced_params,).into_val(&env),
206
+ sub_invokes: &[],
207
+ },
208
+ }]);
209
+ let result = oapp_client.try_set_enforced_options(&enforced_params);
210
+ assert_eq!(result.err().unwrap().ok().unwrap(), OAppError::InvalidOptions.into());
211
+ }
212
+
213
+ #[test]
214
+ fn test_combine_options_extra_invalid_type_returns_error_when_enforced_present() {
215
+ let TestSetup { env, owner, oapp_client, .. } = setup();
216
+
217
+ let enforced = create_valid_options(&env, &[1, 2, 3]);
218
+ let params = vec![&env, EnforcedOptionParam { eid: REMOTE_EID_1, msg_type: MSG_TYPE_SEND, options: enforced }];
219
+ set_enforced_options_with_auth(&env, &owner, &oapp_client, &params);
220
+
221
+ // extra has wrong option type (not 3) but len >= 2 -> validated and should panic
222
+ let mut extra_invalid = Bytes::from_array(&env, &(4u16).to_be_bytes());
223
+ extra_invalid.extend_from_slice(&[9, 9, 9]);
224
+ let result = oapp_client.try_combine_options(&REMOTE_EID_1, &MSG_TYPE_SEND, &extra_invalid);
225
+ assert_eq!(result.err().unwrap().ok().unwrap(), OAppError::InvalidOptions.into());
226
+ }
227
+
228
+ #[test]
229
+ fn test_combine_options_extra_too_short_returns_error_when_enforced_present() {
230
+ let TestSetup { env, owner, oapp_client, .. } = setup();
231
+
232
+ let enforced = create_valid_options(&env, &[1, 2, 3]);
233
+ let params = vec![&env, EnforcedOptionParam { eid: REMOTE_EID_1, msg_type: MSG_TYPE_SEND, options: enforced }];
234
+ set_enforced_options_with_auth(&env, &owner, &oapp_client, &params);
235
+
236
+ // extra is non-empty but len < 2 -> should panic
237
+ let extra_too_short = Bytes::from_array(&env, &[1u8]);
238
+ let result = oapp_client.try_combine_options(&REMOTE_EID_1, &MSG_TYPE_SEND, &extra_too_short);
239
+ assert_eq!(result.err().unwrap().ok().unwrap(), OAppError::InvalidOptions.into());
240
+ }
@@ -0,0 +1,381 @@
1
+ use crate::{self as oapp, errors::OAppError, oapp_receiver::LzReceiveInternal};
2
+ use endpoint_v2::Origin;
3
+ use soroban_sdk::{
4
+ contract, contractimpl, symbol_short,
5
+ testutils::{Address as _, MockAuth, MockAuthInvoke},
6
+ token::StellarAssetClient,
7
+ Address, Bytes, BytesN, Env, IntoVal,
8
+ };
9
+
10
+ #[oapp_macros::oapp]
11
+ pub struct DummyOAppReceiver;
12
+
13
+ impl LzReceiveInternal for DummyOAppReceiver {
14
+ fn __lz_receive(
15
+ _env: &Env,
16
+ _origin: &Origin,
17
+ _guid: &BytesN<32>,
18
+ _message: &Bytes,
19
+ _extra_data: &Bytes,
20
+ _executor: &Address,
21
+ _value: i128,
22
+ ) {
23
+ // do nothing
24
+ }
25
+ }
26
+
27
+ #[contractimpl]
28
+ impl DummyOAppReceiver {
29
+ pub fn __constructor(env: &Env, owner: &Address, endpoint: &Address) {
30
+ oapp::oapp_core::initialize_oapp::<Self>(env, owner, endpoint, &None);
31
+ }
32
+ }
33
+
34
+ const REMOTE_EID: u32 = 100;
35
+ const UNSET_EID: u32 = 999;
36
+
37
+ // Mock Endpoint (minimal subset used by oapp_receiver::verify_and_clear_payload)
38
+
39
+ #[contract]
40
+ pub struct MockEndpoint;
41
+
42
+ #[contractimpl]
43
+ impl MockEndpoint {
44
+ pub fn __constructor(env: Env, native_token: Address) {
45
+ env.storage().instance().set(&symbol_short!("ntk"), &native_token);
46
+ }
47
+
48
+ pub fn set_delegate(_env: Env, _oapp: &Address, _delegate: &Option<Address>) {
49
+ // do nothing
50
+ }
51
+
52
+ pub fn native_token(env: Env) -> Address {
53
+ env.storage().instance().get(&symbol_short!("ntk")).unwrap()
54
+ }
55
+
56
+ pub fn clear(env: Env, caller: Address, origin: Origin, receiver: Address, guid: BytesN<32>, message: Bytes) {
57
+ // Record last clear for assertions
58
+ env.storage().instance().set(&symbol_short!("clr_c"), &caller);
59
+ env.storage().instance().set(&symbol_short!("clr_o"), &origin);
60
+ env.storage().instance().set(&symbol_short!("clr_r"), &receiver);
61
+ env.storage().instance().set(&symbol_short!("clr_g"), &guid);
62
+ env.storage().instance().set(&symbol_short!("clr_m"), &message);
63
+ }
64
+
65
+ pub fn last_clear(env: Env) -> (Address, Origin, Address, BytesN<32>, Bytes) {
66
+ (
67
+ env.storage().instance().get(&symbol_short!("clr_c")).unwrap(),
68
+ env.storage().instance().get(&symbol_short!("clr_o")).unwrap(),
69
+ env.storage().instance().get(&symbol_short!("clr_r")).unwrap(),
70
+ env.storage().instance().get(&symbol_short!("clr_g")).unwrap(),
71
+ env.storage().instance().get(&symbol_short!("clr_m")).unwrap(),
72
+ )
73
+ }
74
+ }
75
+
76
+ struct TestSetup<'a> {
77
+ env: Env,
78
+ owner: Address,
79
+ endpoint: Address,
80
+ token_admin: Address,
81
+ native_token: Address,
82
+ native_token_admin_client: StellarAssetClient<'a>,
83
+ oapp_client: DummyOAppReceiverClient<'a>,
84
+ }
85
+
86
+ fn setup<'a>() -> TestSetup<'a> {
87
+ let env = Env::default();
88
+
89
+ let owner = Address::generate(&env);
90
+ let token_admin = Address::generate(&env);
91
+ let native_token_sac = env.register_stellar_asset_contract_v2(token_admin.clone());
92
+ let native_token = native_token_sac.address();
93
+ let native_token_admin_client = StellarAssetClient::new(&env, &native_token);
94
+
95
+ let endpoint = env.register(MockEndpoint, (&native_token,));
96
+ let oapp = env.register(DummyOAppReceiver, (&owner, &endpoint));
97
+ let oapp_client = DummyOAppReceiverClient::new(&env, &oapp);
98
+ TestSetup { env, owner, endpoint, token_admin, native_token, native_token_admin_client, oapp_client }
99
+ }
100
+
101
+ fn set_peer(env: &Env, owner: &Address, oapp_client: &DummyOAppReceiverClient<'_>, eid: u32, peer: &BytesN<32>) {
102
+ let peer_option = Some(peer.clone());
103
+ env.mock_auths(&[MockAuth {
104
+ address: owner,
105
+ invoke: &MockAuthInvoke {
106
+ contract: &oapp_client.address,
107
+ fn_name: "set_peer",
108
+ args: (&eid, &peer_option).into_val(env),
109
+ sub_invokes: &[],
110
+ },
111
+ }]);
112
+ oapp_client.set_peer(&eid, &peer_option);
113
+ }
114
+
115
+ fn lz_receive(
116
+ env: &Env,
117
+ oapp_client: &DummyOAppReceiverClient<'_>,
118
+ executor: &Address,
119
+ origin: &Origin,
120
+ guid: &BytesN<32>,
121
+ message: &Bytes,
122
+ extra_data: &Bytes,
123
+ value: i128,
124
+ sub_invokes: &[MockAuthInvoke<'_>],
125
+ ) {
126
+ env.mock_auths(&[MockAuth {
127
+ address: executor,
128
+ invoke: &MockAuthInvoke {
129
+ contract: &oapp_client.address,
130
+ fn_name: "lz_receive",
131
+ args: (executor, origin, guid, message, extra_data, value).into_val(env),
132
+ sub_invokes,
133
+ },
134
+ }]);
135
+ oapp_client.lz_receive(executor, origin, guid, message, extra_data, &value);
136
+ }
137
+
138
+ #[test]
139
+ fn test_is_compose_msg_sender() {
140
+ let TestSetup { env, oapp_client, .. } = setup();
141
+
142
+ let origin = Origin { src_eid: REMOTE_EID, sender: BytesN::from_array(&env, &[1; 32]), nonce: 1 };
143
+ let message = Bytes::from_array(&env, &[1, 2, 3, 4]);
144
+
145
+ // Test with same contract address (should return true)
146
+ let result = oapp_client.is_compose_msg_sender(&origin, &message, &oapp_client.address);
147
+ assert_eq!(result, true);
148
+ let different_sender = Address::generate(&env);
149
+
150
+ // Test with different sender address (should return false)
151
+ assert_eq!(oapp_client.is_compose_msg_sender(&origin, &message, &different_sender), false);
152
+ }
153
+
154
+ #[test]
155
+ fn test_allow_initialize_path_cases() {
156
+ let TestSetup { env, owner, oapp_client, .. } = setup();
157
+
158
+ // no peer set -> false
159
+ let origin_no_peer = Origin { src_eid: UNSET_EID, sender: BytesN::from_array(&env, &[5; 32]), nonce: 1 };
160
+ assert_eq!(oapp_client.allow_initialize_path(&origin_no_peer), false);
161
+
162
+ // set peer for REMOTE_EID
163
+ let peer_bytes: BytesN<32> = BytesN::from_array(&env, &[5; 32]);
164
+ set_peer(&env, &owner, &oapp_client, REMOTE_EID, &peer_bytes);
165
+
166
+ // matching -> true
167
+ let origin_match = Origin { src_eid: REMOTE_EID, sender: peer_bytes.clone(), nonce: 1 };
168
+ assert_eq!(oapp_client.allow_initialize_path(&origin_match), true);
169
+
170
+ // non-matching -> false
171
+ let origin_non_match = Origin { src_eid: REMOTE_EID, sender: BytesN::from_array(&env, &[6; 32]), nonce: 1 };
172
+ assert_eq!(oapp_client.allow_initialize_path(&origin_non_match), false);
173
+ }
174
+
175
+ #[test]
176
+ fn test_lz_receive_verifies_peer_and_calls_clear_value_zero() {
177
+ let TestSetup { env, owner, endpoint, oapp_client, .. } = setup();
178
+
179
+ // Configure peer
180
+ let peer: BytesN<32> = BytesN::from_array(&env, &[7; 32]);
181
+ set_peer(&env, &owner, &oapp_client, REMOTE_EID, &peer);
182
+
183
+ let executor = Address::generate(&env);
184
+ let origin = Origin { src_eid: REMOTE_EID, sender: peer, nonce: 1 };
185
+ let guid = BytesN::from_array(&env, &[2u8; 32]);
186
+ let message = Bytes::from_array(&env, &[1, 2, 3]);
187
+ let extra_data = Bytes::new(&env);
188
+ lz_receive(&env, &oapp_client, &executor, &origin, &guid, &message, &extra_data, 0, &[]);
189
+
190
+ let endpoint_client = MockEndpointClient::new(&env, &endpoint);
191
+ let (caller, cleared_origin, receiver, cleared_guid, cleared_message) = endpoint_client.last_clear();
192
+ assert_eq!(caller, oapp_client.address);
193
+ assert_eq!(cleared_origin, origin);
194
+ assert_eq!(receiver, oapp_client.address);
195
+ assert_eq!(cleared_guid, guid);
196
+ assert_eq!(cleared_message, message);
197
+ }
198
+
199
+ #[test]
200
+ fn test_lz_receive_transfers_native_token_when_value_positive() {
201
+ let TestSetup { env, owner, endpoint, native_token, native_token_admin_client, token_admin, oapp_client, .. } =
202
+ setup();
203
+
204
+ // Configure peer
205
+ let peer: BytesN<32> = BytesN::from_array(&env, &[9; 32]);
206
+ set_peer(&env, &owner, &oapp_client, REMOTE_EID, &peer);
207
+
208
+ let executor = Address::generate(&env);
209
+ let origin = Origin { src_eid: REMOTE_EID, sender: peer, nonce: 1 };
210
+ let guid = BytesN::from_array(&env, &[3u8; 32]);
211
+ let message = Bytes::from_array(&env, &[4, 5, 6]);
212
+ let extra_data = Bytes::new(&env);
213
+ let value: i128 = 123;
214
+
215
+ // Mint native token to executor (admin auth)
216
+ env.mock_auths(&[MockAuth {
217
+ address: &token_admin,
218
+ invoke: &MockAuthInvoke {
219
+ contract: &native_token,
220
+ fn_name: "mint",
221
+ args: (&executor, &value).into_val(&env),
222
+ sub_invokes: &[],
223
+ },
224
+ }]);
225
+ native_token_admin_client.mint(&executor, &value);
226
+
227
+ // lz_receive should transfer tokens from executor -> oapp
228
+ let transfer_invoke = MockAuthInvoke {
229
+ contract: &native_token,
230
+ fn_name: "transfer",
231
+ args: (&executor, &oapp_client.address, &value).into_val(&env),
232
+ sub_invokes: &[],
233
+ };
234
+ let sub_invokes = [transfer_invoke];
235
+ lz_receive(&env, &oapp_client, &executor, &origin, &guid, &message, &extra_data, value, &sub_invokes);
236
+
237
+ let endpoint_client = MockEndpointClient::new(&env, &endpoint);
238
+ // Asserts clear() was called (last_clear() will panic if not)
239
+ endpoint_client.last_clear();
240
+
241
+ let token_client = soroban_sdk::token::TokenClient::new(&env, &native_token);
242
+ assert_eq!(token_client.balance(&executor), 0);
243
+ assert_eq!(token_client.balance(&oapp_client.address), value);
244
+ }
245
+
246
+ #[test]
247
+ fn test_lz_receive_rejects_negative_value_and_does_not_clear() {
248
+ let TestSetup { env, owner, endpoint, native_token, native_token_admin_client, token_admin, oapp_client, .. } =
249
+ setup();
250
+
251
+ // Configure peer
252
+ let peer: BytesN<32> = BytesN::from_array(&env, &[9; 32]);
253
+ set_peer(&env, &owner, &oapp_client, REMOTE_EID, &peer);
254
+
255
+ let executor = Address::generate(&env);
256
+ let origin = Origin { src_eid: REMOTE_EID, sender: peer, nonce: 1 };
257
+ let guid = BytesN::from_array(&env, &[3u8; 32]);
258
+ let message = Bytes::from_array(&env, &[4, 5, 6]);
259
+ let extra_data = Bytes::new(&env);
260
+ let value: i128 = -123;
261
+
262
+ // Fund executor with a positive balance so the only failure is the negative amount.
263
+ env.mock_auths(&[MockAuth {
264
+ address: &token_admin,
265
+ invoke: &MockAuthInvoke {
266
+ contract: &native_token,
267
+ fn_name: "mint",
268
+ args: (&executor, &(-value)).into_val(&env),
269
+ sub_invokes: &[],
270
+ },
271
+ }]);
272
+ native_token_admin_client.mint(&executor, &(-value));
273
+
274
+ // lz_receive should attempt transfer with a negative value and fail.
275
+ let transfer_invoke = MockAuthInvoke {
276
+ contract: &native_token,
277
+ fn_name: "transfer",
278
+ args: (&executor, &oapp_client.address, &value).into_val(&env),
279
+ sub_invokes: &[],
280
+ };
281
+ let sub_invokes = [transfer_invoke];
282
+ env.mock_auths(&[MockAuth {
283
+ address: &executor,
284
+ invoke: &MockAuthInvoke {
285
+ contract: &oapp_client.address,
286
+ fn_name: "lz_receive",
287
+ args: (&executor, &origin, &guid, &message, &extra_data, &value).into_val(&env),
288
+ sub_invokes: &sub_invokes,
289
+ },
290
+ }]);
291
+
292
+ let result = oapp_client.try_lz_receive(&executor, &origin, &guid, &message, &extra_data, &value);
293
+ assert_eq!(result.err().unwrap().ok().unwrap(), soroban_sdk::Error::from_contract_error(8)); //negative amount is not allowed
294
+
295
+ // No balances changed.
296
+ let token_client = soroban_sdk::token::TokenClient::new(&env, &native_token);
297
+ assert_eq!(token_client.balance(&executor), -value);
298
+ assert_eq!(token_client.balance(&oapp_client.address), 0);
299
+
300
+ // Payload should not have been cleared.
301
+ let endpoint_client = MockEndpointClient::new(&env, &endpoint);
302
+ assert!(endpoint_client.try_last_clear().is_err());
303
+ }
304
+
305
+ #[test]
306
+ fn test_next_nonce_defaults_to_zero() {
307
+ let TestSetup { env, oapp_client, .. } = setup();
308
+ let sender = BytesN::from_array(&env, &[1u8; 32]);
309
+ assert_eq!(oapp_client.next_nonce(&REMOTE_EID, &sender), 0);
310
+ }
311
+
312
+ #[test]
313
+ #[should_panic(expected = "HostError: Error(Auth, InvalidAction)")]
314
+ fn test_lz_receive_requires_executor_auth() {
315
+ let TestSetup { env, owner, oapp_client, .. } = setup();
316
+
317
+ let peer: BytesN<32> = BytesN::from_array(&env, &[7; 32]);
318
+ set_peer(&env, &owner, &oapp_client, REMOTE_EID, &peer);
319
+
320
+ // Call without executor auth mocked -> should fail at executor.require_auth()
321
+ let executor = Address::generate(&env);
322
+ let origin = Origin { src_eid: REMOTE_EID, sender: peer, nonce: 1 };
323
+ let guid = BytesN::from_array(&env, &[2u8; 32]);
324
+ let message = Bytes::from_array(&env, &[1, 2, 3]);
325
+ let extra_data = Bytes::new(&env);
326
+ oapp_client.lz_receive(&executor, &origin, &guid, &message, &extra_data, &0);
327
+ }
328
+
329
+ #[test]
330
+ fn test_lz_receive_wrong_peer_returns_only_peer_error() {
331
+ let TestSetup { env, owner, oapp_client, .. } = setup();
332
+
333
+ let configured_peer: BytesN<32> = BytesN::from_array(&env, &[7; 32]);
334
+ set_peer(&env, &owner, &oapp_client, REMOTE_EID, &configured_peer);
335
+
336
+ let executor = Address::generate(&env);
337
+ let wrong_sender: BytesN<32> = BytesN::from_array(&env, &[8; 32]);
338
+ let origin = Origin { src_eid: REMOTE_EID, sender: wrong_sender, nonce: 1 };
339
+ let guid = BytesN::from_array(&env, &[2u8; 32]);
340
+ let message = Bytes::from_array(&env, &[1, 2, 3]);
341
+ let extra_data = Bytes::new(&env);
342
+ let value: i128 = 0;
343
+
344
+ env.mock_auths(&[MockAuth {
345
+ address: &executor,
346
+ invoke: &MockAuthInvoke {
347
+ contract: &oapp_client.address,
348
+ fn_name: "lz_receive",
349
+ args: (&executor, &origin, &guid, &message, &extra_data, &value).into_val(&env),
350
+ sub_invokes: &[],
351
+ },
352
+ }]);
353
+ let result = oapp_client.try_lz_receive(&executor, &origin, &guid, &message, &extra_data, &value);
354
+ assert_eq!(result.err().unwrap().ok().unwrap(), OAppError::OnlyPeer.into());
355
+ }
356
+
357
+ #[test]
358
+ fn test_lz_receive_no_peer_returns_only_peer_error() {
359
+ let TestSetup { env, oapp_client, .. } = setup();
360
+
361
+ let executor = Address::generate(&env);
362
+ let origin = Origin { src_eid: REMOTE_EID, sender: BytesN::from_array(&env, &[1; 32]), nonce: 1 };
363
+ let guid = BytesN::from_array(&env, &[2u8; 32]);
364
+ let message = Bytes::from_array(&env, &[1, 2, 3]);
365
+ let extra_data = Bytes::new(&env);
366
+ let value: i128 = 0;
367
+
368
+ env.mock_auths(&[MockAuth {
369
+ address: &executor,
370
+ invoke: &MockAuthInvoke {
371
+ contract: &oapp_client.address,
372
+ fn_name: "lz_receive",
373
+ args: (&executor, &origin, &guid, &message, &extra_data, &value).into_val(&env),
374
+ sub_invokes: &[],
375
+ },
376
+ }]);
377
+
378
+ // No peer configured -> should fail the peer check with OnlyPeer
379
+ let result = oapp_client.try_lz_receive(&executor, &origin, &guid, &message, &extra_data, &value);
380
+ assert_eq!(result.err().unwrap().ok().unwrap(), OAppError::OnlyPeer.into());
381
+ }