diff --git a/programs/bets/src/error.rs b/programs/bets/src/error.rs index f9e101d..2fdc8dc 100644 --- a/programs/bets/src/error.rs +++ b/programs/bets/src/error.rs @@ -16,5 +16,7 @@ pub enum BettingError { #[msg("The winner must be either the owner or the joiner of the bet.")] InvalidWinner, #[msg("Please use the correct fee collector address")] - InvalidFeeCollector + InvalidFeeCollector, + #[msg("")] + JoinerAccountNotProvided } \ No newline at end of file diff --git a/programs/bets/src/instructions/mod.rs b/programs/bets/src/instructions/mod.rs index 29cd29f..cb19ba4 100644 --- a/programs/bets/src/instructions/mod.rs +++ b/programs/bets/src/instructions/mod.rs @@ -8,4 +8,7 @@ pub mod join_bet; pub use join_bet::*; pub mod close_bet; -pub use close_bet::*; \ No newline at end of file +pub use close_bet::*; + +pub mod refund_bet; +pub use refund_bet::*; \ No newline at end of file diff --git a/programs/bets/src/instructions/refund_bet.rs b/programs/bets/src/instructions/refund_bet.rs new file mode 100644 index 0000000..ab1d039 --- /dev/null +++ b/programs/bets/src/instructions/refund_bet.rs @@ -0,0 +1,58 @@ +use anchor_lang::prelude::*; +use crate::{error::BettingError, *}; + +pub fn refund(ctx: Context, owner: Pubkey) -> Result<()> { + let bet_vault = &mut ctx.accounts.bet_vault; + + require!( + bet_vault.owner == owner || bet_vault.joiner == owner, + BettingError::InvalidWinner + ); + + // Check if there's a joiner and it's a valid account (not the system program or default) + if bet_vault.joiner != Pubkey::default() && bet_vault.joiner != ctx.accounts.system_program.key() { + // Calculate the 50% that goes to the joiner + let total_lamports = **bet_vault.to_account_info().lamports.borrow(); + let joiner_share = total_lamports / 2; + + // Transfer joiner's share + **bet_vault.to_account_info().try_borrow_mut_lamports()? -= joiner_share; + + // We need to find the joiner account in the remaining accounts + let joiner_account = ctx.remaining_accounts + .iter() + .find(|account| account.key() == bet_vault.joiner) + .ok_or(BettingError::JoinerAccountNotProvided)?; + + **joiner_account.try_borrow_mut_lamports()? += joiner_share; + + msg!("Sent {} lamports to joiner {}", joiner_share, bet_vault.joiner); + } + + // The remaining balance will go to the owner through the close=owner directive + + let bets_list = &mut ctx.accounts.bets_list; + // Remove the bet_vault public key from the list + bets_list.bets.retain(|&bet| bet != bet_vault.key()); + + msg!("Bet {} Refunded by {}", bet_vault.key(), owner); + + Ok(()) +} + + +#[derive(Accounts)] +pub struct RefundBet<'info> { + #[account(mut)] + pub bets_list: Account<'info, BetsList>, + + #[account(mut, close=owner)] + pub bet_vault: Account<'info, BetVault>, + + #[account(mut)] + pub owner: SystemAccount<'info>, + + #[account(mut)] + pub payer: Signer<'info>, + pub system_program: Program<'info, System> +} diff --git a/programs/bets/src/lib.rs b/programs/bets/src/lib.rs index b0f1737..9197860 100644 --- a/programs/bets/src/lib.rs +++ b/programs/bets/src/lib.rs @@ -30,4 +30,8 @@ pub mod bets { pub fn close_bet(ctx:Context, winner:Pubkey)->Result<()> { close_bet::close(ctx, winner) } + + pub fn refund_bet(ctx:Context, owner:Pubkey)->Result<()>{ + refund_bet::refund(ctx, owner) + } }