@layerzerolabs/protocol-stellar-v2 0.2.8

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 (265) hide show
  1. package/.turbo/turbo-build.log +727 -0
  2. package/.turbo/turbo-lint.log +158 -0
  3. package/.turbo/turbo-test.log +796 -0
  4. package/Cargo.lock +2237 -0
  5. package/Cargo.toml +63 -0
  6. package/clippy.toml +7 -0
  7. package/contracts/common-macros/Cargo.toml +20 -0
  8. package/contracts/common-macros/src/error.rs +53 -0
  9. package/contracts/common-macros/src/event.rs +16 -0
  10. package/contracts/common-macros/src/lib.rs +255 -0
  11. package/contracts/common-macros/src/ownable.rs +63 -0
  12. package/contracts/common-macros/src/snapshots/common_macros__tests__tests__snapshot_generated_storage_code.snap +310 -0
  13. package/contracts/common-macros/src/storage.rs +439 -0
  14. package/contracts/common-macros/src/tests.rs +287 -0
  15. package/contracts/common-macros/src/ttl_configurable.rs +60 -0
  16. package/contracts/endpoint-v2/ARCHITECTURE.md +233 -0
  17. package/contracts/endpoint-v2/Cargo.toml +30 -0
  18. package/contracts/endpoint-v2/src/constants.rs +52 -0
  19. package/contracts/endpoint-v2/src/endpoint_v2.rs +305 -0
  20. package/contracts/endpoint-v2/src/errors.rs +29 -0
  21. package/contracts/endpoint-v2/src/events.rs +207 -0
  22. package/contracts/endpoint-v2/src/interfaces/layerzero_composer.rs +26 -0
  23. package/contracts/endpoint-v2/src/interfaces/layerzero_endpoint_v2.rs +170 -0
  24. package/contracts/endpoint-v2/src/interfaces/layerzero_receiver.rs +43 -0
  25. package/contracts/endpoint-v2/src/interfaces/message_lib.rs +62 -0
  26. package/contracts/endpoint-v2/src/interfaces/message_lib_manager.rs +220 -0
  27. package/contracts/endpoint-v2/src/interfaces/messaging_channel.rs +121 -0
  28. package/contracts/endpoint-v2/src/interfaces/messaging_composer.rs +63 -0
  29. package/contracts/endpoint-v2/src/interfaces/mod.rs +17 -0
  30. package/contracts/endpoint-v2/src/interfaces/send_lib.rs +70 -0
  31. package/contracts/endpoint-v2/src/lib.rs +22 -0
  32. package/contracts/endpoint-v2/src/message_lib_manager.rs +315 -0
  33. package/contracts/endpoint-v2/src/messaging_channel.rs +218 -0
  34. package/contracts/endpoint-v2/src/messaging_composer.rs +76 -0
  35. package/contracts/endpoint-v2/src/storage.rs +78 -0
  36. package/contracts/endpoint-v2/src/tests/endpoint_setup.rs +131 -0
  37. package/contracts/endpoint-v2/src/tests/endpoint_v2/clear.rs +237 -0
  38. package/contracts/endpoint-v2/src/tests/endpoint_v2/delegate.rs +42 -0
  39. package/contracts/endpoint-v2/src/tests/endpoint_v2/initializable.rs +76 -0
  40. package/contracts/endpoint-v2/src/tests/endpoint_v2/lz_receive_alert.rs +211 -0
  41. package/contracts/endpoint-v2/src/tests/endpoint_v2/mod.rs +18 -0
  42. package/contracts/endpoint-v2/src/tests/endpoint_v2/native_token.rs +10 -0
  43. package/contracts/endpoint-v2/src/tests/endpoint_v2/owner.rs +10 -0
  44. package/contracts/endpoint-v2/src/tests/endpoint_v2/pay_messaging_fees.rs +424 -0
  45. package/contracts/endpoint-v2/src/tests/endpoint_v2/quote.rs +144 -0
  46. package/contracts/endpoint-v2/src/tests/endpoint_v2/recover_token.rs +72 -0
  47. package/contracts/endpoint-v2/src/tests/endpoint_v2/require_oapp_auth.rs +29 -0
  48. package/contracts/endpoint-v2/src/tests/endpoint_v2/send.rs +513 -0
  49. package/contracts/endpoint-v2/src/tests/endpoint_v2/set_delegate.rs +43 -0
  50. package/contracts/endpoint-v2/src/tests/endpoint_v2/set_zro.rs +27 -0
  51. package/contracts/endpoint-v2/src/tests/endpoint_v2/transfer_ownership.rs +30 -0
  52. package/contracts/endpoint-v2/src/tests/endpoint_v2/ttl_config.rs +202 -0
  53. package/contracts/endpoint-v2/src/tests/endpoint_v2/verifiable.rs +59 -0
  54. package/contracts/endpoint-v2/src/tests/endpoint_v2/verify.rs +172 -0
  55. package/contracts/endpoint-v2/src/tests/endpoint_v2/zro.rs +23 -0
  56. package/contracts/endpoint-v2/src/tests/message_lib_manager/mod.rs +10 -0
  57. package/contracts/endpoint-v2/src/tests/message_lib_manager/register_library.rs +131 -0
  58. package/contracts/endpoint-v2/src/tests/message_lib_manager/require_registered.rs +35 -0
  59. package/contracts/endpoint-v2/src/tests/message_lib_manager/require_supported_eid.rs +28 -0
  60. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_config.rs +79 -0
  61. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_default_receive_lib_timeout.rs +246 -0
  62. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_default_receive_library.rs +285 -0
  63. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_default_send_library.rs +180 -0
  64. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_receive_library.rs +405 -0
  65. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_receive_library_timeout.rs +80 -0
  66. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_send_library.rs +131 -0
  67. package/contracts/endpoint-v2/src/tests/messaging_channel/burn.rs +358 -0
  68. package/contracts/endpoint-v2/src/tests/messaging_channel/clear.rs +316 -0
  69. package/contracts/endpoint-v2/src/tests/messaging_channel/inbound_nonce.rs +288 -0
  70. package/contracts/endpoint-v2/src/tests/messaging_channel/inbound_payload_hash.rs +316 -0
  71. package/contracts/endpoint-v2/src/tests/messaging_channel/internal.rs +388 -0
  72. package/contracts/endpoint-v2/src/tests/messaging_channel/lazy_inbound_nonce.rs +307 -0
  73. package/contracts/endpoint-v2/src/tests/messaging_channel/mod.rs +10 -0
  74. package/contracts/endpoint-v2/src/tests/messaging_channel/next_guid.rs +239 -0
  75. package/contracts/endpoint-v2/src/tests/messaging_channel/nilify.rs +324 -0
  76. package/contracts/endpoint-v2/src/tests/messaging_channel/outbound_nonce.rs +242 -0
  77. package/contracts/endpoint-v2/src/tests/messaging_channel/skip.rs +232 -0
  78. package/contracts/endpoint-v2/src/tests/messaging_composer/clear_compose.rs +212 -0
  79. package/contracts/endpoint-v2/src/tests/messaging_composer/compose_queue.rs +213 -0
  80. package/contracts/endpoint-v2/src/tests/messaging_composer/lz_compose_alert.rs +269 -0
  81. package/contracts/endpoint-v2/src/tests/messaging_composer/mod.rs +4 -0
  82. package/contracts/endpoint-v2/src/tests/messaging_composer/send_compose.rs +173 -0
  83. package/contracts/endpoint-v2/src/tests/mock.rs +132 -0
  84. package/contracts/endpoint-v2/src/tests/mod.rs +12 -0
  85. package/contracts/endpoint-v2/src/tests/util/build_payload.rs +126 -0
  86. package/contracts/endpoint-v2/src/tests/util/compute_guid.rs +82 -0
  87. package/contracts/endpoint-v2/src/tests/util/keccak256.rs +115 -0
  88. package/contracts/endpoint-v2/src/tests/util/mod.rs +3 -0
  89. package/contracts/endpoint-v2/src/util.rs +52 -0
  90. package/contracts/message-libs/Cargo.toml +12 -0
  91. package/contracts/message-libs/block-message-lib/Cargo.toml +19 -0
  92. package/contracts/message-libs/block-message-lib/src/lib.rs +70 -0
  93. package/contracts/message-libs/lib.rs +2 -0
  94. package/contracts/message-libs/message-lib-common/Cargo.toml +24 -0
  95. package/contracts/message-libs/message-lib-common/src/errors.rs +20 -0
  96. package/contracts/message-libs/message-lib-common/src/interfaces/dvn.rs +55 -0
  97. package/contracts/message-libs/message-lib-common/src/interfaces/executor.rs +46 -0
  98. package/contracts/message-libs/message-lib-common/src/interfaces/mod.rs +7 -0
  99. package/contracts/message-libs/message-lib-common/src/interfaces/treasury.rs +17 -0
  100. package/contracts/message-libs/message-lib-common/src/lib.rs +14 -0
  101. package/contracts/message-libs/message-lib-common/src/packet_codec_v1.rs +99 -0
  102. package/contracts/message-libs/message-lib-common/src/testing_utils.rs +27 -0
  103. package/contracts/message-libs/message-lib-common/src/tests/mod.rs +2 -0
  104. package/contracts/message-libs/message-lib-common/src/tests/packet_codec_v1.rs +162 -0
  105. package/contracts/message-libs/message-lib-common/src/tests/worker_options.rs +319 -0
  106. package/contracts/message-libs/message-lib-common/src/worker_options.rs +190 -0
  107. package/contracts/message-libs/simple-message-lib/Cargo.toml +26 -0
  108. package/contracts/message-libs/simple-message-lib/src/errors.rs +11 -0
  109. package/contracts/message-libs/simple-message-lib/src/lib.rs +14 -0
  110. package/contracts/message-libs/simple-message-lib/src/simple_message_lib.rs +136 -0
  111. package/contracts/message-libs/simple-message-lib/src/storage.rs +27 -0
  112. package/contracts/message-libs/simple-message-lib/src/test.rs +280 -0
  113. package/contracts/message-libs/treasury/Cargo.toml +27 -0
  114. package/contracts/message-libs/treasury/src/errors.rs +10 -0
  115. package/contracts/message-libs/treasury/src/events.rs +28 -0
  116. package/contracts/message-libs/treasury/src/interfaces/mod.rs +3 -0
  117. package/contracts/message-libs/treasury/src/interfaces/zro_fee_lib.rs +20 -0
  118. package/contracts/message-libs/treasury/src/lib.rs +20 -0
  119. package/contracts/message-libs/treasury/src/storage.rs +18 -0
  120. package/contracts/message-libs/treasury/src/tests/mod.rs +2 -0
  121. package/contracts/message-libs/treasury/src/tests/setup.rs +112 -0
  122. package/contracts/message-libs/treasury/src/tests/treasury_tests.rs +562 -0
  123. package/contracts/message-libs/treasury/src/treasury.rs +140 -0
  124. package/contracts/message-libs/uln-302/Cargo.toml +28 -0
  125. package/contracts/message-libs/uln-302/src/config_validation.rs +173 -0
  126. package/contracts/message-libs/uln-302/src/errors.rs +29 -0
  127. package/contracts/message-libs/uln-302/src/events.rs +72 -0
  128. package/contracts/message-libs/uln-302/src/interfaces/mod.rs +5 -0
  129. package/contracts/message-libs/uln-302/src/interfaces/receive.rs +82 -0
  130. package/contracts/message-libs/uln-302/src/interfaces/send.rs +159 -0
  131. package/contracts/message-libs/uln-302/src/lib.rs +20 -0
  132. package/contracts/message-libs/uln-302/src/receive.rs +199 -0
  133. package/contracts/message-libs/uln-302/src/send.rs +349 -0
  134. package/contracts/message-libs/uln-302/src/storage.rs +47 -0
  135. package/contracts/message-libs/uln-302/src/tests/config/mod.rs +2 -0
  136. package/contracts/message-libs/uln-302/src/tests/config/oapp_uln_config.rs +291 -0
  137. package/contracts/message-libs/uln-302/src/tests/config/uln_config.rs +163 -0
  138. package/contracts/message-libs/uln-302/src/tests/mod.rs +7 -0
  139. package/contracts/message-libs/uln-302/src/tests/receive_uln302/commit_verification.rs +183 -0
  140. package/contracts/message-libs/uln-302/src/tests/receive_uln302/confirmations.rs +128 -0
  141. package/contracts/message-libs/uln-302/src/tests/receive_uln302/effective_receive_uln_config.rs +104 -0
  142. package/contracts/message-libs/uln-302/src/tests/receive_uln302/mod.rs +66 -0
  143. package/contracts/message-libs/uln-302/src/tests/receive_uln302/set_default_receive_uln_configs.rs +79 -0
  144. package/contracts/message-libs/uln-302/src/tests/receive_uln302/verifiable.rs +463 -0
  145. package/contracts/message-libs/uln-302/src/tests/receive_uln302/verify.rs +173 -0
  146. package/contracts/message-libs/uln-302/src/tests/send_uln302/effective_executor_config.rs +132 -0
  147. package/contracts/message-libs/uln-302/src/tests/send_uln302/effective_send_uln_config.rs +117 -0
  148. package/contracts/message-libs/uln-302/src/tests/send_uln302/mod.rs +6 -0
  149. package/contracts/message-libs/uln-302/src/tests/send_uln302/quote.rs +586 -0
  150. package/contracts/message-libs/uln-302/src/tests/send_uln302/send.rs +834 -0
  151. package/contracts/message-libs/uln-302/src/tests/send_uln302/set_default_executor_configs.rs +95 -0
  152. package/contracts/message-libs/uln-302/src/tests/send_uln302/set_default_send_uln_configs.rs +80 -0
  153. package/contracts/message-libs/uln-302/src/tests/setup.rs +268 -0
  154. package/contracts/message-libs/uln-302/src/tests/testing_utils.rs +47 -0
  155. package/contracts/message-libs/uln-302/src/tests/uln302/get_app_receive_uln_config.rs +51 -0
  156. package/contracts/message-libs/uln-302/src/tests/uln302/get_app_send_uln_config.rs +51 -0
  157. package/contracts/message-libs/uln-302/src/tests/uln302/get_oapp_executor_config.rs +48 -0
  158. package/contracts/message-libs/uln-302/src/tests/uln302/mod.rs +4 -0
  159. package/contracts/message-libs/uln-302/src/tests/uln302/set_config.rs +998 -0
  160. package/contracts/message-libs/uln-302/src/uln302.rs +117 -0
  161. package/contracts/oapp-macros/Cargo.toml +21 -0
  162. package/contracts/oapp-macros/src/lib.rs +408 -0
  163. package/contracts/oapp-macros/src/oapp_core.rs +49 -0
  164. package/contracts/oapp-macros/src/oapp_full.rs +15 -0
  165. package/contracts/oapp-macros/src/oapp_options_type3.rs +46 -0
  166. package/contracts/oapp-macros/src/oapp_receiver.rs +67 -0
  167. package/contracts/oapp-macros/src/oapp_sender.rs +23 -0
  168. package/contracts/oapp-macros/src/util.rs +103 -0
  169. package/contracts/oapp-macros/tests/test_macros.rs +522 -0
  170. package/contracts/oapps/Cargo.toml +12 -0
  171. package/contracts/oapps/counter/Cargo.toml +24 -0
  172. package/contracts/oapps/counter/integration_tests/mod.rs +3 -0
  173. package/contracts/oapps/counter/integration_tests/setup.rs +201 -0
  174. package/contracts/oapps/counter/integration_tests/test_with_sml.rs +166 -0
  175. package/contracts/oapps/counter/integration_tests/utils.rs +144 -0
  176. package/contracts/oapps/counter/src/codec.rs +63 -0
  177. package/contracts/oapps/counter/src/counter.rs +235 -0
  178. package/contracts/oapps/counter/src/errors.rs +9 -0
  179. package/contracts/oapps/counter/src/lib.rs +16 -0
  180. package/contracts/oapps/counter/src/options.rs +30 -0
  181. package/contracts/oapps/counter/src/storage.rs +33 -0
  182. package/contracts/oapps/counter/src/tests/mod.rs +37 -0
  183. package/contracts/oapps/counter/src/tests/test_codec.rs +64 -0
  184. package/contracts/oapps/counter/src/tests/test_counter.rs +390 -0
  185. package/contracts/oapps/counter/src/u256_ext.rs +21 -0
  186. package/contracts/oapps/lib.rs +2 -0
  187. package/contracts/oapps/oapp/Cargo.toml +21 -0
  188. package/contracts/oapps/oapp/src/errors.rs +9 -0
  189. package/contracts/oapps/oapp/src/lib.rs +10 -0
  190. package/contracts/oapps/oapp/src/oapp_core.rs +92 -0
  191. package/contracts/oapps/oapp/src/oapp_options_type3.rs +89 -0
  192. package/contracts/oapps/oapp/src/oapp_receiver.rs +72 -0
  193. package/contracts/oapps/oapp/src/oapp_sender.rs +66 -0
  194. package/contracts/oapps/oapp/src/tests/mod.rs +4 -0
  195. package/contracts/oapps/oapp/src/tests/test_oapp_core.rs +162 -0
  196. package/contracts/oapps/oapp/src/tests/test_oapp_options_type3.rs +180 -0
  197. package/contracts/oapps/oapp/src/tests/test_oapp_receiver.rs +157 -0
  198. package/contracts/oapps/oapp/src/tests/test_oapp_sender.rs +283 -0
  199. package/contracts/utils/Cargo.toml +21 -0
  200. package/contracts/utils/src/buffer_reader.rs +143 -0
  201. package/contracts/utils/src/buffer_writer.rs +117 -0
  202. package/contracts/utils/src/bytes_ext.rs +19 -0
  203. package/contracts/utils/src/errors.rs +30 -0
  204. package/contracts/utils/src/lib.rs +15 -0
  205. package/contracts/utils/src/option_ext.rs +38 -0
  206. package/contracts/utils/src/ownable.rs +88 -0
  207. package/contracts/utils/src/testing_utils.rs +100 -0
  208. package/contracts/utils/src/tests/buffer_reader.rs +1006 -0
  209. package/contracts/utils/src/tests/buffer_writer.rs +330 -0
  210. package/contracts/utils/src/tests/bytes_ext.rs +77 -0
  211. package/contracts/utils/src/tests/mod.rs +4 -0
  212. package/contracts/utils/src/tests/ownable.rs +149 -0
  213. package/contracts/utils/src/ttl.rs +164 -0
  214. package/contracts/workers/Cargo.toml +13 -0
  215. package/contracts/workers/executor/Cargo.toml +26 -0
  216. package/contracts/workers/executor/src/events.rs +22 -0
  217. package/contracts/workers/executor/src/executor.rs +347 -0
  218. package/contracts/workers/executor/src/interfaces/executor.rs +40 -0
  219. package/contracts/workers/executor/src/interfaces/mod.rs +5 -0
  220. package/contracts/workers/executor/src/interfaces/types.rs +51 -0
  221. package/contracts/workers/executor/src/lib.rs +10 -0
  222. package/contracts/workers/executor/src/storage.rs +23 -0
  223. package/contracts/workers/lib.rs +2 -0
  224. package/contracts/workers/worker-common/Cargo.toml +18 -0
  225. package/contracts/workers/worker-common/src/constants.rs +17 -0
  226. package/contracts/workers/worker-common/src/errors.rs +6 -0
  227. package/contracts/workers/worker-common/src/events.rs +34 -0
  228. package/contracts/workers/worker-common/src/interfaces/executor_fee_lib.rs +35 -0
  229. package/contracts/workers/worker-common/src/interfaces/mod.rs +7 -0
  230. package/contracts/workers/worker-common/src/interfaces/price_feed.rs +40 -0
  231. package/contracts/workers/worker-common/src/interfaces/worker.rs +60 -0
  232. package/contracts/workers/worker-common/src/lib.rs +19 -0
  233. package/contracts/workers/worker-common/src/storage.rs +32 -0
  234. package/contracts/workers/worker-common/src/worker_common.rs +166 -0
  235. package/package.json +25 -0
  236. package/rust-toolchain.toml +4 -0
  237. package/rustfmt.toml +17 -0
  238. package/sdk/.turbo/turbo-build.log +4 -0
  239. package/sdk/dist/generated/bml.d.ts +452 -0
  240. package/sdk/dist/generated/bml.js +72 -0
  241. package/sdk/dist/generated/counter.d.ts +824 -0
  242. package/sdk/dist/generated/counter.js +125 -0
  243. package/sdk/dist/generated/endpoint.d.ts +1676 -0
  244. package/sdk/dist/generated/endpoint.js +216 -0
  245. package/sdk/dist/generated/sml.d.ts +810 -0
  246. package/sdk/dist/generated/sml.js +132 -0
  247. package/sdk/dist/generated/uln302.d.ts +1227 -0
  248. package/sdk/dist/generated/uln302.js +185 -0
  249. package/sdk/dist/index.d.ts +5 -0
  250. package/sdk/dist/index.js +5 -0
  251. package/sdk/node_modules/.bin/tsc +21 -0
  252. package/sdk/node_modules/.bin/tsserver +21 -0
  253. package/sdk/node_modules/.bin/vitest +21 -0
  254. package/sdk/node_modules/.bin/zx +21 -0
  255. package/sdk/package.json +40 -0
  256. package/sdk/src/index.ts +5 -0
  257. package/sdk/test/index.test.ts +271 -0
  258. package/sdk/test/suites/constants.ts +13 -0
  259. package/sdk/test/suites/deploy.ts +277 -0
  260. package/sdk/test/suites/localnet.ts +42 -0
  261. package/sdk/test/suites/scan.ts +189 -0
  262. package/sdk/tsconfig.json +106 -0
  263. package/tools/ts-bindings-gen/Cargo.toml +14 -0
  264. package/tools/ts-bindings-gen/src/main.rs +147 -0
  265. package/turbo.json +12 -0
