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

fix(react): out-of-sync persisted contract results #552

Merged
merged 6 commits into from
Jun 6, 2022

Conversation

jxom
Copy link
Member

@jxom jxom commented Jun 4, 2022

Fixes #460

Description

There is an interesting bug where persisted useContractRead struct results would be out of sync with the ethers contract Result. This is because the ethers Result currently doesn't serialize properly with our serialize function. I first attempted to try fix this in our serialize/deserialize functions to try get it to persist into our storage, however, after doing that, I then realised that React Query also doesn't cater for this data structure in their data comparison functions.

In this proposed fix, I ended up just checking to see if the result returned from RQ is in an out-of-sync state, and if it is, it will use the contract interface to parse it back into an ethers contract Result.

@jxom jxom requested a review from tmm June 4, 2022 06:18
@changeset-bot
Copy link

changeset-bot bot commented Jun 4, 2022

⚠️ No Changeset found

Latest commit: 6840669

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@vercel
Copy link

vercel bot commented Jun 4, 2022

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Updated
wagmi ✅ Ready (Inspect) Visit Preview Jun 6, 2022 at 2:42PM (UTC)

Copy link
Member

@tmm tmm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice job hunting this down.

packages/react/src/hooks/contracts/useContractRead.ts Outdated Show resolved Hide resolved
packages/react/src/hooks/utils/index.ts Outdated Show resolved Hide resolved
packages/react/src/hooks/utils/parseContractResult.test.ts Outdated Show resolved Hide resolved
packages/react/src/hooks/utils/parseContractResult.test.ts Outdated Show resolved Hide resolved
Copy link
Member

@tmm tmm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great! Nice job on getting RQ update in.

@jxom jxom merged commit e65559e into main Jun 6, 2022
@jxom jxom deleted the jxom/fix-contract-result branch June 6, 2022 20:12
@0xfffxfff
Copy link

0xfffxfff commented Jun 8, 2022

@jxom Since updating to wagmi@0.4.10 I'm getting errors with all my instances of useContractRead:

next-dev.js?3515:25 TypeError: Cannot add property null, object is not extensible
    at Function.assign (<anonymous>)
    at parseContractResult (wagmi.esm.js?20d3:73:1)
    at Object.select (wagmi.esm.js?20d3:1275:1)
    at QueryObserver.createResult (queryObserver.mjs?eb18:273:1)
    at QueryObserver.getOptimisticResult (queryObserver.mjs?eb18:92:1)
    at useQuery (wagmi.esm.js?20d3:365:5)
    at useContractRead (wagmi.esm.js?20d3:1272:1)

For now I'm reverting to 0.4.7, our previous version. Any idea what this could be caused by?

npm view wagmi dependencies
{
  '@coinbase/wallet-sdk': '^3.2.0',
  '@wagmi/core': '^0.3.7',
  '@walletconnect/ethereum-provider': '^1.7.8',
  'react-query': '^4.0.0-beta.23',
  'use-sync-external-store': '^1.1.0'
}

@jxom
Copy link
Member Author

jxom commented Jun 8, 2022

@0xfffxfff would you be able to provide me with a minimal reproducible example via a CodeSandbox or something?
Thanks for spotting this too!

@0xfffxfff
Copy link

0xfffxfff commented Jun 8, 2022

@jxom We're in the middle of a release right now. I can try spinning one up on Monday. 👍

@0xfffxfff
Copy link

0xfffxfff commented Jun 8, 2022

@jxom Just to give you an idea where this happens:

const balanceOf = useKubboPartsRead('balanceOf', { args: account?.data?.address, enabled: Boolean(account?.data?.address), watch: true })

where useKubboPartsRead is a hook that wraps useContractRead

export const useKubboPartsRead = (
  functionName: string, config?: Parameters<typeof useContractRead>[2]
) => {
  const network = useNetwork()
  const contract = Contracts.KubboParts[network?.activeChain?.id || chain.mainnet.id];
  return useContractRead(contract, functionName, config)
}

Entirely possible that my use of the hook is causing this.

Edit: This is how we include our contracts

KubboParts[chain.mainnet.id] = {
  addressOrName: KubboPartsABI.address,
  contractInterface: KubboPartsABI.abi as ContractInterface,
} as UseContractConfig

@jxom
Copy link
Member Author

jxom commented Jun 8, 2022

Thanks! I'll do some digging.

@jxom
Copy link
Member Author

jxom commented Jun 9, 2022

@0xfffxfff – I'm assuming the return type of this method was a tuple?

There is a fix here: #566

@0xfffxfff
Copy link

0xfffxfff commented Jun 12, 2022

Thanks @jxom! This fixed it.

I'm assuming the return type of this method was a tuple?

It was an array of uint256. Funnily enough, I had to change a useEffect dependency from this:

  }, [
   tokensOf.data,
   ...
 ]);

to this:

 }, [
  tokensOf.data?.reduce((c,i) => c+i?.toString(),''),
  ...
]);

I'm guessing the reason is that it's no longer receiving the same array but rather a newly constructed one on each call? In any case, with this in place everything's now properly chugging along 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[bug] useContractRead not returning key/value pairs after second page refresh
3 participants