diff --git a/frontend/Components/LandingPage/Logger/index.tsx b/frontend/Components/LandingPage/Logger/index.tsx index 8596d12..85f4af4 100644 --- a/frontend/Components/LandingPage/Logger/index.tsx +++ b/frontend/Components/LandingPage/Logger/index.tsx @@ -7,7 +7,7 @@ import { tagToUser } from '../../../Functions/RelayFunctions/Users' import Relay from '../../../lib/nostr/Relay' import { Event, EventKind } from '../../../lib/nostr/Events' import { AppContext } from '../../../Contexts/AppContext' -import { insertUserContact } from '../../../Functions/DatabaseFunctions/Users' +import { insertUserContact, insertUserMeta } from '../../../Functions/DatabaseFunctions/Users' import SInfo from 'react-native-sensitive-info' import Icon from 'react-native-vector-icons/FontAwesome5' import { generateRandomKey, getPublickey } from '../../../lib/nostr/Bip' @@ -59,11 +59,12 @@ export const Logger: React.FC = () => { relayPool?.on('event', 'landing', (_relay: Relay, _subId?: string, event?: Event) => { console.log('LANDING EVENT =======>', event) if (event && database) { - setLastEventId(event?.id ?? '') + setLastEventId(event.id ?? '') if (event.kind === EventKind.petNames) { loadPets(event) } else if (event.kind === EventKind.meta) { setLoadedUsers((prev) => (prev ? prev + 1 : 1)) + insertUserMeta(event, database) if (loadedUsers && loadedUsers >= authors.length && status < 3) setStatus(3) } } @@ -111,7 +112,16 @@ export const Logger: React.FC = () => { clearTimeout(timer) } } - }, [status, lastEventId]) + }, [status]) + + useEffect(() => { + if (status > 1) { + const timer = setTimeout(() => setStatus(status + 1), 5000) + return () => { + clearTimeout(timer) + } + } + }, [lastEventId]) const randomKeyGenerator: () => JSX.Element = () => { if (!isPrivate) return <> diff --git a/frontend/Contexts/RelayPoolContext.tsx b/frontend/Contexts/RelayPoolContext.tsx index 8936f60..2864a7b 100644 --- a/frontend/Contexts/RelayPoolContext.tsx +++ b/frontend/Contexts/RelayPoolContext.tsx @@ -4,7 +4,7 @@ import { Event, EventKind } from '../lib/nostr/Events' import RelayPool from '../lib/nostr/RelayPool/intex' import { AppContext } from './AppContext' import { storeEvent } from '../Functions/DatabaseFunctions/Events' -import { getRelays, Relay as RelayEntity, storeRelay } from '../Functions/DatabaseFunctions/Relays' +import { getRelays, storeRelay } from '../Functions/DatabaseFunctions/Relays' import { showMessage } from 'react-native-flash-message' import SInfo from 'react-native-sensitive-info' import { getPublickey } from '../lib/nostr/Bip' @@ -47,45 +47,44 @@ export const RelayPoolContextProvider = ({ const [lastEventId, setLastEventId] = useState('') const [lastPage, setLastPage] = useState(page) - const loadRelayPool: () => void = () => { + const loadRelayPool: () => void = async () => { if (database) { - getRelays(database).then((relays: RelayEntity[]) => { - const initRelayPool = new RelayPool([], privateKey) - if (relays.length > 0) { - relays.forEach((relay) => { - initRelayPool.add(relay.url) - }) - } else { - ;['wss://relay.damus.io'].forEach((relayUrl) => { - initRelayPool.add(relayUrl) - storeRelay({ url: relayUrl }, database) - }) - } + const relays = await getRelays(database) + const initRelayPool = new RelayPool([], privateKey) + if (relays && relays.length > 0) { + relays.forEach((relay) => { + initRelayPool.add(relay.url) + }) + } else { + ;['wss://nostr.oxtr.dev'].forEach((relayUrl) => { + initRelayPool.add(relayUrl) + storeRelay({ url: relayUrl }, database) + }) + } - initRelayPool?.on( - 'notice', - 'RelayPoolContextProvider', - (relay: Relay, _subId?: string, event?: Event) => { - showMessage({ - message: relay.url, - description: event?.content ?? '', - type: 'info', - }) - }, - ) - initRelayPool?.on( - 'event', - 'RelayPoolContextProvider', - (relay: Relay, _subId?: string, event?: Event) => { - console.log('RELAYPOOL EVENT =======>', relay.url, event) - if (database && event?.id && event.kind !== EventKind.petNames) { - storeEvent(event, database).finally(() => setLastEventId(event.id)) - } - }, - ) - setRelayPool(initRelayPool) - setLoadingRelayPool(false) - }) + initRelayPool?.on( + 'notice', + 'RelayPoolContextProvider', + (relay: Relay, _subId?: string, event?: Event) => { + showMessage({ + message: relay.url, + description: event?.content ?? '', + type: 'info', + }) + }, + ) + initRelayPool?.on( + 'event', + 'RelayPoolContextProvider', + (relay: Relay, _subId?: string, event?: Event) => { + console.log('RELAYPOOL EVENT =======>', relay.url, event) + if (database && event?.id && event.kind !== EventKind.petNames) { + storeEvent(event, database).finally(() => setLastEventId(event.id ?? '')) + } + }, + ) + setRelayPool(initRelayPool) + setLoadingRelayPool(false) } } diff --git a/frontend/Functions/DatabaseFunctions/Notes/index.ts b/frontend/Functions/DatabaseFunctions/Notes/index.ts index 392c532..fec4605 100644 --- a/frontend/Functions/DatabaseFunctions/Notes/index.ts +++ b/frontend/Functions/DatabaseFunctions/Notes/index.ts @@ -17,33 +17,36 @@ export const insertNote: (event: Event, db: QuickSQLiteConnection) => Promise { - if (!verifySignature(event) || !event.id) return null - if (![EventKind.textNote, EventKind.recommendServer].includes(event.kind)) return null - - const notes = await getNotes(db, { filters: { id: event.id } }) - if (notes && notes.length === 0 && event.id && event.sig) { - const mainEventId = getMainEventId(event) ?? '' - const replyEventId = getReplyEventId(event) ?? '' - const content = event.content.split("'").join("''") - const tags = JSON.stringify(event.tags).split("'").join("''") - const query = `INSERT INTO nostros_notes - (id,content,created_at,kind,pubkey,sig,tags,main_event_id,reply_event_id) - VALUES - (?,?,?,?,?,?,?,?,?);` - const queryValues = [ - event.id, - content, - event.created_at, - event.kind, - event.pubkey, - event.sig, - tags, - mainEventId, - replyEventId, - ] - return db.executeAsync(query, queryValues) + const valid = await verifySignature(event) + if (valid && event.id && [EventKind.textNote, EventKind.recommendServer].includes(event.kind)) { + const notes = await getNotes(db, { filters: { id: event.id } }) + if (notes && notes.length === 0 && event.id && event.sig) { + const mainEventId = getMainEventId(event) ?? '' + const replyEventId = getReplyEventId(event) ?? '' + const content = event.content.split("'").join("''") + const tags = JSON.stringify(event.tags).split("'").join("''") + const query = `INSERT INTO nostros_notes + (id,content,created_at,kind,pubkey,sig,tags,main_event_id,reply_event_id) + VALUES + (?,?,?,?,?,?,?,?,?);` + const queryValues = [ + event.id, + content, + event.created_at, + event.kind, + event.pubkey, + event.sig, + tags, + mainEventId, + replyEventId, + ] + return db.executeAsync(query, queryValues) + } else { + return null + } + } else { + return null } - return null } export const getNotes: ( diff --git a/frontend/Functions/DatabaseFunctions/Users/index.ts b/frontend/Functions/DatabaseFunctions/Users/index.ts index ce181a4..63c5841 100644 --- a/frontend/Functions/DatabaseFunctions/Users/index.ts +++ b/frontend/Functions/DatabaseFunctions/Users/index.ts @@ -20,51 +20,55 @@ export const insertUserMeta: ( event: Event, db: QuickSQLiteConnection, ) => Promise = async (event, db) => { - if (!verifySignature(event)) return null - if (event.kind !== EventKind.meta) return null + const valid = await verifySignature(event) - const user: User = JSON.parse(event.content) - const id = event.pubkey - const name = user.name?.replace("\\'", "'") ?? '' - const mainRelay = user.main_relay?.replace("\\'", "'") ?? '' - const about = user.about?.replace("\\'", "'") ?? '' - const picture = user.picture?.replace("\\'", "'") ?? '' + if (valid && event.kind === EventKind.meta) { + const user: User = JSON.parse(event.content) + const id = event.pubkey + const name = user.name?.replace("\\'", "'") ?? '' + const mainRelay = user.main_relay?.replace("\\'", "'") ?? '' + const about = user.about?.replace("\\'", "'") ?? '' + const picture = user.picture?.replace("\\'", "'") ?? '' - const userDb = await getUser(user.id, db) - if (userDb) { - const userQuery = ` - UPDATE nostros_users - SET - name = ?', - main_relay = ?, - about = ?, - picture = ? - WHERE - id = ?; - ` - const queryParams = [ - name.split("'").join("''"), - mainRelay.split("'").join("''"), - about.split("'").join("''"), - picture.split("'").join("''"), - user.id, - ] - return db.execute(userQuery, queryParams) + const userDb = await getUser(user.id, db) + console.log('userDb', userDb) + if (userDb) { + const userQuery = ` + UPDATE nostros_users + SET + name = ?', + main_relay = ?, + about = ?, + picture = ? + WHERE + id = ?; + ` + const queryParams = [ + name.split("'").join("''"), + mainRelay.split("'").join("''"), + about.split("'").join("''"), + picture.split("'").join("''"), + user.id, + ] + return db.execute(userQuery, queryParams) + } else { + const userQuery = ` + INSERT INTO nostros_users + (id, name, picture, about, main_relay) + VALUES + (?,?,?,?,?); + ` + const queryParams = [ + id, + name.split("'").join("''"), + picture.split("'").join("''"), + about.split("'").join("''"), + '', + ] + return db.execute(userQuery, queryParams) + } } else { - const userQuery = ` - INSERT INTO nostros_users - (id, name, picture, about, main_relay) - VALUES - (?,?,?,?,?); - ` - const queryParams = [ - id, - name.split("'").join("''"), - picture.split("'").join("''"), - about.split("'").join("''"), - '', - ] - return db.execute(userQuery, queryParams) + return null } } @@ -72,14 +76,17 @@ export const insertUserContact: ( event: Event, db: QuickSQLiteConnection, ) => Promise> | null> = async (event, db) => { - if (!verifySignature(event)) return null - if (event.kind !== EventKind.petNames) return null + const valid = await verifySignature(event) - const userTags: string[] = event.tags.map((tag) => tagToUser(tag).id) - const users = userTags.map(async (userId) => { - return await addContact(userId, db) - }) - return users + if (valid && event.kind === EventKind.petNames) { + const userTags: string[] = event.tags.map((tag) => tagToUser(tag).id) + const users = userTags.map(async (userId) => { + return await addContact(userId, db) + }) + return users + } else { + return null + } } export const getUser: (pubkey: string, db: QuickSQLiteConnection) => Promise = async ( @@ -87,13 +94,17 @@ export const getUser: (pubkey: string, db: QuickSQLiteConnection) => Promise { const userQuery = `SELECT * FROM nostros_users WHERE id = '${pubkey}';` - const resultSet = db.execute(userQuery) + const resultSet = await db.execute(userQuery) + if (resultSet.rows && resultSet.rows?.length > 0) { const items: object[] = getItems(resultSet) const user: User = databaseToEntity(items[0]) + console.log('if (resultSet.rows && resultSet.rows?.length > 0)', user) return user + } else { + console.log('NULL') + return null } - return null } export const removeContact: ( @@ -153,6 +164,7 @@ export const getUsers: ( const items: object[] = getItems(resultSet) const users: User[] = items.map((object) => databaseToEntity(object)) return users + } else { + return [] } - return [] } diff --git a/frontend/lib/nostr/RelayPool/intex.ts b/frontend/lib/nostr/RelayPool/intex.ts index 83a90cb..8f3da75 100644 --- a/frontend/lib/nostr/RelayPool/intex.ts +++ b/frontend/lib/nostr/RelayPool/intex.ts @@ -97,28 +97,29 @@ class RelayPool { relay.close() delete this.relays[relayUrl] return true + } else { + return false } - - return false } public readonly sendEvent: (event: Event) => Promise = async (event) => { - if (!this.privateKey) return null + if (this.privateKey) { + const signedEvent: Event = await signEvent(event, this.privateKey) - const signedEvent: Event = await signEvent(event, this.privateKey) + if (validateEvent(signedEvent)) { + Object.keys(this.relays).forEach((relayUrl: string) => { + const relay: Relay = this.relays[relayUrl] + relay.sendEvent(signedEvent) + }) - if (validateEvent(signedEvent)) { - Object.keys(this.relays).forEach((relayUrl: string) => { - const relay: Relay = this.relays[relayUrl] - relay.sendEvent(signedEvent) - }) - - return signedEvent + return signedEvent + } else { + console.log('Not valid event', event) + return null + } } else { - console.log('Not valid event', event) + return null } - - return null } public readonly subscribe: (subId: string, filters?: RelayFilters) => void = (subId, filters) => {