@@ -0,0 +1,242 @@
1
+ use soroban_sdk::{testutils::Address as _, Address, BytesN};
2
+
3
+ use crate::{storage, tests::endpoint_setup::setup};
4
+
5
+ #[test]
6
+ fn test_outbound_nonce_initial_value() {
7
+ let test_setup = setup();
8
+ let env = &test_setup.env;
9
+ let endpoint_client = &test_setup.endpoint_client;
10
+
11
+ let sender = Address::generate(env);
12
+ let dst_eid = 2;
13
+ let receiver = BytesN::from_array(env, &[1u8; 32]);
14
+
15
+ // Initial outbound nonce should be 0
16
+ let nonce = endpoint_client.outbound_nonce(&sender, &dst_eid, &receiver);
17
+ assert_eq!(nonce, 0);
18
+ }
19
+
20
+ #[test]
21
+ fn test_outbound_nonce_after_setting() {
22
+ let test_setup = setup();
23
+ let env = &test_setup.env;
24
+ let endpoint_client = &test_setup.endpoint_client;
25
+
26
+ let sender = Address::generate(env);
27
+ let dst_eid = 2;
28
+ let receiver = BytesN::from_array(env, &[1u8; 32]);
29
+ let expected_nonce = 42;
30
+
31
+ // Set outbound nonce
32
+ env.as_contract(&endpoint_client.address, || {
33
+ storage::EndpointStorage::set_outbound_nonce(env, &sender, dst_eid, &receiver, &expected_nonce)
34
+ });
35
+
36
+ // Verify outbound nonce is retrieved correctly
37
+ let nonce = endpoint_client.outbound_nonce(&sender, &dst_eid, &receiver);
38
+ assert_eq!(nonce, expected_nonce);
39
+ }
40
+
41
+ #[test]
42
+ fn test_outbound_nonce_different_senders() {
43
+ let test_setup = setup();
44
+ let env = &test_setup.env;
45
+ let endpoint_client = &test_setup.endpoint_client;
46
+
47
+ let sender1 = Address::generate(env);
48
+ let sender2 = Address::generate(env);
49
+ let dst_eid = 2;
50
+ let receiver = BytesN::from_array(env, &[1u8; 32]);
51
+
52
+ // Set different nonces for different senders
53
+ let nonce1 = 10;
54
+ let nonce2 = 20;
55
+
56
+ env.as_contract(&endpoint_client.address, || {
57
+ storage::EndpointStorage::set_outbound_nonce(env, &sender1, dst_eid, &receiver, &nonce1)
58
+ });
59
+ env.as_contract(&endpoint_client.address, || {
60
+ storage::EndpointStorage::set_outbound_nonce(env, &sender2, dst_eid, &receiver, &nonce2)
61
+ });
62
+
63
+ // Verify each sender has its own independent nonce
64
+ let retrieved_nonce1 = endpoint_client.outbound_nonce(&sender1, &dst_eid, &receiver);
65
+ let retrieved_nonce2 = endpoint_client.outbound_nonce(&sender2, &dst_eid, &receiver);
66
+
67
+ assert_eq!(retrieved_nonce1, nonce1);
68
+ assert_eq!(retrieved_nonce2, nonce2);
69
+
70
+ // Verify a third sender still has initial nonce of 0
71
+ let sender3 = Address::generate(env);
72
+ let retrieved_nonce3 = endpoint_client.outbound_nonce(&sender3, &dst_eid, &receiver);
73
+ assert_eq!(retrieved_nonce3, 0);
74
+ }
75
+
76
+ #[test]
77
+ fn test_outbound_nonce_different_dst_eids() {
78
+ let test_setup = setup();
79
+ let env = &test_setup.env;
80
+ let endpoint_client = &test_setup.endpoint_client;
81
+
82
+ let sender = Address::generate(env);
83
+ let dst_eid1 = 2;
84
+ let dst_eid2 = 3;
85
+ let receiver = BytesN::from_array(env, &[1u8; 32]);
86
+
87
+ // Set different nonces for different destination EIDs
88
+ let nonce1 = 15;
89
+ let nonce2 = 25;
90
+
91
+ env.as_contract(&endpoint_client.address, || {
92
+ storage::EndpointStorage::set_outbound_nonce(env, &sender, dst_eid1, &receiver, &nonce1)
93
+ });
94
+ env.as_contract(&endpoint_client.address, || {
95
+ storage::EndpointStorage::set_outbound_nonce(env, &sender, dst_eid2, &receiver, &nonce2)
96
+ });
97
+
98
+ // Verify each dst_eid has its own independent nonce
99
+ let retrieved_nonce1 = endpoint_client.outbound_nonce(&sender, &dst_eid1, &receiver);
100
+ let retrieved_nonce2 = endpoint_client.outbound_nonce(&sender, &dst_eid2, &receiver);
101
+
102
+ assert_eq!(retrieved_nonce1, nonce1);
103
+ assert_eq!(retrieved_nonce2, nonce2);
104
+
105
+ // Verify a third dst_eid still has initial nonce of 0
106
+ let dst_eid3 = 4;
107
+ let retrieved_nonce3 = endpoint_client.outbound_nonce(&sender, &dst_eid3, &receiver);
108
+ assert_eq!(retrieved_nonce3, 0);
109
+ }
110
+
111
+ #[test]
112
+ fn test_outbound_nonce_different_receivers() {
113
+ let test_setup = setup();
114
+ let env = &test_setup.env;
115
+ let endpoint_client = &test_setup.endpoint_client;
116
+
117
+ let sender = Address::generate(env);
118
+ let dst_eid = 2;
119
+ let receiver1 = BytesN::from_array(env, &[1u8; 32]);
120
+ let receiver2 = BytesN::from_array(env, &[2u8; 32]);
121
+
122
+ // Set different nonces for different receivers
123
+ let nonce1 = 30;
124
+ let nonce2 = 40;
125
+
126
+ env.as_contract(&endpoint_client.address, || {
127
+ storage::EndpointStorage::set_outbound_nonce(env, &sender, dst_eid, &receiver1, &nonce1)
128
+ });
129
+ env.as_contract(&endpoint_client.address, || {
130
+ storage::EndpointStorage::set_outbound_nonce(env, &sender, dst_eid, &receiver2, &nonce2)
131
+ });
132
+
133
+ // Verify each receiver has its own independent nonce
134
+ let retrieved_nonce1 = endpoint_client.outbound_nonce(&sender, &dst_eid, &receiver1);
135
+ let retrieved_nonce2 = endpoint_client.outbound_nonce(&sender, &dst_eid, &receiver2);
136
+
137
+ assert_eq!(retrieved_nonce1, nonce1);
138
+ assert_eq!(retrieved_nonce2, nonce2);
139
+
140
+ // Verify a third receiver still has initial nonce of 0
141
+ let receiver3 = BytesN::from_array(env, &[3u8; 32]);
142
+ let retrieved_nonce3 = endpoint_client.outbound_nonce(&sender, &dst_eid, &receiver3);
143
+ assert_eq!(retrieved_nonce3, 0);
144
+ }
145
+
146
+ #[test]
147
+ fn test_outbound_nonce_large_values() {
148
+ let test_setup = setup();
149
+ let env = &test_setup.env;
150
+ let endpoint_client = &test_setup.endpoint_client;
151
+
152
+ let sender = Address::generate(env);
153
+ let dst_eid = 2;
154
+ let receiver = BytesN::from_array(env, &[1u8; 32]);
155
+
156
+ // Test with maximum u64 value
157
+ let max_nonce = u64::MAX;
158
+ env.as_contract(&endpoint_client.address, || {
159
+ storage::EndpointStorage::set_outbound_nonce(env, &sender, dst_eid, &receiver, &max_nonce)
160
+ });
161
+
162
+ let retrieved_nonce = endpoint_client.outbound_nonce(&sender, &dst_eid, &receiver);
163
+ assert_eq!(retrieved_nonce, max_nonce);
164
+
165
+ // Test with large but not maximum value
166
+ let large_nonce = u64::MAX - 1000;
167
+ env.as_contract(&endpoint_client.address, || {
168
+ storage::EndpointStorage::set_outbound_nonce(env, &sender, dst_eid, &receiver, &large_nonce)
169
+ });
170
+
171
+ let retrieved_large_nonce = endpoint_client.outbound_nonce(&sender, &dst_eid, &receiver);
172
+ assert_eq!(retrieved_large_nonce, large_nonce);
173
+ }
174
+
175
+ #[test]
176
+ fn test_outbound_nonce_incremental_updates() {
177
+ let test_setup = setup();
178
+ let env = &test_setup.env;
179
+ let endpoint_client = &test_setup.endpoint_client;
180
+
181
+ let sender = Address::generate(env);
182
+ let dst_eid = 2;
183
+ let receiver = BytesN::from_array(env, &[1u8; 32]);
184
+
185
+ // Start with nonce 0
186
+ let initial_nonce = endpoint_client.outbound_nonce(&sender, &dst_eid, &receiver);
187
+ assert_eq!(initial_nonce, 0);
188
+
189
+ // Incrementally update nonce
190
+ for expected_nonce in 1..=10 {
191
+ env.as_contract(&endpoint_client.address, || {
192
+ storage::EndpointStorage::set_outbound_nonce(env, &sender, dst_eid, &receiver, &expected_nonce)
193
+ });
194
+
195
+ let retrieved_nonce = endpoint_client.outbound_nonce(&sender, &dst_eid, &receiver);
196
+ assert_eq!(retrieved_nonce, expected_nonce);
197
+ }
198
+ }
199
+
200
+ #[test]
201
+ fn test_outbound_nonce_multiple_paths_independence() {
202
+ let test_setup = setup();
203
+ let env = &test_setup.env;
204
+ let endpoint_client = &test_setup.endpoint_client;
205
+
206
+ let sender1 = Address::generate(env);
207
+ let sender2 = Address::generate(env);
208
+ let dst_eid1 = 2;
209
+ let dst_eid2 = 3;
210
+ let receiver1 = BytesN::from_array(env, &[1u8; 32]);
211
+ let receiver2 = BytesN::from_array(env, &[2u8; 32]);
212
+
213
+ // Set nonces for different combinations
214
+ let nonce_s1_e1_r1 = 100;
215
+ let nonce_s1_e1_r2 = 200;
216
+ let nonce_s1_e2_r1 = 300;
217
+ let nonce_s2_e1_r1 = 400;
218
+
219
+ env.as_contract(&endpoint_client.address, || {
220
+ storage::EndpointStorage::set_outbound_nonce(env, &sender1, dst_eid1, &receiver1, &nonce_s1_e1_r1)
221
+ });
222
+ env.as_contract(&endpoint_client.address, || {
223
+ storage::EndpointStorage::set_outbound_nonce(env, &sender1, dst_eid1, &receiver2, &nonce_s1_e1_r2)
224
+ });
225
+ env.as_contract(&endpoint_client.address, || {
226
+ storage::EndpointStorage::set_outbound_nonce(env, &sender1, dst_eid2, &receiver1, &nonce_s1_e2_r1)
227
+ });
228
+ env.as_contract(&endpoint_client.address, || {
229
+ storage::EndpointStorage::set_outbound_nonce(env, &sender2, dst_eid1, &receiver1, &nonce_s2_e1_r1)
230
+ });
231
+
232
+ // Verify all paths are independent
233
+ assert_eq!(endpoint_client.outbound_nonce(&sender1, &dst_eid1, &receiver1), nonce_s1_e1_r1);
234
+ assert_eq!(endpoint_client.outbound_nonce(&sender1, &dst_eid1, &receiver2), nonce_s1_e1_r2);
235
+ assert_eq!(endpoint_client.outbound_nonce(&sender1, &dst_eid2, &receiver1), nonce_s1_e2_r1);
236
+ assert_eq!(endpoint_client.outbound_nonce(&sender2, &dst_eid1, &receiver1), nonce_s2_e1_r1);
237
+
238
+ // Verify unset paths still return 0
239
+ assert_eq!(endpoint_client.outbound_nonce(&sender2, &dst_eid1, &receiver2), 0);
240
+ assert_eq!(endpoint_client.outbound_nonce(&sender2, &dst_eid2, &receiver1), 0);
241
+ assert_eq!(endpoint_client.outbound_nonce(&sender2, &dst_eid2, &receiver2), 0);
242
+ }
@@ -0,0 +1,232 @@
1
+ use soroban_sdk::{testutils::Address as _, Address, BytesN, IntoVal};
2
+
3
+ use crate::{events::InboundNonceSkipped, storage, tests::endpoint_setup::setup};
4
+ use utils::testing_utils::assert_event;
5
+
6
+ #[test]
7
+ fn test_skip_success() {
8
+ let test_setup = setup();
9
+ let env = &test_setup.env;
10
+ let endpoint_client = &test_setup.endpoint_client;
11
+
12
+ let receiver = Address::generate(env);
13
+ let src_eid = 2;
14
+ let sender = BytesN::from_array(env, &[1u8; 32]);
15
+ let nonce = 1;
16
+
17
+ // Verify initial state - lazy inbound nonce should be 0
18
+ let initial_lazy_nonce = env.as_contract(&endpoint_client.address, || {
19
+ storage::EndpointStorage::lazy_inbound_nonce(env, &receiver, src_eid, &sender)
20
+ });
21
+ assert_eq!(initial_lazy_nonce, 0, "Initial lazy inbound nonce should be 0");
22
+
23
+ // Initially, inbound nonce should be 0
24
+ let initial_nonce = endpoint_client.inbound_nonce(&receiver, &src_eid, &sender);
25
+ assert_eq!(initial_nonce, 0);
26
+
27
+ // Skip nonce 1 (expected nonce is initial_nonce + 1 = 1)
28
+ endpoint_client
29
+ .mock_auths(&[soroban_sdk::testutils::MockAuth {
30
+ address: &receiver,
31
+ invoke: &soroban_sdk::testutils::MockAuthInvoke {
32
+ contract: &endpoint_client.address,
33
+ fn_name: "skip",
34
+ args: (&receiver, &receiver, &src_eid, &sender, &nonce).into_val(env),
35
+ sub_invokes: &[],
36
+ },
37
+ }])
38
+ .skip(&receiver, &receiver, &src_eid, &sender, &nonce);
39
+
40
+ // Verify InboundNonceSkipped event was emitted
41
+ assert_event(
42
+ env,
43
+ &endpoint_client.address,
44
+ InboundNonceSkipped { src_eid, sender: sender.clone(), receiver: receiver.clone(), nonce },
45
+ );
46
+
47
+ // Verify inbound nonce reflects the skip via public interface
48
+ let updated_nonce = endpoint_client.inbound_nonce(&receiver, &src_eid, &sender);
49
+ assert_eq!(updated_nonce, nonce);
50
+
51
+ // Assert storage change directly - lazy inbound nonce was updated
52
+ let lazy_nonce = env.as_contract(&endpoint_client.address, || {
53
+ storage::EndpointStorage::lazy_inbound_nonce(env, &receiver, src_eid, &sender)
54
+ });
55
+ assert_eq!(lazy_nonce, nonce, "Storage should contain updated lazy inbound nonce");
56
+ }
57
+
58
+ #[test]
59
+ fn test_skip_multiple_nonces() {
60
+ let test_setup = setup();
61
+ let env = &test_setup.env;
62
+ let endpoint_client = &test_setup.endpoint_client;
63
+
64
+ let receiver = Address::generate(env);
65
+ let src_eid = 2;
66
+ let sender = BytesN::from_array(env, &[1u8; 32]);
67
+
68
+ // Skip nonce 1
69
+ let nonce1 = 1;
70
+ endpoint_client
71
+ .mock_auths(&[soroban_sdk::testutils::MockAuth {
72
+ address: &receiver,
73
+ invoke: &soroban_sdk::testutils::MockAuthInvoke {
74
+ contract: &endpoint_client.address,
75
+ fn_name: "skip",
76
+ args: (&receiver, &receiver, &src_eid, &sender, &nonce1).into_val(env),
77
+ sub_invokes: &[],
78
+ },
79
+ }])
80
+ .skip(&receiver, &receiver, &src_eid, &sender, &nonce1);
81
+
82
+ // Skip nonce 2
83
+ let nonce2 = 2;
84
+ endpoint_client
85
+ .mock_auths(&[soroban_sdk::testutils::MockAuth {
86
+ address: &receiver,
87
+ invoke: &soroban_sdk::testutils::MockAuthInvoke {
88
+ contract: &endpoint_client.address,
89
+ fn_name: "skip",
90
+ args: (&receiver, &receiver, &src_eid, &sender, &nonce2).into_val(env),
91
+ sub_invokes: &[],
92
+ },
93
+ }])
94
+ .skip(&receiver, &receiver, &src_eid, &sender, &nonce2);
95
+
96
+ // Verify lazy inbound nonce was updated to nonce2
97
+ let lazy_nonce = env.as_contract(&endpoint_client.address, || {
98
+ storage::EndpointStorage::lazy_inbound_nonce(env, &receiver, src_eid, &sender)
99
+ });
100
+ assert_eq!(lazy_nonce, nonce2);
101
+
102
+ // Verify inbound nonce reflects the latest skip
103
+ let updated_nonce = endpoint_client.inbound_nonce(&receiver, &src_eid, &sender);
104
+ assert_eq!(updated_nonce, nonce2);
105
+ }
106
+
107
+ #[test]
108
+ fn test_skip_with_delegate() {
109
+ let test_setup = setup();
110
+ let env = &test_setup.env;
111
+ let endpoint_client = &test_setup.endpoint_client;
112
+
113
+ let receiver = Address::generate(env);
114
+ let delegate = Address::generate(env);
115
+ let src_eid = 2;
116
+ let sender = BytesN::from_array(env, &[1u8; 32]);
117
+ let nonce = 1;
118
+
119
+ // Set delegate for receiver
120
+ env.as_contract(&endpoint_client.address, || storage::EndpointStorage::set_delegate(env, &receiver, &delegate));
121
+
122
+ // Delegate can skip on behalf of receiver
123
+ endpoint_client
124
+ .mock_auths(&[soroban_sdk::testutils::MockAuth {
125
+ address: &delegate,
126
+ invoke: &soroban_sdk::testutils::MockAuthInvoke {
127
+ contract: &endpoint_client.address,
128
+ fn_name: "skip",
129
+ args: (&delegate, &receiver, &src_eid, &sender, &nonce).into_val(env),
130
+ sub_invokes: &[],
131
+ },
132
+ }])
133
+ .skip(&delegate, &receiver, &src_eid, &sender, &nonce);
134
+
135
+ // Verify InboundNonceSkipped event was emitted
136
+ assert_event(
137
+ env,
138
+ &endpoint_client.address,
139
+ InboundNonceSkipped { src_eid, sender: sender.clone(), receiver: receiver.clone(), nonce },
140
+ );
141
+
142
+ // Verify lazy inbound nonce was updated
143
+ let lazy_nonce = env.as_contract(&endpoint_client.address, || {
144
+ storage::EndpointStorage::lazy_inbound_nonce(env, &receiver, src_eid, &sender)
145
+ });
146
+ assert_eq!(lazy_nonce, nonce);
147
+ }
148
+
149
+ #[test]
150
+ fn test_skip_different_paths() {
151
+ let test_setup = setup();
152
+ let env = &test_setup.env;
153
+ let endpoint_client = &test_setup.endpoint_client;
154
+
155
+ let receiver1 = Address::generate(env);
156
+ let receiver2 = Address::generate(env);
157
+ let src_eid1 = 2;
158
+ let src_eid2 = 3;
159
+ let sender1 = BytesN::from_array(env, &[1u8; 32]);
160
+ let sender2 = BytesN::from_array(env, &[2u8; 32]);
161
+ let nonce = 1;
162
+
163
+ // Skip for different receivers
164
+ endpoint_client
165
+ .mock_auths(&[soroban_sdk::testutils::MockAuth {
166
+ address: &receiver1,
167
+ invoke: &soroban_sdk::testutils::MockAuthInvoke {
168
+ contract: &endpoint_client.address,
169
+ fn_name: "skip",
170
+ args: (&receiver1, &receiver1, &src_eid1, &sender1, &nonce).into_val(env),
171
+ sub_invokes: &[],
172
+ },
173
+ }])
174
+ .skip(&receiver1, &receiver1, &src_eid1, &sender1, &nonce);
175
+
176
+ endpoint_client
177
+ .mock_auths(&[soroban_sdk::testutils::MockAuth {
178
+ address: &receiver2,
179
+ invoke: &soroban_sdk::testutils::MockAuthInvoke {
180
+ contract: &endpoint_client.address,
181
+ fn_name: "skip",
182
+ args: (&receiver2, &receiver2, &src_eid1, &sender1, &nonce).into_val(env),
183
+ sub_invokes: &[],
184
+ },
185
+ }])
186
+ .skip(&receiver2, &receiver2, &src_eid1, &sender1, &nonce);
187
+
188
+ // Skip for different src_eids
189
+ endpoint_client
190
+ .mock_auths(&[soroban_sdk::testutils::MockAuth {
191
+ address: &receiver1,
192
+ invoke: &soroban_sdk::testutils::MockAuthInvoke {
193
+ contract: &endpoint_client.address,
194
+ fn_name: "skip",
195
+ args: (&receiver1, &receiver1, &src_eid2, &sender1, &nonce).into_val(env),
196
+ sub_invokes: &[],
197
+ },
198
+ }])
199
+ .skip(&receiver1, &receiver1, &src_eid2, &sender1, &nonce);
200
+
201
+ // Skip for different senders
202
+ endpoint_client
203
+ .mock_auths(&[soroban_sdk::testutils::MockAuth {
204
+ address: &receiver1,
205
+ invoke: &soroban_sdk::testutils::MockAuthInvoke {
206
+ contract: &endpoint_client.address,
207
+ fn_name: "skip",
208
+ args: (&receiver1, &receiver1, &src_eid1, &sender2, &nonce).into_val(env),
209
+ sub_invokes: &[],
210
+ },
211
+ }])
212
+ .skip(&receiver1, &receiver1, &src_eid1, &sender2, &nonce);
213
+
214
+ // Verify all paths have independent lazy nonces
215
+ let lazy_nonce1 = env.as_contract(&endpoint_client.address, || {
216
+ storage::EndpointStorage::lazy_inbound_nonce(env, &receiver1, src_eid1, &sender1)
217
+ });
218
+ let lazy_nonce2 = env.as_contract(&endpoint_client.address, || {
219
+ storage::EndpointStorage::lazy_inbound_nonce(env, &receiver2, src_eid1, &sender1)
220
+ });
221
+ let lazy_nonce3 = env.as_contract(&endpoint_client.address, || {
222
+ storage::EndpointStorage::lazy_inbound_nonce(env, &receiver1, src_eid2, &sender1)
223
+ });
224
+ let lazy_nonce4 = env.as_contract(&endpoint_client.address, || {
225
+ storage::EndpointStorage::lazy_inbound_nonce(env, &receiver1, src_eid1, &sender2)
226
+ });
227
+
228
+ assert_eq!(lazy_nonce1, nonce);
229
+ assert_eq!(lazy_nonce2, nonce);
230
+ assert_eq!(lazy_nonce3, nonce);
231
+ assert_eq!(lazy_nonce4, nonce);
232
+ }
@@ -0,0 +1,212 @@
1
+ use crate::{events::ComposeDelivered, storage, tests::endpoint_setup::setup, util::keccak256};
2
+ use soroban_sdk::{
3
+ testutils::{Address as _, MockAuth, MockAuthInvoke},
4
+ Address, Bytes, BytesN, IntoVal,
5
+ };
6
+ use utils::testing_utils::assert_event;
7
+
8
+ const RECEIVED_MESSAGE_HASH_BYTES: [u8; 32] =
9
+ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1];
10
+
11
+ #[test]
12
+ fn test_clear_compose_success() {
13
+ let context = setup();
14
+ let env = &context.env;
15
+ let endpoint_client = &context.endpoint_client;
16
+
17
+ let from = Address::generate(env);
18
+ let composer = Address::generate(env);
19
+ let guid = BytesN::from_array(env, &[1u8; 32]);
20
+ let index = 0u32;
21
+ let message = Bytes::from_array(env, &[1, 2, 3, 4, 5]);
22
+
23
+ // First, send compose
24
+ env.mock_auths(&[MockAuth {
25
+ address: &from,
26
+ invoke: &MockAuthInvoke {
27
+ contract: &endpoint_client.address,
28
+ fn_name: "send_compose",
29
+ args: (&from, &composer, &guid, &index, &message).into_val(env),
30
+ sub_invokes: &[],
31
+ },
32
+ }]);
33
+ endpoint_client.send_compose(&from, &composer, &guid, &index, &message);
34
+
35
+ // Verify it was stored before clear
36
+ let message_hash = keccak256(env, &message);
37
+ assert_eq!(endpoint_client.compose_queue(&from, &composer, &guid, &index), Some(message_hash.clone()));
38
+
39
+ // Verify storage before clear
40
+ let hash_before_clear = env.as_contract(&endpoint_client.address, || {
41
+ storage::EndpointStorage::compose_queue(env, &from, &composer, &guid, index)
42
+ });
43
+ assert_eq!(hash_before_clear, Some(message_hash), "Storage should contain message hash before clear");
44
+
45
+ // Now clear compose
46
+ env.mock_auths(&[MockAuth {
47
+ address: &composer,
48
+ invoke: &MockAuthInvoke {
49
+ contract: &endpoint_client.address,
50
+ fn_name: "clear_compose",
51
+ args: (&composer, &from, &guid, &index, &message).into_val(env),
52
+ sub_invokes: &[],
53
+ },
54
+ }]);
55
+ endpoint_client.clear_compose(&composer, &from, &guid, &index, &message);
56
+
57
+ // Verify the event was published
58
+ assert_event(
59
+ env,
60
+ &endpoint_client.address,
61
+ ComposeDelivered { from: from.clone(), to: composer.clone(), guid: guid.clone(), index },
62
+ );
63
+
64
+ // Verify the compose queue was marked as received via public interface
65
+ let received_hash = BytesN::from_array(env, &RECEIVED_MESSAGE_HASH_BYTES);
66
+ let stored_hash = endpoint_client.compose_queue(&from, &composer, &guid, &index);
67
+ assert_eq!(stored_hash, Some(received_hash.clone()));
68
+
69
+ // Assert storage change directly
70
+ let stored_hash_direct = env.as_contract(&endpoint_client.address, || {
71
+ storage::EndpointStorage::compose_queue(env, &from, &composer, &guid, index)
72
+ });
73
+ assert_eq!(stored_hash_direct, Some(received_hash), "Storage should contain received message hash marker");
74
+ }
75
+
76
+ #[test]
77
+ fn test_clear_compose_multiple_messages() {
78
+ let context = setup();
79
+ let env = &context.env;
80
+ let endpoint_client = &context.endpoint_client;
81
+
82
+ let from = Address::generate(env);
83
+ let composer = Address::generate(env);
84
+ let guid = BytesN::from_array(env, &[1u8; 32]);
85
+ let message1 = Bytes::from_array(env, &[1, 2, 3]);
86
+ let message2 = Bytes::from_array(env, &[4, 5, 6]);
87
+
88
+ // Send two compose messages
89
+ env.mock_auths(&[MockAuth {
90
+ address: &from,
91
+ invoke: &MockAuthInvoke {
92
+ contract: &endpoint_client.address,
93
+ fn_name: "send_compose",
94
+ args: (&from, &composer, &guid, &0u32, &message1).into_val(env),
95
+ sub_invokes: &[],
96
+ },
97
+ }]);
98
+ endpoint_client.send_compose(&from, &composer, &guid, &0, &message1);
99
+
100
+ env.mock_auths(&[MockAuth {
101
+ address: &from,
102
+ invoke: &MockAuthInvoke {
103
+ contract: &endpoint_client.address,
104
+ fn_name: "send_compose",
105
+ args: (&from, &composer, &guid, &1u32, &message2).into_val(env),
106
+ sub_invokes: &[],
107
+ },
108
+ }]);
109
+ endpoint_client.send_compose(&from, &composer, &guid, &1, &message2);
110
+
111
+ // Clear first message
112
+ env.mock_auths(&[MockAuth {
113
+ address: &composer,
114
+ invoke: &MockAuthInvoke {
115
+ contract: &endpoint_client.address,
116
+ fn_name: "clear_compose",
117
+ args: (&composer, &from, &guid, &0u32, &message1).into_val(env),
118
+ sub_invokes: &[],
119
+ },
120
+ }]);
121
+ endpoint_client.clear_compose(&composer, &from, &guid, &0, &message1);
122
+
123
+ // Verify first message is cleared and second still exists
124
+ let received_hash = BytesN::from_array(env, &RECEIVED_MESSAGE_HASH_BYTES);
125
+ assert_eq!(endpoint_client.compose_queue(&from, &composer, &guid, &0), Some(received_hash));
126
+
127
+ let hash2 = keccak256(env, &message2);
128
+ assert_eq!(endpoint_client.compose_queue(&from, &composer, &guid, &1), Some(hash2));
129
+ }
130
+
131
+ #[test]
132
+ fn test_clear_compose_empty_message() {
133
+ let context = setup();
134
+ let env = &context.env;
135
+ let endpoint_client = &context.endpoint_client;
136
+
137
+ let from = Address::generate(env);
138
+ let composer = Address::generate(env);
139
+ let guid = BytesN::from_array(env, &[1u8; 32]);
140
+ let index = 0u32;
141
+ let message = Bytes::new(env);
142
+
143
+ // Send compose with empty message
144
+ env.mock_auths(&[MockAuth {
145
+ address: &from,
146
+ invoke: &MockAuthInvoke {
147
+ contract: &endpoint_client.address,
148
+ fn_name: "send_compose",
149
+ args: (&from, &composer, &guid, &index, &message).into_val(env),
150
+ sub_invokes: &[],
151
+ },
152
+ }]);
153
+ endpoint_client.send_compose(&from, &composer, &guid, &index, &message);
154
+
155
+ // Clear compose
156
+ env.mock_auths(&[MockAuth {
157
+ address: &composer,
158
+ invoke: &MockAuthInvoke {
159
+ contract: &endpoint_client.address,
160
+ fn_name: "clear_compose",
161
+ args: (&composer, &from, &guid, &index, &message).into_val(env),
162
+ sub_invokes: &[],
163
+ },
164
+ }]);
165
+ endpoint_client.clear_compose(&composer, &from, &guid, &index, &message);
166
+
167
+ // Verify the compose queue was marked as received
168
+ let received_hash = BytesN::from_array(env, &RECEIVED_MESSAGE_HASH_BYTES);
169
+ let stored_hash = endpoint_client.compose_queue(&from, &composer, &guid, &index);
170
+ assert_eq!(stored_hash, Some(received_hash));
171
+ }
172
+
173
+ #[test]
174
+ fn test_clear_compose_sequential_operations() {
175
+ let context = setup();
176
+ let env = &context.env;
177
+ let endpoint_client = &context.endpoint_client;
178
+
179
+ let from = Address::generate(env);
180
+ let composer = Address::generate(env);
181
+ let guid = BytesN::from_array(env, &[1u8; 32]);
182
+ let index = 0u32;
183
+ let message = Bytes::from_array(env, &[1, 2, 3, 4, 5]);
184
+
185
+ // Send, clear, and verify the flow works correctly
186
+ env.mock_auths(&[MockAuth {
187
+ address: &from,
188
+ invoke: &MockAuthInvoke {
189
+ contract: &endpoint_client.address,
190
+ fn_name: "send_compose",
191
+ args: (&from, &composer, &guid, &index, &message).into_val(env),
192
+ sub_invokes: &[],
193
+ },
194
+ }]);
195
+ endpoint_client.send_compose(&from, &composer, &guid, &index, &message);
196
+
197
+ // Clear
198
+ env.mock_auths(&[MockAuth {
199
+ address: &composer,
200
+ invoke: &MockAuthInvoke {
201
+ contract: &endpoint_client.address,
202
+ fn_name: "clear_compose",
203
+ args: (&composer, &from, &guid, &index, &message).into_val(env),
204
+ sub_invokes: &[],
205
+ },
206
+ }]);
207
+ endpoint_client.clear_compose(&composer, &from, &guid, &index, &message);
208
+
209
+ // Verify it's marked as received
210
+ let received_hash = BytesN::from_array(env, &RECEIVED_MESSAGE_HASH_BYTES);
211
+ assert_eq!(endpoint_client.compose_queue(&from, &composer, &guid, &index), Some(received_hash));
212
+ }