Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Python: anchor related changes #1538

Merged
merged 6 commits into from
Oct 31, 2023
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 21 additions & 2 deletions bindings/python/iota_sdk/types/address.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@ class AddressType(IntEnum):
NFT (16): Nft address.
IMPLICIT_ACCOUNT_CREATION (24): Implicit Account Creation address.
RESTRICTED (40): Address with restricted capabilities.
ANCHOR (48): Anchor address.
"""
ED25519 = 0
ACCOUNT = 8
NFT = 16
IMPLICIT_ACCOUNT_CREATION = 24
RESTRICTED = 40
ANCHOR = 48


@json
Expand Down Expand Up @@ -88,7 +90,8 @@ def from_dict(addr_dict: dict):
"""
Creates an implicit account creation address from a dictionary representation.
"""
return ImplicitAccountCreationAddress(Ed25519Address(addr_dict['pubKeyHash']))
return ImplicitAccountCreationAddress(
Ed25519Address(addr_dict['pubKeyHash']))


@json
Expand All @@ -112,6 +115,20 @@ def with_allowed_capabilities(self, capabilities: bytes):
self.allowed_capabilities = '0x' + capabilities.hex()


@json
@dataclass
class AnchorAddress:
"""Represents an Anchor address.
Attributes:
anchor_id: The hex encoded anchor id.
"""
anchor_id: HexStr
type: int = field(
default_factory=lambda: int(
AddressType.ANCHOR),
init=False)


@json
@dataclass
class AddressWithUnspentOutputs():
Expand All @@ -124,7 +141,7 @@ class AddressWithUnspentOutputs():


Address: TypeAlias = Union[Ed25519Address, AccountAddress,
NFTAddress, ImplicitAccountCreationAddress, RestrictedAddress]
NFTAddress, ImplicitAccountCreationAddress, RestrictedAddress, AnchorAddress]


def deserialize_address(d: Dict[str, Any]) -> Address:
Expand All @@ -145,6 +162,8 @@ def deserialize_address(d: Dict[str, Any]) -> Address:
return ImplicitAccountCreationAddress.from_dict(d)
if address_type == AddressType.RESTRICTED:
return RestrictedAddress.from_dict(d)
if address_type == AddressType.ANCHOR:
return AnchorAddress.from_dict(d)
raise Exception(f'invalid address type: {address_type}')


Expand Down
65 changes: 63 additions & 2 deletions bindings/python/iota_sdk/types/output.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from iota_sdk.types.feature import deserialize_features, SenderFeature, IssuerFeature, MetadataFeature, TagFeature
from iota_sdk.types.native_token import NativeToken
from iota_sdk.types.token_scheme import SimpleTokenScheme
from iota_sdk.types.unlock_condition import deserialize_unlock_conditions, AddressUnlockCondition, StorageDepositReturnUnlockCondition, TimelockUnlockCondition, ExpirationUnlockCondition, ImmutableAccountAddressUnlockCondition
from iota_sdk.types.unlock_condition import deserialize_unlock_conditions, AddressUnlockCondition, StateControllerAddressUnlockCondition, GovernorAddressUnlockCondition, StorageDepositReturnUnlockCondition, TimelockUnlockCondition, ExpirationUnlockCondition, ImmutableAccountAddressUnlockCondition


class OutputType(IntEnum):
Expand All @@ -22,12 +22,14 @@ class OutputType(IntEnum):
Foundry (2): A foundry output.
Nft (3): An NFT output.
Delegation (4): A delegation output.
Anchor (5): An anchor output.
"""
Basic = 0
Account = 1
Foundry = 2
Nft = 3
Delegation = 4
Anchor = 5


@json
Expand Down Expand Up @@ -123,6 +125,63 @@ class AccountOutput:
init=False)


