diff --git a/README.md b/README.md index 9ef18b5b..6aeb4d36 100644 --- a/README.md +++ b/README.md @@ -15,3 +15,14 @@ ## Overview Monarch is an unofficial user interface designed for composing custom lending strategies on [Morpho Blue](https://github.com/morpho-org/morpho-blue). It enables you to compose your own lending strategies by bundling multiple markets, each with your defined risk parameters. Access Morpho Blue directly without intermediaries, maintaining full control over your lending positions. + +## Core Features + +🔍 **Market Analysis**: Easily evaluate risk of markets with real-time data, interactive graphs, and oracle breakdown + +💱 **Smart Reallocation**: Move funds seamlessly between markets to maximize yield + +📊 **Performance Report**: Generate detailed earnings reports from any selected period, aggregating all market positions into a single view + +🤖 **Automation** (Beta): Delegate operations to [Monarch Agents](https://github.com/monarch-xyz/monarch-agents) to automate reallocations + diff --git a/app/history/components/HistoryContent.tsx b/app/history/components/HistoryContent.tsx index 03e2619d..d7ad8dd7 100644 --- a/app/history/components/HistoryContent.tsx +++ b/app/history/components/HistoryContent.tsx @@ -13,7 +13,7 @@ export default function HistoryContent({ account }: { account: string }) { return (
-
+

Transaction History

