Skip to content

Commit

Permalink
Wen not ValueError: Circular reference detected
Browse files Browse the repository at this point in the history
  • Loading branch information
Thoralf-M committed Jun 20, 2023
1 parent dcf68dd commit d1a0a48
Show file tree
Hide file tree
Showing 6 changed files with 168 additions and 33 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from iota_sdk import Wallet
from iota_sdk import Wallet, TransactionOptions, TaggedDataPayload
from dotenv import load_dotenv
import os

Expand All @@ -23,5 +23,6 @@
"amount": "1000000",
}]

transaction = account.send_amount(outputs)
print(f'Block sent: {os.environ["EXPLORER_URL"]}/block/{transaction["blockId"]}')
transaction = account.send_amount(outputs, TransactionOptions(note="my first tx", tagged_data_payload=TaggedDataPayload("tag", "data")))
print(transaction)
# print(f'Block sent: {os.environ["EXPLORER_URL"]}/block/{transaction["blockId"]}')
2 changes: 2 additions & 0 deletions bindings/python/iota_sdk/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,7 @@
from .types.feature import *
from .types.native_token import *
from .types.output_id import *
from .types.payload import *
from .types.token_scheme import *
from .types.transaction_options import *
from .types.unlock_condition import *
63 changes: 63 additions & 0 deletions bindings/python/iota_sdk/types/payload.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Copyright 2023 IOTA Stiftung
# SPDX-License-Identifier: Apache-2.0

from enum import Enum
from typing import Any, Optional


class PayloadType(Enum):
TreasuryTransaction = 4
TaggedData = 5
Transaction = 6
Milestone = 7


class Payload():
def __init__(self, type, milestone: Optional[Any] = None, tagged_data=None, transaction=None, treasury_transaction: Optional[Any] = None):
"""Initialize a payload
"""
self.type = type
self.milestone = milestone
self.tagged_data = tagged_data
self.transaction = transaction
self.treasury_transaction = treasury_transaction

def as_dict(self):
config = {k: v for k, v in self.__dict__.items() if v != None}

config['type'] = config['type'].value

if 'sender' in config:
config['address'] = config.pop('sender').as_dict()

if 'issuer' in config:
config['address'] = config.pop('issuer').as_dict()

return config


class MilestonePayload(Payload):
def __init__(self, essence, signatures):
"""Initialize a MilestonePayload
"""
self.essence = essence
self.signatures = signatures
super().__init__(PayloadType.Milestone, milestone=self)


class TaggedDataPayload(Payload):
def __init__(self, tag, data):
"""Initialize a TaggedDataPayload
"""
self.tag = tag
self.data = data
super().__init__(PayloadType.TaggedData, tagged_data=self)


class TransactionPayload(Payload):
def __init__(self, essence, unlocks):
"""Initialize a TransactionPayload
"""
self.essence = essence
self.unlocks = unlocks
super().__init__(PayloadType.Transaction, transaction=self)
64 changes: 64 additions & 0 deletions bindings/python/iota_sdk/types/transaction_options.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Copyright 2023 IOTA Stiftung
# SPDX-License-Identifier: Apache-2.0

from iota_sdk.types.burn import Burn
from iota_sdk.types.output_id import OutputId
from iota_sdk.types.payload import TaggedDataPayload
from enum import Enum
from typing import Optional, List

class AccountAddress:
def __int__(self,
address: str,
key_index: int,
internal: bool,
used: bool):
self.address = address
self.keyIndex = key_index
self.internal = internal
self.used = used


class CustomAddress(Enum):
AccountAddress=AccountAddress

class RemainderValueStrategy(Enum):
ChangeAddress = "ChangeAddress",
ReuseAddress = "ReuseAddress",
CustomAddress = CustomAddress

def __int__(self):
return self.value


