; onChange: (step: number) => void }) {
7 | const isMobile = useAppStore((s) => s.isMobile)
8 | const { t } = useTranslation()
9 | return (
10 |
21 | )
22 | }
23 |
--------------------------------------------------------------------------------
/src/features/Create/ClmmPool/components/type.ts:
--------------------------------------------------------------------------------
1 | export interface TickData {
2 | tickLower?: number
3 | tickUpper?: number
4 | priceLower?: string
5 | priceUpper?: string
6 | }
7 |
--------------------------------------------------------------------------------
/src/features/Create/ClmmPool/index.tsx:
--------------------------------------------------------------------------------
1 | export { default } from './CreateClmmPool'
2 |
--------------------------------------------------------------------------------
/src/features/Create/StandardPool/hooks/useMarketSchema.ts:
--------------------------------------------------------------------------------
1 | import { useTranslation } from 'react-i18next'
2 | import * as yup from 'yup'
3 |
4 | const numberTransform = yup.number().transform((value) => (isNaN(value) ? 0 : value))
5 | const numberSchema = (errMsg: string) => numberTransform.moreThan(0, errMsg).required(errMsg)
6 |
7 | export default function useMarketSchema() {
8 | // prepare for i18n usage
9 | const { t } = useTranslation()
10 | return yup.object().shape({
11 | baseToken: yup.mixed().required(t('error.select_base_token') ?? ''),
12 | quoteToken: yup.mixed().required(t('error.select_quote_token') ?? ''),
13 | orderSize: numberSchema(t('error.enter_order_size') ?? ''),
14 | priceTick: numberSchema(t('error.enter_price_tick') ?? '')
15 | })
16 | }
17 |
--------------------------------------------------------------------------------
/src/features/Debug/components/NonAtaItem.tsx:
--------------------------------------------------------------------------------
1 | import { Flex } from '@chakra-ui/react'
2 | import { TokenAccount } from '@raydium-io/raydium-sdk-v2'
3 | import { getAssociatedTokenAddressSync } from '@solana/spl-token'
4 |
5 | import useTokenInfo from '@/hooks/token/useTokenInfo'
6 | import { useAppStore } from '@/store'
7 | import Decimal from 'decimal.js'
8 |
9 | export default function NonAtaItem({ account }: { account: TokenAccount }) {
10 | const publicKey = useAppStore((s) => s.publicKey)
11 | const token = useTokenInfo({
12 | mint: account.mint.toString(),
13 | programId: account.programId
14 | }).tokenInfo
15 | const symbol = token?.symbol || account.mint.toString().slice(0, 6)
16 |
17 | return (
18 |
19 | token: {symbol}, amount: {new Decimal(account.amount.toString()).div(10 ** (token?.decimals || 0)).toString()}, publicKey:{' '}
20 | {account.publicKey?.toString()}, ata: {getAssociatedTokenAddressSync(account.mint, publicKey!).toString()}
21 |
22 | )
23 | }
24 |
--------------------------------------------------------------------------------
/src/features/Debug/index.tsx:
--------------------------------------------------------------------------------
1 | import { Box } from '@chakra-ui/react'
2 | import { useTokenAccountStore } from '@/store'
3 | import NonAtaItem from './components/NonAtaItem'
4 |
5 | export default function Debug() {
6 | const tokenAccounts = useTokenAccountStore((s) => s.tokenAccounts)
7 | const nonAtaList = tokenAccounts.filter((acc) => !acc.isNative && !acc.isAssociated)
8 |
9 | return (
10 |
11 | {nonAtaList.map((acc) => (
12 |
13 | ))}
14 |
15 | )
16 | }
17 |
--------------------------------------------------------------------------------
/src/features/Farm/Create/components/DetailReview/RewardTotalValue.tsx:
--------------------------------------------------------------------------------
1 | import { useTranslation } from 'react-i18next'
2 | import { HStack, Text } from '@chakra-ui/react'
3 | import { colors } from '@/theme/cssVariables'
4 | import { formatCurrency } from '@/utils/numberish/formatter'
5 |
6 | export function RewardTotalValue(props: { total: number | string }) {
7 | const { t } = useTranslation()
8 | return (
9 |
10 |
11 | {t('field.total_value')}
12 |
13 |
14 | {formatCurrency(props.total, { symbol: '$', decimalPlaces: 2 })}
15 |
16 |
17 | )
18 | }
19 |
--------------------------------------------------------------------------------
/src/features/Farm/Create/type.ts:
--------------------------------------------------------------------------------
1 | import { ApiV3Token } from '@raydium-io/raydium-sdk-v2'
2 |
3 | export type NewRewardInfo = {
4 | id: string
5 | token?: ApiV3Token
6 | amount?: string
7 | farmStart?: number
8 | farmEnd?: number
9 | perWeek?: string
10 | error?: string
11 | isValid: boolean
12 | }
13 |
--------------------------------------------------------------------------------
/src/features/Farm/Edit/index.tsx:
--------------------------------------------------------------------------------
1 | export { default } from './Edit'
2 |
--------------------------------------------------------------------------------
/src/features/Liquidity/Increase/components/StakeableHint.tsx:
--------------------------------------------------------------------------------
1 | import { Grid, Text } from '@chakra-ui/react'
2 | import { useTranslation } from 'react-i18next'
3 |
4 | import ExclaimationOctagon from '@/icons/misc/ExclaimationOctagon'
5 | import { colors } from '@/theme/cssVariables'
6 | import { panelCard } from '@/theme/cssBlocks'
7 |
8 | export default function StakeableHint() {
9 | const { t } = useTranslation()
10 | return (
11 |
20 |
21 |
22 | {t('liquidity.stakeable_hint')}
23 |
24 |
25 | )
26 | }
27 |
--------------------------------------------------------------------------------
/src/features/Moonpay/index.tsx:
--------------------------------------------------------------------------------
1 | export { default } from './Moonpay'
2 |
--------------------------------------------------------------------------------
/src/features/Pools/components/PoolChart/const.ts:
--------------------------------------------------------------------------------
1 | export type TimeType = '15m' | '1H' | '4H' | '1D' | '1W'
2 | export const availableTimeType = ['15m', '1H', '4H', '1D', '1W'] as const
3 |
--------------------------------------------------------------------------------
/src/features/Pools/components/PoolItemLoadingSkeleton.tsx:
--------------------------------------------------------------------------------
1 | import { Flex, Skeleton, SkeletonCircle } from '@chakra-ui/react'
2 |
3 | export default function PoolItemLoadingSkeleton({ isGrid }: { isGrid: boolean }) {
4 | const arr = new Array(isGrid ? 2 : 5).fill(0)
5 | return (
6 |
7 | {isGrid
8 | ? arr.map((_, idx) => (
9 |
16 |
17 |
18 |
19 |
20 | ))
21 | : arr.map((_, idx) => (
22 |
23 |
24 |
25 |
26 |
27 | ))}
28 |
29 | )
30 | }
31 |
--------------------------------------------------------------------------------
/src/features/Pools/components/PoolTabList.tsx:
--------------------------------------------------------------------------------
1 | import { Tabs, TabList, Tab } from '@chakra-ui/react'
2 | import { sizes } from '@/theme/cssVariables'
3 |
4 | /**
5 | * just a wrapper for chakra-ui Tabs
6 | */
7 | export function PoolTabList(props: { names: T[]; active?: T; onChange?: (active: string) => void }) {
8 | return (
9 | props.onChange?.(props.names[index])}>
10 |
11 | {props.names.map((name) => (
12 |
13 | {name}
14 |
15 | ))}
16 |
17 |
18 | )
19 | }
20 |
--------------------------------------------------------------------------------
/src/features/Pools/cssBlocks.ts:
--------------------------------------------------------------------------------
1 | import { SystemStyleObject } from '@chakra-ui/react'
2 |
3 | export const poolListGrid: SystemStyleObject = {
4 | display: 'grid',
5 | gridTemplateColumns: [
6 | '1.4fr .7fr .8fr',
7 | 'minmax(0, 1.7fr) minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1.2fr) minmax(200px, 1fr)'
8 | ],
9 | columnGap: ['max(1rem, 2%)', 'max(1rem, 3%)'],
10 | alignItems: 'center'
11 | }
12 |
--------------------------------------------------------------------------------
/src/features/Pools/index.tsx:
--------------------------------------------------------------------------------
1 | export { default } from './Pools'
2 |
--------------------------------------------------------------------------------
/src/features/Portfolio/components/SectionMyFarms/components/Tvl.tsx:
--------------------------------------------------------------------------------
1 | import { Flex, FlexProps, Text } from '@chakra-ui/react'
2 | import { colors } from '@/theme/cssVariables'
3 | import { formatCurrency } from '@/utils/numberish/formatter'
4 |
5 | type TvlProps = FlexProps & {
6 | tvl: string | number
7 | decimals: number
8 | }
9 |
10 | export default function Tvl({ tvl, decimals, ...rest }: TvlProps) {
11 | return (
12 |
13 |
14 | TVL
15 |
16 |
17 | {formatCurrency(tvl, { symbol: '$', decimalPlaces: decimals })}
18 |
19 |
20 | )
21 | }
22 |
--------------------------------------------------------------------------------
/src/features/Portfolio/components/SectionMyPositions/components/Staked/Apr.tsx:
--------------------------------------------------------------------------------
1 | import { Flex, Spacer, Text } from '@chakra-ui/react'
2 | import { formatToRawLocaleStr } from '@/utils/numberish/formatter'
3 |
4 | import { colors } from '@/theme/cssVariables'
5 |
6 | type AprProps = {
7 | apr: string
8 | }
9 |
10 | export default function Apr({ apr }: AprProps) {
11 | return (
12 |
13 |
14 | APR
15 |
16 |
17 | {formatToRawLocaleStr(apr)}
18 |
19 |
20 |
21 | )
22 | }
23 |
--------------------------------------------------------------------------------
/src/features/Portfolio/components/SectionMyPositions/components/Staked/StakedValue.tsx:
--------------------------------------------------------------------------------
1 | import { Flex, Text } from '@chakra-ui/react'
2 | import { ApiV3Token } from '@raydium-io/raydium-sdk-v2'
3 |
4 | import { colors } from '@/theme/cssVariables'
5 | import { formatCurrency } from '@/utils/numberish/formatter'
6 |
7 | type StakedValueProps = {
8 | positionUsd: string
9 | staked: {
10 | token: ApiV3Token | undefined
11 | amount: string
12 | }
13 | }
14 |
15 | export default function StakedValue({ positionUsd, staked }: StakedValueProps) {
16 | return (
17 |
18 |
19 | My Staked RAY
20 |
21 |
22 | {formatCurrency(staked.amount)} {staked.token?.symbol}
23 |
24 |
25 | {formatCurrency(positionUsd, { symbol: '$', decimalPlaces: 2 })}
26 |
27 |
28 | )
29 | }
30 |
--------------------------------------------------------------------------------
/src/features/Portfolio/components/SectionMyPositions/components/Staked/TokenBriefFace.tsx:
--------------------------------------------------------------------------------
1 | import { Text, VStack } from '@chakra-ui/react'
2 | import { ApiV3Token } from '@raydium-io/raydium-sdk-v2'
3 |
4 | import TokenAvatar from '@/components/TokenAvatar'
5 | import { colors } from '@/theme/cssVariables'
6 |
7 | type TokenBriefFaceProps = {
8 | token: ApiV3Token | undefined
9 | }
10 |
11 | export default function TokenBriefFace({ token }: TokenBriefFaceProps) {
12 | return (
13 |
14 |
15 |
16 | {token?.symbol}
17 |
18 |
19 | )
20 | }
21 |
--------------------------------------------------------------------------------
/src/features/Portfolio/components/SectionMyPositions/components/Standard/ItemDetail/StandardMyPosition.tsx:
--------------------------------------------------------------------------------
1 | import { Flex, Text } from '@chakra-ui/react'
2 |
3 | import { colors } from '@/theme/cssVariables'
4 | import { formatCurrency } from '@/utils/numberish/formatter'
5 | import { useTranslation } from 'react-i18next'
6 |
7 | type MyPositionProps = {
8 | positionUsd: number | string
9 | center?: boolean
10 | }
11 |
12 | export default function StandardMyPosition({ positionUsd, center }: MyPositionProps) {
13 | const { t } = useTranslation()
14 | return (
15 |
16 |
17 | {t('liquidity.my_position')}
18 |
19 |
20 | {formatCurrency(positionUsd, { symbol: '$', abbreviated: true, decimalPlaces: 2 })}
21 |
22 |
23 | )
24 | }
25 |
--------------------------------------------------------------------------------
/src/features/Portfolio/components/SectionMyPositions/components/Standard/ItemDetail/TokenPair.tsx:
--------------------------------------------------------------------------------
1 | import { Box, Flex } from '@chakra-ui/react'
2 | import { TokenInfo } from '@raydium-io/raydium-sdk-v2'
3 |
4 | import TokenAvatarPair from '@/components/TokenAvatarPair'
5 | import { colors } from '@/theme/cssVariables'
6 |
7 | type TokenPairProps = {
8 | base: TokenInfo | undefined
9 | quote: TokenInfo | undefined
10 | poolName: string
11 | }
12 |
13 | export default function TokenPair({ base, quote, poolName }: TokenPairProps) {
14 | return (
15 |
16 |
17 |
18 |
19 | {poolName}
20 |
21 |
22 |
23 | )
24 | }
25 |
--------------------------------------------------------------------------------
/src/features/Staking/Staking.tsx:
--------------------------------------------------------------------------------
1 | import { Box, Skeleton } from '@chakra-ui/react'
2 |
3 | import PageHeroTitle from '@/components/PageHeroTitle'
4 | import useFetchStakePools from '@/hooks/pool/useFetchStakePools'
5 | import useFarmPositions from '@/hooks/portfolio/farm/useFarmPositions'
6 | import { useTranslation } from 'react-i18next'
7 | import StakingPoolItem from './components/StakingPoolItem'
8 |
9 | export type StakingPageQuery = {
10 | dialog?: 'unstake' | 'stake'
11 | open?: string // token mint
12 | }
13 |
14 | export default function Staking() {
15 | const { t } = useTranslation()
16 | const { activeStakePools, isLoading } = useFetchStakePools({})
17 | const { lpBasedData } = useFarmPositions({})
18 |
19 | return (
20 |
21 |
22 |
23 |
24 | {isLoading ? (
25 |
26 | ) : (
27 | activeStakePools.map((pool) => (
28 |
29 | ))
30 | )}
31 |
32 | )
33 | }
34 |
--------------------------------------------------------------------------------
/src/features/Staking/index.tsx:
--------------------------------------------------------------------------------
1 | export { default } from './Staking'
2 |
--------------------------------------------------------------------------------
/src/features/Swap/index.tsx:
--------------------------------------------------------------------------------
1 | export { default } from './Swap'
2 |
--------------------------------------------------------------------------------
/src/features/Swap/swapMeta.tsx:
--------------------------------------------------------------------------------
1 | import { Trans } from 'react-i18next'
2 | import { Text } from '@chakra-ui/react'
3 | import i18n from '@/i18n'
4 | import { colors } from '@/theme/cssVariables/colors'
5 |
6 | const SWAP_TX_MSG = {
7 | swap: {
8 | title: 'transaction_history.name_swap',
9 | desc: 'transaction_history.desc_swap',
10 | txHistoryTitle: 'transaction_history.name_swap',
11 | txHistoryDesc: 'transaction_history.desc_swap',
12 | components: { sub: }
13 | }
14 | }
15 | export const getTxMeta = ({ action, values = {} }: { action: keyof typeof SWAP_TX_MSG; values?: Record }) => {
16 | const meta = SWAP_TX_MSG[action]
17 | return {
18 | title: i18n.t(meta.title, values),
19 | description: ,
20 | txHistoryTitle: meta.txHistoryTitle || meta.title,
21 | txHistoryDesc: meta.txHistoryDesc || meta.desc,
22 | txValues: values
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/features/Swap/type.ts:
--------------------------------------------------------------------------------
1 | export interface ApiSwapV1OutError {
2 | id: string
3 | success: false
4 | version: 'V0' | 'V1'
5 | msg: string
6 | openTime?: string
7 | data: undefined
8 | }
9 | export interface ApiSwapV1OutSuccess {
10 | id: string
11 | success: true
12 | version: 'V0' | 'V1'
13 | openTime?: undefined
14 | msg: undefined
15 | data: {
16 | swapType: 'BaseIn' | 'BaseOut'
17 | inputMint: string
18 | inputAmount: string
19 | outputMint: string
20 | outputAmount: string
21 | otherAmountThreshold: string
22 | slippageBps: number
23 | priceImpactPct: number
24 | routePlan: {
25 | poolId: string
26 | inputMint: string
27 | outputMint: string
28 | feeMint: string
29 | feeRate: number
30 | feeAmount: string
31 | }[]
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/features/Swap/util.ts:
--------------------------------------------------------------------------------
1 | import { SOLMint, WSOLMint } from '@raydium-io/raydium-sdk-v2'
2 | import { isClient } from '@/utils/common'
3 |
4 | export const isSol = (mint: string) => mint === SOLMint.toBase58()
5 | export const isWSol = (mint: string) => mint === WSOLMint.toBase58()
6 |
7 | export const isSolWSol = (mint1: string, mint2: string) => (isSol(mint1) && isWSol(mint2)) || (isWSol(mint1) && isSol(mint2))
8 |
9 | const CACHE_KEY = '_ray_swap_'
10 |
11 | export interface PairData {
12 | inputMint: string
13 | outputMint: string
14 | }
15 | export const getSwapPairCache = (): PairData => {
16 | if (!isClient()) return { inputMint: '', outputMint: '' }
17 | const cache = localStorage.getItem(CACHE_KEY)
18 | return cache ? JSON.parse(cache) : { inputMint: '', outputMint: '' }
19 | }
20 |
21 | export const setSwapPairCache = (params: Partial) => {
22 | if (!isClient()) return
23 | const currentCache = getSwapPairCache()
24 | localStorage.setItem(
25 | CACHE_KEY,
26 | JSON.stringify({
27 | ...currentCache,
28 | ...params
29 | })
30 | )
31 | }
32 |
--------------------------------------------------------------------------------
/src/features/Wormhole/index.tsx:
--------------------------------------------------------------------------------
1 | export { default } from './WormholeWidget'
2 |
--------------------------------------------------------------------------------
/src/features/Wormhole/types.ts:
--------------------------------------------------------------------------------
1 | export type PaletteColor = {
2 | 50: string
3 | 100: string
4 | 200: string
5 | 300: string
6 | 400: string
7 | 500: string
8 | 600: string
9 | 700: string
10 | 800: string
11 | 900: string
12 | A100: string
13 | A200: string
14 | A400: string
15 | A700: string
16 | }
17 |
18 | export type Theme = {
19 | primary: PaletteColor
20 | secondary: PaletteColor
21 | divider: string
22 | background: {
23 | default: string
24 | }
25 | text: {
26 | primary: string
27 | secondary: string
28 | }
29 | error: PaletteColor
30 | info: PaletteColor
31 | success: PaletteColor
32 | warning: PaletteColor
33 | button: {
34 | primary: string
35 | primaryText: string
36 | disabled: string
37 | disabledText: string
38 | action: string
39 | actionText: string
40 | hover: string
41 | }
42 | options: {
43 | hover: string
44 | select: string
45 | }
46 | card: {
47 | background: string
48 | elevation: string
49 | secondary: string
50 | }
51 | popover: {
52 | background: string
53 | elevation: string
54 | secondary: string
55 | }
56 | modal: {
57 | background: string
58 | }
59 | font: {
60 | primary: string
61 | header: string
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/hooks/app/useInitMobileDetector.ts:
--------------------------------------------------------------------------------
1 | import { useEffect } from 'react'
2 | import { useDiviceInfoDetector } from '../useMobileDetector'
3 | import { useAppStore } from '@/store'
4 |
5 | export default function useInitMobileDetector() {
6 | const { isMobile, isLaptop } = useDiviceInfoDetector()
7 | useEffect(() => {
8 | useAppStore.setState({ isMobile })
9 | }, [isMobile])
10 | useEffect(() => {
11 | useAppStore.setState({ isLaptop })
12 | }, [isLaptop])
13 | }
14 |
--------------------------------------------------------------------------------
/src/hooks/app/useRefreshChainTime.ts:
--------------------------------------------------------------------------------
1 | import { useEffect } from 'react'
2 | import { useAppStore } from '@/store/useAppStore'
3 |
4 | function useRefreshChainTime() {
5 | const [fetchChainTimeAct, fetchBlockSlotCountAct, raydium] = useAppStore((s) => [
6 | s.fetchChainTimeAct,
7 | s.fetchBlockSlotCountAct,
8 | s.raydium
9 | ])
10 |
11 | useEffect(() => {
12 | if (!raydium) return
13 | const interval = window.setInterval(() => {
14 | fetchChainTimeAct()
15 | }, 1000 * 60 * 5)
16 | return () => window.clearInterval(interval)
17 | }, [fetchChainTimeAct, raydium])
18 |
19 | useEffect(() => {
20 | if (!raydium) return
21 | // fetchBlockSlotCountAct()
22 | const interval = window.setInterval(() => {
23 | fetchBlockSlotCountAct()
24 | }, 1000 * 60 * 1)
25 |
26 | return () => window.clearInterval(interval)
27 | }, [fetchBlockSlotCountAct, raydium])
28 | return null
29 | }
30 |
31 | export default useRefreshChainTime
32 |
--------------------------------------------------------------------------------
/src/hooks/app/useRefreshEpochInfo.ts:
--------------------------------------------------------------------------------
1 | import { useEffect } from 'react'
2 | import { useAppStore } from '@/store'
3 | import { retry } from '@/utils/common'
4 |
5 | export default function useRefreshEpochInfo() {
6 | const getEpochInfo = useAppStore((s) => s.getEpochInfo)
7 |
8 | useEffect(() => {
9 | if (!useAppStore.getState().epochInfo) {
10 | retry(getEpochInfo)
11 | }
12 | const interval = window.setInterval(getEpochInfo, 1000 * 60)
13 | return () => window.clearInterval(interval)
14 | }, [getEpochInfo])
15 |
16 | return null
17 | }
18 |
--------------------------------------------------------------------------------
/src/hooks/info/useFetchMainInfo.ts:
--------------------------------------------------------------------------------
1 | import useSWR from 'swr'
2 | import shallow from 'zustand/shallow'
3 | import axios from '@/api/axios'
4 | import { useAppStore } from '@/store'
5 |
6 | const fetcher = (url: string) => axios.get<{ tvl: number; volume24: number }>(url, { skipError: true })
7 |
8 | export default function useFetchMainInfo(props: { refreshInterval?: number }) {
9 | const { refreshInterval = 1000 * 60 * 15 } = props || {}
10 |
11 | const [host, infoUrl] = useAppStore((s) => [s.urlConfigs.BASE_HOST, s.urlConfigs.INFO], shallow)
12 |
13 | const { data, isLoading, error, ...rest } = useSWR(host + infoUrl, fetcher, {
14 | refreshInterval,
15 | dedupingInterval: refreshInterval,
16 | focusThrottleInterval: refreshInterval
17 | })
18 | const isEmptyResult = !isLoading && !(data && !error)
19 |
20 | return {
21 | data: data?.data,
22 | isLoading,
23 | error,
24 | isEmptyResult,
25 | ...rest
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/hooks/token/useTokenSetting.ts:
--------------------------------------------------------------------------------
1 | import { useAppStore, useTokenStore } from '@/store'
2 | import { useEffect } from 'react'
3 | import shallow from 'zustand/shallow'
4 |
5 | export default function useTokenSetting() {
6 | const displayTokenSettings = useAppStore((s) => s.displayTokenSettings)
7 | const [setDisplayTokenListAct, loadTokensAct] = useTokenStore((s) => [s.setDisplayTokenListAct, s.loadTokensAct], shallow)
8 |
9 | useEffect(() => {
10 | setDisplayTokenListAct()
11 | }, [displayTokenSettings, setDisplayTokenListAct])
12 |
13 | useEffect(() => {
14 | const intervalId = window.setInterval(() => {
15 | loadTokensAct(true)
16 | }, 60 * 1000 * 5)
17 | return () => clearInterval(intervalId)
18 | }, [loadTokensAct])
19 | }
20 |
--------------------------------------------------------------------------------
/src/hooks/useElementSizeRectDetector.ts:
--------------------------------------------------------------------------------
1 | import { ElementSingle, getSingleElement } from '@/utils/react/getElementsFromRef'
2 | import { useState } from 'react'
3 | import { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect'
4 | import useResizeObserver from './useResizeObserver'
5 |
6 | /**
7 | * only itself(ref)
8 | *
9 | * this hooks build on assumption: resize of a child will resize his parent. so just observe it's parent node.
10 | *
11 | * @param ref
12 | * @param callback
13 | */
14 | export default function useElementSizeRectDetector(ref: ElementSingle): { width: number | undefined; height: number | undefined } {
15 | const [width, setWidth] = useState(undefined)
16 | const [height, setHeight] = useState(undefined)
17 |
18 | const updateRect = () => {
19 | const el = getSingleElement(ref)
20 | if (!el) return
21 | const rect = el.getBoundingClientRect()
22 | setWidth(rect.width)
23 | setHeight(rect.height)
24 | }
25 |
26 | useIsomorphicLayoutEffect(updateRect, [ref])
27 | useResizeObserver(ref, updateRect)
28 | return { width, height }
29 | }
30 |
--------------------------------------------------------------------------------
/src/hooks/useEvent.ts:
--------------------------------------------------------------------------------
1 | import { useCallback, useRef } from 'react'
2 | import { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect'
3 |
4 | /**@see https://github.com/facebook/react/issues/14099 */
5 | export function useEvent(handler: T): T {
6 | const handlerRef = useRef(handler)
7 |
8 | useIsomorphicLayoutEffect(() => {
9 | handlerRef.current = handler
10 | })
11 |
12 | // @ts-expect-error force
13 | return useCallback((...args) => {
14 | const fn = handlerRef.current
15 | // @ts-expect-error force
16 | return fn?.(...args)
17 | }, [])
18 | }
19 |
--------------------------------------------------------------------------------
/src/hooks/useIsomorphicLayoutEffect.ts:
--------------------------------------------------------------------------------
1 | import { isClient } from '@/utils/common'
2 | import { useLayoutEffect, useEffect } from 'react'
3 |
4 | export const useIsomorphicLayoutEffect = isClient() ? useLayoutEffect : useEffect
5 |
--------------------------------------------------------------------------------
/src/hooks/useMobileDetector.ts:
--------------------------------------------------------------------------------
1 | // import { useBreakpointValue } from '@chakra-ui/react'
2 | import { useEffect, useState } from 'react'
3 | import { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect'
4 | import { isClient } from '@/utils/common'
5 |
6 | const maxMobileWidth = 768
7 | const maxLaptopWidth = 1440
8 |
9 | // you can see https://vscode.dev/github/chakra-ui/chakra-ui for more detail
10 | export function useDiviceInfoDetector() {
11 | const [isMobile, setIsMobile] = useState(false)
12 | const [isLaptop, setIsLaptop] = useState(false)
13 | const calcViewport = () => {
14 | if (isClient()) {
15 | const screenWidth = globalThis.innerWidth
16 | const isMobile = screenWidth < maxMobileWidth
17 | setIsMobile(isMobile)
18 | const isLaptop = screenWidth >= maxMobileWidth && screenWidth < maxLaptopWidth
19 | setIsLaptop(isLaptop)
20 | }
21 | }
22 | useEffect(() => {
23 | window.addEventListener('resize', calcViewport)
24 | return () => window.removeEventListener('resize', calcViewport)
25 | }, [])
26 |
27 | useIsomorphicLayoutEffect(() => {
28 | calcViewport()
29 | }, [])
30 | return { isMobile, isLaptop }
31 | }
32 |
--------------------------------------------------------------------------------
/src/hooks/usePrevious.ts:
--------------------------------------------------------------------------------
1 | import { useEffect, useRef } from 'react'
2 |
3 | // modified from https://usehooks.com/usePrevious/
4 | export default function usePrevious(value: T) {
5 | // The ref object is a generic container whose current property is mutable ...
6 | // ... and can hold any value, similar to an instance property on a class
7 | const ref = useRef()
8 |
9 | // Store current value in ref
10 | useEffect(() => {
11 | ref.current = value
12 | }, [value]) // Only re-run if value changes
13 |
14 | // Return previous value (happens before update in useEffect above)
15 | return ref.current
16 | }
17 |
--------------------------------------------------------------------------------
/src/hooks/useRefreshEpochInfo.ts:
--------------------------------------------------------------------------------
1 | import { useEffect } from 'react'
2 | import { useAppStore } from '@/store/useAppStore'
3 | import shallow from 'zustand/shallow'
4 |
5 | export default function useRefreshEpochInfo() {
6 | const [getEpochInfo, epochInfo, connection] = useAppStore((s) => [s.getEpochInfo, s.epochInfo, s.connection], shallow)
7 | useEffect(() => {
8 | getEpochInfo()
9 | const id = window.setInterval(() => {
10 | getEpochInfo()
11 | }, 60 * 1000)
12 | return () => window.clearInterval(id)
13 | }, [connection])
14 |
15 | return epochInfo
16 | }
17 |
--------------------------------------------------------------------------------
/src/hooks/useResponsive.ts:
--------------------------------------------------------------------------------
1 | import { useState, useEffect, createContext, useContext } from 'react'
2 | import { useBreakpointValue } from '@chakra-ui/react'
3 |
4 | export const MatchBreakpointsContext = createContext({
5 | isMobile: false,
6 | isTablet: false,
7 | isDesktop: false
8 | })
9 |
10 | export type BreakpointChecks = {
11 | isMobile: boolean
12 | isTablet: boolean
13 | isDesktop: boolean
14 | }
15 |
16 | const useResponsive = (): BreakpointChecks => {
17 | const [isClient, setIsClient] = useState(false)
18 | const breakPoints = useContext(MatchBreakpointsContext)
19 |
20 | const isMobile = useBreakpointValue({ base: true, sm: false }) || false
21 | const isTablet = useBreakpointValue({ sm: true, md: false }) || false
22 | const isDesktop = useBreakpointValue({ md: true }) || false
23 |
24 | useEffect(() => {
25 | setIsClient(typeof window !== 'undefined')
26 | }, [])
27 |
28 | if (!isClient && breakPoints) {
29 | return breakPoints
30 | }
31 |
32 | return { isMobile, isTablet, isDesktop }
33 | }
34 |
35 | export default useResponsive
36 |
--------------------------------------------------------------------------------
/src/hooks/useScroll.ts:
--------------------------------------------------------------------------------
1 | import { useEffect, useState } from 'react'
2 |
3 | import { throbounce } from '@/utils/functionMethods'
4 |
5 | function useScroll() {
6 | const [pageYOffset, setPageYOffset] = useState(0)
7 | const [isScrollup, setIsScrollup] = useState(false)
8 |
9 | const handleScroll = () => {
10 | setPageYOffset((p) => {
11 | p > window.pageYOffset ? setIsScrollup(true) : setIsScrollup(false)
12 | return window.pageYOffset
13 | })
14 | }
15 |
16 | useEffect(() => {
17 | window.addEventListener('scroll', throbounce(handleScroll, 200), { passive: true })
18 |
19 | return () => {
20 | window.removeEventListener('scroll', throbounce(handleScroll, 200))
21 | }
22 | }, [])
23 |
24 | return { pageYOffset, isScrollup }
25 | }
26 |
27 | export default useScroll
28 |
--------------------------------------------------------------------------------
/src/hooks/useScrollDegreeDetector.ts:
--------------------------------------------------------------------------------
1 | import { RefObject, useEffect, useRef } from 'react'
2 | import { useEvent } from './useEvent'
3 |
4 | export type UseScrollDegreeDetectorOptions = {
5 | onReachBottom?: () => void
6 | reachBottomMargin?: number
7 | }
8 |
9 | export function useScrollDegreeDetector(ref: RefObject, options?: UseScrollDegreeDetectorOptions) {
10 | const isReachedBottom = useRef(false)
11 |
12 | const onScroll = useEvent(() => {
13 | if (!ref.current) return
14 | const { scrollHeight, scrollTop, clientHeight } = ref.current
15 | const isNearlyReachBottom = scrollTop + clientHeight + (options?.reachBottomMargin ?? 0) >= scrollHeight
16 |
17 | if (isNearlyReachBottom && !isReachedBottom.current) {
18 | options?.onReachBottom?.()
19 | isReachedBottom.current = true
20 | }
21 |
22 | if (!isNearlyReachBottom && isReachedBottom.current) {
23 | isReachedBottom.current = false
24 | }
25 | })
26 |
27 | useEffect(() => {
28 | onScroll()
29 | ref.current?.addEventListener('scroll', onScroll, { passive: true })
30 | return () => ref.current?.removeEventListener('scroll', onScroll)
31 | }, [ref, onScroll])
32 | }
33 |
--------------------------------------------------------------------------------
/src/hooks/useSearch.ts:
--------------------------------------------------------------------------------
1 | import { isString } from '@/utils/judges/judgeType'
2 | import { searchItems, SearchOptions } from '@/utils/searchItems'
3 | import { useMemo } from 'react'
4 |
5 | /**
6 | * it will apply search text , every search inputs in App will apply this hook
7 | * it's a wrapper hook version of {@link searchItems}
8 | */
9 | export function useSearch(items: T[], options: string | SearchOptions): T[] {
10 | const searched = useMemo(() => searchItems(items, isString(options) ? { searchText: options } : options), [options, items])
11 | return searched
12 | }
13 |
--------------------------------------------------------------------------------
/src/hooks/useTransitionEffect.ts:
--------------------------------------------------------------------------------
1 | import { startTransition, useEffect } from 'react'
2 |
3 | export default function useTransitionedEffect(effect: () => any, dependenceList?: any[]) {
4 | useEffect(() => {
5 | startTransition(() => {
6 | effect()
7 | })
8 | }, dependenceList)
9 | }
10 |
--------------------------------------------------------------------------------
/src/hooks/useViewportObserver.ts:
--------------------------------------------------------------------------------
1 | import { useEffect } from 'react'
2 | import { useEvent } from './useEvent'
3 |
4 | /**
5 | * only itself(ref)
6 | *
7 | * this hooks build on assumption: resize of a child will resize his parent. so just observe it's parent node.
8 | *
9 | * @param ref
10 | * @param callback
11 | */
12 | export default function useViewportObserver(callback?: (utilities: { w: number; height: number }) => void) {
13 | const invokeCallback = useEvent(() => {
14 | callback?.({ w: window.innerWidth, height: window.innerHeight })
15 | })
16 | useEffect(() => {
17 | document.addEventListener('resize', invokeCallback)
18 | invokeCallback()
19 | return () => {
20 | document.removeEventListener('resize', invokeCallback)
21 | }
22 | }, [])
23 | }
24 |
--------------------------------------------------------------------------------
/src/hooks/useWindowDimensions.ts:
--------------------------------------------------------------------------------
1 | import { useEffect, useState } from 'react'
2 |
3 | type WindowDimentions = {
4 | width: number | undefined
5 | height: number | undefined
6 | isMobile: boolean
7 | }
8 |
9 | const useWindowDimensions = (breakPoint?: number): WindowDimentions => {
10 | const mobileWidth = breakPoint ?? 768
11 | const [windowDimensions, setWindowDimensions] = useState({
12 | width: undefined,
13 | height: undefined,
14 | isMobile: false
15 | })
16 | useEffect(() => {
17 | function handleResize(): void {
18 | setWindowDimensions({
19 | width: window.innerWidth,
20 | height: window.innerHeight,
21 | isMobile: window.innerWidth > mobileWidth ? false : true
22 | })
23 | }
24 | handleResize()
25 | window.addEventListener('resize', handleResize)
26 | return (): void => window.removeEventListener('resize', handleResize)
27 | }, [])
28 |
29 | return windowDimensions
30 | }
31 |
32 | export default useWindowDimensions
33 |
--------------------------------------------------------------------------------
/src/hooks/useWindowResize.ts:
--------------------------------------------------------------------------------
1 | import { useEffect, useState, useMemo } from 'react'
2 | import { debounce } from '@/utils/functionMethods'
3 |
4 | export default function useWindowResize(delay?: number) {
5 | const [size, setSize] = useState([0, 0])
6 | const debounceUpdate = useMemo(() => debounce(() => setSize([window.innerWidth, window.innerHeight]), delay || 100), [delay])
7 | useEffect(() => {
8 | const getSize = () => {
9 | debounceUpdate()
10 | }
11 | getSize()
12 | window.addEventListener('resize', getSize)
13 | return () => window.removeEventListener('resize', getSize)
14 | }, [debounceUpdate])
15 |
16 | return size
17 | }
18 |
--------------------------------------------------------------------------------
/src/icons/media/TelegrameMediaIcon.tsx:
--------------------------------------------------------------------------------
1 | import { SvgIcon } from '../type'
2 |
3 | /** used in PC nav top bar */
4 | export default function TelegrameMediaIcon(props: SvgIcon) {
5 | const { width = 32, height = 32, ...restProps } = props
6 |
7 | return (
8 |
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/src/icons/media/TwitterMediaIcon.tsx:
--------------------------------------------------------------------------------
1 | import { SvgIcon } from '../type'
2 |
3 | /** used in PC nav top bar */
4 | export default function TwitterMediaIcon(props: SvgIcon) {
5 | const { width = 32, height = 32, ...restProps } = props
6 |
7 | return (
8 |
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/src/icons/misc/AddLiquidityPlus.tsx:
--------------------------------------------------------------------------------
1 | import { colors } from '@/theme/cssVariables'
2 | import { SvgIcon } from '../type'
3 | import { forwardRef } from '@chakra-ui/react'
4 |
5 | export default forwardRef(function AddLiquidityPlus(props: SvgIcon, ref) {
6 | return (
7 |
14 | )
15 | })
16 |
--------------------------------------------------------------------------------
/src/icons/misc/AddTokenIcon.tsx:
--------------------------------------------------------------------------------
1 | import { forwardRef } from 'react'
2 | import { SvgIcon } from '../type'
3 |
4 | export default forwardRef(function AddTokenIcon(props: SvgIcon, ref: any) {
5 | return (
6 |
16 | )
17 | })
18 |
--------------------------------------------------------------------------------
/src/icons/misc/ChartInfoIcon.tsx:
--------------------------------------------------------------------------------
1 | import { SvgIcon } from '../type'
2 |
3 | export default function ChartInfoIcon(props: SvgIcon) {
4 | const { width = 16, height = 14 } = props
5 |
6 | return (
7 |
16 | )
17 | }
18 |
--------------------------------------------------------------------------------
/src/icons/misc/ChevronDoubleDownIcon.tsx:
--------------------------------------------------------------------------------
1 | import { SvgIcon } from '../type'
2 |
3 | export default function ChevronDownIcon(props: SvgIcon) {
4 | return (
5 |
21 | )
22 | }
23 |
--------------------------------------------------------------------------------
/src/icons/misc/ChevronDownIcon.tsx:
--------------------------------------------------------------------------------
1 | import { SvgIcon } from '../type'
2 |
3 | export default function ChevronDownIcon(props: SvgIcon) {
4 | return (
5 |
8 | )
9 | }
10 |
--------------------------------------------------------------------------------
/src/icons/misc/ChevronLeftIcon.tsx:
--------------------------------------------------------------------------------
1 | import { SvgIcon } from '../type'
2 |
3 | export default function ChevronLeftIcon(props: SvgIcon) {
4 | const { width = '18px', height = '18px', ...restProps } = props
5 | return (
6 |
9 | )
10 | }
11 |
--------------------------------------------------------------------------------
/src/icons/misc/ChevronRightIcon.tsx:
--------------------------------------------------------------------------------
1 | import { Box } from '@chakra-ui/react'
2 | import { SvgIcon } from '../type'
3 |
4 | export default function ChevronRightIcon(props: SvgIcon) {
5 | const { width = '18px', height = '18px' } = props
6 | return (
7 |
8 |
11 |
12 | )
13 | }
14 |
--------------------------------------------------------------------------------
/src/icons/misc/ChevronUpIcon.tsx:
--------------------------------------------------------------------------------
1 | import { SvgIcon } from '../type'
2 |
3 | export default function ChevronUpIcon(props: SvgIcon) {
4 | return (
5 |
17 | )
18 | }
19 |
--------------------------------------------------------------------------------
/src/icons/misc/CircleArrowDown.tsx:
--------------------------------------------------------------------------------
1 | import { forwardRef } from '@chakra-ui/react'
2 | import { SvgIcon } from '../type'
3 |
4 | /** use currentColor */
5 | export default forwardRef(function CircleArrowDown(props: SvgIcon, ref) {
6 | return (
7 |
24 | )
25 | })
26 |
--------------------------------------------------------------------------------
/src/icons/misc/CircleArrowRight.tsx:
--------------------------------------------------------------------------------
1 | import { forwardRef } from '@chakra-ui/react'
2 | import { SvgIcon } from '../type'
3 |
4 | /** use currentColor */
5 | export default forwardRef(function CircleArrowRight(props: SvgIcon, ref) {
6 | return (
7 |
24 | )
25 | })
26 |
--------------------------------------------------------------------------------
/src/icons/misc/CircleCheck.tsx:
--------------------------------------------------------------------------------
1 | import { SvgIcon } from '../type'
2 |
3 | /** use currentColor */
4 | export default function CircleCheck(props: SvgIcon) {
5 | const { width = 16, height = 16, fill = 'currentColor' } = props
6 |
7 | return (
8 |
18 | )
19 | }
20 |
--------------------------------------------------------------------------------
/src/icons/misc/CircleCheckBreaker.tsx:
--------------------------------------------------------------------------------
1 | import { colors } from '@/theme/cssVariables'
2 | import { SvgIcon } from '../type'
3 | import { forwardRef } from '@chakra-ui/react'
4 |
5 | export default forwardRef(function CircleCheckBreaker(props: SvgIcon, ref) {
6 | return (
7 |
24 | )
25 | })
26 |
--------------------------------------------------------------------------------
/src/icons/misc/CircleError.tsx:
--------------------------------------------------------------------------------
1 | import { colors } from '@/theme/cssVariables'
2 | import { SvgIcon } from '../type'
3 |
4 | export default function CircleError(props: SvgIcon) {
5 | const { width = 24, height = 24, color = colors.semanticError } = props
6 |
7 | return (
8 |
19 | )
20 | }
21 |
--------------------------------------------------------------------------------
/src/icons/misc/CirclePlus.tsx:
--------------------------------------------------------------------------------
1 | import { SvgIcon } from '../type'
2 |
3 | /** use currentColor */
4 | export default function CirclePlus(props: SvgIcon) {
5 | return (
6 |
22 | )
23 | }
24 |
--------------------------------------------------------------------------------
/src/icons/misc/Close.tsx:
--------------------------------------------------------------------------------
1 | import { SvgIcon } from '../type'
2 |
3 | export default function Close(props: SvgIcon) {
4 | const { width = 20, height = 20 } = props
5 |
6 | return (
7 |
15 | )
16 | }
17 |
--------------------------------------------------------------------------------
/src/icons/misc/CopyIcon.tsx:
--------------------------------------------------------------------------------
1 | import { colors } from '@/theme/cssVariables'
2 |
3 | import { SvgIcon } from '../type'
4 |
5 | export default function CopyIcon(props: SvgIcon) {
6 | const { color = colors.secondary } = props
7 |
8 | return (
9 |
12 | )
13 | }
14 |
--------------------------------------------------------------------------------
/src/icons/misc/DeleteIcon.tsx:
--------------------------------------------------------------------------------
1 | import { colors } from '@/theme/cssVariables'
2 |
3 | import { SvgIcon } from '../type'
4 |
5 | export default function DeleteIcon(props: SvgIcon) {
6 | const { width = 24, height = 24, fill = colors.primary } = props
7 |
8 | return (
9 |
24 | )
25 | }
26 |
--------------------------------------------------------------------------------
/src/icons/misc/ExclaimationOctagon.tsx:
--------------------------------------------------------------------------------
1 | import { SvgIcon } from '../type'
2 |
3 | export default function ExclaimationOctagon(props: SvgIcon) {
4 | const { width = 20, height = 20 } = props
5 |
6 | return (
7 |
25 | )
26 | }
27 |
--------------------------------------------------------------------------------
/src/icons/misc/ExpandDownIcon.tsx:
--------------------------------------------------------------------------------
1 | import { SvgIcon } from '../type'
2 |
3 | export default function ExpandDownIcon(props: SvgIcon) {
4 | const { width = 14, height = 14, stroke = '#22D1F8' } = props
5 |
6 | return (
7 |
23 | )
24 | }
25 |
--------------------------------------------------------------------------------
/src/icons/misc/ExpandLeftTopIcon.tsx:
--------------------------------------------------------------------------------
1 | import { SvgIcon } from '../type'
2 |
3 | export default function ExpandLeftTopIcon(props: SvgIcon) {
4 | const { width = 10, height = 10 } = props
5 |
6 | return (
7 |
20 | )
21 | }
22 |
--------------------------------------------------------------------------------
/src/icons/misc/ExpandUpIcon.tsx:
--------------------------------------------------------------------------------
1 | import { SvgIcon } from '../type'
2 |
3 | export default function ExpandUpIcon(props: SvgIcon) {
4 | return (
5 |
20 | )
21 | }
22 |
--------------------------------------------------------------------------------
/src/icons/misc/ExternalLink.tsx:
--------------------------------------------------------------------------------
1 | import { colors } from '@/theme/cssVariables'
2 | import { SvgIcon } from '../type'
3 |
4 | export default function ExternalLink(props: SvgIcon) {
5 | const { width = 14, height = 14, color = colors.secondary } = props
6 |
7 | return (
8 |
23 | )
24 | }
25 |
--------------------------------------------------------------------------------
/src/icons/misc/ExternalLinkLargeIcon.tsx:
--------------------------------------------------------------------------------
1 | import { colors } from '@/theme/cssVariables'
2 |
3 | import { SvgIcon } from '../type'
4 |
5 | export default function ExternalLinkLargeIcon(props: SvgIcon) {
6 | const { width = 14, height = 14, color = colors.priceFloatingUp } = props
7 |
8 | return (
9 |
25 | )
26 | }
27 |
--------------------------------------------------------------------------------
/src/icons/misc/HorizontalSwitchIcon.tsx:
--------------------------------------------------------------------------------
1 | import { SvgIcon } from '../type'
2 |
3 | export default function HorizontalSwitchIcon(props: SvgIcon) {
4 | return (
5 |
8 | )
9 | }
10 |
--------------------------------------------------------------------------------
/src/icons/misc/HorizontalSwitchSmallIcon.tsx:
--------------------------------------------------------------------------------
1 | import { SvgIcon } from '../type'
2 |
3 | export default function HorizontalSwitchSmallIcon(props: SvgIcon) {
4 | return (
5 |
8 | )
9 | }
10 |
--------------------------------------------------------------------------------
/src/icons/misc/InfoCircleIcon.tsx:
--------------------------------------------------------------------------------
1 | import { forwardRef } from 'react'
2 | import { SvgIcon } from '../type'
3 |
4 | export default forwardRef(function InfoCircleIcon(props: SvgIcon, ref: any) {
5 | return (
6 |
10 | )
11 | })
12 |
--------------------------------------------------------------------------------
/src/icons/misc/InputLockIcon.tsx:
--------------------------------------------------------------------------------
1 | import { forwardRef } from '@chakra-ui/react'
2 | import { SvgIcon } from '../type'
3 |
4 | export default forwardRef(function InputLockIcon(props: SvgIcon, ref) {
5 | return (
6 |
22 | )
23 | })
24 |
--------------------------------------------------------------------------------
/src/icons/misc/LiquidityLockIcon.tsx:
--------------------------------------------------------------------------------
1 | import { SvgIcon } from '../type'
2 |
3 | export default function LiquidityLockIcon(props: SvgIcon) {
4 | const { width = 12, height = 13 } = props
5 |
6 | return (
7 |
23 | )
24 | }
25 |
--------------------------------------------------------------------------------
/src/icons/misc/ListIcon.tsx:
--------------------------------------------------------------------------------
1 | import { SvgIcon } from '../type'
2 |
3 | export default function ListIcon(props: SvgIcon) {
4 | const { width = 20, height = 20 } = props
5 |
6 | return (
7 |
15 | )
16 | }
17 |
--------------------------------------------------------------------------------
/src/icons/misc/LockIcon.tsx:
--------------------------------------------------------------------------------
1 | import { SvgIcon } from '../type'
2 |
3 | export default function LockIcon(props: SvgIcon) {
4 | const { width = 12, height = 13 } = props
5 |
6 | return (
7 |
31 | )
32 | }
33 |
--------------------------------------------------------------------------------
/src/icons/misc/MenuHamburgerNavIcon.tsx:
--------------------------------------------------------------------------------
1 | import { colors } from '@/theme/cssVariables'
2 | import { SvgIcon } from '../type'
3 |
4 | export default function MenuHamburgerNavIcon(props: SvgIcon) {
5 | const { width = 40, height = 40, color = colors.textSecondary } = props
6 |
7 | return (
8 |
24 | )
25 | }
26 |
--------------------------------------------------------------------------------
/src/icons/misc/MinusIcon.tsx:
--------------------------------------------------------------------------------
1 | import { SvgIcon } from '../type'
2 |
3 | export default function MinusIcon(props: SvgIcon) {
4 | return (
5 |
11 | )
12 | }
13 |
--------------------------------------------------------------------------------
/src/icons/misc/OpenBookIcon.tsx:
--------------------------------------------------------------------------------
1 | import { colors } from '@/theme/cssVariables'
2 |
3 | import { SvgIcon } from '../type'
4 |
5 | export default function OpenBookIcon(props: SvgIcon) {
6 | const { width = 19, height = 12, fill = colors.textSecondary } = props
7 |
8 | return (
9 |
17 | )
18 | }
19 |
--------------------------------------------------------------------------------
/src/icons/misc/Plus.tsx:
--------------------------------------------------------------------------------
1 | import { SvgIcon } from '../type'
2 |
3 | export default function Plus(props: SvgIcon) {
4 | return (
5 |
9 | )
10 | }
11 |
--------------------------------------------------------------------------------
/src/icons/misc/PlusCircleIcon.tsx:
--------------------------------------------------------------------------------
1 | import { SvgIcon } from '../type'
2 |
3 | export default function PlusCircleIcon(props: SvgIcon) {
4 | return (
5 |
25 | )
26 | }
27 |
--------------------------------------------------------------------------------
/src/icons/misc/PlusIcon.tsx:
--------------------------------------------------------------------------------
1 | import { SvgIcon } from '../type'
2 |
3 | export default function PlusIcon(props: SvgIcon) {
4 | const { width = 16, height = 16 } = props
5 |
6 | return (
7 |
11 | )
12 | }
13 |
--------------------------------------------------------------------------------
/src/icons/misc/PriorityFastIcon.tsx:
--------------------------------------------------------------------------------
1 | import { SvgIcon } from '../type'
2 |
3 | export default function PriorityFastIcon(props: SvgIcon) {
4 | const { width = 24, height = 24, color = 'currentColor' } = props
5 |
6 | return (
7 |
10 | )
11 | }
12 |
--------------------------------------------------------------------------------
/src/icons/misc/PriorityFixIcon.tsx:
--------------------------------------------------------------------------------
1 | import { SvgIcon } from '../type'
2 |
3 | export default function PriorityFixIcon(props: SvgIcon) {
4 | const { width = 24, height = 24, color = 'currentColor' } = props
5 |
6 | return (
7 |
24 | )
25 | }
26 |
--------------------------------------------------------------------------------
/src/icons/misc/PriorityUltraIcon.tsx:
--------------------------------------------------------------------------------
1 | import { SvgIcon } from '../type'
2 |
3 | export default function PriorityUltraIcon(props: SvgIcon) {
4 | const { width = 24, height = 24, color = 'currentColor' } = props
5 |
6 | return (
7 |
10 | )
11 | }
12 |
--------------------------------------------------------------------------------
/src/icons/misc/PulseIcon.tsx:
--------------------------------------------------------------------------------
1 | import { SvgIcon } from '../type'
2 |
3 | export default function PulseIcon(props: SvgIcon) {
4 | return (
5 |
19 | )
20 | }
21 |
--------------------------------------------------------------------------------
/src/icons/misc/RemoveTokenIcon.tsx:
--------------------------------------------------------------------------------
1 | import { forwardRef } from 'react'
2 | import { SvgIcon } from '../type'
3 |
4 | export default forwardRef(function RemoveTokenIcon(props: SvgIcon, ref: any) {
5 | return (
6 |
12 | )
13 | })
14 |
--------------------------------------------------------------------------------
/src/icons/misc/SliderThumb.tsx:
--------------------------------------------------------------------------------
1 | import { SvgIcon } from '../type'
2 |
3 | export default function SliderThumbIcon(props: SvgIcon) {
4 | const { width = 25, height = 24 } = props
5 |
6 | return (
7 |
12 | )
13 | }
14 |
--------------------------------------------------------------------------------
/src/icons/misc/SortDownIcon.tsx:
--------------------------------------------------------------------------------
1 | import { SvgIcon } from '../type'
2 |
3 | export default function SortDownIcon(props: SvgIcon) {
4 | return (
5 |
8 | )
9 | }
10 |
--------------------------------------------------------------------------------
/src/icons/misc/SubtractIcon.tsx:
--------------------------------------------------------------------------------
1 | import { SvgIcon } from '../type'
2 |
3 | export default function SubtractIcon(props: SvgIcon) {
4 | const { width = 14, height = 14 } = props
5 |
6 | return (
7 |
24 | )
25 | }
26 |
--------------------------------------------------------------------------------
/src/icons/misc/SwapButtonOneTurnIcon.tsx:
--------------------------------------------------------------------------------
1 | import { colors } from '@/theme/cssVariables'
2 | import { SvgIcon } from '../type'
3 |
4 | export default function SwapButtonOneTurnIcon(props: SvgIcon) {
5 | return (
6 |
25 | )
26 | }
27 |
--------------------------------------------------------------------------------
/src/icons/misc/SwapChatEmptyIcon.tsx:
--------------------------------------------------------------------------------
1 | import { SvgIcon } from '../type'
2 |
3 | export default function SwapChatEmptyIcon(props: SvgIcon) {
4 | return (
5 |
11 | )
12 | }
13 |
--------------------------------------------------------------------------------
/src/icons/misc/SwapChatIcon.tsx:
--------------------------------------------------------------------------------
1 | import { SvgIcon } from '../type'
2 |
3 | export default function SwapChatIcon(props: SvgIcon) {
4 | return (
5 |
11 | )
12 | }
13 |
--------------------------------------------------------------------------------
/src/icons/misc/SwapExchangeIcon.tsx:
--------------------------------------------------------------------------------
1 | import { SvgIcon } from '../type'
2 |
3 | export default function SwapExchangeIcon(props: SvgIcon) {
4 | return (
5 |
25 | )
26 | }
27 |
--------------------------------------------------------------------------------
/src/icons/misc/SwapHorizontalIcon.tsx:
--------------------------------------------------------------------------------
1 | import { forwardRef } from 'react'
2 | import { SvgIcon } from '../type'
3 |
4 | export default forwardRef(function SwapHorizontalIcon(props: SvgIcon, ref: any) {
5 | return (
6 |
9 | )
10 | })
11 |
--------------------------------------------------------------------------------
/src/icons/misc/SwapIcon.tsx:
--------------------------------------------------------------------------------
1 | import { forwardRef } from 'react'
2 | import { SvgIcon } from '../type'
3 | import { useColorMode } from '@chakra-ui/react'
4 |
5 | export default forwardRef(function SwapIcon(props: SvgIcon, ref: any) {
6 | const { width = 16, height = 16 } = props
7 | const { colorMode } = useColorMode()
8 | const isLight = colorMode === 'light'
9 | const colorFill = isLight ? '#474ABB' : '#ABC4FF'
10 | return (
11 |
14 | )
15 | })
16 |
--------------------------------------------------------------------------------
/src/icons/misc/SwapMobileIcon.tsx:
--------------------------------------------------------------------------------
1 | import { forwardRef } from 'react'
2 | import { SvgIcon } from '../type'
3 | import { useColorMode } from '@chakra-ui/react'
4 |
5 | export default forwardRef(function SwapMobileIcon(props: SvgIcon, ref: any) {
6 | const { colorMode } = useColorMode()
7 | const isLight = colorMode === 'light'
8 | const colorFill = isLight ? '#474ABB' : "#ABC4FF"
9 | return (
10 |
13 | )
14 | })
15 |
--------------------------------------------------------------------------------
/src/icons/misc/SwapPoolItemIcon.tsx:
--------------------------------------------------------------------------------
1 | import { forwardRef } from 'react'
2 | import { SvgIcon } from '../type'
3 |
4 | export default forwardRef(function SwapPoolItemIcon(props: SvgIcon, ref: any) {
5 | const { width = 14, height = 14 } = props
6 | return (
7 |
10 | )
11 | })
12 |
--------------------------------------------------------------------------------
/src/icons/misc/WalletSelectEggIcon.tsx:
--------------------------------------------------------------------------------
1 | import { SvgIcon } from '../type'
2 | import { Box } from '@chakra-ui/react'
3 |
4 | export default function WalletSelectEggIcon(props: SvgIcon) {
5 | const { width = '20px', height = '20px', color = 'currentColor' } = props
6 |
7 | return (
8 |
9 |
24 |
25 | )
26 | }
27 |
--------------------------------------------------------------------------------
/src/icons/misc/WalletSelectWalletIcon.tsx:
--------------------------------------------------------------------------------
1 | import { SvgIcon } from '../type'
2 | import { Box } from '@chakra-ui/react'
3 |
4 | export default function WalletSelectWalletIcon(props: SvgIcon) {
5 | const { width = '20px', height = '20px', color = 'currentColor' } = props
6 |
7 | return (
8 |
9 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | )
27 | }
28 |
--------------------------------------------------------------------------------
/src/icons/pageNavigation/AcceleraytorPageThumbnailIcon.tsx:
--------------------------------------------------------------------------------
1 | import { SvgIcon } from '../type'
2 |
3 | /** used in PC nav top bar */
4 | export default function AcceleraytorPageThumbnailIcon(props: SvgIcon) {
5 | const { width = 16, height = 16, ...restProps } = props
6 |
7 | return (
8 |
9 |
13 |
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/src/icons/pageNavigation/FeedbackThumbnailIcon.tsx:
--------------------------------------------------------------------------------
1 | import { SvgIcon } from '../type'
2 |
3 | /** used in PC nav top bar */
4 | export default function FeedbackThumbnailIcon(props: SvgIcon) {
5 | const { width = 14, height = 14, ...restProps } = props
6 |
7 | return (
8 |
9 |
13 |
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/src/icons/pageNavigation/StakingPageThumbnailIcon.tsx:
--------------------------------------------------------------------------------
1 | import { SvgIcon } from '../type'
2 |
3 | /** used in PC nav top bar */
4 | export default function StakingPageThumbnailIcon(props: SvgIcon) {
5 | const { width = 16, height = 16, ...restProps } = props
6 |
7 | return (
8 |
9 |
15 |
16 | )
17 | }
18 |
--------------------------------------------------------------------------------
/src/icons/type.ts:
--------------------------------------------------------------------------------
1 | import { SVGProps } from 'react'
2 | import { BoxProps } from '@chakra-ui/react'
3 |
4 | export type SvgIcon = SVGProps & BoxProps & Omit, keyof BoxProps>
5 |
--------------------------------------------------------------------------------
/src/icons/wallet/Binance.tsx:
--------------------------------------------------------------------------------
1 | import { SvgIcon } from '../type'
2 |
3 | export default function Binance(props: SvgIcon) {
4 | return (
5 |
6 |
10 |
11 | )
12 | }
13 |
--------------------------------------------------------------------------------
/src/icons/wallet/Coinbase.tsx:
--------------------------------------------------------------------------------
1 | import { SvgIcon } from '../type'
2 |
3 | export default function Coinbase(props: SvgIcon) {
4 | return (
5 |
18 |
23 |
29 |
30 | )
31 | }
32 |
--------------------------------------------------------------------------------
/src/icons/wallet/Safepal.tsx:
--------------------------------------------------------------------------------
1 | import { SvgIcon } from '../type'
2 |
3 | export default function Safepal(props: SvgIcon) {
4 | return (
5 |
18 |
27 |
28 | )
29 | }
30 |
--------------------------------------------------------------------------------
/src/icons/wallet/Trustwallet.tsx:
--------------------------------------------------------------------------------
1 | import { SvgIcon } from '../type'
2 |
3 | export default function Trustwallet(props: SvgIcon) {
4 | return (
5 |
6 |
7 |
11 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | )
27 | }
28 |
--------------------------------------------------------------------------------
/src/icons/wallet/Walletconnect.tsx:
--------------------------------------------------------------------------------
1 | import { SvgIcon } from '../type'
2 |
3 | export default function Walletconnect(props: SvgIcon) {
4 | return (
5 |
6 |
10 |
11 | )
12 | }
13 |
--------------------------------------------------------------------------------
/src/instrumentation.ts:
--------------------------------------------------------------------------------
1 | export async function register() {
2 | if (process.env.NEXT_RUNTIME === 'nodejs') {
3 | await import('../sentry.server.config');
4 | }
5 |
6 | if (process.env.NEXT_RUNTIME === 'edge') {
7 | await import('../sentry.edge.config');
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/pages/404.tsx:
--------------------------------------------------------------------------------
1 | import { useEffect } from 'react'
2 | import { useRouter } from 'next/router'
3 |
4 | export default function Page404() {
5 | const router = useRouter()
6 |
7 | useEffect(() => {
8 | router.push('/')
9 | }, [])
10 |
11 | return null
12 | }
13 |
--------------------------------------------------------------------------------
/src/pages/_document.tsx:
--------------------------------------------------------------------------------
1 | import { theme } from '@/theme'
2 | import { ColorModeScript } from '@chakra-ui/react'
3 | import NextDocument, { Html, Main, Head, NextScript } from 'next/document'
4 |
5 | /**
6 | * @see https://chakra-ui.com/docs/styled-system/color-mode#for-nextjs
7 | */
8 | export default class Document extends NextDocument {
9 | render() {
10 | return (
11 |
12 |
13 |
14 | {/* 👇 Here's the script */}
15 |
16 |
17 |
18 |
19 |
20 | )
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/pages/_error.jsx:
--------------------------------------------------------------------------------
1 | import * as Sentry from "@sentry/nextjs";
2 | import Error from "next/error";
3 |
4 | const CustomErrorComponent = (props) => {
5 | return ;
6 | };
7 |
8 | CustomErrorComponent.getInitialProps = async (contextData) => {
9 | // In case this is running in a serverless function, await this in order to give Sentry
10 | // time to send the error before the lambda exits
11 | await Sentry.captureUnderscoreErrorException(contextData);
12 |
13 | // This will contain the status code of the response
14 | return Error.getInitialProps(contextData);
15 | };
16 |
17 | export default CustomErrorComponent;
18 |
--------------------------------------------------------------------------------
/src/pages/bridge.tsx:
--------------------------------------------------------------------------------
1 | import dynamic from 'next/dynamic'
2 | const Wormhole = dynamic(() => import('@/features/Wormhole'))
3 |
4 | function Bridge() {
5 | return
6 | }
7 |
8 | export default Bridge
9 |
10 | export async function getStaticProps() {
11 | return {
12 | props: { title: 'Wormhole' }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/pages/clmm/create-pool.tsx:
--------------------------------------------------------------------------------
1 | import { useClmmStore, useAppStore } from '@/store'
2 | import { useEffect } from 'react'
3 | import dynamic from 'next/dynamic'
4 |
5 | const CreatePool = dynamic(() => import('@/features/Create/ClmmPool'))
6 |
7 | function CreatePoolPage() {
8 | const raydium = useAppStore((s) => s.raydium)
9 | const fetchAmmConfigsAct = useClmmStore((s) => s.fetchAmmConfigsAct)
10 |
11 | useEffect(() => {
12 | if (!raydium) return
13 | fetchAmmConfigsAct()
14 | }, [raydium, fetchAmmConfigsAct])
15 |
16 | return
17 | }
18 |
19 | export default CreatePoolPage
20 |
21 | export async function getStaticProps() {
22 | return {
23 | props: { title: 'Create Clmm Pool' }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/pages/clmm/create-position.tsx:
--------------------------------------------------------------------------------
1 | import { useEffect } from 'react'
2 | import dynamic from 'next/dynamic'
3 | import { useClmmStore } from '@/store'
4 |
5 | const CreatePosition = dynamic(() => import('@/features/Clmm/ClmmPosition'))
6 |
7 | const action = { type: 'CreatePositionPage' }
8 |
9 | function CreatePositionPage() {
10 | useEffect(
11 | () => () => {
12 | useClmmStore.setState(
13 | {
14 | currentPoolInfo: undefined
15 | },
16 | false,
17 | action
18 | )
19 | },
20 | []
21 | )
22 |
23 | return
24 | }
25 |
26 | export default CreatePositionPage
27 |
28 | export async function getStaticProps() {
29 | return {
30 | props: { title: 'Create Clmm Position' }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/pages/clmm/lock.tsx:
--------------------------------------------------------------------------------
1 | import dynamic from 'next/dynamic'
2 |
3 | const Lock = dynamic(() => import('@/features/Clmm/Lock'))
4 |
5 | function LockPage() {
6 | return
7 | }
8 |
9 | export default LockPage
10 |
11 | export async function getStaticProps() {
12 | return {
13 | props: { title: 'Burn Clmm Pool' }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/pages/debug.tsx:
--------------------------------------------------------------------------------
1 | import Debug from '@/features/Debug'
2 |
3 | export default function DebugPage() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/src/pages/farms/create.tsx:
--------------------------------------------------------------------------------
1 | import CreateFarm from '@/features/Farm/Create'
2 |
3 | function FarmCreatePage() {
4 | return
5 | }
6 |
7 | export default FarmCreatePage
8 |
9 | export async function getStaticProps() {
10 | return {
11 | props: { title: 'Create Farm' }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/pages/farms/edit.tsx:
--------------------------------------------------------------------------------
1 | import { useEffect } from 'react'
2 | import EditFarm from '@/features/Farm/Edit'
3 | import { useAppStore, useClmmStore } from '@/store'
4 |
5 | function FarmEditPage() {
6 | const raydium = useAppStore((s) => s.raydium)
7 | const loadAddRewardWhiteListAct = useClmmStore((s) => s.loadAddRewardWhiteListAct)
8 |
9 | useEffect(() => {
10 | raydium && loadAddRewardWhiteListAct({ checkFetch: true })
11 | }, [loadAddRewardWhiteListAct, raydium])
12 |
13 | return
14 | }
15 |
16 | export default FarmEditPage
17 |
18 | export async function getStaticProps() {
19 | return {
20 | props: { title: 'Edit Farm' }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/pages/index.tsx:
--------------------------------------------------------------------------------
1 | import { useEffect } from 'react'
2 | import { Flex } from '@chakra-ui/react'
3 | import type { NextPage } from 'next'
4 | import { useRouter } from 'next/router'
5 | // import Entry from '@/components/LandingPage/Entry'
6 | // import Facilitate from '@/components/LandingPage/Facilitate'
7 | // import Feature from '@/components/LandingPage/Feature'
8 | // import Footer from '@/components/LandingPage/Footer'
9 | // import Header from '@/components/LandingPage/Header'
10 | // import Liquidity from '@/components/LandingPage/Liquidity'
11 | // import Partner from '@/components/LandingPage/Partner'
12 | // import ProtocolStat from '@/components/LandingPage/ProtocolStat'
13 |
14 | const Home: NextPage = () => {
15 | const router = useRouter()
16 | useEffect(() => {
17 | // no ssr
18 | router.replace('/swap')
19 | }, [])
20 | return (
21 |
22 | {/*
23 |
24 |
25 |
26 |
27 |
28 |
29 | */}
30 |
31 | )
32 | }
33 |
34 | export default Home
35 |
--------------------------------------------------------------------------------
/src/pages/liquidity-pools.tsx:
--------------------------------------------------------------------------------
1 | import dynamic from 'next/dynamic'
2 | const Pools = dynamic(() => import('@/features/Pools'))
3 |
4 | function LiquidityPoolsPage() {
5 | return
6 | }
7 |
8 | export default LiquidityPoolsPage
9 |
10 | export async function getStaticProps() {
11 | return {
12 | props: { title: 'Liquidity Pools' }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/pages/liquidity/create-farm.tsx:
--------------------------------------------------------------------------------
1 | import dynamic from 'next/dynamic'
2 | const CreateFarm = dynamic(() => import('@/features/Farm/Create'))
3 |
4 | function CreateFarmPage() {
5 | return
6 | }
7 |
8 | export default CreateFarmPage
9 |
10 | export async function getStaticProps() {
11 | return {
12 | props: { title: 'Create Farm' }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/pages/liquidity/create-pool.tsx:
--------------------------------------------------------------------------------
1 | import dynamic from 'next/dynamic'
2 | import { useLiquidityStore, useAppStore } from '@/store'
3 | import { useEffect } from 'react'
4 |
5 | const CreatePool = dynamic(() => import('@/features/Create/StandardPool'))
6 |
7 | function CreatePoolPage() {
8 | const raydium = useAppStore((s) => s.raydium)
9 | const fetchCpmmConfigsAct = useLiquidityStore((s) => s.fetchCpmmConfigsAct)
10 |
11 | useEffect(() => {
12 | if (!raydium) return
13 | fetchCpmmConfigsAct()
14 | }, [raydium, fetchCpmmConfigsAct])
15 |
16 | return
17 | }
18 |
19 | export default CreatePoolPage
20 |
21 | export async function getStaticProps() {
22 | return {
23 | props: { title: 'Create Pool' }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/pages/liquidity/decrease.tsx:
--------------------------------------------------------------------------------
1 | import dynamic from 'next/dynamic'
2 | const Decrease = dynamic(() => import('@/features/Liquidity/Decrease'))
3 |
4 | function DecreasePage() {
5 | return
6 | }
7 |
8 | export default DecreasePage
9 |
10 | export async function getStaticProps() {
11 | return {
12 | props: { title: 'Liquidity Decrease' }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/pages/liquidity/increase.tsx:
--------------------------------------------------------------------------------
1 | import dynamic from 'next/dynamic'
2 | const Increase = dynamic(() => import('@/features/Liquidity/Increase'))
3 |
4 | function IncreasePage() {
5 | return
6 | }
7 |
8 | export default IncreasePage
9 |
10 | export async function getStaticProps() {
11 | return {
12 | props: { title: 'Liquidity Increase' }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/pages/moonpay.tsx:
--------------------------------------------------------------------------------
1 | import dynamic from 'next/dynamic'
2 | const Moonpay = dynamic(() => import('@/features/Moonpay'))
3 |
4 | function MoonpayPage() {
5 | return
6 | }
7 |
8 | export default MoonpayPage
9 |
10 | export async function getStaticProps() {
11 | return {
12 | props: { title: 'Moonpay' }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/pages/playground.tsx:
--------------------------------------------------------------------------------
1 | import ComponentSpecification from '@/features/ComponentSpecification'
2 |
3 | export default function DEVPlaygroundPage() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/src/pages/portfolio.tsx:
--------------------------------------------------------------------------------
1 | import dynamic from 'next/dynamic'
2 | const Portfolio = dynamic(() => import('@/features/Portfolio'))
3 |
4 | function PortfolioPage() {
5 | return
6 | }
7 |
8 | export default PortfolioPage
9 |
10 | export async function getStaticProps() {
11 | return {
12 | props: { title: 'Portfolio' }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/pages/settings.tsx:
--------------------------------------------------------------------------------
1 | import { Flex, Box, Text } from '@chakra-ui/react'
2 | import { useAppStore } from '@/store/useAppStore'
3 |
4 | export default function SettingsPage() {
5 | const [urlConfigs, programIdConfig] = useAppStore((s) => [s.urlConfigs, s.programIdConfig])
6 | return (
7 |
8 |
9 | API
10 |
11 |
12 |
13 | BASE HOST:
14 | {urlConfigs.BASE_HOST}
15 |
16 |
17 | SWAP HOST:
18 | {urlConfigs.SWAP_HOST}
19 |
20 |
21 |
22 | Program ID
23 |
24 |
25 | {Object.keys(programIdConfig).map((config) => (
26 |
27 | {config}:
28 | {programIdConfig[config as keyof typeof programIdConfig]?.toString()}
29 |
30 | ))}
31 |
32 |
33 | )
34 | }
35 |
--------------------------------------------------------------------------------
/src/pages/staking.tsx:
--------------------------------------------------------------------------------
1 | import Staking from '@/features/Staking'
2 |
3 | function StakingPage() {
4 | return
5 | }
6 |
7 | export default StakingPage
8 |
9 | export async function getStaticProps() {
10 | return {
11 | props: { title: 'Staking' }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/pages/swap.tsx:
--------------------------------------------------------------------------------
1 | import dynamic from 'next/dynamic'
2 |
3 | const Swap = dynamic(() => import('@/features/Swap'))
4 |
5 | function SwapPage() {
6 | return
7 | }
8 |
9 | export default SwapPage
10 |
11 | export async function getStaticProps() {
12 | return {
13 | props: { title: 'Swap' }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/provider/Ledger/polyfill.ts:
--------------------------------------------------------------------------------
1 | import { Buffer } from 'buffer'
2 |
3 | if (typeof window !== 'undefined' && window.Buffer === undefined) {
4 | // eslint-disable-next-line @typescript-eslint/no-extra-semi
5 | ;(window as any).Buffer = Buffer
6 | }
7 |
8 | export {}
9 |
--------------------------------------------------------------------------------
/src/store/configs/market.tsx:
--------------------------------------------------------------------------------
1 | import { Trans } from 'react-i18next'
2 | import { Text } from '@chakra-ui/react'
3 | import i18n from '@/i18n'
4 | import { colors } from '@/theme/cssVariables/colors'
5 |
6 | const MARKET_TX_MSG = {
7 | create: {
8 | title: 'create_market.title',
9 | desc: 'create_market.desc',
10 | txHistoryTitle: 'create_market.title',
11 | txHistoryDesc: 'create_market.desc',
12 | components: { sub: }
13 | }
14 | }
15 |
16 | export const getTxMeta = ({ action, values }: { action: keyof typeof MARKET_TX_MSG; values: Record }) => {
17 | const meta = MARKET_TX_MSG[action]
18 | return {
19 | title: i18n.t(meta.title, values),
20 | description: ,
21 | txHistoryTitle: meta.txHistoryTitle || meta.title,
22 | txHistoryDesc: meta.txHistoryDesc || meta.desc,
23 | txValues: values
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/store/index.ts:
--------------------------------------------------------------------------------
1 | export * from './useAppStore'
2 | export * from './useLiquidityStore'
3 | export * from './useTokenStore'
4 | export * from './useFarmStore'
5 | export * from './useTokenAccountStore'
6 | export * from './useEVMStore'
7 | export * from './useClmmStore'
8 | export * from './useCreateMarketStore'
9 | export { default as createStore } from './createStore'
10 |
--------------------------------------------------------------------------------
/src/store/useEVMStore.ts:
--------------------------------------------------------------------------------
1 | import { Connection } from '@solana/web3.js'
2 | import { isClient } from '@/utils/common'
3 | import createStore from './createStore'
4 |
5 | interface EVNState {
6 | chainId: number
7 | connection?: Connection
8 | address?: string
9 |
10 | setChainIdAct: (chainId: number) => void
11 | }
12 |
13 | const CHAIN_CACHE_KEY = '_ray_chain_id_'
14 |
15 | const evmInitState = {
16 | chainId: Number(isClient() ? localStorage.getItem(CHAIN_CACHE_KEY) || 1 : 1)
17 | }
18 |
19 | export const useEVMStore = createStore((set) => {
20 | return {
21 | ...evmInitState,
22 | setChainIdAct: (chainId) => {
23 | set({ chainId }, false, { type: 'setChainIdAct' })
24 | isClient() && localStorage.setItem(CHAIN_CACHE_KEY, chainId.toString())
25 | },
26 | reset: () => set(evmInitState)
27 | }
28 | }, 'useEVMStore')
29 |
--------------------------------------------------------------------------------
/src/theme/components/Alert.ts:
--------------------------------------------------------------------------------
1 | import { alertAnatomy } from '@chakra-ui/anatomy'
2 | import { createMultiStyleConfigHelpers } from '@chakra-ui/react'
3 |
4 | import { colors } from '../cssVariables'
5 |
6 | const { definePartsStyle, defineMultiStyleConfig } = createMultiStyleConfigHelpers(alertAnatomy.keys)
7 |
8 | const baseStyle = definePartsStyle({
9 | container: {
10 | pr: 8,
11 | pl: 6,
12 | py: 5,
13 | bg: colors.backgroundMedium,
14 | borderTopRightRadius: '12px',
15 | borderBottomRightRadius: '12px'
16 | },
17 | title: {
18 | fontWeight: 500,
19 | fontSize: '16px',
20 | lineHeight: '20px',
21 | color: colors.primary
22 | },
23 | description: {
24 | fontWeight: 300,
25 | fontSize: '14px',
26 | lineHeight: '16px',
27 | mt: 3,
28 | color: 'rgba(196, 214, 255, 0.5)'
29 | }
30 | })
31 |
32 | export const Alert = defineMultiStyleConfig({ baseStyle })
33 |
--------------------------------------------------------------------------------
/src/theme/components/Avatar.ts:
--------------------------------------------------------------------------------
1 | export const Avatar = {
2 | defaultProps: {
3 | variant: 'sm',
4 | colorScheme: 'blue' // default is gray
5 | },
6 | baseStyle: {
7 | container: {
8 | bg: 'transparent',
9 | color: '#fff'
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/theme/components/Card.ts:
--------------------------------------------------------------------------------
1 | import { cardAnatomy } from '@chakra-ui/anatomy'
2 | import { createMultiStyleConfigHelpers } from '@chakra-ui/react'
3 | import { colors } from '../cssVariables'
4 |
5 | const { definePartsStyle, defineMultiStyleConfig } = createMultiStyleConfigHelpers(cardAnatomy.keys)
6 |
7 | const baseStyle = definePartsStyle({
8 | container: {
9 | '--card-bg': colors.backgroundLight,
10 | px: 8,
11 | py: 12
12 | }
13 | })
14 |
15 | export const Card = defineMultiStyleConfig({ variants: { unstyled: baseStyle }, defaultProps: { variant: 'unstyled' } })
16 |
--------------------------------------------------------------------------------
/src/theme/components/Checkbox.ts:
--------------------------------------------------------------------------------
1 | import { checkboxAnatomy } from '@chakra-ui/anatomy'
2 | import { createMultiStyleConfigHelpers } from '@chakra-ui/react'
3 | import { colors } from '../cssVariables'
4 |
5 | const { definePartsStyle, defineMultiStyleConfig } = createMultiStyleConfigHelpers(checkboxAnatomy.keys)
6 |
7 | const baseStyle = definePartsStyle({
8 | icon: {
9 | color: colors.backgroundDark
10 | },
11 | control: {
12 | backgroundColor: colors.buttonBg01,
13 | borderWidth: '0',
14 | borderRadius: '4px',
15 | _checked: {
16 | backgroundColor: colors.secondary,
17 | borderColor: 'transparent',
18 | '&:hover': {
19 | backgroundColor: colors.secondary,
20 | borderColor: 'transparent'
21 | }
22 | }
23 | }
24 | })
25 | export const Checkbox = defineMultiStyleConfig({ baseStyle })
26 |
--------------------------------------------------------------------------------
/src/theme/components/Divider.ts:
--------------------------------------------------------------------------------
1 | import { defineStyle, defineStyleConfig } from '@chakra-ui/react'
2 |
3 | import { colors } from '../cssVariables'
4 |
5 | const solid = defineStyle({
6 | borderWidth: '1.5px', // change the width of the border
7 | borderStyle: 'solid', // change the style of the border
8 | borderRadius: 10, // set border radius to 10
9 | borderColor: colors.dividerBg
10 | })
11 |
12 | const dash = defineStyle({
13 | borderWidth: '2px',
14 | borderStyle: 'dashed',
15 | borderColor: colors.dividerBg
16 | })
17 |
18 | export const dividerTheme = defineStyleConfig({
19 | variants: { solid, dash }
20 | })
21 |
--------------------------------------------------------------------------------
/src/theme/components/FormLabel.ts:
--------------------------------------------------------------------------------
1 | import { defineStyle, defineStyleConfig } from '@chakra-ui/react'
2 | import { colors } from '../cssVariables'
3 |
4 | export const FormLabel = defineStyleConfig({
5 | baseStyle: defineStyle({
6 | marginBottom: '0',
7 | fontSize: '14px',
8 | color: colors.textTertiary
9 | })
10 | })
11 |
--------------------------------------------------------------------------------
/src/theme/components/Link.ts:
--------------------------------------------------------------------------------
1 | import { colors } from '../cssVariables'
2 |
3 | export const Link = {
4 | variants: {
5 | outline: {
6 | textDecoration: 'none',
7 | '&:hover': {
8 | textDecoration: 'none'
9 | }
10 | },
11 | highlight: {
12 | color: colors.textSeptenary,
13 | textDecoration: 'underline'
14 | }
15 | },
16 | baseStyle: { fontWeight: 500, color: colors.textLink, display: 'inline' }
17 | }
18 |
--------------------------------------------------------------------------------
/src/theme/components/Popover.ts:
--------------------------------------------------------------------------------
1 | import { colors } from '../cssVariables'
2 |
3 | export const Popover = {
4 | baseStyle: {
5 | popper: {
6 | border: 'none',
7 | '--popper-arrow-size': '12px'
8 | },
9 | header: {
10 | border: 'none',
11 | paddingBottom: '0',
12 | fontSize: '14px',
13 | fontWeight: '500',
14 | color: colors.textPrimary
15 | },
16 | body: {
17 | paddingTop: '0',
18 | fontSize: '12px',
19 | color: colors.textSecondary
20 | },
21 | content: {
22 | bg: colors.popoverBg,
23 | border: 'none',
24 | width: 'fit-content',
25 | maxWidth: '300px'
26 | },
27 | arrow: {
28 | boxShadow: 'none !important',
29 | borderColor: colors.popoverBg,
30 | bg: `${colors.popoverBg} !important`
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/theme/components/Progress.ts:
--------------------------------------------------------------------------------
1 | import { progressAnatomy } from '@chakra-ui/anatomy'
2 | import { createMultiStyleConfigHelpers } from '@chakra-ui/react'
3 | import { colors } from '../cssVariables'
4 |
5 | const { definePartsStyle, defineMultiStyleConfig } = createMultiStyleConfigHelpers(progressAnatomy.keys)
6 |
7 | const baseStyle = definePartsStyle({
8 | track: {
9 | bg: colors.backgroundDark,
10 | borderRadius: '100vw'
11 | },
12 | filledTrack: {
13 | bg: colors.filledProgressBg
14 | }
15 | })
16 |
17 | export const Progress = defineMultiStyleConfig({ baseStyle })
18 |
--------------------------------------------------------------------------------
/src/theme/components/Slider.ts:
--------------------------------------------------------------------------------
1 | import { sliderAnatomy } from '@chakra-ui/anatomy'
2 | import { createMultiStyleConfigHelpers } from '@chakra-ui/react'
3 |
4 | import { colors } from '../cssVariables'
5 |
6 | const { definePartsStyle, defineMultiStyleConfig } = createMultiStyleConfigHelpers(sliderAnatomy.keys)
7 |
8 | const baseStyle = definePartsStyle({
9 | container: {
10 | pb: 4
11 | },
12 | filledTrack: {
13 | bg: colors.secondary
14 | },
15 | track: {
16 | bg: colors.backgroundDark
17 | },
18 | thumb: {
19 | bg: colors.secondary,
20 | boxSize: '24px',
21 | _active: {
22 | transform: 'translateY(-50%)'
23 | }
24 | },
25 | mark: {
26 | color: colors.textSecondary,
27 | mt: '16px',
28 | fontSize: '12px',
29 | fontWeight: '500',
30 | transform: 'translateX(var(--tx, 0))',
31 | bg: colors.backgroundTransparent12,
32 | borderRadius: '4px',
33 | py: '2px',
34 | px: '4px'
35 | }
36 | })
37 |
38 | export const Slider = defineMultiStyleConfig({ baseStyle })
39 |
--------------------------------------------------------------------------------
/src/theme/components/Spinner.ts:
--------------------------------------------------------------------------------
1 | import { colors } from '../cssVariables'
2 |
3 | export const Spinner = {
4 | baseStyle: {
5 | colorScheme: {
6 | color: colors.textSecondary
7 | }
8 | }
9 | // sizes: {
10 | // lg: {
11 | // number: {
12 | // fontSize: 'md'
13 | // },
14 | // title: {
15 | // fontSize: 'sm'
16 | // },
17 | // description: {
18 | // fontSize: 'md'
19 | // },
20 | // separator: {
21 | // marginLeft: '5px',
22 | // marginTop: '7.5px'
23 | // }
24 | // }
25 | // }
26 | }
27 |
--------------------------------------------------------------------------------
/src/theme/components/Stepper.ts:
--------------------------------------------------------------------------------
1 | import { colors } from '../cssVariables'
2 |
3 | export const Stepper = {
4 | baseStyle: {
5 | indicator: {
6 | '&[data-status=active]': {
7 | borderWidth: '0px',
8 | color: colors.backgroundDark
9 | },
10 | borderWidth: 'transparent',
11 | bg: colors.primary
12 | },
13 | separator: {
14 | background: colors.primary
15 | }
16 | },
17 | sizes: {
18 | lg: {
19 | number: {
20 | fontSize: 'md'
21 | },
22 | title: {
23 | fontSize: 'sm'
24 | },
25 | description: {
26 | fontSize: 'md'
27 | },
28 | separator: {
29 | marginLeft: '5px',
30 | marginTop: '7.5px'
31 | }
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/theme/components/Switch.ts:
--------------------------------------------------------------------------------
1 | import { switchAnatomy } from '@chakra-ui/anatomy'
2 | import { createMultiStyleConfigHelpers } from '@chakra-ui/react'
3 | import { colors } from '../cssVariables'
4 |
5 | const { definePartsStyle, defineMultiStyleConfig } = createMultiStyleConfigHelpers(switchAnatomy.keys)
6 |
7 | const baseStyle = definePartsStyle({
8 | thumb: {
9 | bg: colors.switchOff,
10 | opacity: 0.5,
11 | _checked: {
12 | bg: colors.switchOn,
13 | opacity: 1
14 | }
15 | },
16 | track: {
17 | bg: colors.backgroundTransparent12
18 | }
19 | })
20 | const sm = definePartsStyle({
21 | container: { '--switch-track-width': '1.5em' },
22 | track: { width: '1.5em' }
23 | })
24 | const md = definePartsStyle({
25 | container: { '--switch-track-width': '2.25em' },
26 | track: { width: '2.25em' }
27 | })
28 | const lg = definePartsStyle({
29 | container: { '--switch-track-width': '3.5em' },
30 | track: { width: '3.5em' }
31 | })
32 |
33 | export const Switch = defineMultiStyleConfig({ baseStyle, sizes: { sm, md, lg } })
34 |
--------------------------------------------------------------------------------
/src/theme/components/Table.ts:
--------------------------------------------------------------------------------
1 | import { tableAnatomy } from '@chakra-ui/anatomy'
2 | import { createMultiStyleConfigHelpers } from '@chakra-ui/react'
3 |
4 | const { definePartsStyle, defineMultiStyleConfig } = createMultiStyleConfigHelpers(tableAnatomy.keys)
5 |
6 | const baseStyle = definePartsStyle({
7 | // define the parts you're going to style
8 | thead: {
9 | th: {
10 | py: '10px',
11 | '&:last-child td': {
12 | borderBottom: 'none'
13 | }
14 | }
15 | },
16 | tbody: {}
17 | })
18 |
19 | export const Table = defineMultiStyleConfig({ baseStyle, defaultProps: { size: 'sm' } })
20 |
--------------------------------------------------------------------------------
/src/theme/components/Text.ts:
--------------------------------------------------------------------------------
1 | import { colors } from '../cssVariables'
2 |
3 | export const Text = {
4 | variants: {
5 | dialogTitle: {
6 | fontSize: '20px',
7 | fontWeight: 500,
8 | color: colors.textPrimary
9 | },
10 | title: {
11 | fontSize: 'md',
12 | fontWeight: 500,
13 | color: colors.textSecondary
14 | },
15 | subTitle: {
16 | fontSize: 'sm',
17 | fontWeight: 400,
18 | color: colors.textSecondary
19 | },
20 | label: {
21 | fontSize: 'xs',
22 | color: colors.textTertiary
23 | },
24 | error: {
25 | fontSize: 'sm',
26 | fontWeight: 400,
27 | color: colors.textPink
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/theme/components/Tooltip.ts:
--------------------------------------------------------------------------------
1 | import { defineStyle, defineStyleConfig, Tooltip as _Tooltip } from '@chakra-ui/react'
2 | import { colors } from '../cssVariables'
3 |
4 | const baseStyle = defineStyle({
5 | // '--popper-arrow-bg': commonTheme.colors.lightenMain,
6 | '--tooltip-bg': `revert !important`,
7 | '--tooltip-fg': `${colors.textSecondary} !important`,
8 | fontSize: '14px',
9 | borderRadius: '8px',
10 | py: 3,
11 | px: 4
12 | })
13 | const card = defineStyle({
14 | py: 'revert',
15 | px: 'revert',
16 | borderRadius: '12px'
17 | })
18 |
19 | _Tooltip.defaultProps = {
20 | hasArrow: true,
21 | placement: 'top'
22 | }
23 |
24 | export const Tooltip = defineStyleConfig({
25 | baseStyle,
26 | variants: { card }
27 | })
28 |
--------------------------------------------------------------------------------
/src/theme/cssBlocks.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * for faster development, just pass css blocks to chakra-ui component
3 | */
4 |
5 | import { SystemProps } from '@chakra-ui/react'
6 | import { colors, sizes } from './cssVariables'
7 |
8 | export const heroGridientColorCSSBlock: SystemProps = {
9 | background: colors.brandGradient,
10 | backgroundClip: 'text',
11 | color: 'transparent',
12 | fontSize: sizes.textHeroTitle,
13 | fontWeight: '700'
14 | }
15 |
16 | export const panelCard: SystemProps = {
17 | bg: colors.backgroundLight,
18 | border: colors.panelCardBorder,
19 | boxShadow: colors.panelCardShadow,
20 | borderRadius: ['12px', '20px'],
21 | overflow: 'hidden'
22 | }
23 |
--------------------------------------------------------------------------------
/src/theme/cssVariables/index.ts:
--------------------------------------------------------------------------------
1 | export * from './colors'
2 | export * from './shadow'
3 | export * from './size'
4 |
--------------------------------------------------------------------------------
/src/theme/cssVariables/shadow.ts:
--------------------------------------------------------------------------------
1 | export const shadows = {
2 | bigCard: '0px 8px 48px 0px rgba(79, 83, 243, 0.10)',
3 | appMask: '0px 8px 0px 100vmax rgba(0, 0, 0, 0.4)'
4 | }
5 |
--------------------------------------------------------------------------------
/src/theme/cssVariables/size.ts:
--------------------------------------------------------------------------------
1 | /**@deprecated should use chakra build-in text system, don't use is anymore!!! */
2 | export const miscSize = {
3 | // text
4 | textHeroTitle: '40px',
5 | text2XL: '28px',
6 | textLG: '20px',
7 | textSimi: '18px',
8 | textMD: '16px',
9 | textSM: '14px',
10 | textXS: '12px'
11 | }
12 |
13 | /**
14 | * note: size info may change in run-time by setting page, so use runtime css variable
15 | * @deprecated should use chakra build-in text system, don't use is anymore!!!
16 | */
17 | export const sizes = {
18 | // text
19 | textHeroTitle: 'var(--text-hero-title)',
20 | /** 28px */
21 | text2XL: 'var(--text-2xl)',
22 | /** 20px */
23 | textLG: 'var(--text-lg)',
24 | /** 18px */
25 | textSimi: 'var(--text-simi)',
26 | /** 16px */
27 | textMD: 'var(--text-md)',
28 | /** 14px */
29 | textSM: 'var(--text-sm)',
30 | /** 12px */
31 | textXS: 'var(--text-xs)'
32 | }
33 |
--------------------------------------------------------------------------------
/src/theme/detailConfig.ts:
--------------------------------------------------------------------------------
1 | // some global config, (note: these are just js variable not state or css variable)
2 | // const contentWidth = 'clamp(1600px, 80vw, 2000px)'
3 | const contentWidth = '1600px'
4 | export const appLayoutPaddingX = ['20px', `max((100vw - ${contentWidth}) / 2, 7%)`]
5 | export const revertAppLayoutPaddingX = ['-20px', `min((100vw - ${contentWidth}) / -2, -7%)`]
6 |
7 | const baseWindowWidth = 1440
8 | const getGridSlot = (body: number | 'auto', frNumber: number) => {
9 | if (body === 'auto') return `minmax(0, ${frNumber}fr)`
10 | return `minmax(clamp(${body * 0.8}px, ${((body / baseWindowWidth) * 100).toFixed(2)}vw, ${body * 1.2}px), ${frNumber}fr)`
11 | }
12 |
13 | /**
14 | * CSS value
15 | */
16 | export function genCSS3GridTemplateColumns(options: { /** px */ rightLeft?: number | 'auto'; /** px */ center: number }) {
17 | return `${getGridSlot(options.rightLeft ?? 'auto', 1)} ${getGridSlot(options.center, 1.5)} ${getGridSlot(options.rightLeft ?? 'auto', 1)}`
18 | }
19 |
20 | /**
21 | * CSS value
22 | */
23 | export function genCSS2GridTemplateColumns(options: { /** px */ rightLeft?: number | 'auto'; /** px */ center: number }) {
24 | return `${getGridSlot(options.rightLeft ?? 'auto', 1)} ${getGridSlot(options.center, 1.5)}`
25 | }
26 |
--------------------------------------------------------------------------------
/src/theme/foundations/breakpoints.ts:
--------------------------------------------------------------------------------
1 | // mobile <48em -- laptop 48~90em -- big-desktop >90em
2 | export const breakpoints = {
3 | sm: '48em',
4 | md: '90em',
5 | lg: '90em',
6 | xl: '90em',
7 | '2xl': '90em'
8 | }
9 |
--------------------------------------------------------------------------------
/src/theme/foundations/fontSize.ts:
--------------------------------------------------------------------------------
1 | export const fontSizes = {
2 | '3xs': '8px',
3 | '2xs': '10px',
4 | xs: '12px',
5 | sm: '14px',
6 | md: '16px',
7 | lg: '18px',
8 | xl: '20px',
9 | '2xl': '24px',
10 | '3xl': '28px',
11 | 'hero-title': '40px'
12 | }
13 |
--------------------------------------------------------------------------------
/src/theme/foundations/radii.ts:
--------------------------------------------------------------------------------
1 | export const radii = {
2 | none: '0',
3 | sm: '0.125rem',
4 | base: '0.25rem',
5 | md: '8px',
6 | lg: '0.5rem',
7 | xl: '0.75rem',
8 | '2xl': '1rem',
9 | '3xl': '1.5rem',
10 | full: '9999px'
11 | }
12 |
--------------------------------------------------------------------------------
/src/theme/styles.ts:
--------------------------------------------------------------------------------
1 | export const styles = {
2 | // global: {
3 | // 'html,body,#__next,#app-layout': {
4 | // height: '100%'
5 | // },
6 | // body: {
7 | // fontFamily: `'Space Grotesk', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB',
8 | // 'Microsoft YaHei', 'Helvetica Neue', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji',
9 | // 'Segoe UI Symbol'`,
10 | // fontFeatureSettings: "'ss04', 'tnum' 1",
11 | // background: commonTheme.gradient.appGlobalBg,
12 | // backgroundAttachment: 'fixed',
13 | // color: commonTheme.colors.textTertiary
14 | // },
15 | // '::-webkit-scrollbar': {
16 | // backgroundColor: 'transparent',
17 | // width: '7px',
18 | // height: '7px'
19 | // },
20 | // '::-webkit-scrollbar-thumb': {
21 | // backgroundColor: commonTheme.colors.scrollbarThumb,
22 | // borderRadius: '8px'
23 | // },
24 | // '@font-face': {
25 | // fontFamily: 'Space Grotesk',
26 | // src: "url('/SpaceGrotesk[wght].woff2') format('woff2')",
27 | // fontWeight: '300'
28 | // }
29 | // }
30 | }
31 |
--------------------------------------------------------------------------------
/src/type.ts:
--------------------------------------------------------------------------------
1 | import { RaydiumApiBatchRequestParams } from '@raydium-io/raydium-sdk-v2'
2 |
3 | export type SSRData = Omit
4 | export type ValueOf = T[keyof T]
5 |
6 | interface SolanaFeeInfo {
7 | min: number
8 | max: number
9 | avg: number
10 | priorityTx: number
11 | nonVotes: number
12 | priorityRatio: number
13 | avgCuPerBlock: number
14 | blockspaceUsageRatio: number
15 | }
16 |
17 | export type SolanaFeeInfoJson = {
18 | '1': SolanaFeeInfo
19 | '5': SolanaFeeInfo
20 | '15': SolanaFeeInfo
21 | }
22 |
--------------------------------------------------------------------------------
/src/types/tools.ts:
--------------------------------------------------------------------------------
1 | export type ArrayElement = ArrayType extends readonly (infer ElementType)[] ? ElementType : never
2 |
3 | export type Unpacked = T extends (infer U)[] ? U : T
4 |
5 | export type Primitive = boolean | number | string | bigint
6 |
7 | export type AnyFn = (...args: any[]) => any
8 | export type AnyObj = { [key: string]: any }
9 | export type AnyArr = any[]
10 |
11 | export type MayFunction = T | ((...params: Params) => T)
12 | export type MayPromise = T | Promise
13 | export type MayArray = T | T[]
14 | export type DeMayArray> = T extends any[] ? T[number] : T
15 |
16 | export type NotFunctionValue = Exclude
17 |
18 | export type ExtendProps = Omit & Main
19 |
--------------------------------------------------------------------------------
/src/types/tx.ts:
--------------------------------------------------------------------------------
1 | export interface TxCallbackProps {
2 | onSent?: (props?: O) => void
3 | onError?: () => void
4 | onFinally?: (props?: O) => void
5 | onConfirmed?: () => void
6 | }
7 |
8 | export type ToastStatus = 'success' | 'error' | 'info' | 'warning'
9 |
--------------------------------------------------------------------------------
/src/utils/arrayMethods.ts:
--------------------------------------------------------------------------------
1 | export function shakeUndifindedItem(arr: T[]): NonNullable[] {
2 | return arr.filter((item) => item != null) as NonNullable[]
3 | }
4 | export function shakeFalsyItem(arr: readonly T[]): NonNullable[] {
5 | return arr.filter(Boolean) as NonNullable[]
6 | }
7 |
--------------------------------------------------------------------------------
/src/utils/config/birdeyeAPI.ts:
--------------------------------------------------------------------------------
1 | // birdeye api key
2 | export const birdeyHost = 'https://birdeye-proxy.raydium.io'
3 |
4 | export const birdeyeKlineApiAddress = ({
5 | baseMint,
6 | quoteMint,
7 | timeType,
8 | timeFrom,
9 | timeTo
10 | }: {
11 | baseMint: string
12 | quoteMint: string
13 | timeType: string
14 | timeFrom: number
15 | timeTo: number
16 | }) =>
17 | `${birdeyHost}/defi/ohlcv/base_quote?base_address=${baseMint}"e_address=${quoteMint}&type=${timeType}&time_from=${timeFrom}&time_to=${timeTo}`
18 |
19 | export const birdeyePairVolumeApiAddress = ({
20 | poolAddress,
21 | timeType,
22 | timeFrom,
23 | timeTo
24 | }: {
25 | poolAddress: string
26 | timeType: string
27 | timeFrom: number
28 | timeTo: number
29 | }) => `${birdeyHost}/defi/ohlcv/pair?address=${poolAddress}&type=${timeType}&time_from=${timeFrom}&time_to=${timeTo}`
30 |
31 | export const birdeyePairPriceApiAddress = ({
32 | baseMint,
33 | timeType,
34 | timeFrom,
35 | timeTo
36 | }: {
37 | baseMint: string
38 | timeType: string
39 | timeFrom: number
40 | timeTo: number
41 | }) => `${birdeyHost}/defi/history_price?address=${baseMint}&type=${timeType}&address_type=token&time_from=${timeFrom}&time_to=${timeTo}`
42 |
43 | export const birdeyePriceUrl = `${birdeyHost}/defi/multi_price`
44 |
--------------------------------------------------------------------------------
/src/utils/dom/onBreackpointChange.ts:
--------------------------------------------------------------------------------
1 | const breakPointsMobilePC = '48em'
2 | export function onBreackpointChange(cb: () => void): { cancel(): void } {
3 | const mediaQueryLists = [`(min-width: ${breakPointsMobilePC})`].map((m) => window.matchMedia(m))
4 | mediaQueryLists.forEach((mql) => mql.addEventListener('change', cb))
5 | return {
6 | cancel() {
7 | mediaQueryLists.forEach((mql) => mql.removeEventListener('change', cb))
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/utils/dom/onNodeChildrenChange.ts:
--------------------------------------------------------------------------------
1 | export function onNodeChildrenChange(observeNode: HTMLElement, cb: () => void): { cancel(): void } {
2 | const observer = new MutationObserver(cb)
3 | observer.observe(observeNode, { childList: true, subtree: true })
4 | return {
5 | cancel() {
6 | observer.disconnect()
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/utils/dom/onWindowSizeChange.ts:
--------------------------------------------------------------------------------
1 | export function onWindowSizeChange(cb: () => void): { cancel: () => void } {
2 | const rAFcallback = () => {
3 | requestAnimationFrame(cb)
4 | }
5 | window.addEventListener('resize', rAFcallback)
6 | return {
7 | cancel() {
8 | window.removeEventListener('resize', rAFcallback)
9 | }
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/utils/judges/judgeType.ts:
--------------------------------------------------------------------------------
1 | export const isString = (v: unknown): v is string => typeof v === 'string'
2 |
3 | export const isArray = Array.isArray
4 |
5 | export function isFunction(value: unknown): value is (...args: any[]) => any {
6 | return typeof value === 'function'
7 | }
8 |
9 | export function isObject(val: unknown): val is Record | Array {
10 | return !(val === null) && typeof val === 'object'
11 | }
12 |
13 | export function isEmptyObject(obj: any): boolean {
14 | return (isArray(obj) && obj.length === 0) || (isObject(obj) && Object.keys(obj).length === 0)
15 | }
16 |
17 | export function isUndefined(val: unknown): val is undefined {
18 | return val === undefined
19 | }
20 |
21 | /**
22 | * @example
23 | * notNullish('') // true
24 | * notNullish(undefined) // false
25 | * notNullish([]) // true
26 | */
27 | export function notNullish(value: T): value is NonNullable {
28 | return value !== undefined && value !== null
29 | }
30 | export function isNullish(value: any): value is undefined | null {
31 | return !notNullish(value)
32 | }
33 |
34 | export const isExist = notNullish
35 |
36 | export const notExist = isNullish
37 |
--------------------------------------------------------------------------------
/src/utils/listToMap.ts:
--------------------------------------------------------------------------------
1 | export function listToMap(
2 | source: T[],
3 | getKey: (item: T, index: number) => S,
4 | getValue?: (item: T, index: number) => V
5 | ): Record {
6 | // @ts-expect-error force
7 | return Object.fromEntries(source.map((item, idx) => [getKey(item, idx), getValue ? getValue(item, idx) : item]))
8 | }
9 |
--------------------------------------------------------------------------------
/src/utils/localStorage.ts:
--------------------------------------------------------------------------------
1 | import { isClient, isLocal } from './common'
2 |
3 | export const getStorageItem = (key: string): string | null => {
4 | if (!isClient()) return null
5 | return localStorage.getItem(key)
6 | }
7 |
8 | export const setStorageItem = (key: string, value: string | number): void => {
9 | if (!isClient()) return
10 | return localStorage.setItem(key, String(value))
11 | }
12 |
13 | export const deleteStorageItem = (key: string): void => {
14 | if (!isClient()) return
15 | return localStorage.removeItem(key)
16 | }
17 |
18 | export const getDevOnlyStorage = (key: string): string | null => {
19 | if (!isClient() || !isLocal()) return null
20 | return localStorage.getItem(key)
21 | }
22 |
--------------------------------------------------------------------------------
/src/utils/log.ts:
--------------------------------------------------------------------------------
1 | import dayjs from 'dayjs'
2 | import utc from 'dayjs/plugin/utc'
3 |
4 | dayjs.extend(utc)
5 |
6 | export default function logMessage(...params: any) {
7 | console.log(`${dayjs().utc().valueOf()} -`, ...params)
8 | }
9 |
--------------------------------------------------------------------------------
/src/utils/numberish/regex.ts:
--------------------------------------------------------------------------------
1 | export const numberRegExp = new RegExp(/^[0-9.,]$/)
2 | export const numberOnlyRex = new RegExp(/[0-9.]/gi)
3 | export const extractNumberOnly = (val?: string | number, propsFallback?: string | number) => {
4 | const fallback = propsFallback ? String(propsFallback) : ''
5 | return val ? String(val).match(numberOnlyRex)?.join('') || fallback : fallback
6 | }
7 |
--------------------------------------------------------------------------------
/src/utils/numberish/toApr.ts:
--------------------------------------------------------------------------------
1 | import Decimal from 'decimal.js'
2 | import { getFirstNonZeroDecimal, formatLocaleStr } from './formatter'
3 |
4 | export default function toApr({ val, multiply = true, decimal }: { val: string | number; multiply?: boolean; decimal?: number }) {
5 | const calVal = multiply ? new Decimal(val).mul(100).toString() : String(val ?? 0)
6 | return formatLocaleStr(calVal, decimal === undefined ? Math.max(2, getFirstNonZeroDecimal(calVal) + 1) : decimal) + '%'
7 | }
8 |
--------------------------------------------------------------------------------
/src/utils/parallelSwitch.ts:
--------------------------------------------------------------------------------
1 | import { NotFunctionValue, Primitive } from '@/types/tools'
2 | import { shrinkToValue } from './shrinkToValue'
3 |
4 | // TODO: It's type generic is not correct
5 | /**
6 | * this Function can generally replace javascript:switch
7 | *
8 | * @param value detected value
9 | * @param conditionPairs conditions (one of them or none of them can match). this's returned Value must have same type.
10 | * @param fallbackValue
11 | * @example
12 | * parallelSwitch('hello', [
13 | * [(k) => k.charAt(0) === 'h', 3],
14 | * ['world', 4]
15 | * ]) //=> 3
16 | *
17 | * parallelSwitch('hello', [
18 | * ['world', 1],
19 | * ['hello', 4]
20 | * ]) //=> 4
21 | */
22 | export default function parallelSwitch<
23 | SwitchKey,
24 | ResultValue extends Primitive // this type is not correct
25 | >(
26 | value: SwitchKey,
27 | conditionPairs: Array<
28 | [is: NotFunctionValue | ((value: SwitchKey) => boolean), returnValue: ResultValue | ((value: SwitchKey) => ResultValue)]
29 | >,
30 | fallbackValue?: ResultValue
31 | ): ResultValue {
32 | for (const [is, returnValue] of conditionPairs) {
33 | if (value === is || shrinkToValue(is, [value]) === true) return shrinkToValue(returnValue, [value])
34 | }
35 | return fallbackValue!
36 | }
37 |
--------------------------------------------------------------------------------
/src/utils/pool/nameFormat.ts:
--------------------------------------------------------------------------------
1 | import { ApiV3Token } from '@raydium-io/raydium-sdk-v2'
2 | import { wSolToSolString } from '@/utils/token'
3 |
4 | export const transformSymbol = (symbols: ApiV3Token[]) => {
5 | if (symbols.length < 2) return wSolToSolString(symbols[0].symbol) || symbols[0]?.address.substring(0, 6)
6 | return `${wSolToSolString(symbols[0].symbol) || symbols[0]?.address.substring(0, 6)} - ${
7 | wSolToSolString(symbols[1]?.symbol) || symbols[1]?.address.substring(0, 6)
8 | }`
9 | }
10 |
--------------------------------------------------------------------------------
/src/utils/publicKey.ts:
--------------------------------------------------------------------------------
1 | import { PublicKey } from '@solana/web3.js'
2 |
3 | const CACHE_KEYS = new Map()
4 |
5 | export const isValidPublicKey = (val: string | PublicKey): boolean => {
6 | if (!val) return false
7 | const valStr = val.toString()
8 | if (CACHE_KEYS.has(valStr)) return true
9 | try {
10 | new PublicKey(valStr)
11 | return true
12 | } catch {
13 | return false
14 | }
15 | }
16 |
17 | export default function ToPublicKey(key: string | PublicKey): PublicKey {
18 | const keyStr = key?.toString() || ''
19 | if (CACHE_KEYS.has(keyStr)) return CACHE_KEYS.get(keyStr)!
20 | const pubKey = new PublicKey(keyStr)
21 | CACHE_KEYS.set(keyStr, pubKey)
22 | return pubKey
23 | }
24 |
--------------------------------------------------------------------------------
/src/utils/react/addPropsToReactElement.ts:
--------------------------------------------------------------------------------
1 | import { MayFunction } from '@/types/tools'
2 | import { cloneElement, isValidElement as isValidReactElement } from 'react'
3 |
4 | import { shrinkToValue } from '../shrinkToValue'
5 | import mergeProps from './mergeProps'
6 |
7 | export default function addPropsToReactElement(
8 | element: any,
9 | props?: MayFunction & { key?: number | string }, [oldprops: Partial]>
10 | ): JSX.Element {
11 | if (!isValidReactElement(element)) return element
12 | // @ts-expect-error force type
13 | return element ? cloneElement(element, mergeProps(element.props, shrinkToValue(props, [element.props]))) : null
14 | }
15 |
16 | export function addPropsToReactElements(
17 | elements: any,
18 | props?: Partial
19 | ): JSX.Element {
20 | //@ts-expect-error force
21 | return [elements]
22 | .flat()
23 | .map((element, idx) =>
24 | isValidReactElement(element)
25 | ? element
26 | ? cloneElement(element, mergeProps(element.props, props, { key: (elements as any)?.key ?? idx }))
27 | : null
28 | : element
29 | )
30 | }
31 |
--------------------------------------------------------------------------------
/src/utils/react/getElementsFromRef.ts:
--------------------------------------------------------------------------------
1 | import { RefObject } from 'react'
2 | import { isObject } from '../judges/judgeType'
3 | import { MayArray } from '@/types/tools'
4 | import { shakeFalsyItem } from '../arrayMethods'
5 |
6 | type Element = HTMLElement | undefined | null
7 |
8 | type MayRef = T | RefObject
9 |
10 | export type ElementSingle = MayRef
11 | export type ElementRefs = MayRef>>
12 | export function getElementsFromRef(refs: ElementRefs): HTMLElement[] {
13 | const getRef = (ref: T | RefObject): T => (isObject(ref) && 'current' in ref ? ref.current : ref) as T
14 | return shakeFalsyItem(flap(getRef(refs)).map((ref) => getRef(ref)))
15 | }
16 |
17 | export function flap(arr: T): T extends Array ? U[] : T[] {
18 | // @ts-expect-error force type
19 | return Array.isArray(arr) ? arr : [arr]
20 | }
21 |
22 | export function getSingleElement(ref: ElementSingle): HTMLElement | undefined {
23 | const el = isObject(ref) && 'current' in ref ? ref.current : ref
24 | return el ?? undefined
25 | }
26 |
--------------------------------------------------------------------------------
/src/utils/react/mergeRef.ts:
--------------------------------------------------------------------------------
1 | import { MutableRefObject, RefCallback, RefObject } from 'react'
2 |
3 | import { createCallbackRef } from '@/hooks/useCallbackRef'
4 | import { isArray, isFunction, isNullish } from '../judges/judgeType'
5 |
6 | function loadRef(ref: RefCallback | MutableRefObject | null | undefined, el: any) {
7 | if (isNullish(ref)) return
8 |
9 | if (isFunction(ref)) {
10 | ref(el)
11 | } else if (isArray(ref.current)) {
12 | // 👇 have to do that to pretend the address of variable
13 | ref.current.forEach((_, idx) => {
14 | ref.current.splice(idx, 1, el)
15 | })
16 | } else {
17 | ref.current = el
18 | }
19 | }
20 |
21 | export default function mergeRef(...refs: (MutableRefObject | null | undefined)[]): RefObject {
22 | return createCallbackRef((el) => refs.forEach((ref) => loadRef(ref, el)))
23 | }
24 |
--------------------------------------------------------------------------------
/src/utils/shakeUndefindedItem.ts:
--------------------------------------------------------------------------------
1 | export function shakeUndefindedItem(arr: T[]): NonNullable[] {
2 | return arr.filter((item) => item != null) as NonNullable[]
3 | }
4 |
--------------------------------------------------------------------------------
/src/utils/shrinkToValue.ts:
--------------------------------------------------------------------------------
1 | type AnyFn = (...args: any[]) => any
2 | export type MayFn = T | ((...params: Params) => T)
3 | /**
4 | * get value from input, if input is a function. it will ve invoked
5 | *
6 | * @param mayValue maybe a function that will return targetValue
7 | * @param params the parameters that will be passed in mayValue(if it's function)
8 | * @returns a pure value which can't be a function
9 | */
10 | export function shrinkToValue(mayValue: T, params?: T extends AnyFn ? Parameters : any[]): Exclude {
11 | return typeof mayValue === 'function' ? mayValue(...(params ?? [])) : mayValue
12 | }
13 |
--------------------------------------------------------------------------------
/src/utils/startLazyIntervalTask.ts:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | * Stop when document hidden
4 | */
5 | export function startLazyIntervalTask(cb: () => void, duration: number /* ms */): { stop(): void } {
6 | const { isVisiable, stop } = checkDocumentVisibility()
7 | const timeid = setInterval(() => {
8 | if (isVisiable()) cb()
9 | }, duration)
10 | const stopInterval = () => {
11 | stop()
12 | clearInterval(timeid)
13 | }
14 | return { stop: stopInterval }
15 | }
16 |
17 | export function checkDocumentVisibility() {
18 | let isDocumentContentVisiable = true
19 | function isVisiable() {
20 | return isDocumentContentVisiable
21 | }
22 | const handleVisibilityChange = () => {
23 | const visibilityState = document.visibilityState
24 | isDocumentContentVisiable = visibilityState === 'visible'
25 | }
26 | document.addEventListener('visibilitychange', handleVisibilityChange, { passive: true })
27 | const stop = () => document.removeEventListener('visibilitychange', handleVisibilityChange)
28 | return { isVisiable, stop }
29 | }
30 |
--------------------------------------------------------------------------------
/src/utils/time.ts:
--------------------------------------------------------------------------------
1 | /** timeA is before timeB */
2 | export const isBefore = (timeA: number, timeB: number) => timeA < timeB
3 |
4 | /** timeA is after timeB */
5 | export const isAfter = (timeA: number, timeB: number) => timeA > timeB
6 |
7 | export const DATE_FORMAT_REGEX = 'YYYY-MM-DD HH:mm'
8 | export const DATE_FORMAT_REGEX_UTC = 'YYYY-MM-DD HH:mm UTC'
9 | export const HOUR_SECONDS = 3600
10 | export const DAY_SECONDS = HOUR_SECONDS * 24
11 | // duration should be seconds
12 | export const getDurationUnits = (duration: number) => {
13 | const days = Math.floor(duration / DAY_SECONDS)
14 | const hours = Math.floor((duration % DAY_SECONDS) / HOUR_SECONDS)
15 | const minutes = Math.floor((duration % HOUR_SECONDS) / 60)
16 | const seconds = Math.floor(duration % 60)
17 | return {
18 | days,
19 | hours,
20 | minutes,
21 | seconds,
22 | text: [[`${days}D`, ...(hours ? [`${hours}H`] : [])].join(' ')]
23 | }
24 | }
25 |
26 | export const timeBasis = {
27 | day: '24h',
28 | week: '7d',
29 | month: '30d'
30 | }
31 |
32 | export const timeBasisOptions = Object.values(timeBasis)
33 |
34 | export const getTimeBasis = (idx: number) => {
35 | return timeBasisOptions[idx]
36 | }
37 |
--------------------------------------------------------------------------------
/src/utils/tx/getEphemeralSigners.ts:
--------------------------------------------------------------------------------
1 | import { Wallet } from '@solana/wallet-adapter-react'
2 |
3 | export default async function getEphemeralSigners(wallet: Wallet) {
4 | const { adapter } = wallet
5 | return (
6 | adapter &&
7 | 'standard' in adapter &&
8 | 'fuse:getEphemeralSigners' in adapter.wallet.features &&
9 | // eslint-disable-next-line @typescript-eslint/ban-ts-comment
10 | // @ts-ignore
11 | adapter.wallet.features['fuse:getEphemeralSigners'].getEphemeralSigners
12 | )
13 | }
14 |
--------------------------------------------------------------------------------
/src/utils/tx/swapError.ts:
--------------------------------------------------------------------------------
1 | import { SignatureResult } from '@solana/web3.js'
2 |
3 | export function isSwapSlippageError(result: SignatureResult): boolean {
4 | try {
5 | // @ts-expect-error force
6 | if ([38, 6022].includes(result.err?.InstructionError[1].Custom)) {
7 | return true
8 | } else {
9 | return false
10 | }
11 | } catch {
12 | return false
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/utils/url.ts:
--------------------------------------------------------------------------------
1 | export const isValidUrl = (url: string) => {
2 | try {
3 | new URL(url)
4 | return true
5 | } catch {
6 | return false
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
3 | "compilerOptions": {
4 | "target": "es6",
5 | "lib": ["dom", "dom.iterable", "esnext"],
6 | "allowJs": true,
7 | "skipLibCheck": true,
8 | "strict": true,
9 | "forceConsistentCasingInFileNames": true,
10 | "noEmit": true,
11 | "esModuleInterop": true,
12 | "module": "esnext",
13 | "moduleResolution": "node",
14 | "resolveJsonModule": true,
15 | "isolatedModules": true,
16 | "jsx": "preserve",
17 | "incremental": true,
18 | "baseUrl": ".",
19 | "paths": {
20 | "@/*": ["./src/*"]
21 | }
22 | },
23 | "exclude": ["node_modules"]
24 | }
25 |
--------------------------------------------------------------------------------