@json
@dataclass
class AnchorOutput:
"""Describes an anchor output.
Attributes:
amount :
The base coin amount of the output.
mana :
Amount of stored Mana held by this output.
unlock_conditions:
The conditions to unlock the output.
kwek20 marked this conversation as resolved.
Show resolved Hide resolved
anchor_id :
The anchor ID if it's an anchor output.
state_index :
A counter that must increase by 1 every time the anchor is state transitioned.
state_metadata :
Metadata that can only be changed by the state controller.
features :
Features that add utility to the output but do not impose unlocking conditions.
native_tokens :
Native tokens added to the new output.
immutable_features :
Features that add utility to the output but do not impose unlocking conditions. These features need to be kept in future transitions of the UTXO state machine.
type :
The type of output.
"""
amount: int = field(metadata=config(
encoder=str
))
mana: int = field(metadata=config(
encoder=str
))
anchor_id: HexStr
state_index: int
unlock_conditions: List[Union[StateControllerAddressUnlockCondition,
GovernorAddressUnlockCondition]] = field(
metadata=config(
decoder=deserialize_unlock_conditions
))
features: Optional[List[Union[SenderFeature,
MetadataFeature]]] = field(default=None,
metadata=config(
decoder=deserialize_features
))
immutable_features: Optional[List[Union[IssuerFeature,
MetadataFeature]]] = field(default=None,
metadata=config(
decoder=deserialize_features
))
state_metadata: Optional[HexStr] = None
native_tokens: Optional[List[NativeToken]] = None
type: int = field(
default_factory=lambda: int(
OutputType.Anchor),
init=False)


@json
@dataclass
class FoundryOutput:
Expand Down Expand Up @@ -246,7 +305,7 @@ class DelegationOutput:


Output: TypeAlias = Union[BasicOutput, AccountOutput,
FoundryOutput, NftOutput, DelegationOutput]
FoundryOutput, NftOutput, DelegationOutput, AnchorOutput]


def deserialize_output(d: Dict[str, Any]) -> Output:
Expand All @@ -267,6 +326,8 @@ def deserialize_output(d: Dict[str, Any]) -> Output:
return NftOutput.from_dict(d)
if output_type == OutputType.Delegation:
return DelegationOutput.from_dict(d)
if output_type == OutputType.Anchor:
return AnchorOutput.from_dict(d)
raise Exception(f'invalid output type: {output_type}')


Expand Down
28 changes: 23 additions & 5 deletions bindings/python/iota_sdk/types/unlock.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from __future__ import annotations
from dataclasses import dataclass, field
from enum import IntEnum
from typing import Dict, List, Union, Any
from typing import Dict, List, TypeAlias, Union, Any
from iota_sdk.types.signature import Ed25519Signature
from iota_sdk.types.common import json

Expand All @@ -17,11 +17,13 @@ class UnlockType(IntEnum):
Reference (1): An unlock which must reference a previous unlock which unlocks also the input at the same index as this Reference Unlock.
Account (2): An unlock which must reference a previous unlock which unlocks the account that the input is locked to.
Nft (3): An unlock which must reference a previous unlock which unlocks the NFT that the input is locked to.
Anchor (4): An unlock which must reference a previous unlock which unlocks the anchor that the input is locked to.
"""
Signature = 0
Reference = 1
Account = 2
Nft = 3
Anchor = 4


@json
Expand Down Expand Up @@ -77,8 +79,23 @@ class NftUnlock:
type: int = field(default_factory=lambda: int(UnlockType.Nft), init=False)


def deserialize_unlock(d: Dict[str, Any]) -> Union[SignatureUnlock,
ReferenceUnlock, AccountUnlock, NftUnlock]:
@json
@dataclass
class AnchorUnlock:
"""An unlock which must reference a previous unlock which unlocks the anchor that the input is locked to.
"""
reference: int
type: int = field(
default_factory=lambda: int(
UnlockType.Anchor),
init=False)


Unlock: TypeAlias = Union[SignatureUnlock,
ReferenceUnlock, AccountUnlock, NftUnlock, AnchorUnlock]


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.

Expand All @@ -94,11 +111,12 @@ def deserialize_unlock(d: Dict[str, Any]) -> Union[SignatureUnlock,
return AccountUnlock.from_dict(d)
if unlock_type == UnlockType.Nft:
return NftUnlock.from_dict(d)
if unlock_type == UnlockType.Anchor:
return AnchorUnlock.from_dict(d)
raise Exception(f'invalid unlock type: {unlock_type}')


def deserialize_unlocks(dicts: List[Dict[str, Any]]) -> List[Union[SignatureUnlock,
ReferenceUnlock, AccountUnlock, NftUnlock]]:
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.

Expand Down