Skip to content

Commit

Permalink
Merge pull request #815 from scaffold-eth/backmerge-wagmiv2
Browse files Browse the repository at this point in the history
  • Loading branch information
technophile-04 committed Apr 16, 2024
2 parents 3a5b515 + 7b401f1 commit 7675de4
Show file tree
Hide file tree
Showing 49 changed files with 704 additions and 642 deletions.
8 changes: 8 additions & 0 deletions .changeset/strong-beers-compare.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"create-eth": patch
---

- Wagmi v2 migration (#700)
- Tailwind dark variant working (#810)
- Gitignored dist folder and updated gitigore files (#804)
- Fixed the main frontend path in README (#808)
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ node_modules/
!.yarn/versions

# macos files
.DS_Store
.DS_Store
13 changes: 6 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,12 @@ Visit your app on: `http://localhost:3000`. You can interact with your smart con

Run smart contract test with `yarn hardhat:test` or `yarn foundry:test` depending of your solidity framework.

- Edit your smart contract:
- Hardhat => `YourContract.sol` in `packages/hardhat/contracts`
- Foundry => `YourContract.sol` in `packages/foundry/contracts`
- Edit your frontend in `packages/nextjs/pages`
- Edit your deployment scripts:
- Hardhat => `packages/hardhat/deploy`
- Foundry => `packages/foundry/script`
**What's next**:

- Edit your smart contract `YourContract.sol` in `packages/hardhat/contracts`
- Edit your frontend homepage at `packages/nextjs/app/page.tsx`. For guidance on [routing](https://nextjs.org/docs/app/building-your-application/routing/defining-routes) and configuring [pages/layouts](https://nextjs.org/docs/app/building-your-application/routing/pages-and-layouts) checkout the Next.js documentation.
- Edit your deployment scripts in `packages/hardhat/deploy`
- Edit your smart contract test in: `packages/hardhat/test`. To run test use `yarn hardhat:test`

## Documentation

Expand Down
17 changes: 12 additions & 5 deletions templates/base/.gitignore.template.mjs
Original file line number Diff line number Diff line change
@@ -1,19 +1,26 @@
const contents = () =>
`node_modules
`# dependencies
node_modules
# dependencies, yarn, etc
# yarn / eslint
# yarn
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions
# eslint
.eslintcache
.vscode/**
# misc
.DS_Store
# IDE
.vscode
.idea
.vercel`;
# cli
dist`;

export default contents
4 changes: 2 additions & 2 deletions templates/base/packages/nextjs/.gitignore.template.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const contents = () =>
# next.js
/.next/
/out/
.vercel
# production
/build
Expand All @@ -34,7 +35,6 @@ yarn-error.log*
.env.production.local
# typescript
*.tsbuildinfo
.vercel`
*.tsbuildinfo`

export default contents
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export const SearchBar = () => {
event.preventDefault();
if (isHex(searchInput)) {
try {
const tx = await client.getTransaction({ hash: searchInput });
const tx = await client?.getTransaction({ hash: searchInput });
if (tx) {
router.push(`/blockexplorer/transaction/${searchInput}`);
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const TransactionPage: NextPage<PageProps> = ({ params }: PageProps) => {
const { targetNetwork } = useTargetNetwork();

useEffect(() => {
if (txHash) {
if (txHash && client) {
const fetchTransaction = async () => {
const tx = await client.getTransaction({ hash: txHash });
const receipt = await client.getTransactionReceipt({ hash: txHash });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ import { InheritanceTooltip } from "./InheritanceTooltip";
import { displayTxResult } from "./utilsDisplay";
import { Abi, AbiFunction } from "abitype";
import { Address } from "viem";
import { useContractRead } from "wagmi";
import { useReadContract } from "wagmi";
import { ArrowPathIcon } from "@heroicons/react/24/outline";
import { useAnimationConfig } from "~~/hooks/scaffold-eth";
import { notification } from "~~/utils/scaffold-eth";
import { useTargetNetwork } from "~~/hooks/scaffold-eth/useTargetNetwork";
import { getParsedError, notification } from "~~/utils/scaffold-eth";

type DisplayVariableProps = {
contractAddress: Address;
Expand All @@ -25,16 +26,20 @@ export const DisplayVariable = ({
abi,
inheritedFrom,
}: DisplayVariableProps) => {
const { targetNetwork } = useTargetNetwork();

const {
data: result,
isFetching,
refetch,
} = useContractRead({
error,
} = useReadContract({
address: contractAddress,
functionName: abiFunction.name,
abi: abi,
onError: error => {
notification.error(error.message);
chainId: targetNetwork.id,
query: {
retry: false,
},
});

Expand All @@ -44,6 +49,13 @@ export const DisplayVariable = ({
refetch();
}, [refetch, refreshDisplayVariables]);

useEffect(() => {
if (error) {
const parsedError = getParsedError(error);
notification.error(parsedError);
}
}, [error]);

return (
<div className="space-y-1 pb-2">
<div className="flex items-center">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
"use client";

import { useState } from "react";
import { useEffect, useState } from "react";
import { InheritanceTooltip } from "./InheritanceTooltip";
import { Abi, AbiFunction } from "abitype";
import { Address } from "viem";
import { useContractRead } from "wagmi";
import { useReadContract } from "wagmi";
import {
ContractInput,
displayTxResult,
Expand All @@ -13,6 +13,7 @@ import {
getParsedContractFunctionArgs,
transformAbiFunction,
} from "~~/app/debug/_components/contract";
import { useTargetNetwork } from "~~/hooks/scaffold-eth/useTargetNetwork";
import { getParsedError, notification } from "~~/utils/scaffold-eth";

type ReadOnlyFunctionFormProps = {
Expand All @@ -30,19 +31,27 @@ export const ReadOnlyFunctionForm = ({
}: ReadOnlyFunctionFormProps) => {
const [form, setForm] = useState<Record<string, any>>(() => getInitialFormState(abiFunction));
const [result, setResult] = useState<unknown>();
const { targetNetwork } = useTargetNetwork();

const { isFetching, refetch } = useContractRead({
const { isFetching, refetch, error } = useReadContract({
address: contractAddress,
functionName: abiFunction.name,
abi: abi,
args: getParsedContractFunctionArgs(form),
enabled: false,
onError: (error: any) => {
const parsedErrror = getParsedError(error);
notification.error(parsedErrror);
chainId: targetNetwork.id,
query: {
enabled: false,
retry: false,
},
});

useEffect(() => {
if (error) {
const parsedError = getParsedError(error);
notification.error(parsedError);
}
}, [error]);

const transformedFunction = transformAbiFunction(abiFunction);
const inputElements = transformedFunction.inputs.map((input, inputIndex) => {
const key = getFunctionInputKey(abiFunction.name, input, inputIndex);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { useEffect, useState } from "react";
import { InheritanceTooltip } from "./InheritanceTooltip";
import { Abi, AbiFunction } from "abitype";
import { Address, TransactionReceipt } from "viem";
import { useContractWrite, useNetwork, useWaitForTransaction } from "wagmi";
import { useAccount, useWaitForTransactionReceipt, useWriteContract } from "wagmi";
import {
ContractInput,
TxReceipt,
Expand Down Expand Up @@ -34,26 +34,24 @@ export const WriteOnlyFunctionForm = ({
}: WriteOnlyFunctionFormProps) => {
const [form, setForm] = useState<Record<string, any>>(() => getInitialFormState(abiFunction));
const [txValue, setTxValue] = useState<string | bigint>("");
const { chain } = useNetwork();
const { chain } = useAccount();
const writeTxn = useTransactor();
const { targetNetwork } = useTargetNetwork();
const writeDisabled = !chain || chain?.id !== targetNetwork.id;

const {
data: result,
isLoading,
writeAsync,
} = useContractWrite({
address: contractAddress,
functionName: abiFunction.name,
abi: abi,
args: getParsedContractFunctionArgs(form),
});
const { data: result, isPending, writeContractAsync } = useWriteContract();

const handleWrite = async () => {
if (writeAsync) {
if (writeContractAsync) {
try {
const makeWriteWithParams = () => writeAsync({ value: BigInt(txValue) });
const makeWriteWithParams = () =>
writeContractAsync({
address: contractAddress,
functionName: abiFunction.name,
abi: abi,
args: getParsedContractFunctionArgs(form),
value: BigInt(txValue),
});
await writeTxn(makeWriteWithParams);
onChange();
} catch (e: any) {
Expand All @@ -63,8 +61,8 @@ export const WriteOnlyFunctionForm = ({
};

const [displayedTxResult, setDisplayedTxResult] = useState<TransactionReceipt>();
const { data: txResult } = useWaitForTransaction({
hash: result?.hash,
const { data: txResult } = useWaitForTransactionReceipt({
hash: result,
});
useEffect(() => {
setDisplayedTxResult(txResult);
Expand Down Expand Up @@ -126,8 +124,8 @@ export const WriteOnlyFunctionForm = ({
}`}
data-tip={`${writeDisabled && "Wallet not connected or in the wrong network"}`}
>
<button className="btn btn-secondary btn-sm" disabled={writeDisabled || isLoading} onClick={handleWrite}>
{isLoading && <span className="loading loading-spinner loading-xs"></span>}
<button className="btn btn-secondary btn-sm" disabled={writeDisabled || isPending} onClick={handleWrite}>
{isPending && <span className="loading loading-spinner loading-xs"></span>}
Send 💸
</button>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@

import { useEffect, useState } from "react";
import { RainbowKitProvider, darkTheme, lightTheme } from "@rainbow-me/rainbowkit";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { useTheme } from "next-themes";
import { Toaster } from "react-hot-toast";
import { WagmiConfig } from "wagmi";
import { WagmiProvider } from "wagmi";
import { Footer } from "~~/components/Footer";
import { Header } from "~~/components/Header";
import { BlockieAvatar } from "~~/components/scaffold-eth";
import { ProgressBar } from "~~/components/scaffold-eth/ProgressBar";
import { useNativeCurrencyPrice } from "~~/hooks/scaffold-eth";
import { useGlobalState } from "~~/services/store/store";
import { wagmiConfig } from "~~/services/web3/wagmiConfig";
import { appChains } from "~~/services/web3/wagmiConnectors";

const ScaffoldEthApp = ({ children }: { children: React.ReactNode }) => {
const price = useNativeCurrencyPrice();
Expand All @@ -36,6 +36,14 @@ const ScaffoldEthApp = ({ children }: { children: React.ReactNode }) => {
);
};

export const queryClient = new QueryClient({
defaultOptions: {
queries: {
refetchOnWindowFocus: false,
},
},
});

export const ScaffoldEthAppWithProviders = ({ children }: { children: React.ReactNode }) => {
const { resolvedTheme } = useTheme();
const isDarkMode = resolvedTheme === "dark";
Expand All @@ -46,15 +54,16 @@ export const ScaffoldEthAppWithProviders = ({ children }: { children: React.Reac
}, []);

return (
<WagmiConfig config={wagmiConfig}>
<ProgressBar />
<RainbowKitProvider
chains={appChains.chains}
avatar={BlockieAvatar}
theme={mounted ? (isDarkMode ? darkTheme() : lightTheme()) : lightTheme()}
>
<ScaffoldEthApp>{children}</ScaffoldEthApp>
</RainbowKitProvider>
</WagmiConfig>
<WagmiProvider config={wagmiConfig}>
<QueryClientProvider client={queryClient}>
<ProgressBar />
<RainbowKitProvider
avatar={BlockieAvatar}
theme={mounted ? (isDarkMode ? darkTheme() : lightTheme()) : lightTheme()}
>
<ScaffoldEthApp>{children}</ScaffoldEthApp>
</RainbowKitProvider>
</QueryClientProvider>
</WagmiProvider>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Link from "next/link";
import { CopyToClipboard } from "react-copy-to-clipboard";
import { Address as AddressType, getAddress, isAddress } from "viem";
import { hardhat } from "viem/chains";
import { normalize } from "viem/ens";
import { useEnsAvatar, useEnsName } from "wagmi";
import { CheckCircleIcon, DocumentDuplicateIcon } from "@heroicons/react/24/outline";
import { BlockieAvatar } from "~~/components/scaffold-eth";
Expand Down Expand Up @@ -41,14 +42,18 @@ export const Address = ({ address, disableAddressLink, format, size = "base" }:

const { data: fetchedEns } = useEnsName({
address: checkSumAddress,
enabled: isAddress(checkSumAddress ?? ""),
chainId: 1,
query: {
enabled: isAddress(checkSumAddress ?? ""),
},
});
const { data: fetchedEnsAvatar } = useEnsAvatar({
name: fetchedEns,
enabled: Boolean(fetchedEns),
name: fetchedEns ? normalize(fetchedEns) : undefined,
chainId: 1,
cacheTime: 30_000,
query: {
enabled: Boolean(fetchedEns),
gcTime: 30_000,
},
});

// We need to apply this pattern to avoid Hydration errors.
Expand Down
Loading

0 comments on commit 7675de4

Please sign in to comment.