Пример #1
0
class Token(dict):
    """ hive-engine token dict

        :param str token: Name of the token
    """
    def __init__(self, symbol, api=None):
        if api is None:
            self.api = Api()
        else:
            self.api = api
        if isinstance(symbol, dict):
            self.symbol = symbol["symbol"]
            super(Token, self).__init__(symbol)
        else:
            self.symbol = symbol.upper()
            self.refresh()

    def refresh(self):
        info = self.get_info()
        if info is None:
            raise TokenDoesNotExists("Token %s does not exists!" % self.symbol)
        super(Token, self).__init__(info)

    def quantize(self, amount):
        """Round down a amount using the token precision and returns a Decimal object"""
        amount = decimal.Decimal(amount)
        places = decimal.Decimal(10) ** (-self["precision"])
        return amount.quantize(places, rounding=decimal.ROUND_DOWN)

    def get_info(self):
        """Returns information about the token"""
        token = self.api.find_one("tokens", "tokens", query={"symbol": self.symbol})
        if len(token) > 0:
            return token[0]
        else:
            return token

    def get_holder(self, limit=1000, offset=0):
        """Returns all token holders"""
        holder = self.api.find("tokens", "balances", query={"symbol": self.symbol}, limit=limit, offset=offset)
        return holder

    def get_market_info(self):
        """Returns market information"""
        metrics = self.api.find_one("market", "metrics", query={"symbol": self.symbol})
        if len(metrics) > 0:
            return metrics[0]
        else:
            return metrics

    def get_buy_book(self, limit=100, offset=0):
        """Returns the buy book"""
        holder = self.api.find("market", "buyBook", query={"symbol": self.symbol}, limit=limit, offset=offset)
        return holder

    def get_sell_book(self, limit=100, offset=0):
        """Returns the sell book"""
        holder = self.api.find("market", "sellBook", query={"symbol": self.symbol}, limit=limit, offset=offset)
        return holder
Пример #2
0
class Tokens(list):
    """ Access the steem-engine tokens
    """
    def __init__(self, api=None, **kwargs):
        if api is None:
            self.api = Api()
        else:
            self.api = api
        self.refresh()

    def refresh(self):
        super(Tokens, self).__init__(self.get_token_list())

    def get_token_list(self):
        """Returns all available token as list"""
        tokens = self.api.find("tokens", "tokens", query={})
        return tokens

    def get_token(self, symbol):
        """Returns Token from given token symbol. Is None
            when token does not exists.
        """
        for t in self:
            if t["symbol"].lower() == symbol.lower():
                return Token(t, api=self.api)
        return None
Пример #3
0
    def test_api(self):
        api = Api()
        result = api.get_latest_block_info()
        self.assertTrue(len(result) > 0)

        result = api.get_block_info(1910)
        self.assertTrue(len(result) > 0)

        result = api.get_transaction_info(
            "78aea60cdc4477cdf9437d8224e34c6033499169")
        self.assertTrue(len(result) > 0)

        result = api.get_contract("tokens")
        self.assertTrue(len(result) > 0)

        result = api.find("tokens", "tokens")
        self.assertTrue(len(result) > 0)

        result = api.find_one("tokens", "tokens")
        self.assertTrue(len(result) > 0)
