def handle_error(self, error): msg = "API_ERROR>>>url:%s, method:[%s], data:%s" % ( request.url, request.method, request.form) from models import db db.session.rollback() api_logger.error(msg) api_logger.error(format_exc()) return make_resp(500, False, message="error")
def put(self): """ 站内用户资产划转 :return: """ parse = reqparse.RequestParser() parse.add_argument('coin_name', type=str, required=True, trim=True) parse.add_argument('amount', type=str, required=True) parse.add_argument('to_account', type=str, required=True, trim=True) args = parse.parse_args() coin_name = args.get('coin_name') account_key = g.account_key amount = Decimal(str(args.get('amount'))) to_account = args.get('to_account') api_logger.info( "transfer api, to:%s, amount:%s, account_key:%s, coin_name:%s" % (to_account, amount, account_key, coin_name)) try: user_asset_sender = UserAsset.query.filter_by( account_key=account_key, coin_name=coin_name).with_for_update(read=True).first() user_asset_receiver = UserAsset.query.filter_by( account_key=to_account, coin_name=coin_name).with_for_update(read=True).first() if not user_asset_sender or not user_asset_receiver: api_logger.error("withdrawal,user not found %s" % account_key) return make_resp(404, False, message="用户资产错误") if user_asset_sender.available_asset < amount or user_asset_sender.total_asset < amount: return make_resp(400, False, message="余额不足") user_asset_sender.available_asset -= amount user_asset_sender.total_asset -= amount user_asset_receiver.available += amount user_asset_receiver.total_asset += amount db.session.commit() except Exception as e: api_logger.error("transfer, error %s" % str(e)) db.session.rollback() return make_resp(500, False, message="提现申请提交失败") api_logger.info("transfer api, succeed") return make_resp(200, True)
def get(self): """ 生成用户钱包地址 :return: """ parse = reqparse.RequestParser() parse.add_argument('coin_name', type=str, required=True, trim=True) args = parse.parse_args() account_key = g.account_key coin_name = args.get('coin_name').lower() api_logger.info("generate address, account_key:%s, coin_name:%s" % (account_key, coin_name)) # 检查是否已有地址 bhd_address = PoolAddress.query.filter_by(account_key=account_key, coin_name=coin_name).first() if bhd_address: return make_resp(**bhd_address.to_dict()) # 从节点获取地址 client = get_rpc(coin_name) try: format_address = "" if coin_name != NEWBI_NAME: address, priv_key = client.generate_address(g.user.id) else: priv_key = os.urandom(32).hex() address, format_address = client.generate_address(priv_key) # 插入数据库 bhd_address = PoolAddress(account_key, address, priv_key, coin_name, format_address) db.session.add(bhd_address) db.session.commit() api_logger.info( "wallet address api, insert into wallet_address %s" % bhd_address.to_dict()) except Exception as e: db.session.rollback() api_logger.error("generate address %s " % e) return make_resp(400, False, message="生成地址失败") return make_resp(**bhd_address.to_dict())
def wrapper(*args, **kwargs): token = request.headers.get("token") if token is None: return make_resp(401, False, message="token not found") try: auth_dict = jwt.decode(token, JWT_SECRET, audience='pool') except Exception as e: api_logger.error("auth failed %s" % str(e)) return make_resp(401, False, message="用户登陆过期,请重新登录") account_key = auth_dict.get("accountKey") userid = auth_dict.get("userid") user = User.query.filter_by(account_key=account_key).first() if not user or user.account_key != account_key: return make_resp(401, False, message="account key not found") g.account_key = account_key g.user = user g.token = token return f(*args, **kwargs)
def put(self): """ 撤销转账 :return: """ parse = reqparse.RequestParser() parse.add_argument('id', type=int, required=True) parse.add_argument('coin_name', type=str) args = parse.parse_args() account_key = g.account_key id = args.get('id') coin_name = args.get('coin_name') or BHD_COIN_NAME withdrawal = WithdrawalTransaction.query.filter_by( id=id, account_key=account_key).first() if not withdrawal: api_logger.warning("account_key:%s, apply revocation:%s" % withdrawal.to_dict()) return make_resp(406, False, message="撤销订单不存在") if withdrawal.status != WITHDRAWAL_APPLY: api_logger.warning("account_key:%s, apply revocation:%s" % (account_key, withdrawal.to_dict())) return make_resp(400, False, message="订单状态不可撤销") try: user_asset = UserAsset.query.filter_by( account_key=account_key, coin_name=coin_name).with_for_update(read=True).first() user_asset.frozen_asset -= withdrawal.amount user_asset.available_asset += withdrawal.amount withdrawal.status = WITHDRAWAL_UNDO db.session.commit() api_logger.info("account_key:%s, revoke:%s " % (account_key, id)) return make_resp(200) except Exception as e: api_logger.error("account_key:%s, 撤销转账失败:%s " % (account_key, e)) withdrawal.status = WITHDRAWAL_FAILED db.session.rollback() return make_resp(400, False, message="撤销订单失败")
def post(self): """ 转账 :return: """ parse = reqparse.RequestParser() parse.add_argument('coin_name', type=str, required=True, trim=True) parse.add_argument('amount', type=str, required=True) parse.add_argument('to_address', type=str, required=True, trim=True) parse.add_argument('seccode', type=str, required=True, trim=True) args = parse.parse_args() coin_name = args.get('coin_name') account_key = g.account_key amount = Decimal(str(args.get('amount'))) to_address = args.get('to_address') seccode = args.get('seccode') api_logger.info("Withdrawal api, to:%s, amount:%s, account_key:%s" % (to_address, amount, account_key)) try: user_asset = UserAsset.query.filter_by( account_key=account_key, coin_name=coin_name).with_for_update(read=True).first() if not user_asset: api_logger.error("withdrawal,user not found %s" % account_key) return make_resp(404, False, message="用户资产错误") key = "withdrawal:seccode:%s" % account_key seccode_cache = redis_auth.get(key) if seccode != seccode_cache: api_logger.error("withdrawal, seccode error") return make_resp(400, False, message="验证码错误") redis_auth.delete(key) api_logger.error( "withdrawal, user:%s, available_asset:%s, amount:%s" % (account_key, user_asset.available_asset, amount)) if user_asset.available_asset < amount or user_asset.total_asset < amount: return make_resp(400, False, message="可用余额不足") client = get_rpc(coin_name) if not client.check_address(to_address): return make_resp(400, False, message="地址错误") if user_asset.get_available_margin_amount() < amount: return make_resp(400, False, message="可提现金额不足") user_asset.available_asset -= amount user_asset.frozen_asset += amount withdrawal_transaction = WithdrawalTransaction(account_key, amount, to_address, coin_name=coin_name) db.session.add(withdrawal_transaction) db.session.commit() except Exception as e: api_logger.error("withdrawal, error %s" % str(e)) db.session.rollback() return make_resp(500, False, message="提现申请提交失败") api_logger.info( "Withdrawal api, insert into withdrawal_transaction %s" % withdrawal_transaction.to_dict()) return make_resp(200, True)
def put(self): """ 用户资产划转,从抵押到余额划转,余额到抵押。 :return: """ parse = reqparse.RequestParser() parse.add_argument('amount', type=str, required=True) parse.add_argument('direction', type=bool, required=False, default=True, help="True:抵押到余额,False:余额到抵押") parse.add_argument('coin_name', type=str) args = parse.parse_args() coin_name = args.get('coin_name') or BHD_COIN_NAME amount = Decimal(args.get('amount')) # todo """ 到抵押时: 1、先从远程借贷中抵押到远程抵押 2、不够从可用中抵押到矿机抵押 到余额时: 1、先从矿机抵押划转到可用 2、不够从远程抵押减去 """ direction = args.get('direction') account_key = g.account_key api_logger.info("asset transfer, amount:%s, user:%s, direction:%s" % (amount, account_key, direction)) try: user_asset = UserAsset.query.filter_by( account_key=account_key, coin_name=coin_name).with_for_update(read=True).first() total_available_2pledge = user_asset.get_total_available_pledge_amount( ) total_available_2balance = user_asset.get_pledge_amount() if direction and total_available_2balance < amount: api_logger.error( "asset transfer, user:%s, pledge_asset:%s, amount:%s" % (account_key, user_asset.pledge_asset, amount)) return make_resp(400, False, message="pledge_asset not enough") if not direction and total_available_2pledge < amount: api_logger.error( "asset transfer, user:%s, available_asset:%s, amount:%s" % (account_key, user_asset.available_asset, amount)) return make_resp(400, False, message="available not enough") if direction: if user_asset.pledge_asset >= amount: user_asset.pledge_asset -= amount user_asset.available_asset += amount else: user_asset.remote_4pledge_asset -= ( amount - user_asset.pledge_asset) user_asset.available_asset += user_asset.pledge_asset user_asset.pledge_asset = 0 else: remote_avai2_pledge = user_asset.get_remote_avai_amount() if remote_avai2_pledge >= amount: user_asset.remote_4pledge_asset += amount else: user_asset.remote_4pledge_asset += remote_avai2_pledge del_available_asset = amount - remote_avai2_pledge user_asset.available_asset -= del_available_asset user_asset.pledge_asset += del_available_asset asset_transfer = AssetTransfer(account_key, abs(amount), direction, coin_name) db.session.add(asset_transfer) db.session.commit() except Exception as e: api_logger.error("asset transfer, error %s" % str(e)) db.session.rollback() return make_resp(500, False, message="transfer failed") api_logger.info( "asset transfer succeed, amount:%s, user:%s, direction:%s" % (amount, account_key, direction)) return make_resp(200, True)