light_sdk/instruction/mod.rs
1//! # Instruction data with AccountMeta (in Solana program)
2//! ### Example instruction data to create new compressed account with address:
3//! ```ignore
4//! #[derive(Clone, Debug, Default, BorshDeserialize, BorshSerialize)]
5//! pub struct CreatePdaInstructionData {
6//! /// Prove validity of the new address.
7//! pub proof: ValidityProof,
8//! pub address_tree_info: PackedAddressTreeInfo,
9//! /// Index of Merkle tree in the account array (remaining accounts in anchor).
10//! pub output_merkle_tree_index: u8,
11//! /// Arbitrary data of the new account.
12//! pub data: [u8; 31],
13//! /// Account offsets for convenience (can be hardcoded).
14//! pub system_accounts_offset: u8,
15//! pub tree_accounts_offset: u8,
16//! }
17//! ```
18//!
19//!
20//! ### Example instruction data to update a compressed account:
21//! ```ignore
22//! #[derive(Clone, Debug, Default, BorshDeserialize, BorshSerialize)]
23//!pub struct UpdatePdaInstructionData {
24//! /// Prove validity of the existing compressed account state.
25//! pub proof: ValidityProof,
26//! /// Data and metadata of the compressed account.
27//! pub my_compressed_account: UpdateMyCompressedAccount,
28//! /// Arbitrary new data the compressed account will be updated with.
29//! pub new_data: [u8; 31],
30//! /// Account offsets for convenience (can be hardcoded).
31//! pub system_accounts_offset: u8,
32//! }
33//!
34//! #[derive(Clone, Debug, Default, BorshDeserialize, BorshSerialize)]
35//! pub struct UpdateMyCompressedAccount {
36//! /// Metadata of the compressed account.
37//! pub meta: CompressedAccountMeta,
38//! /// Data of the compressed account.
39//! pub data: [u8; 31],
40//! }
41//! ```
42//! ### Example anchor instruction data to create new compressed account with address:
43//! ```ignore
44//! pub fn create_compressed_account<'info>(
45//! ctx: Context<'_, '_, '_, 'info, WithNestedData<'info>>,
46//! /// Prove validity of the new address.
47//! proof: ValidityProof,
48//! address_tree_info: PackedAddressTreeInfo,
49//! /// Index of Merkle tree in remaining accounts.
50//! output_tree_index: u8,
51//! /// Arbitrary data of the new account.
52//! name: String,
53//! ) -> Result<()>;
54//! ```
55//! ### Example anchor instruction data to update a compressed account:
56//! ```ignore
57//! pub fn update_compressed_account<'info>(
58//! ctx: Context<'_, '_, '_, 'info, UpdateNestedData<'info>>,
59//! /// Prove validity of the existing compressed account state.
60//! proof: ValidityProof,
61//! /// Data of the compressed account.
62//! my_compressed_account: MyCompressedAccount,
63//! /// Metadata of the compressed account.
64//! account_meta: CompressedAccountMeta,
65//! /// Arbitrary new data the compressed account will be updated with.
66//! nested_data: NestedData,
67//! ) -> Result<()>;
68//! ```
69//! ### Example instruction data to update a compressed account:
70//! # Create instruction with packed accounts (in client)
71//!
72//! ### Create instruction to create 1 compressed account and address
73//! ```ignore
74//! let config =
75//! ProgramTestConfig::new_v2(true, Some(vec![("sdk_anchor_test", sdk_anchor_test::ID)]));
76//! let mut rpc = LightProgramTest::new(config).await.unwrap();
77//! let name = "test";
78//! let address_tree_info = rpc.get_address_tree_v1();
79//! let (address, _) = derive_address(
80//! &[b"compressed", name.as_bytes()],
81//! &address_tree_info.tree,
82//! &sdk_anchor_test::ID,
83//! );
84//! let config = SystemAccountMetaConfig::new(sdk_anchor_test::ID);
85//! let mut remaining_accounts = PackedAccounts::default();
86//! remaining_accounts.add_system_accounts(config);
87//!
88//! let address_merkle_tree_info = rpc.get_address_tree_v1();
89//!
90//! let rpc_result = rpc
91//! .get_validity_proof(
92//! vec![],
93//! vec![AddressWithTree {
94//! address: *address,
95//! tree: address_merkle_tree_info.tree,
96//! }],
97//! None,
98//! )
99//! .await?
100//! .value;
101//! let packed_accounts = rpc_result.pack_tree_infos(&mut remaining_accounts);
102//!
103//! let output_tree_index = rpc
104//! .get_random_state_tree_info()
105//! .pack_output_tree_index(&mut remaining_accounts)
106//! .unwrap();
107//!
108//! let (remaining_accounts, _, _) = remaining_accounts.to_account_metas();
109//!
110//! let instruction_data = sdk_anchor_test::instruction::WithNestedData {
111//! proof: rpc_result.proof,
112//! address_tree_info: packed_accounts.address_trees[0],
113//! name,
114//! output_tree_index,
115//! };
116//!
117//! let accounts = sdk_anchor_test::accounts::WithNestedData {
118//! signer: payer.pubkey(),
119//! };
120//!
121//! let instruction = Instruction {
122//! program_id: sdk_anchor_test::ID,
123//! accounts: [accounts.to_account_metas(Some(true)), remaining_accounts].concat(),
124//! data: instruction_data.data(),
125//! };
126//! ```
127//!
128//! ### Create instruction to create 1 compressed account and address (anchor)
129//! ```ignore
130//! let mut remaining_accounts = PackedAccounts::default();
131//!
132//! let config = SystemAccountMetaConfig::new(sdk_anchor_test::ID);
133//! remaining_accounts.add_system_accounts(config);
134//! let hash = compressed_account.hash;
135//!
136//! let rpc_result = rpc
137//! .get_validity_proof(vec![hash], vec![], None)
138//! .await?
139//! .value;
140//!
141//! let packed_tree_accounts = rpc_result
142//! .pack_tree_infos(&mut remaining_accounts)
143//! .state_trees
144//! .unwrap();
145//!
146//! let (remaining_accounts, _, _) = remaining_accounts.to_account_metas();
147//!
148//! let my_compressed_account = MyCompressedAccount::deserialize(
149//! &mut compressed_account.data.as_mut().unwrap().data.as_slice(),
150//! )
151//! .unwrap();
152//! let instruction_data = sdk_anchor_test::instruction::UpdateNestedData {
153//! proof: rpc_result.proof,
154//! my_compressed_account,
155//! account_meta: CompressedAccountMeta {
156//! tree_info: packed_tree_accounts.packed_tree_infos[0],
157//! address: compressed_account.address.unwrap(),
158//! output_state_tree_index: packed_tree_accounts.output_tree_index,
159//! },
160//! nested_data,
161//! };
162//!
163//! let accounts = sdk_anchor_test::accounts::UpdateNestedData {
164//! signer: payer.pubkey(),
165//! };
166//!
167//! let instruction = Instruction {
168//! program_id: sdk_anchor_test::ID,
169//! accounts: [accounts.to_account_metas(Some(true)), remaining_accounts].concat(),
170//! data: instruction_data.data(),
171//! };
172//! ```
173// TODO: link to examples
174
175mod pack_accounts;
176mod system_accounts;
177mod tree_info;
178
179/// Zero-knowledge proof to prove the validity of existing compressed accounts and new addresses.
180pub use light_compressed_account::instruction_data::compressed_proof::ValidityProof;
181pub use light_sdk_types::instruction::*;
182pub use pack_accounts::*;
183pub use system_accounts::*;
184pub use tree_info::*;