more cleanup and add txid link when transaction error
This commit is contained in:
parent
329a2cd302
commit
d239416364
|
@ -48,6 +48,7 @@ const BalancesTable = () => {
|
|||
notify({
|
||||
message: 'Error settling funds',
|
||||
description: e.message,
|
||||
txid: e.txid,
|
||||
type: 'error',
|
||||
})
|
||||
}
|
||||
|
|
|
@ -85,6 +85,7 @@ const DepositModal = ({ isOpen, onClose }) => {
|
|||
message:
|
||||
'Could not perform init margin account and deposit operation',
|
||||
type: 'error',
|
||||
txid: err.txid
|
||||
})
|
||||
onClose()
|
||||
})
|
||||
|
@ -112,6 +113,7 @@ const DepositModal = ({ isOpen, onClose }) => {
|
|||
notify({
|
||||
message: 'Could not perform deposit operation',
|
||||
type: 'error',
|
||||
txid: err.txid
|
||||
})
|
||||
onClose()
|
||||
})
|
||||
|
|
|
@ -1,137 +0,0 @@
|
|||
import React, { useMemo, useState } from 'react'
|
||||
import { nativeToUi } from '@blockworks-foundation/mango-client/lib/utils'
|
||||
import Modal from './Modal'
|
||||
import AccountSelect from './AccountSelect'
|
||||
import useMangoStore from '../stores/useMangoStore'
|
||||
import useConnection from '../hooks/useConnection'
|
||||
import { depositSrm } from '../utils/mango'
|
||||
import { PublicKey } from '@solana/web3.js'
|
||||
import Loading from './Loading'
|
||||
import Button from './Button'
|
||||
import { ElementTitle } from './styles'
|
||||
import Input from './Input'
|
||||
import { notify } from '../utils/notifications'
|
||||
import { SRM_DECIMALS } from '@project-serum/serum/lib/token-instructions'
|
||||
import { floorToDecimal, sleep } from '../utils'
|
||||
|
||||
const DepositSrmModal = ({ isOpen, onClose }) => {
|
||||
const [inputAmount, setInputAmount] = useState('')
|
||||
const [submitting, setSubmitting] = useState(false)
|
||||
const { connection, programId } = useConnection()
|
||||
const walletAccounts = useMangoStore((s) => s.wallet.balances)
|
||||
const actions = useMangoStore((s) => s.actions)
|
||||
const srmMintAddress = useMangoStore((s) => s.connection.srmMint)
|
||||
const mangoSrmAccountsForOwner = useMangoStore(
|
||||
(s) => s.wallet.srmAccountsForOwner
|
||||
)
|
||||
const depositAccounts = useMemo(
|
||||
() =>
|
||||
walletAccounts.filter(
|
||||
(acc) => srmMintAddress === acc.account.mint.toString()
|
||||
),
|
||||
[walletAccounts, srmMintAddress]
|
||||
)
|
||||
const [selectedAccount, setSelectedAccount] = useState(depositAccounts[0])
|
||||
|
||||
// TODO: remove duplication in AccountSelect
|
||||
const getBalanceForAccount = (account) => {
|
||||
const balance = nativeToUi(account?.account?.amount, SRM_DECIMALS)
|
||||
|
||||
return floorToDecimal(balance, SRM_DECIMALS).toString()
|
||||
}
|
||||
|
||||
const setMaxForSelectedAccount = () => {
|
||||
const max = getBalanceForAccount(selectedAccount)
|
||||
setInputAmount(max)
|
||||
}
|
||||
|
||||
const handleDeposit = () => {
|
||||
setSubmitting(true)
|
||||
const marginAccount = useMangoStore.getState().selectedMarginAccount.current
|
||||
const mangoGroup = useMangoStore.getState().selectedMangoGroup.current
|
||||
const wallet = useMangoStore.getState().wallet.current
|
||||
if (marginAccount && mangoGroup) {
|
||||
depositSrm(
|
||||
connection,
|
||||
new PublicKey(programId),
|
||||
mangoGroup,
|
||||
wallet,
|
||||
selectedAccount.publicKey,
|
||||
Number(inputAmount),
|
||||
mangoSrmAccountsForOwner?.length
|
||||
? mangoSrmAccountsForOwner[0].publicKey
|
||||
: undefined
|
||||
)
|
||||
.then(async (_mangoSrmAcct: PublicKey) => {
|
||||
setSubmitting(false)
|
||||
onClose()
|
||||
await sleep(500)
|
||||
actions.fetchWalletBalances()
|
||||
actions.fetchMangoSrmAccounts()
|
||||
actions.fetchMangoGroup()
|
||||
})
|
||||
.catch((err) => {
|
||||
setSubmitting(false)
|
||||
console.error(err)
|
||||
notify({
|
||||
message: 'Could not perform SRM deposit operation',
|
||||
description: '',
|
||||
type: 'error',
|
||||
})
|
||||
onClose()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Modal isOpen={isOpen} onClose={onClose}>
|
||||
<Modal.Header>
|
||||
<div className={`text-th-fgd-3 flex-shrink invisible w-5`}>X</div>
|
||||
<ElementTitle noMarignBottom>Contribute SRM</ElementTitle>
|
||||
</Modal.Header>
|
||||
<>
|
||||
<AccountSelect
|
||||
symbols={{ SRM: srmMintAddress }}
|
||||
accounts={depositAccounts}
|
||||
selectedAccount={selectedAccount}
|
||||
onSelectAccount={setSelectedAccount}
|
||||
/>
|
||||
<div className="flex justify-between pb-2 pt-4">
|
||||
<div className={`text-th-fgd-1`}>Amount</div>
|
||||
<div
|
||||
className="text-th-fgd-1 underline cursor-pointer default-transition hover:text-th-primary hover:no-underline"
|
||||
onClick={setMaxForSelectedAccount}
|
||||
>
|
||||
Max
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center">
|
||||
<Input
|
||||
type="number"
|
||||
min="0"
|
||||
className={`border border-th-fgd-4 flex-grow pr-11`}
|
||||
placeholder="0.00"
|
||||
value={inputAmount}
|
||||
onChange={(e) => setInputAmount(e.target.value)}
|
||||
suffix="SRM"
|
||||
/>
|
||||
</div>
|
||||
<div className={`mt-5 flex justify-center`}>
|
||||
<Button
|
||||
onClick={handleDeposit}
|
||||
className="w-full"
|
||||
disabled={!selectedAccount}
|
||||
>
|
||||
<div className={`flex items-center justify-center`}>
|
||||
{submitting && <Loading className="-ml-1 mr-3" />}
|
||||
{`Deposit ${inputAmount ? inputAmount : ''} SRM
|
||||
`}
|
||||
</div>
|
||||
</Button>
|
||||
</div>
|
||||
</>
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
|
||||
export default React.memo(DepositSrmModal)
|
|
@ -76,6 +76,7 @@ const Notification = ({ type, message, description, txid }) => {
|
|||
<a
|
||||
href={'https://explorer.solana.com/tx/' + txid}
|
||||
className="text-th-primary"
|
||||
target="_blank"
|
||||
>
|
||||
View transaction {txid.slice(0, 8)}...
|
||||
{txid.slice(txid.length - 8)}
|
||||
|
|
|
@ -40,6 +40,7 @@ const OpenOrdersTable = () => {
|
|||
notify({
|
||||
message: 'Error cancelling order',
|
||||
description: e.message,
|
||||
txid: e.txid,
|
||||
type: 'error',
|
||||
})
|
||||
return
|
||||
|
|
|
@ -193,6 +193,7 @@ export default function TradeForm() {
|
|||
notify({
|
||||
message: 'Error placing order',
|
||||
description: e.message,
|
||||
txid: e.txid,
|
||||
type: 'error',
|
||||
})
|
||||
} finally {
|
||||
|
|
|
@ -179,7 +179,7 @@ const WithdrawModal = ({ isOpen, onClose }) => {
|
|||
console.warn('Error withdrawing:', err)
|
||||
notify({
|
||||
message: 'Could not perform withdraw',
|
||||
description: `${err}`,
|
||||
txid: err.txid,
|
||||
type: 'error',
|
||||
})
|
||||
onClose()
|
||||
|
@ -208,6 +208,7 @@ const WithdrawModal = ({ isOpen, onClose }) => {
|
|||
notify({
|
||||
message: 'Could not perform borrow and withdraw',
|
||||
description: `${err}`,
|
||||
txid: err.txid,
|
||||
type: 'error',
|
||||
})
|
||||
onClose()
|
||||
|
|
|
@ -1,132 +0,0 @@
|
|||
import React, { useMemo, useState } from 'react'
|
||||
import Modal from './Modal'
|
||||
import MangoSrmAccountSelector from './MangoSrmAccountSelector'
|
||||
import useMangoStore from '../stores/useMangoStore'
|
||||
import useConnection from '../hooks/useConnection'
|
||||
import { withdrawSrm } from '../utils/mango'
|
||||
import Loading from './Loading'
|
||||
import Button from './Button'
|
||||
import { ElementTitle } from './styles'
|
||||
import Input from './Input'
|
||||
import { notify } from '../utils/notifications'
|
||||
import { SRM_DECIMALS } from '@project-serum/serum/lib/token-instructions'
|
||||
import { PublicKey } from '@solana/web3.js'
|
||||
import { sleep } from '../utils'
|
||||
|
||||
const WithdrawModal = ({ isOpen, onClose }) => {
|
||||
const [inputAmount, setInputAmount] = useState('')
|
||||
const [submitting, setSubmitting] = useState(false)
|
||||
const { connection, programId } = useConnection()
|
||||
const walletAccounts = useMangoStore((s) => s.wallet.balances)
|
||||
const actions = useMangoStore((s) => s.actions)
|
||||
const srmMintAddress = useMangoStore((s) => s.connection.srmMint)
|
||||
const contributedSrm = useMangoStore((s) => s.wallet.contributedSrm)
|
||||
const mangoSrmAccountsForOwner = useMangoStore(
|
||||
(s) => s.wallet.srmAccountsForOwner
|
||||
)
|
||||
const walletSrmAccount = useMemo(
|
||||
() =>
|
||||
walletAccounts.find(
|
||||
(acc) => srmMintAddress === acc.account.mint.toString()
|
||||
),
|
||||
[walletAccounts, srmMintAddress]
|
||||
)
|
||||
const [selectedAccount, setSelectedAccount] = useState(
|
||||
mangoSrmAccountsForOwner[0]
|
||||
)
|
||||
|
||||
const withdrawDisabled = Number(inputAmount) <= 0
|
||||
|
||||
const setMaxForSelectedAccount = () => {
|
||||
setInputAmount(contributedSrm.toFixed(SRM_DECIMALS))
|
||||
}
|
||||
|
||||
const handleWithdraw = () => {
|
||||
setSubmitting(true)
|
||||
const marginAccount = useMangoStore.getState().selectedMarginAccount.current
|
||||
const mangoGroup = useMangoStore.getState().selectedMangoGroup.current
|
||||
const wallet = useMangoStore.getState().wallet.current
|
||||
if (marginAccount && mangoGroup) {
|
||||
withdrawSrm(
|
||||
connection,
|
||||
new PublicKey(programId),
|
||||
mangoGroup,
|
||||
selectedAccount,
|
||||
wallet,
|
||||
walletSrmAccount.publicKey,
|
||||
Number(inputAmount)
|
||||
)
|
||||
.then(async (_transSig: string) => {
|
||||
setSubmitting(false)
|
||||
onClose()
|
||||
await sleep(500)
|
||||
actions.fetchWalletBalances()
|
||||
actions.fetchMangoSrmAccounts()
|
||||
actions.fetchMangoGroup()
|
||||
})
|
||||
.catch((err) => {
|
||||
setSubmitting(false)
|
||||
console.warn('Error withdrawing:', err)
|
||||
notify({
|
||||
message: 'Could not perform withdraw operation',
|
||||
description: `${err}`,
|
||||
type: 'error',
|
||||
})
|
||||
onClose()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Modal isOpen={isOpen} onClose={onClose}>
|
||||
<Modal.Header>
|
||||
{/* not sure what the below div os for? */}
|
||||
<div className={`text-th-fgd-3 flex-shrink invisible w-5`}>X</div>
|
||||
<ElementTitle noMarignBottom>Withdraw SRM</ElementTitle>
|
||||
</Modal.Header>
|
||||
<>
|
||||
<div className={`text-th-fgd-1 pb-2`}>Token Account</div>
|
||||
<MangoSrmAccountSelector
|
||||
accounts={mangoSrmAccountsForOwner}
|
||||
selectedAccount={selectedAccount}
|
||||
onSelectAccount={setSelectedAccount}
|
||||
/>
|
||||
<div className="flex justify-between pb-2 pt-4">
|
||||
<div className={`text-th-fgd-1`}>Amount</div>
|
||||
<div
|
||||
className="text-th-fgd-1 underline cursor-pointer default-transition hover:text-th-primary hover:no-underline"
|
||||
onClick={setMaxForSelectedAccount}
|
||||
>
|
||||
Max
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center">
|
||||
<Input
|
||||
type="number"
|
||||
min="0"
|
||||
className={`border border-th-fgd-4 flex-grow pr-11`}
|
||||
placeholder="0.00"
|
||||
value={inputAmount}
|
||||
onChange={(e) => setInputAmount(e.target.value)}
|
||||
suffix="SRM"
|
||||
/>
|
||||
</div>
|
||||
<div className={`mt-5 flex justify-center`}>
|
||||
<Button
|
||||
onClick={handleWithdraw}
|
||||
disabled={withdrawDisabled}
|
||||
className="w-full"
|
||||
>
|
||||
<div className={`flex items-center justify-center`}>
|
||||
{submitting && <Loading className="-ml-1 mr-3" />}
|
||||
{`Withdraw ${inputAmount ? inputAmount : ''} SRM
|
||||
`}
|
||||
</div>
|
||||
</Button>
|
||||
</div>
|
||||
</>
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
|
||||
export default React.memo(WithdrawModal)
|
|
@ -16,6 +16,14 @@ import { Buffer } from 'buffer'
|
|||
import assert from 'assert'
|
||||
import { struct } from 'superstruct'
|
||||
|
||||
class TransactionError extends Error {
|
||||
public txid: string;
|
||||
constructor (message: string, txid?: string) {
|
||||
super(message);
|
||||
this.txid = txid;
|
||||
}
|
||||
}
|
||||
|
||||
export const getUnixTs = () => {
|
||||
return new Date().getTime() / 1000
|
||||
}
|
||||
|
@ -153,15 +161,22 @@ export async function sendSignedTransaction({
|
|||
for (let i = simulateResult.logs.length - 1; i >= 0; --i) {
|
||||
const line = simulateResult.logs[i]
|
||||
if (line.startsWith('Program log: ')) {
|
||||
throw new Error(
|
||||
'Transaction failed: ' + line.slice('Program log: '.length)
|
||||
throw new TransactionError(
|
||||
'Transaction failed: ' + line.slice('Program log: '.length),
|
||||
txid
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new Error(JSON.stringify(simulateResult.err))
|
||||
throw new TransactionError(
|
||||
JSON.stringify(simulateResult.err),
|
||||
txid
|
||||
)
|
||||
}
|
||||
throw new Error('Transaction failed')
|
||||
throw new TransactionError(
|
||||
'Transaction failed',
|
||||
txid
|
||||
)
|
||||
} finally {
|
||||
done = true
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue