Coin Handlers

Module contents

This module init file is responsible for loading the Coin Handler modules, and offering methods for accessing loaders and managers.

A Coin Handler is a Python module (folder containing classes and init file) designed to handle sending/receiving cryptocurrency/tokens for a certain network, or certain family of networks sharing similar code.

They may handle just one single coin, several coins, or they may even allow users to dynamically add coins by querying for a specific coin_type from the model payments.models.Coin

A coin handler must contain:

  • An __init__.py with a dictionary named exports, containing the keys ‘loader’ and/or ‘manager’ pointing to the un-instantiated loader/manager class.

    • If your init file needs to do some sort-of initialisation, such as dynamically generating provides for your classes, or adding a new coin type to settings.COIN_TYPES, it’s best to place it in a function named “reload” with a global boolean loaded so that you only initialise the module the first time it’s loaded.

      See the example __init__.py near the bottom of this module docstring.

      This is optional, but it will allow reload_handlers() to properly re-trigger your initialisation code only when changes occur, such as Coin’s being created/updated in the database.

  • Two classes, a Loader and a Manager. Each class can either in it’s own file, or in a single file containing other classes / functions.

    • A Loader is a class which extends base.BaseLoader, and is responsible for retrieving transactions that occur on that coin to detect incoming transactions.
    • A Manager is a class which extends base.BaseManager, and is responsible for handling sending/issuing of coins/tokens, as well as other small functions such as validating addresses, and checking balances.

Your Loader class may choose to extend the helper class base.BatchLoader, allowing your loader to use batches/chunking for memory efficiency, without having to write much code.

Your Coin Handler classes should ONLY use the exceptions in base.exceptions, along with any exceptions listed in the :raises: pydoc statements of the overridden method.

For handling automatic retry when something goes wrong, you can use the decorator base.decorators.retry_on_err()

Example __init__.py:

>>> from django.conf import settings
>>> from payments.coin_handlers.SteemEngine.SteemEngineLoader import SteemEngineLoader
>>> from payments.coin_handlers.SteemEngine.SteemEngineManager import SteemEngineManager
>>>
>>> loaded = False
>>>
>>> def reload():
>>>     global loaded
>>>     if 'steemengine' not in dict(settings.COIN_TYPES):
>>>         settings.COIN_TYPES += (('steemengine', 'SteemEngine Token',),)
>>>     loaded = True
>>>
>>> if not loaded:
>>>    reload()
>>>
>>> exports = {
>>>     "loader": SteemEngineLoader,
>>>     "manager": SteemEngineManager
>>> }

For an example of how to layout your coin handler module, check out the pre-included Coin Handlers:

payments.coin_handlers.add_handler(handler, handler_type)[source]
payments.coin_handlers.ch_base = 'payments.coin_handlers'

Base module path to where the coin handler modules are located. E.g. payments.coin_handlers

payments.coin_handlers.get_loader(symbol: str) → payments.coin_handlers.base.BaseLoader.BaseLoader[source]

For some use-cases, you may want to just grab the first loader that supports this coin.

>>> m = get_loader('ENG')
>>> m.send(amount=Decimal(1), from_address='someguy123', address='privex')
Parameters:symbol – The coin symbol to get the loader for (uppercase)
Return BaseLoader:
 An instance implementing base.BaseLoader
payments.coin_handlers.get_loaders(symbol: str = None) → list[source]

Get all loader’s, or all loader’s for a certain coin

Parameters:symbol – The coin symbol to get all loaders for (uppercase)
Return list:If symbol not specified, a list of tuples (symbol, list<BaseLoader>,)
Return list:If symbol IS specified, a list of instantiated base.BaseLoader’s
payments.coin_handlers.get_manager(symbol: str) → payments.coin_handlers.base.BaseManager.BaseManager[source]

For some use-cases, you may want to just grab the first manager that supports this coin.

>>> m = get_manager('ENG')
>>> m.send(amount=Decimal(1), from_address='someguy123', address='privex')
Parameters:symbol – The coin symbol to get the manager for (uppercase)
Return BaseManager:
 An instance implementing base.BaseManager
payments.coin_handlers.get_managers(symbol: str = None) → list[source]

Get all manager’s, or all manager’s for a certain coin

Parameters:symbol – The coin symbol to get all managers for (uppercase)
Return list:If symbol not specified, a list of tuples (symbol, list<BaseManager>,)
Return list:If symbol IS specified, a list of instantiated base.BaseManager’s
payments.coin_handlers.handlers = {}

A dictionary of coin symbols, containing instantiated managers (BaseManager) and loaders (BaseLoader)

Example layout:

handlers = {
    'ENG': {
        'loaders':  [ SteemEngineLoader, ],
        'managers': [ SteemEngineLoader, ],
    },
    'SGTK': {
        'loaders':  [ SteemEngineLoader, ],
        'managers': [ SteemEngineLoader, ],
    },
}
payments.coin_handlers.handlers_loaded = False

Used to track whether the Coin Handlers have been initialized, so reload_handlers can be auto-called.

payments.coin_handlers.has_loader(symbol: str) → bool[source]

Helper function - does this symbol have a loader class?

payments.coin_handlers.has_manager(symbol: str) → bool[source]

Helper function - does this symbol have a manager class?

payments.coin_handlers.is_database_synchronized(database: str) → bool[source]

Check if all migrations have been ran. Useful for preventing auto-running code accessing models before the tables even exist, thus preventing you from migrating…

>>> from django.db import DEFAULT_DB_ALIAS
>>> if not is_database_synchronized(DEFAULT_DB_ALIAS):
>>>     log.warning('Cannot run reload_handlers because there are unapplied migrations!')
>>>     return
Parameters:database (str) – Which Django database config is being used? Generally just pass django.db.DEFAULT_DB_ALIAS
Return bool:True if all migrations have been ran, False if not.
payments.coin_handlers.reload_handlers()[source]

Resets handler to an empty dict, then loads all settings.COIN_HANDLER classes into the dictionary handlers using settings.COIN_HANDLERS_BASE as the base module path to load from