Compare commits
3 Commits
master
...
philip/har
Author | SHA1 | Date | |
---|---|---|---|
ff0ed7b99c | |||
8a6d332bca | |||
4d812a74e6 |
62
apps/cic-ussd/cic_ussd/account/__init__.py
Normal file
62
apps/cic-ussd/cic_ussd/account/__init__.py
Normal file
@ -0,0 +1,62 @@
|
||||
"""This package handles account operations."""
|
||||
|
||||
# external imports
|
||||
from cic_eth.api import Api
|
||||
|
||||
# local imports
|
||||
from cic_ussd.operations import (add_tasks_to_tracker,
|
||||
cache_account_creation_task_id,
|
||||
create_or_update_session,
|
||||
define_multilingual_responses)
|
||||
from cic_ussd.menu.ussd_menu import UssdMenu
|
||||
|
||||
|
||||
def create(chain_str: str,
|
||||
external_session_id: str,
|
||||
phone_number: str,
|
||||
service_code: str,
|
||||
user_input: str) -> str:
|
||||
"""This function issues a task to create a blockchain account on cic-eth. It then creates a record of the ussd
|
||||
session corresponding to the creation of the account and returns a response denoting that the user's account is
|
||||
being created.
|
||||
:param chain_str: The chain name and network id.
|
||||
:type chain_str: str
|
||||
:param external_session_id: A unique ID from africastalking.
|
||||
:type external_session_id: str
|
||||
:param phone_number: The phone number for the account to be created.
|
||||
:type phone_number: str
|
||||
:param service_code: The service code dialed.
|
||||
:type service_code: str
|
||||
:param user_input: The input entered by the user.
|
||||
:type user_input: str
|
||||
:return: A response denoting that the account is being created.
|
||||
:rtype: str
|
||||
"""
|
||||
# attempt to create a user
|
||||
cic_eth_api = Api(callback_task='cic_ussd.tasks.callback_handler.process_account_creation_callback',
|
||||
callback_queue='cic-ussd',
|
||||
callback_param='',
|
||||
chain_str=chain_str)
|
||||
creation_task_id = cic_eth_api.create_account().id
|
||||
|
||||
# record task initiation time
|
||||
add_tasks_to_tracker(task_uuid=creation_task_id)
|
||||
|
||||
# cache account creation data
|
||||
cache_account_creation_task_id(phone_number=phone_number, task_id=creation_task_id)
|
||||
|
||||
# find menu to notify user account is being created
|
||||
current_menu = UssdMenu.find_by_name(name='account_creation_prompt')
|
||||
|
||||
# create a ussd session session
|
||||
create_or_update_session(
|
||||
external_session_id=external_session_id,
|
||||
phone=phone_number,
|
||||
service_code=service_code,
|
||||
current_menu=current_menu.get('name'),
|
||||
user_input=user_input)
|
||||
|
||||
# define response to relay to user
|
||||
response = define_multilingual_responses(
|
||||
key='ussd.kenya.account_creation_prompt', locales=['en', 'sw'], prefix='END')
|
||||
return response
|
@ -33,12 +33,12 @@ class BalanceManager:
|
||||
def get_balances(self, asynchronous: bool = False) -> Union[celery.Task, dict]:
|
||||
"""
|
||||
This function queries cic-eth for an account's balances, It provides a means to receive the balance either
|
||||
asynchronously or synchronously depending on the provided value for teh asynchronous parameter. It returns a
|
||||
dictionary containing network, outgoing and incoming balances.
|
||||
asynchronously or synchronously depending on the provided asynchronous value from the function's caller. It
|
||||
returns a dictionary containing network, outgoing and incoming balances when synchronously called.
|
||||
:param asynchronous: Boolean value checking whether to return balances asynchronously
|
||||
:type asynchronous: bool
|
||||
:return:
|
||||
:rtype:
|
||||
:return: dict containing network, outgoing and incoming balances | an async result object from celery.
|
||||
:rtype: dict|celery.Task
|
||||
"""
|
||||
if asynchronous:
|
||||
cic_eth_api = Api(
|
||||
@ -47,7 +47,7 @@ class BalanceManager:
|
||||
callback_task='cic_ussd.tasks.callback_handler.process_balances_callback',
|
||||
callback_param=''
|
||||
)
|
||||
cic_eth_api.balance(address=self.address, token_symbol=self.token_symbol)
|
||||
return cic_eth_api.balance(address=self.address, token_symbol=self.token_symbol)
|
||||
else:
|
||||
cic_eth_api = Api(chain_str=self.chain_str)
|
||||
balance_request_task = cic_eth_api.balance(
|
||||
@ -56,27 +56,30 @@ class BalanceManager:
|
||||
return balance_request_task.get()[0]
|
||||
|
||||
|
||||
def compute_operational_balance(balances: dict) -> float:
|
||||
"""This function calculates the right balance given incoming and outgoing
|
||||
:param balances:
|
||||
:type balances:
|
||||
:return:
|
||||
:rtype:
|
||||
def operational_balance(balances: dict) -> float:
|
||||
"""This function computes the operational balance at an instance in the system by providing the difference of the
|
||||
outgoing balance from the sum of incoming and network balances.
|
||||
:param balances: A dictionary containing incoming, outgoing and network balances.
|
||||
:type balances: dict
|
||||
:return: The operational balance of the account at the instance of querying.
|
||||
:rtype: float
|
||||
"""
|
||||
incoming_balance = balances.get('balance_incoming')
|
||||
outgoing_balance = balances.get('balance_outgoing')
|
||||
network_balance = balances.get('balance_network')
|
||||
|
||||
operational_balance = (network_balance + incoming_balance) - outgoing_balance
|
||||
return from_wei(value=operational_balance)
|
||||
balance = (network_balance + incoming_balance) - outgoing_balance
|
||||
return from_wei(value=balance)
|
||||
|
||||
|
||||
def get_cached_operational_balance(blockchain_address: str):
|
||||
"""
|
||||
:param blockchain_address:
|
||||
:type blockchain_address:
|
||||
:return:
|
||||
:rtype:
|
||||
def cached_operational_balance(blockchain_address: str) -> float:
|
||||
"""This function retrieves the cached balances data from redis cache and computes the operational balance from
|
||||
the cached data.
|
||||
:param blockchain_address: Ethereum address of the account whose balance data is being retrieved.
|
||||
:type blockchain_address: str, 0x-hex
|
||||
:return: The operational balance of the account as per cached balance data.
|
||||
:rtype: float
|
||||
:raises CachedDataNotFoundError
|
||||
"""
|
||||
key = create_cached_data_key(
|
||||
identifier=bytes.fromhex(blockchain_address[2:]),
|
||||
@ -84,7 +87,7 @@ def get_cached_operational_balance(blockchain_address: str):
|
||||
)
|
||||
cached_balance = get_cached_data(key=key)
|
||||
if cached_balance:
|
||||
operational_balance = compute_operational_balance(balances=json.loads(cached_balance))
|
||||
return operational_balance
|
||||
balance = operational_balance(balances=json.loads(cached_balance))
|
||||
return balance
|
||||
else:
|
||||
raise CachedDataNotFoundError('Cached operational balance not found.')
|
50
apps/cic-ussd/cic_ussd/account/data.py
Normal file
50
apps/cic-ussd/cic_ussd/account/data.py
Normal file
@ -0,0 +1,50 @@
|
||||
"""This module defines functions required to query external components of the cic platform for data relevant to
|
||||
accounts on the cic-ussd component.
|
||||
"""
|
||||
|
||||
# external imports
|
||||
import celery
|
||||
from cic_eth.api import Api
|
||||
|
||||
# local imports
|
||||
from cic_ussd.chain import Chain
|
||||
|
||||
|
||||
def person_metadata(blockchain_address: str):
|
||||
"""This function asynchronously queries the metadata server for metadata associated with the person data type and
|
||||
a given blockchain address.
|
||||
:param blockchain_address: Ethereum address of account whose metadata is being queried.
|
||||
:type blockchain_address: str, 0x-hex
|
||||
"""
|
||||
s_query_person_metadata = celery.signature(
|
||||
'cic_ussd.tasks.metadata.query_person_metadata',
|
||||
[blockchain_address]
|
||||
)
|
||||
s_query_person_metadata.apply_async(queue='cic-ussd')
|
||||
|
||||
|
||||
def default_token_data() -> dict:
|
||||
"""This function queries for the default token's data from the cic_eth tasks exposed over its Api class.
|
||||
:return: A dict containing the default token address and it's corresponding symbol.
|
||||
:rtype: dict
|
||||
"""
|
||||
chain_str = Chain.spec.__str__()
|
||||
cic_eth_api = Api(chain_str=chain_str)
|
||||
default_token_request_task = cic_eth_api.default_token()
|
||||
return default_token_request_task.get()
|
||||
|
||||
|
||||
def transactions_statement(blockchain_address: str):
|
||||
"""This function asynchronously queries the cic-eth server to retrieve a chronologically reversed list of
|
||||
transactions for an account.
|
||||
:param blockchain_address: Ethereum address of account whose transactions is being queried.
|
||||
:type blockchain_address:
|
||||
"""
|
||||
chain_str = Chain.spec.__str__()
|
||||
cic_eth_api = Api(
|
||||
chain_str=chain_str,
|
||||
callback_queue='cic-ussd',
|
||||
callback_task='cic_ussd.tasks.callback_handler.process_statement_callback',
|
||||
callback_param=blockchain_address
|
||||
)
|
||||
cic_eth_api.list(address=blockchain_address, limit=9)
|
Loading…
Reference in New Issue
Block a user