import { RelaySettings, ConnectionStateSnapshot, OkResponse } from "./connection"; import { RequestBuilder } from "./request-builder"; import { NoteStore, NoteStoreSnapshotData } from "./note-collection"; import { Query } from "./query"; import { NostrEvent, ReqFilter, TaggedNostrEvent } from "./nostr"; import { ProfileLoaderService } from "./profile-cache"; import { RelayCache } from "./outbox-model"; import { QueryOptimizer } from "./query-optimizer"; import { base64 } from "@scure/base"; export { NostrSystem } from "./nostr-system"; export { default as EventKind } from "./event-kind"; export { default as SocialGraph, socialGraphInstance } from "./SocialGraph/SocialGraph"; export * from "./SocialGraph/UniqueIds"; export * from "./nostr"; export * from "./links"; export * from "./nips"; export * from "./relay-info"; export * from "./event-ext"; export * from "./connection"; export * from "./note-collection"; export * from "./request-builder"; export * from "./event-publisher"; export * from "./event-builder"; export * from "./nostr-link"; export * from "./profile-cache"; export * from "./zaps"; export * from "./signer"; export * from "./text"; export * from "./pow"; export * from "./pow-util"; export * from "./query-optimizer"; export * from "./encrypted"; export * from "./outbox-model"; export * from "./impl/nip4"; export * from "./impl/nip44"; export * from "./impl/nip7"; export * from "./impl/nip46"; export * from "./cache/index"; export * from "./cache/user-relays"; export * from "./cache/user-metadata"; export * from "./cache/relay-metric"; export interface SystemInterface { /** * Check event signatures (reccomended) */ checkSigs: boolean; /** * Get a snapshot of the relay connections */ get Sockets(): Array; /** * Get an active query by ID * @param id Query ID */ GetQuery(id: string): Query | undefined; /** * Open a new query to relays * @param type Store type * @param req Request to send to relays */ Query(type: { new (): T }, req: RequestBuilder): Query; /** * Fetch data from nostr relays asynchronously * @param req Request to send to relays * @param cb A callback which will fire every 100ms when new data is received */ Fetch(req: RequestBuilder, cb?: (evs: Array) => void): Promise>; /** * Create a new permanent connection to a relay * @param address Relay URL * @param options Read/Write settings */ ConnectToRelay(address: string, options: RelaySettings): Promise; /** * Disconnect permanent relay connection * @param address Relay URL */ DisconnectRelay(address: string): void; /** * Send an event to all permanent connections * @param ev Event to broadcast * @param cb Callback to handle OkResponse as they arrive */ BroadcastEvent(ev: NostrEvent, cb?: (rsp: OkResponse) => void): Promise>; /** * Connect to a specific relay and send an event and wait for the response * @param relay Relay URL * @param ev Event to send */ WriteOnceToRelay(relay: string, ev: NostrEvent): Promise; /** * Profile cache/loader */ get ProfileLoader(): ProfileLoaderService; /** * Relay cache for "Gossip" model */ get RelayCache(): RelayCache; /** * Query optimizer */ get QueryOptimizer(): QueryOptimizer; } export interface SystemSnapshot { queries: Array<{ id: string; filters: Array; subFilters: Array; }>; } export const enum MessageEncryptorVersion { Nip4 = 0, XChaCha20 = 1, } export interface MessageEncryptorPayload { ciphertext: Uint8Array; nonce: Uint8Array; v: MessageEncryptorVersion; } export interface MessageEncryptor { getSharedSecret(privateKey: string, publicKey: string): Promise | Uint8Array; encryptData(plaintext: string, sharedSecet: Uint8Array): Promise | MessageEncryptorPayload; decryptData(payload: MessageEncryptorPayload, sharedSecet: Uint8Array): Promise | string; } export function decodeEncryptionPayload(p: string): MessageEncryptorPayload { if (p.startsWith("{") && p.endsWith("}")) { const pj = JSON.parse(p) as { v: number; nonce: string; ciphertext: string }; return { v: pj.v, nonce: base64.decode(pj.nonce), ciphertext: base64.decode(pj.ciphertext), }; } else if (p.includes("?iv=")) { const [ciphertext, nonce] = p.split("?iv="); return { v: MessageEncryptorVersion.Nip4, nonce: base64.decode(nonce), ciphertext: base64.decode(ciphertext), }; } else { const buf = base64.decode(p); return { v: buf[0], nonce: buf.subarray(1, 25), ciphertext: buf.subarray(25), }; } } export function encodeEncryptionPayload(p: MessageEncryptorPayload) { return base64.encode(new Uint8Array([p.v, ...p.nonce, ...p.ciphertext])); }