def decode(string):
    """Decode Erlang external term."""
    if not string:
        raise IncompleteData(string)
    if string[0] != 131:
        raise ValueError("unknown protocol version: %r" % string[0])
    if string[1:2] == b'P':
        # compressed term
        if len(string) < 16:
            raise IncompleteData(string)
        d = decompressobj()
        term_string = d.decompress(string[6:]) + d.flush()
        uncompressed_size, = _int4_unpack(string[2:6])
        if len(term_string) != uncompressed_size:
            raise ValueError(
                "invalid compressed tag, "
                "%d bytes but got %d" % (uncompressed_size, len(term_string)))
        # tail data returned by decode_term() can be simple ignored
        term, _tail = decode_term(term_string)
        return term, d.unused_data
    return decode_term(string[1:])

def
decode
(
string
)
:
if
not
string
:
raise
IncompleteData
(
string
)
if
string
[
0
]
!=
131
:
raise
ValueError
(
"unknown protocol version: %r"
%
string
[
0
]
)
if
string
[
1
:
2
]
==
b'P'
:
if
len
(
string
)
<
16
:
raise
IncompleteData
(
string
)
d
=
decompressobj
(
)
term_string
=
d
.
decompress
(
string
[
6
:
]
)
+
d
.
flush
(
)
uncompressed_size
,
=
_int4_unpack
(
string
[
2
:
6
]
)
if
len
(
term_string
)
!=
uncompressed_size
:
raise
ValueError
(
"invalid compressed tag, "
"%d bytes but got %d"
%
(
uncompressed_size
,
len
(
term_string
)
)
)
term
,
_tail
=
decode_term
(
term_string
)
return
term
,
d
.
unused_data
return
decode_term
(
string
[
1
:
]
)


def encode(term, compressed=False):
    """Encode Erlang external term."""
    encoded_term = encode_term(term)
    # False and 0 do not attempt compression.
    if compressed:
        if compressed is True:
            # default compression level of 6
            compressed = 6
        elif compressed < 0 or compressed > 9:
            raise ValueError("invalid compression level: %r" % (compressed,))
        zlib_term = compress(encoded_term, compressed)
        ln = len(encoded_term)
        if len(zlib_term) + 5 <= ln:
            # Compressed term should be smaller
            return b"\x83P" + _int4_pack(ln) + zlib_term
    return b"\x83" + encoded_term

def
encode
(
term
,
compressed
=
False
)
:
encoded_term
=
encode_term
(
term
)
if
compressed
:
if
compressed
is
True
:
compressed
=
6
elif
compressed
<
0
or
compressed
>
9
:
raise
ValueError
(
"invalid compression level: %r"
%
(
compressed
,
)
)
zlib_term
=
compress
(
encoded_term
,
compressed
)
ln
=
len
(
encoded_term
)
if
len
(
zlib_term
)
+
5
<=
ln
:
return
b"\x83P"
+
_int4_pack
(
ln
)
+
zlib_term
return
b"\x83"
+
encoded_term


def addSourceAddr(self, addr):
        """None means 'system default'"""
        try:
            self._multiInSocket.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, self._makeMreq(addr))
        except socket.error:  # if 1 interface has more than 1 address, exception is raised for the second
            pass

        sock = self._createMulticastOutSocket(addr, self._observer.ttl)
        self._multiOutUniInSockets[addr] = sock
        self._poll.register(sock, select.POLLIN)

def addSourceAddr ( self , addr ) : try : self . _multiInSocket . setsockopt ( socket . IPPROTO_IP , socket . IP_ADD_MEMBERSHIP , self . _makeMreq ( addr ) ) except socket . error : pass sock = self . _createMulticastOutSocket ( addr , self . _observer . ttl ) self . _multiOutUniInSockets [ addr ] = sock self . _poll . register ( sock , select . POLLIN )


def _sendPendingMessages(self):
        """Method sleeps, if nothing to do"""
        if len(self._queue) == 0:
            time.sleep(0.1)
            return
        msg = self._queue.pop(0)
        if msg.canSend():
            self._sendMsg(msg)
            msg.refresh()
            if not (msg.isFinished()):
                self._queue.append(msg)
        else:
            self._queue.append(msg)
            time.sleep(0.01)

def _sendPendingMessages ( self ) : if len ( self . _queue ) == 0 : time . sleep ( 0.1 ) return msg = self . _queue . pop ( 0 ) if msg . canSend ( ) : self . _sendMsg ( msg ) msg . refresh ( ) if not ( msg . isFinished ( ) ) : self . _queue . append ( msg ) else : self . _queue . append ( msg ) time . sleep ( 0.01 )


def setRemoteServiceHelloCallback(self, cb, types=None, scopes=None):
        """Set callback, which will be called when new service appeared online
        and sent Hi message

        typesFilter and scopesFilter might be list of types and scopes.
        If filter is set, callback is called only for Hello messages,
        which match filter

        Set None to disable callback
        """
        self._remoteServiceHelloCallback = cb
        self._remoteServiceHelloCallbackTypesFilter = types
        self._remoteServiceHelloCallbackScopesFilter = scopes

def setRemoteServiceHelloCallback ( self , cb , types = None , scopes = None ) : self . _remoteServiceHelloCallback = cb self . _remoteServiceHelloCallbackTypesFilter = types self . _remoteServiceHelloCallbackScopesFilter = scopes

Set callback which will be called when new service appeared online and sent Hi message


def stop(self):
        'cleans up and stops the discovery server'

        self.clearRemoteServices()
        self.clearLocalServices()

        self._stopThreads()
        self._serverStarted = False


def clearLocalServices(self):
        'send Bye messages for the services and remove them'

        for service in list(self._localServices.values()):
            self._sendBye(service)

        self._localServices.clear()


def searchServices(self, types=None, scopes=None, timeout=3):
        'search for services given the TYPES and SCOPES in a given TIMEOUT'

        if not self._serverStarted:
            raise Exception("Server not started")

        self._sendProbe(types, scopes)

        time.sleep(timeout)

        return self._filterServices(list(self._remoteServices.values()), types, scopes)


def createSOAPMessage(env):
    "construct a a raw SOAP XML string, given a prepared SoapEnvelope object"
    if env.getAction() == ACTION_PROBE:
        return createProbeMessage(env)
    if env.getAction() == ACTION_PROBE_MATCH:
        return createProbeMatchMessage(env)
    if env.getAction() == ACTION_RESOLVE:
        return createResolveMessage(env)
    if env.getAction() == ACTION_RESOLVE_MATCH:
        return createResolveMatchMessage(env)
    if env.getAction() == ACTION_HELLO:
        return createHelloMessage(env)
    if env.getAction() == ACTION_BYE:
        return createByeMessage(env)

construct a a raw SOAP XML string given a prepared SoapEnvelope object


def discover(scope, loglevel, capture):
    "Discover systems using WS-Discovery"

    if loglevel:
        level = getattr(logging, loglevel, None)
        if not level:
           print("Invalid log level '%s'" % loglevel)
           return
        logger.setLevel(level)

    run(scope=scope, capture=capture)

def
discover
(
scope
,
loglevel
,
capture
)
:
"Discover systems using WS-Discovery"
if
loglevel
:
level
=
getattr
(
logging
,
loglevel
,
)
if
not
level
:
print
(
"Invalid log level '%s'"
%
loglevel
)
return
logger
.
setLevel
(
level
)
run
(
scope
=
scope
,
capture
=
capture
)


def get_tagged_item_manager(self):
        """Return the manager that handles the relation from this instance to the tagged_item class.
        If content_object on the tagged_item class is defined as a ParentalKey, this will be a
        DeferringRelatedManager which allows writing related objects without committing them
        to the database.
        """
        rel_name = self.through._meta.get_field('content_object').remote_field.get_accessor_name()
        return getattr(self.instance, rel_name)

def get_tagged_item_manager ( self ) : rel_name = self . through . _meta . get_field ( 'content_object' ) . remote_field . get_accessor_name ( ) return getattr ( self . instance , rel_name )

Return the manager that handles the relation from this instance to the tagged_item class . If content_object on the tagged_item class is defined as a ParentalKey this will be a DeferringRelatedManager which allows writing related objects without committing them to the database .


def get_all_child_relations(model):
    """
    Return a list of RelatedObject records for child relations of the given model,
    including ones attached to ancestors of the model
    """
    return [
        field for field in model._meta.get_fields()
        if isinstance(field.remote_field, ParentalKey)
    ]

def get_all_child_relations ( model ) : return [ field for field in model . _meta . get_fields ( ) if isinstance ( field . remote_field , ParentalKey ) ]

Return a list of RelatedObject records for child relations of the given model including ones attached to ancestors of the model


def get_all_child_m2m_relations(model):
    """
    Return a list of ParentalManyToManyFields on the given model,
    including ones attached to ancestors of the model
    """
    return [
        field for field in model._meta.get_fields()
        if isinstance(field, ParentalManyToManyField)
    ]

def get_all_child_m2m_relations ( model ) : return [ field for field in model . _meta . get_fields ( ) if isinstance ( field , ParentalManyToManyField ) ]

Return a list of ParentalManyToManyFields on the given model including ones attached to ancestors of the model


def save(self, **kwargs):
        """
        Save the model and commit all child relations.
        """
        child_relation_names = [rel.get_accessor_name() for rel in get_all_child_relations(self)]
        child_m2m_field_names = [field.name for field in get_all_child_m2m_relations(self)]

        update_fields = kwargs.pop('update_fields', None)
        if update_fields is None:
            real_update_fields = None
            relations_to_commit = child_relation_names
            m2m_fields_to_commit = child_m2m_field_names
        else:
            real_update_fields = []
            relations_to_commit = []
            m2m_fields_to_commit = []
            for field in update_fields:
                if field in child_relation_names:
                    relations_to_commit.append(field)
                elif field in child_m2m_field_names:
                    m2m_fields_to_commit.append(field)
                else:
                    real_update_fields.append(field)

        super(ClusterableModel, self).save(update_fields=real_update_fields, **kwargs)

        for relation in relations_to_commit:
            getattr(self, relation).commit()

        for field in m2m_fields_to_commit:
            getattr(self, field).commit()

def save ( self , ** kwargs ) : child_relation_names = [ rel . get_accessor_name ( ) for rel in get_all_child_relations ( self ) ] child_m2m_field_names = [ field . name for field in get_all_child_m2m_relations ( self ) ] update_fields = kwargs . pop ( 'update_fields' , None ) if update_fields is None : real_update_fields = None relations_to_commit = child_relation_names m2m_fields_to_commit = child_m2m_field_names else : real_update_fields = [ ] relations_to_commit = [ ] m2m_fields_to_commit = [ ] for field in update_fields : if field in child_relation_names : relations_to_commit . append ( field ) elif field in child_m2m_field_names : m2m_fields_to_commit . append ( field ) else : real_update_fields . append ( field ) super ( ClusterableModel , self ) . save ( update_fields = real_update_fields , ** kwargs ) for relation in relations_to_commit : getattr ( self , relation ) . commit ( ) for field in m2m_fields_to_commit : getattr ( self , field ) . commit ( )

