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]:
|
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
|
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
|
asynchronously or synchronously depending on the provided asynchronous value from the function's caller. It
|
||||||
dictionary containing network, outgoing and incoming balances.
|
returns a dictionary containing network, outgoing and incoming balances when synchronously called.
|
||||||
:param asynchronous: Boolean value checking whether to return balances asynchronously
|
:param asynchronous: Boolean value checking whether to return balances asynchronously
|
||||||
:type asynchronous: bool
|
:type asynchronous: bool
|
||||||
:return:
|
:return: dict containing network, outgoing and incoming balances | an async result object from celery.
|
||||||
:rtype:
|
:rtype: dict|celery.Task
|
||||||
"""
|
"""
|
||||||
if asynchronous:
|
if asynchronous:
|
||||||
cic_eth_api = Api(
|
cic_eth_api = Api(
|
||||||
@ -47,7 +47,7 @@ class BalanceManager:
|
|||||||
callback_task='cic_ussd.tasks.callback_handler.process_balances_callback',
|
callback_task='cic_ussd.tasks.callback_handler.process_balances_callback',
|
||||||
callback_param=''
|
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:
|
else:
|
||||||
cic_eth_api = Api(chain_str=self.chain_str)
|
cic_eth_api = Api(chain_str=self.chain_str)
|
||||||
balance_request_task = cic_eth_api.balance(
|
balance_request_task = cic_eth_api.balance(
|
||||||
@ -56,27 +56,30 @@ class BalanceManager:
|
|||||||
return balance_request_task.get()[0]
|
return balance_request_task.get()[0]
|
||||||
|
|
||||||
|
|
||||||
def compute_operational_balance(balances: dict) -> float:
|
def operational_balance(balances: dict) -> float:
|
||||||
"""This function calculates the right balance given incoming and outgoing
|
"""This function computes the operational balance at an instance in the system by providing the difference of the
|
||||||
:param balances:
|
outgoing balance from the sum of incoming and network balances.
|
||||||
:type balances:
|
:param balances: A dictionary containing incoming, outgoing and network balances.
|
||||||
:return:
|
:type balances: dict
|
||||||
:rtype:
|
:return: The operational balance of the account at the instance of querying.
|
||||||
|
:rtype: float
|
||||||
"""
|
"""
|
||||||
incoming_balance = balances.get('balance_incoming')
|
incoming_balance = balances.get('balance_incoming')
|
||||||
outgoing_balance = balances.get('balance_outgoing')
|
outgoing_balance = balances.get('balance_outgoing')
|
||||||
network_balance = balances.get('balance_network')
|
network_balance = balances.get('balance_network')
|
||||||
|
|
||||||
operational_balance = (network_balance + incoming_balance) - outgoing_balance
|
balance = (network_balance + incoming_balance) - outgoing_balance
|
||||||
return from_wei(value=operational_balance)
|
return from_wei(value=balance)
|
||||||
|
|
||||||
|
|
||||||
def get_cached_operational_balance(blockchain_address: str):
|
def cached_operational_balance(blockchain_address: str) -> float:
|
||||||
"""
|
"""This function retrieves the cached balances data from redis cache and computes the operational balance from
|
||||||
:param blockchain_address:
|
the cached data.
|
||||||
:type blockchain_address:
|
:param blockchain_address: Ethereum address of the account whose balance data is being retrieved.
|
||||||
:return:
|
:type blockchain_address: str, 0x-hex
|
||||||
:rtype:
|
:return: The operational balance of the account as per cached balance data.
|
||||||
|
:rtype: float
|
||||||
|
:raises CachedDataNotFoundError
|
||||||
"""
|
"""
|
||||||
key = create_cached_data_key(
|
key = create_cached_data_key(
|
||||||
identifier=bytes.fromhex(blockchain_address[2:]),
|
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)
|
cached_balance = get_cached_data(key=key)
|
||||||
if cached_balance:
|
if cached_balance:
|
||||||
operational_balance = compute_operational_balance(balances=json.loads(cached_balance))
|
balance = operational_balance(balances=json.loads(cached_balance))
|
||||||
return operational_balance
|
return balance
|
||||||
else:
|
else:
|
||||||
raise CachedDataNotFoundError('Cached operational balance not found.')
|
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