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/my token interaction #9

Open
wants to merge 11 commits into
base: master
Choose a base branch
from

Conversation

andriy-shymkiv
Copy link
Owner

@andriy-shymkiv andriy-shymkiv commented Feb 25, 2024

Summary by CodeRabbit

  • New Features
    • Updated the React component to display token details and enable various token-related operations.
    • Introduced a custom hook for interacting with token contracts on the Ethereum blockchain.
    • Added a custom hook for fetching transaction history for a specified address.
  • Enhancements
    • Included a new constant for improved network and token management.
    • Defined environment variables for easier configuration.

Copy link

vercel bot commented Feb 25, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
swap-tokens-dapp ✅ Ready (Inspect) Visit Preview 💬 Add feedback Mar 7, 2024 4:38pm

Copy link

coderabbitai bot commented Feb 25, 2024

Walkthrough

The recent changes introduce a comprehensive update to enhance token interactions, transaction history fetching, and environment variable management in the application.

Changes

Files Change Summary
src/components/MyTokenScreen.tsx, hooks/useMyToken.ts Updated MyTokenScreen to manage token details and added hooks for token contract interaction.
hooks/useTransactionHistory.tsx Introduced useTransactionHistory hook for fetching transaction history.
utils/constants.ts, store/appSlice.ts Added constants SEPOLIA_CHAIN_ID, MY_TOKEN, and enum value MY_TOKEN.
utils/env.ts Added functionality for defining environment variables.

🐰✨
In code's garden, fresh changes bloom,
Where tokens dance and hooks find room.
History fetched, constants new,
Our app evolves with a vibrant hue.
Hop along, devs, in this digital zoom!
🌟🐾

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share

Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • Generate unit-tests for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit tests for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit tests.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger a review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • The JSON schema for the configuration file is available here.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/coderabbit-overrides.v2.json

CodeRabbit Discord Community

Join our Discord Community to get help, request features, and share feedback.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Status

