def user_put(userId): request = app.current_request data = request.json_body if 'address' in data: # Find if another user # requestingUser = request.user data['address'] = Web3Helper.toChecksumAddress(data['address']) # user = Database.find_one("User", {'address': data['address']}) # if user and user['id'] != requestingUser['id']: # raise ForbiddenError('user already exists with address {}'.format(data['address'])) user = Database.find_one("User", {'id': int(userId)}) if not user: raise NotFoundError('user not found with id {}'.format(userId)) user = Database.update('User', {'id': user['id']}, data, return_updated=True)[0] if 'address' in data: # Set user athorized as investor tx = Web3Helper.transact(permissions_contract, 'setAuthorized', data['address'], 1) return toObject( user, ['id', 'name', 'address', 'role', 'ik', 'spk', 'signature'])
def feeTaken(): request = app.current_request data = request.json_body print(data) token = Database.find_one("Token", {"address": data["token"]}) ownerUser = Database.find_one("User", {'address': data["owner"]}) if not ownerUser: raise NotFoundError('user not found with address {}'.format( data["owner"])) value = data['value'] ownerBalance = Database.find_one("TokenBalance", { 'userId': ownerUser['id'], "tokenId": token["id"] }, insert=True) if 'balance' not in ownerBalance: ownerBalance['balance'] = '0' if not ownerBalance['balance']: ownerBalance['balance'] = '0' newOwnerBalance = int(float(ownerBalance['balance'])) + int( float(value)) ownerBalance = Database.update("TokenBalance", {"id": ownerBalance["id"]}, {"balance": newOwnerBalance}, return_updated=True)[0] return {"message": "Fee taken"}
def test_find(self): with patch.dict('os.environ', env): Database.insert("User", {'name': 'tom'}) users = Database.find("User", {'name': 'tom'}) self.assertEqual(len(users), 1) self.assertEqual(users[0]['name'], 'tom')
def truelayer(): request = app.current_request if 'id' not in request.query_params: raise NotFoundError('id') user_id = request.query_params['id'] user = Database.find_one('User', {'id': user_id}) nonce = ''.join( random.choice("qwertyuioplkjhgfdsazxvbnm") for _ in range(10)) Database.update('User', {"id": int(user["id"])}, {"nonce": nonce}) url = TL.get_auth_url(nonce) return Response(body=None, status_code=302, headers={"Location": url})
def trades_delete(tradeId): request = app.current_request data = request.json_body trade = Database.find_one("Trade", {"id": int(tradeId)}) if not trade: raise NotFoundError("trade not found with id {}".format(tradeId)) trade = Database.update("Trade", {"id": int(tradeId)}, {'state': 3}, return_updated=True)[0] # Socket, should be pushing to a message queue of some kind r = passWithoutError(requests.post)(socket_uri + "trade-update", data=toObject(trade)) return toObject(trade)
def tokens_nav_update(): print('\n\n\n\n') request = app.current_request data = request.json_body token = Database.find_one("Token", {"address": data["token"]}) time = data["time"] executionDate = arrow.get(time).format('YYYY-MM-DD') nav = Database.insert("NAVTimestamp", { "tokenId": token['id'], "price": data['value'], "executionDate": executionDate }, return_inserted=True) # First need to collect the trades print(token['id']) trades = Database.find("Trade", {"state": 1, "tokenId": token["id"]}) print(trades) # Need to go through each trade and get the NAV+price supplyUpdate = 0 for trade in trades: decryptedNominalAmount = Cryptor.decryptInput( trade['nominalAmount'], trade['sk']) amountInvested = int(decryptedNominalAmount.split(':')[1]) price = Cryptor.decryptInput(trade['price'], trade['sk']) price = float(price) print("amountInvested: ", amountInvested) print("price: ", price) effectiveNAV = (1.0 + float(price) / 100) * nav['price'] print("supplyUpdate", int(amountInvested * 1.0 / effectiveNAV)) # supplyUpdate += int(amountInvested * math.pow(10, token['decimals']) / nav['price']) supplyUpdate += int(amountInvested * math.pow(10, token['decimals']) / effectiveNAV) tokenContract = Web3Helper.getContract("ETT.json", token['address']) # Update trades to be ready for claiming tradeQuery = [[('id', '=', t['id'])] for t in trades] trades = Database.update("Trade", tradeQuery, {'state': 4}, return_updated=True) for trade in trades: # Take funds takeFunds(trade) tx = Web3Helper.transact( tokenContract, 'updateTotalSupply', supplyUpdate, '', # we are ignoring this for now executionDate) # tx = b'' print(tx.hex()) return toObject(nav)
def getBalance(tokenId, user): token = Database.find_one("Token", {"id": int(tokenId)}) if not token: raise NotFoundError("token not found with id {}".format(tokenId)) tokenBalance = Database.find_one("TokenBalance", { "tokenId": int(tokenId), "userId": user["id"] }, insert=True) tokenBalance['token'] = toObject(token) return tokenBalance
def getBalances(tokenId): token = Database.find_one("Token", {"id": int(tokenId)}) if not token: raise NotFoundError("token not found with id {}".format(tokenId)) tokenBalances = Database.find("TokenBalance", {"tokenId": token["id"]}) for tokenBalance in tokenBalances: investor = Database.find_one( "User", {"id": tokenBalance["userId"]}, ["id", "name", "type", "juristiction", "address"]) tokenBalance["investor"] = investor tokenBalance["token"] = toObject(token) return tokenBalances
def trades_post(): request = app.current_request data = request.json_body tradeData = { "investorId": data["investorId"], "tokenId": data["tokenId"], "executionDate": data["executionDate"], "expirationTimestampInSec": data["expirationTimestampInSec"], "salt": data["salt"] } trade = Database.find_one("Trade", tradeData) if trade: return toObject(trade) tradeData['state'] = 0 Database.insert("Trade", tradeData) trade = Database.find_one("Trade", tradeData) data['id'] = trade['id'] for brokerId, ik, ek, nominalAmount in zip(data['brokers'],data['iks'],data['eks'],data['nominalAmounts']): tradeBrokerData = {"tradeId": trade['id'],"brokerId": brokerId, "ik": ik, "ek": ek, "nominalAmount": nominalAmount} tradeBroker = Database.find_one("TradeBroker", tradeBrokerData) if tradeBroker: continue tradeBrokerData['state'] = 0 Database.insert("TradeBroker", tradeBrokerData) tradeBroker = Database.find_one("TradeBroker", tradeBrokerData) # Socket, should be pushing to a message queue of some kind r = passWithoutError(requests.post)(socket_uri + "trade-created", data=data) return toObject(trade)
def trades_show(tradeId): request = app.current_request data = request.json_body trade = Database.find_one("Trade", {"id": int(tradeId)}) if not trade: raise NotFoundError("trade not found with id {}".format(tradeId)) tradeBroker = Database.find_one("TradeBroker", { "tradeId": trade["id"], "brokerId": request.user["id"] }) if not tradeBroker: raise NotFoundError("tradeBroker not found with trade id {}".format(tradeId)) Database.update("TradeBroker", {"id": tradeBroker["id"]}, {"price": data["price"]}) # Socket, should be pushing to a message queue of some kind r = passWithoutError(requests.post)(socket_uri + "trade-update", data=toObject(trade)) return toObject(trade)
def users_get(): request = app.current_request users = None query_params = request.query_params or {} if 'role' in query_params: role = query_params['role'] users = Database.find("User", {'role': role}) users = [u for u in users if u['ik']] else: users = Database.find("User") users = [ toObject( u, ['id', 'name', 'address', 'role', 'ik', 'spk', 'signature']) for u in users ] return users
def auth_login(): request = app.current_request data = request.json_body email = data['email'] password = data['password'] user = Database.find_one("User", {'email': email}) if not user: raise NotFoundError('user not found with email {}'.format(email)) if not pbkdf2_sha256.verify(password, user['password']): raise ForbiddenError('Wrong password') token = jwt.encode(toObject(user, [ 'id', 'name', 'email', 'address', 'role', 'ik', 'spk', 'signature', 'truelayerAccountId' ]), secret, algorithm='HS256') return { 'user': toObject(user, [ 'id', 'name', 'email', 'address', 'role', 'ik', 'spk', 'signature', 'truelayerAccountId' ]), 'token': token.decode("utf-8") }
def getTokenHoldings(tokenId): token = Database.find_one("Token", {"id": int(tokenId)}) if not token: raise NotFoundError("token not found with id {}".format(tokenId)) tokenHoldings = Database.find_one("TokenHoldings", {"tokenId": token["id"]}, order_by='-createdAt') tokenHoldingsList = Database.find("TokenHolding", {"tokenHoldingsId": tokenHoldings["id"]}) for tokenHolding in tokenHoldingsList: tokenHolding['security'] = toObject( Database.find_one('Security', {'id': tokenHolding["securityId"]})) tokenHolding['securityTimestamp'] = toObject( Database.find_one('SecurityTimestamp', {'securityId': tokenHolding["securityId"]}, order_by='-createdAt')) return tokenHoldingsList
def user_get(userId): request = app.current_request user = Database.find_one("User", {'id': int(userId)}) if not user: raise NotFoundError('user not found with id {}'.format(userId)) user['bankConnected'] = not not user['truelayerAccessToken'] user = refresh_user_token(user) accounts = TL.get_accounts(user) return toObject(accounts)
def truelayer_callback(): request = app.current_request code = request.query_params['code'] nonce = request.query_params['state'] user = Database.find_one("User", {'nonce': nonce}) if not user: raise NotFoundError('user not found') user = Database.update('User', {"id": user["id"]}, TL.get_access_token(user, code), return_updated=True)[0] accounts = TL.get_accounts(user) if not len(accounts): raise NotFoundError('No accounts found for user') # update the permissions contract # Web3Helper.transact(permissions_contract,'setAuthorized',Web3Helper.toChecksumAddress(user['address']),1) return Response( body=None, status_code=302, headers={"Location": "{}investor/profile".format(front_end_url)})
def test_update_multiple_with_or(self): with patch.dict('os.environ', env): Database.insert("User", {'name': 'tom'}) Database.insert("User", {'name': 'tom2'}) Database.update("User", [[('name','=','tom')],[('name','=','tom2')]], {'name': 'tom3'}) user = Database.find_one("User", {'name': 'tom'}) self.assertEqual(user, None) user = Database.find_one("User", {'name': 'tom2'}) self.assertEqual(user, None) users = Database.find("User", {'name': 'tom3'}) self.assertEqual(len(users), 2) self.assertEqual(users[0]['name'], 'tom3') self.assertEqual(users[1]['name'], 'tom3')
def getInvested(tokenId, user): token = Database.find_one("Token", {"id": int(tokenId)}) if not token: raise NotFoundError("token not found with id {}".format(tokenId)) # Need to find all the trades this investor invested in claimedTrades = Database.find("Trade", { "tokenId": token["id"], "investorId": user["id"], "state": 6 }) totalAmount = 0 for trade in claimedTrades: decrypted = Cryptor.decryptInput(trade['nominalAmount'], trade['sk']) # I'll need to include the currency here amountInvested = int(decrypted.split(':')[1]) print(amountInvested) totalAmount += amountInvested return totalAmount
def checkKyc(address): user = Database.find_one("User", {'address': address}) if not user: raise NotFoundError( 'user not found with address {}'.format(address)) user = refresh_user_token(user) accounts = TL.get_accounts(user) if not (len(accounts)): raise ForbiddenError('Not KYC') else: return {'message': 'Is KYC', 'status': 200}
def user_get(userId): request = app.current_request user = Database.find_one("User", {'id': int(userId)}) if not user: raise NotFoundError('user not found with id {}'.format(userId)) user['bankConnected'] = not not user['truelayerAccessToken'] return toObject(user, [ 'id', 'name', 'address', 'role', 'ik', 'spk', 'signature', 'bankConnected', 'identity', 'juristiction' 'addressLine1', 'addressLine2', 'city', 'postcode', 'country', 'truelayerAccountId' ])
def balanceTotalSupply(): request = app.current_request data = request.json_body token = Database.find_one("Token", {"address": data["token"]}) if not token: raise NotFoundError('token not found with address {}'.format( data["token"])) print(data) Database.update("Token", {"id": token["id"]}, {"totalSupply": data["newTotalSupply"]}) user = Database.find_one("User", {'address': data["owner"]}) if not user: raise NotFoundError('user not found with address {}'.format( data["owner"])) userBalance = Database.find_one("TokenBalance", { 'userId': user['id'], "tokenId": token["id"] }, insert=True) if 'balance' not in userBalance: userBalance['balance'] = '0' if not userBalance['balance']: userBalance['balance'] = '0' newBalance = int(float(userBalance['balance'])) + int( float(data["newTotalSupply"])) - int(float(data["oldTotalSupply"])) userBalance = Database.update("TokenBalance", {"id": userBalance["id"]}, {"balance": newBalance}, return_updated=True)[0] return toObject(userBalance)
def auth_signup(): request = app.current_request data = request.json_body email = data['email'] name = data['name'] password = data['password'] # addressLine1 = data['addressLine1'] # addressLine2 = data['addressLine2'] # city = data['city'] # postcode = data['postcode'] # country = data['country'] # juristiction = data['juristiction'] print(data) role = data['role'] if 'role' in data else 'investor' user = Database.find_one("User", {'email': email}) if not user: password_hash = pbkdf2_sha256.hash(password) user = Database.insert( "User", { 'name': name, 'email': email, 'password': password_hash, 'role': role, # 'addressLine1': addressLine1, # 'addressLine2': addressLine2, # 'city': city, # 'postcode': postcode, # 'country': country, # 'juristiction': juristiction, 'type': 'institutional', }, return_inserted=True) return toObject(user, [ 'id', 'name', 'address', 'role', 'ik', 'spk', 'signature', 'truelayerAccountId' ])
def funds_post(): request = app.current_request data = request.json_body owner = None ownerId = data["ownerId"] if "ownerId" in data else None if not ownerId: owner = Database.find_one("User", {"address": Web3Helper.account()}) ownerId = owner["id"] else: owner = Database.find_one("User", {"id": ownerId}) if not owner: raise NotFoundError('No user found') fund_data = { "name": data["name"], "ownerId": ownerId } fund = Database.find_one('Fund', fund_data, insert=True) for token in data["tokens"]: token_data = { "name": data["name"], "fundId": fund["id"], "decimals": token["decimals"], "symbol": token["symbol"], "cutoffTime": int(token["cutoffTime"]), "fee": int(token["fee"]), "ownerId": ownerId, "currency": token["currency"], "initialAmount": token["initialAmount"], "incomeCategory": token["incomeCategory"], "minimumOrder": token["minimumOrder"] } if "nav" in token: token_data["nav"] = token['nav'] if "holdings" in token: token_data["holdings"] = token["holdings"] token = createToken(token_data) return toObject(fund)
def balanceTransfer(): request = app.current_request data = request.json_body print("\n\nbalanceTransfer\n\n") print(data) print("\n\nbalanceTransfer\n\n") token = Database.find_one("Token", {"address": data["token"]}) fromUser = Database.find_one("User", {'address': data["from"]}) if not fromUser: raise NotFoundError('user not found with address {}'.format( data["from"])) toUser = Database.find_one("User", {'address': data["to"]}) if not toUser: raise NotFoundError('user not found with address {}'.format( data["to"])) value = data['value'] fromBalance = Database.find_one("TokenBalance", { 'userId': fromUser['id'], "tokenId": token["id"] }, for_update=True) # If there is no from balance this transfer cannot be valid if not fromBalance: raise NotFoundError('token balance not found for user {}'.format( fromUser['id'])) # Check does the user have enough balance print("fromBalanceYo: ", fromBalance) if ('balance' not in fromBalance or not fromBalance['balance'] or int(fromBalance['balance']) < int(value)): raise NotFoundError('token balance not enough for user {}'.format( fromUser['id'])) newFromBalance = int(float(fromBalance['balance'])) - int(float(value)) fromBalance = Database.update("TokenBalance", {"id": fromBalance["id"]}, {"balance": newFromBalance}, return_updated=True)[0] toBalance = Database.find_one("TokenBalance", { 'userId': toUser['id'], "tokenId": token["id"] }, insert=True, for_update=True) if 'balance' not in toBalance: toBalance['balance'] = '0' if not toBalance['balance']: toBalance['balance'] = '0' newToBalance = int(float(toBalance['balance'])) + int(float(value)) toBalance = Database.update("TokenBalance", {"id": toBalance["id"]}, {"balance": newToBalance}, return_updated=True)[0] return {"message": "Funds transferred"}
def fund_balances(fundId): request = app.current_request fund = Database.find_one("Fund", {"id": int(fundId)}) if not fund: raise NotFoundError("fund not found with id {}".format(fundId)) tokens = Database.find("Token", {"fundId": fund["id"]}) token_balances = [] for token in tokens: token_balances += getBalances(token["id"]) user_hash = {} total_balance = [] for token_balance in token_balances: if not token_balance['balance']: continue id = token_balance['investor']['id'] if id in user_hash: total_balance[user_hash[id]]['balance'] = int(total_balance[user_hash[id]]['balance']) total_balance[user_hash[id]]['balance'] += int(token_balance['balance']) total_balance[user_hash[id]]['balance'] = str(total_balance[user_hash[id]]['balance']) else: index = len(total_balance) user_hash[id] = index total_balance.append(token_balance) return toObject(total_balance)
def trades_claim(tradeId): trade = Database.find_one("Trade", {"id": int(tradeId)}) decrypted = Cryptor.decryptInput(trade['nominalAmount'], trade['sk']) price = Cryptor.decryptInput(trade['price'], trade['sk']) # Ill need to include the currency here amountInvested = int(decrypted.split(':')[1]) if trade['state'] != 5: return {'message': 'Trade is in state {}, requires state 5'.format(trade['state'])} # get trade dates nav nav = Database.find_one("NAVTimestamp", {"tokenId": trade["tokenId"]}, order_by='-createdAt') # get todays nav and totalSupply token = Database.find_one('Token', {'id': trade['tokenId']}) totalTokens = int(amountInvested / nav['price']) investorTokens = None if amountInvested > 0: effectiveNAV = (1.0+float(price)/100)*nav['price'] investorTokens = amountInvested / effectiveNAV else: investorTokenBalance = Database.find_one("TokenBalance", {"tokenId": token["id"], "userId": investor["id"]}) if not investorTokenBalance['balance']: investorTokenBalance['balance'] = '0' effectiveNAV = (1-float(price)/100)*nav['price'] investorTokens = min(int(amountInvested / effectiveNAV), -1 * int(investorTokenBalance['balance'])) tokenContract = Web3Helper.getContract("ETT.json", token['address']) totalSupply = Web3Helper.call(tokenContract,'dateTotalSupply',arrow.get(trade['executionDate']).format('YYYY-MM-DD'),) # find number of tokens user allocated numberTokens = 0 if not nav['price'] else math.floor(amountInvested * totalSupply / nav['price']) investorTokens = int(investorTokens * math.pow(10, token['decimals'])) # now ask the contract to distribute the tokens (maybe should be the investor that does this) investor = Database.find_one("User", {"id": trade["investorId"]}) tradeKernelContract = Web3Helper.getContract("TradeKernel.json") tx = Web3Helper.transact( tradeKernelContract, 'distributeTokens', trade['hash'], [ Web3Helper.toChecksumAddress(token['address']), Web3Helper.toChecksumAddress(investor['address']), ], [ investorTokens ] ) print(tx.hex()) Database.update("Trade", {"id": trade["id"]}, {"state": 6, "numberTokens": numberTokens}) return {"message": "Tokens distributed"}
def test_update(self): with patch.dict('os.environ', env): Database.insert("User", {'name': 'tom'}) Database.update("User", [[('name','=','tom')]], {'name': 'tom2'}) user = Database.find_one("User", {'name': 'tom'}) self.assertEqual(user, None) user = Database.find_one("User", {'name': 'tom2'}) self.assertEqual(user['name'], 'tom2')
def orders_show(orderId): order = Database.find_one("Order", {"id": orderId}) order["broker"] = Database.find_one("User", {"id": order["brokerId"]}, ['id','name','email','address']) order["token"] = toObject(Database.find_one("Token", {"id": order["tokenId"]})) order["orderHoldings"] = Database.find("OrderHolding", {"orderId": order["id"]}) for orderHolding in order["orderHoldings"]: orderHolding["security"] = toObject(Database.find_one("Security", {"id": orderHolding["securityId"]})) order["orderTrades"] = Database.find("OrderTrade", {"orderId": order["id"]}) for orderTrade in order["orderTrades"]: orderTrade["trade"] = toObject(Database.find_one("Trade", {"id": orderTrade["tradeId"]})) return toObject(order)
def orders_get(): request = app.current_request query = request.query_params or {} single = False orders = [] total = None if 'page' in query: page = int(query['page']) del query['page'] if 'page_count' in query: page_count = int(query['page_count']) del query['page_count'] if 'single' in query: del query['single'] single = True order = Database.find_one("Order", query) if not order: raise NotFoundError("No order found") orders = [order] else: dbRes = Database.find("Order", query, page=page, page_count=page_count) orders = dbRes['data'] total = dbRes['total'] for order in orders: order["broker"] = Database.find_one("User", {"id": order["brokerId"]}, ['id','name','email','address']) order["token"] = toObject(Database.find_one("Token", {"id": order["tokenId"]})) order["orderHoldings"] = Database.find("OrderHolding", {"orderId": order["id"]}) for orderHolding in order["orderHoldings"]: orderHolding["security"] = toObject(Database.find_one("Security", {"id": orderHolding["securityId"]})) order["orderTrades"] = Database.find("OrderTrade", {"orderId": order["id"]}) for orderTrade in order["orderTrades"]: orderTrade["trade"] = toObject(Database.find_one("Trade", {"id": orderTrade["tradeId"]})) if single: return toObject(orders[0]) return {"data": toObject(orders), "total": total}
def token_post_dividend(tokenId): request = app.current_request user = request.user data = request.json_body amount = data["amount"] currency = data["currency"] paymentDate = data["paymentDate"] exDividendDate = data["exDividendDate"] dividend = { "amount": amount, "tokenId": tokenId, "currency": currency, "paymentDate": paymentDate, "exDividendDate": exDividendDate } dividend = Database.insert("Dividend", dividend, return_inserted=True) return toObject(dividend)
def checkBalance(address): request = app.current_request amount = int(request.query_params['amount']) user = Database.find_one("User", {'address': Web3.toChecksumAddress(address)}) if not user: raise NotFoundError( 'user not found with address {}'.format(address)) user = refresh_user_token(user) balance = TL.get_balance(user) balance_small = int(balance['available'] * 100) if (balance_small < amount): raise ForbiddenError('Not enough funds') else: return {'message': 'Has funds', 'status': 200}