@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,319 @@
1
+ use crate::worker_options::{
2
+ convert_legacy_options, split_worker_options, EXECUTOR_OPTION_TYPE_LZRECEIVE, EXECUTOR_OPTION_TYPE_NATIVE_DROP,
3
+ EXECUTOR_WORKER_ID, LEGACY_OPTIONS_TYPE_1, LEGACY_OPTIONS_TYPE_2, OPTIONS_TYPE_3,
4
+ };
5
+ use hex_literal::hex;
6
+ use soroban_sdk::{Bytes, BytesN, Env};
7
+ use utils::buffer_reader::BufferReader;
8
+
9
+ #[test]
10
+ fn test_split_worker_options_dvn_only() {
11
+ let env = Env::default();
12
+
13
+ // Build TYPE_3 options with only DVN options
14
+ // x"0003" + x"020002000102000302ff0102000200010200020101"
15
+ let mut options = Bytes::new(&env);
16
+ options.extend_from_slice(&OPTIONS_TYPE_3.to_be_bytes());
17
+ options.extend_from_slice(&hex!("020002000102000302ff0102000200010200020101"));
18
+
19
+ let (executor_options, dvn_options) = split_worker_options(&env, &options);
20
+
21
+ assert_eq!(executor_options.len(), 0);
22
+ assert_eq!(dvn_options.len(), 3);
23
+
24
+ // Check DVN options are grouped correctly by index
25
+ assert_eq!(dvn_options.get(0).unwrap(), Bytes::from_slice(&env, &hex!("02000200010200020001")));
26
+ assert_eq!(dvn_options.get(1).unwrap(), Bytes::from_slice(&env, &hex!("0200020101")));
27
+ assert_eq!(dvn_options.get(2).unwrap(), Bytes::from_slice(&env, &hex!("02000302ff01")));
28
+ }
29
+
30
+ #[test]
31
+ fn test_split_worker_options_executor_only() {
32
+ let env = Env::default();
33
+
34
+ // Build TYPE_3 options with two executor options
35
+ // x"0003" + x"0100110100000000000000000000000000009470010011010000000000000000000000000000ea60"
36
+ let executor_options_raw = hex!("0100110100000000000000000000000000009470010011010000000000000000000000000000ea60");
37
+ let mut options = Bytes::new(&env);
38
+ options.extend_from_slice(&OPTIONS_TYPE_3.to_be_bytes());
39
+ options.extend_from_slice(&executor_options_raw);
40
+
41
+ let (executor_options, dvn_options) = split_worker_options(&env, &options);
42
+
43
+ assert_eq!(executor_options, Bytes::from_slice(&env, &executor_options_raw));
44
+ assert_eq!(dvn_options.len(), 0);
45
+ }
46
+
47
+ #[test]
48
+ fn test_split_worker_options_options() {
49
+ let env = Env::default();
50
+
51
+ // Build TYPE_3 options with executor and DVN options
52
+ // executor: x"0100110100000000000000000000000000009470010011010000000000000000000000000000ea60"
53
+ // dvn: x"020002000102000302ff0102000200010200020101"
54
+ let executor_options_raw = hex!("0100110100000000000000000000000000009470010011010000000000000000000000000000ea60");
55
+ let dvn_options_raw = hex!("020002000102000302ff0102000200010200020101");
56
+
57
+ let mut options = Bytes::new(&env);
58
+ options.extend_from_slice(&OPTIONS_TYPE_3.to_be_bytes());
59
+ options.extend_from_slice(&executor_options_raw);
60
+ options.extend_from_slice(&dvn_options_raw);
61
+
62
+ let (executor_options, dvn_options) = split_worker_options(&env, &options);
63
+
64
+ assert_eq!(executor_options, Bytes::from_slice(&env, &executor_options_raw));
65
+ assert_eq!(dvn_options.len(), 3);
66
+
67
+ // Check DVN options grouped by index
68
+ assert_eq!(dvn_options.get(0).unwrap(), Bytes::from_slice(&env, &hex!("02000200010200020001")));
69
+ assert_eq!(dvn_options.get(1).unwrap(), Bytes::from_slice(&env, &hex!("0200020101")));
70
+ assert_eq!(dvn_options.get(2).unwrap(), Bytes::from_slice(&env, &hex!("02000302ff01")));
71
+ }
72
+
73
+ #[test]
74
+ fn test_decode_legacy_options_type_1() {
75
+ let env = Env::default();
76
+
77
+ // Legacy type 1: x"0001" + gas as u256 (200000 = 0x30d40)
78
+ let mut options = Bytes::new(&env);
79
+ options.extend_from_slice(&LEGACY_OPTIONS_TYPE_1.to_be_bytes());
80
+ options.extend_from_slice(&hex!("0000000000000000000000000000000000000000000000000000000000030d40"));
81
+
82
+ let (executor_options, dvn_options) = split_worker_options(&env, &options);
83
+
84
+ // Expected: x"0100110100000000000000000000000000030d40"
85
+ assert_eq!(executor_options, Bytes::from_slice(&env, &hex!("0100110100000000000000000000000000030d40")));
86
+ assert_eq!(dvn_options.len(), 0);
87
+
88
+ // Verify by parsing
89
+ let mut reader = BufferReader::new(&executor_options);
90
+ assert_eq!(reader.read_u8(), EXECUTOR_WORKER_ID);
91
+ assert_eq!(reader.read_u16(), 17);
92
+ assert_eq!(reader.read_u8(), EXECUTOR_OPTION_TYPE_LZRECEIVE);
93
+ assert_eq!(reader.read_u128(), 200000);
94
+ assert_eq!(reader.remaining(), 0);
95
+ }
96
+
97
+ #[test]
98
+ fn test_decode_legacy_options_type_2() {
99
+ let env = Env::default();
100
+
101
+ // Legacy type 2: gas(u256) + amount(u256) + receiver(20 bytes)
102
+ // gas: 200000 (0x30d40), amount: 10000000 (0x989680), receiver: 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266
103
+ let legacy_options = Bytes::from_slice(&env, &hex!("0000000000000000000000000000000000000000000000000000000000030d400000000000000000000000000000000000000000000000000000000000989680f39fd6e51aad88f6f4ce6ab8827279cfffb92266"));
104
+ let expected_options = hex!("0100110100000000000000000000000000030d400100310200000000000000000000000000989680000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266");
105
+
106
+ let executor_options = convert_legacy_options(&env, &mut BufferReader::new(&legacy_options), LEGACY_OPTIONS_TYPE_2);
107
+
108
+ // adapter params type 2 includes both lzReceive and nativeDrop
109
+ assert_eq!(executor_options, Bytes::from_slice(&env, &expected_options));
110
+
111
+ // Verify by parsing
112
+ let mut reader = BufferReader::new(&executor_options);
113
+
114
+ // lzReceive option
115
+ assert_eq!(reader.read_u8(), EXECUTOR_WORKER_ID);
116
+ assert_eq!(reader.read_u16(), 17);
117
+ assert_eq!(reader.read_u8(), EXECUTOR_OPTION_TYPE_LZRECEIVE);
118
+ assert_eq!(reader.read_u128(), 200000);
119
+
120
+ // nativeDrop option
121
+ assert_eq!(reader.read_u8(), EXECUTOR_WORKER_ID);
122
+ assert_eq!(reader.read_u16(), 49);
123
+ assert_eq!(reader.read_u8(), EXECUTOR_OPTION_TYPE_NATIVE_DROP);
124
+ assert_eq!(reader.read_u128(), 10000000);
125
+ assert_eq!(
126
+ reader.read_bytes_n(),
127
+ BytesN::from_array(&env, &hex!("000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266"))
128
+ );
129
+ }
130
+
131
+ #[test]
132
+ fn test_split_worker_options_using_legacy_option() {
133
+ let env = Env::default();
134
+
135
+ // Same as test_decode_legacy_options_type_2
136
+ let mut legacy_options = Bytes::new(&env);
137
+ legacy_options.extend_from_slice(&LEGACY_OPTIONS_TYPE_2.to_be_bytes());
138
+ legacy_options.extend_from_slice(&hex!("0000000000000000000000000000000000000000000000000000000000030d400000000000000000000000000000000000000000000000000000000000989680f39fd6e51aad88f6f4ce6ab8827279cfffb92266"));
139
+ let expected_options = hex!("0100110100000000000000000000000000030d400100310200000000000000000000000000989680000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266");
140
+
141
+ let (executor_options, _) = split_worker_options(&env, &legacy_options);
142
+
143
+ // adapter params type 2 includes both lzReceive and nativeDrop
144
+ assert_eq!(executor_options, Bytes::from_slice(&env, &expected_options));
145
+
146
+ let mut reader = BufferReader::new(&executor_options);
147
+
148
+ // lzReceive
149
+ assert_eq!(reader.read_u8(), EXECUTOR_WORKER_ID);
150
+ assert_eq!(reader.read_u16(), 17);
151
+ assert_eq!(reader.read_u8(), EXECUTOR_OPTION_TYPE_LZRECEIVE);
152
+ assert_eq!(reader.read_u128(), 200000);
153
+
154
+ // nativeDrop
155
+ assert_eq!(reader.read_u8(), EXECUTOR_WORKER_ID);
156
+ assert_eq!(reader.read_u16(), 49);
157
+ assert_eq!(reader.read_u8(), EXECUTOR_OPTION_TYPE_NATIVE_DROP);
158
+ assert_eq!(reader.read_u128(), 10000000);
159
+ assert_eq!(
160
+ reader.read_bytes_n(),
161
+ BytesN::from_array(&env, &hex!("000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266"))
162
+ );
163
+ }
164
+
165
+ #[test]
166
+ fn test_group_dvn_options_by_index() {
167
+ let env = Env::default();
168
+
169
+ let dvn_option_bytes = hex!("020002000102000302ff0102000200010200020101");
170
+ let mut options = Bytes::new(&env);
171
+ options.extend_from_slice(&OPTIONS_TYPE_3.to_be_bytes());
172
+ options.extend_from_slice(&dvn_option_bytes);
173
+
174
+ let (_, dvn_options) = split_worker_options(&env, &options);
175
+
176
+ let expected_dvn_0_options = hex!("02000200010200020001"); // 2 DVN options, id = 0
177
+ let expected_dvn_1_options = hex!("0200020101"); // 1 DVN option, id = 1
178
+ let expected_dvn_2_options = hex!("02000302ff01"); // 1 DVN option, id = 2
179
+
180
+ let mut found_0 = false;
181
+ let mut found_1 = false;
182
+ let mut found_2 = false;
183
+
184
+ // Check that DVN options are grouped correctly by index
185
+ for (index, option) in dvn_options.iter() {
186
+ if index == 0 {
187
+ found_0 = true;
188
+ assert_eq!(option, Bytes::from_slice(&env, &expected_dvn_0_options));
189
+ }
190
+ if index == 1 {
191
+ found_1 = true;
192
+ assert_eq!(option, Bytes::from_slice(&env, &expected_dvn_1_options));
193
+ }
194
+ if index == 2 {
195
+ found_2 = true;
196
+ assert_eq!(option, Bytes::from_slice(&env, &expected_dvn_2_options));
197
+ }
198
+ }
199
+ assert!(found_0 && found_1 && found_2);
200
+ }
201
+
202
+ #[test]
203
+ fn test_get_matching_options() {
204
+ let env = Env::default();
205
+
206
+ // Same DVN options as test_split_worker_options_dvn_only
207
+ let mut options = Bytes::new(&env);
208
+ options.extend_from_slice(&OPTIONS_TYPE_3.to_be_bytes());
209
+ options.extend_from_slice(&hex!("020002000102000302ff0102000200010200020101"));
210
+
211
+ let (_, dvn_options) = split_worker_options(&env, &options);
212
+
213
+ assert_eq!(dvn_options.get(0).unwrap(), Bytes::from_slice(&env, &hex!("02000200010200020001")));
214
+ assert_eq!(dvn_options.get(1).unwrap(), Bytes::from_slice(&env, &hex!("0200020101")));
215
+ assert_eq!(dvn_options.get(2).unwrap(), Bytes::from_slice(&env, &hex!("02000302ff01")));
216
+ }
217
+
218
+ // ============ Error tests ============
219
+
220
+ #[test]
221
+ #[should_panic(expected = "Error(Contract, #11101)")] // WorkerOptionsError::InvalidOptions
222
+ fn test_decode_invalid_options_too_short() {
223
+ let env = Env::default();
224
+ let mut options = Bytes::new(&env);
225
+ options.push_back(OPTIONS_TYPE_3 as u8);
226
+ split_worker_options(&env, &options);
227
+ }
228
+
229
+ #[test]
230
+ #[should_panic(expected = "Error(Contract, #11102)")] // WorkerOptionsError::InvalidWorkerId
231
+ fn test_decode_invalid_worker_id() {
232
+ let env = Env::default();
233
+ let mut options = Bytes::new(&env);
234
+ options.extend_from_slice(&OPTIONS_TYPE_3.to_be_bytes());
235
+ options.extend_from_slice(&hex!("00000501020304050607")); // Invalid worker_id = 0
236
+ split_worker_options(&env, &options);
237
+ }
238
+
239
+ #[test]
240
+ #[should_panic(expected = "Error(Contract, #11104)")] // WorkerOptionsError::LegacyOptionsType1GasOverflow
241
+ fn test_legacy_type1_gas_overflow() {
242
+ let env = Env::default();
243
+ let mut options = Bytes::new(&env);
244
+ options.extend_from_slice(&LEGACY_OPTIONS_TYPE_1.to_be_bytes());
245
+ options.extend_from_slice(&hex!("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")); // u256 max
246
+ split_worker_options(&env, &options);
247
+ }
248
+
249
+ #[test]
250
+ #[should_panic(expected = "Error(Contract, #11106)")] // WorkerOptionsError::LegacyOptionsType2GasOverflow
251
+ fn test_legacy_type2_gas_overflow() {
252
+ let env = Env::default();
253
+ let mut options = Bytes::new(&env);
254
+ options.extend_from_slice(&LEGACY_OPTIONS_TYPE_2.to_be_bytes());
255
+ options.extend_from_slice(&hex!("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000000003e84242424242424242424242424242424242424242424242424242424242424242"));
256
+ split_worker_options(&env, &options);
257
+ }
258
+
259
+ #[test]
260
+ #[should_panic(expected = "Error(Contract, #11107)")] // WorkerOptionsError::LegacyOptionsType2AmountOverflow
261
+ fn test_legacy_type2_amount_overflow() {
262
+ let env = Env::default();
263
+ let mut options = Bytes::new(&env);
264
+ options.extend_from_slice(&LEGACY_OPTIONS_TYPE_2.to_be_bytes());
265
+ options.extend_from_slice(&hex!("0000000000000000000000000000000000000000000000000000000000030d40ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4242424242424242424242424242424242424242424242424242424242424242"));
266
+ split_worker_options(&env, &options);
267
+ }
268
+
269
+ #[test]
270
+ #[should_panic(expected = "Error(Contract, #11103)")] // WorkerOptionsError::InvalidLegacyOptionsType1
271
+ fn test_legacy_type1_invalid_size_too_short() {
272
+ let env = Env::default();
273
+ let mut options = Bytes::new(&env);
274
+ options.extend_from_slice(&LEGACY_OPTIONS_TYPE_1.to_be_bytes());
275
+ options.extend_from_slice(&hex!("00000000000000000000000000000000")); // Only 16 bytes
276
+ split_worker_options(&env, &options);
277
+ }
278
+
279
+ #[test]
280
+ #[should_panic(expected = "Error(Contract, #11103)")] // WorkerOptionsError::InvalidLegacyOptionsType1
281
+ fn test_legacy_type1_invalid_size_too_long() {
282
+ let env = Env::default();
283
+ let mut options = Bytes::new(&env);
284
+ options.extend_from_slice(&LEGACY_OPTIONS_TYPE_1.to_be_bytes());
285
+ options.extend_from_slice(&hex!(
286
+ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
287
+ )); // 48 bytes
288
+ split_worker_options(&env, &options);
289
+ }
290
+
291
+ #[test]
292
+ #[should_panic(expected = "Error(Contract, #11105)")] // WorkerOptionsError::InvalidLegacyOptionsType2
293
+ fn test_legacy_type2_invalid_size_too_short() {
294
+ let env = Env::default();
295
+ let mut options = Bytes::new(&env);
296
+ options.extend_from_slice(&LEGACY_OPTIONS_TYPE_2.to_be_bytes());
297
+ options.extend_from_slice(&hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")); // 64 bytes, no receiver
298
+ split_worker_options(&env, &options);
299
+ }
300
+
301
+ #[test]
302
+ #[should_panic(expected = "Error(Contract, #11105)")] // WorkerOptionsError::InvalidLegacyOptionsType2
303
+ fn test_legacy_type2_invalid_size_too_long() {
304
+ let env = Env::default();
305
+ let mut options = Bytes::new(&env);
306
+ options.extend_from_slice(&LEGACY_OPTIONS_TYPE_2.to_be_bytes());
307
+ options.extend_from_slice(&[0u8; 97]); // 97 bytes, too long
308
+ split_worker_options(&env, &options);
309
+ }
310
+
311
+ #[test]
312
+ #[should_panic(expected = "Error(Contract, #11108)")] // WorkerOptionsError::InvalidOptionType
313
+ fn test_unsupported_option_type() {
314
+ let env = Env::default();
315
+ let mut options = Bytes::new(&env);
316
+ options.extend_from_slice(&hex!("0063")); // Invalid type 99
317
+ options.extend_from_slice(&hex!("0000000000000000000000000000000000000000000000000000000000000000"));
318
+ split_worker_options(&env, &options);
319
+ }
@@ -0,0 +1,190 @@
1
+ use crate::errors::WorkerOptionsError;
2
+ use soroban_sdk::{assert_with_error, bytes, map, panic_with_error, Bytes, BytesN, Env, Map};
3
+ use utils::{buffer_reader::BufferReader, buffer_writer::BufferWriter, option_ext::OptionExt};
4
+
5
+ // Option type constants
6
+ pub const LEGACY_OPTIONS_TYPE_1: u16 = 1; // legacy options type 1
7
+ pub const LEGACY_OPTIONS_TYPE_2: u16 = 2; // legacy options type 2
8
+ pub const OPTIONS_TYPE_3: u16 = 3; // modern options type 3
9
+
10
+ // Worker ID constants
11
+ pub const EXECUTOR_WORKER_ID: u8 = 1;
12
+ pub const DVN_WORKER_ID: u8 = 2;
13
+
14
+ // Executor option type constants
15
+ pub const EXECUTOR_OPTION_TYPE_LZRECEIVE: u8 = 1;
16
+ pub const EXECUTOR_OPTION_TYPE_NATIVE_DROP: u8 = 2;
17
+
18
+ // DVN option byte offset (dvn_idx is the 4th byte of the option bytes)
19
+ pub const DVN_IDX_OFFSET: u32 = 3;
20
+
21
+ /// Splits worker options into separate executor and DVN option collections.
22
+ ///
23
+ /// This is the main entry point for processing worker options. It automatically
24
+ /// detects the option format version and delegates to the appropriate parser.
25
+ ///
26
+ /// Format detection:
27
+ /// - Type 3: Modern flexible format with multiple worker types
28
+ /// - Type 1 & 2: Legacy formats (executor options only, no DVN options)
29
+ ///
30
+ /// # Arguments
31
+ /// * `options` - The raw options bytes
32
+ ///
33
+ /// # Returns
34
+ /// A tuple of (executor_options, dvn_options_map)
35
+ pub fn split_worker_options(env: &Env, options: &Bytes) -> (Bytes, Map<u32, Bytes>) {
36
+ assert_with_error!(env, options.len() >= 2, WorkerOptionsError::InvalidOptions);
37
+
38
+ let mut reader = BufferReader::new(options);
39
+ let options_type = reader.read_u16();
40
+
41
+ if options_type == OPTIONS_TYPE_3 {
42
+ extract_type_3_options(env, &mut reader)
43
+ } else {
44
+ let executor_options = convert_legacy_options(env, &mut reader, options_type);
45
+ (executor_options, map![env])
46
+ }
47
+ }
48
+
49
+ /// Extracts options from the modern Type 3 format.
50
+ ///
51
+ /// Type 3 format supports multiple workers (executors and DVNs) with flexible
52
+ /// option structures. Each worker option includes its own size header.
53
+ ///
54
+ /// Format Structure:
55
+ /// ```text
56
+ /// [worker_option][worker_option][worker_option]...
57
+ ///
58
+ /// Worker Option:
59
+ /// [worker_id: u8][option_size: u16][option_data: bytes(option_size)]
60
+ /// ```
61
+ ///
62
+ /// # Arguments
63
+ /// * `options_reader` - Buffer reader positioned after the options type header
64
+ ///
65
+ /// # Returns
66
+ /// A tuple of (executor_options, dvn_options_map)
67
+ pub fn extract_type_3_options(env: &Env, options_reader: &mut BufferReader) -> (Bytes, Map<u32, Bytes>) {
68
+ let mut executor_options = bytes!(env);
69
+ let mut dvn_options = map![env];
70
+
71
+ while options_reader.remaining() > 0 {
72
+ let worker_id = options_reader.read_u8();
73
+ let option_size = options_reader.read_u16() as u32;
74
+
75
+ // Rewind to the start of the current option and read the complete option bytes
76
+ // 3 bytes for worker_id (1) + option_size (2)
77
+ let current_option = options_reader.rewind(3).read_bytes(3 + option_size);
78
+
79
+ match worker_id {
80
+ EXECUTOR_WORKER_ID => executor_options.append(&current_option),
81
+ DVN_WORKER_ID => append_dvn_option(&mut dvn_options, current_option),
82
+ _ => panic_with_error!(env, WorkerOptionsError::InvalidWorkerId),
83
+ }
84
+ }
85
+
86
+ (executor_options, dvn_options)
87
+ }
88
+
89
+ /// Converts legacy option formats (Type 1 and Type 2) to executor options in Type 3 format.
90
+ ///
91
+ /// Legacy formats only supported executor options and did not include DVN options.
92
+ ///
93
+ /// Legacy Format Details:
94
+ /// - **Type 1**: `[execution_gas: u256]` (32 bytes total)
95
+ /// - **Type 2**: `[execution_gas: u256][amount: u256][receiver: bytes(0-32)]` (64-96 bytes total)
96
+ ///
97
+ /// Note: Legacy formats use u256 for gas/amounts, but Type 3 uses u128.
98
+ /// The conversion will panic if values exceed u128 range.
99
+ ///
100
+ /// # Arguments
101
+ /// * `options` - Buffer reader positioned after the options type header
102
+ /// * `option_type` - The legacy option type (1 or 2)
103
+ ///
104
+ /// # Returns
105
+ /// Executor options in Type 3 format
106
+ pub fn convert_legacy_options(env: &Env, options: &mut BufferReader, option_type: u16) -> Bytes {
107
+ let mut executor_options = BufferWriter::new(env);
108
+ let options_size = options.remaining();
109
+
110
+ match option_type {
111
+ LEGACY_OPTIONS_TYPE_1 => {
112
+ assert_with_error!(env, options_size == 32, WorkerOptionsError::InvalidLegacyOptionsType1);
113
+ // Execution gas (u256 -> u128)
114
+ let execution_gas =
115
+ options.read_u256().to_u128().unwrap_or_panic(env, WorkerOptionsError::LegacyOptionsType1GasOverflow);
116
+
117
+ append_lz_receive_option(&mut executor_options, execution_gas);
118
+ }
119
+ LEGACY_OPTIONS_TYPE_2 => {
120
+ assert_with_error!(
121
+ env,
122
+ options_size > 64 && options_size <= 96,
123
+ WorkerOptionsError::InvalidLegacyOptionsType2
124
+ );
125
+ // Execution gas & amount (u256 -> u128)
126
+ let execution_gas =
127
+ options.read_u256().to_u128().unwrap_or_panic(env, WorkerOptionsError::LegacyOptionsType2GasOverflow);
128
+ let amount = options
129
+ .read_u256()
130
+ .to_u128()
131
+ .unwrap_or_panic(env, WorkerOptionsError::LegacyOptionsType2AmountOverflow);
132
+
133
+ let receiver = left_pad_to_bytes32(env, &options.read_bytes_until_end());
134
+
135
+ append_lz_receive_option(&mut executor_options, execution_gas);
136
+ append_native_drop_option(&mut executor_options, amount, &receiver);
137
+ }
138
+ _ => panic_with_error!(env, WorkerOptionsError::InvalidOptionType),
139
+ }
140
+
141
+ // Ensure all bytes were consumed
142
+ assert_with_error!(env, options.remaining() == 0, WorkerOptionsError::InvalidOptions);
143
+ executor_options.to_bytes()
144
+ }
145
+
146
+ // ========================================================
147
+ // Internal Helper Functions
148
+ // ========================================================
149
+
150
+ /// Efficiently groups DVN options by index.
151
+ ///
152
+ /// Searches for existing DVN options with the same index and concatenates them,
153
+ /// or creates a new entry if this is the first option for this DVN index.
154
+ fn append_dvn_option(dvn_options: &mut Map<u32, Bytes>, option_bytes: Bytes) {
155
+ let dvn_idx = option_bytes.get(DVN_IDX_OFFSET).unwrap() as u32;
156
+ if dvn_options.contains_key(dvn_idx) {
157
+ let mut existing = dvn_options.get(dvn_idx).unwrap();
158
+ existing.append(&option_bytes);
159
+ dvn_options.set(dvn_idx, existing);
160
+ } else {
161
+ dvn_options.set(dvn_idx, option_bytes);
162
+ }
163
+ }
164
+
165
+ /// Appends a LzReceive option to the executor options bytes.
166
+ /// Format: [worker_id][option_size][option_type][execution_gas]
167
+ fn append_lz_receive_option(buf: &mut BufferWriter, execution_gas: u128) {
168
+ buf.write_u8(EXECUTOR_WORKER_ID) // worker_id (1 byte)
169
+ .write_u16(17) // option_size: option_type(1) + data(16) = 17 bytes
170
+ .write_u8(EXECUTOR_OPTION_TYPE_LZRECEIVE) // option_type (1 byte)
171
+ .write_u128(execution_gas); // execution gas data (16 bytes)
172
+ }
173
+
174
+ /// Appends a native drop option to the executor options bytes.
175
+ /// Format: [worker_id][option_size][option_type][amount][receiver]
176
+ fn append_native_drop_option(buf: &mut BufferWriter, amount: u128, receiver: &BytesN<32>) {
177
+ buf.write_u8(EXECUTOR_WORKER_ID) // worker_id (1 byte)
178
+ .write_u16(49) // option_size: option_type(1) + amount(16) + receiver(32) = 49 bytes
179
+ .write_u8(EXECUTOR_OPTION_TYPE_NATIVE_DROP) // option_type (1 byte)
180
+ .write_u128(amount) // drop amount (16 bytes)
181
+ .write_bytes_n(receiver); // receiver address (32 bytes)
182
+ }
183
+
184
+ /// Converts Bytes to BytesN<32> with left-padding (zeros at the beginning)
185
+ fn left_pad_to_bytes32(env: &Env, bytes: &Bytes) -> BytesN<32> {
186
+ assert_with_error!(env, bytes.len() <= 32, WorkerOptionsError::InvalidBytesLength);
187
+ let mut buf = [0u8; 32];
188
+ bytes.copy_into_slice(&mut buf[32 - bytes.len() as usize..]);
189
+ BytesN::from_array(env, &buf)
190
+ }
@@ -0,0 +1,26 @@
1
+ [package]
2
+ name = "simple-message-lib"
3
+ version.workspace = true
4
+ edition.workspace = true
5
+ license.workspace = true
6
+ publish = false
7
+
8
+ [lib]
9
+ crate-type = ["cdylib", "rlib"]
10
+ doctest = false
11
+
12
+ [features]
13
+ library = []
14
+ testutils = []
15
+
16
+ [dependencies]
17
+ cfg-if = { workspace = true }
18
+ soroban-sdk = { workspace = true }
19
+ # workspace dependencies
20
+ common-macros = { workspace = true }
21
+ utils = { workspace = true }
22
+ endpoint-v2 = { workspace = true, features = ["library"] }
23
+ message-lib-common = { workspace = true }
24
+
25
+ [dev-dependencies]
26
+ soroban-sdk = { workspace = true, features = ["testutils"] }
@@ -0,0 +1,11 @@
1
+ use common_macros::contract_error;
2
+
3
+ #[contract_error]
4
+ pub enum SimpleMessageLibError {
5
+ NotImplemented,
6
+ NativeFeeNotSet,
7
+ ZROFeeNotSet,
8
+ ZROTokenNotSet,
9
+ OnlyWhitelistedCaller,
10
+ UnableToConvertAddress,
11
+ }
@@ -0,0 +1,14 @@
1
+ #![no_std]
2
+
3
+ cfg_if::cfg_if! {
4
+ if #[cfg(any(not(feature = "library"), feature = "testutils"))] {
5
+ mod errors;
6
+ mod simple_message_lib;
7
+ mod storage;
8
+
9
+ pub use simple_message_lib::{SimpleMessageLib, SimpleMessageLibClient};
10
+ }
11
+ }
12
+
13
+ #[cfg(test)]
14
+ mod test;