diff --git a/bindings/nodejs/examples/.env.example b/bindings/nodejs/examples/.env.example deleted file mode 100644 index c29af6273a..0000000000 --- a/bindings/nodejs/examples/.env.example +++ /dev/null @@ -1,14 +0,0 @@ -NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_1="endorse answer radar about source reunion marriage tag sausage weekend frost daring base attack because joke dream slender leisure group reason prepare broken river" - -# The Wallet database folder used to store account data -WALLET_DB_PATH="./example-walletdb" -# The Stronghold snapshot file location used to store secrets -STRONGHOLD_SNAPSHOT_PATH="./example.stronghold" -# The password to unlock the Stronghold snapshot file (Don't use it to protect real secrets!) -STRONGHOLD_PASSWORD="ENCRYPTION_PASSWORD" -# The node URL to issue transactions with -NODE_URL="https://api.testnet.shimmer.network" -# The faucet URL to request test coins from -FAUCET_URL="https://faucet.testnet.shimmer.network/api/enqueue" -# The explorer URL to look up transactions, blocks, addresses and more -EXPLORER_URL="https://explorer.shimmer.network/testnet" diff --git a/bindings/nodejs/examples/.env.example b/bindings/nodejs/examples/.env.example new file mode 120000 index 0000000000..6b529fb08e --- /dev/null +++ b/bindings/nodejs/examples/.env.example @@ -0,0 +1 @@ +../../../sdk/examples/.env.example \ No newline at end of file diff --git a/bindings/nodejs/examples/how_tos/native_tokens/burn.ts b/bindings/nodejs/examples/how_tos/native_tokens/burn.ts index b0db86200d..c611a4aec6 100644 --- a/bindings/nodejs/examples/how_tos/native_tokens/burn.ts +++ b/bindings/nodejs/examples/how_tos/native_tokens/burn.ts @@ -12,7 +12,7 @@ const BURN_AMOUNT = '0x1'; // therefore the foundry output is also not required. But this will also make it impossible to destroy the foundry // output that minted it. // -// Make sure that `example.stronghold` and `example.walletdb` already exist by +// Make sure that `STRONGHOLD_SNAPSHOT_PATH` and `WALLET_DB_PATH` already exist by // running the `how_tos/accounts-and-addresses/create-wallet` example! // // Rename `.env.example` to `.env` first, then run diff --git a/bindings/nodejs/examples/how_tos/native_tokens/destroy-foundry.ts b/bindings/nodejs/examples/how_tos/native_tokens/destroy-foundry.ts index d09bb68644..817837e40e 100644 --- a/bindings/nodejs/examples/how_tos/native_tokens/destroy-foundry.ts +++ b/bindings/nodejs/examples/how_tos/native_tokens/destroy-foundry.ts @@ -6,7 +6,7 @@ import { getUnlockedWallet } from '../../wallet/common'; // In this example we will try to destroy the first foundry there is in the account. This is only possible if its // circulating supply is 0 and no native tokens were burned. // -// Make sure that `example.stronghold` and `example.walletdb` already exist by +// Make sure that `STRONGHOLD_SNAPSHOT_PATH` and `WALLET_DB_PATH` already exist by // running the `how_tos/accounts-and-addresses/create-wallet` example! // // Rename `.env.example` to `.env` first, then run diff --git a/bindings/nodejs/examples/how_tos/native_tokens/melt.ts b/bindings/nodejs/examples/how_tos/native_tokens/melt.ts index a347f380c4..f3e096f7c8 100644 --- a/bindings/nodejs/examples/how_tos/native_tokens/melt.ts +++ b/bindings/nodejs/examples/how_tos/native_tokens/melt.ts @@ -8,7 +8,7 @@ const MELT_AMOUNT = '0xA'; // In this example we will melt an existing native token with its foundry. // -// Make sure that `example.stronghold` and `example.walletdb` already exist by +// Make sure that `STRONGHOLD_SNAPSHOT_PATH` and `WALLET_DB_PATH` already exist by // running the `how_tos/accounts-and-addresses/create-wallet` example! // // Rename `.env.example` to `.env` first, then run diff --git a/bindings/nodejs/examples/how_tos/native_tokens/mint.ts b/bindings/nodejs/examples/how_tos/native_tokens/mint.ts index abea43983e..2cb6964d51 100644 --- a/bindings/nodejs/examples/how_tos/native_tokens/mint.ts +++ b/bindings/nodejs/examples/how_tos/native_tokens/mint.ts @@ -8,7 +8,7 @@ const MINT_AMOUNT = '0xA'; // In this example we will mint an existing native token with its foundry. // -// Make sure that `example.stronghold` and `example.walletdb` already exist by +// Make sure that `STRONGHOLD_SNAPSHOT_PATH` and `WALLET_DB_PATH` already exist by // running the `how_tos/accounts-and-addresses/create-wallet` example! // // Rename `.env.example` to `.env` first, then run diff --git a/bindings/nodejs/examples/how_tos/native_tokens/send.ts b/bindings/nodejs/examples/how_tos/native_tokens/send.ts index 4db62d5d40..444311e9d2 100644 --- a/bindings/nodejs/examples/how_tos/native_tokens/send.ts +++ b/bindings/nodejs/examples/how_tos/native_tokens/send.ts @@ -13,7 +13,7 @@ const RECV_ADDRESS = // In this example we will send native tokens. // -// Make sure that `example.stronghold` and `example.walletdb` already exist by +// Make sure that `STRONGHOLD_SNAPSHOT_PATH` and `WALLET_DB_PATH` already exist by // running the `how_tos/accounts-and-addresses/create-wallet` example! // // Rename `.env.example` to `.env` first, then run diff --git a/bindings/nodejs/examples/how_tos/nfts/burn_nft.ts b/bindings/nodejs/examples/how_tos/nfts/burn_nft.ts index 0c6b0660e8..acfff86555 100644 --- a/bindings/nodejs/examples/how_tos/nfts/burn_nft.ts +++ b/bindings/nodejs/examples/how_tos/nfts/burn_nft.ts @@ -5,7 +5,7 @@ import { Wallet } from '@iota/sdk'; // In this example we will burn an existing nft output. // -// Make sure that `example.stronghold` and `example.walletdb` already exist by +// Make sure that `STRONGHOLD_SNAPSHOT_PATH` and `WALLET_DB_PATH` already exist by // running the `how_tos/accounts-and-addresses/create-wallet` example! // // Rename `.env.example` to `.env` first, then run diff --git a/bindings/nodejs/examples/how_tos/nfts/mint_nft.ts b/bindings/nodejs/examples/how_tos/nfts/mint_nft.ts index 50e681da0f..e95f3a5bbc 100644 --- a/bindings/nodejs/examples/how_tos/nfts/mint_nft.ts +++ b/bindings/nodejs/examples/how_tos/nfts/mint_nft.ts @@ -26,7 +26,7 @@ const NFT2_AMOUNT = '1000000'; // In this example we will mint a new nft. // -// Make sure that `example.stronghold` and `example.walletdb` already exist by +// Make sure that `STRONGHOLD_SNAPSHOT_PATH` and `WALLET_DB_PATH` already exist by // running the `how_tos/accounts-and-addresses/create-wallet` example! // // Rename `.env.example` to `.env` first, then run diff --git a/bindings/nodejs/examples/how_tos/nfts/send_nft.ts b/bindings/nodejs/examples/how_tos/nfts/send_nft.ts index 2c8060f97b..4a369e3760 100644 --- a/bindings/nodejs/examples/how_tos/nfts/send_nft.ts +++ b/bindings/nodejs/examples/how_tos/nfts/send_nft.ts @@ -9,7 +9,7 @@ const RECV_ADDRESS = // In this example we will send an NFT (Non-fungible token). // -// Make sure that `example.stronghold` and `example.walletdb` already exist by +// Make sure that `STRONGHOLD_SNAPSHOT_PATH` and `WALLET_DB_PATH` already exist by // running the `how_tos/accounts-and-addresses/create-wallet` example! // // Rename `.env.example` to `.env` first, then run diff --git a/bindings/nodejs/examples/wallet/06-send-micro-transaction.ts b/bindings/nodejs/examples/wallet/06-send-micro-transaction.ts index c27b78f2d6..b964b83cd6 100644 --- a/bindings/nodejs/examples/wallet/06-send-micro-transaction.ts +++ b/bindings/nodejs/examples/wallet/06-send-micro-transaction.ts @@ -13,7 +13,7 @@ const RECV_ADDRESS = // In this example we will send an amount below the minimum storage deposit. // -// Make sure that `example.stronghold` and `example.walletdb` already exist by +// Make sure that `STRONGHOLD_SNAPSHOT_PATH` and `WALLET_DB_PATH` already exist by // running the `how_tos/accounts-and-addresses/create-wallet` example! // // Rename `.env.example` to `.env` first, then run @@ -47,7 +47,7 @@ async function run() { ); console.log( - `Transaction included: ${process.env.EXPLORER_URL}/block/${blockId}`, + `Block included: ${process.env.EXPLORER_URL}/block/${blockId}`, ); } catch (error) { console.log('Error: ', error); diff --git a/bindings/nodejs/examples/wallet/16-destroy-alias.ts b/bindings/nodejs/examples/wallet/16-destroy-alias.ts index 04a644b0d9..2da6620c70 100644 --- a/bindings/nodejs/examples/wallet/16-destroy-alias.ts +++ b/bindings/nodejs/examples/wallet/16-destroy-alias.ts @@ -6,7 +6,7 @@ import { getUnlockedWallet } from './common'; // In this example we will try to destroy the first alias there is in the account. This is only possible if possible // foundry outputs have circulating supply of 0. // -// Make sure that `example.stronghold` and `example.walletdb` already exist by +// Make sure that `STRONGHOLD_SNAPSHOT_PATH` and `WALLET_DB_PATH` already exist by // running the `how_tos/accounts-and-addresses/create-wallet` example! // // Rename `.env.example` to `.env` first, then run @@ -44,7 +44,7 @@ async function run() { transaction.transactionId, ); console.log( - `Transaction included: ${process.env.EXPLORER_URL}/block/${blockId}`, + `Block included: ${process.env.EXPLORER_URL}/block/${blockId}`, ); console.log(`Destroyed alias ${aliasId}`); diff --git a/bindings/nodejs/examples/wallet/17-check-unlock-conditions.ts b/bindings/nodejs/examples/wallet/17-check-unlock-conditions.ts index 4cb710329d..bc689973c4 100644 --- a/bindings/nodejs/examples/wallet/17-check-unlock-conditions.ts +++ b/bindings/nodejs/examples/wallet/17-check-unlock-conditions.ts @@ -10,7 +10,7 @@ const AMOUNT = '1000000'; // In this example we check if an output has only an address unlock condition and that the address is from the account. // -// Make sure that `example.stronghold` and `example.walletdb` already exist by +// Make sure that `STRONGHOLD_SNAPSHOT_PATH` and `WALLET_DB_PATH` already exist by // running the `how_tos/accounts-and-addresses/create-wallet` example! // // Rename `.env.example` to `.env` first, then run diff --git a/bindings/python/.env.example b/bindings/python/.env.example deleted file mode 100644 index a6d7394080..0000000000 --- a/bindings/python/.env.example +++ /dev/null @@ -1,5 +0,0 @@ -NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_1="endorse answer radar about source reunion marriage tag sausage weekend frost daring base attack because joke dream slender leisure group reason prepare broken river" -NODE_URL="https://api.testnet.shimmer.network" -FAUCET_URL="https://faucet.testnet.shimmer.network/api/enqueue" -EXPLORER_URL="https://explorer.shimmer.network/testnet" -STRONGHOLD_PASSWORD="some_hopefully_secure_password" \ No newline at end of file diff --git a/bindings/python/examples/.env.example b/bindings/python/examples/.env.example new file mode 120000 index 0000000000..6b529fb08e --- /dev/null +++ b/bindings/python/examples/.env.example @@ -0,0 +1 @@ +../../../sdk/examples/.env.example \ No newline at end of file diff --git a/sdk/Cargo.toml b/sdk/Cargo.toml index aa3aa03e78..54e9bf3d20 100644 --- a/sdk/Cargo.toml +++ b/sdk/Cargo.toml @@ -76,7 +76,7 @@ iota-sdk = { path = ".", default-features = false, features = [ "rand" ] } dotenvy = { version = "0.15.7", default-features = false } fern-logger = { version = "0.5.0", default-features = false } -tokio = { version = "1.28.2", default-features = false, features = [ "macros", "rt-multi-thread", "time", "sync", "fs" ] } +tokio = { version = "1.28.2", default-features = false, features = [ "macros", "rt", "rt-multi-thread", "time", "sync", "fs" ] } [features] default = [ "client", "wallet", "tls" ] @@ -92,7 +92,7 @@ rocksdb = [ "dep:rocksdb", "storage" ] serde = [ "serde_repr", "serde-big-array", "hashbrown/serde", "packable/serde", "primitive-types/serde_no_std", "zeroize?/serde" ] std = [ "packable/std", "prefix-hex/std", "primitive-types/std", "bech32/std", "bitflags/std", "rand?/std_rng", "regex?/std", "backtrace?/std", "derive_builder?/std", "iota_stronghold?/std", "iota-crypto/std", "once_cell?/std" ] storage = [ "iota-crypto/chacha", "dep:time", "dep:anymap", "dep:once_cell", "dep:heck" ] -stronghold = [ "iota_stronghold", "derive_builder", "iota-crypto/chacha", "dep:time", "dep:anymap", "dep:once_cell" ] +stronghold = [ "iota_stronghold", "derive_builder", "iota-crypto/chacha", "dep:time", "dep:anymap", "dep:once_cell", "dep:heck" ] tls = [ "reqwest?/rustls-tls", "rumqttc?/use-rustls" ] client = [ "pow", "tokio", "zeroize", "url", "reqwest", "async-trait", "log", "thiserror", "futures", "serde", "instant", "iota-crypto/bip39", "iota-crypto/bip39-en", "iota-crypto/slip10" ] @@ -298,6 +298,23 @@ name = "transaction" path = "examples/client/block/transaction.rs" required-features = [ "client" ] +# High Level examples + +[[example]] +name = "address_consolidation" +path = "examples/client/high_level/consolidation.rs" +required-features = [ "client" ] + +[[example]] +name = "inputs_from_transaction_id" +path = "examples/client/high_level/inputs_from_transaction_id.rs" +required-features = [ "client" ] + +[[example]] +name = "search_address" +path = "examples/client/high_level/search_address.rs" +required-features = [ "client" ] + # Node API core examples [[example]] @@ -445,15 +462,35 @@ required-features = [ "client" ] ####### [[example]] -name = "generate_addresses" +name = "01_generate_addresses" path = "examples/client/01_generate_addresses.rs" required-features = [ "client" ] +[[example]] +name = "02_address_balance" +path = "examples/client/02_address_balance.rs" +required-features = [ "client" ] + +[[example]] +name = "03_simple_block" +path = "examples/client/03_simple_block.rs" +required-features = [ "client" ] + [[example]] name = "07_mqtt" path = "examples/client/07_mqtt.rs" required-features = [ "client", "mqtt" ] +[[example]] +name = "client_config" +path = "examples/client/client_config.rs" +required-features = [ "client" ] + +[[example]] +name = "custom_remainder_address" +path = "examples/client/custom_remainder_address.rs" +required-features = [ "client" ] + [[example]] name = "get_block" path = "examples/client/get_block.rs" @@ -469,6 +506,11 @@ name = "ledger_nano_transaction" path = "examples/client/ledger_nano_transaction.rs" required-features = [ "client", "ledger_nano" ] +[[example]] +name = "client_logger" +path = "examples/client/logger.rs" +required-features = [ "client" ] + [[example]] name = "stronghold" path = "examples/client/stronghold.rs" @@ -564,6 +606,26 @@ name = "participation" path = "examples/client/participation.rs" required-features = [ "client", "participation" ] +[[example]] +name = "quorum" +path = "examples/client/quorum.rs" +required-features = [ "client" ] + +[[example]] +name = "send_all" +path = "examples/client/send_all.rs" +required-features = [ "client" ] + +[[example]] +name = "client_split_funds" +path = "examples/client/split_funds.rs" +required-features = [ "client" ] + +[[example]] +name = "tagged_data_to_utf8" +path = "examples/client/tagged_data_to_utf8.rs" +required-features = [ "client" ] + ### Wallet [[example]] diff --git a/sdk/.env.example b/sdk/examples/.env.example similarity index 65% rename from sdk/.env.example rename to sdk/examples/.env.example index 73980b7421..d394010c02 100644 --- a/sdk/.env.example +++ b/sdk/examples/.env.example @@ -1,24 +1,20 @@ -# This file contains environment variables that are used in our SDK examples. -# Make sure to change the mnemonic/seed variables if you want to start fresh -# and without interference by other users. -# You can create a mnemonic by running: `cargo run --package cli-wallet -- mnemonic`. +# This file contains environment variables that are used across all of our SDK examples including the bindings. +# Make sure to change the mnemonic variables to something new if you want to run the examples from a fresh state +# and without any interference by other users. +# You can create a new random mnemonic by running: `cargo run --package cli-wallet -- mnemonic`. # Mnemonics (Don't ever use them to manage real funds!) NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_1="endorse answer radar about source reunion marriage tag sausage weekend frost daring base attack because joke dream slender leisure group reason prepare broken river" NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_2="width scatter jaguar sponsor erosion enable cave since ancient first garden royal luggage exchange ritual exotic play wall clinic ride autumn divert spin exchange" -# Seeds (Don't ever use them to manage real funds!) -NON_SECURE_USE_OF_DEVELOPMENT_SEED_1="0x256a818b2aac458941f7274985a410e57fb750f3a3a67969ece5bd9ae7eef5b2" -NON_SECURE_USE_OF_DEVELOPMENT_SEED_2="0x256a818b2aac458941f7274985a410e57fb750f3a3a67969ece5bd9ae7eef5b3" # The Wallet database folder used to store account data WALLET_DB_PATH="./example-walletdb" # The Stronghold snapshot file location used to store secrets STRONGHOLD_SNAPSHOT_PATH="./example.stronghold" # The password to unlock the Stronghold snapshot file (Don't use it to protect real secrets!) -STRONGHOLD_PASSWORD="motdepasse" +STRONGHOLD_PASSWORD="24?drowssap" # The node URL to issue transactions with NODE_URL="https://api.testnet.shimmer.network" # The faucet URL to request test coins from FAUCET_URL="https://faucet.testnet.shimmer.network/api/enqueue" # The explorer URL to look up transactions, blocks, addresses and more EXPLORER_URL="https://explorer.shimmer.network/testnet" - diff --git a/sdk/examples/client/01_generate_addresses.rs b/sdk/examples/client/01_generate_addresses.rs index 183eb46723..bdfec91602 100644 --- a/sdk/examples/client/01_generate_addresses.rs +++ b/sdk/examples/client/01_generate_addresses.rs @@ -1,9 +1,12 @@ // Copyright 2021 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -//! TODO: Example description +//! This example shows how to generate addresses. //! -//! `cargo run --example generate_addresses --release -- [NODE_URL]` +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example 01_generate_addresses +//! ``` use iota_sdk::client::{ api::GetAddressesOptions, @@ -16,14 +19,9 @@ async fn main() -> Result<()> { // This example uses secrets in environment variables for simplicity which should not be done in production. dotenvy::dotenv().ok(); - // Take the node URL from command line argument or use one from env as default. - let node_url = std::env::args() - .nth(1) - .unwrap_or_else(|| std::env::var("NODE_URL").unwrap()); - - // Create a client instance + // Create a node client. let client = Client::builder() - .with_node(&node_url)? // Insert your node URL here + .with_node(&std::env::var("NODE_URL").unwrap())? .finish() .await?; @@ -35,7 +33,7 @@ async fn main() -> Result<()> { .generate_ed25519_addresses(GetAddressesOptions::from_client(&client).await?) .await?; - println!("List of generated public addresses:"); + println!("List of generated public addresses (default):"); println!("{addresses:#?}\n"); // Generate addresses with custom account index and range @@ -48,7 +46,7 @@ async fn main() -> Result<()> { ) .await?; - println!("List of generated public addresses:\n"); + println!("List of generated public addresses (0..4):\n"); println!("{addresses:#?}\n"); // Generate internal addresses with custom account index and range diff --git a/sdk/examples/client/02_get_address_balance.rs b/sdk/examples/client/02_address_balance.rs similarity index 54% rename from sdk/examples/client/02_get_address_balance.rs rename to sdk/examples/client/02_address_balance.rs index 51c82002ad..a37200cd01 100644 --- a/sdk/examples/client/02_get_address_balance.rs +++ b/sdk/examples/client/02_address_balance.rs @@ -1,16 +1,20 @@ // Copyright 2021 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -//! In this example we will get the outputs of an address that have no additional unlock conditions and sum the amounts -//! and native tokens. +//! This example shows how to get the outputs of an address that have no additional unlock conditions, and sum the +//! amounts and native tokens. //! -//! `cargo run --example 02_get_address_balance --release` +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example 02_address_balance +//! ``` -use iota_sdk::client::{ - block::output::{NativeTokensBuilder, Output}, - node_api::indexer::query_parameters::QueryParameter, - secret::{mnemonic::MnemonicSecretManager, SecretManager}, - Client, Result, +use iota_sdk::{ + client::{ + api::GetAddressesOptions, node_api::indexer::query_parameters::QueryParameter, secret::SecretManager, Client, + Result, + }, + types::block::output::NativeTokensBuilder, }; #[tokio::main] @@ -18,31 +22,29 @@ async fn main() -> Result<()> { // This example uses secrets in environment variables for simplicity which should not be done in production. dotenvy::dotenv().ok(); - let node_url = std::env::var("NODE_URL").unwrap(); - - // Create a client instance + // Create a node client. let client = Client::builder() - .with_node(&node_url)? // Insert your node URL here + .with_node(&std::env::var("NODE_URL").unwrap())? .finish() .await?; let secret_manager = - MnemonicSecretManager::try_from_mnemonic(std::env::var("NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_1").unwrap())?; - - let token_supply = client.get_token_supply().await?; + SecretManager::try_from_mnemonic(std::env::var("NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_1").unwrap())?; // Generate the first address - let addresses = client - .get_addresses(&SecretManager::Mnemonic(secret_manager)) - .with_account_index(0) - .with_range(0..1) - .finish() + let addresses = secret_manager + .generate_ed25519_addresses( + GetAddressesOptions::from_client(&client) + .await? + .with_account_index(0) + .with_range(0..1), + ) .await?; // Get output ids of outputs that can be controlled by this address without further unlock constraints let output_ids_response = client .basic_output_ids([ - QueryParameter::Address(addresses[0].clone()), + QueryParameter::Address(addresses[0]), QueryParameter::HasExpiration(false), QueryParameter::HasTimelock(false), QueryParameter::HasStorageDepositReturn(false), @@ -50,14 +52,13 @@ async fn main() -> Result<()> { .await?; // Get the outputs by their id - let outputs_responses = client.get_outputs(output_ids_response.items).await?; + let outputs_responses = client.get_outputs(&output_ids_response.items).await?; // Calculate the total amount and native tokens let mut total_amount = 0; let mut total_native_tokens = NativeTokensBuilder::new(); for output_response in outputs_responses { - let output = Output::try_from_dto(&output_response.output, token_supply)?; - + let output = output_response.output(); if let Some(native_tokens) = output.native_tokens() { total_native_tokens.add_native_tokens(native_tokens.clone())?; } @@ -65,7 +66,7 @@ async fn main() -> Result<()> { } println!( - "Outputs controlled by {} have: {:?}i and native tokens: {:?}", + "Outputs controlled by {} have: {:?}i and native tokens:\n{:#?}", addresses[0], total_amount, total_native_tokens.finish_vec()? diff --git a/sdk/examples/client/03_simple_block.rs b/sdk/examples/client/03_simple_block.rs index 23c44b6a11..1688c7516b 100644 --- a/sdk/examples/client/03_simple_block.rs +++ b/sdk/examples/client/03_simple_block.rs @@ -2,8 +2,11 @@ // SPDX-License-Identifier: Apache-2.0 //! In this example we will send a block without a payload. -//! -//! `cargo run --example 03_simple_block --release` +//! +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example 03_simple_block +//! ``` use iota_sdk::client::{Client, Result}; @@ -12,12 +15,11 @@ async fn main() -> Result<()> { // This example uses secrets in environment variables for simplicity which should not be done in production. dotenvy::dotenv().ok(); - let node_url = std::env::var("NODE_URL").unwrap(); - + // Create a node client. let client = Client::builder() - .with_node(&node_url)? - .with_pow_worker_count(1) - .finish()?; + .with_node(&std::env::var("NODE_URL").unwrap())? + .finish() + .await?; let block = client.block().finish().await?; @@ -26,5 +28,6 @@ async fn main() -> Result<()> { std::env::var("EXPLORER_URL").unwrap(), block.id() ); + Ok(()) } diff --git a/sdk/examples/client/07_mqtt.rs b/sdk/examples/client/07_mqtt.rs index 4074b4ae5d..9aaf1336ea 100644 --- a/sdk/examples/client/07_mqtt.rs +++ b/sdk/examples/client/07_mqtt.rs @@ -1,22 +1,35 @@ // Copyright 2021 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -//! TODO: Example description +//! This example shows how to listen to MQTT events of a node. //! -//! cargo run --example 07_mqtt --features=mqtt --release +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --all-features --example 07_mqtt [NUM_EVENTS] [ADDRESS] +//! ``` -use iota_sdk::client::{ - mqtt::{MqttEvent, MqttPayload, Topic}, - Client, Result, +use iota_sdk::{ + client::{ + mqtt::{BrokerOptions, MqttEvent, MqttPayload, Topic}, + Client, Result, + }, + types::block::address::Bech32Address, }; // Connecting to a MQTT broker using raw ip doesn't work with TCP. This is a limitation of rustls. #[tokio::main] async fn main() -> Result<()> { - // Create a client instance + let num_events: usize = std::env::args().nth(1).map(|s| s.parse().unwrap()).unwrap_or(10); + + let address: Bech32Address = std::env::args() + .nth(2) + .unwrap_or("atoi1qzt0nhsf38nh6rs4p6zs5knqp6psgha9wsv74uajqgjmwc75ugupx3y7x0r".to_string()) + .parse()?; + + // Create a node client. let client = Client::builder() .with_node("https://api.testnet.shimmer.network")? - // .with_mqtt_broker_options(BrokerOptions::new().use_ws(false)) + .with_mqtt_broker_options(BrokerOptions::new().use_ws(true)) .finish() .await?; @@ -27,10 +40,10 @@ async fn main() -> Result<()> { [ Topic::new("milestone-info/latest")?, Topic::new("blocks")?, - Topic::new("outputs/unlock/address/atoi1qzt0nhsf38nh6rs4p6zs5knqp6psgha9wsv74uajqgjmwc75ugupx3y7x0r")?, + Topic::new(format!("outputs/unlock/address/{address}"))?, ], move |event| { - println!("Topic: {}", event.topic); + println!("> Topic: {}", event.topic); match &event.payload { MqttPayload::Json(val) => println!("{}", serde_json::to_string(&val).unwrap()), MqttPayload::Block(block) => println!("{block:?}"), @@ -42,15 +55,21 @@ async fn main() -> Result<()> { ) .await?; - for i in 0..10 { + let mut event_count = 0; + loop { tokio::select! { _ = rx.recv() => { - if i == 7 { + event_count += 1; + if event_count == num_events { + client.unsubscribe([Topic::new("milestone-info/latest")?]).await?; client.unsubscribe([Topic::new("blocks")?]).await?; + client.unsubscribe([Topic::new(format!("outputs/unlock/address/{address}"))?]).await?; + break; } } _ = async { client.mqtt_event_receiver().await.wait_for(|msg| *msg == MqttEvent::Disconnected).await.unwrap(); + println!("Disconnected by remote"); } => { panic!("mqtt disconnected"); } @@ -60,5 +79,8 @@ async fn main() -> Result<()> { client.subscriber().disconnect().await?; // alternatively // client.subscriber().unsubscribe().await?; + + println!("Example completed successfully"); + Ok(()) } diff --git a/sdk/examples/client/block/00_block_no_payload.rs b/sdk/examples/client/block/00_block_no_payload.rs index 35173280fd..11b4cb0152 100644 --- a/sdk/examples/client/block/00_block_no_payload.rs +++ b/sdk/examples/client/block/00_block_no_payload.rs @@ -3,20 +3,21 @@ //! This example sends a block with no payload. //! -//! `cargo run --example block_no_payload --release -- [NODE URL]` +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example block_no_payload +//! ``` use iota_sdk::client::{Client, Result}; #[tokio::main] async fn main() -> Result<()> { - // Take the node URL from command line argument or use one from env as default. - let node_url = std::env::args().nth(1).unwrap_or_else(|| { - // This example uses secrets in environment variables for simplicity which should not be done in production. - dotenvy::dotenv().ok(); - std::env::var("NODE_URL").unwrap() - }); - - // Create a client with that node. + // This example uses secrets in environment variables for simplicity which should not be done in production. + dotenvy::dotenv().ok(); + + let node_url = std::env::var("NODE_URL").unwrap(); + + // Create a node client. let client = Client::builder().with_node(&node_url)?.finish().await?; // Create and send the block. diff --git a/sdk/examples/client/block/01_block_confirmation_time.rs b/sdk/examples/client/block/01_block_confirmation_time.rs index e9e60585a8..041c79e637 100644 --- a/sdk/examples/client/block/01_block_confirmation_time.rs +++ b/sdk/examples/client/block/01_block_confirmation_time.rs @@ -3,20 +3,21 @@ //! This example sends a block and returns the time at which it got confirmed. //! -//! `cargo run --example block_confirmation_time --release -- [NODE URL]` +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example block_confirmation_time +//! ``` use iota_sdk::client::{Client, Result}; #[tokio::main] async fn main() -> Result<()> { - // Take the node URL from command line argument or use one from env as default. - let node_url = std::env::args().nth(1).unwrap_or_else(|| { - // This example uses secrets in environment variables for simplicity which should not be done in production. - dotenvy::dotenv().ok(); - std::env::var("NODE_URL").unwrap() - }); - - // Create a client with that node. + // This example uses secrets in environment variables for simplicity which should not be done in production. + dotenvy::dotenv().ok(); + + let node_url = std::env::var("NODE_URL").unwrap(); + + // Create a node client. let client = Client::builder().with_node(&node_url)?.finish().await?; // Create and send a block. @@ -26,7 +27,7 @@ async fn main() -> Result<()> { println!("{block:#?}"); // Try to check if the block has been confirmed. - let _ = client.retry_until_included(&block_id, None, None).await?; + client.retry_until_included(&block_id, None, None).await?; println!( "Block with no payload included: {}/block/{}", std::env::var("EXPLORER_URL").unwrap(), diff --git a/sdk/examples/client/block/02_block_custom_parents.rs b/sdk/examples/client/block/02_block_custom_parents.rs index a890197053..ad1cdeeb12 100644 --- a/sdk/examples/client/block/02_block_custom_parents.rs +++ b/sdk/examples/client/block/02_block_custom_parents.rs @@ -3,27 +3,29 @@ //! This example sends a block, with custom parents, which can be used for promoting. //! -//! `cargo run --example block_custom_parents --release -- [NODE URL]` +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example block_custom_parents +//! ``` use iota_sdk::client::{Client, Result}; #[tokio::main] async fn main() -> Result<()> { - // Take the node URL from command line argument or use one from env as default. - let node_url = std::env::args().nth(1).unwrap_or_else(|| { - // This example uses secrets in environment variables for simplicity which should not be done in production. - dotenvy::dotenv().ok(); - std::env::var("NODE_URL").unwrap() - }); - - // Create a client with that node. + // This example uses secrets in environment variables for simplicity which should not be done in production. + dotenvy::dotenv().ok(); + + let node_url = std::env::var("NODE_URL").unwrap(); + + // Create a node client. let client = Client::builder().with_node(&node_url)?.finish().await?; // Use tips as custom parents. - let parents = client.get_tips().await?; + let tips = client.get_tips().await?; + println!("Custom tips:\n{tips:#?}"); // Create and send the block with custom parents. - let block = client.block().with_parents(parents)?.finish().await?; + let block = client.block().with_parents(tips)?.finish().await?; println!("{block:#?}"); diff --git a/sdk/examples/client/block/03_block_custom_payload.rs b/sdk/examples/client/block/03_block_custom_payload.rs index 0841fb8fe2..602503a566 100644 --- a/sdk/examples/client/block/03_block_custom_payload.rs +++ b/sdk/examples/client/block/03_block_custom_payload.rs @@ -3,7 +3,10 @@ //! This example sends a block with a custom payload. //! -//! `cargo run --example block_custom_payload --release -- [NODE URL]` +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example block_custom_payload +//! ``` use iota_sdk::{ client::{Client, Result}, @@ -12,18 +15,16 @@ use iota_sdk::{ #[tokio::main] async fn main() -> Result<()> { - // Take the node URL from command line argument or use one from env as default. - let node_url = std::env::args().nth(1).unwrap_or_else(|| { - // This example uses secrets in environment variables for simplicity which should not be done in production. - dotenvy::dotenv().ok(); - std::env::var("NODE_URL").unwrap() - }); - - // Create a client with that node. + // This example uses secrets in environment variables for simplicity which should not be done in production. + dotenvy::dotenv().ok(); + + let node_url = std::env::var("NODE_URL").unwrap(); + + // Create a node client. let client = Client::builder().with_node(&node_url)?.finish().await?; // Create a custom payload. - let tagged_data_payload = TaggedDataPayload::new(b"Your tag".to_vec(), b"Your data".to_vec())?; + let tagged_data_payload = TaggedDataPayload::new(*b"Your tag", *b"Your data")?; // Create and send the block with the custom payload. let block = client diff --git a/sdk/examples/client/block/04_block_tagged_data.rs b/sdk/examples/client/block/04_block_tagged_data.rs index 4888a1f2d5..f7fa6ac47d 100644 --- a/sdk/examples/client/block/04_block_tagged_data.rs +++ b/sdk/examples/client/block/04_block_tagged_data.rs @@ -3,7 +3,10 @@ //! This example sends a block with a tagged data payload. //! -//! `cargo run --example block_tagged_data --release -- [NODE URL]` +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example block_tagged_data [TAG] [DATA] +//! ``` use iota_sdk::{ client::{Client, Result}, @@ -12,21 +15,22 @@ use iota_sdk::{ #[tokio::main] async fn main() -> Result<()> { - // Take the node URL from command line argument or use one from env as default. - let node_url = std::env::args().nth(1).unwrap_or_else(|| { - // This example uses secrets in environment variables for simplicity which should not be done in production. - dotenvy::dotenv().ok(); - std::env::var("NODE_URL").unwrap() - }); - - // Create a client with that node. + // This example uses secrets in environment variables for simplicity which should not be done in production. + dotenvy::dotenv().ok(); + + let node_url = std::env::var("NODE_URL").unwrap(); + + let tag = std::env::args().nth(1).unwrap_or_else(|| "Hello".to_string()); + let data = std::env::args().nth(2).unwrap_or_else(|| "Tangle".to_string()); + + // Create a node client. let client = Client::builder().with_node(&node_url)?.finish().await?; // Create and send the block with tag and data. let block = client .block() - .with_tag(b"Hello".to_vec()) - .with_data(b"Tangle".to_vec()) + .with_tag(tag.as_bytes().to_vec()) + .with_data(data.as_bytes().to_vec()) .finish() .await?; diff --git a/sdk/examples/client/block/custom_inputs.rs b/sdk/examples/client/block/custom_inputs.rs index b800db56ee..8d7a438db1 100644 --- a/sdk/examples/client/block/custom_inputs.rs +++ b/sdk/examples/client/block/custom_inputs.rs @@ -1,10 +1,12 @@ // Copyright 2021 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -//! In this example we will send 1_000_000 tokens to atoi1qzt0nhsf38nh6rs4p6zs5knqp6psgha9wsv74uajqgjmwc75ugupx3y7x0r. -//! This address belongs to the first seed in .env.example. +//! In this example we will send a certain amount of tokens to some address using custom inputs. //! -//! `cargo run --example custom_inputs --release` +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example custom_inputs [AMOUNT] [ADDRESS] +//! ``` use iota_sdk::{ client::{ @@ -22,36 +24,46 @@ async fn main() -> Result<()> { let node_url = std::env::var("NODE_URL").unwrap(); let faucet_url = std::env::var("FAUCET_URL").unwrap(); - // Create a client instance - let client = Client::builder() - .with_node(&node_url)? // Insert your node URL here - .finish() - .await?; + let amount = std::env::args() + .nth(1) + .map(|s| s.parse::().unwrap()) + .unwrap_or(1_000_000u64); + + // Create a node client. + let client = Client::builder().with_node(&node_url)?.finish().await?; - // First address from the seed below is atoi1qzt0nhsf38nh6rs4p6zs5knqp6psgha9wsv74uajqgjmwc75ugupx3y7x0r let secret_manager = - SecretManager::try_from_hex_seed(std::env::var("NON_SECURE_USE_OF_DEVELOPMENT_SEED_1").unwrap())?; + SecretManager::try_from_mnemonic(std::env::var("NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_1").unwrap())?; - let addresses = secret_manager + // Get the first address of the seed + let first_address = secret_manager .generate_ed25519_addresses(GetAddressesOptions::from_client(&client).await?.with_range(0..1)) - .await?; - println!("{:?}", addresses[0]); + .await?[0]; + println!("1st address: {first_address:#?}"); - println!("{}", request_funds_from_faucet(&faucet_url, &addresses[0]).await?); + println!( + "Requesting funds (waiting 15s): {}", + request_funds_from_faucet(&faucet_url, &first_address).await? + ); tokio::time::sleep(std::time::Duration::from_secs(15)).await; - let output_ids_response = client.basic_output_ids([QueryParameter::Address(addresses[0])]).await?; + let output_ids_response = client + .basic_output_ids([QueryParameter::Address(first_address)]) + .await?; println!("{output_ids_response:?}"); + // If no custom address is provided, we will use the first address from the seed. + let recv_address = std::env::args() + .nth(2) + .map(|s| s.parse().unwrap()) + .unwrap_or(first_address); + let block = client .block() .with_secret_manager(&secret_manager) .with_input(UtxoInput::from(output_ids_response.items[0]))? //.with_input_range(20..25) - .with_output( - "atoi1qzt0nhsf38nh6rs4p6zs5knqp6psgha9wsv74uajqgjmwc75ugupx3y7x0r", - 1_000_000, - ) + .with_output(recv_address, amount) .await? .finish() .await?; diff --git a/sdk/examples/client/block/output.rs b/sdk/examples/client/block/output.rs index 359c648e24..3dfbecbec1 100644 --- a/sdk/examples/client/block/output.rs +++ b/sdk/examples/client/block/output.rs @@ -1,9 +1,12 @@ // Copyright 2021 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -//! In this example we will send a transaction. +//! In this example we will send a certain amount of tokens to some address by specifying the outputs. //! -//! `cargo run --example output --release` +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example output [AMOUNT] [ADDRESS] +//! ``` use iota_sdk::{ client::{api::GetAddressesOptions, secret::SecretManager, utils::request_funds_from_faucet, Client, Result}, @@ -13,13 +16,17 @@ use iota_sdk::{ #[tokio::main] async fn main() -> Result<()> { // This example uses secrets in environment variables for simplicity which should not be done in production. - // Configure your own mnemonic in ".env". Since the output amount cannot be zero, the mnemonic must contain non-zero - // balance. dotenvy::dotenv().ok(); let node_url = std::env::var("NODE_URL").unwrap(); let faucet_url = std::env::var("FAUCET_URL").unwrap(); + let amount = std::env::args() + .nth(1) + .map(|s| s.parse::().unwrap()) + .unwrap_or(1_000_000u64); + + // Create a node client. let client = Client::builder().with_node(&node_url)?.finish().await?; let secret_manager = @@ -27,13 +34,26 @@ async fn main() -> Result<()> { let token_supply = client.get_token_supply().await?; - let address = secret_manager + // Get the first address of the seed + let first_address = secret_manager .generate_ed25519_addresses(GetAddressesOptions::from_client(&client).await?.with_range(0..1)) .await?[0]; - request_funds_from_faucet(&faucet_url, &address).await?; + println!("1st address: {first_address:#?}"); + + println!( + "Requesting funds (waiting 15s): {}", + request_funds_from_faucet(&faucet_url, &first_address).await? + ); + tokio::time::sleep(std::time::Duration::from_secs(15)).await; + + // If no custom address is provided, we will use the first address from the seed. + let recv_address = std::env::args() + .nth(2) + .map(|s| s.parse().unwrap()) + .unwrap_or(first_address); - let outputs = [BasicOutputBuilder::new_with_amount(1_000_000) - .add_unlock_condition(AddressUnlockCondition::new(address)) + let outputs = [BasicOutputBuilder::new_with_amount(amount) + .add_unlock_condition(AddressUnlockCondition::new(recv_address)) .finish_output(token_supply)?]; let block = client diff --git a/sdk/examples/client/block/transaction.rs b/sdk/examples/client/block/transaction.rs index 99e4c16c43..07136c5a1a 100644 --- a/sdk/examples/client/block/transaction.rs +++ b/sdk/examples/client/block/transaction.rs @@ -1,37 +1,57 @@ // Copyright 2021 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -//! In this example we will send a transaction. +//! In this example we will send a certain amount of tokens to some address by using the block builder only. //! -//! `cargo run --example transaction --release` +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example transaction [AMOUNT] [ADDRESS] +//! ``` -use iota_sdk::client::{api::GetAddressesOptions, secret::SecretManager, Client, Result}; +use iota_sdk::client::{api::GetAddressesOptions, request_funds_from_faucet, secret::SecretManager, Client, Result}; #[tokio::main] async fn main() -> Result<()> { // This example uses secrets in environment variables for simplicity which should not be done in production. - // Configure your own mnemonic in ".env". Since the output amount cannot be zero, the mnemonic must contain non-zero - // balance. dotenvy::dotenv().ok(); let node_url = std::env::var("NODE_URL").unwrap(); + let faucet_url = std::env::var("FAUCET_URL").unwrap(); + let amount = std::env::args() + .nth(1) + .map(|s| s.parse::().unwrap()) + .unwrap_or(1_000_000u64); + + // Create a node client. let client = Client::builder().with_node(&node_url)?.finish().await?; let secret_manager = SecretManager::try_from_mnemonic(std::env::var("NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_1").unwrap())?; + // Get the first address of the seed + let first_address = secret_manager + .generate_ed25519_addresses(GetAddressesOptions::from_client(&client).await?.with_range(0..1)) + .await?[0]; + println!("1st address: {first_address:#?}"); + + println!( + "Requesting funds (waiting 15s): {}", + request_funds_from_faucet(&faucet_url, &first_address).await? + ); + tokio::time::sleep(std::time::Duration::from_secs(15)).await; + + // If no custom address is provided, we will use the first address from the seed. + let recv_address = std::env::args() + .nth(2) + .map(|s| s.parse().unwrap()) + .unwrap_or(first_address); + let block = client .block() .with_secret_manager(&secret_manager) // Insert the output address and amount to spent. The amount cannot be zero. - .with_output( - // We generate an address from our own mnemonic so that we send the funds to ourselves - &secret_manager - .generate_ed25519_addresses(GetAddressesOptions::from_client(&client).await?.with_range(1..2)) - .await?[0], - 1_000_000, - ) + .with_output(recv_address, amount) .await? .finish() .await?; diff --git a/sdk/examples/client/client_config.rs b/sdk/examples/client/client_config.rs index 70bfb71326..d488f813b9 100644 --- a/sdk/examples/client/client_config.rs +++ b/sdk/examples/client/client_config.rs @@ -2,8 +2,11 @@ // SPDX-License-Identifier: Apache-2.0 //! In this example we will create a client from a JSON config. -//! -//! `cargo run --example client_config --release` +//! +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example client_config +//! ``` use iota_sdk::client::{Client, Result}; @@ -32,10 +35,11 @@ async fn main() -> Result<()> { } }"#, )? - .finish()?; + .finish() + .await?; let info = client.get_info().await?; - println!("Node Info: {info:?}"); + println!("{info:#?}"); Ok(()) } diff --git a/sdk/examples/client/custom_remainder_address.rs b/sdk/examples/client/custom_remainder_address.rs index 68027fa130..3ce803a733 100644 --- a/sdk/examples/client/custom_remainder_address.rs +++ b/sdk/examples/client/custom_remainder_address.rs @@ -1,34 +1,46 @@ // Copyright 2021 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -//! In this example we will send 9_000_000 tokens to a given receiver and 1_000_000 tokens to a custom remainder -//! address. The used addresses belong to the first seed in .env.example. +//! In this example we will send a certain amount of tokens to a given receiver address and any remaining +//! tokens to a custom remainder address. //! -//! `cargo run --example custom_remainder_address --release` +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example custom_remainder_address [AMOUNT] +//! ``` use iota_sdk::client::{ - node_api::indexer::query_parameters::QueryParameter, request_funds_from_faucet, secret::SecretManager, Client, - Result, + api::GetAddressesOptions, node_api::indexer::query_parameters::QueryParameter, request_funds_from_faucet, + secret::SecretManager, Client, Result, }; #[tokio::main] async fn main() -> Result<()> { + let amount = std::env::args() + .nth(1) + .map(|s| s.parse::().unwrap()) + .unwrap_or(9_000_000); + // This example uses secrets in environment variables for simplicity which should not be done in production. dotenvy::dotenv().ok(); - let node_url = std::env::var("NODE_URL").unwrap(); - let faucet_url = std::env::var("FAUCET_URL").unwrap(); - - // Create a client instance + // Create a client instance. let client = Client::builder() - .with_node(&node_url)? // Insert your node URL here - .finish()?; + .with_node(&std::env::var("NODE_URL").unwrap())? + .finish() + .await?; - // First address from the seed below is atoi1qzt0nhsf38nh6rs4p6zs5knqp6psgha9wsv74uajqgjmwc75ugupx3y7x0r let secret_manager = - SecretManager::try_from_hex_seed(&std::env::var("NON_SECURE_USE_OF_DEVELOPMENT_SEED_1").unwrap())?; + SecretManager::try_from_mnemonic(std::env::var("NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_1").unwrap())?; - let addresses = client.get_addresses(&secret_manager).with_range(0..3).finish().await?; + let addresses = secret_manager + .generate_ed25519_addresses( + GetAddressesOptions::from_client(&client) + .await? + .with_account_index(0) + .with_range(0..3), + ) + .await?; let sender_address = &addresses[0]; let receiver_address = &addresses[1]; @@ -39,26 +51,21 @@ async fn main() -> Result<()> { println!("remainder address: {remainder_address}"); println!( - "automatically funding sender address with faucet: {}", - request_funds_from_faucet(faucet_url, sender_address).await? + "Requesting funds (waiting 15s): {}", + request_funds_from_faucet(&std::env::var("FAUCET_URL").unwrap(), sender_address).await?, ); tokio::time::sleep(std::time::Duration::from_secs(15)).await; let output_ids_response = client - .basic_output_ids([QueryParameter::Address(sender_address.clone())]) + .basic_output_ids([QueryParameter::Address(*sender_address)]) .await?; - println!("{output_ids_response:?}"); + println!("{output_ids_response:#?}"); let block = client .block() .with_secret_manager(&secret_manager) - .with_output( - // We generate an address from our seed so that we send the funds to ourselves - receiver_address, - 9_000_000, - ) + .with_output(receiver_address, amount) .await? - // We send the remainder to an address where we don't have access to. .with_custom_remainder_address(remainder_address)? .finish() .await?; diff --git a/sdk/examples/client/get_block.rs b/sdk/examples/client/get_block.rs index eabf27aa96..d9d1396d8c 100644 --- a/sdk/examples/client/get_block.rs +++ b/sdk/examples/client/get_block.rs @@ -3,7 +3,10 @@ //! In this example we will get a block and its metadata. //! -//! `cargo run --example get_block --release` +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example get_block +//! ``` use iota_sdk::client::{Client, Result}; @@ -12,10 +15,9 @@ async fn main() -> Result<()> { // This example uses secrets in environment variables for simplicity which should not be done in production. dotenvy::dotenv().ok(); - let node_url = std::env::var("NODE_URL").unwrap(); - + // Create a node client. let client = Client::builder() - .with_node(&node_url)? + .with_node(&std::env::var("NODE_URL").unwrap())? .with_pow_worker_count(1) .finish() .await?; @@ -29,5 +31,6 @@ async fn main() -> Result<()> { let block_metadata = client.get_block_metadata(&block_id).await?; println!("{block_metadata:#?}"); + Ok(()) } diff --git a/sdk/examples/client/high_level/consolidation.rs b/sdk/examples/client/high_level/consolidation.rs index 5e927ab902..dea1e7a73e 100644 --- a/sdk/examples/client/high_level/consolidation.rs +++ b/sdk/examples/client/high_level/consolidation.rs @@ -3,41 +3,49 @@ //! In this example we will consolidate all funds in a range of addresses. //! -//! `cargo run --example consolidation --release` +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example address_consolidation [ADDRESS INDEX START] [ADDRESS COUNT] +//! ``` -use iota_sdk::client::{ - api::GetAddressesBuilderOptions, - secret::{mnemonic::MnemonicSecretManager, SecretManager}, - Client, Result, -}; +use iota_sdk::client::{api::GetAddressesOptions, secret::SecretManager, Client, Result}; #[tokio::main] async fn main() -> Result<()> { // This example uses secrets in environment variables for simplicity which should not be done in production. - // Configure your own mnemonic in ".env". Since the output amount cannot be zero, the mnemonic must contain non-zero - // balance. dotenvy::dotenv().ok(); - let node_url = std::env::var("NODE_URL").unwrap(); + let address_range_start = std::env::args().nth(1).map(|s| s.parse::().unwrap()).unwrap_or(0); + let address_range_len = std::env::args().nth(2).map(|s| s.parse::().unwrap()).unwrap_or(10); - let address_range = 0u32..150; - // Create a client instance - let client = Client::builder().with_node(&node_url)?.finish().await?; + let address_range = address_range_start..address_range_start + address_range_len; + println!("Address consolidation range: {:?}", address_range); + + // Create a node client. + let client = Client::builder() + .with_node(&std::env::var("NODE_URL").unwrap())? + .finish() + .await?; let secret_manager = - SecretManager::try_from_hex_seed(&std::env::var("NON_SECURE_USE_OF_DEVELOPMENT_SEED_1").unwrap())?; + SecretManager::try_from_mnemonic(std::env::var("NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_1").unwrap())?; // Here all funds will be send to the address with the lowest index in the range let address = client .consolidate_funds( &secret_manager, - GetAddressesBuilderOptions { - range: Some(address_range), + GetAddressesOptions { + range: address_range, ..Default::default() }, ) .await?; - println!("Funds consolidated to {}", address); + println!( + "Funds consolidated to: {}/addr/{}", + std::env::var("EXPLORER_URL").unwrap(), + address + ); + Ok(()) } diff --git a/sdk/examples/client/high_level/inputs_from_transaction_id.rs b/sdk/examples/client/high_level/inputs_from_transaction_id.rs index ff779a0bf4..1b8f1072c2 100644 --- a/sdk/examples/client/high_level/inputs_from_transaction_id.rs +++ b/sdk/examples/client/high_level/inputs_from_transaction_id.rs @@ -3,9 +3,17 @@ //! In this example we will fetch all inputs from a given transaction id. //! -//! `cargo run --example inputs_from_transaction_id --release` +//! Make sure to provide a somewhat recent transaction id to make this example run successfully! +//! +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example inputs_from_transaction_id +//! ``` -use iota_sdk::client::{block::payload::transaction::TransactionId, Client, Result}; +use iota_sdk::{ + client::{Client, Result}, + types::block::payload::transaction::TransactionId, +}; #[tokio::main] async fn main() -> Result<()> { @@ -14,14 +22,16 @@ async fn main() -> Result<()> { let node_url = std::env::var("NODE_URL").unwrap(); + // Create a node client. let client = Client::builder().with_node(&node_url)?.finish().await?; - - let transaction_id = - "0xaf7579fb57746219561072c2cc0e4d0fbb8d493d075bd21bf25ae81a450c11ef".parse::()?; + let transaction_id = std::env::args() + .nth(1) + .expect("missing example argument: TRANSACTION ID") + .parse::()?; let inputs = client.inputs_from_transaction_id(&transaction_id).await?; - println!("Transaction inputs {:?}", inputs); + println!("Transaction inputs:\n{:#?}", inputs); Ok(()) } diff --git a/sdk/examples/client/high_level/search_address.rs b/sdk/examples/client/high_level/search_address.rs index 64a7140518..0795ca659e 100644 --- a/sdk/examples/client/high_level/search_address.rs +++ b/sdk/examples/client/high_level/search_address.rs @@ -3,12 +3,15 @@ //! In this example we will try to find the index and address type of an address. //! -//! `cargo run --example search_address --release` +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example search_address [BECH32_ADDRESS] [START_INDEX] [RANGE_SIZE] +//! ``` use iota_sdk::client::{ - api::search_address, - constants::IOTA_COIN_TYPE, - secret::{mnemonic::MnemonicSecretManager, SecretManager}, + api::{search_address, GetAddressesOptions}, + constants::SHIMMER_COIN_TYPE, + secret::SecretManager, Client, Result, }; @@ -19,33 +22,38 @@ async fn main() -> Result<()> { let node_url = std::env::var("NODE_URL").unwrap(); - // Create a client instance - let client = Client::builder() - .with_node(&node_url)? // Insert your node URL here - .finish()?; + // Create a node client. + let client = Client::builder().with_node(&node_url)?.finish().await?; let secret_manager = SecretManager::try_from_mnemonic(std::env::var("NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_1").unwrap())?; - let addresses = client - .get_addresses(&secret_manager) - .with_account_index(0) - .with_range(9..10) - .get_raw() - .await?; - - println!("{:?}", addresses[0]); - - let res = search_address( + let address = if let Some(addr) = std::env::args() + .nth(1) + .map(|addr| addr.parse().expect("invalid address")) + { + addr + } else { + secret_manager + .generate_ed25519_addresses(GetAddressesOptions::from_client(&client).await?.with_range(0..1)) + .await?[0] + }; + println!("Search address: {address:#?}"); + + let address_range_start = std::env::args().nth(2).map(|s| s.parse::().unwrap()).unwrap_or(0); + let address_range_len = std::env::args().nth(3).map(|s| s.parse::().unwrap()).unwrap_or(10); + let address_range = address_range_start..address_range_start + address_range_len; + + let (address_index, is_internal) = search_address( &secret_manager, - &client.get_bech32_hrp().await?, - IOTA_COIN_TYPE, + client.get_bech32_hrp().await?, + SHIMMER_COIN_TYPE, 0, - 0..10, - &addresses[0], + address_range, + &address.into(), ) .await?; + println!("Address index: {address_index}\nIs internal address: {is_internal}"); - println!("Address index: {}\nIs internal address: {}", res.0, res.1); Ok(()) } diff --git a/sdk/examples/client/ledger_nano.rs b/sdk/examples/client/ledger_nano.rs index 566ac52802..3b83715854 100644 --- a/sdk/examples/client/ledger_nano.rs +++ b/sdk/examples/client/ledger_nano.rs @@ -1,11 +1,20 @@ // Copyright 2021 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -//! In this example we will create addresses with a ledger nano hardware wallet. -//! To use the ledger nano simulator clone https://github.com/iotaledger/ledger-shimmer-app, run `git submodule init && git submodule update --recursive`, -//! then `./build.sh -m nanos|nanox|nanosplus -s` and use `true` in `LedgerSecretManager::new(true)`. +//! In this example we will create testnet addresses with a simulated ledger nano hardware wallet. //! -//! `cargo run --example ledger_nano --features=ledger_nano --release` +//! To use the ledger nano simulator, run the following commands: +//! 1. `clone https://github.com/iotaledger/ledger-shimmer-app` +//! 2. `cd ledger-shimmer-app` +//! 3. `git submodule init && git submodule update --recursive` +//! 4. `./build.sh -m nanos|nanox|nanosplus -s` +//! +//! Then, open the ledger nano web interface at `http://localhost:5000`. +//! +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --all-features --example ledger_nano +//! ``` use iota_sdk::client::{ api::GetAddressesOptions, @@ -19,7 +28,7 @@ async fn main() -> Result<()> { // This example uses secrets in environment variables for simplicity which should not be done in production. dotenvy::dotenv().ok(); - let ledger_nano = LedgerSecretManager::new(false); + let ledger_nano = LedgerSecretManager::new(true); println!("{:?}", ledger_nano.get_ledger_nano_status().await); diff --git a/sdk/examples/client/ledger_nano_transaction.rs b/sdk/examples/client/ledger_nano_transaction.rs index a855854011..7cd9636d65 100644 --- a/sdk/examples/client/ledger_nano_transaction.rs +++ b/sdk/examples/client/ledger_nano_transaction.rs @@ -1,9 +1,21 @@ // Copyright 2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -//! In this example we will create a transaction with a ledger nano hardware wallet. +//! In this example we will create a testnet transaction with a simulated ledger nano hardware wallet. //! -//! `cargo run --example ledger_nano_transaction --features=ledger_nano --release` +//! To use the ledger nano simulator, run the following commands: +//! 1. `clone https://github.com/iotaledger/ledger-shimmer-app` +//! 2. `cd ledger-shimmer-app` +//! 3. `git submodule init && git submodule update --recursive` +//! 4. `./build.sh -m nanos|nanox|nanosplus -s` +//! +//! Then, open the ledger nano web interface at `http://localhost:5000`. You'll have to approve the +//! transaction the same way as you would with a regular ledger nano device. +//! +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --all-features --example ledger_nano_transaction +//! ``` use iota_sdk::client::{ api::GetAddressesOptions, @@ -11,16 +23,16 @@ use iota_sdk::client::{ Client, Result, }; +const AMOUNT: u64 = 1_000_000; + #[tokio::main] async fn main() -> Result<()> { // This example uses secrets in environment variables for simplicity which should not be done in production. dotenvy::dotenv().ok(); - let node_url = std::env::var("NODE_URL").unwrap(); - // Create a client instance let client = Client::builder() - .with_node(&node_url)? // Insert your node URL here + .with_node(&std::env::var("NODE_URL").unwrap())? .finish() .await?; @@ -36,17 +48,15 @@ async fn main() -> Result<()> { ) .await?; - println!("List of generated public addresses:\n{addresses:?}\n"); + println!("List of generated public addresses:\n{addresses:#?}\n"); + + let recv_address = addresses[1]; + println!("Sending {AMOUNT} to {recv_address}"); let block = client .block() .with_secret_manager(&secret_manager) - // Insert the output address and amount to spent. The amount cannot be zero. - .with_output( - // We generate an address from our seed so that we send the funds to ourselves - addresses[1], - 1_000_000, - ) + .with_output(recv_address, AMOUNT) .await? .finish() .await?; diff --git a/sdk/examples/client/logger.rs b/sdk/examples/client/logger.rs index 203cde7c5a..3ed2376c46 100644 --- a/sdk/examples/client/logger.rs +++ b/sdk/examples/client/logger.rs @@ -1,38 +1,42 @@ // Copyright 2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -//! TODO: Example description +//! This examples shows how to create log files. //! -//! `cargo run --example logger --release` +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example client_logger +//! ``` use iota_sdk::client::{Client, Result}; #[tokio::main] async fn main() -> Result<()> { + // This example uses secrets in environment variables for simplicity which should not be done in production. + dotenvy::dotenv().ok(); + // Generates a client.log file with logs for debugging let logger_output_config = fern_logger::LoggerOutputConfigBuilder::new() .name("client.log") .target_exclusions(&["h2", "hyper", "rustls"]) .level_filter(log::LevelFilter::Debug); + let config = fern_logger::LoggerConfig::build() .with_output(logger_output_config) .finish(); - fern_logger::logger_init(config).unwrap(); - // Take the node URL from command line argument or use one from env as default. - let node_url = std::env::args().nth(1).unwrap_or_else(|| { - // This example uses secrets in environment variables for simplicity which should not be done in production. - dotenvy::dotenv().ok(); - std::env::var("NODE_URL").unwrap() - }); + fern_logger::logger_init(config).unwrap(); - // Create a client with that node. - let client = Client::builder().with_node(&node_url)?.finish().await?; + // Create a node client. + let client = Client::builder() + .with_node(&std::env::var("NODE_URL").unwrap())? + .finish() + .await?; // Get node info. - let info = client.get_info().await?; + let _ = client.get_info().await?; - println!("{info:#?}"); + println!("Example completed successfully. `client.log` file has been updated."); Ok(()) } diff --git a/sdk/examples/client/node_api_core/01_get_routes.rs b/sdk/examples/client/node_api_core/01_get_routes.rs index f5c3688f56..74c8b672d1 100644 --- a/sdk/examples/client/node_api_core/01_get_routes.rs +++ b/sdk/examples/client/node_api_core/01_get_routes.rs @@ -1,22 +1,26 @@ // Copyright 2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -//! Returns the available API route groups of the node by calling `GET /api/routes`. +//! Returns the available API route groups of the node by querying its `/api/routes` endpoint. //! -//! `cargo run --example node_api_core_get_routes --release -- [NODE URL]` +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example node_api_core_get_routes [NODE URL] +//! ``` use iota_sdk::client::{Client, Result}; #[tokio::main] async fn main() -> Result<()> { + // If not provided we use the default node from the `.env` file. + dotenvy::dotenv().ok(); + // Take the node URL from command line argument or use one from env as default. - let node_url = std::env::args().nth(1).unwrap_or_else(|| { - // This example uses secrets in environment variables for simplicity which should not be done in production. - dotenvy::dotenv().ok(); - std::env::var("NODE_URL").unwrap() - }); + let node_url = std::env::args() + .nth(1) + .unwrap_or_else(|| std::env::var("NODE_URL").unwrap()); - // Create a client with that node. + // Create a node client. let client = Client::builder() .with_node(&node_url)? .with_ignore_node_health() @@ -26,7 +30,7 @@ async fn main() -> Result<()> { // Get routes. let routes = client.get_routes().await?; - println!("{routes:#?}"); + println!("Routes:\n{routes:#?}"); Ok(()) } diff --git a/sdk/examples/client/node_api_core/03_get_tips.rs b/sdk/examples/client/node_api_core/03_get_tips.rs index e12744e590..11f2ecbc2e 100644 --- a/sdk/examples/client/node_api_core/03_get_tips.rs +++ b/sdk/examples/client/node_api_core/03_get_tips.rs @@ -1,28 +1,32 @@ // Copyright 2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -//! Returns tips that are ideal for attaching a block by calling `GET /api/core/v2/tips`. +//! Returns tips that are ideal for attaching a block by querying its `/api/core/v2/tips` endpoint. //! -//! `cargo run --example node_api_core_get_tips --release -- [NODE URL]` +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example node_api_core_get_tips [NODE URL] +//! ``` use iota_sdk::client::{Client, Result}; #[tokio::main] async fn main() -> Result<()> { + // If not provided we use the default node from the `.env` file. + dotenvy::dotenv().ok(); + // Take the node URL from command line argument or use one from env as default. - let node_url = std::env::args().nth(1).unwrap_or_else(|| { - // This example uses secrets in environment variables for simplicity which should not be done in production. - dotenvy::dotenv().ok(); - std::env::var("NODE_URL").unwrap() - }); + let node_url = std::env::args() + .nth(1) + .unwrap_or_else(|| std::env::var("NODE_URL").unwrap()); - // Create a client with that node. + // Create a node client. let client = Client::builder().with_node(&node_url)?.finish().await?; // Get tips. let tips = client.get_tips().await?; - println!("Tips: {tips:#?}"); + println!("Tips:\n{tips:#?}"); Ok(()) } diff --git a/sdk/examples/client/node_api_core/04_post_block.rs b/sdk/examples/client/node_api_core/04_post_block.rs index e6466e899f..19ea03c8ba 100644 --- a/sdk/examples/client/node_api_core/04_post_block.rs +++ b/sdk/examples/client/node_api_core/04_post_block.rs @@ -1,26 +1,31 @@ // Copyright 2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -//! Submits a block as a JSON payload by calling `POST /api/core/v2/blocks`. +//! Submits a block as a JSON payload using the `/api/core/v2/blocks` node endpoint. //! -//! `cargo run --example node_api_core_post_block --release -- [NODE URL]` +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example node_api_core_post_block [NODE URL] +//! ``` use iota_sdk::client::{Client, Result}; #[tokio::main] async fn main() -> Result<()> { + // If not provided we use the default node from the `.env` file. + dotenvy::dotenv().ok(); + // Take the node URL from command line argument or use one from env as default. - let node_url = std::env::args().nth(1).unwrap_or_else(|| { - // This example uses secrets in environment variables for simplicity which should not be done in production. - dotenvy::dotenv().ok(); - std::env::var("NODE_URL").unwrap() - }); + let node_url = std::env::args() + .nth(1) + .unwrap_or_else(|| std::env::var("NODE_URL").unwrap()); - // Create a client with that node. + // Create a node client. let client = Client::builder().with_node(&node_url)?.finish().await?; // Create the block. let block = client.block().finish().await?; + // Post the block. let block_id = client.post_block(&block).await?; diff --git a/sdk/examples/client/node_api_core/05_post_block_raw.rs b/sdk/examples/client/node_api_core/05_post_block_raw.rs index 99f3ed160f..1bca619812 100644 --- a/sdk/examples/client/node_api_core/05_post_block_raw.rs +++ b/sdk/examples/client/node_api_core/05_post_block_raw.rs @@ -1,26 +1,31 @@ // Copyright 2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -//! Submits a block as raw bytes by calling `POST /api/core/v2/blocks`. +//! Submits a block as raw bytes using the `/api/core/v2/blocks` node endpoint. //! -//! `cargo run --example node_api_core_post_block_raw --release -- [NODE URL]` +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example node_api_core_post_block_raw [NODE URL] +//! ``` use iota_sdk::client::{Client, Result}; #[tokio::main] async fn main() -> Result<()> { + // If not provided we use the default node from the `.env` file. + dotenvy::dotenv().ok(); + // Take the node URL from command line argument or use one from env as default. - let node_url = std::env::args().nth(1).unwrap_or_else(|| { - // This example uses secrets in environment variables for simplicity which should not be done in production. - dotenvy::dotenv().ok(); - std::env::var("NODE_URL").unwrap() - }); + let node_url = std::env::args() + .nth(1) + .unwrap_or_else(|| std::env::var("NODE_URL").unwrap()); - // Create a client with that node. + // Create a node client. let client = Client::builder().with_node(&node_url)?.finish().await?; // Create the block. let block = client.block().finish().await?; + // Post the block as raw bytes. let block_id = client.post_block_raw(&block).await?; diff --git a/sdk/examples/client/node_api_core/06_get_block.rs b/sdk/examples/client/node_api_core/06_get_block.rs index 45fd9a78a5..c61c4aa4cd 100644 --- a/sdk/examples/client/node_api_core/06_get_block.rs +++ b/sdk/examples/client/node_api_core/06_get_block.rs @@ -1,31 +1,30 @@ // Copyright 2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -//! Returns block data as JSON by its identifier by calling `GET /api/core/v2/blocks/{blockId}`. +//! Returns block data as JSON by its identifier by querying the `/api/core/v2/blocks/{blockId}` node endpoint. //! -//! `cargo run --example node_api_core_get_block --release -- [NODE URL] [BLOCK ID]` +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example node_api_core_get_block [BLOCK ID] [NODE URL] +//! ``` -use std::str::FromStr; - -use iota_sdk::{ - client::{Client, Result}, - types::block::BlockId, -}; +use iota_sdk::client::{Client, Result}; #[tokio::main] async fn main() -> Result<()> { + // If not provided we use the default node from the `.env` file. + dotenvy::dotenv().ok(); + // Take the node URL from command line argument or use one from env as default. - let node_url = std::env::args().nth(1).unwrap_or_else(|| { - // This example uses secrets in environment variables for simplicity which should not be done in production. - dotenvy::dotenv().ok(); - std::env::var("NODE_URL").unwrap() - }); + let node_url = std::env::args() + .nth(2) + .unwrap_or_else(|| std::env::var("NODE_URL").unwrap()); - // Create a client with that node. + // Create a node client. let client = Client::builder().with_node(&node_url)?.finish().await?; // Take the block ID from command line argument or... - let block_id = if let Some(Ok(block_id)) = std::env::args().nth(2).map(|s| BlockId::from_str(&s)) { + let block_id = if let Some(Ok(block_id)) = std::env::args().nth(1).map(|s| s.parse()) { block_id } else { // ... fetch one from the node. diff --git a/sdk/examples/client/node_api_core/07_get_block_raw.rs b/sdk/examples/client/node_api_core/07_get_block_raw.rs index f8c6ba486e..5a9bc10fa3 100644 --- a/sdk/examples/client/node_api_core/07_get_block_raw.rs +++ b/sdk/examples/client/node_api_core/07_get_block_raw.rs @@ -1,31 +1,30 @@ // Copyright 2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -//! Returns block data as raw bytes by its identifier by calling `GET /api/core/v2/blocks/{blockId}`. +//! Returns block data as raw bytes by its identifier by querying the `/api/core/v2/blocks/{blockId}` node endpoint. //! -//! `cargo run --example node_api_core_get_block_raw --release -- [NODE URL] [BLOCK ID]` +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example node_api_core_get_block_raw [BLOCK ID] [NODE URL] +//! ``` -use std::str::FromStr; - -use iota_sdk::{ - client::{Client, Result}, - types::block::BlockId, -}; +use iota_sdk::client::{Client, Result}; #[tokio::main] async fn main() -> Result<()> { + // If not provided we use the default node from the `.env` file. + dotenvy::dotenv().ok(); + // Take the node URL from command line argument or use one from env as default. - let node_url = std::env::args().nth(1).unwrap_or_else(|| { - // This example uses secrets in environment variables for simplicity which should not be done in production. - dotenvy::dotenv().ok(); - std::env::var("NODE_URL").unwrap() - }); + let node_url = std::env::args() + .nth(2) + .unwrap_or_else(|| std::env::var("NODE_URL").unwrap()); - // Create a client with that node. + // Create a node client. let client = Client::builder().with_node(&node_url)?.finish().await?; // Take the block ID from command line argument or... - let block_id = if let Some(Ok(block_id)) = std::env::args().nth(2).map(|s| BlockId::from_str(&s)) { + let block_id = if let Some(Ok(block_id)) = std::env::args().nth(1).map(|s| s.parse()) { block_id } else { // ... fetch one from the node. @@ -35,7 +34,7 @@ async fn main() -> Result<()> { // Get the block as raw bytes. let block_bytes = client.get_block_raw(&block_id).await?; - println!("Block bytes: {block_bytes:?}"); + println!("Block bytes:\n{block_bytes:?}"); Ok(()) } diff --git a/sdk/examples/client/node_api_core/08_get_block_metadata.rs b/sdk/examples/client/node_api_core/08_get_block_metadata.rs index 217d680817..1c507015e2 100644 --- a/sdk/examples/client/node_api_core/08_get_block_metadata.rs +++ b/sdk/examples/client/node_api_core/08_get_block_metadata.rs @@ -1,26 +1,36 @@ // Copyright 2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -//! Finds the metadata of a given block by calling `GET /api/core/v2/blocks/{blockId}/metadata`. +//! Finds the metadata of a given block by querying the `/api/core/v2/blocks/{blockId}/metadata` node endpoint. //! -//! `cargo run --example node_api_core_get_block_metadata --release -- [NODE URL]` +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example node_api_core_get_block_metadata [BLOCK ID] [NODE URL] +//! ``` use iota_sdk::client::{Client, Result}; #[tokio::main] async fn main() -> Result<()> { + // If not provided we use the default node from the `.env` file. + dotenvy::dotenv().ok(); + // Take the node URL from command line argument or use one from env as default. - let node_url = std::env::args().nth(1).unwrap_or_else(|| { - // This example uses secrets in environment variables for simplicity which should not be done in production. - dotenvy::dotenv().ok(); - std::env::var("NODE_URL").unwrap() - }); + let node_url = std::env::args() + .nth(2) + .unwrap_or_else(|| std::env::var("NODE_URL").unwrap()); - // Create a client with that node. + // Create a node client. let client = Client::builder().with_node(&node_url)?.finish().await?; - // Fetch a block ID from the node. - let block_id = client.get_tips().await?[0]; + // Take the block ID from command line argument or... + let block_id = if let Some(Ok(block_id)) = std::env::args().nth(1).map(|s| s.parse()) { + block_id + } else { + // ... fetch one from the node. + client.get_tips().await?[0] + }; + // Send the request. let block_metadata = client.get_block_metadata(&block_id).await?; diff --git a/sdk/examples/client/node_api_core/09_get_output.rs b/sdk/examples/client/node_api_core/09_get_output.rs index 4ecf274d96..b3ce27baef 100644 --- a/sdk/examples/client/node_api_core/09_get_output.rs +++ b/sdk/examples/client/node_api_core/09_get_output.rs @@ -1,11 +1,14 @@ // Copyright 2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -//! Find an output, as JSON, by its identifier by calling `GET /api/core/v2/outputs/{outputId}`. +//! Find an output, as JSON, by its identifier by querying the `/api/core/v2/outputs/{outputId}` node endpoint. //! -//! `cargo run --example node_api_core_get_output --release -- [NODE URL] [OUTPUT ID]` - -use std::str::FromStr; +//! Make sure to provide a somewhat recent output id to make this example run successfully! +//! +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example node_api_core_get_output [NODE URL] +//! ``` use iota_sdk::{ client::{Client, Result}, @@ -14,21 +17,22 @@ use iota_sdk::{ #[tokio::main] async fn main() -> Result<()> { + // If not provided we use the default node from the `.env` file. + dotenvy::dotenv().ok(); + // Take the node URL from command line argument or use one from env as default. - let node_url = std::env::args().nth(1).unwrap_or_else(|| { - // This example uses secrets in environment variables for simplicity which should not be done in production. - dotenvy::dotenv().ok(); - std::env::var("NODE_URL").unwrap() - }); + let node_url = std::env::args() + .nth(2) + .unwrap_or_else(|| std::env::var("NODE_URL").unwrap()); - // Create a client with that node. + // Create a node client. let client = Client::builder().with_node(&node_url)?.finish().await?; - // Take the output ID from command line argument or use a default one. - let output_id = - OutputId::from_str(&std::env::args().nth(2).unwrap_or_else(|| { - String::from("0xb66fd384cb5755668f1890ea2e41d699db9cf32f3bc422ad3c24ffeb9c7f01d00000") - }))?; + // Take the output id from the command line, or panic. + let output_id = std::env::args() + .nth(1) + .expect("missing example argument: OUTPUT ID") + .parse::()?; // Get the output. let output = client.get_output(&output_id).await?; diff --git a/sdk/examples/client/node_api_core/10_get_output_raw.rs b/sdk/examples/client/node_api_core/10_get_output_raw.rs index 7a9ead5c17..bd553a7e44 100644 --- a/sdk/examples/client/node_api_core/10_get_output_raw.rs +++ b/sdk/examples/client/node_api_core/10_get_output_raw.rs @@ -1,11 +1,14 @@ // Copyright 2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -//! Find an output, as raw bytes, by its identifier by calling `GET /api/core/v2/outputs/{outputId}`. +//! Find an output, as raw bytes, by its identifier by querying the `/api/core/v2/outputs/{outputId}` node endpoint. //! -//! `cargo run --example node_api_core_get_output_raw --release -- [NODE URL] [OUTPUT ID]` - -use std::str::FromStr; +//! Make sure to provide a somewhat recent output id to make this example run successfully! +//! +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example node_api_core_get_output_raw [NODE URL] +//! ``` use iota_sdk::{ client::{Client, Result}, @@ -14,26 +17,27 @@ use iota_sdk::{ #[tokio::main] async fn main() -> Result<()> { + // If not provided we use the default node from the `.env` file. + dotenvy::dotenv().ok(); + // Take the node URL from command line argument or use one from env as default. - let node_url = std::env::args().nth(1).unwrap_or_else(|| { - // This example uses secrets in environment variables for simplicity which should not be done in production. - dotenvy::dotenv().ok(); - std::env::var("NODE_URL").unwrap() - }); + let node_url = std::env::args() + .nth(2) + .unwrap_or_else(|| std::env::var("NODE_URL").unwrap()); - // Create a client with that node. + // Create a node client. let client = Client::builder().with_node(&node_url)?.finish().await?; - // Take the output ID from command line argument or use a default one. - let output_id = - OutputId::from_str(&std::env::args().nth(2).unwrap_or_else(|| { - String::from("0xb66fd384cb5755668f1890ea2e41d699db9cf32f3bc422ad3c24ffeb9c7f01d00000") - }))?; + // Take the output id from the command line, or panic. + let output_id = std::env::args() + .nth(1) + .expect("missing example argument: OUTPUT ID") + .parse::()?; // Get the output as raw bytes. let output_bytes = client.get_output_raw(&output_id).await?; - println!("Output bytes: {output_bytes:?}"); + println!("Output bytes:\n{output_bytes:?}"); Ok(()) } diff --git a/sdk/examples/client/node_api_core/11_get_output_metadata.rs b/sdk/examples/client/node_api_core/11_get_output_metadata.rs index c93c9ff874..3bc469a09c 100644 --- a/sdk/examples/client/node_api_core/11_get_output_metadata.rs +++ b/sdk/examples/client/node_api_core/11_get_output_metadata.rs @@ -1,11 +1,14 @@ // Copyright 2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -//! Returns metadata about an output by its identifier by calling `GET /api/core/v2/outputs/{outputId}`. +//! Returns metadata about an output by its identifier by querying the `/api/core/v2/outputs/{outputId}` node endpoint. //! -//! `cargo run --example node_api_core_get_output_metadata --release -- [NODE URL] [OUTPUT ID]` - -use std::str::FromStr; +//! Make sure to provide a somewhat recent output id to make this example run successfully! +//! +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example node_api_core_get_output_metadata [NODE URL] +//! ``` use iota_sdk::{ client::{Client, Result}, @@ -14,21 +17,22 @@ use iota_sdk::{ #[tokio::main] async fn main() -> Result<()> { + // If not provided we use the default node from the `.env` file. + dotenvy::dotenv().ok(); + // Take the node URL from command line argument or use one from env as default. - let node_url = std::env::args().nth(1).unwrap_or_else(|| { - // This example uses secrets in environment variables for simplicity which should not be done in production. - dotenvy::dotenv().ok(); - std::env::var("NODE_URL").unwrap() - }); + let node_url = std::env::args() + .nth(2) + .unwrap_or_else(|| std::env::var("NODE_URL").unwrap()); - // Create a client with that node. + // Create a node client. let client = Client::builder().with_node(&node_url)?.finish().await?; - // Take the output ID from command line argument or use a default one. - let output_id = - OutputId::from_str(&std::env::args().nth(2).unwrap_or_else(|| { - String::from("0xb66fd384cb5755668f1890ea2e41d699db9cf32f3bc422ad3c24ffeb9c7f01d00000") - }))?; + // Take the output id from the command line, or panic. + let output_id = std::env::args() + .nth(1) + .expect("missing example argument: OUTPUT ID") + .parse::()?; // Get the output metadata. let output_metadata = client.get_output_metadata(&output_id).await?; diff --git a/sdk/examples/client/node_api_core/12_get_receipts.rs b/sdk/examples/client/node_api_core/12_get_receipts.rs index c2461d5d98..b3c9a93f0c 100644 --- a/sdk/examples/client/node_api_core/12_get_receipts.rs +++ b/sdk/examples/client/node_api_core/12_get_receipts.rs @@ -1,28 +1,32 @@ // Copyright 2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -//! Returns all stored receipts by calling `GET /api/core/v2/receipts`. +//! Returns all stored receipts by querying the `/api/core/v2/receipts` node endpoint. //! -//! `cargo run --example node_api_core_get_receipts --release -- [NODE URL]` +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example node_api_core_get_receipts [NODE URL] +//! ``` use iota_sdk::client::{Client, Result}; #[tokio::main] async fn main() -> Result<()> { + // If not provided we use the default node from the `.env` file. + dotenvy::dotenv().ok(); + // Take the node URL from command line argument or use one from env as default. - let node_url = std::env::args().nth(1).unwrap_or_else(|| { - // This example uses secrets in environment variables for simplicity which should not be done in production. - dotenvy::dotenv().ok(); - std::env::var("NODE_URL").unwrap() - }); + let node_url = std::env::args() + .nth(1) + .unwrap_or_else(|| std::env::var("NODE_URL").unwrap()); - // Create a client with that node. + // Create a node client. let client = Client::builder().with_node(&node_url)?.finish().await?; // Send the request. let receipts = client.get_receipts().await?; - println!("{receipts:#?}"); + println!("Receipts:\n{receipts:#?}"); Ok(()) } diff --git a/sdk/examples/client/node_api_core/13_get_receipts_migrated_at.rs b/sdk/examples/client/node_api_core/13_get_receipts_migrated_at.rs index 3a1f85af23..6285236b96 100644 --- a/sdk/examples/client/node_api_core/13_get_receipts_migrated_at.rs +++ b/sdk/examples/client/node_api_core/13_get_receipts_migrated_at.rs @@ -1,28 +1,40 @@ // Copyright 2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -//! Returns all stored receipts for a given migration index by calling `GET /api/core/v2/receipts/{migratedAt}`. +//! Returns all stored receipts for a given migration index by querying the `/api/core/v2/receipts/{migratedAt}` node +//! endpoint. //! -//! `cargo run --example node_api_core_get_receipts_migrated_at --release -- [NODE URL]` +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example node_api_core_get_receipts_migrated_at [MILESTONE_INDEX] [NODE URL] +//! ``` use iota_sdk::client::{Client, Result}; #[tokio::main] async fn main() -> Result<()> { + // If not provided we use the default node from the `.env` file. + dotenvy::dotenv().ok(); + // Take the node URL from command line argument or use one from env as default. - let node_url = std::env::args().nth(1).unwrap_or_else(|| { - // This example uses secrets in environment variables for simplicity which should not be done in production. - dotenvy::dotenv().ok(); - std::env::var("NODE_URL").unwrap() - }); + let node_url = std::env::args() + .nth(2) + .unwrap_or_else(|| std::env::var("NODE_URL").unwrap()); - // Create a client with that node. + // Create a node client. let client = Client::builder().with_node(&node_url)?.finish().await?; + // Take the milestone index from the command line, or use a default. + let milestone_index = if let Some(s) = std::env::args().nth(1) { + s.parse().expect("invalid milestone index") + } else { + client.get_info().await?.node_info.status.latest_milestone.index + }; + // Send the request. - let receipts = client.get_receipts_migrated_at(1_000_000).await?; + let receipts = client.get_receipts_migrated_at(milestone_index).await?; - println!("{receipts:#?}"); + println!("Receipts:\n{receipts:#?}"); Ok(()) } diff --git a/sdk/examples/client/node_api_core/14_get_treasury.rs b/sdk/examples/client/node_api_core/14_get_treasury.rs index e88dcdd371..1d8cdd480e 100644 --- a/sdk/examples/client/node_api_core/14_get_treasury.rs +++ b/sdk/examples/client/node_api_core/14_get_treasury.rs @@ -1,22 +1,26 @@ // Copyright 2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -//! Returns information about the treasury by calling `GET /api/core/v2/treasury`. +//! Returns information about the treasury by querying the `/api/core/v2/treasury` node endpoint. //! -//! `cargo run --example node_api_core_get_treasury --release -- [NODE URL]` +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example node_api_core_get_treasury [NODE URL] +//! ``` use iota_sdk::client::{Client, Result}; #[tokio::main] async fn main() -> Result<()> { + // If not provided we use the default node from the `.env` file. + dotenvy::dotenv().ok(); + // Take the node URL from command line argument or use one from env as default. - let node_url = std::env::args().nth(1).unwrap_or_else(|| { - // This example uses secrets in environment variables for simplicity which should not be done in production. - dotenvy::dotenv().ok(); - std::env::var("NODE_URL").unwrap() - }); + let node_url = std::env::args() + .nth(1) + .unwrap_or_else(|| std::env::var("NODE_URL").unwrap()); - // Create a client with that node. + // Create a node client. let client = Client::builder().with_node(&node_url)?.finish().await?; // Send the request. diff --git a/sdk/examples/client/node_api_core/15_get_included_block.rs b/sdk/examples/client/node_api_core/15_get_included_block.rs index 086a0a5e32..1ae2efde40 100644 --- a/sdk/examples/client/node_api_core/15_get_included_block.rs +++ b/sdk/examples/client/node_api_core/15_get_included_block.rs @@ -1,32 +1,37 @@ // Copyright 2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -//! Returns the included block, as JSON, of a transaction by calling -//! `GET /api/core/v2/transactions/{transactionId}/included-block`. +//! Returns the included block, as JSON, of a transaction by querying the +//! `/api/core/v2/transactions/{transactionId}/included-block` node endpoint. //! -//! `cargo run --example node_api_core_get_included_block --release -- [NODE URL]` - -use std::str::FromStr; +//! Make sure to provide a somewhat recent transaction id to make this example run successfully! +//! +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example node_api_core_get_included_block [NODE URL] +//! ``` -use iota_sdk::{ - client::{Client, Result}, - types::block::payload::transaction::TransactionId, -}; +use iota_sdk::client::{Client, Result}; #[tokio::main] async fn main() -> Result<()> { + // If not provided we use the default node from the `.env` file. + dotenvy::dotenv().ok(); + // Take the node URL from command line argument or use one from env as default. - let node_url = std::env::args().nth(1).unwrap_or_else(|| { - // This example uses secrets in environment variables for simplicity which should not be done in production. - dotenvy::dotenv().ok(); - std::env::var("NODE_URL").unwrap() - }); + let node_url = std::env::args() + .nth(2) + .unwrap_or_else(|| std::env::var("NODE_URL").expect("NODE_URL not set")); - // Create a client with that node. + // Create a node client. let client = Client::builder().with_node(&node_url)?.finish().await?; - // Transactions get pruned from the node after some time, replace with a new TransactionId. - let transaction_id = TransactionId::from_str("0xb66fd384cb5755668f1890ea2e41d699db9cf32f3bc422ad3c24ffeb9c7f01d0")?; + // Take the transaction id from the command line, or panic. + let transaction_id = std::env::args() + .nth(1) + .expect("missing example argument: TRANSACTION ID") + .parse()?; + // Send the request. let block = client.get_included_block(&transaction_id).await?; diff --git a/sdk/examples/client/node_api_core/16_get_included_block_raw.rs b/sdk/examples/client/node_api_core/16_get_included_block_raw.rs index baa3cd25a8..b49dd88a18 100644 --- a/sdk/examples/client/node_api_core/16_get_included_block_raw.rs +++ b/sdk/examples/client/node_api_core/16_get_included_block_raw.rs @@ -1,32 +1,37 @@ // Copyright 2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -//! Returns the included block, as raw bytes, of a transaction by calling -//! `GET /api/core/v2/transactions/{transactionId}/included-block`. +//! Returns the included block, as raw bytes, of a transaction by querying the +//! `/api/core/v2/transactions/{transactionId}/included-block` node endpoint. //! -//! `cargo run --example node_api_core_get_included_block_raw --release -- [NODE URL]` - -use std::str::FromStr; +//! Make sure to provide a somewhat recent transaction id to make this example run successfully! +//! +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example node_api_core_get_included_block_raw [NODE URL] +//! ``` -use iota_sdk::{ - client::{Client, Result}, - types::block::payload::transaction::TransactionId, -}; +use iota_sdk::client::{Client, Result}; #[tokio::main] async fn main() -> Result<()> { + // If not provided we use the default node from the `.env` file. + dotenvy::dotenv().ok(); + // Take the node URL from command line argument or use one from env as default. - let node_url = std::env::args().nth(1).unwrap_or_else(|| { - // This example uses secrets in environment variables for simplicity which should not be done in production. - dotenvy::dotenv().ok(); - std::env::var("NODE_URL").unwrap() - }); + let node_url = std::env::args() + .nth(2) + .unwrap_or_else(|| std::env::var("NODE_URL").expect("NODE_URL not set")); - // Create a client with that node. + // Create a node client. let client = Client::builder().with_node(&node_url)?.finish().await?; - // Transactions get pruned from the node after some time, replace with a new TransactionId. - let transaction_id = TransactionId::from_str("0xb66fd384cb5755668f1890ea2e41d699db9cf32f3bc422ad3c24ffeb9c7f01d0")?; + // Take the transaction id from the command line, or panic. + let transaction_id = std::env::args() + .nth(1) + .expect("missing example argument: TRANSACTION ID") + .parse()?; + // Send the request. let block_bytes = client.get_included_block_raw(&transaction_id).await?; diff --git a/sdk/examples/client/node_api_core/17_get_milestone_by_id.rs b/sdk/examples/client/node_api_core/17_get_milestone_by_id.rs index e8edfef620..fb5bf58afe 100644 --- a/sdk/examples/client/node_api_core/17_get_milestone_by_id.rs +++ b/sdk/examples/client/node_api_core/17_get_milestone_by_id.rs @@ -1,28 +1,46 @@ // Copyright 2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -//! Returns milestone data as JSON by its identifier by calling -//! `GET /api/core/v2/milestones/{milestoneId}`. +//! Returns milestone data as JSON by its identifier by querying the +//! `/api/core/v2/milestones/{milestoneId}` node endpoint. //! -//! `cargo run --example node_api_core_get_milestone_by_id --release -- [NODE URL]` +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example node_api_core_get_milestone_by_id [MILESTONE ID] [NODE URL]` +//! ``` -use iota_sdk::client::{Client, Result}; +use iota_sdk::{ + client::{Client, Result}, + types::block::payload::milestone::MilestoneId, +}; #[tokio::main] async fn main() -> Result<()> { + // If not provided we use the default node from the `.env` file. + dotenvy::dotenv().ok(); + // Take the node URL from command line argument or use one from env as default. - let node_url = std::env::args().nth(1).unwrap_or_else(|| { - // This example uses secrets in environment variables for simplicity which should not be done in production. - dotenvy::dotenv().ok(); - std::env::var("NODE_URL").unwrap() - }); + let node_url = std::env::args() + .nth(2) + .unwrap_or_else(|| std::env::var("NODE_URL").unwrap()); - // Create a client with that node. + // Create a node client. let client = Client::builder().with_node(&node_url)?.finish().await?; - // Fetch the latest milestone ID from the node. - let info = client.get_info().await?; - let milestone_id = info.node_info.status.latest_milestone.milestone_id.unwrap(); + // Take the milestone id from the command line, or use a default. + let milestone_id = if let Some(s) = std::env::args().nth(1) { + s.parse::().expect("invalid milestone id") + } else { + client + .get_info() + .await? + .node_info + .status + .latest_milestone + .milestone_id + .unwrap() + }; + // Send the request. let milestone = client.get_milestone_by_id(&milestone_id).await?; diff --git a/sdk/examples/client/node_api_core/18_get_milestone_by_id_raw.rs b/sdk/examples/client/node_api_core/18_get_milestone_by_id_raw.rs index 2c14713797..e21c4be4ba 100644 --- a/sdk/examples/client/node_api_core/18_get_milestone_by_id_raw.rs +++ b/sdk/examples/client/node_api_core/18_get_milestone_by_id_raw.rs @@ -1,32 +1,50 @@ // Copyright 2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -//! Returns milestone data as raw bytes by its identifier by calling -//! `GET /api/core/v2/milestones/{milestoneId}`. +//! Returns milestone data as raw bytes by its identifier by querying the +//! `/api/core/v2/milestones/{milestoneId}` node endpoint. //! -//! `cargo run --example node_api_core_get_milestone_by_id_raw --release -- [NODE URL]` +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example node_api_core_get_milestone_by_id_raw [MILESTONE ID] [NODE URL]` +//! ``` -use iota_sdk::client::{Client, Result}; +use iota_sdk::{ + client::{Client, Result}, + types::block::payload::milestone::MilestoneId, +}; #[tokio::main] async fn main() -> Result<()> { + // If not provided we use the default node from the `.env` file. + dotenvy::dotenv().ok(); + // Take the node URL from command line argument or use one from env as default. - let node_url = std::env::args().nth(1).unwrap_or_else(|| { - // This example uses secrets in environment variables for simplicity which should not be done in production. - dotenvy::dotenv().ok(); - std::env::var("NODE_URL").unwrap() - }); + let node_url = std::env::args() + .nth(2) + .unwrap_or_else(|| std::env::var("NODE_URL").unwrap()); - // Create a client with that node. + // Create a node client. let client = Client::builder().with_node(&node_url)?.finish().await?; - // Fetch the latest milestone ID from the node. - let info = client.get_info().await?; - let milestone_id = info.node_info.status.latest_milestone.milestone_id.unwrap(); + // Take the milestone id from the command line, or use a default. + let milestone_id = if let Some(s) = std::env::args().nth(1) { + s.parse::().expect("invalid milestone id") + } else { + client + .get_info() + .await? + .node_info + .status + .latest_milestone + .milestone_id + .unwrap() + }; + // Send the request. let milestone = client.get_milestone_by_id_raw(&milestone_id).await?; - println!("{milestone:?}"); + println!("{milestone:#?}"); Ok(()) } diff --git a/sdk/examples/client/node_api_core/19_get_utxo_changes_by_id.rs b/sdk/examples/client/node_api_core/19_get_utxo_changes_by_id.rs index ea7411086f..61dc28920f 100644 --- a/sdk/examples/client/node_api_core/19_get_utxo_changes_by_id.rs +++ b/sdk/examples/client/node_api_core/19_get_utxo_changes_by_id.rs @@ -1,28 +1,46 @@ // Copyright 2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -//! Gets all UTXO changes of a given milestone by milestone identifier by calling -//! `GET /api/core/v2/milestones/{milestoneId}/utxo-changes`. +//! Gets all UTXO changes of a given milestone by milestone identifier by querying the +//! `/api/core/v2/milestones/{milestoneId}/utxo-changes` node endpoint. //! -//! `cargo run --example node_api_core_get_utxo_changes_by_id --release -- [NODE URL]` +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example node_api_core_get_utxo_changes_by_id [MILESTONE ID] [NODE URL] +//! ``` -use iota_sdk::client::{Client, Result}; +use iota_sdk::{ + client::{Client, Result}, + types::block::payload::milestone::MilestoneId, +}; #[tokio::main] async fn main() -> Result<()> { + // If not provided we use the default node from the `.env` file. + dotenvy::dotenv().ok(); + // Take the node URL from command line argument or use one from env as default. - let node_url = std::env::args().nth(1).unwrap_or_else(|| { - // This example uses secrets in environment variables for simplicity which should not be done in production. - dotenvy::dotenv().ok(); - std::env::var("NODE_URL").unwrap() - }); + let node_url = std::env::args() + .nth(2) + .unwrap_or_else(|| std::env::var("NODE_URL").unwrap()); - // Create a client with that node. + // Create a node client. let client = Client::builder().with_node(&node_url)?.finish().await?; - // Fetch the latest milestone ID from the node. - let info = client.get_info().await?; - let milestone_id = info.node_info.status.latest_milestone.milestone_id.unwrap(); + // Take the milestone id from the command line, or use a default. + let milestone_id = if let Some(s) = std::env::args().nth(1) { + s.parse::().expect("invalid milestone id") + } else { + client + .get_info() + .await? + .node_info + .status + .latest_milestone + .milestone_id + .unwrap() + }; + // Send the request. let utxo_changes = client.get_utxo_changes_by_id(&milestone_id).await?; diff --git a/sdk/examples/client/node_api_core/20_get_milestone_by_index.rs b/sdk/examples/client/node_api_core/20_get_milestone_by_index.rs index 6f54ef6443..fd8d7824f9 100644 --- a/sdk/examples/client/node_api_core/20_get_milestone_by_index.rs +++ b/sdk/examples/client/node_api_core/20_get_milestone_by_index.rs @@ -1,28 +1,36 @@ // Copyright 2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -//! Returns milestone data as JSON by its index by calling -//! `GET /api/core/v2/milestones/by-index/{index}`. +//! Returns milestone data as JSON by its index by querying the +//! `/api/core/v2/milestones/by-index/{index}` node endpoint. //! -//! `cargo run --example node_api_core_get_milestone_by_index --release -- [NODE URL]` +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example node_api_core_get_milestone_by_index [MILESTONE INDEX] [NODE URL] +//! ``` use iota_sdk::client::{Client, Result}; #[tokio::main] async fn main() -> Result<()> { + // If not provided we use the default node from the `.env` file. + dotenvy::dotenv().ok(); + // Take the node URL from command line argument or use one from env as default. - let node_url = std::env::args().nth(1).unwrap_or_else(|| { - // This example uses secrets in environment variables for simplicity which should not be done in production. - dotenvy::dotenv().ok(); - std::env::var("NODE_URL").unwrap() - }); + let node_url = std::env::args() + .nth(2) + .unwrap_or_else(|| std::env::var("NODE_URL").unwrap()); - // Create a client with that node. + // Create a node client. let client = Client::builder().with_node(&node_url)?.finish().await?; - // Fetch the latest milestone index from the node. - let info = client.get_info().await?; - let milestone_index = info.node_info.status.latest_milestone.index; + // Take the milestone index from the command line, or use a default. + let milestone_index = if let Some(s) = std::env::args().nth(1) { + s.parse().expect("invalid milestone index") + } else { + client.get_info().await?.node_info.status.latest_milestone.index + }; + // Send the request. let milestone = client.get_milestone_by_index(milestone_index).await?; diff --git a/sdk/examples/client/node_api_core/21_get_milestone_by_index_raw.rs b/sdk/examples/client/node_api_core/21_get_milestone_by_index_raw.rs index 2a4b461c53..7ae7c47b4e 100644 --- a/sdk/examples/client/node_api_core/21_get_milestone_by_index_raw.rs +++ b/sdk/examples/client/node_api_core/21_get_milestone_by_index_raw.rs @@ -1,32 +1,40 @@ // Copyright 2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -//! Returns milestone data as raw bytes by its index by calling -//! `GET /api/core/v2/milestones/by-index/{index}`. +//! Returns milestone data as raw bytes by its index by querying the +//! `/api/core/v2/milestones/by-index/{index}` node endpoint. //! -//! `cargo run --example node_api_core_get_milestone_by_index_raw --release -- [NODE URL]` +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example node_api_core_get_milestone_by_index_raw [MILESTONE INDEX] [NODE URL] +//! ``` use iota_sdk::client::{Client, Result}; #[tokio::main] async fn main() -> Result<()> { + // If not provided we use the default node from the `.env` file. + dotenvy::dotenv().ok(); + // Take the node URL from command line argument or use one from env as default. - let node_url = std::env::args().nth(1).unwrap_or_else(|| { - // This example uses secrets in environment variables for simplicity which should not be done in production. - dotenvy::dotenv().ok(); - std::env::var("NODE_URL").unwrap() - }); + let node_url = std::env::args() + .nth(2) + .unwrap_or_else(|| std::env::var("NODE_URL").unwrap()); - // Create a client with that node. + // Create a node client. let client = Client::builder().with_node(&node_url)?.finish().await?; - // Fetch the latest milestone index from the node. - let info = client.get_info().await?; - let milestone_index = info.node_info.status.latest_milestone.index; + // Take the milestone index from the command line, or use a default. + let milestone_index = if let Some(s) = std::env::args().nth(1) { + s.parse().expect("invalid milestone index") + } else { + client.get_info().await?.node_info.status.latest_milestone.index + }; + // Send the request. let milestone = client.get_milestone_by_index_raw(milestone_index).await?; - println!("{milestone:?}"); + println!("{milestone:#?}"); Ok(()) } diff --git a/sdk/examples/client/node_api_core/22_get_utxo_changes_by_index.rs b/sdk/examples/client/node_api_core/22_get_utxo_changes_by_index.rs index 910c484ea4..4bb0c8c679 100644 --- a/sdk/examples/client/node_api_core/22_get_utxo_changes_by_index.rs +++ b/sdk/examples/client/node_api_core/22_get_utxo_changes_by_index.rs @@ -1,28 +1,36 @@ // Copyright 2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -//! Gets all UTXO changes of a given milestone by milestone index by calling -//! `GET /api/core/v2/milestones/by-index/{index}/utxo-changes`. +//! Gets all UTXO changes of a given milestone by milestone index by querying the +//! `/api/core/v2/milestones/by-index/{index}/utxo-changes` node endpoint. //! -//! `cargo run --example node_api_core_get_utxo_changes_by_index --release -- [NODE URL]` +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example node_api_core_get_utxo_changes_by_index [MILESTONE INDEX] [NODE URL] +//! ``` use iota_sdk::client::{Client, Result}; #[tokio::main] async fn main() -> Result<()> { + // If not provided we use the default node from the `.env` file. + dotenvy::dotenv().ok(); + // Take the node URL from command line argument or use one from env as default. - let node_url = std::env::args().nth(1).unwrap_or_else(|| { - // This example uses secrets in environment variables for simplicity which should not be done in production. - dotenvy::dotenv().ok(); - std::env::var("NODE_URL").unwrap() - }); + let node_url = std::env::args() + .nth(2) + .unwrap_or_else(|| std::env::var("NODE_URL").unwrap()); - // Create a client with that node. + // Create a node client. let client = Client::builder().with_node(&node_url)?.finish().await?; - // Fetch the latest milestone index from the node. - let info = client.get_info().await?; - let milestone_index = info.node_info.status.latest_milestone.index; + // Take the milestone index from the command line, or use a default. + let milestone_index = if let Some(s) = std::env::args().nth(1) { + s.parse().expect("invalid milestone index") + } else { + client.get_info().await?.node_info.status.latest_milestone.index + }; + // Send the request. let utxo_changes = client.get_utxo_changes_by_index(milestone_index).await?; diff --git a/sdk/examples/client/node_api_indexer/01_get_alias_output.rs b/sdk/examples/client/node_api_indexer/01_get_alias_output.rs index 59a3a3cd3e..9013f5ced2 100644 --- a/sdk/examples/client/node_api_indexer/01_get_alias_output.rs +++ b/sdk/examples/client/node_api_indexer/01_get_alias_output.rs @@ -1,12 +1,15 @@ // Copyright 2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -//! TODO: by calling -//! `GET api/indexer/v1/outputs/alias/{aliasId}`. +//! Gets the alias output from the corresponding alias id by querying the +//! `api/indexer/v1/outputs/alias/{aliasId}` node endpoint. //! -//! `cargo run --example node_api_indexer_get_alias_output --release -- [NODE URL] [ALIAS ID]` - -use std::str::FromStr; +//! Make sure that the node has the indexer plugin enabled. +//! +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example node_api_indexer_get_alias_output [NODE URL] +//! ``` use iota_sdk::{ client::{Client, Result}, @@ -15,28 +18,24 @@ use iota_sdk::{ #[tokio::main] async fn main() -> Result<()> { + // This example uses secrets in environment variables for simplicity which should not be done in production. + dotenvy::dotenv().ok(); + // Take the node URL from command line argument or use one from env as default. - let node_url = std::env::args().nth(1).unwrap_or_else(|| { - // This example uses secrets in environment variables for simplicity which should not be done in production. - dotenvy::dotenv().ok(); - std::env::var("NODE_URL").unwrap() - }); - - // Create a client with that node. - let client = Client::builder() - // The node needs to have the indexer plugin enabled. - .with_node(&node_url)? - .finish() - .await?; - - // Take the alias ID from command line argument or use a default one. - let alias_id = AliasId::from_str( - &std::env::args() - .nth(2) - .unwrap_or_else(|| String::from("0xdb4db7643d768139d6f8ac3f9c9b7a82a245b619fa9f7c18fcd8f0f67e57abc2")), - )?; - - // Get the output ID by the alias ID. + let node_url = std::env::args() + .nth(2) + .unwrap_or_else(|| std::env::var("NODE_URL").unwrap()); + + // Create a node client. + let client = Client::builder().with_node(&node_url)?.finish().await?; + + // Take the alias id from the command line, or panic. + let alias_id = std::env::args() + .nth(1) + .expect("missing example argument: ALIAS ID") + .parse::()?; + + // Get the output ID by providing the corresponding alias ID. let output_id = client.alias_output_id(alias_id).await?; println!("Alias output ID: {output_id}"); diff --git a/sdk/examples/client/node_api_indexer/02_get_alias_outputs.rs b/sdk/examples/client/node_api_indexer/02_get_alias_outputs.rs index 6273f9273a..8ecb7150ba 100644 --- a/sdk/examples/client/node_api_indexer/02_get_alias_outputs.rs +++ b/sdk/examples/client/node_api_indexer/02_get_alias_outputs.rs @@ -1,10 +1,15 @@ // Copyright 2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -//! TODO: by calling -//! `GET api/indexer/v1/outputs/alias`. +//! Gets all alias output ids accociated with an address by querying the +//! `api/indexer/v1/outputs/alias` node endpoint. //! -//! `cargo run --example node_api_indexer_get_alias_outputs --release -- [NODE URL] [ADDRESS]` +//! Make sure that the node has the indexer plugin enabled. +//! +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example node_api_indexer_get_alias_outputs
[NODE URL] +//! ``` use iota_sdk::{ client::{node_api::indexer::query_parameters::QueryParameter, Client, Result}, @@ -13,27 +18,26 @@ use iota_sdk::{ #[tokio::main] async fn main() -> Result<()> { + // This example uses secrets in environment variables for simplicity which should not be done in production. + dotenvy::dotenv().ok(); + // Take the node URL from command line argument or use one from env as default. - let node_url = std::env::args().nth(1).unwrap_or_else(|| { - // This example uses secrets in environment variables for simplicity which should not be done in production. - dotenvy::dotenv().ok(); - std::env::var("NODE_URL").unwrap() - }); + let node_url = std::env::args() + .nth(2) + .unwrap_or_else(|| std::env::var("NODE_URL").unwrap()); - // Create a client with that node. + // Create a node client. let client = Client::builder() // The node needs to have the indexer plugin enabled. .with_node(&node_url)? .finish() .await?; - // Take the address from command line argument or use a default one. - let address = Bech32Address::try_from_str( - std::env::args() - .nth(2) - .as_deref() - .unwrap_or("rms1qrrdjmdkadtcnuw0ue5n9g4fmkelrj3dl26eyeshkha3w3uu0wheu5z5qqz"), - )?; + // Take the address from the command line, or panic. + let address = std::env::args() + .nth(1) + .expect("missing example argument: ADDRESS") + .parse::()?; // Get output IDs of alias outputs that can be controlled by this address. let output_ids_response = client diff --git a/sdk/examples/client/node_api_indexer/03_get_foundry_output.rs b/sdk/examples/client/node_api_indexer/03_get_foundry_output.rs index e55bd0ffca..5006b35448 100644 --- a/sdk/examples/client/node_api_indexer/03_get_foundry_output.rs +++ b/sdk/examples/client/node_api_indexer/03_get_foundry_output.rs @@ -1,12 +1,15 @@ // Copyright 2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -//! TODO: by calling -//! `GET api/indexer/v1/outputs/foundry/{foundryId}`. +//! Gets the foundry output from the corresponding foundry id by querying the +//! `api/indexer/v1/outputs/foundry/{foundryId}` node endpoint. //! -//! `cargo run --example node_api_indexer_get_foundry_output --release -- [NODE URL] [FOUNDRY ID]` - -use std::str::FromStr; +//! Make sure that the node has the indexer plugin enabled. +//! +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example node_api_indexer_get_foundry_output [NODE URL] +//! ``` use iota_sdk::{ client::{Client, Result}, @@ -15,26 +18,24 @@ use iota_sdk::{ #[tokio::main] async fn main() -> Result<()> { + // This example uses secrets in environment variables for simplicity which should not be done in production. + dotenvy::dotenv().ok(); + // Take the node URL from command line argument or use one from env as default. - let node_url = std::env::args().nth(1).unwrap_or_else(|| { - // This example uses secrets in environment variables for simplicity which should not be done in production. - dotenvy::dotenv().ok(); - std::env::var("NODE_URL").unwrap() - }); - - // Create a client with that node. - let client = Client::builder() - // The node needs to have the indexer plugin enabled. - .with_node(&node_url)? - .finish() - .await?; - - // Take the foundry ID from command line argument or use a default one. - let foundry_id = FoundryId::from_str(&std::env::args().nth(2).unwrap_or_else(|| { - String::from("0x08db4db7643d768139d6f8ac3f9c9b7a82a245b619fa9f7c18fcd8f0f67e57abc20100000000") - }))?; - - // Get the output ID by the foundry ID. + let node_url = std::env::args() + .nth(2) + .unwrap_or_else(|| std::env::var("NODE_URL").unwrap()); + + // Create a node client. + let client = Client::builder().with_node(&node_url)?.finish().await?; + + // Take the foundry id from the command line, or panic. + let foundry_id = std::env::args() + .nth(1) + .expect("missing example argument: FOUNDRY ID") + .parse::()?; + + // Get the output ID by providing the corresponding foundry ID. let output_id = client.foundry_output_id(foundry_id).await?; println!("Foundry output ID: {output_id}"); diff --git a/sdk/examples/client/node_api_indexer/04_get_foundry_outputs.rs b/sdk/examples/client/node_api_indexer/04_get_foundry_outputs.rs index 1230255305..3b8f506495 100644 --- a/sdk/examples/client/node_api_indexer/04_get_foundry_outputs.rs +++ b/sdk/examples/client/node_api_indexer/04_get_foundry_outputs.rs @@ -1,10 +1,15 @@ // Copyright 2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -//! TODO: by calling -//! `GET api/indexer/v1/outputs/foundry`. +//! Gets all foundry output ids accociated with an alias address by querying the +//! `api/indexer/v1/outputs/foundry` node endpoint. //! -//! `cargo run --example node_api_indexer_get_foundry_outputs --release -- [NODE URL] [ADDRESS]` +//! Make sure that the node has the indexer plugin enabled. +//! +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example node_api_indexer_get_foundry_outputs
[NODE URL] +//! ``` use iota_sdk::{ client::{node_api::indexer::query_parameters::QueryParameter, Client, Result}, @@ -13,31 +18,30 @@ use iota_sdk::{ #[tokio::main] async fn main() -> Result<()> { + // This example uses secrets in environment variables for simplicity which should not be done in production. + dotenvy::dotenv().ok(); + // Take the node URL from command line argument or use one from env as default. - let node_url = std::env::args().nth(1).unwrap_or_else(|| { - // This example uses secrets in environment variables for simplicity which should not be done in production. - dotenvy::dotenv().ok(); - std::env::var("NODE_URL").unwrap() - }); + let node_url = std::env::args() + .nth(2) + .unwrap_or_else(|| std::env::var("NODE_URL").unwrap()); - // Create a client with that node. + // Create a node client. let client = Client::builder() // The node needs to have the indexer plugin enabled. .with_node(&node_url)? .finish() .await?; - // Take the address from command line argument or use a default one. - let alias_address = Bech32Address::try_from_str( - std::env::args() - .nth(2) - .as_deref() - .unwrap_or("rms1prd5mdmy84mgzwwklzkrl8ym02p2y3dkr8af7lqclnv0pan7274uyjrmwx5"), - )?; + // Take the address from the command line, or panic. + let address = std::env::args() + .nth(1) + .expect("missing example argument: ADDRESS") + .parse::()?; // Get output IDs of foundry outputs that can be controlled by this address. let output_ids_response = client - .foundry_output_ids([QueryParameter::AliasAddress(alias_address)]) + .foundry_output_ids([QueryParameter::AliasAddress(address)]) .await?; println!("Foundry output IDs: {output_ids_response:#?}"); diff --git a/sdk/examples/client/node_api_indexer/05_get_nft_output.rs b/sdk/examples/client/node_api_indexer/05_get_nft_output.rs index b91a233d79..10a7d14546 100644 --- a/sdk/examples/client/node_api_indexer/05_get_nft_output.rs +++ b/sdk/examples/client/node_api_indexer/05_get_nft_output.rs @@ -1,12 +1,15 @@ // Copyright 2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -//! TODO: by calling -//! `GET api/indexer/v1/outputs/nft/{nftId}`. +//! Gets the nft output from the corresponding nft id by querying the +//! `api/indexer/v1/outputs/nft/{nftId}` node endpoint. //! -//! `cargo run --example node_api_indexer_get_nft_output --release -- [NODE URL] [NFT ID]` - -use std::str::FromStr; +//! Make sure that the node has the indexer plugin enabled. +//! +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example node_api_indexer_get_nft_output [NODE URL] +//! ``` use iota_sdk::{ client::{Client, Result}, @@ -15,35 +18,29 @@ use iota_sdk::{ #[tokio::main] async fn main() -> Result<()> { + // This example uses secrets in environment variables for simplicity which should not be done in production. + dotenvy::dotenv().ok(); + // Take the node URL from command line argument or use one from env as default. - let node_url = std::env::args().nth(1).unwrap_or_else(|| { - // This example uses secrets in environment variables for simplicity which should not be done in production. - dotenvy::dotenv().ok(); - std::env::var("NODE_URL").unwrap() - }); - - // Create a client with that node. - let client = Client::builder() - // The node needs to have the indexer plugin enabled. - .with_node(&node_url)? - .finish() - .await?; - - // Take the NFT ID from command line argument or use a default one. - let nft_id = NftId::from_str( - &std::env::args() - .nth(2) - .unwrap_or_else(|| String::from("0xa3691952eaed71f85553f6e94fab82d5ed57301b2308be7c13d1f7df2be98995")), - )?; + let node_url = std::env::args() + .nth(2) + .unwrap_or_else(|| std::env::var("NODE_URL").unwrap()); + + // Create a node client. + let client = Client::builder().with_node(&node_url)?.finish().await?; + + // Take the NFT id from the command line, or panic. + let nft_id = std::env::args() + .nth(1) + .expect("missing example argument: NFT ID") + .parse::()?; // Get the output ID by the NFT ID. let output_id = client.nft_output_id(nft_id).await?; - println!("NFT output ID: {output_id}"); // Get the output by its ID. let output_response = client.get_output(&output_id).await?; - println!("{output_response:#?}",); Ok(()) diff --git a/sdk/examples/client/node_api_indexer/06_get_nft_outputs.rs b/sdk/examples/client/node_api_indexer/06_get_nft_outputs.rs index e1e418d2ae..0ce95267c0 100644 --- a/sdk/examples/client/node_api_indexer/06_get_nft_outputs.rs +++ b/sdk/examples/client/node_api_indexer/06_get_nft_outputs.rs @@ -1,10 +1,15 @@ // Copyright 2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -//! TODO: by calling -//! `GET api/indexer/v1/outputs/nft`. +//! Gets all nft output ids accociated with an address by querying the +//! `api/indexer/v1/outputs/nft` node endpoint. //! -//! `cargo run --example node_api_indexer_get_nft_outputs --release -- [NODE URL] [ADDRESS]` +//! Make sure that the node has the indexer plugin enabled. +//! +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example node_api_indexer_get_nft_outputs
[NODE URL] +//! ``` use iota_sdk::{ client::{node_api::indexer::query_parameters::QueryParameter, Client, Result}, @@ -13,27 +18,26 @@ use iota_sdk::{ #[tokio::main] async fn main() -> Result<()> { + // This example uses secrets in environment variables for simplicity which should not be done in production. + dotenvy::dotenv().ok(); + // Take the node URL from command line argument or use one from env as default. - let node_url = std::env::args().nth(1).unwrap_or_else(|| { - // This example uses secrets in environment variables for simplicity which should not be done in production. - dotenvy::dotenv().ok(); - std::env::var("NODE_URL").unwrap() - }); + let node_url = std::env::args() + .nth(2) + .unwrap_or_else(|| std::env::var("NODE_URL").unwrap()); - // Create a client with that node. + // Create a node client. let client = Client::builder() // The node needs to have the indexer plugin enabled. .with_node(&node_url)? .finish() .await?; - // Take the address from command line argument or use a default one. - let address = Bech32Address::try_from_str( - std::env::args() - .nth(2) - .as_deref() - .unwrap_or("rms1qrrdjmdkadtcnuw0ue5n9g4fmkelrj3dl26eyeshkha3w3uu0wheu5z5qqz"), - )?; + // Take the address from the command line, or panic. + let address = std::env::args() + .nth(1) + .expect("missing example argument: ADDRESS") + .parse::()?; // Get output IDs of NFT outputs that can be controlled by this address without further unlock constraints. let output_ids_response = client diff --git a/sdk/examples/client/node_api_indexer/07_get_random_basic_outputs.rs b/sdk/examples/client/node_api_indexer/07_get_random_basic_outputs.rs index 6bda3509d0..23eb1c0e57 100644 --- a/sdk/examples/client/node_api_indexer/07_get_random_basic_outputs.rs +++ b/sdk/examples/client/node_api_indexer/07_get_random_basic_outputs.rs @@ -1,28 +1,30 @@ // Copyright 2023 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -//! TODO: by calling -//! `GET api/indexer/v1/outputs/basic`. +//! Gets the first page of output ids when querying the +//! `api/indexer/v1/outputs/basic` node endpoint. //! -//! `cargo run --example node_api_indexer_get_random_basic_outputs --release -- [NODE URL]` +//! Make sure that the node has the indexer plugin enabled. +//! +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example node_api_indexer_get_random_basic_outputs [NODE_URL] +//! ``` use iota_sdk::client::{node_api::indexer::query_parameters::QueryParameter, Client, Result}; #[tokio::main] async fn main() -> Result<()> { + // This example uses secrets in environment variables for simplicity which should not be done in production. + dotenvy::dotenv().ok(); + // Take the node URL from command line argument or use one from env as default. - let node_url = std::env::args().nth(1).unwrap_or_else(|| { - // This example uses secrets in environment variables for simplicity which should not be done in production. - dotenvy::dotenv().ok(); - std::env::var("NODE_URL").unwrap() - }); - - // Create a client with that node. - let client = Client::builder() - // The node needs to have the indexer plugin enabled. - .with_node(&node_url)? - .finish() - .await?; + let node_url = std::env::args() + .nth(2) + .unwrap_or_else(|| std::env::var("NODE_URL").unwrap()); + + // Create a node client. + let client = Client::builder().with_node(&node_url)?.finish().await?; // Get a single page with random output IDs by providing only `QueryParameter::Cursor(_)`. let output_ids_response = client.basic_output_ids([QueryParameter::Cursor(String::new())]).await?; diff --git a/sdk/examples/client/offline_signing/0_address_generation.rs b/sdk/examples/client/offline_signing/0_address_generation.rs index 1f58054062..4ff0f791b6 100644 --- a/sdk/examples/client/offline_signing/0_address_generation.rs +++ b/sdk/examples/client/offline_signing/0_address_generation.rs @@ -3,13 +3,10 @@ //! In this example we generate an address which will be used later to find inputs. //! -//! `cargo run --example 0_address_generation --release` - -use std::{ - fs::File, - io::{BufWriter, Write}, - path::Path, -}; +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example 0_address_generation +//! ``` use iota_sdk::{ client::{api::GetAddressesOptions, constants::SHIMMER_TESTNET_BECH32_HRP, secret::SecretManager, Result}, @@ -36,16 +33,20 @@ async fn main() -> Result<()> { ) .await?; - write_address_to_file(ADDRESS_FILE_NAME, &address) + write_address_to_file(ADDRESS_FILE_NAME, &address).await?; + + Ok(()) } -fn write_address_to_file>(path: P, address: &[Bech32Address]) -> Result<()> { +async fn write_address_to_file(path: impl AsRef, address: &[Bech32Address]) -> Result<()> { + use tokio::io::AsyncWriteExt; + let json = serde_json::to_string_pretty(&address)?; - let mut file = BufWriter::new(File::create(path).unwrap()); + let mut file = tokio::io::BufWriter::new(tokio::fs::File::create(path).await.expect("failed to create file")); println!("{json}"); - file.write_all(json.as_bytes()).unwrap(); + file.write_all(json.as_bytes()).await.expect("failed to write to file"); Ok(()) } diff --git a/sdk/examples/client/offline_signing/1_transaction_preparation.rs b/sdk/examples/client/offline_signing/1_transaction_preparation.rs index 159e71b9aa..455f86b942 100644 --- a/sdk/examples/client/offline_signing/1_transaction_preparation.rs +++ b/sdk/examples/client/offline_signing/1_transaction_preparation.rs @@ -3,13 +3,12 @@ //! In this example we get inputs and prepare a transaction. //! -//! `cargo run --example 1_transaction_preparation --release` - -use std::{ - fs::File, - io::{prelude::*, BufWriter}, - path::Path, -}; +//! Make sure to run `0_address_generation` before. +//! +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example 1_transaction_preparation [RECV ADDRESS] [AMOUNT] +//! ``` use iota_sdk::{ client::{ @@ -30,19 +29,23 @@ async fn main() -> Result<()> { let node_url = std::env::var("NODE_URL").unwrap(); // Address to which we want to send the amount. - let address = "rms1qruzprxum2934lr3p77t96pzlecxv8pjzvtjrzdcgh2f5exa22n6ga0vm69"; + let recv_address = std::env::args() + .nth(1) + .unwrap_or_else(|| "rms1qruzprxum2934lr3p77t96pzlecxv8pjzvtjrzdcgh2f5exa22n6ga0vm69".to_string()); + let recv_address = recv_address.as_str(); + // The amount to send. - let amount = 1_000_000; + let amount = std::env::args() + .nth(2) + .map(|s| s.parse::().unwrap()) + .unwrap_or(1_000_000u64); - // Create a client instance. - let online_client = Client::builder() - // Insert your node URL in the .env. - .with_node(&node_url)? - .finish() - .await?; + // Create a node client. + let online_client = Client::builder().with_node(&node_url)?.finish().await?; + + // Recovers addresses from the previous example. + let addresses = read_addresses_from_file(ADDRESS_FILE_NAME).await?; - // Recovers addresses from example `0_address_generation`. - let addresses = read_addresses_from_file(ADDRESS_FILE_NAME)?; // Gets enough inputs related to these addresses to cover the amount. let inputs = online_client.find_inputs(addresses, amount).await?; @@ -52,34 +55,40 @@ async fn main() -> Result<()> { transaction_builder = transaction_builder.with_input(input)?; } let prepared_transaction = transaction_builder - .with_output(address, amount) + .with_output(recv_address, amount) .await? .prepare_transaction() .await?; - println!("Prepared transaction sending {amount} to {address}."); + println!("Prepared transaction sending {amount} to {recv_address}."); + + write_prepared_transaction_to_file(PREPARED_TRANSACTION_FILE_NAME, &prepared_transaction).await?; - write_prepared_transaction_to_file(PREPARED_TRANSACTION_FILE_NAME, &prepared_transaction) + Ok(()) } -fn read_addresses_from_file>(path: P) -> Result> { - let mut file = File::open(&path).unwrap(); +async fn read_addresses_from_file(path: impl AsRef) -> Result> { + use tokio::io::AsyncReadExt; + + let mut file = tokio::fs::File::open(&path).await.expect("failed to open file"); let mut json = String::new(); - file.read_to_string(&mut json).unwrap(); + file.read_to_string(&mut json).await.expect("failed to read file"); Ok(serde_json::from_str(&json)?) } -fn write_prepared_transaction_to_file>( - path: P, +async fn write_prepared_transaction_to_file( + path: impl AsRef, prepared_transaction: &PreparedTransactionData, ) -> Result<()> { + use tokio::io::AsyncWriteExt; + let json = serde_json::to_string_pretty(&PreparedTransactionDataDto::from(prepared_transaction))?; - let mut file = BufWriter::new(File::create(path).unwrap()); + let mut file = tokio::io::BufWriter::new(tokio::fs::File::create(path).await.expect("failed to create file")); println!("{json}"); - file.write_all(json.as_bytes()).unwrap(); + file.write_all(json.as_bytes()).await.expect("failed to write file"); Ok(()) } diff --git a/sdk/examples/client/offline_signing/2_transaction_signing.rs b/sdk/examples/client/offline_signing/2_transaction_signing.rs index da762742d0..6415b84117 100644 --- a/sdk/examples/client/offline_signing/2_transaction_signing.rs +++ b/sdk/examples/client/offline_signing/2_transaction_signing.rs @@ -3,13 +3,12 @@ //! In this example we sign the prepared transaction. //! -//! `cargo run --example 2_transaction_signing --release` - -use std::{ - fs::File, - io::{prelude::*, BufWriter}, - path::Path, -}; +//! Make sure to run `1_transaction_preparation` before. +//! +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example 2_transaction_signing +//! ``` use iota_sdk::{ client::{ @@ -31,7 +30,7 @@ async fn main() -> Result<()> { let secret_manager = SecretManager::try_from_mnemonic(std::env::var("NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_1").unwrap())?; - let prepared_transaction_data = read_prepared_transaction_from_file(PREPARED_TRANSACTION_FILE_NAME)?; + let prepared_transaction_data = read_prepared_transaction_from_file(PREPARED_TRANSACTION_FILE_NAME).await?; // Signs the prepared transaction offline. let unlocks = secret_manager @@ -46,32 +45,34 @@ async fn main() -> Result<()> { println!("Signed transaction."); - write_signed_transaction_to_file(SIGNED_TRANSACTION_FILE_NAME, &signed_transaction_data)?; + write_signed_transaction_to_file(SIGNED_TRANSACTION_FILE_NAME, &signed_transaction_data).await?; Ok(()) } -fn read_prepared_transaction_from_file>(path: P) -> Result { - let mut file = File::open(&path).unwrap(); +async fn read_prepared_transaction_from_file(path: impl AsRef) -> Result { + use tokio::io::AsyncReadExt; + + let mut file = tokio::fs::File::open(&path).await.expect("failed to open file"); let mut json = String::new(); - file.read_to_string(&mut json).unwrap(); + file.read_to_string(&mut json).await.expect("failed to read file"); Ok(PreparedTransactionData::try_from_dto_unverified( serde_json::from_str::(&json)?, )?) } -fn write_signed_transaction_to_file>( - path: P, +async fn write_signed_transaction_to_file( + path: impl AsRef, signed_transaction_data: &SignedTransactionData, ) -> Result<()> { + use tokio::io::AsyncWriteExt; + let dto = SignedTransactionDataDto::from(signed_transaction_data); let json = serde_json::to_string_pretty(&dto)?; - let mut file = BufWriter::new(File::create(path).unwrap()); - + let mut file = tokio::io::BufWriter::new(tokio::fs::File::create(path).await.expect("failed to create file")); println!("{json}"); - - file.write_all(json.as_bytes()).unwrap(); + file.write_all(json.as_bytes()).await.expect("failed to write file"); Ok(()) } diff --git a/sdk/examples/client/offline_signing/3_send_block.rs b/sdk/examples/client/offline_signing/3_send_block.rs index c80a1b8e75..496622ac68 100644 --- a/sdk/examples/client/offline_signing/3_send_block.rs +++ b/sdk/examples/client/offline_signing/3_send_block.rs @@ -3,9 +3,12 @@ //! In this example we send the signed transaction in a block. //! -//! `cargo run --example 3_send_block --release` - -use std::{fs::File, io::prelude::*, path::Path}; +//! Make sure to run `2_transaction_signing` before. +//! +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example 3_send_block +//! ``` use iota_sdk::{ client::{ @@ -24,14 +27,10 @@ async fn main() -> Result<()> { let node_url = std::env::var("NODE_URL").unwrap(); - // Create a client instance. - let online_client = Client::builder() - // Insert your node URL in the .env. - .with_node(&node_url)? - .finish() - .await?; + // Create a node client. + let online_client = Client::builder().with_node(&node_url)?.finish().await?; - let signed_transaction_payload = read_signed_transaction_from_file(SIGNED_TRANSACTION_FILE_NAME)?; + let signed_transaction_payload = read_signed_transaction_from_file(SIGNED_TRANSACTION_FILE_NAME).await?; let current_time = online_client.get_time_checked().await?; @@ -62,10 +61,12 @@ async fn main() -> Result<()> { Ok(()) } -fn read_signed_transaction_from_file>(path: P) -> Result { - let mut file = File::open(&path).unwrap(); +async fn read_signed_transaction_from_file(path: impl AsRef) -> Result { + use tokio::io::AsyncReadExt; + + let mut file = tokio::fs::File::open(path).await.expect("failed to open file"); let mut json = String::new(); - file.read_to_string(&mut json).unwrap(); + file.read_to_string(&mut json).await.expect("failed to read file"); let dto = serde_json::from_str::(&json)?; diff --git a/sdk/examples/client/output/alias.rs b/sdk/examples/client/output/alias.rs index 15eac15b87..9b85c4290a 100644 --- a/sdk/examples/client/output/alias.rs +++ b/sdk/examples/client/output/alias.rs @@ -3,7 +3,10 @@ //! In this example we will create an alias output. //! -//! `cargo run --example alias --release` +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example alias [ALIAS AMOUNT] +//! ``` use iota_sdk::{ client::{api::GetAddressesOptions, request_funds_from_faucet, secret::SecretManager, Client, Result}, @@ -24,11 +27,11 @@ async fn main() -> Result<()> { // non-zero balance. dotenvy::dotenv().ok(); - let node_url = std::env::var("NODE_URL").unwrap(); - let faucet_url = std::env::var("FAUCET_URL").unwrap(); - - // Create a client instance. - let client = Client::builder().with_node(&node_url)?.finish().await?; + // Create a node client. + let client = Client::builder() + .with_node(&std::env::var("NODE_URL").unwrap())? + .finish() + .await?; let secret_manager = SecretManager::try_from_mnemonic(std::env::var("NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_1").unwrap())?; @@ -38,13 +41,21 @@ async fn main() -> Result<()> { let address = secret_manager .generate_ed25519_addresses(GetAddressesOptions::from_client(&client).await?.with_range(0..1)) .await?[0]; - request_funds_from_faucet(&faucet_url, &address).await?; + + println!( + "Requesting funds (waiting 15s): {}", + request_funds_from_faucet(&std::env::var("FAUCET_URL").unwrap(), &address).await?, + ); tokio::time::sleep(std::time::Duration::from_secs(15)).await; ////////////////////////////////// // create new alias output ////////////////////////////////// - let alias_output_builder = AliasOutputBuilder::new_with_amount(1_000_000, AliasId::null()) + let alias_amount = std::env::args() + .nth(1) + .map(|s| s.parse::().unwrap()) + .unwrap_or(1_000_000u64); + let alias_output_builder = AliasOutputBuilder::new_with_amount(alias_amount, AliasId::null()) .add_feature(SenderFeature::new(address)) .add_feature(MetadataFeature::new([1, 2, 3])?) .add_immutable_feature(IssuerFeature::new(address)) diff --git a/sdk/examples/client/output/all.rs b/sdk/examples/client/output/all.rs index 7edba792cd..bfdf7e5eb5 100644 --- a/sdk/examples/client/output/all.rs +++ b/sdk/examples/client/output/all.rs @@ -3,7 +3,10 @@ //! In this example we will create all output types in a single transaction. //! -//! `cargo run --example all --release` +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example all +//! ``` use iota_sdk::{ client::{ @@ -34,12 +37,11 @@ async fn main() -> Result<()> { // non-zero balance. dotenvy::dotenv().ok(); - let node_url = std::env::var("NODE_URL").unwrap(); - let explorer_url = std::env::var("EXPLORER_URL").unwrap(); - let faucet_url = std::env::var("FAUCET_URL").unwrap(); - - // Create a client instance. - let client = Client::builder().with_node(&node_url)?.finish().await?; + // Create a node client. + let client = Client::builder() + .with_node(&std::env::var("NODE_URL").unwrap())? + .finish() + .await?; let secret_manager = SecretManager::try_from_mnemonic(std::env::var("NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_1").unwrap())?; @@ -49,7 +51,11 @@ async fn main() -> Result<()> { let address = secret_manager .generate_ed25519_addresses(GetAddressesOptions::from_client(&client).await?.with_range(0..1)) .await?[0]; - println!("{}", request_funds_from_faucet(&faucet_url, &address).await?); + + println!( + "Requesting funds (waiting 15s): {}", + request_funds_from_faucet(&std::env::var("FAUCET_URL").unwrap(), &address).await?, + ); tokio::time::sleep(std::time::Duration::from_secs(15)).await; ////////////////////////////////// @@ -85,7 +91,8 @@ async fn main() -> Result<()> { .await?; println!( - "Block with new nft and alias output sent: {explorer_url}/block/{}", + "Block with new nft and alias output sent: {}/block/{}", + std::env::var("EXPLORER_URL").unwrap(), block.id() ); let _ = client.retry_until_included(&block.id(), None, None).await?; @@ -138,7 +145,8 @@ async fn main() -> Result<()> { .finish() .await?; println!( - "Block with foundry output, minted tokens and nft sent: {explorer_url}/block/{}", + "Block with foundry output, minted tokens and nft sent: {}/block/{}", + std::env::var("EXPLORER_URL").unwrap(), block.id() ); let _ = client.retry_until_included(&block.id(), None, None).await?; @@ -216,7 +224,12 @@ async fn main() -> Result<()> { .with_outputs(outputs)? .finish() .await?; - println!("Block with all outputs sent: {explorer_url}/block/{}", block.id()); + println!( + "Block with all outputs sent: {}/block/{}", + std::env::var("EXPLORER_URL").unwrap(), + block.id(), + ); + let _ = client.retry_until_included(&block.id(), None, None).await?; Ok(()) diff --git a/sdk/examples/client/output/all_automatic_input_selection.rs b/sdk/examples/client/output/all_automatic_input_selection.rs index b0e7729bb0..5d1136a906 100644 --- a/sdk/examples/client/output/all_automatic_input_selection.rs +++ b/sdk/examples/client/output/all_automatic_input_selection.rs @@ -3,7 +3,10 @@ //! In this example we will create all output types in a single transaction. //! -//! `cargo run --example all_automatic_input_selection --release` +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example all_automatic_input_selection +//! ``` use iota_sdk::{ client::{api::GetAddressesOptions, request_funds_from_faucet, secret::SecretManager, Client, Result}, @@ -31,12 +34,11 @@ async fn main() -> Result<()> { // non-zero balance. dotenvy::dotenv().ok(); - let node_url = std::env::var("NODE_URL").unwrap(); - let explorer_url = std::env::var("EXPLORER_URL").unwrap(); - let faucet_url = std::env::var("FAUCET_URL").unwrap(); - - // Create a client instance. - let client = Client::builder().with_node(&node_url)?.finish().await?; + // Create a node client. + let client = Client::builder() + .with_node(&std::env::var("NODE_URL").unwrap())? + .finish() + .await?; let secret_manager = SecretManager::try_from_mnemonic(std::env::var("NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_1").unwrap())?; @@ -46,7 +48,11 @@ async fn main() -> Result<()> { let address = secret_manager .generate_ed25519_addresses(GetAddressesOptions::from_client(&client).await?.with_range(0..1)) .await?[0]; - println!("{}", request_funds_from_faucet(&faucet_url, &address).await?); + + println!( + "Requesting funds (waiting 15s): {}", + request_funds_from_faucet(&std::env::var("FAUCET_URL").unwrap(), &address).await?, + ); tokio::time::sleep(std::time::Duration::from_secs(15)).await; ////////////////////////////////// @@ -80,7 +86,8 @@ async fn main() -> Result<()> { .await?; println!( - "Block with new nft and alias output sent: {explorer_url}/block/{}", + "Block with new nft and alias output sent: {}/block/{}", + std::env::var("EXPLORER_URL").unwrap(), block.id() ); let _ = client.retry_until_included(&block.id(), None, None).await?; @@ -129,8 +136,9 @@ async fn main() -> Result<()> { .finish() .await?; println!( - "Block with alias id, foundry output with minted native tokens, and nfts sent: {explorer_url}/block/{}", - block.id() + "Block with alias id, foundry output with minted native tokens, and nfts sent: {}/block/{}", + std::env::var("EXPLORER_URL").unwrap(), + block.id(), ); let _ = client.retry_until_included(&block.id(), None, None).await?; @@ -190,7 +198,11 @@ async fn main() -> Result<()> { .with_outputs(outputs)? .finish() .await?; - println!("Block with all outputs sent: {explorer_url}/block/{}", block.id()); + println!( + "Block with all outputs sent: {}/block/{}", + std::env::var("EXPLORER_URL").unwrap(), + block.id() + ); let _ = client.retry_until_included(&block.id(), None, None).await?; Ok(()) diff --git a/sdk/examples/client/output/basic.rs b/sdk/examples/client/output/basic.rs index 414c1338c9..f8e4b12f67 100644 --- a/sdk/examples/client/output/basic.rs +++ b/sdk/examples/client/output/basic.rs @@ -3,7 +3,10 @@ //! In this example we will send basic outputs with different feature blocks. //! -//! `cargo run --example basic --release` +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example basic +//! ``` use iota_sdk::{ client::{api::GetAddressesOptions, secret::SecretManager, utils::request_funds_from_faucet, Client, Result}, @@ -24,12 +27,11 @@ async fn main() -> Result<()> { // non-zero balance. dotenvy::dotenv().ok(); - let node_url = std::env::var("NODE_URL").unwrap(); - let explorer_url = std::env::var("EXPLORER_URL").unwrap(); - let faucet_url = std::env::var("FAUCET_URL").unwrap(); - - // Create a client instance. - let client = Client::builder().with_node(&node_url)?.finish().await?; + // Create a node client. + let client = Client::builder() + .with_node(&std::env::var("NODE_URL").unwrap())? + .finish() + .await?; let secret_manager = SecretManager::try_from_mnemonic(std::env::var("NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_1").unwrap())?; @@ -40,7 +42,11 @@ async fn main() -> Result<()> { .generate_ed25519_addresses(GetAddressesOptions::from_client(&client).await?.with_range(0..1)) .await?[0]; - println!("{}", request_funds_from_faucet(&faucet_url, &address).await?); + println!( + "Requesting funds (waiting 15s): {}", + request_funds_from_faucet(&std::env::var("FAUCET_URL").unwrap(), &address).await?, + ); + tokio::time::sleep(std::time::Duration::from_secs(15)).await; let basic_output_builder = BasicOutputBuilder::new_with_amount(1_000_000).add_unlock_condition(AddressUnlockCondition::new(address)); @@ -82,7 +88,11 @@ async fn main() -> Result<()> { .finish() .await?; - println!("Basic outputs block sent: {explorer_url}/block/{}", block.id()); + println!( + "Basic outputs block sent: {}/block/{}", + std::env::var("EXPLORER_URL").unwrap(), + block.id() + ); let _ = client.retry_until_included(&block.id(), None, None).await?; Ok(()) } diff --git a/sdk/examples/client/output/build_alias_output.rs b/sdk/examples/client/output/build_alias_output.rs index de68296f35..727097cca7 100644 --- a/sdk/examples/client/output/build_alias_output.rs +++ b/sdk/examples/client/output/build_alias_output.rs @@ -3,7 +3,10 @@ //! In this example we will build an alias output. //! -//! `cargo run --example build_alias_output --release` +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example build_alias_output [METADATA] [ADDRESS] +//! ``` use iota_sdk::{ client::{Client, Result}, @@ -22,24 +25,30 @@ async fn main() -> Result<()> { // This example uses secrets in environment variables for simplicity which should not be done in production. dotenvy::dotenv().ok(); - let node_url = std::env::var("NODE_URL").unwrap(); + let metadata = std::env::args().nth(1).unwrap_or("hello".to_string()); + let metadata = metadata.as_bytes(); - // Create a client instance. - let client = Client::builder().with_node(&node_url)?.finish().await?; + // Create a node client. + let client = Client::builder() + .with_node(&std::env::var("NODE_URL").unwrap())? + .finish() + .await?; let token_supply = client.get_token_supply().await?; let rent_structure = client.get_rent_structure().await?; - let address = Address::try_from_bech32("rms1qpllaj0pyveqfkwxmnngz2c488hfdtmfrj3wfkgxtk4gtyrax0jaxzt70zy")?; + let address = std::env::args() + .nth(1) + .unwrap_or("rms1qpllaj0pyveqfkwxmnngz2c488hfdtmfrj3wfkgxtk4gtyrax0jaxzt70zy".to_string()); + let address = Address::try_from_bech32(address)?; // Alias id needs to be null the first time let alias_output = AliasOutputBuilder::new_with_minimum_storage_deposit(rent_structure, AliasId::null()) - // `hello` in bytes - .with_state_metadata([104, 101, 108, 108, 111]) + .with_state_metadata(metadata) .add_feature(SenderFeature::new(address)) - .add_feature(MetadataFeature::new([104, 101, 108, 108, 111])?) + .add_feature(MetadataFeature::new(metadata)?) .add_immutable_feature(IssuerFeature::new(address)) - .add_immutable_feature(MetadataFeature::new([104, 101, 108, 108, 111])?) + .add_immutable_feature(MetadataFeature::new(metadata)?) .add_unlock_condition(StateControllerAddressUnlockCondition::new(address)) .add_unlock_condition(GovernorAddressUnlockCondition::new(address)) .finish_output(token_supply)?; diff --git a/sdk/examples/client/output/build_basic_output.rs b/sdk/examples/client/output/build_basic_output.rs index b050e5e4c6..900cadfa19 100644 --- a/sdk/examples/client/output/build_basic_output.rs +++ b/sdk/examples/client/output/build_basic_output.rs @@ -3,7 +3,10 @@ //! In this example we will build basic outputs with different feature blocks. //! -//! `cargo run --example build_basic_output --release` +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example build_basic_output [ADDRESS] +//! ``` use iota_sdk::{ client::{Client, Result}, @@ -20,19 +23,25 @@ use iota_sdk::{ }, }; +const METADATA: &str = "Hello, World!"; + #[tokio::main] async fn main() -> Result<()> { // This example uses secrets in environment variables for simplicity which should not be done in production. dotenvy::dotenv().ok(); - let node_url = std::env::var("NODE_URL").unwrap(); - - // Create a client instance. - let client = Client::builder().with_node(&node_url)?.finish().await?; + // Create a node client. + let client = Client::builder() + .with_node(&std::env::var("NODE_URL").unwrap())? + .finish() + .await?; let token_supply = client.get_token_supply().await?; - let address = Address::try_from_bech32("rms1qpllaj0pyveqfkwxmnngz2c488hfdtmfrj3wfkgxtk4gtyrax0jaxzt70zy")?; + let address = std::env::args() + .nth(1) + .unwrap_or("rms1qpllaj0pyveqfkwxmnngz2c488hfdtmfrj3wfkgxtk4gtyrax0jaxzt70zy".to_string()); + let address = Address::try_from_bech32(address)?; let basic_output_builder = BasicOutputBuilder::new_with_amount(1_000_000).add_unlock_condition(AddressUnlockCondition::new(address)); @@ -43,14 +52,14 @@ async fn main() -> Result<()> { // with metadata feature block basic_output_builder .clone() - .add_feature(MetadataFeature::new("Hello, World!")?) + .add_feature(MetadataFeature::new(METADATA)?) .finish_output(token_supply)?, // with storage deposit return basic_output_builder .clone() .add_unlock_condition(StorageDepositReturnUnlockCondition::new( address, - 1000000, + 1_000_000, token_supply, )?) .finish_output(token_supply)?, @@ -67,7 +76,7 @@ async fn main() -> Result<()> { // with tag feature basic_output_builder .clone() - .add_feature(TagFeature::new("Hello, World!")?) + .add_feature(TagFeature::new(METADATA)?) .finish_output(token_supply)?, // with sender feature basic_output_builder diff --git a/sdk/examples/client/output/build_nft_output.rs b/sdk/examples/client/output/build_nft_output.rs index 4487af4d15..e75aa942ba 100644 --- a/sdk/examples/client/output/build_nft_output.rs +++ b/sdk/examples/client/output/build_nft_output.rs @@ -3,7 +3,10 @@ //! In this example we will build an NFT output. //! -//! `cargo run --example build_nft_output --release --features="client"` +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example build_nft_output [ADDRESS] +//! ``` use iota_sdk::{ client::{Client, Result}, @@ -17,30 +20,38 @@ use iota_sdk::{ }, }; +const MUTABLE_METADATA: &str = "mutable metadata"; +const TAG: &str = "my tag"; + #[tokio::main] async fn main() -> Result<()> { // This example uses secrets in environment variables for simplicity which should not be done in production. dotenvy::dotenv().ok(); - let node_url = std::env::var("NODE_URL").unwrap(); - - // Create a client instance. - let client = Client::builder().with_node(&node_url)?.finish().await?; + // Create a node client. + let client = Client::builder() + .with_node(&std::env::var("NODE_URL").unwrap())? + .finish() + .await?; let token_supply = client.get_token_supply().await?; let rent_structure = client.get_rent_structure().await?; - let address = Address::try_from_bech32("rms1qpllaj0pyveqfkwxmnngz2c488hfdtmfrj3wfkgxtk4gtyrax0jaxzt70zy")?; + let address = std::env::args() + .nth(1) + .unwrap_or("rms1qpllaj0pyveqfkwxmnngz2c488hfdtmfrj3wfkgxtk4gtyrax0jaxzt70zy".to_string()); + let address = Address::try_from_bech32(address)?; // IOTA NFT Standard - IRC27: https://github.com/iotaledger/tips/blob/main/tips/TIP-0027/tip-0027.md let tip_27_immutable_metadata = serde_json::from_str::( - r#"{ - "standard": "IRC27", - "version": "v1.0", - "type":"image/jpeg", - "uri":"https://mywebsite.com/my-nft-files-1.jpeg", - "name":"My NFT #0001" - }"#, + r#" + { + "standard": "IRC27", + "version": "v1.0", + "type":"image/jpeg", + "uri":"https://mywebsite.com/my-nft-files-1.jpeg", + "name":"My NFT #0001" + }"#, )? .to_string(); @@ -48,8 +59,8 @@ async fn main() -> Result<()> { let nft_output = NftOutputBuilder::new_with_minimum_storage_deposit(rent_structure, NftId::null()) .add_unlock_condition(AddressUnlockCondition::new(address)) .add_feature(SenderFeature::new(address)) - .add_feature(MetadataFeature::new("mutable metadata")?) - .add_feature(TagFeature::new("my tag")?) + .add_feature(MetadataFeature::new(MUTABLE_METADATA)?) + .add_feature(TagFeature::new(TAG)?) .add_immutable_feature(IssuerFeature::new(address)) .add_immutable_feature(MetadataFeature::new(tip_27_immutable_metadata)?) .finish_output(token_supply)?; diff --git a/sdk/examples/client/output/expiration.rs b/sdk/examples/client/output/expiration.rs index afdbb0560f..3e31761d05 100644 --- a/sdk/examples/client/output/expiration.rs +++ b/sdk/examples/client/output/expiration.rs @@ -6,9 +6,10 @@ //! When the receiver (address in AddressUnlockCondition) doesn't consume the output before it gets expired, the sender //! (address in ExpirationUnlockCondition) will get the full control back. //! -//! `cargo run --example expiration --release` - -use std::time::{Duration, SystemTime, UNIX_EPOCH}; +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example expiration +//! ``` use iota_sdk::{ client::{api::GetAddressesOptions, request_funds_from_faucet, secret::SecretManager, Client, Result}, @@ -18,6 +19,8 @@ use iota_sdk::{ }, }; +const AMOUNT: u64 = 255_100; + #[tokio::main] async fn main() -> Result<()> { // This example uses secrets in environment variables for simplicity which should not be done in production. @@ -25,12 +28,11 @@ async fn main() -> Result<()> { // non-zero balance. dotenvy::dotenv().ok(); - let node_url = std::env::var("NODE_URL").unwrap(); - let explorer_url = std::env::var("EXPLORER_URL").unwrap(); - let faucet_url = std::env::var("FAUCET_URL").unwrap(); - - // Create a client instance. - let client = Client::builder().with_node(&node_url)?.finish().await?; + // Create a node client. + let client = Client::builder() + .with_node(&std::env::var("NODE_URL").unwrap())? + .finish() + .await?; let secret_manager = SecretManager::try_from_mnemonic(std::env::var("NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_1").unwrap())?; @@ -43,11 +45,14 @@ async fn main() -> Result<()> { let token_supply = client.get_token_supply().await?; - request_funds_from_faucet(&faucet_url, &sender_address).await?; + println!( + "Requesting funds (waiting 15s): {}", + request_funds_from_faucet(&std::env::var("FAUCET_URL").unwrap(), &sender_address).await?, + ); tokio::time::sleep(std::time::Duration::from_secs(15)).await; - let tomorrow = (SystemTime::now() + Duration::from_secs(24 * 3600)) - .duration_since(UNIX_EPOCH) + let tomorrow = (std::time::SystemTime::now() + std::time::Duration::from_secs(24 * 3600)) + .duration_since(std::time::UNIX_EPOCH) .expect("clock went backwards") .as_secs() .try_into() @@ -55,7 +60,7 @@ async fn main() -> Result<()> { let outputs = [ // with storage deposit return - BasicOutputBuilder::new_with_amount(255_100) + BasicOutputBuilder::new_with_amount(AMOUNT) .add_unlock_condition(AddressUnlockCondition::new(receiver_address)) // If the receiver does not consume this output, we Unlock after a day to avoid // locking our funds forever. @@ -71,7 +76,8 @@ async fn main() -> Result<()> { .await?; println!( - "Block with ExpirationUnlockCondition transaction sent: {explorer_url}/block/{}", + "Block with ExpirationUnlockCondition transaction sent: {}/block/{}", + std::env::var("EXPLORER_URL").unwrap(), block.id() ); let _ = client.retry_until_included(&block.id(), None, None).await?; diff --git a/sdk/examples/client/output/foundry.rs b/sdk/examples/client/output/foundry.rs index 56f298e4f5..09b177889d 100644 --- a/sdk/examples/client/output/foundry.rs +++ b/sdk/examples/client/output/foundry.rs @@ -3,7 +3,10 @@ //! In this example we will create a foundry output. //! -//! `cargo run --example foundry --release` +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example foundry +//! ``` use iota_sdk::{ client::{ @@ -36,12 +39,11 @@ async fn main() -> Result<()> { // non-zero balance. dotenvy::dotenv().ok(); - let node_url = std::env::var("NODE_URL").unwrap(); - let explorer_url = std::env::var("EXPLORER_URL").unwrap(); - let faucet_url = std::env::var("FAUCET_URL").unwrap(); - - // Create a client instance. - let client = Client::builder().with_node(&node_url)?.finish().await?; + // Create a node client. + let client = Client::builder() + .with_node(&std::env::var("NODE_URL").unwrap())? + .finish() + .await?; let secret_manager = SecretManager::try_from_mnemonic(std::env::var("NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_1").unwrap())?; @@ -51,8 +53,12 @@ async fn main() -> Result<()> { let address = secret_manager .generate_ed25519_addresses(GetAddressesOptions::from_client(&client).await?.with_range(0..1)) .await?[0]; - println!("{}", request_funds_from_faucet(&faucet_url, &address).await?); - tokio::time::sleep(std::time::Duration::from_secs(20)).await; + + println!( + "Requesting funds (waiting 15s): {}", + request_funds_from_faucet(&std::env::var("FAUCET_URL").unwrap(), &address).await?, + ); + tokio::time::sleep(std::time::Duration::from_secs(15)).await; ////////////////////////////////// // create new alias output @@ -74,7 +80,11 @@ async fn main() -> Result<()> { .finish() .await?; - println!("Block with new alias output sent: {explorer_url}/block/{}", block.id()); + println!( + "Block with new alias output sent: {}/block/{}", + std::env::var("EXPLORER_URL").unwrap(), + block.id() + ); let _ = client.retry_until_included(&block.id(), None, None).await?; ////////////////////////////////////////////////// @@ -115,7 +125,11 @@ async fn main() -> Result<()> { .with_outputs(outputs)? .finish() .await?; - println!("Block with foundry output sent: {explorer_url}/block/{}", block.id()); + println!( + "Block with foundry output sent: {}/block/{}", + std::env::var("EXPLORER_URL").unwrap(), + block.id() + ); let _ = client.retry_until_included(&block.id(), None, None).await?; ////////////////////////////////// @@ -157,10 +171,13 @@ async fn main() -> Result<()> { .with_outputs(outputs)? .finish() .await?; + println!( - "Block with native tokens burnt sent: {explorer_url}/block/{}", + "Block with native tokens burnt sent: {}/block/{}", + std::env::var("EXPLORER_URL").unwrap(), block.id() ); + let _ = client.retry_until_included(&block.id(), None, None).await?; ////////////////////////////////// @@ -203,7 +220,12 @@ async fn main() -> Result<()> { .with_outputs(outputs)? .finish() .await?; - println!("Block with native tokens sent: {explorer_url}/block/{}", block.id()); + println!( + "Block with native tokens sent: {}/block/{}", + std::env::var("EXPLORER_URL").unwrap(), + block.id() + ); + let _ = client.retry_until_included(&block.id(), None, None).await?; ////////////////////////////////// @@ -223,10 +245,13 @@ async fn main() -> Result<()> { .with_outputs(outputs)? .finish() .await?; + println!( - "Second block with native tokens sent: {explorer_url}/block/{}", + "Second block with native tokens sent: {}/block/{}", + std::env::var("EXPLORER_URL").unwrap(), block.id() ); + let _ = client.retry_until_included(&block.id(), None, None).await?; ////////////////////////////////// @@ -246,10 +271,13 @@ async fn main() -> Result<()> { .with_outputs(outputs)? .finish() .await?; + println!( - "Third block with native tokens burned sent: {explorer_url}/block/{}", + "Third block with native tokens burned sent: {}/block/{}", + std::env::var("EXPLORER_URL").unwrap(), block.id() ); + let _ = client.retry_until_included(&block.id(), None, None).await?; Ok(()) diff --git a/sdk/examples/client/output/micro_transaction.rs b/sdk/examples/client/output/micro_transaction.rs index a7b3a14e2f..fcba1f11a2 100644 --- a/sdk/examples/client/output/micro_transaction.rs +++ b/sdk/examples/client/output/micro_transaction.rs @@ -7,9 +7,10 @@ //! However, it is possible to send a large amount and ask a slightly smaller amount in return to //! effectively transfer a small amount. //! -//! `cargo run --example microtransaction --release` - -use std::time::{Duration, SystemTime, UNIX_EPOCH}; +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example microtransaction +//! ``` use iota_sdk::{ client::{api::GetAddressesOptions, request_funds_from_faucet, secret::SecretManager, Client, Result}, @@ -26,12 +27,11 @@ async fn main() -> Result<()> { // non-zero balance. dotenvy::dotenv().ok(); - let node_url = std::env::var("NODE_URL").unwrap(); - let explorer_url = std::env::var("EXPLORER_URL").unwrap(); - let faucet_url = std::env::var("FAUCET_URL").unwrap(); - - // Create a client instance. - let client = Client::builder().with_node(&node_url)?.finish().await?; + // Create a node client. + let client = Client::builder() + .with_node(&std::env::var("NODE_URL").unwrap())? + .finish() + .await?; let secret_manager = SecretManager::try_from_mnemonic(std::env::var("NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_1").unwrap())?; @@ -44,15 +44,19 @@ async fn main() -> Result<()> { let token_supply = client.get_token_supply().await?; - request_funds_from_faucet(&faucet_url, &sender_address).await?; + println!( + "Requesting funds (waiting 15s): {}", + request_funds_from_faucet(&std::env::var("FAUCET_URL").unwrap(), &sender_address).await?, + ); tokio::time::sleep(std::time::Duration::from_secs(15)).await; - let tomorrow = (SystemTime::now() + Duration::from_secs(24 * 3600)) - .duration_since(UNIX_EPOCH) + let tomorrow = (std::time::SystemTime::now() + std::time::Duration::from_secs(24 * 3600)) + .duration_since(std::time::UNIX_EPOCH) .expect("clock went backwards") .as_secs() .try_into() .unwrap(); + let outputs = [ // with storage deposit return BasicOutputBuilder::new_with_amount(255_100) @@ -76,7 +80,11 @@ async fn main() -> Result<()> { .finish() .await?; - println!("Block with micro amount sent: {explorer_url}/block/{}", block.id()); + println!( + "Block with micro amount sent: {}/block/{}", + std::env::var("EXPLORER_URL").unwrap(), + block.id() + ); let _ = client.retry_until_included(&block.id(), None, None).await?; Ok(()) diff --git a/sdk/examples/client/output/native_tokens.rs b/sdk/examples/client/output/native_tokens.rs index 3957f1bb0f..706aea6403 100644 --- a/sdk/examples/client/output/native_tokens.rs +++ b/sdk/examples/client/output/native_tokens.rs @@ -5,9 +5,10 @@ //! 1. receiver gets the full output amount + native tokens //! 2. receiver needs to claim the output to get the native tokens, but has to send the amount back //! -//! `cargo run --example native_tokens --release` - -use std::time::{Duration, SystemTime, UNIX_EPOCH}; +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example native_tokens [TOKEN ID] +//! ``` use iota_sdk::{ client::{api::GetAddressesOptions, secret::SecretManager, utils::request_funds_from_faucet, Client, Result}, @@ -16,7 +17,6 @@ use iota_sdk::{ BasicOutputBuilder, NativeToken, TokenId, }, }; -use primitive_types::U256; #[tokio::main] async fn main() -> Result<()> { @@ -25,12 +25,11 @@ async fn main() -> Result<()> { // non-zero balance. dotenvy::dotenv().ok(); - let node_url = std::env::var("NODE_URL").unwrap(); - let explorer_url = std::env::var("EXPLORER_URL").unwrap(); - let faucet_url = std::env::var("FAUCET_URL").unwrap(); - - // Create a client instance. - let client = Client::builder().with_node(&node_url)?.finish().await?; + // Create a node client. + let client = Client::builder() + .with_node(&std::env::var("NODE_URL").unwrap())? + .finish() + .await?; let secret_manager = SecretManager::try_from_mnemonic(std::env::var("NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_1").unwrap())?; @@ -43,32 +42,43 @@ async fn main() -> Result<()> { let token_supply = client.get_token_supply().await?; - request_funds_from_faucet(&faucet_url, &sender_address).await?; + println!( + "Requesting funds (waiting 15s): {}", + request_funds_from_faucet(&std::env::var("FAUCET_URL").unwrap(), &sender_address).await?, + ); tokio::time::sleep(std::time::Duration::from_secs(15)).await; - let tomorrow = (SystemTime::now() + Duration::from_secs(24 * 3600)) - .duration_since(UNIX_EPOCH) + let tomorrow = (std::time::SystemTime::now() + std::time::Duration::from_secs(24 * 3600)) + .duration_since(std::time::UNIX_EPOCH) .expect("clock went backwards") .as_secs() .try_into() .unwrap(); // Replace with the token ID of native tokens you own. - let token_id: [u8; 38] = - prefix_hex::decode("0x08e68f7616cd4948efebc6a77c4f935eaed770ac53869cba56d104f2b472a8836d0100000000")?; + let token_id = std::env::args() + .nth(1) + .unwrap_or("0x08e68f7616cd4948efebc6a77c4f935eaed770ac53869cba56d104f2b472a8836d0100000000".to_string()); + let token_id: [u8; 38] = prefix_hex::decode(token_id)?; let outputs = [ // Without StorageDepositReturnUnlockCondition, the receiver will get the amount of the output and the native // tokens BasicOutputBuilder::new_with_amount(1_000_000) .add_unlock_condition(AddressUnlockCondition::new(receiver_address)) - .add_native_token(NativeToken::new(TokenId::new(token_id), U256::from(10))?) + .add_native_token(NativeToken::new( + TokenId::new(token_id), + primitive_types::U256::from(10), + )?) .finish_output(token_supply)?, // With StorageDepositReturnUnlockCondition, the receiver can consume the output to get the native tokens, but // he needs to send the amount back BasicOutputBuilder::new_with_amount(1_000_000) .add_unlock_condition(AddressUnlockCondition::new(receiver_address)) - .add_native_token(NativeToken::new(TokenId::new(token_id), U256::from(10))?) + .add_native_token(NativeToken::new( + TokenId::new(token_id), + primitive_types::U256::from(10), + )?) // Return the full amount. .add_unlock_condition(StorageDepositReturnUnlockCondition::new( sender_address, @@ -88,7 +98,11 @@ async fn main() -> Result<()> { .finish() .await?; - println!("Block with native tokens sent: {explorer_url}/block/{}", block.id()); + println!( + "Block with native tokens sent: {}/block/{}", + std::env::var("EXPLORER_URL").unwrap(), + block.id() + ); Ok(()) } diff --git a/sdk/examples/client/output/nft.rs b/sdk/examples/client/output/nft.rs index e0be1ab460..4d81246b4f 100644 --- a/sdk/examples/client/output/nft.rs +++ b/sdk/examples/client/output/nft.rs @@ -3,7 +3,10 @@ //! In this example we will create an NFT output. //! -//! `cargo run --example nft --release` +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example nft +//! ``` use iota_sdk::{ client::{ @@ -30,7 +33,7 @@ async fn main() -> Result<()> { let explorer_url = std::env::var("EXPLORER_URL").unwrap(); let faucet_url = std::env::var("FAUCET_URL").unwrap(); - // Create a client instance. + // Create a node client. let client = Client::builder().with_node(&node_url)?.finish().await?; let secret_manager = @@ -41,8 +44,12 @@ async fn main() -> Result<()> { let address = secret_manager .generate_ed25519_addresses(GetAddressesOptions::from_client(&client).await?.with_range(0..1)) .await?[0]; - request_funds_from_faucet(&faucet_url, &address).await?; - tokio::time::sleep(std::time::Duration::from_secs(20)).await; + + println!( + "Requesting funds (waiting 15s): {}", + request_funds_from_faucet(&faucet_url, &address).await?, + ); + tokio::time::sleep(std::time::Duration::from_secs(15)).await; ////////////////////////////////// // create new nft output @@ -64,7 +71,8 @@ async fn main() -> Result<()> { .finish() .await?; - println!("Block with new NFT output sent: {explorer_url}/block/{}", block.id()); + println!("Block with new NFT output sent: {}/block/{}", explorer_url, block.id()); + let _ = client.retry_until_included(&block.id(), None, None).await?; ////////////////////////////////// @@ -77,11 +85,12 @@ async fn main() -> Result<()> { let nft_address = NftAddress::new(nft_id); let bech32_nft_address = Bech32Address::new(client.get_bech32_hrp().await?, nft_address); println!("bech32_nft_address {bech32_nft_address}"); + println!( - "Faucet request {:?}", - request_funds_from_faucet(&faucet_url, &bech32_nft_address).await? + "Requesting funds (waiting 15s): {}", + request_funds_from_faucet(&faucet_url, &bech32_nft_address).await?, ); - tokio::time::sleep(std::time::Duration::from_secs(20)).await; + tokio::time::sleep(std::time::Duration::from_secs(15)).await; let output_ids_response = client .basic_output_ids([QueryParameter::Address(bech32_nft_address)]) @@ -102,7 +111,8 @@ async fn main() -> Result<()> { .await?; println!( - "Block with input (basic output) to NFT output sent: {explorer_url}/block/{}", + "Block with input (basic output) to NFT output sent: {}/block/{}", + explorer_url, block.id() ); @@ -125,8 +135,15 @@ async fn main() -> Result<()> { .with_outputs(outputs)? .finish() .await?; - println!("Block with burn transaction sent: {explorer_url}/block/{}", block.id()); + + println!( + "Block with burn transaction sent: {}/block/{}", + explorer_url, + block.id() + ); + let _ = client.retry_until_included(&block.id(), None, None).await?; + Ok(()) } diff --git a/sdk/examples/client/output/recursive_alias.rs b/sdk/examples/client/output/recursive_alias.rs index 1bef96694a..3c61b9675b 100644 --- a/sdk/examples/client/output/recursive_alias.rs +++ b/sdk/examples/client/output/recursive_alias.rs @@ -3,7 +3,10 @@ //! In this example we will create three alias outputs, where the first one can control the other two (recursively). //! -//! `cargo run --example recursive_alias --release` +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example recursive_alias +//! ``` use iota_sdk::{ client::{api::GetAddressesOptions, request_funds_from_faucet, secret::SecretManager, Client, Result}, @@ -25,12 +28,11 @@ async fn main() -> Result<()> { // non-zero balance. dotenvy::dotenv().ok(); - let node_url = std::env::var("NODE_URL").unwrap(); - let explorer_url = std::env::var("EXPLORER_URL").unwrap(); - let faucet_url = std::env::var("FAUCET_URL").unwrap(); - - // Create a client instance. - let client = Client::builder().with_node(&node_url)?.finish().await?; + // Create a node client. + let client = Client::builder() + .with_node(&std::env::var("NODE_URL").unwrap())? + .finish() + .await?; let secret_manager = SecretManager::try_from_mnemonic(std::env::var("NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_1").unwrap())?; @@ -38,8 +40,11 @@ async fn main() -> Result<()> { let address = secret_manager .generate_ed25519_addresses(GetAddressesOptions::from_client(&client).await?.with_range(0..1)) .await?[0]; - println!("{}", request_funds_from_faucet(&faucet_url, &address).await?); - // Wait some time for the faucet transaction + + println!( + "Requesting funds (waiting 15s): {}", + request_funds_from_faucet(&std::env::var("FAUCET_URL").unwrap(), &address).await?, + ); tokio::time::sleep(std::time::Duration::from_secs(15)).await; let rent_structure = client.get_rent_structure().await?; @@ -65,9 +70,11 @@ async fn main() -> Result<()> { .await?; println!( - "Block with new alias outputs sent: {explorer_url}/block/{}", + "Block with new alias outputs sent: {}/block/{}", + std::env::var("EXPLORER_URL").unwrap(), block_1.id() ); + let _ = client.retry_until_included(&block_1.id(), None, None).await?; ////////////////////////////////// @@ -110,7 +117,8 @@ async fn main() -> Result<()> { .finish() .await?; println!( - "Block with alias id set and ownership assigned to the first alias sent: {explorer_url}/block/{}", + "Block with alias id set and ownership assigned to the first alias sent: {}/block/{}", + std::env::var("EXPLORER_URL").unwrap(), block_2.id() ); let _ = client.retry_until_included(&block_2.id(), None, None).await?; @@ -134,9 +142,11 @@ async fn main() -> Result<()> { .finish() .await?; println!( - "Block with state metadata of the third alias updated sent: {explorer_url}/block/{}", + "Block with state metadata of the third alias updated sent: {}/block/{}", + std::env::var("EXPLORER_URL").unwrap(), block_3.id() ); + let _ = client.retry_until_included(&block_3.id(), None, None).await?; ////////////////////////////////// @@ -157,9 +167,11 @@ async fn main() -> Result<()> { .finish() .await?; println!( - "Another block with state metadata of the third alias updated sent: {explorer_url}/block/{}", + "Another block with state metadata of the third alias updated sent: {}/block/{}", + std::env::var("EXPLORER_URL").unwrap(), block_3.id() ); + let _ = client.retry_until_included(&block_3.id(), None, None).await?; Ok(()) } diff --git a/sdk/examples/client/participation.rs b/sdk/examples/client/participation.rs index d1201a6a66..a6514e80b4 100644 --- a/sdk/examples/client/participation.rs +++ b/sdk/examples/client/participation.rs @@ -1,9 +1,17 @@ // Copyright 2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -//! TODO: Example description +//! This example shows how to participate in voting events. //! -//! `cargo run --example participation --features=participation --release` +//! Command to create an event: +//! curl -X POST http://localhost:14265/api/participation/v1/admin/events -H 'Content-Type: application/json' -d '{"name":"Shimmer Proposal","milestoneIndexCommence":580,"milestoneIndexStart":600,"milestoneIndexEnd":700,"payload":{"type":0,"questions":[{"text":"Should we be on CMC rank #1 eoy?","answers":[{"value":1,"text":"Yes","additionalInfo":""},{"value":2,"text":"No","additionalInfo":""}],"additionalInfo":""}]},"additionalInfo":"Nothing needed here"}' +//! Command to delete an event: +//! curl -X DELETE http://localhost:14265/api/participation/v1/admin/events/0x30bec90738f04b72e44ca853f98d90d19fb1c6b06eebdae3cc744439cbcb7e68 +//! +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --all-features --example participation +//! ``` use iota_sdk::{ client::{ @@ -18,20 +26,14 @@ use iota_sdk::{ #[tokio::main] async fn main() -> Result<()> { - // Command to create an event: - // curl -X POST http://localhost:14265/api/participation/v1/admin/events -H 'Content-Type: application/json' -d '{"name":"Shimmer Proposal","milestoneIndexCommence":580,"milestoneIndexStart":600,"milestoneIndexEnd":700,"payload":{"type":0,"questions":[{"text":"Should we be on CMC rank #1 eoy?","answers":[{"value":1,"text":"Yes","additionalInfo":""},{"value":2,"text":"No","additionalInfo":""}],"additionalInfo":""}]},"additionalInfo":"Nothing needed here"}' - // Command to delete an event: - // curl -X DELETE http://localhost:14265/api/participation/v1/admin/events/0x30bec90738f04b72e44ca853f98d90d19fb1c6b06eebdae3cc744439cbcb7e68 - - // Take the node URL from command line argument or use one from env as default. - let node_url = std::env::args().nth(1).unwrap_or_else(|| { - // This example uses secrets in environment variables for simplicity which should not be done in production. - dotenvy::dotenv().ok(); - std::env::var("NODE_URL").unwrap() - }); + // This example uses secrets in environment variables for simplicity which should not be done in production. + dotenvy::dotenv().ok(); - // Create a client with that node. - let client = Client::builder().with_node(&node_url)?.finish().await?; + // Create a node client. + let client = Client::builder() + .with_node(&std::env::var("NODE_URL").unwrap())? + .finish() + .await?; // Get the participation events. let events = client.events(None).await?; @@ -52,7 +54,11 @@ async fn main() -> Result<()> { .await?[0]; let faucet_url = std::env::var("FAUCET_URL").unwrap(); - request_funds_from_faucet(&faucet_url, &address).await?; + println!( + "Requesting funds (waiting 15s): {}", + request_funds_from_faucet(&faucet_url, &address).await? + ); + tokio::time::sleep(std::time::Duration::from_secs(15)).await; let address_participation = client.address_staking_status(address).await?; println!("{address_participation:#?}"); @@ -129,5 +135,6 @@ async fn participate(client: &Client, event_id: ParticipationEventId) -> Result< std::env::var("EXPLORER_URL").unwrap(), block.id() ); + Ok(()) } diff --git a/sdk/examples/client/quorum.rs b/sdk/examples/client/quorum.rs index 5fcfba1e38..4e5075b608 100644 --- a/sdk/examples/client/quorum.rs +++ b/sdk/examples/client/quorum.rs @@ -3,41 +3,58 @@ //! In this example we will get outputs with quorum, which will compare the responses from the nodes. //! -//! `cargo run --example quorum --release` +//! Make sure to have 3 nodes available for this example to run successfully, e.g.: +//! - http://localhost:14265 +//! - http://your-vps:14265 +//! - https://api.testnet.shimmer.network +//! +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example quorum +//! ``` -use iota_sdk::client::{node_api::indexer::query_parameters::QueryParameter, secret::SecretManager, Client, Result}; +use iota_sdk::client::{ + api::GetAddressesOptions, node_api::indexer::query_parameters::QueryParameter, secret::SecretManager, Client, + Result, +}; #[tokio::main] async fn main() -> Result<()> { // This example uses secrets in environment variables for simplicity which should not be done in production. dotenvy::dotenv().ok(); - let node_url = std::env::var("NODE_URL").unwrap(); + let node_1 = std::env::args().nth(1).expect("missing example argument: NODE 1"); + let node_2 = std::env::args().nth(2).expect("missing example argument: NODE 2"); + let node_3 = std::env::args().nth(3).expect("missing example argument: NODE 3"); + // Create a node client. let client = Client::builder() - .with_node("https://api.testnet.shimmer.network")? - .with_node(&node_url)? - .with_node("http://localhost:14265")? + .with_node(&node_1)? + .with_node(&node_2)? + .with_node(&node_3)? .with_quorum(true) .with_min_quorum_size(3) .with_quorum_threshold(66) - .finish()?; + .finish() + .await?; let secret_manager = SecretManager::try_from_mnemonic(std::env::var("NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_1").unwrap())?; // Generate the first address - let addresses = client - .get_addresses(&secret_manager) - .with_account_index(0) - .with_range(0..1) - .finish() + let addresses = secret_manager + .generate_ed25519_addresses( + GetAddressesOptions::from_client(&client) + .await? + .with_account_index(0) + .with_range(0..1), + ) .await?; // Get output ids of outputs that can be controlled by this address without further unlock constraints let output_ids_response = client .basic_output_ids([ - QueryParameter::Address(addresses[0].clone()), + QueryParameter::Address(addresses[0]), QueryParameter::HasExpiration(false), QueryParameter::HasTimelock(false), QueryParameter::HasStorageDepositReturn(false), diff --git a/sdk/examples/client/send_all.rs b/sdk/examples/client/send_all.rs index 9071c63af4..18c7799b9b 100644 --- a/sdk/examples/client/send_all.rs +++ b/sdk/examples/client/send_all.rs @@ -4,15 +4,17 @@ //! In this example we will get the outputs of the first address of the seed and send everything. //! Run the consolidation example first if there are more than 128 outputs. //! -//! `cargo run --example send_all --release` - -use iota_sdk::client::{ - block::output::{ - unlock_condition::AddressUnlockCondition, BasicOutputBuilder, NativeTokensBuilder, Output, UnlockCondition, +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example send_all +//! ``` + +use iota_sdk::{ + client::{ + api::GetAddressesOptions, node_api::indexer::query_parameters::QueryParameter, secret::SecretManager, Client, + Result, }, - node_api::indexer::query_parameters::QueryParameter, - secret::SecretManager, - Client, Result, + types::block::output::{unlock_condition::AddressUnlockCondition, BasicOutputBuilder, NativeTokensBuilder}, }; #[tokio::main] @@ -22,31 +24,27 @@ async fn main() -> Result<()> { // balance. dotenvy::dotenv().ok(); - let node_url = std::env::var("NODE_URL").unwrap(); - - // Create a client instance + // Create a node client. let client = Client::builder() - .with_node(&node_url)? // Insert your node URL here - .finish()?; + .with_node(&std::env::var("NODE_URL").unwrap())? + .finish() + .await?; let secret_manager_1 = SecretManager::try_from_mnemonic(std::env::var("NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_1").unwrap())?; let secret_manager_2 = - SecretManager::try_from_hex_seed(&std::env::var("NON_SECURE_USE_OF_DEVELOPMENT_SEED_2").unwrap())?; + SecretManager::try_from_mnemonic(std::env::var("NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_2").unwrap())?; let token_supply = client.get_token_supply().await?; + let address = secret_manager_1 + .generate_ed25519_addresses(GetAddressesOptions::from_client(&client).await?.with_range(0..1)) + .await?[0]; + // Get output ids of outputs that can be controlled by this address without further unlock constraints let output_ids_response = client .basic_output_ids([ - QueryParameter::Address( - client - .get_addresses(&secret_manager_1) - .with_range(0..1) - .finish() - .await?[0] - .clone(), - ), + QueryParameter::Address(address), QueryParameter::HasExpiration(false), QueryParameter::HasTimelock(false), QueryParameter::HasStorageDepositReturn(false), @@ -54,14 +52,14 @@ async fn main() -> Result<()> { .await?; // Get the outputs by their id - let outputs_responses = client.get_outputs(output_ids_response.items).await?; + let outputs_responses = client.get_outputs(&output_ids_response.items).await?; // Calculate the total amount and native tokens let mut total_amount = 0; let mut total_native_tokens = NativeTokensBuilder::new(); for output_response in outputs_responses { - let output = Output::try_from_dto(&output_response.output, token_supply)?; + let output = output_response.output(); if let Some(native_tokens) = output.native_tokens() { total_native_tokens.add_native_tokens(native_tokens.clone())?; @@ -73,14 +71,12 @@ async fn main() -> Result<()> { println!("Total amount: {total_amount}"); + let address = secret_manager_2 + .generate_ed25519_addresses(GetAddressesOptions::from_client(&client).await?.with_range(0..1)) + .await?[0]; + let mut basic_output_builder = - BasicOutputBuilder::new_with_amount(total_amount)?.add_unlock_condition(AddressUnlockCondition::new( - client - .get_addresses(&secret_manager_2) - .with_range(0..1) - .get_raw() - .await?[0], - )); + BasicOutputBuilder::new_with_amount(total_amount).add_unlock_condition(AddressUnlockCondition::new(address)); for native_token in total_native_tokens { basic_output_builder = basic_output_builder.add_native_token(native_token); diff --git a/sdk/examples/client/split_funds.rs b/sdk/examples/client/split_funds.rs index 3f161830ed..e5c80fbf2a 100644 --- a/sdk/examples/client/split_funds.rs +++ b/sdk/examples/client/split_funds.rs @@ -3,9 +3,12 @@ //! In this example we will send 100 basic outputs to our first address. //! -//! `cargo run --example split_funds --release` +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example client_split_funds +//! ``` -use iota_sdk::client::{request_funds_from_faucet, secret::SecretManager, Client, Result}; +use iota_sdk::client::{api::GetAddressesOptions, request_funds_from_faucet, secret::SecretManager, Client, Result}; #[tokio::main] async fn main() -> Result<()> { @@ -14,33 +17,29 @@ async fn main() -> Result<()> { // balance. dotenvy::dotenv().ok(); - let node_url = std::env::var("NODE_URL").unwrap(); - let faucet_url = std::env::var("FAUCET_URL").unwrap(); - - let client = Client::builder().with_node(&node_url)?.finish().await?; + // Create a node client. + let client = Client::builder() + .with_node(&std::env::var("NODE_URL").unwrap())? + .finish() + .await?; let secret_manager = SecretManager::try_from_mnemonic(std::env::var("NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_1").unwrap())?; - let address = client.get_addresses(&secret_manager).with_range(0..1).get_raw().await?[0]; + let address = secret_manager + .generate_ed25519_addresses(GetAddressesOptions::from_client(&client).await?.with_range(0..1)) + .await?[0]; println!( - "{}", - request_funds_from_faucet(&faucet_url, &address.to_bech32(client.get_bech32_hrp().await?)).await? + "Requesting funds (waiting 15s): {}", + request_funds_from_faucet(&std::env::var("FAUCET_URL").unwrap(), &address,).await? ); - // wait so the faucet can send the funds - // tokio::time::sleep(std::time::Duration::from_secs(20)).await; + tokio::time::sleep(std::time::Duration::from_secs(15)).await; let mut block_builder = client.block().with_secret_manager(&secret_manager); // Insert the output address and amount to spent. The amount cannot be zero. for _ in 0..100 { - block_builder = block_builder - .with_output( - // We generate an address from our seed so that we send the funds to ourselves - &client.get_addresses(&secret_manager).with_range(0..1).finish().await?[0], - 1_000_000, - ) - .await?; + block_builder = block_builder.with_output(address, 1_000_000).await?; } let block = block_builder.finish().await?; @@ -49,5 +48,6 @@ async fn main() -> Result<()> { std::env::var("EXPLORER_URL").unwrap(), block.id() ); + Ok(()) } diff --git a/sdk/examples/client/stronghold.rs b/sdk/examples/client/stronghold.rs index c5d6f3c01e..5512a660f9 100644 --- a/sdk/examples/client/stronghold.rs +++ b/sdk/examples/client/stronghold.rs @@ -3,7 +3,10 @@ //! In this example we will create an address with a stronghold secret manager. //! -//! `cargo run --example stronghold --features=stronghold --release` +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --all-features --example client_stronghold +//! ``` use iota_sdk::client::{ api::GetAddressesOptions, @@ -20,7 +23,9 @@ async fn main() -> Result<()> { // This example uses secrets in environment variables for simplicity which should not be done in production. dotenvy::dotenv().ok(); + let mnemonic = std::env::var("NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_1").unwrap(); + // The mnemonic only needs to be stored the first time stronghold_secret_manager.store_mnemonic(mnemonic).await?; diff --git a/sdk/examples/client/tagged_data_to_utf8.rs b/sdk/examples/client/tagged_data_to_utf8.rs index a187c35909..9660384ea7 100644 --- a/sdk/examples/client/tagged_data_to_utf8.rs +++ b/sdk/examples/client/tagged_data_to_utf8.rs @@ -2,17 +2,23 @@ // SPDX-License-Identifier: Apache-2.0 //! In this example we will UTF-8 encode the tag and the data of an `TaggedDataPayload`. -//! -//! `cargo run --example tagged_data_to_utf8 --release` +//! +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --example tagged_data_to_utf8 +//! ``` -use iota_sdk::client::{block::payload::TaggedDataPayload, Client, Result}; +use iota_sdk::{ + client::{Client, Result}, + types::block::payload::TaggedDataPayload, +}; #[tokio::main] async fn main() -> Result<()> { // `hello` in hexadecimal. - let tag = prefix_hex::decode("0x68656c6c6f")?; + let tag = prefix_hex::decode::>("0x68656c6c6f")?; // `world` in hexadecimal. - let data = prefix_hex::decode("0x776f726c64")?; + let data = prefix_hex::decode::>("0x776f726c64")?; let (tag_utf8, data_utf8) = Client::tagged_data_to_utf8(&TaggedDataPayload::new(tag, data)?)?; diff --git a/sdk/examples/how_tos/accounts_and_addresses/check_balance.rs b/sdk/examples/how_tos/accounts_and_addresses/check_balance.rs index eb2506d5ad..b9d7794add 100644 --- a/sdk/examples/how_tos/accounts_and_addresses/check_balance.rs +++ b/sdk/examples/how_tos/accounts_and_addresses/check_balance.rs @@ -3,16 +3,14 @@ //! In this example we sync the account and get the balance. //! -//! Make sure that `example.stronghold` and `example.walletdb` already exist by -//! running the `create_account` example! +//! Make sure that `STRONGHOLD_SNAPSHOT_PATH` and `WALLET_DB_PATH` already exist by +//! running the `./how_tos/accounts_and_addresses/create_account.rs` example! //! //! Rename `.env.example` to `.env` first, then run the command: //! ```sh //! cargo run --release --all-features --example check_balance //! ``` -use std::env::var; - use iota_sdk::{wallet::Result, Wallet}; #[tokio::main] @@ -21,7 +19,7 @@ async fn main() -> Result<()> { dotenvy::dotenv().ok(); let wallet = Wallet::builder() - .with_storage_path(&var("WALLET_DB_PATH").unwrap()) + .with_storage_path(&std::env::var("WALLET_DB_PATH").unwrap()) .finish() .await?; let account = wallet.get_account("Alice").await?; @@ -31,7 +29,7 @@ async fn main() -> Result<()> { println!("{balance:#?}"); println!("ADDRESSES:"); - let explorer_url = var("EXPLORER_URL").ok(); + let explorer_url = std::env::var("EXPLORER_URL").ok(); let prepended = explorer_url.map(|url| format!("{url}/addr/")).unwrap_or_default(); for address in account.addresses().await? { println!(" - {prepended}{}", address.address()); diff --git a/sdk/examples/how_tos/accounts_and_addresses/consolidate_outputs.rs b/sdk/examples/how_tos/accounts_and_addresses/consolidate_outputs.rs index 7abc19e420..176babf5ef 100644 --- a/sdk/examples/how_tos/accounts_and_addresses/consolidate_outputs.rs +++ b/sdk/examples/how_tos/accounts_and_addresses/consolidate_outputs.rs @@ -4,16 +4,14 @@ //! In this example we will consolidate basic outputs from an account with only an AddressUnlockCondition by sending //! them to the same address again. //! -//! Make sure that `example.stronghold` and `example.walletdb` already exist by -//! running the `create_account` example! +//! Make sure that `STRONGHOLD_SNAPSHOT_PATH` and `WALLET_DB_PATH` already exist by +//! running the `./how_tos/accounts_and_addresses/create_account.rs` example! //! //! Rename `.env.example` to `.env` first, then run the command: //! ```sh //! cargo run --release --all-features --example consolidate_outputs //! ``` -use std::env::var; - use iota_sdk::{types::block::address::ToBech32Ext, wallet::Result, Wallet}; #[tokio::main] @@ -22,14 +20,14 @@ async fn main() -> Result<()> { dotenvy::dotenv().ok(); let wallet = Wallet::builder() - .with_storage_path(&var("WALLET_DB_PATH").unwrap()) + .with_storage_path(&std::env::var("WALLET_DB_PATH").unwrap()) .finish() .await?; let account = wallet.get_account("Alice").await?; // Set the stronghold password wallet - .set_stronghold_password(var("STRONGHOLD_PASSWORD").unwrap()) + .set_stronghold_password(std::env::var("STRONGHOLD_PASSWORD").unwrap()) .await?; // Sync account to make sure account is updated with outputs from previous examples @@ -65,8 +63,8 @@ async fn main() -> Result<()> { .retry_transaction_until_included(&transaction.transaction_id, None, None) .await?; println!( - "Transaction included: {}/block/{}", - var("EXPLORER_URL").unwrap(), + "Block included: {}/block/{}", + std::env::var("EXPLORER_URL").unwrap(), block_id ); diff --git a/sdk/examples/how_tos/accounts_and_addresses/create_account.rs b/sdk/examples/how_tos/accounts_and_addresses/create_account.rs index ce576351b7..6999552653 100644 --- a/sdk/examples/how_tos/accounts_and_addresses/create_account.rs +++ b/sdk/examples/how_tos/accounts_and_addresses/create_account.rs @@ -3,15 +3,13 @@ //! In this example we will create a new wallet. //! -//! Make sure there's no `example.stronghold` file and no `example.walletdb` folder yet! +//! Make sure there's no `STRONGHOLD_SNAPSHOT_PATH` file and no `WALLET_DB_PATH` folder yet! //! //! Rename `.env.example` to `.env` first, then run the command: //! ```sh //! cargo run --release --all-features --example create_account //! ``` -use std::env::var; - use iota_sdk::{ client::{ constants::SHIMMER_COIN_TYPE, @@ -27,21 +25,21 @@ async fn main() -> Result<()> { // Setup Stronghold secret_manager let secret_manager = StrongholdSecretManager::builder() - .password(var("STRONGHOLD_PASSWORD").unwrap()) - .build(var("STRONGHOLD_SNAPSHOT_PATH").unwrap())?; + .password(std::env::var("STRONGHOLD_PASSWORD").unwrap()) + .build(std::env::var("STRONGHOLD_SNAPSHOT_PATH").unwrap())?; // Only required the first time, can also be generated with `manager.generate_mnemonic()?` - let mnemonic = var("NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_1").unwrap(); + let mnemonic = std::env::var("NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_1").unwrap(); // The mnemonic only needs to be stored the first time secret_manager.store_mnemonic(mnemonic).await?; - let client_options = ClientOptions::new().with_node(&var("NODE_URL").unwrap())?; + let client_options = ClientOptions::new().with_node(&std::env::var("NODE_URL").unwrap())?; // Create the wallet let wallet = Wallet::builder() .with_secret_manager(SecretManager::Stronghold(secret_manager)) - .with_storage_path(&var("WALLET_DB_PATH").unwrap()) + .with_storage_path(&std::env::var("WALLET_DB_PATH").unwrap()) .with_client_options(client_options) .with_coin_type(SHIMMER_COIN_TYPE) .finish() diff --git a/sdk/examples/how_tos/accounts_and_addresses/create_address.rs b/sdk/examples/how_tos/accounts_and_addresses/create_address.rs index f34d9218f0..0ea29cb5e8 100644 --- a/sdk/examples/how_tos/accounts_and_addresses/create_address.rs +++ b/sdk/examples/how_tos/accounts_and_addresses/create_address.rs @@ -3,16 +3,14 @@ //! In this example we will generate addresses for an already existing wallet. //! -//! Make sure that `example.stronghold` and `example.walletdb` already exist by -//! running the `create_account` example! +//! Make sure that `STRONGHOLD_SNAPSHOT_PATH` and `WALLET_DB_PATH` already exist by +//! running the `./how_tos/accounts_and_addresses/create_account.rs` example! //! //! Rename `.env.example` to `.env` first, then run the command: //! ```sh //! cargo run --release --all-features --example create_address` //! ``` -use std::env::var; - use iota_sdk::{wallet::Result, Wallet}; // The number of addresses to generate @@ -24,17 +22,17 @@ async fn main() -> Result<()> { dotenvy::dotenv().ok(); let wallet = Wallet::builder() - .with_storage_path(&var("WALLET_DB_PATH").unwrap()) + .with_storage_path(&std::env::var("WALLET_DB_PATH").unwrap()) .finish() .await?; let account = wallet.get_account("Alice").await?; // Provide the stronghold password wallet - .set_stronghold_password(var("STRONGHOLD_PASSWORD").unwrap()) + .set_stronghold_password(std::env::var("STRONGHOLD_PASSWORD").unwrap()) .await?; - let explorer_url = var("EXPLORER_URL").ok(); + let explorer_url = std::env::var("EXPLORER_URL").ok(); let address_url = explorer_url.map(|url| format!("{url}/addr/")).unwrap_or_default(); println!("Current addresses:"); diff --git a/sdk/examples/how_tos/accounts_and_addresses/list_accounts.rs b/sdk/examples/how_tos/accounts_and_addresses/list_accounts.rs index 51ea518404..ffc57e6e45 100644 --- a/sdk/examples/how_tos/accounts_and_addresses/list_accounts.rs +++ b/sdk/examples/how_tos/accounts_and_addresses/list_accounts.rs @@ -8,8 +8,6 @@ //! cargo run --release --all-features --example list_accounts //! ``` -use std::env::var; - use iota_sdk::{wallet::Result, Wallet}; #[tokio::main] @@ -18,7 +16,7 @@ async fn main() -> Result<()> { dotenvy::dotenv().ok(); let wallet = Wallet::builder() - .with_storage_path(&var("WALLET_DB_PATH").unwrap()) + .with_storage_path(&std::env::var("WALLET_DB_PATH").unwrap()) .finish() .await?; diff --git a/sdk/examples/how_tos/accounts_and_addresses/list_addresses.rs b/sdk/examples/how_tos/accounts_and_addresses/list_addresses.rs index a1ee416afb..b4ef1f315f 100644 --- a/sdk/examples/how_tos/accounts_and_addresses/list_addresses.rs +++ b/sdk/examples/how_tos/accounts_and_addresses/list_addresses.rs @@ -8,8 +8,6 @@ //! cargo run --release --all-features --example list_addresses //! ``` -use std::env::var; - use iota_sdk::{wallet::Result, Wallet}; #[tokio::main] @@ -18,7 +16,7 @@ async fn main() -> Result<()> { dotenvy::dotenv().ok(); let wallet = Wallet::builder() - .with_storage_path(&var("WALLET_DB_PATH").unwrap()) + .with_storage_path(&std::env::var("WALLET_DB_PATH").unwrap()) .finish() .await?; let account = wallet.get_account("Alice").await?; diff --git a/sdk/examples/how_tos/accounts_and_addresses/list_outputs.rs b/sdk/examples/how_tos/accounts_and_addresses/list_outputs.rs index 044c86c0ed..3593cbd5ee 100644 --- a/sdk/examples/how_tos/accounts_and_addresses/list_outputs.rs +++ b/sdk/examples/how_tos/accounts_and_addresses/list_outputs.rs @@ -8,8 +8,6 @@ //! cargo run --release --all-features --example list_outputs //! ``` -use std::env::var; - use iota_sdk::{wallet::Result, Wallet}; #[tokio::main] @@ -18,7 +16,7 @@ async fn main() -> Result<()> { dotenvy::dotenv().ok(); let wallet = Wallet::builder() - .with_storage_path(&var("WALLET_DB_PATH").unwrap()) + .with_storage_path(&std::env::var("WALLET_DB_PATH").unwrap()) .finish() .await?; let account = wallet.get_account("Alice").await?; diff --git a/sdk/examples/how_tos/accounts_and_addresses/list_transactions.rs b/sdk/examples/how_tos/accounts_and_addresses/list_transactions.rs index 8a9f871d36..59b46f5044 100644 --- a/sdk/examples/how_tos/accounts_and_addresses/list_transactions.rs +++ b/sdk/examples/how_tos/accounts_and_addresses/list_transactions.rs @@ -8,8 +8,6 @@ //! cargo run --release --all-features --example list_transactions //! ``` -use std::env::var; - use iota_sdk::{ wallet::{account::SyncOptions, Result}, Wallet, @@ -21,7 +19,7 @@ async fn main() -> Result<()> { dotenvy::dotenv().ok(); let wallet = Wallet::builder() - .with_storage_path(&var("WALLET_DB_PATH").unwrap()) + .with_storage_path(&std::env::var("WALLET_DB_PATH").unwrap()) .finish() .await?; let account = wallet.get_account("Alice").await?; diff --git a/sdk/examples/how_tos/advanced_transactions/advanced_transaction.rs b/sdk/examples/how_tos/advanced_transactions/advanced_transaction.rs index d5a7061205..8de70aff0e 100644 --- a/sdk/examples/how_tos/advanced_transactions/advanced_transaction.rs +++ b/sdk/examples/how_tos/advanced_transactions/advanced_transaction.rs @@ -6,8 +6,6 @@ //! //! `cargo run --release --all-features --example advanced_transaction` -use std::time::{Duration, SystemTime, UNIX_EPOCH}; - use iota_sdk::{ types::block::{ address::Bech32Address, @@ -40,8 +38,8 @@ async fn main() -> Result<()> { .await?; // Create an ouput with amount 1_000_000 and a timelock of 1 hour - let in_an_hour = (SystemTime::now() + Duration::from_secs(3600)) - .duration_since(UNIX_EPOCH) + let in_an_hour = (std::time::SystemTime::now() + std::time::Duration::from_secs(3600)) + .duration_since(std::time::UNIX_EPOCH) .expect("clock went backwards") .as_secs() .try_into() diff --git a/sdk/examples/how_tos/advanced_transactions/send_micro_transaction.rs b/sdk/examples/how_tos/advanced_transactions/send_micro_transaction.rs index c07c8b412b..2bef2983ca 100644 --- a/sdk/examples/how_tos/advanced_transactions/send_micro_transaction.rs +++ b/sdk/examples/how_tos/advanced_transactions/send_micro_transaction.rs @@ -3,16 +3,14 @@ //! In this example we will send an amount below the minimum storage deposit. //! -//! Make sure that `example.stronghold` and `example.walletdb` already exist by -//! running the `create_account` example! +//! Make sure that `STRONGHOLD_SNAPSHOT_PATH` and `WALLET_DB_PATH` already exist by +//! running the `./how_tos/accounts_and_addresses/create_account.rs` example! //! //! Rename `.env.example` to `.env` first, then run the command: //! ```sh //! cargo run --release --all-features --example send_micro_transaction //! ``` -use std::env::var; - use iota_sdk::{ wallet::{account::TransactionOptions, Result, SendAmountParams}, Wallet, @@ -29,7 +27,7 @@ async fn main() -> Result<()> { dotenvy::dotenv().ok(); let wallet = Wallet::builder() - .with_storage_path(&var("WALLET_DB_PATH").unwrap()) + .with_storage_path(&std::env::var("WALLET_DB_PATH").unwrap()) .finish() .await?; let account = wallet.get_account("Alice").await?; @@ -39,7 +37,7 @@ async fn main() -> Result<()> { // Set the stronghold password wallet - .set_stronghold_password(var("STRONGHOLD_PASSWORD").unwrap()) + .set_stronghold_password(std::env::var("STRONGHOLD_PASSWORD").unwrap()) .await?; println!("Sending '{}' coin(s) to '{}'...", SEND_MICRO_AMOUNT, RECV_ADDRESS); @@ -63,7 +61,11 @@ async fn main() -> Result<()> { .retry_transaction_until_included(&transaction.transaction_id, None, None) .await?; - println!("Block included: {}/block/{}", var("EXPLORER_URL").unwrap(), block_id); + println!( + "Block included: {}/block/{}", + std::env::var("EXPLORER_URL").unwrap(), + block_id + ); Ok(()) } diff --git a/sdk/examples/how_tos/alias_wallet/request_funds.rs b/sdk/examples/how_tos/alias_wallet/request_funds.rs index ca2478a9f7..731636dece 100644 --- a/sdk/examples/how_tos/alias_wallet/request_funds.rs +++ b/sdk/examples/how_tos/alias_wallet/request_funds.rs @@ -6,8 +6,6 @@ //! //! `cargo run --release --all-features --example alias_wallet_request_funds` -use std::env::var; - use iota_sdk::{ client::request_funds_from_faucet, types::block::address::{AliasAddress, ToBech32Ext}, @@ -23,11 +21,11 @@ async fn main() -> Result<()> { // This example uses secrets in environment variables for simplicity which should not be done in production. dotenvy::dotenv().ok(); - let faucet_url = var("FAUCET_URL").unwrap(); + let faucet_url = std::env::var("FAUCET_URL").unwrap(); // Create the wallet let wallet = Wallet::builder() - .with_storage_path(&var("WALLET_DB_PATH").unwrap()) + .with_storage_path(&std::env::var("WALLET_DB_PATH").unwrap()) .finish() .await?; diff --git a/sdk/examples/how_tos/alias_wallet/transaction.rs b/sdk/examples/how_tos/alias_wallet/transaction.rs index 52432702c0..12290c1008 100644 --- a/sdk/examples/how_tos/alias_wallet/transaction.rs +++ b/sdk/examples/how_tos/alias_wallet/transaction.rs @@ -6,8 +6,6 @@ //! //! `cargo run --release --all-features --example alias_wallet_transaction` -use std::env::var; - use iota_sdk::{ client::node_api::indexer::query_parameters::QueryParameter, types::block::address::{AliasAddress, ToBech32Ext}, @@ -33,11 +31,11 @@ async fn main() -> Result<()> { // Create the wallet let wallet = Wallet::builder() - .with_storage_path(&var("WALLET_DB_PATH").unwrap()) + .with_storage_path(&std::env::var("WALLET_DB_PATH").unwrap()) .finish() .await?; wallet - .set_stronghold_password(var("STRONGHOLD_PASSWORD").unwrap()) + .set_stronghold_password(std::env::var("STRONGHOLD_PASSWORD").unwrap()) .await?; // Get the account diff --git a/sdk/examples/how_tos/client/get_health.rs b/sdk/examples/how_tos/client/get_health.rs index aec5e2a5d5..ab0a68262d 100644 --- a/sdk/examples/how_tos/client/get_health.rs +++ b/sdk/examples/how_tos/client/get_health.rs @@ -1,22 +1,26 @@ // Copyright 2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -//! This example returns the health of the node by calling `GET /health`. +//! This example returns the health of the node by querying its `/health` endpoint. //! -//! `cargo run --example node_api_core_get_health --release -- [NODE URL]` +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --all-features --example get_health [NODE_URL] +//! ``` use iota_sdk::client::{Client, Result}; #[tokio::main] async fn main() -> Result<()> { + // If not provided we use the default node from the `.env` file. + dotenvy::dotenv().ok(); + // Take the node URL from command line argument or use one from env as default. - let node_url = std::env::args().nth(1).unwrap_or_else(|| { - // This example uses secrets in environment variables for simplicity which should not be done in production. - dotenvy::dotenv().ok(); - std::env::var("NODE_URL").unwrap() - }); + let node_url = std::env::args() + .nth(1) + .unwrap_or_else(|| std::env::var("NODE_URL").unwrap()); - // Create a client with that node. + // Create a node client. let client = Client::builder() .with_node(&node_url)? .with_ignore_node_health() diff --git a/sdk/examples/how_tos/client/get_info.rs b/sdk/examples/how_tos/client/get_info.rs index 832d6168cf..cbfabd8199 100644 --- a/sdk/examples/how_tos/client/get_info.rs +++ b/sdk/examples/how_tos/client/get_info.rs @@ -1,22 +1,26 @@ // Copyright 2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -//! Returns general information about the node by calling `GET /api/core/v2/info`. +//! Returns general information about the node by querying its `/api/core/v2/info` endpoint. //! -//! `cargo run --release --example get_info -- [NODE URL]` +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --all-features --example get_info [NODE URL] +//! ``` use iota_sdk::client::{Client, Result}; #[tokio::main] async fn main() -> Result<()> { + // If not provided we use the default node from the `.env` file. + dotenvy::dotenv().ok(); + // Take the node URL from command line argument or use one from env as default. - let node_url = std::env::args().nth(1).unwrap_or_else(|| { - // This example uses secrets in environment variables for simplicity which should not be done in production. - dotenvy::dotenv().ok(); - std::env::var("NODE_URL").unwrap() - }); + let node_url = std::env::args() + .nth(1) + .unwrap_or_else(|| std::env::var("NODE_URL").unwrap()); - // Create a client with that node. + // Create a node client. let client = Client::builder() .with_node(&node_url)? .with_ignore_node_health() diff --git a/sdk/examples/how_tos/client/get_outputs.rs b/sdk/examples/how_tos/client/get_outputs.rs index 10f0874443..7711a1d990 100644 --- a/sdk/examples/how_tos/client/get_outputs.rs +++ b/sdk/examples/how_tos/client/get_outputs.rs @@ -1,10 +1,16 @@ // Copyright 2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -//! TODO: by calling -//! `GET api/indexer/v1/outputs/basic`. +//! Gets all basic output ids accociated with an address by querying the +//! `api/indexer/v1/outputs/basic` node endpoint. //! -//! `cargo run --release --example get_outputs -- [NODE_URL] [ADDRESS]`. +//! Make sure that the node has the indexer plugin enabled. +//! Make sure to provide a somewhat recently used address to make this example run successfully! +//! +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --all-features --example get_outputs [ADDRESS] [NODE_URL] +//! ``` use iota_sdk::{ client::{node_api::indexer::query_parameters::QueryParameter, Client, Result}, @@ -13,24 +19,21 @@ use iota_sdk::{ #[tokio::main] async fn main() -> Result<()> { + // This example uses secrets in environment variables for simplicity which should not be done in production. + dotenvy::dotenv().ok(); + // Take the node URL from command line argument or use one from env as default. - let node_url = std::env::args().nth(1).unwrap_or_else(|| { - // This example uses secrets in environment variables for simplicity which should not be done in production. - dotenvy::dotenv().ok(); - std::env::var("NODE_URL").unwrap() - }); - - // Create a client with that node. - let client = Client::builder() - // The node needs to have the indexer plugin enabled. - .with_node(&node_url)? - .finish() - .await?; + let node_url = std::env::args() + .nth(2) + .unwrap_or_else(|| std::env::var("NODE_URL").unwrap()); + + // Create a node client. + let client = Client::builder().with_node(&node_url)?.finish().await?; // Take the address from command line argument or use a default one. let address = Bech32Address::try_from_str( std::env::args() - .nth(2) + .nth(1) .as_deref() .unwrap_or("rms1qpllaj0pyveqfkwxmnngz2c488hfdtmfrj3wfkgxtk4gtyrax0jaxzt70zy"), )?; diff --git a/sdk/examples/how_tos/native_tokens/burn.rs b/sdk/examples/how_tos/native_tokens/burn.rs index 4aebcd6498..c74f0b52f8 100644 --- a/sdk/examples/how_tos/native_tokens/burn.rs +++ b/sdk/examples/how_tos/native_tokens/burn.rs @@ -5,8 +5,8 @@ //! therefore the foundry output is also not required. But this will also make it impossible to destroy the foundry //! output that minted it. //! -//! Make sure that `example.stronghold` and `example.walletdb` already exist by -//! running the `create_account` example! +//! Make sure that `STRONGHOLD_SNAPSHOT_PATH` and `WALLET_DB_PATH` already exist by +//! running the `./how_tos/accounts_and_addresses/create_account.rs` example! //! //! You may provide a TOKEN_ID that is available in the account. You can check this by running the //! `get_balance` example. You can create a new native token by running the `create_native_token` example. diff --git a/sdk/examples/how_tos/native_tokens/create.rs b/sdk/examples/how_tos/native_tokens/create.rs index 5fcb45e240..5aa47936fa 100644 --- a/sdk/examples/how_tos/native_tokens/create.rs +++ b/sdk/examples/how_tos/native_tokens/create.rs @@ -11,8 +11,6 @@ //! cargo run --release --all-features --example create_native_token //! ``` -use std::env::var; - use iota_sdk::{ wallet::{CreateNativeTokenParams, Result}, Wallet, U256, @@ -29,7 +27,7 @@ async fn main() -> Result<()> { dotenvy::dotenv().ok(); let wallet = Wallet::builder() - .with_storage_path(&var("WALLET_DB_PATH").unwrap()) + .with_storage_path(&std::env::var("WALLET_DB_PATH").unwrap()) .finish() .await?; let account = wallet.get_account("Alice").await?; @@ -37,7 +35,7 @@ async fn main() -> Result<()> { // Set the stronghold password wallet - .set_stronghold_password(var("STRONGHOLD_PASSWORD").unwrap()) + .set_stronghold_password(std::env::var("STRONGHOLD_PASSWORD").unwrap()) .await?; // We can first check if we already have an alias in our account, because an alias can have many foundry outputs and @@ -51,7 +49,11 @@ async fn main() -> Result<()> { let block_id = account .retry_transaction_until_included(&transaction.transaction_id, None, None) .await?; - println!("Block included: {}/block/{}", var("EXPLORER_URL").unwrap(), block_id); + println!( + "Block included: {}/block/{}", + std::env::var("EXPLORER_URL").unwrap(), + block_id + ); account.sync(None).await?; println!("Account synced"); @@ -73,7 +75,11 @@ async fn main() -> Result<()> { let block_id = account .retry_transaction_until_included(&transaction.transaction.transaction_id, None, None) .await?; - println!("Block included: {}/block/{}", var("EXPLORER_URL").unwrap(), block_id); + println!( + "Block included: {}/block/{}", + std::env::var("EXPLORER_URL").unwrap(), + block_id + ); println!("Created token: {}", transaction.token_id); // Ensure the account is synced after creating the native token. diff --git a/sdk/examples/how_tos/native_tokens/destroy_foundry.rs b/sdk/examples/how_tos/native_tokens/destroy_foundry.rs index e53438db12..ef51b7d795 100644 --- a/sdk/examples/how_tos/native_tokens/destroy_foundry.rs +++ b/sdk/examples/how_tos/native_tokens/destroy_foundry.rs @@ -4,16 +4,14 @@ //! In this example we will try to destroy the first foundry there is in the account. This is only possible if its //! circulating supply is 0 and no native tokens were burned. //! -//! Make sure that `example.stronghold` and `example.walletdb` already exist by -//! running the `create_account` example! +//! Make sure that `STRONGHOLD_SNAPSHOT_PATH` and `WALLET_DB_PATH` already exist by +//! running the `./how_tos/accounts_and_addresses/create_account.rs` example! //! //! Rename `.env.example` to `.env` first, then run the command: //! ```sh //! cargo run --release --all-features --example destroy_foundry //! ``` -use std::env::var; - use iota_sdk::{wallet::Result, Wallet}; #[tokio::main] @@ -22,7 +20,7 @@ async fn main() -> Result<()> { dotenvy::dotenv().ok(); let wallet = Wallet::builder() - .with_storage_path(&var("WALLET_DB_PATH").unwrap()) + .with_storage_path(&std::env::var("WALLET_DB_PATH").unwrap()) .finish() .await?; let alias = "Alice"; @@ -38,7 +36,7 @@ async fn main() -> Result<()> { // Set the stronghold password wallet - .set_stronghold_password(var("STRONGHOLD_PASSWORD").unwrap()) + .set_stronghold_password(std::env::var("STRONGHOLD_PASSWORD").unwrap()) .await?; let transaction = account.burn(*foundry_id, None).await?; @@ -47,7 +45,11 @@ async fn main() -> Result<()> { let block_id = account .retry_transaction_until_included(&transaction.transaction_id, None, None) .await?; - println!("Block included: {}/block/{}", var("EXPLORER_URL").unwrap(), block_id); + println!( + "Block included: {}/block/{}", + std::env::var("EXPLORER_URL").unwrap(), + block_id + ); let foundry_count = balance.foundries().len(); println!("Foundries after destroying: {foundry_count}"); diff --git a/sdk/examples/how_tos/native_tokens/melt.rs b/sdk/examples/how_tos/native_tokens/melt.rs index 6027d0e37d..61364f0a5a 100644 --- a/sdk/examples/how_tos/native_tokens/melt.rs +++ b/sdk/examples/how_tos/native_tokens/melt.rs @@ -3,8 +3,8 @@ //! In this example we will melt an existing native token with its foundry. //! -//! Make sure that `example.stronghold` and `example.walletdb` already exist by -//! running the `create_account` example! +//! Make sure that `STRONGHOLD_SNAPSHOT_PATH` and `WALLET_DB_PATH` already exist by +//! running the `./how_tos/accounts_and_addresses/create_account.rs` example! //! //! You may provide a TOKEN_ID that is available in the account. The foundry //! output which minted it needs to be available as well. You can check this by @@ -33,9 +33,7 @@ async fn main() -> Result<()> { let account = wallet.get_account("Alice").await?; // May want to ensure the account is synced before sending a transaction. - account.sync(None).await?; - - let balance = account.balance().await?; + let balance = account.sync(None).await?; // Find first foundry and corresponding token id let token_id = std::env::args() diff --git a/sdk/examples/how_tos/native_tokens/mint.rs b/sdk/examples/how_tos/native_tokens/mint.rs index c604d7b3c2..8c3b3ea37e 100644 --- a/sdk/examples/how_tos/native_tokens/mint.rs +++ b/sdk/examples/how_tos/native_tokens/mint.rs @@ -3,8 +3,8 @@ //! In this example we will mint an existing native token with its foundry. //! -//! Make sure that `example.stronghold` and `example.walletdb` already exist by -//! running the `create_account` example! +//! Make sure that `STRONGHOLD_SNAPSHOT_PATH` and `WALLET_DB_PATH` already exist by +//! running the `./how_tos/accounts_and_addresses/create_account.rs` example! //! //! You may provide a TOKEN_ID that is available in the account. The foundry //! output which minted it needs to be available as well. You can check this by @@ -35,24 +35,28 @@ async fn main() -> Result<()> { // May want to ensure the account is synced before sending a transaction. let balance = account.sync(None).await?; - // Set the stronghold password - wallet - .set_stronghold_password(std::env::var("STRONGHOLD_PASSWORD").unwrap()) - .await?; - // Find first foundry and corresponding token id let token_id = std::env::args() .nth(1) .map(|s| s.parse::().expect("invalid token id")) .unwrap_or_else(|| TokenId::from(*balance.foundries().first().unwrap())); - let available_balance = balance + if let Some(native_token_balance) = balance .native_tokens() .iter() - .find(|t| t.token_id() == &token_id) - .unwrap() - .available(); - println!("Balance before minting: {available_balance}",); + .find(|native_token| native_token.token_id() == &token_id) + { + let available_balance = native_token_balance.available(); + println!("Balance before minting: {available_balance}"); + } else { + println!("Couldn't find native token '{token_id}' in the account"); + return Ok(()); + } + + // Set the stronghold password + wallet + .set_stronghold_password(std::env::var("STRONGHOLD_PASSWORD").unwrap()) + .await?; // Mint some more native tokens let mint_amount = U256::from(MINT_AMOUNT); @@ -62,6 +66,7 @@ async fn main() -> Result<()> { let block_id = account .retry_transaction_until_included(&transaction.transaction_id, None, None) .await?; + println!( "Block included: {}/block/{}", std::env::var("EXPLORER_URL").unwrap(), diff --git a/sdk/examples/how_tos/native_tokens/send.rs b/sdk/examples/how_tos/native_tokens/send.rs index 5218fafbea..778c9c1159 100644 --- a/sdk/examples/how_tos/native_tokens/send.rs +++ b/sdk/examples/how_tos/native_tokens/send.rs @@ -3,16 +3,14 @@ //! In this example we will send native tokens. //! -//! Make sure that `example.stronghold` and `example.walletdb` already exist by -//! running the `create_account` example! +//! Make sure that `STRONGHOLD_SNAPSHOT_PATH` and `WALLET_DB_PATH` already exist by +//! running the `./how_tos/accounts_and_addresses/create_account.rs` example! //! //! Rename `.env.example` to `.env` first, then run the command: //! ```sh //! cargo run --release --all-features --example send_native_tokens //! ``` -use std::env::var; - use iota_sdk::{ types::block::address::Bech32Address, wallet::{Result, SendNativeTokensParams}, @@ -31,7 +29,7 @@ async fn main() -> Result<()> { dotenvy::dotenv().ok(); let wallet = Wallet::builder() - .with_storage_path(&var("WALLET_DB_PATH").unwrap()) + .with_storage_path(&std::env::var("WALLET_DB_PATH").unwrap()) .finish() .await?; let account = wallet.get_account("Alice").await?; @@ -56,7 +54,7 @@ async fn main() -> Result<()> { // Set the stronghold password wallet - .set_stronghold_password(var("STRONGHOLD_PASSWORD").unwrap()) + .set_stronghold_password(std::env::var("STRONGHOLD_PASSWORD").unwrap()) .await?; let bech32_address = RECV_ADDRESS.parse::()?; @@ -73,7 +71,11 @@ async fn main() -> Result<()> { let block_id = account .retry_transaction_until_included(&transaction.transaction_id, None, None) .await?; - println!("Block included: {}/block/{}", var("EXPLORER_URL").unwrap(), block_id); + println!( + "Block included: {}/block/{}", + std::env::var("EXPLORER_URL").unwrap(), + block_id + ); let balance = account.sync(None).await?; diff --git a/sdk/examples/how_tos/nfts/burn_nft.rs b/sdk/examples/how_tos/nfts/burn_nft.rs index c6024acf91..37182618d2 100644 --- a/sdk/examples/how_tos/nfts/burn_nft.rs +++ b/sdk/examples/how_tos/nfts/burn_nft.rs @@ -2,11 +2,14 @@ // SPDX-License-Identifier: Apache-2.0 //! In this example we will burn an existing nft output. -//! Rename `.env.example` to `.env` first. //! -//! `cargo run --release --example burn_nft` - -use std::env::var; +//! Make sure that `STRONGHOLD_SNAPSHOT_PATH` and `WALLET_DB_PATH` already exist by +//! running the `./how_tos/accounts_and_addresses/create_account.rs` example! +//! +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --all-features --example burn_nft +//! ``` use iota_sdk::{wallet::Result, Wallet}; @@ -17,7 +20,7 @@ async fn main() -> Result<()> { // Create the wallet let wallet = Wallet::builder() - .with_storage_path(&var("WALLET_DB_PATH").unwrap()) + .with_storage_path(&std::env::var("WALLET_DB_PATH").unwrap()) .finish() .await?; let alias = "Alice"; @@ -33,7 +36,7 @@ async fn main() -> Result<()> { // Set the stronghold password wallet - .set_stronghold_password(var("STRONGHOLD_PASSWORD").unwrap()) + .set_stronghold_password(std::env::var("STRONGHOLD_PASSWORD").unwrap()) .await?; let transaction = account.burn(*nft_id, None).await?; @@ -43,7 +46,11 @@ async fn main() -> Result<()> { .retry_transaction_until_included(&transaction.transaction_id, None, None) .await?; - println!("Block included: {}/block/{}", var("EXPLORER_URL").unwrap(), block_id); + println!( + "Block included: {}/block/{}", + std::env::var("EXPLORER_URL").unwrap(), + block_id + ); println!("Burned NFT '{}'", nft_id); diff --git a/sdk/examples/how_tos/nfts/mint_nft.rs b/sdk/examples/how_tos/nfts/mint_nft.rs index 72fda4d19b..39948a270e 100644 --- a/sdk/examples/how_tos/nfts/mint_nft.rs +++ b/sdk/examples/how_tos/nfts/mint_nft.rs @@ -1,12 +1,15 @@ // Copyright 2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -//! In this example we will mint an NFT. -//! Rename `.env.example` to `.env` first. +//! In this example we will mint some NFTs. //! -//! `cargo run --release --example mint_nft` - -use std::env::var; +//! Make sure that `STRONGHOLD_SNAPSHOT_PATH` and `WALLET_DB_PATH` already exist by +//! running the `./how_tos/accounts_and_addresses/create_account.rs` example! +//! +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --all-features --example mint_nft +//! ``` use iota_sdk::{ types::block::output::{ @@ -36,7 +39,7 @@ async fn main() -> Result<()> { // Create the wallet let wallet = Wallet::builder() - .with_storage_path(&var("WALLET_DB_PATH").unwrap()) + .with_storage_path(&std::env::var("WALLET_DB_PATH").unwrap()) .finish() .await?; @@ -51,7 +54,7 @@ async fn main() -> Result<()> { // Set the stronghold password wallet - .set_stronghold_password(var("STRONGHOLD_PASSWORD").unwrap()) + .set_stronghold_password(std::env::var("STRONGHOLD_PASSWORD").unwrap()) .await?; let nft_params = [MintNftParams::new() @@ -69,7 +72,11 @@ async fn main() -> Result<()> { let block_id = account .retry_transaction_until_included(&transaction.transaction_id, None, None) .await?; - println!("Block included: {}/block/{}", var("EXPLORER_URL").unwrap(), block_id); + println!( + "Block included: {}/block/{}", + std::env::var("EXPLORER_URL").unwrap(), + block_id + ); println!("Minted NFT 1"); // Build an NFT manually by using the `NftOutputBuilder` @@ -90,7 +97,11 @@ async fn main() -> Result<()> { let block_id = account .retry_transaction_until_included(&transaction.transaction_id, None, None) .await?; - println!("Block included: {}/block/{}", var("EXPLORER_URL").unwrap(), block_id); + println!( + "Block included: {}/block/{}", + std::env::var("EXPLORER_URL").unwrap(), + block_id + ); println!("Minted NFT 2"); // Ensure the account is synced after minting. diff --git a/sdk/examples/how_tos/nfts/send_nft.rs b/sdk/examples/how_tos/nfts/send_nft.rs index 5cd5f09ef8..2b5df323a9 100644 --- a/sdk/examples/how_tos/nfts/send_nft.rs +++ b/sdk/examples/how_tos/nfts/send_nft.rs @@ -1,12 +1,15 @@ // Copyright 2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -//! In this example we will send an nft. -//! Rename `.env.example` to `.env` first. +//! In this example we will send an NFT. //! -//! `cargo run --release --example send_nft` - -use std::env::var; +//! Make sure that `STRONGHOLD_SNAPSHOT_PATH` and `WALLET_DB_PATH` already exist by +//! running the `./how_tos/accounts_and_addresses/create_account.rs` example! +//! +//! Rename `.env.example` to `.env` first, then run the command: +//! ```sh +//! cargo run --release --all-features --example send_nft +//! ``` use iota_sdk::{ wallet::{Result, SendNftParams}, @@ -23,7 +26,7 @@ async fn main() -> Result<()> { // Create the wallet let wallet = Wallet::builder() - .with_storage_path(&var("WALLET_DB_PATH").unwrap()) + .with_storage_path(&std::env::var("WALLET_DB_PATH").unwrap()) .finish() .await?; let account = wallet.get_account("Alice").await?; @@ -35,7 +38,7 @@ async fn main() -> Result<()> { if let Some(nft_id) = balance.nfts().first() { // Set the stronghold password wallet - .set_stronghold_password(var("STRONGHOLD_PASSWORD").unwrap()) + .set_stronghold_password(std::env::var("STRONGHOLD_PASSWORD").unwrap()) .await?; let outputs = [SendNftParams::new(RECV_ADDRESS, *nft_id)?]; @@ -50,7 +53,11 @@ async fn main() -> Result<()> { .retry_transaction_until_included(&transaction.transaction_id, None, None) .await?; - println!("Block included: {}/block/{}", var("EXPLORER_URL").unwrap(), block_id); + println!( + "Block included: {}/block/{}", + std::env::var("EXPLORER_URL").unwrap(), + block_id + ); } else { println!("No available NFTs"); } diff --git a/sdk/examples/how_tos/simple_transaction/request_funds.rs b/sdk/examples/how_tos/simple_transaction/request_funds.rs index bce6b7b9e7..9eba872978 100644 --- a/sdk/examples/how_tos/simple_transaction/request_funds.rs +++ b/sdk/examples/how_tos/simple_transaction/request_funds.rs @@ -3,16 +3,14 @@ //! In this example we request funds from the faucet to the first address in the account. //! -//! Make sure that `example.stronghold` and `example.walletdb` already exist by -//! running the `create_account` example! +//! Make sure that `STRONGHOLD_SNAPSHOT_PATH` and `WALLET_DB_PATH` already exist by +//! running the `./how_tos/accounts_and_addresses/create_account.rs` example! //! //! Rename `.env.example` to `.env` first, then run the command: //! ```sh //! cargo run --release --all-features --example request_funds //! ``` -use std::env::var; - use iota_sdk::{client::request_funds_from_faucet, wallet::Result, Wallet}; #[tokio::main] @@ -21,7 +19,7 @@ async fn main() -> Result<()> { dotenvy::dotenv().ok(); let wallet = Wallet::builder() - .with_storage_path(&var("WALLET_DB_PATH").unwrap()) + .with_storage_path(&std::env::var("WALLET_DB_PATH").unwrap()) .finish() .await?; let account = wallet.get_account("Alice").await?; @@ -35,7 +33,8 @@ async fn main() -> Result<()> { println!("Current available funds: {funds_before}"); println!("Requesting funds from faucet..."); - let faucet_response = request_funds_from_faucet(&var("FAUCET_URL").unwrap(), addresses[0].address()).await?; + let faucet_response = + request_funds_from_faucet(&std::env::var("FAUCET_URL").unwrap(), addresses[0].address()).await?; println!("Response from faucet: {}", faucet_response.trim_end()); diff --git a/sdk/examples/how_tos/simple_transaction/simple_transaction.rs b/sdk/examples/how_tos/simple_transaction/simple_transaction.rs index 163e45ae71..41618cae1a 100644 --- a/sdk/examples/how_tos/simple_transaction/simple_transaction.rs +++ b/sdk/examples/how_tos/simple_transaction/simple_transaction.rs @@ -3,16 +3,14 @@ //! In this example we will issue a simple base coin transaction. //! -//! Make sure that `example.stronghold` and `example.walletdb` already exist by -//! running the `create_account` example! +//! Make sure that `STRONGHOLD_SNAPSHOT_PATH` and `WALLET_DB_PATH` already exist by +//! running the `./how_tos/accounts_and_addresses/create_account.rs` example! //! //! Rename `.env.example` to `.env` first, then run the command: //! ```sh //! cargo run --release --all-features --example simple_transaction //! ``` -use std::env::var; - use iota_sdk::{ wallet::{Result, SendAmountParams}, Wallet, @@ -29,7 +27,7 @@ async fn main() -> Result<()> { dotenvy::dotenv().ok(); let wallet = Wallet::builder() - .with_storage_path(&var("WALLET_DB_PATH").unwrap()) + .with_storage_path(&std::env::var("WALLET_DB_PATH").unwrap()) .finish() .await?; let account = wallet.get_account("Alice").await?; @@ -39,7 +37,7 @@ async fn main() -> Result<()> { // Set the stronghold password wallet - .set_stronghold_password(var("STRONGHOLD_PASSWORD").unwrap()) + .set_stronghold_password(std::env::var("STRONGHOLD_PASSWORD").unwrap()) .await?; println!("Trying to send '{}' coins to '{}'...", SEND_AMOUNT, RECV_ADDRESS); @@ -51,7 +49,11 @@ async fn main() -> Result<()> { .retry_transaction_until_included(&transaction.transaction_id, None, None) .await?; - println!("Block included: {}/block/{}", var("EXPLORER_URL").unwrap(), block_id); + println!( + "Block included: {}/block/{}", + std::env::var("EXPLORER_URL").unwrap(), + block_id + ); Ok(()) } diff --git a/sdk/examples/wallet/16_destroy_alias.rs b/sdk/examples/wallet/16_destroy_alias.rs index 1130a0fe8b..1955f97343 100644 --- a/sdk/examples/wallet/16_destroy_alias.rs +++ b/sdk/examples/wallet/16_destroy_alias.rs @@ -4,16 +4,14 @@ //! In this example we will try to destroy the first alias there is in the account. This is only possible if possible //! foundry outputs have circulating supply of 0. //! -//! Make sure that `example.stronghold` and `example.walletdb` already exist by -//! running the `create_account` example! +//! Make sure that `STRONGHOLD_SNAPSHOT_PATH` and `WALLET_DB_PATH` already exist by +//! running the `./how_tos/accounts_and_addresses/create_account.rs` example! //! //! Rename `.env.example` to `.env` first, then run the command: //! ```sh //! cargo run --release --all-features --example destroy_alias //! ``` -use std::env::var; - use iota_sdk::{wallet::Result, Wallet}; #[tokio::main] @@ -22,7 +20,7 @@ async fn main() -> Result<()> { dotenvy::dotenv().ok(); let wallet = Wallet::builder() - .with_storage_path(&var("WALLET_DB_PATH").unwrap()) + .with_storage_path(&std::env::var("WALLET_DB_PATH").unwrap()) .finish() .await?; let alias = "Alice"; @@ -38,7 +36,7 @@ async fn main() -> Result<()> { // Set the stronghold password wallet - .set_stronghold_password(var("STRONGHOLD_PASSWORD").unwrap()) + .set_stronghold_password(std::env::var("STRONGHOLD_PASSWORD").unwrap()) .await?; println!("Sending alias burn transaction..."); @@ -51,8 +49,8 @@ async fn main() -> Result<()> { .await?; println!( - "Transaction included: {}/block/{}", - var("EXPLORER_URL").unwrap(), + "Block included: {}/block/{}", + std::env::var("EXPLORER_URL").unwrap(), block_id ); diff --git a/sdk/examples/wallet/17_check_unlock_conditions.rs b/sdk/examples/wallet/17_check_unlock_conditions.rs index 434d39f224..6ffdb3e445 100644 --- a/sdk/examples/wallet/17_check_unlock_conditions.rs +++ b/sdk/examples/wallet/17_check_unlock_conditions.rs @@ -3,15 +3,13 @@ //! In this example we check if an output has only an address unlock condition and that the address is from the account. //! -//! Make sure that `example.stronghold` and `example.walletdb` already exist by -//! running the `create_account` example! +//! Make sure that `STRONGHOLD_SNAPSHOT_PATH` and `WALLET_DB_PATH` already exist by +//! running the `./how_tos/accounts_and_addresses/create_account.rs` example! //! //! ```sh //! cargo run --release --all-features --example check_unlock_conditions //! ``` -use std::env::var; - use iota_sdk::{ types::block::{ address::Bech32Address, @@ -30,7 +28,7 @@ async fn main() -> Result<()> { dotenvy::dotenv().ok(); let wallet = Wallet::builder() - .with_storage_path(&var("WALLET_DB_PATH").unwrap()) + .with_storage_path(&std::env::var("WALLET_DB_PATH").unwrap()) .finish() .await?; let account = wallet.get_account("Alice").await?; diff --git a/sdk/examples/wallet/accounts.rs b/sdk/examples/wallet/accounts.rs index d596e24be8..8c9d33c958 100644 --- a/sdk/examples/wallet/accounts.rs +++ b/sdk/examples/wallet/accounts.rs @@ -4,15 +4,13 @@ //! In this example we will print the details of two accounts in the wallet. If an account doesn't exist yet it will be //! created. For the second account it will generate as many addresses as defined in the constant. //! -//! Make sure there's no `example.stronghold` file and no `example.walletdb` folder yet! +//! Make sure there's no `STRONGHOLD_SNAPSHOT_PATH` file and no `WALLET_DB_PATH` folder yet! //! //! Rename `.env.example` to `.env` first, then run the command: //! ```sh //! cargo run --release --all-features --example accounts //! ``` -use std::{env::var, time::Instant}; - use iota_sdk::{ client::{ constants::SHIMMER_COIN_TYPE, @@ -30,14 +28,14 @@ async fn main() -> Result<()> { // This example uses secrets in environment variables for simplicity which should not be done in production. dotenvy::dotenv().ok(); - let client_options = ClientOptions::new().with_node(&var("NODE_URL").unwrap())?; + let client_options = ClientOptions::new().with_node(&std::env::var("NODE_URL").unwrap())?; let secret_manager = - MnemonicSecretManager::try_from_mnemonic(var("NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_1").unwrap())?; + MnemonicSecretManager::try_from_mnemonic(std::env::var("NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_1").unwrap())?; let wallet = Wallet::builder() .with_secret_manager(SecretManager::Mnemonic(secret_manager)) - .with_storage_path(&var("WALLET_DB_PATH").unwrap()) + .with_storage_path(&std::env::var("WALLET_DB_PATH").unwrap()) .with_client_options(client_options) .with_coin_type(SHIMMER_COIN_TYPE) .finish() @@ -67,7 +65,8 @@ async fn main() -> Result<()> { println!("Current available funds: {funds_before}"); println!("Requesting funds from faucet..."); - let faucet_response = request_funds_from_faucet(&var("FAUCET_URL").unwrap(), addresses[0].address()).await?; + let faucet_response = + request_funds_from_faucet(&std::env::var("FAUCET_URL").unwrap(), addresses[0].address()).await?; println!("Response from faucet: {}", faucet_response.trim_end()); println!("Waiting for funds (timeout=60s)..."); @@ -78,7 +77,7 @@ async fn main() -> Result<()> { println!("Timeout: waiting for funds took too long"); return Ok(()); }; - let now = Instant::now(); + let now = tokio::time::Instant::now(); let balance = account2.sync(None).await?; if balance.base_coin().available() > funds_before { println!("Account synced in: {:.2?}", now.elapsed()); diff --git a/sdk/examples/wallet/background_syncing.rs b/sdk/examples/wallet/background_syncing.rs index 9e522ebf44..630c5c675d 100644 --- a/sdk/examples/wallet/background_syncing.rs +++ b/sdk/examples/wallet/background_syncing.rs @@ -8,8 +8,6 @@ //! cargo run --release --all-features --example background_syncing //! ``` -use std::env::var; - use iota_sdk::{ client::{ constants::SHIMMER_COIN_TYPE, @@ -25,12 +23,12 @@ async fn main() -> Result<()> { dotenvy::dotenv().ok(); // Create a wallet - let client_options = ClientOptions::new().with_node(&var("NODE_URL").unwrap())?; + let client_options = ClientOptions::new().with_node(&std::env::var("NODE_URL").unwrap())?; let secret_manager = - MnemonicSecretManager::try_from_mnemonic(var("NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_1").unwrap())?; + MnemonicSecretManager::try_from_mnemonic(std::env::var("NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_1").unwrap())?; let wallet = Wallet::builder() .with_secret_manager(SecretManager::Mnemonic(secret_manager)) - .with_storage_path(&var("WALLET_DB_PATH").unwrap()) + .with_storage_path(&std::env::var("WALLET_DB_PATH").unwrap()) .with_client_options(client_options) .with_coin_type(SHIMMER_COIN_TYPE) .finish() @@ -55,7 +53,8 @@ async fn main() -> Result<()> { println!("Started background syncing"); println!("Requesting funds from faucet..."); - let faucet_response = request_funds_from_faucet(&var("FAUCET_URL").unwrap(), addresses[0].address()).await?; + let faucet_response = + request_funds_from_faucet(&std::env::var("FAUCET_URL").unwrap(), addresses[0].address()).await?; println!("Response from faucet: {}", faucet_response.trim_end()); println!("Waiting for funds (timeout=60s)..."); diff --git a/sdk/examples/wallet/create_alias.rs b/sdk/examples/wallet/create_alias.rs index 551cf28b7d..00bdcc664c 100644 --- a/sdk/examples/wallet/create_alias.rs +++ b/sdk/examples/wallet/create_alias.rs @@ -3,8 +3,8 @@ //! In this example we will create an alias output. //! -//! Make sure that `example.stronghold` and `example.walletdb` already exist by -//! running the `create_account` example and that funds are available by running +//! Make sure that `STRONGHOLD_SNAPSHOT_PATH` and `WALLET_DB_PATH` already exist by +//! running the `./how_tos/accounts_and_addresses/create_account.rs` example and that funds are available by running //! the `get_funds` example! //! //! Rename `.env.example` to `.env` first, then run the command: @@ -12,8 +12,6 @@ //! cargo run --release --all-features --example create_alias //! ``` -use std::env::var; - use iota_sdk::{wallet::Result, Wallet}; #[tokio::main] @@ -22,7 +20,7 @@ async fn main() -> Result<()> { dotenvy::dotenv().ok(); let wallet = Wallet::builder() - .with_storage_path(&var("WALLET_DB_PATH").unwrap()) + .with_storage_path(&std::env::var("WALLET_DB_PATH").unwrap()) .finish() .await?; let account = wallet.get_account("Alice").await?; @@ -33,7 +31,7 @@ async fn main() -> Result<()> { // Set the stronghold password wallet - .set_stronghold_password(var("STRONGHOLD_PASSWORD").unwrap()) + .set_stronghold_password(std::env::var("STRONGHOLD_PASSWORD").unwrap()) .await?; println!("Sending the create-alias transaction..."); @@ -46,8 +44,8 @@ async fn main() -> Result<()> { .retry_transaction_until_included(&transaction.transaction_id, None, None) .await?; println!( - "Transaction included: {}/block/{}", - var("EXPLORER_URL").unwrap(), + "Block included: {}/block/{}", + std::env::var("EXPLORER_URL").unwrap(), block_id ); diff --git a/sdk/examples/wallet/events.rs b/sdk/examples/wallet/events.rs index acdf208f7a..bef6e13a3c 100644 --- a/sdk/examples/wallet/events.rs +++ b/sdk/examples/wallet/events.rs @@ -9,8 +9,6 @@ //! cargo run --release --all-features --example events //! ``` -use std::env::var; - use iota_sdk::{ client::{ constants::SHIMMER_COIN_TYPE, @@ -33,14 +31,14 @@ async fn main() -> Result<()> { // This example uses secrets in environment variables for simplicity which should not be done in production. dotenvy::dotenv().ok(); - let client_options = ClientOptions::new().with_node(&var("NODE_URL").unwrap())?; + let client_options = ClientOptions::new().with_node(&std::env::var("NODE_URL").unwrap())?; let secret_manager = - MnemonicSecretManager::try_from_mnemonic(var("NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_1").unwrap())?; + MnemonicSecretManager::try_from_mnemonic(std::env::var("NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_1").unwrap())?; let wallet = Wallet::builder() .with_secret_manager(SecretManager::Mnemonic(secret_manager)) - .with_storage_path(&var("WALLET_DB_PATH").unwrap()) + .with_storage_path(&std::env::var("WALLET_DB_PATH").unwrap()) .with_client_options(client_options) .with_coin_type(SHIMMER_COIN_TYPE) .finish() @@ -77,8 +75,8 @@ async fn main() -> Result<()> { .await?; println!( - "Transaction included: {}/block/{}", - var("EXPLORER_URL").unwrap(), + "Block included: {}/block/{}", + std::env::var("EXPLORER_URL").unwrap(), block_id ); diff --git a/sdk/examples/wallet/getting_started.rs b/sdk/examples/wallet/getting_started.rs index 100573f397..6a214cad1c 100644 --- a/sdk/examples/wallet/getting_started.rs +++ b/sdk/examples/wallet/getting_started.rs @@ -4,15 +4,13 @@ //! In this example we will create a new wallet, a mnemonic, and an initial account. Then, we'll print the first address //! of that account. //! -//! Make sure there's no `example.stronghold` file and no `example.walletdb` folder yet! +//! Make sure there's no `STRONGHOLD_SNAPSHOT_PATH` file and no `WALLET_DB_PATH` folder yet! //! //! Rename `.env.example` to `.env` first, then run the command: //! ```sh //! cargo run --release --all-features --example wallet_getting_started //! ``` -use std::env::var; - use iota_sdk::{ client::{ constants::SHIMMER_COIN_TYPE, @@ -28,15 +26,15 @@ async fn main() -> Result<()> { // Setup Stronghold secret_manager let secret_manager = StrongholdSecretManager::builder() - .password(var("STRONGHOLD_PASSWORD").unwrap()) - .build(var("STRONGHOLD_SNAPSHOT_PATH").unwrap())?; + .password(std::env::var("STRONGHOLD_PASSWORD").unwrap()) + .build(std::env::var("STRONGHOLD_SNAPSHOT_PATH").unwrap())?; - let client_options = ClientOptions::new().with_node(&var("NODE_URL").unwrap())?; + let client_options = ClientOptions::new().with_node(&std::env::var("NODE_URL").unwrap())?; // Create the wallet let wallet = Wallet::builder() .with_secret_manager(SecretManager::Stronghold(secret_manager)) - .with_storage_path(&var("WALLET_DB_PATH").unwrap()) + .with_storage_path(&std::env::var("WALLET_DB_PATH").unwrap()) .with_client_options(client_options) .with_coin_type(SHIMMER_COIN_TYPE) .finish() diff --git a/sdk/examples/wallet/ledger_nano.rs b/sdk/examples/wallet/ledger_nano.rs index c3b6b5f19e..c6f58791e3 100644 --- a/sdk/examples/wallet/ledger_nano.rs +++ b/sdk/examples/wallet/ledger_nano.rs @@ -14,8 +14,6 @@ //! cargo run --release --all-features --example ledger_nano //! ``` -use std::{env::var, time::Instant}; - use iota_sdk::{ client::{ constants::SHIMMER_COIN_TYPE, @@ -38,11 +36,11 @@ async fn main() -> Result<()> { // This example uses secrets in environment variables for simplicity which should not be done in production. dotenvy::dotenv().ok(); - let client_options = ClientOptions::new().with_node(&var("NODE_URL").unwrap())?; + let client_options = ClientOptions::new().with_node(&std::env::var("NODE_URL").unwrap())?; let secret_manager = LedgerSecretManager::new(true); let wallet = Wallet::builder() .with_secret_manager(SecretManager::LedgerNano(secret_manager)) - .with_storage_path(&var("WALLET_DB_PATH").unwrap()) + .with_storage_path(&std::env::var("WALLET_DB_PATH").unwrap()) .with_client_options(client_options) .with_coin_type(SHIMMER_COIN_TYPE) .finish() @@ -59,7 +57,7 @@ async fn main() -> Result<()> { }; println!("Generating {NUM_ADDRESSES_TO_GENERATE} addresses..."); - let now = Instant::now(); + let now = tokio::time::Instant::now(); let addresses = account .generate_ed25519_addresses(NUM_ADDRESSES_TO_GENERATE, None) .await?; @@ -67,7 +65,7 @@ async fn main() -> Result<()> { println!("ADDRESSES:\n{addresses:#?}"); - let now = Instant::now(); + let now = tokio::time::Instant::now(); let balance = account.sync(None).await?; println!("Account synced in: {:.2?}", now.elapsed()); @@ -82,12 +80,12 @@ async fn main() -> Result<()> { .retry_transaction_until_included(&transaction.transaction_id, None, None) .await?; println!( - "Transaction included: {}/block/{}", - var("EXPLORER_URL").unwrap(), + "Block included: {}/block/{}", + std::env::var("EXPLORER_URL").unwrap(), block_id ); - let now = Instant::now(); + let now = tokio::time::Instant::now(); let balance = account.sync(None).await?; println!("Account synced in: {:.2?}", now.elapsed()); diff --git a/sdk/examples/wallet/logger.rs b/sdk/examples/wallet/logger.rs index bf1154e610..756b8d4b7b 100644 --- a/sdk/examples/wallet/logger.rs +++ b/sdk/examples/wallet/logger.rs @@ -8,8 +8,6 @@ //! cargo run --release --all-features --example logger //! ``` -use std::env::var; - use iota_sdk::{ client::{ constants::SHIMMER_COIN_TYPE, @@ -37,11 +35,12 @@ async fn main() -> Result<()> { fern_logger::logger_init(config).unwrap(); // Restore a wallet - let client_options = ClientOptions::new().with_node(&var("NODE_URL").unwrap())?; + let client_options = ClientOptions::new().with_node(&std::env::var("NODE_URL").unwrap())?; let secret_manager = - MnemonicSecretManager::try_from_mnemonic(var("NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_1").unwrap())?; + MnemonicSecretManager::try_from_mnemonic(std::env::var("NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_1").unwrap())?; let wallet = Wallet::builder() .with_secret_manager(SecretManager::Mnemonic(secret_manager)) + .with_storage_path(&std::env::var("WALLET_DB_PATH").unwrap()) .with_client_options(client_options) .with_coin_type(SHIMMER_COIN_TYPE) .finish() diff --git a/sdk/examples/wallet/nft_collection/00_mint_issuer_nft.rs b/sdk/examples/wallet/nft_collection/00_mint_issuer_nft.rs index 5ff1c4af8c..aade6dbc40 100644 --- a/sdk/examples/wallet/nft_collection/00_mint_issuer_nft.rs +++ b/sdk/examples/wallet/nft_collection/00_mint_issuer_nft.rs @@ -3,8 +3,8 @@ //! In this example we will mint the issuer NFT for the NFT collection. //! -//! Make sure that `example.stronghold` and `example.walletdb` already exist by -//! running the `create_account` example! +//! Make sure that `STRONGHOLD_SNAPSHOT_PATH` and `WALLET_DB_PATH` already exist by +//! running the `./how_tos/accounts_and_addresses/create_account.rs` example! //! //! Rename `.env.example` to `.env` first, then run the command: //! ```sh @@ -72,7 +72,7 @@ async fn wait_for_inclusion(transaction_id: &TransactionId, account: &Account) - .retry_transaction_until_included(transaction_id, None, None) .await?; println!( - "Transaction included: {}/block/{}", + "Block included: {}/block/{}", std::env::var("EXPLORER_URL").unwrap(), block_id ); diff --git a/sdk/examples/wallet/nft_collection/01_mint_collection_nft.rs b/sdk/examples/wallet/nft_collection/01_mint_collection_nft.rs index dbad4fee95..2ca7f1d6f7 100644 --- a/sdk/examples/wallet/nft_collection/01_mint_collection_nft.rs +++ b/sdk/examples/wallet/nft_collection/01_mint_collection_nft.rs @@ -3,10 +3,10 @@ //! In this example we will mint some collection NFTs with issuer feature. //! -//! Make sure that `example.stronghold` and `example.walletdb` already exist by -//! running the `create_account` example. +//! Make sure that `STRONGHOLD_SNAPSHOT_PATH` and `WALLET_DB_PATH` already exist by +//! running the `./how_tos/accounts_and_addresses/create_account.rs` example. //! -//! You have to provide the ISSUER_NFT_ID that you created by running the +//! You have to provide the ISSUER_NFT_ID that was created by first running the //! `mint_issuer_nft` example! //! //! Rename `.env.example` to `.env` first, then run the command: @@ -110,7 +110,7 @@ async fn wait_for_inclusion(transaction_id: &TransactionId, account: &Account) - .retry_transaction_until_included(transaction_id, None, None) .await?; println!( - "Transaction included: {}/block/{}", + "Block included: {}/block/{}", std::env::var("EXPLORER_URL").unwrap(), block_id ); diff --git a/sdk/examples/wallet/offline_signing/0_generate_addresses.rs b/sdk/examples/wallet/offline_signing/0_generate_addresses.rs index 0322c6345d..ca239c1ffb 100644 --- a/sdk/examples/wallet/offline_signing/0_generate_addresses.rs +++ b/sdk/examples/wallet/offline_signing/0_generate_addresses.rs @@ -8,8 +8,6 @@ //! cargo run --release --all-features --example 0_generate_addresses //! ``` -use std::env::var; - use iota_sdk::{ client::{ constants::{SHIMMER_BECH32_HRP, SHIMMER_COIN_TYPE}, @@ -17,10 +15,6 @@ use iota_sdk::{ }, wallet::{Account, ClientOptions, Result, Wallet}, }; -use tokio::{ - fs::File, - io::{AsyncWriteExt, BufWriter}, -}; const OFFLINE_WALLET_DB_PATH: &str = "./examples/wallet/offline_signing/example-offline-walletdb"; const STRONGHOLD_SNAPSHOT_PATH: &str = "./examples/wallet/offline_signing/example.stronghold"; @@ -35,10 +29,10 @@ async fn main() -> Result<()> { // Setup Stronghold secret_manager let secret_manager = StrongholdSecretManager::builder() - .password(var("STRONGHOLD_PASSWORD").unwrap()) + .password(std::env::var("STRONGHOLD_PASSWORD").unwrap()) .build(STRONGHOLD_SNAPSHOT_PATH)?; - let mnemonic = var("NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_1").unwrap(); + let mnemonic = std::env::var("NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_1").unwrap(); // The mnemonic only needs to be stored the first time secret_manager.store_mnemonic(mnemonic).await?; @@ -66,9 +60,11 @@ async fn main() -> Result<()> { } async fn write_addresses_to_file(account: &Account) -> Result<()> { + use tokio::io::AsyncWriteExt; + let addresses = account.addresses().await?; let json = serde_json::to_string_pretty(&addresses)?; - let mut file = BufWriter::new(File::create(ADDRESSES_FILE_PATH).await?); + let mut file = tokio::io::BufWriter::new(tokio::fs::File::create(ADDRESSES_FILE_PATH).await?); println!("example.addresses.json:\n{json}"); file.write_all(json.as_bytes()).await?; file.flush().await?; diff --git a/sdk/examples/wallet/offline_signing/1_prepare_transaction.rs b/sdk/examples/wallet/offline_signing/1_prepare_transaction.rs index 743e94b4ac..2d2469066d 100644 --- a/sdk/examples/wallet/offline_signing/1_prepare_transaction.rs +++ b/sdk/examples/wallet/offline_signing/1_prepare_transaction.rs @@ -8,8 +8,6 @@ //! cargo run --release --all-features --example 1_prepare_transaction //! ``` -use std::env::var; - use iota_sdk::{ client::{ api::{PreparedTransactionData, PreparedTransactionDataDto}, @@ -18,10 +16,6 @@ use iota_sdk::{ }, wallet::{account::types::AccountAddress, ClientOptions, Result, SendAmountParams, Wallet}, }; -use tokio::{ - fs::File, - io::{AsyncReadExt, AsyncWriteExt, BufReader, BufWriter}, -}; const ONLINE_WALLET_DB_PATH: &str = "./examples/wallet/offline_signing/example-online-walletdb"; const ADDRESSES_FILE_PATH: &str = "./examples/wallet/offline_signing/example.addresses.json"; @@ -41,7 +35,7 @@ async fn main() -> Result<()> { // Recovers addresses from example `0_address_generation`. let addresses = read_addresses_from_file().await?; - let client_options = ClientOptions::new().with_node(&var("NODE_URL").unwrap())?; + let client_options = ClientOptions::new().with_node(&std::env::var("NODE_URL").unwrap())?; // Create the wallet with the secret_manager and client options let wallet = Wallet::builder() @@ -73,7 +67,9 @@ async fn main() -> Result<()> { } async fn read_addresses_from_file() -> Result> { - let mut file = BufReader::new(File::open(ADDRESSES_FILE_PATH).await?); + use tokio::io::AsyncReadExt; + + let mut file = tokio::io::BufReader::new(tokio::fs::File::open(ADDRESSES_FILE_PATH).await?); let mut json = String::new(); file.read_to_string(&mut json).await?; @@ -81,8 +77,10 @@ async fn read_addresses_from_file() -> Result> { } async fn write_transaction_to_file(prepared_transaction: PreparedTransactionData) -> Result<()> { + use tokio::io::AsyncWriteExt; + let json = serde_json::to_string_pretty(&PreparedTransactionDataDto::from(&prepared_transaction))?; - let mut file = BufWriter::new(File::create(PREPARED_TRANSACTION_FILE_PATH).await?); + let mut file = tokio::io::BufWriter::new(tokio::fs::File::create(PREPARED_TRANSACTION_FILE_PATH).await?); println!("example.prepared_transaction.json:\n{json}"); file.write_all(json.as_bytes()).await?; file.flush().await?; diff --git a/sdk/examples/wallet/offline_signing/2_sign_transaction.rs b/sdk/examples/wallet/offline_signing/2_sign_transaction.rs index 8c598c615b..443fa7e30b 100644 --- a/sdk/examples/wallet/offline_signing/2_sign_transaction.rs +++ b/sdk/examples/wallet/offline_signing/2_sign_transaction.rs @@ -8,8 +8,6 @@ //! cargo run --release --all-features --example 2_sign_transaction //! ``` -use std::env::var; - use iota_sdk::{ client::{ api::{ @@ -21,10 +19,6 @@ use iota_sdk::{ types::block::{output::RentStructure, payload::TransactionPayload, protocol::ProtocolParameters}, wallet::Result, }; -use tokio::{ - fs::File, - io::{AsyncReadExt, AsyncWriteExt, BufReader, BufWriter}, -}; const STRONGHOLD_SNAPSHOT_PATH: &str = "./examples/wallet/offline_signing/example.stronghold"; const PREPARED_TRANSACTION_FILE_PATH: &str = "./examples/wallet/offline_signing/example.prepared_transaction.json"; @@ -37,7 +31,7 @@ async fn main() -> Result<()> { // Setup Stronghold secret_manager let secret_manager = StrongholdSecretManager::builder() - .password(var("STRONGHOLD_PASSWORD").unwrap()) + .password(std::env::var("STRONGHOLD_PASSWORD").unwrap()) .build(STRONGHOLD_SNAPSHOT_PATH)?; // Load snapshot file @@ -84,7 +78,9 @@ async fn main() -> Result<()> { async fn read_prepared_transaction_from_file( protocol_parameters: &ProtocolParameters, ) -> Result { - let mut file = BufReader::new(File::open(PREPARED_TRANSACTION_FILE_PATH).await?); + use tokio::io::AsyncReadExt; + + let mut file = tokio::io::BufReader::new(tokio::fs::File::open(PREPARED_TRANSACTION_FILE_PATH).await?); let mut json = String::new(); file.read_to_string(&mut json).await?; @@ -95,9 +91,11 @@ async fn read_prepared_transaction_from_file( } async fn write_signed_transaction_to_file(signed_transaction_data: &SignedTransactionData) -> Result<()> { + use tokio::io::AsyncWriteExt; + let dto = SignedTransactionDataDto::from(signed_transaction_data); let json = serde_json::to_string_pretty(&dto)?; - let mut file = BufWriter::new(File::create(SIGNED_TRANSACTION_FILE_PATH).await?); + let mut file = tokio::io::BufWriter::new(tokio::fs::File::create(SIGNED_TRANSACTION_FILE_PATH).await?); println!("example.signed_transaction.json:\n{json}"); file.write_all(json.as_bytes()).await?; file.flush().await?; diff --git a/sdk/examples/wallet/offline_signing/3_send_transaction.rs b/sdk/examples/wallet/offline_signing/3_send_transaction.rs index f8ab04f3a2..2422826b9f 100644 --- a/sdk/examples/wallet/offline_signing/3_send_transaction.rs +++ b/sdk/examples/wallet/offline_signing/3_send_transaction.rs @@ -8,8 +8,6 @@ //! cargo run --release --all-features --example 3_send_transaction //! ``` -use std::env::var; - use iota_sdk::{ client::{ api::{SignedTransactionData, SignedTransactionDataDto}, @@ -19,10 +17,6 @@ use iota_sdk::{ wallet::{Account, Result}, Wallet, }; -use tokio::{ - fs::File, - io::{AsyncReadExt, BufReader}, -}; const ONLINE_WALLET_DB_PATH: &str = "./examples/wallet/offline_signing/example-online-walletdb"; const SIGNED_TRANSACTION_FILE_PATH: &str = "./examples/wallet/offline_signing/example.signed_transaction.json"; @@ -50,7 +44,9 @@ async fn main() -> Result<()> { } async fn read_signed_transaction_from_file(client: &Client) -> Result { - let mut file = BufReader::new(File::open(SIGNED_TRANSACTION_FILE_PATH).await?); + use tokio::io::AsyncReadExt; + + let mut file = tokio::io::BufReader::new(tokio::fs::File::open(SIGNED_TRANSACTION_FILE_PATH).await?); let mut json = String::new(); file.read_to_string(&mut json).await?; @@ -65,7 +61,7 @@ async fn read_signed_transaction_from_file(client: &Client) -> Result Result<()> { println!( "Transaction sent: {}/transaction/{}", - var("EXPLORER_URL").unwrap(), + std::env::var("EXPLORER_URL").unwrap(), transaction_id ); // Wait for transaction to get included @@ -73,8 +69,8 @@ async fn wait_for_inclusion(transaction_id: &TransactionId, account: &Account) - .retry_transaction_until_included(transaction_id, None, None) .await?; println!( - "Transaction included: {}/block/{}", - var("EXPLORER_URL").unwrap(), + "Block included: {}/block/{}", + std::env::var("EXPLORER_URL").unwrap(), block_id ); Ok(()) diff --git a/sdk/examples/wallet/participation.rs b/sdk/examples/wallet/participation.rs index 025a280a76..2b19927aa6 100644 --- a/sdk/examples/wallet/participation.rs +++ b/sdk/examples/wallet/participation.rs @@ -7,8 +7,8 @@ //! * try to vote (the example aborts if you vote on an already ended voting) //! * if a voting occurred, stops the voting and destroys the voting output //! -//! Make sure that `example.stronghold` and `example.walletdb` already exist by -//! running the `create_account` example and there are funds on the first address +//! Make sure that `STRONGHOLD_SNAPSHOT_PATH` and `WALLET_DB_PATH` already exist by +//! running the `./how_tos/accounts_and_addresses/create_account.rs` example and there are funds on the first address //! by running the `get_funds` example! //! //! Rename `.env.example` to `.env` first, then run the command: @@ -16,11 +16,8 @@ //! cargo run --release --all-features --example wallet_participation //! ``` -use std::{env::var, str::FromStr}; - use iota_sdk::{ client::node_manager::node::Node, - types::api::plugins::participation::types::ParticipationEventId, wallet::{account::types::participation::ParticipationEventRegistrationOptions, Result}, Url, Wallet, }; @@ -45,17 +42,17 @@ async fn main() -> Result<()> { dotenvy::dotenv().ok(); let wallet = Wallet::builder() - .with_storage_path(&var("WALLET_DB_PATH").unwrap()) + .with_storage_path(&std::env::var("WALLET_DB_PATH").unwrap()) .finish() .await?; let account = wallet.get_account("Alice").await?; // Provide the stronghold password wallet - .set_stronghold_password(var("STRONGHOLD_PASSWORD").unwrap()) + .set_stronghold_password(std::env::var("STRONGHOLD_PASSWORD").unwrap()) .await?; - let event_id = ParticipationEventId::from_str(PARTICIPATION_EVENT_ID_1)?; + let event_id = PARTICIPATION_EVENT_ID_1.parse()?; let node = Node { url: Url::parse(PARTICPATION_NODE_URL).map_err(iota_sdk::client::Error::Url)?, auth: None, @@ -66,7 +63,7 @@ async fn main() -> Result<()> { node, // We ignore this particular event events_to_ignore: (!IGNORED_PARTICIPATION_EVENT_ID.is_empty()) - .then_some(vec![ParticipationEventId::from_str(IGNORED_PARTICIPATION_EVENT_ID)?]), + .then_some(vec![IGNORED_PARTICIPATION_EVENT_ID.parse()?]), // We register all others. If you want to register only particular events provide their ids with a // `Some(vec![...])` events_to_register: None, @@ -103,7 +100,7 @@ async fn main() -> Result<()> { //////////////////////////////////////////////// if !DEREGISTERED_PARTICIPATION_EVENT.is_empty() { account - .deregister_participation_event(&ParticipationEventId::from_str(DEREGISTERED_PARTICIPATION_EVENT)?) + .deregister_participation_event(&DEREGISTERED_PARTICIPATION_EVENT.parse()?) .await?; println!("Registered events (updated):"); @@ -139,8 +136,8 @@ async fn main() -> Result<()> { .retry_transaction_until_included(&transaction.transaction_id, None, None) .await?; println!( - "Transaction included: {}/block/{}", - var("EXPLORER_URL").unwrap(), + "Block included: {}/block/{}", + std::env::var("EXPLORER_URL").unwrap(), block_id ); @@ -164,8 +161,8 @@ async fn main() -> Result<()> { .retry_transaction_until_included(&transaction.transaction_id, None, None) .await?; println!( - "Transaction included: {}/block/{}", - var("EXPLORER_URL").unwrap(), + "Block included: {}/block/{}", + std::env::var("EXPLORER_URL").unwrap(), block_id ); @@ -189,8 +186,8 @@ async fn main() -> Result<()> { .retry_transaction_until_included(&transaction.transaction_id, None, None) .await?; println!( - "Transaction included: {}/block/{}", - var("EXPLORER_URL").unwrap(), + "Block included: {}/block/{}", + std::env::var("EXPLORER_URL").unwrap(), block_id ); @@ -216,8 +213,8 @@ async fn main() -> Result<()> { .retry_transaction_until_included(&transaction.transaction_id, None, None) .await?; println!( - "Transaction included: {}/block/{}", - var("EXPLORER_URL").unwrap(), + "Block included: {}/block/{}", + std::env::var("EXPLORER_URL").unwrap(), block_id ); @@ -240,8 +237,8 @@ async fn main() -> Result<()> { .retry_transaction_until_included(&transaction.transaction_id, None, None) .await?; println!( - "Transaction included: {}/block/{}", - var("EXPLORER_URL").unwrap(), + "Block included: {}/block/{}", + std::env::var("EXPLORER_URL").unwrap(), block_id ); diff --git a/sdk/examples/wallet/recover_accounts.rs b/sdk/examples/wallet/recover_accounts.rs index fa19153e18..bd61f3b0c6 100644 --- a/sdk/examples/wallet/recover_accounts.rs +++ b/sdk/examples/wallet/recover_accounts.rs @@ -10,8 +10,6 @@ //! cargo run --release --all-features --example recover_accounts //! ``` -use std::{env::var, time::Instant}; - use iota_sdk::{ client::{ constants::SHIMMER_COIN_TYPE, @@ -32,7 +30,7 @@ async fn main() -> Result<()> { let wallet = Wallet::builder() .with_secret_manager(SecretManager::Mnemonic(secret_manager)) - .with_storage_path(&var("WALLET_DB_PATH").unwrap()) + .with_storage_path(&std::env::var("WALLET_DB_PATH").unwrap()) .with_client_options(client_options) .with_coin_type(SHIMMER_COIN_TYPE) .finish() @@ -43,7 +41,7 @@ async fn main() -> Result<()> { println!("Recovered {} accounts", accounts.len()); for account in accounts.iter() { println!("ACCOUNT #{}:", account.details().await.index()); - let now = Instant::now(); + let now = tokio::time::Instant::now(); let balance = account.sync(None).await?; println!("Account synced in: {:.2?}", now.elapsed()); println!("Balance: {balance:#?}"); diff --git a/sdk/examples/wallet/spammer.rs b/sdk/examples/wallet/spammer.rs index 4e1a59140c..6e83ec9333 100644 --- a/sdk/examples/wallet/spammer.rs +++ b/sdk/examples/wallet/spammer.rs @@ -5,11 +5,9 @@ //! //! Rename `.env.example` to `.env` first, then run the command: //! ```sh -//! cargo run --release --features=wallet --example spammer +//! cargo run --release --all-features --example spammer //! ``` -use std::{env::var, time::Duration}; - use iota_sdk::{ client::{ constants::SHIMMER_COIN_TYPE, @@ -19,10 +17,6 @@ use iota_sdk::{ types::block::{address::Bech32Address, output::BasicOutput, payload::transaction::TransactionId}, wallet::{account::FilterOptions, Account, ClientOptions, Result, SendAmountParams, Wallet}, }; -use tokio::{ - task::JoinSet, - time::{sleep, Instant}, -}; // The account alias used in this example. const ACCOUNT_ALIAS: &str = "spammer"; @@ -43,9 +37,9 @@ async fn main() -> Result<()> { println!("Spammer set up to issue {num_simultaneous_txs} transactions simultaneously."); // Restore wallet from a mnemonic phrase. - let client_options = ClientOptions::new().with_node(&var("NODE_URL").unwrap())?; + let client_options = ClientOptions::new().with_node(&std::env::var("NODE_URL").unwrap())?; let secret_manager = - MnemonicSecretManager::try_from_mnemonic(var("NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_1").unwrap())?; + MnemonicSecretManager::try_from_mnemonic(std::env::var("NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_1").unwrap())?; let wallet = Wallet::builder() .with_secret_manager(SecretManager::Mnemonic(secret_manager)) .with_client_options(client_options) @@ -55,6 +49,7 @@ async fn main() -> Result<()> { let account = get_or_create_account(&wallet, ACCOUNT_ALIAS).await?; let recv_address = *account.addresses().await?[0].address(); + println!("Recv address: {}", recv_address); // Ensure there are enough available funds for spamming. ensure_enough_funds(&account, &recv_address).await?; @@ -87,9 +82,9 @@ async fn main() -> Result<()> { println!("Spamming transactions..."); for i in 1..=NUM_ROUNDS { println!("ROUND {i}/{NUM_ROUNDS}"); - let round_timer = Instant::now(); + let round_timer = tokio::time::Instant::now(); - let mut tasks = JoinSet::>::new(); + let mut tasks = tokio::task::JoinSet::>::new(); for n in 0..num_simultaneous_txs { let account_clone = account.clone(); @@ -97,14 +92,14 @@ async fn main() -> Result<()> { tasks.spawn(async move { println!("Thread {n}: sending {SEND_AMOUNT} coins to own address"); - let thread_timer = Instant::now(); + let thread_timer = tokio::time::Instant::now(); let outputs = vec![SendAmountParams::new(recv_address, SEND_AMOUNT).map_err(|err| (n, err))?]; let transaction = account_clone.send_amount(outputs, None).await.map_err(|err| (n, err))?; let elapsed = thread_timer.elapsed(); println!( "Thread {n}: sent in {elapsed:.2?}: {}/transaction/{}", - var("EXPLORER_URL").unwrap(), + std::env::var("EXPLORER_URL").unwrap(), transaction.transaction_id ); @@ -131,7 +126,7 @@ async fn main() -> Result<()> { while balance.base_coin().available() == 0 { println!("No funds available"); - sleep(Duration::from_secs(2)).await; + tokio::time::sleep(std::time::Duration::from_secs(2)).await; balance = account.sync(None).await?; println!("Account synced"); } @@ -162,7 +157,7 @@ async fn ensure_enough_funds(account: &Account, bech32_address: &Bech32Address) println!("Min required funds: {min_required_funds}"); if available_funds < min_required_funds { println!("Requesting funds from faucet..."); - let faucet_response = request_funds_from_faucet(&var("FAUCET_URL").unwrap(), bech32_address).await?; + let faucet_response = request_funds_from_faucet(&std::env::var("FAUCET_URL").unwrap(), bech32_address).await?; println!("Response from faucet: {}", faucet_response.trim_end()); if faucet_response.contains("error") { panic!("Requesting funds failed (error response)"); @@ -198,7 +193,7 @@ async fn ensure_enough_funds(account: &Account, bech32_address: &Bech32Address) async fn wait_for_inclusion(transaction_id: &TransactionId, account: &Account) -> Result<()> { println!( "Transaction sent: {}/transaction/{}", - var("EXPLORER_URL").unwrap(), + std::env::var("EXPLORER_URL").unwrap(), transaction_id ); // Wait for transaction to get included @@ -206,8 +201,8 @@ async fn wait_for_inclusion(transaction_id: &TransactionId, account: &Account) - .retry_transaction_until_included(transaction_id, None, None) .await?; println!( - "Transaction included: {}/block/{}", - var("EXPLORER_URL").unwrap(), + "Block included: {}/block/{}", + std::env::var("EXPLORER_URL").unwrap(), block_id ); Ok(()) diff --git a/sdk/examples/wallet/split_funds.rs b/sdk/examples/wallet/split_funds.rs index ee78c32d75..c5035d3c89 100644 --- a/sdk/examples/wallet/split_funds.rs +++ b/sdk/examples/wallet/split_funds.rs @@ -11,8 +11,6 @@ //! cargo run --release --all-features --example split_funds //! ``` -use std::{env::var, time::Instant}; - use iota_sdk::{ client::{ constants::SHIMMER_COIN_TYPE, @@ -32,14 +30,14 @@ async fn main() -> Result<()> { // This example uses secrets in environment variables for simplicity which should not be done in production. dotenvy::dotenv().ok(); - let client_options = ClientOptions::new().with_node(&var("NODE_URL").unwrap())?; + let client_options = ClientOptions::new().with_node(&std::env::var("NODE_URL").unwrap())?; let secret_manager = - MnemonicSecretManager::try_from_mnemonic(var("NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_1").unwrap())?; + MnemonicSecretManager::try_from_mnemonic(std::env::var("NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_1").unwrap())?; let wallet = Wallet::builder() .with_secret_manager(SecretManager::Mnemonic(secret_manager)) - .with_storage_path(&var("WALLET_DB_PATH").unwrap()) + .with_storage_path(&std::env::var("WALLET_DB_PATH").unwrap()) .with_client_options(client_options) .with_coin_type(SHIMMER_COIN_TYPE) .finish() @@ -83,7 +81,7 @@ async fn main() -> Result<()> { let transaction = account.send(outputs_per_transaction, None).await?; println!( "Transaction sent: {}/transaction/{}", - var("EXPLORER_URL").unwrap(), + std::env::var("EXPLORER_URL").unwrap(), transaction.transaction_id ); @@ -93,8 +91,8 @@ async fn main() -> Result<()> { .await?; println!( - "Transaction included: {}/block/{}", - var("EXPLORER_URL").unwrap(), + "Block included: {}/block/{}", + std::env::var("EXPLORER_URL").unwrap(), block_id ); } @@ -123,7 +121,7 @@ async fn create_account(wallet: &Wallet, alias: &str) -> Result { async fn sync_print_balance(account: &Account) -> Result<()> { let alias = account.alias().await; - let now = Instant::now(); + let now = tokio::time::Instant::now(); let balance = account.sync(None).await?; println!("{alias}'s account synced in: {:.2?}", now.elapsed()); println!("{alias}'s balance:\n{:#?}", balance.base_coin()); diff --git a/sdk/examples/wallet/storage.rs b/sdk/examples/wallet/storage.rs index e6a656edb5..8e2e715d32 100644 --- a/sdk/examples/wallet/storage.rs +++ b/sdk/examples/wallet/storage.rs @@ -8,8 +8,6 @@ //! cargo run --release --all-features --example storage //! ``` -use std::{env::var, time::Instant}; - use iota_sdk::{ client::{ constants::SHIMMER_COIN_TYPE, @@ -27,13 +25,13 @@ async fn main() -> Result<()> { dotenvy::dotenv().ok(); let secret_manager = - MnemonicSecretManager::try_from_mnemonic(var("NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_1").unwrap())?; + MnemonicSecretManager::try_from_mnemonic(std::env::var("NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_1").unwrap())?; - let client_options = ClientOptions::new().with_node(&var("NODE_URL").unwrap())?; + let client_options = ClientOptions::new().with_node(&std::env::var("NODE_URL").unwrap())?; let wallet = Wallet::builder() .with_secret_manager(SecretManager::Mnemonic(secret_manager)) - .with_storage_path(&var("WALLET_DB_PATH").unwrap()) + .with_storage_path(&std::env::var("WALLET_DB_PATH").unwrap()) .with_client_options(client_options) .with_coin_type(SHIMMER_COIN_TYPE) .finish() @@ -83,7 +81,7 @@ async fn generate_max_addresses(account: &Account, max: usize) -> Result Result<()> { let alias = account.alias().await; - let now = Instant::now(); + let now = tokio::time::Instant::now(); let balance = account.sync(None).await?; println!("{alias}'s account synced in: {:.2?}", now.elapsed()); println!("{alias}'s balance:\n{:#?}", balance.base_coin()); diff --git a/sdk/examples/wallet/update_alias_output.rs b/sdk/examples/wallet/update_alias_output.rs index 2019bdae30..d0f6729236 100644 --- a/sdk/examples/wallet/update_alias_output.rs +++ b/sdk/examples/wallet/update_alias_output.rs @@ -3,18 +3,16 @@ //! In this example we will update the state metadata of an alias output. //! -//! Make sure that `example.stronghold` and `example.walletdb` already exist by -//! running the `create_account` example! +//! Make sure that `STRONGHOLD_SNAPSHOT_PATH` and `WALLET_DB_PATH` already exist by +//! running the `./how_tos/accounts_and_addresses/create_account.rs` example! //! //! Rename `.env.example` to `.env` first, then run the command: //! ```sh //! cargo run --release --all-features --example update_alias_output //! ``` -use std::{env::var, str::FromStr, time::Instant}; - use iota_sdk::{ - types::block::output::{AliasId, AliasOutputBuilder, Output}, + types::block::output::{AliasOutputBuilder, Output}, wallet::{Account, Result}, Wallet, }; @@ -30,7 +28,7 @@ async fn main() -> Result<()> { dotenvy::dotenv().ok(); let wallet = Wallet::builder() - .with_storage_path(&var("WALLET_DB_PATH").unwrap()) + .with_storage_path(&std::env::var("WALLET_DB_PATH").unwrap()) .finish() .await?; let account = wallet.get_account("Alice").await?; @@ -39,11 +37,11 @@ async fn main() -> Result<()> { // Set the stronghold password wallet - .set_stronghold_password(var("STRONGHOLD_PASSWORD").unwrap()) + .set_stronghold_password(std::env::var("STRONGHOLD_PASSWORD").unwrap()) .await?; // Get the alias output by its alias id - let alias_id = AliasId::from_str(ALIAS_ID)?; + let alias_id = ALIAS_ID.parse()?; if let Some(alias_output_data) = account.unspent_alias_output(&alias_id).await? { println!( "Alias '{ALIAS_ID}' found in unspent output: '{}'", @@ -76,7 +74,7 @@ async fn main() -> Result<()> { async fn sync_and_print_balance(account: &Account) -> Result<()> { let alias = account.alias().await; - let now = Instant::now(); + let now = tokio::time::Instant::now(); let balance = account.sync(None).await?; println!("{alias}'s account synced in: {:.2?}", now.elapsed()); println!("{alias}'s base coin balance:\n{:#?}", balance.base_coin()); @@ -88,7 +86,7 @@ async fn send_and_wait_for_inclusion(account: &Account, outputs: Vec) -> let transaction = account.send(outputs, None).await?; println!( "Transaction sent: {}/transaction/{}", - var("EXPLORER_URL").unwrap(), + std::env::var("EXPLORER_URL").unwrap(), transaction.transaction_id ); // Wait for transaction to get included @@ -96,8 +94,8 @@ async fn send_and_wait_for_inclusion(account: &Account, outputs: Vec) -> .retry_transaction_until_included(&transaction.transaction_id, None, None) .await?; println!( - "Transaction included: {}/block/{}", - var("EXPLORER_URL").unwrap(), + "Block included: {}/block/{}", + std::env::var("EXPLORER_URL").unwrap(), block_id ); Ok(()) diff --git a/sdk/examples/wallet/wallet.rs b/sdk/examples/wallet/wallet.rs index 9fd2778875..aa2dac443e 100644 --- a/sdk/examples/wallet/wallet.rs +++ b/sdk/examples/wallet/wallet.rs @@ -9,15 +9,13 @@ //! * print all addresses with funds in the account //! * make a coin transaction //! -//! Make sure there's no `example.stronghold` file and no `example.walletdb` folder yet! +//! Make sure there's no `STRONGHOLD_SNAPSHOT_PATH` file and no `WALLET_DB_PATH` folder yet! //! //! Rename `.env.example` to `.env` first, then run the command: //! ```sh //! cargo run --release --all-features --example wallet //! ``` -use std::{env::var, time::Instant}; - use iota_sdk::{ client::{ constants::SHIMMER_COIN_TYPE, @@ -64,12 +62,12 @@ async fn main() -> Result<()> { } async fn create_wallet() -> Result { - let client_options = ClientOptions::new().with_node(&var("NODE_URL").unwrap())?; + let client_options = ClientOptions::new().with_node(&std::env::var("NODE_URL").unwrap())?; let secret_manager = - MnemonicSecretManager::try_from_mnemonic(var("NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_1").unwrap())?; + MnemonicSecretManager::try_from_mnemonic(std::env::var("NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_1").unwrap())?; Wallet::builder() .with_secret_manager(SecretManager::Mnemonic(secret_manager)) - .with_storage_path(&var("WALLET_DB_PATH").unwrap()) + .with_storage_path(&std::env::var("WALLET_DB_PATH").unwrap()) .with_client_options(client_options) .with_coin_type(SHIMMER_COIN_TYPE) .finish() @@ -100,7 +98,7 @@ async fn generate_addresses(account: &Account, max: usize) -> Result<()> { if account.addresses().await?.len() < max { let num_addresses_to_generate = max - account.addresses().await?.len(); println!("Generating {num_addresses_to_generate} addresses ..."); - let now = Instant::now(); + let now = tokio::time::Instant::now(); account .generate_ed25519_addresses(num_addresses_to_generate as u32, None) .await?; @@ -120,7 +118,7 @@ async fn print_addresses(account: &Account) -> Result<()> { async fn sync_print_balance(account: &Account, full_report: bool) -> Result<()> { let alias = account.alias().await; - let now = Instant::now(); + let now = tokio::time::Instant::now(); let balance = account.sync(None).await?; println!("{alias}'s account synced in: {:.2?}", now.elapsed()); if full_report { @@ -151,7 +149,7 @@ async fn print_addresses_with_funds(account: &Account) -> Result<()> { async fn wait_for_inclusion(transaction_id: &TransactionId, account: &Account) -> Result<()> { println!( "Transaction sent: {}/transaction/{}", - var("EXPLORER_URL").unwrap(), + std::env::var("EXPLORER_URL").unwrap(), transaction_id ); // Wait for transaction to get included @@ -159,8 +157,8 @@ async fn wait_for_inclusion(transaction_id: &TransactionId, account: &Account) - .retry_transaction_until_included(transaction_id, None, None) .await?; println!( - "Transaction included: {}/block/{}", - var("EXPLORER_URL").unwrap(), + "Block included: {}/block/{}", + std::env::var("EXPLORER_URL").unwrap(), block_id ); Ok(()) diff --git a/sdk/src/client/api/block_builder/mod.rs b/sdk/src/client/api/block_builder/mod.rs index 72910b2f57..98cd5482b4 100644 --- a/sdk/src/client/api/block_builder/mod.rs +++ b/sdk/src/client/api/block_builder/mod.rs @@ -203,9 +203,8 @@ impl<'a> ClientBlockBuilder<'a> { } /// Set a custom remainder address - pub fn with_custom_remainder_address(mut self, address: &str) -> Result { - let address = Address::try_from_bech32(address)?; - self.custom_remainder_address.replace(address); + pub fn with_custom_remainder_address(mut self, address: impl ConvertTo) -> Result { + self.custom_remainder_address.replace(address.convert()?.into()); Ok(self) } diff --git a/sdk/src/types/block/address/mod.rs b/sdk/src/types/block/address/mod.rs index 9f8a07fd46..aaf3007371 100644 --- a/sdk/src/types/block/address/mod.rs +++ b/sdk/src/types/block/address/mod.rs @@ -190,6 +190,7 @@ pub trait ToBech32Ext: Sized { /// validity. fn to_bech32_unchecked(self, hrp: impl ConvertTo) -> Bech32Address; } + impl> ToBech32Ext for T { /// Try to encode this address to a bech32 string with the given Human Readable Part as prefix. fn try_to_bech32(self, hrp: impl ConvertTo) -> Result { diff --git a/sdk/src/wallet/bindings/nodejs/examples/.env.example b/sdk/src/wallet/bindings/nodejs/examples/.env.example deleted file mode 100644 index 48a4796417..0000000000 --- a/sdk/src/wallet/bindings/nodejs/examples/.env.example +++ /dev/null @@ -1,5 +0,0 @@ -STRONGHOLD_PASSWORD="A12345678*" -MNEMONIC="bulk spoon broken license diary nominee tribe visit used giant rail insect lesson home toast autumn cancel alley park give same wet wash vanish" -NODE_URL="https://api.testnet.shimmer.network" -FAUCET_URL="https://faucet.testnet.shimmer.network/api/enqueue" -EXPLORER_URL = "https://explorer.shimmer.network/testnet" \ No newline at end of file diff --git a/sdk/src/wallet/bindings/nodejs/examples/.env.example b/sdk/src/wallet/bindings/nodejs/examples/.env.example new file mode 120000 index 0000000000..241fba8c8b --- /dev/null +++ b/sdk/src/wallet/bindings/nodejs/examples/.env.example @@ -0,0 +1 @@ +../../../../../examples/.env.example \ No newline at end of file diff --git a/sdk/tests/wallet/message_interface.rs b/sdk/tests/wallet/message_interface.rs index b49f789666..115694cf32 100644 --- a/sdk/tests/wallet/message_interface.rs +++ b/sdk/tests/wallet/message_interface.rs @@ -203,7 +203,7 @@ async fn message_interface_events() -> Result<()> { let response = wallet_handle.send_message(transaction).await; - let Response::SentTransaction(_)= response else { + let Response::SentTransaction(_) = response else { panic!("unexpected response {response:?}"); };