Save the model and commit all child relations .


def from_serializable_data(cls, data, check_fks=True, strict_fks=False):
        """
        Build an instance of this model from the JSON-like structure passed in,
        recursing into related objects as required.
        If check_fks is true, it will check whether referenced foreign keys still
        exist in the database.
        - dangling foreign keys on related objects are dealt with by either nullifying the key or
        dropping the related object, according to the 'on_delete' setting.
        - dangling foreign keys on the base object will be nullified, unless strict_fks is true,
        in which case any dangling foreign keys with on_delete=CASCADE will cause None to be
        returned for the entire object.
        """
        obj = model_from_serializable_data(cls, data, check_fks=check_fks, strict_fks=strict_fks)
        if obj is None:
            return None

        child_relations = get_all_child_relations(cls)

        for rel in child_relations:
            rel_name = rel.get_accessor_name()
            try:
                child_data_list = data[rel_name]
            except KeyError:
                continue

            related_model = rel.related_model
            if hasattr(related_model, 'from_serializable_data'):
                children = [
                    related_model.from_serializable_data(child_data, check_fks=check_fks, strict_fks=True)
                    for child_data in child_data_list
                ]
            else:
                children = [
                    model_from_serializable_data(related_model, child_data, check_fks=check_fks, strict_fks=True)
                    for child_data in child_data_list
                ]

            children = filter(lambda child: child is not None, children)

            setattr(obj, rel_name, children)

        return obj

def from_serializable_data ( cls , data , check_fks = True , strict_fks = False ) : obj = model_from_serializable_data ( cls , data , check_fks = check_fks , strict_fks = strict_fks ) if obj is None : return None child_relations = get_all_child_relations ( cls ) for rel in child_relations : rel_name = rel . get_accessor_name ( ) try : child_data_list = data [ rel_name ] except KeyError : continue related_model = rel . related_model if hasattr ( related_model , 'from_serializable_data' ) : children = [ related_model . from_serializable_data ( child_data , check_fks = check_fks , strict_fks = True ) for child_data in child_data_list ] else : children = [ model_from_serializable_data ( related_model , child_data , check_fks = check_fks , strict_fks = True ) for child_data in child_data_list ] children = filter ( lambda child : child is not None , children ) setattr ( obj , rel_name , children ) return obj

Build an instance of this model from the JSON - like structure passed in recursing into related objects as required . If check_fks is true it will check whether referenced foreign keys still exist in the database . - dangling foreign keys on related objects are dealt with by either nullifying the key or dropping the related object according to the on_delete setting . - dangling foreign keys on the base object will be nullified unless strict_fks is true in which case any dangling foreign keys with on_delete = CASCADE will cause None to be returned for the entire object .


def validate_unique(self):
        '''This clean method will check for unique_together condition'''
        # Collect unique_checks and to run from all the forms.
        all_unique_checks = set()
        all_date_checks = set()
        forms_to_delete = self.deleted_forms
        valid_forms = [form for form in self.forms if form.is_valid() and form not in forms_to_delete]
        for form in valid_forms:
            unique_checks, date_checks = form.instance._get_unique_checks()
            all_unique_checks.update(unique_checks)
            all_date_checks.update(date_checks)

        errors = []
        # Do each of the unique checks (unique and unique_together)
        for uclass, unique_check in all_unique_checks:
            seen_data = set()
            for form in valid_forms:
                # Get the data for the set of fields that must be unique among the forms.
                row_data = (
                    field if field in self.unique_fields else form.cleaned_data[field]
                    for field in unique_check if field in form.cleaned_data
                )
                # Reduce Model instances to their primary key values
                row_data = tuple(d._get_pk_val() if hasattr(d, '_get_pk_val') else d
                                 for d in row_data)
                if row_data and None not in row_data:
                    # if we've already seen it then we have a uniqueness failure
                    if row_data in seen_data:
                        # poke error messages into the right places and mark
                        # the form as invalid
                        errors.append(self.get_unique_error_message(unique_check))
                        form._errors[NON_FIELD_ERRORS] = self.error_class([self.get_form_error()])
                        # remove the data from the cleaned_data dict since it was invalid
                        for field in unique_check:
                            if field in form.cleaned_data:
                                del form.cleaned_data[field]
                    # mark the data as seen
                    seen_data.add(row_data)

        if errors:
            raise ValidationError(errors)

def validate_unique ( self ) : all_unique_checks = set ( ) all_date_checks = set ( ) forms_to_delete = self . deleted_forms valid_forms = [ form for form in self . forms if form . is_valid ( ) and form not in forms_to_delete ] for form in valid_forms : unique_checks , date_checks = form . instance . _get_unique_checks ( ) all_unique_checks . update ( unique_checks ) all_date_checks . update ( date_checks ) errors = [ ] for uclass , unique_check in all_unique_checks : seen_data = set ( ) for form in valid_forms : row_data = ( field if field in self . unique_fields else form . cleaned_data [ field ] for field in unique_check if field in form . cleaned_data ) row_data = tuple ( d . _get_pk_val ( ) if hasattr ( d , '_get_pk_val' ) else d for d in row_data ) if row_data and None not in row_data : if row_data in seen_data : errors . append ( self . get_unique_error_message ( unique_check ) ) form . _errors [ NON_FIELD_ERRORS ] = self . error_class ( [ self . get_form_error ( ) ] ) for field in unique_check : if field in form . cleaned_data : del form . cleaned_data [ field ] seen_data . add ( row_data ) if errors : raise ValidationError ( errors )


def has_changed(self):
        """Return True if data differs from initial."""

        # Need to recurse over nested formsets so that the form is saved if there are changes
        # to child forms but not the parent
        if self.formsets:
            for formset in self.formsets.values():
                for form in formset.forms:
                    if form.has_changed():
                        return True
        return bool(self.changed_data)

def has_changed ( self ) : if self . formsets : for formset in self . formsets . values ( ) : for form in formset . forms : if form . has_changed ( ) : return True return bool ( self . changed_data )

Return True if data differs from initial .


def with_valid_checksum(self):
        # type: () -> Address
        """
        Returns the address with a valid checksum attached.
        """
        return Address(
            trytes=self.address + self._generate_checksum(),

            # Make sure to copy all of the ancillary attributes, too!
            balance=self.balance,
            key_index=self.key_index,
            security_level=self.security_level,
        )

def with_valid_checksum ( self ) : return Address ( trytes = self . address + self . _generate_checksum ( ) , balance = self . balance , key_index = self . key_index , security_level = self . security_level , )

Returns the address with a valid checksum attached .


def _generate_checksum(self):
        # type: () -> AddressChecksum
        """
        Generates the correct checksum for this address.
        """
        checksum_trits = []  # type: MutableSequence[int]

        sponge = Kerl()
        sponge.absorb(self.address.as_trits())
        sponge.squeeze(checksum_trits)

        checksum_length = AddressChecksum.LEN * TRITS_PER_TRYTE

        return AddressChecksum.from_trits(checksum_trits[-checksum_length:])

def _generate_checksum ( self ) : checksum_trits = [ ] sponge = Kerl ( ) sponge . absorb ( self . address . as_trits ( ) ) sponge . squeeze ( checksum_trits ) checksum_length = AddressChecksum . LEN * TRITS_PER_TRYTE return AddressChecksum . from_trits ( checksum_trits [ - checksum_length : ] )

Generates the correct checksum for this address .


def parse_argv(self, argv=None):
        # type: (Optional[tuple]) -> dict
        """
        Parses arguments for the command.

        :param argv:
            Arguments to pass to the argument parser.
            If ``None``, defaults to ``sys.argv[1:]``.
        """
        arguments = vars(self.create_argument_parser().parse_args(argv))

        seed = None
        if self.requires_seed:
            seed_filepath = arguments.pop('seed_file')

            seed = (
                self.seed_from_filepath(seed_filepath)
                if seed_filepath
                else self.prompt_for_seed()
            )

        arguments['api'] = Iota(
            adapter=arguments.pop('uri'),
            seed=seed,
            testnet=arguments.pop('testnet'),
        )

        return arguments

def parse_argv ( self , argv = None ) : arguments = vars ( self . create_argument_parser ( ) . parse_args ( argv ) ) seed = None if self . requires_seed : seed_filepath = arguments . pop ( 'seed_file' ) seed = ( self . seed_from_filepath ( seed_filepath ) if seed_filepath else self . prompt_for_seed ( ) ) arguments [ 'api' ] = Iota ( adapter = arguments . pop ( 'uri' ) , seed = seed , testnet = arguments . pop ( 'testnet' ) , ) return arguments


def create_argument_parser(self):
        # type: () -> ArgumentParser
        """
        Returns the argument parser that will be used to interpret
        arguments and options from argv.
        """
        parser = ArgumentParser(
            description=self.__doc__,
            epilog='PyOTA v{version}'.format(version=__version__),
        )

        parser.add_argument(
            '--uri',
            type=text_type,
            default='http://localhost:14265/',

            help=(
                'URI of the node to connect to '
                '(defaults to http://localhost:14265/).'
            ),
        )

        if self.requires_seed:
            parser.add_argument(
                '--seed-file',
                type=text_type,
                dest='seed_file',

                help=(
                    'Path to a file containing your seed in cleartext. '
                    'If not provided, you will be prompted to enter '
                    'your seed via stdin.'
                ),
            )

        parser.add_argument(
            '--testnet',
            action='store_true',
            default=False,
            help='If set, use testnet settings (e.g., for PoW).',
        )

        return parser

Returns the argument parser that will be used to interpret arguments and options from argv .


def prompt_for_seed():
        # type: () -> Seed
        """
        Prompts the user to enter their seed via stdin.
        """
        seed = secure_input(
            'Enter seed and press return (typing will not be shown).\n'
            'If no seed is specified, a random one will be used instead.\n'
        )

        if isinstance(seed, text_type):
            seed = seed.encode('ascii')

        return Seed(seed) if seed else Seed.random()

Prompts the user to enter their seed via stdin .


