@layerzerolabs/protocol-stellar-v2 0.2.15 → 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 (257) hide show
  1. package/.turbo/turbo-build.log +350 -309
  2. package/.turbo/turbo-lint.log +146 -108
  3. package/.turbo/turbo-test.log +1423 -1238
  4. package/Cargo.lock +12 -0
  5. package/Cargo.toml +3 -0
  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 +181 -30
  10. package/contracts/common-macros/src/lz_contract.rs +83 -0
  11. package/contracts/common-macros/src/tests/{ownable.rs → auth.rs} +48 -15
  12. package/contracts/common-macros/src/tests/contract_ttl.rs +662 -0
  13. package/contracts/common-macros/src/tests/mod.rs +2 -2
  14. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__auth__snapshot_generated_multisig_code.snap +20 -0
  15. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__auth__snapshot_generated_ownable_code.snap +24 -0
  16. 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
  17. 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} +3 -3
  18. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__contract_ttl__snapshot_generated_contracttrait_code.snap +69 -0
  19. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__ttl_configurable__snapshot_generated_ttl_configurable_code.snap +7 -21
  20. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__upgradeable__snapshot_generated_upgradeable_code.snap +2 -2
  21. package/contracts/common-macros/src/ttl_configurable.rs +19 -34
  22. package/contracts/common-macros/src/ttl_extendable.rs +36 -0
  23. package/contracts/common-macros/src/upgradeable.rs +5 -5
  24. package/contracts/common-macros/src/utils.rs +9 -0
  25. package/contracts/endpoint-v2/src/constants.rs +4 -4
  26. package/contracts/endpoint-v2/src/endpoint_v2.rs +38 -40
  27. package/contracts/endpoint-v2/src/errors.rs +4 -3
  28. package/contracts/endpoint-v2/src/events.rs +1 -1
  29. package/contracts/endpoint-v2/src/message_lib_manager.rs +18 -5
  30. package/contracts/endpoint-v2/src/messaging_channel.rs +11 -1
  31. package/contracts/endpoint-v2/src/messaging_composer.rs +11 -1
  32. package/contracts/endpoint-v2/src/storage.rs +1 -1
  33. package/contracts/endpoint-v2/src/tests/endpoint_v2/pay_messaging_fees.rs +3 -3
  34. package/contracts/endpoint-v2/src/tests/endpoint_v2/quote.rs +1 -1
  35. package/contracts/endpoint-v2/src/tests/endpoint_v2/require_oapp_auth.rs +2 -2
  36. package/contracts/endpoint-v2/src/tests/endpoint_v2/send.rs +3 -3
  37. package/contracts/endpoint-v2/src/tests/endpoint_v2/set_zro.rs +4 -4
  38. package/contracts/endpoint-v2/src/tests/message_lib_manager/require_receive_lib_for_eid.rs +3 -3
  39. package/contracts/endpoint-v2/src/tests/message_lib_manager/require_registered.rs +1 -1
  40. package/contracts/endpoint-v2/src/tests/message_lib_manager/require_send_lib_for_eid.rs +3 -3
  41. package/contracts/endpoint-v2/src/tests/message_lib_manager/require_supported_eid.rs +1 -1
  42. package/contracts/endpoint-v2/src/tests/messaging_channel/clear_payload.rs +4 -4
  43. package/contracts/endpoint-v2/src/tests/messaging_channel/inbound.rs +1 -1
  44. package/contracts/layerzero-views/src/layerzero_view.rs +3 -6
  45. package/contracts/macro-integration-tests/tests/runtime/ownable/mod.rs +2 -2
  46. package/contracts/macro-integration-tests/tests/runtime/ownable/{only_owner_guard.rs → only_auth_guard.rs} +1 -1
  47. package/contracts/macro-integration-tests/tests/runtime/ttl_configurable/configuration.rs +1 -1
  48. package/contracts/macro-integration-tests/tests/runtime/ttl_configurable/freeze.rs +1 -1
  49. package/contracts/macro-integration-tests/tests/runtime/ttl_configurable/mod.rs +0 -1
  50. package/contracts/macro-integration-tests/tests/ui/ownable/fail/{only_owner_missing_env.rs → only_auth_missing_env.rs} +3 -3
  51. package/contracts/macro-integration-tests/tests/ui/ownable/fail/{only_owner_missing_env.stderr → only_auth_missing_env.stderr} +4 -4
  52. package/contracts/macro-integration-tests/tests/ui/ownable/pass/namespacing_and_imports.rs +2 -3
  53. package/contracts/macro-integration-tests/tests/ui/ownable/pass/{only_owner_env_param_variants.rs → only_auth_env_param_variants.rs} +9 -9
  54. package/contracts/macro-integration-tests/tests/ui/ttl_configurable/pass/minimal_contract.rs +6 -6
  55. package/contracts/message-libs/message-lib-common/src/errors.rs +7 -2
  56. package/contracts/message-libs/message-lib-common/src/tests/packet_codec_v1/decode_packet_header.rs +3 -3
  57. package/contracts/message-libs/message-lib-common/src/tests/worker_options/append_lz_receive_option.rs +1 -2
  58. package/contracts/message-libs/message-lib-common/src/tests/worker_options/append_native_drop_option.rs +1 -2
  59. package/contracts/message-libs/message-lib-common/src/tests/worker_options/convert_legacy_options.rs +9 -9
  60. package/contracts/message-libs/message-lib-common/src/tests/worker_options/extract_type_3_options.rs +1 -1
  61. package/contracts/message-libs/message-lib-common/src/tests/worker_options/left_pad_to_bytes32.rs +1 -1
  62. package/contracts/message-libs/message-lib-common/src/tests/worker_options/split_worker_options.rs +2 -2
  63. package/contracts/message-libs/simple-message-lib/src/simple_message_lib.rs +7 -9
  64. package/contracts/message-libs/treasury/src/errors.rs +2 -2
  65. package/contracts/message-libs/treasury/src/events.rs +1 -1
  66. package/contracts/message-libs/treasury/src/interfaces/zro_fee_lib.rs +2 -2
  67. package/contracts/message-libs/treasury/src/storage.rs +1 -1
  68. package/contracts/message-libs/treasury/src/tests/treasury_tests.rs +1 -1
  69. package/contracts/message-libs/treasury/src/treasury.rs +14 -16
  70. package/contracts/message-libs/uln-302/src/receive_uln.rs +13 -2
  71. package/contracts/message-libs/uln-302/src/send_uln.rs +23 -3
  72. package/contracts/message-libs/uln-302/src/uln302.rs +6 -24
  73. package/contracts/oapps/counter/Cargo.toml +14 -1
  74. package/contracts/oapps/counter/integration_tests/mod.rs +4 -1
  75. package/contracts/oapps/counter/integration_tests/{setup.rs → setup_sml.rs} +48 -80
  76. package/contracts/oapps/counter/integration_tests/setup_uln.rs +997 -0
  77. package/contracts/oapps/counter/integration_tests/signing.rs +62 -0
  78. package/contracts/oapps/counter/integration_tests/test_with_sml.rs +24 -55
  79. package/contracts/oapps/counter/integration_tests/test_with_uln.rs +314 -0
  80. package/contracts/oapps/counter/integration_tests/utils.rs +196 -53
  81. package/contracts/oapps/counter/src/counter.rs +67 -43
  82. package/contracts/oapps/counter/src/tests/mod.rs +0 -13
  83. package/contracts/oapps/counter/src/tests/test_counter.rs +5 -7
  84. package/contracts/oapps/oapp/src/errors.rs +5 -1
  85. package/contracts/oapps/oapp/src/macro_tests/test_macros.rs +93 -78
  86. package/contracts/oapps/oapp/src/oapp_core.rs +36 -21
  87. package/contracts/oapps/oapp/src/oapp_options_type3.rs +48 -12
  88. package/contracts/oapps/oapp/src/oapp_receiver.rs +106 -41
  89. package/contracts/oapps/oapp/src/oapp_sender.rs +26 -34
  90. package/contracts/oapps/oapp/src/tests/test_oapp_core.rs +9 -8
  91. package/contracts/oapps/oapp/src/tests/test_oapp_options_type3.rs +25 -17
  92. package/contracts/oapps/oapp/src/tests/test_oapp_receiver.rs +7 -7
  93. package/contracts/oapps/oapp/src/tests/test_oapp_sender.rs +14 -15
  94. package/contracts/oapps/oapp-macros/src/generators.rs +128 -0
  95. package/contracts/oapps/oapp-macros/src/lib.rs +113 -56
  96. package/contracts/oapps/oft/integration-tests/setup.rs +25 -7
  97. package/contracts/oapps/oft/src/errors.rs +6 -1
  98. package/contracts/oapps/oft/src/extensions/oft_fee.rs +8 -8
  99. package/contracts/oapps/oft/src/extensions/pausable.rs +4 -4
  100. package/contracts/oapps/oft/src/extensions/rate_limiter.rs +5 -5
  101. package/contracts/oapps/oft/src/lib.rs +4 -2
  102. package/contracts/oapps/oft/src/oft.rs +24 -64
  103. package/contracts/oapps/oft/src/oft_impl.rs +201 -0
  104. package/contracts/oapps/oft/src/oft_types/lock_unlock.rs +1 -3
  105. package/contracts/oapps/oft/src/oft_types/mint_burn.rs +1 -4
  106. package/contracts/oapps/oft/src/storage.rs +2 -0
  107. package/contracts/oapps/oft/src/tests/extensions/setup.rs +36 -22
  108. package/contracts/oapps/oft/src/tests/extensions/test_oft_fee.rs +5 -3
  109. package/contracts/oapps/oft/src/tests/extensions/test_pausable.rs +5 -3
  110. package/contracts/oapps/oft/src/tests/extensions/test_rate_limiter.rs +5 -3
  111. package/contracts/oapps/oft/src/tests/test_decimals.rs +2 -2
  112. package/contracts/oapps/oft/src/tests/test_oft_msg_codec.rs +1 -2
  113. package/contracts/oapps/oft/src/tests/test_utils.rs +45 -23
  114. package/contracts/oapps/oft/src/types.rs +20 -0
  115. package/contracts/oapps/oft-std/integration-tests/setup.rs +4 -2
  116. package/contracts/oapps/oft-std/src/oft.rs +24 -6
  117. package/contracts/upgrader/src/lib.rs +4 -4
  118. package/contracts/utils/src/auth.rs +44 -0
  119. package/contracts/utils/src/errors.rs +27 -5
  120. package/contracts/utils/src/lib.rs +3 -0
  121. package/contracts/utils/src/multisig.rs +211 -0
  122. package/contracts/utils/src/ownable.rs +12 -10
  123. package/contracts/utils/src/tests/buffer_reader.rs +6 -6
  124. package/contracts/utils/src/tests/buffer_writer.rs +6 -6
  125. package/contracts/utils/src/tests/bytes_ext.rs +2 -4
  126. package/contracts/utils/src/tests/mod.rs +1 -0
  127. package/contracts/utils/src/tests/multisig.rs +731 -0
  128. package/contracts/utils/src/tests/option_ext.rs +2 -5
  129. package/contracts/utils/src/tests/ownable.rs +16 -5
  130. package/contracts/utils/src/tests/ttl_configurable.rs +27 -16
  131. package/contracts/utils/src/tests/upgradeable.rs +4 -2
  132. package/contracts/utils/src/ttl_configurable.rs +23 -8
  133. package/contracts/utils/src/ttl_extendable.rs +27 -0
  134. package/contracts/utils/src/upgradeable.rs +2 -0
  135. package/contracts/workers/dvn/Cargo.toml +1 -1
  136. package/contracts/workers/dvn/src/auth.rs +7 -7
  137. package/contracts/workers/dvn/src/dvn.rs +10 -38
  138. package/contracts/workers/dvn/src/errors.rs +0 -7
  139. package/contracts/workers/dvn/src/events.rs +1 -14
  140. package/contracts/workers/dvn/src/interfaces/dvn.rs +2 -2
  141. package/contracts/workers/dvn/src/interfaces/mod.rs +0 -2
  142. package/contracts/workers/dvn/src/storage.rs +3 -13
  143. package/contracts/workers/dvn/src/tests/auth.rs +4 -4
  144. package/contracts/workers/dvn/src/tests/dvn.rs +1 -2
  145. package/contracts/workers/dvn/src/tests/multisig/set_signer.rs +7 -8
  146. package/contracts/workers/dvn/src/tests/multisig/set_threshold.rs +11 -8
  147. package/contracts/workers/dvn/src/tests/multisig/verify_signatures.rs +11 -12
  148. package/contracts/workers/dvn/src/tests/setup.rs +5 -5
  149. package/contracts/workers/dvn-fee-lib/Cargo.toml +1 -1
  150. package/contracts/workers/dvn-fee-lib/src/dvn_fee_lib.rs +3 -6
  151. package/contracts/workers/executor/src/auth.rs +80 -16
  152. package/contracts/workers/executor/src/executor.rs +5 -31
  153. package/contracts/workers/executor/src/storage.rs +2 -9
  154. package/contracts/workers/executor-fee-lib/Cargo.toml +1 -1
  155. package/contracts/workers/executor-fee-lib/src/executor_fee_lib.rs +3 -6
  156. package/contracts/workers/executor-helper/Cargo.toml +1 -1
  157. package/contracts/workers/executor-helper/src/executor_helper.rs +53 -73
  158. package/contracts/workers/price-feed/Cargo.toml +1 -1
  159. package/contracts/workers/price-feed/src/price_feed.rs +7 -10
  160. package/contracts/workers/worker/src/errors.rs +4 -0
  161. package/contracts/workers/worker/src/tests/worker.rs +7 -6
  162. package/contracts/workers/worker/src/worker.rs +20 -16
  163. package/package.json +8 -5
  164. package/sdk/.turbo/turbo-build.log +1 -0
  165. package/sdk/.turbo/turbo-test.log +1009 -0
  166. package/sdk/dist/generated/bml.d.ts +65 -8
  167. package/sdk/dist/generated/bml.js +70 -34
  168. package/sdk/dist/generated/counter.d.ts +167 -42
  169. package/sdk/dist/generated/counter.js +86 -45
  170. package/sdk/dist/generated/dvn.d.ts +282 -229
  171. package/sdk/dist/generated/dvn.js +119 -81
  172. package/sdk/dist/generated/dvn_fee_lib.d.ts +142 -67
  173. package/sdk/dist/generated/dvn_fee_lib.js +64 -24
  174. package/sdk/dist/generated/endpoint.d.ts +97 -22
  175. package/sdk/dist/generated/endpoint.js +75 -37
  176. package/sdk/dist/generated/executor.d.ts +117 -85
  177. package/sdk/dist/generated/executor.js +102 -59
  178. package/sdk/dist/generated/executor_fee_lib.d.ts +162 -78
  179. package/sdk/dist/generated/executor_fee_lib.js +104 -57
  180. package/sdk/dist/generated/executor_helper.d.ts +133 -21
  181. package/sdk/dist/generated/executor_helper.js +99 -50
  182. package/sdk/dist/generated/oft_std.d.ts +233 -55
  183. package/sdk/dist/generated/oft_std.js +99 -54
  184. package/sdk/dist/generated/price_feed.d.ts +142 -67
  185. package/sdk/dist/generated/price_feed.js +64 -24
  186. package/sdk/dist/generated/sml.d.ts +113 -32
  187. package/sdk/dist/generated/sml.js +93 -49
  188. package/sdk/dist/generated/treasury.d.ts +896 -0
  189. package/sdk/dist/generated/treasury.js +219 -0
  190. package/sdk/dist/generated/uln302.d.ts +113 -32
  191. package/sdk/dist/generated/uln302.js +93 -49
  192. package/sdk/dist/generated/upgrader.d.ts +2 -2
  193. package/sdk/dist/generated/upgrader.js +1 -1
  194. package/sdk/dist/index.d.ts +2 -0
  195. package/sdk/dist/index.js +3 -0
  196. package/sdk/dist/wasm/blocked-message-lib.d.ts +1 -0
  197. package/sdk/dist/wasm/blocked-message-lib.js +2 -0
  198. package/sdk/dist/wasm/counter.d.ts +1 -0
  199. package/sdk/dist/wasm/counter.js +2 -0
  200. package/sdk/dist/wasm/dvn-fee-lib.d.ts +1 -0
  201. package/sdk/dist/wasm/dvn-fee-lib.js +2 -0
  202. package/sdk/dist/wasm/dvn.d.ts +1 -0
  203. package/sdk/dist/wasm/dvn.js +2 -0
  204. package/sdk/dist/wasm/endpoint-v2.d.ts +1 -0
  205. package/sdk/dist/wasm/endpoint-v2.js +2 -0
  206. package/sdk/dist/wasm/executor-fee-lib.d.ts +1 -0
  207. package/sdk/dist/wasm/executor-fee-lib.js +2 -0
  208. package/sdk/dist/wasm/executor-helper.d.ts +1 -0
  209. package/sdk/dist/wasm/executor-helper.js +2 -0
  210. package/sdk/dist/wasm/executor.d.ts +1 -0
  211. package/sdk/dist/wasm/executor.js +2 -0
  212. package/sdk/dist/wasm/layerzero-views.d.ts +1 -0
  213. package/sdk/dist/wasm/layerzero-views.js +2 -0
  214. package/sdk/dist/wasm/oft-std.d.ts +1 -0
  215. package/sdk/dist/wasm/oft-std.js +2 -0
  216. package/sdk/dist/wasm/price-feed.d.ts +1 -0
  217. package/sdk/dist/wasm/price-feed.js +2 -0
  218. package/sdk/dist/wasm/simple-message-lib.d.ts +1 -0
  219. package/sdk/dist/wasm/simple-message-lib.js +2 -0
  220. package/sdk/dist/wasm/treasury.d.ts +1 -0
  221. package/sdk/dist/wasm/treasury.js +2 -0
  222. package/sdk/dist/wasm/uln302.d.ts +1 -0
  223. package/sdk/dist/wasm/uln302.js +2 -0
  224. package/sdk/dist/wasm/upgrader.d.ts +1 -0
  225. package/sdk/dist/wasm/upgrader.js +2 -0
  226. package/sdk/dist/wasm.d.ts +15 -0
  227. package/sdk/dist/wasm.js +15 -0
  228. package/sdk/package.json +4 -2
  229. package/sdk/src/index.ts +4 -0
  230. package/sdk/test/counter-sml.test.ts +376 -0
  231. package/sdk/test/counter-uln.test.ts +493 -0
  232. package/sdk/test/{oft.test.ts → oft-sml.test.ts} +185 -310
  233. package/sdk/test/suites/constants.ts +22 -2
  234. package/sdk/test/suites/globalSetup.ts +450 -0
  235. package/sdk/test/suites/localnet.ts +23 -6
  236. package/sdk/test/upgrader.test.ts +7 -16
  237. package/sdk/test/utils.ts +558 -85
  238. package/sdk/vitest.config.ts +21 -0
  239. package/tools/ts-bindings-gen/src/main.rs +1 -0
  240. package/turbo.json +2 -0
  241. package/contracts/common-macros/src/contract_impl.rs +0 -52
  242. package/contracts/common-macros/src/ownable.rs +0 -41
  243. package/contracts/common-macros/src/tests/contract_impl.rs +0 -386
  244. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__ownable__snapshot_generated_ownable_code.snap +0 -12
  245. package/contracts/macro-integration-tests/tests/runtime/ttl_configurable/extend_instance_ttl.rs +0 -50
  246. package/contracts/oapps/oapp-macros/src/oapp_core.rs +0 -41
  247. package/contracts/oapps/oapp-macros/src/oapp_full.rs +0 -21
  248. package/contracts/oapps/oapp-macros/src/oapp_options_type3.rs +0 -31
  249. package/contracts/oapps/oapp-macros/src/oapp_receiver.rs +0 -48
  250. package/contracts/oapps/oapp-macros/src/oapp_sender.rs +0 -21
  251. package/contracts/oapps/oapp-macros/src/util.rs +0 -107
  252. package/contracts/oapps/oft/src/constants.rs +0 -5
  253. package/contracts/oapps/oft/src/default_oft_impl.rs +0 -152
  254. package/contracts/workers/dvn/src/interfaces/multisig.rs +0 -56
  255. package/contracts/workers/dvn/src/multisig.rs +0 -157
  256. package/sdk/test/index.test.ts +0 -375
  257. /package/sdk/test/suites/{testUpgradeable.ts → dummyContractClient.ts} +0 -0
