From 3ab40ccd7b848e7cedb000f88a863eb639f44451 Mon Sep 17 00:00:00 2001 From: rhiza Date: Mon, 5 Feb 2024 01:31:52 -0600 Subject: [PATCH] latest contract --- anchor/programs/squares/src/lib.rs | 519 +++++++++-------------------- anchor/target/types/squares.ts | 4 +- 2 files changed, 167 insertions(+), 356 deletions(-) diff --git a/anchor/programs/squares/src/lib.rs b/anchor/programs/squares/src/lib.rs index 32014d8..8416e4a 100644 --- a/anchor/programs/squares/src/lib.rs +++ b/anchor/programs/squares/src/lib.rs @@ -1,480 +1,291 @@ -se anchor_lang::prelude::*; - -use solana_program::pubkey; -use solana_program::{program::invoke, system_instruction}; +use anchor_lang::prelude::*; +use anchor_lang::solana_program::clock::Clock; +use anchor_lang::solana_program::program::invoke; +use anchor_lang::solana_program::pubkey; +use anchor_lang::solana_program::system_instruction; declare_id!("8B9VcQmn65FYQmWjEvmyEL2D2CiMr2oacoaQstmVuXWV"); -const FEE_RECEIVER_ACCOUNT: &str = "8eTKgcgBERz1MGiQALfZjkuAY6Fz79UtziNsqptPkHEd"; -const ADMIN_PUBKEY: &Pubkey = &pubkey!("3iGJM28vywNTUt5hZgHjri5LEzeRBevE75EbGY7wakJA"); - #[program] pub mod football_squares { use super::*; - pub fn create_game(ctx: Context, cost_per_square: u64) -> Result<()> { - let game = &mut ctx.accounts.game; - game.owner = *ctx.accounts.user.key; - game.cost_per_square = cost_per_square; - game.game_status = GameStatus::Open; - game.squares = vec![ - Square { + pub fn create_game_board(ctx: Context, cost_per_square: u64) -> Result<()> { + let board = &mut ctx.accounts.board; + board.creator = *ctx.accounts.creator.key; + board.cost_per_square = cost_per_square; + board.status = GameBoardStatus::Open; + board.squares = vec![ + GameBoardSquare { owner: None, home_team_index: 0, away_team_index: 0 }; 100 - ]; // Assuming a 10x10 grid - + ]; Ok(()) } pub fn purchase_square(ctx: Context, square_indices: Vec) -> Result<()> { - let game = &mut ctx.accounts.game; - require!(game.game_status == GameStatus::Open, ErrorCode::GameClosed); + let board = &mut ctx.accounts.board; + require!( + board.status == GameBoardStatus::Open, + ErrorCode::GameBoardClosed + ); - let total_cost = calculate_total_cost(game.cost_per_square, square_indices.len()); - let fee = calculate_fee(total_cost, 6.9); - let amount_to_game = total_cost + fee; + let total_cost = board.cost_per_square * square_indices.len() as u64; + let fee = (total_cost as f64 * 0.069).round() as u64; // TODO + let amount_to_user = total_cost + fee; for &square_index in &square_indices { require!(square_index < 100, ErrorCode::InvalidSquareIndex); - let square = &mut game.squares[square_index as usize]; + let square = &mut board.squares[square_index as usize]; require!(square.owner.is_none(), ErrorCode::SquareAlreadyPurchased); - square.owner = Some(*ctx.accounts.user.key); + square.owner = Some(*ctx.accounts.owner.key); } let game_transfer_instruction = system_instruction::transfer( - &ctx.accounts.user.key(), - &ctx.accounts.game.key(), - amount_to_game, + &ctx.accounts.owner.key(), + &ctx.accounts.board.key(), + amount_to_user, ); invoke( &game_transfer_instruction, &[ - ctx.accounts.user.to_account_info(), - ctx.accounts.game.to_account_info(), + ctx.accounts.owner.to_account_info(), + ctx.accounts.board.to_account_info(), ctx.accounts.system_program.to_account_info(), ], )?; - // let fee_receiver_pubkey = FEE_RECEIVER_ACCOUNT.parse::().unwrap(); - - // let fee_transfer_instruction = - // system_instruction::transfer(&ctx.accounts.user.key(), &fee_receiver_pubkey, fee); - // invoke( - // &fee_transfer_instruction, - // &[ - // ctx.accounts.user.to_account_info(), - // ctx.accounts.system_program.to_account_info(), - // ], - // )?; - Ok(()) } - pub fn finalize_game(ctx: Context) -> Result<()> { - let game = &mut ctx.accounts.game; - let user = &ctx.accounts.user; + pub fn finalize_board(ctx: Context) -> Result<()> { + let board = &mut ctx.accounts.board; - require!(game.game_status == GameStatus::Open, ErrorCode::GameNotOpen); require!( - game.squares.iter().all(|s| s.owner.is_some()), + board.status == GameBoardStatus::Open, + ErrorCode::NotAllSquaresPurchased + ); + require!( + board.squares.iter().all(|s| s.owner.is_some()), ErrorCode::NotAllSquaresPurchased ); - require!(game.owner == user.key(), ErrorCode::Unauthorized); - - // Use the current slot as the seed for randomness - let slot = Clock::get()?.slot; - - // Generate and shuffle indices for the home and away teams - let mut home_indices: Vec = (0..10).collect(); - let mut away_indices: Vec = (0..10).collect(); - shuffle(&mut home_indices, slot); - shuffle(&mut away_indices, slot + 1); - - // Assign the shuffled indices to the game - game.home_team_indices = home_indices; - game.away_team_indices = away_indices; - - let home_team_indices = game.home_team_indices.clone(); - let away_team_indices = game.away_team_indices.clone(); - - // Assign shuffled indices to each square - for i in 0..10 { - for j in 0..10 { - let square_index = i * 10 + j; - let square = &mut game.squares[square_index]; - square.home_team_index = home_team_indices[i]; - square.away_team_index = away_team_indices[j]; - } - } - - game.game_status = GameStatus::Finalized; - Ok(()) - } + // Randomization logic + let clock = Clock::get()?; + board.home_team_indices = generate_random_indices(clock.slot); + board.away_team_indices = generate_random_indices(clock.slot + 1); - pub fn initialize_scores(ctx: Context) -> Result<()> { - let scores = &mut ctx.accounts.scores; - // Initialize scores with default values + board.status = GameBoardStatus::Finalized; Ok(()) } - pub fn update_scores( - ctx: Context, - quarter: u8, + pub fn update_event_scores( + ctx: Context, + period: u8, home: u8, away: u8, ) -> Result<()> { require_keys_eq!( - *ADMIN_PUBKEY, *ctx.accounts.admin.key, + *ADMIN_PUBKEY, ErrorCode::Unauthorized ); - let scores = &mut ctx.accounts.scores; - // Update scores based on the quarter - match quarter { - 1 => { - scores.first_quarter_scores = QuarterScores { - home: Some(home), // Wrapping with Some() - away: Some(away), // Wrapping with Some() - } - } - 2 => { - scores.second_quarter_scores = QuarterScores { - home: Some(home), // Wrapping with Some() - away: Some(away), // Wrapping with Some() - } - } - 3 => { - scores.third_quarter_scores = QuarterScores { - home: Some(home), // Wrapping with Some() - away: Some(away), // Wrapping with Some() - } - } - 4 => { - scores.fourth_quarter_scores = QuarterScores { - home: Some(home), // Wrapping with Some() - away: Some(away), // Wrapping with Some() - } - } - 5 => { - scores.final_scores = QuarterScores { - home: Some(home), // Wrapping with Some() - away: Some(away), // Wrapping with Some() - } - } - _ => return Err(ErrorCode::InvalidQuarter.into()), + let score_update = Some((home, away)); + match period { + 1..=4 => scores.period_scores[period as usize - 1] = score_update, + 5 => scores.period_scores[4] = score_update, + _ => return Err(ErrorCode::InvalidPeriod.into()), } Ok(()) } - pub fn calculate_winners(ctx: Context) -> Result<()> { - let game = &mut ctx.accounts.game; + pub fn initialize_event_scores( + ctx: Context, + event_name: String, + home_team_name: String, + away_team_name: String, + ) -> Result<()> { + let scores = &mut ctx.accounts.scores; + scores.event_name = event_name; + scores.home_team_name = home_team_name; + scores.away_team_name = away_team_name; + scores.period_scores = [None; 5]; + Ok(()) + } + + pub fn calculate_game_board_winners(ctx: Context) -> Result<()> { + let board = &mut ctx.accounts.board; let scores = &ctx.accounts.scores; - // Ensure the game is in the correct state to calculate winners - require!(game.game_status == GameStatus::Open, ErrorCode::GameNotOpen); + if scores + .period_scores + .iter() + .filter(|score| score.is_some()) + .count() + > board + .period_winners + .iter() + .filter(|winner| winner.is_some()) + .count() + { + update_period_winners(board, scores); + } - // Update the winners for each quarter based on available scores - if update_quarter_winners(game, scores) { - game.game_status = GameStatus::GameOver; + if board + .period_winners + .iter() + .filter(|winner| winner.is_some()) + .count() + == 5 + { + board.status = GameBoardStatus::GameOver; } Ok(()) } +} - // pub fn distribute_winnings(ctx: Context, quarter: u8) -> Result<()> { - // // Directly access immutable fields before mutable borrow - // let game_balance = ctx.accounts.game.to_account_info().lamports(); - // let game_key = *ctx.accounts.game.to_account_info().key; - - // // Now perform the mutable borrow - // let game = &mut ctx.accounts.game; - - // require!( - // game.game_status == GameStatus::Finalized, - // ErrorCode::GameNotFinalized - // ); - - // // Since we've completed the immutable borrow operations above, we can now proceed with mutable operations - // let payout_per_winner = game_balance / 5; // Example logic - - // let winner_pubkey = determine_quarter_winner(game, quarter)?; - // if let Some(winner_pubkey) = winner_pubkey { - // let transfer_instruction = - // system_instruction::transfer(&game_key, &winner_pubkey, payout_per_winner); - - // invoke( - // &transfer_instruction, - // &[ - // ctx.accounts.game.to_account_info(), - // ctx.accounts.winner.to_account_info(), // Assuming this dynamically determines the winner - // ctx.accounts.system_program.to_account_info(), - // ], - // )?; - - // // Mark the quarter as paid to prevent double payouts - // mark_quarter_paid(game, quarter)?; - // } - - // Ok(()) - // } - - // pub fn check_scores(ctx: Context) -> Result<()> { - // let game = &mut ctx.accounts.game; - // require!( - // game.game_status == GameStatus::Finalized, - // ErrorCode::GameNotFinalized - // ); - - // // Logic to interact with the oracle and fetch the scores - // // Determine the winners based on the fetched scores - // // Distribute the winnings from the escrow account - - // Ok(()) - // } - - // pub fn cancel_game(ctx: Context) -> Result<()> { - // let game = &mut ctx.accounts.game; - // require!( - // game.owner == *ctx.accounts.user.key, - // ErrorCode::NotGameOwner - // ); - // require!( - // game.game_status != GameStatus::Finalized, - // ErrorCode::GameAlreadyFinalized - // ); - - // // Logic to refund the purchases to each user - // // Return the rent to the game owner - // // Update the game status to Closed - - // Ok(()) - // } +#[account] +pub struct GameBoard { + pub creator: Pubkey, + pub cost_per_square: u64, + pub status: GameBoardStatus, + pub squares: Vec, + pub home_team_indices: Vec, + pub away_team_indices: Vec, + pub scores_account: Pubkey, + pub period_winners: [Option; 5], +} +#[derive(AnchorSerialize, AnchorDeserialize, Clone)] +pub struct GameBoardSquare { + pub owner: Option, + pub home_team_index: u8, + pub away_team_index: u8, +} + +#[account] +pub struct EventScores { + pub admin: Pubkey, + pub event_name: String, + pub home_team_name: String, + pub away_team_name: String, + pub period_scores: [Option<(u8, u8)>; 5], } #[derive(Accounts)] -pub struct CreateGame<'info> { - #[account(init, payer = user, space = 3730)] - pub game: Account<'info, Game>, +pub struct CreateGameBoard<'info> { + #[account(init, payer = creator, space = 8 + 5000)] + pub board: Account<'info, GameBoard>, #[account(mut)] - pub user: Signer<'info>, + pub creator: Signer<'info>, pub system_program: Program<'info, System>, } #[derive(Accounts)] pub struct PurchaseSquare<'info> { #[account(mut)] - pub game: Account<'info, Game>, + pub board: Account<'info, GameBoard>, #[account(mut)] - pub user: Signer<'info>, + pub owner: Signer<'info>, pub system_program: Program<'info, System>, } #[derive(Accounts)] -pub struct FinalizeGame<'info> { - #[account(mut)] - pub game: Account<'info, Game>, +pub struct FinalizeBoard<'info> { + #[account(mut, has_one = creator)] + pub board: Account<'info, GameBoard>, #[account(mut)] - pub user: Signer<'info>, + pub creator: Signer<'info>, pub system_program: Program<'info, System>, } #[derive(Accounts)] -pub struct UpdateScores<'info> { - #[account(mut)] - pub scores: Account<'info, Scores>, - pub admin: Signer<'info>, -} - -#[derive(AnchorSerialize, AnchorDeserialize, Clone)] -pub struct QuarterScores { - pub home: Option, // Updated to be nullable - pub away: Option, // Updated to be nullable +pub struct UpdateEventScores<'info> { + #[account(mut, has_one = admin)] + pub scores: Account<'info, EventScores>, + #[account(signer)] + pub admin: AccountInfo<'info>, } #[derive(Accounts)] -pub struct InitializeScores<'info> { - #[account(init, payer = user, space = 8 + 536 + /* Fixed size for other fields */)] - pub scores: Account<'info, Scores>, - #[account(mut)] - pub user: Signer<'info>, +pub struct InitializeEventScores<'info> { + #[account(init, payer = admin, space = 8 + 1024)] + pub scores: Account<'info, EventScores>, + #[account(mut, signer)] + pub admin: Signer<'info>, pub system_program: Program<'info, System>, } -#[account] -pub struct Scores { - pub first_quarter_scores: QuarterScores, - pub second_quarter_scores: QuarterScores, - pub third_quarter_scores: QuarterScores, - pub fourth_quarter_scores: QuarterScores, - pub final_scores: QuarterScores, -} #[derive(Accounts)] -pub struct CalculateWinners<'info> { +pub struct CalculateGameBoardWinners<'info> { + #[account(mut, has_one = creator)] + pub board: Account<'info, GameBoard>, #[account(mut)] - pub game: Account<'info, Game>, - pub scores: Account<'info, Scores>, - // Ensure that only an authorized user or the game owner can calculate winners - pub authority: Signer<'info>, -} - -// #[derive(Accounts)] -// pub struct CheckScores<'info> { -// pub game: Account<'info, Game>, -// // Accounts and constraints for score checking -// } - -// #[derive(Accounts)] -// pub struct CancelGame<'info> { -// #[account(mut)] -// pub game: Account<'info, Game>, -// // Additional accounts and constraints for game cancellation -// } - -#[account] -pub struct Game { - pub owner: Pubkey, - pub cost_per_square: u64, - pub game_status: GameStatus, - pub squares: Vec, - pub home_team_indices: Vec, // Stores shuffled indices for the home team - pub away_team_indices: Vec, // Stores shuffled indices for the away team - pub scores_account: Pubkey, // Reference to the Scores account - pub quarter_winners: [Option; 5], // Winner for each quarter + pub scores: Account<'info, EventScores>, + #[account(mut)] + pub creator: Signer<'info>, } #[derive(PartialEq, Debug, Clone, Copy, AnchorSerialize, AnchorDeserialize)] -pub enum GameStatus { +pub enum GameBoardStatus { Open, Closed, Finalized, GameOver, } -#[derive(AnchorSerialize, AnchorDeserialize, Clone)] -pub struct Square { - pub owner: Option, - pub home_team_index: u8, - pub away_team_index: u8, -} - -// #[derive(Accounts)] -// pub struct DistributeWinnings<'info> { -// #[account(mut)] -// pub game: Account<'info, Game>, -// /// CHECK: Only used for SOL transfer, no need to deserialize account data. -// #[account(mut)] -// pub winner: AccountInfo<'info>, -// pub system_program: Program<'info, System>, -// } - -// Define error codes for the program #[error_code] pub enum ErrorCode { - #[msg("The game is not open for purchases.")] - GameClosed, - #[msg("Invalid square index.")] + GameBoardClosed, InvalidSquareIndex, - #[msg("This square has already been purchased.")] SquareAlreadyPurchased, - #[msg("Only program owner can update scores.")] Unauthorized, - #[msg("Should be a number 1-5, where 5 is final score.")] - InvalidQuarter, - #[msg("Game's not open.")] - GameNotOpen, - #[msg("Can't finalize, not all squares are occupied.")] + InvalidPeriod, + GameBoardNotOpen, NotAllSquaresPurchased, - #[msg("Can't distribute winnings, game not finalized.")] - GameNotFinalized, - QuarterAlreadyPaid, + GameBoardNotFinalized, + PeriodAlreadyPaid, } -fn calculate_total_cost(cost_per_square: u64, num_squares: usize) -> u64 { - cost_per_square * (num_squares as u64) -} +const ADMIN_PUBKEY: &Pubkey = &pubkey!("3iGJM28vywNTUt5hZgHjri5LEzeRBevE75EbGY7wakJA"); -fn calculate_fee(amount: u64, fee_percentage: f64) -> u64 { - (amount as f64 * (fee_percentage / 100.0)).round() as u64 +fn generate_random_indices(seed: u64) -> Vec { + let mut indices: Vec = (0..10).collect(); + let mut rng_seed = seed; + for i in (1..indices.len()).rev() { + rng_seed = xorshift64star(rng_seed); + let j = (rng_seed % (i + 1) as u64) as usize; + indices.swap(i, j); + } + indices } -fn xorshift64star(seed: u64) -> u64 { - let mut x = seed; +fn xorshift64star(mut x: u64) -> u64 { x ^= x << 12; x ^= x >> 25; x ^= x << 27; - x = (x as u128 * 0x2545F4914F6CDD1D) as u64; - x + x.wrapping_mul(0x2545F4914F6CDD1D) } -fn shuffle(numbers: &mut Vec, seed: u64) { - let mut rng_seed = seed; - for i in (1..numbers.len()).rev() { - rng_seed = xorshift64star(rng_seed); // Generate a new random number - let j = (rng_seed % (i + 1) as u64) as usize; // Simple modulo for the index - numbers.swap(i, j); - } -} - -// Placeholder function to calculate winners -// Adapt this function based on your game's logic -fn calculate_winners(game: &Account) -> Vec { - // Implement logic to determine winners based on the game state - // Return a vector of AccountInfo representing the winners - Vec::new() -} - -// Placeholder function to calculate the winning amount for a winner -// Adapt this function based on your game's prize distribution logic -fn calculate_winning_amount(game: &Account, winner: &AccountInfo) -> u64 { - // Implement logic to calculate the amount of winnings for a given winner - 0 -} +fn update_period_winners(board: &mut Account, scores: &Account) { + for (period_index, score_option) in scores.period_scores.iter().enumerate() { + if let Some((home, away)) = score_option { + let home_mod = home % 10; + let away_mod = away % 10; -fn update_quarter_winners(game: &mut Account, scores: &Account) -> bool { - // Iterate through each quarter's scores and update the game's quarter winners accordingly - let quarters_scores = [ - scores.first_quarter_scores, - scores.second_quarter_scores, - scores.third_quarter_scores, - scores.fourth_quarter_scores, - scores.final_scores, // Assuming this is how you represent the final scores - ]; - - for (quarter_index, quarter_scores) in quarters_scores.iter().enumerate() { - // Check if both home and away scores are available for this quarter - if let Some(quarter_scores) = quarter_scores { - // Calculate the mod 10 of home and away scores to determine the winning square - let home_mod = quarter_scores.home.unwrap_or(0) % 10; - let away_mod = quarter_scores.away.unwrap_or(0) % 10; - - // Find the owner of the square that matches the winning condition - let mut found_winner = false; - for square in &game.squares { + for square in &board.squares { if square.home_team_index == home_mod && square.away_team_index == away_mod { - // Update the winner for this quarter - game.quarter_winners[quarter_index] = square.owner; - found_winner = true; - break; // Assuming only one winner per quarter + board.period_winners[period_index] = square.owner; + break; } } - - // If no winner is found for a square, it means the scores were not set for this quarter - if !found_winner { - break; // Stop processing further quarters if no scores are available for the current one - } - } else { - // No scores available for this quarter, stop processing further - break; } } - - matches!(last_scored_quarter, Some(4)) -} \ No newline at end of file +} diff --git a/anchor/target/types/squares.ts b/anchor/target/types/squares.ts index cad1a38..34af606 100644 --- a/anchor/target/types/squares.ts +++ b/anchor/target/types/squares.ts @@ -1,2 +1,2 @@ -export type Squares = {"version":"0.1.0","name":"football_squares","instructions":[{"name":"createGame","accounts":[{"name":"game","isMut":true,"isSigner":true},{"name":"user","isMut":true,"isSigner":true},{"name":"systemProgram","isMut":false,"isSigner":false}],"args":[{"name":"costPerSquare","type":"u64"}]},{"name":"purchaseSquare","accounts":[{"name":"game","isMut":true,"isSigner":false},{"name":"user","isMut":true,"isSigner":true},{"name":"systemProgram","isMut":false,"isSigner":false}],"args":[{"name":"squareIndices","type":"bytes"}]},{"name":"finalizeGame","accounts":[{"name":"game","isMut":true,"isSigner":false},{"name":"user","isMut":true,"isSigner":true},{"name":"systemProgram","isMut":false,"isSigner":false}],"args":[]},{"name":"updateScores","accounts":[{"name":"scores","isMut":true,"isSigner":false},{"name":"owner","isMut":false,"isSigner":true}],"args":[{"name":"quarter","type":"u8"},{"name":"home","type":"u8"},{"name":"away","type":"u8"}]}],"accounts":[{"name":"Scores","type":{"kind":"struct","fields":[{"name":"firstQuarterScores","type":{"defined":"QuarterScores"}},{"name":"secondQuarterScores","type":{"defined":"QuarterScores"}},{"name":"thirdQuarterScores","type":{"defined":"QuarterScores"}},{"name":"fourthQuarterScores","type":{"defined":"QuarterScores"}},{"name":"finalScores","type":{"defined":"QuarterScores"}}]}},{"name":"Game","type":{"kind":"struct","fields":[{"name":"owner","type":"publicKey"},{"name":"costPerSquare","type":"u64"},{"name":"gameStatus","type":{"defined":"GameStatus"}},{"name":"squares","type":{"vec":{"defined":"Square"}}},{"name":"homeTeamIndices","type":"bytes"},{"name":"awayTeamIndices","type":"bytes"},{"name":"quarterScores","type":{"array":[{"option":{"defined":"QuarterScores"}},5]}},{"name":"quarterWinners","type":{"array":[{"option":"publicKey"},5]}}]}}],"types":[{"name":"QuarterScores","type":{"kind":"struct","fields":[{"name":"home","type":{"option":"u8"}},{"name":"away","type":{"option":"u8"}}]}},{"name":"Square","type":{"kind":"struct","fields":[{"name":"owner","type":{"option":"publicKey"}},{"name":"homeTeamIndex","type":"u8"},{"name":"awayTeamIndex","type":"u8"}]}},{"name":"GameStatus","type":{"kind":"enum","variants":[{"name":"Open"},{"name":"Closed"},{"name":"Finalized"}]}}],"errors":[{"code":6000,"name":"GameClosed","msg":"The game is not open for purchases."},{"code":6001,"name":"InvalidSquareIndex","msg":"Invalid square index."},{"code":6002,"name":"SquareAlreadyPurchased","msg":"This square has already been purchased."},{"code":6003,"name":"Unauthorized","msg":"Only program owner can update scores."},{"code":6004,"name":"InvalidQuarter","msg":"Should be a number 1-5, where 5 is final score."},{"code":6005,"name":"GameNotOpen","msg":"Game's not open."},{"code":6006,"name":"NotAllSquaresPurchased","msg":"Can't finalize, not all squares are occupied."},{"code":6007,"name":"GameNotFinalized","msg":"Can't distribute winnings, game not finalized."},{"code":6008,"name":"QuarterAlreadyPaid"}]}; -export const IDL: Squares = {"version":"0.1.0","name":"football_squares","instructions":[{"name":"createGame","accounts":[{"name":"game","isMut":true,"isSigner":true},{"name":"user","isMut":true,"isSigner":true},{"name":"systemProgram","isMut":false,"isSigner":false}],"args":[{"name":"costPerSquare","type":"u64"}]},{"name":"purchaseSquare","accounts":[{"name":"game","isMut":true,"isSigner":false},{"name":"user","isMut":true,"isSigner":true},{"name":"systemProgram","isMut":false,"isSigner":false}],"args":[{"name":"squareIndices","type":"bytes"}]},{"name":"finalizeGame","accounts":[{"name":"game","isMut":true,"isSigner":false},{"name":"user","isMut":true,"isSigner":true},{"name":"systemProgram","isMut":false,"isSigner":false}],"args":[]},{"name":"updateScores","accounts":[{"name":"scores","isMut":true,"isSigner":false},{"name":"owner","isMut":false,"isSigner":true}],"args":[{"name":"quarter","type":"u8"},{"name":"home","type":"u8"},{"name":"away","type":"u8"}]}],"accounts":[{"name":"Scores","type":{"kind":"struct","fields":[{"name":"firstQuarterScores","type":{"defined":"QuarterScores"}},{"name":"secondQuarterScores","type":{"defined":"QuarterScores"}},{"name":"thirdQuarterScores","type":{"defined":"QuarterScores"}},{"name":"fourthQuarterScores","type":{"defined":"QuarterScores"}},{"name":"finalScores","type":{"defined":"QuarterScores"}}]}},{"name":"Game","type":{"kind":"struct","fields":[{"name":"owner","type":"publicKey"},{"name":"costPerSquare","type":"u64"},{"name":"gameStatus","type":{"defined":"GameStatus"}},{"name":"squares","type":{"vec":{"defined":"Square"}}},{"name":"homeTeamIndices","type":"bytes"},{"name":"awayTeamIndices","type":"bytes"},{"name":"quarterScores","type":{"array":[{"option":{"defined":"QuarterScores"}},5]}},{"name":"quarterWinners","type":{"array":[{"option":"publicKey"},5]}}]}}],"types":[{"name":"QuarterScores","type":{"kind":"struct","fields":[{"name":"home","type":{"option":"u8"}},{"name":"away","type":{"option":"u8"}}]}},{"name":"Square","type":{"kind":"struct","fields":[{"name":"owner","type":{"option":"publicKey"}},{"name":"homeTeamIndex","type":"u8"},{"name":"awayTeamIndex","type":"u8"}]}},{"name":"GameStatus","type":{"kind":"enum","variants":[{"name":"Open"},{"name":"Closed"},{"name":"Finalized"}]}}],"errors":[{"code":6000,"name":"GameClosed","msg":"The game is not open for purchases."},{"code":6001,"name":"InvalidSquareIndex","msg":"Invalid square index."},{"code":6002,"name":"SquareAlreadyPurchased","msg":"This square has already been purchased."},{"code":6003,"name":"Unauthorized","msg":"Only program owner can update scores."},{"code":6004,"name":"InvalidQuarter","msg":"Should be a number 1-5, where 5 is final score."},{"code":6005,"name":"GameNotOpen","msg":"Game's not open."},{"code":6006,"name":"NotAllSquaresPurchased","msg":"Can't finalize, not all squares are occupied."},{"code":6007,"name":"GameNotFinalized","msg":"Can't distribute winnings, game not finalized."},{"code":6008,"name":"QuarterAlreadyPaid"}]}; \ No newline at end of file +export type Squares = {"version":"0.1.0","name":"football_squares","instructions":[{"name":"createGameBoard","accounts":[{"name":"board","isMut":true,"isSigner":true},{"name":"creator","isMut":true,"isSigner":true},{"name":"systemProgram","isMut":false,"isSigner":false}],"args":[{"name":"costPerSquare","type":"u64"}]},{"name":"purchaseSquare","accounts":[{"name":"board","isMut":true,"isSigner":false},{"name":"owner","isMut":true,"isSigner":true},{"name":"systemProgram","isMut":false,"isSigner":false}],"args":[{"name":"squareIndices","type":"bytes"}]},{"name":"finalizeBoard","accounts":[{"name":"board","isMut":true,"isSigner":false},{"name":"creator","isMut":true,"isSigner":true},{"name":"systemProgram","isMut":false,"isSigner":false}],"args":[]},{"name":"updateEventScores","accounts":[{"name":"scores","isMut":true,"isSigner":false},{"name":"admin","isMut":false,"isSigner":true}],"args":[{"name":"period","type":"u8"},{"name":"home","type":"u8"},{"name":"away","type":"u8"}]},{"name":"initializeEventScores","accounts":[{"name":"scores","isMut":true,"isSigner":true},{"name":"admin","isMut":true,"isSigner":true},{"name":"systemProgram","isMut":false,"isSigner":false}],"args":[{"name":"eventName","type":"string"},{"name":"homeTeamName","type":"string"},{"name":"awayTeamName","type":"string"}]},{"name":"calculateGameBoardWinners","accounts":[{"name":"board","isMut":true,"isSigner":false},{"name":"scores","isMut":true,"isSigner":false},{"name":"creator","isMut":true,"isSigner":true}],"args":[]}],"accounts":[{"name":"GameBoard","type":{"kind":"struct","fields":[{"name":"creator","type":"publicKey"},{"name":"costPerSquare","type":"u64"},{"name":"status","type":{"defined":"GameBoardStatus"}},{"name":"squares","type":{"vec":{"defined":"GameBoardSquare"}}},{"name":"homeTeamIndices","type":"bytes"},{"name":"awayTeamIndices","type":"bytes"},{"name":"scoresAccount","type":"publicKey"},{"name":"periodWinners","type":{"array":[{"option":"publicKey"},5]}}]}},{"name":"EventScores","type":{"kind":"struct","fields":[{"name":"admin","type":"publicKey"},{"name":"eventName","type":"string"},{"name":"homeTeamName","type":"string"},{"name":"awayTeamName","type":"string"},{"name":"periodScores","type":{"array":[{"option":{"defined":"(u8,u8)"}},5]}}]}}],"types":[{"name":"GameBoardSquare","type":{"kind":"struct","fields":[{"name":"owner","type":{"option":"publicKey"}},{"name":"homeTeamIndex","type":"u8"},{"name":"awayTeamIndex","type":"u8"}]}},{"name":"GameBoardStatus","type":{"kind":"enum","variants":[{"name":"Open"},{"name":"Closed"},{"name":"Finalized"},{"name":"GameOver"}]}}],"errors":[{"code":6000,"name":"GameBoardClosed"},{"code":6001,"name":"InvalidSquareIndex"},{"code":6002,"name":"SquareAlreadyPurchased"},{"code":6003,"name":"Unauthorized"},{"code":6004,"name":"InvalidPeriod"},{"code":6005,"name":"GameBoardNotOpen"},{"code":6006,"name":"NotAllSquaresPurchased"},{"code":6007,"name":"GameBoardNotFinalized"},{"code":6008,"name":"PeriodAlreadyPaid"}]} +export const IDL: Squares = {"version":"0.1.0","name":"football_squares","instructions":[{"name":"createGameBoard","accounts":[{"name":"board","isMut":true,"isSigner":true},{"name":"creator","isMut":true,"isSigner":true},{"name":"systemProgram","isMut":false,"isSigner":false}],"args":[{"name":"costPerSquare","type":"u64"}]},{"name":"purchaseSquare","accounts":[{"name":"board","isMut":true,"isSigner":false},{"name":"owner","isMut":true,"isSigner":true},{"name":"systemProgram","isMut":false,"isSigner":false}],"args":[{"name":"squareIndices","type":"bytes"}]},{"name":"finalizeBoard","accounts":[{"name":"board","isMut":true,"isSigner":false},{"name":"creator","isMut":true,"isSigner":true},{"name":"systemProgram","isMut":false,"isSigner":false}],"args":[]},{"name":"updateEventScores","accounts":[{"name":"scores","isMut":true,"isSigner":false},{"name":"admin","isMut":false,"isSigner":true}],"args":[{"name":"period","type":"u8"},{"name":"home","type":"u8"},{"name":"away","type":"u8"}]},{"name":"initializeEventScores","accounts":[{"name":"scores","isMut":true,"isSigner":true},{"name":"admin","isMut":true,"isSigner":true},{"name":"systemProgram","isMut":false,"isSigner":false}],"args":[{"name":"eventName","type":"string"},{"name":"homeTeamName","type":"string"},{"name":"awayTeamName","type":"string"}]},{"name":"calculateGameBoardWinners","accounts":[{"name":"board","isMut":true,"isSigner":false},{"name":"scores","isMut":true,"isSigner":false},{"name":"creator","isMut":true,"isSigner":true}],"args":[]}],"accounts":[{"name":"GameBoard","type":{"kind":"struct","fields":[{"name":"creator","type":"publicKey"},{"name":"costPerSquare","type":"u64"},{"name":"status","type":{"defined":"GameBoardStatus"}},{"name":"squares","type":{"vec":{"defined":"GameBoardSquare"}}},{"name":"homeTeamIndices","type":"bytes"},{"name":"awayTeamIndices","type":"bytes"},{"name":"scoresAccount","type":"publicKey"},{"name":"periodWinners","type":{"array":[{"option":"publicKey"},5]}}]}},{"name":"EventScores","type":{"kind":"struct","fields":[{"name":"admin","type":"publicKey"},{"name":"eventName","type":"string"},{"name":"homeTeamName","type":"string"},{"name":"awayTeamName","type":"string"},{"name":"periodScores","type":{"array":[{"option":{"defined":"(u8,u8)"}},5]}}]}}],"types":[{"name":"GameBoardSquare","type":{"kind":"struct","fields":[{"name":"owner","type":{"option":"publicKey"}},{"name":"homeTeamIndex","type":"u8"},{"name":"awayTeamIndex","type":"u8"}]}},{"name":"GameBoardStatus","type":{"kind":"enum","variants":[{"name":"Open"},{"name":"Closed"},{"name":"Finalized"},{"name":"GameOver"}]}}],"errors":[{"code":6000,"name":"GameBoardClosed"},{"code":6001,"name":"InvalidSquareIndex"},{"code":6002,"name":"SquareAlreadyPurchased"},{"code":6003,"name":"Unauthorized"},{"code":6004,"name":"InvalidPeriod"},{"code":6005,"name":"GameBoardNotOpen"},{"code":6006,"name":"NotAllSquaresPurchased"},{"code":6007,"name":"GameBoardNotFinalized"},{"code":6008,"name":"PeriodAlreadyPaid"}]} \ No newline at end of file