Compare commits

..

2 Commits

15 changed files with 195 additions and 1133 deletions

View File

@@ -423,6 +423,12 @@ def process_request(user_input: str, user: Account, ussd_session: Optional[dict]
:return: A ussd menu's corresponding text value. :return: A ussd menu's corresponding text value.
:rtype: Document :rtype: Document
""" """
# retrieve metadata before any transition
key = generate_metadata_pointer(
identifier=blockchain_address_to_metadata_pointer(blockchain_address=user.blockchain_address),
cic_type=':cic.person'
)
person_metadata = get_cached_data(key=key)
if ussd_session: if ussd_session:
if user_input == "0": if user_input == "0":
@@ -446,7 +452,7 @@ def process_request(user_input: str, user: Account, ussd_session: Optional[dict]
'exit_pin_mismatch', 'exit_pin_mismatch',
'exit_invalid_request', 'exit_invalid_request',
'exit_successful_transaction' 'exit_successful_transaction'
]: ] and person_metadata is not None:
return UssdMenu.find_by_name(name='start') return UssdMenu.find_by_name(name='start')
else: else:
return UssdMenu.find_by_name(name=last_state) return UssdMenu.find_by_name(name=last_state)

View File

@@ -145,7 +145,7 @@ def application(env, start_response):
if get_request_method(env=env) == 'POST' and get_request_endpoint(env=env) == '/': if get_request_method(env=env) == 'POST' and get_request_endpoint(env=env) == '/':
if env.get('CONTENT_TYPE') != 'application/x-www-form-urlencoded': if env.get('CONTENT_TYPE') != 'application/x-www-form-urlencoded':
start_response('405 Urlencoded, please', errors_headers) start_response('405 Play by the rules', errors_headers)
return [] return []
post_data = env.get('wsgi.input').read() post_data = env.get('wsgi.input').read()
@@ -213,9 +213,6 @@ def application(env, start_response):
return [response_bytes] return [response_bytes]
else: else:
logg.error('invalid query {}'.format(env))
for r in env:
logg.debug('{}: {}'.format(r, env))
start_response('405 Play by the rules', errors_headers) start_response('405 Play by the rules', errors_headers)
return [] return []

View File

@@ -1,4 +1,4 @@
cic_base[full_graph]~=0.1.2b17 cic_base[full_graph]~=0.1.2b15
cic-eth~=0.11.0b17 cic-eth~=0.11.0b16
cic-notify~=0.4.0a5 cic-notify~=0.4.0a5
cic-types~=0.1.0a10 cic-types~=0.1.0a10

View File

@@ -0,0 +1,25 @@
# INTEGRATION TESTING
This folder contains integration tests.
## OVERVIEW
There are four files defining the integration tests.
* **test_account_creation**: Tests account sign up process.
* **test_transactions**: Tests transactions between two accounts.
* **test_profile_management**: Tests that account metadata can be edited.
* **test_account_management**: Tests that account management functionalities are intact.
## REQUIREMENTS
In order to run the transaction tests, please ensure that the faucet amount is set to a non-zero value, ideally `50000000`
which is the value set in the config file `.config/test/integration.ini`.
This implies setting the `DEV_FAUCET_AMOUNT` to a non-zero value before bringing up the contract-migration image:
```shell
export DEV_FAUCET_AMOUNT=50000000
RUN_MASK=1 docker-compose up contract-migration
RUN_MASK=2 docker-compose up contract-migration
```

View File

