multiversx / mx-sdk-js-core

MultiversX SDK for interacting with the MultiversX blockchain (in general) and Smart Contracts (in particular).
https://multiversx.github.io/mx-sdk-js-core/
Other
58 stars 37 forks source link

Problem with smart contracts ESDTTransfer in sdk-core 13.0.0-beta.9 and newer #455

Closed Ebuliga closed 1 month ago

Ebuliga commented 1 month ago

There is a problem with Interaction.buildTransaction in sdk-core/out/smartcontracts/interaction with how the function name is set and then validated against the ABI smart contract. In buildTransaction() function there is this call which is executed for an ESFTTransfer: let func = this.function; let args = this.args; if (this.isWithSingleESDTTransfer) { func = new function_1.ContractFunction(constants_1.ESDT_TRANSFER_FUNCTION_NAME); args = this.tokenTransfers.buildArgsForSingleESDTTransfer();

Function name will change for example from unDelegate to ESDTTransfer. image You can see in the attached image that the function name is changed from unDelegate to ESDTTransfer. This seems correct according to the protocol and how ESDTTransfer are processed. Then this function is called: let transaction = this.contract.call({ func ... which calls: const transaction = factory.createTransactionForExecute({

In createTransactionForExecute() there is this code that checks the number of tokens and sets the dataParts. The first potential problem I see is that this numberOfTokens is zero and then no arguments builder function is called for ESDTTransfer or ESDTNFTTransfer. I don't have in depth knowledge so maybe this is ok for this scenario.

image

The problem and the root cause of the failure is that it is searching for the "ESDTTransfer" function in the smartcontract as defined in ABI.
In our case there is no function "ESDTTransfer" defined in the ABI so this will fail to find the endpoint and it will return an error: dataParts = dataParts.concat(this.argsToDataParts(args, (_a = this.abi) == null ? void 0 : _a.getEndpoint(options.functionName))); image

Here we will get an error: endpoint ESDTTransfer not found

Example of how this functionality is called: let interaction = contract.methods.unDelegate([]); interaction.withSender(new Address(address)); interaction.withSingleESDTTransfer(TokenTransfer.fungibleFromAmount(legldID, values.amount, 18)); interaction.withGasLimit(gasLimits.unDelegate); interaction.withChainID(chainId); interaction.buildTransaction(); let query = interaction.check().buildQuery();

I did verified this with "@multiversx/sdk-core": "12.11.0", and the same code is working just fine. The transaction is built, sent and processed correctly, so this looks like a regression.

Ebuliga commented 1 month ago

Question: is there a nicer way to debug libraries like sdk-core by having the .ts files instead of plain .js?

andreibancioiu commented 1 month ago

Hello @Ebuliga,

Most probably, the issue has been solved in v13.0.0-beta.13 (29th of March 2024):

https://github.com/multiversx/mx-sdk-js-core/pull/420 - Hotfix (regression): interaction (legacy API) with ABI, with transfers (transfer & execute)

Do you think you can switch to the stable channel instead?

Additional references:

Thank you!

Let us know how it goes :pray:

Ebuliga commented 1 month ago

We will try to switch and I will let you know the outcome.

Ebuliga commented 1 month ago

With the same code as above but using the latest version 13.2.0 we get the following error: Error: Request error on url [query]: [Insufficient undelegated amount]

That happens because the transfer value when building the query is not taken from the tokenTransfers but from the value parameter (which is 0 for ESDTTransfer).

image

Because of this the final request is created with value set to zero which triggers the error above.

image

For now we will revert to sdk-core 12 and we will change again to 13 later when we will migrate to the new recommended way of using TransferTransactionsFactory class.

Ebuliga commented 1 month ago

Changing also "@multiversx/sdk-dapp" to a newer stable version fixed this issue also. So with this config it works: "@multiversx/sdk-core": "13.2.0", "@multiversx/sdk-dapp": "2.32.0",

But occasionally now I get this pop-up error message after a successful transaction: Wallet window is not instantiated. Screenshot from 2024-06-01 17-25-01 Nevertheless the transaction is successful.

andreibancioiu commented 1 month ago

Hello @Ebuliga,

That happens because the transfer value when building the query is not taken from the tokenTransfers but from the value parameter (which is 0 for ESDTTransfer).

Your analysis is correct. When using the legacy Interaction API for queries, you should pass a desired native amount (if any) to withValue(). However, generally speaking, this happens both in v12 and v13.

Glad to hear it works now. Regarding the error pop-up - we will forward this matter.

Thanks again :raised_hands:

Ebuliga commented 1 month ago

Issue solved.