v1 bug
This commit is contained in:
parent
97304366cb
commit
d41d3a13c0
|
|
@ -87,7 +87,7 @@ export default function Header() {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Mobile-only view (Logo & Login) */}
|
{/* Mobile-only view (Logo & Login) */}
|
||||||
<div className="flex md:hidden items-center scale-80 ">
|
<div className="flex md:hidden items-center ">
|
||||||
<PrivyButton></PrivyButton>
|
<PrivyButton></PrivyButton>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
|
|
|
||||||
|
|
@ -59,12 +59,14 @@ export default function HeroSection() {
|
||||||
const wallet = wallets.find((_wallet) => _wallet.type === "solana") || wallets[0];
|
const wallet = wallets.find((_wallet) => _wallet.type === "solana") || wallets[0];
|
||||||
setSolWallet(wallet);
|
setSolWallet(wallet);
|
||||||
|
|
||||||
const fetchedBets = await fetchOpenBets(wallet);
|
const fetchedBets = await fetchOpenBets();
|
||||||
const filteredBets = fetchedBets.filter((bet) => !(bet.owner_id && bet.joiner_id));
|
const filteredBets = fetchedBets.filter((bet) => !(bet.owner_id && bet.joiner_id));
|
||||||
const filledBets = fetchedBets.filter((bet) => bet.owner_id && bet.joiner_id);
|
const filledBets = fetchedBets.filter((bet) => bet.owner_id && bet.joiner_id);
|
||||||
let activeBet = filledBets.find((bet) => bet.owner_id === user?.id || bet.joiner_id === user?.id);
|
let activeBet = filledBets.find((bet) => bet.owner_id === user?.id || bet.joiner_id === user?.id);
|
||||||
|
|
||||||
if(activeBet){
|
if(activeBet){
|
||||||
|
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
||||||
const betHistoryResponse = await fetch(`${API_URL}get_game_completed.php?address=${activeBet.address}`);
|
const betHistoryResponse = await fetch(`${API_URL}get_game_completed.php?address=${activeBet.address}`);
|
||||||
const betHistory = await betHistoryResponse.text();
|
const betHistory = await betHistoryResponse.text();
|
||||||
|
|
||||||
|
|
@ -114,7 +116,7 @@ export default function HeroSection() {
|
||||||
// Step 3: Poll until vault account is found
|
// Step 3: Poll until vault account is found
|
||||||
const pollUntilFound = async (
|
const pollUntilFound = async (
|
||||||
maxRetries = 10,
|
maxRetries = 10,
|
||||||
delayMs = 3000
|
delayMs = 10000
|
||||||
): Promise<Bet | undefined> => {
|
): Promise<Bet | undefined> => {
|
||||||
for (let i:number = 0; i < maxRetries; i++) {
|
for (let i:number = 0; i < maxRetries; i++) {
|
||||||
const vault = await getVaultByAddress(solWallet, tx);
|
const vault = await getVaultByAddress(solWallet, tx);
|
||||||
|
|
@ -150,7 +152,7 @@ export default function HeroSection() {
|
||||||
try {
|
try {
|
||||||
const pollForRematchAddress = async (
|
const pollForRematchAddress = async (
|
||||||
maxRetries = 10,
|
maxRetries = 10,
|
||||||
delayMs = 3000
|
delayMs = 10000
|
||||||
): Promise<string | null> => {
|
): Promise<string | null> => {
|
||||||
for (let i = 0; i < maxRetries; i++) {
|
for (let i = 0; i < maxRetries; i++) {
|
||||||
console.log(`Polling rematch address... (${i + 1}/${maxRetries})`);
|
console.log(`Polling rematch address... (${i + 1}/${maxRetries})`);
|
||||||
|
|
@ -178,7 +180,7 @@ export default function HeroSection() {
|
||||||
const pollForVault = async (
|
const pollForVault = async (
|
||||||
address: string,
|
address: string,
|
||||||
maxRetries = 10,
|
maxRetries = 10,
|
||||||
delayMs = 3000
|
delayMs = 10000
|
||||||
): Promise<Bet | undefined> => {
|
): Promise<Bet | undefined> => {
|
||||||
for (let i:number = 0; i < maxRetries; i++) {
|
for (let i:number = 0; i < maxRetries; i++) {
|
||||||
console.log(`Polling vault for address ${address}... (${i + 1}/${maxRetries})`);
|
console.log(`Polling vault for address ${address}... (${i + 1}/${maxRetries})`);
|
||||||
|
|
@ -212,7 +214,7 @@ export default function HeroSection() {
|
||||||
if (!ready) return;
|
if (!ready) return;
|
||||||
|
|
||||||
updateBets();
|
updateBets();
|
||||||
const interval = setInterval(updateBets, 3500);
|
const interval = setInterval(updateBets, 3000);
|
||||||
|
|
||||||
return () => clearInterval(interval);
|
return () => clearInterval(interval);
|
||||||
}, [ready]);
|
}, [ready]);
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ export default function YourGames({ bets }: GameModalProps) {
|
||||||
|
|
||||||
setMyBets(enrichedBets);
|
setMyBets(enrichedBets);
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
console.log(`Got ${bets.length} bets`);
|
console.log(`Got ${bets.length} bets, enriched to ${enrichedBets.length}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -103,6 +103,8 @@ export default function YourGames({ bets }: GameModalProps) {
|
||||||
) : (
|
) : (
|
||||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
|
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||||
{myBets.map((bet) => {
|
{myBets.map((bet) => {
|
||||||
|
console.log(`Bet ${bet}`);
|
||||||
|
|
||||||
const game = games.find((g) => g.id === bet.id);
|
const game = games.find((g) => g.id === bet.id);
|
||||||
if (!game) return null;
|
if (!game) return null;
|
||||||
|
|
||||||
|
|
@ -135,7 +137,7 @@ export default function YourGames({ bets }: GameModalProps) {
|
||||||
|
|
||||||
<div className="flex justify-between text-xs font-mono py-1">
|
<div className="flex justify-between text-xs font-mono py-1">
|
||||||
<p className="text-white">{bet.wager} SOL</p>
|
<p className="text-white">{bet.wager} SOL</p>
|
||||||
<p className="text-white">{(bet.wager * 2 * WAGER_PRIZE_MULT).toFixed(2)} SOL</p>
|
<p className="text-white">{(bet.wager * 2 * WAGER_PRIZE_MULT).toFixed(3)} SOL</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{bet.ownerProfile && (
|
{bet.ownerProfile && (
|
||||||
|
|
@ -219,7 +221,7 @@ export default function YourGames({ bets }: GameModalProps) {
|
||||||
</div>
|
</div>
|
||||||
<div className="flex justify-between items-center">
|
<div className="flex justify-between items-center">
|
||||||
<span className="text-gray-400">Prize:</span>
|
<span className="text-gray-400">Prize:</span>
|
||||||
<span className="font-bold">{(selectedBet.wager * 2 * WAGER_PRIZE_MULT).toFixed(2)} SOL</span>
|
<span className="font-bold">{(selectedBet.wager * 2 * WAGER_PRIZE_MULT).toFixed(3)} SOL</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ export default function PrivyButton() {
|
||||||
setSolBalance((balance / 1e9).toFixed(2));
|
setSolBalance((balance / 1e9).toFixed(2));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to get balance:", error);
|
console.error("Failed to get balance:", error);
|
||||||
setSolBalance("Error");
|
setSolBalance("0");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -75,7 +75,7 @@ export default function PrivyButton() {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const intervalId = setInterval(() => {
|
const intervalId = setInterval(() => {
|
||||||
fetchSolBalance();
|
fetchSolBalance();
|
||||||
}, 5000); // 5000 milliseconds = 5 seconds
|
}, 15000); // 5000 milliseconds = 5 seconds
|
||||||
|
|
||||||
// Cleanup function to clear the interval on unmount or when `ready` changes
|
// Cleanup function to clear the interval on unmount or when `ready` changes
|
||||||
return () => clearInterval(intervalId);
|
return () => clearInterval(intervalId);
|
||||||
|
|
|
||||||
|
|
@ -87,6 +87,7 @@ export default function YourGames({bets}:GameModalProps) {
|
||||||
) : (
|
) : (
|
||||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
|
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||||
{myBets.map((bet) => {
|
{myBets.map((bet) => {
|
||||||
|
console.log(`Bet id:${bet.id}`);
|
||||||
const game = games.find((g) => g.id === bet.id);
|
const game = games.find((g) => g.id === bet.id);
|
||||||
if (!game) return null;
|
if (!game) return null;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,11 @@
|
||||||
import { Connection } from "@solana/web3.js";
|
import { Connection } from "@solana/web3.js";
|
||||||
|
|
||||||
export const CLUSTER_URL = "https://api.devnet.solana.com";
|
// Replace this URL with your dedicated RPC endpoint
|
||||||
export const EXPLORER_ADDRESS_TEMPLATE = "https://explorer.solana.com/address/{address}?cluster=devnet";
|
// You can get one from providers like QuickNode, Alchemy, Helius, or GenesysGo
|
||||||
export const EXPLORER_TX_TEMPLATE = "https://explorer.solana.com/tx/{address}?cluster=devnet";
|
export const CLUSTER_URL = "https://tiniest-cold-darkness.solana-mainnet.quiknode.pro/72332d636ff78d498b880bd8fdc3eb646c827da8/";
|
||||||
|
export const EXPLORER_ADDRESS_TEMPLATE = "https://explorer.solana.com/address/{address}";
|
||||||
|
export const EXPLORER_TX_TEMPLATE = "https://explorer.solana.com/tx/{address}";
|
||||||
export const connection = new Connection(CLUSTER_URL);
|
export const connection = new Connection(CLUSTER_URL);
|
||||||
|
|
||||||
|
|
||||||
export const API_URL = "https://api.duelfi.io/v1/";
|
export const API_URL = "https://api.duelfi.io/v1/";
|
||||||
|
export const VALIDATOR_URL = "https://validator.duelfi.io/";
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
* IDL can be found at `target/idl/bets.json`.
|
* IDL can be found at `target/idl/bets.json`.
|
||||||
*/
|
*/
|
||||||
export type Bets = {
|
export type Bets = {
|
||||||
"address": "JAf3ZkQ469okXAzA6BKJeKBb9ZkCtZanULaUsapskoyn",
|
"address": "Haj94DF925qNRgcoRwQfNsVLKgSmFhG4bjgtvusMkkpD",
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"name": "bets",
|
"name": "bets",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
|
|
@ -223,6 +223,48 @@ export type Bets = {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "refundBet",
|
||||||
|
"discriminator": [
|
||||||
|
209,
|
||||||
|
182,
|
||||||
|
226,
|
||||||
|
96,
|
||||||
|
55,
|
||||||
|
121,
|
||||||
|
83,
|
||||||
|
183
|
||||||
|
],
|
||||||
|
"accounts": [
|
||||||
|
{
|
||||||
|
"name": "betsList",
|
||||||
|
"writable": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "betVault",
|
||||||
|
"writable": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "owner",
|
||||||
|
"writable": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "payer",
|
||||||
|
"writable": true,
|
||||||
|
"signer": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "systemProgram",
|
||||||
|
"address": "11111111111111111111111111111111"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"args": [
|
||||||
|
{
|
||||||
|
"name": "owner",
|
||||||
|
"type": "pubkey"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"accounts": [
|
"accounts": [
|
||||||
|
|
@ -312,7 +354,7 @@ export type Bets = {
|
||||||
{
|
{
|
||||||
"name": "feeCollector",
|
"name": "feeCollector",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"value": "\"cocD4r4yNpHxPq7CzUebxEMyLki3X4d2Y3HcTX5ptUc\""
|
"value": "\"9esrj2X33pr5og6fdkDMjaW6fdnnb9hT1cWshamxTdL4\""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "seed",
|
"name": "seed",
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"address": "JAf3ZkQ469okXAzA6BKJeKBb9ZkCtZanULaUsapskoyn",
|
"address": "Haj94DF925qNRgcoRwQfNsVLKgSmFhG4bjgtvusMkkpD",
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"name": "bets",
|
"name": "bets",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
|
|
@ -217,6 +217,48 @@
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "refund_bet",
|
||||||
|
"discriminator": [
|
||||||
|
209,
|
||||||
|
182,
|
||||||
|
226,
|
||||||
|
96,
|
||||||
|
55,
|
||||||
|
121,
|
||||||
|
83,
|
||||||
|
183
|
||||||
|
],
|
||||||
|
"accounts": [
|
||||||
|
{
|
||||||
|
"name": "bets_list",
|
||||||
|
"writable": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "bet_vault",
|
||||||
|
"writable": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "owner",
|
||||||
|
"writable": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "payer",
|
||||||
|
"writable": true,
|
||||||
|
"signer": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "system_program",
|
||||||
|
"address": "11111111111111111111111111111111"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"args": [
|
||||||
|
{
|
||||||
|
"name": "owner",
|
||||||
|
"type": "pubkey"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"accounts": [
|
"accounts": [
|
||||||
|
|
@ -306,7 +348,7 @@
|
||||||
{
|
{
|
||||||
"name": "FEE_COLLECTOR",
|
"name": "FEE_COLLECTOR",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"value": "\"cocD4r4yNpHxPq7CzUebxEMyLki3X4d2Y3HcTX5ptUc\""
|
"value": "\"9esrj2X33pr5og6fdkDMjaW6fdnnb9hT1cWshamxTdL4\""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "SEED",
|
"name": "SEED",
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { Commitment, PublicKey } from "@solana/web3.js";
|
import { Commitment, PublicKey } from "@solana/web3.js";
|
||||||
|
|
||||||
export const FEE_COLLECTOR_PUBKEY = new PublicKey("cocD4r4yNpHxPq7CzUebxEMyLki3X4d2Y3HcTX5ptUc");
|
export const FEE_COLLECTOR_PUBKEY = new PublicKey("9esrj2X33pr5og6fdkDMjaW6fdnnb9hT1cWshamxTdL4");
|
||||||
export const WAGER_PRIZE_MULT = 0.95;
|
export const WAGER_PRIZE_MULT = 0.95;
|
||||||
|
|
||||||
export const CONFIRMATION_THRESHOLD:Commitment = 'finalized';
|
export const CONFIRMATION_THRESHOLD:Commitment = 'finalized';
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { CLUSTER_URL, connection } from "@/data/shared";
|
import { CLUSTER_URL, connection, VALIDATOR_URL } from "@/data/shared";
|
||||||
import { Bets } from "@/idl/bets";
|
import { Bets } from "@/idl/bets";
|
||||||
import { AnchorProvider, BN, Program } from "@coral-xyz/anchor";
|
import { AnchorProvider, BN, Program } from "@coral-xyz/anchor";
|
||||||
import { ConnectedSolanaWallet } from "@privy-io/react-auth";
|
import { ConnectedSolanaWallet } from "@privy-io/react-auth";
|
||||||
|
|
@ -8,52 +8,60 @@ import { Bet } from "@/types/Bet";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
import { CONFIRMATION_THRESHOLD, FEE_COLLECTOR_PUBKEY } from "./constants";
|
import { CONFIRMATION_THRESHOLD, FEE_COLLECTOR_PUBKEY } from "./constants";
|
||||||
|
|
||||||
export const fetchOpenBets = async (wallets: ConnectedSolanaWallet): Promise<Bet[]> => {
|
export async function fetchOpenBets(): Promise<Bet[]> {
|
||||||
try {
|
|
||||||
if (!wallets) return [];
|
|
||||||
|
|
||||||
const wallet = {
|
const response = await fetch(`${VALIDATOR_URL}fetchBets`);
|
||||||
publicKey: new PublicKey(wallets.address),
|
const data = await response.json();
|
||||||
signTransaction: wallets.signTransaction,
|
|
||||||
signAllTransactions: wallets.signAllTransactions,
|
|
||||||
};
|
|
||||||
const provider = new AnchorProvider(connection, wallet, {
|
|
||||||
preflightCommitment: CONFIRMATION_THRESHOLD,
|
|
||||||
});
|
|
||||||
|
|
||||||
const program = new Program<Bets>(idl, provider);
|
return data;
|
||||||
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, CONFIRMATION_THRESHOLD);
|
|
||||||
|
|
||||||
// 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 {
|
|
||||||
address: bet.toString(),
|
|
||||||
id: betAcc.gameId,
|
|
||||||
owner: betAcc.owner.toBase58(),
|
|
||||||
owner_id: betAcc.ownerId,
|
|
||||||
joiner: betAcc.joiner ? betAcc.joiner.toBase58() : "Open",
|
|
||||||
joiner_id: betAcc.joinerId,
|
|
||||||
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 const fetchOpenBets = async (wallets: ConnectedSolanaWallet): Promise<Bet[]> => {
|
||||||
|
// try {
|
||||||
|
// if (!wallets) return [];
|
||||||
|
|
||||||
|
// const wallet = {
|
||||||
|
// publicKey: new PublicKey(wallets.address),
|
||||||
|
// signTransaction: wallets.signTransaction,
|
||||||
|
// signAllTransactions: wallets.signAllTransactions,
|
||||||
|
// };
|
||||||
|
// const provider = new AnchorProvider(connection, wallet, {
|
||||||
|
// preflightCommitment: CONFIRMATION_THRESHOLD,
|
||||||
|
// });
|
||||||
|
|
||||||
|
// 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, CONFIRMATION_THRESHOLD);
|
||||||
|
|
||||||
|
// // 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 {
|
||||||
|
// address: bet.toString(),
|
||||||
|
// id: betAcc.gameId,
|
||||||
|
// owner: betAcc.owner.toBase58(),
|
||||||
|
// owner_id: betAcc.ownerId,
|
||||||
|
// joiner: betAcc.joiner ? betAcc.joiner.toBase58() : "Open",
|
||||||
|
// joiner_id: betAcc.joinerId,
|
||||||
|
// 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 getVaultByAddress(wallets: ConnectedSolanaWallet, address: string): Promise<Bet | undefined> {
|
export async function getVaultByAddress(wallets: ConnectedSolanaWallet, address: string): Promise<Bet | undefined> {
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user