From c1269298b92a96ec391b74e1d372dd1034a94a92 Mon Sep 17 00:00:00 2001 From: Tyler Shipe Date: Mon, 13 Sep 2021 17:14:59 -0400 Subject: [PATCH] use custom endpoint url --- components/AccountInfo.tsx | 3 +- components/AccountNameModal.tsx | 3 +- components/BalancesTable.tsx | 3 +- components/ConnectWalletButton.tsx | 17 ++++++++ components/Input.tsx | 8 ++-- components/MarketCloseModal.tsx | 9 ++-- components/MarketPosition.tsx | 3 +- components/OpenOrdersTable.tsx | 3 +- components/SettingsModal.tsx | 48 +++++++++++++++++++++ components/TradeForm.tsx | 4 +- components/account-page/AccountAssets.tsx | 4 +- hooks/useHydrateStore.tsx | 11 ++--- hooks/useSrmAccount.tsx | 5 ++- stores/useMangoStore.tsx | 51 +++++++++++++++-------- utils/mango.tsx | 4 +- 15 files changed, 134 insertions(+), 42 deletions(-) create mode 100644 components/SettingsModal.tsx diff --git a/components/AccountInfo.tsx b/components/AccountInfo.tsx index 463d3f4a..2c898b9d 100644 --- a/components/AccountInfo.tsx +++ b/components/AccountInfo.tsx @@ -8,7 +8,7 @@ import { } from '@blockworks-foundation/mango-client' import { useCallback, useState } from 'react' import { HeartIcon } from '@heroicons/react/solid' -import useMangoStore, { mangoClient, MNGO_INDEX } from '../stores/useMangoStore' +import useMangoStore, { MNGO_INDEX } from '../stores/useMangoStore' import { formatUsdValue, usdFormatter } from '../utils' import { notify } from '../utils/notifications' import { LinkButton } from './Button' @@ -29,6 +29,7 @@ export default function AccountInfo() { const mangoAccount = useMangoStore((s) => s.selectedMangoAccount.current) const isLoading = useMangoStore((s) => s.selectedMangoAccount.initialLoad) const marketConfig = useMangoStore((s) => s.selectedMarket.config) + const mangoClient = useMangoStore((s) => s.connection.client) const actions = useMangoStore((s) => s.actions) const [showDepositModal, setShowDepositModal] = useState(false) diff --git a/components/AccountNameModal.tsx b/components/AccountNameModal.tsx index de8fa5c0..f8b9df3b 100644 --- a/components/AccountNameModal.tsx +++ b/components/AccountNameModal.tsx @@ -1,5 +1,5 @@ import { FunctionComponent, useState } from 'react' -import useMangoStore, { mangoClient } from '../stores/useMangoStore' +import useMangoStore from '../stores/useMangoStore' import { ExclamationCircleIcon, InformationCircleIcon, @@ -26,6 +26,7 @@ const AccountNameModal: FunctionComponent = ({ const [invalidNameMessage, setInvalidNameMessage] = useState('') const mangoGroup = useMangoStore((s) => s.selectedMangoGroup.current) const mangoAccount = useMangoStore((s) => s.selectedMangoAccount.current) + const mangoClient = useMangoStore((s) => s.connection.client) const actions = useMangoStore((s) => s.actions) const submitName = async () => { diff --git a/components/BalancesTable.tsx b/components/BalancesTable.tsx index d7dc7ec3..63e274a0 100644 --- a/components/BalancesTable.tsx +++ b/components/BalancesTable.tsx @@ -1,6 +1,6 @@ import { useCallback } from 'react' import { useBalances } from '../hooks/useBalances' -import useMangoStore, { mangoClient } from '../stores/useMangoStore' +import useMangoStore from '../stores/useMangoStore' import Button, { LinkButton } from '../components/Button' import { notify } from '../utils/notifications' import { ArrowSmDownIcon, ExclamationIcon } from '@heroicons/react/outline' @@ -38,6 +38,7 @@ const BalancesTable = ({ showZeroBalances = false }) => { const actions = useMangoStore((s) => s.actions) const mangoGroup = useMangoStore((s) => s.selectedMangoGroup.current) const mangoGroupConfig = useMangoStore((s) => s.selectedMangoGroup.config) + const mangoClient = useMangoStore((s) => s.connection.client) const { width } = useViewport() const [submitting, setSubmitting] = useState(false) const isMobile = width ? width < breakpoints.md : false diff --git a/components/ConnectWalletButton.tsx b/components/ConnectWalletButton.tsx index eecaa5dc..41d3e926 100644 --- a/components/ConnectWalletButton.tsx +++ b/components/ConnectWalletButton.tsx @@ -17,12 +17,14 @@ import WalletSelect from './WalletSelect' import { WalletIcon, ProfileIcon } from './icons' import AccountsModal from './AccountsModal' import { useEffect } from 'react' +import SettingsModal from './SettingsModal' const ConnectWalletButton = () => { const wallet = useMangoStore((s) => s.wallet.current) const connected = useMangoStore((s) => s.wallet.connected) const set = useMangoStore((s) => s.set) const [showAccountsModal, setShowAccountsModal] = useState(false) + const [showSettingsModal, setShowSettingsModal] = useState(false) const [selectedWallet, setSelectedWallet] = useState(DEFAULT_PROVIDER.url) const [savedProviderUrl] = useLocalStorageState( PROVIDER_LOCAL_STORAGE_KEY, @@ -63,6 +65,15 @@ const ConnectWalletButton = () => {
Accounts
+ + + + + + + ) +} + +export default React.memo(SettingsModal) diff --git a/components/TradeForm.tsx b/components/TradeForm.tsx index 33debd77..526e4a35 100644 --- a/components/TradeForm.tsx +++ b/components/TradeForm.tsx @@ -9,7 +9,7 @@ import { notify } from '../utils/notifications' import { calculateTradePrice, getDecimalCount, sleep } from '../utils' import FloatingElement from './FloatingElement' import { floorToDecimal } from '../utils/index' -import useMangoStore, { mangoClient } from '../stores/useMangoStore' +import useMangoStore from '../stores/useMangoStore' import Button from './Button' import TradeType from './TradeType' import Input from './Input' @@ -32,6 +32,7 @@ export default function TradeForm() { const groupConfig = useMangoStore((s) => s.selectedMangoGroup.config) const marketConfig = useMangoStore((s) => s.selectedMarket.config) const mangoAccount = useMangoStore((s) => s.selectedMangoAccount.current) + const mangoClient = useMangoStore((s) => s.connection.client) const market = useMangoStore((s) => s.selectedMarket.current) const { side, baseSize, quoteSize, price, tradeType } = useMangoStore( (s) => s.tradeForm @@ -373,6 +374,7 @@ export default function TradeForm() { value={baseSize} className="rounded-r-none" wrapperClassName="w-3/5" + prefixClassName="w-12" prefix={'Size'} suffix={marketConfig.baseSymbol} /> diff --git a/components/account-page/AccountAssets.tsx b/components/account-page/AccountAssets.tsx index 81f6d2e5..58694c64 100644 --- a/components/account-page/AccountAssets.tsx +++ b/components/account-page/AccountAssets.tsx @@ -1,8 +1,7 @@ import { useCallback, useState } from 'react' import { Table, Thead, Tbody, Tr, Th, Td } from 'react-super-responsive-table' import { InformationCircleIcon } from '@heroicons/react/outline' -import useMangoStore, { mangoClient } from '../../stores/useMangoStore' -// import { settleAllTrades } from '../../utils/mango' +import useMangoStore from '../../stores/useMangoStore' import { useBalances } from '../../hooks/useBalances' import { tokenPrecision } from '../../utils/index' import DepositModal from '../DepositModal' @@ -24,6 +23,7 @@ export default function AccountAssets() { const mangoCache = useMangoStore((s) => s.selectedMangoGroup.cache) const groupConfig = useMangoStore((s) => s.selectedMangoGroup.config) const mangoAccount = useMangoStore((s) => s.selectedMangoAccount.current) + const mangoClient = useMangoStore((s) => s.connection.client) const loadingMangoAccount = useMangoStore( (s) => s.selectedMangoAccount.initialLoad ) diff --git a/hooks/useHydrateStore.tsx b/hooks/useHydrateStore.tsx index 331843af..a9280cd4 100644 --- a/hooks/useHydrateStore.tsx +++ b/hooks/useHydrateStore.tsx @@ -1,6 +1,6 @@ import { useEffect } from 'react' import { AccountInfo } from '@solana/web3.js' -import useMangoStore, { WEBSOCKET_CONNECTION } from '../stores/useMangoStore' +import useMangoStore from '../stores/useMangoStore' import useInterval from './useInterval' import useOrderbook from './useOrderbook' @@ -13,6 +13,7 @@ const useHydrateStore = () => { const markets = useMangoStore((s) => s.selectedMangoGroup.markets) const marketConfig = useMangoStore((s) => s.selectedMarket.config) const selectedMarket = useMangoStore((s) => s.selectedMarket.current) + const connection = useMangoStore((s) => s.connection.current) useOrderbook() useEffect(() => { @@ -39,7 +40,7 @@ const useHydrateStore = () => { let previousAskInfo: AccountInfo | null = null if (!marketConfig) return - const bidSubscriptionId = WEBSOCKET_CONNECTION.onAccountChange( + const bidSubscriptionId = connection.onAccountChange( marketConfig.bidsKey, (info, context) => { const lastSlot = useMangoStore.getState().connection.slot @@ -57,7 +58,7 @@ const useHydrateStore = () => { } } ) - const askSubscriptionId = WEBSOCKET_CONNECTION.onAccountChange( + const askSubscriptionId = connection.onAccountChange( marketConfig.asksKey, (info, context) => { const lastSlot = useMangoStore.getState().connection.slot @@ -77,8 +78,8 @@ const useHydrateStore = () => { ) return () => { - WEBSOCKET_CONNECTION.removeAccountChangeListener(bidSubscriptionId) - WEBSOCKET_CONNECTION.removeAccountChangeListener(askSubscriptionId) + connection.removeAccountChangeListener(bidSubscriptionId) + connection.removeAccountChangeListener(askSubscriptionId) } }, [selectedMarket]) diff --git a/hooks/useSrmAccount.tsx b/hooks/useSrmAccount.tsx index 268f380a..f9ef8678 100644 --- a/hooks/useSrmAccount.tsx +++ b/hooks/useSrmAccount.tsx @@ -1,5 +1,5 @@ import { useState } from 'react' -import useMangoStore, { DEFAULT_CONNECTION } from '../stores/useMangoStore' +import useMangoStore from '../stores/useMangoStore' import { nativeToUi } from '@blockworks-foundation/mango-client' import { SRM_DECIMALS } from '@project-serum/serum/lib/token-instructions' import { getFeeTier, getFeeRates } from '@project-serum/serum' @@ -8,6 +8,7 @@ import { useEffect } from 'react' const useSrmAccount = () => { const mangoGroup = useMangoStore((s) => s.selectedMangoGroup.current) + const connection = useMangoStore((s) => s.connection.current) const [srmAccount, setSrmAccount] = useState(null) // const [msrmAccount, setMsrmAccount] = useState(null) @@ -15,7 +16,7 @@ const useSrmAccount = () => { if (mangoGroup) { const srmPk = mangoGroup.srmVault const fetchAccounts = async () => { - const srmAccountInfo = await DEFAULT_CONNECTION.getAccountInfo(srmPk) + const srmAccountInfo = await connection.getAccountInfo(srmPk) setSrmAccount(srmAccountInfo) } diff --git a/stores/useMangoStore.tsx b/stores/useMangoStore.tsx index eea19710..d9a68c42 100644 --- a/stores/useMangoStore.tsx +++ b/stores/useMangoStore.tsx @@ -73,8 +73,6 @@ export const programId = new PublicKey(defaultMangoGroupIds.mangoProgramId) export const serumProgramId = new PublicKey(defaultMangoGroupIds.serumProgramId) const mangoGroupPk = new PublicKey(defaultMangoGroupIds.publicKey) -export const mangoClient = new MangoClient(DEFAULT_CONNECTION, programId) - export const INITIAL_STATE = { WALLET: { providerUrl: null, @@ -115,6 +113,7 @@ interface MangoStore extends State { current: Connection websocket: Connection endpoint: string + client: MangoClient slot: number } selectedMarket: { @@ -172,6 +171,7 @@ const useMangoStore = create((set, get) => ({ cluster: CLUSTER, current: DEFAULT_CONNECTION, websocket: WEBSOCKET_CONNECTION, + client: new MangoClient(DEFAULT_CONNECTION, programId), endpoint: ENDPOINT.url, slot: 0, }, @@ -221,11 +221,12 @@ const useMangoStore = create((set, get) => ({ const groupConfig = get().selectedMangoGroup.config const wallet = get().wallet.current const connected = get().wallet.connected + const connection = get().connection.current const set = get().set if (wallet?.publicKey && connected) { const ownedTokenAccounts = await getTokenAccountsByOwnerWithWrappedSol( - DEFAULT_CONNECTION, + connection, wallet.publicKey ) const tokens = [] @@ -249,6 +250,7 @@ const useMangoStore = create((set, get) => ({ async fetchMangoAccounts() { const set = get().set const mangoGroup = get().selectedMangoGroup.current + const mangoClient = get().connection.client const wallet = get().wallet.current const walletPk = wallet?.publicKey @@ -299,6 +301,8 @@ const useMangoStore = create((set, get) => ({ const set = get().set const mangoGroupConfig = get().selectedMangoGroup.config const selectedMarketConfig = get().selectedMarket.config + const mangoClient = get().connection.client + const connection = get().connection.current return mangoClient .getMangoGroup(mangoGroupPk) @@ -309,9 +313,9 @@ const useMangoStore = create((set, get) => ({ let allMarketAccountInfos, mangoCache try { const resp = await Promise.all([ - getMultipleAccounts(DEFAULT_CONNECTION, allMarketPks), - mangoGroup.loadCache(DEFAULT_CONNECTION), - mangoGroup.loadRootBanks(DEFAULT_CONNECTION), + getMultipleAccounts(connection, allMarketPks), + mangoGroup.loadCache(connection), + mangoGroup.loadRootBanks(connection), ]) allMarketAccountInfos = resp[0] mangoCache = resp[1] @@ -352,7 +356,7 @@ const useMangoStore = create((set, get) => ({ .map((m) => [m.bidsKey, m.asksKey]) .flat() const allBidsAndAsksAccountInfos = await getMultipleAccounts( - DEFAULT_CONNECTION, + connection, allBidsAndAsksPks ) @@ -421,12 +425,10 @@ const useMangoStore = create((set, get) => ({ async reloadMangoAccount() { const set = get().set const mangoAccount = get().selectedMangoAccount.current + const connection = get().connection.current const [reloadedMangoAccount, reloadedOpenOrders] = await Promise.all([ - mangoAccount.reload(DEFAULT_CONNECTION), - mangoAccount.loadOpenOrders( - DEFAULT_CONNECTION, - new PublicKey(serumProgramId) - ), + mangoAccount.reload(connection), + mangoAccount.loadOpenOrders(connection, new PublicKey(serumProgramId)), ]) reloadedMangoAccount.spotOpenOrdersAccounts = reloadedOpenOrders @@ -436,12 +438,13 @@ const useMangoStore = create((set, get) => ({ }, async updateOpenOrders() { const set = get().set + const connection = get().connection.current const bidAskAccounts = Object.keys(get().accountInfos).map( (pk) => new PublicKey(pk) ) const allBidsAndAsksAccountInfos = await getMultipleAccounts( - DEFAULT_CONNECTION, + connection, bidAskAccounts ) @@ -457,14 +460,12 @@ const useMangoStore = create((set, get) => ({ async loadMarketFills() { const set = get().set const selectedMarket = get().selectedMarket.current + const connection = get().connection.current if (!selectedMarket) { return null } try { - const loadedFills = await selectedMarket.loadFills( - DEFAULT_CONNECTION, - 10000 - ) + const loadedFills = await selectedMarket.loadFills(connection, 10000) set((state) => { state.selectedMarket.fills = loadedFills }) @@ -475,14 +476,28 @@ const useMangoStore = create((set, get) => ({ async fetchMangoGroupCache() { const set = get().set const mangoGroup = get().selectedMangoGroup.current + const connection = get().connection.current if (mangoGroup) { - const mangoCache = await mangoGroup.loadCache(DEFAULT_CONNECTION) + const mangoCache = await mangoGroup.loadCache(connection) set((state) => { state.selectedMangoGroup.cache = mangoCache }) } }, + async updateConnection(endpointUrl) { + const set = get().set + + const newConnection = new Connection(endpointUrl, 'processed') + + const newClient = new MangoClient(newConnection, programId) + + set((state) => { + state.connection.endpoint = endpointUrl + state.connection.current = newConnection + state.connection.client = newClient + }) + }, }, })) diff --git a/utils/mango.tsx b/utils/mango.tsx index 4dec0fd3..ca74961a 100644 --- a/utils/mango.tsx +++ b/utils/mango.tsx @@ -1,6 +1,6 @@ import { MangoAccount, TokenAccount } from '@blockworks-foundation/mango-client' import { PublicKey } from '@solana/web3.js' -import useMangoStore, { mangoClient } from '../stores/useMangoStore' +import useMangoStore from '../stores/useMangoStore' export async function deposit({ amount, @@ -16,6 +16,7 @@ export async function deposit({ const mangoGroup = useMangoStore.getState().selectedMangoGroup.current const wallet = useMangoStore.getState().wallet.current const tokenIndex = mangoGroup.getTokenIndex(fromTokenAcc.mint) + const mangoClient = useMangoStore.getState().connection.client if (mangoAccount) { return await mangoClient.deposit( @@ -55,6 +56,7 @@ export async function withdraw({ const mangoGroup = useMangoStore.getState().selectedMangoGroup.current const wallet = useMangoStore.getState().wallet.current const tokenIndex = mangoGroup.getTokenIndex(token) + const mangoClient = useMangoStore.getState().connection.client return await mangoClient.withdraw( mangoGroup,