diff --git a/docs/developers/developer-reference/code-metadata.md b/docs/developers/developer-reference/code-metadata.md index 27f30c824..f8212dbae 100644 --- a/docs/developers/developer-reference/code-metadata.md +++ b/docs/developers/developer-reference/code-metadata.md @@ -65,4 +65,4 @@ For example, if we wish to deploy a contract that is payable and upgradeable our We hope these flags will make it a lot easier to create and upgrade smart contracts. -If you want to take a look at some more examples of how Code Metadata is used, take a look here: https://github.com/multiversx/mx-sdk-rs/tree/master/contracts/examples +If you want to take a look at some more examples of how Code Metadata is used, take a look [here](https://github.com/multiversx/mx-sdk-rs/tree/master/contracts/examples). diff --git a/docs/developers/developer-reference/sc-build-reference.md b/docs/developers/developer-reference/sc-build-reference.md index 0844ea2df..8944b364b 100644 --- a/docs/developers/developer-reference/sc-build-reference.md +++ b/docs/developers/developer-reference/sc-build-reference.md @@ -204,7 +204,7 @@ fn world() -> ScenarioWorld { ### Calling `build` -A build can be triggered by calling either `mxpy contract build ` or `cargo run build` in the meta crate. In fact, mxpy calls the meta crate itself. +A build can be triggered by calling either `mxpy contract build --path ` or `cargo run build` in the meta crate. In fact, mxpy calls the meta crate itself. By default, this command will produce three files for each output contract: the ABI (`.abi.json`), the contract (`.wasm`) and a json file with all the used VM EI imported functions (`.imports.json`). For the multisig example above, the produced files are as follows: @@ -271,7 +271,7 @@ This command is similar to `build-dbg`, in that it provides a shorthand for buil ### Calling `clean` -Calling `mxpy contract clean ` or `cargo run clean` in the meta crate will delete the `output` folder and clean outputs of the Rust crates. +Calling `mxpy contract clean --path ` or `cargo run clean` in the meta crate will delete the `output` folder and clean outputs of the Rust crates. [comment]: # (mx-context-auto) diff --git a/docs/developers/tutorials/counter.md b/docs/developers/tutorials/counter.md index c58e2b7ae..e96efe76c 100644 --- a/docs/developers/tutorials/counter.md +++ b/docs/developers/tutorials/counter.md @@ -13,7 +13,7 @@ This is a mere example. We **do not offer support for writing contracts in C**. ## **Prerequisites** -You need to have [mxpy](/sdk-and-tools/sdk-py/installing-mxpy) installed. +You need to have `mxpy` installed. Follow the installation guide [here](/sdk-and-tools/sdk-py/installing-mxpy). [comment]: # (mx-context-auto) @@ -34,7 +34,7 @@ The file `counter.c` is the implementation of the Smart Contract, which defines In order to build the contract to WASM, run the following command: ``` -mxpy --verbose contract build mycounter +mxpy --verbose contract build --path mycounter ``` Above, `mycounter` refers to the folder that holds the source code. After executing the command, you can inspect the generated files in `mycounter/output`. diff --git a/docs/developers/tutorials/staking-contract.md b/docs/developers/tutorials/staking-contract.md index b40eb46c9..2c8083bb8 100644 --- a/docs/developers/tutorials/staking-contract.md +++ b/docs/developers/tutorials/staking-contract.md @@ -15,13 +15,13 @@ If you find anything not answered here, feel free to ask further questions on th ## Prerequisites -First and foremost, you need to have mxpy installed: https://docs.multiversx.com/sdk-and-tools/sdk-py/installing-mxpy/. If you already have mxpy installed, make sure to update it to the latest version, using the same instructions as for the installation. +First and foremost, you need to have `mxpy` installed. You can follow the installation guide [here](/sdk-and-tools/sdk-py/installing-mxpy/). If you already have `mxpy` installed, make sure to update it to the latest version, using the same instructions as for the installation. [comment]: # (mx-context-auto) ### mxpy -We're going to use mxpy for interacting with our contracts, so if you need more details about some of the steps we will perform, you can check here for more detailed explanations regarding what each command does: https://docs.multiversx.com/sdk-and-tools/sdk-py/smart-contract-interactions/ +We're going to use mxpy for interacting with our contracts, so if you need more details about some of the steps we will perform, you can check [here](/sdk-and-tools/sdk-py/smart-contract-interactions/) for more detailed explanations regarding what each command does. [comment]: # (mx-context-auto) @@ -161,7 +161,7 @@ pub trait StakingContract { `require!` is a macro that is a shortcut for `if !condition { signal_error(msg) }`. Signalling an error will terminate the execution and revert any changes made to the internal state, including token transfers from and to the SC. In this case, there is no reason to continue if the user did not pay anything. -We've also added #[view] annotation for the storage mappers, so we can later perform queries on those storage entries. You can read more about annotations here: https://docs.multiversx.com/developers/developer-reference/sc-annotations/ +We've also added `#[view]` annotation for the storage mappers, so we can later perform queries on those storage entries. You can read more about annotations [here](/developers/developer-reference/sc-annotations/). Also, if you're confused about some of the functions used or the storage mappers, you can read more here: @@ -170,7 +170,7 @@ Also, if you're confused about some of the functions used or the storage mappers Now, I've intentionally written some bad code here. Can you spot the improvements we can make? -Firstly, the last _clone_ is not needed. If you clone variables all the time, then you need to take some time to read the Rust ownership chapter of the Rust book: https://doc.rust-lang.org/book/ch04-00-understanding-ownership.html and also about the implications of cloning types from the Rust framework: https://docs.multiversx.com/developers/best-practices/biguint-operations/ +Firstly, the last _clone_ is not needed. If you clone variables all the time, then you need to take some time to read the Rust ownership chapter of the Rust book: https://doc.rust-lang.org/book/ch04-00-understanding-ownership.html and also about the implications of cloning types from the Rust framework: https://docs.multiversx.com/developers/best-practices/biguint-operations/. Secondly, the `staking_position` does not need an owned value of the `addr` argument. We can take a reference instead. @@ -224,7 +224,7 @@ Every smart contract needs to have a function annotated with `#[init]`. This fun You can skip this section if you already have a devnet wallet setup. ::: -Let's create a devnet wallet. Go to https://devnet-wallet.multiversx.com/, and select "create wallet". Save your 24 words (in the given order!), and create a password for your keystore file. +Let's create a devnet wallet. Access the [Web Wallet](https://devnet-wallet.multiversx.com/), and select "create new wallet". Save your 24 words (in the given order!), and create a password for your keystore file. Now, we could use the keystore file with a password, but it's more convenient to use a PEM file. To generate the PEM file from your secret phrase, follow these instructions: https://docs.multiversx.com/sdk-and-tools/sdk-py/deriving-the-wallet-pem-file/ @@ -260,7 +260,7 @@ If you wanted to use testnet, the proxy would be "https://testnet-gateway.multiv More details can be found [here](/developers/constants/). ::: -The things you need to edit are the CLI parameters --pem and --project with your local paths. +The things you need to edit are the CLI parameters `--pem` and `--bytecode` with your local paths. [comment]: # (mx-context-auto) @@ -438,7 +438,7 @@ getAllStakers ### Converting erd1 addresses to hex -The smart contracts never work with the erd1 address format, but rather with the hex format. This is NOT an ASCII to hex conversion. This is a bech32 to ASCII conversion. +The smart contracts never work with the `erd1...` address format, but rather with the hex format. This is NOT an ASCII to hex conversion. This is a bech32 to ASCII conversion. But then, why did the previous query work? @@ -875,9 +875,10 @@ Then, we've staked the user's entire balance, unstaked half, then unstaked fully ### Running the test To run a test, you can use click on the `Run Test` button from under the test name. + ![img](/developers/staking-contract-tutorial-img/running_rust_test.png) -There is also a `Debug` button, which can be used to debug smart contracts. More details on that here: https://docs.multiversx.com/developers/developer-reference/sc-debugging/ +There is also a `Debug` button, which can be used to debug smart contracts. More details on that [here](/developers/developer-reference/sc-debugging/). Alternatively, you can run all the tests in the file by running the following command in the VSCode terminal, in the `./staking-contract` folder: @@ -936,7 +937,7 @@ We've also added `TypeAbi`, since this is required for ABI generation. ABIs are Additionally, we've added `PartialEq` and `Debug` derives, for easier use within tests. This will not affect performance in any way, as the code for these is only used during testing/debugging. `PartialEq` allows us to use `==` for comparing instances, while `Debug` will pretty-print the struct, field by field, in case of errors. -If you want to learn more about how such a struct is encoded, and the difference between top and nested encoding/decoding, you can read more [here](/developers/developer-reference/serialization-format): +If you want to learn more about how such a struct is encoded, and the difference between top and nested encoding/decoding, you can read more [here](/developers/developer-reference/serialization-format). [comment]: # (mx-context-auto) diff --git a/docs/developers/tutorials/wallet-connect-v2-migration.md b/docs/developers/tutorials/wallet-connect-v2-migration.md index 1f81f2bb4..5e295c82c 100644 --- a/docs/developers/tutorials/wallet-connect-v2-migration.md +++ b/docs/developers/tutorials/wallet-connect-v2-migration.md @@ -23,7 +23,7 @@ Using `@multiversx/sdk-wallet-connect-provider` >= 3.0.1 or `@elrondnetwork/erdj Since the WalletConnect 2.0 implementation was complimentary to the existing 1.0 version, there should be no breaking changes to upgrade the library -Check out some detailed examples [here](/sdk-and-tools/sdk-js/sdk-js-signing-providers/#the-wallet-connect-provider) +Check out some detailed examples [here](/sdk-and-tools/sdk-js/sdk-js-signing-providers/#the-wallet-connect-provider). To Set up the 2.0 functionality you can check out the examples here: [https://github.com/multiversx/mx-sdk-js-examples](https://github.com/multiversx/mx-sdk-js-examples) or a more advanced implementation on sdk-dapp here: [https://github.com/multiversx/mx-sdk-dapp/blob/main/src/hooks/login/useWalletConnectV2Login.ts](https://github.com/multiversx/mx-sdk-dapp/blob/main/src/hooks/login/useWalletConnectV2Login.ts) diff --git a/docs/developers/tutorials/your-first-dapp.md b/docs/developers/tutorials/your-first-dapp.md index 62b4e63a6..1e86492e0 100644 --- a/docs/developers/tutorials/your-first-dapp.md +++ b/docs/developers/tutorials/your-first-dapp.md @@ -94,7 +94,7 @@ sudo apt install libncurses5 build-essential python3-pip nodejs npm python3.8-ve ``` We'll also need `mxpy`, the MultiversX command line tool, which is helpful for signing transactions, deploying smart contracts, managing wallets, accounts and validators. We'll use it to deploy our smart contract. -mxpy can be installed using the MultiversX documentation page [https://docs.multiversx.com/sdk-and-tools/sdk-py/installing-mxpy](https://docs.multiversx.com/sdk-and-tools/sdk-py/installing-mxpy) +mxpy can be installed using the MultiversX [documentation page](/sdk-and-tools/sdk-py/installing-mxpy). We'll download the `mxpy` installer and we run it diff --git a/docs/sdk-and-tools/rest-api/addresses.mdx b/docs/sdk-and-tools/rest-api/addresses.mdx index c39eef58d..67e6c0853 100644 --- a/docs/sdk-and-tools/rest-api/addresses.mdx +++ b/docs/sdk-and-tools/rest-api/addresses.mdx @@ -265,10 +265,14 @@ Balance successfully retrieved. [comment]: # (mx-context-auto) -## GET **Get Address Transactions** {#get-address-transactions} +## GET **Get Address Transactions (deprecated)** {#get-address-transactions} `https://gateway.multiversx.com/address/:bech32Address/transactions` +:::caution +This endpoint is deprecated. In order to fetch the Transactions involving an Address, use the [transactions](https://api.multiversx.com/#/accounts/AccountController_getAccountTransactions) endpoint of MultiversX API, instead. +::: + This endpoint allows one to retrieve the latest 20 Transactions sent from an Address. + [comment]: # (mx-context-auto) @@ -223,7 +223,7 @@ For a different awaiting strategy, also see [extending sdk-js](https://docs.mult - + [comment]: # (mx-context-auto) @@ -305,7 +305,7 @@ const tx4 = factory.createMultiESDTNFTTransfer({ - + [comment]: # (mx-context-auto) @@ -415,8 +415,7 @@ console.log("Return code:", returnCode); - - + [comment]: # (mx-context-auto) ## ABI @@ -450,7 +449,7 @@ existingContract = new SmartContract({ address: existingContractAddress, abi: ab - + [comment]: # (mx-context-auto) @@ -566,7 +565,7 @@ let firstValueAsStruct = firstValue; - + [comment]: # (mx-context-auto) @@ -623,7 +622,7 @@ Then, sign, broadcast `tx` and wait for its completion. ``` import { AbiRegistry } from "@multiversx/sdk-core"; -const abiRegistry = AbiRegistry.create({ +let abiRegistry = AbiRegistry.create({ "endpoints": [ { "name": "foobar", @@ -657,6 +656,47 @@ let tx3 = contract.methods.doSomethingWithValue([1, 2, 3]) .buildTransaction(); ``` +Now let's see an example using variadic arguments, as well: + +``` +import { StringValue, VariadicValue } from "@multiversx/sdk-core"; + +abiRegistry = AbiRegistry.create({ + "endpoints": [ + { + "name": "foobar", + "inputs": [], + "outputs": [] + }, + { + "name": "doSomething", + "inputs": [{ + "type": "counted-variadic" + }, + { + "type": "variadic" + }], + "outputs": [] + } + ] +}); + +contract = new SmartContract({ address: contractAddress, abi: abiRegistry }); + +let tx4 = contract.methods.doSomething( + [ + // Counted variadic must be explicitly typed + VariadicValue.fromItemsCounted(StringValue.fromUTF8("foo"), StringValue.fromUTF8("bar")), + // Regular variadic can be implicitly typed + 1, 2, 3 + ]) + .withSender(addressOfAlice) + .withNonce(45) + .withGasLimit(20000000) + .withChainID("D") + .buildTransaction(); +``` + [comment]: # (mx-context-auto) ### Transfer & execute @@ -748,7 +788,7 @@ For customizing the default parser, also see [extending sdk-js](/sdk-and-tools/s - + [comment]: # (mx-context-auto) diff --git a/docs/sdk-and-tools/sdk-py/mxpy-cli.md b/docs/sdk-and-tools/sdk-py/mxpy-cli.md index 318aa3c28..a11474ce0 100644 --- a/docs/sdk-and-tools/sdk-py/mxpy-cli.md +++ b/docs/sdk-and-tools/sdk-py/mxpy-cli.md @@ -83,15 +83,74 @@ mxpy deps install rust --tag nightly-2023-04-24 --overwrite [comment]: # (mx-context-auto) +## Creating wallets + +There are a couple available wallet formats: +- `raw-mnemonic` - secret phrase in plain text +- `keystore-mnemonic` - secret phrase, as a password-encrypted JSON keystore file +- `keystore-secret-key` - secret key (irreversibly derived from the secret phrase), as a password-encrypted JSON keystore file +- `pem` - secret key (irreversibly derived from the secret phrase), as a PEM file + +For this example, we are going to create a `keystore-mnemonic` wallet. + +Let's create a keystore wallet: +```sh +mxpy wallet new --format keystore-mnemonic --outfile test_wallet.json +``` +The wallet's mnemonic will appear, followed by a prompt to set a password for the file. Once you input the password and press "Enter", the file will be generated at the location specified by the `--outfile` argument. + +[comment]: # (mx-context-auto) + +## Converting a wallet + +As you have read above, there are multiple ways in which you can store your secret keys. + +To convert a wallet from a type to another you can use: +```sh +mxpy wallet convert +``` + +:::info +Keep in mind that the conversion isn't always possible (due to irreversible derivations of the secret phrase): + - `raw-mnemonic` can be converted to any other format + - `keystore-mnemonic` can be converted to any other format + - `keystore-secret-key` can only be converted to `pem` + - `pem` can only be converted to `keystore-secret-key` + +It's mandatory that you keep a backup of your secret phrase somewhere safe. +::: + +Let's convert the previously created `keystore-mnemonic` to a `PEM` wallet. We discourage the use of PEM wallets for storing cryptocurrencies due to their lower security level. However, they prove to be highly convenient and user-friendly for application testing purposes. + +To convert the wallet we type the follwing command: +```sh +mxpy wallet convert --infile test_wallet.json --in-format keystore-mnemonic --outfile converted_wallet.pem --out-format pem +``` + +After being prompted to enter the password you've previously set for the wallet the new `.pem` file will be created. + +The command arguments can be found [here](https://github.com/multiversx/mx-sdk-py-cli/blob/main/CLI.md#walletconvert) or by typing: +```sh +mxpy wallet convert --help +``` + +[comment]: # (mx-context-auto) + ## Building a smart contract In order to deploy a smart contract on the network, you need to build it first. +The contract we will be using for this examples can be found [here](https://github.com/multiversx/mx-contracts-rs/tree/main/contracts/adder). + The `mxpy` command used for building contracts is: ```sh -mxpy contract build +mxpy contract build --path ``` +If our working directory is already the contract's directory we can skip the `--path` argument as by default the contract's directory is the _current working directory_. + +The generated `.wasm` file will be created in a directory called `output` inside the contract's directory. + The command accepts a few parameters that you can check out [here](https://github.com/multiversx/mx-sdk-py-cli/blob/main/CLI.md#contractbuild) or by simply typing: ```sh mxpy contract build --help @@ -121,16 +180,106 @@ The `mxpy contract deploy` command needs a multitude of other parameters that ca mxpy contract deploy --help ``` +We will use a `.pem` file for the sake of simplicity but you can easily use any wallet type. + Let's see a simple example: ```sh mxpy contract deploy --bytecode ~/contracts/adder/output/adder.wasm \ --proxy=https://devnet-gateway.multiversx.com --recall-nonce \ - --arguments 42 --gas-limit 5000000 \ + --arguments 0 --gas-limit 5000000 \ + --pem=~/multiversx-sdk/testwallets/latest/users/alice.pem \ + --send +``` + +The `--proxy` is used to specify the url of the proxy and the `--chain` is used to select the network the contract will be deployed to. The chain ID and the proxy need to match for our transaction to be executed. We can't prepare a transaction for the Devnet (using `--chain D`) and send it using the mainnet proxy (https://gateway.multiversx.com). + +The `--recall-nonce` is used to get the nonce of the address so we don't search it manually. It simply makes an API request to get the nonce of the account. The `--arguments` is used in case our contract needs any arguments for the initialization. We know our `adder` needs a value to start adding from, so we set that to `0`. + +The `--gas-limit` is used to set the gas we are willing to pay so our transaction will be executed. 5 million gas is a bit too much because our contract is very small and simple, but better to be sure. In case our transaction doesn't have enough gas the network will not execute it, saying something like `Insufficent gas limit`. + +The `--pem` argument is used to provide the sender of the transaction, the payer of the fee. The sender will also be the owner of the contract. + +[comment]: # (mx-context-auto) + +## Calling the Smart Contract + +After deploying our smart contract we can start interacting with it. The contract has a function called `add()` that we can call and it will increase the value stored in the contract with the value we provide. + +To call a function we use the `mxpy contract call` command. Here's an example of how we can do that: +```sh +mxpy contract call erd1qqqqqqqqqqqqqpgq3zrpqj3sulnc9xq95sljetxhf9s07pqtd8ssfkxjv4 \ + --pem=~/multiversx-sdk/testwallets/latest/users/alice.pem --recall-nonce \ + --proxy=https://devnet-gateway.multiversx.com --chain D \ + --function add --arguments 5 --gas-limit 1000000 \ + --send +``` + +The positional argument is the contract address that we want to interact with. The `--pem`, `--recall-nonce`, `--proxy` and `--chain` arguments are used the same as above in the deploy transaction. + +Using the `--function` argument we specify the function we want to call and with the `--arguments` argument we specify the value we want to add. We set the gas we are willing to pay for the transaction and finally we send the transaction. + +[comment]: # (mx-context-auto) + +## Querying a Smart Contract + +Querying a contract is done by calling a so called `view function`. We can get data from a contract without sending a transaction to the contract, basically without spending money. + +As you know, our contract has a function called `add()` that we previously called, and a `view function` called `getSum()`. Using this `getSum()` function we can see the value that is currently stored in the contract. + +If you remember, when we deployed the contract we passed the value `0` as a contract argument, this means the contract started adding from `0`. When calling the `add()` function we used the value `5`. This means that now if we call `getSum()` we should get the value `5`. To do that, we use the `mxpy contract query` command. Let's try it! + +```sh +mxpy contract query erd1qqqqqqqqqqqqqpgq3zrpqj3sulnc9xq95sljetxhf9s07pqtd8ssfkxjv4 \ + --proxy https://devnet-gateway.multiversx.com \ + --function getSum +``` + +We see that `mxpy` returns our value as a base64 string, as a hex number and as a integer. Indee, we see the expected value. + +[comment]: # (mx-context-auto) + +## Upgrading a Smart Contract + +In case there's a new release of your Smart Contract, or perhaps you've patched a possible vulnerability you can upgrade the code of the Smart Contract deployed on the network. + +We've modified our adder contract to add `1` to every value added to the contract. Now everytime the `add()` function is called will add the value provided with `1`. In order to do that we access the source code and navigate to the `add()` endpoint. We can see that `value` is added to `sum` each time the endpoint is called. Modify the line to look something like this `self.sum().update(|sum| *sum += value + 1u32);` + +Before deploying the contract we need to build it again to make sure we are using the latest version. We then deploy the newly built contract, then we call it and query it. + +First we build the contract: +```sh +mxpy contract build +``` + +Then we upgrade the contract by running: +```sh +mxpy contract upgrade erd1qqqqqqqqqqqqqpgq3zrpqj3sulnc9xq95sljetxhf9s07pqtd8ssfkxjv4 \ + --bytecode ~/contracts/adder/output/adder.wasm \ + --proxy=https://devnet-gateway.multiversx.com --chain D \ + --recall-nonce --arguments 0 --gas-limit 5000000 \ --pem=~/multiversx-sdk/testwallets/latest/users/alice.pem \ --send ``` +We provide as a positional argument the contract's address that we want to upgrade, in our case the previously deployed adder contract. The `--bytecode` is used to provide the new code that will replace the old code. We also set the `--arguments` to `0` as we didn't change the constructor and the contract will start counting from `0` again. The rest of the arguments you know from all the previous operations we've done. + +Now let's add `5` to the contract one more time. We do so by running the following: +```sh +mxpy contract call erd1qqqqqqqqqqqqqpgq3zrpqj3sulnc9xq95sljetxhf9s07pqtd8ssfkxjv4 \ + --pem=~/multiversx-sdk/testwallets/latest/users/alice.pem --recall-nonce \ + --proxy=https://devnet-gateway.multiversx.com --chain D \ + --function add --arguments 5 --gas-limit 1000000 \ + --send +``` + +Now, if we query the contract we should see the value `6`. We added `5` in the contract but modified the contract code to add `1` to every value. Let's see! +```sh +mxpy contract query erd1qqqqqqqqqqqqqpgq3zrpqj3sulnc9xq95sljetxhf9s07pqtd8ssfkxjv4 --proxy https://devnet-gateway.multiversx.com --function getSum +``` + +We see that we indeed got the value `6`. Our upgrade was sucessfull. + [comment]: # (mx-context-auto) ## Verifying a smart contract @@ -166,46 +315,17 @@ The _packaged source_ passed as `--packaged-src` can be obtained either from [th [comment]: # (mx-context-auto) -## Converting a wallet - -As you may know, there are multiple ways in which you can store your secret keys. +## Creating and sending transactions -To convert a wallet from a type to another you can use: +To create a new transaction we use the `mxpy tx new` command. Let's see how that works: ```sh -mxpy wallet convert -``` - -The available formats are: - - `raw-mnemonic` - secret phrase in plain text - - `keystore-mnemonic` - secret phrase, as a password-encrypted JSON keystore file - - `keystore-secret-key` - secret key (irreversibly derived from the secret phrase), as a password-encrypted JSON keystore file - - `pem` - secret key (irreversibly derived from the secret phrase), as a PEM file - -:::info -Keep in mind that the conversion isn't always possible (due to irreversible derivations of the secret phrase): - - `raw-mnemonic` can be converted to any other format - - `keystore-mnemonic` can be converted to any other format - - `keystore-secret-key` can only be converted to `pem` - - `pem` can only be converted to `keystore-secret-key` - -It's mandatory that you keep a backup of your secret phrase somewhere safe. -::: - -For example, let's say you want to convert from _mnemonic_ to a _PEM_ file. We can do that by typing the following: -```sh -mxpy wallet convert --in-format raw-mnemonic --out-format pem --outfile key.pem -``` - -You will then be asked to enter the mnemonic. After typing the mnemonic press `Ctrl + D` for Linux/MacOS or `Ctrl + Z` for Windows. - -We can also convert your mnemonic to a keystore file. That can be done by typing: -```sh -mxpy wallet convert --in-format raw-mnemonic --out-format keystore-mnemonic --outfile keystore.json +mxpy tx new --pem ~/multiversx-sdk/testwallets/latest/users/alice.pem --recall-nonce \ + --receiver erd1spyavw0956vq68xj8y4tenjpq2wd5a9p2c6j8gsz7ztyrnpxrruqzu66jx \ + --gas-limit 50000 --value 1000000000000000000 \ + --proxy https://devnet-gateway.multiversx.com --chain D \ + --send ``` -After inserting the mnemonic you will be asked to provide a password for the file. Insert the password then press enter. A file named `keystore.json` has been created. +That's it! As easy as that. We sent a transaction from Alice to Bob. We choose the receiver of our transaction using the `--receiver` argument and set the gas limit to `50000` because that is the gas cost of a simple move balance transaction. Notice we used the `--value` argument to pass the value that we want to transfer but we passed in the denomintated value. We transferred 1 eGLD (1 * 10^18). We then specify the proxy and the chain ID for the network we want to send our transaction to and use the `--send` argument to broadcast it. -The command arguments can be found [here](https://github.com/multiversx/mx-sdk-py-cli/blob/main/CLI.md#walletconvert) or by typing: -```sh -mxpy wallet convert --help -``` +In case you want to save the transaction you can also provide the `--outfile` argument and a `json` file containing the transaction will be saved at the specified location. If you just want to prepare the transaction without broadcasting it simply remove the `--send` argument.