diff --git a/packages/website/src/features/Deploy/QueueFromGitOpsPage.tsx b/packages/website/src/features/Deploy/QueueFromGitOpsPage.tsx
index 51e4910ad..0b1f7548f 100644
--- a/packages/website/src/features/Deploy/QueueFromGitOpsPage.tsx
+++ b/packages/website/src/features/Deploy/QueueFromGitOpsPage.tsx
@@ -435,7 +435,8 @@ export default function QueueFromGitOps() {
const execTxn = useWriteContract();
const isOutsideSafeTxnsRequired =
- (buildState.result?.deployerSteps.length || 0) > 0 && !deployer.isComplete;
+ (buildState.result?.deployerSteps.length || 0) > 0 &&
+ deployer.executionProgress.status !== 'success';
const loadingDataForDeploy =
prevCannonDeployInfo.isFetching ||
@@ -930,7 +931,7 @@ export default function QueueFromGitOps() {
p="4"
borderRadius="md"
>
- {deployer.queuedTransactions.length === 0 ? (
+ {buildState.result?.deployerSteps.length === 0 ? (
The following steps should be executed outside the safe
@@ -957,11 +958,13 @@ export default function QueueFromGitOps() {
Execute Outside Safe Txns
- ) : deployer.executionProgress.length <
- deployer.queuedTransactions.length ? (
+ ) : deployer.executionProgress.status === 'executing' ? (
- Deploying txns {deployer.executionProgress.length + 1} /{' '}
- {deployer.queuedTransactions.length}
+ Deploying txns{' '}
+ {deployer.transactionStatuses.findIndex(
+ (t) => t === 'executing'
+ ) + 1}{' '}
+ / {deployer.transactionStatuses.length}
) : (
diff --git a/packages/website/src/hooks/deployer.ts b/packages/website/src/hooks/deployer.ts
index 41adee2a1..a033c11ce 100644
--- a/packages/website/src/hooks/deployer.ts
+++ b/packages/website/src/hooks/deployer.ts
@@ -1,77 +1,81 @@
-import { useAccount, useSendTransaction, useWaitForTransactionReceipt, useSwitchChain } from 'wagmi';
-import _ from 'lodash';
+import { useAccount, useSendTransaction, useSwitchChain } from 'wagmi';
import * as viem from 'viem';
-import { useState, useEffect } from 'react';
+import { useState } from 'react';
+
+type Status = 'idle' | 'executing' | 'success' | 'error';
export function useDeployerWallet(chainId?: number) {
- // for now, we just return the currently connected wallet
const connectedAccount = useAccount();
- const [queuedTransactions, setQueuedTransactions] = useState([]);
- const [executionProgress, setExecutionProgress] = useState([]);
- const [error, setError] = useState(null);
+ const [transactionStatuses, setTransactionStatuses] = useState([]);
+ const [executionProgress, setExecutionProgress] = useState<{
+ status: Status;
+ message?: string;
+ }>({ status: 'idle' });
const { switchChainAsync } = useSwitchChain();
+ const { sendTransaction } = useSendTransaction();
- const { sendTransaction, isIdle, data: hash, error: txnError } = useSendTransaction();
+ async function queueTransactions(txns: viem.TransactionRequestBase[]) {
+ setTransactionStatuses(Array(txns.length).fill('idle'));
+ setExecutionProgress({ status: 'executing' });
- const { isSuccess: isConfirmed } = useWaitForTransactionReceipt({ hash });
+ if (!chainId) return;
- useEffect(
- function () {
- if (!chainId) {
- return;
- }
+ try {
+ for (let i = 0; i < txns.length; i++) {
+ await switchChainAsync({ chainId });
- (async () => {
- // is this the first transaction, or have we finished executing a transaction?
- if ((isIdle && !executionProgress.length && queuedTransactions.length) || isConfirmed) {
- // ensure we are on the correct network
- await switchChainAsync({ chainId });
- // execute the next transaction
- sendTransaction(
- {
- ...queuedTransactions[executionProgress.length],
- type: queuedTransactions[executionProgress.length].type as
- | 'legacy'
- | 'eip2930'
- | 'eip1559'
- | 'eip4844'
- | 'eip7702'
- | undefined,
- },
- {
- onSuccess(hash: viem.Hash) {
- setExecutionProgress([...executionProgress, hash]);
- },
- }
- );
- }
- })()
- .then(_.noop)
- .catch((err) => {
- // unexpected issue in the deployer
- // eslint-disable-next-line no-console
- console.error('deployer issue', err);
- setError(err);
+ setTransactionStatuses((prevStatuses) => {
+ const newStatuses = [...prevStatuses];
+ newStatuses[i] = 'executing';
+ return newStatuses;
});
- },
- [isConfirmed, isIdle, executionProgress.length, queuedTransactions, chainId]
- );
+
+ sendTransaction(
+ {
+ ...txns[i],
+ type: txns[i].type as 'legacy' | 'eip2930' | 'eip1559' | 'eip4844' | 'eip7702' | undefined,
+ },
+ {
+ onSuccess: () => {
+ setTransactionStatuses((prevStatuses) => {
+ const newStatuses = [...prevStatuses];
+ newStatuses[i] = 'success';
+ return newStatuses;
+ });
+
+ const isLastTransaction = i === txns.length - 1;
+ if (isLastTransaction) {
+ setExecutionProgress({ status: 'success' });
+ }
+ },
+ onError: (error) => {
+ setTransactionStatuses((prevStatuses) => {
+ const newStatuses = [...prevStatuses];
+ newStatuses[i] = 'error';
+ return newStatuses;
+ });
+ setExecutionProgress({ status: 'error', message: error.message });
+ throw error;
+ },
+ }
+ );
+ }
+ } catch (err) {
+ setExecutionProgress({ status: 'error', message: (err as Error).message });
+ }
+ }
return {
address: connectedAccount.address,
- queuedTransactions,
+ transactionStatuses,
executionProgress,
- isComplete: queuedTransactions.length > 0 && executionProgress.length === queuedTransactions.length,
- error: error || txnError,
- queueTransactions: function (txn: viem.TransactionRequestBase[]) {
- setQueuedTransactions([...queuedTransactions, ...txn]);
- },
+ queueTransactions,
reset: function () {
- setQueuedTransactions([]);
- setExecutionProgress([]);
+ setTransactionStatuses([]);
+ setExecutionProgress({ status: 'idle' });
},
};
}