@elisym/sdk 0.7.0 → 0.8.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/dist/agent-store.cjs +4 -0
- package/dist/agent-store.cjs.map +1 -1
- package/dist/agent-store.d.cts +11 -9
- package/dist/agent-store.d.ts +11 -9
- package/dist/agent-store.js +4 -1
- package/dist/agent-store.js.map +1 -1
- package/dist/index.cjs +139 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +110 -1
- package/dist/index.d.ts +110 -1
- package/dist/index.js +128 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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/priorityFee.ts","../src/payment/schema.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","../src/primitives/rateLimiter.ts","../src/primitives/logRedact.ts"],"names":["address","getProgramDerivedAddress","Decimal","cache","getAddressDecoder","AccountRole","finalizeEvent","verifyEvent","nip19"],"mappings":"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","file":"index.js","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 type { Address, Rpc, SolanaRpcApi } from '@solana/kit';\n\nconst PRIORITY_FEE_FLOOR_MICROLAMPORTS = 1_000n;\nconst DEFAULT_PERCENTILE = 75;\nconst DEFAULT_CACHE_TTL_MS = 10_000;\n\ninterface CacheEntry {\n microLamports: bigint;\n expires: number;\n}\n\nconst cache = new Map<string, CacheEntry>();\n\nexport interface EstimatePriorityFeeOptions {\n /**\n * Percentile of the recent prioritization-fee distribution to charge.\n * 50 = median, 75 = upper quartile, 90 = aggressive. Defaults to 75.\n */\n percentile?: number;\n /**\n * Cache window in milliseconds. Subsequent calls within this window with the\n * same accounts will return the cached value. Defaults to 10s.\n */\n ttlMs?: number;\n /**\n * Optional account list passed to `getRecentPrioritizationFees` so the node\n * returns fees observed on writes touching these accounts. Empty = global.\n */\n accounts?: readonly Address[];\n}\n\n/**\n * Estimate a per-compute-unit priority fee from recent blocks, in\n * microLamports (1 microLamport = 0.000001 Lamports).\n *\n * Falls back to a 1000 microLamport floor when the RPC returns no samples\n * (typical on private clusters or under maintenance). Negative percentiles\n * are clamped to the median.\n *\n * Cached per accounts-key for `ttlMs` (default 10s) using the same\n * in-process cache pattern as `getProtocolConfig`.\n */\nexport async function estimatePriorityFeeMicroLamports(\n rpc: Rpc<SolanaRpcApi>,\n options?: EstimatePriorityFeeOptions,\n): Promise<bigint> {\n const percentile = clampPercentile(options?.percentile ?? DEFAULT_PERCENTILE);\n const ttl = options?.ttlMs ?? DEFAULT_CACHE_TTL_MS;\n const accounts = options?.accounts ?? [];\n const key = cacheKey(percentile, accounts);\n const now = Date.now();\n const cached = cache.get(key);\n if (cached && now < cached.expires) {\n return cached.microLamports;\n }\n\n const samples = await rpc.getRecentPrioritizationFees(accounts).send();\n const fee = pickPercentileFee(samples, percentile);\n cache.set(key, { microLamports: fee, expires: now + ttl });\n return fee;\n}\n\nexport function clearPriorityFeeCache(): void {\n cache.clear();\n}\n\ninterface RecentPrioritizationFeeLike {\n prioritizationFee: bigint | number;\n slot?: bigint | number;\n}\n\nexport function pickPercentileFee(\n samples: readonly RecentPrioritizationFeeLike[],\n percentile: number,\n): bigint {\n if (samples.length === 0) {\n return PRIORITY_FEE_FLOOR_MICROLAMPORTS;\n }\n const sorted = samples.map((sample) => BigInt(sample.prioritizationFee)).sort(compareBigInt);\n const clamped = clampPercentile(percentile);\n const indexFloat = ((clamped / 100) * (sorted.length - 1)) | 0;\n const value = sorted[indexFloat];\n return value > PRIORITY_FEE_FLOOR_MICROLAMPORTS ? value : PRIORITY_FEE_FLOOR_MICROLAMPORTS;\n}\n\nfunction clampPercentile(value: number): number {\n if (!Number.isFinite(value)) {\n return DEFAULT_PERCENTILE;\n }\n if (value < 0) {\n return 0;\n }\n if (value > 100) {\n return 100;\n }\n return value;\n}\n\nfunction compareBigInt(left: bigint, right: bigint): number {\n if (left < right) {\n return -1;\n }\n if (left > right) {\n return 1;\n }\n return 0;\n}\n\nfunction cacheKey(percentile: number, accounts: readonly Address[]): string {\n if (accounts.length === 0) {\n return `p:${percentile}`;\n }\n return `p:${percentile}:${[...accounts].sort().join(',')}`;\n}\n","import { z } from 'zod';\nimport { LIMITS } from '../constants';\n\nconst MAX_DESCRIPTION_LENGTH = LIMITS.MAX_DESCRIPTION_LENGTH;\nconst MAX_SAFE_LAMPORTS = Number.MAX_SAFE_INTEGER;\n// Hard cap on the schema-level expiry. The create path enforces a tighter\n// LIMITS.MAX_TIMEOUT_SECS (10 min) but historical providers may have\n// emitted longer expiries; we only refuse outright nonsense here.\nconst MAX_EXPIRY_SECS_SCHEMA = 86_400;\nconst BASE58_RE = /^[1-9A-HJ-NP-Za-km-z]+$/;\n// Solana addresses + reference keys are 32-byte ed25519 public keys, which\n// base58-encode to 32 - 44 characters. Tighter than naive `length>0`.\nconst SOLANA_ADDRESS_LENGTH_RE = /^.{32,44}$/;\n\nconst lamportsSchema = z\n .number()\n .int()\n .positive()\n .max(MAX_SAFE_LAMPORTS, `amount must be <= ${MAX_SAFE_LAMPORTS}`);\n\nconst feeAmountSchema = z\n .number()\n .int()\n .nonnegative()\n .max(MAX_SAFE_LAMPORTS, `fee_amount must be <= ${MAX_SAFE_LAMPORTS}`);\n\nconst solanaAddressSchema = z\n .string()\n .regex(BASE58_RE, 'must be base58')\n .regex(SOLANA_ADDRESS_LENGTH_RE, 'must be 32-44 base58 chars');\n\n/**\n * Wire-shape for a NIP-90 payment_request blob, as parsed via JSON.parse.\n *\n * Stricter than the loose TypeScript interface: rejects negative amounts,\n * floats, NaN/Infinity, mistyped recipient/reference, and any expiry\n * outside `[1, LIMITS.MAX_TIMEOUT_SECS]`. The strategy applies semantic\n * checks (recipient match, fee amount, expiry-vs-now) on top of this.\n */\nexport const PaymentRequestSchema = z.object({\n recipient: solanaAddressSchema,\n amount: lamportsSchema,\n reference: solanaAddressSchema,\n description: z.string().max(MAX_DESCRIPTION_LENGTH).optional(),\n fee_address: solanaAddressSchema.optional(),\n fee_amount: feeAmountSchema.optional(),\n created_at: z.number().int().positive(),\n expiry_secs: z\n .number()\n .int()\n .positive()\n .max(MAX_EXPIRY_SECS_SCHEMA, `expiry_secs must be <= ${MAX_EXPIRY_SECS_SCHEMA}`),\n});\n\nexport type ParsedPaymentRequest = z.infer<typeof PaymentRequestSchema>;\n\nexport interface ParseOptions {\n /** Optional max amount cap (lamports). Rejects requests that exceed it. */\n maxAmountLamports?: bigint;\n}\n\nexport interface ParseError {\n code: 'invalid_json' | 'schema' | 'amount_exceeds_max';\n message: string;\n}\n\nexport type ParseResult =\n | { ok: true; data: ParsedPaymentRequest }\n | { ok: false; error: ParseError };\n\n/**\n * Parse a JSON-encoded payment request through the Zod schema, optionally\n * enforcing a `maxAmountLamports` ceiling supplied by the caller (e.g. the\n * customer's per-job spending cap).\n */\nexport function parsePaymentRequest(input: string, options?: ParseOptions): ParseResult {\n let parsed: unknown;\n try {\n parsed = JSON.parse(input);\n } catch (e) {\n return {\n ok: false,\n error: { code: 'invalid_json', message: `Invalid payment request JSON: ${e}` },\n };\n }\n const result = PaymentRequestSchema.safeParse(parsed);\n if (!result.success) {\n return {\n ok: false,\n error: { code: 'schema', message: result.error.message },\n };\n }\n if (options?.maxAmountLamports !== undefined) {\n if (BigInt(result.data.amount) > options.maxAmountLamports) {\n return {\n ok: false,\n error: {\n code: 'amount_exceeds_max',\n message: `Payment amount ${result.data.amount} lamports exceeds approved max ${options.maxAmountLamports}.`,\n },\n };\n }\n }\n return { ok: true, data: result.data };\n}\n","import { getTransferSolInstruction } from '@solana-program/system';\nimport {\n type Address,\n type Rpc,\n type Signature,\n type SolanaRpcApi,\n AccountRole,\n address,\n appendTransactionMessageInstructions,\n createTransactionMessage,\n getAddressDecoder,\n isAddress,\n pipe,\n setTransactionMessageComputeUnitLimit,\n setTransactionMessageComputeUnitPrice,\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 { estimatePriorityFeeMicroLamports } from './priorityFee';\nimport { parsePaymentRequest } from './schema';\nimport type {\n BuildTransactionOptions,\n PaymentStrategy,\n ProtocolConfigInput,\n Signer,\n} from './strategy';\n\nconst DEFAULT_COMPUTE_UNIT_LIMIT = 200_000;\nconst DEFAULT_PRIORITY_FEE_PERCENTILE = 75;\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 options?: { maxAmountLamports?: bigint },\n ): PaymentValidationError | null {\n assertConfig(config);\n const parsed = parsePaymentRequest(requestJson, {\n maxAmountLamports: options?.maxAmountLamports,\n });\n if (!parsed.ok) {\n if (parsed.error.code === 'invalid_json') {\n return { code: 'invalid_json', message: parsed.error.message };\n }\n if (parsed.error.code === 'amount_exceeds_max') {\n return { code: 'invalid_amount', message: parsed.error.message };\n }\n // Schema-level rejections collapse into invalid_amount/recipient/etc\n // but the precise field is preserved in the message.\n return { code: 'invalid_amount', message: parsed.error.message };\n }\n const data: PaymentRequestData = parsed.data;\n\n // Defense in depth: the Zod schema only enforces base58 + length, not\n // the canonical 32-byte ed25519 check that `isAddress` performs.\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 (!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 // feeBps=0 is a legal on-chain state (set_fee_bps only enforces <= MAX_FEE_BPS).\n // createPaymentRequest still populates fee_address=treasury and fee_amount=0 in\n // that case, which does not match either of the hasFee branches below. Mirror the\n // `expectedFee > 0` guard in verifyPayment so both code paths agree.\n if (expectedFee === 0) {\n return null;\n }\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: Signer,\n rpc: Rpc<SolanaRpcApi>,\n config: ProtocolConfigInput,\n options?: BuildTransactionOptions,\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 computeUnitLimit = options?.computeUnitLimit ?? DEFAULT_COMPUTE_UNIT_LIMIT;\n if (!Number.isInteger(computeUnitLimit) || computeUnitLimit <= 0) {\n throw new Error(`Invalid computeUnitLimit: ${computeUnitLimit}. Must be a positive integer.`);\n }\n // Build payment instructions first - this is synchronous and surfaces\n // shape errors (e.g. fee >= amount) before any RPC round-trip.\n const paymentInstructions = buildPaymentInstructions(paymentRequest, payerSigner);\n\n const priorityFeeMicroLamports =\n options?.priorityFeeMicroLamports ??\n (await estimatePriorityFeeMicroLamports(rpc, {\n percentile: options?.priorityFeePercentile ?? DEFAULT_PRIORITY_FEE_PERCENTILE,\n }));\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) => setTransactionMessageComputeUnitLimit(computeUnitLimit, m),\n (m) => setTransactionMessageComputeUnitPrice(priorityFeeMicroLamports, m),\n (m) =>\n appendTransactionMessageInstructions(\n paymentInstructions 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: Signer,\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 * Agent-name validation shared between CLI and MCP.\n * Browser-safe - no Node.js imports.\n */\n\nimport { LIMITS } from '../constants';\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 * Sliding-window rate limiter keyed by an arbitrary string (typically a\n * customer pubkey). Each key gets at most `maxPerWindow` requests inside a\n * rolling `windowMs`. Stale timestamps are pruned lazily on every `check`.\n * When the tracked-key set grows past `maxKeys`, the least-recently-used\n * key is evicted so an attacker cannot exhaust memory by cycling keys.\n *\n * Thread-safety: not required. Designed for single-threaded JS consumers\n * (Node/Bun event loops, browser main thread). No timers - pruning happens\n * inside `check` and `prune`.\n */\n\nexport interface SlidingWindowLimiterOptions {\n /** Rolling window width, in ms. */\n windowMs: number;\n /** Max hits allowed per key inside the window. */\n maxPerWindow: number;\n /** Cap on total tracked keys. LRU-evicted past this cap. */\n maxKeys: number;\n}\n\nexport interface RateLimitDecision {\n allowed: boolean;\n /** Wall-clock timestamp (ms) when the limit window will reset for this key. */\n resetAt: number;\n /** Number of hits inside the current window after this call (or the attempted hit if denied). */\n count: number;\n}\n\nexport interface SlidingWindowLimiter {\n /** Record a hit against `key`; return whether it was allowed. */\n check(key: string, now?: number): RateLimitDecision;\n /**\n * Inspect the current state for `key` without recording a hit. Useful\n * when a single request must clear multiple limiters and callers want\n * to avoid double-counting against one limiter after another denies.\n */\n peek(key: string, now?: number): RateLimitDecision;\n /** Drop entries whose windows have fully elapsed. Bounded memory hygiene. */\n prune(now?: number): void;\n /** Current number of tracked keys. */\n size(): number;\n /** Clear all state. */\n reset(): void;\n}\n\ninterface Entry {\n /** Sliding-window timestamps in ms. Sorted ascending. */\n hits: number[];\n}\n\nexport function createSlidingWindowLimiter(\n options: SlidingWindowLimiterOptions,\n): SlidingWindowLimiter {\n const { windowMs, maxPerWindow, maxKeys } = options;\n if (windowMs <= 0) {\n throw new RangeError('windowMs must be > 0');\n }\n if (maxPerWindow <= 0) {\n throw new RangeError('maxPerWindow must be > 0');\n }\n if (maxKeys <= 0) {\n throw new RangeError('maxKeys must be > 0');\n }\n\n // LRU is implemented via Map's insertion-order: every check refreshes\n // the entry by deleting and re-setting it, moving it to the tail.\n const entries = new Map<string, Entry>();\n\n function evictIfNeeded(): void {\n while (entries.size > maxKeys) {\n const oldestKey = entries.keys().next().value as string | undefined;\n if (oldestKey === undefined) {\n return;\n }\n entries.delete(oldestKey);\n }\n }\n\n return {\n peek(key, now = Date.now()): RateLimitDecision {\n const entry = entries.get(key);\n if (!entry) {\n return { allowed: true, resetAt: now + windowMs, count: 0 };\n }\n const cutoff = now - windowMs;\n const fresh = entry.hits.filter((timestamp) => timestamp > cutoff);\n return {\n allowed: fresh.length < maxPerWindow,\n resetAt: (fresh[0] ?? now) + windowMs,\n count: fresh.length,\n };\n },\n check(key, now = Date.now()): RateLimitDecision {\n const entry = entries.get(key) ?? { hits: [] };\n const cutoff = now - windowMs;\n const fresh = entry.hits.filter((timestamp) => timestamp > cutoff);\n\n if (fresh.length >= maxPerWindow) {\n // Refresh LRU order even on denial so an attacker hammering the\n // same key cannot push other tracked keys out via eviction.\n entries.delete(key);\n entries.set(key, { hits: fresh });\n return {\n allowed: false,\n resetAt: (fresh[0] ?? now) + windowMs,\n count: fresh.length,\n };\n }\n fresh.push(now);\n entries.delete(key);\n entries.set(key, { hits: fresh });\n evictIfNeeded();\n return {\n allowed: true,\n resetAt: (fresh[0] ?? now) + windowMs,\n count: fresh.length,\n };\n },\n prune(now = Date.now()): void {\n const cutoff = now - windowMs;\n for (const [key, entry] of entries) {\n const fresh = entry.hits.filter((timestamp) => timestamp > cutoff);\n if (fresh.length === 0) {\n entries.delete(key);\n } else if (fresh.length !== entry.hits.length) {\n entry.hits = fresh;\n }\n }\n },\n size(): number {\n return entries.size;\n },\n reset(): void {\n entries.clear();\n },\n };\n}\n","/**\n * Canonical pino redact paths for the elisym stack. Plugin, CLI, MCP, and\n * any downstream integrator should consume these arrays directly - one\n * source of truth for \"fields that carry user input or secrets\".\n *\n * Wire them into a pino instance like:\n *\n * import pino from 'pino';\n * import { DEFAULT_REDACT_PATHS, makeCensor } from '@elisym/sdk';\n * const logger = pino({\n * redact: { paths: DEFAULT_REDACT_PATHS, censor: makeCensor() },\n * });\n */\n\n/**\n * Field paths that carry Nostr / Solana secret keys or operator secrets.\n * Censored as `[REDACTED]`.\n */\nexport const SECRET_REDACT_PATHS: string[] = [\n '*.ELISYM_NOSTR_PRIVATE_KEY',\n '*.ELISYM_SOLANA_PRIVATE_KEY',\n '*.nostrPrivateKeyHex',\n '*.solanaPrivateKeyBase58',\n '*.secretKey',\n '*.secret',\n 'ELISYM_NOSTR_PRIVATE_KEY',\n 'ELISYM_SOLANA_PRIVATE_KEY',\n // Canonical on-disk `.secrets.json` field names. Logging the whole\n // `secrets` object, or any single field directly, must not leak.\n 'llm_api_key',\n 'nostr_secret_key',\n 'solana_secret_key',\n '*.llm_api_key',\n '*.nostr_secret_key',\n '*.solana_secret_key',\n 'secrets',\n '*.secrets',\n];\n\n/**\n * Field paths that carry customer-confidential text (LLM prompts, raw\n * event content, job input). Censored as `[INPUT REDACTED]` so log\n * readers can distinguish redacted input from redacted secrets.\n */\nexport const INPUT_REDACT_PATHS: string[] = [\n 'content',\n 'input',\n 'prompt',\n '*.content',\n '*.input',\n '*.prompt',\n 'event.content',\n '*.event.content',\n // JobLedger entries carry the raw Nostr event JSON (which embeds\n // `event.content`) and the full LLM `resultContent` - both are\n // customer-confidential and must never land in a structured log.\n 'rawEventJson',\n 'resultContent',\n '*.rawEventJson',\n '*.resultContent',\n];\n\n/**\n * Union of the two arrays, in the order pino's redact engine should\n * visit them. Prefer this when wiring a new logger so no downstream\n * consumer forgets half the set.\n */\nexport const DEFAULT_REDACT_PATHS: string[] = [...SECRET_REDACT_PATHS, ...INPUT_REDACT_PATHS];\n\n/**\n * pino `redact.censor` callback. Returns the appropriate marker string\n * based on the final segment of the redacted path.\n *\n * pino calls `censor(value, path)` where `path` is `string[]`. Plugin's\n * historical signature accepted `(_value, path)` with that shape; we\n * preserve that. Pino types vary across versions, so we accept unknown\n * and narrow.\n */\nconst INPUT_REDACT_LEAVES = new Set([\n 'content',\n 'input',\n 'prompt',\n 'rawEventJson',\n 'resultContent',\n]);\n\nexport function makeCensor(): (value: unknown, path: string[]) => string {\n return (_value, path) => {\n const last = path[path.length - 1];\n if (last !== undefined && INPUT_REDACT_LEAVES.has(last)) {\n return '[INPUT REDACTED]';\n }\n return '[REDACTED]';\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/priorityFee.ts","../src/payment/schema.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/payment/assets.ts","../src/agent-store/writer.ts","../src/config/global.ts","../src/primitives/format.ts","../src/primitives/config.ts","../src/primitives/rateLimiter.ts","../src/primitives/logRedact.ts"],"names":["address","getProgramDerivedAddress","Decimal","cache","getAddressDecoder","AccountRole","finalizeEvent","verifyEvent","nip19","z","YAML"],"mappings":"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","file":"index.js","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 type { Address, Rpc, SolanaRpcApi } from '@solana/kit';\n\nconst PRIORITY_FEE_FLOOR_MICROLAMPORTS = 1_000n;\nconst DEFAULT_PERCENTILE = 75;\nconst DEFAULT_CACHE_TTL_MS = 10_000;\n\ninterface CacheEntry {\n microLamports: bigint;\n expires: number;\n}\n\nconst cache = new Map<string, CacheEntry>();\n\nexport interface EstimatePriorityFeeOptions {\n /**\n * Percentile of the recent prioritization-fee distribution to charge.\n * 50 = median, 75 = upper quartile, 90 = aggressive. Defaults to 75.\n */\n percentile?: number;\n /**\n * Cache window in milliseconds. Subsequent calls within this window with the\n * same accounts will return the cached value. Defaults to 10s.\n */\n ttlMs?: number;\n /**\n * Optional account list passed to `getRecentPrioritizationFees` so the node\n * returns fees observed on writes touching these accounts. Empty = global.\n */\n accounts?: readonly Address[];\n}\n\n/**\n * Estimate a per-compute-unit priority fee from recent blocks, in\n * microLamports (1 microLamport = 0.000001 Lamports).\n *\n * Falls back to a 1000 microLamport floor when the RPC returns no samples\n * (typical on private clusters or under maintenance). Negative percentiles\n * are clamped to the median.\n *\n * Cached per accounts-key for `ttlMs` (default 10s) using the same\n * in-process cache pattern as `getProtocolConfig`.\n */\nexport async function estimatePriorityFeeMicroLamports(\n rpc: Rpc<SolanaRpcApi>,\n options?: EstimatePriorityFeeOptions,\n): Promise<bigint> {\n const percentile = clampPercentile(options?.percentile ?? DEFAULT_PERCENTILE);\n const ttl = options?.ttlMs ?? DEFAULT_CACHE_TTL_MS;\n const accounts = options?.accounts ?? [];\n const key = cacheKey(percentile, accounts);\n const now = Date.now();\n const cached = cache.get(key);\n if (cached && now < cached.expires) {\n return cached.microLamports;\n }\n\n const samples = await rpc.getRecentPrioritizationFees(accounts).send();\n const fee = pickPercentileFee(samples, percentile);\n cache.set(key, { microLamports: fee, expires: now + ttl });\n return fee;\n}\n\nexport function clearPriorityFeeCache(): void {\n cache.clear();\n}\n\ninterface RecentPrioritizationFeeLike {\n prioritizationFee: bigint | number;\n slot?: bigint | number;\n}\n\nexport function pickPercentileFee(\n samples: readonly RecentPrioritizationFeeLike[],\n percentile: number,\n): bigint {\n if (samples.length === 0) {\n return PRIORITY_FEE_FLOOR_MICROLAMPORTS;\n }\n const sorted = samples.map((sample) => BigInt(sample.prioritizationFee)).sort(compareBigInt);\n const clamped = clampPercentile(percentile);\n const indexFloat = ((clamped / 100) * (sorted.length - 1)) | 0;\n const value = sorted[indexFloat];\n return value > PRIORITY_FEE_FLOOR_MICROLAMPORTS ? value : PRIORITY_FEE_FLOOR_MICROLAMPORTS;\n}\n\nfunction clampPercentile(value: number): number {\n if (!Number.isFinite(value)) {\n return DEFAULT_PERCENTILE;\n }\n if (value < 0) {\n return 0;\n }\n if (value > 100) {\n return 100;\n }\n return value;\n}\n\nfunction compareBigInt(left: bigint, right: bigint): number {\n if (left < right) {\n return -1;\n }\n if (left > right) {\n return 1;\n }\n return 0;\n}\n\nfunction cacheKey(percentile: number, accounts: readonly Address[]): string {\n if (accounts.length === 0) {\n return `p:${percentile}`;\n }\n return `p:${percentile}:${[...accounts].sort().join(',')}`;\n}\n","import { z } from 'zod';\nimport { LIMITS } from '../constants';\n\nconst MAX_DESCRIPTION_LENGTH = LIMITS.MAX_DESCRIPTION_LENGTH;\nconst MAX_SAFE_LAMPORTS = Number.MAX_SAFE_INTEGER;\n// Hard cap on the schema-level expiry. The create path enforces a tighter\n// LIMITS.MAX_TIMEOUT_SECS (10 min) but historical providers may have\n// emitted longer expiries; we only refuse outright nonsense here.\nconst MAX_EXPIRY_SECS_SCHEMA = 86_400;\nconst BASE58_RE = /^[1-9A-HJ-NP-Za-km-z]+$/;\n// Solana addresses + reference keys are 32-byte ed25519 public keys, which\n// base58-encode to 32 - 44 characters. Tighter than naive `length>0`.\nconst SOLANA_ADDRESS_LENGTH_RE = /^.{32,44}$/;\n\nconst lamportsSchema = z\n .number()\n .int()\n .positive()\n .max(MAX_SAFE_LAMPORTS, `amount must be <= ${MAX_SAFE_LAMPORTS}`);\n\nconst feeAmountSchema = z\n .number()\n .int()\n .nonnegative()\n .max(MAX_SAFE_LAMPORTS, `fee_amount must be <= ${MAX_SAFE_LAMPORTS}`);\n\nconst solanaAddressSchema = z\n .string()\n .regex(BASE58_RE, 'must be base58')\n .regex(SOLANA_ADDRESS_LENGTH_RE, 'must be 32-44 base58 chars');\n\n/**\n * Wire-shape for a NIP-90 payment_request blob, as parsed via JSON.parse.\n *\n * Stricter than the loose TypeScript interface: rejects negative amounts,\n * floats, NaN/Infinity, mistyped recipient/reference, and any expiry\n * outside `[1, LIMITS.MAX_TIMEOUT_SECS]`. The strategy applies semantic\n * checks (recipient match, fee amount, expiry-vs-now) on top of this.\n */\nexport const PaymentRequestSchema = z.object({\n recipient: solanaAddressSchema,\n amount: lamportsSchema,\n reference: solanaAddressSchema,\n description: z.string().max(MAX_DESCRIPTION_LENGTH).optional(),\n fee_address: solanaAddressSchema.optional(),\n fee_amount: feeAmountSchema.optional(),\n created_at: z.number().int().positive(),\n expiry_secs: z\n .number()\n .int()\n .positive()\n .max(MAX_EXPIRY_SECS_SCHEMA, `expiry_secs must be <= ${MAX_EXPIRY_SECS_SCHEMA}`),\n});\n\nexport type ParsedPaymentRequest = z.infer<typeof PaymentRequestSchema>;\n\nexport interface ParseOptions {\n /** Optional max amount cap (lamports). Rejects requests that exceed it. */\n maxAmountLamports?: bigint;\n}\n\nexport interface ParseError {\n code: 'invalid_json' | 'schema' | 'amount_exceeds_max';\n message: string;\n}\n\nexport type ParseResult =\n | { ok: true; data: ParsedPaymentRequest }\n | { ok: false; error: ParseError };\n\n/**\n * Parse a JSON-encoded payment request through the Zod schema, optionally\n * enforcing a `maxAmountLamports` ceiling supplied by the caller (e.g. the\n * customer's per-job spending cap).\n */\nexport function parsePaymentRequest(input: string, options?: ParseOptions): ParseResult {\n let parsed: unknown;\n try {\n parsed = JSON.parse(input);\n } catch (e) {\n return {\n ok: false,\n error: { code: 'invalid_json', message: `Invalid payment request JSON: ${e}` },\n };\n }\n const result = PaymentRequestSchema.safeParse(parsed);\n if (!result.success) {\n return {\n ok: false,\n error: { code: 'schema', message: result.error.message },\n };\n }\n if (options?.maxAmountLamports !== undefined) {\n if (BigInt(result.data.amount) > options.maxAmountLamports) {\n return {\n ok: false,\n error: {\n code: 'amount_exceeds_max',\n message: `Payment amount ${result.data.amount} lamports exceeds approved max ${options.maxAmountLamports}.`,\n },\n };\n }\n }\n return { ok: true, data: result.data };\n}\n","import { getTransferSolInstruction } from '@solana-program/system';\nimport {\n type Address,\n type Rpc,\n type Signature,\n type SolanaRpcApi,\n AccountRole,\n address,\n appendTransactionMessageInstructions,\n createTransactionMessage,\n getAddressDecoder,\n isAddress,\n pipe,\n setTransactionMessageComputeUnitLimit,\n setTransactionMessageComputeUnitPrice,\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 { estimatePriorityFeeMicroLamports } from './priorityFee';\nimport { parsePaymentRequest } from './schema';\nimport type {\n BuildTransactionOptions,\n PaymentStrategy,\n ProtocolConfigInput,\n Signer,\n} from './strategy';\n\nconst DEFAULT_COMPUTE_UNIT_LIMIT = 200_000;\nconst DEFAULT_PRIORITY_FEE_PERCENTILE = 75;\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 options?: { maxAmountLamports?: bigint },\n ): PaymentValidationError | null {\n assertConfig(config);\n const parsed = parsePaymentRequest(requestJson, {\n maxAmountLamports: options?.maxAmountLamports,\n });\n if (!parsed.ok) {\n if (parsed.error.code === 'invalid_json') {\n return { code: 'invalid_json', message: parsed.error.message };\n }\n if (parsed.error.code === 'amount_exceeds_max') {\n return { code: 'invalid_amount', message: parsed.error.message };\n }\n // Schema-level rejections collapse into invalid_amount/recipient/etc\n // but the precise field is preserved in the message.\n return { code: 'invalid_amount', message: parsed.error.message };\n }\n const data: PaymentRequestData = parsed.data;\n\n // Defense in depth: the Zod schema only enforces base58 + length, not\n // the canonical 32-byte ed25519 check that `isAddress` performs.\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 (!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 // feeBps=0 is a legal on-chain state (set_fee_bps only enforces <= MAX_FEE_BPS).\n // createPaymentRequest still populates fee_address=treasury and fee_amount=0 in\n // that case, which does not match either of the hasFee branches below. Mirror the\n // `expectedFee > 0` guard in verifyPayment so both code paths agree.\n if (expectedFee === 0) {\n return null;\n }\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: Signer,\n rpc: Rpc<SolanaRpcApi>,\n config: ProtocolConfigInput,\n options?: BuildTransactionOptions,\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 computeUnitLimit = options?.computeUnitLimit ?? DEFAULT_COMPUTE_UNIT_LIMIT;\n if (!Number.isInteger(computeUnitLimit) || computeUnitLimit <= 0) {\n throw new Error(`Invalid computeUnitLimit: ${computeUnitLimit}. Must be a positive integer.`);\n }\n // Build payment instructions first - this is synchronous and surfaces\n // shape errors (e.g. fee >= amount) before any RPC round-trip.\n const paymentInstructions = buildPaymentInstructions(paymentRequest, payerSigner);\n\n const priorityFeeMicroLamports =\n options?.priorityFeeMicroLamports ??\n (await estimatePriorityFeeMicroLamports(rpc, {\n percentile: options?.priorityFeePercentile ?? DEFAULT_PRIORITY_FEE_PERCENTILE,\n }));\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) => setTransactionMessageComputeUnitLimit(computeUnitLimit, m),\n (m) => setTransactionMessageComputeUnitPrice(priorityFeeMicroLamports, m),\n (m) =>\n appendTransactionMessageInstructions(\n paymentInstructions 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: Signer,\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","/**\n * Multi-asset / multi-chain payment model.\n *\n * `Asset` describes a currency a customer can spend: native coins (SOL, ETH, BTC)\n * or tokens (SPL, ERC-20). `assetKey` produces a stable string id for Map lookups.\n *\n * Today only `NATIVE_SOL` is in `KNOWN_ASSETS`. SPL (USDC) and other chains are\n * extended by adding entries to `KNOWN_ASSETS` and, where relevant, to the\n * MCP `DEFAULT_SESSION_LIMITS` catalogue.\n */\n\nexport type Chain = 'solana';\n\nexport interface Asset {\n chain: Chain;\n /** Lowercase token id: 'sol', 'usdc', 'btc', 'eth'. */\n token: string;\n /** SPL mint / ERC-20 contract. Undefined for a native coin. */\n mint?: string;\n /** Subunits per whole (9 SOL, 6 USDC, 8 BTC, 18 ETH). */\n decimals: number;\n /** Display symbol: 'SOL', 'USDC'. */\n symbol: string;\n}\n\nexport const NATIVE_SOL: Asset = {\n chain: 'solana',\n token: 'sol',\n decimals: 9,\n symbol: 'SOL',\n};\n\n// When SPL-token support lands in the payment strategy, uncomment and add to KNOWN_ASSETS.\n// export const USDC_SOLANA_DEVNET: Asset = {\n// chain: 'solana',\n// token: 'usdc',\n// mint: '4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU',\n// decimals: 6,\n// symbol: 'USDC',\n// };\n\nexport const KNOWN_ASSETS: readonly Asset[] = [NATIVE_SOL];\n\n/** Stable Map key for `Asset`. Same shape regardless of Asset identity. */\nexport function assetKey(a: Pick<Asset, 'chain' | 'token' | 'mint'>): string {\n return a.mint ? `${a.chain}:${a.token}:${a.mint}` : `${a.chain}:${a.token}`;\n}\n\n/** Find a known asset by (chain, token, mint). Returns undefined if unknown. */\nexport function resolveKnownAsset(chain: string, token: string, mint?: string): Asset | undefined {\n const key = mint ? `${chain}:${token}:${mint}` : `${chain}:${token}`;\n return KNOWN_ASSETS.find((asset) => assetKey(asset) === key);\n}\n\n/** Reverse lookup: given an assetKey string, return the known asset or undefined. */\nexport function assetByKey(key: string): Asset | undefined {\n return KNOWN_ASSETS.find((asset) => assetKey(asset) === key);\n}\n\nconst DECIMAL_RE = /^(\\d+\\.\\d*|\\d*\\.\\d+|\\d+)$/;\n\n/**\n * Parse a human amount string (\"0.5\", \"1\", \"0.000001\") into raw subunits (BigInt).\n * Uses integer math to avoid float precision issues.\n *\n * Throws on: empty, negative, zero, malformed, too many fractional digits, or\n * a value exceeding `Number.MAX_SAFE_INTEGER` (to keep downstream `Number(...)`\n * call-sites safe).\n */\nexport function parseAssetAmount(asset: Asset, human: string): bigint {\n const trimmed = human.trim();\n if (!trimmed) {\n throw new Error(`${asset.symbol} amount is empty`);\n }\n if (trimmed.startsWith('-')) {\n throw new Error(`${asset.symbol} amount cannot be negative`);\n }\n if (!DECIMAL_RE.test(trimmed)) {\n throw new Error(\n `${asset.symbol} amount must be a non-negative decimal (e.g. \"0.5\", \"1\"); got \"${human}\"`,\n );\n }\n\n const dotPos = trimmed.indexOf('.');\n let wholePart: string;\n if (dotPos === -1) {\n wholePart = trimmed;\n } else if (dotPos === 0) {\n wholePart = '0';\n } else {\n wholePart = trimmed.slice(0, dotPos);\n }\n const fracPart = dotPos === -1 ? '' : trimmed.slice(dotPos + 1);\n\n if (fracPart.length > asset.decimals) {\n throw new Error(\n `${asset.symbol} amount has too many decimals (max ${asset.decimals}); got \"${human}\"`,\n );\n }\n\n const unit = 10n ** BigInt(asset.decimals);\n const whole = BigInt(wholePart);\n const frac = fracPart ? BigInt(fracPart.padEnd(asset.decimals, '0')) : 0n;\n const raw = whole * unit + frac;\n\n if (raw === 0n) {\n throw new Error(`${asset.symbol} amount must be positive; got \"${human}\"`);\n }\n if (raw > BigInt(Number.MAX_SAFE_INTEGER)) {\n throw new Error(\n `${asset.symbol} amount exceeds safe range (max ${Number.MAX_SAFE_INTEGER} subunits)`,\n );\n }\n return raw;\n}\n\n/** Format raw subunits back to `\"<whole>.<frac> <SYMBOL>\"`. Keeps all `decimals` digits. */\nexport function formatAssetAmount(asset: Asset, raw: bigint): string {\n const sign = raw < 0n ? '-' : '';\n const abs = raw < 0n ? -raw : raw;\n const unit = 10n ** BigInt(asset.decimals);\n const whole = abs / unit;\n const frac = abs % unit;\n if (asset.decimals === 0) {\n return `${sign}${whole} ${asset.symbol}`;\n }\n return `${sign}${whole}.${frac.toString().padStart(asset.decimals, '0')} ${asset.symbol}`;\n}\n","/**\n * Write agent files: elisym.yaml, .secrets.json, .gitignore, and create agent dirs.\n */\n\nimport { randomBytes } from 'node:crypto';\nimport { mkdir, rename, writeFile } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport YAML from 'yaml';\nimport { encryptSecret, isEncrypted } from '../primitives/encryption';\nimport { agentPaths, type AgentPaths } from './paths';\nimport { elisymRootFor, type AgentSource } from './resolver';\nimport { ElisymYamlSchema, SecretsSchema, type ElisymYaml, type Secrets } from './schema';\n\nconst GITIGNORE_CONTENT = [\n '# elisym private state - do not commit.',\n '.secrets.json',\n '.media-cache.json',\n '.jobs.json',\n '.jobs.json.corrupt.*',\n '',\n].join('\\n');\n\nexport interface CreateAgentDirOptions {\n target: AgentSource;\n name: string;\n cwd: string;\n /**\n * For `target: 'project'`: if no .elisym/ dir exists above cwd,\n * where should we create one? Defaults to cwd.\n */\n projectRoot?: string;\n}\n\nexport interface CreatedAgentDir {\n dir: string;\n paths: AgentPaths;\n source: AgentSource;\n createdNewElisymRoot: boolean;\n}\n\n/**\n * Create (or reuse) the directory layout for a new agent. Idempotent: if the\n * agent directory already exists, returns its paths without overwriting.\n * Writes `.gitignore` in project-local .elisym/ on first creation.\n */\nexport async function createAgentDir(options: CreateAgentDirOptions): Promise<CreatedAgentDir> {\n const { target, name, cwd, projectRoot } = options;\n\n const existingRoot = elisymRootFor(target, cwd);\n let elisymRoot: string;\n let createdNewElisymRoot = false;\n\n if (existingRoot) {\n elisymRoot = existingRoot;\n } else if (target === 'project') {\n elisymRoot = join(projectRoot ?? cwd, '.elisym');\n createdNewElisymRoot = true;\n } else {\n throw new Error('homeElisymDir should always exist conceptually - this is unreachable');\n }\n\n const agentDir = join(elisymRoot, name);\n const mode = target === 'home' ? 0o700 : 0o755;\n await mkdir(agentDir, { recursive: true, mode });\n await mkdir(join(agentDir, 'skills'), { recursive: true, mode });\n\n if (target === 'project') {\n const gitignorePath = join(elisymRoot, '.gitignore');\n await writeFileIfMissing(gitignorePath, GITIGNORE_CONTENT, 0o644);\n }\n\n return {\n dir: agentDir,\n paths: agentPaths(agentDir),\n source: target,\n createdNewElisymRoot,\n };\n}\n\n/** Write elisym.yaml atomically. Validates via Zod before writing. */\nexport async function writeYaml(agentDir: string, yaml: ElisymYaml): Promise<void> {\n const validated = ElisymYamlSchema.parse(yaml);\n const body = YAML.stringify(validated);\n const target = agentPaths(agentDir).yaml;\n await writeFileAtomic(target, body, 0o644);\n}\n\n/**\n * Write .secrets.json atomically. If `passphrase` is given, encrypts all\n * plaintext secret fields (already-encrypted values are left as-is).\n */\nexport async function writeSecrets(\n agentDir: string,\n secrets: Secrets,\n passphrase?: string,\n): Promise<void> {\n const validated = SecretsSchema.parse(secrets);\n const finalSecrets: Secrets = {\n ...validated,\n nostr_secret_key: maybeEncrypt(validated.nostr_secret_key, passphrase),\n solana_secret_key: validated.solana_secret_key\n ? maybeEncrypt(validated.solana_secret_key, passphrase)\n : undefined,\n llm_api_key: validated.llm_api_key\n ? maybeEncrypt(validated.llm_api_key, passphrase)\n : undefined,\n };\n const body = JSON.stringify(finalSecrets, null, 2) + '\\n';\n const target = agentPaths(agentDir).secrets;\n await writeFileAtomic(target, body, 0o600);\n}\n\nfunction maybeEncrypt(value: string, passphrase: string | undefined): string {\n if (!passphrase) {\n return value;\n }\n if (isEncrypted(value)) {\n return value;\n }\n return encryptSecret(value, passphrase);\n}\n\n/** Atomic write: temp file + rename. Preserves mode. */\nexport async function writeFileAtomic(\n path: string,\n data: string | Buffer,\n mode: number,\n): Promise<void> {\n await mkdir(dirname(path), { recursive: true });\n const tmpPath = `${path}.tmp.${randomBytes(6).toString('hex')}`;\n await writeFile(tmpPath, data, { mode });\n try {\n await rename(tmpPath, path);\n } catch (e) {\n // Best-effort cleanup of temp file on rename failure.\n try {\n const { unlink } = await import('node:fs/promises');\n await unlink(tmpPath);\n } catch {\n /* ignore */\n }\n throw e;\n }\n}\n\nasync function writeFileIfMissing(path: string, data: string, mode: number): Promise<void> {\n try {\n await writeFile(path, data, { mode, flag: 'wx' });\n } catch (e: unknown) {\n // wx fails with EEXIST if file exists - that's fine.\n if (!isEexist(e)) {\n throw e;\n }\n }\n}\n\nfunction isEexist(e: unknown): boolean {\n return (\n typeof e === 'object' && e !== null && 'code' in e && (e as { code: string }).code === 'EEXIST'\n );\n}\n","/**\n * Global (not per-agent) config stored at `~/.elisym/config.yaml`.\n *\n * Currently holds only session-spend-limit overrides; other top-level fields\n * may be added later. The loader tolerates a missing file (returns `{}`), but\n * fails fast on malformed YAML or schema violations.\n */\n\nimport { readFile } from 'node:fs/promises';\nimport YAML from 'yaml';\nimport { z } from 'zod';\nimport { writeFileAtomic } from '../agent-store/writer';\n\nexport const SessionSpendLimitEntrySchema = z\n .object({\n chain: z.enum(['solana']),\n token: z\n .string()\n .min(1)\n .max(16)\n .regex(/^[a-z0-9]+$/, 'token must be lowercase alphanumeric'),\n mint: z.string().min(1).max(64).optional(),\n amount: z.number().positive().finite(),\n })\n .strict();\n\nexport const GlobalConfigSchema = z\n .object({\n session_spend_limits: z.array(SessionSpendLimitEntrySchema).max(16).optional(),\n })\n .strict();\n\nexport type SessionSpendLimitEntry = z.infer<typeof SessionSpendLimitEntrySchema>;\nexport type GlobalConfig = z.infer<typeof GlobalConfigSchema>;\n\nfunction isEnoent(e: unknown): boolean {\n return (\n typeof e === 'object' && e !== null && 'code' in e && (e as { code: string }).code === 'ENOENT'\n );\n}\n\n/**\n * Read and validate `~/.elisym/config.yaml`. Returns `{}` if missing. Throws\n * on malformed YAML or schema violations — the MCP server treats these as fatal\n * at startup rather than silently ignoring bad overrides.\n */\nexport async function loadGlobalConfig(path: string): Promise<GlobalConfig> {\n let raw: string;\n try {\n raw = await readFile(path, 'utf-8');\n } catch (e) {\n if (isEnoent(e)) {\n return {};\n }\n throw e;\n }\n if (raw.trim() === '') {\n return {};\n }\n const parsed: unknown = YAML.parse(raw);\n return GlobalConfigSchema.parse(parsed ?? {});\n}\n\n/** Write the config YAML atomically. Validates via Zod before writing. */\nexport async function writeGlobalConfig(path: string, config: GlobalConfig): Promise<void> {\n const validated = GlobalConfigSchema.parse(config);\n const body = YAML.stringify(validated);\n await writeFileAtomic(path, body, 0o644);\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 * Agent-name validation shared between CLI and MCP.\n * Browser-safe - no Node.js imports.\n */\n\nimport { LIMITS } from '../constants';\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 * Sliding-window rate limiter keyed by an arbitrary string (typically a\n * customer pubkey). Each key gets at most `maxPerWindow` requests inside a\n * rolling `windowMs`. Stale timestamps are pruned lazily on every `check`.\n * When the tracked-key set grows past `maxKeys`, the least-recently-used\n * key is evicted so an attacker cannot exhaust memory by cycling keys.\n *\n * Thread-safety: not required. Designed for single-threaded JS consumers\n * (Node/Bun event loops, browser main thread). No timers - pruning happens\n * inside `check` and `prune`.\n */\n\nexport interface SlidingWindowLimiterOptions {\n /** Rolling window width, in ms. */\n windowMs: number;\n /** Max hits allowed per key inside the window. */\n maxPerWindow: number;\n /** Cap on total tracked keys. LRU-evicted past this cap. */\n maxKeys: number;\n}\n\nexport interface RateLimitDecision {\n allowed: boolean;\n /** Wall-clock timestamp (ms) when the limit window will reset for this key. */\n resetAt: number;\n /** Number of hits inside the current window after this call (or the attempted hit if denied). */\n count: number;\n}\n\nexport interface SlidingWindowLimiter {\n /** Record a hit against `key`; return whether it was allowed. */\n check(key: string, now?: number): RateLimitDecision;\n /**\n * Inspect the current state for `key` without recording a hit. Useful\n * when a single request must clear multiple limiters and callers want\n * to avoid double-counting against one limiter after another denies.\n */\n peek(key: string, now?: number): RateLimitDecision;\n /** Drop entries whose windows have fully elapsed. Bounded memory hygiene. */\n prune(now?: number): void;\n /** Current number of tracked keys. */\n size(): number;\n /** Clear all state. */\n reset(): void;\n}\n\ninterface Entry {\n /** Sliding-window timestamps in ms. Sorted ascending. */\n hits: number[];\n}\n\nexport function createSlidingWindowLimiter(\n options: SlidingWindowLimiterOptions,\n): SlidingWindowLimiter {\n const { windowMs, maxPerWindow, maxKeys } = options;\n if (windowMs <= 0) {\n throw new RangeError('windowMs must be > 0');\n }\n if (maxPerWindow <= 0) {\n throw new RangeError('maxPerWindow must be > 0');\n }\n if (maxKeys <= 0) {\n throw new RangeError('maxKeys must be > 0');\n }\n\n // LRU is implemented via Map's insertion-order: every check refreshes\n // the entry by deleting and re-setting it, moving it to the tail.\n const entries = new Map<string, Entry>();\n\n function evictIfNeeded(): void {\n while (entries.size > maxKeys) {\n const oldestKey = entries.keys().next().value as string | undefined;\n if (oldestKey === undefined) {\n return;\n }\n entries.delete(oldestKey);\n }\n }\n\n return {\n peek(key, now = Date.now()): RateLimitDecision {\n const entry = entries.get(key);\n if (!entry) {\n return { allowed: true, resetAt: now + windowMs, count: 0 };\n }\n const cutoff = now - windowMs;\n const fresh = entry.hits.filter((timestamp) => timestamp > cutoff);\n return {\n allowed: fresh.length < maxPerWindow,\n resetAt: (fresh[0] ?? now) + windowMs,\n count: fresh.length,\n };\n },\n check(key, now = Date.now()): RateLimitDecision {\n const entry = entries.get(key) ?? { hits: [] };\n const cutoff = now - windowMs;\n const fresh = entry.hits.filter((timestamp) => timestamp > cutoff);\n\n if (fresh.length >= maxPerWindow) {\n // Refresh LRU order even on denial so an attacker hammering the\n // same key cannot push other tracked keys out via eviction.\n entries.delete(key);\n entries.set(key, { hits: fresh });\n return {\n allowed: false,\n resetAt: (fresh[0] ?? now) + windowMs,\n count: fresh.length,\n };\n }\n fresh.push(now);\n entries.delete(key);\n entries.set(key, { hits: fresh });\n evictIfNeeded();\n return {\n allowed: true,\n resetAt: (fresh[0] ?? now) + windowMs,\n count: fresh.length,\n };\n },\n prune(now = Date.now()): void {\n const cutoff = now - windowMs;\n for (const [key, entry] of entries) {\n const fresh = entry.hits.filter((timestamp) => timestamp > cutoff);\n if (fresh.length === 0) {\n entries.delete(key);\n } else if (fresh.length !== entry.hits.length) {\n entry.hits = fresh;\n }\n }\n },\n size(): number {\n return entries.size;\n },\n reset(): void {\n entries.clear();\n },\n };\n}\n","/**\n * Canonical pino redact paths for the elisym stack. Plugin, CLI, MCP, and\n * any downstream integrator should consume these arrays directly - one\n * source of truth for \"fields that carry user input or secrets\".\n *\n * Wire them into a pino instance like:\n *\n * import pino from 'pino';\n * import { DEFAULT_REDACT_PATHS, makeCensor } from '@elisym/sdk';\n * const logger = pino({\n * redact: { paths: DEFAULT_REDACT_PATHS, censor: makeCensor() },\n * });\n */\n\n/**\n * Field paths that carry Nostr / Solana secret keys or operator secrets.\n * Censored as `[REDACTED]`.\n */\nexport const SECRET_REDACT_PATHS: string[] = [\n '*.ELISYM_NOSTR_PRIVATE_KEY',\n '*.ELISYM_SOLANA_PRIVATE_KEY',\n '*.nostrPrivateKeyHex',\n '*.solanaPrivateKeyBase58',\n '*.secretKey',\n '*.secret',\n 'ELISYM_NOSTR_PRIVATE_KEY',\n 'ELISYM_SOLANA_PRIVATE_KEY',\n // Canonical on-disk `.secrets.json` field names. Logging the whole\n // `secrets` object, or any single field directly, must not leak.\n 'llm_api_key',\n 'nostr_secret_key',\n 'solana_secret_key',\n '*.llm_api_key',\n '*.nostr_secret_key',\n '*.solana_secret_key',\n 'secrets',\n '*.secrets',\n];\n\n/**\n * Field paths that carry customer-confidential text (LLM prompts, raw\n * event content, job input). Censored as `[INPUT REDACTED]` so log\n * readers can distinguish redacted input from redacted secrets.\n */\nexport const INPUT_REDACT_PATHS: string[] = [\n 'content',\n 'input',\n 'prompt',\n '*.content',\n '*.input',\n '*.prompt',\n 'event.content',\n '*.event.content',\n // JobLedger entries carry the raw Nostr event JSON (which embeds\n // `event.content`) and the full LLM `resultContent` - both are\n // customer-confidential and must never land in a structured log.\n 'rawEventJson',\n 'resultContent',\n '*.rawEventJson',\n '*.resultContent',\n];\n\n/**\n * Union of the two arrays, in the order pino's redact engine should\n * visit them. Prefer this when wiring a new logger so no downstream\n * consumer forgets half the set.\n */\nexport const DEFAULT_REDACT_PATHS: string[] = [...SECRET_REDACT_PATHS, ...INPUT_REDACT_PATHS];\n\n/**\n * pino `redact.censor` callback. Returns the appropriate marker string\n * based on the final segment of the redacted path.\n *\n * pino calls `censor(value, path)` where `path` is `string[]`. Plugin's\n * historical signature accepted `(_value, path)` with that shape; we\n * preserve that. Pino types vary across versions, so we accept unknown\n * and narrow.\n */\nconst INPUT_REDACT_LEAVES = new Set([\n 'content',\n 'input',\n 'prompt',\n 'rawEventJson',\n 'resultContent',\n]);\n\nexport function makeCensor(): (value: unknown, path: string[]) => string {\n return (_value, path) => {\n const last = path[path.length - 1];\n if (last !== undefined && INPUT_REDACT_LEAVES.has(last)) {\n return '[INPUT REDACTED]';\n }\n return '[REDACTED]';\n };\n}\n"]}
|