@@ -214,12 +214,13 @@ stages:
status_code: status_code:
- 200 - 200
headers: headers:
Content-Length: '28' Content-Length: '51'
Content-Type: "text/plain" Content-Type: "text/plain"
verify_response_with: verify_response_with:
function: ext.validator:validate_response function: ext.validator:validate_response
extra_kwargs: extra_kwargs:
expected_response: "CON Enter first name\n0. Back" expected_response: "CON Balance {gift_value} {token_symbol}\n1. Send\n2. My Account\n3. Help"
delay_before: 10
- name: Pin number confirmation [{second_account_pin_number} - second account] - name: Pin number confirmation [{second_account_pin_number} - second account]
request: request:
@@ -232,227 +233,6 @@ stages:
headers: headers:
content-type: "application/x-www-form-urlencoded" content-type: "application/x-www-form-urlencoded"
method: POST method: POST
response:
status_code:
- 200
headers:
Content-Length: '37'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Weka jina lako la kwanza\n0. Nyuma"
- name: Enter first name [first_account_given_name - first account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{first_metadata_entry_session_id}"
phoneNumber: "{first_account_phone_number}"
text: "1*{first_account_pin_number}*{first_account_pin_number}*{first_account_given_name}"
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '29'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Enter family name\n0. Back"
- name: Enter first name [second_account_given_name - second account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{second_metadata_entry_session_id}"
phoneNumber: "{second_account_phone_number}"
text: "2*{second_account_pin_number}*{second_account_pin_number}*{second_account_given_name}"
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '37'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Weka jina lako la mwisho\n0. Nyuma"
- name: Enter last name [first_account_family_name - first account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{first_metadata_entry_session_id}"
phoneNumber: "{first_account_phone_number}"
text: "1*{first_account_pin_number}*{first_account_pin_number}*{first_account_given_name}*{first_account_family_name}"
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '51'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Enter gender\n1. Male\n2. Female\n3. Other\n0. Back"
- name: Enter last name [second_account_family_name - second account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{second_metadata_entry_session_id}"
phoneNumber: "{second_account_phone_number}"
text: "2*{second_account_pin_number}*{second_account_pin_number}*{second_account_given_name}*{second_account_family_name}"
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '64'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Weka jinsia yako\n1. Mwanaume\n2. Mwanamke\n3. Nyngine\n0. Nyuma"
- name: Select gender [Male - first account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{first_metadata_entry_session_id}"
phoneNumber: "{first_account_phone_number}"
text: "1*{first_account_pin_number}*{first_account_pin_number}*{first_account_given_name}*{first_account_family_name}*1"
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '31'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Enter your location\n0. Back"
- name: Select gender [Female - second account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{second_metadata_entry_session_id}"
phoneNumber: "{second_account_phone_number}"
text: "2*{second_account_pin_number}*{second_account_pin_number}*{second_account_given_name}*{second_account_family_name}*2"
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '27'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Weka eneo lako\n0. Nyuma"
- name: Enter location [first_account_location - first account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{first_metadata_entry_session_id}"
phoneNumber: "{first_account_phone_number}"
text: "1*{first_account_pin_number}*{first_account_pin_number}*{first_account_given_name}*{first_account_family_name}*1*{first_account_location}"
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '55'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Please enter a product or service you offer\n0. Back"
- name: Enter location [second_account_location - second account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{second_metadata_entry_session_id}"
phoneNumber: "{second_account_phone_number}"
text: "2*{second_account_pin_number}*{second_account_pin_number}*{second_account_given_name}*{second_account_family_name}*2*{second_account_location}"
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '42'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Weka bidhaa ama huduma unauza\n0. Nyuma"
- name: Enter product [first_account_product - first account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{first_metadata_entry_session_id}"
phoneNumber: "{first_account_phone_number}"
text: "1*{first_account_pin_number}*{first_account_pin_number}*{first_account_given_name}*{first_account_family_name}*1*{first_account_location}*{first_account_product}"
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '51'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Balance {gift_value} {token_symbol}\n1. Send\n2. My Account\n3. Help"
delay_before: 10
- name: Enter product [second_account_product - second account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{second_metadata_entry_session_id}"
phoneNumber: "{second_account_phone_number}"
text: "2*{second_account_pin_number}*{second_account_pin_number}*{second_account_given_name}*{second_account_family_name}*2*{second_account_location}*{second_account_product}"
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response: response:
status_code: status_code:
- 200 - 200

View File

@@ -170,7 +170,7 @@ stages:
verify_response_with: verify_response_with:
function: ext.validator:validate_response function: ext.validator:validate_response
extra_kwargs: extra_kwargs:
expected_response: "CON {second_account_given_name} {second_account_family_name} {second_account_phone_number} will receive 17.00 {token_symbol} from {first_account_given_name} {first_account_family_name} {first_account_phone_number}.\nPlease enter your PIN to confirm.\n0. Back" expected_response: "CON {second_account_phone_number} will receive 17.00 {token_symbol} from {first_account_phone_number}.\nPlease enter your PIN to confirm.\n0. Back"
- name: Enter transcation amount [second account] - name: Enter transcation amount [second account]
request: request:
@@ -191,7 +191,7 @@ stages:
verify_response_with: verify_response_with:
function: ext.validator:validate_response function: ext.validator:validate_response
extra_kwargs: extra_kwargs:
expected_response: "CON {first_account_given_name} {first_account_family_name} {first_account_phone_number} atapokea 25.00 {token_symbol} kutoka kwa {second_account_given_name} {second_account_family_name} {second_account_phone_number}.\nTafadhali weka nambari yako ya siri kudhibitisha.\n0. Nyuma" expected_response: "CON {first_account_phone_number} atapokea 25.00 {token_symbol} kutoka kwa {second_account_phone_number}.\nTafadhali weka nambari yako ya siri kudhibitisha.\n0. Nyuma"
- name: Pin to authorize transaction [first account] - name: Pin to authorize transaction [first account]
request: request:
@@ -212,7 +212,7 @@ stages:
verify_response_with: verify_response_with:
function: ext.validator:validate_response function: ext.validator:validate_response
extra_kwargs: extra_kwargs:
expected_response: "CON Your request has been sent. {second_account_given_name} {second_account_family_name} {second_account_phone_number} will receive 17.00 {token_symbol} from {first_account_given_name} {first_account_family_name} {first_account_phone_number}.\n00. Back\n99. Exit" expected_response: "CON Your request has been sent. {second_account_phone_number} will receive 17.00 {token_symbol} from {first_account_phone_number}.\n00. Back\n99. Exit"
- name: Pin to authorize transaction [second account] - name: Pin to authorize transaction [second account]
request: request:
@@ -233,7 +233,7 @@ stages:
verify_response_with: verify_response_with:
function: ext.validator:validate_response function: ext.validator:validate_response
extra_kwargs: extra_kwargs:
expected_response: "CON Ombi lako limetumwa. {first_account_given_name} {first_account_family_name} {first_account_phone_number} atapokea 25.00 {token_symbol} kutoka kwa {second_account_given_name} {second_account_family_name} {second_account_phone_number}.\n00. Nyuma\n99. Ondoka" expected_response: "CON Ombi lako limetumwa. {first_account_phone_number} atapokea 25.00 {token_symbol} kutoka kwa {second_account_phone_number}.\n00. Nyuma\n99. Ondoka"
- name: Verify balance changes [first account] - name: Verify balance changes [first account]
delay_before: 10 delay_before: 10

View File

@@ -136,7 +136,7 @@ First, make a note of the **block height** before running anything:
To import, run to _completion_: To import, run to _completion_:
`python eth/import_users.py -v -c config -p <eth_provider> -r <cic_registry_address> -y ../contract-migration/keystore/UTC--2021-01-08T17-18-44.521011372Z--eb3907ecad74a0013c259d5874ae7f22dcbcc95c <datadir>` `python eth/import_users.py -v -c config -p <eth_provider> -r <cic_registry_address> -y ../keystore/UTC--2021-01-08T17-18-44.521011372Z--eb3907ecad74a0013c259d5874ae7f22dcbcc95c <datadir>`
After the script completes, keystore files for all generated accouts will be found in `<datadir>/keystore`, all with `foo` as password (would set it empty, but believe it or not some interfaces out there won't work unless you have one). After the script completes, keystore files for all generated accouts will be found in `<datadir>/keystore`, all with `foo` as password (would set it empty, but believe it or not some interfaces out there won't work unless you have one).
@@ -150,7 +150,7 @@ Then run:
Run in sequence, in first terminal: Run in sequence, in first terminal:
`python cic_eth/import_balance.py -v -c config -p <eth_provider> -r <cic_registry_address> --token-symbol <token_symbol> -y ../contract-migration/keystore/UTC--2021-01-08T17-18-44.521011372Z--eb3907ecad74a0013c259d5874ae7f22dcbcc95c --head out` `python cic_eth/import_balance.py -v -c config -p <eth_provider> -r <cic_registry_address> --token-symbol <token_symbol> -y ../keystore/UTC--2021-01-08T17-18-44.521011372Z--eb3907ecad74a0013c259d5874ae7f22dcbcc95c --head out`
In another terminal: In another terminal:
@@ -226,7 +226,7 @@ The connection parameters for the `cic-ussd-server` is currently _hardcoded_ in
### Step 5 - Verify ### Step 5 - Verify
`python verify.py -v -c config -r <cic_registry_address> -p <eth_provider> --token-symbol <token_symbol> <datadir>` `python verify.py -v -c config -r <cic_registry_address> -p <eth_provider> <datadir>`
Included checks: Included checks:
* Private key is in cic-eth keystore * Private key is in cic-eth keystore
@@ -262,5 +262,3 @@ Should exit with code 0 if all input data is found in the respective services.
- MacOS BigSur issue when installing psycopg2: ld: library not found for -lssl -> https://github.com/psycopg/psycopg2/issues/1115#issuecomment-831498953 - MacOS BigSur issue when installing psycopg2: ld: library not found for -lssl -> https://github.com/psycopg/psycopg2/issues/1115#issuecomment-831498953
- `cic_ussd` imports is poorly implemented, and consumes a lot of resources. Therefore it takes a long time to complete. Reducing the amount of polls for the phone pointer would go a long way to improve it. - `cic_ussd` imports is poorly implemented, and consumes a lot of resources. Therefore it takes a long time to complete. Reducing the amount of polls for the phone pointer would go a long way to improve it.
- A strict constraint is maintained insistin the use of postgresql-12.

View File

@@ -114,7 +114,7 @@ def main():
conn = EthHTTPConnection(config.get('ETH_PROVIDER')) conn = EthHTTPConnection(config.get('ETH_PROVIDER'))
ImportTask.balance_processor = BalanceProcessor(conn, chain_spec, config.get('CIC_REGISTRY_ADDRESS'), signer_address, signer) ImportTask.balance_processor = BalanceProcessor(conn, chain_spec, config.get('CIC_REGISTRY_ADDRESS'), signer_address, signer)
ImportTask.balance_processor.init(token_symbol) ImportTask.balance_processor.init()
# TODO get decimals from token # TODO get decimals from token
balances = {} balances = {}
@@ -139,7 +139,6 @@ def main():
ImportTask.balances = balances ImportTask.balances = balances
ImportTask.count = i ImportTask.count = i
ImportTask.import_dir = user_dir
s = celery.signature( s = celery.signature(
'import_task.send_txs', 'import_task.send_txs',

View File

@@ -39,7 +39,6 @@ elif args.vv:
config_dir = args.c config_dir = args.c
config = confini.Config(config_dir, os.environ.get('CONFINI_ENV_PREFIX')) config = confini.Config(config_dir, os.environ.get('CONFINI_ENV_PREFIX'))
config.process() config.process()
logg.debug('config loaded from {}:\n{}'.format(args.c, config))
celery_app = celery.Celery(broker=config.get('CELERY_BROKER_URL'), backend=config.get('CELERY_RESULT_URL')) celery_app = celery.Celery(broker=config.get('CELERY_BROKER_URL'), backend=config.get('CELERY_RESULT_URL'))
@@ -63,6 +62,9 @@ def main():
) )
s_import_pins.apply_async() s_import_pins.apply_async()
argv = ['worker', '-Q', 'cic-import-ussd', '--loglevel=DEBUG']
celery_app.worker_main(argv)
if __name__ == '__main__': if __name__ == '__main__':
main() main()

View File

@@ -1,21 +1,29 @@
# standard imports # standard imports
import argparse
import json
import logging
import os import os
import sys import sys
import json
import logging
import argparse
import uuid
import datetime
import time import time
import urllib.request import urllib.request
import uuid from glob import glob
from urllib.parse import urlencode
# external imports # third-party imports
import celery
import confini
import phonenumbers
import redis import redis
from chainlib.chain import ChainSpec import confini
import celery
from hexathon import (
add_0x,
strip_0x,
)
from chainlib.eth.address import to_checksum
from cic_types.models.person import Person from cic_types.models.person import Person
from cic_eth.api.api_task import Api
from chainlib.chain import ChainSpec
from cic_types.processor import generate_metadata_pointer
import phonenumbers
logging.basicConfig(level=logging.WARNING) logging.basicConfig(level=logging.WARNING)
logg = logging.getLogger() logg = logging.getLogger()
@@ -79,13 +87,21 @@ chain_str = str(chain_spec)
batch_size = args.batch_size batch_size = args.batch_size
batch_delay = args.batch_delay batch_delay = args.batch_delay
db_configs = {
'database': config.get('DATABASE_NAME'),
'host': config.get('DATABASE_HOST'),
'port': config.get('DATABASE_PORT'),
'user': config.get('DATABASE_USER'),
'password': config.get('DATABASE_PASSWORD')
}
def build_ussd_request(phone, host, port, service_code, username, password, ssl=False): def build_ussd_request(phone, host, port, service_code, username, password, ssl=False):
url = 'http' url = 'http'
if ssl: if ssl:
url += 's' url += 's'
url += '://{}:{}'.format(host, port) url += '://{}:{}'.format(host, port)
url += '/?username={}&password={}'.format(username, password) url += '/?username={}&password={}'.format(username, password) #config.get('USSD_USER'), config.get('USSD_PASS'))
logg.info('ussd service url {}'.format(url)) logg.info('ussd service url {}'.format(url))
logg.info('ussd phone {}'.format(phone)) logg.info('ussd phone {}'.format(phone))
@@ -98,10 +114,9 @@ def build_ussd_request(phone, host, port, service_code, username, password, ssl=
'text': service_code, 'text': service_code,
} }
req = urllib.request.Request(url) req = urllib.request.Request(url)
req.method=('POST') data_str = json.dumps(data)
data_str = urlencode(data)
data_bytes = data_str.encode('utf-8') data_bytes = data_str.encode('utf-8')
req.add_header('Content-Type', 'application/x-www-form-urlencoded') req.add_header('Content-Type', 'application/json')
req.data = data_bytes req.data = data_bytes
return req return req

View File

@@ -31,7 +31,9 @@ elif args.vv:
config_dir = args.c config_dir = args.c
config = Config(config_dir, os.environ.get('CONFINI_ENV_PREFIX')) config = Config(config_dir, os.environ.get('CONFINI_ENV_PREFIX'))
config.process() config.process()
logg.debug('config loaded from {}:\n{}'.format(args.c, config))
user_old_dir = os.path.join(args.user_dir, 'old')
os.stat(user_old_dir)
db_configs = { db_configs = {
'database': config.get('DATABASE_NAME'), 'database': config.get('DATABASE_NAME'),
@@ -43,15 +45,18 @@ db_configs = {
celery_app = celery.Celery(broker=config.get('CELERY_BROKER_URL'), backend=config.get('CELERY_RESULT_URL')) celery_app = celery.Celery(broker=config.get('CELERY_BROKER_URL'), backend=config.get('CELERY_RESULT_URL'))
if __name__ == '__main__': if __name__ == '__main__':
for x in os.walk(args.user_dir): for x in os.walk(user_old_dir):
for y in x[2]: for y in x[2]:
if y[len(y) - 5:] == '.json': if y[len(y) - 5:] != '.json':
continue
# handle ussd_data json object
if y[:15] == '_ussd_data.json':
filepath = os.path.join(x[0], y) filepath = os.path.join(x[0], y)
f = open(filepath, 'r') f = open(filepath, 'r')
try: try:
ussd_data = json.load(f) ussd_data = json.load(f)
logg.debug(f'LOADING USSD DATA: {ussd_data}')
except json.decoder.JSONDecodeError as e: except json.decoder.JSONDecodeError as e:
f.close() f.close()
logg.error('load error for {}: {}'.format(y, e)) logg.error('load error for {}: {}'.format(y, e))

View File

@@ -6,7 +6,7 @@ from eth_contract_registry import Registry
from eth_token_index import TokenUniqueSymbolIndex from eth_token_index import TokenUniqueSymbolIndex
from chainlib.eth.gas import OverrideGasOracle from chainlib.eth.gas import OverrideGasOracle
from chainlib.eth.nonce import OverrideNonceOracle from chainlib.eth.nonce import OverrideNonceOracle
from eth_erc20 import ERC20 from chainlib.eth.erc20 import ERC20
from chainlib.eth.tx import ( from chainlib.eth.tx import (
count, count,
TxFormat, TxFormat,
@@ -37,7 +37,7 @@ class BalanceProcessor:
self.value_multiplier = 1 self.value_multiplier = 1
def init(self, token_symbol): def init(self):
# Get Token registry address # Get Token registry address
registry = Registry(self.chain_spec) registry = Registry(self.chain_spec)
o = registry.address_of(self.registry_address, 'TokenRegistry') o = registry.address_of(self.registry_address, 'TokenRegistry')
@@ -46,10 +46,10 @@ class BalanceProcessor:
logg.info('found token index address {}'.format(self.token_index_address)) logg.info('found token index address {}'.format(self.token_index_address))
token_registry = TokenUniqueSymbolIndex(self.chain_spec) token_registry = TokenUniqueSymbolIndex(self.chain_spec)
o = token_registry.address_of(self.token_index_address, token_symbol) o = token_registry.address_of(self.token_index_address, 'SRF')
r = self.conn.do(o) r = self.conn.do(o)
self.token_address = token_registry.parse_address_of(r) self.token_address = token_registry.parse_address_of(r)
logg.info('found {} token address {}'.format(token_symbol, self.token_address)) logg.info('found SRF token address {}'.format(self.token_address))
tx_factory = ERC20(self.chain_spec) tx_factory = ERC20(self.chain_spec)
o = tx_factory.decimals(self.token_address) o = tx_factory.decimals(self.token_address)

View File

@@ -3,7 +3,6 @@ import argparse
import json import json
import logging import logging
import os import os
import uuid
# third-party imports # third-party imports
import bcrypt import bcrypt
@@ -84,7 +83,7 @@ if __name__ == '__main__':
phone_object = phonenumbers.parse(u.tel) phone_object = phonenumbers.parse(u.tel)
phone = phonenumbers.format_number(phone_object, phonenumbers.PhoneNumberFormat.E164) phone = phonenumbers.format_number(phone_object, phonenumbers.PhoneNumberFormat.E164)
password_hash = uuid.uuid4().hex password_hash = generate_password_hash()
pins_file.write(f'{phone},{password_hash}\n') pins_file.write(f'{phone},{password_hash}\n')
logg.info(f'Writing phone: {phone}, password_hash: {password_hash}') logg.info(f'Writing phone: {phone}, password_hash: {password_hash}')

View File

@@ -9,7 +9,6 @@ import sys
import urllib import urllib
import urllib.request import urllib.request
import uuid import uuid
import urllib.parse
# external imports # external imports
import celery import celery
@@ -73,7 +72,7 @@ argparser.add_argument('--ussd-provider', type=str, dest='ussd_provider', defaul
argparser.add_argument('--skip-custodial', dest='skip_custodial', action='store_true', help='skip all custodial verifications') argparser.add_argument('--skip-custodial', dest='skip_custodial', action='store_true', help='skip all custodial verifications')
argparser.add_argument('--exclude', action='append', type=str, default=[], help='skip specified verification') argparser.add_argument('--exclude', action='append', type=str, default=[], help='skip specified verification')
argparser.add_argument('--include', action='append', type=str, help='include specified verification') argparser.add_argument('--include', action='append', type=str, help='include specified verification')
argparser.add_argument('--token-symbol', default='GFT', type=str, dest='token_symbol', help='Token symbol to use for trnsactions') argparser.add_argument('--token-symbol', default='SRF', type=str, dest='token_symbol', help='Token symbol to use for trnsactions')
argparser.add_argument('-r', '--registry-address', type=str, dest='r', help='CIC Registry address') argparser.add_argument('-r', '--registry-address', type=str, dest='r', help='CIC Registry address')
argparser.add_argument('--env-prefix', default=os.environ.get('CONFINI_ENV_PREFIX'), dest='env_prefix', type=str, help='environment prefix for variables to overwrite configuration') argparser.add_argument('--env-prefix', default=os.environ.get('CONFINI_ENV_PREFIX'), dest='env_prefix', type=str, help='environment prefix for variables to overwrite configuration')
argparser.add_argument('-x', '--exit-on-error', dest='x', action='store_true', help='Halt exection on error') argparser.add_argument('-x', '--exit-on-error', dest='x', action='store_true', help='Halt exection on error')
@@ -186,9 +185,9 @@ def send_ussd_request(address, data_dir):
} }
req = urllib.request.Request(config.get('_USSD_PROVIDER')) req = urllib.request.Request(config.get('_USSD_PROVIDER'))
urlencoded_data = urllib.parse.urlencode(data) data_str = json.dumps(data)
data_bytes = urlencoded_data.encode('utf-8') data_bytes = data_str.encode('utf-8')
req.add_header('Content-Type', 'application/x-www-form-urlencoded') req.add_header('Content-Type', 'application/json')
req.data = data_bytes req.data = data_bytes
response = urllib.request.urlopen(req) response = urllib.request.urlopen(req)
return response.read().decode('utf-8') return response.read().decode('utf-8')
@@ -389,9 +388,10 @@ class Verifier:
def verify_ussd_pins(self, address, balance): def verify_ussd_pins(self, address, balance):
response_data = send_ussd_request(address, self.data_dir) response_data = send_ussd_request(address, self.data_dir)
if response_data[:11] != 'CON Balance' and response_data[:9] != 'CON Salio': if response_data[:11] != 'CON Balance':
raise VerifierError(response_data, 'pins') raise VerifierError(response_data, 'pins')
def verify(self, address, balance, debug_stem=None): def verify(self, address, balance, debug_stem=None):
for k in active_tests: for k in active_tests: