Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use new dialog
Browse files Browse the repository at this point in the history
cgero-eth committed Apr 10, 2024

Verified

This commit was signed with the committer’s verified signature.
jleach Jason C. Leach
1 parent db54292 commit ee11110
Showing 3 changed files with 38 additions and 156 deletions.
Original file line number Diff line number Diff line change
@@ -3,9 +3,13 @@ import {useNetwork} from 'context/network';
import {useProviders} from 'context/providers';
import {useDaoDetailsQuery} from 'hooks/useDaoDetails';
import {useIsUpdateProposal} from 'hooks/useIsUpdateProposal';
import {PluginTypes} from 'hooks/usePluginClient';
import {useSendTransaction} from 'hooks/useSendTransaction';
import {useParams} from 'react-router-dom';
import {aragonSdkQueryKeys} from 'services/aragon-sdk/query-keys';
import {
AragonSdkQueryItem,
aragonSdkQueryKeys,
} from 'services/aragon-sdk/query-keys';
import {ITransaction} from 'services/transactions/domain/transaction';
import {CHAIN_METADATA} from 'utils/constants';
import {toDisplayEns} from 'utils/library';
@@ -34,6 +38,7 @@ export const useSendExecuteProposalTransaction = (
const {id: proposalId} = useParams();

const {data: daoDetails} = useDaoDetailsQuery();
const pluginType = daoDetails?.plugins[0].id as PluginTypes;
const daoAddressOrEns =
toDisplayEns(daoDetails?.ensDomain) || daoDetails?.address;

@@ -69,6 +74,15 @@ export const useSendExecuteProposalTransaction = (
aragonSdkQueryKeys.protocolVersion(daoDetails?.address)
);
}

const allProposalsQuery = [AragonSdkQueryItem.PROPOSALS];
const currentProposal = aragonSdkQueryKeys.proposal({
id: proposalId!,
pluginType,
});

queryClient.invalidateQueries(allProposalsQuery);
queryClient.invalidateQueries(currentProposal);
};

