@elisym/sdk 0.1.2 → 0.1.3
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.
- package/LICENSE +21 -0
- package/dist/index.cjs +3 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/package.json +2 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Igor Peregudov
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/index.cjs
CHANGED
|
@@ -267,7 +267,9 @@ function buildAgentsFromEvents(events, network) {
|
|
|
267
267
|
if (existing) {
|
|
268
268
|
const dupIndex = existing.entries.findIndex((e) => e.card.name === card.name);
|
|
269
269
|
if (dupIndex >= 0) {
|
|
270
|
-
existing.entries[dupIndex]
|
|
270
|
+
if (entry.createdAt >= existing.entries[dupIndex].createdAt) {
|
|
271
|
+
existing.entries[dupIndex] = entry;
|
|
272
|
+
}
|
|
271
273
|
} else {
|
|
272
274
|
existing.entries.push(entry);
|
|
273
275
|
}
|
package/dist/index.cjs.map
CHANGED
|
@@ -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 existing.entries[dupIndex] = entry;\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/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"]}
|
package/dist/index.js
CHANGED
|
@@ -240,7 +240,9 @@ function buildAgentsFromEvents(events, network) {
|
|
|
240
240
|
if (existing) {
|
|
241
241
|
const dupIndex = existing.entries.findIndex((e) => e.card.name === card.name);
|
|
242
242
|
if (dupIndex >= 0) {
|
|
243
|
-
existing.entries[dupIndex]
|
|
243
|
+
if (entry.createdAt >= existing.entries[dupIndex].createdAt) {
|
|
244
|
+
existing.entries[dupIndex] = entry;
|
|
245
|
+
}
|
|
244
246
|
} else {
|
|
245
247
|
existing.entries.push(entry);
|
|
246
248
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -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":["nip19","finalizeEvent","Decimal"],"mappings":"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","file":"index.js","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 existing.entries[dupIndex] = entry;\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/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":["nip19","finalizeEvent","Decimal"],"mappings":"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","file":"index.js","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"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elisym/sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "TypeScript SDK for elisym - AI agent discovery, marketplace, messaging, and payments on Nostr",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -37,6 +37,7 @@
|
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
39
|
"@solana/web3.js": "^1.98.0",
|
|
40
|
+
"decimal.js-light": "^2.5.1",
|
|
40
41
|
"nostr-tools": "^2.23.0",
|
|
41
42
|
"tsup": "^8.4.0",
|
|
42
43
|
"typescript": "^5.7.0",
|
|
@@ -46,8 +47,5 @@
|
|
|
46
47
|
"repository": {
|
|
47
48
|
"type": "git",
|
|
48
49
|
"url": "https://github.com/elisymlabs/elisym-sdk-ts"
|
|
49
|
-
},
|
|
50
|
-
"dependencies": {
|
|
51
|
-
"decimal.js-light": "^2.5.1"
|
|
52
50
|
}
|
|
53
51
|
}
|