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

fixes #2531 value type on function overload #2561

Merged
merged 14 commits into from
Aug 6, 2024

Conversation

Yuripetusko
Copy link
Contributor

@Yuripetusko Yuripetusko commented Jul 30, 2024

fixes #2531 - infer correct type of value on function overload, by matching correct function signature from a union type, given the function args


PR-Codex overview

This PR focuses on improving type inference for function values in contracts.

Detailed summary

  • Added type definitions for GetMutabilityAwareValue and SimulateContractParameters in simulateContract.ts
  • Updated imports and types in simulateContract.ts and writeContract.ts
  • Fixed issue Fix: #2531 value types function overload #2560 related to function overloads in simulateContract.test-d.ts

✨ Ask PR-Codex anything about this PR by commenting with /codex {your question}

Copy link

changeset-bot bot commented Jul 30, 2024

🦋 Changeset detected

Latest commit: 3001b93

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
viem Patch

Not sure what this means? Click here to learn what changesets are.

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

Copy link

vercel bot commented Jul 30, 2024

@Yuripetusko is attempting to deploy a commit to the Wevm Team on Vercel.

A member of the Team first needs to authorize it.

@Yuripetusko Yuripetusko changed the title fixes #2560 value type on function overload fixes #2531 value type on function overload Jul 30, 2024
@jxom jxom self-requested a review July 30, 2024 03:44
Copy link
Member

@jxom jxom left a comment

Choose a reason for hiding this comment

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

Looks fine to me. Would be good to get @tmm eyes on it too!

@@ -303,10 +303,19 @@ export type EventDefinition = `${string}(${string})`

export type GetValue<
abi extends Abi | readonly unknown[],
functionName extends string,
mutability extends AbiStateMutability = AbiStateMutability,
Copy link
Contributor Author

@Yuripetusko Yuripetusko Jul 30, 2024

Choose a reason for hiding this comment

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

Ideally mutability should be inferred also, but it's hard to do because of the order of generics arguments (args would be needed to infer mutability on overloads, and mutability is needed to infer args). Also it sucks that it's a second argument of this Generic (because subsequent arguments require it), as it makes it hard to skip it if you don't want to pass it. But I couldn't think of a better way right now, or it would require a bigger refactor

Copy link
Member

Choose a reason for hiding this comment

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

Since GetValue is a public API (exported in index.ts), let's pull this logic directly into simulateContract.ts for now.

