Skip to main content
Version: IOTA

Examples in Rust

You can see the examples in the library's examples directory. You can list all available examples by running the following command:

cargo run --example # lists the available examples

To run an example, you can use the following command, replacing transfer with the desired example:

cargo run --example transfer # execute the `transfer` example

Backup and Restore Example

  1. Create an account manager and set a password:
let manager = AccountManager::builder().finish().await.unwrap();

manager.set_stronghold_password("password").await.unwrap();
manager.store_mnemonic(SignerType::Stronghold, None).await.unwrap();

  1. Create your account:
let client_options = ClientOptionsBuilder::new()
.with_node("https://api.lb-0.h.chrysalis-devnet.iota.cafe")?
.build()
.unwrap();
let account_handle = manager
.create_account(client_options)?
.alias("alias")
.initialise()
.await?;
let id = account_handle.id().await;

  1. You can secure your account in a backup file:
// backup the stored accounts to ./backup/${backup_name}
let backup_path = manager.backup("./backup").await?;

  1. You can import the backup later, or in another application using the following snippet:
manager.import_accounts(backup_path, "password").await?;

let imported_account_handle = manager.get_account(&id).await?;

let account = account_handle.read().await;
let imported_account = imported_account_handle.read().await;

That's it! You can now backup and restore your account!

You can see the full code for the example in the wallet.rs repository

Transfer Example:

You use the following example to generate an account and transfer funds.

// Copyright 2021 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

//! cargo run --example transfer --release

use iota_wallet::{
account_manager::AccountManager,
address::{parse, OutputKind},
client::ClientOptionsBuilder,
message::Transfer,
signing::SignerType,
};
use std::num::NonZeroU64;

#[tokio::main]
async fn main() -> iota_wallet::Result<()> {
let manager = AccountManager::builder().finish().await.unwrap();
manager.set_stronghold_password("password").await.unwrap();

// Get account or create a new one
let account_alias = "alias";
let account = match manager.get_account(account_alias).await {
Ok(account) => account,
_ => {
// first we'll create an example account and store it
manager.store_mnemonic(SignerType::Stronghold, None).await.unwrap();
let client_options = ClientOptionsBuilder::new()
.with_node("https://api.lb-0.h.chrysalis-devnet.iota.cafe")?
.build()
.unwrap();
manager
.create_account(client_options)?
.alias(account_alias)
.initialise()
.await?
}
};

let address = account.generate_address().await?;
println!(
"Send iotas from the faucet to {} and press enter after the transaction got confirmed",
address.address().to_bech32()
);
let mut input = String::new();
std::io::stdin().read_line(&mut input).unwrap();
println!("Sending transfer...");
let message = account
.transfer(
Transfer::builder(
parse("atoi1qzt0nhsf38nh6rs4p6zs5knqp6psgha9wsv74uajqgjmwc75ugupx3y7x0r")?,
NonZeroU64::new(10000000).unwrap(),
Some(OutputKind::SignatureLockedDustAllowance),
)
.finish(),
)
.await?;
println!("Message sent: {}", message.id());

Ok(())
}

Events Example:

wallet.rs library is able to listen to several supported event. As soon as the event occurs, a provided callback will be triggered.

You can use the following example to fetch an existing Account and listen to transaction events related to that Account :

// Copyright 2021 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

//! cargo run --example event --release
use iota_wallet::{
account::AccountHandle, account_manager::AccountManager, address::Address, client::ClientOptionsBuilder,
event::on_balance_change, signing::SignerType, Error, Result,
};
use reqwest::Client;
use std::collections::HashMap;

#[tokio::main]
async fn main() -> Result<()> {
let stronghold_password = "password".to_string();
let account_alias = "alice".to_string();
let node_url = "https://api.lb-1.h.chrysalis-devnet.iota.cafe/".to_string();
let faucet_url = "https://faucet.chrysalis-devnet.iota.cafe".to_string();

let account_manager: AccountManager = AccountManager::builder().finish().await?;
account_manager.set_stronghold_password(stronghold_password).await?;

// If no account was previously created, we create one. Otherwise, recover from local storage
// This ensures that the script can be run multiple times
let account: AccountHandle = match account_manager.get_account(&account_alias).await {
Ok(account) => account,
_ => {
account_manager.store_mnemonic(SignerType::Stronghold, None).await?;

let client_options = ClientOptionsBuilder::new().with_node(&node_url)?.build()?;
account_manager
.create_account(client_options)?
.alias(account_alias)
.initialise()
.await?
}
};

// Possible events are: on_balance_change, on_broadcast, on_confirmation_state_change, on_error,
// on_migration_progress, on_new_transaction, on_reattachment, on_stronghold_status_change,
// on_transfer_progress,
on_balance_change(move |event| {
println!("BalanceEvent: {:?}", event);
println!("Press enter to exit");
})
.await;

let address = account.generate_address().await?;
println!("Requesting funds from the faucet to {}", address.address().to_bech32());
get_funds(&address, &faucet_url).await?;

// Wait for event before exit
let mut exit = String::new();
std::io::stdin().read_line(&mut exit).unwrap();
Ok(())
}

// Requests a testnet funds transaction to our generated address
// This API is rate limited: only a request every minute is allowed
async fn get_funds(address: &Address, faucet_url: &str) -> Result<()> {
let mut body = HashMap::new();
body.insert("address", address.address().to_bech32());

let faucet_response = Client::new()
.post(format!("{}/api/plugins/faucet/enqueue", faucet_url))
.json(&body)
.send()
.await
.map_err(|e| Error::ClientError(Box::new(e.into())))?;

println!(
"{}",
faucet_response
.text()
.await
.map_err(|e| Error::ClientError(Box::new(e.into())))?
);

println!("Requested funds");

Ok(())
}

Logger Example:

// Copyright 2020 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

//! cargo run --example logger --release

use iota_client::common::logger::{logger_init, LoggerConfig, LoggerOutputConfigBuilder};
use iota_wallet::{account_manager::AccountManager, client::ClientOptionsBuilder, signing::SignerType};
use log::LevelFilter;
use std::time::Instant;

#[tokio::main]
async fn main() -> iota_wallet::Result<()> {
// Generates a wallet.log file with logs for debugging
let output_config = LoggerOutputConfigBuilder::new()
.name("wallet.log")
.level_filter(LevelFilter::Debug);
let config = LoggerConfig::build().with_output(output_config).finish();
logger_init(config).unwrap();

let manager = AccountManager::builder()
.with_storage("./backup", None)?
.with_skip_polling()
.finish()
.await?;
manager.set_stronghold_password("password").await?;

// Get account or create a new one
let account_alias = "logger";
let account = match manager.get_account(account_alias).await {
Ok(account) => account,
_ => {
// first we'll create an example account and store it
manager.store_mnemonic(SignerType::Stronghold, None).await.unwrap();
let client_options = ClientOptionsBuilder::new()
.with_node("https://api.lb-0.h.chrysalis-devnet.iota.cafe")?
.build()
.unwrap();
manager
.create_account(client_options)?
.alias(account_alias)
.initialise()
.await?
}
};

let now = Instant::now();
account.sync().await.execute().await?;
println!("Syncing took: {:.2?}", now.elapsed());

println!("Balance: {:?}", account.balance().await?);

let addresses = account.list_unspent_addresses().await?;
println!("Addresses: {}", addresses.len());

let address = account.generate_address().await?;
println!("Generated a new address: {:?}", address);

Ok(())
}