182 lines
5.9 KiB
TypeScript
182 lines
5.9 KiB
TypeScript
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<Bet[]> => {
|
|
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<Bets>(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<string> {
|
|
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<Bets>(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<string>{
|
|
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<Bets>(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 "";
|
|
} |