async def api_lnurlscan(code: str): try: url = lnurl.Lnurl(code) except ValueError: return jsonify({"message": "invalid lnurl"}), HTTPStatus.BAD_REQUEST domain = urlparse(url.url).netloc # params is what will be returned to the client params: Dict = {"domain": domain} if url.is_login: params.update(kind="auth") params.update(callback=url.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.url, timeout=40) if r.is_error: return ( jsonify({ "domain": domain, "message": "failed to get parameters" }), HTTPStatus.SERVICE_UNAVAILABLE, ) try: jdata = json.loads(r.text) data: lnurl.LnurlResponseModel = lnurl.LnurlResponse.from_dict( jdata) except (json.decoder.JSONDecodeError, lnurl.exceptions.LnurlResponseException): return ( jsonify({ "domain": domain, "message": f"got invalid response '{r.text[:200]}'", }), HTTPStatus.SERVICE_UNAVAILABLE, ) if type(data) is lnurl.LnurlChannelResponse: return ( jsonify({ "domain": domain, "kind": "channel", "message": "unsupported" }), HTTPStatus.BAD_REQUEST, ) params.update(**data.dict()) if type(data) is lnurl.LnurlWithdrawResponse: params.update(kind="withdraw") params.update(fixed=data.min_withdrawable == data.max_withdrawable) # 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 jdata: params.update(balanceCheck=jdata["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 type(data) is lnurl.LnurlPayResponse: params.update(kind="pay") params.update(fixed=data.min_sendable == data.max_sendable) params.update(description_hash=data.metadata.h) params.update(description=data.metadata.text) if data.metadata.images: image = min(data.metadata.images, key=lambda image: len(image[1])) data_uri = "data:" + image[0] + "," + image[1] params.update(image=data_uri) params.update(commentAllowed=jdata.get("commentAllowed", 0)) return jsonify(params)
async def api_lnurlscan(code: str): try: url = lnurl.Lnurl(code) except ValueError: return jsonify({"error": "invalid lnurl"}), HTTPStatus.BAD_REQUEST domain = urlparse(url.url).netloc if url.is_login: return jsonify({ "domain": domain, "kind": "auth", "error": "unsupported" }), HTTPStatus.BAD_REQUEST async with httpx.AsyncClient() as client: r = await client.get(url.url, timeout=40) if r.is_error: return jsonify({ "domain": domain, "error": "failed to get parameters" }), HTTPStatus.SERVICE_UNAVAILABLE try: jdata = json.loads(r.text) data: lnurl.LnurlResponseModel = lnurl.LnurlResponse.from_dict(jdata) except (json.decoder.JSONDecodeError, lnurl.exceptions.LnurlResponseException): return ( jsonify({ "domain": domain, "error": f"got invalid response '{r.text[:200]}'" }), HTTPStatus.SERVICE_UNAVAILABLE, ) if type(data) is lnurl.LnurlChannelResponse: return jsonify({ "domain": domain, "kind": "channel", "error": "unsupported" }), HTTPStatus.BAD_REQUEST params: Dict = data.dict() if type(data) is lnurl.LnurlWithdrawResponse: params.update(kind="withdraw") params.update(fixed=data.min_withdrawable == data.max_withdrawable) # callback with k1 already in it parsed_callback: ParseResult = urlparse(data.callback) qs: Dict = parse_qs(parsed_callback.query) qs["k1"] = data.k1 parsed_callback = parsed_callback._replace( query=urlencode(qs, doseq=True)) params.update(callback=urlunparse(parsed_callback)) if type(data) is lnurl.LnurlPayResponse: params.update(kind="pay") params.update(fixed=data.min_sendable == data.max_sendable) params.update(description_hash=data.metadata.h) params.update(description=data.metadata.text) if data.metadata.images: image = min(data.metadata.images, key=lambda image: len(image[1])) data_uri = "data:" + image[0] + "," + image[1] params.update(image=data_uri) params.update(commentAllowed=jdata.get("commentAllowed", 0)) params.update(domain=domain) return jsonify(params)