def validate_signature_fragments(
        fragments,
        hash_,
        public_key,
        sponge_type=Kerl,
):
    # type: (Sequence[TryteString], Hash, TryteString, type) -> bool
    """
    Returns whether a sequence of signature fragments is valid.

    :param fragments:
      Sequence of signature fragments (usually
      :py:class:`iota.transaction.Fragment` instances).

    :param hash_:
      Hash used to generate the signature fragments (usually a
      :py:class:`iota.transaction.BundleHash` instance).

    :param public_key:
      The public key value used to verify the signature digest (usually a
      :py:class:`iota.types.Address` instance).

    :param sponge_type:
      The class used to create the cryptographic sponge (i.e., Curl or Kerl).
    """
    checksum = [0] * (HASH_LENGTH * len(fragments))
    normalized_hash = normalize(hash_)

    for i, fragment in enumerate(fragments):
        outer_sponge = sponge_type()

        # If there are more than 3 iterations, loop back around to the
        # start.
        normalized_chunk = normalized_hash[i % len(normalized_hash)]

        buffer = []
        for j, hash_trytes in enumerate(fragment.iter_chunks(Hash.LEN)):
            buffer = hash_trytes.as_trits()  # type: List[int]
            inner_sponge = sponge_type()

            # Note the sign flip compared to
            # :py;class:`SignatureFragmentGenerator`.
            for _ in range(13 + normalized_chunk[j]):
                inner_sponge.reset()
                inner_sponge.absorb(buffer)
                inner_sponge.squeeze(buffer)

            outer_sponge.absorb(buffer)

        outer_sponge.squeeze(buffer)
        checksum[i * HASH_LENGTH:(i + 1) * HASH_LENGTH] = buffer

    actual_public_key = [0] * HASH_LENGTH
    addy_sponge = sponge_type()
    addy_sponge.absorb(checksum)
    addy_sponge.squeeze(actual_public_key)

    return actual_public_key == public_key.as_trits()

def validate_signature_fragments ( fragments , hash_ , public_key , sponge_type = Kerl , ) : checksum = [ 0 ] * ( HASH_LENGTH * len ( fragments ) ) normalized_hash = normalize ( hash_ ) for i , fragment in enumerate ( fragments ) : outer_sponge = sponge_type ( ) normalized_chunk = normalized_hash [ i % len ( normalized_hash ) ] buffer = [ ] for j , hash_trytes in enumerate ( fragment . iter_chunks ( Hash . LEN ) ) : buffer = hash_trytes . as_trits ( ) inner_sponge = sponge_type ( ) for _ in range ( 13 + normalized_chunk [ j ] ) : inner_sponge . reset ( ) inner_sponge . absorb ( buffer ) inner_sponge . squeeze ( buffer ) outer_sponge . absorb ( buffer ) outer_sponge . squeeze ( buffer ) checksum [ i * HASH_LENGTH : ( i + 1 ) * HASH_LENGTH ] = buffer actual_public_key = [ 0 ] * HASH_LENGTH addy_sponge = sponge_type ( ) addy_sponge . absorb ( checksum ) addy_sponge . squeeze ( actual_public_key ) return actual_public_key == public_key . as_trits ( )

Returns whether a sequence of signature fragments is valid .


def get_key(self, index, iterations):
        # type: (int, int) -> PrivateKey
        """
        Generates a single key.

        :param index:
            The key index.

        :param iterations:
            Number of transform iterations to apply to the key, also
            known as security level.
            Must be >= 1.

            Increasing this value makes key generation slower, but more
            resistant to brute-forcing.
        """
        return (
            self.get_keys(
                start=index,
                count=1,
                step=1,
                iterations=iterations,
            )[0]
        )

def get_key ( self , index , iterations ) : return ( self . get_keys ( start = index , count = 1 , step = 1 , iterations = iterations , ) [ 0 ] )


def get_key_for(self, address):
        """
        Generates the key associated with the specified address.

        Note that this method will generate the wrong key if the input
        address was generated from a different key!
        """
        return self.get_key(
            index=address.key_index,
            iterations=address.security_level,
        )

def get_key_for ( self , address ) : return self . get_key ( index = address . key_index , iterations = address . security_level , )

Generates the key associated with the specified address .


def create_iterator(self, start=0, step=1, security_level=1):
        # type: (int, int, int) -> KeyIterator
        """
        Creates a generator that can be used to progressively generate
        new keys.

        :param start:
            Starting index.

            Warning: This method may take awhile to reset if ``start``
            is a large number!

        :param step:
            Number of indexes to advance after each key.

            This value can be negative; the generator will exit if it
            reaches an index < 0.

            Warning: The generator may take awhile to advance between
            iterations if ``step`` is a large number!

        :param security_level:
            Number of _transform iterations to apply to each key.
            Must be >= 1.

            Increasing this value makes key generation slower, but more
            resistant to brute-forcing.
        """
        return KeyIterator(self.seed, start, step, security_level)

def create_iterator ( self , start = 0 , step = 1 , security_level = 1 ) : return KeyIterator ( self . seed , start , step , security_level )

Creates a generator that can be used to progressively generate new keys .


def _create_sponge(self, index):
        # type: (int) -> Kerl
        """
        Prepares the hash sponge for the generator.
        """
        seed = self.seed_as_trits[:]

        sponge = Kerl()
        sponge.absorb(add_trits(seed, trits_from_int(index)))

        # Squeeze all of the trits out of the sponge and re-absorb them.
        # Note that the sponge transforms several times per operation,
        # so this sequence is not as redundant as it looks at first
        # glance.
        sponge.squeeze(seed)
        sponge.reset()
        sponge.absorb(seed)

        return sponge

def _create_sponge ( self , index ) : seed = self . seed_as_trits [ : ] sponge = Kerl ( ) sponge . absorb ( add_trits ( seed , trits_from_int ( index ) ) ) sponge . squeeze ( seed ) sponge . reset ( ) sponge . absorb ( seed ) return sponge

Prepares the hash sponge for the generator .


def absorb(self, trits, offset=0, length=None):
        # type: (Sequence[int], Optional[int], Optional[int]) -> None
        """
        Absorb trits into the sponge.

        :param trits:
            Sequence of trits to absorb.

        :param offset:
            Starting offset in ``trits``.

        :param length:
            Number of trits to absorb.  Defaults to ``len(trits)``.
        """
        pad = ((len(trits) % HASH_LENGTH) or HASH_LENGTH)
        trits += [0] * (HASH_LENGTH - pad)

        if length is None:
            length = len(trits)

        if length < 1:
            raise with_context(
                exc=ValueError('Invalid length passed to ``absorb``.'),

                context={
                    'trits': trits,
                    'offset': offset,
                    'length': length,
                },
            )

        # Copy trits from ``trits`` into internal state, one hash at a
        # time, transforming internal state in between hashes.
        while offset < length:
            start = offset
            stop = min(start + HASH_LENGTH, length)

            # Copy the next hash worth of trits to internal state.
            #
            # Note that we always copy the trits to the start of the
            # state. ``self._state`` is 3 hashes long, but only the
            # first hash is "public"; the other 2 are only accessible to
            # :py:meth:`_transform`.
            self._state[0:stop - start] = trits[start:stop]

            # Transform.
            self._transform()

            # Move on to the next hash.
            offset += HASH_LENGTH

def
absorb
(
self
,
trits
,
offset
=
0
,
length
=
)
:
pad
=
(
(
len
(
trits
)
%
HASH_LENGTH
)
or
HASH_LENGTH
)
trits
+=
[
0
]
*
(
HASH_LENGTH
pad
)
if
length
is
:
length
=
len
(
trits
)
if
length
<
1
:
raise
with_context
(
exc
=
ValueError
(
'Invalid length passed to ``absorb``.'
)
,
context
=
{
'trits'
:
trits
,
'offset'
:
offset
,
'length'
:
length
,
}
,
)
while
offset
<
length
:
start
=
offset
stop
=
min
(
start
+
HASH_LENGTH
,
length
)
self
.
_state
[
0
:
stop
start
]
=
trits
[
start
:
stop
]
self
.
_transform
(
)
offset
+=
HASH_LENGTH


def squeeze(self, trits, offset=0, length=HASH_LENGTH):
        # type: (MutableSequence[int], Optional[int], Optional[int]) -> None
        """
        Squeeze trits from the sponge.

        :param trits:
            Sequence that the squeezed trits will be copied to.
            Note: this object will be modified!

        :param offset:
            Starting offset in ``trits``.

        :param length:
            Number of trits to squeeze, default to ``HASH_LENGTH``
        """
        # Squeeze is kind of like the opposite of absorb; it copies
        # trits from internal state to the ``trits`` parameter, one hash
        # at a time, and transforming internal state in between hashes.
        #
        # However, only the first hash of the state is "public", so we
        # can simplify the implementation somewhat.

        # Ensure length can be mod by HASH_LENGTH
        if length % HASH_LENGTH != 0:
            raise with_context(
                exc=ValueError('Invalid length passed to ``squeeze`.'),

                context={
                    'trits': trits,
                    'offset': offset,
                    'length': length,
                })

        # Ensure that ``trits`` can hold at least one hash worth of
        # trits.
        trits.extend([0] * max(0, length - len(trits)))

        # Check trits with offset can handle hash length
        if len(trits) - offset < HASH_LENGTH:
            raise with_context(
                exc=ValueError('Invalid offset passed to ``squeeze``.'),

                context={
                    'trits': trits,
                    'offset': offset,
                    'length': length
                },
            )

        while length >= HASH_LENGTH:
            # Copy exactly one hash.
            trits[offset:offset + HASH_LENGTH] = self._state[0:HASH_LENGTH]

            # One hash worth of trits copied; now transform.
            self._transform()

            offset += HASH_LENGTH
            length -= HASH_LENGTH

def
squeeze
(
self
,
trits
,
offset
=
0
,
length
=
HASH_LENGTH
)
:
if
length
%
HASH_LENGTH
!=
0
:
raise
with_context
(
exc
=
ValueError
(
'Invalid length passed to ``squeeze`.'
)
,
context
=
{
'trits'
:
trits
,
'offset'
:
offset
,
'length'
:
length
,
}
)
trits
.
extend
(
[
0
]
*
max
(
0
,
length
len
(
trits
)
)
)
if
len
(
trits
)
offset
<
HASH_LENGTH
:
raise
with_context
(
exc
=
ValueError
(
'Invalid offset passed to ``squeeze``.'
)
,
context
=
{
'trits'
:
trits
,
'offset'
:
offset
,
'length'
:
length
}
,
)
while
length
>=
HASH_LENGTH
:
trits
[
offset
:
offset
+
HASH_LENGTH
]
=
self
.
_state
[
0
:
HASH_LENGTH
]
self
.
_transform
(
)
offset
+=
HASH_LENGTH
length
-=
HASH_LENGTH


