import { CLUSTER_URL } from "@/data/shared"; import { Bets } from "@/idl/bets"; import { AnchorProvider, BN, Program } from "@coral-xyz/anchor"; import { ConnectedSolanaWallet } from "@privy-io/react-auth"; import { Connection, Keypair, LAMPORTS_PER_SOL, PublicKey } from "@solana/web3.js"; import idl from "../idl/bets_idl.json"; import { Bet } from "@/types/Bet"; import { toast } from "sonner"; import { Game } from "@/types/Game"; export const fetchOpenBets = async (wallets: ConnectedSolanaWallet): Promise => { try { if (!wallets) return []; const connection = new Connection(CLUSTER_URL); const wallet = { publicKey: new PublicKey(wallets.address), signTransaction: wallets.signTransaction, signAllTransactions: wallets.signAllTransactions, }; const provider = new AnchorProvider(connection, wallet, { preflightCommitment: "confirmed", }); const program = new Program(idl, provider); const [bet_list_pda] = await PublicKey.findProgramAddress( [Buffer.from("bets_list")], program.programId ); // Fetch all open bet accounts const bet_list = await program.account.betsList.fetch(bet_list_pda); // Extract required bet data const formattedBets = await Promise.all( bet_list.bets.map(async (bet) => { const betAcc = await program.account.betVault.fetch(bet); console.log(betAcc.gameId); return { id: betAcc.gameId, owner: betAcc.owner.toBase58(), joiner: betAcc.joiner ? betAcc.joiner.toBase58() : "Open", wager: betAcc.wager.toNumber() / LAMPORTS_PER_SOL }; }) ); console.log(`Got ${formattedBets.length} bets`); return formattedBets; } catch (error) { console.error("Error fetching open bets:", error); } return []; }; export async function closeBet(wallets: ConnectedSolanaWallet, betId: string): Promise { try { const connection = new Connection(CLUSTER_URL); const wallet = { publicKey: new PublicKey(wallets.address), signTransaction: wallets.signTransaction, signAllTransactions: wallets.signAllTransactions, }; const provider = new AnchorProvider(connection, wallet, { preflightCommitment: "confirmed", }); const program = new Program(idl, provider); const [bet_list_pda] = await PublicKey.findProgramAddress( [Buffer.from("bets_list")], program.programId ); // Fetch the bet list const betList = await program.account.betsList.fetch(bet_list_pda); let chosenBet: PublicKey | null = null; for (const bet of betList.bets) { const betAcc = await program.account.betVault.fetch(bet); if (betAcc.owner.toBase58() === wallets.address && betAcc.gameId.toString() === betId) { chosenBet = bet; break; } } if (!chosenBet) { console.error("Bet not found or not owned by the user"); return ""; } const winner = new PublicKey(wallets.address); // Execute the closeBet transaction const tx = await program.methods .closeBet(winner) .accounts({ betVault: chosenBet, betsList: bet_list_pda, winner: winner, }) .transaction(); tx.feePayer = new PublicKey(wallets.address); tx.recentBlockhash = (await connection.getLatestBlockhash()).blockhash; // Sign transaction with Privy const signedTx = await wallet.signTransaction(tx); // Send transaction// Replace with correct RPC endpoint const txId = await connection.sendRawTransaction(signedTx.serialize()); console.log(`Transaction: ${tx}`); return txId; } catch (error) { console.error("Error closing bet:", error); } return ""; } export async function createBet(wallets:ConnectedSolanaWallet,selectedPrice:number,selectedGame:Game):Promise{ const connection = new Connection(CLUSTER_URL); const wallet = { publicKey: new PublicKey(wallets.address), signTransaction: wallets.signTransaction, signAllTransactions: wallets.signAllTransactions, }; const provider = new AnchorProvider(connection, wallet, { preflightCommitment: "confirmed", }); const program = new Program(idl, provider); const [bet_list_pda] = await PublicKey.findProgramAddress( [Buffer.from("bets_list")], program.programId ); try { const nonce = 1; const [bet_list_pda] = await PublicKey.findProgramAddress( [Buffer.from("bets_list")], program.programId ); const connection = new Connection(CLUSTER_URL, "confirmed"); console.log(`bets list : ${bet_list_pda}`); // Create transaction const tx = await program.methods .createBet(new BN(selectedPrice * 1000000000), selectedGame.id, new BN(nonce)) .accounts({ betsList: bet_list_pda, }) .transaction(); // Get transaction object instead of RPC call tx.feePayer = new PublicKey(wallets.address); tx.recentBlockhash = (await connection.getLatestBlockhash()).blockhash; // Sign transaction with Privy const signedTx = await wallet.signTransaction(tx); // Send transaction// Replace with correct RPC endpoint const txId = await connection.sendRawTransaction(signedTx.serialize()); console.log(`Transaction ID: ${txId}`); return txId; } catch (error:unknown) { const errorMessage = String(error); // Converts error to string safely if (errorMessage.includes("already in use")) { toast.error("You can't make 2 bets for the same game."); } else { toast.error("Failed to create bet."); console.error(error); } } return ""; }