add market select dropdown
This commit is contained in:
parent
ea376cc166
commit
a0c0768473
|
@ -0,0 +1,53 @@
|
|||
import xw from 'xwind'
|
||||
import { Menu, Transition } from '@headlessui/react'
|
||||
import useMarketList from '../hooks/useMarketList'
|
||||
import useMarket from '../hooks/useMarket'
|
||||
|
||||
const DropdownExample = () => {
|
||||
const { spotMarkets } = useMarketList()
|
||||
const { marketName } = useMarket()
|
||||
|
||||
console.log('spot markets', spotMarkets)
|
||||
|
||||
// const handleChange = (e) => {
|
||||
// console.log('new market selected', e)
|
||||
// }
|
||||
|
||||
return (
|
||||
<div css={xw`ml-4`}>
|
||||
<Menu>
|
||||
{({ open }) => (
|
||||
<>
|
||||
<Menu.Button>{marketName}</Menu.Button>
|
||||
<Transition
|
||||
show={open}
|
||||
enter="transition ease-out duration-100"
|
||||
enterFrom="transform opacity-0 scale-95"
|
||||
enterTo="transform opacity-100 scale-100"
|
||||
leave="transition ease-in duration-75"
|
||||
leaveFrom="transform opacity-100 scale-100"
|
||||
leaveTo="transform opacity-0 scale-95"
|
||||
>
|
||||
<Menu.Items>
|
||||
{Object.entries(spotMarkets).map(([name, address]) => (
|
||||
<Menu.Item key={address}>
|
||||
{({ active }) => (
|
||||
<a
|
||||
className={`${active && 'bg-blue-500'}`}
|
||||
href="/account-settings"
|
||||
>
|
||||
{name}
|
||||
</a>
|
||||
)}
|
||||
</Menu.Item>
|
||||
))}
|
||||
</Menu.Items>
|
||||
</Transition>
|
||||
</>
|
||||
)}
|
||||
</Menu>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default DropdownExample
|
|
@ -73,9 +73,8 @@ export default function MarginInfo() {
|
|||
>(null)
|
||||
const { tradeHistory } = useTradeHistory()
|
||||
|
||||
// Settle bororows
|
||||
useEffect(() => {
|
||||
console.log('HERE mangoGroup: ', mangoGroup)
|
||||
console.log('marginInfo useEffect')
|
||||
|
||||
if (mangoGroup) {
|
||||
mangoGroup.getPrices(connection).then((prices) => {
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
import xw from 'xwind'
|
||||
import { Listbox, Transition } from '@headlessui/react'
|
||||
import { ChevronDownIcon, ChevronUpIcon } from '@heroicons/react/solid'
|
||||
import useMarketList from '../hooks/useMarketList'
|
||||
// import useMarket from '../hooks/useMarket'
|
||||
import useMangoStore from '../stores/useMangoStore'
|
||||
|
||||
const MarketSelect = () => {
|
||||
const { spotMarkets } = useMarketList()
|
||||
const selectedMarket = useMangoStore((s) => s.selectedMarket)
|
||||
const setMangoStore = useMangoStore((s) => s.set)
|
||||
|
||||
const handleChange = (mktName) => {
|
||||
setMangoStore((state) => {
|
||||
state.selectedMarket = { name: mktName, address: spotMarkets[mktName] }
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<div css={xw`ml-4 relative inline-block -mb-1`}>
|
||||
<Listbox value={selectedMarket.name} onChange={handleChange}>
|
||||
{({ open }) => (
|
||||
<>
|
||||
<Listbox.Button
|
||||
css={xw`border border-mango-dark-lighter focus:outline-none focus:ring-1 focus:ring-mango-yellow p-2 w-56`}
|
||||
>
|
||||
<div
|
||||
css={xw`flex items-center text-lg justify-between font-light`}
|
||||
>
|
||||
{selectedMarket.name}
|
||||
{open ? (
|
||||
<ChevronUpIcon css={xw`h-5 w-5 mr-1`} />
|
||||
) : (
|
||||
<ChevronDownIcon css={xw`h-5 w-5 mr-1`} />
|
||||
)}
|
||||
</div>
|
||||
</Listbox.Button>
|
||||
<Transition
|
||||
show={open}
|
||||
enter="transition duration-100 ease-out"
|
||||
enterFrom="transform scale-95 opacity-0"
|
||||
enterTo="transform scale-100 opacity-100"
|
||||
leave="transition duration-75 ease-out"
|
||||
leaveFrom="transform scale-100 opacity-100"
|
||||
leaveTo="transform scale-95 opacity-0"
|
||||
>
|
||||
<Listbox.Options
|
||||
static
|
||||
css={xw`z-20 p-1 absolute left-0 w-56 mt-1 bg-mango-dark-light origin-top-left divide-y divide-mango-dark-lighter shadow-lg outline-none`}
|
||||
>
|
||||
<div css={xw`opacity-50 p-2`}>Markets</div>
|
||||
{Object.entries(spotMarkets).map(([name, address]) => (
|
||||
<Listbox.Option key={address} value={name}>
|
||||
{({ selected }) => (
|
||||
<div
|
||||
css={[
|
||||
xw`p-2 text-base hover:bg-mango-dark-lighter hover:cursor-pointer tracking-wider font-light`,
|
||||
selected &&
|
||||
xw`text-mango-yellow bg-mango-dark-lighter`,
|
||||
]}
|
||||
>
|
||||
{name}
|
||||
</div>
|
||||
)}
|
||||
</Listbox.Option>
|
||||
))}
|
||||
</Listbox.Options>
|
||||
</Transition>
|
||||
</>
|
||||
)}
|
||||
</Listbox>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default MarketSelect
|
|
@ -3,7 +3,7 @@ import xw from 'xwind'
|
|||
import { TrashIcon } from '@heroicons/react/solid'
|
||||
|
||||
const OpenOrdersTable = () => {
|
||||
const [openOrders, setOpenOrders] = useState(['test'])
|
||||
const [openOrders] = useState(['test'])
|
||||
|
||||
return (
|
||||
<div css={xw`flex flex-col py-6`}>
|
||||
|
@ -79,7 +79,7 @@ const OpenOrdersTable = () => {
|
|||
0.00
|
||||
</td>
|
||||
<td
|
||||
css={xw`px-6 py-4 whitespace-nowrap text-right text-sm font-medium`}
|
||||
css={xw`px-6 py-4 opacity-75 whitespace-nowrap text-right text-sm font-medium`}
|
||||
>
|
||||
<button
|
||||
css={xw`flex items-center ml-auto text-mango-red border border-mango-red hover:text-red-700 hover:border-red-700 py-1 px-4`}
|
||||
|
|
|
@ -7,7 +7,7 @@ import { isEqual, getDecimalCount } from '../utils/'
|
|||
import { ArrowUpIcon, ArrowDownIcon } from '@heroicons/react/solid'
|
||||
import useMarkPrice from '../hooks/useMarkPrice'
|
||||
import useOrderbook from '../hooks/useOrderbook'
|
||||
import useMarkets from '../hooks/useMarkets'
|
||||
import useMarket from '../hooks/useMarket'
|
||||
import { ElementTitle } from './styles'
|
||||
|
||||
const Line = styled.div<any>`
|
||||
|
@ -22,7 +22,7 @@ const Line = styled.div<any>`
|
|||
export default function Orderbook({ depth = 7 }) {
|
||||
const markPrice = useMarkPrice()
|
||||
const [orderbook] = useOrderbook()
|
||||
const { baseCurrency, quoteCurrency } = useMarkets()
|
||||
const { baseCurrency, quoteCurrency } = useMarket()
|
||||
|
||||
const currentOrderbookData = useRef(null)
|
||||
const lastOrderbookData = useRef(null)
|
||||
|
@ -117,7 +117,7 @@ export default function Orderbook({ depth = 7 }) {
|
|||
const OrderbookRow = React.memo<any>(
|
||||
({ side, price, size, sizePercent, onSizeClick, onPriceClick, invert }) => {
|
||||
const element = useRef(null)
|
||||
const { market } = useMarkets()
|
||||
const { market } = useMarket()
|
||||
|
||||
useEffect(() => {
|
||||
!element.current?.classList.contains('flash') &&
|
||||
|
@ -193,7 +193,7 @@ const OrderbookRow = React.memo<any>(
|
|||
|
||||
const MarkPriceComponent = React.memo<{ markPrice: number }>(
|
||||
({ markPrice }) => {
|
||||
const { market } = useMarkets()
|
||||
const { market } = useMarket()
|
||||
const previousMarkPrice: number = usePrevious(markPrice)
|
||||
|
||||
const markPriceColor =
|
||||
|
|
|
@ -4,13 +4,13 @@ import xw from 'xwind'
|
|||
import { getDecimalCount } from '../utils'
|
||||
import { ChartTradeType } from '../@types/types'
|
||||
import FloatingElement from './FloatingElement'
|
||||
import useMarkets from '../hooks/useMarkets'
|
||||
import useMarket from '../hooks/useMarket'
|
||||
import useInterval from '../hooks/useInterval'
|
||||
import ChartApi from '../utils/chartDataConnector'
|
||||
import { ElementTitle } from './styles'
|
||||
|
||||
export default function PublicTrades() {
|
||||
const { baseCurrency, quoteCurrency, market, marketAddress } = useMarkets()
|
||||
const { baseCurrency, quoteCurrency, market, marketAddress } = useMarket()
|
||||
const [trades, setTrades] = useState([])
|
||||
|
||||
useInterval(async () => {
|
||||
|
|
|
@ -43,7 +43,7 @@ const TopBar = () => {
|
|||
onClick={handleConnectDisconnect}
|
||||
css={xw`bg-mango-dark-light hover:bg-mango-dark-lighter text-mango-yellow rounded-md px-4 py-2 focus:outline-none`}
|
||||
>
|
||||
<div css={xw`text-base font-light`}>
|
||||
<div css={xw`text-lg font-light`}>
|
||||
{connected ? (
|
||||
<div onClick={wallet.disconnect}>
|
||||
<span>Disconnect: </span>
|
||||
|
|
|
@ -2,7 +2,7 @@ import { useState, useEffect, useRef } from 'react'
|
|||
import { Input, Radio, Switch, Select } from 'antd'
|
||||
import xw from 'xwind'
|
||||
import styled from '@emotion/styled'
|
||||
import useMarkets from '../hooks/useMarkets'
|
||||
import useMarket from '../hooks/useMarket'
|
||||
import useWallet from '../hooks/useWallet'
|
||||
import useIpAddress from '../hooks/useIpAddress'
|
||||
import useConnection from '../hooks/useConnection'
|
||||
|
@ -36,10 +36,10 @@ export default function TradeForm({
|
|||
ref: ({ size, price }: { size?: number; price?: number }) => void
|
||||
) => void
|
||||
}) {
|
||||
console.log('reloading trade form')
|
||||
// console.log('reloading trade form')
|
||||
|
||||
const [side, setSide] = useState<'buy' | 'sell'>('buy')
|
||||
const { baseCurrency, quoteCurrency, market } = useMarkets()
|
||||
const { baseCurrency, quoteCurrency, market } = useMarket()
|
||||
const address = market?.publicKey
|
||||
const { wallet, connected } = useWallet()
|
||||
|
||||
|
@ -368,20 +368,24 @@ export default function TradeForm({
|
|||
side === 'buy' ? (
|
||||
<BuyButton
|
||||
disabled={
|
||||
(!price && tradeType === 'Limit') || !baseSize || !connected
|
||||
(!price && tradeType === 'Limit') ||
|
||||
!baseSize ||
|
||||
!connected ||
|
||||
submitting
|
||||
}
|
||||
onClick={onSubmit}
|
||||
loading={submitting}
|
||||
>
|
||||
{connected ? `Buy ${baseCurrency}` : 'CONNECT WALLET TO TRADE'}
|
||||
</BuyButton>
|
||||
) : (
|
||||
<SellButton
|
||||
disabled={
|
||||
(!price && tradeType === 'Limit') || !baseSize || !connected
|
||||
(!price && tradeType === 'Limit') ||
|
||||
!baseSize ||
|
||||
!connected ||
|
||||
submitting
|
||||
}
|
||||
onClick={onSubmit}
|
||||
loading={submitting}
|
||||
>
|
||||
{connected ? `Sell ${baseCurrency}` : 'CONNECT WALLET TO TRADE'}
|
||||
</SellButton>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import * as React from 'react'
|
||||
import { useEffect, useRef } from 'react'
|
||||
import {
|
||||
widget,
|
||||
ChartingLibraryWidgetOptions,
|
||||
|
@ -7,6 +7,7 @@ import {
|
|||
} from '../charting_library' // Make sure to follow step 1 of the README
|
||||
// import { useMarket } from '../../utils/markets';
|
||||
import { CHART_DATA_FEED } from '../../utils/chartDataConnector'
|
||||
import useMangoStore from '../../stores/useMangoStore'
|
||||
|
||||
// This is a basic example of how to create a TV widget
|
||||
// You can add more feature such as storing charts in localStorage
|
||||
|
@ -30,9 +31,10 @@ export interface ChartContainerProps {
|
|||
// export interface ChartContainerState {}
|
||||
|
||||
const TVChartContainer = () => {
|
||||
const selectedMarketName = useMangoStore((s) => s.selectedMarket.name)
|
||||
// @ts-ignore
|
||||
const defaultProps: ChartContainerProps = {
|
||||
symbol: 'BTC/USDT',
|
||||
symbol: selectedMarketName,
|
||||
interval: '60' as ResolutionString,
|
||||
theme: 'Dark',
|
||||
containerId: 'tv_chart_container',
|
||||
|
@ -46,25 +48,13 @@ const TVChartContainer = () => {
|
|||
},
|
||||
}
|
||||
|
||||
const tvWidgetRef = React.useRef<IChartingLibraryWidget | null>(null)
|
||||
const tvWidgetRef = useRef<IChartingLibraryWidget | null>(null)
|
||||
// TODO: fetch market from store and wire up to chart
|
||||
// const { market, marketName } = useMarket()
|
||||
|
||||
const parsedMarketName = 'BTC/USDT'
|
||||
// switch (marketName) {
|
||||
// case 'BTC/WUSDT':
|
||||
// parsedMarketName = 'BTC/USDT'
|
||||
// break
|
||||
// case 'ETH/WUSDT':
|
||||
// parsedMarketName = 'ETH/USDT'
|
||||
// break
|
||||
// default:
|
||||
// parsedMarketName = marketName
|
||||
// }
|
||||
|
||||
React.useEffect(() => {
|
||||
useEffect(() => {
|
||||
const widgetOptions: ChartingLibraryWidgetOptions = {
|
||||
symbol: parsedMarketName,
|
||||
symbol: selectedMarketName,
|
||||
// BEWARE: no trailing slash is expected in feed URL
|
||||
// tslint:disable-next-line:no-any
|
||||
datafeed: new (window as any).Datafeeds.UDFCompatibleDatafeed(
|
||||
|
@ -138,7 +128,7 @@ const TVChartContainer = () => {
|
|||
})
|
||||
})
|
||||
//eslint-disable-next-line
|
||||
}, [])
|
||||
}, [selectedMarketName])
|
||||
|
||||
// TODO: add market back to dep array
|
||||
// }, [market])
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
import { useEffect } from 'react'
|
||||
import { Market } from '@project-serum/serum'
|
||||
import useConnection from './useConnection'
|
||||
import useMangoStore from '../stores/useMangoStore'
|
||||
import { PublicKey } from '@solana/web3.js'
|
||||
|
||||
const useHydrateStore = () => {
|
||||
const setMangoStore = useMangoStore((s) => s.set)
|
||||
const selectedMarket = useMangoStore((s) => s.selectedMarket)
|
||||
const { connection, dexProgramId } = useConnection()
|
||||
|
||||
useEffect(() => {
|
||||
console.log(
|
||||
'useEffect loading market',
|
||||
selectedMarket.address,
|
||||
dexProgramId
|
||||
)
|
||||
Market.load(
|
||||
connection,
|
||||
new PublicKey(selectedMarket.address),
|
||||
{},
|
||||
new PublicKey(dexProgramId)
|
||||
)
|
||||
.then((market) => {
|
||||
setMangoStore((state) => {
|
||||
state.market.current = market
|
||||
// @ts-ignore
|
||||
state.accountInfos[market._decoded.bids.toString()] = null
|
||||
// @ts-ignore
|
||||
state.accountInfos[market._decoded.asks.toString()] = null
|
||||
})
|
||||
})
|
||||
.catch(
|
||||
(e) => {
|
||||
console.error('failed to load market', e)
|
||||
}
|
||||
// TODO
|
||||
// notify({
|
||||
// message: 'Error loading market',
|
||||
// description: e.message,
|
||||
// type: 'error',
|
||||
// }),
|
||||
)
|
||||
}, [selectedMarket])
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
export default useHydrateStore
|
|
@ -0,0 +1,60 @@
|
|||
import { useMemo } from 'react'
|
||||
import useConnection from './useConnection'
|
||||
import { PublicKey } from '@solana/web3.js'
|
||||
import useMangoStore from '../stores/useMangoStore'
|
||||
import { IDS } from '@blockworks-foundation/mango-client'
|
||||
|
||||
const formatTokenMints = (symbols: { [name: string]: string }) => {
|
||||
return Object.entries(symbols).map(([name, address]) => {
|
||||
return {
|
||||
address: new PublicKey(address),
|
||||
name: name,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const useMarket = () => {
|
||||
const market = useMangoStore((state) => state.market.current)
|
||||
const selectedMarket = useMangoStore((state) => state.selectedMarket)
|
||||
const { cluster, programId } = useConnection()
|
||||
|
||||
const marketAddress = useMemo(
|
||||
() => (market ? market.publicKey.toString() : null),
|
||||
[market]
|
||||
)
|
||||
|
||||
const TOKEN_MINTS = useMemo(() => formatTokenMints(IDS[cluster].symbols), [
|
||||
cluster,
|
||||
])
|
||||
|
||||
const baseCurrency = useMemo(
|
||||
() =>
|
||||
(market?.baseMintAddress &&
|
||||
TOKEN_MINTS.find((token) =>
|
||||
token.address.equals(market.baseMintAddress)
|
||||
)?.name) ||
|
||||
'UNKNOWN',
|
||||
[market, TOKEN_MINTS]
|
||||
)
|
||||
|
||||
const quoteCurrency = useMemo(
|
||||
() =>
|
||||
(market?.quoteMintAddress &&
|
||||
TOKEN_MINTS.find((token) =>
|
||||
token.address.equals(market.quoteMintAddress)
|
||||
)?.name) ||
|
||||
'UNKNOWN',
|
||||
[market, TOKEN_MINTS]
|
||||
)
|
||||
|
||||
return {
|
||||
market,
|
||||
marketAddress,
|
||||
programId,
|
||||
marketName: selectedMarket.name,
|
||||
baseCurrency,
|
||||
quoteCurrency,
|
||||
}
|
||||
}
|
||||
|
||||
export default useMarket
|
|
@ -0,0 +1,36 @@
|
|||
import { useMemo } from 'react'
|
||||
import useConnection from './useConnection'
|
||||
import { PublicKey } from '@solana/web3.js'
|
||||
import useMangoStore from '../stores/useMangoStore'
|
||||
import { IDS } from '@blockworks-foundation/mango-client'
|
||||
|
||||
const useMarketList = () => {
|
||||
const mangoGroupName = useMangoStore((state) => state.selectedMangoGroup.name)
|
||||
const { cluster, programId, dexProgramId } = useConnection()
|
||||
|
||||
const spotMarkets = useMemo(
|
||||
() => IDS[cluster]?.mango_groups[mangoGroupName]?.spot_market_symbols || {},
|
||||
[cluster, mangoGroupName]
|
||||
)
|
||||
|
||||
const marketList = useMemo(
|
||||
() =>
|
||||
Object.entries(spotMarkets).map(([name, address]) => {
|
||||
return {
|
||||
address: new PublicKey(address as string),
|
||||
programId: new PublicKey(dexProgramId as string),
|
||||
deprecated: false,
|
||||
name,
|
||||
}
|
||||
}),
|
||||
[spotMarkets, dexProgramId]
|
||||
)
|
||||
|
||||
return {
|
||||
programId,
|
||||
marketList,
|
||||
spotMarkets,
|
||||
}
|
||||
}
|
||||
|
||||
export default useMarketList
|
|
@ -1,106 +0,0 @@
|
|||
import { useEffect, useMemo } from 'react'
|
||||
import useConnection from './useConnection'
|
||||
import { PublicKey } from '@solana/web3.js'
|
||||
import { Market } from '@project-serum/serum'
|
||||
import useMangoStore from '../stores/useMangoStore'
|
||||
import { IDS } from '@blockworks-foundation/mango-client'
|
||||
|
||||
const formatTokenMints = (symbols: { [name: string]: string }) => {
|
||||
return Object.entries(symbols).map(([name, address]) => {
|
||||
return {
|
||||
address: new PublicKey(address),
|
||||
name: name,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const useMarkets = () => {
|
||||
const setMangoStore = useMangoStore((state) => state.set)
|
||||
const mangoGroupName = useMangoStore((state) => state.selectedMangoGroup.name)
|
||||
const market = useMangoStore((state) => state.market.current)
|
||||
const { connection, cluster, programId, dexProgramId } = useConnection()
|
||||
const marketAddress = useMemo(
|
||||
() => (market ? market.publicKey.toString() : null),
|
||||
[market]
|
||||
)
|
||||
|
||||
const spotMarkets = useMemo(
|
||||
() => IDS[cluster]?.mango_groups[mangoGroupName]?.spot_market_symbols || {},
|
||||
[cluster, mangoGroupName]
|
||||
)
|
||||
|
||||
const marketList = useMemo(
|
||||
() =>
|
||||
Object.entries(spotMarkets).map(([name, address]) => {
|
||||
return {
|
||||
address: new PublicKey(address as string),
|
||||
programId: new PublicKey(dexProgramId as string),
|
||||
deprecated: false,
|
||||
name,
|
||||
}
|
||||
}),
|
||||
[spotMarkets]
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
if (market) return
|
||||
|
||||
console.log('loading market', connection)
|
||||
Market.load(connection, marketList[0].address, {}, marketList[0].programId)
|
||||
.then((market) => {
|
||||
setMangoStore((state) => {
|
||||
state.market.current = market
|
||||
// @ts-ignore
|
||||
state.accountInfos[market._decoded.bids.toString()] = null
|
||||
// @ts-ignore
|
||||
state.accountInfos[market._decoded.asks.toString()] = null
|
||||
})
|
||||
})
|
||||
.catch(
|
||||
(e) => {
|
||||
console.error('failed to load market', e)
|
||||
}
|
||||
// TODO
|
||||
// notify({
|
||||
// message: 'Error loading market',
|
||||
// description: e.message,
|
||||
// type: 'error',
|
||||
// }),
|
||||
)
|
||||
}, [])
|
||||
|
||||
const TOKEN_MINTS = useMemo(() => formatTokenMints(IDS[cluster].symbols), [
|
||||
cluster,
|
||||
])
|
||||
|
||||
const baseCurrency = useMemo(
|
||||
() =>
|
||||
(market?.baseMintAddress &&
|
||||
TOKEN_MINTS.find((token) =>
|
||||
token.address.equals(market.baseMintAddress)
|
||||
)?.name) ||
|
||||
'UNKNOWN',
|
||||
[market, TOKEN_MINTS]
|
||||
)
|
||||
|
||||
const quoteCurrency = useMemo(
|
||||
() =>
|
||||
(market?.quoteMintAddress &&
|
||||
TOKEN_MINTS.find((token) =>
|
||||
token.address.equals(market.quoteMintAddress)
|
||||
)?.name) ||
|
||||
'UNKNOWN',
|
||||
[market, TOKEN_MINTS]
|
||||
)
|
||||
|
||||
return {
|
||||
market,
|
||||
marketAddress,
|
||||
programId,
|
||||
marketList,
|
||||
baseCurrency,
|
||||
quoteCurrency,
|
||||
}
|
||||
}
|
||||
|
||||
export default useMarkets
|
|
@ -1,7 +1,7 @@
|
|||
import { useEffect, useMemo } from 'react'
|
||||
import { PublicKey, AccountInfo } from '@solana/web3.js'
|
||||
import { Orderbook } from '@project-serum/serum'
|
||||
import useMarkets from './useMarkets'
|
||||
import useMarket from './useMarket'
|
||||
import useInterval from './useInterval'
|
||||
import useMangoStore from '../stores/useMangoStore'
|
||||
import useConnection from './useConnection'
|
||||
|
@ -69,7 +69,7 @@ export default function useOrderbook(
|
|||
depth = 20
|
||||
): [{ bids: number[][]; asks: number[][] }, boolean] {
|
||||
const { bidOrderbook, askOrderbook } = useOrderbookAccounts()
|
||||
const { market } = useMarkets()
|
||||
const { market } = useMarket()
|
||||
|
||||
const setMangoStore = useMangoStore((s) => s.set)
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
"@blockworks-foundation/mango-client": "^0.1.10",
|
||||
"@emotion/react": "^11.1.5",
|
||||
"@emotion/styled": "^11.1.5",
|
||||
"@headlessui/react": "^0.3.2",
|
||||
"@heroicons/react": "^1.0.0",
|
||||
"@project-serum/serum": "^0.13.31",
|
||||
"@project-serum/sol-wallet-adapter": "^0.1.8",
|
||||
|
|
|
@ -2,12 +2,17 @@ import xw from 'xwind'
|
|||
import TopBar from '../components/TopBar'
|
||||
import Notifications from '../components/Notification'
|
||||
import TradePageGrid from '../components/TradePageGrid'
|
||||
import MarketSelect from '../components/MarketSelect'
|
||||
import useHydrateStore from '../hooks/useHydrateStore'
|
||||
|
||||
const Index = () => {
|
||||
useHydrateStore()
|
||||
|
||||
return (
|
||||
<div css={xw`bg-mango-dark text-white`}>
|
||||
<TopBar />
|
||||
<div css={xw`min-h-screen p-1 sm:p-2 md:p-6`}>
|
||||
<div css={xw`min-h-screen p-1 sm:p-2 md:p-6 md:pt-4`}>
|
||||
<MarketSelect />
|
||||
<TradePageGrid />
|
||||
</div>
|
||||
<Notifications
|
||||
|
|
|
@ -3,6 +3,7 @@ import { devtools } from 'zustand/middleware'
|
|||
import produce from 'immer'
|
||||
import { Market } from '@project-serum/serum'
|
||||
import {
|
||||
IDS,
|
||||
MangoClient,
|
||||
MangoGroup,
|
||||
MarginAccount,
|
||||
|
@ -27,6 +28,7 @@ export const ENDPOINTS: EndpointInfo[] = [
|
|||
const CLUSTER = 'mainnet-beta'
|
||||
const ENDPOINT_URL = ENDPOINTS.find((e) => e.name === CLUSTER).endpoint
|
||||
const DEFAULT_CONNECTION = new Connection(ENDPOINT_URL, 'recent')
|
||||
const DEFAULT_MANGO_GROUP = 'BTC_ETH_USDT'
|
||||
|
||||
interface AccountInfoList {
|
||||
[key: string]: AccountInfo<Buffer>
|
||||
|
@ -40,11 +42,15 @@ interface MangoStore extends State {
|
|||
endpoint: string
|
||||
}
|
||||
market: {
|
||||
programId: number | null
|
||||
current: Market | null
|
||||
mangoProgramId: number | null
|
||||
markPrice: number
|
||||
orderBook: any[]
|
||||
}
|
||||
selectedMarket: {
|
||||
name: string
|
||||
address: string
|
||||
}
|
||||
mangoClient: MangoClient
|
||||
mangoGroups: Array<MangoGroup>
|
||||
selectedMangoGroup: {
|
||||
|
@ -74,17 +80,24 @@ const useMangoStore = create<MangoStore>(
|
|||
endpoint: ENDPOINT_URL,
|
||||
},
|
||||
selectedMangoGroup: {
|
||||
name: 'BTC_ETH_USDT',
|
||||
name: DEFAULT_MANGO_GROUP,
|
||||
current: null,
|
||||
},
|
||||
selectedMarket: {
|
||||
name: Object.entries(
|
||||
IDS[CLUSTER].mango_groups[DEFAULT_MANGO_GROUP].spot_market_symbols
|
||||
)[0][0],
|
||||
address: Object.entries(
|
||||
IDS[CLUSTER].mango_groups[DEFAULT_MANGO_GROUP].spot_market_symbols
|
||||
)[0][1],
|
||||
},
|
||||
market: {
|
||||
programId: null,
|
||||
current: null,
|
||||
mangoProgramId: null,
|
||||
markPrice: 0,
|
||||
orderBook: [],
|
||||
},
|
||||
mangoClient: new MangoClient(),
|
||||
mangoGroup: null,
|
||||
mangoGroups: [],
|
||||
marginAccounts: [],
|
||||
selectedMarginAccount: {
|
||||
|
|
|
@ -1153,6 +1153,11 @@
|
|||
resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.1.1.tgz#9daf5745156fd84b8e9889a2dc721f0c58e894aa"
|
||||
integrity sha512-CAEbWH7OIur6jEOzaai83jq3FmKmv4PmX1JYfs9IrYcGEVI/lyL1EXJGCj7eFVJ0bg5QR8LMxBlEtA+xKiLpFw==
|
||||
|
||||
"@headlessui/react@^0.3.2":
|
||||
version "0.3.2"
|
||||
resolved "https://registry.yarnpkg.com/@headlessui/react/-/react-0.3.2.tgz#fa8600fa669fe704b84e9256855fb39092b6e233"
|
||||
integrity sha512-N8XpYJNEP1jH5V8qq2cX8pnipOd93UJNKky1B7Ac3/yFFehB/0C4k5kOHt8ShHsmcohrZUB4sOl4+m0CjQpXng==
|
||||
|
||||
"@heroicons/react@^1.0.0":
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@heroicons/react/-/react-1.0.0.tgz#16a6147f665434b68f401f050a6cb1d68cf819bc"
|
||||
|
|
Loading…
Reference in New Issue