예제 #1
0
def _create_transaction_waves(recipient, amount, attachment):
    # get fee
    path = f"/assets/details/{ASSET_ID}"
    response = requests.get(NODE_BASE_URL + path)
    if response.ok:
        asset_fee = response.json()["minSponsoredAssetFee"]
    else:
        short_msg = "failed to get asset info"
        logger.error("%s: (%d, %s, %s):\n\t%s", short_msg, response.status_code, response.request.method, response.url, response.text)
        err = OtherError(short_msg, tx_utils.ERR_FAILED_TO_GET_ASSET_INFO)
        err.data = response.text
        raise err
    if not recipient:
        short_msg = "recipient is null or an empty string"
        logger.error(short_msg)
        err = OtherError(short_msg, tx_utils.ERR_EMPTY_ADDRESS)
        raise err
    if not utils.is_address(recipient):
        short_msg = "recipient is not a valid address"
        logger.error(short_msg)
        err = OtherError(short_msg, tx_utils.ERR_EMPTY_ADDRESS)
        raise err
    recipient = pywaves.Address(recipient)
    asset = pywaves.Asset(ASSET_ID)
    address_data = PW_ADDRESS.sendAsset(recipient, asset, amount, attachment, feeAsset=asset, txFee=asset_fee)
    signed_tx = json.loads(address_data["api-data"])
    signed_tx["type"] = 4 # sendAsset does not include "type" - https://github.com/PyWaves/PyWaves/issues/131
    # calc txid properly
    txid = tx_utils.tx_to_txid(signed_tx)
    # store tx in db
    dbtx = WavesTx(txid, "transfer", tx_utils.CTX_CREATED, signed_tx["amount"], True, json.dumps(signed_tx))
    return dbtx
예제 #2
0
def tx_view(txid):
    dbtx = WavesTx.from_txid(db.session, txid)
    if not dbtx:
        flash('tx not found', 'danger')
        return redirect(url_for('tx_link', txid=txid, _external=True))
    tx = dbtx.tx_with_sigs()
    return render_template("mw/tx_show.html", tx=json.dumps(tx))
예제 #3
0
def tx_status():
    content = request.get_json(force=True)
    if content is None:
        return bad_request("failed to decode JSON object")
    params, err_response = get_json_params(content, ["txid"])
    if err_response:
        return err_response
    txid, = params
    dbtx = WavesTx.from_txid(db.session, txid)
    if not dbtx:
        return bad_request('tx not found', 404)
    tx = dbtx.tx_with_sigs()
    return jsonify(dict(txid=txid, state=dbtx.state, tx=tx))
예제 #4
0
def _tx_broadcast(txid):
    dbtx = WavesTx.from_txid(db.session, txid)
    if not dbtx:
        return bad_request('tx not found', 404)
    tx = dbtx.tx_with_sigs()
    error = ""
    # broadcast transaction
    try:
        dbtx = tx_utils.broadcast_transaction(db.session, dbtx.txid)
        db.session.add(dbtx)
        db.session.commit()
    except OtherError as ex:
        error = ex.message
        if hasattr(ex, 'data'):
            error = "{} - {}".format(ex.message, ex.data)
    return error, dbtx, tx
예제 #5
0
def tx_signature():
    content = request.get_json(force=True)
    if content is None:
        return bad_request("failed to decode JSON object")
    params, err_response = get_json_params(content, ["txid", "signer_index", "signature"])
    if err_response:
        return err_response
    txid, signer_index, signature = params
    dbtx = WavesTx.from_txid(db.session, txid)
    if not dbtx:
        return bad_request('tx not found', 404)
    logger.info(":: adding sig to tx - %s, %d, %s", txid, signer_index, signature)
    sig = WavesTxSig(dbtx, signer_index, signature)
    db.session.add(sig)
    db.session.commit()
    tx = dbtx.tx_with_sigs()
    return jsonify(dict(txid=txid, state=dbtx.state, tx=tx))
