async def submit_empty_asset(app, requester, claimed=False): """ claimed : False, Which means this account hasnt been claimed, it doesnt have a orgnization_account Implies that create_asset_idxs array of float account will be appended with key_index rather the orgnization acount create_asset_idxs float_accounts cannot create assets, but any other orgnization who have been claimed can force float_account to create empty asset, thats why for create_asset claimed will be always True. Now empty asset can be created by any account, Child, orgnization or float_account Child account for float_account can't exists """ f = await userapis.SolveAccount(requester, app) decrypted_mnemonic = f.decrypted_mnemonic org_db_entry = f.org_db logging.info(f"THis is the decrypted mnemonic {decrypted_mnemonic}") create_asset_idxs = f.org_state.get("create_asset_idxs") child_zero_pub = f.child_zero_pub child_user_id = f.child_user_id zero_pub = f.zero_pub if not claimed: ##these are required so that create_asset_idxs of float account ##can be apended with key_index flt_account_parent_pub = requester[ "parent_pub"] #exists both in users_table flt_account_parent_idx = requester["parent_idx"] else: flt_account_parent_pub = None #exists both in users_table flt_account_parent_idx = None key_index = await ledger_utils.generate_key_index(array=create_asset_idxs) nth_keys = await remote_calls.key_index_keys(app, decrypted_mnemonic, [key_index]) nth_priv, nth_pub = nth_keys[str(key_index)]["private_key"], \ nth_keys[str(key_index)]["public_key"] key = encrypted_key = s3_url = encrypted_s3_url = None master_key = master_url = None ##the transaction will be signed by users nth private key create_asset_signer = ledger_utils.create_signer(nth_priv) ##we havent included the child_nth_pub in this transaction because it ## can be calculated from txn_key on the processor side asset_address = addresser.create_asset_address(asset_id=nth_pub, index=key_index) transaction_data = { "config": app.config, "txn_key": create_asset_signer, "batch_key": app.config.SIGNER, "key": None, "url": None, "time": int(time.time()), "indiantime": upload_utils.indian_time_stamp(), "file_name": None, "file_hash": None, "idx": key_index, "master_key": None, "master_url": None, "scope": None, "role": requester["role"], "zero_pub": zero_pub, "is_acc_claimed": claimed, "flt_account_parent_pub": flt_account_parent_pub, "flt_account_parent_idx": flt_account_parent_idx, "child_zero_pub": child_zero_pub, } logging.info(f"THis is the transaction data {transaction_data}") transaction_ids, batch_id = await send_create_asset(**transaction_data) if batch_id: [ transaction_data.pop(field) for field in [ "config", "txn_key", "batch_key", "is_acc_claimed", "flt_account_parent_pub", "flt_account_parent_idx" ] ] transaction_data.update({ "user_id": requester["user_id"], "public": nth_pub, "transaction_id": transaction_ids[0], "batch_id": batch_id, "asset_address": asset_address, "child_zero_pub": child_zero_pub }) await assets_query.store_assets(app, transaction_data) if claimed: await accounts_query.update_create_asst_idxs( app, org_db_entry["user_id"], key_index) else: logging.error("Must be a float account") await accounts_query.update_create_asst_idxs_pending( app, org_db_entry["user_id"], key_index) if child_user_id: await accounts_query.update_create_asst_idxs( app, child_user_id, key_index) #await accounts_query.update_create_asst_idxs_pending(app, #requester["user_id"], key_index) return nth_priv, nth_pub, key_index, asset_address else: logging.error("Create asset Faied, GO to hell Dude!!!!,\ Kabhi kabhi lagta hai ki bhagwan hone ka bhi kya fayda") return
async def submit_create_asset(app, requester, file_data): """ Creates an empty asset or asset with data, Process: Get user Mnemonic If user is child, then get the mnemonic of the parent orgnization This can be done by getting by fetching org account present on the blokchchain constructing org_address from child["parent_pub"] Checks: 1.check if child is actually a valid child by checking if child parent_idx is in org_account["child_account_idxs"] 2. Check child org_name is same is orgnization org_name Fecth org entry in the dabase corresponding to the user_id of the org in orgnization entry on blokchchain NOw decrypt the org menmonic with Admin public key if org is not admin Now, get the create_asset_idxs array of the organization from the blockchain if requester is orgnization: Fecth org entry in the dabase corresponding to the user_id of the org in orgnization entry on blokchchain NOw decrypt the org menmonic with Admin public key if org is not admin Now, get the create_asset_idxs array of the organization from the blockchain A new key_index will be generated at create_asset_idxs, From the decrypted_nemonic, Public/Private key pair will be generated at this key_index, this will be a asset_address NOw, Check if file_Data is there or not, if yes, Encrypt the file data with random AES key, and post it on S3, Now encrypt both AES key and s3_url with the public key generated at random index Now there are two main conditions which needs attention, The user who still dont have an orgnization account but only a float_account In this case, is_claimed "flt_account_parent_pub": requester["parent_pub"], "flt_account_parent_idx": requester["parent_idx"], THese are required because since this is a float_account, on the processor side, the key_index will be appended to float_account which will be calculated from these two keys Th user does have an orgnization account The user whom is floating this transaction if claimed=False, user havent claimed his/her account if claimed=False, the requester["role"] cant be child, as float accounts arent allowed to create child roles, ADMIN doesnt have float accounts "flt_account_parent_pub": None, "flt_account_parent_idx": None, THese keys are required if the account is float_account, Now since this orgnization doesnt have any real account or the account has not been claimed, the create_asset_idxs will be appended to create_asset_idxs of float account Now since float account can not create new assets, only assets being transffered to them, Float account cannot run this function as credentials of float account are debarred from accessing this api or this function so, only CHILD, AQDMIN or any other orgnixzation who already have alimed their account can access this API, which means they have orgnization account, which means key_index will be appende to their orgnization account not float_account_idxs, Hence these two keys will be none for this function """ logging.info("Enterintosubmitcreateasset") f = await userapis.SolveAccount(requester, app) decrypted_mnemonic = f.decrypted_mnemonic org_state = f.org_state logging.info(f"THis is the decrypted mnemonic {decrypted_mnemonic}") create_asset_idxs = f.org_state.get("create_asset_idxs") child_zero_pub = f.child_zero_pub child_user_id = f.child_user_id zero_pub = f.zero_pub flt_account_parent_pub = None #exists both in users_table flt_account_parent_idx = None ##generate a new random index key which is not present in the ## create_asset_idxs key_index = await ledger_utils.generate_key_index(array=create_asset_idxs) logging.info(f"User key index create_asset_idxs for user {key_index}") ##retrieve pub/priv key pair corresponding to the random index just ##generated nth_keys = await remote_calls.key_index_keys(app, decrypted_mnemonic, [key_index]) nth_priv, nth_pub = nth_keys[str(key_index)]["private_key"], \ nth_keys[str(key_index)]["public_key"] ## all the data being encrypted with user nth public key key, encrypted_key, s3_url, encrypted_s3_url = \ await asset_utils.encrypt_file_data(requester["user_id"], nth_pub, app.config, file_data) master_key, master_url = await asset_utils.master_url_n_key( app.config.ADMIN_ZERO_PUB, key, s3_url) ##the transaction will be signed by users nth private key create_asset_signer = ledger_utils.create_signer(nth_priv) ##we havent included the child_nth_pub in this transaction because it ## can be calculated from txn_key on the processor side asset_address = addresser.create_asset_address(asset_id=nth_pub, index=key_index) transaction_data = { "config": app.config, "txn_key": create_asset_signer, "batch_key": app.config.SIGNER, "key": encrypted_key, "url": encrypted_s3_url, "time": int(time.time()), "indiantime": upload_utils.indian_time_stamp(), "file_name": file_data["file_name"], "file_hash": file_data["file_hash"], "idx": key_index, "master_key": master_key, "master_url": master_url, "role": requester["role"], "scope": file_data["scope"], "zero_pub": zero_pub, "is_acc_claimed": True, "flt_account_parent_pub": None, "flt_account_parent_idx": None, "child_zero_pub": child_zero_pub, } logging.info(f"THis is the transaction data {transaction_data}") transaction_ids, batch_id = await send_create_asset(**transaction_data) if batch_id: logging.info("Create Transaction has been created successfully") ##which imlies the transaction has been submitted successfully, ##now all the changes that are required to be done on the databse can ##be done ##Update users create_asset_idxs key on users entry will be updated by ## whomever will call this, because update can happend on pending_users ## table or users table depending upon user has been claimed or not. ##if transaction was submitted successfully ##Update user entry in the pending_users table of uer_table with the new ##new asset_index in creat_asset_idxs ##insert in asests with new asset created [ transaction_data.pop(field) for field in [ "config", "txn_key", "batch_key", "is_acc_claimed", "flt_account_parent_pub", "flt_account_parent_idx" ] ] transaction_data.update({ "user_id": requester["user_id"], "public": nth_pub, "transaction_id": transaction_ids[0], "batch_id": batch_id, "asset_address": asset_address, "child_zero_pub": child_zero_pub }) ##updating assets table with this new asset await assets_query.store_assets(app, transaction_data) ##updating org_state user_id in users table with new index of asset await accounts_query.update_create_asst_idxs(app, org_state["user_id"], key_index) if child_user_id: ##updating child_user_id user_id in users table with new index of asset await accounts_query.update_create_asst_idxs( app, child_user_id, key_index) #await accounts_query.update_create_asst_idxs_pending(app, #requester["user_id"], key_index) return nth_priv, nth_pub, key_index, asset_address else: logging.error("Create asset Faied, GO to hell Dude!!!!,\ Kabhi kabhi lagta hai ki bhagwan hone ka bhi kya fayda") return
async def submit_share_asset(app, requester, asset_address, receive_asset_address, unique_code, revoked_on, comments): """ 1.check whether asset_address is valid asset address or not 2. check whether the asset is empty or not 3.check whether the asset has been transsefred the ownership to someother empty asset 4.check whether the requester is the owner of this asset or not 5.check whether the receiver_asset_address is a valid receive_asset_address or not 6.check whether at_which_asset_expires is stil valid or hasnt expired 7.cheque whether the sha_2224 hash of unique code matches with receiver_asset """ f = await userapis.SolveAccount(requester, app) decrypted_mnemonic = f.decrypted_mnemonic org_state = f.org_state logging.info(f"THis is the decrypted mnemonic {decrypted_mnemonic}") share_asset_idxs = f.org_state.get("share_asset_idxs") child_user_id = f.child_user_id child_zero_pub = f.child_zero_pub account_zero_pub = f.zero_pub unique_code_hash = hashlib.sha224(str(unique_code).encode()).hexdigest() if await share_assets_query.find_share_asset(app, asset_address, receive_asset_address): raise ApiInternalError("This shared asset has already been done") ##checking point 5 receive_asset_instance = await userapis.SolveAddress( receive_asset_address, app.config.REST_API_URL) if receive_asset_instance.type != "RECEIVE_ASSET": raise AssetError("receive_asset_address is notreceive asset address") if not receive_asset_instance.data[ "at_which_asset_expires"] > upload_utils.now_time_stamp(): raise errors.InvalidValidityPeriod("The time to share asset with this \ address has been expired") if receive_asset_instance.data["unique_code_hash"] !=\ unique_code_hash: raise AssetError( "Unique code provided is either wrong or meant for different receiver_address" ) asset_instance = await userapis.SolveAddress(asset_address, app.config.REST_API_URL) if asset_instance.type != "CREATE_ASSET": raise AssetError("asset_address is not asset address") ##check point 2 if not asset_instance.data["file_name"] or not asset_instance.data[ "file_hash"]: raise AssetError("Empty assets cannot be shared") ##decrypting issuer mnemonic requester_account_address = addresser.create_organization_account_address( account_id=org_state["public"], index=0) ##Check if the asset had been transffered to the issuer i.e issets which were ###not created by the issuer cant be transffered to other users if asset_instance.data.get("ownership_transfer"): message = f"This asset which already have been transffered to \ {issuer_asset.get('ownership_transfer')} can be shared" logging.error(message) raise AssetError(message) key_index = await ledger_utils.generate_key_index(share_asset_idxs) logging.info(f"THis is the key index for issuer {key_index}") ##at which the asset was created asset_index = asset_instance.data["idx"] nth_keys = await remote_calls.key_index_keys(app, decrypted_mnemonic, [0, key_index, asset_index]) ##account kets for the issuer requester_zeroth_priv, requester_zeroth_pub = \ nth_keys[str(0)]["private_key"], \ nth_keys[str(0)]["public_key"] ##keys at which teh asset which needs to be shared was floated create_asset_priv, create_asset_pub = nth_keys[str(asset_index)]["private_key"], \ nth_keys[str(asset_index)]["public_key"] ##keys at which the shared asset index will be floated share_asset_priv, share_asset_pub = nth_keys[str(key_index)]["private_key"], \ nth_keys[str(key_index)]["public_key"] ##check if issuer n th public key is exactly the public key mentioned in the ##asset transaction present on the blockchain, this also checks whether ##the requester is actually the owner of the asset if create_asset_pub != asset_instance.data.get("public"): logging.error("This asset address is not owned by the issuer") raise AssetError("This asset address is not owned by the issuer") ##decrypting file data stored ob the issuer asset address, this can be ##done by issuer private key present on the nth index data = await asset_utils.decrypt_file_data( asset_instance.data["key"], asset_instance.data["url"], asset_instance.data["file_hash"], create_asset_priv) ##TODO: check file_hash file_data = { "data": data, "file_name": asset_instance.data["file_name"], "file_hash": asset_instance.data["file_hash"] } ##encrypting again with the public key present at the receiver_asset_address key, encrypted_key, s3_url, encrypted_s3_url = \ await asset_utils.encrypt_file_data(None, receive_asset_instance.data["public"], app.config, file_data) logging.info(f"This is the key {key} , encrypted_key{encrypted_key} \ and the s3_url {s3_url}") master_key, master_url = await asset_utils.master_url_n_key( app.config.ADMIN_ZERO_PUB, key, s3_url) ##Now this transaction should be signed by user create_asset_signer = ledger_utils.create_signer(share_asset_priv) ##for added security we will send a nonce signed by issuer account ##private key nonce = random.randint(2**20, 2**30) nonce_hash = hashlib.sha224(str(nonce).encode()).hexdigest() account_hex_signature = signatures.ecdsa_signature(requester_zeroth_priv, nonce) ##nonce must also be signed with the private key at random index at which ##create asset is present asset_hex_signature = signatures.ecdsa_signature(create_asset_priv, nonce) transaction_data = { "config": app.config, "txn_key": create_asset_signer, "batch_key": app.config.SIGNER, "key": encrypted_key, "url": encrypted_s3_url, "master_key": master_key, "master_url": master_url, "time": int(time.time()), "indiantime": upload_utils.indian_time_stamp(), "file_name": asset_instance.data["file_name"], "file_hash": asset_instance.data["file_hash"], "original_asset_address": asset_address, "revoked_on": revoked_on, "comments": comments, "idx": key_index, "account_signature": account_hex_signature, "asset_signature": asset_hex_signature, "nonce": nonce, "nonce_hash": nonce_hash, "to_org_name": receive_asset_instance.data["org_name"], "to_org_address": receive_asset_instance.data["org_address"], "issuer_account_address": requester_account_address, "receive_asset_address": receive_asset_address, "child_zero_pub": child_zero_pub, "unique_code_hash": unique_code_hash, } transaction_ids, batch_id = await send_share_asset(**transaction_data) if transaction_ids: logging.info("Share Transaction has been created successfully") ##which imlies the transaction has been submitted successfully, ##now all the changes that are required to be done on the databse can ##be done ##Update users create_asset_idxs key on users entry will be updated by ## whomever will call this, because update can happend on pending_users share_asset_address = addresser.share_asset_address( share_asset_pub, key_index) account_signature = account_hex_signature.decode() asset_signature = asset_hex_signature.decode() transaction_data.update({ "transaction_id": transaction_ids[0], "batch_id": batch_id, "account_signature": account_signature, "asset_signature": asset_signature, "address": share_asset_address }) [ transaction_data.pop(field) for field in ["config", "txn_key", "batch_key"] ] await share_assets_query.store_share_asset(app, transaction_data) ##now asset must be update with share_with key await assets_query.update_issuer_asset_shared(app, asset_address, key_index) ##TOFO update receiver_address asset and issuer_asset_Address in DB await accounts_query.update_share_asset_idxs(app, org_state["user_id"], key_index) if child_user_id: await accounts_query.update_share_asset_idxs( app, child_user_id, key_index) return share_asset_address else: return False return
async def submit_receive_asset(app, requester, _id_, name, description, at_which_asset_expires): """ """ f = await userapis.SolveAccount(requester, app) decrypted_mnemonic = f.decrypted_mnemonic logging.info(f"THis is the decrypted mnemonic {decrypted_mnemonic}") org_db_entry = f.org_db receive_asset_idxs = f.org_state.get("receive_asset_idxs") child_user_id = f.child_user_id child_zero_pub = f.child_zero_pub account_zero_pub = f.zero_pub key_index = await ledger_utils.generate_key_index(array=receive_asset_idxs) nth_keys = await remote_calls.key_index_keys(app, decrypted_mnemonic, [key_index, 0]) nth_priv, nth_pub = nth_keys[str(key_index)]["private_key"], \ nth_keys[str(key_index)]["public_key"] org_priv, org_pub = nth_keys[str(0)]["private_key"], \ nth_keys[str(0)]["public_key"] org_account_address = addresser.create_organization_account_address( account_id=account_zero_pub, index=0) instance = await userapis.SolveAddress(org_account_address, app.config.REST_API_URL) org_state = instance.data ##the transaction will be signed by users nth private key create_asset_signer = ledger_utils.create_signer(nth_priv) ##we havent included the child_nth_pub in this transaction because it ## can be calculated from txn_key on the processor side ##for added security we will send a nonce signed by issuer account ##private key nonce = random.randint(2**20, 2**30) nonce_hash = hashlib.sha224(str(nonce).encode()).hexdigest() ##nonce signed by zerothprivate key and in hex format hex_signatures = signatures.ecdsa_signature(org_priv, nonce) receive_asset_address = addresser.receive_asset_address(asset_id=nth_pub, index=key_index) unique_code = int("".join(map(str, random.choices(list(range(1, 10)), k=5)))) unique_code_hash = hashlib.sha224(str(unique_code).encode()).hexdigest() encrypted_unique_code = encryption_utils.encrypt_w_pubkey( str(unique_code).encode(), nth_pub) encrypted_admin_unique_code = encryption_utils.encrypt_w_pubkey( str(unique_code).encode(), app.config.ADMIN_ZERO_PUB) transaction_data = { "config": app.config, "txn_key": create_asset_signer, "batch_key": app.config.SIGNER, "_id_": _id_, "time": int(time.time()), "indiantime": upload_utils.indian_time_stamp(), "idx": key_index, "at_which_asset_expires": at_which_asset_expires, "org_name": org_state["org_name"], "org_address": org_account_address, "org_zero_pub": org_pub, "org_role": org_state["role"], "receive_asset_details": { "name": name, "description": description }, "child_zero_pub": child_zero_pub, "signed_nonce": hex_signatures, "nonce": nonce, "nonce_hash": nonce_hash, "unique_code_hash": unique_code_hash, "encrypted_unique_code": encrypted_unique_code, "encrypted_admin_unique_code": encrypted_admin_unique_code } logging.info(f"THis is the transaction data in receive_asset") logging.info(pprint(transaction_data)) transaction_ids, batch_id = await send_receive_asset(**transaction_data) if batch_id: [ transaction_data.pop(field) for field in ["config", "txn_key", "batch_key"] ] signed_nonce = transaction_data["signed_nonce"].decode() transaction_data.update({ "user_id": requester["user_id"], "public": nth_pub, "transaction_id": transaction_ids[0], "batch_id": batch_id, "signed_nonce": signed_nonce, "unique_code": unique_code }) await receive_assets_query.store_receive_assets(app, transaction_data) await accounts_query.update_receive_assets_idxs( app, org_db_entry["user_id"], key_index) ##if this receive_asset is created by child of the organization ##then update the child account receive_asset_idxs array also if child_user_id: await accounts_query.update_receive_assets_idxs( app, child_user_id, key_index) #await accounts_query.update_create_asst_idxs_pending(app, #requester["user_id"], key_index) return nth_pub, key_index, receive_asset_address else: logging.error("Create asset Faied, GO to hell Dude!!!!,\ Kabhi kabhi lagta hai ki bhagwan hone ka bhi kya fayda") return
async def submit_transfer_asset(app, requester, issuer_address, receiver_address, expired_on): ##decrypting issuer mnemonic logging.info("Enter into Transfer asset") f = await userapis.SolveAccount(requester, app) decrypted_mnemonic = f.decrypted_mnemonic logging.info(f"Requester Mnemonic is {decrypted_mnemonic}") instance = await userapis.SolveAddress(issuer_address, app.config.REST_API_URL) ##getting issuer public key and the index at which this asset was created if instance.type != "CREATE_ASSET": raise AssetError("Not a valid issuer address") issuer_asset = instance.data issuer_asset_public_key, issuer_asset_idx = \ issuer_asset["public"], issuer_asset["idx"] instance = await userapis.SolveAddress(receiver_address, app.config.REST_API_URL) if instance.type != "CREATE_ASSET": raise AssetError("Not a valid receiver address") receiver_asset = instance.data logging.info(f"Deserialized receiver asset <<{issuer_asset}>>") ##checking is issuer asset is empty or not, empty assets cant be transffered if not issuer_asset["file_name"] or not issuer_asset["file_hash"]: logging.error("Empty assets cannot be transffered") raise AssetError("Empty assets cannot be transffered") ##Check if the asset had been transffered to the issuer i.e issets which were ###not created by the issuer cant be transffered to other users if issuer_asset.get("ownership_received"): message = f"This asset is not owned by the user but \ received from {issuer_asset['parent_address']}" logging.error(message) raise AssetError(message) ##checking if receiver_asset is empty or not, non empty assets couldnt receive ##assets if receiver_asset.get("file_name") or receiver_asset.get("file_hash"): logging.error("Non empty assets cannot be a receiver") raise AssetError("Non empty assets cannot be a receiver") ##get issuer keys from the GOAPI_URL, private key corresponding to the ##random index public key at which the asset was floated issuer_keys = await remote_calls.key_index_keys(app, decrypted_mnemonic, [issuer_asset_idx, 0]) issuer_zeroth_priv, issuer_zeroth_pub = \ issuer_keys[str(0)]["private_key"], \ issuer_keys[str(0)]["public_key"] issuer_nth_priv, issuer_nth_pub = issuer_keys[str(issuer_asset_idx)]["private_key"], \ issuer_keys[str(issuer_asset_idx)]["public_key"] ##check if issuer n th public key is exactly the public key mentioned in the ##asset transaction present on the blockchain, this also checks whether ##the requester is actually the owner of the asset if issuer_nth_pub != issuer_asset_public_key: logging.error("This asset address is not owned by the issuer") raise AssetError("This asset address is not owned by the issuer") ##decrypting file data stored ob the issuer asset address, this can be ##done by issuer private key present on the nth index data = await asset_utils.decrypt_file_data(issuer_asset["key"], issuer_asset["url"], issuer_asset["file_hash"], issuer_nth_priv) ##TODO: check file_hash file_data = { "data": data, "file_name": issuer_asset["file_name"], "file_hash": issuer_asset["file_hash"] } ##encrypting again with the public key present at the receiver_asset_address key, encrypted_key, s3_url, encrypted_s3_url = \ await asset_utils.encrypt_file_data(None, receiver_asset["public"], app.config, file_data) logging.info(f"This is the key {key} , encrypted_key{encrypted_key} \ and the s3_url {s3_url}") master_key, master_url = await asset_utils.master_url_n_key( app.config.ADMIN_ZERO_PUB, key, s3_url) ##Now this transaction should be signed by user create_asset_signer = ledger_utils.create_signer(issuer_nth_priv) ##for added security we will send a nonce signed by issuer account ##private key nonce = random.randint(2**20, 2**30) ##nonce signed by zerothprivate key and in hex format hex_signatures = signatures.ecdsa_signature(issuer_zeroth_priv, nonce) transaction_data = { "config": app.config, "txn_key": create_asset_signer, "batch_key": app.config.SIGNER, "key": encrypted_key, "url": encrypted_s3_url, "time": int(time.time()), "indiantime": upload_utils.indian_time_stamp(), "file_name": issuer_asset["file_name"], "file_hash": issuer_asset["file_hash"], "expired_on": expired_on, "master_key": master_key, "master_url": master_url, "scope": issuer_asset["scope"], "receiver_address": receiver_address, "issuer_address": issuer_address, "issuer_pub": issuer_nth_pub, "issuer_zero_pub": issuer_zeroth_pub, "signed_nonce": hex_signatures, "nonce": nonce, "issuer_child_zero_pub": issuer_asset.get("child_zero_pub"), } logging.info(transaction_data) transaction_ids, batch_id = await send_transfer_asset(**transaction_data) if transaction_ids: ##just because signatures are in bytes signed_nonce = transaction_data["signed_nonce"].decode() logging.info("Create Transaction has been created successfully") ##which imlies the transaction has been submitted successfully, ##now all the changes that are required to be done on the databse can ##be done ##Update users create_asset_idxs key on users entry will be updated by ## whomever will call this, because update can happend on pending_users transaction_data.update({ "transaction_id": transaction_ids[0], "batch_id": batch_id, "signed_nonce": signed_nonce }) [ transaction_data.pop(field) for field in ["config", "txn_key", "batch_key"] ] await transfer_assets_query.store_transfer_assets( app, transaction_data) await assets_query.update_issuer_asset(app, issuer_address, transaction_data) await assets_query.update_receiver_asset(app, receiver_address, transaction_data) ##TOFO update receiver_address asset and issuer_asset_Address in DB return True else: return False return