diff --git a/.env.example b/.env.example index 33138989..5cafa626 100644 --- a/.env.example +++ b/.env.example @@ -5,7 +5,6 @@ NEXT_PUBLIC_GQL=https://testnet-osmosis-node.marsprotocol.io/XF32UOOU55CX/osmosi NEXT_PUBLIC_REST=https://testnet-osmosis-node.marsprotocol.io/XF32UOOU55CX/osmosis-lcd-front/ NEXT_PUBLIC_SWAP=https://testnet.osmosis.zone NEXT_PUBLIC_APOLLO_APR=https://api.apollo.farm/api/vault_infos/v2/osmo-test-5 -NEXT_PUBLIC_WALLETS=keplr,cosmostation NEXT_PUBLIC_ACCOUNT_NFT=osmo1gmpua5rkzg6cmju73fz5a9x454nz4vwlnkgs4g8wjlyeqtmzsuhq5funky NEXT_PUBLIC_ORACLE=osmo1khe29uw3t85nmmp3mtr8dls7v2qwsfk3tndu5h4w5g2r5tzlz5qqarq2e2 NEXT_PUBLIC_RED_BANK=osmo1dl4rylasnd7mtfzlkdqn2gr0ss4gvyykpvr6d7t5ylzf6z535n9s5jjt8u @@ -21,6 +20,7 @@ CHARTING_LIBRARY_ACCESS_TOKEN="access_token_with_access_to_charting_library" CHARTING_LIBRARY_REPOSITORY="github.com/username/charting_library/" NEXT_PUBLIC_PYTH_ENDPOINT=https://xc-mainnet.pyth.network/api NEXT_PUBLIC_MAINNET_REST=https://osmosis-node.marsprotocol.io/GGSFGSFGFG34/osmosis-lcd-front/ +NEXT_PUBLIC_WALLET_CONNECT_ID=d93fdffb159bae5ec87d8fee4cdbb045 # MAINNET # # NEXT_PUBLIC_NETWORK=mainnet @@ -30,7 +30,6 @@ NEXT_PUBLIC_MAINNET_REST=https://osmosis-node.marsprotocol.io/GGSFGSFGFG34/osmos # NEXT_PUBLIC_REST=https://osmosis-node.marsprotocol.io/GGSFGSFGFG34/osmosis-lcd-front/ # NEXT_PUBLIC_SWAP=https://app.osmosis.zone # NEXT_PUBLIC_APOLLO_APR=https://api.apollo.farm/api/vault_infos/v2/osmosis-1 -# NEXT_PUBLIC_WALLETS=keplr,xfi-cosmos,leap-cosmos,cosmostation,mobile-keplr,mobile-cosmostation # NEXT_PUBLIC_ACCOUNT_NFT=osmo1450hrg6dv2l58c0rvdwx8ec2a0r6dd50hn4frk370tpvqjhy8khqw7sw09 # NEXT_PUBLIC_ORACLE=osmo1mhznfr60vjdp2gejhyv2gax9nvyyzhd3z0qcwseyetkfustjauzqycsy2g # NEXT_PUBLIC_RED_BANK=osmo1c3ljch9dfw5kf52nfwpxd2zmj2ese7agnx0p9tenkrryasrle5sqf3ftpg @@ -44,3 +43,5 @@ NEXT_PUBLIC_MAINNET_REST=https://osmosis-node.marsprotocol.io/GGSFGSFGFG34/osmos # CHARTING_LIBRARY_REPOSITORY="username/charting_library" # NEXT_PUBLIC_PYTH_ENDPOINT=https://xc-mainnet.pyth.network/api # NEXT_PUBLIC_MAINNET_REST=https://osmosis-node.marsprotocol.io/GGSFGSFGFG34/osmosis-lcd-front/ +# NEXT_PUBLIC_WALLET_CONNECT_ID=d93fdffb159bae5ec87d8fee4cdbb045 + diff --git a/__tests__/components/Account/AccountDetails.test.tsx b/__tests__/components/Account/AccountDetails.test.tsx index d988e409..80fce63b 100644 --- a/__tests__/components/Account/AccountDetails.test.tsx +++ b/__tests__/components/Account/AccountDetails.test.tsx @@ -1,13 +1,24 @@ import { render, screen } from '@testing-library/react' -import useCurrentAccount from 'hooks/useCurrentAccount' import AccountDetails from 'components/Account/AccountDetails' +import useCurrentAccount from 'hooks/useCurrentAccount' +import useStore from 'store' jest.mock('hooks/useCurrentAccount', () => jest.fn(() => null)) const mockedUseCurrentAccount = useCurrentAccount as jest.Mock describe('', () => { + beforeAll(() => { + useStore.setState({ + address: 'walletAddress', + }) + }) + + afterAll(() => { + useStore.clearState() + }) + it('renders account details WHEN account is selected', () => { mockedUseCurrentAccount.mockReturnValue({ id: 1 }) render() diff --git a/next.config.js b/next.config.js index a6bc0b47..1ac29385 100644 --- a/next.config.js +++ b/next.config.js @@ -2,6 +2,13 @@ const nextConfig = { reactStrictMode: true, + images: { + domains: [ + 'assets.leapwallet.io', + 'raw.githubusercontent.com', + 'xdefi-static.s3.eu-west-1.amazonaws.com', + ], + }, async rewrites() { return [ { diff --git a/package.json b/package.json index 9847965f..23d41d1c 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,8 @@ }, "dependencies": { "@cosmjs/cosmwasm-stargate": "^0.31.0", - "@marsprotocol/wallet-connector": "^1.8.9", + "@delphi-labs/shuttle-react": "^3.3.0", + "@keplr-wallet/cosmos": "^0.12.16", "@sentry/nextjs": "^7.60.0", "@tanstack/react-table": "^8.9.3", "@tippyjs/react": "^4.2.6", @@ -30,6 +31,7 @@ "react-dom": "^18.2.0", "react-draggable": "^4.4.5", "react-helmet": "^6.1.0", + "react-qr-code": "^2.0.11", "react-router-dom": "^6.14.1", "react-spring": "^9.7.2", "react-toastify": "^9.1.3", diff --git a/public/images/bridges/gravity.png b/public/images/bridges/gravity.png new file mode 100644 index 00000000..37c7154e Binary files /dev/null and b/public/images/bridges/gravity.png differ diff --git a/public/images/bridges/satellite.png b/public/images/bridges/satellite.png new file mode 100644 index 00000000..b3dd1cf7 Binary files /dev/null and b/public/images/bridges/satellite.png differ diff --git a/public/tokens/atom.svg b/public/images/tokens/atom.svg similarity index 100% rename from public/tokens/atom.svg rename to public/images/tokens/atom.svg diff --git a/public/tokens/axlusdc.svg b/public/images/tokens/axlusdc.svg similarity index 100% rename from public/tokens/axlusdc.svg rename to public/images/tokens/axlusdc.svg diff --git a/public/tokens/axlwbtc.svg b/public/images/tokens/axlwbtc.svg similarity index 100% rename from public/tokens/axlwbtc.svg rename to public/images/tokens/axlwbtc.svg diff --git a/public/tokens/axlweth.svg b/public/images/tokens/axlweth.svg similarity index 100% rename from public/tokens/axlweth.svg rename to public/images/tokens/axlweth.svg diff --git a/public/tokens/cro.svg b/public/images/tokens/cro.svg similarity index 100% rename from public/tokens/cro.svg rename to public/images/tokens/cro.svg diff --git a/public/tokens/injective.svg b/public/images/tokens/injective.svg similarity index 100% rename from public/tokens/injective.svg rename to public/images/tokens/injective.svg diff --git a/public/tokens/juno.svg b/public/images/tokens/juno.svg similarity index 100% rename from public/tokens/juno.svg rename to public/images/tokens/juno.svg diff --git a/public/tokens/mars.svg b/public/images/tokens/mars.svg similarity index 100% rename from public/tokens/mars.svg rename to public/images/tokens/mars.svg diff --git a/public/tokens/nusdc.svg b/public/images/tokens/nusdc.svg similarity index 100% rename from public/tokens/nusdc.svg rename to public/images/tokens/nusdc.svg diff --git a/public/tokens/osmo.svg b/public/images/tokens/osmo.svg similarity index 100% rename from public/tokens/osmo.svg rename to public/images/tokens/osmo.svg diff --git a/public/tokens/statom.svg b/public/images/tokens/statom.svg similarity index 100% rename from public/tokens/statom.svg rename to public/images/tokens/statom.svg diff --git a/public/images/wallets/keplr.png b/public/images/wallets/keplr.png new file mode 100644 index 00000000..0db08c87 Binary files /dev/null and b/public/images/wallets/keplr.png differ diff --git a/public/images/wallets/station.png b/public/images/wallets/station.png new file mode 100644 index 00000000..41c27bd2 Binary files /dev/null and b/public/images/wallets/station.png differ diff --git a/public/images/wallets/xdelfi.png b/public/images/wallets/xdelfi.png new file mode 100644 index 00000000..2de78526 Binary files /dev/null and b/public/images/wallets/xdelfi.png differ diff --git a/src/components/Account/AccountCreateFirst.tsx b/src/components/Account/AccountCreateFirst.tsx new file mode 100644 index 00000000..d80e0dcb --- /dev/null +++ b/src/components/Account/AccountCreateFirst.tsx @@ -0,0 +1,39 @@ +import { useCallback } from 'react' +import { useNavigate } from 'react-router-dom' + +import FullOverlayContent from 'components/FullOverlayContent' +import useToggle from 'hooks/useToggle' +import useStore from 'store' +import { hardcodedFee } from 'utils/constants' + +export default function AccountCreateFirst() { + const navigate = useNavigate() + const address = useStore((s) => s.address) + const createAccount = useStore((s) => s.createAccount) + const [isCreating, setIsCreating] = useToggle(false) + + const handleClick = useCallback(async () => { + setIsCreating(true) + const accountId = await createAccount({ fee: hardcodedFee }) + setIsCreating(false) + // TODO: set focusComponent to fund account + useStore.setState({ focusComponent: null }) + accountId && navigate(`/wallets/${address}/accounts/${accountId}`) + }, [address, createAccount, navigate, setIsCreating]) + + return ( + + ) +} diff --git a/src/components/Account/AccountDetails.tsx b/src/components/Account/AccountDetails.tsx index 1db54a2a..7c53a32b 100644 --- a/src/components/Account/AccountDetails.tsx +++ b/src/components/Account/AccountDetails.tsx @@ -2,6 +2,7 @@ import { Gauge } from 'components/Gauge' import { Heart } from 'components/Icons' import Text from 'components/Text' import useCurrentAccount from 'hooks/useCurrentAccount' +import useStore from 'store' interface Props { account: Account @@ -9,8 +10,9 @@ interface Props { export default function AccountDetailsController() { const account = useCurrentAccount() + const address = useStore((s) => s.address) - if (!account) return null + if (!account || !address) return null return } diff --git a/src/components/Account/AccountMenu.tsx b/src/components/Account/AccountMenu.tsx index a92dbb68..7516a2a7 100644 --- a/src/components/Account/AccountMenu.tsx +++ b/src/components/Account/AccountMenu.tsx @@ -2,8 +2,8 @@ import { Suspense } from 'react' import AccountMenuContent from 'components/Account/AccountMenuContent' import Loading from 'components/Loading' -import useStore from 'store' import useAccounts from 'hooks/useAccounts' +import useStore from 'store' function Content() { const address = useStore((s) => s.address) diff --git a/src/components/Account/AccountMenuContent.tsx b/src/components/Account/AccountMenuContent.tsx index efbf830e..703d342c 100644 --- a/src/components/Account/AccountMenuContent.tsx +++ b/src/components/Account/AccountMenuContent.tsx @@ -2,6 +2,7 @@ import classNames from 'classnames' import { useCallback, useEffect, useState } from 'react' import { useNavigate, useParams } from 'react-router-dom' +import AccountCreateFirst from 'components/Account/AccountCreateFirst' import AccountList from 'components/Account/AccountList' import CreateAccount from 'components/Account/CreateAccount' import FundAccount from 'components/Account/FundAccount' @@ -10,12 +11,13 @@ import { CircularProgress } from 'components/CircularProgress' import { Account, Plus, PlusCircled } from 'components/Icons' import Overlay from 'components/Overlay' import Text from 'components/Text' +import WalletBridges from 'components/Wallet/WalletBridges' +import useCurrentWalletBalance from 'hooks/useCurrentWalletBalance' import useToggle from 'hooks/useToggle' import useStore from 'store' import { hardcodedFee } from 'utils/constants' -import { isNumber } from 'utils/parsers' -import useCurrentWalletBalance from 'hooks/useCurrentWalletBalance' import { BN } from 'utils/helpers' +import { isNumber } from 'utils/parsers' const menuClasses = 'absolute isolate flex w-full flex-wrap scrollbar-hide' const ACCOUNT_MENU_BUTTON_ID = 'account-menu-button' @@ -61,11 +63,17 @@ export default function AccountMenuContent(props: Props) { }, [address, createAccount, navigate, setIsCreating, setShowMenu]) const handleCreateAccountClick = useCallback(() => { - setShowMenu(!showMenu) - if (!hasCreditAccounts && checkHasFunds()) { - performCreateAccount() + if (!checkHasFunds()) { + useStore.setState({ focusComponent: }) + return } - }, [checkHasFunds, hasCreditAccounts, performCreateAccount, setShowMenu, showMenu]) + if (!hasCreditAccounts) { + useStore.setState({ focusComponent: }) + return + } + + setShowMenu(!showMenu) + }, [checkHasFunds, hasCreditAccounts, setShowMenu, showMenu]) useEffect(() => { useStore.setState({ accounts: props.accounts }) diff --git a/src/components/Button/EscButton.tsx b/src/components/Button/EscButton.tsx index b9db5221..0b2bdb7a 100644 --- a/src/components/Button/EscButton.tsx +++ b/src/components/Button/EscButton.tsx @@ -1,7 +1,7 @@ import { useCallback, useEffect } from 'react' -import { Cross } from 'components/Icons' import Button from 'components/Button' +import { Cross } from 'components/Icons' import Text from 'components/Text' interface Props { @@ -34,7 +34,7 @@ export default function EscButton(props: Props) { leftIcon={} iconClassName='w-3' color='tertiary' - className='h-3' + className='h-3 w-13' size='xs' > ESC diff --git a/src/components/Button/index.tsx b/src/components/Button/index.tsx index cad4b09e..667a2446 100644 --- a/src/components/Button/index.tsx +++ b/src/components/Button/index.tsx @@ -20,27 +20,6 @@ import { DEFAULT_SETTINGS } from 'constants/defaultSettings' import { REDUCE_MOTION_KEY } from 'constants/localStore' import useLocalStorage from 'hooks/useLocalStorage' -interface Props { - children?: string | ReactNode - className?: string - color?: 'primary' | 'secondary' | 'tertiary' | 'quaternary' - disabled?: boolean - id?: string - showProgressIndicator?: boolean - size?: 'xs' | 'sm' | 'md' | 'lg' - text?: string | ReactNode - variant?: 'solid' | 'transparent' | 'round' | 'rounded' - onClick?: (e: React.MouseEvent) => void - leftIcon?: ReactElement - rightIcon?: ReactElement - iconClassName?: string - hasSubmenu?: boolean - hasFocus?: boolean - dataTestId?: string - tabIndex?: number - textClassNames?: string -} - const Button = React.forwardRef(function Button( { children, @@ -61,7 +40,7 @@ const Button = React.forwardRef(function Button( dataTestId, tabIndex = 0, textClassNames, - }: Props, + }: ButtonProps, ref, ) { const [reduceMotion] = useLocalStorage(REDUCE_MOTION_KEY, DEFAULT_SETTINGS.reduceMotion) diff --git a/src/components/DocsLink.tsx b/src/components/DocsLink.tsx new file mode 100644 index 00000000..0c7347db --- /dev/null +++ b/src/components/DocsLink.tsx @@ -0,0 +1,40 @@ +import { ExternalLink } from 'components/Icons' +import Text from 'components/Text' + +interface Props { + type: 'wallet' | 'account' | 'terms' +} + +function getData(type: string) { + if (type === 'wallet') + return [ + 'New with wallets?', + 'Learn more', + 'https://docs.marsprotocol.io/docs/learn/workstation/basics/basics-intro', + ] + if (type === 'account') + return [ + 'Why mint your account?', + 'Learn more', + 'https://docs.marsprotocol.io/docs/learn/workstation/rover/rover-intro', + ] + return [ + 'By continuing you accept our', + 'terms of service', + 'https://docs.marsprotocol.io/docs/overview/legal/terms-of-service', + ] +} + +export default function DocsLink(props: Props) { + const [intro, linkText, url] = getData(props.type) + + return ( + + {`${intro} `} + + {linkText} + + + + ) +} diff --git a/src/components/Footer.tsx b/src/components/Footer.tsx index 1a440c76..6fc67d60 100644 --- a/src/components/Footer.tsx +++ b/src/components/Footer.tsx @@ -5,7 +5,7 @@ import packageInfo from '../../package.json' export default function Footer() { return (