class TransactionOptions():
def __init__(self, remainder_value_strategy: RemainderValueStrategy = RemainderValueStrategy.ReuseAddress,
tagged_data_payload: Optional[TaggedDataPayload] = None,
custom_inputs: Optional[List[OutputId]] = None,
mandatory_inputs: Optional[List[OutputId]] = None,
burn: Optional[Burn] = None,
note: Optional[str] = None,
allow_micro_amount: Optional[bool] = None):
"""Initialize TransactionOptions
"""
self.remainder_value_strategy = remainder_value_strategy
self.tagged_data_payload = tagged_data_payload
self.custom_inputs = custom_inputs
self.mandatory_inputs = mandatory_inputs
self.burn = burn
self.note = note
self.allow_micro_amount = allow_micro_amount

def as_dict(self):
config = dict(self.__dict__)

# config['type'] = config['type'].value

# if self.type == AddressType.ED25519:
# config['pubKeyHash'] = config.pop('address_or_id')
# elif self.type == AddressType.ALIAS:
# config['aliasId'] = config.pop('address_or_id')
# elif self.type == AddressType.NFT:
# config['nftId'] = config.pop('address_or_id')

return {k: v for k, v in config.items() if v}
55 changes: 28 additions & 27 deletions bindings/python/iota_sdk/wallet/account.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from iota_sdk.types.common import HexStr
from iota_sdk.types.native_token import NativeToken
from iota_sdk.types.output_id import OutputId
from iota_sdk.types.transaction_options import TransactionOptions
from typing import List, Optional


Expand Down Expand Up @@ -41,7 +42,7 @@ def _call_account_method(self, method, data=None):

return message

def prepare_burn(self, burn: Burn, options=None):
def prepare_burn(self, burn: Burn, options: Optional[TransactionOptions] = None):
"""
A generic `prepare_burn()` function that can be used to prepare the burn of native tokens, nfts, foundries and aliases.
"""
Expand All @@ -54,9 +55,9 @@ def prepare_burn(self, burn: Burn, options=None):
return PreparedTransactionData(self, prepared)

def prepare_burn_native_token(self,
token_id: HexStr,
burn_amount: int,
options=None):
token_id: HexStr,
burn_amount: int,
options: Optional[TransactionOptions] = None):
"""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.
Expand All @@ -70,8 +71,8 @@ def prepare_burn_native_token(self,
return PreparedTransactionData(self, prepared)

def prepare_burn_nft(self,
nft_id: HexStr,
options=None):
nft_id: HexStr,
options: Optional[TransactionOptions] = None):
"""Burn an nft output.
"""
prepared = self._call_account_method(
Expand All @@ -83,8 +84,8 @@ def prepare_burn_nft(self,
return PreparedTransactionData(self, prepared)

def prepare_consolidate_outputs(self,
force: bool,
output_consolidation_threshold: Optional[int] = None):
force: bool,
output_consolidation_threshold: Optional[int] = None):
"""Consolidate outputs.
"""
prepared = self._call_account_method(
Expand All @@ -96,8 +97,8 @@ def prepare_consolidate_outputs(self,
return PreparedTransactionData(self, prepared)

def prepare_create_alias_output(self,
params,
options):
params,
options: Optional[TransactionOptions] = None):
"""Create an alias output.
"""
prepared = self._call_account_method(
Expand All @@ -109,8 +110,8 @@ def prepare_create_alias_output(self,
return PreparedTransactionData(self, prepared)

def prepare_destroy_alias(self,
alias_id: HexStr,
options=None):
alias_id: HexStr,
options: Optional[TransactionOptions] = None):
"""Destroy an alias output.
"""

Expand All @@ -123,8 +124,8 @@ def prepare_destroy_alias(self,
return PreparedTransactionData(self, prepared)

def prepare_destroy_foundry(self,
foundry_id: HexStr,
options=None):
foundry_id: HexStr,
options: Optional[TransactionOptions] = None):
"""Destroy a foundry output with a circulating supply of 0.
"""
prepared = self._call_account_method(
Expand Down Expand Up @@ -226,9 +227,9 @@ def pending_transactions(self):
)

def prepare_decrease_native_token_supply(self,
token_id: HexStr,
melt_amount: int,
options=None):
token_id: HexStr,
melt_amount: int,
options: Optional[TransactionOptions] = None):
"""Melt native tokens. This happens with the foundry output which minted them, by increasing it's
`melted_tokens` field.
"""
Expand All @@ -241,7 +242,7 @@ def prepare_decrease_native_token_supply(self,
)
return PreparedTransactionData(self, prepared)

def prepare_increase_native_token_supply(self, token_id: HexStr, mint_amount: int, options=None):
def prepare_increase_native_token_supply(self, token_id: HexStr, mint_amount: int, options: Optional[TransactionOptions] = None):
"""Mint more native token.
"""
prepared = self._call_account_method(
Expand All @@ -253,7 +254,7 @@ def prepare_increase_native_token_supply(self, token_id: HexStr, mint_amount: in
)
return PreparedMintTokenTransaction(account=self, prepared_transaction_data=prepared)

def prepare_mint_native_token(self, params, options=None):
def prepare_mint_native_token(self, params, options: Optional[TransactionOptions] = None):
"""Mint native token.
"""
prepared = self._call_account_method(
Expand All @@ -273,7 +274,7 @@ def minimum_required_storage_deposit(self, output):
}
)

def prepare_mint_nfts(self, params, options=None):
def prepare_mint_nfts(self, params, options: Optional[TransactionOptions] = None):
"""Mint nfts.
"""
prepared = self._call_account_method(
Expand All @@ -291,7 +292,7 @@ def get_balance(self):
'getBalance'
)

def prepare_output(self, output_options, transaction_options=None):
def prepare_output(self, output_options, transaction_options: Optional[TransactionOptions] = None):
"""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
Expand All @@ -306,7 +307,7 @@ def prepare_output(self, output_options, transaction_options=None):
}
)

