Expand description
The base library to use Compressed Accounts in Solana on-chain Rust and Anchor programs.
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.
For detailed documentation, visit zkcompression.com.
For pinocchio solana program development see light-sdk-pinocchio.
For rust client development see light-client.
For rust program testing see light-program-test.
For local test validator with light system programs see Light CLI.
§Using Compressed Accounts in Solana Programs
InstructionCompressedAccountMeta- Compressed account metadata structs for instruction data.PackedAccounts- Abstraction to prepare accounts offchain for instructions with compressed accounts.ValidityProof- Proves that new addresses don’t exist yet, and compressed account state exists.
- Compressed Account in Program
LightAccount- Compressed account abstraction similar to anchor Account.derive_address- Create a compressed account address.LightDiscriminator- DeriveMacro to derive a compressed account discriminator.
CpiCpiAccounts- Prepare accounts to cpi the light system program.LightSystemProgramCpi- Prepare instruction data to cpi the light system program.InvokeLightSystemProgram::invoke- Invoke the light system program via cpi.
§Client Program Interaction Flow
├─ 𝐂𝐥𝐢𝐞𝐧𝐭
│ ├─ 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
-
anchor- Derives AnchorSerialize, AnchorDeserialize instead of BorshSerialize, BorshDeserialize. -
v2- available on devnet, localnet, and light-program-test.
- Support for optimized v2 light system program instructions.
-
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
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
}Re-exports§
pub use account::sha::LightAccount;pub use proof::borsh_compat;pub use compressible::process_initialize_compression_config_account_info;pub use compressible::process_initialize_compression_config_checked;pub use compressible::process_update_compression_config;pub use compressible::CompressAs;pub use compressible::CompressedInitSpace;pub use compressible::CompressibleConfig;pub use compressible::CompressionInfo;pub use compressible::HasCompressionInfo;pub use compressible::Pack;pub use compressible::Space;pub use compressible::Unpack;pub use compressible::COMPRESSIBLE_CONFIG_SEED;pub use compressible::MAX_ADDRESS_TREES_PER_SPACE;pub use light_account_checks;pub use light_hasher;
Modules§
- account
- Compressed account abstraction similar to anchor Account.
- address
- Functions to derive compressed account addresses.
- compressible
- constants
- cpi
- Utilities to invoke the light-system-program via cpi.
- error
- instruction
- Utilities to build instructions for programs with compressed accounts.
- legacy
- Legacy types re-imported from programs which should be removed as soon as possible.
- proof
- transfer
- Transfer compressed sol between compressed accounts.
- utils
Macros§
- derive_
light_ cpi_ signer - Derives a complete Light Protocol CPI configuration at runtime
- derive_
light_ cpi_ signer_ pda - Derives a Light Protocol CPI signer PDA at compile time
- derive_
light_ rent_ sponsor - Derives a complete Rent Sponsor configuration for a program at compile time.
- derive_
light_ rent_ sponsor_ pda - Derives a Rent Sponsor PDA for a program at compile time.
- find_
cpi_ signer_ macro
Structs§
- CpiSigner
- Configuration struct containing program ID, CPI signer, and bump for Light Protocol
Traits§
Attribute Macros§
- light_
system_ accounts - Adds required fields to your anchor instruction for applying a zk-compressed state transition.
Derive Macros§
- Light
Discriminator - Light
Hasher - Makes the annotated struct hashable by implementing the following traits:
- Light
Hasher Sha - SHA256 variant of the LightHasher derive macro.
- Light
Traits - Implements traits on the given struct required for invoking The Light system program via CPI.