1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
//! The base library to use Compressed Accounts in Solana on-chain Rust and Anchor programs.
//! Compressed accounts do not require rent-exemption, which makes them suitable for:
//! - user owned accounts
//! - not for config accounts which are often read
//! - not pool accounts, since compressed accounts cannot be used concurrently
//!
//! Compressed Accounts store state as account hashes in State Merkle trees.
//! and unique addresses in Address Merkle trees.
//! Validity proofs (zero-knowledge proofs) verify that compressed account
//! state exists and new addresses do not exist yet.
//!
//! - No rent exemption payment required.
//! - Constant 128-byte validity proof per transaction for one or multiple compressed accounts and addresses.
//! - Compressed account data is sent as instruction data when accessed.
//! - State and address trees are managed by the protocol.
//!
//! For full program examples, see the [Program Examples](https://github.com/Lightprotocol/program-examples).
//! For detailed documentation, visit [zkcompression.com](https://www.zkcompression.com/).
//! For pinocchio solana program development see [`light-sdk-pinocchio`](https://docs.rs/light-sdk-pinocchio).
//! For rust client development see [`light-client`](https://docs.rs/light-client).
//! For rust program testing see [`light-program-test`](https://docs.rs/light-program-test).
//! For local test validator with light system programs see [Light CLI](https://www.npmjs.com/package/@lightprotocol/zk-compression-cli).
//!
//! ## Difference to Light-Accounts (Light-PDA)
//! Light-PDAs are Solana accounts with sponsored rent-exemption.
//! There is no proof required for interactions with Light-PDAs which makes
//! them suitable for Defi Usecases. Compressed PDAs don't require rent-exemption,
//! but a proof for interactions.
//!
//! # Using Compressed Accounts in Solana Programs
//! 1. [`Instruction`](crate::instruction)
//! - [`CompressedAccountMeta`](crate::instruction::account_meta::CompressedAccountMeta) - Compressed account metadata structs for instruction data.
//! - [`PackedAccounts`](crate::instruction::PackedAccounts) - Abstraction to prepare accounts offchain for instructions with compressed accounts.
//! - [`ValidityProof`](crate::instruction::ValidityProof) - Proves that new addresses don't exist yet, and compressed account state exists.
//! 2. Compressed Account in Program
//! - [`LightAccount`](crate::account) - Compressed account abstraction similar to anchor Account.
//! - [`derive_address`](crate::address) - Create a compressed account address.
//! - [`LightDiscriminator`] - DeriveMacro to derive a compressed account discriminator.
//! 3. [`Cpi`](crate::cpi)
//! - [`CpiAccounts`](crate::cpi::v1::CpiAccounts) - Prepare accounts to cpi the light system program.
//! - [`LightSystemProgramCpi`](crate::cpi::v1::LightSystemProgramCpi) - Prepare instruction data to cpi the light system program.
//! - [`InvokeLightSystemProgram::invoke`](crate::cpi) - Invoke the light system program via cpi.
//!
//! # Client Program Interaction Flow
//! ```text
//! ├─ 𝐂𝐥𝐢𝐞𝐧𝐭
//! │ ├─ Get ValidityProof from RPC.
//! │ ├─ pack accounts with PackedAccounts into PackedAddressTreeInfo and PackedStateTreeInfo.
//! │ ├─ pack CompressedAccountMeta.
//! │ ├─ Build Instruction from PackedAccounts and CompressedAccountMetas.
//! │ └─ Send transaction.
//! │
//! └─ 𝐂𝐮𝐬𝐭𝐨𝐦 𝐏𝐫𝐨𝐠𝐫𝐚𝐦
//! ├─ CpiAccounts parse accounts consistent with PackedAccounts.
//! ├─ LightAccount instantiates from CompressedAccountMeta.
//! │
//! └─ 𝐋𝐢𝐠𝐡𝐭 𝐒𝐲𝐬𝐭𝐞𝐦 𝐏𝐫𝐨𝐠𝐫𝐚𝐦 𝐂𝐏𝐈
//! ├─ Verify ValidityProof.
//! ├─ Update State Merkle tree.
//! ├─ Update Address Merkle tree.
//! └─ Complete atomic state transition.
//! ```
//!
//! # Features
//! 1. `anchor` - Derives AnchorSerialize, AnchorDeserialize instead of BorshSerialize, BorshDeserialize.
//!
//! 2. `v2`
//! - available on devnet, localnet, and light-program-test.
//! - Support for optimized v2 light system program instructions.
//!
//! 3. `cpi-context` - Enables CPI context operations for batched compressed account operations.
//! - available on devnet, localnet, and light-program-test.
//! - Enables the use of one validity proof across multiple cpis from different programs in one instruction.
//! - For example spending compressed tokens (owned by the ctoken program) and updating a compressed pda (owned by a custom program)
//! with one validity proof.
//! - An instruction should not use more than one validity proof.
//! - Requires the v2 feature.
//!
//! ### Example Solana program code to create a compressed account
//! ```rust, compile_fail
//! use anchor_lang::{prelude::*, Discriminator};
//! use light_sdk::{
//! account::LightAccount,
//! address::v1::derive_address,
//! cpi::{v1::LightSystemProgramCpi, CpiAccounts, InvokeLightSystemProgram, LightCpiInstruction},
//! derive_light_cpi_signer,
//! instruction::{account_meta::CompressedAccountMeta, PackedAddressTreeInfo},
//! CpiSigner, LightDiscriminator, LightHasher, ValidityProof,
//! };
//!
//! declare_id!("2tzfijPBGbrR5PboyFUFKzfEoLTwdDSHUjANCw929wyt");
//!
//! pub const LIGHT_CPI_SIGNER: CpiSigner =
//! derive_light_cpi_signer!("2tzfijPBGbrR5PboyFUFKzfEoLTwdDSHUjANCw929wyt");
//!
//! #[program]
//! pub mod counter {
//!
//! use super::*;
//!
//! pub fn create_compressed_account<'info>(
//! ctx: Context<'_, '_, '_, 'info, CreateCompressedAccount<'info>>,
//! proof: ValidityProof,
//! address_tree_info: PackedAddressTreeInfo,
//! output_tree_index: u8,
//! ) -> Result<()> {
//! let light_cpi_accounts = CpiAccounts::new(
//! ctx.accounts.fee_payer.as_ref(),
//! ctx.remaining_accounts,
//! crate::LIGHT_CPI_SIGNER,
//! )?;
//!
//! let (address, address_seed) = derive_address(
//! &[b"counter", ctx.accounts.fee_payer.key().as_ref()],
//! &address_tree_info.get_tree_pubkey(&light_cpi_accounts)?,
//! &crate::ID,
//! );
//! let new_address_params = address_tree_info
//! .into_new_address_params_packed(address_seed);
//!
//! let mut my_compressed_account = LightAccount::<CounterAccount>::new_init(
//! &crate::ID,
//! Some(address),
//! output_tree_index,
//! );
//!
//! my_compressed_account.owner = ctx.accounts.fee_payer.key();
//!
//! LightSystemProgramCpi::new_cpi(crate::LIGHT_CPI_SIGNER, proof)
//! .with_light_account(my_compressed_account)?
//! .with_new_addresses(&[new_address_params])
//! .invoke(light_cpi_accounts)
//! }
//! }
//!
//! #[derive(Accounts)]
//! pub struct CreateCompressedAccount<'info> {
//! #[account(mut)]
//! pub fee_payer: Signer<'info>,
//! }
//!
//! #[derive(Clone, Debug, Default, LightDiscriminator)]
//!pub struct CounterAccount {
//! pub owner: Pubkey,
//! pub counter: u64
//!}
//! ```
/// Compressed account abstraction similar to anchor Account.
pub use LightAccount;
/// Functions to derive compressed account addresses.
/// Utilities to invoke the light-system-program via cpi.
/// Utilities to build instructions for programs with compressed accounts.
/// Transfer compressed sol between compressed accounts.
pub use borsh_compat;
// Re-export hasher types for macro-generated code
// Re-export compressed_account types for macro-generated code
// Re-export sdk_types for macro-generated code
use ;
use ;
pub use ;
// Re-export as extern crate so downstream crates can use `::light_hasher::` paths
pub extern crate light_hasher;
use DataHasher;
pub use ;
pub use ;
pub use ;
use AccountInfo;
use AccountMeta;
use ProgramError;
use Pubkey;
// Re-export SDK traits
pub use crateLightCpiInstruction;