Skip to content

Commit 971240e

Browse files
committed
Remove legacy relay URL configuration and add automatic default icon management
- Remove REACT_APP_OWN_RELAY_URL requirement from config and environment - Simplify NDK configuration to use default relay URLs only - Add automatic relay icon management with domain-aware default logo - Relay icon now defaults to logo-dark-192.png served from current domain - Auto-updates icon URL when domain changes (localhost to production) - Remove obsolete blossomUpload.ts (replaced by panel API) - Update documentation to reflect simplified configuration - Add profile API system with caching and default profile pictures - Clean up unused relay URL references across codebase
1 parent 0c783f6 commit 971240e

12 files changed

Lines changed: 529 additions & 720 deletions

File tree

README.md

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,6 @@ REACT_APP_DEMO_MODE=false
158158
REACT_APP_BASENAME=
159159
160160
# Nostr relay configuration for profile fetching
161-
REACT_APP_OWN_RELAY_URL=ws://localhost:9001
162161
# REACT_APP_NOSTR_RELAY_URLS=wss://your-relay1.com,wss://your-relay2.com,wss://your-relay3.com
163162
164163
# More info https://create-react-app.dev/docs/advanced-configuration
@@ -177,7 +176,6 @@ REACT_APP_DEMO_MODE=false
177176
178177
# Service URLs
179178
# REACT_APP_WALLET_BASE_URL - No longer needed! Wallet operations routed through panel API
180-
REACT_APP_OWN_RELAY_URL=ws://localhost:9001 # Required for profile fetching
181179
182180
# Router configuration (empty for direct access)
183181
REACT_APP_BASENAME=
@@ -193,10 +191,9 @@ TSC_COMPILE_ON_ERROR=true
193191

194192

195193
**🎯 Key Requirements**:
196-
-**Relay URL Required** - REACT_APP_OWN_RELAY_URL must be configured for profile fetching
197194
-**Wallet Always Available** - Wallet operations routed through panel API, no configuration needed
198195
-**Panel Routing Auto-Detection** - Panel paths (REACT_APP_BASENAME/PUBLIC_URL) can be auto-detected
199-
-**Simplified Configuration** - Only relay URL needs to be configured
196+
-**Simplified Configuration** - Uses default Nostr relay URLs, no custom configuration needed
200197
-**Simple Deployment** - No reverse proxy needed for basic functionality
201198

202199
### 4. Start Development Server
@@ -265,7 +262,6 @@ Controls the React app's routing base path:
265262
### Service URLs
266263
**🎯 Configuration Requirements**:
267264
- **Wallet Service**: No longer requires configuration! Wallet operations are routed through panel API (`/api/wallet-proxy/*`)
268-
- **Relay WebSocket**: `REACT_APP_OWN_RELAY_URL=ws://localhost:9001` (required for profile fetching)
269265
- **Panel API**: Auto-detected from current origin (no configuration needed)
270266

271267
**✅ Simplified**: Wallet functionality is now always available through the panel's backend proxy.

src/App.tsx

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,8 @@ import { useNDKInit } from '@nostr-dev-kit/ndk-hooks';
1818
import config from './config/config';
1919

2020
// Configure NDK with user's relay URLs from environment variables
21-
const getRelayUrls = () => {
22-
const relayUrls = [...config.nostrRelayUrls];
23-
24-
// Add user's own relay URL as the first priority if provided
25-
if (config.ownRelayUrl) {
26-
relayUrls.unshift(config.ownRelayUrl);
27-
}
28-
29-
return relayUrls;
30-
};
31-
3221
const ndk = new NDK({
33-
explicitRelayUrls: getRelayUrls(),
22+
explicitRelayUrls: config.nostrRelayUrls,
3423
signer: new NDKNip07Signer(),
3524
});
3625

@@ -39,7 +28,7 @@ ndk.relayAuthDefaultPolicy = NDKRelayAuthPolicies.signIn({ ndk });
3928

4029
ndk
4130
.connect()
42-
.then(() => console.log('NDK connected with relay URLs and NIP-42 auth policy:', getRelayUrls()))
31+
.then(() => console.log('NDK connected with relay URLs and NIP-42 auth policy:', config.nostrRelayUrls))
4332
.catch((error) => console.error('NDK connection error:', error));
4433