def _transform(self):
        # type: () -> None
        """
        Transforms internal state.
        """
        # Copy some values locally so we can avoid global lookups in the
        # inner loop.
        #
        # References:
        #
        # - https://wiki.python.org/moin/PythonSpeed/PerformanceTips#Local_Variables
        state_length = STATE_LENGTH
        truth_table = TRUTH_TABLE

        # Operate on a copy of ``self._state`` to eliminate dot lookups
        # in the inner loop.
        #
        # References:
        #
        # - https://wiki.python.org/moin/PythonSpeed/PerformanceTips#Avoiding_dots...
        # - http://stackoverflow.com/a/2612990/
        prev_state = self._state[:]
        new_state = prev_state[:]

        # Note: This code looks significantly different from the C
        # implementation because it has been optimized to limit the
        # number of list item lookups (these are relatively slow in
        # Python).
        index = 0
        for _ in range(NUMBER_OF_ROUNDS):
            prev_trit = prev_state[index]

            for pos in range(state_length):
                index += (364 if index < 365 else -365)

                new_trit = prev_state[index]

                new_state[pos] = truth_table[prev_trit + (3 * new_trit) + 4]

                prev_trit = new_trit

            prev_state = new_state
            new_state = new_state[:]

        self._state = new_state

def _transform ( self ) : state_length = STATE_LENGTH truth_table = TRUTH_TABLE prev_state = self . _state [ : ] new_state = prev_state [ : ] index = 0 for _ in range ( NUMBER_OF_ROUNDS ) : prev_trit = prev_state [ index ] for pos in range ( state_length ) : index += ( 364 if index < 365 else - 365 ) new_trit = prev_state [ index ] new_state [ pos ] = truth_table [ prev_trit + ( 3 * new_trit ) + 4 ] prev_trit = new_trit prev_state = new_state new_state = new_state [ : ] self . _state = new_state


def get_digests(
            self,
            index=0,
            count=1,
            security_level=AddressGenerator.DEFAULT_SECURITY_LEVEL,
    ):
        # type: (int, int, int) -> dict
        """
        Generates one or more key digests from the seed.

        Digests are safe to share; use them to generate multisig
        addresses.

        :param index:
            The starting key index.

        :param count:
            Number of digests to generate.

        :param security_level:
            Number of iterations to use when generating new addresses.

            Larger values take longer, but the resulting signatures are
            more secure.

            This value must be between 1 and 3, inclusive.

        :return:
            Dict with the following items::

                {
                    'digests': List[Digest],
                        Always contains a list, even if only one digest
                        was generated.
                }
        """
        return commands.GetDigestsCommand(self.adapter)(
            seed=self.seed,
            index=index,
            count=count,
            securityLevel=security_level,
        )

def get_digests ( self , index = 0 , count = 1 , security_level = AddressGenerator . DEFAULT_SECURITY_LEVEL , ) : return commands . GetDigestsCommand ( self . adapter ) ( seed = self . seed , index = index , count = count , securityLevel = security_level , )

Generates one or more key digests from the seed .


def get_private_keys(
            self,
            index=0,
            count=1,
            security_level=AddressGenerator.DEFAULT_SECURITY_LEVEL,
    ):
        # type: (int, int, int) -> dict
        """
        Generates one or more private keys from the seed.

        As the name implies, private keys should not be shared.
        However, in a few cases it may be necessary (e.g., for M-of-N
        transactions).

        :param index:
            The starting key index.

        :param count:
            Number of keys to generate.

        :param security_level:
            Number of iterations to use when generating new keys.

            Larger values take longer, but the resulting signatures are
            more secure.

            This value must be between 1 and 3, inclusive.

        :return:
            Dict with the following items::

                {
                    'keys': List[PrivateKey],
                        Always contains a list, even if only one key was
                        generated.
                }

        References:

        - :py:class:`iota.crypto.signing.KeyGenerator`
        - https://github.com/iotaledger/wiki/blob/master/multisigs.md#how-m-of-n-works
        """
        return commands.GetPrivateKeysCommand(self.adapter)(
            seed=self.seed,
            index=index,
            count=count,
            securityLevel=security_level,
        )

def get_private_keys ( self , index = 0 , count = 1 , security_level = AddressGenerator . DEFAULT_SECURITY_LEVEL , ) : return commands . GetPrivateKeysCommand ( self . adapter ) ( seed = self . seed , index = index , count = count , securityLevel = security_level , )

Generates one or more private keys from the seed .


def prepare_multisig_transfer(
            self,
            transfers,  # type: Iterable[ProposedTransaction]
            multisig_input,  # type: MultisigAddress
            change_address=None,  # type: Optional[Address]
    ):
        # type: (...) -> dict
        """
        Prepares a bundle that authorizes the spending of IOTAs from a
        multisig address.

        .. note::
            This method is used exclusively to spend IOTAs from a
            multisig address.

            If you want to spend IOTAs from non-multisig addresses, or
            if you want to create 0-value transfers (i.e., that don't
            require inputs), use
            :py:meth:`iota.api.Iota.prepare_transfer` instead.

        :param transfers:
            Transaction objects to prepare.

            .. important::
                Must include at least one transaction that spends IOTAs
                (i.e., has a nonzero ``value``).  If you want to prepare
                a bundle that does not spend any IOTAs, use
                :py:meth:`iota.api.prepare_transfer` instead.

        :param multisig_input:
            The multisig address to use as the input for the transfers.

            .. note::
                This method only supports creating a bundle with a
                single multisig input.

                If you would like to spend from multiple multisig
                addresses in the same bundle, create the
                :py:class:`iota.multisig.transaction.ProposedMultisigBundle`
                object manually.

        :param change_address:
            If inputs are provided, any unspent amount will be sent to
            this address.

            If the bundle has no unspent inputs, ``change_address` is
            ignored.

            .. important::
                Unlike :py:meth:`iota.api.Iota.prepare_transfer`, this
                method will NOT generate a change address automatically.
                If there are unspent inputs and ``change_address`` is
                empty, an exception will be raised.

                This is because multisig transactions typically involve
                multiple individuals, and it would be unfair to the
                participants if we generated a change address
                automatically using the seed of whoever happened to run
                the ``prepare_multisig_transfer`` method!

                .. danger::
                    Note that this protective measure is not a
                    substitute for due diligence!

                    Always verify the details of every transaction in a
                    bundle (including the change transaction) before
                    signing the input(s)!

        :return:
            Dict containing the following values::

                {
                    'trytes': List[TransactionTrytes],
                        Finalized bundle, as trytes.
                        The input transactions are not signed.
                }

          In order to authorize the spending of IOTAs from the multisig
          input, you must generate the correct private keys and invoke
          the :py:meth:`iota.crypto.types.PrivateKey.sign_input_at`
          method for each key, in the correct order.

          Once the correct signatures are applied, you can then perform
          proof of work (``attachToTangle``) and broadcast the bundle
          using :py:meth:`iota.api.Iota.send_trytes`.
        """
        return commands.PrepareMultisigTransferCommand(self.adapter)(
            changeAddress=change_address,
            multisigInput=multisig_input,
            transfers=transfers,
        )

def prepare_multisig_transfer ( self , transfers , multisig_input , change_address = None , ) : return commands . PrepareMultisigTransferCommand ( self . adapter ) ( changeAddress = change_address , multisigInput = multisig_input , transfers = transfers , )

Prepares a bundle that authorizes the spending of IOTAs from a multisig address .


def add_trits(left, right):
    # type: (Sequence[int], Sequence[int]) -> List[int]
    """
    Adds two sequences of trits together.

    The result is a list of trits equal in length to the longer of the
    two sequences.

    .. note::
        Overflow is possible.

        For example, ``add_trits([1], [1])`` returns ``[-1]``.
    """
    target_len = max(len(left), len(right))

    res = [0] * target_len
    left += [0] * (target_len - len(left))
    right += [0] * (target_len - len(right))

    carry = 0
    for i in range(len(res)):
        res[i], carry = _full_add_trits(left[i], right[i], carry)

    return res

def add_trits ( left , right ) : target_len = max ( len ( left ) , len ( right ) ) res = [ 0 ] * target_len left += [ 0 ] * ( target_len - len ( left ) ) right += [ 0 ] * ( target_len - len ( right ) ) carry = 0 for i in range ( len ( res ) ) : res [ i ] , carry = _full_add_trits ( left [ i ] , right [ i ] , carry ) return res


def trits_from_int(n, pad=1):
    # type: (int, Optional[int]) -> List[int]
    """
    Returns a trit representation of an integer value.

    :param n:
        Integer value to convert.

    :param pad:
        Ensure the result has at least this many trits.

    References:

    - https://dev.to/buntine/the-balanced-ternary-machines-of-soviet-russia
    - https://en.wikipedia.org/wiki/Balanced_ternary
    - https://rosettacode.org/wiki/Balanced_ternary#Python
    """
    if n == 0:
        trits = []
    else:
        quotient, remainder = divmod(n, 3)

        if remainder == 2:
            # Lend 1 to the next place so we can make this trit
            # negative.
            quotient += 1
            remainder = -1

        trits = [remainder] + trits_from_int(quotient, pad=0)

    if pad:
        trits += [0] * max(0, pad - len(trits))

    return trits

def trits_from_int ( n , pad = 1 ) : if n == 0 : trits = [ ] else : quotient , remainder = divmod ( n , 3 ) if remainder == 2 : quotient += 1 remainder = - 1 trits = [ remainder ] + trits_from_int ( quotient , pad = 0 ) if pad : trits += [ 0 ] * max ( 0 , pad - len ( trits ) ) return trits

Returns a trit representation of an integer value .


def _add_trits(left, right):
    # type: (int, int) -> int
    """
    Adds two individual trits together.

    The result is always a single trit.
    """
    res = left + right
    return res if -2 < res < 2 else (res < 0) - (res > 0)

def _add_trits ( left , right ) : res = left + right return res if - 2 < res < 2 else ( res < 0 ) - ( res > 0 )


def _full_add_trits(left, right, carry):
    # type: (int, int, int) -> Tuple[int, int]
    """
    Adds two trits together, with support for a carry trit.
    """
    sum_both = _add_trits(left, right)
    cons_left = _cons_trits(left, right)
    cons_right = _cons_trits(sum_both, carry)

    return _add_trits(sum_both, carry), _any_trits(cons_left, cons_right)

def _full_add_trits ( left , right , carry ) : sum_both = _add_trits ( left , right ) cons_left = _cons_trits ( left , right ) cons_right = _cons_trits ( sum_both , carry ) return _add_trits ( sum_both , carry ) , _any_trits ( cons_left , cons_right )

Adds two trits together with support for a carry trit .


def output_seed(seed):
    # type: (Seed) -> None
    """
    Outputs the user's seed to stdout, along with lots of warnings
    about security.
    """
    print(
        'WARNING: Anyone who has your seed can spend your IOTAs! '
        'Clear the screen after recording your seed!'
    )
    compat.input('')
    print('Your seed is:')
    print('')
    print(binary_type(seed).decode('ascii'))
    print('')

    print(
        'Clear the screen to prevent shoulder surfing, '
        'and press return to continue.'
    )
    print('https://en.wikipedia.org/wiki/Shoulder_surfing_(computer_security)')
    compat.input('')

Outputs the user s seed to stdout along with lots of warnings about security .


