Skip to content

Commit

Permalink
feat: BIP-353 resolver
Browse files Browse the repository at this point in the history
  • Loading branch information
michael1011 committed Sep 25, 2024
1 parent 1e4dc33 commit a2ca5ad
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 12 deletions.
49 changes: 37 additions & 12 deletions src/components/CreateButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { fetchBolt12Invoice, getPairs } from "../utils/boltzClient";
import { formatAmount } from "../utils/denomination";
import { formatError } from "../utils/errors";
import { coalesceLn } from "../utils/helper";
import { fetchLnurl } from "../utils/invoice";
import { fetchBip353, fetchLnurl } from "../utils/invoice";
import {
SomeSwap,
createChain,
Expand Down Expand Up @@ -153,17 +153,42 @@ export const CreateButton = () => {
const create = async () => {
if (validWayToFetchInvoice()) {
if (lnurl() !== undefined && lnurl() !== "") {
log.info("Fetching invoice from lnurl", lnurl());
try {
const inv = await fetchLnurl(
lnurl(),
Number(receiveAmount()),
);
setInvoice(inv);
log.info("Fetching invoice from LNURL or BIP-353", lnurl());

const fetchResults = await Promise.allSettled([
(() => {
try {
return fetchLnurl(lnurl(), Number(receiveAmount()));
} catch (e) {
log.warn("Fetching invoice from LNURL failed", e);
throw e;
}
})(),
(() => {
try {
return fetchBip353(
lnurl(),
Number(receiveAmount()),
);
} catch (e) {
log.warn("Fetching invoice from BIP-353 failed", e);
throw e;
}
})(),
]);

const fetched = fetchResults.find(
(res) => res.status === "fulfilled",
);
if (fetched !== undefined) {
setInvoice(fetched.value);
setLnurl("");
} catch (e) {
notify("error", e.message);
log.warn("fetch lnurl failed", e);
} else {
// All failed, so we can safely cast the first one
notify(
"error",
(fetchResults[0] as PromiseRejectedResult).reason,
);
return;
}
} else {
Expand All @@ -177,7 +202,7 @@ export const CreateButton = () => {
setBolt12Offer(undefined);
} catch (e) {
notify("error", formatError(e));
log.warn("Fetching invoice from bol12 failed", e);
log.warn("Fetching invoice from bolt12 failed", e);
return;
}
}
Expand Down
1 change: 1 addition & 0 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const defaults = {
testnetUrl: "https://testnet.boltz.exchange",
telegramUrl: "https://t.me/boltzhq",
email: "[email protected]",
dnsOverHttps: "https://1.1.1.1/dns-query",
};

type Asset = {
Expand Down
28 changes: 28 additions & 0 deletions src/utils/invoice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Invoice, Offer } from "boltz-bolt12";
import log from "loglevel";

import { config } from "../config";
import { fetchBolt12Invoice } from "./boltzClient";
import { checkResponse } from "./http";

type LnurlResponse = {
Expand Down Expand Up @@ -104,6 +105,33 @@ export const fetchLnurl = (
});
};

export const fetchBip353 = async (
hrn: string,
amountSat: number,
): Promise<string> => {
const split = hrn.split("@");
if (split.length !== 2) {
throw "invalid BIP-353";
}

log.debug(`Fetching BIP-353: ${hrn}`);

const params = new URLSearchParams({
type: "TXT",
name: `${split[0]}.user._bitcoin-payment.${split[1]}`,
});
const res = await fetch(`${config.dnsOverHttps}?${params.toString()}`, {
headers: {
Accept: "application/dns-json",
},
});
const resBody = await res.json();
const paymentRequest = resBody.Answer[0].data;
const offer = new URLSearchParams(paymentRequest.split("?")[1]).get("lno");
return (await fetchBolt12Invoice(offer.replaceAll('"', ""), amountSat))
.invoice;
};

const checkLnurlResponse = (amount: number, data: LnurlResponse) => {
log.debug(
"amount check: (x, min, max)",
Expand Down

0 comments on commit a2ca5ad

Please sign in to comment.