4534
const App: React.FC = () => {

src/components/header/components/searchDropdown/SearchDropdown.tsx

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,8 @@ import { CategoryComponents } from '@app/components/header/components/HeaderSear
55
import { Btn, InputSearch } from '../HeaderSearch/HeaderSearch.styles';
66
import { useTranslation } from 'react-i18next';
77
import { BasePopover } from '@app/components/common/BasePopover/BasePopover';
8-
import { NDKUserProfile, useNDK } from '@nostr-dev-kit/ndk-hooks';
98
import usePaidSubscribers from '@app/hooks/usePaidSubscribers';
10-
import { convertNDKUserProfileToSubscriberProfile } from '@app/utils/utils';
9+
import { useProfileAPI } from '@app/hooks/useProfileAPI';
1110
import { InvalidPubkey } from '../../Header.styles';
1211

1312
import { SubscriberProfile } from '@app/hooks/usePaidSubscribers';
@@ -34,7 +33,7 @@ export const SearchDropdown: React.FC<SearchOverlayProps> = ({
3433
const [subscriberProfile, setSubscriberProfile] = useState<SubscriberProfile | null>(null);
3534
const [invalidPubkey, setInvalidPubkey] = useState(false);
3635
const { subscribers } = usePaidSubscribers();
37-
const ndkInstance = useNDK();
36+
const { fetchSingleProfile, loading: profileAPILoading } = useProfileAPI();
3837
const { t } = useTranslation();
3938

4039
useEffect(() => {
@@ -44,19 +43,19 @@ export const SearchDropdown: React.FC<SearchOverlayProps> = ({
4443
// eslint-disable-next-line @typescript-eslint/no-explicit-any
4544
const ref = useRef<any>(null);
4645

47-
const fetchProfile = async (pubkey: string): Promise<NDKUserProfile | null> => {
48-
if (!ndkInstance) return null;
49-
46+
const fetchProfile = async (pubkey: string): Promise<SubscriberProfile | null> => {
5047
try {
5148
setFetchingProfile(true);
52-
const profile = await ndkInstance.ndk?.getUser({ pubkey: pubkey }).fetchProfile();
53-
49+
setFetchingFailed(false);
50+
51+
const profile = await fetchSingleProfile(pubkey);
52+
5453
if (profile) {
5554
setFetchingProfile(false);
5655
setFetchingFailed(false);
5756
return profile;
5857
} else {
59-
console.error('Profile not found for pubkey:', pubkey);
58+
console.log('Profile not found for pubkey:', pubkey);
6059
setFetchingProfile(false);
6160
setFetchingFailed(true);
6261
return null;
@@ -71,34 +70,35 @@ export const SearchDropdown: React.FC<SearchOverlayProps> = ({
7170

7271
const handleSearchProfile = async () => {
7372
if (!query) return;
74-
//verify that it's a pubkey
73+
74+
// Verify that it's a valid pubkey (hex format)
7575
if (/^[a-fA-F0-9]{64}$/.test(query)) {
7676
setSubscriberDetailModalOpen(true);
77+
setInvalidPubkey(false);
7778

78-
//See if the pubkey exists in the subscribers
7979
const pubkey = query;
80-
const subscriber = subscribers.find((sub) => sub.pubkey === query);
81-
// If it exists, open the modal with the subscriber details. If name,picture, or about are not set, fetch profile.
82-
//if It doesnt exist, fetch the profile from NDK
83-
//once fetched, convert it to SubscriberProfile and open the modal
84-
if (subscriber) {
85-
if (!subscriber.name || !subscriber.picture || !subscriber.about) {
86-
const profile = await fetchProfile(pubkey);
87-
if (profile) {
88-
const subscriberProfile: SubscriberProfile = convertNDKUserProfileToSubscriberProfile(pubkey, profile);
89-
// Open the modal with the fetched subscriber profile
90-
setSubscriberProfile(subscriberProfile);
91-
}
92-
}
80+
81+
// First check if the pubkey exists in current subscribers list
82+
const existingSubscriber = subscribers.find((sub) => sub.pubkey === pubkey);
83+
84+
if (existingSubscriber && existingSubscriber.name && existingSubscriber.picture) {
85+
// We already have complete profile data, use it directly
86+
setSubscriberProfile(existingSubscriber);
87+
setFetchingProfile(false);
88+
setFetchingFailed(false);
9389
} else {
90+
// Fetch the profile from API (either new subscriber or incomplete data)
9491
const profile = await fetchProfile(pubkey);
9592
if (profile) {
96-
const subscriberProfile: SubscriberProfile = convertNDKUserProfileToSubscriberProfile(pubkey, profile);
97-
// Open the modal with the fetched subscriber profile
98-
setSubscriberProfile(subscriberProfile);
93+
setSubscriberProfile(profile);
94+
} else {
95+
// If API doesn't have the profile, use existing subscriber data if available
96+
if (existingSubscriber) {
97+
setSubscriberProfile(existingSubscriber);
98+
}
9999
}
100100
}
101-
}else{
101+
} else {
102102
setInvalidPubkey(true);
103103
}
104104
};
@@ -152,7 +152,7 @@ export const SearchDropdown: React.FC<SearchOverlayProps> = ({
152152
</HeaderActionWrapper>
153153
{isSubscriberDetailModalOpen && (
154154
<SubscriberDetailModal
155-
loading={fetchingProfile}
155+
loading={fetchingProfile || profileAPILoading}
156156
fetchFailed={fetchingFailed}
157157
isVisible={isSubscriberDetailModalOpen}
158158
subscriber={subscriberProfile}

0 commit comments

Comments
 (0)