Cost Efficiency
ZEclipse is engineered to provide strong privacy without destroying Solana’s cost advantages.
This page summarizes the efficiency design from docs/TECHNICAL_DOCUMENTATION.md and the DApp connector docs.
Goals
- Maximize the percentage of funds that reach the recipient (“efficiency”).
- Minimize rent and compute overhead.
- Support multi-recipient and batched transfers without linear cost blowup.
In benchmarks from the technical documentation:
- Efficiency ≈ 98% vs 92% baseline.
- Rent costs reduced by ~70%.
- Total cost reduced by ~43.4%.
Optimized Account Management
Problem:
- Naive designs create and keep many temporary accounts, paying rent that is never reclaimed.
Solution:
- Use deterministic Program Derived Addresses (PDAs) for transfer state.
- Reuse accounts where safe, and close them immediately after use.
- Reclaim rent back to the user on finalization.
Conceptually (TypeScript side):
// In the client / SDK finalize call
const finalizeIx = await program.methods
.finalizeTransfer(finalProof)
.accounts({
authority: wallet.publicKey,
transferState: transferStatePda,
recipient,
systemProgram: web3.SystemProgram.programId,
})
.instruction()
// Finalization closes the state account and returns rent
await sendAndConfirmTransaction([finalizeIx])
Multi-Recipient Transfers
ZEclipse encourages using 3–6 recipient wallets for privacy, but still keeps costs under control:
- Multiple recipients are stored in a single
TransferStateaccount. - Proofs and compute-heavy work are shared across recipients.
On-chain (simplified Rust structure from the docs):
pub struct TransferState {
pub recipients: [Pubkey; 6], // up to 6 recipients
pub recipient_count: u8,
// ...
}
This allows:
- One state account per transfer.
- One set of proofs and heavy computation.
- Controlled incremental cost per extra recipient.
Compute Unit Optimization
Problem:
- Over-allocating compute units wastes lamports; under-allocating leads to failures.
Solution:
- Measure and set an optimal compute unit limit based on transfer shape.
Example pattern from the SDK:
const modifyComputeUnits = ComputeBudgetProgram.setComputeUnitLimit({
units: calculateOptimalComputeUnits(recipientCount),
})
transaction.add(modifyComputeUnits)
Where calculateOptimalComputeUnits uses:
- A base compute budget for ZK verification.
- A small linear increment per additional recipient.
Efficiency Metrics in the SDK
The DApp connector exposes efficiency calculations for UI and monitoring:
const efficiency = connector.calculateTransferEfficiency(
1_500_000_000, // amount in lamports
2, // number of recipients
)
console.log(`Transfer efficiency: ${efficiency.efficiency}%`)
console.log(`Cost breakdown: ${JSON.stringify(efficiency.costBreakdown)}`)
Typical cost breakdown from the docs:
| Component | Baseline | Optimized | Savings |
|---|---|---|---|
| TX Fee | 5,500 | 5,250 | 4.5% |
| Rent | 890,880 | 267,264 | 70.0% |
| Compute | 220,000 | 200,000 | 9.1% |
| Total | 1,116,380 | 472,514 | 43.4% |
Values are in lamports and will vary with network conditions and configuration.
Design Tradeoffs
- Slightly more complexity in client and program logic.
- Significant cost savings for users, especially with:
- Multi-recipient transfers.
- Frequent use (batch workloads, dApps with many users).
For a deeper dive, see:
docs/TECHNICAL_DOCUMENTATION.md(Cost Efficiency Optimizations section).- The
cost-efficiency.tsandterminal-dashboard.tsmodules inapp/src/efficiency.