@layerzerolabs/protocol-stellar-v2 0.2.13 → 0.2.18

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 (435) hide show
  1. package/.turbo/turbo-build.log +484 -337
  2. package/.turbo/turbo-lint.log +126 -56
  3. package/.turbo/turbo-test.log +1403 -984
  4. package/Cargo.lock +142 -3
  5. package/Cargo.toml +5 -1
  6. package/contracts/ERROR_SPEC.md +44 -0
  7. package/contracts/common-macros/src/auth.rs +113 -0
  8. package/contracts/common-macros/src/contract_ttl.rs +84 -0
  9. package/contracts/common-macros/src/lib.rs +219 -29
  10. package/contracts/common-macros/src/lz_contract.rs +83 -0
  11. package/contracts/common-macros/src/storage.rs +1 -1
  12. package/contracts/common-macros/src/tests/{ownable.rs → auth.rs} +48 -15
  13. package/contracts/common-macros/src/tests/contract_ttl.rs +662 -0
  14. package/contracts/common-macros/src/tests/mod.rs +3 -2
  15. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__auth__snapshot_generated_multisig_code.snap +20 -0
  16. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__auth__snapshot_generated_ownable_code.snap +24 -0
  17. package/contracts/common-macros/src/tests/snapshots/{common_macros__tests__ownable__snapshot_only_owner_preserves_function_signature.snap → common_macros__tests__auth__snapshot_only_auth_preserves_function_signature.snap} +4 -4
  18. package/contracts/common-macros/src/tests/snapshots/{common_macros__tests__contract_impl__snapshot_generated_contract_impl_code.snap → common_macros__tests__contract_ttl__snapshot_generated_contractimpl_code.snap} +26 -10
  19. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__contract_ttl__snapshot_generated_contracttrait_code.snap +69 -0
  20. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__storage__snapshot_generated_storage_code.snap +48 -48
  21. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__ttl_configurable__snapshot_generated_ttl_configurable_code.snap +7 -41
  22. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__upgradeable__snapshot_generated_upgradeable_code.snap +21 -0
  23. package/contracts/common-macros/src/tests/upgradeable.rs +31 -0
  24. package/contracts/common-macros/src/ttl_configurable.rs +21 -66
  25. package/contracts/common-macros/src/ttl_extendable.rs +36 -0
  26. package/contracts/common-macros/src/upgradeable.rs +76 -0
  27. package/contracts/common-macros/src/utils.rs +9 -0
  28. package/contracts/endpoint-v2/src/constants.rs +4 -4
  29. package/contracts/endpoint-v2/src/endpoint_v2.rs +58 -36
  30. package/contracts/endpoint-v2/src/errors.rs +4 -3
  31. package/contracts/endpoint-v2/src/events.rs +1 -1
  32. package/contracts/endpoint-v2/src/message_lib_manager.rs +18 -5
  33. package/contracts/endpoint-v2/src/messaging_channel.rs +11 -1
  34. package/contracts/endpoint-v2/src/messaging_composer.rs +11 -1
  35. package/contracts/endpoint-v2/src/storage.rs +1 -1
  36. package/contracts/endpoint-v2/src/tests/endpoint_setup.rs +175 -8
  37. package/contracts/endpoint-v2/src/tests/endpoint_v2/build_outbound_packet.rs +76 -0
  38. package/contracts/endpoint-v2/src/tests/endpoint_v2/clear.rs +342 -159
  39. package/contracts/endpoint-v2/src/tests/endpoint_v2/delegate.rs +3 -15
  40. package/contracts/endpoint-v2/src/tests/endpoint_v2/initializable.rs +20 -31
  41. package/contracts/endpoint-v2/src/tests/endpoint_v2/lz_receive_alert.rs +126 -164
  42. package/contracts/endpoint-v2/src/tests/endpoint_v2/mod.rs +1 -0
  43. package/contracts/endpoint-v2/src/tests/endpoint_v2/native_token.rs +0 -1
  44. package/contracts/endpoint-v2/src/tests/endpoint_v2/owner.rs +0 -1
  45. package/contracts/endpoint-v2/src/tests/endpoint_v2/pay_messaging_fees.rs +311 -304
  46. package/contracts/endpoint-v2/src/tests/endpoint_v2/quote.rs +423 -96
  47. package/contracts/endpoint-v2/src/tests/endpoint_v2/recover_token.rs +1 -1
  48. package/contracts/endpoint-v2/src/tests/endpoint_v2/require_oapp_auth.rs +47 -20
  49. package/contracts/endpoint-v2/src/tests/endpoint_v2/send.rs +373 -403
  50. package/contracts/endpoint-v2/src/tests/endpoint_v2/set_delegate.rs +96 -22
  51. package/contracts/endpoint-v2/src/tests/endpoint_v2/set_zro.rs +62 -10
  52. package/contracts/endpoint-v2/src/tests/endpoint_v2/transfer_ownership.rs +4 -4
  53. package/contracts/endpoint-v2/src/tests/endpoint_v2/ttl_config.rs +8 -11
  54. package/contracts/endpoint-v2/src/tests/endpoint_v2/verifiable.rs +81 -30
  55. package/contracts/endpoint-v2/src/tests/endpoint_v2/verify.rs +209 -76
  56. package/contracts/endpoint-v2/src/tests/endpoint_v2/zro.rs +0 -1
  57. package/contracts/endpoint-v2/src/tests/message_lib_manager/default_receive_library.rs +24 -0
  58. package/contracts/endpoint-v2/src/tests/message_lib_manager/default_receive_library_timeout.rs +40 -0
  59. package/contracts/endpoint-v2/src/tests/message_lib_manager/default_send_library.rs +24 -0
  60. package/contracts/endpoint-v2/src/tests/message_lib_manager/get_config.rs +108 -0
  61. package/contracts/endpoint-v2/src/tests/message_lib_manager/get_library_index.rs +52 -0
  62. package/contracts/endpoint-v2/src/tests/message_lib_manager/get_receive_library.rs +92 -0
  63. package/contracts/endpoint-v2/src/tests/message_lib_manager/get_registered_libraries.rs +74 -0
  64. package/contracts/endpoint-v2/src/tests/message_lib_manager/get_send_library.rs +83 -0
  65. package/contracts/endpoint-v2/src/tests/message_lib_manager/is_registered_library.rs +32 -0
  66. package/contracts/endpoint-v2/src/tests/message_lib_manager/is_supported_eid.rs +28 -0
  67. package/contracts/endpoint-v2/src/tests/message_lib_manager/is_valid_receive_library.rs +261 -0
  68. package/contracts/endpoint-v2/src/tests/message_lib_manager/mod.rs +16 -0
  69. package/contracts/endpoint-v2/src/tests/message_lib_manager/receive_library_timeout.rs +62 -0
  70. package/contracts/endpoint-v2/src/tests/message_lib_manager/register_library.rs +65 -43
  71. package/contracts/endpoint-v2/src/tests/message_lib_manager/registered_libraries_count.rs +42 -0
  72. package/contracts/endpoint-v2/src/tests/message_lib_manager/require_receive_lib_for_eid.rs +61 -0
  73. package/contracts/endpoint-v2/src/tests/message_lib_manager/require_registered.rs +4 -6
  74. package/contracts/endpoint-v2/src/tests/message_lib_manager/require_send_lib_for_eid.rs +59 -0
  75. package/contracts/endpoint-v2/src/tests/message_lib_manager/require_supported_eid.rs +16 -2
  76. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_config.rs +155 -51
  77. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_default_receive_lib_timeout.rs +114 -92
  78. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_default_receive_library.rs +235 -132
  79. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_default_send_library.rs +93 -87
  80. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_receive_library.rs +346 -245
  81. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_receive_library_timeout.rs +406 -60
  82. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_send_library.rs +252 -78
  83. package/contracts/endpoint-v2/src/tests/message_lib_manager/timeout.rs +102 -0
  84. package/contracts/endpoint-v2/src/tests/messaging_channel/burn.rs +212 -273
  85. package/contracts/endpoint-v2/src/tests/messaging_channel/clear_payload.rs +203 -0
  86. package/contracts/endpoint-v2/src/tests/messaging_channel/inbound.rs +94 -0
  87. package/contracts/endpoint-v2/src/tests/messaging_channel/inbound_nonce.rs +78 -248
  88. package/contracts/endpoint-v2/src/tests/messaging_channel/inbound_payload_hash.rs +7 -282
  89. package/contracts/endpoint-v2/src/tests/messaging_channel/lazy_inbound_nonce.rs +6 -274
  90. package/contracts/endpoint-v2/src/tests/messaging_channel/mod.rs +3 -2
  91. package/contracts/endpoint-v2/src/tests/messaging_channel/next_guid.rs +86 -178
  92. package/contracts/endpoint-v2/src/tests/messaging_channel/nilify.rs +328 -212
  93. package/contracts/endpoint-v2/src/tests/messaging_channel/outbound.rs +68 -0
  94. package/contracts/endpoint-v2/src/tests/messaging_channel/outbound_nonce.rs +6 -209
  95. package/contracts/endpoint-v2/src/tests/messaging_channel/skip.rs +207 -159
  96. package/contracts/endpoint-v2/src/tests/messaging_composer/clear_compose.rs +142 -153
  97. package/contracts/endpoint-v2/src/tests/messaging_composer/compose_queue.rs +6 -179
  98. package/contracts/endpoint-v2/src/tests/messaging_composer/lz_compose_alert.rs +163 -221
  99. package/contracts/endpoint-v2/src/tests/messaging_composer/send_compose.rs +90 -121
  100. package/contracts/endpoint-v2/src/tests/mock.rs +18 -4
  101. package/contracts/endpoint-v2/src/tests/util/build_payload.rs +4 -70
  102. package/contracts/endpoint-v2/src/tests/util/compute_guid.rs +2 -1
  103. package/contracts/endpoint-v2/src/tests/util/keccak256.rs +17 -106
  104. package/contracts/layerzero-views/Cargo.toml +35 -0
  105. package/contracts/layerzero-views/src/errors.rs +10 -0
  106. package/contracts/layerzero-views/src/layerzero_view.rs +226 -0
  107. package/contracts/layerzero-views/src/lib.rs +38 -0
  108. package/contracts/layerzero-views/src/storage.rs +18 -0
  109. package/contracts/layerzero-views/src/tests/layerzero_view_tests.rs +423 -0
  110. package/contracts/layerzero-views/src/tests/mod.rs +4 -0
  111. package/contracts/layerzero-views/src/tests/setup.rs +377 -0
  112. package/contracts/layerzero-views/src/types.rs +50 -0
  113. package/contracts/macro-integration-tests/Cargo.toml +30 -0
  114. package/contracts/macro-integration-tests/src/lib.rs +1 -0
  115. package/contracts/macro-integration-tests/tests/runtime/ownable/initialization.rs +62 -0
  116. package/contracts/macro-integration-tests/tests/runtime/ownable/mod.rs +22 -0
  117. package/contracts/macro-integration-tests/tests/runtime/ownable/only_auth_guard.rs +97 -0
  118. package/contracts/macro-integration-tests/tests/runtime/ownable/ownership_transfer.rs +101 -0
  119. package/contracts/macro-integration-tests/tests/runtime/storage/keyed_roundtrip.rs +225 -0
  120. package/contracts/macro-integration-tests/tests/runtime/storage/mod.rs +4 -0
  121. package/contracts/macro-integration-tests/tests/runtime/storage/name_override_runtime.rs +52 -0
  122. package/contracts/macro-integration-tests/tests/runtime/storage/ttl_extension.rs +261 -0
  123. package/contracts/macro-integration-tests/tests/runtime/storage/unkeyed_roundtrip.rs +137 -0
  124. package/contracts/macro-integration-tests/tests/runtime/ttl_configurable/configuration.rs +113 -0
  125. package/contracts/macro-integration-tests/tests/runtime/ttl_configurable/freeze.rs +139 -0
  126. package/contracts/macro-integration-tests/tests/runtime/ttl_configurable/mod.rs +2 -0
  127. package/contracts/macro-integration-tests/tests/runtime.rs +5 -0
  128. package/contracts/macro-integration-tests/tests/ui/error/fail/attr_not_empty.rs +12 -0
  129. package/contracts/macro-integration-tests/tests/ui/error/fail/attr_not_empty.stderr +7 -0
  130. package/contracts/macro-integration-tests/tests/ui/error/fail/decreasing_discriminant.rs +12 -0
  131. package/contracts/macro-integration-tests/tests/ui/error/fail/decreasing_discriminant.stderr +7 -0
  132. package/contracts/macro-integration-tests/tests/ui/error/fail/non_int_discriminant.rs +21 -0
  133. package/contracts/macro-integration-tests/tests/ui/error/fail/non_int_discriminant.stderr +7 -0
  134. package/contracts/macro-integration-tests/tests/ui/error/fail/non_unit_variant.rs +13 -0
  135. package/contracts/macro-integration-tests/tests/ui/error/fail/non_unit_variant.stderr +7 -0
  136. package/contracts/macro-integration-tests/tests/ui/error/pass/attr_on_variant_allowed.rs +20 -0
  137. package/contracts/macro-integration-tests/tests/ui/error/pass/basic_auto_discriminants.rs +15 -0
  138. package/contracts/macro-integration-tests/tests/ui/error/pass/mixed_discriminants.rs +16 -0
  139. package/contracts/macro-integration-tests/tests/ui/ownable/fail/only_auth_missing_env.rs +22 -0
  140. package/contracts/macro-integration-tests/tests/ui/ownable/fail/only_auth_missing_env.stderr +16 -0
  141. package/contracts/macro-integration-tests/tests/ui/ownable/pass/minimal_contract.rs +26 -0
  142. package/contracts/macro-integration-tests/tests/ui/ownable/pass/namespacing_and_imports.rs +21 -0
  143. package/contracts/macro-integration-tests/tests/ui/ownable/pass/only_auth_env_param_variants.rs +46 -0
  144. package/contracts/macro-integration-tests/tests/ui/storage/fail/invalid_storage_type_param.rs +13 -0
  145. package/contracts/macro-integration-tests/tests/ui/storage/fail/invalid_storage_type_param.stderr +7 -0
  146. package/contracts/macro-integration-tests/tests/ui/storage/fail/missing_storage_type_param.rs +13 -0
  147. package/contracts/macro-integration-tests/tests/ui/storage/fail/missing_storage_type_param.stderr +7 -0
  148. package/contracts/macro-integration-tests/tests/ui/storage/fail/multiple_storage_kinds.rs +10 -0
  149. package/contracts/macro-integration-tests/tests/ui/storage/fail/multiple_storage_kinds.stderr +7 -0
  150. package/contracts/macro-integration-tests/tests/ui/storage/fail/multiple_type_params.rs +12 -0
  151. package/contracts/macro-integration-tests/tests/ui/storage/fail/multiple_type_params.stderr +7 -0
  152. package/contracts/macro-integration-tests/tests/ui/storage/fail/no_ttl_extension_on_non_persistent.rs +10 -0
  153. package/contracts/macro-integration-tests/tests/ui/storage/fail/no_ttl_extension_on_non_persistent.stderr +7 -0
  154. package/contracts/macro-integration-tests/tests/ui/storage/fail/non_enum_input.rs +10 -0
  155. package/contracts/macro-integration-tests/tests/ui/storage/fail/non_enum_input.stderr +7 -0
  156. package/contracts/macro-integration-tests/tests/ui/storage/fail/storage_attr_rejects_args.rs +12 -0
  157. package/contracts/macro-integration-tests/tests/ui/storage/fail/storage_attr_rejects_args.stderr +7 -0
  158. package/contracts/macro-integration-tests/tests/ui/storage/fail/tuple_variant_rejected.rs +13 -0
  159. package/contracts/macro-integration-tests/tests/ui/storage/fail/tuple_variant_rejected.stderr +7 -0
  160. package/contracts/macro-integration-tests/tests/ui/storage/fail/unknown_variant_attr.rs +13 -0
  161. package/contracts/macro-integration-tests/tests/ui/storage/fail/unknown_variant_attr.stderr +7 -0
  162. package/contracts/macro-integration-tests/tests/ui/storage/pass/default_value_on_variant.rs +14 -0
  163. package/contracts/macro-integration-tests/tests/ui/storage/pass/enum_instance_unit_basic.rs +14 -0
  164. package/contracts/macro-integration-tests/tests/ui/storage/pass/enum_persistent_named_fields_keyed.rs +16 -0
  165. package/contracts/macro-integration-tests/tests/ui/storage/pass/enum_temporary_unit_option.rs +15 -0
  166. package/contracts/macro-integration-tests/tests/ui/storage/pass/name_override.rs +14 -0
  167. package/contracts/macro-integration-tests/tests/ui/storage/pass/no_auto_ttl_extension.rs +19 -0
  168. package/contracts/macro-integration-tests/tests/ui/storage/pass/ttl_provider_basic.rs +15 -0
  169. package/contracts/macro-integration-tests/tests/ui/ttl_configurable/pass/minimal_contract.rs +44 -0
  170. package/contracts/macro-integration-tests/tests/ui_error.rs +11 -0
  171. package/contracts/macro-integration-tests/tests/ui_ownable.rs +11 -0
  172. package/contracts/macro-integration-tests/tests/ui_storage.rs +11 -0
  173. package/contracts/macro-integration-tests/tests/ui_ttl_configurable.rs +12 -0
  174. package/contracts/message-libs/blocked-message-lib/src/lib.rs +17 -17
  175. package/contracts/message-libs/message-lib-common/src/errors.rs +7 -2
  176. package/contracts/message-libs/message-lib-common/src/tests/packet_codec_v1/decode_packet_header.rs +64 -0
  177. package/contracts/message-libs/message-lib-common/src/tests/packet_codec_v1/encode_packet.rs +58 -0
  178. package/contracts/message-libs/message-lib-common/src/tests/packet_codec_v1/encode_packet_header.rs +138 -0
  179. package/contracts/message-libs/message-lib-common/src/tests/packet_codec_v1/mod.rs +6 -0
  180. package/contracts/message-libs/message-lib-common/src/tests/packet_codec_v1/payload.rs +30 -0
  181. package/contracts/message-libs/message-lib-common/src/tests/packet_codec_v1/payload_hash.rs +15 -0
  182. package/contracts/message-libs/message-lib-common/src/tests/packet_codec_v1/test_helper.rs +39 -0
  183. package/contracts/message-libs/message-lib-common/src/tests/worker_options/append_dvn_option.rs +57 -0
  184. package/contracts/message-libs/message-lib-common/src/tests/worker_options/append_lz_receive_option.rs +49 -0
  185. package/contracts/message-libs/message-lib-common/src/tests/worker_options/append_native_drop_option.rs +73 -0
  186. package/contracts/message-libs/message-lib-common/src/tests/worker_options/convert_legacy_options.rs +280 -0
  187. package/contracts/message-libs/message-lib-common/src/tests/worker_options/extract_type_3_options.rs +126 -0
  188. package/contracts/message-libs/message-lib-common/src/tests/worker_options/left_pad_to_bytes32.rs +48 -0
  189. package/contracts/message-libs/message-lib-common/src/tests/worker_options/mod.rs +7 -0
  190. package/contracts/message-libs/message-lib-common/src/tests/worker_options/split_worker_options.rs +139 -0
  191. package/contracts/message-libs/message-lib-common/src/worker_options.rs +31 -1
  192. package/contracts/message-libs/simple-message-lib/src/simple_message_lib.rs +7 -9
  193. package/contracts/message-libs/treasury/src/errors.rs +2 -3
  194. package/contracts/message-libs/treasury/src/events.rs +1 -1
  195. package/contracts/message-libs/treasury/src/interfaces/zro_fee_lib.rs +2 -2
  196. package/contracts/message-libs/treasury/src/lib.rs +3 -3
  197. package/contracts/message-libs/treasury/src/storage.rs +3 -1
  198. package/contracts/message-libs/treasury/src/tests/treasury_tests.rs +1 -1
  199. package/contracts/message-libs/treasury/src/treasury.rs +23 -26
  200. package/contracts/message-libs/uln-302/Cargo.toml +1 -1
  201. package/contracts/message-libs/uln-302/src/errors.rs +0 -5
  202. package/contracts/message-libs/uln-302/src/events.rs +5 -6
  203. package/contracts/message-libs/uln-302/src/receive_uln.rs +37 -56
  204. package/contracts/message-libs/uln-302/src/send_uln.rs +112 -138
  205. package/contracts/message-libs/uln-302/src/storage.rs +5 -5
  206. package/contracts/message-libs/uln-302/src/tests/receive_uln302/effective_receive_uln_config.rs +5 -7
  207. package/contracts/message-libs/uln-302/src/tests/receive_uln302/set_default_receive_uln_configs.rs +3 -3
  208. package/contracts/message-libs/uln-302/src/tests/send_uln302/effective_send_uln_config.rs +6 -9
  209. package/contracts/message-libs/uln-302/src/tests/send_uln302/set_default_executor_configs.rs +2 -2
  210. package/contracts/message-libs/uln-302/src/tests/send_uln302/set_default_send_uln_configs.rs +3 -3
  211. package/contracts/message-libs/uln-302/src/tests/setup.rs +9 -0
  212. package/contracts/message-libs/uln-302/src/tests/testing_utils.rs +5 -0
  213. package/contracts/message-libs/uln-302/src/tests/uln302/get_app_receive_uln_config.rs +1 -2
  214. package/contracts/message-libs/uln-302/src/tests/uln302/get_app_send_uln_config.rs +1 -2
  215. package/contracts/message-libs/uln-302/src/tests/uln302/set_config.rs +37 -55
  216. package/contracts/message-libs/uln-302/src/uln302.rs +10 -25
  217. package/contracts/oapps/counter/Cargo.toml +14 -1
  218. package/contracts/oapps/counter/integration_tests/mod.rs +4 -1
  219. package/contracts/oapps/counter/integration_tests/setup_sml.rs +169 -0
  220. package/contracts/oapps/counter/integration_tests/setup_uln.rs +997 -0
  221. package/contracts/oapps/counter/integration_tests/signing.rs +62 -0
  222. package/contracts/oapps/counter/integration_tests/test_with_sml.rs +24 -55
  223. package/contracts/oapps/counter/integration_tests/test_with_uln.rs +314 -0
  224. package/contracts/oapps/counter/integration_tests/utils.rs +196 -53
  225. package/contracts/oapps/counter/src/counter.rs +67 -44
  226. package/contracts/oapps/counter/src/tests/mod.rs +0 -13
  227. package/contracts/oapps/counter/src/tests/test_counter.rs +5 -7
  228. package/contracts/oapps/oapp/src/errors.rs +5 -1
  229. package/contracts/oapps/oapp/src/macro_tests/test_macros.rs +318 -221
  230. package/contracts/oapps/oapp/src/oapp_core.rs +36 -21
  231. package/contracts/oapps/oapp/src/oapp_options_type3.rs +48 -12
  232. package/contracts/oapps/oapp/src/oapp_receiver.rs +106 -41
  233. package/contracts/oapps/oapp/src/oapp_sender.rs +26 -34
  234. package/contracts/oapps/oapp/src/tests/test_oapp_core.rs +9 -9
  235. package/contracts/oapps/oapp/src/tests/test_oapp_options_type3.rs +25 -18
  236. package/contracts/oapps/oapp/src/tests/test_oapp_receiver.rs +7 -8
  237. package/contracts/oapps/oapp/src/tests/test_oapp_sender.rs +14 -16
  238. package/contracts/oapps/oapp-macros/src/generators.rs +128 -0
  239. package/contracts/oapps/oapp-macros/src/lib.rs +211 -0
  240. package/contracts/oapps/oft/integration-tests/setup.rs +34 -9
  241. package/contracts/oapps/oft/integration-tests/utils.rs +1 -1
  242. package/contracts/oapps/oft/src/errors.rs +6 -1
  243. package/contracts/oapps/oft/src/extensions/oft_fee.rs +13 -13
  244. package/contracts/oapps/oft/src/extensions/pausable.rs +5 -5
  245. package/contracts/oapps/oft/src/extensions/rate_limiter.rs +23 -23
  246. package/contracts/oapps/oft/src/lib.rs +4 -2
  247. package/contracts/oapps/oft/src/oft.rs +31 -71
  248. package/contracts/oapps/oft/src/oft_impl.rs +201 -0
  249. package/contracts/oapps/oft/src/oft_types/lock_unlock.rs +2 -4
  250. package/contracts/oapps/oft/src/oft_types/mint_burn.rs +1 -4
  251. package/contracts/oapps/oft/src/storage.rs +2 -0
  252. package/contracts/oapps/oft/src/tests/extensions/setup.rs +60 -31
  253. package/contracts/oapps/oft/src/tests/extensions/test_oft_fee.rs +5 -3
  254. package/contracts/oapps/oft/src/tests/extensions/test_pausable.rs +5 -3
  255. package/contracts/oapps/oft/src/tests/extensions/test_rate_limiter.rs +6 -4
  256. package/contracts/oapps/oft/src/tests/test_decimals.rs +2 -2
  257. package/contracts/oapps/oft/src/tests/test_oft_msg_codec.rs +1 -2
  258. package/contracts/oapps/oft/src/tests/test_send.rs +4 -4
  259. package/contracts/oapps/oft/src/tests/test_utils.rs +122 -81
  260. package/contracts/oapps/oft/src/types.rs +20 -0
  261. package/contracts/oapps/oft-std/Cargo.toml +6 -0
  262. package/contracts/oapps/oft-std/integration-tests/extensions/mod.rs +3 -0
  263. package/contracts/oapps/oft-std/integration-tests/extensions/test_oft_fee.rs +157 -0
  264. package/contracts/oapps/oft-std/integration-tests/extensions/test_pausable.rs +162 -0
  265. package/contracts/oapps/oft-std/integration-tests/extensions/test_rate_limiter.rs +186 -0
  266. package/contracts/oapps/oft-std/integration-tests/mod.rs +3 -0
  267. package/contracts/oapps/{counter/integration_tests → oft-std/integration-tests}/setup.rs +76 -30
  268. package/contracts/oapps/oft-std/integration-tests/utils.rs +427 -0
  269. package/contracts/oapps/oft-std/src/lib.rs +12 -1
  270. package/contracts/oapps/oft-std/src/oft.rs +141 -26
  271. package/contracts/upgrader/Cargo.toml +19 -0
  272. package/contracts/upgrader/src/lib.rs +96 -0
  273. package/contracts/upgrader/src/tests/mod.rs +1 -0
  274. package/contracts/upgrader/src/tests/test_data/test_upgradeable_contract1.wasm +0 -0
  275. package/contracts/upgrader/src/tests/test_data/test_upgradeable_contract2.wasm +0 -0
  276. package/contracts/upgrader/src/tests/test_upgrader.rs +120 -0
  277. package/contracts/utils/src/auth.rs +44 -0
  278. package/contracts/utils/src/errors.rs +32 -5
  279. package/contracts/utils/src/lib.rs +5 -1
  280. package/contracts/utils/src/multisig.rs +211 -0
  281. package/contracts/utils/src/ownable.rs +50 -60
  282. package/contracts/utils/src/tests/buffer_reader.rs +6 -6
  283. package/contracts/utils/src/tests/buffer_writer.rs +6 -6
  284. package/contracts/utils/src/tests/bytes_ext.rs +2 -4
  285. package/contracts/utils/src/tests/mod.rs +4 -1
  286. package/contracts/utils/src/tests/multisig.rs +731 -0
  287. package/contracts/utils/src/tests/option_ext.rs +18 -0
  288. package/contracts/utils/src/tests/ownable.rs +22 -70
  289. package/contracts/utils/src/tests/ttl_configurable.rs +607 -0
  290. package/contracts/utils/src/tests/upgradeable.rs +290 -0
  291. package/contracts/utils/src/ttl_configurable.rs +153 -0
  292. package/contracts/utils/src/ttl_extendable.rs +27 -0
  293. package/contracts/utils/src/upgradeable.rs +56 -0
  294. package/contracts/workers/dvn/Cargo.toml +2 -2
  295. package/contracts/workers/dvn/src/auth.rs +24 -35
  296. package/contracts/workers/dvn/src/dvn.rs +23 -14
  297. package/contracts/workers/dvn/src/errors.rs +1 -7
  298. package/contracts/workers/dvn/src/events.rs +1 -14
  299. package/contracts/workers/dvn/src/interfaces/dvn.rs +2 -2
  300. package/contracts/workers/dvn/src/interfaces/mod.rs +0 -2
  301. package/contracts/workers/dvn/src/storage.rs +3 -13
  302. package/contracts/workers/dvn/src/tests/auth.rs +4 -4
  303. package/contracts/workers/dvn/src/tests/dvn.rs +1 -2
  304. package/contracts/workers/dvn/src/tests/multisig/set_signer.rs +7 -8
  305. package/contracts/workers/dvn/src/tests/multisig/set_threshold.rs +11 -8
  306. package/contracts/workers/dvn/src/tests/multisig/verify_signatures.rs +11 -12
  307. package/contracts/workers/dvn/src/tests/setup.rs +5 -5
  308. package/contracts/workers/dvn-fee-lib/Cargo.toml +0 -1
  309. package/contracts/workers/dvn-fee-lib/src/dvn_fee_lib.rs +45 -16
  310. package/contracts/workers/dvn-fee-lib/src/errors.rs +3 -2
  311. package/contracts/workers/dvn-fee-lib/src/lib.rs +5 -11
  312. package/contracts/workers/dvn-fee-lib/src/tests/dvn_fee_lib.rs +30 -16
  313. package/contracts/workers/executor/src/auth.rs +80 -16
  314. package/contracts/workers/executor/src/executor.rs +17 -29
  315. package/contracts/workers/executor/src/storage.rs +2 -9
  316. package/contracts/workers/executor-fee-lib/Cargo.toml +1 -1
  317. package/contracts/workers/executor-fee-lib/src/errors.rs +9 -7
  318. package/contracts/workers/executor-fee-lib/src/executor_fee_lib.rs +153 -121
  319. package/contracts/workers/executor-helper/Cargo.toml +1 -6
  320. package/contracts/workers/executor-helper/src/executor_helper.rs +53 -73
  321. package/contracts/workers/executor-helper/src/lib.rs +1 -7
  322. package/contracts/workers/price-feed/Cargo.toml +1 -2
  323. package/contracts/workers/price-feed/src/errors.rs +3 -2
  324. package/contracts/workers/price-feed/src/lib.rs +5 -6
  325. package/contracts/workers/price-feed/src/price_feed.rs +42 -23
  326. package/contracts/workers/worker/Cargo.toml +4 -0
  327. package/contracts/workers/worker/src/errors.rs +4 -0
  328. package/contracts/workers/worker/src/interfaces/price_feed.rs +3 -3
  329. package/contracts/workers/worker/src/lib.rs +2 -2
  330. package/contracts/workers/worker/src/tests/mod.rs +4 -0
  331. package/contracts/workers/worker/src/tests/setup.rs +147 -0
  332. package/contracts/workers/worker/src/tests/worker.rs +502 -0
  333. package/contracts/workers/worker/src/worker.rs +28 -30
  334. package/package.json +8 -5
  335. package/sdk/.turbo/turbo-build.log +1 -0
  336. package/sdk/.turbo/turbo-test.log +1009 -0
  337. package/sdk/dist/generated/bml.d.ts +104 -37
  338. package/sdk/dist/generated/bml.js +83 -42
  339. package/sdk/dist/generated/counter.d.ts +334 -175
  340. package/sdk/dist/generated/counter.js +109 -63
  341. package/sdk/dist/generated/dvn.d.ts +1985 -0
  342. package/sdk/dist/generated/dvn.js +326 -0
  343. package/sdk/dist/generated/dvn_fee_lib.d.ts +690 -0
  344. package/sdk/dist/generated/dvn_fee_lib.js +163 -0
  345. package/sdk/dist/generated/endpoint.d.ts +155 -46
  346. package/sdk/dist/generated/endpoint.js +93 -50
  347. package/sdk/dist/generated/executor.d.ts +1841 -0
  348. package/sdk/dist/generated/executor.js +312 -0
  349. package/sdk/dist/generated/executor_fee_lib.d.ts +1083 -0
  350. package/sdk/dist/generated/executor_fee_lib.js +255 -0
  351. package/sdk/dist/generated/executor_helper.d.ts +981 -0
  352. package/sdk/dist/generated/executor_helper.js +236 -0
  353. package/sdk/dist/generated/oft_std.d.ts +1722 -0
  354. package/sdk/dist/generated/oft_std.js +316 -0
  355. package/sdk/dist/generated/price_feed.d.ts +1077 -0
  356. package/sdk/dist/generated/price_feed.js +210 -0
  357. package/sdk/dist/generated/sml.d.ts +171 -56
  358. package/sdk/dist/generated/sml.js +111 -62
  359. package/sdk/dist/generated/treasury.d.ts +896 -0
  360. package/sdk/dist/generated/treasury.js +219 -0
  361. package/sdk/dist/generated/uln302.d.ts +175 -75
  362. package/sdk/dist/generated/uln302.js +126 -82
  363. package/sdk/dist/generated/upgrader.d.ts +70 -0
  364. package/sdk/dist/generated/upgrader.js +19 -0
  365. package/sdk/dist/index.d.ts +10 -0
  366. package/sdk/dist/index.js +14 -0
  367. package/sdk/dist/wasm/blocked-message-lib.d.ts +1 -0
  368. package/sdk/dist/wasm/blocked-message-lib.js +2 -0
  369. package/sdk/dist/wasm/counter.d.ts +1 -0
  370. package/sdk/dist/wasm/counter.js +2 -0
  371. package/sdk/dist/wasm/dvn-fee-lib.d.ts +1 -0
  372. package/sdk/dist/wasm/dvn-fee-lib.js +2 -0
  373. package/sdk/dist/wasm/dvn.d.ts +1 -0
  374. package/sdk/dist/wasm/dvn.js +2 -0
  375. package/sdk/dist/wasm/endpoint-v2.d.ts +1 -0
  376. package/sdk/dist/wasm/endpoint-v2.js +2 -0
  377. package/sdk/dist/wasm/executor-fee-lib.d.ts +1 -0
  378. package/sdk/dist/wasm/executor-fee-lib.js +2 -0
  379. package/sdk/dist/wasm/executor-helper.d.ts +1 -0
  380. package/sdk/dist/wasm/executor-helper.js +2 -0
  381. package/sdk/dist/wasm/executor.d.ts +1 -0
  382. package/sdk/dist/wasm/executor.js +2 -0
  383. package/sdk/dist/wasm/layerzero-views.d.ts +1 -0
  384. package/sdk/dist/wasm/layerzero-views.js +2 -0
  385. package/sdk/dist/wasm/oft-std.d.ts +1 -0
  386. package/sdk/dist/wasm/oft-std.js +2 -0
  387. package/sdk/dist/wasm/price-feed.d.ts +1 -0
  388. package/sdk/dist/wasm/price-feed.js +2 -0
  389. package/sdk/dist/wasm/simple-message-lib.d.ts +1 -0
  390. package/sdk/dist/wasm/simple-message-lib.js +2 -0
  391. package/sdk/dist/wasm/treasury.d.ts +1 -0
  392. package/sdk/dist/wasm/treasury.js +2 -0
  393. package/sdk/dist/wasm/uln302.d.ts +1 -0
  394. package/sdk/dist/wasm/uln302.js +2 -0
  395. package/sdk/dist/wasm/upgrader.d.ts +1 -0
  396. package/sdk/dist/wasm/upgrader.js +2 -0
  397. package/sdk/dist/wasm.d.ts +15 -0
  398. package/sdk/dist/wasm.js +15 -0
  399. package/sdk/package.json +7 -4
  400. package/sdk/src/index.ts +17 -0
  401. package/sdk/test/counter-sml.test.ts +376 -0
  402. package/sdk/test/counter-uln.test.ts +493 -0
  403. package/sdk/test/{oft.test.ts → oft-sml.test.ts} +187 -323
  404. package/sdk/test/suites/constants.ts +22 -2
  405. package/sdk/test/suites/dummyContractClient.ts +169 -0
  406. package/sdk/test/suites/globalSetup.ts +450 -0
  407. package/sdk/test/suites/localnet.ts +23 -6
  408. package/sdk/test/upgrader.test.ts +300 -0
  409. package/sdk/test/utils.ts +558 -85
  410. package/sdk/vitest.config.ts +21 -0
  411. package/tools/ts-bindings-gen/src/main.rs +12 -1
  412. package/turbo.json +2 -0
  413. package/contracts/common-macros/src/contract_impl.rs +0 -47
  414. package/contracts/common-macros/src/ownable.rs +0 -59
  415. package/contracts/common-macros/src/tests/contract_impl.rs +0 -381
  416. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__ownable__snapshot_generated_ownable_code.snap +0 -32
  417. package/contracts/endpoint-v2/src/tests/messaging_channel/clear.rs +0 -316
  418. package/contracts/endpoint-v2/src/tests/messaging_channel/internal.rs +0 -388
  419. package/contracts/message-libs/message-lib-common/src/tests/packet_codec_v1.rs +0 -162
  420. package/contracts/message-libs/message-lib-common/src/tests/worker_options.rs +0 -319
  421. package/contracts/oapp-macros/src/lib.rs +0 -154
  422. package/contracts/oapp-macros/src/oapp_core.rs +0 -40
  423. package/contracts/oapp-macros/src/oapp_full.rs +0 -21
  424. package/contracts/oapp-macros/src/oapp_options_type3.rs +0 -31
  425. package/contracts/oapp-macros/src/oapp_receiver.rs +0 -48
  426. package/contracts/oapp-macros/src/oapp_sender.rs +0 -21
  427. package/contracts/oapp-macros/src/util.rs +0 -107
  428. package/contracts/oapps/oft/src/constants.rs +0 -5
  429. package/contracts/oapps/oft/src/default_oft_impl.rs +0 -146
  430. package/contracts/utils/src/tests/ttl.rs +0 -421
  431. package/contracts/utils/src/ttl.rs +0 -123
  432. package/contracts/workers/dvn/src/interfaces/multisig.rs +0 -56
  433. package/contracts/workers/dvn/src/multisig.rs +0 -153
  434. package/sdk/test/index.test.ts +0 -376
  435. /package/contracts/{oapp-macros → oapps/oapp-macros}/Cargo.toml +0 -0