예제 #6
0
def tx_broadcast():
    content = request.get_json(force=True)
    if content is None:
        return bad_request("failed to decode JSON object")
    params, err_response = get_json_params(content, ["txid"])
    if err_response:
        return err_response
    txid, = params
    dbtx = WavesTx.from_txid(db.session, txid)
    if not dbtx:
        return bad_request('tx not found', 404)
    tx = dbtx.tx_with_sigs()
    error = ""
    # broadcast transaction
    try:
        dbtx = tx_utils.broadcast_transaction(db.session, dbtx.txid)
        db.session.add(dbtx)
        db.session.commit()
    except OtherError as ex:
        error = ex.message
        if hasattr(ex, 'data'):
            error = "{} - {}".format(ex.message, ex.data)
    return jsonify(dict(txid=txid, state=dbtx.state, tx=tx, error=error))
예제 #7
0
def broadcast_transaction(session, txid):
    dbtx = WavesTx.from_txid(session, txid)
    if not dbtx:
        raise OtherError("transaction not found", ERR_NO_TXID)
    if dbtx.state == CTX_EXPIRED:
        raise OtherError("transaction expired", ERR_TX_EXPIRED)
    signed_tx = dbtx.tx_with_sigs()
    logger.info("broadcasting tx: %s", str(signed_tx))
    # broadcast
    logger.debug("requesting broadcast of tx:\n\t%s, ", str(signed_tx))
    path = "/transactions/broadcast"
    headers = {"Content-Type": "application/json"}
    response = requests.post(NODE_BASE_URL + path, headers=headers, data=json.dumps(signed_tx))
    if response.ok:
        # update tx in db
        dbtx.state = CTX_BROADCAST
    else:
        short_msg = "failed to broadcast"
        logger.error("%s: (%d, %s, %s):\n\t%s", short_msg, response.status_code, response.request.method, response.url, response.text)
        err = OtherError(short_msg, ERR_FAILED_TO_BROADCAST)
        err.data = response.text
        raise err
    return dbtx
예제 #8
0
def tx_create():
    tx_utils.tx_init_chain_id(TESTNET)

    content = request.get_json(force=True)
    if content is None:
        return bad_request("failed to decode JSON object")
    params, err_response = get_json_params(content, ["type", "timestamp"])
    if err_response:
        return err_response
    type_, timestamp = params
    if not type_ in tx_utils.TYPES:
        return bad_request("'type' not valid")
    pubkey = ASSET_MASTER_PUBKEY
    address = tx_utils.generate_address(pubkey)
    amount = 0
    if type_ == "transfer":
        fee = tx_utils.get_fee(NODE_BASE_URL, tx_utils.DEFAULT_TX_FEE, address,
                               None)
        params, err_response = get_json_params(content,
                                               ["recipient", "amount"])
        if err_response:
            return err_response
        recipient, amount = params
        tx = tx_utils.transfer_asset_payload(address, pubkey, None, recipient,
                                             ASSET_ID, amount, "", None, fee,
                                             timestamp)
    elif type_ == "issue":
        fee = tx_utils.get_fee(NODE_BASE_URL, tx_utils.DEFAULT_ASSET_FEE,
                               address, None)
        params, err_response = get_json_params(
            content, ["asset_name", "asset_description", "amount"])
        if err_response:
            return err_response
        asset_name, asset_description, amount = params
        tx = tx_utils.issue_asset_payload(address, pubkey, None, asset_name,
                                          asset_description, amount, None, 2,
                                          True, fee, timestamp)
    elif type_ == "reissue":
        fee = tx_utils.get_fee(NODE_BASE_URL, tx_utils.DEFAULT_ASSET_FEE,
                               address, None)
        params, err_response = get_json_params(content, ["amount"])
        if err_response:
            return err_response
        amount, = params
        tx = tx_utils.reissue_asset_payload(address, pubkey, None, ASSET_ID,
                                            amount, True, fee, timestamp)
    elif type_ == "sponsor":
        fee = tx_utils.get_fee(NODE_BASE_URL, tx_utils.DEFAULT_SPONSOR_FEE,
                               address, None)
        params, err_response = get_json_params(content, ["asset_fee"])
        if err_response:
            return err_response
        asset_fee, = params
        amount = asset_fee
        tx = tx_utils.sponsor_payload(address, pubkey, None, ASSET_ID,
                                      asset_fee, fee, timestamp)
    elif type_ == "setscript":
        fee = tx_utils.get_fee(NODE_BASE_URL, tx_utils.DEFAULT_SCRIPT_FEE,
                               address, None)
        params, err_response = get_json_params(content, ["script"])
        if err_response:
            return err_response
        script, = params
        tx = tx_utils.set_script_payload(address, pubkey, None, script, fee,
                                         timestamp)
    else:
        return bad_request("invalid type")

    txid = tx_utils.tx_to_txid(tx)
    dbtx = WavesTx.from_txid(db.session, txid)
    if dbtx:
        return bad_request("txid already exists")
    dbtx = WavesTx(txid, type_, tx_utils.CTX_CREATED, amount, False,
                   json.dumps(tx))
    db.session.add(dbtx)
    db.session.commit()
    return jsonify(dict(txid=txid, state=tx_utils.CTX_CREATED, tx=tx))