{loading ? ( diff --git a/app/layout.tsx b/app/layout.tsx index 8b0e247d..8a1888b4 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -25,14 +25,14 @@ export default function RootLayout({ children }: { children: React.ReactNode }) return ( - - + + {children} - - + + diff --git a/app/markets/components/markets.tsx b/app/markets/components/markets.tsx index e6ff05b6..fef6d346 100644 --- a/app/markets/components/markets.tsx +++ b/app/markets/components/markets.tsx @@ -321,7 +321,7 @@ export default function Markets() { return (
-
+

Markets

{showSupplyModal && ( diff --git a/app/positions/components/PositionsContent.tsx b/app/positions/components/PositionsContent.tsx index e8cf8db7..c2d49fb0 100644 --- a/app/positions/components/PositionsContent.tsx +++ b/app/positions/components/PositionsContent.tsx @@ -1,7 +1,6 @@ 'use client'; import { useMemo, useState } from 'react'; -import { Name } from '@coinbase/onchainkit/identity'; import Link from 'next/link'; import { useParams } from 'next/navigation'; import { FaHistory, FaPlus, FaCircle } from 'react-icons/fa'; @@ -9,6 +8,7 @@ import { TbReport } from 'react-icons/tb'; import { useAccount } from 'wagmi'; import { Avatar } from '@/components/Avatar/Avatar'; import { Button } from '@/components/common/Button'; +import { Name } from '@/components/common/Name'; import Header from '@/components/layout/header/Header'; import EmptyScreen from '@/components/Status/EmptyScreen'; import LoadingScreen from '@/components/Status/LoadingScreen'; @@ -45,9 +45,9 @@ export default function Positions() { return (
-
-
-

Portfolio

+
+
+

Portfolio

diff --git a/app/positions/components/onboarding/AssetSelection.tsx b/app/positions/components/onboarding/AssetSelection.tsx index 5cfbd4aa..137f350d 100644 --- a/app/positions/components/onboarding/AssetSelection.tsx +++ b/app/positions/components/onboarding/AssetSelection.tsx @@ -1,4 +1,5 @@ import { useMemo } from 'react'; +// import { Tooltip } from '@nextui-org/tooltip'; import { motion } from 'framer-motion'; import Image from 'next/image'; import Link from 'next/link'; diff --git a/app/providers.tsx b/app/providers.tsx index 86e17d5c..169decf1 100644 --- a/app/providers.tsx +++ b/app/providers.tsx @@ -5,7 +5,13 @@ import { ThemeProvider as NextThemesProvider } from 'next-themes'; export function Providers({ children }: { children: React.ReactNode }) { return ( - + {children} ); diff --git a/app/rewards/components/RewardContent.tsx b/app/rewards/components/RewardContent.tsx index f75e8200..80639e95 100644 --- a/app/rewards/components/RewardContent.tsx +++ b/app/rewards/components/RewardContent.tsx @@ -24,8 +24,6 @@ export default function Rewards() { const { loading, markets } = useMarkets(); const { rewards, distributions, loading: loadingRewards } = useUserRewards(account); - console.log('distributions', distributions); - const marketRewards = useMemo(() => filterMarketRewards(rewards), [rewards]); const uniformRewards = useMemo(() => filterUniformRewards(rewards), [rewards]); @@ -53,11 +51,10 @@ export default function Rewards() { return (
- -
-
-
Rewards
-
+
+
+

Reward

+
Morpho offers multiple reward programs to incentivize user participation. Choose a program type below to see more details.
diff --git a/app/settings/page.tsx b/app/settings/page.tsx index 29a5450d..38f7be83 100644 --- a/app/settings/page.tsx +++ b/app/settings/page.tsx @@ -15,13 +15,13 @@ export default function SettingsPage() { return (
-
+

Settings

{/* Transaction Settings Section */}
-

Transaction Settings

+

Transaction Settings

@@ -48,8 +48,8 @@ export default function SettingsPage() {
{/* Filter Settings Section */} -
-

Filter Settings

+
+

Filter Settings

{/* Group related settings with a subtle separator */} diff --git a/package.json b/package.json index e0f60157..83d2ff0c 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,6 @@ "test:coverage:open": "yarn test:coverage && open coverage/lcov-report/index.html" }, "dependencies": { - "@coinbase/onchainkit": "0.10.0", "@coinbase/wallet-sdk": "^3.9.1", "@nextui-org/accordion": "^2.0.35", "@nextui-org/button": "^2.0.34", diff --git a/src/OnchainProviders.tsx b/src/OnchainProviders.tsx index fcc5ddd6..ea39c519 100644 --- a/src/OnchainProviders.tsx +++ b/src/OnchainProviders.tsx @@ -20,19 +20,22 @@ if (!projectId) { const wagmiConfig = createWagmiConfig(projectId); -/** - * Monarch - * TODO Docs ~~~ - */ function OnchainProviders({ children }: Props) { return ( {children} diff --git a/src/components/ButtonGroup.tsx b/src/components/ButtonGroup.tsx index 7ca36287..f4be5115 100644 --- a/src/components/ButtonGroup.tsx +++ b/src/components/ButtonGroup.tsx @@ -26,7 +26,6 @@ const sizeClasses = { const variantStyles = { default: (isSelected: boolean) => [ isSelected ? 'bg-hovered hover:bg-surface z-10' : 'bg-surface hover:bg-hovered', - 'border border-divider', 'shadow-sm', ], primary: (isSelected: boolean) => [ diff --git a/src/components/SearchOrConnect/SearchOrConnect.tsx b/src/components/SearchOrConnect/SearchOrConnect.tsx index 6fbbf335..61f73c6f 100644 --- a/src/components/SearchOrConnect/SearchOrConnect.tsx +++ b/src/components/SearchOrConnect/SearchOrConnect.tsx @@ -17,7 +17,7 @@ export default function SearchOrConnect({ path }: { path: string }) { return (
-
+
Connect wallet or search an account to continue. diff --git a/src/components/common/Name.tsx b/src/components/common/Name.tsx new file mode 100644 index 00000000..6451df0b --- /dev/null +++ b/src/components/common/Name.tsx @@ -0,0 +1,23 @@ +'use client'; + +import { useEnsName } from 'wagmi'; + +type NameProps = { + address: `0x${string}`; + className?: string; +}; + +export function Name({ address, className = '' }: NameProps) { + const { data: ensName, isLoading } = useEnsName({ + address, + chainId: 1, + }); + + if (isLoading) { + return ...; + } + + return ( + {ensName ?? `${address.slice(0, 6)}...${address.slice(-4)}`} + ); +} diff --git a/src/components/layout/header/AccountConnect.tsx b/src/components/layout/header/AccountConnect.tsx index d6ac5d93..438c38c5 100644 --- a/src/components/layout/header/AccountConnect.tsx +++ b/src/components/layout/header/AccountConnect.tsx @@ -1,5 +1,6 @@ import { ConnectButton } from '@rainbow-me/rainbowkit'; import '@rainbow-me/rainbowkit/styles.css'; +import { Button } from '@/components/common'; import { AccountDropdown } from './AccountDropdown'; /** @@ -34,13 +35,9 @@ function AccountConnect() { {(() => { if (!connected) { return ( - + ); } diff --git a/src/components/layout/header/AccountDropdown.tsx b/src/components/layout/header/AccountDropdown.tsx index a03f952f..3f547ba7 100644 --- a/src/components/layout/header/AccountDropdown.tsx +++ b/src/components/layout/header/AccountDropdown.tsx @@ -1,5 +1,6 @@ +'use client'; + import { useCallback, useState } from 'react'; -import { Name } from '@coinbase/onchainkit/identity'; import * as DropdownMenu from '@radix-ui/react-dropdown-menu'; import { ExitIcon, ExternalLinkIcon } from '@radix-ui/react-icons'; import { clsx } from 'clsx'; @@ -8,6 +9,7 @@ import { usePathname } from 'next/navigation'; import { FiSettings } from 'react-icons/fi'; import { useAccount, useDisconnect } from 'wagmi'; import { Avatar } from '@/components/Avatar/Avatar'; +import { Name } from '@/components/common/Name'; import { getSlicedAddress } from '@/utils/address'; import { getExplorerURL } from '@/utils/external'; diff --git a/src/components/layout/header/Navbar.test.tsx b/src/components/layout/header/Navbar.test.tsx deleted file mode 100644 index c6b2be64..00000000 --- a/src/components/layout/header/Navbar.test.tsx +++ /dev/null @@ -1,20 +0,0 @@ -/** - * @jest-environment jsdom - */ -import { render, screen, waitFor } from '@testing-library/react'; -import OnchainProviders from '@/OnchainProviders'; -import Navbar from './Navbar'; - -describe('Navbar', () => { - it('mounts', async () => { - render( - - - , - ); - - await waitFor(() => { - expect(screen.getByText('Get Started')).toBeInTheDocument(); - }); - }); -}); diff --git a/src/components/layout/header/Navbar.tsx b/src/components/layout/header/Navbar.tsx index efb7c7c4..f4f90264 100644 --- a/src/components/layout/header/Navbar.tsx +++ b/src/components/layout/header/Navbar.tsx @@ -1,11 +1,14 @@ 'use client'; +import { useEffect, useState } from 'react'; import { clsx } from 'clsx'; import Image from 'next/image'; import NextLink from 'next/link'; import { usePathname } from 'next/navigation'; import { useTheme } from 'next-themes'; -import { FaRegMoon, FaSun } from 'react-icons/fa'; +import { FaRegMoon } from 'react-icons/fa'; +import { LuSunMedium } from 'react-icons/lu'; + import { useAccount } from 'wagmi'; import logo from '../../imgs/logo.png'; import AccountConnect from './AccountConnect'; @@ -62,6 +65,15 @@ export function NavbarTitle() { export function Navbar() { const { theme, setTheme } = useTheme(); const { address } = useAccount(); + const [mounted, setMounted] = useState(false); + + useEffect(() => { + setMounted(true); + }, []); + + const toggleTheme = () => { + setTheme(theme === 'dark' ? 'light' : 'dark'); + }; return (
diff --git a/src/components/layout/header/NavbarMobile.test.tsx b/src/components/layout/header/NavbarMobile.test.tsx deleted file mode 100644 index f1398cb9..00000000 --- a/src/components/layout/header/NavbarMobile.test.tsx +++ /dev/null @@ -1,31 +0,0 @@ -/** - * @jest-environment jsdom - */ -import { render, screen, waitFor } from '@testing-library/react'; -import userEvent from '@testing-library/user-event'; -import OnchainProviders from '@/OnchainProviders'; -import NavbarMobile from './NavbarMobile'; - -describe('NavbarMobile', () => { - it('mounts', () => { - render( - - - , - ); - expect(screen.getByText('BUILD ONCHAIN APPS')).toBeInTheDocument(); - }); - - it('clicking the hamburger icon opens the navbar menu', async () => { - render( - - - , - ); - await userEvent.click(screen.getByRole('button')); - - await waitFor(() => { - expect(screen.getByText('Get Started')).toBeInTheDocument(); - }); - }); -}); diff --git a/src/hooks/useTransactionWithToast.tsx b/src/hooks/useTransactionWithToast.tsx index d5d841c9..2b66fa03 100644 --- a/src/hooks/useTransactionWithToast.tsx +++ b/src/hooks/useTransactionWithToast.tsx @@ -37,8 +37,6 @@ export function useTransactionWithToast({ hash, }); - console.log('isConfirmed', isConfirmed, toastId, hash); - const onClick = useCallback(() => { if (hash) { // if chainId is not supported, use 1 diff --git a/src/store/createWagmiConfig.ts b/src/store/createWagmiConfig.ts index 3e4a9b62..9380af0c 100644 --- a/src/store/createWagmiConfig.ts +++ b/src/store/createWagmiConfig.ts @@ -7,6 +7,8 @@ import { safeWallet, argentWallet, injectedWallet, + trustWallet, + ledgerWallet, } from '@rainbow-me/rainbowkit/wallets'; import { createConfig, http } from 'wagmi'; import { base, mainnet } from 'wagmi/chains'; @@ -27,12 +29,14 @@ export function createWagmiConfig(projectId: string) { { groupName: 'Other Wallets', wallets: [ + metaMaskWallet, rainbowWallet, coinbaseWallet, - metaMaskWallet, safeWallet, argentWallet, injectedWallet, + trustWallet, + ledgerWallet, ], }, ], diff --git a/yarn.lock b/yarn.lock index ddb43faf..bfabc1f0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1516,21 +1516,6 @@ __metadata: languageName: node linkType: hard -"@coinbase/onchainkit@npm:0.10.0": - version: 0.10.0 - resolution: "@coinbase/onchainkit@npm:0.10.0" - peerDependencies: - "@tanstack/react-query": ^5 - "@xmtp/frames-validator": ^0.5.0 - graphql: ^14 - graphql-request: ^6 - react: ^18 - react-dom: ^18 - viem: ^2.7.0 - checksum: 10c0/f1b3bb3d805703c3fcb5e28821971efbaa098cd7729995ac8a8502cdec38395cbcbcac81442f8ce45a30c333ecafaaeaa368fce77ca69732f045c88ec93342e8 - languageName: node - linkType: hard - "@coinbase/wallet-sdk@npm:4.0.4": version: 4.0.4 resolution: "@coinbase/wallet-sdk@npm:4.0.4" @@ -15227,7 +15212,6 @@ __metadata: "@babel/preset-env": "npm:^7.23.5" "@babel/preset-react": "npm:^7.23.3" "@babel/preset-typescript": "npm:^7.23.3" - "@coinbase/onchainkit": "npm:0.10.0" "@coinbase/wallet-sdk": "npm:^3.9.1" "@jest/globals": "npm:^29.7.0" "@nextui-org/accordion": "npm:^2.0.35"