@layerzerolabs/protocol-stellar-v2 0.2.20 → 0.2.22

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 (198) hide show
  1. package/.turbo/turbo-build.log +783 -802
  2. package/.turbo/turbo-lint.log +320 -157
  3. package/.turbo/turbo-test.log +1414 -1457
  4. package/Cargo.lock +109 -108
  5. package/Cargo.toml +32 -18
  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 +2 -2
  9. package/contracts/common-macros/src/lib.rs +27 -10
  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/snapshots/common_macros__tests__auth__snapshot_generated_multisig_code.snap +6 -12
  13. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__auth__snapshot_generated_ownable_code.snap +12 -17
  14. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__ttl_configurable__snapshot_generated_ttl_configurable_code.snap +2 -7
  15. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__upgradeable__snapshot_generated_upgradeable_code.snap +20 -9
  16. package/contracts/common-macros/src/tests/upgradeable.rs +26 -4
  17. package/contracts/common-macros/src/ttl_configurable.rs +2 -10
  18. package/contracts/common-macros/src/ttl_extendable.rs +2 -10
  19. package/contracts/common-macros/src/upgradeable.rs +56 -15
  20. package/contracts/common-macros/src/utils.rs +0 -9
  21. package/contracts/endpoint-v2/src/lib.rs +3 -2
  22. package/contracts/endpoint-v2/src/tests/endpoint_v2/clear.rs +2 -2
  23. package/contracts/endpoint-v2/src/tests/endpoint_v2/lz_receive_alert.rs +3 -3
  24. package/contracts/endpoint-v2/src/tests/endpoint_v2/send.rs +4 -4
  25. package/contracts/endpoint-v2/src/tests/endpoint_v2/set_delegate.rs +17 -5
  26. package/contracts/endpoint-v2/src/tests/endpoint_v2/set_zro.rs +4 -4
  27. package/contracts/endpoint-v2/src/tests/endpoint_v2/verify.rs +2 -2
  28. package/contracts/endpoint-v2/src/tests/message_lib_manager/register_library.rs +2 -2
  29. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_default_receive_lib_timeout.rs +6 -6
  30. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_default_receive_library.rs +67 -37
  31. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_default_send_library.rs +5 -5
  32. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_receive_library.rs +44 -54
  33. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_receive_library_timeout.rs +7 -7
  34. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_send_library.rs +8 -8
  35. package/contracts/endpoint-v2/src/tests/messaging_channel/burn.rs +3 -3
  36. package/contracts/endpoint-v2/src/tests/messaging_channel/nilify.rs +4 -4
  37. package/contracts/endpoint-v2/src/tests/messaging_channel/skip.rs +3 -3
  38. package/contracts/endpoint-v2/src/tests/messaging_composer/clear_compose.rs +2 -2
  39. package/contracts/endpoint-v2/src/tests/messaging_composer/lz_compose_alert.rs +3 -3
  40. package/contracts/endpoint-v2/src/tests/messaging_composer/send_compose.rs +2 -2
  41. package/contracts/layerzero-views/Cargo.toml +0 -1
  42. package/contracts/layerzero-views/src/layerzero_view.rs +1 -13
  43. package/contracts/macro-integration-tests/Cargo.toml +5 -15
  44. package/contracts/macro-integration-tests/tests/runtime/oapp/mod.rs +48 -0
  45. package/contracts/macro-integration-tests/tests/runtime/oapp/oapp_core.rs +170 -0
  46. package/contracts/macro-integration-tests/tests/runtime/oapp/options_type3.rs +154 -0
  47. package/contracts/macro-integration-tests/tests/runtime/oapp/receiver.rs +338 -0
  48. package/contracts/macro-integration-tests/tests/runtime/oapp/sender.rs +435 -0
  49. package/contracts/macro-integration-tests/tests/runtime.rs +1 -0
  50. package/contracts/macro-integration-tests/tests/ui/oapp/fail/custom_wrong_value.rs +8 -0
  51. package/contracts/macro-integration-tests/tests/ui/oapp/fail/custom_wrong_value.stderr +5 -0
  52. package/contracts/macro-integration-tests/tests/ui/oapp/fail/missing_lz_receive_internal.rs +8 -0
  53. package/contracts/macro-integration-tests/tests/ui/oapp/fail/missing_lz_receive_internal.stderr +71 -0
  54. package/contracts/macro-integration-tests/tests/ui/oapp/fail/non_struct_input.rs +10 -0
  55. package/contracts/macro-integration-tests/tests/ui/oapp/fail/non_struct_input.stderr +5 -0
  56. package/contracts/macro-integration-tests/tests/ui/oapp/fail/unknown_custom_option.rs +8 -0
  57. package/contracts/macro-integration-tests/tests/ui/oapp/fail/unknown_custom_option.stderr +5 -0
  58. package/contracts/macro-integration-tests/tests/ui/oapp/fail/wrong_key.rs +8 -0
  59. package/contracts/macro-integration-tests/tests/ui/oapp/fail/wrong_key.stderr +5 -0
  60. package/contracts/macro-integration-tests/tests/ui/oapp/pass/custom_all.rs +38 -0
  61. package/contracts/macro-integration-tests/tests/ui/oapp/pass/custom_single_trait.rs +96 -0
  62. package/contracts/macro-integration-tests/tests/ui/oapp/pass/minimal_contract.rs +64 -0
  63. package/contracts/macro-integration-tests/tests/ui/oapp/pass/struct_with_fields.rs +46 -0
  64. package/contracts/macro-integration-tests/tests/ui/ownable/fail/only_auth_missing_env.stderr +8 -0
  65. package/contracts/macro-integration-tests/tests/ui/ownable/pass/namespacing_and_imports.rs +1 -1
  66. package/contracts/macro-integration-tests/tests/ui/ownable/pass/only_auth_env_param_variants.rs +1 -1
  67. package/contracts/macro-integration-tests/tests/ui_oapp.rs +11 -0
  68. package/contracts/message-libs/message-lib-common/Cargo.toml +0 -1
  69. package/contracts/message-libs/message-lib-common/src/errors.rs +1 -1
  70. package/contracts/message-libs/treasury/Cargo.toml +0 -2
  71. package/contracts/message-libs/treasury/src/tests/treasury_tests.rs +2 -2
  72. package/contracts/message-libs/uln-302/src/tests/receive_uln302/effective_receive_uln_config.rs +2 -2
  73. package/contracts/message-libs/uln-302/src/tests/receive_uln302/set_default_receive_uln_configs.rs +2 -2
  74. package/contracts/message-libs/uln-302/src/tests/receive_uln302/verify.rs +2 -2
  75. package/contracts/message-libs/uln-302/src/tests/send_uln302/effective_executor_config.rs +2 -2
  76. package/contracts/message-libs/uln-302/src/tests/send_uln302/effective_send_uln_config.rs +2 -2
  77. package/contracts/message-libs/uln-302/src/tests/send_uln302/send.rs +7 -27
  78. package/contracts/message-libs/uln-302/src/tests/send_uln302/set_default_executor_configs.rs +2 -2
  79. package/contracts/message-libs/uln-302/src/tests/send_uln302/set_default_send_uln_configs.rs +2 -2
  80. package/contracts/oapps/counter/Cargo.toml +4 -6
  81. package/contracts/oapps/counter/integration_tests/utils.rs +19 -12
  82. package/contracts/oapps/oapp/src/errors.rs +1 -1
  83. package/contracts/oapps/oapp/src/interfaces/mod.rs +3 -0
  84. package/contracts/oapps/oapp/src/interfaces/oapp_msg_inspector.rs +47 -0
  85. package/contracts/oapps/oapp/src/lib.rs +1 -0
  86. package/contracts/oapps/oapp/src/macro_tests/test_macros.rs +4 -4
  87. package/contracts/oapps/oapp/src/oapp_core.rs +5 -5
  88. package/contracts/oapps/oapp/src/oapp_options_type3.rs +12 -4
  89. package/contracts/oapps/oapp/src/oapp_receiver.rs +14 -9
  90. package/contracts/oapps/oapp/src/tests/mod.rs +4 -4
  91. package/contracts/oapps/oapp/src/tests/{test_oapp_core.rs → oapp_core.rs} +4 -4
  92. package/contracts/oapps/oapp/src/tests/{test_oapp_options_type3.rs → oapp_options_type3.rs} +3 -4
  93. package/contracts/oapps/oapp-macros/Cargo.toml +8 -4
  94. package/contracts/oapps/oapp-macros/src/generators.rs +9 -34
  95. package/contracts/oapps/oapp-macros/src/lib.rs +3 -0
  96. package/contracts/oapps/oapp-macros/src/tests/mod.rs +2 -0
  97. package/contracts/oapps/oapp-macros/src/tests/oapp.rs +88 -0
  98. package/contracts/oapps/oapp-macros/src/tests/parse_custom_impls.rs +86 -0
  99. package/contracts/oapps/oapp-macros/src/tests/snapshots/oapp_macros__tests__oapp__snapshot_generate_oapp.snap +103 -0
  100. package/contracts/oapps/oft/integration-tests/utils.rs +28 -8
  101. package/contracts/oapps/oft/src/extensions/oft_fee.rs +136 -74
  102. package/contracts/oapps/oft/src/extensions/pausable.rs +44 -10
  103. package/contracts/oapps/oft/src/extensions/rate_limiter.rs +170 -130
  104. package/contracts/oapps/oft/src/oft.rs +19 -12
  105. package/contracts/oapps/oft/src/oft_types/lock_unlock.rs +1 -1
  106. package/contracts/oapps/oft/src/oft_types/mint_burn.rs +1 -1
  107. package/contracts/oapps/oft-core/Cargo.toml +1 -4
  108. package/contracts/oapps/oft-core/integration-tests/setup.rs +2 -2
  109. package/contracts/oapps/oft-core/integration-tests/utils.rs +21 -3
  110. package/contracts/oapps/oft-core/src/errors.rs +3 -2
  111. package/contracts/oapps/oft-core/src/events.rs +6 -0
  112. package/contracts/oapps/oft-core/src/lib.rs +1 -1
  113. package/contracts/oapps/oft-core/src/oft_core.rs +115 -60
  114. package/contracts/oapps/oft-core/src/storage.rs +7 -3
  115. package/contracts/oapps/oft-core/src/tests/mod.rs +1 -0
  116. package/contracts/oapps/oft-core/src/tests/test_decimals.rs +37 -2
  117. package/contracts/oapps/oft-core/src/tests/test_lz_receive.rs +2 -2
  118. package/contracts/oapps/oft-core/src/tests/test_msg_inspector.rs +323 -0
  119. package/contracts/oapps/oft-core/src/tests/test_send.rs +2 -2
  120. package/contracts/oapps/oft-core/src/tests/test_utils.rs +59 -14
  121. package/contracts/utils/Cargo.toml +0 -1
  122. package/contracts/utils/src/errors.rs +1 -1
  123. package/contracts/utils/src/multisig.rs +17 -8
  124. package/contracts/utils/src/ownable.rs +6 -6
  125. package/contracts/utils/src/testing_utils.rs +124 -54
  126. package/contracts/utils/src/tests/multisig.rs +12 -12
  127. package/contracts/utils/src/tests/ownable.rs +6 -6
  128. package/contracts/utils/src/tests/testing_utils.rs +50 -167
  129. package/contracts/utils/src/tests/ttl_configurable.rs +5 -5
  130. package/contracts/utils/src/tests/upgradeable.rs +1 -1
  131. package/contracts/utils/src/ttl_configurable.rs +10 -4
  132. package/contracts/utils/src/upgradeable.rs +5 -5
  133. package/contracts/workers/dvn/Cargo.toml +5 -6
  134. package/contracts/workers/dvn/src/dvn.rs +2 -12
  135. package/contracts/workers/dvn-fee-lib/Cargo.toml +1 -1
  136. package/contracts/workers/dvn-fee-lib/src/dvn_fee_lib.rs +37 -19
  137. package/contracts/workers/dvn-fee-lib/src/lib.rs +12 -2
  138. package/contracts/workers/dvn-fee-lib/src/tests/dvn_fee_lib.rs +15 -13
  139. package/contracts/workers/executor/Cargo.toml +3 -0
  140. package/contracts/workers/executor/src/executor.rs +2 -12
  141. package/contracts/workers/executor/src/lib.rs +2 -2
  142. package/contracts/workers/executor/src/tests/auth.rs +394 -0
  143. package/contracts/workers/executor/src/tests/executor.rs +410 -0
  144. package/contracts/workers/executor/src/tests/mod.rs +3 -0
  145. package/contracts/workers/executor/src/tests/setup.rs +250 -0
  146. package/contracts/workers/executor-fee-lib/Cargo.toml +5 -0
  147. package/contracts/workers/executor-fee-lib/src/executor_fee_lib.rs +1 -12
  148. package/contracts/workers/executor-fee-lib/src/lib.rs +8 -2
  149. package/contracts/workers/executor-helper/Cargo.toml +0 -1
  150. package/contracts/workers/price-feed/Cargo.toml +5 -0
  151. package/contracts/workers/price-feed/src/lib.rs +9 -4
  152. package/contracts/workers/price-feed/src/price_feed.rs +1 -11
  153. package/contracts/workers/worker/src/errors.rs +1 -1
  154. package/contracts/workers/worker/src/tests/setup.rs +1 -1
  155. package/contracts/workers/worker/src/tests/worker.rs +55 -41
  156. package/contracts/workers/worker/src/worker.rs +34 -25
  157. package/docs/error-spec.md +55 -0
  158. package/docs/layerzero-v2-on-stellar.md +447 -0
  159. package/docs/oapp-guide.md +212 -0
  160. package/docs/oft-guide.md +314 -0
  161. package/package.json +3 -3
  162. package/sdk/.turbo/turbo-test.log +260 -257
  163. package/sdk/dist/generated/bml.d.ts +3 -3
  164. package/sdk/dist/generated/bml.js +4 -4
  165. package/sdk/dist/generated/counter.d.ts +295 -295
  166. package/sdk/dist/generated/counter.js +43 -43
  167. package/sdk/dist/generated/dvn.d.ts +91 -91
  168. package/sdk/dist/generated/dvn.js +24 -24
  169. package/sdk/dist/generated/dvn_fee_lib.d.ts +92 -92
  170. package/sdk/dist/generated/dvn_fee_lib.js +25 -25
  171. package/sdk/dist/generated/endpoint.d.ts +99 -99
  172. package/sdk/dist/generated/endpoint.js +16 -16
  173. package/sdk/dist/generated/executor.d.ts +91 -91
  174. package/sdk/dist/generated/executor.js +24 -24
  175. package/sdk/dist/generated/executor_fee_lib.d.ts +92 -92
  176. package/sdk/dist/generated/executor_fee_lib.js +25 -25
  177. package/sdk/dist/generated/executor_helper.d.ts +3 -3
  178. package/sdk/dist/generated/executor_helper.js +4 -4
  179. package/sdk/dist/generated/layerzero_view.d.ts +186 -186
  180. package/sdk/dist/generated/layerzero_view.js +35 -35
  181. package/sdk/dist/generated/oft.d.ts +366 -352
  182. package/sdk/dist/generated/oft.js +74 -79
  183. package/sdk/dist/generated/price_feed.d.ts +198 -198
  184. package/sdk/dist/generated/price_feed.js +39 -39
  185. package/sdk/dist/generated/sml.d.ts +99 -99
  186. package/sdk/dist/generated/sml.js +16 -16
  187. package/sdk/dist/generated/treasury.d.ts +99 -99
  188. package/sdk/dist/generated/treasury.js +16 -16
  189. package/sdk/dist/generated/uln302.d.ts +99 -99
  190. package/sdk/dist/generated/uln302.js +16 -16
  191. package/sdk/dist/generated/upgrader.d.ts +3 -3
  192. package/sdk/dist/generated/upgrader.js +3 -3
  193. package/sdk/package.json +1 -1
  194. package/sdk/test/suites/localnet.ts +84 -20
  195. package/contracts/ERROR_SPEC.md +0 -51
  196. package/contracts/endpoint-v2/ARCHITECTURE.md +0 -233
  197. /package/contracts/oapps/oapp/src/tests/{test_oapp_receiver.rs → oapp_receiver.rs} +0 -0
  198. /package/contracts/oapps/oapp/src/tests/{test_oapp_sender.rs → oapp_sender.rs} +0 -0
