diff --git a/src/components/pages/game/game.tsx b/src/components/pages/game/game.tsx index e54f89a..b512f61 100644 --- a/src/components/pages/game/game.tsx +++ b/src/components/pages/game/game.tsx @@ -1,6 +1,6 @@ import { zodResolver } from '@hookform/resolvers/zod'; import { usePrivy } from '@privy-io/react-auth'; -import { useFundWallet } from '@privy-io/react-auth/solana'; +import { useCreateWallet, useFundWallet, useWallets } from '@privy-io/react-auth/solana'; import { useWallet } from '@solana/wallet-adapter-react'; import { useEffect, useRef, useState } from 'react'; import { SubmitHandler, useForm } from 'react-hook-form'; @@ -16,6 +16,7 @@ import { currencies, Currencies } from '@/constants/addresses'; import usePaymentPrices from '@/hooks/api/use-payment-prices'; import useStatus from '@/hooks/api/use-status'; import useMakePrediction from '@/hooks/contracts/write/use-make-prediction'; +import usePrivyMakePrediction from '@/hooks/contracts/write/use-privy-make-prediction'; import useSend from '@/hooks/contracts/write/use-send'; import { useBreakpoint } from '@/hooks/use-breakpoint'; import { cn, showTxToast } from '@/lib/utils'; @@ -70,12 +71,19 @@ type TarotRequestSchemaType = z.infer; export const GameSection = () => { const { publicKey } = useWallet(); const { fundWallet } = useFundWallet(); + const { createWallet } = useCreateWallet(); + const { wallets, ready: walletsReady } = useWallets(); const { authenticated, login } = usePrivy(); const pendingFund = useRef(false); + const privyWallet = walletsReady + ? (wallets.find((w) => 'isPrivyWallet' in w.standardWallet && (w.standardWallet as { isPrivyWallet: boolean }).isPrivyWallet) ?? null) + : null; + const isMd = useBreakpoint('md'); const { setIsOpen } = useWalletModalStore(); const { mutateAsync: transfer, isPending } = useMakePrediction(); + const { mutateAsync: privyTransfer, isPending: isPrivyPending } = usePrivyMakePrediction(); const { mutateAsync: transferCurrency, isPending: isSolPending, isSuccess: isTipSuccess } = useSend(); const { data: status } = useStatus(); const { data: paymentPrices } = usePaymentPrices(); @@ -214,6 +222,27 @@ export const GameSection = () => { }; }, [showTip, dontReload]); + const onPrivySubmit: SubmitHandler = async (data, e) => { + e?.preventDefault(); + if (isDemoPending) return; + if (predictionResponseTimer.current) clearTimeout(predictionResponseTimer.current); + setDemoReading(null); + setDisplayedTarots(null); + setShowTip(false); + setRetry(false); + const trimmedQuestion = data.question.trim(); + const amount = paymentPrices?.[currencyName] ?? currencies[currencyName].defaultPrice; + const result = await privyTransfer({ question: trimmedQuestion, tokenName: currencyName, amount, onStep: setLoadingStep }); + if (!result) return; + setDisplayedTarots(result.tarots); + predictionResponseTimer.current = setTimeout(() => { + const formatted = result.answer.replaceAll('*', ''); + setValue('question', formatReadingResponse({ answer: formatted, question: trimmedQuestion })); + setShowTip(true); + setRetry(true); + }, 3200); + }; + const onSubmit: SubmitHandler = async (data, e) => { e?.preventDefault(); @@ -341,35 +370,35 @@ export const GameSection = () => { }; useEffect(() => { - if (!pendingFund.current || !authenticated || !publicKey) { - return; - } + if (!authenticated || !walletsReady || privyWallet) return; + createWallet().catch(() => {}); + }, [authenticated, walletsReady, privyWallet, createWallet]); + useEffect(() => { + if (!pendingFund.current || !authenticated || !walletsReady) return; + const target = privyWallet?.address ?? publicKey?.toBase58(); + if (!target) return; pendingFund.current = false; - fundWallet({ address: publicKey.toBase58(), options: { defaultFundingMethod: 'card' } }).catch((error: unknown) => { + fundWallet({ address: target, options: { defaultFundingMethod: 'card', card: { preferredProvider: 'moonpay' } } }).catch((error: unknown) => { console.error('Fund wallet error:', error); toast.error('Could not open top-up modal. Please try again.'); }); - }, [authenticated, publicKey, fundWallet]); + }, [authenticated, walletsReady, privyWallet, publicKey, fundWallet]); const handleTopUpWithCard = async () => { - if (!publicKey) { - toast.error('Connect a wallet first'); - return; - } - if (!authenticated) { pendingFund.current = true; login(); return; } - + const target = privyWallet?.address ?? publicKey?.toBase58(); + if (!target) { + pendingFund.current = true; + return; + } try { - await fundWallet({ - address: publicKey.toBase58(), - options: { defaultFundingMethod: 'card' } - }); - } catch (error) { + await fundWallet({ address: target, options: { defaultFundingMethod: 'card', card: { preferredProvider: 'moonpay' } } }); + } catch (error: unknown) { console.error('Fund wallet error:', error); toast.error('Could not open top-up modal. Please try again.'); } @@ -497,27 +526,34 @@ export const GameSection = () => { variant="outline" onClick={ isRetry - ? () => { - setDontReload(true); - setTimeout(() => { - window.location.reload(); - }, 10); - } + ? () => { setDontReload(true); setTimeout(() => { window.location.reload(); }, 10); } : handleSubmit(onSubmit) } - disabled={isPending || isDemoPending || status?.isShutDown || !paymentPrices} + disabled={isPending || isPrivyPending || isDemoPending || status?.isShutDown || !paymentPrices} className="h-full w-full bg-[#9DA990] text-[22px]" > {isRetry ? 'Make a new Forecast' : 'Make a Forecast'} + ) : privyWallet ? ( + ) : (