Actionable comments generated: 0

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between de0b4b2 and 18d253d.
Files ignored due to path filters (3)
  • package.json is excluded by: !**/*.json
  • pnpm-lock.yaml is excluded by: !**/*.yaml
  • src/abis/mytoken.json is excluded by: !**/*.json
Files selected for processing (7)
  • src/App.tsx (4 hunks)
  • src/components/MyTokenScreen.tsx (1 hunks)
  • src/components/SwapTokensScreen.tsx (4 hunks)
  • src/components/UnsupportedNetworkScreen.tsx (1 hunks)
  • src/hooks/useMyToken.ts (1 hunks)
  • src/store/appSlice.ts (1 hunks)
  • src/utils/constants.ts (2 hunks)
Additional comments: 10
src/components/UnsupportedNetworkScreen.tsx (1)
  • 30-30: The addition of textAlign: 'center' to the Box component is a good UI enhancement for aligning content in the center. This change improves the visual presentation and user experience on unsupported networks.
src/App.tsx (2)
  • 10-10: The import of MyTokenScreen aligns with the PR objectives to enhance the application's token management functionalities. Good addition.
  • 66-66: The inclusion of MyTokenScreen in the application's navigation logic is a significant enhancement, enabling users to interact with and manage their tokens directly. This change effectively integrates the new screen into the app.
src/utils/constants.ts (2)
  • 75-75: The addition of SEPOLIA_CHAIN_ID is appropriate for supporting interactions with the Sepolia testnet, facilitating development and testing.
  • 92-92: Introducing a constant for MY_TOKEN with a specific contract address is a good practice for managing contract interactions, making the code more readable and maintainable.
src/store/appSlice.ts (1)
  • 13-13: Adding MY_TOKEN to the AppScreen enum is a necessary step for integrating the new MyTokenScreen into the application's navigation logic. This change supports the PR's objectives of enhancing token management functionalities.
src/components/SwapTokensScreen.tsx (4)
  • 14-16: The introduction of useIsNetworkSupported hook and UnsupportedNetworkScreen component in SwapTokensScreen is a good practice for handling network support checks and improving user experience on unsupported networks.
  • 25-30: Adding a StyledGoToMyTokenButton with specific styling enhances the UI consistency and user experience by providing a visually distinct button for navigating to the MyTokenScreen.
  • 78-99: The conditional rendering based on chainId for the StyledGoToMyTokenButton, using a Tooltip to indicate availability only for Sepolia, is a thoughtful UI enhancement. It guides users effectively and prevents confusion on unsupported networks.
  • 96-120: The conditional rendering to display either the UnsupportedNetworkScreen or the swap tokens interface based on network support is a crucial enhancement. It ensures users are informed and guided correctly when their network is not supported, improving the overall user experience.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Status

Actionable comments generated: 1

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 18d253d and 50d4037.
Files selected for processing (3)
  • src/App.tsx (4 hunks)
  • src/components/MyTokenScreen.tsx (1 hunks)
  • src/hooks/useMyToken.ts (1 hunks)
Files skipped from review as they are similar to previous changes (2)
  • src/App.tsx
  • src/hooks/useMyToken.ts
Additional comments: 2
src/components/MyTokenScreen.tsx (2)
  • 1-13: The imports are well-organized, separating external libraries, hooks, utilities, and components. This organization enhances readability and maintainability.
  • 19-26: The StyledTxButton component is a good example of customizing Material UI components using the styled API. This approach keeps the styling consistent and reusable across different parts of the application.

Comment on lines 28 to 322
size="small"
name="amount"
placeholder="amount"
value={values.amount}
onChange={handleChange}
/>
</Box>
</Box>
</Form>
)}
</Formik>

<Formik
initialValues={{
to: '',
amount: '',
}}
onSubmit={({ to, amount }) => {
if (!isAddress(to) || !amount) {
showSnackbar({
message: 'Invalid address or amount',
severity: 'error',
});
} else {
mint({
to,
amount: parseUnits(amount, 18),
});
}
}}
>
{({ values, handleChange, handleSubmit }) => (
<Form onSubmit={handleSubmit} style={{ width: '100%' }}>
<Box display={'flex'} justifyContent={'space-between'} alignItems={'center'} gap={4}>
<StyledTxButton variant="contained" type="submit">
{'mint'}
</StyledTxButton>
<Box display={'flex'} flexDirection={'column'} gap={1}>
<TextField size="small" name="to" placeholder="address" value={values.to} onChange={handleChange} />
<TextField
size="small"
name="amount"
placeholder="amount"
value={values.amount}
onChange={handleChange}
/>
</Box>
</Box>
</Form>
)}
</Formik>
<Formik
initialValues={{
from: '',
amount: '',
}}
onSubmit={({ from, amount }) => {
if (!isAddress(from) || !amount) {
showSnackbar({
message: 'Invalid address or amount',
severity: 'error',
});
} else {
burnFrom({
from,
amount: parseUnits(amount, 18),
});
}
}}
>
{({ values, handleChange, handleSubmit }) => (
<Form onSubmit={handleSubmit} style={{ width: '100%' }}>
<Box display={'flex'} justifyContent={'space-between'} alignItems={'center'} gap={4}>
<StyledTxButton variant="contained" type="submit">
{'burnFrom'}
</StyledTxButton>
<Box display={'flex'} flexDirection={'column'} gap={1}>
<TextField
size="small"
name="from"
placeholder="address"
value={values.from}
onChange={handleChange}
/>
<TextField
size="small"
name="amount"
placeholder="amount"
value={values.amount}
onChange={handleChange}
/>
</Box>
</Box>
</Form>
)}
</Formik>
</Box>
</Box>
</Box>
);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The MyTokenScreen component is comprehensive, covering various aspects of token management. However, there are several areas where improvements can be made for better maintainability, readability, and performance:

  1. Code Duplication in Formik Components: There's noticeable duplication in the Formik components used for managing the blacklist, transferring tokens, minting, and burning. Consider abstracting the common logic into a reusable component or function to reduce duplication and improve maintainability.

  2. Error Handling: While the showSnackbar function is used to display errors for invalid addresses or amounts, consider adding more robust error handling for the asynchronous operations performed by the hooks (e.g., transfer, mint, burnFrom, manageBlackList). This could involve catching errors from these operations and displaying appropriate error messages to the user.

  3. Validation Logic: The validation for addresses and amounts is performed inline within the onSubmit functions of the Formik components. Extracting this validation logic into a separate utility function or using Formik's validation schema feature could improve code readability and reusability.

  4. UI Feedback for Asynchronous Operations: There's no UI feedback (e.g., loading indicators or disabled buttons) provided to the user during the execution of asynchronous operations like transferring, minting, or burning tokens. Implementing such feedback could enhance the user experience by making the application feel more responsive and informative.

  5. Hardcoded Strings: There are several hardcoded strings throughout the component (e.g., 'addToBlackList', 'removeFromBlackList', 'transfer', 'mint', 'burnFrom'). Moving these strings to a constants file could improve maintainability and make it easier to support multiple languages in the future.

  6. Use of Magic Numbers: The number 18 is used as a magic number in multiple places for formatting and parsing units. Consider defining this as a constant to improve readability and maintainability.

- {formatUnits(value || 0, 18)}
+ const DECIMALS = 18;
+ {formatUnits(value || 0, DECIMALS)}
  1. Styling Consistency: Ensure that the styling across different Formik components is consistent. For example, the style attribute is used directly in one of the Formik components but not in others. Consider using styled components or a consistent approach to applying styles.

  2. Accessibility: Ensure that form elements have associated labels for better accessibility. This can be achieved by using the InputLabel component from Material UI or the aria-label attribute.


Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
export const MyTokenScreen = (): JSX.Element => {
const { account } = useWeb3React();
const { showSnackbar } = useSnackbar();
const { data: details, isLoading: isDetailsLoading } = useMyTokenDetails();
const { data: isAdmin, isLoading: isAdminLoading } = useIsAdmin(account);
const { data: isBlackListed, isLoading: isBlackListedLoading } = useIsBlackListed(account);
const { data: balanceOf, isLoading: isBalanceOfLoading } = useBalanceOf(account);
const { data: allowance, isLoading: isAllowanceLoading } = useAllowance(account);
const { mutate: transfer } = useTransfer();
const { mutate: mint } = useMint();
const { mutate: burnFrom } = useBurnFrom();
const { mutate: manageBlackList } = useManageBlackList();
return (
<Box display={'flex'} flexDirection={'column'} gap={6}>
<Box>
Basic details:
{isDetailsLoading ? (
<CircularProgress size={20} thickness={8} />
) : (
Object.entries(details || {}).map(([key, value]) => (
<Box key={`${key}_${value}`}>
<Typography key={key} display="inline" color={(theme) => theme.palette.info.main}>
{key}:
</Typography>{' '}
<Typography display="inline" fontWeight={700}>
{key === 'totalSupply' ? formatUnits(value || 0, 18) : value.toString()}
</Typography>
</Box>
))
)}
</Box>
<Box>
{getEllipsisString(account)}:
<Box>
<Typography display="inline" color={(theme) => theme.palette.info.main}>
{'hasRole(ADMIN_ROLE):'}
</Typography>{' '}
{isAdminLoading ? (
<CircularProgress size={20} thickness={8} />
) : isAdmin ? (
<Typography display="inline" fontWeight={700} color={(theme) => theme.palette.success.main}>
{'true'}
</Typography>
) : (
<Typography display="inline" fontWeight={700} color={(theme) => theme.palette.info.main}>
{'false'}
</Typography>
)}
</Box>
<Box>
<Typography display="inline" color={(theme) => theme.palette.info.main}>
{'blackList:'}
</Typography>{' '}
{isBlackListedLoading ? (
<CircularProgress size={20} thickness={8} />
) : isBlackListed ? (
<Typography display="inline" fontWeight={700} color={(theme) => theme.palette.error.main}>
{'true'}
</Typography>
) : (
<Typography display="inline" fontWeight={700} color={(theme) => theme.palette.success.main}>
{'false'}
</Typography>
)}
</Box>
<Box>
<Typography display="inline" color={(theme) => theme.palette.info.main}>
{'balanceOf:'}
</Typography>{' '}
{isBalanceOfLoading ? (
<CircularProgress size={20} thickness={8} />
) : (
<Typography display="inline" fontWeight={700}>
{formatUnits(balanceOf || 0, 18)}
</Typography>
)}
</Box>
<Box>
<Typography display="inline" color={(theme) => theme.palette.info.main}>
{'allowance:'}
</Typography>{' '}
{isAllowanceLoading ? (
<CircularProgress size={20} thickness={8} />
) : (
<Typography display="inline" fontWeight={700}>
{formatUnits(allowance || 0, 18)}
</Typography>
)}
</Box>
<Box display={'flex'} flexDirection={'column'} gap={2}>
<Formik
initialValues={{
account: '',
}}
onSubmit={({ account }) => {
if (!isAddress(account)) {
showSnackbar({
message: 'Invalid address',
severity: 'error',
});
} else {
manageBlackList({
action: 'add',
account,
});
}
}}
>
{({ values, handleChange, handleSubmit }) => (
<Form onSubmit={handleSubmit}>
<Box display={'flex'} justifyContent={'space-between'} alignItems={'center'} gap={4}>
<StyledTxButton variant="contained" type="submit">
{'addToBlackList'}
</StyledTxButton>
<Box display={'flex'} flexDirection={'column'} gap={1}>
<TextField
size="small"
name="account"
placeholder="address"
value={values.account}
onChange={handleChange}
/>
</Box>
</Box>
</Form>
)}
</Formik>
<Formik
initialValues={{
account: '',
}}
onSubmit={({ account }) => {
if (!isAddress(account)) {
showSnackbar({
message: 'Invalid address',
severity: 'error',
});
} else {
manageBlackList({
action: 'remove',
account,
});
}
}}
>
{({ values, handleChange, handleSubmit }) => (
<Form onSubmit={handleSubmit}>
<Box display={'flex'} justifyContent={'space-between'} alignItems={'center'} gap={4}>
<StyledTxButton variant="contained" type="submit">
{'removeFromBlackList'}
</StyledTxButton>
<Box display={'flex'} flexDirection={'column'} gap={1}>
<TextField
size="small"
name="account"
placeholder="address"
value={values.account}
onChange={handleChange}
/>
</Box>
</Box>
</Form>
)}
</Formik>
<Formik
initialValues={{
to: '',
amount: '',
}}
onSubmit={({ to, amount }) => {
if (!isAddress(to) || !amount) {
showSnackbar({
message: 'Invalid address or amount',
severity: 'error',
});
} else {
transfer({
to,
amount: parseUnits(amount, 18),
});
}
}}
>
{({ values, handleChange, handleSubmit }) => (
<Form onSubmit={handleSubmit} style={{ width: '100%' }}>
<Box display={'flex'} justifyContent={'space-between'} alignItems={'center'} gap={4}>
<StyledTxButton variant="contained" type="submit">
{'transfer'}
</StyledTxButton>
<Box display={'flex'} flexDirection={'column'} gap={1}>
<TextField size="small" name="to" placeholder="address" value={values.to} onChange={handleChange} />
<TextField
size="small"
name="amount"
placeholder="amount"
value={values.amount}
onChange={handleChange}
/>
</Box>
</Box>
</Form>
)}
</Formik>
<Formik
initialValues={{
to: '',
amount: '',
}}
onSubmit={({ to, amount }) => {
if (!isAddress(to) || !amount) {
showSnackbar({
message: 'Invalid address or amount',
severity: 'error',
});
} else {
mint({
to,
amount: parseUnits(amount, 18),
});
}
}}
>
{({ values, handleChange, handleSubmit }) => (
<Form onSubmit={handleSubmit} style={{ width: '100%' }}>
<Box display={'flex'} justifyContent={'space-between'} alignItems={'center'} gap={4}>
<StyledTxButton variant="contained" type="submit">
{'mint'}
</StyledTxButton>
<Box display={'flex'} flexDirection={'column'} gap={1}>
<TextField size="small" name="to" placeholder="address" value={values.to} onChange={handleChange} />
<TextField
size="small"
name="amount"
placeholder="amount"
value={values.amount}
onChange={handleChange}
/>
</Box>
</Box>
</Form>
)}
</Formik>
<Formik
initialValues={{
from: '',
amount: '',
}}
onSubmit={({ from, amount }) => {
if (!isAddress(from) || !amount) {
showSnackbar({
message: 'Invalid address or amount',
severity: 'error',
});
} else {
burnFrom({
from,
amount: parseUnits(amount, 18),
});
}
}}
>
{({ values, handleChange, handleSubmit }) => (
<Form onSubmit={handleSubmit} style={{ width: '100%' }}>
<Box display={'flex'} justifyContent={'space-between'} alignItems={'center'} gap={4}>
<StyledTxButton variant="contained" type="submit">
{'burnFrom'}
</StyledTxButton>
<Box display={'flex'} flexDirection={'column'} gap={1}>
<TextField
size="small"
name="from"
placeholder="address"
value={values.from}
onChange={handleChange}
/>
<TextField
size="small"
name="amount"
placeholder="amount"
value={values.amount}
onChange={handleChange}
/>
</Box>
</Box>
</Form>
)}
</Formik>
</Box>
</Box>
</Box>
);
export const MyTokenScreen = (): JSX.Element => {
const { account } = useWeb3React();
const { showSnackbar } = useSnackbar();
const { data: details, isLoading: isDetailsLoading } = useMyTokenDetails();
const { data: isAdmin, isLoading: isAdminLoading } = useIsAdmin(account);
const { data: isBlackListed, isLoading: isBlackListedLoading } = useIsBlackListed(account);
const { data: balanceOf, isLoading: isBalanceOfLoading } = useBalanceOf(account);
const { data: allowance, isLoading: isAllowanceLoading } = useAllowance(account);
const { mutate: transfer } = useTransfer();
const { mutate: mint } = useMint();
const { mutate: burnFrom } = useBurnFrom();
const { mutate: manageBlackList } = useManageBlackList();
const DECIMALS = 18;
return (
<Box display={'flex'} flexDirection={'column'} gap={6}>
<Box>
Basic details:
{isDetailsLoading ? (
<CircularProgress size={20} thickness={8} />
) : (
Object.entries(details || {}).map(([key, value]) => (
<Box key={`${key}_${value}`}>
<Typography key={key} display="inline" color={(theme) => theme.palette.info.main}>
{key}:
</Typography>{' '}
<Typography display="inline" fontWeight={700}>
{key === 'totalSupply' ? formatUnits(value || 0, DECIMALS) : value.toString()}
</Typography>
</Box>
))
)}
</Box>
<Box>
{getEllipsisString(account)}:
<Box>
<Typography display="inline" color={(theme) => theme.palette.info.main}>
{'hasRole(ADMIN_ROLE):'}
</Typography>{' '}
{isAdminLoading ? (
<CircularProgress size={20} thickness={8} />
) : isAdmin ? (
<Typography display="inline" fontWeight={700} color={(theme) => theme.palette.success.main}>
{'true'}
</Typography>
) : (
<Typography display="inline" fontWeight={700} color={(theme) => theme.palette.info.main}>
{'false'}
</Typography>
)}
</Box>
<Box>
<Typography display="inline" color={(theme) => theme.palette.info.main}>
{'blackList:'}
</Typography>{' '}
{isBlackListedLoading ? (
<CircularProgress size={20} thickness={8} />
) : isBlackListed ? (
<Typography display="inline" fontWeight={700} color={(theme) => theme.palette.error.main}>
{'true'}
</Typography>
) : (
<Typography display="inline" fontWeight={700} color={(theme) => theme.palette.success.main}>
{'false'}
</Typography>
)}
</Box>
<Box>
<Typography display="inline" color={(theme) => theme.palette.info.main}>
{'balanceOf:'}
</Typography>{' '}
{isBalanceOfLoading ? (
<CircularProgress size={20} thickness={8} />
) : (
<Typography display="inline" fontWeight={700}>
{formatUnits(balanceOf || 0, DECIMALS)}
</Typography>
)}
</Box>
<Box>
<Typography display="inline" color={(theme) => theme.palette.info.main}>
{'allowance:'}
</Typography>{' '}
{isAllowanceLoading ? (
<CircularProgress size={20} thickness={8} />
) : (
<Typography display="inline" fontWeight={700}>
{formatUnits(allowance || 0, DECIMALS)}
</Typography>
)}
</Box>
<Box display={'flex'} flexDirection={'column'} gap={2}>
<Formik
initialValues={{
account: '',
}}
onSubmit={({ account }) => {
if (!isAddress(account)) {
showSnackbar({
message: 'Invalid address',
severity: 'error',
});
} else {
manageBlackList({
action: 'add',
account,
});
}
}}
>
{({ values, handleChange, handleSubmit }) => (
<Form onSubmit={handleSubmit}>
<Box display={'flex'} justifyContent={'space-between'} alignItems={'center'} gap={4}>
<StyledTxButton variant="contained" type="submit">
{'addToBlackList'}
</StyledTxButton>
<Box display={'flex'} flexDirection={'column'} gap={1}>
<TextField
size="small"
name="account"
placeholder="address"
value={values.account}
onChange={handleChange}
/>
</Box>
</Box>
</Form>
)}
</Formik>
<Formik
initialValues={{
account: '',
}}
onSubmit={({ account }) => {
if (!isAddress(account)) {
showSnackbar({
message: 'Invalid address',
severity: 'error',
});
} else {
manageBlackList({
action: 'remove',
account,
});
}
}}
>
{({ values, handleChange, handleSubmit }) => (
<Form onSubmit={handleSubmit}>
<Box display={'flex'} justifyContent={'space-between'} alignItems={'center'} gap={4}>
<StyledTxButton variant="contained" type="submit">
{'removeFromBlackList'}
</StyledTxButton>
<Box display={'flex'} flexDirection={'column'} gap={1}>
<TextField
size="small"
name="account"
placeholder="address"
value={values.account}
onChange={handleChange}
/>
</Box>
</Box>
</Form>
)}
</Formik>
<Formik
initialValues={{
to: '',
amount: '',
}}
onSubmit={({ to, amount }) => {
if (!isAddress(to) || !amount) {
showSnackbar({
message: 'Invalid address or amount',
severity: 'error',
});
} else {
transfer({
to,
amount: parseUnits(amount, DECIMALS),
});
}
}}
>
{({ values, handleChange, handleSubmit }) => (
<Form onSubmit={handleSubmit} style={{ width: '100%' }}>
<Box display={'flex'} justifyContent={'space-between'} alignItems={'center'} gap={4}>
<StyledTxButton variant="contained" type="submit">
{'transfer'}
</StyledTxButton>
<Box display={'flex'} flexDirection={'column'} gap={1}>
<TextField size="small" name="to" placeholder="address" value={values.to} onChange={handleChange} />
<TextField
size="small"
name="amount"
placeholder="amount"
value={values.amount}
onChange={handleChange}
/>
</Box>
</Box>
</Form>
)}
</Formik>
<Formik
initialValues={{
to: '',
amount: '',
}}
onSubmit={({ to, amount }) => {
if (!isAddress(to) || !amount) {
showSnackbar({
message: 'Invalid address or amount',
severity: 'error',
});
} else {
mint({
to,
amount: parseUnits(amount, DECIMALS),
});
}
}}
>
{({ values, handleChange, handleSubmit }) => (
<Form onSubmit={handleSubmit} style={{ width: '100%' }}>
<Box display={'flex'} justifyContent={'space-between'} alignItems={'center'} gap={4}>
<StyledTxButton variant="contained" type="submit">
{'mint'}
</StyledTxButton>
<Box display={'flex'} flexDirection={'column'} gap={1}>
<TextField size="small" name="to" placeholder="address" value={values.to} onChange={handleChange} />
<TextField
size="small"
name="amount"
placeholder="amount"
value={values.amount}
onChange={handleChange}
/>
</Box>
</Box>
</Form>
)}
</Formik>
<Formik
initialValues={{
from: '',
amount: '',
}}
onSubmit={({ from, amount }) => {
if (!isAddress(from) || !amount) {
showSnackbar({
message: 'Invalid address or amount',
severity: 'error',
});
} else {
burnFrom({
from,
amount: parseUnits(amount, DECIMALS),
});
}
}}
>
{({ values, handleChange, handleSubmit }) => (
<Form onSubmit={handleSubmit} style={{ width: '100%' }}>
<Box display={'flex'} justifyContent={'space-between'} alignItems={'center'} gap={4}>
<StyledTxButton variant="contained" type="submit">
{'burnFrom'}
</StyledTxButton>
<Box display={'flex'} flexDirection={'column'} gap={1}>
<TextField
size="small"
name="from"
placeholder="address"
value={values.from}
onChange={handleChange}
/>
<TextField
size="small"
name="amount"
placeholder="amount"
value={values.amount}
onChange={handleChange}
/>
</Box>
</Box>
</Form>
)}
</Formik>
</Box>
</Box>
</Box>
);

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Status

Actionable comments generated: 3

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 50d4037 and d73d312.
Files selected for processing (5)
  • src/components/MyTokenScreen.tsx (1 hunks)
  • src/hooks/useMyToken.ts (1 hunks)
  • src/hooks/useTransactionHistory.tsx (1 hunks)
  • src/utils/constants.ts (2 hunks)
  • src/utils/env.ts (1 hunks)
Files skipped from review as they are similar to previous changes (3)
  • src/components/MyTokenScreen.tsx
  • src/hooks/useMyToken.ts
  • src/utils/constants.ts
Additional comments: 2
src/hooks/useTransactionHistory.tsx (2)
  • 1-4: The import statements are well-organized, and importing necessary utilities from external libraries and local files is done correctly. This ensures that the hook has access to all the required functionalities.
  • 7-33: The useTransactionHistory hook is well-implemented, making good use of the useQuery hook from @tanstack/react-query for fetching transaction history. The configuration for caching and stale time is appropriate, enhancing the performance by reducing unnecessary API calls.

Repository owner deleted a comment from coderabbitai bot Feb 26, 2024
Repository owner deleted a comment from coderabbitai bot Feb 26, 2024
Repository owner deleted a comment from coderabbitai bot Feb 26, 2024
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Status

Actionable comments generated: 0

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between d73d312 and 1ed9e04.
Files selected for processing (1)
  • src/components/MyTokenScreen.tsx (1 hunks)
Files skipped from review as they are similar to previous changes (1)
  • src/components/MyTokenScreen.tsx

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Status

Actionable comments generated: 2

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 1ed9e04 and 1e1e5ef.
Files selected for processing (1)
  • src/hooks/useMyToken.ts (1 hunks)
Additional comments: 9
src/hooks/useMyToken.ts (9)
  • 33-60: The useMyTokenDetails hook fetches details about the token such as name, symbol, decimals, and totalSupply. It's important to ensure that the hook correctly handles cases where myToken might be null or the contract calls fail.

Ensure that the contract calls within this hook are properly handled in case of failure (e.g., the contract method returns undefined or throws an error). This might involve adding error handling logic or ensuring that the UI can gracefully handle incomplete or missing data.

  • 63-72: The useIsAdmin hook checks if a given address has the admin role. It's crucial to ensure that the role checking mechanism is secure and correctly implemented.

Verify that the myToken?.hasRole?.(myToken?.ADMIN_ROLE?.(), address) call correctly checks for the admin role and consider handling cases where myToken or address might be undefined to prevent runtime errors.

  • 75-84: The useIsBlackListed hook checks if a given address is blacklisted. Similar to useIsAdmin, it's important to ensure that the blacklist checking mechanism is secure and correctly implemented.

Confirm that the myToken?.blackList?.(address) call correctly checks for blacklisted addresses and consider adding error handling for cases where myToken or address might be undefined.

  • 87-95: The useBalanceOf hook fetches the token balance of a given address. Ensuring accuracy and security in balance queries is essential.

Ensure that the myToken?.balanceOf?.(address) call accurately fetches the token balance and consider adding error handling for cases where myToken or address might be undefined.

  • 98-106: The useAllowance hook checks the allowance of a token for a given address. It's important to ensure that the allowance checking mechanism is secure and correctly implemented.

Verify that the myToken?.allowance?.(address, address) call correctly checks for token allowance and consider handling cases where myToken or address might be undefined to prevent runtime errors.

  • 109-126: The useManageBlackList hook allows adding or removing addresses from the blacklist. It's crucial to ensure that this functionality is secure and only accessible to authorized users.

Confirm that the blacklist management functionality is properly secured and consider adding more detailed error handling to provide users with specific feedback based on the error encountered.

  • 129-145: The useTransfer hook enables token transfers. Ensuring the security and correctness of token transfers is paramount.

Ensure that the myToken?.transfer?.(to, amount) call correctly performs token transfers and consider adding error handling for cases where myToken, to, or amount might be undefined or invalid.

  • 148-164: The useMint hook allows minting new tokens. It's important to ensure that this functionality is secure and only accessible to authorized users.

Verify that the minting functionality is properly secured and consider adding more detailed error handling to provide users with specific feedback based on the error encountered.

  • 167-183: The useBurnFrom hook enables burning tokens from a specified address. Ensuring the security and correctness of token burning is crucial.

Ensure that the myToken?.burnFrom?.(from, amount) call correctly performs token burning and consider adding error handling for cases where myToken, from, or amount might be undefined or invalid.

import { MY_TOKEN } from '~/utils/constants';
import { useSnackbar } from './useSnackbar';

// the most of this hooks probably will be deleted after pdp
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment on line 10 mentions that most of these hooks will probably be deleted after PDP (Product Development Phase). It's important to track such TODOs or temporary comments to ensure they are addressed before moving to production.

Would you like me to help track this task or remind you to review these hooks before production deployment?

Comment on lines +22 to +25
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
// todo: need to fix type mismatch between ethers and @web3-react
provider.getSigner(),
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use of @ts-ignore to bypass TypeScript type checking is generally discouraged as it can hide potential type mismatches or errors. It's mentioned that there's a need to fix a type mismatch between ethers and @web3-react. It's crucial to address this issue properly to ensure type safety and avoid runtime errors.

Consider resolving the type mismatch by defining appropriate types or using type assertions that are more specific than @ts-ignore. This approach will help maintain type safety and code quality.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant