From 2234c7eaad0bf7d6630ac6acddab089dc32e74da Mon Sep 17 00:00:00 2001 From: Alec Ananian <1013230+alecananian@users.noreply.github.com> Date: Wed, 10 Jul 2024 15:39:26 -0700 Subject: [PATCH] switch format/lint to biome; add knip code analyzer (#48) * add knip * replace prettier and eslint with biome --- .eslintignore | 3 - .eslintrc | 3 - .github/workflows/pr.yml | 4 +- .husky/pre-commit | 2 +- .prettierignore | 9 - .prettierrc | 14 - app/api/collections.server.ts | 16 +- app/api/pools.server.ts | 22 +- app/api/stats.server.ts | 2 +- app/api/tokens.server.ts | 38 +- app/api/user.server.ts | 6 +- app/assets/Svgs.tsx | 52 - app/components/Badge.tsx | 4 +- app/components/ConnectButton.tsx | 14 +- app/components/CurrencyInput.tsx | 4 +- app/components/DisabledInputPopover.tsx | 4 +- app/components/Footer.tsx | 6 +- app/components/FooterBars.tsx | 6 +- app/components/Icons.tsx | 49 +- app/components/Input.tsx | 35 - app/components/Landing/InfoCard.tsx | 10 +- app/components/Landing/StatisticCard.tsx | 10 +- app/components/Layout.tsx | 20 +- app/components/NumberInput.tsx | 15 +- app/components/PopupOverlay.tsx | 19 - app/components/SettingsDropdownMenu.tsx | 6 +- app/components/Table.tsx | 54 +- app/components/Tabs.tsx | 7 +- .../item_selection/SelectionPopup.tsx | 69 +- .../item_selection/TotalDisplayInner.tsx | 4 +- app/components/pools/PoolDepositTab.tsx | 54 +- app/components/pools/PoolImage.tsx | 2 +- app/components/pools/PoolInput.tsx | 15 +- app/components/pools/PoolNftTokenInput.tsx | 20 +- app/components/pools/PoolTokenImage.tsx | 4 +- app/components/pools/PoolTokenInput.tsx | 12 +- app/components/pools/PoolTransactionImage.tsx | 2 +- app/components/pools/PoolWithdrawTab.tsx | 28 +- app/components/swap/SwapRoutePanel.tsx | 8 +- app/components/ui/Button.tsx | 10 +- app/components/ui/Checkbox.tsx | 12 +- app/components/ui/Dialog.tsx | 25 +- app/components/ui/Dropdown.tsx | 47 +- app/components/ui/IconToggle.tsx | 10 +- app/components/ui/Input.tsx | 6 +- app/components/ui/Label.tsx | 2 +- app/components/ui/MultiSelect.tsx | 11 +- app/components/ui/NumberSelect.tsx | 10 +- app/components/ui/Popover.tsx | 10 +- app/components/ui/Sheet.tsx | 26 +- app/contexts/account.tsx | 2 +- app/entry.client.tsx | 2 +- app/entry.server.tsx | 20 +- app/hooks/useAddLiquidity.ts | 10 +- app/hooks/useApproval.ts | 2 +- app/hooks/useApprove.ts | 8 +- app/hooks/useIsApproved.ts | 2 +- app/hooks/usePoolTokenBalance.ts | 2 +- app/hooks/useRemoveLiquidity.ts | 10 +- app/hooks/useSwap.tsx | 24 +- app/hooks/useSwapRoute.ts | 14 +- app/hooks/useVaultItems.ts | 2 +- app/hooks/useWaitForTransaction.tsx | 26 +- app/lib/cache.server.ts | 6 +- app/lib/chain.server.ts | 4 +- app/lib/collections.server.ts | 2 +- app/lib/currency.test.ts | 2 +- app/lib/number.ts | 23 +- app/lib/og.server.tsx | 13 +- app/lib/pools.server.ts | 10 +- app/lib/pools.test.ts | 10 +- app/lib/pools.ts | 14 +- app/lib/seo.ts | 12 - app/lib/tokens.server.ts | 20 +- app/lib/tokens.test.ts | 2 +- app/lib/tokens.ts | 2 +- app/polyfills.ts | 2 - app/root.tsx | 20 +- app/routes/404.tsx | 20 +- app/routes/_index.tsx | 53 +- app/routes/pools.tsx | 14 +- app/routes/pools_.$id.tsx | 80 +- app/routes/pools_.$id[.]png.tsx | 8 +- app/routes/privacy.tsx | 26 +- app/routes/resources.session.ts | 4 +- app/routes/swap.$tokenIn.$tokenOut[.]png.tsx | 2 +- app/routes/swap.tsx | 80 +- app/sessions.ts | 18 +- app/store/settings.tsx | 7 +- biome.json | 41 + env.d.ts | 2 +- global.d.ts | 2 +- knip.json | 9 + package-lock.json | 3198 +++-------------- package.json | 18 +- public/site.webmanifest | 34 +- 96 files changed, 1116 insertions(+), 3587 deletions(-) delete mode 100644 .eslintignore delete mode 100644 .eslintrc delete mode 100644 .prettierignore delete mode 100644 .prettierrc delete mode 100644 app/components/Input.tsx delete mode 100644 app/components/PopupOverlay.tsx create mode 100644 biome.json create mode 100644 knip.json diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 5ee373f..0000000 --- a/.eslintignore +++ /dev/null @@ -1,3 +0,0 @@ -app/generated.ts -build/ -tailwind.config.js \ No newline at end of file diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index 4eac665..0000000 --- a/.eslintrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "extends": ["@remix-run/eslint-config", "plugin:@typescript-eslint/recommended", "prettier"] -} diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 5863b07..7f7950a 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -19,8 +19,8 @@ jobs: MAGICSWAPV2_API_URL: ${{ vars.MAGICSWAPV2_API_URL }} - name: Lint code run: npm run lint - # - name: Analyze code - # run: npm run knip + - name: Analyze code + run: npm run knip - name: Test code run: npm test - name: Check types diff --git a/.husky/pre-commit b/.husky/pre-commit index 2312dc5..bb25e7a 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1 +1 @@ -npx lint-staged +npx lint-staged && npm run knip diff --git a/.prettierignore b/.prettierignore deleted file mode 100644 index 554a08f..0000000 --- a/.prettierignore +++ /dev/null @@ -1,9 +0,0 @@ -.cache/ -.github/ -.graphclient/ -.husky/ -app/generated.ts -node_modules/ -public/ -.dockerignore -.prettierignore diff --git a/.prettierrc b/.prettierrc deleted file mode 100644 index 76b44ba..0000000 --- a/.prettierrc +++ /dev/null @@ -1,14 +0,0 @@ -{ - "plugins": [ - "@trivago/prettier-plugin-sort-imports", - "prettier-plugin-tailwindcss" - ], - "printWidth": 80, - "trailingComma": "es5", - "tabWidth": 2, - "semi": true, - "singleQuote": false, - "importOrder": ["", "^[./~]"], - "importOrderSeparation": true, - "importOrderSortSpecifiers": true -} diff --git a/app/api/collections.server.ts b/app/api/collections.server.ts index 85a50d9..378a45b 100644 --- a/app/api/collections.server.ts +++ b/app/api/collections.server.ts @@ -1,4 +1,3 @@ -import { fetchTroveTokenMapping } from "./tokens.server"; import { getCachedValue } from "~/lib/cache.server"; import { ENV } from "~/lib/env.server"; import type { @@ -7,6 +6,7 @@ import type { TroveCollectionMapping, TroveTokenMapping, } from "~/types"; +import { fetchTroveTokenMapping } from "./tokens.server"; /** * Fetches NFT collection metadata @@ -19,7 +19,7 @@ const fetchCollections = (addresses: string[]) => "slugs", addresses .map((address) => `${ENV.TROVE_API_NETWORK}/${address}`) - .join(",") + .join(","), ); const response = await fetch(url.toString(), { @@ -32,13 +32,13 @@ const fetchCollections = (addresses: string[]) => }); export const fetchTokensCollections = async ( - tokens: Token[] + tokens: Token[], ): Promise<[TroveCollectionMapping, TroveTokenMapping]> => { const addresses = [ ...new Set( tokens.flatMap(({ vaultCollections }) => - vaultCollections.map(({ collection }) => collection.id) - ) + vaultCollections.map(({ collection }) => collection.id), + ), ), ]; @@ -47,9 +47,9 @@ export const fetchTokensCollections = async ( tokens.flatMap(({ vaultCollections }) => vaultCollections.flatMap( ({ collection: { id: address }, tokenIds }) => - tokenIds?.map((tokenId) => `${address}/${tokenId}`) ?? [] - ) - ) + tokenIds?.map((tokenId) => `${address}/${tokenId}`) ?? [], + ), + ), ), ]; diff --git a/app/api/pools.server.ts b/app/api/pools.server.ts index 8451cd1..6fa8f77 100644 --- a/app/api/pools.server.ts +++ b/app/api/pools.server.ts @@ -1,5 +1,11 @@ import type { ExecutionResult } from "graphql"; +import { uniswapV2PairAbi } from "~/generated"; +import { client } from "~/lib/chain.server"; +import type { Pool } from "~/lib/pools.server"; +import { createPoolFromPair } from "~/lib/pools.server"; +import { itemToTroveTokenItem } from "~/lib/tokens.server"; +import type { AddressString, Pair } from "~/types"; import { GetPairDocument, type GetPairQuery, @@ -12,12 +18,6 @@ import { import { fetchTokensCollections } from "./collections.server"; import { fetchMagicUSD } from "./stats.server"; import { fetchTroveTokenMapping } from "./tokens.server"; -import { uniswapV2PairAbi } from "~/generated"; -import { client } from "~/lib/chain.server"; -import type { Pool } from "~/lib/pools.server"; -import { createPoolFromPair } from "~/lib/pools.server"; -import { itemToTroveTokenItem } from "~/lib/tokens.server"; -import type { AddressString, Pair } from "~/types"; export const fetchTransactions = async (pool: Pool) => { const result = (await execute(GetPairTransactionsDocument, { @@ -29,10 +29,10 @@ export const fetchTransactions = async (pool: Pool) => { ...new Set([ ...transactions.flatMap((transaction) => [ ...(transaction.items0?.map( - ({ collection, tokenId }) => `${collection.id}/${tokenId}` + ({ collection, tokenId }) => `${collection.id}/${tokenId}`, ) ?? []), ...(transaction.items1?.map( - ({ collection, tokenId }) => `${collection.id}/${tokenId}` + ({ collection, tokenId }) => `${collection.id}/${tokenId}`, ) ?? []), ]), ]), @@ -55,7 +55,7 @@ export const createPoolsFromPairs = async (pairs: Pair[]) => { const [[collectionMapping, tokenMapping], magicUSD, reserves] = await Promise.all([ fetchTokensCollections( - pairs.flatMap(({ token0, token1 }) => [token0, token1]) + pairs.flatMap(({ token0, token1 }) => [token0, token1]), ), fetchMagicUSD(), client.multicall({ @@ -78,7 +78,7 @@ export const createPoolsFromPairs = async (pairs: Pair[]) => { magicUSD, reserve?.status === "success" ? [reserve.result[0], reserve.result[1]] - : undefined + : undefined, ); }); }; @@ -86,7 +86,7 @@ export const createPoolsFromPairs = async (pairs: Pair[]) => { export const fetchPools = async () => { const result = (await execute( GetPairsDocument, - {} + {}, )) as ExecutionResult; const { pairs = [] } = result.data ?? {}; return createPoolsFromPairs(pairs); diff --git a/app/api/stats.server.ts b/app/api/stats.server.ts index 33291bc..086ceb9 100644 --- a/app/api/stats.server.ts +++ b/app/api/stats.server.ts @@ -5,7 +5,7 @@ import { GetStatsDocument, type GetStatsQuery, execute } from ".graphclient"; export const fetchStats = async () => { const result = (await execute( GetStatsDocument, - {} + {}, )) as ExecutionResult; const { factories = [] } = result.data ?? {}; return factories[0]; diff --git a/app/api/tokens.server.ts b/app/api/tokens.server.ts index 17c6dfd..4b82ebd 100644 --- a/app/api/tokens.server.ts +++ b/app/api/tokens.server.ts @@ -1,5 +1,10 @@ import type { ExecutionResult } from "graphql"; +import { sumArray } from "~/lib/array"; +import { getCachedValue } from "~/lib/cache.server"; +import { ENV } from "~/lib/env.server"; +import { createPoolToken } from "~/lib/tokens.server"; +import type { PoolToken, TroveToken, TroveTokenMapping } from "~/types"; import { fetchTokensCollections } from "./collections.server"; import { fetchMagicUSD } from "./stats.server"; import { @@ -11,11 +16,6 @@ import { type GetTokensQuery, execute, } from ".graphclient"; -import { sumArray } from "~/lib/array"; -import { getCachedValue } from "~/lib/cache.server"; -import { ENV } from "~/lib/env.server"; -import { createPoolToken } from "~/lib/tokens.server"; -import type { PoolToken, TroveToken, TroveTokenMapping } from "~/types"; /** * Fetches tokens available for swapping with NFT metadata and USD prices @@ -23,7 +23,7 @@ import type { PoolToken, TroveToken, TroveTokenMapping } from "~/types"; export const fetchTokens = async () => { const result = (await execute( GetTokensDocument, - {} + {}, )) as ExecutionResult; const { tokens: rawTokens = [] } = result.data ?? {}; const [[collectionMapping, tokenMapping], magicUSD] = await Promise.all([ @@ -31,7 +31,7 @@ export const fetchTokens = async () => { fetchMagicUSD(), ]); return rawTokens.map((token) => - createPoolToken(token, collectionMapping, tokenMapping, magicUSD) + createPoolToken(token, collectionMapping, tokenMapping, magicUSD), ); }; @@ -80,8 +80,12 @@ const fetchTroveTokens = async (ids: string[]) => export const fetchTroveTokenMapping = async (ids: string[]) => { const tokens = await fetchTroveTokens(ids); return tokens.reduce((acc, token) => { - const collection = (acc[token.collectionAddr.toLowerCase()] ??= {}); - collection[token.tokenId] = token; + const address = token.collectionAddr.toLowerCase(); + if (!acc[address]) { + acc[address] = {}; + } + + acc[address][token.tokenId] = token; return acc; }, {} as TroveTokenMapping); }; @@ -91,14 +95,14 @@ export const fetchTroveTokenMapping = async (ids: string[]) => { */ export const fetchPoolTokenBalance = async ( token: PoolToken, - address: string + address: string, ) => { const url = new URL(`${ENV.TROVE_API_URL}/tokens-for-user`); url.searchParams.append("userAddress", address); url.searchParams.append("projection", "queryUserQuantityOwned"); const tokenIds = token.collections.flatMap(({ id, tokenIds }) => - tokenIds.map((tokenId) => `${ENV.TROVE_API_NETWORK}/${id}/${tokenId}`) + tokenIds.map((tokenId) => `${ENV.TROVE_API_NETWORK}/${id}/${tokenId}`), ); if (tokenIds.length > 0) { url.searchParams.append("ids", tokenIds.join(",")); @@ -107,7 +111,7 @@ export const fetchPoolTokenBalance = async ( "slugs", token.collections .map(({ id }) => `${ENV.TROVE_API_NETWORK}/${id}`) - .join(",") + .join(","), ); } @@ -147,8 +151,8 @@ export const fetchVaultUserInventory = async ({ token.vaultCollections.flatMap( ({ collection: { id: collectionId }, tokenIds }) => tokenIds?.map( - (tokenId) => `${ENV.TROVE_API_NETWORK}/${collectionId}/${tokenId}` - ) ?? [] + (tokenId) => `${ENV.TROVE_API_NETWORK}/${collectionId}/${tokenId}`, + ) ?? [], ) ?? []; if (tokenIds.length > 0) { url.searchParams.append("ids", tokenIds.join(",")); @@ -158,9 +162,9 @@ export const fetchVaultUserInventory = async ({ token.vaultCollections .map( ({ collection: { id: collectionId } }) => - `${ENV.TROVE_API_NETWORK}/${collectionId}` + `${ENV.TROVE_API_NETWORK}/${collectionId}`, ) - .join(",") + .join(","), ); } @@ -199,7 +203,7 @@ export const fetchVaultReserveItems = async ({ acc[`${collectionId.toLowerCase()}/${tokenId}`] = amount; return acc; }, - {} as Record + {} as Record, ); // Fetch token metadata diff --git a/app/api/user.server.ts b/app/api/user.server.ts index 12f4de5..30815b6 100644 --- a/app/api/user.server.ts +++ b/app/api/user.server.ts @@ -1,10 +1,10 @@ import type { ExecutionResult } from "graphql"; -import { createPoolsFromPairs } from "./pools.server"; -import { GetUserDocument, type GetUserQuery, execute } from ".graphclient"; import { getCachedValue } from "~/lib/cache.server"; import { ENV } from "~/lib/env.server"; import type { AccountDomains } from "~/types"; +import { createPoolsFromPairs } from "./pools.server"; +import { GetUserDocument, type GetUserQuery, execute } from ".graphclient"; export const fetchUser = async (address: string) => { const result = (await execute(GetUserDocument, { @@ -18,7 +18,7 @@ export const fetchUser = async (address: string) => { return { ...user, pools: await createPoolsFromPairs( - user.liquidityPositions.map(({ pair }) => pair) + user.liquidityPositions.map(({ pair }) => pair), ), }; }; diff --git a/app/assets/Svgs.tsx b/app/assets/Svgs.tsx index d0ee4ce..b33aa60 100644 --- a/app/assets/Svgs.tsx +++ b/app/assets/Svgs.tsx @@ -2,58 +2,6 @@ interface Props { className?: string; } -export const ExchangeIcon = ({ className }: Props) => ( - - - -); - -export const FlatMagicIcon = ({ className }: Props) => ( - - - - - -); - -export const ChartIcon = ({ className }: Props) => ( - - - - - -); - export const RoyaltiesIcon = ({ className }: Props) => ( (
{children} diff --git a/app/components/ConnectButton.tsx b/app/components/ConnectButton.tsx index 0f509f0..40feca6 100644 --- a/app/components/ConnectButton.tsx +++ b/app/components/ConnectButton.tsx @@ -4,11 +4,11 @@ import { AnimatePresence, motion } from "framer-motion"; import { ChevronDown } from "lucide-react"; import { useEffect, useState } from "react"; -import { LoaderIcon } from "./Icons"; -import { Button } from "./ui/Button"; import { truncateEthAddress } from "~/lib/address"; import type { DomainLoader } from "~/routes/resources.domain"; import type { AddressString } from "~/types"; +import { LoaderIcon } from "./Icons"; +import { Button } from "./ui/Button"; export const ConnectButton = () => ( @@ -29,7 +29,7 @@ const ConnectedButton = ({ address }: { address: AddressString }) => { const [error, setError] = useState(false); const truncatedAddress = truncateEthAddress(address); - const domain = data && data.ok ? data.domain : null; + const domain = data?.ok ? data.domain : null; const preferredDomainType = domain?.preferredDomainType ?? "address"; const domainType = domain?.[preferredDomainType]; const name = @@ -50,7 +50,7 @@ const ConnectedButton = ({ address }: { address: AddressString }) => { return (
@@ -92,7 +92,11 @@ const ConnectedButton = ({ address }: { address: AddressString }) => {
-
diff --git a/app/components/CurrencyInput.tsx b/app/components/CurrencyInput.tsx index 77e1dba..0efe4e8 100644 --- a/app/components/CurrencyInput.tsx +++ b/app/components/CurrencyInput.tsx @@ -1,7 +1,7 @@ import type { InputHTMLAttributes } from "react"; -import { Input } from "./ui/Input"; import { cn } from "~/lib/utils"; +import { Input } from "./ui/Input"; type Props = Omit< InputHTMLAttributes, @@ -31,7 +31,7 @@ export const CurrencyInput = ({ type="text" className={cn( "h-auto border-none p-0 text-right text-base focus-visible:ring-0 focus-visible:ring-offset-0", - className + className, )} placeholder="0.00" value={value === "0" ? "" : value} diff --git a/app/components/DisabledInputPopover.tsx b/app/components/DisabledInputPopover.tsx index 55610b8..6895a46 100644 --- a/app/components/DisabledInputPopover.tsx +++ b/app/components/DisabledInputPopover.tsx @@ -6,12 +6,12 @@ import { Popover, PopoverContent, PopoverTrigger } from "./ui/Popover"; export const DisabledInputPopover = () => ( - -

+

Input is disabled because the amount will be auto-calculated based on the selected NFTs. diff --git a/app/components/Footer.tsx b/app/components/Footer.tsx index 1af8579..f45fdc5 100644 --- a/app/components/Footer.tsx +++ b/app/components/Footer.tsx @@ -85,7 +85,7 @@ export const Footer = () => {

-

+

The gateway to the cross-game{" "} economy @@ -115,7 +115,7 @@ export const Footer = () => {
{Object.keys(FooterPoints).map((key: string) => (
-

{key}

+

{key}

{FooterPoints[key]?.map((link: LinkType) => ( {
-

+

Copyright © {new Date().getFullYear()} Magicswap. All rights reserved.

diff --git a/app/components/FooterBars.tsx b/app/components/FooterBars.tsx index 80bd89f..c43db65 100644 --- a/app/components/FooterBars.tsx +++ b/app/components/FooterBars.tsx @@ -8,17 +8,17 @@ export const DiscordSupportBar = () => { return (
-

+

Still have Questions?

-

+

Join our community on Discord and find out more!

Messages of discord users helping each other
- ); -}; - -export default PopupOverlay; diff --git a/app/components/SettingsDropdownMenu.tsx b/app/components/SettingsDropdownMenu.tsx index c69b53d..3749b14 100644 --- a/app/components/SettingsDropdownMenu.tsx +++ b/app/components/SettingsDropdownMenu.tsx @@ -1,14 +1,14 @@ import { SettingsIcon } from "lucide-react"; import { memo, useRef } from "react"; -import { NumberInput } from "./NumberInput"; -import { Button } from "./ui/Button"; import { Popover, PopoverContent, PopoverTrigger, } from "~/components/ui/Popover"; import { useSettingsStore } from "~/store/settings"; +import { NumberInput } from "./NumberInput"; +import { Button } from "./ui/Button"; export const SettingsDropdownMenu = memo(() => { const state = useSettingsStore(); @@ -62,7 +62,7 @@ export const SettingsDropdownMenu = memo(() => { errorCondition={(value) => value > 60} >
- Minutes + Minutes
diff --git a/app/components/Table.tsx b/app/components/Table.tsx index 52ef2ac..aba5084 100644 --- a/app/components/Table.tsx +++ b/app/components/Table.tsx @@ -1,7 +1,3 @@ -import { AnimatePresence, motion } from "framer-motion"; -import { CheckIcon, CopyIcon } from "lucide-react"; -import React, { useState } from "react"; - import { cn } from "~/lib/utils"; interface TableItem { @@ -14,11 +10,11 @@ interface TableProps { children?: React.ReactNode; } -const Table = ({ children, items }: TableProps) => { +export const Table = ({ children, items }: TableProps) => { return (
-
- +
+
{items.map((item) => ( { ); }; - -interface CopyTableProps { - label: string; - value: string; -} - -export const CopyTable = ({ label, value }: CopyTableProps) => { - const [showCopied, setShowCopied] = useState(false); - const copyHandler = () => { - navigator.clipboard.writeText(value); - setShowCopied(true); - setTimeout(() => { - setShowCopied(false); - }, 1000); - }; - - return ( -
-

{label}

-
-

{value}

- - - {showCopied && ( - - Copied - - - )} - -
-
- ); -}; - -export default Table; diff --git a/app/components/Tabs.tsx b/app/components/Tabs.tsx index 79434cb..79f65f0 100644 --- a/app/components/Tabs.tsx +++ b/app/components/Tabs.tsx @@ -26,10 +26,11 @@ export const Tabs = ({ {tabs.map(({ id, title }) => (
  • diff --git a/app/components/item_selection/SelectionPopup.tsx b/app/components/item_selection/SelectionPopup.tsx index da416fb..aa58438 100644 --- a/app/components/item_selection/SelectionPopup.tsx +++ b/app/components/item_selection/SelectionPopup.tsx @@ -6,14 +6,10 @@ import { RotateCwIcon as RefreshIcon, XIcon, } from "lucide-react"; -import React, { useState } from "react"; +import type React from "react"; +import { useState } from "react"; import { useAccount } from "wagmi"; -import { CheckIcon, LoaderIcon } from "../Icons"; -import { PoolTokenImage } from "../pools/PoolTokenImage"; -import { Button } from "../ui/Button"; -import IconToggle from "../ui/IconToggle"; -import { NumberSelect } from "../ui/NumberSelect"; import { DialogClose, DialogContent } from "~/components/ui/Dialog"; import { useTrove } from "~/hooks/useTrove"; import { useVaultItems } from "~/hooks/useVaultItems"; @@ -21,6 +17,11 @@ import { formatNumber } from "~/lib/number"; import { countTokens } from "~/lib/tokens"; import { cn } from "~/lib/utils"; import type { PoolToken, TroveToken, TroveTokenWithQuantity } from "~/types"; +import { CheckIcon, LoaderIcon } from "../Icons"; +import { PoolTokenImage } from "../pools/PoolTokenImage"; +import { Button } from "../ui/Button"; +import IconToggle from "../ui/IconToggle"; +import { NumberSelect } from "../ui/NumberSelect"; const ItemCard = ({ selected, @@ -46,11 +47,11 @@ const ItemCard = ({
    {selected && ( -
    +
    )} @@ -60,11 +61,11 @@ const ItemCard = ({ alt={item.tokenId} className={cn( "w-full", - !viewOnly && !disableUnselected && "group-hover:opacity-75" + !viewOnly && !disableUnselected && "group-hover:opacity-75", )} /> {quantity > 1 ? ( - + {formatNumber(quantity)}x ) : null} @@ -72,10 +73,10 @@ const ItemCard = ({ {!compact ? (
    -

    +

    {item.metadata.name}

    -

    #{item.tokenId}

    +

    #{item.tokenId}

    { enabled: token.isNFT, }); const [selectedItems, setSelectedItems] = useState( - !props.viewOnly ? props.selectedTokens ?? [] : [] + !props.viewOnly ? props.selectedTokens ?? [] : [], ); const [isCompactMode, setIsCompactMode] = useState(false); const selectedQuantity = selectedItems.reduce( (acc, curr) => acc + curr.quantity, - 0 + 0, ); const selectionDisabled = !props.viewOnly && props.limit ? selectedQuantity >= props.limit : false; @@ -164,7 +166,7 @@ export const SelectionPopup = ({ token, type, ...props }: Props) => { const selectionHandler = (item: TroveTokenWithQuantity) => { if (selectedItems.some((i) => i.tokenId === item.tokenId)) { const itemIndex = selectedItems.findIndex( - (i) => i.tokenId === item.tokenId + (i) => i.tokenId === item.tokenId, ); setSelectedItems([ ...selectedItems.slice(0, itemIndex), @@ -181,20 +183,20 @@ export const SelectionPopup = ({ token, type, ...props }: Props) => { "h-full [grid-template-rows:auto_auto_1fr_1fr_25%] sm:max-w-8xl", !props.viewOnly ? "grid-areas-nft-modal-mobile lg:grid-areas-nft-modal lg:[grid-template-columns:repeat(4,1fr)_25%]" - : "grid-areas-nft-modal-viewonly" + : "grid-areas-nft-modal-viewonly", )} > -
    +

    {props.viewOnly ? "View" : "Select"}

    -

    +

    {token.name}{" "} - + from {type === "vault" ? "the Vault" : "your Inventory"}

    -
    +
    { onChange={(id) => setIsCompactMode(id === "compact")} />
    -
    +
    {isLoading ? (
    @@ -229,14 +232,14 @@ export const SelectionPopup = ({ token, type, ...props }: Props) => { "grid gap-3", isCompactMode ? "grid-cols-4 md:grid-cols-5 lg:grid-cols-6" - : "grid-cols-3 md:grid-cols-4 lg:grid-cols-5" + : "grid-cols-3 md:grid-cols-4 lg:grid-cols-5", )} > {items.map((item) => ( i.tokenId === item.tokenId + (i) => i.tokenId === item.tokenId, )} key={item.tokenId} item={item} @@ -250,7 +253,7 @@ export const SelectionPopup = ({ token, type, ...props }: Props) => { !props.viewOnly && props.limit ? Math.min( props.limit - selectedQuantity, - item.queryUserQuantityOwned ?? 1 + item.queryUserQuantityOwned ?? 1, ) : 1, }); @@ -262,9 +265,9 @@ export const SelectionPopup = ({ token, type, ...props }: Props) => {
    {!props.viewOnly && ( -
    +
    -

    +

    Selected assets

    {selectedItems.length > 0 ? ( @@ -290,10 +293,10 @@ export const SelectionPopup = ({ token, type, ...props }: Props) => {
    )}
    -

    +

    {item.metadata.name}

    -

    +

    #{item.tokenId}

    @@ -306,8 +309,8 @@ export const SelectionPopup = ({ token, type, ...props }: Props) => { prev.map((i) => i.tokenId === item.tokenId ? { ...i, quantity: num } - : i - ) + : i, + ), ); }} value={item.quantity} @@ -327,14 +330,14 @@ export const SelectionPopup = ({ token, type, ...props }: Props) => {
    ) : ( -

    +

    You haven't selected any assets yet.

    )}
    - Total + Total {!props.viewOnly && props.children && props.children({ diff --git a/app/components/item_selection/TotalDisplayInner.tsx b/app/components/item_selection/TotalDisplayInner.tsx index 69fc88e..958e6da 100644 --- a/app/components/item_selection/TotalDisplayInner.tsx +++ b/app/components/item_selection/TotalDisplayInner.tsx @@ -1,5 +1,5 @@ -import { PoolTokenImage } from "../pools/PoolTokenImage"; import type { Optional, PoolToken } from "~/types"; +import { PoolTokenImage } from "../pools/PoolTokenImage"; export const TotalDisplayInner = ({ token, @@ -10,6 +10,6 @@ export const TotalDisplayInner = ({ }) => ( - {total} + {total} ); diff --git a/app/components/pools/PoolDepositTab.tsx b/app/components/pools/PoolDepositTab.tsx index 7f4350d..5f5b4da 100644 --- a/app/components/pools/PoolDepositTab.tsx +++ b/app/components/pools/PoolDepositTab.tsx @@ -3,16 +3,6 @@ import { useCallback, useEffect, useState } from "react"; import { Balancer } from "react-wrap-balancer"; import { formatEther, formatUnits, parseUnits } from "viem"; -import Table from "../Table"; -import { SelectionPopup } from "../item_selection/SelectionPopup"; -import { TotalDisplayInner } from "../item_selection/TotalDisplayInner"; -import { TransactionButton } from "../ui/Button"; -import { LabeledCheckbox } from "../ui/Checkbox"; -import { Dialog } from "../ui/Dialog"; -import { Popover, PopoverContent, PopoverTrigger } from "../ui/Popover"; -import { PoolImage } from "./PoolImage"; -import { PoolNftTokenInput } from "./PoolNftTokenInput"; -import { PoolTokenInput } from "./PoolTokenInput"; import { useAccount } from "~/contexts/account"; import { useReadErc20BalanceOf } from "~/generated"; import { useAddLiquidity } from "~/hooks/useAddLiquidity"; @@ -31,6 +21,16 @@ import type { PoolToken, TroveTokenWithQuantity, } from "~/types"; +import { Table } from "../Table"; +import { SelectionPopup } from "../item_selection/SelectionPopup"; +import { TotalDisplayInner } from "../item_selection/TotalDisplayInner"; +import { TransactionButton } from "../ui/Button"; +import { LabeledCheckbox } from "../ui/Checkbox"; +import { Dialog } from "../ui/Dialog"; +import { Popover, PopoverContent, PopoverTrigger } from "../ui/Popover"; +import { PoolImage } from "./PoolImage"; +import { PoolNftTokenInput } from "./PoolNftTokenInput"; +import { PoolTokenInput } from "./PoolTokenInput"; type Props = { pool: Pool; @@ -61,7 +61,7 @@ export const PoolDepositTab = ({ const amount = parseUnits( rawAmount as NumberString, - isExactB ? pool.token1.decimals : pool.token0.decimals + isExactB ? pool.token1.decimals : pool.token0.decimals, ); const amountA = isExactB ? quote(amount, BigInt(pool.token1.reserve), BigInt(pool.token0.reserve)) @@ -148,7 +148,7 @@ export const PoolDepositTab = ({ const estimatedLp = getLpCountForTokens( amount, BigInt(pool.token0.reserve), - BigInt(pool.totalSupply) + BigInt(pool.totalSupply), ); useEffect(() => { @@ -164,15 +164,15 @@ export const PoolDepositTab = ({ }, [isApproveSuccess1, refetchApproval1]); const insufficientBalanceA = !pool.token0.isNFT - ? parseFloat( - isExactB ? formatUnits(amountA, pool.token0.decimals) : rawAmount - ) > parseFloat(formatEther(balance0 ?? 0n)) + ? Number.parseFloat( + isExactB ? formatUnits(amountA, pool.token0.decimals) : rawAmount, + ) > Number.parseFloat(formatEther(balance0 ?? 0n)) : false; const insufficientBalanceB = !pool.token1.isNFT - ? parseFloat( - !isExactB ? formatUnits(amountB, pool.token1.decimals) : rawAmount - ) > parseFloat(formatEther(balance1 ?? 0n)) + ? Number.parseFloat( + !isExactB ? formatUnits(amountB, pool.token1.decimals) : rawAmount, + ) > Number.parseFloat(formatEther(balance1 ?? 0n)) : false; return ( @@ -309,7 +309,7 @@ export const PoolDepositTab = ({ { label: "Estimated LP Tokens", value: ( -
    +
    {formatTokenAmount(estimatedLp)}
    @@ -322,7 +322,7 @@ export const PoolDepositTab = ({ ? bigIntToNumber(estimatedLp) / (bigIntToNumber(BigInt(pool.totalSupply)) + bigIntToNumber(estimatedLp)) - : 0 + : 0, ), }, ]} @@ -394,7 +394,7 @@ const TotalDisplay = ({ }) => { const amount = parseUnits( rawAmount as NumberString, - isExactB ? pool.token1.decimals : pool.token0.decimals + isExactB ? pool.token1.decimals : pool.token0.decimals, ); const amountA = isExactB @@ -406,11 +406,11 @@ const TotalDisplay = ({ const formattedTokenInAmount = formatTokenAmount( amountA, - pool.token0.decimals + pool.token0.decimals, ); const formattedTokenOutAmount = formatTokenAmount( amountB, - pool.token1?.decimals ?? 18 + pool.token1?.decimals ?? 18, ); return ( @@ -424,12 +424,16 @@ const TotalDisplay = ({ const ApproveAgainInfoPopover = () => ( - -

    +

    You will need to approve again because the amount you entered exceeds the amount you previously approved. diff --git a/app/components/pools/PoolImage.tsx b/app/components/pools/PoolImage.tsx index 45bb1c5..cbc503b 100644 --- a/app/components/pools/PoolImage.tsx +++ b/app/components/pools/PoolImage.tsx @@ -1,8 +1,8 @@ import type { HTMLAttributes } from "react"; -import { PoolTokenImage } from "./PoolTokenImage"; import type { Pool } from "~/lib/pools.server"; import { cn } from "~/lib/utils"; +import { PoolTokenImage } from "./PoolTokenImage"; type Props = HTMLAttributes & { pool: Pool; diff --git a/app/components/pools/PoolInput.tsx b/app/components/pools/PoolInput.tsx index 10989e6..9340831 100644 --- a/app/components/pools/PoolInput.tsx +++ b/app/components/pools/PoolInput.tsx @@ -1,11 +1,11 @@ import { formatEther } from "viem"; -import { CurrencyInput } from "../CurrencyInput"; -import { PoolImage } from "./PoolImage"; import { useAccount } from "~/contexts/account"; import { formatAmount, formatUSD } from "~/lib/currency"; import { bigIntToNumber, formatPercent } from "~/lib/number"; import type { Pool } from "~/lib/pools.server"; +import { CurrencyInput } from "../CurrencyInput"; +import { PoolImage } from "./PoolImage"; export const PoolInput = ({ pool, @@ -25,7 +25,7 @@ export const PoolInput = ({

    -

    {pool.name}

    +

    {pool.name}

    {pool.reserveUSD ? ( - + {formatUSD( (pool.reserveUSD / bigIntToNumber(BigInt(pool.totalSupply))) * (Number.isNaN(parsedAmount) || parsedAmount === 0 ? 1 - : Number(amount.replace(/,/g, ""))) + : Number(amount.replace(/,/g, ""))), )} ) : null} @@ -49,12 +49,13 @@ export const PoolInput = ({ {[0.25, 0.5, 0.75, 1].map((percent) => (
    {pool.isNFTNFT && (amountALeftover > 0 || amountBLeftover > 0) ? ( @@ -190,8 +190,8 @@ export const PoolWithdrawTab = ({ pool, balance, onSuccess }: Props) => { : BigInt(pool.token1.reserve), pool.token0.isNFT ? BigInt(pool.token1.reserve) - : BigInt(pool.token0.reserve) - ) + : BigInt(pool.token0.reserve), + ), )} {pool.token0.isNFT @@ -204,11 +204,11 @@ export const PoolWithdrawTab = ({ pool, balance, onSuccess }: Props) => { amountALeftover, pool.token0.isNFT ? pool.token0.decimals - : pool.token1.decimals + : pool.token1.decimals, ) * (pool.token0.isNFT ? pool.token0.priceUSD - : pool.token1.priceUSD) + : pool.token1.priceUSD), )}
    diff --git a/app/components/swap/SwapRoutePanel.tsx b/app/components/swap/SwapRoutePanel.tsx index 9868635..5d0a447 100644 --- a/app/components/swap/SwapRoutePanel.tsx +++ b/app/components/swap/SwapRoutePanel.tsx @@ -33,11 +33,11 @@ export const SwapRoutePanel = ({ return (
    -
    +
    1{" "} {tokenOut?.symbol} ={" "} @@ -81,7 +81,7 @@ export const SwapRoutePanel = ({ isExactOut ? amountIn - floorBigInt(amountIn) : amountOut - floorBigInt(amountOut), - isExactOut ? tokenIn.decimals : tokenOut.decimals + isExactOut ? tokenIn.decimals : tokenOut.decimals, )}{" "} {isExactOut ? tokenIn.symbol : tokenOut.symbol} diff --git a/app/components/ui/Button.tsx b/app/components/ui/Button.tsx index f63e317..73e514f 100644 --- a/app/components/ui/Button.tsx +++ b/app/components/ui/Button.tsx @@ -33,7 +33,7 @@ const buttonVariants = cva( variant: "default", size: "default", }, - } + }, ); interface ButtonProps @@ -44,12 +44,13 @@ const Button = React.forwardRef( ({ className, variant, size, ...props }, ref) => { return ( ); - } + }, ); CloseButton.displayName = "CloseButton"; @@ -124,4 +126,4 @@ export const TransactionButton = React.forwardRef< TransactionButton.displayName = "TransactionButton"; -export { Button, buttonVariants, CloseButton }; +export { Button }; diff --git a/app/components/ui/Checkbox.tsx b/app/components/ui/Checkbox.tsx index d6f0f99..0f87869 100644 --- a/app/components/ui/Checkbox.tsx +++ b/app/components/ui/Checkbox.tsx @@ -1,9 +1,9 @@ import * as CheckboxPrimitive from "@radix-ui/react-checkbox"; import * as React from "react"; +import { cn } from "~/lib/utils"; import { CheckIcon } from "../Icons"; import { Label } from "./Label"; -import { cn } from "~/lib/utils"; const Checkbox = React.forwardRef< React.ElementRef, @@ -12,8 +12,8 @@ const Checkbox = React.forwardRef< @@ -42,7 +42,7 @@ const LabeledCheckbox = ({ { "items-start": description, }, - className + className, )} > {description && ( -

    +

    {description}

    )} @@ -60,4 +60,4 @@ const LabeledCheckbox = ({
    ); -export { Checkbox, LabeledCheckbox }; +export { LabeledCheckbox }; diff --git a/app/components/ui/Dialog.tsx b/app/components/ui/Dialog.tsx index ef1fe14..0ec8a1d 100644 --- a/app/components/ui/Dialog.tsx +++ b/app/components/ui/Dialog.tsx @@ -2,8 +2,8 @@ import * as DialogPrimitive from "@radix-ui/react-dialog"; import { XIcon } from "lucide-react"; import * as React from "react"; -import { Button } from "./Button"; import { cn } from "~/lib/utils"; +import { Button } from "./Button"; const Dialog = DialogPrimitive.Root; @@ -11,7 +11,7 @@ const DialogTrigger = DialogPrimitive.Trigger; const DialogClose = DialogPrimitive.Close; -export const DialogPortal = ({ +const DialogPortal = ({ children, ...props }: DialogPrimitive.DialogPortalProps) => ( @@ -30,8 +30,8 @@ const DialogOverlay = React.forwardRef< @@ -48,8 +48,8 @@ const DialogContent = React.forwardRef< @@ -57,7 +57,7 @@ const DialogContent = React.forwardRef< @@ -198,7 +201,7 @@ export default function Homepage() {
    -

    +

    What makes Magicswap special?

    @@ -228,12 +231,12 @@ export default function Homepage() { animate={{ opacity: 1 }} >
    -

    - Role of $MAGIC +

    + Role of $MAGIC

    -

    +

    Magicswap utilizes{" "} - $MAGIC{" "} + $MAGIC{" "} as the governance and fee token. The protocol collects a{" "} 2.5% base fee{" "} for transactions with additional fees for projects and LPs set by @@ -242,19 +245,19 @@ export default function Homepage() { Magic Illustration -

    +
    -
    -

    +
    +

    Start trading today

    -

    +

    Explore our huge library of pools and get your desired NFTs!

    @@ -265,12 +268,12 @@ export default function Homepage() { Different collections on magicswap

    -
    +
    ); diff --git a/app/routes/pools.tsx b/app/routes/pools.tsx index 916a073..e8bcaef 100644 --- a/app/routes/pools.tsx +++ b/app/routes/pools.tsx @@ -65,23 +65,23 @@ const PoolsTable = ({ pools }: { pools: Pool[] }) => {
    - - - - - @@ -90,7 +90,7 @@ const PoolsTable = ({ pools }: { pools: Pool[] }) => { {pools.map((pool) => (
    + Name + Volume (24h) + APY + TVL + LP Fees
    -

    Pools

    +

    Pools

    Use your game assets to earn rewards by providing liquidity.

    diff --git a/app/routes/pools_.$id.tsx b/app/routes/pools_.$id.tsx index 8166e71..de23517 100644 --- a/app/routes/pools_.$id.tsx +++ b/app/routes/pools_.$id.tsx @@ -23,7 +23,8 @@ import { RepeatIcon, ArrowUpToLineIcon as WithdrawIcon, } from "lucide-react"; -import React, { +import type React from "react"; +import { Fragment, Suspense as ReactSuspense, useCallback, @@ -44,7 +45,7 @@ import { } from "~/api/tokens.server"; import { LoaderIcon } from "~/components/Icons"; import { SettingsDropdownMenu } from "~/components/SettingsDropdownMenu"; -import Table from "~/components/Table"; +import { Table } from "~/components/Table"; import { SelectionPopup } from "~/components/item_selection/SelectionPopup"; import { PoolDepositTab } from "~/components/pools/PoolDepositTab"; import { PoolImage } from "~/components/pools/PoolImage"; @@ -70,7 +71,7 @@ import { getPoolVolume24hDisplay, } from "~/lib/pools"; import type { Pool } from "~/lib/pools.server"; -import { generateTitle, generateUrl, getSocialMetas, getUrl } from "~/lib/seo"; +import { generateTitle, generateUrl, getSocialMetas } from "~/lib/seo"; import { cn } from "~/lib/utils"; import type { RootLoader } from "~/root"; import { getSession } from "~/sessions"; @@ -101,7 +102,7 @@ export const meta: MetaFunction< return getSocialMetas({ url, title: generateTitle( - `${pool?.token0.symbol}/${pool?.token1.symbol} Liquidity Pool` + `${pool?.token0.symbol}/${pool?.token1.symbol} Liquidity Pool`, ), description: `Provide liquidity for ${pool?.token0.symbol}/${pool?.token1.symbol} on Magicswap`, image: `${url}.png`, @@ -190,7 +191,7 @@ export default function PoolDetailsPage() {
    All Pools @@ -198,11 +199,11 @@ export default function PoolDetailsPage() {
    -
    +
    {pool.name} - + LP Fees: {formatPercent(pool.lpFee)}
    @@ -234,13 +235,13 @@ export default function PoolDetailsPage() { ) : null}
    -
    +

    {formatTokenAmount(lpBalance)}

    -

    +

    Current LP Token Balance

    @@ -255,7 +256,7 @@ export default function PoolDetailsPage() { token.symbol.toUpperCase() ? ( <>
    -

    +

    {token.symbol}

    @@ -272,20 +273,20 @@ export default function PoolDetailsPage() { lpShare * bigIntToNumber( BigInt(token.reserve), - token.decimals - ) + token.decimals, + ), )}

    {token.priceUSD > 0 ? ( -

    +

    {formatUSD( lpShare * bigIntToNumber( BigInt(token.reserve), - token.decimals + token.decimals, ) * - token.priceUSD + token.priceUSD, )}

    ) : null} @@ -333,12 +334,12 @@ export default function PoolDetailsPage() { {formatAmount( bigIntToNumber( BigInt(quoteToken.reserve), - quoteToken.decimals + quoteToken.decimals, ) / bigIntToNumber( BigInt(baseToken.reserve), - baseToken.decimals - ) + baseToken.decimals, + ), )} {" "} {quoteToken.symbol} @@ -360,16 +361,16 @@ export default function PoolDetailsPage() {

    {formatTokenAmount( BigInt(token.reserve), - token.decimals + token.decimals, )}

    {token.priceUSD > 0 ? ( -

    +

    {formatUSD( bigIntToNumber( BigInt(token.reserve), - token.decimals - ) * token.priceUSD + token.decimals, + ) * token.priceUSD, )}

    ) : null} @@ -463,9 +464,10 @@ export default function PoolDetailsPage() { ).map(({ label, value }) => (
    -
    +
    @@ -528,7 +530,7 @@ const PoolManagementView = ({
    -

    +

    Add Liquidity

    @@ -605,7 +607,7 @@ const PoolActivityTable = ({
    - + @@ -673,7 +675,7 @@ const PoolActivityTable = ({ - -
    Tokens
    -
    +
    {tx.amountUSD !== "0" ? formatUSD(tx.amountUSD) : "-"}
    + {truncateEthAddress(tx.user.id)} + {new Date( - Number(tx.timestamp) * 1000 + Number(tx.timestamp) * 1000, ).toLocaleString()} @@ -777,7 +779,7 @@ const PoolActivityTable = ({