mango-v4-ui/pages/_app.tsx

164 lines
5.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import '../styles/globals.css'
import 'react-nice-dates/build/style.css'
import '../styles/datepicker.css'
import type { AppProps } from 'next/app'
import { useCallback, useMemo } from 'react'
import {
Adapter,
WalletAdapterNetwork,
WalletError,
WalletNotReadyError,
} from '@solana/wallet-adapter-base'
import {
ConnectionProvider,
WalletProvider,
} from '@solana/wallet-adapter-react'
import {
PhantomWalletAdapter,
SolflareWalletAdapter,
GlowWalletAdapter,
} from '@solana/wallet-adapter-wallets'
import { clusterApiUrl } from '@solana/web3.js'
import TransactionNotification from '@components/notifications/TransactionNotification'
import { ThemeProvider } from 'next-themes'
import { appWithTranslation } from 'next-i18next'
import Layout from '../components/Layout'
import { ViewportProvider } from '../hooks/useViewport'
import MangoProvider from '@components/MangoProvider'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import EnhancedWalletProvider from '@components/wallet/EnhancedWalletProvider'
import { notify } from 'utils/notifications'
import { useRouter } from 'next/router'
import useSelectedMarket from 'hooks/useSelectedMarket'
import Head from 'next/head'
import useMangoGroup from 'hooks/useMangoGroup'
import { PerpMarket } from '@blockworks-foundation/mango-v4'
import { getDecimalCount } from 'utils/numbers'
import { THEME_KEY } from 'utils/constants'
// Do not add hooks to this component that will cause unnecessary rerenders
// Top level state hydrating/updating should go in MangoProvider
// Create a client
export const queryClient = new QueryClient()
const metaTitle = 'Mango Markets Safer. Smarter. Faster.'
const metaDescription =
'A magical new way to interact with DeFi. Groundbreaking safety features designed to keep your funds secure. The easiest way to margin trade any token pair. All powered by flashloans.'
function MyApp({ Component, pageProps }: AppProps) {
const network = WalletAdapterNetwork.Mainnet
const endpoint = useMemo(() => clusterApiUrl(network), [network])
const wallets = useMemo(
() => [
new PhantomWalletAdapter(),
new SolflareWalletAdapter(),
new GlowWalletAdapter(),
],
[]
)
const onError = useCallback((error: WalletError, adapter?: Adapter) => {
console.error(error, adapter)
if (error instanceof WalletNotReadyError && adapter) {
notify({
title: `${adapter.name} Error`,
type: 'error',
description: `Please install ${adapter.name} and then reload this page.`,
})
if (typeof window !== 'undefined') {
window.open(adapter.url, '_blank')
}
}
}, [])
return (
<>
<Head>
<title>Mango Markets</title>
<link rel="icon" href="/favicon.ico" />
<meta property="og:title" content={metaTitle} />
<meta name="description" content={metaDescription} />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link
rel="apple-touch-icon"
sizes="192x192"
href="/apple-touch-icon.png"
/>
<meta name="msapplication-TileColor" content="#da532c" />
<meta name="theme-color" content="#ffffff" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content={metaTitle} />
<meta name="twitter:description" content={metaDescription} />
<meta
name="twitter:image"
content="https://app.mango.markets/images/1200x600-share.png?34567879"
/>
<meta name="google" content="notranslate" />
<link rel="manifest" href="/manifest.json"></link>
</Head>
<MangoProvider />
<QueryClientProvider client={queryClient}>
<ConnectionProvider endpoint={endpoint}>
<WalletProvider wallets={wallets} onError={onError}>
<EnhancedWalletProvider>
<ThemeProvider
defaultTheme="Mango Classic"
storageKey={THEME_KEY}
>
<ViewportProvider>
<PageTitle />
<Layout>
<Component {...pageProps} />
</Layout>
</ViewportProvider>
<TransactionNotification />
</ThemeProvider>
</EnhancedWalletProvider>
</WalletProvider>
</ConnectionProvider>
</QueryClientProvider>
</>
)
}
export default appWithTranslation(MyApp)
const PageTitle = () => {
const router = useRouter()
const { selectedMarket } = useSelectedMarket()
const { group } = useMangoGroup()
const [market, price] = useMemo(() => {
if (!selectedMarket || !group) return []
if (selectedMarket instanceof PerpMarket) {
return [selectedMarket, selectedMarket.uiPrice]
} else {
const baseBank = group.getFirstBankByTokenIndex(
selectedMarket.baseTokenIndex
)
const quoteBank = group.getFirstBankByTokenIndex(
selectedMarket.quoteTokenIndex
)
const market = group.getSerum3ExternalMarket(
selectedMarket.serumMarketExternal
)
const price = baseBank.uiPrice / quoteBank.uiPrice
return [market, price]
}
}, [selectedMarket, group])
const marketTitleString =
market && selectedMarket && router.pathname == '/trade'
? `${price?.toFixed(getDecimalCount(market.tickSize))} ${
selectedMarket.name
} - `
: ''
return (
<Head>
<title>{marketTitleString}Mango Markets</title>
</Head>
)
}