feat: zaps #78
@ -7,6 +7,7 @@
|
||||
"@fortawesome/free-solid-svg-icons": "^6.2.1",
|
||||
"@fortawesome/react-fontawesome": "^0.2.0",
|
||||
"@jukben/emoji-search": "^2.0.1",
|
||||
"@noble/hashes": "^1.2.0",
|
||||
"@noble/secp256k1": "^1.7.0",
|
||||
"@protobufjs/base64": "^1.1.2",
|
||||
"@reduxjs/toolkit": "^1.9.1",
|
||||
|
@ -1,12 +1,16 @@
|
||||
import "./LNURLTip.css";
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import { bech32ToText } from "Util";
|
||||
import { HexKey } from "Nostr";
|
||||
import useEventPublisher from "Feed/EventPublisher";
|
||||
import Modal from "Element/Modal";
|
||||
import QrCode from "Element/QrCode";
|
||||
import Copy from "Element/Copy";
|
||||
import useWebln from "Hooks/useWebln";
|
||||
|
||||
interface LNURLService {
|
||||
allowsNostr?: boolean
|
||||
nostrPubkey?: HexKey
|
||||
minSendable?: number,
|
||||
maxSendable?: number,
|
||||
metadata: string,
|
||||
@ -31,12 +35,15 @@ export interface LNURLTipProps {
|
||||
invoice?: string, // shortcut to invoice qr tab
|
||||
title?: string,
|
||||
notice?: string
|
||||
note?: HexKey
|
||||
author?: HexKey
|
||||
}
|
||||
|
||||
export default function LNURLTip(props: LNURLTipProps) {
|
||||
const onClose = props.onClose || (() => { });
|
||||
const service = props.svc;
|
||||
const show = props.show || false;
|
||||
const { note, author } = props
|
||||
const amounts = [50, 100, 500, 1_000, 5_000, 10_000, 50_000];
|
||||
const [payService, setPayService] = useState<LNURLService>();
|
||||
const [amount, setAmount] = useState<number>();
|
||||
@ -46,6 +53,7 @@ export default function LNURLTip(props: LNURLTipProps) {
|
||||
const [error, setError] = useState<string>();
|
||||
const [success, setSuccess] = useState<LNURLSuccessAction>();
|
||||
const webln = useWebln(show);
|
||||
const publisher = useEventPublisher();
|
||||
|
||||
useEffect(() => {
|
||||
if (show && !props.invoice) {
|
||||
@ -117,7 +125,16 @@ export default function LNURLTip(props: LNURLTipProps) {
|
||||
|
||||
async function loadInvoice() {
|
||||
if (!amount || !payService) return null;
|
||||
const url = `${payService.callback}?amount=${Math.floor(amount * 1000)}${comment ? `&comment=${encodeURIComponent(comment)}` : ""}`;
|
||||
let url = ''
|
||||
const amountParam = `amount=${Math.floor(amount * 1000)}`
|
||||
const commentParam = comment ? `&comment=${encodeURIComponent(comment)}` : ""
|
||||
if (payService.allowsNostr && payService.nostrPubkey && author) {
|
||||
const ev = await publisher.zap(author, note, comment)
|
||||
const nostrParam = ev && `&nostr=${encodeURIComponent(JSON.stringify(ev.ToObject()))}`
|
||||
url = `${payService.callback}?${amountParam}${commentParam}${nostrParam}`;
|
||||
} else {
|
||||
url = `${payService.callback}?${amountParam}${commentParam}`;
|
||||
}
|
||||
try {
|
||||
let rsp = await fetch(url);
|
||||
if (rsp.ok) {
|
||||
|
@ -14,6 +14,7 @@ import useEventPublisher from "Feed/EventPublisher";
|
||||
import { getReactions, hexToBech32, normalizeReaction, Reaction } from "Util";
|
||||
import { NoteCreator } from "Element/NoteCreator";
|
||||
import LNURLTip from "Element/LNURLTip";
|
||||
import { parseZap, ZapsSummary } from "Element/Zap";
|
||||
import { useUserProfile } from "Feed/ProfileFeed";
|
||||
import { default as NEvent } from "Nostr/Event";
|
||||
import { RootState } from "State/Store";
|
||||
@ -50,6 +51,9 @@ export default function NoteFooter(props: NoteFooterProps) {
|
||||
const langNames = new Intl.DisplayNames([...window.navigator.languages], { type: "language" });
|
||||
const reactions = useMemo(() => getReactions(related, ev.Id, EventKind.Reaction), [related, ev]);
|
||||
const reposts = useMemo(() => getReactions(related, ev.Id, EventKind.Repost), [related, ev]);
|
||||
const zaps = useMemo(() => getReactions(related, ev.Id, EventKind.ZapReceipt).map(parseZap).filter(z => z.valid), [related]);
|
||||
const zapTotal = zaps.reduce((acc, z) => acc + z.amount, 0)
|
||||
const didZap = zaps.some(a => a.zapper === login);
|
||||
const groupReactions = useMemo(() => {
|
||||
return reactions?.reduce((acc, { content }) => {
|
||||
let r = normalizeReaction(content);
|
||||
@ -97,10 +101,11 @@ export default function NoteFooter(props: NoteFooterProps) {
|
||||
if (service) {
|
||||
return (
|
||||
<>
|
||||
<div className="reaction-pill" onClick={() => setTip(true)}>
|
||||
<div className={`reaction-pill ${didZap ? 'reacted' : ''}`} onClick={() => setTip(true)}>
|
||||
<div className="reaction-pill-icon">
|
||||
<Zap />
|
||||
</div>
|
||||
{zapTotal > 0 && (<div className="reaction-pill-number">{formatShort(zapTotal)}</div>)}
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
@ -233,6 +238,7 @@ export default function NoteFooter(props: NoteFooterProps) {
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="footer">
|
||||
<div className="footer-reactions">
|
||||
{tipButton()}
|
||||
@ -259,7 +265,11 @@ export default function NoteFooter(props: NoteFooterProps) {
|
||||
show={reply}
|
||||
setShow={setReply}
|
||||
/>
|
||||
<LNURLTip svc={author?.lud16 || author?.lud06} onClose={() => setTip(false)} show={tip} />
|
||||
<LNURLTip svc={author?.lud16 || author?.lud06} onClose={() => setTip(false)} show={tip} author={author?.pubkey} note={ev.Id} />
|
||||
</div>
|
||||
<div className="zaps-container">
|
||||
<ZapsSummary zaps={zaps} />
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import useTimelineFeed, { TimelineSubject } from "Feed/TimelineFeed";
|
||||
import { TaggedRawEvent } from "Nostr";
|
||||
import EventKind from "Nostr/EventKind";
|
||||
import LoadMore from "Element/LoadMore";
|
||||
import Zap, { parseZap } from "Element/Zap";
|
||||
import Note from "Element/Note";
|
||||
import NoteReaction from "Element/NoteReaction";
|
||||
import useModeration from "Hooks/useModeration";
|
||||
@ -45,15 +46,19 @@ export default function Timeline({ subject, postsOnly = false, method, ignoreMod
|
||||
function eventElement(e: TaggedRawEvent) {
|
||||
switch (e.kind) {
|
||||
case EventKind.SetMetadata: {
|
||||
return <ProfilePreview pubkey={e.pubkey} className="card"/>
|
||||
return <ProfilePreview pubkey={e.pubkey} className="card" />
|
||||
}
|
||||
case EventKind.TextNote: {
|
||||
return <Note key={e.id} data={e} related={related.notes} ignoreModeration={ignoreModeration} />
|
||||
}
|
||||
case EventKind.ZapReceipt: {
|
||||
const zap = parseZap(e)
|
||||
return zap.e ? null : <Zap zap={zap} key={e.id} />
|
||||
}
|
||||
case EventKind.Reaction:
|
||||
case EventKind.Repost: {
|
||||
let eRef = e.tags.find(a => a[0] === "e")?.at(1);
|
||||
return <NoteReaction data={e} key={e.id} root={parent.notes.find(a => a.id === eRef)}/>
|
||||
return <NoteReaction data={e} key={e.id} root={parent.notes.find(a => a.id === eRef)} />
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -61,12 +66,12 @@ export default function Timeline({ subject, postsOnly = false, method, ignoreMod
|
||||
return (
|
||||
<div className="main-content">
|
||||
{latestFeed.length > 1 && (<div className="card latest-notes pointer" onClick={() => showLatest()}>
|
||||
<FontAwesomeIcon icon={faForward} size="xl"/>
|
||||
<FontAwesomeIcon icon={faForward} size="xl" />
|
||||
|
||||
Show latest {latestFeed.length - 1} notes
|
||||
</div>)}
|
||||
{mainFeed.map(eventElement)}
|
||||
<LoadMore onLoadMore={loadMore} shouldLoadMore={main.end}/>
|
||||
<LoadMore onLoadMore={loadMore} shouldLoadMore={main.end} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
84
src/Element/Zap.css
Normal file
@ -0,0 +1,84 @@
|
||||
.zap {
|
||||
min-height: unset;
|
||||
}
|
||||
|
||||
@media (max-width: 520px) {
|
||||
.zap .header {
|
||||
flex-direction: column;
|
||||
}
|
||||
.zap .header .pfp {
|
||||
width: 100%;
|
||||
padding: 4px;
|
||||
}
|
||||
.zap .header .amount {
|
||||
font-size: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
.zap .summary {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.zap .amount {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.zap .amount:before {
|
||||
content: '⚡️ ';
|
||||
}
|
||||
|
||||
.top-zap .amount:before {
|
||||
content: '';
|
||||
}
|
||||
|
||||
.zaps-summary {
|
||||
margin-top: 8px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.top-zap {
|
||||
font-size: 14px;
|
||||
border: none;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.top-zap .pfp {
|
||||
margin-right: .3em;
|
||||
}
|
||||
|
||||
.top-zap .summary {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.top-zap .avatar {
|
||||
width: 21px;
|
||||
height: 21px;
|
||||
}
|
||||
|
||||
.top-zap .nip05 {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.amount-number {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.rest-zaps:before {
|
||||
content: ", ";
|
||||
}
|
||||
|
||||
.note.zap > .header {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.note.zap > .body {
|
||||
margin-bottom: 0;
|
||||
}
|
155
src/Element/Zap.tsx
Normal file
@ -0,0 +1,155 @@
|
||||
|
||||
import "./Zap.css";
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
import { useMemo } from "react";
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
import { useSelector } from "react-redux";
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
// @ts-expect-error
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
import { decode as invoiceDecode } from "light-bolt11-decoder";
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
import { bytesToHex } from "@noble/hashes/utils";
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
import { sha256 } from "Util";
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
//import { sha256 } from "Util";
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
import { formatShort } from "Number";
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
import { HexKey, TaggedRawEvent } from "Nostr";
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
import Event from "Nostr/Event";
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
import Text from "Element/Text";
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
import ProfileImage from "Element/ProfileImage";
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
import { RootState } from "State/Store";
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
function findTag(e: TaggedRawEvent, tag: string) {
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
const maybeTag = e.tags.find((evTag) => {
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
return evTag[0] === tag
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
})
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
return maybeTag && maybeTag[1]
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
}
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
function getInvoice(zap: TaggedRawEvent) {
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
const bolt11 = findTag(zap, 'bolt11')
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
const decoded = invoiceDecode(bolt11)
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
const amount = decoded.sections.find((section: any) => section.name === 'amount')?.value
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
const hash = decoded.sections.find((section: any) => section.name === 'description_hash')?.value;
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
return { amount, hash: hash ? bytesToHex(hash) : undefined };
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
}
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
interface Zapper {
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
pubkey?: HexKey,
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
isValid: boolean
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
}
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
function getZapper(zap: TaggedRawEvent, dhash: string): Zapper {
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
const zapRequest = findTag(zap, 'description')
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
if (zapRequest) {
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
const rawEvent: TaggedRawEvent = JSON.parse(zapRequest);
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
if (Array.isArray(rawEvent)) {
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
// old format, ignored
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
return { isValid: false };
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
}
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
const metaHash = sha256(zapRequest);
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
const ev = new Event(rawEvent)
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
return { pubkey: ev.PubKey, isValid: dhash === metaHash };
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
}
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
return { isValid: false }
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
}
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
interface ParsedZap {
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
id: HexKey
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
e?: HexKey
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
p: HexKey
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
amount: number
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
content: string
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
zapper?: HexKey
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
valid: boolean
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
}
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
export function parseZap(zap: TaggedRawEvent): ParsedZap {
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
const { amount, hash } = getInvoice(zap)
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
const zapper = hash ? getZapper(zap, hash) : { isValid: false };
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
const e = findTag(zap, 'e')
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
const p = findTag(zap, 'p')!
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
return {
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
id: zap.id,
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
e,
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
p,
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
amount: Number(amount) / 1000,
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
zapper: zapper.pubkey,
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
content: zap.content,
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
valid: zapper.isValid,
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
}
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
}
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
const Zap = ({ zap, showZapped = true }: { zap: ParsedZap, showZapped?: boolean }) => {
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
const { amount, content, zapper, valid, p } = zap
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
const pubKey = useSelector((s: RootState) => s.login.publicKey)
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
return valid ? (
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
<div className="zap note card">
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
<div className="header">
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
{zapper ? <ProfileImage pubkey={zapper} /> : <div>Anon </div>}
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
{p !== pubKey && showZapped && <ProfileImage pubkey={p} />}
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
<div className="amount">
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
<span className="amount-number">{formatShort(amount)}</span> sats
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
</div>
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
</div>
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
<div className="body">
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
<Text
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
creator={zapper || ""}
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
content={content}
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
tags={[]}
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
users={new Map()}
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
/>
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
</div>
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
</div>
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
) : null
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
}
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
interface ZapsSummaryProps { zaps: ParsedZap[] }
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
export const ZapsSummary = ({ zaps }: ZapsSummaryProps) => {
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
const sortedZaps = useMemo(() => {
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
const pub = [...zaps.filter(z => z.zapper)]
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
const priv = [...zaps.filter(z => !z.zapper)]
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
pub.sort((a, b) => b.amount - a.amount)
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
return pub.concat(priv)
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
}, [zaps])
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
if (zaps.length === 0) {
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
return null
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
}
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
const [topZap, ...restZaps] = sortedZaps
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
const restZapsTotal = restZaps.reduce((acc, z) => acc + z.amount, 0)
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
const { zapper, amount, content, valid } = topZap
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
return (
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
<div className="zaps-summary">
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
{amount && (
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
<div className={`top-zap`}>
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
<div className="summary">
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
{zapper ? <ProfileImage pubkey={zapper} /> : <div>Anon </div>}
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
<div className="amount">
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
zapped <span className="amount-number">{formatShort(amount)}</span> sats
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
</div>
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
</div>
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
<div className="body">
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
{content && (
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
<Text
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
creator={zapper || ""}
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
content={content}
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
tags={[]}
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
users={new Map()}
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
/>
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
)}
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
</div>
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
</div>
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
)}
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
{restZapsTotal > 0 && (
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
<div className="rest-zaps">
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
{restZaps.length} other{restZaps.length > 1 ? 's' : ''} zapped
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
<span className="amount-number">{formatShort(restZapsTotal)}</span> sats
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
</div>
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
)}
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
</div>
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
)
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
}
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
||||
export default Zap
|
||||
This is wrong, were not using this format anymore, can you revert to previous? The This is wrong, were not using this format anymore, can you revert to previous?
The `description` tag contains the zap note and the hash of this should match the description hash of the invoice
|
@ -19,7 +19,7 @@ const ZapButton = ({ pubkey, svc }: { pubkey?: HexKey, svc?: string }) => {
|
||||
<div className="zap-button" onClick={(e) => setZap(true)}>
|
||||
<FontAwesomeIcon icon={faBolt} />
|
||||
</div>
|
||||
<LNURLTip svc={service} show={zap} onClose={() => setZap(false)} />
|
||||
<LNURLTip svc={service} show={zap} onClose={() => setZap(false)} author={pubkey} />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
@ -144,6 +144,24 @@ export default function useEventPublisher() {
|
||||
return await signEvent(ev);
|
||||
}
|
||||
},
|
||||
zap: async (author: HexKey, note?: HexKey, msg?: string) => {
|
||||
if (pubKey) {
|
||||
let ev = NEvent.ForPubKey(pubKey);
|
||||
ev.Kind = EventKind.ZapRequest;
|
||||
if (note) {
|
||||
// @ts-ignore
|
||||
ev.Tags.push(new Tag(["e", note]))
|
||||
}
|
||||
// @ts-ignore
|
||||
ev.Tags.push(new Tag(["p", author]))
|
||||
// @ts-ignore
|
||||
const relayTag = ['relays', ...Object.keys(relays).slice(0, 10)]
|
||||
// @ts-ignore
|
||||
ev.Tags.push(new Tag(relayTag))
|
||||
processContent(ev, msg || '');
|
||||
return await signEvent(ev);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Reply to a note
|
||||
*/
|
||||
|
@ -41,6 +41,7 @@ export default function useLoginFeed() {
|
||||
|
||||
let sub = new Subscriptions();
|
||||
sub.Id = "login:notifications";
|
||||
// todo: add zaps
|
||||
sub.Kinds = new Set([EventKind.TextNote]);
|
||||
sub.PTags = new Set([pubKey]);
|
||||
sub.Limit = 1;
|
||||
|
@ -31,7 +31,7 @@ export default function useThreadFeed(id: u256) {
|
||||
|
||||
// get replies to this event
|
||||
const subRelated = new Subscriptions();
|
||||
subRelated.Kinds = new Set(pref.enableReactions ? [EventKind.Reaction, EventKind.TextNote, EventKind.Deletion, EventKind.Repost] : [EventKind.TextNote]);
|
||||
subRelated.Kinds = new Set(pref.enableReactions ? [EventKind.Reaction, EventKind.TextNote, EventKind.Deletion, EventKind.Repost, EventKind.ZapReceipt] : [EventKind.TextNote]);
|
||||
subRelated.ETags = thisSub.Ids;
|
||||
thisSub.AddSubscription(subRelated);
|
||||
|
||||
|
@ -35,7 +35,7 @@ export default function useTimelineFeed(subject: TimelineSubject, options: Timel
|
||||
|
||||
let sub = new Subscriptions();
|
||||
sub.Id = `timeline:${subject.type}:${subject.discriminator}`;
|
||||
sub.Kinds = new Set([EventKind.TextNote, EventKind.Repost]);
|
||||
sub.Kinds = new Set([EventKind.TextNote, EventKind.Repost, EventKind.ZapReceipt]);
|
||||
switch (subject.type) {
|
||||
case "pubkey": {
|
||||
sub.Authors = new Set(subject.items);
|
||||
@ -107,7 +107,7 @@ export default function useTimelineFeed(subject: TimelineSubject, options: Timel
|
||||
if (trackingEvents.length > 0 && pref.enableReactions) {
|
||||
sub = new Subscriptions();
|
||||
sub.Id = `timeline-related:${subject.type}`;
|
||||
sub.Kinds = new Set([EventKind.Reaction, EventKind.Deletion]);
|
||||
sub.Kinds = new Set([EventKind.Reaction, EventKind.Deletion, EventKind.ZapReceipt]);
|
||||
sub.ETags = new Set(trackingEvents);
|
||||
}
|
||||
return sub ?? null;
|
||||
|
17
src/Feed/ZapsFeed.ts
Normal file
@ -0,0 +1,17 @@
|
||||
import { useMemo } from "react";
|
||||
import { HexKey } from "Nostr";
|
||||
import EventKind from "Nostr/EventKind";
|
||||
import { Subscriptions } from "Nostr/Subscriptions";
|
||||
import useSubscription from "./Subscription";
|
||||
|
||||
export default function useZapsFeed(pubkey: HexKey) {
|
||||
const sub = useMemo(() => {
|
||||
let x = new Subscriptions();
|
||||
x.Id = `zaps:${pubkey}`;
|
||||
x.Kinds = new Set([EventKind.ZapReceipt]);
|
||||
x.PTags = new Set([pubkey]);
|
||||
return x;
|
||||
}, [pubkey]);
|
||||
|
||||
return useSubscription(sub, { leaveOpen: true, cache: true });
|
||||
}
|
@ -10,6 +10,8 @@ const enum EventKind {
|
||||
Reaction = 7, // NIP-25
|
||||
Auth = 22242, // NIP-42
|
||||
Lists = 30000, // NIP-51
|
||||
ZapRequest = 9734, // NIP tba
|
||||
ZapReceipt = 9735 // NIP tba
|
||||
};
|
||||
|
||||
export default EventKind;
|
||||
|
@ -4,11 +4,11 @@ const intl = new Intl.NumberFormat("en", {
|
||||
});
|
||||
|
||||
export function formatShort(n: number) {
|
||||
if (n < 999) {
|
||||
if (n < 2e3) {
|
||||
return n
|
||||
} else if (n < 1e8) {
|
||||
return `${intl.format(Math.floor(n / 1e3))}K`
|
||||
return `${intl.format(n / 1e3)}K`
|
||||
} else {
|
||||
return `${intl.format(Math.floor(n / 1e6))}M`
|
||||
return `${intl.format(n / 1e6)}M`
|
||||
}
|
||||
}
|
||||
|
@ -71,7 +71,10 @@ const DonatePage = () => {
|
||||
</p>
|
||||
<div className="flex">
|
||||
<div className="mr10">Lightning Donation: </div>
|
||||
<ZapButton svc={"donate@snort.social"} />
|
||||
<ZapButton
|
||||
pubkey={"84de35e2584d2b144aae823c9ed0b0f3deda09648530b93d1a2a146d1dea9864"}
|
||||
svc={"donate@snort.social"}
|
||||
/>
|
||||
</div>
|
||||
{today && (<small>Total today (UTC): {today.donations.toLocaleString()} sats</small>)}
|
||||
<h3>Primary Developers</h3>
|
||||
|
@ -213,3 +213,8 @@
|
||||
.qr-modal .modal-body {
|
||||
width: unset;
|
||||
}
|
||||
|
||||
.profile .zap-amount {
|
||||
font-weight: normal;
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
@ -4,11 +4,14 @@ import { useEffect, useMemo, useState } from "react";
|
||||
import { useSelector } from "react-redux";
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
|
||||
import { formatShort } from "Number";
|
||||
import Link from "Icons/Link";
|
||||
import Qr from "Icons/Qr";
|
||||
import Zap from "Icons/Zap";
|
||||
import Envelope from "Icons/Envelope";
|
||||
import { useUserProfile } from "Feed/ProfileFeed";
|
||||
import useZapsFeed from "Feed/ZapsFeed";
|
||||
import { default as ZapElement, parseZap } from "Element/Zap";
|
||||
import FollowButton from "Element/FollowButton";
|
||||
import { extractLnAddress, parseId, hexToBech32 } from "Util";
|
||||
import Avatar from "Element/Avatar";
|
||||
@ -36,6 +39,7 @@ enum ProfileTab {
|
||||
Reactions = "Reactions",
|
||||
Followers = "Followers",
|
||||
Follows = "Follows",
|
||||
Zaps = "Zaps",
|
||||
Muted = "Muted",
|
||||
Blocked = "Blocked"
|
||||
};
|
||||
@ -58,6 +62,13 @@ export default function ProfilePage() {
|
||||
const website_url = (user?.website && !user.website.startsWith("http"))
|
||||
? "https://" + user.website
|
||||
: user?.website || "";
|
||||
const zapFeed = useZapsFeed(id)
|
||||
const zaps = useMemo(() => {
|
||||
const profileZaps = zapFeed.store.notes.map(parseZap).filter(z => z.valid && z.p === id && !z.e && z.zapper !== id)
|
||||
profileZaps.sort((a, b) => b.amount - a.amount)
|
||||
return profileZaps
|
||||
}, [zapFeed.store.notes, id])
|
||||
const zapsTotal = zaps.reduce((acc, z) => acc + z.amount, 0)
|
||||
|
||||
useEffect(() => {
|
||||
setTab(ProfileTab.Notes);
|
||||
@ -89,7 +100,7 @@ export default function ProfilePage() {
|
||||
</div>
|
||||
)}
|
||||
|
||||
<LNURLTip svc={lnurl} show={showLnQr} onClose={() => setShowLnQr(false)} />
|
||||
<LNURLTip svc={lnurl} show={showLnQr} onClose={() => setShowLnQr(false)} author={id} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@ -109,6 +120,14 @@ export default function ProfilePage() {
|
||||
switch (tab) {
|
||||
case ProfileTab.Notes:
|
||||
return <Timeline key={id} subject={{ type: "pubkey", items: [id], discriminator: id.slice(0, 12) }} postsOnly={false} method={"LIMIT_UNTIL"} ignoreModeration={true} />;
|
||||
case ProfileTab.Zaps: {
|
||||
return (
|
||||
<div className="main-content">
|
||||
{zaps.map(z => <ZapElement showZapped={false} zap={z} />)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
case ProfileTab.Follows: {
|
||||
if (isMe) {
|
||||
return (
|
||||
@ -163,6 +182,9 @@ export default function ProfilePage() {
|
||||
<>
|
||||
<IconButton onClick={() => setShowLnQr(true)}>
|
||||
<Zap width={14} height={16} />
|
||||
<span className="zap-amount">
|
||||
{zapsTotal > 0 && formatShort(zapsTotal)}
|
||||
</span>
|
||||
</IconButton>
|
||||
{!loggedOut && (
|
||||
<>
|
||||
@ -205,7 +227,7 @@ export default function ProfilePage() {
|
||||
</div>
|
||||
</div>
|
||||
<div className="tabs">
|
||||
{[ProfileTab.Notes, ProfileTab.Followers, ProfileTab.Follows, ProfileTab.Muted].map(renderTab)}
|
||||
{[ProfileTab.Notes, ProfileTab.Followers, ProfileTab.Follows, ProfileTab.Zaps, ProfileTab.Muted].map(renderTab)}
|
||||
{isMe && renderTab(ProfileTab.Blocked)}
|
||||
</div>
|
||||
{tabContent()}
|
||||
|
@ -1,8 +1,13 @@
|
||||
import * as secp from "@noble/secp256k1";
|
||||
import { sha256 as hash } from '@noble/hashes/sha256';
|
||||
import { bech32 } from "bech32";
|
||||
import { HexKey, TaggedRawEvent, u256 } from "Nostr";
|
||||
import { HexKey, RawEvent, TaggedRawEvent, u256 } from "Nostr";
|
||||
import EventKind from "Nostr/EventKind";
|
||||
|
||||
export const sha256 = (str: string) => {
|
||||
return secp.utils.bytesToHex(hash(str))
|
||||
}
|
||||
|
||||
export async function openFile(): Promise<File | undefined> {
|
||||
return new Promise((resolve, reject) => {
|
||||
let elm = document.createElement("input");
|
||||
|
@ -1569,6 +1569,11 @@
|
||||
dependencies:
|
||||
eslint-scope "5.1.1"
|
||||
|
||||
"@noble/hashes@^1.2.0":
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.2.0.tgz#a3150eeb09cc7ab207ebf6d7b9ad311a9bdbed12"
|
||||
integrity sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==
|
||||
|
||||
"@noble/secp256k1@^1.7.0":
|
||||
version "1.7.1"
|
||||
resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.7.1.tgz#b251c70f824ce3ca7f8dc3df08d58f005cc0507c"
|
||||
|
This is wrong, were not using this format anymore, can you revert to previous?
The
description
tag contains the zap note and the hash of this should match the description hash of the invoiceThis is wrong, were not using this format anymore, can you revert to previous?
The
description
tag contains the zap note and the hash of this should match the description hash of the invoice