@elisym/sdk 0.1.3 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/constants.ts","../src/core/pool.ts","../src/core/identity.ts","../src/core/discovery.ts","../src/core/marketplace.ts","../src/core/messaging.ts","../src/core/payment.ts","../src/core/format.ts","../src/core/njump.ts","../src/index.ts"],"names":["SimplePool","getPublicKey","nip19","generateSecretKey","finalizeEvent","nip44","nip17","nip59","Decimal","PublicKey","SystemProgram","Transaction"],"mappings":"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","file":"index.cjs","sourcesContent":["export const RELAYS = [\n \"wss://relay.damus.io\",\n \"wss://nos.lol\",\n \"wss://relay.nostr.band\",\n \"wss://relay.primal.net\",\n \"wss://relay.snort.social\",\n];\n\nexport const KIND_APP_HANDLER = 31990;\nexport const KIND_JOB_REQUEST_BASE = 5000;\nexport const KIND_JOB_RESULT_BASE = 6000;\nexport const KIND_JOB_FEEDBACK = 7000;\nexport const DEFAULT_KIND_OFFSET = 100;\nexport const KIND_DELETION = 5;\nexport const KIND_GIFT_WRAP = 1059;\n\n/** Default job request kind (5000 + 100). */\nexport const KIND_JOB_REQUEST = KIND_JOB_REQUEST_BASE + DEFAULT_KIND_OFFSET;\n/** Default job result kind (6000 + 100). */\nexport const KIND_JOB_RESULT = KIND_JOB_RESULT_BASE + DEFAULT_KIND_OFFSET;\n\n/** Compute a job request kind from an offset (5000 + offset). */\nexport function jobRequestKind(offset: number): number {\n return KIND_JOB_REQUEST_BASE + offset;\n}\n\n/** Compute a job result kind from an offset (6000 + offset). */\nexport function jobResultKind(offset: number): number {\n return KIND_JOB_RESULT_BASE + offset;\n}\n\n/** Ephemeral ping/pong kinds (not stored by relays, forwarded in real-time). */\nexport const KIND_PING = 20200;\nexport const KIND_PONG = 20201;\n\n\nexport const LAMPORTS_PER_SOL = 1_000_000_000;\n\n/** Protocol fee in basis points (300 = 3%). */\nexport const PROTOCOL_FEE_BPS = 300;\n/** Solana address of the protocol treasury. */\nexport const PROTOCOL_TREASURY = \"GY7vnWMkKpftU4nQ16C2ATkj1JwrQpHhknkaBUn67VTy\";\n","import { SimplePool, type Filter, type Event } from \"nostr-tools\";\nimport { RELAYS } from \"../constants\";\n\nexport type SubCloser = { close: (reason?: string) => void };\n\nexport class NostrPool {\n private pool: SimplePool;\n private relays: string[];\n\n constructor(relays: string[] = RELAYS) {\n this.pool = new SimplePool();\n this.relays = relays;\n }\n\n async querySync(filter: Filter): Promise<Event[]> {\n return Promise.race([\n this.pool.querySync(this.relays, filter),\n new Promise<Event[]>((resolve) =>\n setTimeout(() => resolve([]), 15_000),\n ),\n ]);\n }\n\n async queryBatched(\n filter: Omit<Filter, \"authors\">,\n keys: string[],\n batchSize = 250,\n ): Promise<Event[]> {\n const batches: Promise<Event[]>[] = [];\n for (let i = 0; i < keys.length; i += batchSize) {\n const batch = keys.slice(i, i + batchSize);\n batches.push(\n Promise.race([\n this.pool.querySync(this.relays, {\n ...filter,\n authors: batch,\n } as Filter),\n new Promise<Event[]>((resolve) =>\n setTimeout(() => resolve([]), 15_000),\n ),\n ]),\n );\n }\n return (await Promise.all(batches)).flat();\n }\n\n async queryBatchedByTag(\n filter: Filter,\n tagName: string,\n values: string[],\n batchSize = 250,\n ): Promise<Event[]> {\n const batches: Promise<Event[]>[] = [];\n for (let i = 0; i < values.length; i += batchSize) {\n const batch = values.slice(i, i + batchSize);\n batches.push(\n Promise.race([\n this.pool.querySync(this.relays, {\n ...filter,\n [`#${tagName}`]: batch,\n } as Filter),\n new Promise<Event[]>((resolve) =>\n setTimeout(() => resolve([]), 15_000),\n ),\n ]),\n );\n }\n return (await Promise.all(batches)).flat();\n }\n\n async publish(event: Event): Promise<void> {\n try {\n await Promise.any(this.pool.publish(this.relays, event));\n } catch (err) {\n if (err instanceof AggregateError) {\n throw new Error(\n `Failed to publish to all ${this.relays.length} relays: ${err.errors.map((e: Error) => e.message).join(\", \")}`,\n );\n }\n throw err;\n }\n }\n\n /** Publish to all relays and wait for all to settle. Throws if none accepted. */\n async publishAll(event: Event): Promise<void> {\n const results = await Promise.allSettled(this.pool.publish(this.relays, event));\n const anyOk = results.some((r) => r.status === \"fulfilled\");\n if (!anyOk) {\n throw new Error(\n `Failed to publish to all ${this.relays.length} relays`,\n );\n }\n }\n\n subscribe(\n filter: Filter,\n onEvent: (event: Event) => void,\n ): SubCloser {\n return this.pool.subscribeMany(\n this.relays,\n filter,\n { onevent: onEvent },\n );\n }\n\n /**\n * Subscribe and wait until at least one relay confirms the subscription\n * is active (EOSE). Resolves on the first relay that responds.\n * Essential for ephemeral events where the subscription must be live\n * before publishing.\n */\n subscribeAndWait(\n filter: Filter,\n onEvent: (event: Event) => void,\n timeoutMs = 3_000,\n ): Promise<SubCloser> {\n return new Promise((resolve) => {\n let resolved = false;\n const done = () => {\n if (resolved) return;\n resolved = true;\n resolve(combinedSub);\n };\n\n // Subscribe to each relay individually so we can resolve\n // as soon as the first relay sends EOSE (not waiting for all).\n const subs: SubCloser[] = [];\n for (const relay of this.relays) {\n const sub = this.pool.subscribeMany(\n [relay],\n filter,\n {\n onevent: onEvent,\n oneose: done,\n },\n );\n subs.push(sub);\n }\n\n const combinedSub: SubCloser = {\n close: (reason?: string) => {\n for (const s of subs) s.close(reason);\n },\n };\n\n setTimeout(done, timeoutMs);\n });\n }\n\n /**\n * Tear down pool and create a fresh one.\n * Works around nostr-tools `onerror → skipReconnection = true` bug\n * that permanently kills subscriptions. Callers must re-subscribe.\n */\n reset(): void {\n try { this.pool.close(this.relays); } catch { /* ignore */ }\n this.pool = new SimplePool();\n }\n\n /**\n * Lightweight connectivity probe. Returns true if at least one relay responds.\n */\n async probe(timeoutMs = 3_000): Promise<boolean> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n try {\n await Promise.race([\n this.pool.querySync(this.relays, { kinds: [0], limit: 1 } as Filter),\n new Promise<never>((_, reject) => {\n timer = setTimeout(() => reject(new Error(\"probe timeout\")), timeoutMs);\n }),\n ]);\n return true;\n } catch {\n return false;\n } finally {\n clearTimeout(timer);\n }\n }\n\n getRelays(): string[] {\n return this.relays;\n }\n\n close(): void {\n this.pool.close(this.relays);\n }\n}\n","import { generateSecretKey, getPublicKey } from \"nostr-tools\";\nimport { nip19 } from \"nostr-tools\";\n\nexport class ElisymIdentity {\n readonly secretKey: Uint8Array;\n readonly publicKey: string;\n readonly npub: string;\n\n private constructor(secretKey: Uint8Array) {\n this.secretKey = secretKey;\n this.publicKey = getPublicKey(secretKey);\n this.npub = nip19.npubEncode(this.publicKey);\n }\n\n static generate(): ElisymIdentity {\n return new ElisymIdentity(generateSecretKey());\n }\n\n static fromSecretKey(sk: Uint8Array): ElisymIdentity {\n return new ElisymIdentity(sk);\n }\n\n static fromHex(hex: string): ElisymIdentity {\n if (hex.length !== 64 || !/^[0-9a-fA-F]{64}$/.test(hex)) {\n throw new Error(\"Invalid secret key hex: expected 64 hex characters (32 bytes).\");\n }\n const bytes = new Uint8Array(32);\n for (let i = 0; i < 64; i += 2) {\n bytes[i / 2] = parseInt(hex.substring(i, i + 2), 16);\n }\n return new ElisymIdentity(bytes);\n }\n\n}\n","import { nip19 } from \"nostr-tools\";\nimport type { Filter, Event } from \"nostr-tools\";\nimport { finalizeEvent } from \"nostr-tools\";\nimport type { NostrPool } from \"./pool\";\nimport type { ElisymIdentity } from \"./identity\";\nimport {\n KIND_APP_HANDLER,\n KIND_JOB_FEEDBACK,\n KIND_JOB_REQUEST,\n KIND_JOB_REQUEST_BASE,\n KIND_JOB_RESULT_BASE,\n jobResultKind,\n DEFAULT_KIND_OFFSET,\n} from \"../constants\";\nimport type { Agent, CapabilityCard, Network } from \"../types\";\n\n/** Convert a capability name to its Nostr d-tag form. */\nexport function toDTag(name: string): string {\n return name.toLowerCase().replace(/\\s+/g, \"-\");\n}\n\n/**\n * Deduplicate events by (pubkey, d-tag) keeping only the newest,\n * then build an Agent map filtered by network.\n */\nfunction buildAgentsFromEvents(\n events: Event[],\n network: Network,\n): Map<string, Agent> {\n // Deduplicate by author + d-tag, keeping only the newest event\n const latestByDTag = new Map<string, Event>();\n for (const event of events) {\n const dTag = event.tags.find((t) => t[0] === \"d\")?.[1] ?? \"\";\n const key = `${event.pubkey}:${dTag}`;\n const prev = latestByDTag.get(key);\n if (!prev || event.created_at > prev.created_at) {\n latestByDTag.set(key, event);\n }\n }\n\n // Intermediate structure: keep kTags per card so we can recompute\n // supportedKinds from only the surviving (deduplicated) entries.\n interface CardEntry {\n card: CapabilityCard;\n kTags: number[];\n createdAt: number;\n }\n interface AgentAccum {\n pubkey: string;\n npub: string;\n entries: CardEntry[];\n eventId: string;\n lastSeen: number;\n }\n\n const accumMap = new Map<string, AgentAccum>();\n\n for (const event of latestByDTag.values()) {\n try {\n const card = JSON.parse(event.content) as CapabilityCard & { deleted?: boolean };\n if (!card.name || card.deleted) continue;\n\n const agentNetwork = card.payment?.network ?? \"devnet\";\n if (agentNetwork !== network) continue;\n\n const kTags = event.tags\n .filter((t) => t[0] === \"k\")\n .map((t) => parseInt(t[1] ?? \"\", 10))\n .filter((k) => !isNaN(k));\n\n const entry: CardEntry = { card, kTags, createdAt: event.created_at };\n\n const existing = accumMap.get(event.pubkey);\n if (existing) {\n // Deduplicate by card name — keep the newer version\n const dupIndex = existing.entries.findIndex((e) => e.card.name === card.name);\n if (dupIndex >= 0) {\n if (entry.createdAt >= existing.entries[dupIndex]!.createdAt) {\n existing.entries[dupIndex] = entry;\n }\n } else {\n existing.entries.push(entry);\n }\n if (event.created_at > existing.lastSeen) {\n existing.lastSeen = event.created_at;\n existing.eventId = event.id;\n }\n } else {\n accumMap.set(event.pubkey, {\n pubkey: event.pubkey,\n npub: nip19.npubEncode(event.pubkey),\n entries: [entry],\n eventId: event.id,\n lastSeen: event.created_at,\n });\n }\n } catch {\n // skip malformed events\n }\n }\n\n // Build final Agent map — recompute supportedKinds from surviving entries only\n const agentMap = new Map<string, Agent>();\n for (const [pubkey, acc] of accumMap) {\n const supportedKinds: number[] = [];\n for (const e of acc.entries) {\n for (const k of e.kTags) {\n if (!supportedKinds.includes(k)) supportedKinds.push(k);\n }\n }\n agentMap.set(pubkey, {\n pubkey: acc.pubkey,\n npub: acc.npub,\n cards: acc.entries.map((e) => e.card),\n eventId: acc.eventId,\n supportedKinds,\n lastSeen: acc.lastSeen,\n });\n }\n\n return agentMap;\n}\n\nexport class DiscoveryService {\n // Instance-level set — avoids module-level state leak across clients\n private allSeenAgents = new Set<string>();\n\n constructor(private pool: NostrPool) {}\n\n /** Count elisym agents (kind:31990 with \"elisym\" tag). */\n async fetchAllAgentCount(): Promise<number> {\n const events = await this.pool.querySync({\n kinds: [KIND_APP_HANDLER],\n \"#t\": [\"elisym\"],\n } as Filter);\n\n for (const event of events) {\n this.allSeenAgents.add(event.pubkey);\n }\n return this.allSeenAgents.size;\n }\n\n /**\n * Fetch a single page of elisym agents with relay-side pagination.\n * Uses `until` cursor for Nostr cursor-based pagination.\n * Does NOT fetch activity (faster than fetchAgents).\n */\n async fetchAgentsPage(\n network: Network = \"devnet\",\n limit = 20,\n until?: number,\n ): Promise<{ agents: Agent[]; oldestCreatedAt: number | null; rawEventCount: number }> {\n const filter: Filter = {\n kinds: [KIND_APP_HANDLER],\n \"#t\": [\"elisym\"],\n limit,\n };\n if (until !== undefined) {\n filter.until = until;\n }\n\n const events = await this.pool.querySync(filter);\n const rawEventCount = events.length;\n\n // Compute cursor from ALL raw events (before any filtering)\n let oldestCreatedAt: number | null = null;\n for (const event of events) {\n if (oldestCreatedAt === null || event.created_at < oldestCreatedAt) {\n oldestCreatedAt = event.created_at;\n }\n }\n\n const agentMap = buildAgentsFromEvents(events, network);\n\n const agents = Array.from(agentMap.values()).sort(\n (a, b) => b.lastSeen - a.lastSeen,\n );\n\n return { agents, oldestCreatedAt, rawEventCount };\n }\n\n /** Enrich agents with kind:0 metadata (name, picture, about). Mutates in place and returns the same array. */\n async enrichWithMetadata(agents: Agent[]): Promise<Agent[]> {\n const pubkeys = agents.map((a) => a.pubkey);\n if (pubkeys.length === 0) return agents;\n\n const metaEvents = await this.pool.queryBatched(\n { kinds: [0] } as Omit<Filter, \"authors\">,\n pubkeys,\n );\n const latestMeta = new Map<string, (typeof metaEvents)[0]>();\n for (const ev of metaEvents) {\n const prev = latestMeta.get(ev.pubkey);\n if (!prev || ev.created_at > prev.created_at) {\n latestMeta.set(ev.pubkey, ev);\n }\n }\n const agentLookup = new Map(agents.map((a) => [a.pubkey, a]));\n for (const [pubkey, ev] of latestMeta) {\n const agent = agentLookup.get(pubkey);\n if (!agent) continue;\n try {\n const meta = JSON.parse(ev.content);\n if (meta.picture) agent.picture = meta.picture;\n if (meta.name) agent.name = meta.name;\n if (meta.about) agent.about = meta.about;\n } catch {\n // skip malformed metadata\n }\n }\n return agents;\n }\n\n /** Fetch elisym agents filtered by network. */\n async fetchAgents(network: Network = \"devnet\", limit?: number): Promise<Agent[]> {\n const filter: Filter = {\n kinds: [KIND_APP_HANDLER],\n \"#t\": [\"elisym\"],\n };\n if (limit !== undefined) filter.limit = limit;\n const events = await this.pool.querySync(filter);\n\n const agentMap = buildAgentsFromEvents(events, network);\n\n // Update lastSeen from recent job activity\n const agentPubkeys = Array.from(agentMap.keys());\n if (agentPubkeys.length > 0) {\n const activitySince = Math.floor(Date.now() / 1000) - 24 * 60 * 60;\n // Derive result kinds from agents' supported request kinds (5xxx → 6xxx)\n const resultKinds = new Set<number>();\n for (const agent of agentMap.values()) {\n for (const k of agent.supportedKinds) {\n if (k >= KIND_JOB_REQUEST_BASE && k < KIND_JOB_RESULT_BASE) {\n resultKinds.add(KIND_JOB_RESULT_BASE + (k - KIND_JOB_REQUEST_BASE));\n }\n }\n }\n resultKinds.add(jobResultKind(DEFAULT_KIND_OFFSET));\n\n const activityEvents = await this.pool.queryBatched(\n {\n kinds: [...resultKinds, KIND_JOB_FEEDBACK],\n since: activitySince,\n } as Omit<Filter, \"authors\">,\n agentPubkeys,\n );\n for (const ev of activityEvents) {\n const agent = agentMap.get(ev.pubkey);\n if (agent && ev.created_at > agent.lastSeen) {\n agent.lastSeen = ev.created_at;\n }\n }\n }\n\n const agents = Array.from(agentMap.values()).sort(\n (a, b) => b.lastSeen - a.lastSeen,\n );\n\n // Enrich with metadata (non-blocking — already has timeout via queryBatched)\n await this.enrichWithMetadata(agents);\n\n return agents;\n }\n\n /** Publish a capability card (kind:31990) as a provider. */\n async publishCapability(\n identity: ElisymIdentity,\n card: CapabilityCard,\n kinds: number[] = [KIND_JOB_REQUEST],\n ): Promise<string> {\n if (!card.payment?.address) {\n throw new Error(\n \"Cannot publish capability without a payment address. Connect a wallet before publishing.\",\n );\n }\n\n const tags: string[][] = [\n [\"d\", toDTag(card.name)],\n [\"t\", \"elisym\"],\n ...card.capabilities.map((c) => [\"t\", c]),\n ...kinds.map((k) => [\"k\", String(k)]),\n ];\n\n const event = finalizeEvent(\n {\n kind: KIND_APP_HANDLER,\n created_at: Math.floor(Date.now() / 1000),\n tags,\n content: JSON.stringify(card),\n },\n identity.secretKey,\n );\n\n await this.pool.publish(event);\n return event.id;\n }\n\n /** Publish a Nostr profile (kind:0) as a provider. */\n async publishProfile(\n identity: ElisymIdentity,\n name: string,\n about: string,\n picture?: string,\n ): Promise<string> {\n const content: Record<string, string> = { name, about };\n if (picture) content.picture = picture;\n\n const event = finalizeEvent(\n {\n kind: 0,\n created_at: Math.floor(Date.now() / 1000),\n tags: [],\n content: JSON.stringify(content),\n },\n identity.secretKey,\n );\n\n await this.pool.publish(event);\n return event.id;\n }\n\n /**\n * Delete a capability by publishing a tombstone replacement.\n * Since kind:31990 is a parameterized replaceable event,\n * publishing a new event with the same `d` tag and `\"deleted\":true`\n * content replaces the old one on all relays.\n */\n async deleteCapability(\n identity: ElisymIdentity,\n capabilityName: string,\n ): Promise<string> {\n const dTag = toDTag(capabilityName);\n\n const event = finalizeEvent(\n {\n kind: KIND_APP_HANDLER,\n created_at: Math.floor(Date.now() / 1000),\n tags: [\n [\"d\", dTag],\n [\"t\", \"elisym\"],\n ],\n content: JSON.stringify({ deleted: true }),\n },\n identity.secretKey,\n );\n\n await this.pool.publishAll(event);\n return event.id;\n }\n}\n","import { finalizeEvent, type Filter, type Event } from \"nostr-tools\";\nimport * as nip44 from \"nostr-tools/nip44\";\nimport type { SubCloser } from \"./pool\";\nimport type { NostrPool } from \"./pool\";\nimport type { ElisymIdentity } from \"./identity\";\nimport {\n KIND_JOB_FEEDBACK,\n KIND_JOB_REQUEST_BASE,\n KIND_JOB_RESULT_BASE,\n DEFAULT_KIND_OFFSET,\n jobRequestKind,\n jobResultKind,\n} from \"../constants\";\nimport type { Job, JobStatus } from \"../types\";\n\nfunction isEncrypted(event: Event): boolean {\n return event.tags.some((t) => t[0] === \"encrypted\" && t[1] === \"nip44\");\n}\n\nfunction nip44Encrypt(plaintext: string, secretKey: Uint8Array, recipientPubkey: string): string {\n const conversationKey = nip44.v2.utils.getConversationKey(secretKey, recipientPubkey);\n return nip44.v2.encrypt(plaintext, conversationKey);\n}\n\nfunction nip44Decrypt(ciphertext: string, secretKey: Uint8Array, senderPubkey: string): string {\n const conversationKey = nip44.v2.utils.getConversationKey(secretKey, senderPubkey);\n return nip44.v2.decrypt(ciphertext, conversationKey);\n}\n\nfunction resolveRequestId(event: Event): string | undefined {\n return event.tags.find((t) => t[0] === \"e\")?.[1];\n}\n\nexport interface SubmitJobOptions {\n input: string;\n capability: string;\n providerPubkey?: string;\n /** Kind offset (default 100 → kind 5100). */\n kindOffset?: number;\n}\n\nexport interface JobUpdateCallbacks {\n onFeedback?: (status: string, amount?: number, paymentRequest?: string) => void;\n onResult?: (content: string, eventId: string) => void;\n onError?: (error: string) => void;\n}\n\nexport class MarketplaceService {\n constructor(private pool: NostrPool) {}\n\n /** Submit a job request with NIP-44 encrypted input. Returns the event ID. */\n async submitJobRequest(\n identity: ElisymIdentity,\n options: SubmitJobOptions,\n ): Promise<string> {\n if (!options.input) {\n throw new Error(\"Job input must not be empty.\");\n }\n const plaintext = options.input;\n const encrypted = options.providerPubkey\n ? nip44Encrypt(plaintext, identity.secretKey, options.providerPubkey)\n : plaintext;\n\n const iValue = options.providerPubkey ? \"encrypted\" : \"\";\n const tags: string[][] = [\n [\"i\", iValue, \"text\"],\n [\"t\", options.capability],\n [\"t\", \"elisym\"],\n [\"output\", \"text/plain\"],\n ];\n\n if (options.providerPubkey) {\n tags.push([\"p\", options.providerPubkey]);\n tags.push([\"encrypted\", \"nip44\"]);\n }\n\n const kind = jobRequestKind(options.kindOffset ?? DEFAULT_KIND_OFFSET);\n const event = finalizeEvent(\n {\n kind,\n created_at: Math.floor(Date.now() / 1000),\n tags,\n content: encrypted,\n },\n identity.secretKey,\n );\n\n await this.pool.publish(event);\n return event.id;\n }\n\n /**\n * Subscribe to job updates (feedback + results) for a given job.\n * Returns a cleanup function.\n */\n subscribeToJobUpdates(\n jobEventId: string,\n providerPubkey: string | undefined,\n customerPublicKey: string,\n callbacks: JobUpdateCallbacks,\n timeoutMs = 120_000,\n customerSecretKey?: Uint8Array,\n /** Kind offsets to listen for (default [100]). */\n kindOffsets?: number[],\n ): () => void {\n const offsets = kindOffsets ?? [DEFAULT_KIND_OFFSET];\n const resultKinds = offsets.map(jobResultKind);\n const since = Math.floor(Date.now() / 1000) - 5;\n const subs: SubCloser[] = [];\n let resolved = false;\n let resultDelivered = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n const done = () => {\n resolved = true;\n if (timer) clearTimeout(timer);\n for (const s of subs) s.close();\n };\n\n const decryptResult = (ev: Event): string => {\n if (customerSecretKey && isEncrypted(ev)) {\n try {\n return nip44Decrypt(ev.content, customerSecretKey, ev.pubkey);\n } catch {\n return ev.content;\n }\n }\n return ev.content;\n };\n\n const handleResult = (ev: Event) => {\n if (resolved || resultDelivered) return;\n if (providerPubkey && ev.pubkey !== providerPubkey) return;\n resultDelivered = true;\n callbacks.onResult?.(decryptResult(ev), ev.id);\n done();\n };\n\n // Feedback subscription\n const feedbackSub = this.pool.subscribe(\n {\n kinds: [KIND_JOB_FEEDBACK],\n \"#e\": [jobEventId],\n since,\n } as Filter,\n (ev) => {\n if (resolved) return;\n if (providerPubkey && ev.pubkey !== providerPubkey) return;\n const statusTag = ev.tags.find((t) => t[0] === \"status\");\n if (statusTag?.[1] === \"payment-required\") {\n const amtTag = ev.tags.find((t) => t[0] === \"amount\");\n const amt = amtTag?.[1] ? parseInt(amtTag[1], 10) : 0;\n const paymentReq = amtTag?.[2];\n callbacks.onFeedback?.(\"payment-required\", amt, paymentReq);\n }\n },\n );\n subs.push(feedbackSub);\n\n // Result subscription by #e tag\n const resultSub = this.pool.subscribe(\n {\n kinds: resultKinds,\n \"#e\": [jobEventId],\n since,\n } as Filter,\n handleResult,\n );\n subs.push(resultSub);\n\n // Result subscription by #p tag (customer pubkey) + #e tag\n const resultSub2 = this.pool.subscribe(\n {\n kinds: resultKinds,\n \"#p\": [customerPublicKey],\n \"#e\": [jobEventId],\n since,\n } as Filter,\n handleResult,\n );\n subs.push(resultSub2);\n\n timer = setTimeout(() => {\n if (!resolved) {\n done();\n callbacks.onError?.(`Timed out waiting for response (${timeoutMs / 1000}s).`);\n }\n }, timeoutMs);\n\n return done;\n }\n\n /** Submit payment confirmation feedback. */\n async submitPaymentConfirmation(\n identity: ElisymIdentity,\n jobEventId: string,\n providerPubkey: string,\n txSignature: string,\n ): Promise<void> {\n const event = finalizeEvent(\n {\n kind: KIND_JOB_FEEDBACK,\n created_at: Math.floor(Date.now() / 1000),\n tags: [\n [\"e\", jobEventId],\n [\"p\", providerPubkey],\n [\"status\", \"payment-completed\"],\n [\"tx\", txSignature, \"solana\"],\n [\"t\", \"elisym\"],\n ],\n content: \"\",\n },\n identity.secretKey,\n );\n\n await this.pool.publish(event);\n }\n\n /** Submit rating feedback for a job. */\n async submitFeedback(\n identity: ElisymIdentity,\n jobEventId: string,\n providerPubkey: string,\n positive: boolean,\n capability?: string,\n ): Promise<void> {\n const tags: string[][] = [\n [\"e\", jobEventId],\n [\"p\", providerPubkey],\n [\"status\", \"success\"],\n [\"rating\", positive ? \"1\" : \"0\"],\n [\"t\", \"elisym\"],\n ];\n if (capability) tags.push([\"t\", capability]);\n\n const event = finalizeEvent(\n {\n kind: KIND_JOB_FEEDBACK,\n created_at: Math.floor(Date.now() / 1000),\n tags,\n content: positive ? \"Good result\" : \"Poor result\",\n },\n identity.secretKey,\n );\n\n await this.pool.publish(event);\n }\n\n // --- Provider methods ---\n\n /** Subscribe to incoming job requests for specific kinds. */\n subscribeToJobRequests(\n identity: ElisymIdentity,\n kinds: number[],\n onRequest: (event: Event) => void,\n ): SubCloser {\n return this.pool.subscribe(\n {\n kinds,\n \"#p\": [identity.publicKey],\n since: Math.floor(Date.now() / 1000),\n } as Filter,\n onRequest,\n );\n }\n\n /** Submit a job result with NIP-44 encrypted content. Result kind is derived from the request kind. */\n async submitJobResult(\n identity: ElisymIdentity,\n requestEvent: Event,\n content: string,\n amount?: number,\n ): Promise<string> {\n const encrypted = nip44Encrypt(content, identity.secretKey, requestEvent.pubkey);\n const resultKind = KIND_JOB_RESULT_BASE + (requestEvent.kind - KIND_JOB_REQUEST_BASE);\n\n const tags: string[][] = [\n [\"e\", requestEvent.id],\n [\"p\", requestEvent.pubkey],\n [\"t\", \"elisym\"],\n [\"encrypted\", \"nip44\"],\n ];\n\n if (amount != null) {\n tags.push([\"amount\", String(amount)]);\n }\n\n const event = finalizeEvent(\n {\n kind: resultKind,\n created_at: Math.floor(Date.now() / 1000),\n tags,\n content: encrypted,\n },\n identity.secretKey,\n );\n\n await this.pool.publish(event);\n return event.id;\n }\n\n /** Submit payment-required feedback with a payment request. */\n async submitPaymentRequiredFeedback(\n identity: ElisymIdentity,\n requestEvent: Event,\n amount: number,\n paymentRequestJson: string,\n ): Promise<void> {\n const event = finalizeEvent(\n {\n kind: KIND_JOB_FEEDBACK,\n created_at: Math.floor(Date.now() / 1000),\n tags: [\n [\"e\", requestEvent.id],\n [\"p\", requestEvent.pubkey],\n [\"status\", \"payment-required\"],\n [\"amount\", String(amount), paymentRequestJson, \"solana\"],\n [\"t\", \"elisym\"],\n ],\n content: \"\",\n },\n identity.secretKey,\n );\n\n await this.pool.publish(event);\n }\n\n // --- Query methods ---\n\n /** Fetch recent jobs from the network. */\n async fetchRecentJobs(\n agentPubkeys?: Set<string>,\n limit?: number,\n since?: number,\n /** Kind offsets to query (default [100]). */\n kindOffsets?: number[],\n ): Promise<Job[]> {\n const offsets = kindOffsets ?? [DEFAULT_KIND_OFFSET];\n const requestKinds = offsets.map(jobRequestKind);\n const resultKinds = offsets.map(jobResultKind);\n\n const reqFilter: Filter = {\n kinds: requestKinds,\n \"#t\": [\"elisym\"],\n ...(limit != null && { limit }),\n ...(since != null && { since }),\n };\n const requests = await this.pool.querySync(reqFilter);\n\n const requestIds = requests.map((r) => r.id);\n let results: Event[] = [];\n let feedbacks: Event[] = [];\n\n if (requestIds.length > 0) {\n const [resultArrays, feedbackArrays] = await Promise.all([\n this.pool.queryBatchedByTag(\n { kinds: resultKinds } as Filter,\n \"e\",\n requestIds,\n ),\n this.pool.queryBatchedByTag(\n { kinds: [KIND_JOB_FEEDBACK] } as Filter,\n \"e\",\n requestIds,\n ),\n ]);\n results = resultArrays;\n feedbacks = feedbackArrays;\n }\n\n // Build targeted agent map\n const targetedAgentByRequest = new Map<string, string>();\n for (const req of requests) {\n const pTag = req.tags.find((t) => t[0] === \"p\");\n if (pTag?.[1]) targetedAgentByRequest.set(req.id, pTag[1]);\n }\n\n // Index results by request ID (respect targeted agent)\n const resultsByRequest = new Map<string, Event>();\n for (const r of results) {\n const reqId = resolveRequestId(r);\n if (!reqId) continue;\n const targeted = targetedAgentByRequest.get(reqId);\n if (targeted && r.pubkey !== targeted) continue;\n const existing = resultsByRequest.get(reqId);\n if (!existing || (targeted && r.pubkey === targeted)) {\n resultsByRequest.set(reqId, r);\n }\n }\n\n const feedbackByRequest = new Map<string, Event>();\n for (const f of feedbacks) {\n const reqId = resolveRequestId(f);\n if (!reqId) continue;\n const targeted = targetedAgentByRequest.get(reqId);\n if (targeted && f.pubkey !== targeted) continue;\n const existing = feedbackByRequest.get(reqId);\n if (!existing || (targeted && f.pubkey === targeted)) {\n feedbackByRequest.set(reqId, f);\n }\n }\n\n const jobs: Job[] = [];\n for (const req of requests) {\n const result = resultsByRequest.get(req.id);\n const feedback = feedbackByRequest.get(req.id);\n const jobAgentPubkey = result?.pubkey ?? feedback?.pubkey;\n\n if (agentPubkeys && agentPubkeys.size > 0 && jobAgentPubkey) {\n if (!agentPubkeys.has(jobAgentPubkey)) continue;\n }\n\n const capability = req.tags.find((t) => t[0] === \"t\" && t[1] !== \"elisym\")?.[1];\n const bid = req.tags.find((t) => t[0] === \"bid\")?.[1];\n\n let status: JobStatus | string = \"processing\";\n let amount: number | undefined;\n let txHash: string | undefined;\n\n if (result) {\n status = \"success\";\n const amtTag = result.tags.find((t) => t[0] === \"amount\");\n if (amtTag?.[1]) amount = parseInt(amtTag[1], 10);\n }\n\n // Check all feedbacks for tx hash\n const allFeedbacksForReq = feedbacks.filter(\n (f) => resolveRequestId(f) === req.id,\n );\n for (const fb of allFeedbacksForReq) {\n const txTag = fb.tags.find((t) => t[0] === \"tx\");\n if (txTag?.[1]) {\n txHash = txTag[1];\n break;\n }\n }\n\n if (feedback) {\n if (!result) {\n const statusTag = feedback.tags.find((t) => t[0] === \"status\");\n if (statusTag?.[1]) {\n const isTargeted = targetedAgentByRequest.has(req.id);\n if (statusTag[1] === \"payment-required\" && !bid && !isTargeted) {\n // keep \"processing\" for untargeted broadcast\n } else {\n status = statusTag[1] as JobStatus;\n }\n }\n }\n if (!amount) {\n const amtTag = feedback.tags.find((t) => t[0] === \"amount\");\n if (amtTag?.[1]) amount = parseInt(amtTag[1], 10);\n }\n }\n\n jobs.push({\n eventId: req.id,\n customer: req.pubkey,\n agentPubkey: jobAgentPubkey,\n capability,\n bid: bid ? parseInt(bid, 10) : undefined,\n status,\n result: result?.content,\n resultEventId: result?.id,\n amount,\n txHash,\n createdAt: req.created_at,\n });\n }\n\n return jobs.sort((a, b) => b.createdAt - a.createdAt);\n }\n\n /** Subscribe to live elisym events (requests, results, feedback). */\n subscribeToEvents(\n kinds: number[],\n onEvent: (event: Event) => void,\n ): SubCloser {\n return this.pool.subscribe(\n {\n kinds,\n \"#t\": [\"elisym\"],\n since: Math.floor(Date.now() / 1000),\n } as Filter,\n onEvent,\n );\n }\n}\n","import { finalizeEvent } from \"nostr-tools\";\nimport * as nip17 from \"nostr-tools/nip17\";\nimport * as nip59 from \"nostr-tools/nip59\";\nimport type { Filter } from \"nostr-tools\";\nimport type { SubCloser } from \"./pool\";\nimport type { NostrPool } from \"./pool\";\nimport { ElisymIdentity } from \"./identity\";\nimport { KIND_GIFT_WRAP, KIND_PING, KIND_PONG } from \"../constants\";\nimport type { PingResult } from \"../types\";\n\nexport class MessagingService {\n private sessionIdentity: ElisymIdentity;\n private pingCache = new Map<string, number>(); // pubkey → timestamp of last online result\n private pendingPings = new Map<string, Promise<PingResult>>(); // dedup in-flight pings\n private static PING_CACHE_TTL = 30_000; // 30s\n\n constructor(private pool: NostrPool) {\n this.sessionIdentity = ElisymIdentity.generate();\n }\n\n /**\n * Ping an agent via ephemeral Nostr events (kind 20200/20201).\n * Uses a persistent session identity to avoid relay rate-limiting.\n * Publishes to ALL relays for maximum delivery reliability.\n * Caches results for 30s to prevent redundant publishes.\n */\n async pingAgent(agentPubkey: string, timeoutMs = 15_000, signal?: AbortSignal): Promise<PingResult> {\n // Return cached online result if fresh enough (avoids relay rate-limiting)\n const cachedAt = this.pingCache.get(agentPubkey);\n if (cachedAt && Date.now() - cachedAt < MessagingService.PING_CACHE_TTL) {\n console.log(`[ping] cache hit for ${agentPubkey.slice(0, 8)}: online`);\n return { online: true, identity: this.sessionIdentity };\n }\n\n // Dedup: return existing in-flight ping for same agent (React Strict Mode sends two)\n const pending = this.pendingPings.get(agentPubkey);\n if (pending) {\n console.log(`[ping] dedup: reusing in-flight ping for ${agentPubkey.slice(0, 8)}`);\n return pending;\n }\n\n const promise = this._doPing(agentPubkey, timeoutMs, signal);\n this.pendingPings.set(agentPubkey, promise);\n promise.finally(() => this.pendingPings.delete(agentPubkey));\n return promise;\n }\n\n private async _doPing(agentPubkey: string, timeoutMs: number, signal?: AbortSignal): Promise<PingResult> {\n const sk = this.sessionIdentity.secretKey;\n const pk = this.sessionIdentity.publicKey;\n\n const nonce = crypto\n .getRandomValues(new Uint8Array(16))\n .reduce((s, b) => s + b.toString(16).padStart(2, \"0\"), \"\");\n\n const shortNonce = nonce.slice(0, 8);\n const shortAgent = agentPubkey.slice(0, 8);\n console.log(`[ping] → ping ${shortAgent} nonce=${shortNonce}`);\n\n if (signal?.aborted) {\n return { online: false, identity: null };\n }\n\n return new Promise(async (resolve) => {\n let resolved = false;\n const done = (online: boolean, reason?: string) => {\n if (resolved) return;\n resolved = true;\n clearTimeout(timer);\n sub.close();\n signal?.removeEventListener(\"abort\", onAbort);\n console.log(`[ping] ${online ? \"✓ ONLINE\" : \"✗ OFFLINE\"} agent=${shortAgent} nonce=${shortNonce}${reason ? ` (${reason})` : \"\"}`);\n if (online) this.pingCache.set(agentPubkey, Date.now());\n resolve({ online, identity: online ? this.sessionIdentity : null });\n };\n\n const onAbort = () => done(false, \"aborted\");\n signal?.addEventListener(\"abort\", onAbort);\n\n // Subscribe for ephemeral pong — no `since` (ephemeral = nothing stored)\n const sub = this.pool.subscribe(\n { kinds: [KIND_PONG], \"#p\": [pk] } as Filter,\n (ev) => {\n try {\n const msg = JSON.parse(ev.content);\n if (msg.type === \"elisym_pong\" && msg.nonce === nonce) {\n console.log(`[ping] ← pong from ${ev.pubkey.slice(0, 8)} nonce=${shortNonce}`);\n done(true, \"pong matched\");\n }\n } catch {\n /* ignore */\n }\n },\n );\n\n // Publish ephemeral ping to ALL relays\n const pingEvent = finalizeEvent(\n {\n kind: KIND_PING,\n created_at: Math.floor(Date.now() / 1000),\n tags: [[\"p\", agentPubkey]],\n content: JSON.stringify({ type: \"elisym_ping\", nonce }),\n },\n sk,\n );\n this.pool.publishAll(pingEvent)\n .then(() => console.log(`[ping] ✓ published nonce=${shortNonce}`))\n .catch((err) => {\n console.error(`[ping] ✗ publish failed nonce=${shortNonce}`, err);\n done(false, \"publish failed\");\n });\n\n const timer = setTimeout(() => done(false, \"timeout\"), timeoutMs);\n });\n }\n\n /**\n * Subscribe to incoming ephemeral ping events (kind 20200).\n * No `since` filter needed - ephemeral events are never stored.\n */\n subscribeToPings(\n identity: ElisymIdentity,\n onPing: (senderPubkey: string, nonce: string) => void,\n ): SubCloser {\n return this.pool.subscribe(\n { kinds: [KIND_PING], \"#p\": [identity.publicKey] } as Filter,\n (ev) => {\n try {\n const msg = JSON.parse(ev.content);\n if (msg.type === \"elisym_ping\" && msg.nonce) {\n onPing(ev.pubkey, msg.nonce);\n }\n } catch {\n /* ignore */\n }\n },\n );\n }\n\n /** Send an ephemeral pong response to ALL relays. */\n async sendPong(\n identity: ElisymIdentity,\n recipientPubkey: string,\n nonce: string,\n ): Promise<void> {\n const pongEvent = finalizeEvent(\n {\n kind: KIND_PONG,\n created_at: Math.floor(Date.now() / 1000),\n tags: [[\"p\", recipientPubkey]],\n content: JSON.stringify({ type: \"elisym_pong\", nonce }),\n },\n identity.secretKey,\n );\n await this.pool.publishAll(pongEvent);\n }\n\n /** Send a NIP-17 DM. */\n async sendMessage(\n identity: ElisymIdentity,\n recipientPubkey: string,\n content: string,\n ): Promise<void> {\n const wrap = nip17.wrapEvent(\n identity.secretKey,\n { publicKey: recipientPubkey },\n content,\n );\n await this.pool.publish(wrap);\n }\n\n /** Fetch historical NIP-17 DMs from relays. Returns decrypted messages sorted by time. */\n async fetchMessageHistory(\n identity: ElisymIdentity,\n since: number,\n ): Promise<{ senderPubkey: string; content: string; createdAt: number; rumorId: string }[]> {\n const events = await this.pool.querySync({\n kinds: [KIND_GIFT_WRAP],\n \"#p\": [identity.publicKey],\n since,\n } as Filter);\n\n const seen = new Set<string>();\n const messages: { senderPubkey: string; content: string; createdAt: number; rumorId: string }[] = [];\n\n for (const ev of events) {\n try {\n const rumor = nip59.unwrapEvent(ev, identity.secretKey);\n if (seen.has(rumor.id)) continue;\n seen.add(rumor.id);\n messages.push({\n senderPubkey: rumor.pubkey,\n content: rumor.content,\n createdAt: rumor.created_at,\n rumorId: rumor.id,\n });\n } catch {\n /* not encrypted for us */\n }\n }\n\n return messages.sort((a, b) => a.createdAt - b.createdAt);\n }\n\n /** Subscribe to incoming NIP-17 DMs. */\n subscribeToMessages(\n identity: ElisymIdentity,\n onMessage: (senderPubkey: string, content: string, createdAt: number, rumorId: string) => void,\n since?: number,\n ): SubCloser {\n const seen = new Set<string>();\n const filter: Filter = {\n kinds: [KIND_GIFT_WRAP],\n \"#p\": [identity.publicKey],\n };\n if (since !== undefined) filter.since = since;\n return this.pool.subscribe(\n filter,\n (ev) => {\n try {\n const rumor = nip59.unwrapEvent(ev, identity.secretKey);\n if (seen.has(rumor.id)) return;\n seen.add(rumor.id);\n onMessage(rumor.pubkey, rumor.content, rumor.created_at, rumor.id);\n } catch {\n /* not our message */\n }\n },\n );\n }\n}\n","import { PublicKey, SystemProgram, Transaction } from \"@solana/web3.js\";\nimport Decimal from \"decimal.js-light\";\nimport { PROTOCOL_FEE_BPS, PROTOCOL_TREASURY } from \"../constants\";\nimport type { PaymentRequestData } from \"../types\";\n\nexport class PaymentService {\n /**\n * Calculate protocol fee using Decimal basis-point math (no floats).\n * Returns ceil(amount * PROTOCOL_FEE_BPS / 10000).\n */\n static calculateProtocolFee(amount: number): number {\n if (amount === 0) return 0;\n return new Decimal(amount)\n .mul(PROTOCOL_FEE_BPS)\n .div(10000)\n .toDecimalPlaces(0, Decimal.ROUND_CEIL)\n .toNumber();\n }\n\n /**\n * Validate that a payment request has the correct recipient and protocol fee.\n * Returns an error message if invalid, null if OK.\n */\n static validatePaymentFee(\n requestJson: string,\n expectedRecipient?: string,\n ): string | null {\n let data: PaymentRequestData;\n try {\n data = JSON.parse(requestJson);\n } catch (e) {\n return `Invalid payment request JSON: ${e}`;\n }\n\n if (expectedRecipient && data.recipient !== expectedRecipient) {\n return (\n `Recipient mismatch: expected ${expectedRecipient}, got ${data.recipient}. ` +\n `Provider may be attempting to redirect payment.`\n );\n }\n\n // Check expiry (created_at + expiry_secs)\n if (data.created_at > 0 && data.expiry_secs > 0) {\n const elapsed = Math.floor(Date.now() / 1000) - data.created_at;\n if (elapsed > data.expiry_secs) {\n return `Payment request expired (created ${data.created_at}, expiry ${data.expiry_secs}s).`;\n }\n }\n\n const expectedFee = PaymentService.calculateProtocolFee(data.amount);\n\n const { fee_address, fee_amount } = data;\n\n if (fee_address && fee_amount && fee_amount > 0) {\n if (fee_address !== PROTOCOL_TREASURY) {\n return (\n `Fee address mismatch: expected ${PROTOCOL_TREASURY}, got ${fee_address}. ` +\n `Provider may be attempting to redirect fees.`\n );\n }\n if (fee_amount !== expectedFee) {\n return (\n `Fee amount mismatch: expected ${expectedFee} lamports ` +\n `(${PROTOCOL_FEE_BPS}bps of ${data.amount}), got ${fee_amount}. ` +\n `Provider may be tampering with fee.`\n );\n }\n return null;\n }\n\n if (!fee_address && !fee_amount) {\n return (\n `Payment request missing protocol fee (${PROTOCOL_FEE_BPS}bps). ` +\n `Expected fee: ${expectedFee} lamports to ${PROTOCOL_TREASURY}.`\n );\n }\n\n return (\n `Invalid fee params in payment request. ` +\n `Expected fee: ${expectedFee} lamports to ${PROTOCOL_TREASURY}.`\n );\n }\n\n /**\n * Build a Solana transaction from a payment request.\n * The caller must sign and send via wallet adapter.\n */\n static buildPaymentTransaction(\n payerPubkey: PublicKey,\n paymentRequest: PaymentRequestData,\n ): Transaction {\n const recipient = new PublicKey(paymentRequest.recipient);\n const reference = new PublicKey(paymentRequest.reference);\n const feeAddress = paymentRequest.fee_address\n ? new PublicKey(paymentRequest.fee_address)\n : null;\n const feeAmount = paymentRequest.fee_amount ?? 0;\n\n const providerAmount =\n feeAddress && feeAmount > 0\n ? new Decimal(paymentRequest.amount).minus(feeAmount).toNumber()\n : paymentRequest.amount;\n\n // Provider transfer with reference key (for payment detection)\n const transferIx = SystemProgram.transfer({\n fromPubkey: payerPubkey,\n toPubkey: recipient,\n lamports: providerAmount,\n });\n // Append reference as read-only non-signer so provider can detect via getSignaturesForAddress\n transferIx.keys.push({\n pubkey: reference,\n isSigner: false,\n isWritable: false,\n });\n\n const tx = new Transaction().add(transferIx);\n\n // Fee transfer\n if (feeAddress && feeAmount > 0) {\n tx.add(\n SystemProgram.transfer({\n fromPubkey: payerPubkey,\n toPubkey: feeAddress,\n lamports: feeAmount,\n }),\n );\n }\n\n return tx;\n }\n\n /**\n * Create a payment request with auto-calculated protocol fee.\n * Used by providers to generate payment requests for customers.\n */\n static createPaymentRequest(\n recipientAddress: string,\n amount: number,\n expirySecs = 600,\n ): PaymentRequestData {\n const feeAmount = PaymentService.calculateProtocolFee(amount);\n const reference = PublicKey.unique().toBase58();\n\n return {\n recipient: recipientAddress,\n amount,\n reference,\n fee_address: PROTOCOL_TREASURY,\n fee_amount: feeAmount,\n created_at: Math.floor(Date.now() / 1000),\n expiry_secs: expirySecs,\n };\n }\n}\n","import Decimal from \"decimal.js-light\";\nimport { LAMPORTS_PER_SOL } from \"../constants\";\n\nexport function formatSol(lamports: number): string {\n const sol = new Decimal(lamports).div(LAMPORTS_PER_SOL);\n if (sol.gte(1_000_000)) return `${sol.idiv(1_000_000)}m SOL`;\n if (sol.gte(10_000)) return `${sol.idiv(1_000)}k SOL`;\n return `${compactSol(sol)} SOL`;\n}\n\n/** Format a SOL Decimal — show enough decimals so the value isn't lost. */\nfunction compactSol(sol: Decimal): string {\n if (sol.isZero()) return \"0\";\n if (sol.gte(1000)) return sol.toDecimalPlaces(0, Decimal.ROUND_FLOOR).toString();\n // Show enough decimals so the rounded value equals the original\n const maxFrac = 9; // lamport precision\n for (let d = 1; d <= maxFrac; d++) {\n const s = sol.toFixed(d);\n if (new Decimal(s).eq(sol)) {\n return s.replace(/0+$/, \"\").replace(/\\.$/, \"\");\n }\n }\n return sol.toFixed(maxFrac).replace(/0+$/, \"\").replace(/\\.$/, \"\");\n}\n\nexport function timeAgo(unix: number): string {\n const seconds = Math.max(0, Math.floor(Date.now() / 1000 - unix));\n if (seconds < 60) return `${seconds}s ago`;\n const minutes = Math.floor(seconds / 60);\n if (minutes < 60) return `${minutes}m ago`;\n const hours = Math.floor(minutes / 60);\n if (hours < 24) return `${hours}h ago`;\n const days = Math.floor(hours / 24);\n return `${days}d ago`;\n}\n\nexport function truncateKey(hex: string, chars = 6): string {\n if (hex.length <= chars * 2) return hex;\n return `${hex.slice(0, chars)}...${hex.slice(-chars)}`;\n}\n","import { nip19 } from \"nostr-tools\";\nimport { RELAYS } from \"../constants\";\n\nexport function makeNjumpUrl(\n eventId: string,\n relays: string[] = RELAYS,\n): string {\n const nevent = nip19.neventEncode({\n id: eventId,\n relays: relays.slice(0, 2),\n });\n return `https://njump.me/${nevent}`;\n}\n","// Core services\nexport { NostrPool } from \"./core/pool\";\nexport type { SubCloser } from \"./core/pool\";\nexport { ElisymIdentity } from \"./core/identity\";\nexport { DiscoveryService, toDTag } from \"./core/discovery\";\nexport { MarketplaceService } from \"./core/marketplace\";\nexport { MessagingService } from \"./core/messaging\";\nexport { PaymentService } from \"./core/payment\";\n\n// Utilities\nexport { formatSol, timeAgo, truncateKey } from \"./core/format\";\nexport { makeNjumpUrl } from \"./core/njump\";\n\n// Constants\nexport {\n RELAYS,\n KIND_APP_HANDLER,\n KIND_JOB_REQUEST_BASE,\n KIND_JOB_RESULT_BASE,\n KIND_JOB_REQUEST,\n KIND_JOB_RESULT,\n KIND_JOB_FEEDBACK,\n DEFAULT_KIND_OFFSET,\n jobRequestKind,\n jobResultKind,\n KIND_GIFT_WRAP,\n KIND_PING,\n KIND_PONG,\n LAMPORTS_PER_SOL,\n PROTOCOL_FEE_BPS,\n PROTOCOL_TREASURY,\n} from \"./constants\";\n\n// Types\nexport type {\n PaymentInfo,\n CapabilityCard,\n Agent,\n JobStatus,\n Job,\n NetworkStats,\n Network,\n PingResult,\n PaymentRequestData,\n ElisymClientConfig,\n} from \"./types\";\nexport type { SubmitJobOptions, JobUpdateCallbacks } from \"./core/marketplace\";\n\n// Top-level orchestrator\nimport { NostrPool } from \"./core/pool\";\nimport { DiscoveryService } from \"./core/discovery\";\nimport { MarketplaceService } from \"./core/marketplace\";\nimport { MessagingService } from \"./core/messaging\";\nimport { RELAYS } from \"./constants\";\nimport type { ElisymClientConfig } from \"./types\";\n\nexport class ElisymClient {\n readonly pool: NostrPool;\n readonly discovery: DiscoveryService;\n readonly marketplace: MarketplaceService;\n readonly messaging: MessagingService;\n\n constructor(config: ElisymClientConfig = {}) {\n this.pool = new NostrPool(config.relays ?? RELAYS);\n this.discovery = new DiscoveryService(this.pool);\n this.marketplace = new MarketplaceService(this.pool);\n this.messaging = new MessagingService(this.pool);\n }\n\n close(): void {\n this.pool.close();\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/constants.ts","../src/payment/fee.ts","../src/payment/solana.ts","../src/services/discovery.ts","../src/primitives/crypto.ts","../src/services/marketplace.ts","../src/services/media.ts","../src/primitives/bounded-set.ts","../src/primitives/identity.ts","../src/services/messaging.ts","../src/transport/pool.ts","../src/client.ts","../src/primitives/format.ts","../src/primitives/config.ts"],"names":["Decimal","PublicKey","Keypair","SystemProgram","Transaction","verifyEvent","nip19","finalizeEvent","nip44","getPublicKey","generateSecretKey","nip17","nip59","SimplePool"],"mappings":"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","file":"index.cjs","sourcesContent":["export const RELAYS = [\n 'wss://relay.damus.io',\n 'wss://nos.lol',\n 'wss://relay.nostr.band',\n 'wss://relay.primal.net',\n 'wss://relay.snort.social',\n];\n\nexport const KIND_APP_HANDLER = 31990;\nexport const KIND_JOB_REQUEST_BASE = 5000;\nexport const KIND_JOB_RESULT_BASE = 6000;\nexport const KIND_JOB_FEEDBACK = 7000;\nexport const DEFAULT_KIND_OFFSET = 100;\nexport const KIND_GIFT_WRAP = 1059;\n\n/** Default job request kind (5000 + 100). */\nexport const KIND_JOB_REQUEST = KIND_JOB_REQUEST_BASE + DEFAULT_KIND_OFFSET;\n/** Default job result kind (6000 + 100). */\nexport const KIND_JOB_RESULT = KIND_JOB_RESULT_BASE + DEFAULT_KIND_OFFSET;\n\n/** Compute a job request kind from an offset (5000 + offset). */\nexport function jobRequestKind(offset: number): number {\n if (!Number.isInteger(offset) || offset < 0 || offset >= 1000) {\n throw new Error(`Invalid kind offset: ${offset}. Must be integer 0-999.`);\n }\n return KIND_JOB_REQUEST_BASE + offset;\n}\n\n/** Compute a job result kind from an offset (6000 + offset). */\nexport function jobResultKind(offset: number): number {\n if (!Number.isInteger(offset) || offset < 0 || offset >= 1000) {\n throw new Error(`Invalid kind offset: ${offset}. Must be integer 0-999.`);\n }\n return KIND_JOB_RESULT_BASE + offset;\n}\n\n/** Ephemeral ping/pong kinds (not stored by relays, forwarded in real-time). */\nexport const KIND_PING = 20200;\nexport const KIND_PONG = 20201;\n\nexport const LAMPORTS_PER_SOL = 1_000_000_000;\n\n/** Protocol fee in basis points (300 = 3%). */\nexport const PROTOCOL_FEE_BPS = 300;\n/** Solana address of the protocol treasury. */\nexport const PROTOCOL_TREASURY = 'GY7vnWMkKpftU4nQ16C2ATkj1JwrQpHhknkaBUn67VTy';\n\n/** Default values for timeouts, retries, and batch sizes. */\nexport const DEFAULTS = {\n SUBSCRIPTION_TIMEOUT_MS: 120_000,\n PING_TIMEOUT_MS: 15_000,\n PING_RETRIES: 2,\n PING_CACHE_TTL_MS: 30_000,\n PAYMENT_EXPIRY_SECS: 600,\n BATCH_SIZE: 250,\n QUERY_TIMEOUT_MS: 15_000,\n EOSE_TIMEOUT_MS: 3_000,\n VERIFY_RETRIES: 10,\n VERIFY_INTERVAL_MS: 3_000,\n VERIFY_BY_REF_RETRIES: 15,\n VERIFY_BY_REF_INTERVAL_MS: 2_000,\n RESULT_RETRY_COUNT: 3,\n RESULT_RETRY_BASE_MS: 1_000,\n QUERY_MAX_CONCURRENCY: 6,\n VERIFY_SIGNATURE_LIMIT: 25,\n} as const;\n\n/** Protocol limits for input validation. */\nexport const LIMITS = {\n MAX_INPUT_LENGTH: 100_000,\n MAX_TIMEOUT_SECS: 600,\n MAX_CAPABILITIES: 20,\n MAX_DESCRIPTION_LENGTH: 500,\n MAX_AGENT_NAME_LENGTH: 64,\n MAX_MESSAGE_LENGTH: 10_000,\n MAX_CAPABILITY_LENGTH: 64,\n} as const;\n","import Decimal from 'decimal.js-light';\nimport { PROTOCOL_FEE_BPS } from '../constants';\n\n/** Assert that a value is a non-negative integer (lamports). */\nexport function assertLamports(value: number, field: string): void {\n if (!Number.isInteger(value) || value < 0) {\n throw new Error(`Invalid ${field}: ${value}. Must be a non-negative integer.`);\n }\n}\n\n/**\n * Calculate protocol fee using Decimal basis-point math (no floats).\n * Returns ceil(amount * PROTOCOL_FEE_BPS / 10000).\n * Safe for amounts up to Number.MAX_SAFE_INTEGER - Decimal handles intermediate values.\n */\nexport function calculateProtocolFee(amount: number): number {\n if (!Number.isInteger(amount) || amount < 0) {\n throw new Error(`Invalid fee amount: ${amount}. Must be a non-negative integer.`);\n }\n if (amount === 0) {\n return 0;\n }\n return new Decimal(amount)\n .mul(PROTOCOL_FEE_BPS)\n .div(10000)\n .toDecimalPlaces(0, Decimal.ROUND_CEIL)\n .toNumber();\n}\n\n/** Validate payment request timestamps. Returns error message or null if valid. */\nexport function validateExpiry(createdAt: number, expirySecs: number): string | null {\n if (!Number.isInteger(createdAt) || createdAt <= 0) {\n return 'Invalid or missing created_at in payment request.';\n }\n if (!Number.isInteger(expirySecs) || expirySecs <= 0) {\n return 'Invalid or missing expiry_secs in payment request.';\n }\n const now = Math.floor(Date.now() / 1000);\n if (createdAt > now + 120) {\n return `Payment request created_at is in the future (${createdAt} vs now ${now}). Possible manipulation.`;\n }\n if (now - createdAt > expirySecs) {\n return `Payment request expired (created ${createdAt}, expiry ${expirySecs}s).`;\n }\n return null;\n}\n\n/** Assert that payment request timestamps are valid and not expired. Throws on failure. */\nexport function assertExpiry(createdAt: number, expirySecs: number): void {\n const error = validateExpiry(createdAt, expirySecs);\n if (error) {\n throw new Error(error);\n }\n}\n","import { Connection, Keypair, PublicKey, SystemProgram, Transaction } from '@solana/web3.js';\nimport { PROTOCOL_TREASURY, PROTOCOL_FEE_BPS, DEFAULTS, LIMITS } from '../constants';\nimport type {\n PaymentRequestData,\n VerifyResult,\n VerifyOptions,\n PaymentValidationError,\n} from '../types';\nimport { calculateProtocolFee, validateExpiry, assertExpiry, assertLamports } from './fee';\nimport type { PaymentStrategy } from './strategy';\n\nfunction isValidSolanaAddress(address: string): boolean {\n try {\n void new PublicKey(address);\n return true;\n } catch {\n return false;\n }\n}\n\nexport class SolanaPaymentStrategy implements PaymentStrategy {\n readonly chain = 'solana';\n\n calculateFee(amount: number): number {\n return calculateProtocolFee(amount);\n }\n\n createPaymentRequest(\n recipientAddress: string,\n amount: number,\n expirySecs: number = DEFAULTS.PAYMENT_EXPIRY_SECS,\n ): PaymentRequestData {\n try {\n void new PublicKey(recipientAddress);\n } catch {\n throw new Error(`Invalid Solana address: ${recipientAddress}`);\n }\n assertLamports(amount, 'payment amount');\n if (amount === 0) {\n throw new Error('Invalid payment amount: 0. Must be positive.');\n }\n if (!Number.isInteger(expirySecs) || expirySecs <= 0 || expirySecs > LIMITS.MAX_TIMEOUT_SECS) {\n throw new Error(\n `Invalid expiry: ${expirySecs}. Must be integer 1-${LIMITS.MAX_TIMEOUT_SECS}.`,\n );\n }\n const feeAmount = calculateProtocolFee(amount);\n const reference = Keypair.generate().publicKey.toBase58();\n\n return {\n recipient: recipientAddress,\n amount,\n reference,\n fee_address: PROTOCOL_TREASURY,\n fee_amount: feeAmount,\n created_at: Math.floor(Date.now() / 1000),\n expiry_secs: expirySecs,\n };\n }\n\n validatePaymentRequest(\n requestJson: string,\n expectedRecipient?: string,\n ): PaymentValidationError | null {\n let data: PaymentRequestData;\n try {\n data = JSON.parse(requestJson);\n } catch (e) {\n return { code: 'invalid_json', message: `Invalid payment request JSON: ${e}` };\n }\n\n if (typeof data.amount !== 'number' || !Number.isInteger(data.amount) || data.amount <= 0) {\n return {\n code: 'invalid_amount',\n message: `Invalid amount in payment request: ${data.amount}`,\n };\n }\n if (typeof data.recipient !== 'string' || !data.recipient) {\n return { code: 'missing_recipient', message: 'Missing recipient in payment request' };\n }\n if (!isValidSolanaAddress(data.recipient)) {\n return {\n code: 'invalid_recipient_address',\n message: `Invalid Solana address for recipient: ${data.recipient}`,\n };\n }\n if (typeof data.reference !== 'string' || !data.reference) {\n return { code: 'missing_reference', message: 'Missing reference in payment request' };\n }\n if (!isValidSolanaAddress(data.reference)) {\n return {\n code: 'invalid_reference_address',\n message: `Invalid Solana address for reference: ${data.reference}`,\n };\n }\n\n if (expectedRecipient && data.recipient !== expectedRecipient) {\n return {\n code: 'recipient_mismatch',\n message:\n `Recipient mismatch: expected ${expectedRecipient}, got ${data.recipient}. ` +\n `Provider may be attempting to redirect payment.`,\n };\n }\n\n const expiryError = validateExpiry(data.created_at, data.expiry_secs);\n if (expiryError) {\n const code = expiryError.includes('future')\n ? ('future_timestamp' as const)\n : ('expired' as const);\n return { code, message: expiryError };\n }\n\n const expectedFee = calculateProtocolFee(data.amount);\n\n const { fee_address, fee_amount } = data;\n const hasFeeAddress = typeof fee_address === 'string' && fee_address.length > 0;\n const hasFeeAmount = typeof fee_amount === 'number' && fee_amount > 0;\n\n // Branch 1: fee present and valid - verify address and amount\n if (hasFeeAddress && hasFeeAmount) {\n if (fee_address !== PROTOCOL_TREASURY) {\n return {\n code: 'fee_address_mismatch',\n message:\n `Fee address mismatch: expected ${PROTOCOL_TREASURY}, got ${fee_address}. ` +\n `Provider may be attempting to redirect fees.`,\n };\n }\n if (fee_amount !== expectedFee) {\n return {\n code: 'fee_amount_mismatch',\n message:\n `Fee amount mismatch: expected ${expectedFee} lamports ` +\n `(${PROTOCOL_FEE_BPS}bps of ${data.amount}), got ${fee_amount}. ` +\n `Provider may be tampering with fee.`,\n };\n }\n return null;\n }\n\n // Branch 2: fee entirely absent - reject\n if (!hasFeeAddress && (fee_amount === null || fee_amount === undefined || fee_amount === 0)) {\n return {\n code: 'missing_fee',\n message:\n `Payment request missing protocol fee (${PROTOCOL_FEE_BPS}bps). ` +\n `Expected fee: ${expectedFee} lamports to ${PROTOCOL_TREASURY}.`,\n };\n }\n\n // Branch 3: partial fee params (one present, other missing/zero) - reject\n return {\n code: 'invalid_fee_params',\n message:\n `Invalid fee params in payment request. ` +\n `Expected fee: ${expectedFee} lamports to ${PROTOCOL_TREASURY}.`,\n };\n }\n\n /**\n * Build an unsigned transaction from a payment request.\n * The caller must set `recentBlockhash` and `feePayer` on the\n * returned Transaction before signing and sending.\n */\n async buildTransaction(\n payerAddress: string,\n paymentRequest: PaymentRequestData,\n ): Promise<Transaction> {\n assertLamports(paymentRequest.amount, 'payment amount');\n if (paymentRequest.amount === 0) {\n throw new Error('Invalid payment amount: 0. Must be positive.');\n }\n if (\n paymentRequest.fee_amount !== null &&\n paymentRequest.fee_amount !== undefined &&\n (!Number.isInteger(paymentRequest.fee_amount) || paymentRequest.fee_amount < 0)\n ) {\n throw new Error(\n `Invalid fee amount: ${paymentRequest.fee_amount}. Must be a non-negative integer (lamports).`,\n );\n }\n assertExpiry(paymentRequest.created_at, paymentRequest.expiry_secs);\n\n if (paymentRequest.fee_address && paymentRequest.fee_address !== PROTOCOL_TREASURY) {\n throw new Error(\n `Invalid fee address: expected ${PROTOCOL_TREASURY}, got ${paymentRequest.fee_address}. ` +\n `Cannot build transaction with redirected fees.`,\n );\n }\n\n const payerPubkey = new PublicKey(payerAddress);\n const recipient = new PublicKey(paymentRequest.recipient);\n const reference = new PublicKey(paymentRequest.reference);\n const feeAddress = paymentRequest.fee_address\n ? new PublicKey(paymentRequest.fee_address)\n : null;\n const feeAmount = paymentRequest.fee_amount ?? 0;\n\n // Both amount and feeAmount are validated integers (lamports), so subtraction is exact.\n const providerAmount =\n feeAddress && feeAmount > 0 ? paymentRequest.amount - feeAmount : paymentRequest.amount;\n\n if (providerAmount <= 0) {\n throw new Error(\n `Fee amount (${feeAmount}) exceeds or equals total amount (${paymentRequest.amount}). Cannot create transaction with non-positive provider amount.`,\n );\n }\n\n // Provider transfer with reference key (for payment detection)\n const transferIx = SystemProgram.transfer({\n fromPubkey: payerPubkey,\n toPubkey: recipient,\n lamports: providerAmount,\n });\n // Append reference as read-only non-signer so provider can detect via getSignaturesForAddress\n transferIx.keys.push({\n pubkey: reference,\n isSigner: false,\n isWritable: false,\n });\n\n const tx = new Transaction().add(transferIx);\n\n // Fee transfer\n if (feeAddress && feeAmount > 0) {\n tx.add(\n SystemProgram.transfer({\n fromPubkey: payerPubkey,\n toPubkey: feeAddress,\n lamports: feeAmount,\n }),\n );\n }\n\n return tx;\n }\n\n async verifyPayment(\n connection: unknown,\n paymentRequest: PaymentRequestData,\n options?: VerifyOptions,\n ): Promise<VerifyResult> {\n if (\n !connection ||\n typeof (connection as Record<string, unknown>).getTransaction !== 'function'\n ) {\n return { verified: false, error: 'Invalid connection: expected Solana Connection instance' };\n }\n const conn = connection as Connection;\n\n if (!paymentRequest.reference || !paymentRequest.recipient) {\n return { verified: false, error: 'Missing required fields in payment request' };\n }\n if (!Number.isInteger(paymentRequest.amount) || paymentRequest.amount <= 0) {\n return {\n verified: false,\n error: `Invalid payment amount: ${paymentRequest.amount}. Must be a positive integer.`,\n };\n }\n\n // No expiry check here - verification confirms on-chain payment regardless of timing.\n // Expiry is enforced before payment in validatePaymentRequest() and buildTransaction().\n\n if (\n paymentRequest.fee_amount !== null &&\n paymentRequest.fee_amount !== undefined &&\n (!Number.isInteger(paymentRequest.fee_amount) || paymentRequest.fee_amount < 0)\n ) {\n return {\n verified: false,\n error: `Invalid fee_amount: ${paymentRequest.fee_amount}. Must be a non-negative integer.`,\n };\n }\n\n const expectedFee = calculateProtocolFee(paymentRequest.amount);\n const feeAmount = paymentRequest.fee_amount ?? 0;\n\n if (expectedFee > 0) {\n if (feeAmount < expectedFee) {\n return {\n verified: false,\n error: `Protocol fee ${feeAmount} below required ${expectedFee} (${PROTOCOL_FEE_BPS}bps of ${paymentRequest.amount})`,\n };\n }\n if (!paymentRequest.fee_address) {\n return { verified: false, error: 'Missing fee address in payment request' };\n }\n if (paymentRequest.fee_address !== PROTOCOL_TREASURY) {\n return { verified: false, error: `Invalid fee address: ${paymentRequest.fee_address}` };\n }\n }\n\n // Both amount and feeAmount are validated integers (lamports), so subtraction is exact.\n const expectedNet = paymentRequest.amount - feeAmount;\n\n if (expectedNet <= 0) {\n return {\n verified: false,\n error: `Fee amount (${feeAmount}) exceeds or equals total amount (${paymentRequest.amount})`,\n };\n }\n\n // If tx signature provided, verify by signature\n if (options?.txSignature) {\n return this._verifyBySignature(\n conn,\n options.txSignature,\n paymentRequest.reference,\n paymentRequest.recipient,\n expectedNet,\n feeAmount,\n options?.retries ?? DEFAULTS.VERIFY_RETRIES,\n options?.intervalMs ?? DEFAULTS.VERIFY_INTERVAL_MS,\n );\n }\n\n // Otherwise verify by reference key\n return this._verifyByReference(\n conn,\n paymentRequest.reference,\n paymentRequest.recipient,\n expectedNet,\n feeAmount,\n options?.retries ?? DEFAULTS.VERIFY_BY_REF_RETRIES,\n options?.intervalMs ?? DEFAULTS.VERIFY_BY_REF_INTERVAL_MS,\n );\n }\n\n private async _verifyBySignature(\n connection: Connection,\n txSignature: string,\n referenceKey: string,\n recipientAddress: string,\n expectedNet: number,\n expectedFee: number,\n retries: number,\n intervalMs: number,\n ): Promise<VerifyResult> {\n let lastError: unknown;\n for (let attempt = 0; attempt < retries; attempt++) {\n try {\n const tx = await connection.getTransaction(txSignature, {\n maxSupportedTransactionVersion: 0,\n commitment: 'confirmed',\n });\n\n if (!tx?.meta || tx.meta.err) {\n if (attempt < retries - 1) {\n await new Promise((r) => setTimeout(r, intervalMs));\n continue;\n }\n return {\n verified: false,\n error: tx?.meta?.err ? 'Transaction failed on-chain' : 'Transaction not found',\n };\n }\n\n const accountKeys = tx.transaction.message.getAccountKeys();\n const balanceCount = tx.meta.preBalances.length;\n // Map address -> original index to preserve balance array correspondence.\n const keyToIdx = new Map<string, number>();\n for (let i = 0; i < Math.min(accountKeys.length, balanceCount); i++) {\n const key = accountKeys.get(i);\n if (key) {\n keyToIdx.set(key.toBase58(), i);\n }\n }\n\n if (!keyToIdx.has(referenceKey)) {\n return {\n verified: false,\n error: 'Reference key not found in transaction - possible replay',\n };\n }\n\n const recipientIdx = keyToIdx.get(recipientAddress);\n if (recipientIdx === undefined) {\n return { verified: false, error: 'Recipient not found in transaction' };\n }\n\n const recipientDelta =\n (tx.meta.postBalances[recipientIdx] ?? 0) - (tx.meta.preBalances[recipientIdx] ?? 0);\n if (recipientDelta < expectedNet) {\n return {\n verified: false,\n error: `Recipient received ${recipientDelta}, expected >= ${expectedNet}`,\n };\n }\n\n if (expectedFee > 0) {\n const treasuryIdx = keyToIdx.get(PROTOCOL_TREASURY);\n if (treasuryIdx === undefined) {\n return { verified: false, error: 'Treasury not found in transaction' };\n }\n const treasuryDelta =\n (tx.meta.postBalances[treasuryIdx] ?? 0) - (tx.meta.preBalances[treasuryIdx] ?? 0);\n if (treasuryDelta < expectedFee) {\n return {\n verified: false,\n error: `Treasury received ${treasuryDelta}, expected >= ${expectedFee}`,\n };\n }\n }\n\n return { verified: true, txSignature };\n } catch (err) {\n lastError = err;\n if (attempt < retries - 1) {\n await new Promise((r) => setTimeout(r, intervalMs));\n }\n }\n }\n return {\n verified: false,\n error: `Verification failed after ${retries} retries: ${lastError instanceof Error ? lastError.message : 'unknown error'}`,\n };\n }\n\n private async _verifyByReference(\n connection: Connection,\n referenceKey: string,\n recipientAddress: string,\n expectedNet: number,\n expectedFee: number,\n retries: number,\n intervalMs: number,\n ): Promise<VerifyResult> {\n const reference = new PublicKey(referenceKey);\n let lastError: unknown;\n\n for (let attempt = 0; attempt < retries; attempt++) {\n try {\n const signatures = await connection.getSignaturesForAddress(reference, {\n limit: DEFAULTS.VERIFY_SIGNATURE_LIMIT,\n });\n const validSigs = signatures.filter((s) => !s.err);\n\n if (validSigs.length > 0) {\n const txResults = await Promise.all(\n validSigs.map((s) =>\n connection\n .getTransaction(s.signature, {\n maxSupportedTransactionVersion: 0,\n commitment: 'confirmed',\n })\n .then((tx) => ({ sig: s.signature, tx }))\n .catch(() => ({\n sig: s.signature,\n tx: null as Awaited<ReturnType<Connection['getTransaction']>>,\n })),\n ),\n );\n\n for (const { sig, tx } of txResults) {\n if (!tx?.meta || tx.meta.err) {\n continue;\n }\n\n const accountKeys = tx.transaction.message.getAccountKeys();\n const balanceCount = tx.meta.preBalances.length;\n // Map address -> original index to preserve balance array correspondence.\n const keyToIdx = new Map<string, number>();\n for (let i = 0; i < Math.min(accountKeys.length, balanceCount); i++) {\n const key = accountKeys.get(i);\n if (key) {\n keyToIdx.set(key.toBase58(), i);\n }\n }\n\n const recipientIdx = keyToIdx.get(recipientAddress);\n if (recipientIdx === undefined) {\n continue;\n }\n\n const recipientDelta =\n (tx.meta.postBalances[recipientIdx] ?? 0) - (tx.meta.preBalances[recipientIdx] ?? 0);\n if (recipientDelta < expectedNet) {\n continue;\n }\n\n if (expectedFee > 0) {\n const treasuryIdx = keyToIdx.get(PROTOCOL_TREASURY);\n if (treasuryIdx === undefined) {\n continue;\n }\n const treasuryDelta =\n (tx.meta.postBalances[treasuryIdx] ?? 0) - (tx.meta.preBalances[treasuryIdx] ?? 0);\n if (treasuryDelta < expectedFee) {\n continue;\n }\n }\n\n return { verified: true, txSignature: sig };\n }\n }\n } catch (err) {\n lastError = err;\n }\n\n if (attempt < retries - 1) {\n await new Promise((r) => setTimeout(r, intervalMs));\n }\n }\n return {\n verified: false,\n error: lastError\n ? `Verification failed: ${lastError instanceof Error ? lastError.message : 'unknown error'}`\n : 'No matching transaction found for reference key',\n };\n }\n}\n","import { nip19, finalizeEvent, verifyEvent, type Filter, type Event } from 'nostr-tools';\nimport {\n KIND_APP_HANDLER,\n KIND_JOB_FEEDBACK,\n KIND_JOB_REQUEST,\n KIND_JOB_REQUEST_BASE,\n KIND_JOB_RESULT_BASE,\n jobResultKind,\n DEFAULT_KIND_OFFSET,\n LIMITS,\n} from '../constants';\nimport type { ElisymIdentity } from '../primitives/identity';\nimport type { NostrPool } from '../transport/pool';\nimport type { Agent, CapabilityCard, Network } from '../types';\n\n/** Convert a capability name to its Nostr d-tag form (ASCII-only, lowercase, hyphen-separated). */\nexport function toDTag(name: string): string {\n const tag = name\n .toLowerCase()\n .replace(/[^a-z0-9\\s-]/g, (ch) => '_' + ch.charCodeAt(0).toString(16).padStart(2, '0'))\n .replace(/\\s+/g, '-')\n .replace(/^-+|-+$/g, '');\n if (!tag) {\n throw new Error('Capability name must contain at least one ASCII alphanumeric character.');\n }\n return tag;\n}\n\n/**\n * Deduplicate events by (pubkey, d-tag) keeping only the newest,\n * then build an Agent map filtered by network.\n */\nfunction buildAgentsFromEvents(events: Event[], network: Network): Map<string, Agent> {\n // Deduplicate by author + d-tag, keeping only the newest event\n const latestByDTag = new Map<string, Event>();\n for (const event of events) {\n if (!verifyEvent(event)) {\n continue;\n }\n const dTag = event.tags.find((t) => t[0] === 'd')?.[1] ?? '';\n const key = `${event.pubkey}:${dTag}`;\n const prev = latestByDTag.get(key);\n if (!prev || event.created_at > prev.created_at) {\n latestByDTag.set(key, event);\n }\n }\n\n // Intermediate structure: keep kTags per card so we can recompute\n // supportedKinds from only the surviving (deduplicated) entries.\n interface CardEntry {\n card: CapabilityCard;\n kTags: number[];\n createdAt: number;\n }\n interface AgentAccum {\n pubkey: string;\n npub: string;\n entries: CardEntry[];\n eventId: string;\n lastSeen: number;\n }\n\n const accumMap = new Map<string, AgentAccum>();\n\n for (const event of latestByDTag.values()) {\n try {\n if (!event.content) {\n continue;\n }\n const raw = JSON.parse(event.content);\n if (!raw || typeof raw !== 'object') {\n continue;\n }\n if (typeof raw.name !== 'string' || !raw.name) {\n continue;\n }\n if (typeof raw.description !== 'string') {\n continue;\n }\n if (\n !Array.isArray(raw.capabilities) ||\n !raw.capabilities.every((c: unknown) => typeof c === 'string')\n ) {\n continue;\n }\n if (raw.deleted) {\n continue;\n }\n const card = raw as CapabilityCard & { deleted?: boolean };\n\n // Validate payment field types if present\n if (\n card.payment &&\n (typeof card.payment.chain !== 'string' ||\n typeof card.payment.network !== 'string' ||\n typeof card.payment.address !== 'string')\n ) {\n continue;\n }\n\n // Validate payment.job_price if present\n if (\n card.payment?.job_price !== null &&\n card.payment?.job_price !== undefined &&\n (!Number.isInteger(card.payment.job_price) || card.payment.job_price < 0)\n ) {\n continue;\n }\n\n const agentNetwork = card.payment?.network ?? 'devnet';\n if (agentNetwork !== network) {\n continue;\n }\n\n const kTags = event.tags\n .filter((t) => t[0] === 'k')\n .map((t) => parseInt(t[1] ?? '', 10))\n .filter((k) => !isNaN(k));\n\n const entry: CardEntry = { card, kTags, createdAt: event.created_at };\n\n const existing = accumMap.get(event.pubkey);\n if (existing) {\n // Deduplicate by card name - keep the newer version\n const dupIndex = existing.entries.findIndex((e) => e.card.name === card.name);\n if (dupIndex >= 0) {\n if (entry.createdAt >= existing.entries[dupIndex]!.createdAt) {\n existing.entries[dupIndex] = entry;\n }\n } else {\n existing.entries.push(entry);\n }\n if (event.created_at > existing.lastSeen) {\n existing.lastSeen = event.created_at;\n existing.eventId = event.id;\n }\n } else {\n accumMap.set(event.pubkey, {\n pubkey: event.pubkey,\n npub: nip19.npubEncode(event.pubkey),\n entries: [entry],\n eventId: event.id,\n lastSeen: event.created_at,\n });\n }\n } catch {\n // skip malformed events\n }\n }\n\n // Build final Agent map - recompute supportedKinds from surviving entries only\n const agentMap = new Map<string, Agent>();\n for (const [pubkey, acc] of accumMap) {\n const kindsSet = new Set<number>();\n for (const e of acc.entries) {\n for (const k of e.kTags) {\n kindsSet.add(k);\n }\n }\n const supportedKinds = [...kindsSet];\n agentMap.set(pubkey, {\n pubkey: acc.pubkey,\n npub: acc.npub,\n cards: acc.entries.map((e) => e.card),\n eventId: acc.eventId,\n supportedKinds,\n lastSeen: acc.lastSeen,\n });\n }\n\n return agentMap;\n}\n\nexport class DiscoveryService {\n constructor(private pool: NostrPool) {}\n\n /** Count elisym agents (kind:31990 with \"elisym\" tag). */\n async fetchAllAgentCount(): Promise<number> {\n const events = await this.pool.querySync({\n kinds: [KIND_APP_HANDLER],\n '#t': ['elisym'],\n } as Filter);\n\n const uniquePubkeys = new Set<string>();\n for (const event of events) {\n if (!verifyEvent(event)) {\n continue;\n }\n uniquePubkeys.add(event.pubkey);\n }\n return uniquePubkeys.size;\n }\n\n /**\n * Fetch a single page of elisym agents with relay-side pagination.\n * Uses `until` cursor for Nostr cursor-based pagination.\n *\n * Unlike `fetchAgents`, this method does NOT enrich agents with\n * kind:0 metadata (name, picture, about) or update `lastSeen` from\n * recent job activity. Call `enrichWithMetadata()` separately if needed.\n */\n async fetchAgentsPage(\n network: Network = 'devnet',\n limit = 20,\n until?: number,\n ): Promise<{ agents: Agent[]; oldestCreatedAt: number | null; rawEventCount: number }> {\n const filter: Filter = {\n kinds: [KIND_APP_HANDLER],\n '#t': ['elisym'],\n limit,\n };\n if (until !== undefined) {\n filter.until = until;\n }\n\n const events = await this.pool.querySync(filter);\n const rawEventCount = events.length;\n\n // Compute cursor from ALL raw events (before any filtering)\n let oldestCreatedAt: number | null = null;\n for (const event of events) {\n if (oldestCreatedAt === null || event.created_at < oldestCreatedAt) {\n oldestCreatedAt = event.created_at;\n }\n }\n\n const agentMap = buildAgentsFromEvents(events, network);\n\n const agents = Array.from(agentMap.values()).sort((a, b) => b.lastSeen - a.lastSeen);\n\n return { agents, oldestCreatedAt, rawEventCount };\n }\n\n /** Enrich agents with kind:0 metadata (name, picture, about). Mutates in place and returns the same array. */\n async enrichWithMetadata(agents: Agent[]): Promise<Agent[]> {\n const pubkeys = agents.map((a) => a.pubkey);\n if (pubkeys.length === 0) {\n return agents;\n }\n\n const metaEvents = await this.pool.queryBatched(\n { kinds: [0] } as Omit<Filter, 'authors'>,\n pubkeys,\n );\n const latestMeta = new Map<string, (typeof metaEvents)[0]>();\n for (const ev of metaEvents) {\n if (!verifyEvent(ev)) {\n continue;\n }\n const prev = latestMeta.get(ev.pubkey);\n if (!prev || ev.created_at > prev.created_at) {\n latestMeta.set(ev.pubkey, ev);\n }\n }\n const agentLookup = new Map(agents.map((a) => [a.pubkey, a]));\n for (const [pubkey, ev] of latestMeta) {\n const agent = agentLookup.get(pubkey);\n if (!agent) {\n continue;\n }\n try {\n const meta = JSON.parse(ev.content);\n if (typeof meta.picture === 'string') {\n agent.picture = meta.picture;\n }\n if (typeof meta.name === 'string') {\n agent.name = meta.name;\n }\n if (typeof meta.about === 'string') {\n agent.about = meta.about;\n }\n } catch {\n // skip malformed metadata\n }\n }\n return agents;\n }\n\n /** Fetch elisym agents filtered by network. */\n async fetchAgents(network: Network = 'devnet', limit?: number): Promise<Agent[]> {\n const filter: Filter = {\n kinds: [KIND_APP_HANDLER],\n '#t': ['elisym'],\n };\n if (limit !== undefined) {\n filter.limit = limit;\n }\n const events = await this.pool.querySync(filter);\n\n const agentMap = buildAgentsFromEvents(events, network);\n\n const agents = Array.from(agentMap.values()).sort((a, b) => b.lastSeen - a.lastSeen);\n\n // Update lastSeen from recent job activity\n const agentPubkeys = Array.from(agentMap.keys());\n if (agentPubkeys.length > 0) {\n const activitySince = Math.floor(Date.now() / 1000) - 24 * 60 * 60;\n // Derive result kinds from agents' supported request kinds (5xxx - 6xxx)\n const resultKinds = new Set<number>();\n for (const agent of agentMap.values()) {\n for (const k of agent.supportedKinds) {\n if (k >= KIND_JOB_REQUEST_BASE && k < KIND_JOB_RESULT_BASE) {\n resultKinds.add(KIND_JOB_RESULT_BASE + (k - KIND_JOB_REQUEST_BASE));\n }\n }\n }\n resultKinds.add(jobResultKind(DEFAULT_KIND_OFFSET));\n\n // Fetch activity and metadata in parallel (independent: activity writes lastSeen, metadata writes name/picture/about)\n const [activityEvents] = await Promise.all([\n this.pool.queryBatched(\n {\n kinds: [...resultKinds, KIND_JOB_FEEDBACK],\n since: activitySince,\n } as Omit<Filter, 'authors'>,\n agentPubkeys,\n ),\n this.enrichWithMetadata(agents),\n ]);\n for (const ev of activityEvents) {\n if (!verifyEvent(ev)) {\n continue;\n }\n const agent = agentMap.get(ev.pubkey);\n if (agent && ev.created_at > agent.lastSeen) {\n agent.lastSeen = ev.created_at;\n }\n }\n\n agents.sort((a, b) => b.lastSeen - a.lastSeen);\n }\n\n return agents;\n }\n\n /**\n * Publish a capability card (kind:31990) as a provider.\n * Solana address is validated for Base58 format only - full decode\n * validation (32-byte public key) happens at payment time.\n */\n async publishCapability(\n identity: ElisymIdentity,\n card: CapabilityCard,\n kinds: number[] = [KIND_JOB_REQUEST],\n ): Promise<string> {\n if (!card.payment?.address) {\n throw new Error(\n 'Cannot publish capability without a payment address. Connect a wallet before publishing.',\n );\n }\n // Base58 charset + length check. Full validation (decode + 32 bytes) happens\n // at payment time via PublicKey constructor - no @solana/web3.js import here\n // to keep discovery browser-safe without Solana peer dep.\n if (\n card.payment.chain === 'solana' &&\n !/^[1-9A-HJ-NP-Za-km-z]{32,44}$/.test(card.payment.address)\n ) {\n throw new Error(`Invalid Solana address format: ${card.payment.address}`);\n }\n if (card.name.length > LIMITS.MAX_AGENT_NAME_LENGTH) {\n throw new Error(\n `Agent name too long: ${card.name.length} chars (max ${LIMITS.MAX_AGENT_NAME_LENGTH}).`,\n );\n }\n if (card.description.length > LIMITS.MAX_DESCRIPTION_LENGTH) {\n throw new Error(\n `Description too long: ${card.description.length} chars (max ${LIMITS.MAX_DESCRIPTION_LENGTH}).`,\n );\n }\n if (card.capabilities.length > LIMITS.MAX_CAPABILITIES) {\n throw new Error(\n `Too many capabilities: ${card.capabilities.length} (max ${LIMITS.MAX_CAPABILITIES}).`,\n );\n }\n for (const cap of card.capabilities) {\n if (cap.length > LIMITS.MAX_CAPABILITY_LENGTH) {\n throw new Error(\n `Capability name too long: \"${cap}\" (${cap.length} chars, max ${LIMITS.MAX_CAPABILITY_LENGTH}).`,\n );\n }\n }\n\n const tags: string[][] = [\n ['d', toDTag(card.name)],\n ['t', 'elisym'],\n ...card.capabilities.map((c) => ['t', c]),\n ...kinds.map((k) => ['k', String(k)]),\n ];\n\n const event = finalizeEvent(\n {\n kind: KIND_APP_HANDLER,\n created_at: Math.floor(Date.now() / 1000),\n tags,\n content: JSON.stringify(card),\n },\n identity.secretKey,\n );\n\n await this.pool.publishAll(event);\n return event.id;\n }\n\n /** Publish a Nostr profile (kind:0) as a provider. */\n async publishProfile(\n identity: ElisymIdentity,\n name: string,\n about: string,\n picture?: string,\n banner?: string,\n ): Promise<string> {\n if (name.length > LIMITS.MAX_AGENT_NAME_LENGTH) {\n throw new Error(\n `Profile name too long: ${name.length} chars (max ${LIMITS.MAX_AGENT_NAME_LENGTH}).`,\n );\n }\n if (about.length > LIMITS.MAX_DESCRIPTION_LENGTH) {\n throw new Error(\n `Profile about too long: ${about.length} chars (max ${LIMITS.MAX_DESCRIPTION_LENGTH}).`,\n );\n }\n const content: Record<string, string> = { name, about };\n if (picture) {\n content.picture = picture;\n }\n if (banner) {\n content.banner = banner;\n }\n\n const event = finalizeEvent(\n {\n kind: 0,\n created_at: Math.floor(Date.now() / 1000),\n tags: [],\n content: JSON.stringify(content),\n },\n identity.secretKey,\n );\n\n await this.pool.publishAll(event);\n return event.id;\n }\n\n /**\n * Delete a capability by publishing a tombstone replacement.\n * Since kind:31990 is a parameterized replaceable event,\n * publishing a new event with the same `d` tag and `\"deleted\":true`\n * content replaces the old one on all relays.\n */\n async deleteCapability(identity: ElisymIdentity, capabilityName: string): Promise<string> {\n const dTag = toDTag(capabilityName);\n\n const event = finalizeEvent(\n {\n kind: KIND_APP_HANDLER,\n created_at: Math.floor(Date.now() / 1000),\n tags: [\n ['d', dTag],\n ['t', 'elisym'],\n ],\n content: JSON.stringify({ deleted: true }),\n },\n identity.secretKey,\n );\n\n await this.pool.publishAll(event);\n return event.id;\n }\n}\n","/**\n * NIP-44 encryption/decryption helpers.\n * Wraps nostr-tools nip44 v2 for convenience.\n */\nimport * as nip44 from 'nostr-tools/nip44';\n\n/** Encrypt plaintext using NIP-44 v2 (sender secret key + recipient public key). */\nexport function nip44Encrypt(\n plaintext: string,\n senderSk: Uint8Array,\n recipientPubkey: string,\n): string {\n const conversationKey = nip44.v2.utils.getConversationKey(senderSk, recipientPubkey);\n return nip44.v2.encrypt(plaintext, conversationKey);\n}\n\n/** Decrypt ciphertext using NIP-44 v2 (receiver secret key + sender public key). */\nexport function nip44Decrypt(\n ciphertext: string,\n receiverSk: Uint8Array,\n senderPubkey: string,\n): string {\n const conversationKey = nip44.v2.utils.getConversationKey(receiverSk, senderPubkey);\n return nip44.v2.decrypt(ciphertext, conversationKey);\n}\n","import { finalizeEvent, verifyEvent, type Filter, type Event } from 'nostr-tools';\nimport {\n KIND_JOB_FEEDBACK,\n KIND_JOB_REQUEST_BASE,\n KIND_JOB_RESULT_BASE,\n DEFAULT_KIND_OFFSET,\n DEFAULTS,\n LIMITS,\n jobRequestKind,\n jobResultKind,\n} from '../constants';\nimport { assertLamports } from '../payment/fee';\nimport { nip44Encrypt, nip44Decrypt } from '../primitives/crypto';\nimport type { ElisymIdentity } from '../primitives/identity';\nimport type { NostrPool } from '../transport/pool';\nimport type { Job, JobStatus, SubCloser, SubmitJobOptions, JobSubscriptionOptions } from '../types';\n\nfunction isEncrypted(event: Event): boolean {\n return event.tags.some((t) => t[0] === 'encrypted' && t[1] === 'nip44');\n}\n\nfunction resolveRequestId(event: Event): string | undefined {\n return event.tags.find((t) => t[0] === 'e')?.[1];\n}\n\nfunction safeParseInt(value: string | undefined): number | undefined {\n if (!value) {\n return undefined;\n }\n const n = parseInt(value, 10);\n return isNaN(n) ? undefined : n;\n}\n\nconst VALID_JOB_STATUSES = new Set<string>([\n 'payment-required',\n 'payment-completed',\n 'processing',\n 'error',\n 'success',\n 'partial',\n]);\n\nfunction toJobStatus(raw: string): JobStatus {\n return VALID_JOB_STATUSES.has(raw) ? (raw as JobStatus) : 'unknown';\n}\n\nexport class MarketplaceService {\n constructor(private pool: NostrPool) {}\n\n /** Submit a job request with NIP-44 encrypted input. Returns the event ID. */\n async submitJobRequest(identity: ElisymIdentity, options: SubmitJobOptions): Promise<string> {\n if (!options.input) {\n throw new Error('Job input must not be empty.');\n }\n if (options.input.length > LIMITS.MAX_INPUT_LENGTH) {\n throw new Error(\n `Job input too long: ${options.input.length} chars (max ${LIMITS.MAX_INPUT_LENGTH}).`,\n );\n }\n if (!options.capability || options.capability.length > LIMITS.MAX_CAPABILITY_LENGTH) {\n throw new Error(`Invalid capability: must be 1-${LIMITS.MAX_CAPABILITY_LENGTH} characters.`);\n }\n if (options.providerPubkey && !/^[0-9a-f]{64}$/.test(options.providerPubkey)) {\n throw new Error('Invalid provider pubkey: expected 64 hex characters.');\n }\n const plaintext = options.input;\n const encrypted = options.providerPubkey\n ? nip44Encrypt(plaintext, identity.secretKey, options.providerPubkey)\n : plaintext;\n\n const tags: string[][] = [\n ['i', options.providerPubkey ? 'encrypted' : 'text', 'text'],\n ['t', options.capability],\n ['t', 'elisym'],\n ['output', 'text/plain'],\n ];\n\n if (options.providerPubkey) {\n tags.push(['p', options.providerPubkey]);\n tags.push(['encrypted', 'nip44']);\n }\n\n const kind = jobRequestKind(options.kindOffset ?? DEFAULT_KIND_OFFSET);\n const event = finalizeEvent(\n {\n kind,\n created_at: Math.floor(Date.now() / 1000),\n tags,\n content: encrypted,\n },\n identity.secretKey,\n );\n\n await this.pool.publish(event);\n return event.id;\n }\n\n /**\n * Subscribe to job updates (feedback + results) for a given job.\n * Creates 3 subscriptions per call (feedback, result by #e, result by #p+#e)\n * to cover different relay indexing strategies. Returns a cleanup function.\n */\n subscribeToJobUpdates(options: JobSubscriptionOptions): () => void {\n const {\n jobEventId: jid,\n providerPubkey: provPk,\n customerPublicKey: custPk,\n callbacks: cb,\n timeoutMs = DEFAULTS.SUBSCRIPTION_TIMEOUT_MS,\n customerSecretKey: custSk,\n kindOffsets: offsets_,\n sinceOverride: since_,\n } = options;\n\n const offsets = offsets_ ?? [DEFAULT_KIND_OFFSET];\n if (offsets.length === 0) {\n throw new Error('kindOffsets must not be empty.');\n }\n const resultKinds = offsets.map(jobResultKind);\n const since = since_ ?? Math.floor(Date.now() / 1000) - 30;\n const subs: SubCloser[] = [];\n let resolved = false;\n let resultDelivered = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n const done = () => {\n resolved = true;\n if (timer) {\n clearTimeout(timer);\n }\n for (const s of subs) {\n try {\n s.close();\n } catch {\n /* ignore */\n }\n }\n };\n\n const decryptResult = (ev: Event): string | null => {\n if (isEncrypted(ev)) {\n if (!custSk) {\n return null;\n }\n try {\n return nip44Decrypt(ev.content, custSk, ev.pubkey);\n } catch {\n return null;\n }\n }\n return ev.content;\n };\n\n const handleResult = (ev: Event) => {\n if (resolved || resultDelivered) {\n return;\n }\n if (!verifyEvent(ev)) {\n return;\n }\n if (provPk && ev.pubkey !== provPk) {\n return;\n }\n const eTag = ev.tags.find((t) => t[0] === 'e')?.[1];\n if (eTag !== jid) {\n return;\n }\n const content = decryptResult(ev);\n if (content === null) {\n // Skip undecryptable results instead of terminating the subscription.\n // For broadcast jobs a rogue agent could send fake encrypted results;\n // killing the subscription would be a DoS vector.\n return;\n }\n resultDelivered = true;\n try {\n cb.onResult?.(content, ev.id);\n } catch {\n /* caller error - don't crash subscription */\n } finally {\n done();\n }\n };\n\n try {\n // Feedback subscription\n subs.push(\n this.pool.subscribe(\n {\n kinds: [KIND_JOB_FEEDBACK],\n '#e': [jid],\n since,\n } as Filter,\n (ev) => {\n if (resolved) {\n return;\n }\n if (!verifyEvent(ev)) {\n return;\n }\n if (provPk && ev.pubkey !== provPk) {\n return;\n }\n const eTag = ev.tags.find((t) => t[0] === 'e')?.[1];\n if (eTag !== jid) {\n return;\n }\n const statusTag = ev.tags.find((t) => t[0] === 'status');\n if (statusTag?.[1]) {\n const amtTag = ev.tags.find((t) => t[0] === 'amount');\n const amt = safeParseInt(amtTag?.[1]) ?? 0;\n const paymentReq = amtTag?.[2];\n try {\n cb.onFeedback?.(statusTag[1], amt, paymentReq, ev.pubkey);\n } catch {\n /* caller error - don't crash subscription */\n }\n }\n },\n ),\n );\n\n // Result subscription by #e tag\n subs.push(\n this.pool.subscribe(\n {\n kinds: resultKinds,\n '#e': [jid],\n since,\n } as Filter,\n handleResult,\n ),\n );\n\n // Result subscription by #p tag (customer pubkey) + #e tag\n subs.push(\n this.pool.subscribe(\n {\n kinds: resultKinds,\n '#p': [custPk],\n '#e': [jid],\n since,\n } as Filter,\n handleResult,\n ),\n );\n } catch (err) {\n done();\n throw err;\n }\n\n timer = setTimeout(() => {\n if (!resolved) {\n done();\n try {\n cb.onError?.(`Timed out waiting for response (${timeoutMs / 1000}s).`);\n } catch {\n /* caller error - don't crash subscription */\n }\n }\n }, timeoutMs);\n\n return done;\n }\n\n /** Submit payment confirmation feedback. */\n async submitPaymentConfirmation(\n identity: ElisymIdentity,\n jobEventId: string,\n providerPubkey: string,\n txSignature: string,\n ): Promise<void> {\n const event = finalizeEvent(\n {\n kind: KIND_JOB_FEEDBACK,\n created_at: Math.floor(Date.now() / 1000),\n tags: [\n ['e', jobEventId],\n ['p', providerPubkey],\n ['status', 'payment-completed'],\n ['tx', txSignature, 'solana'],\n ['t', 'elisym'],\n ],\n content: '',\n },\n identity.secretKey,\n );\n\n await this.pool.publishAll(event);\n }\n\n /** Submit rating feedback for a job. */\n async submitFeedback(\n identity: ElisymIdentity,\n jobEventId: string,\n providerPubkey: string,\n positive: boolean,\n capability?: string,\n ): Promise<void> {\n const tags: string[][] = [\n ['e', jobEventId],\n ['p', providerPubkey],\n ['status', 'success'],\n ['rating', positive ? '1' : '0'],\n ['t', 'elisym'],\n ];\n if (capability) {\n tags.push(['t', capability]);\n }\n\n const event = finalizeEvent(\n {\n kind: KIND_JOB_FEEDBACK,\n created_at: Math.floor(Date.now() / 1000),\n tags,\n content: positive ? 'Good result' : 'Poor result',\n },\n identity.secretKey,\n );\n\n await this.pool.publishAll(event);\n }\n\n // --- Provider methods ---\n\n /**\n * Subscribe to incoming job requests for specific kinds.\n * Automatically decrypts NIP-44 encrypted content.\n * Note: decrypted events have modified `content` - do not call `verifyEvent()` on them.\n * Signature verification is performed before decryption.\n */\n subscribeToJobRequests(\n identity: ElisymIdentity,\n kinds: number[],\n onRequest: (event: Event) => void,\n ): SubCloser {\n return this.pool.subscribe(\n {\n kinds,\n '#p': [identity.publicKey],\n '#t': ['elisym'],\n since: Math.floor(Date.now() / 1000) - 5,\n } as Filter,\n (event: Event) => {\n if (!verifyEvent(event)) {\n return;\n }\n if (isEncrypted(event) && event.content) {\n try {\n const decrypted = nip44Decrypt(event.content, identity.secretKey, event.pubkey);\n onRequest({ ...event, content: decrypted });\n } catch {\n // Can't decrypt - skip event (likely not intended for us)\n return;\n }\n } else {\n onRequest(event);\n }\n },\n );\n }\n\n /** Submit a job result with NIP-44 encrypted content. Result kind is derived from the request kind. */\n async submitJobResult(\n identity: ElisymIdentity,\n requestEvent: Event,\n content: string,\n amount?: number,\n ): Promise<string> {\n if (!content) {\n throw new Error('Job result content must not be empty.');\n }\n if (!Number.isInteger(requestEvent.kind)) {\n throw new Error(`Invalid request event kind: expected integer, got ${requestEvent.kind}.`);\n }\n const offset = requestEvent.kind - KIND_JOB_REQUEST_BASE;\n if (offset < 0 || offset >= 1000) {\n throw new Error(\n `Invalid request event kind ${requestEvent.kind}: expected a NIP-90 job request kind (5000-5999).`,\n );\n }\n const shouldEncrypt = isEncrypted(requestEvent);\n const resultContent = shouldEncrypt\n ? nip44Encrypt(content, identity.secretKey, requestEvent.pubkey)\n : content;\n const resultKind = KIND_JOB_RESULT_BASE + offset;\n\n const tags: string[][] = [\n ['e', requestEvent.id],\n ['p', requestEvent.pubkey],\n ['t', 'elisym'],\n ];\n if (shouldEncrypt) {\n tags.push(['encrypted', 'nip44']);\n }\n\n if (amount !== null && amount !== undefined) {\n assertLamports(amount, 'result amount');\n tags.push(['amount', String(amount)]);\n }\n\n const event = finalizeEvent(\n {\n kind: resultKind,\n created_at: Math.floor(Date.now() / 1000),\n tags,\n content: resultContent,\n },\n identity.secretKey,\n );\n\n await this.pool.publishAll(event);\n return event.id;\n }\n\n /**\n * Submit a job result with retry and exponential backoff.\n * Retries on publish failures (e.g. relay disconnects).\n * With maxAttempts=3: try, ~1s, try, ~2s, try, throw.\n * Jitter: 0.5x-1.0x of calculated delay.\n */\n async submitJobResultWithRetry(\n identity: ElisymIdentity,\n requestEvent: Event,\n content: string,\n amount?: number,\n maxAttempts: number = DEFAULTS.RESULT_RETRY_COUNT,\n baseDelayMs: number = DEFAULTS.RESULT_RETRY_BASE_MS,\n ): Promise<string> {\n const attempts = Math.max(1, maxAttempts);\n for (let attempt = 0; attempt < attempts; attempt++) {\n try {\n return await this.submitJobResult(identity, requestEvent, content, amount);\n } catch (e: unknown) {\n if (attempt >= attempts - 1) {\n throw e;\n }\n // Math.random is fine for jitter - not a security context\n const jitter = 0.5 + Math.random() * 0.5;\n await new Promise((r) => setTimeout(r, baseDelayMs * Math.pow(2, attempt) * jitter));\n }\n }\n throw new Error('All delivery attempts failed');\n }\n\n /** Submit payment-required feedback with a payment request. */\n async submitPaymentRequiredFeedback(\n identity: ElisymIdentity,\n requestEvent: Event,\n amount: number,\n paymentRequestJson: string,\n ): Promise<void> {\n assertLamports(amount, 'payment amount');\n if (amount === 0) {\n throw new Error('Invalid payment amount: 0. Must be positive.');\n }\n try {\n JSON.parse(paymentRequestJson);\n } catch {\n throw new Error('Invalid paymentRequestJson: must be valid JSON.');\n }\n if (paymentRequestJson.length > LIMITS.MAX_INPUT_LENGTH) {\n throw new Error(\n `paymentRequestJson too long: ${paymentRequestJson.length} chars (max ${LIMITS.MAX_INPUT_LENGTH}).`,\n );\n }\n\n const event = finalizeEvent(\n {\n kind: KIND_JOB_FEEDBACK,\n created_at: Math.floor(Date.now() / 1000),\n tags: [\n ['e', requestEvent.id],\n ['p', requestEvent.pubkey],\n ['status', 'payment-required'],\n ['amount', String(amount), paymentRequestJson, 'solana'],\n ['t', 'elisym'],\n ],\n content: '',\n },\n identity.secretKey,\n );\n\n await this.pool.publishAll(event);\n }\n\n /** Submit processing feedback to notify customer that work has started. */\n async submitProcessingFeedback(identity: ElisymIdentity, requestEvent: Event): Promise<void> {\n const event = finalizeEvent(\n {\n kind: KIND_JOB_FEEDBACK,\n created_at: Math.floor(Date.now() / 1000),\n tags: [\n ['e', requestEvent.id],\n ['p', requestEvent.pubkey],\n ['status', 'processing'],\n ['t', 'elisym'],\n ],\n content: '',\n },\n identity.secretKey,\n );\n\n await this.pool.publishAll(event);\n }\n\n /** Submit error feedback to notify customer of a failure. */\n async submitErrorFeedback(\n identity: ElisymIdentity,\n requestEvent: Event,\n message: string,\n ): Promise<void> {\n if (!message) {\n throw new Error('Error message must not be empty.');\n }\n if (message.length > LIMITS.MAX_INPUT_LENGTH) {\n throw new Error(\n `Error message too long: ${message.length} chars (max ${LIMITS.MAX_INPUT_LENGTH}).`,\n );\n }\n const event = finalizeEvent(\n {\n kind: KIND_JOB_FEEDBACK,\n created_at: Math.floor(Date.now() / 1000),\n tags: [\n ['e', requestEvent.id],\n ['p', requestEvent.pubkey],\n ['status', 'error'],\n ['t', 'elisym'],\n ],\n content: message,\n },\n identity.secretKey,\n );\n\n await this.pool.publishAll(event);\n }\n\n /** Query job results by request IDs and decrypt NIP-44 content. */\n async queryJobResults(\n identity: ElisymIdentity,\n requestIds: string[],\n kindOffsets?: number[],\n providerPubkey?: string,\n ): Promise<\n Map<\n string,\n { content: string; amount?: number; senderPubkey: string; decryptionFailed: boolean }\n >\n > {\n const offsets = kindOffsets ?? [DEFAULT_KIND_OFFSET];\n if (offsets.length === 0) {\n throw new Error('kindOffsets must not be empty.');\n }\n const resultKinds = offsets.map(jobResultKind);\n\n const results = await this.pool.queryBatchedByTag(\n { kinds: resultKinds } as Filter,\n 'e',\n requestIds,\n );\n\n const resultByRequest = new Map<\n string,\n { content: string; amount?: number; senderPubkey: string; decryptionFailed: boolean }\n >();\n const createdAtByRequest = new Map<string, number>();\n for (const r of results) {\n if (!verifyEvent(r)) {\n continue;\n }\n if (providerPubkey && r.pubkey !== providerPubkey) {\n continue;\n }\n const eTag = r.tags.find((t) => t[0] === 'e');\n if (!eTag?.[1]) {\n continue;\n }\n\n const prevTs = createdAtByRequest.get(eTag[1]) ?? 0;\n if (r.created_at < prevTs) {\n continue;\n }\n\n const amtTag = r.tags.find((t) => t[0] === 'amount');\n\n let content = r.content;\n let decryptionFailed = false;\n if (isEncrypted(r)) {\n try {\n content = nip44Decrypt(r.content, identity.secretKey, r.pubkey);\n } catch {\n content = '';\n decryptionFailed = true;\n }\n }\n\n createdAtByRequest.set(eTag[1], r.created_at);\n resultByRequest.set(eTag[1], {\n content,\n amount: safeParseInt(amtTag?.[1]),\n senderPubkey: r.pubkey,\n decryptionFailed,\n });\n }\n\n return resultByRequest;\n }\n\n // --- Query methods ---\n\n /**\n * Fetch recent jobs from the network.\n * NOTE: Job.result contains raw event content. For encrypted jobs,\n * this will be NIP-44 ciphertext - use queryJobResults() for decryption.\n */\n async fetchRecentJobs(\n agentPubkeys?: Set<string>,\n limit?: number,\n since?: number,\n /** Kind offsets to query (default [100]). */\n kindOffsets?: number[],\n ): Promise<Job[]> {\n const offsets = kindOffsets ?? [DEFAULT_KIND_OFFSET];\n if (offsets.length === 0) {\n throw new Error('kindOffsets must not be empty.');\n }\n const requestKinds = offsets.map(jobRequestKind);\n const resultKinds = offsets.map(jobResultKind);\n\n const reqFilter: Filter = {\n kinds: requestKinds,\n '#t': ['elisym'],\n ...(limit !== null && limit !== undefined && { limit }),\n ...(since !== null && since !== undefined && { since }),\n };\n const rawRequests = await this.pool.querySync(reqFilter);\n const requests = rawRequests.filter(verifyEvent);\n\n const requestIds = requests.map((r) => r.id);\n let results: Event[] = [];\n let feedbacks: Event[] = [];\n\n if (requestIds.length > 0) {\n const [rawResults, rawFeedbacks] = await Promise.all([\n this.pool.queryBatchedByTag({ kinds: resultKinds } as Filter, 'e', requestIds),\n this.pool.queryBatchedByTag({ kinds: [KIND_JOB_FEEDBACK] } as Filter, 'e', requestIds),\n ]);\n results = rawResults.filter(verifyEvent);\n feedbacks = rawFeedbacks.filter(verifyEvent);\n }\n\n // Build targeted agent map\n const targetedAgentByRequest = new Map<string, string>();\n for (const req of requests) {\n const pTag = req.tags.find((t) => t[0] === 'p');\n if (pTag?.[1]) {\n targetedAgentByRequest.set(req.id, pTag[1]);\n }\n }\n\n // Index results by request ID (respect targeted agent, keep newest)\n const resultsByRequest = new Map<string, Event>();\n for (const r of results) {\n const reqId = resolveRequestId(r);\n if (!reqId) {\n continue;\n }\n const targeted = targetedAgentByRequest.get(reqId);\n if (targeted && r.pubkey !== targeted) {\n continue;\n }\n const existing = resultsByRequest.get(reqId);\n if (!existing || r.created_at > existing.created_at) {\n resultsByRequest.set(reqId, r);\n }\n }\n\n const feedbackByRequest = new Map<string, Event>();\n for (const f of feedbacks) {\n const reqId = resolveRequestId(f);\n if (!reqId) {\n continue;\n }\n const targeted = targetedAgentByRequest.get(reqId);\n if (targeted && f.pubkey !== targeted) {\n continue;\n }\n const existing = feedbackByRequest.get(reqId);\n if (!existing || f.created_at > existing.created_at) {\n feedbackByRequest.set(reqId, f);\n }\n }\n\n // Index all feedbacks by request ID for O(1) lookup\n const feedbacksByRequestId = new Map<string, Event[]>();\n for (const f of feedbacks) {\n const reqId = resolveRequestId(f);\n if (!reqId) {\n continue;\n }\n const arr = feedbacksByRequestId.get(reqId);\n if (arr) {\n arr.push(f);\n } else {\n feedbacksByRequestId.set(reqId, [f]);\n }\n }\n\n const jobs: Job[] = [];\n for (const req of requests) {\n const result = resultsByRequest.get(req.id);\n const feedback = feedbackByRequest.get(req.id);\n const jobAgentPubkey = result?.pubkey ?? feedback?.pubkey;\n\n if (agentPubkeys && agentPubkeys.size > 0 && jobAgentPubkey) {\n if (!agentPubkeys.has(jobAgentPubkey)) {\n continue;\n }\n }\n\n // NIP-90: one capability per job request - take the first non-elisym t tag\n const capability = req.tags.find((t) => t[0] === 't' && t[1] !== 'elisym')?.[1];\n const bid = req.tags.find((t) => t[0] === 'bid')?.[1];\n\n let status: JobStatus = 'processing';\n let amount: number | undefined;\n let txHash: string | undefined;\n\n if (result) {\n status = 'success';\n const amtTag = result.tags.find((t) => t[0] === 'amount');\n amount = safeParseInt(amtTag?.[1]);\n }\n\n // Check all feedbacks for tx hash\n const allFeedbacksForReq = feedbacksByRequestId.get(req.id) ?? [];\n for (const fb of allFeedbacksForReq) {\n const txTag = fb.tags.find((t) => t[0] === 'tx');\n if (txTag?.[1]) {\n txHash = txTag[1];\n break;\n }\n }\n\n if (feedback) {\n if (!result) {\n const statusTag = feedback.tags.find((t) => t[0] === 'status');\n if (statusTag?.[1]) {\n const isTargeted = targetedAgentByRequest.has(req.id);\n if (statusTag[1] === 'payment-required' && !bid && !isTargeted) {\n // Broadcast job without bid: a provider offered to work, but customer\n // hasn't committed. Keep \"processing\" because showing \"payment-required\"\n // would imply the customer chose this provider. The actual payment-required\n // transition happens via subscribeToJobUpdates() in real-time.\n } else {\n status = toJobStatus(statusTag[1]);\n }\n }\n }\n if (!amount) {\n const amtTag = feedback.tags.find((t) => t[0] === 'amount');\n amount = safeParseInt(amtTag?.[1]);\n }\n }\n\n jobs.push({\n eventId: req.id,\n customer: req.pubkey,\n agentPubkey: jobAgentPubkey,\n capability,\n bid: safeParseInt(bid),\n status,\n result: result?.content,\n resultEventId: result?.id,\n amount,\n txHash,\n createdAt: req.created_at,\n });\n }\n\n return jobs.sort((a, b) => b.createdAt - a.createdAt);\n }\n\n /** Subscribe to live elisym events (requests, results, feedback). */\n subscribeToEvents(kinds: number[], onEvent: (event: Event) => void): SubCloser {\n return this.pool.subscribe(\n {\n kinds,\n '#t': ['elisym'],\n since: Math.floor(Date.now() / 1000),\n } as Filter,\n (event) => {\n if (!verifyEvent(event)) {\n return;\n }\n onEvent(event);\n },\n );\n }\n}\n","/**\n * MediaService - NIP-98 authenticated file uploads to nostr.build.\n * Used for avatar, banner, and capability card images.\n */\nimport { finalizeEvent } from 'nostr-tools';\nimport type { ElisymIdentity } from '../primitives/identity';\n\nconst KIND_HTTP_AUTH = 27235;\nconst DEFAULT_UPLOAD_URL = 'https://nostr.build/api/v2/upload/files';\n\nexport class MediaService {\n constructor(private uploadUrl: string = DEFAULT_UPLOAD_URL) {}\n\n /**\n * Upload a file with NIP-98 authentication.\n * Works with browser File objects and Node.js/Bun Blobs.\n *\n * @param identity - Nostr identity used to sign the NIP-98 auth event.\n * @param file - File or Blob to upload.\n * @param filename - Optional filename for the upload (defaults to \"upload\").\n * @returns URL of the uploaded file.\n */\n async upload(identity: ElisymIdentity, file: Blob, filename?: string): Promise<string> {\n const hashBuffer = await crypto.subtle.digest('SHA-256', await file.arrayBuffer());\n const hashHex = [...new Uint8Array(hashBuffer)]\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n\n const authEvent = finalizeEvent(\n {\n kind: KIND_HTTP_AUTH,\n created_at: Math.floor(Date.now() / 1000),\n tags: [\n ['u', this.uploadUrl],\n ['method', 'POST'],\n ['payload', hashHex],\n ],\n content: '',\n },\n identity.secretKey,\n );\n\n const authHeader = 'Nostr ' + btoa(JSON.stringify(authEvent));\n\n const formData = new FormData();\n formData.append('file', file, filename ?? 'upload');\n\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), 30_000);\n try {\n const res = await fetch(this.uploadUrl, {\n method: 'POST',\n headers: { Authorization: authHeader },\n body: formData,\n signal: controller.signal,\n });\n\n if (!res.ok) {\n throw new Error(`Upload failed: ${res.status} ${res.statusText}`);\n }\n\n let data: { data?: { url?: string }[] };\n try {\n data = await res.json();\n } catch {\n throw new Error('Invalid response from upload service.');\n }\n const url = data?.data?.[0]?.url;\n if (!url) {\n throw new Error('No URL returned from upload service.');\n }\n return url;\n } finally {\n clearTimeout(timer);\n }\n }\n}\n","/** A Set that evicts the oldest entries when it exceeds maxSize. Uses a ring buffer for O(1) eviction. */\nexport class BoundedSet<T> {\n private items: (T | undefined)[];\n private set = new Set<T>();\n private head = 0;\n private count = 0;\n constructor(private maxSize: number) {\n if (maxSize <= 0) {\n throw new Error('BoundedSet maxSize must be positive.');\n }\n this.items = new Array(maxSize);\n }\n has(item: T): boolean {\n return this.set.has(item);\n }\n add(item: T): void {\n if (this.set.has(item)) {\n return;\n }\n if (this.count >= this.maxSize) {\n const evicted = this.items[this.head]!;\n this.set.delete(evicted);\n } else {\n this.count++;\n }\n this.items[this.head] = item;\n this.head = (this.head + 1) % this.maxSize;\n this.set.add(item);\n }\n}\n","import { generateSecretKey, getPublicKey, nip19 } from 'nostr-tools';\n\nexport class ElisymIdentity {\n private _secretKey: Uint8Array;\n readonly publicKey: string;\n readonly npub: string;\n\n get secretKey(): Uint8Array {\n return new Uint8Array(this._secretKey);\n }\n\n private constructor(secretKey: Uint8Array) {\n this._secretKey = new Uint8Array(secretKey);\n this.publicKey = getPublicKey(secretKey);\n this.npub = nip19.npubEncode(this.publicKey);\n }\n\n static generate(): ElisymIdentity {\n return new ElisymIdentity(generateSecretKey());\n }\n\n static fromSecretKey(sk: Uint8Array): ElisymIdentity {\n if (sk.length !== 32) {\n throw new Error('Secret key must be exactly 32 bytes.');\n }\n return new ElisymIdentity(sk);\n }\n\n toJSON(): { publicKey: string; npub: string } {\n return { publicKey: this.publicKey, npub: this.npub };\n }\n\n /** Best-effort scrub of the secret key bytes in memory. */\n scrub(): void {\n this._secretKey.fill(0);\n }\n\n static fromHex(hex: string): ElisymIdentity {\n if (hex.length !== 64 || !/^[0-9a-fA-F]{64}$/.test(hex)) {\n throw new Error('Invalid secret key hex: expected 64 hex characters (32 bytes).');\n }\n const bytes = new Uint8Array(32);\n for (let i = 0; i < 64; i += 2) {\n bytes[i / 2] = parseInt(hex.substring(i, i + 2), 16);\n }\n return new ElisymIdentity(bytes);\n }\n}\n","import { finalizeEvent, verifyEvent } from 'nostr-tools';\nimport type { Filter } from 'nostr-tools';\nimport * as nip17 from 'nostr-tools/nip17';\nimport * as nip59 from 'nostr-tools/nip59';\nimport { KIND_GIFT_WRAP, KIND_PING, KIND_PONG, DEFAULTS, LIMITS } from '../constants';\nimport { BoundedSet } from '../primitives/bounded-set';\nimport { ElisymIdentity } from '../primitives/identity';\nimport type { NostrPool } from '../transport/pool';\nimport type { PingResult, SubCloser } from '../types';\n\n/**\n * Ping/pong and NIP-17 DM service.\n *\n * Uses a session identity (random keypair) for ping operations to avoid\n * relay rate-limiting. The session identity persists for the lifetime of\n * this instance - recreating the service generates a new keypair.\n *\n * Requires `globalThis.crypto` (Node 20+, Bun, browsers).\n */\nexport class MessagingService {\n private static readonly PING_CACHE_MAX = 1000;\n private sessionIdentity: ElisymIdentity;\n private pingCache = new Map<string, number>(); // pubkey - timestamp of last online result\n private pendingPings = new Map<string, Promise<PingResult>>(); // dedup in-flight pings\n\n constructor(private pool: NostrPool) {\n this.sessionIdentity = ElisymIdentity.generate();\n }\n\n /**\n * Ping an agent via ephemeral Nostr events (kind 20200/20201).\n * Uses a persistent session identity to avoid relay rate-limiting.\n * Publishes to ALL relays for maximum delivery reliability.\n * Caches results for 30s to prevent redundant publishes.\n */\n async pingAgent(\n agentPubkey: string,\n timeoutMs: number = DEFAULTS.PING_TIMEOUT_MS,\n signal?: AbortSignal,\n retries: number = DEFAULTS.PING_RETRIES,\n ): Promise<PingResult> {\n // Return cached online result if fresh enough (avoids relay rate-limiting)\n const cachedAt = this.pingCache.get(agentPubkey);\n if (cachedAt) {\n if (Date.now() - cachedAt < DEFAULTS.PING_CACHE_TTL_MS) {\n return { online: true, identity: this.sessionIdentity };\n }\n this.pingCache.delete(agentPubkey); // evict stale entry\n }\n\n // Lazy sweep: evict stale entries when cache is over half full\n if (this.pingCache.size > MessagingService.PING_CACHE_MAX / 2) {\n const now = Date.now();\n for (const [key, ts] of this.pingCache) {\n if (now - ts >= DEFAULTS.PING_CACHE_TTL_MS) {\n this.pingCache.delete(key);\n }\n }\n }\n\n // Dedup: return existing in-flight ping for same agent (React Strict Mode sends two)\n const pending = this.pendingPings.get(agentPubkey);\n if (pending) {\n return pending;\n }\n\n // Guard against unbounded pending pings\n if (this.pendingPings.size >= MessagingService.PING_CACHE_MAX) {\n return { online: false, identity: null };\n }\n\n const promise = this._doPingWithRetry(agentPubkey, timeoutMs, retries, signal);\n this.pendingPings.set(agentPubkey, promise);\n promise.finally(() => this.pendingPings.delete(agentPubkey));\n return promise;\n }\n\n private async _doPingWithRetry(\n agentPubkey: string,\n timeoutMs: number,\n retries: number,\n signal?: AbortSignal,\n ): Promise<PingResult> {\n // Split total timeout evenly across attempts\n const attempts = retries + 1;\n const perAttemptTimeout = Math.floor(timeoutMs / attempts);\n\n for (let i = 0; i < attempts; i++) {\n if (signal?.aborted) {\n return { online: false, identity: null };\n }\n const result = await this._doPing(agentPubkey, perAttemptTimeout, signal);\n if (result.online) {\n return result;\n }\n }\n return { online: false, identity: null };\n }\n\n private async _doPing(\n agentPubkey: string,\n timeoutMs: number,\n signal?: AbortSignal,\n ): Promise<PingResult> {\n const sk = this.sessionIdentity.secretKey;\n const pk = this.sessionIdentity.publicKey;\n\n const nonce = crypto\n .getRandomValues(new Uint8Array(16))\n .reduce((s, b) => s + b.toString(16).padStart(2, '0'), '');\n\n if (signal?.aborted) {\n return { online: false, identity: null };\n }\n\n let resolved = false;\n let sub: SubCloser | undefined;\n let timer: ReturnType<typeof setTimeout> | undefined;\n let resolvePing!: (result: PingResult) => void;\n\n const promise = new Promise<PingResult>((resolve) => {\n resolvePing = resolve;\n });\n\n const done = (online: boolean) => {\n if (resolved) {\n return;\n }\n resolved = true;\n if (timer) {\n clearTimeout(timer);\n }\n sub?.close();\n signal?.removeEventListener('abort', onAbort);\n if (online) {\n this.pingCache.delete(agentPubkey);\n this.pingCache.set(agentPubkey, Date.now());\n if (this.pingCache.size > MessagingService.PING_CACHE_MAX) {\n const oldest = this.pingCache.keys().next().value;\n if (oldest !== undefined) {\n this.pingCache.delete(oldest);\n }\n }\n }\n resolvePing({ online, identity: online ? this.sessionIdentity : null });\n };\n\n const onAbort = () => done(false);\n signal?.addEventListener('abort', onAbort);\n\n // Start timeout BEFORE subscribeAndWait so total time per attempt is bounded by timeoutMs\n timer = setTimeout(() => done(false), timeoutMs);\n\n // Subscribe and wait for relay confirmation before publishing (ephemeral events require active subscription)\n try {\n sub = await this.pool.subscribeAndWait({ kinds: [KIND_PONG], '#p': [pk] } as Filter, (ev) => {\n if (!verifyEvent(ev)) {\n return;\n }\n if (ev.pubkey !== agentPubkey) {\n return;\n }\n try {\n const msg = JSON.parse(ev.content);\n if (\n msg.type === 'elisym_pong' &&\n typeof msg.nonce === 'string' &&\n msg.nonce.length === 32 &&\n msg.nonce === nonce\n ) {\n done(true);\n }\n } catch {\n /* ignore */\n }\n });\n } catch {\n done(false);\n return promise;\n }\n\n if (resolved) {\n sub?.close();\n return promise;\n }\n\n // Publish ephemeral ping to ALL relays - subscription is confirmed active\n const pingEvent = finalizeEvent(\n {\n kind: KIND_PING,\n created_at: Math.floor(Date.now() / 1000),\n tags: [['p', agentPubkey]],\n content: JSON.stringify({ type: 'elisym_ping', nonce }),\n },\n sk,\n );\n this.pool.publishAll(pingEvent).catch(() => {\n done(false);\n });\n\n return promise;\n }\n\n /**\n * Subscribe to incoming ephemeral ping events (kind 20200).\n * No `since` filter needed - ephemeral events are never stored.\n */\n subscribeToPings(\n identity: ElisymIdentity,\n onPing: (senderPubkey: string, nonce: string) => void,\n ): SubCloser {\n return this.pool.subscribe(\n { kinds: [KIND_PING], '#p': [identity.publicKey] } as Filter,\n (ev) => {\n if (!verifyEvent(ev)) {\n return;\n }\n try {\n const msg = JSON.parse(ev.content);\n if (\n msg.type === 'elisym_ping' &&\n typeof msg.nonce === 'string' &&\n msg.nonce.length === 32\n ) {\n onPing(ev.pubkey, msg.nonce);\n }\n } catch {\n /* ignore */\n }\n },\n );\n }\n\n /** Send an ephemeral pong response to ALL relays. */\n async sendPong(identity: ElisymIdentity, recipientPubkey: string, nonce: string): Promise<void> {\n const pongEvent = finalizeEvent(\n {\n kind: KIND_PONG,\n created_at: Math.floor(Date.now() / 1000),\n tags: [['p', recipientPubkey]],\n content: JSON.stringify({ type: 'elisym_pong', nonce }),\n },\n identity.secretKey,\n );\n await this.pool.publishAll(pongEvent);\n }\n\n /** Send a NIP-17 DM. */\n async sendMessage(\n identity: ElisymIdentity,\n recipientPubkey: string,\n content: string,\n ): Promise<void> {\n if (!/^[0-9a-f]{64}$/.test(recipientPubkey)) {\n throw new Error('Invalid recipient pubkey: expected 64 hex characters.');\n }\n if (content.length > LIMITS.MAX_MESSAGE_LENGTH) {\n throw new Error(\n `Message too long: ${content.length} chars (max ${LIMITS.MAX_MESSAGE_LENGTH}).`,\n );\n }\n const wrap = nip17.wrapEvent(identity.secretKey, { publicKey: recipientPubkey }, content);\n await this.pool.publish(wrap);\n }\n\n /** Fetch historical NIP-17 DMs from relays. Returns decrypted messages sorted by time. */\n async fetchMessageHistory(\n identity: ElisymIdentity,\n since: number,\n ): Promise<{ senderPubkey: string; content: string; createdAt: number; rumorId: string }[]> {\n const events = await this.pool.querySync({\n kinds: [KIND_GIFT_WRAP],\n '#p': [identity.publicKey],\n since,\n } as Filter);\n\n const seen = new BoundedSet<string>(10_000);\n const messages: {\n senderPubkey: string;\n content: string;\n createdAt: number;\n rumorId: string;\n }[] = [];\n\n for (const ev of events) {\n try {\n const rumor = nip59.unwrapEvent(ev, identity.secretKey);\n if (rumor.kind !== 14) {\n continue;\n } // NIP-17: DM rumor kind must be 14\n if (seen.has(rumor.id)) {\n continue;\n }\n seen.add(rumor.id);\n messages.push({\n senderPubkey: rumor.pubkey,\n content: rumor.content,\n createdAt: rumor.created_at,\n rumorId: rumor.id,\n });\n } catch {\n /* not encrypted for us */\n }\n }\n\n return messages.sort((a, b) => a.createdAt - b.createdAt);\n }\n\n /** Subscribe to incoming NIP-17 DMs. */\n subscribeToMessages(\n identity: ElisymIdentity,\n onMessage: (senderPubkey: string, content: string, createdAt: number, rumorId: string) => void,\n since?: number,\n ): SubCloser {\n const seen = new BoundedSet<string>(10_000);\n const filter: Filter = {\n kinds: [KIND_GIFT_WRAP],\n '#p': [identity.publicKey],\n };\n if (since !== undefined) {\n filter.since = since;\n }\n return this.pool.subscribe(filter, (ev) => {\n try {\n const rumor = nip59.unwrapEvent(ev, identity.secretKey);\n if (rumor.kind !== 14) {\n return;\n } // NIP-17: DM rumor kind must be 14\n if (seen.has(rumor.id)) {\n return;\n }\n seen.add(rumor.id);\n onMessage(rumor.pubkey, rumor.content, rumor.created_at, rumor.id);\n } catch {\n /* not our message */\n }\n });\n }\n}\n","import { SimplePool, type Filter, type Event } from 'nostr-tools';\nimport { RELAYS, DEFAULTS } from '../constants';\nimport { BoundedSet } from '../primitives/bounded-set';\nimport type { SubCloser } from '../types';\n\nexport class NostrPool {\n private pool: SimplePool;\n private relays: string[];\n private activeSubscriptions = new Set<SubCloser>();\n\n constructor(relays: string[] = RELAYS) {\n this.pool = new SimplePool();\n this.relays = relays;\n }\n\n /** Query relays synchronously. Returns `[]` on timeout (no error thrown). */\n async querySync(filter: Filter): Promise<Event[]> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const query = this.pool.querySync(this.relays, filter);\n query.catch(() => {}); // prevent unhandled rejection if timeout wins\n try {\n const result = await Promise.race([\n query,\n new Promise<Event[]>((resolve) => {\n timer = setTimeout(() => resolve([]), DEFAULTS.QUERY_TIMEOUT_MS);\n }),\n ]);\n return result;\n } finally {\n clearTimeout(timer);\n }\n }\n\n async queryBatched(\n filter: Omit<Filter, 'authors'>,\n keys: string[],\n batchSize: number = DEFAULTS.BATCH_SIZE,\n maxConcurrency: number = DEFAULTS.QUERY_MAX_CONCURRENCY,\n ): Promise<Event[]> {\n const batchKeys: string[][] = [];\n for (let i = 0; i < keys.length; i += batchSize) {\n batchKeys.push(keys.slice(i, i + batchSize));\n }\n\n const results: Event[] = [];\n for (let c = 0; c < batchKeys.length; c += maxConcurrency) {\n const chunk = batchKeys.slice(c, c + maxConcurrency);\n const chunkResults = await Promise.all(\n chunk.map((batch) => {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const query = this.pool.querySync(this.relays, {\n ...filter,\n authors: batch,\n } as Filter);\n query.catch(() => {}); // prevent unhandled rejection if timeout wins\n return (async () => {\n try {\n return await Promise.race([\n query,\n new Promise<Event[]>((resolve) => {\n timer = setTimeout(() => resolve([]), DEFAULTS.QUERY_TIMEOUT_MS);\n }),\n ]);\n } finally {\n clearTimeout(timer);\n }\n })();\n }),\n );\n results.push(...chunkResults.flat());\n }\n return results;\n }\n\n async queryBatchedByTag(\n filter: Filter,\n tagName: string,\n values: string[],\n batchSize: number = DEFAULTS.BATCH_SIZE,\n maxConcurrency: number = DEFAULTS.QUERY_MAX_CONCURRENCY,\n ): Promise<Event[]> {\n const batchValues: string[][] = [];\n for (let i = 0; i < values.length; i += batchSize) {\n batchValues.push(values.slice(i, i + batchSize));\n }\n\n const results: Event[] = [];\n for (let c = 0; c < batchValues.length; c += maxConcurrency) {\n const chunk = batchValues.slice(c, c + maxConcurrency);\n const chunkResults = await Promise.all(\n chunk.map((batch) => {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const query = this.pool.querySync(this.relays, {\n ...filter,\n [`#${tagName}`]: batch,\n } as Filter);\n query.catch(() => {}); // prevent unhandled rejection if timeout wins\n return (async () => {\n try {\n return await Promise.race([\n query,\n new Promise<Event[]>((resolve) => {\n timer = setTimeout(() => resolve([]), DEFAULTS.QUERY_TIMEOUT_MS);\n }),\n ]);\n } finally {\n clearTimeout(timer);\n }\n })();\n }),\n );\n results.push(...chunkResults.flat());\n }\n return results;\n }\n\n async publish(event: Event): Promise<void> {\n try {\n await Promise.any(this.pool.publish(this.relays, event));\n } catch (err) {\n if (err instanceof AggregateError) {\n throw new Error(\n `Failed to publish to all ${this.relays.length} relays: ${err.errors.map((e: unknown) => (e instanceof Error ? e.message : String(e))).join(', ')}`,\n );\n }\n throw err;\n }\n }\n\n /** Publish to all relays and wait for all to settle. Throws if none accepted. */\n async publishAll(event: Event): Promise<void> {\n const results = await Promise.allSettled(this.pool.publish(this.relays, event));\n const anyOk = results.some((r) => r.status === 'fulfilled');\n if (!anyOk) {\n throw new Error(`Failed to publish to all ${this.relays.length} relays`);\n }\n }\n\n subscribe(filter: Filter, onEvent: (event: Event) => void): SubCloser {\n const rawSub = this.pool.subscribeMany(this.relays, filter, { onevent: onEvent });\n const tracked: SubCloser = {\n close: (reason?: string) => {\n this.activeSubscriptions.delete(tracked);\n rawSub.close(reason);\n },\n };\n this.activeSubscriptions.add(tracked);\n return tracked;\n }\n\n /**\n * Subscribe and wait until at least one relay confirms the subscription\n * is active (EOSE). Resolves on the first relay that responds.\n * Essential for ephemeral events where the subscription must be live\n * before publishing.\n *\n * Note: resolves on timeout even if no relay sent EOSE. The caller\n * cannot distinguish timeout from success - this is intentional for\n * best-effort ephemeral event delivery.\n */\n subscribeAndWait(\n filter: Filter,\n onEvent: (event: Event) => void,\n timeoutMs: number = DEFAULTS.EOSE_TIMEOUT_MS,\n ): Promise<SubCloser> {\n return new Promise((resolve) => {\n let resolved = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n const subs: SubCloser[] = [];\n const combinedSub: SubCloser = {\n close: (reason?: string) => {\n this.activeSubscriptions.delete(combinedSub);\n for (const s of subs) {\n s.close(reason);\n }\n },\n };\n this.activeSubscriptions.add(combinedSub);\n\n const done = () => {\n if (resolved) {\n return;\n }\n resolved = true;\n if (timer) {\n clearTimeout(timer);\n }\n resolve(combinedSub);\n };\n\n // Subscribe to each relay individually so we can resolve\n // as soon as the first relay sends EOSE (not waiting for all).\n // Dedup events by id since per-relay subscriptions bypass SimplePool dedup.\n const seen = new BoundedSet<string>(10_000);\n const dedupedOnEvent = (ev: Event) => {\n if (seen.has(ev.id)) {\n return;\n }\n seen.add(ev.id);\n onEvent(ev);\n };\n\n for (const relay of this.relays) {\n try {\n const sub = this.pool.subscribeMany([relay], filter, {\n onevent: dedupedOnEvent,\n oneose: done,\n });\n subs.push(sub);\n } catch {\n /* skip failed relay - handled by subs.length === 0 check below */\n }\n }\n\n // If all relays failed, resolve immediately\n if (subs.length === 0) {\n done();\n return;\n }\n\n if (!resolved) {\n timer = setTimeout(done, timeoutMs);\n }\n });\n }\n\n /**\n * Tear down pool and create a fresh one.\n * Works around nostr-tools `onerror - skipReconnection = true` bug\n * that permanently kills subscriptions. Callers must re-subscribe.\n */\n reset(): void {\n for (const sub of this.activeSubscriptions) {\n sub.close('pool reset');\n }\n this.activeSubscriptions.clear();\n try {\n this.pool.close(this.relays);\n } catch {\n /* ignore */\n }\n this.pool = new SimplePool();\n }\n\n /**\n * Lightweight connectivity probe. Returns true if at least one relay responds.\n */\n async probe(timeoutMs: number = DEFAULTS.EOSE_TIMEOUT_MS): Promise<boolean> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const query = this.pool.querySync(this.relays, { kinds: [0], limit: 1 } as Filter);\n query.catch(() => {}); // prevent unhandled rejection if timeout wins\n try {\n await Promise.race([\n query,\n new Promise<never>((_, reject) => {\n timer = setTimeout(() => reject(new Error('probe timeout')), timeoutMs);\n }),\n ]);\n return true;\n } catch {\n return false;\n } finally {\n clearTimeout(timer);\n }\n }\n\n getRelays(): string[] {\n return this.relays;\n }\n\n close(): void {\n for (const sub of this.activeSubscriptions) {\n sub.close('pool closed');\n }\n this.activeSubscriptions.clear();\n try {\n this.pool.close(this.relays);\n } catch {\n /* ignore - already disconnected */\n }\n }\n}\n","import { RELAYS } from './constants';\nimport { SolanaPaymentStrategy } from './payment/solana';\nimport type { PaymentStrategy } from './payment/strategy';\nimport { DiscoveryService } from './services/discovery';\nimport { MarketplaceService } from './services/marketplace';\nimport { MediaService } from './services/media';\nimport { MessagingService } from './services/messaging';\nimport { NostrPool } from './transport/pool';\nimport type { ElisymClientConfig } from './types';\n\nexport interface ElisymClientFullConfig extends ElisymClientConfig {\n payment?: PaymentStrategy;\n /** Custom upload URL for file uploads (defaults to nostr.build). */\n uploadUrl?: string;\n}\n\nexport class ElisymClient {\n readonly pool: NostrPool;\n readonly discovery: DiscoveryService;\n readonly marketplace: MarketplaceService;\n readonly messaging: MessagingService;\n readonly media: MediaService;\n readonly payment: PaymentStrategy;\n\n constructor(config: ElisymClientFullConfig = {}) {\n this.pool = new NostrPool(config.relays ?? RELAYS);\n this.discovery = new DiscoveryService(this.pool);\n this.marketplace = new MarketplaceService(this.pool);\n this.messaging = new MessagingService(this.pool);\n this.media = new MediaService(config.uploadUrl);\n this.payment = config.payment ?? new SolanaPaymentStrategy();\n }\n\n close(): void {\n this.pool.close();\n }\n}\n","import Decimal from 'decimal.js-light';\nimport { LAMPORTS_PER_SOL } from '../constants';\n\nexport function formatSol(lamports: number): string {\n const sol = new Decimal(lamports).div(LAMPORTS_PER_SOL);\n if (sol.gte(1_000_000)) {\n return `${sol.idiv(1_000_000)}m SOL`;\n }\n if (sol.gte(10_000)) {\n return `${sol.idiv(1_000)}k SOL`;\n }\n return `${compactSol(sol)} SOL`;\n}\n\n/** Format a SOL Decimal - show enough decimals so the value isn't lost. */\nfunction compactSol(sol: Decimal): string {\n if (sol.isZero()) {\n return '0';\n }\n if (sol.gte(1000)) {\n return sol.toDecimalPlaces(0, Decimal.ROUND_FLOOR).toString();\n }\n // Show enough decimals so the rounded value equals the original\n const maxFrac = 9; // lamport precision\n for (let d = 1; d <= maxFrac; d++) {\n const s = sol.toFixed(d);\n if (new Decimal(s).eq(sol)) {\n return s.replace(/0+$/, '').replace(/\\.$/, '');\n }\n }\n return sol.toFixed(maxFrac).replace(/0+$/, '').replace(/\\.$/, '');\n}\n\nexport function timeAgo(unix: number): string {\n const seconds = Math.max(0, Math.floor(Date.now() / 1000 - unix));\n if (seconds < 60) {\n return `${seconds}s ago`;\n }\n const minutes = Math.floor(seconds / 60);\n if (minutes < 60) {\n return `${minutes}m ago`;\n }\n const hours = Math.floor(minutes / 60);\n if (hours < 24) {\n return `${hours}h ago`;\n }\n const days = Math.floor(hours / 24);\n return `${days}d ago`;\n}\n\nexport function truncateKey(hex: string, chars = 6): string {\n if (hex.length <= chars * 2) {\n return hex;\n }\n return `${hex.slice(0, chars)}...${hex.slice(-chars)}`;\n}\n","/**\n * Shared agent config - validation and serialization.\n * Browser-safe - no Node.js imports.\n * parseConfig lives in config-node.ts (exported from @elisym/sdk/node).\n */\n\nimport { LIMITS } from '../constants';\nimport type { AgentConfig } from '../types';\n\nexport function validateAgentName(name: string): void {\n if (!name || name.length > LIMITS.MAX_AGENT_NAME_LENGTH || !/^[a-zA-Z0-9_-]+$/.test(name)) {\n throw new Error('Agent name must be 1-64 characters, alphanumeric, underscore, or hyphen.');\n }\n}\n\n/** Serialize an AgentConfig to JSON string. */\nexport function serializeConfig(config: AgentConfig): string {\n return JSON.stringify(config, null, 2) + '\\n';\n}\n"]}