This commit is contained in:
Kieran 2023-04-05 11:58:26 +01:00
parent 8ef20c27b3
commit 729cbe7cbb
Signed by: Kieran
GPG Key ID: DE71CEB3925BE941
5 changed files with 78 additions and 29 deletions

View File

@ -58,6 +58,7 @@ export function NoteCreator(props: NoteCreatorProps) {
try {
const svc = new LNURL(zapForward);
await svc.load();
extraTags = [svc.getZapTag()];
} catch {
setError(
formatMessage({
@ -66,7 +67,6 @@ export function NoteCreator(props: NoteCreatorProps) {
);
return;
}
extraTags = [["zap", zapForward]];
}
const ev = replyTo ? await publisher.reply(replyTo, note, extraTags) : await publisher.note(note, extraTags);
console.debug("Sending note: ", ev);

View File

@ -154,11 +154,16 @@ export default function NoteFooter(props: NoteFooterProps) {
}
function getLNURL() {
return ev.Tags.find(a => a.Key === "zap")?.LNURL || author?.lud16 || author?.lud06;
return ev.tags.find(a => a[0] === "zap")?.[1] || author?.lud16 || author?.lud06;
}
function getTargetName() {
return ev.Tags.find(a => a.Key === "zap")?.LNURL || author?.display_name || author?.name;
const zapTarget = ev.tags.find(a => a[0] === "zap")?.[1];
if (zapTarget) {
return new LNURL(zapTarget).name;
} else {
return author?.display_name || author?.name;
}
}
async function fastZap(e?: React.MouseEvent) {

View File

@ -48,6 +48,62 @@ export class LNURL {
}
}
/**
* URL of this payService
*/
get url() {
return this.#url;
}
/**
* Return the optimal formatted LNURL
*/
get lnurl() {
if (this.isLNAddress) {
return this.getLNAddress();
}
return this.#url.toString();
}
/**
* Human readable name for this service
*/
get name() {
// LN Address formatted URL
if (this.isLNAddress) {
return this.getLNAddress();
}
// Generic LUD-06 url
return this.#url.hostname;
}
/**
* Is this LNURL a LUD-16 Lightning Address
*/
get isLNAddress() {
return this.#url.pathname.startsWith("/.well-known/lnurlp/");
}
/**
* Get the LN Address for this LNURL
*/
getLNAddress() {
const pathParts = this.#url.pathname.split("/");
const username = pathParts[pathParts.length - 1];
return `${username}@${this.#url.hostname}`;
}
/**
* Create a NIP-57 zap tag from this LNURL
*/
getZapTag() {
if (this.isLNAddress) {
return ["zap", this.getLNAddress(), "lud16"];
} else {
return ["zap", this.#url.toString(), "lud06"];
}
}
async load() {
const rsp = await fetch(this.#url);
if (rsp.ok) {

View File

@ -24,7 +24,7 @@ import useModeration from "Hooks/useModeration";
import useZapsFeed from "Feed/ZapsFeed";
import { default as ZapElement } from "Element/Zap";
import FollowButton from "Element/FollowButton";
import { extractLnAddress, parseId, hexToBech32 } from "Util";
import { parseId, hexToBech32 } from "Util";
import Avatar from "Element/Avatar";
import Timeline from "Element/Timeline";
import Text from "Element/Text";
@ -43,9 +43,11 @@ import Modal from "Element/Modal";
import BadgeList from "Element/BadgeList";
import { ProxyImg } from "Element/ProxyImg";
import useHorizontalScroll from "Hooks/useHorizontalScroll";
import messages from "./messages";
import { EmailRegex } from "Const";
import { getNip05PubKey } from "./Login";
import { getNip05PubKey } from "Pages/Login";
import { LNURL } from "LNURL";
import messages from "./messages";
const NOTES = 0;
const REACTIONS = 1;
@ -111,7 +113,13 @@ export default function ProfilePage() {
});
const npub = !id?.startsWith(NostrPrefix.PublicKey) ? hexToBech32(NostrPrefix.PublicKey, id || undefined) : id;
const lnurl = extractLnAddress(user?.lud16 || user?.lud06 || "");
const lnurl = (() => {
try {
return new LNURL(user?.lud16 || user?.lud06 || "");
} catch {
// ignored
}
})();
const website_url =
user?.website && !user.website.startsWith("http") ? "https://" + user.website : user?.website || "";
// feeds
@ -185,12 +193,12 @@ export default function ProfilePage() {
{lnurl && (
<div className="lnurl f-ellipsis" onClick={() => setShowLnQr(true)}>
<Icon name="zap" />
{lnurl}
{lnurl.name}
</div>
)}
<SendSats
lnurl={lnurl}
lnurl={lnurl?.lnurl}
show={showLnQr}
onClose={() => setShowLnQr(false)}
author={id}

View File

@ -146,26 +146,6 @@ export function getAllReactions(notes: readonly TaggedRawEvent[] | undefined, id
return notes?.filter(a => a.kind === (kind ?? a.kind) && a.tags.some(a => a[0] === "e" && ids.includes(a[1]))) || [];
}
/**
* Converts LNURL service to LN Address
*/
export function extractLnAddress(lnurl: string) {
// some clients incorrectly set this to LNURL service, patch this
if (lnurl.toLowerCase().startsWith("lnurl")) {
const url = bech32ToText(lnurl);
if (url.startsWith("http")) {
const parsedUri = new URL(url);
// is lightning address
if (parsedUri.pathname.startsWith("/.well-known/lnurlp/")) {
const pathParts = parsedUri.pathname.split("/");
const username = pathParts[pathParts.length - 1];
return `${username}@${parsedUri.hostname}`;
}
}
}
return lnurl;
}
export function unixNow() {
return Math.floor(unixNowMs() / 1000);
}