Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/other currency #39

Merged
merged 4 commits into from
Jan 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"@radix-ui/react-accordion": "^1.2.2",
"@radix-ui/react-dialog": "^1.1.4",
"@radix-ui/react-popover": "^1.1.4",
"@radix-ui/react-select": "^2.1.4",
"@radix-ui/react-slot": "^1.1.1",
"@radix-ui/react-tooltip": "^1.1.6",
"@solana/spl-token": "^0.4.9",
Expand Down
12 changes: 12 additions & 0 deletions public/icons/currencies/usdcMint.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions public/icons/currencies/usdtMint.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 20 additions & 0 deletions public/icons/currencies/wSolMint.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
29 changes: 29 additions & 0 deletions src/components/common/CurrencySelect/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { Select, SelectTrigger, SelectItem, SelectValue, SelectContent } from '@/components/ui/select.tsx';
import { currencies, TCurrencies } from '@/constants/addresses.ts';

interface ICurrencySelect {
value: string;
onValueChange: (value: TCurrencies) => void;
}

export const CurrencySelect = ({ value, onValueChange }: ICurrencySelect) => {
return (
<Select value={value} onValueChange={onValueChange}>
<SelectTrigger className="font-poppins">
<SelectValue placeholder="Theme" />
</SelectTrigger>
<SelectContent className="font-poppins">
{Object.values(currencies).map((e, index) => {
return (
<SelectItem key={index} value={Object.keys(currencies)[index]}>
<div className="flex flex-row items-center gap-4">
<img src={`/icons/currencies/${Object.keys(currencies)[index]}.svg`} alt="currecy" />
<div>{e.defaultPrice}</div>
</div>
</SelectItem>
);
})}
</SelectContent>
</Select>
);
};
27 changes: 13 additions & 14 deletions src/components/pages/game/game.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ import { toast } from 'react-toastify';
import { z } from 'zod';

import { BaseTooltip } from '@/components/common/BaseTooltip';
import Solana from '@/components/common/Svg/Solana.tsx';
import { CurrencySelect } from '@/components/common/CurrencySelect';
import { Button } from '@/components/ui/button.tsx';
import { env } from '@/env';
import { currencies, TCurrencies } from '@/constants/addresses.ts';
import useStatus from '@/hooks/api/use-status';
import useMakePrediction from '@/hooks/contracts/write/use-make-prediction';
import useSendSol from '@/hooks/contracts/write/use-send-sol';
import { cn } from '@/lib/utils';
import useSend from '@/hooks/contracts/write/use-send.ts';
import { cn, showTxToast } from '@/lib/utils';
import { useWalletModalStore } from '@/store/wallet-modal.tsx';

