Browse Source

Rework donation to use local lnd

refactor
Hampus Sjöberg 4 years ago
parent
commit
fe9ae56608
  1. 24
      api.ts
  2. 24
      config/config.ts_TEMPLATE
  3. 18
      frontend/components/Donation.tsx
  4. 2
      run-server.sh
  5. 5
      utils.ts

24
api.ts

@ -1,8 +1,11 @@
import { Router } from "https://deno.land/x/oak/mod.ts"; import { Router } from "https://deno.land/x/oak/mod.ts";
import { exec, OutputMode } from "https://deno.land/x/exec/mod.ts";
import { getBlocks } from "./blocks.ts"; import { getBlocks } from "./blocks.ts";
import { getblockchaininfo, getblockcount, getblockhash } from "./jsonrpc/index.ts"; import { getblockchaininfo, getblockcount, getblockhash } from "./jsonrpc/index.ts";
import Pageviews from "./pageviews/index.ts"; import Pageviews from "./pageviews/index.ts";
import config from "./config/config.ts";
import { bytesToHexString } from "./utils.ts";
const router = new Router(); const router = new Router();
@ -23,6 +26,7 @@ router
status: "ERROR", status: "ERROR",
reason: "Missing param height", reason: "Missing param height",
}); });
return;
} }
const blockhash = await getblockhash(Number.parseInt(context.params.height)); const blockhash = await getblockhash(Number.parseInt(context.params.height));
context.response.body = blockhash; context.response.body = blockhash;
@ -37,4 +41,24 @@ router.get("/blocks", (context) => {
context.response.body = blocks; context.response.body = blocks;
}); });
router.get("/invoice", async (context) => {
if (!config.donation) {
context.response.status = 400;
context.response.body = JSON.stringify({
status: "ERROR",
reason: "Donation is not configured",
});
return;
}
const macaroonHeader = bytesToHexString(await Deno.readFile(config.donation.data.macaroon));
// -d '{"memo":"Donation"}'
const command = `curl -X POST --cacert ${config.donation.data.cert} --header "Grpc-Metadata-macaroon: ${macaroonHeader}" ${config.donation.data.server}/v1/invoices`;
const result = await exec(command, {
output: OutputMode.Capture,
});
context.response.body = JSON.parse(result.output).payment_request;
});
export default router; export default router;

24
config/config.ts_TEMPLATE

@ -29,6 +29,21 @@ interface Config {
// Threshold for the softfork to be locked in // Threshold for the softfork to be locked in
threshold: number; threshold: number;
}; };
// Donation configuration, right now only supports lnd
donation?: {
// Backend type, currently only supports lnd
type: "lnd";
// Data for the backend
data: {
// REST server
server: string;
// Path to tls.cert
cert: string;
// Path to invoice.macaroon
macaroon: string;
};
};
} }
const config: Config = { const config: Config = {
@ -49,6 +64,15 @@ const config: Config = {
versionBit: 2, versionBit: 2,
threshold: 1845, threshold: 1845,
}, },
// donation: {
// type: "lnd",
// data: {
// server: "https://127.0.0.1:8080",
// cert: "/path/to/tls.cert",
// macaroon: "/path/to/invoice.macaroon",
// },
// },
}; };
export default config; export default config;

18
frontend/components/Donation.tsx

@ -1,9 +1,6 @@
import React, { useState } from "https://esm.sh/react@17.0.2"; import React, { useState } from "https://esm.sh/react@17.0.2";
import styled from "https://esm.sh/styled-components"; import styled from "https://esm.sh/styled-components";
import { QRCode } from "https://esm.sh/react-qr-svg"; import { QRCode } from "https://esm.sh/react-qr-svg";
import { Link } from "https://deno.land/x/aleph@v0.2.28/mod.ts";
const DONATION_LNURL_PAY = "LNURL1DP68GURN8GHJ7MRWVF5HGUEWVDHK6TMVDE6HYMRS9ASHQ6F0WCCJ7MRWW4EXCTE38Y6QYWETXD";
export const DonateContainer = styled.div` export const DonateContainer = styled.div`
text-align: center; text-align: center;
@ -18,22 +15,27 @@ export const DonateText = styled.a`
`; `;
export function Donation() { export function Donation() {
const [showQr, setShowQr] = useState(false); const [invoice, setInvoice] = useState<string | undefined>(undefined);
const fetchInvoice = async () => {
const result = await fetch("/invoice");
setInvoice(await result.text());
};
return ( return (
<DonateContainer> <DonateContainer>
{!showQr && <DonateText onClick={() => setShowQr(true)}>Donate via Lightning Network</DonateText>} {!invoice && <DonateText onClick={fetchInvoice}>Donate via Lightning Network</DonateText>}
{showQr && ( {invoice && (
<div <div
style={{ cursor: "pointer" }} style={{ cursor: "pointer" }}
onClick={() => { onClick={() => {
window.location.replace("lightning:" + DONATION_LNURL_PAY.toLowerCase()); window.location.replace("lightning:" + invoice);
}} }}
> >
<QRCode <QRCode
bgColor="#FFFFFF" bgColor="#FFFFFF"
fgColor="#000000" fgColor="#000000"
value={DONATION_LNURL_PAY} value={invoice.toUpperCase()}
style={{ border: "8px solid #fff", width: 200 }} style={{ border: "8px solid #fff", width: 200 }}
/> />
</div> </div>

2
run-server.sh

@ -6,4 +6,4 @@ mkdir frontend/dist
deno run -A https://deno.land/x/aleph@v0.3.0-alpha.32/cli.ts build frontend --reload deno run -A https://deno.land/x/aleph@v0.3.0-alpha.32/cli.ts build frontend --reload
# Run backend # Run backend
deno run --unstable --allow-net --allow-read --allow-write index.ts deno run --unstable --allow-net --allow-read --allow-write --allow-run index.ts

5
utils.ts

@ -0,0 +1,5 @@
export const bytesToHexString = (bytes: Uint8Array) => {
return bytes.reduce(function (memo: unknown, i: number) {
return memo + ("0" + i.toString(16)).slice(-2); //padd with leading 0 if <16
}, "");
};
Loading…
Cancel
Save