Example #1
0
async def api_payments_decode():
    try:
        if g.data["data"][:5] == "LNURL":
            url = lnurl.decode(g.data["data"])
            return (
                jsonify({"domain": url}),
                HTTPStatus.OK,
            )
        else:
            invoice = bolt11.decode(g.data["data"])
            return (
                jsonify(
                    {
                        "payment_hash": invoice.payment_hash,
                        "amount_msat": invoice.amount_msat,
                        "description": invoice.description,
                        "description_hash": invoice.description_hash,
                        "payee": invoice.payee,
                        "date": invoice.date,
                        "expiry": invoice.expiry,
                        "secret": invoice.secret,
                        "route_hints": invoice.route_hints,
                        "min_final_cltv_expiry": invoice.min_final_cltv_expiry,
                    }
                ),
                HTTPStatus.OK,
            )
    except:
        return jsonify({"message": "Failed to decode"}), HTTPStatus.BAD_REQUEST
Example #2
0
async def api_lnurlscan(code: str):
    try:
        url = lnurl.decode(code)
        domain = urlparse(url).netloc
    except:
        # parse internet identifier ([email protected])
        name_domain = code.split("@")
        if len(name_domain) == 2 and len(name_domain[1].split(".")) >= 2:
            name, domain = name_domain
            url = (("http://" if domain.endswith(".onion") else "https://") +
                   domain + "/.well-known/lnurlp/" + name.lower())
            # will proceed with these values
        else:
            return jsonify({"message":
                            "invalid lnurl"}), HTTPStatus.BAD_REQUEST

    # params is what will be returned to the client
    params: Dict = {"domain": domain}

    if "tag=login" in url:
        params.update(kind="auth")
        params.update(callback=url)  # with k1 already in it

        lnurlauth_key = g.wallet.lnurlauth_key(domain)
        params.update(
            pubkey=lnurlauth_key.verifying_key.to_string("compressed").hex())
    else:
        async with httpx.AsyncClient() as client:
            r = await client.get(url, timeout=5)
            if r.is_error:
                return (
                    jsonify({
                        "domain": domain,
                        "message": "failed to get parameters"
                    }),
                    HTTPStatus.SERVICE_UNAVAILABLE,
                )

        try:
            data = json.loads(r.text)
        except json.decoder.JSONDecodeError:
            return (
                jsonify({
                    "domain": domain,
                    "message": f"got invalid response '{r.text[:200]}'",
                }),
                HTTPStatus.SERVICE_UNAVAILABLE,
            )

        try:
            tag = data["tag"]
            if tag == "channelRequest":
                return (
                    jsonify({
                        "domain": domain,
                        "kind": "channel",
                        "message": "unsupported"
                    }),
                    HTTPStatus.BAD_REQUEST,
                )

            params.update(**data)

            if tag == "withdrawRequest":
                params.update(kind="withdraw")
                params.update(
                    fixed=data["minWithdrawable"] == data["maxWithdrawable"])

                # callback with k1 already in it
                parsed_callback: ParseResult = urlparse(data["callback"])
                qs: Dict = parse_qs(parsed_callback.query)
                qs["k1"] = data["k1"]

                # balanceCheck/balanceNotify
                if "balanceCheck" in data:
                    params.update(balanceCheck=data["balanceCheck"])

                # format callback url and send to client
                parsed_callback = parsed_callback._replace(
                    query=urlencode(qs, doseq=True))
                params.update(callback=urlunparse(parsed_callback))

            if tag == "payRequest":
                params.update(kind="pay")
                params.update(fixed=data["minSendable"] == data["maxSendable"])

                params.update(description_hash=hashlib.sha256(
                    data["metadata"].encode("utf-8")).hexdigest())
                metadata = json.loads(data["metadata"])
                for [k, v] in metadata:
                    if k == "text/plain":
                        params.update(description=v)
                    if k == "image/jpeg;base64" or k == "image/png;base64":
                        data_uri = "data:" + k + "," + v
                        params.update(image=data_uri)
                    if k == "text/email" or k == "text/identifier":
                        params.update(targetUser=v)

                params.update(commentAllowed=data.get("commentAllowed", 0))
        except KeyError as exc:
            return (
                jsonify({
                    "domain": domain,
                    "message": f"lnurl JSON response invalid: {exc}",
                }),
                HTTPStatus.SERVICE_UNAVAILABLE,
            )

    return jsonify(params)