def find_transactions(
            self,
            bundles=None,  # type: Optional[Iterable[BundleHash]]
            addresses=None,  # type: Optional[Iterable[Address]]
            tags=None,  # type: Optional[Iterable[Tag]]
            approvees=None,  # type: Optional[Iterable[TransactionHash]]
    ):
        # type: (...) -> dict
        """
        Find the transactions which match the specified input and
        return.

        All input values are lists, for which a list of return values
        (transaction hashes), in the same order, is returned for all
        individual elements.

        Using multiple of these input fields returns the intersection of
        the values.

        :param bundles:
          List of bundle IDs.

        :param addresses:
            List of addresses.

        :param tags:
            List of tags.

        :param approvees:
            List of approvee transaction IDs.

        References:

        - https://iota.readme.io/docs/findtransactions
        """
        return core.FindTransactionsCommand(self.adapter)(
            bundles=bundles,
            addresses=addresses,
            tags=tags,
            approvees=approvees,
        )

def find_transactions ( self , bundles = None , addresses = None , tags = None , approvees = None , ) : return core . FindTransactionsCommand ( self . adapter ) ( bundles = bundles , addresses = addresses , tags = tags , approvees = approvees , )

Find the transactions which match the specified input and return .


def get_inputs(
            self,
            start=0,
            stop=None,
            threshold=None,
            security_level=None,
    ):
        # type: (int, Optional[int], Optional[int], Optional[int]) -> dict
        """
        Gets all possible inputs of a seed and returns them, along with
        the total balance.

        This is either done deterministically (by generating all
        addresses until :py:meth:`find_transactions` returns an empty
        result), or by providing a key range to search.

        :param start:
            Starting key index.
            Defaults to 0.

        :param stop:
            Stop before this index.

            Note that this parameter behaves like the ``stop`` attribute
            in a :py:class:`slice` object; the stop index is *not*
            included in the result.

            If ``None`` (default), then this method will not stop until
            it finds an unused address.

        :param threshold:
            If set, determines the minimum threshold for a successful
            result:

            - As soon as this threshold is reached, iteration will stop.
            - If the command runs out of addresses before the threshold
              is reached, an exception is raised.

            .. note::
                This method does not attempt to "optimize" the result
                (e.g., smallest number of inputs, get as close to
                ``threshold`` as possible, etc.); it simply accumulates
                inputs in order until the threshold is met.

            If ``threshold`` is 0, the first address in the key range
            with a non-zero balance will be returned (if it exists).

            If ``threshold`` is ``None`` (default), this method will
            return **all** inputs in the specified key range.

        :param security_level:
            Number of iterations to use when generating new addresses
            (see :py:meth:`get_new_addresses`).

            This value must be between 1 and 3, inclusive.

            If not set, defaults to
            :py:attr:`AddressGenerator.DEFAULT_SECURITY_LEVEL`.

        :return:
            Dict with the following structure::

                {
                    'inputs': List[Address],
                        Addresses with nonzero balances that can be used
                        as inputs.

                    'totalBalance': int,
                        Aggregate balance from all matching addresses.
                }

            Note that each Address in the result has its ``balance``
            attribute set.

            Example:

            .. code-block:: python

                response = iota.get_inputs(...)

                input0 = response['inputs'][0] # type: Address
                input0.balance # 42

        :raise:
            - :py:class:`iota.adapter.BadApiResponse` if ``threshold``
              is not met.  Not applicable if ``threshold`` is ``None``.

        References:

        - https://github.com/iotaledger/wiki/blob/master/api-proposal.md#getinputs
        """
        return extended.GetInputsCommand(self.adapter)(
            seed=self.seed,
            start=start,
            stop=stop,
            threshold=threshold,
            securityLevel=security_level
        )

def get_inputs ( self , start = 0 , stop = None , threshold = None , security_level = None , ) : return extended . GetInputsCommand ( self . adapter ) ( seed = self . seed , start = start , stop = stop , threshold = threshold , securityLevel = security_level )

Gets all possible inputs of a seed and returns them along with the total balance .


def get_new_addresses(
            self,
            index=0,
            count=1,
            security_level=AddressGenerator.DEFAULT_SECURITY_LEVEL,
            checksum=False,
    ):
        # type: (int, Optional[int], int, bool) -> dict
        """
        Generates one or more new addresses from the seed.

        :param index:
            The key index of the first new address to generate (must be
            >= 1).

        :param count:
            Number of addresses to generate (must be >= 1).

            .. tip::
                This is more efficient than calling ``get_new_address``
                inside a loop.

            If ``None``, this method will progressively generate
            addresses and scan the Tangle until it finds one that has no
            transactions referencing it.

        :param security_level:
            Number of iterations to use when generating new addresses.

            Larger values take longer, but the resulting signatures are
            more secure.

            This value must be between 1 and 3, inclusive.

        :param checksum:
            Specify whether to return the address with the checksum.
            Defaults to ``False``.

        :return:
            Dict with the following structure::

            {
                'addresses': List[Address],
                    Always a list, even if only one address was
                    generated.
            }

        References:

        - https://github.com/iotaledger/wiki/blob/master/api-proposal.md#getnewaddress
        """
        return extended.GetNewAddressesCommand(self.adapter)(
            count=count,
            index=index,
            securityLevel=security_level,
            checksum=checksum,
            seed=self.seed,
        )

def get_new_addresses ( self , index = 0 , count = 1 , security_level = AddressGenerator . DEFAULT_SECURITY_LEVEL , checksum = False , ) : return extended . GetNewAddressesCommand ( self . adapter ) ( count = count , index = index , securityLevel = security_level , checksum = checksum , seed = self . seed , )

Generates one or more new addresses from the seed .


def get_transfers(self, start=0, stop=None, inclusion_states=False):
        # type: (int, Optional[int], bool) -> dict
        """
        Returns all transfers associated with the seed.

        :param start:
            Starting key index.

        :param stop:
            Stop before this index.

            Note that this parameter behaves like the ``stop`` attribute
            in a :py:class:`slice` object; the stop index is *not*
            included in the result.

            If ``None`` (default), then this method will check every
            address until it finds one without any transfers.

        :param inclusion_states:
            Whether to also fetch the inclusion states of the transfers.

            This requires an additional API call to the node, so it is
            disabled by default.

        :return:
            Dict with the following structure::

                {
                    'bundles': List[Bundle],
                        Matching bundles, sorted by tail transaction
                        timestamp.

                        This value is always a list, even if only one
                        bundle was found.
                }

        References:

        - https://github.com/iotaledger/wiki/blob/master/api-proposal.md#gettransfers
        """
        return extended.GetTransfersCommand(self.adapter)(
            seed=self.seed,
            start=start,
            stop=stop,
            inclusionStates=inclusion_states,
        )

def get_transfers ( self , start = 0 , stop = None , inclusion_states = False ) : return extended . GetTransfersCommand ( self . adapter ) ( seed = self . seed , start = start , stop = stop , inclusionStates = inclusion_states , )

Returns all transfers associated with the seed .


def promote_transaction(
            self,
            transaction,
            depth=3,
            min_weight_magnitude=None,
    ):
        # type: (TransactionHash, int, Optional[int]) -> dict
        """
        Promotes a transaction by adding spam on top of it.

        :return:
            Dict with the following structure::

                {
                    'bundle': Bundle,
                        The newly-published bundle.
                }
        """
        if min_weight_magnitude is None:
            min_weight_magnitude = self.default_min_weight_magnitude

        return extended.PromoteTransactionCommand(self.adapter)(
            transaction=transaction,
            depth=depth,
            minWeightMagnitude=min_weight_magnitude,
        )

def promote_transaction ( self , transaction , depth = 3 , min_weight_magnitude = None , ) : if min_weight_magnitude is None : min_weight_magnitude = self . default_min_weight_magnitude return extended . PromoteTransactionCommand ( self . adapter ) ( transaction = transaction , depth = depth , minWeightMagnitude = min_weight_magnitude , )

Promotes a transaction by adding spam on top of it .


def replay_bundle(
            self,
            transaction,
            depth=3,
            min_weight_magnitude=None,
    ):
        # type: (TransactionHash, int, Optional[int]) -> dict
        """
        Takes a tail transaction hash as input, gets the bundle
        associated with the transaction and then replays the bundle by
        attaching it to the Tangle.

        :param transaction:
            Transaction hash.  Must be a tail.

        :param depth:
            Depth at which to attach the bundle.
            Defaults to 3.

        :param min_weight_magnitude:
            Min weight magnitude, used by the node to calibrate Proof of
            Work.

            If not provided, a default value will be used.

        :return:
            Dict with the following structure::

                {
                    'trytes': List[TransactionTrytes],
                        Raw trytes that were published to the Tangle.
                }

        References:

        - https://github.com/iotaledger/wiki/blob/master/api-proposal.md#replaytransfer
        """
        if min_weight_magnitude is None:
            min_weight_magnitude = self.default_min_weight_magnitude

        return extended.ReplayBundleCommand(self.adapter)(
            transaction=transaction,
            depth=depth,
            minWeightMagnitude=min_weight_magnitude,
        )

def replay_bundle ( self , transaction , depth = 3 , min_weight_magnitude = None , ) : if min_weight_magnitude is None : min_weight_magnitude = self . default_min_weight_magnitude return extended . ReplayBundleCommand ( self . adapter ) ( transaction = transaction , depth = depth , minWeightMagnitude = min_weight_magnitude , )

Takes a tail transaction hash as input gets the bundle associated with the transaction and then replays the bundle by attaching it to the Tangle .


def send_transfer(
            self,
            transfers,  # type: Iterable[ProposedTransaction]
            depth=3,  # type: int
            inputs=None,  # type: Optional[Iterable[Address]]
            change_address=None,  # type: Optional[Address]
            min_weight_magnitude=None,  # type: Optional[int]
            security_level=None,  # type: Optional[int]
    ):
        # type: (...) -> dict
        """
        Prepares a set of transfers and creates the bundle, then
        attaches the bundle to the Tangle, and broadcasts and stores the
        transactions.

        :param transfers:
            Transfers to include in the bundle.

        :param depth:
            Depth at which to attach the bundle.
            Defaults to 3.

        :param inputs:
            List of inputs used to fund the transfer.
            Not needed for zero-value transfers.

        :param change_address:
            If inputs are provided, any unspent amount will be sent to
            this address.

            If not specified, a change address will be generated
            automatically.

        :param min_weight_magnitude:
            Min weight magnitude, used by the node to calibrate Proof of
            Work.

            If not provided, a default value will be used.

        :param security_level:
            Number of iterations to use when generating new addresses
            (see :py:meth:`get_new_addresses`).

            This value must be between 1 and 3, inclusive.

            If not set, defaults to
            :py:attr:`AddressGenerator.DEFAULT_SECURITY_LEVEL`.

        :return:
            Dict with the following structure::

                {
                    'bundle': Bundle,
                        The newly-published bundle.
                }

        References:

        - https://github.com/iotaledger/wiki/blob/master/api-proposal.md#sendtransfer
        """
        if min_weight_magnitude is None:
            min_weight_magnitude = self.default_min_weight_magnitude

        return extended.SendTransferCommand(self.adapter)(
            seed=self.seed,
            depth=depth,
            transfers=transfers,
            inputs=inputs,
            changeAddress=change_address,
            minWeightMagnitude=min_weight_magnitude,
            securityLevel=security_level,
        )