const TarotRequestSchema = z.object({
Expand Down Expand Up @@ -46,7 +46,7 @@ export const GameSection = () => {

const { setIsOpen } = useWalletModalStore();
const { mutateAsync: transfer, isSuccess, isPending, data: predictionAnswer } = useMakePrediction();
const { mutateAsync: transferSol, isPending: isSolPending, isSuccess: isTipSuccess } = useSendSol();
const { mutateAsync: transferCurrency, isPending: isSolPending, isSuccess: isTipSuccess } = useSend();
const { data: status } = useStatus();

const [selectedTip, setSelectedTip] = useState<number>(0);
Expand All @@ -56,6 +56,7 @@ export const GameSection = () => {
const [showTip, setShowTip] = useState<boolean>(false);
const [isRetry, setRetry] = useState(false);
const [dontReload, setDontReload] = useState(false);
const [currencyName, setCurrencyName] = useState<TCurrencies>(Object.keys(currencies)[0] as TCurrencies);

const {
register,
Expand All @@ -69,7 +70,7 @@ export const GameSection = () => {

const onSubmit: SubmitHandler<TarotRequestSchemaType> = async (data, e) => {
e?.preventDefault();
await transfer(data.question.trim());
await transfer({ question: data.question.trim(), tokenName: currencyName });
};

const handleTip = async () => {
Expand All @@ -83,7 +84,9 @@ export const GameSection = () => {
return;
}

await transferSol(selectedTip);
await showTxToast('Tipping the Oracle', async () => {
await transferCurrency({ amount: selectedTip, tokenName: currencyName });
});
};

useEffect(() => {
Expand Down Expand Up @@ -213,11 +216,7 @@ export const GameSection = () => {
</div>

<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 sm:gap-10">
<div className="flex flex-row items-center gap-4 rounded-[8px] border border-[#3A3939] bg-[#D0C7A3] p-[14px] text-[20px]">
<Solana />
<div className="font-poppins">{env.VITE_DEPOSIT_AMOUNT_SOL} SOL</div>
</div>

<CurrencySelect onValueChange={setCurrencyName} value={currencyName} />
{publicKey ? (
<BaseTooltip content={status?.isShutDown ? 'Oracle is taking a brake' : ''}>
<Button
Expand Down Expand Up @@ -257,10 +256,10 @@ export const GameSection = () => {
<div className="grid grid-rows-[auto_auto] gap-5 lg:grid-cols-2 lg:gap-10">
<div className="grid grid-cols-2 gap-[20px] md:grid-cols-5">
<div className="flex w-full items-center justify-center rounded-[8px] border border-[#3A3939] bg-[#D0C7A3] p-[14px] text-[20px] max-md:col-span-2">
<Solana />
<img src={`/icons/currencies/${currencyName}.svg`} alt="currecy" />
</div>

{[0.002, 0.004, 0.02, 0.5].map((tip) => (
{currencies[currencyName].tips.map((tip) => (
<Button
size="responsive"
variant="outline"
Expand Down
144 changes: 144 additions & 0 deletions src/components/ui/select.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
'use client';

import * as SelectPrimitive from '@radix-ui/react-select';
import { Check, ChevronDown, ChevronUp } from 'lucide-react';
import * as React from 'react';

import { cn } from '@/lib/utils';

const Select = SelectPrimitive.Root;

const SelectGroup = SelectPrimitive.Group;

const SelectValue = SelectPrimitive.Value;

const SelectTrigger = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Trigger>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>
>(({ className, children, ...props }, ref) => (
<SelectPrimitive.Trigger
ref={ref}
className={cn(
'flex w-full items-center justify-between whitespace-nowrap rounded-[8px] border border-[#3A3939] bg-[#D0C7A3] p-[14px] text-[20px] ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1',
className,
)}
{...props}
>
{children}
<SelectPrimitive.Icon asChild>
<ChevronDown className="h-4 w-4 opacity-50" />
</SelectPrimitive.Icon>
</SelectPrimitive.Trigger>
));
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;

const SelectScrollUpButton = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.ScrollUpButton>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollUpButton>
>(({ className, ...props }, ref) => (
<SelectPrimitive.ScrollUpButton
ref={ref}
className={cn('flex cursor-default items-center justify-center py-1', className)}
{...props}
>
<ChevronUp className="h-4 w-4" />
</SelectPrimitive.ScrollUpButton>
));
SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;

const SelectScrollDownButton = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.ScrollDownButton>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollDownButton>
>(({ className, ...props }, ref) => (
<SelectPrimitive.ScrollDownButton
ref={ref}
className={cn('flex cursor-default items-center justify-center py-1', className)}
{...props}
>
<ChevronDown className="h-4 w-4" />
</SelectPrimitive.ScrollDownButton>
));
SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;

const SelectContent = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>
>(({ className, children, position = 'popper', ...props }, ref) => (
<SelectPrimitive.Portal>
<SelectPrimitive.Content
ref={ref}
className={cn(
'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md',
position === 'popper' &&
'data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1',
className,
)}
position={position}
{...props}
>
<SelectScrollUpButton />
<SelectPrimitive.Viewport
className={cn(
'p-1',
position === 'popper' &&
'h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]',
)}
>
{children}
</SelectPrimitive.Viewport>
<SelectScrollDownButton />
</SelectPrimitive.Content>
</SelectPrimitive.Portal>
));
SelectContent.displayName = SelectPrimitive.Content.displayName;

const SelectLabel = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Label>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>
>(({ className, ...props }, ref) => (
<SelectPrimitive.Label ref={ref} className={cn('px-2 py-1.5 text-sm font-semibold', className)} {...props} />
));
SelectLabel.displayName = SelectPrimitive.Label.displayName;

const SelectItem = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Item>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>
>(({ className, children, ...props }, ref) => (
<SelectPrimitive.Item
ref={ref}
className={cn(
'relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
className,
)}
{...props}
>
<span className="absolute right-2 flex h-3.5 w-3.5 items-center justify-center">
<SelectPrimitive.ItemIndicator>
<Check className="h-4 w-4" />
</SelectPrimitive.ItemIndicator>
</span>
<SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
</SelectPrimitive.Item>
));
SelectItem.displayName = SelectPrimitive.Item.displayName;

const SelectSeparator = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Separator>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>
>(({ className, ...props }, ref) => (
<SelectPrimitive.Separator ref={ref} className={cn('-mx-1 my-1 h-px bg-muted', className)} {...props} />
));
SelectSeparator.displayName = SelectPrimitive.Separator.displayName;

export {
Select,
SelectGroup,
SelectValue,
SelectTrigger,
SelectContent,
SelectLabel,
SelectItem,
SelectSeparator,
SelectScrollUpButton,
SelectScrollDownButton,
};
29 changes: 28 additions & 1 deletion src/constants/addresses.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,36 @@
import { WalletAdapterNetwork } from '@solana/wallet-adapter-base';
import { PublicKey } from '@solana/web3.js';

export const wSolMint = new PublicKey('So11111111111111111111111111111111111111112');
import { env } from '@/env.ts';

export const wSolMint = new PublicKey(env.VITE_WSOL_MINT);
export const usdcMint = new PublicKey(env.VITE_USDC_MINT);
export const usdtMint = new PublicKey(env.VITE_USDT_MINT);

export const OwnerAddress = {
[WalletAdapterNetwork.Mainnet]: new PublicKey('2Mko2nLhSiehXGJDseYCj6hYQdrK3cKNMetcGaXtbrJk'),
[WalletAdapterNetwork.Devnet]: new PublicKey('8LD69Ao7ULmWJNWULkUa5jhaLY9n7ucWcVGFcbfrFNwm'),
};

export const currencies = {
wSolMint: {
address: wSolMint,
decimals: 9,
tips: [0.002, 0.004, 0.02, 0.5],
defaultPrice: 0.003,
},
usdcMint: {
address: usdcMint,
decimals: 6,
tips: [0.5, 1, 5, 10],
defaultPrice: 0.4,
},
usdtMint: {
address: usdtMint,
decimals: 6,
tips: [0.5, 1, 5, 10],
defaultPrice: 0.4,
},
};

export type TCurrencies = keyof typeof currencies;
4 changes: 3 additions & 1 deletion src/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ export const env = createEnv({
VITE_API_URL: z.string().optional(),
VITE_PUBLIC_NETWORKS_MODE: z.enum(['testnet', 'mainnet']).default('testnet'),
VITE_PUBLIC_SOLANA_RPC: z.string().optional(),
VITE_DEPOSIT_AMOUNT_SOL: z.string().default('0.003'),
VITE_WSOL_MINT: z.string().default('So11111111111111111111111111111111111111112'),
VITE_USDC_MINT: z.string().default('GcdYBygdoiv6KNH4noHmdkK5hvKqdnfUUKMhe9d7vHek'),
VITE_USDT_MINT: z.string().default('DViAQybZkCmA3RioGmaZ3c5SsxAdPARoCTKpE5qKe8Z9'),
VITE_TWITTER_URL: z.string().optional(),
},
runtimeEnv: import.meta.env,
Expand Down
13 changes: 12 additions & 1 deletion src/hooks/api/use-submit-cards.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,17 @@ const useSubmitTarotCards = () => {
const { publicKey } = useWallet();

return useMutation({
async mutationFn({ tarots, hash, question }: { tarots: TarotCard[]; hash: string; question: string }) {
async mutationFn({
tarots,
hash,
question,
address,
}: {
tarots: TarotCard[];
hash: string;
question: string;
address: string;
}) {
if (!publicKey) {
return;
}
Expand All @@ -21,6 +31,7 @@ const useSubmitTarotCards = () => {
tarots,
hash,
question,
address,
});
},

Expand Down
Loading
Loading