This section will guide you through several examples using the python binding of the
wallet.rs library. You can also find the code for the examples in the
/bindings/python/examples folder in the official GitHub repository.
All the examples in this section expect you to set your custom password in the .env file:
You can initialize (open) a secure storage for individual accounts. The storage is backed up by
Stronghold by default, using an AccountManager instance.
The following example creates a new database and account:
- Storage is initialized under the given path (
- The password is set based on your password in .env file (
- When you initialize the new database, a Stronghold mnemonic (seed) is automatically generated and stored by default (
- The seed should be set only for the first time. In order to open already initialized database, you can simply use your password.
The storage is encrypted at rest, so you need a strong password and location where to place your storage.
We highly recommended that you to store your
Stronghold password encrypted on rest and separated from
Deal with the password with utmost care.
The storage comprises two things:
- A single file called wallet.stronghold , which contains seed and is secured by
Strongholdand encrypted at rest. The generated seed (mnemonic) serves as a cryptographic key from which all accounts and related addresses are generated.
- Other data used by library that is stored under the db sub-directory. The includes account information, generated addresses, fetched messages, etc. This data is used to speed up some operations, such as account creation, address generation, etc.
One of the key principles behind
Stronghold based storage is that no one can extract a seed from the storage. You deal with all accounts purely via an AccountManager instance. All complexities are hidden under the hood and dealt with securely.
If you also want to store a seed somewhere else, you can use the
AccountManager.generateMnemonic() method. This method will generate a random seed, and it can be used before the actual account initialization.
You can find detailed information about seed generation at Developer Guide to Chrysalis.
wallet.rs library uses a model of individual accounts to separate individual users and clients from each other. It is possible to generate multiple addresses for each account deterministically.
Each account is related to a specific IOTA network (mainnet or testnet), which is referenced by node properties such as node url. In this example, the
Chrysalis testnet balancer.
For more information about client_options , please refer to Wallet Python API Reference.
Alias should be unique, and it can be any string that you see fit. The alias is usually used to identify the account later on. Each account is also represented by an index which is incremented by 1 every time new account is created. Any account can be then referred to by its index , alias or one of its generated addresses .
Once an account has been created, you retrieve an instance of it using the following methods:
You can get an overview of all available accounts by running the following snippet:
You can get and instance of a specific account using the
account_manager.get_account("ALIAS"), replacing "ALIAS" for the given alias:
Several API calls can be performed via an account instance.
It is a good practice to sync the given account with the Tangle every time you work with an account instance to retrieve the latest information available. You can do this using the
account.sync() method. By default,
account.sync() is performed automatically on
promote API calls.
The most common methods of account instance are:
account.alias(): returns an alias of the given account.
account.addresses(): returns list of addresses related to the account.
account.get_unused_address(): returns a first unused address.
account.is_latest_address_unused(): queries the Tangle and returns a bool whether latest address was already used.
account.generate_address(): generates a new address for the address index incremented by 1.
account.balance(): returns the balance for the given account.
account.sync(): syncs the account information with the tangle.
Each account can have multiple addresses . Addresses are generated deterministically based on the account and address index. This means that the combination of account and index uniquely identifies the given address.
There are two types of addresses, internal and public (external), and each set of addresses is independent of each other and has independent index id.
- Public addresses are created by
account.generateAddress()and are indicated as
- Internal addresses are also called change addresses. Internal addresses are used to store the excess funds and are indicated as
This approach is also known as a BIP32 Hierarchical Deterministic wallet (HD Wallet).
The IOTA 1.5 (Chrysalis) network supports reusing addresses multiple times.
You can use the following example to generate a new address via an instance of account which was retrieved using an account_manager instance:
There are two human-readable prefixes in IOTA 1.5 network: iota (mainnet) and atoi (testnet). If you take a close look at the addresses in the output, you will be able to notice that both of them start with atoi , and are therefore testnet addresses.
You can find detailed information about generating addresses at the Developer Guide to Chrysalis.
Before we continue further, please visit the IOTA testnet faucet service and send some tokens to your testnet addresses.
You can use the following example to sync your accounts and retrieve their balances.
In the detailed view per individual addresses, there is also outputs section. The outputs shows all the transactions (also known as wallet message(s) ), which are related to that address, and therefore account for the balance.
You can also check the balance using the Tangle Explorer.
IOTA is based on Unspent Transaction Output model. You can find a detailed explanation in the Developer Guide to Chrysalis.
The process of sending tokens via wallet.rs can be described as follows:
- Create instance of
iota_wallet.Transfer()class with the following mandatory arguments: amount, address and remainder_value_strategy . The remainder_value_strategy argument can be either:
- Once you have created an instance of
iota_wallet.Transfer(), you can send the tokens using the
transfer()function of the Account instance.
We highly recommend that you sync the account information with the Tangle by running the
account.sync().execute() method before doing anything with the account. This way you can ensure that you rely on the latest available information.
The previous snippet should have a similar output to the following JSON object:
This is a wallet message that fully describes the given transaction.
To understand all aspects of messages, you will need to get familiar with concept of UTXO . You can find detailed information in the UTXO section in the Developer Guide to Chrysalis.
You can double-check the message using Tangle Explorer using its node_response['id']. Please make sure you select the right network.
If you have used the ChangeAddress remainder_value_strategy, the message will transfer tokens to the target address as well as new internal address within the given account (
You can find detailed information about messages and payloads in the Developer Guide to Chrysalis.
If you need to reattach a message, you should use the
iota_wallet.promote(account_id, message_id) or
iota_wallet.reattach(account_id, message_id) methods, sending your account_id and message_id as arguments.
You can use those methods to check whether a message is confirmed, broadcast, etc. You should always Sync the account with the Tangle before checking confirmation status.
You can use the following example to sync an account , and list all the messages related to the account .
The network uses a dust protection protocol to prevent malicious actors from spamming the network while also keeping track of the unspent amount ( UTXO ).
“... micro-transaction below 1Mi of IOTA tokens can be sent to another address if there is already at least 1Mi on that address. That's why we sent 1Mi in the last example to comply with the protection.”
Dust protection also means you can't leave less than 1Mi on a spent address (leave a dust behind).
Due to security practices that are incorporated in the
Stronghold's DNA, there's no way to retrieve a seed, as seeds are encrypted at rest. Therefore, if you're using the default options, backing up the seed storage is a very important task.
The following example will guide you in backing up your data in secure files. You can move this file to another app or device, and restore it.
To restore a database via
wallet.rs, you will need to:
- Create new empty database with a password (without mnemonic seed)
- Import all accounts from the file that has been backed up earlier
The following example restores a secured backup file:
Since the backup file is just a copy of the original database it can be also be renamed to wallet.stronghold and opened in a standard way.
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 add any of the following event listeners:
Once you have registered an event listener using, the function will return an id for the listener as a list[Bytes].
You can later use this id to remove a listener by using the corresponding method described below:
The following example set's up a listener for the on_balance_change event using an event-based pattern:
Alternatively, events can be consumed via queue-base pattern as shown in the following example: