relax zaps validation

This commit is contained in:
Kieran 2023-10-11 10:03:52 +01:00
parent bcaaba3fd4
commit 3b505f6c3e
Signed by: Kieran
GPG Key ID: DE71CEB3925BE941
1 changed files with 27 additions and 21 deletions

View File

@ -1,9 +1,13 @@
import { FeedCache } from "@snort/shared"; import { FeedCache } from "@snort/shared";
import { sha256, decodeInvoice, InvoiceDetails } from "@snort/shared"; import { decodeInvoice, InvoiceDetails } from "@snort/shared";
import { HexKey, NostrEvent } from "./nostr"; import { NostrEvent } from "./nostr";
import { findTag } from "./utils"; import { findTag } from "./utils";
import { MetadataCache } from "./cache"; import { MetadataCache } from "./cache";
import { EventExt } from "./event-ext";
import { NostrLink } from "./nostr-link";
import debug from "debug";
const Log = debug("zaps");
const ParsedZapCache = new Map<string, ParsedZap>(); const ParsedZapCache = new Map<string, ParsedZap>();
function getInvoice(zap: NostrEvent): InvoiceDetails | undefined { function getInvoice(zap: NostrEvent): InvoiceDetails | undefined {
@ -32,15 +36,17 @@ export function parseZap(zapReceipt: NostrEvent, userCache: FeedCache<MetadataCa
// old format, ignored // old format, ignored
throw new Error("deprecated zap format"); throw new Error("deprecated zap format");
} }
const zapRequestThread = EventExt.extractThread(zapRequest);
const requestContext = zapRequestThread?.root;
const isForwardedZap = refNote?.tags.some(a => a[0] === "zap") ?? false; const isForwardedZap = refNote?.tags.some(a => a[0] === "zap") ?? false;
const anonZap = zapRequest.tags.find(a => a[0] === "anon"); const anonZap = zapRequest.tags.find(a => a[0] === "anon");
const metaHash = sha256(innerZapJson);
const pollOpt = zapRequest.tags.find(a => a[0] === "poll_option")?.[1]; const pollOpt = zapRequest.tags.find(a => a[0] === "poll_option")?.[1];
const ret: ParsedZap = { const ret: ParsedZap = {
id: zapReceipt.id, id: zapReceipt.id,
zapService: zapReceipt.pubkey, zapService: zapReceipt.pubkey,
amount: (invoice?.amount ?? 0) / 1000, amount: (invoice?.amount ?? 0) / 1000,
event: findTag(zapRequest, "e"), event: requestContext ? NostrLink.fromThreadTag(requestContext) : undefined,
sender: zapRequest.pubkey, sender: zapRequest.pubkey,
receiver: findTag(zapRequest, "p"), receiver: findTag(zapRequest, "p"),
valid: true, valid: true,
@ -49,18 +55,10 @@ export function parseZap(zapReceipt: NostrEvent, userCache: FeedCache<MetadataCa
errors: [], errors: [],
pollOption: pollOpt ? Number(pollOpt) : undefined, pollOption: pollOpt ? Number(pollOpt) : undefined,
}; };
if (invoice?.descriptionHash !== metaHash) {
ret.valid = false;
ret.errors.push("description_hash does not match zap request");
}
if (findTag(zapRequest, "p") !== findTag(zapReceipt, "p")) { if (findTag(zapRequest, "p") !== findTag(zapReceipt, "p")) {
ret.valid = false; ret.valid = false;
ret.errors.push("p tags dont match"); ret.errors.push("p tags dont match");
} }
if (ret.event && ret.event !== findTag(zapReceipt, "e")) {
ret.valid = false;
ret.errors.push("e tags dont match");
}
if (findTag(zapRequest, "amount") === invoice?.amount) { if (findTag(zapRequest, "amount") === invoice?.amount) {
ret.valid = false; ret.valid = false;
ret.errors.push("amount tag does not match invoice amount"); ret.errors.push("amount tag does not match invoice amount");
@ -69,9 +67,13 @@ export function parseZap(zapReceipt: NostrEvent, userCache: FeedCache<MetadataCa
ret.valid = false; ret.valid = false;
ret.errors.push("zap service pubkey doesn't match"); ret.errors.push("zap service pubkey doesn't match");
} }
if (!ret.valid) {
Log("Invalid zap %O", ret);
}
return ret; return ret;
} catch (e) { } catch {
// ignored: console.debug("Invalid zap", zapReceipt, e); // ignored
} }
} }
const ret = { const ret = {
@ -82,20 +84,24 @@ export function parseZap(zapReceipt: NostrEvent, userCache: FeedCache<MetadataCa
anonZap: false, anonZap: false,
errors: ["invalid zap, parsing failed"], errors: ["invalid zap, parsing failed"],
}; };
if (!ret.valid) {
Log("Invalid zap %O", ret);
}
ParsedZapCache.set(ret.id, ret); ParsedZapCache.set(ret.id, ret);
return ret; return ret;
} }
export interface ParsedZap { export interface ParsedZap {
id: HexKey; id: string;
event?: HexKey;
receiver?: HexKey;
amount: number; amount: number;
content?: string; zapService: string;
sender?: HexKey;
valid: boolean; valid: boolean;
zapService: HexKey;
anonZap: boolean;
errors: Array<string>; errors: Array<string>;
anonZap: boolean;
event?: NostrLink;
receiver?: string;
content?: string;
sender?: string;
pollOption?: number; pollOption?: number;
} }