Merge branch 'main' into alpha
This commit is contained in:
commit
ad79ce2695
|
@ -41,6 +41,7 @@ const Input = forwardRef<HTMLInputElement, InputProps>((props, ref) => {
|
|||
</div>
|
||||
) : null}
|
||||
<input
|
||||
{...props}
|
||||
className={`${className} default-transition h-12 w-full flex-1 rounded-md border bg-th-input-bkg px-3 text-base
|
||||
text-th-fgd-1 ${
|
||||
error ? 'border-th-down' : 'border-th-input-border'
|
||||
|
@ -55,7 +56,6 @@ const Input = forwardRef<HTMLInputElement, InputProps>((props, ref) => {
|
|||
${suffix ? 'pr-11' : ''}`}
|
||||
disabled={disabled}
|
||||
ref={ref}
|
||||
{...props}
|
||||
type={type}
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
import ButtonGroup from '@components/forms/ButtonGroup'
|
||||
import Input from '@components/forms/Input'
|
||||
import Button from '@components/shared/Button'
|
||||
import mangoStore from '@store/mangoStore'
|
||||
import useLocalStorageState from 'hooks/useLocalStorageState'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import { ChangeEvent, useEffect, useState } from 'react'
|
||||
import { RPC_PROVIDER_KEY } from 'utils/constants'
|
||||
|
||||
const RPC_URLS = [
|
||||
{
|
||||
label: 'Triton',
|
||||
value: 'https://mango.rpcpool.com/0f9acc0d45173b51bf7d7e09c1e5',
|
||||
},
|
||||
// {
|
||||
// label: 'Genesys Go',
|
||||
// value: 'https://mango.genesysgo.net',
|
||||
// },
|
||||
{ label: 'Custom', value: '' },
|
||||
]
|
||||
|
||||
const RpcSettings = () => {
|
||||
const { t } = useTranslation('settings')
|
||||
const actions = mangoStore((s) => s.actions)
|
||||
const [customUrl, setCustomUrl] = useState('')
|
||||
const [showCustomForm, setShowCustomForm] = useState(false)
|
||||
const [rpcEndpointProvider, setRpcEndpointProvider] = useLocalStorageState(
|
||||
RPC_PROVIDER_KEY,
|
||||
RPC_URLS[0].value
|
||||
)
|
||||
const rpcEndpoint =
|
||||
RPC_URLS.find((node) => node.label === rpcEndpointProvider.label) ||
|
||||
RPC_URLS[0]
|
||||
|
||||
const handleSetEndpointProvider = (provider: string) => {
|
||||
const endpointProvider =
|
||||
RPC_URLS.find((node) => node.label === provider) || RPC_URLS[0]
|
||||
setRpcEndpointProvider(endpointProvider.value)
|
||||
if (provider !== 'Custom') {
|
||||
setShowCustomForm(false)
|
||||
actions.updateConnection(endpointProvider.value)
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (rpcEndpointProvider.label === 'Custom') {
|
||||
setShowCustomForm(true)
|
||||
setCustomUrl(rpcEndpointProvider.value)
|
||||
}
|
||||
}, [rpcEndpointProvider])
|
||||
|
||||
const handleSaveCustomEndpoint = () => {
|
||||
if (!customUrl) return
|
||||
const provider = { label: 'Custom', value: customUrl }
|
||||
setRpcEndpointProvider(provider)
|
||||
actions.updateConnection(customUrl)
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<h2 className="mb-4 text-base">{t('rpc')}</h2>
|
||||
<div className="flex flex-col border-t border-th-bkg-3 py-4 md:flex-row md:items-center md:justify-between md:px-4">
|
||||
<p className="mb-2 md:mb-0">{t('rpc-provider')}</p>
|
||||
<div className="w-full min-w-[240px] md:w-[340px] md:pl-4">
|
||||
<ButtonGroup
|
||||
activeValue={rpcEndpoint.label}
|
||||
onChange={(v) => handleSetEndpointProvider(v)}
|
||||
values={RPC_URLS.map((val) => val.label)}
|
||||
/>
|
||||
{showCustomForm ? (
|
||||
<div className="mt-2">
|
||||
<div className="flex space-x-2">
|
||||
<Input
|
||||
type="text"
|
||||
name="url"
|
||||
id="url"
|
||||
className="!h-10"
|
||||
placeholder={t('rpc-url')}
|
||||
value={customUrl}
|
||||
onChange={(e: ChangeEvent<HTMLInputElement>) =>
|
||||
setCustomUrl(e.target.value)
|
||||
}
|
||||
/>
|
||||
<Button
|
||||
className="h-12"
|
||||
disabled={!customUrl}
|
||||
onClick={handleSaveCustomEndpoint}
|
||||
>
|
||||
{t('save')}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default RpcSettings
|
|
@ -1,12 +1,16 @@
|
|||
import AnimationSettings from './AnimationSettings'
|
||||
import DisplaySettings from './DisplaySettings'
|
||||
import PreferredExplorerSettings from './PreferredExplorerSettings'
|
||||
import RpcSettings from './RpcSettings'
|
||||
import SoundSettings from './SoundSettings'
|
||||
|
||||
const SettingsPage = () => {
|
||||
return (
|
||||
<div className="grid grid-cols-12">
|
||||
<div className="col-span-12 border-b border-th-bkg-3 lg:col-span-8 lg:col-start-3">
|
||||
<RpcSettings />
|
||||
</div>
|
||||
<div className="col-span-12 border-b border-th-bkg-3 pt-8 lg:col-span-8 lg:col-start-3">
|
||||
<DisplaySettings />
|
||||
</div>
|
||||
<div className="col-span-12 border-b border-th-bkg-3 pt-8 lg:col-span-8 lg:col-start-3">
|
||||
|
|
|
@ -25,7 +25,11 @@
|
|||
"orderbook-flash": "Orderbook Flash",
|
||||
"preferred-explorer": "Preferred Explorer",
|
||||
"recent-trades": "Recent Trades",
|
||||
"rpc": "RPC",
|
||||
"rpc-provider": "RPC Provider",
|
||||
"rpc-url": "Enter RPC URL",
|
||||
"russian": "Русский",
|
||||
"save": "Save",
|
||||
"slider": "Slider",
|
||||
"solana-beach": "Solana Beach",
|
||||
"solana-explorer": "Solana Explorer",
|
||||
|
|
|
@ -25,7 +25,11 @@
|
|||
"orderbook-flash": "Orderbook Flash",
|
||||
"preferred-explorer": "Preferred Explorer",
|
||||
"recent-trades": "Recent Trades",
|
||||
"rpc": "RPC",
|
||||
"rpc-provider": "RPC Provider",
|
||||
"rpc-url": "Enter RPC URL",
|
||||
"russian": "Русский",
|
||||
"save": "Save",
|
||||
"slider": "Slider",
|
||||
"solana-beach": "Solana Beach",
|
||||
"solana-explorer": "Solana Explorer",
|
||||
|
|
|
@ -25,7 +25,11 @@
|
|||
"orderbook-flash": "Orderbook Flash",
|
||||
"preferred-explorer": "Preferred Explorer",
|
||||
"recent-trades": "Recent Trades",
|
||||
"rpc": "RPC",
|
||||
"rpc-provider": "RPC Provider",
|
||||
"rpc-url": "Enter RPC URL",
|
||||
"russian": "Русский",
|
||||
"save": "Save",
|
||||
"slider": "Slider",
|
||||
"solana-beach": "Solana Beach",
|
||||
"solana-explorer": "Solana Explorer",
|
||||
|
|
|
@ -25,7 +25,11 @@
|
|||
"orderbook-flash": "Orderbook Flash",
|
||||
"preferred-explorer": "Preferred Explorer",
|
||||
"recent-trades": "Recent Trades",
|
||||
"rpc": "RPC",
|
||||
"rpc-provider": "RPC Provider",
|
||||
"rpc-url": "Enter RPC URL",
|
||||
"russian": "Русский",
|
||||
"save": "Save",
|
||||
"slider": "Slider",
|
||||
"solana-beach": "Solana Beach",
|
||||
"solana-explorer": "Solana Explorer",
|
||||
|
|
|
@ -25,7 +25,11 @@
|
|||
"orderbook-flash": "Orderbook Flash",
|
||||
"preferred-explorer": "Preferred Explorer",
|
||||
"recent-trades": "Recent Trades",
|
||||
"rpc": "RPC",
|
||||
"rpc-provider": "RPC Provider",
|
||||
"rpc-url": "Enter RPC URL",
|
||||
"russian": "Русский",
|
||||
"save": "Save",
|
||||
"slider": "Slider",
|
||||
"solana-beach": "Solana Beach",
|
||||
"solana-explorer": "Solana Explorer",
|
||||
|
|
|
@ -32,6 +32,7 @@ import {
|
|||
INPUT_TOKEN_DEFAULT,
|
||||
LAST_ACCOUNT_KEY,
|
||||
OUTPUT_TOKEN_DEFAULT,
|
||||
RPC_PROVIDER_KEY,
|
||||
} from '../utils/constants'
|
||||
import { OrderbookL2, SpotBalances } from 'types'
|
||||
import spotBalancesUpdater from './spotBalancesUpdater'
|
||||
|
@ -40,24 +41,45 @@ import perpPositionsUpdater from './perpPositionsUpdater'
|
|||
|
||||
const GROUP = new PublicKey('78b8f4cGCwmZ9ysPFMWLaLTkkaYnUjwMJYStWe5RTSSX')
|
||||
|
||||
export const connection = new web3.Connection(
|
||||
process.env.NEXT_PUBLIC_ENDPOINT ||
|
||||
'https://mango.rpcpool.com/0f9acc0d45173b51bf7d7e09c1e5',
|
||||
'processed'
|
||||
)
|
||||
const ENDPOINTS = [
|
||||
{
|
||||
name: 'mainnet-beta',
|
||||
url:
|
||||
process.env.NEXT_PUBLIC_ENDPOINT ||
|
||||
'https://mango.rpcpool.com/0f9acc0d45173b51bf7d7e09c1e5',
|
||||
websocket:
|
||||
process.env.NEXT_PUBLIC_ENDPOINT ||
|
||||
'https://mango.rpcpool.com/0f9acc0d45173b51bf7d7e09c1e5',
|
||||
custom: false,
|
||||
},
|
||||
{
|
||||
name: 'devnet',
|
||||
url: 'https://mango.devnet.rpcpool.com',
|
||||
websocket: 'https://mango.devnet.rpcpool.com',
|
||||
custom: false,
|
||||
},
|
||||
]
|
||||
|
||||
const options = AnchorProvider.defaultOptions()
|
||||
export const CLUSTER: 'mainnet-beta' | 'devnet' = 'mainnet-beta'
|
||||
const wallet = new EmptyWallet(Keypair.generate())
|
||||
const DEFAULT_PROVIDER = new AnchorProvider(connection, wallet, options)
|
||||
DEFAULT_PROVIDER.opts.skipPreflight = true
|
||||
const DEFAULT_CLIENT = MangoClient.connect(
|
||||
DEFAULT_PROVIDER,
|
||||
CLUSTER,
|
||||
MANGO_V4_ID[CLUSTER],
|
||||
{
|
||||
const ENDPOINT = ENDPOINTS.find((e) => e.name === CLUSTER) || ENDPOINTS[0]
|
||||
const emptyWallet = new EmptyWallet(Keypair.generate())
|
||||
|
||||
const initMangoClient = (provider: AnchorProvider): MangoClient => {
|
||||
return MangoClient.connect(provider, CLUSTER, MANGO_V4_ID[CLUSTER], {
|
||||
// blockhashCommitment: 'confirmed',
|
||||
idsSource: 'get-program-accounts',
|
||||
}
|
||||
)
|
||||
prioritizationFee: 2,
|
||||
postSendTxCallback: ({ txid }: { txid: string }) => {
|
||||
notify({
|
||||
title: 'Transaction sent',
|
||||
description: 'Waiting for confirmation',
|
||||
type: 'confirm',
|
||||
txid: txid,
|
||||
})
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
export interface TotalInterestDataItem {
|
||||
borrow_interest: number
|
||||
|
@ -296,13 +318,27 @@ export type MangoStore = {
|
|||
fetchTourSettings: (walletPk: string) => void
|
||||
fetchWalletTokens: (wallet: Wallet) => Promise<void>
|
||||
connectMangoClientWithWallet: (wallet: WalletAdapter) => Promise<void>
|
||||
reloadGroup: () => Promise<void>
|
||||
loadMarketFills: () => Promise<void>
|
||||
updateConnection: (url: string) => void
|
||||
}
|
||||
}
|
||||
|
||||
const mangoStore = create<MangoStore>()(
|
||||
subscribeWithSelector((_set, get) => {
|
||||
let rpcUrl = ENDPOINT?.url
|
||||
|
||||
if (typeof window !== 'undefined' && CLUSTER === 'mainnet-beta') {
|
||||
const urlFromLocalStorage = localStorage.getItem(RPC_PROVIDER_KEY)
|
||||
rpcUrl = urlFromLocalStorage
|
||||
? JSON.parse(urlFromLocalStorage).value
|
||||
: ENDPOINT?.url
|
||||
}
|
||||
|
||||
const connection = new web3.Connection(rpcUrl, 'processed')
|
||||
const provider = new AnchorProvider(connection, emptyWallet, options)
|
||||
provider.opts.skipPreflight = true
|
||||
const client = initMangoClient(provider)
|
||||
|
||||
return {
|
||||
activityFeed: {
|
||||
feed: [],
|
||||
|
@ -313,7 +349,7 @@ const mangoStore = create<MangoStore>()(
|
|||
connection,
|
||||
group: undefined,
|
||||
groupLoaded: false,
|
||||
client: DEFAULT_CLIENT,
|
||||
client,
|
||||
mangoAccount: {
|
||||
current: undefined,
|
||||
initialLoad: true,
|
||||
|
@ -530,6 +566,11 @@ const mangoStore = create<MangoStore>()(
|
|||
try {
|
||||
const set = get().set
|
||||
const client = get().client
|
||||
console.log(
|
||||
'fetching group',
|
||||
client.program.provider.connection.rpcEndpoint
|
||||
)
|
||||
|
||||
const group = await client.getGroup(GROUP)
|
||||
const selectedMarketName = get().selectedMarket.name
|
||||
|
||||
|
@ -826,23 +867,8 @@ const mangoStore = create<MangoStore>()(
|
|||
options
|
||||
)
|
||||
provider.opts.skipPreflight = true
|
||||
const client = await MangoClient.connect(
|
||||
provider,
|
||||
CLUSTER,
|
||||
MANGO_V4_ID[CLUSTER],
|
||||
{
|
||||
idsSource: 'get-program-accounts',
|
||||
prioritizationFee: 2,
|
||||
postSendTxCallback: ({ txid }: { txid: string }) => {
|
||||
notify({
|
||||
title: 'Transaction sent',
|
||||
description: 'Waiting for confirmation',
|
||||
type: 'confirm',
|
||||
txid: txid,
|
||||
})
|
||||
},
|
||||
}
|
||||
)
|
||||
const client = initMangoClient(provider)
|
||||
|
||||
set((s) => {
|
||||
s.client = client
|
||||
})
|
||||
|
@ -856,19 +882,6 @@ const mangoStore = create<MangoStore>()(
|
|||
}
|
||||
}
|
||||
},
|
||||
reloadGroup: async () => {
|
||||
try {
|
||||
const set = get().set
|
||||
const client = get().client
|
||||
const group = await client.getGroup(GROUP)
|
||||
|
||||
set((state) => {
|
||||
state.group = group
|
||||
})
|
||||
} catch (e) {
|
||||
console.error('Error fetching group', e)
|
||||
}
|
||||
},
|
||||
async fetchProfileDetails(walletPk: string) {
|
||||
const set = get().set
|
||||
set((state) => {
|
||||
|
@ -946,6 +959,24 @@ const mangoStore = create<MangoStore>()(
|
|||
console.log('Error fetching fills:', err)
|
||||
}
|
||||
},
|
||||
updateConnection(endpointUrl) {
|
||||
const set = get().set
|
||||
const client = mangoStore.getState().client
|
||||
const newConnection = new web3.Connection(endpointUrl, 'processed')
|
||||
const oldProvider = client.program.provider as AnchorProvider
|
||||
const newProvider = new AnchorProvider(
|
||||
newConnection,
|
||||
oldProvider.wallet,
|
||||
options
|
||||
)
|
||||
newProvider.opts.skipPreflight = true
|
||||
const newClient = initMangoClient(newProvider)
|
||||
|
||||
set((state) => {
|
||||
state.connection = newConnection
|
||||
state.client = newClient
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
})
|
||||
|
|
|
@ -34,6 +34,7 @@ export const GRID_LAYOUT_KEY = 'savedLayouts-0.2'
|
|||
export const NOTIFICATION_POSITION_KEY = 'notificationPosition-0.2'
|
||||
|
||||
export const TRADE_CHART_UI_KEY = 'tradeChart-0.2'
|
||||
|
||||
export const FAVORITE_MARKETS_KEY = 'favoriteMarkets-0.2'
|
||||
|
||||
export const THEME_KEY = 'theme-0.1'
|
||||
|
@ -57,6 +58,8 @@ export const DEFAULT_MARKET_NAME = 'SOL/USDC'
|
|||
|
||||
export const MIN_SOL_BALANCE = 0.04
|
||||
|
||||
export const RPC_PROVIDER_KEY = 'rpcProviderKey'
|
||||
|
||||
export const ACCOUNT_ACTION_MODAL_HEIGHT = '478px'
|
||||
|
||||
export const ACCOUNT_ACTION_MODAL_INNER_HEIGHT = '416px'
|
||||
|
|
Loading…
Reference in New Issue