diff --git a/HeliumVotePlugin/components/LockTokensAccount.tsx b/HeliumVotePlugin/components/LockTokensAccount.tsx
index c3bb1450f6..882ca86e15 100644
--- a/HeliumVotePlugin/components/LockTokensAccount.tsx
+++ b/HeliumVotePlugin/components/LockTokensAccount.tsx
@@ -401,7 +401,6 @@ export const LockTokensAccount: React.FC<{
diff --git a/HeliumVotePlugin/components/VotingPowerCard.tsx b/HeliumVotePlugin/components/VotingPowerCard.tsx
index 3b20531b05..78fc7167e8 100644
--- a/HeliumVotePlugin/components/VotingPowerCard.tsx
+++ b/HeliumVotePlugin/components/VotingPowerCard.tsx
@@ -63,7 +63,6 @@ export const VotingPowerCard: React.FC<{
diff --git a/VoteStakeRegistry/components/Account/LockTokensAccount.tsx b/VoteStakeRegistry/components/Account/LockTokensAccount.tsx
index c486b37120..e8c56a3b29 100644
--- a/VoteStakeRegistry/components/Account/LockTokensAccount.tsx
+++ b/VoteStakeRegistry/components/Account/LockTokensAccount.tsx
@@ -415,7 +415,6 @@ const LockTokensAccount: React.FC<{
diff --git a/VoteStakeRegistry/components/Account/LockTokensAccountWithdraw.tsx b/VoteStakeRegistry/components/Account/LockTokensAccountWithdraw.tsx
index 8a97d2a872..c0a4c58665 100644
--- a/VoteStakeRegistry/components/Account/LockTokensAccountWithdraw.tsx
+++ b/VoteStakeRegistry/components/Account/LockTokensAccountWithdraw.tsx
@@ -438,7 +438,6 @@ const LockTokensAccount = ({ tokenOwnerRecordPk }) => {
diff --git a/VoteStakeRegistry/components/TokenBalance/LockPluginTokenBalanceCard.tsx b/VoteStakeRegistry/components/TokenBalance/LockPluginTokenBalanceCard.tsx
index 77cd8bcfbe..4435986393 100644
--- a/VoteStakeRegistry/components/TokenBalance/LockPluginTokenBalanceCard.tsx
+++ b/VoteStakeRegistry/components/TokenBalance/LockPluginTokenBalanceCard.tsx
@@ -133,7 +133,6 @@ const LockPluginTokenBalanceCard = ({
diff --git a/components/GovernancePower/GovernancePowerForRole.tsx b/components/GovernancePower/GovernancePowerForRole.tsx
index 6b627cbc9f..1ef1b12f89 100644
--- a/components/GovernancePower/GovernancePowerForRole.tsx
+++ b/components/GovernancePower/GovernancePowerForRole.tsx
@@ -3,15 +3,14 @@ import { useAsync } from 'react-async-hook'
import { determineVotingPowerType } from '@hooks/queries/governancePower'
import { useConnection } from '@solana/wallet-adapter-react'
import useSelectedRealmPubkey from '@hooks/selectedRealm/useSelectedRealmPubkey'
-import LockedCommunityVotingPower from '@components/ProposalVotingPower/LockedCommunityVotingPower'
import NftVotingPower from '@components/ProposalVotingPower/NftVotingPower'
import LockedCommunityNFTRecordVotingPower from '@components/ProposalVotingPower/LockedCommunityNFTRecordVotingPower'
import VanillaVotingPower from './Vanilla/VanillaVotingPower'
import { Deposit } from './Vanilla/Deposit'
import { useUserCommunityTokenOwnerRecord } from '@hooks/queries/tokenOwnerRecord'
import { ExclamationIcon } from '@heroicons/react/solid'
-import { VSR_PLUGIN_PKS } from '@constants/plugins'
-import { useRealmConfigQuery } from '@hooks/queries/realmConfig'
+import VanillaWithdrawTokensButton from '@components/TokenBalance/VanillaWithdrawTokensButton'
+import LockedCommunityVotingPower from '@components/ProposalVotingPower/LockedCommunityVotingPower'
export default function GovernancePowerForRole({
role,
@@ -23,16 +22,11 @@ export default function GovernancePowerForRole({
}) {
const { connection } = useConnection()
const realmPk = useSelectedRealmPubkey()
- const config = useRealmConfigQuery().data?.result
const ownTokenRecord = useUserCommunityTokenOwnerRecord().data?.result
- //if dao transited to use plugin and some users have still deposited tokens they should withdraw before
+
+ //VSR if dao transited to use plugin and some users have still deposited tokens they should withdraw before
//depositing to plugin
- const isVsr =
- config?.account?.communityTokenConfig?.voterWeightAddin &&
- VSR_PLUGIN_PKS.includes(
- config?.account?.communityTokenConfig?.voterWeightAddin?.toBase58()
- )
const didWithdrawFromVanillaSetup =
!ownTokenRecord ||
ownTokenRecord.account.governingTokenDepositAmount.isZero()
@@ -42,10 +36,8 @@ export default function GovernancePowerForRole({
const { result: kind } = useAsync(async () => {
if (realmPk === undefined) return undefined
- return didWithdrawFromVanillaSetup
- ? determineVotingPowerType(connection, realmPk, role)
- : 'vanilla'
- }, [connection, realmPk, role, didWithdrawFromVanillaSetup])
+ return determineVotingPowerType(connection, realmPk, role)
+ }, [connection, realmPk, role])
if (connected && kind === undefined && !props.hideIfZero) {
return (
@@ -60,16 +52,28 @@ export default function GovernancePowerForRole({
- {isVsr && !didWithdrawFromVanillaSetup && (
-
-
- Please withdraw your tokens and deposit again to get governance
- power
-
- )}
) : kind === 'VSR' ? (
-
+ didWithdrawFromVanillaSetup ? (
+
+ ) : (
+ //TODO make a better generic little prompt for when a plugin is used but there are still tokens in vanilla
+ <>
+
+
+
+
+
+ Please withdraw your tokens and deposit again to get
+ governance power
+
+
+
+
+
+
+ >
+ )
) : kind === 'NFT' ? (
) : kind === 'HeliumVSR' ? (
diff --git a/components/TokenBalance/TokenDeposit.tsx b/components/TokenBalance/TokenDeposit.tsx
index ac8cc76d0e..6b4a9ebc01 100644
--- a/components/TokenBalance/TokenDeposit.tsx
+++ b/components/TokenBalance/TokenDeposit.tsx
@@ -1,34 +1,11 @@
-import {
- ASSOCIATED_TOKEN_PROGRAM_ID,
- MintInfo,
- Token,
- TOKEN_PROGRAM_ID,
-} from '@solana/spl-token'
-import { PublicKey, Transaction, TransactionInstruction } from '@solana/web3.js'
+import { MintInfo } from '@solana/spl-token'
import BN from 'bn.js'
import useRealm from '@hooks/useRealm'
-import {
- getProposal,
- GoverningTokenType,
- ProposalState,
-} from '@solana/spl-governance'
-import { getUnrelinquishedVoteRecords } from '@models/api'
-import { withRelinquishVote } from '@solana/spl-governance'
-import { withWithdrawGoverningTokens } from '@solana/spl-governance'
-import { sendTransaction } from '@utils/send'
-import { SecondaryButton } from '../Button'
+import { GoverningTokenType } from '@solana/spl-governance'
import { GoverningTokenRole } from '@solana/spl-governance'
import { fmtMintAmount } from '@tools/sdk/units'
import { getMintMetadata } from '../instructions/programs/splToken'
-import { withFinalizeVote } from '@solana/spl-governance'
-import { chunks } from '@utils/helpers'
-import { getProgramVersionForRealm } from '@models/registry/api'
-import { notify } from '@utils/notifications'
-import { ExclamationIcon } from '@heroicons/react/outline'
import { useEffect } from 'react'
-import useVotePluginsClientStore from 'stores/useVotePluginsClientStore'
-import { VSR_PLUGIN_PKS } from '@constants/plugins'
-import { useMaxVoteRecord } from '@hooks/useMaxVoteRecord'
import useWalletOnePointOh from '@hooks/useWalletOnePointOh'
import {
useUserCommunityTokenOwnerRecord,
@@ -36,37 +13,25 @@ import {
} from '@hooks/queries/tokenOwnerRecord'
import { useRealmQuery } from '@hooks/queries/realm'
import { useRealmConfigQuery } from '@hooks/queries/realmConfig'
-import { fetchGovernanceByPubkey } from '@hooks/queries/governance'
-import { useConnection } from '@solana/wallet-adapter-react'
-import queryClient from '@hooks/queries/queryClient'
-import { proposalQueryKeys } from '@hooks/queries/proposal'
-import asFindable from '@utils/queries/asFindable'
import VanillaVotingPower from '@components/GovernancePower/Vanilla/VanillaVotingPower'
-import { fetchTokenAccountByPubkey } from '@hooks/queries/tokenAccount'
import { DepositTokensButton } from '@components/DepositTokensButton'
+import VanillaWithdrawTokensButton from './VanillaWithdrawTokensButton'
+/** deposit + withdraw for vanilla govtokens, used only in account view. plugin views still use this for council. */
export const TokenDeposit = ({
mint,
tokenRole,
- councilVote,
inAccountDetails,
setHasGovPower,
}: {
mint: MintInfo | undefined
tokenRole: GoverningTokenRole
- councilVote?: boolean
inAccountDetails?: boolean
setHasGovPower?: (hasGovPower: boolean) => void
}) => {
const wallet = useWalletOnePointOh()
const connected = !!wallet?.connected
- const { connection } = useConnection()
-
- const client = useVotePluginsClientStore(
- (s) => s.state.currentRealmVotingClient
- )
- const maxVoterWeight = useMaxVoteRecord()?.pubkey || undefined
const ownTokenRecord = useUserCommunityTokenOwnerRecord().data?.result
const ownCouncilTokenRecord = useUserCouncilTokenOwnerRecord().data?.result
const realm = useRealmQuery().data?.result
@@ -79,13 +44,7 @@ export const TokenDeposit = ({
const isMembership =
relevantTokenConfig?.tokenType === GoverningTokenType.Membership
- const {
- realmInfo,
- realmTokenAccount,
- councilTokenAccount,
- toManyCommunityOutstandingProposalsForUser,
- toManyCouncilOutstandingProposalsForUse,
- } = useRealm()
+ const { realmTokenAccount, councilTokenAccount } = useRealm()
const depositTokenRecord =
tokenRole === GoverningTokenRole.Community
@@ -108,152 +67,6 @@ export const TokenDeposit = ({
tokenRole === GoverningTokenRole.Community ? '' : 'Council'
}`
- const withdrawAllTokens = async function () {
- const instructions: TransactionInstruction[] = []
- // If there are unrelinquished votes for the voter then let's release them in the same instruction as convenience
- if (depositTokenRecord!.account!.unrelinquishedVotesCount > 0) {
- const voteRecords = await getUnrelinquishedVoteRecords(
- connection,
- realmInfo!.programId,
- depositTokenRecord!.account!.governingTokenOwner
- )
-
- for (const voteRecord of Object.values(voteRecords)) {
- const proposalQuery = await queryClient.fetchQuery({
- queryKey: proposalQueryKeys.byPubkey(
- connection.rpcEndpoint,
- voteRecord.account.proposal
- ),
- staleTime: 0,
- queryFn: () =>
- asFindable(() =>
- getProposal(connection, voteRecord.account.proposal)
- )(),
- })
- const proposal = proposalQuery.result
- if (!proposal) {
- continue
- }
-
- if (proposal.account.state === ProposalState.Voting) {
- if (proposal.account.state === ProposalState.Voting) {
- const governance = (
- await fetchGovernanceByPubkey(
- connection,
- proposal.account.governance
- )
- ).result
- if (!governance) throw new Error('failed to fetch governance')
- if (proposal.account.getTimeToVoteEnd(governance.account) > 0) {
- // Note: It's technically possible to withdraw the vote here but I think it would be confusing and people would end up unconsciously withdrawing their votes
- notify({
- type: 'error',
- message: `Can't withdraw tokens while Proposal ${proposal.account.name} is being voted on. Please withdraw your vote first`,
- })
- throw new Error(
- `Can't withdraw tokens while Proposal ${proposal.account.name} is being voted on. Please withdraw your vote first`
- )
- } else {
- // finalize proposal before withdrawing tokens so we don't stop the vote from succeeding
- await withFinalizeVote(
- instructions,
- realmInfo!.programId,
- getProgramVersionForRealm(realmInfo!),
- realm!.pubkey,
- proposal.account.governance,
- proposal.pubkey,
- proposal.account.tokenOwnerRecord,
- proposal.account.governingTokenMint,
- maxVoterWeight
- )
- }
- }
- }
- // Note: We might hit single transaction limits here (accounts and size) if user has too many unrelinquished votes
- // It's not going to be an issue for now due to the limited number of proposals so I'm leaving it for now
- // As a temp. work around I'm leaving the 'Release Tokens' button on finalized Proposal to make it possible to release the tokens from one Proposal at a time
- await withRelinquishVote(
- instructions,
- realmInfo!.programId,
- realmInfo!.programVersion!,
- realmInfo!.realmId,
- proposal.account.governance,
- proposal.pubkey,
- depositTokenRecord!.pubkey,
- proposal.account.governingTokenMint,
- voteRecord.pubkey,
- depositTokenRecord!.account.governingTokenOwner,
- wallet!.publicKey!
- )
- await client.withRelinquishVote(
- instructions,
- proposal,
- voteRecord.pubkey,
- depositTokenRecord!.pubkey
- )
- }
- }
-
- const ataPk = await Token.getAssociatedTokenAddress(
- ASSOCIATED_TOKEN_PROGRAM_ID,
- TOKEN_PROGRAM_ID,
- depositMint!,
- wallet!.publicKey!,
- true
- )
- const ata = await fetchTokenAccountByPubkey(connection, ataPk)
-
- if (!ata.found) {
- const ataIx = Token.createAssociatedTokenAccountInstruction(
- ASSOCIATED_TOKEN_PROGRAM_ID,
- TOKEN_PROGRAM_ID,
- depositMint!,
- ataPk,
- wallet!.publicKey!,
- wallet!.publicKey! // fee payer
- )
- instructions.push(ataIx)
- }
-
- await withWithdrawGoverningTokens(
- instructions,
- realmInfo!.programId,
- realmInfo!.programVersion!,
- realm!.pubkey,
- depositTokenAccount?.publicKey
- ? depositTokenAccount!.publicKey
- : new PublicKey(ataPk),
- depositTokenRecord!.account.governingTokenMint,
- wallet!.publicKey!
- )
-
- try {
- // use chunks of 8 here since we added finalize,
- // because previously 9 withdraws used to fit into one tx
- const ixChunks = chunks(instructions, 8)
- for (const [index, chunk] of ixChunks.entries()) {
- const transaction = new Transaction().add(...chunk)
- await sendTransaction({
- connection,
- wallet: wallet!,
- transaction,
- sendingMessage:
- index == ixChunks.length - 1
- ? 'Withdrawing tokens'
- : `Releasing tokens (${index}/${ixChunks.length - 2})`,
- successMessage:
- index == ixChunks.length - 1
- ? 'Tokens have been withdrawn'
- : `Released tokens (${index}/${ixChunks.length - 2})`,
- })
- }
- } catch (ex) {
- //TODO change to more friendly notification
- notify({ type: 'error', message: `${ex}` })
- console.error("Can't withdraw tokens", ex)
- }
- }
-
const hasTokensInWallet =
depositTokenAccount && depositTokenAccount.account.amount.gt(new BN(0))
@@ -261,16 +74,6 @@ export const TokenDeposit = ({
depositTokenRecord &&
depositTokenRecord.account.governingTokenDepositAmount.gt(new BN(0))
- const withdrawTooltipContent = !connected
- ? 'Connect your wallet to withdraw'
- : !hasTokensDeposited
- ? "You don't have any tokens deposited to withdraw."
- : !councilVote &&
- (toManyCouncilOutstandingProposalsForUse ||
- toManyCommunityOutstandingProposalsForUser)
- ? 'You have to many outstanding proposals to withdraw.'
- : ''
-
const availableTokens =
depositTokenRecord && mint
? fmtMintAmount(
@@ -292,12 +95,6 @@ export const TokenDeposit = ({
: hasTokensInWallet
? availableTokens
: 0
- const isVsr =
- config?.account?.communityTokenConfig?.voterWeightAddin &&
- VSR_PLUGIN_PKS.includes(
- config?.account?.communityTokenConfig?.voterWeightAddin?.toBase58()
- ) &&
- tokenRole === GoverningTokenRole.Community
// Do not show deposits for mints with zero supply because nobody can deposit anyway
if (!mint || mint.supply.isZero()) {
@@ -316,57 +113,38 @@ export const TokenDeposit = ({
)}
- {
- <>
-
- You have {tokensToShow} {hasTokensDeposited ? `more ` : ``}
- {depositTokenName} tokens available to deposit.
-
-
-
- {hasTokensInWallet || inAccountDetails ? (
-
- ) : null}
- {!isMembership && // Membership tokens can't be withdrawn (that is their whole point, actually)
- (inAccountDetails || isVsr) && (
-
- Withdraw
-
- )}
-
- >
- }
- {isVsr && (
-
-
- Please withdraw your tokens and deposit again to get governance power
-
- )}
+
+ You have {tokensToShow} {hasTokensDeposited ? `more ` : ``}
+ {depositTokenName} tokens available to deposit.
+
+
+
+ {hasTokensInWallet || inAccountDetails ? (
+
+ ) : null}
+ {!isMembership && // Membership tokens can't be withdrawn (that is their whole point, actually)
+ inAccountDetails && (
+
+ )}
+
)
}
diff --git a/components/TokenBalance/VanillaAccountDetails.tsx b/components/TokenBalance/VanillaAccountDetails.tsx
index 7d35da1b41..0004c0bea2 100644
--- a/components/TokenBalance/VanillaAccountDetails.tsx
+++ b/components/TokenBalance/VanillaAccountDetails.tsx
@@ -34,7 +34,6 @@ const VanillaAccountDetails = () => {
)}
@@ -42,7 +41,6 @@ const VanillaAccountDetails = () => {
)}
diff --git a/components/TokenBalance/VanillaWithdrawTokensButton.tsx b/components/TokenBalance/VanillaWithdrawTokensButton.tsx
new file mode 100644
index 0000000000..7a4b71cc00
--- /dev/null
+++ b/components/TokenBalance/VanillaWithdrawTokensButton.tsx
@@ -0,0 +1,265 @@
+import {
+ ASSOCIATED_TOKEN_PROGRAM_ID,
+ Token,
+ TOKEN_PROGRAM_ID,
+} from '@solana/spl-token'
+import { PublicKey, Transaction, TransactionInstruction } from '@solana/web3.js'
+import BN from 'bn.js'
+import useRealm from '@hooks/useRealm'
+import {
+ getProposal,
+ GoverningTokenType,
+ ProposalState,
+} from '@solana/spl-governance'
+import { getUnrelinquishedVoteRecords } from '@models/api'
+import { withRelinquishVote } from '@solana/spl-governance'
+import { withWithdrawGoverningTokens } from '@solana/spl-governance'
+import { sendTransaction } from '@utils/send'
+import { SecondaryButton } from '../Button'
+import { withFinalizeVote } from '@solana/spl-governance'
+import { chunks } from '@utils/helpers'
+import { getProgramVersionForRealm } from '@models/registry/api'
+import { notify } from '@utils/notifications'
+import useVotePluginsClientStore from 'stores/useVotePluginsClientStore'
+import { useMaxVoteRecord } from '@hooks/useMaxVoteRecord'
+import useWalletOnePointOh from '@hooks/useWalletOnePointOh'
+import {
+ useUserCommunityTokenOwnerRecord,
+ useUserCouncilTokenOwnerRecord,
+} from '@hooks/queries/tokenOwnerRecord'
+import { useRealmQuery } from '@hooks/queries/realm'
+import { useRealmConfigQuery } from '@hooks/queries/realmConfig'
+import { fetchGovernanceByPubkey } from '@hooks/queries/governance'
+import { useConnection } from '@solana/wallet-adapter-react'
+import queryClient from '@hooks/queries/queryClient'
+import { proposalQueryKeys } from '@hooks/queries/proposal'
+import asFindable from '@utils/queries/asFindable'
+import { fetchTokenAccountByPubkey } from '@hooks/queries/tokenAccount'
+
+// TODO make this have reasonable props
+// TODO, also just refactor it
+const VanillaWithdrawTokensButton = ({
+ role,
+}: {
+ role: 'community' | 'council'
+}) => {
+ const wallet = useWalletOnePointOh()
+ const connected = !!wallet?.connected
+ const { connection } = useConnection()
+
+ const client = useVotePluginsClientStore(
+ (s) => s.state.currentRealmVotingClient
+ )
+
+ const maxVoterWeight = useMaxVoteRecord()?.pubkey || undefined
+ const ownTokenRecord = useUserCommunityTokenOwnerRecord().data?.result
+ const ownCouncilTokenRecord = useUserCouncilTokenOwnerRecord().data?.result
+ const realm = useRealmQuery().data?.result
+ const config = useRealmConfigQuery().data?.result
+
+ const relevantTokenConfig =
+ role === 'community'
+ ? config?.account.communityTokenConfig
+ : config?.account.councilTokenConfig
+ const isMembership =
+ relevantTokenConfig?.tokenType === GoverningTokenType.Membership
+
+ const {
+ realmInfo,
+ realmTokenAccount,
+ councilTokenAccount,
+ toManyCommunityOutstandingProposalsForUser,
+ toManyCouncilOutstandingProposalsForUse,
+ } = useRealm()
+
+ const depositTokenRecord =
+ role === 'community' ? ownTokenRecord : ownCouncilTokenRecord
+
+ const depositTokenAccount =
+ role === 'community' ? realmTokenAccount : councilTokenAccount
+
+ const depositMint =
+ role === 'community'
+ ? realm?.account.communityMint
+ : realm?.account.config.councilMint
+
+ const withdrawAllTokens = async function () {
+ const instructions: TransactionInstruction[] = []
+ // If there are unrelinquished votes for the voter then let's release them in the same instruction as convenience
+ if (depositTokenRecord!.account!.unrelinquishedVotesCount > 0) {
+ const voteRecords = await getUnrelinquishedVoteRecords(
+ connection,
+ realmInfo!.programId,
+ depositTokenRecord!.account!.governingTokenOwner
+ )
+
+ for (const voteRecord of Object.values(voteRecords)) {
+ const proposalQuery = await queryClient.fetchQuery({
+ queryKey: proposalQueryKeys.byPubkey(
+ connection.rpcEndpoint,
+ voteRecord.account.proposal
+ ),
+ staleTime: 0,
+ queryFn: () =>
+ asFindable(() =>
+ getProposal(connection, voteRecord.account.proposal)
+ )(),
+ })
+ const proposal = proposalQuery.result
+ if (!proposal) {
+ continue
+ }
+
+ if (proposal.account.state === ProposalState.Voting) {
+ if (proposal.account.state === ProposalState.Voting) {
+ const governance = (
+ await fetchGovernanceByPubkey(
+ connection,
+ proposal.account.governance
+ )
+ ).result
+ if (!governance) throw new Error('failed to fetch governance')
+ if (proposal.account.getTimeToVoteEnd(governance.account) > 0) {
+ // Note: It's technically possible to withdraw the vote here but I think it would be confusing and people would end up unconsciously withdrawing their votes
+ notify({
+ type: 'error',
+ message: `Can't withdraw tokens while Proposal ${proposal.account.name} is being voted on. Please withdraw your vote first`,
+ })
+ throw new Error(
+ `Can't withdraw tokens while Proposal ${proposal.account.name} is being voted on. Please withdraw your vote first`
+ )
+ } else {
+ // finalize proposal before withdrawing tokens so we don't stop the vote from succeeding
+ await withFinalizeVote(
+ instructions,
+ realmInfo!.programId,
+ getProgramVersionForRealm(realmInfo!),
+ realm!.pubkey,
+ proposal.account.governance,
+ proposal.pubkey,
+ proposal.account.tokenOwnerRecord,
+ proposal.account.governingTokenMint,
+ maxVoterWeight
+ )
+ }
+ }
+ }
+ // Note: We might hit single transaction limits here (accounts and size) if user has too many unrelinquished votes
+ // It's not going to be an issue for now due to the limited number of proposals so I'm leaving it for now
+ // As a temp. work around I'm leaving the 'Release Tokens' button on finalized Proposal to make it possible to release the tokens from one Proposal at a time
+ await withRelinquishVote(
+ instructions,
+ realmInfo!.programId,
+ realmInfo!.programVersion!,
+ realmInfo!.realmId,
+ proposal.account.governance,
+ proposal.pubkey,
+ depositTokenRecord!.pubkey,
+ proposal.account.governingTokenMint,
+ voteRecord.pubkey,
+ depositTokenRecord!.account.governingTokenOwner,
+ wallet!.publicKey!
+ )
+ await client.withRelinquishVote(
+ instructions,
+ proposal,
+ voteRecord.pubkey,
+ depositTokenRecord!.pubkey
+ )
+ }
+ }
+
+ const ataPk = await Token.getAssociatedTokenAddress(
+ ASSOCIATED_TOKEN_PROGRAM_ID,
+ TOKEN_PROGRAM_ID,
+ depositMint!,
+ wallet!.publicKey!,
+ true
+ )
+ const ata = await fetchTokenAccountByPubkey(connection, ataPk)
+
+ if (!ata.found) {
+ const ataIx = Token.createAssociatedTokenAccountInstruction(
+ ASSOCIATED_TOKEN_PROGRAM_ID,
+ TOKEN_PROGRAM_ID,
+ depositMint!,
+ ataPk,
+ wallet!.publicKey!,
+ wallet!.publicKey! // fee payer
+ )
+ instructions.push(ataIx)
+ }
+
+ await withWithdrawGoverningTokens(
+ instructions,
+ realmInfo!.programId,
+ realmInfo!.programVersion!,
+ realm!.pubkey,
+ depositTokenAccount?.publicKey
+ ? depositTokenAccount!.publicKey
+ : new PublicKey(ataPk),
+ depositTokenRecord!.account.governingTokenMint,
+ wallet!.publicKey!
+ )
+
+ try {
+ // use chunks of 8 here since we added finalize,
+ // because previously 9 withdraws used to fit into one tx
+ const ixChunks = chunks(instructions, 8)
+ for (const [index, chunk] of ixChunks.entries()) {
+ const transaction = new Transaction().add(...chunk)
+ await sendTransaction({
+ connection,
+ wallet: wallet!,
+ transaction,
+ sendingMessage:
+ index == ixChunks.length - 1
+ ? 'Withdrawing tokens'
+ : `Releasing tokens (${index}/${ixChunks.length - 2})`,
+ successMessage:
+ index == ixChunks.length - 1
+ ? 'Tokens have been withdrawn'
+ : `Released tokens (${index}/${ixChunks.length - 2})`,
+ })
+ }
+ } catch (ex) {
+ //TODO change to more friendly notification
+ notify({ type: 'error', message: `${ex}` })
+ console.error("Can't withdraw tokens", ex)
+ }
+ }
+
+ const hasTokensDeposited =
+ depositTokenRecord &&
+ depositTokenRecord.account.governingTokenDepositAmount.gt(new BN(0))
+
+ const withdrawTooltipContent = !connected
+ ? 'Connect your wallet to withdraw'
+ : !hasTokensDeposited
+ ? "You don't have any tokens deposited to withdraw."
+ : role === 'community' &&
+ (toManyCouncilOutstandingProposalsForUse ||
+ toManyCommunityOutstandingProposalsForUser)
+ ? 'You have to many outstanding proposals to withdraw.'
+ : ''
+
+ return (
+
+ Withdraw
+
+ )
+}
+export default VanillaWithdrawTokensButton