Пример #4
0
class Nft(dict):
    """ Access the hive-engine Nfts
    """
    def __init__(self, symbol, api=None, blockchain_instance=None):
        if api is None:
            self.api = Api()
        else:
            self.api = api
        self.blockchain = blockchain_instance or shared_blockchain_instance()
        self.ssc_id = "ssc-mainnet-hive"
        if isinstance(symbol, dict):
            self.symbol = symbol["symbol"]
            super(Nft, self).__init__(symbol)
        else:
            self.symbol = symbol.upper()
            self.refresh()

    def refresh(self):
        info = self.get_info()
        if info is None:
            raise NftDoesNotExists("Nft %s does not exists!" % self.symbol)
        super(Nft, self).__init__(info)

    def get_info(self):
        """Returns information about the nft"""
        token = self.api.find_one("nft", "nfts", query={"symbol": self.symbol})
        if len(token) > 0:
            return token[0]
        else:
            return token

    @property
    def properties(self):
        return list(self["properties"].keys())

    @property
    def issuer(self):
        return self["issuer"]

    def get_property(self, property_name):
        """Returns all token properties"""
        return self.api.find_all("nft", "%sinstances" % self.symbol, query={"properties.name": property_name})

    def get_collection(self, account):
        """ Get NFT collection"""
        tokens = self.api.find_all("nft", "%sinstances" % self.symbol, query={"account": account})
        return tokens

    def get_id(self, _id):
        """ Get info about a token"""
        tokens = self.api.find_one("nft", "%sinstances" % self.symbol, query={"_id": _id})
        if len(tokens) > 0:
            return tokens[0]
        return tokens

    def get_trade_history(self, query={}, limit=-1, offset=0):
        """Returns market information
           :param dict query: can be priceSymbol, timestamp
        """
        if limit < 0 or limit > 1000:
            return self.api.find_all("nftmarket", "%stradesHistory" % self.symbol, query=query)
        else:
            return self.api.find("nftmarket", "%stradesHistory" % self.symbol, query=query, limit=limit, offset=offset)

    def get_open_interest(self, query={}, limit=-1, offset=0):
        """Returns open interests
           :param dict query: side, priceSymbol, grouping
        """
        if limit < 0 or limit > 1000:
            return self.api.find_all("nftmarket", "%sopenInterest" % self.symbol, query=query)
        else:
            return self.api.find("nftmarket", "%sopenInterest" % self.symbol, query=query, limit=limit, offset=offset)

    def get_sell_book(self, query={}, limit=-1, offset=0):
        """Returns the sell book
           :param dict query: can be ownedBy, account, nftId, grouping, priceSymbol 
        """
        if limit < 0 or limit > 1000:
            return self.api.find_all("nftmarket", "%ssellBook" % self.symbol, query=query)
        else:
            return self.api.find("nftmarket", "%ssellBook" % self.symbol, query=query, limit=limit, offset=offset)

    def update_url(self, url):
        """Updates the NFT project website

            :param str url: new url

            example:

            .. code-block:: python

                from hiveengine.nft import Nft
                from beem import Hive
                active_wif = "5xxxx"
                hive = Hive(keys=[active_wif])
                nft = Nft("STAR", blockchain_instance=hive)
                nft.update_url("https://new_url.com")
        """
        contract_payload = {"symbol": self.symbol.upper(), "url": url}
        json_data = {"contractName":"nft","contractAction":"updateUrl",
                     "contractPayload":contract_payload}
        assert self.blockchain.is_hive
        tx = self.blockchain.custom_json(self.ssc_id, json_data, required_posting_auths=[self["issuer"]])
        return tx

    def update_metadata(self, medadata):
        """Updates the metadata of a token.

            :param dict medadata: new medadata

            example:

            .. code-block:: python

                from hiveengine.nft import Nft
                from beem import Hive
                active_wif = "5xxxx"
                hive = Hive(keys=[active_wif])
                nft = Nft("STAR", blockchain_instance=hive)
                metadata = {"url": "https://mycoolnft.com",
                            "icon": "https://mycoolnft.com/token.jpg",
                            "desc": "This NFT will rock your world! It has features x, y, and z. So cool!"}
                nft.update_metadata(metadata)
        """
        contract_payload = {"symbol": self.symbol.upper(), "metadata": metadata}
        json_data = {"contractName":"nft","contractAction":"updateMetadata",
                     "contractPayload":contract_payload}
        assert self.blockchain.is_hive
        tx = self.blockchain.custom_json(self.ssc_id, json_data, required_posting_auths=[self["issuer"]])
        return tx

    def update_name(self, name):
        """Updates the user friendly name of an NFT.

            :param str name: new name

            example:

            .. code-block:: python

                from hiveengine.nft import Nft
                from beem import Hive
                posting_wif = "5xxxx"
                hive = Hive(keys=[posting_wif])
                nft = Nft("STAR", blockchain_instance=hive)
                nft.update_name("My Awesome NFT")
        """
        contract_payload = {"symbol": self.symbol.upper(), "name": name}
        json_data = {"contractName":"nft","contractAction":"updateName",
                     "contractPayload":contract_payload}
        assert self.blockchain.is_hive
        tx = self.blockchain.custom_json(self.ssc_id, json_data, required_posting_auths=[self["issuer"]])
        return tx

    def update_org_name(self, org_name):
        """Updates the name of the company/organization that manages an NFT.

            :param str org_name: new org_name

            example:

            .. code-block:: python

                from hiveengine.nft import Nft
                from beem import Hive
                posting_wif = "5xxxx"
                hive = Hive(keys=[posting_wif])
                nft = Nft("STAR", blockchain_instance=hive)
                nft.update_org_name("Nifty Company Inc")
        """
        contract_payload = {"symbol": self.symbol.upper(), "orgName": org_name}
        json_data = {"contractName":"nft","contractAction":"updateOrgName",
                     "contractPayload":contract_payload}
        assert self.blockchain.is_hive
        tx = self.blockchain.custom_json(self.ssc_id, json_data, required_posting_auths=[self["issuer"]])
        return tx

    def update_product_name(self, product_name):
        """Updates the name of the company/organization that manages an NFT.

            :param str org_name: new org_name

            example:

            .. code-block:: python

                from hiveengine.nft import Nft
                from beem import Hive
                posting_wif = "5xxxx"
                hive = Hive(keys=[posting_wif])
                nft = Nft("STAR", blockchain_instance=hive)
                nft.update_product_name("Acme Exploding NFTs")
        """
        contract_payload = {"symbol": self.symbol.upper(), "productName": product_name}
        json_data = {"contractName":"nft","contractAction":"updateProductName",
                     "contractPayload":contract_payload}
        assert self.blockchain.is_hive
        tx = self.blockchain.custom_json(self.ssc_id, json_data, required_posting_auths=[self["issuer"]])
        return tx

    def add_authorized_issuing_accounts(self, accounts):
        """Adds Hive accounts to the list of accounts that are authorized to issue
           new tokens on behalf of the NFT owner. 

            :param list accounts: A list of hive accounts to add to the authorized list

            example:

            .. code-block:: python

                from hiveengine.nft import Nft
                from beem import Hive
                active_wif = "5xxxx"
                hive = Hive(keys=[active_wif])
                nft = Nft("TESTNFT", blockchain_instance=hive)
                nft.add_authorized_issuing_accounts(["satoshi","aggroed","cryptomancer"])
        """
        contract_payload = {"symbol": self.symbol.upper(), "accounts": accounts}
        json_data = {"contractName":"nft","contractAction":"addAuthorizedIssuingAccounts",
                     "contractPayload":contract_payload}
        assert self.blockchain.is_hive
        tx = self.blockchain.custom_json(self.ssc_id, json_data, required_auths=[self["issuer"]])
        return tx

    def add_authorized_issuing_contracts(self, contracts):
        """Adds smart contracts to the list of contracts that are authorized to issue
           new tokens on behalf of the NFT owner.

            :param list contracts: A list of smart contracts t to add to the authorized list

            example:

            .. code-block:: python

                from hiveengine.nft import Nft
                from beem import Hive
                active_wif = "5xxxx"
                hive = Hive(keys=[active_wif])
                nft = Nft("TESTNFT", blockchain_instance=hive)
                nft.add_authorized_issuing_contracts(["mycontract","anothercontract","mygamecontract"])
        """
        contract_payload = {"symbol": self.symbol.upper(), "contracts": contracts}
        json_data = {"contractName":"nft","contractAction":"addAuthorizedIssuingContracts",
                     "contractPayload":contract_payload}
        assert self.blockchain.is_hive
        tx = self.blockchain.custom_json(self.ssc_id, json_data, required_auths=[self["issuer"]])
        return tx

    def remove_authorized_issuing_accounts(self, accounts):
        """Removes Hive accounts from the list of accounts that are authorized to issue
           new tokens on behalf of the NFT owner. 

            :param list accounts: A list of hive accounts to remove from the authorized list

            example:

            .. code-block:: python

                from hiveengine.nft import Nft
                from beem import Hive
                active_wif = "5xxxx"
                hive = Hive(keys=[active_wif])
                nft = Nft("TESTNFT", blockchain_instance=hive)
                nft.remove_authorized_issuing_accounts(["aggroed","cryptomancer"])
        """
        contract_payload = {"symbol": self.symbol.upper(), "accounts": accounts}
        json_data = {"contractName":"nft","contractAction":"removeAuthorizedIssuingAccounts",
                     "contractPayload":contract_payload}
        assert self.blockchain.is_hive
        tx = self.blockchain.custom_json(self.ssc_id, json_data, required_auths=[self["issuer"]])
        return tx

    def remove_authorized_issuing_contracts(self, contracts):
        """Remvoes smart contracts from the list of contracts that are authorized to issue
           new tokens on behalf of the NFT owner.

            :param list contracts: A list of smart contracts to remove from the authorized list

            example:

            .. code-block:: python

                from hiveengine.nft import Nft
                from beem import Hive
                active_wif = "5xxxx"
                hive = Hive(keys=[active_wif])
                nft = Nft("TESTNFT", blockchain_instance=hive)
                nft.remove_authorized_issuing_contracts(["mycontract","mygamecontract"])
        """
        contract_payload = {"symbol": self.symbol.upper(), "contracts": contracts}
        json_data = {"contractName":"nft","contractAction":"removeAuthorizedIssuingContracts",
                     "contractPayload":contract_payload}
        assert self.blockchain.is_hive
        tx = self.blockchain.custom_json(self.ssc_id, json_data, required_auths=[self["issuer"]])
        return tx

    def transfer_ownership(self, to):
        """Transfers ownership of an NFT from the current owner to another Hive account.

            :param str to: Hive accounts to become the new owner

            example:

            .. code-block:: python

                from hiveengine.nft import Nft
                from beem import Hive
                active_wif = "5xxxx"
                hive = Hive(keys=[active_wif])
                nft = Nft("TESTNFT", blockchain_instance=hive)
                nft.transfer_ownership("aggroed")
        """
        contract_payload = {"symbol": self.symbol.upper(), "to": to}
        json_data = {"contractName":"nft","contractAction":"transferOwnership",
                     "contractPayload":contract_payload}
        assert self.blockchain.is_hive
        tx = self.blockchain.custom_json(self.ssc_id, json_data, required_auths=[self["issuer"]])
        return tx

    def add_property(self, name, prop_type, is_read_only=None, authorized_editing_accounts=None,
                     authorized_editing_contracts=None):
        """Adds a new data property schema to an existing NFT definition

            :param str name: Name of the new property
            :param str prop_type: must be number, string or boolean
            :param bool is_read_only: 
            :param list authorized_editing_accounts:
            :param list authorized_editing_contracts:

            example:

            .. code-block:: python

                from hiveengine.nft import Nft
                from beem import Hive
                active_wif = "5xxxx"
                hive = Hive(keys=[active_wif])
                nft = Nft("TESTNFT", blockchain_instance=hive)
                nft.add_property("color", "string")
        """
        contract_payload = {"symbol": self.symbol.upper(), "name": name, "type": prop_type}
        if is_read_only is not None:
            contract_payload["isReadOnly"] = is_read_only
        if authorized_editing_accounts is not None:
            contract_payload["authorizedEditingAccounts"] = authorized_editing_accounts
        if authorized_editing_contracts is not None:
            contract_payload["authorizedEditingContracts"] = authorized_editing_contracts
        json_data = {"contractName":"nft","contractAction":"addProperty",
                     "contractPayload":contract_payload}
        assert self.blockchain.is_hive
        tx = self.blockchain.custom_json(self.ssc_id, json_data, required_auths=[self["issuer"]])
        return tx

    def set_property_permissions(self, name, accounts=None, contracts=None):
        """Can be used after calling the addProperty action to change the lists of
           authorized editing accounts & contracts for a given data property. 

            :param str name: Name of the new property
            :param list accounts:
            :param list contracts:

            example:

            .. code-block:: python

                from hiveengine.nft import Nft
                from beem import Hive
                active_wif = "5xxxx"
                hive = Hive(keys=[active_wif])
                nft = Nft("TESTNFT", blockchain_instance=hive)
                nft.set_property_permissions("color", accounts=["cryptomancer","marc"])
        """
        contract_payload = {"symbol": self.symbol.upper(), "name": name}
        if accounts is not None:
            contract_payload["accounts"] = accounts
        if contracts  is not None:
            contract_payload["contracts"] = contracts
        json_data = {"contractName":"nft","contractAction":"setPropertyPermissions",
                     "contractPayload":contract_payload}
        assert self.blockchain.is_hive
        tx = self.blockchain.custom_json(self.ssc_id, json_data, required_auths=[self["issuer"]])
        return tx

    def set_properties(self, nfts, from_type=None, authorized_account=None):
        """Edits one or more data properties on one or more instances of an NFT. 

            :param list nfts:
            :param str from_type:
            :param str authorized_account: authorized hive account

            example:

            .. code-block:: python

                from hiveengine.nft import Nft
                from beem import Hive
                posting_wif = "5xxxx"
                hive = Hive(keys=[posting_wif])
                nft = Nft("TESTNFT", blockchain_instance=hive)
                nft.set_properties([{ "id":"573", "properties": {"color": "red", "level": 2}}])
        """
        if authorized_account is None:
            authorized_account = self["issuer"]
        contract_payload = {"symbol": self.symbol.upper(), "nfts": nfts}
        if from_type is not None:
            contract_payload["fromType"] = from_type
        json_data = {"contractName":"nft","contractAction":"setPropertyPermissions",
                     "contractPayload":contract_payload}
        assert self.blockchain.is_hive
        tx = self.blockchain.custom_json(self.ssc_id, json_data, required_posting_auths=[authorized_account])
        return tx

    def set_group_by(self, properties):
        """Can be used after calling the addProperty action to change the lists of
           authorized editing accounts & contracts for a given data property. 

            :param list properties:

            example:

            .. code-block:: python

                from hiveengine.nft import Nft
                from beem import Hive
                active_wif = "5xxxx"
                hive = Hive(keys=[active_wif])
                nft = Nft("TESTNFT", blockchain_instance=hive)
                nft.set_group_by(["level", "isFood"])
        """
        contract_payload = {"symbol": self.symbol.upper(), "properties ": properties}
        json_data = {"contractName":"nft","contractAction":"setGroupBy",
                     "contractPayload":contract_payload}
        assert self.blockchain.is_hive
        tx = self.blockchain.custom_json(self.ssc_id, json_data, required_auths=[self["issuer"]])
        return tx

    def update_property_definition(self, name, new_name=None, prop_type=None, is_read_only=None):
        """ Updates the schema of a data property. 
            This action can only be called if no tokens for this NFT have been issued yet.

            :param str name: Name of the new property
            :param str name:
            :param str new_name:
            :param str prop_type:
            :param bool is_read_only:

            example:

            .. code-block:: python

                from hiveengine.nft import Nft
                from beem import Hive
                active_wif = "5xxxx"
                hive = Hive(keys=[active_wif])
                nft = Nft("TESTNFT", blockchain_instance=hive)
                nft.update_property_definition("color", new_name="Color")
        """
        contract_payload = {"symbol": self.symbol.upper(), "name": name}
        if new_name is not None:
            contract_payload["newName"] = new_name
        if prop_type is not None:
            contract_payload["type"] = prop_type
        if is_read_only is not None:
            contract_payload["isReadOnly"] = is_read_only
        json_data = {"contractName":"nft","contractAction":"updatePropertyDefinition",
                     "contractPayload":contract_payload}
        assert self.blockchain.is_hive
        tx = self.blockchain.custom_json(self.ssc_id, json_data, required_auths=[self["issuer"]])
        return tx

    def issue(self, to, fee_symbol, from_type=None, to_type=None, lock_tokens=None, lock_nfts=None,
              properties=None, authorized_account=None):
        """Issues a new instance of an NFT to a Hive account or smart contract.

            :param str to:
            :param str fee_symbol:
            :param str from_type:
            :param str to_type:
            :param dict lock_tokens:
            :param list lock_nfts:
            :param dict properties:
            :param str authorized_account: authorized hive account

            example:

            .. code-block:: python

                from hiveengine.nft import Nft
                from beem import Hive
                active_wif = "5xxxx"
                hive = Hive(keys=[active_wif])
                nft = Nft("TESTNFT", blockchain_instance=hive)
                nft.issue("aggroed", "PAL")
        """
        if authorized_account is None:
            authorized_account = self["issuer"]
        contract_payload = {"symbol": self.symbol.upper(), "to": to, "feeSymbol": fee_symbol}
        if from_type is not None:
            contract_payload["fromType"] = from_type
        if to_type is not None:
            contract_payload["toType"] = to_type
        if lock_tokens is not None:
            contract_payload["lockTokens"] = lock_tokens
        if lock_nfts is not None:
            contract_payload["lockNfts"] = lock_nfts
        if properties is not None:
            contract_payload["properties"] = properties

        json_data = {"contractName":"nft","contractAction":"issue",
                     "contractPayload":contract_payload}
        assert self.blockchain.is_hive
        tx = self.blockchain.custom_json(self.ssc_id, json_data, required_auths=[authorized_account])
        return tx

    def issue_multiple(self, instances, authorized_account=None):
        """Issues multiple NFT instances at once.

            :param list instances:
            :param str authorized_account: authorized hive account

            example:

            .. code-block:: python

                from hiveengine.nft import Nft
                from beem import Hive
                active_wif = "5xxxx"
                hive = Hive(keys=[active_wif])
                nft = Nft("TESTNFT", blockchain_instance=hive)
                nft.issue_multiple([{"fromType": "contract", "symbol": "TSTNFT", "to": "marc", "feeSymbol": "PAL"}])
        """
        if authorized_account is None:
            authorized_account = self["issuer"]
        contract_payload = {"instances": instances}
        json_data = {"contractName":"nft","contractAction":"issueMultiple",
                     "contractPayload":contract_payload}
        assert self.blockchain.is_hive
        tx = self.blockchain.custom_json(self.ssc_id, json_data, required_auths=[authorized_account])
        return tx

    def enable_delegation(self, undelegation_cooldown):
        """Enables the delegation feature for a NFT

            :param int undelegation_cooldown: Cooldown in days

            example:

            .. code-block:: python

                from hiveengine.nft import Nft
                from beem import Hive
                active_wif = "5xxxx"
                hive = Hive(keys=[active_wif])
                nft = Nft("TESTNFT", blockchain_instance=hive)
                nft.enable_delegation(30)
        """
        contract_payload = {"symbol": self.symbol.upper(), "undelegationCooldown": undelegation_cooldown}
        json_data = {"contractName":"nft","contractAction":"enableDelegation",
                     "contractPayload":contract_payload}
        assert self.blockchain.is_hive
        tx = self.blockchain.custom_json(self.ssc_id, json_data, required_auths=[self["issuer"]])
        return tx
