diff --git a/contracts/game_contract/src/game_state.rs b/contracts/game_contract/src/game_state.rs deleted file mode 100644 index 30578a9..0000000 --- a/contracts/game_contract/src/game_state.rs +++ /dev/null @@ -1,55 +0,0 @@ -#![no_std] - -use soroban_sdk::{contract, contractimpl, contracttype, Address, Env, Symbol}; - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct GameState { - pub board: String, // FEN representation of the board - pub current_turn: String, // "white" or "black" - pub status: String, // "in_progress", "checkmate", "stalemate", etc. -} - -#[contracttype] -pub enum DataKey { - Game(String), -} - -#[contract] -pub struct GameContract; - -#[contractimpl] -impl GameContract { - pub fn create_game(env: Env, game_id: String, initial_board: String) { - let state = GameState { - board: initial_board, - current_turn: "white".into(), - status: "in_progress".into(), - }; - - let key = DataKey::Game(game_id); - env.storage().persistent().set(&key, &state); - } - - pub fn get_game(env: Env, game_id: String) -> Option { - let key = DataKey::Game(game_id); - env.storage().persistent().get(&key) - } - - pub fn make_move(env: Env, game_id: String, new_board: String, next_turn: String) { - let key = DataKey::Game(game_id); - if let Some(mut state) = env.storage().persistent().get::(&key) { - state.board = new_board; - state.current_turn = next_turn; - env.storage().persistent().set(&key, &state); - } - } - - pub fn finalize_game(env: Env, game_id: String, final_status: String) { - let key = DataKey::Game(game_id); - if let Some(mut state) = env.storage().persistent().get::(&key) { - state.status = final_status; - env.storage().persistent().set(&key, &state); - } - } -} \ No newline at end of file diff --git a/contracts/game_contract/src/lib.rs b/contracts/game_contract/src/lib.rs index 7bcf9b3..b1a2e45 100644 --- a/contracts/game_contract/src/lib.rs +++ b/contracts/game_contract/src/lib.rs @@ -32,6 +32,7 @@ pub struct Game { pub created_at: u64, pub winner: Option
, pub last_move_at: u64, // Ledger sequence of last move + pub board_fen: Bytes, } #[contracttype] @@ -178,6 +179,7 @@ impl GameContract { env: Env, player1: Address, wager_amount: i128, + initial_board: Bytes, ) -> Result { let max_stake: i128 = env.storage().instance().get(&MAX_STAKE).unwrap_or(1_000); if wager_amount > max_stake { @@ -210,6 +212,7 @@ impl GameContract { created_at: env.ledger().sequence() as u64, winner: None, last_move_at: env.ledger().sequence() as u64, + board_fen: initial_board, }; let mut games: Map = env @@ -291,6 +294,8 @@ impl GameContract { game_id: u64, player: Address, move_data: Vec, + new_board: Bytes, + game_status: u32, ) -> Result<(), ContractError> { let mut games: Map = env .storage() @@ -330,6 +335,19 @@ impl GameContract { game.moves.push_back(chess_move); game.current_turn = if game.current_turn == 1 { 2 } else { 1 }; game.last_move_at = env.ledger().sequence() as u64; + game.board_fen = new_board; + + // Auto settlement logic based on status flag + if game_status == 1 { + // Checkmate: submitting player wins + game.state = GameState::Completed; + game.winner = Some(player.clone()); + Self::process_payout(&env, &game, &player)?; + } else if game_status == 2 { + // Draw + game.state = GameState::Drawn; + Self::process_draw_payout(&env, &game)?; + } games.set(game_id, game); env.storage().instance().set(&GAMES, &games); @@ -1291,7 +1309,7 @@ mod tests { // Create & join game with wager = 5 (pool = 10) let wager: i128 = 5; - let game_id = client.create_game(&player1, &wager); + let game_id = client.create_game(&player1, &wager, &Bytes::new(&env)); client.join_game(&game_id, &player2); // player1 forfeits → player2 wins @@ -1350,7 +1368,7 @@ mod tests { client.set_max_stake(&1_000i128); let wager: i128 = 500; // pool = 1000 - let game_id = client.create_game(&player1, &wager); + let game_id = client.create_game(&player1, &wager, &Bytes::new(&env)); client.join_game(&game_id, &player2); client.forfeit(&game_id, &player1); // player2 wins @@ -1389,7 +1407,7 @@ mod tests { client.initialize_token(&admin, &token_address); let initial_wager: i128 = 100; - let game_id = client.create_game(&player1, &initial_wager); + let game_id = client.create_game(&player1, &initial_wager, &Bytes::new(&env)); client.join_game(&game_id, &player2); client.forfeit(&game_id, &player1); @@ -1505,7 +1523,7 @@ mod tests { client.set_max_stake(&1_000i128); let wager: i128 = 100; - let game_id = client.create_game(&player1, &wager); + let game_id = client.create_game(&player1, &wager, &Bytes::new(&env)); client.join_game(&game_id, &player2); env.as_contract(&contract_id, || { @@ -1556,7 +1574,7 @@ mod tests { client.set_max_stake(&1_000i128); let wager: i128 = 100; - let game_id = client.create_game(&player1, &wager); + let game_id = client.create_game(&player1, &wager, &Bytes::new(&env)); client.join_game(&game_id, &player2); let result = client.try_claim_timeout_win(&game_id, &player2); @@ -1596,7 +1614,7 @@ mod tests { client.set_max_stake(&1_000i128); let wager: i128 = 100; - let game_id = client.create_game(&player1, &wager); + let game_id = client.create_game(&player1, &wager, &Bytes::new(&env)); client.join_game(&game_id, &player2); let remaining = client.get_timeout_remaining(&game_id); @@ -1648,7 +1666,7 @@ mod tests { client.set_max_stake(&1_000i128); let wager: i128 = 100; - let game_id = client.create_game(&player1, &wager); + let game_id = client.create_game(&player1, &wager, &Bytes::new(&env)); client.join_game(&game_id, &player2); let reason = Bytes::from_slice(&env, b"Engine abuse"); @@ -1697,7 +1715,7 @@ mod tests { client.set_max_stake(&1_000i128); let wager: i128 = 100; - let game_id = client.create_game(&player1, &wager); + let game_id = client.create_game(&player1, &wager, &Bytes::new(&env)); client.join_game(&game_id, &player2); let reason = Bytes::from_slice(&env, b"Illegal move"); @@ -1749,7 +1767,7 @@ mod tests { client.set_max_stake(&1_000i128); let wager: i128 = 100; - let game_id = client.create_game(&player1, &wager); + let game_id = client.create_game(&player1, &wager, &Bytes::new(&env)); client.join_game(&game_id, &player2); client.forfeit(&game_id, &player1); @@ -1792,7 +1810,7 @@ mod tests { client.set_max_stake(&1_000i128); let wager: i128 = 100; - let game_id = client.create_game(&player1, &wager); + let game_id = client.create_game(&player1, &wager, &Bytes::new(&env)); client.join_game(&game_id, &player2); let reason = Bytes::from_slice(&env, b"Illegal move"); @@ -1843,7 +1861,7 @@ mod tests { client.set_max_stake(&1_000i128); let wager: i128 = 100; - let game_id = client.create_game(&player1, &wager); + let game_id = client.create_game(&player1, &wager, &Bytes::new(&env)); client.join_game(&game_id, &player2); env.as_contract(&contract_id, || { @@ -1884,16 +1902,16 @@ mod tests { client.set_max_stake(&1_000i128); let wager: i128 = 100; - let game_id = client.create_game(&player1, &wager); + let game_id = client.create_game(&player1, &wager, &Bytes::new(&env)); client.join_game(&game_id, &player2); let first_move = Vec::from_array(&env, [12u32, 28u32]); - client.submit_move(&game_id, &player1, &first_move); + client.submit_move(&game_id, &player1, &first_move, &Bytes::new(&env), &0u32); env.ledger().set_sequence_number(2); let second_move = Vec::from_array(&env, [52u32, 36u32]); - client.submit_move(&game_id, &player2, &second_move); + client.submit_move(&game_id, &player2, &second_move, &Bytes::new(&env), &0u32); let game = client.get_game(&game_id); assert_eq!(game.current_turn, 1); @@ -1942,15 +1960,15 @@ mod tests { client.set_max_stake(&1_000i128); let wager: i128 = 100; - let game_id = client.create_game(&player1, &wager); + let game_id = client.create_game(&player1, &wager, &Bytes::new(&env)); client.join_game(&game_id, &player2); let early_move = Vec::from_array(&env, [52u32, 36u32]); - let result = client.try_submit_move(&game_id, &player2, &early_move); + let result = client.try_submit_move(&game_id, &player2, &early_move, &Bytes::new(&env), &0u32); assert_eq!(result, Err(Ok(ContractError::NotYourTurn))); let empty_move = Vec::new(&env); - let result = client.try_submit_move(&game_id, &player1, &empty_move); + let result = client.try_submit_move(&game_id, &player1, &empty_move, &Bytes::new(&env), &0u32); assert_eq!(result, Err(Ok(ContractError::InvalidMove))); } @@ -1989,7 +2007,7 @@ mod tests { client.set_max_stake(&1_000i128); let wager: i128 = 100; - let game_id = client.create_game(&player1, &wager); + let game_id = client.create_game(&player1, &wager, &Bytes::new(&env)); client.join_game(&game_id, &player2); // File dispute diff --git a/contracts/game_contract/src/test.rs b/contracts/game_contract/src/test.rs index 2ac456c..4332790 100644 --- a/contracts/game_contract/src/test.rs +++ b/contracts/game_contract/src/test.rs @@ -31,6 +31,7 @@ fn seed_completed_game( created_at: 0, winner: None, last_move_at: 0, + board_fen: Bytes::new(env), }; let mut games: Map = Map::new(env); games.set(game_id, game); @@ -190,7 +191,7 @@ fn test_create_game_exceeds_max_stake() { let player1 = Address::generate(&env); let wager = 1001; // Exceeds default 1000 - let res = client.try_create_game(&player1, &wager); + let res = client.try_create_game(&player1, &wager, &Bytes::new(&env)); assert!(res.is_err()); // The error should be StakeLimitExceeded (15) @@ -226,11 +227,11 @@ fn test_set_max_stake() { client.set_max_stake(&500); // Try to create game with 600 - let res = client.try_create_game(&player1, &600); + let res = client.try_create_game(&player1, &600, &Bytes::new(&env)); assert!(res.is_err()); // Try to create game with 500 - let game_id_res = client.try_create_game(&player1, &500); + let game_id_res = client.try_create_game(&player1, &500, &Bytes::new(&env)); assert!(game_id_res.is_ok()); } @@ -263,7 +264,7 @@ fn test_payout_with_fee() { stellar_asset_client.mint(&player1, &wager); stellar_asset_client.mint(&player2, &wager); - let game_id = client.create_game(&player1, &wager); + let game_id = client.create_game(&player1, &wager, &Bytes::new(&env)); client.join_game(&game_id, &player2); // Force complete the game and set winner diff --git a/frontend/components/WalletConnectModal.tsx b/frontend/components/WalletConnectModal.tsx index d39728b..0d9cff9 100644 --- a/frontend/components/WalletConnectModal.tsx +++ b/frontend/components/WalletConnectModal.tsx @@ -110,9 +110,12 @@ export function WalletConnectModal({ {/* Content */} - + + {/* Glowing Aura Background */} +
+ {/* Header gradient bar */} -
+
{/* Close button */} @@ -290,10 +293,10 @@ export function WalletConnectModal({