@layerzerolabs/oapp-solana-contracts 1.2.63 → 1.2.65

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/Anchor.toml CHANGED
@@ -1,5 +1,5 @@
1
1
  [toolchain]
2
- anchor_version = "1.0.2"
2
+ anchor_version = "1.1.2"
3
3
  solana_version = "3.1.10"
4
4
 
5
5
  [features]
package/Cargo.toml CHANGED
@@ -19,13 +19,9 @@ idl-build = ["anchor-lang/idl-build", "anchor-spl/idl-build", "oapp-macros/idl-b
19
19
  unexpected_cfgs = { level = "warn", check-cfg = ['cfg(target_os, values("solana"))'] }
20
20
 
21
21
  [dependencies]
22
- anchor-lang = { version = "1.0.2" }
23
- anchor-spl = { version = "1.0.2" }
22
+ anchor-lang = { version = "1.1.2" }
23
+ anchor-spl = { version = "1.1.2" }
24
24
  oapp-macros = { path = "macros" }
25
- solana-address-lookup-table-interface = { version = "3.0.1", features = [
26
- "bincode",
27
- "bytemuck",
28
- ] }
29
25
  solana-keccak-hasher = "3.1.0"
30
26
  spl-type-length-value = { version = "0.9.1", features = ["derive"] }
31
27
  spl-discriminator = "0.5.2"
package/README.md CHANGED
@@ -65,8 +65,12 @@ Generated by the `#[oapp]` attribute macro from `oapp`.
65
65
  | `next_nonce` | Yes | Yes | Read next inbound nonce |
66
66
  | `is_compose_msg_sender` | Yes | Yes | Validate compose message sender |
67
67
  | `lz_receive_types_info` | Yes | No | Return LzReceiveTypes version and accounts |
68
- | `lz_receive_types_v2` | Yes | No | Return accounts and instructions for lz_receive |
68
+ | `lz_receive_types_v3` | No | No | Write the lz_receive execution plan to caller scratch |
69
69
  | `lz_receive` | No | No | Execute inbound cross-chain message |
70
+ | `clear` | No | Yes | Consume a verified inbound message without `lz_receive` |
71
+ | `skip` | No | Yes | Skip the next inbound nonce |
72
+ | `burn` | No | Yes | Permanently burn a verified inbound payload |
73
+ | `nilify` | No | Yes | Block an inbound nonce until it is re-verified |
70
74
 
71
75
  ### RBAC Instructions
72
76
 
@@ -85,6 +89,8 @@ Generated by the `#[rbac]` attribute macro from `rbac`. All have default impleme
85
89
  >
86
90
  > **Security Note (`lz_receive`):** The Endpoint does NOT validate the inbound peer. The `lz_receive` override MUST bind an `OAppPeer` PDA to `params.src_eid` via `seeds` and enforce `peer.address == params.sender` — recommended declaratively via Anchor's `constraint`. Omitting this check lets any program impersonate a registered peer. See the `#[oapp_instruction]` rustdoc for the canonical Anchor account snippet.
87
91
 
92
+ The program's role enum must implement `MessagingChannelRoles`. `clear`, `skip`, and `burn` use the messaging-channel manager role; `nilify` uses a separate message-nilifier role. The DefaultAdmin, as the OApp's Endpoint delegate, can already call these on the Endpoint directly; the roles let other keys do the same through the OApp. These wrappers omit a caller-controlled receiver and inject the OApp PDA into the Endpoint CPI.
93
+
88
94
  ### Initialization Requirements
89
95
 
90
96
  The `#[oapp]` macro generates instruction entrypoints, but deployment initialization remains the program's responsibility. A production OApp `initialize` handler must complete these setup steps:
@@ -156,25 +162,25 @@ For the full `OAppInfo` struct, SDK decision flow, app-specific extensions, and
156
162
 
157
163
  > LzReceiveTypes is an existing protocol that predates the OApp Standard. It is documented here for completeness, as it handles account discovery for `lz_receive` — the one instruction not covered by `OAppInfo`.
158
164
 
159
- `lz_receive` is unique among OApp instructions: its accounts depend on the message content and cannot be resolved off-chain from a predefined template. The LzReceiveTypes protocol solves this by providing an on-chain instruction (`lz_receive_types_v2`) that returns the exact accounts and instructions needed for a given message.
165
+ `lz_receive` is unique among OApp instructions: its accounts depend on the message content and cannot be resolved off-chain from a predefined template. The LzReceiveTypes protocol solves this by providing an on-chain instruction (`lz_receive_types_v3`) that returns the exact accounts and instructions needed for a given message.
160
166
 
161
167
  Key concepts:
162
168
 
163
- - **Two-stage execution** — the Executor first calls `lz_receive_types_v2` to discover accounts, then submits the full `lz_receive` transaction.
164
- - **Transaction-based model (V2)** — replaces the original CPI-based model to avoid Solana's CPI depth limit of 4, enabling ABA messaging patterns.
165
- - **`AddressLocator` enum** — compact account referencing via direct address, ALT index, payer, additional signers, or executor context account.
166
- - **Multi-instruction support** — `lz_receive_types_v2` can return multiple instructions (preprocessing steps + `lz_receive`), executed atomically in a single transaction.
169
+ - **Simulated planning** — the Executor simulates `lz_receive_types_info` and then `lz_receive_types_v3`, which writes the plan into a caller-created scratch account, and submits the resulting instructions.
170
+ - **Top-level delivery** — planned instructions, including `lz_receive`, run as top-level instructions in the Executor's transaction, between its `PreExecute` and `PostExecute`, rather than through an Executor CPI, leaving `lz_receive` the full CPI depth (e.g. for ABA messaging).
171
+ - **`AddressLocator` enum** — accounts are referenced by literal address, the Executor payer, additional Executor-provided signers, or the Executor's execution-context account.
172
+ - **Multi-instruction support** — `lz_receive_types_v3` can return multiple instructions (preprocessing steps + `lz_receive`), executed atomically in a single transaction.
167
173
  - **Versioned via `lz_receive_types_info`** — the protocol self-describes its version; the Executor reads this to determine how to interact with the OApp.
168
174
 
169
- For the full protocol design, data structures, execution flow, and V2 transaction model, see [`lz-receive-types.md`](./docs/lz-receive-types.md).
175
+ For the planning flow, scratch sizing, and plan format, see [`lz-receive-types.md`](./docs/lz-receive-types.md).
170
176
 
171
177
  ---
172
178
 
173
179
  ## Appendix: LzComposeTypes
174
180
 
175
181
  `lz_compose` is the follow-up execution phase for composed messages emitted by
176
- `lz_receive`. LzComposeTypes uses the same V2 account reference and transaction
177
- model as LzReceiveTypes, but its interface is scoped to composer programs and
182
+ `lz_receive`. LzComposeTypes uses the same V3 planning protocol and plan encoding
183
+ as LzReceiveTypes, but its interface is scoped to composer programs and
178
184
  `LzComposeParams`.
179
185
 
180
186
  For the compose-specific interface and differences, see
package/macros/Cargo.toml CHANGED
@@ -11,7 +11,7 @@ default = []
11
11
  idl-build = ["anchor-lang/idl-build"]
12
12
 
13
13
  [dependencies]
14
- anchor-lang = { version = "1.0.2" }
14
+ anchor-lang = { version = "1.1.2" }
15
15
  anchor-trait = { path = "../dependencies/framework-solana-anchor-trait" }
16
16
  syn = { version = "2.0", features = ["full", "parsing", "extra-traits"] }
17
17
  quote = "1.0"
@@ -12,7 +12,7 @@
12
12
  //! The framework does not enforce it at compile time, so a mismatch only
13
13
  //! surfaces as a runtime failure when the Executor calls the deployed program.
14
14
  //!
15
- //! This follows the same V2 account-discovery model as `lz_receive_types_info`.
15
+ //! This follows the same V3 account-discovery model as `lz_receive_types_info`.
16
16
  //! See `docs/lz-compose-types.md` for the compose-specific differences.
17
17
 
18
18
  use super::ComposerCodegenContext;
@@ -22,7 +22,7 @@ use quote::quote;
22
22
  pub(super) fn spec() -> InstructionSpec<ComposerCodegenContext> {
23
23
  InstructionSpec {
24
24
  params_type: Some(quote!(::oapp::types::LzComposeParams)),
25
- return_type: quote!((u8, ::oapp::lz_compose_types_v2::LzComposeTypesV2Accounts)),
25
+ return_type: quote!((u8, ::oapp::lz_compose_types_v3::LzComposeTypesV3Accounts)),
26
26
  is_view: true,
27
27
  default_impl: None,
28
28
  }
@@ -0,0 +1,18 @@
1
+ //! Code generator for the `lz_compose_types_v3` instruction.
2
+ //!
3
+ //! Required override (no default). Users MUST provide a custom handler named
4
+ //! `lz_compose_types_v3` with `#[composer_instruction]`. The handler writes its plan with
5
+ //! `oapp::lz_plan::write` and returns the plan's encoded length; see `docs/lz-compose-types.md`.
6
+
7
+ use super::ComposerCodegenContext;
8
+ use anchor_trait::InstructionSpec;
9
+ use quote::quote;
10
+
11
+ pub(super) fn spec() -> InstructionSpec<ComposerCodegenContext> {
12
+ InstructionSpec {
13
+ params_type: Some(quote!(::oapp::types::LzComposeParams)),
14
+ return_type: quote!(u32),
15
+ is_view: false,
16
+ default_impl: None,
17
+ }
18
+ }
@@ -5,7 +5,7 @@
5
5
 
6
6
  mod lz_compose;
7
7
  mod lz_compose_types_info;
8
- mod lz_compose_types_v2;
8
+ mod lz_compose_types_v3;
9
9
 
10
10
  use anchor_trait::declare_instructions;
11
11
 
@@ -18,6 +18,6 @@ declare_instructions! {
18
18
  context = ComposerCodegenContext;
19
19
 
20
20
  LzComposeTypesInfo => lz_compose_types_info,
21
- LzComposeTypesV2 => lz_compose_types_v2,
21
+ LzComposeTypesV3 => lz_compose_types_v3,
22
22
  LzCompose => lz_compose,
23
23
  }
@@ -0,0 +1,69 @@
1
+ //! Code generator for the messaging-channel `burn` instruction.
2
+ //!
3
+ //! Permanently disables execution / re-verification of a payload.
4
+ //! Requires [`MessagingChannelRoles::messaging_channel_manager_role`]. The Endpoint accounts are
5
+ //! passed as remaining accounts in `oapp::endpoint_cpi::burn` order.
6
+
7
+ use super::CodegenContext;
8
+ use anchor_trait::{DefaultAccounts, DefaultImpl, InstructionSpec};
9
+ use quote::{format_ident, quote};
10
+ use syn::parse_quote;
11
+
12
+ pub(super) fn spec() -> InstructionSpec<CodegenContext> {
13
+ InstructionSpec {
14
+ params_type: Some(quote!(::oapp::types::BurnParams)),
15
+ return_type: quote!(()),
16
+ is_view: false,
17
+ default_impl: Some(DefaultImpl {
18
+ handler_ident: format_ident!("apply"),
19
+ generator: generate_default_impl,
20
+ }),
21
+ }
22
+ }
23
+
24
+ fn generate_default_impl(
25
+ ctx: &CodegenContext,
26
+ spec: &InstructionSpec<CodegenContext>,
27
+ ) -> DefaultAccounts {
28
+ let handler_ident = &spec.default_impl.as_ref().unwrap().handler_ident;
29
+ let params_type = spec.params_type.as_ref().unwrap();
30
+ let return_type = &spec.return_type;
31
+ let oapp_type = &ctx.oapp_type;
32
+ let role_type = &ctx.role_type;
33
+
34
+ DefaultAccounts {
35
+ struct_type: parse_quote! {
36
+ #[::rbac::only_role(
37
+ role = #role_type::messaging_channel_manager_role(),
38
+ state = oapp,
39
+ authority = authority
40
+ )]
41
+ #[derive(Accounts)]
42
+ pub struct StdBurn<'info> {
43
+ pub authority: Signer<'info>,
44
+
45
+ pub oapp: Account<'info, #oapp_type>,
46
+ }
47
+ },
48
+ impl_block: parse_quote! {
49
+ impl StdBurn<'_> {
50
+ pub fn #handler_ident(ctx: &mut Context<Self>, params: &#params_type) -> Result<#return_type> {
51
+ let receiver = ctx.accounts.oapp.key();
52
+ ::oapp::endpoint_cpi::burn(
53
+ ::oapp::endpoint::ID,
54
+ receiver,
55
+ ctx.remaining_accounts,
56
+ &ctx.accounts.oapp.signer_seeds(),
57
+ ::oapp::endpoint::types::BurnParams {
58
+ receiver,
59
+ src_eid: params.src_eid,
60
+ sender: params.sender,
61
+ nonce: params.nonce,
62
+ payload_hash: params.payload_hash,
63
+ },
64
+ )
65
+ }
66
+ }
67
+ },
68
+ }
69
+ }
@@ -0,0 +1,70 @@
1
+ //! Code generator for the messaging-channel `clear` instruction.
2
+ //!
3
+ //! Consumes a verified inbound message without running the normal receive
4
+ //! callback. Requires [`MessagingChannelRoles::messaging_channel_manager_role`]. The Endpoint
5
+ //! accounts are passed as remaining accounts in `oapp::endpoint_cpi::clear` order.
6
+
7
+ use super::CodegenContext;
8
+ use anchor_trait::{DefaultAccounts, DefaultImpl, InstructionSpec};
9
+ use quote::{format_ident, quote};
10
+ use syn::parse_quote;
11
+
12
+ pub(super) fn spec() -> InstructionSpec<CodegenContext> {
13
+ InstructionSpec {
14
+ params_type: Some(quote!(::oapp::types::ClearParams)),
15
+ return_type: quote!([u8; 32]),
16
+ is_view: false,
17
+ default_impl: Some(DefaultImpl {
18
+ handler_ident: format_ident!("apply"),
19
+ generator: generate_default_impl,
20
+ }),
21
+ }
22
+ }
23
+
24
+ fn generate_default_impl(
25
+ ctx: &CodegenContext,
26
+ spec: &InstructionSpec<CodegenContext>,
27
+ ) -> DefaultAccounts {
28
+ let handler_ident = &spec.default_impl.as_ref().unwrap().handler_ident;
29
+ let params_type = spec.params_type.as_ref().unwrap();
30
+ let return_type = &spec.return_type;
31
+ let oapp_type = &ctx.oapp_type;
32
+ let role_type = &ctx.role_type;
33
+
34
+ DefaultAccounts {
35
+ struct_type: parse_quote! {
36
+ #[::rbac::only_role(
37
+ role = #role_type::messaging_channel_manager_role(),
38
+ state = oapp,
39
+ authority = authority
40
+ )]
41
+ #[derive(Accounts)]
42
+ pub struct StdClear<'info> {
43
+ pub authority: Signer<'info>,
44
+
45
+ pub oapp: Account<'info, #oapp_type>,
46
+ }
47
+ },
48
+ impl_block: parse_quote! {
49
+ impl StdClear<'_> {
50
+ pub fn #handler_ident(ctx: &mut Context<Self>, params: &#params_type) -> Result<#return_type> {
51
+ let receiver = ctx.accounts.oapp.key();
52
+ ::oapp::endpoint_cpi::clear(
53
+ ::oapp::endpoint::ID,
54
+ receiver,
55
+ ctx.remaining_accounts,
56
+ &ctx.accounts.oapp.signer_seeds(),
57
+ ::oapp::endpoint::types::ClearParams {
58
+ receiver,
59
+ src_eid: params.src_eid,
60
+ sender: params.sender,
61
+ nonce: params.nonce,
62
+ guid: params.guid,
63
+ message: params.message.clone(),
64
+ },
65
+ )
66
+ }
67
+ }
68
+ },
69
+ }
70
+ }
@@ -11,8 +11,6 @@
11
11
  //! Custom handlers MUST declare an `Accounts` struct matching this shape.
