Exemplo n.º 1
0
async def asset_burn(amount: Amount or int or float,
                     symbol: str = None) -> dict:
    instance = shared_bitshares_instance()
    instance.nobroadcast = True
    if not isinstance(amount, Amount) and type(amount) in (int, float):
        amount = await Amount(amount, symbol)
    return await instance.reserve(amount)
Exemplo n.º 2
0
async def asset_transfer(to: str,
                         amount: float,
                         asset: str,
                         memo: str = None,
                         account: str = None) -> dict:
    instance = shared_bitshares_instance()
    instance.nobroadcast = True
    if not account:
        account = instance.config["default_account"]
    return await instance.transfer(account=account,
                                   to=to,
                                   amount=amount,
                                   asset=asset,
                                   memo=memo)
Exemplo n.º 3
0
async def wait_new_account_ops(account: str = None, last_op: int = 0) -> list:
    """
    Wait for new operations on (gateway) account

    :param account: bitshares account to parse
    :param last_op: number or last processed operation. It will be NOT included in first cycle iteration
    :return: Reversed iterator of account's operations. Gateway must process operations in order older->newer
    """

    instance = shared_bitshares_instance()
    if not account:
        account = instance.config["default_account"]

    account = await Account(account)

    while True:
        history_agen = account.history(last=last_op)
        new_ops = [op async for op in history_agen]
        if new_ops:
            return list(reversed(new_ops))
        else:
            await asyncio.sleep(BITSHARES_BLOCK_TIME)
Exemplo n.º 4
0
async def broadcast_tx(tx: dict) -> dict:
    instance: BitShares = shared_bitshares_instance()
    instance.nobroadcast = False
    tx_res = await instance.broadcast(tx)
    return tx_res
Exemplo n.º 5
0
async def validate_op(op: dict) -> BitSharesOperationDTO:
    """Parse BitShares operation body from Account.history generator, check fields. Return DataTransferObject"""
    instance = shared_bitshares_instance()

    # Check operations types
    # To learn more info about bithsares operationsIDs and types look at:
    # https://github.com/bitshares/python-bitshares/blob/master/bitsharesbase/operationids.py
    op_type = op["op"][0]

    # Transfer type is 0
    if op_type == 0:

        from_account = await Account(op["op"][1]["from"])
        to = await Account(op["op"][1]["to"])
        amount = await Amount(op["op"][1]["amount"])
        asset = await Asset(amount["asset"])
        memo = await read_memo(op["op"][1].get("memo"))

        op_log_string = (
            f"Op {op['id']}: {from_account.name} transfer {amount} to {to.name}"
        )
        if memo:
            op_log_string += f" with memo `{memo}`"

        log.info(op_log_string)

        error = TxError.NO_ERROR
        status = TxStatus.RECEIVED_NOT_CONFIRMED

        # Validate asset
        if asset.symbol != gateway_cfg["gateway_distribute_asset"]:
            error = TxError.BAD_ASSET

        # Validate account
        if from_account.name == instance.config["default_account"]:
            order_type = OrderType.DEPOSIT
        elif to.name == instance.config["default_account"]:
            order_type = OrderType.WITHDRAWAL
        else:
            raise  # Just pretty code, this situation is impossible

        # Validate amount for withdrawals
        if order_type == OrderType.WITHDRAWAL:

            if amount < gateway_cfg["gateway_min_withdrawal"]:
                error = TxError.LESS_MIN

            if amount > gateway_cfg["gateway_max_withdrawal"]:
                error = TxError.GREATER_MAX

            if not memo:
                error = TxError.NO_MEMO
            else:
                try:
                    await validate_withdrawal_memo(memo)
                except InvalidMemoMask:
                    error = TxError.FLOOD_MEMO

        # Validate amount for deposits
        if order_type == OrderType.DEPOSIT:

            if amount < gateway_cfg["gateway_min_deposit"]:
                error = TxError.LESS_MIN

            if amount > gateway_cfg["gateway_max_withdrawal"]:
                error = TxError.GREATER_MAX

        try:
            tx_hash = await get_tx_hash_from_op(op)
        except OperationsCollision as ex:
            log.exception(ex)
            tx_hash = "Unknown"
            error = TxError.OP_COLLISION
        except TransactionNotFound as ex:
            log.exception(ex)
            tx_hash = "Unknown"
            error = TxError.TX_HASH_NOT_FOUND
        except Exception as ex:
            log.exception(ex)
            tx_hash = "Unknown"
            error = TxError.UNKNOWN_ERROR

        if error != TxError.NO_ERROR:
            status = TxStatus.ERROR
            log.info(f"Op {op['id']}: catch Error: {error.name}")
        else:
            log.info(
                f"Op {op['id']}: operation is valid and will be processed as {order_type.name}"
            )

        op_dto = BitSharesOperationDTO(
            op_id=int(op["id"].split(".")[2]),
            order_type=order_type,
            asset=asset.symbol,
            from_account=from_account.name,
            to_account=to.name,
            amount=amount.amount,
            status=status,
            tx_hash=tx_hash,
            confirmations=0,
            block_num=op["block_num"],
            tx_created_at=(await Block(op["block_num"])).time(),
            error=error,
        )

        return op_dto