Source code for tradehub.authenticated_client

"""
Description:

    Authenticated Client Class for interacting with the Tradehub network.
    This client performs the actions on the tradehub network by submitting transaction on-chain.
    This class is designed to use public nodes for the API and WS clients to use.

Usage::

    from tradehub.authenticated_client import AuthenticatedClient
"""

from tradehub.transactions import Transactions as TradehubTransactions
import tradehub.types as types
from tradehub.utils import to_tradehub_asset_amount, format_withdraw_address
from tradehub.wallet import Wallet


[docs]class AuthenticatedClient(TradehubTransactions): """ This class uses a private key to interact with the Tradehub network of validators. Execution of this function is as follows:: AuthenticatedClient(network='mainnet', wallet=Wallet(mnemonic='', network='mainnet') trusted_ips=None, trusted_uris=None) """ ''' TODO # AMM reward % -> /get_amm_reward_percentage # Vault types -> /get_vault_types # Vaults by address -> /get_vaults?address=${address} ''' def __init__(self, wallet: Wallet, trusted_ips: list = None, trusted_uris: list = None, network: str = "testnet"): """ :param wallet: Wallet Client that contains the attributes necessary for submitting on-chain transactions. :type wallet: Wallet :param network: The network you want to interact with. Accepts "testnet" or "mainnet". :type network: str :param trusted_ips: Known and trusted IPs to connect to for your API requests. :type trusted_ips: list :param trusted_uris: Known and trusted URIs to connect to for your API requests. :type trusted_uris: list """ TradehubTransactions.__init__(self, wallet=wallet, trusted_ips=trusted_ips, trusted_uris=trusted_uris, network=network) self.wallet = wallet # Authenticated Client Functions ''' The way each of these functions work follow a similar pattern. (1) The function is passed a message that matches a class from the type file. (2) That message and matching transaction type are sent to a function that standardizes builds of transaction sent to the blockchain. (3) Inside that standardization are the: (3a) - Determination of fees (3b) - Transformation of the message class to a Python dictionary/JSON object to facilitate signing and broadcast to the network. (3c) - Determination of account details (4) With everything standardized, each of the objects are then sent off to be signed and broadcast to the Tradehub blockchain. '''
[docs] def update_profile(self, message: types.UpdateProfileMessage, fee: dict = None): """ Function that makes the network requests to the Tradehub validators across the network. Execution of this function is as follows:: update_profile(message=types.UpdateProfileMessage(username='PythonCICD', twitter='PythonCICD')) The expected return result for this function is as follows:: { 'height': '1927295', 'txhash': 'C6AF947EE35EE5282BD140F9F51614FA1C7ACADAB263B921621097C786C06977', 'raw_log': ..., 'logs': ..., 'gas_wanted': '100000000000', 'gas_used': '68345' } :param message: UpdateProfileMessage Type that is a class of attributes required to make this on-chain action. :param fee: Dict of the fee type, generally this can be left blank and allow the API to handle this. :return: Dictionary of the transaction response sent on-chain. """ transaction_type = "UPDATE_PROFILE_MSG_TYPE" return self.submit_transaction_on_chain(messages=[message], transaction_type=transaction_type, fee=fee)
[docs] def send_tokens(self, message: types.SendTokensMessage, fee: dict = None): """ Function to send tokens from your wallet to a recipient. Execution of this function is as follows:: sent_tokens(message=types.SendTokensMessage(to_address=send_address, amount=types.SendTokensAmount(amount='10.1', denom='swth'))) :param message: SendTokensMessage Type that is a class of attributes required to make this on-chain action. :param fee: Dict of the fee type, generally this can be left blank and allow the API to handle this. :return: Dictionary of the transaction response sent on-chain, look in the logs to be sure it matches what was sent. """ transaction_type = "SEND_TOKENS_TYPE" if hasattr(message, 'from_address') and message.from_address in [None, ""]: message.from_address = self.wallet.address amounts = [] for amount in message.amount: formatted_amount = to_tradehub_asset_amount(amount=float(amount.amount), decimals=self.tokens[amount.denom]["decimals"]) amounts.append(types.SendTokensAmount(amount=formatted_amount, denom=amount.denom)) message.amount = sorted(amounts, key=lambda x: x.denom.lower()) # When dealing with coin lists in Cosmos it is a requirement that they be ordered by name - https://github.com/cosmos/cosmos-sdk/blob/master/types/coin.go#L215 return self.submit_transaction_on_chain(messages=[message], transaction_type=transaction_type, fee=fee)
[docs] def create_order(self, message: types.CreateOrderMessage, fee: dict = None): """ Function to create an order on the Tradehub network. Execution of this function is as follows:: create_order(message=types.CreateOrderMessage(market="swth_eth1", side="sell", quantity="200", price="0.00002", type="limit")) :param message: CreateOrderMessage Type that is a class of attributes required to make this on-chain action. :param fee: Dict of the fee type, generally this can be left blank and allow the API to handle this. :return: Dictionary of the transaction response sent on-chain, look in the logs to be sure it matches what was sent. """ return self.create_orders(messages=[message], fee=fee)
[docs] def create_orders(self, messages: [types.CreateOrderMessage], fee: dict = None): """ Function to create multiple orders on the Tradehub network. Execution of this function is as follows:: create_orders([message=types.CreateOrderMessage(market="swth_eth1", side="sell", quantity="200", price="0.00002", type="limit")]) :param message: List of CreateOrderMessage Type that is a class of attributes required to make this on-chain action. :param fee: Dict of the fee type, generally this can be left blank and allow the API to handle this. :return: Dictionary of the transaction response sent on-chain, look in the logs to be sure it matches what was sent. """ transaction_type = "CREATE_ORDER_MSG_TYPE" return self.submit_transaction_on_chain(messages=messages, transaction_type=transaction_type, fee=fee)
[docs] def cancel_order(self, message: types.CancelOrderMessage, fee: dict = None): """ Function to cancel an order on the Tradehub network. Execution of this function is as follows:: cancel_order(message=types.CancelOrderMessage(id="D3F370A91D260DB3B1112757D8F9B66EEA1B7887FB4B247872D367F04A4C56EB")) :param message: CancelOrderMessage Type that is a class of attributes required to make this on-chain action. :param fee: Dict of the fee type, generally this can be left blank and allow the API to handle this. :return: Dictionary of the transaction response sent on-chain, look in the logs to be sure it matches what was sent. """ return self.cancel_orders(messages=[message], fee=fee)
[docs] def cancel_orders(self, messages: [types.CancelOrderMessage], fee: dict = None): """ Function to cancel multiple order on the Tradehub network. Execution of this function is as follows:: cancel_orders(message=[types.CancelOrderMessage(id="D3F370A91D260DB3B1112757D8F9B66EEA1B7887FB4B247872D367F04A4C56EB")]) :param message: List of CancelOrderMessage Type that is a class of attributes required to make this on-chain action. :param fee: Dict of the fee type, generally this can be left blank and allow the API to handle this. :return: Dictionary of the transaction response sent on-chain, look in the logs to be sure it matches what was sent. """ transaction_type = "CANCEL_ORDER_MSG_TYPE" return self.submit_transaction_on_chain(messages=messages, transaction_type=transaction_type, fee=fee)
[docs] def cancel_all(self, message: types.CancelAllMessage, fee: dict = None): """ Function to cancel all orders for a specific market on the Tradehub network. Execution of this function is as follows:: cancel_all(message=types.CancelAllMessage(market='swth_eth1')) :param message: CancelAllMessage Type that is a class of attributes required to make this on-chain action. :param fee: Dict of the fee type, generally this can be left blank and allow the API to handle this. :return: Dictionary of the transaction response sent on-chain, look in the logs to be sure it matches what was sent. """ transaction_type = "CANCEL_ALL_MSG_TYPE" return self.submit_transaction_on_chain(messages=[message], transaction_type=transaction_type, fee=fee)
[docs] def edit_order(self, message: types.EditOrderMessage, fee: dict = None): """ Function to edit an open order on the Tradehub network. Execution of this function is as follows:: edit_order(message=types.EditOrderMessage(id="816F6D321F696EA81EB9961BE51DB5CB31520217DAF75FA569446BDD85A21E96", quantity="220", stop_price="0.0000175")) :param message: EditOrderMessage Type that is a class of attributes required to make this on-chain action. :param fee: Dict of the fee type, generally this can be left blank and allow the API to handle this. :return: Dictionary of the transaction response sent on-chain, look in the logs to be sure it matches what was sent. """ return self.edit_orders(messages=[message], fee=fee)
[docs] def edit_orders(self, messages: [types.EditOrderMessage], fee: dict = None): """ Function to edit open orders on the Tradehub network. Execution of this function is as follows:: edit_orders(message=[types.EditOrderMessage(id="816F6D321F696EA81EB9961BE51DB5CB31520217DAF75FA569446BDD85A21E96", quantity="220", stop_price="0.0000175")]) :param message: List of EditOrderMessage Type that is a class of attributes required to make this on-chain action. :param fee: Dict of the fee type, generally this can be left blank and allow the API to handle this. :return: Dictionary of the transaction response sent on-chain, look in the logs to be sure it matches what was sent. """ transaction_type = "EDIT_ORDER_MSG_TYPE" return self.submit_transaction_on_chain(messages=messages, transaction_type=transaction_type, fee=fee)
# def set_leverage(self, message: types.SetLeverageMessage, fee: dict = None): # return self.set_leverages(messages=[message], fee=fee) # def set_leverages(self, messages: [types.SetLeverageMessage], fee: dict = None): # transaction_type = "SET_LEVERAGE_MSG_TYPE" # return self.submit_transaction_on_chain(messages=messages, transaction_type=transaction_type, fee=fee) # def edit_margin(self, message: types.EditMarginMessage, fee: dict = None): # return self.edit_margins(messages=[message], fee=fee) # def edit_margins(self, messages: [types.EditMarginMessage], fee: dict = None): # transaction_type = "EDIT_MARGIN_MSG_TYPE" # return self.submit_transaction_on_chain(messages=messages, transaction_type=transaction_type, fee=fee)
[docs] def stake_switcheo(self, message=types.DelegateTokensMessage, fee: dict = None): """ Function to stake (or delegate) Switcheo to validators on the Tradehub network. Execution of this function is as follows:: stake_switcheo(message=types.DelegateTokensMessage(delegator_address=self._wallet.address, validator_address='tswthvaloper1hn0spc9plh5ker8lrtzyz9uqfe3xk2yn0c6nyf', amount=types.DelegateTokensAmount(amount = '10.1', denom = 'swth'))) :param message: DelegateTokensMessage Type that is a class of attributes required to make this on-chain action. :param fee: Dict of the fee type, generally this can be left blank and allow the API to handle this. :return: Dictionary of the transaction response sent on-chain, look in the logs to be sure it matches what was sent. """ transaction_type = "DELEGATE_TOKENS_MSG_TYPE" message.amount.amount = to_tradehub_asset_amount(amount=float(message.amount.amount), decimals=self.tokens["swth"]["decimals"]) return self.submit_transaction_on_chain(messages=[message], transaction_type=transaction_type, fee=fee)
[docs] def claim_staking_rewards(self, message=types.WithdrawDelegatorRewardsMessage, fee: dict = None): """ Function to claim rewards generated from staking with a Switcheo validator on the Tradehub network. Execution of this function is as follows:: claim_staking_rewards(message=types.WithdrawDelegatorRewardsMessage(delegator_address=self._wallet.address, validator_address='tswthvaloper10229tj7kh2mzwsn9cnfxuq3sqjuph860dlezpr')) :param message: WithdrawDelegatorRewardsMessage Type that is a class of attributes required to make this on-chain action. :param fee: Dict of the fee type, generally this can be left blank and allow the API to handle this. :return: Dictionary of the transaction response sent on-chain, look in the logs to be sure it matches what was sent. """ transaction_type = "WITHDRAW_DELEGATOR_REWARDS_MSG_TYPE" return self.submit_transaction_on_chain(messages=[message], transaction_type=transaction_type, fee=fee)
[docs] def claim_all_staking_rewards(self, message=types.WithdrawAllDelegatorRewardsParams, fee: dict = None): """ Function to claim rewards generated from all validators a wallet is staking with on the Tradehub network. Execution of this function is as follows:: claim_all_staking_rewards(message=types.WithdrawAllDelegatorRewardsParams(delegator_address=self._wallet.address, validator_addresses=['tswthvaloper1hn0spc9plh5ker8lrtzyz9uqfe3xk2yn0c6nyf', 'tswthvaloper10229tj7kh2mzwsn9cnfxuq3sqjuph860dlezpr'])) :param message: WithdrawAllDelegatorRewardsMessage Type that is a class of attributes required to make this on-chain action. :param fee: Dict of the fee type, generally this can be left blank and allow the API to handle this. :return: Dictionary of the transaction response sent on-chain, look in the logs to be sure it matches what was sent. """ transaction_type = "WITHDRAW_DELEGATOR_REWARDS_MSG_TYPE" messages = [] for validator_address in message.validator_addresses: messages.append(types.WithdrawDelegatorRewardsMessage(delegator_address=message.delegator_address, validator_address=validator_address)) return self.submit_transaction_on_chain(messages=messages, transaction_type=transaction_type, fee=fee)
[docs] def unbond_tokens(self, message: types.BeginUnbondingTokensMessage, fee: dict = None): """ Function to unbond tokens a validator on the Tradehub network. Execution of this function is as follows:: unbond_tokens(message=types.BeginUnbondingTokensMessage(delegator_address=self._wallet.address, validator_address='tswthvaloper1hn0spc9plh5ker8lrtzyz9uqfe3xk2yn0c6nyf', amount=types.AmountMessage(amount='0.1', denom='swth'))) :param message: BeginUnbondingTokensMessage Type that is a class of attributes required to make this on-chain action. :param fee: Dict of the fee type, generally this can be left blank and allow the API to handle this. :return: Dictionary of the transaction response sent on-chain, look in the logs to be sure it matches what was sent. """ transaction_type = "BEGIN_UNBONDING_TOKENS_MSG_TYPE" message.amount.amount = to_tradehub_asset_amount(amount=float(message.amount.amount), decimals=self.tokens["swth"]["decimals"]) return self.submit_transaction_on_chain(messages=[message], transaction_type=transaction_type, fee=fee)
[docs] def redelegate_tokens(self, message: types.BeginRedelegatingTokensMessage, fee: dict = None): """ Function to move tokens from one validator to another on the Tradehub network. Execution of this function is as follows:: redelegate_tokens(message=types.BeginRedelegatingTokensMessage(delegator_address=self._wallet.address, validator_src_address='tswthvaloper1hn0spc9plh5ker8lrtzyz9uqfe3xk2yn0c6nyf', validator_dst_address='tswthvaloper10229tj7kh2mzwsn9cnfxuq3sqjuph860dlezpr', amount=types.AmountMessage(amount='0.1', denom='swth')) :param message: BeginRedelegatingTokensMessage Type that is a class of attributes required to make this on-chain action. :param fee: Dict of the fee type, generally this can be left blank and allow the API to handle this. :return: Dictionary of the transaction response sent on-chain, look in the logs to be sure it matches what was sent. """ transaction_type = "BEGIN_REDELEGATING_TOKENS_MSG_TYPE" message.amount.amount = to_tradehub_asset_amount(amount=float(message.amount.amount), decimals=self.tokens["swth"]["decimals"]) return self.submit_transaction_on_chain(messages=[message], transaction_type=transaction_type, fee=fee)
[docs] def create_withdraw(self, message: types.CreateWithdrawMessage, blockchain: str, fee: dict = None): """ Function to withdraw tokens from the Tradehub network onto the desired blockchain. Execution of this function is as follows:: create_withdraw(message=types.CreateWithdrawMessage(to_address=NEO_ADDRESS, denom='swth-n', amount='87', fee_amount="1"), blockchain='NEO') :param message: CreateWithdrawMessage Type that is a class of attributes required to make this on-chain action. :param blockchain: String to specify if the withdraw is going to the NEO or Ethereum network. :param fee: Dict of the fee type, generally this can be left blank and allow the API to handle this. :return: Dictionary of the transaction response sent on-chain, look in the logs to be sure it matches what was sent. """ message.fee_address = 'swth1prv0t8j8tqcdngdmjlt59pwy6dxxmtqgycy2h7' message.to_address = format_withdraw_address(address=message.to_address, blockchain=blockchain) transaction_type = "CREATE_WITHDRAWAL_TYPE" return self.submit_transaction_on_chain(messages=[message], transaction_type=transaction_type, fee=fee)
[docs] def create_validator(self, message: types.CreateValidatorMessage, fee: dict = None): transaction_type = "CREATE_VALIDATOR_MSG_TYPE" return self.submit_transaction_on_chain(messages=[message], transaction_type=transaction_type, fee=fee)
[docs] def create_sub_account(self, message: types.CreateSubAccountMessage, fee: dict = None): transaction_type = "CREATE_SUB_ACCOUNT_MSG_TYPE" return self.submit_transaction_on_chain(messages=[message], transaction_type=transaction_type, fee=fee)
[docs] def activate_sub_account(self, message: types.ActivateSubAccountMessage, fee: dict = None): transaction_type = "ACTIVATE_SUB_ACCOUNT_MSG_TYPE" return self.submit_transaction_on_chain(messages=[message], transaction_type=transaction_type, fee=fee)
[docs] def add_liquidity(self, message: types.AddLiquidityMessage, fee: dict = None): transaction_type = "ADD_LIQUIDITY_MSG_TYPE" if not hasattr(message, 'min_shares'): message.min_shares = '0' return self.submit_transaction_on_chain(messages=[message], transaction_type=transaction_type, fee=fee)
[docs] def remove_liquidity(self, message: types.RemoveLiquidityMessage, fee: dict = None): transaction_type = "REMOVE_LIQUIDITY_MSG_TYPE" return self.submit_transaction_on_chain(messages=[message], transaction_type=transaction_type, fee=fee)
[docs] def stake_pool_token(self, message: types.StakePoolTokenMessage, fee: dict = None): transaction_type = "STAKE_POOL_TOKEN_MSG_TYPE" return self.submit_transaction_on_chain(messages=[message], transaction_type=transaction_type, fee=fee)
[docs] def unstake_pool_token(self, message: types.UnstakePoolTokenMessage, fee: dict = None): transaction_type = "UNSTAKE_POOL_TOKEN_MSG_TYPE" return self.submit_transaction_on_chain(messages=[message], transaction_type=transaction_type, fee=fee)
[docs] def claim_pool_rewards(self, message: types.ClaimPoolRewardsMessage, fee: dict = None): transaction_type = "CLAIM_POOL_REWARDS_MSG_TYPE" return self.submit_transaction_on_chain(messages=[message], transaction_type=transaction_type, fee=fee)