예제 #9
0
def claim_payment(token):
    payment = Payment.from_token(db.session, token)
    if not payment:
        return bad_request('payment not found', 404)
    now = datetime.datetime.now()
    if now > payment.proposal.date_expiry and payment.status != payment.STATE_SENT_FUNDS:
        return bad_request('expired', 404)

    def render(recipient):
        url_parts = urlparse(request.url)
        url = url_parts._replace(scheme=DEEP_LINK_SCHEME,
                                 query='scheme={}'.format(
                                     url_parts.scheme)).geturl()
        qrcode_svg = utils.qrcode_svg_create(url)
        return render_template("claim_payment.html",
                               payment=payment,
                               recipient=recipient,
                               qrcode_svg=qrcode_svg,
                               url=url)

    def render_waves(dbtx):
        recipient = None
        if dbtx:
            recipient = dbtx.tx_with_sigs()["recipient"]
        return render(recipient)

    if SERVER_MODE == SERVER_MODE_WAVES:
        dbtx = WavesTx.from_txid(db.session, payment.txid)

    if request.method == "POST":
        content_type = request.content_type
        using_app = content_type.startswith('application/json')
        logger.info("claim_payment: content type - %s, using_app - %s",
                    content_type, using_app)
        recipient = ""
        asset_id = ""
        if using_app:
            content = request.get_json(force=True)
            if content is None:
                return bad_request("failed to decode JSON object")
            if SERVER_MODE == SERVER_MODE_WAVES:
                params, err_response = get_json_params(
                    content, ["recipient", "asset_id"])
                if err_response:
                    return err_response
                recipient, asset_id = params
            else:  # paydb
                params, err_response = get_json_params(content, ["recipient"])
                if err_response:
                    return err_response
                recipient, = params
        else:  # using html form
            try:
                recipient = request.form["recipient"]
            except:  # pylint: disable=bare-except
                flash("'recipient' parameter not present", "danger")
                return render_waves(dbtx)
            try:
                asset_id = request.form["asset_id"]
            except:  # pylint: disable=bare-except
                pass
        if SERVER_MODE == SERVER_MODE_WAVES:
            dbtx, err_msg = process_claim_waves(payment, dbtx, recipient,
                                                asset_id)
        else:  # paydb
            err_msg = process_claim_paydb(payment, recipient)
        if err_msg:
            logger.error("claim_payment: %s", err_msg)
            if using_app:
                return bad_request(err_msg)
            flash(err_msg, "danger")
    if SERVER_MODE == SERVER_MODE_WAVES:
        return render_waves(dbtx)
    return render(None)