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

Migration support: "v12" to "v13" (April 2024) #392

Open
andreibancioiu opened this issue Feb 28, 2024 · 14 comments
Open

Migration support: "v12" to "v13" (April 2024) #392

andreibancioiu opened this issue Feb 28, 2024 · 14 comments
Assignees
Labels
migration Migration support

Comments

@andreibancioiu
Copy link
Contributor

andreibancioiu commented Feb 28, 2024

Here, we describe the main steps for migrating from sdk-core v12 to sdk-core v13.

💡 For any questions about the migration, feel free to leave a comment 🙏 💡

When transitioning from v12 to v13, you should encounter little to no breaking changes.

However, we've introduced new approaches of creating transactions (transfers, smart contract transactions, token management operations, delegation operations), performing contract queries, and parsing transaction outcome. These new approaches are (mostly) in line with our newest SDK specs, and we recommend you to use them whenever possible.

Legacy methods are still available - though, at some point into the future, they will be marked as deprecated.

References:

@andreibancioiu andreibancioiu added the migration Migration support label Feb 28, 2024
@andreibancioiu
Copy link
Contributor Author

andreibancioiu commented Feb 28, 2024

1 / Non-breaking change: new TransactionFactories vs. legacy factories and builders

In v13, we have new ways of constructing transactions. The existing (legacy) approaches (v12) are still available.

Transfer (EGLD, ESDT) transactions

  • Instead of new TransferTransactionsFactory(gasEstimator), use new TransferTransactionsFactory({ config: new TransactionsFactoryConfig(...), tokenComputer: new TokenComputer() }).
  • Instead of TransferTransactionsFactory.createEGLDTransfer(), use TransferTransactionsFactory.createTransactionForNativeTokenTransfer().
  • Instead of TransferTransactionsFactory.createESDTTransfer(), use TransferTransactionsFactory.createTransactionForESDTTokenTransfer.
  • Instead of TransferTransactionsFactory.createESDTNFTTransfer, use TransferTransactionsFactory.createTransactionForESDTTokenTransfer.
  • Instead of TransferTransactionsFactory.createMultiESDTNFTTransfer, use TransferTransactionsFactory.createTransactionForESDTTokenTransfer.

Smart Contract transactions

  • Instead of SmartContract.deploy(), use SmartContractTransactionsFactory.createTransactionForDeploy().
  • Instead of SmartContract.upgrade(), use SmartContractTransactionsFactory.createTransactionForUpgrade().
  • Instead of SmartContract.call(), use SmartContractTransactionsFactory.createTransactionForExecute().

Relayed transactions

  • Instead of RelayedTransactionV1Builder, use RelayedTransactionsFactory.createRelayedV1Transaction()
  • Instead of RelayedTransactionV2Builder, use RelayedTransactionsFactory.createRelayedV2Transaction()

Token management transactions

  • Instead of TokenOperationsFactory (legacy, somehow unknown), use the new TokenManagementTransactionsFactory.

References

@andreibancioiu
Copy link
Contributor Author

andreibancioiu commented Feb 28, 2024

2 / Non-breaking change: new way of performing contract queries

The existing (legacy) approaches are still working.

Before:

query = contract.createQuery({
    func: "getUltimateAnswer"
});

rawResponse = await networkProvider.queryContract(query);

Or using the interaction API:

query = contract.methods.getUltimateAnswer().buildQuery();
rawResponse = await networkProvider.queryContract(query);

Now:

adapter = new QueryRunnerAdapter({ networkProvider });
controller = new SmartContractQueriesController({ abi, queryRunner: adapter });
nicelyParsedResponse = await controller.runQuery({ function: "getUltimateAnswer" });

References

@andreibancioiu
Copy link
Contributor Author

andreibancioiu commented Feb 28, 2024

3 / Non-breaking change: new way of parsing outcome of transactions

The existing (legacy) approaches are still available.

Smart Contract transactions

  • Instead of ResultsParser.parseOutcome(), use SmartContractTransactionsOutcomeParser.parseExecute().
  • Instead of ResultsParser.parseUntypedOutcome(), use SmartContractTransactionsOutcomeParser.parseExecute().
  • Instead of ResultsParser.parseEvent(), use TransactionEventsParser.parseEvent().

Token management transactions

  • Instead of TokenOperationsOutcomeParser.*, use TokenManagementTransactionsOutcomeParser.*.

References

For the rest of outcome parsers & more details, check out:

@andreibancioiu
Copy link
Contributor Author

andreibancioiu commented Feb 28, 2024

4 / Non-breaking change: constructor and properties of Transaction

Since v13, the Transaction class exhibits its state as public read-write properties. For example, you can access and set the nonce property, instead of using getNonce and setNonce.

Additionally, the constructor has been adjusted in a non-breaking manner to accept initialization parameters as improved, simplified types.

E.g. transaction data can now be passed both as a simple, standard Uint8Array (new approach) and as a legacy TransactionPayload object. Value can now be passed both as a simple, standard bigint (new approach) and as a BigNumber (legacy). For the rest, see the cookbook and the auto-generated API docs.

Cookbook

@andreibancioiu
Copy link
Contributor Author

andreibancioiu commented Feb 28, 2024

