-
For help with debugging use the [MCP Configuration](/learn/ai-tools-guide#mcp) or AskDevin via
+
For help with debugging use the [MCP Configuration](/ai-tools/guide#mcp) or AskDevin via
diff --git a/skill.md b/skill.md
index 4fa9a22f..4c8c9582 100644
--- a/skill.md
+++ b/skill.md
@@ -90,14 +90,14 @@ npx skills add https://zkcompression.com
| Use case | Skill |
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- |
-| Build DeFi programs (AMMs, vaults, lending) with Anchor or Pinocchio | [defi-program](ai-tools/skills/defi-program/) |
-| Integrate rent-free markets into routers and aggregators | [defi-router](ai-tools/skills/defi-router/) |
-| Stream account state via Laserstream gRPC | [data-streaming](ai-tools/skills/data-streaming/) |
-| Wallets and payment flows with light-token. Includes privy, wallet adapter, mobile wallet adapter signing. Optional nullifier to prevent your onchain instruction from being executed more than once. | [payments-and-wallets](ai-tools/skills/payments-and-wallets/) |
-| Airdrops, DePIN, token distribution | [airdrop](ai-tools/skills/airdrop/) |
-| Anti-double-spend nullifiers for Privacy-preserving ZK programs | [zk-nullifier](ai-tools/skills/zk-nullifier/) |
-| Testing programs and clients on localnet, devnet, mainnet | [testing](ai-tools/skills/testing/) |
-| Help with Debugging and Questions via DeepWiki MCP | [ask-mcp](ai-tools/skills/ask-mcp/) |
+| Build DeFi programs (AMMs, vaults, lending) with Anchor or Pinocchio | [defi-program](https://github.com/Lightprotocol/skills/tree/main/skills/defi-program) |
+| Integrate rent-free markets into routers and aggregators | [defi-router](https://github.com/Lightprotocol/skills/tree/main/skills/defi-router) |
+| Stream account state via Laserstream gRPC | [data-streaming](https://github.com/Lightprotocol/skills/tree/main/skills/data-streaming) |
+| Wallets and payment flows with light-token. Includes privy, wallet adapter, mobile wallet adapter signing. Optional nullifier to prevent your onchain instruction from being executed more than once. | [payments-and-wallets](https://github.com/Lightprotocol/skills/tree/main/skills/payments-and-wallets) |
+| Airdrops, DePIN, token distribution | [airdrop](https://github.com/Lightprotocol/skills/tree/main/skills/airdrop) |
+| Anti-double-spend nullifiers for Privacy-preserving ZK programs | [zk-nullifier](https://github.com/Lightprotocol/skills/tree/main/skills/zk-nullifier) |
+| Testing programs and clients on localnet, devnet, mainnet | [testing](https://github.com/Lightprotocol/skills/tree/main/skills/testing) |
+| Help with Debugging and Questions via DeepWiki MCP | [ask-mcp](https://github.com/Lightprotocol/skills/tree/main/skills/ask-mcp) |
Skills for compressed PDAs and more are in development.
diff --git a/snippets/code-snippets/light-token/counter/anchor-macro/full-example.mdx b/snippets/code-snippets/light-token/counter/anchor-macro/full-example.mdx
new file mode 100644
index 00000000..dd4680f2
--- /dev/null
+++ b/snippets/code-snippets/light-token/counter/anchor-macro/full-example.mdx
@@ -0,0 +1,266 @@
+
+
+
+```rust lib.rs expandable
+use anchor_lang::prelude::*;
+use light_account::{
+ CompressionInfo, LightAccount, LightAccounts, CreateAccountsProof,
+ derive_light_cpi_signer, light_program, CpiSigner,
+};
+
+declare_id!("YourProgramId11111111111111111111111111111111");
+
+pub const LIGHT_CPI_SIGNER: CpiSigner =
+ derive_light_cpi_signer!("YourProgramId11111111111111111111111111111111");
+
+pub const COUNTER_SEED: &[u8] = b"counter";
+
+#[derive(Default, Debug, InitSpace, LightAccount)]
+#[account]
+pub struct Counter {
+ pub compression_info: CompressionInfo,
+ pub owner: Pubkey,
+ pub count: u64,
+}
+
+#[derive(AnchorSerialize, AnchorDeserialize, Clone)]
+pub struct CreateCounterParams {
+ pub create_accounts_proof: CreateAccountsProof,
+ pub count: u64,
+}
+
+#[light_program]
+#[program]
+pub mod counter {
+ use super::*;
+
+ pub fn create_counter<'info>(
+ ctx: Context<'_, '_, '_, 'info, CreateCounter<'info>>,
+ params: CreateCounterParams,
+ ) -> Result<()> {
+ ctx.accounts.counter.owner = ctx.accounts.owner.key();
+ ctx.accounts.counter.count = params.count;
+ Ok(())
+ }
+
+ /// Standard Anchor — no Light-specific changes.
+ pub fn increment(ctx: Context) -> Result<()> {
+ ctx.accounts.counter.count = ctx.accounts.counter.count.checked_add(1).unwrap();
+ Ok(())
+ }
+
+ /// Standard Anchor — no Light-specific changes.
+ pub fn close_counter(_ctx: Context) -> Result<()> {
+ Ok(())
+ }
+}
+
+#[derive(Accounts, LightAccounts)]
+#[instruction(params: CreateCounterParams)]
+pub struct CreateCounter<'info> {
+ #[account(mut)]
+ pub fee_payer: Signer<'info>,
+
+ /// CHECK: Read-only, used for PDA derivation.
+ pub owner: AccountInfo<'info>,
+
+ /// CHECK: Validated by Light Protocol CPI.
+ pub compression_config: AccountInfo<'info>,
+
+ /// CHECK: PDA rent sponsor for compression rent reimbursement.
+ #[account(mut)]
+ pub pda_rent_sponsor: AccountInfo<'info>,
+
+ #[account(
+ init,
+ payer = fee_payer,
+ space = 8 + ::INIT_SPACE,
+ seeds = [COUNTER_SEED, owner.key().as_ref()],
+ bump,
+ )]
+ #[light_account(init)]
+ pub counter: Account<'info, Counter>,
+
+ pub system_program: Program<'info, System>,
+}
+
+/// Standard Anchor
+#[derive(Accounts)]
+pub struct Increment<'info> {
+ pub owner: Signer<'info>,
+
+ #[account(
+ mut,
+ seeds = [COUNTER_SEED, owner.key().as_ref()],
+ bump,
+ has_one = owner,
+ )]
+ pub counter: Account<'info, Counter>,
+}
+
+/// Standard Anchor close
+#[derive(Accounts)]
+pub struct CloseCounter<'info> {
+ #[account(mut)]
+ pub fee_payer: Signer<'info>,
+
+ pub owner: Signer<'info>,
+
+ #[account(
+ mut,
+ close = fee_payer,
+ seeds = [COUNTER_SEED, owner.key().as_ref()],
+ bump,
+ has_one = owner,
+ )]
+ pub counter: Account<'info, Counter>,
+}
+```
+
+
+
+
+```rust counter.rs expandable
+//! Light-PDA lifecycle test: create → increment → close.
+
+use anchor_lang::{InstructionData, ToAccountMetas};
+use light_client::interface::{
+ get_create_accounts_proof, CreateAccountsProofInput, InitializeRentFreeConfig,
+};
+use light_program_test::{
+ program_test::{setup_mock_program_data, LightProgramTest},
+ ProgramTestConfig, Rpc,
+};
+use light_token::instruction::RENT_SPONSOR;
+use solana_instruction::Instruction;
+use solana_keypair::Keypair;
+use solana_pubkey::Pubkey;
+use solana_signer::Signer;
+
+const PROGRAM_ID: Pubkey = counter::ID;
+
+/// Setup: create test RPC and initialize rent-free config for the counter program.
+async fn setup() -> (LightProgramTest, Keypair, Pubkey) {
+ let config = ProgramTestConfig::new_v2(true, Some(vec![("counter", PROGRAM_ID)]));
+ let mut rpc = LightProgramTest::new(config).await.unwrap();
+ let payer = rpc.get_payer().insecure_clone();
+
+ let program_data_pda = setup_mock_program_data(&mut rpc, &payer, &PROGRAM_ID);
+
+ // Register this program for rent-free accounts. One-time setup per program.
+ let (init_config_ix, compression_config) = InitializeRentFreeConfig::new(
+ &PROGRAM_ID,
+ &payer.pubkey(),
+ &program_data_pda,
+ RENT_SPONSOR,
+ payer.pubkey(),
+ )
+ .build();
+
+ rpc.create_and_send_transaction(&[init_config_ix], &payer.pubkey(), &[&payer])
+ .await
+ .expect("initialize rent-free config");
+
+ (rpc, payer, compression_config)
+}
+
+#[tokio::test]
+async fn test_counter_lifecycle() {
+ let (mut rpc, payer, compression_config) = setup().await;
+
+ // ── Create ───────────────────────────────────────────────────────────
+ let (counter_pda, _) = Pubkey::find_program_address(
+ &[counter::COUNTER_SEED, payer.pubkey().as_ref()],
+ &PROGRAM_ID,
+ );
+
+ let proof_result = get_create_accounts_proof(
+ &rpc,
+ &PROGRAM_ID,
+ vec![CreateAccountsProofInput::pda(counter_pda)],
+ )
+ .await
+ .unwrap();
+
+ let create_accounts = counter::accounts::CreateCounter {
+ fee_payer: payer.pubkey(),
+ owner: payer.pubkey(),
+ compression_config,
+ counter: counter_pda,
+ system_program: solana_sdk::system_program::ID,
+ };
+
+ let create_data = counter::instruction::CreateCounter {
+ params: counter::CreateCounterParams {
+ create_accounts_proof: proof_result.create_accounts_proof,
+ count: 0,
+ },
+ };
+
+ let create_ix = Instruction {
+ program_id: PROGRAM_ID,
+ accounts: [
+ create_accounts.to_account_metas(None),
+ proof_result.remaining_accounts,
+ ]
+ .concat(),
+ data: create_data.data(),
+ };
+
+ rpc.create_and_send_transaction(&[create_ix], &payer.pubkey(), &[&payer])
+ .await
+ .expect("create_counter");
+
+ // Verify initial state.
+ let account = rpc.get_account(counter_pda).await.unwrap().unwrap();
+ let ctr: counter::Counter =
+ anchor_lang::AccountDeserialize::try_deserialize(&mut account.data.as_slice()).unwrap();
+ assert_eq!(ctr.count, 0);
+ assert_eq!(ctr.owner, payer.pubkey());
+
+ // ── Increment (standard Anchor) ────────────────────────────
+ let inc_accounts = counter::accounts::Increment {
+ owner: payer.pubkey(),
+ counter: counter_pda,
+ };
+ let inc_data = counter::instruction::Increment {};
+ let inc_ix = Instruction {
+ program_id: PROGRAM_ID,
+ accounts: inc_accounts.to_account_metas(None),
+ data: inc_data.data(),
+ };
+
+ rpc.create_and_send_transaction(&[inc_ix], &payer.pubkey(), &[&payer])
+ .await
+ .expect("increment");
+
+ let account = rpc.get_account(counter_pda).await.unwrap().unwrap();
+ let ctr: counter::Counter =
+ anchor_lang::AccountDeserialize::try_deserialize(&mut account.data.as_slice()).unwrap();
+ assert_eq!(ctr.count, 1);
+
+ // ── Close (standard Anchor) ────────────────────────────────
+ let close_accounts = counter::accounts::CloseCounter {
+ fee_payer: payer.pubkey(),
+ owner: payer.pubkey(),
+ counter: counter_pda,
+ };
+ let close_data = counter::instruction::CloseCounter {};
+ let close_ix = Instruction {
+ program_id: PROGRAM_ID,
+ accounts: close_accounts.to_account_metas(None),
+ data: close_data.data(),
+ };
+
+ rpc.create_and_send_transaction(&[close_ix], &payer.pubkey(), &[&payer])
+ .await
+ .expect("close_counter");
+
+ // Account should no longer exist.
+ let account = rpc.get_account(counter_pda).await.unwrap();
+ assert!(account.is_none(), "counter should be closed");
+}
+```
+
+
+
diff --git a/snippets/code-snippets/light-token/transfer-interface/anchor-program/create-and-transfer-example.mdx b/snippets/code-snippets/light-token/transfer-interface/anchor-program/create-and-transfer-example.mdx
new file mode 100644
index 00000000..868d48b6
--- /dev/null
+++ b/snippets/code-snippets/light-token/transfer-interface/anchor-program/create-and-transfer-example.mdx
@@ -0,0 +1,249 @@
+
+```rust lib.rs
+#![allow(unexpected_cfgs, deprecated)]
+
+use anchor_lang::prelude::*;
+use light_sdk::interface::CreateAccountsProof;
+use light_token::anchor::{derive_light_cpi_signer, light_program, CpiSigner, LightAccounts};
+use light_token::instruction::TransferInterfaceCpi;
+
+declare_id!("672fL1Nm191MbPoygNM9DRiG2psBELn97XUpGbU3jW7E");
+
+pub const LIGHT_CPI_SIGNER: CpiSigner =
+ derive_light_cpi_signer!("672fL1Nm191MbPoygNM9DRiG2psBELn97XUpGbU3jW7E");
+
+#[derive(AnchorSerialize, AnchorDeserialize, Clone)]
+pub struct TransferParams {
+ pub create_accounts_proof: CreateAccountsProof,
+ pub dest_associated_token_account_bump: u8,
+ pub amount: u64,
+ pub decimals: u8,
+}
+
+#[light_program]
+#[program]
+pub mod create_and_transfer {
+ use super::*;
+
+ pub fn transfer<'info>(
+ ctx: Context<'_, '_, '_, 'info, Transfer<'info>>,
+ params: TransferParams,
+ ) -> Result<()> {
+ TransferInterfaceCpi::new(
+ params.amount,
+ params.decimals,
+ ctx.accounts.source.to_account_info(),
+ ctx.accounts.destination.to_account_info(),
+ ctx.accounts.authority.to_account_info(),
+ ctx.accounts.payer.to_account_info(),
+ ctx.accounts.light_token_cpi_authority.to_account_info(),
+ ctx.accounts.system_program.to_account_info(),
+ )
+ .invoke()
+ .map_err(|e| anchor_lang::prelude::ProgramError::from(e))?;
+ Ok(())
+ }
+}
+
+#[derive(Accounts, LightAccounts)]
+#[instruction(params: TransferParams)]
+pub struct Transfer<'info> {
+ #[account(mut)]
+ pub payer: Signer<'info>,
+
+ pub authority: Signer<'info>,
+
+ /// CHECK: Validated by light-token CPI
+ pub mint: AccountInfo<'info>,
+
+ /// CHECK: Validated by light-token CPI
+ #[account(mut)]
+ pub source: AccountInfo<'info>,
+
+ /// CHECK: Validated by light-token CPI
+ pub recipient: AccountInfo<'info>,
+
+ /// CHECK: Validated by light-token CPI
+ #[account(mut)]
+ #[light_account(init,
+ associated_token::authority = recipient,
+ associated_token::mint = mint,
+ associated_token::bump = params.dest_associated_token_account_bump
+ )]
+ pub destination: UncheckedAccount<'info>,
+
+ /// CHECK: Validated by light-token CPI
+ pub light_token_program: AccountInfo<'info>,
+
+ pub system_program: Program<'info, System>,
+
+ /// CHECK: Validated by light-token CPI
+ pub light_token_compressible_config: AccountInfo<'info>,
+
+ /// CHECK: Validated by light-token CPI
+ #[account(mut)]
+ pub rent_sponsor: AccountInfo<'info>,
+
+ /// CHECK: Validated by light-token CPI
+ pub light_token_cpi_authority: AccountInfo<'info>,
+}
+```
+
+```rust test.rs
+use anchor_lang::{InstructionData, ToAccountMetas};
+use light_client::interface::{get_create_accounts_proof, InitializeRentFreeConfig};
+use light_program_test::{
+ program_test::{setup_mock_program_data, LightProgramTest},
+ Indexer, ProgramTestConfig, Rpc,
+};
+use light_sdk_types::LIGHT_TOKEN_PROGRAM_ID;
+use light_token::instruction::{
+ derive_token_ata, find_mint_address, COMPRESSIBLE_CONFIG_V1, RENT_SPONSOR,
+};
+use solana_instruction::Instruction;
+use solana_keypair::Keypair;
+use solana_signer::Signer;
+use create_and_transfer::{TransferParams, ID};
+
+#[tokio::test]
+async fn test_transfer() {
+ let config = ProgramTestConfig::new_v2(true, Some(vec![("create_and_transfer", ID)]))
+ .with_light_protocol_events();
+
+ let mut rpc = LightProgramTest::new(config).await.unwrap();
+ let payer = rpc.get_payer().insecure_clone();
+
+ let program_data_pda = setup_mock_program_data(&mut rpc, &payer, &ID);
+
+ let (init_config_ix, _config_pda) = InitializeRentFreeConfig::new(
+ &ID,
+ &payer.pubkey(),
+ &program_data_pda,
+ RENT_SPONSOR,
+ payer.pubkey(),
+ )
+ .build();
+
+ rpc.create_and_send_transaction(&[init_config_ix], &payer.pubkey(), &[&payer])
+ .await
+ .unwrap();
+
+ let (mint_pda, _mint_seed) = setup_create_mint(
+ &mut rpc,
+ &payer,
+ payer.pubkey(), // mint_authority
+ 9, // decimals
+ )
+ .await;
+
+ println!("Mint created at: {}", mint_pda);
+
+ let sender = Keypair::new();
+ let (sender_associated_token_account, _sender_associated_token_account_bump) =
+ derive_token_ata(&sender.pubkey(), &mint_pda);
+
+ let create_sender_associated_token_account_ix =
+ light_token::instruction::CreateAssociatedTokenAccount::new(
+ payer.pubkey(),
+ sender.pubkey(),
+ mint_pda,
+ )
+ .instruction()
+ .unwrap();
+
+ rpc.create_and_send_transaction(
+ &[create_sender_associated_token_account_ix],
+ &payer.pubkey(),
+ &[&payer],
+ )
+ .await
+ .unwrap();
+
+ let mint_amount: u64 = 1_000_000_000;
+ mint_tokens(&mut rpc, &payer, mint_pda, sender_associated_token_account, mint_amount).await;
+
+ println!(
+ "Minted {} tokens to sender: {}",
+ mint_amount, sender_associated_token_account
+ );
+
+ let recipient = Keypair::new();
+ let (recipient_associated_token_account, recipient_associated_token_account_bump) =
+ derive_token_ata(&recipient.pubkey(), &mint_pda);
+
+ let transfer_proof_result = get_create_accounts_proof(&rpc, &ID, vec![]).await.unwrap();
+
+ let transfer_accounts = create_and_transfer::accounts::Transfer {
+ payer: payer.pubkey(),
+ authority: sender.pubkey(),
+ mint: mint_pda,
+ source: sender_associated_token_account,
+ recipient: recipient.pubkey(),
+ destination: recipient_associated_token_account,
+ light_token_program: LIGHT_TOKEN_PROGRAM_ID.into(),
+ system_program: solana_sdk::system_program::ID,
+ light_token_compressible_config: COMPRESSIBLE_CONFIG_V1,
+ rent_sponsor: RENT_SPONSOR,
+ light_token_cpi_authority: light_token_types::CPI_AUTHORITY_PDA.into(),
+ };
+
+ let transfer_amount: u64 = 500_000_000; // 0.5 tokens
+ let decimals: u8 = 9;
+
+ let transfer_ix = Instruction {
+ program_id: ID,
+ accounts: [
+ transfer_accounts.to_account_metas(None),
+ transfer_proof_result.remaining_accounts,
+ ]
+ .concat(),
+ data: create_and_transfer::instruction::Transfer {
+ params: TransferParams {
+ create_accounts_proof: transfer_proof_result.create_accounts_proof,
+ dest_associated_token_account_bump: recipient_associated_token_account_bump,
+ amount: transfer_amount,
+ decimals,
+ },
+ }
+ .data(),
+ };
+
+ let sig = rpc
+ .create_and_send_transaction(&[transfer_ix], &payer.pubkey(), &[&payer, &sender])
+ .await
+ .unwrap();
+
+ println!("Transfer Tx: {}", sig);
+
+ use light_token_interface::state::Token;
+
+ let recipient_account = rpc
+ .get_account(recipient_associated_token_account)
+ .await
+ .unwrap()
+ .unwrap();
+ let recipient_token: Token =
+ borsh::BorshDeserialize::deserialize(&mut &recipient_account.data[..]).unwrap();
+
+ assert_eq!(recipient_token.amount, transfer_amount);
+ assert_eq!(recipient_token.owner, recipient.pubkey().to_bytes());
+
+ println!(
+ "Recipient balance: {}, owner: {}",
+ recipient_token.amount,
+ recipient.pubkey()
+ );
+
+ let sender_account = rpc
+ .get_account(sender_associated_token_account)
+ .await
+ .unwrap()
+ .unwrap();
+ let sender_token: Token =
+ borsh::BorshDeserialize::deserialize(&mut &sender_account.data[..]).unwrap();
+
+ assert_eq!(sender_token.amount, mint_amount - transfer_amount);
+ println!("Sender remaining balance: {}", sender_token.amount);
+}
+```
+
\ No newline at end of file
diff --git a/snippets/jsx/liquid-glass-pill.jsx b/snippets/jsx/liquid-glass-pill.jsx
index 05670a24..2e721839 100644
--- a/snippets/jsx/liquid-glass-pill.jsx
+++ b/snippets/jsx/liquid-glass-pill.jsx
@@ -1,6 +1,6 @@
// Styles in style.css - uses .glass-pill classes
-export const LiquidGlassPill = ({ title }) => {
+export const LiquidGlassPill = ({ title, children }) => {
return (
@@ -8,6 +8,7 @@ export const LiquidGlassPill = ({ title }) => {
{title}
+ {children}
);
diff --git a/snippets/jsx/partner-logos.jsx b/snippets/jsx/partner-logos.jsx
new file mode 100644
index 00000000..94465bc1
--- /dev/null
+++ b/snippets/jsx/partner-logos.jsx
@@ -0,0 +1,24 @@
+// Styles in style.css - uses .partner-logos classes
+
+export const PartnerLogos = () => {
+ return (
+
+ );
+};
diff --git a/snippets/overview-tables/compressed-pdas-guides-table.mdx b/snippets/overview-tables/compressed-pdas-guides-table.mdx
index b72a52b2..8ee1299f 100644
--- a/snippets/overview-tables/compressed-pdas-guides-table.mdx
+++ b/snippets/overview-tables/compressed-pdas-guides-table.mdx
@@ -1,7 +1,50 @@
-| Guide | Description |
-| ------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
-| [Create Compressed Accounts](/compressed-pdas/guides/how-to-create-compressed-accounts) | Create compressed accounts with address |
-| [Update Compressed Accounts](/compressed-pdas/guides/how-to-update-compressed-accounts) | Update compressed accounts |
-| [Close Compressed Accounts](/compressed-pdas/guides/how-to-close-compressed-accounts) | Close compressed accounts, retain the address |
-| [Reinitialize Compressed Accounts](/compressed-pdas/guides/how-to-reinitialize-compressed-accounts) | Reinitialize closed compressed accounts with the same address and new values |
-| [Burn Compressed Accounts](/compressed-pdas/guides/how-to-burn-compressed-accounts) | Burn compressed accounts and their address permanently |
+
+
+
+
+
+
+
+ |
+ |
+
+
+
+
+ |
+ Create
+ |
+ Initialize compressed PDAs in your program |
+
+
+ |
+ Update
+ |
+ Modify state in compressed accounts |
+
+
+ |
+ Close
+ |
+ Reclaim lamports from compressed accounts |
+
+
+ |
+ Reinitialize
+ |
+ Reset and reuse compressed accounts |
+
+
+ |
+ Burn
+ |
+ Permanently delete compressed accounts |
+
+
+ |
+ Nullifier PDAs
+ |
+ Prevent replay attacks with one-time use accounts |
+
+
+
diff --git a/snippets/overview-tables/compressed-tokens-advanced-guides-table.mdx b/snippets/overview-tables/compressed-tokens-advanced-guides-table.mdx
index ac09b01c..48166ba4 100644
--- a/snippets/overview-tables/compressed-tokens-advanced-guides-table.mdx
+++ b/snippets/overview-tables/compressed-tokens-advanced-guides-table.mdx
@@ -1,7 +1,4 @@
| Guide | Description |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ |
-| [Create an Airdrop without Claim](/compressed-tokens/advanced-guides/airdrop) | ZK Compression is the most efficient way to distribute SPL tokens. Distribute via Webapp or customize with claim. |
-| [Combine Instructions in One Transaction](/compressed-tokens/advanced-guides/how-to-combine-operations-in-one-transaction) | Execute multiple token instructions within a single transaction |
-| [For Wallet Applications](/compressed-tokens/advanced-guides/add-wallet-support-for-compressed-tokens) | Add compressed token support in your wallet application |
-| [Use Token-2022 with Compression](/compressed-tokens/advanced-guides/use-token-2022-with-compression) | Create compressed Token-2022 mints with metadata and other extensions |
+| [Create an Airdrop without Claim](/compressed-tokens/airdrop) | ZK Compression is the most efficient way to distribute SPL tokens. Distribute via Webapp or customize with claim. |
| [Privy Guide](/compressed-tokens/for-privy) | Integrate compressed tokens with Privy embedded wallets for rent-free token accounts |
diff --git a/snippets/overview-tables/compressed-tokens-guides-table.mdx b/snippets/overview-tables/compressed-tokens-guides-table.mdx
index a9997b8c..555d7b53 100644
--- a/snippets/overview-tables/compressed-tokens-guides-table.mdx
+++ b/snippets/overview-tables/compressed-tokens-guides-table.mdx
@@ -1,11 +1,11 @@
| Guide | Description |
| :---------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------- |
-| [Create Compressed Token Accounts](/compressed-tokens/guides/create-compressed-token-accounts) | Create compressed and learn difference to regular token accounts |
-| [Mint Compressed Tokens](/compressed-tokens/guides/mint-compressed-tokens) | Create new compressed tokens to existing mint |
-| [Transfer Compressed Tokens](/compressed-tokens/guides/transfer-compressed-tokens) | Move compressed tokens between compressed accounts |
-| [Decompress and Compress Tokens](/compressed-tokens/guides/compress-decompress) | Convert SPL tokens between regular and compressed format |
-| [Compress Complete SPL Token Accounts](/compressed-tokens/guides/compress-spl-token-account) | Compress complete SPL token accounts and reclaim rent afterwards |
-| [Create a Mint with Token Pool for Compression](/compressed-tokens/guides/create-mint-with-token-pool) | Create new SPL mint with token pool for compression |
-| [Create Token Pools for Mint Accounts](/compressed-tokens/guides/add-token-pools-to-mint-accounts) | Create token pool for compression for existing SPL mints |
-| [Merge Compressed Accounts](/compressed-tokens/guides/merge-compressed-token-accounts) | Consolidate multiple compressed accounts of the same mint into one |
-| [Approve and Revoke Delegate Authority](/compressed-tokens/guides/delegate) | Approve or revoke delegates for compressed token accounts |
+| [Create Compressed Token Accounts](https://github.com/Lightprotocol/examples-zk-compression/tree/main/compressed-token-cookbook) | Create compressed and learn difference to regular token accounts |
+| [Mint Compressed Tokens](https://github.com/Lightprotocol/examples-zk-compression/tree/main/compressed-token-cookbook) | Create new compressed tokens to existing mint |
+| [Transfer Compressed Tokens](https://github.com/Lightprotocol/examples-zk-compression/tree/main/compressed-token-cookbook) | Move compressed tokens between compressed accounts |
+| [Decompress and Compress Tokens](https://github.com/Lightprotocol/examples-zk-compression/tree/main/compressed-token-cookbook) | Convert SPL tokens between regular and compressed format |
+| [Compress Complete SPL Token Accounts](https://github.com/Lightprotocol/examples-zk-compression/tree/main/compressed-token-cookbook) | Compress complete SPL token accounts and reclaim rent afterwards |
+| [Create a Mint with Interface PDA for Compression](https://github.com/Lightprotocol/examples-zk-compression/tree/main/compressed-token-cookbook) | Create new SPL mint with token pool for compression |
+| [Create Token Pools for Mint Accounts](https://github.com/Lightprotocol/examples-zk-compression/tree/main/compressed-token-cookbook) | Create token pool for compression for existing SPL mints |
+| [Merge Compressed Accounts](https://github.com/Lightprotocol/examples-zk-compression/tree/main/compressed-token-cookbook) | Consolidate multiple compressed accounts of the same mint into one |
+| [Approve and Revoke Delegate Authority](https://github.com/Lightprotocol/examples-zk-compression/tree/main/compressed-token-cookbook) | Approve or revoke delegates for compressed token accounts |
diff --git a/snippets/overview-tables/examples-guides-table.mdx b/snippets/overview-tables/examples-guides-table.mdx
new file mode 100644
index 00000000..d0d9dbb3
--- /dev/null
+++ b/snippets/overview-tables/examples-guides-table.mdx
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+ |
+ |
+
+
+
+
+ |
+ Client
+ |
+ TypeScript and Rust client examples for light-token SDK |
+
+
+ |
+ Program
+ |
+ Anchor program examples for light-token CPI, Macros and more |
+
+
+
\ No newline at end of file
diff --git a/snippets/overview-tables/light-token-program-examples-table.mdx b/snippets/overview-tables/light-token-program-examples-table.mdx
index 57943e36..6865d378 100644
--- a/snippets/overview-tables/light-token-program-examples-table.mdx
+++ b/snippets/overview-tables/light-token-program-examples-table.mdx
@@ -4,6 +4,8 @@
|---------|-------------|
| [cp-swap-reference](https://github.com/Lightprotocol/cp-swap-reference) | Fork of Raydium AMM that creates markets without paying rent-exemption |
| [create-and-transfer](https://github.com/Lightprotocol/examples-light-token/tree/main/programs/anchor/create-and-transfer) | Create account via macro and transfer via CPI |
+| [pinocchio-swap](https://github.com/Lightprotocol/examples-light-token/tree/main/pinocchio/swap) | Light Token swap reference implementation |
+
### Macros
| | Description |
diff --git a/snippets/overview-tables/program-examples-table.mdx b/snippets/overview-tables/program-examples-table.mdx
index 86761063..e736f453 100644
--- a/snippets/overview-tables/program-examples-table.mdx
+++ b/snippets/overview-tables/program-examples-table.mdx
@@ -1,12 +1,15 @@
| Example | Description |
|:---------|:------------|
+| [Account Comparison](https://github.com/Lightprotocol/program-examples/tree/main/account-comparison) | Compare compressed accounts with standard Solana accounts |
| [basic-operations/anchor](https://github.com/Lightprotocol/program-examples/tree/main/basic-operations/anchor) | Anchor programs to create, update, close, reinitialize and burn compressed accounts with Rust and TypeScript tests |
| [basic-operations/native](https://github.com/Lightprotocol/program-examples/tree/main/basic-operations/native) | Native Solana program implementation to create, update, close, reinitialize and burn compressed accounts with Rust tests |
| [Counter (Anchor)](https://github.com/Lightprotocol/program-examples/tree/main/counter/anchor) | Full compressed account lifecycle (create, increment, decrement, reset, close) using Anchor framework |
| [Counter (Native)](https://github.com/Lightprotocol/program-examples/tree/main/counter/native) | Native Solana program implementation with Rust tests |
| [Counter (Pinocchio)](https://github.com/Lightprotocol/program-examples/tree/main/counter/pinocchio) | Pinocchio implementation using light-sdk-pinocchio with Rust tests |
| [Create-and-Update](https://github.com/Lightprotocol/program-examples/tree/main/create-and-update) | Create new compressed accounts and update existing ones within a single instruction and one validity proof |
+| [merkle-distributor](https://github.com/Lightprotocol/distributor) | SPL token distribution with compressed PDAs for claim tracking, vesting, and clawback |
+| [Nullifier Program](https://github.com/Lightprotocol/nullifier-program) | System for payments, AI agents and more to prevent your onchain instruction from being executed more than once |
| [Read-Only](https://github.com/Lightprotocol/program-examples/tree/main/read-only) | Create compressed accounts and read them on-chain |
-| [Account Comparison](https://github.com/Lightprotocol/program-examples/tree/main/account-comparison) | Compare compressed accounts with standard Solana accounts |
-| [Nullifier Program](https://github.com/Lightprotocol/nullifier-program) | For some use cases, such as sending payments, you might want to prevent your onchain instruction from being executed more than once. Creates a rent-free PDA derived from an id. If the id has been used before, the PDA already exists, causing the instruction to fail |
-| [ZK-ID](https://github.com/Lightprotocol/program-examples/tree/main/zk-id) | Program that uses zero-knowledge proofs for identity verification with compressed accounts |
+| [simple-claim](https://github.com/Lightprotocol/program-examples-airdrop-implementations/tree/main/simple-claim) | Distributes compressed tokens that decompress to SPL on claim |
+| [ZK-ID](https://github.com/Lightprotocol/program-examples/tree/main/zk-id) | Zero-knowledge proofs for identity verification with compressed accounts |
+| [ZK-Nullifier](https://github.com/Lightprotocol/program-examples/tree/main/zk-nullifier) | Implementation of nullifiers for zk programs on Solana to prevent double spending |
diff --git a/snippets/overview-tables/sdk-reference-compressed-pdas.mdx b/snippets/overview-tables/sdk-reference-compressed-pdas.mdx
new file mode 100644
index 00000000..99739874
--- /dev/null
+++ b/snippets/overview-tables/sdk-reference-compressed-pdas.mdx
@@ -0,0 +1,32 @@
+### Client
+
+
+
+ TypeScript RPC client for compressed accounts, validity proofs, and address derivation.
+
+
+ Rust RPC client and indexer for compressed accounts.
+
+
+
+### Program
+
+
+
+ Core SDK for compressed accounts in Anchor programs.
+
+
+ Procedural macros for LightAccount derivation.
+
+
+ Local testing framework for programs.
+
+
diff --git a/snippets/overview-tables/sdk-reference.mdx b/snippets/overview-tables/sdk-reference.mdx
new file mode 100644
index 00000000..09d94598
--- /dev/null
+++ b/snippets/overview-tables/sdk-reference.mdx
@@ -0,0 +1,45 @@
+### Client
+
+
+
+ TypeScript RPC client for Light Token and Compressed Accounts.
+
+
+ Rust RPC client for Light Token and ZK Compression.
+
+
+ TypeScript token operations for Light Token and Compressed Tokens.
+
+
+ Rust token operations for Light Token.
+
+
+
+### Program
+
+
+
+ Core SDK for on-chain programs.
+
+
+ Procedural macros for Light accounts.
+
+
+ CPI instructions for Light Token program.
+
+
+ Local testing framework for programs.
+
+
diff --git a/snippets/setup/compressed-tokens-mint-prereq.mdx b/snippets/setup/compressed-tokens-mint-prereq.mdx
index a45998ff..b7d3ccea 100644
--- a/snippets/setup/compressed-tokens-mint-prereq.mdx
+++ b/snippets/setup/compressed-tokens-mint-prereq.mdx
@@ -1,5 +1,5 @@
Make sure the SPL mint has a token pool for compression.
The script creates this token pool for you.
-For development, you can create a new mint with token pool via [`createMint()`](/compressed-tokens/guides/create-mint-with-token-pool) or add a token pool to an existing mint via [`createTokenPool()`](/compressed-tokens/guides/add-token-pools-to-mint-accounts).
+For development, you can create a new mint with token pool via [`createMint()`](https://github.com/Lightprotocol/examples-zk-compression/tree/main/compressed-token-cookbook) or add a token pool to an existing mint via [`createTokenPool()`](https://github.com/Lightprotocol/examples-zk-compression/tree/main/compressed-token-cookbook).
diff --git a/snippets/versions/rust-native-token.mdx b/snippets/versions/rust-native-token.mdx
new file mode 100644
index 00000000..e77600fa
--- /dev/null
+++ b/snippets/versions/rust-native-token.mdx
@@ -0,0 +1,7 @@
+```toml
+[dependencies]
+light-token = "0.4.0"
+light-compressible = "0.4.0"
+light-token-interface = "0.3.0"
+light-compressed-account = "0.9.0"
+```
diff --git a/snippets/versions/rust-sdk-macros.mdx b/snippets/versions/rust-sdk-macros.mdx
new file mode 100644
index 00000000..cd5fc463
--- /dev/null
+++ b/snippets/versions/rust-sdk-macros.mdx
@@ -0,0 +1,5 @@
+```toml
+[dependencies]
+light-sdk = { version = "0.19.0", features = ["anchor", "v2", "cpi-context"] }
+light-sdk-macros = "0.19.0"
+```
diff --git a/snippets/versions/rust-sdk.mdx b/snippets/versions/rust-sdk.mdx
new file mode 100644
index 00000000..110d90ab
--- /dev/null
+++ b/snippets/versions/rust-sdk.mdx
@@ -0,0 +1,4 @@
+```toml
+[dependencies]
+light-sdk = "0.19.0"
+```
diff --git a/snippets/versions/rust-test.mdx b/snippets/versions/rust-test.mdx
new file mode 100644
index 00000000..ab8e5c69
--- /dev/null
+++ b/snippets/versions/rust-test.mdx
@@ -0,0 +1,5 @@
+```toml
+[dev-dependencies]
+light-program-test = { version = "0.19.0", features = ["v2"] }
+light-client = { version = "0.19.0", features = ["v2"] }
+```
diff --git a/snippets/versions/rust-token-defi.mdx b/snippets/versions/rust-token-defi.mdx
new file mode 100644
index 00000000..dbaa0a59
--- /dev/null
+++ b/snippets/versions/rust-token-defi.mdx
@@ -0,0 +1,6 @@
+```toml
+[dependencies]
+light-sdk = { version = "0.19.0", features = ["anchor", "v2", "cpi-context"] }
+light-sdk-macros = "0.19.0"
+light-token = { version = "0.4.0", features = ["anchor"] }
+```
diff --git a/snippets/versions/rust-token.mdx b/snippets/versions/rust-token.mdx
new file mode 100644
index 00000000..e51ec9cc
--- /dev/null
+++ b/snippets/versions/rust-token.mdx
@@ -0,0 +1,5 @@
+```toml
+[dependencies]
+light-sdk = "0.19.0"
+light-token = "0.4.0"
+```
diff --git a/style.css b/style.css
index 642acdf1..d89567fc 100644
--- a/style.css
+++ b/style.css
@@ -219,3 +219,49 @@ html.dark .hero-title {
font-size: 3rem;
}
}
+
+/* Partner logos inside hero pill */
+.partner-logos {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 24px;
+ margin-top: 8px;
+ pointer-events: none;
+}
+
+.partner-logos img {
+ height: 24px;
+ width: auto;
+}
+
+.partner-divider {
+ color: #9ca3af;
+ font-size: 12px;
+}
+
+/* Light wordmark is white SVG - invert for light mode */
+.light-wordmark {
+ filter: invert(1);
+}
+
+html.dark .light-wordmark {
+ filter: none;
+}
+
+/* Helius logo switching */
+.logo-dark {
+ display: none;
+}
+
+html.dark .logo-light {
+ display: none;
+}
+
+html.dark .logo-dark {
+ display: block;
+}
+
+html.dark .partner-divider {
+ color: #6b7280;
+}
diff --git a/support.mdx b/support.mdx
index a2dc3cf0..d40ffb06 100644
--- a/support.mdx
+++ b/support.mdx
@@ -45,7 +45,7 @@ Install our MCP server for advanced AI assistance.
title="AI Tools Guide"
icon="chevron-right"
color="#0066ff"
- href="/learn/ai-tools-guide#MCP"
+ href="/ai-tools/guide#mcp"
horizontal
>
diff --git a/welcome.mdx b/welcome.mdx
index 16f17ef4..b68b8adb 100644
--- a/welcome.mdx
+++ b/welcome.mdx
@@ -9,51 +9,6 @@ import WelcomePageInstall from "/snippets/setup/welcome-page-install.mdx";

-| **Creation Cost** | Solana | ZK Compression |
-| :---------------- | :------------------ | :------------------- |
-| **Token Account** | ~2,000,000 lamports | ~**5,000** lamports |
-| **100-byte PDA** | ~1,600,000 lamports | ~**15,000** lamports |
-
-## Features
-
-
- High performance token standard for rent-free DeFi and Payments.
-
-
-
-
-
- For App State.
-
-
- For Token Distribution.
-
-
-
-## Quickstart
-
-
-
-
-
-
-
-
-
-
## What is ZK Compression?
ZK Compression is a framework that reduces the storage cost of Solana accounts by combining generalized state compression and
zero-knowledge proofs.
@@ -68,57 +23,4 @@ ZK Compression is a framework that reduces the storage cost of Solana accounts b
the compressed accounts. By default, this is all done under the hood. You can fetch validity
proofs from RPC providers that support ZK Compression.
-
-
-## Resources
-
-
-
- Browse ZK Compression's JSON RPC methods.
-
-
- Explore our TypeScript and Rust SDKs.
-
-
- Install the ZK Compression CLI for local development.
-
-
-
-## Learn & Community
-
-
-
- Learn about ZK Compression's core concepts.
-
-
- Read our external audit and formal verification reports.
-
-
- Join our Discord for support and discussions.
-
-
-
-## Next Steps
-
-
+
\ No newline at end of file
diff --git a/zk/overview.mdx b/zk/overview.mdx
index c56e4714..781e76dd 100644
--- a/zk/overview.mdx
+++ b/zk/overview.mdx
@@ -16,11 +16,11 @@ Building a ZK Solana program requires:
4. An indexer to serve Merkle proofs
5. Encrypted state
-## Nullifiers on Solana
+## Nullifiers for ZK on Solana
A nullifier is a deterministically derived hash to ensure an action can only be performed once.
The nullifier cannot be linked to the action or user.
-For example Zcash uses nullifiers to prevent double spending.
+For example Zcash uses nullifiers to prevent double spending.
To implement nullifiers we need a data structure that ensures every nullifier is only created once and never deleted.
On Solana a straight forward way to implement nullifiers is to create a PDA account with the nullifier as seed.