replace any type with more defined types

This commit is contained in:
tjs 2023-02-25 19:22:39 -05:00
parent dc33e98a8a
commit abb408678e
30 changed files with 161 additions and 121 deletions

View File

@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { makeApiRequest, parseResolution } from './helpers'
import {
closeSocket,

View File

@ -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'

View File

@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { parseResolution, getNextBarTime, socketUrl } from './helpers'
let subscriptionItem: any = {}

View File

@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { makeApiRequest, parseResolution } from './helpers'
import {
subscribeOnStream,

View File

@ -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

View File

@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { getNextBarTime } from './helpers'
let subscriptionItem: any = {}

View File

@ -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) => {

View File

@ -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

View File

@ -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 []

View File

@ -37,7 +37,7 @@ const ActionTokenList = ({
{banks?.length ? (
banks
.filter((b: BankParams) => !!b)
.map((b: any) => {
.map((b) => {
return (
<ActionTokenItem
bank={b.bank}

View File

@ -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>

View File

@ -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">

View File

@ -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) {

View File

@ -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">

View File

@ -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')

View File

@ -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

View File

@ -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('')

View File

@ -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}

View File

@ -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">

View File

@ -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]

View File

@ -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)
}

View File

@ -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>

View File

@ -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 &&

View File

@ -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,

View File

@ -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) {

View File

@ -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!),
{

View File

@ -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]
}

View File

@ -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
}

View File

@ -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[]
}

View File

@ -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,