-
Notifications
You must be signed in to change notification settings - Fork 927
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
Optional chain parameter in Scaffold hooks #931
Optional chain parameter in Scaffold hooks #931
Conversation
Any more thoughts on this? |
Hey @JacobHomanics love this and very helpful! Some initial thoughts, on ideally how the API should look like:
|
Great! I've taken ya'lls feedback into consideration. Let me know your updated thoughts on the modifications! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for updates @JacobHomanics ! Overall looking good!
Added some nitpicks. Also, before merging this we need to add PR to update docs and merge those two PRs together
Everything else has been accounted for! @rin-st Let me know of any more proposed changes, then will try my hand at updating the docs. |
Great, thank you!
For me, just #931 (comment) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is amazing and works great! Tsym @JacobHomanics!!
@JacobHomanics do you want to make a PR to the SE-2 docs? Lets keep it simple and minimal. I think we just need to do this changes:
- Replace 1 param with object for the changed hooks
- Add chainId to accepted params tables for the respective hoooks
If anyone wants to test:
- Copy this in
deployedContracts.ts
`deployedContracts.ts`
/**
* This file is autogenerated by Scaffold-ETH.
* You should not edit it manually or your changes might be overwritten.
*/
import { GenericContractsDeclaration } from "~~/utils/scaffold-eth/contract";
const deployedContracts = {
31337: {
YourContract: {
address: "0x5FbDB2315678afecb367f032d93F642f64180aa3",
abi: [
{
inputs: [
{
internalType: "address",
name: "_owner",
type: "address",
},
],
stateMutability: "nonpayable",
type: "constructor",
},
{
anonymous: false,
inputs: [
{
indexed: true,
internalType: "address",
name: "greetingSetter",
type: "address",
},
{
indexed: false,
internalType: "string",
name: "newGreeting",
type: "string",
},
{
indexed: false,
internalType: "bool",
name: "premium",
type: "bool",
},
{
indexed: false,
internalType: "uint256",
name: "value",
type: "uint256",
},
],
name: "GreetingChange",
type: "event",
},
{
inputs: [],
name: "greeting",
outputs: [
{
internalType: "string",
name: "",
type: "string",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [],
name: "owner",
outputs: [
{
internalType: "address",
name: "",
type: "address",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [],
name: "premium",
outputs: [
{
internalType: "bool",
name: "",
type: "bool",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [
{
internalType: "string",
name: "_newGreeting",
type: "string",
},
],
name: "setGreeting",
outputs: [],
stateMutability: "payable",
type: "function",
},
{
inputs: [],
name: "totalCounter",
outputs: [
{
internalType: "uint256",
name: "",
type: "uint256",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [
{
internalType: "address",
name: "",
type: "address",
},
],
name: "userGreetingCounter",
outputs: [
{
internalType: "uint256",
name: "",
type: "uint256",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [],
name: "withdraw",
outputs: [],
stateMutability: "nonpayable",
type: "function",
},
{
stateMutability: "payable",
type: "receive",
},
],
inheritedFunctions: {},
},
},
84532: {
YourContract: {
address: "0x9Bf3fBCFc62109562bC8bB1F9b092eF285030B22",
abi: [
{
inputs: [
{
internalType: "address",
name: "_owner",
type: "address",
},
],
stateMutability: "nonpayable",
type: "constructor",
},
{
anonymous: false,
inputs: [
{
indexed: true,
internalType: "address",
name: "greetingSetter",
type: "address",
},
{
indexed: false,
internalType: "string",
name: "newGreeting",
type: "string",
},
{
indexed: false,
internalType: "bool",
name: "premium",
type: "bool",
},
{
indexed: false,
internalType: "uint256",
name: "value",
type: "uint256",
},
],
name: "GreetingChange",
type: "event",
},
{
inputs: [],
name: "greeting",
outputs: [
{
internalType: "string",
name: "",
type: "string",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [],
name: "owner",
outputs: [
{
internalType: "address",
name: "",
type: "address",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [],
name: "premium",
outputs: [
{
internalType: "bool",
name: "",
type: "bool",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [
{
internalType: "string",
name: "_newGreeting",
type: "string",
},
],
name: "setGreeting",
outputs: [],
stateMutability: "payable",
type: "function",
},
{
inputs: [],
name: "totalCounter",
outputs: [
{
internalType: "uint256",
name: "",
type: "uint256",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [
{
internalType: "address",
name: "",
type: "address",
},
],
name: "userGreetingCounter",
outputs: [
{
internalType: "uint256",
name: "",
type: "uint256",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [],
name: "withdraw",
outputs: [],
stateMutability: "nonpayable",
type: "function",
},
{
stateMutability: "payable",
type: "receive",
},
],
inheritedFunctions: {},
},
},
11155420: {
YourContract: {
address: "0x4D634e9BD2646Eb5Aa085bF4f4D76B62B2d3655f",
abi: [
{
inputs: [
{
internalType: "address",
name: "_owner",
type: "address",
},
],
stateMutability: "nonpayable",
type: "constructor",
},
{
anonymous: false,
inputs: [
{
indexed: true,
internalType: "address",
name: "greetingSetter",
type: "address",
},
{
indexed: false,
internalType: "string",
name: "newGreeting",
type: "string",
},
{
indexed: false,
internalType: "bool",
name: "premium",
type: "bool",
},
{
indexed: false,
internalType: "uint256",
name: "value",
type: "uint256",
},
],
name: "GreetingChange",
type: "event",
},
{
inputs: [],
name: "greeting",
outputs: [
{
internalType: "string",
name: "",
type: "string",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [],
name: "owner",
outputs: [
{
internalType: "address",
name: "",
type: "address",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [],
name: "premium",
outputs: [
{
internalType: "bool",
name: "",
type: "bool",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [
{
internalType: "string",
name: "_newGreeting",
type: "string",
},
],
name: "setGreeting",
outputs: [],
stateMutability: "payable",
type: "function",
},
{
inputs: [],
name: "totalCounter",
outputs: [
{
internalType: "uint256",
name: "",
type: "uint256",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [
{
internalType: "address",
name: "",
type: "address",
},
],
name: "userGreetingCounter",
outputs: [
{
internalType: "uint256",
name: "",
type: "uint256",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [],
name: "withdraw",
outputs: [],
stateMutability: "nonpayable",
type: "function",
},
{
stateMutability: "payable",
type: "receive",
},
],
inheritedFunctions: {},
},
},
} as const;
export default deployedContracts satisfies GenericContractsDeclaration;
-
Update the scaffold.config to have
[chains.baseSepolia, chains.optimismSepolia]
-
Update
page.tsx
with this:
`page.tsx`
"use client";
import { useState } from "react";
import type { NextPage } from "next";
import { optimismSepolia } from "viem/chains";
import { InputBase } from "~~/components/scaffold-eth";
import { useScaffoldReadContract, useScaffoldWriteContract } from "~~/hooks/scaffold-eth";
const Home: NextPage = () => {
const [greeting, setGreeting] = useState("");
const { data: greetingOnUserSelectedChain } = useScaffoldReadContract({
contractName: "YourContract",
functionName: "greeting",
});
const { data: greetingOnOPSepolia } = useScaffoldReadContract({
contractName: "YourContract",
functionName: "greeting",
chainId: optimismSepolia.id,
});
const { writeContractAsync: writeContractAsyncOnUserChain } = useScaffoldWriteContract({
contractName: "YourContract",
});
const { writeContractAsync: writeContractAsyncOPSepolia } = useScaffoldWriteContract({
contractName: "YourContract",
chainId: optimismSepolia.id,
});
return (
<>
<div className="flex items-center flex-col flex-grow pt-10">
<InputBase value={greeting} onChange={setGreeting} />
<button
className="btn btn-primary mt-4"
onClick={async () => {
try {
await writeContractAsyncOPSepolia({ functionName: "setGreeting", args: [greeting] });
} catch (e) {
console.error(e);
}
}}
>
Write on OP Sepolia
</button>
<button
className="btn btn-primary mt-4"
onClick={async () => {
try {
await writeContractAsyncOnUserChain({ functionName: "setGreeting", args: [greeting] });
} catch (e) {
console.error(e);
}
}}
>
Write on connectChain
</button>
<p className="mt-4">Greeting on OP Sepolia: {greetingOnOPSepolia}</p>
<p className="mt-4">Greeting on connectChain: {greetingOnUserSelectedChain}</p>
</div>
</>
);
};
export default Home;
Description
Provides the option to pass a different network into the scaffold hooks than the one that the user's wallet is currently connected to. This allows for applications that can show data from different blockchains than that of which the user's wallet is connected to. The hooks still abide by the rules that the contract instance's need to be within the
deployedContracts
file andtargetNetworks
needs to have the expected chain(s) present.live example: https://scaffold-eth-optional-chains-example-nextjs.vercel.app/
live example repo: https://github.com/Hotmanics/scaffold-eth-optionalChainsExample
Additional Information
Your ENS/address: jacobhomanics.eth