@@ -1,72 +1,50 @@
1
- use crate::{events::PacketSent, tests::endpoint_setup::setup, MessagingParams};
2
- use soroban_sdk::{
3
- testutils::{Address as _, MockAuth, MockAuthInvoke},
4
- token::TokenClient,
5
- vec, Bytes, BytesN, IntoVal,
6
- };
1
+ use soroban_sdk::{testutils::Address as _, vec, Address, Bytes, BytesN, Env};
7
2
  use utils::testing_utils::assert_event;
8
3
 
4
+ use crate::{
5
+ errors::EndpointError,
6
+ events::PacketSent,
7
+ tests::endpoint_setup::{setup, TestSetup},
8
+ MessagingParams, MessagingReceipt,
9
+ };
10
+
11
+ // Helpers
12
+ fn default_params(env: &Env, dst_eid: u32, pay_in_zro: bool) -> MessagingParams {
13
+ MessagingParams {
14
+ dst_eid,
15
+ receiver: BytesN::from_array(env, &[1u8; 32]),
16
+ message: Bytes::from_array(env, &[1, 2, 3, 4]),
17
+ options: Bytes::new(env),
18
+ pay_in_zro,
19
+ }
20
+ }
21
+
22
+ fn send_with_auth<'a>(
23
+ context: &TestSetup<'a>,
24
+ sender: &Address,
25
+ params: &MessagingParams,
26
+ refund_address: &Address,
27
+ ) -> MessagingReceipt {
28
+ context.mock_auth(sender, "send", (sender, params, refund_address));
29
+ context.endpoint_client.send(sender, params, refund_address)
30
+ }
31
+
32
+ // Native Fee Payment
9
33
  #[test]
