mango-v4-ui/components/modals/SecurityCouncilModal.tsx

237 lines
6.8 KiB
TypeScript
Raw Normal View History

2024-04-04 03:11:35 -07:00
import { useCallback, useState } from 'react'
import { ModalProps } from '../../types/modal'
import Modal from '../shared/Modal'
import mangoStore from '@store/mangoStore'
import { useWallet } from '@solana/wallet-adapter-react'
import { Bank, Group } from '@blockworks-foundation/mango-v4'
import { AccountMeta, PublicKey, Transaction } from '@solana/web3.js'
import {
MANGO_DAO_SECURITY_WALLET_GOVERNANCE,
MANGO_GOVERNANCE_PROGRAM,
MANGO_SECURITY_COUNCIL_MINT,
MANGO_SECURITY_COUNCIL_WALLET,
MANGO_SECURITY_REALM_PK,
} from 'utils/governance/constants'
import { createProposal } from 'utils/governance/instructions/createProposal'
import { notify } from 'utils/notifications'
import Button from '@components/shared/Button'
import { getAllProposals } from '@solana/spl-governance'
import useSecurityCouncilDao from 'hooks/useSecurityCouncilDao'
import Loading from '@components/shared/Loading'
import Select from '@components/forms/Select'
import { abbreviateAddress } from 'utils/formatting'
const SecurityCouncilModal = ({
isOpen,
onClose,
bank,
group,
}: ModalProps & {
bank: Bank
group: Group
}) => {
const client = mangoStore((s) => s.client)
//do not deconstruct wallet is used for anchor to sign
const wallet = useWallet()
const connection = mangoStore((s) => s.connection)
const fee = mangoStore((s) => s.priorityFee)
const { queries, currentDelegate, setDelegate, currentVoter } =
useSecurityCouncilDao()
const [proposing, setProposing] = useState(false)
2024-04-04 05:18:18 -07:00
//2 no borrows
2024-04-04 03:11:35 -07:00
//1 no borrows no deposits
const proposeEdit = useCallback(
async (bank: Bank, mode: number | null, initAssetWeight: number | null) => {
2024-04-04 03:11:35 -07:00
if (!currentVoter) {
notify({
type: 'error',
description: 'No vote record found',
title: 'No vote record found',
})
}
const mintInfo = group!.mintInfosMapByTokenIndex.get(bank.tokenIndex)!
setProposing(true)
const proposalTx = []
const walletSigner = wallet as never
const ix = await client!.program.methods
.tokenEdit(
null,
null,
null,
null,
null,
null,
null,
initAssetWeight,
2024-04-04 03:11:35 -07:00
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
false,
false,
mode,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
false,
false,
null,
null,
null,
null,
null,
null,
)
.accounts({
group: group!.publicKey,
oracle: bank.oracle,
admin: MANGO_SECURITY_COUNCIL_WALLET,
mintInfo: mintInfo.publicKey,
fallbackOracle: bank.fallbackOracle,
})
.remainingAccounts([
{
pubkey: bank.publicKey,
isWritable: true,
isSigner: false,
} as AccountMeta,
])
.instruction()
proposalTx.push(ix)
try {
setProposing(true)
const simTransaction = new Transaction({ feePayer: wallet.publicKey })
simTransaction.add(...proposalTx)
const simulation = await connection.simulateTransaction(simTransaction)
2024-04-04 03:11:35 -07:00
if (!simulation.value.err) {
const proposals = await getAllProposals(
connection,
MANGO_GOVERNANCE_PROGRAM,
MANGO_SECURITY_REALM_PK,
)
const index = proposals ? Object.values(proposals).length : 0
const proposalAddress = await createProposal(
connection,
client,
walletSigner,
MANGO_DAO_SECURITY_WALLET_GOVERNANCE,
currentVoter!,
`Edit ${bank.name} token`,
'',
index,
proposalTx,
null,
fee,
MANGO_SECURITY_COUNCIL_MINT,
MANGO_SECURITY_REALM_PK,
)
window.open(
`https://dao.mango.markets/dao/AQbsV8b3Yv3UHUmd62hw9vFmNTHgBTdiLfaWzwmVfXB2/proposal/${proposalAddress.toBase58()}`,
'_blank',
)
} else {
throw simulation.value.logs
}
} catch (e) {
console.log(e)
notify({
title: 'Error during proposal creation',
description: `${e}`,
type: 'error',
})
}
setProposing(false)
},
[client, connection, currentVoter, fee, group, wallet],
)
return (
<Modal
panelClassNames="!max-w-[300px] min-h-[300px]"
isOpen={isOpen}
onClose={onClose}
>
<h3 className="mb-6">Token: {bank.name}</h3>
{queries.data?.delegatedAccounts.length ? (
<div className="flex items-start">
<p className="mr-2">delegate</p>
<Select
value={
currentDelegate
? abbreviateAddress(
new PublicKey(
queries.data.delegatedAccounts.find(
(x) => x.pubkey.toBase58() === currentDelegate,
)!.account.governingTokenOwner!,
),
)
: 'none'
}
onChange={(selected) => {
setDelegate(selected)
}}
className="w-full"
>
<Select.Option value={''}>
<div className="flex w-full items-center justify-between">
none
</div>
</Select.Option>
{queries.data.delegatedAccounts.map((x) => (
<Select.Option
key={x.pubkey.toBase58()}
value={x.pubkey.toBase58()}
>
<div className="flex w-full items-center justify-between">
{abbreviateAddress(x.account.governingTokenOwner)}
</div>
</Select.Option>
))}
</Select>
</div>
) : null}
<div className="mt-6 space-y-3">
<Button onClick={() => proposeEdit(bank, 1, null)} disabled={proposing}>
2024-04-04 03:11:35 -07:00
{proposing ? (
<Loading className="w-5"></Loading>
) : (
'No borrows no deposits'
)}
</Button>
<Button onClick={() => proposeEdit(bank, 2, null)} disabled={proposing}>
2024-04-04 03:11:35 -07:00
{proposing ? <Loading className="w-5"></Loading> : 'No borrows'}
</Button>
<Button onClick={() => proposeEdit(bank, null, 0)} disabled={proposing}>
{proposing ? (
<Loading className="w-5"></Loading>
) : (
'0 init asset weight'
)}
</Button>
2024-04-04 03:11:35 -07:00
</div>
</Modal>
)
}
export default SecurityCouncilModal