Skip to content

Commit

Permalink
Finish warp deployment implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
jmrossy committed Jan 2, 2025
1 parent 3e2c42c commit cab904c
Show file tree
Hide file tree
Showing 16 changed files with 184 additions and 123 deletions.
2 changes: 1 addition & 1 deletion src/components/icons/ConfirmedIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { Color } from '../../styles/Color';
function _ConfirmedIcon({ color, ...rest }: DefaultIconProps) {
return (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 28 26" {...rest}>
<g clip-path="url(#confirmed-icon-clip-path)">
<g clipPath="url(#confirmed-icon-clip-path)">
<path
d="M1.93105 13.4815C1.93076 11.6219 2.42129 9.79511 3.35333 8.1846C4.28537 6.57409 5.62608 5.23667 7.24067 4.30678C8.85527 3.37689 10.6869 2.8873 12.5513 2.88723C14.4158 2.88716 16.2474 3.3766 17.8621 4.30637C18.0837 4.43205 18.3462 4.46519 18.5923 4.39857C18.8383 4.33194 19.048 4.17096 19.1754 3.95074C19.3029 3.73052 19.3379 3.46895 19.2727 3.22311C19.2076 2.97727 19.0475 2.76712 18.8276 2.63851C16.4348 1.26067 13.653 0.708778 10.9136 1.06842C8.17424 1.42807 5.63041 2.67916 3.67662 4.62766C1.72282 6.57616 0.468253 9.11318 0.107478 11.8453C-0.253297 14.5774 0.299883 17.3519 1.68123 19.7384C3.06257 22.125 5.19488 23.9903 7.74747 25.0451C10.3001 26.0998 13.1303 26.2851 15.7992 25.5721C18.4681 24.8592 20.8266 23.2878 22.5088 21.1018C24.1911 18.9157 25.1031 16.2372 25.1035 13.4815C25.1035 13.2261 25.0017 12.9812 24.8207 12.8006C24.6396 12.62 24.394 12.5185 24.1379 12.5185C23.8819 12.5185 23.6363 12.62 23.4552 12.8006C23.2741 12.9812 23.1724 13.2261 23.1724 13.4815C23.1724 16.2908 22.0535 18.9851 20.0617 20.9716C18.0699 22.9581 15.3685 24.0741 12.5517 24.0741C9.73495 24.0741 7.03354 22.9581 5.04178 20.9716C3.05001 18.9851 1.93105 16.2908 1.93105 13.4815Z"
fill={color || Color.black}
Expand Down
4 changes: 2 additions & 2 deletions src/components/toast/TxSuccessToast.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { toast } from 'react-toastify';
import { useMultiProvider } from '../../features/chains/hooks';

export function toastTxSuccess(msg: string, txHash: string, chain: ChainName) {
export function toastTxSuccess(msg: string, txHash: string, chain: ChainName, autoClose = 10_000) {
toast.success(<TxSuccessToast msg={msg} txHash={txHash} chain={chain} />, {
autoClose: 12000,
autoClose,
});
}

Expand Down
2 changes: 1 addition & 1 deletion src/features/deployerWallet/fund.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ async function executeTransfer({
});
const txReceipt = await confirm();
logger.debug(`Deployer funding tx confirmed on ${chainName}, hash: ${hash}`);
toastTxSuccess(`Deployer funded on ${chainName}!`, hash, origin);
toastTxSuccess(`Deployer funded on ${chainName}!`, hash, origin, 5_000);
return txReceipt;
} catch (error: any) {
const errorDetails = error.message || error.toString();
Expand Down
76 changes: 42 additions & 34 deletions src/features/deployerWallet/refund.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ export function useRefundDeployerAccounts(onSettled?: () => void) {
const { wallets } = useDeployerWallets();
const { accounts } = useAccounts(multiProvider);

const { error, mutate, isIdle, isPending } = useMutation({
mutationKey: ['refundDeployerAccounts', chains, wallets, accounts],
const { error, mutate, mutateAsync, isIdle, isPending } = useMutation({
mutationKey: ['refundDeployerAccounts', chains, accounts],
mutationFn: () => refundDeployerAccounts(chains, wallets, multiProvider, accounts),
retry: false,
onSettled,
Expand All @@ -39,6 +39,7 @@ export function useRefundDeployerAccounts(onSettled?: () => void) {

return {
refund: mutate,
refundAsync: mutateAsync,
isIdle,
isPending,
};
Expand All @@ -63,39 +64,43 @@ async function transferBalances(
multiProvider: MultiProtocolProvider,
accounts: Record<ProtocolType, AccountInfo>,
) {
const txReceipts: Array<PromiseSettledResult<TypedTransactionReceipt>> = await Promise.allSettled(
balances.map(async (balance) => {
const { chainName, protocol, amount: balanceAmount, address: deployerAddress } = balance;
logger.debug('Preparing transfer from deployer', chainName, balanceAmount);
const txReceipts: Array<PromiseSettledResult<TypedTransactionReceipt | undefined>> =
await Promise.allSettled(
balances.map(async (balance) => {
const { chainName, protocol, amount: balanceAmount, address: deployerAddress } = balance;
logger.debug('Preparing transfer from deployer', chainName, balanceAmount);

try {
const chainMetadata = multiProvider.getChainMetadata(chainName);
const token = Token.FromChainMetadataNativeToken(chainMetadata);
const recipient = getAccountAddressForChain(multiProvider, chainName, accounts);
assert(recipient, `No user account found for chain ${chainName}`);
const deployer = wallets[protocol];
assert(deployer, `No deployer wallet found for protocol ${protocol}`);
try {
const chainMetadata = multiProvider.getChainMetadata(chainName);
const token = Token.FromChainMetadataNativeToken(chainMetadata);
const recipient = getAccountAddressForChain(multiProvider, chainName, accounts);
assert(recipient, `No user account found for chain ${chainName}`);
const deployer = wallets[protocol];
assert(deployer, `No deployer wallet found for protocol ${protocol}`);

const estimationTx = await getTransferTx(recipient, balanceAmount, token, multiProvider);
const adjustedAmount = await computeNetTransferAmount(
chainName,
estimationTx,
balanceAmount,
multiProvider,
deployerAddress,
);
const tx = await getTransferTx(recipient, adjustedAmount, token, multiProvider);
const estimationTx = await getTransferTx(recipient, balanceAmount, token, multiProvider);

const txReceipt = await sendTxFromWallet(deployer, tx, chainName, multiProvider);
logger.debug('Transfer tx confirmed on chain', chainName, txReceipt.receipt);
return txReceipt;
} catch (error) {
const msg = `Error refunding balance on chain ${chainName}`;
logger.error(msg, error);
throw new Error(msg, { cause: error });
}
}),
);
const adjustedAmount = await computeNetTransferAmount(
chainName,
estimationTx,
balanceAmount,
multiProvider,
deployerAddress,
);
if (adjustedAmount <= 0n) return undefined;

const tx = await getTransferTx(recipient, adjustedAmount, token, multiProvider);

const txReceipt = await sendTxFromWallet(deployer, tx, chainName, multiProvider);
logger.debug('Transfer tx confirmed on chain', chainName, txReceipt.receipt);
return txReceipt;
} catch (error) {
const msg = `Error refunding balance on chain ${chainName}`;
logger.error(msg, error);
throw new Error(msg, { cause: error });
}
}),
);

const failedTransferChains = balances
.filter((_, i) => txReceipts[i].status === 'rejected')
Expand All @@ -106,7 +111,10 @@ async function transferBalances(
`Failed to transfer deployer balances on chains: ${failedTransferChains.join(', ')}`,
);
} else {
return txReceipts.filter((t) => t.status === 'fulfilled').map((r) => r.value);
return txReceipts
.filter((t) => t.status === 'fulfilled')
.map((t) => t.value)
.filter((t): t is TypedTransactionReceipt => !!t);
}
}

Expand All @@ -133,7 +141,7 @@ async function computeNetTransferAmount(
logger.debug(`Net amount for transfer on ${chain}`, netAmountBn);
return netAmountBn;
} else {
logger.warn(`Estimated fee is greater than balance on ${chain}`);
logger.debug(`Estimated fee is greater than balance on ${chain}`);
return 0n;
}
}
14 changes: 8 additions & 6 deletions src/features/deployerWallet/wallets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export function useDeployerWallets() {
const { deployerKeys } = useStore((s) => ({
deployerKeys: s.deployerKeys,
}));
const { error, isLoading, data } = useQuery({
const { error, isLoading, data, refetch } = useQuery({
queryKey: ['getDeployerWallets', deployerKeys],
queryFn: () => getDeployerWallets(deployerKeys),
retry: false,
Expand All @@ -28,6 +28,7 @@ export function useDeployerWallets() {
isLoading,
error,
wallets: data || {},
refetch,
};
}

Expand All @@ -43,7 +44,7 @@ export function useOrCreateDeployerWallets(
deployerKeys: s.deployerKeys,
setDeployerKey: s.setDeployerKey,
}));
const { error, isLoading, data } = useQuery({
const { error, isLoading, data, refetch } = useQuery({
queryKey: ['getOrCreateDeployerWallets', protocols, deployerKeys, setDeployerKey],
queryFn: () => getOrCreateDeployerWallets(protocols, deployerKeys, setDeployerKey),
retry: false,
Expand All @@ -59,6 +60,7 @@ export function useOrCreateDeployerWallets(
isLoading,
error,
wallets: data || {},
refetch,
};
}

Expand Down Expand Up @@ -156,10 +158,10 @@ async function decryptDeployerWallet(
}

// TODO multi-protocol support
export function getDeployerWalletKey(wallet: TypedWallet) {
if (wallet.type === ProviderType.EthersV5) {
return wallet.wallet.privateKey;
export function getDeployerWalletKey({ wallet, type }: TypedWallet) {
if (type === ProviderType.EthersV5) {
return wallet.privateKey;
} else {
throw new Error(`Unsupported wallet type for address: ${wallet.type}`);
throw new Error(`Unsupported wallet type: ${type}`);
}
}
6 changes: 6 additions & 0 deletions src/features/deployment/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,19 @@ export function useDeploymentHistory() {
deployments: s.deployments,
addDeployment: s.addDeployment,
updateDeploymentStatus: s.updateDeploymentStatus,
completeDeployment: s.completeDeployment,
}));
return {
...state,
currentIndex: state.deployments.length - 1,
};
}

export function useLatestDeployment() {
const { deployments, currentIndex } = useDeploymentHistory();
return deployments[currentIndex];
}

export function usePastDeploymentChains() {
const multiProvider = useMultiProvider();
const { deployments } = useDeploymentHistory();
Expand Down
2 changes: 1 addition & 1 deletion src/features/deployment/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export interface WarpDeploymentResult extends ResultBase {

export interface CoreDeploymentResult extends ResultBase {
type: DeploymentType.Core;
config: any; // TODO
result: any; // TODO
}

export type DeploymentResult = WarpDeploymentResult | CoreDeploymentResult;
7 changes: 3 additions & 4 deletions src/features/deployment/utils.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { tryClipboardSet } from '@hyperlane-xyz/widgets';
import { toast } from 'react-toastify';
import { stringify } from 'yaml';
import { DeploymentConfig } from './types';

export async function tryCopyConfig(deploymentConfig: DeploymentConfig | undefined) {
if (!deploymentConfig) return;
const yamlConfig = stringify(deploymentConfig.config);
export async function tryCopyConfig(config: unknown | undefined) {
if (!config) return;
const yamlConfig = stringify(config);
const result = await tryClipboardSet(yamlConfig);
if (result) toast.success('Config copied to clipboard');
else toast.error('Unable to set clipboard');
Expand Down
Loading

0 comments on commit cab904c

Please sign in to comment.