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