const sendTransactionResults = useSendTransaction({
158 changes: 12 additions & 146 deletions src/context/proposalTransaction.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import {
ApproveMultisigProposalParams,
ApproveProposalStep,
ExecuteProposalStep,
VoteProposalParams,
VoteProposalStep,
VoteValues,
@@ -60,16 +59,12 @@ type ProposalTransactionContextType = {
/** handles voting on proposal */
handlePrepareVote: (params: SubmitVoteParams) => void;
handlePrepareApproval: (params: ApproveMultisigProposalParams) => void;
handlePrepareExecution: () => void;
handleGaslessVoting: (params: SubmitVoteParams) => void;
handleExecutionMultisigApprove: (
params: ApproveMultisigProposalParams
) => void;
isLoading: boolean;
voteOrApprovalSubmitted: boolean;
executionSubmitted: boolean;
executionFailed: boolean;
executionTxHash: string;
};

type Props = Record<'children', ReactNode>;
@@ -87,7 +82,7 @@ const ProposalTransactionProvider: React.FC<Props> = ({children}) => {
const {id: urlId} = useParams();
const proposalId = new ProposalId(urlId!).export();

const {address, isConnected} = useWallet();
const {address} = useWallet();
const {network} = useNetwork();
const queryClient = useQueryClient();
const {api: provider} = useProviders();
@@ -99,7 +94,6 @@ const ProposalTransactionProvider: React.FC<Props> = ({children}) => {
// state values
const [showVoteModal, setShowVoteModal] = useState(false);
const [showGaslessModal, setShowGaslessModal] = useState(false);
const [showExecutionModal, setShowExecutionModal] = useState(false);
const [voteTokenAddress, setVoteTokenAddress] = useState<string>();
const [showCommitteeApprovalModal, setShowCommitteeApprovalModal] =
useState(false);
@@ -114,11 +108,6 @@ const ProposalTransactionProvider: React.FC<Props> = ({children}) => {
const [voteOrApprovalProcessState, setVoteOrApprovalProcessState] =
useState<TransactionState>();

const [executionFailed, setExecutionFailed] = useState(false);
const [executionSubmitted, setExecuteSubmitted] = useState(false);
const [executionProcessState, setExecutionProcessState] =
useState<TransactionState>();

const [executionTxHash, setExecutionTxHash] = useState<string>('');

// intermediate values
@@ -140,16 +129,12 @@ const ProposalTransactionProvider: React.FC<Props> = ({children}) => {
(voteParams != null || approvalParams != null) &&
voteOrApprovalProcessState === TransactionState.WAITING;

const isWaitingForExecution =
!!proposalId && executionProcessState === TransactionState.WAITING;

const notInSuccessState =
executionProcessState !== TransactionState.SUCCESS &&
voteOrApprovalProcessState !== TransactionState.SUCCESS;

const noActionsPending = !voteParams && !approvalParams && !proposalId;

const shouldPollFees = isWaitingForVoteOrApproval || isWaitingForExecution;
const shouldPollFees = isWaitingForVoteOrApproval;
const shouldDisableModalCta = noActionsPending && notInSuccessState;

/*************************************************
@@ -195,11 +180,6 @@ const ProposalTransactionProvider: React.FC<Props> = ({children}) => {
[]
);

const handlePrepareExecution = useCallback(() => {
setShowExecutionModal(true);
setExecutionProcessState(TransactionState.WAITING);
}, []);

/*************************************************
* Estimations *
*************************************************/
@@ -228,22 +208,14 @@ const ProposalTransactionProvider: React.FC<Props> = ({children}) => {
isGaslessVotingPluginClient,
]);

// estimate proposal execution fees
const estimateExecutionFees = useCallback(async () => {
return pluginClient?.estimation.executeProposal(proposalId);
}, [pluginClient?.estimation, proposalId]);

// estimation fees for voting on proposal/executing proposal
const {
tokenPrice,
maxFee,
averageFee,
stopPolling,
error: gasEstimationError,
} = usePollGasFee(
showExecutionModal ? estimateExecutionFees : estimateVoteOrApprovalFees,
shouldPollFees
);
} = usePollGasFee(estimateVoteOrApprovalFees, shouldPollFees);

/*************************************************
* Cleanup & Cache *
@@ -438,23 +410,6 @@ const ProposalTransactionProvider: React.FC<Props> = ({children}) => {
}
}, [invalidateProposalQueries, stopPolling, voteOrApprovalProcessState]);

// handles closing execute modal
const handleCloseExecuteModal = useCallback(() => {
switch (executionProcessState) {
case TransactionState.LOADING:
break;
case TransactionState.SUCCESS:
setShowExecutionModal(false);
setExecuteSubmitted(true);
invalidateProposalQueries();
break;
default: {
setShowExecutionModal(false);
stopPolling();
}
}
}, [executionProcessState, invalidateProposalQueries, stopPolling]);

/*************************************************
* Submit Transactions *
*************************************************/
@@ -597,117 +552,41 @@ const ProposalTransactionProvider: React.FC<Props> = ({children}) => {
]
);

// handles proposal execution
const handleProposalExecution = useCallback(async () => {
if (executionProcessState === TransactionState.SUCCESS) {
handleCloseExecuteModal();
return;
}
if (!proposalId || executionProcessState === TransactionState.LOADING) {
console.log('Transaction is running');
return;
}

if (!pluginAddress) {
console.error('Plugin address is required');
return;
}

if (!isConnected) {
open('wallet');
return;
}

// start proposal execution
setExecutionProcessState(TransactionState.LOADING);

const executeSteps = pluginClient?.methods.executeProposal(proposalId);
if (!executeSteps) {
throw new Error('Voting function is not initialized correctly');
}

try {
let txHash = '';

for await (const step of executeSteps) {
switch (step.key) {
case ExecuteProposalStep.EXECUTING:
setExecutionTxHash(step.txHash);
txHash = step.txHash;
break;
case ExecuteProposalStep.DONE:
onExecutionSuccess(proposalId, txHash);
setExecutionFailed(false);
setExecutionProcessState(TransactionState.SUCCESS);
break;
}
}
} catch (err) {
console.error(err);
setExecutionFailed(true);
setExecutionProcessState(TransactionState.ERROR);
}
}, [
executionProcessState,
proposalId,
pluginAddress,
isConnected,
handleCloseExecuteModal,
pluginClient?.methods,
onExecutionSuccess,
]);

const value = useMemo(
() => ({
handlePrepareVote,
handlePrepareApproval,
handlePrepareExecution,
handleGaslessVoting,
handleExecutionMultisigApprove,
isLoading,
voteOrApprovalSubmitted,
executionSubmitted,
executionFailed,
executionTxHash,
}),
[
handlePrepareVote,
handlePrepareApproval,
handlePrepareExecution,
handleGaslessVoting,
handleExecutionMultisigApprove,
isLoading,
voteOrApprovalSubmitted,
executionSubmitted,
executionFailed,
executionTxHash,
]
);

/*************************************************
* Render *
*************************************************/
// modal values
const isExecutionContext = showExecutionModal;
const isVotingContext = showVoteModal || showCommitteeApprovalModal;

const state =
(isExecutionContext ? executionProcessState : voteOrApprovalProcessState) ??
TransactionState.WAITING;
const state = voteOrApprovalProcessState ?? TransactionState.WAITING;

let title = isVotingContext
? t('labels.signVote')
: t('labels.signExecuteProposal');
let title = t('labels.signVote');

const labels: TransactionStateLabels = {
[TransactionState.WAITING]: isVotingContext
? t('governance.proposals.buttons.vote')
: t('governance.proposals.buttons.execute'),
[TransactionState.WAITING]: t('governance.proposals.buttons.vote'),
};

if (
(isVotingContext && pluginType === 'multisig.plugin.dao.eth') ||
(isVotingContext && pluginType === GaslessPluginName)
pluginType === 'multisig.plugin.dao.eth' ||
pluginType === GaslessPluginName
) {
title = t('transactionModal.multisig.title.approveProposal');
labels.WAITING = t('transactionModal.multisig.ctaApprove');
@@ -720,20 +599,7 @@ const ProposalTransactionProvider: React.FC<Props> = ({children}) => {
}
}

const isOpen =
showVoteModal || showExecutionModal || showCommitteeApprovalModal;

const onClose = isExecutionContext
? handleCloseExecuteModal
: handleCloseVoteModal;

const closeOnDrag = isExecutionContext
? executionProcessState !== TransactionState.LOADING
: voteOrApprovalProcessState !== TransactionState.LOADING;

const callback = isExecutionContext
? handleProposalExecution
: handleVoteOrApprovalTx;
const isOpen = showVoteModal || showCommitteeApprovalModal;

return (
<ProposalTransactionContext.Provider value={value}>
@@ -751,9 +617,9 @@ const ProposalTransactionProvider: React.FC<Props> = ({children}) => {
buttonStateLabels={labels}
state={state}
isOpen={isOpen}
onClose={onClose}
callback={callback}
closeOnDrag={closeOnDrag}
onClose={handleCloseVoteModal}
callback={handleVoteOrApprovalTx}
closeOnDrag={voteOrApprovalProcessState !== TransactionState.LOADING}
maxFee={maxFee}
averageFee={averageFee}
tokenPrice={tokenPrice}
20 changes: 11 additions & 9 deletions src/pages/proposal.tsx
Original file line number Diff line number Diff line change
@@ -92,6 +92,7 @@ import {Action} from 'utils/types';
import {GaslessVotingTerminal} from '../containers/votingTerminal/gaslessVotingTerminal';
import {useGaslessHasAlreadyVote} from '../context/useGaslessVoting';
import {UpdateVerificationCard} from 'containers/updateVerificationCard';
import {ExecuteProposalDialog} from 'containers/executeProposalDialog';

export const PENDING_PROPOSAL_STATUS_INTERVAL = 1000 * 10;
export const PROPOSAL_STATUS_INTERVAL = 1000 * 60;
@@ -129,19 +130,18 @@ export const Proposal: React.FC = () => {
const {api: provider} = useProviders();
const {address, isConnected, isOnWrongNetwork} = useWallet();

const [showExecuteDialog, setShowExecuteDialog] = useState(false);

const [voteStatus, setVoteStatus] = useState('');
const [decodedActions, setDecodedActions] =
useState<(Action | undefined)[]>();

const {
handlePrepareVote,
handlePrepareApproval,
handlePrepareExecution,
handleGaslessVoting,
isLoading: paramsAreLoading,
voteOrApprovalSubmitted,
executionFailed,
executionTxHash,
} = useProposalTransactionContext();

const {
@@ -558,7 +558,7 @@ export const Proposal: React.FC = () => {
const executionStatus = getProposalExecutionStatus(
proposalStatus,
canExecuteEarly,
executionFailed,
false,
undefined
);

@@ -674,7 +674,7 @@ export const Proposal: React.FC = () => {
// don't allow execution on wrong network
open('network');
} else {
handlePrepareExecution();
setShowExecuteDialog(true);
}
};

@@ -713,7 +713,7 @@ export const Proposal: React.FC = () => {
proposal.creationBlockNumber
? NumberFormatter.format(proposal.creationBlockNumber)
: '',
executionFailed,
false,
isSuccessfulMultisigSignalingProposal,
proposal.executionBlockNumber
? NumberFormatter.format(proposal.executionBlockNumber!)
@@ -878,9 +878,7 @@ export const Proposal: React.FC = () => {
actions={decodedActions}
status={executionStatus}
onExecuteClicked={handleExecuteNowClicked}
txhash={
executionTxHash || proposal.executionTxHash || undefined
}
txhash={proposal.executionTxHash || undefined}
/>
</>
)
@@ -891,6 +889,10 @@ export const Proposal: React.FC = () => {
<WidgetStatus steps={proposalSteps} />
</AdditionalInfoContainer>
</ContentContainer>
<ExecuteProposalDialog
isOpen={showExecuteDialog}
onClose={() => setShowExecuteDialog(false)}
/>
</Container>
);
};

0 comments on commit ee11110

Please sign in to comment.