def prepare_send_amount(self, params, options=None):
def prepare_send_amount(self, params, options: Optional[TransactionOptions] = None):
"""Prepare send amount.
"""
prepared = self._call_account_method(
Expand All @@ -317,7 +318,7 @@ def prepare_send_amount(self, params, options=None):
)
return PreparedTransactionData(self, prepared)

def prepare_transaction(self, outputs, options=None):
def prepare_transaction(self, outputs, options: Optional[TransactionOptions] = None):
"""Prepare transaction.
"""
prepared = self._call_account_method(
Expand Down Expand Up @@ -351,7 +352,7 @@ def sync(self, options=None):
}
)

def send_amount(self, params, options=None):
def send_amount(self, params, options: Optional[TransactionOptions] = None):
"""Send amount.
"""
return self._call_account_method(
Expand All @@ -361,7 +362,7 @@ def send_amount(self, params, options=None):
}
)

def prepare_send_native_tokens(self, params, options=None):
def prepare_send_native_tokens(self, params, options: Optional[TransactionOptions] = None):
"""Send native tokens.
"""
prepared = self._call_account_method(
Expand All @@ -372,7 +373,7 @@ def prepare_send_native_tokens(self, params, options=None):
)
return PreparedTransactionData(self, prepared)

def prepare_send_nft(self, params, options=None):
def prepare_send_nft(self, params, options: Optional[TransactionOptions] = None):
"""Send nft.
"""
prepared = self._call_account_method(
Expand Down Expand Up @@ -438,7 +439,7 @@ def claim_outputs(self, output_ids_to_claim: List[OutputId]):
}
)

def send_outputs(self, outputs, options=None):
def send_outputs(self, outputs, options: Optional[TransactionOptions] = None):
"""Send outputs in a transaction.
"""
return self._call_account_method(
Expand Down
10 changes: 7 additions & 3 deletions bindings/python/iota_sdk/wallet/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,21 @@
# SPDX-License-Identifier: Apache-2.0

from iota_sdk import call_wallet_method
import humps
import json
from json import dumps
from json import dumps, JSONEncoder


def _call_method_routine(func):
"""The routine of dump json string and call call_wallet_method()
"""
def wrapper(*args, **kwargs):
message = func(*args, **kwargs)
message = dumps(message)
class MyEncoder(JSONEncoder):
def default(self, obj):
return humps.camelize({k: v for k, v in obj.__dict__.items() if v} )

message = func(*args, **kwargs)
message = dumps(message, cls=MyEncoder)
# Send message to the Rust library
response = call_wallet_method(args[0].handle, message)

Expand Down

0 comments on commit d1a0a48

Please sign in to comment.