sigit.io/src/utils/relays.ts

108 lines
2.8 KiB
TypeScript
Raw Normal View History

import { Filter, SimplePool } from 'nostr-tools'
import { RelayList } from 'nostr-tools/kinds'
import { Event } from 'nostr-tools'
import { localCache } from '../services'
import { ONE_WEEK_IN_MS, SIGIT_RELAY } from './const.ts'
import { RelayMap, RelaySet } from '../types'
const READ_MARKER = "read"
const WRITE_MARKET = "write"
/**
* Attempts to find a relay list from the provided lookUpRelays.
* If the relay list is found, it will be added to the user relay list metadata.
* @param lookUpRelays
* @param hexKey
* @return found relay list or null
*/
const findRelayListAndUpdateCache = async (lookUpRelays: string[], hexKey: string): Promise<Event | null> => {
try {
const eventFilter: Filter = {
kinds: [RelayList],
authors: [hexKey]
}
const pool = new SimplePool()
const event = await pool.get(lookUpRelays, eventFilter)
if (event) {
await localCache.addUserRelayListMetadata(event)
}
return event
} catch (error) {
console.error(error)
return null
}
}
/**
* Attempts to find a relay list in cache. If it is present, it will check that the cached event is not
* older than one week.
* @param hexKey
* @return RelayList event if it's not older than a week; otherwise null
*/
const findRelayListInCache = async (hexKey: string): Promise<Event | null> => {
try {
// Attempt to retrieve the metadata event from the local cache
const cachedRelayListMetadataEvent = await localCache.getUserRelayListMetadata(hexKey)
// Check if the cached event is not older than one week
if (cachedRelayListMetadataEvent && isOlderThanOneWeek(cachedRelayListMetadataEvent.cachedAt)) {
return cachedRelayListMetadataEvent.event
}
return null
} catch (error) {
console.error(error)
return null
}
}
/**
* Transforms a list of relay tags from a Nostr Event to a RelaySet.
* @param tags
*/
const getUserRelaySet = (tags: string[][]): RelaySet => {
return tags
.filter(isRelayTag)
.reduce<RelaySet>(toRelaySet, getDefaultRelaySet())
}
const getDefaultRelaySet = (): RelaySet => ({
read: [SIGIT_RELAY],
write: [SIGIT_RELAY]
})
const getDefaultRelayMap = (): RelayMap => ({
[SIGIT_RELAY]: { write: true, read: true }
})
const isOlderThanOneWeek = (cachedAt: number) => {
return Date.now() - cachedAt < ONE_WEEK_IN_MS
}
const isRelayTag = (tag: string[]): boolean => tag[0] === 'r'
const toRelaySet = (obj: RelaySet, tag: string[]): RelaySet => {
if (tag.length >= 3) {
const marker = tag[2]
if (marker === READ_MARKER) {
obj.read.push(tag[1])
} else if (marker === WRITE_MARKET) {
obj.write.push(tag[1])
}
}
if (tag.length === 2) {
obj.read.push(tag[1])
obj.write.push(tag[1])
}
return obj
}
export {
findRelayListAndUpdateCache,
findRelayListInCache,
getUserRelaySet,
getDefaultRelaySet,
getDefaultRelayMap,
}