Compare commits
No commits in common. "dev" and "master" have entirely different histories.
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
|
|
@ -260,7 +260,7 @@ export default function HeroSection() {
|
|||
<div className="w-full h-screen flex justify-center items-center bg-black">
|
||||
<iframe
|
||||
ref={iframeRef}
|
||||
src={`/UnityBuild/${myActiveBet.id}/index.html?betId=${myActiveBet.id}&owner=${myActiveBet.owner_id}&joiner=${myActiveBet.joiner_id}&address=${myActiveBet.address}&uid=${user?.id}&pubkey=${solWallet?.address}&wager=${myActiveBet.wager * 1e8}&isDev=${(CLUSTER_URL == clusterApiUrl("devnet")) ? "true" : "false"}`}
|
||||
src={`/UnityBuild/${myActiveBet.id}/index.html?betId=${myActiveBet.id}&owner=${myActiveBet.owner_id}&joiner=${myActiveBet.joiner_id}&address=${myActiveBet.address}&uid=${user?.id}&pubkey=${solWallet?.address}&wager=${myActiveBet.wager * 1e8}`}
|
||||
className="w-full h-full"
|
||||
allowFullScreen
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -12,9 +12,8 @@ import { Game } from "@/types/Game";
|
|||
import { games } from "@/data/games";
|
||||
import { WAGER_PRIZE_MULT } from "@/shared/constants";
|
||||
import { EXPLORER_ADDRESS_TEMPLATE } from "@/data/shared";
|
||||
import ReferralSection from "./ReferralSection";
|
||||
|
||||
const ENABLE_REFERRAL_SYSTEM = true; // Toggle for referral system visibility
|
||||
const ENABLE_REFERRAL_SYSTEM = false; // Toggle for referral system visibility
|
||||
|
||||
interface GameHistory {
|
||||
ended_time: string;
|
||||
|
|
@ -41,6 +40,26 @@ interface Opponent {
|
|||
x_profile_url: string;
|
||||
}
|
||||
|
||||
interface Referee {
|
||||
ref_id: string;
|
||||
id: string;
|
||||
username: string;
|
||||
bio: string;
|
||||
x_profile_url: string;
|
||||
referred_id: string;
|
||||
profilePicture?: string;
|
||||
joinedAt?: string;
|
||||
earnings?: number;
|
||||
}
|
||||
|
||||
interface ApiReferee {
|
||||
ref_id: string;
|
||||
id: string;
|
||||
username: string;
|
||||
bio: string;
|
||||
x_profile_url: string;
|
||||
referred_id: string;
|
||||
}
|
||||
|
||||
const GameHistoryItem = ({ game, user, gameImages, defaultPFP, failedImages, setFailedImages, handleViewTxClick }: {
|
||||
game: GameHistory,
|
||||
|
|
@ -178,6 +197,10 @@ export default function PrivyButton() {
|
|||
const [newUsername, setNewUsername] = useState("");
|
||||
const [referralId, setReferralId] = useState("");
|
||||
|
||||
const [isReferreesModalOpen, setIsReferreesModalOpen] = useState(false);
|
||||
const [referrees, setReferrees] = useState<Referee[]>([]);
|
||||
const [referralStats, setReferralStats] = useState({ earnings: 0, count: 0 });
|
||||
|
||||
const modalRef = useRef<HTMLDivElement>(null);
|
||||
const updateSolWallet = () => {
|
||||
wallets.forEach((wallet) => {
|
||||
|
|
@ -450,6 +473,7 @@ export default function PrivyButton() {
|
|||
);
|
||||
|
||||
setGameImages(gameDataWithImages);
|
||||
fetchReferralData();
|
||||
} catch (err) {
|
||||
console.error("Error fetching game history", err);
|
||||
} finally {
|
||||
|
|
@ -465,7 +489,31 @@ export default function PrivyButton() {
|
|||
window.open(`${EXPLORER_ADDRESS_TEMPLATE.replace("{address}",address)}`, "_blank");
|
||||
};
|
||||
|
||||
const fetchReferralData = async () => {
|
||||
if (!refId) return;
|
||||
|
||||
try {
|
||||
const response = await axios.get<ApiReferee[]>(`${API_URL}get_users_by_referral.php?id=${refId}`);
|
||||
const referreesData = response.data || [];
|
||||
|
||||
// Transform the data to match our Referee interface
|
||||
const transformedReferrees = referreesData.map((ref: ApiReferee) => ({
|
||||
...ref,
|
||||
profilePicture: ref.x_profile_url,
|
||||
joinedAt: new Date().toISOString(), // Since join date isn't provided in API
|
||||
earnings: 0.01 // Each referral gives 0.01 SOL
|
||||
}));
|
||||
|
||||
setReferrees(transformedReferrees);
|
||||
setReferralStats({
|
||||
earnings: transformedReferrees.length * 0.01, // 0.01 SOL per referral
|
||||
count: transformedReferrees.length
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch referral data:', error);
|
||||
toast.error('Failed to load referral data');
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
|
|
@ -677,10 +725,62 @@ export default function PrivyButton() {
|
|||
|
||||
{/* Referral Section */}
|
||||
{ENABLE_REFERRAL_SYSTEM && (
|
||||
<ReferralSection
|
||||
refId={refId}
|
||||
wallet={solWallet}
|
||||
/>
|
||||
<div>
|
||||
<h3 className="text-xl font-bold mb-4">Referral Program</h3>
|
||||
<div className="bg-gray-800 p-4 rounded-lg">
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<p className="text-gray-400 text-sm">Your Referral ID:</p>
|
||||
<p className="font-mono text-sm">{refId}</p>
|
||||
<button
|
||||
onClick={() => {
|
||||
navigator.clipboard.writeText(refId.toString());
|
||||
toast.success('Referral ID copied!');
|
||||
}}
|
||||
className="text-gray-400 hover:text-white transition p-1"
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M8 5H6a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2v-1M8 5a2 2 0 002 2h2a2 2 0 002-2M8 5a2 2 0 012-2h2a2 2 0 012 2m0 0h2a2 2 0 012 2v3m2 4H10m0 0l3-3m-3 3l3 3" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<button
|
||||
onClick={() => {
|
||||
const referralLink = `${window.location.origin}?ref=${refId}`;
|
||||
navigator.clipboard.writeText(referralLink);
|
||||
toast.success('Referral link copied!');
|
||||
}}
|
||||
className="bg-[rgb(248,144,22)] hover:bg-[rgb(248,200,100)] text-black px-4 py-2 rounded-md text-sm font-semibold flex items-center gap-2"
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M8.684 13.342C8.886 12.938 9 12.482 9 12c0-.482-.114-.938-.316-1.342m0 2.684a3 3 0 110-2.684m0 2.684l6.632 3.316m-6.632-6l6.632-3.316m0 0a3 3 0 105.367-2.684 3 3 0 00-5.367 2.684zm0 9.316a3 3 0 105.368 2.684 3 3 0 00-5.368-2.684z" />
|
||||
</svg>
|
||||
Share
|
||||
</button>
|
||||
</div>
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center gap-4">
|
||||
{/* <div>
|
||||
<p className="text-gray-400 text-xs">Referral Earnings</p>
|
||||
<p className="text-lg font-semibold">{referralStats.earnings.toFixed(2)} SOL</p>
|
||||
</div> */}
|
||||
<div>
|
||||
<p className="text-gray-400 text-xs">Total Referrals</p>
|
||||
<p className="text-lg font-semibold">{referralStats.count}</p>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
onClick={() => setIsReferreesModalOpen(true)}
|
||||
className="bg-gray-700 hover:bg-gray-600 text-white px-4 py-2 rounded-md text-sm font-semibold flex items-center gap-2"
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z" />
|
||||
</svg>
|
||||
View Referrees
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Divider */}
|
||||
|
|
@ -731,6 +831,49 @@ export default function PrivyButton() {
|
|||
</div>
|
||||
)}
|
||||
|
||||
{/* Referrees Modal */}
|
||||
{ENABLE_REFERRAL_SYSTEM && isReferreesModalOpen && (
|
||||
<div className="fixed inset-0 bg-black/70 flex justify-center items-center z-50">
|
||||
<div className="bg-[rgb(30,30,30)] text-white w-full max-w-lg p-6 rounded-2xl shadow-lg space-y-6">
|
||||
<div className="flex justify-between items-center">
|
||||
<h2 className="text-2xl font-bold">Your Referrees</h2>
|
||||
<button
|
||||
onClick={() => setIsReferreesModalOpen(false)}
|
||||
className="text-gray-400 hover:text-white transition duration-300 hover:scale-105"
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div className="max-h-96 overflow-y-auto space-y-4">
|
||||
{referrees.length === 0 ? (
|
||||
<p className="text-gray-500 text-center py-4">No referrees yet.</p>
|
||||
) : (
|
||||
referrees.map((referee, index) => (
|
||||
<div key={index} className="flex items-center justify-between bg-gray-800 p-3 rounded-lg">
|
||||
<div className="flex items-center gap-3">
|
||||
<Image
|
||||
src={referee.profilePicture || defaultPFP}
|
||||
alt="Profile"
|
||||
width={40}
|
||||
height={40}
|
||||
className="rounded-full border border-gray-700 object-cover"
|
||||
/>
|
||||
<div>
|
||||
<p className="font-semibold">{referee.username}</p>
|
||||
<p className="text-sm text-gray-400">Joined {referee.joinedAt ? new Date(referee.joinedAt).toLocaleDateString() : 'Recently'}</p>
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-sm text-gray-400">{referee.earnings} SOL earned</p>
|
||||
</div>
|
||||
))
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Username Claim Modal */}
|
||||
{isUsernameClaimModalOpen && (
|
||||
<div className="fixed inset-0 bg-black/70 flex justify-center items-center z-50">
|
||||
|
|
|
|||
|
|
@ -1,223 +0,0 @@
|
|||
import { useState, useEffect } from "react";
|
||||
import Image from "next/image";
|
||||
import { toast } from "sonner";
|
||||
import axios from "axios";
|
||||
import { GetGameByID } from "@/data/games";
|
||||
import { EXPLORER_ADDRESS_TEMPLATE, API_URL } from "@/data/shared";
|
||||
|
||||
interface GameHistory {
|
||||
ended_time: string;
|
||||
address: string;
|
||||
game: string;
|
||||
master_score: string;
|
||||
client_score: string;
|
||||
winner: string;
|
||||
wager: string;
|
||||
master_id: string;
|
||||
client_id: string;
|
||||
reward_tx: string;
|
||||
owner_referree: string;
|
||||
joiner_referree: string;
|
||||
}
|
||||
|
||||
interface ReferralSectionProps {
|
||||
refId: number;
|
||||
wallet: string;
|
||||
}
|
||||
|
||||
export default function ReferralSection({
|
||||
refId,
|
||||
wallet,
|
||||
}: ReferralSectionProps) {
|
||||
const [isReferreesModalOpen, setIsReferreesModalOpen] = useState(false);
|
||||
const [gamesHistory, setGamesHistory] = useState<GameHistory[]>([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [playerUsernames, setPlayerUsernames] = useState<{ [key: string]: string }>({});
|
||||
|
||||
useEffect(() => {
|
||||
const fetchGames = async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const response = await axios.get(`https://api.duelfi.io/v1/get_referrals.php?address=${wallet}`);
|
||||
const gameData = response.data || [];
|
||||
setGamesHistory(gameData);
|
||||
|
||||
// Fetch usernames for all players
|
||||
const uniquePlayerIds = new Set([
|
||||
...gameData.map((game: GameHistory) => game.master_id),
|
||||
...gameData.map((game: GameHistory) => game.client_id)
|
||||
]);
|
||||
|
||||
const usernames: { [key: string]: string } = {};
|
||||
await Promise.all(
|
||||
Array.from(uniquePlayerIds).map(async (playerId) => {
|
||||
try {
|
||||
const response = await axios.get(`${API_URL}get_user_by_id.php?id=${playerId}`);
|
||||
usernames[playerId] = response.data.username;
|
||||
} catch (err) {
|
||||
console.error("Failed to fetch username for", playerId, err);
|
||||
usernames[playerId] = "Unknown Player";
|
||||
}
|
||||
})
|
||||
);
|
||||
setPlayerUsernames(usernames);
|
||||
} catch (err) {
|
||||
console.error("Error fetching game history", err);
|
||||
toast.error("Failed to load game history");
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
fetchGames();
|
||||
}, [wallet]);
|
||||
|
||||
const handleViewTxClick = (address: string) => {
|
||||
window.open(`${EXPLORER_ADDRESS_TEMPLATE.replace("{address}", address)}`, "_blank");
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div>
|
||||
<h3 className="text-xl font-bold mb-4">Referral Program</h3>
|
||||
<div className="bg-gray-800 p-4 rounded-lg">
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<p className="text-gray-400 text-sm">Your Referral ID:</p>
|
||||
<p className="font-mono text-sm">{refId}</p>
|
||||
<button
|
||||
onClick={() => {
|
||||
navigator.clipboard.writeText(refId.toString());
|
||||
toast.success('Referral ID copied!');
|
||||
}}
|
||||
className="text-gray-400 hover:text-white transition p-1"
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M8 5H6a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2v-1M8 5a2 2 0 002 2h2a2 2 0 002-2M8 5a2 2 0 012-2h2a2 2 0 012 2m0 0h2a2 2 0 012 2v3m2 4H10m0 0l3-3m-3 3l3 3" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<button
|
||||
onClick={() => {
|
||||
const referralLink = `${window.location.origin}?ref=${refId}`;
|
||||
navigator.clipboard.writeText(referralLink);
|
||||
toast.success('Referral link copied!');
|
||||
}}
|
||||
className="bg-[rgb(248,144,22)] hover:bg-[rgb(248,200,100)] text-black px-4 py-2 rounded-md text-sm font-semibold flex items-center gap-2"
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M8.684 13.342C8.886 12.938 9 12.482 9 12c0-.482-.114-.938-.316-1.342m0 2.684a3 3 0 110-2.684m0 2.684l6.632 3.316m-6.632-6l6.632-3.316m0 0a3 3 0 105.367-2.684 3 3 0 00-5.367 2.684zm0 9.316a3 3 0 105.368 2.684 3 3 0 00-5.368-2.684z" />
|
||||
</svg>
|
||||
Share
|
||||
</button>
|
||||
</div>
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center gap-8">
|
||||
<div>
|
||||
<p className="text-gray-400 text-xs">Total Games</p>
|
||||
<p className="text-lg font-semibold">
|
||||
{loading ? "Loading..." : gamesHistory.length}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-gray-400 text-xs">Total Earnings</p>
|
||||
<p className="text-lg font-semibold text-green-500">
|
||||
{loading ? "Loading..." :
|
||||
`${gamesHistory.reduce((total, game) => {
|
||||
const wagerAmount = parseFloat(game.wager);
|
||||
const referralReward = (wagerAmount / 1e8) * 0.025;
|
||||
return total + referralReward;
|
||||
}, 0).toFixed(4)} SOL`
|
||||
}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
onClick={() => setIsReferreesModalOpen(true)}
|
||||
className="bg-gray-700 hover:bg-gray-600 text-white px-4 py-2 rounded-md text-sm font-semibold flex items-center gap-2"
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z" />
|
||||
</svg>
|
||||
View Referrees
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Referrees Modal */}
|
||||
{isReferreesModalOpen && (
|
||||
<div className="fixed inset-0 bg-black/70 flex justify-center items-center z-50">
|
||||
<div className="bg-[rgb(30,30,30)] text-white w-full max-w-lg p-6 rounded-2xl shadow-lg space-y-6">
|
||||
<div className="flex justify-between items-center">
|
||||
<h2 className="text-2xl font-bold">Your Referrees</h2>
|
||||
<button
|
||||
onClick={() => setIsReferreesModalOpen(false)}
|
||||
className="text-gray-400 hover:text-white transition duration-300 hover:scale-105"
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div className="max-h-96 overflow-y-auto space-y-4">
|
||||
{loading ? (
|
||||
<p className="text-gray-500 text-center py-4">Loading...</p>
|
||||
) : gamesHistory.length === 0 ? (
|
||||
<p className="text-gray-500 text-center py-4">No games played by referrees yet.</p>
|
||||
) : (
|
||||
gamesHistory.map((game, index) => {
|
||||
const gameData = GetGameByID(game.game);
|
||||
const gameImageUrl = gameData?.thumbnail || "/duelfiassets/default-game-thumbnail.png";
|
||||
const wagerAmount = parseFloat(game.wager);
|
||||
const referralReward = (wagerAmount / 1e8) * 0.025; // 2.5% of wager
|
||||
const outcomeText = `+${referralReward.toFixed(4)} SOL`;
|
||||
|
||||
return (
|
||||
<div key={index} className="relative border border-[rgb(30,30,30)] rounded-xl p-3 flex gap-3 items-center group">
|
||||
<div className="flex-1">
|
||||
<p className="text-sm font-semibold text-white">
|
||||
{gameData?.name}
|
||||
</p>
|
||||
<p className="text-xs text-gray-400">
|
||||
{playerUsernames[game.master_id] || "Unknown"} vs {playerUsernames[game.client_id] || "Unknown"}
|
||||
</p>
|
||||
<p className="text-xs text-gray-400">
|
||||
{new Date(game.ended_time).toLocaleString(undefined, {
|
||||
year: 'numeric',
|
||||
month: 'numeric',
|
||||
day: 'numeric',
|
||||
hour: 'numeric',
|
||||
minute: 'numeric'
|
||||
})}
|
||||
</p>
|
||||
<p className="text-xs text-green-500">
|
||||
{outcomeText}
|
||||
</p>
|
||||
</div>
|
||||
<Image
|
||||
src={gameImageUrl}
|
||||
alt="Game Thumbnail"
|
||||
width={64}
|
||||
height={64}
|
||||
className="rounded-md object-cover ml-4"
|
||||
/>
|
||||
<div className="absolute top-0 right-0 h-full w-28 bg-blue-500 text-white flex items-center justify-center opacity-0 group-hover:opacity-100 group-hover:translate-x-0 transition-all">
|
||||
<button
|
||||
onClick={() => handleViewTxClick(game.address)}
|
||||
className="px-4 py-2 text-sm font-semibold"
|
||||
>
|
||||
View TX
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
import { clusterApiUrl, Connection } from "@solana/web3.js";
|
||||
import { Connection } from "@solana/web3.js";
|
||||
|
||||
// Replace this URL with your dedicated RPC endpoint
|
||||
// You can get one from providers like QuickNode, Alchemy, Helius, or GenesysGo
|
||||
// export const CLUSTER_URL = "https://tiniest-cold-darkness.solana-mainnet.quiknode.pro/72332d636ff78d498b880bd8fdc3eb646c827da8/";
|
||||
// export const CLUSTER_URL = "https://go.getblock.io/908837801b534ae7a6f0869fc44cc567";
|
||||
// export const CLUSTER_URL = "https://solana-mainnet.core.chainstack.com/c54e14eef17693283a0323efcc4ce731";
|
||||
export const CLUSTER_URL = "https://solana-mainnet.core.chainstack.com/c54e14eef17693283a0323efcc4ce731";
|
||||
// export const CLUSTER_URL = "https://mainnet.helius-rpc.com/?api-key=72332d63-6ff7-4d49-8b88-0bd8fdc3eb64";
|
||||
export const CLUSTER_URL = clusterApiUrl("devnet");
|
||||
// export const CLUSTER_URL = clusterApiUrl("devnet");
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -13,31 +13,6 @@ export type Bets = {
|
|||
"description": "Created with Anchor"
|
||||
},
|
||||
"instructions": [
|
||||
{
|
||||
"name": "clearBetsList",
|
||||
"discriminator": [
|
||||
128,
|
||||
73,
|
||||
20,
|
||||
28,
|
||||
69,
|
||||
26,
|
||||
247,
|
||||
185
|
||||
],
|
||||
"accounts": [
|
||||
{
|
||||
"name": "betsList",
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"name": "payer",
|
||||
"writable": true,
|
||||
"signer": true
|
||||
}
|
||||
],
|
||||
"args": []
|
||||
},
|
||||
{
|
||||
"name": "closeBet",
|
||||
"discriminator": [
|
||||
|
|
@ -59,6 +34,10 @@ export type Bets = {
|
|||
"name": "betVault",
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"name": "feeWallet",
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"name": "winner",
|
||||
"writable": true
|
||||
|
|
@ -68,6 +47,14 @@ export type Bets = {
|
|||
"writable": true,
|
||||
"signer": true
|
||||
},
|
||||
{
|
||||
"name": "ownerReferrer",
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"name": "joinerReferrer",
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"name": "systemProgram",
|
||||
"address": "11111111111111111111111111111111"
|
||||
|
|
@ -164,60 +151,6 @@ export type Bets = {
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "deductFees",
|
||||
"discriminator": [
|
||||
249,
|
||||
7,
|
||||
117,
|
||||
167,
|
||||
160,
|
||||
108,
|
||||
235,
|
||||
14
|
||||
],
|
||||
"accounts": [
|
||||
{
|
||||
"name": "betsList",
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"name": "betVault",
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"name": "feeWallet",
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"name": "payer",
|
||||
"writable": true,
|
||||
"signer": true
|
||||
},
|
||||
{
|
||||
"name": "ownerReferrer",
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"name": "joinerReferrer",
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"name": "systemProgram",
|
||||
"address": "11111111111111111111111111111111"
|
||||
}
|
||||
],
|
||||
"args": [
|
||||
{
|
||||
"name": "winner",
|
||||
"type": "pubkey"
|
||||
},
|
||||
{
|
||||
"name": "userid",
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "initialize",
|
||||
"discriminator": [
|
||||
|
|
|
|||
|
|
@ -7,31 +7,6 @@
|
|||
"description": "Created with Anchor"
|
||||
},
|
||||
"instructions": [
|
||||
{
|
||||
"name": "clear_bets_list",
|
||||
"discriminator": [
|
||||
128,
|
||||
73,
|
||||
20,
|
||||
28,
|
||||
69,
|
||||
26,
|
||||
247,
|
||||
185
|
||||
],
|
||||
"accounts": [
|
||||
{
|
||||
"name": "bets_list",
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"name": "payer",
|
||||
"writable": true,
|
||||
"signer": true
|
||||
}
|
||||
],
|
||||
"args": []
|
||||
},
|
||||
{
|
||||
"name": "close_bet",
|
||||
"discriminator": [
|
||||
|
|
@ -53,6 +28,10 @@
|
|||
"name": "bet_vault",
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"name": "fee_wallet",
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"name": "winner",
|
||||
"writable": true
|
||||
|
|
@ -62,6 +41,14 @@
|
|||
"writable": true,
|
||||
"signer": true
|
||||
},
|
||||
{
|
||||
"name": "owner_referrer",
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"name": "joiner_referrer",
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"name": "system_program",
|
||||
"address": "11111111111111111111111111111111"
|
||||
|
|
@ -158,60 +145,6 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "deduct_fees",
|
||||
"discriminator": [
|
||||
249,
|
||||
7,
|
||||
117,
|
||||
167,
|
||||
160,
|
||||
108,
|
||||
235,
|
||||
14
|
||||
],
|
||||
"accounts": [
|
||||
{
|
||||
"name": "bets_list",
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"name": "bet_vault",
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"name": "fee_wallet",
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"name": "payer",
|
||||
"writable": true,
|
||||
"signer": true
|
||||
},
|
||||
{
|
||||
"name": "owner_referrer",
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"name": "joiner_referrer",
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"name": "system_program",
|
||||
"address": "11111111111111111111111111111111"
|
||||
}
|
||||
],
|
||||
"args": [
|
||||
{
|
||||
"name": "winner",
|
||||
"type": "pubkey"
|
||||
},
|
||||
{
|
||||
"name": "userid",
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "initialize",
|
||||
"discriminator": [
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import { Connection, 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 { CONFIRMATION_THRESHOLD } from "./constants";
|
||||
import { CONFIRMATION_THRESHOLD, FEE_COLLECTOR_PUBKEY } from "./constants";
|
||||
|
||||
export async function fetchOpenBets(): Promise<Bet[]> {
|
||||
|
||||
|
|
@ -22,7 +22,53 @@ export async function fetchOpenBetsDev(): Promise<Bet[]> {
|
|||
console.log(`Fetched ${data.length} open bets from validator`);
|
||||
return data;
|
||||
}
|
||||
// export const fetchOpenBetsSol = 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
|
||||
// );
|
||||
// console.log(`bet_list_pda: ${bet_list_pda}`);
|
||||
// // Fetch all open bet accounts
|
||||
// const bet_list = await program.account.betsList.fetch(bet_list_pda, CONFIRMATION_THRESHOLD);
|
||||
// console.log(`Fetched ${bet_list.bets.length} open bets from solana`);
|
||||
// // 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> {
|
||||
try {
|
||||
|
|
@ -94,14 +140,16 @@ export async function closeBet(wallets: ConnectedSolanaWallet, uid:string, betI
|
|||
|
||||
const winner = new PublicKey(wallets.address);
|
||||
|
||||
|
||||
// Execute the closeBet transaction
|
||||
const tx = await program.methods
|
||||
.closeBet(winner, uid)
|
||||
.accounts({
|
||||
betVault: chosenBet,
|
||||
betsList: bet_list_pda,
|
||||
winner: winner
|
||||
winner: winner,
|
||||
feeWallet: FEE_COLLECTOR_PUBKEY,
|
||||
ownerReferrer: FEE_COLLECTOR_PUBKEY,
|
||||
joinerReferrer: FEE_COLLECTOR_PUBKEY
|
||||
})
|
||||
.transaction();
|
||||
tx.feePayer = new PublicKey(wallets.address);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user