@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
@@ -1,44 +0,0 @@
1
- # Stellar LayerZero Protocol - Error Code Specification
2
-
3
- This document defines the error code allocation strategy for the Stellar LayerZero contracts.
4
-
5
- ## Purpose
6
-
7
- Each library has a unique error code range to:
8
-
9
- - **Prevent collisions**: Avoid error code conflicts between different libraries
10
- - **Enable traceability**: Quickly identify which library an error originated from based on its code
11
- - **Simplify debugging**: Error codes are globally unique, making it easier to track and diagnose issues
12
-
13
- ## Allocation Rules
14
-
15
- - **Library allocation**: Each library is allocated a 100-unit block (e.g., 1000-1099, 1100-1199). Total errors in one library should not exceed 100.
16
- - **Sub-range allocation**: Each error type within a library is allocated a 10-unit block. Example from `utils` (1000-1099):
17
-
18
- - BufferReaderError: 1000-1009
19
- - BufferWriterError: 1010-1019
20
- - TtlConfigurableError: 1020-1029
21
- - OwnableError: 1030-1039
22
- - BytesExtError: 1040-1049
23
- - UpgradeableError: 1050-1059
24
- - MultisigError: 1060-1069
25
-
26
- If an error type exceeds 10 errors (e.g., 12 errors), it extends into the next block but the following error type should start at the next 10-unit boundary (e.g., if errors are 1000-1011, next sub-range starts at 1020).
27
-
28
- - **Auto-increment**: Within each error enum, values auto-increment from the starting value.
29
-
30
- ## Error Code Ranges
31
-
32
- | Range | Category | Library | Description |
33
- | ----------- | --------------- | ------------------ | ------------------------------------------------------------ |
34
- | 1 - 999 | Contract Errors | - | Application-specific contract errors (auto-increment from 1) |
35
- | 1000 - 1099 | Protocol Lib | utils | `utils/src/errors.rs` |
36
- | 1100 - 1199 | Protocol Lib | message-lib-common | `message-libs/message-lib-common/src/errors.rs` |
37
- | 1200 - 1299 | Protocol Lib | worker | `workers/worker/src/errors.rs` |
38
- | 1300 - 1999 | Protocol Lib | (reserved) | Future protocol libs |
39
- | 2000 - 2099 | OApp Lib | oapp | `oapps/oapp/src/errors.rs` |
40
- | 2100 - 2999 | OApp Lib | (reserved) | Future OApp libs |
41
- | 3000 - 3099 | OFT Lib | oft-core | `oapps/oft-core/src/errors.rs` |
42
- | 3100 - 3999 | OFT Lib | (reserved) | Future OFT libs |
43
-
44
- ---
@@ -1,233 +0,0 @@
1
- # EndpointV2 Architecture
2
-
3
- ## Overview
4
-
5
- **EndpointV2** is the core Soroban contract for LayerZero's cross-chain messaging protocol on Stellar. It serves as the central hub for omnichain applications (OApps) to send and receive cross-chain messages using pluggable message libraries.
6
-
7
- **Key Architecture Principles:**
8
-
9
- - **Interfaces exported as library** - External contracts depend on trait definitions only
10
- - **Contract entry point** - `endpoint_v2.rs` implements all interfaces
11
- - **Internal modules** - Separate files for business logic implementation
12
- - **Centralized resources** - Unified `storage.rs`, `errors.rs`, `events.rs`
13
-
14
- ---
15
-
16
- ## Project Structure
17
-
18
- ```
19
- endpoint-v2/
20
- ├── Cargo.toml # Package configuration with "library" feature
21
- ├── ARCHITECTURE.md # This file - architecture documentation
22
-
23
- ├── src/
24
-
25
- │ ├── interfaces/ # Public interface definitions (library exports)
26
- │ │ ├── mod.rs
27
- │ │ ├── layerzero_endpoint_v2.rs # Core endpoint interface
28
- │ │ ├── layerzero_composer.rs # Interface for Composer
29
- │ │ ├── layerzero_receiver.rs # Interface for OApp (receive)
30
- │ │ ├── message_lib.rs # Interface for MessageLib
31
- │ │ ├── message_lib_manager.rs # Library management interface of EndpointV2
32
- │ │ ├── send_lib.rs # Interface for SendLib (extends MessageLib)
33
- │ │ ├── messaging_channel.rs # Channel operations interface of EndpointV2
34
- │ │ └── messaging_composer.rs # Compose operations interface of EndpointV2
35
- | |
36
- │ ├── lib.rs # Module exports & conditional compilation
37
- │ ├── endpoint_v2.rs # Main contract implementation
38
- │ ├── message_lib_manager.rs # Internal: Library registration & management
39
- │ ├── messaging_channel.rs # Internal: Channel logic (nonce, payload)
40
- │ ├── messaging_composer.rs # Internal: Compose queue management
41
- │ │
42
- │ ├── util.rs # Public: Utility functions (GUID, payload, keccak256)
43
- │ ├── storage.rs # Centralized storage management
44
- │ ├── errors.rs # Centralized error definitions
45
- │ ├── events.rs # Centralized event definitions
46
- │ │
47
- │ └── tests/ # Comprehensive test suite
48
-
49
- ```
50
-
51
- ---
52
-
53
- ## Design Principles
54
-
55
- ### 1. Interfaces as Library Exports
56
-
57
- The `interfaces/` directory contains Soroban trait definitions exported as a library for external contracts. Controlled by the `library` feature in `Cargo.toml`.
58
-
59
- ```rust
60
- // lib.rs - conditional compilation
61
- cfg_if::cfg_if! {
62
- if #[cfg(any(not(feature = "library"), feature = "default"))] {
63
- mod endpoint_v2; // Only included when building contract
64
- mod errors;
65
- mod events;
66
- mod storage;
67
-
68
- pub use endpoint_v2::{EndpointV2, EndpointV2Client};
69
- }
70
- }
71
- ```
72
-
73
- **Usage Example:**
74
-
75
- ```rust
76
- // In a MessageLib contract
77
- use endpoint_v2::{EndpointV2Client, OutboundPacket};
78
-
79
- let endpoint = EndpointV2Client::new(&env, &endpoint_address);
80
- endpoint.verify(&origin, &receiver, &payload_hash);
81
- ```
82
-
83
- **Interface Categories:**
84
-
85
- - **For OApps**: `ILayerZeroReceiver`, `ILayerZeroComposer`
86
- - **For MessageLibs**: `IMessageLib`, `ISendLib` (includes `OutboundPacket`, `FeeRecipient`)
87
- - **For All**: `ILayerZeroEndpointV2` (composes all sub-interfaces)
88
- - **Utilities**: `util::compute_guid()`, `util::build_payload()`, `util::keccak256()`
89
-
90
- ### 2. Contract Entry Point (`endpoint_v2.rs`)
91
-
92
- The main Soroban contract that implements all interfaces and delegates to internal modules:
93
-
94
- ```rust
95
- #[contract]
96
- pub struct EndpointV2;
97
-
98
- #[contract_impl]
99
- impl EndpointV2 {
100
- pub fn __constructor(env: &Env, eid: u32, native_token: &Address, owner: &Address) {
101
- storage::EndpointData::set_eid(env, eid);
102
- storage::EndpointData::set_native_token(env, native_token);
103
- ownable::set_owner(env, owner);
104
- }
105
-
106
- pub fn set_ttl_configs(env: &Env, ...) {
107
- ownable::require_owner_auth(env);
108
- // Configure TTL settings for storage
109
- }
110
- }
111
-
112
- #[contract_impl]
113
- impl ILayerZeroEndpointV2 for EndpointV2 {
114
- fn send(env: &Env, sender: &Address, params: &MessagingParams, ...) -> MessagingReceipt {
115
- sender.require_auth();
116
- // Send cross-chain message via SendLib
117
- }
118
-
119
- fn lz_receive(env: &Env, origin: &Origin, receiver: &Address, ...) {
120
- // Verify payload hash and deliver to OApp
121
- let receiver_client = LayerZeroReceiverClient::new(env, receiver);
122
- receiver_client.lz_receive(...);
123
- }
124
- }
125
-
126
- #[contract_impl]
127
- impl Ownable for EndpointV2 {
128
- // Ownership management
129
- }
130
- ```
131
-
132
- **Implements:** `ILayerZeroEndpointV2` (which includes `IMessageLibManager`, `IMessagingChannel`, `IMessagingComposer`), `Ownable`
133
-
134
- ### 3. Internal Implementation Modules
135
-
136
- Internal modules provide business logic implementation for `endpoint_v2.rs`:
137
-
138
- | Module | Purpose |
139
- | ---------------------------- | -------------------------------------------------------------------------------------------------------- |
140
- | **`message_lib_manager.rs`** | Library registration, selection, and configuration. Tracks default/per-OApp libraries per EID. |
141
- | **`messaging_channel.rs`** | Nonce tracking, payload hash storage/verification, message state transitions (verify → receive → clear). |
142
- | **`messaging_composer.rs`** | Manages compose message queues for multi-stage execution between OApp and Composers. |
143
- | **`util.rs`** | Public utilities: `compute_guid()`, `build_payload()`, `keccak256()` for message processing. |
144
-
145
- ### 4. Centralized Resource Management
146
-
147
- | Module | Purpose | Example |
148
- | ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
149
- | **`storage.rs`** | Type-safe storage with `#[storage]` derive macro. Organized into: `EndpointData`, `MessagingChannelData`, `MessageLibManagerData`, `MessagingComposerData`. | `EndpointData::eid(env)`, `MessagingChannelData::outbound_nonce(env, sender, dst_eid, receiver)` |
150
- | **`errors.rs`** | All error codes using `#[contracterror]`. 29 error types including validation, authorization, state, and configuration errors. | `InvalidNonce = 3`, `Unauthorized = 10`, `InsufficientNativeFee = 27` |
151
- | **`events.rs`** | All events using `#[contractevent]`. Includes config, messaging, library, and compose events. | `PacketSent`, `PacketVerified`, `LibraryRegistered` |
152
-
153
- ---
154
-
155
- ## Key Patterns
156
-
157
- **1. Interface Composition**
158
-
159
- ```rust
160
- pub trait ILayerZeroEndpointV2:
161
- IMessageLibManager + IMessagingChannel + IMessagingComposer
162
- {
163
- fn quote(env: &Env, sender: &Address, params: &MessagingParams) -> MessagingFee;
164
- fn send(env: &Env, sender: &Address, params: &MessagingParams, refund_address: &Address) -> MessagingReceipt;
165
- fn lz_receive(env: &Env, origin: &Origin, receiver: &Address, guid: &BytesN<32>, message: &Bytes, extra_data: &Bytes);
166
- // ... more methods
167
- }
168
- ```
169
-
170
- Each sub-interface handles one domain, enabling modularity and clear separation of concerns. Ownership is handled through the `Ownable` trait from the `utils` crate.
171
-
172
- **2. Client Generation**
173
-
174
- ```rust
175
- #[contractclient(name = "LayerZeroReceiverClient")]
176
- pub trait ILayerZeroReceiver {
177
- fn lz_receive(env: &Env, origin: &Origin, guid: &BytesN<32>, message: &Bytes, extra_data: &Bytes);
178
- }
179
-
180
- // Usage: type-safe cross-contract calls
181
- let receiver = LayerZeroReceiverClient::new(&env, &receiver_address);
182
- receiver.lz_receive(&origin, &guid, &message, &extra_data);
183
- ```
184
-
185
- The `#[contractclient]` macro automatically generates type-safe client wrappers for cross-contract calls.
186
-
187
- ---
188
-
189
- ## Message Flows
190
-
191
- ### Sending
192
-
193
- ```
194
- OApp → EndpointV2.send(sender, params, refund_address)
195
-
196
- MessageLibManager.get_send_library(sender, dst_eid)
197
-
198
- MessagingChannel.outbound_nonce++ (create OutboundPacket)
199
-
200
- SendLib.send(packet, options, pay_in_zro) → Returns (Vec<FeeRecipient>, encoded_packet)
201
-
202
- Pay fees (native or ZRO) to fee recipients
203
-
204
- Emit PacketSent event
205
-
206
- Return MessagingReceipt { guid, nonce, fee }
207
- ```
208
-
209
- ### Receiving
210
-
211
- ```
212
- Off-chain Verifier → EndpointV2.verify(origin, receiver, payload_hash)
213
-
214
- Validate library is registered receive lib
215
-
216
- MessagingChannel.inbound(receiver, origin, payload_hash) → Store payload hash
217
-
218
- Emit PacketVerified event
219
-
220
- Later: Executor → OApp.lz_receive(origin, guid, message, extra_data)
221
-
222
- OApp executes business logic
223
-
224
- OApp → EndpointV2.clear(caller, origin, receiver, guid, message)
225
-
226
- Validate caller is OApp or its delegate (require_oapp_auth)
227
-
228
- Validate payload hash matches keccak256(guid || message)
229
-
230
- Clear payload hash from storage
231
-
232
- Emit PacketDelivered event
233
- ```
@@ -1,175 +0,0 @@
1
- use crate::{self as oapp, oapp_core::PeerSet, oapp_receiver::LzReceiveInternal};
2
- use endpoint_v2::Origin;
3
- use soroban_sdk::{
4
- contract, contractimpl,
5
- testutils::{Address as _, MockAuth, MockAuthInvoke},
6
- Address, Bytes, BytesN, Env, IntoVal,
7
- };
8
- use utils::testing_utils::assert_event;
9
-
10
- #[contract]
11
- pub struct DummyEndpoint;
12
-
13
- #[contractimpl]
14
- impl DummyEndpoint {
15
- pub fn set_delegate(_env: Env, _oapp: &Address, _delegate: &Option<Address>) {
16
- // do nothing
17
- }
18
- }
19
-
20
- #[oapp_macros::oapp]
21
- pub struct DummyOApp;
22
-
23
- impl LzReceiveInternal for DummyOApp {
24
- fn __lz_receive(
25
- _env: &Env,
26
- _origin: &Origin,
27
- _guid: &BytesN<32>,
28
- _message: &Bytes,
29
- _extra_data: &Bytes,
30
- _executor: &Address,
31
- _value: i128,
32
- ) {
33
- // Not used in core tests
34
- }
35
- }
36
-
37
- #[contractimpl]
38
- impl DummyOApp {
39
- pub fn __constructor(env: &Env, owner: &Address, endpoint: &Address) {
40
- oapp::oapp_core::initialize_oapp::<Self>(env, owner, endpoint, &None);
41
- }
42
- }
43
-
44
- const REMOTE_EID: u32 = 100;
45
- const UNSET_EID: u32 = 999;
46
-
47
- struct TestSetup<'a> {
48
- env: Env,
49
- owner: Address,
50
- endpoint: Address,
51
- oapp_client: DummyOAppClient<'a>,
52
- }
53
-
54
- fn setup<'a>() -> TestSetup<'a> {
55
- let env = Env::default();
56
-
57
- let owner = Address::generate(&env);
58
- soroban_sdk::log!(&env, "owner: {}", owner);
59
- let endpoint = env.register(DummyEndpoint, ());
60
- soroban_sdk::log!(&env, "endpoint: {}", endpoint);
61
- let oapp = env.register(DummyOApp, (&owner, &endpoint));
62
- soroban_sdk::log!(&env, "oapp: {}", oapp);
63
- let oapp_client = DummyOAppClient::new(&env, &oapp);
64
- TestSetup { env, owner, endpoint, oapp_client }
65
- }
66
-
67
- #[test]
68
- fn test_set_peer() {
69
- let TestSetup { env, owner, oapp_client, .. } = setup();
70
-
71
- let test_peer: BytesN<32> = BytesN::from_array(&env, &[33; 32]);
72
- let test_peer_option = Some(test_peer.clone());
73
- env.mock_auths(&[MockAuth {
74
- address: &owner,
75
- invoke: &MockAuthInvoke {
76
- contract: &oapp_client.address,
77
- fn_name: "set_peer",
78
- args: (&REMOTE_EID, &test_peer_option).into_val(&env),
79
- sub_invokes: &[],
80
- },
81
- }]);
82
- oapp_client.set_peer(&REMOTE_EID, &test_peer_option);
83
-
84
- // assert event
85
- assert_event(&env, &oapp_client.address, PeerSet { eid: REMOTE_EID, peer: Some(test_peer.clone()) });
86
-
87
- // Test getting peer for set eid
88
- let retrieved_peer = oapp_client.peer(&REMOTE_EID);
89
- assert_eq!(Some(test_peer), retrieved_peer);
90
-
91
- // Test getting peer for unset eid
92
- let retrieved_peer = oapp_client.peer(&UNSET_EID);
93
- assert_eq!(None, retrieved_peer);
94
- }
95
-
96
- #[test]
97
- #[should_panic(expected = "HostError: Error(Auth, InvalidAction)")]
98
- fn test_set_peer_unauthorized() {
99
- let TestSetup { env, oapp_client, .. } = setup();
100
-
101
- let test_peer: BytesN<32> = BytesN::from_array(&env, &[33; 32]);
102
- oapp_client.set_peer(&REMOTE_EID, &Some(test_peer));
103
- }
104
-
105
- #[test]
106
- fn test_get_peer_success() {
107
- let TestSetup { env, oapp_client, .. } = setup();
108
- env.mock_all_auths();
109
-
110
- let test_peer: BytesN<32> = BytesN::from_array(&env, &[1; 32]);
111
- oapp_client.set_peer(&REMOTE_EID, &Some(test_peer.clone()));
112
-
113
- let retrieved_peer = oapp_client.peer(&REMOTE_EID);
114
- assert_eq!(Some(test_peer), retrieved_peer);
115
- }
116
-
117
- #[test]
118
- fn test_get_peer_returns_none_for_unset_eid() {
119
- let TestSetup { oapp_client, .. } = setup();
120
-
121
- let result = oapp_client.peer(&UNSET_EID);
122
- assert_eq!(result, None);
123
- }
124
-
125
- #[test]
126
- fn test_update_peer() {
127
- let TestSetup { env, oapp_client, .. } = setup();
128
- env.mock_all_auths();
129
-
130
- // Set initial peer
131
- let initial_peer: BytesN<32> = BytesN::from_array(&env, &[1; 32]);
132
- oapp_client.set_peer(&REMOTE_EID, &Some(initial_peer));
133
-
134
- // Update to new peer
135
- let updated_peer: BytesN<32> = BytesN::from_array(&env, &[2; 32]);
136
- oapp_client.set_peer(&REMOTE_EID, &Some(updated_peer.clone()));
137
-
138
- let retrieved_peer = oapp_client.peer(&REMOTE_EID);
139
- assert_eq!(Some(updated_peer), retrieved_peer);
140
- }
141
-
142
- #[test]
143
- fn test_set_delegate() {
144
- let TestSetup { env, owner, oapp_client, .. } = setup();
145
-
146
- let delegate = Address::generate(&env);
147
- let delegate_option = Some(delegate.clone());
148
- env.mock_auths(&[MockAuth {
149
- address: &owner,
150
- invoke: &MockAuthInvoke {
151
- contract: &oapp_client.address,
152
- fn_name: "set_delegate",
153
- args: (&delegate_option,).into_val(&env),
154
- sub_invokes: &[],
155
- },
156
- }]);
157
- oapp_client.set_delegate(&delegate_option);
158
- }
159
-
160
- #[test]
161
- #[should_panic(expected = "HostError: Error(Auth, InvalidAction)")]
162
- fn test_set_delegate_unauthorized() {
163
- let TestSetup { env, oapp_client, .. } = setup();
164
-
165
- let delegate = Address::generate(&env);
166
- oapp_client.set_delegate(&Some(delegate));
167
- }
168
-
169
- #[test]
170
- fn test_get_endpoint() {
171
- let TestSetup { endpoint, oapp_client, .. } = setup();
172
-
173
- let retrieved_endpoint = oapp_client.endpoint();
174
- assert_eq!(endpoint, retrieved_endpoint);
175
- }
@@ -1,212 +0,0 @@
1
- use crate::{
2
- self as oapp,
3
- oapp_core::OAppCore,
4
- oapp_options_type3::{EnforcedOptionParam, EnforcedOptionSet},
5
- oapp_receiver::{LzReceiveInternal, OAppReceiver},
6
- };
7
- use common_macros::contract_impl;
8
- use endpoint_v2::Origin;
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_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
- #[test]
87
- fn test_set_and_get_enforced_options() {
88
- let TestSetup { env, owner, oapp_client, .. } = setup();
89
-
90
- // Create enforced options for different eid/msg_type combinations
91
- let options1 = create_valid_options(&env, &[1, 2, 3, 4]);
92
- let options2 = create_valid_options(&env, &[5, 6, 7, 8]);
93
-
94
- let enforced_params = vec![
95
- &env,
96
- EnforcedOptionParam { eid: REMOTE_EID_1, msg_type: MSG_TYPE_SEND, options: options1.clone() },
97
- EnforcedOptionParam { eid: REMOTE_EID_2, msg_type: MSG_TYPE_RECEIVE, options: options2.clone() },
98
- ];
99
- env.mock_auths(&[MockAuth {
100
- address: &owner,
101
- invoke: &MockAuthInvoke {
102
- contract: &oapp_client.address,
103
- fn_name: "set_enforced_options",
104
- args: (&enforced_params,).into_val(&env),
105
- sub_invokes: &[],
106
- },
107
- }]);
108
-
109
- oapp_client.set_enforced_options(&enforced_params);
110
-
111
- // assert events
112
- assert_event(&env, &oapp_client.address, EnforcedOptionSet { enforced_option_params: enforced_params.clone() });
113
-
114
- // Verify options were set correctly
115
- let retrieved1 = oapp_client.enforced_options(&REMOTE_EID_1, &MSG_TYPE_SEND);
116
- assert_eq!(retrieved1, options1);
117
-
118
- let retrieved2 = oapp_client.enforced_options(&REMOTE_EID_2, &MSG_TYPE_RECEIVE);
119
- assert_eq!(retrieved2, options2);
120
- }
121
-
122
- #[test]
123
- #[should_panic(expected = "HostError: Error(Auth, InvalidAction)")]
124
- fn test_set_enforced_options_unauthorized() {
125
- let TestSetup { env, oapp_client, .. } = setup();
126
-
127
- let options = create_valid_options(&env, &[1, 2, 3, 4]);
128
- let enforced_params =
129
- vec![&env, EnforcedOptionParam { eid: REMOTE_EID_1, msg_type: MSG_TYPE_SEND, options: options.clone() }];
130
- oapp_client.set_enforced_options(&enforced_params);
131
- }
132
-
133
- #[test]
134
- fn test_combine_options_with_empty_enforced() {
135
- let TestSetup { env, oapp_client, .. } = setup();
136
-
137
- let extra_options = create_valid_options(&env, &[9, 10, 11]);
138
- // When no enforced options are set, should return extra options
139
- let combined = oapp_client.combine_options(&REMOTE_EID_1, &MSG_TYPE_SEND, &extra_options);
140
- assert_eq!(combined, extra_options);
141
- }
142
-
143
- #[test]
144
- fn test_combine_options_with_empty_extra() {
145
- let TestSetup { env, oapp_client, .. } = setup();
146
-
147
- // This test now simply validates that empty extra options return empty result
148
- // when no enforced options are set
149
- let empty_extra = Bytes::new(&env);
150
- let combined = oapp_client.combine_options(&REMOTE_EID_1, &MSG_TYPE_SEND, &empty_extra);
151
- assert_eq!(combined, empty_extra);
152
- }
153
-
154
- #[test]
155
- fn test_combine_options_both_present() {
156
- let TestSetup { env, oapp_client, .. } = setup();
157
- env.mock_all_auths();
158
-
159
- let enforced = create_valid_options(&env, &[1, 2, 3]);
160
- oapp_client.set_enforced_options(&vec![
161
- &env,
162
- EnforcedOptionParam { eid: REMOTE_EID_1, msg_type: MSG_TYPE_SEND, options: enforced.clone() },
163
- ]);
164
-
165
- let extra = create_valid_options(&env, &[4, 5, 6]);
166
- let combined = oapp_client.combine_options(&REMOTE_EID_1, &MSG_TYPE_SEND, &extra);
167
-
168
- let mut expected_combined = enforced;
169
- expected_combined.append(&extra.slice(2..));
170
-
171
- // Should return extra options when no enforced options exist
172
- assert_eq!(combined, expected_combined);
173
- }
174
-
175
- #[test]
176
- fn test_update_enforced_options() {
177
- let TestSetup { env, oapp_client, .. } = setup();
178
- env.mock_all_auths();
179
-
180
- // Set initial options
181
- let initial_options = create_valid_options(&env, &[1, 2, 3]);
182
- let params = vec![
183
- &env,
184
- EnforcedOptionParam { eid: REMOTE_EID_1, msg_type: MSG_TYPE_SEND, options: initial_options.clone() },
185
- ];
186
- oapp_client.set_enforced_options(&params);
187
-
188
- // Verify initial options
189
- let retrieved = oapp_client.enforced_options(&REMOTE_EID_1, &MSG_TYPE_SEND);
190
- assert_eq!(retrieved, initial_options);
191
-
192
- // Update with new options
193
- let updated_options = create_valid_options(&env, &[9, 8, 7, 6, 5]);
194
- let update_params = vec![
195
- &env,
196
- EnforcedOptionParam { eid: REMOTE_EID_1, msg_type: MSG_TYPE_SEND, options: updated_options.clone() },
197
- ];
198
- oapp_client.set_enforced_options(&update_params);
199
-
200
- // Verify options were updated
201
- let retrieved_after_update = oapp_client.enforced_options(&REMOTE_EID_1, &MSG_TYPE_SEND);
202
- assert_eq!(retrieved_after_update, updated_options);
203
- }
204
-
205
- #[test]
206
- fn test_get_enforced_options_for_unset_combination() {
207
- let TestSetup { env, oapp_client, .. } = setup();
208
-
209
- // Try to get options for an eid/msg_type that hasn't been set
210
- let result = oapp_client.enforced_options(&999, &999);
211
- assert_eq!(result, Bytes::new(&env));
212
- }