12
12
  //! The framework does not enforce it at compile time, so a mismatch only
13
13
  //! surfaces as a runtime failure when the Executor calls the deployed program.
14
- //!
15
- //! See: <https://docs.layerzero.network/v2/developers/solana/oapp/overview#how-lz_receive_types_v2-works>
16
14
 
17
15
  use super::CodegenContext;
18
16
  use anchor_trait::InstructionSpec;
@@ -21,7 +19,7 @@ use quote::quote;
21
19
  pub(super) fn spec() -> InstructionSpec<CodegenContext> {
22
20
  InstructionSpec {
23
21
  params_type: Some(quote!(::oapp::types::LzReceiveParams)),
24
- return_type: quote!((u8, ::oapp::lz_receive_types_v2::LzReceiveTypesV2Accounts)),
22
+ return_type: quote!((u8, ::oapp::lz_receive_types_v3::LzReceiveTypesV3Accounts)),
25
23
  is_view: true,
26
24
  default_impl: None,
27
25
  }
@@ -0,0 +1,17 @@
1
+ //! Code generator for the `lz_receive_types_v3` instruction.
2
+ //!
3
+ //! Required override (no default). The handler writes its plan with `oapp::lz_plan::write` and
4
+ //! returns the plan's encoded length; see `docs/lz-receive-types.md`.
5
+
6
+ use super::CodegenContext;
7
+ use anchor_trait::InstructionSpec;
8
+ use quote::quote;
9
+
10
+ pub(super) fn spec() -> InstructionSpec<CodegenContext> {
11
+ InstructionSpec {
12
+ params_type: Some(quote!(::oapp::types::LzReceiveParams)),
13
+ return_type: quote!(u32),
14
+ is_view: false,
15
+ default_impl: None,
16
+ }
17
+ }
@@ -4,16 +4,20 @@
4
4
  //! `InstructionName::spec()` maps instruction variants to their specs.
5
5
 
6
6
  pub(crate) mod accept_default_admin_transfer;
7
+ mod burn;
8
+ mod clear;
7
9
  mod get_enforced_options;
8
10
  mod get_peer;
9
11
  mod init_enforced_options;
10
12
  mod is_compose_msg_sender;
11
13
  mod lz_receive;
12
14
  mod lz_receive_types_info;
13
- mod lz_receive_types_v2;
15
+ mod lz_receive_types_v3;
14
16
  mod next_nonce;
17
+ mod nilify;
15
18
  mod set_enforced_options;
16
19
  mod set_peer;
20
+ mod skip;
17
21
 
18
22
  use anchor_trait::declare_instructions;
19
23
  use proc_macro2::TokenStream;
@@ -36,6 +40,10 @@ declare_instructions! {
36
40
  NextNonce => next_nonce,
37
41
  IsComposeMsgSender => is_compose_msg_sender,
38
42
  LzReceiveTypesInfo => lz_receive_types_info,
39
- LzReceiveTypesV2 => lz_receive_types_v2,
43
+ LzReceiveTypesV3 => lz_receive_types_v3,
40
44
  LzReceive => lz_receive,
45
+ Clear => clear,
46
+ Skip => skip,
47
+ Burn => burn,
48
+ Nilify => nilify,
41
49
  }
@@ -0,0 +1,69 @@
1
+ //! Code generator for the messaging-channel `nilify` instruction.
2
+ //!
3
+ //! Temporarily blocks execution until re-verification.
4
+ //! Requires [`MessagingChannelRoles::message_nilifier_role`]. The Endpoint accounts are passed as
5
+ //! remaining accounts in `oapp::endpoint_cpi::nilify` order.
6
+
7
+ use super::CodegenContext;
8
+ use anchor_trait::{DefaultAccounts, DefaultImpl, InstructionSpec};
9
+ use quote::{format_ident, quote};
10
+ use syn::parse_quote;
11
+
12
+ pub(super) fn spec() -> InstructionSpec<CodegenContext> {
13
+ InstructionSpec {
14
+ params_type: Some(quote!(::oapp::types::NilifyParams)),
15
+ return_type: quote!(()),
16
+ is_view: false,
17
+ default_impl: Some(DefaultImpl {
18
+ handler_ident: format_ident!("apply"),
19
+ generator: generate_default_impl,
20
+ }),
21
+ }
22
+ }
23
+
24
+ fn generate_default_impl(
25
+ ctx: &CodegenContext,
26
+ spec: &InstructionSpec<CodegenContext>,
27
+ ) -> DefaultAccounts {
28
+ let handler_ident = &spec.default_impl.as_ref().unwrap().handler_ident;
29
+ let params_type = spec.params_type.as_ref().unwrap();
30
+ let return_type = &spec.return_type;
31
+ let oapp_type = &ctx.oapp_type;
32
+ let role_type = &ctx.role_type;
33
+
34
+ DefaultAccounts {
35
+ struct_type: parse_quote! {
36
+ #[::rbac::only_role(
37
+ role = #role_type::message_nilifier_role(),
38
+ state = oapp,
39
+ authority = authority
40
+ )]
41
+ #[derive(Accounts)]
42
+ pub struct StdNilify<'info> {
43
+ pub authority: Signer<'info>,
44
+
45
+ pub oapp: Account<'info, #oapp_type>,
46
+ }
47
+ },
48
+ impl_block: parse_quote! {
49
+ impl StdNilify<'_> {
50
+ pub fn #handler_ident(ctx: &mut Context<Self>, params: &#params_type) -> Result<#return_type> {
51
+ let receiver = ctx.accounts.oapp.key();
52
+ ::oapp::endpoint_cpi::nilify(
53
+ ::oapp::endpoint::ID,
54
+ receiver,
55
+ ctx.remaining_accounts,
56
+ &ctx.accounts.oapp.signer_seeds(),
57
+ ::oapp::endpoint::types::NilifyParams {
58
+ receiver,
59
+ src_eid: params.src_eid,
60
+ sender: params.sender,
61
+ nonce: params.nonce,
62
+ payload_hash: params.payload_hash,
63
+ },
64
+ )
65
+ }
66
+ }
67
+ },
68
+ }
69
+ }
@@ -0,0 +1,68 @@
1
+ //! Code generator for the messaging-channel `skip` instruction.
2
+ //!
3
+ //! Skips the next inbound nonce. Requires
4
+ //! [`MessagingChannelRoles::messaging_channel_manager_role`]. The Endpoint accounts are passed as
5
+ //! remaining accounts in `oapp::endpoint_cpi::skip` order.
6
+
7
+ use super::CodegenContext;
8
+ use anchor_trait::{DefaultAccounts, DefaultImpl, InstructionSpec};
9
+ use quote::{format_ident, quote};
10
+ use syn::parse_quote;
11
+
12
+ pub(super) fn spec() -> InstructionSpec<CodegenContext> {
13
+ InstructionSpec {
14
+ params_type: Some(quote!(::oapp::types::SkipParams)),
15
+ return_type: quote!(()),
16
+ is_view: false,
17
+ default_impl: Some(DefaultImpl {
18
+ handler_ident: format_ident!("apply"),
19
+ generator: generate_default_impl,
20
+ }),
21
+ }
22
+ }
23
+
24
+ fn generate_default_impl(
25
+ ctx: &CodegenContext,
26
+ spec: &InstructionSpec<CodegenContext>,
27
+ ) -> DefaultAccounts {
28
+ let handler_ident = &spec.default_impl.as_ref().unwrap().handler_ident;
29
+ let params_type = spec.params_type.as_ref().unwrap();
30
+ let return_type = &spec.return_type;
31
+ let oapp_type = &ctx.oapp_type;
32
+ let role_type = &ctx.role_type;
33
+
34
+ DefaultAccounts {
35
+ struct_type: parse_quote! {
36
+ #[::rbac::only_role(
37
+ role = #role_type::messaging_channel_manager_role(),
38
+ state = oapp,
39
+ authority = authority
40
+ )]
41
+ #[derive(Accounts)]
42
+ pub struct StdSkip<'info> {
43
+ pub authority: Signer<'info>,
44
+
45
+ pub oapp: Account<'info, #oapp_type>,
46
+ }
47
+ },
48
+ impl_block: parse_quote! {
49
+ impl StdSkip<'_> {
50
+ pub fn #handler_ident(ctx: &mut Context<Self>, params: &#params_type) -> Result<#return_type> {
51
+ let receiver = ctx.accounts.oapp.key();
52
+ ::oapp::endpoint_cpi::skip(
53
+ ::oapp::endpoint::ID,
54
+ receiver,
55
+ ctx.remaining_accounts,
56
+ &ctx.accounts.oapp.signer_seeds(),
57
+ ::oapp::endpoint::types::SkipParams {
58
+ receiver,
59
+ src_eid: params.src_eid,
60
+ sender: params.sender,
61
+ nonce: params.nonce,
62
+ },
63
+ )
64
+ }
65
+ }
66
+ },
67
+ }
68
+ }
package/macros/src/lib.rs CHANGED
@@ -53,7 +53,7 @@ pub fn oapp_instruction(_attr: TokenStream, item: TokenStream) -> TokenStream {
53
53
 
54
54
  /// Attribute macro for generating Composer program entrypoints.
55
55
  ///
56
- /// This macro generates `lz_compose`, `lz_compose_types_v2`, and
56
+ /// This macro generates `lz_compose`, `lz_compose_types_v3`, and
57
57
  /// `lz_compose_types_info` instruction entrypoints for programs that implement
58
58
  /// the LayerZero composer interface. All three instructions are required —
59
59
  /// the implementor must provide custom handlers for each via
@@ -68,7 +68,7 @@ pub fn composer(attr: TokenStream, item: TokenStream) -> TokenStream {
68
68
 
69
69
  /// Marker attribute for required Composer instruction handlers.
70
70
  ///
71
- /// All three instructions (`lz_compose`, `lz_compose_types_v2`, `lz_compose_types_info`)
71
+ /// All three instructions (`lz_compose`, `lz_compose_types_v3`, `lz_compose_types_info`)
72
72
  /// must be provided — there are no framework-supplied defaults. Each handler's
73
73
  /// `ctx` parameter must be taken **by reference** (`&Context<T>`).
74
74
  ///
@@ -61,6 +61,7 @@ pub fn expand(attr: TokenStream, item: TokenStream) -> syn::Result<TokenStream>
61
61
  #enforced_options_prelude
62
62
 
63
63
  use ::oapp::OAppState as _;
64
+ use ::oapp::MessagingChannelRoles as _;
64
65
  }
65
66
  };