Пример #5
0
class Wallet(list):
    """ Access the hive-engine wallet

        :param str account: Name of the account
        :param Hive blockchain_instance: Hive
               instance
               
        Wallet example:

            .. code-block:: python

                from hiveengine.wallet import Wallet
                wallet = Wallet("test")
                print(wallet)

    """
    def __init__(self,
                 account,
                 api=None,
                 blockchain_instance=None,
                 steem_instance=None):
        if api is None:
            self.api = Api()
        else:
            self.api = api
        self.ssc_id = "ssc-mainnet-hive"
        self.blockchain = blockchain_instance or steem_instance or shared_blockchain_instance(
        )
        check_account = Account(account, blockchain_instance=self.blockchain)
        self.account = check_account["name"]
        self.refresh()

    def refresh(self):
        super(Wallet, self).__init__(self.get_balances())

    def set_id(self, ssc_id):
        """Sets the ssc id (default is ssc-mainnet-hive)"""
        self.ssc_id = ssc_id

    def get_balances(self):
        """Returns all token within the wallet as list"""
        balances = self.api.find("tokens",
                                 "balances",
                                 query={"account": self.account})
        return balances

    def change_account(self, account):
        """Changes the wallet account"""
        check_account = Account(account, blockchain_instance=self.blockchain)
        self.account = check_account["name"]
        self.refresh()

    def get_token(self, symbol):
        """Returns a token from the wallet. Is None when not available."""
        for token in self:
            if token["symbol"].lower() == symbol.lower():
                return token
        return None

    def transfer(self, to, amount, symbol, memo=""):
        """Transfer a token to another account.

            :param str to: Recipient
            :param float amount: Amount to transfer
            :param str symbol: Token to transfer
            :param str memo: (optional) Memo


            Transfer example:

            .. code-block:: python

                from hiveengine.wallet import Wallet
                from beem import Steem
                active_wif = "5xxxx"
                stm = Steem(keys=[active_wif])
                wallet = Wallet("test", blockchain_instance=stm)
                wallet.transfer("test1", 1, "BEE", "test")
        """
        token_in_wallet = self.get_token(symbol)
        if token_in_wallet is None:
            raise TokenNotInWallet("%s is not in wallet." % symbol)
        if float(token_in_wallet["balance"]) < float(amount):
            raise InsufficientTokenAmount("Only %.3f in wallet" %
                                          float(token_in_wallet["balance"]))
        token = Token(symbol, api=self.api)
        quant_amount = token.quantize(amount)
        if quant_amount <= decimal.Decimal("0"):
            raise InvalidTokenAmount(
                "Amount to transfer is below token precision of %d" %
                token["precision"])
        check_to = Account(to, blockchain_instance=self.blockchain)
        contract_payload = {
            "symbol": symbol.upper(),
            "to": to,
            "quantity": str(quant_amount),
            "memo": memo
        }
        json_data = {
            "contractName": "tokens",
            "contractAction": "transfer",
            "contractPayload": contract_payload
        }
        assert self.blockchain.is_hive
        tx = self.blockchain.custom_json(self.ssc_id,
                                         json_data,
                                         required_auths=[self.account])
        return tx

    def stake(self, amount, symbol, receiver=None):
        """Stake a token.

            :param float amount: Amount to stake
            :param str symbol: Token to stake

            Stake example:

            .. code-block:: python

                from hiveengine.wallet import Wallet
                from beem import Steem
                active_wif = "5xxxx"
                stm = Steem(keys=[active_wif])
                wallet = Wallet("test", blockchain_instance=stm)
                wallet.stake(1, "BEE")
        """
        token_in_wallet = self.get_token(symbol)
        if token_in_wallet is None:
            raise TokenNotInWallet("%s is not in wallet." % symbol)
        if float(token_in_wallet["balance"]) < float(amount):
            raise InsufficientTokenAmount("Only %.3f in wallet" %
                                          float(token_in_wallet["balance"]))
        token = Token(symbol, api=self.api)
        quant_amount = token.quantize(amount)
        if quant_amount <= decimal.Decimal("0"):
            raise InvalidTokenAmount(
                "Amount to stake is below token precision of %d" %
                token["precision"])
        if receiver is None:
            receiver = self.account
        else:
            _ = Account(receiver, blockchain_instance=self.blockchain)
        contract_payload = {
            "symbol": symbol.upper(),
            "to": receiver,
            "quantity": str(quant_amount)
        }
        json_data = {
            "contractName": "tokens",
            "contractAction": "stake",
            "contractPayload": contract_payload
        }
        assert self.blockchain.is_hive
        tx = self.blockchain.custom_json(self.ssc_id,
                                         json_data,
                                         required_auths=[self.account])
        return tx

    def unstake(self, amount, symbol):
        """Unstake a token.

            :param float amount: Amount to unstake
            :param str symbol: Token to unstake

            Unstake example:

            .. code-block:: python

                from hiveengine.wallet import Wallet
                from beem import Steem
                active_wif = "5xxxx"
                stm = Steem(keys=[active_wif])
                wallet = Wallet("test", blockchain_instance=stm)
                wallet.unstake(1, "BEE")
        """
        token_in_wallet = self.get_token(symbol)
        if token_in_wallet is None:
            raise TokenNotInWallet("%s is not in wallet." % symbol)
        if "stake" not in token_in_wallet:
            raise InsufficientTokenAmount("Token cannot be unstaked")
        if float(token_in_wallet["stake"]) < float(amount):
            raise InsufficientTokenAmount(
                "Only %.3f are staked in the wallet" %
                float(token_in_wallet["stake"]))
        token = Token(symbol, api=self.api)
        quant_amount = token.quantize(amount)
        if quant_amount <= decimal.Decimal("0"):
            raise InvalidTokenAmount(
                "Amount to stake is below token precision of %d" %
                token["precision"])
        contract_payload = {
            "symbol": symbol.upper(),
            "quantity": str(quant_amount)
        }
        json_data = {
            "contractName": "tokens",
            "contractAction": "unstake",
            "contractPayload": contract_payload
        }
        assert self.blockchain.is_hive
        tx = self.blockchain.custom_json(self.ssc_id,
                                         json_data,
                                         required_auths=[self.account])
        return tx

    def cancel_unstake(self, trx_id):
        """Cancel unstaking a token.

            :param str trx_id: transaction id in which the tokan was unstaked

            Cancel unstake example:

            .. code-block:: python

                from hiveengine.wallet import Wallet
                from beem import Steem
                active_wif = "5xxxx"
                stm = Steem(keys=[active_wif])
                wallet = Wallet("test", blockchain_instance=stm)
                wallet.stake("cf39ecb8b846f1efffb8db526fada21a5fcf41c3")
        """
        contract_payload = {"txID": trx_id}
        json_data = {
            "contractName": "tokens",
            "contractAction": "cancelUnstake",
            "contractPayload": contract_payload
        }
        assert self.blockchain.is_hive
        tx = self.blockchain.custom_json(self.ssc_id,
                                         json_data,
                                         required_auths=[self.account])
        return tx

    def issue(self, to, amount, symbol):
        """Issues a specific token amount.

            :param str to: Recipient
            :param float amount: Amount to issue
            :param str symbol: Token to issue


            Issue example:

            .. code-block:: python

                from hiveengine.wallet import Wallet
                from beem import Steem
                active_wif = "5xxxx"
                stm = Steem(keys=[active_wif])
                wallet = Wallet("test", blockchain_instance=stm)
                wallet.issue(1, "my_token")
        """
        token = Token(symbol, api=self.api)
        if token["issuer"] != self.account:
            raise TokenIssueNotPermitted("%s is not the issuer of token %s" %
                                         (self.account, symbol))

        if token["maxSupply"] == token["supply"]:
            raise MaxSupplyReached("%s has reached is maximum supply of %d" %
                                   (symbol, token["maxSupply"]))
        quant_amount = token.quantize(amount)
        if quant_amount <= decimal.Decimal("0"):
            raise InvalidTokenAmount(
                "Amount to issue is below token precision of %d" %
                token["precision"])
        check_to = Account(to, blockchain_instance=self.blockchain)
        contract_payload = {
            "symbol": symbol.upper(),
            "to": to,
            "quantity": str(quant_amount)
        }
        json_data = {
            "contractName": "tokens",
            "contractAction": "issue",
            "contractPayload": contract_payload
        }
        assert self.blockchain.is_hive
        tx = self.blockchain.custom_json(self.ssc_id,
                                         json_data,
                                         required_auths=[self.account])
        return tx

    def get_history(self, symbol, limit=1000, offset=0):
        """Returns the transfer history of a token"""
        return self.api.get_history(self.account, symbol, limit, offset)

    def get_buy_book(self, symbol=None, limit=100, offset=0):
        """Returns the buy book for the wallet account. When symbol is set,
            the order book from the given token is shown.
        """
        if symbol is None:
            buy_book = self.api.find("market",
                                     "buyBook",
                                     query={"account": self.account},
                                     limit=limit,
                                     offset=offset)
        else:
            buy_book = self.api.find("market",
                                     "buyBook",
                                     query={
                                         "symbol": symbol,
                                         "account": self.account
                                     },
                                     limit=limit,
                                     offset=offset)
        return buy_book

    def get_sell_book(self, symbol=None, limit=100, offset=0):
        """Returns the sell book for the wallet account. When symbol is set,
            the order book from the given token is shown.
        """
        if symbol is None:
            sell_book = self.api.find("market",
                                      "sellBook",
                                      query={"account": self.account},
                                      limit=limit,
                                      offset=offset)
        else:
            sell_book = self.api.find("market",
                                      "sellBook",
                                      query={
                                          "symbol": symbol,
                                          "account": self.account
                                      },
                                      limit=limit,
                                      offset=offset)
        return sell_book
