refactor(relays): route every relay consumer through useRelays()
So Local relays are used and Blocked relays are excluded EVERYWHERE, not just in the NPool routers: - useListingReports, useSellerInfo, useSkateRelays (read+write), useZaps (NIP-57 relays tag), usePurchasePro, CollectionDetailPage, CrewForm, useDirectMessages write fallback - AppProvider's empty-relays defaults check is the only intentional direct reader - AGENTS.md updated Gate: 101 tests, 0 errors/warnings, boot smoke green.
This commit is contained in:
parent
5d1a0e0fb0
commit
21a0390ed5
9 changed files with 39 additions and 59 deletions
10
AGENTS.md
10
AGENTS.md
|
|
@ -66,10 +66,12 @@ session with **no other memory of this project**. So:
|
||||||
"Trusted" (no distinct behaviour — would be empty UI), and Amethyst's proxy/
|
"Trusted" (no distinct behaviour — would be empty UI), and Amethyst's proxy/
|
||||||
broadcast/private-home (we don't have that relay-discovery model) — don't add
|
broadcast/private-home (we don't have that relay-discovery model) — don't add
|
||||||
UI for features we don't implement.
|
UI for features we don't implement.
|
||||||
- ⚠️ A few hooks build relay lists directly from `config.relayMetadata.relays`
|
- All relay consumers now go through **`useRelays()`** (read/write — blocklist
|
||||||
(listing reports, seller info, skate relays, zaps) and therefore do NOT yet
|
applied, local included): listing reports, seller info, skate relays, zaps,
|
||||||
honour Local/Blocked — migrate them to `useRelays()` when touched. DMs are
|
Sasquatch purchase, collections, crew form, and DMs. AppProvider's
|
||||||
migrated, but their DM relays aren't block-filtered either.
|
empty-relays defaults check is the only intentional direct reader.
|
||||||
|
- ⚠️ DM **inbox** relays (kind 10050) are delivered-to/read-from but are not
|
||||||
|
yet block-filtered (they're a separate list from the NIP-65 `relays`).
|
||||||
- **Group DMs**: NIP-17 (`useDirectMessages`, `GroupConversationPage`).
|
- **Group DMs**: NIP-17 (`useDirectMessages`, `GroupConversationPage`).
|
||||||
- **Mints directory**: `/mints` page lists Cashu mints from the community
|
- **Mints directory**: `/mints` page lists Cashu mints from the community
|
||||||
**MintRadar** project. MintRadar has **no CORS**, so it's fetched same-origin
|
**MintRadar** project. MintRadar has **no CORS**, so it's fetched same-origin
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ import { CrewSponsorPicker } from '@/components/crew/CrewSponsorPicker';
|
||||||
import { NofferField } from '@/components/NofferField';
|
import { NofferField } from '@/components/NofferField';
|
||||||
import { SKATE_CREW_KIND, SKATE_SPOT_KIND, SKATE_SHOP_KIND, parseAddrCoord, ZAP_GOAL_KIND, CREW_VIBE_LABELS, CREW_FOCUS_LABELS, CREW_FOCUS_DESCRIPTIONS, CREW_FOCUS_TAG, CREW_LOOKING_FOR_OPTIONS, CREW_ROLE_META, CREW_ROLE_ORDER, SHOW_CREW_TREASURY, isValidNoffer, type SkateCrew, type CrewFocus, type CrewRole } from '@/lib/types';
|
import { SKATE_CREW_KIND, SKATE_SPOT_KIND, SKATE_SHOP_KIND, parseAddrCoord, ZAP_GOAL_KIND, CREW_VIBE_LABELS, CREW_FOCUS_LABELS, CREW_FOCUS_DESCRIPTIONS, CREW_FOCUS_TAG, CREW_LOOKING_FOR_OPTIONS, CREW_ROLE_META, CREW_ROLE_ORDER, SHOW_CREW_TREASURY, isValidNoffer, type SkateCrew, type CrewFocus, type CrewRole } from '@/lib/types';
|
||||||
import { useCrewGoal } from '@/hooks/useCrewGoal';
|
import { useCrewGoal } from '@/hooks/useCrewGoal';
|
||||||
import { useAppContext } from '@/hooks/useAppContext';
|
import { useRelays } from '@/lib/relays';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
import { Users, Upload, X, Loader2, MapPin, Plus, ShieldCheck, AtSign, HardHat, Camera, GraduationCap, Sparkles, Target, Megaphone, Music, Palette, Dumbbell, Eye, Store, Film, Check, ArrowRight, ArrowLeft as ArrowLeftIcon, Server } from 'lucide-react';
|
import { Users, Upload, X, Loader2, MapPin, Plus, ShieldCheck, AtSign, HardHat, Camera, GraduationCap, Sparkles, Target, Megaphone, Music, Palette, Dumbbell, Eye, Store, Film, Check, ArrowRight, ArrowLeft as ArrowLeftIcon, Server } from 'lucide-react';
|
||||||
|
|
||||||
|
|
@ -286,7 +286,7 @@ export function CrewForm({ existing }: CrewFormProps) {
|
||||||
|
|
||||||
// Crew treasury (NIP-75 zap goal). Load existing goal to prefill when editing.
|
// Crew treasury (NIP-75 zap goal). Load existing goal to prefill when editing.
|
||||||
const { data: existingGoal } = useCrewGoal(existing?.goalRef);
|
const { data: existingGoal } = useCrewGoal(existing?.goalRef);
|
||||||
const { config } = useAppContext();
|
const { write } = useRelays();
|
||||||
const [goalEnabled, setGoalEnabled] = useState(!!existing?.goalRef);
|
const [goalEnabled, setGoalEnabled] = useState(!!existing?.goalRef);
|
||||||
const [goalTitle, setGoalTitle] = useState('');
|
const [goalTitle, setGoalTitle] = useState('');
|
||||||
const [goalTarget, setGoalTarget] = useState('');
|
const [goalTarget, setGoalTarget] = useState('');
|
||||||
|
|
@ -420,7 +420,7 @@ export function CrewForm({ existing }: CrewFormProps) {
|
||||||
let goalRef: string | undefined = existing?.goalRef;
|
let goalRef: string | undefined = existing?.goalRef;
|
||||||
const targetSats = parseInt(goalTarget, 10);
|
const targetSats = parseInt(goalTarget, 10);
|
||||||
if (goalEnabled && goalTitle.trim() && targetSats > 0) {
|
if (goalEnabled && goalTitle.trim() && targetSats > 0) {
|
||||||
const relayUrls = config.relayMetadata.relays.filter((r) => r.write).map((r) => r.url);
|
const relayUrls = write;
|
||||||
const needsNewGoal =
|
const needsNewGoal =
|
||||||
!existingGoal ||
|
!existingGoal ||
|
||||||
existingGoal.description !== goalTitle.trim() ||
|
existingGoal.description !== goalTitle.trim() ||
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import { useNostrLogin } from '@nostrify/react/login';
|
||||||
import { useCurrentUser } from './useCurrentUser';
|
import { useCurrentUser } from './useCurrentUser';
|
||||||
import { useAppContext } from './useAppContext';
|
import { useAppContext } from './useAppContext';
|
||||||
import { hasNip44 as checkNip44, isInteractiveSigner } from '@/lib/signerCapabilities';
|
import { hasNip44 as checkNip44, isInteractiveSigner } from '@/lib/signerCapabilities';
|
||||||
|
import { useRelays } from '@/lib/relays';
|
||||||
import type { RelayMetadata } from '@/contexts/AppContext';
|
import type { RelayMetadata } from '@/contexts/AppContext';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -124,6 +125,7 @@ export function useSendDirectMessage() {
|
||||||
const { nostr } = useNostr();
|
const { nostr } = useNostr();
|
||||||
const { user } = useCurrentUser();
|
const { user } = useCurrentUser();
|
||||||
const { config } = useAppContext();
|
const { config } = useAppContext();
|
||||||
|
const { write } = useRelays();
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
const sendMessage = useCallback(async (
|
const sendMessage = useCallback(async (
|
||||||
|
|
@ -189,9 +191,7 @@ export function useSendDirectMessage() {
|
||||||
// 4. Deliver to NIP-17 DM relays (kind 10050): the recipients' inboxes plus
|
// 4. Deliver to NIP-17 DM relays (kind 10050): the recipients' inboxes plus
|
||||||
// our own, so both sides can read from their DM relays. Fall back to the
|
// our own, so both sides can read from their DM relays. Fall back to the
|
||||||
// NIP-65 write relays when nobody has published a DM relay list.
|
// NIP-65 write relays when nobody has published a DM relay list.
|
||||||
const writeRelays = config.relayMetadata.relays
|
const writeRelays = write;
|
||||||
.filter(r => r.write)
|
|
||||||
.map(r => r.url);
|
|
||||||
|
|
||||||
const dmTargets = [...new Set([...recipients, user.pubkey])];
|
const dmTargets = [...new Set([...recipients, user.pubkey])];
|
||||||
const deliverRelays = new Set<string>(config.relayMetadata.dmRelays ?? []);
|
const deliverRelays = new Set<string>(config.relayMetadata.dmRelays ?? []);
|
||||||
|
|
@ -230,7 +230,7 @@ export function useSendDirectMessage() {
|
||||||
queryClient.invalidateQueries({ queryKey: ['group-conversations'] });
|
queryClient.invalidateQueries({ queryKey: ['group-conversations'] });
|
||||||
}
|
}
|
||||||
|
|
||||||
}, [user, nostr, config, queryClient]);
|
}, [user, nostr, config, write, queryClient]);
|
||||||
|
|
||||||
return useMutation({
|
return useMutation({
|
||||||
mutationFn: async ({ recipients, content, replyTo, subject }: {
|
mutationFn: async ({ recipients, content, replyTo, subject }: {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { useNostr } from '@nostrify/react';
|
import { useNostr } from '@nostrify/react';
|
||||||
import { useQuery } from '@tanstack/react-query';
|
import { useQuery } from '@tanstack/react-query';
|
||||||
import type { NostrEvent } from '@nostrify/nostrify';
|
import type { NostrEvent } from '@nostrify/nostrify';
|
||||||
import { useAppContext } from '@/hooks/useAppContext';
|
import { useRelays } from '@/lib/relays';
|
||||||
|
|
||||||
const REPORT_KIND = 1984; // NIP-56 Report kind
|
const REPORT_KIND = 1984; // NIP-56 Report kind
|
||||||
|
|
||||||
|
|
@ -21,13 +21,9 @@ export interface ListingReport {
|
||||||
*/
|
*/
|
||||||
export function useListingReports(eventId: string, pubkey: string) {
|
export function useListingReports(eventId: string, pubkey: string) {
|
||||||
const { nostr } = useNostr();
|
const { nostr } = useNostr();
|
||||||
const { config } = useAppContext();
|
const { read } = useRelays();
|
||||||
|
|
||||||
const relayUrls = config.relayMetadata.relays
|
const relayUrls = read.slice().sort().join(',');
|
||||||
.filter(r => r.read)
|
|
||||||
.map(r => r.url)
|
|
||||||
.sort()
|
|
||||||
.join(',');
|
|
||||||
|
|
||||||
return useQuery({
|
return useQuery({
|
||||||
queryKey: ['listing-reports', eventId, relayUrls],
|
queryKey: ['listing-reports', eventId, relayUrls],
|
||||||
|
|
@ -35,9 +31,7 @@ export function useListingReports(eventId: string, pubkey: string) {
|
||||||
const signal = AbortSignal.any([c.signal, AbortSignal.timeout(8000)]);
|
const signal = AbortSignal.any([c.signal, AbortSignal.timeout(8000)]);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const readRelays = config.relayMetadata.relays
|
const readRelays = read;
|
||||||
.filter(r => r.read)
|
|
||||||
.map(r => r.url);
|
|
||||||
|
|
||||||
const allEvents: NostrEvent[] = [];
|
const allEvents: NostrEvent[] = [];
|
||||||
|
|
||||||
|
|
@ -115,13 +109,9 @@ export function useListingReports(eventId: string, pubkey: string) {
|
||||||
*/
|
*/
|
||||||
export function useBatchListingReports(eventIds: string[]) {
|
export function useBatchListingReports(eventIds: string[]) {
|
||||||
const { nostr } = useNostr();
|
const { nostr } = useNostr();
|
||||||
const { config } = useAppContext();
|
const { read } = useRelays();
|
||||||
|
|
||||||
const relayUrls = config.relayMetadata.relays
|
const relayUrls = read.slice().sort().join(',');
|
||||||
.filter(r => r.read)
|
|
||||||
.map(r => r.url)
|
|
||||||
.sort()
|
|
||||||
.join(',');
|
|
||||||
|
|
||||||
return useQuery({
|
return useQuery({
|
||||||
queryKey: ['batch-listing-reports', eventIds.sort().join(','), relayUrls],
|
queryKey: ['batch-listing-reports', eventIds.sort().join(','), relayUrls],
|
||||||
|
|
@ -137,9 +127,7 @@ export function useBatchListingReports(eventIds: string[]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const readRelays = config.relayMetadata.relays
|
const readRelays = read;
|
||||||
.filter(r => r.read)
|
|
||||||
.map(r => r.url);
|
|
||||||
|
|
||||||
const allEvents: NostrEvent[] = [];
|
const allEvents: NostrEvent[] = [];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ import { useNostr } from '@nostrify/react';
|
||||||
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';
|
||||||
import { useAppContext } from '@/hooks/useAppContext';
|
import { useRelays } from '@/lib/relays';
|
||||||
import { useSendDirectMessage } from '@/hooks/useDirectMessages';
|
import { useSendDirectMessage } from '@/hooks/useDirectMessages';
|
||||||
import { PLATFORM_OWNER_PUBKEYS } from '@/hooks/useListingRestrictions';
|
import { PLATFORM_OWNER_PUBKEYS } from '@/hooks/useListingRestrictions';
|
||||||
import {
|
import {
|
||||||
|
|
@ -46,7 +46,7 @@ export function usePurchasePro() {
|
||||||
const { user } = useCurrentUser();
|
const { user } = useCurrentUser();
|
||||||
const { getActiveConnection, sendPayment } = useNWC();
|
const { getActiveConnection, sendPayment } = useNWC();
|
||||||
const { webln } = useWallet();
|
const { webln } = useWallet();
|
||||||
const { config } = useAppContext();
|
const { read, write } = useRelays();
|
||||||
const { mutateAsync: sendDM } = useSendDirectMessage();
|
const { mutateAsync: sendDM } = useSendDirectMessage();
|
||||||
|
|
||||||
const [result, setResult] = useState<PurchaseResult>({ invoice: null, state: 'idle', error: null });
|
const [result, setResult] = useState<PurchaseResult>({ invoice: null, state: 'idle', error: null });
|
||||||
|
|
@ -121,7 +121,7 @@ export function usePurchasePro() {
|
||||||
const now = Math.floor(Date.now() / 1000);
|
const now = Math.floor(Date.now() / 1000);
|
||||||
const expiry = now + tier.days * DAY_SECONDS;
|
const expiry = now + tier.days * DAY_SECONDS;
|
||||||
const amountMsats = tier.sats * 1000;
|
const amountMsats = tier.sats * 1000;
|
||||||
const relays = config.relayMetadata.relays.map((r) => r.url);
|
const relays = [...new Set([...read, ...write])];
|
||||||
const comment = `Sasquatch Pro — ${tier.label} 🦧`;
|
const comment = `Sasquatch Pro — ${tier.label} 🦧`;
|
||||||
|
|
||||||
// Try a NIP-57 zap first (unforgeable, npub-bound). Fall back to a plain
|
// Try a NIP-57 zap first (unforgeable, npub-bound). Fall back to a plain
|
||||||
|
|
@ -198,7 +198,7 @@ export function usePurchasePro() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[user, config, getActiveConnection, sendPayment, webln, publishReceipt, sendConfirmationDM],
|
[user, read, write, getActiveConnection, sendPayment, webln, publishReceipt, sendConfirmationDM],
|
||||||
);
|
);
|
||||||
|
|
||||||
/** Called after a manual (QR) payment to record the pass locally. */
|
/** Called after a manual (QR) payment to record the pass locally. */
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import { useNostr } from '@nostrify/react';
|
||||||
import { useQuery } from '@tanstack/react-query';
|
import { useQuery } from '@tanstack/react-query';
|
||||||
import type { NostrEvent } from '@nostrify/nostrify';
|
import type { NostrEvent } from '@nostrify/nostrify';
|
||||||
import { MARKETPLACE_ITEM_KIND } from '@/lib/types';
|
import { MARKETPLACE_ITEM_KIND } from '@/lib/types';
|
||||||
import { useAppContext } from '@/hooks/useAppContext';
|
import { useRelays } from '@/lib/relays';
|
||||||
|
|
||||||
export interface SellerInfo {
|
export interface SellerInfo {
|
||||||
pubkey: string;
|
pubkey: string;
|
||||||
|
|
@ -19,13 +19,9 @@ export interface SellerInfo {
|
||||||
*/
|
*/
|
||||||
export function useSellerInfo(pubkey: string | undefined) {
|
export function useSellerInfo(pubkey: string | undefined) {
|
||||||
const { nostr } = useNostr();
|
const { nostr } = useNostr();
|
||||||
const { config } = useAppContext();
|
const { read } = useRelays();
|
||||||
|
|
||||||
const relayUrls = config.relayMetadata.relays
|
const relayUrls = read.slice().sort().join(',');
|
||||||
.filter(r => r.read)
|
|
||||||
.map(r => r.url)
|
|
||||||
.sort()
|
|
||||||
.join(',');
|
|
||||||
|
|
||||||
return useQuery({
|
return useQuery({
|
||||||
queryKey: ['seller-info', pubkey, relayUrls],
|
queryKey: ['seller-info', pubkey, relayUrls],
|
||||||
|
|
@ -35,9 +31,7 @@ export function useSellerInfo(pubkey: string | undefined) {
|
||||||
const signal = AbortSignal.any([c.signal, AbortSignal.timeout(10000)]);
|
const signal = AbortSignal.any([c.signal, AbortSignal.timeout(10000)]);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const readRelays = config.relayMetadata.relays
|
const readRelays = read;
|
||||||
.filter(r => r.read)
|
|
||||||
.map(r => r.url);
|
|
||||||
|
|
||||||
// Query profile (kind 0) and marketplace listings in parallel
|
// Query profile (kind 0) and marketplace listings in parallel
|
||||||
const profileEventsPromise: Promise<NostrEvent[]>[] = [];
|
const profileEventsPromise: Promise<NostrEvent[]>[] = [];
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import { useNostr } from '@nostrify/react';
|
import { useNostr } from '@nostrify/react';
|
||||||
import { useCurrentUser } from '@/hooks/useCurrentUser';
|
import { useCurrentUser } from '@/hooks/useCurrentUser';
|
||||||
import { useAppContext } from '@/hooks/useAppContext';
|
import { useAppContext } from '@/hooks/useAppContext';
|
||||||
|
import { useRelays } from '@/lib/relays';
|
||||||
import { useCitrine } from '@/hooks/useCitrine';
|
import { useCitrine } from '@/hooks/useCitrine';
|
||||||
import { SKATE_RELAY } from '@/lib/types';
|
import { SKATE_RELAY } from '@/lib/types';
|
||||||
import type { NostrEvent, NostrFilter } from '@nostrify/nostrify';
|
import type { NostrEvent, NostrFilter } from '@nostrify/nostrify';
|
||||||
|
|
@ -17,6 +18,7 @@ export function useSkateRelays() {
|
||||||
const { nostr } = useNostr();
|
const { nostr } = useNostr();
|
||||||
const { user } = useCurrentUser();
|
const { user } = useCurrentUser();
|
||||||
const { config } = useAppContext();
|
const { config } = useAppContext();
|
||||||
|
const { read, write } = useRelays();
|
||||||
const citrine = useCitrine();
|
const citrine = useCitrine();
|
||||||
|
|
||||||
const isLoggedIn = !!user;
|
const isLoggedIn = !!user;
|
||||||
|
|
@ -43,9 +45,7 @@ export function useSkateRelays() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Logged in: check setting
|
// Logged in: check setting
|
||||||
const userRelays = config.relayMetadata.relays
|
const userRelays = read;
|
||||||
.filter(r => r.read)
|
|
||||||
.map(r => r.url);
|
|
||||||
|
|
||||||
if (useSkateRelay) {
|
if (useSkateRelay) {
|
||||||
// Include community relay + user relays (deduplicated)
|
// Include community relay + user relays (deduplicated)
|
||||||
|
|
@ -67,9 +67,7 @@ export function useSkateRelays() {
|
||||||
return [SKATE_RELAY];
|
return [SKATE_RELAY];
|
||||||
}
|
}
|
||||||
|
|
||||||
const userRelays = config.relayMetadata.relays
|
const userRelays = write;
|
||||||
.filter(r => r.write)
|
|
||||||
.map(r => r.url);
|
|
||||||
|
|
||||||
if (useSkateRelay) {
|
if (useSkateRelay) {
|
||||||
// Include community relay + user relays (deduplicated)
|
// Include community relay + user relays (deduplicated)
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { useState, useMemo, useEffect, useCallback } from 'react';
|
import { useState, useMemo, useEffect, useCallback } from 'react';
|
||||||
import { useCurrentUser } from '@/hooks/useCurrentUser';
|
import { useCurrentUser } from '@/hooks/useCurrentUser';
|
||||||
import { useAuthor } from '@/hooks/useAuthor';
|
import { useAuthor } from '@/hooks/useAuthor';
|
||||||
import { useAppContext } from '@/hooks/useAppContext';
|
import { useRelays } from '@/lib/relays';
|
||||||
import { useToast } from '@/hooks/useToast';
|
import { useToast } from '@/hooks/useToast';
|
||||||
import { useNWC } from '@/hooks/useNWCContext';
|
import { useNWC } from '@/hooks/useNWCContext';
|
||||||
import type { NWCConnection } from '@/hooks/useNWC';
|
import type { NWCConnection } from '@/hooks/useNWC';
|
||||||
|
|
@ -23,7 +23,7 @@ export function useZaps(
|
||||||
const { nostr } = useNostr();
|
const { nostr } = useNostr();
|
||||||
const { toast } = useToast();
|
const { toast } = useToast();
|
||||||
const { user } = useCurrentUser();
|
const { user } = useCurrentUser();
|
||||||
const { config } = useAppContext();
|
const { read, write } = useRelays();
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
// Handle the case where an empty array is passed (from ZapButton when external data is provided)
|
// Handle the case where an empty array is passed (from ZapButton when external data is provided)
|
||||||
|
|
@ -162,7 +162,7 @@ export function useZaps(
|
||||||
|
|
||||||
const isAddressable = actualTarget.kind >= 30000 && actualTarget.kind < 40000;
|
const isAddressable = actualTarget.kind >= 30000 && actualTarget.kind < 40000;
|
||||||
const zapTags: string[][] = [
|
const zapTags: string[][] = [
|
||||||
['relays', ...config.relayMetadata.relays.map((r) => r.url)],
|
['relays', ...read, ...write],
|
||||||
['amount', String(zapAmount)],
|
['amount', String(zapAmount)],
|
||||||
['p', actualTarget.pubkey],
|
['p', actualTarget.pubkey],
|
||||||
];
|
];
|
||||||
|
|
@ -202,7 +202,7 @@ export function useZaps(
|
||||||
assertInvoiceAmount(newInvoice, amount);
|
assertInvoiceAmount(newInvoice, amount);
|
||||||
|
|
||||||
return newInvoice;
|
return newInvoice;
|
||||||
}, [user, actualTarget, author.data, config.relayMetadata.relays]);
|
}, [user, actualTarget, author.data, read, write]);
|
||||||
|
|
||||||
const zap = async (amount: number, comment: string) => {
|
const zap = async (amount: number, comment: string) => {
|
||||||
if (amount <= 0) {
|
if (amount <= 0) {
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ import { Badge } from '@/components/ui/badge';
|
||||||
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle } from '@/components/ui/alert-dialog';
|
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle } from '@/components/ui/alert-dialog';
|
||||||
import { useToast } from '@/hooks/useToast';
|
import { useToast } from '@/hooks/useToast';
|
||||||
import { useCurrentUser } from '@/hooks/useCurrentUser';
|
import { useCurrentUser } from '@/hooks/useCurrentUser';
|
||||||
import { useAppContext } from '@/hooks/useAppContext';
|
import { useRelays } from '@/lib/relays';
|
||||||
import { useSpotCollection, useRemoveSpotFromCollection, useDeleteSpotCollection } from '@/hooks/useSpotCollections';
|
import { useSpotCollection, useRemoveSpotFromCollection, useDeleteSpotCollection } from '@/hooks/useSpotCollections';
|
||||||
import type { NostrEvent } from '@nostrify/nostrify';
|
import type { NostrEvent } from '@nostrify/nostrify';
|
||||||
import { SKATE_SPOT_KIND, parseSkateSpot, type SkateSpot } from '@/lib/types';
|
import { SKATE_SPOT_KIND, parseSkateSpot, type SkateSpot } from '@/lib/types';
|
||||||
|
|
@ -46,7 +46,7 @@ export default function CollectionDetailPage() {
|
||||||
const { data: collection, isLoading, error, refetch } = useSpotCollection(identifier || '', pubkey);
|
const { data: collection, isLoading, error, refetch } = useSpotCollection(identifier || '', pubkey);
|
||||||
const { user } = useCurrentUser();
|
const { user } = useCurrentUser();
|
||||||
const { nostr } = useNostr();
|
const { nostr } = useNostr();
|
||||||
const { config } = useAppContext();
|
const { read } = useRelays();
|
||||||
const { removeSpotFromCollection, isPending: isRemoving } = useRemoveSpotFromCollection();
|
const { removeSpotFromCollection, isPending: isRemoving } = useRemoveSpotFromCollection();
|
||||||
const { deleteCollection, isPending: isDeleting } = useDeleteSpotCollection();
|
const { deleteCollection, isPending: isDeleting } = useDeleteSpotCollection();
|
||||||
const { toast } = useToast();
|
const { toast } = useToast();
|
||||||
|
|
@ -69,9 +69,7 @@ export default function CollectionDetailPage() {
|
||||||
if (!collection || collection.spotRefs.length === 0) return [];
|
if (!collection || collection.spotRefs.length === 0) return [];
|
||||||
|
|
||||||
const signal = AbortSignal.any([c.signal, AbortSignal.timeout(15000)]);
|
const signal = AbortSignal.any([c.signal, AbortSignal.timeout(15000)]);
|
||||||
const readRelays = config.relayMetadata.relays
|
const readRelays = read;
|
||||||
.filter(r => r.read)
|
|
||||||
.map(r => r.url);
|
|
||||||
|
|
||||||
// Parse spot references to build filters
|
// Parse spot references to build filters
|
||||||
const spotFilters = collection.spotRefs.map((ref) => {
|
const spotFilters = collection.spotRefs.map((ref) => {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue