Skip to content

Commit

Permalink
feat: connect verify flow
Browse files Browse the repository at this point in the history
  • Loading branch information
jakim929 committed Jan 9, 2025
1 parent dc501af commit 2818b01
Show file tree
Hide file tree
Showing 12 changed files with 360 additions and 386 deletions.
91 changes: 1 addition & 90 deletions packages/cli/src/actions/verifyContract.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
import {fromFoundryArtifactPath} from '@/forge/foundryProject';
import {queryMappingChainListItemByIdentifier} from '@/queries/chainRegistryItemByIdentifier';
import {useContractVerificationStore} from '@/stores/contractVerification';
import {zodSupportedNetwork} from '@/superchain-registry/fetchChainList';
import {zodAddress} from '@/validators/schemas';
import {verifyContractOnBlockscout} from '@/verify/blockscout';
import {createStandardJsonInput} from '@/verify/createStandardJsonInput';
import {identifyExplorer} from '@/verify/identifyExplorerType';

import {option} from 'pastel';
import {z} from 'zod';

Expand Down Expand Up @@ -35,87 +30,3 @@ export const zodVerifyContractParams = z.object({
}),
),
});

const getVerifyContractContext = async (
params: z.infer<typeof zodVerifyContractParams>,
) => {
const {forgeArtifactPath, network, chains} = params;
const chainIdentifiers = chains.map(chain => `${network}/${chain}`);

const chainListItemByIdentifier =
await queryMappingChainListItemByIdentifier();
const {foundryProject, contractFileName} = await fromFoundryArtifactPath(
forgeArtifactPath,
);

return {
selectedChainList: chainIdentifiers.map(
identifier => chainListItemByIdentifier[identifier],
),
foundryProject,
contractFileName,
};
};

export const verifyContract = async (
params: z.infer<typeof zodVerifyContractParams>,
) => {
const store = useContractVerificationStore.getState();

const {contractAddress} = params;

let context: Awaited<ReturnType<typeof getVerifyContractContext>>;
try {
context = await getVerifyContractContext(params);

store.setPrepareSuccess(
context.selectedChainList.map(chain => chain!.chainId),
);
} catch (e) {
store.setPrepareError(e as Error);
return;
}

const {foundryProject, contractFileName} = context;

// TODO: Type this
let standardJsonInput: any;
try {
standardJsonInput = await createStandardJsonInput(
foundryProject.baseDir,
contractFileName,
);
store.setGenerateSuccess();
} catch (e) {
store.setGenerateError(e as Error);
return;
}

await Promise.all(
context.selectedChainList.map(async chain => {
const chainId = chain!.chainId;
const explorer = chain!.explorers[0]!;

store.setVerifyPending(chainId);

const explorerType = await identifyExplorer(explorer).catch(() => null);

if (explorerType !== 'blockscout') {
throw new Error('Unsupported explorer');
}

try {
await verifyContractOnBlockscout(
chain!.explorers[0]!,
contractAddress,
contractFileName.replace('.sol', ''),
standardJsonInput,
);
store.setVerifySuccess(chainId);
} catch (e) {
store.setVerifyError(chainId, e as Error);
return;
}
}),
);
};
10 changes: 5 additions & 5 deletions packages/cli/src/bridge-wizard/BridgeWizard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import {
useBridgeWizardStore,
} from '@/bridge-wizard/bridgeWizardStore';
import {EnterAmount} from '@/bridge-wizard/EnterAmount';
import {EnterPrivateKey} from '@/bridge-wizard/EnterPrivateKey';
import {SelectChains} from '@/bridge-wizard/SelectChains';
import {SelectNetwork} from '@/bridge-wizard/SelectNetwork';
import {useSaveWizardProgress} from '@/hooks/useSaveWizardProgress';
Expand Down Expand Up @@ -82,9 +81,11 @@ const WizardProgress = () => {
}
return (
<Box flexDirection="column">
{steps.map(({id}) => {
return <WizardProgressForStep stepId={id} key={id} />;
})}
{steps
.filter(({id}) => id !== 'completed')
.map(({id}) => {
return <WizardProgressForStep stepId={id} key={id} />;
})}
</Box>
);
};
Expand All @@ -109,7 +110,6 @@ export const BridgeWizard = () => {

<Box flexDirection="column">
{stepId === 'select-network' && <SelectNetwork />}
{stepId === 'enter-private-key' && <EnterPrivateKey />}
{stepId === 'select-chains' && <SelectChains />}
{stepId === 'enter-amount' && <EnterAmount />}
</Box>
Expand Down
58 changes: 3 additions & 55 deletions packages/cli/src/bridge-wizard/SelectChains.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,8 @@
import {useBridgeWizardStore} from '@/bridge-wizard/bridgeWizardStore';
import {ChainListItem, initChainConfig} from '@/utils/superchainRegistry';
import {useChainConfig} from '@/queries/chainConfig';
import {MultiSelect, Spinner} from '@inkjs/ui';
import {useQuery} from '@tanstack/react-query';
import {Box, Text} from 'ink';
import {useState} from 'react';
import {Address, createPublicClient, http, formatEther} from 'viem';

const getBalanceForChain = (chainListItem: ChainListItem, address: Address) => {
const client = createPublicClient({
transport: http(chainListItem.rpc[0]),
});

return client.getBalance({
address,
});
};

export const SelectChains = () => {
const {wizardState, submitSelectChains} = useBridgeWizardStore();
Expand All @@ -27,39 +15,7 @@ export const SelectChains = () => {
data: chains,
isLoading: isLoadingChains,
error: loadChainsError,
} = useQuery({
queryKey: ['init-chain-config'],
queryFn: async () => {
return await initChainConfig();
},
});

// TODO: break this out into separate keyed queries by chainId
// TODO: handle errors
const {
data: balanceByChainId,
isLoading: isLoadingBalances,
error: loadBalancesError,
} = useQuery({
queryKey: ['balance', 'l2', wizardState.network, wizardState.address],
queryFn: async () => {
const chainsInNetwork = chains!.filter(
chain => chain.parent.chain === wizardState.network,
);
const balances = await Promise.all(
chainsInNetwork.map(chain =>
getBalanceForChain(chain, wizardState.address),
),
);

return Object.fromEntries(
chainsInNetwork.map((chain, index) => [chain.chainId, balances[index]]),
);
},
enabled:
Boolean(chains) && chains!.length > 0 && Boolean(wizardState.address),
staleTime: Infinity,
});
} = useChainConfig();

const [errorMessage, setErrorMessage] = useState<string | null>(null);

Expand Down Expand Up @@ -94,9 +50,6 @@ export const SelectChains = () => {

return (
<Box flexDirection="column">
{loadBalancesError && (
<Text color="yellow">⚠️ Unable to load balances</Text>
)}
<Text>
<Text color="cyan" bold>
Select chains to bridge to{' '}
Expand All @@ -113,12 +66,7 @@ export const SelectChains = () => {
options={chains
.filter(chain => chain.parent.chain === wizardState.network)
.map(chain => ({
label:
isLoadingBalances || loadBalancesError
? chain.name
: `${chain.name} (${formatEther(
balanceByChainId?.[chain.chainId] ?? 0n,
)} ETH)`,
label: `${chain.name} (${chain.chainId})`,
value: chain.chainId.toString(),
}))}
onSubmit={chainIdStrs => {
Expand Down
Loading

0 comments on commit 2818b01

Please sign in to comment.