Skip to content

Commit

Permalink
handle disconnect during pending create pool tx
Browse files Browse the repository at this point in the history
  • Loading branch information
MattPereira committed Dec 12, 2024
1 parent e9daa1a commit 7c2043c
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 27 deletions.
7 changes: 4 additions & 3 deletions packages/nextjs/app/v3/_components/PoolConfiguration.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { TABS, type TabType, usePoolCreationStore, useValidatePoolCreationInput
import { bgBeigeGradient } from "~~/utils";

export function PoolConfiguration() {
const { selectedTab, updatePool, step } = usePoolCreationStore();
const { selectedTab, updatePool, createPoolTxHash } = usePoolCreationStore();
const { targetNetwork } = useTargetNetwork();
const [isPoolCreationModalOpen, setIsPoolCreationModalOpen] = useState(false);
const { prev, next } = getAdjacentTabs(selectedTab);
Expand Down Expand Up @@ -44,9 +44,10 @@ export function PoolConfiguration() {
};
}

// Force modal to open if user has already sent "Deploy Pool" transaction (always step 1)
useEffect(() => {
if (step > 1) setIsPoolCreationModalOpen(true);
}, [step]);
if (createPoolTxHash) setIsPoolCreationModalOpen(true);
}, [createPoolTxHash]);

return (
<>
Expand Down
2 changes: 0 additions & 2 deletions packages/nextjs/hooks/v3/useBoostableWhitelist.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,6 @@ export const useBoostableWhitelist = () => {

const data = json.data.tokenGetTokens;

console.log("data", data);

// Create map of underlying token address to matching boosted variant info
const boostableTokensMap = data.reduce((acc: Record<Address, Token>, token: Token) => {
if (token.underlyingTokenAddress) acc[token.underlyingTokenAddress] = token;
Expand Down
62 changes: 43 additions & 19 deletions packages/nextjs/hooks/v3/useCreatePool.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useEffect } from "react";
import {
CreatePool,
CreatePoolV3BaseInput,
Expand All @@ -10,7 +11,7 @@ import {
import { useMutation } from "@tanstack/react-query";
import { parseEventLogs, parseUnits, zeroAddress } from "viem";
import { usePublicClient, useWalletClient } from "wagmi";
import { useTransactor } from "~~/hooks/scaffold-eth";
// import { useTransactor } from "~~/hooks/scaffold-eth";
import { useBoostableWhitelist, usePoolCreationStore } from "~~/hooks/v3";

const poolFactoryAbi = {
Expand All @@ -24,7 +25,8 @@ const TOKEN_WEIGHT_DECIMALS = 16;
export const useCreatePool = () => {
const { data: walletClient } = useWalletClient();
const publicClient = usePublicClient();
const writeTx = useTransactor();
// const writeTx = useTransactor();

const {
tokenConfigs,
name,
Expand All @@ -38,8 +40,34 @@ export const useCreatePool = () => {
disableUnbalancedLiquidity,
amplificationParameter,
updatePool,
createPoolTxHash,
step,
} = usePoolCreationStore();

const { data: boostableWhitelist } = useBoostableWhitelist();

// If user disconnects during pending tx state, this will look up tx receipt based on tx hash saved in local storage immediately after tx is sent (i.e. right after button is clicked)
useEffect(() => {
async function getTxReceipt() {
if (!publicClient || !createPoolTxHash || poolType === undefined || step !== 1) return;

const txReceipt = await publicClient.waitForTransactionReceipt({ hash: createPoolTxHash });

const logs = parseEventLogs({
abi: poolFactoryAbi[poolType],
logs: txReceipt.logs,
});

if (logs.length > 0 && "args" in logs[0] && "pool" in logs[0].args) {
const newPool = logs[0].args.pool;
updatePool({ poolAddress: newPool, step: 2 });
} else {
throw new Error("Expected pool address not found in event logs");
}
}
getTxReceipt();
}, [createPoolTxHash, publicClient, poolType, updatePool, step]);

function createPoolInput(poolType: PoolType): CreatePoolV3StableInput | CreatePoolV3WeightedInput {
if (poolType === undefined) throw new Error("No pool type provided!");
if (!publicClient) throw new Error("Public client must be available!");
Expand Down Expand Up @@ -88,30 +116,26 @@ export const useCreatePool = () => {
const input = createPoolInput(poolType);
const call = createPool.buildCall(input);

const hash = await writeTx(
() =>
walletClient.sendTransaction({
account: walletClient.account,
data: call.callData,
to: call.to,
}),
{
blockConfirmations: 1,
onBlockConfirmation: () => {
console.log("Successfully deployed and registered a balancer v3 pool!");
},
},
);
// Not using transactor here because we need to immediately save tx hash to local storage for zen dragon edge case
// He sends transactions with low gas limit which means they stay pending for hours
const hash = await walletClient.sendTransaction({
account: walletClient.account,
data: call.callData,
to: call.to,
});
if (!hash) throw new Error("Failed to generate pool creation transaction hash");

updatePool({ createPoolTxHash: hash });

if (!hash) throw new Error("No pool creation transaction hash");
const txReceipt = await publicClient.getTransactionReceipt({ hash });
const txReceipt = await publicClient.waitForTransactionReceipt({ hash });
const logs = parseEventLogs({
abi: poolFactoryAbi[poolType],
logs: txReceipt.logs,
});

if (logs.length > 0 && "args" in logs[0] && "pool" in logs[0].args) {
const newPool = logs[0].args.pool;
updatePool({ poolAddress: newPool, createPoolTxHash: hash, step: 2 });
updatePool({ poolAddress: newPool, step: 2 });
} else {
throw new Error("Expected pool address not found in event logs");
}
Expand Down
6 changes: 3 additions & 3 deletions packages/nextjs/hooks/v3/usePoolCreationStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ export interface PoolCreationStore {
disableUnbalancedLiquidity: boolean;
enableDonation: boolean;
amplificationParameter: string;
createPoolTxHash: string | undefined;
swapTxHash: string | undefined;
initPoolTxHash: string | undefined;
createPoolTxHash: `0x${string}` | undefined;
swapTxHash: `0x${string}` | undefined;
initPoolTxHash: `0x${string}` | undefined;
updatePool: (updates: Partial<PoolCreationStore>) => void;
updateTokenConfig: (index: number, updates: Partial<TokenConfig>) => void;
clearPoolStore: () => void;
Expand Down

0 comments on commit 7c2043c

Please sign in to comment.