diff --git a/src/commands/account/create.ts b/src/commands/account/create.ts index fbf685d..72d7be6 100644 --- a/src/commands/account/create.ts +++ b/src/commands/account/create.ts @@ -164,10 +164,44 @@ export async function createSafe() { try { const safeService = new SafeService(chain) - const { predictedAddress, safeAccountConfig } = await safeService.createPredictedSafe({ - owners, - threshold: thresholdNum, - }) + + // Find an available salt nonce (increment if Safe already deployed) + let saltNonce = '0' + let predictedAddress: Address | undefined + let safeAccountConfig: { owners: string[]; threshold: number } | undefined + let attempts = 0 + const maxAttempts = 100 + + while (attempts < maxAttempts) { + const result = await safeService.createPredictedSafe({ + owners, + threshold: thresholdNum, + saltNonce, + }) + + predictedAddress = result.predictedAddress + safeAccountConfig = result.safeAccountConfig + + // Check if Safe already deployed at this address + try { + const safeInfo = await safeService.getSafeInfo(predictedAddress) + if (safeInfo.isDeployed) { + // Safe already deployed, try next salt nonce + saltNonce = (BigInt(saltNonce) + 1n).toString() + attempts++ + continue + } + } catch { + // Error checking deployment status, assume not deployed + } + + // Found an available address + break + } + + if (attempts >= maxAttempts || !predictedAddress || !safeAccountConfig) { + throw new Error(`Could not find available Safe address after ${maxAttempts} attempts`) + } spinner.stop('Safe created!') @@ -180,6 +214,7 @@ export async function createSafe() { predictedConfig: { owners: safeAccountConfig.owners, threshold: safeAccountConfig.threshold, + saltNonce, }, }) diff --git a/src/commands/account/deploy.ts b/src/commands/account/deploy.ts index 11426c2..5149dc0 100644 --- a/src/commands/account/deploy.ts +++ b/src/commands/account/deploy.ts @@ -72,16 +72,37 @@ export async function deploySafe(account?: string) { return } - if (safe.deployed) { - logError('Safe is already deployed') - return - } - if (!safe.predictedConfig) { logError('Safe does not have deployment configuration') return } + // Verify on-chain deployment status + const chain = configStore.getChain(safe.chainId)! + const safeService = new SafeService(chain) + + try { + const safeInfo = await safeService.getSafeInfo(address) + + // If Safe is actually deployed on-chain + if (safeInfo.isDeployed) { + // Sync local storage with on-chain reality + if (!safe.deployed) { + safeStorage.updateSafe(chainId, address, { deployed: true }) + } + logError('Safe is already deployed on-chain') + return + } + + // If local storage says deployed but on-chain says not deployed, fix the storage + if (safe.deployed && !safeInfo.isDeployed) { + safeStorage.updateSafe(chainId, address, { deployed: false }) + } + } catch { + // If we can't verify, log warning but continue + console.log(pc.yellow('⚠ Warning: Could not verify on-chain deployment status')) + } + // Get active wallet const activeWallet = walletStorage.getActiveWallet() if (!activeWallet) { @@ -90,7 +111,6 @@ export async function deploySafe(account?: string) { return } - const chain = configStore.getChain(safe.chainId)! const eip3770 = formatSafeAddress(safe.address as Address, safe.chainId, chains) console.log('')