Closed technophile-04 closed 4 weeks ago
Great changes! And thank you for testing steps! 🙏
As I understand there's no polling interval anymore
upd. My bad, it works as expected
This should possibly be added to recipes
in docs
<button
className="btn btn-primary"
onClick={async () => {
try {
await writeYourContractAsync({
functionName: "setGreeting",
args: [newGreetings],
});
// refetch events again so that UI is reactive and shows the latest event
await refetchAllEvents();
} catch (e) {
console.error("Error setting greeting:", e);
}
}}
>
Set Greeting
</button>
Thanks Rinat and Damu review, updated it with suggested changes
Description:
Rewrote useScaffoldEventHistory with
useInfiniteQuery
fromtanstack-query
.Our present logic felt like a bit try-hard solution to get it working also introducing lots of imperative logic and also have a bug example #633.
I have been diving deep in to
tanstack-query
recently and also had #633 in back of mind for a while, anduseInfiniteQuery
seems like a perfect solution for this with some additional advantage:Solves #633
Cleans up the code nicely
feature like
refetch
, it will allow people to imperatively fetch events again after a write is performed(without needing for watch) :Example :
```tsx const { data: eventHistory, refetch: refetchAllEvents } = useScaffoldEventHistory({ contractName: "YourContract", eventName: "GreetingChange", filters: { greetingSetter: connectedAddress }, fromBlock: 0n, }); // ... ```Testing steps :
Switch to main branch.
2. Copy this in externalContract.ts :
```ts import { GenericContractsDeclaration } from "~~/utils/scaffold-eth/contract"; const externalContracts = { 11155111: { YourContract: { address: "0xE009aea21af005e6B531B5f4a8f909C64A0c596d", 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: "0x8806fc80A0274Eda6a45E2944f6bB6E6Bb635831", 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 externalContracts satisfies GenericContractsDeclaration; ```3. Copy this in `app/page.tsx` :
```tsx "use client"; import type { NextPage } from "next"; import { Address } from "~~/components/scaffold-eth"; import { useScaffoldEventHistory } from "~~/hooks/scaffold-eth"; const Home: NextPage = () => { const { data: eventHistory } = useScaffoldEventHistory({ contractName: "YourContract", eventName: "GreetingChange", fromBlock: 4738147n, }); return ( <>Welcome to Scaffold-ETH 2
Update
scaffold.config.ts#targetNetworks
with[chains.sepolia, chains.baseSepolia]
.yarn start.
Connect wallet and switch network to
baseSepolia
you will see that instead of showing just 3 events it appended the events to previously fetched events fromsepolia
Demo: bug video :
https://github.com/scaffold-eth/scaffold-eth-2/assets/80153681/ce9b3704-f366-4d53-b8da-3ea9dc5bd877Now switch to this branch(no need to stash above changes, you could directly switch to this PR branch) and try test point 6 again it should work as expected and solve #633.
Demo: bug is solved :
https://github.com/scaffold-eth/scaffold-eth-2/assets/80153681/90ee1d6e-cab7-410e-939a-15974acae309Testing watch mode:
Just to make sure we don't break anything and
watch
mode also works perfectly, you revert all the above changes keep everything clean switch to this branch. Run three magical commandyarn chain
,yarn deploy
andyarn start
after that copy this inapp/page.tsx
Example :
```tsx "use client"; import { useState } from "react"; import type { NextPage } from "next"; import { useAccount } from "wagmi"; import { Address, InputBase } from "~~/components/scaffold-eth"; import { useScaffoldEventHistory, useScaffoldWriteContract } from "~~/hooks/scaffold-eth"; const Home: NextPage = () => { const { address: connectedAddress } = useAccount(); const [newGreetings, setNewGreetings] = useStateWelcome to Scaffold-ETH 2
Set the greeting on home page and see it updating
Also types should also work as expected and consuming it still remains same, but we need to document some new return values like
refetch
,isFetchingNewEvents
in SE-2 docs