Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migration to wagmi v1 and viem #352

Merged
merged 79 commits into from
Jul 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
79 commits
Select commit Hold shift + click to select a range
9a2b016
upgrade wagmi and add viem
technophile-04 May 23, 2023
f0017fa
upgrade rainbowkit to v1
technophile-04 May 23, 2023
e4bd460
update wagmiConnectors.tsx
technophile-04 May 24, 2023
5b82efc
update wagmiClient.tsx
technophile-04 May 24, 2023
d64abe9
rename wagmiClient -> wagmiConfig more inlined with wagmi
technophile-04 May 24, 2023
75c12a9
fix useEnsAvatar hook
technophile-04 May 24, 2023
73d40ba
fix Connectory type in useAutoConnect hook
technophile-04 May 24, 2023
de6985d
WIP: fix useDeployedContractInfo with bug in Address
technophile-04 May 24, 2023
3cb837e
assert Address type from viem in useDeployedContractInfo hook
technophile-04 May 24, 2023
047c2fd
update useNativeCurrencyPrice and todo for useDeployedContract
technophile-04 May 26, 2023
9798b62
rename provider to publicClient
technophile-04 May 26, 2023
67ec461
update useScaffoldContract and corresponding README
technophile-04 May 26, 2023
f533d40
remove file added by mistake
technophile-04 May 27, 2023
5d0b521
fix:AddressType, up wami and viem
technophile-04 May 28, 2023
f15a77d
remove AddressType assertion
technophile-04 May 28, 2023
066a3ae
Merge remote-tracking branch 'origin/main' into migration/wagmi-1.x
technophile-04 May 28, 2023
d55d517
WIP: Update useTransactor, Faucet, remove getLocalProvider
technophile-04 May 28, 2023
75ce0c3
refactor: migrate scaffold write hook to use viem
sverps Jun 2, 2023
bc2776e
refactor: partial migration of ethers -> viem, mainly BigNumber to bi…
sverps Jun 2, 2023
04cddb1
Merge branch 'main' into migration/wagmi-1.x
technophile-04 Jun 3, 2023
c0c5f67
update comments for useTransactor
technophile-04 Jun 3, 2023
76b09f8
WIP: fix useBurnerWallet
technophile-04 Jun 3, 2023
28e9608
complete buner wallet
technophile-04 Jun 3, 2023
dc048cf
put ethers providers for Connector of buner wallet
technophile-04 Jun 3, 2023
3028a5b
put deployedContracts back to null
technophile-04 Jun 3, 2023
d3d2b31
wip(ContractUI): ethers -> viem
sverps Jun 3, 2023
c80f5ef
refactor(ContractUI): ethers -> viem
sverps Jun 4, 2023
4f9c7d6
refactor(useScaffoldEventHistory): ethers -> viem
sverps Jun 4, 2023
59dc486
refactor: ethers - viem util functions
sverps Jun 5, 2023
720493f
refactor(useScaffoldEventSubscriber): updated wagmi lib
sverps Jun 5, 2023
09f14bf
fix: useContractWrite value takes a string in ether
sverps Jun 5, 2023
574e158
wip(decodeTxData): ethers -> viem
sverps Jun 5, 2023
92abc2c
update DisplayVaribles: useScaffold-> useContractRead, fix: abi requi…
technophile-04 Jun 8, 2023
de6a489
remove console and fix prettier warning
technophile-04 Jun 8, 2023
22c0272
refacotr ReadMethodsWith params
technophile-04 Jun 8, 2023
ba87174
refactor WritOnlyFunction to usePrepareContractWrite
technophile-04 Jun 9, 2023
7845914
update viem to latest version
sverps Jun 9, 2023
4a7c345
fix enabled config type error in AddressInput
technophile-04 Jun 10, 2023
6d7c4b9
decode functionName and data properly
technophile-04 Jun 10, 2023
104e42a
remove extra type in decodeTxn
technophile-04 Jun 10, 2023
ecf87f1
fix type error in useFetchBlock
technophile-04 Jun 10, 2023
de9e470
complete blockexplorer
technophile-04 Jun 10, 2023
656aec5
update versions of wagmi and viem
technophile-04 Jun 14, 2023
06d3cb5
use useContractWrite and update parsing error func inline with viem
technophile-04 Jun 15, 2023
5aaca1c
update fetchPrice use @etherprojcet/provider
technophile-04 Jun 15, 2023
447a093
remove ethers from nextjs dependency and fix failing next:check-types
technophile-04 Jun 15, 2023
087baa8
Merge origin/main into migration/wagmi-1.x
technophile-04 Jun 15, 2023
60d0389
remove AddressType assertions
technophile-04 Jun 17, 2023
cded40d
change localhost.id -> hardhat.id
technophile-04 Jun 17, 2023
2eedb34
fix gn-actions-fail: Omit mode from useContractWriteConfig for useSca…
technophile-04 Jun 17, 2023
e6c2433
Merge remote-tracking branch 'origin/main' into migration/wagmi-1.x
technophile-04 Jun 17, 2023
8f07140
fix contract's tab showing for every address on UI
technophile-04 Jun 19, 2023
48dec0b
fix AddressInput, make arg of onChange of CommonPropInputProp to stri…
technophile-04 Jun 20, 2023
636a131
Merge remote-tracking branch 'origin/main' into migration/wagmi-1.x
technophile-04 Jun 26, 2023
1f065f5
fix(useTransactor): pass the write as callback rather than as promise…
sverps Jun 26, 2023
71c0403
Revert "fix AddressInput, make arg of onChange of CommonPropInputProp…
sverps Jun 26, 2023
c13e535
fix(AddressInput): nicer behavior for string useState as controlled v…
sverps Jun 26, 2023
e742b0b
fix(useFetchBlocks): watchBlocks now receives full tx data
sverps Jun 26, 2023
8672243
Merge remote-tracking branch 'origin/main' into migration/wagmi-1.x
technophile-04 Jun 28, 2023
934b82a
update useScaffoldContractWrite to take args when calling writeAsync
technophile-04 Jun 28, 2023
ecad24c
up wagmi, viem, rainbow & remove @uniswap/sdk instead use @uniswap/v2…
technophile-04 Jun 28, 2023
9a01aa5
add alchemy link to publicClient in fetchUniswap func
technophile-04 Jun 28, 2023
50b7b02
remove parseTxnValue function & show error directly in UI
technophile-04 Jun 29, 2023
fcb9703
update handling of errors & dispaly error nicely
technophile-04 Jun 29, 2023
cf63271
update utilsDisplayy to show ETH value if value is big
technophile-04 Jun 29, 2023
d76328c
bugFix: when you sent 1 wei its was going 49wei
technophile-04 Jun 29, 2023
69a0464
remove console.log
sverps Jun 29, 2023
c21089e
remove console.logs from displayContent and TODO comment
technophile-04 Jun 30, 2023
1f46ed9
remove need of assertion for useScaffoldEventSubs due to contract fil…
technophile-04 Jun 30, 2023
a6fb33c
handle array and tuple inputs
technophile-04 Jun 30, 2023
439c4f2
fix: cleanup event listener logs type
sverps Jun 30, 2023
fc54d8f
Merge branch 'main' into migration/wagmi-1.x
technophile-04 Jul 3, 2023
9ab3636
fix ens Avatart not showing
technophile-04 Jul 4, 2023
bc9ae63
fix ContractRead/Write/Variables loading separately
technophile-04 Jul 4, 2023
da14bc9
fix Address component's ens avatar
technophile-04 Jul 4, 2023
5edb8f6
fix const spelling in README
technophile-04 Jul 4, 2023
3abac4a
remove assertion in ContractInteraction for useSEWrite
technophile-04 Jul 4, 2023
7938e0a
Fix error when inputing decimals in tx value
carletex Jul 5, 2023
b911815
Merge branch 'main' into migration/wagmi-1.x
carletex Jul 5, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 5 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -213,8 +213,8 @@ const {
} = useScaffoldEventHistory({
contractName: "YourContract",
eventName: "GreetingChange",
// Specify the starting block number from which to read events.
fromBlock: 31231,
// Specify the starting block number from which to read events, this is a bigint.
fromBlock: 31231n,
blockData: true,
// Apply filters to the event based on parameter names and values { [parameterName]: value },
filters: { premium: true }
Expand Down Expand Up @@ -251,13 +251,12 @@ const { data: yourContract } = useScaffoldContract({
await yourContract?.greeting();

// Used to write to a contract and can be called in any function
import { Signer } from "ethers";
import { useSigner } from "wagmi";
import { useWalletClient } from "wagmi";

const { data: signer, isError, isLoading } = useSigner();
const { data: walletClient } = useWalletClient();
const { data: yourContract } = useScaffoldContract({
contractName: "YourContract",
signerOrProvider: signer as Signer,
walletClient,
});
const setGreeting = async () => {
// Call the method in any function
Expand Down
6 changes: 4 additions & 2 deletions packages/nextjs/components/blockexplorer/AddressLogsTab.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { Address } from "viem";
import { useContractLogs } from "~~/hooks/scaffold-eth";
import { replacer } from "~~/utils/scaffold-eth/common";

export const AddressLogsTab = ({ address }: { address: string }) => {
export const AddressLogsTab = ({ address }: { address: Address }) => {
const contractLogs = useContractLogs(address);

return (
Expand All @@ -9,7 +11,7 @@ export const AddressLogsTab = ({ address }: { address: string }) => {
<pre className="px-5 whitespace-pre-wrap break-words">
{contractLogs.map((log, i) => (
<div key={i}>
<strong>Log:</strong> {JSON.stringify(log, null, 2)}
<strong>Log:</strong> {JSON.stringify(log, replacer, 2)}
</div>
))}
</pre>
Expand Down
14 changes: 10 additions & 4 deletions packages/nextjs/components/blockexplorer/AddressStorageTab.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { useEffect, useState } from "react";
import { localhost } from "wagmi/chains";
import { getLocalProvider } from "~~/utils/scaffold-eth";
import { createPublicClient, http, toHex } from "viem";
import { hardhat } from "wagmi/chains";

const provider = getLocalProvider(localhost);
const publicClient = createPublicClient({
chain: hardhat,
transport: http(),
});

export const AddressStorageTab = ({ address }: { address: string }) => {
const [storage, setStorage] = useState<string[]>([]);
Expand All @@ -14,7 +17,10 @@ export const AddressStorageTab = ({ address }: { address: string }) => {
let idx = 0;

while (true) {
const storageAtPosition = await provider?.getStorageAt(address, idx);
const storageAtPosition = await publicClient.getStorageAt({
address: address,
slot: toHex(idx),
});

if (storageAtPosition === "0x" + "0".repeat(64)) break;

Expand Down
15 changes: 8 additions & 7 deletions packages/nextjs/components/blockexplorer/SearchBar.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
import { useState } from "react";
import { useRouter } from "next/router";
import { ethers } from "ethers";
import { localhost } from "wagmi/chains";
import { getLocalProvider } from "~~/utils/scaffold-eth";
import { isAddress, isHex } from "viem";
import { usePublicClient } from "wagmi";
import { hardhat } from "wagmi/chains";

const provider = getLocalProvider(localhost);
export const SearchBar = () => {
const [searchInput, setSearchInput] = useState("");
const router = useRouter();

const client = usePublicClient({ chainId: hardhat.id });

const handleSearch = async (event: React.FormEvent) => {
event.preventDefault();
if (ethers.utils.isHexString(searchInput)) {
if (isHex(searchInput)) {
try {
const tx = await provider?.getTransaction(searchInput);
const tx = await client.getTransaction({ hash: searchInput });
if (tx) {
router.push(`/blockexplorer/transaction/${searchInput}`);
return;
Expand All @@ -23,7 +24,7 @@ export const SearchBar = () => {
}
}

if (ethers.utils.isAddress(searchInput)) {
if (isAddress(searchInput)) {
router.push(`/blockexplorer/address/${searchInput}`);
return;
}
Expand Down
14 changes: 7 additions & 7 deletions packages/nextjs/components/blockexplorer/TransactionsTable.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ethers } from "ethers";
import { formatEther } from "viem";
import { TransactionHash } from "~~/components/blockexplorer/TransactionHash";
import { Address } from "~~/components/scaffold-eth";
import { getTargetNetwork } from "~~/utils/scaffold-eth";
import { TransactionWithFunction, getTargetNetwork } from "~~/utils/scaffold-eth";
import { TransactionsTableProps } from "~~/utils/scaffold-eth/";

export const TransactionsTable = ({ blocks, transactionReceipts, isLoading }: TransactionsTableProps) => {
Expand Down Expand Up @@ -36,10 +36,10 @@ export const TransactionsTable = ({ blocks, transactionReceipts, isLoading }: Tr
) : (
<tbody>
{blocks.map(block =>
block.transactions.map(tx => {
(block.transactions as TransactionWithFunction[]).map(tx => {
const receipt = transactionReceipts[tx.hash];
const timeMined = new Date(block.timestamp * 1000).toLocaleString();
const functionCalled = tx.data.substring(0, 10);
const timeMined = new Date(Number(block.timestamp) * 1000).toLocaleString();
const functionCalled = tx.input.substring(0, 10);

return (
<tr key={tx.hash} className="hover text-sm">
Expand All @@ -52,7 +52,7 @@ export const TransactionsTable = ({ blocks, transactionReceipts, isLoading }: Tr
<span className="badge badge-primary font-bold text-xs">{functionCalled}</span>
)}
</td>
<td className="w-1/12">{block.number}</td>
<td className="w-1/12">{block.number?.toString()}</td>
<td className="w-2/12">{timeMined}</td>
<td className="w-2/12">
<Address address={tx.from} size="sm" />
Expand All @@ -68,7 +68,7 @@ export const TransactionsTable = ({ blocks, transactionReceipts, isLoading }: Tr
)}
</td>
<td className="text-right">
{ethers.utils.formatEther(tx.value)} {targetNetwork.nativeCurrency.symbol}
{formatEther(tx.value)} {targetNetwork.nativeCurrency.symbol}
</td>
</tr>
);
Expand Down
9 changes: 6 additions & 3 deletions packages/nextjs/components/example-ui/ContractData.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,11 @@ export const ContractData = () => {
useScaffoldEventSubscriber({
contractName: "YourContract",
eventName: "GreetingChange",
listener: (greetingSetter, newGreeting, premium, value) => {
console.log(greetingSetter, newGreeting, premium, value);
listener: logs => {
logs.map(log => {
const { greetingSetter, value, premium, newGreeting } = log.args;
console.log("📡 GreetingChange event", greetingSetter, value, premium, newGreeting);
});
carletex marked this conversation as resolved.
Show resolved Hide resolved
},
});

Expand All @@ -45,7 +48,7 @@ export const ContractData = () => {
} = useScaffoldEventHistory({
contractName: "YourContract",
eventName: "GreetingChange",
fromBlock: Number(process.env.NEXT_PUBLIC_DEPLOY_BLOCK) || 0,
fromBlock: process.env.NEXT_PUBLIC_DEPLOY_BLOCK ? BigInt(process.env.NEXT_PUBLIC_DEPLOY_BLOCK) : 0n,
filters: { greetingSetter: address },
blockData: true,
});
Expand Down
9 changes: 4 additions & 5 deletions packages/nextjs/components/scaffold-eth/Address.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { useEffect, useState } from "react";
import Link from "next/link";
import { ethers } from "ethers";
import { isAddress } from "ethers/lib/utils";
import Blockies from "react-blockies";
import { CopyToClipboard } from "react-copy-to-clipboard";
import { isAddress } from "viem";
import { useEnsAvatar, useEnsName } from "wagmi";
import { hardhat } from "wagmi/chains";
import { CheckCircleIcon, DocumentDuplicateIcon } from "@heroicons/react/24/outline";
Expand Down Expand Up @@ -36,8 +35,8 @@ export const Address = ({ address, disableAddressLink, format, size = "base" }:

const { data: fetchedEns } = useEnsName({ address, enabled: isAddress(address ?? ""), chainId: 1 });
const { data: fetchedEnsAvatar } = useEnsAvatar({
address,
enabled: isAddress(address ?? ""),
name: fetchedEns,
enabled: Boolean(fetchedEns),
chainId: 1,
cacheTime: 30_000,
});
Expand All @@ -63,7 +62,7 @@ export const Address = ({ address, disableAddressLink, format, size = "base" }:
);
}

if (!ethers.utils.isAddress(address)) {
if (!isAddress(address)) {
return <span className="text-error">Wrong address</span>;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Dispatch, SetStateAction } from "react";
import { utils } from "ethers";
import { AbiParameter } from "abitype";
import {
AddressInput,
Bytes32Input,
Expand All @@ -11,9 +11,9 @@ import {

type ContractInputProps = {
setForm: Dispatch<SetStateAction<Record<string, any>>>;
form: Record<string, any>;
form: Record<string, any> | undefined;
stateObjectKey: string;
paramType: utils.ParamType;
paramType: AbiParameter;
};

/**
Expand All @@ -22,7 +22,7 @@ type ContractInputProps = {
export const ContractInput = ({ setForm, form, stateObjectKey, paramType }: ContractInputProps) => {
const inputProps = {
name: stateObjectKey,
value: form[stateObjectKey],
value: form?.[stateObjectKey],
placeholder: paramType.name ? `${paramType.type} ${paramType.name}` : paramType.type,
onChange: (value: any) => {
setForm(form => ({ ...form, [stateObjectKey]: value }));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { ReadOnlyFunctionForm } from "./ReadOnlyFunctionForm";
import { Abi, AbiFunction } from "abitype";
import { Contract, ContractName } from "~~/utils/scaffold-eth/contract";

export const ContractReadMethods = ({ deployedContractData }: { deployedContractData: Contract<ContractName> }) => {
if (!deployedContractData) {
return null;
}

const functionsToDisplay = (
((deployedContractData.abi || []) as Abi).filter(part => part.type === "function") as AbiFunction[]
).filter(fn => {
const isQueryableWithParams =
(fn.stateMutability === "view" || fn.stateMutability === "pure") && fn.inputs.length > 0;
return isQueryableWithParams;
});

if (!functionsToDisplay.length) {
return <>No read methods</>;
}

return (
<>
{functionsToDisplay.map(fn => (
<ReadOnlyFunctionForm contractAddress={deployedContractData.address} abiFunction={fn} key={fn.name} />
))}
</>
);
};
52 changes: 15 additions & 37 deletions packages/nextjs/components/scaffold-eth/Contract/ContractUI.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
import { useMemo, useState } from "react";
import { Abi } from "abitype";
import { useContract, useProvider } from "wagmi";
import { useReducer } from "react";
import { ContractReadMethods } from "./ContractReadMethods";
import { ContractVariables } from "./ContractVariables";
import { ContractWriteMethods } from "./ContractWriteMethods";
import { Spinner } from "~~/components/Spinner";
import {
Address,
Balance,
getAllContractFunctions,
getContractReadOnlyMethodsWithParams,
getContractVariablesAndNoParamsReadMethods,
getContractWriteMethods,
} from "~~/components/scaffold-eth";
import { Address, Balance } from "~~/components/scaffold-eth";
import { useDeployedContractInfo, useNetworkColor } from "~~/hooks/scaffold-eth";
import { getTargetNetwork } from "~~/utils/scaffold-eth";
import { ContractName } from "~~/utils/scaffold-eth/contract";
Expand All @@ -23,34 +17,12 @@ type ContractUIProps = {
* UI component to interface with deployed contracts.
**/
export const ContractUI = ({ contractName, className = "" }: ContractUIProps) => {
const provider = useProvider();
const [refreshDisplayVariables, setRefreshDisplayVariables] = useState(false);
const [refreshDisplayVariables, triggerRefreshDisplayVariables] = useReducer(value => !value, false);
const configuredNetwork = getTargetNetwork();

const { data: deployedContractData, isLoading: deployedContractLoading } = useDeployedContractInfo(contractName);
const networkColor = useNetworkColor();

const contract = useContract({
address: deployedContractData?.address,
abi: deployedContractData?.abi as Abi,
signerOrProvider: provider,
});

const displayedContractFunctions = useMemo(() => getAllContractFunctions(contract), [contract]);

const contractVariablesDisplay = useMemo(() => {
return getContractVariablesAndNoParamsReadMethods(contract, displayedContractFunctions, refreshDisplayVariables);
}, [contract, displayedContractFunctions, refreshDisplayVariables]);

const contractMethodsDisplay = useMemo(
() => getContractReadOnlyMethodsWithParams(contract, displayedContractFunctions),
[contract, displayedContractFunctions],
);
const contractWriteMethods = useMemo(
() => getContractWriteMethods(contract, displayedContractFunctions, setRefreshDisplayVariables),
[contract, displayedContractFunctions],
);

if (deployedContractLoading) {
return (
<div className="mt-14">
Expand Down Expand Up @@ -90,7 +62,10 @@ export const ContractUI = ({ contractName, className = "" }: ContractUIProps) =>
)}
</div>
<div className="bg-base-300 rounded-3xl px-6 lg:px-8 py-4 shadow-lg shadow-base-300">
{contractVariablesDisplay.methods.length > 0 ? contractVariablesDisplay.methods : "No contract variables"}
<ContractVariables
refreshDisplayVariables={refreshDisplayVariables}
deployedContractData={deployedContractData}
/>
</div>
</div>
<div className="col-span-1 lg:col-span-2 flex flex-col gap-6">
Expand All @@ -102,7 +77,7 @@ export const ContractUI = ({ contractName, className = "" }: ContractUIProps) =>
</div>
</div>
<div className="p-5 divide-y divide-base-300">
{contractMethodsDisplay.methods.length > 0 ? contractMethodsDisplay.methods : "No read methods"}
<ContractReadMethods deployedContractData={deployedContractData} />
</div>
</div>
</div>
Expand All @@ -114,7 +89,10 @@ export const ContractUI = ({ contractName, className = "" }: ContractUIProps) =>
</div>
</div>
<div className="p-5 divide-y divide-base-300">
{contractWriteMethods.methods.length > 0 ? contractWriteMethods.methods : "No write methods"}
<ContractWriteMethods
deployedContractData={deployedContractData}
onChange={triggerRefreshDisplayVariables}
/>
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { DisplayVariable } from "./DisplayVariable";
import { Abi, AbiFunction } from "abitype";
import { Contract, ContractName } from "~~/utils/scaffold-eth/contract";

export const ContractVariables = ({
refreshDisplayVariables,
deployedContractData,
}: {
refreshDisplayVariables: boolean;
deployedContractData: Contract<ContractName>;
}) => {
if (!deployedContractData) {
return null;
}

const functionsToDisplay = (
(deployedContractData.abi as Abi).filter(part => part.type === "function") as AbiFunction[]
).filter(fn => {
const isQueryableWithNoParams =
(fn.stateMutability === "view" || fn.stateMutability === "pure") && fn.inputs.length === 0;
return isQueryableWithNoParams;
});

if (!functionsToDisplay.length) {
return <>No contract variables</>;
}

return (
<>
{functionsToDisplay.map(fn => (
<DisplayVariable
abiFunction={fn}
contractAddress={deployedContractData.address}
key={fn.name}
refreshDisplayVariables={refreshDisplayVariables}
/>
))}
</>
);
};
Loading