def send_transfer ( self , transfers , depth = 3 , inputs = None , change_address = None , min_weight_magnitude = None , security_level = None , ) : if min_weight_magnitude is None : min_weight_magnitude = self . default_min_weight_magnitude return extended . SendTransferCommand ( self . adapter ) ( seed = self . seed , depth = depth , transfers = transfers , inputs = inputs , changeAddress = change_address , minWeightMagnitude = min_weight_magnitude , securityLevel = security_level , )

Prepares a set of transfers and creates the bundle then attaches the bundle to the Tangle and broadcasts and stores the transactions .


def send_trytes(self, trytes, depth=3, min_weight_magnitude=None):
        # type: (Iterable[TransactionTrytes], int, Optional[int]) -> dict
        """
        Attaches transaction trytes to the Tangle, then broadcasts and
        stores them.

        :param trytes:
            Transaction encoded as a tryte sequence.

        :param depth:
            Depth at which to attach the bundle.
            Defaults to 3.

        :param min_weight_magnitude:
            Min weight magnitude, used by the node to calibrate Proof of
            Work.

            If not provided, a default value will be used.

        :return:
            Dict with the following structure::

                {
                    'trytes': List[TransactionTrytes],
                        Raw trytes that were published to the Tangle.
                }

        References:

        - https://github.com/iotaledger/wiki/blob/master/api-proposal.md#sendtrytes
        """
        if min_weight_magnitude is None:
            min_weight_magnitude = self.default_min_weight_magnitude

        return extended.SendTrytesCommand(self.adapter)(
            trytes=trytes,
            depth=depth,
            minWeightMagnitude=min_weight_magnitude,
        )

def send_trytes ( self , trytes , depth = 3 , min_weight_magnitude = None ) : if min_weight_magnitude is None : min_weight_magnitude = self . default_min_weight_magnitude return extended . SendTrytesCommand ( self . adapter ) ( trytes = trytes , depth = depth , minWeightMagnitude = min_weight_magnitude , )

Attaches transaction trytes to the Tangle then broadcasts and stores them .


def resolve_adapter(uri):
    # type: (AdapterSpec) -> BaseAdapter
    """
    Given a URI, returns a properly-configured adapter instance.
    """
    if isinstance(uri, BaseAdapter):
        return uri

    parsed = compat.urllib_parse.urlsplit(uri)  # type: SplitResult

    if not parsed.scheme:
        raise with_context(
            exc=InvalidUri(
                'URI must begin with "<protocol>://" (e.g., "udp://").',
            ),

            context={
                'parsed': parsed,
                'uri': uri,
            },
        )

    try:
        adapter_type = adapter_registry[parsed.scheme]
    except KeyError:
        raise with_context(
            exc=InvalidUri('Unrecognized protocol {protocol!r}.'.format(
                protocol=parsed.scheme,
            )),

            context={
                'parsed': parsed,
                'uri': uri,
            },
        )

    return adapter_type.configure(parsed)

Given a URI returns a properly - configured adapter instance .


def send_request(self, payload, **kwargs):
        # type: (dict, dict) -> dict
        """
        Sends an API request to the node.

        :param payload:
            JSON payload.

        :param kwargs:
            Additional keyword arguments for the adapter.

        :return:
            Decoded response from the node.

        :raise:
            - :py:class:`BadApiResponse` if a non-success response was
              received.
        """
        raise NotImplementedError(
            'Not implemented in {cls}.'.format(cls=type(self).__name__),
        )

def
send_request
(
self
,
payload
,
**
kwargs
)
:
raise
NotImplementedError
(
'Not implemented in {cls}.'
.
format
(
cls
=
type
(
self
)
.
__name__
)
,
)


def _log(self, level, message, context=None):
        # type: (int, Text, Optional[dict]) -> None
        """
        Sends a message to the instance's logger, if configured.
        """
        if self._logger:
            self._logger.log(level, message, extra={'context': context or {}})

def _log ( self , level , message , context = None ) : if self . _logger : self . _logger . log ( level , message , extra = { 'context' : context or { } } )

Sends a message to the instance s logger if configured .


def _send_http_request(self, url, payload, method='post', **kwargs):
        # type: (Text, Optional[Text], Text, dict) -> Response
        """
        Sends the actual HTTP request.

        Split into its own method so that it can be mocked during unit
        tests.
        """
        kwargs.setdefault(
            'timeout',
            self.timeout if self.timeout else get_default_timeout(),
        )

        if self.authentication:
            kwargs.setdefault('auth', auth.HTTPBasicAuth(*self.authentication))

        self._log(
            level=DEBUG,

            message='Sending {method} to {url}: {payload!r}'.format(
                method=method,
                payload=payload,
                url=url,
            ),

            context={
                'request_method': method,
                'request_kwargs': kwargs,
                'request_payload': payload,
                'request_url': url,
            },
        )

        response = request(method=method, url=url, data=payload, **kwargs)

        self._log(
            level=DEBUG,

            message='Receiving {method} from {url}: {response!r}'.format(
                method=method,
                response=response.content,
                url=url,
            ),

            context={
                'request_method': method,
                'request_kwargs': kwargs,
                'request_payload': payload,
                'request_url': url,

                'response_headers': response.headers,
                'response_content': response.content,
            },
        )

        return response


def _interpret_response(self, response, payload, expected_status):
        # type: (Response, dict, Container[int]) -> dict
        """
        Interprets the HTTP response from the node.

        :param response:
            The response object received from
            :py:meth:`_send_http_request`.

        :param payload:
            The request payload that was sent (used for debugging).

        :param expected_status:
            The response should match one of these status codes to be
            considered valid.
        """
        raw_content = response.text
        if not raw_content:
            raise with_context(
                exc=BadApiResponse(
                    'Empty {status} response from node.'.format(
                        status=response.status_code,
                    ),
                ),

                context={
                    'request': payload,
                },
            )

        try:
            decoded = json.loads(raw_content)  # type: dict
        # :bc: py2k doesn't have JSONDecodeError
        except ValueError:
            raise with_context(
                exc=BadApiResponse(
                    'Non-JSON {status} response from node: '
                    '{raw_content}'.format(
                        status=response.status_code,
                        raw_content=raw_content,
                    )
                ),

                context={
                    'request': payload,
                    'raw_response': raw_content,
                },
            )

        if not isinstance(decoded, dict):
            raise with_context(
                exc=BadApiResponse(
                    'Malformed {status} response from node: {decoded!r}'.format(
                        status=response.status_code,
                        decoded=decoded,
                    ),
                ),

                context={
                    'request': payload,
                    'response': decoded,
                },
            )

        if response.status_code in expected_status:
            return decoded

        error = None
        try:
            if response.status_code == codes['bad_request']:
                error = decoded['error']
            elif response.status_code == codes['internal_server_error']:
                error = decoded['exception']
        except KeyError:
            pass

        raise with_context(
            exc=BadApiResponse(
                '{status} response from node: {error}'.format(
                    error=error or decoded,
                    status=response.status_code,
                ),
            ),

            context={
                'request': payload,
                'response': decoded,
            },
        )

Interprets the HTTP response from the node .


def seed_response(self, command, response):
        # type: (Text, dict) -> MockAdapter
        """
        Sets the response that the adapter will return for the specified
        command.

        You can seed multiple responses per command; the adapter will
        put them into a FIFO queue.  When a request comes in, the
        adapter will pop the corresponding response off of the queue.

        Example:

        .. code-block:: python

            adapter.seed_response('sayHello', {'message': 'Hi!'})
            adapter.seed_response('sayHello', {'message': 'Hello!'})

            adapter.send_request({'command': 'sayHello'})
            # {'message': 'Hi!'}

            adapter.send_request({'command': 'sayHello'})
            # {'message': 'Hello!'}
        """
        if command not in self.responses:
            self.responses[command] = deque()

        self.responses[command].append(response)
        return self

def seed_response ( self , command , response ) : if command not in self . responses : self . responses [ command ] = deque ( ) self . responses [ command ] . append ( response ) return self

Sets the response that the adapter will return for the specified command .


def add_digest(self, digest):
        # type: (Digest) -> None
        """
        Absorbs a digest into the sponge.

        .. important::
            Keep track of the order that digests are added!

            To spend inputs from a multisig address, you must provide
            the private keys in the same order!

        References:

        - https://github.com/iotaledger/wiki/blob/master/multisigs.md#spending-inputs
        """
        if self._address:
            raise ValueError('Cannot add digests once an address is extracted.')

        self._sponge.absorb(digest.as_trits())
        self._digests.append(digest)


def get_address(self):
        # type: () -> MultisigAddress
        """
        Returns the new multisig address.

        Note that you can continue to add digests after extracting an
        address; the next address will use *all* of the digests that
        have been added so far.
        """
        if not self._digests:
            raise ValueError(
                'Must call ``add_digest`` at least once '
                'before calling ``get_address``.',
            )

        if not self._address:
            address_trits = [0] * HASH_LENGTH
            self._sponge.squeeze(address_trits)

            self._address = MultisigAddress.from_trits(
                address_trits,
                digests=self._digests[:],
            )

        return self._address


def create_iterator(self, start=0, step=1):
        # type: (int, int) -> Generator[Address, None, None]
        """
        Creates an iterator that can be used to progressively generate new
        addresses.

        :param start:
            Starting index.

            Warning: This method may take awhile to reset if ``start``
            is a large number!

        :param step:
            Number of indexes to advance after each address.

            Warning: The generator may take awhile to advance between
            iterations if ``step`` is a large number!
        """
        key_iterator = (
            KeyGenerator(self.seed).create_iterator(
                start,
                step,
                self.security_level,
            )
        )

        while True:
            yield self._generate_address(key_iterator)

def create_iterator ( self , start = 0 , step = 1 ) : key_iterator = ( KeyGenerator ( self . seed ) . create_iterator ( start , step , self . security_level , ) ) while True : yield self . _generate_address ( key_iterator )

Creates an iterator that can be used to progressively generate new addresses .


def address_from_digest(digest):
        # type: (Digest) -> Address
        """
        Generates an address from a private key digest.
        """
        address_trits = [0] * (Address.LEN * TRITS_PER_TRYTE)  # type: List[int]

        sponge = Kerl()
        sponge.absorb(digest.as_trits())
        sponge.squeeze(address_trits)

        return Address.from_trits(
            trits=address_trits,

            key_index=digest.key_index,
            security_level=digest.security_level,
        )