5 / Small breaking change on Transaction: adjusted type for version and options

In v12, these fields were marked as deprecated:

class Transaction {
    // @deprecated
    version: TransactionVersion;
    // @deprecated
    options: TransactionOptions;

Now, in v13, we've un-deprecated them, but we've also altered their types:

class Transaction {
    ...
    version: number;
    options: number;
    ...
}

References

@andreibancioiu
Copy link
Contributor Author

andreibancioiu commented Mar 24, 2024

6 / Non-breaking (in practice) change: default transaction version is now 2, instead of 1

That is, when you create a Transaction object and do not specify an explicit version for the transaction, the new default is 2. Previously, it was 1.

Generally speaking, this should not be a breaking change within client code.

Overriding the transaction version is possible.

References

@andreibancioiu
Copy link
Contributor Author

andreibancioiu commented Mar 25, 2024

7 / Non-breaking change: pass a transaction hash to TransactionWatcher.await*

This is a non-breaking change. The old way of using TransactionWatcher is still available. However, we recommend the new approach.

Before:

async awaitCompleted(transaction: ITransaction): Promise<ITransactionOnNetwork> {...}
async awaitAnyEvent(transaction: ITransaction): Promise<ITransactionOnNetwork> {...}
...

Now:

async awaitCompleted(txHash: string): Promise<ITransactionOnNetwork> {...}
async awaitAnyEvent(txHash: string): Promise<ITransactionOnNetwork> {...}
...

References

@andreibancioiu
Copy link
Contributor Author

andreibancioiu commented Mar 25, 2024

8 / Non-breaking change: BigInt vs. BigNumber

We now favor the use of bigint primitive, instead of number or BigNumber of bignumber.js (library) - where applicable: for nonces, gas limit, gas price, amounts etc.

Classes / functions continue to accept BigNumber of bignumber.js library, just as before v13.

References

@andreibancioiu
Copy link
Contributor Author

andreibancioiu commented Mar 25, 2024

9 / Non-breaking change: serializing objects for signing

The legacy method serializeForSigning() is still available on Transaction and Message. However, we recommend using the new TransactionComputer and MessageComputer to convert these objects to raw bytes - in order to sign them:

const transactionComputer = new TransactionComputer();
const transactionBytes = transactionComputer.computeBytesForSigning(transaction);

const messageComputer = new MessageComputer();
const messageBytes = messageComputer.computeBytesForSigning(message);

Furthermore, the class SignableMessage is not deprecated - use Message, instead. Additionally, if your application is concerned with passing signed message over the Internet (e.g. towards a service, an API) and verifying them, you might be interested into: packing and unpacking a message.

References

@multiversx multiversx deleted a comment from andreibancioiu Mar 27, 2024
@andreibancioiu andreibancioiu changed the title Migration support: "v12" to "v13" (March 2024) Migration support: "v12" to "v13" (April 2024) Apr 1, 2024
@andreibancioiu
Copy link
Contributor Author

andreibancioiu commented Apr 1, 2024

10 / Formatting and parsing amounts

For formatting or parsing token amounts as numbers (with fixed number of decimals), do not rely on sdk-core. Instead, use sdk-dapp (higher level) or bignumber.js (lower level).

References

@andreibancioiu
Copy link
Contributor Author

andreibancioiu commented Apr 1, 2024

11 / Breaking change (trivial): Interaction.withSingleESDTNFTTransfer() and Interaction.withMultiESDTNFTTransfer() - dropped sender parameter

We've removed the (long deprecated) sender parameter from the methods: Interaction.withSingleESDTNFTTransfer() and Interaction.withMultiESDTNFTTransfer().

When using the (now legacy) interaction facility to build smart contract calls, make sure to use withSender() instead.

However, now, since v13, the recommended way to build smart contract calls is by means of the new transactions factories. See SmartContractTransactionsFactory.

Cookbook

@andreibancioiu
Copy link
Contributor Author

andreibancioiu commented Apr 1, 2024

12 / Small (trivial) breaking change: Address constructor cannot be called without parameters anymore

The Address constructor cannot be called without parameters anymore. Replacement: Address.empty().

However, generally speaking, new Address(/no params/) should have never been used within client code. Just the same, Address.empty() should not be used by client code, generally speaking (internal use only).

References

@andreibancioiu
Copy link
Contributor Author

andreibancioiu commented Apr 1, 2024

13 / Breaking (fixing) change: TokenOperationsFactory - removed canMint, canBurn

On TokenOperationsFactory (legacy, somehow unknown component), some unused and already deprecated input parameters (flags) have been removed: canMint, canBurn.

However, now, since v13, the recommended way to build smart contract calls is by means of the new transactions factories. Note: TokenOperationsFactory is not part of the new set of factories - it's an old one. The corresponding new one is called TokenManagementTransactionsFactory.

Cookbook

  • pending

Additional references

@multiversx multiversx deleted a comment from BrodysgotMs Apr 17, 2024
@andreibancioiu
Copy link
Contributor Author

andreibancioiu commented Apr 17, 2024

14 / Breaking change when passing variadic values to SmartContract.call()

Please follow this:

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

No branches or pull requests

2 participants