<commit_before># coding: utf-8
import binascii
import warnings

from .asset import Asset
from .horizon import HORIZON_LIVE, HORIZON_TEST
from .horizon import Horizon
from .keypair import Keypair
from . import memo
from .network import NETWORKS, Network
from . import operation
from .transaction import Transaction
from .transaction_envelope import TransactionEnvelope as Te
from .exceptions import NoStellarSecretOrAddressError, StellarAddressInvalidError, SequenceError
from .federation import federation, FederationError


class Builder(object):
    """The :class:`Builder` object, which uses the builder pattern to create
    a list of operations in a :class:`Transaction`, ultimately to be submitted
    as a :class:`TransactionEnvelope` to the network via Horizon (see
    :class:`Horizon`).

    :param str secret: The base32 secret seed for the source address.
    :param str address: The base32 source address.
    :param str horizon_uri: The horizon instance to use for submitting the created
        transaction.
    :param str network: The network to connect to for verifying and retrieving
        additional attributes from. 'PUBLIC' is an alias for 'Public Global Stellar Network ; September 2015',
        'TESTNET' is an alias for 'Test SDF Network ; September 2015'. Defaults to TESTNET.
    :param sequence: The sequence number to use for submitting this
        transaction with (must be the *current* sequence number of the source
        account)
    :type sequence: int, str
    :param int fee: Base fee in stroops. The network base fee is obtained by default from the latest ledger.
        Transaction fee is equal to base fee times number of operations in this transaction.
    """

    def __init__(self,
                 secret=None,
                 address=None,
                 horizon_uri=None,
                 network=None,
                 sequence=None,
                 fee=None):
        if secret:
            self.keypair = Keypair.from_seed(secret)
            self.address = self.keypair.address().decode()
        else:
            self.keypair = None
            self.address = None

        if address is None and secret is None:
            raise NoStellarSecretOrAddressError('Stellar secret or address is required.')
        if address is not None and secret is None:
            self.address = Keypair.from_address(address).address().decode()
            self.keypair = None

        if network is None:
            self.network = 'TESTNET'
        elif network.upper() in NETWORKS:
            self.network = network.upper()
        else:
            self.network = network

        if horizon_uri:
            self.horizon = Horizon(horizon_uri)
        elif self.network == 'PUBLIC':
            self.horizon = Horizon(HORIZON_LIVE)
        else:
            self.horizon = Horizon(HORIZON_TEST)

        if sequence:
            self.sequence = int(sequence)
        elif self.address:
            self.sequence = self.get_sequence()
        else:
            self.sequence = None  # Do we need this? Doesn't the address always exist?

        if fee is None:
            self.fee = self.horizon.base_fee()
        else:
            self.fee = fee

        self.ops = []
        self.time_bounds = None
        self.memo = memo.NoneMemo()
        self.tx = None
        self.te = None

    def append_op(self, operation):
        """Append an :class:`Operation <stellar_base.operation.Operation>` to
        the list of operations.

        Add the operation specified if it doesn't already exist in the list of
        operations of this :class:`Builder` instance.

        :param operation: The operation to append to the list of operations.
        :type operation: :class:`Operation`
        :return: This builder instance.

        """
        if operation not in self.ops:
            self.ops.append(operation)
        return self

    def append_create_account_op(self,
                                 destination,
                                 starting_balance,
                                 source=None):
        """Append a :class:`CreateAccount
        <stellar_base.operation.CreateAccount>` operation to the list of
        operations.

        :param str destination: Account address that is created and funded.
        :param str starting_balance: Amount of XLM to send to the newly created
            account. This XLM comes from the source account.
        :param str source: The source address to deduct funds from to fund the
            new account.
        :return: This builder instance.

        """
        op = operation.CreateAccount(destination, starting_balance, source)
        return self.append_op(op)

    def append_trust_op(self, destination, code, limit=None, source=None):  # pragma: no cover
        """append_trust_op will be deprecated in the future, use append_change_trust_op instead.
        Append a :class:`ChangeTrust <stellar_base.operation.ChangeTrust>`
        operation to the list of operations.

        :param str destination: The issuer address for the asset.
        :param str code: The asset code for the asset.
        :param str limit: The limit of the new trustline.
        :param str source: The source address to add the trustline to.
        :return: This builder instance.

        """
        warnings.warn(
            "append_trust_op will be deprecated in the future, use append_change_trust_op instead.",
            PendingDeprecationWarning
        )  # pragma: no cover

        return self.append_change_trust_op(asset_code=code, asset_issuer=destination, limit=limit,
                                           source=source)  # pragma: no cover

    def append_change_trust_op(self, asset_code, asset_issuer, limit=None, source=None):
        """Append a :class:`ChangeTrust <stellar_base.operation.ChangeTrust>`
        operation to the list of operations.

        :param str asset_issuer: The issuer address for the asset.
        :param str asset_code: The asset code for the asset.
        :param str limit: The limit of the new trustline.
        :param str source: The source address to add the trustline to.
        :return: This builder instance.

        """
        asset = Asset(asset_code, asset_issuer)
        op = operation.ChangeTrust(asset, limit, source)
        return self.append_op(op)

    def append_payment_op(self,
                          destination,
                          amount,
                          asset_code='XLM',
                          asset_issuer=None,
                          source=None):
        """Append a :class:`Payment <stellar_base.operation.Payment>` operation
        to the list of operations.

        :param str destination: Account address that receives the payment.
        :param str amount: The amount of the currency to send in the payment.
        :param str asset_code: The asset code for the asset to send.
        :param asset_issuer: The address of the issuer of the asset.
        :type asset_issuer: str, None
        :param str source: The source address of the payment.
        :return: This builder instance.

        """
        asset = Asset(code=asset_code, issuer=asset_issuer)
        op = operation.Payment(destination, asset, amount, source)
        return self.append_op(op)

    def append_path_payment_op(self,
                               destination,
                               send_code,
                               send_issuer,
                               send_max,
                               dest_code,
                               dest_issuer,
                               dest_amount,
                               path,
                               source=None):
        """Append a :class:`PathPayment <stellar_base.operation.PathPayment>`
        operation to the list of operations.

        :param str destination: The destination address (Account ID) for the
            payment.
        :param str send_code: The asset code for the source asset deducted from
            the source account.
        :param send_issuer: The address of the issuer of the source asset.
        :type send_issuer: str, None
        :param str send_max: The maximum amount of send asset to deduct
            (excluding fees).
        :param str dest_code: The asset code for the final destination asset
            sent to the recipient.
        :param dest_issuer: Account address that receives the payment.
        :type dest_issuer: str, None
        :param str dest_amount: The amount of destination asset the destination
            account receives.
        :param list path: A list of asset tuples, each tuple containing a
            (asset_code, asset_issuer) for each asset in the path. For the native
            asset, `None` is used for the asset_issuer.
        :param str source: The source address of the path payment.
        :return: This builder instance.

        """
        # path: a list of asset tuple which contains asset_code and asset_issuer,
        # [(asset_code, asset_issuer), (asset_code, asset_issuer)] for native asset you can deliver
        # ('XLM', None)

        send_asset = Asset(send_code, send_issuer)
        dest_asset = Asset(dest_code, dest_issuer)

        assets = []
        for p in path:
            assets.append(Asset(p[0], p[1]))
        op = operation.PathPayment(destination, send_asset, send_max,
                                   dest_asset, dest_amount, assets, source)
        return self.append_op(op)

    def append_allow_trust_op(self,
                              trustor,
                              asset_code,
                              authorize,
                              source=None):
        """Append an :class:`AllowTrust <stellar_base.operation.AllowTrust>`
        operation to the list of operations.

        :param str trustor: The account of the recipient of the trustline.
        :param str asset_code:  The asset of the trustline the source account
            is authorizing. For example, if an anchor wants to allow another
            account to hold its USD credit, the type is USD:anchor.
        :param bool authorize: Flag indicating whether the trustline is
            authorized.
        :param str source: The source address that is establishing the trust in
            the allow trust operation.
        :return: This builder instance.

        """
        op = operation.AllowTrust(trustor, asset_code, authorize, source)
        return self.append_op(op)

    def append_set_options_op(self,
                              inflation_dest=None,
                              clear_flags=None,
                              set_flags=None,
                              master_weight=None,
                              low_threshold=None,
                              med_threshold=None,
                              high_threshold=None,
                              home_domain=None,
                              signer_address=None,
                              signer_type=None,
                              signer_weight=None,
                              source=None):
        """Append a :class:`SetOptions <stellar_base.operation.SetOptions>`
        operation to the list of operations.

        .. _Accounts:
            https://www.stellar.org/developers/guides/concepts/accounts.html

        :param str inflation_dest: The address in which to send inflation to on
            an :class:`Inflation <stellar_base.operation.Inflation>` operation.
        :param int clear_flags: Indicates which flags to clear. For details
            about the flags, please refer to Stellar's documentation on
            `Accounts`_. The bit mask integer subtracts from the existing flags
            of the account. This allows for setting specific bits without
            knowledge of existing flags.
        :param int set_flags: Indicates which flags to set. For details about
            the flags, please refer to Stellar's documentation on `Accounts`_.
            The bit mask integer adds onto the existing flags of the account.
            This allows for setting specific bits without knowledge of existing
            flags.
        :param int master_weight: Weight of the master key. This account may
            also add other keys with which to sign transactions using the
            signer param.
        :param int low_threshold: A number from 0-255 representing the
            threshold this account sets on all operations it performs that have
            a `low threshold
            <https://www.stellar.org/developers/guides/concepts/multi-sig.html>`_.
        :param int med_threshold: A number from 0-255 representing the
            threshold this account sets on all operations it performs that have
            a `medium threshold
            <https://www.stellar.org/developers/guides/concepts/multi-sig.html>`_.
        :param int high_threshold: A number from 0-255 representing the
            threshold this account sets on all operations it performs that have
            a `high threshold
            <https://www.stellar.org/developers/guides/concepts/multi-sig.html>`_.
        :param str home_domain: Sets the home domain of an account. See
            Stellar's documentation on `Federation
            <https://www.stellar.org/developers/guides/concepts/federation.html>`_.
        :param signer_address: The address of the new signer to add to the
            source account.
        :type signer_address: str, bytes
        :param str signer_type: The type of signer to add to the account. Must
            be in ('ed25519PublicKey', 'hashX', 'preAuthTx'). See Stellar's
            documentation for `Multi-Sign
            <https://www.stellar.org/developers/guides/concepts/multi-sig.html>`_
            for more information.
        :param int signer_weight: The weight of the signer. If the weight is 0,
            the signer will be deleted.
        :param str source: The source address for which options are being set.
        :return: This builder instance.

        """

        op = operation.SetOptions(inflation_dest, clear_flags, set_flags,
                                  master_weight, low_threshold, med_threshold,
                                  high_threshold, home_domain, signer_address,
                                  signer_type, signer_weight, source)
        return self.append_op(op)

    def append_hashx_signer(self, hashx, signer_weight, source=None):
        """Add a HashX signer to an account.

        Add a HashX signer to an account via a :class:`SetOptions
        <stellar_base.operation.SetOptions` operation. This is a helper
        function for :meth:`append_set_options_op`.

        :param hashx: The address of the new hashX signer.
        :type hashx: str, bytes
        :param int signer_weight: The weight of the new signer.
        :param str source: The source account that is adding a signer to its
            list of signers.
        :return: This builder instance.

        """
        return self.append_set_options_op(
            signer_address=hashx,
            signer_type='hashX',
            signer_weight=signer_weight,
            source=source)

    def append_pre_auth_tx_signer(self,
                                  pre_auth_tx,
                                  signer_weight,
                                  source=None):
        """Add a PreAuthTx signer to an account.

        Add a PreAuthTx signer to an account via a :class:`SetOptions
        <stellar_base.operation.SetOptions` operation. This is a helper
        function for :meth:`append_set_options_op`.

        :param pre_auth_tx: The address of the new preAuthTx signer - obtained by calling `hash_meta` on the TransactionEnvelope.
        :type pre_auth_tx: str, bytes
        :param int signer_weight: The weight of the new signer.
        :param str source: The source account that is adding a signer to its
            list of signers.
        :return: This builder instance.

        """
        return self.append_set_options_op(
            signer_address=pre_auth_tx,
            signer_type='preAuthTx',
            signer_weight=signer_weight,
            source=source)

    def append_manage_offer_op(self,
                               selling_code,
                               selling_issuer,
                               buying_code,
                               buying_issuer,
                               amount,
                               price,
                               offer_id=0,
                               source=None):
        """Append a :class:`ManageOffer <stellar_base.operation.ManageOffer>`
        operation to the list of operations.

        :param str selling_code: The asset code for the asset the offer creator
            is selling.
        :param selling_issuer: The issuing address for the asset the offer
            creator is selling.
        :type selling_issuer: str, None
        :param str buying_code: The asset code for the asset the offer creator
            is buying.
        :param buying_issuer: The issuing address for the asset the offer
            creator is selling.
        :type buying_issuer: str, None
        :param str amount: Amount of the asset being sold. Set to 0 if you want
            to delete an existing offer.
        :param price: Price of 1 unit of selling in terms of buying. You can pass
            in a number as a string or a dict like `{n: numerator, d: denominator}`
        :type price: str, dict
        :param int offer_id: The ID of the offer. 0 for new offer. Set to
            existing offer ID to update or delete.
        :param str source: The source address that is managing an offer on
            Stellar's distributed exchange.
        :return: This builder instance.

        """
        warnings.warn(
            "append_manage_offer_op has been deprecated, use append_manage_sell_offer_op instead.",
            DeprecationWarning
        )  # pragma: no cover
        selling = Asset(selling_code, selling_issuer)
        buying = Asset(buying_code, buying_issuer)
        op = operation.ManageOffer(selling, buying, amount, price, offer_id,
                                   source)
        return self.append_op(op)

    def append_manage_buy_offer_op(self,
                                   selling_code,
                                   selling_issuer,
                                   buying_code,
                                   buying_issuer,
                                   amount,
                                   price,
                                   offer_id=0,
                                   source=None):
        """Append a :class:`ManageBuyOfferOp <stellar_base.operation.ManageBuyOfferOp>`
        operation to the list of operations.

        :param str selling_code: The asset code for the asset the offer creator
            is selling.
        :param selling_issuer: The issuing address for the asset the offer
            creator is selling.
        :type selling_issuer: str, None
        :param str buying_code: The asset code for the asset the offer creator
            is buying.
        :param buying_issuer: The issuing address for the asset the offer
            creator is selling.
        :type buying_issuer: str, None
        :param str amount: Amount being bought. if set to. Set to 0 if you want
            to delete an existing offer.
        :param price: Price of thing being bought in terms of what you are selling. You can pass
            in a number as a string or a dict like `{n: numerator, d: denominator}`
        :type price: str, dict
        :param int offer_id: The ID of the offer. 0 for new offer. Set to
            existing offer ID to update or delete.
        :param str source: The source address that is managing an offer on
            Stellar's distributed exchange.
        :return: This builder instance.

        """
        selling = Asset(selling_code, selling_issuer)
        buying = Asset(buying_code, buying_issuer)
        op = operation.ManageBuyOfferOp(selling, buying, amount, price, offer_id,
                                        source)
        return self.append_op(op)

    def append_manage_sell_offer_op(self,
                                    selling_code,
                                    selling_issuer,
                                    buying_code,
                                    buying_issuer,
                                    amount,
                                    price,
                                    offer_id=0,
                                    source=None):
        """Append a :class:`ManageSellOffer <stellar_base.operation.ManageSellOffer>`
        operation to the list of operations.

        :param str selling_code: The asset code for the asset the offer creator
            is selling.<commit_msg>typo: spelling<commit_after># coding: utf-8
import binascii
import warnings

from .asset import Asset
from .horizon import HORIZON_LIVE, HORIZON_TEST
from .horizon import Horizon
from .keypair import Keypair
from . import memo
from .network import NETWORKS, Network
from . import operation
from .transaction import Transaction
from .transaction_envelope import TransactionEnvelope as Te
from .exceptions import NoStellarSecretOrAddressError, StellarAddressInvalidError, SequenceError
from .federation import federation, FederationError


class Builder(object):
    """The :class:`Builder` object, which uses the builder pattern to create
    a list of operations in a :class:`Transaction`, ultimately to be submitted
    as a :class:`TransactionEnvelope` to the network via Horizon (see
    :class:`Horizon`).

    :param str secret: The base32 secret seed for the source address.
    :param str address: The base32 source address.
    :param str horizon_uri: The horizon instance to use for submitting the created
        transaction.
    :param str network: The network to connect to for verifying and retrieving
        additional attributes from. 'PUBLIC' is an alias for 'Public Global Stellar Network ; September 2015',
        'TESTNET' is an alias for 'Test SDF Network ; September 2015'. Defaults to TESTNET.
    :param sequence: The sequence number to use for submitting this
        transaction with (must be the *current* sequence number of the source
        account)
    :type sequence: int, str
    :param int fee: Base fee in stroops. The network base fee is obtained by default from the latest ledger.
        Transaction fee is equal to base fee times number of operations in this transaction.
    """

    def __init__(self,
                 secret=None,
                 address=None,
                 horizon_uri=None,
                 network=None,
                 sequence=None,
                 fee=None):
        if secret:
            self.keypair = Keypair.from_seed(secret)
            self.address = self.keypair.address().decode()
        else:
            self.keypair = None
            self.address = None

        if address is None and secret is None:
            raise NoStellarSecretOrAddressError('Stellar secret or address is required.')
        if address is not None and secret is None:
            self.address = Keypair.from_address(address).address().decode()
            self.keypair = None

        if network is None:
            self.network = 'TESTNET'
        elif network.upper() in NETWORKS:
            self.network = network.upper()
        else:
            self.network = network

        if horizon_uri:
            self.horizon = Horizon(horizon_uri)
        elif self.network == 'PUBLIC':
            self.horizon = Horizon(HORIZON_LIVE)
        else:
            self.horizon = Horizon(HORIZON_TEST)

        if sequence:
            self.sequence = int(sequence)
        elif self.address:
            self.sequence = self.get_sequence()
        else:
            self.sequence = None  # Do we need this? Doesn't the address always exist?

        if fee is None:
            self.fee = self.horizon.base_fee()
        else:
            self.fee = fee

        self.ops = []
        self.time_bounds = None
        self.memo = memo.NoneMemo()
        self.tx = None
        self.te = None

    def append_op(self, operation):
        """Append an :class:`Operation <stellar_base.operation.Operation>` to
        the list of operations.

        Add the operation specified if it doesn't already exist in the list of
        operations of this :class:`Builder` instance.

        :param operation: The operation to append to the list of operations.
        :type operation: :class:`Operation`
        :return: This builder instance.

        """
        if operation not in self.ops:
            self.ops.append(operation)
        return self

    def append_create_account_op(self,
                                 destination,
                                 starting_balance,
                                 source=None):
        """Append a :class:`CreateAccount
        <stellar_base.operation.CreateAccount>` operation to the list of
        operations.

        :param str destination: Account address that is created and funded.
        :param str starting_balance: Amount of XLM to send to the newly created
            account. This XLM comes from the source account.
        :param str source: The source address to deduct funds from to fund the
            new account.
        :return: This builder instance.

        """
        op = operation.CreateAccount(destination, starting_balance, source)
        return self.append_op(op)

    def append_trust_op(self, destination, code, limit=None, source=None):  # pragma: no cover
        """append_trust_op will be deprecated in the future, use append_change_trust_op instead.
        Append a :class:`ChangeTrust <stellar_base.operation.ChangeTrust>`
        operation to the list of operations.

        :param str destination: The issuer address for the asset.
        :param str code: The asset code for the asset.
        :param str limit: The limit of the new trustline.
        :param str source: The source address to add the trustline to.
        :return: This builder instance.

        """
        warnings.warn(
            "append_trust_op will be deprecated in the future, use append_change_trust_op instead.",
            PendingDeprecationWarning
        )  # pragma: no cover

        return self.append_change_trust_op(asset_code=code, asset_issuer=destination, limit=limit,
                                           source=source)  # pragma: no cover

    def append_change_trust_op(self, asset_code, asset_issuer, limit=None, source=None):
        """Append a :class:`ChangeTrust <stellar_base.operation.ChangeTrust>`
        operation to the list of operations.

        :param str asset_issuer: The issuer address for the asset.
        :param str asset_code: The asset code for the asset.
        :param str limit: The limit of the new trustline.
        :param str source: The source address to add the trustline to.
        :return: This builder instance.

        """
        asset = Asset(asset_code, asset_issuer)
        op = operation.ChangeTrust(asset, limit, source)
        return self.append_op(op)

    def append_payment_op(self,
                          destination,
                          amount,
                          asset_code='XLM',
                          asset_issuer=None,
                          source=None):
        """Append a :class:`Payment <stellar_base.operation.Payment>` operation
        to the list of operations.

        :param str destination: Account address that receives the payment.
        :param str amount: The amount of the currency to send in the payment.
        :param str asset_code: The asset code for the asset to send.
        :param asset_issuer: The address of the issuer of the asset.
        :type asset_issuer: str, None
        :param str source: The source address of the payment.
        :return: This builder instance.

        """
        asset = Asset(code=asset_code, issuer=asset_issuer)
        op = operation.Payment(destination, asset, amount, source)
        return self.append_op(op)

    def append_path_payment_op(self,
                               destination,
                               send_code,
                               send_issuer,
                               send_max,
                               dest_code,
                               dest_issuer,
                               dest_amount,
                               path,
                               source=None):
        """Append a :class:`PathPayment <stellar_base.operation.PathPayment>`
        operation to the list of operations.

        :param str destination: The destination address (Account ID) for the
            payment.
        :param str send_code: The asset code for the source asset deducted from
            the source account.
        :param send_issuer: The address of the issuer of the source asset.
        :type send_issuer: str, None
        :param str send_max: The maximum amount of send asset to deduct
            (excluding fees).
        :param str dest_code: The asset code for the final destination asset
            sent to the recipient.
        :param dest_issuer: Account address that receives the payment.
        :type dest_issuer: str, None
        :param str dest_amount: The amount of destination asset the destination
            account receives.
        :param list path: A list of asset tuples, each tuple containing a
            (asset_code, asset_issuer) for each asset in the path. For the native
            asset, `None` is used for the asset_issuer.
        :param str source: The source address of the path payment.
        :return: This builder instance.

        """
        # path: a list of asset tuple which contains asset_code and asset_issuer,
        # [(asset_code, asset_issuer), (asset_code, asset_issuer)] for native asset you can deliver
        # ('XLM', None)

        send_asset = Asset(send_code, send_issuer)
        dest_asset = Asset(dest_code, dest_issuer)

        assets = []
        for p in path:
            assets.append(Asset(p[0], p[1]))
        op = operation.PathPayment(destination, send_asset, send_max,
                                   dest_asset, dest_amount, assets, source)
        return self.append_op(op)

    def append_allow_trust_op(self,
                              trustor,
                              asset_code,
                              authorize,
                              source=None):
        """Append an :class:`AllowTrust <stellar_base.operation.AllowTrust>`
        operation to the list of operations.

        :param str trustor: The account of the recipient of the trustline.
        :param str asset_code:  The asset of the trustline the source account
            is authorizing. For example, if an anchor wants to allow another
            account to hold its USD credit, the type is USD:anchor.
        :param bool authorize: Flag indicating whether the trustline is
            authorized.
        :param str source: The source address that is establishing the trust in
            the allow trust operation.
        :return: This builder instance.

        """
        op = operation.AllowTrust(trustor, asset_code, authorize, source)
        return self.append_op(op)

    def append_set_options_op(self,
                              inflation_dest=None,
                              clear_flags=None,
                              set_flags=None,
                              master_weight=None,
                              low_threshold=None,
                              med_threshold=None,
                              high_threshold=None,
                              home_domain=None,
                              signer_address=None,
                              signer_type=None,
                              signer_weight=None,
                              source=None):
        """Append a :class:`SetOptions <stellar_base.operation.SetOptions>`
        operation to the list of operations.

        .. _Accounts:
            https://www.stellar.org/developers/guides/concepts/accounts.html

        :param str inflation_dest: The address in which to send inflation to on
            an :class:`Inflation <stellar_base.operation.Inflation>` operation.
        :param int clear_flags: Indicates which flags to clear. For details
            about the flags, please refer to Stellar's documentation on
            `Accounts`_. The bit mask integer subtracts from the existing flags
            of the account. This allows for setting specific bits without
            knowledge of existing flags.
        :param int set_flags: Indicates which flags to set. For details about
            the flags, please refer to Stellar's documentation on `Accounts`_.
            The bit mask integer adds onto the existing flags of the account.
            This allows for setting specific bits without knowledge of existing
            flags.
        :param int master_weight: Weight of the master key. This account may
            also add other keys with which to sign transactions using the
            signer param.
        :param int low_threshold: A number from 0-255 representing the
            threshold this account sets on all operations it performs that have
            a `low threshold
            <https://www.stellar.org/developers/guides/concepts/multi-sig.html>`_.
        :param int med_threshold: A number from 0-255 representing the
            threshold this account sets on all operations it performs that have
            a `medium threshold
            <https://www.stellar.org/developers/guides/concepts/multi-sig.html>`_.
        :param int high_threshold: A number from 0-255 representing the
            threshold this account sets on all operations it performs that have
            a `high threshold
            <https://www.stellar.org/developers/guides/concepts/multi-sig.html>`_.
        :param str home_domain: Sets the home domain of an account. See
            Stellar's documentation on `Federation
            <https://www.stellar.org/developers/guides/concepts/federation.html>`_.
        :param signer_address: The address of the new signer to add to the
            source account.
        :type signer_address: str, bytes
        :param str signer_type: The type of signer to add to the account. Must
            be in ('ed25519PublicKey', 'hashX', 'preAuthTx'). See Stellar's
            documentation for `Multi-Sign
            <https://www.stellar.org/developers/guides/concepts/multi-sig.html>`_
            for more information.
        :param int signer_weight: The weight of the signer. If the weight is 0,
            the signer will be deleted.
        :param str source: The source address for which options are being set.
        :return: This builder instance.

        """

        op = operation.SetOptions(inflation_dest, clear_flags, set_flags,
                                  master_weight, low_threshold, med_threshold,
                                  high_threshold, home_domain, signer_address,
                                  signer_type, signer_weight, source)
        return self.append_op(op)

    def append_hashx_signer(self, hashx, signer_weight, source=None):
        """Add a HashX signer to an account.

        Add a HashX signer to an account via a :class:`SetOptions
        <stellar_base.operation.SetOptions` operation. This is a helper
        function for :meth:`append_set_options_op`.

        :param hashx: The address of the new hashX signer.
        :type hashx: str, bytes
        :param int signer_weight: The weight of the new signer.
        :param str source: The source account that is adding a signer to its
            list of signers.
        :return: This builder instance.

        """
        return self.append_set_options_op(
            signer_address=hashx,
            signer_type='hashX',
            signer_weight=signer_weight,
            source=source)

    def append_pre_auth_tx_signer(self,
                                  pre_auth_tx,
                                  signer_weight,
                                  source=None):
        """Add a PreAuthTx signer to an account.

        Add a PreAuthTx signer to an account via a :class:`SetOptions
        <stellar_base.operation.SetOptions` operation. This is a helper
        function for :meth:`append_set_options_op`.

        :param pre_auth_tx: The address of the new preAuthTx signer - obtained by calling `hash_meta` on the TransactionEnvelope.
        :type pre_auth_tx: str, bytes
        :param int signer_weight: The weight of the new signer.
        :param str source: The source account that is adding a signer to its
            list of signers.
        :return: This builder instance.

        """
        return self.append_set_options_op(
            signer_address=pre_auth_tx,
            signer_type='preAuthTx',
            signer_weight=signer_weight,
            source=source)

    def append_manage_offer_op(self,
                               selling_code,
                               selling_issuer,
                               buying_code,
                               buying_issuer,
                               amount,
                               price,
                               offer_id=0,
                               source=None):
        """Append a :class:`ManageOffer <stellar_base.operation.ManageOffer>`
        operation to the list of operations.

        :param str selling_code: The asset code for the asset the offer creator
            is selling.
        :param selling_issuer: The issuing address for the asset the offer
            creator is selling.
        :type selling_issuer: str, None
        :param str buying_code: The asset code for the asset the offer creator
            is buying.
        :param buying_issuer: The issuing address for the asset the offer
            creator is selling.
        :type buying_issuer: str, None
        :param str amount: Amount of the asset being sold. Set to 0 if you want
            to delete an existing offer.
        :param price: Price of 1 unit of selling in terms of buying. You can pass
            in a number as a string or a dict like `{n: numerator, d: denominator}`
        :type price: str, dict
        :param int offer_id: The ID of the offer. 0 for new offer. Set to
            existing offer ID to update or delete.
        :param str source: The source address that is managing an offer on
            Stellar's distributed exchange.
        :return: This builder instance.

        """
        warnings.warn(
            "append_manage_offer_op has been deprecated, use append_manage_sell_offer_op instead.",
            DeprecationWarning
        )  # pragma: no cover
        selling = Asset(selling_code, selling_issuer)
        buying = Asset(buying_code, buying_issuer)
        op = operation.ManageOffer(selling, buying, amount, price, offer_id,
                                   source)
        return self.append_op(op)

    def append_manage_buy_offer_op(self,
                                   selling_code,
                                   selling_issuer,
                                   buying_code,
                                   buying_issuer,
                                   amount,
                                   price,
                                   offer_id=0,
                                   source=None):
        """Append a :class:`ManageBuyOffer <stellar_base.operation.ManageBuyOffer>`
        operation to the list of operations.

        :param str selling_code: The asset code for the asset the offer creator
            is selling.
        :param selling_issuer: The issuing address for the asset the offer
            creator is selling.
        :type selling_issuer: str, None
        :param str buying_code: The asset code for the asset the offer creator
            is buying.
        :param buying_issuer: The issuing address for the asset the offer
            creator is selling.
        :type buying_issuer: str, None
        :param str amount: Amount being bought. if set to. Set to 0 if you want
            to delete an existing offer.
        :param price: Price of thing being bought in terms of what you are selling. You can pass
            in a number as a string or a dict like `{n: numerator, d: denominator}`
        :type price: str, dict
        :param int offer_id: The ID of the offer. 0 for new offer. Set to
            existing offer ID to update or delete.
        :param str source: The source address that is managing an offer on
            Stellar's distributed exchange.
        :return: This builder instance.

        """
        selling = Asset(selling_code, selling_issuer)
        buying = Asset(buying_code, buying_issuer)
        op = operation.ManageBuyOffer(selling, buying, amount, price, offer_id,
                                        source)
        return self.append_op(op)

    def append_manage_sell_offer_op(self,
                                    selling_code,
                                    selling_issuer,
                                    buying_code,
                                    buying_issuer,
                                    amount,
                                    price,
                                    offer_id=0,
                                    source=None):
        """Append a :class:`ManageSellOffer <stellar_base.operation.ManageSellOffer>`
        operation to the list of operations.

        :param str selling_code: The asset code for the asset the offer creator
            is selling.
{'fraction_non_alphanumeric': 0.0598302856459902, 'fraction_numerical': 0.0019600812716624835, 'mean_word_length': 1.8066550382396351, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 37, 'https://': 12, 'lorem ipsum': 0, 'www.': 12, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 60, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7285124', 'n_tokens_mistral': 10487, 'n_tokens_neox': 10005, 'n_words': 3862}