Skip to content

Commit

Permalink
refactor cow amm to store create pool tx hash in local storage
Browse files Browse the repository at this point in the history
  • Loading branch information
MattPereira committed Dec 14, 2024
1 parent 0b12176 commit 243235b
Show file tree
Hide file tree
Showing 8 changed files with 78 additions and 65 deletions.
2 changes: 1 addition & 1 deletion packages/nextjs/app/cow/_components/PoolConfiguration.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ export const PoolConfiguration = () => {
address: undefined,
step: 1,
tokenWeights,
isInitialState: true,
createPoolTxHash: undefined,
});
}}
/>
Expand Down
10 changes: 1 addition & 9 deletions packages/nextjs/app/cow/_components/PoolCreated.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { useState } from "react";
import { usePathname, useRouter } from "next/navigation";
import CopyToClipboard from "react-copy-to-clipboard";
import { getAddress } from "viem";
import { CheckCircleIcon, DocumentDuplicateIcon } from "@heroicons/react/24/outline";
Expand All @@ -16,8 +15,6 @@ interface PoolCreatedProps {

export const PoolCreated = ({ etherscanURL, poolAddress, chainId, clearState }: PoolCreatedProps) => {
const [addressCopied, setAddressCopied] = useState(false);
const router = useRouter();
const pathname = usePathname();

if (!poolAddress) return null;

Expand All @@ -26,11 +23,6 @@ export const PoolCreated = ({ etherscanURL, poolAddress, chainId, clearState }:
const domainName = extractDomain(etherscanURL || "");
const blockExplorerName = domainName.split(".")[0];

const handleCreateAnother = () => {
clearState();
router.replace(pathname);
};

return (
<>
<div className="bg-base-200 w-full p-6 rounded-xl flex flex-col gap-6 shadow-xl justify-center items-center">
Expand Down Expand Up @@ -77,7 +69,7 @@ export const PoolCreated = ({ etherscanURL, poolAddress, chainId, clearState }:
<div className="w-80">
<TransactionButton
title="Create Another Pool"
onClick={handleCreateAnother}
onClick={() => clearState()}
isPending={false}
isDisabled={false}
/>
Expand Down
43 changes: 23 additions & 20 deletions packages/nextjs/app/cow/_components/PoolCreation.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { useEffect } from "react";
import { useSearchParams } from "next/navigation";
import { PoolCreated } from "./";
import { parseUnits } from "viem";
import { useSwitchChain } from "wagmi";
Expand All @@ -16,15 +15,16 @@ import { CHAIN_NAMES } from "~~/hooks/balancer/";
import {
type PoolCreationState,
useBindToken,
useCowFactoryEvents,
useCreatePool,
useFinalizePool,
useReadPool,
useSetSwapFee,
useWaitForTransactionReceipt,
} from "~~/hooks/cow/";
import { useTargetNetwork } from "~~/hooks/scaffold-eth/useTargetNetwork";
import { useApproveToken, useReadToken } from "~~/hooks/token";
import { getBlockExplorerAddressLink } from "~~/utils/scaffold-eth";
import { getBlockExplorerTxLink } from "~~/utils/scaffold-eth";
import { getPerTokenWeights } from "~~/utils/token-weights";

interface ManagePoolCreationProps {
Expand All @@ -34,17 +34,10 @@ interface ManagePoolCreationProps {
}

export const PoolCreation = ({ poolCreation, updatePoolCreation, clearPoolCreation }: ManagePoolCreationProps) => {
useCowFactoryEvents();
const { address: poolAddress, createPoolTxHash } = poolCreation;

const searchParams = useSearchParams();
const poolAddress = searchParams.get("address") || poolCreation.address;

useEffect(() => {
const addressParam = searchParams.get("address");
if (addressParam && addressParam !== poolCreation.address) {
updatePoolCreation({ address: addressParam });
}
}, [searchParams, poolCreation.address, updatePoolCreation]);
const { error: poolCreationTxReceiptError, isPending: isPoolCreationTxReceiptPending } =
useWaitForTransactionReceipt();

const token1RawAmount = parseUnits(poolCreation.token1Amount, poolCreation.token1.decimals);
const token2RawAmount = parseUnits(poolCreation.token2Amount, poolCreation.token2.decimals);
Expand Down Expand Up @@ -74,11 +67,19 @@ export const PoolCreation = ({ poolCreation, updatePoolCreation, clearPoolCreati
} = useBindToken(poolCreation.tokenWeights, false);
const { mutate: setSwapFee, isPending: isSetSwapFeePending, error: setSwapFeeError } = useSetSwapFee();
const { mutate: finalizePool, isPending: isFinalizePending, error: finalizeError } = useFinalizePool();

const txError =
createPoolError || approve1Error || approve2Error || bind1Error || bind2Error || setSwapFeeError || finalizeError;
createPoolError ||
poolCreationTxReceiptError ||
approve1Error ||
approve2Error ||
bind1Error ||
bind2Error ||
setSwapFeeError ||
finalizeError;

useEffect(() => {
if (!poolData || poolCreation.isInitialState) return;
if (!poolData || !poolAddress) return;

if (poolData.isFinalized) {
updatePoolCreation({ step: 8 });
Expand Down Expand Up @@ -144,12 +145,9 @@ export const PoolCreation = ({ poolCreation, updatePoolCreation, clearPoolCreati
return (
<TransactionButton
title="Create Pool"
isPending={isCreatePending}
isDisabled={isCreatePending || isWrongNetwork}
isPending={isCreatePending || isPoolCreationTxReceiptPending}
isDisabled={isCreatePending || isPoolCreationTxReceiptPending || isWrongNetwork}
onClick={() => {
// user has officially begun the pool creation process
updatePoolCreation({ isInitialState: false });

createPool(
{ name: poolCreation.name, symbol: poolCreation.symbol },
{
Expand Down Expand Up @@ -303,7 +301,12 @@ export const PoolCreation = ({ poolCreation, updatePoolCreation, clearPoolCreati
<PoolStepsDisplay
currentStepNumber={poolCreation.step}
steps={[
{ label: "Create Pool" },
{
label: "Create Pool",
blockExplorerUrl: createPoolTxHash
? getBlockExplorerTxLink(poolCreation.chainId, createPoolTxHash)
: undefined,
},
{ label: `Approve ${poolCreation.token1.symbol}` },
{ label: `Approve ${poolCreation.token2.symbol}` },
{ label: `Add ${poolCreation.token1.symbol}` },
Expand Down
2 changes: 1 addition & 1 deletion packages/nextjs/hooks/cow/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ export * from "./useBindToken";
export * from "./useSetSwapFee";
export * from "./getPoolUrl";
export * from "./usePoolCreationStore";
export * from "./useCowFactoryEvents";
export * from "./useWaitForTransactionReceipt";
28 changes: 0 additions & 28 deletions packages/nextjs/hooks/cow/useCowFactoryEvents.ts

This file was deleted.

22 changes: 17 additions & 5 deletions packages/nextjs/hooks/cow/useCreatePool.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,36 @@
import { useMutation } from "@tanstack/react-query";
import { Address, parseEventLogs } from "viem";
import { usePublicClient } from "wagmi";
import { usePublicClient, useWalletClient } from "wagmi";
import { abis } from "~~/contracts/abis";
import { useScaffoldWriteContract } from "~~/hooks/scaffold-eth";
import { usePoolCreationStore } from "~~/hooks/cow/usePoolCreationStore";
import { useScaffoldContract, useTransactor } from "~~/hooks/scaffold-eth";

type CreatePoolPayload = {
name: string;
symbol: string;
};

export const useCreatePool = () => {
const { writeContractAsync: bCoWFactory } = useScaffoldWriteContract("BCoWFactory");
const { data: bCoWFactory } = useScaffoldContract({ contractName: "BCoWFactory" });
const publicClient = usePublicClient();
const { data: walletClient } = useWalletClient();
const writeTx = useTransactor();
const { updatePoolCreation } = usePoolCreationStore();

const createPool = async ({ name, symbol }: CreatePoolPayload): Promise<Address> => {
if (!publicClient) throw new Error("No public client");
const hash = await bCoWFactory({
if (!publicClient || !bCoWFactory || !walletClient) throw new Error("useCreatePool missing required setup");

const { request } = await publicClient.simulateContract({
account: walletClient.account,
address: bCoWFactory.address,
abi: bCoWFactory.abi,
functionName: "newBPool",
args: [name, symbol],
});

const hash = await writeTx(() => walletClient.writeContract(request), {
onTransactionHash: txHash => updatePoolCreation({ createPoolTxHash: txHash }),
});
if (!hash) throw new Error("No pool creation transaction hash");
const txReceipt = await publicClient.getTransactionReceipt({ hash });
const logs = parseEventLogs({
Expand Down
2 changes: 1 addition & 1 deletion packages/nextjs/hooks/cow/usePoolCreationStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export interface PoolCreationState {
address: Address | undefined; // updated by tx receipt from completion of step 1
step: number;
tokenWeights: "5050" | "8020";
isInitialState: boolean;
createPoolTxHash: `0x${string}` | undefined;
}

export const usePoolCreationStore = create(
Expand Down
34 changes: 34 additions & 0 deletions packages/nextjs/hooks/cow/useWaitForTransactionReceipt.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { useQuery } from "@tanstack/react-query";
import { parseEventLogs } from "viem";
import { usePublicClient } from "wagmi";
import { abis } from "~~/contracts/abis";
import { usePoolCreationStore } from "~~/hooks/cow/usePoolCreationStore";

export const useWaitForTransactionReceipt = () => {
const publicClient = usePublicClient();
const { poolCreation, updatePoolCreation } = usePoolCreationStore();
const createPoolTxHash = poolCreation?.createPoolTxHash;
const poolAddress = poolCreation?.address;

return useQuery({
queryKey: ["fetch-createPool-tx-receipt", createPoolTxHash],
queryFn: async () => {
if (!publicClient) throw new Error("Missing public client for fetching pool creation tx receipt");
if (!createPoolTxHash) return "No need to fetch receipt yet";
if (poolAddress) return poolAddress;

const txReceipt = await publicClient.waitForTransactionReceipt({ hash: createPoolTxHash });
const logs = parseEventLogs({
abi: abis.CoW.BCoWFactory,
logs: txReceipt.logs,
});

const newPoolAddress = (logs[0].args as { caller: string; bPool: string }).bPool;
if (!newPoolAddress) throw new Error("No new pool address from pool creation tx receipt");

updatePoolCreation({ address: newPoolAddress, step: 2 });

return newPoolAddress;
},
});
};

0 comments on commit 243235b

Please sign in to comment.