Skip to content

Commit

Permalink
Merge pull request #39 from RedDuck-Software/feat/other-currency
Browse files Browse the repository at this point in the history
Feat/other currency
  • Loading branch information
NikiTaysRD authored Jan 17, 2025
2 parents e233dd6 + 451a062 commit 6139876
Show file tree
Hide file tree
Showing 15 changed files with 456 additions and 48 deletions.
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

0 comments on commit 6139876

Please sign in to comment.