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
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))
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))
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
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))
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))
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
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))
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)