def address_from_digest ( digest ) : address_trits = [ 0 ] * ( Address . LEN * TRITS_PER_TRYTE ) sponge = Kerl ( ) sponge . absorb ( digest . as_trits ( ) ) sponge . squeeze ( address_trits ) return Address . from_trits ( trits = address_trits , key_index = digest . key_index , security_level = digest . security_level , )

Generates an address from a private key digest .


def _generate_address(self, key_iterator):
        # type: (KeyIterator) -> Address
        """
        Generates a new address.

        Used in the event of a cache miss.
        """
        if self.checksum:
            return (
                self.address_from_digest(
                    digest=self._get_digest(key_iterator),
                ).with_valid_checksum()
            )
        else:
            return self.address_from_digest(self._get_digest(key_iterator))

def _generate_address ( self , key_iterator ) : if self . checksum : return ( self . address_from_digest ( digest = self . _get_digest ( key_iterator ) , ) . with_valid_checksum ( ) ) else : return self . address_from_digest ( self . _get_digest ( key_iterator ) )


def find_transaction_objects(adapter, **kwargs):
    # type: (BaseAdapter, **Iterable) -> List[Transaction]
    """
    Finds transactions matching the specified criteria, fetches the
    corresponding trytes and converts them into Transaction objects.
    """
    ft_response = FindTransactionsCommand(adapter)(**kwargs)

    hashes = ft_response['hashes']

    if hashes:
        gt_response = GetTrytesCommand(adapter)(hashes=hashes)

        return list(map(
            Transaction.from_tryte_string,
            gt_response.get('trytes') or [],
        ))  # type: List[Transaction]

    return []

def find_transaction_objects ( adapter , ** kwargs ) : ft_response = FindTransactionsCommand ( adapter ) ( ** kwargs ) hashes = ft_response [ 'hashes' ] if hashes : gt_response = GetTrytesCommand ( adapter ) ( hashes = hashes ) return list ( map ( Transaction . from_tryte_string , gt_response . get ( 'trytes' ) or [ ] , ) ) return [ ]

Finds transactions matching the specified criteria fetches the corresponding trytes and converts them into Transaction objects .


def iter_used_addresses(
        adapter,  # type: BaseAdapter
        seed,  # type: Seed
        start,  # type: int
        security_level=None,  # type: Optional[int]
):
    # type: (...) -> Generator[Tuple[Address, List[TransactionHash]], None, None]
    """
    Scans the Tangle for used addresses.

    This is basically the opposite of invoking ``getNewAddresses`` with
    ``stop=None``.
    """
    if security_level is None:
        security_level = AddressGenerator.DEFAULT_SECURITY_LEVEL

    ft_command = FindTransactionsCommand(adapter)

    for addy in AddressGenerator(seed, security_level).create_iterator(start):
        ft_response = ft_command(addresses=[addy])

        if ft_response['hashes']:
            yield addy, ft_response['hashes']
        else:
            break

        # Reset the command so that we can call it again.
        ft_command.reset()

def iter_used_addresses ( adapter , seed , start , security_level = None , ) : if security_level is None : security_level = AddressGenerator . DEFAULT_SECURITY_LEVEL ft_command = FindTransactionsCommand ( adapter ) for addy in AddressGenerator ( seed , security_level ) . create_iterator ( start ) : ft_response = ft_command ( addresses = [ addy ] ) if ft_response [ 'hashes' ] : yield addy , ft_response [ 'hashes' ] else : break ft_command . reset ( )


def get_bundles_from_transaction_hashes(
        adapter,
        transaction_hashes,
        inclusion_states,
):
    # type: (BaseAdapter, Iterable[TransactionHash], bool) -> List[Bundle]
    """
    Given a set of transaction hashes, returns the corresponding bundles,
    sorted by tail transaction timestamp.
    """
    transaction_hashes = list(transaction_hashes)
    if not transaction_hashes:
        return []

    my_bundles = []  # type: List[Bundle]

    # Sort transactions into tail and non-tail.
    tail_transaction_hashes = set()
    non_tail_bundle_hashes = set()

    gt_response = GetTrytesCommand(adapter)(hashes=transaction_hashes)
    all_transactions = list(map(
        Transaction.from_tryte_string,
        gt_response['trytes'],
    ))  # type: List[Transaction]

    for txn in all_transactions:
        if txn.is_tail:
            tail_transaction_hashes.add(txn.hash)
        else:
            # Capture the bundle ID instead of the transaction hash so
            # that we can query the node to find the tail transaction
            # for that bundle.
            non_tail_bundle_hashes.add(txn.bundle_hash)

    if non_tail_bundle_hashes:
        for txn in find_transaction_objects(
                adapter=adapter,
                bundles=list(non_tail_bundle_hashes),
        ):
            if txn.is_tail:
                if txn.hash not in tail_transaction_hashes:
                    all_transactions.append(txn)
                    tail_transaction_hashes.add(txn.hash)

    # Filter out all non-tail transactions.
    tail_transactions = [
        txn
        for txn in all_transactions
        if txn.hash in tail_transaction_hashes
    ]

    # Attach inclusion states, if requested.
    if inclusion_states:
        gli_response = GetLatestInclusionCommand(adapter)(
            hashes=list(tail_transaction_hashes),
        )

        for txn in tail_transactions:
            txn.is_confirmed = gli_response['states'].get(txn.hash)

    # Find the bundles for each transaction.
    for txn in tail_transactions:
        gb_response = GetBundlesCommand(adapter)(transaction=txn.hash)
        txn_bundles = gb_response['bundles']  # type: List[Bundle]

        if inclusion_states:
            for bundle in txn_bundles:
                bundle.is_confirmed = txn.is_confirmed

        my_bundles.extend(txn_bundles)

    return list(sorted(
        my_bundles,
        key=lambda bundle_: bundle_.tail_transaction.timestamp,
    ))

def get_bundles_from_transaction_hashes ( adapter , transaction_hashes , inclusion_states , ) : transaction_hashes = list ( transaction_hashes ) if not transaction_hashes : return [ ] my_bundles = [ ] tail_transaction_hashes = set ( ) non_tail_bundle_hashes = set ( ) gt_response = GetTrytesCommand ( adapter ) ( hashes = transaction_hashes ) all_transactions = list ( map ( Transaction . from_tryte_string , gt_response [ 'trytes' ] , ) ) for txn in all_transactions : if txn . is_tail : tail_transaction_hashes . add ( txn . hash ) else : non_tail_bundle_hashes . add ( txn . bundle_hash ) if non_tail_bundle_hashes : for txn in find_transaction_objects ( adapter = adapter , bundles = list ( non_tail_bundle_hashes ) , ) : if txn . is_tail : if txn . hash not in tail_transaction_hashes : all_transactions . append ( txn ) tail_transaction_hashes . add ( txn . hash ) tail_transactions = [ txn for txn in all_transactions if txn . hash in tail_transaction_hashes ] if inclusion_states : gli_response = GetLatestInclusionCommand ( adapter ) ( hashes = list ( tail_transaction_hashes ) , ) for txn in tail_transactions : txn . is_confirmed = gli_response [ 'states' ] . get ( txn . hash ) for txn in tail_transactions : gb_response = GetBundlesCommand ( adapter ) ( transaction = txn . hash ) txn_bundles = gb_response [ 'bundles' ] if inclusion_states : for bundle in txn_bundles : bundle . is_confirmed = txn . is_confirmed my_bundles . extend ( txn_bundles ) return list ( sorted ( my_bundles , key = lambda bundle_ : bundle_ . tail_transaction . timestamp , ) )

Given a set of transaction hashes returns the corresponding bundles sorted by tail transaction timestamp .


def check_trytes_codec(encoding):
    """
    Determines which codec to use for the specified encoding.

    References:

    - https://docs.python.org/3/library/codecs.html#codecs.register
    """
    if encoding == AsciiTrytesCodec.name:
        return AsciiTrytesCodec.get_codec_info()

    elif encoding == AsciiTrytesCodec.compat_name:
        warn(
            '"{old_codec}" codec will be removed in PyOTA v2.1. '
            'Use "{new_codec}" instead.'.format(
                new_codec=AsciiTrytesCodec.name,
                old_codec=AsciiTrytesCodec.compat_name,
            ),

            DeprecationWarning,
        )
        return AsciiTrytesCodec.get_codec_info()

    return None

Determines which codec to use for the specified encoding .


def get_codec_info(cls):
        """
        Returns information used by the codecs library to configure the
        codec for use.
        """
        codec = cls()

        codec_info = {
            'encode': codec.encode,
            'decode': codec.decode,
        }

        # In Python 2, all codecs are made equal.
        # In Python 3, some codecs are more equal than others.
        if PY3:
            codec_info['_is_text_encoding'] = False

        return CodecInfo(**codec_info)

def get_codec_info ( cls ) : codec = cls ( ) codec_info = { 'encode' : codec . encode , 'decode' : codec . decode , } if PY3 : codec_info [ '_is_text_encoding' ] = False return CodecInfo ( ** codec_info )

Returns information used by the codecs library to configure the codec for use .


def encode(self, input, errors='strict'):
        """
        Encodes a byte string into trytes.
        """
        if isinstance(input, memoryview):
            input = input.tobytes()

        if not isinstance(input, (binary_type, bytearray)):
            raise with_context(
                exc=TypeError(
                    "Can't encode {type}; byte string expected.".format(
                        type=type(input).__name__,
                    )),

                context={
                    'input': input,
                },
            )

        # :bc: In Python 2, iterating over a byte string yields
        # characters instead of integers.
        if not isinstance(input, bytearray):
            input = bytearray(input)

        trytes = bytearray()

        for c in input:
            second, first = divmod(c, len(self.alphabet))

            trytes.append(self.alphabet[first])
            trytes.append(self.alphabet[second])

        return binary_type(trytes), len(input)


def decode(self, input, errors='strict'):
        """
        Decodes a tryte string into bytes.
        """
        if isinstance(input, memoryview):
            input = input.tobytes()

        if not isinstance(input, (binary_type, bytearray)):
            raise with_context(
                exc=TypeError(
                    "Can't decode {type}; byte string expected.".format(
                        type=type(input).__name__,
                    )),

                context={
                    'input': input,
                },
            )

        # :bc: In Python 2, iterating over a byte string yields
        # characters instead of integers.
        if not isinstance(input, bytearray):
            input = bytearray(input)

        bytes_ = bytearray()

        for i in range(0, len(input), 2):
            try:
                first, second = input[i:i + 2]
            except ValueError:
                if errors == 'strict':
                    raise with_context(
                        exc=TrytesDecodeError(
                            "'{name}' codec can't decode value; "
                            "tryte sequence has odd length.".format(
                                name=self.name,
                            ),
                        ),

                        context={
                            'input': input,
                        },
                    )
                elif errors == 'replace':
                    bytes_ += b'?'

                continue

            try:
                bytes_.append(
                    self.index[first]
                    + (self.index[second] * len(self.index))
                )
            except ValueError:
                # This combination of trytes yields a value > 255 when
                # decoded.
                # Naturally, we can't represent this using ASCII.
                if errors == 'strict':
                    raise with_context(
                        exc=TrytesDecodeError(
                            "'{name}' codec can't decode trytes {pair} "
                            "at position {i}-{j}: "
                            "ordinal not in range(255)".format(
                                name=self.name,
                                pair=chr(first) + chr(second),
                                i=i,
                                j=i + 1,
                            ),
                        ),

                        context={
                            'input': input,
                        }
                    )
                elif errors == 'replace':
                    bytes_ += b'?'

        return binary_type(bytes_), len(input)


