Fix zap request construction for newer nostr-tools types

The clean node_modules reinstall pulled newer @nostrify/* and nostr-tools
minors whose nip57.makeZapRequest signature changed (event param became a
required full NostrEvent), breaking tsc in useZaps and usePurchasePro.

Build the kind:9734 zap request events directly per NIP-57 instead of
relying on nip57.makeZapRequest, so we're decoupled from that helper's
changing type signature. Preserves correct target tagging:
- addressable events → 'a' tag (kind:pubkey:dTag)
- other events       → 'e' tag (event id)
- profile-only (pro purchase) → no event tag, keeps pro-tier/pro-expiry.

Pin @nostrify/nostrify, @nostrify/react and nostr-tools so the tree
stays reproducible.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
This commit is contained in:
shakespeare.diy 2026-09-03 22:14:46 +07:00
parent 0665d94a30
commit 144227b88b
4 changed files with 46 additions and 39 deletions

13
package-lock.json generated
View file

@ -1473,18 +1473,7 @@
"node_modules/@nostrify/nostrify": { "node_modules/@nostrify/nostrify": {
"version": "0.47.1", "version": "0.47.1",
"resolved": "https://registry.npmjs.org/@nostrify/nostrify/-/nostrify-0.47.1.tgz", "resolved": "https://registry.npmjs.org/@nostrify/nostrify/-/nostrify-0.47.1.tgz",
"integrity": "sha512-8jdAeKIyyDK/UQN92WgrQn9+B067HYcjfW35TpIjNLAT9qYe+KYFHaC9O6PD+I1DvLHziJMxk4Q18Fu4fqOiAQ==", "integrity": "sha512-8jdAeKIyyDK/UQN92WgrQn9+B067HYcjfW35TpIjNLAT9qYe+KYFHaC9O6PD+I1DvLHziJMxk4Q18Fu4fqOiAQ=="
"dependencies": {
"@nostrify/types": "0.36.7",
"@scure/base": "^1.2.6",
"@std/encoding": "npm:@jsr/std__encoding@^0.224.1",
"@types/node": "^24.1.0",
"lru-cache": "^10.2.0",
"nostr-tools": "^2.13.0",
"websocket-ts": "^2.2.1",
"ws": "^8.18.3",
"zod": "^3.23.8"
}
}, },
"node_modules/@nostrify/nostrify/node_modules/@scure/base": { "node_modules/@nostrify/nostrify/node_modules/@scure/base": {
"version": "1.2.6", "version": "1.2.6",

View file

@ -34,7 +34,7 @@
"@noble/curves": "^2.0.1", "@noble/curves": "^2.0.1",
"@noble/hashes": "^2.0.1", "@noble/hashes": "^2.0.1",
"@nostrify/nostrify": "^0.47.1", "@nostrify/nostrify": "^0.47.1",
"@nostrify/react": "^0.2.17", "@nostrify/react": "0.2.17",
"@radix-ui/react-accordion": "^1.2.0", "@radix-ui/react-accordion": "^1.2.0",
"@radix-ui/react-alert-dialog": "^1.1.1", "@radix-ui/react-alert-dialog": "^1.1.1",
"@radix-ui/react-aspect-ratio": "^1.1.0", "@radix-ui/react-aspect-ratio": "^1.1.0",
@ -89,7 +89,7 @@
"lucide-react": "^0.462.0", "lucide-react": "^0.462.0",
"ngeohash": "^0.6.3", "ngeohash": "^0.6.3",
"nostr-signer-capacitor-plugin": "github:coracle-social/nostr-signer-capacitor-plugin#main", "nostr-signer-capacitor-plugin": "github:coracle-social/nostr-signer-capacitor-plugin#main",
"nostr-tools": "^2.13.0", "nostr-tools": "2.13.0",
"npubcash-sdk": "^0.2.0", "npubcash-sdk": "^0.2.0",
"qrcode": "^1.5.4", "qrcode": "^1.5.4",
"react": "^18.3.1", "react": "^18.3.1",

View file

@ -16,7 +16,6 @@
import { useCallback, useState } from 'react'; import { useCallback, useState } from 'react';
import { useNostr } from '@nostrify/react'; import { useNostr } from '@nostrify/react';
import { nip57 } from 'nostr-tools';
import { useCurrentUser } from '@/hooks/useCurrentUser'; import { useCurrentUser } from '@/hooks/useCurrentUser';
import { useNWC } from '@/hooks/useNWCContext'; import { useNWC } from '@/hooks/useNWCContext';
import { useWallet } from '@/hooks/useWallet'; import { useWallet } from '@/hooks/useWallet';
@ -132,16 +131,22 @@ export function usePurchasePro() {
let invoice: string; let invoice: string;
if (providerPubkey) { if (providerPubkey) {
const zapRequest = nip57.makeZapRequest({ // Build the NIP-57 zap request event directly (profile zap, no event
profile: PLATFORM_PUBKEY, // target). Constructed by hand rather than via nip57.makeZapRequest so
event: null, // we're not coupled to that helper's changing type signature.
amount: amountMsats, const zapRequest = {
relays, kind: 9734,
comment, content: comment,
}); created_at: Math.floor(Date.now() / 1000),
// Tag the purchase so verification can read tier + expiry from the receipt. tags: [
zapRequest.tags.push(['pro-tier', tier.id]); ['relays', ...relays],
zapRequest.tags.push(['pro-expiry', String(expiry)]); ['amount', String(amountMsats)],
['p', PLATFORM_PUBKEY],
// Tag the purchase so verification can read tier + expiry from the receipt.
['pro-tier', tier.id],
['pro-expiry', String(expiry)],
] as string[][],
};
const signed = await user.signer.signEvent(zapRequest); const signed = await user.signer.signEvent(zapRequest);
invoice = await getZapInvoiceFromLightningAddress({ invoice = await getZapInvoiceFromLightningAddress({
lightningAddress: PRO_LIGHTNING_ADDRESS, lightningAddress: PRO_LIGHTNING_ADDRESS,

View file

@ -192,22 +192,35 @@ export function useZaps(
return; return;
} }
// Create zap request - use appropriate event format based on kind
// For addressable events (30000-39999), pass the object to get 'a' tag
// For all other events, pass the ID string to get 'e' tag
const event = (actualTarget.kind >= 30000 && actualTarget.kind < 40000)
? actualTarget
: actualTarget.id;
const zapAmount = amount * 1000; // convert to millisats const zapAmount = amount * 1000; // convert to millisats
const zapRequest = nip57.makeZapRequest({ // Build the NIP-57 zap request event directly. We construct it by hand
profile: actualTarget.pubkey, // (rather than nip57.makeZapRequest) so we're not coupled to that helper's
event: event, // changing type signature across nostr-tools versions, and so we can emit
amount: zapAmount, // the correct target tag:
relays: config.relayMetadata.relays.map(r => r.url), // - addressable events (30000-39999) → 'a' tag (kind:pubkey:dTag)
comment // - all other events → 'e' tag (event id)
}); const isAddressable =
actualTarget.kind >= 30000 && actualTarget.kind < 40000;
const zapTags: string[][] = [
['relays', ...config.relayMetadata.relays.map(r => r.url)],
['amount', String(zapAmount)],
['p', actualTarget.pubkey],
];
if (isAddressable) {
const dTag = actualTarget.tags.find(([n]) => n === 'd')?.[1] ?? '';
zapTags.push(['a', `${actualTarget.kind}:${actualTarget.pubkey}:${dTag}`]);
} else {
zapTags.push(['e', actualTarget.id]);
}
const zapRequest = {
kind: 9734,
content: comment ?? '',
tags: zapTags,
created_at: Math.floor(Date.now() / 1000),
};
// Sign the zap request (but don't publish to relays - only send to LNURL endpoint) // Sign the zap request (but don't publish to relays - only send to LNURL endpoint)
if (!user.signer) { if (!user.signer) {