Overview
Photon is the official ZK Compression indexer for Light Protocol, maintained by Helius Labs. It provides fast, efficient querying of compressed accounts and state on Solana.Photon Repository
Official Photon indexer source code and documentation
What is Photon?
Photon is a specialized indexer that:- Indexes compressed accounts stored in Merkle trees
- Provides RPC endpoints for querying compressed state
- Generates validity proofs required for transactions
- Tracks Merkle tree state including roots and leaf indices
- Supports both V1 and V2 protocol versions
Key Features
Fast Queries
Photon indexes all compressed accounts and provides efficient query endpoints:- Query by owner
- Query by address
- Filter by mint (for compressed tokens)
- Pagination support
Validity Proofs
Photon generates the validity proofs needed to create transactions that interact with compressed accounts:Merkle Tree State
Photon tracks the current state of all Merkle trees:- Current root
- Root history (for validity proofs)
- Next available index
- Tree capacity and rollover status
Using Photon
With Light Client
Thelight-client Rust library provides a high-level interface to Photon:
Endpoints
Local Development
Local Development
When running a local test validator with Light Protocol:Start with Light CLI:
Devnet
Devnet
Helius provides hosted Photon for devnet:
Mainnet
Mainnet
Helius provides hosted Photon for mainnet:
API Methods
Query Methods
Get all compressed accounts owned by a public keyParameters:
owner: Public key of the account ownercursor: Optional pagination cursorlimit: Optional result limit
Get a specific compressed account by hashParameters:
hash: 32-byte account hash
Get compressed token accounts filtered by owner and optional mintParameters:
owner: Public key of the token account ownermint: Optional mint public key to filter bycursor: Optional pagination cursorlimit: Optional result limit
Proof Methods
Generate validity proof for transaction creationParameters:
hashes: Array of compressed account hashes to prove inclusionnewAddresses: Array of addresses for new compressed accounts
- Compressed proof (Groth16 ZK proof)
- Merkle tree roots
- Leaf indices
- Address tree roots (for new addresses)
Indexer Status
Check indexer health and sync statusReturns:
- Current slot
- Sync status
- Version information
Architecture
Photon works alongside the Light Protocol on-chain programs:Local Development
Using Light CLI
The easiest way to run Photon locally:- Solana test validator
- Light Protocol programs
- Photon indexer (port 8784)
- Prover service
With Rust Test Code
Configuration
Environment Variables
When running your own Photon instance:PostgreSQL connection string for state storage
Solana RPC endpoint to index from
Solana WebSocket endpoint for real-time updates
Address and port for Photon RPC server (default:
0.0.0.0:8784)Best Practices
Always Use Indexed Data for UI
Always Use Indexed Data for UI
Query Photon for displaying compressed accounts in your UI. Don’t try to reconstruct state from on-chain Merkle trees directly.
Cache Validity Proofs
Cache Validity Proofs
Validity proofs are tied to specific Merkle roots. Cache them for the current slot to avoid repeated queries.
Handle Tree Rollovers
Handle Tree Rollovers
When a Merkle tree reaches capacity, it rolls over to a new tree. Photon handles this automatically, but your code should handle the rollover event.
Monitor Indexer Health
Monitor Indexer Health
Periodically check
getIndexerHealth to ensure Photon is synced with the latest slot.Resources
Photon GitHub
Official repository and documentation
Light Client API
Rust client library documentation
Helius RPC
Get API keys for hosted Photon
Light Protocol Docs
Complete protocol documentation
Troubleshooting
Indexer Not Syncing
Indexer Not Syncing
Problem: Photon is not returning recent compressed accounts.Solution:
- Check
getIndexerHealthto see current slot - Verify Solana RPC connection
- Check database connectivity
- Review Photon logs for errors
Validity Proof Failures
Validity Proof Failures
Problem: Transactions fail with “Invalid proof” errors.Solution:
- Ensure proof is for correct Merkle root
- Check that compressed accounts haven’t been spent
- Verify tree hasn’t rolled over since proof generation
- Use fresh validity proofs (don’t cache across slots)
Missing Accounts
Missing Accounts
Problem: Compressed accounts not appearing in queries.Solution:
- Wait for indexer to sync (check slot)
- Verify transaction confirmed on-chain
- Check query parameters (owner, mint, cursor)
- Confirm account wasn’t already spent/nullified