Skip to content

Commit

Permalink
chore: extract createSafeIfNeeded
Browse files Browse the repository at this point in the history
  • Loading branch information
truemiller committed Dec 16, 2024
1 parent 814b633 commit 5ff7f79
Showing 1 changed file with 97 additions and 51 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Button, ButtonProps } from 'antd';
import { Button, ButtonProps, message } from 'antd';
import { isNil, sum } from 'lodash';
import { useCallback, useMemo } from 'react';

Expand All @@ -7,17 +7,26 @@ import { CHAIN_CONFIG } from '@/config/chains';
import { MechType } from '@/config/mechs';
import { STAKING_PROGRAMS } from '@/config/stakingPrograms';
import { SERVICE_TEMPLATES } from '@/constants/serviceTemplates';
import { Pages } from '@/enums/Pages';
import { SettingsScreen } from '@/enums/SettingsScreen';
import { TokenSymbol } from '@/enums/Token';
import { WalletOwnerType, WalletType } from '@/enums/Wallet';
import {
MasterEoa,
MasterSafe,
WalletOwnerType,
WalletType,
} from '@/enums/Wallet';
import {
useBalanceContext,
useMasterBalances,
useServiceBalances,
} from '@/hooks/useBalanceContext';
import { useElectronApi } from '@/hooks/useElectronApi';
import { useMultisigs } from '@/hooks/useMultisig';
import { MultisigOwners, useMultisigs } from '@/hooks/useMultisig';
import { usePageState } from '@/hooks/usePageState';
import { useService } from '@/hooks/useService';
import { useServices } from '@/hooks/useServices';
import { useSettings } from '@/hooks/useSettings';
import {
useActiveStakingContractDetails,
useStakingContractContext,
Expand All @@ -27,13 +36,17 @@ import { useStore } from '@/hooks/useStore';
import { useMasterWalletContext } from '@/hooks/useWallet';
import { ServicesService } from '@/service/Services';
import { WalletService } from '@/service/Wallet';
import { AgentConfig } from '@/types/Agent';
import { delayInSeconds } from '@/utils/delay';

/** Button used to start / deploy the agent */
export const AgentNotRunningButton = () => {
const { storeState } = useStore();
const { showNotification } = useElectronApi();

const { goto: gotoPage } = usePageState();
const { goto: gotoSettings } = useSettings();

const { masterWallets, masterSafes, masterEoa } = useMasterWalletContext();
const {
selectedService,
Expand Down Expand Up @@ -186,51 +199,6 @@ export const AgentNotRunningButton = () => {
setIsBalancePollingPaused,
setIsStakingContractInfoPollingPaused,
]);

const createSafeIfNeeded = useCallback(async () => {
const selectedChainHasMasterSafe = masterSafes?.some(
(masterSafe) =>
masterSafe.evmChainId === selectedAgentConfig.evmHomeChainId,
);

if (selectedChainHasMasterSafe) return;

// 1. check for other safe owners on other chains
const otherChainOwners = new Set(
masterSafesOwners
?.filter(
(masterSafe) =>
masterSafe.evmChainId !== selectedAgentConfig.evmHomeChainId,
)
.map((masterSafe) => masterSafe.owners)
.flat(),
);

// 2. remove master eoa from the list
if (masterEoa) otherChainOwners.delete(masterEoa?.address);

// 3. if there's more than one signer, there's a disrepancy, alert user
if (otherChainOwners.size > 1) {
showNotification?.(
'You have safes on other chains. Please make sure you use the same signer on all chains.',
);
return;
}

// 4. otherwise, create a new safe with the same signer
await WalletService.createSafe(
selectedAgentConfig.middlewareHomeChainId,
[...otherChainOwners][0],
);
}, [
masterEoa,
masterSafes,
masterSafesOwners,
selectedAgentConfig.evmHomeChainId,
selectedAgentConfig.middlewareHomeChainId,
showNotification,
]);

/**
* @note only create a service if `service` does not exist
*/
Expand Down Expand Up @@ -319,7 +287,19 @@ export const AgentNotRunningButton = () => {
overrideSelectedServiceStatus(MiddlewareDeploymentStatus.DEPLOYING);

try {
await createSafeIfNeeded();
await createSafeIfNeeded({
masterSafes,
masterSafesOwners,
masterEoa,
selectedAgentConfig,
gotoBackupPage: () => {
gotoPage(Pages.Settings);
gotoSettings(SettingsScreen.AddBackupWallet);
},
gotoBackupSafePage: () => {
gotoPage(Pages.AddBackupWalletViaSafe);
},
});
await deployAndStartService();
} catch (error) {
console.error('Error while starting the agent:', error);
Expand All @@ -344,10 +324,15 @@ export const AgentNotRunningButton = () => {
}, [
masterWallets,
pauseAllPolling,
resumeAllPolling,
overrideSelectedServiceStatus,
createSafeIfNeeded,
resumeAllPolling,
masterSafes,
masterSafesOwners,
masterEoa,
selectedAgentConfig,
deployAndStartService,
gotoPage,
gotoSettings,
showNotification,
updateStatesSequentially,
]);
Expand All @@ -363,3 +348,64 @@ export const AgentNotRunningButton = () => {

return <Button {...buttonProps}>{buttonText}</Button>;
};

export const createSafeIfNeeded = async ({
masterSafes,
masterSafesOwners,
masterEoa,
selectedAgentConfig,
gotoBackupPage,
gotoBackupSafePage,
}: {
selectedAgentConfig: AgentConfig;
gotoBackupPage: () => void;
gotoBackupSafePage: () => void;
masterEoa?: MasterEoa;
masterSafes?: MasterSafe[];
masterSafesOwners?: MultisigOwners[];
}) => {
const selectedChainHasMasterSafe = masterSafes?.some(
(masterSafe) =>
masterSafe.evmChainId === selectedAgentConfig.evmHomeChainId,
);

if (selectedChainHasMasterSafe) return;

// 1. get safe owners on other chains
const otherChainOwners = new Set(
masterSafesOwners
?.filter(
(masterSafe) =>
masterSafe.evmChainId !== selectedAgentConfig.evmHomeChainId,
)
.map((masterSafe) => masterSafe.owners)
.flat(),
);

// 2. remove master eoa from the set, to find backup signers
if (masterEoa) otherChainOwners.delete(masterEoa?.address);

// 3. if there are no signers, the user needs to add a backup signer

if (otherChainOwners.size <= 0) {
message.error(
'A backup signer is required to create a new safe on the home chain. Please add a backup signer.',
);
gotoBackupPage();
throw new Error('No backup signers found');
}

if (otherChainOwners.size !== 1) {
message.error(
'The same backup signer address must be used on all chains. Please remove any extra backup signers.',
);
gotoBackupSafePage();
throw new Error('Multiple backup signers found');
}

// 4. otherwise, create a new safe with the same signer
await WalletService.createSafe(
selectedAgentConfig.middlewareHomeChainId,
[...otherChainOwners][0],
);
};

0 comments on commit 5ff7f79

Please sign in to comment.