-
Notifications
You must be signed in to change notification settings - Fork 355
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 more possibilities to call contract messages #4469
Comments
The API doesn't track or work on ink versions. So have no idea what versions you are referring to. What it does do is work on the version of the metadata, which is actually broader than ink itself, i.e. versioned metadata is also output by other compilers, for instance In both your examples, providing an ABI to see what the different outputs are is the best route. |
Of course. This is a {
"args": [],
"docs": [
" Returns the token name."
],
"mutates": false,
"name": [
"PSP22Metadata",
"token_name"
],
"payable": false,
"returnType": {
"displayName": [
"psp22metadata_external",
"TokenNameOutput"
],
"type": 19
},
"selector": "0x3d261bd4"
} This one is V3 metadata by ink v3.0.0-rc7: {
"args": [],
"docs": [
" Returns the total token supply."
],
"label": "BaseErc20::total_supply",
"mutates": false,
"payable": false,
"returnType": {
"displayName": [
"Balance"
],
"type": 0
},
"selector": "0x8244a1ad"
} So in the V1 metadata, the 'name' key denotes the method name, and it's an array of trait prefix + method name. In V3, it's located in the 'label' key, and follows Rust syntax of |
So I understand why in V1 the name came through with As for the V3 with the For the first - checks against the v1ToLatest function to ensure it ends up in the same form as the current V3 traits For the second - seeing what it actually does in practice and then being able to formulate some way around it. |
I can do that, just assign me to this issue |
Indeed, that is what #4471 addresses - it changes the up-conversion to combine the name -> labels in the same way as natively supplied in V2+, aka with This is where more actual real-world contracts are needed, none of the versions tested against has the same type of labelling, https://github.com/polkadot-js/api/tree/master/packages/api-contract/src/test/contracts |
Ok, got it. Should I provide example contracts & tests for conversions? |
That would be great, one V1 with the namespaces (https://github.com/polkadot-js/api/tree/master/packages/api-contract/src/test/contracts/ink/v1) and a V2/V3 (doesn't matter, they would both be equivalent with |
I'm on it 👌 |
Indeed, now that the discrepancies have been addressed, back to the original. The contracts Basically with the metadata available, things like UIs can then display additional extra information, i.e. original trait info. (It can be gotten to at this point, but it really does need to be consistent, and here it is not yet) So generally the API itself never decorates using Rust syntax, it decorates with JS syntax - which we everywhere try to get to via So on the options you laid out -
Something like |
I would say that the interfaces now make calling methods harder :) For example, from the first look and without some debugging, I would have no idea how to call methods, especially when the namespaces and method names are camelCased and concatenated. This approach is favorable cause we directly use the
Well, after the comma change in stringCamelCase somewhere in November-December 2021, all of the calls in the frontend have broken :) So changes like this will probably break some code for the users. But having syntax like this, we can really cut down on the internal information the frontend gets of the contracts. Consider this code: const myContract: Contract = await new ContractPromise(api, abi, address);
for (const prop in myContract) {
if (typeof(prop) === 'object') { // forgive me my js/ts knowledge :)
for (const method in prop) {
myContract[method] = myContract[prop][method];
}
delete myContract[prop];
}
} This would copy out all of the methods from all of the namespaces that we know of, while in theory leaving non-namespaced methods unchanged, hence providing less information to the front-end about the contract structure (e.g., when storing the contract in the window). To sum up, I would really want to have the second syntax (or some form of it) available. |
I can only verify what I can see - since I had no tests for namespaced methods (never actually seen them) and nobody complained, well, it is what it is :) I understand you would like Rust-like syntax, however we will not provide it - the API is following JS-like way of doing things, not transferring Rust-isms to JS. The same approach is followed through the whole API in all naming. The same applies to consistency, i.e. |
I don't agree that it's Rust-like syntax. Accessing a property of an object via Still, if you don't want to have Rust-like property names, the 3rd option is fine. But since some methods can be non-namespaced, they'd have to be accessed without Aaand if we decide to keep the things as they are - it's the worst solution, as namespace methods might start with |
The last example is 100% fine, it is exactly the same way the metadata v14 types names are generated. What we are trying to do is to ensure users never have to resort to |
Sorry, missed it, what example? :) |
|
Hi, I also want to participate in that discussion=)
I agree with Varg regarding the unreadable long name of the functions. We need to find a way how we can improve that.
Also, I agree with Jacogr, that we should resolve all questions to ensure users never have to resort
I think the idea with
Also, I think that it is better than So if method without interface: I think we don't need to camelcase the name of the interface and take it as it was in the The same idea we can use in UI, to improve readability. Near the method |
Needs to be verified/test cases added, but this does expand into namespaces under (It is actually really unfriendly atm without TS augmentation on a per-contract basis) As per the rest of the API, everything is ... having said all that, if something like |
Why it will be a nightmare? Because the user doesn't know is that method or an interface? For that case, we can introduce a assert(contract.query.balanceOf.type == `method`);
assert(contract.tx.balanceOf.type == `method`);
assert(contract.query.PSP22.balanceOf.type == `interface`);
assert(contract.tx.PSP22.balanceOf.type == `interface `);
Do you mean auto-generated code from the ABI, like classes and interfaces? I think we still can generate everything clearly for the developer: class Query {
PSP22: PSP22Interface;
balanceOf() {
...
}
}
interface PSP22Interface {
balanceOf() {
...
}
} BTW, what does "PITA" mean?=D |
PITA = Pain In The Ass. Sprinkling in asserts everywhere is exactly that - and inconsistent with the API. The above is not a negotiation- sadly I personally have to deal with breakages and the support around it. |
I didn't mean to add asserts=) I meant that if for the developer is important to know that the field is not a method and it is an interface, that information can be provided via the
Okay, maybe you can provide an example, I'm only want to understand what kind of problems that can cause. I checked the PR:
|
It is the second variant. The API always applies camelCase. As I stated before - the interface or method may become standard somewhere along the way, but at this point not breaking userspace for the 1% of cases where these are used. And certainly not bumping to a major version to introduce this breakage anytime soon. TL;DR on this one, not budging from meeting halfway, since the fallout is on my shoulders alone. When and if -
… then, can re-evaluate |
Okay, so when the usage of the namespaces/interfaces will be popular in ink!, we can elaborate on merging
Maybe is possible to keep the name of the namespace/interface as it is without camelCase? And it also changes the behavior of namespaces. For example
And what do you think about the idea with UI to show methods without namespace prefix and show the info about namespace in a separate place? |
This is not the place for UI, sadly the queue there is different - although I do both, I cannot track in both places - information overload. I believe I answered the rest at least twice now :) |
For that question I need "yes" or "no", to be sure that I understood you correctly =) Regarding namespace and camelCase, I only want to highlight, that the code of the contract is sensitive to registers of letters in the namespaces and it can cause an error during the parsing of that contract(when the developer has in the contract both |
The problem
The problem right now is that contract messages (txs & queries), which have a trait prefix, are only callable like
myTraitMyMethod
. Previously, thestringCamelCase
function allowed commas, so we could differentiate between message name and trait name when calling the functions. Like this:But now, as the
stringCamelCase
function replaces the commas with whitespace (and camelCases the trait), it means we have only one way to call a contract function:As the trait names may grow longer, we end up calling simple methods like this:
In some cases, we don't want the frontend calls to contain the trait names, and with this approach, it is almost impossible to remove the trait prefixes without doing hacks.
Proposed solution
The proposed solution is following:
::
, add the unchanged generated identifier to the query and tx objects. (Ends up like myContract.query['MyTrait::my_method'])In the end, we want to end up with several ways to call the same ABI message.
I would be pleased to work on this issue personally if you need my help :)
The text was updated successfully, but these errors were encountered: