logoCheckmate
Program

Accounts

Program account structures and their usage

PlatformConfig

The global platform configuration account that stores system-wide settings.

Structure

#[account]
#[derive(InitSpace, Debug)]
pub struct PlatformConfig {
    pub fee_basis_points: u16, // 500 = 5%
    pub authority: Pubkey,
    pub fee_vault: Pubkey,
    pub bump: u8,
}

Fields

FieldTypeDescription
fee_basis_pointsu16Platform fee in basis points (500 = 5%)
authorityPubkeyPlatform authority with admin privileges
fee_vaultPubkeyVault account for collecting platform fees
bumpu8PDA bump seed

PDA Derivation

const [platformConfig] = PublicKey.findProgramAddressSync(
  [Buffer.from("platform_config")],
  PROGRAM_ID
);

Methods

calculate_fee(amount: u64) -> u64

Calculates the platform fee for a given amount.

pub fn calculate_fee(&self, amount: u64) -> u64 {
    (amount * self.fee_basis_points as u64) / 10000
}

IntegratorConfig

Configuration account for each integrator (third-party platform) using the chess program.

Structure

#[account]
#[derive(InitSpace)]
pub struct IntegratorConfig {
    pub integrator_id: Pubkey,
    pub integrator: Pubkey,
    pub fee_basis_points: u16, // 500 = 5%
    pub fee_vault: Pubkey,
    pub total_games_created: u64,
    pub active_games_count: u32,
    pub total_volume: u64,
    pub platform_fees_collected: u64,
    pub next_game_id: u64,
    pub bump: u8,
}

Fields

FieldTypeDescription
integrator_idPubkeyUnique identifier for the integrator
integratorPubkeyIntegrator's authority public key
fee_basis_pointsu16Integrator fee in basis points
fee_vaultPubkeyVault for collecting integrator fees
total_games_createdu64Total number of games created
active_games_countu32Current number of active games
total_volumeu64Total volume processed in lamports
platform_fees_collectedu64Total platform fees collected
next_game_idu64Next available game ID
bumpu8PDA bump seed

PDA Derivation

const [integratorConfig] = PublicKey.findProgramAddressSync(
  [Buffer.from("integrator_config"), integratorId.toBuffer()],
  PROGRAM_ID
);

GameAccount

The main account storing individual chess game state and metadata.

Structure

#[account]
#[derive(InitSpace)]
pub struct GameAccount {
    pub game_id: u64,
    pub integrator_id: Pubkey,
    pub white_player: Pubkey,
    pub black_player: Option<Pubkey>,
    pub game_status: GameStatus,
    pub current_turn: PlayerColor,
    pub board_state: [[Option<(PieceType, PlayerColor)>; 8]; 8],
    pub move_count: u16,
    pub halfmove_clock: u8,
    pub castling_rights: CastlingRights,
    pub en_passant_target: Option<(u8, u8)>,
    pub last_move: Option<LastMove>,
    pub game_result: Option<GameResult>,
    pub entry_fee: u64,
    pub prize_pool: u64,
    pub time_control: Option<TimeControl>,
    pub white_time_remaining: Option<i64>,
    pub black_time_remaining: Option<i64>,
    pub last_move_time: Option<i64>,
    pub created_at: i64,
    pub finished_at: Option<i64>,
    pub winner: Option<PlayerColor>,
    pub rating_change: Option<RatingChange>,
    pub bump: u8,
}

Key Fields

FieldTypeDescription
game_idu64Unique game identifier
integrator_idPubkeyAssociated integrator
white_playerPubkeyWhite player's public key
black_playerOption<Pubkey>Black player's public key (None if waiting)
game_statusGameStatusCurrent game status
current_turnPlayerColorWhose turn it is
board_state[[Option<(PieceType, PlayerColor)>; 8]; 8]8x8 board representation
move_countu16Number of moves played
halfmove_clocku8Moves since last capture/pawn move
entry_feeu64Entry fee in lamports
prize_poolu64Total prize pool
time_controlOption<TimeControl>Time control settings

PDA Derivation

const [gameAccount] = PublicKey.findProgramAddressSync(
  [
    Buffer.from("game"),
    integratorId.toBuffer(),
    new BN(gameId).toArrayLike(Buffer, "le", 8),
  ],
  PROGRAM_ID
);

Enums and Supporting Types

GameStatus

#[derive(AnchorSerialize, AnchorDeserialize, Clone, PartialEq, Eq, Debug)]
pub enum GameStatus {
    WaitingForPlayer,
    InProgress,
    Finished,
    Cancelled,
}

PlayerColor

#[derive(AnchorSerialize, AnchorDeserialize, Clone, Copy, PartialEq, Eq, Debug)]
pub enum PlayerColor {
    White,
    Black,
}

PieceType

#[derive(AnchorSerialize, AnchorDeserialize, Clone, Copy, PartialEq, Eq, Debug)]
pub enum PieceType {
    Pawn,
    Rook,
    Knight,
    Bishop,
    Queen,
    King,
}

GameResult

#[derive(AnchorSerialize, AnchorDeserialize, Clone, PartialEq, Eq, Debug)]
pub enum GameResult {
    Checkmate,
    Stalemate,
    Resignation,
    Timeout,
    Draw,
    Abandoned,
}

TimeControl

#[derive(AnchorSerialize, AnchorDeserialize, Clone, Debug, PartialEq, Eq)]
pub struct TimeControl {
    pub initial_time: u32,    // seconds
    pub increment: u32,       // seconds per move
    pub time_limit: u32,      // maximum time in seconds
}

CastlingRights

#[derive(AnchorSerialize, AnchorDeserialize, Clone, Debug, PartialEq, Eq)]
pub struct CastlingRights {
    pub white_kingside: bool,
    pub white_queenside: bool,
    pub black_kingside: bool,
    pub black_queenside: bool,
}

Account Size Calculations

All accounts use the InitSpace derive macro for automatic space calculation:

  • PlatformConfig: ~50 bytes
  • IntegratorConfig: ~100 bytes
  • GameAccount: ~1,000+ bytes (due to board state)

Security Considerations

Access Control

  • PlatformConfig: Only platform authority can modify
  • IntegratorConfig: Only integrator authority can modify
  • GameAccount: Players can only modify through valid game instructions

Data Validation

  • All moves are validated against chess rules
  • Time controls are enforced
  • Entry fees and prize pools are protected
  • Board state integrity is maintained

PDA Security

  • All accounts use deterministic PDA derivation
  • Bump seeds prevent address collision attacks
  • Seeds include relevant identifiers for uniqueness

Usage Examples

Reading Game State

const gameAccount = await program.account.gameAccount.fetch(gameAccountPda);
console.log("Current turn:", gameAccount.currentTurn);
console.log("Move count:", gameAccount.moveCount);
console.log("Game status:", gameAccount.gameStatus);

Monitoring Integrator Stats

const integratorConfig = await program.account.integratorConfig.fetch(
  integratorConfigPda
);
console.log("Total games:", integratorConfig.totalGamesCreated);
console.log("Active games:", integratorConfig.activeGamesCount);
console.log("Total volume:", integratorConfig.totalVolume);