Exemplo n.º 1
0
 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")
Exemplo n.º 2
0
    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)
Exemplo n.º 3
0
    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())
Exemplo n.º 4
0
    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)
Exemplo n.º 5
0
    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="撤销订单失败")
Exemplo n.º 6
0
    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)
Exemplo n.º 7
0
    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)