@@ -1,5 +1,5 @@
1
1
  use soroban_sdk::{testutils::Address as _, Address, Bytes, BytesN, Env};
2
- use utils::testing_utils::assert_event;
2
+ use utils::testing_utils::assert_eq_event;
3
3
 
4
4
  use crate::{
5
5
  constants::MAX_COMPOSE_INDEX, endpoint_v2::EndpointV2Client, errors::EndpointError, events::LzComposeAlert,
@@ -81,7 +81,7 @@ fn test_lz_compose_alert_auth() {
81
81
  &f.reason,
82
82
  );
83
83
 
84
- assert_event(
84
+ assert_eq_event(
85
85
  env,
86
86
  &endpoint_client.address,
87
87
  LzComposeAlert {
@@ -192,7 +192,7 @@ fn test_lz_compose_alert_with_empty_data() {
192
192
  &f.reason,
193
193
  );
194
194
 
195
- assert_event(
195
+ assert_eq_event(
196
196
  env,
197
197
  &endpoint_client.address,
198
198
  LzComposeAlert {
@@ -1,5 +1,5 @@
1
1
  use soroban_sdk::{testutils::Address as _, Address, Bytes, BytesN};
2
- use utils::testing_utils::assert_event;
2
+ use utils::testing_utils::assert_eq_event;
3
3
 
4
4
  use crate::{
5
5
  constants::MAX_COMPOSE_INDEX, errors::EndpointError, events::ComposeSent, tests::endpoint_setup::setup,
@@ -85,7 +85,7 @@ fn test_send_compose_success() {
85
85
  context.send_compose_with_auth(&from, &to, &guid, index, &message);
86
86
 
87
87
  // Verify the event was published.
88
- assert_event(
88
+ assert_eq_event(
89
89
  env,
90
90
  &endpoint_client.address,
91
91
  ComposeSent { from: from.clone(), to: to.clone(), guid: guid.clone(), index, message: message.clone() },
@@ -18,7 +18,6 @@ testnet = []
18
18
  sandbox = []
19
19
 
20
20
  [dependencies]
21
- cfg-if = { workspace = true }
22
21
  soroban-sdk = { workspace = true }
23
22
  # workspace dependencies
24
23
  utils = { workspace = true }
@@ -14,9 +14,8 @@ use endpoint_v2::{LayerZeroEndpointV2Client, MessageLibManagerClient, MessagingC
14
14
  use message_lib_common::packet_codec_v1::{decode_packet_header, PacketHeader};
15
15
  use soroban_sdk::{address_payload::AddressPayload, assert_with_error, Address, Bytes, BytesN, Env};
16
16
  use uln302::ReceiveUln302Client;
17
- use utils::upgradeable::UpgradeableInternal;
18
17
 
19
- #[lz_contract(upgradeable)]
18
+ #[lz_contract(upgradeable(no_migration))]
20
19
  pub struct LayerZeroView;
21
20
 
22
21
  #[contract_impl]
@@ -213,14 +212,3 @@ impl LayerZeroView {
213
212
  }
214
213
  }
215
214
 
216
- // ============================================================================
217
- // Upgradeable Implementation
218
- // ============================================================================
219
-
220
- impl UpgradeableInternal for LayerZeroView {
221
- type MigrationData = ();
222
-
223
- fn __migrate(_env: &Env, _migration_data: &Self::MigrationData) {
224
- // No migration logic needed for initial upgrade capability
225
- }
226
- }
@@ -10,21 +10,11 @@ publish = false
10
10
  # The lib.rs provides shared testing utilities.
11
11
  doctest = false
12
12
 
13
- [dependencies]
14
- soroban-sdk = { workspace = true }
15
-
16
- # Macro crates to be tested
17
- common-macros = { workspace = true }
18
- oapp-macros = { workspace = true }
19
- # oft-macros = { workspace = true } # TODO: Add when available
20
-
21
- # Runtime libraries (for verifying generated code behavior)
22
- utils = { workspace = true }
23
- oapp = { workspace = true }
24
- # oft = { workspace = true } # TODO: Add when available
25
- endpoint-v2 = { workspace = true, features = ["library"] }
26
-
27
13
  [dev-dependencies]
28
14
  soroban-sdk = { workspace = true, features = ["testutils"] }
15
+ trybuild = { workspace = true }
16
+ common-macros = { workspace = true }
29
17
  utils = { workspace = true, features = ["testutils"] }
30
- trybuild = "1.0.114"
18
+ endpoint-v2 = { workspace = true, features = ["testutils"] }
19
+ oapp = { workspace = true }
20
+ oapp-macros = { workspace = true }
@@ -0,0 +1,48 @@
1
+ use endpoint_v2::Origin;
2
+ use oapp::oapp_receiver::LzReceiveInternal;
3
+ use oapp_macros::oapp;
4
+ use soroban_sdk::{contractimpl, symbol_short, Address, Bytes, BytesN, Env};
5
+
6
+ mod oapp_core;
7
+ mod options_type3;
8
+ mod receiver;
9
+ mod sender;
10
+
11
+ /// Shared contract used by oapp-macros runtime tests.
12
+ ///
13
+ /// Notes:
14
+ /// - `#[oapp]` expands to `#[common_macros::lz_contract]` + default trait impls for:
15
+ /// - `oapp::oapp_core::OAppCore` (contract trait)
16
+ /// - `oapp::oapp_receiver::OAppReceiver` (contract trait)
17
+ /// - `oapp::oapp_options_type3::OAppOptionsType3` (contract trait)
18
+ /// - `oapp::oapp_sender::OAppSenderInternal` (internal trait)
19
+ #[oapp]
20
+ pub struct TestOApp;
21
+
22
+ impl LzReceiveInternal for TestOApp {
23
+ fn __lz_receive(
24
+ env: &Env,
25
+ _origin: &Origin,
26
+ _guid: &BytesN<32>,
27
+ _message: &Bytes,
28
+ _extra_data: &Bytes,
29
+ _executor: &Address,
30
+ _value: i128,
31
+ ) {
32
+ // Mark that the internal handler was invoked.
33
+ env.storage().instance().set(&symbol_short!("lzr_c"), &true);
34
+ }
35
+ }
36
+
37
+ #[contractimpl]
38
+ impl TestOApp {
39
+ /// Initializes owner and stores an endpoint address for `OAppCore::endpoint`.
40
+ pub fn init(env: Env, owner: Address, endpoint: Address) {
41
+ Self::init_owner(&env, &owner);
42
+ oapp::oapp_core::OAppCoreStorage::set_endpoint(&env, &endpoint);
43
+ }
44
+
45
+ pub fn lz_receive_called(env: Env) -> bool {
46
+ env.storage().instance().get(&symbol_short!("lzr_c")).unwrap_or(false)
47
+ }
48
+ }
@@ -0,0 +1,170 @@
1
+ // Runtime tests: OAppCore behavior generated by `#[oapp]`.
2
+
3
+ use super::{TestOApp, TestOAppClient};
4
+ use oapp::oapp_core::{OAppCoreStorage, PeerSet};
5
+ use soroban_sdk::{
6
+ contract, contractimpl,
7
+ testutils::{Address as _, MockAuth, MockAuthInvoke},
8
+ xdr::{ScErrorCode, ScErrorType},
9
+ Address, BytesN, Env, Error, IntoVal,
10
+ };
11
+ use utils::testing_utils::assert_contains_event;
12
+
13
+ /// Minimal endpoint stub used to verify `OAppCore::set_delegate` forwards calls.
14
+ #[contract]
15
+ pub struct MockEndpoint;
16
+
17
+ #[contractimpl]
18
+ impl MockEndpoint {
19
+ pub fn set_delegate(env: Env, oapp: Address, new_delegate: Option<Address>) {
20
+ if let Some(d) = new_delegate {
21
+ env.storage().instance().set(&oapp, &d);
22
+ } else {
23
+ env.storage().instance().remove(&oapp);
24
+ }
25
+ }
26
+
27
+ pub fn delegate(env: Env, oapp: Address) -> Option<Address> {
28
+ env.storage().instance().get(&oapp)
29
+ }
30
+ }
31
+
32
+ #[test]
33
+ fn oapp_version_default() {
34
+ let env = Env::default();
35
+ let contract_id = env.register(TestOApp, ());
36
+ let client = TestOAppClient::new(&env, &contract_id);
37
+
38
+ // Default `OAppCore::oapp_version` should be callable without initialization.
39
+ assert_eq!(client.oapp_version(), (1u64, 1u64));
40
+ }
41
+
42
+ #[test]
43
+ fn endpoint_roundtrip() {
44
+ let env = Env::default();
45
+ let contract_id = env.register(TestOApp, ());
46
+ let client = TestOAppClient::new(&env, &contract_id);
47
+
48
+ // Before init, `endpoint()` unwraps storage and should fail.
49
+ assert!(client.try_endpoint().is_err());
50
+
51
+ let owner = Address::generate(&env);
52
+ let endpoint = Address::generate(&env);
53
+ client.init(&owner, &endpoint);
54
+
55
+ assert_eq!(client.endpoint(), endpoint);
56
+ }
57
+
58
+ #[test]
59
+ fn set_peer_requires_auth_and_updates_storage() {
60
+ let env = Env::default();
61
+ let contract_id = env.register(TestOApp, ());
62
+ let client = TestOAppClient::new(&env, &contract_id);
63
+
64
+ let owner = Address::generate(&env);
65
+ let endpoint = Address::generate(&env);
66
+ client.init(&owner, &endpoint);
67
+
68
+ let eid: u32 = 101;
69
+ let peer = Some(BytesN::<32>::from_array(&env, &[7u8; 32]));
70
+
71
+ // Peer is None when unset.
72
+ assert_eq!(client.peer(&eid), None);
73
+
74
+ // Unauthorized set should fail.
75
+ let unauthorized = client.try_set_peer(&eid, &peer);
76
+ assert_eq!(
77
+ unauthorized.unwrap_err().unwrap(),
78
+ Error::from_type_and_code(ScErrorType::Context, ScErrorCode::InvalidAction)
79
+ );
80
+
81
+ // Authorized set should succeed.
82
+ client
83
+ .mock_auths(&[MockAuth {
84
+ address: &owner,
85
+ invoke: &MockAuthInvoke {
86
+ contract: &contract_id,
87
+ fn_name: "set_peer",
88
+ args: (&eid, &peer).into_val(&env),
89
+ sub_invokes: &[],
90
+ },
91
+ }])
92
+ .set_peer(&eid, &peer);
93
+
94
+ // Assert event before any other contract call (Soroban events are per-call).
95
+ assert_contains_event(&env, &contract_id, PeerSet { eid, peer: peer.clone() });
96
+
97
+ // Verify storage without issuing another contract call (so we don't clobber event log).
98
+ env.as_contract(&contract_id, || {
99
+ assert_eq!(OAppCoreStorage::peer(&env, eid), peer.clone());
100
+ });
101
+
102
+ // Remove peer by setting None.
103
+ let none: Option<BytesN<32>> = None;
104
+ env.mock_auths(&[MockAuth {
105
+ address: &owner,
106
+ invoke: &MockAuthInvoke {
107
+ contract: &contract_id,
108
+ fn_name: "set_peer",
109
+ args: (&eid, &none).into_val(&env),
110
+ sub_invokes: &[],
111
+ },
112
+ }]);
113
+ client.set_peer(&eid, &none);
114
+ assert_contains_event(&env, &contract_id, PeerSet { eid, peer: None });
115
+ env.as_contract(&contract_id, || {
116
+ assert_eq!(OAppCoreStorage::peer(&env, eid), None);
117
+ });
118
+ }
119
+
120
+ #[test]
121
+ fn set_delegate_requires_auth_and_updates_endpoint() {
122
+ let env = Env::default();
123
+ let contract_id = env.register(TestOApp, ());
124
+ let client = TestOAppClient::new(&env, &contract_id);
125
+
126
+ let endpoint_id = env.register(MockEndpoint, ());
127
+ let endpoint_client = MockEndpointClient::new(&env, &endpoint_id);
128
+
129
+ let owner = Address::generate(&env);
130
+ client.init(&owner, &endpoint_id);
131
+
132
+ // Unauthorized set should fail.
133
+ let delegate = Some(Address::generate(&env));
134
+ let unauthorized = client.try_set_delegate(&delegate);
135
+ assert_eq!(
136
+ unauthorized.unwrap_err().unwrap(),
137
+ Error::from_type_and_code(ScErrorType::Context, ScErrorCode::InvalidAction)
138
+ );
139
+
140
+ // Authorized set should succeed and forward to the endpoint.
141
+ client
142
+ .mock_auths(&[MockAuth {
143
+ address: &owner,
144
+ invoke: &MockAuthInvoke {
145
+ contract: &contract_id,
146
+ fn_name: "set_delegate",
147
+ args: (&delegate,).into_val(&env),
148
+ sub_invokes: &[],
149
+ },
150
+ }])
151
+ .set_delegate(&delegate);
152
+
153
+ assert_eq!(endpoint_client.delegate(&contract_id), delegate);
154
+
155
+ // Authorized removal should clear the endpoint delegate.
156
+ let none: Option<Address> = None;
157
+ client
158
+ .mock_auths(&[MockAuth {
159
+ address: &owner,
160
+ invoke: &MockAuthInvoke {
161
+ contract: &contract_id,
162
+ fn_name: "set_delegate",
163
+ args: (&none,).into_val(&env),
164
+ sub_invokes: &[],
165
+ },
166
+ }])
167
+ .set_delegate(&none);
168
+
169
+ assert_eq!(endpoint_client.delegate(&contract_id), None);
170
+ }
@@ -0,0 +1,154 @@
1
+ // Runtime tests: OAppOptionsType3 defaults generated by `#[oapp]`.
2
+
3
+ use super::{TestOApp, TestOAppClient};
4
+ use oapp::errors::OAppError;
5
+ use oapp::oapp_options_type3::{EnforcedOptionParam, EnforcedOptionSet};
6
+ use soroban_sdk::{
7
+ testutils::{Address as _, MockAuth, MockAuthInvoke},
8
+ vec, Address, Bytes, Env, IntoVal,
9
+ };
10
+ use utils::testing_utils::assert_contains_event;
11
+
12
+ const OPTION_TYPE_3: u16 = 3;
13
+ const REMOTE_EID_1: u32 = 100;
14
+ const MSG_TYPE_SEND: u32 = 1;
15
+ const MSG_TYPE_RECEIVE: u32 = 2;
16
+
17
+ fn create_valid_options(env: &Env, data: &[u8]) -> Bytes {
18
+ let mut buffer = Bytes::from_array(env, &OPTION_TYPE_3.to_be_bytes());
19
+ buffer.extend_from_slice(data);
20
+ buffer
21
+ }
22
+
23
+ #[test]
24
+ fn enforced_options_lifecycle_and_auth() {
25
+ let env = Env::default();
26
+ let contract_id = env.register(TestOApp, ());
27
+ let client = TestOAppClient::new(&env, &contract_id);
28
+
29
+ let owner = Address::generate(&env);
30
+ client.init(&owner, &Address::generate(&env));
31
+
32
+ // Unset returns empty bytes (storage default).
33
+ assert_eq!(client.enforced_options(&999, &999), Bytes::new(&env));
34
+
35
+ let enforced_1 = create_valid_options(&env, &[1, 2, 3, 4]);
36
+ let enforced_2 = create_valid_options(&env, &[5, 6, 7, 8]);
37
+ let params = vec![
38
+ &env,
39
+ EnforcedOptionParam { eid: REMOTE_EID_1, msg_type: MSG_TYPE_SEND, options: enforced_1.clone() },
40
+ EnforcedOptionParam { eid: REMOTE_EID_1, msg_type: MSG_TYPE_RECEIVE, options: enforced_2.clone() },
41
+ ];
42
+
43
+ // Unauthorized set should fail (only_auth).
44
+ assert!(client.try_set_enforced_options(&params).is_err());
45
+
46
+ // Non-owner authorized should also fail.
47
+ let non_owner = Address::generate(&env);
48
+ env.mock_auths(&[MockAuth {
49
+ address: &non_owner,
50
+ invoke: &MockAuthInvoke {
51
+ contract: &contract_id,
52
+ fn_name: "set_enforced_options",
53
+ args: (&params,).into_val(&env),
54
+ sub_invokes: &[],
55
+ },
56
+ }]);
57
+ assert!(client.try_set_enforced_options(&params).is_err());
58
+
59
+ // Owner-authorized set should succeed.
60
+ env.mock_auths(&[MockAuth {
61
+ address: &owner,
62
+ invoke: &MockAuthInvoke {
63
+ contract: &contract_id,
64
+ fn_name: "set_enforced_options",
65
+ args: (&params,).into_val(&env),
66
+ sub_invokes: &[],
67
+ },
68
+ }]);
69
+ client.set_enforced_options(&params);
70
+
71
+ assert_contains_event(&env, &contract_id, EnforcedOptionSet { enforced_option_params: params.clone() });
72
+
73
+ assert_eq!(client.enforced_options(&REMOTE_EID_1, &MSG_TYPE_SEND), enforced_1);
74
+ assert_eq!(client.enforced_options(&REMOTE_EID_1, &MSG_TYPE_RECEIVE), enforced_2);
75
+ }
76
+
77
+ #[test]
78
+ fn set_enforced_options_rejects_invalid_option_type() {
79
+ let env = Env::default();
80
+ let contract_id = env.register(TestOApp, ());
81
+ let client = TestOAppClient::new(&env, &contract_id);
82
+
83
+ let owner = Address::generate(&env);
84
+ client.init(&owner, &Address::generate(&env));
85
+
86
+ // wrong type header (not 3)
87
+ let mut invalid = Bytes::from_array(&env, &(4u16).to_be_bytes());
88
+ invalid.extend_from_slice(&[1, 2, 3]);
89
+
90
+ let params = vec![&env, EnforcedOptionParam { eid: REMOTE_EID_1, msg_type: MSG_TYPE_SEND, options: invalid }];
91
+
92
+ env.mock_auths(&[MockAuth {
93
+ address: &owner,
94
+ invoke: &MockAuthInvoke {
95
+ contract: &contract_id,
96
+ fn_name: "set_enforced_options",
97
+ args: (&params,).into_val(&env),
98
+ sub_invokes: &[],
99
+ },
100
+ }]);
101
+ let result = client.try_set_enforced_options(&params);
102
+ assert_eq!(result.err().unwrap().ok().unwrap(), OAppError::InvalidOptions.into());
103
+ }
104
+
105
+ #[test]
106
+ fn combine_options_behavior_and_validation() {
107
+ let env = Env::default();
108
+ let contract_id = env.register(TestOApp, ());
109
+ let client = TestOAppClient::new(&env, &contract_id);
110
+
111
+ let owner = Address::generate(&env);
112
+ client.init(&owner, &Address::generate(&env));
113
+
114
+ // No enforced => returns extra (including empty).
115
+ let extra_only = create_valid_options(&env, &[9, 10, 11]);
116
+ assert_eq!(client.combine_options(&REMOTE_EID_1, &MSG_TYPE_SEND, &extra_only), extra_only);
117
+ let empty_extra = Bytes::new(&env);
118
+ assert_eq!(client.combine_options(&REMOTE_EID_1, &MSG_TYPE_SEND, &empty_extra), empty_extra);
119
+
120
+ // Set enforced for (eid, msg_type).
121
+ let enforced = create_valid_options(&env, &[1, 2, 3, 4]);
122
+ let params =
123
+ vec![&env, EnforcedOptionParam { eid: REMOTE_EID_1, msg_type: MSG_TYPE_SEND, options: enforced.clone() }];
124
+ env.mock_auths(&[MockAuth {
125
+ address: &owner,
126
+ invoke: &MockAuthInvoke {
127
+ contract: &contract_id,
128
+ fn_name: "set_enforced_options",
129
+ args: (&params,).into_val(&env),
130
+ sub_invokes: &[],
131
+ },
132
+ }]);
133
+ client.set_enforced_options(&params);
134
+
135
+ // Enforced present: empty extra => enforced.
136
+ assert_eq!(client.combine_options(&REMOTE_EID_1, &MSG_TYPE_SEND, &Bytes::new(&env)), enforced.clone());
137
+
138
+ // Both present: enforced + extra(without its 2-byte header).
139
+ let extra = create_valid_options(&env, &[4, 5, 6]);
140
+ let combined = client.combine_options(&REMOTE_EID_1, &MSG_TYPE_SEND, &extra);
141
+ let expected = create_valid_options(&env, &[1, 2, 3, 4, 4, 5, 6]);
142
+ assert_eq!(combined, expected);
143
+
144
+ // Extra has wrong type (len >= 2) => InvalidOptions.
145
+ let mut extra_invalid = Bytes::from_array(&env, &(4u16).to_be_bytes());
146
+ extra_invalid.extend_from_slice(&[9, 9, 9]);
147
+ let bad = client.try_combine_options(&REMOTE_EID_1, &MSG_TYPE_SEND, &extra_invalid);
148
+ assert_eq!(bad.err().unwrap().ok().unwrap(), OAppError::InvalidOptions.into());
149
+
150
+ // Extra non-empty but too short (<2) => InvalidOptions.
151
+ let too_short = Bytes::from_array(&env, &[1u8]);
152
+ let bad2 = client.try_combine_options(&REMOTE_EID_1, &MSG_TYPE_SEND, &too_short);
153
+ assert_eq!(bad2.err().unwrap().ok().unwrap(), OAppError::InvalidOptions.into());
154
+ }