update to latest client and program version
This commit is contained in:
parent
32ca6ff2f5
commit
ae324a6da5
|
@ -10,7 +10,7 @@ import { useTranslation } from 'next-i18next'
|
|||
import { useTheme } from 'next-themes'
|
||||
import Image from 'next/image'
|
||||
import { useRouter } from 'next/router'
|
||||
import { Fragment, useEffect, useMemo, useState } from 'react'
|
||||
import { Fragment, useCallback, useEffect, useMemo, useState } from 'react'
|
||||
import { useViewport } from '../hooks/useViewport'
|
||||
|
||||
import mangoStore from '../store/state'
|
||||
|
@ -53,8 +53,8 @@ const TokenList = () => {
|
|||
}, [coingeckoPrices, actions])
|
||||
|
||||
const banks = useMemo(() => {
|
||||
if (group?.banksMap) {
|
||||
const rawBanks = Array.from(group?.banksMap, ([key, value]) => ({
|
||||
if (group) {
|
||||
const rawBanks = Array.from(group?.banksMapByName, ([key, value]) => ({
|
||||
key,
|
||||
value,
|
||||
}))
|
||||
|
@ -62,17 +62,27 @@ const TokenList = () => {
|
|||
? showZeroBalances
|
||||
? rawBanks.sort(
|
||||
(a, b) =>
|
||||
Math.abs(mangoAccount?.getUi(b.value) * Number(b.value.price)) -
|
||||
Math.abs(mangoAccount?.getUi(a.value) * Number(a.value.price))
|
||||
Math.abs(
|
||||
mangoAccount?.getTokenBalanceUi(b.value[0]) *
|
||||
Number(b.value[0].price)
|
||||
) -
|
||||
Math.abs(
|
||||
mangoAccount?.getTokenBalanceUi(a.value[0]) *
|
||||
Number(a.value[0].price)
|
||||
)
|
||||
)
|
||||
: rawBanks
|
||||
.filter((b) => mangoAccount?.getUi(b.value) !== 0)
|
||||
.filter((b) => mangoAccount?.getTokenBalanceUi(b.value[0]) !== 0)
|
||||
.sort(
|
||||
(a, b) =>
|
||||
Math.abs(
|
||||
mangoAccount?.getUi(b.value) * Number(b.value.price)
|
||||
mangoAccount?.getTokenBalanceUi(b.value[0]) *
|
||||
Number(b.value[0].price)
|
||||
) -
|
||||
Math.abs(mangoAccount?.getUi(a.value) * Number(a.value.price))
|
||||
Math.abs(
|
||||
mangoAccount?.getTokenBalanceUi(a.value[0]) *
|
||||
Number(a.value[0].price)
|
||||
)
|
||||
)
|
||||
: rawBanks
|
||||
}
|
||||
|
@ -116,11 +126,12 @@ const TokenList = () => {
|
|||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{banks.map((bank, index) => {
|
||||
const oraclePrice = bank.value.price
|
||||
{banks.map(({ key, value }, index) => {
|
||||
const bank = value[0]
|
||||
const oraclePrice = bank.price
|
||||
|
||||
const coingeckoData = coingeckoPrices.find(
|
||||
(asset) => asset.symbol === bank.key
|
||||
(asset) => asset.symbol === key
|
||||
)
|
||||
|
||||
const change = coingeckoData
|
||||
|
@ -135,12 +146,12 @@ const TokenList = () => {
|
|||
let logoURI
|
||||
if (jupiterTokens.length) {
|
||||
logoURI = jupiterTokens.find(
|
||||
(t) => t.address === bank.value.mint.toString()
|
||||
(t) => t.address === bank.mint.toString()
|
||||
)!.logoURI
|
||||
}
|
||||
|
||||
const hasInterestEarned = totalInterestData.find(
|
||||
(d) => d.symbol === bank.value.name
|
||||
(d) => d.symbol === bank.name
|
||||
)
|
||||
|
||||
const interestAmount = hasInterestEarned
|
||||
|
@ -154,7 +165,7 @@ const TokenList = () => {
|
|||
: 0.0
|
||||
|
||||
return (
|
||||
<tr key={bank.key}>
|
||||
<tr key={key}>
|
||||
<td className="w-[16.67%]">
|
||||
<div className="flex items-center">
|
||||
<div className="mr-2.5 flex flex-shrink-0 items-center">
|
||||
|
@ -164,7 +175,7 @@ const TokenList = () => {
|
|||
<QuestionMarkCircleIcon className="h-7 w-7 text-th-fgd-3" />
|
||||
)}
|
||||
</div>
|
||||
<p>{bank.value.name}</p>
|
||||
<p>{bank.name}</p>
|
||||
</div>
|
||||
</td>
|
||||
<td className="w-[16.67%]">
|
||||
|
@ -183,12 +194,12 @@ const TokenList = () => {
|
|||
}
|
||||
data={chartData}
|
||||
height={40}
|
||||
name={bank.key}
|
||||
name={key}
|
||||
width={104}
|
||||
xKey="0"
|
||||
yKey="1"
|
||||
/>
|
||||
) : bank.key === 'USDC' || bank.key === 'USDT' ? null : (
|
||||
) : key === 'USDC' || key === 'USDT' ? null : (
|
||||
<p className="mb-0 text-th-fgd-4">{t('unavailable')}</p>
|
||||
)
|
||||
) : (
|
||||
|
@ -198,20 +209,16 @@ const TokenList = () => {
|
|||
<td className="w-[16.67%]">
|
||||
<div className="flex justify-center space-x-2">
|
||||
<p className="text-th-green">
|
||||
{formatDecimal(
|
||||
bank.value.getDepositRate().toNumber(),
|
||||
2,
|
||||
{ fixed: true }
|
||||
)}
|
||||
{formatDecimal(bank.getDepositRate().toNumber(), 2, {
|
||||
fixed: true,
|
||||
})}
|
||||
%
|
||||
</p>
|
||||
<span className="text-th-fgd-4">|</span>
|
||||
<p className="text-th-red">
|
||||
{formatDecimal(
|
||||
bank.value.getBorrowRate().toNumber(),
|
||||
2,
|
||||
{ fixed: true }
|
||||
)}
|
||||
{formatDecimal(bank.getBorrowRate().toNumber(), 2, {
|
||||
fixed: true,
|
||||
})}
|
||||
%
|
||||
</p>
|
||||
</div>
|
||||
|
@ -227,13 +234,13 @@ const TokenList = () => {
|
|||
<td className="w-[16.67%] pt-4 text-right">
|
||||
<p className="px-2">
|
||||
{mangoAccount
|
||||
? formatDecimal(mangoAccount.getUi(bank.value))
|
||||
? formatDecimal(mangoAccount.getTokenBalanceUi(bank))
|
||||
: 0}
|
||||
</p>
|
||||
<p className="px-2 text-sm text-th-fgd-4">
|
||||
{mangoAccount
|
||||
? `${formatFixedDecimals(
|
||||
mangoAccount.getUi(bank.value) *
|
||||
mangoAccount.getTokenBalanceUi(bank) *
|
||||
oraclePrice.toNumber(),
|
||||
true
|
||||
)}`
|
||||
|
@ -242,10 +249,7 @@ const TokenList = () => {
|
|||
</td>
|
||||
<td className="w-[16.67%]">
|
||||
<div className="flex justify-end space-x-2">
|
||||
<ActionsMenu
|
||||
bank={bank.value}
|
||||
mangoAccount={mangoAccount}
|
||||
/>
|
||||
<ActionsMenu bank={bank} mangoAccount={mangoAccount} />
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -255,19 +259,17 @@ const TokenList = () => {
|
|||
</table>
|
||||
) : (
|
||||
<div className="mt-4 space-y-2">
|
||||
{banks.map((bank) => {
|
||||
const oraclePrice = bank.value.price
|
||||
{banks.map(({ key, value }) => {
|
||||
const bank = value[0]
|
||||
const oraclePrice = bank.price
|
||||
let logoURI
|
||||
if (jupiterTokens.length) {
|
||||
logoURI = jupiterTokens.find(
|
||||
(t) => t.address === bank.value.mint.toString()
|
||||
(t) => t.address === bank.mint.toString()
|
||||
)!.logoURI
|
||||
}
|
||||
return (
|
||||
<div
|
||||
key={bank.key}
|
||||
className="rounded-md border border-th-bkg-4 p-4"
|
||||
>
|
||||
<div key={key} className="rounded-md border border-th-bkg-4 p-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center">
|
||||
<div className="mr-2.5 flex flex-shrink-0 items-center">
|
||||
|
@ -278,28 +280,25 @@ const TokenList = () => {
|
|||
)}
|
||||
</div>
|
||||
<div>
|
||||
<p>{bank.value.name}</p>
|
||||
<p>{bank.name}</p>
|
||||
<p className="text-sm">
|
||||
<span className="mr-1 text-th-fgd-4">
|
||||
{t('available')}:
|
||||
</span>
|
||||
{mangoAccount
|
||||
? formatDecimal(mangoAccount.getUi(bank.value))
|
||||
? formatDecimal(mangoAccount.getTokenBalanceUi(bank))
|
||||
: 0}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center space-x-3">
|
||||
<ActionsMenu
|
||||
bank={bank.value}
|
||||
mangoAccount={mangoAccount}
|
||||
/>
|
||||
<ActionsMenu bank={bank} mangoAccount={mangoAccount} />
|
||||
<IconButton
|
||||
onClick={() => handleShowTokenDetails(bank.value.name)}
|
||||
onClick={() => handleShowTokenDetails(bank.name)}
|
||||
>
|
||||
<ChevronDownIcon
|
||||
className={`${
|
||||
showTokenDetails === bank.value.name
|
||||
showTokenDetails === bank.name
|
||||
? 'rotate-180'
|
||||
: 'rotate-360'
|
||||
} h-6 w-6 flex-shrink-0 text-th-fgd-1`}
|
||||
|
@ -309,7 +308,7 @@ const TokenList = () => {
|
|||
</div>
|
||||
<Transition
|
||||
appear={true}
|
||||
show={showTokenDetails === bank.value.name}
|
||||
show={showTokenDetails === bank.name}
|
||||
as={Fragment}
|
||||
enter="transition ease-in duration-200"
|
||||
enterFrom="opacity-0"
|
||||
|
@ -338,19 +337,11 @@ const TokenList = () => {
|
|||
<p className="text-xs text-th-fgd-3">{t('rates')}</p>
|
||||
<p className="space-x-2 font-bold">
|
||||
<span className="text-th-green">
|
||||
{formatDecimal(
|
||||
bank.value.getDepositRate().toNumber(),
|
||||
2
|
||||
)}
|
||||
%
|
||||
{formatDecimal(bank.getDepositRate().toNumber(), 2)}%
|
||||
</span>
|
||||
<span className="font-normal text-th-fgd-4">|</span>
|
||||
<span className="text-th-red">
|
||||
{formatDecimal(
|
||||
bank.value.getBorrowRate().toNumber(),
|
||||
2
|
||||
)}
|
||||
%
|
||||
{formatDecimal(bank.getBorrowRate().toNumber(), 2)}%
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
|
@ -358,8 +349,8 @@ const TokenList = () => {
|
|||
<p className="text-xs text-th-fgd-3">{t('liquidity')}</p>
|
||||
<p className="font-bold">
|
||||
{formatDecimal(
|
||||
bank.value.uiDeposits() - bank.value.uiBorrows(),
|
||||
bank.value.mintDecimals
|
||||
bank.uiDeposits() - bank.uiBorrows(),
|
||||
bank.mintDecimals
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
|
@ -392,37 +383,35 @@ const ActionsMenu = ({
|
|||
const router = useRouter()
|
||||
const { asPath } = router
|
||||
|
||||
const handleShowActionModals = (
|
||||
token: string,
|
||||
action: 'borrow' | 'deposit' | 'withdraw'
|
||||
) => {
|
||||
setSelectedToken(token)
|
||||
action === 'borrow'
|
||||
? setShowBorrowModal(true)
|
||||
: action === 'deposit'
|
||||
? setShowDepositModal(true)
|
||||
: setShowWithdrawModal(true)
|
||||
}
|
||||
const handleShowActionModals = useCallback(
|
||||
(token: string, action: 'borrow' | 'deposit' | 'withdraw') => {
|
||||
setSelectedToken(token)
|
||||
action === 'borrow'
|
||||
? setShowBorrowModal(true)
|
||||
: action === 'deposit'
|
||||
? setShowDepositModal(true)
|
||||
: setShowWithdrawModal(true)
|
||||
},
|
||||
[]
|
||||
)
|
||||
|
||||
const handleBuy = () => {
|
||||
const handleBuy = useCallback(() => {
|
||||
set((s) => {
|
||||
s.swap.inputToken = 'USDC'
|
||||
s.swap.outputToken = bank.name
|
||||
s.swap.outputBank = bank
|
||||
})
|
||||
if (asPath === '/') {
|
||||
router.push('/trade', undefined, { shallow: true })
|
||||
}
|
||||
}
|
||||
}, [bank, router, asPath, set])
|
||||
|
||||
const handleSell = () => {
|
||||
const handleSell = useCallback(() => {
|
||||
set((s) => {
|
||||
s.swap.inputToken = bank.name
|
||||
s.swap.outputToken = 'USDC'
|
||||
s.swap.inputBank = bank
|
||||
})
|
||||
if (asPath === '/') {
|
||||
router.push('/trade', undefined, { shallow: true })
|
||||
}
|
||||
}
|
||||
}, [router, asPath, set, bank])
|
||||
|
||||
return (
|
||||
<>
|
||||
|
@ -465,14 +454,14 @@ const ActionsMenu = ({
|
|||
<LinkButton
|
||||
className="w-full text-left"
|
||||
disabled={!mangoAccount}
|
||||
onClick={() => handleBuy()}
|
||||
onClick={handleBuy}
|
||||
>
|
||||
{t('buy')}
|
||||
</LinkButton>
|
||||
<LinkButton
|
||||
className="w-full text-left"
|
||||
disabled={!mangoAccount}
|
||||
onClick={() => handleSell()}
|
||||
onClick={handleSell}
|
||||
>
|
||||
{t('sell')}
|
||||
</LinkButton>
|
||||
|
|
|
@ -3,12 +3,16 @@ import Image from 'next/image'
|
|||
import mangoStore from '../store/state'
|
||||
|
||||
type TokenSelectProps = {
|
||||
token: string
|
||||
tokenSymbol: string | undefined
|
||||
showTokenList: (x: any) => void
|
||||
type: 'input' | 'output'
|
||||
}
|
||||
|
||||
const TokenSelect = ({ token, showTokenList, type }: TokenSelectProps) => {
|
||||
const TokenSelect = ({
|
||||
tokenSymbol,
|
||||
showTokenList,
|
||||
type,
|
||||
}: TokenSelectProps) => {
|
||||
const group = mangoStore((s) => s.group)
|
||||
const jupiterTokens = mangoStore((s) => s.jupiterTokens)
|
||||
|
||||
|
@ -16,7 +20,7 @@ const TokenSelect = ({ token, showTokenList, type }: TokenSelectProps) => {
|
|||
|
||||
let logoURI
|
||||
if (jupiterTokens.length) {
|
||||
logoURI = jupiterTokens.find((t) => t.symbol === token)!.logoURI
|
||||
logoURI = jupiterTokens.find((t) => t.symbol === tokenSymbol)!.logoURI
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -33,7 +37,7 @@ const TokenSelect = ({ token, showTokenList, type }: TokenSelectProps) => {
|
|||
)}
|
||||
</div>
|
||||
<div className="flex w-full items-center justify-between">
|
||||
<div className="text-xl font-bold text-th-fgd-1">{token}</div>
|
||||
<div className="text-xl font-bold text-th-fgd-1">{tokenSymbol}</div>
|
||||
<ChevronDownIcon className="h-6 w-6" />
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -13,7 +13,7 @@ const ActionTokenItem = ({
|
|||
}: {
|
||||
bank: Bank
|
||||
customValue: number
|
||||
onSelect: (x: any) => void
|
||||
onSelect: (x: string) => void
|
||||
showBorrowRates?: boolean
|
||||
showDepositRates?: boolean
|
||||
}) => {
|
||||
|
|
|
@ -9,7 +9,7 @@ const ActionTokenList = ({
|
|||
showDepositRates,
|
||||
}: {
|
||||
banks: any
|
||||
onSelect: (x: any) => void
|
||||
onSelect: (x: string) => void
|
||||
sortByKey: string
|
||||
showBorrowRates?: boolean
|
||||
showDepositRates?: boolean
|
||||
|
|
|
@ -3,7 +3,7 @@ import { ChevronDownIcon } from '@heroicons/react/solid'
|
|||
import { useTranslation } from 'next-i18next'
|
||||
import Image from 'next/image'
|
||||
import React, { ChangeEvent, useCallback, useMemo, useState } from 'react'
|
||||
import mangoStore from '../../store/state'
|
||||
import mangoStore, { INPUT_TOKEN_DEFAULT } from '../../store/state'
|
||||
import { ModalProps } from '../../types/modal'
|
||||
import { notify } from '../../utils/notifications'
|
||||
import { formatFixedDecimals } from '../../utils/numbers'
|
||||
|
@ -29,14 +29,16 @@ function BorrowModal({ isOpen, onClose, token }: ModalCombinedProps) {
|
|||
const group = mangoStore((s) => s.group)
|
||||
const [inputAmount, setInputAmount] = useState('')
|
||||
const [submitting, setSubmitting] = useState(false)
|
||||
const [selectedToken, setSelectedToken] = useState(token || 'USDC')
|
||||
const [selectedToken, setSelectedToken] = useState(
|
||||
token || INPUT_TOKEN_DEFAULT
|
||||
)
|
||||
const [showTokenList, setShowTokenList] = useState(false)
|
||||
const [sizePercentage, setSizePercentage] = useState('')
|
||||
const jupiterTokens = mangoStore((s) => s.jupiterTokens)
|
||||
|
||||
const bank = useMemo(() => {
|
||||
const group = mangoStore.getState().group
|
||||
return group?.banksMap.get(selectedToken)
|
||||
return group?.banksMapByName.get(selectedToken)![0]
|
||||
}, [selectedToken])
|
||||
|
||||
const logoUri = useMemo(() => {
|
||||
|
@ -55,7 +57,7 @@ function BorrowModal({ isOpen, onClose, token }: ModalCombinedProps) {
|
|||
const group = mangoStore.getState().group
|
||||
if (!group || !bank) return 0
|
||||
const amount = mangoAccount
|
||||
?.getMaxWithdrawWithBorrowForToken(group, selectedToken)
|
||||
?.getMaxWithdrawWithBorrowForToken(group, bank.mint)
|
||||
.toNumber()
|
||||
return amount && amount > 0 ? toUiDecimals(amount, bank.mintDecimals) : 0
|
||||
}, [mangoAccount, bank, selectedToken])
|
||||
|
@ -89,7 +91,7 @@ function BorrowModal({ isOpen, onClose, token }: ModalCombinedProps) {
|
|||
const tx = await client.tokenWithdraw(
|
||||
group,
|
||||
mangoAccount,
|
||||
selectedToken,
|
||||
bank!.mint,
|
||||
parseFloat(inputAmount),
|
||||
true
|
||||
)
|
||||
|
@ -116,17 +118,18 @@ function BorrowModal({ isOpen, onClose, token }: ModalCombinedProps) {
|
|||
|
||||
const banks = useMemo(() => {
|
||||
if (mangoAccount) {
|
||||
return group?.banksMap
|
||||
? Array.from(group?.banksMap, ([key, value]) => {
|
||||
return group?.banksMapByName
|
||||
? Array.from(group?.banksMapByName, ([key, value]) => {
|
||||
const bank = value[0]
|
||||
const amount = mangoAccount
|
||||
?.getMaxWithdrawWithBorrowForToken(group, key)
|
||||
?.getMaxWithdrawWithBorrowForToken(group, bank.mint)
|
||||
.toNumber()
|
||||
return {
|
||||
key,
|
||||
value,
|
||||
maxAmount:
|
||||
amount && amount > 0
|
||||
? toUiDecimals(amount, value.mintDecimals)
|
||||
? toUiDecimals(amount, bank.mintDecimals)
|
||||
: 0,
|
||||
}
|
||||
})
|
||||
|
@ -230,10 +233,7 @@ function BorrowModal({ isOpen, onClose, token }: ModalCombinedProps) {
|
|||
/>
|
||||
</div>
|
||||
</div>
|
||||
<HealthImpact
|
||||
tokenName={selectedToken}
|
||||
amount={parseFloat(inputAmount)}
|
||||
/>
|
||||
<HealthImpact tokenPk={bank!.mint} amount={parseFloat(inputAmount)} />
|
||||
</div>
|
||||
<Button
|
||||
onClick={handleWithdraw}
|
||||
|
|
|
@ -30,7 +30,7 @@ export const walletBalanceForToken = (
|
|||
token: string
|
||||
): { maxAmount: number; maxDecimals: number } => {
|
||||
const group = mangoStore.getState().group
|
||||
const bank = group?.banksMap.get(token)
|
||||
const bank = group?.banksMapByName.get(token)![0]
|
||||
|
||||
let walletToken
|
||||
if (bank) {
|
||||
|
@ -58,7 +58,7 @@ function DepositModal({ isOpen, onClose, token }: ModalCombinedProps) {
|
|||
|
||||
const bank = useMemo(() => {
|
||||
const group = mangoStore.getState().group
|
||||
return group?.banksMap.get(selectedToken)
|
||||
return group?.banksMapByName.get(selectedToken)![0]
|
||||
}, [selectedToken])
|
||||
|
||||
const logoUri = useMemo(() => {
|
||||
|
@ -114,7 +114,7 @@ function DepositModal({ isOpen, onClose, token }: ModalCombinedProps) {
|
|||
const tx = await client.tokenDeposit(
|
||||
group,
|
||||
mangoAccount,
|
||||
selectedToken,
|
||||
bank!.mint,
|
||||
parseFloat(inputAmount)
|
||||
)
|
||||
notify({
|
||||
|
@ -140,8 +140,8 @@ function DepositModal({ isOpen, onClose, token }: ModalCombinedProps) {
|
|||
}
|
||||
|
||||
const banks = useMemo(() => {
|
||||
return group?.banksMap
|
||||
? Array.from(group?.banksMap, ([key, value]) => {
|
||||
return group?.banksMapByName
|
||||
? Array.from(group?.banksMapByName, ([key, value]) => {
|
||||
const walletBalance = walletBalanceForToken(walletTokens, key)
|
||||
return {
|
||||
key,
|
||||
|
@ -153,7 +153,7 @@ function DepositModal({ isOpen, onClose, token }: ModalCombinedProps) {
|
|||
}
|
||||
})
|
||||
: []
|
||||
}, [group?.banksMap, walletTokens])
|
||||
}, [group?.banksMapByName, walletTokens])
|
||||
|
||||
return (
|
||||
<Modal isOpen={isOpen} onClose={onClose}>
|
||||
|
@ -243,7 +243,7 @@ function DepositModal({ isOpen, onClose, token }: ModalCombinedProps) {
|
|||
</div>
|
||||
</div>
|
||||
<HealthImpact
|
||||
tokenName={selectedToken}
|
||||
tokenPk={bank!.mint}
|
||||
amount={parseFloat(inputAmount)}
|
||||
isDeposit
|
||||
/>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Transition } from '@headlessui/react'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import { ChangeEvent, useEffect, useMemo, useState } from 'react'
|
||||
import { ChangeEvent, useCallback, useEffect, useMemo, useState } from 'react'
|
||||
import { ModalProps } from '../../types/modal'
|
||||
// import { PROFILE_CATEGORIES } from '../../utils/profile'
|
||||
import Input from '../forms/Input'
|
||||
|
@ -12,7 +12,6 @@ import Modal from '../shared/Modal'
|
|||
import useLocalStorageState from '../../hooks/useLocalStorageState'
|
||||
import { CheckCircleIcon, PencilIcon } from '@heroicons/react/solid'
|
||||
import { useWallet } from '@solana/wallet-adapter-react'
|
||||
import { handleWalletConnect } from '../../utils/wallet'
|
||||
import mangoStore from '../../store/state'
|
||||
import { IS_ONBOARDED_KEY } from '../Layout'
|
||||
import { EnterRightExitLeft, FadeInFadeOut } from '../shared/Transitions'
|
||||
|
@ -57,12 +56,13 @@ const UserSetupModal = ({ isOpen, onClose }: ModalProps) => {
|
|||
}
|
||||
|
||||
const connectWallet = async () => {
|
||||
const actions = mangoStore.getState().actions
|
||||
if (wallet) {
|
||||
handleWalletConnect(wallet)
|
||||
actions.handleWalletConnect(wallet)
|
||||
}
|
||||
}
|
||||
|
||||
const handleCreateAccount = async () => {
|
||||
const handleCreateAccount = useCallback(async () => {
|
||||
const client = mangoStore.getState().client
|
||||
const group = mangoStore.getState().group
|
||||
const actions = mangoStore.getState().actions
|
||||
|
@ -94,22 +94,22 @@ const UserSetupModal = ({ isOpen, onClose }: ModalProps) => {
|
|||
})
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
}, [accountName, wallet, t])
|
||||
|
||||
const handleDeposit = async () => {
|
||||
const handleDeposit = useCallback(async () => {
|
||||
const client = mangoStore.getState().client
|
||||
const group = mangoStore.getState().group
|
||||
const actions = mangoStore.getState().actions
|
||||
const mangoAccount = mangoStore.getState().mangoAccount.current
|
||||
|
||||
if (!mangoAccount || !group) return
|
||||
|
||||
const bank = group.banksMapByName.get(depositToken)![0]
|
||||
try {
|
||||
setSubmitDeposit(true)
|
||||
const tx = await client.tokenDeposit(
|
||||
group,
|
||||
mangoAccount,
|
||||
depositToken,
|
||||
bank.mint,
|
||||
parseFloat(depositAmount)
|
||||
)
|
||||
notify({
|
||||
|
@ -132,7 +132,7 @@ const UserSetupModal = ({ isOpen, onClose }: ModalProps) => {
|
|||
setSubmitDeposit(false)
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
}, [depositAmount, depositToken, onClose, setIsOnboarded])
|
||||
|
||||
useEffect(() => {
|
||||
if (mangoAccount && showSetupStep === 1) {
|
||||
|
@ -148,8 +148,8 @@ const UserSetupModal = ({ isOpen, onClose }: ModalProps) => {
|
|||
}, [connected, mangoAccountLoading])
|
||||
|
||||
const banks = useMemo(() => {
|
||||
return group?.banksMap
|
||||
? Array.from(group?.banksMap, ([key, value]) => {
|
||||
return group?.banksMapByName
|
||||
? Array.from(group?.banksMapByName, ([key, value]) => {
|
||||
const walletBalance = walletBalanceForToken(walletTokens, key)
|
||||
return {
|
||||
key,
|
||||
|
@ -161,7 +161,7 @@ const UserSetupModal = ({ isOpen, onClose }: ModalProps) => {
|
|||
}
|
||||
})
|
||||
: []
|
||||
}, [group?.banksMap, walletTokens])
|
||||
}, [group?.banksMapByName, walletTokens])
|
||||
|
||||
return (
|
||||
<Modal isOpen={isOpen} onClose={onClose} disableOutsideClose hideClose>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { ChevronDownIcon } from '@heroicons/react/solid'
|
||||
import { PublicKey } from '@solana/web3.js'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import Image from 'next/image'
|
||||
import { ChangeEvent, useCallback, useMemo, useState } from 'react'
|
||||
|
@ -23,19 +24,19 @@ interface WithdrawModalProps {
|
|||
|
||||
type ModalCombinedProps = WithdrawModalProps & ModalProps
|
||||
|
||||
function WithdrawModal({ isOpen, onClose, token }: ModalCombinedProps) {
|
||||
function WithdrawModal({ isOpen, onClose }: ModalCombinedProps) {
|
||||
const { t } = useTranslation('common')
|
||||
const group = mangoStore((s) => s.group)
|
||||
const [inputAmount, setInputAmount] = useState('')
|
||||
const [submitting, setSubmitting] = useState(false)
|
||||
const [selectedToken, setSelectedToken] = useState(token || 'USDC')
|
||||
const [selectedToken, setSelectedToken] = useState('USDC')
|
||||
const [showTokenList, setShowTokenList] = useState(false)
|
||||
const [sizePercentage, setSizePercentage] = useState('')
|
||||
const jupiterTokens = mangoStore((s) => s.jupiterTokens)
|
||||
|
||||
const bank = useMemo(() => {
|
||||
const group = mangoStore.getState().group
|
||||
return group?.banksMap.get(selectedToken)
|
||||
return group?.banksMapByName.get(selectedToken)![0]
|
||||
}, [selectedToken])
|
||||
|
||||
const logoUri = useMemo(() => {
|
||||
|
@ -52,7 +53,7 @@ function WithdrawModal({ isOpen, onClose, token }: ModalCombinedProps) {
|
|||
|
||||
const tokenMax = useMemo(() => {
|
||||
if (!bank) return 0
|
||||
const amount = mangoAccount?.getUi(bank)
|
||||
const amount = mangoAccount?.getTokenBalanceUi(bank)
|
||||
return amount ? floorToDecimal(amount, bank.mintDecimals) : 0
|
||||
}, [mangoAccount, bank])
|
||||
|
||||
|
@ -76,7 +77,7 @@ function WithdrawModal({ isOpen, onClose, token }: ModalCombinedProps) {
|
|||
const tx = await client.tokenWithdraw(
|
||||
group,
|
||||
mangoAccount,
|
||||
selectedToken,
|
||||
bank!.mint,
|
||||
parseFloat(inputAmount),
|
||||
false
|
||||
)
|
||||
|
@ -108,9 +109,9 @@ function WithdrawModal({ isOpen, onClose, token }: ModalCombinedProps) {
|
|||
|
||||
const banks = useMemo(() => {
|
||||
if (mangoAccount) {
|
||||
return group?.banksMap
|
||||
? Array.from(group?.banksMap, ([key, value]) => {
|
||||
const accountBalance = mangoAccount?.getUi(value)
|
||||
return group?.banksMapByName
|
||||
? Array.from(group?.banksMapByName, ([key, value]) => {
|
||||
const accountBalance = mangoAccount?.getTokenBalanceUi(value[0])
|
||||
return {
|
||||
key,
|
||||
value,
|
||||
|
@ -120,7 +121,7 @@ function WithdrawModal({ isOpen, onClose, token }: ModalCombinedProps) {
|
|||
: []
|
||||
}
|
||||
return []
|
||||
}, [mangoAccount, group?.banksMap])
|
||||
}, [mangoAccount, group?.banksMapByName])
|
||||
|
||||
return (
|
||||
<Modal isOpen={isOpen} onClose={onClose}>
|
||||
|
@ -207,7 +208,7 @@ function WithdrawModal({ isOpen, onClose, token }: ModalCombinedProps) {
|
|||
</div>
|
||||
</div>
|
||||
<HealthImpact
|
||||
tokenName={selectedToken}
|
||||
tokenPk={bank!.mint}
|
||||
amount={parseFloat(inputAmount)}
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { HealthType } from '@blockworks-foundation/mango-v4'
|
||||
import { ArrowRightIcon } from '@heroicons/react/solid'
|
||||
import { PublicKey } from '@solana/web3.js'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import { useMemo } from 'react'
|
||||
import mangoStore from '../../store/state'
|
||||
|
@ -7,11 +8,11 @@ import mangoStore from '../../store/state'
|
|||
const HealthImpact = ({
|
||||
amount,
|
||||
isDeposit,
|
||||
tokenName,
|
||||
tokenPk,
|
||||
}: {
|
||||
amount: number
|
||||
isDeposit?: boolean
|
||||
tokenName: string
|
||||
tokenPk: PublicKey
|
||||
}) => {
|
||||
const { t } = useTranslation('common')
|
||||
const mangoAccount = mangoStore((s) => s.mangoAccount.current)
|
||||
|
@ -26,7 +27,7 @@ const HealthImpact = ({
|
|||
if (!group || !mangoAccount) return 0
|
||||
const projectedHealth = mangoAccount
|
||||
.simHealthRatioWithTokenPositionChanges(group, [
|
||||
{ tokenName: tokenName, tokenAmount: isDeposit ? amount : amount * -1 },
|
||||
{ mintPk: tokenPk, tokenAmount: isDeposit ? amount : amount * -1 },
|
||||
])
|
||||
.toNumber()
|
||||
|
||||
|
@ -35,7 +36,7 @@ const HealthImpact = ({
|
|||
: projectedHealth < 0
|
||||
? 0
|
||||
: projectedHealth
|
||||
}, [mangoAccount, tokenName, amount, isDeposit])
|
||||
}, [mangoAccount, tokenPk, amount, isDeposit])
|
||||
|
||||
return (
|
||||
<div className="space-y-2 border-y border-th-bkg-3 px-2 py-4">
|
||||
|
|
|
@ -26,18 +26,17 @@ import Image from 'next/image'
|
|||
import { formatDecimal } from '../../utils/numbers'
|
||||
|
||||
type JupiterRouteInfoProps = {
|
||||
inputToken: string
|
||||
outputToken: string
|
||||
amountIn: Decimal
|
||||
slippage: number
|
||||
submitting: boolean
|
||||
handleSwap: (x: TransactionInstruction[]) => void
|
||||
onClose: () => void
|
||||
inputTokenInfo: Token | undefined
|
||||
jupiter: Jupiter | undefined
|
||||
routes: RouteInfo[] | undefined
|
||||
onClose: () => void
|
||||
outputTokenInfo: Token | undefined
|
||||
routes: RouteInfo[] | undefined
|
||||
selectedRoute: RouteInfo | undefined
|
||||
setSelectedRoute: Dispatch<SetStateAction<RouteInfo | undefined>>
|
||||
slippage: number
|
||||
submitting: boolean
|
||||
}
|
||||
|
||||
const parseJupiterRoute = async (
|
||||
|
@ -63,7 +62,7 @@ const parseJupiterRoute = async (
|
|||
}
|
||||
|
||||
const JupiterRouteInfo = ({
|
||||
inputToken,
|
||||
inputTokenInfo,
|
||||
amountIn,
|
||||
handleSwap,
|
||||
submitting,
|
||||
|
@ -85,12 +84,8 @@ const JupiterRouteInfo = ({
|
|||
const connected = mangoStore((s) => s.connected)
|
||||
|
||||
const inputTokenIconUri = useMemo(() => {
|
||||
if (jupiterTokens.length) {
|
||||
const found = jupiterTokens.find((t) => t.symbol === inputToken)
|
||||
return found ? found.logoURI : ''
|
||||
}
|
||||
return ''
|
||||
}, [inputToken, jupiterTokens])
|
||||
return inputTokenInfo ? inputTokenInfo.logoURI : ''
|
||||
}, [inputTokenInfo])
|
||||
|
||||
const amountOut = useMemo(() => {
|
||||
if (!selectedRoute || !outputTokenInfo) return
|
||||
|
@ -114,27 +109,35 @@ const JupiterRouteInfo = ({
|
|||
|
||||
const healthImpact = useMemo(() => {
|
||||
const group = mangoStore.getState().group
|
||||
if (!group || !mangoAccount || !outputTokenInfo || !amountOut)
|
||||
if (
|
||||
!inputTokenInfo ||
|
||||
!mangoAccount ||
|
||||
!outputTokenInfo ||
|
||||
!amountOut ||
|
||||
!group
|
||||
)
|
||||
return 'Unknown'
|
||||
const bank = group.banksMap.get(inputToken)!
|
||||
|
||||
const simulatedHealthRatio = mangoAccount
|
||||
.simHealthRatioWithTokenPositionChanges(group, [
|
||||
{
|
||||
tokenName: inputToken,
|
||||
mintPk: new PublicKey(inputTokenInfo.address),
|
||||
tokenAmount:
|
||||
toNativeDecimals(
|
||||
amountIn.toNumber(),
|
||||
bank.mintDecimals
|
||||
inputTokenInfo.decimals
|
||||
).toNumber() * -1,
|
||||
},
|
||||
{ tokenName: outputTokenInfo.symbol, tokenAmount: amountOut },
|
||||
{
|
||||
mintPk: new PublicKey(outputTokenInfo.address),
|
||||
tokenAmount: amountOut,
|
||||
},
|
||||
])
|
||||
.toNumber()
|
||||
// console.log('simulatedHealthRatio', simulatedHealthRatio)
|
||||
|
||||
return simulatedHealthRatio
|
||||
}, [mangoAccount, inputToken, outputTokenInfo, amountIn, amountOut])
|
||||
}, [mangoAccount, inputTokenInfo, outputTokenInfo, amountIn, amountOut])
|
||||
|
||||
const onSwap = async () => {
|
||||
if (!jupiter || !selectedRoute) return
|
||||
|
@ -171,12 +174,14 @@ const JupiterRouteInfo = ({
|
|||
/>
|
||||
</div>
|
||||
</div>
|
||||
<p className="mb-0.5 text-lg font-bold text-th-fgd-1">{`${amountIn} ${inputToken} for ${amountOut} ${outputTokenInfo.symbol}`}</p>
|
||||
<p className="mb-0.5 text-lg font-bold text-th-fgd-1">{`${amountIn} ${
|
||||
inputTokenInfo!.name
|
||||
} for ${amountOut} ${outputTokenInfo.symbol}`}</p>
|
||||
<div className="flex items-center justify-end">
|
||||
<p className="text-right text-sm">
|
||||
{swapRate ? (
|
||||
<>
|
||||
1 {inputToken} ≈{' '}
|
||||
1 {inputTokenInfo!.name} ≈{' '}
|
||||
{formatDecimal(amountOut / amountIn.toNumber(), 6)}{' '}
|
||||
{outputTokenInfo?.symbol}
|
||||
</>
|
||||
|
@ -184,7 +189,7 @@ const JupiterRouteInfo = ({
|
|||
<>
|
||||
1 {outputTokenInfo?.symbol} ≈{' '}
|
||||
{formatDecimal(amountIn.toNumber() / amountOut, 6)}{' '}
|
||||
{inputToken}
|
||||
{inputTokenInfo!.name}
|
||||
</>
|
||||
)}
|
||||
</p>
|
||||
|
@ -417,7 +422,7 @@ const JupiterRouteInfo = ({
|
|||
setSelectedRoute={setSelectedRoute}
|
||||
selectedRoute={selectedRoute}
|
||||
routes={routes}
|
||||
inputTokenSymbol={inputToken}
|
||||
inputTokenSymbol={inputTokenInfo!.name}
|
||||
outputTokenInfo={outputTokenInfo}
|
||||
/>
|
||||
) : null}
|
||||
|
|
|
@ -1,14 +1,8 @@
|
|||
import { PublicKey } from '@solana/web3.js'
|
||||
import { ChangeEvent, useEffect, useRef, useState } from 'react'
|
||||
import mangoStore from '../../store/state'
|
||||
import { useTokenMax } from './Swap'
|
||||
|
||||
type LeverageSliderProps = {
|
||||
amount: number
|
||||
inputToken: string
|
||||
outputToken: string
|
||||
onChange: (x: string) => void
|
||||
}
|
||||
|
||||
const LeverageSlider = ({
|
||||
amount,
|
||||
leverageMax,
|
||||
|
@ -16,7 +10,7 @@ const LeverageSlider = ({
|
|||
}: {
|
||||
amount: number
|
||||
leverageMax: number
|
||||
onChange: (x: any) => any
|
||||
onChange: (x: string) => any
|
||||
}) => {
|
||||
const [value, setValue] = useState(0)
|
||||
const inputEl = useRef<HTMLInputElement>(null)
|
||||
|
@ -36,8 +30,10 @@ const LeverageSlider = ({
|
|||
}, [leverageMax, value])
|
||||
|
||||
useEffect(() => {
|
||||
onChange(amount.toString())
|
||||
setValue(amount)
|
||||
if (amount) {
|
||||
onChange(amount.toString())
|
||||
setValue(amount)
|
||||
}
|
||||
}, [amount])
|
||||
|
||||
const handleSliderChange = (e: ChangeEvent<HTMLInputElement>) => {
|
||||
|
@ -72,11 +68,12 @@ const LeverageSlider = ({
|
|||
|
||||
export const SwapLeverageSlider = ({
|
||||
amount,
|
||||
inputToken,
|
||||
outputToken,
|
||||
onChange,
|
||||
}: LeverageSliderProps) => {
|
||||
const { amountWithBorrow } = useTokenMax(inputToken, outputToken)
|
||||
}: {
|
||||
amount: number
|
||||
onChange: (x: string) => void
|
||||
}) => {
|
||||
const { amountWithBorrow } = useTokenMax()
|
||||
|
||||
return (
|
||||
<>
|
||||
|
@ -96,7 +93,7 @@ export const BorrowLeverageSlider = ({
|
|||
}: {
|
||||
amount: number
|
||||
tokenMax: number
|
||||
onChange: (x: any) => any
|
||||
onChange: (x: string) => any
|
||||
}) => {
|
||||
return (
|
||||
<>
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
import { useState, useCallback, useEffect, useMemo } from 'react'
|
||||
import { TransactionInstruction } from '@solana/web3.js'
|
||||
import { PublicKey, TransactionInstruction } from '@solana/web3.js'
|
||||
import { ArrowDownIcon, CogIcon } from '@heroicons/react/solid'
|
||||
import { RouteInfo } from '@jup-ag/core'
|
||||
import NumberFormat, { NumberFormatValues } from 'react-number-format'
|
||||
import Decimal from 'decimal.js'
|
||||
|
||||
import mangoStore from '../../store/state'
|
||||
import mangoStore, {
|
||||
INPUT_TOKEN_DEFAULT,
|
||||
OUTPUT_TOKEN_DEFAULT,
|
||||
} from '../../store/state'
|
||||
import ContentBox from '../shared/ContentBox'
|
||||
import { notify } from '../../utils/notifications'
|
||||
import JupiterRouteInfo from './JupiterRouteInfo'
|
||||
|
@ -45,18 +48,15 @@ const Swap = () => {
|
|||
const set = mangoStore.getState().set
|
||||
const useMargin = mangoStore((s) => s.swap.margin)
|
||||
const slippage = mangoStore((s) => s.swap.slippage)
|
||||
const inputToken = mangoStore((s) => s.swap.inputToken)
|
||||
const outputToken = mangoStore((s) => s.swap.outputToken)
|
||||
const inputTokenInfo = mangoStore((s) => s.swap.inputTokenInfo)
|
||||
const outputTokenInfo = mangoStore((s) => s.swap.outputTokenInfo)
|
||||
const jupiterTokens = mangoStore((s) => s.jupiterTokens)
|
||||
const connected = mangoStore((s) => s.connected)
|
||||
const [debouncedAmountIn, setDebouncedValue] = useDebounce(
|
||||
amountInFormValue,
|
||||
300
|
||||
)
|
||||
const [debouncedAmountIn] = useDebounce(amountInFormValue, 300)
|
||||
|
||||
const { amountOut, jupiter, outputTokenInfo, routes } = useJupiter({
|
||||
inputTokenSymbol: inputToken,
|
||||
outputTokenSymbol: outputToken,
|
||||
const { amountOut, jupiter, routes } = useJupiter({
|
||||
inputTokenInfo,
|
||||
outputTokenInfo,
|
||||
inputAmount: debouncedAmountIn,
|
||||
slippage,
|
||||
})
|
||||
|
@ -69,11 +69,6 @@ const Swap = () => {
|
|||
setAmountInFormValue(e.value)
|
||||
}, [])
|
||||
|
||||
const inputBank = useMemo(() => {
|
||||
const group = mangoStore.getState().group
|
||||
return group?.banksMap.get(inputToken)
|
||||
}, [inputToken])
|
||||
|
||||
const handleTokenInSelect = useCallback(
|
||||
(mintAddress: string) => {
|
||||
const inputTokenInfo = jupiterTokens.find(
|
||||
|
@ -81,10 +76,9 @@ const Swap = () => {
|
|||
)
|
||||
const group = mangoStore.getState().group
|
||||
if (group) {
|
||||
const banks = Array.from(group.banksMap.values())
|
||||
const bank = banks.find((b) => b.mint.toString() === mintAddress)
|
||||
const bank = group.getFirstBankByMint(new PublicKey(mintAddress))
|
||||
set((s) => {
|
||||
s.swap.inputToken = bank!.name
|
||||
s.swap.inputBank = bank
|
||||
s.swap.inputTokenInfo = inputTokenInfo
|
||||
})
|
||||
}
|
||||
|
@ -100,10 +94,9 @@ const Swap = () => {
|
|||
)
|
||||
const group = mangoStore.getState().group
|
||||
if (group) {
|
||||
const banks = Array.from(group.banksMap.values())
|
||||
const bank = banks.find((b) => b.mint.toString() === mintAddress)
|
||||
const bank = group.getFirstBankByMint(new PublicKey(mintAddress))
|
||||
set((s) => {
|
||||
s.swap.outputToken = bank!.name
|
||||
s.swap.outputBank = bank
|
||||
s.swap.outputTokenInfo = outputTokenInfo
|
||||
})
|
||||
}
|
||||
|
@ -113,24 +106,19 @@ const Swap = () => {
|
|||
)
|
||||
|
||||
const handleSwitchTokens = useCallback(() => {
|
||||
const inputTokenInfo = jupiterTokens.find(
|
||||
(t: any) => t.symbol === inputToken
|
||||
)
|
||||
const outputTokenInfo = jupiterTokens.find(
|
||||
(t: any) => t.symbol === outputToken
|
||||
)
|
||||
setAmountInFormValue(amountOut.toString())
|
||||
|
||||
const inputBank = mangoStore.getState().swap.inputBank
|
||||
const outputBank = mangoStore.getState().swap.outputBank
|
||||
set((s) => {
|
||||
s.swap.inputToken = outputToken
|
||||
s.swap.outputToken = inputToken
|
||||
s.swap.inputBank = outputBank
|
||||
s.swap.outputBank = inputBank
|
||||
s.swap.inputTokenInfo = outputTokenInfo
|
||||
s.swap.outputTokenInfo = inputTokenInfo
|
||||
})
|
||||
setAnimateSwitchArrow(
|
||||
(prevanimateSwitchArrow) => prevanimateSwitchArrow + 1
|
||||
)
|
||||
}, [jupiterTokens, inputToken, outputToken, set, amountOut])
|
||||
}, [inputTokenInfo, outputTokenInfo, set, amountOut])
|
||||
|
||||
const handleSwap = useCallback(
|
||||
async (userDefinedInstructions: TransactionInstruction[]) => {
|
||||
|
@ -138,17 +126,20 @@ const Swap = () => {
|
|||
const group = mangoStore.getState().group
|
||||
const actions = mangoStore.getState().actions
|
||||
const mangoAccount = mangoStore.getState().mangoAccount.current
|
||||
if (!mangoAccount || !group) return
|
||||
const inputBank = mangoStore.getState().swap.inputBank
|
||||
const outputBank = mangoStore.getState().swap.outputBank
|
||||
if (!mangoAccount || !group || !inputBank || !outputBank) return
|
||||
|
||||
try {
|
||||
setSubmitting(true)
|
||||
const tx = await client.marginTrade({
|
||||
group,
|
||||
mangoAccount,
|
||||
inputToken,
|
||||
inputMintPk: inputBank.mint,
|
||||
amountIn: parseFloat(debouncedAmountIn),
|
||||
outputToken,
|
||||
outputMintPk: outputBank.mint,
|
||||
userDefinedInstructions,
|
||||
flashLoanType: 'swap',
|
||||
})
|
||||
console.log('Success swapping:', tx)
|
||||
notify({
|
||||
|
@ -170,7 +161,7 @@ const Swap = () => {
|
|||
setSubmitting(false)
|
||||
}
|
||||
},
|
||||
[debouncedAmountIn, inputToken, outputToken]
|
||||
[debouncedAmountIn]
|
||||
)
|
||||
|
||||
const amountIn: Decimal | null = useMemo(() => {
|
||||
|
@ -198,9 +189,8 @@ const Swap = () => {
|
|||
leaveTo="translate-x-full"
|
||||
>
|
||||
<JupiterRouteInfo
|
||||
inputToken={inputToken}
|
||||
inputTokenInfo={inputTokenInfo}
|
||||
onClose={() => setShowConfirm(false)}
|
||||
outputToken={outputToken}
|
||||
amountIn={amountIn}
|
||||
slippage={slippage}
|
||||
handleSwap={handleSwap}
|
||||
|
@ -246,15 +236,13 @@ const Swap = () => {
|
|||
<p className="text-th-fgd-3">{t('sell')}</p>
|
||||
<MaxSwapAmount
|
||||
useMargin={useMargin}
|
||||
inputToken={inputToken}
|
||||
outputToken={outputToken}
|
||||
setAmountIn={setAmountInFormValue}
|
||||
/>
|
||||
</div>
|
||||
<div className="mb-3 grid grid-cols-2">
|
||||
<div className="col-span-1 rounded-lg rounded-r-none border border-r-0 border-th-bkg-4 bg-th-bkg-1">
|
||||
<TokenSelect
|
||||
token={inputToken}
|
||||
tokenSymbol={inputTokenInfo?.symbol || INPUT_TOKEN_DEFAULT}
|
||||
showTokenList={setShowTokenSelect}
|
||||
type="input"
|
||||
/>
|
||||
|
@ -263,7 +251,7 @@ const Swap = () => {
|
|||
<NumberFormat
|
||||
inputMode="decimal"
|
||||
thousandSeparator=","
|
||||
decimalScale={inputBank?.mintDecimals || 6}
|
||||
decimalScale={inputTokenInfo?.decimals || 6}
|
||||
name="amountIn"
|
||||
id="amountIn"
|
||||
className="w-full rounded-lg rounded-l-none border border-th-bkg-4 bg-th-bkg-1 p-3 text-right text-xl font-bold tracking-wider text-th-fgd-1 focus:outline-none"
|
||||
|
@ -274,11 +262,7 @@ const Swap = () => {
|
|||
/>
|
||||
</div>
|
||||
{!useMargin ? (
|
||||
<PercentageSelectButtons
|
||||
setAmountIn={setAmountInFormValue}
|
||||
inputToken={inputToken}
|
||||
outputToken={outputToken}
|
||||
/>
|
||||
<PercentageSelectButtons setAmountIn={setAmountInFormValue} />
|
||||
) : null}
|
||||
</div>
|
||||
<div className="flex justify-center">
|
||||
|
@ -300,7 +284,7 @@ const Swap = () => {
|
|||
<div className="mb-3 grid grid-cols-2">
|
||||
<div className="col-span-1 rounded-lg rounded-r-none border border-r-0 border-th-bkg-4 bg-th-bkg-1">
|
||||
<TokenSelect
|
||||
token={outputToken}
|
||||
tokenSymbol={outputTokenInfo?.symbol || OUTPUT_TOKEN_DEFAULT}
|
||||
showTokenList={setShowTokenSelect}
|
||||
type="output"
|
||||
/>
|
||||
|
@ -314,7 +298,7 @@ const Swap = () => {
|
|||
</div>
|
||||
) : (
|
||||
<span className="p-3">
|
||||
{amountOut ? numberFormat.format(amountOut) : 0}
|
||||
{amountOut ? numberFormat.format(amountOut) : ''}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
|
@ -327,8 +311,6 @@ const Swap = () => {
|
|||
</div>
|
||||
<SwapLeverageSlider
|
||||
amount={amountIn.toNumber()}
|
||||
inputToken={inputToken}
|
||||
outputToken={outputToken}
|
||||
onChange={setAmountInFormValue}
|
||||
/>
|
||||
</>
|
||||
|
@ -361,53 +343,47 @@ const Swap = () => {
|
|||
|
||||
export default Swap
|
||||
|
||||
export const useTokenMax = (inputToken: string, outputToken: string) => {
|
||||
export const useTokenMax = () => {
|
||||
const mangoAccount = mangoStore((s) => s.mangoAccount.current)
|
||||
const inputBank = mangoStore((s) => s.swap.inputBank)
|
||||
const outputBank = mangoStore((s) => s.swap.outputBank)
|
||||
|
||||
const tokenInMax = useMemo(() => {
|
||||
const group = mangoStore.getState().group
|
||||
const bank = group?.banksMap.get(inputToken)
|
||||
|
||||
if (!group || !bank || !mangoAccount)
|
||||
if (!group || !inputBank || !mangoAccount || !outputBank)
|
||||
return { amount: 0.0, decimals: 6, amountWithBorrow: 0.0 }
|
||||
|
||||
const amount = mangoAccount.getUi(bank)
|
||||
const amount = mangoAccount.getTokenBalanceUi(inputBank)
|
||||
const amountWithBorrow = mangoAccount
|
||||
?.getMaxSourceForTokenSwap(group, inputToken, outputToken, 0.94)
|
||||
?.getMaxSourceForTokenSwap(group, inputBank.mint, outputBank.mint, 0.94)
|
||||
.toNumber()
|
||||
|
||||
return {
|
||||
amount: amount > 0 ? floorToDecimal(amount, bank.mintDecimals) : 0,
|
||||
amount: amount > 0 ? floorToDecimal(amount, inputBank.mintDecimals) : 0,
|
||||
amountWithBorrow:
|
||||
amountWithBorrow > 0
|
||||
? floorToDecimal(
|
||||
toUiDecimals(amountWithBorrow, bank.mintDecimals),
|
||||
bank.mintDecimals
|
||||
toUiDecimals(amountWithBorrow, inputBank.mintDecimals),
|
||||
inputBank.mintDecimals
|
||||
)
|
||||
: 0,
|
||||
decimals: bank.mintDecimals,
|
||||
decimals: inputBank.mintDecimals,
|
||||
}
|
||||
}, [inputToken, mangoAccount, outputToken])
|
||||
}, [inputBank, mangoAccount, outputBank])
|
||||
|
||||
return tokenInMax
|
||||
}
|
||||
|
||||
const MaxSwapAmount = ({
|
||||
inputToken,
|
||||
outputToken,
|
||||
setAmountIn,
|
||||
useMargin,
|
||||
}: {
|
||||
inputToken: string
|
||||
outputToken: string
|
||||
setAmountIn: (x: any) => void
|
||||
useMargin: boolean
|
||||
}) => {
|
||||
const { t } = useTranslation('common')
|
||||
const { amount: tokenMax, amountWithBorrow } = useTokenMax(
|
||||
inputToken,
|
||||
outputToken
|
||||
)
|
||||
const { amount: tokenMax, amountWithBorrow } = useTokenMax()
|
||||
|
||||
const setMaxInputAmount = () => {
|
||||
const amountIn = useMargin ? amountWithBorrow : tokenMax
|
||||
|
@ -425,16 +401,12 @@ const MaxSwapAmount = ({
|
|||
}
|
||||
|
||||
const PercentageSelectButtons = ({
|
||||
inputToken,
|
||||
outputToken,
|
||||
setAmountIn,
|
||||
}: {
|
||||
inputToken: string
|
||||
outputToken: string
|
||||
setAmountIn: (x: any) => any
|
||||
}) => {
|
||||
const [sizePercentage, setSizePercentage] = useState('')
|
||||
const { amount: tokenMax, decimals } = useTokenMax(inputToken, outputToken)
|
||||
const { amount: tokenMax, decimals } = useTokenMax()
|
||||
|
||||
const handleSizePercentage = (percentage: string) => {
|
||||
setSizePercentage(percentage)
|
||||
|
|
|
@ -6,29 +6,28 @@ import Decimal from 'decimal.js'
|
|||
|
||||
import mangoStore, { CLUSTER } from '../../store/state'
|
||||
import { Token } from '../../types/jupiter'
|
||||
import { PublicKey } from '@solana/web3.js'
|
||||
|
||||
type useJupiterPropTypes = {
|
||||
inputTokenSymbol: string
|
||||
outputTokenSymbol: string
|
||||
inputTokenInfo: Token | undefined
|
||||
outputTokenInfo: Token | undefined
|
||||
inputAmount: string
|
||||
slippage: number
|
||||
}
|
||||
|
||||
type RouteParams = {
|
||||
routes: RouteInfo[]
|
||||
outputTokenInfo: Token | undefined
|
||||
amountOut: number
|
||||
}
|
||||
|
||||
const defaultComputedInfo = {
|
||||
routes: [],
|
||||
outputTokenInfo: undefined,
|
||||
amountOut: 0,
|
||||
}
|
||||
|
||||
const useJupiter = ({
|
||||
inputTokenSymbol,
|
||||
outputTokenSymbol,
|
||||
inputTokenInfo,
|
||||
outputTokenInfo,
|
||||
inputAmount,
|
||||
slippage,
|
||||
}: useJupiterPropTypes) => {
|
||||
|
@ -61,19 +60,17 @@ const useJupiter = ({
|
|||
const tokens = mangoStore.getState().jupiterTokens
|
||||
|
||||
const loadRoutes = async () => {
|
||||
const inputBank = group.banksMap.get(inputTokenSymbol)
|
||||
const outputBank = group.banksMap.get(outputTokenSymbol)
|
||||
if (!inputBank || !outputBank) return
|
||||
if (!outputTokenInfo || !inputTokenInfo) return
|
||||
if (!inputAmount) {
|
||||
setComputedInfo(defaultComputedInfo)
|
||||
} else {
|
||||
try {
|
||||
const computedRoutes = await jupiter
|
||||
?.computeRoutes({
|
||||
inputMint: inputBank.mint, // Mint address of the input token
|
||||
outputMint: outputBank.mint, // Mint address of the output token
|
||||
inputMint: new PublicKey(inputTokenInfo.address), // Mint address of the input token
|
||||
outputMint: new PublicKey(outputTokenInfo.address), // Mint address of the output token
|
||||
amount: JSBI.BigInt(
|
||||
new Decimal(inputAmount).mul(10 ** inputBank.mintDecimals)
|
||||
new Decimal(inputAmount).mul(10 ** inputTokenInfo.decimals)
|
||||
),
|
||||
slippage, // The slippage in % terms
|
||||
filterTopNResult: 10,
|
||||
|
@ -83,9 +80,7 @@ const useJupiter = ({
|
|||
console.error('Error computing Jupiter routes:', e)
|
||||
return
|
||||
})
|
||||
const tokenOut = tokens.find(
|
||||
(t: any) => t.address === outputBank.mint.toString()
|
||||
)
|
||||
|
||||
const routesInfosWithoutRaydium = computedRoutes?.routesInfos.filter(
|
||||
(r) => {
|
||||
for (const mkt of r.marketInfos) {
|
||||
|
@ -101,10 +96,9 @@ const useJupiter = ({
|
|||
|
||||
setComputedInfo({
|
||||
routes: routesInfosWithoutRaydium,
|
||||
outputTokenInfo: tokenOut,
|
||||
amountOut: toUiDecimals(
|
||||
JSBI.toNumber(bestRoute.outAmount),
|
||||
tokenOut?.decimals!
|
||||
outputTokenInfo.decimals!
|
||||
),
|
||||
})
|
||||
}
|
||||
|
@ -115,7 +109,7 @@ const useJupiter = ({
|
|||
}
|
||||
|
||||
loadRoutes()
|
||||
}, [inputTokenSymbol, outputTokenSymbol, jupiter, slippage, inputAmount])
|
||||
}, [inputTokenInfo, outputTokenInfo, jupiter, slippage, inputAmount])
|
||||
|
||||
return { jupiter, ...computedInfo }
|
||||
}
|
||||
|
|
|
@ -4,26 +4,9 @@ import { WalletReadyState } from '@solana/wallet-adapter-base'
|
|||
import { useTranslation } from 'next-i18next'
|
||||
// import AccountsModal from './AccountsModal'
|
||||
import uniqBy from 'lodash/uniqBy'
|
||||
import { notify } from '../../utils/notifications'
|
||||
import WalletSelect from './WalletSelect'
|
||||
import mangoStore from '../../store/state'
|
||||
|
||||
export const handleWalletConnect = (wallet: Wallet) => {
|
||||
if (!wallet) {
|
||||
return
|
||||
}
|
||||
|
||||
wallet?.adapter?.connect().catch((e) => {
|
||||
if (e.name.includes('WalletLoadError')) {
|
||||
notify({
|
||||
title: `${wallet.adapter.name} Error`,
|
||||
type: 'error',
|
||||
description: `Please install ${wallet.adapter.name} and then reload this page.`,
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export const ConnectWalletButton: React.FC = () => {
|
||||
const { wallet, wallets, select } = useWallet()
|
||||
const { t } = useTranslation('common')
|
||||
|
@ -49,11 +32,12 @@ export const ConnectWalletButton: React.FC = () => {
|
|||
|
||||
const handleConnect = useCallback(() => {
|
||||
const set = mangoStore.getState().set
|
||||
const actions = mangoStore.getState().actions
|
||||
if (wallet) {
|
||||
set((state) => {
|
||||
state.mangoAccount.loading = true
|
||||
})
|
||||
handleWalletConnect(wallet)
|
||||
actions.handleWalletConnect(wallet)
|
||||
}
|
||||
}, [wallet])
|
||||
|
||||
|
|
|
@ -5,12 +5,12 @@ import { Wallet } from '@project-serum/anchor'
|
|||
|
||||
const WalletListener = () => {
|
||||
const { wallet, connected, disconnecting } = useWallet()
|
||||
const loadingMangoAccounts = mangoStore((s) => s.mangoAccounts.loading)
|
||||
const mangoAccounts = mangoStore((s) => s.mangoAccounts.accounts)
|
||||
|
||||
useEffect(() => {
|
||||
const actions = mangoStore.getState().actions
|
||||
const set = mangoStore.getState().set
|
||||
const mangoAccounts = mangoStore.getState().mangoAccounts.accounts
|
||||
const loadingMangoAccounts = mangoStore.getState().mangoAccounts.loading
|
||||
|
||||
const onConnect = async () => {
|
||||
if (!wallet) return
|
||||
|
@ -21,11 +21,9 @@ const WalletListener = () => {
|
|||
mangoAccounts[0].accountNum
|
||||
)
|
||||
} else {
|
||||
if (!loadingMangoAccounts) {
|
||||
set((s) => {
|
||||
s.mangoAccount.loading = false
|
||||
})
|
||||
}
|
||||
set((s) => {
|
||||
s.mangoAccount.loading = false
|
||||
})
|
||||
}
|
||||
actions.fetchProfilePicture(wallet.adapter as unknown as Wallet)
|
||||
actions.fetchWalletTokens(wallet.adapter as unknown as Wallet)
|
||||
|
@ -35,7 +33,7 @@ const WalletListener = () => {
|
|||
if (connected) {
|
||||
onConnect()
|
||||
}
|
||||
}, [wallet, connected, loadingMangoAccounts, mangoAccounts.length])
|
||||
}, [wallet, connected])
|
||||
|
||||
useEffect(() => {
|
||||
const setStore = mangoStore.getState().set
|
||||
|
|
147
store/state.ts
147
store/state.ts
|
@ -1,17 +1,27 @@
|
|||
import dayjs from 'dayjs'
|
||||
import produce from 'immer'
|
||||
import create from 'zustand'
|
||||
import { subscribeWithSelector } from 'zustand/middleware'
|
||||
import produce from 'immer'
|
||||
import { AnchorProvider, Wallet, web3 } from '@project-serum/anchor'
|
||||
import {
|
||||
AnchorProvider,
|
||||
Wallet as AnchorWallet,
|
||||
web3,
|
||||
} from '@project-serum/anchor'
|
||||
import { Connection, Keypair, PublicKey } from '@solana/web3.js'
|
||||
import { getProfilePicture, ProfilePicture } from '@solflare-wallet/pfp'
|
||||
import { TOKEN_LIST_URL } from '@jup-ag/core'
|
||||
import { Order } from '@project-serum/serum/lib/market'
|
||||
import { Wallet } from '@solana/wallet-adapter-react'
|
||||
import {
|
||||
MangoClient,
|
||||
Group,
|
||||
MangoAccount,
|
||||
Serum3Market,
|
||||
MANGO_V4_ID,
|
||||
Bank,
|
||||
} from '@blockworks-foundation/mango-v4'
|
||||
|
||||
import EmptyWallet from '../utils/wallet'
|
||||
import { Order } from '@project-serum/serum/lib/market'
|
||||
import { Notification, notify } from '../utils/notifications'
|
||||
import {
|
||||
COINGECKO_IDS,
|
||||
|
@ -20,9 +30,6 @@ import {
|
|||
TokenAccount,
|
||||
} from '../utils/tokens'
|
||||
import { Token } from '../types/jupiter'
|
||||
import { getProfilePicture, ProfilePicture } from '@solflare-wallet/pfp'
|
||||
import { TOKEN_LIST_URL } from '@jup-ag/core'
|
||||
import dayjs from 'dayjs'
|
||||
|
||||
const GROUP = new PublicKey('DLdcpC6AsAJ9xeKMR3WhHrN5sM5o7GVVXQhQ5vwisTtz')
|
||||
|
||||
|
@ -44,6 +51,8 @@ const DEFAULT_CLIENT = MangoClient.connect(
|
|||
CLUSTER,
|
||||
MANGO_V4_ID[CLUSTER]
|
||||
)
|
||||
export const INPUT_TOKEN_DEFAULT = 'USDC'
|
||||
export const OUTPUT_TOKEN_DEFAULT = 'SOL'
|
||||
|
||||
interface TotalInterestDataItem {
|
||||
borrow_interest: number
|
||||
|
@ -109,8 +118,8 @@ export type MangoStore = {
|
|||
notifications: Array<Notification>
|
||||
serumOrders: Order[] | undefined
|
||||
swap: {
|
||||
inputToken: string
|
||||
outputToken: string
|
||||
inputBank: Bank | undefined
|
||||
outputBank: Bank | undefined
|
||||
inputTokenInfo: Token | undefined
|
||||
outputTokenInfo: Token | undefined
|
||||
margin: boolean
|
||||
|
@ -134,16 +143,19 @@ export type MangoStore = {
|
|||
) => Promise<void>
|
||||
fetchCoingeckoPrices: () => Promise<void>
|
||||
fetchGroup: () => Promise<void>
|
||||
fetchMangoAccount: (wallet: Wallet, accountNumber?: number) => Promise<void>
|
||||
fetchMangoAccounts: (wallet: Wallet) => Promise<void>
|
||||
fetchMangoAccount: (
|
||||
wallet: AnchorWallet,
|
||||
accountNumber?: number
|
||||
) => Promise<void>
|
||||
fetchMangoAccounts: (wallet: AnchorWallet) => Promise<void>
|
||||
fetchNfts: (connection: Connection, walletPk: PublicKey) => void
|
||||
fetchProfilePicture: (wallet: Wallet) => void
|
||||
fetchProfilePicture: (wallet: AnchorWallet) => void
|
||||
fetchJupiterTokens: () => Promise<void>
|
||||
fetchTradeHistory: (mangoAccountPk: string) => Promise<void>
|
||||
fetchWalletTokens: (wallet: Wallet) => Promise<void>
|
||||
fetchWalletTokens: (wallet: AnchorWallet) => Promise<void>
|
||||
handleWalletConnect: (wallet: Wallet) => Promise<void>
|
||||
reloadAccount: () => Promise<void>
|
||||
reloadGroup: () => Promise<void>
|
||||
loadSerumMarket: () => Promise<void>
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -175,8 +187,8 @@ const mangoStore = create<MangoStore>(
|
|||
serumOrders: undefined,
|
||||
set: (fn) => set(produce(fn)),
|
||||
swap: {
|
||||
inputToken: 'USDC',
|
||||
outputToken: 'SOL',
|
||||
inputBank: undefined,
|
||||
outputBank: undefined,
|
||||
inputTokenInfo: undefined,
|
||||
outputTokenInfo: undefined,
|
||||
margin: true,
|
||||
|
@ -301,15 +313,8 @@ const mangoStore = create<MangoStore>(
|
|||
const client = get().client
|
||||
const group = await client.getGroup(GROUP)
|
||||
|
||||
const markets = await client.serum3GetMarkets(
|
||||
group,
|
||||
group.banksMap.get('BTC')?.tokenIndex,
|
||||
group.banksMap.get('USDC')?.tokenIndex
|
||||
)
|
||||
|
||||
set((state) => {
|
||||
state.group = group
|
||||
state.markets = markets
|
||||
})
|
||||
} catch (e) {
|
||||
console.error('Error fetching group', e)
|
||||
|
@ -319,27 +324,9 @@ const mangoStore = create<MangoStore>(
|
|||
const set = get().set
|
||||
try {
|
||||
const group = get().group
|
||||
const client = get().client
|
||||
if (!group) throw new Error('Group not loaded')
|
||||
|
||||
const provider = new AnchorProvider(connection, wallet, options)
|
||||
provider.opts.skipPreflight = true
|
||||
const client = await MangoClient.connect(
|
||||
provider,
|
||||
CLUSTER,
|
||||
MANGO_V4_ID[CLUSTER],
|
||||
{
|
||||
prioritizationFee: 2,
|
||||
postSendTxCallback: ({ txid }: { txid: string }) => {
|
||||
notify({
|
||||
title: 'Transaction sent',
|
||||
description: 'Waiting for confirmation',
|
||||
type: 'confirm',
|
||||
txid: txid,
|
||||
})
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
const mangoAccount = await client.getMangoAccountForOwner(
|
||||
group,
|
||||
wallet.publicKey,
|
||||
|
@ -355,11 +342,8 @@ const mangoStore = create<MangoStore>(
|
|||
await mangoAccount.reloadAccountData(client, group)
|
||||
}
|
||||
set((state) => {
|
||||
state.client = client
|
||||
state.mangoAccount.current = mangoAccount
|
||||
state.mangoAccount.loading = false
|
||||
state.connected = true
|
||||
// state.serumOrders = orders
|
||||
})
|
||||
} catch (e) {
|
||||
set((state) => {
|
||||
|
@ -443,7 +427,7 @@ const mangoStore = create<MangoStore>(
|
|||
})
|
||||
}
|
||||
},
|
||||
fetchWalletTokens: async (wallet: Wallet) => {
|
||||
fetchWalletTokens: async (wallet: AnchorWallet) => {
|
||||
const set = get().set
|
||||
const connection = get().connection
|
||||
|
||||
|
@ -471,8 +455,8 @@ const mangoStore = create<MangoStore>(
|
|||
)
|
||||
return
|
||||
}
|
||||
const bankMints = Array.from(group.banksMap.values()).map((b) =>
|
||||
b.mint.toString()
|
||||
const bankMints = Array.from(group.banksMapByName.values()).map((b) =>
|
||||
b[0].mint.toString()
|
||||
)
|
||||
|
||||
fetch(TOKEN_LIST_URL[CLUSTER])
|
||||
|
@ -482,10 +466,10 @@ const mangoStore = create<MangoStore>(
|
|||
bankMints.includes(t.address)
|
||||
)
|
||||
const inputTokenInfo = groupTokens.find(
|
||||
(t: any) => t.symbol === 'SOL'
|
||||
(t: any) => t.symbol === INPUT_TOKEN_DEFAULT
|
||||
)
|
||||
const outputTokenInfo = groupTokens.find(
|
||||
(t: any) => t.symbol === 'USDC'
|
||||
(t: any) => t.symbol === OUTPUT_TOKEN_DEFAULT
|
||||
)
|
||||
set((s) => {
|
||||
s.swap.inputTokenInfo = inputTokenInfo
|
||||
|
@ -494,6 +478,50 @@ const mangoStore = create<MangoStore>(
|
|||
})
|
||||
})
|
||||
},
|
||||
handleWalletConnect: async (wallet: Wallet) => {
|
||||
if (!wallet) {
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
await wallet?.adapter?.connect()
|
||||
|
||||
const provider = new AnchorProvider(
|
||||
connection,
|
||||
wallet as unknown as AnchorWallet,
|
||||
options
|
||||
)
|
||||
provider.opts.skipPreflight = true
|
||||
const client = await MangoClient.connect(
|
||||
provider,
|
||||
CLUSTER,
|
||||
MANGO_V4_ID[CLUSTER],
|
||||
{
|
||||
prioritizationFee: 2,
|
||||
postSendTxCallback: ({ txid }: { txid: string }) => {
|
||||
notify({
|
||||
title: 'Transaction sent',
|
||||
description: 'Waiting for confirmation',
|
||||
type: 'confirm',
|
||||
txid: txid,
|
||||
})
|
||||
},
|
||||
}
|
||||
)
|
||||
set((s) => {
|
||||
s.client = client
|
||||
s.connected = true
|
||||
})
|
||||
} catch (e: any) {
|
||||
if (e.name.includes('WalletLoadError')) {
|
||||
notify({
|
||||
title: `${wallet.adapter.name} Error`,
|
||||
type: 'error',
|
||||
description: `Please install ${wallet.adapter.name} and then reload this page.`,
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
reloadGroup: async () => {
|
||||
try {
|
||||
const set = get().set
|
||||
|
@ -527,26 +555,7 @@ const mangoStore = create<MangoStore>(
|
|||
console.error('Error reloading mango account')
|
||||
}
|
||||
},
|
||||
loadSerumMarket: async () => {
|
||||
const set = get().set
|
||||
const client = get().client
|
||||
const group = get().group
|
||||
if (!group) return
|
||||
|
||||
const markets = await client.serum3GetMarkets(
|
||||
group,
|
||||
group.banksMap.get('BTC')?.tokenIndex,
|
||||
group.banksMap.get('USDC')?.tokenIndex
|
||||
)
|
||||
|
||||
let orders = await client.getSerum3Orders(group, 'BTC/USDC')
|
||||
|
||||
set((state) => {
|
||||
state.markets = markets
|
||||
state.serumOrders = orders
|
||||
})
|
||||
},
|
||||
async fetchProfilePicture(wallet: Wallet) {
|
||||
async fetchProfilePicture(wallet: AnchorWallet) {
|
||||
const set = get().set
|
||||
const walletPk = wallet?.publicKey
|
||||
const connection = get().connection
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
import { Wallet } from '@project-serum/anchor'
|
||||
import { Wallet as WalletAdapter } from '@solana/wallet-adapter-react'
|
||||
import { Keypair, PublicKey, Transaction } from '@solana/web3.js'
|
||||
import { notify } from './notifications'
|
||||
|
||||
export default class EmptyWallet implements Wallet {
|
||||
constructor(readonly payer: Keypair) {}
|
||||
|
@ -22,19 +20,3 @@ export default class EmptyWallet implements Wallet {
|
|||
return this.payer.publicKey
|
||||
}
|
||||
}
|
||||
|
||||
export const handleWalletConnect = (wallet: WalletAdapter) => {
|
||||
if (!wallet) {
|
||||
return
|
||||
}
|
||||
|
||||
wallet?.adapter?.connect().catch((e) => {
|
||||
if (e.name.includes('WalletLoadError')) {
|
||||
notify({
|
||||
title: `${wallet.adapter.name} Error`,
|
||||
type: 'error',
|
||||
description: `Please install ${wallet.adapter.name} and then reload this page.`,
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
|
||||
"@blockworks-foundation/mango-v4@git+https://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:x-oauth-basic@github.com/blockworks-foundation/mango-v4.git#main":
|
||||
version "0.0.1-beta.1"
|
||||
resolved "git+https://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:x-oauth-basic@github.com/blockworks-foundation/mango-v4.git#3c06b718c6faaee861fdbc734399aa72547e8a5c"
|
||||
resolved "git+https://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:x-oauth-basic@github.com/blockworks-foundation/mango-v4.git#f40f33f3b35a8c18e1a74a9db2cca1b73faafa9b"
|
||||
dependencies:
|
||||
"@project-serum/anchor" "^0.25.0"
|
||||
"@project-serum/serum" "^0.13.65"
|
||||
|
@ -1195,9 +1195,9 @@
|
|||
integrity sha512-/THyiqyQAP9AfARo4pF+aCGcyiQ94tX/Is2I7HofNRqoYLgN1PBoOWu2/zTA5zMxzP5EFutMtWtGAFRKUe961Q==
|
||||
|
||||
"@types/node@*":
|
||||
version "18.7.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.7.5.tgz#f1c1d4b7d8231c0278962347163656f9c36f3e83"
|
||||
integrity sha512-NcKK6Ts+9LqdHJaW6HQmgr7dT/i3GOHG+pt6BiWv++5SnjtRd4NXeiuN2kA153SjhXPR/AhHIPHPbrsbpUVOww==
|
||||
version "18.7.6"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.7.6.tgz#31743bc5772b6ac223845e18c3fc26f042713c83"
|
||||
integrity sha512-EdxgKRXgYsNITy5mjjXjVE/CS8YENSdhiagGrLqjG0pvA2owgJ6i4l7wy/PFZGC0B1/H20lWKN7ONVDNYDZm7A==
|
||||
|
||||
"@types/node@17.0.23":
|
||||
version "17.0.23"
|
||||
|
|
Loading…
Reference in New Issue