Skip to content

Commit ae1338f

Browse files
Up wagmi, viem and rainbowkit (#1049)
1 parent 1100319 commit ae1338f

File tree

6 files changed

+286
-224
lines changed

6 files changed

+286
-224
lines changed

packages/nextjs/app/debug/_components/contract/WriteOnlyFunctionForm.tsx

+14-9
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { useEffect, useState } from "react";
44
import { InheritanceTooltip } from "./InheritanceTooltip";
55
import { Abi, AbiFunction } from "abitype";
66
import { Address, TransactionReceipt } from "viem";
7-
import { useAccount, useWaitForTransactionReceipt, useWriteContract } from "wagmi";
7+
import { useAccount, useConfig, useWaitForTransactionReceipt, useWriteContract } from "wagmi";
88
import {
99
ContractInput,
1010
TxReceipt,
@@ -16,6 +16,7 @@ import {
1616
import { IntegerInput } from "~~/components/scaffold-eth";
1717
import { useTransactor } from "~~/hooks/scaffold-eth";
1818
import { useTargetNetwork } from "~~/hooks/scaffold-eth/useTargetNetwork";
19+
import { simulateContractWriteAndNotifyError } from "~~/utils/scaffold-eth/contract";
1920

2021
type WriteOnlyFunctionFormProps = {
2122
abi: Abi;
@@ -41,17 +42,21 @@ export const WriteOnlyFunctionForm = ({
4142

4243
const { data: result, isPending, writeContractAsync } = useWriteContract();
4344

45+
const wagmiConfig = useConfig();
46+
4447
const handleWrite = async () => {
4548
if (writeContractAsync) {
4649
try {
47-
const makeWriteWithParams = () =>
48-
writeContractAsync({
49-
address: contractAddress,
50-
functionName: abiFunction.name,
51-
abi: abi,
52-
args: getParsedContractFunctionArgs(form),
53-
value: BigInt(txValue),
54-
});
50+
const writeContractObj = {
51+
address: contractAddress,
52+
functionName: abiFunction.name,
53+
abi: abi,
54+
args: getParsedContractFunctionArgs(form),
55+
value: BigInt(txValue),
56+
};
57+
await simulateContractWriteAndNotifyError({ wagmiConfig, writeContractParams: writeContractObj });
58+
59+
const makeWriteWithParams = () => writeContractAsync(writeContractObj);
5560
await writeTxn(makeWriteWithParams);
5661
onChange();
5762
} catch (e: any) {

packages/nextjs/hooks/scaffold-eth/useScaffoldWriteContract.ts

+16-6
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { useEffect, useState } from "react";
22
import { MutateOptions } from "@tanstack/react-query";
33
import { Abi, ExtractAbiFunctionNames } from "abitype";
4-
import { Config, UseWriteContractParameters, useAccount, useWriteContract } from "wagmi";
4+
import { Config, UseWriteContractParameters, useAccount, useConfig, useWriteContract } from "wagmi";
55
import { WriteContractErrorType, WriteContractReturnType } from "wagmi/actions";
66
import { WriteContractVariables } from "wagmi/query";
77
import { useSelectedNetwork } from "~~/hooks/scaffold-eth";
@@ -13,6 +13,7 @@ import {
1313
ScaffoldWriteContractOptions,
1414
ScaffoldWriteContractVariables,
1515
UseScaffoldWriteConfig,
16+
simulateContractWriteAndNotifyError,
1617
} from "~~/utils/scaffold-eth/contract";
1718

1819
type ScaffoldWriteContractReturnType<TContractName extends ContractName> = Omit<
@@ -60,6 +61,8 @@ export function useScaffoldWriteContract<TContractName extends ContractName>(
6061
: (configOrName as UseScaffoldWriteConfig<TContractName>);
6162
const { contractName, chainId, writeContractParams: finalWriteContractParams } = finalConfig;
6263

64+
const wagmiConfig = useConfig();
65+
6366
useEffect(() => {
6467
if (typeof configOrName === "string") {
6568
console.warn(
@@ -105,13 +108,20 @@ export function useScaffoldWriteContract<TContractName extends ContractName>(
105108
try {
106109
setIsMining(true);
107110
const { blockConfirmations, onBlockConfirmation, ...mutateOptions } = options || {};
111+
112+
const writeContractObject = {
113+
abi: deployedContractData.abi as Abi,
114+
address: deployedContractData.address,
115+
...variables,
116+
} as WriteContractVariables<Abi, string, any[], Config, number>;
117+
118+
if (!finalConfig?.disableSimulate) {
119+
await simulateContractWriteAndNotifyError({ wagmiConfig, writeContractParams: writeContractObject });
120+
}
121+
108122
const makeWriteWithParams = () =>
109123
wagmiContractWrite.writeContractAsync(
110-
{
111-
abi: deployedContractData.abi as Abi,
112-
address: deployedContractData.address,
113-
...variables,
114-
} as WriteContractVariables<Abi, string, any[], Config, number>,
124+
writeContractObject,
115125
mutateOptions as
116126
| MutateOptions<
117127
WriteContractReturnType,

packages/nextjs/package.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
},
1717
"dependencies": {
1818
"@heroicons/react": "^2.1.5",
19-
"@rainbow-me/rainbowkit": "2.1.6",
19+
"@rainbow-me/rainbowkit": "2.2.3",
2020
"@tanstack/react-query": "^5.59.15",
2121
"@uniswap/sdk-core": "^5.8.2",
2222
"@uniswap/v2-sdk": "^4.6.1",
@@ -32,8 +32,8 @@
3232
"react-dom": "^18.3.1",
3333
"react-hot-toast": "^2.4.0",
3434
"usehooks-ts": "^3.1.0",
35-
"viem": "2.21.32",
36-
"wagmi": "2.12.23",
35+
"viem": "2.23.0",
36+
"wagmi": "2.14.11",
3737
"zustand": "^5.0.0"
3838
},
3939
"devDependencies": {

packages/nextjs/utils/scaffold-eth/common.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// To be used in JSON.stringify when a field might be bigint
2+
23
// https://wagmi.sh/react/faq#bigint-serialization
34
export const replacer = (_key: string, value: unknown) => (typeof value === "bigint" ? value.toString() : value);
45

packages/nextjs/utils/scaffold-eth/contract.ts

+20-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
import { getParsedError } from "./getParsedError";
12
import { AllowedChainIds } from "./networks";
3+
import { notification } from "./notification";
24
import { MutateOptions } from "@tanstack/react-query";
35
import {
46
Abi,
@@ -23,7 +25,7 @@ import {
2325
WriteContractErrorType,
2426
} from "viem";
2527
import { Config, UseReadContractParameters, UseWatchContractEventParameters, UseWriteContractParameters } from "wagmi";
26-
import { WriteContractParameters, WriteContractReturnType } from "wagmi/actions";
28+
import { WriteContractParameters, WriteContractReturnType, simulateContract } from "wagmi/actions";
2729
import { WriteContractVariables } from "wagmi/query";
2830
import deployedContractsData from "~~/contracts/deployedContracts";
2931
import externalContractsData from "~~/contracts/externalContracts";
@@ -175,6 +177,7 @@ export type UseDeployedContractConfig<TContractName extends ContractName> = {
175177
export type UseScaffoldWriteConfig<TContractName extends ContractName> = {
176178
contractName: TContractName;
177179
chainId?: AllowedChainIds;
180+
disableSimulate?: boolean;
178181
writeContractParams?: UseWriteContractParameters;
179182
};
180183

@@ -328,3 +331,19 @@ export type UseScaffoldEventHistoryData<
328331
| undefined;
329332

330333
export type AbiParameterTuple = Extract<AbiParameter, { type: "tuple" | `tuple[${string}]` }>;
334+
335+
export const simulateContractWriteAndNotifyError = async ({
336+
wagmiConfig,
337+
writeContractParams: params,
338+
}: {
339+
wagmiConfig: Config;
340+
writeContractParams: WriteContractVariables<Abi, string, any[], Config, number>;
341+
}) => {
342+
try {
343+
await simulateContract(wagmiConfig, params);
344+
} catch (error) {
345+
const parsedError = getParsedError(error);
346+
notification.error(parsedError);
347+
throw error;
348+
}
349+
};

0 commit comments

Comments
 (0)