Files

215 lines
7.0 KiB
TypeScript

/* 'use client';
import { zodResolver } from '@hookform/resolvers/zod';
import { CHAIN, SENT_SYMBOL, chains } from '@session/contracts';
import { Module, ModuleContent } from '@session/ui/components/Module';
import { Button } from '@session/ui/ui/button';
import { Input } from '@session/ui/ui/input';
import { collapseString } from '@session/util/string';
import { useTranslations } from 'next-intl';
import { useEffect, useMemo, useState } from 'react';
import { useForm } from 'react-hook-form';
import { Address, formatEther, isAddress } from 'viem';
import { useAccount, useBalance, useDisconnect } from 'wagmi';
import { z } from 'zod';
import { sentTestSent } from './actions';
import { WalletAddTokenWithLocales } from '@/components/WalletAddTokenWithLocales';
import { WalletModalButtonWithLocales } from '@/components/WalletModalButtonWithLocales';
import { URL } from '@/lib/constants';
import { ButtonDataTestId } from '@/testing/data-test-ids';
import { toast } from '@session/ui/lib/toast';
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
FormSubmitButton,
} from '@session/ui/ui/form';
import { useWalletChain } from '@session/wallet/hooks/wallet-hooks';
export default function FaucetModule() {
const dictionary = useTranslations('faucet');
const [transactionHash, setTransactionHash] = useState<Address | null>(null);
const { address, status } = useAccount();
const { disconnect } = useDisconnect();
const { chain, switchChain } = useWalletChain();
const { data: ethBalance } = useBalance({
address,
chainId: chains[CHAIN.TESTNET].id,
query: { enabled: !!address },
});
const FormSchema = z.object({
walletAddress: z.string().refine((value) => isAddress(value), {
message: dictionary('form.errorInvalidAddress', { example: '0x...' }),
}),
});
const form = useForm<z.infer<typeof FormSchema>>({
resolver: zodResolver(FormSchema),
defaultValues: {
walletAddress: '',
},
});
const successMessage = (hash: Address) => (
<div className="flex flex-col text-sm font-normal">
<span>{dictionary('form.success', { tokenSymbol: SENT_SYMBOL })}</span>
<span>{dictionary('form.transactionHash', { hash })}</span>
</div>
);
async function onSubmit(data: z.infer<typeof FormSchema>) {
const { walletAddress } = data;
if (!walletAddress || !isAddress(walletAddress)) {
return;
}
const promise: Promise<Address> = new Promise((resolve, reject) =>
sentTestSent({ address: walletAddress, chain: CHAIN.TESTNET }).then(({ hash, error }) => {
if (hash) {
setTransactionHash(hash);
return resolve(hash);
}
if (error) {
form.setError('root', { message: error });
return reject(error);
}
})
);
toast.promise(promise, {
loading: dictionary('form.loading', { tokenSymbol: SENT_SYMBOL }),
success: successMessage,
error: (error: string) => (
<div className="flex flex-col">
<span>{dictionary('form.error', { tokenSymbol: SENT_SYMBOL })}</span>
<span>{error}</span>
</div>
),
});
await promise;
}
const disconnectWallet = () => {
disconnect();
};
const ethAmount = useMemo(() => {
if (!address || ethBalance === undefined) {
return null;
}
return parseFloat(formatEther(ethBalance.value));
}, [ethBalance, address]);
useEffect(() => {
if (status === 'connected') {
form.clearErrors();
form.setValue('walletAddress', address, {
shouldValidate: true,
shouldTouch: true,
shouldDirty: true,
});
setTransactionHash(null);
if (chain !== CHAIN.TESTNET) {
switchChain(CHAIN.TESTNET);
}
} else if (status === 'disconnected') {
form.reset({ walletAddress: '' });
form.clearErrors();
setTransactionHash(null);
}
}, [status, address, form]);
return (
<Module className="max-w-xl items-center">
<ModuleContent className="flex h-full flex-col items-center gap-2 align-middle font-bold">
{address && ethAmount !== null && ethAmount <= 0.001 ? (
<p className="text-destructive text-lg">
{dictionary.rich('form.lowEthBalance', {
link: (chunks) => (
<a
href={URL.ARB_SEP_FAUCET}
target="_blank"
rel="noreferrer"
className="text-blue-400 underline"
>
{chunks}
</a>
),
ethAmount,
})}
</p>
) : null}
{address ? (
<p className="text-md font-normal">
{dictionary('connectedWalletInfo', {
address: collapseString(address, 6, 6),
})}
</p>
) : (
<WalletModalButtonWithLocales />
)}
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="flex w-full flex-col gap-6">
<FormField
control={form.control}
name="walletAddress"
render={({ field }) => (
<FormItem className="flex flex-col">
{address ? null : <span> - {dictionary('or')} - </span>}
{address ? null : (
<FormLabel title={dictionary('form.description', { tokenSymbol: SENT_SYMBOL })}>
{dictionary('form.label')}
</FormLabel>
)}
<FormControl>
<div className="flex w-full items-center gap-2">
<Input
placeholder={address ?? dictionary('form.placeholder')}
disabled={!!address}
className="w-full"
{...field}
/>
{address ? (
<Button
variant="destructive"
onClick={disconnectWallet}
data-testid={ButtonDataTestId.Faucet_Disconnect}
>
{dictionary('form.disconnectWallet')}
</Button>
) : null}
</div>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormSubmitButton data-testid={ButtonDataTestId.Faucet_Submit}>
{dictionary('form.button', { tokenSymbol: SENT_SYMBOL })}
</FormSubmitButton>
</form>
</Form>
{transactionHash ? successMessage(transactionHash) : null}
{address ? <div className="my-6 w-11/12 border" /> : null}
{address ? (
<div className="flex flex-col gap-4">
<p className="text-sm font-normal">
{dictionary('addTokenInfo', { tokenSymbol: SENT_SYMBOL })}
</p>
<WalletAddTokenWithLocales variant="outline" />
</div>
) : null}
</ModuleContent>
</Module>
);
}
*/