all the fixes

This commit is contained in:
Tyler Shipe 2021-04-13 19:41:04 -04:00
parent e0510dd3f8
commit 062ac4105a
19 changed files with 167 additions and 126 deletions

View File

@ -47,23 +47,27 @@ const AccountSelect = ({
<div
className={`flex items-center text-base justify-between font-light`}
>
<div className={`flex items-center flex-grow`}>
<img
alt=""
width="20"
height="20"
src={`/assets/icons/${getSymbolForTokenMintAddress(
selectedAccount?.account?.mint.toString()
).toLowerCase()}.svg`}
className={`mr-4`}
/>
{abbreviateAddress(selectedAccount?.publicKey)}
{!hideBalance ? (
<div className={`ml-4 text-sm text-right flex-grow`}>
({getBalanceForAccount(selectedAccount)})
</div>
) : null}
</div>
{selectedAccount ? (
<div className={`flex items-center flex-grow`}>
<img
alt=""
width="20"
height="20"
src={`/assets/icons/${getSymbolForTokenMintAddress(
selectedAccount?.account?.mint.toString()
).toLowerCase()}.svg`}
className={`mr-4`}
/>
{abbreviateAddress(selectedAccount?.publicKey)}
{!hideBalance ? (
<div className={`ml-4 text-sm text-right flex-grow`}>
({getBalanceForAccount(selectedAccount)})
</div>
) : null}
</div>
) : (
'No wallet addresses found'
)}
{open ? (
<ChevronUpIcon className={`h-5 w-5 ml-2`} />
) : (
@ -86,7 +90,7 @@ const AccountSelect = ({
className={`z-20 p-1 absolute left-0 w-full mt-1 bg-th-bkg-3 origin-top-left divide-y divide-th-fgd-4 shadow-lg outline-none border border-th-fgd-4`}
>
<div className={`opacity-50 p-2`}>
Your Connected Wallet Token Accounts
Your Connected Wallet Token Accounts:
</div>
{accounts.map((account) => {
const symbolForAccount = getSymbolForTokenMintAddress(

View File

@ -110,32 +110,32 @@ const BalancesTable = () => {
`}
>
<td
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2 font-light`}
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2`}
>
{balance.coin}
</td>
<td
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2 font-light`}
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2`}
>
{balance.marginDeposits}
</td>
<td
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2 font-light`}
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2`}
>
{balance.borrows}
</td>
<td
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2 font-light`}
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2`}
>
{balance.orders}
</td>
<td
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2 font-light`}
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2`}
>
{balance.unsettled}
</td>
<td
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2 font-light`}
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2`}
>
{balance.net}
</td>
@ -146,7 +146,7 @@ const BalancesTable = () => {
</div>
) : (
<div
className={`w-full text-center py-6 text-base bg-th-bkg-1 font-light text-th-fgd-2 rounded-md`}
className={`w-full text-center py-6 text-base bg-th-bkg-1 text-th-fgd-2 rounded-md`}
>
No balances
</div>

View File

@ -140,15 +140,17 @@ const DepositModal = ({ isOpen, onClose }) => {
<div className={`pb-6 px-8`}>
<div className={`mt-3 text-center sm:mt-5`}>
<div className={`mt-6 bg-th-bkg-3 rounded-md flex items-center`}>
<img
alt=""
width="20"
height="20"
src={`/assets/icons/${getSymbolForTokenMintAddress(
selectedAccount?.account?.mint.toString()
).toLowerCase()}.svg`}
className={`ml-3`}
/>
{selectedAccount ? (
<img
alt=""
width="20"
height="20"
src={`/assets/icons/${getSymbolForTokenMintAddress(
selectedAccount?.account?.mint.toString()
).toLowerCase()}.svg`}
className={`ml-3`}
/>
) : null}
<input
type="number"
min="0"

View File

@ -3,7 +3,6 @@ import { nativeToUi } from '@blockworks-foundation/mango-client/lib/utils'
import Modal from './Modal'
import AccountSelect from './AccountSelect'
import useMangoStore from '../stores/useMangoStore'
import { getSymbolForTokenMintAddress } from '../utils/index'
import useConnection from '../hooks/useConnection'
import { depositSrm } from '../utils/mango'
import { PublicKey } from '@solana/web3.js'
@ -20,9 +19,7 @@ const DepositSrmModal = ({ isOpen, onClose }) => {
const walletAccounts = useMangoStore((s) => s.wallet.balances)
const actions = useMangoStore((s) => s.actions)
const srmMintAddress = useMangoStore((s) => s.connection.srmMint)
const mangoSrmAccountsForOwner = useMangoStore(
(s) => s.selectedMangoGroup.srmAccountsForOwner
)
const mangoSrmAccountsForOwner = useMangoStore((s) => s.wallet.srmAccountsForOwner)
const depositAccounts = useMemo(
() =>
walletAccounts.filter(
@ -116,9 +113,7 @@ const DepositSrmModal = ({ isOpen, onClose }) => {
alt=""
width="20"
height="20"
src={`/assets/icons/${getSymbolForTokenMintAddress(
selectedAccount?.account?.mint.toString()
).toLowerCase()}.svg`}
src={`/assets/icons/SRM.svg`}
className={`ml-3`}
/>
<input

View File

@ -11,9 +11,7 @@ const FeeDiscountsTable = () => {
const [showWithdraw, setShowWithdraw] = useState(false)
const { totalSrm, rates } = useSrmAccount()
const connected = useMangoStore((s) => s.wallet.connected)
const contributedSrm = useMangoStore(
(s) => s.selectedMangoGroup.contributedSrm
)
const contributedSrm = useMangoStore((s) => s.wallet.contributedSrm)
const handleCloseDeposit = useCallback(() => {
setShowDeposit(false)
@ -55,7 +53,12 @@ const FeeDiscountsTable = () => {
</div>
<div className="flex space-x-4 mt-4">
<Button onClick={() => setShowDeposit(true)}>Deposit</Button>
<Button onClick={() => setShowWithdraw(true)}>Withdraw</Button>
<Button
onClick={() => setShowWithdraw(true)}
disabled={!(contributedSrm > 0)}
>
Withdraw
</Button>
</div>
</div>
) : (

View File

@ -7,6 +7,14 @@ interface InputProps {
[x: string]: any
}
const Group = ({ children, className }) => {
return (
<div className={`flex border border-th-fgd-4 rounded ${className}`}>
{children}
</div>
)
}
const Input = ({
type,
value,
@ -28,31 +36,23 @@ const Input = ({
{prefix}
</div>
) : null}
<div className="flex h-full">
<div className="flex items-center h-full border border-transparent hover:border-th-primary">
<input
type={type}
value={value}
onChange={onChange}
className={`bg-transparent w-full focus:outline-none ${
className={`bg-transparent font-light tracking-wider w-full focus:outline-none ${
disabled && 'opacity-20 cursor-not-allowed'
} ${type === 'number' ? 'text-right' : ''}`}
disabled={disabled}
{...props}
/>
{suffix ? (
<span className="text-xs px-2 bg-transparent text-th-fgd-4">
{suffix}
</span>
) : null}
</div>
{suffix ? (
<span className="text-xs px-2 bg-transparent text-th-fgd-4">
{suffix}
</span>
) : null}
</div>
)
}
const Group = ({ children, className }) => {
return (
<div className={`flex border border-th-fgd-4 rounded ${className}`}>
{children}
</div>
)
}

View File

@ -125,7 +125,7 @@ export default function MarginStats() {
<Button
onClick={() => setShowWithdrawModal(true)}
className="ml-4 w-1/2"
disabled={!connected}
disabled={!connected || !selectedMarginAccount}
>
<span>Withdraw</span>
</Button>

View File

@ -142,7 +142,7 @@ const OpenOrdersTable = () => {
</div>
) : (
<div
className={`w-full text-center py-6 text-base bg-th-bkg-1 font-light text-th-fgd-2 rounded-md`}
className={`w-full text-center py-6 text-base bg-th-bkg-1 font-light text-th-fgd-3 rounded-md`}
>
No open orders
</div>

View File

@ -8,6 +8,7 @@ import useMarkPrice from '../hooks/useMarkPrice'
import useOrderbook from '../hooks/useOrderbook'
import useMarket from '../hooks/useMarket'
import { ElementTitle } from './styles'
import useMangoStore from '../stores/useMangoStore'
const Line = styled.div<any>`
text-align: ${(props) => (props.invert ? 'left' : 'right')};
@ -45,6 +46,7 @@ export default function Orderbook({ depth = 7 }) {
const markPrice = useMarkPrice()
const [orderbook] = useOrderbook()
const { baseCurrency, quoteCurrency } = useMarket()
const setMangoStore = useMangoStore((s) => s.set)
const currentOrderbookData = useRef(null)
const lastOrderbookData = useRef(null)
@ -93,6 +95,18 @@ export default function Orderbook({ depth = 7 }) {
}
}, [orderbook])
const handlePriceClick = (price) => {
setMangoStore((state) => {
state.tradeForm.price = price
})
}
const handleSizeClick = (size) => {
setMangoStore((state) => {
state.tradeForm.baseSize = size
})
}
return (
<>
<ElementTitle>Orderbook</ElementTitle>
@ -107,8 +121,8 @@ export default function Orderbook({ depth = 7 }) {
size={size}
side={'sell'}
sizePercent={sizePercent}
onPriceClick={() => alert(`price ${price}`)}
onSizeClick={() => alert(`size ${size}`)}
onPriceClick={() => handlePriceClick(price)}
onSizeClick={() => handleSizeClick(size)}
/>
))}
<MarkPriceComponent markPrice={markPrice} />
@ -119,8 +133,8 @@ export default function Orderbook({ depth = 7 }) {
size={size}
side={'buy'}
sizePercent={sizePercent}
onPriceClick={() => alert(`price ${price}`)}
onSizeClick={() => alert(`size ${size}`)}
onPriceClick={() => handlePriceClick(price)}
onSizeClick={() => handleSizeClick(size)}
/>
))}
</>

View File

@ -40,16 +40,16 @@ const TopBar = () => {
<MenuItem href="https://docs.mango.markets/">Learn</MenuItem>
</div>
</div>
<div className={`flex`}>
<div className={`flex items-center pr-1`}>
<div className="flex">
<div className="flex items-center pr-1">
{asPath === '/' ? <UiLock className="mr-4" /> : null}
<ThemeSwitch />
<div className={`hidden sm:ml-4 sm:flex sm:items-center`}>
<button
onClick={handleConnectDisconnect}
className={`border border-th-primary hover:bg-th-primary rounded-md px-4 py-2 focus:outline-none text-th-primary hover:text-th-fgd-1 font-semibold text-base`}
>
<div>
<div className="hidden sm:ml-4 sm:flex sm:items-center">
<div className="border border-th-primary hover:bg-th-primary rounded-md ">
<button
onClick={handleConnectDisconnect}
className="px-4 py-2 focus:outline-none text-th-primary hover:text-th-fgd-1 font-semibold text-bas"
>
{connected ? (
<div onClick={wallet.disconnect}>
<span>Disconnect: </span>
@ -64,8 +64,8 @@ const TopBar = () => {
) : (
'Connect Wallet'
)}
</div>
</button>
</button>
</div>
</div>
</div>
<div className={`-mr-2 flex items-center sm:hidden`}>

View File

@ -12,8 +12,8 @@ import { roundToDecimal } from '../utils/index'
import useMangoStore from '../stores/useMangoStore'
import Button from './Button'
import TradeType from './TradeType'
import NewInput from './Input'
import NewSwitch from './Switch'
import Input from './Input'
import Switch from './Switch'
export default function TradeForm() {
const { baseCurrency, quoteCurrency, market, marketAddress } = useMarket()
@ -238,8 +238,8 @@ export default function TradeForm() {
</div>
</button>
</div>
<NewInput.Group className="mt-4">
<NewInput
<Input.Group className="mt-4">
<Input
type="number"
step={market?.tickSize || 1}
onChange={(e) => setPrice(parseFloat(e.target.value))}
@ -252,38 +252,38 @@ export default function TradeForm() {
<TradeType
onChange={handleTradeTypeChange}
value={tradeType}
className="w-2/5"
className="w-2/5 hover:border-th-primary"
/>
</NewInput.Group>
</Input.Group>
<NewInput.Group className="mt-4">
<NewInput
<Input.Group className="mt-4">
<Input
type="number"
step={market?.minOrderSize || 1}
onChange={(e) => onSetBaseSize(parseFloat(e.target.value))}
value={baseSize}
className="text-right flex-grow w-3/5 rounded-r-none"
className="flex-grow w-3/5 rounded-r-none"
prefix={'Size'}
suffix={baseCurrency}
/>
<NewInput
<Input
type="number"
step={market?.minOrderSize || 1}
onChange={(e) => onSetQuoteSize(parseFloat(e.target.value))}
value={quoteSize}
className="text-right border-l border-th-fgd-4 rounded-l-none w-2/5"
className="border-l border-th-fgd-4 rounded-l-none w-2/5"
suffix={quoteCurrency}
/>
</NewInput.Group>
</Input.Group>
{tradeType !== 'Market' ? (
<div className="flex items-center mt-4">
<NewSwitch checked={postOnly} onChange={postOnChange}>
<Switch checked={postOnly} onChange={postOnChange}>
POST
</NewSwitch>
</Switch>
<div className="ml-4">
<NewSwitch checked={ioc} onChange={iocOnChange}>
<Switch checked={ioc} onChange={iocOnChange}>
IOC
</NewSwitch>
</Switch>
</div>
</div>
) : null}

View File

@ -50,6 +50,12 @@ const TradeHistoryTable = () => {
>
Fees
</th>
<th
scope="col"
className={`px-6 py-3 text-left text-base font-medium text-th-fgd-2 tracking-wider`}
>
Date
</th>
</tr>
</thead>
<tbody>
@ -57,16 +63,16 @@ const TradeHistoryTable = () => {
<tr
key={`${trade.orderId}${trade.side}`}
className={`
${index % 2 === 0 ? `bg-th-bkg-2` : `bg-th-bkg-3`}
${index % 2 === 0 ? `bg-th-bkg-3` : `bg-th-bkg-2`}
`}
>
<td
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2 font-light`}
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2`}
>
{trade.marketName}
</td>
<td
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2 font-light`}
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2`}
>
<div
className={`rounded inline-block ${
@ -80,25 +86,32 @@ const TradeHistoryTable = () => {
</div>
</td>
<td
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2 font-light`}
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2`}
>
{trade.size}
</td>
<td
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2 font-light`}
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2`}
>
{trade.price}
</td>
<td
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2 font-light`}
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2`}
>
{trade.liquidity}
</td>
<td
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2 font-light`}
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2`}
>
{trade.feeCost}
</td>
<td
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2`}
>
{trade.loadTimestamp
? new Date(trade.loadTimestamp).toLocaleDateString()
: 'Recent'}
</td>
</tr>
))}
</tbody>
@ -106,7 +119,7 @@ const TradeHistoryTable = () => {
</div>
) : (
<div
className={`w-full text-center py-6 text-base bg-th-bkg-1 font-light text-th-fgd-4 rounded-md`}
className={`w-full text-center py-6 text-base bg-th-bkg-1 text-th-fgd-2 rounded-md`}
>
No trade history
</div>

View File

@ -27,7 +27,7 @@ const WithdrawModal = ({ isOpen, onClose }) => {
)
const [selectedAccount, setSelectedAccount] = useState(withdrawAccounts[0])
const mintAddress = useMemo(() => selectedAccount?.account.mint.toString(), [
selectedAccount.account.mint,
selectedAccount,
])
const tokenIndex = useMemo(() => getTokenIndex(mintAddress), [
mintAddress,
@ -86,6 +86,8 @@ const WithdrawModal = ({ isOpen, onClose }) => {
}
}
if (!selectedAccount) return null
return (
<Modal isOpen={isOpen} onClose={onClose}>
<Modal.Header>

View File

@ -18,11 +18,9 @@ const WithdrawModal = ({ isOpen, onClose }) => {
const walletAccounts = useMangoStore((s) => s.wallet.balances)
const actions = useMangoStore((s) => s.actions)
const srmMintAddress = useMangoStore((s) => s.connection.srmMint)
const contributedSrm = useMangoStore(
(s) => s.selectedMangoGroup.contributedSrm
)
const contributedSrm = useMangoStore((s) => s.wallet.contributedSrm)
const mangoSrmAccountsForOwner = useMangoStore(
(s) => s.selectedMangoGroup.srmAccountsForOwner
(s) => s.wallet.srmAccountsForOwner
)
const walletSrmAccount = useMemo(
() =>

View File

@ -17,13 +17,16 @@ const useMarginAccount = () => {
}, [actions])
useEffect(() => {
if (!connected) return
actions.fetchMarginAcccount()
actions.fetchMangoSrmAccounts()
if (connected) {
actions.fetchMarginAcccount()
actions.fetchMangoSrmAccounts()
}
}, [connected, actions])
useInterval(() => {
actions.fetchMarginAcccount()
if (connected) {
actions.fetchMarginAcccount()
}
// fetchMangoGroup()
}, 9000)

View File

@ -1,7 +1,7 @@
import { useEffect } from 'react'
import Wallet from '@project-serum/sol-wallet-adapter'
import useLocalStorageState from './useLocalStorageState'
import useMangoStore from '../stores/useMangoStore'
import useMangoStore, { INITIAL_STATE } from '../stores/useMangoStore'
import { notify } from '../utils/notifications'
export const WALLET_PROVIDERS = [
@ -33,8 +33,7 @@ export default function useWallet() {
setMangoStore((state) => {
state.wallet.current = newWallet
})
// eslint-disable-next-line
}, [endpoint])
}, [endpoint, connected])
useEffect(() => {
if (!wallet) return
@ -55,7 +54,7 @@ export default function useWallet() {
})
wallet.on('disconnect', () => {
setMangoStore((state) => {
state.wallet.connected = false
state.wallet = INITIAL_STATE.WALLET
state.marginAccounts = []
state.selectedMarginAccount.current = null
})
@ -67,7 +66,7 @@ export default function useWallet() {
return () => {
wallet.disconnect()
setMangoStore((state) => {
state.wallet.connected = false
state.wallet = INITIAL_STATE.WALLET
})
}
}, [wallet])

View File

@ -193,7 +193,7 @@ export default function StatsPage() {
<div className="min-h-screen w-full lg:w-2/3 mx-auto p-1 sm:px-2 sm:py-1 md:px-6 md:py-1">
<FloatingElement>
<div className="text-center">
<h1 className={`text-white text-3xl`}>Mango Stats</h1>
<h1 className={`text-th-fgd-1 text-3xl`}>Mango Stats</h1>
</div>
<div className="hidden md:flex md:flex-col min-w-full">
<table className="min-w-full">

View File

@ -32,6 +32,16 @@ const ENDPOINT_URL = ENDPOINTS.find((e) => e.name === CLUSTER).endpoint
const DEFAULT_CONNECTION = new Connection(ENDPOINT_URL, 'recent')
const DEFAULT_MANGO_GROUP_NAME = 'BTC_ETH_USDT'
export const INITIAL_STATE = {
WALLET: {
connected: false,
current: null,
balances: [],
srmAccountsForOwner: [],
contributedSrm: 0,
},
}
// an object with keys of Solana account addresses that we are
// subscribing to with connection.onAccountChange() in the
// useHydrateStore hook
@ -73,8 +83,6 @@ interface MangoStore extends State {
[key: string]: Market
}
mintDecimals: number[]
srmAccountsForOwner: any[]
contributedSrm: number
}
selectedMarginAccount: {
current: MarginAccount | null
@ -90,6 +98,8 @@ interface MangoStore extends State {
connected: boolean
current: Wallet
balances: Array<{ account: any; publicKey: PublicKey }>
srmAccountsForOwner: any[]
contributedSrm: number
}
settings: {
uiLocked: boolean
@ -113,8 +123,6 @@ const useMangoStore = create<MangoStore>((set, get) => ({
markets: {},
srmAccount: null,
mintDecimals: [],
srmAccountsForOwner: [],
contributedSrm: 0,
},
selectedMarket: {
name: Object.entries(
@ -143,11 +151,7 @@ const useMangoStore = create<MangoStore>((set, get) => ({
tradeType: 'Limit',
price: '',
},
wallet: {
connected: false,
current: null,
balances: [],
},
wallet: INITIAL_STATE.WALLET,
settings: {
uiLocked: true,
},
@ -214,7 +218,7 @@ const useMangoStore = create<MangoStore>((set, get) => ({
const programId = IDS[cluster].mango_program_id
const set = get().set
if (!wallet.publicKey) return
if (!wallet || !wallet.publicKey) return
mangoClient
.getMarginAccountsForOwner(

View File

@ -146,5 +146,9 @@ export const tokenPrecision = {
}
export const getSymbolForTokenMintAddress = (address: string): string => {
return TOKEN_MINTS.find((m) => m.address.toString() === address).name
if (address && address.length) {
return TOKEN_MINTS.find((m) => m.address.toString() === address).name
} else {
return ''
}
}