replace any type with more defined types
This commit is contained in:
parent
dc33e98a8a
commit
abb408678e
|
@ -1,3 +1,4 @@
|
|||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import { makeApiRequest, parseResolution } from './helpers'
|
||||
import {
|
||||
closeSocket,
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
export const NEXT_PUBLIC_BIRDEYE_API_KEY =
|
||||
process.env.NEXT_PUBLIC_BIRDEYE_API_KEY ||
|
||||
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE2NzM0NTE4MDF9.KTEqB1hrmZTMzk19rZNx9aesh2bIHj98Cb8sg5Ikz-Y'
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import { parseResolution, getNextBarTime, socketUrl } from './helpers'
|
||||
|
||||
let subscriptionItem: any = {}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import { makeApiRequest, parseResolution } from './helpers'
|
||||
import {
|
||||
subscribeOnStream,
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import { MANGO_DATA_API_URL } from 'utils/constants'
|
||||
|
||||
// Make requests to mngo.cloud API
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import { getNextBarTime } from './helpers'
|
||||
|
||||
let subscriptionItem: any = {}
|
||||
|
|
|
@ -430,14 +430,12 @@ const ActionsMenu = ({
|
|||
|
||||
const handleSwap = useCallback(() => {
|
||||
const tokenInfo = mangoTokens.find(
|
||||
(t: any) => t.address === bank.mint.toString()
|
||||
(t) => t.address === bank.mint.toString()
|
||||
)
|
||||
const group = mangoStore.getState().group
|
||||
if (balance && balance > 0) {
|
||||
if (tokenInfo?.symbol === 'SOL') {
|
||||
const usdcTokenInfo = mangoTokens.find(
|
||||
(t: any) => t.address === USDC_MINT
|
||||
)
|
||||
const usdcTokenInfo = mangoTokens.find((t) => t.address === USDC_MINT)
|
||||
const usdcBank = group?.getFirstBankByMint(new PublicKey(USDC_MINT))
|
||||
set((s) => {
|
||||
s.swap.inputBank = usdcBank
|
||||
|
@ -451,7 +449,7 @@ const ActionsMenu = ({
|
|||
} else {
|
||||
if (tokenInfo?.symbol === 'USDC') {
|
||||
const solTokenInfo = mangoTokens.find(
|
||||
(t: any) => t.address === WRAPPED_SOL_MINT.toString()
|
||||
(t) => t.address === WRAPPED_SOL_MINT.toString()
|
||||
)
|
||||
const solBank = group?.getFirstBankByMint(WRAPPED_SOL_MINT)
|
||||
set((s) => {
|
||||
|
|
|
@ -22,7 +22,7 @@ const AccountChart = ({
|
|||
const { t } = useTranslation('common')
|
||||
const [daysToShow, setDaysToShow] = useState<string>('1')
|
||||
|
||||
const chartData: any = useMemo(() => {
|
||||
const chartData = useMemo(() => {
|
||||
if (!data.length) return []
|
||||
if (chartToShow === 'cumulative-interest-value') {
|
||||
data.map((d) => ({
|
||||
|
@ -32,7 +32,7 @@ const AccountChart = ({
|
|||
}))
|
||||
}
|
||||
return data
|
||||
}, [data])
|
||||
}, [data, chartToShow])
|
||||
|
||||
return (
|
||||
<DetailedAreaChart
|
||||
|
|
|
@ -55,7 +55,6 @@ const AccountPage = () => {
|
|||
(s) => s.mangoAccount.performance.loading
|
||||
)
|
||||
const performanceData = mangoStore((s) => s.mangoAccount.performance.data)
|
||||
console.log(performanceData)
|
||||
|
||||
const totalInterestData = mangoStore(
|
||||
(s) => s.mangoAccount.interestTotals.data
|
||||
|
@ -76,13 +75,11 @@ const AccountPage = () => {
|
|||
)
|
||||
|
||||
useEffect(() => {
|
||||
console.log('mangoAccountAddress', mangoAccountAddress)
|
||||
|
||||
if (mangoAccountAddress || (!mangoAccountAddress && connected)) {
|
||||
actions.fetchAccountPerformance(mangoAccountAddress, 31)
|
||||
actions.fetchAccountInterestTotals(mangoAccountAddress)
|
||||
}
|
||||
}, [actions, mangoAccountAddress])
|
||||
}, [actions, mangoAccountAddress, connected])
|
||||
|
||||
const oneDayPerformanceData: PerformanceDataItem[] | [] = useMemo(() => {
|
||||
if (!performanceData || !performanceData.length) return []
|
||||
|
|
|
@ -37,7 +37,7 @@ const ActionTokenList = ({
|
|||
{banks?.length ? (
|
||||
banks
|
||||
.filter((b: BankParams) => !!b)
|
||||
.map((b: any) => {
|
||||
.map((b) => {
|
||||
return (
|
||||
<ActionTokenItem
|
||||
bank={b.bank}
|
||||
|
|
|
@ -14,9 +14,10 @@ import { LiquidationActivity } from 'types'
|
|||
|
||||
const ActivityFeed = () => {
|
||||
const activityFeed = mangoStore((s) => s.activityFeed.feed)
|
||||
const [showActivityDetail, setShowActivityDetail] = useState(null)
|
||||
const [showActivityDetail, setShowActivityDetail] =
|
||||
useState<LiquidationActivity>()
|
||||
|
||||
const handleShowActivityDetails = (activity: any) => {
|
||||
const handleShowActivityDetails = (activity: LiquidationActivity) => {
|
||||
setShowActivityDetail(activity)
|
||||
}
|
||||
|
||||
|
@ -40,7 +41,7 @@ const ActivityDetails = ({
|
|||
setShowActivityDetail,
|
||||
}: {
|
||||
activity: LiquidationActivity
|
||||
setShowActivityDetail: (x: any) => void
|
||||
setShowActivityDetail: (x: LiquidationActivity | undefined) => void
|
||||
}) => {
|
||||
const { t } = useTranslation(['common', 'activity', 'settings'])
|
||||
const [preferredExplorer] = useLocalStorageState(
|
||||
|
@ -62,7 +63,7 @@ const ActivityDetails = ({
|
|||
<div className="flex items-center p-6">
|
||||
<IconButton
|
||||
className="mr-4"
|
||||
onClick={() => setShowActivityDetail(null)}
|
||||
onClick={() => setShowActivityDetail(undefined)}
|
||||
>
|
||||
<ArrowLeftIcon className="h-5 w-5" />
|
||||
</IconButton>
|
||||
|
|
|
@ -17,6 +17,7 @@ import useMangoAccount from 'hooks/useMangoAccount'
|
|||
import useMangoGroup from 'hooks/useMangoGroup'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import { ChangeEvent, useCallback, useEffect, useMemo, useState } from 'react'
|
||||
import { DateChangeCallBack } from 'react-nice-dates'
|
||||
|
||||
interface AdvancedFilters {
|
||||
symbol: string[]
|
||||
|
@ -198,8 +199,8 @@ const FiltersForm = ({
|
|||
}: FiltersFormProps) => {
|
||||
const { t } = useTranslation(['common', 'activity'])
|
||||
const { group } = useMangoGroup()
|
||||
const [dateFrom, setDateFrom] = useState<Date | null>(null)
|
||||
const [dateTo, setDateTo] = useState<Date | null>(null)
|
||||
const [dateFrom, setDateFrom] = useState<Date>()
|
||||
const [dateTo, setDateTo] = useState<Date>()
|
||||
const [valueFrom, setValueFrom] = useState(advancedFilters['usd-lower'] || '')
|
||||
const [valueTo, setValueTo] = useState(advancedFilters['usd-upper'] || '')
|
||||
|
||||
|
@ -298,9 +299,9 @@ const FiltersForm = ({
|
|||
<div className="my-4 w-full">
|
||||
<MangoDateRangePicker
|
||||
startDate={dateFrom}
|
||||
setStartDate={setDateFrom}
|
||||
setStartDate={setDateFrom as DateChangeCallBack}
|
||||
endDate={dateTo}
|
||||
setEndDate={setDateTo}
|
||||
setEndDate={setDateTo as DateChangeCallBack}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex items-end pb-6">
|
||||
|
|
|
@ -9,12 +9,12 @@ const ChatForm = ({
|
|||
setLatestMessages,
|
||||
}: {
|
||||
messages: MessageProps[]
|
||||
setLatestMessages: (x: any) => void
|
||||
setLatestMessages: (x: MessageProps[]) => void
|
||||
}) => {
|
||||
const [messageText, setMessageText] = useState('')
|
||||
const { publicKey } = useWallet()
|
||||
|
||||
const validateMessageText = async (text: string) => {
|
||||
const validateMessageText = useCallback(async (text: string) => {
|
||||
try {
|
||||
const response = await fetch(
|
||||
`https://www.purgomalum.com/service/json?text=${text}&fill_char=*`
|
||||
|
@ -25,24 +25,28 @@ const ChatForm = ({
|
|||
return profanityCheck.result
|
||||
}
|
||||
} catch {
|
||||
return
|
||||
console.error('Error validating message text')
|
||||
}
|
||||
}
|
||||
}, [])
|
||||
|
||||
const onSubmitMessage = async (e: FormEvent) => {
|
||||
e.preventDefault()
|
||||
const filteredMessageText = await validateMessageText(messageText)
|
||||
const onSubmitMessage = useCallback(
|
||||
async (e: FormEvent) => {
|
||||
e.preventDefault()
|
||||
if (!publicKey) return
|
||||
const filteredMessageText: string = await validateMessageText(messageText)
|
||||
|
||||
const message = {
|
||||
text: filteredMessageText ? filteredMessageText : messageText,
|
||||
timestamp: new Date().getTime(),
|
||||
user: 'Profile Name',
|
||||
walletPk: publicKey?.toString(),
|
||||
}
|
||||
const newMessages = [...messages, message]
|
||||
setLatestMessages(newMessages)
|
||||
setMessageText('')
|
||||
}
|
||||
const message: MessageProps = {
|
||||
text: filteredMessageText ? filteredMessageText : messageText,
|
||||
timestamp: new Date().getTime(),
|
||||
user: 'Profile Name',
|
||||
walletPk: publicKey.toString(),
|
||||
}
|
||||
const newMessages = [...messages, message]
|
||||
setLatestMessages(newMessages)
|
||||
setMessageText('')
|
||||
},
|
||||
[messageText, messages, publicKey, validateMessageText, setLatestMessages]
|
||||
)
|
||||
|
||||
const callbackRef = useCallback((inputElement: HTMLInputElement) => {
|
||||
if (inputElement) {
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
import { FunctionComponent } from 'react'
|
||||
type Values = string | number
|
||||
|
||||
interface ButtonGroupProps {
|
||||
activeValue: string
|
||||
interface ButtonGroupProps<T extends Values> {
|
||||
activeValue: T
|
||||
className?: string
|
||||
disabled?: boolean
|
||||
onChange: (x: any) => void
|
||||
onChange: (x: T) => void
|
||||
unit?: string
|
||||
values: Array<any>
|
||||
values: T[]
|
||||
names?: Array<string>
|
||||
large?: boolean
|
||||
}
|
||||
|
||||
const ButtonGroup: FunctionComponent<ButtonGroupProps> = ({
|
||||
const ButtonGroup = <T extends Values>({
|
||||
activeValue,
|
||||
className,
|
||||
disabled,
|
||||
|
@ -20,7 +20,7 @@ const ButtonGroup: FunctionComponent<ButtonGroupProps> = ({
|
|||
onChange,
|
||||
names,
|
||||
large,
|
||||
}) => {
|
||||
}: ButtonGroupProps<T>) => {
|
||||
return (
|
||||
<div className={`rounded-md bg-th-bkg-2 ${disabled ? 'opacity-50' : ''}`}>
|
||||
<div className="relative flex">
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { ChevronRightIcon } from '@heroicons/react/20/solid'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import { enUS } from 'date-fns/locale'
|
||||
import { DateRangePicker } from 'react-nice-dates'
|
||||
import { DateChangeCallBack, DateRangePicker } from 'react-nice-dates'
|
||||
import Label from './Label'
|
||||
|
||||
const MangoDateRangePicker = ({
|
||||
|
@ -10,10 +10,10 @@ const MangoDateRangePicker = ({
|
|||
endDate,
|
||||
setEndDate,
|
||||
}: {
|
||||
startDate: Date | null
|
||||
setStartDate: any
|
||||
endDate: Date | null
|
||||
setEndDate: any
|
||||
startDate: Date | undefined
|
||||
setStartDate: DateChangeCallBack | undefined
|
||||
endDate: Date | undefined
|
||||
setEndDate: DateChangeCallBack | undefined
|
||||
}) => {
|
||||
const { t } = useTranslation('common')
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ import { ChangeEvent, forwardRef } from 'react'
|
|||
|
||||
interface InputProps {
|
||||
type: string
|
||||
value: any
|
||||
value: string
|
||||
onChange: (e: ChangeEvent<HTMLInputElement>) => void
|
||||
maxLength?: number
|
||||
className?: string
|
||||
|
|
|
@ -13,7 +13,7 @@ import {
|
|||
} from '@blockworks-foundation/mango-v4'
|
||||
import mangoStore from '@store/mangoStore'
|
||||
import { IconButton, LinkButton } from '../shared/Button'
|
||||
import { useLocalStorageStringState } from '../../hooks/useLocalStorageState'
|
||||
import useLocalStorageState from '../../hooks/useLocalStorageState'
|
||||
import { LAST_ACCOUNT_KEY } from '../../utils/constants'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import { retryFn } from '../../utils'
|
||||
|
@ -43,7 +43,7 @@ const MangoAccountsListModal = ({
|
|||
const actions = mangoStore.getState().actions
|
||||
const { group } = useMangoGroup()
|
||||
const [showNewAccountForm, setShowNewAccountForm] = useState(false)
|
||||
const [, setLastAccountViewed] = useLocalStorageStringState(LAST_ACCOUNT_KEY)
|
||||
const [, setLastAccountViewed] = useLocalStorageState(LAST_ACCOUNT_KEY)
|
||||
const router = useRouter()
|
||||
const { asPath } = useRouter()
|
||||
const [submitting, setSubmitting] = useState('')
|
||||
|
|
|
@ -106,7 +106,7 @@ const PnlHistoryModal = ({
|
|||
<>
|
||||
<div className="thin-scroll overflow-auto pr-1">
|
||||
<div className="border-b border-th-bkg-3">
|
||||
{dailyValues.map((v: any) => (
|
||||
{dailyValues.map((v) => (
|
||||
<div
|
||||
className="flex items-center justify-between border-t border-th-bkg-3 p-3"
|
||||
key={v.time + v.pnlChange}
|
||||
|
|
|
@ -8,7 +8,7 @@ import { bs58 } from '@project-serum/anchor/dist/cjs/utils/bytes'
|
|||
import { notify } from 'utils/notifications'
|
||||
import { MANGO_DATA_API_URL } from 'utils/constants'
|
||||
|
||||
const ImgWithLoader = (props: any) => {
|
||||
const ImgWithLoader = (props: { className: string; src: string }) => {
|
||||
const [isLoading, setIsLoading] = useState(true)
|
||||
return (
|
||||
<div className="relative">
|
||||
|
|
|
@ -73,9 +73,11 @@ const RpcSettings = () => {
|
|||
const handlePriorityFee = useCallback(
|
||||
(label: string) => {
|
||||
const fee = PRIORITY_FEES.find((fee) => fee.label === label)
|
||||
setStoredPriorityFee(fee?.value)
|
||||
if (wallet) {
|
||||
actions.connectMangoClientWithWallet(wallet)
|
||||
if (fee) {
|
||||
setStoredPriorityFee(fee?.value)
|
||||
if (wallet) {
|
||||
actions.connectMangoClientWithWallet(wallet)
|
||||
}
|
||||
}
|
||||
},
|
||||
[setStoredPriorityFee, actions, wallet]
|
||||
|
|
|
@ -9,13 +9,13 @@ const FavoriteMarketButton = ({
|
|||
}: {
|
||||
market: PerpMarket | Serum3Market
|
||||
}) => {
|
||||
const [favoriteMarkets, setFavoriteMarkets] = useLocalStorageState(
|
||||
const [favoriteMarkets, setFavoriteMarkets] = useLocalStorageState<string[]>(
|
||||
FAVORITE_MARKETS_KEY,
|
||||
[]
|
||||
)
|
||||
|
||||
const addToFavorites = (marketName: string) => {
|
||||
const newFavorites: any = [...favoriteMarkets, marketName]
|
||||
const newFavorites = [...favoriteMarkets, marketName]
|
||||
setFavoriteMarkets(newFavorites)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { InformationCircleIcon } from '@heroicons/react/20/solid'
|
||||
import Tooltip from './Tooltip'
|
||||
|
||||
const InfoTooltip = ({ content }: { content: any }) => (
|
||||
const InfoTooltip = ({ content }: { content: string }) => (
|
||||
<Tooltip content={content}>
|
||||
<InformationCircleIcon className="ml-1.5 h-5 w-5 cursor-help text-th-fgd-4" />
|
||||
</Tooltip>
|
||||
|
|
|
@ -44,7 +44,7 @@ const TokenItem = ({
|
|||
useMargin,
|
||||
type,
|
||||
}: {
|
||||
token: Token
|
||||
token: TokenInfoWithAmounts
|
||||
onSubmit: (x: string) => void
|
||||
useMargin: boolean
|
||||
type: 'input' | 'output' | undefined
|
||||
|
@ -110,6 +110,11 @@ const TokenItem = ({
|
|||
|
||||
// const popularTokenSymbols = ['USDC', 'SOL', 'USDT', 'MNGO', 'BTC']
|
||||
|
||||
interface TokenInfoWithAmounts extends Token {
|
||||
amount?: Decimal
|
||||
amountWithBorrow?: Decimal
|
||||
}
|
||||
|
||||
const SwapFormTokenList = ({
|
||||
onClose,
|
||||
onTokenSelect,
|
||||
|
@ -147,7 +152,7 @@ const SwapFormTokenList = ({
|
|||
return () => window.removeEventListener('keydown', onEscape)
|
||||
}, [onClose])
|
||||
|
||||
const tokenInfos = useMemo(() => {
|
||||
const tokenInfos: TokenInfoWithAmounts[] = useMemo(() => {
|
||||
if (
|
||||
mangoTokens?.length &&
|
||||
group &&
|
||||
|
|
|
@ -27,10 +27,10 @@ const DEFAULT_COINGECKO_VALUES = {
|
|||
atl_change_percentage: 0,
|
||||
ath_date: 0,
|
||||
atl_date: 0,
|
||||
high_24h: 0,
|
||||
high_24h: { usd: 0 },
|
||||
circulating_supply: 0,
|
||||
fully_diluted_valuation: 0,
|
||||
low_24h: 0,
|
||||
low_24h: { usd: 0 },
|
||||
market_cap: 0,
|
||||
max_supply: 0,
|
||||
price_change_percentage_24h: 0,
|
||||
|
@ -38,10 +38,16 @@ const DEFAULT_COINGECKO_VALUES = {
|
|||
total_volume: 0,
|
||||
}
|
||||
|
||||
type CryptoStatsResponse = {
|
||||
high_24h: Record<string, number>
|
||||
low_24h: Record<string, number>
|
||||
price_change_percentage_24h: number
|
||||
}
|
||||
|
||||
const fetchTokenInfo = async (tokenId: string | undefined) => {
|
||||
if (!tokenId) return
|
||||
const response = await fetch(
|
||||
`https://api.coingecko.com/api/v3/coins/${tokenId}?localization=false&tickers=false&developer_data=false&sparkline=false
|
||||
`https://api.coingecko.com/api/v3/coins/${tokenId}?localization=false&tickers=false&developer_data=false&sparkline=false&community_data=false
|
||||
`
|
||||
)
|
||||
const data = await response.json()
|
||||
|
@ -86,9 +92,9 @@ const TokenPage = () => {
|
|||
}, [bank, mangoTokens])
|
||||
|
||||
const coingeckoTokenInfo = useQuery<
|
||||
{ market_data: any; name: string },
|
||||
{ market_data: CryptoStatsResponse; name: string },
|
||||
Error
|
||||
>(['ip-address', coingeckoId], () => fetchTokenInfo(coingeckoId), {
|
||||
>(['coingecko-token-info', coingeckoId], () => fetchTokenInfo(coingeckoId), {
|
||||
cacheTime: 1000 * 60 * 15,
|
||||
staleTime: 1000 * 60 * 5,
|
||||
retry: 3,
|
||||
|
|
|
@ -13,7 +13,7 @@ import React, {
|
|||
} from 'react'
|
||||
import mangoStore from '@store/mangoStore'
|
||||
import { notify } from 'utils/notifications'
|
||||
import { useLocalStorageStringState } from 'hooks/useLocalStorageState'
|
||||
import useLocalStorageState from 'hooks/useLocalStorageState'
|
||||
|
||||
interface EnhancedWalletContextState {
|
||||
displayedWallets: Wallet[]
|
||||
|
@ -66,7 +66,7 @@ export default function EnhancedWalletProvider({
|
|||
)
|
||||
|
||||
const [preselectedWalletName, setPreselectedWalletName] =
|
||||
useLocalStorageStringState('preselectedWalletName', null)
|
||||
useLocalStorageState('preselectedWalletName', null)
|
||||
|
||||
useEffect(() => {
|
||||
if (wallet) {
|
||||
|
|
|
@ -9,14 +9,14 @@ const fetchJupiterTokens = async (group: Group) => {
|
|||
const url =
|
||||
CLUSTER === 'devnet'
|
||||
? 'https://api.jup.ag/api/tokens/devnet'
|
||||
: 'https://cache.jup.ag/tokens'
|
||||
: 'https://token.jup.ag/strict'
|
||||
const response = await fetch(url)
|
||||
const data = await response.json()
|
||||
const data: Token[] = await response.json()
|
||||
|
||||
const bankMints = Array.from(group!.banksMapByName.values()).map((b) =>
|
||||
const bankMints = Array.from(group.banksMapByName.values()).map((b) =>
|
||||
b[0].mint.toString()
|
||||
)
|
||||
const mangoTokens = data.filter((t: any) => bankMints.includes(t.address))
|
||||
const mangoTokens = data.filter((t) => bankMints.includes(t.address))
|
||||
|
||||
return {
|
||||
mangoTokens,
|
||||
|
@ -31,7 +31,7 @@ const useJupiterMints = (): {
|
|||
} => {
|
||||
const { group } = useMangoGroup()
|
||||
|
||||
const res = useQuery<{ mangoTokens: Token[]; jupiterTokens: Token[] }, Error>(
|
||||
const res = useQuery(
|
||||
['jupiter-mango-tokens'],
|
||||
() => fetchJupiterTokens(group!),
|
||||
{
|
||||
|
|
|
@ -1,11 +1,23 @@
|
|||
import { useMemo, useState, useEffect, useCallback } from 'react'
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import {
|
||||
useMemo,
|
||||
useState,
|
||||
useEffect,
|
||||
useCallback,
|
||||
SetStateAction,
|
||||
Dispatch,
|
||||
} from 'react'
|
||||
|
||||
const localStorageListeners: any = {}
|
||||
interface LocalStorageListenersType {
|
||||
[key: string]: Array<Dispatch<SetStateAction<string>>>
|
||||
}
|
||||
|
||||
export function useLocalStorageStringState(
|
||||
const localStorageListeners: LocalStorageListenersType = {}
|
||||
|
||||
function useLocalStorageStringState(
|
||||
key: string,
|
||||
defaultState: string | null = null
|
||||
): [string | null, (newState: string | null) => void] {
|
||||
defaultState: string
|
||||
): [string | undefined, (newState: string) => void] {
|
||||
const state =
|
||||
typeof window !== 'undefined'
|
||||
? localStorage.getItem(key) || defaultState
|
||||
|
@ -49,26 +61,31 @@ export function useLocalStorageStringState(
|
|||
return [state, setState]
|
||||
}
|
||||
|
||||
type LocalStoreState = any[] | any
|
||||
|
||||
export default function useLocalStorageState(
|
||||
export default function useLocalStorageState<T = any>(
|
||||
key: string,
|
||||
defaultState: LocalStoreState | null = null
|
||||
): [LocalStoreState, (newState: LocalStoreState) => void] {
|
||||
defaultState?: string | number | object | undefined | null | boolean
|
||||
): [T, (newState: string | number | object | null | boolean) => void] {
|
||||
const [stringState, setStringState] = useLocalStorageStringState(
|
||||
key,
|
||||
JSON.stringify(defaultState)
|
||||
)
|
||||
|
||||
const setState = useCallback(
|
||||
(newState: string | number | object) => {
|
||||
(newState: string | number | object | null | boolean) => {
|
||||
setStringState(JSON.stringify(newState))
|
||||
},
|
||||
[setStringState]
|
||||
)
|
||||
|
||||
return [
|
||||
useMemo(() => stringState && JSON.parse(stringState), [stringState]),
|
||||
setState,
|
||||
]
|
||||
const state: T = useMemo(() => {
|
||||
if (stringState) {
|
||||
try {
|
||||
return JSON.parse(stringState)
|
||||
} catch (e) {
|
||||
return stringState
|
||||
}
|
||||
}
|
||||
}, [stringState])
|
||||
|
||||
return [state, setState]
|
||||
}
|
||||
|
|
|
@ -8,28 +8,25 @@ export default function useMarkPrice() {
|
|||
const orderbook = mangoStore((s) => s.selectedMarket.orderbook)
|
||||
const fills = mangoStore((s) => s.selectedMarket.fills)
|
||||
|
||||
const trades = fills
|
||||
.filter((trade: any) => trade?.eventFlags?.maker || trade?.maker)
|
||||
.map((trade: any) => ({
|
||||
...trade,
|
||||
side: trade.side === 'buy' ? 'sell' : 'buy',
|
||||
}))
|
||||
|
||||
useEffect(() => {
|
||||
const bb = orderbook?.bids?.length > 0 && Number(orderbook.bids[0][0])
|
||||
const ba = orderbook?.asks?.length > 0 && Number(orderbook.asks[0][0])
|
||||
const last = trades && trades.length > 0 && trades[0].price
|
||||
const last = fills && fills.length > 0 && fills[0].price
|
||||
|
||||
const priceElements = [bb, ba, last].filter((e) => e).sort((a, b) => a - b)
|
||||
const newMarkPrice = priceElements.length
|
||||
? priceElements[Math.floor(priceElements.length / 2)]
|
||||
: null
|
||||
if (newMarkPrice !== markPrice) {
|
||||
set((state) => {
|
||||
state.selectedMarket.markPrice = newMarkPrice
|
||||
})
|
||||
if (bb && ba && last) {
|
||||
const priceElements = [bb, ba, last]
|
||||
.filter((e) => e)
|
||||
.sort((a, b) => a - b)
|
||||
const newMarkPrice = priceElements.length
|
||||
? priceElements[Math.floor(priceElements.length / 2)]
|
||||
: null
|
||||
if (newMarkPrice && newMarkPrice !== markPrice) {
|
||||
set((state) => {
|
||||
state.selectedMarket.markPrice = newMarkPrice
|
||||
})
|
||||
}
|
||||
}
|
||||
}, [orderbook, trades, markPrice])
|
||||
}, [orderbook, fills, markPrice])
|
||||
|
||||
return markPrice
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { AccountInfo, PublicKey, TransactionInstruction } from '@solana/web3.js'
|
||||
import Decimal from 'decimal.js'
|
||||
|
||||
export declare type SideType = typeof Side.Ask | typeof Side.Bid
|
||||
export declare const Side: {
|
||||
|
@ -138,17 +137,15 @@ export type Routes = {
|
|||
cached: boolean
|
||||
}
|
||||
|
||||
export interface Token {
|
||||
chainId: number // 101,
|
||||
address: string // 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
|
||||
symbol: string // e.g. 'USDC',
|
||||
name: string // 'Wrapped USDC',
|
||||
decimals: number // 6,
|
||||
logoURI: string // 'https://raw.githubusercontent.com/solana-labs/token-list/main/assets/mainnet/BXXkv6z8ykpG1yuvUDPgh732wzVHB69RnB9YgSYh3itW/logo.png',
|
||||
tags: string[] // [ 'stablecoin' ]
|
||||
extensions?: {
|
||||
coingeckoId: string
|
||||
export type Token = {
|
||||
address: string
|
||||
chainId: number
|
||||
decimals: number
|
||||
name: string
|
||||
symbol: string
|
||||
logoURI: string
|
||||
extensions: {
|
||||
coingeckoId?: string
|
||||
}
|
||||
amount?: Decimal
|
||||
amountWithBorrow?: Decimal
|
||||
tags: string[]
|
||||
}
|
||||
|
|
|
@ -10,7 +10,16 @@ export class TokenAccount {
|
|||
decimals!: number
|
||||
uiAmount: number
|
||||
|
||||
constructor(publicKey: PublicKey, decoded: any) {
|
||||
constructor(
|
||||
publicKey: PublicKey,
|
||||
decoded: {
|
||||
mint: PublicKey
|
||||
owner: PublicKey
|
||||
amount: number
|
||||
decimals: number
|
||||
uiAmount: number
|
||||
}
|
||||
) {
|
||||
this.publicKey = publicKey
|
||||
this.uiAmount = 0
|
||||
Object.assign(this, decoded)
|
||||
|
@ -20,7 +29,7 @@ export class TokenAccount {
|
|||
export async function getTokenAccountsByOwnerWithWrappedSol(
|
||||
connection: Connection,
|
||||
owner: PublicKey
|
||||
): Promise<any> {
|
||||
): Promise<TokenAccount[]> {
|
||||
const solReq = connection.getAccountInfo(owner)
|
||||
const tokenReq = connection.getParsedTokenAccountsByOwner(owner, {
|
||||
programId: TokenInstructions.TOKEN_PROGRAM_ID,
|
||||
|
|
Loading…
Reference in New Issue