@elisym/sdk 0.3.2 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/index.cjs +352 -166
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +166 -26
- package/dist/index.d.ts +166 -26
- package/dist/index.js +347 -167
- package/dist/index.js.map +1 -1
- package/package.json +6 -3
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/constants.ts","../src/payment/fee.ts","../src/payment/solana.ts","../src/services/discovery.ts","../src/primitives/crypto.ts","../src/services/marketplace.ts","../src/services/media.ts","../src/primitives/identity.ts","../src/services/ping.ts","../src/primitives/bounded-set.ts","../src/transport/pool.ts","../src/client.ts","../src/primitives/format.ts","../src/primitives/config.ts"],"names":["Decimal","PublicKey","Keypair","SystemProgram","Transaction","verifyEvent","nip19","finalizeEvent","nip44","getPublicKey","generateSecretKey","SimplePool"],"mappings":"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","file":"index.cjs","sourcesContent":["export const RELAYS = [\n 'wss://relay.damus.io',\n 'wss://nos.lol',\n 'wss://relay.nostr.band',\n 'wss://relay.primal.net',\n 'wss://relay.snort.social',\n];\n\nexport const KIND_APP_HANDLER = 31990;\nexport const KIND_JOB_REQUEST_BASE = 5000;\nexport const KIND_JOB_RESULT_BASE = 6000;\nexport const KIND_JOB_FEEDBACK = 7000;\nexport const DEFAULT_KIND_OFFSET = 100;\n\n/** Default job request kind (5000 + 100). */\nexport const KIND_JOB_REQUEST = KIND_JOB_REQUEST_BASE + DEFAULT_KIND_OFFSET;\n/** Default job result kind (6000 + 100). */\nexport const KIND_JOB_RESULT = KIND_JOB_RESULT_BASE + DEFAULT_KIND_OFFSET;\n\n/** Compute a job request kind from an offset (5000 + offset). */\nexport function jobRequestKind(offset: number): number {\n if (!Number.isInteger(offset) || offset < 0 || offset >= 1000) {\n throw new Error(`Invalid kind offset: ${offset}. Must be integer 0-999.`);\n }\n return KIND_JOB_REQUEST_BASE + offset;\n}\n\n/** Compute a job result kind from an offset (6000 + offset). */\nexport function jobResultKind(offset: number): number {\n if (!Number.isInteger(offset) || offset < 0 || offset >= 1000) {\n throw new Error(`Invalid kind offset: ${offset}. Must be integer 0-999.`);\n }\n return KIND_JOB_RESULT_BASE + offset;\n}\n\n/** Ephemeral ping/pong kinds (not stored by relays, forwarded in real-time). */\nexport const KIND_PING = 20200;\nexport const KIND_PONG = 20201;\n\nexport const LAMPORTS_PER_SOL = 1_000_000_000;\n\n/** Protocol fee in basis points (300 = 3%). */\nexport const PROTOCOL_FEE_BPS = 300;\n/** Solana address of the protocol treasury. */\nexport const PROTOCOL_TREASURY = 'GY7vnWMkKpftU4nQ16C2ATkj1JwrQpHhknkaBUn67VTy';\n\n/** Default values for timeouts, retries, and batch sizes. */\nexport const DEFAULTS = {\n SUBSCRIPTION_TIMEOUT_MS: 120_000,\n PING_TIMEOUT_MS: 15_000,\n PING_RETRIES: 2,\n PING_CACHE_TTL_MS: 30_000,\n PAYMENT_EXPIRY_SECS: 600,\n BATCH_SIZE: 250,\n QUERY_TIMEOUT_MS: 15_000,\n EOSE_TIMEOUT_MS: 3_000,\n VERIFY_RETRIES: 10,\n VERIFY_INTERVAL_MS: 3_000,\n VERIFY_BY_REF_RETRIES: 15,\n VERIFY_BY_REF_INTERVAL_MS: 2_000,\n RESULT_RETRY_COUNT: 3,\n RESULT_RETRY_BASE_MS: 1_000,\n QUERY_MAX_CONCURRENCY: 6,\n VERIFY_SIGNATURE_LIMIT: 25,\n} as const;\n\n/** Protocol limits for input validation. */\nexport const LIMITS = {\n MAX_INPUT_LENGTH: 100_000,\n MAX_TIMEOUT_SECS: 600,\n MAX_CAPABILITIES: 20,\n MAX_DESCRIPTION_LENGTH: 500,\n MAX_AGENT_NAME_LENGTH: 64,\n MAX_CAPABILITY_LENGTH: 64,\n} as const;\n","import Decimal from 'decimal.js-light';\nimport { PROTOCOL_FEE_BPS } from '../constants';\n\n/** Assert that a value is a non-negative integer (lamports). */\nexport function assertLamports(value: number, field: string): void {\n if (!Number.isInteger(value) || value < 0) {\n throw new Error(`Invalid ${field}: ${value}. Must be a non-negative integer.`);\n }\n}\n\n/**\n * Calculate protocol fee using Decimal basis-point math (no floats).\n * Returns ceil(amount * PROTOCOL_FEE_BPS / 10000).\n * Safe for amounts up to Number.MAX_SAFE_INTEGER - Decimal handles intermediate values.\n */\nexport function calculateProtocolFee(amount: number): number {\n if (!Number.isInteger(amount) || amount < 0) {\n throw new Error(`Invalid fee amount: ${amount}. Must be a non-negative integer.`);\n }\n if (amount === 0) {\n return 0;\n }\n return new Decimal(amount)\n .mul(PROTOCOL_FEE_BPS)\n .div(10000)\n .toDecimalPlaces(0, Decimal.ROUND_CEIL)\n .toNumber();\n}\n\n/** Validate payment request timestamps. Returns error message or null if valid. */\nexport function validateExpiry(createdAt: number, expirySecs: number): string | null {\n if (!Number.isInteger(createdAt) || createdAt <= 0) {\n return 'Invalid or missing created_at in payment request.';\n }\n if (!Number.isInteger(expirySecs) || expirySecs <= 0) {\n return 'Invalid or missing expiry_secs in payment request.';\n }\n const now = Math.floor(Date.now() / 1000);\n if (createdAt > now + 120) {\n return `Payment request created_at is in the future (${createdAt} vs now ${now}). Possible manipulation.`;\n }\n if (now - createdAt > expirySecs) {\n return `Payment request expired (created ${createdAt}, expiry ${expirySecs}s).`;\n }\n return null;\n}\n\n/** Assert that payment request timestamps are valid and not expired. Throws on failure. */\nexport function assertExpiry(createdAt: number, expirySecs: number): void {\n const error = validateExpiry(createdAt, expirySecs);\n if (error) {\n throw new Error(error);\n }\n}\n","import { Connection, Keypair, PublicKey, SystemProgram, Transaction } from '@solana/web3.js';\nimport { PROTOCOL_TREASURY, PROTOCOL_FEE_BPS, DEFAULTS, LIMITS } from '../constants';\nimport type {\n PaymentRequestData,\n VerifyResult,\n VerifyOptions,\n PaymentValidationError,\n} from '../types';\nimport { calculateProtocolFee, validateExpiry, assertExpiry, assertLamports } from './fee';\nimport type { PaymentStrategy } from './strategy';\n\nfunction isValidSolanaAddress(address: string): boolean {\n try {\n void new PublicKey(address);\n return true;\n } catch {\n return false;\n }\n}\n\nexport class SolanaPaymentStrategy implements PaymentStrategy {\n readonly chain = 'solana';\n\n calculateFee(amount: number): number {\n return calculateProtocolFee(amount);\n }\n\n createPaymentRequest(\n recipientAddress: string,\n amount: number,\n expirySecs: number = DEFAULTS.PAYMENT_EXPIRY_SECS,\n ): PaymentRequestData {\n try {\n void new PublicKey(recipientAddress);\n } catch {\n throw new Error(`Invalid Solana address: ${recipientAddress}`);\n }\n assertLamports(amount, 'payment amount');\n if (amount === 0) {\n throw new Error('Invalid payment amount: 0. Must be positive.');\n }\n if (!Number.isInteger(expirySecs) || expirySecs <= 0 || expirySecs > LIMITS.MAX_TIMEOUT_SECS) {\n throw new Error(\n `Invalid expiry: ${expirySecs}. Must be integer 1-${LIMITS.MAX_TIMEOUT_SECS}.`,\n );\n }\n const feeAmount = calculateProtocolFee(amount);\n const reference = Keypair.generate().publicKey.toBase58();\n\n return {\n recipient: recipientAddress,\n amount,\n reference,\n fee_address: PROTOCOL_TREASURY,\n fee_amount: feeAmount,\n created_at: Math.floor(Date.now() / 1000),\n expiry_secs: expirySecs,\n };\n }\n\n validatePaymentRequest(\n requestJson: string,\n expectedRecipient?: string,\n ): PaymentValidationError | null {\n let data: PaymentRequestData;\n try {\n data = JSON.parse(requestJson);\n } catch (e) {\n return { code: 'invalid_json', message: `Invalid payment request JSON: ${e}` };\n }\n\n if (typeof data.amount !== 'number' || !Number.isInteger(data.amount) || data.amount <= 0) {\n return {\n code: 'invalid_amount',\n message: `Invalid amount in payment request: ${data.amount}`,\n };\n }\n if (typeof data.recipient !== 'string' || !data.recipient) {\n return { code: 'missing_recipient', message: 'Missing recipient in payment request' };\n }\n if (!isValidSolanaAddress(data.recipient)) {\n return {\n code: 'invalid_recipient_address',\n message: `Invalid Solana address for recipient: ${data.recipient}`,\n };\n }\n if (typeof data.reference !== 'string' || !data.reference) {\n return { code: 'missing_reference', message: 'Missing reference in payment request' };\n }\n if (!isValidSolanaAddress(data.reference)) {\n return {\n code: 'invalid_reference_address',\n message: `Invalid Solana address for reference: ${data.reference}`,\n };\n }\n\n if (expectedRecipient && data.recipient !== expectedRecipient) {\n return {\n code: 'recipient_mismatch',\n message:\n `Recipient mismatch: expected ${expectedRecipient}, got ${data.recipient}. ` +\n `Provider may be attempting to redirect payment.`,\n };\n }\n\n const expiryError = validateExpiry(data.created_at, data.expiry_secs);\n if (expiryError) {\n const code = expiryError.includes('future')\n ? ('future_timestamp' as const)\n : ('expired' as const);\n return { code, message: expiryError };\n }\n\n const expectedFee = calculateProtocolFee(data.amount);\n\n const { fee_address, fee_amount } = data;\n const hasFeeAddress = typeof fee_address === 'string' && fee_address.length > 0;\n const hasFeeAmount = typeof fee_amount === 'number' && fee_amount > 0;\n\n // Branch 1: fee present and valid - verify address and amount\n if (hasFeeAddress && hasFeeAmount) {\n if (fee_address !== PROTOCOL_TREASURY) {\n return {\n code: 'fee_address_mismatch',\n message:\n `Fee address mismatch: expected ${PROTOCOL_TREASURY}, got ${fee_address}. ` +\n `Provider may be attempting to redirect fees.`,\n };\n }\n if (fee_amount !== expectedFee) {\n return {\n code: 'fee_amount_mismatch',\n message:\n `Fee amount mismatch: expected ${expectedFee} lamports ` +\n `(${PROTOCOL_FEE_BPS}bps of ${data.amount}), got ${fee_amount}. ` +\n `Provider may be tampering with fee.`,\n };\n }\n return null;\n }\n\n // Branch 2: fee entirely absent - reject\n if (!hasFeeAddress && (fee_amount === null || fee_amount === undefined || fee_amount === 0)) {\n return {\n code: 'missing_fee',\n message:\n `Payment request missing protocol fee (${PROTOCOL_FEE_BPS}bps). ` +\n `Expected fee: ${expectedFee} lamports to ${PROTOCOL_TREASURY}.`,\n };\n }\n\n // Branch 3: partial fee params (one present, other missing/zero) - reject\n return {\n code: 'invalid_fee_params',\n message:\n `Invalid fee params in payment request. ` +\n `Expected fee: ${expectedFee} lamports to ${PROTOCOL_TREASURY}.`,\n };\n }\n\n /**\n * Build an unsigned transaction from a payment request.\n * The caller must set `recentBlockhash` and `feePayer` on the\n * returned Transaction before signing and sending.\n */\n async buildTransaction(\n payerAddress: string,\n paymentRequest: PaymentRequestData,\n ): Promise<Transaction> {\n assertLamports(paymentRequest.amount, 'payment amount');\n if (paymentRequest.amount === 0) {\n throw new Error('Invalid payment amount: 0. Must be positive.');\n }\n if (\n paymentRequest.fee_amount !== null &&\n paymentRequest.fee_amount !== undefined &&\n (!Number.isInteger(paymentRequest.fee_amount) || paymentRequest.fee_amount < 0)\n ) {\n throw new Error(\n `Invalid fee amount: ${paymentRequest.fee_amount}. Must be a non-negative integer (lamports).`,\n );\n }\n assertExpiry(paymentRequest.created_at, paymentRequest.expiry_secs);\n\n if (paymentRequest.fee_address && paymentRequest.fee_address !== PROTOCOL_TREASURY) {\n throw new Error(\n `Invalid fee address: expected ${PROTOCOL_TREASURY}, got ${paymentRequest.fee_address}. ` +\n `Cannot build transaction with redirected fees.`,\n );\n }\n\n const payerPubkey = new PublicKey(payerAddress);\n const recipient = new PublicKey(paymentRequest.recipient);\n const reference = new PublicKey(paymentRequest.reference);\n const feeAddress = paymentRequest.fee_address\n ? new PublicKey(paymentRequest.fee_address)\n : null;\n const feeAmount = paymentRequest.fee_amount ?? 0;\n\n // Both amount and feeAmount are validated integers (lamports), so subtraction is exact.\n const providerAmount =\n feeAddress && feeAmount > 0 ? paymentRequest.amount - feeAmount : paymentRequest.amount;\n\n if (providerAmount <= 0) {\n throw new Error(\n `Fee amount (${feeAmount}) exceeds or equals total amount (${paymentRequest.amount}). Cannot create transaction with non-positive provider amount.`,\n );\n }\n\n // Provider transfer with reference key (for payment detection)\n const transferIx = SystemProgram.transfer({\n fromPubkey: payerPubkey,\n toPubkey: recipient,\n lamports: providerAmount,\n });\n // Append reference as read-only non-signer so provider can detect via getSignaturesForAddress\n transferIx.keys.push({\n pubkey: reference,\n isSigner: false,\n isWritable: false,\n });\n\n const tx = new Transaction().add(transferIx);\n\n // Fee transfer\n if (feeAddress && feeAmount > 0) {\n tx.add(\n SystemProgram.transfer({\n fromPubkey: payerPubkey,\n toPubkey: feeAddress,\n lamports: feeAmount,\n }),\n );\n }\n\n return tx;\n }\n\n async verifyPayment(\n connection: unknown,\n paymentRequest: PaymentRequestData,\n options?: VerifyOptions,\n ): Promise<VerifyResult> {\n if (\n !connection ||\n typeof (connection as Record<string, unknown>).getTransaction !== 'function'\n ) {\n return { verified: false, error: 'Invalid connection: expected Solana Connection instance' };\n }\n const conn = connection as Connection;\n\n if (!paymentRequest.reference || !paymentRequest.recipient) {\n return { verified: false, error: 'Missing required fields in payment request' };\n }\n if (!Number.isInteger(paymentRequest.amount) || paymentRequest.amount <= 0) {\n return {\n verified: false,\n error: `Invalid payment amount: ${paymentRequest.amount}. Must be a positive integer.`,\n };\n }\n\n // No expiry check here - verification confirms on-chain payment regardless of timing.\n // Expiry is enforced before payment in validatePaymentRequest() and buildTransaction().\n\n if (\n paymentRequest.fee_amount !== null &&\n paymentRequest.fee_amount !== undefined &&\n (!Number.isInteger(paymentRequest.fee_amount) || paymentRequest.fee_amount < 0)\n ) {\n return {\n verified: false,\n error: `Invalid fee_amount: ${paymentRequest.fee_amount}. Must be a non-negative integer.`,\n };\n }\n\n const expectedFee = calculateProtocolFee(paymentRequest.amount);\n const feeAmount = paymentRequest.fee_amount ?? 0;\n\n if (expectedFee > 0) {\n if (feeAmount < expectedFee) {\n return {\n verified: false,\n error: `Protocol fee ${feeAmount} below required ${expectedFee} (${PROTOCOL_FEE_BPS}bps of ${paymentRequest.amount})`,\n };\n }\n if (!paymentRequest.fee_address) {\n return { verified: false, error: 'Missing fee address in payment request' };\n }\n if (paymentRequest.fee_address !== PROTOCOL_TREASURY) {\n return { verified: false, error: `Invalid fee address: ${paymentRequest.fee_address}` };\n }\n }\n\n // Both amount and feeAmount are validated integers (lamports), so subtraction is exact.\n const expectedNet = paymentRequest.amount - feeAmount;\n\n if (expectedNet <= 0) {\n return {\n verified: false,\n error: `Fee amount (${feeAmount}) exceeds or equals total amount (${paymentRequest.amount})`,\n };\n }\n\n // If tx signature provided, verify by signature\n if (options?.txSignature) {\n return this._verifyBySignature(\n conn,\n options.txSignature,\n paymentRequest.reference,\n paymentRequest.recipient,\n expectedNet,\n feeAmount,\n options?.retries ?? DEFAULTS.VERIFY_RETRIES,\n options?.intervalMs ?? DEFAULTS.VERIFY_INTERVAL_MS,\n );\n }\n\n // Otherwise verify by reference key\n return this._verifyByReference(\n conn,\n paymentRequest.reference,\n paymentRequest.recipient,\n expectedNet,\n feeAmount,\n options?.retries ?? DEFAULTS.VERIFY_BY_REF_RETRIES,\n options?.intervalMs ?? DEFAULTS.VERIFY_BY_REF_INTERVAL_MS,\n );\n }\n\n private async _verifyBySignature(\n connection: Connection,\n txSignature: string,\n referenceKey: string,\n recipientAddress: string,\n expectedNet: number,\n expectedFee: number,\n retries: number,\n intervalMs: number,\n ): Promise<VerifyResult> {\n let lastError: unknown;\n for (let attempt = 0; attempt < retries; attempt++) {\n try {\n const tx = await connection.getTransaction(txSignature, {\n maxSupportedTransactionVersion: 0,\n commitment: 'confirmed',\n });\n\n if (!tx?.meta || tx.meta.err) {\n if (attempt < retries - 1) {\n await new Promise((r) => setTimeout(r, intervalMs));\n continue;\n }\n return {\n verified: false,\n error: tx?.meta?.err ? 'Transaction failed on-chain' : 'Transaction not found',\n };\n }\n\n const accountKeys = tx.transaction.message.getAccountKeys();\n const balanceCount = tx.meta.preBalances.length;\n // Map address -> original index to preserve balance array correspondence.\n const keyToIdx = new Map<string, number>();\n for (let i = 0; i < Math.min(accountKeys.length, balanceCount); i++) {\n const key = accountKeys.get(i);\n if (key) {\n keyToIdx.set(key.toBase58(), i);\n }\n }\n\n if (!keyToIdx.has(referenceKey)) {\n return {\n verified: false,\n error: 'Reference key not found in transaction - possible replay',\n };\n }\n\n const recipientIdx = keyToIdx.get(recipientAddress);\n if (recipientIdx === undefined) {\n return { verified: false, error: 'Recipient not found in transaction' };\n }\n\n const recipientDelta =\n (tx.meta.postBalances[recipientIdx] ?? 0) - (tx.meta.preBalances[recipientIdx] ?? 0);\n if (recipientDelta < expectedNet) {\n return {\n verified: false,\n error: `Recipient received ${recipientDelta}, expected >= ${expectedNet}`,\n };\n }\n\n if (expectedFee > 0) {\n const treasuryIdx = keyToIdx.get(PROTOCOL_TREASURY);\n if (treasuryIdx === undefined) {\n return { verified: false, error: 'Treasury not found in transaction' };\n }\n const treasuryDelta =\n (tx.meta.postBalances[treasuryIdx] ?? 0) - (tx.meta.preBalances[treasuryIdx] ?? 0);\n if (treasuryDelta < expectedFee) {\n return {\n verified: false,\n error: `Treasury received ${treasuryDelta}, expected >= ${expectedFee}`,\n };\n }\n }\n\n return { verified: true, txSignature };\n } catch (err) {\n lastError = err;\n if (attempt < retries - 1) {\n await new Promise((r) => setTimeout(r, intervalMs));\n }\n }\n }\n return {\n verified: false,\n error: `Verification failed after ${retries} retries: ${lastError instanceof Error ? lastError.message : 'unknown error'}`,\n };\n }\n\n private async _verifyByReference(\n connection: Connection,\n referenceKey: string,\n recipientAddress: string,\n expectedNet: number,\n expectedFee: number,\n retries: number,\n intervalMs: number,\n ): Promise<VerifyResult> {\n const reference = new PublicKey(referenceKey);\n let lastError: unknown;\n\n for (let attempt = 0; attempt < retries; attempt++) {\n try {\n const signatures = await connection.getSignaturesForAddress(reference, {\n limit: DEFAULTS.VERIFY_SIGNATURE_LIMIT,\n });\n const validSigs = signatures.filter((s) => !s.err);\n\n if (validSigs.length > 0) {\n const txResults = await Promise.all(\n validSigs.map((s) =>\n connection\n .getTransaction(s.signature, {\n maxSupportedTransactionVersion: 0,\n commitment: 'confirmed',\n })\n .then((tx) => ({ sig: s.signature, tx }))\n .catch(() => ({\n sig: s.signature,\n tx: null as Awaited<ReturnType<Connection['getTransaction']>>,\n })),\n ),\n );\n\n for (const { sig, tx } of txResults) {\n if (!tx?.meta || tx.meta.err) {\n continue;\n }\n\n const accountKeys = tx.transaction.message.getAccountKeys();\n const balanceCount = tx.meta.preBalances.length;\n // Map address -> original index to preserve balance array correspondence.\n const keyToIdx = new Map<string, number>();\n for (let i = 0; i < Math.min(accountKeys.length, balanceCount); i++) {\n const key = accountKeys.get(i);\n if (key) {\n keyToIdx.set(key.toBase58(), i);\n }\n }\n\n const recipientIdx = keyToIdx.get(recipientAddress);\n if (recipientIdx === undefined) {\n continue;\n }\n\n const recipientDelta =\n (tx.meta.postBalances[recipientIdx] ?? 0) - (tx.meta.preBalances[recipientIdx] ?? 0);\n if (recipientDelta < expectedNet) {\n continue;\n }\n\n if (expectedFee > 0) {\n const treasuryIdx = keyToIdx.get(PROTOCOL_TREASURY);\n if (treasuryIdx === undefined) {\n continue;\n }\n const treasuryDelta =\n (tx.meta.postBalances[treasuryIdx] ?? 0) - (tx.meta.preBalances[treasuryIdx] ?? 0);\n if (treasuryDelta < expectedFee) {\n continue;\n }\n }\n\n return { verified: true, txSignature: sig };\n }\n }\n } catch (err) {\n lastError = err;\n }\n\n if (attempt < retries - 1) {\n await new Promise((r) => setTimeout(r, intervalMs));\n }\n }\n return {\n verified: false,\n error: lastError\n ? `Verification failed: ${lastError instanceof Error ? lastError.message : 'unknown error'}`\n : 'No matching transaction found for reference key',\n };\n }\n}\n","import { nip19, finalizeEvent, verifyEvent, type Filter, type Event } from 'nostr-tools';\nimport {\n KIND_APP_HANDLER,\n KIND_JOB_FEEDBACK,\n KIND_JOB_REQUEST,\n KIND_JOB_REQUEST_BASE,\n KIND_JOB_RESULT_BASE,\n jobResultKind,\n DEFAULT_KIND_OFFSET,\n LIMITS,\n} from '../constants';\nimport type { ElisymIdentity } from '../primitives/identity';\nimport type { NostrPool } from '../transport/pool';\nimport type { Agent, CapabilityCard, Network } from '../types';\n\n/** Convert a capability name to its Nostr d-tag form (ASCII-only, lowercase, hyphen-separated). */\nexport function toDTag(name: string): string {\n const tag = name\n .toLowerCase()\n .replace(/[^a-z0-9\\s-]/g, (ch) => '_' + ch.charCodeAt(0).toString(16).padStart(2, '0'))\n .replace(/\\s+/g, '-')\n .replace(/^-+|-+$/g, '');\n if (!tag) {\n throw new Error('Capability name must contain at least one ASCII alphanumeric character.');\n }\n return tag;\n}\n\n/**\n * Deduplicate events by (pubkey, d-tag) keeping only the newest,\n * then build an Agent map filtered by network.\n */\nfunction buildAgentsFromEvents(events: Event[], network: Network): Map<string, Agent> {\n // Deduplicate by author + d-tag, keeping only the newest event\n const latestByDTag = new Map<string, Event>();\n for (const event of events) {\n if (!verifyEvent(event)) {\n continue;\n }\n const dTag = event.tags.find((t) => t[0] === 'd')?.[1] ?? '';\n const key = `${event.pubkey}:${dTag}`;\n const prev = latestByDTag.get(key);\n if (!prev || event.created_at > prev.created_at) {\n latestByDTag.set(key, event);\n }\n }\n\n // Intermediate structure: keep kTags per card so we can recompute\n // supportedKinds from only the surviving (deduplicated) entries.\n interface CardEntry {\n card: CapabilityCard;\n kTags: number[];\n createdAt: number;\n }\n interface AgentAccum {\n pubkey: string;\n npub: string;\n entries: CardEntry[];\n eventId: string;\n lastSeen: number;\n }\n\n const accumMap = new Map<string, AgentAccum>();\n\n for (const event of latestByDTag.values()) {\n try {\n if (!event.content) {\n continue;\n }\n const raw = JSON.parse(event.content);\n if (!raw || typeof raw !== 'object') {\n continue;\n }\n if (typeof raw.name !== 'string' || !raw.name) {\n continue;\n }\n if (typeof raw.description !== 'string') {\n continue;\n }\n if (\n !Array.isArray(raw.capabilities) ||\n !raw.capabilities.every((c: unknown) => typeof c === 'string')\n ) {\n continue;\n }\n if (raw.deleted) {\n continue;\n }\n const card = raw as CapabilityCard & { deleted?: boolean };\n\n // Validate payment field types if present\n if (\n card.payment &&\n (typeof card.payment.chain !== 'string' ||\n typeof card.payment.network !== 'string' ||\n typeof card.payment.address !== 'string')\n ) {\n continue;\n }\n\n // Validate payment.job_price if present\n if (\n card.payment?.job_price !== null &&\n card.payment?.job_price !== undefined &&\n (!Number.isInteger(card.payment.job_price) || card.payment.job_price < 0)\n ) {\n continue;\n }\n\n const agentNetwork = card.payment?.network ?? 'devnet';\n if (agentNetwork !== network) {\n continue;\n }\n\n const kTags = event.tags\n .filter((t) => t[0] === 'k')\n .map((t) => parseInt(t[1] ?? '', 10))\n .filter((k) => !isNaN(k));\n\n const entry: CardEntry = { card, kTags, createdAt: event.created_at };\n\n const existing = accumMap.get(event.pubkey);\n if (existing) {\n // Deduplicate by card name - keep the newer version\n const dupIndex = existing.entries.findIndex((e) => e.card.name === card.name);\n if (dupIndex >= 0) {\n if (entry.createdAt >= existing.entries[dupIndex]!.createdAt) {\n existing.entries[dupIndex] = entry;\n }\n } else {\n existing.entries.push(entry);\n }\n if (event.created_at > existing.lastSeen) {\n existing.lastSeen = event.created_at;\n existing.eventId = event.id;\n }\n } else {\n accumMap.set(event.pubkey, {\n pubkey: event.pubkey,\n npub: nip19.npubEncode(event.pubkey),\n entries: [entry],\n eventId: event.id,\n lastSeen: event.created_at,\n });\n }\n } catch {\n // skip malformed events\n }\n }\n\n // Build final Agent map - recompute supportedKinds from surviving entries only\n const agentMap = new Map<string, Agent>();\n for (const [pubkey, acc] of accumMap) {\n const kindsSet = new Set<number>();\n for (const e of acc.entries) {\n for (const k of e.kTags) {\n kindsSet.add(k);\n }\n }\n const supportedKinds = [...kindsSet];\n agentMap.set(pubkey, {\n pubkey: acc.pubkey,\n npub: acc.npub,\n cards: acc.entries.map((e) => e.card),\n eventId: acc.eventId,\n supportedKinds,\n lastSeen: acc.lastSeen,\n });\n }\n\n return agentMap;\n}\n\nexport class DiscoveryService {\n constructor(private pool: NostrPool) {}\n\n /** Count elisym agents (kind:31990 with \"elisym\" tag). */\n async fetchAllAgentCount(): Promise<number> {\n const events = await this.pool.querySync({\n kinds: [KIND_APP_HANDLER],\n '#t': ['elisym'],\n } as Filter);\n\n const uniquePubkeys = new Set<string>();\n for (const event of events) {\n if (!verifyEvent(event)) {\n continue;\n }\n uniquePubkeys.add(event.pubkey);\n }\n return uniquePubkeys.size;\n }\n\n /**\n * Fetch a single page of elisym agents with relay-side pagination.\n * Uses `until` cursor for Nostr cursor-based pagination.\n *\n * Unlike `fetchAgents`, this method does NOT enrich agents with\n * kind:0 metadata (name, picture, about) or update `lastSeen` from\n * recent job activity. Call `enrichWithMetadata()` separately if needed.\n */\n async fetchAgentsPage(\n network: Network = 'devnet',\n limit = 20,\n until?: number,\n ): Promise<{ agents: Agent[]; oldestCreatedAt: number | null; rawEventCount: number }> {\n const filter: Filter = {\n kinds: [KIND_APP_HANDLER],\n '#t': ['elisym'],\n limit,\n };\n if (until !== undefined) {\n filter.until = until;\n }\n\n const events = await this.pool.querySync(filter);\n const rawEventCount = events.length;\n\n // Compute cursor from ALL raw events (before any filtering)\n let oldestCreatedAt: number | null = null;\n for (const event of events) {\n if (oldestCreatedAt === null || event.created_at < oldestCreatedAt) {\n oldestCreatedAt = event.created_at;\n }\n }\n\n const agentMap = buildAgentsFromEvents(events, network);\n\n const agents = Array.from(agentMap.values()).sort((a, b) => b.lastSeen - a.lastSeen);\n\n return { agents, oldestCreatedAt, rawEventCount };\n }\n\n /** Enrich agents with kind:0 metadata (name, picture, about). Mutates in place and returns the same array. */\n async enrichWithMetadata(agents: Agent[]): Promise<Agent[]> {\n const pubkeys = agents.map((a) => a.pubkey);\n if (pubkeys.length === 0) {\n return agents;\n }\n\n const metaEvents = await this.pool.queryBatched(\n { kinds: [0] } as Omit<Filter, 'authors'>,\n pubkeys,\n );\n const latestMeta = new Map<string, (typeof metaEvents)[0]>();\n for (const ev of metaEvents) {\n if (!verifyEvent(ev)) {\n continue;\n }\n const prev = latestMeta.get(ev.pubkey);\n if (!prev || ev.created_at > prev.created_at) {\n latestMeta.set(ev.pubkey, ev);\n }\n }\n const agentLookup = new Map(agents.map((a) => [a.pubkey, a]));\n for (const [pubkey, ev] of latestMeta) {\n const agent = agentLookup.get(pubkey);\n if (!agent) {\n continue;\n }\n try {\n const meta = JSON.parse(ev.content);\n if (typeof meta.picture === 'string') {\n agent.picture = meta.picture;\n }\n if (typeof meta.name === 'string') {\n agent.name = meta.name;\n }\n if (typeof meta.about === 'string') {\n agent.about = meta.about;\n }\n } catch {\n // skip malformed metadata\n }\n }\n return agents;\n }\n\n /** Fetch elisym agents filtered by network. */\n async fetchAgents(network: Network = 'devnet', limit?: number): Promise<Agent[]> {\n const filter: Filter = {\n kinds: [KIND_APP_HANDLER],\n '#t': ['elisym'],\n };\n if (limit !== undefined) {\n filter.limit = limit;\n }\n const events = await this.pool.querySync(filter);\n\n const agentMap = buildAgentsFromEvents(events, network);\n\n const agents = Array.from(agentMap.values()).sort((a, b) => b.lastSeen - a.lastSeen);\n\n // Update lastSeen from recent job activity\n const agentPubkeys = Array.from(agentMap.keys());\n if (agentPubkeys.length > 0) {\n const activitySince = Math.floor(Date.now() / 1000) - 24 * 60 * 60;\n // Derive result kinds from agents' supported request kinds (5xxx - 6xxx)\n const resultKinds = new Set<number>();\n for (const agent of agentMap.values()) {\n for (const k of agent.supportedKinds) {\n if (k >= KIND_JOB_REQUEST_BASE && k < KIND_JOB_RESULT_BASE) {\n resultKinds.add(KIND_JOB_RESULT_BASE + (k - KIND_JOB_REQUEST_BASE));\n }\n }\n }\n resultKinds.add(jobResultKind(DEFAULT_KIND_OFFSET));\n\n // Fetch activity and metadata in parallel (independent: activity writes lastSeen, metadata writes name/picture/about)\n const [activityEvents] = await Promise.all([\n this.pool.queryBatched(\n {\n kinds: [...resultKinds, KIND_JOB_FEEDBACK],\n since: activitySince,\n } as Omit<Filter, 'authors'>,\n agentPubkeys,\n ),\n this.enrichWithMetadata(agents),\n ]);\n for (const ev of activityEvents) {\n if (!verifyEvent(ev)) {\n continue;\n }\n const agent = agentMap.get(ev.pubkey);\n if (agent && ev.created_at > agent.lastSeen) {\n agent.lastSeen = ev.created_at;\n }\n }\n\n agents.sort((a, b) => b.lastSeen - a.lastSeen);\n }\n\n return agents;\n }\n\n /**\n * Publish a capability card (kind:31990) as a provider.\n * Solana address is validated for Base58 format only - full decode\n * validation (32-byte public key) happens at payment time.\n */\n async publishCapability(\n identity: ElisymIdentity,\n card: CapabilityCard,\n kinds: number[] = [KIND_JOB_REQUEST],\n ): Promise<string> {\n if (!card.payment?.address) {\n throw new Error(\n 'Cannot publish capability without a payment address. Connect a wallet before publishing.',\n );\n }\n // Base58 charset + length check. Full validation (decode + 32 bytes) happens\n // at payment time via PublicKey constructor - no @solana/web3.js import here\n // to keep discovery browser-safe without Solana peer dep.\n if (\n card.payment.chain === 'solana' &&\n !/^[1-9A-HJ-NP-Za-km-z]{32,44}$/.test(card.payment.address)\n ) {\n throw new Error(`Invalid Solana address format: ${card.payment.address}`);\n }\n if (card.name.length > LIMITS.MAX_AGENT_NAME_LENGTH) {\n throw new Error(\n `Agent name too long: ${card.name.length} chars (max ${LIMITS.MAX_AGENT_NAME_LENGTH}).`,\n );\n }\n if (card.description.length > LIMITS.MAX_DESCRIPTION_LENGTH) {\n throw new Error(\n `Description too long: ${card.description.length} chars (max ${LIMITS.MAX_DESCRIPTION_LENGTH}).`,\n );\n }\n if (card.capabilities.length > LIMITS.MAX_CAPABILITIES) {\n throw new Error(\n `Too many capabilities: ${card.capabilities.length} (max ${LIMITS.MAX_CAPABILITIES}).`,\n );\n }\n for (const cap of card.capabilities) {\n if (cap.length > LIMITS.MAX_CAPABILITY_LENGTH) {\n throw new Error(\n `Capability name too long: \"${cap}\" (${cap.length} chars, max ${LIMITS.MAX_CAPABILITY_LENGTH}).`,\n );\n }\n }\n\n const tags: string[][] = [\n ['d', toDTag(card.name)],\n ['t', 'elisym'],\n ...card.capabilities.map((c) => ['t', c]),\n ...kinds.map((k) => ['k', String(k)]),\n ];\n\n const event = finalizeEvent(\n {\n kind: KIND_APP_HANDLER,\n created_at: Math.floor(Date.now() / 1000),\n tags,\n content: JSON.stringify(card),\n },\n identity.secretKey,\n );\n\n await this.pool.publishAll(event);\n return event.id;\n }\n\n /** Publish a Nostr profile (kind:0) as a provider. */\n async publishProfile(\n identity: ElisymIdentity,\n name: string,\n about: string,\n picture?: string,\n banner?: string,\n ): Promise<string> {\n if (name.length > LIMITS.MAX_AGENT_NAME_LENGTH) {\n throw new Error(\n `Profile name too long: ${name.length} chars (max ${LIMITS.MAX_AGENT_NAME_LENGTH}).`,\n );\n }\n if (about.length > LIMITS.MAX_DESCRIPTION_LENGTH) {\n throw new Error(\n `Profile about too long: ${about.length} chars (max ${LIMITS.MAX_DESCRIPTION_LENGTH}).`,\n );\n }\n const content: Record<string, string> = { name, about };\n if (picture) {\n content.picture = picture;\n }\n if (banner) {\n content.banner = banner;\n }\n\n const event = finalizeEvent(\n {\n kind: 0,\n created_at: Math.floor(Date.now() / 1000),\n tags: [],\n content: JSON.stringify(content),\n },\n identity.secretKey,\n );\n\n await this.pool.publishAll(event);\n return event.id;\n }\n\n /**\n * Delete a capability by publishing a tombstone replacement.\n * Since kind:31990 is a parameterized replaceable event,\n * publishing a new event with the same `d` tag and `\"deleted\":true`\n * content replaces the old one on all relays.\n */\n async deleteCapability(identity: ElisymIdentity, capabilityName: string): Promise<string> {\n const dTag = toDTag(capabilityName);\n\n const event = finalizeEvent(\n {\n kind: KIND_APP_HANDLER,\n created_at: Math.floor(Date.now() / 1000),\n tags: [\n ['d', dTag],\n ['t', 'elisym'],\n ],\n content: JSON.stringify({ deleted: true }),\n },\n identity.secretKey,\n );\n\n await this.pool.publishAll(event);\n return event.id;\n }\n}\n","/**\n * NIP-44 encryption/decryption helpers.\n * Wraps nostr-tools nip44 v2 for convenience.\n */\nimport * as nip44 from 'nostr-tools/nip44';\n\n/** Encrypt plaintext using NIP-44 v2 (sender secret key + recipient public key). */\nexport function nip44Encrypt(\n plaintext: string,\n senderSk: Uint8Array,\n recipientPubkey: string,\n): string {\n const conversationKey = nip44.v2.utils.getConversationKey(senderSk, recipientPubkey);\n return nip44.v2.encrypt(plaintext, conversationKey);\n}\n\n/** Decrypt ciphertext using NIP-44 v2 (receiver secret key + sender public key). */\nexport function nip44Decrypt(\n ciphertext: string,\n receiverSk: Uint8Array,\n senderPubkey: string,\n): string {\n const conversationKey = nip44.v2.utils.getConversationKey(receiverSk, senderPubkey);\n return nip44.v2.decrypt(ciphertext, conversationKey);\n}\n","import { finalizeEvent, verifyEvent, type Filter, type Event } from 'nostr-tools';\nimport {\n KIND_JOB_FEEDBACK,\n KIND_JOB_REQUEST_BASE,\n KIND_JOB_RESULT_BASE,\n DEFAULT_KIND_OFFSET,\n DEFAULTS,\n LIMITS,\n jobRequestKind,\n jobResultKind,\n} from '../constants';\nimport { assertLamports } from '../payment/fee';\nimport { nip44Encrypt, nip44Decrypt } from '../primitives/crypto';\nimport type { ElisymIdentity } from '../primitives/identity';\nimport type { NostrPool } from '../transport/pool';\nimport type { Job, JobStatus, SubCloser, SubmitJobOptions, JobSubscriptionOptions } from '../types';\n\nfunction isEncrypted(event: Event): boolean {\n return event.tags.some((t) => t[0] === 'encrypted' && t[1] === 'nip44');\n}\n\nfunction resolveRequestId(event: Event): string | undefined {\n return event.tags.find((t) => t[0] === 'e')?.[1];\n}\n\nfunction safeParseInt(value: string | undefined): number | undefined {\n if (!value) {\n return undefined;\n }\n const n = parseInt(value, 10);\n return isNaN(n) ? undefined : n;\n}\n\nconst VALID_JOB_STATUSES = new Set<string>([\n 'payment-required',\n 'payment-completed',\n 'processing',\n 'error',\n 'success',\n 'partial',\n]);\n\nfunction toJobStatus(raw: string): JobStatus {\n return VALID_JOB_STATUSES.has(raw) ? (raw as JobStatus) : 'unknown';\n}\n\nexport class MarketplaceService {\n constructor(private pool: NostrPool) {}\n\n /** Submit a job request with NIP-44 encrypted input. Returns the event ID. */\n async submitJobRequest(identity: ElisymIdentity, options: SubmitJobOptions): Promise<string> {\n if (!options.input) {\n throw new Error('Job input must not be empty.');\n }\n if (options.input.length > LIMITS.MAX_INPUT_LENGTH) {\n throw new Error(\n `Job input too long: ${options.input.length} chars (max ${LIMITS.MAX_INPUT_LENGTH}).`,\n );\n }\n if (!options.capability || options.capability.length > LIMITS.MAX_CAPABILITY_LENGTH) {\n throw new Error(`Invalid capability: must be 1-${LIMITS.MAX_CAPABILITY_LENGTH} characters.`);\n }\n if (options.providerPubkey && !/^[0-9a-f]{64}$/.test(options.providerPubkey)) {\n throw new Error('Invalid provider pubkey: expected 64 hex characters.');\n }\n const plaintext = options.input;\n const encrypted = options.providerPubkey\n ? nip44Encrypt(plaintext, identity.secretKey, options.providerPubkey)\n : plaintext;\n\n const tags: string[][] = [\n ['i', options.providerPubkey ? 'encrypted' : 'text', 'text'],\n ['t', options.capability],\n ['t', 'elisym'],\n ['output', 'text/plain'],\n ];\n\n if (options.providerPubkey) {\n tags.push(['p', options.providerPubkey]);\n tags.push(['encrypted', 'nip44']);\n }\n\n const kind = jobRequestKind(options.kindOffset ?? DEFAULT_KIND_OFFSET);\n const event = finalizeEvent(\n {\n kind,\n created_at: Math.floor(Date.now() / 1000),\n tags,\n content: encrypted,\n },\n identity.secretKey,\n );\n\n await this.pool.publish(event);\n return event.id;\n }\n\n /**\n * Subscribe to job updates (feedback + results) for a given job.\n * Creates 3 subscriptions per call (feedback, result by #e, result by #p+#e)\n * to cover different relay indexing strategies. Returns a cleanup function.\n */\n subscribeToJobUpdates(options: JobSubscriptionOptions): () => void {\n const {\n jobEventId: jid,\n providerPubkey: provPk,\n customerPublicKey: custPk,\n callbacks: cb,\n timeoutMs = DEFAULTS.SUBSCRIPTION_TIMEOUT_MS,\n customerSecretKey: custSk,\n kindOffsets: offsets_,\n sinceOverride: since_,\n } = options;\n\n const offsets = offsets_ ?? [DEFAULT_KIND_OFFSET];\n if (offsets.length === 0) {\n throw new Error('kindOffsets must not be empty.');\n }\n const resultKinds = offsets.map(jobResultKind);\n const since = since_ ?? Math.floor(Date.now() / 1000) - 30;\n const subs: SubCloser[] = [];\n let resolved = false;\n let resultDelivered = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n const done = () => {\n resolved = true;\n if (timer) {\n clearTimeout(timer);\n }\n for (const s of subs) {\n try {\n s.close();\n } catch {\n /* ignore */\n }\n }\n };\n\n const decryptResult = (ev: Event): string | null => {\n if (isEncrypted(ev)) {\n if (!custSk) {\n return null;\n }\n try {\n return nip44Decrypt(ev.content, custSk, ev.pubkey);\n } catch {\n return null;\n }\n }\n return ev.content;\n };\n\n const handleResult = (ev: Event) => {\n if (resolved || resultDelivered) {\n return;\n }\n if (!verifyEvent(ev)) {\n return;\n }\n if (provPk && ev.pubkey !== provPk) {\n return;\n }\n const eTag = ev.tags.find((t) => t[0] === 'e')?.[1];\n if (eTag !== jid) {\n return;\n }\n const content = decryptResult(ev);\n if (content === null) {\n // Skip undecryptable results instead of terminating the subscription.\n // For broadcast jobs a rogue agent could send fake encrypted results;\n // killing the subscription would be a DoS vector.\n return;\n }\n resultDelivered = true;\n try {\n cb.onResult?.(content, ev.id);\n } catch {\n /* caller error - don't crash subscription */\n } finally {\n done();\n }\n };\n\n try {\n // Feedback subscription\n subs.push(\n this.pool.subscribe(\n {\n kinds: [KIND_JOB_FEEDBACK],\n '#e': [jid],\n since,\n } as Filter,\n (ev) => {\n if (resolved) {\n return;\n }\n if (!verifyEvent(ev)) {\n return;\n }\n if (provPk && ev.pubkey !== provPk) {\n return;\n }\n const eTag = ev.tags.find((t) => t[0] === 'e')?.[1];\n if (eTag !== jid) {\n return;\n }\n const statusTag = ev.tags.find((t) => t[0] === 'status');\n if (statusTag?.[1]) {\n const amtTag = ev.tags.find((t) => t[0] === 'amount');\n const amt = safeParseInt(amtTag?.[1]) ?? 0;\n const paymentReq = amtTag?.[2];\n try {\n cb.onFeedback?.(statusTag[1], amt, paymentReq, ev.pubkey);\n } catch {\n /* caller error - don't crash subscription */\n }\n }\n },\n ),\n );\n\n // Result subscription by #e tag\n subs.push(\n this.pool.subscribe(\n {\n kinds: resultKinds,\n '#e': [jid],\n since,\n } as Filter,\n handleResult,\n ),\n );\n\n // Result subscription by #p tag (customer pubkey) + #e tag\n subs.push(\n this.pool.subscribe(\n {\n kinds: resultKinds,\n '#p': [custPk],\n '#e': [jid],\n since,\n } as Filter,\n handleResult,\n ),\n );\n } catch (err) {\n done();\n throw err;\n }\n\n timer = setTimeout(() => {\n if (!resolved) {\n done();\n try {\n cb.onError?.(`Timed out waiting for response (${timeoutMs / 1000}s).`);\n } catch {\n /* caller error - don't crash subscription */\n }\n }\n }, timeoutMs);\n\n return done;\n }\n\n /** Submit payment confirmation feedback. */\n async submitPaymentConfirmation(\n identity: ElisymIdentity,\n jobEventId: string,\n providerPubkey: string,\n txSignature: string,\n ): Promise<void> {\n const event = finalizeEvent(\n {\n kind: KIND_JOB_FEEDBACK,\n created_at: Math.floor(Date.now() / 1000),\n tags: [\n ['e', jobEventId],\n ['p', providerPubkey],\n ['status', 'payment-completed'],\n ['tx', txSignature, 'solana'],\n ['t', 'elisym'],\n ],\n content: '',\n },\n identity.secretKey,\n );\n\n await this.pool.publishAll(event);\n }\n\n /** Submit rating feedback for a job. */\n async submitFeedback(\n identity: ElisymIdentity,\n jobEventId: string,\n providerPubkey: string,\n positive: boolean,\n capability?: string,\n ): Promise<void> {\n const tags: string[][] = [\n ['e', jobEventId],\n ['p', providerPubkey],\n ['status', 'success'],\n ['rating', positive ? '1' : '0'],\n ['t', 'elisym'],\n ];\n if (capability) {\n tags.push(['t', capability]);\n }\n\n const event = finalizeEvent(\n {\n kind: KIND_JOB_FEEDBACK,\n created_at: Math.floor(Date.now() / 1000),\n tags,\n content: positive ? 'Good result' : 'Poor result',\n },\n identity.secretKey,\n );\n\n await this.pool.publishAll(event);\n }\n\n // --- Provider methods ---\n\n /**\n * Subscribe to incoming job requests for specific kinds.\n * Automatically decrypts NIP-44 encrypted content.\n * Note: decrypted events have modified `content` - do not call `verifyEvent()` on them.\n * Signature verification is performed before decryption.\n */\n subscribeToJobRequests(\n identity: ElisymIdentity,\n kinds: number[],\n onRequest: (event: Event) => void,\n ): SubCloser {\n return this.pool.subscribe(\n {\n kinds,\n '#p': [identity.publicKey],\n '#t': ['elisym'],\n since: Math.floor(Date.now() / 1000) - 5,\n } as Filter,\n (event: Event) => {\n if (!verifyEvent(event)) {\n return;\n }\n if (isEncrypted(event) && event.content) {\n try {\n const decrypted = nip44Decrypt(event.content, identity.secretKey, event.pubkey);\n onRequest({ ...event, content: decrypted });\n } catch {\n // Can't decrypt - skip event (likely not intended for us)\n return;\n }\n } else {\n onRequest(event);\n }\n },\n );\n }\n\n /** Submit a job result with NIP-44 encrypted content. Result kind is derived from the request kind. */\n async submitJobResult(\n identity: ElisymIdentity,\n requestEvent: Event,\n content: string,\n amount?: number,\n ): Promise<string> {\n if (!content) {\n throw new Error('Job result content must not be empty.');\n }\n if (!Number.isInteger(requestEvent.kind)) {\n throw new Error(`Invalid request event kind: expected integer, got ${requestEvent.kind}.`);\n }\n const offset = requestEvent.kind - KIND_JOB_REQUEST_BASE;\n if (offset < 0 || offset >= 1000) {\n throw new Error(\n `Invalid request event kind ${requestEvent.kind}: expected a NIP-90 job request kind (5000-5999).`,\n );\n }\n const shouldEncrypt = isEncrypted(requestEvent);\n const resultContent = shouldEncrypt\n ? nip44Encrypt(content, identity.secretKey, requestEvent.pubkey)\n : content;\n const resultKind = KIND_JOB_RESULT_BASE + offset;\n\n const tags: string[][] = [\n ['e', requestEvent.id],\n ['p', requestEvent.pubkey],\n ['t', 'elisym'],\n ];\n if (shouldEncrypt) {\n tags.push(['encrypted', 'nip44']);\n }\n\n if (amount !== null && amount !== undefined) {\n assertLamports(amount, 'result amount');\n tags.push(['amount', String(amount)]);\n }\n\n const event = finalizeEvent(\n {\n kind: resultKind,\n created_at: Math.floor(Date.now() / 1000),\n tags,\n content: resultContent,\n },\n identity.secretKey,\n );\n\n await this.pool.publishAll(event);\n return event.id;\n }\n\n /**\n * Submit a job result with retry and exponential backoff.\n * Retries on publish failures (e.g. relay disconnects).\n * With maxAttempts=3: try, ~1s, try, ~2s, try, throw.\n * Jitter: 0.5x-1.0x of calculated delay.\n */\n async submitJobResultWithRetry(\n identity: ElisymIdentity,\n requestEvent: Event,\n content: string,\n amount?: number,\n maxAttempts: number = DEFAULTS.RESULT_RETRY_COUNT,\n baseDelayMs: number = DEFAULTS.RESULT_RETRY_BASE_MS,\n ): Promise<string> {\n const attempts = Math.max(1, maxAttempts);\n for (let attempt = 0; attempt < attempts; attempt++) {\n try {\n return await this.submitJobResult(identity, requestEvent, content, amount);\n } catch (e: unknown) {\n if (attempt >= attempts - 1) {\n throw e;\n }\n // Math.random is fine for jitter - not a security context\n const jitter = 0.5 + Math.random() * 0.5;\n await new Promise((r) => setTimeout(r, baseDelayMs * Math.pow(2, attempt) * jitter));\n }\n }\n throw new Error('All delivery attempts failed');\n }\n\n /** Submit payment-required feedback with a payment request. */\n async submitPaymentRequiredFeedback(\n identity: ElisymIdentity,\n requestEvent: Event,\n amount: number,\n paymentRequestJson: string,\n ): Promise<void> {\n assertLamports(amount, 'payment amount');\n if (amount === 0) {\n throw new Error('Invalid payment amount: 0. Must be positive.');\n }\n try {\n JSON.parse(paymentRequestJson);\n } catch {\n throw new Error('Invalid paymentRequestJson: must be valid JSON.');\n }\n if (paymentRequestJson.length > LIMITS.MAX_INPUT_LENGTH) {\n throw new Error(\n `paymentRequestJson too long: ${paymentRequestJson.length} chars (max ${LIMITS.MAX_INPUT_LENGTH}).`,\n );\n }\n\n const event = finalizeEvent(\n {\n kind: KIND_JOB_FEEDBACK,\n created_at: Math.floor(Date.now() / 1000),\n tags: [\n ['e', requestEvent.id],\n ['p', requestEvent.pubkey],\n ['status', 'payment-required'],\n ['amount', String(amount), paymentRequestJson, 'solana'],\n ['t', 'elisym'],\n ],\n content: '',\n },\n identity.secretKey,\n );\n\n await this.pool.publishAll(event);\n }\n\n /** Submit processing feedback to notify customer that work has started. */\n async submitProcessingFeedback(identity: ElisymIdentity, requestEvent: Event): Promise<void> {\n const event = finalizeEvent(\n {\n kind: KIND_JOB_FEEDBACK,\n created_at: Math.floor(Date.now() / 1000),\n tags: [\n ['e', requestEvent.id],\n ['p', requestEvent.pubkey],\n ['status', 'processing'],\n ['t', 'elisym'],\n ],\n content: '',\n },\n identity.secretKey,\n );\n\n await this.pool.publishAll(event);\n }\n\n /** Submit error feedback to notify customer of a failure. */\n async submitErrorFeedback(\n identity: ElisymIdentity,\n requestEvent: Event,\n message: string,\n ): Promise<void> {\n if (!message) {\n throw new Error('Error message must not be empty.');\n }\n if (message.length > LIMITS.MAX_INPUT_LENGTH) {\n throw new Error(\n `Error message too long: ${message.length} chars (max ${LIMITS.MAX_INPUT_LENGTH}).`,\n );\n }\n const event = finalizeEvent(\n {\n kind: KIND_JOB_FEEDBACK,\n created_at: Math.floor(Date.now() / 1000),\n tags: [\n ['e', requestEvent.id],\n ['p', requestEvent.pubkey],\n ['status', 'error'],\n ['t', 'elisym'],\n ],\n content: message,\n },\n identity.secretKey,\n );\n\n await this.pool.publishAll(event);\n }\n\n /** Query job results by request IDs and decrypt NIP-44 content. */\n async queryJobResults(\n identity: ElisymIdentity,\n requestIds: string[],\n kindOffsets?: number[],\n providerPubkey?: string,\n ): Promise<\n Map<\n string,\n { content: string; amount?: number; senderPubkey: string; decryptionFailed: boolean }\n >\n > {\n const offsets = kindOffsets ?? [DEFAULT_KIND_OFFSET];\n if (offsets.length === 0) {\n throw new Error('kindOffsets must not be empty.');\n }\n const resultKinds = offsets.map(jobResultKind);\n\n const results = await this.pool.queryBatchedByTag(\n { kinds: resultKinds } as Filter,\n 'e',\n requestIds,\n );\n\n const resultByRequest = new Map<\n string,\n { content: string; amount?: number; senderPubkey: string; decryptionFailed: boolean }\n >();\n const createdAtByRequest = new Map<string, number>();\n for (const r of results) {\n if (!verifyEvent(r)) {\n continue;\n }\n if (providerPubkey && r.pubkey !== providerPubkey) {\n continue;\n }\n const eTag = r.tags.find((t) => t[0] === 'e');\n if (!eTag?.[1]) {\n continue;\n }\n\n const prevTs = createdAtByRequest.get(eTag[1]) ?? 0;\n if (r.created_at < prevTs) {\n continue;\n }\n\n const amtTag = r.tags.find((t) => t[0] === 'amount');\n\n let content = r.content;\n let decryptionFailed = false;\n if (isEncrypted(r)) {\n try {\n content = nip44Decrypt(r.content, identity.secretKey, r.pubkey);\n } catch {\n content = '';\n decryptionFailed = true;\n }\n }\n\n createdAtByRequest.set(eTag[1], r.created_at);\n resultByRequest.set(eTag[1], {\n content,\n amount: safeParseInt(amtTag?.[1]),\n senderPubkey: r.pubkey,\n decryptionFailed,\n });\n }\n\n return resultByRequest;\n }\n\n // --- Query methods ---\n\n /**\n * Fetch recent jobs from the network.\n * NOTE: Job.result contains raw event content. For encrypted jobs,\n * this will be NIP-44 ciphertext - use queryJobResults() for decryption.\n */\n async fetchRecentJobs(\n agentPubkeys?: Set<string>,\n limit?: number,\n since?: number,\n /** Kind offsets to query (default [100]). */\n kindOffsets?: number[],\n ): Promise<Job[]> {\n const offsets = kindOffsets ?? [DEFAULT_KIND_OFFSET];\n if (offsets.length === 0) {\n throw new Error('kindOffsets must not be empty.');\n }\n const requestKinds = offsets.map(jobRequestKind);\n const resultKinds = offsets.map(jobResultKind);\n\n const reqFilter: Filter = {\n kinds: requestKinds,\n '#t': ['elisym'],\n ...(limit !== null && limit !== undefined && { limit }),\n ...(since !== null && since !== undefined && { since }),\n };\n const rawRequests = await this.pool.querySync(reqFilter);\n const requests = rawRequests.filter(verifyEvent);\n\n const requestIds = requests.map((r) => r.id);\n let results: Event[] = [];\n let feedbacks: Event[] = [];\n\n if (requestIds.length > 0) {\n const [rawResults, rawFeedbacks] = await Promise.all([\n this.pool.queryBatchedByTag({ kinds: resultKinds } as Filter, 'e', requestIds),\n this.pool.queryBatchedByTag({ kinds: [KIND_JOB_FEEDBACK] } as Filter, 'e', requestIds),\n ]);\n results = rawResults.filter(verifyEvent);\n feedbacks = rawFeedbacks.filter(verifyEvent);\n }\n\n // Build targeted agent map\n const targetedAgentByRequest = new Map<string, string>();\n for (const req of requests) {\n const pTag = req.tags.find((t) => t[0] === 'p');\n if (pTag?.[1]) {\n targetedAgentByRequest.set(req.id, pTag[1]);\n }\n }\n\n // Index results by request ID (respect targeted agent, keep newest)\n const resultsByRequest = new Map<string, Event>();\n for (const r of results) {\n const reqId = resolveRequestId(r);\n if (!reqId) {\n continue;\n }\n const targeted = targetedAgentByRequest.get(reqId);\n if (targeted && r.pubkey !== targeted) {\n continue;\n }\n const existing = resultsByRequest.get(reqId);\n if (!existing || r.created_at > existing.created_at) {\n resultsByRequest.set(reqId, r);\n }\n }\n\n const feedbackByRequest = new Map<string, Event>();\n for (const f of feedbacks) {\n const reqId = resolveRequestId(f);\n if (!reqId) {\n continue;\n }\n const targeted = targetedAgentByRequest.get(reqId);\n if (targeted && f.pubkey !== targeted) {\n continue;\n }\n const existing = feedbackByRequest.get(reqId);\n if (!existing || f.created_at > existing.created_at) {\n feedbackByRequest.set(reqId, f);\n }\n }\n\n // Index all feedbacks by request ID for O(1) lookup\n const feedbacksByRequestId = new Map<string, Event[]>();\n for (const f of feedbacks) {\n const reqId = resolveRequestId(f);\n if (!reqId) {\n continue;\n }\n const arr = feedbacksByRequestId.get(reqId);\n if (arr) {\n arr.push(f);\n } else {\n feedbacksByRequestId.set(reqId, [f]);\n }\n }\n\n const jobs: Job[] = [];\n for (const req of requests) {\n const result = resultsByRequest.get(req.id);\n const feedback = feedbackByRequest.get(req.id);\n const jobAgentPubkey = result?.pubkey ?? feedback?.pubkey;\n\n if (agentPubkeys && agentPubkeys.size > 0 && jobAgentPubkey) {\n if (!agentPubkeys.has(jobAgentPubkey)) {\n continue;\n }\n }\n\n // NIP-90: one capability per job request - take the first non-elisym t tag\n const capability = req.tags.find((t) => t[0] === 't' && t[1] !== 'elisym')?.[1];\n const bid = req.tags.find((t) => t[0] === 'bid')?.[1];\n\n let status: JobStatus = 'processing';\n let amount: number | undefined;\n let txHash: string | undefined;\n\n if (result) {\n status = 'success';\n const amtTag = result.tags.find((t) => t[0] === 'amount');\n amount = safeParseInt(amtTag?.[1]);\n }\n\n // Check all feedbacks for tx hash\n const allFeedbacksForReq = feedbacksByRequestId.get(req.id) ?? [];\n for (const fb of allFeedbacksForReq) {\n const txTag = fb.tags.find((t) => t[0] === 'tx');\n if (txTag?.[1]) {\n txHash = txTag[1];\n break;\n }\n }\n\n if (feedback) {\n if (!result) {\n const statusTag = feedback.tags.find((t) => t[0] === 'status');\n if (statusTag?.[1]) {\n const isTargeted = targetedAgentByRequest.has(req.id);\n if (statusTag[1] === 'payment-required' && !bid && !isTargeted) {\n // Broadcast job without bid: a provider offered to work, but customer\n // hasn't committed. Keep \"processing\" because showing \"payment-required\"\n // would imply the customer chose this provider. The actual payment-required\n // transition happens via subscribeToJobUpdates() in real-time.\n } else {\n status = toJobStatus(statusTag[1]);\n }\n }\n }\n if (!amount) {\n const amtTag = feedback.tags.find((t) => t[0] === 'amount');\n amount = safeParseInt(amtTag?.[1]);\n }\n }\n\n jobs.push({\n eventId: req.id,\n customer: req.pubkey,\n agentPubkey: jobAgentPubkey,\n capability,\n bid: safeParseInt(bid),\n status,\n result: result?.content,\n resultEventId: result?.id,\n amount,\n txHash,\n createdAt: req.created_at,\n });\n }\n\n return jobs.sort((a, b) => b.createdAt - a.createdAt);\n }\n\n /** Subscribe to live elisym events (requests, results, feedback). */\n subscribeToEvents(kinds: number[], onEvent: (event: Event) => void): SubCloser {\n return this.pool.subscribe(\n {\n kinds,\n '#t': ['elisym'],\n since: Math.floor(Date.now() / 1000),\n } as Filter,\n (event) => {\n if (!verifyEvent(event)) {\n return;\n }\n onEvent(event);\n },\n );\n }\n}\n","/**\n * MediaService - NIP-98 authenticated file uploads to nostr.build.\n * Used for avatar, banner, and capability card images.\n */\nimport { finalizeEvent } from 'nostr-tools';\nimport type { ElisymIdentity } from '../primitives/identity';\n\nconst KIND_HTTP_AUTH = 27235;\nconst DEFAULT_UPLOAD_URL = 'https://nostr.build/api/v2/upload/files';\n\nexport class MediaService {\n constructor(private uploadUrl: string = DEFAULT_UPLOAD_URL) {}\n\n /**\n * Upload a file with NIP-98 authentication.\n * Works with browser File objects and Node.js/Bun Blobs.\n *\n * @param identity - Nostr identity used to sign the NIP-98 auth event.\n * @param file - File or Blob to upload.\n * @param filename - Optional filename for the upload (defaults to \"upload\").\n * @returns URL of the uploaded file.\n */\n async upload(identity: ElisymIdentity, file: Blob, filename?: string): Promise<string> {\n const hashBuffer = await crypto.subtle.digest('SHA-256', await file.arrayBuffer());\n const hashHex = [...new Uint8Array(hashBuffer)]\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n\n const authEvent = finalizeEvent(\n {\n kind: KIND_HTTP_AUTH,\n created_at: Math.floor(Date.now() / 1000),\n tags: [\n ['u', this.uploadUrl],\n ['method', 'POST'],\n ['payload', hashHex],\n ],\n content: '',\n },\n identity.secretKey,\n );\n\n const authHeader = 'Nostr ' + btoa(JSON.stringify(authEvent));\n\n const formData = new FormData();\n formData.append('file', file, filename ?? 'upload');\n\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), 30_000);\n try {\n const res = await fetch(this.uploadUrl, {\n method: 'POST',\n headers: { Authorization: authHeader },\n body: formData,\n signal: controller.signal,\n });\n\n if (!res.ok) {\n throw new Error(`Upload failed: ${res.status} ${res.statusText}`);\n }\n\n let data: { data?: { url?: string }[] };\n try {\n data = await res.json();\n } catch {\n throw new Error('Invalid response from upload service.');\n }\n const url = data?.data?.[0]?.url;\n if (!url) {\n throw new Error('No URL returned from upload service.');\n }\n return url;\n } finally {\n clearTimeout(timer);\n }\n }\n}\n","import { generateSecretKey, getPublicKey, nip19 } from 'nostr-tools';\n\nexport class ElisymIdentity {\n private _secretKey: Uint8Array;\n readonly publicKey: string;\n readonly npub: string;\n\n get secretKey(): Uint8Array {\n return new Uint8Array(this._secretKey);\n }\n\n private constructor(secretKey: Uint8Array) {\n this._secretKey = new Uint8Array(secretKey);\n this.publicKey = getPublicKey(secretKey);\n this.npub = nip19.npubEncode(this.publicKey);\n }\n\n static generate(): ElisymIdentity {\n return new ElisymIdentity(generateSecretKey());\n }\n\n static fromSecretKey(sk: Uint8Array): ElisymIdentity {\n if (sk.length !== 32) {\n throw new Error('Secret key must be exactly 32 bytes.');\n }\n return new ElisymIdentity(sk);\n }\n\n toJSON(): { publicKey: string; npub: string } {\n return { publicKey: this.publicKey, npub: this.npub };\n }\n\n /** Best-effort scrub of the secret key bytes in memory. */\n scrub(): void {\n this._secretKey.fill(0);\n }\n\n static fromHex(hex: string): ElisymIdentity {\n if (hex.length !== 64 || !/^[0-9a-fA-F]{64}$/.test(hex)) {\n throw new Error('Invalid secret key hex: expected 64 hex characters (32 bytes).');\n }\n const bytes = new Uint8Array(32);\n for (let i = 0; i < 64; i += 2) {\n bytes[i / 2] = parseInt(hex.substring(i, i + 2), 16);\n }\n return new ElisymIdentity(bytes);\n }\n}\n","import { finalizeEvent, verifyEvent } from 'nostr-tools';\nimport type { Filter } from 'nostr-tools';\nimport { KIND_PING, KIND_PONG, DEFAULTS } from '../constants';\nimport { ElisymIdentity } from '../primitives/identity';\nimport type { NostrPool } from '../transport/pool';\nimport type { PingResult, SubCloser } from '../types';\n\n/**\n * Ephemeral ping/pong service (kinds 20200/20201).\n *\n * Uses a session identity (random keypair) for ping operations to avoid\n * relay rate-limiting. The session identity persists for the lifetime of\n * this instance - recreating the service generates a new keypair.\n *\n * Requires `globalThis.crypto` (Node 20+, Bun, browsers).\n */\nexport class PingService {\n private static readonly PING_CACHE_MAX = 1000;\n private sessionIdentity: ElisymIdentity;\n private pingCache = new Map<string, number>(); // pubkey - timestamp of last online result\n private pendingPings = new Map<string, Promise<PingResult>>(); // dedup in-flight pings\n\n constructor(private pool: NostrPool) {\n this.sessionIdentity = ElisymIdentity.generate();\n }\n\n /**\n * Ping an agent via ephemeral Nostr events (kind 20200/20201).\n * Uses a persistent session identity to avoid relay rate-limiting.\n * Publishes to ALL relays for maximum delivery reliability.\n * Caches results for 30s to prevent redundant publishes.\n */\n async pingAgent(\n agentPubkey: string,\n timeoutMs: number = DEFAULTS.PING_TIMEOUT_MS,\n signal?: AbortSignal,\n retries: number = DEFAULTS.PING_RETRIES,\n ): Promise<PingResult> {\n // Return cached online result if fresh enough (avoids relay rate-limiting)\n const cachedAt = this.pingCache.get(agentPubkey);\n if (cachedAt) {\n if (Date.now() - cachedAt < DEFAULTS.PING_CACHE_TTL_MS) {\n return { online: true, identity: this.sessionIdentity };\n }\n this.pingCache.delete(agentPubkey); // evict stale entry\n }\n\n // Lazy sweep: evict stale entries when cache is over half full\n if (this.pingCache.size > PingService.PING_CACHE_MAX / 2) {\n const now = Date.now();\n for (const [key, ts] of this.pingCache) {\n if (now - ts >= DEFAULTS.PING_CACHE_TTL_MS) {\n this.pingCache.delete(key);\n }\n }\n }\n\n // Dedup: return existing in-flight ping for same agent (React Strict Mode sends two)\n const pending = this.pendingPings.get(agentPubkey);\n if (pending) {\n return pending;\n }\n\n // Guard against unbounded pending pings\n if (this.pendingPings.size >= PingService.PING_CACHE_MAX) {\n return { online: false, identity: null };\n }\n\n const promise = this._doPingWithRetry(agentPubkey, timeoutMs, retries, signal);\n this.pendingPings.set(agentPubkey, promise);\n promise.finally(() => this.pendingPings.delete(agentPubkey));\n return promise;\n }\n\n private async _doPingWithRetry(\n agentPubkey: string,\n timeoutMs: number,\n retries: number,\n signal?: AbortSignal,\n ): Promise<PingResult> {\n // Split total timeout evenly across attempts\n const attempts = retries + 1;\n const perAttemptTimeout = Math.floor(timeoutMs / attempts);\n\n for (let i = 0; i < attempts; i++) {\n if (signal?.aborted) {\n return { online: false, identity: null };\n }\n const result = await this._doPing(agentPubkey, perAttemptTimeout, signal);\n if (result.online) {\n return result;\n }\n }\n return { online: false, identity: null };\n }\n\n private async _doPing(\n agentPubkey: string,\n timeoutMs: number,\n signal?: AbortSignal,\n ): Promise<PingResult> {\n const sk = this.sessionIdentity.secretKey;\n const pk = this.sessionIdentity.publicKey;\n\n const nonce = crypto\n .getRandomValues(new Uint8Array(16))\n .reduce((s, b) => s + b.toString(16).padStart(2, '0'), '');\n\n if (signal?.aborted) {\n return { online: false, identity: null };\n }\n\n let resolved = false;\n let sub: SubCloser | undefined;\n let timer: ReturnType<typeof setTimeout> | undefined;\n let resolvePing!: (result: PingResult) => void;\n\n const promise = new Promise<PingResult>((resolve) => {\n resolvePing = resolve;\n });\n\n const done = (online: boolean) => {\n if (resolved) {\n return;\n }\n resolved = true;\n if (timer) {\n clearTimeout(timer);\n }\n sub?.close();\n signal?.removeEventListener('abort', onAbort);\n if (online) {\n // Re-insert to move key to the tail of the Map's insertion order.\n // keys().next() below evicts the oldest entry, so we need this entry\n // to count as the newest. A plain set() on an existing key preserves\n // position, so the delete is load-bearing - do not \"simplify\" it away.\n this.pingCache.delete(agentPubkey);\n this.pingCache.set(agentPubkey, Date.now());\n if (this.pingCache.size > PingService.PING_CACHE_MAX) {\n const oldest = this.pingCache.keys().next().value;\n if (oldest !== undefined) {\n this.pingCache.delete(oldest);\n }\n }\n }\n resolvePing({ online, identity: online ? this.sessionIdentity : null });\n };\n\n const onAbort = () => done(false);\n signal?.addEventListener('abort', onAbort);\n\n // Start timeout BEFORE subscribeAndWait so total time per attempt is bounded by timeoutMs\n timer = setTimeout(() => done(false), timeoutMs);\n\n // Subscribe and wait for relay confirmation before publishing (ephemeral events require active subscription)\n try {\n sub = await this.pool.subscribeAndWait({ kinds: [KIND_PONG], '#p': [pk] } as Filter, (ev) => {\n if (!verifyEvent(ev)) {\n return;\n }\n if (ev.pubkey !== agentPubkey) {\n return;\n }\n try {\n const msg = JSON.parse(ev.content);\n if (\n msg.type === 'elisym_pong' &&\n typeof msg.nonce === 'string' &&\n msg.nonce.length === 32 &&\n msg.nonce === nonce\n ) {\n done(true);\n }\n } catch {\n /* ignore */\n }\n });\n } catch {\n done(false);\n return promise;\n }\n\n // The timer may have fired while we were awaiting subscribeAndWait: in that\n // case done(false) already ran, but `sub` was still undefined when it called\n // sub?.close(), so the subscription we just received above would leak on the\n // relay pool. Close it explicitly here.\n if (resolved) {\n sub?.close();\n return promise;\n }\n\n // Publish ephemeral ping to ALL relays - subscription is confirmed active\n const pingEvent = finalizeEvent(\n {\n kind: KIND_PING,\n created_at: Math.floor(Date.now() / 1000),\n tags: [['p', agentPubkey]],\n content: JSON.stringify({ type: 'elisym_ping', nonce }),\n },\n sk,\n );\n this.pool.publishAll(pingEvent).catch(() => {\n done(false);\n });\n\n return promise;\n }\n\n /**\n * Subscribe to incoming ephemeral ping events (kind 20200).\n * No `since` filter needed - ephemeral events are never stored.\n */\n subscribeToPings(\n identity: ElisymIdentity,\n onPing: (senderPubkey: string, nonce: string) => void,\n ): SubCloser {\n return this.pool.subscribe(\n { kinds: [KIND_PING], '#p': [identity.publicKey] } as Filter,\n (ev) => {\n if (!verifyEvent(ev)) {\n return;\n }\n try {\n const msg = JSON.parse(ev.content);\n if (\n msg.type === 'elisym_ping' &&\n typeof msg.nonce === 'string' &&\n msg.nonce.length === 32\n ) {\n onPing(ev.pubkey, msg.nonce);\n }\n } catch {\n /* ignore */\n }\n },\n );\n }\n\n /** Send an ephemeral pong response to ALL relays. */\n async sendPong(identity: ElisymIdentity, recipientPubkey: string, nonce: string): Promise<void> {\n const pongEvent = finalizeEvent(\n {\n kind: KIND_PONG,\n created_at: Math.floor(Date.now() / 1000),\n tags: [['p', recipientPubkey]],\n content: JSON.stringify({ type: 'elisym_pong', nonce }),\n },\n identity.secretKey,\n );\n await this.pool.publishAll(pongEvent);\n }\n}\n","/** A Set that evicts the oldest entries when it exceeds maxSize. Uses a ring buffer for O(1) eviction. */\nexport class BoundedSet<T> {\n private items: (T | undefined)[];\n private set = new Set<T>();\n private head = 0;\n private count = 0;\n constructor(private maxSize: number) {\n if (maxSize <= 0) {\n throw new Error('BoundedSet maxSize must be positive.');\n }\n this.items = new Array(maxSize);\n }\n has(item: T): boolean {\n return this.set.has(item);\n }\n add(item: T): void {\n if (this.set.has(item)) {\n return;\n }\n if (this.count >= this.maxSize) {\n const evicted = this.items[this.head]!;\n this.set.delete(evicted);\n } else {\n this.count++;\n }\n this.items[this.head] = item;\n this.head = (this.head + 1) % this.maxSize;\n this.set.add(item);\n }\n}\n","import { SimplePool, type Filter, type Event } from 'nostr-tools';\nimport { RELAYS, DEFAULTS } from '../constants';\nimport { BoundedSet } from '../primitives/bounded-set';\nimport type { SubCloser } from '../types';\n\nexport class NostrPool {\n private pool: SimplePool;\n private relays: string[];\n private activeSubscriptions = new Set<SubCloser>();\n\n constructor(relays: string[] = RELAYS) {\n this.pool = new SimplePool();\n this.relays = relays;\n }\n\n /** Query relays synchronously. Returns `[]` on timeout (no error thrown). */\n async querySync(filter: Filter): Promise<Event[]> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const query = this.pool.querySync(this.relays, filter);\n query.catch(() => {}); // prevent unhandled rejection if timeout wins\n try {\n const result = await Promise.race([\n query,\n new Promise<Event[]>((resolve) => {\n timer = setTimeout(() => resolve([]), DEFAULTS.QUERY_TIMEOUT_MS);\n }),\n ]);\n return result;\n } finally {\n clearTimeout(timer);\n }\n }\n\n async queryBatched(\n filter: Omit<Filter, 'authors'>,\n keys: string[],\n batchSize: number = DEFAULTS.BATCH_SIZE,\n maxConcurrency: number = DEFAULTS.QUERY_MAX_CONCURRENCY,\n ): Promise<Event[]> {\n const batchKeys: string[][] = [];\n for (let i = 0; i < keys.length; i += batchSize) {\n batchKeys.push(keys.slice(i, i + batchSize));\n }\n\n const results: Event[] = [];\n for (let c = 0; c < batchKeys.length; c += maxConcurrency) {\n const chunk = batchKeys.slice(c, c + maxConcurrency);\n const chunkResults = await Promise.all(\n chunk.map((batch) => {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const query = this.pool.querySync(this.relays, {\n ...filter,\n authors: batch,\n } as Filter);\n query.catch(() => {}); // prevent unhandled rejection if timeout wins\n return (async () => {\n try {\n return await Promise.race([\n query,\n new Promise<Event[]>((resolve) => {\n timer = setTimeout(() => resolve([]), DEFAULTS.QUERY_TIMEOUT_MS);\n }),\n ]);\n } finally {\n clearTimeout(timer);\n }\n })();\n }),\n );\n results.push(...chunkResults.flat());\n }\n return results;\n }\n\n async queryBatchedByTag(\n filter: Filter,\n tagName: string,\n values: string[],\n batchSize: number = DEFAULTS.BATCH_SIZE,\n maxConcurrency: number = DEFAULTS.QUERY_MAX_CONCURRENCY,\n ): Promise<Event[]> {\n const batchValues: string[][] = [];\n for (let i = 0; i < values.length; i += batchSize) {\n batchValues.push(values.slice(i, i + batchSize));\n }\n\n const results: Event[] = [];\n for (let c = 0; c < batchValues.length; c += maxConcurrency) {\n const chunk = batchValues.slice(c, c + maxConcurrency);\n const chunkResults = await Promise.all(\n chunk.map((batch) => {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const query = this.pool.querySync(this.relays, {\n ...filter,\n [`#${tagName}`]: batch,\n } as Filter);\n query.catch(() => {}); // prevent unhandled rejection if timeout wins\n return (async () => {\n try {\n return await Promise.race([\n query,\n new Promise<Event[]>((resolve) => {\n timer = setTimeout(() => resolve([]), DEFAULTS.QUERY_TIMEOUT_MS);\n }),\n ]);\n } finally {\n clearTimeout(timer);\n }\n })();\n }),\n );\n results.push(...chunkResults.flat());\n }\n return results;\n }\n\n async publish(event: Event): Promise<void> {\n try {\n await Promise.any(this.pool.publish(this.relays, event));\n } catch (err) {\n if (err instanceof AggregateError) {\n throw new Error(\n `Failed to publish to all ${this.relays.length} relays: ${err.errors.map((e: unknown) => (e instanceof Error ? e.message : String(e))).join(', ')}`,\n );\n }\n throw err;\n }\n }\n\n /** Publish to all relays and wait for all to settle. Throws if none accepted. */\n async publishAll(event: Event): Promise<void> {\n const results = await Promise.allSettled(this.pool.publish(this.relays, event));\n const anyOk = results.some((r) => r.status === 'fulfilled');\n if (!anyOk) {\n throw new Error(`Failed to publish to all ${this.relays.length} relays`);\n }\n }\n\n subscribe(filter: Filter, onEvent: (event: Event) => void): SubCloser {\n const rawSub = this.pool.subscribeMany(this.relays, filter, { onevent: onEvent });\n const tracked: SubCloser = {\n close: (reason?: string) => {\n this.activeSubscriptions.delete(tracked);\n rawSub.close(reason);\n },\n };\n this.activeSubscriptions.add(tracked);\n return tracked;\n }\n\n /**\n * Subscribe and wait until at least one relay confirms the subscription\n * is active (EOSE). Resolves on the first relay that responds.\n * Essential for ephemeral events where the subscription must be live\n * before publishing.\n *\n * Note: resolves on timeout even if no relay sent EOSE. The caller\n * cannot distinguish timeout from success - this is intentional for\n * best-effort ephemeral event delivery.\n */\n subscribeAndWait(\n filter: Filter,\n onEvent: (event: Event) => void,\n timeoutMs: number = DEFAULTS.EOSE_TIMEOUT_MS,\n ): Promise<SubCloser> {\n return new Promise((resolve) => {\n let resolved = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n const subs: SubCloser[] = [];\n const combinedSub: SubCloser = {\n close: (reason?: string) => {\n this.activeSubscriptions.delete(combinedSub);\n for (const s of subs) {\n s.close(reason);\n }\n },\n };\n this.activeSubscriptions.add(combinedSub);\n\n const done = () => {\n if (resolved) {\n return;\n }\n resolved = true;\n if (timer) {\n clearTimeout(timer);\n }\n resolve(combinedSub);\n };\n\n // Subscribe to each relay individually so we can resolve\n // as soon as the first relay sends EOSE (not waiting for all).\n // Dedup events by id since per-relay subscriptions bypass SimplePool dedup.\n const seen = new BoundedSet<string>(10_000);\n const dedupedOnEvent = (ev: Event) => {\n if (seen.has(ev.id)) {\n return;\n }\n seen.add(ev.id);\n onEvent(ev);\n };\n\n for (const relay of this.relays) {\n try {\n const sub = this.pool.subscribeMany([relay], filter, {\n onevent: dedupedOnEvent,\n oneose: done,\n });\n subs.push(sub);\n } catch {\n /* skip failed relay - handled by subs.length === 0 check below */\n }\n }\n\n // If all relays failed, resolve immediately\n if (subs.length === 0) {\n done();\n return;\n }\n\n if (!resolved) {\n timer = setTimeout(done, timeoutMs);\n }\n });\n }\n\n /**\n * Tear down pool and create a fresh one.\n * Works around nostr-tools `onerror - skipReconnection = true` bug\n * that permanently kills subscriptions. Callers must re-subscribe.\n */\n reset(): void {\n for (const sub of this.activeSubscriptions) {\n sub.close('pool reset');\n }\n this.activeSubscriptions.clear();\n try {\n this.pool.close(this.relays);\n } catch {\n /* ignore */\n }\n this.pool = new SimplePool();\n }\n\n /**\n * Lightweight connectivity probe. Returns true if at least one relay responds.\n */\n async probe(timeoutMs: number = DEFAULTS.EOSE_TIMEOUT_MS): Promise<boolean> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const query = this.pool.querySync(this.relays, { kinds: [0], limit: 1 } as Filter);\n query.catch(() => {}); // prevent unhandled rejection if timeout wins\n try {\n await Promise.race([\n query,\n new Promise<never>((_, reject) => {\n timer = setTimeout(() => reject(new Error('probe timeout')), timeoutMs);\n }),\n ]);\n return true;\n } catch {\n return false;\n } finally {\n clearTimeout(timer);\n }\n }\n\n getRelays(): string[] {\n return this.relays;\n }\n\n close(): void {\n for (const sub of this.activeSubscriptions) {\n sub.close('pool closed');\n }\n this.activeSubscriptions.clear();\n try {\n this.pool.close(this.relays);\n } catch {\n /* ignore - already disconnected */\n }\n }\n}\n","import { RELAYS } from './constants';\nimport { SolanaPaymentStrategy } from './payment/solana';\nimport type { PaymentStrategy } from './payment/strategy';\nimport { DiscoveryService } from './services/discovery';\nimport { MarketplaceService } from './services/marketplace';\nimport { MediaService } from './services/media';\nimport { PingService } from './services/ping';\nimport { NostrPool } from './transport/pool';\nimport type { ElisymClientConfig } from './types';\n\nexport interface ElisymClientFullConfig extends ElisymClientConfig {\n payment?: PaymentStrategy;\n /** Custom upload URL for file uploads (defaults to nostr.build). */\n uploadUrl?: string;\n}\n\nexport class ElisymClient {\n readonly pool: NostrPool;\n readonly discovery: DiscoveryService;\n readonly marketplace: MarketplaceService;\n readonly ping: PingService;\n readonly media: MediaService;\n readonly payment: PaymentStrategy;\n\n constructor(config: ElisymClientFullConfig = {}) {\n this.pool = new NostrPool(config.relays ?? RELAYS);\n this.discovery = new DiscoveryService(this.pool);\n this.marketplace = new MarketplaceService(this.pool);\n this.ping = new PingService(this.pool);\n this.media = new MediaService(config.uploadUrl);\n this.payment = config.payment ?? new SolanaPaymentStrategy();\n }\n\n close(): void {\n this.pool.close();\n }\n}\n","import Decimal from 'decimal.js-light';\nimport { LAMPORTS_PER_SOL } from '../constants';\n\nexport function formatSol(lamports: number): string {\n const sol = new Decimal(lamports).div(LAMPORTS_PER_SOL);\n if (sol.gte(1_000_000)) {\n return `${sol.idiv(1_000_000)}m SOL`;\n }\n if (sol.gte(10_000)) {\n return `${sol.idiv(1_000)}k SOL`;\n }\n return `${compactSol(sol)} SOL`;\n}\n\n/** Format a SOL Decimal - show enough decimals so the value isn't lost. */\nfunction compactSol(sol: Decimal): string {\n if (sol.isZero()) {\n return '0';\n }\n if (sol.gte(1000)) {\n return sol.toDecimalPlaces(0, Decimal.ROUND_FLOOR).toString();\n }\n // Show enough decimals so the rounded value equals the original\n const maxFrac = 9; // lamport precision\n for (let d = 1; d <= maxFrac; d++) {\n const s = sol.toFixed(d);\n if (new Decimal(s).eq(sol)) {\n return s.replace(/0+$/, '').replace(/\\.$/, '');\n }\n }\n return sol.toFixed(maxFrac).replace(/0+$/, '').replace(/\\.$/, '');\n}\n\nexport function timeAgo(unix: number): string {\n const seconds = Math.max(0, Math.floor(Date.now() / 1000 - unix));\n if (seconds < 60) {\n return `${seconds}s ago`;\n }\n const minutes = Math.floor(seconds / 60);\n if (minutes < 60) {\n return `${minutes}m ago`;\n }\n const hours = Math.floor(minutes / 60);\n if (hours < 24) {\n return `${hours}h ago`;\n }\n const days = Math.floor(hours / 24);\n return `${days}d ago`;\n}\n\nexport function truncateKey(hex: string, chars = 6): string {\n if (hex.length <= chars * 2) {\n return hex;\n }\n return `${hex.slice(0, chars)}...${hex.slice(-chars)}`;\n}\n","/**\n * Shared agent config - validation and serialization.\n * Browser-safe - no Node.js imports.\n * parseConfig lives in config-node.ts (exported from @elisym/sdk/node).\n */\n\nimport { LIMITS } from '../constants';\nimport type { AgentConfig } from '../types';\n\nexport function validateAgentName(name: string): void {\n if (!name || name.length > LIMITS.MAX_AGENT_NAME_LENGTH || !/^[a-zA-Z0-9_-]+$/.test(name)) {\n throw new Error('Agent name must be 1-64 characters, alphanumeric, underscore, or hyphen.');\n }\n}\n\n/** Serialize an AgentConfig to JSON string. */\nexport function serializeConfig(config: AgentConfig): string {\n return JSON.stringify(config, null, 2) + '\\n';\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/constants.ts","../../config-client/src/generated/accounts/config.ts","../../config-client/src/generated/errors/elisymConfig.ts","../../config-client/src/helpers.ts","../src/config/onchain.ts","../src/payment/fee.ts","../src/payment/solana.ts","../src/services/discovery.ts","../src/primitives/crypto.ts","../src/services/marketplace.ts","../src/services/media.ts","../src/primitives/identity.ts","../src/services/ping.ts","../src/primitives/bounded-set.ts","../src/transport/pool.ts","../src/client.ts","../src/primitives/format.ts","../src/primitives/config.ts"],"names":["getStructDecoder","fixDecoderSize","getBytesDecoder","getU8Decoder","getAddressDecoder","getOptionDecoder","getU16Decoder","getBooleanDecoder","getI64Decoder","decodeAccount","address","assertAccountExists","fetchEncodedAccount","getProgramDerivedAddress","Decimal","isAddress","pipe","createTransactionMessage","setTransactionMessageFeePayerSigner","setTransactionMessageLifetimeUsingBlockhash","appendTransactionMessageInstructions","signTransactionMessageWithSigners","getTransferSolInstruction","AccountRole","verifyEvent","nip19","finalizeEvent","nip44","getPublicKey","generateSecretKey","SimplePool"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { Address } from '@solana/kit';\n\nexport 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;\n\n/** Default job request kind (5000 + 100). */\nexport const KIND_JOB_REQUEST = KIND_JOB_REQUEST_BASE + DEFAULT_KIND_OFFSET;\n/** Default job result kind (6000 + 100). */\nexport const KIND_JOB_RESULT = KIND_JOB_RESULT_BASE + DEFAULT_KIND_OFFSET;\n\n/** Compute a job request kind from an offset (5000 + offset). */\nexport function jobRequestKind(offset: number): number {\n if (!Number.isInteger(offset) || offset < 0 || offset >= 1000) {\n throw new Error(`Invalid kind offset: ${offset}. Must be integer 0-999.`);\n }\n return KIND_JOB_REQUEST_BASE + offset;\n}\n\n/** Compute a job result kind from an offset (6000 + offset). */\nexport function jobResultKind(offset: number): number {\n if (!Number.isInteger(offset) || offset < 0 || offset >= 1000) {\n throw new Error(`Invalid kind offset: ${offset}. Must be integer 0-999.`);\n }\n return KIND_JOB_RESULT_BASE + offset;\n}\n\n/** Ephemeral ping/pong kinds (not stored by relays, forwarded in real-time). */\nexport const KIND_PING = 20200;\nexport const KIND_PONG = 20201;\n\nexport const LAMPORTS_PER_SOL = 1_000_000_000;\n\n/**\n * @deprecated Fallback only - use `getProtocolConfig(rpc, programId)` for live values.\n *\n * Protocol fee in basis points (300 = 3%). Bundled as a default for offline use\n * and for first-call before the on-chain config has been fetched. The on-chain\n * `elisym-config` program is the source of truth.\n */\nexport const PROTOCOL_FEE_BPS = 300;\n/**\n * @deprecated Fallback only - use `getProtocolConfig(rpc, programId)` for live values.\n *\n * Solana address of the protocol treasury. Bundled fallback; the on-chain\n * `elisym-config` program is the source of truth and may rotate this address.\n */\nexport const PROTOCOL_TREASURY = 'GY7vnWMkKpftU4nQ16C2ATkj1JwrQpHhknkaBUn67VTy' as Address;\n\n/**\n * Solana program ID for the elisym protocol config (devnet deployment).\n *\n * The Anchor program at this address is the source of truth for fee bps,\n * treasury address, and admin rotation state. Read via `getProtocolConfig`.\n */\nexport const PROTOCOL_PROGRAM_ID_DEVNET = 'BrX1CRkSgvcjxBvc2bgc3QqgWjinusofDmeP7ZVxvwrE' as Address;\n\nexport type ProtocolCluster = 'devnet' | 'mainnet' | 'localnet';\n\n/**\n * Resolve the elisym-config program ID for a given Solana cluster.\n * Mainnet is intentionally unsupported until the program ships there.\n */\nexport function getProtocolProgramId(cluster: ProtocolCluster): Address {\n switch (cluster) {\n case 'devnet':\n case 'localnet':\n return PROTOCOL_PROGRAM_ID_DEVNET;\n case 'mainnet':\n throw new Error('Protocol program is not deployed on mainnet yet');\n }\n}\n\n/** Default values for timeouts, retries, and batch sizes. */\nexport const DEFAULTS = {\n SUBSCRIPTION_TIMEOUT_MS: 120_000,\n PING_TIMEOUT_MS: 15_000,\n PING_RETRIES: 2,\n PING_CACHE_TTL_MS: 30_000,\n PAYMENT_EXPIRY_SECS: 600,\n BATCH_SIZE: 250,\n QUERY_TIMEOUT_MS: 15_000,\n EOSE_TIMEOUT_MS: 3_000,\n VERIFY_RETRIES: 10,\n VERIFY_INTERVAL_MS: 3_000,\n VERIFY_BY_REF_RETRIES: 15,\n VERIFY_BY_REF_INTERVAL_MS: 2_000,\n RESULT_RETRY_COUNT: 3,\n RESULT_RETRY_BASE_MS: 1_000,\n QUERY_MAX_CONCURRENCY: 6,\n VERIFY_SIGNATURE_LIMIT: 25,\n} as const;\n\n/** Protocol limits for input validation. */\nexport const LIMITS = {\n MAX_INPUT_LENGTH: 100_000,\n MAX_TIMEOUT_SECS: 600,\n MAX_CAPABILITIES: 20,\n MAX_DESCRIPTION_LENGTH: 500,\n MAX_AGENT_NAME_LENGTH: 64,\n MAX_CAPABILITY_LENGTH: 64,\n} as const;\n","/**\n * This code was AUTOGENERATED using the codama library.\n * Please DO NOT EDIT THIS FILE, instead use visitors\n * to add features, then rerun codama to update it.\n *\n * @see https://github.com/codama-idl/codama\n */\n\nimport {\n assertAccountExists,\n assertAccountsExist,\n combineCodec,\n decodeAccount,\n fetchEncodedAccount,\n fetchEncodedAccounts,\n fixDecoderSize,\n fixEncoderSize,\n getAddressDecoder,\n getAddressEncoder,\n getBooleanDecoder,\n getBooleanEncoder,\n getBytesDecoder,\n getBytesEncoder,\n getI64Decoder,\n getI64Encoder,\n getOptionDecoder,\n getOptionEncoder,\n getStructDecoder,\n getStructEncoder,\n getU16Decoder,\n getU16Encoder,\n getU8Decoder,\n getU8Encoder,\n transformEncoder,\n type Account,\n type Address,\n type Codec,\n type Decoder,\n type EncodedAccount,\n type Encoder,\n type FetchAccountConfig,\n type FetchAccountsConfig,\n type MaybeAccount,\n type MaybeEncodedAccount,\n type Option,\n type OptionOrNullable,\n type ReadonlyUint8Array,\n} from '@solana/kit';\n\nexport const CONFIG_DISCRIMINATOR = new Uint8Array([\n 155, 12, 170, 224, 30, 250, 204, 130,\n]);\n\nexport function getConfigDiscriminatorBytes() {\n return fixEncoderSize(getBytesEncoder(), 8).encode(CONFIG_DISCRIMINATOR);\n}\n\nexport type Config = {\n discriminator: ReadonlyUint8Array;\n version: number;\n bump: number;\n admin: Address;\n pendingAdmin: Option<Address>;\n treasury: Address;\n feeBps: number;\n paused: boolean;\n lastUpdated: bigint;\n reserved: ReadonlyUint8Array;\n};\n\nexport type ConfigArgs = {\n version: number;\n bump: number;\n admin: Address;\n pendingAdmin: OptionOrNullable<Address>;\n treasury: Address;\n feeBps: number;\n paused: boolean;\n lastUpdated: number | bigint;\n reserved: ReadonlyUint8Array;\n};\n\nexport function getConfigEncoder(): Encoder<ConfigArgs> {\n return transformEncoder(\n getStructEncoder([\n ['discriminator', fixEncoderSize(getBytesEncoder(), 8)],\n ['version', getU8Encoder()],\n ['bump', getU8Encoder()],\n ['admin', getAddressEncoder()],\n ['pendingAdmin', getOptionEncoder(getAddressEncoder())],\n ['treasury', getAddressEncoder()],\n ['feeBps', getU16Encoder()],\n ['paused', getBooleanEncoder()],\n ['lastUpdated', getI64Encoder()],\n ['reserved', fixEncoderSize(getBytesEncoder(), 128)],\n ]),\n (value) => ({ ...value, discriminator: CONFIG_DISCRIMINATOR })\n );\n}\n\nexport function getConfigDecoder(): Decoder<Config> {\n return getStructDecoder([\n ['discriminator', fixDecoderSize(getBytesDecoder(), 8)],\n ['version', getU8Decoder()],\n ['bump', getU8Decoder()],\n ['admin', getAddressDecoder()],\n ['pendingAdmin', getOptionDecoder(getAddressDecoder())],\n ['treasury', getAddressDecoder()],\n ['feeBps', getU16Decoder()],\n ['paused', getBooleanDecoder()],\n ['lastUpdated', getI64Decoder()],\n ['reserved', fixDecoderSize(getBytesDecoder(), 128)],\n ]);\n}\n\nexport function getConfigCodec(): Codec<ConfigArgs, Config> {\n return combineCodec(getConfigEncoder(), getConfigDecoder());\n}\n\nexport function decodeConfig<TAddress extends string = string>(\n encodedAccount: EncodedAccount<TAddress>\n): Account<Config, TAddress>;\nexport function decodeConfig<TAddress extends string = string>(\n encodedAccount: MaybeEncodedAccount<TAddress>\n): MaybeAccount<Config, TAddress>;\nexport function decodeConfig<TAddress extends string = string>(\n encodedAccount: EncodedAccount<TAddress> | MaybeEncodedAccount<TAddress>\n): Account<Config, TAddress> | MaybeAccount<Config, TAddress> {\n return decodeAccount(\n encodedAccount as MaybeEncodedAccount<TAddress>,\n getConfigDecoder()\n );\n}\n\nexport async function fetchConfig<TAddress extends string = string>(\n rpc: Parameters<typeof fetchEncodedAccount>[0],\n address: Address<TAddress>,\n config?: FetchAccountConfig\n): Promise<Account<Config, TAddress>> {\n const maybeAccount = await fetchMaybeConfig(rpc, address, config);\n assertAccountExists(maybeAccount);\n return maybeAccount;\n}\n\nexport async function fetchMaybeConfig<TAddress extends string = string>(\n rpc: Parameters<typeof fetchEncodedAccount>[0],\n address: Address<TAddress>,\n config?: FetchAccountConfig\n): Promise<MaybeAccount<Config, TAddress>> {\n const maybeAccount = await fetchEncodedAccount(rpc, address, config);\n return decodeConfig(maybeAccount);\n}\n\nexport async function fetchAllConfig(\n rpc: Parameters<typeof fetchEncodedAccounts>[0],\n addresses: Array<Address>,\n config?: FetchAccountsConfig\n): Promise<Account<Config>[]> {\n const maybeAccounts = await fetchAllMaybeConfig(rpc, addresses, config);\n assertAccountsExist(maybeAccounts);\n return maybeAccounts;\n}\n\nexport async function fetchAllMaybeConfig(\n rpc: Parameters<typeof fetchEncodedAccounts>[0],\n addresses: Array<Address>,\n config?: FetchAccountsConfig\n): Promise<MaybeAccount<Config>[]> {\n const maybeAccounts = await fetchEncodedAccounts(rpc, addresses, config);\n return maybeAccounts.map((maybeAccount) => decodeConfig(maybeAccount));\n}\n","/**\n * This code was AUTOGENERATED using the codama library.\n * Please DO NOT EDIT THIS FILE, instead use visitors\n * to add features, then rerun codama to update it.\n *\n * @see https://github.com/codama-idl/codama\n */\n\nimport {\n isProgramError,\n type Address,\n type SOLANA_ERROR__INSTRUCTION_ERROR__CUSTOM,\n type SolanaError,\n} from '@solana/kit';\nimport { ELISYM_CONFIG_PROGRAM_ADDRESS } from '../programs';\n\n/** Unauthorized: Unauthorized */\nexport const ELISYM_CONFIG_ERROR__UNAUTHORIZED = 0x1770; // 6000\n/** FeeTooHigh: Fee exceeds protocol maximum */\nexport const ELISYM_CONFIG_ERROR__FEE_TOO_HIGH = 0x1771; // 6001\n/** InvalidTreasury: Treasury address cannot be default */\nexport const ELISYM_CONFIG_ERROR__INVALID_TREASURY = 0x1772; // 6002\n/** InvalidAdmin: Admin address cannot be default */\nexport const ELISYM_CONFIG_ERROR__INVALID_ADMIN = 0x1773; // 6003\n/** NoPendingAdmin: No pending admin transfer */\nexport const ELISYM_CONFIG_ERROR__NO_PENDING_ADMIN = 0x1774; // 6004\n/** PendingAdminAlreadySet: Pending admin already set */\nexport const ELISYM_CONFIG_ERROR__PENDING_ADMIN_ALREADY_SET = 0x1775; // 6005\n/** UnsupportedVersion: Unsupported config version */\nexport const ELISYM_CONFIG_ERROR__UNSUPPORTED_VERSION = 0x1776; // 6006\n\nexport type ElisymConfigError =\n | typeof ELISYM_CONFIG_ERROR__FEE_TOO_HIGH\n | typeof ELISYM_CONFIG_ERROR__INVALID_ADMIN\n | typeof ELISYM_CONFIG_ERROR__INVALID_TREASURY\n | typeof ELISYM_CONFIG_ERROR__NO_PENDING_ADMIN\n | typeof ELISYM_CONFIG_ERROR__PENDING_ADMIN_ALREADY_SET\n | typeof ELISYM_CONFIG_ERROR__UNAUTHORIZED\n | typeof ELISYM_CONFIG_ERROR__UNSUPPORTED_VERSION;\n\nlet elisymConfigErrorMessages: Record<ElisymConfigError, string> | undefined;\nif (process.env.NODE_ENV !== 'production') {\n elisymConfigErrorMessages = {\n [ELISYM_CONFIG_ERROR__FEE_TOO_HIGH]: `Fee exceeds protocol maximum`,\n [ELISYM_CONFIG_ERROR__INVALID_ADMIN]: `Admin address cannot be default`,\n [ELISYM_CONFIG_ERROR__INVALID_TREASURY]: `Treasury address cannot be default`,\n [ELISYM_CONFIG_ERROR__NO_PENDING_ADMIN]: `No pending admin transfer`,\n [ELISYM_CONFIG_ERROR__PENDING_ADMIN_ALREADY_SET]: `Pending admin already set`,\n [ELISYM_CONFIG_ERROR__UNAUTHORIZED]: `Unauthorized`,\n [ELISYM_CONFIG_ERROR__UNSUPPORTED_VERSION]: `Unsupported config version`,\n };\n}\n\nexport function getElisymConfigErrorMessage(code: ElisymConfigError): string {\n if (process.env.NODE_ENV !== 'production') {\n return (elisymConfigErrorMessages as Record<ElisymConfigError, string>)[\n code\n ];\n }\n\n return 'Error message not available in production bundles.';\n}\n\nexport function isElisymConfigError<\n TProgramErrorCode extends ElisymConfigError,\n>(\n error: unknown,\n transactionMessage: {\n instructions: Record<number, { programAddress: Address }>;\n },\n code?: TProgramErrorCode\n): error is SolanaError<typeof SOLANA_ERROR__INSTRUCTION_ERROR__CUSTOM> &\n Readonly<{ context: Readonly<{ code: TProgramErrorCode }> }> {\n return isProgramError<TProgramErrorCode>(\n error,\n transactionMessage,\n ELISYM_CONFIG_PROGRAM_ADDRESS,\n code\n );\n}\n","import { type Address, getProgramDerivedAddress } from '@solana/kit';\n\nexport const CONFIG_SEED = 'config';\n\nexport const MAX_FEE_BPS = 1000;\n\nexport async function deriveConfigAddress(programId: Address): Promise<Address> {\n const [pda] = await getProgramDerivedAddress({\n programAddress: programId,\n seeds: [new TextEncoder().encode(CONFIG_SEED)],\n });\n return pda;\n}\n","import { deriveConfigAddress, fetchConfig } from '@elisym/config-client';\nimport type { Address, Rpc, SolanaRpcApi } from '@solana/kit';\n\nconst CACHE_TTL_MS = 60_000;\n\n/**\n * Snapshot of the on-chain elisym-config program state.\n *\n * `source` reflects how this snapshot was obtained:\n * - `onchain`: fresh fetch via RPC.\n * - `cache`: served from in-memory cache (still within TTL or stale-while-error).\n *\n * If RPC fails and no cached value exists, `getProtocolConfig` throws instead of\n * returning stale hardcoded defaults - callers must handle the error explicitly.\n */\nexport interface ProtocolConfig {\n programId: Address;\n feeBps: number;\n treasury: Address;\n admin: Address;\n pendingAdmin: Address | null;\n paused: boolean;\n version: number;\n source: 'onchain' | 'cache';\n}\n\ninterface CacheEntry {\n config: ProtocolConfig;\n expires: number;\n}\n\nconst cache = new Map<string, CacheEntry>();\n\nexport function clearProtocolConfigCache(): void {\n cache.clear();\n}\n\nexport interface GetProtocolConfigOptions {\n ttlMs?: number;\n forceRefresh?: boolean;\n}\n\n/**\n * Fetch the protocol config from the on-chain `elisym-config` program.\n *\n * Caches per-program-id with a TTL (default 60s). On RPC error, returns the\n * last known good snapshot from cache. If nothing is cached, throws - callers\n * must handle the error (e.g. refuse the payment, show a warning).\n */\nexport async function getProtocolConfig(\n rpc: Rpc<SolanaRpcApi>,\n programId: Address,\n options?: GetProtocolConfigOptions,\n): Promise<ProtocolConfig> {\n const key = programId.toString();\n const ttl = options?.ttlMs ?? CACHE_TTL_MS;\n const cached = cache.get(key);\n if (!options?.forceRefresh && cached && Date.now() < cached.expires) {\n return { ...cached.config, source: 'cache' };\n }\n\n try {\n const configPda = await deriveConfigAddress(programId);\n const account = await fetchConfig(rpc, configPda);\n const data = account.data;\n const config: ProtocolConfig = {\n programId,\n feeBps: data.feeBps,\n treasury: data.treasury,\n admin: data.admin,\n pendingAdmin: data.pendingAdmin.__option === 'Some' ? data.pendingAdmin.value : null,\n paused: data.paused,\n version: data.version,\n source: 'onchain',\n };\n cache.set(key, { config, expires: Date.now() + ttl });\n return config;\n } catch (error) {\n if (cached) {\n return { ...cached.config, source: 'cache' };\n }\n throw new Error(\n `Failed to fetch protocol config from on-chain program ${programId} and no cached value exists. ` +\n `Ensure RPC is reachable and the program is initialized. ` +\n `Cause: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n}\n","import Decimal from 'decimal.js-light';\n\nconst BPS_DENOMINATOR = 10_000;\n\n/** Assert that a value is a non-negative integer (lamports). */\nexport function assertLamports(value: number, field: string): void {\n if (!Number.isInteger(value) || value < 0) {\n throw new Error(`Invalid ${field}: ${value}. Must be a non-negative integer.`);\n }\n}\n\n/**\n * Calculate the protocol fee using basis-point math (no floats).\n * Returns ceil(amount * feeBps / 10000).\n *\n * The caller passes the current fee (in basis points). Phase 2 of the\n * Solana Kit migration removes the implicit dependency on PROTOCOL_FEE_BPS\n * so callers can supply on-chain or test values.\n */\nexport function calculateProtocolFee(amount: number, feeBps: number): number {\n if (!Number.isInteger(feeBps) || feeBps < 0) {\n throw new Error(`Invalid feeBps: ${feeBps}. Must be a non-negative integer.`);\n }\n if (!Number.isInteger(amount) || amount < 0) {\n throw new Error(`Invalid fee amount: ${amount}. Must be a non-negative integer.`);\n }\n if (amount === 0 || feeBps === 0) {\n return 0;\n }\n return new Decimal(amount)\n .mul(feeBps)\n .div(BPS_DENOMINATOR)\n .toDecimalPlaces(0, Decimal.ROUND_CEIL)\n .toNumber();\n}\n\n/** Validate payment request timestamps. Returns error message or null if valid. */\nexport function validateExpiry(createdAt: number, expirySecs: number): string | null {\n if (!Number.isInteger(createdAt) || createdAt <= 0) {\n return 'Invalid or missing created_at in payment request.';\n }\n if (!Number.isInteger(expirySecs) || expirySecs <= 0) {\n return 'Invalid or missing expiry_secs in payment request.';\n }\n const now = Math.floor(Date.now() / 1000);\n if (createdAt > now + 120) {\n return `Payment request created_at is in the future (${createdAt} vs now ${now}). Possible manipulation.`;\n }\n if (now - createdAt > expirySecs) {\n return `Payment request expired (created ${createdAt}, expiry ${expirySecs}s).`;\n }\n return null;\n}\n\n/** Assert that payment request timestamps are valid and not expired. Throws on failure. */\nexport function assertExpiry(createdAt: number, expirySecs: number): void {\n const error = validateExpiry(createdAt, expirySecs);\n if (error) {\n throw new Error(error);\n }\n}\n","import { getTransferSolInstruction } from '@solana-program/system';\nimport {\n type Address,\n type Rpc,\n type Signature,\n type SolanaRpcApi,\n type TransactionSigner,\n AccountRole,\n address,\n appendTransactionMessageInstructions,\n createTransactionMessage,\n getAddressDecoder,\n isAddress,\n pipe,\n setTransactionMessageFeePayerSigner,\n setTransactionMessageLifetimeUsingBlockhash,\n signTransactionMessageWithSigners,\n} from '@solana/kit';\nimport { getProtocolConfig } from '../config/onchain';\nimport { DEFAULTS, LIMITS } from '../constants';\nimport type {\n PaymentRequestData,\n PaymentValidationError,\n VerifyOptions,\n VerifyResult,\n} from '../types';\nimport { assertExpiry, assertLamports, calculateProtocolFee, validateExpiry } from './fee';\nimport type { PaymentStrategy, ProtocolConfigInput } from './strategy';\n\nconst REFERENCE_BYTE_LENGTH = 32;\n\nfunction isValidSolanaAddress(value: string): boolean {\n return isAddress(value);\n}\n\nfunction generateReference(): string {\n const bytes = new Uint8Array(REFERENCE_BYTE_LENGTH);\n globalThis.crypto.getRandomValues(bytes);\n return getAddressDecoder().decode(bytes);\n}\n\nfunction assertReference(reference: string): void {\n if (!isValidSolanaAddress(reference)) {\n throw new Error(`Invalid reference address: ${reference}`);\n }\n}\n\nfunction assertExpirySecs(expirySecs: number): void {\n if (!Number.isInteger(expirySecs) || expirySecs <= 0 || expirySecs > LIMITS.MAX_TIMEOUT_SECS) {\n throw new Error(`Invalid expiry: ${expirySecs}. Must be integer 1-${LIMITS.MAX_TIMEOUT_SECS}.`);\n }\n}\n\nfunction assertConfig(config: ProtocolConfigInput): void {\n if (!Number.isInteger(config.feeBps) || config.feeBps < 0) {\n throw new Error(`Invalid feeBps: ${config.feeBps}. Must be a non-negative integer.`);\n }\n if (typeof config.treasury !== 'string' || !isValidSolanaAddress(config.treasury)) {\n throw new Error(`Invalid treasury address: ${String(config.treasury)}`);\n }\n}\n\nexport class SolanaPaymentStrategy implements PaymentStrategy {\n readonly chain = 'solana';\n\n calculateFee(amount: number, config: ProtocolConfigInput): number {\n assertConfig(config);\n return calculateProtocolFee(amount, config.feeBps);\n }\n\n createPaymentRequest(\n recipientAddress: string,\n amount: number,\n config: ProtocolConfigInput,\n options?: { expirySecs?: number },\n ): PaymentRequestData {\n assertConfig(config);\n if (!isValidSolanaAddress(recipientAddress)) {\n throw new Error(`Invalid Solana address: ${recipientAddress}`);\n }\n assertLamports(amount, 'payment amount');\n if (amount === 0) {\n throw new Error('Invalid payment amount: 0. Must be positive.');\n }\n const expirySecs = options?.expirySecs ?? DEFAULTS.PAYMENT_EXPIRY_SECS;\n assertExpirySecs(expirySecs);\n\n const feeAmount = calculateProtocolFee(amount, config.feeBps);\n const reference = generateReference();\n\n return {\n recipient: recipientAddress,\n amount,\n reference,\n fee_address: config.treasury,\n fee_amount: feeAmount,\n created_at: Math.floor(Date.now() / 1000),\n expiry_secs: expirySecs,\n };\n }\n\n validatePaymentRequest(\n requestJson: string,\n config: ProtocolConfigInput,\n expectedRecipient?: string,\n ): PaymentValidationError | null {\n assertConfig(config);\n let data: PaymentRequestData;\n try {\n data = JSON.parse(requestJson);\n } catch (e) {\n return { code: 'invalid_json', message: `Invalid payment request JSON: ${e}` };\n }\n\n if (typeof data.amount !== 'number' || !Number.isInteger(data.amount) || data.amount <= 0) {\n return {\n code: 'invalid_amount',\n message: `Invalid amount in payment request: ${data.amount}`,\n };\n }\n if (typeof data.recipient !== 'string' || !data.recipient) {\n return { code: 'missing_recipient', message: 'Missing recipient in payment request' };\n }\n if (!isValidSolanaAddress(data.recipient)) {\n return {\n code: 'invalid_recipient_address',\n message: `Invalid Solana address for recipient: ${data.recipient}`,\n };\n }\n if (typeof data.reference !== 'string' || !data.reference) {\n return { code: 'missing_reference', message: 'Missing reference in payment request' };\n }\n if (!isValidSolanaAddress(data.reference)) {\n return {\n code: 'invalid_reference_address',\n message: `Invalid Solana address for reference: ${data.reference}`,\n };\n }\n\n if (expectedRecipient && data.recipient !== expectedRecipient) {\n return {\n code: 'recipient_mismatch',\n message:\n `Recipient mismatch: expected ${expectedRecipient}, got ${data.recipient}. ` +\n `Provider may be attempting to redirect payment.`,\n };\n }\n\n const expiryError = validateExpiry(data.created_at, data.expiry_secs);\n if (expiryError) {\n const code = expiryError.includes('future')\n ? ('future_timestamp' as const)\n : ('expired' as const);\n return { code, message: expiryError };\n }\n\n const expectedFee = calculateProtocolFee(data.amount, config.feeBps);\n const treasury = config.treasury;\n\n const { fee_address, fee_amount } = data;\n const hasFeeAddress = typeof fee_address === 'string' && fee_address.length > 0;\n const hasFeeAmount = typeof fee_amount === 'number' && fee_amount > 0;\n\n if (hasFeeAddress && hasFeeAmount) {\n if (fee_address !== treasury) {\n return {\n code: 'fee_address_mismatch',\n message:\n `Fee address mismatch: expected ${treasury}, got ${fee_address}. ` +\n `Provider may be attempting to redirect fees.`,\n };\n }\n if (fee_amount !== expectedFee) {\n return {\n code: 'fee_amount_mismatch',\n message:\n `Fee amount mismatch: expected ${expectedFee} lamports ` +\n `(${config.feeBps}bps of ${data.amount}), got ${fee_amount}. ` +\n `Provider may be tampering with fee.`,\n };\n }\n return null;\n }\n\n if (!hasFeeAddress && (fee_amount === null || fee_amount === undefined || fee_amount === 0)) {\n return {\n code: 'missing_fee',\n message:\n `Payment request missing protocol fee (${config.feeBps}bps). ` +\n `Expected fee: ${expectedFee} lamports to ${treasury}.`,\n };\n }\n\n return {\n code: 'invalid_fee_params',\n message:\n `Invalid fee params in payment request. ` +\n `Expected fee: ${expectedFee} lamports to ${treasury}.`,\n };\n }\n\n /**\n * Build, sign, and return a transaction for the supplied payment request.\n * The caller is responsible for sending it (e.g. via `rpc.sendTransaction`).\n *\n * The provider transfer instruction includes the payment reference as a\n * read-only, non-signer account so providers can detect the payment via\n * `getSignaturesForAddress(reference)`.\n */\n async buildTransaction(\n paymentRequest: PaymentRequestData,\n payerSigner: TransactionSigner,\n rpc: Rpc<SolanaRpcApi>,\n config: ProtocolConfigInput,\n ): Promise<Readonly<unknown>> {\n assertConfig(config);\n assertLamports(paymentRequest.amount, 'payment amount');\n if (paymentRequest.amount === 0) {\n throw new Error('Invalid payment amount: 0. Must be positive.');\n }\n if (\n paymentRequest.fee_amount !== null &&\n paymentRequest.fee_amount !== undefined &&\n (!Number.isInteger(paymentRequest.fee_amount) || paymentRequest.fee_amount < 0)\n ) {\n throw new Error(\n `Invalid fee amount: ${paymentRequest.fee_amount}. Must be a non-negative integer (lamports).`,\n );\n }\n assertReference(paymentRequest.reference);\n assertExpiry(paymentRequest.created_at, paymentRequest.expiry_secs);\n\n const treasury = config.treasury;\n if (paymentRequest.fee_address && paymentRequest.fee_address !== treasury) {\n throw new Error(\n `Invalid fee address: expected ${treasury}, got ${paymentRequest.fee_address}. ` +\n `Cannot build transaction with redirected fees.`,\n );\n }\n\n const instructions = buildPaymentInstructions(paymentRequest, payerSigner);\n\n const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();\n const message = pipe(\n createTransactionMessage({ version: 0 }),\n (m) => setTransactionMessageFeePayerSigner(payerSigner, m),\n (m) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, m),\n (m) =>\n appendTransactionMessageInstructions(\n instructions as Parameters<typeof appendTransactionMessageInstructions>[0],\n m,\n ),\n );\n\n return signTransactionMessageWithSigners(message);\n }\n\n async verifyPayment(\n rpc: Rpc<SolanaRpcApi>,\n paymentRequest: PaymentRequestData,\n config: ProtocolConfigInput,\n options?: VerifyOptions,\n ): Promise<VerifyResult> {\n assertConfig(config);\n if (!rpc || typeof (rpc as { getTransaction?: unknown }).getTransaction !== 'function') {\n return { verified: false, error: 'Invalid rpc: expected Solana Kit Rpc instance' };\n }\n\n if (!paymentRequest.reference || !paymentRequest.recipient) {\n return { verified: false, error: 'Missing required fields in payment request' };\n }\n if (!Number.isInteger(paymentRequest.amount) || paymentRequest.amount <= 0) {\n return {\n verified: false,\n error: `Invalid payment amount: ${paymentRequest.amount}. Must be a positive integer.`,\n };\n }\n\n if (\n paymentRequest.fee_amount !== null &&\n paymentRequest.fee_amount !== undefined &&\n (!Number.isInteger(paymentRequest.fee_amount) || paymentRequest.fee_amount < 0)\n ) {\n return {\n verified: false,\n error: `Invalid fee_amount: ${paymentRequest.fee_amount}. Must be a non-negative integer.`,\n };\n }\n\n const expectedFee = calculateProtocolFee(paymentRequest.amount, config.feeBps);\n const feeAmount = paymentRequest.fee_amount ?? 0;\n const treasury = config.treasury;\n\n if (expectedFee > 0) {\n if (feeAmount < expectedFee) {\n return {\n verified: false,\n error: `Protocol fee ${feeAmount} below required ${expectedFee} (${config.feeBps}bps of ${paymentRequest.amount})`,\n };\n }\n if (!paymentRequest.fee_address) {\n return { verified: false, error: 'Missing fee address in payment request' };\n }\n if (paymentRequest.fee_address !== treasury) {\n return { verified: false, error: `Invalid fee address: ${paymentRequest.fee_address}` };\n }\n }\n\n const expectedNet = paymentRequest.amount - feeAmount;\n if (expectedNet <= 0) {\n return {\n verified: false,\n error: `Fee amount (${feeAmount}) exceeds or equals total amount (${paymentRequest.amount})`,\n };\n }\n\n if (options?.txSignature) {\n return this._verifyBySignature(\n rpc,\n options.txSignature as Signature,\n paymentRequest.reference,\n paymentRequest.recipient,\n treasury,\n expectedNet,\n feeAmount,\n options?.retries ?? DEFAULTS.VERIFY_RETRIES,\n options?.intervalMs ?? DEFAULTS.VERIFY_INTERVAL_MS,\n );\n }\n\n return this._verifyByReference(\n rpc,\n paymentRequest.reference,\n paymentRequest.recipient,\n treasury,\n expectedNet,\n feeAmount,\n options?.retries ?? DEFAULTS.VERIFY_BY_REF_RETRIES,\n options?.intervalMs ?? DEFAULTS.VERIFY_BY_REF_INTERVAL_MS,\n );\n }\n\n private async _verifyBySignature(\n rpc: Rpc<SolanaRpcApi>,\n txSignature: Signature,\n referenceKey: string,\n recipientAddress: string,\n treasuryAddress: string,\n expectedNet: number,\n expectedFee: number,\n retries: number,\n intervalMs: number,\n ): Promise<VerifyResult> {\n let lastError: unknown;\n for (let attempt = 0; attempt < retries; attempt++) {\n try {\n const tx = await rpc\n .getTransaction(txSignature, {\n commitment: 'confirmed',\n encoding: 'json',\n maxSupportedTransactionVersion: 0,\n })\n .send();\n\n if (!tx?.meta || tx.meta.err) {\n if (attempt < retries - 1) {\n await waitMs(intervalMs);\n continue;\n }\n return {\n verified: false,\n error: tx?.meta?.err ? 'Transaction failed on-chain' : 'Transaction not found',\n };\n }\n\n const verdict = checkBalanceDiff({\n accountKeys: tx.transaction.message.accountKeys as readonly string[],\n preBalances: tx.meta.preBalances as readonly bigint[],\n postBalances: tx.meta.postBalances as readonly bigint[],\n referenceKey,\n recipientAddress,\n treasuryAddress,\n expectedNet,\n expectedFee,\n });\n if (verdict.ok) {\n return { verified: true, txSignature: txSignature as string };\n }\n return { verified: false, error: verdict.reason };\n } catch (err) {\n lastError = err;\n if (attempt < retries - 1) {\n await waitMs(intervalMs);\n }\n }\n }\n return {\n verified: false,\n error: `Verification failed after ${retries} retries: ${lastError instanceof Error ? lastError.message : 'unknown error'}`,\n };\n }\n\n private async _verifyByReference(\n rpc: Rpc<SolanaRpcApi>,\n referenceKey: string,\n recipientAddress: string,\n treasuryAddress: string,\n expectedNet: number,\n expectedFee: number,\n retries: number,\n intervalMs: number,\n ): Promise<VerifyResult> {\n let lastError: unknown;\n const reference = address(referenceKey);\n\n for (let attempt = 0; attempt < retries; attempt++) {\n try {\n const signatures = await rpc\n .getSignaturesForAddress(reference, {\n limit: DEFAULTS.VERIFY_SIGNATURE_LIMIT,\n })\n .send();\n const validSigs = signatures.filter((entry) => !entry.err);\n\n if (validSigs.length > 0) {\n const fetchTransaction = (sig: Signature) =>\n rpc\n .getTransaction(sig, {\n commitment: 'confirmed',\n encoding: 'json',\n maxSupportedTransactionVersion: 0,\n })\n .send();\n type TransactionResult = Awaited<ReturnType<typeof fetchTransaction>>;\n const txResults = await Promise.all(\n validSigs.map((entry) =>\n fetchTransaction(entry.signature)\n .then((tx) => ({ sig: entry.signature, tx }))\n .catch(() => ({ sig: entry.signature, tx: null as TransactionResult })),\n ),\n );\n\n for (const { sig, tx } of txResults) {\n if (!tx?.meta || tx.meta.err) {\n continue;\n }\n const verdict = checkBalanceDiff({\n accountKeys: tx.transaction.message.accountKeys as readonly string[],\n preBalances: tx.meta.preBalances as readonly bigint[],\n postBalances: tx.meta.postBalances as readonly bigint[],\n referenceKey,\n recipientAddress,\n treasuryAddress,\n expectedNet,\n expectedFee,\n });\n if (verdict.ok) {\n return { verified: true, txSignature: sig as string };\n }\n }\n }\n } catch (err) {\n lastError = err;\n }\n\n if (attempt < retries - 1) {\n await waitMs(intervalMs);\n }\n }\n return {\n verified: false,\n error: lastError\n ? `Verification failed: ${lastError instanceof Error ? lastError.message : 'unknown error'}`\n : 'No matching transaction found for reference key',\n };\n }\n}\n\ninterface BalanceDiffInput {\n accountKeys: readonly string[];\n preBalances: readonly bigint[];\n postBalances: readonly bigint[];\n referenceKey: string;\n recipientAddress: string;\n treasuryAddress: string;\n expectedNet: number;\n expectedFee: number;\n}\n\ntype BalanceVerdict = { ok: true } | { ok: false; reason: string };\n\nfunction checkBalanceDiff(input: BalanceDiffInput): BalanceVerdict {\n const balanceCount = input.preBalances.length;\n const keyToIdx = new Map<string, number>();\n for (let i = 0; i < Math.min(input.accountKeys.length, balanceCount); i++) {\n const key = input.accountKeys[i];\n if (key) {\n keyToIdx.set(String(key), i);\n }\n }\n\n if (!keyToIdx.has(input.referenceKey)) {\n return { ok: false, reason: 'Reference key not found in transaction - possible replay' };\n }\n const recipientIdx = keyToIdx.get(input.recipientAddress);\n if (recipientIdx === undefined) {\n return { ok: false, reason: 'Recipient not found in transaction' };\n }\n const recipientDelta = bigIntDelta(\n input.postBalances[recipientIdx],\n input.preBalances[recipientIdx],\n );\n if (recipientDelta < BigInt(input.expectedNet)) {\n return {\n ok: false,\n reason: `Recipient received ${recipientDelta.toString()}, expected >= ${input.expectedNet}`,\n };\n }\n\n if (input.expectedFee > 0) {\n const treasuryIdx = keyToIdx.get(input.treasuryAddress);\n if (treasuryIdx === undefined) {\n return { ok: false, reason: 'Treasury not found in transaction' };\n }\n const treasuryDelta = bigIntDelta(\n input.postBalances[treasuryIdx],\n input.preBalances[treasuryIdx],\n );\n if (treasuryDelta < BigInt(input.expectedFee)) {\n return {\n ok: false,\n reason: `Treasury received ${treasuryDelta.toString()}, expected >= ${input.expectedFee}`,\n };\n }\n }\n return { ok: true };\n}\n\nfunction bigIntDelta(post: bigint | undefined, pre: bigint | undefined): bigint {\n const postValue = post === undefined ? 0n : BigInt(post);\n const preValue = pre === undefined ? 0n : BigInt(pre);\n return postValue - preValue;\n}\n\nfunction waitMs(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Build the System program transfer instructions for a payment request.\n *\n * Returns the provider-amount transfer (with the payment reference attached\n * as a read-only, non-signer account) and, if present, the protocol-fee\n * transfer. Exposed so callers and tests can inspect amounts before signing.\n *\n * Caller is responsible for validating `paymentRequest` upstream;\n * `buildTransaction` already does that before invoking this helper.\n */\nexport function buildPaymentInstructions(\n paymentRequest: PaymentRequestData,\n payerSigner: TransactionSigner,\n): readonly unknown[] {\n const recipient = address(paymentRequest.recipient);\n const reference = address(paymentRequest.reference);\n const feeAmount = paymentRequest.fee_amount ?? 0;\n const providerAmount =\n paymentRequest.fee_address && feeAmount > 0\n ? paymentRequest.amount - feeAmount\n : paymentRequest.amount;\n\n if (providerAmount <= 0) {\n throw new Error(\n `Fee amount (${feeAmount}) exceeds or equals total amount (${paymentRequest.amount}). Cannot create transaction with non-positive provider amount.`,\n );\n }\n\n const providerTransferIx = getTransferSolInstruction({\n source: payerSigner,\n destination: recipient,\n amount: BigInt(providerAmount),\n });\n const providerTransferIxWithReference = {\n ...providerTransferIx,\n accounts: [...providerTransferIx.accounts, { address: reference, role: AccountRole.READONLY }],\n };\n\n const instructions: unknown[] = [providerTransferIxWithReference];\n if (paymentRequest.fee_address && feeAmount > 0) {\n instructions.push(\n getTransferSolInstruction({\n source: payerSigner,\n destination: address(paymentRequest.fee_address),\n amount: BigInt(feeAmount),\n }),\n );\n }\n return instructions;\n}\n\n/**\n * Convenience wrapper: fetch the on-chain protocol config first, then build a\n * payment request using its current fee/treasury values.\n *\n * Suitable for callers that want to \"do the right thing\" without managing the\n * config cache or the SolanaPaymentStrategy instance themselves. Uses the same\n * cache as `getProtocolConfig`, so back-to-back calls within the TTL only hit\n * RPC once.\n */\nexport async function createPaymentRequestWithOnchainConfig(\n rpc: Rpc<SolanaRpcApi>,\n programId: Address,\n recipient: string,\n amount: number,\n options?: { expirySecs?: number },\n): Promise<PaymentRequestData> {\n const config = await getProtocolConfig(rpc, programId);\n const strategy = new SolanaPaymentStrategy();\n return strategy.createPaymentRequest(\n recipient,\n amount,\n { feeBps: config.feeBps, treasury: config.treasury },\n options,\n );\n}\n","import { nip19, finalizeEvent, verifyEvent, type Filter, type Event } from 'nostr-tools';\nimport {\n KIND_APP_HANDLER,\n KIND_JOB_FEEDBACK,\n KIND_JOB_REQUEST,\n KIND_JOB_REQUEST_BASE,\n KIND_JOB_RESULT_BASE,\n jobResultKind,\n DEFAULT_KIND_OFFSET,\n LIMITS,\n} from '../constants';\nimport type { ElisymIdentity } from '../primitives/identity';\nimport type { NostrPool } from '../transport/pool';\nimport type { Agent, CapabilityCard, Network } from '../types';\n\n/** Convert a capability name to its Nostr d-tag form (ASCII-only, lowercase, hyphen-separated). */\nexport function toDTag(name: string): string {\n const tag = name\n .toLowerCase()\n .replace(/[^a-z0-9\\s-]/g, (ch) => '_' + ch.charCodeAt(0).toString(16).padStart(2, '0'))\n .replace(/\\s+/g, '-')\n .replace(/^-+|-+$/g, '');\n if (!tag) {\n throw new Error('Capability name must contain at least one ASCII alphanumeric character.');\n }\n return tag;\n}\n\n/**\n * Deduplicate events by (pubkey, d-tag) keeping only the newest,\n * then build an Agent map filtered by network.\n */\nfunction buildAgentsFromEvents(events: Event[], network: Network): Map<string, Agent> {\n // Deduplicate by author + d-tag, keeping only the newest event\n const latestByDTag = new Map<string, Event>();\n for (const event of events) {\n if (!verifyEvent(event)) {\n continue;\n }\n const dTag = event.tags.find((t) => t[0] === 'd')?.[1] ?? '';\n const key = `${event.pubkey}:${dTag}`;\n const prev = latestByDTag.get(key);\n if (!prev || event.created_at > prev.created_at) {\n latestByDTag.set(key, event);\n }\n }\n\n // Intermediate structure: keep kTags per card so we can recompute\n // supportedKinds from only the surviving (deduplicated) entries.\n interface CardEntry {\n card: CapabilityCard;\n kTags: number[];\n createdAt: number;\n }\n interface AgentAccum {\n pubkey: string;\n npub: string;\n entries: CardEntry[];\n eventId: string;\n lastSeen: number;\n }\n\n const accumMap = new Map<string, AgentAccum>();\n\n for (const event of latestByDTag.values()) {\n try {\n if (!event.content) {\n continue;\n }\n const raw = JSON.parse(event.content);\n if (!raw || typeof raw !== 'object') {\n continue;\n }\n if (typeof raw.name !== 'string' || !raw.name) {\n continue;\n }\n if (typeof raw.description !== 'string') {\n continue;\n }\n if (\n !Array.isArray(raw.capabilities) ||\n !raw.capabilities.every((c: unknown) => typeof c === 'string')\n ) {\n continue;\n }\n if (raw.deleted) {\n continue;\n }\n const card = raw as CapabilityCard & { deleted?: boolean };\n\n // Validate payment field types if present\n if (\n card.payment &&\n (typeof card.payment.chain !== 'string' ||\n typeof card.payment.network !== 'string' ||\n typeof card.payment.address !== 'string')\n ) {\n continue;\n }\n\n // Validate payment.job_price if present\n if (\n card.payment?.job_price !== null &&\n card.payment?.job_price !== undefined &&\n (!Number.isInteger(card.payment.job_price) || card.payment.job_price < 0)\n ) {\n continue;\n }\n\n const agentNetwork = card.payment?.network ?? 'devnet';\n if (agentNetwork !== network) {\n continue;\n }\n\n const kTags = event.tags\n .filter((t) => t[0] === 'k')\n .map((t) => parseInt(t[1] ?? '', 10))\n .filter((k) => !isNaN(k));\n\n const entry: CardEntry = { card, kTags, createdAt: event.created_at };\n\n const existing = accumMap.get(event.pubkey);\n if (existing) {\n // Deduplicate by card name - keep the newer version\n const dupIndex = existing.entries.findIndex((e) => e.card.name === card.name);\n if (dupIndex >= 0) {\n if (entry.createdAt >= existing.entries[dupIndex]!.createdAt) {\n existing.entries[dupIndex] = entry;\n }\n } else {\n existing.entries.push(entry);\n }\n if (event.created_at > existing.lastSeen) {\n existing.lastSeen = event.created_at;\n existing.eventId = event.id;\n }\n } else {\n accumMap.set(event.pubkey, {\n pubkey: event.pubkey,\n npub: nip19.npubEncode(event.pubkey),\n entries: [entry],\n eventId: event.id,\n lastSeen: event.created_at,\n });\n }\n } catch {\n // skip malformed events\n }\n }\n\n // Build final Agent map - recompute supportedKinds from surviving entries only\n const agentMap = new Map<string, Agent>();\n for (const [pubkey, acc] of accumMap) {\n const kindsSet = new Set<number>();\n for (const e of acc.entries) {\n for (const k of e.kTags) {\n kindsSet.add(k);\n }\n }\n const supportedKinds = [...kindsSet];\n agentMap.set(pubkey, {\n pubkey: acc.pubkey,\n npub: acc.npub,\n cards: acc.entries.map((e) => e.card),\n eventId: acc.eventId,\n supportedKinds,\n lastSeen: acc.lastSeen,\n });\n }\n\n return agentMap;\n}\n\nexport class DiscoveryService {\n constructor(private pool: NostrPool) {}\n\n /** Count elisym agents (kind:31990 with \"elisym\" tag). */\n async fetchAllAgentCount(): Promise<number> {\n const events = await this.pool.querySync({\n kinds: [KIND_APP_HANDLER],\n '#t': ['elisym'],\n } as Filter);\n\n const uniquePubkeys = new Set<string>();\n for (const event of events) {\n if (!verifyEvent(event)) {\n continue;\n }\n uniquePubkeys.add(event.pubkey);\n }\n return uniquePubkeys.size;\n }\n\n /**\n * Fetch a single page of elisym agents with relay-side pagination.\n * Uses `until` cursor for Nostr cursor-based pagination.\n *\n * Unlike `fetchAgents`, this method does NOT enrich agents with\n * kind:0 metadata (name, picture, about) or update `lastSeen` from\n * recent job activity. Call `enrichWithMetadata()` separately if needed.\n */\n async fetchAgentsPage(\n network: Network = 'devnet',\n limit = 20,\n until?: number,\n ): Promise<{ agents: Agent[]; oldestCreatedAt: number | null; rawEventCount: number }> {\n const filter: Filter = {\n kinds: [KIND_APP_HANDLER],\n '#t': ['elisym'],\n limit,\n };\n if (until !== undefined) {\n filter.until = until;\n }\n\n const events = await this.pool.querySync(filter);\n const rawEventCount = events.length;\n\n // Compute cursor from ALL raw events (before any filtering)\n let oldestCreatedAt: number | null = null;\n for (const event of events) {\n if (oldestCreatedAt === null || event.created_at < oldestCreatedAt) {\n oldestCreatedAt = event.created_at;\n }\n }\n\n const agentMap = buildAgentsFromEvents(events, network);\n\n const agents = Array.from(agentMap.values()).sort((a, b) => b.lastSeen - a.lastSeen);\n\n return { agents, oldestCreatedAt, rawEventCount };\n }\n\n /** Enrich agents with kind:0 metadata (name, picture, about). Mutates in place and returns the same array. */\n async enrichWithMetadata(agents: Agent[]): Promise<Agent[]> {\n const pubkeys = agents.map((a) => a.pubkey);\n if (pubkeys.length === 0) {\n return agents;\n }\n\n const metaEvents = await this.pool.queryBatched(\n { kinds: [0] } as Omit<Filter, 'authors'>,\n pubkeys,\n );\n const latestMeta = new Map<string, (typeof metaEvents)[0]>();\n for (const ev of metaEvents) {\n if (!verifyEvent(ev)) {\n continue;\n }\n const prev = latestMeta.get(ev.pubkey);\n if (!prev || ev.created_at > prev.created_at) {\n latestMeta.set(ev.pubkey, ev);\n }\n }\n const agentLookup = new Map(agents.map((a) => [a.pubkey, a]));\n for (const [pubkey, ev] of latestMeta) {\n const agent = agentLookup.get(pubkey);\n if (!agent) {\n continue;\n }\n try {\n const meta = JSON.parse(ev.content);\n if (typeof meta.picture === 'string') {\n agent.picture = meta.picture;\n }\n if (typeof meta.name === 'string') {\n agent.name = meta.name;\n }\n if (typeof meta.about === 'string') {\n agent.about = meta.about;\n }\n } catch {\n // skip malformed metadata\n }\n }\n return agents;\n }\n\n /** Fetch elisym agents filtered by network. */\n async fetchAgents(network: Network = 'devnet', limit?: number): Promise<Agent[]> {\n const filter: Filter = {\n kinds: [KIND_APP_HANDLER],\n '#t': ['elisym'],\n };\n if (limit !== undefined) {\n filter.limit = limit;\n }\n const events = await this.pool.querySync(filter);\n\n const agentMap = buildAgentsFromEvents(events, network);\n\n const agents = Array.from(agentMap.values()).sort((a, b) => b.lastSeen - a.lastSeen);\n\n // Update lastSeen from recent job activity\n const agentPubkeys = Array.from(agentMap.keys());\n if (agentPubkeys.length > 0) {\n const activitySince = Math.floor(Date.now() / 1000) - 24 * 60 * 60;\n // Derive result kinds from agents' supported request kinds (5xxx - 6xxx)\n const resultKinds = new Set<number>();\n for (const agent of agentMap.values()) {\n for (const k of agent.supportedKinds) {\n if (k >= KIND_JOB_REQUEST_BASE && k < KIND_JOB_RESULT_BASE) {\n resultKinds.add(KIND_JOB_RESULT_BASE + (k - KIND_JOB_REQUEST_BASE));\n }\n }\n }\n resultKinds.add(jobResultKind(DEFAULT_KIND_OFFSET));\n\n // Fetch activity and metadata in parallel (independent: activity writes lastSeen, metadata writes name/picture/about)\n const [activityEvents] = await Promise.all([\n this.pool.queryBatched(\n {\n kinds: [...resultKinds, KIND_JOB_FEEDBACK],\n since: activitySince,\n } as Omit<Filter, 'authors'>,\n agentPubkeys,\n ),\n this.enrichWithMetadata(agents),\n ]);\n for (const ev of activityEvents) {\n if (!verifyEvent(ev)) {\n continue;\n }\n const agent = agentMap.get(ev.pubkey);\n if (agent && ev.created_at > agent.lastSeen) {\n agent.lastSeen = ev.created_at;\n }\n }\n\n agents.sort((a, b) => b.lastSeen - a.lastSeen);\n }\n\n return agents;\n }\n\n /**\n * Publish a capability card (kind:31990) as a provider.\n * Solana address is validated for Base58 format only - full decode\n * validation (32-byte public key) happens at payment time.\n */\n async publishCapability(\n identity: ElisymIdentity,\n card: CapabilityCard,\n kinds: number[] = [KIND_JOB_REQUEST],\n ): Promise<string> {\n if (!card.payment?.address) {\n throw new Error(\n 'Cannot publish capability without a payment address. Connect a wallet before publishing.',\n );\n }\n // Base58 charset + length check. Full validation (decode + 32 bytes) happens\n // at payment time via the @solana/kit `address()` helper - no Kit import here\n // to keep discovery browser-safe without a Solana peer dep at this layer.\n if (\n card.payment.chain === 'solana' &&\n !/^[1-9A-HJ-NP-Za-km-z]{32,44}$/.test(card.payment.address)\n ) {\n throw new Error(`Invalid Solana address format: ${card.payment.address}`);\n }\n if (card.name.length > LIMITS.MAX_AGENT_NAME_LENGTH) {\n throw new Error(\n `Agent name too long: ${card.name.length} chars (max ${LIMITS.MAX_AGENT_NAME_LENGTH}).`,\n );\n }\n if (card.description.length > LIMITS.MAX_DESCRIPTION_LENGTH) {\n throw new Error(\n `Description too long: ${card.description.length} chars (max ${LIMITS.MAX_DESCRIPTION_LENGTH}).`,\n );\n }\n if (card.capabilities.length > LIMITS.MAX_CAPABILITIES) {\n throw new Error(\n `Too many capabilities: ${card.capabilities.length} (max ${LIMITS.MAX_CAPABILITIES}).`,\n );\n }\n for (const cap of card.capabilities) {\n if (cap.length > LIMITS.MAX_CAPABILITY_LENGTH) {\n throw new Error(\n `Capability name too long: \"${cap}\" (${cap.length} chars, max ${LIMITS.MAX_CAPABILITY_LENGTH}).`,\n );\n }\n }\n\n const tags: string[][] = [\n ['d', toDTag(card.name)],\n ['t', 'elisym'],\n ...card.capabilities.map((c) => ['t', c]),\n ...kinds.map((k) => ['k', String(k)]),\n ];\n\n const event = finalizeEvent(\n {\n kind: KIND_APP_HANDLER,\n created_at: Math.floor(Date.now() / 1000),\n tags,\n content: JSON.stringify(card),\n },\n identity.secretKey,\n );\n\n await this.pool.publishAll(event);\n return event.id;\n }\n\n /** Publish a Nostr profile (kind:0) as a provider. */\n async publishProfile(\n identity: ElisymIdentity,\n name: string,\n about: string,\n picture?: string,\n banner?: string,\n ): Promise<string> {\n if (name.length > LIMITS.MAX_AGENT_NAME_LENGTH) {\n throw new Error(\n `Profile name too long: ${name.length} chars (max ${LIMITS.MAX_AGENT_NAME_LENGTH}).`,\n );\n }\n if (about.length > LIMITS.MAX_DESCRIPTION_LENGTH) {\n throw new Error(\n `Profile about too long: ${about.length} chars (max ${LIMITS.MAX_DESCRIPTION_LENGTH}).`,\n );\n }\n const content: Record<string, string> = { name, about };\n if (picture) {\n content.picture = picture;\n }\n if (banner) {\n content.banner = banner;\n }\n\n const event = finalizeEvent(\n {\n kind: 0,\n created_at: Math.floor(Date.now() / 1000),\n tags: [],\n content: JSON.stringify(content),\n },\n identity.secretKey,\n );\n\n await this.pool.publishAll(event);\n return event.id;\n }\n\n /**\n * Delete a capability by publishing a tombstone replacement.\n * Since kind:31990 is a parameterized replaceable event,\n * publishing a new event with the same `d` tag and `\"deleted\":true`\n * content replaces the old one on all relays.\n */\n async deleteCapability(identity: ElisymIdentity, capabilityName: string): Promise<string> {\n const dTag = toDTag(capabilityName);\n\n const event = finalizeEvent(\n {\n kind: KIND_APP_HANDLER,\n created_at: Math.floor(Date.now() / 1000),\n tags: [\n ['d', dTag],\n ['t', 'elisym'],\n ],\n content: JSON.stringify({ deleted: true }),\n },\n identity.secretKey,\n );\n\n await this.pool.publishAll(event);\n return event.id;\n }\n}\n","/**\n * NIP-44 encryption/decryption helpers.\n * Wraps nostr-tools nip44 v2 for convenience.\n */\nimport * as nip44 from 'nostr-tools/nip44';\n\n/** Encrypt plaintext using NIP-44 v2 (sender secret key + recipient public key). */\nexport function nip44Encrypt(\n plaintext: string,\n senderSk: Uint8Array,\n recipientPubkey: string,\n): string {\n const conversationKey = nip44.v2.utils.getConversationKey(senderSk, recipientPubkey);\n return nip44.v2.encrypt(plaintext, conversationKey);\n}\n\n/** Decrypt ciphertext using NIP-44 v2 (receiver secret key + sender public key). */\nexport function nip44Decrypt(\n ciphertext: string,\n receiverSk: Uint8Array,\n senderPubkey: string,\n): string {\n const conversationKey = nip44.v2.utils.getConversationKey(receiverSk, senderPubkey);\n return nip44.v2.decrypt(ciphertext, conversationKey);\n}\n","import { finalizeEvent, verifyEvent, type Filter, type Event } from 'nostr-tools';\nimport {\n KIND_JOB_FEEDBACK,\n KIND_JOB_REQUEST_BASE,\n KIND_JOB_RESULT_BASE,\n DEFAULT_KIND_OFFSET,\n DEFAULTS,\n LIMITS,\n jobRequestKind,\n jobResultKind,\n} from '../constants';\nimport { assertLamports } from '../payment/fee';\nimport { nip44Encrypt, nip44Decrypt } from '../primitives/crypto';\nimport type { ElisymIdentity } from '../primitives/identity';\nimport type { NostrPool } from '../transport/pool';\nimport type { Job, JobStatus, SubCloser, SubmitJobOptions, JobSubscriptionOptions } from '../types';\n\nfunction isEncrypted(event: Event): boolean {\n return event.tags.some((t) => t[0] === 'encrypted' && t[1] === 'nip44');\n}\n\nfunction resolveRequestId(event: Event): string | undefined {\n return event.tags.find((t) => t[0] === 'e')?.[1];\n}\n\nfunction safeParseInt(value: string | undefined): number | undefined {\n if (!value) {\n return undefined;\n }\n const n = parseInt(value, 10);\n return isNaN(n) ? undefined : n;\n}\n\nconst VALID_JOB_STATUSES = new Set<string>([\n 'payment-required',\n 'payment-completed',\n 'processing',\n 'error',\n 'success',\n 'partial',\n]);\n\nfunction toJobStatus(raw: string): JobStatus {\n return VALID_JOB_STATUSES.has(raw) ? (raw as JobStatus) : 'unknown';\n}\n\nexport class MarketplaceService {\n constructor(private pool: NostrPool) {}\n\n /** Submit a job request with NIP-44 encrypted input. Returns the event ID. */\n async submitJobRequest(identity: ElisymIdentity, options: SubmitJobOptions): Promise<string> {\n if (!options.input) {\n throw new Error('Job input must not be empty.');\n }\n if (options.input.length > LIMITS.MAX_INPUT_LENGTH) {\n throw new Error(\n `Job input too long: ${options.input.length} chars (max ${LIMITS.MAX_INPUT_LENGTH}).`,\n );\n }\n if (!options.capability || options.capability.length > LIMITS.MAX_CAPABILITY_LENGTH) {\n throw new Error(`Invalid capability: must be 1-${LIMITS.MAX_CAPABILITY_LENGTH} characters.`);\n }\n if (options.providerPubkey && !/^[0-9a-f]{64}$/.test(options.providerPubkey)) {\n throw new Error('Invalid provider pubkey: expected 64 hex characters.');\n }\n const plaintext = options.input;\n const encrypted = options.providerPubkey\n ? nip44Encrypt(plaintext, identity.secretKey, options.providerPubkey)\n : plaintext;\n\n const tags: string[][] = [\n ['i', options.providerPubkey ? 'encrypted' : 'text', 'text'],\n ['t', options.capability],\n ['t', 'elisym'],\n ['output', 'text/plain'],\n ];\n\n if (options.providerPubkey) {\n tags.push(['p', options.providerPubkey]);\n tags.push(['encrypted', 'nip44']);\n }\n\n const kind = jobRequestKind(options.kindOffset ?? DEFAULT_KIND_OFFSET);\n const event = finalizeEvent(\n {\n kind,\n created_at: Math.floor(Date.now() / 1000),\n tags,\n content: encrypted,\n },\n identity.secretKey,\n );\n\n await this.pool.publish(event);\n return event.id;\n }\n\n /**\n * Subscribe to job updates (feedback + results) for a given job.\n * Creates 3 subscriptions per call (feedback, result by #e, result by #p+#e)\n * to cover different relay indexing strategies. Returns a cleanup function.\n */\n subscribeToJobUpdates(options: JobSubscriptionOptions): () => void {\n const {\n jobEventId: jid,\n providerPubkey: provPk,\n customerPublicKey: custPk,\n callbacks: cb,\n timeoutMs = DEFAULTS.SUBSCRIPTION_TIMEOUT_MS,\n customerSecretKey: custSk,\n kindOffsets: offsets_,\n sinceOverride: since_,\n } = options;\n\n const offsets = offsets_ ?? [DEFAULT_KIND_OFFSET];\n if (offsets.length === 0) {\n throw new Error('kindOffsets must not be empty.');\n }\n const resultKinds = offsets.map(jobResultKind);\n const since = since_ ?? Math.floor(Date.now() / 1000) - 30;\n const subs: SubCloser[] = [];\n let resolved = false;\n let resultDelivered = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n const done = () => {\n resolved = true;\n if (timer) {\n clearTimeout(timer);\n }\n for (const s of subs) {\n try {\n s.close();\n } catch {\n /* ignore */\n }\n }\n };\n\n const decryptResult = (ev: Event): string | null => {\n if (isEncrypted(ev)) {\n if (!custSk) {\n return null;\n }\n try {\n return nip44Decrypt(ev.content, custSk, ev.pubkey);\n } catch {\n return null;\n }\n }\n return ev.content;\n };\n\n const handleResult = (ev: Event) => {\n if (resolved || resultDelivered) {\n return;\n }\n if (!verifyEvent(ev)) {\n return;\n }\n if (provPk && ev.pubkey !== provPk) {\n return;\n }\n const eTag = ev.tags.find((t) => t[0] === 'e')?.[1];\n if (eTag !== jid) {\n return;\n }\n const content = decryptResult(ev);\n if (content === null) {\n // Skip undecryptable results instead of terminating the subscription.\n // For broadcast jobs a rogue agent could send fake encrypted results;\n // killing the subscription would be a DoS vector.\n return;\n }\n resultDelivered = true;\n try {\n cb.onResult?.(content, ev.id);\n } catch {\n /* caller error - don't crash subscription */\n } finally {\n done();\n }\n };\n\n try {\n // Feedback subscription\n subs.push(\n this.pool.subscribe(\n {\n kinds: [KIND_JOB_FEEDBACK],\n '#e': [jid],\n since,\n } as Filter,\n (ev) => {\n if (resolved) {\n return;\n }\n if (!verifyEvent(ev)) {\n return;\n }\n if (provPk && ev.pubkey !== provPk) {\n return;\n }\n const eTag = ev.tags.find((t) => t[0] === 'e')?.[1];\n if (eTag !== jid) {\n return;\n }\n const statusTag = ev.tags.find((t) => t[0] === 'status');\n if (statusTag?.[1]) {\n const amtTag = ev.tags.find((t) => t[0] === 'amount');\n const amt = safeParseInt(amtTag?.[1]) ?? 0;\n const paymentReq = amtTag?.[2];\n try {\n cb.onFeedback?.(statusTag[1], amt, paymentReq, ev.pubkey);\n } catch {\n /* caller error - don't crash subscription */\n }\n }\n },\n ),\n );\n\n // Result subscription by #e tag\n subs.push(\n this.pool.subscribe(\n {\n kinds: resultKinds,\n '#e': [jid],\n since,\n } as Filter,\n handleResult,\n ),\n );\n\n // Result subscription by #p tag (customer pubkey) + #e tag\n subs.push(\n this.pool.subscribe(\n {\n kinds: resultKinds,\n '#p': [custPk],\n '#e': [jid],\n since,\n } as Filter,\n handleResult,\n ),\n );\n } catch (err) {\n done();\n throw err;\n }\n\n timer = setTimeout(() => {\n if (!resolved) {\n done();\n try {\n cb.onError?.(`Timed out waiting for response (${timeoutMs / 1000}s).`);\n } catch {\n /* caller error - don't crash subscription */\n }\n }\n }, timeoutMs);\n\n return done;\n }\n\n /** Submit payment confirmation feedback. */\n async submitPaymentConfirmation(\n identity: ElisymIdentity,\n jobEventId: string,\n providerPubkey: string,\n txSignature: string,\n ): Promise<void> {\n const event = finalizeEvent(\n {\n kind: KIND_JOB_FEEDBACK,\n created_at: Math.floor(Date.now() / 1000),\n tags: [\n ['e', jobEventId],\n ['p', providerPubkey],\n ['status', 'payment-completed'],\n ['tx', txSignature, 'solana'],\n ['t', 'elisym'],\n ],\n content: '',\n },\n identity.secretKey,\n );\n\n await this.pool.publishAll(event);\n }\n\n /** Submit rating feedback for a job. */\n async submitFeedback(\n identity: ElisymIdentity,\n jobEventId: string,\n providerPubkey: string,\n positive: boolean,\n capability?: string,\n ): Promise<void> {\n const tags: string[][] = [\n ['e', jobEventId],\n ['p', providerPubkey],\n ['status', 'success'],\n ['rating', positive ? '1' : '0'],\n ['t', 'elisym'],\n ];\n if (capability) {\n tags.push(['t', capability]);\n }\n\n const event = finalizeEvent(\n {\n kind: KIND_JOB_FEEDBACK,\n created_at: Math.floor(Date.now() / 1000),\n tags,\n content: positive ? 'Good result' : 'Poor result',\n },\n identity.secretKey,\n );\n\n await this.pool.publishAll(event);\n }\n\n // --- Provider methods ---\n\n /**\n * Subscribe to incoming job requests for specific kinds.\n * Automatically decrypts NIP-44 encrypted content.\n * Note: decrypted events have modified `content` - do not call `verifyEvent()` on them.\n * Signature verification is performed before decryption.\n */\n subscribeToJobRequests(\n identity: ElisymIdentity,\n kinds: number[],\n onRequest: (event: Event) => void,\n ): SubCloser {\n return this.pool.subscribe(\n {\n kinds,\n '#p': [identity.publicKey],\n '#t': ['elisym'],\n since: Math.floor(Date.now() / 1000) - 5,\n } as Filter,\n (event: Event) => {\n if (!verifyEvent(event)) {\n return;\n }\n if (isEncrypted(event) && event.content) {\n try {\n const decrypted = nip44Decrypt(event.content, identity.secretKey, event.pubkey);\n onRequest({ ...event, content: decrypted });\n } catch {\n // Can't decrypt - skip event (likely not intended for us)\n return;\n }\n } else {\n onRequest(event);\n }\n },\n );\n }\n\n /** Submit a job result with NIP-44 encrypted content. Result kind is derived from the request kind. */\n async submitJobResult(\n identity: ElisymIdentity,\n requestEvent: Event,\n content: string,\n amount?: number,\n ): Promise<string> {\n if (!content) {\n throw new Error('Job result content must not be empty.');\n }\n if (!Number.isInteger(requestEvent.kind)) {\n throw new Error(`Invalid request event kind: expected integer, got ${requestEvent.kind}.`);\n }\n const offset = requestEvent.kind - KIND_JOB_REQUEST_BASE;\n if (offset < 0 || offset >= 1000) {\n throw new Error(\n `Invalid request event kind ${requestEvent.kind}: expected a NIP-90 job request kind (5000-5999).`,\n );\n }\n const shouldEncrypt = isEncrypted(requestEvent);\n const resultContent = shouldEncrypt\n ? nip44Encrypt(content, identity.secretKey, requestEvent.pubkey)\n : content;\n const resultKind = KIND_JOB_RESULT_BASE + offset;\n\n const tags: string[][] = [\n ['e', requestEvent.id],\n ['p', requestEvent.pubkey],\n ['t', 'elisym'],\n ];\n if (shouldEncrypt) {\n tags.push(['encrypted', 'nip44']);\n }\n\n if (amount !== null && amount !== undefined) {\n assertLamports(amount, 'result amount');\n tags.push(['amount', String(amount)]);\n }\n\n const event = finalizeEvent(\n {\n kind: resultKind,\n created_at: Math.floor(Date.now() / 1000),\n tags,\n content: resultContent,\n },\n identity.secretKey,\n );\n\n await this.pool.publishAll(event);\n return event.id;\n }\n\n /**\n * Submit a job result with retry and exponential backoff.\n * Retries on publish failures (e.g. relay disconnects).\n * With maxAttempts=3: try, ~1s, try, ~2s, try, throw.\n * Jitter: 0.5x-1.0x of calculated delay.\n */\n async submitJobResultWithRetry(\n identity: ElisymIdentity,\n requestEvent: Event,\n content: string,\n amount?: number,\n maxAttempts: number = DEFAULTS.RESULT_RETRY_COUNT,\n baseDelayMs: number = DEFAULTS.RESULT_RETRY_BASE_MS,\n ): Promise<string> {\n const attempts = Math.max(1, maxAttempts);\n for (let attempt = 0; attempt < attempts; attempt++) {\n try {\n return await this.submitJobResult(identity, requestEvent, content, amount);\n } catch (e: unknown) {\n if (attempt >= attempts - 1) {\n throw e;\n }\n // Math.random is fine for jitter - not a security context\n const jitter = 0.5 + Math.random() * 0.5;\n await new Promise((r) => setTimeout(r, baseDelayMs * Math.pow(2, attempt) * jitter));\n }\n }\n throw new Error('All delivery attempts failed');\n }\n\n /** Submit payment-required feedback with a payment request. */\n async submitPaymentRequiredFeedback(\n identity: ElisymIdentity,\n requestEvent: Event,\n amount: number,\n paymentRequestJson: string,\n ): Promise<void> {\n assertLamports(amount, 'payment amount');\n if (amount === 0) {\n throw new Error('Invalid payment amount: 0. Must be positive.');\n }\n try {\n JSON.parse(paymentRequestJson);\n } catch {\n throw new Error('Invalid paymentRequestJson: must be valid JSON.');\n }\n if (paymentRequestJson.length > LIMITS.MAX_INPUT_LENGTH) {\n throw new Error(\n `paymentRequestJson too long: ${paymentRequestJson.length} chars (max ${LIMITS.MAX_INPUT_LENGTH}).`,\n );\n }\n\n const event = finalizeEvent(\n {\n kind: KIND_JOB_FEEDBACK,\n created_at: Math.floor(Date.now() / 1000),\n tags: [\n ['e', requestEvent.id],\n ['p', requestEvent.pubkey],\n ['status', 'payment-required'],\n ['amount', String(amount), paymentRequestJson, 'solana'],\n ['t', 'elisym'],\n ],\n content: '',\n },\n identity.secretKey,\n );\n\n await this.pool.publishAll(event);\n }\n\n /** Submit processing feedback to notify customer that work has started. */\n async submitProcessingFeedback(identity: ElisymIdentity, requestEvent: Event): Promise<void> {\n const event = finalizeEvent(\n {\n kind: KIND_JOB_FEEDBACK,\n created_at: Math.floor(Date.now() / 1000),\n tags: [\n ['e', requestEvent.id],\n ['p', requestEvent.pubkey],\n ['status', 'processing'],\n ['t', 'elisym'],\n ],\n content: '',\n },\n identity.secretKey,\n );\n\n await this.pool.publishAll(event);\n }\n\n /** Submit error feedback to notify customer of a failure. */\n async submitErrorFeedback(\n identity: ElisymIdentity,\n requestEvent: Event,\n message: string,\n ): Promise<void> {\n if (!message) {\n throw new Error('Error message must not be empty.');\n }\n if (message.length > LIMITS.MAX_INPUT_LENGTH) {\n throw new Error(\n `Error message too long: ${message.length} chars (max ${LIMITS.MAX_INPUT_LENGTH}).`,\n );\n }\n const event = finalizeEvent(\n {\n kind: KIND_JOB_FEEDBACK,\n created_at: Math.floor(Date.now() / 1000),\n tags: [\n ['e', requestEvent.id],\n ['p', requestEvent.pubkey],\n ['status', 'error'],\n ['t', 'elisym'],\n ],\n content: message,\n },\n identity.secretKey,\n );\n\n await this.pool.publishAll(event);\n }\n\n /** Query job results by request IDs and decrypt NIP-44 content. */\n async queryJobResults(\n identity: ElisymIdentity,\n requestIds: string[],\n kindOffsets?: number[],\n providerPubkey?: string,\n ): Promise<\n Map<\n string,\n { content: string; amount?: number; senderPubkey: string; decryptionFailed: boolean }\n >\n > {\n const offsets = kindOffsets ?? [DEFAULT_KIND_OFFSET];\n if (offsets.length === 0) {\n throw new Error('kindOffsets must not be empty.');\n }\n const resultKinds = offsets.map(jobResultKind);\n\n const results = await this.pool.queryBatchedByTag(\n { kinds: resultKinds } as Filter,\n 'e',\n requestIds,\n );\n\n const resultByRequest = new Map<\n string,\n { content: string; amount?: number; senderPubkey: string; decryptionFailed: boolean }\n >();\n const createdAtByRequest = new Map<string, number>();\n for (const r of results) {\n if (!verifyEvent(r)) {\n continue;\n }\n if (providerPubkey && r.pubkey !== providerPubkey) {\n continue;\n }\n const eTag = r.tags.find((t) => t[0] === 'e');\n if (!eTag?.[1]) {\n continue;\n }\n\n const prevTs = createdAtByRequest.get(eTag[1]) ?? 0;\n if (r.created_at < prevTs) {\n continue;\n }\n\n const amtTag = r.tags.find((t) => t[0] === 'amount');\n\n let content = r.content;\n let decryptionFailed = false;\n if (isEncrypted(r)) {\n try {\n content = nip44Decrypt(r.content, identity.secretKey, r.pubkey);\n } catch {\n content = '';\n decryptionFailed = true;\n }\n }\n\n createdAtByRequest.set(eTag[1], r.created_at);\n resultByRequest.set(eTag[1], {\n content,\n amount: safeParseInt(amtTag?.[1]),\n senderPubkey: r.pubkey,\n decryptionFailed,\n });\n }\n\n return resultByRequest;\n }\n\n // --- Query methods ---\n\n /**\n * Fetch recent jobs from the network.\n * NOTE: Job.result contains raw event content. For encrypted jobs,\n * this will be NIP-44 ciphertext - use queryJobResults() for decryption.\n */\n async fetchRecentJobs(\n agentPubkeys?: Set<string>,\n limit?: number,\n since?: number,\n /** Kind offsets to query (default [100]). */\n kindOffsets?: number[],\n ): Promise<Job[]> {\n const offsets = kindOffsets ?? [DEFAULT_KIND_OFFSET];\n if (offsets.length === 0) {\n throw new Error('kindOffsets must not be empty.');\n }\n const requestKinds = offsets.map(jobRequestKind);\n const resultKinds = offsets.map(jobResultKind);\n\n const reqFilter: Filter = {\n kinds: requestKinds,\n '#t': ['elisym'],\n ...(limit !== null && limit !== undefined && { limit }),\n ...(since !== null && since !== undefined && { since }),\n };\n const rawRequests = await this.pool.querySync(reqFilter);\n const requests = rawRequests.filter(verifyEvent);\n\n const requestIds = requests.map((r) => r.id);\n let results: Event[] = [];\n let feedbacks: Event[] = [];\n\n if (requestIds.length > 0) {\n const [rawResults, rawFeedbacks] = await Promise.all([\n this.pool.queryBatchedByTag({ kinds: resultKinds } as Filter, 'e', requestIds),\n this.pool.queryBatchedByTag({ kinds: [KIND_JOB_FEEDBACK] } as Filter, 'e', requestIds),\n ]);\n results = rawResults.filter(verifyEvent);\n feedbacks = rawFeedbacks.filter(verifyEvent);\n }\n\n // Build targeted agent map\n const targetedAgentByRequest = new Map<string, string>();\n for (const req of requests) {\n const pTag = req.tags.find((t) => t[0] === 'p');\n if (pTag?.[1]) {\n targetedAgentByRequest.set(req.id, pTag[1]);\n }\n }\n\n // Index results by request ID (respect targeted agent, keep newest)\n const resultsByRequest = new Map<string, Event>();\n for (const r of results) {\n const reqId = resolveRequestId(r);\n if (!reqId) {\n continue;\n }\n const targeted = targetedAgentByRequest.get(reqId);\n if (targeted && r.pubkey !== targeted) {\n continue;\n }\n const existing = resultsByRequest.get(reqId);\n if (!existing || r.created_at > existing.created_at) {\n resultsByRequest.set(reqId, r);\n }\n }\n\n const feedbackByRequest = new Map<string, Event>();\n for (const f of feedbacks) {\n const reqId = resolveRequestId(f);\n if (!reqId) {\n continue;\n }\n const targeted = targetedAgentByRequest.get(reqId);\n if (targeted && f.pubkey !== targeted) {\n continue;\n }\n const existing = feedbackByRequest.get(reqId);\n if (!existing || f.created_at > existing.created_at) {\n feedbackByRequest.set(reqId, f);\n }\n }\n\n // Index all feedbacks by request ID for O(1) lookup\n const feedbacksByRequestId = new Map<string, Event[]>();\n for (const f of feedbacks) {\n const reqId = resolveRequestId(f);\n if (!reqId) {\n continue;\n }\n const arr = feedbacksByRequestId.get(reqId);\n if (arr) {\n arr.push(f);\n } else {\n feedbacksByRequestId.set(reqId, [f]);\n }\n }\n\n const jobs: Job[] = [];\n for (const req of requests) {\n const result = resultsByRequest.get(req.id);\n const feedback = feedbackByRequest.get(req.id);\n const jobAgentPubkey = result?.pubkey ?? feedback?.pubkey;\n\n if (agentPubkeys && agentPubkeys.size > 0 && jobAgentPubkey) {\n if (!agentPubkeys.has(jobAgentPubkey)) {\n continue;\n }\n }\n\n // NIP-90: one capability per job request - take the first non-elisym t tag\n const capability = req.tags.find((t) => t[0] === 't' && t[1] !== 'elisym')?.[1];\n const bid = req.tags.find((t) => t[0] === 'bid')?.[1];\n\n let status: JobStatus = 'processing';\n let amount: number | undefined;\n let txHash: string | undefined;\n\n if (result) {\n status = 'success';\n const amtTag = result.tags.find((t) => t[0] === 'amount');\n amount = safeParseInt(amtTag?.[1]);\n }\n\n // Check all feedbacks for tx hash\n const allFeedbacksForReq = feedbacksByRequestId.get(req.id) ?? [];\n for (const fb of allFeedbacksForReq) {\n const txTag = fb.tags.find((t) => t[0] === 'tx');\n if (txTag?.[1]) {\n txHash = txTag[1];\n break;\n }\n }\n\n if (feedback) {\n if (!result) {\n const statusTag = feedback.tags.find((t) => t[0] === 'status');\n if (statusTag?.[1]) {\n const isTargeted = targetedAgentByRequest.has(req.id);\n if (statusTag[1] === 'payment-required' && !bid && !isTargeted) {\n // Broadcast job without bid: a provider offered to work, but customer\n // hasn't committed. Keep \"processing\" because showing \"payment-required\"\n // would imply the customer chose this provider. The actual payment-required\n // transition happens via subscribeToJobUpdates() in real-time.\n } else {\n status = toJobStatus(statusTag[1]);\n }\n }\n }\n if (!amount) {\n const amtTag = feedback.tags.find((t) => t[0] === 'amount');\n amount = safeParseInt(amtTag?.[1]);\n }\n }\n\n jobs.push({\n eventId: req.id,\n customer: req.pubkey,\n agentPubkey: jobAgentPubkey,\n capability,\n bid: safeParseInt(bid),\n status,\n result: result?.content,\n resultEventId: result?.id,\n amount,\n txHash,\n createdAt: req.created_at,\n });\n }\n\n return jobs.sort((a, b) => b.createdAt - a.createdAt);\n }\n\n /** Subscribe to live elisym events (requests, results, feedback). */\n subscribeToEvents(kinds: number[], onEvent: (event: Event) => void): SubCloser {\n return this.pool.subscribe(\n {\n kinds,\n '#t': ['elisym'],\n since: Math.floor(Date.now() / 1000),\n } as Filter,\n (event) => {\n if (!verifyEvent(event)) {\n return;\n }\n onEvent(event);\n },\n );\n }\n}\n","/**\n * MediaService - NIP-98 authenticated file uploads to nostr.build.\n * Used for avatar, banner, and capability card images.\n */\nimport { finalizeEvent } from 'nostr-tools';\nimport type { ElisymIdentity } from '../primitives/identity';\n\nconst KIND_HTTP_AUTH = 27235;\nconst DEFAULT_UPLOAD_URL = 'https://nostr.build/api/v2/upload/files';\n\nexport class MediaService {\n constructor(private uploadUrl: string = DEFAULT_UPLOAD_URL) {}\n\n /**\n * Upload a file with NIP-98 authentication.\n * Works with browser File objects and Node.js/Bun Blobs.\n *\n * @param identity - Nostr identity used to sign the NIP-98 auth event.\n * @param file - File or Blob to upload.\n * @param filename - Optional filename for the upload (defaults to \"upload\").\n * @returns URL of the uploaded file.\n */\n async upload(identity: ElisymIdentity, file: Blob, filename?: string): Promise<string> {\n const hashBuffer = await crypto.subtle.digest('SHA-256', await file.arrayBuffer());\n const hashHex = [...new Uint8Array(hashBuffer)]\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n\n const authEvent = finalizeEvent(\n {\n kind: KIND_HTTP_AUTH,\n created_at: Math.floor(Date.now() / 1000),\n tags: [\n ['u', this.uploadUrl],\n ['method', 'POST'],\n ['payload', hashHex],\n ],\n content: '',\n },\n identity.secretKey,\n );\n\n const authHeader = 'Nostr ' + btoa(JSON.stringify(authEvent));\n\n const formData = new FormData();\n formData.append('file', file, filename ?? 'upload');\n\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), 30_000);\n try {\n const res = await fetch(this.uploadUrl, {\n method: 'POST',\n headers: { Authorization: authHeader },\n body: formData,\n signal: controller.signal,\n });\n\n if (!res.ok) {\n throw new Error(`Upload failed: ${res.status} ${res.statusText}`);\n }\n\n let data: { data?: { url?: string }[] };\n try {\n data = await res.json();\n } catch {\n throw new Error('Invalid response from upload service.');\n }\n const url = data?.data?.[0]?.url;\n if (!url) {\n throw new Error('No URL returned from upload service.');\n }\n return url;\n } finally {\n clearTimeout(timer);\n }\n }\n}\n","import { generateSecretKey, getPublicKey, nip19 } from 'nostr-tools';\n\nexport class ElisymIdentity {\n private _secretKey: Uint8Array;\n readonly publicKey: string;\n readonly npub: string;\n\n get secretKey(): Uint8Array {\n return new Uint8Array(this._secretKey);\n }\n\n private constructor(secretKey: Uint8Array) {\n this._secretKey = new Uint8Array(secretKey);\n this.publicKey = getPublicKey(secretKey);\n this.npub = nip19.npubEncode(this.publicKey);\n }\n\n static generate(): ElisymIdentity {\n return new ElisymIdentity(generateSecretKey());\n }\n\n static fromSecretKey(sk: Uint8Array): ElisymIdentity {\n if (sk.length !== 32) {\n throw new Error('Secret key must be exactly 32 bytes.');\n }\n return new ElisymIdentity(sk);\n }\n\n toJSON(): { publicKey: string; npub: string } {\n return { publicKey: this.publicKey, npub: this.npub };\n }\n\n /** Best-effort scrub of the secret key bytes in memory. */\n scrub(): void {\n this._secretKey.fill(0);\n }\n\n static fromHex(hex: string): ElisymIdentity {\n if (hex.length !== 64 || !/^[0-9a-fA-F]{64}$/.test(hex)) {\n throw new Error('Invalid secret key hex: expected 64 hex characters (32 bytes).');\n }\n const bytes = new Uint8Array(32);\n for (let i = 0; i < 64; i += 2) {\n bytes[i / 2] = parseInt(hex.substring(i, i + 2), 16);\n }\n return new ElisymIdentity(bytes);\n }\n}\n","import { finalizeEvent, verifyEvent } from 'nostr-tools';\nimport type { Filter } from 'nostr-tools';\nimport { KIND_PING, KIND_PONG, DEFAULTS } from '../constants';\nimport { ElisymIdentity } from '../primitives/identity';\nimport type { NostrPool } from '../transport/pool';\nimport type { PingResult, SubCloser } from '../types';\n\n/**\n * Ephemeral ping/pong service (kinds 20200/20201).\n *\n * Uses a session identity (random keypair) for ping operations to avoid\n * relay rate-limiting. The session identity persists for the lifetime of\n * this instance - recreating the service generates a new keypair.\n *\n * Requires `globalThis.crypto` (Node 20+, Bun, browsers).\n *\n * Lifetime / cleanup:\n * - The constructor registers a listener on `pool.onReset()` and never\n * unsubscribes. This is intentional: PingService is expected to share its\n * lifetime with the NostrPool it is bound to (both live for the lifetime\n * of an ElisymClient). If you ever construct a PingService that outlives\n * its pool - or vice versa - add an explicit `dispose()` that calls the\n * unsubscribe function returned by `pool.onReset()` to avoid leaking a\n * reference to this instance through the pool's listener set.\n * - `clearCache()` drops cached online results but does NOT cancel in-flight\n * pings in `pendingPings`. An in-flight ping started before a pool reset\n * may return `online: false` even if the new pool is healthy; the next\n * ping attempt will go through the fresh subscription and resolve\n * correctly.\n */\nexport class PingService {\n private static readonly PING_CACHE_MAX = 1000;\n private sessionIdentity: ElisymIdentity;\n private pingCache = new Map<string, number>(); // pubkey - timestamp of last online result\n private pendingPings = new Map<string, Promise<PingResult>>(); // dedup in-flight pings\n\n constructor(private pool: NostrPool) {\n this.sessionIdentity = ElisymIdentity.generate();\n // Cached \"online\" entries become misleading after a pool reconnect -\n // the new SimplePool has no verified reachability yet. Drop them.\n pool.onReset(() => this.clearCache());\n }\n\n /** Drop cached online results. In-flight pings are left alone - they'll\n * resolve via their own timeouts and remove themselves from `pendingPings`. */\n clearCache(): void {\n this.pingCache.clear();\n }\n\n /**\n * Ping an agent via ephemeral Nostr events (kind 20200/20201).\n * Uses a persistent session identity to avoid relay rate-limiting.\n * Publishes to ALL relays for maximum delivery reliability.\n * Caches results for 30s to prevent redundant publishes.\n */\n async pingAgent(\n agentPubkey: string,\n timeoutMs: number = DEFAULTS.PING_TIMEOUT_MS,\n signal?: AbortSignal,\n retries: number = DEFAULTS.PING_RETRIES,\n ): Promise<PingResult> {\n // Return cached online result if fresh enough (avoids relay rate-limiting)\n const cachedAt = this.pingCache.get(agentPubkey);\n if (cachedAt) {\n if (Date.now() - cachedAt < DEFAULTS.PING_CACHE_TTL_MS) {\n return { online: true, identity: this.sessionIdentity };\n }\n this.pingCache.delete(agentPubkey); // evict stale entry\n }\n\n // Lazy sweep: evict stale entries when cache is over half full\n if (this.pingCache.size > PingService.PING_CACHE_MAX / 2) {\n const now = Date.now();\n for (const [key, ts] of this.pingCache) {\n if (now - ts >= DEFAULTS.PING_CACHE_TTL_MS) {\n this.pingCache.delete(key);\n }\n }\n }\n\n // Dedup: return existing in-flight ping for same agent (React Strict Mode sends two)\n const pending = this.pendingPings.get(agentPubkey);\n if (pending) {\n return pending;\n }\n\n // Guard against unbounded pending pings\n if (this.pendingPings.size >= PingService.PING_CACHE_MAX) {\n return { online: false, identity: null };\n }\n\n const promise = this._doPingWithRetry(agentPubkey, timeoutMs, retries, signal);\n this.pendingPings.set(agentPubkey, promise);\n promise.finally(() => this.pendingPings.delete(agentPubkey));\n return promise;\n }\n\n private async _doPingWithRetry(\n agentPubkey: string,\n timeoutMs: number,\n retries: number,\n signal?: AbortSignal,\n ): Promise<PingResult> {\n // Split total timeout evenly across attempts\n const attempts = retries + 1;\n const perAttemptTimeout = Math.floor(timeoutMs / attempts);\n\n for (let i = 0; i < attempts; i++) {\n if (signal?.aborted) {\n return { online: false, identity: null };\n }\n const result = await this._doPing(agentPubkey, perAttemptTimeout, signal);\n if (result.online) {\n return result;\n }\n }\n return { online: false, identity: null };\n }\n\n private async _doPing(\n agentPubkey: string,\n timeoutMs: number,\n signal?: AbortSignal,\n ): Promise<PingResult> {\n const sk = this.sessionIdentity.secretKey;\n const pk = this.sessionIdentity.publicKey;\n\n const nonce = crypto\n .getRandomValues(new Uint8Array(16))\n .reduce((s, b) => s + b.toString(16).padStart(2, '0'), '');\n\n if (signal?.aborted) {\n return { online: false, identity: null };\n }\n\n let resolved = false;\n let sub: SubCloser | undefined;\n let timer: ReturnType<typeof setTimeout> | undefined;\n let resolvePing!: (result: PingResult) => void;\n\n const promise = new Promise<PingResult>((resolve) => {\n resolvePing = resolve;\n });\n\n const done = (online: boolean) => {\n if (resolved) {\n return;\n }\n resolved = true;\n if (timer) {\n clearTimeout(timer);\n }\n sub?.close();\n signal?.removeEventListener('abort', onAbort);\n if (online) {\n // Re-insert to move key to the tail of the Map's insertion order.\n // keys().next() below evicts the oldest entry, so we need this entry\n // to count as the newest. A plain set() on an existing key preserves\n // position, so the delete is load-bearing - do not \"simplify\" it away.\n this.pingCache.delete(agentPubkey);\n this.pingCache.set(agentPubkey, Date.now());\n if (this.pingCache.size > PingService.PING_CACHE_MAX) {\n const oldest = this.pingCache.keys().next().value;\n if (oldest !== undefined) {\n this.pingCache.delete(oldest);\n }\n }\n }\n resolvePing({ online, identity: online ? this.sessionIdentity : null });\n };\n\n const onAbort = () => done(false);\n signal?.addEventListener('abort', onAbort);\n\n // Start timeout BEFORE subscribeAndWait so total time per attempt is bounded by timeoutMs\n timer = setTimeout(() => done(false), timeoutMs);\n\n // Subscribe and wait for relay confirmation before publishing (ephemeral events require active subscription)\n try {\n sub = await this.pool.subscribeAndWait({ kinds: [KIND_PONG], '#p': [pk] } as Filter, (ev) => {\n if (!verifyEvent(ev)) {\n return;\n }\n if (ev.pubkey !== agentPubkey) {\n return;\n }\n try {\n const msg = JSON.parse(ev.content);\n if (\n msg.type === 'elisym_pong' &&\n typeof msg.nonce === 'string' &&\n msg.nonce.length === 32 &&\n msg.nonce === nonce\n ) {\n done(true);\n }\n } catch {\n /* ignore */\n }\n });\n } catch {\n done(false);\n return promise;\n }\n\n // The timer may have fired while we were awaiting subscribeAndWait: in that\n // case done(false) already ran, but `sub` was still undefined when it called\n // sub?.close(), so the subscription we just received above would leak on the\n // relay pool. Close it explicitly here.\n if (resolved) {\n sub?.close();\n return promise;\n }\n\n // Publish ephemeral ping to ALL relays - subscription is confirmed active\n const pingEvent = finalizeEvent(\n {\n kind: KIND_PING,\n created_at: Math.floor(Date.now() / 1000),\n tags: [['p', agentPubkey]],\n content: JSON.stringify({ type: 'elisym_ping', nonce }),\n },\n sk,\n );\n this.pool.publishAll(pingEvent).catch(() => {\n done(false);\n });\n\n return promise;\n }\n\n /**\n * Subscribe to incoming ephemeral ping events (kind 20200).\n * No `since` filter needed - ephemeral events are never stored.\n */\n subscribeToPings(\n identity: ElisymIdentity,\n onPing: (senderPubkey: string, nonce: string) => void,\n ): SubCloser {\n return this.pool.subscribe(\n { kinds: [KIND_PING], '#p': [identity.publicKey] } as Filter,\n (ev) => {\n if (!verifyEvent(ev)) {\n return;\n }\n try {\n const msg = JSON.parse(ev.content);\n if (\n msg.type === 'elisym_ping' &&\n typeof msg.nonce === 'string' &&\n msg.nonce.length === 32\n ) {\n onPing(ev.pubkey, msg.nonce);\n }\n } catch {\n /* ignore */\n }\n },\n );\n }\n\n /** Send an ephemeral pong response to ALL relays. */\n async sendPong(identity: ElisymIdentity, recipientPubkey: string, nonce: string): Promise<void> {\n const pongEvent = finalizeEvent(\n {\n kind: KIND_PONG,\n created_at: Math.floor(Date.now() / 1000),\n tags: [['p', recipientPubkey]],\n content: JSON.stringify({ type: 'elisym_pong', nonce }),\n },\n identity.secretKey,\n );\n await this.pool.publishAll(pongEvent);\n }\n}\n","/** A Set that evicts the oldest entries when it exceeds maxSize. Uses a ring buffer for O(1) eviction. */\nexport class BoundedSet<T> {\n private items: (T | undefined)[];\n private set = new Set<T>();\n private head = 0;\n private count = 0;\n constructor(private maxSize: number) {\n if (maxSize <= 0) {\n throw new Error('BoundedSet maxSize must be positive.');\n }\n this.items = new Array(maxSize);\n }\n has(item: T): boolean {\n return this.set.has(item);\n }\n add(item: T): void {\n if (this.set.has(item)) {\n return;\n }\n if (this.count >= this.maxSize) {\n const evicted = this.items[this.head]!;\n this.set.delete(evicted);\n } else {\n this.count++;\n }\n this.items[this.head] = item;\n this.head = (this.head + 1) % this.maxSize;\n this.set.add(item);\n }\n}\n","import { type Event, type Filter, SimplePool } from 'nostr-tools';\nimport { DEFAULTS, RELAYS } from '../constants';\nimport { BoundedSet } from '../primitives/bounded-set';\nimport type { SubCloser } from '../types';\n\nexport class NostrPool {\n private pool: SimplePool;\n private relays: string[];\n private activeSubscriptions = new Set<SubCloser>();\n private resetListeners = new Set<() => void>();\n\n constructor(relays: string[] = RELAYS) {\n this.pool = new SimplePool();\n this.relays = relays;\n }\n\n /**\n * Register a callback to run after `reset()` completes (new SimplePool in place).\n * Services that cache pool-derived state (e.g. ping results) must clear it here,\n * otherwise stale values survive the reconnect. Returns an unsubscribe function.\n *\n * Contract:\n * - Listeners are invoked **synchronously** at the end of `reset()`, in\n * registration order. Do not rely on async work inside a listener having\n * completed before `reset()` returns.\n * - Listener exceptions are caught and swallowed so that one faulty listener\n * cannot prevent the others from running (or abort the reset itself).\n * If a listener needs to surface errors, it must do so out-of-band.\n */\n onReset(listener: () => void): () => void {\n this.resetListeners.add(listener);\n return () => this.resetListeners.delete(listener);\n }\n\n /** Query relays synchronously. Returns `[]` on timeout (no error thrown). */\n async querySync(filter: Filter): Promise<Event[]> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const query = this.pool.querySync(this.relays, filter);\n query.catch(() => {}); // prevent unhandled rejection if timeout wins\n try {\n return await Promise.race([\n query,\n new Promise<Event[]>((resolve) => {\n timer = setTimeout(() => resolve([]), DEFAULTS.QUERY_TIMEOUT_MS);\n }),\n ]);\n } finally {\n clearTimeout(timer);\n }\n }\n\n async queryBatched(\n filter: Omit<Filter, 'authors'>,\n keys: string[],\n batchSize: number = DEFAULTS.BATCH_SIZE,\n maxConcurrency: number = DEFAULTS.QUERY_MAX_CONCURRENCY,\n ): Promise<Event[]> {\n const batchKeys: string[][] = [];\n for (let i = 0; i < keys.length; i += batchSize) {\n batchKeys.push(keys.slice(i, i + batchSize));\n }\n\n const results: Event[] = [];\n for (let c = 0; c < batchKeys.length; c += maxConcurrency) {\n const chunk = batchKeys.slice(c, c + maxConcurrency);\n const chunkResults = await Promise.all(\n chunk.map((batch) => {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const query = this.pool.querySync(this.relays, {\n ...filter,\n authors: batch,\n } as Filter);\n query.catch(() => {}); // prevent unhandled rejection if timeout wins\n return (async () => {\n try {\n return await Promise.race([\n query,\n new Promise<Event[]>((resolve) => {\n timer = setTimeout(() => resolve([]), DEFAULTS.QUERY_TIMEOUT_MS);\n }),\n ]);\n } finally {\n clearTimeout(timer);\n }\n })();\n }),\n );\n results.push(...chunkResults.flat());\n }\n return results;\n }\n\n async queryBatchedByTag(\n filter: Filter,\n tagName: string,\n values: string[],\n batchSize: number = DEFAULTS.BATCH_SIZE,\n maxConcurrency: number = DEFAULTS.QUERY_MAX_CONCURRENCY,\n ): Promise<Event[]> {\n const batchValues: string[][] = [];\n for (let i = 0; i < values.length; i += batchSize) {\n batchValues.push(values.slice(i, i + batchSize));\n }\n\n const results: Event[] = [];\n for (let c = 0; c < batchValues.length; c += maxConcurrency) {\n const chunk = batchValues.slice(c, c + maxConcurrency);\n const chunkResults = await Promise.all(\n chunk.map((batch) => {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const query = this.pool.querySync(this.relays, {\n ...filter,\n [`#${tagName}`]: batch,\n } as Filter);\n query.catch(() => {}); // prevent unhandled rejection if timeout wins\n return (async () => {\n try {\n return await Promise.race([\n query,\n new Promise<Event[]>((resolve) => {\n timer = setTimeout(() => resolve([]), DEFAULTS.QUERY_TIMEOUT_MS);\n }),\n ]);\n } finally {\n clearTimeout(timer);\n }\n })();\n }),\n );\n results.push(...chunkResults.flat());\n }\n return results;\n }\n\n async publish(event: Event): Promise<void> {\n try {\n await Promise.any(this.pool.publish(this.relays, event));\n } catch (err) {\n if (err instanceof AggregateError) {\n throw new Error(\n `Failed to publish to all ${this.relays.length} relays: ${err.errors.map((e: unknown) => (e instanceof Error ? e.message : String(e))).join(', ')}`,\n );\n }\n throw err;\n }\n }\n\n /** Publish to all relays and wait for all to settle. Throws if none accepted. */\n async publishAll(event: Event): Promise<void> {\n const results = await Promise.allSettled(this.pool.publish(this.relays, event));\n const anyOk = results.some((r) => r.status === 'fulfilled');\n if (!anyOk) {\n throw new Error(`Failed to publish to all ${this.relays.length} relays`);\n }\n }\n\n subscribe(filter: Filter, onEvent: (event: Event) => void): SubCloser {\n const rawSub = this.pool.subscribeMany(this.relays, filter, { onevent: onEvent });\n const tracked: SubCloser = {\n close: (reason?: string) => {\n this.activeSubscriptions.delete(tracked);\n rawSub.close(reason);\n },\n };\n this.activeSubscriptions.add(tracked);\n return tracked;\n }\n\n /**\n * Subscribe and wait until at least one relay confirms the subscription\n * is active (EOSE). Resolves on the first relay that responds.\n * Essential for ephemeral events where the subscription must be live\n * before publishing.\n *\n * Note: resolves on timeout even if no relay sent EOSE. The caller\n * cannot distinguish timeout from success - this is intentional for\n * best-effort ephemeral event delivery.\n */\n subscribeAndWait(\n filter: Filter,\n onEvent: (event: Event) => void,\n timeoutMs: number = DEFAULTS.EOSE_TIMEOUT_MS,\n ): Promise<SubCloser> {\n return new Promise((resolve) => {\n let resolved = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n const subs: SubCloser[] = [];\n const combinedSub: SubCloser = {\n close: (reason?: string) => {\n this.activeSubscriptions.delete(combinedSub);\n for (const s of subs) {\n s.close(reason);\n }\n },\n };\n this.activeSubscriptions.add(combinedSub);\n\n const done = () => {\n if (resolved) {\n return;\n }\n resolved = true;\n if (timer) {\n clearTimeout(timer);\n }\n resolve(combinedSub);\n };\n\n // Subscribe to each relay individually so we can resolve\n // as soon as the first relay sends EOSE (not waiting for all).\n // Dedup events by id since per-relay subscriptions bypass SimplePool dedup.\n const seen = new BoundedSet<string>(10_000);\n const dedupedOnEvent = (ev: Event) => {\n if (seen.has(ev.id)) {\n return;\n }\n seen.add(ev.id);\n onEvent(ev);\n };\n\n for (const relay of this.relays) {\n try {\n const sub = this.pool.subscribeMany([relay], filter, {\n onevent: dedupedOnEvent,\n oneose: done,\n });\n subs.push(sub);\n } catch {\n /* skip failed relay - handled by subs.length === 0 check below */\n }\n }\n\n // If all relays failed, resolve immediately\n if (subs.length === 0) {\n done();\n return;\n }\n\n if (!resolved) {\n timer = setTimeout(done, timeoutMs);\n }\n });\n }\n\n /**\n * Tear down pool and create a fresh one.\n * Works around nostr-tools `onerror - skipReconnection = true` bug\n * that permanently kills subscriptions. Callers must re-subscribe.\n */\n reset(): void {\n for (const sub of this.activeSubscriptions) {\n sub.close('pool reset');\n }\n this.activeSubscriptions.clear();\n try {\n this.pool.close(this.relays);\n } catch {\n /* ignore */\n }\n this.pool = new SimplePool();\n for (const listener of this.resetListeners) {\n try {\n listener();\n } catch {\n /* listener errors must not abort reset - other listeners still run */\n }\n }\n }\n\n /**\n * Lightweight connectivity probe. Returns true if at least one relay responds.\n */\n async probe(timeoutMs: number = DEFAULTS.EOSE_TIMEOUT_MS): Promise<boolean> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const query = this.pool.querySync(this.relays, { kinds: [0], limit: 1 } as Filter);\n query.catch(() => {}); // prevent unhandled rejection if timeout wins\n try {\n await Promise.race([\n query,\n new Promise<never>((_, reject) => {\n timer = setTimeout(() => reject(new Error('probe timeout')), timeoutMs);\n }),\n ]);\n return true;\n } catch {\n return false;\n } finally {\n clearTimeout(timer);\n }\n }\n\n getRelays(): string[] {\n return this.relays;\n }\n\n close(): void {\n for (const sub of this.activeSubscriptions) {\n sub.close('pool closed');\n }\n this.activeSubscriptions.clear();\n try {\n this.pool.close(this.relays);\n } catch {\n /* ignore - already disconnected */\n }\n }\n}\n","import { RELAYS } from './constants';\nimport { SolanaPaymentStrategy } from './payment/solana';\nimport type { PaymentStrategy } from './payment/strategy';\nimport { DiscoveryService } from './services/discovery';\nimport { MarketplaceService } from './services/marketplace';\nimport { MediaService } from './services/media';\nimport { PingService } from './services/ping';\nimport { NostrPool } from './transport/pool';\nimport type { ElisymClientConfig } from './types';\n\nexport interface ElisymClientFullConfig extends ElisymClientConfig {\n payment?: PaymentStrategy;\n /** Custom upload URL for file uploads (defaults to nostr.build). */\n uploadUrl?: string;\n}\n\nexport class ElisymClient {\n readonly pool: NostrPool;\n readonly discovery: DiscoveryService;\n readonly marketplace: MarketplaceService;\n readonly ping: PingService;\n readonly media: MediaService;\n readonly payment: PaymentStrategy;\n\n constructor(config: ElisymClientFullConfig = {}) {\n this.pool = new NostrPool(config.relays ?? RELAYS);\n this.discovery = new DiscoveryService(this.pool);\n this.marketplace = new MarketplaceService(this.pool);\n this.ping = new PingService(this.pool);\n this.media = new MediaService(config.uploadUrl);\n this.payment = config.payment ?? new SolanaPaymentStrategy();\n }\n\n close(): void {\n this.pool.close();\n }\n}\n","import Decimal from 'decimal.js-light';\nimport { LAMPORTS_PER_SOL } from '../constants';\n\nexport function formatSol(lamports: number): string {\n const sol = new Decimal(lamports).div(LAMPORTS_PER_SOL);\n if (sol.gte(1_000_000)) {\n return `${sol.idiv(1_000_000)}m SOL`;\n }\n if (sol.gte(10_000)) {\n return `${sol.idiv(1_000)}k SOL`;\n }\n return `${compactSol(sol)} SOL`;\n}\n\n/** Format a SOL Decimal - show enough decimals so the value isn't lost. */\nfunction compactSol(sol: Decimal): string {\n if (sol.isZero()) {\n return '0';\n }\n if (sol.gte(1000)) {\n return sol.toDecimalPlaces(0, Decimal.ROUND_FLOOR).toString();\n }\n // Show enough decimals so the rounded value equals the original\n const maxFrac = 9; // lamport precision\n for (let d = 1; d <= maxFrac; d++) {\n const s = sol.toFixed(d);\n if (new Decimal(s).eq(sol)) {\n return s.replace(/0+$/, '').replace(/\\.$/, '');\n }\n }\n return sol.toFixed(maxFrac).replace(/0+$/, '').replace(/\\.$/, '');\n}\n\nexport function timeAgo(unix: number): string {\n const seconds = Math.max(0, Math.floor(Date.now() / 1000 - unix));\n if (seconds < 60) {\n return `${seconds}s ago`;\n }\n const minutes = Math.floor(seconds / 60);\n if (minutes < 60) {\n return `${minutes}m ago`;\n }\n const hours = Math.floor(minutes / 60);\n if (hours < 24) {\n return `${hours}h ago`;\n }\n const days = Math.floor(hours / 24);\n return `${days}d ago`;\n}\n\nexport function truncateKey(hex: string, chars = 6): string {\n if (hex.length <= chars * 2) {\n return hex;\n }\n return `${hex.slice(0, chars)}...${hex.slice(-chars)}`;\n}\n","/**\n * Shared agent config - validation and serialization.\n * Browser-safe - no Node.js imports.\n * parseConfig lives in config-node.ts (exported from @elisym/sdk/node).\n */\n\nimport { LIMITS } from '../constants';\nimport type { AgentConfig } from '../types';\n\nexport function validateAgentName(name: string): void {\n if (!name || name.length > LIMITS.MAX_AGENT_NAME_LENGTH || !/^[a-zA-Z0-9_-]+$/.test(name)) {\n throw new Error('Agent name must be 1-64 characters, alphanumeric, underscore, or hyphen.');\n }\n}\n\n/** Serialize an AgentConfig to JSON string. */\nexport function serializeConfig(config: AgentConfig): string {\n return JSON.stringify(config, null, 2) + '\\n';\n}\n"]}
|