66
67
  let extra_mod_attrs = quote! {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@layerzerolabs/oapp-solana-contracts",
3
- "version": "1.2.63",
3
+ "version": "1.2.65",
4
4
  "private": false,
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -15,14 +15,14 @@
15
15
  "rustfmt.toml"
16
16
  ],
17
17
  "dependencies": {
18
- "@layerzerolabs/framework-solana-anchor-trait": "1.2.63",
19
- "@layerzerolabs/utils-solana-rbac": "1.2.63"
18
+ "@layerzerolabs/framework-solana-anchor-trait": "1.2.65",
19
+ "@layerzerolabs/rbac-solana-contracts": "1.2.65"
20
20
  },
21
21
  "devDependencies": {
22
- "@layerzerolabs/build-utils-rust": "1.2.63",
23
- "@layerzerolabs/typescript-configuration": "1.2.63",
24
- "@layerzerolabs/tsup-configuration": "1.2.63",
25
- "@layerzerolabs/vm-tooling-solana": "1.2.63"
22
+ "@layerzerolabs/build-utils-rust": "1.2.65",
23
+ "@layerzerolabs/tsup-configuration": "1.2.65",
24
+ "@layerzerolabs/typescript-configuration": "1.2.65",
25
+ "@layerzerolabs/vm-tooling-solana": "1.2.65"
26
26
  },
27
27
  "publishConfig": {
28
28
  "access": "restricted",
@@ -30,13 +30,12 @@
30
30
  },
31
31
  "externalRepoConfig": {
32
32
  "targets": [
33
- "audit-external",
34
- "console-solana-v1-internal"
33
+ "audit-external"
35
34
  ]
36
35
  },
37
36
  "implicitDependencies": {
38
37
  "@layerzerolabs/framework-solana-anchor-trait": "workspace:*",
39
- "@layerzerolabs/utils-solana-rbac": "workspace:*"
38
+ "@layerzerolabs/rbac-solana-contracts": "workspace:*"
40
39
  },
41
40
  "scripts": {
42
41
  "allow-read-write": "[ -z \"$CI\" ] || sudo chmod -R a+rwx ./target",