diff --git a/src/controllers/MetadataController.ts b/src/controllers/MetadataController.ts index 8c10ce6..7dd1285 100644 --- a/src/controllers/MetadataController.ts +++ b/src/controllers/MetadataController.ts @@ -6,9 +6,10 @@ import { validateEvent, verifyEvent, Event, - EventTemplate + EventTemplate, + nip19 } from 'nostr-tools' -import { ProfileMetadata, RelaySet } from '../types' +import { NostrJoiningBlock, ProfileMetadata, RelaySet } from '../types' import { NostrController } from '.' import { toast } from 'react-toastify' import { queryNip05 } from '../utils' @@ -166,14 +167,16 @@ export class MetadataController { }) } - public getNostrJoiningBlockNumber = async (hexKey: string) => { + public getNostrJoiningBlockNumber = async ( + hexKey: string + ): Promise => { const relaySet = await this.findRelayListMetadata(hexKey) - const relays: string[] = [] + const userRelays: string[] = [] // find user's relays if (relaySet.write.length > 0) { - relays.push(...relaySet.write) + userRelays.push(...relaySet.write) } else { const metadata = await this.findMetadata(hexKey) const metadataContent = this.extractProfileMetadataContent(metadata) @@ -182,12 +185,12 @@ export class MetadataController { const nip05Profile = await queryNip05(metadataContent.nip05) if (nip05Profile && nip05Profile.pubkey === hexKey) { - relays.push(...nip05Profile.relays) + userRelays.push(...nip05Profile.relays) } } } - if (relays.length === 0) return null + if (userRelays.length === 0) return null // filter for finding user's first kind 1 event const eventFilter: Filter = { @@ -198,7 +201,7 @@ export class MetadataController { const pool = new SimplePool() // find user's kind 1 events published on user's relays - const events = await pool.querySync(relays, eventFilter) + const events = await pool.querySync(userRelays, eventFilter) if (events && events.length) { // sort events by created_at time in ascending order events.sort((a, b) => a.created_at - b.created_at) @@ -270,10 +273,20 @@ export class MetadataController { '#p': [jobSignedEvent.pubkey] }) - // asynchronously get block number from dvm job with 10 seconds timeout - const dvmJobResult = await subscribeWithTimeout(sub, 10000) + // asynchronously get block number from dvm job with 20 seconds timeout + const dvmJobResult = await subscribeWithTimeout(sub, 20000) - return parseInt(dvmJobResult) + const encodedEventPointer = nip19.neventEncode({ + id: event.id, + relays: userRelays, + author: event.pubkey, + kind: event.kind + }) + + return { + block: parseInt(dvmJobResult), + encodedEventPointer + } } return null diff --git a/src/pages/profile/index.tsx b/src/pages/profile/index.tsx index 257419e..6ad9c2f 100644 --- a/src/pages/profile/index.tsx +++ b/src/pages/profile/index.tsx @@ -9,11 +9,11 @@ import { } from '@mui/material' import { UnsignedEvent, nip19, kinds, VerifiedEvent } from 'nostr-tools' import { useEffect, useMemo, useState } from 'react' -import { useParams } from 'react-router-dom' +import { Link, useParams } from 'react-router-dom' import { toast } from 'react-toastify' import placeholderAvatar from '../../assets/images/nostr-logo.jpg' import { MetadataController, NostrController } from '../../controllers' -import { ProfileMetadata } from '../../types' +import { NostrJoiningBlock, ProfileMetadata } from '../../types' import styles from './style.module.scss' import { useDispatch, useSelector } from 'react-redux' import { State } from '../../store/rootReducer' @@ -34,7 +34,8 @@ export const ProfilePage = () => { const nostrController = NostrController.getInstance() const [pubkey, setPubkey] = useState() - const [blockNumber, setBlockNumber] = useState(null) + const [nostrJoiningBlock, setNostrJoiningBlock] = + useState(null) const [profileMetadata, setProfileMetadata] = useState() const [savingProfileMetadata, setSavingProfileMetadata] = useState(false) const metadataState = useSelector((state: State) => state.metadata) @@ -64,7 +65,7 @@ export const ProfilePage = () => { metadataController .getNostrJoiningBlockNumber(pubkey) .then((res) => { - setBlockNumber(res) + setNostrJoiningBlock(res) }) .catch((err) => { // todo: handle error @@ -239,15 +240,18 @@ export const ProfilePage = () => { src={profileMetadata.picture || placeholderAvatar} alt='Profile Image' /> - {blockNumber && ( + {nostrJoiningBlock && ( - On nostr since {blockNumber.toLocaleString()} + On nostr since {nostrJoiningBlock.block.toLocaleString()} )} diff --git a/src/types/nostr.ts b/src/types/nostr.ts index 87a9b27..67572d8 100644 --- a/src/types/nostr.ts +++ b/src/types/nostr.ts @@ -12,3 +12,8 @@ export interface RelaySet { read: string[] write: string[] } + +export interface NostrJoiningBlock { + block: number + encodedEventPointer: string +}