10
34
  fn test_send_with_native_fee_exact_payment() {
11
35
  let context = setup();
12
36
  let env = &context.env;
13
37
  let endpoint_client = &context.endpoint_client;
14
38
 
15
- let sender = soroban_sdk::Address::generate(env);
16
- let refund_address = soroban_sdk::Address::generate(env);
17
- let fee_recipient = soroban_sdk::Address::generate(env);
18
39
  let dst_eid = 2u32;
19
- let receiver = BytesN::from_array(env, &[1u8; 32]);
20
- let message = Bytes::from_array(env, &[1, 2, 3, 4]);
21
- let options = Bytes::new(env);
22
-
23
- // Set ZRO token (required even when not paying in ZRO due to line 79 in endpoint_v2.rs)
24
- context.mock_owner_auth("set_zro", (&context.zro_token_client.address,));
25
- endpoint_client.set_zro(&context.zro_token_client.address);
26
-
27
- // Setup mock send library with 100 native fee, 0 zro fee
28
- let send_lib = context.setup_mock_send_lib(vec![env, dst_eid], 100, 0, fee_recipient.clone());
29
-
30
- // Register and set as default send library
31
- context.mock_owner_auth("register_library", (&send_lib,));
32
- endpoint_client.register_library(&send_lib);
33
- context.mock_owner_auth("set_default_send_library", (&dst_eid, &send_lib));
34
- endpoint_client.set_default_send_library(&dst_eid, &send_lib);
35
-
36
- // Mint and transfer native tokens to endpoint for payment
37
- context.mint_native(&sender, 100);
38
- let token_client = TokenClient::new(env, &context.native_token_client.address);
39
- env.mock_auths(&[MockAuth {
40
- address: &sender,
41
- invoke: &MockAuthInvoke {
42
- contract: &context.native_token_client.address,
43
- fn_name: "transfer",
44
- args: (&sender, &endpoint_client.address, &100i128).into_val(env),
45
- sub_invokes: &[],
46
- },
47
- }]);
48
- token_client.transfer(&sender, &endpoint_client.address, &100);
40
+ let sender = Address::generate(env);
41
+ let refund_address = Address::generate(env);
49
42
 
50
- let params = MessagingParams {
51
- dst_eid,
52
- receiver: receiver.clone(),
53
- message: message.clone(),
54
- options: options.clone(),
55
- pay_in_zro: false,
56
- };
57
-
58
- // Mock auth for sender to call send
59
- env.mock_auths(&[MockAuth {
60
- address: &sender,
61
- invoke: &MockAuthInvoke {
62
- contract: &endpoint_client.address,
63
- fn_name: "send",
64
- args: (&sender, &params, &refund_address).into_val(env),
65
- sub_invokes: &[],
66
- },
67
- }]);
43
+ let (send_lib, fee_recipient) = context.setup_default_send_lib(dst_eid, 100, 0);
44
+ context.fund_endpoint_with_native(&sender, 100);
68
45
 
69
- let receipt = endpoint_client.send(&sender, &params, &refund_address);
46
+ let params = default_params(env, dst_eid, false);
47
+ let receipt = send_with_auth(&context, &sender, &params, &refund_address);
70
48
 
71
49
  // Verify receipt
72
50
  assert_eq!(receipt.nonce, 1);
@@ -78,11 +56,15 @@ fn test_send_with_native_fee_exact_payment() {
78
56
  assert_event(
79
57
  env,
80
58
  &endpoint_client.address,
81
- PacketSent { encoded_packet: message, options, send_library: send_lib },
59
+ PacketSent {
60
+ encoded_packet: params.message.clone(),
61
+ options: params.options.clone(),
62
+ send_library: send_lib.clone(),
63
+ },
82
64
  );
83
65
 
84
66
  // Verify outbound nonce was incremented
85
- let nonce = endpoint_client.outbound_nonce(&sender, &dst_eid, &receiver);
67
+ let nonce = endpoint_client.outbound_nonce(&sender, &dst_eid, &params.receiver);
86
68
  assert_eq!(nonce, 1);
87
69
 
88
70
  // Verify fee was paid to fee_recipient
@@ -96,57 +78,16 @@ fn test_send_with_native_fee_exact_payment() {
96
78
  fn test_send_with_native_fee_and_refund() {
97
79
  let context = setup();
98
80
  let env = &context.env;
99
- let endpoint_client = &context.endpoint_client;
100
81
 
101
- let sender = soroban_sdk::Address::generate(env);
102
- let refund_address = soroban_sdk::Address::generate(env);
82
+ let sender = Address::generate(env);
83
+ let refund_address = Address::generate(env);
103
84
  let dst_eid = 2u32;
104
- let receiver = BytesN::from_array(env, &[1u8; 32]);
105
- let message = Bytes::from_array(env, &[1, 2, 3, 4]);
106
- let options = Bytes::new(env);
107
- let fee_recipient = soroban_sdk::Address::generate(env);
108
-
109
- // Set ZRO token (required even when not paying in ZRO due to line 79 in endpoint_v2.rs)
110
- context.mock_owner_auth("set_zro", (&context.zro_token_client.address,));
111
- endpoint_client.set_zro(&context.zro_token_client.address);
112
-
113
- // Setup mock send library with 100 native fee
114
- let send_lib = context.setup_mock_send_lib(vec![env, dst_eid], 100, 0, fee_recipient.clone());
115
-
116
- // Register and set as default send library
117
- context.mock_owner_auth("register_library", (&send_lib,));
118
- endpoint_client.register_library(&send_lib);
119
- context.mock_owner_auth("set_default_send_library", (&dst_eid, &send_lib));
120
- endpoint_client.set_default_send_library(&dst_eid, &send_lib);
121
-
122
- // Mint and transfer MORE native tokens than needed (overpay)
123
- context.mint_native(&sender, 250);
124
- let token_client = TokenClient::new(env, &context.native_token_client.address);
125
- env.mock_auths(&[MockAuth {
126
- address: &sender,
127
- invoke: &MockAuthInvoke {
128
- contract: &context.native_token_client.address,
129
- fn_name: "transfer",
130
- args: (&sender, &endpoint_client.address, &250i128).into_val(env),
131
- sub_invokes: &[],
132
- },
133
- }]);
134
- token_client.transfer(&sender, &endpoint_client.address, &250);
135
-
136
- let params = MessagingParams { dst_eid, receiver: receiver.clone(), message, options, pay_in_zro: false };
137
-
138
- // Mock auth for sender to call send
139
- env.mock_auths(&[MockAuth {
140
- address: &sender,
141
- invoke: &MockAuthInvoke {
142
- contract: &endpoint_client.address,
143
- fn_name: "send",
144
- args: (&sender, &params, &refund_address).into_val(env),
145
- sub_invokes: &[],
146
- },
147
- }]);
85
+ let (_, fee_recipient) = context.setup_default_send_lib(dst_eid, 100, 0);
148
86
 
149
- let receipt = endpoint_client.send(&sender, &params, &refund_address);
87
+ // Overpay native fees
88
+ context.fund_endpoint_with_native(&sender, 250);
89
+ let params = default_params(env, dst_eid, false);
90
+ let receipt = send_with_auth(&context, &sender, &params, &refund_address);
150
91
 
151
92
  // Verify receipt
152
93
  assert_eq!(receipt.nonce, 1);
@@ -160,286 +101,264 @@ fn test_send_with_native_fee_and_refund() {
160
101
  }
161
102
 
162
103
  #[test]
163
- fn test_send_increments_nonce_sequentially() {
104
+ fn test_send_insufficient_native_fee() {
164
105
  let context = setup();
165
106
  let env = &context.env;
166
107
  let endpoint_client = &context.endpoint_client;
167
108
 
168
- let sender = soroban_sdk::Address::generate(env);
169
- let refund_address = soroban_sdk::Address::generate(env);
109
+ let sender = Address::generate(env);
110
+ let refund_address = Address::generate(env);
170
111
  let dst_eid = 2u32;
171
- let receiver = BytesN::from_array(env, &[1u8; 32]);
172
- let message = Bytes::from_array(env, &[1, 2, 3, 4]);
173
- let options = Bytes::new(env);
174
- let fee_recipient = soroban_sdk::Address::generate(env);
175
-
176
- // Set ZRO token (required even when not paying in ZRO due to line 79 in endpoint_v2.rs)
177
- context.mock_owner_auth("set_zro", (&context.zro_token_client.address,));
178
- endpoint_client.set_zro(&context.zro_token_client.address);
179
-
180
- // Setup mock send library
181
- let send_lib = context.setup_mock_send_lib(vec![env, dst_eid], 50, 0, fee_recipient.clone());
182
- context.mock_owner_auth("register_library", (&send_lib,));
183
- endpoint_client.register_library(&send_lib);
184
- context.mock_owner_auth("set_default_send_library", (&dst_eid, &send_lib));
185
- endpoint_client.set_default_send_library(&dst_eid, &send_lib);
186
-
187
- // Mint tokens for multiple sends
188
- context.mint_native(&sender, 200);
189
- let token_client = TokenClient::new(env, &context.native_token_client.address);
190
-
191
- let params = MessagingParams {
192
- dst_eid,
193
- receiver: receiver.clone(),
194
- message: message.clone(),
195
- options: options.clone(),
196
- pay_in_zro: false,
197
- };
198
-
199
- // Send first message
200
- env.mock_auths(&[MockAuth {
201
- address: &sender,
202
- invoke: &MockAuthInvoke {
203
- contract: &context.native_token_client.address,
204
- fn_name: "transfer",
205
- args: (&sender, &endpoint_client.address, &50i128).into_val(env),
206
- sub_invokes: &[],
207
- },
208
- }]);
209
- token_client.transfer(&sender, &endpoint_client.address, &50);
210
-
211
- env.mock_auths(&[MockAuth {
212
- address: &sender,
213
- invoke: &MockAuthInvoke {
214
- contract: &endpoint_client.address,
215
- fn_name: "send",
216
- args: (&sender, &params, &refund_address).into_val(env),
217
- sub_invokes: &[],
218
- },
219
- }]);
220
- let receipt1 = endpoint_client.send(&sender, &params, &refund_address);
221
-
222
- // Send second message
223
- env.mock_auths(&[MockAuth {
224
- address: &sender,
225
- invoke: &MockAuthInvoke {
226
- contract: &context.native_token_client.address,
227
- fn_name: "transfer",
228
- args: (&sender, &endpoint_client.address, &50i128).into_val(env),
229
- sub_invokes: &[],
230
- },
231
- }]);
232
- token_client.transfer(&sender, &endpoint_client.address, &50);
233
-
234
- env.mock_auths(&[MockAuth {
235
- address: &sender,
236
- invoke: &MockAuthInvoke {
237
- contract: &endpoint_client.address,
238
- fn_name: "send",
239
- args: (&sender, &params, &refund_address).into_val(env),
240
- sub_invokes: &[],
241
- },
242
- }]);
243
- let receipt2 = endpoint_client.send(&sender, &params, &refund_address);
244
-
245
- // Send third message
246
- env.mock_auths(&[MockAuth {
247
- address: &sender,
248
- invoke: &MockAuthInvoke {
249
- contract: &context.native_token_client.address,
250
- fn_name: "transfer",
251
- args: (&sender, &endpoint_client.address, &50i128).into_val(env),
252
- sub_invokes: &[],
253
- },
254
- }]);
255
- token_client.transfer(&sender, &endpoint_client.address, &50);
256
-
257
- env.mock_auths(&[MockAuth {
258
- address: &sender,
259
- invoke: &MockAuthInvoke {
260
- contract: &endpoint_client.address,
261
- fn_name: "send",
262
- args: (&sender, &params, &refund_address).into_val(env),
263
- sub_invokes: &[],
112
+ context.setup_default_send_lib(dst_eid, 100, 0);
113
+
114
+ // Fund LESS native than required
115
+ context.fund_endpoint_with_native(&sender, 50);
116
+
117
+ let params = default_params(env, dst_eid, false);
118
+ context.mock_auth(&sender, "send", (&sender, &params, &refund_address));
119
+ let result = endpoint_client.try_send(&sender, &params, &refund_address);
120
+ assert_eq!(result.err().unwrap().ok().unwrap(), EndpointError::InsufficientNativeFee.into());
121
+ }
122
+
123
+ // ZRO Fee Payment
124
+ #[test]
125
+ fn test_send_with_zro_fee() {
126
+ let context = setup();
127
+ let env = &context.env;
128
+ let endpoint_client = &context.endpoint_client;
129
+
130
+ let sender = Address::generate(env);
131
+ let refund_address = Address::generate(env);
132
+ let dst_eid = 2u32;
133
+ context.setup_zro_with_auth();
134
+ let (send_lib, fee_recipient) = context.setup_default_send_lib(dst_eid, 50, 25);
135
+
136
+ // Fund exact fees
137
+ context.fund_endpoint_with_native(&sender, 50);
138
+ context.fund_endpoint_with_zro(&sender, 25);
139
+
140
+ let params = default_params(env, dst_eid, true);
141
+ let receipt = send_with_auth(&context, &sender, &params, &refund_address);
142
+
143
+ // Verify receipt
144
+ assert_eq!(receipt.nonce, 1);
145
+ assert_eq!(receipt.fee.native_fee, 50);
146
+ assert_eq!(receipt.fee.zro_fee, 25);
147
+
148
+ // Verify PacketSent event was published
149
+ assert_event(
150
+ env,
151
+ &endpoint_client.address,
152
+ PacketSent {
153
+ encoded_packet: params.message.clone(),
154
+ options: params.options.clone(),
155
+ send_library: send_lib.clone(),
264
156
  },
265
- }]);
266
- let receipt3 = endpoint_client.send(&sender, &params, &refund_address);
157
+ );
267
158
 
268
- // Verify nonces increment sequentially
269
- assert_eq!(receipt1.nonce, 1);
270
- assert_eq!(receipt2.nonce, 2);
271
- assert_eq!(receipt3.nonce, 3);
159
+ // Verify fees were paid
160
+ assert_eq!(context.native_token_client.balance(&fee_recipient), 50);
161
+ assert_eq!(context.zro_token_client.balance(&fee_recipient), 25);
162
+
163
+ // Verify no refunds
164
+ assert_eq!(context.native_token_client.balance(&refund_address), 0);
165
+ assert_eq!(context.zro_token_client.balance(&refund_address), 0);
166
+ }
167
+
168
+ #[test]
169
+ fn test_send_with_zro_refund() {
170
+ let context = setup();
171
+ let env = &context.env;
172
+
173
+ let sender = Address::generate(env);
174
+ let refund_address = Address::generate(env);
175
+ let dst_eid = 2u32;
176
+ context.setup_zro_with_auth();
177
+ let (_, fee_recipient) = context.setup_default_send_lib(dst_eid, 50, 25);
178
+
179
+ // Exact native, overpay ZRO to hit refund branch.
180
+ context.fund_endpoint_with_native(&sender, 50);
181
+ context.fund_endpoint_with_zro(&sender, 80);
182
+
183
+ let params = default_params(env, dst_eid, true);
184
+ let receipt = send_with_auth(&context, &sender, &params, &refund_address);
185
+
186
+ assert_eq!(receipt.nonce, 1);
187
+ assert_eq!(receipt.fee.native_fee, 50);
188
+ assert_eq!(receipt.fee.zro_fee, 25);
189
+
190
+ // Fee recipient got paid
191
+ assert_eq!(context.native_token_client.balance(&fee_recipient), 50);
192
+ assert_eq!(context.zro_token_client.balance(&fee_recipient), 25);
193
+
194
+ // Native was exact, ZRO was overpaid => refund 80 - 25 = 55
195
+ assert_eq!(context.native_token_client.balance(&refund_address), 0);
196
+ assert_eq!(context.zro_token_client.balance(&refund_address), 55);
197
+ }
198
+
199
+ #[test]
200
+ fn test_send_pay_in_zro_false_without_zro_set() {
201
+ let context = setup();
202
+ let env = &context.env;
203
+ let endpoint_client = &context.endpoint_client;
204
+
205
+ let sender = Address::generate(env);
206
+ let refund_address = Address::generate(env);
207
+ let dst_eid = 2u32;
208
+
209
+ // Ensure ZRO is not set; pay_in_zro=false should not require it.
210
+ assert_eq!(endpoint_client.zro(), None);
211
+
212
+ let (_, fee_recipient) = context.setup_default_send_lib(dst_eid, 100, 0);
213
+ context.fund_endpoint_with_native(&sender, 100);
214
+
215
+ let params = default_params(env, dst_eid, false);
216
+ let receipt = send_with_auth(&context, &sender, &params, &refund_address);
217
+
218
+ assert_eq!(receipt.nonce, 1);
219
+ assert_eq!(receipt.fee.native_fee, 100);
220
+ assert_eq!(receipt.fee.zro_fee, 0);
221
+ assert_eq!(context.native_token_client.balance(&fee_recipient), 100);
222
+ assert_eq!(context.native_token_client.balance(&refund_address), 0);
223
+ }
224
+
225
+ #[test]
226
+ fn test_send_zro_unavailable_when_pay_in_zro() {
227
+ let context = setup();
228
+ let env = &context.env;
229
+ let endpoint_client = &context.endpoint_client;
230
+
231
+ let sender = Address::generate(env);
232
+ let refund_address = Address::generate(env);
233
+
234
+ // ZRO is intentionally unset
235
+ assert_eq!(endpoint_client.zro(), None);
236
+
237
+ // ZRO check happens before send lib resolution; we don't need to setup a send lib.
238
+ let params = default_params(env, 998u32, true);
239
+ context.mock_auth(&sender, "send", (&sender, &params, &refund_address));
240
+ let result = endpoint_client.try_send(&sender, &params, &refund_address);
241
+ assert_eq!(result.err().unwrap().ok().unwrap(), EndpointError::ZroUnavailable.into());
242
+ }
243
+
244
+ #[test]
245
+ fn test_send_zero_zro_fee_when_pay_in_zro_true() {
246
+ let context = setup();
247
+ let env = &context.env;
248
+ let endpoint_client = &context.endpoint_client;
249
+
250
+ let sender = Address::generate(env);
251
+ let refund_address = Address::generate(env);
252
+ let dst_eid = 2u32;
253
+
254
+ // Set ZRO token so we pass the send() pre-check, but do NOT transfer any ZRO to the endpoint.
255
+ context.setup_zro_with_auth();
256
+
257
+ // Configure send lib with zero fees, but pay_in_zro=true triggers the ZeroZROFee guard.
258
+ context.setup_default_send_lib(dst_eid, 0, 0);
259
+
260
+ let params = default_params(env, dst_eid, true);
261
+ context.mock_auth(&sender, "send", (&sender, &params, &refund_address));
262
+ let result = endpoint_client.try_send(&sender, &params, &refund_address);
263
+ assert_eq!(result.err().unwrap().ok().unwrap(), EndpointError::ZeroZroFee.into());
264
+ }
265
+
266
+ #[test]
267
+ fn test_send_insufficient_zro_fee() {
268
+ let context = setup();
269
+ let env = &context.env;
270
+ let endpoint_client = &context.endpoint_client;
271
+
272
+ let sender = Address::generate(env);
273
+ let refund_address = Address::generate(env);
274
+ let dst_eid = 2u32;
275
+
276
+ // Set ZRO token
277
+ context.setup_zro_with_auth();
278
+
279
+ // Setup send lib that requires 25 ZRO, 0 native
280
+ context.setup_default_send_lib(dst_eid, 0, 25);
281
+
282
+ // Transfer LESS ZRO than needed (only 10)
283
+ context.fund_endpoint_with_zro(&sender, 10);
284
+
285
+ let params = default_params(env, dst_eid, true);
286
+ context.mock_auth(&sender, "send", (&sender, &params, &refund_address));
287
+ let result = endpoint_client.try_send(&sender, &params, &refund_address);
288
+ assert_eq!(result.err().unwrap().ok().unwrap(), EndpointError::InsufficientZroFee.into());
289
+ }
290
+
291
+ // Nonce Management
292
+ #[test]
293
+ fn test_send_increments_nonce_sequentially() {
294
+ let context = setup();
295
+ let env = &context.env;
296
+ let endpoint_client = &context.endpoint_client;
297
+
298
+ let sender = Address::generate(env);
299
+ let refund_address = Address::generate(env);
300
+ let dst_eid = 2u32;
301
+ context.setup_default_send_lib(dst_eid, 50, 0);
302
+ let params = default_params(env, dst_eid, false);
303
+
304
+ for expected_nonce in 1..=3u64 {
305
+ context.fund_endpoint_with_native(&sender, 50);
306
+ let receipt = send_with_auth(&context, &sender, &params, &refund_address);
307
+ assert_eq!(receipt.nonce, expected_nonce);
308
+ }
272
309
 
273
310
  // Verify final outbound nonce
274
- let final_nonce = endpoint_client.outbound_nonce(&sender, &dst_eid, &receiver);
311
+ let final_nonce = endpoint_client.outbound_nonce(&sender, &dst_eid, &params.receiver);
275
312
  assert_eq!(final_nonce, 3);
276
313
  }
277
314
 
278
315
  #[test]
279
- fn test_send_with_custom_send_library() {
316
+ fn test_next_guid_matches_send_receipt_guid() {
280
317
  let context = setup();
281
318
  let env = &context.env;
282
319
  let endpoint_client = &context.endpoint_client;
283
320
 
284
- let sender = soroban_sdk::Address::generate(env);
285
- let refund_address = soroban_sdk::Address::generate(env);
321
+ let sender = Address::generate(env);
322
+ let refund_address = Address::generate(env);
286
323
  let dst_eid = 2u32;
287
- let receiver = BytesN::from_array(env, &[1u8; 32]);
288
- let message = Bytes::from_array(env, &[1, 2, 3, 4]);
289
- let options = Bytes::new(env);
290
- let default_fee_recipient = soroban_sdk::Address::generate(env);
291
- let custom_fee_recipient = soroban_sdk::Address::generate(env);
292
-
293
- // Set ZRO token (required even when not paying in ZRO due to line 79 in endpoint_v2.rs)
294
- context.mock_owner_auth("set_zro", (&context.zro_token_client.address,));
295
- endpoint_client.set_zro(&context.zro_token_client.address);
296
-
297
- // Setup default send library with 100 fee
298
- let default_lib = context.setup_mock_send_lib(vec![env, dst_eid], 100, 0, default_fee_recipient.clone());
299
- context.mock_owner_auth("register_library", (&default_lib,));
300
- endpoint_client.register_library(&default_lib);
301
- context.mock_owner_auth("set_default_send_library", (&dst_eid, &default_lib));
302
- endpoint_client.set_default_send_library(&dst_eid, &default_lib);
303
-
304
- // Setup custom send library with different fee (200)
305
- let custom_lib = context.setup_mock_send_lib(vec![env, dst_eid], 200, 0, custom_fee_recipient.clone());
306
- context.mock_owner_auth("register_library", (&custom_lib,));
307
- endpoint_client.register_library(&custom_lib);
324
+ context.setup_default_send_lib(dst_eid, 100, 0);
325
+ let params = default_params(env, dst_eid, false);
308
326
 
309
- // Set custom library for this sender
310
- env.mock_auths(&[MockAuth {
311
- address: &sender,
312
- invoke: &MockAuthInvoke {
313
- contract: &endpoint_client.address,
314
- fn_name: "set_send_library",
315
- args: (&sender, &sender, &dst_eid, &custom_lib).into_val(env),
316
- sub_invokes: &[],
317
- },
318
- }]);
319
- endpoint_client.set_send_library(&sender, &sender, &dst_eid, &Some(custom_lib.clone()));
320
-
321
- // Mint and transfer tokens for custom library fee
322
- context.mint_native(&sender, 200);
323
- let token_client = TokenClient::new(env, &context.native_token_client.address);
324
- env.mock_auths(&[MockAuth {
325
- address: &sender,
326
- invoke: &MockAuthInvoke {
327
- contract: &context.native_token_client.address,
328
- fn_name: "transfer",
329
- args: (&sender, &endpoint_client.address, &200i128).into_val(env),
330
- sub_invokes: &[],
331
- },
332
- }]);
333
- token_client.transfer(&sender, &endpoint_client.address, &200);
334
-
335
- let params = MessagingParams { dst_eid, receiver, message, options, pay_in_zro: false };
336
-
337
- // Mock auth for sender to call send
338
- env.mock_auths(&[MockAuth {
339
- address: &sender,
340
- invoke: &MockAuthInvoke {
341
- contract: &endpoint_client.address,
342
- fn_name: "send",
343
- args: (&sender, &params, &refund_address).into_val(env),
344
- sub_invokes: &[],
345
- },
346
- }]);
327
+ // Get the expected GUID before sending
328
+ let next_guid = endpoint_client.next_guid(&sender, &dst_eid, &params.receiver);
347
329
 
348
- let receipt = endpoint_client.send(&sender, &params, &refund_address);
330
+ // Fund endpoint with native fee
331
+ context.fund_endpoint_with_native(&sender, 100);
349
332
 
350
- // Verify receipt uses custom library fee (200, not 100)
351
- assert_eq!(receipt.fee.native_fee, 200);
333
+ let receipt = send_with_auth(&context, &sender, &params, &refund_address);
352
334
 
353
- // Verify fee was paid to custom_fee_recipient (not default_fee_recipient)
354
- assert_eq!(context.native_token_client.balance(&custom_fee_recipient), 200);
355
- assert_eq!(context.native_token_client.balance(&default_fee_recipient), 0);
335
+ // Verify the GUID in receipt matches the expected GUID
336
+ assert_eq!(receipt.guid, next_guid);
356
337
  }
357
338
 
339
+ // Receiver Management
358
340
  #[test]
359
341
  fn test_send_to_different_receivers() {
360
342
  let context = setup();
361
343
  let env = &context.env;
362
344
  let endpoint_client = &context.endpoint_client;
363
345
 
364
- let sender = soroban_sdk::Address::generate(env);
365
- let refund_address = soroban_sdk::Address::generate(env);
346
+ let sender = Address::generate(env);
347
+ let refund_address = Address::generate(env);
366
348
  let dst_eid = 2u32;
367
349
  let receiver1 = BytesN::from_array(env, &[1u8; 32]);
368
350
  let receiver2 = BytesN::from_array(env, &[2u8; 32]);
369
- let message = Bytes::from_array(env, &[1, 2, 3, 4]);
370
- let options = Bytes::new(env);
371
- let fee_recipient = soroban_sdk::Address::generate(env);
372
-
373
- // Set ZRO token (required even when not paying in ZRO due to line 79 in endpoint_v2.rs)
374
- context.mock_owner_auth("set_zro", (&context.zro_token_client.address,));
375
- endpoint_client.set_zro(&context.zro_token_client.address);
376
-
377
- // Setup mock send library
378
- let send_lib = context.setup_mock_send_lib(vec![env, dst_eid], 50, 0, fee_recipient);
379
- context.mock_owner_auth("register_library", (&send_lib,));
380
- endpoint_client.register_library(&send_lib);
381
- context.mock_owner_auth("set_default_send_library", (&dst_eid, &send_lib));
382
- endpoint_client.set_default_send_library(&dst_eid, &send_lib);
383
-
384
- // Mint tokens
385
- context.mint_native(&sender, 100);
386
- let token_client = TokenClient::new(env, &context.native_token_client.address);
387
-
388
- // Send to receiver1
389
- env.mock_auths(&[MockAuth {
390
- address: &sender,
391
- invoke: &MockAuthInvoke {
392
- contract: &context.native_token_client.address,
393
- fn_name: "transfer",
394
- args: (&sender, &endpoint_client.address, &50i128).into_val(env),
395
- sub_invokes: &[],
396
- },
397
- }]);
398
- token_client.transfer(&sender, &endpoint_client.address, &50);
351
+ context.setup_default_send_lib(dst_eid, 50, 0);
399
352
 
400
- let params1 = MessagingParams {
401
- dst_eid,
402
- receiver: receiver1.clone(),
403
- message: message.clone(),
404
- options: options.clone(),
405
- pay_in_zro: false,
406
- };
407
-
408
- env.mock_auths(&[MockAuth {
409
- address: &sender,
410
- invoke: &MockAuthInvoke {
411
- contract: &endpoint_client.address,
412
- fn_name: "send",
413
- args: (&sender, &params1, &refund_address).into_val(env),
414
- sub_invokes: &[],
415
- },
416
- }]);
417
- let receipt1 = endpoint_client.send(&sender, &params1, &refund_address);
418
-
419
- // Send to receiver2
420
- env.mock_auths(&[MockAuth {
421
- address: &sender,
422
- invoke: &MockAuthInvoke {
423
- contract: &context.native_token_client.address,
424
- fn_name: "transfer",
425
- args: (&sender, &endpoint_client.address, &50i128).into_val(env),
426
- sub_invokes: &[],
427
- },
428
- }]);
429
- token_client.transfer(&sender, &endpoint_client.address, &50);
430
-
431
- let params2 = MessagingParams { dst_eid, receiver: receiver2.clone(), message, options, pay_in_zro: false };
432
-
433
- env.mock_auths(&[MockAuth {
434
- address: &sender,
435
- invoke: &MockAuthInvoke {
436
- contract: &endpoint_client.address,
437
- fn_name: "send",
438
- args: (&sender, &params2, &refund_address).into_val(env),
439
- sub_invokes: &[],
440
- },
441
- }]);
442
- let receipt2 = endpoint_client.send(&sender, &params2, &refund_address);
353
+ let mut params1 = default_params(env, dst_eid, false);
354
+ params1.receiver = receiver1.clone();
355
+ context.fund_endpoint_with_native(&sender, 50);
356
+ let receipt1 = send_with_auth(&context, &sender, &params1, &refund_address);
357
+
358
+ let mut params2 = default_params(env, dst_eid, false);
359
+ params2.receiver = receiver2.clone();
360
+ context.fund_endpoint_with_native(&sender, 50);
361
+ let receipt2 = send_with_auth(&context, &sender, &params2, &refund_address);
443
362
 
444
363
  // Verify each receiver has its own nonce tracking
445
364
  assert_eq!(receipt1.nonce, 1);
@@ -452,62 +371,113 @@ fn test_send_to_different_receivers() {
452
371
  assert_eq!(nonce2, 1);
453
372
  }
454
373
 
374
+ // Send Library Management
455
375
  #[test]
456
- fn test_send_returns_correct_guid() {
376
+ fn test_send_with_custom_send_library() {
457
377
  let context = setup();
458
378
  let env = &context.env;
459
379
  let endpoint_client = &context.endpoint_client;
460
380
 
461
- let sender = soroban_sdk::Address::generate(env);
462
- let refund_address = soroban_sdk::Address::generate(env);
381
+ let sender = Address::generate(env);
382
+ let refund_address = Address::generate(env);
463
383
  let dst_eid = 2u32;
464
- let receiver = BytesN::from_array(env, &[1u8; 32]);
465
- let message = Bytes::from_array(env, &[1, 2, 3, 4]);
466
- let options = Bytes::new(env);
467
- let fee_recipient = soroban_sdk::Address::generate(env);
468
-
469
- // Set ZRO token (required even when not paying in ZRO due to line 79 in endpoint_v2.rs)
470
- context.mock_owner_auth("set_zro", (&context.zro_token_client.address,));
471
- endpoint_client.set_zro(&context.zro_token_client.address);
472
-
473
- // Setup mock send library
474
- let send_lib = context.setup_mock_send_lib(vec![env, dst_eid], 100, 0, fee_recipient);
475
- context.mock_owner_auth("register_library", (&send_lib,));
476
- endpoint_client.register_library(&send_lib);
477
- context.mock_owner_auth("set_default_send_library", (&dst_eid, &send_lib));
478
- endpoint_client.set_default_send_library(&dst_eid, &send_lib);
479
384
 
480
- // Get the expected GUID before sending
481
- let next_guid = endpoint_client.next_guid(&sender, &dst_eid, &receiver);
482
-
483
- // Mint and transfer tokens
484
- context.mint_native(&sender, 100);
485
- let token_client = TokenClient::new(env, &context.native_token_client.address);
486
- env.mock_auths(&[MockAuth {
487
- address: &sender,
488
- invoke: &MockAuthInvoke {
489
- contract: &context.native_token_client.address,
490
- fn_name: "transfer",
491
- args: (&sender, &endpoint_client.address, &100i128).into_val(env),
492
- sub_invokes: &[],
493
- },
494
- }]);
495
- token_client.transfer(&sender, &endpoint_client.address, &100);
496
-
497
- let params = MessagingParams { dst_eid, receiver, message, options, pay_in_zro: false };
498
-
499
- env.mock_auths(&[MockAuth {
500
- address: &sender,
501
- invoke: &MockAuthInvoke {
502
- contract: &endpoint_client.address,
503
- fn_name: "send",
504
- args: (&sender, &params, &refund_address).into_val(env),
505
- sub_invokes: &[],
506
- },
507
- }]);
385
+ let (_, default_fee_recipient) = context.setup_default_send_lib(dst_eid, 100, 0);
508
386
 
509
- let receipt = endpoint_client.send(&sender, &params, &refund_address);
387
+ // Setup custom send library with different fee (200)
388
+ let custom_fee_recipient = Address::generate(env);
389
+ let custom_lib = context.setup_mock_send_lib(vec![&context.env, dst_eid], 200, 0, custom_fee_recipient.clone());
390
+ context.register_library_with_auth(&custom_lib);
510
391
 
511
- // Verify the GUID in receipt matches the expected GUID
512
- assert_eq!(receipt.guid, next_guid);
392
+ // Set custom library for this sender
393
+ let custom_lib_option = Some(custom_lib.clone());
394
+ context.mock_auth(&sender, "set_send_library", (&sender, &sender, &dst_eid, &custom_lib_option));
395
+ endpoint_client.set_send_library(&sender, &sender, &dst_eid, &custom_lib_option);
396
+
397
+ // Fund endpoint with native token for custom library fee
398
+ context.fund_endpoint_with_native(&sender, 200);
399
+
400
+ let params = default_params(env, dst_eid, false);
401
+ let receipt = send_with_auth(&context, &sender, &params, &refund_address);
402
+
403
+ // Verify receipt uses custom library fee (200, not 100)
404
+ assert_eq!(receipt.fee.native_fee, 200);
405
+
406
+ // Verify fee was paid to custom_fee_recipient (not default_fee_recipient)
407
+ assert_eq!(context.native_token_client.balance(&custom_fee_recipient), 200);
408
+ assert_eq!(context.native_token_client.balance(&default_fee_recipient), 0);
409
+ }
410
+
411
+ // Options handling
412
+ #[test]
413
+ fn test_send_with_non_empty_options_emits_event_and_charges_fee() {
414
+ let context = setup();
415
+ let env = &context.env;
416
+ let endpoint_client = &context.endpoint_client;
417
+
418
+ let sender = Address::generate(env);
419
+ let refund_address = Address::generate(env);
420
+ let dst_eid = 2u32;
421
+
422
+ // Non-empty options (simulating executor/DVN options)
423
+ // Format example: [worker_id (1 byte), option_size (2 bytes), option_data...]
424
+ let options = Bytes::from_array(env, &[1u8, 0u8, 4u8, 9u8, 8u8, 7u8, 6u8]);
425
+
426
+ let (send_lib, fee_recipient) = context.setup_default_send_lib(dst_eid, 100, 0);
427
+ context.fund_endpoint_with_native(&sender, 100);
428
+
429
+ let mut params = default_params(env, dst_eid, false);
430
+ params.options = options.clone();
431
+
432
+ let receipt = send_with_auth(&context, &sender, &params, &refund_address);
433
+
434
+ assert_eq!(receipt.nonce, 1);
435
+ assert_eq!(receipt.fee.native_fee, 100);
436
+ assert_eq!(receipt.fee.zro_fee, 0);
437
+
438
+ // Verify PacketSent event captures options and encoded packet.
439
+ assert_event(
440
+ env,
441
+ &endpoint_client.address,
442
+ PacketSent { encoded_packet: params.message.clone(), options: options.clone(), send_library: send_lib.clone() },
443
+ );
444
+
445
+ // Fee was paid and there was no refund.
446
+ assert_eq!(context.native_token_client.balance(&fee_recipient), 100);
447
+ assert_eq!(context.native_token_client.balance(&refund_address), 0);
448
+ }
449
+
450
+ #[test]
451
+ fn test_send_default_send_lib_unavailable() {
452
+ let context = setup();
453
+ let env = &context.env;
454
+ let endpoint_client = &context.endpoint_client;
455
+
456
+ let sender = Address::generate(env);
457
+ let refund_address = Address::generate(env);
458
+ let dst_eid = 999u32; // unique eid with no default send library
459
+
460
+ // Ensure no default send library is set
461
+ assert_eq!(endpoint_client.default_send_library(&dst_eid), None);
462
+
463
+ let params = default_params(env, dst_eid, false);
464
+ context.mock_auth(&sender, "send", (&sender, &params, &refund_address));
465
+ let result = endpoint_client.try_send(&sender, &params, &refund_address);
466
+ assert_eq!(result.err().unwrap().ok().unwrap(), EndpointError::DefaultSendLibUnavailable.into());
467
+ }
468
+
469
+ // Authorization
470
+ #[test]
471
+ #[should_panic(expected = "Error(Auth, InvalidAction)")]
472
+ fn test_send_unauthorized() {
473
+ let context = setup();
474
+ let env = &context.env;
475
+ let endpoint_client = &context.endpoint_client;
476
+
477
+ let sender = Address::generate(env);
478
+ let refund_address = Address::generate(env);
479
+
480
+ // No mock auth for `sender` => should panic on `sender.require_auth()`
481
+ let params = default_params(env, 2u32, false);
482
+ endpoint_client.send(&sender, &params, &refund_address);
513
483
  }