@layerzerolabs/protocol-stellar-v2 0.2.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +727 -0
- package/.turbo/turbo-lint.log +158 -0
- package/.turbo/turbo-test.log +796 -0
- package/Cargo.lock +2237 -0
- package/Cargo.toml +63 -0
- package/clippy.toml +7 -0
- package/contracts/common-macros/Cargo.toml +20 -0
- package/contracts/common-macros/src/error.rs +53 -0
- package/contracts/common-macros/src/event.rs +16 -0
- package/contracts/common-macros/src/lib.rs +255 -0
- package/contracts/common-macros/src/ownable.rs +63 -0
- package/contracts/common-macros/src/snapshots/common_macros__tests__tests__snapshot_generated_storage_code.snap +310 -0
- package/contracts/common-macros/src/storage.rs +439 -0
- package/contracts/common-macros/src/tests.rs +287 -0
- package/contracts/common-macros/src/ttl_configurable.rs +60 -0
- package/contracts/endpoint-v2/ARCHITECTURE.md +233 -0
- package/contracts/endpoint-v2/Cargo.toml +30 -0
- package/contracts/endpoint-v2/src/constants.rs +52 -0
- package/contracts/endpoint-v2/src/endpoint_v2.rs +305 -0
- package/contracts/endpoint-v2/src/errors.rs +29 -0
- package/contracts/endpoint-v2/src/events.rs +207 -0
- package/contracts/endpoint-v2/src/interfaces/layerzero_composer.rs +26 -0
- package/contracts/endpoint-v2/src/interfaces/layerzero_endpoint_v2.rs +170 -0
- package/contracts/endpoint-v2/src/interfaces/layerzero_receiver.rs +43 -0
- package/contracts/endpoint-v2/src/interfaces/message_lib.rs +62 -0
- package/contracts/endpoint-v2/src/interfaces/message_lib_manager.rs +220 -0
- package/contracts/endpoint-v2/src/interfaces/messaging_channel.rs +121 -0
- package/contracts/endpoint-v2/src/interfaces/messaging_composer.rs +63 -0
- package/contracts/endpoint-v2/src/interfaces/mod.rs +17 -0
- package/contracts/endpoint-v2/src/interfaces/send_lib.rs +70 -0
- package/contracts/endpoint-v2/src/lib.rs +22 -0
- package/contracts/endpoint-v2/src/message_lib_manager.rs +315 -0
- package/contracts/endpoint-v2/src/messaging_channel.rs +218 -0
- package/contracts/endpoint-v2/src/messaging_composer.rs +76 -0
- package/contracts/endpoint-v2/src/storage.rs +78 -0
- package/contracts/endpoint-v2/src/tests/endpoint_setup.rs +131 -0
- package/contracts/endpoint-v2/src/tests/endpoint_v2/clear.rs +237 -0
- package/contracts/endpoint-v2/src/tests/endpoint_v2/delegate.rs +42 -0
- package/contracts/endpoint-v2/src/tests/endpoint_v2/initializable.rs +76 -0
- package/contracts/endpoint-v2/src/tests/endpoint_v2/lz_receive_alert.rs +211 -0
- package/contracts/endpoint-v2/src/tests/endpoint_v2/mod.rs +18 -0
- package/contracts/endpoint-v2/src/tests/endpoint_v2/native_token.rs +10 -0
- package/contracts/endpoint-v2/src/tests/endpoint_v2/owner.rs +10 -0
- package/contracts/endpoint-v2/src/tests/endpoint_v2/pay_messaging_fees.rs +424 -0
- package/contracts/endpoint-v2/src/tests/endpoint_v2/quote.rs +144 -0
- package/contracts/endpoint-v2/src/tests/endpoint_v2/recover_token.rs +72 -0
- package/contracts/endpoint-v2/src/tests/endpoint_v2/require_oapp_auth.rs +29 -0
- package/contracts/endpoint-v2/src/tests/endpoint_v2/send.rs +513 -0
- package/contracts/endpoint-v2/src/tests/endpoint_v2/set_delegate.rs +43 -0
- package/contracts/endpoint-v2/src/tests/endpoint_v2/set_zro.rs +27 -0
- package/contracts/endpoint-v2/src/tests/endpoint_v2/transfer_ownership.rs +30 -0
- package/contracts/endpoint-v2/src/tests/endpoint_v2/ttl_config.rs +202 -0
- package/contracts/endpoint-v2/src/tests/endpoint_v2/verifiable.rs +59 -0
- package/contracts/endpoint-v2/src/tests/endpoint_v2/verify.rs +172 -0
- package/contracts/endpoint-v2/src/tests/endpoint_v2/zro.rs +23 -0
- package/contracts/endpoint-v2/src/tests/message_lib_manager/mod.rs +10 -0
- package/contracts/endpoint-v2/src/tests/message_lib_manager/register_library.rs +131 -0
- package/contracts/endpoint-v2/src/tests/message_lib_manager/require_registered.rs +35 -0
- package/contracts/endpoint-v2/src/tests/message_lib_manager/require_supported_eid.rs +28 -0
- package/contracts/endpoint-v2/src/tests/message_lib_manager/set_config.rs +79 -0
- package/contracts/endpoint-v2/src/tests/message_lib_manager/set_default_receive_lib_timeout.rs +246 -0
- package/contracts/endpoint-v2/src/tests/message_lib_manager/set_default_receive_library.rs +285 -0
- package/contracts/endpoint-v2/src/tests/message_lib_manager/set_default_send_library.rs +180 -0
- package/contracts/endpoint-v2/src/tests/message_lib_manager/set_receive_library.rs +405 -0
- package/contracts/endpoint-v2/src/tests/message_lib_manager/set_receive_library_timeout.rs +80 -0
- package/contracts/endpoint-v2/src/tests/message_lib_manager/set_send_library.rs +131 -0
- package/contracts/endpoint-v2/src/tests/messaging_channel/burn.rs +358 -0
- package/contracts/endpoint-v2/src/tests/messaging_channel/clear.rs +316 -0
- package/contracts/endpoint-v2/src/tests/messaging_channel/inbound_nonce.rs +288 -0
- package/contracts/endpoint-v2/src/tests/messaging_channel/inbound_payload_hash.rs +316 -0
- package/contracts/endpoint-v2/src/tests/messaging_channel/internal.rs +388 -0
- package/contracts/endpoint-v2/src/tests/messaging_channel/lazy_inbound_nonce.rs +307 -0
- package/contracts/endpoint-v2/src/tests/messaging_channel/mod.rs +10 -0
- package/contracts/endpoint-v2/src/tests/messaging_channel/next_guid.rs +239 -0
- package/contracts/endpoint-v2/src/tests/messaging_channel/nilify.rs +324 -0
- package/contracts/endpoint-v2/src/tests/messaging_channel/outbound_nonce.rs +242 -0
- package/contracts/endpoint-v2/src/tests/messaging_channel/skip.rs +232 -0
- package/contracts/endpoint-v2/src/tests/messaging_composer/clear_compose.rs +212 -0
- package/contracts/endpoint-v2/src/tests/messaging_composer/compose_queue.rs +213 -0
- package/contracts/endpoint-v2/src/tests/messaging_composer/lz_compose_alert.rs +269 -0
- package/contracts/endpoint-v2/src/tests/messaging_composer/mod.rs +4 -0
- package/contracts/endpoint-v2/src/tests/messaging_composer/send_compose.rs +173 -0
- package/contracts/endpoint-v2/src/tests/mock.rs +132 -0
- package/contracts/endpoint-v2/src/tests/mod.rs +12 -0
- package/contracts/endpoint-v2/src/tests/util/build_payload.rs +126 -0
- package/contracts/endpoint-v2/src/tests/util/compute_guid.rs +82 -0
- package/contracts/endpoint-v2/src/tests/util/keccak256.rs +115 -0
- package/contracts/endpoint-v2/src/tests/util/mod.rs +3 -0
- package/contracts/endpoint-v2/src/util.rs +52 -0
- package/contracts/message-libs/Cargo.toml +12 -0
- package/contracts/message-libs/block-message-lib/Cargo.toml +19 -0
- package/contracts/message-libs/block-message-lib/src/lib.rs +70 -0
- package/contracts/message-libs/lib.rs +2 -0
- package/contracts/message-libs/message-lib-common/Cargo.toml +24 -0
- package/contracts/message-libs/message-lib-common/src/errors.rs +20 -0
- package/contracts/message-libs/message-lib-common/src/interfaces/dvn.rs +55 -0
- package/contracts/message-libs/message-lib-common/src/interfaces/executor.rs +46 -0
- package/contracts/message-libs/message-lib-common/src/interfaces/mod.rs +7 -0
- package/contracts/message-libs/message-lib-common/src/interfaces/treasury.rs +17 -0
- package/contracts/message-libs/message-lib-common/src/lib.rs +14 -0
- package/contracts/message-libs/message-lib-common/src/packet_codec_v1.rs +99 -0
- package/contracts/message-libs/message-lib-common/src/testing_utils.rs +27 -0
- package/contracts/message-libs/message-lib-common/src/tests/mod.rs +2 -0
- package/contracts/message-libs/message-lib-common/src/tests/packet_codec_v1.rs +162 -0
- package/contracts/message-libs/message-lib-common/src/tests/worker_options.rs +319 -0
- package/contracts/message-libs/message-lib-common/src/worker_options.rs +190 -0
- package/contracts/message-libs/simple-message-lib/Cargo.toml +26 -0
- package/contracts/message-libs/simple-message-lib/src/errors.rs +11 -0
- package/contracts/message-libs/simple-message-lib/src/lib.rs +14 -0
- package/contracts/message-libs/simple-message-lib/src/simple_message_lib.rs +136 -0
- package/contracts/message-libs/simple-message-lib/src/storage.rs +27 -0
- package/contracts/message-libs/simple-message-lib/src/test.rs +280 -0
- package/contracts/message-libs/treasury/Cargo.toml +27 -0
- package/contracts/message-libs/treasury/src/errors.rs +10 -0
- package/contracts/message-libs/treasury/src/events.rs +28 -0
- package/contracts/message-libs/treasury/src/interfaces/mod.rs +3 -0
- package/contracts/message-libs/treasury/src/interfaces/zro_fee_lib.rs +20 -0
- package/contracts/message-libs/treasury/src/lib.rs +20 -0
- package/contracts/message-libs/treasury/src/storage.rs +18 -0
- package/contracts/message-libs/treasury/src/tests/mod.rs +2 -0
- package/contracts/message-libs/treasury/src/tests/setup.rs +112 -0
- package/contracts/message-libs/treasury/src/tests/treasury_tests.rs +562 -0
- package/contracts/message-libs/treasury/src/treasury.rs +140 -0
- package/contracts/message-libs/uln-302/Cargo.toml +28 -0
- package/contracts/message-libs/uln-302/src/config_validation.rs +173 -0
- package/contracts/message-libs/uln-302/src/errors.rs +29 -0
- package/contracts/message-libs/uln-302/src/events.rs +72 -0
- package/contracts/message-libs/uln-302/src/interfaces/mod.rs +5 -0
- package/contracts/message-libs/uln-302/src/interfaces/receive.rs +82 -0
- package/contracts/message-libs/uln-302/src/interfaces/send.rs +159 -0
- package/contracts/message-libs/uln-302/src/lib.rs +20 -0
- package/contracts/message-libs/uln-302/src/receive.rs +199 -0
- package/contracts/message-libs/uln-302/src/send.rs +349 -0
- package/contracts/message-libs/uln-302/src/storage.rs +47 -0
- package/contracts/message-libs/uln-302/src/tests/config/mod.rs +2 -0
- package/contracts/message-libs/uln-302/src/tests/config/oapp_uln_config.rs +291 -0
- package/contracts/message-libs/uln-302/src/tests/config/uln_config.rs +163 -0
- package/contracts/message-libs/uln-302/src/tests/mod.rs +7 -0
- package/contracts/message-libs/uln-302/src/tests/receive_uln302/commit_verification.rs +183 -0
- package/contracts/message-libs/uln-302/src/tests/receive_uln302/confirmations.rs +128 -0
- package/contracts/message-libs/uln-302/src/tests/receive_uln302/effective_receive_uln_config.rs +104 -0
- package/contracts/message-libs/uln-302/src/tests/receive_uln302/mod.rs +66 -0
- package/contracts/message-libs/uln-302/src/tests/receive_uln302/set_default_receive_uln_configs.rs +79 -0
- package/contracts/message-libs/uln-302/src/tests/receive_uln302/verifiable.rs +463 -0
- package/contracts/message-libs/uln-302/src/tests/receive_uln302/verify.rs +173 -0
- package/contracts/message-libs/uln-302/src/tests/send_uln302/effective_executor_config.rs +132 -0
- package/contracts/message-libs/uln-302/src/tests/send_uln302/effective_send_uln_config.rs +117 -0
- package/contracts/message-libs/uln-302/src/tests/send_uln302/mod.rs +6 -0
- package/contracts/message-libs/uln-302/src/tests/send_uln302/quote.rs +586 -0
- package/contracts/message-libs/uln-302/src/tests/send_uln302/send.rs +834 -0
- package/contracts/message-libs/uln-302/src/tests/send_uln302/set_default_executor_configs.rs +95 -0
- package/contracts/message-libs/uln-302/src/tests/send_uln302/set_default_send_uln_configs.rs +80 -0
- package/contracts/message-libs/uln-302/src/tests/setup.rs +268 -0
- package/contracts/message-libs/uln-302/src/tests/testing_utils.rs +47 -0
- package/contracts/message-libs/uln-302/src/tests/uln302/get_app_receive_uln_config.rs +51 -0
- package/contracts/message-libs/uln-302/src/tests/uln302/get_app_send_uln_config.rs +51 -0
- package/contracts/message-libs/uln-302/src/tests/uln302/get_oapp_executor_config.rs +48 -0
- package/contracts/message-libs/uln-302/src/tests/uln302/mod.rs +4 -0
- package/contracts/message-libs/uln-302/src/tests/uln302/set_config.rs +998 -0
- package/contracts/message-libs/uln-302/src/uln302.rs +117 -0
- package/contracts/oapp-macros/Cargo.toml +21 -0
- package/contracts/oapp-macros/src/lib.rs +408 -0
- package/contracts/oapp-macros/src/oapp_core.rs +49 -0
- package/contracts/oapp-macros/src/oapp_full.rs +15 -0
- package/contracts/oapp-macros/src/oapp_options_type3.rs +46 -0
- package/contracts/oapp-macros/src/oapp_receiver.rs +67 -0
- package/contracts/oapp-macros/src/oapp_sender.rs +23 -0
- package/contracts/oapp-macros/src/util.rs +103 -0
- package/contracts/oapp-macros/tests/test_macros.rs +522 -0
- package/contracts/oapps/Cargo.toml +12 -0
- package/contracts/oapps/counter/Cargo.toml +24 -0
- package/contracts/oapps/counter/integration_tests/mod.rs +3 -0
- package/contracts/oapps/counter/integration_tests/setup.rs +201 -0
- package/contracts/oapps/counter/integration_tests/test_with_sml.rs +166 -0
- package/contracts/oapps/counter/integration_tests/utils.rs +144 -0
- package/contracts/oapps/counter/src/codec.rs +63 -0
- package/contracts/oapps/counter/src/counter.rs +235 -0
- package/contracts/oapps/counter/src/errors.rs +9 -0
- package/contracts/oapps/counter/src/lib.rs +16 -0
- package/contracts/oapps/counter/src/options.rs +30 -0
- package/contracts/oapps/counter/src/storage.rs +33 -0
- package/contracts/oapps/counter/src/tests/mod.rs +37 -0
- package/contracts/oapps/counter/src/tests/test_codec.rs +64 -0
- package/contracts/oapps/counter/src/tests/test_counter.rs +390 -0
- package/contracts/oapps/counter/src/u256_ext.rs +21 -0
- package/contracts/oapps/lib.rs +2 -0
- package/contracts/oapps/oapp/Cargo.toml +21 -0
- package/contracts/oapps/oapp/src/errors.rs +9 -0
- package/contracts/oapps/oapp/src/lib.rs +10 -0
- package/contracts/oapps/oapp/src/oapp_core.rs +92 -0
- package/contracts/oapps/oapp/src/oapp_options_type3.rs +89 -0
- package/contracts/oapps/oapp/src/oapp_receiver.rs +72 -0
- package/contracts/oapps/oapp/src/oapp_sender.rs +66 -0
- package/contracts/oapps/oapp/src/tests/mod.rs +4 -0
- package/contracts/oapps/oapp/src/tests/test_oapp_core.rs +162 -0
- package/contracts/oapps/oapp/src/tests/test_oapp_options_type3.rs +180 -0
- package/contracts/oapps/oapp/src/tests/test_oapp_receiver.rs +157 -0
- package/contracts/oapps/oapp/src/tests/test_oapp_sender.rs +283 -0
- package/contracts/utils/Cargo.toml +21 -0
- package/contracts/utils/src/buffer_reader.rs +143 -0
- package/contracts/utils/src/buffer_writer.rs +117 -0
- package/contracts/utils/src/bytes_ext.rs +19 -0
- package/contracts/utils/src/errors.rs +30 -0
- package/contracts/utils/src/lib.rs +15 -0
- package/contracts/utils/src/option_ext.rs +38 -0
- package/contracts/utils/src/ownable.rs +88 -0
- package/contracts/utils/src/testing_utils.rs +100 -0
- package/contracts/utils/src/tests/buffer_reader.rs +1006 -0
- package/contracts/utils/src/tests/buffer_writer.rs +330 -0
- package/contracts/utils/src/tests/bytes_ext.rs +77 -0
- package/contracts/utils/src/tests/mod.rs +4 -0
- package/contracts/utils/src/tests/ownable.rs +149 -0
- package/contracts/utils/src/ttl.rs +164 -0
- package/contracts/workers/Cargo.toml +13 -0
- package/contracts/workers/executor/Cargo.toml +26 -0
- package/contracts/workers/executor/src/events.rs +22 -0
- package/contracts/workers/executor/src/executor.rs +347 -0
- package/contracts/workers/executor/src/interfaces/executor.rs +40 -0
- package/contracts/workers/executor/src/interfaces/mod.rs +5 -0
- package/contracts/workers/executor/src/interfaces/types.rs +51 -0
- package/contracts/workers/executor/src/lib.rs +10 -0
- package/contracts/workers/executor/src/storage.rs +23 -0
- package/contracts/workers/lib.rs +2 -0
- package/contracts/workers/worker-common/Cargo.toml +18 -0
- package/contracts/workers/worker-common/src/constants.rs +17 -0
- package/contracts/workers/worker-common/src/errors.rs +6 -0
- package/contracts/workers/worker-common/src/events.rs +34 -0
- package/contracts/workers/worker-common/src/interfaces/executor_fee_lib.rs +35 -0
- package/contracts/workers/worker-common/src/interfaces/mod.rs +7 -0
- package/contracts/workers/worker-common/src/interfaces/price_feed.rs +40 -0
- package/contracts/workers/worker-common/src/interfaces/worker.rs +60 -0
- package/contracts/workers/worker-common/src/lib.rs +19 -0
- package/contracts/workers/worker-common/src/storage.rs +32 -0
- package/contracts/workers/worker-common/src/worker_common.rs +166 -0
- package/package.json +25 -0
- package/rust-toolchain.toml +4 -0
- package/rustfmt.toml +17 -0
- package/sdk/.turbo/turbo-build.log +4 -0
- package/sdk/dist/generated/bml.d.ts +452 -0
- package/sdk/dist/generated/bml.js +72 -0
- package/sdk/dist/generated/counter.d.ts +824 -0
- package/sdk/dist/generated/counter.js +125 -0
- package/sdk/dist/generated/endpoint.d.ts +1676 -0
- package/sdk/dist/generated/endpoint.js +216 -0
- package/sdk/dist/generated/sml.d.ts +810 -0
- package/sdk/dist/generated/sml.js +132 -0
- package/sdk/dist/generated/uln302.d.ts +1227 -0
- package/sdk/dist/generated/uln302.js +185 -0
- package/sdk/dist/index.d.ts +5 -0
- package/sdk/dist/index.js +5 -0
- package/sdk/node_modules/.bin/tsc +21 -0
- package/sdk/node_modules/.bin/tsserver +21 -0
- package/sdk/node_modules/.bin/vitest +21 -0
- package/sdk/node_modules/.bin/zx +21 -0
- package/sdk/package.json +40 -0
- package/sdk/src/index.ts +5 -0
- package/sdk/test/index.test.ts +271 -0
- package/sdk/test/suites/constants.ts +13 -0
- package/sdk/test/suites/deploy.ts +277 -0
- package/sdk/test/suites/localnet.ts +42 -0
- package/sdk/test/suites/scan.ts +189 -0
- package/sdk/tsconfig.json +106 -0
- package/tools/ts-bindings-gen/Cargo.toml +14 -0
- package/tools/ts-bindings-gen/src/main.rs +147 -0
- package/turbo.json +12 -0
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
// TODO: split this into multiple tests files
|
|
2
|
+
#[cfg(test)]
|
|
3
|
+
mod tests {
|
|
4
|
+
use quote::{quote, ToTokens};
|
|
5
|
+
|
|
6
|
+
// ========================================
|
|
7
|
+
// Storage Type Attribute Tests
|
|
8
|
+
// ========================================
|
|
9
|
+
|
|
10
|
+
#[test]
|
|
11
|
+
#[should_panic(expected = "storage type must be specified exactly once")]
|
|
12
|
+
fn missing_storage_type_attribute_fails() {
|
|
13
|
+
let input: syn::ItemEnum = syn::parse_quote! {
|
|
14
|
+
enum InvalidEnum {
|
|
15
|
+
Counter,
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
crate::storage::generate_storage(quote! {}, input.to_token_stream());
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
#[test]
|
|
22
|
+
#[should_panic(expected = "storage type must be specified exactly once")]
|
|
23
|
+
fn multiple_storage_type_attributes_fails() {
|
|
24
|
+
let input: syn::DeriveInput = syn::parse_quote! {
|
|
25
|
+
enum InvalidEnum {
|
|
26
|
+
#[instance(u32)]
|
|
27
|
+
#[persistent(u32)]
|
|
28
|
+
Counter,
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
crate::storage::generate_storage(quote! {}, input.to_token_stream());
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
#[test]
|
|
35
|
+
#[should_panic(expected = "failed to parse storage variant for Counter")]
|
|
36
|
+
fn storage_type_without_type_parameter_fails() {
|
|
37
|
+
let input: syn::ItemEnum = syn::parse_quote! {
|
|
38
|
+
enum InvalidEnum {
|
|
39
|
+
#[instance]
|
|
40
|
+
Counter,
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
crate::storage::generate_storage(quote! {}, input.to_token_stream());
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
#[test]
|
|
47
|
+
#[should_panic(expected = "failed to parse storage variant for")]
|
|
48
|
+
fn invalid_storage_type_parameter_fails() {
|
|
49
|
+
let input: syn::ItemEnum = syn::parse_quote! {
|
|
50
|
+
enum InvalidEnum {
|
|
51
|
+
#[persistent(!@#$)]
|
|
52
|
+
Counter,
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
crate::storage::generate_storage(quote! {}, input.to_token_stream());
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// ========================================
|
|
59
|
+
// Variant Type Tests
|
|
60
|
+
// ========================================
|
|
61
|
+
|
|
62
|
+
#[test]
|
|
63
|
+
#[should_panic(expected = "failed to parse enum")]
|
|
64
|
+
fn non_enum_struct_fails() {
|
|
65
|
+
let input: syn::DeriveInput = syn::parse_quote! {
|
|
66
|
+
struct NotAnEnum {
|
|
67
|
+
field: u32,
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
crate::storage::generate_storage(quote! {}.into(), input.to_token_stream().into());
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
#[test]
|
|
74
|
+
#[should_panic(expected = "only unit variants or named fields are supported in storage enums")]
|
|
75
|
+
fn tuple_variant_fails() {
|
|
76
|
+
let input: syn::DeriveInput = syn::parse_quote! {
|
|
77
|
+
enum InvalidEnum {
|
|
78
|
+
#[instance(u32)]
|
|
79
|
+
TupleVariant(String, u32),
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
crate::storage::generate_storage(quote! {}.into(), input.to_token_stream().into());
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// ========================================
|
|
86
|
+
// Default Value Tests
|
|
87
|
+
// ========================================
|
|
88
|
+
|
|
89
|
+
#[test]
|
|
90
|
+
#[should_panic(expected = "multiple default values specified")]
|
|
91
|
+
fn multiple_default_attributes_fails() {
|
|
92
|
+
let input: syn::DeriveInput = syn::parse_quote! {
|
|
93
|
+
enum InvalidEnum {
|
|
94
|
+
#[persistent(u32)]
|
|
95
|
+
#[default(0)]
|
|
96
|
+
#[default(1)]
|
|
97
|
+
Counter,
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
crate::storage::generate_storage(quote! {}.into(), input.to_token_stream().into());
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
#[test]
|
|
104
|
+
#[should_panic(expected = "failed to parse default value")]
|
|
105
|
+
fn invalid_default_value_fails() {
|
|
106
|
+
let input: syn::DeriveInput = syn::parse_quote! {
|
|
107
|
+
enum InvalidEnum {
|
|
108
|
+
#[persistent(u32)]
|
|
109
|
+
#[default(!@#$%)]
|
|
110
|
+
Counter,
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
crate::storage::generate_storage(quote! {}.into(), input.to_token_stream().into());
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// ========================================
|
|
117
|
+
// no_auto_ttl_extension Tests
|
|
118
|
+
// ========================================
|
|
119
|
+
|
|
120
|
+
#[test]
|
|
121
|
+
#[should_panic(expected = "no_auto_ttl_extension does not accept arguments")]
|
|
122
|
+
fn no_auto_ttl_with_arguments_fails() {
|
|
123
|
+
let input: syn::DeriveInput = syn::parse_quote! {
|
|
124
|
+
enum InvalidEnum {
|
|
125
|
+
#[persistent(u32)]
|
|
126
|
+
#[no_auto_ttl_extension(true)]
|
|
127
|
+
Counter,
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
crate::storage::generate_storage(quote! {}.into(), input.to_token_stream().into());
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
#[test]
|
|
134
|
+
#[should_panic(expected = "multiple no_auto_ttl_extension attributes specified")]
|
|
135
|
+
fn multiple_no_auto_ttl_attributes_fails() {
|
|
136
|
+
let input: syn::DeriveInput = syn::parse_quote! {
|
|
137
|
+
enum InvalidEnum {
|
|
138
|
+
#[persistent(u32)]
|
|
139
|
+
#[no_auto_ttl_extension]
|
|
140
|
+
#[no_auto_ttl_extension]
|
|
141
|
+
Counter,
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
crate::storage::generate_storage(quote! {}.into(), input.to_token_stream().into());
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// ========================================
|
|
148
|
+
// Storage Config Tests
|
|
149
|
+
// ========================================
|
|
150
|
+
|
|
151
|
+
#[test]
|
|
152
|
+
#[should_panic(expected = "failed to parse attribute")]
|
|
153
|
+
fn invalid_ttl_provider_format_fails() {
|
|
154
|
+
let input: syn::DeriveInput = syn::parse_quote! {
|
|
155
|
+
enum TestEnum {
|
|
156
|
+
#[instance(u32)]
|
|
157
|
+
Counter,
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
crate::storage::generate_storage(quote! { unknown_option = SomeType }.into(), input.to_token_stream().into());
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// ========================================
|
|
164
|
+
// Combined Attribute Tests
|
|
165
|
+
// ========================================
|
|
166
|
+
|
|
167
|
+
#[test]
|
|
168
|
+
#[should_panic(expected = "only unit variants or named fields are supported in storage enums")]
|
|
169
|
+
fn mixed_valid_and_invalid_variants_fails() {
|
|
170
|
+
let input: syn::ItemEnum = syn::parse_quote! {
|
|
171
|
+
enum InvalidEnum {
|
|
172
|
+
#[instance(u32)]
|
|
173
|
+
ValidCounter,
|
|
174
|
+
#[persistent(String)]
|
|
175
|
+
InvalidTuple(u32),
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
crate::storage::generate_storage(quote! {}, input.to_token_stream());
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// ========================================
|
|
182
|
+
// Unknown Attribute Tests
|
|
183
|
+
// ========================================
|
|
184
|
+
|
|
185
|
+
#[test]
|
|
186
|
+
#[should_panic(expected = "unknown attribute")]
|
|
187
|
+
fn unknown_variant_attribute_fails() {
|
|
188
|
+
let input: syn::DeriveInput = syn::parse_quote! {
|
|
189
|
+
enum InvalidEnum {
|
|
190
|
+
#[persistent(u32)]
|
|
191
|
+
#[unknown_attr]
|
|
192
|
+
Counter,
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
crate::storage::generate_storage(quote! {}.into(), input.to_token_stream().into());
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// ========================================
|
|
199
|
+
// Edge Cases
|
|
200
|
+
// ========================================
|
|
201
|
+
|
|
202
|
+
#[test]
|
|
203
|
+
#[should_panic(expected = "failed to parse storage variant for Counter")]
|
|
204
|
+
fn storage_type_with_empty_parens_fails() {
|
|
205
|
+
let input: syn::ItemEnum = syn::parse_quote! {
|
|
206
|
+
enum InvalidEnum {
|
|
207
|
+
#[instance()]
|
|
208
|
+
Counter,
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
crate::storage::generate_storage(quote! {}, input.to_token_stream());
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
#[test]
|
|
215
|
+
#[should_panic(expected = "failed to parse storage variant for Counter")]
|
|
216
|
+
fn storage_type_with_multiple_types_fails() {
|
|
217
|
+
let input: syn::ItemEnum = syn::parse_quote! {
|
|
218
|
+
enum InvalidEnum {
|
|
219
|
+
#[persistent(u32, String)]
|
|
220
|
+
Counter,
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
crate::storage::generate_storage(quote! {}, input.to_token_stream());
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
#[test]
|
|
227
|
+
fn valid_complex_enum_succeeds() {
|
|
228
|
+
let input: syn::DeriveInput = syn::parse_quote! {
|
|
229
|
+
enum ValidEnum {
|
|
230
|
+
#[instance(u32)]
|
|
231
|
+
Counter,
|
|
232
|
+
#[persistent(String)]
|
|
233
|
+
#[default("hello".to_string())]
|
|
234
|
+
Message { sender: Address },
|
|
235
|
+
#[temporary(bool)]
|
|
236
|
+
#[no_auto_ttl_extension]
|
|
237
|
+
Flag { key: String },
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
let result = crate::storage::generate_storage(quote! { TtlProvider }, input.to_token_stream());
|
|
242
|
+
// Should not panic - this is a valid configuration
|
|
243
|
+
assert!(!result.is_empty());
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// ========================================
|
|
247
|
+
// Snapshot Tests
|
|
248
|
+
// ========================================
|
|
249
|
+
#[test]
|
|
250
|
+
fn snapshot_generated_storage_code() {
|
|
251
|
+
let input: syn::ItemEnum = syn::parse_quote! {
|
|
252
|
+
pub enum StorageKeys {
|
|
253
|
+
/// Instance storage with default value
|
|
254
|
+
#[instance(u32)]
|
|
255
|
+
#[default(0)]
|
|
256
|
+
Counter,
|
|
257
|
+
|
|
258
|
+
/// Persistent storage with named field and default
|
|
259
|
+
#[persistent(String)]
|
|
260
|
+
#[default("hello".to_string())]
|
|
261
|
+
Message { sender: Address },
|
|
262
|
+
|
|
263
|
+
/// Temporary storage with no auto TTL extension
|
|
264
|
+
#[temporary(bool)]
|
|
265
|
+
#[no_auto_ttl_extension]
|
|
266
|
+
Flag { key: String },
|
|
267
|
+
|
|
268
|
+
/// Persistent storage with multiple fields (no default)
|
|
269
|
+
#[persistent(Vec<u8>)]
|
|
270
|
+
Data { id: u64, name: String },
|
|
271
|
+
|
|
272
|
+
/// Persistent storage without fields or default
|
|
273
|
+
#[persistent(Address)]
|
|
274
|
+
Owner,
|
|
275
|
+
|
|
276
|
+
#[persistent(Option<Address>)]
|
|
277
|
+
OptionalData{ key: BytesN<32> }
|
|
278
|
+
}
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
let result = crate::storage::generate_storage(quote! { TtlProvider }, input.to_token_stream());
|
|
282
|
+
let formatted =
|
|
283
|
+
prettyplease::unparse(&syn::parse2::<syn::File>(result).expect("failed to parse generated code"));
|
|
284
|
+
|
|
285
|
+
insta::assert_snapshot!(formatted);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
//! Default implementation macro for Stellar smart contracts.
|
|
2
|
+
//!
|
|
3
|
+
//! Generates a complete contract setup with:
|
|
4
|
+
//! - `#[contract]` attribute
|
|
5
|
+
//! - Ownable trait implementation
|
|
6
|
+
//! - TtlConfigurable trait implementation with owner auth checks
|
|
7
|
+
|
|
8
|
+
use proc_macro2::TokenStream as TokenStream2;
|
|
9
|
+
use quote::quote;
|
|
10
|
+
|
|
11
|
+
/// Generates the TtlConfigurable trait implementation for a contract.
|
|
12
|
+
///
|
|
13
|
+
/// The implementation delegates to `DefaultTtlConfigurable` and adds
|
|
14
|
+
/// owner authentication checks for mutating functions.
|
|
15
|
+
pub fn generate_ttl_configurable_impl(input: &syn::ItemStruct) -> TokenStream2 {
|
|
16
|
+
let name = &input.ident;
|
|
17
|
+
let expanded = quote! {
|
|
18
|
+
use utils::ttl::TtlConfigurable as _;
|
|
19
|
+
|
|
20
|
+
#[soroban_sdk::contractimpl]
|
|
21
|
+
impl utils::ttl::TtlConfigurable for #name {
|
|
22
|
+
|
|
23
|
+
#[common_macros::only_owner]
|
|
24
|
+
fn set_ttl_config(
|
|
25
|
+
env: &soroban_sdk::Env,
|
|
26
|
+
instance: &Option<utils::ttl::TtlConfig>,
|
|
27
|
+
persistent: &Option<utils::ttl::TtlConfig>,
|
|
28
|
+
temporary: &Option<utils::ttl::TtlConfig>,
|
|
29
|
+
) {
|
|
30
|
+
utils::ttl::DefaultTtlConfigurable::set_ttl_config(env, instance, persistent, temporary);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
fn ttl_config(
|
|
34
|
+
env: &soroban_sdk::Env,
|
|
35
|
+
) -> (
|
|
36
|
+
Option<utils::ttl::TtlConfig>,
|
|
37
|
+
Option<utils::ttl::TtlConfig>,
|
|
38
|
+
Option<utils::ttl::TtlConfig>,
|
|
39
|
+
) {
|
|
40
|
+
utils::ttl::DefaultTtlConfigurable::ttl_config(env)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
#[common_macros::only_owner]
|
|
44
|
+
fn freeze_ttl_config(env: &soroban_sdk::Env) {
|
|
45
|
+
utils::ttl::DefaultTtlConfigurable::freeze_ttl_config(env);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
fn is_ttl_config_frozen(env: &soroban_sdk::Env) -> bool {
|
|
49
|
+
utils::ttl::DefaultTtlConfigurable::is_ttl_config_frozen(env)
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
quote! {
|
|
55
|
+
#[common_macros::ownable]
|
|
56
|
+
#input
|
|
57
|
+
|
|
58
|
+
#expanded
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
# EndpointV2 Architecture
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
**EndpointV2** is the core Soroban contract for LayerZero's cross-chain messaging protocol on Stellar. It serves as the central hub for omnichain applications (OApps) to send and receive cross-chain messages using pluggable message libraries.
|
|
6
|
+
|
|
7
|
+
**Key Architecture Principles:**
|
|
8
|
+
|
|
9
|
+
- **Interfaces exported as library** - External contracts depend on trait definitions only
|
|
10
|
+
- **Contract entry point** - `endpoint_v2.rs` implements all interfaces
|
|
11
|
+
- **Internal modules** - Separate files for business logic implementation
|
|
12
|
+
- **Centralized resources** - Unified `storage.rs`, `errors.rs`, `events.rs`
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Project Structure
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
endpoint-v2/
|
|
20
|
+
├── Cargo.toml # Package configuration with "library" feature
|
|
21
|
+
├── ARCHITECTURE.md # This file - architecture documentation
|
|
22
|
+
│
|
|
23
|
+
├── src/
|
|
24
|
+
|
|
25
|
+
│ ├── interfaces/ # Public interface definitions (library exports)
|
|
26
|
+
│ │ ├── mod.rs
|
|
27
|
+
│ │ ├── layerzero_endpoint_v2.rs # Core endpoint interface
|
|
28
|
+
│ │ ├── layerzero_composer.rs # Interface for Composer
|
|
29
|
+
│ │ ├── layerzero_receiver.rs # Interface for OApp (receive)
|
|
30
|
+
│ │ ├── message_lib.rs # Interface for MessageLib
|
|
31
|
+
│ │ ├── message_lib_manager.rs # Library management interface of EndpointV2
|
|
32
|
+
│ │ ├── send_lib.rs # Interface for SendLib (extends MessageLib)
|
|
33
|
+
│ │ ├── messaging_channel.rs # Channel operations interface of EndpointV2
|
|
34
|
+
│ │ └── messaging_composer.rs # Compose operations interface of EndpointV2
|
|
35
|
+
| |
|
|
36
|
+
│ ├── lib.rs # Module exports & conditional compilation
|
|
37
|
+
│ ├── endpoint_v2.rs # Main contract implementation
|
|
38
|
+
│ ├── message_lib_manager.rs # Internal: Library registration & management
|
|
39
|
+
│ ├── messaging_channel.rs # Internal: Channel logic (nonce, payload)
|
|
40
|
+
│ ├── messaging_composer.rs # Internal: Compose queue management
|
|
41
|
+
│ │
|
|
42
|
+
│ ├── util.rs # Public: Utility functions (GUID, payload, keccak256)
|
|
43
|
+
│ ├── storage.rs # Centralized storage management
|
|
44
|
+
│ ├── errors.rs # Centralized error definitions
|
|
45
|
+
│ ├── events.rs # Centralized event definitions
|
|
46
|
+
│ │
|
|
47
|
+
│ └── tests/ # Comprehensive test suite
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Design Principles
|
|
54
|
+
|
|
55
|
+
### 1. Interfaces as Library Exports
|
|
56
|
+
|
|
57
|
+
The `interfaces/` directory contains Soroban trait definitions exported as a library for external contracts. Controlled by the `library` feature in `Cargo.toml`.
|
|
58
|
+
|
|
59
|
+
```rust
|
|
60
|
+
// lib.rs - conditional compilation
|
|
61
|
+
cfg_if::cfg_if! {
|
|
62
|
+
if #[cfg(any(not(feature = "library"), feature = "default"))] {
|
|
63
|
+
mod endpoint_v2; // Only included when building contract
|
|
64
|
+
mod errors;
|
|
65
|
+
mod events;
|
|
66
|
+
mod storage;
|
|
67
|
+
|
|
68
|
+
pub use endpoint_v2::{EndpointV2, EndpointV2Client};
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
**Usage Example:**
|
|
74
|
+
|
|
75
|
+
```rust
|
|
76
|
+
// In a MessageLib contract
|
|
77
|
+
use endpoint_v2::{EndpointV2Client, OutboundPacket};
|
|
78
|
+
|
|
79
|
+
let endpoint = EndpointV2Client::new(&env, &endpoint_address);
|
|
80
|
+
endpoint.verify(&origin, &receiver, &payload_hash);
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
**Interface Categories:**
|
|
84
|
+
|
|
85
|
+
- **For OApps**: `ILayerZeroReceiver`, `ILayerZeroComposer`
|
|
86
|
+
- **For MessageLibs**: `IMessageLib`, `ISendLib` (includes `OutboundPacket`, `FeeRecipient`)
|
|
87
|
+
- **For All**: `ILayerZeroEndpointV2` (composes all sub-interfaces)
|
|
88
|
+
- **Utilities**: `util::compute_guid()`, `util::build_payload()`, `util::keccak256()`
|
|
89
|
+
|
|
90
|
+
### 2. Contract Entry Point (`endpoint_v2.rs`)
|
|
91
|
+
|
|
92
|
+
The main Soroban contract that implements all interfaces and delegates to internal modules:
|
|
93
|
+
|
|
94
|
+
```rust
|
|
95
|
+
#[contract]
|
|
96
|
+
pub struct EndpointV2;
|
|
97
|
+
|
|
98
|
+
#[contractimpl]
|
|
99
|
+
impl EndpointV2 {
|
|
100
|
+
pub fn __constructor(env: &Env, eid: u32, native_token: &Address, owner: &Address) {
|
|
101
|
+
storage::EndpointData::set_eid(env, eid);
|
|
102
|
+
storage::EndpointData::set_native_token(env, native_token);
|
|
103
|
+
ownable::set_owner(env, owner);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
pub fn set_ttl_config(env: &Env, ...) {
|
|
107
|
+
ownable::require_owner_auth(env);
|
|
108
|
+
// Configure TTL settings for storage
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
#[contractimpl]
|
|
113
|
+
impl ILayerZeroEndpointV2 for EndpointV2 {
|
|
114
|
+
fn send(env: &Env, sender: &Address, params: &MessagingParams, ...) -> MessagingReceipt {
|
|
115
|
+
sender.require_auth();
|
|
116
|
+
// Send cross-chain message via SendLib
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
fn lz_receive(env: &Env, origin: &Origin, receiver: &Address, ...) {
|
|
120
|
+
// Verify payload hash and deliver to OApp
|
|
121
|
+
let receiver_client = LayerZeroReceiverClient::new(env, receiver);
|
|
122
|
+
receiver_client.lz_receive(...);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
#[contractimpl]
|
|
127
|
+
impl Ownable for EndpointV2 {
|
|
128
|
+
// Ownership management
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
**Implements:** `ILayerZeroEndpointV2` (which includes `IMessageLibManager`, `IMessagingChannel`, `IMessagingComposer`), `Ownable`
|
|
133
|
+
|
|
134
|
+
### 3. Internal Implementation Modules
|
|
135
|
+
|
|
136
|
+
Internal modules provide business logic implementation for `endpoint_v2.rs`:
|
|
137
|
+
|
|
138
|
+
| Module | Purpose |
|
|
139
|
+
| ---------------------------- | -------------------------------------------------------------------------------------------------------- |
|
|
140
|
+
| **`message_lib_manager.rs`** | Library registration, selection, and configuration. Tracks default/per-OApp libraries per EID. |
|
|
141
|
+
| **`messaging_channel.rs`** | Nonce tracking, payload hash storage/verification, message state transitions (verify → receive → clear). |
|
|
142
|
+
| **`messaging_composer.rs`** | Manages compose message queues for multi-stage execution between OApp and Composers. |
|
|
143
|
+
| **`util.rs`** | Public utilities: `compute_guid()`, `build_payload()`, `keccak256()` for message processing. |
|
|
144
|
+
|
|
145
|
+
### 4. Centralized Resource Management
|
|
146
|
+
|
|
147
|
+
| Module | Purpose | Example |
|
|
148
|
+
| ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
|
|
149
|
+
| **`storage.rs`** | Type-safe storage with `#[storage]` derive macro. Organized into: `EndpointData`, `MessagingChannelData`, `MessageLibManagerData`, `MessagingComposerData`. | `EndpointData::eid(env)`, `MessagingChannelData::outbound_nonce(env, sender, dst_eid, receiver)` |
|
|
150
|
+
| **`errors.rs`** | All error codes using `#[contracterror]`. 29 error types including validation, authorization, state, and configuration errors. | `InvalidNonce = 3`, `Unauthorized = 10`, `InsufficientNativeFee = 27` |
|
|
151
|
+
| **`events.rs`** | All events using `#[contractevent]`. Includes config, messaging, library, and compose events. | `PacketSent`, `PacketVerified`, `LibraryRegistered` |
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## Key Patterns
|
|
156
|
+
|
|
157
|
+
**1. Interface Composition**
|
|
158
|
+
|
|
159
|
+
```rust
|
|
160
|
+
pub trait ILayerZeroEndpointV2:
|
|
161
|
+
IMessageLibManager + IMessagingChannel + IMessagingComposer
|
|
162
|
+
{
|
|
163
|
+
fn quote(env: &Env, sender: &Address, params: &MessagingParams) -> MessagingFee;
|
|
164
|
+
fn send(env: &Env, sender: &Address, params: &MessagingParams, refund_address: &Address) -> MessagingReceipt;
|
|
165
|
+
fn lz_receive(env: &Env, origin: &Origin, receiver: &Address, guid: &BytesN<32>, message: &Bytes, extra_data: &Bytes);
|
|
166
|
+
// ... more methods
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Each sub-interface handles one domain, enabling modularity and clear separation of concerns. Ownership is handled through the `Ownable` trait from the `utils` crate.
|
|
171
|
+
|
|
172
|
+
**2. Client Generation**
|
|
173
|
+
|
|
174
|
+
```rust
|
|
175
|
+
#[contractclient(name = "LayerZeroReceiverClient")]
|
|
176
|
+
pub trait ILayerZeroReceiver {
|
|
177
|
+
fn lz_receive(env: &Env, origin: &Origin, guid: &BytesN<32>, message: &Bytes, extra_data: &Bytes);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Usage: type-safe cross-contract calls
|
|
181
|
+
let receiver = LayerZeroReceiverClient::new(&env, &receiver_address);
|
|
182
|
+
receiver.lz_receive(&origin, &guid, &message, &extra_data);
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
The `#[contractclient]` macro automatically generates type-safe client wrappers for cross-contract calls.
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## Message Flows
|
|
190
|
+
|
|
191
|
+
### Sending
|
|
192
|
+
|
|
193
|
+
```
|
|
194
|
+
OApp → EndpointV2.send(sender, params, refund_address)
|
|
195
|
+
↓
|
|
196
|
+
MessageLibManager.get_send_library(sender, dst_eid)
|
|
197
|
+
↓
|
|
198
|
+
MessagingChannel.outbound_nonce++ (create OutboundPacket)
|
|
199
|
+
↓
|
|
200
|
+
SendLib.send(packet, options, pay_in_zro) → Returns (Vec<FeeRecipient>, encoded_packet)
|
|
201
|
+
↓
|
|
202
|
+
Pay fees (native or ZRO) to fee recipients
|
|
203
|
+
↓
|
|
204
|
+
Emit PacketSent event
|
|
205
|
+
↓
|
|
206
|
+
Return MessagingReceipt { guid, nonce, fee }
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### Receiving
|
|
210
|
+
|
|
211
|
+
```
|
|
212
|
+
Off-chain Verifier → EndpointV2.verify(origin, receiver, payload_hash)
|
|
213
|
+
↓
|
|
214
|
+
Validate library is registered receive lib
|
|
215
|
+
↓
|
|
216
|
+
MessagingChannel.inbound(receiver, origin, payload_hash) → Store payload hash
|
|
217
|
+
↓
|
|
218
|
+
Emit PacketVerified event
|
|
219
|
+
|
|
220
|
+
Later: Executor → OApp.lz_receive(origin, guid, message, extra_data)
|
|
221
|
+
↓
|
|
222
|
+
OApp executes business logic
|
|
223
|
+
↓
|
|
224
|
+
OApp → EndpointV2.clear(caller, origin, receiver, guid, message)
|
|
225
|
+
↓
|
|
226
|
+
Validate caller is OApp or its delegate (require_oapp_auth)
|
|
227
|
+
↓
|
|
228
|
+
Validate payload hash matches keccak256(guid || message)
|
|
229
|
+
↓
|
|
230
|
+
Clear payload hash from storage
|
|
231
|
+
↓
|
|
232
|
+
Emit PacketDelivered event
|
|
233
|
+
```
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
[package]
|
|
2
|
+
name = "endpoint-v2"
|
|
3
|
+
version.workspace = true
|
|
4
|
+
edition.workspace = true
|
|
5
|
+
license.workspace = true
|
|
6
|
+
publish = false
|
|
7
|
+
|
|
8
|
+
[lib]
|
|
9
|
+
crate-type = ["cdylib", "rlib"]
|
|
10
|
+
doctest = false
|
|
11
|
+
|
|
12
|
+
[features]
|
|
13
|
+
library = []
|
|
14
|
+
testutils = []
|
|
15
|
+
# Network selection
|
|
16
|
+
mainnet = []
|
|
17
|
+
testnet = []
|
|
18
|
+
sandbox = []
|
|
19
|
+
|
|
20
|
+
[dependencies]
|
|
21
|
+
cfg-if = { workspace = true }
|
|
22
|
+
soroban-sdk = { workspace = true }
|
|
23
|
+
# workspace dependencies
|
|
24
|
+
utils = { workspace = true }
|
|
25
|
+
common-macros = { workspace = true }
|
|
26
|
+
|
|
27
|
+
[dev-dependencies]
|
|
28
|
+
soroban-sdk = { workspace = true, features = ["testutils"] }
|
|
29
|
+
utils = { workspace = true, features = ["testutils"] }
|
|
30
|
+
hex-literal = { workspace = true }
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
//! Network-specific constants for the LayerZero Endpoint V2.
|
|
2
|
+
//!
|
|
3
|
+
//! This module contains configuration constants that vary by deployment environment.
|
|
4
|
+
//! Constants are selected at compile time based on Cargo features.
|
|
5
|
+
|
|
6
|
+
cfg_if::cfg_if! {
|
|
7
|
+
if #[cfg(any(test, feature = "testutils"))] {
|
|
8
|
+
/// Stellar Endpoint ID for unit test environment.
|
|
9
|
+
/// TODO: This is a placeholder value for testing purposes.
|
|
10
|
+
pub const STELLAR_EID: u32 = 30111;
|
|
11
|
+
|
|
12
|
+
/// Native token address for unit test environment.
|
|
13
|
+
pub const NATIVE_TOKEN: &str = "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL";
|
|
14
|
+
|
|
15
|
+
} else if #[cfg(feature = "testnet")] {
|
|
16
|
+
/// Stellar Endpoint ID for testnet environment.
|
|
17
|
+
/// TODO: Confirm this EID value with LayerZero before testnet deployment.
|
|
18
|
+
pub const STELLAR_EID: u32 = 20111;
|
|
19
|
+
|
|
20
|
+
/// Native token address for testnet (Stellar testnet XLM wrapper).
|
|
21
|
+
pub const NATIVE_TOKEN: &str = "CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC";
|
|
22
|
+
|
|
23
|
+
} else if #[cfg(feature = "sandbox")] {
|
|
24
|
+
/// Stellar Endpoint ID for sandbox environment.
|
|
25
|
+
/// TODO: Confirm this EID value with LayerZero before sandbox deployment.
|
|
26
|
+
pub const STELLAR_EID: u32 = 30111;
|
|
27
|
+
|
|
28
|
+
/// Native token address for sandbox environment.
|
|
29
|
+
pub const NATIVE_TOKEN: &str = "CDMLFMKMMD7MWZP3FKUBZPVHTUEDLSX4BYGYKH4GCESXYHS3IHQ4EIG4";
|
|
30
|
+
|
|
31
|
+
} else {
|
|
32
|
+
/// Stellar Endpoint ID for mainnet environment.
|
|
33
|
+
/// TODO: Confirm this EID value with LayerZero before mainnet deployment.
|
|
34
|
+
pub const STELLAR_EID: u32 = 30111;
|
|
35
|
+
|
|
36
|
+
/// Native token address for mainnet (Stellar mainnet XLM wrapper).
|
|
37
|
+
pub const NATIVE_TOKEN: &str = "CAS3J7GYLGXMF6TDJBBYYSE3HQ6BBSMLNUQ34T6TZMYMW2EVH34XOWMA";
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/// Represents a received message hash marker (equivalent to bytes32(uint256(1)) in Solidity )
|
|
42
|
+
pub const RECEIVED_MESSAGE_HASH_BYTES: [u8; 32] =
|
|
43
|
+
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1];
|
|
44
|
+
|
|
45
|
+
/// Represents an empty payload hash (equivalent to bytes32(uint256(0)) in Solidity )
|
|
46
|
+
pub const EMPTY_PAYLOAD_HASH_BYTES: [u8; 32] = [0u8; 32];
|
|
47
|
+
|
|
48
|
+
/// Represents a nilified payload hash (equivalent to bytes32(type(uint256).max) in Solidity )
|
|
49
|
+
pub const NIL_PAYLOAD_HASH_BYTES: [u8; 32] = [0xffu8; 32];
|
|
50
|
+
|
|
51
|
+
/// Represents the maximum compose index (equivalent to uint16.max in Solidity )
|
|
52
|
+
pub const MAX_COMPOSE_INDEX: u32 = u16::MAX as u32;
|