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

Add struct parsing to @typechain/web3-v1 (#779) #801

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

krzkaczor
Copy link
Member

No description provided.

@changeset-bot
Copy link

changeset-bot bot commented Jan 23, 2023

🦋 Changeset detected

Latest commit: a2e307c

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

This PR includes changesets to release 1 package
Name Type
@typechain/web3-v1 Minor

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

@krzkaczor
Copy link
Member Author

@mihai9-lab there are still some problems with tests. Can u take a look?

Copy link

@sigmachirality sigmachirality left a comment

Choose a reason for hiding this comment

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

Excited to see this being worked on! Commenting a few nits/flagging a bug we ran into trying to use @mihai9-lab's target

Comment on lines +87 to +89
} else {
return `${item}[]`
}

Choose a reason for hiding this comment

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

Hi @mihai9-lab, we ran across a bug on this line specifically. In the case where item is a string declaring a union type (for example: string | number | BN), just appending [] to this type results in string | number | BN[] instead of the intended type (string | number | BN)[] or perhaps string [] | number[] | BN[] (I prefer the first solution, as it allows mixing of types in input arrays).

I was able to fix this with the following code:

if (item.contains("|")) {
  item = `(${item})`
}

However, it may be cleaner to parametrize this function with another boolean and determine whether item is a union upstream of this function, and/or accept length and this proposed boolean as properties of an options object.

Choose a reason for hiding this comment

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

Seems like the original code here just wrapped all types in parenthesis regardless of whether the type was simple or a union type. I leave the exact form of the solution up to you!

Comment on lines -48 to +60
data: [string, string];
0: [string, string];
data: Events.EventDataStructOutput;
0: Events.EventDataStructOutput;

Choose a reason for hiding this comment

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

nit: I prefer keeping these types flat for ease of use during development (would prefer to see that the type is a [string, string] instead of a Events.EventDataStructOutput when hovering over it, for example)

Comment on lines +76 to +77
${outputs.map((t) => t.name && `${t.name}: ${codegenOutputType({ useStructs: true }, t.type)}, `).join('')}
${outputs.map((t, i) => `${i}: ${codegenOutputType({ useStructs: true }, t.type)}`).join(', ')}

Choose a reason for hiding this comment

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

any chance we can reverse this function's type params to codegenOutputType(type, options) instead of codegenOutputType(options, type)? The first is more likely to not break code, since it doesn't change the position of the type param.

Choose a reason for hiding this comment

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

Seems like most codegen functions that take in an options param also take it as the last parameter

useStructs?: boolean // uses struct type for first depth, if false then generates first depth tuple types
}

export function codegenInputTypes(options: GenerateTypeOptions, input: Array<AbiParameter>): string {

Choose a reason for hiding this comment

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

Same feedback for codegenInputTypes (prefer codegenInputTypes(input, options?))

@sigmachirality
Copy link

@mihai9-lab when do you think you'll have bandwidth to work on this change? Want to get this through pretty urgently, can I work on this now if you don't have time soon?

@mihai9-lab
Copy link

@mihai9-lab when do you think you'll have bandwidth to work on this change? Want to get this through pretty urgently, can I work on this now if you don't have time soon?

Hey, sorry for not replying sooner. Currently I'm pretty busy and won't be able to work on this for at least a week or two.
I have no issues with you working on this, so feel free to do so

@sigmachirality
Copy link

The approach of this PR might be a bit flawed: as seen here: https://web3js.readthedocs.io/en/v1.8.1/web3-eth-contract.html#methods-mymethod-call

"Promise returns Mixed: The return value(s) of the smart contract method. If it returns a single value, it’s returned as is. If it has multiple return values they are returned as an object with properties and indices"

Since the return is "an object with properties and indices", we cannot return the type of a struct as a union of an array and an object, as this will annotate the object with all the members of an array (for example, .concat), which do not actually exist on the object.

@mihai9-lab
Copy link

Yeah i didn't expect it to behave like that, it seems that typescript does assume object has all properties of an array(although it isn't one).

I see 2 possible approaches to deal with this - one being to change array generation to object generation, other being to leave it as is but add an additional "converter" type which would exclude unwanted array properties.

I made a quick array to objected converter type as a proof of concept if going with second option, here's a playground for that. Maybe this is a bit hacky, so i'd like to see what you and the community thinks is the best approach.

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.

None yet

3 participants