Skip to content
Launch App >

Documentation for account structures in the zklsol program.

Global program configuration.

Seeds: ["Settings"]

interface Settings {
authority: PublicKey; // Program authority
feeCollector: PublicKey; // Fee collector address
depositFeeBps: number; // Deposit fee in basis points
withdrawFeeBps: number; // Withdrawal fee in basis points
isPaused: boolean; // Emergency pause flag
version: number; // Settings version
}

State for a Merkle tree (one per token/depth combination).

Seeds: ["Merkle", mint, depth]

interface MerkleState {
mint: PublicKey; // Token mint
depth: number; // Tree depth (32)
nextIndex: number; // Next leaf index
root: number[]; // Current root hash (32 bytes)
depositSize: BN; // Fixed deposit size
depositFeeBps: number; // Deposit fee
withdrawFeeBps: number; // Withdrawal fee
status: MerkleStatus; // Active/Paused/Closed
}
enum MerkleStatus {
Active = 0,
Paused = 1,
Closed = 2,
}

Pre-computed zero values for empty tree nodes.

Seeds: ["MerkleZeros", mint, depth]

interface MerkleZeros {
mint: PublicKey;
depth: number;
zeros: number[][]; // Array of 32 zero hashes (32 bytes each)
}

Individual node in the Merkle tree.

Seeds: ["MerkleNode", mint, depth, index]

interface MerkleNode {
mint: PublicKey;
depth: number;
index: BN; // Node index in tree
value: number[]; // Node hash (32 bytes)
}

Record of a spent nullifier (prevents double-spending).

Seeds: ["NullifierHash", mint, depth, nullifier_hash_bytes]

interface NullifierHash {
mint: PublicKey;
depth: number;
nullifierHash: number[]; // 32 bytes
spentAt: BN; // Slot when spent
}

Affiliate registration and earnings tracking.

Seeds: ["Affiliate", affiliate_code]

interface Affiliate {
owner: PublicKey; // Affiliate wallet
affiliateCode: number[]; // Unique identifier
feeShareBps: number; // Share of fees (basis points)
totalEarnings: BN; // Lifetime earnings
pendingWithdraw: BN; // Available to withdraw
createdAt: BN; // Creation timestamp
}

Protocol fee collection.

Seeds: ["FeeCollector"]

interface FeeCollector {
authority: PublicKey; // Can withdraw fees
totalCollected: BN; // Lifetime fees collected
}

Reference to user’s Address Lookup Table.

Seeds: ["UserAddressLookupTable", user]

interface UserAddressLookupTable {
owner: PublicKey; // User wallet
addressLookupTable: PublicKey; // Actual LUT address
createdAt: BN; // Creation timestamp
isActive: boolean; // Whether LUT is active
}

Temporary buffer for multi-step swap operations.

Seeds: ["WithdrawStepBuffer", user, nonce]

interface WithdrawStepBuffer {
owner: PublicKey;
inputMint: PublicKey;
outputMint: PublicKey;
inputAmount: BN;
minOutputAmount: BN;
recipient: PublicKey;
status: SwapStatus;
}

Helper functions for deriving account addresses:

import { PublicKey } from '@solana/web3.js';
const PROGRAM_ID = new PublicKey('FGKoWNsvTTDCGW9JyR2DJWNzSXpejWk7yXcKsFFj9GQp');
// Settings
function getSettings(): PublicKey {
const [pda] = PublicKey.findProgramAddressSync(
[Buffer.from('Settings')],
PROGRAM_ID
);
return pda;
}
// Merkle tree
function getMerkle(mint: PublicKey, depth: number): PublicKey {
const [pda] = PublicKey.findProgramAddressSync(
[Buffer.from('Merkle'), mint.toBuffer(), Buffer.from([depth])],
PROGRAM_ID
);
return pda;
}
// Nullifier hash
function getNullifierHash(
mint: PublicKey,
depth: number,
nullifierHash: Uint8Array
): PublicKey {
const [pda] = PublicKey.findProgramAddressSync(
[
Buffer.from('NullifierHash'),
mint.toBuffer(),
Buffer.from([depth]),
nullifierHash,
],
PROGRAM_ID
);
return pda;
}
// Affiliate
function getAffiliate(affiliateCode: Uint8Array): PublicKey {
const [pda] = PublicKey.findProgramAddressSync(
[Buffer.from('Affiliate'), affiliateCode],
PROGRAM_ID
);
return pda;
}
// User LUT
function getUserLut(user: PublicKey): PublicKey {
const [pda] = PublicKey.findProgramAddressSync(
[Buffer.from('UserAddressLookupTable'), user.toBuffer()],
PROGRAM_ID
);
return pda;
}