def _find_addresses(self, seed, index, count, security_level, checksum):
        # type: (Seed, int, Optional[int], int, bool) -> List[Address]
        """
        Find addresses matching the command parameters.
        """
        generator = AddressGenerator(seed, security_level, checksum)

        if count is None:
            # Connect to Tangle and find the first address without any
            # transactions.
            for addy in generator.create_iterator(start=index):
                # We use addy.address here because FindTransactions does
                # not work on an address with a checksum
                response = FindTransactionsCommand(self.adapter)(
                    addresses=[addy.address],
                )

                if not response.get('hashes'):
                    return [addy]

        return generator.get_addresses(start=index, count=count)

def _find_addresses ( self , seed , index , count , security_level , checksum ) : generator = AddressGenerator ( seed , security_level , checksum ) if count is None : for addy in generator . create_iterator ( start = index ) : response = FindTransactionsCommand ( self . adapter ) ( addresses = [ addy . address ] , ) if not response . get ( 'hashes' ) : return [ addy ] return generator . get_addresses ( start = index , count = count )

Find addresses matching the command parameters .


def add_route(self, command, adapter):
        # type: (Text, AdapterSpec) -> RoutingWrapper
        """
        Adds a route to the wrapper.

        :param command:
            The name of the command to route (e.g., "attachToTangle").

        :param adapter:
            The adapter object or URI to route requests to.
        """
        if not isinstance(adapter, BaseAdapter):
            try:
                adapter = self.adapter_aliases[adapter]
            except KeyError:
                self.adapter_aliases[adapter] = adapter = resolve_adapter(
                    adapter
                )

        self.routes[command] = adapter

        return self

def add_route ( self , command , adapter ) : if not isinstance ( adapter , BaseAdapter ) : try : adapter = self . adapter_aliases [ adapter ] except KeyError : self . adapter_aliases [ adapter ] = adapter = resolve_adapter ( adapter ) self . routes [ command ] = adapter return self


def from_tryte_string(cls, trytes, hash_=None):
        # type: (TrytesCompatible, Optional[TransactionHash]) -> Transaction
        """
        Creates a Transaction object from a sequence of trytes.

        :param trytes:
            Raw trytes.  Should be exactly 2673 trytes long.

        :param hash_:
            The transaction hash, if available.

            If not provided, it will be computed from the transaction
            trytes.
        """
        tryte_string = TransactionTrytes(trytes)

        if not hash_:
            hash_trits = [0] * HASH_LENGTH  # type: MutableSequence[int]

            sponge = Curl()
            sponge.absorb(tryte_string.as_trits())
            sponge.squeeze(hash_trits)

            hash_ = TransactionHash.from_trits(hash_trits)

        return cls(
            hash_=hash_,
            signature_message_fragment=Fragment(tryte_string[0:2187]),
            address=Address(tryte_string[2187:2268]),
            value=int_from_trits(tryte_string[2268:2295].as_trits()),
            legacy_tag=Tag(tryte_string[2295:2322]),
            timestamp=int_from_trits(tryte_string[2322:2331].as_trits()),
            current_index=int_from_trits(tryte_string[2331:2340].as_trits()),
            last_index=int_from_trits(tryte_string[2340:2349].as_trits()),
            bundle_hash=BundleHash(tryte_string[2349:2430]),
            trunk_transaction_hash=TransactionHash(tryte_string[2430:2511]),
            branch_transaction_hash=TransactionHash(tryte_string[2511:2592]),
            tag=Tag(tryte_string[2592:2619]),

            attachment_timestamp=int_from_trits(
                tryte_string[2619:2628].as_trits()),

            attachment_timestamp_lower_bound=int_from_trits(
                tryte_string[2628:2637].as_trits()),

            attachment_timestamp_upper_bound=int_from_trits(
                tryte_string[2637:2646].as_trits()),

            nonce=Nonce(tryte_string[2646:2673]),
        )

def from_tryte_string ( cls , trytes , hash_ = None ) : tryte_string = TransactionTrytes ( trytes ) if not hash_ : hash_trits = [ 0 ] * HASH_LENGTH sponge = Curl ( ) sponge . absorb ( tryte_string . as_trits ( ) ) sponge . squeeze ( hash_trits ) hash_ = TransactionHash . from_trits ( hash_trits ) return cls ( hash_ = hash_ , signature_message_fragment = Fragment ( tryte_string [ 0 : 2187 ] ) , address = Address ( tryte_string [ 2187 : 2268 ] ) , value = int_from_trits ( tryte_string [ 2268 : 2295 ] . as_trits ( ) ) , legacy_tag = Tag ( tryte_string [ 2295 : 2322 ] ) , timestamp = int_from_trits ( tryte_string [ 2322 : 2331 ] . as_trits ( ) ) , current_index = int_from_trits ( tryte_string [ 2331 : 2340 ] . as_trits ( ) ) , last_index = int_from_trits ( tryte_string [ 2340 : 2349 ] . as_trits ( ) ) , bundle_hash = BundleHash ( tryte_string [ 2349 : 2430 ] ) , trunk_transaction_hash = TransactionHash ( tryte_string [ 2430 : 2511 ] ) , branch_transaction_hash = TransactionHash ( tryte_string [ 2511 : 2592 ] ) , tag = Tag ( tryte_string [ 2592 : 2619 ] ) , attachment_timestamp = int_from_trits ( tryte_string [ 2619 : 2628 ] . as_trits ( ) ) , attachment_timestamp_lower_bound = int_from_trits ( tryte_string [ 2628 : 2637 ] . as_trits ( ) ) , attachment_timestamp_upper_bound = int_from_trits ( tryte_string [ 2637 : 2646 ] . as_trits ( ) ) , nonce = Nonce ( tryte_string [ 2646 : 2673 ] ) , )

Creates a Transaction object from a sequence of trytes .


def as_json_compatible(self):
        # type: () -> dict
        """
        Returns a JSON-compatible representation of the object.

        References:

        - :py:class:`iota.json.JsonEncoder`.
        """
        return {
            'hash_': self.hash,
            'signature_message_fragment': self.signature_message_fragment,
            'address': self.address,
            'value': self.value,
            'legacy_tag': self.legacy_tag,
            'timestamp': self.timestamp,
            'current_index': self.current_index,
            'last_index': self.last_index,
            'bundle_hash': self.bundle_hash,
            'trunk_transaction_hash': self.trunk_transaction_hash,
            'branch_transaction_hash': self.branch_transaction_hash,
            'tag': self.tag,
            'attachment_timestamp': self.attachment_timestamp,

            'attachment_timestamp_lower_bound':
                self.attachment_timestamp_lower_bound,

            'attachment_timestamp_upper_bound':
                self.attachment_timestamp_upper_bound,

            'nonce': self.nonce,
        }

def as_json_compatible ( self ) : return { 'hash_' : self . hash , 'signature_message_fragment' : self . signature_message_fragment , 'address' : self . address , 'value' : self . value , 'legacy_tag' : self . legacy_tag , 'timestamp' : self . timestamp , 'current_index' : self . current_index , 'last_index' : self . last_index , 'bundle_hash' : self . bundle_hash , 'trunk_transaction_hash' : self . trunk_transaction_hash , 'branch_transaction_hash' : self . branch_transaction_hash , 'tag' : self . tag , 'attachment_timestamp' : self . attachment_timestamp , 'attachment_timestamp_lower_bound' : self . attachment_timestamp_lower_bound , 'attachment_timestamp_upper_bound' : self . attachment_timestamp_upper_bound , 'nonce' : self . nonce , }

Returns a JSON - compatible representation of the object .


def get_signature_validation_trytes(self):
        # type: () -> TryteString
        """
        Returns the values needed to validate the transaction's
        ``signature_message_fragment`` value.
        """
        return (
                self.address.address
                + self.value_as_trytes
                + self.legacy_tag
                + self.timestamp_as_trytes
                + self.current_index_as_trytes
                + self.last_index_as_trytes
        )

def get_signature_validation_trytes ( self ) : return ( self . address . address + self . value_as_trytes + self . legacy_tag + self . timestamp_as_trytes + self . current_index_as_trytes + self . last_index_as_trytes )

Returns the values needed to validate the transaction s signature_message_fragment value .


def is_confirmed(self, new_is_confirmed):
        # type: (bool) -> None
        """
        Sets the ``is_confirmed`` for the bundle.
        """
        self._is_confirmed = new_is_confirmed

        for txn in self:
            txn.is_confirmed = new_is_confirmed

def is_confirmed ( self , new_is_confirmed ) : self . _is_confirmed = new_is_confirmed for txn in self : txn . is_confirmed = new_is_confirmed


def get_messages(self, errors='drop'):
        # type: (Text) -> List[Text]
        """
        Attempts to decipher encoded messages from the transactions in
        the bundle.

        :param errors:
            How to handle trytes that can't be converted, or bytes that
            can't be decoded using UTF-8:

            'drop'
                Drop the trytes from the result.

            'strict'
                Raise an exception.

            'replace'
                Replace with a placeholder character.

            'ignore'
                Omit the invalid tryte/byte sequence.
        """
        decode_errors = 'strict' if errors == 'drop' else errors

        messages = []

        for group in self.group_transactions():
            # Ignore inputs.
            if group[0].value < 0:
                continue

            message_trytes = TryteString(b'')
            for txn in group:
                message_trytes += txn.signature_message_fragment

            if message_trytes:
                try:
                    messages.append(message_trytes.decode(decode_errors))
                except (TrytesDecodeError, UnicodeDecodeError):
                    if errors != 'drop':
                        raise

        return messages

def get_messages ( self , errors = 'drop' ) : decode_errors = 'strict' if errors == 'drop' else errors messages = [ ] for group in self . group_transactions ( ) : if group [ 0 ] . value < 0 : continue message_trytes = TryteString ( b'' ) for txn in group : message_trytes += txn . signature_message_fragment if message_trytes : try : messages . append ( message_trytes . decode ( decode_errors ) ) except ( TrytesDecodeError , UnicodeDecodeError ) : if errors != 'drop' : raise return messages

Attempts to decipher encoded messages from the transactions in the bundle .