From 6b236d1bcdbd9082c326919f194541400c760afd Mon Sep 17 00:00:00 2001 From: Brord van Wierst Date: Tue, 5 Dec 2023 18:25:08 +0100 Subject: [PATCH 01/34] initial --- Cargo.toml | 3 +- bindings/python/README.md | 2 +- .../python/examples/wallet/getting_started.py | 29 +- bindings/python/iota_sdk/__init__.py | 5 +- bindings/python/iota_sdk/types/common.py | 14 +- bindings/python/iota_sdk/types/payload.py | 1 + .../iota_sdk/types/transaction_options.py | 2 +- bindings/python/iota_sdk/types/unlock.py | 4 + bindings/python/iota_sdk/utils.py | 2 +- bindings/python/iota_sdk/wallet/account.py | 634 --------------- bindings/python/iota_sdk/wallet/wallet.py | 746 +++++++++++++++--- 11 files changed, 656 insertions(+), 786 deletions(-) delete mode 100644 bindings/python/iota_sdk/wallet/account.py diff --git a/Cargo.toml b/Cargo.toml index 51fea11cf3..99647d0d92 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,8 +3,7 @@ resolver = "2" members = [ "bindings/core", "bindings/nodejs", - # TODO: issue #1423 - #"bindings/python", + "bindings/python", "bindings/wasm", "cli", "sdk", diff --git a/bindings/python/README.md b/bindings/python/README.md index d8cea197eb..d5d3df0ac8 100644 --- a/bindings/python/README.md +++ b/bindings/python/README.md @@ -96,7 +96,7 @@ The following example creates a Client instance connected to the Shimmer Testnet ## Wallet Usage -The following example will create a new Wallet Account using a StrongholdSecretManager, and then print the account's information. +The following example will create a new Wallet using a StrongholdSecretManager, and then print the wallet's information. [examples/wallet/getting_started.py](examples/wallet/getting_started.py) diff --git a/bindings/python/examples/wallet/getting_started.py b/bindings/python/examples/wallet/getting_started.py index bb001d7d75..5161ac541d 100644 --- a/bindings/python/examples/wallet/getting_started.py +++ b/bindings/python/examples/wallet/getting_started.py @@ -6,7 +6,7 @@ from dotenv import load_dotenv from iota_sdk import (ClientOptions, CoinType, StrongholdSecretManager, Utils, - Wallet) + Wallet, WalletOptions, Bip44, SecretManager) load_dotenv() @@ -28,24 +28,23 @@ secret_manager = StrongholdSecretManager( STRONGHOLD_SNAPSHOT_PATH, STRONGHOLD_PASSWORD) -# Set up and store the wallet. -client_options = ClientOptions(nodes=[node_url]) - -wallet = Wallet( - client_options=client_options, - coin_type=CoinType.SHIMMER, - secret_manager=secret_manager -) - # Generate a mnemonic and store its seed in the Stronghold vault. # INFO: It is best practice to back up the mnemonic somewhere secure. mnemonic = Utils.generate_mnemonic() print(f'Mnemonic: {mnemonic}') -wallet.store_mnemonic(mnemonic) -# Create an account. -account = wallet.create_account(ACCOUNT_ALIAS) +# SecretManager(secret_manager).store_mnemonic(mnemonic) + +# Set up and store the wallet. +client_options = ClientOptions(nodes=[node_url]) + +bib_path = Bip44( + coin_type=CoinType.SHIMMER +) +wallet_options = WalletOptions(None, None, bib_path, client_options, secret_manager) + +wallet = Wallet(wallet_options) # Get the first address and print it. -address = account.addresses()[0] -print(f'Address:\n{address.address}') +address = wallet.address() +print(f'Address:\n{address}') diff --git a/bindings/python/iota_sdk/__init__.py b/bindings/python/iota_sdk/__init__.py index a08515c175..bbbbc1ed21 100644 --- a/bindings/python/iota_sdk/__init__.py +++ b/bindings/python/iota_sdk/__init__.py @@ -1,11 +1,12 @@ # Copyright 2023 IOTA Stiftung # SPDX-License-Identifier: Apache-2.0 +from .external import * + from .client.client import Client, NodeIndexerAPI, ClientError from .client._high_level_api import GenerateAddressesOptions, GenerateAddressOptions -from .external import * from .utils import Utils -from .wallet.wallet import Wallet, Account +from .wallet.wallet import Wallet, WalletOptions from .wallet.common import WalletError from .wallet.sync_options import AccountSyncOptions, NftSyncOptions, SyncOptions from .secret_manager.secret_manager import * diff --git a/bindings/python/iota_sdk/types/common.py b/bindings/python/iota_sdk/types/common.py index 3cd9ee4218..7866ffc590 100644 --- a/bindings/python/iota_sdk/types/common.py +++ b/bindings/python/iota_sdk/types/common.py @@ -31,8 +31,16 @@ def custom_to_dict(self, *args, **kwargs): # pylint: disable=protected-access original_dict = to_dict(self, *args, **kwargs) - result = {k: v for k, v in original_dict.items() if v is not None} - return result + # recursive remove the None values + def filter_none(value): + if isinstance(value, dict): + return {k: filter_none(v) for k, v in value.items() if v is not None} + elif isinstance(value, list): + return [filter_none(item) for item in value if item is not None] + else: + return value + + return filter_none(original_dict) def custom_to_json(self, *args, **kwargs): # Use the custom to_dict method for serialization @@ -79,7 +87,7 @@ class Node(): password: Optional[str] = None disabled: Optional[bool] = None - def to_dict(self): + def to_dict(self) -> dict: """Custom dict conversion. """ diff --git a/bindings/python/iota_sdk/types/payload.py b/bindings/python/iota_sdk/types/payload.py index 280e97fb82..5187545c6a 100644 --- a/bindings/python/iota_sdk/types/payload.py +++ b/bindings/python/iota_sdk/types/payload.py @@ -5,6 +5,7 @@ from enum import IntEnum from typing import Any, Dict, List, TypeAlias, Union from dataclasses import dataclass, field +from dataclasses_json import config from iota_sdk.types.common import HexStr, json from iota_sdk.types.transaction import Transaction from iota_sdk.types.unlock import Unlock, deserialize_unlocks diff --git a/bindings/python/iota_sdk/types/transaction_options.py b/bindings/python/iota_sdk/types/transaction_options.py index 9437d99e56..fd4fd0107d 100644 --- a/bindings/python/iota_sdk/types/transaction_options.py +++ b/bindings/python/iota_sdk/types/transaction_options.py @@ -52,7 +52,7 @@ class RemainderValueStrategy(Enum): ChangeAddress = None ReuseAddress = None - def to_dict(self): + def to_dict(self) -> dict: """Custom dict conversion. """ diff --git a/bindings/python/iota_sdk/types/unlock.py b/bindings/python/iota_sdk/types/unlock.py index 5f5f4b3296..2cdc139ec1 100644 --- a/bindings/python/iota_sdk/types/unlock.py +++ b/bindings/python/iota_sdk/types/unlock.py @@ -5,6 +5,7 @@ from dataclasses import dataclass, field from enum import IntEnum from typing import Dict, List, TypeAlias, Union, Any +from dataclasses_json import config from iota_sdk.types.signature import Ed25519Signature from iota_sdk.types.common import json @@ -88,6 +89,9 @@ class NftUnlock: type: int = field(default_factory=lambda: int(UnlockType.Nft), init=False) +def deserialize_unlocks(dicts: List[Dict[str, Any]]) -> List[Unlock]: + pass + @json @dataclass class MultiUnlock: diff --git a/bindings/python/iota_sdk/utils.py b/bindings/python/iota_sdk/utils.py index 72218add02..2ff36cd25b 100644 --- a/bindings/python/iota_sdk/utils.py +++ b/bindings/python/iota_sdk/utils.py @@ -210,7 +210,7 @@ def verify_secp256k1_ecdsa_signature( @staticmethod def verify_transaction_semantic( - inputs: transaction: Transaction, inputs: List[InputSigningData], unlocks: Optional[List[Unlock]] = None) -> str: + transaction: Transaction, inputs: List[InputSigningData], unlocks: Optional[List[Unlock]] = None) -> str: """Verifies the semantic of a transaction. """ return _call_method('verifyTransactionSemantic', { diff --git a/bindings/python/iota_sdk/wallet/account.py b/bindings/python/iota_sdk/wallet/account.py deleted file mode 100644 index e1bec85b46..0000000000 --- a/bindings/python/iota_sdk/wallet/account.py +++ /dev/null @@ -1,634 +0,0 @@ -# Copyright 2023 IOTA Stiftung -# SPDX-License-Identifier: Apache-2.0 - -from typing import List, Optional, Union -from dataclasses import dataclass -from dacite import from_dict -from iota_sdk.wallet.common import _call_method_routine -from iota_sdk.wallet.prepared_transaction import PreparedTransaction, PreparedCreateTokenTransaction -from iota_sdk.wallet.sync_options import SyncOptions -from iota_sdk.types.address import AccountAddress, AddressWithUnspentOutputs -from iota_sdk.types.balance import Balance -from iota_sdk.types.burn import Burn -from iota_sdk.types.common import HexStr -from iota_sdk.types.filter_options import FilterOptions -from iota_sdk.types.native_token import NativeToken -from iota_sdk.types.output_data import OutputData -from iota_sdk.types.output_id import OutputId -from iota_sdk.types.output import BasicOutput, NftOutput, Output, deserialize_output -from iota_sdk.types.output_params import OutputParams -from iota_sdk.types.transaction_data import PreparedTransactionData, SignedTransactionData -from iota_sdk.types.send_params import CreateAccountOutputParams, CreateNativeTokenParams, MintNftParams, SendNativeTokenParams, SendNftParams, SendParams -from iota_sdk.types.transaction_with_metadata import TransactionWithMetadata -from iota_sdk.types.transaction_options import TransactionOptions -from iota_sdk.types.consolidation_params import ConsolidationParams - - -@dataclass -class AccountMetadata: - """Account metadata. - - Attributes: - alias: The alias name of the account. - coinType: The type of coin managed with the account. - index: The account index. - """ - alias: str - coinType: int - index: int - -# pylint: disable=too-many-public-methods - - -# pylint: disable=too-many-public-methods -class Account: - """A wallet account. - - Attributes: - meta: Some account metadata. - handle: The account handle. - """ - - def __init__(self, meta: dict, handle): - """Initializes an account. - - Args: - meta: The account data. - handle: The account handle. - """ - self.meta = meta - self.handle = handle - - @_call_method_routine - def _call_account_method(self, method, data=None): - message = { - 'name': 'callAccountMethod', - 'data': { - 'accountId': self.meta["index"], - 'method': { - 'name': method, - } - } - } - if data: - message['data']['method']['data'] = data - - return message - - def get_metadata(self) -> AccountMetadata: - """Get the accounts metadata. - """ - return AccountMetadata( - self.meta["alias"], self.meta["coinType"], self.meta["index"]) - - def burn( - self, burn: Burn, options: Optional[TransactionOptions] = None) -> TransactionWithMetadata: - """A generic function that can be used to burn native tokens, nfts, foundries and aliases. - """ - return self.prepare_burn(burn, options).send() - - def prepare_burn( - self, burn: Burn, options: Optional[TransactionOptions] = None) -> PreparedTransaction: - """A generic `prepare_burn()` function that can be used to prepare the burn of native tokens, nfts, foundries and accounts. - """ - prepared = self._call_account_method( - 'prepareBurn', { - 'burn': burn.to_dict(), - 'options': options - }, - ) - return PreparedTransaction(self, prepared) - - def prepare_burn_native_token(self, - token_id: HexStr, - burn_amount: int, - options: Optional[TransactionOptions] = None) -> PreparedTransaction: - """Burn native tokens. This doesn't require the foundry output which minted them, but will not increase - the foundries `melted_tokens` field, which makes it impossible to destroy the foundry output. Therefore it's - recommended to use melting, if the foundry output is available. - """ - prepared = self._call_account_method( - 'prepareBurn', { - 'burn': Burn().add_native_token(NativeToken(token_id, hex(burn_amount))).to_dict(), - 'options': options - }, - ) - return PreparedTransaction(self, prepared) - - def prepare_burn_nft(self, - nft_id: HexStr, - options: Optional[TransactionOptions] = None) -> PreparedTransaction: - """Burn an nft output. - """ - prepared = self._call_account_method( - 'prepareBurn', { - 'burn': Burn().add_nft(nft_id).to_dict(), - 'options': options - }, - ) - return PreparedTransaction(self, prepared) - - def consolidate_outputs( - self, params: ConsolidationParams) -> TransactionWithMetadata: - """Consolidate outputs. - """ - return self.prepare_consolidate_outputs(params).send() - - def prepare_consolidate_outputs( - self, params: ConsolidationParams) -> PreparedTransaction: - """Consolidate outputs. - """ - prepared = self._call_account_method( - 'prepareConsolidateOutputs', { - 'params': params - } - ) - return PreparedTransaction(self, prepared) - - def create_account_output(self, - params: Optional[CreateAccountOutputParams] = None, - options: Optional[TransactionOptions] = None) -> TransactionWithMetadata: - """Create an account output. - """ - return self.prepare_create_account_output(params, options).send() - - def prepare_create_account_output(self, - params: Optional[CreateAccountOutputParams] = None, - options: Optional[TransactionOptions] = None) -> PreparedTransaction: - """Create an account output. - """ - prepared = self._call_account_method( - 'prepareCreateAccountOutput', { - 'params': params, - 'options': options - } - ) - return PreparedTransaction(self, prepared) - - def prepare_destroy_account(self, - account_id: HexStr, - options: Optional[TransactionOptions] = None) -> PreparedTransaction: - """Destroy an account output. - """ - prepared = self._call_account_method( - 'prepareBurn', { - 'burn': Burn().add_account(account_id).to_dict(), - 'options': options - }, - ) - return PreparedTransaction(self, prepared) - - def prepare_destroy_foundry(self, - foundry_id: HexStr, - options: Optional[TransactionOptions] = None) -> PreparedTransaction: - """Destroy a foundry output with a circulating supply of 0. - """ - prepared = self._call_account_method( - 'prepareBurn', { - 'burn': Burn().add_foundry(foundry_id).to_dict(), - 'options': options - }, - ) - return PreparedTransaction(self, prepared) - - def generate_ed25519_addresses( - self, amount: int, options=None) -> List[AccountAddress]: - """Generate new addresses. - """ - addresses = self._call_account_method( - 'generateEd25519Addresses', { - 'amount': amount, - 'options': options - } - ) - return [AccountAddress.from_dict(address) for address in addresses] - - def claimable_outputs(self, outputs_to_claim: List[OutputId]): - """Get outputs with additional unlock conditions. - """ - return self._call_account_method( - 'claimableOutputs', { - 'outputsToClaim': outputs_to_claim - } - ) - - def get_output(self, output_id: OutputId) -> OutputData: - """Get output. - """ - return from_dict(OutputData, self._call_account_method( - 'getOutput', { - 'outputId': output_id - } - )) - - def get_transaction( - self, transaction_id: HexStr) -> TransactionWithMetadata: - """Get transaction. - """ - return TransactionWithMetadata.from_dict(self._call_account_method( - 'getTransaction', { - 'transactionId': transaction_id - } - )) - - def addresses(self) -> List[AccountAddress]: - """List addresses. - """ - addresses = self._call_account_method( - 'addresses' - ) - return [AccountAddress.from_dict(address) for address in addresses] - - def addresses_with_unspent_outputs( - self) -> List[AddressWithUnspentOutputs]: - """Returns only addresses of the account with unspent outputs. - """ - addresses = self._call_account_method( - 'addressesWithUnspentOutputs' - ) - return [AddressWithUnspentOutputs.from_dict(address) - for address in addresses] - - def outputs( - self, filter_options: Optional[FilterOptions] = None) -> List[OutputData]: - """Returns all outputs of the account. - """ - outputs = self._call_account_method( - 'outputs', { - 'filterOptions': filter_options - } - ) - return [OutputData.from_dict(o) for o in outputs] - - def unspent_outputs( - self, filter_options: Optional[FilterOptions] = None) -> List[OutputData]: - """Returns all unspent outputs of the account. - """ - outputs = self._call_account_method( - 'unspentOutputs', { - 'filterOptions': filter_options - } - ) - return [from_dict(OutputData, o) for o in outputs] - - def implicit_account_creation_address(self) -> str: - """Returns the implicit account creation address of the wallet if it is Ed25519 based. - """ - return self._call_account_method( - 'implicitAccountCreationAddress' - ) - - def implicit_account_transition( - self, output_id: OutputId) -> TransactionWithMetadata: - """Transitions an implicit account to an account. - """ - return self.prepare_implicit_account_transition(output_id).send() - - def prepare_implicit_account_transition( - self, output_id: OutputId) -> PreparedTransaction: - """Prepares to transition an implicit account to an account. - """ - prepared = self._call_account_method( - 'implicitAccountTransition', { - 'outputId': output_id - } - ) - return PreparedTransaction( - account=self, prepared_transaction_data=prepared) - - def accounts(self) -> List[OutputData]: - """Returns the accounts of the wallet. - """ - outputs = self._call_account_method( - 'accounts' - ) - return [from_dict(OutputData, o) for o in outputs] - - def implicit_accounts(self) -> List[OutputData]: - """Returns the implicit accounts of the wallet. - """ - outputs = self._call_account_method( - 'implicitAccounts' - ) - return [from_dict(OutputData, o) for o in outputs] - - def incoming_transactions(self) -> List[TransactionWithMetadata]: - """Returns all incoming transactions of the account. - """ - transactions = self._call_account_method( - 'incomingTransactions' - ) - return [TransactionWithMetadata.from_dict(tx) for tx in transactions] - - def transactions(self) -> List[TransactionWithMetadata]: - """Returns all transaction of the account. - """ - transactions = self._call_account_method( - 'transactions' - ) - return [TransactionWithMetadata.from_dict(tx) for tx in transactions] - - def pending_transactions(self): - """Returns all pending transactions of the account. - """ - transactions = self._call_account_method( - 'pendingTransactions' - ) - return [TransactionWithMetadata.from_dict(tx) for tx in transactions] - - def create_native_token(self, params: CreateNativeTokenParams, - options: Optional[TransactionOptions] = None) -> TransactionWithMetadata: - """Create native token. - """ - return self.prepare_create_native_token(params, options).send() - - def prepare_create_native_token(self, params: CreateNativeTokenParams, - options: Optional[TransactionOptions] = None) -> PreparedTransaction: - """Create native token. - """ - prepared = self._call_account_method( - 'prepareCreateNativeToken', { - 'params': params, - 'options': options - } - ) - return PreparedCreateTokenTransaction( - account=self, prepared_transaction_data=prepared) - - def melt_native_token(self, - token_id: HexStr, - melt_amount: int, - options: Optional[TransactionOptions] = None) -> TransactionWithMetadata: - """Melt native tokens. This happens with the foundry output which minted them, by increasing it's - `melted_tokens` field. - """ - return self.prepare_melt_native_token( - token_id, melt_amount, options).send() - - def prepare_melt_native_token(self, - token_id: HexStr, - melt_amount: int, - options: Optional[TransactionOptions] = None) -> PreparedTransaction: - """Melt native tokens. This happens with the foundry output which minted them, by increasing it's - `melted_tokens` field. - """ - prepared = self._call_account_method( - 'prepareMeltNativeToken', { - 'tokenId': token_id, - 'meltAmount': hex(melt_amount), - 'options': options - } - ) - return PreparedTransaction(self, prepared) - - def mint_native_token(self, token_id: HexStr, mint_amount: int, - options: Optional[TransactionOptions] = None) -> TransactionWithMetadata: - """Mint additional native tokens. - """ - return self.prepare_mint_native_token( - token_id, mint_amount, options).send() - - def prepare_mint_native_token(self, token_id: HexStr, mint_amount: int, - options: Optional[TransactionOptions] = None) -> PreparedTransaction: - """Mint additional native tokens. - """ - prepared = self._call_account_method( - 'prepareMintNativeToken', { - 'tokenId': token_id, - 'mintAmount': hex(mint_amount), - 'options': options - } - ) - return PreparedTransaction(self, prepared) - - def mint_nfts(self, params: List[MintNftParams], - options: Optional[TransactionOptions] = None) -> TransactionWithMetadata: - """Mint NFTs. - """ - return self.prepare_mint_nfts(params, options).send() - - def prepare_mint_nfts(self, params: List[MintNftParams], - options: Optional[TransactionOptions] = None) -> PreparedTransaction: - """Mint NFTs. - """ - prepared = self._call_account_method( - 'prepareMintNfts', { - 'params': params, - 'options': options - } - ) - return PreparedTransaction(self, prepared) - - def get_balance(self) -> Balance: - """Get account balance information. - """ - return Balance.from_dict(self._call_account_method( - 'getBalance' - )) - - def prepare_output(self, params: OutputParams, - transaction_options: Optional[TransactionOptions] = None) -> Union[BasicOutput, NftOutput]: - """Prepare an output for sending. - If the amount is below the minimum required storage deposit, by default the remaining amount will automatically - be added with a StorageDepositReturn UnlockCondition, when setting the ReturnStrategy to `gift`, the full - minimum required storage deposit will be sent to the recipient. - When the assets contain an nft_id, the data from the existing nft output will be used, just with the address - unlock conditions replaced - """ - return deserialize_output(self._call_account_method( - 'prepareOutput', { - 'params': params, - 'transactionOptions': transaction_options - }) - ) - - def prepare_send(self, params: List[SendParams], - options: Optional[TransactionOptions] = None) -> PreparedTransaction: - """Prepare to send base coins. - """ - prepared = self._call_account_method( - 'prepareSend', { - 'params': params, - 'options': options - } - ) - return PreparedTransaction(self, prepared) - - def send_transaction( - self, outputs: List[Output], options: Optional[TransactionOptions] = None) -> TransactionWithMetadata: - """Send a transaction. - """ - return self.prepare_transaction(outputs, options).send() - - def prepare_transaction( - self, outputs: List[Output], options: Optional[TransactionOptions] = None) -> PreparedTransaction: - """Prepare transaction. - """ - prepared = self._call_account_method( - 'prepareTransaction', { - 'outputs': outputs, - 'options': options - } - ) - return PreparedTransaction(self, prepared) - - def reissue_transaction_until_included( - self, transaction_id: HexStr, interval=None, max_attempts=None) -> HexStr: - """Reissues a transaction sent from the account for a provided transaction id until it's - included (referenced by a milestone). Returns the included block id. - """ - return self._call_account_method( - 'reissueTransactionUntilIncluded', { - 'transactionId': transaction_id, - 'interval': interval, - 'maxAttempts': max_attempts - } - ) - - def sync(self, options: Optional[SyncOptions] = None) -> Balance: - """Sync the account by fetching new information from the nodes. - Will also reissue pending transactions and consolidate outputs if necessary. - A custom default can be set using set_default_sync_options. - """ - return from_dict(Balance, self._call_account_method( - 'sync', { - 'options': options, - } - )) - - def send(self, amount: int, address: str, - options: Optional[TransactionOptions] = None) -> TransactionWithMetadata: - """Send base coins. - """ - return TransactionWithMetadata.from_dict(self._call_account_method( - 'send', { - 'amount': str(amount), - 'address': address, - 'options': options - } - )) - - def send_with_params( - self, params: List[SendParams], options: Optional[TransactionOptions] = None) -> TransactionWithMetadata: - """Send base coins to multiple addresses or with additional parameters. - """ - return TransactionWithMetadata.from_dict(self._call_account_method( - 'sendWithParams', { - 'params': [param.to_dict() for param in params], - 'options': options - } - )) - - def send_native_tokens( - self, params: List[SendNativeTokenParams], options: Optional[TransactionOptions] = None) -> TransactionWithMetadata: - """Send native tokens. - """ - return self.prepare_send_native_tokens(params, options).send() - - def prepare_send_native_tokens( - self, - params: List[SendNativeTokenParams], - options: Optional[TransactionOptions] = None) -> PreparedTransaction: - """Send native tokens. - """ - prepared = self._call_account_method( - 'prepareSendNativeTokens', { - 'params': params, - 'options': options - } - ) - return PreparedTransaction(self, prepared) - - def send_nft(self, params: List[SendNftParams], - options: Optional[TransactionOptions] = None) -> TransactionWithMetadata: - """Send nft. - """ - return self.prepare_send_nft(params, options).send() - - def prepare_send_nft(self, params: List[SendNftParams], - options: Optional[TransactionOptions] = None) -> PreparedTransaction: - """Send nft. - """ - prepared = self._call_account_method( - 'prepareSendNft', { - 'params': params, - 'options': options - } - ) - return PreparedTransaction(self, prepared) - - def set_alias(self, alias: str): - """Set alias. - """ - return self._call_account_method( - 'setAlias', { - 'alias': alias - } - ) - - def set_default_sync_options(self, options: SyncOptions): - """Set the fallback SyncOptions for account syncing. - If storage is enabled, will persist during restarts. - """ - return self._call_account_method( - 'setDefaultSyncOptions', { - 'options': options - } - ) - - def sign_transaction( - self, prepared_transaction_data: PreparedTransactionData) -> SignedTransactionData: - """Sign a transaction. - """ - return SignedTransactionData.from_dict(self._call_account_method( - 'signTransaction', { - 'preparedTransactionData': prepared_transaction_data - } - )) - - def sign_and_submit_transaction( - self, prepared_transaction_data: PreparedTransactionData) -> TransactionWithMetadata: - """Validate the transaction, sign it, submit it to a node and store it in the account. - """ - return TransactionWithMetadata.from_dict(self._call_account_method( - 'signAndSubmitTransaction', { - 'preparedTransactionData': prepared_transaction_data - } - )) - - def submit_and_store_transaction( - self, signed_transaction_data: SignedTransactionData) -> TransactionWithMetadata: - """Submit and store transaction. - """ - return TransactionWithMetadata.from_dict(self._call_account_method( - 'submitAndStoreTransaction', { - 'signedTransactionData': signed_transaction_data - } - )) - - def claim_outputs( - self, output_ids_to_claim: List[OutputId]) -> TransactionWithMetadata: - """Claim outputs. - """ - return self.prepare_claim_outputs(output_ids_to_claim).send() - - def prepare_claim_outputs( - self, output_ids_to_claim: List[OutputId]) -> PreparedTransaction: - """Claim outputs. - """ - return PreparedTransaction(self, self._call_account_method( - 'prepareClaimOutputs', { - 'outputIdsToClaim': output_ids_to_claim - } - )) - - def send_outputs( - self, outputs: List[Output], options: Optional[TransactionOptions] = None) -> TransactionWithMetadata: - """Send outputs in a transaction. - """ - return TransactionWithMetadata.from_dict(self._call_account_method( - 'sendOutputs', { - 'outputs': outputs, - 'options': options, - } - )) diff --git a/bindings/python/iota_sdk/wallet/wallet.py b/bindings/python/iota_sdk/wallet/wallet.py index ecaa2bf335..9290c6a7f2 100644 --- a/bindings/python/iota_sdk/wallet/wallet.py +++ b/bindings/python/iota_sdk/wallet/wallet.py @@ -3,16 +3,50 @@ from json import dumps from typing import Any, Dict, List, Optional, Union +from dataclasses import dataclass from iota_sdk import destroy_wallet, create_wallet, listen_wallet, get_client_from_wallet, get_secret_manager_from_wallet, Client from iota_sdk.secret_manager.secret_manager import LedgerNanoSecretManager, MnemonicSecretManager, StrongholdSecretManager, SeedSecretManager, SecretManager from iota_sdk.types.address import AccountAddress -from iota_sdk.wallet.account import Account, _call_method_routine + from iota_sdk.wallet.sync_options import SyncOptions +from iota_sdk.wallet.common import _call_method_routine +from iota_sdk.wallet.prepared_transaction import PreparedTransaction, PreparedCreateTokenTransaction +from iota_sdk.wallet.sync_options import SyncOptions +from iota_sdk.types.address import AccountAddress, AddressWithUnspentOutputs +from iota_sdk.types.balance import Balance +from iota_sdk.types.burn import Burn +from iota_sdk.types.common import HexStr, json +from iota_sdk.types.client_options import ClientOptions +from iota_sdk.types.filter_options import FilterOptions +from iota_sdk.types.native_token import NativeToken +from iota_sdk.types.output_data import OutputData +from iota_sdk.types.output_id import OutputId +from iota_sdk.types.output import BasicOutput, NftOutput, Output, deserialize_output +from iota_sdk.types.output_params import OutputParams +from iota_sdk.types.transaction_data import PreparedTransactionData, SignedTransactionData +from iota_sdk.types.send_params import CreateAccountOutputParams, CreateNativeTokenParams, MintNftParams, SendNativeTokenParams, SendNftParams, SendParams +from iota_sdk.types.signature import Bip44 +from iota_sdk.types.transaction_with_metadata import TransactionWithMetadata +from iota_sdk.types.transaction_options import TransactionOptions +from iota_sdk.types.consolidation_params import ConsolidationParams + # pylint: disable=too-many-public-methods +@json +@dataclass +class WalletOptions: + """Options for the Wallet builder.""" + address: Optional[str] = None + alias: Optional[str] = None + bip_path: Optional[Bip44] = None + client_options: Optional[ClientOptions] = None + secret_manager: Optional[Union[LedgerNanoSecretManager, MnemonicSecretManager, SeedSecretManager, StrongholdSecretManager]] = None + storage_path: Optional[str] = None + + class Wallet(): """An IOTA Wallet. @@ -20,74 +54,17 @@ class Wallet(): handle: The wallet handle. """ - def __init__(self, - storage_path: Optional[str] = None, - client_options: Optional[Dict[str, Any]] = None, - coin_type: Optional[int] = None, - secret_manager: Optional[Union[LedgerNanoSecretManager, MnemonicSecretManager, SeedSecretManager, StrongholdSecretManager]] = None): + def __init__(self, options: WalletOptions): """Initialize `self`. """ - - # Setup the options - options: Dict[str, Any] = {'storagePath': storage_path} - if client_options: - options['clientOptions'] = client_options.to_dict() - if coin_type: - options['coinType'] = coin_type - if secret_manager: - options['secretManager'] = secret_manager - - options_str: str = dumps(options) - # Create the message handler - self.handle = create_wallet(options_str) + self.handle = create_wallet(dumps(options.to_dict())) def get_handle(self): """Return the wallet handle. """ return self.handle - def create_account(self, alias: Optional[str] = None, bech32_hrp: Optional[str] - = None, addresses: Optional[AccountAddress] = None) -> Account: - """Create a new account. - - Args: - alias: The alias of the new account. - bech32_hrp: The Bech32 HRP of the new account. - - Returns: - An account object. - """ - account_data = self._call_method( - 'createAccount', { - 'alias': self.__return_str_or_none(alias), - 'bech32Hrp': self.__return_str_or_none(bech32_hrp), - 'addresses': addresses, - } - ) - return Account(account_data, self.handle) - - def get_account(self, account_id: Union[str, int]) -> Account: - """Get the account associated with the given account ID or index. - """ - account_data = self._call_method( - 'getAccount', { - 'accountId': account_id, - } - ) - return Account(account_data, self.handle) - - def get_client(self): - """Get the client associated with the wallet. - """ - return Client(client_handle=get_client_from_wallet(self.handle)) - - def get_secret_manager(self): - """Get the secret manager associated with the wallet. - """ - return SecretManager( - secret_manager_handle=get_secret_manager_from_wallet(self.handle)) - @_call_method_routine def _call_method(self, name: str, data=None): message = { @@ -97,24 +74,6 @@ def _call_method(self, name: str, data=None): message['data'] = data return message - def get_account_data(self, account_id: Union[str, int]): - """Get account data associated with the given account ID or index. - """ - return self._call_method( - 'getAccount', { - 'accountId': account_id - } - ) - - def get_accounts(self): - """Get all accounts. - """ - accounts_data = self._call_method( - 'getAccounts', - ) - return [Account(account_data, self.handle) - for account_data in accounts_data] - def backup(self, destination: str, password: str): """Backup storage. """ @@ -149,24 +108,47 @@ def is_stronghold_password_available(self) -> bool: 'isStrongholdPasswordAvailable' ) - def recover_accounts(self, account_start_index: int, account_gap_limit: int, - address_gap_limit: int, sync_options: Optional[SyncOptions] = None): - """Recover accounts. + def destroy(self): + """Destroys the wallet instance. + """ + return destroy_wallet(self.handle) + + def emit_test_event(self, event) -> bool: + """Return whether a Stronghold password is available. """ return self._call_method( - 'recoverAccounts', { - 'accountStartIndex': account_start_index, - 'accountGapLimit': account_gap_limit, - 'addressGapLimit': address_gap_limit, - 'syncOptions': sync_options - } + 'emitTestEvent', { + 'event': event, + }, ) - def remove_latest_account(self): - """Remove latest account. + def get_client(self): + """Get the client associated with the wallet. + """ + return Client(client_handle=get_client_from_wallet(self.handle)) + + def get_secret_manager(self): + """Get the secret manager associated with the wallet. + """ + return SecretManager( + secret_manager_handle=get_secret_manager_from_wallet(self.handle)) + + def listen(self, handler, events: Optional[List[int]] = None): + """Listen to wallet events, empty array or None will listen to all events. + The default value for events is None. """ + events_array = [] if events is None else events + listen_wallet(self.handle, events_array, handler) + + def clear_listeners(self, events: Optional[List[int]] = None): + """Remove wallet event listeners, empty array or None will remove all listeners. + The default value for events is None. + """ + events_array = [] if events is None else events return self._call_method( - 'removeLatestAccount' + 'clearListeners', { + 'eventTypes': events_array + } ) def restore_backup(self, source: str, password: str): @@ -193,20 +175,6 @@ def set_client_options(self, client_options): } ) - def generate_ed25519_address(self, account_index: int, internal: bool, address_index: int, - options=None, bech32_hrp: Optional[str] = None) -> List[str]: - """Generate an address without storing it. - """ - return self._call_method( - 'generateEd25519Address', { - 'accountIndex': account_index, - 'internal': internal, - 'addressIndex': address_index, - 'options': options, - 'bech32Hrp': bech32_hrp - } - ) - def set_stronghold_password(self, password: str): """Set stronghold password. """ @@ -227,6 +195,24 @@ def set_stronghold_password_clear_interval( } ) + def start_background_sync( + self, options: Optional[SyncOptions] = None, interval_in_milliseconds: Optional[int] = None): + """Start background syncing. + """ + return self._call_method( + 'startBackgroundSync', { + 'options': options, + 'intervalInMilliseconds': interval_in_milliseconds + } + ) + + def stop_background_sync(self): + """Stop background syncing. + """ + return self._call_method( + 'stopBackgroundSync', + ) + def store_mnemonic(self, mnemonic: str): """Store mnemonic. """ @@ -234,49 +220,555 @@ def store_mnemonic(self, mnemonic: str): 'storeMnemonic', { 'mnemonic': mnemonic } + ) + def update_node_auth(self, url: str, auth=None): + """Update the authentication for the provided node. + """ + return self._call_method( + 'updateNodeAuth', { + 'url': mnemonic, + 'auth': auth + } ) - def start_background_sync( - self, options: Optional[SyncOptions] = None, interval_in_milliseconds: Optional[int] = None): - """Start background syncing. + def accounts(self) -> List[OutputData]: + """Returns the accounts of the wallet. + """ + outputs = self._call_method( + 'accounts' + ) + return [from_dict(OutputData, o) for o in outputs] + + def burn( + self, burn: Burn, options: Optional[TransactionOptions] = None) -> TransactionWithMetadata: + """A generic function that can be used to burn native tokens, nfts, foundries and aliases. + """ + return self.prepare_burn(burn, options).send() + + def prepare_burn( + self, burn: Burn, options: Optional[TransactionOptions] = None) -> PreparedTransaction: + """A generic `prepare_burn()` function that can be used to prepare the burn of native tokens, nfts, foundries and accounts. + """ + prepared = self._call_method( + 'prepareBurn', { + 'burn': burn.to_dict(), + 'options': options + }, + ) + return PreparedTransaction(self, prepared) + + def prepare_burn_native_token(self, + token_id: HexStr, + burn_amount: int, + options: Optional[TransactionOptions] = None) -> PreparedTransaction: + """Burn native tokens. This doesn't require the foundry output which minted them, but will not increase + the foundries `melted_tokens` field, which makes it impossible to destroy the foundry output. Therefore it's + recommended to use melting, if the foundry output is available. + """ + prepared = self._call_method( + 'prepareBurn', { + 'burn': Burn().add_native_token(NativeToken(token_id, hex(burn_amount))).to_dict(), + 'options': options + }, + ) + return PreparedTransaction(self, prepared) + + def prepare_burn_nft(self, + nft_id: HexStr, + options: Optional[TransactionOptions] = None) -> PreparedTransaction: + """Burn an nft output. + """ + prepared = self._call_method( + 'prepareBurn', { + 'burn': Burn().add_nft(nft_id).to_dict(), + 'options': options + }, + ) + return PreparedTransaction(self, prepared) + + def claim_outputs( + self, output_ids_to_claim: List[OutputId]) -> TransactionWithMetadata: + """Claim outputs. + """ + return self.prepare_claim_outputs(output_ids_to_claim).send() + + def prepare_claim_outputs( + self, output_ids_to_claim: List[OutputId]) -> PreparedTransaction: + """Claim outputs. + """ + return PreparedTransaction(self, self._call_method( + 'prepareClaimOutputs', { + 'outputIdsToClaim': output_ids_to_claim + } + )) + + def consolidate_outputs( + self, params: ConsolidationParams) -> TransactionWithMetadata: + """Consolidate outputs. + """ + return self.prepare_consolidate_outputs(params).send() + + def prepare_consolidate_outputs( + self, params: ConsolidationParams) -> PreparedTransaction: + """Consolidate outputs. + """ + prepared = self._call_method( + 'prepareConsolidateOutputs', { + 'params': params + } + ) + return PreparedTransaction(self, prepared) + + def create_account_output(self, + params: Optional[CreateAccountOutputParams] = None, + options: Optional[TransactionOptions] = None) -> TransactionWithMetadata: + """Create an account output. + """ + return self.prepare_create_account_output(params, options).send() + + def prepare_create_account_output(self, + params: Optional[CreateAccountOutputParams] = None, + options: Optional[TransactionOptions] = None) -> PreparedTransaction: + """Create an account output. + """ + prepared = self._call_method( + 'prepareCreateAccountOutput', { + 'params': params, + 'options': options + } + ) + return PreparedTransaction(self, prepared) + + def melt_native_token(self, + token_id: HexStr, + melt_amount: int, + options: Optional[TransactionOptions] = None) -> TransactionWithMetadata: + """Melt native tokens. This happens with the foundry output which minted them, by increasing it's + `melted_tokens` field. + """ + return self.prepare_melt_native_token( + token_id, melt_amount, options).send() + + def prepare_melt_native_token(self, + token_id: HexStr, + melt_amount: int, + options: Optional[TransactionOptions] = None) -> PreparedTransaction: + """Melt native tokens. This happens with the foundry output which minted them, by increasing it's + `melted_tokens` field. + """ + prepared = self._call_method( + 'prepareMeltNativeToken', { + 'tokenId': token_id, + 'meltAmount': hex(melt_amount), + 'options': options + } + ) + return PreparedTransaction(self, prepared) + + def prepare_destroy_account(self, + account_id: HexStr, + options: Optional[TransactionOptions] = None) -> PreparedTransaction: + """Destroy an account output. + """ + prepared = self._call_method( + 'prepareBurn', { + 'burn': Burn().add_account(account_id).to_dict(), + 'options': options + }, + ) + return PreparedTransaction(self, prepared) + + def prepare_destroy_foundry(self, + foundry_id: HexStr, + options: Optional[TransactionOptions] = None) -> PreparedTransaction: + """Destroy a foundry output with a circulating supply of 0. + """ + prepared = self._call_method( + 'prepareBurn', { + 'burn': Burn().add_foundry(foundry_id).to_dict(), + 'options': options + }, + ) + return PreparedTransaction(self, prepared) + + def get_balance(self) -> Balance: + """Get account balance information. + """ + return Balance.from_dict(self._call_method( + 'getBalance' + )) + + def get_output(self, output_id: OutputId) -> OutputData: + """Get output. + """ + return from_dict(OutputData, self._call_method( + 'getOutput', { + 'outputId': output_id + } + )) + + def get_foundry_output(self, token_id: HexStr): + """Get a `FoundryOutput` by native token ID. It will try to get the foundry from the account, if it isn't in the wallet it will try to get it from the node. """ return self._call_method( - 'startBackgroundSync', { - 'options': options, - 'intervalInMilliseconds': interval_in_milliseconds + 'getFoundryOutput', { + 'tokenId': token_id } ) - def stop_background_sync(self): - """Stop background syncing. + def claimable_outputs(self, outputs_to_claim: List[OutputId]): + """Get outputs with additional unlock conditions. """ return self._call_method( - 'stopBackgroundSync', + 'claimableOutputs', { + 'outputsToClaim': outputs_to_claim + } ) - def listen(self, handler, events: Optional[List[int]] = None): - """Listen to wallet events, empty array or None will listen to all events. - The default value for events is None. + def get_transaction( + self, transaction_id: HexStr) -> TransactionWithMetadata: + """Get transaction. """ - events_array = [] if events is None else events - listen_wallet(self.handle, events_array, handler) + return TransactionWithMetadata.from_dict(self._call_method( + 'getTransaction', { + 'transactionId': transaction_id + } + )) - def clear_listeners(self, events: Optional[List[int]] = None): - """Remove wallet event listeners, empty array or None will remove all listeners. - The default value for events is None. + def address(self) -> str: + """Get the address of the wallet. """ - events_array = [] if events is None else events return self._call_method( - 'clearListeners', { - 'eventTypes': events_array + 'getAddress' + ) + + def outputs( + self, filter_options: Optional[FilterOptions] = None) -> List[OutputData]: + """Returns all outputs of the account. + """ + outputs = self._call_method( + 'outputs', { + 'filterOptions': filter_options } ) + return [OutputData.from_dict(o) for o in outputs] - def destroy(self): - """Destroys the wallet instance. + def pending_transactions(self): + """Returns all pending transactions of the account. """ - return destroy_wallet(self.handle) + transactions = self._call_method( + 'pendingTransactions' + ) + return [TransactionWithMetadata.from_dict(tx) for tx in transactions] + + def implicit_account_creation_address(self) -> str: + """Returns the implicit account creation address of the wallet if it is Ed25519 based. + """ + return self._call_method( + 'implicitAccountCreationAddress' + ) + + def implicit_account_transition( + self, output_id: OutputId) -> TransactionWithMetadata: + """Transitions an implicit account to an account. + """ + return self.prepare_implicit_account_transition(output_id).send() + + def prepare_implicit_account_transition( + self, output_id: OutputId) -> PreparedTransaction: + """Prepares to transition an implicit account to an account. + """ + prepared = self._call_method( + 'implicitAccountTransition', { + 'outputId': output_id + } + ) + return PreparedTransaction( + account=self, prepared_transaction_data=prepared) + + def implicit_accounts(self) -> List[OutputData]: + """Returns the implicit accounts of the wallet. + """ + outputs = self._call_method( + 'implicitAccounts' + ) + return [from_dict(OutputData, o) for o in outputs] + + def incoming_transactions(self) -> List[TransactionWithMetadata]: + """Returns all incoming transactions of the account. + """ + transactions = self._call_method( + 'incomingTransactions' + ) + return [TransactionWithMetadata.from_dict(tx) for tx in transactions] + + def transactions(self) -> List[TransactionWithMetadata]: + """Returns all transaction of the account. + """ + transactions = self._call_method( + 'transactions' + ) + return [TransactionWithMetadata.from_dict(tx) for tx in transactions] + + def unspent_outputs( + self, filter_options: Optional[FilterOptions] = None) -> List[OutputData]: + """Returns all unspent outputs of the account. + """ + outputs = self._call_method( + 'unspentOutputs', { + 'filterOptions': filter_options + } + ) + return [from_dict(OutputData, o) for o in outputs] + + def mint_native_token(self, token_id: HexStr, mint_amount: int, + options: Optional[TransactionOptions] = None) -> TransactionWithMetadata: + """Mint additional native tokens. + """ + return self.prepare_mint_native_token( + token_id, mint_amount, options).send() + + def prepare_mint_native_token(self, token_id: HexStr, mint_amount: int, + options: Optional[TransactionOptions] = None) -> PreparedTransaction: + """Mint additional native tokens. + """ + prepared = self._call_method( + 'prepareMintNativeToken', { + 'tokenId': token_id, + 'mintAmount': hex(mint_amount), + 'options': options + } + ) + return PreparedTransaction(self, prepared) + + def create_native_token(self, params: CreateNativeTokenParams, + options: Optional[TransactionOptions] = None) -> TransactionWithMetadata: + """Create native token. + """ + return self.prepare_create_native_token(params, options).send() + + def prepare_create_native_token(self, params: CreateNativeTokenParams, + options: Optional[TransactionOptions] = None) -> PreparedTransaction: + """Create native token. + """ + prepared = self._call_method( + 'prepareCreateNativeToken', { + 'params': params, + 'options': options + } + ) + return PreparedCreateTokenTransaction( + account=self, prepared_transaction_data=prepared) + + def mint_nfts(self, params: List[MintNftParams], + options: Optional[TransactionOptions] = None) -> TransactionWithMetadata: + """Mint NFTs. + """ + return self.prepare_mint_nfts(params, options).send() + + def prepare_mint_nfts(self, params: List[MintNftParams], + options: Optional[TransactionOptions] = None) -> PreparedTransaction: + """Mint NFTs. + """ + prepared = self._call_method( + 'prepareMintNfts', { + 'params': params, + 'options': options + } + ) + return PreparedTransaction(self, prepared) + + def prepare_output(self, params: OutputParams, + transaction_options: Optional[TransactionOptions] = None) -> Union[BasicOutput, NftOutput]: + """Prepare an output for sending. + If the amount is below the minimum required storage deposit, by default the remaining amount will automatically + be added with a StorageDepositReturn UnlockCondition, when setting the ReturnStrategy to `gift`, the full + minimum required storage deposit will be sent to the recipient. + When the assets contain an nft_id, the data from the existing nft output will be used, just with the address + unlock conditions replaced + """ + return deserialize_output(self._call_method( + 'prepareOutput', { + 'params': params, + 'transactionOptions': transaction_options + }) + ) + + def prepare_send(self, params: List[SendParams], + options: Optional[TransactionOptions] = None) -> PreparedTransaction: + """Prepare to send base coins. + """ + prepared = self._call_method( + 'prepareSend', { + 'params': params, + 'options': options + } + ) + return PreparedTransaction(self, prepared) + + def send_transaction( + self, outputs: List[Output], options: Optional[TransactionOptions] = None) -> TransactionWithMetadata: + """Send a transaction. + """ + return self.prepare_transaction(outputs, options).send() + + def prepare_transaction( + self, outputs: List[Output], options: Optional[TransactionOptions] = None) -> PreparedTransaction: + """Prepare transaction. + """ + prepared = self._call_method( + 'prepareTransaction', { + 'outputs': outputs, + 'options': options + } + ) + return PreparedTransaction(self, prepared) + + def reissue_transaction_until_included( + self, transaction_id: HexStr, interval=None, max_attempts=None) -> HexStr: + """Reissues a transaction sent from the account for a provided transaction id until it's + included (referenced by a milestone). Returns the included block id. + """ + return self._call_method( + 'reissueTransactionUntilIncluded', { + 'transactionId': transaction_id, + 'interval': interval, + 'maxAttempts': max_attempts + } + ) + + def send(self, amount: int, address: str, + options: Optional[TransactionOptions] = None) -> TransactionWithMetadata: + """Send base coins. + """ + return TransactionWithMetadata.from_dict(self._call_method( + 'send', { + 'amount': str(amount), + 'address': address, + 'options': options + } + )) + + def send_with_params( + self, params: List[SendParams], options: Optional[TransactionOptions] = None) -> TransactionWithMetadata: + """Send base coins to multiple addresses or with additional parameters. + """ + return TransactionWithMetadata.from_dict(self._call_method( + 'sendWithParams', { + 'params': [param.to_dict() for param in params], + 'options': options + } + )) + + def send_native_tokens( + self, params: List[SendNativeTokenParams], options: Optional[TransactionOptions] = None) -> TransactionWithMetadata: + """Send native tokens. + """ + return self.prepare_send_native_tokens(params, options).send() + + def prepare_send_native_tokens( + self, + params: List[SendNativeTokenParams], + options: Optional[TransactionOptions] = None) -> PreparedTransaction: + """Send native tokens. + """ + prepared = self._call_method( + 'prepareSendNativeTokens', { + 'params': params, + 'options': options + } + ) + return PreparedTransaction(self, prepared) + + def send_nft(self, params: List[SendNftParams], + options: Optional[TransactionOptions] = None) -> TransactionWithMetadata: + """Send nft. + """ + return self.prepare_send_nft(params, options).send() + + def prepare_send_nft(self, params: List[SendNftParams], + options: Optional[TransactionOptions] = None) -> PreparedTransaction: + """Send nft. + """ + prepared = self._call_method( + 'prepareSendNft', { + 'params': params, + 'options': options + } + ) + return PreparedTransaction(self, prepared) + + def send_outputs( + self, outputs: List[Output], options: Optional[TransactionOptions] = None) -> TransactionWithMetadata: + """Send outputs in a transaction. + """ + return TransactionWithMetadata.from_dict(self._call_method( + 'sendOutputs', { + 'outputs': outputs, + 'options': options, + } + )) + + def set_alias(self, alias: str): + """Set alias. + """ + return self._call_method( + 'setAlias', { + 'alias': alias + } + ) + + def set_default_sync_options(self, options: SyncOptions): + """Set the fallback SyncOptions for account syncing. + If storage is enabled, will persist during restarts. + """ + return self._call_method( + 'setDefaultSyncOptions', { + 'options': options + } + ) + + def sign_transaction( + self, prepared_transaction_data: PreparedTransactionData) -> SignedTransactionData: + """Sign a transaction. + """ + return SignedTransactionData.from_dict(self._call_method( + 'signTransaction', { + 'preparedTransactionData': prepared_transaction_data + } + )) + + def sign_and_submit_transaction( + self, prepared_transaction_data: PreparedTransactionData) -> TransactionWithMetadata: + """Validate the transaction, sign it, submit it to a node and store it in the account. + """ + return TransactionWithMetadata.from_dict(self._call_method( + 'signAndSubmitTransaction', { + 'preparedTransactionData': prepared_transaction_data + } + )) + + def submit_and_store_transaction( + self, signed_transaction_data: SignedTransactionData) -> TransactionWithMetadata: + """Submit and store transaction. + """ + return TransactionWithMetadata.from_dict(self._call_method( + 'submitAndStoreTransaction', { + 'signedTransactionData': signed_transaction_data + } + )) + + def sync(self, options: Optional[SyncOptions] = None) -> Balance: + """Sync the account by fetching new information from the nodes. + Will also reissue pending transactions and consolidate outputs if necessary. + A custom default can be set using set_default_sync_options. + """ + return from_dict(Balance, self._call_method( + 'sync', { + 'options': options, + } + )) # pylint: disable=redefined-builtin @staticmethod From d86385f3a9ab24a7eb9563361cda49fd60015645 Mon Sep 17 00:00:00 2001 From: Brord van Wierst Date: Wed, 6 Dec 2023 03:41:09 +0100 Subject: [PATCH 02/34] tests --- .../python/iota_sdk/client/_node_core_api.py | 2 +- .../iota_sdk/secret_manager/secret_manager.py | 1 - bindings/python/iota_sdk/types/address.py | 11 ------ .../python/iota_sdk/types/output_metadata.py | 2 +- bindings/python/iota_sdk/utils.py | 2 +- .../iota_sdk/wallet/prepared_transaction.py | 14 ++++---- bindings/python/iota_sdk/wallet/wallet.py | 2 +- .../python/tests/address_generation_test.py | 34 +++++++++--------- bindings/python/tests/test_offline.py | 11 ++++-- bindings/python/tests/test_output.py | 6 ++-- bindings/python/tests/test_wallet_destroy.py | 36 +++++++++---------- 11 files changed, 56 insertions(+), 65 deletions(-) diff --git a/bindings/python/iota_sdk/client/_node_core_api.py b/bindings/python/iota_sdk/client/_node_core_api.py index b48a59798f..6f9e5009fe 100644 --- a/bindings/python/iota_sdk/client/_node_core_api.py +++ b/bindings/python/iota_sdk/client/_node_core_api.py @@ -85,7 +85,7 @@ def post_block(self, block: SignedBlock) -> HexStr: The block id of the posted block. """ return self._call_method('postBlock', { - 'block': block.__dict__ + 'block': block.to_dict() }) def get_block(self, block_id: HexStr) -> SignedBlock: diff --git a/bindings/python/iota_sdk/secret_manager/secret_manager.py b/bindings/python/iota_sdk/secret_manager/secret_manager.py index 4c3e669c96..4d348b283d 100644 --- a/bindings/python/iota_sdk/secret_manager/secret_manager.py +++ b/bindings/python/iota_sdk/secret_manager/secret_manager.py @@ -3,7 +3,6 @@ from json import dumps, loads from typing import Optional, Union -from dacite import from_dict import humps from iota_sdk.external import create_secret_manager, call_secret_manager_method diff --git a/bindings/python/iota_sdk/types/address.py b/bindings/python/iota_sdk/types/address.py index aa55d0fe5f..607042fa0a 100644 --- a/bindings/python/iota_sdk/types/address.py +++ b/bindings/python/iota_sdk/types/address.py @@ -163,17 +163,6 @@ def with_allowed_capabilities(self, capabilities: bytes): self.allowed_capabilities = None -@json -@dataclass -class AddressWithUnspentOutputs(): - """An Address with unspent outputs. - """ - address: str - key_index: int - internal: bool - output_ids: bool - - Address: TypeAlias = Union[Ed25519Address, AccountAddress, NFTAddress, diff --git a/bindings/python/iota_sdk/types/output_metadata.py b/bindings/python/iota_sdk/types/output_metadata.py index d006cdc648..9ac027eebd 100644 --- a/bindings/python/iota_sdk/types/output_metadata.py +++ b/bindings/python/iota_sdk/types/output_metadata.py @@ -65,7 +65,7 @@ def as_dict(self): """ d = {} - d['metadata'] = self.metadata.__dict__ + d['metadata'] = self.metadata.to_dict() d['output'] = self.output.as_dict() return d diff --git a/bindings/python/iota_sdk/utils.py b/bindings/python/iota_sdk/utils.py index 2ff36cd25b..0f77783e4b 100644 --- a/bindings/python/iota_sdk/utils.py +++ b/bindings/python/iota_sdk/utils.py @@ -193,7 +193,7 @@ def verify_ed25519_signature( """Verify an Ed25519 signature against a message. """ return _call_method('verifyEd25519Signature', { - 'signature': signature.__dict__, + 'signature': signature.to_dict(), 'message': message, }) diff --git a/bindings/python/iota_sdk/wallet/prepared_transaction.py b/bindings/python/iota_sdk/wallet/prepared_transaction.py index 90eb7f835e..7d3e71cb10 100644 --- a/bindings/python/iota_sdk/wallet/prepared_transaction.py +++ b/bindings/python/iota_sdk/wallet/prepared_transaction.py @@ -11,25 +11,25 @@ # Required to prevent circular import if TYPE_CHECKING: - from iota_sdk.wallet.wallet import Account + from iota_sdk.wallet.wallet import Wallet class PreparedTransaction: """A helper class for offline signing. Attributes: - account: An account object used to continue building this transaction. + wallet: An wallet object used to continue building this transaction. prepared_transaction_data_dto: A prepared transaction data object. """ def __init__( self, - account: Account, + wallet: Wallet, prepared_transaction_data: Union[PreparedTransactionData, Dict] ): """Initialize `Self`. """ - self.account = account + self.wallet = wallet self.prepared_transaction_data_dto = prepared_transaction_data def prepared_transaction_data(self) -> PreparedTransactionData: @@ -51,10 +51,10 @@ def send(self) -> TransactionWithMetadata: return self.sign_and_submit_transaction() def sign(self): - """Sign a prepared transaction using the account's private key and returns + """Sign a prepared transaction using the wallet's private key and returns the signed transaction. """ - return self.account.sign_transaction( + return self.wallet.sign_transaction( self.prepared_transaction_data()) def sign_and_submit_transaction(self) -> TransactionWithMetadata: @@ -63,7 +63,7 @@ def sign_and_submit_transaction(self) -> TransactionWithMetadata: Returns: The transaction after it has been signed and submitted. """ - return self.account.sign_and_submit_transaction( + return self.wallet.sign_and_submit_transaction( self.prepared_transaction_data()) diff --git a/bindings/python/iota_sdk/wallet/wallet.py b/bindings/python/iota_sdk/wallet/wallet.py index 9290c6a7f2..fb95972672 100644 --- a/bindings/python/iota_sdk/wallet/wallet.py +++ b/bindings/python/iota_sdk/wallet/wallet.py @@ -14,7 +14,7 @@ from iota_sdk.wallet.common import _call_method_routine from iota_sdk.wallet.prepared_transaction import PreparedTransaction, PreparedCreateTokenTransaction from iota_sdk.wallet.sync_options import SyncOptions -from iota_sdk.types.address import AccountAddress, AddressWithUnspentOutputs +from iota_sdk.types.address import AccountAddress from iota_sdk.types.balance import Balance from iota_sdk.types.burn import Burn from iota_sdk.types.common import HexStr, json diff --git a/bindings/python/tests/address_generation_test.py b/bindings/python/tests/address_generation_test.py index 8aa145bf67..566cbb69e0 100644 --- a/bindings/python/tests/address_generation_test.py +++ b/bindings/python/tests/address_generation_test.py @@ -3,10 +3,9 @@ import shutil import pytest -from iota_sdk import Wallet, MnemonicSecretManager, CoinType, ClientOptions +from iota_sdk import Wallet, MnemonicSecretManager, CoinType, ClientOptions, WalletOptions, Bip44 -@pytest.mark.skip(reason="https://github.com/iotaledger/iota-sdk/issues/1387") def test_address_generation_iota(): db_path = './test_address_generation_iota' shutil.rmtree(db_path, ignore_errors=True) @@ -16,15 +15,15 @@ def test_address_generation_iota(): secret_manager = MnemonicSecretManager( "acoustic trophy damage hint search taste love bicycle foster cradle brown govern endless depend situate athlete pudding blame question genius transfer van random vast") - wallet = Wallet(db_path, - client_options, CoinType.IOTA, secret_manager) - - account = wallet.create_account('Alice') + bib_path = Bip44( + coin_type=CoinType.IOTA + ) + wallet_options = WalletOptions(None, None, bib_path, client_options, secret_manager, db_path) + wallet = Wallet(wallet_options) - addresses = account.addresses() + address = wallet.address() - assert 'smr1qpg2xkj66wwgn8p2ggnp7p582gj8g6p79us5hve2tsudzpsr2ap4sp36wye' == addresses[ - 0].address + assert 'smr1qpg2xkj66wwgn8p2ggnp7p582gj8g6p79us5hve2tsudzpsr2ap4sp36wye' == address shutil.rmtree(db_path, ignore_errors=True) @@ -38,15 +37,14 @@ def test_address_generation_shimmer(): secret_manager = MnemonicSecretManager( "acoustic trophy damage hint search taste love bicycle foster cradle brown govern endless depend situate athlete pudding blame question genius transfer van random vast") - wallet = Wallet(db_path, - client_options, CoinType.SHIMMER, secret_manager) - - wallet.create_account('Alice') - - account = wallet.get_account('Alice') + + bib_path = Bip44( + coin_type=CoinType.IOTA + ) + wallet_options = WalletOptions(None, None, bib_path, client_options, secret_manager, db_path) + wallet = Wallet(wallet_options) - addresses = account.addresses() + address = account.address() - assert 'smr1qzev36lk0gzld0k28fd2fauz26qqzh4hd4cwymlqlv96x7phjxcw6ckj80y' == addresses[ - 0].address + assert 'smr1qzev36lk0gzld0k28fd2fauz26qqzh4hd4cwymlqlv96x7phjxcw6ckj80y' == address shutil.rmtree(db_path, ignore_errors=True) diff --git a/bindings/python/tests/test_offline.py b/bindings/python/tests/test_offline.py index 55c95e24f0..d6a79f83f6 100644 --- a/bindings/python/tests/test_offline.py +++ b/bindings/python/tests/test_offline.py @@ -33,20 +33,25 @@ def test_mnemonic_address_generation(): assert test['bech32_address'] == generated_address[0] -@pytest.mark.skip(reason="https://github.com/iotaledger/iota-sdk/issues/1387") def test_sign_verify_ed25519(): secret_manager = MnemonicSecretManager( "acoustic trophy damage hint search taste love bicycle foster cradle brown govern endless depend situate athlete pudding blame question genius transfer van random vast") message = utf8_to_hex('IOTA') + # IOTA coin type + bib_path = Bip44( + coin_type=CoinType.IOTA + ) + secret_manager = SecretManager(secret_manager) signature = secret_manager.sign_ed25519( message, - # IOTA coin type - Bip44(CoinType.IOTA), + bib_path, ) assert signature.signature == '0x72bf2bc8fbc5dc56d657d7de8afa5208be1db025851e81031c754b371c7a29ce9f352d12df8207f9163316f81f59eb7725e5c0e4f3228e71ffe3764a9de6b10e' + print(f'signature: {signature}') + print(f'message: {message}') valid_signature = Utils.verify_ed25519_signature( signature, message, diff --git a/bindings/python/tests/test_output.py b/bindings/python/tests/test_output.py index dabdffb0c9..848364011e 100644 --- a/bindings/python/tests/test_output.py +++ b/bindings/python/tests/test_output.py @@ -46,8 +46,9 @@ def test_output(): "type": 0, "mana": "57600", "amount": "57600", - "nativeTokens": [ + "features": [ { + "type": 5, "id": "0x086326539ce1b78eb606a75950f31698ddcb51200b4ee6e870050e6ef658cd3bab0100000000", "amount": "0x32" } @@ -85,8 +86,9 @@ def test_output(): "type": 0, "mana": "50100", "amount": "50100", - "nativeTokens": [ + "features": [ { + "type": 5, "id": "0x087f3221adb3be9ef74a69595ef282b4ca47fd98b6bf1142e7d8f9f7b265efeedc0100000000", "amount": "0x1" } diff --git a/bindings/python/tests/test_wallet_destroy.py b/bindings/python/tests/test_wallet_destroy.py index 92d7651749..9ed24497dc 100644 --- a/bindings/python/tests/test_wallet_destroy.py +++ b/bindings/python/tests/test_wallet_destroy.py @@ -4,7 +4,7 @@ import shutil import unittest import pytest -from iota_sdk import Wallet, MnemonicSecretManager, CoinType, ClientOptions, WalletError +from iota_sdk import Wallet, MnemonicSecretManager, CoinType, ClientOptions, WalletOptions, WalletError, Bip44 class WalletDestroy(unittest.TestCase): @@ -18,27 +18,23 @@ def test_wallet_destroy(self): secret_manager = MnemonicSecretManager( "acoustic trophy damage hint search taste love bicycle foster cradle brown govern endless depend situate athlete pudding blame question genius transfer van random vast") - wallet = Wallet(db_path, - client_options, CoinType.IOTA, secret_manager) + bib_path = Bip44( + coin_type=CoinType.SHIMMER + ) + wallet_options = WalletOptions(None, None, bib_path, client_options, secret_manager, db_path) + wallet = Wallet(wallet_options) - account = wallet.create_account('Alice') - - addresses = account.addresses() - assert 'smr1qpg2xkj66wwgn8p2ggnp7p582gj8g6p79us5hve2tsudzpsr2ap4sp36wye' == addresses[ - 0].address + addresses = wallet.address() + assert 'smr1qzev36lk0gzld0k28fd2fauz26qqzh4hd4cwymlqlv96x7phjxcw6ckj80y' == addresses # Destroy the wallet wallet.destroy() # Afterwards destroying we can recreate the wallet again - wallet = Wallet(db_path, - client_options, CoinType.IOTA, secret_manager) - - account = wallet.get_account('Alice') + wallet = Wallet(wallet_options) - addresses = account.addresses() - assert 'smr1qpg2xkj66wwgn8p2ggnp7p582gj8g6p79us5hve2tsudzpsr2ap4sp36wye' == addresses[ - 0].address + addresses = wallet.address() + assert 'smr1qzev36lk0gzld0k28fd2fauz26qqzh4hd4cwymlqlv96x7phjxcw6ckj80y' == addresses shutil.rmtree(db_path, ignore_errors=True) def test_wallet_destroy_error(self): @@ -46,17 +42,19 @@ def test_wallet_destroy_error(self): shutil.rmtree(db_path, ignore_errors=True) client_options = ClientOptions(nodes=[]) - secret_manager = MnemonicSecretManager( "acoustic trophy damage hint search taste love bicycle foster cradle brown govern endless depend situate athlete pudding blame question genius transfer van random vast") - wallet = Wallet(db_path, - client_options, CoinType.IOTA, secret_manager) + bib_path = Bip44( + coin_type=CoinType.SHIMMER + ) + wallet_options = WalletOptions(None, None, bib_path, client_options, secret_manager, db_path) + wallet = Wallet(wallet_options) # Destroy the wallet wallet.destroy() with self.assertRaises(WalletError): - wallet.create_account('Alice') + wallet.address() shutil.rmtree(db_path, ignore_errors=True) From ab831a3c808466924b28b1d3a79e1fe04fdbe173 Mon Sep 17 00:00:00 2001 From: Brord van Wierst Date: Wed, 6 Dec 2023 14:53:18 +0100 Subject: [PATCH 03/34] sync options --- .../python/iota_sdk/wallet/sync_options.py | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/bindings/python/iota_sdk/wallet/sync_options.py b/bindings/python/iota_sdk/wallet/sync_options.py index 4e4526ebe7..53be5ea9df 100644 --- a/bindings/python/iota_sdk/wallet/sync_options.py +++ b/bindings/python/iota_sdk/wallet/sync_options.py @@ -8,8 +8,8 @@ @json @dataclass -class AccountSyncOptions(): - """Sync options for addresses from the account. +class WalletSyncOptions(): + """Specifies what outputs should be synced for the ed25519 address from the wallet. Attributes: basic_outputs: Whether to sync basic outputs. @@ -24,8 +24,8 @@ class AccountSyncOptions(): @json @dataclass -class AliasSyncOptions(): - """Sync options for addresses from account outputs. +class AccountSyncOptions(): + """Specifies what outputs should be synced for the address of an account output. Attributes: basic_outputs: Whether to sync basic outputs. @@ -43,7 +43,7 @@ class AliasSyncOptions(): @json @dataclass class NftSyncOptions(): - """Sync options for addresses from NFT outputs. + """Specifies what outputs should be synced for the address of an nft output. Attributes: basic_outputs: Whether to sync basic outputs. @@ -73,25 +73,26 @@ class SyncOptions(): sync_pending_transactions : Checks pending transactions and reissues them if necessary. account : - Specifies what outputs should be synced for the Ed25519 addresses from the account. - alias : + Specifies what outputs should be synced for the address of an account output. + wallet : Specifies what outputs should be synced for the address of an account output. nft : Specifies what outputs should be synced for the address of an nft output. sync_only_most_basic_outputs : Specifies if only basic outputs with just an address unlock condition should be synced. - This will overwrite the `account`, `alias` and `nft` options. + This will overwrite the `wallet`, `alias` and `nft` options. sync_native_token_foundries : Sync native token foundries, so their metadata can be returned in the balance. + sync_implicit_accounts : + Sync implicit accounts. """ force_syncing: Optional[bool] = None sync_incoming_transactions: Optional[bool] = None sync_pending_transactions: Optional[bool] = None account: Optional[AccountSyncOptions] = None - # TODO Rename when we are done with Account changes - # https://github.com/iotaledger/iota-sdk/issues/647. - alias: Optional[AliasSyncOptions] = None + wallet: Optional[WalletSyncOptions] = None nft: Optional[NftSyncOptions] = None sync_only_most_basic_outputs: Optional[bool] = None sync_native_token_foundries: Optional[bool] = None + sync_implicit_accounts: Optional[bool] = None From c3b93a43dc1114b246c8688a094dc1a12c3ebd93 Mon Sep 17 00:00:00 2001 From: Brord van Wierst Date: Wed, 6 Dec 2023 21:29:01 +0100 Subject: [PATCH 04/34] init example replace --- bindings/python/.pylintrc | 2 +- .../examples/exchange/2_generate_address.py | 2 - .../examples/exchange/3_check_balance.py | 6 +-- .../examples/exchange/4_listen_events.py | 10 ++--- .../python/examples/exchange/5_send_amount.py | 4 +- .../examples/how_tos/account_output/create.py | 4 +- .../how_tos/account_output/destroy.py | 4 +- .../how_tos/account_wallet/request_funds.py | 6 +-- .../how_tos/account_wallet/transaction.py | 6 +-- .../accounts_and_addresses/check_balance.py | 4 +- .../consolidate_outputs.py | 6 +-- .../accounts_and_addresses/create_address.py | 2 - .../accounts_and_addresses/list_addresses.py | 4 +- .../accounts_and_addresses/list_outputs.py | 4 +- .../list_transactions.py | 4 +- .../advanced_transaction.py | 4 +- .../claim_transaction.py | 4 +- .../send_micro_transaction.py | 4 +- .../examples/how_tos/native_tokens/burn.py | 6 +-- .../examples/how_tos/native_tokens/create.py | 8 ++-- .../how_tos/native_tokens/destroy_foundry.py | 6 +-- .../examples/how_tos/native_tokens/melt.py | 6 +-- .../examples/how_tos/native_tokens/mint.py | 6 +-- .../examples/how_tos/native_tokens/send.py | 6 +-- .../nft_collection/00_mint_issuer_nft.py | 4 +- .../nft_collection/01_mint_collection_nft.py | 6 +-- .../python/examples/how_tos/nfts/burn_nft.py | 4 +- .../python/examples/how_tos/nfts/mint_nft.py | 4 +- .../python/examples/how_tos/nfts/send_nft.py | 4 +- .../simple_transaction/request_funds.py | 2 - .../simple_transaction/simple_transaction.py | 4 +- .../examples/wallet/12-prepare_output.py | 2 +- .../wallet/13-check-unlock-conditions.py | 4 +- .../python/examples/wallet/create_alias.py | 4 +- .../python/examples/wallet/getting_started.py | 2 +- .../offline_signing/0_generate_addresses.py | 2 +- .../offline_signing/1_prepare_transaction.py | 2 +- .../examples/wallet/transaction_options.py | 4 +- bindings/python/iota_sdk/client/_utils.py | 2 +- .../iota_sdk/secret_manager/secret_manager.py | 4 +- bindings/python/iota_sdk/types/address.py | 1 + bindings/python/iota_sdk/types/common.py | 5 +-- bindings/python/iota_sdk/types/feature.py | 1 + .../python/iota_sdk/types/output_params.py | 2 +- bindings/python/iota_sdk/types/send_params.py | 2 +- bindings/python/iota_sdk/types/unlock.py | 4 +- bindings/python/iota_sdk/utils.py | 4 +- bindings/python/iota_sdk/wallet/wallet.py | 38 +++++++------------ 48 files changed, 77 insertions(+), 152 deletions(-) diff --git a/bindings/python/.pylintrc b/bindings/python/.pylintrc index cb914f0ddd..fb59d293c6 100644 --- a/bindings/python/.pylintrc +++ b/bindings/python/.pylintrc @@ -9,7 +9,7 @@ disable=missing-module-docstring, fixme, # TODOS too-many-instance-attributes, too-many-arguments, - too-few-public-methods + too-few-public-methods, too-many-public-methods, too-many-locals diff --git a/bindings/python/examples/exchange/2_generate_address.py b/bindings/python/examples/exchange/2_generate_address.py index 36143e754c..8624669d98 100644 --- a/bindings/python/examples/exchange/2_generate_address.py +++ b/bindings/python/examples/exchange/2_generate_address.py @@ -21,7 +21,5 @@ wallet.set_stronghold_password(os.environ["STRONGHOLD_PASSWORD"]) -account = wallet.get_account('Alice') - address = account.generate_ed25519_addresses(1)[0] print('Address:', address.address) diff --git a/bindings/python/examples/exchange/3_check_balance.py b/bindings/python/examples/exchange/3_check_balance.py index 1949e38f6c..afa1ec37b5 100644 --- a/bindings/python/examples/exchange/3_check_balance.py +++ b/bindings/python/examples/exchange/3_check_balance.py @@ -18,14 +18,12 @@ wallet = Wallet(os.environ.get('WALLET_DB_PATH')) -account = wallet.get_account('Alice') - -addresses = account.addresses() +address = wallet.address() print('Addresses:', addresses) # Set sync_only_most_basic_outputs to True if not interested in outputs that are timelocked, # have a storage deposit return, expiration or are nft/account/foundry outputs. -balance = account.sync(SyncOptions(sync_only_most_basic_outputs=True)) +balance = wallet.sync(SyncOptions(sync_only_most_basic_outputs=True)) print('Balance', balance) # Use the faucet to send tokens to your address. diff --git a/bindings/python/examples/exchange/4_listen_events.py b/bindings/python/examples/exchange/4_listen_events.py index 0da6091589..24b43dad43 100644 --- a/bindings/python/examples/exchange/4_listen_events.py +++ b/bindings/python/examples/exchange/4_listen_events.py @@ -21,8 +21,6 @@ wallet = Wallet(os.environ.get('WALLET_DB_PATH')) -account = wallet.get_account('Alice') - received_event = False @@ -41,13 +39,11 @@ def callback(event): # Only interested in new outputs here. wallet.listen(callback, [WalletEventType.NewOutput]) -account = wallet.get_account('Alice') - # Use the faucet to send testnet tokens to your address. print('Fill your address with the faucet: https://faucet.testnet.shimmer.network/') -addresses = account.addresses() -print('Send funds to:', addresses[0].address) +address = wallet.address() +print('Send funds to:', addresss) # Sync every 5 seconds until the faucet transaction gets confirmed. for _ in range(100): @@ -59,4 +55,4 @@ def callback(event): # Set sync_only_most_basic_outputs to True if not interested in outputs that are timelocked, # have a storage deposit return , expiration or are nft/account/foundry # outputs. - account.sync(SyncOptions(sync_only_most_basic_outputs=True)) + wallet.sync(SyncOptions(sync_only_most_basic_outputs=True)) diff --git a/bindings/python/examples/exchange/5_send_amount.py b/bindings/python/examples/exchange/5_send_amount.py index 2f0a2fecb0..23ccbec875 100644 --- a/bindings/python/examples/exchange/5_send_amount.py +++ b/bindings/python/examples/exchange/5_send_amount.py @@ -19,13 +19,11 @@ wallet = Wallet(os.environ.get('WALLET_DB_PATH')) -account = wallet.get_account('Alice') - wallet.set_stronghold_password(os.environ["STRONGHOLD_PASSWORD"]) # Set sync_only_most_basic_outputs to True if not interested in outputs that are timelocked, # have a storage deposit return, expiration or are nft/account/foundry outputs. -balance = account.sync(SyncOptions(sync_only_most_basic_outputs=True)) +balance = wallet.sync(SyncOptions(sync_only_most_basic_outputs=True)) print('Balance', balance) transaction = account.send( diff --git a/bindings/python/examples/how_tos/account_output/create.py b/bindings/python/examples/how_tos/account_output/create.py index c4cdb3cb96..8718da2051 100644 --- a/bindings/python/examples/how_tos/account_output/create.py +++ b/bindings/python/examples/how_tos/account_output/create.py @@ -10,10 +10,8 @@ wallet = Wallet(os.environ['WALLET_DB_PATH']) -account = wallet.get_account('Alice') - # Sync account with the node -account.sync() +wallet.sync() if 'STRONGHOLD_PASSWORD' not in os.environ: raise Exception(".env STRONGHOLD_PASSWORD is undefined, see .env.example") diff --git a/bindings/python/examples/how_tos/account_output/destroy.py b/bindings/python/examples/how_tos/account_output/destroy.py index 87fe39d91e..ac114a2d1d 100644 --- a/bindings/python/examples/how_tos/account_output/destroy.py +++ b/bindings/python/examples/how_tos/account_output/destroy.py @@ -10,10 +10,8 @@ wallet = Wallet(os.environ['WALLET_DB_PATH']) -account = wallet.get_account('Alice') - # Sync account with the node -balance = account.sync() +balance = wallet.sync() # We try to destroy the first account in the account account_id = balance.accounts[0] diff --git a/bindings/python/examples/how_tos/account_wallet/request_funds.py b/bindings/python/examples/how_tos/account_wallet/request_funds.py index e40c12181c..87a7075929 100644 --- a/bindings/python/examples/how_tos/account_wallet/request_funds.py +++ b/bindings/python/examples/how_tos/account_wallet/request_funds.py @@ -13,9 +13,7 @@ 'FAUCET_URL', 'https://faucet.testnet.shimmer.network/api/enqueue') wallet = Wallet(os.environ['WALLET_DB_PATH']) - -account = wallet.get_account('Alice') -balance = account.sync(None) +balance = wallet.sync(None) total_base_token_balance = balance.base_coin.total print( @@ -35,6 +33,6 @@ sync_options = SyncOptions(alias=AccountSyncOptions(basic_outputs=True)) -total_base_token_balance = account.sync(sync_options).base_coin.total +total_base_token_balance = wallet.sync(sync_options).base_coin.total print( f'Balance after requesting funds on account address: {total_base_token_balance}') diff --git a/bindings/python/examples/how_tos/account_wallet/transaction.py b/bindings/python/examples/how_tos/account_wallet/transaction.py index 8cf9ba73e7..95d74d3e95 100644 --- a/bindings/python/examples/how_tos/account_wallet/transaction.py +++ b/bindings/python/examples/how_tos/account_wallet/transaction.py @@ -12,14 +12,12 @@ wallet = Wallet(os.environ['WALLET_DB_PATH']) -account = wallet.get_account('Alice') - if 'STRONGHOLD_PASSWORD' not in os.environ: raise Exception(".env STRONGHOLD_PASSWORD is undefined, see .env.example") wallet.set_stronghold_password(os.environ["STRONGHOLD_PASSWORD"]) -balance = account.sync(sync_options) +balance = wallet.sync(sync_options) total_base_token_balance = balance.base_coin.total print(f'Balance before sending funds from account: {total_base_token_balance}') @@ -49,5 +47,5 @@ print( f'Transaction with custom input: https://explorer.shimmer.network/testnet/transaction/{transaction.transaction_id}') -total_base_token_balance = account.sync(sync_options).base_coin.total +total_base_token_balance = wallet.sync(sync_options).base_coin.total print(f'Balance after sending funds from account: {total_base_token_balance}') diff --git a/bindings/python/examples/how_tos/accounts_and_addresses/check_balance.py b/bindings/python/examples/how_tos/accounts_and_addresses/check_balance.py index cac977d98b..1091fbe5fa 100644 --- a/bindings/python/examples/how_tos/accounts_and_addresses/check_balance.py +++ b/bindings/python/examples/how_tos/accounts_and_addresses/check_balance.py @@ -13,10 +13,8 @@ wallet = Wallet(os.environ['WALLET_DB_PATH']) -account = wallet.get_account('Alice') - # Sync account with the node -_balance = account.sync() +_balance = wallet.sync() # Just calculate the balance with the known state balance = account.get_balance() diff --git a/bindings/python/examples/how_tos/accounts_and_addresses/consolidate_outputs.py b/bindings/python/examples/how_tos/accounts_and_addresses/consolidate_outputs.py index 576c729876..536251f06a 100644 --- a/bindings/python/examples/how_tos/accounts_and_addresses/consolidate_outputs.py +++ b/bindings/python/examples/how_tos/accounts_and_addresses/consolidate_outputs.py @@ -17,11 +17,9 @@ wallet = Wallet(os.environ['WALLET_DB_PATH']) wallet.set_stronghold_password(os.environ['STRONGHOLD_PASSWORD']) -account = wallet.get_account('Alice') - # Sync account to make sure account is updated with outputs from previous # examples. -account.sync() +wallet.sync() print('Account synced') # List unspent outputs before consolidation. @@ -57,7 +55,7 @@ ) # Sync account -account.sync() +wallet.sync() print('Account synced') # Outputs after consolidation diff --git a/bindings/python/examples/how_tos/accounts_and_addresses/create_address.py b/bindings/python/examples/how_tos/accounts_and_addresses/create_address.py index 77a63e98ad..40ca5f6b92 100644 --- a/bindings/python/examples/how_tos/accounts_and_addresses/create_address.py +++ b/bindings/python/examples/how_tos/accounts_and_addresses/create_address.py @@ -15,7 +15,5 @@ wallet.set_stronghold_password(os.environ["STRONGHOLD_PASSWORD"]) -account = wallet.get_account('Alice') - address = account.generate_ed25519_addresses(1) print('Generated address:', address[0].address) diff --git a/bindings/python/examples/how_tos/accounts_and_addresses/list_addresses.py b/bindings/python/examples/how_tos/accounts_and_addresses/list_addresses.py index 38cb28430f..615e16f274 100644 --- a/bindings/python/examples/how_tos/accounts_and_addresses/list_addresses.py +++ b/bindings/python/examples/how_tos/accounts_and_addresses/list_addresses.py @@ -12,9 +12,7 @@ wallet = Wallet(os.environ['WALLET_DB_PATH']) -account = wallet.get_account('Alice') - -addresses = account.addresses() +address = wallet.address() for address in addresses: print(address.address) diff --git a/bindings/python/examples/how_tos/accounts_and_addresses/list_outputs.py b/bindings/python/examples/how_tos/accounts_and_addresses/list_outputs.py index 5e809633ef..2154c44098 100644 --- a/bindings/python/examples/how_tos/accounts_and_addresses/list_outputs.py +++ b/bindings/python/examples/how_tos/accounts_and_addresses/list_outputs.py @@ -11,9 +11,7 @@ load_dotenv() wallet = Wallet(os.environ['WALLET_DB_PATH']) - -account = wallet.get_account('Alice') -account.sync() +wallet.sync() # All outputs stored in the account outputs = account.outputs() diff --git a/bindings/python/examples/how_tos/accounts_and_addresses/list_transactions.py b/bindings/python/examples/how_tos/accounts_and_addresses/list_transactions.py index a0e881703f..ab8dd07516 100644 --- a/bindings/python/examples/how_tos/accounts_and_addresses/list_transactions.py +++ b/bindings/python/examples/how_tos/accounts_and_addresses/list_transactions.py @@ -11,9 +11,7 @@ load_dotenv() wallet = Wallet(os.environ['WALLET_DB_PATH']) - -account = wallet.get_account('Alice') -account.sync({'syncIncomingTransactions': True}) +wallet.sync({'syncIncomingTransactions': True}) # All transactions sent from the the account transactions = account.transactions() diff --git a/bindings/python/examples/how_tos/advanced_transactions/advanced_transaction.py b/bindings/python/examples/how_tos/advanced_transactions/advanced_transaction.py index 090c7c5050..6a0c9f7caa 100644 --- a/bindings/python/examples/how_tos/advanced_transactions/advanced_transaction.py +++ b/bindings/python/examples/how_tos/advanced_transactions/advanced_transaction.py @@ -20,10 +20,8 @@ wallet = Wallet(os.environ['WALLET_DB_PATH']) -account = wallet.get_account('Alice') - # Sync account with the node -response = account.sync() +response = wallet.sync() if 'STRONGHOLD_PASSWORD' not in os.environ: raise Exception(".env STRONGHOLD_PASSWORD is undefined, see .env.example") diff --git a/bindings/python/examples/how_tos/advanced_transactions/claim_transaction.py b/bindings/python/examples/how_tos/advanced_transactions/claim_transaction.py index 32e9f55798..65e3d993ba 100644 --- a/bindings/python/examples/how_tos/advanced_transactions/claim_transaction.py +++ b/bindings/python/examples/how_tos/advanced_transactions/claim_transaction.py @@ -11,15 +11,13 @@ wallet = Wallet(os.environ['WALLET_DB_PATH']) -account = wallet.get_account('Alice') - if 'STRONGHOLD_PASSWORD' not in os.environ: raise Exception(".env STRONGHOLD_PASSWORD is undefined, see .env.example") wallet.set_stronghold_password(os.environ["STRONGHOLD_PASSWORD"]) # Sync account with the node -response = account.sync() +response = wallet.sync() # Only the unspent outputs in the account output_ids = account.claimable_outputs('All') diff --git a/bindings/python/examples/how_tos/advanced_transactions/send_micro_transaction.py b/bindings/python/examples/how_tos/advanced_transactions/send_micro_transaction.py index 2c6af5ee3e..8a337af463 100644 --- a/bindings/python/examples/how_tos/advanced_transactions/send_micro_transaction.py +++ b/bindings/python/examples/how_tos/advanced_transactions/send_micro_transaction.py @@ -10,10 +10,8 @@ wallet = Wallet(os.environ['WALLET_DB_PATH']) -account = wallet.get_account('Alice') - # Sync account with the node -response = account.sync() +response = wallet.sync() if 'STRONGHOLD_PASSWORD' not in os.environ: raise Exception(".env STRONGHOLD_PASSWORD is undefined, see .env.example") diff --git a/bindings/python/examples/how_tos/native_tokens/burn.py b/bindings/python/examples/how_tos/native_tokens/burn.py index 90ff290261..3e4fbcf806 100644 --- a/bindings/python/examples/how_tos/native_tokens/burn.py +++ b/bindings/python/examples/how_tos/native_tokens/burn.py @@ -8,10 +8,8 @@ wallet = Wallet(os.environ['WALLET_DB_PATH']) -account = wallet.get_account('Alice') - # Sync account with the node -balance = account.sync() +balance = wallet.sync() if 'STRONGHOLD_PASSWORD' not in os.environ: raise Exception(".env STRONGHOLD_PASSWORD is undefined, see .env.example") @@ -37,7 +35,7 @@ transaction.transaction_id) print(f'Block included: {os.environ["EXPLORER_URL"]}/block/{block_id}') -balance = account.sync() +balance = wallet.sync() available_balance = int( [native_balance for native_balance in balance.native_tokens if native_balance.token_id == token.token_id][0].available, 0) print(f'Balance after burning: {available_balance}') diff --git a/bindings/python/examples/how_tos/native_tokens/create.py b/bindings/python/examples/how_tos/native_tokens/create.py index 94b3fa5068..424d252102 100644 --- a/bindings/python/examples/how_tos/native_tokens/create.py +++ b/bindings/python/examples/how_tos/native_tokens/create.py @@ -10,15 +10,13 @@ wallet = Wallet(os.environ['WALLET_DB_PATH']) -account = wallet.get_account('Alice') - if 'STRONGHOLD_PASSWORD' not in os.environ: raise Exception(".env STRONGHOLD_PASSWORD is undefined, see .env.example") wallet.set_stronghold_password(os.environ["STRONGHOLD_PASSWORD"]) # Sync account with the node -balance = account.sync() +balance = wallet.sync() # We can first check if we already have an account output in our account, because # an account can have many foundry outputs and therefore we can reuse an @@ -33,7 +31,7 @@ transaction.transaction_id) print(f'Block included: {os.environ["EXPLORER_URL"]}/block/{block_id}') - account.sync() + wallet.sync() print("Account synced") print('Preparing transaction to create native token...') @@ -60,5 +58,5 @@ print(f'Created token: {prepared_transaction.token_id()}') # Ensure the account is synced after creating the native token. -account.sync() +wallet.sync() print('Account synced') diff --git a/bindings/python/examples/how_tos/native_tokens/destroy_foundry.py b/bindings/python/examples/how_tos/native_tokens/destroy_foundry.py index a3e631fc6c..447c3b2bd0 100644 --- a/bindings/python/examples/how_tos/native_tokens/destroy_foundry.py +++ b/bindings/python/examples/how_tos/native_tokens/destroy_foundry.py @@ -8,10 +8,8 @@ wallet = Wallet(os.environ['WALLET_DB_PATH']) -account = wallet.get_account('Alice') - # Sync account with the node -balance = account.sync() +balance = wallet.sync() print(f'Foundries before destroying: {len(balance.foundries)}') if 'STRONGHOLD_PASSWORD' not in os.environ: @@ -31,5 +29,5 @@ transaction.transaction_id) print(f'Block included: {os.environ["EXPLORER_URL"]}/block/{block_id}') -balance = account.sync() +balance = wallet.sync() print(f'Foundries after destroying: {len(balance.foundries)}') diff --git a/bindings/python/examples/how_tos/native_tokens/melt.py b/bindings/python/examples/how_tos/native_tokens/melt.py index 4d67341bbc..136facaba2 100644 --- a/bindings/python/examples/how_tos/native_tokens/melt.py +++ b/bindings/python/examples/how_tos/native_tokens/melt.py @@ -10,10 +10,8 @@ wallet = Wallet(os.environ['WALLET_DB_PATH']) -account = wallet.get_account('Alice') - # Sync account with the node -balance = account.sync() +balance = wallet.sync() # Find first foundry and corresponding token id token_id = balance.foundries[0] @@ -38,7 +36,7 @@ transaction.transaction_id) print(f'Block included: {os.environ["EXPLORER_URL"]}/block/{block_id}') -balance = account.sync() +balance = wallet.sync() available_balance = int( [native_balance for native_balance in balance.native_tokens if native_balance.token_id == token_id][0].available, 0) print(f'Balance after melting: {available_balance}') diff --git a/bindings/python/examples/how_tos/native_tokens/mint.py b/bindings/python/examples/how_tos/native_tokens/mint.py index 6f72425ce7..7598e5da41 100644 --- a/bindings/python/examples/how_tos/native_tokens/mint.py +++ b/bindings/python/examples/how_tos/native_tokens/mint.py @@ -10,10 +10,8 @@ wallet = Wallet(os.environ['WALLET_DB_PATH']) -account = wallet.get_account('Alice') - # Sync account with the node -balance = account.sync() +balance = wallet.sync() # Find first foundry and corresponding token id token_id = balance.foundries[0] @@ -38,7 +36,7 @@ transaction.transaction_id) print(f'Block included: {os.environ["EXPLORER_URL"]}/block/{block_id}') -balance = account.sync() +balance = wallet.sync() available_balance = int( [native_balance for native_balance in balance.native_tokens if native_balance.token_id == token_id][0].available, 0) print(f'Balance after minting: {available_balance}') diff --git a/bindings/python/examples/how_tos/native_tokens/send.py b/bindings/python/examples/how_tos/native_tokens/send.py index 7c854fe215..cabfcf74cb 100644 --- a/bindings/python/examples/how_tos/native_tokens/send.py +++ b/bindings/python/examples/how_tos/native_tokens/send.py @@ -10,10 +10,8 @@ wallet = Wallet(os.environ['WALLET_DB_PATH']) -account = wallet.get_account('Alice') - # Sync account with the node -balance = account.sync() +balance = wallet.sync() token = [native_balance for native_balance in balance.native_tokens if int( native_balance.available, 0) >= 10][0] @@ -40,7 +38,7 @@ transaction.transaction_id) print(f'Block included: {os.environ["EXPLORER_URL"]}/block/{block_id}') -balance = account.sync() +balance = wallet.sync() available_balance = int( [native_balance for native_balance in balance.native_tokens if native_balance.token_id == token.token_id][0].available, 0) print(f'Balance after sending: {available_balance}') diff --git a/bindings/python/examples/how_tos/nft_collection/00_mint_issuer_nft.py b/bindings/python/examples/how_tos/nft_collection/00_mint_issuer_nft.py index 36e2897b9e..ecd6656129 100644 --- a/bindings/python/examples/how_tos/nft_collection/00_mint_issuer_nft.py +++ b/bindings/python/examples/how_tos/nft_collection/00_mint_issuer_nft.py @@ -15,10 +15,8 @@ wallet.set_stronghold_password(os.environ["STRONGHOLD_PASSWORD"]) -account = wallet.get_account('Alice') - # Sync account with the node -account.sync() +wallet.sync() # Issue the minting transaction and wait for its inclusion print('Sending NFT minting transaction...') diff --git a/bindings/python/examples/how_tos/nft_collection/01_mint_collection_nft.py b/bindings/python/examples/how_tos/nft_collection/01_mint_collection_nft.py index fb1acd5c4e..7ae15f0f0b 100644 --- a/bindings/python/examples/how_tos/nft_collection/01_mint_collection_nft.py +++ b/bindings/python/examples/how_tos/nft_collection/01_mint_collection_nft.py @@ -26,10 +26,8 @@ wallet.set_stronghold_password(os.environ["STRONGHOLD_PASSWORD"]) -account = wallet.get_account('Alice') - # Sync account with the node -account.sync() +wallet.sync() bech32_hrp = wallet.get_client().get_bech32_hrp() issuer = Utils.nft_id_to_bech32(issuer_nft_id, bech32_hrp) @@ -74,4 +72,4 @@ def get_immutable_metadata(index: int) -> str: print(f'Block sent: {os.environ["EXPLORER_URL"]}/block/{block_id}') # Sync so the new outputs are available again for new transactions - account.sync() + wallet.sync() diff --git a/bindings/python/examples/how_tos/nfts/burn_nft.py b/bindings/python/examples/how_tos/nfts/burn_nft.py index 948e7c41a2..c21fd8dd68 100644 --- a/bindings/python/examples/how_tos/nfts/burn_nft.py +++ b/bindings/python/examples/how_tos/nfts/burn_nft.py @@ -14,10 +14,8 @@ wallet.set_stronghold_password(os.environ["STRONGHOLD_PASSWORD"]) -account = wallet.get_account('Alice') - # Sync account with the node -balance = account.sync() +balance = wallet.sync() nftId = balance.nfts[0] diff --git a/bindings/python/examples/how_tos/nfts/mint_nft.py b/bindings/python/examples/how_tos/nfts/mint_nft.py index d45db0961d..bd53401b1b 100644 --- a/bindings/python/examples/how_tos/nfts/mint_nft.py +++ b/bindings/python/examples/how_tos/nfts/mint_nft.py @@ -15,10 +15,8 @@ wallet.set_stronghold_password(os.environ["STRONGHOLD_PASSWORD"]) -account = wallet.get_account('Alice') - # Sync account with the node -response = account.sync() +response = wallet.sync() outputs = [MintNftParams( immutable_metadata=utf8_to_hex("some immutable nft metadata"), diff --git a/bindings/python/examples/how_tos/nfts/send_nft.py b/bindings/python/examples/how_tos/nfts/send_nft.py index d980baa520..fd0e647850 100644 --- a/bindings/python/examples/how_tos/nfts/send_nft.py +++ b/bindings/python/examples/how_tos/nfts/send_nft.py @@ -15,10 +15,8 @@ wallet.set_stronghold_password(os.environ["STRONGHOLD_PASSWORD"]) -account = wallet.get_account('Alice') - # Sync account with the node -balance = account.sync() +balance = wallet.sync() outputs = [SendNftParams( address="rms1qpszqzadsym6wpppd6z037dvlejmjuke7s24hm95s9fg9vpua7vluaw60xu", diff --git a/bindings/python/examples/how_tos/simple_transaction/request_funds.py b/bindings/python/examples/how_tos/simple_transaction/request_funds.py index 583a167d87..fedf9bdad6 100644 --- a/bindings/python/examples/how_tos/simple_transaction/request_funds.py +++ b/bindings/python/examples/how_tos/simple_transaction/request_funds.py @@ -14,8 +14,6 @@ wallet = Wallet(os.environ['WALLET_DB_PATH']) -account = wallet.get_account('Alice') - address = account.addresses()[0].address print(address) diff --git a/bindings/python/examples/how_tos/simple_transaction/simple_transaction.py b/bindings/python/examples/how_tos/simple_transaction/simple_transaction.py index 400667c939..f1514b60d3 100644 --- a/bindings/python/examples/how_tos/simple_transaction/simple_transaction.py +++ b/bindings/python/examples/how_tos/simple_transaction/simple_transaction.py @@ -10,10 +10,8 @@ wallet = Wallet(os.environ['WALLET_DB_PATH']) -account = wallet.get_account('Alice') - # Sync account with the node -response = account.sync() +response = wallet.sync() if 'STRONGHOLD_PASSWORD' not in os.environ: raise Exception(".env STRONGHOLD_PASSWORD is undefined, see .env.example") diff --git a/bindings/python/examples/wallet/12-prepare_output.py b/bindings/python/examples/wallet/12-prepare_output.py index 014d29d9ae..ea0dfd21b8 100644 --- a/bindings/python/examples/wallet/12-prepare_output.py +++ b/bindings/python/examples/wallet/12-prepare_output.py @@ -28,7 +28,7 @@ expiration_slot_index=1676570528))) print(f"Output: {json.dumps(output.to_dict(), indent=4)}") -account.sync() +wallet.sync() transaction = account.send_outputs([output]) print(f'Block sent: {os.environ["EXPLORER_URL"]}/block/{transaction.block_id}') diff --git a/bindings/python/examples/wallet/13-check-unlock-conditions.py b/bindings/python/examples/wallet/13-check-unlock-conditions.py index 8fac56b70c..6373a2aecb 100644 --- a/bindings/python/examples/wallet/13-check-unlock-conditions.py +++ b/bindings/python/examples/wallet/13-check-unlock-conditions.py @@ -13,11 +13,11 @@ account = wallet.get_account("Alice") -accountAddresses = account.addresses() +accountaddress = wallet.address() # using prepare_output output = account.prepare_output(OutputParams( - accountAddresses[0].address, 1000000)) + accountaddresss, 1000000)) def hexAddress(address): diff --git a/bindings/python/examples/wallet/create_alias.py b/bindings/python/examples/wallet/create_alias.py index c4cdb3cb96..8718da2051 100644 --- a/bindings/python/examples/wallet/create_alias.py +++ b/bindings/python/examples/wallet/create_alias.py @@ -10,10 +10,8 @@ wallet = Wallet(os.environ['WALLET_DB_PATH']) -account = wallet.get_account('Alice') - # Sync account with the node -account.sync() +wallet.sync() if 'STRONGHOLD_PASSWORD' not in os.environ: raise Exception(".env STRONGHOLD_PASSWORD is undefined, see .env.example") diff --git a/bindings/python/examples/wallet/getting_started.py b/bindings/python/examples/wallet/getting_started.py index 5161ac541d..2f3bbb9fa6 100644 --- a/bindings/python/examples/wallet/getting_started.py +++ b/bindings/python/examples/wallet/getting_started.py @@ -33,7 +33,7 @@ mnemonic = Utils.generate_mnemonic() print(f'Mnemonic: {mnemonic}') -# SecretManager(secret_manager).store_mnemonic(mnemonic) +SecretManager(secret_manager).store_mnemonic(mnemonic) # Set up and store the wallet. client_options = ClientOptions(nodes=[node_url]) diff --git a/bindings/python/examples/wallet/offline_signing/0_generate_addresses.py b/bindings/python/examples/wallet/offline_signing/0_generate_addresses.py index 19a356e77a..f9a70834b5 100644 --- a/bindings/python/examples/wallet/offline_signing/0_generate_addresses.py +++ b/bindings/python/examples/wallet/offline_signing/0_generate_addresses.py @@ -39,7 +39,7 @@ print("Account created:", account.get_metadata()) # Get the addresses from the account (by default only one) -addresses = account.addresses() +address = wallet.address() json_data = json.dumps(list(map(lambda x: x.__dict__, addresses)), indent=4) print(f"example.addresses.json:\n{json_data}") diff --git a/bindings/python/examples/wallet/offline_signing/1_prepare_transaction.py b/bindings/python/examples/wallet/offline_signing/1_prepare_transaction.py index 89741804a4..18c7df09d0 100644 --- a/bindings/python/examples/wallet/offline_signing/1_prepare_transaction.py +++ b/bindings/python/examples/wallet/offline_signing/1_prepare_transaction.py @@ -41,7 +41,7 @@ account = wallet.create_account('Alice', "rms", addresses) print("Account created:", account.get_metadata()) -account.sync() +wallet.sync() prepared_transaction = account.prepare_send(params) diff --git a/bindings/python/examples/wallet/transaction_options.py b/bindings/python/examples/wallet/transaction_options.py index 5352e13310..234e6c9175 100644 --- a/bindings/python/examples/wallet/transaction_options.py +++ b/bindings/python/examples/wallet/transaction_options.py @@ -11,10 +11,8 @@ wallet = Wallet(os.environ['WALLET_DB_PATH']) -account = wallet.get_account('Alice') - # Sync account with the node -response = account.sync() +response = wallet.sync() if 'STRONGHOLD_PASSWORD' not in os.environ: raise Exception(".env STRONGHOLD_PASSWORD is undefined, see .env.example") diff --git a/bindings/python/iota_sdk/client/_utils.py b/bindings/python/iota_sdk/client/_utils.py index a1b0859062..3855d4d8a3 100644 --- a/bindings/python/iota_sdk/client/_utils.py +++ b/bindings/python/iota_sdk/client/_utils.py @@ -34,7 +34,7 @@ def _call_method(self, name, data=None): """ # pylint: disable=redefined-builtin - def hex_to_bech32(self, hex: HexStr, bech32_hrp: str) -> str: + def hex_to_bech32(self, hex_str: HexStr, bech32_hrp: str) -> str: """Transforms a hex encoded address to a bech32 encoded address. """ return self._call_method('hexToBech32', { diff --git a/bindings/python/iota_sdk/secret_manager/secret_manager.py b/bindings/python/iota_sdk/secret_manager/secret_manager.py index 4d348b283d..54eced05ad 100644 --- a/bindings/python/iota_sdk/secret_manager/secret_manager.py +++ b/bindings/python/iota_sdk/secret_manager/secret_manager.py @@ -274,7 +274,7 @@ def sign_transaction( Args: prepare_transaction_data: The prepared transaction data that needs to be signed. """ - return from_dict(SignedTransactionPayload, self._call_method('signTransaction', { + return SignedTransactionPayload.from_dict(self._call_method('signTransaction', { 'preparedTransactionData': prepared_transaction_data.to_dict() })) @@ -286,7 +286,7 @@ def sign_block( unsigned_block: The unsigned block data. chain: The Bip44 chain to use. """ - return from_dict(SignedBlock, self._call_method('signBlock', { + return SignedBlock.from_dict(self._call_method('signBlock', { 'unsignedBlock': unsigned_block.to_dict(), 'chain': chain.to_dict() })) diff --git a/bindings/python/iota_sdk/types/address.py b/bindings/python/iota_sdk/types/address.py index 607042fa0a..b2ca48ef4a 100644 --- a/bindings/python/iota_sdk/types/address.py +++ b/bindings/python/iota_sdk/types/address.py @@ -172,6 +172,7 @@ def with_allowed_capabilities(self, capabilities: bytes): RestrictedAddress] +# pylint: disable=too-many-return-statements def deserialize_address(d: Dict[str, Any]) -> Address: """ Takes a dictionary as input and returns an instance of a specific class based on the value of the 'type' key in the dictionary. diff --git a/bindings/python/iota_sdk/types/common.py b/bindings/python/iota_sdk/types/common.py index 7866ffc590..d750b2bae0 100644 --- a/bindings/python/iota_sdk/types/common.py +++ b/bindings/python/iota_sdk/types/common.py @@ -35,10 +35,9 @@ def custom_to_dict(self, *args, **kwargs): def filter_none(value): if isinstance(value, dict): return {k: filter_none(v) for k, v in value.items() if v is not None} - elif isinstance(value, list): + if isinstance(value, list): return [filter_none(item) for item in value if item is not None] - else: - return value + return value return filter_none(original_dict) diff --git a/bindings/python/iota_sdk/types/feature.py b/bindings/python/iota_sdk/types/feature.py index 4908be3b02..01eb0c4abd 100644 --- a/bindings/python/iota_sdk/types/feature.py +++ b/bindings/python/iota_sdk/types/feature.py @@ -152,6 +152,7 @@ class StakingFeature: MetadataFeature, TagFeature, NativeTokenFeature, BlockIssuerFeature, StakingFeature] +# pylint: disable=too-many-return-statements def deserialize_feature(d: Dict[str, Any]) -> Feature: """ Takes a dictionary as input and returns an instance of a specific class based on the value of the 'type' key in the dictionary. diff --git a/bindings/python/iota_sdk/types/output_params.py b/bindings/python/iota_sdk/types/output_params.py index b5b896b61b..6133a2e704 100644 --- a/bindings/python/iota_sdk/types/output_params.py +++ b/bindings/python/iota_sdk/types/output_params.py @@ -4,7 +4,7 @@ from __future__ import annotations from dataclasses import dataclass, field from enum import Enum -from typing import List, Optional +from typing import Optional from dataclasses_json import config from iota_sdk.types.common import HexStr, json, opt_int_encoder from iota_sdk.types.native_token import NativeToken diff --git a/bindings/python/iota_sdk/types/send_params.py b/bindings/python/iota_sdk/types/send_params.py index 6bcccd9c2e..4807147df8 100644 --- a/bindings/python/iota_sdk/types/send_params.py +++ b/bindings/python/iota_sdk/types/send_params.py @@ -3,7 +3,7 @@ from __future__ import annotations from dataclasses import dataclass, field -from typing import Optional, List +from typing import Optional from dataclasses_json import config from iota_sdk.types.common import hex_str_decoder, HexStr, json from iota_sdk.types.native_token import NativeToken diff --git a/bindings/python/iota_sdk/types/unlock.py b/bindings/python/iota_sdk/types/unlock.py index 2cdc139ec1..3fa712e6b6 100644 --- a/bindings/python/iota_sdk/types/unlock.py +++ b/bindings/python/iota_sdk/types/unlock.py @@ -89,6 +89,7 @@ class NftUnlock: type: int = field(default_factory=lambda: int(UnlockType.Nft), init=False) +# pylint: disable=missing-function-docstring,unused-argument def deserialize_unlocks(dicts: List[Dict[str, Any]]) -> List[Unlock]: pass @@ -125,7 +126,7 @@ class EmptyUnlock: MultiUnlock, EmptyUnlock] - +# pylint: disable=too-many-return-statements def deserialize_unlock(d: Dict[str, Any]) -> Unlock: """ Takes a dictionary as input and returns an instance of a specific class based on the value of the 'type' key in the dictionary. @@ -151,6 +152,7 @@ def deserialize_unlock(d: Dict[str, Any]) -> Unlock: raise Exception(f'invalid unlock type: {unlock_type}') +# pylint: disable=function-redefined def deserialize_unlocks(dicts: List[Dict[str, Any]]) -> List[Unlock]: """ Takes a list of dictionaries as input and returns a list with specific instances of classes based on the value of the 'type' key in the dictionary. diff --git a/bindings/python/iota_sdk/utils.py b/bindings/python/iota_sdk/utils.py index 1e854aad49..a09663df1b 100644 --- a/bindings/python/iota_sdk/utils.py +++ b/bindings/python/iota_sdk/utils.py @@ -3,7 +3,7 @@ from __future__ import annotations from json import dumps, loads -from typing import TYPE_CHECKING, List +from typing import TYPE_CHECKING, List, Optional from iota_sdk.types.signature import Ed25519Signature from iota_sdk.types.address import Address, deserialize_address @@ -11,7 +11,7 @@ from iota_sdk.types.transaction import Transaction from iota_sdk.types.node_info import ProtocolParameters from iota_sdk.types.output_id import OutputId -from iota_sdk.types.output import Output +from iota_sdk.types.unlock import Unlock from iota_sdk.external import call_utils_method from iota_sdk.types.payload import SignedTransactionPayload from iota_sdk.types.transaction_data import InputSigningData diff --git a/bindings/python/iota_sdk/wallet/wallet.py b/bindings/python/iota_sdk/wallet/wallet.py index fb95972672..cb3584b136 100644 --- a/bindings/python/iota_sdk/wallet/wallet.py +++ b/bindings/python/iota_sdk/wallet/wallet.py @@ -2,19 +2,15 @@ # SPDX-License-Identifier: Apache-2.0 from json import dumps -from typing import Any, Dict, List, Optional, Union +from typing import List, Optional, Union from dataclasses import dataclass from iota_sdk import destroy_wallet, create_wallet, listen_wallet, get_client_from_wallet, get_secret_manager_from_wallet, Client from iota_sdk.secret_manager.secret_manager import LedgerNanoSecretManager, MnemonicSecretManager, StrongholdSecretManager, SeedSecretManager, SecretManager -from iota_sdk.types.address import AccountAddress - -from iota_sdk.wallet.sync_options import SyncOptions from iota_sdk.wallet.common import _call_method_routine from iota_sdk.wallet.prepared_transaction import PreparedTransaction, PreparedCreateTokenTransaction -from iota_sdk.wallet.sync_options import SyncOptions -from iota_sdk.types.address import AccountAddress +from iota_sdk.wallet.sync_options import SyncOptions from iota_sdk.types.balance import Balance from iota_sdk.types.burn import Burn from iota_sdk.types.common import HexStr, json @@ -32,8 +28,6 @@ from iota_sdk.types.transaction_options import TransactionOptions from iota_sdk.types.consolidation_params import ConsolidationParams -# pylint: disable=too-many-public-methods - @json @dataclass @@ -47,6 +41,9 @@ class WalletOptions: storage_path: Optional[str] = None +# pylint: disable=too-many-public-methods + + class Wallet(): """An IOTA Wallet. @@ -227,7 +224,7 @@ def update_node_auth(self, url: str, auth=None): """ return self._call_method( 'updateNodeAuth', { - 'url': mnemonic, + 'url': url, 'auth': auth } ) @@ -238,7 +235,7 @@ def accounts(self) -> List[OutputData]: outputs = self._call_method( 'accounts' ) - return [from_dict(OutputData, o) for o in outputs] + return [OutputData.from_dict(o) for o in outputs] def burn( self, burn: Burn, options: Optional[TransactionOptions] = None) -> TransactionWithMetadata: @@ -402,7 +399,7 @@ def get_balance(self) -> Balance: def get_output(self, output_id: OutputId) -> OutputData: """Get output. """ - return from_dict(OutputData, self._call_method( + return OutputData.from_dict(self._call_method( 'getOutput', { 'outputId': output_id } @@ -484,8 +481,7 @@ def prepare_implicit_account_transition( 'outputId': output_id } ) - return PreparedTransaction( - account=self, prepared_transaction_data=prepared) + return PreparedTransaction(self, prepared) def implicit_accounts(self) -> List[OutputData]: """Returns the implicit accounts of the wallet. @@ -493,7 +489,7 @@ def implicit_accounts(self) -> List[OutputData]: outputs = self._call_method( 'implicitAccounts' ) - return [from_dict(OutputData, o) for o in outputs] + return [OutputData.from_dict(o) for o in outputs] def incoming_transactions(self) -> List[TransactionWithMetadata]: """Returns all incoming transactions of the account. @@ -520,7 +516,7 @@ def unspent_outputs( 'filterOptions': filter_options } ) - return [from_dict(OutputData, o) for o in outputs] + return [OutputData.from_dict(o) for o in outputs] def mint_native_token(self, token_id: HexStr, mint_amount: int, options: Optional[TransactionOptions] = None) -> TransactionWithMetadata: @@ -558,8 +554,7 @@ def prepare_create_native_token(self, params: CreateNativeTokenParams, 'options': options } ) - return PreparedCreateTokenTransaction( - account=self, prepared_transaction_data=prepared) + return PreparedCreateTokenTransaction(self, prepared) def mint_nfts(self, params: List[MintNftParams], options: Optional[TransactionOptions] = None) -> TransactionWithMetadata: @@ -764,15 +759,8 @@ def sync(self, options: Optional[SyncOptions] = None) -> Balance: Will also reissue pending transactions and consolidate outputs if necessary. A custom default can be set using set_default_sync_options. """ - return from_dict(Balance, self._call_method( + return Balance.from_dict(self._call_method( 'sync', { 'options': options, } )) - - # pylint: disable=redefined-builtin - @staticmethod - def __return_str_or_none(opt_str): - if opt_str: - return opt_str - return None From d2e3a8483a29a6162cf2b91e66392b6d8cdb63cd Mon Sep 17 00:00:00 2001 From: Brord van Wierst Date: Thu, 7 Dec 2023 12:47:33 +0100 Subject: [PATCH 05/34] examples lint fix --- .../examples/exchange/1_create_account.py | 18 ++++----- .../examples/exchange/2_generate_address.py | 13 ++++--- .../examples/exchange/3_check_balance.py | 8 ++-- .../examples/exchange/4_listen_events.py | 6 +-- .../python/examples/exchange/5_send_amount.py | 6 +-- .../examples/how_tos/account_output/create.py | 6 +-- .../how_tos/account_output/destroy.py | 6 +-- .../how_tos/account_wallet/request_funds.py | 8 ++-- .../how_tos/account_wallet/transaction.py | 10 ++--- .../accounts_and_addresses/check_balance.py | 8 ++-- .../consolidate_outputs.py | 24 +++++++----- .../accounts_and_addresses/create_address.py | 11 +++--- .../{create_account.py => create_wallet.py} | 18 +++------ .../accounts_and_addresses/list_accounts.py | 16 -------- .../{list_addresses.py => list_address.py} | 9 ++--- .../accounts_and_addresses/list_outputs.py | 8 ++-- .../list_transactions.py | 8 ++-- .../advanced_transaction.py | 7 ++-- .../claim_transaction.py | 10 ++--- .../send_micro_transaction.py | 8 ++-- .../examples/how_tos/native_tokens/burn.py | 8 ++-- .../examples/how_tos/native_tokens/create.py | 12 +++--- .../how_tos/native_tokens/destroy_foundry.py | 8 ++-- .../examples/how_tos/native_tokens/melt.py | 8 ++-- .../examples/how_tos/native_tokens/mint.py | 8 ++-- .../examples/how_tos/native_tokens/send.py | 8 ++-- .../nft_collection/00_mint_issuer_nft.py | 8 ++-- .../nft_collection/01_mint_collection_nft.py | 8 ++-- .../python/examples/how_tos/nfts/burn_nft.py | 6 +-- .../python/examples/how_tos/nfts/mint_nft.py | 6 +-- .../python/examples/how_tos/nfts/send_nft.py | 6 +-- .../simple_transaction/request_funds.py | 6 +-- .../simple_transaction/simple_transaction.py | 6 +-- .../examples/wallet/12-prepare_output.py | 10 ++--- .../wallet/13-check-unlock-conditions.py | 31 ++++++--------- bindings/python/examples/wallet/backup.py | 17 ++++---- .../python/examples/wallet/create_alias.py | 6 +-- bindings/python/examples/wallet/get_client.py | 4 +- .../python/examples/wallet/getting_started.py | 4 +- bindings/python/examples/wallet/logger.py | 18 ++++----- .../migrate-stronghold-snapshot-v2-to-v3.py | 27 ++++++------- .../offline_signing/0_generate_addresses.py | 17 ++++---- .../offline_signing/1_prepare_transaction.py | 14 +++---- .../offline_signing/2_sign_transaction.py | 8 ++-- .../offline_signing/3_send_transaction.py | 10 ++--- .../examples/wallet/recover_accounts.py | 39 ------------------- .../python/examples/wallet/restore_backup.py | 15 ++++--- .../examples/wallet/transaction_options.py | 6 +-- bindings/python/iota_sdk/__init__.py | 2 +- .../python/tests/address_generation_test.py | 4 +- bindings/python/tests/test_offline.py | 1 - 51 files changed, 230 insertions(+), 309 deletions(-) rename bindings/python/examples/how_tos/accounts_and_addresses/{create_account.py => create_wallet.py} (73%) delete mode 100644 bindings/python/examples/how_tos/accounts_and_addresses/list_accounts.py rename bindings/python/examples/how_tos/accounts_and_addresses/{list_addresses.py => list_address.py} (52%) delete mode 100644 bindings/python/examples/wallet/recover_accounts.py diff --git a/bindings/python/examples/exchange/1_create_account.py b/bindings/python/examples/exchange/1_create_account.py index d870accd6d..4b8a7790aa 100644 --- a/bindings/python/examples/exchange/1_create_account.py +++ b/bindings/python/examples/exchange/1_create_account.py @@ -8,7 +8,7 @@ from dotenv import load_dotenv from iota_sdk import (ClientOptions, CoinType, StrongholdSecretManager, - SyncOptions, Wallet) + SyncOptions, Wallet, WalletOptions, Bip44) # This example uses secrets in environment variables for simplicity which # should not be done in production. @@ -24,19 +24,17 @@ secret_manager = StrongholdSecretManager( os.environ.get('STRONGHOLD_SNAPSHOT_PATH'), os.environ['STRONGHOLD_PASSWORD']) -wallet = Wallet(os.environ.get('WALLET_DB_PATH'), - client_options, CoinType.IOTA, secret_manager) +bib_path = Bip44( + coin_type=CoinType.SHIMMER +) +wallet_options = WalletOptions(None, None, bib_path, client_options, secret_manager, os.environ.get('WALLET_DB_PATH')) +wallet = Wallet(wallet_options) # Store the mnemonic in the Stronghold snapshot, this only needs to be # done once. -wallet.store_mnemonic( - os.environ['MNEMONIC']) - -account = wallet.create_account('Alice') +wallet.store_mnemonic(os.environ['MNEMONIC']) # Set sync_only_most_basic_outputs to True if not interested in outputs that are timelocked, # have a storage deposit return, expiration or are nft/account/foundry outputs. -account.set_default_sync_options( +wallet.set_default_sync_options( SyncOptions(sync_only_most_basic_outputs=True)) - -print(account.get_metadata()) diff --git a/bindings/python/examples/exchange/2_generate_address.py b/bindings/python/examples/exchange/2_generate_address.py index 8624669d98..0fd365e798 100644 --- a/bindings/python/examples/exchange/2_generate_address.py +++ b/bindings/python/examples/exchange/2_generate_address.py @@ -1,25 +1,26 @@ # Copyright 2023 IOTA Stiftung # SPDX-License-Identifier: Apache-2.0 -# This example generates an address for an account. +# This example generates an address for a wallet. import os from dotenv import load_dotenv -from iota_sdk import Wallet +from iota_sdk import ClientOptions, StrongholdSecretManager, SecretManager # This example uses secrets in environment variables for simplicity which # should not be done in production. load_dotenv() -for env_var in ['WALLET_DB_PATH', 'STRONGHOLD_PASSWORD']: +for env_var in ['STRONGHOLD_SNAPSHOT_PATH', 'STRONGHOLD_PASSWORD']: if env_var not in os.environ: raise Exception(f'.env {env_var} is undefined, see .env.example') -wallet = Wallet(os.environ.get('WALLET_DB_PATH')) +client_options = ClientOptions(nodes=[os.environ.get('NODE_URL')]) -wallet.set_stronghold_password(os.environ["STRONGHOLD_PASSWORD"]) +secret_manager = SecretManager(StrongholdSecretManager( + os.environ.get('STRONGHOLD_SNAPSHOT_PATH'), os.environ['STRONGHOLD_PASSWORD'])) -address = account.generate_ed25519_addresses(1)[0] +address = secret_manager.generate_ed25519_addresses(1)[0] print('Address:', address.address) diff --git a/bindings/python/examples/exchange/3_check_balance.py b/bindings/python/examples/exchange/3_check_balance.py index afa1ec37b5..b0a836dea7 100644 --- a/bindings/python/examples/exchange/3_check_balance.py +++ b/bindings/python/examples/exchange/3_check_balance.py @@ -1,13 +1,13 @@ # Copyright 2023 IOTA Stiftung # SPDX-License-Identifier: Apache-2.0 -# This example gets the balance of an account. +# This example gets the balance of a wallet. import os from dotenv import load_dotenv -from iota_sdk import SyncOptions, Wallet +from iota_sdk import SyncOptions, Wallet, WalletOptions # This example uses secrets in environment variables for simplicity which # should not be done in production. @@ -16,10 +16,10 @@ if 'WALLET_DB_PATH' not in os.environ: raise Exception(".env WALLET_DB_PATH is undefined, see .env.example") -wallet = Wallet(os.environ.get('WALLET_DB_PATH')) +wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) address = wallet.address() -print('Addresses:', addresses) +print('address:', address) # Set sync_only_most_basic_outputs to True if not interested in outputs that are timelocked, # have a storage deposit return, expiration or are nft/account/foundry outputs. diff --git a/bindings/python/examples/exchange/4_listen_events.py b/bindings/python/examples/exchange/4_listen_events.py index 24b43dad43..b5882a829e 100644 --- a/bindings/python/examples/exchange/4_listen_events.py +++ b/bindings/python/examples/exchange/4_listen_events.py @@ -10,7 +10,7 @@ from dotenv import load_dotenv -from iota_sdk import SyncOptions, Wallet, WalletEventType +from iota_sdk import SyncOptions, Wallet, WalletOptions, WalletEventType # This example uses secrets in environment variables for simplicity which # should not be done in production. @@ -19,7 +19,7 @@ if 'WALLET_DB_PATH' not in os.environ: raise Exception(".env WALLET_DB_PATH is undefined, see .env.example") -wallet = Wallet(os.environ.get('WALLET_DB_PATH')) +wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) received_event = False @@ -43,7 +43,7 @@ def callback(event): print('Fill your address with the faucet: https://faucet.testnet.shimmer.network/') address = wallet.address() -print('Send funds to:', addresss) +print('Send funds to:', address) # Sync every 5 seconds until the faucet transaction gets confirmed. for _ in range(100): diff --git a/bindings/python/examples/exchange/5_send_amount.py b/bindings/python/examples/exchange/5_send_amount.py index 23ccbec875..62465aa605 100644 --- a/bindings/python/examples/exchange/5_send_amount.py +++ b/bindings/python/examples/exchange/5_send_amount.py @@ -7,7 +7,7 @@ from dotenv import load_dotenv -from iota_sdk import SyncOptions, Wallet +from iota_sdk import SyncOptions, Wallet, WalletOptions # This example uses secrets in environment variables for simplicity which # should not be done in production. @@ -17,7 +17,7 @@ if env_var not in os.environ: raise Exception(f'.env {env_var} is undefined, see .env.example') -wallet = Wallet(os.environ.get('WALLET_DB_PATH')) +wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) wallet.set_stronghold_password(os.environ["STRONGHOLD_PASSWORD"]) @@ -26,7 +26,7 @@ balance = wallet.sync(SyncOptions(sync_only_most_basic_outputs=True)) print('Balance', balance) -transaction = account.send( +transaction = wallet.send( 1000000, "rms1qpszqzadsym6wpppd6z037dvlejmjuke7s24hm95s9fg9vpua7vluaw60xu", ) diff --git a/bindings/python/examples/how_tos/account_output/create.py b/bindings/python/examples/how_tos/account_output/create.py index 8718da2051..e9d6c4ff34 100644 --- a/bindings/python/examples/how_tos/account_output/create.py +++ b/bindings/python/examples/how_tos/account_output/create.py @@ -2,13 +2,13 @@ from dotenv import load_dotenv -from iota_sdk import Wallet +from iota_sdk import Wallet, WalletOptions load_dotenv() # In this example we will create an account output -wallet = Wallet(os.environ['WALLET_DB_PATH']) +wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) # Sync account with the node wallet.sync() @@ -19,5 +19,5 @@ wallet.set_stronghold_password(os.environ["STRONGHOLD_PASSWORD"]) # Send transaction. -transaction = account.create_account_output(None, None) +transaction = wallet.create_account_output(None, None) print(f'Block sent: {os.environ["EXPLORER_URL"]}/block/{transaction.block_id}') diff --git a/bindings/python/examples/how_tos/account_output/destroy.py b/bindings/python/examples/how_tos/account_output/destroy.py index ac114a2d1d..a54d62d2f9 100644 --- a/bindings/python/examples/how_tos/account_output/destroy.py +++ b/bindings/python/examples/how_tos/account_output/destroy.py @@ -2,13 +2,13 @@ from dotenv import load_dotenv -from iota_sdk import Wallet +from iota_sdk import Wallet, WalletOptions load_dotenv() # In this example we will destroy an account output -wallet = Wallet(os.environ['WALLET_DB_PATH']) +wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) # Sync account with the node balance = wallet.sync() @@ -22,5 +22,5 @@ wallet.set_stronghold_password(os.environ["STRONGHOLD_PASSWORD"]) # Send transaction. -transaction = account.prepare_destroy_account(account_id).send() +transaction = wallet.prepare_destroy_account(account_id).send() print(f'Block sent: {os.environ["EXPLORER_URL"]}/block/{transaction.block_id}') diff --git a/bindings/python/examples/how_tos/account_wallet/request_funds.py b/bindings/python/examples/how_tos/account_wallet/request_funds.py index 87a7075929..58e3a94e58 100644 --- a/bindings/python/examples/how_tos/account_wallet/request_funds.py +++ b/bindings/python/examples/how_tos/account_wallet/request_funds.py @@ -3,16 +3,16 @@ from dotenv import load_dotenv -from iota_sdk import Wallet, Utils, SyncOptions, AccountSyncOptions +from iota_sdk import Wallet, WalletOptions, Utils, SyncOptions, WalletSyncOptions -# In this example we request funds to an account wallet. +# In this example we request funds to a wallet. load_dotenv() FAUCET_URL = os.environ.get( 'FAUCET_URL', 'https://faucet.testnet.shimmer.network/api/enqueue') -wallet = Wallet(os.environ['WALLET_DB_PATH']) +wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) balance = wallet.sync(None) total_base_token_balance = balance.base_coin.total @@ -31,7 +31,7 @@ time.sleep(10) -sync_options = SyncOptions(alias=AccountSyncOptions(basic_outputs=True)) +sync_options = SyncOptions(wallet=WalletSyncOptions(basic_outputs=True)) total_base_token_balance = wallet.sync(sync_options).base_coin.total print( diff --git a/bindings/python/examples/how_tos/account_wallet/transaction.py b/bindings/python/examples/how_tos/account_wallet/transaction.py index 95d74d3e95..00f6f628ae 100644 --- a/bindings/python/examples/how_tos/account_wallet/transaction.py +++ b/bindings/python/examples/how_tos/account_wallet/transaction.py @@ -2,15 +2,15 @@ from dotenv import load_dotenv -from iota_sdk import Wallet, Utils, NodeIndexerAPI, SyncOptions, AccountSyncOptions, SendParams +from iota_sdk import Wallet, WalletOptions, Utils, NodeIndexerAPI, SyncOptions, WalletSyncOptions, SendParams # In this example we send funds from an account wallet. load_dotenv() -sync_options = SyncOptions(alias=AccountSyncOptions(basic_outputs=True)) +sync_options = SyncOptions(account=WalletSyncOptions(basic_outputs=True)) -wallet = Wallet(os.environ['WALLET_DB_PATH']) +wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) if 'STRONGHOLD_PASSWORD' not in os.environ: raise Exception(".env STRONGHOLD_PASSWORD is undefined, see .env.example") @@ -41,8 +41,8 @@ options = { 'mandatoryInputs': inputs, } -transaction = account.send_with_params(params, options) -account.reissue_transaction_until_included( +transaction = wallet.send_with_params(params, options) +wallet.reissue_transaction_until_included( transaction.transaction_id) print( f'Transaction with custom input: https://explorer.shimmer.network/testnet/transaction/{transaction.transaction_id}') diff --git a/bindings/python/examples/how_tos/accounts_and_addresses/check_balance.py b/bindings/python/examples/how_tos/accounts_and_addresses/check_balance.py index 1091fbe5fa..27160b5ce0 100644 --- a/bindings/python/examples/how_tos/accounts_and_addresses/check_balance.py +++ b/bindings/python/examples/how_tos/accounts_and_addresses/check_balance.py @@ -3,19 +3,19 @@ from dotenv import load_dotenv -from iota_sdk import Wallet +from iota_sdk import Wallet, WalletOptions -# This example checks the balance of an account. +# This example checks the balance of a wallet. # This example uses secrets in environment variables for simplicity which # should not be done in production. load_dotenv() -wallet = Wallet(os.environ['WALLET_DB_PATH']) +wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) # Sync account with the node _balance = wallet.sync() # Just calculate the balance with the known state -balance = account.get_balance() +balance = wallet.get_balance() print(f'Balance {json.dumps(balance.to_dict(), indent=4)}') diff --git a/bindings/python/examples/how_tos/accounts_and_addresses/consolidate_outputs.py b/bindings/python/examples/how_tos/accounts_and_addresses/consolidate_outputs.py index 536251f06a..8d26f90f17 100644 --- a/bindings/python/examples/how_tos/accounts_and_addresses/consolidate_outputs.py +++ b/bindings/python/examples/how_tos/accounts_and_addresses/consolidate_outputs.py @@ -2,7 +2,7 @@ from dotenv import load_dotenv -from iota_sdk import ConsolidationParams, Utils, Wallet, FeatureType +from iota_sdk import ConsolidationParams, Utils, Wallet, WalletOptions, FeatureType # In this example we will consolidate basic outputs from an account with only an AddressUnlockCondition by sending # them to the same address again. @@ -14,7 +14,7 @@ if 'STRONGHOLD_PASSWORD' not in os.environ: raise Exception('.env STRONGHOLD_PASSWORD is undefined, see .env.example') -wallet = Wallet(os.environ['WALLET_DB_PATH']) +wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) wallet.set_stronghold_password(os.environ['STRONGHOLD_PASSWORD']) # Sync account to make sure account is updated with outputs from previous @@ -27,7 +27,7 @@ # unlock condition and it is an `AddressUnlockCondition`, and so they are valid for consolidation. They have the # same `AddressUnlockCondition`(the address of the wallet), so they will be consolidated into one # output. -outputs = account.unspent_outputs() +outputs = wallet.unspent_outputs() print('Outputs BEFORE consolidation:') for i, output_data in enumerate(outputs): @@ -35,19 +35,21 @@ print( f'- address: #{Utils.hex_to_bech32(output_data.address.pub_key_hash, "rms")}') print(f'- amount: #{output_data.output.amount}') - print(f'- native tokens: #{}', [feature for feature in output_data.output.features if feature.type - == FeatureType.NativeToken]) + + native_tokens = [feature for feature in output_data.output.features if feature.type == FeatureType.NativeToken] + first_native_token = next(iter(native_tokens), None) + print(f'- native tokens: #{first_native_token}') print('Sending consolidation transaction...') # Consolidate unspent outputs and print the consolidation transaction ID # Set `force` to true to force the consolidation even though the # `output_threshold` isn't reached. -transaction = account.consolidate_outputs(ConsolidationParams(force=True)) +transaction = wallet.consolidate_outputs(ConsolidationParams(force=True)) print('Transaction sent: ', transaction.transaction_id) # Wait for the consolidation transaction to get confirmed -block_id = account.reissue_transaction_until_included( +block_id = wallet.reissue_transaction_until_included( transaction.transaction_id) print( @@ -59,12 +61,14 @@ print('Account synced') # Outputs after consolidation -outputs = account.unspent_outputs() +outputs = wallet.unspent_outputs() print('Outputs AFTER consolidation:') for i, output_data in enumerate(outputs): print(f'OUTPUT #{i}') print( f'- address: #{Utils.hex_to_bech32(output_data.address.pub_key_hash, "rms")}') print(f'- amount: #{output_data.output.amount}') - print(f'- native tokens: #{}', [feature for feature in output_data.output.features if feature.type - == FeatureType.NativeToken]) + + native_tokens = [feature for feature in output_data.output.features if feature.type == FeatureType.NativeToken] + first_native_token = next(iter(native_tokens), None) + print(f'- native tokens: #{first_native_token}') diff --git a/bindings/python/examples/how_tos/accounts_and_addresses/create_address.py b/bindings/python/examples/how_tos/accounts_and_addresses/create_address.py index 40ca5f6b92..2ba5fc678c 100644 --- a/bindings/python/examples/how_tos/accounts_and_addresses/create_address.py +++ b/bindings/python/examples/how_tos/accounts_and_addresses/create_address.py @@ -2,18 +2,19 @@ from dotenv import load_dotenv -from iota_sdk import Wallet +from iota_sdk import StrongholdSecretManager, SecretManager load_dotenv() # This example generates a new address. -wallet = Wallet(os.environ['WALLET_DB_PATH']) - if 'STRONGHOLD_PASSWORD' not in os.environ: raise Exception(".env STRONGHOLD_PASSWORD is undefined, see .env.example") -wallet.set_stronghold_password(os.environ["STRONGHOLD_PASSWORD"]) +secret_manager = SecretManager(StrongholdSecretManager( + os.environ.get('STRONGHOLD_SNAPSHOT_PATH'), + os.environ.get('STRONGHOLD_PASSWORD') +)) -address = account.generate_ed25519_addresses(1) +address = secret_manager.generate_ed25519_addresses(1) print('Generated address:', address[0].address) diff --git a/bindings/python/examples/how_tos/accounts_and_addresses/create_account.py b/bindings/python/examples/how_tos/accounts_and_addresses/create_wallet.py similarity index 73% rename from bindings/python/examples/how_tos/accounts_and_addresses/create_account.py rename to bindings/python/examples/how_tos/accounts_and_addresses/create_wallet.py index 09758a6c23..d9bc949f66 100644 --- a/bindings/python/examples/how_tos/accounts_and_addresses/create_account.py +++ b/bindings/python/examples/how_tos/accounts_and_addresses/create_wallet.py @@ -2,7 +2,7 @@ from dotenv import load_dotenv -from iota_sdk import ClientOptions, CoinType, StrongholdSecretManager, Wallet +from iota_sdk import ClientOptions, CoinType, StrongholdSecretManager, Wallet, WalletOptions, Bip44 load_dotenv() @@ -11,25 +11,19 @@ node_url = os.environ.get('NODE_URL', 'https://api.testnet.shimmer.network') client_options = ClientOptions(nodes=[node_url]) -# Shimmer coin type -coin_type = CoinType.SHIMMER - for env_var in ['STRONGHOLD_PASSWORD', 'MNEMONIC']: if env_var not in os.environ: raise Exception(f".env {env_var} is undefined, see .env.example") secret_manager = StrongholdSecretManager( os.environ['STRONGHOLD_SNAPSHOT_PATH'], os.environ['STRONGHOLD_PASSWORD']) +bib_path = Bip44( + coin_type=CoinType.SHIMMER +) -wallet = Wallet( - os.environ['WALLET_DB_PATH'], - client_options, - coin_type, - secret_manager) +wallet_options = WalletOptions(None, None, bib_path, client_options, secret_manager, os.environ.get('WALLET_DB_PATH')) +wallet = Wallet(wallet_options) # Store the mnemonic in the Stronghold snapshot, this only needs to be # done once. wallet.store_mnemonic(os.environ['MNEMONIC']) - -account = wallet.create_account('Alice') -print("Account created:", account.get_metadata()) diff --git a/bindings/python/examples/how_tos/accounts_and_addresses/list_accounts.py b/bindings/python/examples/how_tos/accounts_and_addresses/list_accounts.py deleted file mode 100644 index abbb5756e9..0000000000 --- a/bindings/python/examples/how_tos/accounts_and_addresses/list_accounts.py +++ /dev/null @@ -1,16 +0,0 @@ -import os - -from dotenv import load_dotenv - -from iota_sdk import Wallet - -# This example lists all accounts in the wallet. - -# This example uses secrets in environment variables for simplicity which -# should not be done in production. -load_dotenv() - -wallet = Wallet(os.environ['WALLET_DB_PATH']) - -for account in wallet.get_accounts(): - print(account.get_metadata()) diff --git a/bindings/python/examples/how_tos/accounts_and_addresses/list_addresses.py b/bindings/python/examples/how_tos/accounts_and_addresses/list_address.py similarity index 52% rename from bindings/python/examples/how_tos/accounts_and_addresses/list_addresses.py rename to bindings/python/examples/how_tos/accounts_and_addresses/list_address.py index 615e16f274..395bdc0f0c 100644 --- a/bindings/python/examples/how_tos/accounts_and_addresses/list_addresses.py +++ b/bindings/python/examples/how_tos/accounts_and_addresses/list_address.py @@ -2,17 +2,16 @@ from dotenv import load_dotenv -from iota_sdk import Wallet +from iota_sdk import Wallet, WalletOptions -# This example lists all addresses in the account. +# This example lists the wallet address. # This example uses secrets in environment variables for simplicity which # should not be done in production. load_dotenv() -wallet = Wallet(os.environ['WALLET_DB_PATH']) +wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) address = wallet.address() -for address in addresses: - print(address.address) +print(address) diff --git a/bindings/python/examples/how_tos/accounts_and_addresses/list_outputs.py b/bindings/python/examples/how_tos/accounts_and_addresses/list_outputs.py index 2154c44098..2010082529 100644 --- a/bindings/python/examples/how_tos/accounts_and_addresses/list_outputs.py +++ b/bindings/python/examples/how_tos/accounts_and_addresses/list_outputs.py @@ -2,7 +2,7 @@ from dotenv import load_dotenv -from iota_sdk import Wallet +from iota_sdk import Wallet, WalletOptions # In this example we will get outputs stored in the account @@ -10,11 +10,11 @@ # should not be done in production. load_dotenv() -wallet = Wallet(os.environ['WALLET_DB_PATH']) +wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) wallet.sync() # All outputs stored in the account -outputs = account.outputs() +outputs = wallet.outputs() # Print all output ids print('Output ids:') @@ -22,7 +22,7 @@ print(output.output_id) # All unspent outputs stored in the account -outputs = account.unspent_outputs() +outputs = wallet.unspent_outputs() # Print all unspent output ids print('Unspent output ids:') diff --git a/bindings/python/examples/how_tos/accounts_and_addresses/list_transactions.py b/bindings/python/examples/how_tos/accounts_and_addresses/list_transactions.py index ab8dd07516..344e1921a9 100644 --- a/bindings/python/examples/how_tos/accounts_and_addresses/list_transactions.py +++ b/bindings/python/examples/how_tos/accounts_and_addresses/list_transactions.py @@ -2,7 +2,7 @@ from dotenv import load_dotenv -from iota_sdk import Wallet +from iota_sdk import Wallet, WalletOptions # In this example we will list transactions @@ -10,18 +10,18 @@ # should not be done in production. load_dotenv() -wallet = Wallet(os.environ['WALLET_DB_PATH']) +wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) wallet.sync({'syncIncomingTransactions': True}) # All transactions sent from the the account -transactions = account.transactions() +transactions = wallet.transactions() print('Sent transactions:') for transaction in transactions: print(transaction.transaction_id) # Incoming transactions -incoming_transactions = account.incoming_transactions() +incoming_transactions = wallet.incoming_transactions() print('Received transactions:') for transaction in incoming_transactions: print(transaction.transaction_id) diff --git a/bindings/python/examples/how_tos/advanced_transactions/advanced_transaction.py b/bindings/python/examples/how_tos/advanced_transactions/advanced_transaction.py index 6a0c9f7caa..9fd27e4e25 100644 --- a/bindings/python/examples/how_tos/advanced_transactions/advanced_transaction.py +++ b/bindings/python/examples/how_tos/advanced_transactions/advanced_transaction.py @@ -9,6 +9,7 @@ Client, Ed25519Address, Wallet, + WalletOptions, Utils, TimelockUnlockCondition, ) @@ -18,7 +19,7 @@ # This example sends a transaction with a timelock. -wallet = Wallet(os.environ['WALLET_DB_PATH']) +wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) # Sync account with the node response = wallet.sync() @@ -44,10 +45,10 @@ ], ) -transaction = account.send_outputs([basic_output]) +transaction = wallet.send_outputs([basic_output]) print(f'Transaction sent: {transaction.transaction_id}') -block_id = account.reissue_transaction_until_included( +block_id = wallet.reissue_transaction_until_included( transaction.transaction_id) print( diff --git a/bindings/python/examples/how_tos/advanced_transactions/claim_transaction.py b/bindings/python/examples/how_tos/advanced_transactions/claim_transaction.py index 65e3d993ba..0ebca3b8c6 100644 --- a/bindings/python/examples/how_tos/advanced_transactions/claim_transaction.py +++ b/bindings/python/examples/how_tos/advanced_transactions/claim_transaction.py @@ -2,14 +2,14 @@ from dotenv import load_dotenv -from iota_sdk import Wallet +from iota_sdk import Wallet, WalletOptions load_dotenv() # In this example we will claim outputs that have additional unlock # conditions as expiration or storage deposit return. -wallet = Wallet(os.environ['WALLET_DB_PATH']) +wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) if 'STRONGHOLD_PASSWORD' not in os.environ: raise Exception(".env STRONGHOLD_PASSWORD is undefined, see .env.example") @@ -20,15 +20,15 @@ response = wallet.sync() # Only the unspent outputs in the account -output_ids = account.claimable_outputs('All') +output_ids = wallet.claimable_outputs('All') print('Available outputs to claim:') for output_id in output_ids: print(f'{output_id}') -transaction = account.claim_outputs(output_ids) +transaction = wallet.claim_outputs(output_ids) print(f'Transaction sent: {transaction.transaction_id}') -block_id = account.reissue_transaction_until_included( +block_id = wallet.reissue_transaction_until_included( transaction.transaction_id) print(f'Block sent: {os.environ["EXPLORER_URL"]}/block/{block_id}') diff --git a/bindings/python/examples/how_tos/advanced_transactions/send_micro_transaction.py b/bindings/python/examples/how_tos/advanced_transactions/send_micro_transaction.py index 8a337af463..4868f2d9ac 100644 --- a/bindings/python/examples/how_tos/advanced_transactions/send_micro_transaction.py +++ b/bindings/python/examples/how_tos/advanced_transactions/send_micro_transaction.py @@ -2,13 +2,13 @@ from dotenv import load_dotenv -from iota_sdk import Wallet, SendParams +from iota_sdk import Wallet, WalletOptions, SendParams load_dotenv() # In this example we will send an amount below the minimum amount -wallet = Wallet(os.environ['WALLET_DB_PATH']) +wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) # Sync account with the node response = wallet.sync() @@ -23,10 +23,10 @@ amount=1, )] -transaction = account.send_with_params(params, {"allowMicroAmount": True}) +transaction = wallet.send_with_params(params, {"allowMicroAmount": True}) print(f'Transaction sent: {transaction.transaction_id}') -block_id = account.reissue_transaction_until_included( +block_id = wallet.reissue_transaction_until_included( transaction.transaction_id) print( diff --git a/bindings/python/examples/how_tos/native_tokens/burn.py b/bindings/python/examples/how_tos/native_tokens/burn.py index 3e4fbcf806..48d6efac81 100644 --- a/bindings/python/examples/how_tos/native_tokens/burn.py +++ b/bindings/python/examples/how_tos/native_tokens/burn.py @@ -1,12 +1,12 @@ import os from dotenv import load_dotenv -from iota_sdk import Wallet +from iota_sdk import Wallet, WalletOptions load_dotenv() # In this example we will burn native tokens -wallet = Wallet(os.environ['WALLET_DB_PATH']) +wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) # Sync account with the node balance = wallet.sync() @@ -26,12 +26,12 @@ burn_amount = 1 # Send transaction. -transaction = account.prepare_burn_native_token( +transaction = wallet.prepare_burn_native_token( token.token_id, burn_amount).send() print(f'Transaction sent: {transaction.transaction_id}') # Wait for transaction to get included -block_id = account.reissue_transaction_until_included( +block_id = wallet.reissue_transaction_until_included( transaction.transaction_id) print(f'Block included: {os.environ["EXPLORER_URL"]}/block/{block_id}') diff --git a/bindings/python/examples/how_tos/native_tokens/create.py b/bindings/python/examples/how_tos/native_tokens/create.py index 424d252102..16f8bf8752 100644 --- a/bindings/python/examples/how_tos/native_tokens/create.py +++ b/bindings/python/examples/how_tos/native_tokens/create.py @@ -2,13 +2,13 @@ from dotenv import load_dotenv -from iota_sdk import CreateNativeTokenParams, Wallet, Irc30Metadata +from iota_sdk import CreateNativeTokenParams, Wallet, WalletOptions, Irc30Metadata load_dotenv() # In this example we will create native tokens -wallet = Wallet(os.environ['WALLET_DB_PATH']) +wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) if 'STRONGHOLD_PASSWORD' not in os.environ: raise Exception(".env STRONGHOLD_PASSWORD is undefined, see .env.example") @@ -23,11 +23,11 @@ # existing one. if not balance.accounts: # If we don't have an account, we need to create one - transaction = account.create_account_output(None, None) + transaction = wallet.create_account_output(None, None) print(f'Transaction sent: {transaction.transaction_id}') # Wait for transaction to get included - block_id = account.reissue_transaction_until_included( + block_id = wallet.reissue_transaction_until_included( transaction.transaction_id) print(f'Block included: {os.environ["EXPLORER_URL"]}/block/{block_id}') @@ -46,12 +46,12 @@ metadata.as_hex(), ) -prepared_transaction = account.prepare_create_native_token(params, None) +prepared_transaction = wallet.prepare_create_native_token(params, None) transaction = prepared_transaction.send() print(f'Transaction sent: {transaction.transaction_id}') # Wait for transaction to get included -block_id = account.reissue_transaction_until_included( +block_id = wallet.reissue_transaction_until_included( transaction.transaction_id) print(f'Block included: {os.environ["EXPLORER_URL"]}/block/{block_id}') diff --git a/bindings/python/examples/how_tos/native_tokens/destroy_foundry.py b/bindings/python/examples/how_tos/native_tokens/destroy_foundry.py index 447c3b2bd0..b8aefd2a83 100644 --- a/bindings/python/examples/how_tos/native_tokens/destroy_foundry.py +++ b/bindings/python/examples/how_tos/native_tokens/destroy_foundry.py @@ -1,12 +1,12 @@ import os from dotenv import load_dotenv -from iota_sdk import Wallet +from iota_sdk import Wallet, WalletOptions load_dotenv() # In this example we will destroy a foundry -wallet = Wallet(os.environ['WALLET_DB_PATH']) +wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) # Sync account with the node balance = wallet.sync() @@ -21,11 +21,11 @@ foundry_id = balance.foundries[0] # Send transaction. -transaction = account.prepare_destroy_foundry(foundry_id).send() +transaction = wallet.prepare_destroy_foundry(foundry_id).send() print(f'Transaction sent: {transaction.transaction_id}') # Wait for transaction to get included -block_id = account.reissue_transaction_until_included( +block_id = wallet.reissue_transaction_until_included( transaction.transaction_id) print(f'Block included: {os.environ["EXPLORER_URL"]}/block/{block_id}') diff --git a/bindings/python/examples/how_tos/native_tokens/melt.py b/bindings/python/examples/how_tos/native_tokens/melt.py index 136facaba2..83526cbb40 100644 --- a/bindings/python/examples/how_tos/native_tokens/melt.py +++ b/bindings/python/examples/how_tos/native_tokens/melt.py @@ -2,13 +2,13 @@ from dotenv import load_dotenv -from iota_sdk import Wallet +from iota_sdk import Wallet, WalletOptions load_dotenv() # In this example we will decrease the native token supply -wallet = Wallet(os.environ['WALLET_DB_PATH']) +wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) # Sync account with the node balance = wallet.sync() @@ -28,11 +28,11 @@ melt_amount = 10 # Send transaction. -transaction = account.melt_native_token(token_id, melt_amount) +transaction = wallet.melt_native_token(token_id, melt_amount) print(f'Transaction sent: {transaction.transaction_id}') # Wait for transaction to get included -block_id = account.reissue_transaction_until_included( +block_id = wallet.reissue_transaction_until_included( transaction.transaction_id) print(f'Block included: {os.environ["EXPLORER_URL"]}/block/{block_id}') diff --git a/bindings/python/examples/how_tos/native_tokens/mint.py b/bindings/python/examples/how_tos/native_tokens/mint.py index 7598e5da41..564e68aea1 100644 --- a/bindings/python/examples/how_tos/native_tokens/mint.py +++ b/bindings/python/examples/how_tos/native_tokens/mint.py @@ -2,13 +2,13 @@ from dotenv import load_dotenv -from iota_sdk import Wallet +from iota_sdk import Wallet, WalletOptions load_dotenv() # In this example we will mint native tokens -wallet = Wallet(os.environ['WALLET_DB_PATH']) +wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) # Sync account with the node balance = wallet.sync() @@ -28,11 +28,11 @@ mint_amount = 10 # Send transaction. -transaction = account.mint_native_token(token_id, mint_amount) +transaction = wallet.mint_native_token(token_id, mint_amount) print(f'Transaction sent: {transaction.transaction_id}') # Wait for transaction to get included -block_id = account.reissue_transaction_until_included( +block_id = wallet.reissue_transaction_until_included( transaction.transaction_id) print(f'Block included: {os.environ["EXPLORER_URL"]}/block/{block_id}') diff --git a/bindings/python/examples/how_tos/native_tokens/send.py b/bindings/python/examples/how_tos/native_tokens/send.py index cabfcf74cb..1e2e8e45db 100644 --- a/bindings/python/examples/how_tos/native_tokens/send.py +++ b/bindings/python/examples/how_tos/native_tokens/send.py @@ -2,13 +2,13 @@ from dotenv import load_dotenv -from iota_sdk import SendNativeTokenParams, Wallet +from iota_sdk import SendNativeTokenParams, Wallet, WalletOptions load_dotenv() # In this example we will send native tokens -wallet = Wallet(os.environ['WALLET_DB_PATH']) +wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) # Sync account with the node balance = wallet.sync() @@ -30,11 +30,11 @@ ), )] -transaction = account.send_native_tokens(outputs, None) +transaction = wallet.send_native_tokens(outputs, None) print(f'Transaction sent: {transaction.transaction_id}') # Wait for transaction to get included -block_id = account.reissue_transaction_until_included( +block_id = wallet.reissue_transaction_until_included( transaction.transaction_id) print(f'Block included: {os.environ["EXPLORER_URL"]}/block/{block_id}') diff --git a/bindings/python/examples/how_tos/nft_collection/00_mint_issuer_nft.py b/bindings/python/examples/how_tos/nft_collection/00_mint_issuer_nft.py index ecd6656129..3a4ce4fc8e 100644 --- a/bindings/python/examples/how_tos/nft_collection/00_mint_issuer_nft.py +++ b/bindings/python/examples/how_tos/nft_collection/00_mint_issuer_nft.py @@ -2,13 +2,13 @@ from dotenv import load_dotenv -from iota_sdk import MintNftParams, Utils, Wallet, utf8_to_hex +from iota_sdk import MintNftParams, Utils, Wallet, WalletOptions, utf8_to_hex load_dotenv() # In this example we will mint the issuer NFT for the NFT collection. -wallet = Wallet(os.environ['WALLET_DB_PATH']) +wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) if 'STRONGHOLD_PASSWORD' not in os.environ: raise Exception(".env STRONGHOLD_PASSWORD is undefined, see .env.example") @@ -26,10 +26,10 @@ ) -tx = account.mint_nfts([params]) +tx = wallet.mint_nfts([params]) # Wait for transaction to get included -block_id = account.reissue_transaction_until_included( +block_id = wallet.reissue_transaction_until_included( tx.transaction_id) print( diff --git a/bindings/python/examples/how_tos/nft_collection/01_mint_collection_nft.py b/bindings/python/examples/how_tos/nft_collection/01_mint_collection_nft.py index 7ae15f0f0b..ef097ff96d 100644 --- a/bindings/python/examples/how_tos/nft_collection/01_mint_collection_nft.py +++ b/bindings/python/examples/how_tos/nft_collection/01_mint_collection_nft.py @@ -3,7 +3,7 @@ from dotenv import load_dotenv -from iota_sdk import MintNftParams, Utils, Wallet, Irc27Metadata +from iota_sdk import MintNftParams, Utils, Wallet, WalletOptions, Irc27Metadata load_dotenv() @@ -19,7 +19,7 @@ issuer_nft_id = sys.argv[1] -wallet = Wallet(os.environ['WALLET_DB_PATH']) +wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) if 'STRONGHOLD_PASSWORD' not in os.environ: raise Exception(".env STRONGHOLD_PASSWORD is undefined, see .env.example") @@ -63,10 +63,10 @@ def get_immutable_metadata(index: int) -> str: print( f'Minting {len(chunk)} NFTs... ({NFT_COLLECTION_SIZE-len(nft_mint_params)}/{NFT_COLLECTION_SIZE})' ) - transaction = account.mint_nfts(chunk) + transaction = wallet.mint_nfts(chunk) # Wait for transaction to get included - block_id = account.reissue_transaction_until_included( + block_id = wallet.reissue_transaction_until_included( transaction.transaction_id) print(f'Block sent: {os.environ["EXPLORER_URL"]}/block/{block_id}') diff --git a/bindings/python/examples/how_tos/nfts/burn_nft.py b/bindings/python/examples/how_tos/nfts/burn_nft.py index c21fd8dd68..53730cd112 100644 --- a/bindings/python/examples/how_tos/nfts/burn_nft.py +++ b/bindings/python/examples/how_tos/nfts/burn_nft.py @@ -2,12 +2,12 @@ from dotenv import load_dotenv -from iota_sdk import Wallet +from iota_sdk import Wallet, WalletOptions load_dotenv() # In this example we will burn an NFT -wallet = Wallet(os.environ['WALLET_DB_PATH']) +wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) if 'STRONGHOLD_PASSWORD' not in os.environ: raise Exception(".env STRONGHOLD_PASSWORD is undefined, see .env.example") @@ -20,5 +20,5 @@ nftId = balance.nfts[0] # Send transaction. -transaction = account.prepare_burn_nft(nftId).send() +transaction = wallet.prepare_burn_nft(nftId).send() print(f'Block sent: {os.environ["EXPLORER_URL"]}/block/{transaction.block_id}') diff --git a/bindings/python/examples/how_tos/nfts/mint_nft.py b/bindings/python/examples/how_tos/nfts/mint_nft.py index bd53401b1b..8c84c2149b 100644 --- a/bindings/python/examples/how_tos/nfts/mint_nft.py +++ b/bindings/python/examples/how_tos/nfts/mint_nft.py @@ -2,13 +2,13 @@ from dotenv import load_dotenv -from iota_sdk import MintNftParams, Wallet, utf8_to_hex +from iota_sdk import MintNftParams, Wallet, WalletOptions, utf8_to_hex load_dotenv() # In this example we will mint an nft -wallet = Wallet(os.environ['WALLET_DB_PATH']) +wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) if 'STRONGHOLD_PASSWORD' not in os.environ: raise Exception(".env STRONGHOLD_PASSWORD is undefined, see .env.example") @@ -22,5 +22,5 @@ immutable_metadata=utf8_to_hex("some immutable nft metadata"), )] -transaction = account.mint_nfts(outputs) +transaction = wallet.mint_nfts(outputs) print(f'Block sent: {os.environ["EXPLORER_URL"]}/block/{transaction.block_id}') diff --git a/bindings/python/examples/how_tos/nfts/send_nft.py b/bindings/python/examples/how_tos/nfts/send_nft.py index fd0e647850..b67c801d2a 100644 --- a/bindings/python/examples/how_tos/nfts/send_nft.py +++ b/bindings/python/examples/how_tos/nfts/send_nft.py @@ -2,13 +2,13 @@ from dotenv import load_dotenv -from iota_sdk import SendNftParams, Wallet +from iota_sdk import SendNftParams, Wallet, WalletOptions load_dotenv() # In this example we will send an nft -wallet = Wallet(os.environ['WALLET_DB_PATH']) +wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) if 'STRONGHOLD_PASSWORD' not in os.environ: raise Exception(".env STRONGHOLD_PASSWORD is undefined, see .env.example") @@ -23,5 +23,5 @@ nft_id=balance.nfts[0], )] -transaction = account.send_nft(outputs) +transaction = wallet.send_nft(outputs) print(f'Block sent: {os.environ["EXPLORER_URL"]}/block/{transaction.block_id}') diff --git a/bindings/python/examples/how_tos/simple_transaction/request_funds.py b/bindings/python/examples/how_tos/simple_transaction/request_funds.py index fedf9bdad6..e97507b006 100644 --- a/bindings/python/examples/how_tos/simple_transaction/request_funds.py +++ b/bindings/python/examples/how_tos/simple_transaction/request_funds.py @@ -2,7 +2,7 @@ from dotenv import load_dotenv -from iota_sdk import Wallet +from iota_sdk import Wallet, WalletOptions # This example requests funds from the faucet @@ -12,9 +12,9 @@ 'FAUCET_URL', 'https://faucet.testnet.shimmer.network/api/enqueue') -wallet = Wallet(os.environ['WALLET_DB_PATH']) +wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) -address = account.addresses()[0].address +address = wallet.address() print(address) response = wallet.get_client().request_funds_from_faucet(FAUCET_URL, address=address) diff --git a/bindings/python/examples/how_tos/simple_transaction/simple_transaction.py b/bindings/python/examples/how_tos/simple_transaction/simple_transaction.py index f1514b60d3..9c59b57a57 100644 --- a/bindings/python/examples/how_tos/simple_transaction/simple_transaction.py +++ b/bindings/python/examples/how_tos/simple_transaction/simple_transaction.py @@ -2,13 +2,13 @@ from dotenv import load_dotenv -from iota_sdk import SendParams, Wallet +from iota_sdk import SendParams, Wallet, WalletOptions load_dotenv() # This example sends a transaction. -wallet = Wallet(os.environ['WALLET_DB_PATH']) +wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) # Sync account with the node response = wallet.sync() @@ -23,5 +23,5 @@ amount=1000000, )] -transaction = account.send_with_params(params) +transaction = wallet.send_with_params(params) print(f'Block sent: {os.environ["EXPLORER_URL"]}/block/{transaction.block_id}') diff --git a/bindings/python/examples/wallet/12-prepare_output.py b/bindings/python/examples/wallet/12-prepare_output.py index ea0dfd21b8..138028d8c1 100644 --- a/bindings/python/examples/wallet/12-prepare_output.py +++ b/bindings/python/examples/wallet/12-prepare_output.py @@ -3,16 +3,14 @@ from dotenv import load_dotenv -from iota_sdk import OutputParams, Unlocks, Wallet +from iota_sdk import OutputParams, Unlocks, Wallet, WalletOptions load_dotenv() # In this example we will prepare an output with an address and expiration # unlock condition and send it. -wallet = Wallet(os.environ['WALLET_DB_PATH']) - -account = wallet.get_account("Alice") +wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) if 'STRONGHOLD_PASSWORD' not in os.environ: raise Exception(".env STRONGHOLD_PASSWORD is undefined, see .env.example") @@ -20,7 +18,7 @@ wallet.set_stronghold_password(os.environ["STRONGHOLD_PASSWORD"]) # using prepare_output -output = account.prepare_output( +output = wallet.prepare_output( OutputParams( "rms1qprutadk4uc9rp6h7wh7sech42sl0z40ztpgyygr5tf0cn5jrqshgm8y43d", 1000000, @@ -30,5 +28,5 @@ wallet.sync() -transaction = account.send_outputs([output]) +transaction = wallet.send_outputs([output]) print(f'Block sent: {os.environ["EXPLORER_URL"]}/block/{transaction.block_id}') diff --git a/bindings/python/examples/wallet/13-check-unlock-conditions.py b/bindings/python/examples/wallet/13-check-unlock-conditions.py index 6373a2aecb..bb8bbf7a70 100644 --- a/bindings/python/examples/wallet/13-check-unlock-conditions.py +++ b/bindings/python/examples/wallet/13-check-unlock-conditions.py @@ -2,37 +2,28 @@ from dotenv import load_dotenv -from iota_sdk import OutputParams, Utils, Wallet +from iota_sdk import OutputParams, Utils, Wallet, WalletOptions load_dotenv() # In this example we check if an output has only an address unlock -# condition and that the address is from the account. +# condition and that the address is from the wallet. -wallet = Wallet(os.environ['WALLET_DB_PATH']) - -account = wallet.get_account("Alice") - -accountaddress = wallet.address() +wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) +address = wallet.address() # using prepare_output -output = account.prepare_output(OutputParams( - accountaddresss, 1000000)) - - -def hexAddress(address): - """Converts an address to hex""" - return Utils.bech32_to_hex(address.address) - +output = wallet.prepare_output(OutputParams( + address, 1000000)) -hexEncodedAccountAddresses = map(hexAddress, accountAddresses) +hexEncodedWalletAddress = Utils.bech32_to_hex(address) -controlled_by_account = False +controlled_by_wallet = False if len( output.unlock_conditions) == 1 and output.unlock_conditions[0].type == 0: - if output.unlock_conditions[0].address.pub_key_hash in hexEncodedAccountAddresses: - controlled_by_account = True + if output.unlock_conditions[0].address.pub_key_hash == hexEncodedWalletAddress: + controlled_by_wallet = True print( - f'The output has only an address unlock condition and the address is from the account: {controlled_by_account}') + f'The output has only an address unlock condition and the address is from the wallet: {controlled_by_wallet}') diff --git a/bindings/python/examples/wallet/backup.py b/bindings/python/examples/wallet/backup.py index b5302bb3df..b5184c0fa0 100644 --- a/bindings/python/examples/wallet/backup.py +++ b/bindings/python/examples/wallet/backup.py @@ -2,7 +2,7 @@ from dotenv import load_dotenv -from iota_sdk import ClientOptions, CoinType, StrongholdSecretManager, Wallet +from iota_sdk import ClientOptions, CoinType, StrongholdSecretManager, Wallet, WalletOptions, Bip44 load_dotenv() @@ -11,9 +11,6 @@ node_url = os.environ.get('NODE_URL', 'https://api.testnet.shimmer.network') client_options = ClientOptions(nodes=[node_url]) -# Shimmer coin type -coin_type = CoinType.SHIMMER - for env_var in ['STRONGHOLD_PASSWORD', 'MNEMONIC']: if env_var not in os.environ: raise Exception(f'.env {env_var} is undefined, see .env.example') @@ -21,14 +18,16 @@ secret_manager = StrongholdSecretManager( os.environ['STRONGHOLD_SNAPSHOT_PATH'], os.environ['STRONGHOLD_PASSWORD']) -wallet = Wallet('./backup-database', client_options, - coin_type, secret_manager) +bib_path = Bip44( + coin_type=CoinType.SHIMMER +) + +wallet_options = WalletOptions(None, None, bib_path, client_options, secret_manager, './backup-database') +wallet = Wallet(wallet_options) # Store the mnemonic in the Stronghold snapshot, this only needs to be # done once. -account = wallet.store_mnemonic(os.environ['MNEMONIC']) - -accounts = wallet.create_account('Alice') +wallet.store_mnemonic(os.environ['MNEMONIC']) wallet.backup("backup.stronghold", os.environ['STRONGHOLD_PASSWORD']) print('Created backup') diff --git a/bindings/python/examples/wallet/create_alias.py b/bindings/python/examples/wallet/create_alias.py index 8718da2051..e9d6c4ff34 100644 --- a/bindings/python/examples/wallet/create_alias.py +++ b/bindings/python/examples/wallet/create_alias.py @@ -2,13 +2,13 @@ from dotenv import load_dotenv -from iota_sdk import Wallet +from iota_sdk import Wallet, WalletOptions load_dotenv() # In this example we will create an account output -wallet = Wallet(os.environ['WALLET_DB_PATH']) +wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) # Sync account with the node wallet.sync() @@ -19,5 +19,5 @@ wallet.set_stronghold_password(os.environ["STRONGHOLD_PASSWORD"]) # Send transaction. -transaction = account.create_account_output(None, None) +transaction = wallet.create_account_output(None, None) print(f'Block sent: {os.environ["EXPLORER_URL"]}/block/{transaction.block_id}') diff --git a/bindings/python/examples/wallet/get_client.py b/bindings/python/examples/wallet/get_client.py index 0e3c8bde03..7b95c00691 100644 --- a/bindings/python/examples/wallet/get_client.py +++ b/bindings/python/examples/wallet/get_client.py @@ -2,13 +2,13 @@ from dotenv import load_dotenv -from iota_sdk import Wallet +from iota_sdk import Wallet, WalletOptions load_dotenv() # This example gets a client from the wallet. -wallet = Wallet(os.environ['WALLET_DB_PATH']) +wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) client = wallet.get_client() diff --git a/bindings/python/examples/wallet/getting_started.py b/bindings/python/examples/wallet/getting_started.py index 2f3bbb9fa6..c22d0a2fee 100644 --- a/bindings/python/examples/wallet/getting_started.py +++ b/bindings/python/examples/wallet/getting_started.py @@ -10,7 +10,7 @@ load_dotenv() -# A name to associate with the created account. +# A name to associate with the created wallet. ACCOUNT_ALIAS = 'Alice' # The node to connect to. @@ -21,7 +21,7 @@ STRONGHOLD_PASSWORD = os.environ.get( 'STRONGHOLD_PASSWORD', 'a-secure-password') -# The path to store the account snapshot. +# The path to store the wallet snapshot. STRONGHOLD_SNAPSHOT_PATH = 'vault.stronghold' # Setup Stronghold secret manager diff --git a/bindings/python/examples/wallet/logger.py b/bindings/python/examples/wallet/logger.py index 30c0019a14..1b7d998094 100644 --- a/bindings/python/examples/wallet/logger.py +++ b/bindings/python/examples/wallet/logger.py @@ -4,7 +4,7 @@ from dotenv import load_dotenv # pylint: disable=no-name-in-module -from iota_sdk import (ClientOptions, CoinType, StrongholdSecretManager, Wallet, +from iota_sdk import (ClientOptions, CoinType, StrongholdSecretManager, Wallet, WalletOptions, Bip44, init_logger) load_dotenv() @@ -24,9 +24,6 @@ node_url = os.environ.get('NODE_URL', 'https://api.testnet.shimmer.network') client_options = ClientOptions(nodes=[node_url]) -# Shimmer coin type -coin_type = CoinType.SHIMMER - for env_var in ['STRONGHOLD_PASSWORD', 'MNEMONIC']: if env_var not in os.environ: raise Exception(f'.env {env_var} is undefined, see .env.example') @@ -35,12 +32,13 @@ "wallet.stronghold", os.environ["STRONGHOLD_PASSWORD"]) -wallet = Wallet(os.environ['WALLET_DB_PATH'], client_options, - coin_type, secret_manager) +bib_path = Bip44( + coin_type=CoinType.SHIMMER +) + +wallet_options = WalletOptions(None, None, bib_path, client_options, secret_manager, os.environ.get('WALLET_DB_PATH')) +wallet = Wallet(wallet_options) # Store the mnemonic in the Stronghold snapshot, this only needs to be # done once. -account = wallet.store_mnemonic(os.environ["MNEMONIC"]) - -account = wallet.create_account('Alice') -print(account.get_metadata()) +wallet.store_mnemonic(os.environ["MNEMONIC"]) diff --git a/bindings/python/examples/wallet/migrate-stronghold-snapshot-v2-to-v3.py b/bindings/python/examples/wallet/migrate-stronghold-snapshot-v2-to-v3.py index 2af7aa5aa4..3bc0eb5a8a 100644 --- a/bindings/python/examples/wallet/migrate-stronghold-snapshot-v2-to-v3.py +++ b/bindings/python/examples/wallet/migrate-stronghold-snapshot-v2-to-v3.py @@ -3,7 +3,7 @@ from dotenv import load_dotenv # pylint: disable=no-name-in-module -from iota_sdk import (ClientOptions, CoinType, StrongholdSecretManager, Wallet, +from iota_sdk import (ClientOptions, CoinType, StrongholdSecretManager, Wallet, WalletOptions, Bip44, migrate_stronghold_snapshot_v2_to_v3) load_dotenv() @@ -12,16 +12,17 @@ v3_path = "./v3.stronghold" node_url = os.environ.get('NODE_URL', 'https://api.testnet.shimmer.network') client_options = ClientOptions(nodes=[node_url]) -coin_type = CoinType.SHIMMER +bib_path = Bip44( + coin_type=CoinType.SHIMMER +) + try: secret_manager = StrongholdSecretManager(v2_path, "current_password") # This should fail with error, migration required. - wallet = Wallet( - os.environ['WALLET_DB_PATH'], - client_options, - coin_type, - secret_manager) + + wallet_options = WalletOptions(None, None, bib_path, client_options, secret_manager, os.environ.get('WALLET_DB_PATH')) + wallet = Wallet(wallet_options) except ValueError as e: print(e) @@ -34,12 +35,8 @@ "new_password") secret_manager = StrongholdSecretManager(v3_path, "new_password") + +wallet_options = WalletOptions(None, None, bib_path, client_options, secret_manager, os.environ.get('WALLET_DB_PATH')) + # This shouldn't fail anymore as snapshot has been migrated. -wallet = Wallet( - os.environ['WALLET_DB_PATH'], - client_options, - coin_type, - secret_manager) - -account = wallet.create_account('Alice') -print(account.get_metadata()) +wallet = Wallet(wallet_options) diff --git a/bindings/python/examples/wallet/offline_signing/0_generate_addresses.py b/bindings/python/examples/wallet/offline_signing/0_generate_addresses.py index f9a70834b5..71cbfcfd11 100644 --- a/bindings/python/examples/wallet/offline_signing/0_generate_addresses.py +++ b/bindings/python/examples/wallet/offline_signing/0_generate_addresses.py @@ -9,7 +9,7 @@ from dotenv import load_dotenv -from iota_sdk import ClientOptions, CoinType, StrongholdSecretManager, Wallet +from iota_sdk import ClientOptions, CoinType, StrongholdSecretManager, Wallet, WalletOptions, Bip44 load_dotenv() @@ -28,20 +28,21 @@ secret_manager = StrongholdSecretManager( STRONGHOLD_SNAPSHOT_PATH, os.environ['STRONGHOLD_PASSWORD']) -wallet = Wallet(OFFLINE_WALLET_DB_PATH, offline_client_options, - CoinType.IOTA, secret_manager) +bib_path = Bip44( + coin_type=CoinType.SHIMMER +) + +wallet_options = WalletOptions(None, None, bib_path, offline_client_options, secret_manager, OFFLINE_WALLET_DB_PATH) +wallet = Wallet(wallet_options) # Store the mnemonic in the Stronghold snapshot, this only needs to be # done once wallet.store_mnemonic(os.environ['MNEMONIC']) -account = wallet.create_account('Alice', "rms") -print("Account created:", account.get_metadata()) - -# Get the addresses from the account (by default only one) +# Get the address from the wallet address = wallet.address() -json_data = json.dumps(list(map(lambda x: x.__dict__, addresses)), indent=4) +json_data = json.dumps(list(map(lambda x: x.__dict__, address)), indent=4) print(f"example.addresses.json:\n{json_data}") f = open(ADDRESSES_FILE_PATH, "w", encoding="utf-8") f.write(json_data) diff --git a/bindings/python/examples/wallet/offline_signing/1_prepare_transaction.py b/bindings/python/examples/wallet/offline_signing/1_prepare_transaction.py index 18c7df09d0..252fcbb3f6 100644 --- a/bindings/python/examples/wallet/offline_signing/1_prepare_transaction.py +++ b/bindings/python/examples/wallet/offline_signing/1_prepare_transaction.py @@ -10,7 +10,7 @@ from dotenv import load_dotenv from iota_sdk import (AccountAddress, ClientOptions, CoinType, SendParams, - Wallet) + Wallet, WalletOptions, Bip44) load_dotenv() @@ -35,15 +35,15 @@ client_options = ClientOptions(nodes=[os.environ.get('NODE_URL')]) -wallet = Wallet(ONLINE_WALLET_DB_PATH, client_options, - CoinType.IOTA, "placeholder") - -account = wallet.create_account('Alice', "rms", addresses) -print("Account created:", account.get_metadata()) +bib_path = Bip44( + coin_type=CoinType.SHIMMER +) +wallet_options = WalletOptions(None, None, bib_path, client_options, "placeholder", ONLINE_WALLET_DB_PATH) +wallet = Wallet(wallet_options) wallet.sync() -prepared_transaction = account.prepare_send(params) +prepared_transaction = wallet.prepare_send(params) json_data = json.dumps( prepared_transaction.prepared_transaction_data().to_dict(), diff --git a/bindings/python/examples/wallet/offline_signing/2_sign_transaction.py b/bindings/python/examples/wallet/offline_signing/2_sign_transaction.py index 6bbfb52dc6..1a30f5c14d 100644 --- a/bindings/python/examples/wallet/offline_signing/2_sign_transaction.py +++ b/bindings/python/examples/wallet/offline_signing/2_sign_transaction.py @@ -9,7 +9,7 @@ from dacite import from_dict from dotenv import load_dotenv -from iota_sdk import PreparedTransactionData, Wallet +from iota_sdk import PreparedTransactionData, Wallet, WalletOptions load_dotenv() @@ -24,9 +24,7 @@ prepared_transaction_data = from_dict( PreparedTransactionData, prepared_transaction_data) -wallet = Wallet(OFFLINE_WALLET_DB_PATH) - -account = wallet.get_account("Alice") +wallet = Wallet(WalletOptions(storage_path=OFFLINE_WALLET_DB_PATH)) if 'STRONGHOLD_PASSWORD' not in os.environ: raise Exception(".env STRONGHOLD_PASSWORD is undefined, see .env.example") @@ -34,7 +32,7 @@ wallet.set_stronghold_password(os.environ["STRONGHOLD_PASSWORD"]) # Signs prepared transaction offline. -signed_transaction_data = account.sign_transaction( +signed_transaction_data = wallet.sign_transaction( prepared_transaction_data) print("Signed transaction.") diff --git a/bindings/python/examples/wallet/offline_signing/3_send_transaction.py b/bindings/python/examples/wallet/offline_signing/3_send_transaction.py index bfa3ff8a8a..e4d4dd3ce3 100644 --- a/bindings/python/examples/wallet/offline_signing/3_send_transaction.py +++ b/bindings/python/examples/wallet/offline_signing/3_send_transaction.py @@ -9,7 +9,7 @@ from dacite import from_dict from dotenv import load_dotenv -from iota_sdk import SignedTransactionData, Wallet +from iota_sdk import SignedTransactionData, Wallet, WalletOptions load_dotenv() @@ -19,9 +19,7 @@ if 'EXPLORER_URL' not in os.environ: raise Exception(".env EXPLORER_URL is undefined, see .env.example") -wallet = Wallet(ONLINE_WALLET_DB_PATH, None, None, "placeholder") - -account = wallet.get_account("Alice") +wallet = Wallet(WalletOptions(storage_path=ONLINE_WALLET_DB_PATH)) signed_transaction_data = json.load( open(SIGNED_TRANSACTION_FILE_PATH, "r", encoding="utf-8")) @@ -29,9 +27,9 @@ SignedTransactionData, signed_transaction_data) # Sends offline signed transaction online. -transaction = account.submit_and_store_transaction(signed_transaction_data) +transaction = wallet.submit_and_store_transaction(signed_transaction_data) print( f'Transaction sent: {os.environ["EXPLORER_URL"]}/transaction/{transaction.transaction_id}') -block_id = account.reissue_transaction_until_included( +block_id = wallet.reissue_transaction_until_included( transaction.transaction_id) print(f'Block included: {os.environ["EXPLORER_URL"]}/block/{block_id}') diff --git a/bindings/python/examples/wallet/recover_accounts.py b/bindings/python/examples/wallet/recover_accounts.py deleted file mode 100644 index b121402463..0000000000 --- a/bindings/python/examples/wallet/recover_accounts.py +++ /dev/null @@ -1,39 +0,0 @@ -import json -import os - -from dotenv import load_dotenv - -from iota_sdk import ClientOptions, CoinType, StrongholdSecretManager, Wallet - -load_dotenv() - -# This example searches for accounts with unspent outputs. - -node_url = os.environ.get('NODE_URL', 'https://api.testnet.shimmer.network') -client_options = ClientOptions(nodes=[node_url]) - -# Shimmer coin type -coin_type = CoinType.SHIMMER - -for env_var in ['STRONGHOLD_PASSWORD', 'MNEMONIC']: - if env_var not in os.environ: - raise Exception(f'.env {env_var} is undefined, see .env.example') - -secret_manager = StrongholdSecretManager( - os.environ['STRONGHOLD_SNAPSHOT_PATH'], os.environ['STRONGHOLD_PASSWORD']) - -wallet = Wallet( - os.environ['WALLET_DB_PATH'], - client_options, - coin_type, - secret_manager) - -# Store the mnemonic in the Stronghold snapshot, this only needs to be -# done once. -account = wallet.store_mnemonic(os.environ['MNEMONIC']) - -# Searches for unspent outputs until no ones are found for 3 accounts in a row -# and checks the addresses for each account until 10 addresses in a row -# have nothing. -accounts = wallet.recover_accounts(0, 3, 10, None) -print(json.dumps(accounts, indent=4)) diff --git a/bindings/python/examples/wallet/restore_backup.py b/bindings/python/examples/wallet/restore_backup.py index 4d726fea05..2439262fc7 100644 --- a/bindings/python/examples/wallet/restore_backup.py +++ b/bindings/python/examples/wallet/restore_backup.py @@ -1,10 +1,9 @@ import json import os -from dataclasses import asdict from dotenv import load_dotenv -from iota_sdk import ClientOptions, CoinType, Wallet +from iota_sdk import ClientOptions, CoinType, Wallet, WalletOptions, Bip44 load_dotenv() @@ -13,16 +12,16 @@ node_url = os.environ.get('NODE_URL', 'https://api.testnet.shimmer.network') client_options = ClientOptions(nodes=[node_url]) -# Shimmer coin type -coin_type = CoinType.SHIMMER +bib_path = Bip44( + coin_type=CoinType.SHIMMER +) -wallet = Wallet('./restore-backup-database', client_options, - coin_type, 'Placeholder') +wallet_options = WalletOptions(None, None, bib_path, client_options, 'Placeholder', './restore-backup-database') +wallet = Wallet(wallet_options) if 'STRONGHOLD_PASSWORD' not in os.environ: raise Exception(".env STRONGHOLD_PASSWORD is undefined, see .env.example") wallet.restore_backup("backup.stronghold", os.environ['STRONGHOLD_PASSWORD']) -accounts = wallet.get_accounts() -print(f'Restored accounts: {json.dumps(asdict(accounts), indent=4)}') +print(f'Restored wallet: {json.dumps(wallet, indent=4)}') diff --git a/bindings/python/examples/wallet/transaction_options.py b/bindings/python/examples/wallet/transaction_options.py index 234e6c9175..8055406e3a 100644 --- a/bindings/python/examples/wallet/transaction_options.py +++ b/bindings/python/examples/wallet/transaction_options.py @@ -3,13 +3,13 @@ from dotenv import load_dotenv from iota_sdk import (RemainderValueStrategy, TaggedDataPayload, SendParams, - TransactionOptions, Wallet, utf8_to_hex) + TransactionOptions, Wallet, WalletOptions, utf8_to_hex) load_dotenv() # This example sends a transaction with a tagged data payload. -wallet = Wallet(os.environ['WALLET_DB_PATH']) +wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) # Sync account with the node response = wallet.sync() @@ -24,7 +24,7 @@ amount=1000000, )] -transaction = account.send_with_params( +transaction = wallet.send_with_params( params, TransactionOptions( remainder_value_strategy=RemainderValueStrategy.ReuseAddress, diff --git a/bindings/python/iota_sdk/__init__.py b/bindings/python/iota_sdk/__init__.py index bbbbc1ed21..538dffa3ae 100644 --- a/bindings/python/iota_sdk/__init__.py +++ b/bindings/python/iota_sdk/__init__.py @@ -8,7 +8,7 @@ from .utils import Utils from .wallet.wallet import Wallet, WalletOptions from .wallet.common import WalletError -from .wallet.sync_options import AccountSyncOptions, NftSyncOptions, SyncOptions +from .wallet.sync_options import AccountSyncOptions, NftSyncOptions, SyncOptions, WalletSyncOptions from .secret_manager.secret_manager import * from .prefix_hex import * from .types.address import * diff --git a/bindings/python/tests/address_generation_test.py b/bindings/python/tests/address_generation_test.py index 566cbb69e0..8d154a0d65 100644 --- a/bindings/python/tests/address_generation_test.py +++ b/bindings/python/tests/address_generation_test.py @@ -37,14 +37,14 @@ def test_address_generation_shimmer(): secret_manager = MnemonicSecretManager( "acoustic trophy damage hint search taste love bicycle foster cradle brown govern endless depend situate athlete pudding blame question genius transfer van random vast") - + bib_path = Bip44( coin_type=CoinType.IOTA ) wallet_options = WalletOptions(None, None, bib_path, client_options, secret_manager, db_path) wallet = Wallet(wallet_options) - address = account.address() + address = wallet.address() assert 'smr1qzev36lk0gzld0k28fd2fauz26qqzh4hd4cwymlqlv96x7phjxcw6ckj80y' == address shutil.rmtree(db_path, ignore_errors=True) diff --git a/bindings/python/tests/test_offline.py b/bindings/python/tests/test_offline.py index d6a79f83f6..0165610024 100644 --- a/bindings/python/tests/test_offline.py +++ b/bindings/python/tests/test_offline.py @@ -3,7 +3,6 @@ import json import unittest -import pytest from iota_sdk import Client, MnemonicSecretManager, Utils, SecretManager, OutputId, hex_to_utf8, utf8_to_hex, Bip44, CoinType, Irc27Metadata, Irc30Metadata From 9a11da5e288f262631a97c16b67d910d44e1d818 Mon Sep 17 00:00:00 2001 From: Brord van Wierst Date: Thu, 7 Dec 2023 12:54:31 +0100 Subject: [PATCH 06/34] format --- .../wallet/migrate-stronghold-snapshot-v2-to-v3.py | 8 +++++++- .../examples/wallet/offline_signing/3_send_transaction.py | 2 +- bindings/python/iota_sdk/types/unlock.py | 3 +++ bindings/python/iota_sdk/wallet/wallet.py | 3 ++- bindings/python/tests/address_generation_test.py | 1 - 5 files changed, 13 insertions(+), 4 deletions(-) diff --git a/bindings/python/examples/wallet/migrate-stronghold-snapshot-v2-to-v3.py b/bindings/python/examples/wallet/migrate-stronghold-snapshot-v2-to-v3.py index 3bc0eb5a8a..3b36d76374 100644 --- a/bindings/python/examples/wallet/migrate-stronghold-snapshot-v2-to-v3.py +++ b/bindings/python/examples/wallet/migrate-stronghold-snapshot-v2-to-v3.py @@ -21,7 +21,13 @@ secret_manager = StrongholdSecretManager(v2_path, "current_password") # This should fail with error, migration required. - wallet_options = WalletOptions(None, None, bib_path, client_options, secret_manager, os.environ.get('WALLET_DB_PATH')) + wallet_options = WalletOptions( + None, + None, + bib_path, + client_options, + secret_manager, + os.environ.get('WALLET_DB_PATH')) wallet = Wallet(wallet_options) except ValueError as e: print(e) diff --git a/bindings/python/examples/wallet/offline_signing/3_send_transaction.py b/bindings/python/examples/wallet/offline_signing/3_send_transaction.py index e4d4dd3ce3..4cba62f441 100644 --- a/bindings/python/examples/wallet/offline_signing/3_send_transaction.py +++ b/bindings/python/examples/wallet/offline_signing/3_send_transaction.py @@ -9,7 +9,7 @@ from dacite import from_dict from dotenv import load_dotenv -from iota_sdk import SignedTransactionData, Wallet, WalletOptions +from iota_sdk import SignedTransactionData, Wallet, WalletOptions load_dotenv() diff --git a/bindings/python/iota_sdk/types/unlock.py b/bindings/python/iota_sdk/types/unlock.py index 3fa712e6b6..47ac3f8716 100644 --- a/bindings/python/iota_sdk/types/unlock.py +++ b/bindings/python/iota_sdk/types/unlock.py @@ -93,6 +93,7 @@ class NftUnlock: def deserialize_unlocks(dicts: List[Dict[str, Any]]) -> List[Unlock]: pass + @json @dataclass class MultiUnlock: @@ -127,6 +128,8 @@ class EmptyUnlock: EmptyUnlock] # pylint: disable=too-many-return-statements + + def deserialize_unlock(d: Dict[str, Any]) -> Unlock: """ Takes a dictionary as input and returns an instance of a specific class based on the value of the 'type' key in the dictionary. diff --git a/bindings/python/iota_sdk/wallet/wallet.py b/bindings/python/iota_sdk/wallet/wallet.py index cb3584b136..69f72dbff3 100644 --- a/bindings/python/iota_sdk/wallet/wallet.py +++ b/bindings/python/iota_sdk/wallet/wallet.py @@ -37,7 +37,8 @@ class WalletOptions: alias: Optional[str] = None bip_path: Optional[Bip44] = None client_options: Optional[ClientOptions] = None - secret_manager: Optional[Union[LedgerNanoSecretManager, MnemonicSecretManager, SeedSecretManager, StrongholdSecretManager]] = None + secret_manager: Optional[Union[LedgerNanoSecretManager, + MnemonicSecretManager, SeedSecretManager, StrongholdSecretManager]] = None storage_path: Optional[str] = None diff --git a/bindings/python/tests/address_generation_test.py b/bindings/python/tests/address_generation_test.py index 8d154a0d65..576243be82 100644 --- a/bindings/python/tests/address_generation_test.py +++ b/bindings/python/tests/address_generation_test.py @@ -37,7 +37,6 @@ def test_address_generation_shimmer(): secret_manager = MnemonicSecretManager( "acoustic trophy damage hint search taste love bicycle foster cradle brown govern endless depend situate athlete pudding blame question genius transfer van random vast") - bib_path = Bip44( coin_type=CoinType.IOTA ) From 71ec713aff21989e1881198bba4895492e54d5f3 Mon Sep 17 00:00:00 2001 From: Brord van Wierst Date: Thu, 7 Dec 2023 13:25:53 +0100 Subject: [PATCH 07/34] prot params --- bindings/python/iota_sdk/types/node_info.py | 36 +++++++++++---------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/bindings/python/iota_sdk/types/node_info.py b/bindings/python/iota_sdk/types/node_info.py index 9cc94c10fa..8c8bfecf8e 100644 --- a/bindings/python/iota_sdk/types/node_info.py +++ b/bindings/python/iota_sdk/types/node_info.py @@ -79,12 +79,22 @@ class StorageScoreParameters: offset_staking_feature: Defines the offset to be used for staking feature. offset_delegation: Defines the offset to be used for delegation output. """ - storage_cost: int + storage_cost: int = field(metadata=config( + encoder=str + )) factor_data: int - offset_output_overhead: int - offset_ed25519_block_issuer_key: int - offset_staking_feature: int - offset_delegation: int + offset_output_overhead: int = field(metadata=config( + encoder=str + )) + offset_ed25519_block_issuer_key: int = field(metadata=config( + encoder=str + )) + offset_staking_feature: int = field(metadata=config( + encoder=str + )) + offset_delegation: int = field(metadata=config( + encoder=str + )) @json @@ -259,22 +269,14 @@ class ProtocolParameters: slot_duration_in_seconds: int slots_per_epoch_exponent: int mana_parameters: ManaParameters - staking_unbonding_period: int = field(metadata=config( - encoder=str - )) + staking_unbonding_period: int validation_blocks_per_slot: int punishment_epochs: int liveness_threshold_lower_bound: int liveness_threshold_upper_bound: int - min_committable_age: int = field(metadata=config( - encoder=str - )) - max_committable_age: int = field(metadata=config( - encoder=str - )) - epoch_nearing_threshold: int = field(metadata=config( - encoder=str - )) + min_committable_age: int + max_committable_age: int + epoch_nearing_threshold: int congestion_control_parameters: CongestionControlParameters version_signaling_parameters: VersionSignalingParameters rewards_parameters: RewardsParameters From 2dce6428270aca71d62b6cf9b7480ea23e02fbaa Mon Sep 17 00:00:00 2001 From: Brord van Wierst Date: Fri, 8 Dec 2023 18:15:25 +0100 Subject: [PATCH 08/34] examples update --- .../python/examples/client/04_get_output.py | 2 +- .../examples/how_tos/account_output/create.py | 17 ++++-- .../how_tos/account_output/destroy.py | 7 +-- .../implicit_account_creation.py | 18 +++++++ .../how_tos/account_wallet/request_funds.py | 9 +++- .../accounts_and_addresses/create_wallet.py | 13 +++-- .../examples/wallet/12-prepare_output.py | 32 ----------- .../wallet/13-check-unlock-conditions.py | 29 ---------- bindings/python/examples/wallet/backup.py | 33 ------------ .../python/examples/wallet/create_alias.py | 23 -------- bindings/python/examples/wallet/get_client.py | 16 ------ .../python/examples/wallet/getting_started.py | 50 ----------------- bindings/python/examples/wallet/logger.py | 44 --------------- .../migrate-stronghold-snapshot-v2-to-v3.py | 48 ----------------- .../offline_signing/0_generate_addresses.py | 49 ----------------- .../offline_signing/1_prepare_transaction.py | 54 ------------------- .../offline_signing/2_sign_transaction.py | 44 --------------- .../offline_signing/3_send_transaction.py | 35 ------------ .../python/examples/wallet/restore_backup.py | 27 ---------- .../examples/wallet/transaction_options.py | 36 ------------- .../account/implicit_account_creation.rs | 7 ++- 21 files changed, 58 insertions(+), 535 deletions(-) create mode 100644 bindings/python/examples/how_tos/account_output/implicit_account_creation.py delete mode 100644 bindings/python/examples/wallet/12-prepare_output.py delete mode 100644 bindings/python/examples/wallet/13-check-unlock-conditions.py delete mode 100644 bindings/python/examples/wallet/backup.py delete mode 100644 bindings/python/examples/wallet/create_alias.py delete mode 100644 bindings/python/examples/wallet/get_client.py delete mode 100644 bindings/python/examples/wallet/getting_started.py delete mode 100644 bindings/python/examples/wallet/logger.py delete mode 100644 bindings/python/examples/wallet/migrate-stronghold-snapshot-v2-to-v3.py delete mode 100644 bindings/python/examples/wallet/offline_signing/0_generate_addresses.py delete mode 100644 bindings/python/examples/wallet/offline_signing/1_prepare_transaction.py delete mode 100644 bindings/python/examples/wallet/offline_signing/2_sign_transaction.py delete mode 100644 bindings/python/examples/wallet/offline_signing/3_send_transaction.py delete mode 100644 bindings/python/examples/wallet/restore_backup.py delete mode 100644 bindings/python/examples/wallet/transaction_options.py diff --git a/bindings/python/examples/client/04_get_output.py b/bindings/python/examples/client/04_get_output.py index 7c3b10e87d..8e1edde5ec 100644 --- a/bindings/python/examples/client/04_get_output.py +++ b/bindings/python/examples/client/04_get_output.py @@ -14,5 +14,5 @@ # Get an outputs by its id output_with_metadata = client.get_output( - '0x022aefa73dff09b35b21ab5493412b0d354ad07a970a12b71e8087c6f3a7b8660000') + '0x022aefa73dff09b35b21ab5493412b0d354ad07a970a12b71e8087c6f3a7b866000000000000') print(json.dumps(output_with_metadata.to_dict(), indent=4)) diff --git a/bindings/python/examples/how_tos/account_output/create.py b/bindings/python/examples/how_tos/account_output/create.py index e9d6c4ff34..3c9ab4b3c5 100644 --- a/bindings/python/examples/how_tos/account_output/create.py +++ b/bindings/python/examples/how_tos/account_output/create.py @@ -6,18 +6,27 @@ load_dotenv() +for env_var in ['WALLET_DB_PATH', 'STRONGHOLD_PASSWORD', 'EXPLORER_URL']: + if env_var not in os.environ: + raise Exception(f".env {env_var} is undefined, see .env.example") + # In this example we will create an account output wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) # Sync account with the node -wallet.sync() - -if 'STRONGHOLD_PASSWORD' not in os.environ: - raise Exception(".env STRONGHOLD_PASSWORD is undefined, see .env.example") +balance = wallet.sync() +print( f'Accounts BEFORE: {balance.accounts}') wallet.set_stronghold_password(os.environ["STRONGHOLD_PASSWORD"]) +print("Sending the create-account transaction...") + # Send transaction. transaction = wallet.create_account_output(None, None) print(f'Block sent: {os.environ["EXPLORER_URL"]}/block/{transaction.block_id}') + +time.sleep(10) + +balance = wallet.sync() +print( f'Accounts AFTER: {balance.accounts}') diff --git a/bindings/python/examples/how_tos/account_output/destroy.py b/bindings/python/examples/how_tos/account_output/destroy.py index a54d62d2f9..928f860779 100644 --- a/bindings/python/examples/how_tos/account_output/destroy.py +++ b/bindings/python/examples/how_tos/account_output/destroy.py @@ -6,6 +6,10 @@ load_dotenv() +for env_var in ['WALLET_DB_PATH', 'STRONGHOLD_PASSWORD', 'EXPLORER_URL']: + if env_var not in os.environ: + raise Exception(f".env {env_var} is undefined, see .env.example") + # In this example we will destroy an account output wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) @@ -16,9 +20,6 @@ # We try to destroy the first account in the account account_id = balance.accounts[0] -if 'STRONGHOLD_PASSWORD' not in os.environ: - raise Exception(".env STRONGHOLD_PASSWORD is undefined, see .env.example") - wallet.set_stronghold_password(os.environ["STRONGHOLD_PASSWORD"]) # Send transaction. diff --git a/bindings/python/examples/how_tos/account_output/implicit_account_creation.py b/bindings/python/examples/how_tos/account_output/implicit_account_creation.py new file mode 100644 index 0000000000..96f21f2b10 --- /dev/null +++ b/bindings/python/examples/how_tos/account_output/implicit_account_creation.py @@ -0,0 +1,18 @@ +import os + +from dotenv import load_dotenv + +from iota_sdk import Wallet, WalletOptions + +load_dotenv() + +if 'WALLET_DB_PATH' not in os.environ: + raise Exception(".env WALLET_DB_PATH is undefined, see .env.example") + +# In this example, we create an implicit account creation address. + +wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) + +# Sync account with the node +address = wallet.implicit_account_creation_address() +print(f'Fund the following address: {address}') diff --git a/bindings/python/examples/how_tos/account_wallet/request_funds.py b/bindings/python/examples/how_tos/account_wallet/request_funds.py index 58e3a94e58..779134627a 100644 --- a/bindings/python/examples/how_tos/account_wallet/request_funds.py +++ b/bindings/python/examples/how_tos/account_wallet/request_funds.py @@ -9,15 +9,20 @@ load_dotenv() +for env_var in ['FAUCET_URL', 'WALLET_DB_PATH', 'EXPLORER_URL']: + if env_var not in os.environ: + raise Exception(f".env {env_var} is undefined, see .env.example") + FAUCET_URL = os.environ.get( 'FAUCET_URL', 'https://faucet.testnet.shimmer.network/api/enqueue') wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) balance = wallet.sync(None) +print(f'{balance}') total_base_token_balance = balance.base_coin.total print( - f'Balance before requesting funds on account address: {total_base_token_balance}') + f'Balance before requesting funds on wallet address: {total_base_token_balance}') account_id = balance.accounts[0] print(f'Account Id: {account_id}') @@ -35,4 +40,4 @@ total_base_token_balance = wallet.sync(sync_options).base_coin.total print( - f'Balance after requesting funds on account address: {total_base_token_balance}') + f'Balance after requesting funds on wallet address: {total_base_token_balance}') diff --git a/bindings/python/examples/how_tos/accounts_and_addresses/create_wallet.py b/bindings/python/examples/how_tos/accounts_and_addresses/create_wallet.py index d9bc949f66..bdc035ad0c 100644 --- a/bindings/python/examples/how_tos/accounts_and_addresses/create_wallet.py +++ b/bindings/python/examples/how_tos/accounts_and_addresses/create_wallet.py @@ -2,7 +2,7 @@ from dotenv import load_dotenv -from iota_sdk import ClientOptions, CoinType, StrongholdSecretManager, Wallet, WalletOptions, Bip44 +from iota_sdk import ClientOptions, CoinType, StrongholdSecretManager, SecretManager, Wallet, WalletOptions, Bip44 load_dotenv() @@ -17,6 +17,11 @@ secret_manager = StrongholdSecretManager( os.environ['STRONGHOLD_SNAPSHOT_PATH'], os.environ['STRONGHOLD_PASSWORD']) + +# Store the mnemonic in the Stronghold snapshot, this only needs to be +# done once. +SecretManager(secret_manager).store_mnemonic(os.environ['MNEMONIC']) + bib_path = Bip44( coin_type=CoinType.SHIMMER ) @@ -24,6 +29,6 @@ wallet_options = WalletOptions(None, None, bib_path, client_options, secret_manager, os.environ.get('WALLET_DB_PATH')) wallet = Wallet(wallet_options) -# Store the mnemonic in the Stronghold snapshot, this only needs to be -# done once. -wallet.store_mnemonic(os.environ['MNEMONIC']) +# Update the wallet to the latest state +balance = wallet.sync() +print('Generated new wallet') diff --git a/bindings/python/examples/wallet/12-prepare_output.py b/bindings/python/examples/wallet/12-prepare_output.py deleted file mode 100644 index 138028d8c1..0000000000 --- a/bindings/python/examples/wallet/12-prepare_output.py +++ /dev/null @@ -1,32 +0,0 @@ -import json -import os - -from dotenv import load_dotenv - -from iota_sdk import OutputParams, Unlocks, Wallet, WalletOptions - -load_dotenv() - -# In this example we will prepare an output with an address and expiration -# unlock condition and send it. - -wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) - -if 'STRONGHOLD_PASSWORD' not in os.environ: - raise Exception(".env STRONGHOLD_PASSWORD is undefined, see .env.example") - -wallet.set_stronghold_password(os.environ["STRONGHOLD_PASSWORD"]) - -# using prepare_output -output = wallet.prepare_output( - OutputParams( - "rms1qprutadk4uc9rp6h7wh7sech42sl0z40ztpgyygr5tf0cn5jrqshgm8y43d", - 1000000, - unlocks=Unlocks( - expiration_slot_index=1676570528))) -print(f"Output: {json.dumps(output.to_dict(), indent=4)}") - -wallet.sync() - -transaction = wallet.send_outputs([output]) -print(f'Block sent: {os.environ["EXPLORER_URL"]}/block/{transaction.block_id}') diff --git a/bindings/python/examples/wallet/13-check-unlock-conditions.py b/bindings/python/examples/wallet/13-check-unlock-conditions.py deleted file mode 100644 index bb8bbf7a70..0000000000 --- a/bindings/python/examples/wallet/13-check-unlock-conditions.py +++ /dev/null @@ -1,29 +0,0 @@ -import os - -from dotenv import load_dotenv - -from iota_sdk import OutputParams, Utils, Wallet, WalletOptions - -load_dotenv() - -# In this example we check if an output has only an address unlock -# condition and that the address is from the wallet. - -wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) -address = wallet.address() - -# using prepare_output -output = wallet.prepare_output(OutputParams( - address, 1000000)) - -hexEncodedWalletAddress = Utils.bech32_to_hex(address) - -controlled_by_wallet = False - -if len( - output.unlock_conditions) == 1 and output.unlock_conditions[0].type == 0: - if output.unlock_conditions[0].address.pub_key_hash == hexEncodedWalletAddress: - controlled_by_wallet = True - -print( - f'The output has only an address unlock condition and the address is from the wallet: {controlled_by_wallet}') diff --git a/bindings/python/examples/wallet/backup.py b/bindings/python/examples/wallet/backup.py deleted file mode 100644 index b5184c0fa0..0000000000 --- a/bindings/python/examples/wallet/backup.py +++ /dev/null @@ -1,33 +0,0 @@ -import os - -from dotenv import load_dotenv - -from iota_sdk import ClientOptions, CoinType, StrongholdSecretManager, Wallet, WalletOptions, Bip44 - -load_dotenv() - -# This example creates a new database and wallet - -node_url = os.environ.get('NODE_URL', 'https://api.testnet.shimmer.network') -client_options = ClientOptions(nodes=[node_url]) - -for env_var in ['STRONGHOLD_PASSWORD', 'MNEMONIC']: - if env_var not in os.environ: - raise Exception(f'.env {env_var} is undefined, see .env.example') - -secret_manager = StrongholdSecretManager( - os.environ['STRONGHOLD_SNAPSHOT_PATH'], os.environ['STRONGHOLD_PASSWORD']) - -bib_path = Bip44( - coin_type=CoinType.SHIMMER -) - -wallet_options = WalletOptions(None, None, bib_path, client_options, secret_manager, './backup-database') -wallet = Wallet(wallet_options) - -# Store the mnemonic in the Stronghold snapshot, this only needs to be -# done once. -wallet.store_mnemonic(os.environ['MNEMONIC']) - -wallet.backup("backup.stronghold", os.environ['STRONGHOLD_PASSWORD']) -print('Created backup') diff --git a/bindings/python/examples/wallet/create_alias.py b/bindings/python/examples/wallet/create_alias.py deleted file mode 100644 index e9d6c4ff34..0000000000 --- a/bindings/python/examples/wallet/create_alias.py +++ /dev/null @@ -1,23 +0,0 @@ -import os - -from dotenv import load_dotenv - -from iota_sdk import Wallet, WalletOptions - -load_dotenv() - -# In this example we will create an account output - -wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) - -# Sync account with the node -wallet.sync() - -if 'STRONGHOLD_PASSWORD' not in os.environ: - raise Exception(".env STRONGHOLD_PASSWORD is undefined, see .env.example") - -wallet.set_stronghold_password(os.environ["STRONGHOLD_PASSWORD"]) - -# Send transaction. -transaction = wallet.create_account_output(None, None) -print(f'Block sent: {os.environ["EXPLORER_URL"]}/block/{transaction.block_id}') diff --git a/bindings/python/examples/wallet/get_client.py b/bindings/python/examples/wallet/get_client.py deleted file mode 100644 index 7b95c00691..0000000000 --- a/bindings/python/examples/wallet/get_client.py +++ /dev/null @@ -1,16 +0,0 @@ -import os - -from dotenv import load_dotenv - -from iota_sdk import Wallet, WalletOptions - -load_dotenv() - -# This example gets a client from the wallet. - -wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) - -client = wallet.get_client() - -info = client.get_info() -print(f'{info}') diff --git a/bindings/python/examples/wallet/getting_started.py b/bindings/python/examples/wallet/getting_started.py deleted file mode 100644 index c22d0a2fee..0000000000 --- a/bindings/python/examples/wallet/getting_started.py +++ /dev/null @@ -1,50 +0,0 @@ -# Copyright 2023 IOTA Stiftung -# SPDX-License-Identifier: Apache-2.0 - -import os - -from dotenv import load_dotenv - -from iota_sdk import (ClientOptions, CoinType, StrongholdSecretManager, Utils, - Wallet, WalletOptions, Bip44, SecretManager) - -load_dotenv() - -# A name to associate with the created wallet. -ACCOUNT_ALIAS = 'Alice' - -# The node to connect to. -node_url = os.environ.get('NODE_URL', 'https://api.testnet.shimmer.network') - -# A password to encrypt the stored data. -# WARNING: Never hardcode passwords in production code. -STRONGHOLD_PASSWORD = os.environ.get( - 'STRONGHOLD_PASSWORD', 'a-secure-password') - -# The path to store the wallet snapshot. -STRONGHOLD_SNAPSHOT_PATH = 'vault.stronghold' - -# Setup Stronghold secret manager -secret_manager = StrongholdSecretManager( - STRONGHOLD_SNAPSHOT_PATH, STRONGHOLD_PASSWORD) - -# Generate a mnemonic and store its seed in the Stronghold vault. -# INFO: It is best practice to back up the mnemonic somewhere secure. -mnemonic = Utils.generate_mnemonic() -print(f'Mnemonic: {mnemonic}') - -SecretManager(secret_manager).store_mnemonic(mnemonic) - -# Set up and store the wallet. -client_options = ClientOptions(nodes=[node_url]) - -bib_path = Bip44( - coin_type=CoinType.SHIMMER -) -wallet_options = WalletOptions(None, None, bib_path, client_options, secret_manager) - -wallet = Wallet(wallet_options) - -# Get the first address and print it. -address = wallet.address() -print(f'Address:\n{address}') diff --git a/bindings/python/examples/wallet/logger.py b/bindings/python/examples/wallet/logger.py deleted file mode 100644 index 1b7d998094..0000000000 --- a/bindings/python/examples/wallet/logger.py +++ /dev/null @@ -1,44 +0,0 @@ -import json -import os - -from dotenv import load_dotenv - -# pylint: disable=no-name-in-module -from iota_sdk import (ClientOptions, CoinType, StrongholdSecretManager, Wallet, WalletOptions, Bip44, - init_logger) - -load_dotenv() - -# This example creates a new database and wallet and write debug logs in -# `wallet.log`. - -log_config = { - "name": './wallet.log', - "levelFilter": 'debug', - "targetExclusions": ["h2", "hyper", "rustls"] -} - -# Init the logger -init_logger(json.dumps(log_config)) - -node_url = os.environ.get('NODE_URL', 'https://api.testnet.shimmer.network') -client_options = ClientOptions(nodes=[node_url]) - -for env_var in ['STRONGHOLD_PASSWORD', 'MNEMONIC']: - if env_var not in os.environ: - raise Exception(f'.env {env_var} is undefined, see .env.example') - -secret_manager = StrongholdSecretManager( - "wallet.stronghold", - os.environ["STRONGHOLD_PASSWORD"]) - -bib_path = Bip44( - coin_type=CoinType.SHIMMER -) - -wallet_options = WalletOptions(None, None, bib_path, client_options, secret_manager, os.environ.get('WALLET_DB_PATH')) -wallet = Wallet(wallet_options) - -# Store the mnemonic in the Stronghold snapshot, this only needs to be -# done once. -wallet.store_mnemonic(os.environ["MNEMONIC"]) diff --git a/bindings/python/examples/wallet/migrate-stronghold-snapshot-v2-to-v3.py b/bindings/python/examples/wallet/migrate-stronghold-snapshot-v2-to-v3.py deleted file mode 100644 index 3b36d76374..0000000000 --- a/bindings/python/examples/wallet/migrate-stronghold-snapshot-v2-to-v3.py +++ /dev/null @@ -1,48 +0,0 @@ -import os - -from dotenv import load_dotenv - -# pylint: disable=no-name-in-module -from iota_sdk import (ClientOptions, CoinType, StrongholdSecretManager, Wallet, WalletOptions, Bip44, - migrate_stronghold_snapshot_v2_to_v3) - -load_dotenv() - -v2_path = "../../../sdk/tests/wallet/fixtures/v2.stronghold" -v3_path = "./v3.stronghold" -node_url = os.environ.get('NODE_URL', 'https://api.testnet.shimmer.network') -client_options = ClientOptions(nodes=[node_url]) -bib_path = Bip44( - coin_type=CoinType.SHIMMER -) - - -try: - secret_manager = StrongholdSecretManager(v2_path, "current_password") - # This should fail with error, migration required. - - wallet_options = WalletOptions( - None, - None, - bib_path, - client_options, - secret_manager, - os.environ.get('WALLET_DB_PATH')) - wallet = Wallet(wallet_options) -except ValueError as e: - print(e) - -migrate_stronghold_snapshot_v2_to_v3( - v2_path, - "current_password", - "wallet.rs", - 100, - v3_path, - "new_password") - -secret_manager = StrongholdSecretManager(v3_path, "new_password") - -wallet_options = WalletOptions(None, None, bib_path, client_options, secret_manager, os.environ.get('WALLET_DB_PATH')) - -# This shouldn't fail anymore as snapshot has been migrated. -wallet = Wallet(wallet_options) diff --git a/bindings/python/examples/wallet/offline_signing/0_generate_addresses.py b/bindings/python/examples/wallet/offline_signing/0_generate_addresses.py deleted file mode 100644 index 71cbfcfd11..0000000000 --- a/bindings/python/examples/wallet/offline_signing/0_generate_addresses.py +++ /dev/null @@ -1,49 +0,0 @@ -# Copyright 2023 IOTA Stiftung -# SPDX-License-Identifier: Apache-2.0 - -# In this example we create an account and store its addresses in a file which will be used later to find -# inputs. - -import json -import os - -from dotenv import load_dotenv - -from iota_sdk import ClientOptions, CoinType, StrongholdSecretManager, Wallet, WalletOptions, Bip44 - -load_dotenv() - -OFFLINE_WALLET_DB_PATH = "./wallet/offline_signing/example-offline-walletdb" -STRONGHOLD_SNAPSHOT_PATH = "./wallet/offline_signing/example.stronghold" -ADDRESSES_FILE_PATH = "./wallet/offline_signing/example.addresses.json" - - -node_url = os.environ.get('NODE_URL', 'https://api.testnet.shimmer.network') -offline_client_options = ClientOptions() - -for env_var in ['STRONGHOLD_PASSWORD', 'MNEMONIC']: - if env_var not in os.environ: - raise Exception(f'.env {env_var} is undefined, see .env.example') - -secret_manager = StrongholdSecretManager( - STRONGHOLD_SNAPSHOT_PATH, os.environ['STRONGHOLD_PASSWORD']) - -bib_path = Bip44( - coin_type=CoinType.SHIMMER -) - -wallet_options = WalletOptions(None, None, bib_path, offline_client_options, secret_manager, OFFLINE_WALLET_DB_PATH) -wallet = Wallet(wallet_options) - -# Store the mnemonic in the Stronghold snapshot, this only needs to be -# done once -wallet.store_mnemonic(os.environ['MNEMONIC']) - -# Get the address from the wallet -address = wallet.address() - -json_data = json.dumps(list(map(lambda x: x.__dict__, address)), indent=4) -print(f"example.addresses.json:\n{json_data}") -f = open(ADDRESSES_FILE_PATH, "w", encoding="utf-8") -f.write(json_data) -f.close() diff --git a/bindings/python/examples/wallet/offline_signing/1_prepare_transaction.py b/bindings/python/examples/wallet/offline_signing/1_prepare_transaction.py deleted file mode 100644 index 252fcbb3f6..0000000000 --- a/bindings/python/examples/wallet/offline_signing/1_prepare_transaction.py +++ /dev/null @@ -1,54 +0,0 @@ -# Copyright 2023 IOTA Stiftung -# SPDX-License-Identifier: Apache-2.0 - -# In this example we will get inputs and prepare a transaction. - -import json -import os - -from dacite import from_dict -from dotenv import load_dotenv - -from iota_sdk import (AccountAddress, ClientOptions, CoinType, SendParams, - Wallet, WalletOptions, Bip44) - -load_dotenv() - -ONLINE_WALLET_DB_PATH = "./wallet/offline_signing/example-online-walletdb" -ADDRESSES_FILE_PATH = "./wallet/offline_signing/example.addresses.json" -PREPARED_TRANSACTION_FILE_PATH = "./wallet/offline_signing/example.prepared_transaction.json" -# Address to which we want to send the amount. -RECV_ADDRESS = "rms1qpszqzadsym6wpppd6z037dvlejmjuke7s24hm95s9fg9vpua7vluaw60xu" -# The amount to send. -SEND_AMOUNT = 1_000_000 - - -params = [SendParams(address=RECV_ADDRESS, amount=SEND_AMOUNT)] - -# Recovers addresses from example `0_address_generation`. -addresses_data = json.load(open(ADDRESSES_FILE_PATH, "r", encoding="utf-8")) -addresses = list(map(lambda x: from_dict( - data_class=AccountAddress, data=x), addresses_data)) - -if 'NODE_URL' not in os.environ: - raise Exception(".env NODE_URL is undefined, see .env.example") - -client_options = ClientOptions(nodes=[os.environ.get('NODE_URL')]) - -bib_path = Bip44( - coin_type=CoinType.SHIMMER -) -wallet_options = WalletOptions(None, None, bib_path, client_options, "placeholder", ONLINE_WALLET_DB_PATH) -wallet = Wallet(wallet_options) - -wallet.sync() - -prepared_transaction = wallet.prepare_send(params) - -json_data = json.dumps( - prepared_transaction.prepared_transaction_data().to_dict(), - indent=4) -print(f"example.prepared_transaction.json:\n{json_data}") -f = open(PREPARED_TRANSACTION_FILE_PATH, "w", encoding="utf-8") -f.write(json_data) -f.close() diff --git a/bindings/python/examples/wallet/offline_signing/2_sign_transaction.py b/bindings/python/examples/wallet/offline_signing/2_sign_transaction.py deleted file mode 100644 index 1a30f5c14d..0000000000 --- a/bindings/python/examples/wallet/offline_signing/2_sign_transaction.py +++ /dev/null @@ -1,44 +0,0 @@ -# Copyright 2023 IOTA Stiftung -# SPDX-License-Identifier: Apache-2.0 - -# In this example we sign the prepared transaction. - -import json -import os - -from dacite import from_dict -from dotenv import load_dotenv - -from iota_sdk import PreparedTransactionData, Wallet, WalletOptions - -load_dotenv() - -OFFLINE_WALLET_DB_PATH = "./wallet/offline_signing/example-offline-walletdb" -STRONGHOLD_SNAPSHOT_PATH = "./wallet/offline_signing/example.stronghold" -PREPARED_TRANSACTION_FILE_PATH = "./wallet/offline_signing/example.prepared_transaction.json" -SIGNED_TRANSACTION_FILE_PATH = "./wallet/offline_signing/example.signed_transaction.json" - - -prepared_transaction_data = json.load( - open(PREPARED_TRANSACTION_FILE_PATH, "r", encoding="utf-8")) -prepared_transaction_data = from_dict( - PreparedTransactionData, prepared_transaction_data) - -wallet = Wallet(WalletOptions(storage_path=OFFLINE_WALLET_DB_PATH)) - -if 'STRONGHOLD_PASSWORD' not in os.environ: - raise Exception(".env STRONGHOLD_PASSWORD is undefined, see .env.example") - -wallet.set_stronghold_password(os.environ["STRONGHOLD_PASSWORD"]) - -# Signs prepared transaction offline. -signed_transaction_data = wallet.sign_transaction( - prepared_transaction_data) - -print("Signed transaction.") - -json_data = json.dumps(signed_transaction_data.to_dict(), indent=4) -print(f"example.signed_transaction.json:\n{json_data}") -f = open(SIGNED_TRANSACTION_FILE_PATH, "w", encoding="utf-8") -f.write(json_data) -f.close() diff --git a/bindings/python/examples/wallet/offline_signing/3_send_transaction.py b/bindings/python/examples/wallet/offline_signing/3_send_transaction.py deleted file mode 100644 index 4cba62f441..0000000000 --- a/bindings/python/examples/wallet/offline_signing/3_send_transaction.py +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright 2023 IOTA Stiftung -# SPDX-License-Identifier: Apache-2.0 - -# In this example we send the signed transaction in a block. - -import json -import os - -from dacite import from_dict -from dotenv import load_dotenv - -from iota_sdk import SignedTransactionData, Wallet, WalletOptions - -load_dotenv() - -ONLINE_WALLET_DB_PATH = "./wallet/offline_signing/example-online-walletdb" -SIGNED_TRANSACTION_FILE_PATH = "./wallet/offline_signing/example.signed_transaction.json" - -if 'EXPLORER_URL' not in os.environ: - raise Exception(".env EXPLORER_URL is undefined, see .env.example") - -wallet = Wallet(WalletOptions(storage_path=ONLINE_WALLET_DB_PATH)) - -signed_transaction_data = json.load( - open(SIGNED_TRANSACTION_FILE_PATH, "r", encoding="utf-8")) -signed_transaction_data = from_dict( - SignedTransactionData, signed_transaction_data) - -# Sends offline signed transaction online. -transaction = wallet.submit_and_store_transaction(signed_transaction_data) -print( - f'Transaction sent: {os.environ["EXPLORER_URL"]}/transaction/{transaction.transaction_id}') -block_id = wallet.reissue_transaction_until_included( - transaction.transaction_id) -print(f'Block included: {os.environ["EXPLORER_URL"]}/block/{block_id}') diff --git a/bindings/python/examples/wallet/restore_backup.py b/bindings/python/examples/wallet/restore_backup.py deleted file mode 100644 index 2439262fc7..0000000000 --- a/bindings/python/examples/wallet/restore_backup.py +++ /dev/null @@ -1,27 +0,0 @@ -import json -import os - -from dotenv import load_dotenv - -from iota_sdk import ClientOptions, CoinType, Wallet, WalletOptions, Bip44 - -load_dotenv() - -# This example restores the wallet from a stronghold. - -node_url = os.environ.get('NODE_URL', 'https://api.testnet.shimmer.network') -client_options = ClientOptions(nodes=[node_url]) - -bib_path = Bip44( - coin_type=CoinType.SHIMMER -) - -wallet_options = WalletOptions(None, None, bib_path, client_options, 'Placeholder', './restore-backup-database') -wallet = Wallet(wallet_options) - -if 'STRONGHOLD_PASSWORD' not in os.environ: - raise Exception(".env STRONGHOLD_PASSWORD is undefined, see .env.example") - -wallet.restore_backup("backup.stronghold", os.environ['STRONGHOLD_PASSWORD']) - -print(f'Restored wallet: {json.dumps(wallet, indent=4)}') diff --git a/bindings/python/examples/wallet/transaction_options.py b/bindings/python/examples/wallet/transaction_options.py deleted file mode 100644 index 8055406e3a..0000000000 --- a/bindings/python/examples/wallet/transaction_options.py +++ /dev/null @@ -1,36 +0,0 @@ -import os - -from dotenv import load_dotenv - -from iota_sdk import (RemainderValueStrategy, TaggedDataPayload, SendParams, - TransactionOptions, Wallet, WalletOptions, utf8_to_hex) - -load_dotenv() - -# This example sends a transaction with a tagged data payload. - -wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) - -# Sync account with the node -response = wallet.sync() - -if 'STRONGHOLD_PASSWORD' not in os.environ: - raise Exception(".env STRONGHOLD_PASSWORD is undefined, see .env.example") - -wallet.set_stronghold_password(os.environ["STRONGHOLD_PASSWORD"]) - -params = [SendParams( - address="rms1qpszqzadsym6wpppd6z037dvlejmjuke7s24hm95s9fg9vpua7vluaw60xu", - amount=1000000, -)] - -transaction = wallet.send_with_params( - params, - TransactionOptions( - remainder_value_strategy=RemainderValueStrategy.ReuseAddress, - note="my first tx", - tagged_data_payload=TaggedDataPayload( - utf8_to_hex("tag"), - utf8_to_hex("data")))) -print(transaction) -print(f'Block sent: {os.environ["EXPLORER_URL"]}/block/{transaction.block_id}') diff --git a/sdk/examples/how_tos/account/implicit_account_creation.rs b/sdk/examples/how_tos/account/implicit_account_creation.rs index 9f565da0b8..eada8b3bfb 100644 --- a/sdk/examples/how_tos/account/implicit_account_creation.rs +++ b/sdk/examples/how_tos/account/implicit_account_creation.rs @@ -19,6 +19,11 @@ async fn main() -> Result<()> { //  This example uses secrets in environment variables for simplicity which should not be done in production. dotenvy::dotenv().ok(); + #[allow(clippy::single_element_loop)] + for var in ["MNEMONIC"] { + std::env::var(var).unwrap_or_else(|_| panic!(".env variable '{var}' is undefined, see .env.example")); + } + let secret_manager = SecretManager::try_from_mnemonic(std::env::var("MNEMONIC").unwrap())?; let client_options = ClientOptions::new().with_node("https://api.testnet.shimmer.network")?; @@ -32,7 +37,7 @@ async fn main() -> Result<()> { let implicit_account_creation_address = wallet.implicit_account_creation_address().await?; - println!("{implicit_account_creation_address}"); + println!("Fund the following address: {implicit_account_creation_address}"); Ok(()) } From dd13c190941f05b48a242411bf8f8d42cede7d3c Mon Sep 17 00:00:00 2001 From: Brord van Wierst Date: Fri, 8 Dec 2023 18:17:11 +0100 Subject: [PATCH 09/34] update comment --- .../how_tos/account_output/implicit_account_creation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bindings/python/examples/how_tos/account_output/implicit_account_creation.py b/bindings/python/examples/how_tos/account_output/implicit_account_creation.py index 96f21f2b10..d6c5400509 100644 --- a/bindings/python/examples/how_tos/account_output/implicit_account_creation.py +++ b/bindings/python/examples/how_tos/account_output/implicit_account_creation.py @@ -13,6 +13,6 @@ wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) -# Sync account with the node +# Get the implicit account address address = wallet.implicit_account_creation_address() print(f'Fund the following address: {address}') From f754ffc56998e555cab6a8b29e1b4a8ba60bccb7 Mon Sep 17 00:00:00 2001 From: Brord van Wierst Date: Fri, 8 Dec 2023 18:31:39 +0100 Subject: [PATCH 10/34] lint --- bindings/python/examples/how_tos/account_output/create.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bindings/python/examples/how_tos/account_output/create.py b/bindings/python/examples/how_tos/account_output/create.py index 3c9ab4b3c5..bf04e728ba 100644 --- a/bindings/python/examples/how_tos/account_output/create.py +++ b/bindings/python/examples/how_tos/account_output/create.py @@ -16,7 +16,7 @@ # Sync account with the node balance = wallet.sync() -print( f'Accounts BEFORE: {balance.accounts}') +print(f'Accounts BEFORE: {balance.accounts}') wallet.set_stronghold_password(os.environ["STRONGHOLD_PASSWORD"]) @@ -29,4 +29,4 @@ time.sleep(10) balance = wallet.sync() -print( f'Accounts AFTER: {balance.accounts}') +print(f'Accounts AFTER: {balance.accounts}') From bb97a040e0000f104ac2d4343f34cb59c17e858a Mon Sep 17 00:00:00 2001 From: Brord van Wierst Date: Mon, 11 Dec 2023 13:20:40 +0100 Subject: [PATCH 11/34] added missing prot params --- bindings/python/iota_sdk/types/node_info.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/bindings/python/iota_sdk/types/node_info.py b/bindings/python/iota_sdk/types/node_info.py index 8c8bfecf8e..8395afc8fe 100644 --- a/bindings/python/iota_sdk/types/node_info.py +++ b/bindings/python/iota_sdk/types/node_info.py @@ -185,6 +185,7 @@ class ManaParameters: decay_factors_exponent: The scaling of decay_factors expressed as an exponent of 2. decay_factor_epochs_sum: An integer approximation of the sum of decay over epochs. decay_factor_epochs_sum_exponent: The scaling of decay_factor_epochs_sum expressed as an exponent of 2. + annual_decay_factor_percentage: Decay factor for 1 year. """ bits_count: int generation_rate: int @@ -193,6 +194,7 @@ class ManaParameters: decay_factors_exponent: int decay_factor_epochs_sum: int decay_factor_epochs_sum_exponent: int + annual_decay_factor_percentage: int @json @@ -252,6 +254,7 @@ class ProtocolParameters: version_signaling_parameters: The version signaling parameters. rewards_parameters: Rewards Parameters defines the parameters that are used to calculate Mana rewards. target_committee_size: Defines the target size of the committee. If there's fewer candidates the actual committee size could be smaller in a given epoch. + chain_switching_threshold: Defines the number of heavier slots that a chain needs to be ahead of the current chain to be considered for switching. """ type: int version: int @@ -281,6 +284,7 @@ class ProtocolParameters: version_signaling_parameters: VersionSignalingParameters rewards_parameters: RewardsParameters target_committee_size: int + chain_switching_threshold: int @json From fc8f1f52cf45e836882f144dc4d32a5df091f2d1 Mon Sep 17 00:00:00 2001 From: Brord van Wierst Date: Mon, 11 Dec 2023 13:46:17 +0100 Subject: [PATCH 12/34] lint.... --- bindings/python/examples/how_tos/account_output/create.py | 5 +++-- bindings/python/examples/how_tos/account_output/destroy.py | 4 ++-- .../how_tos/account_output/implicit_account_creation.py | 4 ++-- .../python/examples/how_tos/account_wallet/transaction.py | 7 ++++--- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/bindings/python/examples/how_tos/account_output/create.py b/bindings/python/examples/how_tos/account_output/create.py index bf04e728ba..e077c67a61 100644 --- a/bindings/python/examples/how_tos/account_output/create.py +++ b/bindings/python/examples/how_tos/account_output/create.py @@ -1,17 +1,18 @@ import os +import time from dotenv import load_dotenv from iota_sdk import Wallet, WalletOptions +# In this example we will create an account output + load_dotenv() for env_var in ['WALLET_DB_PATH', 'STRONGHOLD_PASSWORD', 'EXPLORER_URL']: if env_var not in os.environ: raise Exception(f".env {env_var} is undefined, see .env.example") -# In this example we will create an account output - wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) # Sync account with the node diff --git a/bindings/python/examples/how_tos/account_output/destroy.py b/bindings/python/examples/how_tos/account_output/destroy.py index 928f860779..e90c55e33f 100644 --- a/bindings/python/examples/how_tos/account_output/destroy.py +++ b/bindings/python/examples/how_tos/account_output/destroy.py @@ -4,14 +4,14 @@ from iota_sdk import Wallet, WalletOptions +# In this example we will destroy an account output + load_dotenv() for env_var in ['WALLET_DB_PATH', 'STRONGHOLD_PASSWORD', 'EXPLORER_URL']: if env_var not in os.environ: raise Exception(f".env {env_var} is undefined, see .env.example") -# In this example we will destroy an account output - wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) # Sync account with the node diff --git a/bindings/python/examples/how_tos/account_output/implicit_account_creation.py b/bindings/python/examples/how_tos/account_output/implicit_account_creation.py index d6c5400509..82a7fe098c 100644 --- a/bindings/python/examples/how_tos/account_output/implicit_account_creation.py +++ b/bindings/python/examples/how_tos/account_output/implicit_account_creation.py @@ -4,13 +4,13 @@ from iota_sdk import Wallet, WalletOptions +# In this example, we create an implicit account creation address. + load_dotenv() if 'WALLET_DB_PATH' not in os.environ: raise Exception(".env WALLET_DB_PATH is undefined, see .env.example") -# In this example, we create an implicit account creation address. - wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) # Get the implicit account address diff --git a/bindings/python/examples/how_tos/account_wallet/transaction.py b/bindings/python/examples/how_tos/account_wallet/transaction.py index 00f6f628ae..7c6320295e 100644 --- a/bindings/python/examples/how_tos/account_wallet/transaction.py +++ b/bindings/python/examples/how_tos/account_wallet/transaction.py @@ -8,13 +8,14 @@ load_dotenv() +for env_var in ['WALLET_DB_PATH', 'STRONGHOLD_PASSWORD']: + if env_var not in os.environ: + raise Exception(f".env {env_var} is undefined, see .env.example") + sync_options = SyncOptions(account=WalletSyncOptions(basic_outputs=True)) wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) -if 'STRONGHOLD_PASSWORD' not in os.environ: - raise Exception(".env STRONGHOLD_PASSWORD is undefined, see .env.example") - wallet.set_stronghold_password(os.environ["STRONGHOLD_PASSWORD"]) balance = wallet.sync(sync_options) From 60aa91fec2efce6e33503af2e046e6ec42513158 Mon Sep 17 00:00:00 2001 From: Brord van Wierst Date: Mon, 11 Dec 2023 16:04:21 +0100 Subject: [PATCH 13/34] removed some account references --- bindings/python/examples/exchange/1_create_account.py | 10 +++++----- .../python/examples/exchange/2_generate_address.py | 4 +--- bindings/python/examples/exchange/3_check_balance.py | 2 +- .../python/examples/how_tos/account_output/create.py | 2 +- .../python/examples/how_tos/account_output/destroy.py | 2 +- .../examples/how_tos/account_wallet/transaction.py | 3 +-- .../how_tos/accounts_and_addresses/check_balance.py | 2 +- .../accounts_and_addresses/consolidate_outputs.py | 2 +- .../advanced_transactions/advanced_transaction.py | 2 +- .../how_tos/advanced_transactions/claim_transaction.py | 2 +- .../advanced_transactions/send_micro_transaction.py | 2 +- bindings/python/examples/how_tos/native_tokens/burn.py | 2 +- .../python/examples/how_tos/native_tokens/create.py | 2 +- .../examples/how_tos/native_tokens/destroy_foundry.py | 2 +- bindings/python/examples/how_tos/native_tokens/melt.py | 2 +- bindings/python/examples/how_tos/native_tokens/mint.py | 2 +- bindings/python/examples/how_tos/native_tokens/send.py | 2 +- .../how_tos/nft_collection/00_mint_issuer_nft.py | 2 +- .../how_tos/nft_collection/01_mint_collection_nft.py | 2 +- bindings/python/examples/how_tos/nfts/burn_nft.py | 2 +- bindings/python/examples/how_tos/nfts/mint_nft.py | 2 +- bindings/python/examples/how_tos/nfts/send_nft.py | 2 +- .../how_tos/simple_transaction/simple_transaction.py | 2 +- bindings/python/iota_sdk/wallet/wallet.py | 2 +- 24 files changed, 28 insertions(+), 31 deletions(-) diff --git a/bindings/python/examples/exchange/1_create_account.py b/bindings/python/examples/exchange/1_create_account.py index 4b8a7790aa..a76d8201c0 100644 --- a/bindings/python/examples/exchange/1_create_account.py +++ b/bindings/python/examples/exchange/1_create_account.py @@ -8,7 +8,7 @@ from dotenv import load_dotenv from iota_sdk import (ClientOptions, CoinType, StrongholdSecretManager, - SyncOptions, Wallet, WalletOptions, Bip44) + SecretManager, SyncOptions, Wallet, WalletOptions, Bip44) # This example uses secrets in environment variables for simplicity which # should not be done in production. @@ -24,16 +24,16 @@ secret_manager = StrongholdSecretManager( os.environ.get('STRONGHOLD_SNAPSHOT_PATH'), os.environ['STRONGHOLD_PASSWORD']) +# Store the mnemonic in the Stronghold snapshot, this only needs to be +# done once. +SecretManager(secret_manager).store_mnemonic(os.environ['MNEMONIC']) + bib_path = Bip44( coin_type=CoinType.SHIMMER ) wallet_options = WalletOptions(None, None, bib_path, client_options, secret_manager, os.environ.get('WALLET_DB_PATH')) wallet = Wallet(wallet_options) -# Store the mnemonic in the Stronghold snapshot, this only needs to be -# done once. -wallet.store_mnemonic(os.environ['MNEMONIC']) - # Set sync_only_most_basic_outputs to True if not interested in outputs that are timelocked, # have a storage deposit return, expiration or are nft/account/foundry outputs. wallet.set_default_sync_options( diff --git a/bindings/python/examples/exchange/2_generate_address.py b/bindings/python/examples/exchange/2_generate_address.py index 0fd365e798..3abe078726 100644 --- a/bindings/python/examples/exchange/2_generate_address.py +++ b/bindings/python/examples/exchange/2_generate_address.py @@ -17,10 +17,8 @@ if env_var not in os.environ: raise Exception(f'.env {env_var} is undefined, see .env.example') -client_options = ClientOptions(nodes=[os.environ.get('NODE_URL')]) - secret_manager = SecretManager(StrongholdSecretManager( os.environ.get('STRONGHOLD_SNAPSHOT_PATH'), os.environ['STRONGHOLD_PASSWORD'])) address = secret_manager.generate_ed25519_addresses(1)[0] -print('Address:', address.address) +print('Address:', address) diff --git a/bindings/python/examples/exchange/3_check_balance.py b/bindings/python/examples/exchange/3_check_balance.py index b0a836dea7..c8c6b4d0c2 100644 --- a/bindings/python/examples/exchange/3_check_balance.py +++ b/bindings/python/examples/exchange/3_check_balance.py @@ -19,7 +19,7 @@ wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) address = wallet.address() -print('address:', address) +print('Address:', address) # Set sync_only_most_basic_outputs to True if not interested in outputs that are timelocked, # have a storage deposit return, expiration or are nft/account/foundry outputs. diff --git a/bindings/python/examples/how_tos/account_output/create.py b/bindings/python/examples/how_tos/account_output/create.py index e077c67a61..709396a468 100644 --- a/bindings/python/examples/how_tos/account_output/create.py +++ b/bindings/python/examples/how_tos/account_output/create.py @@ -15,7 +15,7 @@ wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) -# Sync account with the node +# Sync wallet with the node balance = wallet.sync() print(f'Accounts BEFORE: {balance.accounts}') diff --git a/bindings/python/examples/how_tos/account_output/destroy.py b/bindings/python/examples/how_tos/account_output/destroy.py index e90c55e33f..c322e40263 100644 --- a/bindings/python/examples/how_tos/account_output/destroy.py +++ b/bindings/python/examples/how_tos/account_output/destroy.py @@ -14,7 +14,7 @@ wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) -# Sync account with the node +# Sync wallet with the node balance = wallet.sync() # We try to destroy the first account in the account diff --git a/bindings/python/examples/how_tos/account_wallet/transaction.py b/bindings/python/examples/how_tos/account_wallet/transaction.py index 7c6320295e..89f4239586 100644 --- a/bindings/python/examples/how_tos/account_wallet/transaction.py +++ b/bindings/python/examples/how_tos/account_wallet/transaction.py @@ -12,12 +12,11 @@ if env_var not in os.environ: raise Exception(f".env {env_var} is undefined, see .env.example") -sync_options = SyncOptions(account=WalletSyncOptions(basic_outputs=True)) - wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) wallet.set_stronghold_password(os.environ["STRONGHOLD_PASSWORD"]) +sync_options = SyncOptions(account=WalletSyncOptions(basic_outputs=True)) balance = wallet.sync(sync_options) total_base_token_balance = balance.base_coin.total diff --git a/bindings/python/examples/how_tos/accounts_and_addresses/check_balance.py b/bindings/python/examples/how_tos/accounts_and_addresses/check_balance.py index 27160b5ce0..4c85509ddc 100644 --- a/bindings/python/examples/how_tos/accounts_and_addresses/check_balance.py +++ b/bindings/python/examples/how_tos/accounts_and_addresses/check_balance.py @@ -13,7 +13,7 @@ wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) -# Sync account with the node +# Sync wallet with the node _balance = wallet.sync() # Just calculate the balance with the known state diff --git a/bindings/python/examples/how_tos/accounts_and_addresses/consolidate_outputs.py b/bindings/python/examples/how_tos/accounts_and_addresses/consolidate_outputs.py index 8d26f90f17..940e6f8c12 100644 --- a/bindings/python/examples/how_tos/accounts_and_addresses/consolidate_outputs.py +++ b/bindings/python/examples/how_tos/accounts_and_addresses/consolidate_outputs.py @@ -17,7 +17,7 @@ wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) wallet.set_stronghold_password(os.environ['STRONGHOLD_PASSWORD']) -# Sync account to make sure account is updated with outputs from previous +# Sync wallet to make sure account is updated with outputs from previous # examples. wallet.sync() print('Account synced') diff --git a/bindings/python/examples/how_tos/advanced_transactions/advanced_transaction.py b/bindings/python/examples/how_tos/advanced_transactions/advanced_transaction.py index 9fd27e4e25..309cbac125 100644 --- a/bindings/python/examples/how_tos/advanced_transactions/advanced_transaction.py +++ b/bindings/python/examples/how_tos/advanced_transactions/advanced_transaction.py @@ -21,7 +21,7 @@ wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) -# Sync account with the node +# Sync wallet with the node response = wallet.sync() if 'STRONGHOLD_PASSWORD' not in os.environ: diff --git a/bindings/python/examples/how_tos/advanced_transactions/claim_transaction.py b/bindings/python/examples/how_tos/advanced_transactions/claim_transaction.py index 0ebca3b8c6..fe252f762d 100644 --- a/bindings/python/examples/how_tos/advanced_transactions/claim_transaction.py +++ b/bindings/python/examples/how_tos/advanced_transactions/claim_transaction.py @@ -16,7 +16,7 @@ wallet.set_stronghold_password(os.environ["STRONGHOLD_PASSWORD"]) -# Sync account with the node +# Sync wallet with the node response = wallet.sync() # Only the unspent outputs in the account diff --git a/bindings/python/examples/how_tos/advanced_transactions/send_micro_transaction.py b/bindings/python/examples/how_tos/advanced_transactions/send_micro_transaction.py index 4868f2d9ac..f95aa8cde9 100644 --- a/bindings/python/examples/how_tos/advanced_transactions/send_micro_transaction.py +++ b/bindings/python/examples/how_tos/advanced_transactions/send_micro_transaction.py @@ -10,7 +10,7 @@ wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) -# Sync account with the node +# Sync wallet with the node response = wallet.sync() if 'STRONGHOLD_PASSWORD' not in os.environ: diff --git a/bindings/python/examples/how_tos/native_tokens/burn.py b/bindings/python/examples/how_tos/native_tokens/burn.py index 48d6efac81..7ad18ceb4e 100644 --- a/bindings/python/examples/how_tos/native_tokens/burn.py +++ b/bindings/python/examples/how_tos/native_tokens/burn.py @@ -8,7 +8,7 @@ wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) -# Sync account with the node +# Sync wallet with the node balance = wallet.sync() if 'STRONGHOLD_PASSWORD' not in os.environ: diff --git a/bindings/python/examples/how_tos/native_tokens/create.py b/bindings/python/examples/how_tos/native_tokens/create.py index 16f8bf8752..883f07926e 100644 --- a/bindings/python/examples/how_tos/native_tokens/create.py +++ b/bindings/python/examples/how_tos/native_tokens/create.py @@ -15,7 +15,7 @@ wallet.set_stronghold_password(os.environ["STRONGHOLD_PASSWORD"]) -# Sync account with the node +# Sync wallet with the node balance = wallet.sync() # We can first check if we already have an account output in our account, because diff --git a/bindings/python/examples/how_tos/native_tokens/destroy_foundry.py b/bindings/python/examples/how_tos/native_tokens/destroy_foundry.py index b8aefd2a83..8682b1dad7 100644 --- a/bindings/python/examples/how_tos/native_tokens/destroy_foundry.py +++ b/bindings/python/examples/how_tos/native_tokens/destroy_foundry.py @@ -8,7 +8,7 @@ wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) -# Sync account with the node +# Sync wallet with the node balance = wallet.sync() print(f'Foundries before destroying: {len(balance.foundries)}') diff --git a/bindings/python/examples/how_tos/native_tokens/melt.py b/bindings/python/examples/how_tos/native_tokens/melt.py index 83526cbb40..dd66fd965d 100644 --- a/bindings/python/examples/how_tos/native_tokens/melt.py +++ b/bindings/python/examples/how_tos/native_tokens/melt.py @@ -10,7 +10,7 @@ wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) -# Sync account with the node +# Sync wallet with the node balance = wallet.sync() # Find first foundry and corresponding token id diff --git a/bindings/python/examples/how_tos/native_tokens/mint.py b/bindings/python/examples/how_tos/native_tokens/mint.py index 564e68aea1..517eab633a 100644 --- a/bindings/python/examples/how_tos/native_tokens/mint.py +++ b/bindings/python/examples/how_tos/native_tokens/mint.py @@ -10,7 +10,7 @@ wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) -# Sync account with the node +# Sync wallet with the node balance = wallet.sync() # Find first foundry and corresponding token id diff --git a/bindings/python/examples/how_tos/native_tokens/send.py b/bindings/python/examples/how_tos/native_tokens/send.py index 1e2e8e45db..d960dd1191 100644 --- a/bindings/python/examples/how_tos/native_tokens/send.py +++ b/bindings/python/examples/how_tos/native_tokens/send.py @@ -10,7 +10,7 @@ wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) -# Sync account with the node +# Sync wallet with the node balance = wallet.sync() token = [native_balance for native_balance in balance.native_tokens if int( diff --git a/bindings/python/examples/how_tos/nft_collection/00_mint_issuer_nft.py b/bindings/python/examples/how_tos/nft_collection/00_mint_issuer_nft.py index 3a4ce4fc8e..0aadd23767 100644 --- a/bindings/python/examples/how_tos/nft_collection/00_mint_issuer_nft.py +++ b/bindings/python/examples/how_tos/nft_collection/00_mint_issuer_nft.py @@ -15,7 +15,7 @@ wallet.set_stronghold_password(os.environ["STRONGHOLD_PASSWORD"]) -# Sync account with the node +# Sync wallet with the node wallet.sync() # Issue the minting transaction and wait for its inclusion diff --git a/bindings/python/examples/how_tos/nft_collection/01_mint_collection_nft.py b/bindings/python/examples/how_tos/nft_collection/01_mint_collection_nft.py index ef097ff96d..25003d6b41 100644 --- a/bindings/python/examples/how_tos/nft_collection/01_mint_collection_nft.py +++ b/bindings/python/examples/how_tos/nft_collection/01_mint_collection_nft.py @@ -26,7 +26,7 @@ wallet.set_stronghold_password(os.environ["STRONGHOLD_PASSWORD"]) -# Sync account with the node +# Sync wallet with the node wallet.sync() bech32_hrp = wallet.get_client().get_bech32_hrp() diff --git a/bindings/python/examples/how_tos/nfts/burn_nft.py b/bindings/python/examples/how_tos/nfts/burn_nft.py index 53730cd112..aa51158a18 100644 --- a/bindings/python/examples/how_tos/nfts/burn_nft.py +++ b/bindings/python/examples/how_tos/nfts/burn_nft.py @@ -14,7 +14,7 @@ wallet.set_stronghold_password(os.environ["STRONGHOLD_PASSWORD"]) -# Sync account with the node +# Sync wallet with the node balance = wallet.sync() nftId = balance.nfts[0] diff --git a/bindings/python/examples/how_tos/nfts/mint_nft.py b/bindings/python/examples/how_tos/nfts/mint_nft.py index 8c84c2149b..adee0a54bd 100644 --- a/bindings/python/examples/how_tos/nfts/mint_nft.py +++ b/bindings/python/examples/how_tos/nfts/mint_nft.py @@ -15,7 +15,7 @@ wallet.set_stronghold_password(os.environ["STRONGHOLD_PASSWORD"]) -# Sync account with the node +# Sync wallet with the node response = wallet.sync() outputs = [MintNftParams( diff --git a/bindings/python/examples/how_tos/nfts/send_nft.py b/bindings/python/examples/how_tos/nfts/send_nft.py index b67c801d2a..9908e5ca6a 100644 --- a/bindings/python/examples/how_tos/nfts/send_nft.py +++ b/bindings/python/examples/how_tos/nfts/send_nft.py @@ -15,7 +15,7 @@ wallet.set_stronghold_password(os.environ["STRONGHOLD_PASSWORD"]) -# Sync account with the node +# Sync wallet with the node balance = wallet.sync() outputs = [SendNftParams( diff --git a/bindings/python/examples/how_tos/simple_transaction/simple_transaction.py b/bindings/python/examples/how_tos/simple_transaction/simple_transaction.py index 9c59b57a57..3e8492db02 100644 --- a/bindings/python/examples/how_tos/simple_transaction/simple_transaction.py +++ b/bindings/python/examples/how_tos/simple_transaction/simple_transaction.py @@ -10,7 +10,7 @@ wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) -# Sync account with the node +# Sync wallet with the node response = wallet.sync() if 'STRONGHOLD_PASSWORD' not in os.environ: diff --git a/bindings/python/iota_sdk/wallet/wallet.py b/bindings/python/iota_sdk/wallet/wallet.py index 69f72dbff3..af776926b4 100644 --- a/bindings/python/iota_sdk/wallet/wallet.py +++ b/bindings/python/iota_sdk/wallet/wallet.py @@ -737,7 +737,7 @@ def sign_transaction( def sign_and_submit_transaction( self, prepared_transaction_data: PreparedTransactionData) -> TransactionWithMetadata: - """Validate the transaction, sign it, submit it to a node and store it in the account. + """Validate the transaction, sign it, submit it to a node and store it in the wallet. """ return TransactionWithMetadata.from_dict(self._call_method( 'signAndSubmitTransaction', { From 78e022b5a4ce620d1b7a5712d610d568261faf64 Mon Sep 17 00:00:00 2001 From: Brord van Wierst Date: Mon, 11 Dec 2023 16:46:54 +0100 Subject: [PATCH 14/34] fmt again --- bindings/python/examples/exchange/2_generate_address.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bindings/python/examples/exchange/2_generate_address.py b/bindings/python/examples/exchange/2_generate_address.py index 3abe078726..4a329a0d52 100644 --- a/bindings/python/examples/exchange/2_generate_address.py +++ b/bindings/python/examples/exchange/2_generate_address.py @@ -7,7 +7,7 @@ from dotenv import load_dotenv -from iota_sdk import ClientOptions, StrongholdSecretManager, SecretManager +from iota_sdk import StrongholdSecretManager, SecretManager # This example uses secrets in environment variables for simplicity which # should not be done in production. From 6bacf198a0afe52bbc45edc7290331b38967eb80 Mon Sep 17 00:00:00 2001 From: Brord van Wierst Date: Mon, 11 Dec 2023 17:37:34 +0100 Subject: [PATCH 15/34] added protocol params to sign --- bindings/python/iota_sdk/secret_manager/secret_manager.py | 7 +++++-- bindings/python/iota_sdk/types/balance.py | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/bindings/python/iota_sdk/secret_manager/secret_manager.py b/bindings/python/iota_sdk/secret_manager/secret_manager.py index 54eced05ad..6ba6d35e3c 100644 --- a/bindings/python/iota_sdk/secret_manager/secret_manager.py +++ b/bindings/python/iota_sdk/secret_manager/secret_manager.py @@ -8,6 +8,7 @@ from iota_sdk.external import create_secret_manager, call_secret_manager_method from iota_sdk.types.block.signed_block import SignedBlock, UnsignedBlock from iota_sdk.types.common import HexStr +from iota_sdk.types.node_info import ProtocolParameters from iota_sdk.types.signature import Ed25519Signature, Bip44 from iota_sdk.types.transaction_data import PreparedTransactionData from iota_sdk.types.payload import SignedTransactionPayload @@ -268,14 +269,16 @@ def sign_secp256k1_ecdsa(self, message: HexStr, chain: Bip44): }) def sign_transaction( - self, prepared_transaction_data: PreparedTransactionData) -> SignedTransactionPayload: + self, prepared_transaction_data: PreparedTransactionData, protocol_parameters: ProtocolParameters) -> SignedTransactionPayload: """Sign a transaction. Args: prepare_transaction_data: The prepared transaction data that needs to be signed. + protocol_parameters: The protocol parameters used in creating the signed transaction. """ return SignedTransactionPayload.from_dict(self._call_method('signTransaction', { - 'preparedTransactionData': prepared_transaction_data.to_dict() + 'preparedTransactionData': prepared_transaction_data.to_dict(), + 'protocolParameters': protocol_parameters })) def sign_block( diff --git a/bindings/python/iota_sdk/types/balance.py b/bindings/python/iota_sdk/types/balance.py index 27785e4155..c13f0f1466 100644 --- a/bindings/python/iota_sdk/types/balance.py +++ b/bindings/python/iota_sdk/types/balance.py @@ -28,7 +28,7 @@ class BaseCoinBalance: @json @dataclass class RequiredStorageDeposit: - """Required storage deposit for the outputs in the account. + """Required storage deposit for the outputs in the wallet. Attributes: basic: The required amount for basic outputs. From 3eac44d7aaed13bfdc42bb543debb2a32acd6e36 Mon Sep 17 00:00:00 2001 From: Brord van Wierst Date: Tue, 12 Dec 2023 16:25:21 +0100 Subject: [PATCH 16/34] fix, maybe lint? --- bindings/python/iota_sdk/types/unlock.py | 1 + bindings/python/iota_sdk/utils.py | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/bindings/python/iota_sdk/types/unlock.py b/bindings/python/iota_sdk/types/unlock.py index 47ac3f8716..3d5a9d7060 100644 --- a/bindings/python/iota_sdk/types/unlock.py +++ b/bindings/python/iota_sdk/types/unlock.py @@ -91,6 +91,7 @@ class NftUnlock: # pylint: disable=missing-function-docstring,unused-argument def deserialize_unlocks(dicts: List[Dict[str, Any]]) -> List[Unlock]: + # Function gets overwritten further below, but needs to be defined here already pass diff --git a/bindings/python/iota_sdk/utils.py b/bindings/python/iota_sdk/utils.py index a09663df1b..bdc0919985 100644 --- a/bindings/python/iota_sdk/utils.py +++ b/bindings/python/iota_sdk/utils.py @@ -218,13 +218,14 @@ def verify_secp256k1_ecdsa_signature( @staticmethod def verify_transaction_semantic( - transaction: Transaction, inputs: List[InputSigningData], unlocks: Optional[List[Unlock]] = None) -> str: + transaction: Transaction, inputs: List[InputSigningData], protocol_parameters: ProtocolParameters, unlocks: Optional[List[Unlock]] = None) -> str: """Verifies the semantic of a transaction. """ return _call_method('verifyTransactionSemantic', { 'transaction': transaction.as_dict(), 'inputs': [i.as_dict() for i in inputs], 'unlocks': [u.as_dict() for u in unlocks], + 'protocol_parameters': protocol_parameters.as_dict(), }) From df02aad6e7218cc9208dcb74dcb3688a54b7519d Mon Sep 17 00:00:00 2001 From: Brord van Wierst Date: Tue, 12 Dec 2023 17:10:17 +0100 Subject: [PATCH 17/34] rename fix --- bindings/python/tests/test_block.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bindings/python/tests/test_block.py b/bindings/python/tests/test_block.py index b1d10b0af8..ea99fabf9c 100644 --- a/bindings/python/tests/test_block.py +++ b/bindings/python/tests/test_block.py @@ -38,7 +38,7 @@ def test_block_with_tagged_data_payload(): "slotCommitmentId": "0x498bf08a5ed287bc87340341ffab28706768cd3a7035ae5e33932d9a12bb30940000000000000000", "latestFinalizedSlot": 21, "issuerId": "0x3370746f30705b7d0b42597459714d45241e5a64761b09627c447b751c7e145c", - "block": { + "body": { "type": 0, "strongParents": [ "0x304442486c7a05361408585e4b5f7a67441c437528755a70041e0e557a6d4b2d7d4362083d492b57", From dff9e398df7221dfcc0ded730aebe19380c071b6 Mon Sep 17 00:00:00 2001 From: Brord van Wierst Date: Tue, 12 Dec 2023 18:40:07 +0100 Subject: [PATCH 18/34] review --- .../examples/how_tos/account_wallet/request_funds.py | 6 +++--- bindings/python/iota_sdk/utils.py | 2 +- bindings/python/iota_sdk/wallet/wallet.py | 2 +- bindings/python/tests/test_offline.py | 3 --- bindings/python/tests/test_wallet_destroy.py | 8 ++++---- 5 files changed, 9 insertions(+), 12 deletions(-) diff --git a/bindings/python/examples/how_tos/account_wallet/request_funds.py b/bindings/python/examples/how_tos/account_wallet/request_funds.py index 779134627a..1f6a1429dc 100644 --- a/bindings/python/examples/how_tos/account_wallet/request_funds.py +++ b/bindings/python/examples/how_tos/account_wallet/request_funds.py @@ -5,7 +5,7 @@ from iota_sdk import Wallet, WalletOptions, Utils, SyncOptions, WalletSyncOptions -# In this example we request funds to a wallet. +# In this example we request funds to an account wallet. load_dotenv() @@ -22,7 +22,7 @@ total_base_token_balance = balance.base_coin.total print( - f'Balance before requesting funds on wallet address: {total_base_token_balance}') + f'Balance before requesting funds on account address: {total_base_token_balance}') account_id = balance.accounts[0] print(f'Account Id: {account_id}') @@ -40,4 +40,4 @@ total_base_token_balance = wallet.sync(sync_options).base_coin.total print( - f'Balance after requesting funds on wallet address: {total_base_token_balance}') + f'Balance after requesting funds on account address: {total_base_token_balance}') diff --git a/bindings/python/iota_sdk/utils.py b/bindings/python/iota_sdk/utils.py index 33deaa4714..e6fc16c330 100644 --- a/bindings/python/iota_sdk/utils.py +++ b/bindings/python/iota_sdk/utils.py @@ -225,7 +225,7 @@ def verify_transaction_semantic( 'transaction': transaction.as_dict(), 'inputs': [i.as_dict() for i in inputs], 'unlocks': [u.as_dict() for u in unlocks], - 'protocol_parameters': protocol_parameters.as_dict(), + 'protocolParameters': protocol_parameters.as_dict(), }) diff --git a/bindings/python/iota_sdk/wallet/wallet.py b/bindings/python/iota_sdk/wallet/wallet.py index af776926b4..414077c9de 100644 --- a/bindings/python/iota_sdk/wallet/wallet.py +++ b/bindings/python/iota_sdk/wallet/wallet.py @@ -112,7 +112,7 @@ def destroy(self): return destroy_wallet(self.handle) def emit_test_event(self, event) -> bool: - """Return whether a Stronghold password is available. + """Helper function to test events. """ return self._call_method( 'emitTestEvent', { diff --git a/bindings/python/tests/test_offline.py b/bindings/python/tests/test_offline.py index 0165610024..a23d91ec40 100644 --- a/bindings/python/tests/test_offline.py +++ b/bindings/python/tests/test_offline.py @@ -37,7 +37,6 @@ def test_sign_verify_ed25519(): "acoustic trophy damage hint search taste love bicycle foster cradle brown govern endless depend situate athlete pudding blame question genius transfer van random vast") message = utf8_to_hex('IOTA') - # IOTA coin type bib_path = Bip44( coin_type=CoinType.IOTA ) @@ -49,8 +48,6 @@ def test_sign_verify_ed25519(): ) assert signature.signature == '0x72bf2bc8fbc5dc56d657d7de8afa5208be1db025851e81031c754b371c7a29ce9f352d12df8207f9163316f81f59eb7725e5c0e4f3228e71ffe3764a9de6b10e' - print(f'signature: {signature}') - print(f'message: {message}') valid_signature = Utils.verify_ed25519_signature( signature, message, diff --git a/bindings/python/tests/test_wallet_destroy.py b/bindings/python/tests/test_wallet_destroy.py index 9ed24497dc..eafe36b253 100644 --- a/bindings/python/tests/test_wallet_destroy.py +++ b/bindings/python/tests/test_wallet_destroy.py @@ -24,8 +24,8 @@ def test_wallet_destroy(self): wallet_options = WalletOptions(None, None, bib_path, client_options, secret_manager, db_path) wallet = Wallet(wallet_options) - addresses = wallet.address() - assert 'smr1qzev36lk0gzld0k28fd2fauz26qqzh4hd4cwymlqlv96x7phjxcw6ckj80y' == addresses + address = wallet.address() + assert 'smr1qzev36lk0gzld0k28fd2fauz26qqzh4hd4cwymlqlv96x7phjxcw6ckj80y' == address # Destroy the wallet wallet.destroy() @@ -33,8 +33,8 @@ def test_wallet_destroy(self): # Afterwards destroying we can recreate the wallet again wallet = Wallet(wallet_options) - addresses = wallet.address() - assert 'smr1qzev36lk0gzld0k28fd2fauz26qqzh4hd4cwymlqlv96x7phjxcw6ckj80y' == addresses + address = wallet.address() + assert 'smr1qzev36lk0gzld0k28fd2fauz26qqzh4hd4cwymlqlv96x7phjxcw6ckj80y' == address shutil.rmtree(db_path, ignore_errors=True) def test_wallet_destroy_error(self): From 0a8213e0d350e805db5ef385e00c02e140963f13 Mon Sep 17 00:00:00 2001 From: Brord van Wierst Date: Wed, 13 Dec 2023 14:59:02 +0100 Subject: [PATCH 19/34] some review remarks --- .../python/examples/exchange/1_create_account.py | 8 ++++++-- .../accounts_and_addresses/create_wallet.py | 4 ++-- .../{list_address.py => print_address.py} | 7 +++++-- .../advanced_transactions/advanced_transaction.py | 12 +++++++----- .../advanced_transactions/claim_transaction.py | 11 +++++++---- .../send_micro_transaction.py | 12 ++++++++---- bindings/python/examples/how_tos/nfts/mint_nft.py | 14 +++++++++----- .../simple_transaction/simple_transaction.py | 12 ++++++++---- .../python/iota_sdk/wallet/prepared_transaction.py | 2 +- bindings/python/iota_sdk/wallet/wallet.py | 2 +- bindings/python/tests/address_generation_test.py | 8 ++++---- bindings/python/tests/test_offline.py | 4 ++-- bindings/python/tests/test_wallet_destroy.py | 8 ++++---- 13 files changed, 64 insertions(+), 40 deletions(-) rename bindings/python/examples/how_tos/accounts_and_addresses/{list_address.py => print_address.py} (68%) diff --git a/bindings/python/examples/exchange/1_create_account.py b/bindings/python/examples/exchange/1_create_account.py index a76d8201c0..72f8870098 100644 --- a/bindings/python/examples/exchange/1_create_account.py +++ b/bindings/python/examples/exchange/1_create_account.py @@ -28,13 +28,17 @@ # done once. SecretManager(secret_manager).store_mnemonic(os.environ['MNEMONIC']) -bib_path = Bip44( +bip_path = Bip44( coin_type=CoinType.SHIMMER ) -wallet_options = WalletOptions(None, None, bib_path, client_options, secret_manager, os.environ.get('WALLET_DB_PATH')) +wallet_options = WalletOptions(None, None, bip_path, client_options, secret_manager, os.environ.get('WALLET_DB_PATH')) wallet = Wallet(wallet_options) # Set sync_only_most_basic_outputs to True if not interested in outputs that are timelocked, # have a storage deposit return, expiration or are nft/account/foundry outputs. wallet.set_default_sync_options( SyncOptions(sync_only_most_basic_outputs=True)) + +# Update the wallet to the latest state +balance = wallet.sync() +print('Generated new wallet') diff --git a/bindings/python/examples/how_tos/accounts_and_addresses/create_wallet.py b/bindings/python/examples/how_tos/accounts_and_addresses/create_wallet.py index bdc035ad0c..272d32afe5 100644 --- a/bindings/python/examples/how_tos/accounts_and_addresses/create_wallet.py +++ b/bindings/python/examples/how_tos/accounts_and_addresses/create_wallet.py @@ -22,11 +22,11 @@ # done once. SecretManager(secret_manager).store_mnemonic(os.environ['MNEMONIC']) -bib_path = Bip44( +bip_path = Bip44( coin_type=CoinType.SHIMMER ) -wallet_options = WalletOptions(None, None, bib_path, client_options, secret_manager, os.environ.get('WALLET_DB_PATH')) +wallet_options = WalletOptions(None, None, bip_path, client_options, secret_manager, os.environ.get('WALLET_DB_PATH')) wallet = Wallet(wallet_options) # Update the wallet to the latest state diff --git a/bindings/python/examples/how_tos/accounts_and_addresses/list_address.py b/bindings/python/examples/how_tos/accounts_and_addresses/print_address.py similarity index 68% rename from bindings/python/examples/how_tos/accounts_and_addresses/list_address.py rename to bindings/python/examples/how_tos/accounts_and_addresses/print_address.py index 395bdc0f0c..bcd71f0974 100644 --- a/bindings/python/examples/how_tos/accounts_and_addresses/list_address.py +++ b/bindings/python/examples/how_tos/accounts_and_addresses/print_address.py @@ -4,12 +4,15 @@ from iota_sdk import Wallet, WalletOptions -# This example lists the wallet address. - # This example uses secrets in environment variables for simplicity which # should not be done in production. load_dotenv() +# This example prints the wallet address. + +if 'WALLET_DB_PATH' not in os.environ: + raise Exception(".env WALLET_DB_PATH is undefined, see .env.example") + wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) address = wallet.address() diff --git a/bindings/python/examples/how_tos/advanced_transactions/advanced_transaction.py b/bindings/python/examples/how_tos/advanced_transactions/advanced_transaction.py index 309cbac125..acc64ca250 100644 --- a/bindings/python/examples/how_tos/advanced_transactions/advanced_transaction.py +++ b/bindings/python/examples/how_tos/advanced_transactions/advanced_transaction.py @@ -14,18 +14,20 @@ TimelockUnlockCondition, ) - +# This example uses secrets in environment variables for simplicity which +# should not be done in production. load_dotenv() # This example sends a transaction with a timelock. +for env_var in ['WALLET_DB_PATH', 'STRONGHOLD_PASSWORD']: + if env_var not in os.environ: + raise Exception(f'.env {env_var} is undefined, see .env.example') + wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) # Sync wallet with the node -response = wallet.sync() - -if 'STRONGHOLD_PASSWORD' not in os.environ: - raise Exception(".env STRONGHOLD_PASSWORD is undefined, see .env.example") +wallet.sync() wallet.set_stronghold_password(os.environ["STRONGHOLD_PASSWORD"]) diff --git a/bindings/python/examples/how_tos/advanced_transactions/claim_transaction.py b/bindings/python/examples/how_tos/advanced_transactions/claim_transaction.py index fe252f762d..2bc3610407 100644 --- a/bindings/python/examples/how_tos/advanced_transactions/claim_transaction.py +++ b/bindings/python/examples/how_tos/advanced_transactions/claim_transaction.py @@ -4,20 +4,23 @@ from iota_sdk import Wallet, WalletOptions +# This example uses secrets in environment variables for simplicity which +# should not be done in production. load_dotenv() # In this example we will claim outputs that have additional unlock # conditions as expiration or storage deposit return. -wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) +for env_var in ['WALLET_DB_PATH', 'STRONGHOLD_PASSWORD']: + if env_var not in os.environ: + raise Exception(f'.env {env_var} is undefined, see .env.example') -if 'STRONGHOLD_PASSWORD' not in os.environ: - raise Exception(".env STRONGHOLD_PASSWORD is undefined, see .env.example") +wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) wallet.set_stronghold_password(os.environ["STRONGHOLD_PASSWORD"]) # Sync wallet with the node -response = wallet.sync() +wallet.sync() # Only the unspent outputs in the account output_ids = wallet.claimable_outputs('All') diff --git a/bindings/python/examples/how_tos/advanced_transactions/send_micro_transaction.py b/bindings/python/examples/how_tos/advanced_transactions/send_micro_transaction.py index f95aa8cde9..47c47e30f8 100644 --- a/bindings/python/examples/how_tos/advanced_transactions/send_micro_transaction.py +++ b/bindings/python/examples/how_tos/advanced_transactions/send_micro_transaction.py @@ -4,17 +4,21 @@ from iota_sdk import Wallet, WalletOptions, SendParams +# This example uses secrets in environment variables for simplicity which +# should not be done in production. load_dotenv() # In this example we will send an amount below the minimum amount +for env_var in ['WALLET_DB_PATH', 'STRONGHOLD_PASSWORD']: + if env_var not in os.environ: + raise Exception(f'.env {env_var} is undefined, see .env.example') + + wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) # Sync wallet with the node -response = wallet.sync() - -if 'STRONGHOLD_PASSWORD' not in os.environ: - raise Exception(".env STRONGHOLD_PASSWORD is undefined, see .env.example") +wallet.sync() wallet.set_stronghold_password(os.environ["STRONGHOLD_PASSWORD"]) diff --git a/bindings/python/examples/how_tos/nfts/mint_nft.py b/bindings/python/examples/how_tos/nfts/mint_nft.py index adee0a54bd..ea675ab1fc 100644 --- a/bindings/python/examples/how_tos/nfts/mint_nft.py +++ b/bindings/python/examples/how_tos/nfts/mint_nft.py @@ -4,19 +4,23 @@ from iota_sdk import MintNftParams, Wallet, WalletOptions, utf8_to_hex +# This example uses secrets in environment variables for simplicity which +# should not be done in production. load_dotenv() # In this example we will mint an nft -wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) +for env_var in ['WALLET_DB_PATH', 'STRONGHOLD_PASSWORD']: + if env_var not in os.environ: + raise Exception(f'.env {env_var} is undefined, see .env.example') -if 'STRONGHOLD_PASSWORD' not in os.environ: - raise Exception(".env STRONGHOLD_PASSWORD is undefined, see .env.example") -wallet.set_stronghold_password(os.environ["STRONGHOLD_PASSWORD"]) +wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) # Sync wallet with the node -response = wallet.sync() +wallet.sync() + +wallet.set_stronghold_password(os.environ["STRONGHOLD_PASSWORD"]) outputs = [MintNftParams( immutable_metadata=utf8_to_hex("some immutable nft metadata"), diff --git a/bindings/python/examples/how_tos/simple_transaction/simple_transaction.py b/bindings/python/examples/how_tos/simple_transaction/simple_transaction.py index 3e8492db02..8da4b986bd 100644 --- a/bindings/python/examples/how_tos/simple_transaction/simple_transaction.py +++ b/bindings/python/examples/how_tos/simple_transaction/simple_transaction.py @@ -4,17 +4,21 @@ from iota_sdk import SendParams, Wallet, WalletOptions +# This example uses secrets in environment variables for simplicity which +# should not be done in production. load_dotenv() # This example sends a transaction. +for env_var in ['WALLET_DB_PATH', 'STRONGHOLD_PASSWORD']: + if env_var not in os.environ: + raise Exception(f'.env {env_var} is undefined, see .env.example') + + wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) # Sync wallet with the node -response = wallet.sync() - -if 'STRONGHOLD_PASSWORD' not in os.environ: - raise Exception(".env STRONGHOLD_PASSWORD is undefined, see .env.example") +wallet.sync() wallet.set_stronghold_password(os.environ["STRONGHOLD_PASSWORD"]) diff --git a/bindings/python/iota_sdk/wallet/prepared_transaction.py b/bindings/python/iota_sdk/wallet/prepared_transaction.py index 7d3e71cb10..fb9c37f48b 100644 --- a/bindings/python/iota_sdk/wallet/prepared_transaction.py +++ b/bindings/python/iota_sdk/wallet/prepared_transaction.py @@ -18,7 +18,7 @@ class PreparedTransaction: """A helper class for offline signing. Attributes: - wallet: An wallet object used to continue building this transaction. + wallet: A wallet object used to continue building this transaction. prepared_transaction_data_dto: A prepared transaction data object. """ diff --git a/bindings/python/iota_sdk/wallet/wallet.py b/bindings/python/iota_sdk/wallet/wallet.py index 414077c9de..0df0cd0ecb 100644 --- a/bindings/python/iota_sdk/wallet/wallet.py +++ b/bindings/python/iota_sdk/wallet/wallet.py @@ -756,7 +756,7 @@ def submit_and_store_transaction( )) def sync(self, options: Optional[SyncOptions] = None) -> Balance: - """Sync the account by fetching new information from the nodes. + """Sync the wallet by fetching new information from the nodes. Will also reissue pending transactions and consolidate outputs if necessary. A custom default can be set using set_default_sync_options. """ diff --git a/bindings/python/tests/address_generation_test.py b/bindings/python/tests/address_generation_test.py index 576243be82..06acf67735 100644 --- a/bindings/python/tests/address_generation_test.py +++ b/bindings/python/tests/address_generation_test.py @@ -15,10 +15,10 @@ def test_address_generation_iota(): secret_manager = MnemonicSecretManager( "acoustic trophy damage hint search taste love bicycle foster cradle brown govern endless depend situate athlete pudding blame question genius transfer van random vast") - bib_path = Bip44( + bip_path = Bip44( coin_type=CoinType.IOTA ) - wallet_options = WalletOptions(None, None, bib_path, client_options, secret_manager, db_path) + wallet_options = WalletOptions(None, None, bip_path, client_options, secret_manager, db_path) wallet = Wallet(wallet_options) address = wallet.address() @@ -37,10 +37,10 @@ def test_address_generation_shimmer(): secret_manager = MnemonicSecretManager( "acoustic trophy damage hint search taste love bicycle foster cradle brown govern endless depend situate athlete pudding blame question genius transfer van random vast") - bib_path = Bip44( + bip_path = Bip44( coin_type=CoinType.IOTA ) - wallet_options = WalletOptions(None, None, bib_path, client_options, secret_manager, db_path) + wallet_options = WalletOptions(None, None, bip_path, client_options, secret_manager, db_path) wallet = Wallet(wallet_options) address = wallet.address() diff --git a/bindings/python/tests/test_offline.py b/bindings/python/tests/test_offline.py index a23d91ec40..e827558113 100644 --- a/bindings/python/tests/test_offline.py +++ b/bindings/python/tests/test_offline.py @@ -37,14 +37,14 @@ def test_sign_verify_ed25519(): "acoustic trophy damage hint search taste love bicycle foster cradle brown govern endless depend situate athlete pudding blame question genius transfer van random vast") message = utf8_to_hex('IOTA') - bib_path = Bip44( + bip_path = Bip44( coin_type=CoinType.IOTA ) secret_manager = SecretManager(secret_manager) signature = secret_manager.sign_ed25519( message, - bib_path, + bip_path, ) assert signature.signature == '0x72bf2bc8fbc5dc56d657d7de8afa5208be1db025851e81031c754b371c7a29ce9f352d12df8207f9163316f81f59eb7725e5c0e4f3228e71ffe3764a9de6b10e' diff --git a/bindings/python/tests/test_wallet_destroy.py b/bindings/python/tests/test_wallet_destroy.py index eafe36b253..eb35d884a9 100644 --- a/bindings/python/tests/test_wallet_destroy.py +++ b/bindings/python/tests/test_wallet_destroy.py @@ -18,10 +18,10 @@ def test_wallet_destroy(self): secret_manager = MnemonicSecretManager( "acoustic trophy damage hint search taste love bicycle foster cradle brown govern endless depend situate athlete pudding blame question genius transfer van random vast") - bib_path = Bip44( + bip_path = Bip44( coin_type=CoinType.SHIMMER ) - wallet_options = WalletOptions(None, None, bib_path, client_options, secret_manager, db_path) + wallet_options = WalletOptions(None, None, bip_path, client_options, secret_manager, db_path) wallet = Wallet(wallet_options) address = wallet.address() @@ -45,10 +45,10 @@ def test_wallet_destroy_error(self): secret_manager = MnemonicSecretManager( "acoustic trophy damage hint search taste love bicycle foster cradle brown govern endless depend situate athlete pudding blame question genius transfer van random vast") - bib_path = Bip44( + bip_path = Bip44( coin_type=CoinType.SHIMMER ) - wallet_options = WalletOptions(None, None, bib_path, client_options, secret_manager, db_path) + wallet_options = WalletOptions(None, None, bip_path, client_options, secret_manager, db_path) wallet = Wallet(wallet_options) # Destroy the wallet From 489986c3b168bad20e7774df2d97730f23c85298 Mon Sep 17 00:00:00 2001 From: Brord van Wierst Date: Wed, 13 Dec 2023 15:03:52 +0100 Subject: [PATCH 20/34] worded different --- .../how_tos/accounts_and_addresses/consolidate_outputs.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bindings/python/examples/how_tos/accounts_and_addresses/consolidate_outputs.py b/bindings/python/examples/how_tos/accounts_and_addresses/consolidate_outputs.py index 940e6f8c12..1d8c7badd8 100644 --- a/bindings/python/examples/how_tos/accounts_and_addresses/consolidate_outputs.py +++ b/bindings/python/examples/how_tos/accounts_and_addresses/consolidate_outputs.py @@ -37,8 +37,8 @@ print(f'- amount: #{output_data.output.amount}') native_tokens = [feature for feature in output_data.output.features if feature.type == FeatureType.NativeToken] - first_native_token = next(iter(native_tokens), None) - print(f'- native tokens: #{first_native_token}') + opt_native_token = next(iter(native_tokens), None) + print(f'- native tokens: #{opt_native_token}') print('Sending consolidation transaction...') @@ -70,5 +70,5 @@ print(f'- amount: #{output_data.output.amount}') native_tokens = [feature for feature in output_data.output.features if feature.type == FeatureType.NativeToken] - first_native_token = next(iter(native_tokens), None) - print(f'- native tokens: #{first_native_token}') + opt_native_token = next(iter(native_tokens), None) + print(f'- native tokens: #{opt_native_token}') From 2f2b0fa1a7eb96a3423f121947e4ab6e3424fbd6 Mon Sep 17 00:00:00 2001 From: Brord van Wierst Date: Wed, 13 Dec 2023 15:04:44 +0100 Subject: [PATCH 21/34] file rename --- .../examples/exchange/{1_create_account.py => 1_create_wallet.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename bindings/python/examples/exchange/{1_create_account.py => 1_create_wallet.py} (100%) diff --git a/bindings/python/examples/exchange/1_create_account.py b/bindings/python/examples/exchange/1_create_wallet.py similarity index 100% rename from bindings/python/examples/exchange/1_create_account.py rename to bindings/python/examples/exchange/1_create_wallet.py From 720d57c0bb93da0712d657c4579c8d19d69df418 Mon Sep 17 00:00:00 2001 From: Brord van Wierst Date: Thu, 14 Dec 2023 01:08:32 +0100 Subject: [PATCH 22/34] fix --- bindings/python/tests/test_block.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/bindings/python/tests/test_block.py b/bindings/python/tests/test_block.py index ea99fabf9c..87c751bc44 100644 --- a/bindings/python/tests/test_block.py +++ b/bindings/python/tests/test_block.py @@ -32,12 +32,14 @@ def test_basic_block_with_tagged_data_payload(): def test_block_with_tagged_data_payload(): block_dict = { - "protocolVersion": 3, - "networkId": "10549460113735494767", - "issuingTime": "1675563954966263210", - "slotCommitmentId": "0x498bf08a5ed287bc87340341ffab28706768cd3a7035ae5e33932d9a12bb30940000000000000000", - "latestFinalizedSlot": 21, - "issuerId": "0x3370746f30705b7d0b42597459714d45241e5a64761b09627c447b751c7e145c", + "header": { + "protocolVersion": 3, + "networkId": "10549460113735494767", + "issuingTime": "1675563954966263210", + "slotCommitmentId": "0x498bf08a5ed287bc87340341ffab28706768cd3a7035ae5e33932d9a12bb30940000000000000000", + "latestFinalizedSlot": 21, + "issuerId": "0x3370746f30705b7d0b42597459714d45241e5a64761b09627c447b751c7e145c", + }, "body": { "type": 0, "strongParents": [ From 202fb2cd8792e3995603cbe5e58702d310e49b0d Mon Sep 17 00:00:00 2001 From: Brord van Wierst Date: Thu, 14 Dec 2023 02:21:08 +0100 Subject: [PATCH 23/34] one more account removed --- bindings/python/examples/exchange/3_check_balance.py | 7 ++++--- bindings/python/examples/exchange/4_listen_events.py | 7 ++++--- .../how_tos/accounts_and_addresses/consolidate_outputs.py | 6 +++--- bindings/python/examples/how_tos/native_tokens/create.py | 4 ++-- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/bindings/python/examples/exchange/3_check_balance.py b/bindings/python/examples/exchange/3_check_balance.py index c8c6b4d0c2..27d675083d 100644 --- a/bindings/python/examples/exchange/3_check_balance.py +++ b/bindings/python/examples/exchange/3_check_balance.py @@ -13,8 +13,9 @@ # should not be done in production. load_dotenv() -if 'WALLET_DB_PATH' not in os.environ: - raise Exception(".env WALLET_DB_PATH is undefined, see .env.example") +for env_var in ['WALLET_DB_PATH', 'FAUCET_URL']: + if env_var not in os.environ: + raise Exception(f'.env {env_var} is undefined, see .env.example') wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) @@ -27,4 +28,4 @@ print('Balance', balance) # Use the faucet to send tokens to your address. -print('Fill your address with the Faucet: https://faucet.testnet.shimmer.network/') +print(f'Fill your address with the Faucet: {os.environ[FAUCET_URL]}') diff --git a/bindings/python/examples/exchange/4_listen_events.py b/bindings/python/examples/exchange/4_listen_events.py index b5882a829e..17395fd189 100644 --- a/bindings/python/examples/exchange/4_listen_events.py +++ b/bindings/python/examples/exchange/4_listen_events.py @@ -16,8 +16,9 @@ # should not be done in production. load_dotenv() -if 'WALLET_DB_PATH' not in os.environ: - raise Exception(".env WALLET_DB_PATH is undefined, see .env.example") +for env_var in ['WALLET_DB_PATH', 'FAUCET_URL']: + if env_var not in os.environ: + raise Exception(".env WALLET_DB_PATH is undefined, see .env.example") wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) @@ -40,7 +41,7 @@ def callback(event): wallet.listen(callback, [WalletEventType.NewOutput]) # Use the faucet to send testnet tokens to your address. -print('Fill your address with the faucet: https://faucet.testnet.shimmer.network/') +print(f'Fill your address with the Faucet: {os.environ[FAUCET_URL]}') address = wallet.address() print('Send funds to:', address) diff --git a/bindings/python/examples/how_tos/accounts_and_addresses/consolidate_outputs.py b/bindings/python/examples/how_tos/accounts_and_addresses/consolidate_outputs.py index 1d8c7badd8..ef4f6dee17 100644 --- a/bindings/python/examples/how_tos/accounts_and_addresses/consolidate_outputs.py +++ b/bindings/python/examples/how_tos/accounts_and_addresses/consolidate_outputs.py @@ -20,7 +20,7 @@ # Sync wallet to make sure account is updated with outputs from previous # examples. wallet.sync() -print('Account synced') +print('Wallet synced') # List unspent outputs before consolidation. # The output we created with example `request_funds` and the basic output from `mint` have only one @@ -56,9 +56,9 @@ f'Transaction included: {os.environ["EXPLORER_URL"]}/block/{block_id}' ) -# Sync account +# Sync wallet wallet.sync() -print('Account synced') +print('Wallet synced') # Outputs after consolidation outputs = wallet.unspent_outputs() diff --git a/bindings/python/examples/how_tos/native_tokens/create.py b/bindings/python/examples/how_tos/native_tokens/create.py index 883f07926e..4a883a940a 100644 --- a/bindings/python/examples/how_tos/native_tokens/create.py +++ b/bindings/python/examples/how_tos/native_tokens/create.py @@ -57,6 +57,6 @@ print(f'Created token: {prepared_transaction.token_id()}') -# Ensure the account is synced after creating the native token. +# Ensure the wallet is synced after creating the native token. wallet.sync() -print('Account synced') +print('Wallet synced') From ec3715429a3cff348c24c829c94aa63f05f429a9 Mon Sep 17 00:00:00 2001 From: Brord van Wierst Date: Thu, 14 Dec 2023 02:37:44 +0100 Subject: [PATCH 24/34] its a str not a var u dummy --- bindings/python/examples/exchange/3_check_balance.py | 2 +- bindings/python/examples/exchange/4_listen_events.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bindings/python/examples/exchange/3_check_balance.py b/bindings/python/examples/exchange/3_check_balance.py index 27d675083d..e90c5b0144 100644 --- a/bindings/python/examples/exchange/3_check_balance.py +++ b/bindings/python/examples/exchange/3_check_balance.py @@ -28,4 +28,4 @@ print('Balance', balance) # Use the faucet to send tokens to your address. -print(f'Fill your address with the Faucet: {os.environ[FAUCET_URL]}') +print(f'Fill your address with the Faucet: {os.environ['FAUCET_URL']}') diff --git a/bindings/python/examples/exchange/4_listen_events.py b/bindings/python/examples/exchange/4_listen_events.py index 17395fd189..ee40d10912 100644 --- a/bindings/python/examples/exchange/4_listen_events.py +++ b/bindings/python/examples/exchange/4_listen_events.py @@ -41,7 +41,7 @@ def callback(event): wallet.listen(callback, [WalletEventType.NewOutput]) # Use the faucet to send testnet tokens to your address. -print(f'Fill your address with the Faucet: {os.environ[FAUCET_URL]}') +print(f'Fill your address with the Faucet: {os.environ['FAUCET_URL']}') address = wallet.address() print('Send funds to:', address) From 5206f881d39f83d3d791bbbc625547a74ff5cbbb Mon Sep 17 00:00:00 2001 From: Brord van Wierst Date: Thu, 14 Dec 2023 11:44:31 +0100 Subject: [PATCH 25/34] one more timeee --- bindings/python/examples/exchange/3_check_balance.py | 2 +- bindings/python/examples/exchange/4_listen_events.py | 2 +- .../how_tos/accounts_and_addresses/consolidate_outputs.py | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/bindings/python/examples/exchange/3_check_balance.py b/bindings/python/examples/exchange/3_check_balance.py index e90c5b0144..dadcf3ed17 100644 --- a/bindings/python/examples/exchange/3_check_balance.py +++ b/bindings/python/examples/exchange/3_check_balance.py @@ -28,4 +28,4 @@ print('Balance', balance) # Use the faucet to send tokens to your address. -print(f'Fill your address with the Faucet: {os.environ['FAUCET_URL']}') +print(f'Fill your address with the Faucet: {os.environ["FAUCET_URL"]}') diff --git a/bindings/python/examples/exchange/4_listen_events.py b/bindings/python/examples/exchange/4_listen_events.py index ee40d10912..ca89373e93 100644 --- a/bindings/python/examples/exchange/4_listen_events.py +++ b/bindings/python/examples/exchange/4_listen_events.py @@ -41,7 +41,7 @@ def callback(event): wallet.listen(callback, [WalletEventType.NewOutput]) # Use the faucet to send testnet tokens to your address. -print(f'Fill your address with the Faucet: {os.environ['FAUCET_URL']}') +print(f'Fill your address with the Faucet: {os.environ["FAUCET_URL"]}') address = wallet.address() print('Send funds to:', address) diff --git a/bindings/python/examples/how_tos/accounts_and_addresses/consolidate_outputs.py b/bindings/python/examples/how_tos/accounts_and_addresses/consolidate_outputs.py index ef4f6dee17..097eea5c82 100644 --- a/bindings/python/examples/how_tos/accounts_and_addresses/consolidate_outputs.py +++ b/bindings/python/examples/how_tos/accounts_and_addresses/consolidate_outputs.py @@ -17,8 +17,7 @@ wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) wallet.set_stronghold_password(os.environ['STRONGHOLD_PASSWORD']) -# Sync wallet to make sure account is updated with outputs from previous -# examples. +# Sync wallet to make sure it is updated with outputs from the previous examples. wallet.sync() print('Wallet synced') From fc45b39391e574a64db4002a1dc046f50f8d48d8 Mon Sep 17 00:00:00 2001 From: Brord van Wierst Date: Thu, 14 Dec 2023 15:04:39 +0100 Subject: [PATCH 26/34] fix utils --- bindings/python/iota_sdk/client/_utils.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bindings/python/iota_sdk/client/_utils.py b/bindings/python/iota_sdk/client/_utils.py index 41427b8031..79c9e8007e 100644 --- a/bindings/python/iota_sdk/client/_utils.py +++ b/bindings/python/iota_sdk/client/_utils.py @@ -4,6 +4,7 @@ from typing import Optional from abc import ABCMeta, abstractmethod +from iota_sdk.types.block.block import Block from iota_sdk.types.common import HexStr from iota_sdk.types.output import Output @@ -87,7 +88,7 @@ def request_funds_from_faucet(self, url: str, address: str) -> str: } ) - def block_id(block: Block) -> HexStr: + def block_id(self, block: Block) -> HexStr: """ Return a block ID (Blake2b256 hash of block bytes) from a block. """ return self._call_method('blockId', { From 313e79b191ec5601be5cb2b732ebf08500323584 Mon Sep 17 00:00:00 2001 From: Thibault Martinez Date: Mon, 18 Dec 2023 16:36:12 +0100 Subject: [PATCH 27/34] More rename --- Cargo.lock | 114 ++++++++++++++++++ .../how_tos/account_output/destroy.py | 2 +- .../consolidate_outputs.py | 2 +- .../accounts_and_addresses/list_outputs.py | 6 +- .../list_transactions.py | 2 +- .../claim_transaction.py | 2 +- .../examples/how_tos/native_tokens/create.py | 2 +- .../how_tos/native_tokens/destroy_foundry.py | 2 +- 8 files changed, 123 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0e1bd2ff89..a91d299c68 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1535,6 +1535,12 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "indoc" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e186cfbae8084e513daff4240b4797e342f988cecda4fb6c939150f96315fd8" + [[package]] name = "inout" version = "0.1.3" @@ -1695,6 +1701,18 @@ dependencies = [ "tokio", ] +[[package]] +name = "iota-sdk-python" +version = "1.1.1" +dependencies = [ + "futures", + "iota-sdk-bindings-core", + "once_cell", + "pyo3", + "serde_json", + "tokio", +] + [[package]] name = "iota-sdk-wasm" version = "0.1.0" @@ -2172,6 +2190,29 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.48.5", +] + [[package]] name = "paste" version = "1.0.14" @@ -2383,6 +2424,67 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "pyo3" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04e8453b658fe480c3e70c8ed4e3d3ec33eb74988bd186561b0cc66b85c3bc4b" +dependencies = [ + "cfg-if", + "indoc", + "libc", + "memoffset 0.9.0", + "parking_lot", + "pyo3-build-config", + "pyo3-ffi", + "pyo3-macros", + "unindent", +] + +[[package]] +name = "pyo3-build-config" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a96fe70b176a89cff78f2fa7b3c930081e163d5379b4dcdf993e3ae29ca662e5" +dependencies = [ + "once_cell", + "target-lexicon", +] + +[[package]] +name = "pyo3-ffi" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "214929900fd25e6604661ed9cf349727c8920d47deff196c4e28165a6ef2a96b" +dependencies = [ + "libc", + "pyo3-build-config", +] + +[[package]] +name = "pyo3-macros" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dac53072f717aa1bfa4db832b39de8c875b7c7af4f4a6fe93cdbf9264cf8383b" +dependencies = [ + "proc-macro2", + "pyo3-macros-backend", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "pyo3-macros-backend" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7774b5a8282bd4f25f803b1f0d945120be959a36c72e08e7cd031c792fdfd424" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.39", +] + [[package]] name = "quote" version = "1.0.33" @@ -3115,6 +3217,12 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" +[[package]] +name = "target-lexicon" +version = "0.12.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c39fd04924ca3a864207c66fc2cd7d22d7c016007f9ce846cbb9326331930a" + [[package]] name = "thiserror" version = "1.0.50" @@ -3393,6 +3501,12 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" +[[package]] +name = "unindent" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7de7d73e1754487cb58364ee906a499937a0dfabd86bcb980fa99ec8c8fa2ce" + [[package]] name = "universal-hash" version = "0.5.1" diff --git a/bindings/python/examples/how_tos/account_output/destroy.py b/bindings/python/examples/how_tos/account_output/destroy.py index c322e40263..0b84209623 100644 --- a/bindings/python/examples/how_tos/account_output/destroy.py +++ b/bindings/python/examples/how_tos/account_output/destroy.py @@ -17,7 +17,7 @@ # Sync wallet with the node balance = wallet.sync() -# We try to destroy the first account in the account +# We try to destroy the first account in the wallet account_id = balance.accounts[0] wallet.set_stronghold_password(os.environ["STRONGHOLD_PASSWORD"]) diff --git a/bindings/python/examples/how_tos/accounts_and_addresses/consolidate_outputs.py b/bindings/python/examples/how_tos/accounts_and_addresses/consolidate_outputs.py index 097eea5c82..5b2a752e0d 100644 --- a/bindings/python/examples/how_tos/accounts_and_addresses/consolidate_outputs.py +++ b/bindings/python/examples/how_tos/accounts_and_addresses/consolidate_outputs.py @@ -4,7 +4,7 @@ from iota_sdk import ConsolidationParams, Utils, Wallet, WalletOptions, FeatureType -# In this example we will consolidate basic outputs from an account with only an AddressUnlockCondition by sending +# In this example we will consolidate basic outputs from a wallet with only an AddressUnlockCondition by sending # them to the same address again. # This example uses secrets in environment variables for simplicity which diff --git a/bindings/python/examples/how_tos/accounts_and_addresses/list_outputs.py b/bindings/python/examples/how_tos/accounts_and_addresses/list_outputs.py index 2010082529..aaabc7ee45 100644 --- a/bindings/python/examples/how_tos/accounts_and_addresses/list_outputs.py +++ b/bindings/python/examples/how_tos/accounts_and_addresses/list_outputs.py @@ -4,7 +4,7 @@ from iota_sdk import Wallet, WalletOptions -# In this example we will get outputs stored in the account +# In this example we will get outputs stored in the wallet # This example uses secrets in environment variables for simplicity which # should not be done in production. @@ -13,7 +13,7 @@ wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) wallet.sync() -# All outputs stored in the account +# All outputs stored in the wallet outputs = wallet.outputs() # Print all output ids @@ -21,7 +21,7 @@ for output in outputs: print(output.output_id) -# All unspent outputs stored in the account +# All unspent outputs stored in the wallet outputs = wallet.unspent_outputs() # Print all unspent output ids diff --git a/bindings/python/examples/how_tos/accounts_and_addresses/list_transactions.py b/bindings/python/examples/how_tos/accounts_and_addresses/list_transactions.py index 344e1921a9..af354a5d61 100644 --- a/bindings/python/examples/how_tos/accounts_and_addresses/list_transactions.py +++ b/bindings/python/examples/how_tos/accounts_and_addresses/list_transactions.py @@ -13,7 +13,7 @@ wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) wallet.sync({'syncIncomingTransactions': True}) -# All transactions sent from the the account +# All transactions sent from the wallet transactions = wallet.transactions() print('Sent transactions:') for transaction in transactions: diff --git a/bindings/python/examples/how_tos/advanced_transactions/claim_transaction.py b/bindings/python/examples/how_tos/advanced_transactions/claim_transaction.py index 2bc3610407..c833932317 100644 --- a/bindings/python/examples/how_tos/advanced_transactions/claim_transaction.py +++ b/bindings/python/examples/how_tos/advanced_transactions/claim_transaction.py @@ -22,7 +22,7 @@ # Sync wallet with the node wallet.sync() -# Only the unspent outputs in the account +# Only the unspent outputs in the wallet output_ids = wallet.claimable_outputs('All') print('Available outputs to claim:') diff --git a/bindings/python/examples/how_tos/native_tokens/create.py b/bindings/python/examples/how_tos/native_tokens/create.py index 4a883a940a..6510b4b80d 100644 --- a/bindings/python/examples/how_tos/native_tokens/create.py +++ b/bindings/python/examples/how_tos/native_tokens/create.py @@ -32,7 +32,7 @@ print(f'Block included: {os.environ["EXPLORER_URL"]}/block/{block_id}') wallet.sync() - print("Account synced") + print("Wallet synced") print('Preparing transaction to create native token...') diff --git a/bindings/python/examples/how_tos/native_tokens/destroy_foundry.py b/bindings/python/examples/how_tos/native_tokens/destroy_foundry.py index 8682b1dad7..45a04537dc 100644 --- a/bindings/python/examples/how_tos/native_tokens/destroy_foundry.py +++ b/bindings/python/examples/how_tos/native_tokens/destroy_foundry.py @@ -17,7 +17,7 @@ wallet.set_stronghold_password(os.environ["STRONGHOLD_PASSWORD"]) -# We try to destroy the first foundry in the account +# We try to destroy the first foundry in the wallet foundry_id = balance.foundries[0] # Send transaction. From 525f5d34df163b94996ab8590b1fdeff945eb76e Mon Sep 17 00:00:00 2001 From: Thibault Martinez Date: Mon, 18 Dec 2023 16:46:34 +0100 Subject: [PATCH 28/34] More rename + fmt --- .../examples/exchange/1_create_wallet.py | 8 ++++++- .../consolidate_outputs.py | 9 ++++--- .../accounts_and_addresses/create_wallet.py | 8 ++++++- bindings/python/iota_sdk/types/common.py | 6 +++-- .../python/iota_sdk/types/output_params.py | 2 +- bindings/python/iota_sdk/types/unlock.py | 3 ++- bindings/python/iota_sdk/wallet/wallet.py | 24 +++++++++---------- .../python/tests/address_generation_test.py | 16 +++++++++++-- bindings/python/tests/test_wallet_destroy.py | 16 +++++++++++-- 9 files changed, 67 insertions(+), 25 deletions(-) diff --git a/bindings/python/examples/exchange/1_create_wallet.py b/bindings/python/examples/exchange/1_create_wallet.py index 72f8870098..c013112e88 100644 --- a/bindings/python/examples/exchange/1_create_wallet.py +++ b/bindings/python/examples/exchange/1_create_wallet.py @@ -31,7 +31,13 @@ bip_path = Bip44( coin_type=CoinType.SHIMMER ) -wallet_options = WalletOptions(None, None, bip_path, client_options, secret_manager, os.environ.get('WALLET_DB_PATH')) +wallet_options = WalletOptions( + None, + None, + bip_path, + client_options, + secret_manager, + os.environ.get('WALLET_DB_PATH')) wallet = Wallet(wallet_options) # Set sync_only_most_basic_outputs to True if not interested in outputs that are timelocked, diff --git a/bindings/python/examples/how_tos/accounts_and_addresses/consolidate_outputs.py b/bindings/python/examples/how_tos/accounts_and_addresses/consolidate_outputs.py index 5b2a752e0d..434b3b692c 100644 --- a/bindings/python/examples/how_tos/accounts_and_addresses/consolidate_outputs.py +++ b/bindings/python/examples/how_tos/accounts_and_addresses/consolidate_outputs.py @@ -17,7 +17,8 @@ wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) wallet.set_stronghold_password(os.environ['STRONGHOLD_PASSWORD']) -# Sync wallet to make sure it is updated with outputs from the previous examples. +# Sync wallet to make sure it is updated with outputs from the previous +# examples. wallet.sync() print('Wallet synced') @@ -35,7 +36,8 @@ f'- address: #{Utils.hex_to_bech32(output_data.address.pub_key_hash, "rms")}') print(f'- amount: #{output_data.output.amount}') - native_tokens = [feature for feature in output_data.output.features if feature.type == FeatureType.NativeToken] + native_tokens = [ + feature for feature in output_data.output.features if feature.type == FeatureType.NativeToken] opt_native_token = next(iter(native_tokens), None) print(f'- native tokens: #{opt_native_token}') @@ -68,6 +70,7 @@ f'- address: #{Utils.hex_to_bech32(output_data.address.pub_key_hash, "rms")}') print(f'- amount: #{output_data.output.amount}') - native_tokens = [feature for feature in output_data.output.features if feature.type == FeatureType.NativeToken] + native_tokens = [ + feature for feature in output_data.output.features if feature.type == FeatureType.NativeToken] opt_native_token = next(iter(native_tokens), None) print(f'- native tokens: #{opt_native_token}') diff --git a/bindings/python/examples/how_tos/accounts_and_addresses/create_wallet.py b/bindings/python/examples/how_tos/accounts_and_addresses/create_wallet.py index 272d32afe5..c956909b76 100644 --- a/bindings/python/examples/how_tos/accounts_and_addresses/create_wallet.py +++ b/bindings/python/examples/how_tos/accounts_and_addresses/create_wallet.py @@ -26,7 +26,13 @@ coin_type=CoinType.SHIMMER ) -wallet_options = WalletOptions(None, None, bip_path, client_options, secret_manager, os.environ.get('WALLET_DB_PATH')) +wallet_options = WalletOptions( + None, + None, + bip_path, + client_options, + secret_manager, + os.environ.get('WALLET_DB_PATH')) wallet = Wallet(wallet_options) # Update the wallet to the latest state diff --git a/bindings/python/iota_sdk/types/common.py b/bindings/python/iota_sdk/types/common.py index d750b2bae0..2f85d96704 100644 --- a/bindings/python/iota_sdk/types/common.py +++ b/bindings/python/iota_sdk/types/common.py @@ -34,9 +34,11 @@ def custom_to_dict(self, *args, **kwargs): # recursive remove the None values def filter_none(value): if isinstance(value, dict): - return {k: filter_none(v) for k, v in value.items() if v is not None} + return {k: filter_none(v) + for k, v in value.items() if v is not None} if isinstance(value, list): - return [filter_none(item) for item in value if item is not None] + return [filter_none(item) + for item in value if item is not None] return value return filter_none(original_dict) diff --git a/bindings/python/iota_sdk/types/output_params.py b/bindings/python/iota_sdk/types/output_params.py index 6133a2e704..2303396596 100644 --- a/bindings/python/iota_sdk/types/output_params.py +++ b/bindings/python/iota_sdk/types/output_params.py @@ -62,7 +62,7 @@ class StorageDeposit(): @json @dataclass class OutputParams(): - """Params for `Account.prepare_output()`. + """Params for `Wallet.prepare_output()`. """ recipient_address: str amount: int = field(metadata=config( diff --git a/bindings/python/iota_sdk/types/unlock.py b/bindings/python/iota_sdk/types/unlock.py index 3d5a9d7060..507bc35118 100644 --- a/bindings/python/iota_sdk/types/unlock.py +++ b/bindings/python/iota_sdk/types/unlock.py @@ -91,7 +91,8 @@ class NftUnlock: # pylint: disable=missing-function-docstring,unused-argument def deserialize_unlocks(dicts: List[Dict[str, Any]]) -> List[Unlock]: - # Function gets overwritten further below, but needs to be defined here already + # Function gets overwritten further below, but needs to be defined here + # already pass diff --git a/bindings/python/iota_sdk/wallet/wallet.py b/bindings/python/iota_sdk/wallet/wallet.py index 0df0cd0ecb..eb57979fa0 100644 --- a/bindings/python/iota_sdk/wallet/wallet.py +++ b/bindings/python/iota_sdk/wallet/wallet.py @@ -151,8 +151,8 @@ def clear_listeners(self, events: Optional[List[int]] = None): def restore_backup(self, source: str, password: str): """Restore a backup from a Stronghold file. - Replaces `client_options`, `coin_type`, `secret_manager` and accounts. - Returns an error if accounts were already created. If Stronghold is used + Replaces `client_options`, `coin_type`, `secret_manager` and wallet. + Returns an error if the wallet was already created. If Stronghold is used as the secret_manager, the existing Stronghold file will be overwritten. Be aware that if a mnemonic was stored, it will be lost. """ @@ -164,7 +164,7 @@ def restore_backup(self, source: str, password: str): ) def set_client_options(self, client_options): - """Update the client options for all accounts. + """Update the options of the wallet client. """ return self._call_method( 'setClientOptions', @@ -391,7 +391,7 @@ def prepare_destroy_foundry(self, return PreparedTransaction(self, prepared) def get_balance(self) -> Balance: - """Get account balance information. + """Get wallet balance information. """ return Balance.from_dict(self._call_method( 'getBalance' @@ -407,7 +407,7 @@ def get_output(self, output_id: OutputId) -> OutputData: )) def get_foundry_output(self, token_id: HexStr): - """Get a `FoundryOutput` by native token ID. It will try to get the foundry from the account, if it isn't in the wallet it will try to get it from the node. + """Get a `FoundryOutput` by native token ID. It will try to get the foundry from the wallet, if it isn't in the wallet it will try to get it from the node. """ return self._call_method( 'getFoundryOutput', { @@ -443,7 +443,7 @@ def address(self) -> str: def outputs( self, filter_options: Optional[FilterOptions] = None) -> List[OutputData]: - """Returns all outputs of the account. + """Returns all outputs of the wallet. """ outputs = self._call_method( 'outputs', { @@ -453,7 +453,7 @@ def outputs( return [OutputData.from_dict(o) for o in outputs] def pending_transactions(self): - """Returns all pending transactions of the account. + """Returns all pending transactions of the wallet. """ transactions = self._call_method( 'pendingTransactions' @@ -493,7 +493,7 @@ def implicit_accounts(self) -> List[OutputData]: return [OutputData.from_dict(o) for o in outputs] def incoming_transactions(self) -> List[TransactionWithMetadata]: - """Returns all incoming transactions of the account. + """Returns all incoming transactions of the wallet. """ transactions = self._call_method( 'incomingTransactions' @@ -501,7 +501,7 @@ def incoming_transactions(self) -> List[TransactionWithMetadata]: return [TransactionWithMetadata.from_dict(tx) for tx in transactions] def transactions(self) -> List[TransactionWithMetadata]: - """Returns all transaction of the account. + """Returns all transaction of the wallet. """ transactions = self._call_method( 'transactions' @@ -510,7 +510,7 @@ def transactions(self) -> List[TransactionWithMetadata]: def unspent_outputs( self, filter_options: Optional[FilterOptions] = None) -> List[OutputData]: - """Returns all unspent outputs of the account. + """Returns all unspent outputs of the wallet. """ outputs = self._call_method( 'unspentOutputs', { @@ -623,7 +623,7 @@ def prepare_transaction( def reissue_transaction_until_included( self, transaction_id: HexStr, interval=None, max_attempts=None) -> HexStr: - """Reissues a transaction sent from the account for a provided transaction id until it's + """Reissues a transaction sent from the wallet for a provided transaction id until it's included (referenced by a milestone). Returns the included block id. """ return self._call_method( @@ -716,7 +716,7 @@ def set_alias(self, alias: str): ) def set_default_sync_options(self, options: SyncOptions): - """Set the fallback SyncOptions for account syncing. + """Set the fallback SyncOptions for wallet syncing. If storage is enabled, will persist during restarts. """ return self._call_method( diff --git a/bindings/python/tests/address_generation_test.py b/bindings/python/tests/address_generation_test.py index 06acf67735..b335cc0231 100644 --- a/bindings/python/tests/address_generation_test.py +++ b/bindings/python/tests/address_generation_test.py @@ -18,7 +18,13 @@ def test_address_generation_iota(): bip_path = Bip44( coin_type=CoinType.IOTA ) - wallet_options = WalletOptions(None, None, bip_path, client_options, secret_manager, db_path) + wallet_options = WalletOptions( + None, + None, + bip_path, + client_options, + secret_manager, + db_path) wallet = Wallet(wallet_options) address = wallet.address() @@ -40,7 +46,13 @@ def test_address_generation_shimmer(): bip_path = Bip44( coin_type=CoinType.IOTA ) - wallet_options = WalletOptions(None, None, bip_path, client_options, secret_manager, db_path) + wallet_options = WalletOptions( + None, + None, + bip_path, + client_options, + secret_manager, + db_path) wallet = Wallet(wallet_options) address = wallet.address() diff --git a/bindings/python/tests/test_wallet_destroy.py b/bindings/python/tests/test_wallet_destroy.py index eb35d884a9..1e7e7ac712 100644 --- a/bindings/python/tests/test_wallet_destroy.py +++ b/bindings/python/tests/test_wallet_destroy.py @@ -21,7 +21,13 @@ def test_wallet_destroy(self): bip_path = Bip44( coin_type=CoinType.SHIMMER ) - wallet_options = WalletOptions(None, None, bip_path, client_options, secret_manager, db_path) + wallet_options = WalletOptions( + None, + None, + bip_path, + client_options, + secret_manager, + db_path) wallet = Wallet(wallet_options) address = wallet.address() @@ -48,7 +54,13 @@ def test_wallet_destroy_error(self): bip_path = Bip44( coin_type=CoinType.SHIMMER ) - wallet_options = WalletOptions(None, None, bip_path, client_options, secret_manager, db_path) + wallet_options = WalletOptions( + None, + None, + bip_path, + client_options, + secret_manager, + db_path) wallet = Wallet(wallet_options) # Destroy the wallet From f0f6223d9b4f52d70848795d3b5d48f9d6baf75b Mon Sep 17 00:00:00 2001 From: Brord van Wierst Date: Tue, 19 Dec 2023 15:55:24 +0100 Subject: [PATCH 29/34] Revert "examples update" This reverts commit 2dce6428270aca71d62b6cf9b7480ea23e02fbaa. --- .../python/examples/client/04_get_output.py | 2 +- .../examples/how_tos/account_output/create.py | 5 +- .../how_tos/account_output/destroy.py | 3 ++ .../how_tos/account_wallet/request_funds.py | 5 -- .../accounts_and_addresses/create_wallet.py | 6 +-- .../examples/wallet/12-prepare_output.py | 32 +++++++++++ .../wallet/13-check-unlock-conditions.py | 29 ++++++++++ bindings/python/examples/wallet/backup.py | 33 ++++++++++++ .../python/examples/wallet/create_alias.py | 23 ++++++++ bindings/python/examples/wallet/get_client.py | 16 ++++++ .../python/examples/wallet/getting_started.py | 50 +++++++++++++++++ bindings/python/examples/wallet/logger.py | 44 +++++++++++++++ .../migrate-stronghold-snapshot-v2-to-v3.py | 48 +++++++++++++++++ .../offline_signing/0_generate_addresses.py | 49 +++++++++++++++++ .../offline_signing/1_prepare_transaction.py | 54 +++++++++++++++++++ .../offline_signing/2_sign_transaction.py | 44 +++++++++++++++ .../offline_signing/3_send_transaction.py | 35 ++++++++++++ .../python/examples/wallet/restore_backup.py | 27 ++++++++++ .../examples/wallet/transaction_options.py | 36 +++++++++++++ .../account/implicit_account_creation.rs | 7 +-- 20 files changed, 529 insertions(+), 19 deletions(-) create mode 100644 bindings/python/examples/wallet/12-prepare_output.py create mode 100644 bindings/python/examples/wallet/13-check-unlock-conditions.py create mode 100644 bindings/python/examples/wallet/backup.py create mode 100644 bindings/python/examples/wallet/create_alias.py create mode 100644 bindings/python/examples/wallet/get_client.py create mode 100644 bindings/python/examples/wallet/getting_started.py create mode 100644 bindings/python/examples/wallet/logger.py create mode 100644 bindings/python/examples/wallet/migrate-stronghold-snapshot-v2-to-v3.py create mode 100644 bindings/python/examples/wallet/offline_signing/0_generate_addresses.py create mode 100644 bindings/python/examples/wallet/offline_signing/1_prepare_transaction.py create mode 100644 bindings/python/examples/wallet/offline_signing/2_sign_transaction.py create mode 100644 bindings/python/examples/wallet/offline_signing/3_send_transaction.py create mode 100644 bindings/python/examples/wallet/restore_backup.py create mode 100644 bindings/python/examples/wallet/transaction_options.py diff --git a/bindings/python/examples/client/04_get_output.py b/bindings/python/examples/client/04_get_output.py index 8e1edde5ec..7c3b10e87d 100644 --- a/bindings/python/examples/client/04_get_output.py +++ b/bindings/python/examples/client/04_get_output.py @@ -14,5 +14,5 @@ # Get an outputs by its id output_with_metadata = client.get_output( - '0x022aefa73dff09b35b21ab5493412b0d354ad07a970a12b71e8087c6f3a7b866000000000000') + '0x022aefa73dff09b35b21ab5493412b0d354ad07a970a12b71e8087c6f3a7b8660000') print(json.dumps(output_with_metadata.to_dict(), indent=4)) diff --git a/bindings/python/examples/how_tos/account_output/create.py b/bindings/python/examples/how_tos/account_output/create.py index 709396a468..6fa19f0d6a 100644 --- a/bindings/python/examples/how_tos/account_output/create.py +++ b/bindings/python/examples/how_tos/account_output/create.py @@ -19,9 +19,10 @@ balance = wallet.sync() print(f'Accounts BEFORE: {balance.accounts}') -wallet.set_stronghold_password(os.environ["STRONGHOLD_PASSWORD"]) +if 'STRONGHOLD_PASSWORD' not in os.environ: + raise Exception(".env STRONGHOLD_PASSWORD is undefined, see .env.example") -print("Sending the create-account transaction...") +wallet.set_stronghold_password(os.environ["STRONGHOLD_PASSWORD"]) # Send transaction. transaction = wallet.create_account_output(None, None) diff --git a/bindings/python/examples/how_tos/account_output/destroy.py b/bindings/python/examples/how_tos/account_output/destroy.py index c322e40263..dc0b7d7323 100644 --- a/bindings/python/examples/how_tos/account_output/destroy.py +++ b/bindings/python/examples/how_tos/account_output/destroy.py @@ -20,6 +20,9 @@ # We try to destroy the first account in the account account_id = balance.accounts[0] +if 'STRONGHOLD_PASSWORD' not in os.environ: + raise Exception(".env STRONGHOLD_PASSWORD is undefined, see .env.example") + wallet.set_stronghold_password(os.environ["STRONGHOLD_PASSWORD"]) # Send transaction. diff --git a/bindings/python/examples/how_tos/account_wallet/request_funds.py b/bindings/python/examples/how_tos/account_wallet/request_funds.py index 1f6a1429dc..b37b1a05f4 100644 --- a/bindings/python/examples/how_tos/account_wallet/request_funds.py +++ b/bindings/python/examples/how_tos/account_wallet/request_funds.py @@ -9,16 +9,11 @@ load_dotenv() -for env_var in ['FAUCET_URL', 'WALLET_DB_PATH', 'EXPLORER_URL']: - if env_var not in os.environ: - raise Exception(f".env {env_var} is undefined, see .env.example") - FAUCET_URL = os.environ.get( 'FAUCET_URL', 'https://faucet.testnet.shimmer.network/api/enqueue') wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) balance = wallet.sync(None) -print(f'{balance}') total_base_token_balance = balance.base_coin.total print( diff --git a/bindings/python/examples/how_tos/accounts_and_addresses/create_wallet.py b/bindings/python/examples/how_tos/accounts_and_addresses/create_wallet.py index 272d32afe5..33f4f6792c 100644 --- a/bindings/python/examples/how_tos/accounts_and_addresses/create_wallet.py +++ b/bindings/python/examples/how_tos/accounts_and_addresses/create_wallet.py @@ -2,7 +2,7 @@ from dotenv import load_dotenv -from iota_sdk import ClientOptions, CoinType, StrongholdSecretManager, SecretManager, Wallet, WalletOptions, Bip44 +from iota_sdk import ClientOptions, CoinType, StrongholdSecretManager, Wallet, WalletOptions, Bip44 load_dotenv() @@ -28,7 +28,3 @@ wallet_options = WalletOptions(None, None, bip_path, client_options, secret_manager, os.environ.get('WALLET_DB_PATH')) wallet = Wallet(wallet_options) - -# Update the wallet to the latest state -balance = wallet.sync() -print('Generated new wallet') diff --git a/bindings/python/examples/wallet/12-prepare_output.py b/bindings/python/examples/wallet/12-prepare_output.py new file mode 100644 index 0000000000..138028d8c1 --- /dev/null +++ b/bindings/python/examples/wallet/12-prepare_output.py @@ -0,0 +1,32 @@ +import json +import os + +from dotenv import load_dotenv + +from iota_sdk import OutputParams, Unlocks, Wallet, WalletOptions + +load_dotenv() + +# In this example we will prepare an output with an address and expiration +# unlock condition and send it. + +wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) + +if 'STRONGHOLD_PASSWORD' not in os.environ: + raise Exception(".env STRONGHOLD_PASSWORD is undefined, see .env.example") + +wallet.set_stronghold_password(os.environ["STRONGHOLD_PASSWORD"]) + +# using prepare_output +output = wallet.prepare_output( + OutputParams( + "rms1qprutadk4uc9rp6h7wh7sech42sl0z40ztpgyygr5tf0cn5jrqshgm8y43d", + 1000000, + unlocks=Unlocks( + expiration_slot_index=1676570528))) +print(f"Output: {json.dumps(output.to_dict(), indent=4)}") + +wallet.sync() + +transaction = wallet.send_outputs([output]) +print(f'Block sent: {os.environ["EXPLORER_URL"]}/block/{transaction.block_id}') diff --git a/bindings/python/examples/wallet/13-check-unlock-conditions.py b/bindings/python/examples/wallet/13-check-unlock-conditions.py new file mode 100644 index 0000000000..bb8bbf7a70 --- /dev/null +++ b/bindings/python/examples/wallet/13-check-unlock-conditions.py @@ -0,0 +1,29 @@ +import os + +from dotenv import load_dotenv + +from iota_sdk import OutputParams, Utils, Wallet, WalletOptions + +load_dotenv() + +# In this example we check if an output has only an address unlock +# condition and that the address is from the wallet. + +wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) +address = wallet.address() + +# using prepare_output +output = wallet.prepare_output(OutputParams( + address, 1000000)) + +hexEncodedWalletAddress = Utils.bech32_to_hex(address) + +controlled_by_wallet = False + +if len( + output.unlock_conditions) == 1 and output.unlock_conditions[0].type == 0: + if output.unlock_conditions[0].address.pub_key_hash == hexEncodedWalletAddress: + controlled_by_wallet = True + +print( + f'The output has only an address unlock condition and the address is from the wallet: {controlled_by_wallet}') diff --git a/bindings/python/examples/wallet/backup.py b/bindings/python/examples/wallet/backup.py new file mode 100644 index 0000000000..b5184c0fa0 --- /dev/null +++ b/bindings/python/examples/wallet/backup.py @@ -0,0 +1,33 @@ +import os + +from dotenv import load_dotenv + +from iota_sdk import ClientOptions, CoinType, StrongholdSecretManager, Wallet, WalletOptions, Bip44 + +load_dotenv() + +# This example creates a new database and wallet + +node_url = os.environ.get('NODE_URL', 'https://api.testnet.shimmer.network') +client_options = ClientOptions(nodes=[node_url]) + +for env_var in ['STRONGHOLD_PASSWORD', 'MNEMONIC']: + if env_var not in os.environ: + raise Exception(f'.env {env_var} is undefined, see .env.example') + +secret_manager = StrongholdSecretManager( + os.environ['STRONGHOLD_SNAPSHOT_PATH'], os.environ['STRONGHOLD_PASSWORD']) + +bib_path = Bip44( + coin_type=CoinType.SHIMMER +) + +wallet_options = WalletOptions(None, None, bib_path, client_options, secret_manager, './backup-database') +wallet = Wallet(wallet_options) + +# Store the mnemonic in the Stronghold snapshot, this only needs to be +# done once. +wallet.store_mnemonic(os.environ['MNEMONIC']) + +wallet.backup("backup.stronghold", os.environ['STRONGHOLD_PASSWORD']) +print('Created backup') diff --git a/bindings/python/examples/wallet/create_alias.py b/bindings/python/examples/wallet/create_alias.py new file mode 100644 index 0000000000..e9d6c4ff34 --- /dev/null +++ b/bindings/python/examples/wallet/create_alias.py @@ -0,0 +1,23 @@ +import os + +from dotenv import load_dotenv + +from iota_sdk import Wallet, WalletOptions + +load_dotenv() + +# In this example we will create an account output + +wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) + +# Sync account with the node +wallet.sync() + +if 'STRONGHOLD_PASSWORD' not in os.environ: + raise Exception(".env STRONGHOLD_PASSWORD is undefined, see .env.example") + +wallet.set_stronghold_password(os.environ["STRONGHOLD_PASSWORD"]) + +# Send transaction. +transaction = wallet.create_account_output(None, None) +print(f'Block sent: {os.environ["EXPLORER_URL"]}/block/{transaction.block_id}') diff --git a/bindings/python/examples/wallet/get_client.py b/bindings/python/examples/wallet/get_client.py new file mode 100644 index 0000000000..7b95c00691 --- /dev/null +++ b/bindings/python/examples/wallet/get_client.py @@ -0,0 +1,16 @@ +import os + +from dotenv import load_dotenv + +from iota_sdk import Wallet, WalletOptions + +load_dotenv() + +# This example gets a client from the wallet. + +wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) + +client = wallet.get_client() + +info = client.get_info() +print(f'{info}') diff --git a/bindings/python/examples/wallet/getting_started.py b/bindings/python/examples/wallet/getting_started.py new file mode 100644 index 0000000000..c22d0a2fee --- /dev/null +++ b/bindings/python/examples/wallet/getting_started.py @@ -0,0 +1,50 @@ +# Copyright 2023 IOTA Stiftung +# SPDX-License-Identifier: Apache-2.0 + +import os + +from dotenv import load_dotenv + +from iota_sdk import (ClientOptions, CoinType, StrongholdSecretManager, Utils, + Wallet, WalletOptions, Bip44, SecretManager) + +load_dotenv() + +# A name to associate with the created wallet. +ACCOUNT_ALIAS = 'Alice' + +# The node to connect to. +node_url = os.environ.get('NODE_URL', 'https://api.testnet.shimmer.network') + +# A password to encrypt the stored data. +# WARNING: Never hardcode passwords in production code. +STRONGHOLD_PASSWORD = os.environ.get( + 'STRONGHOLD_PASSWORD', 'a-secure-password') + +# The path to store the wallet snapshot. +STRONGHOLD_SNAPSHOT_PATH = 'vault.stronghold' + +# Setup Stronghold secret manager +secret_manager = StrongholdSecretManager( + STRONGHOLD_SNAPSHOT_PATH, STRONGHOLD_PASSWORD) + +# Generate a mnemonic and store its seed in the Stronghold vault. +# INFO: It is best practice to back up the mnemonic somewhere secure. +mnemonic = Utils.generate_mnemonic() +print(f'Mnemonic: {mnemonic}') + +SecretManager(secret_manager).store_mnemonic(mnemonic) + +# Set up and store the wallet. +client_options = ClientOptions(nodes=[node_url]) + +bib_path = Bip44( + coin_type=CoinType.SHIMMER +) +wallet_options = WalletOptions(None, None, bib_path, client_options, secret_manager) + +wallet = Wallet(wallet_options) + +# Get the first address and print it. +address = wallet.address() +print(f'Address:\n{address}') diff --git a/bindings/python/examples/wallet/logger.py b/bindings/python/examples/wallet/logger.py new file mode 100644 index 0000000000..1b7d998094 --- /dev/null +++ b/bindings/python/examples/wallet/logger.py @@ -0,0 +1,44 @@ +import json +import os + +from dotenv import load_dotenv + +# pylint: disable=no-name-in-module +from iota_sdk import (ClientOptions, CoinType, StrongholdSecretManager, Wallet, WalletOptions, Bip44, + init_logger) + +load_dotenv() + +# This example creates a new database and wallet and write debug logs in +# `wallet.log`. + +log_config = { + "name": './wallet.log', + "levelFilter": 'debug', + "targetExclusions": ["h2", "hyper", "rustls"] +} + +# Init the logger +init_logger(json.dumps(log_config)) + +node_url = os.environ.get('NODE_URL', 'https://api.testnet.shimmer.network') +client_options = ClientOptions(nodes=[node_url]) + +for env_var in ['STRONGHOLD_PASSWORD', 'MNEMONIC']: + if env_var not in os.environ: + raise Exception(f'.env {env_var} is undefined, see .env.example') + +secret_manager = StrongholdSecretManager( + "wallet.stronghold", + os.environ["STRONGHOLD_PASSWORD"]) + +bib_path = Bip44( + coin_type=CoinType.SHIMMER +) + +wallet_options = WalletOptions(None, None, bib_path, client_options, secret_manager, os.environ.get('WALLET_DB_PATH')) +wallet = Wallet(wallet_options) + +# Store the mnemonic in the Stronghold snapshot, this only needs to be +# done once. +wallet.store_mnemonic(os.environ["MNEMONIC"]) diff --git a/bindings/python/examples/wallet/migrate-stronghold-snapshot-v2-to-v3.py b/bindings/python/examples/wallet/migrate-stronghold-snapshot-v2-to-v3.py new file mode 100644 index 0000000000..3b36d76374 --- /dev/null +++ b/bindings/python/examples/wallet/migrate-stronghold-snapshot-v2-to-v3.py @@ -0,0 +1,48 @@ +import os + +from dotenv import load_dotenv + +# pylint: disable=no-name-in-module +from iota_sdk import (ClientOptions, CoinType, StrongholdSecretManager, Wallet, WalletOptions, Bip44, + migrate_stronghold_snapshot_v2_to_v3) + +load_dotenv() + +v2_path = "../../../sdk/tests/wallet/fixtures/v2.stronghold" +v3_path = "./v3.stronghold" +node_url = os.environ.get('NODE_URL', 'https://api.testnet.shimmer.network') +client_options = ClientOptions(nodes=[node_url]) +bib_path = Bip44( + coin_type=CoinType.SHIMMER +) + + +try: + secret_manager = StrongholdSecretManager(v2_path, "current_password") + # This should fail with error, migration required. + + wallet_options = WalletOptions( + None, + None, + bib_path, + client_options, + secret_manager, + os.environ.get('WALLET_DB_PATH')) + wallet = Wallet(wallet_options) +except ValueError as e: + print(e) + +migrate_stronghold_snapshot_v2_to_v3( + v2_path, + "current_password", + "wallet.rs", + 100, + v3_path, + "new_password") + +secret_manager = StrongholdSecretManager(v3_path, "new_password") + +wallet_options = WalletOptions(None, None, bib_path, client_options, secret_manager, os.environ.get('WALLET_DB_PATH')) + +# This shouldn't fail anymore as snapshot has been migrated. +wallet = Wallet(wallet_options) diff --git a/bindings/python/examples/wallet/offline_signing/0_generate_addresses.py b/bindings/python/examples/wallet/offline_signing/0_generate_addresses.py new file mode 100644 index 0000000000..71cbfcfd11 --- /dev/null +++ b/bindings/python/examples/wallet/offline_signing/0_generate_addresses.py @@ -0,0 +1,49 @@ +# Copyright 2023 IOTA Stiftung +# SPDX-License-Identifier: Apache-2.0 + +# In this example we create an account and store its addresses in a file which will be used later to find +# inputs. + +import json +import os + +from dotenv import load_dotenv + +from iota_sdk import ClientOptions, CoinType, StrongholdSecretManager, Wallet, WalletOptions, Bip44 + +load_dotenv() + +OFFLINE_WALLET_DB_PATH = "./wallet/offline_signing/example-offline-walletdb" +STRONGHOLD_SNAPSHOT_PATH = "./wallet/offline_signing/example.stronghold" +ADDRESSES_FILE_PATH = "./wallet/offline_signing/example.addresses.json" + + +node_url = os.environ.get('NODE_URL', 'https://api.testnet.shimmer.network') +offline_client_options = ClientOptions() + +for env_var in ['STRONGHOLD_PASSWORD', 'MNEMONIC']: + if env_var not in os.environ: + raise Exception(f'.env {env_var} is undefined, see .env.example') + +secret_manager = StrongholdSecretManager( + STRONGHOLD_SNAPSHOT_PATH, os.environ['STRONGHOLD_PASSWORD']) + +bib_path = Bip44( + coin_type=CoinType.SHIMMER +) + +wallet_options = WalletOptions(None, None, bib_path, offline_client_options, secret_manager, OFFLINE_WALLET_DB_PATH) +wallet = Wallet(wallet_options) + +# Store the mnemonic in the Stronghold snapshot, this only needs to be +# done once +wallet.store_mnemonic(os.environ['MNEMONIC']) + +# Get the address from the wallet +address = wallet.address() + +json_data = json.dumps(list(map(lambda x: x.__dict__, address)), indent=4) +print(f"example.addresses.json:\n{json_data}") +f = open(ADDRESSES_FILE_PATH, "w", encoding="utf-8") +f.write(json_data) +f.close() diff --git a/bindings/python/examples/wallet/offline_signing/1_prepare_transaction.py b/bindings/python/examples/wallet/offline_signing/1_prepare_transaction.py new file mode 100644 index 0000000000..252fcbb3f6 --- /dev/null +++ b/bindings/python/examples/wallet/offline_signing/1_prepare_transaction.py @@ -0,0 +1,54 @@ +# Copyright 2023 IOTA Stiftung +# SPDX-License-Identifier: Apache-2.0 + +# In this example we will get inputs and prepare a transaction. + +import json +import os + +from dacite import from_dict +from dotenv import load_dotenv + +from iota_sdk import (AccountAddress, ClientOptions, CoinType, SendParams, + Wallet, WalletOptions, Bip44) + +load_dotenv() + +ONLINE_WALLET_DB_PATH = "./wallet/offline_signing/example-online-walletdb" +ADDRESSES_FILE_PATH = "./wallet/offline_signing/example.addresses.json" +PREPARED_TRANSACTION_FILE_PATH = "./wallet/offline_signing/example.prepared_transaction.json" +# Address to which we want to send the amount. +RECV_ADDRESS = "rms1qpszqzadsym6wpppd6z037dvlejmjuke7s24hm95s9fg9vpua7vluaw60xu" +# The amount to send. +SEND_AMOUNT = 1_000_000 + + +params = [SendParams(address=RECV_ADDRESS, amount=SEND_AMOUNT)] + +# Recovers addresses from example `0_address_generation`. +addresses_data = json.load(open(ADDRESSES_FILE_PATH, "r", encoding="utf-8")) +addresses = list(map(lambda x: from_dict( + data_class=AccountAddress, data=x), addresses_data)) + +if 'NODE_URL' not in os.environ: + raise Exception(".env NODE_URL is undefined, see .env.example") + +client_options = ClientOptions(nodes=[os.environ.get('NODE_URL')]) + +bib_path = Bip44( + coin_type=CoinType.SHIMMER +) +wallet_options = WalletOptions(None, None, bib_path, client_options, "placeholder", ONLINE_WALLET_DB_PATH) +wallet = Wallet(wallet_options) + +wallet.sync() + +prepared_transaction = wallet.prepare_send(params) + +json_data = json.dumps( + prepared_transaction.prepared_transaction_data().to_dict(), + indent=4) +print(f"example.prepared_transaction.json:\n{json_data}") +f = open(PREPARED_TRANSACTION_FILE_PATH, "w", encoding="utf-8") +f.write(json_data) +f.close() diff --git a/bindings/python/examples/wallet/offline_signing/2_sign_transaction.py b/bindings/python/examples/wallet/offline_signing/2_sign_transaction.py new file mode 100644 index 0000000000..1a30f5c14d --- /dev/null +++ b/bindings/python/examples/wallet/offline_signing/2_sign_transaction.py @@ -0,0 +1,44 @@ +# Copyright 2023 IOTA Stiftung +# SPDX-License-Identifier: Apache-2.0 + +# In this example we sign the prepared transaction. + +import json +import os + +from dacite import from_dict +from dotenv import load_dotenv + +from iota_sdk import PreparedTransactionData, Wallet, WalletOptions + +load_dotenv() + +OFFLINE_WALLET_DB_PATH = "./wallet/offline_signing/example-offline-walletdb" +STRONGHOLD_SNAPSHOT_PATH = "./wallet/offline_signing/example.stronghold" +PREPARED_TRANSACTION_FILE_PATH = "./wallet/offline_signing/example.prepared_transaction.json" +SIGNED_TRANSACTION_FILE_PATH = "./wallet/offline_signing/example.signed_transaction.json" + + +prepared_transaction_data = json.load( + open(PREPARED_TRANSACTION_FILE_PATH, "r", encoding="utf-8")) +prepared_transaction_data = from_dict( + PreparedTransactionData, prepared_transaction_data) + +wallet = Wallet(WalletOptions(storage_path=OFFLINE_WALLET_DB_PATH)) + +if 'STRONGHOLD_PASSWORD' not in os.environ: + raise Exception(".env STRONGHOLD_PASSWORD is undefined, see .env.example") + +wallet.set_stronghold_password(os.environ["STRONGHOLD_PASSWORD"]) + +# Signs prepared transaction offline. +signed_transaction_data = wallet.sign_transaction( + prepared_transaction_data) + +print("Signed transaction.") + +json_data = json.dumps(signed_transaction_data.to_dict(), indent=4) +print(f"example.signed_transaction.json:\n{json_data}") +f = open(SIGNED_TRANSACTION_FILE_PATH, "w", encoding="utf-8") +f.write(json_data) +f.close() diff --git a/bindings/python/examples/wallet/offline_signing/3_send_transaction.py b/bindings/python/examples/wallet/offline_signing/3_send_transaction.py new file mode 100644 index 0000000000..4cba62f441 --- /dev/null +++ b/bindings/python/examples/wallet/offline_signing/3_send_transaction.py @@ -0,0 +1,35 @@ +# Copyright 2023 IOTA Stiftung +# SPDX-License-Identifier: Apache-2.0 + +# In this example we send the signed transaction in a block. + +import json +import os + +from dacite import from_dict +from dotenv import load_dotenv + +from iota_sdk import SignedTransactionData, Wallet, WalletOptions + +load_dotenv() + +ONLINE_WALLET_DB_PATH = "./wallet/offline_signing/example-online-walletdb" +SIGNED_TRANSACTION_FILE_PATH = "./wallet/offline_signing/example.signed_transaction.json" + +if 'EXPLORER_URL' not in os.environ: + raise Exception(".env EXPLORER_URL is undefined, see .env.example") + +wallet = Wallet(WalletOptions(storage_path=ONLINE_WALLET_DB_PATH)) + +signed_transaction_data = json.load( + open(SIGNED_TRANSACTION_FILE_PATH, "r", encoding="utf-8")) +signed_transaction_data = from_dict( + SignedTransactionData, signed_transaction_data) + +# Sends offline signed transaction online. +transaction = wallet.submit_and_store_transaction(signed_transaction_data) +print( + f'Transaction sent: {os.environ["EXPLORER_URL"]}/transaction/{transaction.transaction_id}') +block_id = wallet.reissue_transaction_until_included( + transaction.transaction_id) +print(f'Block included: {os.environ["EXPLORER_URL"]}/block/{block_id}') diff --git a/bindings/python/examples/wallet/restore_backup.py b/bindings/python/examples/wallet/restore_backup.py new file mode 100644 index 0000000000..2439262fc7 --- /dev/null +++ b/bindings/python/examples/wallet/restore_backup.py @@ -0,0 +1,27 @@ +import json +import os + +from dotenv import load_dotenv + +from iota_sdk import ClientOptions, CoinType, Wallet, WalletOptions, Bip44 + +load_dotenv() + +# This example restores the wallet from a stronghold. + +node_url = os.environ.get('NODE_URL', 'https://api.testnet.shimmer.network') +client_options = ClientOptions(nodes=[node_url]) + +bib_path = Bip44( + coin_type=CoinType.SHIMMER +) + +wallet_options = WalletOptions(None, None, bib_path, client_options, 'Placeholder', './restore-backup-database') +wallet = Wallet(wallet_options) + +if 'STRONGHOLD_PASSWORD' not in os.environ: + raise Exception(".env STRONGHOLD_PASSWORD is undefined, see .env.example") + +wallet.restore_backup("backup.stronghold", os.environ['STRONGHOLD_PASSWORD']) + +print(f'Restored wallet: {json.dumps(wallet, indent=4)}') diff --git a/bindings/python/examples/wallet/transaction_options.py b/bindings/python/examples/wallet/transaction_options.py new file mode 100644 index 0000000000..8055406e3a --- /dev/null +++ b/bindings/python/examples/wallet/transaction_options.py @@ -0,0 +1,36 @@ +import os + +from dotenv import load_dotenv + +from iota_sdk import (RemainderValueStrategy, TaggedDataPayload, SendParams, + TransactionOptions, Wallet, WalletOptions, utf8_to_hex) + +load_dotenv() + +# This example sends a transaction with a tagged data payload. + +wallet = Wallet(WalletOptions(storage_path=os.environ.get('WALLET_DB_PATH'))) + +# Sync account with the node +response = wallet.sync() + +if 'STRONGHOLD_PASSWORD' not in os.environ: + raise Exception(".env STRONGHOLD_PASSWORD is undefined, see .env.example") + +wallet.set_stronghold_password(os.environ["STRONGHOLD_PASSWORD"]) + +params = [SendParams( + address="rms1qpszqzadsym6wpppd6z037dvlejmjuke7s24hm95s9fg9vpua7vluaw60xu", + amount=1000000, +)] + +transaction = wallet.send_with_params( + params, + TransactionOptions( + remainder_value_strategy=RemainderValueStrategy.ReuseAddress, + note="my first tx", + tagged_data_payload=TaggedDataPayload( + utf8_to_hex("tag"), + utf8_to_hex("data")))) +print(transaction) +print(f'Block sent: {os.environ["EXPLORER_URL"]}/block/{transaction.block_id}') diff --git a/sdk/examples/how_tos/account/implicit_account_creation.rs b/sdk/examples/how_tos/account/implicit_account_creation.rs index eada8b3bfb..9f565da0b8 100644 --- a/sdk/examples/how_tos/account/implicit_account_creation.rs +++ b/sdk/examples/how_tos/account/implicit_account_creation.rs @@ -19,11 +19,6 @@ async fn main() -> Result<()> { //  This example uses secrets in environment variables for simplicity which should not be done in production. dotenvy::dotenv().ok(); - #[allow(clippy::single_element_loop)] - for var in ["MNEMONIC"] { - std::env::var(var).unwrap_or_else(|_| panic!(".env variable '{var}' is undefined, see .env.example")); - } - let secret_manager = SecretManager::try_from_mnemonic(std::env::var("MNEMONIC").unwrap())?; let client_options = ClientOptions::new().with_node("https://api.testnet.shimmer.network")?; @@ -37,7 +32,7 @@ async fn main() -> Result<()> { let implicit_account_creation_address = wallet.implicit_account_creation_address().await?; - println!("Fund the following address: {implicit_account_creation_address}"); + println!("{implicit_account_creation_address}"); Ok(()) } From 7bcf247ef2a04b07ddfa5e689d0f4574c0d45677 Mon Sep 17 00:00:00 2001 From: Brord van Wierst Date: Wed, 20 Dec 2023 10:20:47 +0100 Subject: [PATCH 30/34] revert part of revert again :D --- Cargo.lock | 6 +++--- bindings/python/examples/client/04_get_output.py | 2 +- bindings/python/examples/how_tos/account_output/create.py | 3 --- bindings/python/examples/how_tos/account_output/destroy.py | 3 --- .../python/examples/how_tos/account_wallet/request_funds.py | 4 ++++ .../how_tos/accounts_and_addresses/create_address.py | 5 +++-- .../how_tos/accounts_and_addresses/create_wallet.py | 4 ++++ yarn.lock | 4 ++++ 8 files changed, 19 insertions(+), 12 deletions(-) create mode 100644 yarn.lock diff --git a/Cargo.lock b/Cargo.lock index 1441dcb0a2..516b0c9c6b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1696,7 +1696,7 @@ dependencies = [ [[package]] name = "iota-sdk-python" -version = "1.1.1" +version = "1.1.2" dependencies = [ "futures", "iota-sdk-bindings-core", @@ -2464,7 +2464,7 @@ dependencies = [ "proc-macro2", "pyo3-macros-backend", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -2476,7 +2476,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] diff --git a/bindings/python/examples/client/04_get_output.py b/bindings/python/examples/client/04_get_output.py index 7c3b10e87d..8e1edde5ec 100644 --- a/bindings/python/examples/client/04_get_output.py +++ b/bindings/python/examples/client/04_get_output.py @@ -14,5 +14,5 @@ # Get an outputs by its id output_with_metadata = client.get_output( - '0x022aefa73dff09b35b21ab5493412b0d354ad07a970a12b71e8087c6f3a7b8660000') + '0x022aefa73dff09b35b21ab5493412b0d354ad07a970a12b71e8087c6f3a7b866000000000000') print(json.dumps(output_with_metadata.to_dict(), indent=4)) diff --git a/bindings/python/examples/how_tos/account_output/create.py b/bindings/python/examples/how_tos/account_output/create.py index 6fa19f0d6a..a162f62b4e 100644 --- a/bindings/python/examples/how_tos/account_output/create.py +++ b/bindings/python/examples/how_tos/account_output/create.py @@ -19,9 +19,6 @@ balance = wallet.sync() print(f'Accounts BEFORE: {balance.accounts}') -if 'STRONGHOLD_PASSWORD' not in os.environ: - raise Exception(".env STRONGHOLD_PASSWORD is undefined, see .env.example") - wallet.set_stronghold_password(os.environ["STRONGHOLD_PASSWORD"]) # Send transaction. diff --git a/bindings/python/examples/how_tos/account_output/destroy.py b/bindings/python/examples/how_tos/account_output/destroy.py index fadc4a077e..0b84209623 100644 --- a/bindings/python/examples/how_tos/account_output/destroy.py +++ b/bindings/python/examples/how_tos/account_output/destroy.py @@ -20,9 +20,6 @@ # We try to destroy the first account in the wallet account_id = balance.accounts[0] -if 'STRONGHOLD_PASSWORD' not in os.environ: - raise Exception(".env STRONGHOLD_PASSWORD is undefined, see .env.example") - wallet.set_stronghold_password(os.environ["STRONGHOLD_PASSWORD"]) # Send transaction. diff --git a/bindings/python/examples/how_tos/account_wallet/request_funds.py b/bindings/python/examples/how_tos/account_wallet/request_funds.py index b37b1a05f4..c8cbb2ab77 100644 --- a/bindings/python/examples/how_tos/account_wallet/request_funds.py +++ b/bindings/python/examples/how_tos/account_wallet/request_funds.py @@ -9,6 +9,10 @@ load_dotenv() +for env_var in ['FAUCET_URL', 'WALLET_DB_PATH', 'EXPLORER_URL']: + if env_var not in os.environ: + raise Exception(f".env {env_var} is undefined, see .env.example") + FAUCET_URL = os.environ.get( 'FAUCET_URL', 'https://faucet.testnet.shimmer.network/api/enqueue') diff --git a/bindings/python/examples/how_tos/accounts_and_addresses/create_address.py b/bindings/python/examples/how_tos/accounts_and_addresses/create_address.py index 2ba5fc678c..929385a8d4 100644 --- a/bindings/python/examples/how_tos/accounts_and_addresses/create_address.py +++ b/bindings/python/examples/how_tos/accounts_and_addresses/create_address.py @@ -8,8 +8,9 @@ # This example generates a new address. -if 'STRONGHOLD_PASSWORD' not in os.environ: - raise Exception(".env STRONGHOLD_PASSWORD is undefined, see .env.example") +for env_var in ['STRONGHOLD_PASSWORD', 'STRONGHOLD_SNAPSHOT_PATH']: + if env_var not in os.environ: + raise Exception(f".env {env_var} is undefined, see .env.example") secret_manager = SecretManager(StrongholdSecretManager( os.environ.get('STRONGHOLD_SNAPSHOT_PATH'), diff --git a/bindings/python/examples/how_tos/accounts_and_addresses/create_wallet.py b/bindings/python/examples/how_tos/accounts_and_addresses/create_wallet.py index 0f0a1cfc2f..70ea75d8b7 100644 --- a/bindings/python/examples/how_tos/accounts_and_addresses/create_wallet.py +++ b/bindings/python/examples/how_tos/accounts_and_addresses/create_wallet.py @@ -34,3 +34,7 @@ secret_manager, os.environ.get('WALLET_DB_PATH')) wallet = Wallet(wallet_options) + +# Update the wallet to the latest state +balance = wallet.sync() +print('Generated new wallet') \ No newline at end of file diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000000..fb57ccd13a --- /dev/null +++ b/yarn.lock @@ -0,0 +1,4 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + From aff8f3d141be808650c537b6eeb501c3e3842f00 Mon Sep 17 00:00:00 2001 From: Brord van Wierst Date: Wed, 20 Dec 2023 10:28:28 +0100 Subject: [PATCH 31/34] newline --- .../examples/how_tos/accounts_and_addresses/create_wallet.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bindings/python/examples/how_tos/accounts_and_addresses/create_wallet.py b/bindings/python/examples/how_tos/accounts_and_addresses/create_wallet.py index 70ea75d8b7..e0a4dc701c 100644 --- a/bindings/python/examples/how_tos/accounts_and_addresses/create_wallet.py +++ b/bindings/python/examples/how_tos/accounts_and_addresses/create_wallet.py @@ -37,4 +37,4 @@ # Update the wallet to the latest state balance = wallet.sync() -print('Generated new wallet') \ No newline at end of file +print('Generated new wallet') From e5ca71384084dfb495a54a5f9694b81ad3644e2a Mon Sep 17 00:00:00 2001 From: Thibault Martinez Date: Wed, 20 Dec 2023 12:25:21 +0100 Subject: [PATCH 32/34] Lint/fmt examples --- .../how_tos/accounts_and_addresses/create_wallet.py | 2 +- bindings/python/examples/wallet/backup.py | 8 +++++++- bindings/python/examples/wallet/getting_started.py | 7 ++++++- bindings/python/examples/wallet/logger.py | 8 +++++++- .../wallet/migrate-stronghold-snapshot-v2-to-v3.py | 8 +++++++- .../wallet/offline_signing/0_generate_addresses.py | 8 +++++++- .../wallet/offline_signing/1_prepare_transaction.py | 8 +++++++- bindings/python/examples/wallet/restore_backup.py | 8 +++++++- 8 files changed, 49 insertions(+), 8 deletions(-) diff --git a/bindings/python/examples/how_tos/accounts_and_addresses/create_wallet.py b/bindings/python/examples/how_tos/accounts_and_addresses/create_wallet.py index e0a4dc701c..c956909b76 100644 --- a/bindings/python/examples/how_tos/accounts_and_addresses/create_wallet.py +++ b/bindings/python/examples/how_tos/accounts_and_addresses/create_wallet.py @@ -2,7 +2,7 @@ from dotenv import load_dotenv -from iota_sdk import ClientOptions, CoinType, StrongholdSecretManager, Wallet, WalletOptions, Bip44 +from iota_sdk import ClientOptions, CoinType, StrongholdSecretManager, SecretManager, Wallet, WalletOptions, Bip44 load_dotenv() diff --git a/bindings/python/examples/wallet/backup.py b/bindings/python/examples/wallet/backup.py index b5184c0fa0..9c8c9f6ba2 100644 --- a/bindings/python/examples/wallet/backup.py +++ b/bindings/python/examples/wallet/backup.py @@ -22,7 +22,13 @@ coin_type=CoinType.SHIMMER ) -wallet_options = WalletOptions(None, None, bib_path, client_options, secret_manager, './backup-database') +wallet_options = WalletOptions( + None, + None, + bib_path, + client_options, + secret_manager, + './backup-database') wallet = Wallet(wallet_options) # Store the mnemonic in the Stronghold snapshot, this only needs to be diff --git a/bindings/python/examples/wallet/getting_started.py b/bindings/python/examples/wallet/getting_started.py index c22d0a2fee..bf4e077f69 100644 --- a/bindings/python/examples/wallet/getting_started.py +++ b/bindings/python/examples/wallet/getting_started.py @@ -41,7 +41,12 @@ bib_path = Bip44( coin_type=CoinType.SHIMMER ) -wallet_options = WalletOptions(None, None, bib_path, client_options, secret_manager) +wallet_options = WalletOptions( + None, + None, + bib_path, + client_options, + secret_manager) wallet = Wallet(wallet_options) diff --git a/bindings/python/examples/wallet/logger.py b/bindings/python/examples/wallet/logger.py index 1b7d998094..0ea4a0313b 100644 --- a/bindings/python/examples/wallet/logger.py +++ b/bindings/python/examples/wallet/logger.py @@ -36,7 +36,13 @@ coin_type=CoinType.SHIMMER ) -wallet_options = WalletOptions(None, None, bib_path, client_options, secret_manager, os.environ.get('WALLET_DB_PATH')) +wallet_options = WalletOptions( + None, + None, + bib_path, + client_options, + secret_manager, + os.environ.get('WALLET_DB_PATH')) wallet = Wallet(wallet_options) # Store the mnemonic in the Stronghold snapshot, this only needs to be diff --git a/bindings/python/examples/wallet/migrate-stronghold-snapshot-v2-to-v3.py b/bindings/python/examples/wallet/migrate-stronghold-snapshot-v2-to-v3.py index 3b36d76374..2e79b52205 100644 --- a/bindings/python/examples/wallet/migrate-stronghold-snapshot-v2-to-v3.py +++ b/bindings/python/examples/wallet/migrate-stronghold-snapshot-v2-to-v3.py @@ -42,7 +42,13 @@ secret_manager = StrongholdSecretManager(v3_path, "new_password") -wallet_options = WalletOptions(None, None, bib_path, client_options, secret_manager, os.environ.get('WALLET_DB_PATH')) +wallet_options = WalletOptions( + None, + None, + bib_path, + client_options, + secret_manager, + os.environ.get('WALLET_DB_PATH')) # This shouldn't fail anymore as snapshot has been migrated. wallet = Wallet(wallet_options) diff --git a/bindings/python/examples/wallet/offline_signing/0_generate_addresses.py b/bindings/python/examples/wallet/offline_signing/0_generate_addresses.py index 71cbfcfd11..0c2adfbfcb 100644 --- a/bindings/python/examples/wallet/offline_signing/0_generate_addresses.py +++ b/bindings/python/examples/wallet/offline_signing/0_generate_addresses.py @@ -32,7 +32,13 @@ coin_type=CoinType.SHIMMER ) -wallet_options = WalletOptions(None, None, bib_path, offline_client_options, secret_manager, OFFLINE_WALLET_DB_PATH) +wallet_options = WalletOptions( + None, + None, + bib_path, + offline_client_options, + secret_manager, + OFFLINE_WALLET_DB_PATH) wallet = Wallet(wallet_options) # Store the mnemonic in the Stronghold snapshot, this only needs to be diff --git a/bindings/python/examples/wallet/offline_signing/1_prepare_transaction.py b/bindings/python/examples/wallet/offline_signing/1_prepare_transaction.py index 252fcbb3f6..a36263fd4b 100644 --- a/bindings/python/examples/wallet/offline_signing/1_prepare_transaction.py +++ b/bindings/python/examples/wallet/offline_signing/1_prepare_transaction.py @@ -38,7 +38,13 @@ bib_path = Bip44( coin_type=CoinType.SHIMMER ) -wallet_options = WalletOptions(None, None, bib_path, client_options, "placeholder", ONLINE_WALLET_DB_PATH) +wallet_options = WalletOptions( + None, + None, + bib_path, + client_options, + "placeholder", + ONLINE_WALLET_DB_PATH) wallet = Wallet(wallet_options) wallet.sync() diff --git a/bindings/python/examples/wallet/restore_backup.py b/bindings/python/examples/wallet/restore_backup.py index 2439262fc7..4e18db71b7 100644 --- a/bindings/python/examples/wallet/restore_backup.py +++ b/bindings/python/examples/wallet/restore_backup.py @@ -16,7 +16,13 @@ coin_type=CoinType.SHIMMER ) -wallet_options = WalletOptions(None, None, bib_path, client_options, 'Placeholder', './restore-backup-database') +wallet_options = WalletOptions( + None, + None, + bib_path, + client_options, + 'Placeholder', + './restore-backup-database') wallet = Wallet(wallet_options) if 'STRONGHOLD_PASSWORD' not in os.environ: From 4315f0b616e796c60e9703d4569fdc709dac2027 Mon Sep 17 00:00:00 2001 From: Thibault Martinez Date: Wed, 20 Dec 2023 13:53:33 +0100 Subject: [PATCH 33/34] Remove root yarn.lock --- yarn.lock | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 yarn.lock diff --git a/yarn.lock b/yarn.lock deleted file mode 100644 index fb57ccd13a..0000000000 --- a/yarn.lock +++ /dev/null @@ -1,4 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - From 5da034426245a3a4b23ae71281dbfee20b3f7108 Mon Sep 17 00:00:00 2001 From: Thibault Martinez Date: Wed, 20 Dec 2023 14:03:14 +0100 Subject: [PATCH 34/34] SyncOptions wallet --- bindings/python/examples/how_tos/account_wallet/transaction.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bindings/python/examples/how_tos/account_wallet/transaction.py b/bindings/python/examples/how_tos/account_wallet/transaction.py index 89f4239586..edf07f1b0b 100644 --- a/bindings/python/examples/how_tos/account_wallet/transaction.py +++ b/bindings/python/examples/how_tos/account_wallet/transaction.py @@ -16,7 +16,7 @@ wallet.set_stronghold_password(os.environ["STRONGHOLD_PASSWORD"]) -sync_options = SyncOptions(account=WalletSyncOptions(basic_outputs=True)) +sync_options = SyncOptions(wallet=WalletSyncOptions(basic_outputs=True)) balance = wallet.sync(sync_options) total_base_token_balance = balance.base_coin.total