test/src/abis.ts Outdated
@@ -1363,6 +1363,16 @@ export const wagmiContractConfig = {
stateMutability: 'nonpayable',
type: 'function',
},
{
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I see that this config has a contract address, do I need to add this function to the actual contract? or it's fine to just have this dummy/placeholder abi for a contract that is not actually deployed?

Copy link
Member

Choose a reason for hiding this comment

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

Let's remove this addition to the ABI.

@tmm
Copy link
Member

tmm commented Jul 31, 2024

Will take a look tomorrow!

@Yuripetusko
Copy link
Contributor Author

Will take a look tomorrow!

bump

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.

Let's revert the change to GetValue and update SimulateContractParameters directly with this logic. Also, let's add the following test. (Haven't found a quick way to get @ts-expect-error to work correctly in this case so might be best to remove that for now. There's a larger type refactor coming to Viem, which will fix this so allowing it to pass for the time being isn't the end of the world.)

test('https://github.com/wevm/viem/issues/2531', async () => {
  const abi = parseAbi([
    'function safeTransferFrom(address, address, uint256)',
    'function safeTransferFrom(address, address, uint256, bytes) payable',
  ])

  const res1 = await simulateContract(client, {
    address: '0x',
    abi,
    functionName: 'safeTransferFrom',
    args: ['0x', '0x', 123n],
    // @ts-expect-error
    value: 123n,
  })
  assertType<void>(res1.result)
  expectTypeOf(res1.request.abi).toEqualTypeOf(
    parseAbi(['function safeTransferFrom(address, address, uint256)']),
  )

  const res2 = await simulateContract(client, {
    address: '0x',
    abi,
    functionName: 'safeTransferFrom',
    args: ['0x', '0x', 123n, '0x'],
    value: 123n,
  })
  assertType<void>(res2.result)
  expectTypeOf(res2.request.abi).toEqualTypeOf(
    parseAbi([
      'function safeTransferFrom(address, address, uint256, bytes) payable',
    ]),
  )
})

In summary:

  • Remove GetValue related changes
  • Add logic directly to SimulateContractParameters
  • Add test to simulateContract.test-d.ts

@@ -303,10 +303,19 @@ export type EventDefinition = `${string}(${string})`

export type GetValue<
abi extends Abi | readonly unknown[],
functionName extends string,
mutability extends AbiStateMutability = AbiStateMutability,
Copy link
Member

Choose a reason for hiding this comment

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

Since GetValue is a public API (exported in index.ts), let's pull this logic directly into simulateContract.ts for now.

test/src/abis.ts Outdated
@@ -1363,6 +1363,16 @@ export const wagmiContractConfig = {
stateMutability: 'nonpayable',
type: 'function',
},
{
Copy link
Member

Choose a reason for hiding this comment

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

Let's remove this addition to the ABI.

Copy link
Member

Choose a reason for hiding this comment

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

Let's revert this change.

@Yuripetusko
Copy link
Contributor Author

Yuripetusko commented Aug 6, 2024

Let's revert the change to GetValue and update SimulateContractParameters directly with this logic. Also, let's add the following test. (Haven't found a quick way to get @ts-expect-error to work correctly in this case so might be best to remove that for now. There's a larger type refactor coming to Viem, which will fix this so allowing it to pass for the time being isn't the end of the world.)

test('https://github.com/wevm/viem/issues/2531', async () => {
  const abi = parseAbi([
    'function safeTransferFrom(address, address, uint256)',
    'function safeTransferFrom(address, address, uint256, bytes) payable',
  ])

  const res1 = await simulateContract(client, {
    address: '0x',
    abi,
    functionName: 'safeTransferFrom',
    args: ['0x', '0x', 123n],
    // @ts-expect-error
    value: 123n,
  })
  assertType<void>(res1.result)
  expectTypeOf(res1.request.abi).toEqualTypeOf(
    parseAbi(['function safeTransferFrom(address, address, uint256)']),
  )

  const res2 = await simulateContract(client, {
    address: '0x',
    abi,
    functionName: 'safeTransferFrom',
    args: ['0x', '0x', 123n, '0x'],
    value: 123n,
  })
  assertType<void>(res2.result)
  expectTypeOf(res2.request.abi).toEqualTypeOf(
    parseAbi([
      'function safeTransferFrom(address, address, uint256, bytes) payable',
    ]),
  )
})

In summary:

  • Remove GetValue related changes
  • Add logic directly to SimulateContractParameters
  • Add test to simulateContract.test-d.ts

Hm the reason ts-expect-error doesn't do anything here is that parseAi only picks one of the mutability options when merging an overload

image

EDIT: Actually it doesn't merge them even. Doesn't look like it handles overloads, and just returns the first match 🤔 will check a bit more

@tmm
Copy link
Member

tmm commented Aug 6, 2024

@Yuripetusko nice find. Can drop parseAbi and add the object directly instead.

@Yuripetusko
Copy link
Contributor Author

@Yuripetusko nice find. Can drop parseAbi and add the object directly instead.

Weirdly I can't reproduce this in here. So maybe it's my Jetbrains IDE messing with me again

https://stackblitz.com/edit/viem-getting-started-jixksa?file=package.json,index.ts

@Yuripetusko Yuripetusko marked this pull request as draft August 6, 2024 15:16
@Yuripetusko
Copy link
Contributor Author

@tmm added it to writeContract too, but lmk if I should just add it to simulateContract. Unfortunately I keep getting http errors when running all tests locally. But selected tests seems to be fine. Ignore the previous comments about parseAbi, it was due to something else entirely (missing args on new Generic, which is required to find the correct function in case of overloads)

@Yuripetusko Yuripetusko marked this pull request as ready for review August 6, 2024 15:19
@Yuripetusko Yuripetusko requested a review from tmm August 6, 2024 15:20
.changeset/new-hotels-sell.md Outdated Show resolved Hide resolved
@tmm tmm merged commit 1c5d64a into wevm:main Aug 6, 2024
19 of 32 checks passed
@github-actions github-actions bot mentioned this pull request Aug 6, 2024
@Yuripetusko Yuripetusko deleted the fix/2532-value-type-overload-types branch August 7, 2024 00:09
@tmm tmm mentioned this pull request Dec 21, 2024
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.

(simulate|write)Contract payable value not working for overloads
3 participants