Пример #6
0
class Market(list):
    """ Access the hive-engine market

        :param Hive blockchain_instance: Hive
               instance
    """
    def __init__(self,
                 api=None,
                 blockchain_instance=None,
                 steem_instance=None):
        if api is None:
            self.api = Api()
        else:
            self.api = api
        self.blockchain = blockchain_instance or steem_instance or shared_blockchain_instance(
        )
        self.tokens = Tokens(api=self.api)
        self.ssc_id = "ssc-mainnet-hive"
        self.refresh()

    def refresh(self):
        super(Market, self).__init__(self.get_metrics())

    def set_id(self, ssc_id):
        """Sets the ssc id (default is ssc-mainnet-hive)"""
        self.ssc_id = ssc_id

    def get_metrics(self):
        """Returns all token within the wallet as list"""
        metrics = self.api.find("market", "metrics", query={})
        return metrics

    def get_buy_book(self, symbol, account=None, limit=100, offset=0):
        """Returns the buy book for a given symbol. When account is set,
            the order book from the given account is shown.
        """
        if self.tokens.get_token(symbol) is None:
            raise TokenDoesNotExists("%s does not exists" % symbol)
        if account is None:
            buy_book = self.api.find("market",
                                     "buyBook",
                                     query={"symbol": symbol.upper()},
                                     limit=limit,
                                     offset=offset)
        else:
            buy_book = self.api.find("market",
                                     "buyBook",
                                     query={
                                         "symbol": symbol.upper(),
                                         "account": account
                                     },
                                     limit=limit,
                                     offset=offset)
        return buy_book

    def get_sell_book(self, symbol, account=None, limit=100, offset=0):
        """Returns the sell book for a given symbol. When account is set,
            the order book from the given account is shown.
        """
        if self.tokens.get_token(symbol) is None:
            raise TokenDoesNotExists("%s does not exists" % symbol)
        if account is None:
            sell_book = self.api.find("market",
                                      "sellBook",
                                      query={"symbol": symbol.upper()},
                                      limit=limit,
                                      offset=offset)
        else:
            sell_book = self.api.find("market",
                                      "sellBook",
                                      query={
                                          "symbol": symbol.upper(),
                                          "account": account
                                      },
                                      limit=limit,
                                      offset=offset)
        return sell_book

    def get_trades_history(self, symbol, account=None, limit=30, offset=0):
        """Returns the trade history for a given symbol. When account is set,
            the trade history from the given account is shown.
        """
        if self.tokens.get_token(symbol) is None:
            raise TokenDoesNotExists("%s does not exists" % symbol)
        if account is None:
            trades_history = self.api.find("market",
                                           "tradesHistory",
                                           query={"symbol": symbol.upper()},
                                           limit=limit,
                                           offset=offset)
        else:
            trades_history = self.api.find("market",
                                           "tradesHistory",
                                           query={
                                               "symbol": symbol.upper(),
                                               "account": account
                                           },
                                           limit=limit,
                                           offset=offset)
        return trades_history

    def withdraw(self, account, amount):
        """Widthdraw SWAP.HIVE to account as HIVE.

            :param str account: account name
            :param float amount: Amount to withdraw

            Withdraw example:

            .. code-block:: python

                from hiveengine.market import Market
                from beem import Steem
                active_wif = "5xxxx"
                stm = Steem(keys=[active_wif])
                market = Market(blockchain_instance=stm)
                market.withdraw("test", 1)
        """
        wallet = Wallet(account,
                        api=self.api,
                        blockchain_instance=self.blockchain)
        token_in_wallet = wallet.get_token("SWAP.HIVE")
        if token_in_wallet is None:
            raise TokenNotInWallet("%s is not in wallet." % "SWAP.HIVE")
        if float(token_in_wallet["balance"]) < float(amount):
            raise InsufficientTokenAmount("Only %.3f in wallet" %
                                          float(token_in_wallet["balance"]))
        token = Token("SWAP.HIVE", api=self.api)
        quant_amount = token.quantize(amount)
        if quant_amount <= decimal.Decimal("0"):
            raise InvalidTokenAmount(
                "Amount to transfer is below token precision of %d" %
                token["precision"])
        contract_payload = {"quantity": str(quant_amount)}
        json_data = {
            "contractName": "hivepegged",
            "contractAction": "withdraw",
            "contractPayload": contract_payload
        }
        assert self.blockchain.is_hive
        tx = self.blockchain.custom_json(self.ssc_id,
                                         json_data,
                                         required_auths=[account])
        return tx

    def deposit(self, account, amount):
        """Deposit HIVE to market in exchange for SWAP.HIVE.

            :param str account: account name
            :param float amount: Amount to deposit

            Deposit example:

            .. code-block:: python

                from hiveengine.market import Market
                from beem import Steem
                active_wif = "5xxxx"
                stm = Steem(keys=[active_wif])
                market = Market(blockchain_instance=stm)
                market.deposit("test", 1)
        """
        acc = Account(account, blockchain_instance=self.blockchain)
        steem_balance = acc.get_balance("available", "HIVE")
        if float(steem_balance) < float(amount):
            raise InsufficientTokenAmount("Only %.3f in wallet" %
                                          float(steem_balance))
        json_data = '{"id":"' + self.ssc_id + '","json":{"contractName":"hivepegged","contractAction":"buy","contractPayload":{}}}'
        tx = acc.transfer("honey-swap", amount, "HIVE", memo=json_data)
        return tx

    def buy(self, account, amount, symbol, price):
        """Buy token for given price.

            :param str account: account name
            :param float amount: Amount to withdraw
            :param str symbol: symbol
            :param float price: price

            Buy example:

            .. code-block:: python

                from hiveengine.market import Market
                from beem import Steem
                active_wif = "5xxxx"
                stm = Steem(keys=[active_wif])
                market = Market(blockchain_instance=stm)
                market.buy("test", 1, "BEE", 0.95)
        """
        wallet = Wallet(account,
                        api=self.api,
                        blockchain_instance=self.blockchain)
        token_in_wallet = wallet.get_token("SWAP.HIVE")
        if token_in_wallet is None:
            raise TokenNotInWallet("%s is not in wallet." % "SWAP.HIVE")
        if float(token_in_wallet["balance"]) < float(amount) * float(price):
            raise InsufficientTokenAmount("Only %.3f in wallet" %
                                          float(token_in_wallet["balance"]))

        token = Token(symbol, api=self.api)
        quant_amount = token.quantize(amount)
        if quant_amount <= decimal.Decimal("0"):
            raise InvalidTokenAmount(
                "Amount to transfer is below token precision of %d" %
                token["precision"])
        contract_payload = {
            "symbol": symbol.upper(),
            "quantity": str(quant_amount),
            "price": str(price)
        }
        json_data = {
            "contractName": "market",
            "contractAction": "buy",
            "contractPayload": contract_payload
        }
        assert self.blockchain.is_hive
        tx = self.blockchain.custom_json(self.ssc_id,
                                         json_data,
                                         required_auths=[account])
        return tx

    def sell(self, account, amount, symbol, price):
        """Sell token for given price.

            :param str account: account name
            :param float amount: Amount to withdraw
            :param str symbol: symbol
            :param float price: price

            Sell example:

            .. code-block:: python

                from hiveengine.market import Market
                from beem import Steem
                active_wif = "5xxxx"
                stm = Steem(keys=[active_wif])
                market = Market(blockchain_instance=stm)
                market.sell("test", 1, "BEE", 0.95)
        """
        wallet = Wallet(account,
                        api=self.api,
                        blockchain_instance=self.blockchain)
        token_in_wallet = wallet.get_token(symbol)
        if token_in_wallet is None:
            raise TokenNotInWallet("%s is not in wallet." % symbol)
        if float(token_in_wallet["balance"]) < float(amount):
            raise InsufficientTokenAmount("Only %.3f in wallet" %
                                          float(token_in_wallet["balance"]))

        token = Token(symbol, api=self.api)
        quant_amount = token.quantize(amount)
        if quant_amount <= decimal.Decimal("0"):
            raise InvalidTokenAmount(
                "Amount to transfer is below token precision of %d" %
                token["precision"])
        contract_payload = {
            "symbol": symbol.upper(),
            "quantity": str(quant_amount),
            "price": str(price)
        }
        json_data = {
            "contractName": "market",
            "contractAction": "sell",
            "contractPayload": contract_payload
        }
        assert self.blockchain.is_hive
        tx = self.blockchain.custom_json(self.ssc_id,
                                         json_data,
                                         required_auths=[account])
        return tx

    def cancel(self, account, order_type, order_id):
        """Cancel buy/sell order.

            :param str account: account name
            :param str order_type: sell or buy
            :param int order_id: order id

            Cancel example:

            .. code-block:: python

                from hiveengine.market import Market
                from beem import Steem
                active_wif = "5xxxx"
                stm = Steem(keys=[active_wif])
                market = Market(blockchain_instance=stm)
                market.sell("test", "sell", 12)
        """

        contract_payload = {"type": order_type, "id": order_id}
        json_data = {
            "contractName": "market",
            "contractAction": "cancel",
            "contractPayload": contract_payload
        }
        assert self.blockchain.is_hive
        tx = self.blockchain.custom_json(self.ssc_id,
                                         json_data,
                                         required_auths=[account])
        return tx