EOS Coin Handler¶
Module contents¶
EOS Coin Handler
This python module is a Coin Handler for Privex’s CryptoToken Converter, designed to handle all required functionality for both receiving and sending tokens on the EOS network.
It will automatically handle any payments.models.Coin
which has it’s type set to eos
To use this handler, you must first create the base coin with symbol EOS
:
Coin Name: EOS
Symbol: EOS
Our Account: (username of account used for sending/receiving native EOS token)
Custom JSON: {"contract": "eosio.token"}
To change the RPC node from the admin panel, simply set the host/port/username/password on the EOS Coin:
# Below are the defaults used if you don't configure the EOS coin:
Host: eos.greymass.com
Port: 443
User: (leave blank)
Pass: (leave blank)
Custom JSON: {"ssl": True}
Coin Settings (Custom JSON settings)
Tip
You can override the defaults for all EOS coins by setting the
settings_json
for a coin with the symbolEOS
.All
Coin
’s handled by the EOS handler will inherit theEOS
coin’s custom JSON settings, which can be overrided via the individual coin’ssettings_json
.You can set the following JSON keys inside of a
Coin
’s “settings_json” field to adjust settings such as the “contract account” for the token, whether or not to use SSL with the RPC node, as well as the precision (DP) of the coin, if it’s different from the default of4
decimal places.
Coin Key Description endpoint (str) The base URI to query against, e.g. /eos_rpc/
ssl (bool) Whether or not to use SSL (https). Boolean true
orfalse
contract (str) The contract account for this token, e.g. eosio.token
orsteemenginex
precision (int) The precision (decimal places) of this coin (defaults to 4
)load_method (str) Either actions
to use v1/history, orpvx
to use Privex EOS Historyhistory_url (str) (if load_method is pvx) Privex history URL, e.g. https://eos-history.privex.io
Copyright:
+===================================================+
| © 2019 Privex Inc. |
| https://www.privex.io |
+===================================================+
| |
| CryptoToken Converter |
| |
| Core Developer(s): |
| |
| (+) Chris (@someguy123) [Privex] |
| |
+===================================================+
-
payments.coin_handlers.EOS.
reload
()[source]¶ Reload’s the
provides
property for the loader and manager from the DB.By default, since new tokens are constantly being created for EOS, our classes can provide for any
models.Coin
by scanning for coins with the typeeos
. This saves us from hard coding specific coin symbols.
Submodules¶
EOSLoader module¶
-
class
payments.coin_handlers.EOS.EOSLoader.
EOSLoader
(symbols)[source]¶ Bases:
payments.coin_handlers.base.BaseLoader.BaseLoader
,payments.coin_handlers.EOS.EOSMixin.EOSMixin
-
clean_txs
(account, symbol, contract, transactions: Iterable[dict]) → Generator[dict, None, None][source]¶ Filters a given Iterable of dict’s containing raw EOS “actions”:
- Finds only incoming transfer transactions from accounts that are not us (account)
- Filters transactions by both symbol and verifies they’re from the contract account
- Outputs valid incoming TXs in the standardised Deposit format.
Parameters: Return Generator cleaned_txs: A generator yielding valid Deposit TXs as dict’s
-
get_actions
(account: str, count=100) → List[dict][source]¶ Loads EOS transactions for a given account, and caches them per account to avoid constant queries.
Parameters: - account – The EOS account to load transactions for
- count – Amount of transactions to load
Return list transactions: A list of EOS transactions as dict’s
-
list_txs
(batch=100) → Generator[dict, None, None][source]¶ Get transactions for all coins in self.coins where the ‘to’ field matches coin.our_account If
load()
hasn’t been ran already, it will automatically call self.load()Parameters: batch – Amount of transactions to load per batch Returns: Generator yielding dict’s that conform to models.Deposit
-
load
(tx_count=1000)[source]¶ Prepares the loader by disabling any symbols / coin objects that don’t have an our_account set, or don’t have a contract set in either
models.Coin.settings_json
ordefault_contracts
Parameters: tx_count – Amount of transactions to load per account, most recent first Returns: None
-
provides
¶
-
pvx_clean_txs
(account, symbol, contract, transactions: Iterable[dict]) → Generator[dict, None, None][source]¶ Filters a given Iterable of dict’s containing EOS “actions” from Privex history API
- Finds only incoming transfer transactions from accounts that are not us (account)
- Filters transactions by both symbol and verifies they’re from the contract account
- Outputs valid incoming TXs in the standardised Deposit format.
Parameters: Return Generator cleaned_txs: A generator yielding valid Deposit TXs as dict’s
-
pvx_get_actions
(account: str, count=100, symbol=None, contract=None, history_url=None) → List[dict][source]¶ Loads EOS transactions for a given account, and caches them per account to avoid constant queries.
Parameters: - account – The EOS account to load transactions for
- count – Amount of transactions to load
Return list transactions: A list of EOS transactions as dict’s
-
EOSManager module¶
-
class
payments.coin_handlers.EOS.EOSManager.
EOSManager
(symbol: str)[source]¶ Bases:
payments.coin_handlers.base.BaseManager.BaseManager
,payments.coin_handlers.EOS.EOSMixin.EOSMixin
-
address_valid
(*addresses) → bool[source]¶ Check if one or more account usernames exist on the EOS network.
Example:
>>> if not self.address_valid('someguy12333', 'steemenginex'): ... print('The EOS account "someguy12333" and/or "steemenginex" does not exist. ')
Parameters: addresses (str) – One or more EOS usernames to verify the existence of Return bool account_exists: True if all of the given accounts in addresses exist on the EOS network. Return bool account_exists: False if at least one account in addresses does not exist on EOS.
-
address_valid_ex
(*addresses)[source]¶ Check if one or more account usernames exist on the EOS network. Throws an exception if any do not exist.
A slightly different version of
address_valid()
which raises AccountNotFound with the username that failed the test, instead of simply returning True / False.Parameters: addresses (str) – One or more EOS usernames to verify the existence of Raises: AccountNotFound – When one of the accounts in addresses does not exist.
-
balance
(address: str = None, memo: str = None, memo_case: bool = False) → decimal.Decimal[source]¶ Return the balance of self.symbol for our “wallet”, or a given address/account, optionally filtered by memo
Parameters: - address – The address or account to get the balance for. If None, return our total wallet (or default account) balance.
- memo – If not None (and coin supports memos), return the total balance of a given memo
- memo_case – Whether or not to total memo’s case sensitive, or not. False = case-insensitive memo
Raises: AccountNotFound – The requested account/address doesn’t exist
Return Decimal: Decimal() balance of address/account, optionally balance (total received) of a given memo
-
build_tx
(tx_type, contract, sender, tx_args: dict, key_types=None, broadcast: bool = True) → dict[source]¶ Crafts an EOS transaction using the various arguments, signs it using the stored private key for sender, then broadcasts it (if broadcast is True) and returns the result.
Example:
>>> args = {"from": "someguy12333", "to": "steemenginex", "quantity": "1.000 EOS", "memo": ""} >>> res = self.build_tx('transfer', 'eosio.token', 'someguy12333', args) >>> print(res['transaction_id']) dc9ece0dfb8da0b92068e23bdc22c971e0bc713d31ffc1b7552a861197b0d23e
Parameters: - tx_type (str) – The type of transaction, e.g. “transfer” or “issue”
- contract (str) – The contract username to execute against, e.g. ‘eosio.token’
- sender (str) – The account name that will be signing the transaction, will auto lookup it’s private key
- tx_args (dict) – A dictionary of transaction arguments to add to the payload data
- key_types (list) – (optional) Which types of key can be used for this TX? e.g. [‘owner’, ‘active’]
- broadcast (bool) – (default: True) If true, broadcasts the TX after signing. Otherwise returns just the signed TX and does not broadcast it to the network.
Return dict tfr: The results of the transaction. Includes information about the broadcast if it was sent.
-
can_issue
= True¶
-
get_deposit
() → tuple[source]¶ Return tuple: If the coin uses addresses, this method should return a tuple of (‘address’, coin_address) Return tuple: If the coin uses accounts/memos, this method should return a tuple (‘account’, receiving_account) The memo will automatically be generated by the calling function.
-
classmethod
get_privkey
(from_account: str, key_types: list = None) → Tuple[str, str][source]¶ Find the EOS
models.CryptoKeyPair
in the database for a given account from_account , decrypt the private key, then returns a tuple containing (key_type:str, priv_key:str,)If no matching key pair could be found, will raise an AuthorityMissing exception.
Example:
>>> key_type, priv_key = EOSManager.get_privkey('steemenginex', key_types=['active']) >>> print(key_type) active >>> print(priv_key) # The below private key was randomly generated for this pydoc block, is isn't a real key. 5KK4oSvg9n5NxiAK9CXRd7zhbARpx8oxh15miPTXW8htGbYQPKD
Parameters: Raises: - AuthorityMissing – No key pair could be found for the given from_account
- EncryptKeyMissing – CTC admin did not set ENCRYPT_KEY in their .env, or it is invalid
- EncryptionError – Something went wrong while decrypting the private key (maybe ENCRYPT_KEY is invalid)
Return tuple k: A tuple containing the key type (active/owner etc.) and the private key.
-
issue
(amount: decimal.Decimal, address: str, memo: str = None, trigger_data=None)[source]¶ Issue (create/print) tokens to a given address/account, optionally specifying a memo if supported
Parameters: - amount (Decimal) – Amount of tokens to issue, as a Decimal()
- address – Address or account to issue the tokens to
- memo – Memo to issue tokens with (if supported)
- trigger_data (dict) – Metadata related to this issue transaction (e.g. the deposit that triggered this)
Raises: - IssuerKeyError – Cannot issue because we don’t have authority to (missing key etc.)
- IssueNotSupported – Class does not support issuing, or requested symbol cannot be issued.
- AccountNotFound – The requested account/address doesn’t exist
Return dict: Result Information
Format:
dict { txid:str - Transaction ID - None if not known, coin:str - Symbol that was sent, amount:Decimal - The amount that was sent (after fees), fee:Decimal - TX Fee that was taken from the amount, from:str - The account/address the coins were issued from. If it's not possible to determine easily, set this to None. send_type:str - Should be statically set to "issue" }
-
provides
¶
-
send
(amount, address, from_address=None, memo=None, trigger_data=None) → dict[source]¶ Send a given
amount
of EOS (or a token on EOS) fromfrom_address
toaddress
with the memomemo
.Only
amount
andaddress
are mandatory.Parameters: Raises: - AuthorityMissing – Cannot send because we don’t have authority to (missing key etc.)
- AccountNotFound – The requested account doesn’t exist
- NotEnoughBalance – Sending account/address does not have enough balance to send
Return dict: Result Information
Format:
dict { txid:str - Transaction ID - None if not known, coin:str - Symbol that was sent, amount:Decimal - The amount that was sent (after fees), fee:Decimal - TX Fee that was taken from the amount (static Decimal(0) for EOS) from:str - The account the coins were sent from. send_type:str - Statically set to "send" }
-
send_or_issue
(amount, address, memo=None, trigger_data=None) → dict[source]¶ Attempt to send an amount to an address/account, if not enough balance, attempt to issue it instead. You may override this method if needed.
Parameters: - amount (Decimal) – Amount of coins/tokens to send/issue, as a Decimal()
- address – Address or account to send/issue the coins/tokens to
- memo – Memo to send/issue coins/tokens with (if supported)
- trigger_data (dict) – Metadata related to this issue transaction (e.g. the deposit that triggered this)
Raises: - IssuerKeyError – Cannot issue because we don’t have authority to (missing key etc.)
- IssueNotSupported – Class does not support issuing, or requested symbol cannot be issued.
- AccountNotFound – The requested account/address doesn’t exist
Return dict: Result Information
Format:
dict { txid:str - Transaction ID - None if not known, coin:str - Symbol that was sent, amount:Decimal - The amount that was sent (after fees), fee:Decimal - TX Fee that was taken from the amount, from:str - The account(s)/address(es) the coins were sent from. if more than one, comma separated. If it's not possible to determine easily, set this to None. send_type:str - Should be set to "send" if the coins were sent, or "issue" if the coins were issued. }
-
validate_amount
(amount: Union[decimal.Decimal, float, str], from_account: str = None) → decimal.Decimal[source]¶ Validates a user specified EOS token amount by:
- if amount is a float, we round it down to a 4 DP string
- we then pass the amount to Decimal so we can perform more precise calculations
- checks that the amount is at least 0.0001 (minimum amount of EOS that can be sent)
- if from_account is specified, will raise NotEnoughBalance if we don’t have enough balance to cover the TX.
Example:
>>> amount = self.validate_amount(1.23) >>> amount Decimal('1.23')
Parameters: - amount (Decimal) – The amount of EOS (or token) to be sent, ideally as Decimal (but works with float/str)
- from_account (str) – (optional) If specified, check that from_account has enough balance for this TX.
Raises: - ArithmeticError – When the amount is lower than the lowest amount allowed by the token’s precision
- NotEnoughBalance – The account from_account does not have enough balance to send this amount.
- TokenNotFound – from_account does not have a listed balance of self.symbol
Return Decimal amount: The amount after sanitization, converted to a Decimal
-
EOSMixin module¶
Copyright:
+===================================================+
| © 2019 Privex Inc. |
| https://www.privex.io |
+===================================================+
| |
| CryptoToken Converter |
| |
| Core Developer(s): |
| |
| (+) Chris (@someguy123) [Privex] |
| |
+===================================================+
-
class
payments.coin_handlers.EOS.EOSMixin.
EOSMixin
[source]¶ Bases:
payments.coin_handlers.base.SettingsMixin.SettingsMixin
EOSMixin - A child class of SettingsMixin that is used by both EOSLoader and EOSManager for shared functionality.
Main features:
- Access the EOS shared instance via :py:attr:`.eos` - Get the general ``EOS`` symbol coin settings via :py:attr:`.eos_settings` - Access individual token settings (e.g. contract) via ``self.settings[symbol]`` - Helper method :py:meth:`.get_contract` - get contract via DB, or fall back to :py:attr:`.default_contracts` - Automatically sets setting defaults, such as the RPC node (using Greymass node over SSL)
Copyright:
+===================================================+ | © 2019 Privex Inc. | | https://www.privex.io | +===================================================+ | | | CryptoToken Converter | | | | Core Developer(s): | | | | (+) Chris (@someguy123) [Privex] | | | +===================================================+
-
all_coins
¶ Ensures that the coin ‘EOS’ always has it’s settings loaded by
base.SettingsMixin
by overriding this methodall_coins
to inject the coin EOS if it’s not our symbol.Return dict coins: A dict<str,Coin> of supported coins, mapped by symbol
-
chain
= 'eos'¶ This controls the name of the chain and is used for logging, cache keys etc. It may be converted to upper case for logging, and lower case for cache keys. Forks of EOS may override this when sub-classing EOSMixin to adjust logging, cache keys etc.
-
chain_coin
= 'EOS'¶ Forks of EOS may override this when sub-classing EOSMixin to change the native coin symbol of the network
-
chain_type
= 'eos'¶ Used for looking up ‘coin_type=xxx’ Forks of EOS should override this to match the coin_type they use for
provides
generation
-
current_rpc
= None¶ Contains the current EOS API node as a string
-
default_contracts
= {'EOS': 'eosio.token'}¶ To make it easier to add common tokens on the EOS network, the loader/manager will fallback to this map between symbols and contracts.
This means that you don’t have to set the contract in the custom JSON for popular tokens in this list, such as the native EOS token (which uses the contract account eosio.token).
-
eos
¶ Returns an instance of Cleos and caches it in the attribute _eos after creation
-
eos_settings
¶ Since EOS deals with tokens under one network, this is a helper property to quickly get the base EOS settings
Return dict settings: A map of setting keys to their values
-
get_contract
(symbol: str) → str[source]¶ Attempt to find the contract account for a given token symbol, searches the database Coin objects first using
settings
- if not found, falls back todefault_contracts
Example usage:
>>> contract_acc = self.get_contract('EOS') >>> print(contract_acc) eosio.token
Parameters: symbol (str) – The token symbol to find the contract for, e.g.
EOS
Raises: - TokenNotFound – The given
symbol
does not exist in self.settings - MissingTokenMetadata – Could not find contract in DB coin settings nor default_contracts
Return str contract_acc: The contract username as a string, e.g.
eosio.token
- TokenNotFound – The given
-
provides
= ['EOS']¶ This attribute is automatically generated by scanning for
models.Coin
s with the typeeos
. This saves us from hard coding specific coin symbols. See __init__.py for populating code.
-
replace_eos
(**conn) → eospy.cleos.Cleos[source]¶ Destroy the EOS
Cleos
instance at_eos
and re-create it with the modified connection settingsconn
Also returns the EOS instance for convenience.
Only need to specify settings you want to override.
Example:
>>> eos = self.replace_eos(host='example.com', port=80, ssl=False) >>> eos.get_account('someguy123')
Parameters: conn – Connection settings. Keys: endpoint, ssl, host, port, username, password Return Cleos eos: A Cleos
instance with the modified connection settings.
-
setting_defaults
= {'endpoint': '/', 'history_url': 'https://eos-history.privex.io', 'host': 'eos.greymass.com', 'load_method': 'actions', 'password': None, 'port': 443, 'precision': 4, 'ssl': True, 'telos': False, 'username': None}¶ Default settings to use if any required values are empty, e.g. default to Greymass’s RPC node
load_method
can be eitherpvx
for Privex EOS History API, oractions
to use v1/history from the RPC node.
-
settings
¶ Get all settings, mapped by coin symbol (each coin symbol dict contains custom json settings merged)
Return dict settings: A dictionary mapping coin symbols to settings
-
url
¶ Creates a URL from the host settings on the EOS coin
-