@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 +1 -1
- package/Cargo.toml +2 -6
- package/README.md +15 -9
- package/macros/Cargo.toml +1 -1
- package/macros/src/instructions/composer/lz_compose_types_info.rs +2 -2
- package/macros/src/instructions/composer/lz_compose_types_v3.rs +18 -0
- package/macros/src/instructions/composer/mod.rs +2 -2
- package/macros/src/instructions/oapp/burn.rs +69 -0
- package/macros/src/instructions/oapp/clear.rs +70 -0
- package/macros/src/instructions/oapp/lz_receive_types_info.rs +1 -3
- package/macros/src/instructions/oapp/lz_receive_types_v3.rs +17 -0
- package/macros/src/instructions/oapp/mod.rs +10 -2
- package/macros/src/instructions/oapp/nilify.rs +69 -0
- package/macros/src/instructions/oapp/skip.rs +68 -0
- package/macros/src/lib.rs +2 -2
- package/macros/src/oapp.rs +1 -0
- package/package.json +9 -10
- package/src/common.rs +14 -96
- package/src/endpoint_cpi.rs +155 -13
- package/src/errors.rs +4 -3
- package/src/lib.rs +26 -12
- package/src/lz_compose_types_v3.rs +72 -0
- package/src/lz_plan.rs +71 -0
- package/src/{lz_receive_types_v2.rs → lz_receive_types_v3.rs} +27 -54
- package/src/oapp_info.rs +1 -1
- package/src/options.rs +5 -15
- package/src/types.rs +44 -0
- package/macros/src/instructions/composer/lz_compose_types_v2.rs +0 -17
- package/macros/src/instructions/oapp/lz_receive_types_v2.rs +0 -17
- package/src/lz_compose_types_v2.rs +0 -88
|
@@ -1,74 +1,46 @@
|
|
|
1
|
+
//! Receive plan format (planner version 3) and Endpoint account helpers for building plans.
|
|
2
|
+
//!
|
|
3
|
+
//! See `docs/lz-receive-types.md` for the planning protocol.
|
|
1
4
|
use crate::{
|
|
2
|
-
|
|
3
|
-
COMPOSED_MESSAGE_HASH_SEED, ENDPOINT_SEED, EVENT_SEED, NONCE_SEED, OAPP_SEED,
|
|
4
|
-
PAYLOAD_HASH_SEED,
|
|
5
|
+
COMPOSED_MESSAGE_HASH_SEED, ENDPOINT_SEED, EVENT_SEED, NONCE_SEED, OAPP_SEED, PAYLOAD_HASH_SEED,
|
|
5
6
|
};
|
|
6
7
|
use anchor_lang::{prelude::*, solana_program::system_program::ID as SYSTEM_ID};
|
|
7
8
|
use solana_keccak_hasher::hash;
|
|
8
9
|
|
|
9
|
-
///
|
|
10
|
-
pub const LZ_RECEIVE_TYPES_VERSION: u8 =
|
|
10
|
+
/// Planner version returned by `lz_receive_types_info`.
|
|
11
|
+
pub const LZ_RECEIVE_TYPES_VERSION: u8 = 3;
|
|
11
12
|
|
|
12
|
-
///
|
|
13
|
+
/// Returned by `lz_receive_types_info`: the planner's read-only, app-specific inputs.
|
|
13
14
|
///
|
|
14
|
-
/// The
|
|
15
|
-
///
|
|
15
|
+
/// The client prepends the payer and the plan scratch account. Account order is part of the
|
|
16
|
+
/// planner ABI, including Anchor's optional-account sentinels.
|
|
16
17
|
#[derive(AnchorSerialize, AnchorDeserialize, Clone, Debug)]
|
|
17
|
-
pub struct
|
|
18
|
+
pub struct LzReceiveTypesV3Accounts {
|
|
18
19
|
pub accounts: Vec<Pubkey>,
|
|
19
20
|
}
|
|
20
21
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
///
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
pub struct LzReceiveTypesV2Result {
|
|
28
|
-
/// The version of context account
|
|
22
|
+
use crate::common::{AccountMetaRef, AddressLocator};
|
|
23
|
+
|
|
24
|
+
/// Receive plan written by `lz_receive_types_v3`.
|
|
25
|
+
#[derive(AnchorSerialize, AnchorDeserialize, Clone, Debug, PartialEq, Eq)]
|
|
26
|
+
pub struct LzReceiveTypesV3Result {
|
|
27
|
+
/// Execution-context version; selects the account [`AddressLocator::Context`] resolves to.
|
|
29
28
|
pub context_version: u8,
|
|
30
|
-
///
|
|
31
|
-
///
|
|
32
|
-
/// Enables efficient account list compression for complex transactions
|
|
33
|
-
pub alts: Vec<Pubkey>,
|
|
34
|
-
/// The complete list of instructions required for LzReceive execution
|
|
35
|
-
/// MUST include exactly one LzReceive instruction
|
|
36
|
-
/// MAY include additional Standard instructions for preprocessing/postprocessing
|
|
37
|
-
/// Instructions are executed in the order returned
|
|
29
|
+
/// Executed in order in one transaction. Must contain exactly one `LzReceive`; `Standard`
|
|
30
|
+
/// instructions may precede or follow it.
|
|
38
31
|
pub instructions: Vec<Instruction>,
|
|
39
32
|
}
|
|
40
33
|
|
|
41
|
-
///
|
|
42
|
-
|
|
43
|
-
/// V2's multi-instruction model enables complex patterns such as:
|
|
44
|
-
/// - Preprocessing steps before lz_receive (e.g., account initialization)
|
|
45
|
-
/// - Postprocessing steps after lz_receive (e.g., verification, cleanup)
|
|
46
|
-
/// - ABA messaging patterns with additional LayerZero sends
|
|
47
|
-
/// - Conditional execution flows based on message content
|
|
48
|
-
#[derive(AnchorSerialize, AnchorDeserialize, Clone)]
|
|
34
|
+
/// One instruction of a receive plan.
|
|
35
|
+
#[derive(AnchorSerialize, AnchorDeserialize, Clone, Debug, PartialEq, Eq)]
|
|
49
36
|
pub enum Instruction {
|
|
50
|
-
/// The
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
/// Uses AddressLocator for flexible address resolution
|
|
55
|
-
accounts: Vec<AccountMetaRef>,
|
|
56
|
-
},
|
|
57
|
-
/// Arbitrary custom instruction for preprocessing/postprocessing
|
|
58
|
-
/// Enables OApps to implement complex execution flows
|
|
59
|
-
Standard {
|
|
60
|
-
/// Target program ID for the custom instruction
|
|
61
|
-
program_id: Pubkey,
|
|
62
|
-
/// Account list for the custom instruction
|
|
63
|
-
/// Uses same AddressLocator system as LzReceive
|
|
64
|
-
accounts: Vec<AccountMetaRef>,
|
|
65
|
-
/// Instruction data payload
|
|
66
|
-
/// Raw bytes containing the instruction's parameters
|
|
67
|
-
data: Vec<u8>,
|
|
68
|
-
},
|
|
37
|
+
/// The delivery: this program's `lz_receive`, called with the original params.
|
|
38
|
+
LzReceive { accounts: Vec<AccountMetaRef> },
|
|
39
|
+
/// Any other instruction, submitted as given.
|
|
40
|
+
Standard { program_id: Pubkey, accounts: Vec<AccountMetaRef>, data: Vec<u8> },
|
|
69
41
|
}
|
|
70
42
|
|
|
71
|
-
///
|
|
43
|
+
/// Accounts for the Endpoint `clear` CPI, in the order [`crate::endpoint_cpi::clear`] expects.
|
|
72
44
|
pub fn get_accounts_for_clear(
|
|
73
45
|
endpoint_program: Pubkey,
|
|
74
46
|
receiver: &Pubkey,
|
|
@@ -111,7 +83,8 @@ pub fn get_accounts_for_clear(
|
|
|
111
83
|
]
|
|
112
84
|
}
|
|
113
85
|
|
|
114
|
-
///
|
|
86
|
+
/// Accounts for the Endpoint `send_compose` CPI, in the order [`crate::endpoint_cpi::send_compose`]
|
|
87
|
+
/// expects. The Executor's payer funds the composed-message account.
|
|
115
88
|
pub fn get_accounts_for_send_compose(
|
|
116
89
|
endpoint_program: Pubkey,
|
|
117
90
|
from: &Pubkey,
|
package/src/oapp_info.rs
CHANGED
|
@@ -32,7 +32,7 @@ pub const OAPP_BASE_SCHEMA_VERSION: u8 = 1;
|
|
|
32
32
|
|
|
33
33
|
/// IDL version (instructions + events) for this build. See `docs/oapp-info.md` § `idl_version`
|
|
34
34
|
/// Bump Rules.
|
|
35
|
-
pub const OAPP_BASE_IDL_VERSION: IdlVersion = IdlVersion { major:
|
|
35
|
+
pub const OAPP_BASE_IDL_VERSION: IdlVersion = IdlVersion { major: 2, minor: 0 };
|
|
36
36
|
|
|
37
37
|
/// Sentinel: no app-layer TLV entry follows `OAppBase`.
|
|
38
38
|
pub const NO_APP_DISCRIMINATOR: [u8; 8] = [0u8; 8];
|
package/src/options.rs
CHANGED
|
@@ -55,15 +55,11 @@ mod tests {
|
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
#[test]
|
|
58
|
-
fn
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
#[test]
|
|
64
|
-
fn assert_type_3_one_byte_returns_invalid_length() {
|
|
65
|
-
let err = assert_type_3(&[0x00]).unwrap_err();
|
|
66
|
-
assert_eq!(err, OAppError::InvalidOptionsLength.into());
|
|
58
|
+
fn assert_type_3_rejects_options_shorter_than_the_type_header() {
|
|
59
|
+
for options in [&[][..], &[0x00][..]] {
|
|
60
|
+
let err = assert_type_3(options).unwrap_err();
|
|
61
|
+
assert_eq!(err, OAppError::InvalidOptionsLength.into());
|
|
62
|
+
}
|
|
67
63
|
}
|
|
68
64
|
|
|
69
65
|
#[test]
|
|
@@ -82,12 +78,6 @@ mod tests {
|
|
|
82
78
|
assert_eq!(result, vec![0x01, 0x02, 0x03]);
|
|
83
79
|
}
|
|
84
80
|
|
|
85
|
-
#[test]
|
|
86
|
-
fn combine_no_enforced_extra_also_empty_returns_empty() {
|
|
87
|
-
let result = combine_options(vec![], &[]).unwrap();
|
|
88
|
-
assert_eq!(result, Vec::<u8>::new());
|
|
89
|
-
}
|
|
90
|
-
|
|
91
81
|
// -----------------------------------------------------------------------
|
|
92
82
|
// combine_options — extra empty
|
|
93
83
|
// -----------------------------------------------------------------------
|
package/src/types.rs
CHANGED
|
@@ -112,3 +112,47 @@ pub struct IsComposeMsgSenderParams {
|
|
|
112
112
|
/// The account claiming authorization to send the compose message.
|
|
113
113
|
pub compose_sender: Pubkey,
|
|
114
114
|
}
|
|
115
|
+
|
|
116
|
+
/// Params for the OApp `clear` instruction (messaging-channel manager).
|
|
117
|
+
///
|
|
118
|
+
/// `receiver` is intentionally omitted — the handler injects the OApp PDA.
|
|
119
|
+
#[derive(AnchorSerialize, AnchorDeserialize, Clone)]
|
|
120
|
+
pub struct ClearParams {
|
|
121
|
+
pub src_eid: u32,
|
|
122
|
+
pub sender: [u8; 32],
|
|
123
|
+
pub nonce: u64,
|
|
124
|
+
pub guid: [u8; 32],
|
|
125
|
+
pub message: Vec<u8>,
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/// Params for the OApp `skip` instruction (messaging-channel manager).
|
|
129
|
+
///
|
|
130
|
+
/// `receiver` is intentionally omitted — the handler injects the OApp PDA.
|
|
131
|
+
#[derive(AnchorSerialize, AnchorDeserialize, Clone)]
|
|
132
|
+
pub struct SkipParams {
|
|
133
|
+
pub src_eid: u32,
|
|
134
|
+
pub sender: [u8; 32],
|
|
135
|
+
pub nonce: u64,
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/// Params for the OApp `burn` instruction (messaging-channel manager).
|
|
139
|
+
///
|
|
140
|
+
/// `receiver` is intentionally omitted — the handler injects the OApp PDA.
|
|
141
|
+
#[derive(AnchorSerialize, AnchorDeserialize, Clone)]
|
|
142
|
+
pub struct BurnParams {
|
|
143
|
+
pub src_eid: u32,
|
|
144
|
+
pub sender: [u8; 32],
|
|
145
|
+
pub nonce: u64,
|
|
146
|
+
pub payload_hash: [u8; 32],
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/// Params for the OApp `nilify` instruction (message nilifier).
|
|
150
|
+
///
|
|
151
|
+
/// `receiver` is intentionally omitted — the handler injects the OApp PDA.
|
|
152
|
+
#[derive(AnchorSerialize, AnchorDeserialize, Clone)]
|
|
153
|
+
pub struct NilifyParams {
|
|
154
|
+
pub src_eid: u32,
|
|
155
|
+
pub sender: [u8; 32],
|
|
156
|
+
pub nonce: u64,
|
|
157
|
+
pub payload_hash: [u8; 32],
|
|
158
|
+
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
//! Code generator for the `lz_compose_types_v2` instruction.
|
|
2
|
-
//!
|
|
3
|
-
//! This instruction has no default implementation — users MUST provide
|
|
4
|
-
//! a custom handler named `lz_compose_types_v2` with `#[composer_instruction]`.
|
|
5
|
-
|
|
6
|
-
use super::ComposerCodegenContext;
|
|
7
|
-
use anchor_trait::InstructionSpec;
|
|
8
|
-
use quote::quote;
|
|
9
|
-
|
|
10
|
-
pub(super) fn spec() -> InstructionSpec<ComposerCodegenContext> {
|
|
11
|
-
InstructionSpec {
|
|
12
|
-
params_type: Some(quote!(::oapp::types::LzComposeParams)),
|
|
13
|
-
return_type: quote!(::oapp::lz_compose_types_v2::LzComposeTypesV2Result),
|
|
14
|
-
is_view: true,
|
|
15
|
-
default_impl: None,
|
|
16
|
-
}
|
|
17
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
//! Code generator for the `lz_receive_types_v2` instruction.
|
|
2
|
-
//!
|
|
3
|
-
//! This instruction has no default implementation — users MUST provide
|
|
4
|
-
//! a custom handler named `lz_receive_types_v2` with `#[oapp_instruction]`.
|
|
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!(::oapp::lz_receive_types_v2::LzReceiveTypesV2Result),
|
|
14
|
-
is_view: true,
|
|
15
|
-
default_impl: None,
|
|
16
|
-
}
|
|
17
|
-
}
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
use crate::{common::AccountMetaRef, COMPOSED_MESSAGE_HASH_SEED, EVENT_SEED};
|
|
2
|
-
use anchor_lang::prelude::*;
|
|
3
|
-
use solana_keccak_hasher::hash;
|
|
4
|
-
|
|
5
|
-
/// Version identifier returned by `lz_compose_types_info` for the V2 flow.
|
|
6
|
-
pub const LZ_COMPOSE_TYPES_VERSION: u8 = 2;
|
|
7
|
-
|
|
8
|
-
/// Payload returned from `lz_compose_types_info` when the version is V2.
|
|
9
|
-
///
|
|
10
|
-
/// The executor uses these accounts to construct the follow-up
|
|
11
|
-
/// `lz_compose_types_v2` call.
|
|
12
|
-
#[derive(AnchorSerialize, AnchorDeserialize, Clone, Debug)]
|
|
13
|
-
pub struct LzComposeTypesV2Accounts {
|
|
14
|
-
pub accounts: Vec<Pubkey>,
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/// Output of the lz_compose_types_v2 instruction.
|
|
18
|
-
///
|
|
19
|
-
/// This structure enables the multi-instruction execution model where composers
|
|
20
|
-
/// can define multiple instructions to be executed atomically by the Executor.
|
|
21
|
-
/// The Executor constructs a single transaction containing all returned instructions.
|
|
22
|
-
#[derive(AnchorSerialize, AnchorDeserialize, Clone)]
|
|
23
|
-
pub struct LzComposeTypesV2Result {
|
|
24
|
-
/// The version of context account
|
|
25
|
-
pub context_version: u8,
|
|
26
|
-
/// ALTs required for this execution context
|
|
27
|
-
/// Used by the Executor to resolve AltIndex references in AccountMetaRef
|
|
28
|
-
pub alts: Vec<Pubkey>,
|
|
29
|
-
/// The complete list of instructions required for LzCompose execution
|
|
30
|
-
/// MUST include exactly one LzCompose instruction
|
|
31
|
-
/// MAY include additional Standard instructions for preprocessing/postprocessing
|
|
32
|
-
/// Instructions are executed in the order returned
|
|
33
|
-
pub instructions: Vec<ComposeInstruction>,
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/// The list of instructions that can be executed in the LzCompose transaction.
|
|
37
|
-
#[derive(AnchorSerialize, AnchorDeserialize, Clone)]
|
|
38
|
-
pub enum ComposeInstruction {
|
|
39
|
-
/// The main LzCompose instruction (exactly one required per transaction)
|
|
40
|
-
/// This instruction processes the incoming composed message
|
|
41
|
-
LzCompose {
|
|
42
|
-
/// Account list for the lz_compose instruction
|
|
43
|
-
/// Uses AddressLocator for flexible address resolution
|
|
44
|
-
accounts: Vec<AccountMetaRef>,
|
|
45
|
-
},
|
|
46
|
-
/// Arbitrary custom instruction for preprocessing/postprocessing
|
|
47
|
-
Standard {
|
|
48
|
-
/// Target program ID for the custom instruction
|
|
49
|
-
program_id: Pubkey,
|
|
50
|
-
/// Account list for the custom instruction
|
|
51
|
-
accounts: Vec<AccountMetaRef>,
|
|
52
|
-
/// Instruction data payload
|
|
53
|
-
data: Vec<u8>,
|
|
54
|
-
},
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/// V2 version of get_accounts_for_clear_compose that returns AccountMetaRef
|
|
58
|
-
pub fn get_accounts_for_clear_compose(
|
|
59
|
-
endpoint_program: Pubkey,
|
|
60
|
-
from: &Pubkey,
|
|
61
|
-
to: &Pubkey,
|
|
62
|
-
guid: &[u8; 32],
|
|
63
|
-
index: u16,
|
|
64
|
-
composed_message: &[u8],
|
|
65
|
-
) -> Vec<AccountMetaRef> {
|
|
66
|
-
let (composed_message_account, _) = Pubkey::find_program_address(
|
|
67
|
-
&[
|
|
68
|
-
COMPOSED_MESSAGE_HASH_SEED,
|
|
69
|
-
&from.to_bytes(),
|
|
70
|
-
&to.to_bytes(),
|
|
71
|
-
&guid[..],
|
|
72
|
-
&index.to_be_bytes(),
|
|
73
|
-
&hash(composed_message).to_bytes(),
|
|
74
|
-
],
|
|
75
|
-
&endpoint_program,
|
|
76
|
-
);
|
|
77
|
-
|
|
78
|
-
let (event_authority_account, _) =
|
|
79
|
-
Pubkey::find_program_address(&[EVENT_SEED], &endpoint_program);
|
|
80
|
-
|
|
81
|
-
vec![
|
|
82
|
-
AccountMetaRef { pubkey: endpoint_program.into(), is_writable: false },
|
|
83
|
-
AccountMetaRef { pubkey: (*to).into(), is_writable: false },
|
|
84
|
-
AccountMetaRef { pubkey: composed_message_account.into(), is_writable: true },
|
|
85
|
-
AccountMetaRef { pubkey: event_authority_account.into(), is_writable: false },
|
|
86
|
-
AccountMetaRef { pubkey: endpoint_program.into(), is_writable: false },
|
|
87
|
-
]
|
|
88
|
-
}
|