@@ -1,48 +0,0 @@
1
- use heck::ToSnakeCase;
2
- use proc_macro2::TokenStream;
3
- use quote::quote;
4
- use syn::Ident;
5
-
6
- /// Generates the `OAppReceiver` trait implementation.
7
- ///
8
- /// When `manual_impl_receiver` is false, generates `lz_receive` that calls
9
- /// `verify_and_clear_payload` then delegates to the user's `__lz_receive` method.
10
- pub fn generate_impl(name: &Ident, manual_impl_receiver: bool) -> TokenStream {
11
- // Use a distinct module name to avoid conflicts with oapp_core's module
12
- let impl_mod = syn::Ident::new(&format!("__oapp_receiver_impl_{}", name.to_string().to_snake_case()), name.span());
13
-
14
- let receiver_impl = (!manual_impl_receiver).then(|| {
15
- quote! {
16
- // OAppReceiver implementation
17
- // This generates contract entry points that are callable via LayerZeroReceiverClient
18
- // because the function names match ILayerZeroReceiver's interface.
19
- #[doc(hidden)]
20
- mod #impl_mod {
21
- use super::*;
22
- use soroban_sdk::{Address, Bytes, BytesN, Env};
23
- use endpoint_v2::Origin;
24
- use oapp::oapp_receiver::OAppReceiver;
25
-
26
- #[soroban_sdk::contractimpl(contracttrait)]
27
- impl OAppReceiver for #name {
28
- fn lz_receive(
29
- env: &soroban_sdk::Env,
30
- executor: &soroban_sdk::Address,
31
- origin: &endpoint_v2::Origin,
32
- guid: &soroban_sdk::BytesN<32>,
33
- message: &soroban_sdk::Bytes,
34
- extra_data: &soroban_sdk::Bytes,
35
- value: i128,
36
- ) {
37
- oapp::oapp_receiver::verify_and_clear_payload::<Self>(env, executor, origin, guid, message, value);
38
- Self::__lz_receive(env, executor, origin, guid, message, extra_data, value)
39
- }
40
- }
41
- }
42
- }
43
- });
44
-
45
- quote! {
46
- #receiver_impl
47
- }
48
- }
@@ -1,21 +0,0 @@
1
- use proc_macro2::TokenStream;
2
- use quote::quote;
3
- use syn::Ident;
4
-
5
- /// Generates the `OAppSender` trait implementation.
6
- ///
7
- /// When `manual_impl_sender` is false, generates an empty `impl OAppSender`
8
- /// that uses the trait's default implementations for `lz_quote` and `lz_send`...
9
- pub fn generate_impl(name: &Ident, manual_impl_sender: bool) -> TokenStream {
10
- let sender_impl = (!manual_impl_sender).then(|| {
11
- quote! {
12
- use oapp::oapp_sender::OAppSender as _;
13
-
14
- impl oapp::oapp_sender::OAppSender for #name {}
15
- }
16
- });
17
-
18
- quote! {
19
- #sender_impl
20
- }
21
- }
@@ -1,107 +0,0 @@
1
- use proc_macro::TokenStream;
2
- use proc_macro2::Ident;
3
- use syn::{
4
- parse::{Parse, ParseStream},
5
- punctuated::Punctuated,
6
- Error, ItemStruct, Token,
7
- };
8
-
9
- /// Configuration for which OApp trait implementations should be manually provided by the user.
10
- ///
11
- /// This struct is parsed from the `#[oapp_manual_impl(...)]` attribute and controls
12
- /// which default trait implementations are generated by the macros.
13
- ///
14
- /// # Fields
15
- /// * `core` - If `true`, the user must manually implement `OAppCore`
16
- /// * `sender` - If `true`, the user must manually implement `OAppSender`
17
- /// * `receiver` - If `true`, the user must manually implement `OAppReceiver` trait entirely
18
- /// * `options_type3` - If `true`, the user must manually implement `OAppOptionsType3`
19
- ///
20
- /// # Receiver Manual Implementation
21
- /// When `receiver` is `true`, the macro will NOT generate `impl OAppReceiver`. The user
22
- /// must manually implement the entire `OAppReceiver` trait, including `lz_receive`,
23
- /// `next_nonce`, `allow_initialize_path`, and `is_compose_msg_sender`.
24
- ///
25
- /// This is useful when you need to customize methods like `next_nonce` (e.g., for ordered delivery).
26
- #[derive(Debug, Clone, Copy, Default)]
27
- pub struct ManualImplConfig {
28
- pub core: bool,
29
- pub sender: bool,
30
- pub receiver: bool,
31
- pub options_type3: bool,
32
- }
33
-
34
- impl ManualImplConfig {
35
- /// Parses configuration from the `#[oapp_manual_impl(...)]` attribute arguments.
36
- ///
37
- /// Accepts a comma-separated list of identifiers: `core`, `sender`, `receiver`, `options_type3`.
38
- /// Returns an error if any invalid identifier is provided.
39
- fn from_attr(input: ParseStream) -> syn::Result<Self> {
40
- let idents = Punctuated::<syn::Ident, Token![,]>::parse_terminated(input)?;
41
-
42
- let mut cfg = ManualImplConfig::default();
43
-
44
- for ident in idents {
45
- match ident.to_string().as_str() {
46
- "core" => cfg.core = true,
47
- "sender" => cfg.sender = true,
48
- "receiver" => cfg.receiver = true,
49
- "options_type3" => cfg.options_type3 = true,
50
- _ => {
51
- return Err(Error::new(
52
- ident.span(),
53
- "invalid value for oapp_manual_impl: expected one of `core`, `sender`, `receiver`, `options_type3`",
54
- ));
55
- }
56
- }
57
- }
58
-
59
- Ok(cfg)
60
- }
61
- }
62
-
63
- impl Parse for ManualImplConfig {
64
- fn parse(input: ParseStream) -> syn::Result<Self> {
65
- ManualImplConfig::from_attr(input)
66
- }
67
- }
68
-
69
- /// Parses a struct definition and extracts manual implementation configuration.
70
- ///
71
- /// This function is used by all OApp macros to:
72
- /// 1. Parse the annotated item as a struct
73
- /// 2. Extract the struct name
74
- /// 3. Parse any `#[oapp_manual_impl(...)]` attributes to determine configuration
75
- ///
76
- /// # Returns
77
- /// A tuple containing:
78
- /// * The struct identifier
79
- /// * The complete struct definition
80
- /// * The manual implementation configuration
81
- ///
82
- /// # Errors
83
- /// Returns a compile error if:
84
- /// * The item is not a struct
85
- /// * The `#[oapp_manual_impl(...)]` attribute has invalid syntax
86
- pub fn parse_struct(item: TokenStream) -> Result<(Ident, ItemStruct, ManualImplConfig), TokenStream> {
87
- let item_struct = syn::parse::<ItemStruct>(item).map_err(|e| e.to_compile_error())?;
88
- let name = item_struct.ident.clone();
89
-
90
- let mut cfg = ManualImplConfig::default();
91
- // TODO: match at most once oapp_manual_impl attribute
92
- for attr in item_struct.attrs.iter() {
93
- if attr.path().is_ident("oapp_manual_impl") {
94
- match attr.parse_args::<ManualImplConfig>() {
95
- Ok(parsed) => {
96
- cfg = parsed;
97
- }
98
- Err(e) => {
99
- return Err(e.to_compile_error().into());
100
- }
101
- }
102
- break;
103
- }
104
- }
105
-
106
- Ok((name, item_struct, cfg))
107
- }
@@ -1,5 +0,0 @@
1
- /// Message type for simple OFT send
2
- pub const SEND: u32 = 1;
3
-
4
- /// Message type for OFT send with compose functionality
5
- pub const SEND_AND_CALL: u32 = 2;
@@ -1,152 +0,0 @@
1
- //! Default OFT implementations.
2
- //!
3
- //! This module provides default standalone functions for common OFT operations that can be
4
- //! reused by trait implementations.
5
-
6
- use crate::{
7
- codec::{oft_compose_msg_codec::OFTComposeMsg, oft_msg_codec::OFTMessage},
8
- constants,
9
- errors::OFTError,
10
- events,
11
- events::OFTSent,
12
- storage::OFTStorage,
13
- types::{OFTFeeDetail, OFTLimit, OFTReceipt, SendParam},
14
- utils::{address_to_bytes32, remove_dust, resolve_address, to_ld, to_sd},
15
- };
16
- use endpoint_v2::{MessagingComposerClient, MessagingFee, MessagingReceipt, Origin};
17
- use oapp::oapp_options_type3::OAppOptionsType3;
18
- use soroban_sdk::{assert_with_error, vec, Address, Bytes, BytesN, Env, Vec};
19
-
20
- /// Calculates debit amounts without executing (view function).
21
- pub fn default_debit_view(env: &Env, amount_ld: i128, min_amount_ld: i128, _dst_eid: u32) -> OFTReceipt {
22
- let conversion_rate = OFTStorage::decimal_conversion_rate(env).unwrap();
23
- let amount_sent_ld = remove_dust(amount_ld, conversion_rate);
24
- let amount_received_ld = amount_sent_ld;
25
-
26
- assert_with_error!(env, amount_received_ld >= min_amount_ld, OFTError::SlippageExceeded);
27
-
28
- OFTReceipt { amount_sent_ld, amount_received_ld }
29
- }
30
-
31
- /// Builds OFT message and combines options for cross-chain transfer.
32
- pub fn default_build_msg_and_options<T>(
33
- env: &Env,
34
- sender: &Address,
35
- send_param: &SendParam,
36
- amount_ld: i128,
37
- ) -> (Bytes, Bytes)
38
- where
39
- T: OAppOptionsType3,
40
- {
41
- let has_compose = !send_param.compose_msg.is_empty();
42
- let conversion_rate = OFTStorage::decimal_conversion_rate(env).unwrap();
43
- let msg = OFTMessage {
44
- send_to: send_param.to.clone(),
45
- amount_sd: to_sd(env, amount_ld, conversion_rate),
46
- compose_from: if has_compose { Some(address_to_bytes32(sender)) } else { None },
47
- compose_msg: if has_compose { Some(send_param.compose_msg.clone()) } else { None },
48
- };
49
- let (msg, _) = msg.encode(env);
50
- let msg_type = if has_compose { constants::SEND_AND_CALL } else { constants::SEND };
51
-
52
- (msg, T::combine_options(env, send_param.dst_eid, msg_type, &send_param.extra_options))
53
- }
54
-
55
- /// Handles OFT receive logic.
56
- pub fn default_lz_receive<T>(
57
- env: &Env,
58
- _executor: &Address,
59
- origin: &Origin,
60
- guid: &BytesN<32>,
61
- message: &Bytes,
62
- _extra_data: &Bytes,
63
- _value: i128,
64
- ) where
65
- T: crate::oft::OFTInternal,
66
- {
67
- let oft_msg = OFTMessage::decode(message);
68
- let send_to = resolve_address(env, &oft_msg.send_to);
69
-
70
- let conversion_rate = OFTStorage::decimal_conversion_rate(env).unwrap();
71
- let amount_received_ld = T::__credit(env, &send_to, to_ld(oft_msg.amount_sd, conversion_rate), origin.src_eid);
72
-
73
- if oft_msg.is_composed() {
74
- let compose_msg = OFTComposeMsg {
75
- nonce: origin.nonce,
76
- src_eid: origin.src_eid,
77
- amount_ld: amount_received_ld,
78
- compose_from: oft_msg.compose_from.unwrap(),
79
- compose_msg: oft_msg.compose_msg.unwrap(),
80
- }
81
- .encode(env);
82
-
83
- let endpoint = MessagingComposerClient::new(env, &T::endpoint(env));
84
- endpoint.send_compose(&env.current_contract_address(), &send_to, guid, &0, &compose_msg);
85
- }
86
-
87
- events::OFTReceived { guid: guid.clone(), src_eid: origin.src_eid, to: send_to, amount_received_ld }.publish(env);
88
- }
89
-
90
- /// Quotes an OFT transfer without executing.
91
- /// Returns (OFTLimit, fee details, receipt with estimated amounts).
92
- pub fn default_quote_oft<T>(env: &Env, send_param: &SendParam) -> (OFTLimit, Vec<OFTFeeDetail>, OFTReceipt)
93
- where
94
- T: crate::oft::OFTInternal,
95
- {
96
- let oft_receipt = T::__debit_view(env, send_param.amount_ld, send_param.min_amount_ld, send_param.dst_eid);
97
- let oft_fee_details = if oft_receipt.amount_sent_ld > oft_receipt.amount_received_ld {
98
- vec![
99
- env,
100
- OFTFeeDetail {
101
- fee_amount_ld: oft_receipt.amount_sent_ld - oft_receipt.amount_received_ld,
102
- description: Bytes::from_array(env, b"OFT Fee"),
103
- },
104
- ]
105
- } else {
106
- vec![env]
107
- };
108
- (OFTLimit { min_amount_ld: 0, max_amount_ld: i128::MAX }, oft_fee_details, oft_receipt)
109
- }
110
-
111
- /// Quotes a send operation including LayerZero messaging fees.
112
- pub fn default_quote_send<T>(env: &Env, sender: &Address, send_param: &SendParam, pay_in_zro: bool) -> MessagingFee
113
- where
114
- T: crate::oft::OFT,
115
- {
116
- let OFTReceipt { amount_received_ld, .. } =
117
- T::__debit_view(env, send_param.amount_ld, send_param.min_amount_ld, send_param.dst_eid);
118
-
119
- let (msg, options) = default_build_msg_and_options::<T>(env, sender, send_param, amount_received_ld);
120
- T::lz_quote(env, send_param.dst_eid, &msg, &options, pay_in_zro)
121
- }
122
-
123
- /// Sends tokens cross-chain to another endpoint.
124
- /// Sender must be authenticated. Returns (MessagingReceipt, OFTReceipt).
125
- pub fn default_send<T>(
126
- env: &Env,
127
- sender: &Address,
128
- send_param: &SendParam,
129
- fee: &MessagingFee,
130
- refund_address: &Address,
131
- ) -> (MessagingReceipt, OFTReceipt)
132
- where
133
- T: crate::oft::OFT,
134
- {
135
- sender.require_auth();
136
-
137
- let oft_receipt = T::__debit(env, sender, send_param.amount_ld, send_param.min_amount_ld, send_param.dst_eid);
138
-
139
- let (msg, options) = default_build_msg_and_options::<T>(env, sender, send_param, oft_receipt.amount_received_ld);
140
- let msg_receipt = T::lz_send(env, sender, send_param.dst_eid, &msg, &options, fee, refund_address);
141
-
142
- OFTSent {
143
- guid: msg_receipt.guid.clone(),
144
- dst_eid: send_param.dst_eid,
145
- from: sender.clone(),
146
- amount_sent_ld: oft_receipt.amount_sent_ld,
147
- amount_received_ld: oft_receipt.amount_received_ld,
148
- }
149
- .publish(env);
150
-
151
- (msg_receipt, oft_receipt)
152
- }
@@ -1,56 +0,0 @@
1
- use soroban_sdk::{contractclient, BytesN, Env, Vec};
2
-
3
- /// Length of an ECDSA signature (64 bytes) plus recovery ID (1 byte).
4
- pub const SIGNATURE_LENGTH: usize = 65;
5
-
6
- /// Multisig interface for threshold-based signature verification.
7
- ///
8
- /// Provides functionality to manage signers and verify that a sufficient
9
- /// number of valid signatures (meeting the threshold) have signed a message.
10
- #[contractclient(name = "MultiSigClient")]
11
- pub trait IMultisig {
12
- /// Adds or removes a signer from the multisig.
13
- ///
14
- /// # Arguments
15
- /// * `signer` - The 20-byte signer address (derived from secp256k1 public key)
16
- /// * `active` - `true` to add, `false` to remove
17
- fn set_signer(env: &Env, signer: &BytesN<20>, active: bool);
18
-
19
- /// Returns all registered signers.
20
- fn get_signers(env: &Env) -> Vec<BytesN<20>>;
21
-
22
- /// Returns the total number of registered signers.
23
- fn total_signers(env: &Env) -> u32;
24
-
25
- /// Checks if an address is a registered signer.
26
- fn is_signer(env: &Env, signer: &BytesN<20>) -> bool;
27
-
28
- /// Returns the current signature threshold (quorum).
29
- fn threshold(env: &Env) -> u32;
30
-
31
- /// Sets the signature threshold (quorum).
32
- ///
33
- /// The threshold must be greater than 0 and not exceed total signers.
34
- fn set_threshold(env: &Env, threshold: u32);
35
-
36
- /// Verifies signatures against the configured threshold.
37
- ///
38
- /// # Arguments
39
- /// * `hash` - The 32-byte message hash that was signed
40
- /// * `signatures` - List of signatures to verify
41
- ///
42
- /// # Panics
43
- /// If fewer than `threshold` valid signatures from registered signers are provided.
44
- fn verify_signatures(env: &Env, hash: &BytesN<32>, signatures: &Vec<BytesN<SIGNATURE_LENGTH>>);
45
-
46
- /// Verifies signatures against a custom threshold.
47
- ///
48
- /// # Arguments
49
- /// * `hash` - The 32-byte message hash that was signed
50
- /// * `signatures` - List of signatures to verify
51
- /// * `threshold` - Custom threshold to use instead of the configured one
52
- ///
53
- /// # Panics
54
- /// If fewer than `threshold` valid signatures from registered signers are provided.
55
- fn verify_n_signatures(env: &Env, hash: &BytesN<32>, signatures: &Vec<BytesN<SIGNATURE_LENGTH>>, threshold: u32);
56
- }
@@ -1,157 +0,0 @@
1
- //! Multisig functionality for the DVN contract.
2
- //!
3
- //! Provides secp256k1-based multisig signature verification using Ethereum-style
4
- //! 20-byte addresses derived from recovered public keys.
5
-
6
- use super::*;
7
-
8
- use crate::{
9
- errors::DvnError,
10
- events::{SignerSet, ThresholdSet},
11
- storage::DvnStorage,
12
- };
13
- use common_macros::only_owner;
14
- use soroban_sdk::assert_with_error;
15
-
16
- // ============================================================================
17
- // IMultisig Implementation
18
- // ============================================================================
19
-
20
- #[contract_impl]
21
- impl IMultisig for LzDVN {
22
- /// Adds or removes a signer. Requires multisig approval.
23
- #[only_owner]
24
- fn set_signer(env: &Env, signer: &BytesN<20>, active: bool) {
25
- if active {
26
- Self::add_signer(env, signer);
27
- } else {
28
- Self::remove_signer(env, signer);
29
- }
30
- }
31
-
32
- /// Updates the signature threshold. Requires multisig approval.
33
- #[only_owner]
34
- fn set_threshold(env: &Env, threshold: u32) {
35
- assert_with_error!(env, threshold > 0, DvnError::ZeroThreshold);
36
- assert_with_error!(env, Self::total_signers(env) >= threshold, DvnError::TotalSignersLessThanThreshold);
37
-
38
- DvnStorage::set_threshold(env, &threshold);
39
-
40
- ThresholdSet { threshold }.publish(env);
41
- }
42
-
43
- // ================================================================
44
- // View Functions
45
- // ================================================================
46
-
47
- /// Returns the list of all registered signers.
48
- fn get_signers(env: &Env) -> Vec<BytesN<20>> {
49
- DvnStorage::signers(env)
50
- }
51
-
52
- /// Returns the total number of registered signers.
53
- fn total_signers(env: &Env) -> u32 {
54
- DvnStorage::signers(env).len()
55
- }
56
-
57
- /// Checks if an address is a registered signer.
58
- fn is_signer(env: &Env, signer: &BytesN<20>) -> bool {
59
- DvnStorage::signers(env).iter().any(|s| &s == signer)
60
- }
61
-
62
- /// Returns the current signature threshold.
63
- fn threshold(env: &Env) -> u32 {
64
- DvnStorage::threshold(env)
65
- }
66
-
67
- /// Verifies signatures against the current threshold.
68
- fn verify_signatures(env: &Env, hash: &BytesN<32>, signatures: &Vec<BytesN<65>>) {
69
- Self::verify_n_signatures(env, hash, signatures, Self::threshold(env));
70
- }
71
-
72
- /// Verifies that at least `threshold` valid signatures exist for the given hash.
73
- ///
74
- /// Signatures must be:
75
- /// - From registered signers
76
- /// - Sorted by signer address (ascending, no duplicates)
77
- fn verify_n_signatures(env: &Env, hash: &BytesN<32>, signatures: &Vec<BytesN<65>>, threshold: u32) {
78
- assert_with_error!(env, threshold > 0, DvnError::ZeroThreshold);
79
- assert_with_error!(env, signatures.len() >= threshold, DvnError::SignatureError);
80
-
81
- let mut last_signer: Option<BytesN<20>> = None;
82
- signatures.iter().for_each(|signature| {
83
- let signer = Self::recover_signer(env, hash, &signature);
84
-
85
- // Signers must be strictly increasing (ensures no duplicates)
86
- assert_with_error!(env, last_signer.as_ref().is_none_or(|last| &signer > last), DvnError::UnsortedSigners);
87
- assert_with_error!(env, Self::is_signer(env, &signer), DvnError::SignerNotFound);
88
-
89
- last_signer = Some(signer);
90
- });
91
- }
92
- }
93
-
94
- // ============================================================================
95
- // Internal Functions
96
- // ============================================================================
97
-
98
- impl LzDVN {
99
- /// Initializes the multisig with a set of signers and threshold.
100
- /// Called during contract construction.
101
- pub(super) fn init_multisig(env: &Env, signers: &Vec<BytesN<20>>, threshold: u32) {
102
- signers.iter().for_each(|signer| Self::add_signer(env, &signer));
103
- Self::set_threshold(env, threshold);
104
- }
105
-
106
- /// Adds a new signer to the multisig.
107
- ///
108
- /// # Errors
109
- /// - `InvalidSigner` if the signer is the zero address
110
- /// - `SignerAlreadyExists` if the signer is already registered
111
- fn add_signer(env: &Env, signer: &BytesN<20>) {
112
- let zero_signer = BytesN::from_array(env, &[0u8; 20]);
113
- assert_with_error!(env, signer != &zero_signer, DvnError::InvalidSigner);
114
-
115
- let mut signers = Self::get_signers(env);
116
- assert_with_error!(env, !signers.iter().any(|s| &s == signer), DvnError::SignerAlreadyExists);
117
- signers.push_back(signer.clone());
118
- DvnStorage::set_signers(env, &signers);
119
-
120
- SignerSet { signer: signer.clone(), active: true }.publish(env);
121
- }
122
-
123
- /// Removes a signer from the multisig.
124
- ///
125
- /// # Errors
126
- /// - `SignerNotFound` if the signer is not registered
127
- /// - `TotalSignersLessThanThreshold` if removal would violate threshold constraint
128
- fn remove_signer(env: &Env, signer: &BytesN<20>) {
129
- let mut signers = Self::get_signers(env);
130
- let index = signers.first_index_of(signer);
131
- assert_with_error!(env, index.is_some(), DvnError::SignerNotFound);
132
-
133
- signers.remove(index.unwrap());
134
-
135
- // Ensure removal doesn't violate threshold constraint
136
- assert_with_error!(env, signers.len() >= Self::threshold(env), DvnError::TotalSignersLessThanThreshold);
137
- DvnStorage::set_signers(env, &signers);
138
-
139
- SignerSet { signer: signer.clone(), active: false }.publish(env);
140
- }
141
-
142
- /// Recovers the Ethereum-style signer address from a secp256k1 signature.
143
- ///
144
- /// The signature format is 65 bytes: r (32) + s (32) + v (1).
145
- /// Returns the last 20 bytes of keccak256(uncompressed_pubkey[1..65]).
146
- fn recover_signer(env: &Env, digest: &BytesN<32>, signature: &BytesN<65>) -> BytesN<20> {
147
- let sig_bytes: Bytes = signature.into();
148
- let v = sig_bytes.get(64).unwrap();
149
- let recovery_id = if (27..=30).contains(&v) { v - 27 } else { v };
150
- let sig_rs: BytesN<64> = sig_bytes.slice(0..64).try_into().unwrap();
151
-
152
- let public_key = env.crypto_hazmat().secp256k1_recover(digest, &sig_rs, recovery_id as u32);
153
-
154
- // Derive Ethereum address: keccak256(pubkey[1..65])[12..32]
155
- Bytes::from(env.crypto().keccak256(&Bytes::from(public_key).slice(1..65))).slice(12..32).try_into().unwrap()
156
- }
157
- }