@elisym/sdk 0.25.1 → 0.25.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/constants.ts","../../config-client/src/generated/accounts/config.ts","../../config-client/src/generated/accounts/networkStats.ts","../../config-client/src/generated/programs/elisymConfig.ts","../../config-client/src/generated/errors/elisymConfig.ts","../../config-client/src/generated/shared/index.ts","../../config-client/src/generated/instructions/incrementStats.ts","../../config-client/src/helpers.ts","../src/config/onchain.ts","../src/payment/assets.ts","../src/payment/fee.ts","../src/payment/priorityFee.ts","../src/payment/schema.ts","../src/payment/solana.ts","../src/services/blossom.ts","../src/services/discovery.ts","../src/primitives/crypto.ts","../src/transport/attachment.ts","../src/services/marketplace.ts","../src/services/media.ts","../src/primitives/identity.ts","../src/services/ping.ts","../src/services/policies.ts","../src/primitives/bounded-set.ts","../src/transport/pool.ts","../src/client.ts","../src/primitives/file-crypto.ts","../src/transport/blossom-transport.ts","../src/transport/file-jobs.ts","../src/services/jobErrors.ts","../src/payment/feeEstimate.ts","../src/payment/quick-verify.ts","../src/payment/analytics.ts","../src/config/global-schema.ts","../src/primitives/format.ts","../src/primitives/config.ts","../src/primitives/rateLimiter.ts","../src/primitives/logRedact.ts"],"names":["getStructDecoder","fixDecoderSize","getBytesDecoder","getU8Decoder","getAddressDecoder","getOptionDecoder","getU16Decoder","getBooleanDecoder","getI64Decoder","decodeAccount","address","assertAccountExists","fetchEncodedAccount","getU64Decoder","getU128Decoder","AccountRole","upgradeRoleToSigner","kitIsTransactionSigner","transformEncoder","getStructEncoder","fixEncoderSize","getBytesEncoder","getU64Encoder","getBooleanEncoder","getProgramDerivedAddress","Decimal","cache","z","isAddress","pipe","createTransactionMessage","setTransactionMessageFeePayerSigner","setTransactionMessageLifetimeUsingBlockhash","setTransactionMessageComputeUnitLimit","setTransactionMessageComputeUnitPrice","appendTransactionMessageInstructions","signTransactionMessageWithSigners","getAddMemoInstruction","providerTransferIx","getTransferSolInstruction","providerTransferIxWithMarkers","instructions","findAssociatedTokenPda","TOKEN_PROGRAM_ADDRESS","getCreateAssociatedTokenIdempotentInstruction","ASSOCIATED_TOKEN_PROGRAM_ADDRESS","getTransferCheckedInstruction","finalizeEvent","verifyEvent","nip19","nip44","getPublicKey","generateSecretKey","SimplePool","DEFAULT_COMPUTE_UNIT_LIMIT","DEFAULT_PRIORITY_FEE_PERCENTILE","LAMPORTS_PER_SOL","cacheKey"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { Address } from '@solana/kit';\n\nexport const RELAYS = [\n 'wss://relay.damus.io',\n 'wss://nos.lol',\n 'wss://relay.nostr.band',\n 'wss://relay.primal.net',\n 'wss://relay.snort.social',\n];\n\nexport const KIND_APP_HANDLER = 31990;\nexport const KIND_LONG_FORM_ARTICLE = 30023;\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/** Discovery tag attached to elisym agent policy events (kind 30023). */\nexport const POLICY_T_TAG = 'elisym-policy';\n/** d-tag prefix for policy events: full d-tag = `<prefix><type>` (e.g. `elisym-policy-tos`). */\nexport const POLICY_D_TAG_PREFIX = 'elisym-policy-';\n/** Validation regex for policy `type` slug. Lowercase ASCII + hyphen, 1-32 chars, no leading/trailing hyphen. */\nexport const POLICY_TYPE_REGEX = /^[a-z0-9](?:[a-z0-9-]{0,30}[a-z0-9])?$/;\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 * 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\n/**\n * Read-only marker pubkey attached as a non-signer account to every elisym\n * payment transaction. Lets indexers enumerate every elisym tx network-wide\n * via a single `getSignaturesForAddress(ELISYM_PROTOCOL_TAG)` call,\n * independent of fee size or recipient.\n *\n * The account does not need to exist on-chain; including its pubkey as an\n * extra read-only account in the provider transfer instruction is enough for\n * Solana's tx-by-account index to pick it up. The corresponding secret key\n * was generated and discarded - the tag never signs and never holds funds.\n */\nexport const ELISYM_PROTOCOL_TAG = 'ELiZksgwDt41LaeuPDLkUfWgFXhGgVayTMP7L5nTSEL8' 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: 3_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 // Default ceiling for a single iroh file transfer (seed/fetch). A tunable\n // default, not a protocol constant - the transfer is resumable and its own\n // budget, decoupled from the result-wait window.\n IROH_FETCH_TIMEOUT_MS: 300_000,\n // Ceiling for a single Blossom blob upload (PUT /upload). Large blobs (up to\n // LIMITS.MAX_FILE_SIZE) need far more than the 30s used for small media images.\n BLOSSOM_UPLOAD_TIMEOUT_MS: 300_000,\n // Ceiling for a single encrypted Blossom blob download (GET). Same budget as upload.\n BLOSSOM_FETCH_TIMEOUT_MS: 300_000,\n} as const;\n\n/** Protocol limits for input validation. */\nexport const LIMITS = {\n MAX_INPUT_LENGTH: 100_000,\n // NIP-44 v2 hard cap on encrypted plaintext: the pad() length prefix is a u16,\n // so the plaintext can be at most 65_535 BYTES (not chars). Encrypting anything\n // larger throws `invalid plaintext size` inside nip44Encrypt. This is the binding\n // limit for TARGETED (encrypted) jobs - lower than every relay's NIP-11 cap.\n NIP44_MAX_PLAINTEXT_BYTES: 65_535,\n // Spill threshold for encrypted content: above this many UTF-8 bytes, callers\n // route the text through iroh out-of-band instead of inlining it. A non-spilled\n // job is encrypted RAW (no envelope - see marketplace.submitJobRequest), so a\n // 60_000-byte input is a 60_000-byte plaintext; the ~5.5KB gap under the hard cap\n // is plain slack, and NIP44_MAX_PLAINTEXT_BYTES is the SDK backstop.\n MAX_ENCRYPTED_INLINE_BYTES: 60_000,\n // Ceiling above which a text/* attachment is NOT materialized back into a string\n // (re-inlined into SkillInput.data) - the consumer gets a filePath / explicit\n // fetch instead. Also bounds the in-memory git-diff buffer (memory-DoS guard).\n MAX_REINLINE_TEXT_BYTES: 4_194_304, // 4 MiB\n // Hard safety cap on a single file transferred via iroh, enforced on the\n // actual streamed bytes (never the sender-declared `size`). A tunable default;\n // providers may lower it per deployment.\n MAX_FILE_SIZE: 1_073_741_824, // 1 GiB\n // Cap for the ENCRYPTED Blossom path (web/SDK). The encrypt-then-upload flow is\n // whole-buffer in WebCrypto + BlossomService (~3x file-size peak RAM), so this is\n // deliberately far below MAX_FILE_SIZE to stay safe in a browser tab; larger files\n // use iroh. The relay enforces a ~128 MiB server-side backstop.\n MAX_BLOSSOM_ENCRYPTED_BYTES: 104_857_600, // 100 MiB\n\n MAX_TIMEOUT_SECS: 600,\n // Upper bound for execution budgets (`max_execution_secs` / `execution_timeout_secs`).\n // Distinct from MAX_TIMEOUT_SECS (the result-wait cap): execution budgets may be\n // hours, so this exists only to keep `secs * 1000` within Node's setTimeout limit\n // (2_147_483_647 ms) - a larger value overflows and fires the timer immediately.\n MAX_EXECUTION_SECS: 2_147_483,\n MAX_CAPABILITIES: 20,\n MAX_DESCRIPTION_LENGTH: 500,\n MAX_AGENT_NAME_LENGTH: 64,\n MAX_CAPABILITY_LENGTH: 64,\n MAX_POLICY_CONTENT_LENGTH: 50_000,\n MAX_POLICIES_PER_AGENT: 12,\n MAX_POLICY_TYPE_LENGTH: 32,\n MAX_POLICY_TITLE_LENGTH: 120,\n MAX_POLICY_SUMMARY_LENGTH: 280,\n MAX_POLICY_VERSION_LENGTH: 32,\n} as const;\n\nconst UTF8_ENCODER = new TextEncoder();\n\n/**\n * UTF-8 byte length of a string. All size guards on encrypted content measure\n * BYTES, not `String.length` (UTF-16 code units): NIP-44's plaintext cap is a\n * byte cap, so a multibyte string under the char cap can still exceed it.\n */\nexport function utf8ByteLength(value: string): number {\n return UTF8_ENCODER.encode(value).length;\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 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 assertAccountExists,\n assertAccountsExist,\n combineCodec,\n decodeAccount,\n fetchEncodedAccount,\n fetchEncodedAccounts,\n fixDecoderSize,\n fixEncoderSize,\n getBytesDecoder,\n getBytesEncoder,\n getI64Decoder,\n getI64Encoder,\n getStructDecoder,\n getStructEncoder,\n getU128Decoder,\n getU128Encoder,\n getU64Decoder,\n getU64Encoder,\n getU8Decoder,\n getU8Encoder,\n transformEncoder,\n type Account,\n type Address,\n type EncodedAccount,\n type FetchAccountConfig,\n type FetchAccountsConfig,\n type FixedSizeCodec,\n type FixedSizeDecoder,\n type FixedSizeEncoder,\n type MaybeAccount,\n type MaybeEncodedAccount,\n type ReadonlyUint8Array,\n} from '@solana/kit';\n\nexport const NETWORK_STATS_DISCRIMINATOR = new Uint8Array([\n 171, 11, 222, 71, 255, 220, 21, 3,\n]);\n\nexport function getNetworkStatsDiscriminatorBytes() {\n return fixEncoderSize(getBytesEncoder(), 8).encode(\n NETWORK_STATS_DISCRIMINATOR\n );\n}\n\nexport type NetworkStats = {\n discriminator: ReadonlyUint8Array;\n version: number;\n bump: number;\n jobCount: bigint;\n volumeNative: bigint;\n volumeUsdc: bigint;\n lastUpdated: bigint;\n reserved: ReadonlyUint8Array;\n};\n\nexport type NetworkStatsArgs = {\n version: number;\n bump: number;\n jobCount: number | bigint;\n volumeNative: number | bigint;\n volumeUsdc: number | bigint;\n lastUpdated: number | bigint;\n reserved: ReadonlyUint8Array;\n};\n\nexport function getNetworkStatsEncoder(): FixedSizeEncoder<NetworkStatsArgs> {\n return transformEncoder(\n getStructEncoder([\n ['discriminator', fixEncoderSize(getBytesEncoder(), 8)],\n ['version', getU8Encoder()],\n ['bump', getU8Encoder()],\n ['jobCount', getU64Encoder()],\n ['volumeNative', getU128Encoder()],\n ['volumeUsdc', getU128Encoder()],\n ['lastUpdated', getI64Encoder()],\n ['reserved', fixEncoderSize(getBytesEncoder(), 128)],\n ]),\n (value) => ({ ...value, discriminator: NETWORK_STATS_DISCRIMINATOR })\n );\n}\n\nexport function getNetworkStatsDecoder(): FixedSizeDecoder<NetworkStats> {\n return getStructDecoder([\n ['discriminator', fixDecoderSize(getBytesDecoder(), 8)],\n ['version', getU8Decoder()],\n ['bump', getU8Decoder()],\n ['jobCount', getU64Decoder()],\n ['volumeNative', getU128Decoder()],\n ['volumeUsdc', getU128Decoder()],\n ['lastUpdated', getI64Decoder()],\n ['reserved', fixDecoderSize(getBytesDecoder(), 128)],\n ]);\n}\n\nexport function getNetworkStatsCodec(): FixedSizeCodec<\n NetworkStatsArgs,\n NetworkStats\n> {\n return combineCodec(getNetworkStatsEncoder(), getNetworkStatsDecoder());\n}\n\nexport function decodeNetworkStats<TAddress extends string = string>(\n encodedAccount: EncodedAccount<TAddress>\n): Account<NetworkStats, TAddress>;\nexport function decodeNetworkStats<TAddress extends string = string>(\n encodedAccount: MaybeEncodedAccount<TAddress>\n): MaybeAccount<NetworkStats, TAddress>;\nexport function decodeNetworkStats<TAddress extends string = string>(\n encodedAccount: EncodedAccount<TAddress> | MaybeEncodedAccount<TAddress>\n): Account<NetworkStats, TAddress> | MaybeAccount<NetworkStats, TAddress> {\n return decodeAccount(\n encodedAccount as MaybeEncodedAccount<TAddress>,\n getNetworkStatsDecoder()\n );\n}\n\nexport async function fetchNetworkStats<TAddress extends string = string>(\n rpc: Parameters<typeof fetchEncodedAccount>[0],\n address: Address<TAddress>,\n config?: FetchAccountConfig\n): Promise<Account<NetworkStats, TAddress>> {\n const maybeAccount = await fetchMaybeNetworkStats(rpc, address, config);\n assertAccountExists(maybeAccount);\n return maybeAccount;\n}\n\nexport async function fetchMaybeNetworkStats<TAddress extends string = string>(\n rpc: Parameters<typeof fetchEncodedAccount>[0],\n address: Address<TAddress>,\n config?: FetchAccountConfig\n): Promise<MaybeAccount<NetworkStats, TAddress>> {\n const maybeAccount = await fetchEncodedAccount(rpc, address, config);\n return decodeNetworkStats(maybeAccount);\n}\n\nexport async function fetchAllNetworkStats(\n rpc: Parameters<typeof fetchEncodedAccounts>[0],\n addresses: Array<Address>,\n config?: FetchAccountsConfig\n): Promise<Account<NetworkStats>[]> {\n const maybeAccounts = await fetchAllMaybeNetworkStats(rpc, addresses, config);\n assertAccountsExist(maybeAccounts);\n return maybeAccounts;\n}\n\nexport async function fetchAllMaybeNetworkStats(\n rpc: Parameters<typeof fetchEncodedAccounts>[0],\n addresses: Array<Address>,\n config?: FetchAccountsConfig\n): Promise<MaybeAccount<NetworkStats>[]> {\n const maybeAccounts = await fetchEncodedAccounts(rpc, addresses, config);\n return maybeAccounts.map((maybeAccount) => decodeNetworkStats(maybeAccount));\n}\n\nexport function getNetworkStatsSize(): number {\n return 186;\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 containsBytes,\n fixEncoderSize,\n getBytesEncoder,\n type Address,\n type ReadonlyUint8Array,\n} from '@solana/kit';\nimport {\n type ParsedAcceptAdminInstruction,\n type ParsedCancelPendingAdminInstruction,\n type ParsedIncrementStatsInstruction,\n type ParsedInitializeInstruction,\n type ParsedInitializeStatsInstruction,\n type ParsedProposeAdminInstruction,\n type ParsedSetFeeBpsInstruction,\n type ParsedSetTreasuryInstruction,\n} from '../instructions';\n\nexport const ELISYM_CONFIG_PROGRAM_ADDRESS =\n 'BrX1CRkSgvcjxBvc2bgc3QqgWjinusofDmeP7ZVxvwrE' as Address<'BrX1CRkSgvcjxBvc2bgc3QqgWjinusofDmeP7ZVxvwrE'>;\n\nexport enum ElisymConfigAccount {\n Config,\n NetworkStats,\n}\n\nexport function identifyElisymConfigAccount(\n account: { data: ReadonlyUint8Array } | ReadonlyUint8Array\n): ElisymConfigAccount {\n const data = 'data' in account ? account.data : account;\n if (\n containsBytes(\n data,\n fixEncoderSize(getBytesEncoder(), 8).encode(\n new Uint8Array([155, 12, 170, 224, 30, 250, 204, 130])\n ),\n 0\n )\n ) {\n return ElisymConfigAccount.Config;\n }\n if (\n containsBytes(\n data,\n fixEncoderSize(getBytesEncoder(), 8).encode(\n new Uint8Array([171, 11, 222, 71, 255, 220, 21, 3])\n ),\n 0\n )\n ) {\n return ElisymConfigAccount.NetworkStats;\n }\n throw new Error(\n 'The provided account could not be identified as a elisymConfig account.'\n );\n}\n\nexport enum ElisymConfigInstruction {\n AcceptAdmin,\n CancelPendingAdmin,\n IncrementStats,\n Initialize,\n InitializeStats,\n ProposeAdmin,\n SetFeeBps,\n SetTreasury,\n}\n\nexport function identifyElisymConfigInstruction(\n instruction: { data: ReadonlyUint8Array } | ReadonlyUint8Array\n): ElisymConfigInstruction {\n const data = 'data' in instruction ? instruction.data : instruction;\n if (\n containsBytes(\n data,\n fixEncoderSize(getBytesEncoder(), 8).encode(\n new Uint8Array([112, 42, 45, 90, 116, 181, 13, 170])\n ),\n 0\n )\n ) {\n return ElisymConfigInstruction.AcceptAdmin;\n }\n if (\n containsBytes(\n data,\n fixEncoderSize(getBytesEncoder(), 8).encode(\n new Uint8Array([96, 213, 92, 102, 118, 54, 82, 93])\n ),\n 0\n )\n ) {\n return ElisymConfigInstruction.CancelPendingAdmin;\n }\n if (\n containsBytes(\n data,\n fixEncoderSize(getBytesEncoder(), 8).encode(\n new Uint8Array([145, 78, 96, 206, 45, 21, 111, 175])\n ),\n 0\n )\n ) {\n return ElisymConfigInstruction.IncrementStats;\n }\n if (\n containsBytes(\n data,\n fixEncoderSize(getBytesEncoder(), 8).encode(\n new Uint8Array([175, 175, 109, 31, 13, 152, 155, 237])\n ),\n 0\n )\n ) {\n return ElisymConfigInstruction.Initialize;\n }\n if (\n containsBytes(\n data,\n fixEncoderSize(getBytesEncoder(), 8).encode(\n new Uint8Array([144, 201, 117, 76, 127, 118, 176, 16])\n ),\n 0\n )\n ) {\n return ElisymConfigInstruction.InitializeStats;\n }\n if (\n containsBytes(\n data,\n fixEncoderSize(getBytesEncoder(), 8).encode(\n new Uint8Array([121, 214, 199, 212, 87, 39, 117, 234])\n ),\n 0\n )\n ) {\n return ElisymConfigInstruction.ProposeAdmin;\n }\n if (\n containsBytes(\n data,\n fixEncoderSize(getBytesEncoder(), 8).encode(\n new Uint8Array([2, 161, 245, 141, 111, 32, 39, 198])\n ),\n 0\n )\n ) {\n return ElisymConfigInstruction.SetFeeBps;\n }\n if (\n containsBytes(\n data,\n fixEncoderSize(getBytesEncoder(), 8).encode(\n new Uint8Array([57, 97, 196, 95, 195, 206, 106, 136])\n ),\n 0\n )\n ) {\n return ElisymConfigInstruction.SetTreasury;\n }\n throw new Error(\n 'The provided instruction could not be identified as a elisymConfig instruction.'\n );\n}\n\nexport type ParsedElisymConfigInstruction<\n TProgram extends string = 'BrX1CRkSgvcjxBvc2bgc3QqgWjinusofDmeP7ZVxvwrE',\n> =\n | ({\n instructionType: ElisymConfigInstruction.AcceptAdmin;\n } & ParsedAcceptAdminInstruction<TProgram>)\n | ({\n instructionType: ElisymConfigInstruction.CancelPendingAdmin;\n } & ParsedCancelPendingAdminInstruction<TProgram>)\n | ({\n instructionType: ElisymConfigInstruction.IncrementStats;\n } & ParsedIncrementStatsInstruction<TProgram>)\n | ({\n instructionType: ElisymConfigInstruction.Initialize;\n } & ParsedInitializeInstruction<TProgram>)\n | ({\n instructionType: ElisymConfigInstruction.InitializeStats;\n } & ParsedInitializeStatsInstruction<TProgram>)\n | ({\n instructionType: ElisymConfigInstruction.ProposeAdmin;\n } & ParsedProposeAdminInstruction<TProgram>)\n | ({\n instructionType: ElisymConfigInstruction.SetFeeBps;\n } & ParsedSetFeeBpsInstruction<TProgram>)\n | ({\n instructionType: ElisymConfigInstruction.SetTreasury;\n } & ParsedSetTreasuryInstruction<TProgram>);\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/** StatsOverflow: Stats counter overflow */\nexport const ELISYM_CONFIG_ERROR__STATS_OVERFLOW = 0x1777; // 6007\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__STATS_OVERFLOW\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__STATS_OVERFLOW]: `Stats counter overflow`,\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","/**\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 AccountRole,\n isProgramDerivedAddress,\n isTransactionSigner as kitIsTransactionSigner,\n type AccountMeta,\n type AccountSignerMeta,\n type Address,\n type ProgramDerivedAddress,\n type TransactionSigner,\n upgradeRoleToSigner,\n} from '@solana/kit';\n\n/**\n * Asserts that the given value is not null or undefined.\n * @internal\n */\nexport function expectSome<T>(value: T | null | undefined): T {\n if (value === null || value === undefined) {\n throw new Error('Expected a value but received null or undefined.');\n }\n return value;\n}\n\n/**\n * Asserts that the given value is a PublicKey.\n * @internal\n */\nexport function expectAddress<T extends string = string>(\n value:\n | Address<T>\n | ProgramDerivedAddress<T>\n | TransactionSigner<T>\n | null\n | undefined\n): Address<T> {\n if (!value) {\n throw new Error('Expected a Address.');\n }\n if (typeof value === 'object' && 'address' in value) {\n return value.address;\n }\n if (Array.isArray(value)) {\n return value[0] as Address<T>;\n }\n return value as Address<T>;\n}\n\n/**\n * Asserts that the given value is a PDA.\n * @internal\n */\nexport function expectProgramDerivedAddress<T extends string = string>(\n value:\n | Address<T>\n | ProgramDerivedAddress<T>\n | TransactionSigner<T>\n | null\n | undefined\n): ProgramDerivedAddress<T> {\n if (!value || !Array.isArray(value) || !isProgramDerivedAddress(value)) {\n throw new Error('Expected a ProgramDerivedAddress.');\n }\n return value;\n}\n\n/**\n * Asserts that the given value is a TransactionSigner.\n * @internal\n */\nexport function expectTransactionSigner<T extends string = string>(\n value:\n | Address<T>\n | ProgramDerivedAddress<T>\n | TransactionSigner<T>\n | null\n | undefined\n): TransactionSigner<T> {\n if (!value || !isTransactionSigner(value)) {\n throw new Error('Expected a TransactionSigner.');\n }\n return value;\n}\n\n/**\n * Defines an instruction account to resolve.\n * @internal\n */\nexport type ResolvedAccount<\n T extends string = string,\n U extends\n | Address<T>\n | ProgramDerivedAddress<T>\n | TransactionSigner<T>\n | null =\n | Address<T>\n | ProgramDerivedAddress<T>\n | TransactionSigner<T>\n | null,\n> = {\n isWritable: boolean;\n value: U;\n};\n\n/**\n * Defines an instruction that stores additional bytes on-chain.\n * @internal\n */\nexport type InstructionWithByteDelta = {\n byteDelta: number;\n};\n\n/**\n * Get account metas and signers from resolved accounts.\n * @internal\n */\nexport function getAccountMetaFactory(\n programAddress: Address,\n optionalAccountStrategy: 'omitted' | 'programId'\n) {\n return (\n account: ResolvedAccount\n ): AccountMeta | AccountSignerMeta | undefined => {\n if (!account.value) {\n if (optionalAccountStrategy === 'omitted') return;\n return Object.freeze({\n address: programAddress,\n role: AccountRole.READONLY,\n });\n }\n\n const writableRole = account.isWritable\n ? AccountRole.WRITABLE\n : AccountRole.READONLY;\n return Object.freeze({\n address: expectAddress(account.value),\n role: isTransactionSigner(account.value)\n ? upgradeRoleToSigner(writableRole)\n : writableRole,\n ...(isTransactionSigner(account.value) ? { signer: account.value } : {}),\n });\n };\n}\n\nexport function isTransactionSigner<TAddress extends string = string>(\n value:\n | Address<TAddress>\n | ProgramDerivedAddress<TAddress>\n | TransactionSigner<TAddress>\n): value is TransactionSigner<TAddress> {\n return (\n !!value &&\n typeof value === 'object' &&\n 'address' in value &&\n kitIsTransactionSigner(value)\n );\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 combineCodec,\n fixDecoderSize,\n fixEncoderSize,\n getBooleanDecoder,\n getBooleanEncoder,\n getBytesDecoder,\n getBytesEncoder,\n getProgramDerivedAddress,\n getStructDecoder,\n getStructEncoder,\n getU64Decoder,\n getU64Encoder,\n transformEncoder,\n type AccountMeta,\n type Address,\n type FixedSizeCodec,\n type FixedSizeDecoder,\n type FixedSizeEncoder,\n type Instruction,\n type InstructionWithAccounts,\n type InstructionWithData,\n type ReadonlyAccount,\n type ReadonlyUint8Array,\n type WritableAccount,\n} from '@solana/kit';\nimport { ELISYM_CONFIG_PROGRAM_ADDRESS } from '../programs';\nimport { getAccountMetaFactory, type ResolvedAccount } from '../shared';\n\nexport const INCREMENT_STATS_DISCRIMINATOR = new Uint8Array([\n 145, 78, 96, 206, 45, 21, 111, 175,\n]);\n\nexport function getIncrementStatsDiscriminatorBytes() {\n return fixEncoderSize(getBytesEncoder(), 8).encode(\n INCREMENT_STATS_DISCRIMINATOR\n );\n}\n\nexport type IncrementStatsInstruction<\n TProgram extends string = typeof ELISYM_CONFIG_PROGRAM_ADDRESS,\n TAccountStats extends string | AccountMeta<string> = string,\n TAccountEventAuthority extends string | AccountMeta<string> = string,\n TAccountProgram extends string | AccountMeta<string> = string,\n TRemainingAccounts extends readonly AccountMeta<string>[] = [],\n> = Instruction<TProgram> &\n InstructionWithData<ReadonlyUint8Array> &\n InstructionWithAccounts<\n [\n TAccountStats extends string\n ? WritableAccount<TAccountStats>\n : TAccountStats,\n TAccountEventAuthority extends string\n ? ReadonlyAccount<TAccountEventAuthority>\n : TAccountEventAuthority,\n TAccountProgram extends string\n ? ReadonlyAccount<TAccountProgram>\n : TAccountProgram,\n ...TRemainingAccounts,\n ]\n >;\n\nexport type IncrementStatsInstructionData = {\n discriminator: ReadonlyUint8Array;\n amount: bigint;\n isNative: boolean;\n};\n\nexport type IncrementStatsInstructionDataArgs = {\n amount: number | bigint;\n isNative: boolean;\n};\n\nexport function getIncrementStatsInstructionDataEncoder(): FixedSizeEncoder<IncrementStatsInstructionDataArgs> {\n return transformEncoder(\n getStructEncoder([\n ['discriminator', fixEncoderSize(getBytesEncoder(), 8)],\n ['amount', getU64Encoder()],\n ['isNative', getBooleanEncoder()],\n ]),\n (value) => ({ ...value, discriminator: INCREMENT_STATS_DISCRIMINATOR })\n );\n}\n\nexport function getIncrementStatsInstructionDataDecoder(): FixedSizeDecoder<IncrementStatsInstructionData> {\n return getStructDecoder([\n ['discriminator', fixDecoderSize(getBytesDecoder(), 8)],\n ['amount', getU64Decoder()],\n ['isNative', getBooleanDecoder()],\n ]);\n}\n\nexport function getIncrementStatsInstructionDataCodec(): FixedSizeCodec<\n IncrementStatsInstructionDataArgs,\n IncrementStatsInstructionData\n> {\n return combineCodec(\n getIncrementStatsInstructionDataEncoder(),\n getIncrementStatsInstructionDataDecoder()\n );\n}\n\nexport type IncrementStatsAsyncInput<\n TAccountStats extends string = string,\n TAccountEventAuthority extends string = string,\n TAccountProgram extends string = string,\n> = {\n stats?: Address<TAccountStats>;\n eventAuthority: Address<TAccountEventAuthority>;\n program: Address<TAccountProgram>;\n amount: IncrementStatsInstructionDataArgs['amount'];\n isNative: IncrementStatsInstructionDataArgs['isNative'];\n};\n\nexport async function getIncrementStatsInstructionAsync<\n TAccountStats extends string,\n TAccountEventAuthority extends string,\n TAccountProgram extends string,\n TProgramAddress extends Address = typeof ELISYM_CONFIG_PROGRAM_ADDRESS,\n>(\n input: IncrementStatsAsyncInput<\n TAccountStats,\n TAccountEventAuthority,\n TAccountProgram\n >,\n config?: { programAddress?: TProgramAddress }\n): Promise<\n IncrementStatsInstruction<\n TProgramAddress,\n TAccountStats,\n TAccountEventAuthority,\n TAccountProgram\n >\n> {\n // Program address.\n const programAddress =\n config?.programAddress ?? ELISYM_CONFIG_PROGRAM_ADDRESS;\n\n // Original accounts.\n const originalAccounts = {\n stats: { value: input.stats ?? null, isWritable: true },\n eventAuthority: { value: input.eventAuthority ?? null, isWritable: false },\n program: { value: input.program ?? null, isWritable: false },\n };\n const accounts = originalAccounts as Record<\n keyof typeof originalAccounts,\n ResolvedAccount\n >;\n\n // Original args.\n const args = { ...input };\n\n // Resolve default values.\n if (!accounts.stats.value) {\n accounts.stats.value = await getProgramDerivedAddress({\n programAddress,\n seeds: [\n getBytesEncoder().encode(\n new Uint8Array([\n 110, 101, 116, 119, 111, 114, 107, 95, 115, 116, 97, 116, 115,\n ])\n ),\n ],\n });\n }\n\n const getAccountMeta = getAccountMetaFactory(programAddress, 'programId');\n const instruction = {\n accounts: [\n getAccountMeta(accounts.stats),\n getAccountMeta(accounts.eventAuthority),\n getAccountMeta(accounts.program),\n ],\n programAddress,\n data: getIncrementStatsInstructionDataEncoder().encode(\n args as IncrementStatsInstructionDataArgs\n ),\n } as IncrementStatsInstruction<\n TProgramAddress,\n TAccountStats,\n TAccountEventAuthority,\n TAccountProgram\n >;\n\n return instruction;\n}\n\nexport type IncrementStatsInput<\n TAccountStats extends string = string,\n TAccountEventAuthority extends string = string,\n TAccountProgram extends string = string,\n> = {\n stats: Address<TAccountStats>;\n eventAuthority: Address<TAccountEventAuthority>;\n program: Address<TAccountProgram>;\n amount: IncrementStatsInstructionDataArgs['amount'];\n isNative: IncrementStatsInstructionDataArgs['isNative'];\n};\n\nexport function getIncrementStatsInstruction<\n TAccountStats extends string,\n TAccountEventAuthority extends string,\n TAccountProgram extends string,\n TProgramAddress extends Address = typeof ELISYM_CONFIG_PROGRAM_ADDRESS,\n>(\n input: IncrementStatsInput<\n TAccountStats,\n TAccountEventAuthority,\n TAccountProgram\n >,\n config?: { programAddress?: TProgramAddress }\n): IncrementStatsInstruction<\n TProgramAddress,\n TAccountStats,\n TAccountEventAuthority,\n TAccountProgram\n> {\n // Program address.\n const programAddress =\n config?.programAddress ?? ELISYM_CONFIG_PROGRAM_ADDRESS;\n\n // Original accounts.\n const originalAccounts = {\n stats: { value: input.stats ?? null, isWritable: true },\n eventAuthority: { value: input.eventAuthority ?? null, isWritable: false },\n program: { value: input.program ?? null, isWritable: false },\n };\n const accounts = originalAccounts as Record<\n keyof typeof originalAccounts,\n ResolvedAccount\n >;\n\n // Original args.\n const args = { ...input };\n\n const getAccountMeta = getAccountMetaFactory(programAddress, 'programId');\n const instruction = {\n accounts: [\n getAccountMeta(accounts.stats),\n getAccountMeta(accounts.eventAuthority),\n getAccountMeta(accounts.program),\n ],\n programAddress,\n data: getIncrementStatsInstructionDataEncoder().encode(\n args as IncrementStatsInstructionDataArgs\n ),\n } as IncrementStatsInstruction<\n TProgramAddress,\n TAccountStats,\n TAccountEventAuthority,\n TAccountProgram\n >;\n\n return instruction;\n}\n\nexport type ParsedIncrementStatsInstruction<\n TProgram extends string = typeof ELISYM_CONFIG_PROGRAM_ADDRESS,\n TAccountMetas extends readonly AccountMeta[] = readonly AccountMeta[],\n> = {\n programAddress: Address<TProgram>;\n accounts: {\n stats: TAccountMetas[0];\n eventAuthority: TAccountMetas[1];\n program: TAccountMetas[2];\n };\n data: IncrementStatsInstructionData;\n};\n\nexport function parseIncrementStatsInstruction<\n TProgram extends string,\n TAccountMetas extends readonly AccountMeta[],\n>(\n instruction: Instruction<TProgram> &\n InstructionWithAccounts<TAccountMetas> &\n InstructionWithData<ReadonlyUint8Array>\n): ParsedIncrementStatsInstruction<TProgram, TAccountMetas> {\n if (instruction.accounts.length < 3) {\n // TODO: Coded error.\n throw new Error('Not enough accounts');\n }\n let accountIndex = 0;\n const getNextAccount = () => {\n const accountMeta = (instruction.accounts as TAccountMetas)[accountIndex]!;\n accountIndex += 1;\n return accountMeta;\n };\n return {\n programAddress: instruction.programAddress,\n accounts: {\n stats: getNextAccount(),\n eventAuthority: getNextAccount(),\n program: getNextAccount(),\n },\n data: getIncrementStatsInstructionDataDecoder().decode(instruction.data),\n };\n}\n","import { type Address, getProgramDerivedAddress } from '@solana/kit';\n\nexport const CONFIG_SEED = 'config';\nexport const STATS_SEED = 'network_stats';\nexport const EVENT_AUTHORITY_SEED = '__event_authority';\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\nexport async function deriveNetworkStatsAddress(programId: Address): Promise<Address> {\n const [pda] = await getProgramDerivedAddress({\n programAddress: programId,\n seeds: [new TextEncoder().encode(STATS_SEED)],\n });\n return pda;\n}\n\n/**\n * Derives the Anchor `event_authority` PDA used by `emit_cpi!()` instructions.\n * Required as a read-only account for any instruction declared with `#[event_cpi]`.\n */\nexport async function deriveEventAuthorityAddress(programId: Address): Promise<Address> {\n const [pda] = await getProgramDerivedAddress({\n programAddress: programId,\n seeds: [new TextEncoder().encode(EVENT_AUTHORITY_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","/**\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\nimport Decimal from 'decimal.js-light';\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\nexport 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, USDC_SOLANA_DEVNET];\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\n/**\n * Resolve the asset a payment request targets. Returns `NATIVE_SOL` when the\n * request has no `asset` field (back-compat with payment requests published\n * before multi-asset support). Throws when `asset` is present but refers to an\n * asset that isn't in `KNOWN_ASSETS` - callers that want to tolerate unknown\n * assets should check `resolveKnownAsset` directly instead.\n */\nexport function resolveAssetFromPaymentRequest(request: {\n asset?: { chain: string; token: string; mint?: string };\n}): Asset {\n if (!request.asset) {\n return NATIVE_SOL;\n }\n const found = resolveKnownAsset(request.asset.chain, request.asset.token, request.asset.mint);\n if (!found) {\n const display = request.asset.mint\n ? `${request.asset.chain}:${request.asset.token}:${request.asset.mint}`\n : `${request.asset.chain}:${request.asset.token}`;\n throw new Error(\n `Unknown asset in payment request: ${display}. ` +\n `Known assets: ${KNOWN_ASSETS.map(assetKey).join(', ')}`,\n );\n }\n return found;\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// Cloned config keeps `Decimal.toString()` from switching to exponential notation\n// for small fractional amounts (e.g. 1 lamport = 1e-9 SOL).\nconst FormatDecimal = Decimal.clone({ toExpNeg: -100, toExpPos: 100, precision: 50 });\n\n/**\n * Format raw subunits back to `\"<value> <SYMBOL>\"`. Trailing zeros and a bare\n * trailing dot are stripped, so 0.01 USDC renders as `\"0.01 USDC\"` rather than\n * `\"0.010000 USDC\"`.\n */\nexport function formatAssetAmount(asset: Asset, raw: bigint): string {\n const value = new FormatDecimal(raw.toString()).div(new FormatDecimal(10).pow(asset.decimals));\n return `${value.toString()} ${asset.symbol}`;\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), typically obtained\n * from `getProtocolConfig` or supplied as a test fixture.\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\nconst paymentAssetRefSchema = z.object({\n chain: z.string().min(1),\n token: z.string().min(1),\n mint: solanaAddressSchema.optional(),\n decimals: z.number().int().min(0).max(18),\n});\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 asset: paymentAssetRefSchema.optional(),\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 {\n deriveEventAuthorityAddress,\n deriveNetworkStatsAddress,\n getIncrementStatsInstruction,\n} from '@elisym/config-client';\nimport { getAddMemoInstruction } from '@solana-program/memo';\nimport { getTransferSolInstruction } from '@solana-program/system';\nimport {\n ASSOCIATED_TOKEN_PROGRAM_ADDRESS,\n TOKEN_PROGRAM_ADDRESS,\n findAssociatedTokenPda,\n getCreateAssociatedTokenIdempotentInstruction,\n getTransferCheckedInstruction,\n} from '@solana-program/token';\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, ELISYM_PROTOCOL_TAG, LIMITS, getProtocolProgramId } from '../constants';\nimport type {\n PaymentAssetRef,\n PaymentRequestData,\n PaymentValidationError,\n VerifyOptions,\n VerifyResult,\n} from '../types';\nimport { type Asset, NATIVE_SOL, resolveAssetFromPaymentRequest } from './assets';\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; asset?: Asset },\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 const assetRef: PaymentAssetRef | undefined =\n options?.asset && options.asset !== NATIVE_SOL\n ? {\n chain: options.asset.chain,\n token: options.asset.token,\n mint: options.asset.mint,\n decimals: options.asset.decimals,\n }\n : undefined;\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 ...(assetRef ? { asset: assetRef } : {}),\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 // Reject payment requests that reference an asset the SDK doesn't know\n // about - the customer cannot safely build a transaction without knowing\n // the wire format (System transfer vs SPL TransferChecked).\n if (data.asset) {\n try {\n resolveAssetFromPaymentRequest(data);\n } catch (error) {\n return {\n code: 'invalid_asset',\n message: error instanceof Error ? error.message : String(error),\n };\n }\n }\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 surfaces shape errors (e.g. fee\n // >= amount) and, for SPL assets, derives the ATAs, before any RPC\n // round-trip that depends on them.\n const paymentInstructions = await buildPaymentInstructions(paymentRequest, payerSigner, {\n jobEventId: options?.jobEventId,\n programId: options?.programId,\n });\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 let asset: Asset;\n try {\n asset = resolveAssetFromPaymentRequest(paymentRequest);\n } catch (error) {\n return {\n verified: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n const mint = asset.mint;\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 mint,\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 mint,\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 mint: string | undefined,\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 = checkTxDiff({\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 preTokenBalances: tx.meta.preTokenBalances as readonly TokenBalanceEntry[] | undefined,\n postTokenBalances: tx.meta.postTokenBalances as readonly TokenBalanceEntry[] | undefined,\n referenceKey,\n recipientAddress,\n treasuryAddress,\n expectedNet,\n expectedFee,\n mint,\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 mint: string | undefined,\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 = checkTxDiff({\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 preTokenBalances: tx.meta.preTokenBalances as\n | readonly TokenBalanceEntry[]\n | undefined,\n postTokenBalances: tx.meta.postTokenBalances as\n | readonly TokenBalanceEntry[]\n | undefined,\n referenceKey,\n recipientAddress,\n treasuryAddress,\n expectedNet,\n expectedFee,\n mint,\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 TokenBalanceEntry {\n accountIndex: number;\n mint: string;\n owner?: string;\n uiTokenAmount: { amount: string };\n}\n\ninterface TxDiffInput {\n accountKeys: readonly string[];\n preBalances: readonly bigint[];\n postBalances: readonly bigint[];\n preTokenBalances?: readonly TokenBalanceEntry[];\n postTokenBalances?: readonly TokenBalanceEntry[];\n referenceKey: string;\n recipientAddress: string;\n treasuryAddress: string;\n expectedNet: number;\n expectedFee: number;\n /** SPL mint for token transfers. `undefined` => native SOL path. */\n mint?: string;\n}\n\ntype BalanceVerdict = { ok: true } | { ok: false; reason: string };\n\nfunction checkTxDiff(input: TxDiffInput): 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\n if (input.mint) {\n return checkTokenBalanceDiff(input);\n }\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 checkTokenBalanceDiff(input: TxDiffInput): BalanceVerdict {\n const mint = input.mint;\n if (!mint) {\n return { ok: false, reason: 'Expected mint for SPL verification, got none' };\n }\n const pre = input.preTokenBalances ?? [];\n const post = input.postTokenBalances ?? [];\n\n const tokenDelta = (ownerAddress: string): bigint => {\n // Pre-entry may be absent when the ATA is created inside the same tx\n // (first-ever payment to this recipient). Missing => 0.\n const preEntry = pre.find((entry) => entry.owner === ownerAddress && entry.mint === mint);\n const postEntry = post.find((entry) => entry.owner === ownerAddress && entry.mint === mint);\n if (!postEntry) {\n return -1n;\n }\n const preAmount = preEntry ? BigInt(preEntry.uiTokenAmount.amount) : 0n;\n const postAmount = BigInt(postEntry.uiTokenAmount.amount);\n return postAmount - preAmount;\n };\n\n const recipientDelta = tokenDelta(input.recipientAddress);\n if (recipientDelta === -1n) {\n return { ok: false, reason: 'Recipient token account not found in transaction' };\n }\n if (recipientDelta < BigInt(input.expectedNet)) {\n return {\n ok: false,\n reason: `Recipient received ${recipientDelta.toString()} tokens, expected >= ${input.expectedNet}`,\n };\n }\n\n if (input.expectedFee > 0) {\n const treasuryDelta = tokenDelta(input.treasuryAddress);\n if (treasuryDelta === -1n) {\n return { ok: false, reason: 'Treasury token account not found in transaction' };\n }\n if (treasuryDelta < BigInt(input.expectedFee)) {\n return {\n ok: false,\n reason: `Treasury received ${treasuryDelta.toString()} tokens, 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 transfer instructions for a payment request.\n *\n * For native SOL (no `paymentRequest.asset` or asset=NATIVE_SOL), emits System\n * program `TransferSol` instructions with the payment reference attached as a\n * read-only, non-signer account so providers can detect the payment via\n * `getSignaturesForAddress(reference)`.\n *\n * For SPL assets (USDC on Solana), emits:\n * 1. `CreateAssociatedTokenIdempotent` for the recipient ATA (funded by payer);\n * 2. `CreateAssociatedTokenIdempotent` for the treasury ATA if a protocol fee applies;\n * 3. `TransferChecked` from payer ATA to recipient ATA, with `reference` as an\n * extra read-only account (canonical Solana Pay pattern);\n * 4. `TransferChecked` from payer ATA to treasury ATA if a fee applies.\n *\n * Every provider transfer instruction also carries `ELISYM_PROTOCOL_TAG` as a\n * read-only marker account so off-chain indexers can enumerate every elisym\n * transaction with a single `getSignaturesForAddress(ELISYM_PROTOCOL_TAG)`\n * call, regardless of fee size.\n *\n * If `options.jobEventId` is provided, an SPL Memo instruction with payload\n * `elisym:v1:<jobEventId>` is prepended so explorers display the originating\n * Nostr job id and indexers can join on-chain payments back to off-chain\n * job context.\n *\n * Async because SPL ATAs are PDAs and `findAssociatedTokenPda` is async.\n *\n * Caller is responsible for validating `paymentRequest` upstream;\n * `buildTransaction` already does that before invoking this helper.\n */\nexport async function buildPaymentInstructions(\n paymentRequest: PaymentRequestData,\n payerSigner: Signer,\n options?: { jobEventId?: string; programId?: Address },\n): Promise<readonly unknown[]> {\n const recipient = address(paymentRequest.recipient);\n const reference = address(paymentRequest.reference);\n const protocolTag = address(ELISYM_PROTOCOL_TAG);\n const programId = options?.programId ?? getProtocolProgramId('devnet');\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 const statsPda = await deriveNetworkStatsAddress(programId);\n const eventAuthority = await deriveEventAuthorityAddress(programId);\n const incrementStatsIx = getIncrementStatsInstruction(\n {\n stats: statsPda,\n eventAuthority,\n program: programId,\n amount: BigInt(paymentRequest.amount),\n isNative: !resolveAssetFromPaymentRequest(paymentRequest).mint,\n },\n { programAddress: programId },\n );\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 memoInstruction = options?.jobEventId\n ? getAddMemoInstruction({ memo: `elisym:v1:${options.jobEventId}` })\n : null;\n\n // Native SOL path - unchanged from the pre-USDC behaviour.\n const asset = resolveAssetFromPaymentRequest(paymentRequest);\n if (!asset.mint) {\n const providerTransferIx = getTransferSolInstruction({\n source: payerSigner,\n destination: recipient,\n amount: BigInt(providerAmount),\n });\n const providerTransferIxWithMarkers = {\n ...providerTransferIx,\n accounts: [\n ...providerTransferIx.accounts,\n { address: reference, role: AccountRole.READONLY },\n { address: protocolTag, role: AccountRole.READONLY },\n ],\n };\n\n const instructions: unknown[] = [];\n if (memoInstruction) {\n instructions.push(memoInstruction);\n }\n instructions.push(providerTransferIxWithMarkers);\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 instructions.push(incrementStatsIx);\n return instructions;\n }\n\n // SPL path.\n const mint = address(asset.mint);\n const payerAddress = payerSigner.address;\n const [payerAta] = await findAssociatedTokenPda({\n owner: payerAddress,\n tokenProgram: TOKEN_PROGRAM_ADDRESS,\n mint,\n });\n const [recipientAta] = await findAssociatedTokenPda({\n owner: recipient,\n tokenProgram: TOKEN_PROGRAM_ADDRESS,\n mint,\n });\n\n const instructions: unknown[] = [];\n if (memoInstruction) {\n instructions.push(memoInstruction);\n }\n instructions.push(\n getCreateAssociatedTokenIdempotentInstruction(\n {\n payer: payerSigner,\n ata: recipientAta,\n owner: recipient,\n mint,\n },\n { programAddress: ASSOCIATED_TOKEN_PROGRAM_ADDRESS },\n ),\n );\n\n let treasuryAta: Address | undefined;\n if (paymentRequest.fee_address && feeAmount > 0) {\n const treasuryOwner = address(paymentRequest.fee_address);\n [treasuryAta] = await findAssociatedTokenPda({\n owner: treasuryOwner,\n tokenProgram: TOKEN_PROGRAM_ADDRESS,\n mint,\n });\n instructions.push(\n getCreateAssociatedTokenIdempotentInstruction(\n {\n payer: payerSigner,\n ata: treasuryAta,\n owner: treasuryOwner,\n mint,\n },\n { programAddress: ASSOCIATED_TOKEN_PROGRAM_ADDRESS },\n ),\n );\n }\n\n const providerTransferIx = getTransferCheckedInstruction({\n source: payerAta,\n mint,\n destination: recipientAta,\n authority: payerSigner,\n amount: BigInt(providerAmount),\n decimals: asset.decimals,\n });\n const providerTransferIxWithMarkers = {\n ...providerTransferIx,\n accounts: [\n ...providerTransferIx.accounts,\n { address: reference, role: AccountRole.READONLY },\n { address: protocolTag, role: AccountRole.READONLY },\n ],\n };\n instructions.push(providerTransferIxWithMarkers);\n\n if (treasuryAta && paymentRequest.fee_address && feeAmount > 0) {\n instructions.push(\n getTransferCheckedInstruction({\n source: payerAta,\n mint,\n destination: treasuryAta,\n authority: payerSigner,\n amount: BigInt(feeAmount),\n decimals: asset.decimals,\n }),\n );\n }\n\n instructions.push(incrementStatsIx);\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","/**\n * BlossomService - BUD-11 authenticated blob uploads to a Blossom server.\n *\n * Blossom (https://github.com/hzrd149/blossom) is content-addressed: blobs are stored\n * by sha256 and writes are authorized with a signed Nostr event (BUD-11, kind 24242) -\n * NOT NIP-98 (kind 27235) like MediaService/nostr.build. This service uploads to the\n * self-hosted elisym relay and, if that fails, falls back to an injected uploader (the\n * client wires MediaService/nostr.build in) so uploads stay resilient.\n */\nimport { finalizeEvent } from 'nostr-tools';\nimport { DEFAULTS, LIMITS } from '../constants';\nimport type { ElisymIdentity } from '../primitives/identity';\n\nconst KIND_BLOSSOM_AUTH = 24242;\nconst DEFAULT_BLOSSOM_URL = 'https://files.elisym.network';\nconst AUTH_TTL_SECS = 600;\n\n/** Result of an upload. */\nexport interface BlobDescriptor {\n /**\n * Publicly GET-able URL. Content-addressed (https://<host>/<sha256>.<ext>) ONLY when\n * `provider === 'blossom'`; on `'fallback'` it is a provider-assigned nostr.build URL\n * that may NOT be addressed by `sha256` (the host may re-encode the bytes).\n */\n url: string;\n /**\n * Lowercase-hex SHA-256 of the bytes the caller uploaded. On `'blossom'` it is also\n * verified to equal what the server stored (integrity check). On `'fallback'` it is the\n * local hash only - do NOT assume `url` resolves to it.\n */\n sha256: string;\n size: number;\n type: string;\n /** Unix seconds; only the Blossom path returns it. */\n uploaded?: number;\n provider: 'blossom' | 'fallback';\n}\n\n/** Fallback uploader invoked when the Blossom upload fails; returns the stored URL. */\nexport type BlossomUploadFallback = (identity: ElisymIdentity, file: Blob) => Promise<string>;\n\nexport class BlossomService {\n constructor(\n private serverUrl: string = DEFAULT_BLOSSOM_URL,\n private fallback?: BlossomUploadFallback,\n ) {}\n\n /**\n * Upload a file to the Blossom server, returning its descriptor. On any failure, falls\n * back to the configured uploader (if any) and returns a normalized descriptor with\n * `provider: 'fallback'`. Works with browser File objects and Node.js/Bun Blobs.\n */\n async upload(identity: ElisymIdentity, file: Blob): Promise<BlobDescriptor> {\n const bytes = new Uint8Array(await file.arrayBuffer());\n if (bytes.byteLength > LIMITS.MAX_FILE_SIZE) {\n throw new Error(\n `File too large: ${bytes.byteLength} bytes exceeds limit of ${LIMITS.MAX_FILE_SIZE}.`,\n );\n }\n\n const hashBuffer = await crypto.subtle.digest('SHA-256', bytes);\n const hashHex = [...new Uint8Array(hashBuffer)]\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n\n try {\n return await this.uploadToBlossom(identity, bytes, hashHex, file.type);\n } catch (err) {\n if (!this.fallback) {\n throw err;\n }\n const url = await this.fallback(identity, file);\n return {\n url,\n sha256: hashHex,\n size: file.size,\n type: file.type || 'application/octet-stream',\n provider: 'fallback',\n };\n }\n }\n\n /** Delete a blob by sha256 (BUD-02). Blossom only - there is no fallback for deletes. */\n async delete(identity: ElisymIdentity, sha256: string): Promise<void> {\n if (!/^[0-9a-f]{64}$/.test(sha256)) {\n throw new Error('sha256 must be 64 lowercase hex chars.');\n }\n\n const authHeader = this.authHeader(identity, 'delete', sha256);\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), DEFAULTS.BLOSSOM_UPLOAD_TIMEOUT_MS);\n try {\n const res = await fetch(`${this.serverUrl}/${sha256}`, {\n method: 'DELETE',\n headers: { Authorization: authHeader },\n signal: controller.signal,\n });\n if (!res.ok) {\n throw new Error(`Delete failed: ${res.status} ${res.statusText}`);\n }\n } finally {\n clearTimeout(timer);\n }\n }\n\n /**\n * Download a public blob (BUD-01 GET, no auth). Bounds memory on the ACTUAL streamed bytes (never\n * the declared Content-Length) and verifies the sha256 when `expectedSha256` is given. Browser-safe.\n */\n async download(\n url: string,\n opts: { maxBytes?: number; timeoutMs?: number; expectedSha256?: string } = {},\n ): Promise<Uint8Array> {\n const maxBytes = opts.maxBytes ?? LIMITS.MAX_FILE_SIZE;\n const controller = new AbortController();\n const timer = setTimeout(\n () => controller.abort(),\n opts.timeoutMs ?? DEFAULTS.BLOSSOM_FETCH_TIMEOUT_MS,\n );\n try {\n const res = await fetch(url, { signal: controller.signal });\n if (!res.ok) {\n throw new Error(`Download failed: ${res.status} ${res.statusText}`);\n }\n const declared = Number(res.headers.get('content-length'));\n if (Number.isFinite(declared) && declared > maxBytes) {\n throw new Error(`Blob too large: ${declared} bytes exceeds limit of ${maxBytes}.`);\n }\n if (!res.body) {\n throw new Error('Download response has no body.');\n }\n\n const reader = res.body.getReader();\n const chunks: Uint8Array[] = [];\n let total = 0;\n let chunk = await reader.read();\n while (!chunk.done) {\n total += chunk.value.byteLength;\n if (total > maxBytes) {\n await reader.cancel();\n throw new Error(`Blob exceeds limit of ${maxBytes} bytes.`);\n }\n chunks.push(chunk.value);\n chunk = await reader.read();\n }\n\n const bytes = new Uint8Array(total);\n let offset = 0;\n for (const c of chunks) {\n bytes.set(c, offset);\n offset += c.byteLength;\n }\n\n if (opts.expectedSha256 !== undefined) {\n const digest = await crypto.subtle.digest('SHA-256', bytes);\n const hashHex = [...new Uint8Array(digest)]\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n if (hashHex !== opts.expectedSha256) {\n throw new Error(\n `Download integrity check failed: got ${hashHex}, expected ${opts.expectedSha256}.`,\n );\n }\n }\n return bytes;\n } finally {\n clearTimeout(timer);\n }\n }\n\n private async uploadToBlossom(\n identity: ElisymIdentity,\n bytes: Uint8Array,\n hashHex: string,\n mime: string,\n ): Promise<BlobDescriptor> {\n const contentType = mime || 'application/octet-stream';\n const authHeader = this.authHeader(identity, 'upload', hashHex);\n\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), DEFAULTS.BLOSSOM_UPLOAD_TIMEOUT_MS);\n try {\n const res = await fetch(`${this.serverUrl}/upload`, {\n method: 'PUT',\n headers: { Authorization: authHeader, 'Content-Type': contentType },\n body: bytes,\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: {\n url?: string;\n sha256?: string;\n size?: number;\n type?: string;\n uploaded?: number;\n };\n try {\n data = await res.json();\n } catch {\n throw new Error('Invalid response from Blossom server.');\n }\n\n if (!data.url || !data.sha256) {\n throw new Error('No descriptor returned from Blossom server.');\n }\n if (data.sha256 !== hashHex) {\n throw new Error(\n `Blossom upload integrity check failed: server returned ${data.sha256}, expected ${hashHex}.`,\n );\n }\n\n return {\n url: data.url,\n sha256: data.sha256,\n size: data.size ?? bytes.byteLength,\n type: data.type ?? contentType,\n uploaded: data.uploaded,\n provider: 'blossom',\n };\n } finally {\n clearTimeout(timer);\n }\n }\n\n private authHeader(identity: ElisymIdentity, verb: 'upload' | 'delete', sha256: string): string {\n const now = Math.floor(Date.now() / 1000);\n const authEvent = finalizeEvent(\n {\n kind: KIND_BLOSSOM_AUTH,\n created_at: now,\n tags: [\n ['t', verb],\n ['x', sha256],\n ['expiration', String(now + AUTH_TTL_SECS)],\n ],\n content: `${verb} blob via elisym SDK`,\n },\n identity.secretKey,\n );\n // btoa is safe here: a signed Nostr event serializes to pure ASCII (hex ids/keys,\n // integer timestamps, ASCII tag strings and content).\n return 'Nostr ' + btoa(JSON.stringify(authEvent));\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,\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, SubCloser } from '../types';\n\nconst RANKING_ACTIVITY_WINDOW_SECS = 30 * 24 * 60 * 60;\nconst RANKING_BUCKET_SIZE_SECS = 60;\nconst COLD_START_BUCKET = -Infinity;\n\n/** Sentinel signal that never aborts; lets `runEnrichment` accept an `AbortSignal` uniformly. */\nconst NEVER_ABORTED_SIGNAL: AbortSignal = new AbortController().signal;\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/** Sort key derived from an Agent. Higher bucket / rate / lastPaidJobAt = ranks higher. */\nexport interface RankKey {\n /** Floor-to-minute timestamp of the agent's last verified paid job. `-Infinity` for cold start. */\n bucket: number;\n /** Positive review rate in `[0, 1]`. 0 when the agent has no rated feedback. */\n rate: number;\n /** Raw `lastPaidJobAt` (Unix sec) for tiebreak inside a bucket. 0 for cold start. */\n lastPaidJobAt: number;\n /** Final tiebreak; orders cold-start agents by NIP-89 freshness. */\n lastSeen: number;\n}\n\nexport function computeRankKey(agent: Agent): RankKey {\n const lastPaidJobAt = agent.lastPaidJobAt ?? 0;\n const total = agent.totalRatingCount ?? 0;\n const positive = agent.positiveCount ?? 0;\n const rate = total > 0 ? positive / total : 0;\n const bucket =\n lastPaidJobAt > 0\n ? Math.floor(lastPaidJobAt / RANKING_BUCKET_SIZE_SECS) * RANKING_BUCKET_SIZE_SECS\n : COLD_START_BUCKET;\n return { bucket, rate, lastPaidJobAt, lastSeen: agent.lastSeen };\n}\n\nexport function compareAgentsByRank(a: Agent, b: Agent): number {\n const ka = computeRankKey(a);\n const kb = computeRankKey(b);\n if (kb.bucket !== ka.bucket) {\n return kb.bucket - ka.bucket;\n }\n if (kb.rate !== ka.rate) {\n return kb.rate - ka.rate;\n }\n if (kb.lastPaidJobAt !== ka.lastPaidJobAt) {\n return kb.lastPaidJobAt - ka.lastPaidJobAt;\n }\n return kb.lastSeen - ka.lastSeen;\n}\n\n/**\n * Parse a single NIP-89 capability event into a one-card Agent.\n *\n * Returns `null` if the event fails signature verification, content schema\n * checks, or the `network` filter. The returned Agent's `supportedKinds`\n * holds only this event's `k` tags - merging across multiple events for the\n * same author is the caller's responsibility.\n */\nexport function parseCapabilityEvent(event: Event, network: Network): Agent | null {\n if (!verifyEvent(event)) {\n return null;\n }\n if (!event.content) {\n return null;\n }\n let raw: unknown;\n try {\n raw = JSON.parse(event.content);\n } catch {\n return null;\n }\n if (!raw || typeof raw !== 'object') {\n return null;\n }\n const candidate = raw as Record<string, unknown>;\n if (typeof candidate.name !== 'string' || !candidate.name) {\n return null;\n }\n if (typeof candidate.description !== 'string') {\n return null;\n }\n if (\n !Array.isArray(candidate.capabilities) ||\n !candidate.capabilities.every((cap: unknown) => typeof cap === 'string')\n ) {\n return null;\n }\n if (candidate.deleted) {\n return null;\n }\n const card = candidate as unknown as CapabilityCard & { deleted?: boolean };\n\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 return null;\n }\n\n // Optional token/symbol/mint must be strings when present: a non-string slips\n // through to display code (`payment.token.toUpperCase()`) and throws at render.\n if (\n card.payment &&\n ((card.payment.token !== undefined && typeof card.payment.token !== 'string') ||\n (card.payment.symbol !== undefined && typeof card.payment.symbol !== 'string') ||\n (card.payment.mint !== undefined && typeof card.payment.mint !== 'string'))\n ) {\n return null;\n }\n\n // Optional file-MIME hints must be bounded strings when present. This is\n // untrusted remote data; the cap (matching the loader's) keeps an unbounded\n // string out of client state. Clients gate on presence, not the value.\n if (\n (card.inputMime !== undefined &&\n (typeof card.inputMime !== 'string' || card.inputMime.length > 255)) ||\n (card.outputMime !== undefined &&\n (typeof card.outputMime !== 'string' || card.outputMime.length > 255))\n ) {\n return null;\n }\n\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 return null;\n }\n\n const agentNetwork = card.payment?.network ?? 'devnet';\n if (agentNetwork !== network) {\n return null;\n }\n\n const kTags = event.tags\n .filter((tag) => tag[0] === 'k')\n .map((tag) => parseInt(tag[1] ?? '', 10))\n .filter((kind) => !isNaN(kind));\n\n return {\n pubkey: event.pubkey,\n npub: nip19.npubEncode(event.pubkey),\n cards: [card],\n eventId: event.id,\n supportedKinds: kTags,\n lastSeen: event.created_at,\n };\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 // Verify here (not in `parseCapabilityEvent` alone) so a forged event with\n // a future `created_at` cannot displace a legitimate event from the dedup\n // map and effectively erase the victim's agent from results.\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((tag) => tag[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 // Per-pubkey accumulator. We track per-card `createdAt` + `kTags` so\n // `supportedKinds` is recomputed from only the surviving (name-dedup'd)\n // cards, matching the pre-refactor behavior.\n interface Accum {\n agent: Agent;\n perCard: Map<string, { createdAt: number; kTags: number[] }>;\n }\n const accumMap = new Map<string, Accum>();\n\n for (const event of latestByDTag.values()) {\n const parsed = parseCapabilityEvent(event, network);\n if (!parsed) {\n continue;\n }\n const card = parsed.cards[0]!;\n const cardKinds = parsed.supportedKinds;\n const createdAt = parsed.lastSeen;\n\n const existing = accumMap.get(parsed.pubkey);\n if (existing) {\n const prevForName = existing.perCard.get(card.name);\n if (prevForName) {\n if (createdAt >= prevForName.createdAt) {\n const idx = existing.agent.cards.findIndex(\n (existingCard) => existingCard.name === card.name,\n );\n if (idx >= 0) {\n existing.agent.cards[idx] = card;\n }\n existing.perCard.set(card.name, { createdAt, kTags: cardKinds });\n }\n } else {\n existing.agent.cards.push(card);\n existing.perCard.set(card.name, { createdAt, kTags: cardKinds });\n }\n if (createdAt > existing.agent.lastSeen) {\n existing.agent.lastSeen = createdAt;\n existing.agent.eventId = parsed.eventId;\n }\n } else {\n accumMap.set(parsed.pubkey, {\n agent: parsed,\n perCard: new Map([[card.name, { createdAt, kTags: cardKinds }]]),\n });\n }\n }\n\n const agentMap = new Map<string, Agent>();\n for (const [pubkey, acc] of accumMap) {\n const kindsSet = new Set<number>();\n for (const { kTags } of acc.perCard.values()) {\n for (const kind of kTags) {\n kindsSet.add(kind);\n }\n }\n acc.agent.supportedKinds = [...kindsSet];\n agentMap.set(pubkey, acc.agent);\n }\n\n return agentMap;\n}\n\nexport class DiscoveryService {\n constructor(private pool: NostrPool) {}\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.banner === 'string') {\n agent.banner = meta.banner;\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 /**\n * Fetch elisym agents filtered by network, ranked by paid-job recency and\n * positive-feedback rate.\n *\n * Ranking algorithm:\n * 1. Bucket each agent into 1-minute slots by `lastPaidJobAt` (newest\n * `payment-completed` feedback timestamp, gated by a matching kind:6xxx\n * result from the provider on the same job event). Cold-start agents go\n * into a sentinel bucket below all populated buckets.\n * 2. Within a bucket, sort by positive review rate descending.\n * 3. Tiebreak by raw `lastPaidJobAt`, then `lastSeen` (NIP-89 freshness).\n *\n * NOTE: We do not verify the `tx` signature on-chain - public Solana devnet\n * RPC rate-limits trivially exceed what discovery needs (N agents * up-to-5\n * candidates), and the resulting 429s blocked discovery entirely. As a\n * lighter sybil mitigation we cross-check `payment-completed` feedback\n * against a kind:6xxx result event authored by the provider on the same\n * job: a customer can publish a fake `payment-completed`, but they cannot\n * forge a result event signed by the provider. Tighten with recipient-tied\n * on-chain checks when the network moves to mainnet with a paid RPC\n * provider.\n */\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 const agents = Array.from(agentMap.values());\n\n return this.runEnrichment(agents, agentMap, NEVER_ABORTED_SIGNAL);\n }\n\n /**\n * Fetch a single agent by pubkey, fully enriched (kind:0 metadata,\n * cross-checked `lastPaidJobAt`, rating counters). Returns `null` if the\n * pubkey has no surviving capability cards on the requested network.\n *\n * Use this when navigating directly to an agent's page; running\n * `fetchAgents`/`streamAgents` for that case streams the entire marketplace\n * just to find one author.\n */\n async fetchAgent(network: Network, pubkey: string): Promise<Agent | null> {\n const events = await this.pool.querySync({\n kinds: [KIND_APP_HANDLER],\n '#t': ['elisym'],\n authors: [pubkey],\n });\n\n const agentMap = buildAgentsFromEvents(events, network);\n if (agentMap.size === 0) {\n return null;\n }\n const agents = Array.from(agentMap.values());\n await this.runEnrichment(agents, agentMap, NEVER_ABORTED_SIGNAL);\n return agentMap.get(pubkey) ?? null;\n }\n\n /**\n * Enrich an agent map with paid-job stats, feedback counters, and kind:0\n * metadata, then return them sorted by `compareAgentsByRank`. Mutates the\n * passed-in `Agent` objects in place.\n *\n * Shared between `fetchAgents` (one-shot) and `streamAgents` (post-EOSE\n * second pass). The `signal` short-circuits the post-query work; in-flight\n * pool queries are not cancellable today (they fall through to the standard\n * timeout) and the caller drops the resolved value.\n */\n private async runEnrichment(\n agents: Agent[],\n agentMap: Map<string, Agent>,\n signal: AbortSignal,\n ): Promise<Agent[]> {\n const agentPubkeys = Array.from(agentMap.keys());\n if (agentPubkeys.length === 0) {\n return agents;\n }\n\n const activitySince = Math.floor(Date.now() / 1000) - RANKING_ACTIVITY_WINDOW_SECS;\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 supportedKind of agent.supportedKinds) {\n if (supportedKind >= KIND_JOB_REQUEST_BASE && supportedKind < KIND_JOB_RESULT_BASE) {\n resultKinds.add(KIND_JOB_RESULT_BASE + (supportedKind - KIND_JOB_REQUEST_BASE));\n }\n }\n }\n resultKinds.add(jobResultKind(DEFAULT_KIND_OFFSET));\n\n const [resultEvents, feedbackEvents] = await Promise.all([\n this.pool.queryBatched(\n {\n kinds: [...resultKinds],\n since: activitySince,\n } as Omit<Filter, 'authors'>,\n agentPubkeys,\n ),\n this.pool.queryBatchedByTag(\n { kinds: [KIND_JOB_FEEDBACK], since: activitySince } as Filter,\n 'p',\n agentPubkeys,\n ),\n this.enrichWithMetadata(agents),\n ]);\n\n if (signal.aborted) {\n return agents;\n }\n\n // Result events: written by the agent, indexed by author. Build\n // (provider, jobEventId) pairs so we can cross-check `payment-completed`\n // feedback against an actual delivered result. Customers publish\n // `payment-completed` immediately on payment, before the result arrives -\n // an unmatched feedback means the provider never delivered (or never\n // existed at the time), so it must not count as a verified paid job.\n const deliveredJobsByProvider = new Map<string, Set<string>>();\n // jobEventId -> the customer pubkey the provider addressed the result to\n // (the result's `p` tag is `requestEvent.pubkey`, see submitJobResult). Used\n // to bind feedback/rating authorship to the job's actual customer below.\n const customerByJob = new Map<string, string>();\n for (const ev of resultEvents) {\n if (!verifyEvent(ev)) {\n continue;\n }\n const agent = agentMap.get(ev.pubkey);\n if (!agent) {\n continue;\n }\n if (ev.created_at > agent.lastSeen) {\n agent.lastSeen = ev.created_at;\n }\n const jobEventId = ev.tags.find((tag) => tag[0] === 'e')?.[1];\n if (jobEventId) {\n let delivered = deliveredJobsByProvider.get(ev.pubkey);\n if (!delivered) {\n delivered = new Set();\n deliveredJobsByProvider.set(ev.pubkey, delivered);\n }\n delivered.add(jobEventId);\n const customerPubkey = ev.tags.find((tag) => tag[0] === 'p')?.[1];\n if (customerPubkey) {\n customerByJob.set(jobEventId, customerPubkey);\n }\n }\n }\n\n // Feedback events: written by the *customer*, target agent in the `p` tag.\n // Tally rating counters and pick the newest `payment-completed` feedback\n // per agent as `lastPaidJobAt` / `lastPaidJobTx`. A feedback only counts\n // when (a) it references a job (`e` tag) that has a matching kind:6xxx\n // result from the provider, and (b) its author is the customer that result\n // was addressed to. This blocks unauthenticated third parties from inflating\n // ratings / minting paid-job timestamps. Provider-vs-sock-puppet collusion\n // still needs on-chain payment verification (roadmap).\n const countedRatings = new Set<string>();\n for (const ev of feedbackEvents) {\n if (!verifyEvent(ev)) {\n continue;\n }\n const targetPubkey = ev.tags.find((tag) => tag[0] === 'p')?.[1];\n if (!targetPubkey) {\n continue;\n }\n const agent = agentMap.get(targetPubkey);\n if (!agent) {\n continue;\n }\n if (ev.created_at > agent.lastSeen) {\n agent.lastSeen = ev.created_at;\n }\n\n const jobEventId = ev.tags.find((tag) => tag[0] === 'e')?.[1];\n const hasDeliveredResult =\n jobEventId !== undefined &&\n deliveredJobsByProvider.get(targetPubkey)?.has(jobEventId) === true;\n // Was this feedback authored by the job's actual customer?\n const jobCustomer = jobEventId !== undefined ? customerByJob.get(jobEventId) : undefined;\n const authoredByCustomer = jobCustomer !== undefined && ev.pubkey === jobCustomer;\n\n const rating = ev.tags.find((tag) => tag[0] === 'rating')?.[1];\n if ((rating === '1' || rating === '0') && hasDeliveredResult && authoredByCustomer) {\n // Dedupe: at most one rating per (customer, job).\n const ratingKey = `${ev.pubkey}:${jobEventId}`;\n if (!countedRatings.has(ratingKey)) {\n countedRatings.add(ratingKey);\n agent.totalRatingCount = (agent.totalRatingCount ?? 0) + 1;\n if (rating === '1') {\n agent.positiveCount = (agent.positiveCount ?? 0) + 1;\n }\n }\n }\n\n const status = ev.tags.find((tag) => tag[0] === 'status')?.[1];\n const txTag = ev.tags.find((tag) => tag[0] === 'tx');\n const txSignature = txTag?.[1];\n if (\n status === 'payment-completed' &&\n typeof txSignature === 'string' &&\n txSignature &&\n hasDeliveredResult &&\n authoredByCustomer\n ) {\n if (!agent.lastPaidJobAt || ev.created_at > agent.lastPaidJobAt) {\n agent.lastPaidJobAt = ev.created_at;\n agent.lastPaidJobTx = txSignature;\n }\n }\n }\n\n agents.sort(compareAgentsByRank);\n\n return agents;\n }\n\n /**\n * Stream elisym agents progressively as relays deliver events.\n *\n * Two live subscriptions:\n * - kind:31990 (capability cards) - emits `onAgent(agent)` for every new or\n * updated `(pubkey, d-tag)`. The emitted Agent is the merged view across\n * all surviving cards for that author.\n * - kind:6100 (default-offset job results) tagged `t=elisym` since 30d ago -\n * emits `onPaidJob(pubkey, ts)` for each delivered result. Custom-kind\n * results (offset != 100) are not on this stream; they enter the final\n * ranking via the post-EOSE enrichment pass.\n *\n * After capabilities EOSE, an enrichment pass runs in parallel to the live\n * subscriptions and produces a ranked snapshot via `onComplete`. The snapshot\n * is a clone, so further live updates do not mutate it.\n *\n * `closer.close()` tears down both subscriptions and aborts an in-flight\n * enrichment. If `opts.signal` is provided, aborting it does the same.\n */\n streamAgents(\n network: Network,\n opts: {\n onAgent: (agent: Agent) => void;\n onPaidJob?: (pubkey: string, ts: number) => void;\n onEose?: () => void;\n onComplete?: (agents: Agent[]) => void;\n signal?: AbortSignal;\n },\n ): SubCloser {\n const eventsByPubkey = new Map<string, Map<string, Event>>();\n const agentByPubkey = new Map<string, Agent>();\n const eoseSeen = { caps: false, results: false };\n let enrichmentStarted = false;\n const enrichmentAbort = new AbortController();\n\n const onExternalAbort = () => enrichmentAbort.abort();\n if (opts.signal) {\n if (opts.signal.aborted) {\n enrichmentAbort.abort();\n } else {\n opts.signal.addEventListener('abort', onExternalAbort, { once: true });\n }\n }\n\n const checkEose = () => {\n if (eoseSeen.caps && eoseSeen.results) {\n opts.onEose?.();\n }\n };\n\n const startEnrichment = () => {\n if (enrichmentStarted) {\n return;\n }\n enrichmentStarted = true;\n // Snapshot live agents so further `onAgent` updates do not race with\n // enrichment mutation.\n const snapshotAgents = Array.from(agentByPubkey.values()).map((agent) => ({ ...agent }));\n const snapshotMap = new Map(snapshotAgents.map((agent) => [agent.pubkey, agent]));\n void this.runEnrichment(snapshotAgents, snapshotMap, enrichmentAbort.signal).then(\n (sorted) => {\n if (enrichmentAbort.signal.aborted) {\n return;\n }\n opts.onComplete?.(sorted);\n },\n () => {\n /* enrichment errors are swallowed - stream stays usable until closed */\n },\n );\n };\n\n const capSub = this.pool.subscribe(\n { kinds: [KIND_APP_HANDLER], '#t': ['elisym'] },\n (event) => {\n const dTag = event.tags.find((tag) => tag[0] === 'd')?.[1] ?? '';\n let perDTag = eventsByPubkey.get(event.pubkey);\n const prev = perDTag?.get(dTag);\n if (prev && event.created_at <= prev.created_at) {\n return;\n }\n // Verify before trusting `event.pubkey`. An unsigned forged event with a\n // future `created_at` would otherwise displace a legitimate event from\n // the (pubkey, d-tag) slot.\n if (!verifyEvent(event)) {\n return;\n }\n\n // Distinguish tombstones (`{deleted: true}`) from invalid events.\n // `parseCapabilityEvent` returns null for both, but tombstones must be\n // stored in `perDTag` so the next `buildAgentsFromEvents` re-merge can\n // drop the corresponding card. Truthy check matches the validator in\n // `parseCapabilityEvent` (`if (candidate.deleted) return null`).\n if (!event.content) {\n return;\n }\n let payload: unknown;\n try {\n payload = JSON.parse(event.content);\n } catch {\n return;\n }\n const isTombstone =\n payload !== null &&\n typeof payload === 'object' &&\n Boolean((payload as { deleted?: unknown }).deleted);\n\n if (!isTombstone && !parseCapabilityEvent(event, network)) {\n return;\n }\n\n if (!perDTag) {\n perDTag = new Map();\n eventsByPubkey.set(event.pubkey, perDTag);\n }\n perDTag.set(dTag, event);\n\n const merged = buildAgentsFromEvents(Array.from(perDTag.values()), network).get(\n event.pubkey,\n );\n if (!merged) {\n // All cards for this author are now tombstoned. Drop the agent from\n // the snapshot so the post-EOSE enrichment pass excludes it. The\n // live UI will continue to show the agent until the next remount;\n // adding a removal callback is the proper fix.\n agentByPubkey.delete(event.pubkey);\n return;\n }\n agentByPubkey.set(event.pubkey, merged);\n opts.onAgent(merged);\n },\n {\n oneose: () => {\n eoseSeen.caps = true;\n startEnrichment();\n checkEose();\n },\n },\n );\n\n const activitySince = Math.floor(Date.now() / 1000) - RANKING_ACTIVITY_WINDOW_SECS;\n const resultsSub = this.pool.subscribe(\n { kinds: [KIND_JOB_RESULT], '#t': ['elisym'], since: activitySince },\n (event) => {\n // Verify signature before trusting `event.pubkey`. Without this, a\n // forged unsigned event would let an attacker bump any pubkey's\n // streaming `lastPaidJobAt` until enrichment overrides it. The\n // post-enrichment flush guards against bare-event spoofing once\n // `lastPaidJobTx` is set, but the pre-enrichment window would\n // otherwise be unprotected.\n if (!verifyEvent(event)) {\n return;\n }\n opts.onPaidJob?.(event.pubkey, event.created_at);\n },\n {\n oneose: () => {\n eoseSeen.results = true;\n checkEose();\n },\n },\n );\n\n return {\n close: (reason) => {\n capSub.close(reason);\n resultsSub.close(reason);\n enrichmentAbort.abort();\n opts.signal?.removeEventListener('abort', onExternalAbort);\n },\n };\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","/**\n * Job file-attachment descriptor and the job-payload envelope (browser-safe).\n *\n * A file job carries its file out-of-band (P2P via iroh); the Nostr event's\n * (NIP-44-encrypted) `content` carries only a small JSON envelope describing the\n * file and how to fetch it. This module owns the envelope shape, its encode, and\n * its strict decode. It deliberately does NOT construct an iroh `BlobTicket` - the\n * `ticket` is validated only as a bounded opaque string so that decoding an\n * untrusted, possibly pre-payment request never pulls in the native iroh addon.\n *\n * The transport is a discriminated union keyed on `kind`; Phase 1 ships only\n * `iroh`. A future HTTP/Blossom transport is added as another union member without\n * changing this contract.\n */\nimport { z } from 'zod';\nimport { LIMITS } from '../constants';\n\n/** Current envelope version. Bumped only on a breaking envelope-shape change. */\nexport const ENVELOPE_VERSION = 'elisym-job/1';\n\n/** Namespace prefix shared by all envelope versions, used to detect \"this is ours\". */\nconst ENVELOPE_NAMESPACE_PREFIX = 'elisym-job/';\n\n/** Upper bound on a serialized transport locator (e.g. an iroh BlobTicket string). */\nconst MAX_TICKET_LENGTH = 4096;\n\nconst FileTransportSchema = z.discriminatedUnion('kind', [\n z.object({\n kind: z.literal('iroh'),\n /** Opaque iroh `BlobTicket` string. Parsed into a real ticket only at fetch time. */\n ticket: z.string().min(1).max(MAX_TICKET_LENGTH),\n }),\n z.object({\n kind: z.literal('blossom'),\n /** Public HTTP(S) URL of the CIPHERTEXT blob on a Blossom relay. */\n url: z.string().url().max(2048),\n /** sha256 (lowercase hex) of the ciphertext - what the relay stores and addresses. */\n sha256: z.string().regex(/^[0-9a-f]{64}$/),\n /**\n * Hybrid-encryption parameters. The file bytes are AES-256-GCM encrypted with a random\n * content key; that key is NIP-44-wrapped to the recipient. `name`/`mime`/`size` on the\n * attachment describe the PLAINTEXT and live only inside the (encrypted) envelope - never\n * sent to the relay (the relay only ever sees opaque ciphertext).\n */\n enc: z.object({\n alg: z.literal('AES-256-GCM'),\n /** base64 12-byte GCM IV (non-secret). */\n iv: z.string().min(1).max(64),\n /** NIP-44-wrapped content key. */\n key: z.string().min(1).max(2048),\n }),\n }),\n]);\n\nconst FileAttachmentSchema = z.object({\n /** Display name only. Never used to derive a filesystem path (callers sanitize). */\n name: z.string().min(1).max(255),\n /** Declared size in bytes (display/hint only; enforcement is on actual streamed bytes). */\n size: z.number().int().nonnegative(),\n mime: z.string().min(1).max(255),\n /**\n * Ordered by sender preference; at least one KNOWN transport. Parsed leniently: unknown\n * transport `kind`s are dropped (not rejected) so adding a new transport never makes an older\n * decoder throw away the whole envelope - it just ignores the kinds it doesn't know and uses\n * the ones it does. At least one known transport must survive, else the attachment is invalid.\n */\n transports: z\n .array(z.unknown())\n .transform((arr): z.infer<typeof FileTransportSchema>[] =>\n arr.flatMap((t) => {\n const parsed = FileTransportSchema.safeParse(t);\n return parsed.success ? [parsed.data] : [];\n }),\n )\n .refine((arr) => arr.length >= 1, { message: 'attachment has no known transport' }),\n /** Optional provider hint (unix seconds) for when seeding may stop. */\n seedingExpiresAt: z.number().int().nonnegative().optional(),\n});\n\nconst JobPayloadEnvelopeSchema = z.object({\n v: z.literal(ENVELOPE_VERSION),\n text: z.string().optional(),\n attachment: FileAttachmentSchema.optional(),\n});\n\nexport type FileTransport = z.infer<typeof FileTransportSchema>;\nexport type FileAttachment = z.infer<typeof FileAttachmentSchema>;\nexport type JobPayloadEnvelope = z.infer<typeof JobPayloadEnvelopeSchema>;\n\n/** The kinds of file transport a job can use ('iroh' | 'blossom'). */\nexport type TransportKind = FileTransport['kind'];\n\n/** Public job-request tag advertising which transports a customer can RECEIVE output on. */\nexport const ACCEPT_TRANSPORTS_TAG = 'accept';\n\nconst KNOWN_TRANSPORT_KINDS: readonly TransportKind[] = ['iroh', 'blossom'];\n\nfunction isKnownTransportKind(value: string): value is TransportKind {\n return (KNOWN_TRANSPORT_KINDS as readonly string[]).includes(value);\n}\n\n/**\n * Build the `['accept', ...kinds]` job-request tag from a client's RECEIVE-capable transports.\n * Drops unknown kinds and dedupes, preserving the client's preference order.\n */\nexport function buildAcceptTransportsTag(kinds: TransportKind[]): string[] {\n const seen = new Set<string>();\n const out: string[] = [ACCEPT_TRANSPORTS_TAG];\n for (const kind of kinds) {\n if (isKnownTransportKind(kind) && !seen.has(kind)) {\n seen.add(kind);\n out.push(kind);\n }\n }\n return out;\n}\n\n/**\n * Read accepted transports from an event's tags. Returns the ordered, deduped, known kinds, or\n * `undefined` when there is no `accept` tag or it carries no known kind - both normalize to the\n * provider's default (seed all transports). Lenient: unknown kinds (from a newer client) are ignored\n * so this never strands a job.\n */\nexport function readAcceptedTransports(tags: string[][]): TransportKind[] | undefined {\n const tag = tags.find((t) => t[0] === ACCEPT_TRANSPORTS_TAG);\n if (tag === undefined) {\n return undefined;\n }\n const seen = new Set<string>();\n const out: TransportKind[] = [];\n for (const value of tag.slice(1)) {\n if (isKnownTransportKind(value) && !seen.has(value)) {\n seen.add(value);\n out.push(value);\n }\n }\n return out.length > 0 ? out : undefined;\n}\n\n/** Decoded job payload: a free-text note and/or a file attachment. */\nexport interface DecodedJobPayload {\n text?: string;\n attachment?: FileAttachment;\n}\n\n/**\n * Serialize a job payload into the envelope string that goes (encrypted) into a\n * Nostr event's `content`. Used only when an attachment is present; plain-text\n * jobs send their text directly and are never wrapped.\n */\nexport function encodeJobPayload(payload: DecodedJobPayload): string {\n const envelope: JobPayloadEnvelope = { v: ENVELOPE_VERSION };\n if (payload.text !== undefined) {\n envelope.text = payload.text;\n }\n if (payload.attachment !== undefined) {\n envelope.attachment = payload.attachment;\n }\n return JSON.stringify(envelope);\n}\n\n/**\n * Decode decrypted `content` into a job payload.\n *\n * - Content longer than `MAX_INPUT_LENGTH` is treated as raw text without parsing\n * (a valid envelope is small and a valid text job is capped at submit time), so\n * untrusted, possibly-huge intake content is never `JSON.parse`d unbounded.\n * - Non-JSON, non-object JSON, or a JSON object that does not carry our\n * `elisym-job/` version marker is returned as raw text.\n * - A value that DOES carry an `elisym-job/` marker is validated strictly: an\n * unknown version or a malformed envelope throws (callers skip/surface it)\n * rather than being silently mistreated as text.\n */\nexport function decodeJobPayload(content: string): DecodedJobPayload {\n if (content.length > LIMITS.MAX_INPUT_LENGTH) {\n return { text: content };\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(content);\n } catch {\n return { text: content };\n }\n\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n return { text: content };\n }\n\n const version = (parsed as { v?: unknown }).v;\n if (typeof version !== 'string' || !version.startsWith(ENVELOPE_NAMESPACE_PREFIX)) {\n return { text: content };\n }\n\n const result = JobPayloadEnvelopeSchema.safeParse(parsed);\n if (!result.success) {\n throw new Error(\n `Invalid elisym job payload (v=${JSON.stringify(version)}): ${result.error.message}`,\n );\n }\n\n return { text: result.data.text, attachment: result.data.attachment };\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 utf8ByteLength,\n} from '../constants';\nimport { assertLamports } from '../payment/fee';\nimport { parsePaymentRequest } from '../payment/schema';\nimport { nip44Encrypt, nip44Decrypt } from '../primitives/crypto';\nimport type { ElisymIdentity } from '../primitives/identity';\nimport {\n encodeJobPayload,\n decodeJobPayload,\n buildAcceptTransportsTag,\n type FileAttachment,\n} from '../transport/attachment';\nimport type { NostrPool } from '../transport/pool';\nimport type {\n Job,\n JobStatus,\n PaymentAssetRef,\n SubCloser,\n SubmitJobOptions,\n JobSubscriptionOptions,\n} 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 const hasAttachment = options.attachment !== undefined;\n if (!options.input && !hasAttachment) {\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 // A file job wraps the (optional) text note + attachment in an envelope; a\n // plain-text job sends its text directly. The `i` tag is unchanged either way.\n const plaintext = hasAttachment\n ? encodeJobPayload({ text: options.input || undefined, attachment: options.attachment })\n : options.input;\n // NIP-44 backstop: the plaintext (post-envelope, the exact string handed to\n // nip44Encrypt) must fit the 65_535-byte cap or nip44Encrypt throws cryptically.\n // Large text should have been spilled to an attachment by the caller before here.\n if (options.providerPubkey) {\n const plaintextBytes = utf8ByteLength(plaintext);\n if (plaintextBytes > LIMITS.NIP44_MAX_PLAINTEXT_BYTES) {\n throw new Error(\n `Encrypted job input too large: ${plaintextBytes} bytes (max ${LIMITS.NIP44_MAX_PLAINTEXT_BYTES}). Send large input as a file/iroh attachment instead.`,\n );\n }\n }\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 if (options.acceptTransports && options.acceptTransports.length > 0) {\n // Advertise which transports this customer can RECEIVE output on. Public, signed tag; the\n // provider reads it to decide which transports to seed. Skip if no known kind survives.\n const acceptTag = buildAcceptTransportsTag(options.acceptTransports);\n if (acceptTag.length > 1) {\n tags.push(acceptTag);\n }\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 let decoded;\n try {\n decoded = decodeJobPayload(content);\n } catch {\n // Malformed/unknown-version envelope - skip like an undecryptable result\n // rather than crashing the subscription.\n return;\n }\n resultDelivered = true;\n try {\n // For a file result, surface the text note (or '') plus the attachment\n // descriptor; the file is fetched separately, never inlined here.\n cb.onResult?.(decoded.text ?? '', ev.id, decoded.attachment);\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 // For targeted jobs (`provPk` set) an `error` feedback from\n // THE provider is terminal: surface the message via `onError`\n // and close the subscription so the customer doesn't sit\n // waiting until the global timeout. Broadcast jobs (no\n // `provPk`) intentionally keep the subscription open - a\n // single provider's rejection should not silence the others.\n if (provPk && statusTag[1] === 'error' && !resolved) {\n const errorMessage = ev.content?.trim() || 'Provider returned an error';\n done();\n try {\n cb.onError?.(errorMessage);\n } catch {\n /* caller error - don't crash subscription */\n }\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 // Prefer the structured `onTimeout` signal; fall back to the\n // legacy `onError` string so callers that predate `onTimeout`\n // (and the external agent `hire.ts` scripts) keep working.\n if (cb.onTimeout) {\n cb.onTimeout(timeoutMs);\n } else {\n cb.onError?.(`Timed out waiting for response (${timeoutMs / 1000}s).`);\n }\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 attachment?: FileAttachment,\n ): Promise<string> {\n const hasAttachment = attachment !== undefined;\n if (!content && !hasAttachment) {\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 // A file result wraps the (optional) text + attachment in an envelope so the\n // recovery/empty-content path always has non-empty content to deliver.\n const payload = hasAttachment\n ? encodeJobPayload({ text: content || undefined, attachment })\n : content;\n // NIP-44 backstop (same as submitJobRequest): the post-envelope payload must\n // fit the 65_535-byte cap. A large text result should have been spilled to a\n // text/plain attachment by the provider, leaving only the small ticket here.\n if (shouldEncrypt) {\n const payloadBytes = utf8ByteLength(payload);\n if (payloadBytes > LIMITS.NIP44_MAX_PLAINTEXT_BYTES) {\n throw new Error(\n `Encrypted job result too large: ${payloadBytes} bytes (max ${LIMITS.NIP44_MAX_PLAINTEXT_BYTES}). Deliver large results as a file/iroh attachment instead.`,\n );\n }\n }\n const resultContent = shouldEncrypt\n ? nip44Encrypt(payload, identity.secretKey, requestEvent.pubkey)\n : payload;\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 attachment?: FileAttachment,\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, attachment);\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 let asset: PaymentAssetRef | 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 + payment asset (encoded inside the\n // payment-required feedback's amount tag as `[amount, raw, requestJson, chain]`).\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] && !txHash) {\n txHash = txTag[1];\n }\n if (!asset) {\n const amtTag = fb.tags.find((t) => t[0] === 'amount');\n const requestJson = amtTag?.[2];\n if (requestJson) {\n const parsed = parsePaymentRequest(requestJson);\n if (parsed.ok && parsed.data.asset) {\n asset = parsed.data.asset;\n }\n }\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 asset,\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","import { type Event, type Filter, finalizeEvent, nip19, verifyEvent } from 'nostr-tools';\nimport {\n KIND_LONG_FORM_ARTICLE,\n LIMITS,\n POLICY_D_TAG_PREFIX,\n POLICY_T_TAG,\n POLICY_TYPE_REGEX,\n} from '../constants';\nimport type { ElisymIdentity } from '../primitives/identity';\nimport type { NostrPool } from '../transport/pool';\nimport type { AgentPolicy, PolicyInput } from '../types';\n\nfunction dTagFor(type: string): string {\n return `${POLICY_D_TAG_PREFIX}${type}`;\n}\n\nfunction validatePolicyInput(input: PolicyInput): void {\n if (!POLICY_TYPE_REGEX.test(input.type)) {\n throw new Error(\n `Invalid policy type \"${input.type}\". Must be lowercase ASCII + hyphen, 1-${LIMITS.MAX_POLICY_TYPE_LENGTH} chars, no leading/trailing hyphen.`,\n );\n }\n if (input.version.length === 0 || input.version.length > LIMITS.MAX_POLICY_VERSION_LENGTH) {\n throw new Error(\n `Policy version must be 1-${LIMITS.MAX_POLICY_VERSION_LENGTH} chars (got ${input.version.length}).`,\n );\n }\n if (input.title.length === 0 || input.title.length > LIMITS.MAX_POLICY_TITLE_LENGTH) {\n throw new Error(\n `Policy title must be 1-${LIMITS.MAX_POLICY_TITLE_LENGTH} chars (got ${input.title.length}).`,\n );\n }\n if (input.summary !== undefined && input.summary.length > LIMITS.MAX_POLICY_SUMMARY_LENGTH) {\n throw new Error(\n `Policy summary too long: ${input.summary.length} chars (max ${LIMITS.MAX_POLICY_SUMMARY_LENGTH}).`,\n );\n }\n if (input.content.length === 0) {\n throw new Error('Policy content cannot be empty.');\n }\n if (input.content.length > LIMITS.MAX_POLICY_CONTENT_LENGTH) {\n throw new Error(\n `Policy content too long: ${input.content.length} chars (max ${LIMITS.MAX_POLICY_CONTENT_LENGTH}).`,\n );\n }\n}\n\nfunction parsePolicyEvent(event: Event): AgentPolicy | null {\n if (!verifyEvent(event)) {\n return null;\n }\n if (event.kind !== KIND_LONG_FORM_ARTICLE) {\n return null;\n }\n if (!event.content || event.content.length > LIMITS.MAX_POLICY_CONTENT_LENGTH) {\n return null;\n }\n\n const dTag = event.tags.find((tag) => tag[0] === 'd')?.[1];\n if (!dTag || !dTag.startsWith(POLICY_D_TAG_PREFIX)) {\n return null;\n }\n\n const type = event.tags.find((tag) => tag[0] === 'policy_type')?.[1];\n if (!type || !POLICY_TYPE_REGEX.test(type)) {\n return null;\n }\n\n const version = event.tags.find((tag) => tag[0] === 'policy_version')?.[1];\n if (!version || version.length > LIMITS.MAX_POLICY_VERSION_LENGTH) {\n return null;\n }\n\n const title = event.tags.find((tag) => tag[0] === 'title')?.[1];\n if (!title || title.length > LIMITS.MAX_POLICY_TITLE_LENGTH) {\n return null;\n }\n\n const summaryTag = event.tags.find((tag) => tag[0] === 'summary')?.[1];\n const summary =\n summaryTag !== undefined && summaryTag.length <= LIMITS.MAX_POLICY_SUMMARY_LENGTH\n ? summaryTag\n : undefined;\n\n const naddr = nip19.naddrEncode({\n kind: KIND_LONG_FORM_ARTICLE,\n pubkey: event.pubkey,\n identifier: dTag,\n relays: [],\n });\n\n return {\n type,\n version,\n title,\n summary,\n content: event.content,\n naddr,\n dTag,\n publishedAt: event.created_at,\n eventId: event.id,\n authorPubkey: event.pubkey,\n };\n}\n\nexport class PoliciesService {\n constructor(private pool: NostrPool) {}\n\n /**\n * Fetch all elisym policies published by `pubkey`. Verifies signatures,\n * dedupes by d-tag (latest `created_at` wins), and returns sorted by `type`\n * for deterministic UI rendering.\n *\n * Returns `[]` on empty result. Network errors propagate to the caller.\n */\n async fetchPolicies(pubkey: string): Promise<AgentPolicy[]> {\n const filter: Filter = {\n kinds: [KIND_LONG_FORM_ARTICLE],\n authors: [pubkey],\n '#t': [POLICY_T_TAG],\n };\n const events = await this.pool.querySync(filter);\n\n const latestByDTag = new Map<string, Event>();\n for (const event of events) {\n const dTag = event.tags.find((tag) => tag[0] === 'd')?.[1] ?? '';\n const prev = latestByDTag.get(dTag);\n if (!prev || event.created_at > prev.created_at) {\n latestByDTag.set(dTag, event);\n }\n }\n\n const policies: AgentPolicy[] = [];\n for (const event of latestByDTag.values()) {\n const parsed = parsePolicyEvent(event);\n if (parsed) {\n policies.push(parsed);\n }\n }\n policies.sort((a, b) => a.type.localeCompare(b.type));\n return policies;\n }\n\n /**\n * Publish a policy as a NIP-23 long-form article (kind 30023). Replaces any\n * existing policy of the same `type` for this pubkey via the addressable\n * `(kind, pubkey, d-tag)` slot.\n */\n async publishPolicy(\n identity: ElisymIdentity,\n input: PolicyInput,\n ): Promise<{ eventId: string; naddr: string }> {\n validatePolicyInput(input);\n\n const dTag = dTagFor(input.type);\n const tags: string[][] = [\n ['d', dTag],\n ['t', POLICY_T_TAG],\n ['title', input.title],\n ['policy_type', input.type],\n ['policy_version', input.version],\n ];\n if (input.summary) {\n tags.push(['summary', input.summary]);\n }\n\n const event = finalizeEvent(\n {\n kind: KIND_LONG_FORM_ARTICLE,\n created_at: Math.floor(Date.now() / 1000),\n tags,\n content: input.content,\n },\n identity.secretKey,\n );\n\n await this.pool.publishAll(event);\n\n const naddr = nip19.naddrEncode({\n kind: KIND_LONG_FORM_ARTICLE,\n pubkey: event.pubkey,\n identifier: dTag,\n relays: [],\n });\n\n return { eventId: event.id, naddr };\n }\n\n /**\n * Tombstone a policy by publishing an empty replacement under the same\n * `(kind, pubkey, d-tag)` slot. Readers skip events with empty content.\n */\n async deletePolicy(identity: ElisymIdentity, type: string): Promise<string> {\n if (!POLICY_TYPE_REGEX.test(type)) {\n throw new Error(`Invalid policy type \"${type}\".`);\n }\n const dTag = dTagFor(type);\n const event = finalizeEvent(\n {\n kind: KIND_LONG_FORM_ARTICLE,\n created_at: Math.floor(Date.now() / 1000),\n tags: [\n ['d', dTag],\n ['t', POLICY_T_TAG],\n ['policy_type', type],\n ],\n content: '',\n },\n identity.secretKey,\n );\n await this.pool.publishAll(event);\n return event.id;\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(\n filter: Filter,\n onEvent: (event: Event) => void,\n opts?: { oneose?: () => void },\n ): SubCloser {\n const rawSub = this.pool.subscribeMany(this.relays, filter, {\n onevent: onEvent,\n oneose: opts?.oneose,\n });\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 { BlossomService } from './services/blossom';\nimport { DiscoveryService } from './services/discovery';\nimport { MarketplaceService } from './services/marketplace';\nimport { MediaService } from './services/media';\nimport { PingService } from './services/ping';\nimport { PoliciesService } from './services/policies';\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 /** Custom Blossom server base URL for blob uploads (defaults to files.elisym.network). */\n blossomUrl?: 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 blossom: BlossomService;\n readonly policies: PoliciesService;\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.blossom = new BlossomService(config.blossomUrl, (identity, file) =>\n this.media.upload(identity, file),\n );\n this.policies = new PoliciesService(this.pool);\n this.payment = config.payment ?? new SolanaPaymentStrategy();\n }\n\n close(): void {\n this.pool.close();\n }\n}\n","/**\n * Hybrid file encryption for the Blossom transport (browser-safe).\n *\n * NIP-44 is text-only and capped at ~64 KB, so it cannot encrypt a file directly. Instead this uses\n * the standard hybrid scheme: a fresh random AES-256-GCM content key encrypts the file bytes, and that\n * small key is NIP-44-wrapped to the recipient's pubkey. The recipient unwraps the key (with their\n * secret key + the sender's pubkey) and decrypts the bytes.\n *\n * WebCrypto only (`crypto.subtle` + `crypto.getRandomValues`) - NO `node:crypto`, NO `Buffer` - so it\n * runs in the browser. The IV is non-secret and travels in the transport descriptor (`enc.iv`).\n */\nimport { nip44Decrypt, nip44Encrypt } from './crypto';\n\nconst KEY_BYTES = 32; // AES-256\nconst IV_BYTES = 12; // GCM standard nonce length\n\n// base64 helpers (browser-safe via btoa/atob). Only ever applied to the tiny content key (32 B) and\n// IV (12 B) - never to the file bytes, which are uploaded raw - so the per-char loop cost is trivial.\nfunction bytesToBase64(bytes: Uint8Array): string {\n let bin = '';\n for (const b of bytes) {\n bin += String.fromCharCode(b);\n }\n return btoa(bin);\n}\n\nfunction base64ToBytes(b64: string): Uint8Array {\n const bin = atob(b64);\n const out = new Uint8Array(bin.length);\n for (let i = 0; i < bin.length; i += 1) {\n out[i] = bin.charCodeAt(i);\n }\n return out;\n}\n\nexport interface EncryptedBytes {\n /** AES-256-GCM ciphertext with the 16-byte auth tag appended (WebCrypto layout). */\n ciphertext: Uint8Array;\n /** NIP-44-wrapped content key (sender secret key -> recipient pubkey). */\n wrappedKey: string;\n /** base64 GCM IV (non-secret). */\n iv: string;\n}\n\n/** Encrypt `bytes` so that only `recipientPubkey` (with the sender's pubkey) can decrypt. */\nexport async function encryptBytesForRecipient(\n bytes: Uint8Array,\n senderSk: Uint8Array,\n recipientPubkey: string,\n): Promise<EncryptedBytes> {\n const rawKey = crypto.getRandomValues(new Uint8Array(KEY_BYTES));\n const iv = crypto.getRandomValues(new Uint8Array(IV_BYTES));\n const key = await crypto.subtle.importKey('raw', rawKey, 'AES-GCM', false, ['encrypt']);\n const ct = await crypto.subtle.encrypt({ name: 'AES-GCM', iv, tagLength: 128 }, key, bytes);\n const wrappedKey = nip44Encrypt(bytesToBase64(rawKey), senderSk, recipientPubkey);\n return { ciphertext: new Uint8Array(ct), wrappedKey, iv: bytesToBase64(iv) };\n}\n\n/**\n * Decrypt bytes produced by `encryptBytesForRecipient`. Throws on any tamper (GCM auth tag), a\n * corrupted/forged wrapped key (NIP-44 MAC), or the wrong receiver/sender key pair.\n */\nexport async function decryptBytesFromSender(\n ciphertext: Uint8Array,\n wrappedKey: string,\n iv: string,\n receiverSk: Uint8Array,\n senderPubkey: string,\n): Promise<Uint8Array> {\n const rawKey = base64ToBytes(nip44Decrypt(wrappedKey, receiverSk, senderPubkey));\n const key = await crypto.subtle.importKey('raw', rawKey, 'AES-GCM', false, ['decrypt']);\n const pt = await crypto.subtle.decrypt(\n { name: 'AES-GCM', iv: base64ToBytes(iv), tagLength: 128 },\n key,\n ciphertext,\n );\n return new Uint8Array(pt);\n}\n","/**\n * Encrypted Blossom blob transport - the browser-safe peer to the (Node-only) iroh transport.\n *\n * Seeds a file by encrypting it to a recipient (hybrid AES-256-GCM + NIP-44 key-wrap) and uploading\n * the ciphertext to a Blossom relay; fetches by downloading the ciphertext (bounded + sha256-verified)\n * and decrypting it. The local party's `identity` is both the BUD-11 upload signer AND the\n * encryption sender/receiver; the counterparty pubkey is passed per call.\n */\nimport { LIMITS } from '../constants';\nimport { decryptBytesFromSender, encryptBytesForRecipient } from '../primitives/file-crypto';\nimport type { ElisymIdentity } from '../primitives/identity';\nimport type { BlossomService } from '../services/blossom';\nimport type { FileTransport } from './attachment';\n\ntype BlossomTransport = Extract<FileTransport, { kind: 'blossom' }>;\n\n// AES-256-GCM appends a 16-byte auth tag, so the uploaded ciphertext is exactly 16 bytes larger than\n// the plaintext. The size caps are expressed in PLAINTEXT bytes (the seed side gates on plaintext\n// length), so the ciphertext-download bound is widened by the tag - otherwise a file at exactly the\n// cap seeds fine but its (cap + 16) ciphertext trips the streamed-bytes guard and can't be fetched.\nconst AES_GCM_TAG_BYTES = 16;\n\nexport interface BlossomBlobTransport {\n /** Encrypt `bytes` to `recipientPubkey`, upload the ciphertext, return a `blossom` transport member. */\n seedBytes(args: { bytes: Uint8Array; recipientPubkey: string }): Promise<BlossomTransport>;\n /** Download the ciphertext (bounded + sha256-verified) and decrypt it (sent by `senderPubkey`). */\n fetchToBytes(args: {\n transport: BlossomTransport;\n senderPubkey: string;\n maxBytes?: number;\n }): Promise<Uint8Array>;\n}\n\nexport function createBlossomTransport(opts: {\n blossom: BlossomService;\n identity: ElisymIdentity;\n}): BlossomBlobTransport {\n const { blossom, identity } = opts;\n return {\n async seedBytes({ bytes, recipientPubkey }) {\n if (bytes.byteLength > LIMITS.MAX_BLOSSOM_ENCRYPTED_BYTES) {\n throw new Error(\n `File too large for encrypted Blossom: ${bytes.byteLength} bytes exceeds ${LIMITS.MAX_BLOSSOM_ENCRYPTED_BYTES}.`,\n );\n }\n const { ciphertext, wrappedKey, iv } = await encryptBytesForRecipient(\n bytes,\n identity.secretKey,\n recipientPubkey,\n );\n // Upload the ciphertext as opaque octet-stream - the plaintext mime never reaches the relay.\n const blob = new Blob([ciphertext], { type: 'application/octet-stream' });\n const descriptor = await blossom.upload(identity, blob);\n if (descriptor.provider !== 'blossom') {\n // Fell back to nostr.build: its URL is not content-addressed by our ciphertext sha256, so the\n // fetch-time integrity check would fail. Refuse so the caller emits an iroh-only attachment.\n throw new Error('Blossom upload fell back to a non-content-addressed provider.');\n }\n return {\n kind: 'blossom',\n url: descriptor.url,\n sha256: descriptor.sha256,\n enc: { alg: 'AES-256-GCM', iv, key: wrappedKey },\n };\n },\n\n async fetchToBytes({ transport, senderPubkey, maxBytes }) {\n const plaintextCap = maxBytes ?? LIMITS.MAX_BLOSSOM_ENCRYPTED_BYTES;\n const ciphertext = await blossom.download(transport.url, {\n maxBytes: plaintextCap + AES_GCM_TAG_BYTES,\n expectedSha256: transport.sha256,\n });\n return decryptBytesFromSender(\n ciphertext,\n transport.enc.key,\n transport.enc.iv,\n identity.secretKey,\n senderPubkey,\n );\n },\n };\n}\n","/**\n * Customer-side helpers to send/receive ENCRYPTED file jobs over Blossom with no iroh/Node dependency\n * (browser-safe). These are the seams a web app calls.\n *\n * Encrypted-Blossom needs a recipient pubkey, so a file INPUT is only meaningful on a TARGETED job (a\n * chosen provider) - hence `buildEncryptedFileInput` requires `providerPubkey`. Broadcast file inputs\n * are not supported here (no recipient to encrypt to); those stay on iroh.\n */\nimport type { ElisymIdentity } from '../primitives/identity';\nimport type { BlossomService } from '../services/blossom';\nimport type { FileAttachment, FileTransport } from './attachment';\nimport { createBlossomTransport } from './blossom-transport';\n\n// Best-effort, UX-only refusal of obviously-executable inputs. NOT a security control - once the bytes\n// are ciphertext the relay cannot enforce anything; this just helps users avoid an obvious mistake.\nconst EXECUTABLE_EXTENSIONS = new Set([\n '.exe',\n '.dll',\n '.bat',\n '.cmd',\n '.com',\n '.msi',\n '.sh',\n '.app',\n '.scr',\n '.ps1',\n]);\nconst EXECUTABLE_MIMES = new Set([\n 'application/x-msdownload',\n 'application/x-msdos-program',\n 'application/x-sh',\n 'application/x-executable',\n 'application/vnd.microsoft.portable-executable',\n 'application/x-mach-binary',\n]);\n\nfunction looksExecutable(name: string, type: string): boolean {\n const dot = name.lastIndexOf('.');\n const ext = dot >= 0 ? name.slice(dot).toLowerCase() : '';\n return EXECUTABLE_EXTENSIONS.has(ext) || EXECUTABLE_MIMES.has(type);\n}\n\n/**\n * Encrypt `file` to `providerPubkey` and upload the ciphertext to Blossom, returning a `FileAttachment`\n * with a single `blossom` transport. TARGETED jobs only (a recipient pubkey is required to encrypt).\n */\nexport async function buildEncryptedFileInput(args: {\n file: Blob & { name?: string };\n providerPubkey: string;\n identity: ElisymIdentity;\n blossom: BlossomService;\n}): Promise<FileAttachment> {\n const { file, providerPubkey, identity, blossom } = args;\n const name = file.name ?? 'upload';\n if (looksExecutable(name, file.type)) {\n throw new Error('Refusing to upload an executable file.');\n }\n const transport = createBlossomTransport({ blossom, identity });\n const bytes = new Uint8Array(await file.arrayBuffer());\n const member = await transport.seedBytes({ bytes, recipientPubkey: providerPubkey });\n return {\n name,\n size: bytes.byteLength,\n mime: file.type || 'application/octet-stream',\n transports: [member],\n };\n}\n\n/**\n * Download + decrypt a `blossom` file output from an attachment (sent by `providerPubkey`). Returns the\n * plaintext bytes plus the envelope-carried name/mime. Throws if there is no blossom transport.\n */\nexport async function fetchEncryptedFileOutput(args: {\n attachment: FileAttachment;\n providerPubkey: string;\n identity: ElisymIdentity;\n blossom: BlossomService;\n maxBytes?: number;\n}): Promise<{ bytes: Uint8Array; name: string; mime: string }> {\n const { attachment, providerPubkey, identity, blossom, maxBytes } = args;\n const member = attachment.transports.find(\n (t): t is Extract<FileTransport, { kind: 'blossom' }> => t.kind === 'blossom',\n );\n if (member === undefined) {\n throw new Error('Attachment has no blossom transport.');\n }\n const transport = createBlossomTransport({ blossom, identity });\n const bytes = await transport.fetchToBytes({\n transport: member,\n senderPubkey: providerPubkey,\n maxBytes,\n });\n return { bytes, name: attachment.name, mime: attachment.mime };\n}\n","/**\n * Customer-facing error feedback that arrives via `subscribeToJobUpdates`'s\n * `onError` callback can come from many places:\n *\n * - The runtime's stable `Agent temporarily unavailable` string when the\n * LLM health gate refuses a job (preflight) or an in-flight skill\n * surfaced a billing/invalid signal.\n * - The runtime's `Internal processing error` sanitization mask for any\n * \"<Provider> API error: ...\" string that leaks out of an LLM call.\n * - Raw script-skill failures the runtime forwards as-is when the\n * message does not contain \"API\" - e.g. shell scripts that reach\n * Anthropic's `count_tokens` endpoint and exit 1 with the body in\n * stderr instead of using the canonical exit-42 contract.\n * - Generic transport errors (timeouts, \"Provider returned an error\",\n * rate-limit refusals, payment errors).\n *\n * Customers don't care which path produced the error - they care whether\n * the agent is down (try later, payment recoverable) or something else\n * went wrong (their input, their wallet, etc). This classifier collapses\n * the first three categories into a single `agent-unavailable` kind so\n * the UI can render one stable message regardless of how the underlying\n * provider chose to surface the failure.\n *\n * Markers are kept as a permissive superset of every billing/auth phrase\n * the CLI and skill scripts are known to emit. Adding a new marker is\n * always safe; removing one risks classifying a real outage as `unknown`.\n */\n\nconst AGENT_UNAVAILABLE_MARKERS = [\n 'agent temporarily unavailable',\n 'internal processing error',\n 'invalid x-api-key',\n 'invalid api key',\n 'invalid_api_key',\n 'x-api-key',\n 'credit balance',\n 'billing',\n 'insufficient',\n 'insufficient_quota',\n 'authentication_error',\n 'unauthorized',\n 'unauthenticated',\n];\n\nexport type JobErrorKind = 'agent-unavailable' | 'unknown';\n\n/**\n * Classify a customer-facing error string surfaced via\n * `JobUpdateCallbacks.onError` into a stable kind the UI can branch on.\n *\n * Match is case-insensitive against the message text. Returns\n * `agent-unavailable` for any known billing/auth/invalid-key signal;\n * `unknown` for everything else (timeouts, validation errors, transport).\n */\nexport function classifyJobError(message: string): JobErrorKind {\n const lower = message.toLowerCase();\n for (const marker of AGENT_UNAVAILABLE_MARKERS) {\n if (lower.includes(marker)) {\n return 'agent-unavailable';\n }\n }\n return 'unknown';\n}\n\n/**\n * Signalled via `JobUpdateCallbacks.onTimeout` (and thrown by helpers that\n * await a result) when the wait window expires without a result. This is a\n * distinct, structured signal from a genuine provider/transport error, so\n * callers can branch on the type instead of substring-matching \"timed out\"\n * on a free-form error message (which masks real errors that happen to\n * mention a timeout).\n */\nexport class JobWaitTimeoutError extends Error {\n constructor(timeoutMs?: number) {\n super(\n timeoutMs === undefined\n ? 'Timed out waiting for job result'\n : `Timed out waiting for job result (${Math.round(timeoutMs / 1000)}s)`,\n );\n this.name = 'JobWaitTimeoutError';\n }\n}\n","/**\n * SOL-denominated fee estimator for payment requests.\n *\n * For a USDC payment the user still spends SOL to cover the base signature fee,\n * the priority fee, and (for first-time recipients) the ATA rent-exemption\n * deposit. Before calling `send_payment` the customer wants to know whether\n * their SOL balance is sufficient - that's what this helper answers.\n *\n * Browser-safe: no Node-specific imports. The web dashboard will use the same\n * function.\n */\n\nimport { TOKEN_PROGRAM_ADDRESS, findAssociatedTokenPda } from '@solana-program/token';\nimport { type Address, type Rpc, type SolanaRpcApi, address } from '@solana/kit';\nimport type { PaymentRequestData } from '../types';\nimport { resolveAssetFromPaymentRequest } from './assets';\nimport { estimatePriorityFeeMicroLamports } from './priorityFee';\n\n/**\n * Default compute-unit limit attached to payment transactions.\n *\n * Kept in sync with `DEFAULT_COMPUTE_UNIT_LIMIT` in solana.ts. Duplicating the\n * constant keeps the estimator browser-safe without pulling the build path.\n */\nconst DEFAULT_COMPUTE_UNIT_LIMIT = 200_000;\nconst DEFAULT_PRIORITY_FEE_PERCENTILE = 75;\n\n/** Base fee per signature (lamports). See `SystemProgram::get_fee_payer`. */\nconst BASE_FEE_LAMPORTS_PER_SIGNATURE = 5_000n;\n\n/**\n * Rent-exemption minimum for a 165-byte SPL Token account, as of Solana 1.18+.\n *\n * Used as a fallback when `getMinimumBalanceForRentExemption` is unavailable.\n * The real on-chain value is ~2039280 lamports (= 0.00203928 SOL).\n */\nconst FALLBACK_ATA_RENT_LAMPORTS = 2_039_280n;\n\n/** SPL Token account size in bytes. */\nconst SPL_TOKEN_ACCOUNT_SIZE = 165;\n\nexport interface SolFeeEstimate {\n /** Base per-signature fee. Currently 5000 lamports * 1 signature. */\n baseFeeLamports: bigint;\n /**\n * Priority fee in lamports: `ceil(priorityFeeMicroLamports * computeUnitLimit\n * / 1_000_000)`. Rounded up so we don't underestimate.\n */\n priorityFeeLamports: bigint;\n /**\n * Rent-exemption deposit for ATAs that the tx creates.\n *\n * 0 for native SOL. For SPL, `rentPerAta * (# of missing ATAs)`: recipient\n * ATA is missing iff the recipient has never received this token; treasury\n * ATA is missing only on the first-ever protocol fee into this mint.\n */\n rentLamports: bigint;\n /** `baseFeeLamports + priorityFeeLamports + rentLamports`. */\n totalLamports: bigint;\n breakdown: {\n numSignatures: number;\n priorityFeeMicroLamports: bigint;\n computeUnitLimit: number;\n rentPerAtaLamports: bigint;\n missingAtaCount: number;\n };\n}\n\nexport interface EstimateSolFeeOptions {\n /** Override the compute-unit limit used by `buildTransaction`. */\n computeUnitLimit?: number;\n /** Override the priority fee directly (skips RPC). */\n priorityFeeMicroLamports?: bigint;\n /**\n * Percentile of the recent priority-fee distribution to charge when\n * `priorityFeeMicroLamports` is not supplied. Defaults to 75.\n */\n priorityFeePercentile?: number;\n /** Override the number of signatures. Defaults to 1. */\n numSignatures?: number;\n}\n\n/**\n * Estimate the SOL cost (in lamports) to submit the transaction that would pay\n * this payment request from `payerAddress`.\n *\n * Returns a breakdown and a total. Does not submit anything on-chain.\n */\nexport async function estimateSolFeeLamports(\n rpc: Rpc<SolanaRpcApi>,\n paymentRequest: PaymentRequestData,\n _payerAddress: string,\n options?: EstimateSolFeeOptions,\n): Promise<SolFeeEstimate> {\n const numSignatures = options?.numSignatures ?? 1;\n const computeUnitLimit = options?.computeUnitLimit ?? DEFAULT_COMPUTE_UNIT_LIMIT;\n const priorityFeeMicroLamports =\n options?.priorityFeeMicroLamports ??\n (await estimatePriorityFeeMicroLamports(rpc, {\n percentile: options?.priorityFeePercentile ?? DEFAULT_PRIORITY_FEE_PERCENTILE,\n }));\n\n const baseFeeLamports = BASE_FEE_LAMPORTS_PER_SIGNATURE * BigInt(numSignatures);\n const priorityFeeLamports = ceilDiv(\n priorityFeeMicroLamports * BigInt(computeUnitLimit),\n 1_000_000n,\n );\n\n const asset = resolveAssetFromPaymentRequest(paymentRequest);\n let rentLamports = 0n;\n let rentPerAtaLamports = 0n;\n let missingAtaCount = 0;\n\n if (asset.mint) {\n rentPerAtaLamports = await fetchAtaRent(rpc);\n const mint = address(asset.mint);\n\n const ataAccountsToCheck: Address[] = [];\n const [recipientAta] = await findAssociatedTokenPda({\n owner: address(paymentRequest.recipient),\n tokenProgram: TOKEN_PROGRAM_ADDRESS,\n mint,\n });\n ataAccountsToCheck.push(recipientAta);\n\n const feeAmount = paymentRequest.fee_amount ?? 0;\n if (paymentRequest.fee_address && feeAmount > 0) {\n const [treasuryAta] = await findAssociatedTokenPda({\n owner: address(paymentRequest.fee_address),\n tokenProgram: TOKEN_PROGRAM_ADDRESS,\n mint,\n });\n ataAccountsToCheck.push(treasuryAta);\n }\n\n missingAtaCount = await countMissingAccounts(rpc, ataAccountsToCheck);\n rentLamports = rentPerAtaLamports * BigInt(missingAtaCount);\n }\n\n const totalLamports = baseFeeLamports + priorityFeeLamports + rentLamports;\n return {\n baseFeeLamports,\n priorityFeeLamports,\n rentLamports,\n totalLamports,\n breakdown: {\n numSignatures,\n priorityFeeMicroLamports,\n computeUnitLimit,\n rentPerAtaLamports,\n missingAtaCount,\n },\n };\n}\n\nasync function fetchAtaRent(rpc: Rpc<SolanaRpcApi>): Promise<bigint> {\n try {\n const lamports = await rpc\n .getMinimumBalanceForRentExemption(BigInt(SPL_TOKEN_ACCOUNT_SIZE))\n .send();\n if (typeof lamports === 'bigint') {\n return lamports;\n }\n if (typeof lamports === 'number' && Number.isFinite(lamports) && lamports > 0) {\n return BigInt(lamports);\n }\n return FALLBACK_ATA_RENT_LAMPORTS;\n } catch {\n return FALLBACK_ATA_RENT_LAMPORTS;\n }\n}\n\nasync function countMissingAccounts(rpc: Rpc<SolanaRpcApi>, accounts: Address[]): Promise<number> {\n if (accounts.length === 0) {\n return 0;\n }\n let missing = 0;\n for (const acct of accounts) {\n try {\n const res = await rpc.getAccountInfo(acct, { encoding: 'base64' }).send();\n if (!res || !res.value) {\n missing++;\n }\n } catch {\n // If we can't tell, assume the ATA must be created - safer to\n // overestimate the cost than to surprise the payer.\n missing++;\n }\n }\n return missing;\n}\n\nfunction ceilDiv(num: bigint, denom: bigint): bigint {\n if (denom === 0n) {\n throw new Error('division by zero in ceilDiv');\n }\n const q = num / denom;\n const r = num % denom;\n return r === 0n ? q : q + 1n;\n}\n\n/**\n * Multi-line human-readable breakdown. Used by the MCP `estimate_payment_cost`\n * tool and (in a future PR) by the web dashboard's pre-payment panel.\n *\n * We render lamports as raw integers and also show a SOL decimal with 9 places.\n * The `@elisym/sdk` `formatAssetAmount` helper lives in assets.ts, but the\n * formatter does not need to be identical; this stays dependency-free.\n */\nexport function formatFeeBreakdown(estimate: SolFeeEstimate): string {\n const line = (label: string, lamports: bigint): string => {\n const label16 = label.padEnd(14);\n return ` ${label16}${lamports.toString()} lamports (${lamportsToSol(lamports)} SOL)`;\n };\n const lines = [\n 'Estimated SOL cost for this transaction:',\n line('Base fee:', estimate.baseFeeLamports),\n line('Priority fee:', estimate.priorityFeeLamports),\n ];\n if (estimate.rentLamports > 0n) {\n lines.push(line('ATA rent:', estimate.rentLamports));\n }\n lines.push(line('Total:', estimate.totalLamports));\n return lines.join('\\n');\n}\n\nfunction lamportsToSol(lamports: bigint): string {\n const LAMPORTS_PER_SOL = 1_000_000_000n;\n const whole = lamports / LAMPORTS_PER_SOL;\n const frac = lamports % LAMPORTS_PER_SOL;\n return `${whole}.${frac.toString().padStart(9, '0')}`;\n}\n\nexport interface NetworkBaselineEstimate {\n baseFeeLamports: bigint;\n priorityFeeMicroLamports: bigint;\n computeUnitLimit: number;\n priorityFeeLamports: bigint;\n /** Present only when `includeAtaRent: true`. */\n ataRentLamports?: bigint;\n /** baseFeeLamports + priorityFeeLamports + (ataRentLamports ?? 0n). */\n totalLamports: bigint;\n}\n\nexport interface NetworkBaselineOptions {\n /** Add one ATA rent-exemption deposit to the total (USDC first-time payer). */\n includeAtaRent?: boolean;\n /** Override the priority-fee percentile (default 75). */\n priorityFeePercentile?: number;\n /** Override the compute-unit limit (default 200_000). */\n computeUnitLimit?: number;\n /** Override priority fee directly, skipping the RPC call. */\n priorityFeeMicroLamports?: bigint;\n}\n\n/**\n * Estimate the SOL cost of a typical payment transaction on the current\n * cluster, without needing a concrete `payment_request`. Used by MCP\n * confirmation messages (e.g. `buy_capability` price gate) to surface\n * gas before the provider has issued a payment-required feedback.\n *\n * Reuses the priority-fee cache in `estimatePriorityFeeMicroLamports`\n * (TTL 10s) so consecutive confirmations don't double-hit the RPC.\n */\nexport async function estimateNetworkBaseline(\n rpc: Rpc<SolanaRpcApi>,\n options?: NetworkBaselineOptions,\n): Promise<NetworkBaselineEstimate> {\n const computeUnitLimit = options?.computeUnitLimit ?? DEFAULT_COMPUTE_UNIT_LIMIT;\n const priorityFeeMicroLamports =\n options?.priorityFeeMicroLamports ??\n (await estimatePriorityFeeMicroLamports(rpc, {\n percentile: options?.priorityFeePercentile ?? DEFAULT_PRIORITY_FEE_PERCENTILE,\n }));\n const baseFeeLamports = BASE_FEE_LAMPORTS_PER_SIGNATURE;\n const priorityFeeLamports = ceilDiv(\n priorityFeeMicroLamports * BigInt(computeUnitLimit),\n 1_000_000n,\n );\n const ataRentLamports = options?.includeAtaRent ? await fetchAtaRent(rpc) : undefined;\n const totalLamports = baseFeeLamports + priorityFeeLamports + (ataRentLamports ?? 0n);\n return {\n baseFeeLamports,\n priorityFeeMicroLamports,\n computeUnitLimit,\n priorityFeeLamports,\n ataRentLamports,\n totalLamports,\n };\n}\n\n/**\n * Single-line summary of a network baseline estimate, suitable for embedding\n * inside MCP confirmation strings.\n */\nexport function formatNetworkBaseline(estimate: NetworkBaselineEstimate): string {\n const total = lamportsToSol(estimate.totalLamports);\n const base = lamportsToSol(estimate.baseFeeLamports);\n const priority = lamportsToSol(estimate.priorityFeeLamports);\n const parts = [`base ${base}`, `priority ${priority}`];\n if (estimate.ataRentLamports !== undefined) {\n parts.push(`ATA rent ${lamportsToSol(estimate.ataRentLamports)}`);\n }\n return `Estimated network gas: ${total} SOL (${parts.join(' + ')}).`;\n}\n","import { type Address, type Rpc, type Signature, type SolanaRpcApi, isAddress } from '@solana/kit';\n\n/**\n * Lightweight payment verifier used by discovery ranking.\n *\n * Unlike `SolanaPaymentStrategy.verifyPayment`, this is a single-shot check\n * with no retries: discovery cannot afford the 30-second confirmation budget\n * the customer-side verifier uses. If the RPC has not seen the transaction\n * yet, we treat the agent as \"no verified paid job\" rather than blocking.\n *\n * Positive results are cached forever (Solana txs are immutable once\n * confirmed). Negative results expire after `NEGATIVE_CACHE_TTL_MS` so a\n * just-confirmed tx will be picked up on the next discovery refresh.\n */\n\nexport type QuickVerifyReason =\n | 'not_found'\n | 'tx_failed'\n | 'recipient_mismatch'\n | 'rpc_error'\n | 'invalid_input';\n\nexport interface QuickVerifyResult {\n /**\n * True when the recipient address received funds in this transaction.\n *\n * NOTE: this is NOT proof of a valid elisym job payment. It does not check\n * the payment `reference` key or that the amount matches the job price - it\n * is a best-effort signal for the fast discovery-ranking path, where the\n * original payment request is unavailable. For an authoritative check\n * (amount + reference) use `SolanaPaymentStrategy.verifyPayment`.\n */\n receivedFunds: boolean;\n txSignature: string;\n reason?: QuickVerifyReason;\n}\n\ninterface VerifyCacheEntry {\n result: QuickVerifyResult;\n cachedAt: number;\n}\n\nconst NEGATIVE_CACHE_TTL_MS = 60_000;\n// Cap so a long-running process cannot grow the cache without bound (#44).\nconst MAX_CACHE_ENTRIES = 5_000;\n\nconst verifyCache = new Map<string, VerifyCacheEntry>();\n\nexport function clearQuickVerifyCache(): void {\n verifyCache.clear();\n}\n\nexport async function verifyJobPaymentQuick(\n rpc: Rpc<SolanaRpcApi>,\n txSignature: string,\n expectedRecipient: Address,\n): Promise<QuickVerifyResult> {\n if (!txSignature) {\n return { receivedFunds: false, txSignature: '', reason: 'invalid_input' };\n }\n if (!expectedRecipient || !isAddress(expectedRecipient as string)) {\n return { receivedFunds: false, txSignature, reason: 'invalid_input' };\n }\n\n const cacheKey = `${txSignature}:${expectedRecipient}`;\n const cached = verifyCache.get(cacheKey);\n if (cached) {\n if (cached.result.receivedFunds) {\n return cached.result;\n }\n if (Date.now() - cached.cachedAt < NEGATIVE_CACHE_TTL_MS) {\n return cached.result;\n }\n // Expired negative result - drop it so re-verification can refresh.\n verifyCache.delete(cacheKey);\n }\n\n const result = await doVerifyOnce(rpc, txSignature as Signature, expectedRecipient);\n // Map preserves insertion order, so evicting the first key is LRU-ish.\n if (verifyCache.size >= MAX_CACHE_ENTRIES) {\n const oldest = verifyCache.keys().next().value;\n if (oldest !== undefined) {\n verifyCache.delete(oldest);\n }\n }\n verifyCache.set(cacheKey, { result, cachedAt: Date.now() });\n return result;\n}\n\ninterface TokenBalanceEntry {\n accountIndex: number;\n mint: string;\n owner?: string;\n uiTokenAmount: { amount: string };\n}\n\nasync function doVerifyOnce(\n rpc: Rpc<SolanaRpcApi>,\n txSignature: Signature,\n expectedRecipient: Address,\n): Promise<QuickVerifyResult> {\n const sigStr = txSignature as string;\n\n if (!rpc || typeof (rpc as { getTransaction?: unknown }).getTransaction !== 'function') {\n return { receivedFunds: false, txSignature: sigStr, reason: 'rpc_error' };\n }\n\n let tx: Awaited<ReturnType<ReturnType<Rpc<SolanaRpcApi>['getTransaction']>['send']>>;\n try {\n tx = await rpc\n .getTransaction(txSignature, {\n commitment: 'confirmed',\n encoding: 'json',\n maxSupportedTransactionVersion: 0,\n })\n .send();\n } catch {\n return { receivedFunds: false, txSignature: sigStr, reason: 'rpc_error' };\n }\n\n if (!tx) {\n return { receivedFunds: false, txSignature: sigStr, reason: 'not_found' };\n }\n if (!tx.meta || tx.meta.err) {\n return { receivedFunds: false, txSignature: sigStr, reason: 'tx_failed' };\n }\n\n const accountKeys = tx.transaction.message.accountKeys as readonly string[];\n const recipientStr = expectedRecipient as string;\n\n const recipientIdx = accountKeys.indexOf(recipientStr);\n if (recipientIdx !== -1) {\n const preBalances = tx.meta.preBalances as readonly bigint[] | undefined;\n const postBalances = tx.meta.postBalances as readonly bigint[] | undefined;\n if (preBalances && postBalances) {\n const pre = preBalances[recipientIdx];\n const post = postBalances[recipientIdx];\n if (pre !== undefined && post !== undefined) {\n const delta = BigInt(post) - BigInt(pre);\n if (delta > 0n) {\n return { receivedFunds: true, txSignature: sigStr };\n }\n }\n }\n }\n\n const postTokenBalances = tx.meta.postTokenBalances as readonly TokenBalanceEntry[] | undefined;\n const preTokenBalances = tx.meta.preTokenBalances as readonly TokenBalanceEntry[] | undefined;\n if (postTokenBalances) {\n for (const post of postTokenBalances) {\n if (post.owner !== recipientStr) {\n continue;\n }\n const pre = preTokenBalances?.find(\n (entry) => entry.owner === recipientStr && entry.mint === post.mint,\n );\n const preAmount = pre ? BigInt(pre.uiTokenAmount.amount) : 0n;\n const postAmount = BigInt(post.uiTokenAmount.amount);\n if (postAmount > preAmount) {\n return { receivedFunds: true, txSignature: sigStr };\n }\n }\n }\n\n return { receivedFunds: false, txSignature: sigStr, reason: 'recipient_mismatch' };\n}\n","import { deriveNetworkStatsAddress, fetchMaybeNetworkStats } from '@elisym/config-client';\nimport type { Address, Rpc, Signature, SolanaRpcApi } from '@solana/kit';\nimport { address } from '@solana/kit';\nimport { DEFAULTS, ELISYM_PROTOCOL_TAG } from '../constants';\n\n/**\n * Aggregated on-chain stats across the entire elisym network. Volume is\n * keyed by `'native'` for SOL or by SPL mint address; values are subunits\n * (lamports for native, raw token units for SPL).\n */\nexport interface NetworkStatsResult {\n jobCount: number;\n volumeByAsset: Record<string, bigint>;\n /** Most-recent signature returned by the RPC (use as cursor for forward sync). */\n latestSignature?: string;\n /** Oldest signature scanned in this batch (use as `before` for next page). */\n oldestSignature?: string;\n}\n\nexport interface AggregateNetworkStatsOptions {\n /** Cap on signatures fetched in one call. Defaults to 1000 (RPC max). */\n limit?: number;\n /** Page backwards from this signature for historical scans. */\n before?: Signature;\n /** Parallel `getTransaction` calls. Defaults to `DEFAULTS.QUERY_MAX_CONCURRENCY`. */\n concurrency?: number;\n}\n\nconst DEFAULT_LIMIT = 1000;\nconst NATIVE_KEY = 'native';\n\ninterface TokenBalanceEntry {\n accountIndex: number;\n mint: string;\n owner?: string;\n uiTokenAmount: { amount: string };\n}\n\n/**\n * Enumerate every elisym payment transaction reachable from the protocol tag\n * pubkey and aggregate gross volume + count.\n *\n * Implementation detail: for SPL txs we sum positive token-balance deltas per\n * mint (ignores ATA rent that would inflate native lamport deltas in the same\n * tx). For native SOL txs we sum positive lamport deltas across all non-payer\n * accounts - elisym native txs only emit provider + optional fee transfers,\n * so this equals gross volume. The `tx_fee` paid by the fee-payer never shows\n * up as a positive delta, so it is naturally excluded.\n */\nexport async function aggregateNetworkStats(\n rpc: Rpc<SolanaRpcApi>,\n options?: AggregateNetworkStatsOptions,\n): Promise<NetworkStatsResult> {\n const limit = options?.limit ?? DEFAULT_LIMIT;\n const concurrency = options?.concurrency ?? DEFAULTS.QUERY_MAX_CONCURRENCY;\n const tag = address(ELISYM_PROTOCOL_TAG);\n\n const signatures = await rpc\n .getSignaturesForAddress(tag, { limit, before: options?.before })\n .send();\n const validSigs = signatures.filter((entry) => entry.err === null);\n\n if (validSigs.length === 0) {\n return { jobCount: 0, volumeByAsset: {} };\n }\n\n const volumeByAsset: Record<string, bigint> = {};\n let jobCount = 0;\n\n for (let start = 0; start < validSigs.length; start += concurrency) {\n const batch = validSigs.slice(start, start + concurrency);\n const txResults = await Promise.all(\n batch.map((entry) =>\n rpc\n .getTransaction(entry.signature, {\n commitment: 'confirmed',\n encoding: 'json',\n maxSupportedTransactionVersion: 0,\n })\n .send()\n .catch(() => null),\n ),\n );\n\n for (const tx of txResults) {\n if (!tx?.meta || tx.meta.err) {\n continue;\n }\n jobCount += 1;\n accumulateTransfers(tx, volumeByAsset);\n }\n }\n\n const latest = validSigs[0]?.signature;\n const oldest = validSigs.at(-1)?.signature;\n\n return {\n jobCount,\n volumeByAsset,\n latestSignature: latest as string | undefined,\n oldestSignature: oldest as string | undefined,\n };\n}\n\ninterface RawTransaction {\n meta: {\n err: unknown;\n preBalances: readonly bigint[];\n postBalances: readonly bigint[];\n preTokenBalances?: readonly TokenBalanceEntry[];\n postTokenBalances?: readonly TokenBalanceEntry[];\n } | null;\n transaction: {\n message: {\n accountKeys: readonly string[];\n };\n };\n}\n\nfunction accumulateTransfers(tx: unknown, volumeByAsset: Record<string, bigint>): void {\n const raw = tx as RawTransaction;\n const meta = raw.meta;\n if (!meta) {\n return;\n }\n\n const preTokens = meta.preTokenBalances ?? [];\n const postTokens = meta.postTokenBalances ?? [];\n const isSpl = postTokens.length > 0 || preTokens.length > 0;\n\n if (isSpl) {\n accumulateSplDeltas(preTokens, postTokens, volumeByAsset);\n return;\n }\n\n accumulateNativeDeltas(meta.preBalances, meta.postBalances, volumeByAsset);\n}\n\nfunction accumulateSplDeltas(\n pre: readonly TokenBalanceEntry[],\n post: readonly TokenBalanceEntry[],\n volumeByAsset: Record<string, bigint>,\n): void {\n for (const postEntry of post) {\n const preEntry = pre.find((entry) => entry.accountIndex === postEntry.accountIndex);\n const preAmount = preEntry ? BigInt(preEntry.uiTokenAmount.amount) : 0n;\n const postAmount = BigInt(postEntry.uiTokenAmount.amount);\n const delta = postAmount - preAmount;\n if (delta > 0n) {\n volumeByAsset[postEntry.mint] = (volumeByAsset[postEntry.mint] ?? 0n) + delta;\n }\n }\n}\n\nfunction accumulateNativeDeltas(\n pre: readonly bigint[],\n post: readonly bigint[],\n volumeByAsset: Record<string, bigint>,\n): void {\n // accountKeys[0] is the fee payer; its negative delta covers gross + tx_fee.\n // Skip it and sum positive deltas of every other account - equals gross.\n for (let i = 1; i < post.length; i++) {\n const preValue = pre[i] ?? 0n;\n const postValue = post[i] ?? 0n;\n const delta = BigInt(postValue) - BigInt(preValue);\n if (delta > 0n) {\n volumeByAsset[NATIVE_KEY] = (volumeByAsset[NATIVE_KEY] ?? 0n) + delta;\n }\n }\n}\n\n/**\n * Best-effort network stats read from the on-chain `NetworkStats` PDA\n * maintained by the elisym-config program. One `getAccountInfo` call - no\n * signature scans, no per-tx aggregation.\n *\n * The PDA is incremented by the client SDK alongside each payment and is not\n * yet bound to a verified transfer, so totals can be inflated cheaply by a\n * malicious caller. Authoritative tracking will land with the escrow rewrite.\n *\n * Returns `null` when the PDA has not been initialized yet (admin must call\n * `initialize_stats` once after program upgrade).\n */\n/**\n * Best-effort network counters read from the on-chain PDA. These are NOT bound\n * to verified transfers and can be inflated by a malicious caller, so present\n * them as approximate/unverified, never as authoritative proof of activity. For\n * a transfer-derived figure use `aggregateNetworkStats`.\n */\nexport interface OnchainNetworkStats {\n jobCount: number;\n volumeNative: bigint;\n volumeUsdc: bigint;\n}\n\nexport async function getNetworkStats(\n rpc: Rpc<SolanaRpcApi>,\n programId: Address,\n): Promise<OnchainNetworkStats | null> {\n const statsPda = await deriveNetworkStatsAddress(programId);\n const account = await fetchMaybeNetworkStats(rpc, statsPda);\n if (!account.exists) {\n return null;\n }\n return {\n jobCount: Number(account.data.jobCount),\n volumeNative: account.data.volumeNative,\n volumeUsdc: account.data.volumeUsdc,\n };\n}\n","/**\n * Zod schemas and types for `~/.elisym/config.yaml`.\n *\n * Split from `./global` so the schemas can be re-exported from the\n * browser-safe `@elisym/sdk` entry point without dragging in `node:fs/promises`\n * (which the loader/writer in `./global` needs).\n */\n\nimport { z } from 'zod';\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 // Stored as a string to preserve the operator's exact decimal text (avoids\n // Number round-tripping to scientific notation). Legacy configs persisted a\n // number; accept both and normalize to a positive-decimal string.\n amount: z\n .union([z.string(), z.number()])\n .transform((value) => (typeof value === 'number' ? String(value) : value.trim()))\n .refine((value) => /^\\d+(?:\\.\\d+)?$/.test(value) && /[1-9]/.test(value), {\n message: 'amount must be a positive decimal (e.g. \"0.5\", \"1\")',\n }),\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","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_keys` is a Record<provider-id, key> after the registry\n // refactor; the wildcard variants cover any nested provider id.\n 'nostr_secret_key',\n 'solana_secret_key',\n 'llm_api_keys',\n '*.nostr_secret_key',\n '*.solana_secret_key',\n '*.llm_api_keys',\n 'llm_api_keys.*',\n '*.llm_api_keys.*',\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/accounts/networkStats.ts","../../config-client/src/generated/programs/elisymConfig.ts","../../config-client/src/generated/errors/elisymConfig.ts","../../config-client/src/generated/shared/index.ts","../../config-client/src/generated/instructions/incrementStats.ts","../../config-client/src/helpers.ts","../src/config/onchain.ts","../src/payment/assets.ts","../src/payment/fee.ts","../src/payment/priorityFee.ts","../src/payment/schema.ts","../src/payment/solana.ts","../src/services/blossom.ts","../src/services/discovery.ts","../src/primitives/crypto.ts","../src/transport/attachment.ts","../src/services/marketplace.ts","../src/services/media.ts","../src/primitives/identity.ts","../src/services/ping.ts","../src/services/policies.ts","../src/primitives/bounded-set.ts","../src/transport/pool.ts","../src/client.ts","../src/primitives/file-crypto.ts","../src/transport/blossom-transport.ts","../src/transport/file-jobs.ts","../src/services/jobErrors.ts","../src/payment/feeEstimate.ts","../src/payment/quick-verify.ts","../src/payment/analytics.ts","../src/config/global-schema.ts","../src/primitives/format.ts","../src/primitives/config.ts","../src/primitives/rateLimiter.ts","../src/primitives/logRedact.ts"],"names":["getStructDecoder","fixDecoderSize","getBytesDecoder","getU8Decoder","getAddressDecoder","getOptionDecoder","getU16Decoder","getBooleanDecoder","getI64Decoder","decodeAccount","address","assertAccountExists","fetchEncodedAccount","getU64Decoder","getU128Decoder","AccountRole","upgradeRoleToSigner","kitIsTransactionSigner","transformEncoder","getStructEncoder","fixEncoderSize","getBytesEncoder","getU64Encoder","getBooleanEncoder","getProgramDerivedAddress","Decimal","cache","z","isAddress","pipe","createTransactionMessage","setTransactionMessageFeePayerSigner","setTransactionMessageLifetimeUsingBlockhash","setTransactionMessageComputeUnitLimit","setTransactionMessageComputeUnitPrice","appendTransactionMessageInstructions","signTransactionMessageWithSigners","getAddMemoInstruction","providerTransferIx","getTransferSolInstruction","providerTransferIxWithMarkers","instructions","findAssociatedTokenPda","TOKEN_PROGRAM_ADDRESS","getCreateAssociatedTokenIdempotentInstruction","ASSOCIATED_TOKEN_PROGRAM_ADDRESS","getTransferCheckedInstruction","finalizeEvent","verifyEvent","nip19","nip44","getPublicKey","generateSecretKey","SimplePool","DEFAULT_COMPUTE_UNIT_LIMIT","DEFAULT_PRIORITY_FEE_PERCENTILE","LAMPORTS_PER_SOL","cacheKey"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { Address } from '@solana/kit';\n\nexport const RELAYS = [\n 'wss://relay.damus.io',\n 'wss://nos.lol',\n 'wss://relay.nostr.band',\n 'wss://relay.primal.net',\n 'wss://relay.snort.social',\n];\n\nexport const KIND_APP_HANDLER = 31990;\nexport const KIND_LONG_FORM_ARTICLE = 30023;\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/** Discovery tag attached to elisym agent policy events (kind 30023). */\nexport const POLICY_T_TAG = 'elisym-policy';\n/** d-tag prefix for policy events: full d-tag = `<prefix><type>` (e.g. `elisym-policy-tos`). */\nexport const POLICY_D_TAG_PREFIX = 'elisym-policy-';\n/** Validation regex for policy `type` slug. Lowercase ASCII + hyphen, 1-32 chars, no leading/trailing hyphen. */\nexport const POLICY_TYPE_REGEX = /^[a-z0-9](?:[a-z0-9-]{0,30}[a-z0-9])?$/;\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 * 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\n/**\n * Read-only marker pubkey attached as a non-signer account to every elisym\n * payment transaction. Lets indexers enumerate every elisym tx network-wide\n * via a single `getSignaturesForAddress(ELISYM_PROTOCOL_TAG)` call,\n * independent of fee size or recipient.\n *\n * The account does not need to exist on-chain; including its pubkey as an\n * extra read-only account in the provider transfer instruction is enough for\n * Solana's tx-by-account index to pick it up. The corresponding secret key\n * was generated and discarded - the tag never signs and never holds funds.\n */\nexport const ELISYM_PROTOCOL_TAG = 'ELiZksgwDt41LaeuPDLkUfWgFXhGgVayTMP7L5nTSEL8' 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: 3_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 // Default ceiling for a single iroh file transfer (seed/fetch). A tunable\n // default, not a protocol constant - the transfer is resumable and its own\n // budget, decoupled from the result-wait window.\n IROH_FETCH_TIMEOUT_MS: 300_000,\n // Ceiling for a single iroh SEED (addFromPath/addBytes/share). Seeding is local\n // (hash + store-copy + ticket mint), so this is a generous backstop: it bounds\n // the JS await so a wedged native call surfaces as a thrown error (and triggers a\n // node reset) instead of an indefinite hang that stalls file delivery.\n IROH_SEED_TIMEOUT_MS: 120_000,\n // Ceiling for a single Blossom blob upload (PUT /upload). Large blobs (up to\n // LIMITS.MAX_FILE_SIZE) need far more than the 30s used for small media images.\n BLOSSOM_UPLOAD_TIMEOUT_MS: 300_000,\n // Ceiling for a single encrypted Blossom blob download (GET). Same budget as upload.\n BLOSSOM_FETCH_TIMEOUT_MS: 300_000,\n} as const;\n\n/** Protocol limits for input validation. */\nexport const LIMITS = {\n MAX_INPUT_LENGTH: 100_000,\n // NIP-44 v2 hard cap on encrypted plaintext: the pad() length prefix is a u16,\n // so the plaintext can be at most 65_535 BYTES (not chars). Encrypting anything\n // larger throws `invalid plaintext size` inside nip44Encrypt. This is the binding\n // limit for TARGETED (encrypted) jobs - lower than every relay's NIP-11 cap.\n NIP44_MAX_PLAINTEXT_BYTES: 65_535,\n // Spill threshold for encrypted content: above this many UTF-8 bytes, callers\n // route the text through iroh out-of-band instead of inlining it. A non-spilled\n // job is encrypted RAW (no envelope - see marketplace.submitJobRequest), so a\n // 60_000-byte input is a 60_000-byte plaintext; the ~5.5KB gap under the hard cap\n // is plain slack, and NIP44_MAX_PLAINTEXT_BYTES is the SDK backstop.\n MAX_ENCRYPTED_INLINE_BYTES: 60_000,\n // Ceiling above which a text/* attachment is NOT materialized back into a string\n // (re-inlined into SkillInput.data) - the consumer gets a filePath / explicit\n // fetch instead. Also bounds the in-memory git-diff buffer (memory-DoS guard).\n MAX_REINLINE_TEXT_BYTES: 4_194_304, // 4 MiB\n // Hard safety cap on a single file transferred via iroh, enforced on the\n // actual streamed bytes (never the sender-declared `size`). A tunable default;\n // providers may lower it per deployment.\n MAX_FILE_SIZE: 1_073_741_824, // 1 GiB\n // Cap for the ENCRYPTED Blossom path (web/SDK). The encrypt-then-upload flow is\n // whole-buffer in WebCrypto + BlossomService (~3x file-size peak RAM), so this is\n // deliberately far below MAX_FILE_SIZE to stay safe in a browser tab; larger files\n // use iroh. The relay enforces a ~128 MiB server-side backstop.\n MAX_BLOSSOM_ENCRYPTED_BYTES: 104_857_600, // 100 MiB\n\n MAX_TIMEOUT_SECS: 600,\n // Upper bound for execution budgets (`max_execution_secs` / `execution_timeout_secs`).\n // Distinct from MAX_TIMEOUT_SECS (the result-wait cap): execution budgets may be\n // hours, so this exists only to keep `secs * 1000` within Node's setTimeout limit\n // (2_147_483_647 ms) - a larger value overflows and fires the timer immediately.\n MAX_EXECUTION_SECS: 2_147_483,\n MAX_CAPABILITIES: 20,\n MAX_DESCRIPTION_LENGTH: 500,\n MAX_AGENT_NAME_LENGTH: 64,\n MAX_CAPABILITY_LENGTH: 64,\n MAX_POLICY_CONTENT_LENGTH: 50_000,\n MAX_POLICIES_PER_AGENT: 12,\n MAX_POLICY_TYPE_LENGTH: 32,\n MAX_POLICY_TITLE_LENGTH: 120,\n MAX_POLICY_SUMMARY_LENGTH: 280,\n MAX_POLICY_VERSION_LENGTH: 32,\n} as const;\n\nconst UTF8_ENCODER = new TextEncoder();\n\n/**\n * UTF-8 byte length of a string. All size guards on encrypted content measure\n * BYTES, not `String.length` (UTF-16 code units): NIP-44's plaintext cap is a\n * byte cap, so a multibyte string under the char cap can still exceed it.\n */\nexport function utf8ByteLength(value: string): number {\n return UTF8_ENCODER.encode(value).length;\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 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 assertAccountExists,\n assertAccountsExist,\n combineCodec,\n decodeAccount,\n fetchEncodedAccount,\n fetchEncodedAccounts,\n fixDecoderSize,\n fixEncoderSize,\n getBytesDecoder,\n getBytesEncoder,\n getI64Decoder,\n getI64Encoder,\n getStructDecoder,\n getStructEncoder,\n getU128Decoder,\n getU128Encoder,\n getU64Decoder,\n getU64Encoder,\n getU8Decoder,\n getU8Encoder,\n transformEncoder,\n type Account,\n type Address,\n type EncodedAccount,\n type FetchAccountConfig,\n type FetchAccountsConfig,\n type FixedSizeCodec,\n type FixedSizeDecoder,\n type FixedSizeEncoder,\n type MaybeAccount,\n type MaybeEncodedAccount,\n type ReadonlyUint8Array,\n} from '@solana/kit';\n\nexport const NETWORK_STATS_DISCRIMINATOR = new Uint8Array([\n 171, 11, 222, 71, 255, 220, 21, 3,\n]);\n\nexport function getNetworkStatsDiscriminatorBytes() {\n return fixEncoderSize(getBytesEncoder(), 8).encode(\n NETWORK_STATS_DISCRIMINATOR\n );\n}\n\nexport type NetworkStats = {\n discriminator: ReadonlyUint8Array;\n version: number;\n bump: number;\n jobCount: bigint;\n volumeNative: bigint;\n volumeUsdc: bigint;\n lastUpdated: bigint;\n reserved: ReadonlyUint8Array;\n};\n\nexport type NetworkStatsArgs = {\n version: number;\n bump: number;\n jobCount: number | bigint;\n volumeNative: number | bigint;\n volumeUsdc: number | bigint;\n lastUpdated: number | bigint;\n reserved: ReadonlyUint8Array;\n};\n\nexport function getNetworkStatsEncoder(): FixedSizeEncoder<NetworkStatsArgs> {\n return transformEncoder(\n getStructEncoder([\n ['discriminator', fixEncoderSize(getBytesEncoder(), 8)],\n ['version', getU8Encoder()],\n ['bump', getU8Encoder()],\n ['jobCount', getU64Encoder()],\n ['volumeNative', getU128Encoder()],\n ['volumeUsdc', getU128Encoder()],\n ['lastUpdated', getI64Encoder()],\n ['reserved', fixEncoderSize(getBytesEncoder(), 128)],\n ]),\n (value) => ({ ...value, discriminator: NETWORK_STATS_DISCRIMINATOR })\n );\n}\n\nexport function getNetworkStatsDecoder(): FixedSizeDecoder<NetworkStats> {\n return getStructDecoder([\n ['discriminator', fixDecoderSize(getBytesDecoder(), 8)],\n ['version', getU8Decoder()],\n ['bump', getU8Decoder()],\n ['jobCount', getU64Decoder()],\n ['volumeNative', getU128Decoder()],\n ['volumeUsdc', getU128Decoder()],\n ['lastUpdated', getI64Decoder()],\n ['reserved', fixDecoderSize(getBytesDecoder(), 128)],\n ]);\n}\n\nexport function getNetworkStatsCodec(): FixedSizeCodec<\n NetworkStatsArgs,\n NetworkStats\n> {\n return combineCodec(getNetworkStatsEncoder(), getNetworkStatsDecoder());\n}\n\nexport function decodeNetworkStats<TAddress extends string = string>(\n encodedAccount: EncodedAccount<TAddress>\n): Account<NetworkStats, TAddress>;\nexport function decodeNetworkStats<TAddress extends string = string>(\n encodedAccount: MaybeEncodedAccount<TAddress>\n): MaybeAccount<NetworkStats, TAddress>;\nexport function decodeNetworkStats<TAddress extends string = string>(\n encodedAccount: EncodedAccount<TAddress> | MaybeEncodedAccount<TAddress>\n): Account<NetworkStats, TAddress> | MaybeAccount<NetworkStats, TAddress> {\n return decodeAccount(\n encodedAccount as MaybeEncodedAccount<TAddress>,\n getNetworkStatsDecoder()\n );\n}\n\nexport async function fetchNetworkStats<TAddress extends string = string>(\n rpc: Parameters<typeof fetchEncodedAccount>[0],\n address: Address<TAddress>,\n config?: FetchAccountConfig\n): Promise<Account<NetworkStats, TAddress>> {\n const maybeAccount = await fetchMaybeNetworkStats(rpc, address, config);\n assertAccountExists(maybeAccount);\n return maybeAccount;\n}\n\nexport async function fetchMaybeNetworkStats<TAddress extends string = string>(\n rpc: Parameters<typeof fetchEncodedAccount>[0],\n address: Address<TAddress>,\n config?: FetchAccountConfig\n): Promise<MaybeAccount<NetworkStats, TAddress>> {\n const maybeAccount = await fetchEncodedAccount(rpc, address, config);\n return decodeNetworkStats(maybeAccount);\n}\n\nexport async function fetchAllNetworkStats(\n rpc: Parameters<typeof fetchEncodedAccounts>[0],\n addresses: Array<Address>,\n config?: FetchAccountsConfig\n): Promise<Account<NetworkStats>[]> {\n const maybeAccounts = await fetchAllMaybeNetworkStats(rpc, addresses, config);\n assertAccountsExist(maybeAccounts);\n return maybeAccounts;\n}\n\nexport async function fetchAllMaybeNetworkStats(\n rpc: Parameters<typeof fetchEncodedAccounts>[0],\n addresses: Array<Address>,\n config?: FetchAccountsConfig\n): Promise<MaybeAccount<NetworkStats>[]> {\n const maybeAccounts = await fetchEncodedAccounts(rpc, addresses, config);\n return maybeAccounts.map((maybeAccount) => decodeNetworkStats(maybeAccount));\n}\n\nexport function getNetworkStatsSize(): number {\n return 186;\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 containsBytes,\n fixEncoderSize,\n getBytesEncoder,\n type Address,\n type ReadonlyUint8Array,\n} from '@solana/kit';\nimport {\n type ParsedAcceptAdminInstruction,\n type ParsedCancelPendingAdminInstruction,\n type ParsedIncrementStatsInstruction,\n type ParsedInitializeInstruction,\n type ParsedInitializeStatsInstruction,\n type ParsedProposeAdminInstruction,\n type ParsedSetFeeBpsInstruction,\n type ParsedSetTreasuryInstruction,\n} from '../instructions';\n\nexport const ELISYM_CONFIG_PROGRAM_ADDRESS =\n 'BrX1CRkSgvcjxBvc2bgc3QqgWjinusofDmeP7ZVxvwrE' as Address<'BrX1CRkSgvcjxBvc2bgc3QqgWjinusofDmeP7ZVxvwrE'>;\n\nexport enum ElisymConfigAccount {\n Config,\n NetworkStats,\n}\n\nexport function identifyElisymConfigAccount(\n account: { data: ReadonlyUint8Array } | ReadonlyUint8Array\n): ElisymConfigAccount {\n const data = 'data' in account ? account.data : account;\n if (\n containsBytes(\n data,\n fixEncoderSize(getBytesEncoder(), 8).encode(\n new Uint8Array([155, 12, 170, 224, 30, 250, 204, 130])\n ),\n 0\n )\n ) {\n return ElisymConfigAccount.Config;\n }\n if (\n containsBytes(\n data,\n fixEncoderSize(getBytesEncoder(), 8).encode(\n new Uint8Array([171, 11, 222, 71, 255, 220, 21, 3])\n ),\n 0\n )\n ) {\n return ElisymConfigAccount.NetworkStats;\n }\n throw new Error(\n 'The provided account could not be identified as a elisymConfig account.'\n );\n}\n\nexport enum ElisymConfigInstruction {\n AcceptAdmin,\n CancelPendingAdmin,\n IncrementStats,\n Initialize,\n InitializeStats,\n ProposeAdmin,\n SetFeeBps,\n SetTreasury,\n}\n\nexport function identifyElisymConfigInstruction(\n instruction: { data: ReadonlyUint8Array } | ReadonlyUint8Array\n): ElisymConfigInstruction {\n const data = 'data' in instruction ? instruction.data : instruction;\n if (\n containsBytes(\n data,\n fixEncoderSize(getBytesEncoder(), 8).encode(\n new Uint8Array([112, 42, 45, 90, 116, 181, 13, 170])\n ),\n 0\n )\n ) {\n return ElisymConfigInstruction.AcceptAdmin;\n }\n if (\n containsBytes(\n data,\n fixEncoderSize(getBytesEncoder(), 8).encode(\n new Uint8Array([96, 213, 92, 102, 118, 54, 82, 93])\n ),\n 0\n )\n ) {\n return ElisymConfigInstruction.CancelPendingAdmin;\n }\n if (\n containsBytes(\n data,\n fixEncoderSize(getBytesEncoder(), 8).encode(\n new Uint8Array([145, 78, 96, 206, 45, 21, 111, 175])\n ),\n 0\n )\n ) {\n return ElisymConfigInstruction.IncrementStats;\n }\n if (\n containsBytes(\n data,\n fixEncoderSize(getBytesEncoder(), 8).encode(\n new Uint8Array([175, 175, 109, 31, 13, 152, 155, 237])\n ),\n 0\n )\n ) {\n return ElisymConfigInstruction.Initialize;\n }\n if (\n containsBytes(\n data,\n fixEncoderSize(getBytesEncoder(), 8).encode(\n new Uint8Array([144, 201, 117, 76, 127, 118, 176, 16])\n ),\n 0\n )\n ) {\n return ElisymConfigInstruction.InitializeStats;\n }\n if (\n containsBytes(\n data,\n fixEncoderSize(getBytesEncoder(), 8).encode(\n new Uint8Array([121, 214, 199, 212, 87, 39, 117, 234])\n ),\n 0\n )\n ) {\n return ElisymConfigInstruction.ProposeAdmin;\n }\n if (\n containsBytes(\n data,\n fixEncoderSize(getBytesEncoder(), 8).encode(\n new Uint8Array([2, 161, 245, 141, 111, 32, 39, 198])\n ),\n 0\n )\n ) {\n return ElisymConfigInstruction.SetFeeBps;\n }\n if (\n containsBytes(\n data,\n fixEncoderSize(getBytesEncoder(), 8).encode(\n new Uint8Array([57, 97, 196, 95, 195, 206, 106, 136])\n ),\n 0\n )\n ) {\n return ElisymConfigInstruction.SetTreasury;\n }\n throw new Error(\n 'The provided instruction could not be identified as a elisymConfig instruction.'\n );\n}\n\nexport type ParsedElisymConfigInstruction<\n TProgram extends string = 'BrX1CRkSgvcjxBvc2bgc3QqgWjinusofDmeP7ZVxvwrE',\n> =\n | ({\n instructionType: ElisymConfigInstruction.AcceptAdmin;\n } & ParsedAcceptAdminInstruction<TProgram>)\n | ({\n instructionType: ElisymConfigInstruction.CancelPendingAdmin;\n } & ParsedCancelPendingAdminInstruction<TProgram>)\n | ({\n instructionType: ElisymConfigInstruction.IncrementStats;\n } & ParsedIncrementStatsInstruction<TProgram>)\n | ({\n instructionType: ElisymConfigInstruction.Initialize;\n } & ParsedInitializeInstruction<TProgram>)\n | ({\n instructionType: ElisymConfigInstruction.InitializeStats;\n } & ParsedInitializeStatsInstruction<TProgram>)\n | ({\n instructionType: ElisymConfigInstruction.ProposeAdmin;\n } & ParsedProposeAdminInstruction<TProgram>)\n | ({\n instructionType: ElisymConfigInstruction.SetFeeBps;\n } & ParsedSetFeeBpsInstruction<TProgram>)\n | ({\n instructionType: ElisymConfigInstruction.SetTreasury;\n } & ParsedSetTreasuryInstruction<TProgram>);\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/** StatsOverflow: Stats counter overflow */\nexport const ELISYM_CONFIG_ERROR__STATS_OVERFLOW = 0x1777; // 6007\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__STATS_OVERFLOW\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__STATS_OVERFLOW]: `Stats counter overflow`,\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","/**\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 AccountRole,\n isProgramDerivedAddress,\n isTransactionSigner as kitIsTransactionSigner,\n type AccountMeta,\n type AccountSignerMeta,\n type Address,\n type ProgramDerivedAddress,\n type TransactionSigner,\n upgradeRoleToSigner,\n} from '@solana/kit';\n\n/**\n * Asserts that the given value is not null or undefined.\n * @internal\n */\nexport function expectSome<T>(value: T | null | undefined): T {\n if (value === null || value === undefined) {\n throw new Error('Expected a value but received null or undefined.');\n }\n return value;\n}\n\n/**\n * Asserts that the given value is a PublicKey.\n * @internal\n */\nexport function expectAddress<T extends string = string>(\n value:\n | Address<T>\n | ProgramDerivedAddress<T>\n | TransactionSigner<T>\n | null\n | undefined\n): Address<T> {\n if (!value) {\n throw new Error('Expected a Address.');\n }\n if (typeof value === 'object' && 'address' in value) {\n return value.address;\n }\n if (Array.isArray(value)) {\n return value[0] as Address<T>;\n }\n return value as Address<T>;\n}\n\n/**\n * Asserts that the given value is a PDA.\n * @internal\n */\nexport function expectProgramDerivedAddress<T extends string = string>(\n value:\n | Address<T>\n | ProgramDerivedAddress<T>\n | TransactionSigner<T>\n | null\n | undefined\n): ProgramDerivedAddress<T> {\n if (!value || !Array.isArray(value) || !isProgramDerivedAddress(value)) {\n throw new Error('Expected a ProgramDerivedAddress.');\n }\n return value;\n}\n\n/**\n * Asserts that the given value is a TransactionSigner.\n * @internal\n */\nexport function expectTransactionSigner<T extends string = string>(\n value:\n | Address<T>\n | ProgramDerivedAddress<T>\n | TransactionSigner<T>\n | null\n | undefined\n): TransactionSigner<T> {\n if (!value || !isTransactionSigner(value)) {\n throw new Error('Expected a TransactionSigner.');\n }\n return value;\n}\n\n/**\n * Defines an instruction account to resolve.\n * @internal\n */\nexport type ResolvedAccount<\n T extends string = string,\n U extends\n | Address<T>\n | ProgramDerivedAddress<T>\n | TransactionSigner<T>\n | null =\n | Address<T>\n | ProgramDerivedAddress<T>\n | TransactionSigner<T>\n | null,\n> = {\n isWritable: boolean;\n value: U;\n};\n\n/**\n * Defines an instruction that stores additional bytes on-chain.\n * @internal\n */\nexport type InstructionWithByteDelta = {\n byteDelta: number;\n};\n\n/**\n * Get account metas and signers from resolved accounts.\n * @internal\n */\nexport function getAccountMetaFactory(\n programAddress: Address,\n optionalAccountStrategy: 'omitted' | 'programId'\n) {\n return (\n account: ResolvedAccount\n ): AccountMeta | AccountSignerMeta | undefined => {\n if (!account.value) {\n if (optionalAccountStrategy === 'omitted') return;\n return Object.freeze({\n address: programAddress,\n role: AccountRole.READONLY,\n });\n }\n\n const writableRole = account.isWritable\n ? AccountRole.WRITABLE\n : AccountRole.READONLY;\n return Object.freeze({\n address: expectAddress(account.value),\n role: isTransactionSigner(account.value)\n ? upgradeRoleToSigner(writableRole)\n : writableRole,\n ...(isTransactionSigner(account.value) ? { signer: account.value } : {}),\n });\n };\n}\n\nexport function isTransactionSigner<TAddress extends string = string>(\n value:\n | Address<TAddress>\n | ProgramDerivedAddress<TAddress>\n | TransactionSigner<TAddress>\n): value is TransactionSigner<TAddress> {\n return (\n !!value &&\n typeof value === 'object' &&\n 'address' in value &&\n kitIsTransactionSigner(value)\n );\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 combineCodec,\n fixDecoderSize,\n fixEncoderSize,\n getBooleanDecoder,\n getBooleanEncoder,\n getBytesDecoder,\n getBytesEncoder,\n getProgramDerivedAddress,\n getStructDecoder,\n getStructEncoder,\n getU64Decoder,\n getU64Encoder,\n transformEncoder,\n type AccountMeta,\n type Address,\n type FixedSizeCodec,\n type FixedSizeDecoder,\n type FixedSizeEncoder,\n type Instruction,\n type InstructionWithAccounts,\n type InstructionWithData,\n type ReadonlyAccount,\n type ReadonlyUint8Array,\n type WritableAccount,\n} from '@solana/kit';\nimport { ELISYM_CONFIG_PROGRAM_ADDRESS } from '../programs';\nimport { getAccountMetaFactory, type ResolvedAccount } from '../shared';\n\nexport const INCREMENT_STATS_DISCRIMINATOR = new Uint8Array([\n 145, 78, 96, 206, 45, 21, 111, 175,\n]);\n\nexport function getIncrementStatsDiscriminatorBytes() {\n return fixEncoderSize(getBytesEncoder(), 8).encode(\n INCREMENT_STATS_DISCRIMINATOR\n );\n}\n\nexport type IncrementStatsInstruction<\n TProgram extends string = typeof ELISYM_CONFIG_PROGRAM_ADDRESS,\n TAccountStats extends string | AccountMeta<string> = string,\n TAccountEventAuthority extends string | AccountMeta<string> = string,\n TAccountProgram extends string | AccountMeta<string> = string,\n TRemainingAccounts extends readonly AccountMeta<string>[] = [],\n> = Instruction<TProgram> &\n InstructionWithData<ReadonlyUint8Array> &\n InstructionWithAccounts<\n [\n TAccountStats extends string\n ? WritableAccount<TAccountStats>\n : TAccountStats,\n TAccountEventAuthority extends string\n ? ReadonlyAccount<TAccountEventAuthority>\n : TAccountEventAuthority,\n TAccountProgram extends string\n ? ReadonlyAccount<TAccountProgram>\n : TAccountProgram,\n ...TRemainingAccounts,\n ]\n >;\n\nexport type IncrementStatsInstructionData = {\n discriminator: ReadonlyUint8Array;\n amount: bigint;\n isNative: boolean;\n};\n\nexport type IncrementStatsInstructionDataArgs = {\n amount: number | bigint;\n isNative: boolean;\n};\n\nexport function getIncrementStatsInstructionDataEncoder(): FixedSizeEncoder<IncrementStatsInstructionDataArgs> {\n return transformEncoder(\n getStructEncoder([\n ['discriminator', fixEncoderSize(getBytesEncoder(), 8)],\n ['amount', getU64Encoder()],\n ['isNative', getBooleanEncoder()],\n ]),\n (value) => ({ ...value, discriminator: INCREMENT_STATS_DISCRIMINATOR })\n );\n}\n\nexport function getIncrementStatsInstructionDataDecoder(): FixedSizeDecoder<IncrementStatsInstructionData> {\n return getStructDecoder([\n ['discriminator', fixDecoderSize(getBytesDecoder(), 8)],\n ['amount', getU64Decoder()],\n ['isNative', getBooleanDecoder()],\n ]);\n}\n\nexport function getIncrementStatsInstructionDataCodec(): FixedSizeCodec<\n IncrementStatsInstructionDataArgs,\n IncrementStatsInstructionData\n> {\n return combineCodec(\n getIncrementStatsInstructionDataEncoder(),\n getIncrementStatsInstructionDataDecoder()\n );\n}\n\nexport type IncrementStatsAsyncInput<\n TAccountStats extends string = string,\n TAccountEventAuthority extends string = string,\n TAccountProgram extends string = string,\n> = {\n stats?: Address<TAccountStats>;\n eventAuthority: Address<TAccountEventAuthority>;\n program: Address<TAccountProgram>;\n amount: IncrementStatsInstructionDataArgs['amount'];\n isNative: IncrementStatsInstructionDataArgs['isNative'];\n};\n\nexport async function getIncrementStatsInstructionAsync<\n TAccountStats extends string,\n TAccountEventAuthority extends string,\n TAccountProgram extends string,\n TProgramAddress extends Address = typeof ELISYM_CONFIG_PROGRAM_ADDRESS,\n>(\n input: IncrementStatsAsyncInput<\n TAccountStats,\n TAccountEventAuthority,\n TAccountProgram\n >,\n config?: { programAddress?: TProgramAddress }\n): Promise<\n IncrementStatsInstruction<\n TProgramAddress,\n TAccountStats,\n TAccountEventAuthority,\n TAccountProgram\n >\n> {\n // Program address.\n const programAddress =\n config?.programAddress ?? ELISYM_CONFIG_PROGRAM_ADDRESS;\n\n // Original accounts.\n const originalAccounts = {\n stats: { value: input.stats ?? null, isWritable: true },\n eventAuthority: { value: input.eventAuthority ?? null, isWritable: false },\n program: { value: input.program ?? null, isWritable: false },\n };\n const accounts = originalAccounts as Record<\n keyof typeof originalAccounts,\n ResolvedAccount\n >;\n\n // Original args.\n const args = { ...input };\n\n // Resolve default values.\n if (!accounts.stats.value) {\n accounts.stats.value = await getProgramDerivedAddress({\n programAddress,\n seeds: [\n getBytesEncoder().encode(\n new Uint8Array([\n 110, 101, 116, 119, 111, 114, 107, 95, 115, 116, 97, 116, 115,\n ])\n ),\n ],\n });\n }\n\n const getAccountMeta = getAccountMetaFactory(programAddress, 'programId');\n const instruction = {\n accounts: [\n getAccountMeta(accounts.stats),\n getAccountMeta(accounts.eventAuthority),\n getAccountMeta(accounts.program),\n ],\n programAddress,\n data: getIncrementStatsInstructionDataEncoder().encode(\n args as IncrementStatsInstructionDataArgs\n ),\n } as IncrementStatsInstruction<\n TProgramAddress,\n TAccountStats,\n TAccountEventAuthority,\n TAccountProgram\n >;\n\n return instruction;\n}\n\nexport type IncrementStatsInput<\n TAccountStats extends string = string,\n TAccountEventAuthority extends string = string,\n TAccountProgram extends string = string,\n> = {\n stats: Address<TAccountStats>;\n eventAuthority: Address<TAccountEventAuthority>;\n program: Address<TAccountProgram>;\n amount: IncrementStatsInstructionDataArgs['amount'];\n isNative: IncrementStatsInstructionDataArgs['isNative'];\n};\n\nexport function getIncrementStatsInstruction<\n TAccountStats extends string,\n TAccountEventAuthority extends string,\n TAccountProgram extends string,\n TProgramAddress extends Address = typeof ELISYM_CONFIG_PROGRAM_ADDRESS,\n>(\n input: IncrementStatsInput<\n TAccountStats,\n TAccountEventAuthority,\n TAccountProgram\n >,\n config?: { programAddress?: TProgramAddress }\n): IncrementStatsInstruction<\n TProgramAddress,\n TAccountStats,\n TAccountEventAuthority,\n TAccountProgram\n> {\n // Program address.\n const programAddress =\n config?.programAddress ?? ELISYM_CONFIG_PROGRAM_ADDRESS;\n\n // Original accounts.\n const originalAccounts = {\n stats: { value: input.stats ?? null, isWritable: true },\n eventAuthority: { value: input.eventAuthority ?? null, isWritable: false },\n program: { value: input.program ?? null, isWritable: false },\n };\n const accounts = originalAccounts as Record<\n keyof typeof originalAccounts,\n ResolvedAccount\n >;\n\n // Original args.\n const args = { ...input };\n\n const getAccountMeta = getAccountMetaFactory(programAddress, 'programId');\n const instruction = {\n accounts: [\n getAccountMeta(accounts.stats),\n getAccountMeta(accounts.eventAuthority),\n getAccountMeta(accounts.program),\n ],\n programAddress,\n data: getIncrementStatsInstructionDataEncoder().encode(\n args as IncrementStatsInstructionDataArgs\n ),\n } as IncrementStatsInstruction<\n TProgramAddress,\n TAccountStats,\n TAccountEventAuthority,\n TAccountProgram\n >;\n\n return instruction;\n}\n\nexport type ParsedIncrementStatsInstruction<\n TProgram extends string = typeof ELISYM_CONFIG_PROGRAM_ADDRESS,\n TAccountMetas extends readonly AccountMeta[] = readonly AccountMeta[],\n> = {\n programAddress: Address<TProgram>;\n accounts: {\n stats: TAccountMetas[0];\n eventAuthority: TAccountMetas[1];\n program: TAccountMetas[2];\n };\n data: IncrementStatsInstructionData;\n};\n\nexport function parseIncrementStatsInstruction<\n TProgram extends string,\n TAccountMetas extends readonly AccountMeta[],\n>(\n instruction: Instruction<TProgram> &\n InstructionWithAccounts<TAccountMetas> &\n InstructionWithData<ReadonlyUint8Array>\n): ParsedIncrementStatsInstruction<TProgram, TAccountMetas> {\n if (instruction.accounts.length < 3) {\n // TODO: Coded error.\n throw new Error('Not enough accounts');\n }\n let accountIndex = 0;\n const getNextAccount = () => {\n const accountMeta = (instruction.accounts as TAccountMetas)[accountIndex]!;\n accountIndex += 1;\n return accountMeta;\n };\n return {\n programAddress: instruction.programAddress,\n accounts: {\n stats: getNextAccount(),\n eventAuthority: getNextAccount(),\n program: getNextAccount(),\n },\n data: getIncrementStatsInstructionDataDecoder().decode(instruction.data),\n };\n}\n","import { type Address, getProgramDerivedAddress } from '@solana/kit';\n\nexport const CONFIG_SEED = 'config';\nexport const STATS_SEED = 'network_stats';\nexport const EVENT_AUTHORITY_SEED = '__event_authority';\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\nexport async function deriveNetworkStatsAddress(programId: Address): Promise<Address> {\n const [pda] = await getProgramDerivedAddress({\n programAddress: programId,\n seeds: [new TextEncoder().encode(STATS_SEED)],\n });\n return pda;\n}\n\n/**\n * Derives the Anchor `event_authority` PDA used by `emit_cpi!()` instructions.\n * Required as a read-only account for any instruction declared with `#[event_cpi]`.\n */\nexport async function deriveEventAuthorityAddress(programId: Address): Promise<Address> {\n const [pda] = await getProgramDerivedAddress({\n programAddress: programId,\n seeds: [new TextEncoder().encode(EVENT_AUTHORITY_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","/**\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\nimport Decimal from 'decimal.js-light';\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\nexport 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, USDC_SOLANA_DEVNET];\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\n/**\n * Resolve the asset a payment request targets. Returns `NATIVE_SOL` when the\n * request has no `asset` field (back-compat with payment requests published\n * before multi-asset support). Throws when `asset` is present but refers to an\n * asset that isn't in `KNOWN_ASSETS` - callers that want to tolerate unknown\n * assets should check `resolveKnownAsset` directly instead.\n */\nexport function resolveAssetFromPaymentRequest(request: {\n asset?: { chain: string; token: string; mint?: string };\n}): Asset {\n if (!request.asset) {\n return NATIVE_SOL;\n }\n const found = resolveKnownAsset(request.asset.chain, request.asset.token, request.asset.mint);\n if (!found) {\n const display = request.asset.mint\n ? `${request.asset.chain}:${request.asset.token}:${request.asset.mint}`\n : `${request.asset.chain}:${request.asset.token}`;\n throw new Error(\n `Unknown asset in payment request: ${display}. ` +\n `Known assets: ${KNOWN_ASSETS.map(assetKey).join(', ')}`,\n );\n }\n return found;\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// Cloned config keeps `Decimal.toString()` from switching to exponential notation\n// for small fractional amounts (e.g. 1 lamport = 1e-9 SOL).\nconst FormatDecimal = Decimal.clone({ toExpNeg: -100, toExpPos: 100, precision: 50 });\n\n/**\n * Format raw subunits back to `\"<value> <SYMBOL>\"`. Trailing zeros and a bare\n * trailing dot are stripped, so 0.01 USDC renders as `\"0.01 USDC\"` rather than\n * `\"0.010000 USDC\"`.\n */\nexport function formatAssetAmount(asset: Asset, raw: bigint): string {\n const value = new FormatDecimal(raw.toString()).div(new FormatDecimal(10).pow(asset.decimals));\n return `${value.toString()} ${asset.symbol}`;\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), typically obtained\n * from `getProtocolConfig` or supplied as a test fixture.\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\nconst paymentAssetRefSchema = z.object({\n chain: z.string().min(1),\n token: z.string().min(1),\n mint: solanaAddressSchema.optional(),\n decimals: z.number().int().min(0).max(18),\n});\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 asset: paymentAssetRefSchema.optional(),\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 {\n deriveEventAuthorityAddress,\n deriveNetworkStatsAddress,\n getIncrementStatsInstruction,\n} from '@elisym/config-client';\nimport { getAddMemoInstruction } from '@solana-program/memo';\nimport { getTransferSolInstruction } from '@solana-program/system';\nimport {\n ASSOCIATED_TOKEN_PROGRAM_ADDRESS,\n TOKEN_PROGRAM_ADDRESS,\n findAssociatedTokenPda,\n getCreateAssociatedTokenIdempotentInstruction,\n getTransferCheckedInstruction,\n} from '@solana-program/token';\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, ELISYM_PROTOCOL_TAG, LIMITS, getProtocolProgramId } from '../constants';\nimport type {\n PaymentAssetRef,\n PaymentRequestData,\n PaymentValidationError,\n VerifyOptions,\n VerifyResult,\n} from '../types';\nimport { type Asset, NATIVE_SOL, resolveAssetFromPaymentRequest } from './assets';\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; asset?: Asset },\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 const assetRef: PaymentAssetRef | undefined =\n options?.asset && options.asset !== NATIVE_SOL\n ? {\n chain: options.asset.chain,\n token: options.asset.token,\n mint: options.asset.mint,\n decimals: options.asset.decimals,\n }\n : undefined;\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 ...(assetRef ? { asset: assetRef } : {}),\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 // Reject payment requests that reference an asset the SDK doesn't know\n // about - the customer cannot safely build a transaction without knowing\n // the wire format (System transfer vs SPL TransferChecked).\n if (data.asset) {\n try {\n resolveAssetFromPaymentRequest(data);\n } catch (error) {\n return {\n code: 'invalid_asset',\n message: error instanceof Error ? error.message : String(error),\n };\n }\n }\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 surfaces shape errors (e.g. fee\n // >= amount) and, for SPL assets, derives the ATAs, before any RPC\n // round-trip that depends on them.\n const paymentInstructions = await buildPaymentInstructions(paymentRequest, payerSigner, {\n jobEventId: options?.jobEventId,\n programId: options?.programId,\n });\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 let asset: Asset;\n try {\n asset = resolveAssetFromPaymentRequest(paymentRequest);\n } catch (error) {\n return {\n verified: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n const mint = asset.mint;\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 mint,\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 mint,\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 mint: string | undefined,\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 = checkTxDiff({\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 preTokenBalances: tx.meta.preTokenBalances as readonly TokenBalanceEntry[] | undefined,\n postTokenBalances: tx.meta.postTokenBalances as readonly TokenBalanceEntry[] | undefined,\n referenceKey,\n recipientAddress,\n treasuryAddress,\n expectedNet,\n expectedFee,\n mint,\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 mint: string | undefined,\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 = checkTxDiff({\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 preTokenBalances: tx.meta.preTokenBalances as\n | readonly TokenBalanceEntry[]\n | undefined,\n postTokenBalances: tx.meta.postTokenBalances as\n | readonly TokenBalanceEntry[]\n | undefined,\n referenceKey,\n recipientAddress,\n treasuryAddress,\n expectedNet,\n expectedFee,\n mint,\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 TokenBalanceEntry {\n accountIndex: number;\n mint: string;\n owner?: string;\n uiTokenAmount: { amount: string };\n}\n\ninterface TxDiffInput {\n accountKeys: readonly string[];\n preBalances: readonly bigint[];\n postBalances: readonly bigint[];\n preTokenBalances?: readonly TokenBalanceEntry[];\n postTokenBalances?: readonly TokenBalanceEntry[];\n referenceKey: string;\n recipientAddress: string;\n treasuryAddress: string;\n expectedNet: number;\n expectedFee: number;\n /** SPL mint for token transfers. `undefined` => native SOL path. */\n mint?: string;\n}\n\ntype BalanceVerdict = { ok: true } | { ok: false; reason: string };\n\nfunction checkTxDiff(input: TxDiffInput): 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\n if (input.mint) {\n return checkTokenBalanceDiff(input);\n }\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 checkTokenBalanceDiff(input: TxDiffInput): BalanceVerdict {\n const mint = input.mint;\n if (!mint) {\n return { ok: false, reason: 'Expected mint for SPL verification, got none' };\n }\n const pre = input.preTokenBalances ?? [];\n const post = input.postTokenBalances ?? [];\n\n const tokenDelta = (ownerAddress: string): bigint => {\n // Pre-entry may be absent when the ATA is created inside the same tx\n // (first-ever payment to this recipient). Missing => 0.\n const preEntry = pre.find((entry) => entry.owner === ownerAddress && entry.mint === mint);\n const postEntry = post.find((entry) => entry.owner === ownerAddress && entry.mint === mint);\n if (!postEntry) {\n return -1n;\n }\n const preAmount = preEntry ? BigInt(preEntry.uiTokenAmount.amount) : 0n;\n const postAmount = BigInt(postEntry.uiTokenAmount.amount);\n return postAmount - preAmount;\n };\n\n const recipientDelta = tokenDelta(input.recipientAddress);\n if (recipientDelta === -1n) {\n return { ok: false, reason: 'Recipient token account not found in transaction' };\n }\n if (recipientDelta < BigInt(input.expectedNet)) {\n return {\n ok: false,\n reason: `Recipient received ${recipientDelta.toString()} tokens, expected >= ${input.expectedNet}`,\n };\n }\n\n if (input.expectedFee > 0) {\n const treasuryDelta = tokenDelta(input.treasuryAddress);\n if (treasuryDelta === -1n) {\n return { ok: false, reason: 'Treasury token account not found in transaction' };\n }\n if (treasuryDelta < BigInt(input.expectedFee)) {\n return {\n ok: false,\n reason: `Treasury received ${treasuryDelta.toString()} tokens, 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 transfer instructions for a payment request.\n *\n * For native SOL (no `paymentRequest.asset` or asset=NATIVE_SOL), emits System\n * program `TransferSol` instructions with the payment reference attached as a\n * read-only, non-signer account so providers can detect the payment via\n * `getSignaturesForAddress(reference)`.\n *\n * For SPL assets (USDC on Solana), emits:\n * 1. `CreateAssociatedTokenIdempotent` for the recipient ATA (funded by payer);\n * 2. `CreateAssociatedTokenIdempotent` for the treasury ATA if a protocol fee applies;\n * 3. `TransferChecked` from payer ATA to recipient ATA, with `reference` as an\n * extra read-only account (canonical Solana Pay pattern);\n * 4. `TransferChecked` from payer ATA to treasury ATA if a fee applies.\n *\n * Every provider transfer instruction also carries `ELISYM_PROTOCOL_TAG` as a\n * read-only marker account so off-chain indexers can enumerate every elisym\n * transaction with a single `getSignaturesForAddress(ELISYM_PROTOCOL_TAG)`\n * call, regardless of fee size.\n *\n * If `options.jobEventId` is provided, an SPL Memo instruction with payload\n * `elisym:v1:<jobEventId>` is prepended so explorers display the originating\n * Nostr job id and indexers can join on-chain payments back to off-chain\n * job context.\n *\n * Async because SPL ATAs are PDAs and `findAssociatedTokenPda` is async.\n *\n * Caller is responsible for validating `paymentRequest` upstream;\n * `buildTransaction` already does that before invoking this helper.\n */\nexport async function buildPaymentInstructions(\n paymentRequest: PaymentRequestData,\n payerSigner: Signer,\n options?: { jobEventId?: string; programId?: Address },\n): Promise<readonly unknown[]> {\n const recipient = address(paymentRequest.recipient);\n const reference = address(paymentRequest.reference);\n const protocolTag = address(ELISYM_PROTOCOL_TAG);\n const programId = options?.programId ?? getProtocolProgramId('devnet');\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 const statsPda = await deriveNetworkStatsAddress(programId);\n const eventAuthority = await deriveEventAuthorityAddress(programId);\n const incrementStatsIx = getIncrementStatsInstruction(\n {\n stats: statsPda,\n eventAuthority,\n program: programId,\n amount: BigInt(paymentRequest.amount),\n isNative: !resolveAssetFromPaymentRequest(paymentRequest).mint,\n },\n { programAddress: programId },\n );\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 memoInstruction = options?.jobEventId\n ? getAddMemoInstruction({ memo: `elisym:v1:${options.jobEventId}` })\n : null;\n\n // Native SOL path - unchanged from the pre-USDC behaviour.\n const asset = resolveAssetFromPaymentRequest(paymentRequest);\n if (!asset.mint) {\n const providerTransferIx = getTransferSolInstruction({\n source: payerSigner,\n destination: recipient,\n amount: BigInt(providerAmount),\n });\n const providerTransferIxWithMarkers = {\n ...providerTransferIx,\n accounts: [\n ...providerTransferIx.accounts,\n { address: reference, role: AccountRole.READONLY },\n { address: protocolTag, role: AccountRole.READONLY },\n ],\n };\n\n const instructions: unknown[] = [];\n if (memoInstruction) {\n instructions.push(memoInstruction);\n }\n instructions.push(providerTransferIxWithMarkers);\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 instructions.push(incrementStatsIx);\n return instructions;\n }\n\n // SPL path.\n const mint = address(asset.mint);\n const payerAddress = payerSigner.address;\n const [payerAta] = await findAssociatedTokenPda({\n owner: payerAddress,\n tokenProgram: TOKEN_PROGRAM_ADDRESS,\n mint,\n });\n const [recipientAta] = await findAssociatedTokenPda({\n owner: recipient,\n tokenProgram: TOKEN_PROGRAM_ADDRESS,\n mint,\n });\n\n const instructions: unknown[] = [];\n if (memoInstruction) {\n instructions.push(memoInstruction);\n }\n instructions.push(\n getCreateAssociatedTokenIdempotentInstruction(\n {\n payer: payerSigner,\n ata: recipientAta,\n owner: recipient,\n mint,\n },\n { programAddress: ASSOCIATED_TOKEN_PROGRAM_ADDRESS },\n ),\n );\n\n let treasuryAta: Address | undefined;\n if (paymentRequest.fee_address && feeAmount > 0) {\n const treasuryOwner = address(paymentRequest.fee_address);\n [treasuryAta] = await findAssociatedTokenPda({\n owner: treasuryOwner,\n tokenProgram: TOKEN_PROGRAM_ADDRESS,\n mint,\n });\n instructions.push(\n getCreateAssociatedTokenIdempotentInstruction(\n {\n payer: payerSigner,\n ata: treasuryAta,\n owner: treasuryOwner,\n mint,\n },\n { programAddress: ASSOCIATED_TOKEN_PROGRAM_ADDRESS },\n ),\n );\n }\n\n const providerTransferIx = getTransferCheckedInstruction({\n source: payerAta,\n mint,\n destination: recipientAta,\n authority: payerSigner,\n amount: BigInt(providerAmount),\n decimals: asset.decimals,\n });\n const providerTransferIxWithMarkers = {\n ...providerTransferIx,\n accounts: [\n ...providerTransferIx.accounts,\n { address: reference, role: AccountRole.READONLY },\n { address: protocolTag, role: AccountRole.READONLY },\n ],\n };\n instructions.push(providerTransferIxWithMarkers);\n\n if (treasuryAta && paymentRequest.fee_address && feeAmount > 0) {\n instructions.push(\n getTransferCheckedInstruction({\n source: payerAta,\n mint,\n destination: treasuryAta,\n authority: payerSigner,\n amount: BigInt(feeAmount),\n decimals: asset.decimals,\n }),\n );\n }\n\n instructions.push(incrementStatsIx);\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","/**\n * BlossomService - BUD-11 authenticated blob uploads to a Blossom server.\n *\n * Blossom (https://github.com/hzrd149/blossom) is content-addressed: blobs are stored\n * by sha256 and writes are authorized with a signed Nostr event (BUD-11, kind 24242) -\n * NOT NIP-98 (kind 27235) like MediaService/nostr.build. This service uploads to the\n * self-hosted elisym relay and, if that fails, falls back to an injected uploader (the\n * client wires MediaService/nostr.build in) so uploads stay resilient.\n */\nimport { finalizeEvent } from 'nostr-tools';\nimport { DEFAULTS, LIMITS } from '../constants';\nimport type { ElisymIdentity } from '../primitives/identity';\n\nconst KIND_BLOSSOM_AUTH = 24242;\nconst DEFAULT_BLOSSOM_URL = 'https://files.elisym.network';\nconst AUTH_TTL_SECS = 600;\n\n/** Result of an upload. */\nexport interface BlobDescriptor {\n /**\n * Publicly GET-able URL. Content-addressed (https://<host>/<sha256>.<ext>) ONLY when\n * `provider === 'blossom'`; on `'fallback'` it is a provider-assigned nostr.build URL\n * that may NOT be addressed by `sha256` (the host may re-encode the bytes).\n */\n url: string;\n /**\n * Lowercase-hex SHA-256 of the bytes the caller uploaded. On `'blossom'` it is also\n * verified to equal what the server stored (integrity check). On `'fallback'` it is the\n * local hash only - do NOT assume `url` resolves to it.\n */\n sha256: string;\n size: number;\n type: string;\n /** Unix seconds; only the Blossom path returns it. */\n uploaded?: number;\n provider: 'blossom' | 'fallback';\n}\n\n/** Fallback uploader invoked when the Blossom upload fails; returns the stored URL. */\nexport type BlossomUploadFallback = (identity: ElisymIdentity, file: Blob) => Promise<string>;\n\nexport class BlossomService {\n constructor(\n private serverUrl: string = DEFAULT_BLOSSOM_URL,\n private fallback?: BlossomUploadFallback,\n ) {}\n\n /**\n * The content-addressed GET URL for a blob, derivable from its sha256 BEFORE\n * upload (BUD-01: `<serverUrl>/<sha256>`, no extension for our octet-stream\n * ciphertext uploads - same form `delete` addresses by). Lets a caller build a\n * complete attachment descriptor and defer the actual byte upload (the descriptor\n * is submitted first, the bytes PUT later). `upload()` re-verifies the server\n * returns this exact url.\n */\n contentUrl(sha256: string): string {\n return `${this.serverUrl}/${sha256}`;\n }\n\n /**\n * Upload a file to the Blossom server, returning its descriptor. On any failure, falls\n * back to the configured uploader (if any) and returns a normalized descriptor with\n * `provider: 'fallback'`. Works with browser File objects and Node.js/Bun Blobs.\n */\n async upload(identity: ElisymIdentity, file: Blob): Promise<BlobDescriptor> {\n const bytes = new Uint8Array(await file.arrayBuffer());\n if (bytes.byteLength > LIMITS.MAX_FILE_SIZE) {\n throw new Error(\n `File too large: ${bytes.byteLength} bytes exceeds limit of ${LIMITS.MAX_FILE_SIZE}.`,\n );\n }\n\n const hashBuffer = await crypto.subtle.digest('SHA-256', bytes);\n const hashHex = [...new Uint8Array(hashBuffer)]\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n\n try {\n return await this.uploadToBlossom(identity, bytes, hashHex, file.type);\n } catch (err) {\n if (!this.fallback) {\n throw err;\n }\n const url = await this.fallback(identity, file);\n return {\n url,\n sha256: hashHex,\n size: file.size,\n type: file.type || 'application/octet-stream',\n provider: 'fallback',\n };\n }\n }\n\n /** Delete a blob by sha256 (BUD-02). Blossom only - there is no fallback for deletes. */\n async delete(identity: ElisymIdentity, sha256: string): Promise<void> {\n if (!/^[0-9a-f]{64}$/.test(sha256)) {\n throw new Error('sha256 must be 64 lowercase hex chars.');\n }\n\n const authHeader = this.authHeader(identity, 'delete', sha256);\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), DEFAULTS.BLOSSOM_UPLOAD_TIMEOUT_MS);\n try {\n const res = await fetch(`${this.serverUrl}/${sha256}`, {\n method: 'DELETE',\n headers: { Authorization: authHeader },\n signal: controller.signal,\n });\n if (!res.ok) {\n throw new Error(`Delete failed: ${res.status} ${res.statusText}`);\n }\n } finally {\n clearTimeout(timer);\n }\n }\n\n /**\n * Download a public blob (BUD-01 GET, no auth). Bounds memory on the ACTUAL streamed bytes (never\n * the declared Content-Length) and verifies the sha256 when `expectedSha256` is given. Browser-safe.\n */\n async download(\n url: string,\n opts: { maxBytes?: number; timeoutMs?: number; expectedSha256?: string } = {},\n ): Promise<Uint8Array> {\n const maxBytes = opts.maxBytes ?? LIMITS.MAX_FILE_SIZE;\n const controller = new AbortController();\n const timer = setTimeout(\n () => controller.abort(),\n opts.timeoutMs ?? DEFAULTS.BLOSSOM_FETCH_TIMEOUT_MS,\n );\n try {\n const res = await fetch(url, { signal: controller.signal });\n if (!res.ok) {\n throw new Error(`Download failed: ${res.status} ${res.statusText}`);\n }\n const declared = Number(res.headers.get('content-length'));\n if (Number.isFinite(declared) && declared > maxBytes) {\n throw new Error(`Blob too large: ${declared} bytes exceeds limit of ${maxBytes}.`);\n }\n if (!res.body) {\n throw new Error('Download response has no body.');\n }\n\n const reader = res.body.getReader();\n const chunks: Uint8Array[] = [];\n let total = 0;\n let chunk = await reader.read();\n while (!chunk.done) {\n total += chunk.value.byteLength;\n if (total > maxBytes) {\n await reader.cancel();\n throw new Error(`Blob exceeds limit of ${maxBytes} bytes.`);\n }\n chunks.push(chunk.value);\n chunk = await reader.read();\n }\n\n const bytes = new Uint8Array(total);\n let offset = 0;\n for (const c of chunks) {\n bytes.set(c, offset);\n offset += c.byteLength;\n }\n\n if (opts.expectedSha256 !== undefined) {\n const digest = await crypto.subtle.digest('SHA-256', bytes);\n const hashHex = [...new Uint8Array(digest)]\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n if (hashHex !== opts.expectedSha256) {\n throw new Error(\n `Download integrity check failed: got ${hashHex}, expected ${opts.expectedSha256}.`,\n );\n }\n }\n return bytes;\n } finally {\n clearTimeout(timer);\n }\n }\n\n private async uploadToBlossom(\n identity: ElisymIdentity,\n bytes: Uint8Array,\n hashHex: string,\n mime: string,\n ): Promise<BlobDescriptor> {\n const contentType = mime || 'application/octet-stream';\n const authHeader = this.authHeader(identity, 'upload', hashHex);\n\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), DEFAULTS.BLOSSOM_UPLOAD_TIMEOUT_MS);\n try {\n const res = await fetch(`${this.serverUrl}/upload`, {\n method: 'PUT',\n headers: { Authorization: authHeader, 'Content-Type': contentType },\n body: bytes,\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: {\n url?: string;\n sha256?: string;\n size?: number;\n type?: string;\n uploaded?: number;\n };\n try {\n data = await res.json();\n } catch {\n throw new Error('Invalid response from Blossom server.');\n }\n\n if (!data.url || !data.sha256) {\n throw new Error('No descriptor returned from Blossom server.');\n }\n if (data.sha256 !== hashHex) {\n throw new Error(\n `Blossom upload integrity check failed: server returned ${data.sha256}, expected ${hashHex}.`,\n );\n }\n\n return {\n url: data.url,\n sha256: data.sha256,\n size: data.size ?? bytes.byteLength,\n type: data.type ?? contentType,\n uploaded: data.uploaded,\n provider: 'blossom',\n };\n } finally {\n clearTimeout(timer);\n }\n }\n\n private authHeader(identity: ElisymIdentity, verb: 'upload' | 'delete', sha256: string): string {\n const now = Math.floor(Date.now() / 1000);\n const authEvent = finalizeEvent(\n {\n kind: KIND_BLOSSOM_AUTH,\n created_at: now,\n tags: [\n ['t', verb],\n ['x', sha256],\n ['expiration', String(now + AUTH_TTL_SECS)],\n ],\n content: `${verb} blob via elisym SDK`,\n },\n identity.secretKey,\n );\n // btoa is safe here: a signed Nostr event serializes to pure ASCII (hex ids/keys,\n // integer timestamps, ASCII tag strings and content).\n return 'Nostr ' + btoa(JSON.stringify(authEvent));\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,\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, SubCloser } from '../types';\n\nconst RANKING_ACTIVITY_WINDOW_SECS = 30 * 24 * 60 * 60;\nconst RANKING_BUCKET_SIZE_SECS = 60;\nconst COLD_START_BUCKET = -Infinity;\n\n/** Sentinel signal that never aborts; lets `runEnrichment` accept an `AbortSignal` uniformly. */\nconst NEVER_ABORTED_SIGNAL: AbortSignal = new AbortController().signal;\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/** Sort key derived from an Agent. Higher bucket / rate / lastPaidJobAt = ranks higher. */\nexport interface RankKey {\n /** Floor-to-minute timestamp of the agent's last verified paid job. `-Infinity` for cold start. */\n bucket: number;\n /** Positive review rate in `[0, 1]`. 0 when the agent has no rated feedback. */\n rate: number;\n /** Raw `lastPaidJobAt` (Unix sec) for tiebreak inside a bucket. 0 for cold start. */\n lastPaidJobAt: number;\n /** Final tiebreak; orders cold-start agents by NIP-89 freshness. */\n lastSeen: number;\n}\n\nexport function computeRankKey(agent: Agent): RankKey {\n const lastPaidJobAt = agent.lastPaidJobAt ?? 0;\n const total = agent.totalRatingCount ?? 0;\n const positive = agent.positiveCount ?? 0;\n const rate = total > 0 ? positive / total : 0;\n const bucket =\n lastPaidJobAt > 0\n ? Math.floor(lastPaidJobAt / RANKING_BUCKET_SIZE_SECS) * RANKING_BUCKET_SIZE_SECS\n : COLD_START_BUCKET;\n return { bucket, rate, lastPaidJobAt, lastSeen: agent.lastSeen };\n}\n\nexport function compareAgentsByRank(a: Agent, b: Agent): number {\n const ka = computeRankKey(a);\n const kb = computeRankKey(b);\n if (kb.bucket !== ka.bucket) {\n return kb.bucket - ka.bucket;\n }\n if (kb.rate !== ka.rate) {\n return kb.rate - ka.rate;\n }\n if (kb.lastPaidJobAt !== ka.lastPaidJobAt) {\n return kb.lastPaidJobAt - ka.lastPaidJobAt;\n }\n return kb.lastSeen - ka.lastSeen;\n}\n\n/**\n * Parse a single NIP-89 capability event into a one-card Agent.\n *\n * Returns `null` if the event fails signature verification, content schema\n * checks, or the `network` filter. The returned Agent's `supportedKinds`\n * holds only this event's `k` tags - merging across multiple events for the\n * same author is the caller's responsibility.\n */\nexport function parseCapabilityEvent(event: Event, network: Network): Agent | null {\n if (!verifyEvent(event)) {\n return null;\n }\n if (!event.content) {\n return null;\n }\n let raw: unknown;\n try {\n raw = JSON.parse(event.content);\n } catch {\n return null;\n }\n if (!raw || typeof raw !== 'object') {\n return null;\n }\n const candidate = raw as Record<string, unknown>;\n if (typeof candidate.name !== 'string' || !candidate.name) {\n return null;\n }\n if (typeof candidate.description !== 'string') {\n return null;\n }\n if (\n !Array.isArray(candidate.capabilities) ||\n !candidate.capabilities.every((cap: unknown) => typeof cap === 'string')\n ) {\n return null;\n }\n if (candidate.deleted) {\n return null;\n }\n const card = candidate as unknown as CapabilityCard & { deleted?: boolean };\n\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 return null;\n }\n\n // Optional token/symbol/mint must be strings when present: a non-string slips\n // through to display code (`payment.token.toUpperCase()`) and throws at render.\n if (\n card.payment &&\n ((card.payment.token !== undefined && typeof card.payment.token !== 'string') ||\n (card.payment.symbol !== undefined && typeof card.payment.symbol !== 'string') ||\n (card.payment.mint !== undefined && typeof card.payment.mint !== 'string'))\n ) {\n return null;\n }\n\n // Optional file-MIME hints must be bounded strings when present. This is\n // untrusted remote data; the cap (matching the loader's) keeps an unbounded\n // string out of client state. Clients gate on presence, not the value.\n if (\n (card.inputMime !== undefined &&\n (typeof card.inputMime !== 'string' || card.inputMime.length > 255)) ||\n (card.outputMime !== undefined &&\n (typeof card.outputMime !== 'string' || card.outputMime.length > 255))\n ) {\n return null;\n }\n\n // `inputText` is an enum, so coerce an unknown value to undefined (do NOT drop the\n // whole card like the strict MIME check above): forward-compat so a future value\n // never hides an agent from older clients. Clients gate on the known values only.\n if (card.inputText !== undefined && !['required', 'optional', 'none'].includes(card.inputText)) {\n card.inputText = undefined;\n }\n\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 return null;\n }\n\n const agentNetwork = card.payment?.network ?? 'devnet';\n if (agentNetwork !== network) {\n return null;\n }\n\n const kTags = event.tags\n .filter((tag) => tag[0] === 'k')\n .map((tag) => parseInt(tag[1] ?? '', 10))\n .filter((kind) => !isNaN(kind));\n\n return {\n pubkey: event.pubkey,\n npub: nip19.npubEncode(event.pubkey),\n cards: [card],\n eventId: event.id,\n supportedKinds: kTags,\n lastSeen: event.created_at,\n };\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 // Verify here (not in `parseCapabilityEvent` alone) so a forged event with\n // a future `created_at` cannot displace a legitimate event from the dedup\n // map and effectively erase the victim's agent from results.\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((tag) => tag[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 // Per-pubkey accumulator. We track per-card `createdAt` + `kTags` so\n // `supportedKinds` is recomputed from only the surviving (name-dedup'd)\n // cards, matching the pre-refactor behavior.\n interface Accum {\n agent: Agent;\n perCard: Map<string, { createdAt: number; kTags: number[] }>;\n }\n const accumMap = new Map<string, Accum>();\n\n for (const event of latestByDTag.values()) {\n const parsed = parseCapabilityEvent(event, network);\n if (!parsed) {\n continue;\n }\n const card = parsed.cards[0]!;\n const cardKinds = parsed.supportedKinds;\n const createdAt = parsed.lastSeen;\n\n const existing = accumMap.get(parsed.pubkey);\n if (existing) {\n const prevForName = existing.perCard.get(card.name);\n if (prevForName) {\n if (createdAt >= prevForName.createdAt) {\n const idx = existing.agent.cards.findIndex(\n (existingCard) => existingCard.name === card.name,\n );\n if (idx >= 0) {\n existing.agent.cards[idx] = card;\n }\n existing.perCard.set(card.name, { createdAt, kTags: cardKinds });\n }\n } else {\n existing.agent.cards.push(card);\n existing.perCard.set(card.name, { createdAt, kTags: cardKinds });\n }\n if (createdAt > existing.agent.lastSeen) {\n existing.agent.lastSeen = createdAt;\n existing.agent.eventId = parsed.eventId;\n }\n } else {\n accumMap.set(parsed.pubkey, {\n agent: parsed,\n perCard: new Map([[card.name, { createdAt, kTags: cardKinds }]]),\n });\n }\n }\n\n const agentMap = new Map<string, Agent>();\n for (const [pubkey, acc] of accumMap) {\n const kindsSet = new Set<number>();\n for (const { kTags } of acc.perCard.values()) {\n for (const kind of kTags) {\n kindsSet.add(kind);\n }\n }\n acc.agent.supportedKinds = [...kindsSet];\n agentMap.set(pubkey, acc.agent);\n }\n\n return agentMap;\n}\n\nexport class DiscoveryService {\n constructor(private pool: NostrPool) {}\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.banner === 'string') {\n agent.banner = meta.banner;\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 /**\n * Fetch elisym agents filtered by network, ranked by paid-job recency and\n * positive-feedback rate.\n *\n * Ranking algorithm:\n * 1. Bucket each agent into 1-minute slots by `lastPaidJobAt` (newest\n * `payment-completed` feedback timestamp, gated by a matching kind:6xxx\n * result from the provider on the same job event). Cold-start agents go\n * into a sentinel bucket below all populated buckets.\n * 2. Within a bucket, sort by positive review rate descending.\n * 3. Tiebreak by raw `lastPaidJobAt`, then `lastSeen` (NIP-89 freshness).\n *\n * NOTE: We do not verify the `tx` signature on-chain - public Solana devnet\n * RPC rate-limits trivially exceed what discovery needs (N agents * up-to-5\n * candidates), and the resulting 429s blocked discovery entirely. As a\n * lighter sybil mitigation we cross-check `payment-completed` feedback\n * against a kind:6xxx result event authored by the provider on the same\n * job: a customer can publish a fake `payment-completed`, but they cannot\n * forge a result event signed by the provider. Tighten with recipient-tied\n * on-chain checks when the network moves to mainnet with a paid RPC\n * provider.\n */\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 const agents = Array.from(agentMap.values());\n\n return this.runEnrichment(agents, agentMap, NEVER_ABORTED_SIGNAL);\n }\n\n /**\n * Fetch a single agent by pubkey, fully enriched (kind:0 metadata,\n * cross-checked `lastPaidJobAt`, rating counters). Returns `null` if the\n * pubkey has no surviving capability cards on the requested network.\n *\n * Use this when navigating directly to an agent's page; running\n * `fetchAgents`/`streamAgents` for that case streams the entire marketplace\n * just to find one author.\n */\n async fetchAgent(network: Network, pubkey: string): Promise<Agent | null> {\n const events = await this.pool.querySync({\n kinds: [KIND_APP_HANDLER],\n '#t': ['elisym'],\n authors: [pubkey],\n });\n\n const agentMap = buildAgentsFromEvents(events, network);\n if (agentMap.size === 0) {\n return null;\n }\n const agents = Array.from(agentMap.values());\n await this.runEnrichment(agents, agentMap, NEVER_ABORTED_SIGNAL);\n return agentMap.get(pubkey) ?? null;\n }\n\n /**\n * Enrich an agent map with paid-job stats, feedback counters, and kind:0\n * metadata, then return them sorted by `compareAgentsByRank`. Mutates the\n * passed-in `Agent` objects in place.\n *\n * Shared between `fetchAgents` (one-shot) and `streamAgents` (post-EOSE\n * second pass). The `signal` short-circuits the post-query work; in-flight\n * pool queries are not cancellable today (they fall through to the standard\n * timeout) and the caller drops the resolved value.\n */\n private async runEnrichment(\n agents: Agent[],\n agentMap: Map<string, Agent>,\n signal: AbortSignal,\n ): Promise<Agent[]> {\n const agentPubkeys = Array.from(agentMap.keys());\n if (agentPubkeys.length === 0) {\n return agents;\n }\n\n const activitySince = Math.floor(Date.now() / 1000) - RANKING_ACTIVITY_WINDOW_SECS;\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 supportedKind of agent.supportedKinds) {\n if (supportedKind >= KIND_JOB_REQUEST_BASE && supportedKind < KIND_JOB_RESULT_BASE) {\n resultKinds.add(KIND_JOB_RESULT_BASE + (supportedKind - KIND_JOB_REQUEST_BASE));\n }\n }\n }\n resultKinds.add(jobResultKind(DEFAULT_KIND_OFFSET));\n\n const [resultEvents, feedbackEvents] = await Promise.all([\n this.pool.queryBatched(\n {\n kinds: [...resultKinds],\n since: activitySince,\n } as Omit<Filter, 'authors'>,\n agentPubkeys,\n ),\n this.pool.queryBatchedByTag(\n { kinds: [KIND_JOB_FEEDBACK], since: activitySince } as Filter,\n 'p',\n agentPubkeys,\n ),\n this.enrichWithMetadata(agents),\n ]);\n\n if (signal.aborted) {\n return agents;\n }\n\n // Result events: written by the agent, indexed by author. Build\n // (provider, jobEventId) pairs so we can cross-check `payment-completed`\n // feedback against an actual delivered result. Customers publish\n // `payment-completed` immediately on payment, before the result arrives -\n // an unmatched feedback means the provider never delivered (or never\n // existed at the time), so it must not count as a verified paid job.\n const deliveredJobsByProvider = new Map<string, Set<string>>();\n // jobEventId -> the customer pubkey the provider addressed the result to\n // (the result's `p` tag is `requestEvent.pubkey`, see submitJobResult). Used\n // to bind feedback/rating authorship to the job's actual customer below.\n const customerByJob = new Map<string, string>();\n for (const ev of resultEvents) {\n if (!verifyEvent(ev)) {\n continue;\n }\n const agent = agentMap.get(ev.pubkey);\n if (!agent) {\n continue;\n }\n if (ev.created_at > agent.lastSeen) {\n agent.lastSeen = ev.created_at;\n }\n const jobEventId = ev.tags.find((tag) => tag[0] === 'e')?.[1];\n if (jobEventId) {\n let delivered = deliveredJobsByProvider.get(ev.pubkey);\n if (!delivered) {\n delivered = new Set();\n deliveredJobsByProvider.set(ev.pubkey, delivered);\n }\n delivered.add(jobEventId);\n const customerPubkey = ev.tags.find((tag) => tag[0] === 'p')?.[1];\n if (customerPubkey) {\n customerByJob.set(jobEventId, customerPubkey);\n }\n }\n }\n\n // Feedback events: written by the *customer*, target agent in the `p` tag.\n // Tally rating counters and pick the newest `payment-completed` feedback\n // per agent as `lastPaidJobAt` / `lastPaidJobTx`. A feedback only counts\n // when (a) it references a job (`e` tag) that has a matching kind:6xxx\n // result from the provider, and (b) its author is the customer that result\n // was addressed to. This blocks unauthenticated third parties from inflating\n // ratings / minting paid-job timestamps. Provider-vs-sock-puppet collusion\n // still needs on-chain payment verification (roadmap).\n const countedRatings = new Set<string>();\n for (const ev of feedbackEvents) {\n if (!verifyEvent(ev)) {\n continue;\n }\n const targetPubkey = ev.tags.find((tag) => tag[0] === 'p')?.[1];\n if (!targetPubkey) {\n continue;\n }\n const agent = agentMap.get(targetPubkey);\n if (!agent) {\n continue;\n }\n if (ev.created_at > agent.lastSeen) {\n agent.lastSeen = ev.created_at;\n }\n\n const jobEventId = ev.tags.find((tag) => tag[0] === 'e')?.[1];\n const hasDeliveredResult =\n jobEventId !== undefined &&\n deliveredJobsByProvider.get(targetPubkey)?.has(jobEventId) === true;\n // Was this feedback authored by the job's actual customer?\n const jobCustomer = jobEventId !== undefined ? customerByJob.get(jobEventId) : undefined;\n const authoredByCustomer = jobCustomer !== undefined && ev.pubkey === jobCustomer;\n\n const rating = ev.tags.find((tag) => tag[0] === 'rating')?.[1];\n if ((rating === '1' || rating === '0') && hasDeliveredResult && authoredByCustomer) {\n // Dedupe: at most one rating per (customer, job).\n const ratingKey = `${ev.pubkey}:${jobEventId}`;\n if (!countedRatings.has(ratingKey)) {\n countedRatings.add(ratingKey);\n agent.totalRatingCount = (agent.totalRatingCount ?? 0) + 1;\n if (rating === '1') {\n agent.positiveCount = (agent.positiveCount ?? 0) + 1;\n }\n }\n }\n\n const status = ev.tags.find((tag) => tag[0] === 'status')?.[1];\n const txTag = ev.tags.find((tag) => tag[0] === 'tx');\n const txSignature = txTag?.[1];\n if (\n status === 'payment-completed' &&\n typeof txSignature === 'string' &&\n txSignature &&\n hasDeliveredResult &&\n authoredByCustomer\n ) {\n if (!agent.lastPaidJobAt || ev.created_at > agent.lastPaidJobAt) {\n agent.lastPaidJobAt = ev.created_at;\n agent.lastPaidJobTx = txSignature;\n }\n }\n }\n\n agents.sort(compareAgentsByRank);\n\n return agents;\n }\n\n /**\n * Stream elisym agents progressively as relays deliver events.\n *\n * Two live subscriptions:\n * - kind:31990 (capability cards) - emits `onAgent(agent)` for every new or\n * updated `(pubkey, d-tag)`. The emitted Agent is the merged view across\n * all surviving cards for that author.\n * - kind:6100 (default-offset job results) tagged `t=elisym` since 30d ago -\n * emits `onPaidJob(pubkey, ts)` for each delivered result. Custom-kind\n * results (offset != 100) are not on this stream; they enter the final\n * ranking via the post-EOSE enrichment pass.\n *\n * After capabilities EOSE, an enrichment pass runs in parallel to the live\n * subscriptions and produces a ranked snapshot via `onComplete`. The snapshot\n * is a clone, so further live updates do not mutate it.\n *\n * `closer.close()` tears down both subscriptions and aborts an in-flight\n * enrichment. If `opts.signal` is provided, aborting it does the same.\n */\n streamAgents(\n network: Network,\n opts: {\n onAgent: (agent: Agent) => void;\n onPaidJob?: (pubkey: string, ts: number) => void;\n onEose?: () => void;\n onComplete?: (agents: Agent[]) => void;\n signal?: AbortSignal;\n },\n ): SubCloser {\n const eventsByPubkey = new Map<string, Map<string, Event>>();\n const agentByPubkey = new Map<string, Agent>();\n const eoseSeen = { caps: false, results: false };\n let enrichmentStarted = false;\n const enrichmentAbort = new AbortController();\n\n const onExternalAbort = () => enrichmentAbort.abort();\n if (opts.signal) {\n if (opts.signal.aborted) {\n enrichmentAbort.abort();\n } else {\n opts.signal.addEventListener('abort', onExternalAbort, { once: true });\n }\n }\n\n const checkEose = () => {\n if (eoseSeen.caps && eoseSeen.results) {\n opts.onEose?.();\n }\n };\n\n const startEnrichment = () => {\n if (enrichmentStarted) {\n return;\n }\n enrichmentStarted = true;\n // Snapshot live agents so further `onAgent` updates do not race with\n // enrichment mutation.\n const snapshotAgents = Array.from(agentByPubkey.values()).map((agent) => ({ ...agent }));\n const snapshotMap = new Map(snapshotAgents.map((agent) => [agent.pubkey, agent]));\n void this.runEnrichment(snapshotAgents, snapshotMap, enrichmentAbort.signal).then(\n (sorted) => {\n if (enrichmentAbort.signal.aborted) {\n return;\n }\n opts.onComplete?.(sorted);\n },\n () => {\n /* enrichment errors are swallowed - stream stays usable until closed */\n },\n );\n };\n\n const capSub = this.pool.subscribe(\n { kinds: [KIND_APP_HANDLER], '#t': ['elisym'] },\n (event) => {\n const dTag = event.tags.find((tag) => tag[0] === 'd')?.[1] ?? '';\n let perDTag = eventsByPubkey.get(event.pubkey);\n const prev = perDTag?.get(dTag);\n if (prev && event.created_at <= prev.created_at) {\n return;\n }\n // Verify before trusting `event.pubkey`. An unsigned forged event with a\n // future `created_at` would otherwise displace a legitimate event from\n // the (pubkey, d-tag) slot.\n if (!verifyEvent(event)) {\n return;\n }\n\n // Distinguish tombstones (`{deleted: true}`) from invalid events.\n // `parseCapabilityEvent` returns null for both, but tombstones must be\n // stored in `perDTag` so the next `buildAgentsFromEvents` re-merge can\n // drop the corresponding card. Truthy check matches the validator in\n // `parseCapabilityEvent` (`if (candidate.deleted) return null`).\n if (!event.content) {\n return;\n }\n let payload: unknown;\n try {\n payload = JSON.parse(event.content);\n } catch {\n return;\n }\n const isTombstone =\n payload !== null &&\n typeof payload === 'object' &&\n Boolean((payload as { deleted?: unknown }).deleted);\n\n if (!isTombstone && !parseCapabilityEvent(event, network)) {\n return;\n }\n\n if (!perDTag) {\n perDTag = new Map();\n eventsByPubkey.set(event.pubkey, perDTag);\n }\n perDTag.set(dTag, event);\n\n const merged = buildAgentsFromEvents(Array.from(perDTag.values()), network).get(\n event.pubkey,\n );\n if (!merged) {\n // All cards for this author are now tombstoned. Drop the agent from\n // the snapshot so the post-EOSE enrichment pass excludes it. The\n // live UI will continue to show the agent until the next remount;\n // adding a removal callback is the proper fix.\n agentByPubkey.delete(event.pubkey);\n return;\n }\n agentByPubkey.set(event.pubkey, merged);\n opts.onAgent(merged);\n },\n {\n oneose: () => {\n eoseSeen.caps = true;\n startEnrichment();\n checkEose();\n },\n },\n );\n\n const activitySince = Math.floor(Date.now() / 1000) - RANKING_ACTIVITY_WINDOW_SECS;\n const resultsSub = this.pool.subscribe(\n { kinds: [KIND_JOB_RESULT], '#t': ['elisym'], since: activitySince },\n (event) => {\n // Verify signature before trusting `event.pubkey`. Without this, a\n // forged unsigned event would let an attacker bump any pubkey's\n // streaming `lastPaidJobAt` until enrichment overrides it. The\n // post-enrichment flush guards against bare-event spoofing once\n // `lastPaidJobTx` is set, but the pre-enrichment window would\n // otherwise be unprotected.\n if (!verifyEvent(event)) {\n return;\n }\n opts.onPaidJob?.(event.pubkey, event.created_at);\n },\n {\n oneose: () => {\n eoseSeen.results = true;\n checkEose();\n },\n },\n );\n\n return {\n close: (reason) => {\n capSub.close(reason);\n resultsSub.close(reason);\n enrichmentAbort.abort();\n opts.signal?.removeEventListener('abort', onExternalAbort);\n },\n };\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","/**\n * Job file-attachment descriptor and the job-payload envelope (browser-safe).\n *\n * A file job carries its file out-of-band (P2P via iroh); the Nostr event's\n * (NIP-44-encrypted) `content` carries only a small JSON envelope describing the\n * file and how to fetch it. This module owns the envelope shape, its encode, and\n * its strict decode. It deliberately does NOT construct an iroh `BlobTicket` - the\n * `ticket` is validated only as a bounded opaque string so that decoding an\n * untrusted, possibly pre-payment request never pulls in the native iroh addon.\n *\n * The transport is a discriminated union keyed on `kind`; Phase 1 ships only\n * `iroh`. A future HTTP/Blossom transport is added as another union member without\n * changing this contract.\n */\nimport { z } from 'zod';\nimport { LIMITS } from '../constants';\n\n/** Current envelope version. Bumped only on a breaking envelope-shape change. */\nexport const ENVELOPE_VERSION = 'elisym-job/1';\n\n/** Namespace prefix shared by all envelope versions, used to detect \"this is ours\". */\nconst ENVELOPE_NAMESPACE_PREFIX = 'elisym-job/';\n\n/** Upper bound on a serialized transport locator (e.g. an iroh BlobTicket string). */\nconst MAX_TICKET_LENGTH = 4096;\n\nconst FileTransportSchema = z.discriminatedUnion('kind', [\n z.object({\n kind: z.literal('iroh'),\n /** Opaque iroh `BlobTicket` string. Parsed into a real ticket only at fetch time. */\n ticket: z.string().min(1).max(MAX_TICKET_LENGTH),\n }),\n z.object({\n kind: z.literal('blossom'),\n /** Public HTTP(S) URL of the CIPHERTEXT blob on a Blossom relay. */\n url: z.string().url().max(2048),\n /** sha256 (lowercase hex) of the ciphertext - what the relay stores and addresses. */\n sha256: z.string().regex(/^[0-9a-f]{64}$/),\n /**\n * Hybrid-encryption parameters. The file bytes are AES-256-GCM encrypted with a random\n * content key; that key is NIP-44-wrapped to the recipient. `name`/`mime`/`size` on the\n * attachment describe the PLAINTEXT and live only inside the (encrypted) envelope - never\n * sent to the relay (the relay only ever sees opaque ciphertext).\n */\n enc: z.object({\n alg: z.literal('AES-256-GCM'),\n /** base64 12-byte GCM IV (non-secret). */\n iv: z.string().min(1).max(64),\n /** NIP-44-wrapped content key. */\n key: z.string().min(1).max(2048),\n }),\n }),\n]);\n\nconst FileAttachmentSchema = z.object({\n /** Display name only. Never used to derive a filesystem path (callers sanitize). */\n name: z.string().min(1).max(255),\n /** Declared size in bytes (display/hint only; enforcement is on actual streamed bytes). */\n size: z.number().int().nonnegative(),\n mime: z.string().min(1).max(255),\n /**\n * Ordered by sender preference; at least one KNOWN transport. Parsed leniently: unknown\n * transport `kind`s are dropped (not rejected) so adding a new transport never makes an older\n * decoder throw away the whole envelope - it just ignores the kinds it doesn't know and uses\n * the ones it does. At least one known transport must survive, else the attachment is invalid.\n */\n transports: z\n .array(z.unknown())\n .transform((arr): z.infer<typeof FileTransportSchema>[] =>\n arr.flatMap((t) => {\n const parsed = FileTransportSchema.safeParse(t);\n return parsed.success ? [parsed.data] : [];\n }),\n )\n .refine((arr) => arr.length >= 1, { message: 'attachment has no known transport' }),\n /** Optional provider hint (unix seconds) for when seeding may stop. */\n seedingExpiresAt: z.number().int().nonnegative().optional(),\n});\n\nconst JobPayloadEnvelopeSchema = z.object({\n v: z.literal(ENVELOPE_VERSION),\n text: z.string().optional(),\n // Legacy single attachment - kept (and mirrored from `attachments[0]`) so an old\n // decoder that doesn't know `attachments` still gets the first file.\n attachment: FileAttachmentSchema.optional(),\n // Multiple result/input files. Additive; old decoders strip this unknown key.\n attachments: z.array(FileAttachmentSchema).optional(),\n});\n\nexport type FileTransport = z.infer<typeof FileTransportSchema>;\nexport type FileAttachment = z.infer<typeof FileAttachmentSchema>;\nexport type JobPayloadEnvelope = z.infer<typeof JobPayloadEnvelopeSchema>;\n\n/** The kinds of file transport a job can use ('iroh' | 'blossom'). */\nexport type TransportKind = FileTransport['kind'];\n\n/** Public job-request tag advertising which transports a customer can RECEIVE output on. */\nexport const ACCEPT_TRANSPORTS_TAG = 'accept';\n\nconst KNOWN_TRANSPORT_KINDS: readonly TransportKind[] = ['iroh', 'blossom'];\n\nfunction isKnownTransportKind(value: string): value is TransportKind {\n return (KNOWN_TRANSPORT_KINDS as readonly string[]).includes(value);\n}\n\n/**\n * Build the `['accept', ...kinds]` job-request tag from a client's RECEIVE-capable transports.\n * Drops unknown kinds and dedupes, preserving the client's preference order.\n */\nexport function buildAcceptTransportsTag(kinds: TransportKind[]): string[] {\n const seen = new Set<string>();\n const out: string[] = [ACCEPT_TRANSPORTS_TAG];\n for (const kind of kinds) {\n if (isKnownTransportKind(kind) && !seen.has(kind)) {\n seen.add(kind);\n out.push(kind);\n }\n }\n return out;\n}\n\n/**\n * Read accepted transports from an event's tags. Returns the ordered, deduped, known kinds, or\n * `undefined` when there is no `accept` tag or it carries no known kind - both normalize to the\n * provider's default (seed all transports). Lenient: unknown kinds (from a newer client) are ignored\n * so this never strands a job.\n */\nexport function readAcceptedTransports(tags: string[][]): TransportKind[] | undefined {\n const tag = tags.find((t) => t[0] === ACCEPT_TRANSPORTS_TAG);\n if (tag === undefined) {\n return undefined;\n }\n const seen = new Set<string>();\n const out: TransportKind[] = [];\n for (const value of tag.slice(1)) {\n if (isKnownTransportKind(value) && !seen.has(value)) {\n seen.add(value);\n out.push(value);\n }\n }\n return out.length > 0 ? out : undefined;\n}\n\n/** Decoded job payload: a free-text note and/or file attachment(s). */\nexport interface DecodedJobPayload {\n text?: string;\n /** Legacy single attachment (also mirrors `attachments[0]`). */\n attachment?: FileAttachment;\n /** All attachments when a job carries multiple files. */\n attachments?: FileAttachment[];\n}\n\n/**\n * Normalize a decoded payload to the full attachment list, treating the legacy\n * single `attachment` as a 1-element list. Use this everywhere instead of reading\n * `.attachment`/`.attachments` directly, so single- and multi-file are uniform.\n */\nexport function attachmentsOf(decoded: DecodedJobPayload): FileAttachment[] {\n if (decoded.attachments !== undefined && decoded.attachments.length > 0) {\n return decoded.attachments;\n }\n return decoded.attachment !== undefined ? [decoded.attachment] : [];\n}\n\n/**\n * Serialize a job payload into the envelope string that goes (encrypted) into a\n * Nostr event's `content`. Used only when an attachment is present; plain-text\n * jobs send their text directly and are never wrapped.\n */\nexport function encodeJobPayload(payload: DecodedJobPayload): string {\n const envelope: JobPayloadEnvelope = { v: ENVELOPE_VERSION };\n if (payload.text !== undefined) {\n envelope.text = payload.text;\n }\n // Prefer the multi-attachment form and mirror the first into the legacy single\n // `attachment` (old decoders that ignore `attachments` still get one file).\n if (payload.attachments !== undefined && payload.attachments.length > 0) {\n envelope.attachments = payload.attachments;\n envelope.attachment = payload.attachments[0];\n } else if (payload.attachment !== undefined) {\n envelope.attachment = payload.attachment;\n }\n return JSON.stringify(envelope);\n}\n\n/**\n * Decode decrypted `content` into a job payload.\n *\n * - Content longer than `MAX_INPUT_LENGTH` is treated as raw text without parsing\n * (a valid envelope is small and a valid text job is capped at submit time), so\n * untrusted, possibly-huge intake content is never `JSON.parse`d unbounded.\n * - Non-JSON, non-object JSON, or a JSON object that does not carry our\n * `elisym-job/` version marker is returned as raw text.\n * - A value that DOES carry an `elisym-job/` marker is validated strictly: an\n * unknown version or a malformed envelope throws (callers skip/surface it)\n * rather than being silently mistreated as text.\n */\nexport function decodeJobPayload(content: string): DecodedJobPayload {\n if (content.length > LIMITS.MAX_INPUT_LENGTH) {\n return { text: content };\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(content);\n } catch {\n return { text: content };\n }\n\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n return { text: content };\n }\n\n const version = (parsed as { v?: unknown }).v;\n if (typeof version !== 'string' || !version.startsWith(ENVELOPE_NAMESPACE_PREFIX)) {\n return { text: content };\n }\n\n const result = JobPayloadEnvelopeSchema.safeParse(parsed);\n if (!result.success) {\n throw new Error(\n `Invalid elisym job payload (v=${JSON.stringify(version)}): ${result.error.message}`,\n );\n }\n\n return {\n text: result.data.text,\n attachment: result.data.attachment,\n attachments: result.data.attachments,\n };\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 utf8ByteLength,\n} from '../constants';\nimport { assertLamports } from '../payment/fee';\nimport { parsePaymentRequest } from '../payment/schema';\nimport { nip44Encrypt, nip44Decrypt } from '../primitives/crypto';\nimport type { ElisymIdentity } from '../primitives/identity';\nimport {\n encodeJobPayload,\n decodeJobPayload,\n attachmentsOf,\n buildAcceptTransportsTag,\n type FileAttachment,\n} from '../transport/attachment';\nimport type { NostrPool } from '../transport/pool';\nimport type {\n Job,\n JobStatus,\n PaymentAssetRef,\n SubCloser,\n SubmitJobOptions,\n JobSubscriptionOptions,\n} 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 const hasAttachment = options.attachment !== undefined;\n if (!options.input && !hasAttachment) {\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 // A file job wraps the (optional) text note + attachment in an envelope; a\n // plain-text job sends its text directly. The `i` tag is unchanged either way.\n const plaintext = hasAttachment\n ? encodeJobPayload({ text: options.input || undefined, attachment: options.attachment })\n : options.input;\n // NIP-44 backstop: the plaintext (post-envelope, the exact string handed to\n // nip44Encrypt) must fit the 65_535-byte cap or nip44Encrypt throws cryptically.\n // Large text should have been spilled to an attachment by the caller before here.\n if (options.providerPubkey) {\n const plaintextBytes = utf8ByteLength(plaintext);\n if (plaintextBytes > LIMITS.NIP44_MAX_PLAINTEXT_BYTES) {\n throw new Error(\n `Encrypted job input too large: ${plaintextBytes} bytes (max ${LIMITS.NIP44_MAX_PLAINTEXT_BYTES}). Send large input as a file/iroh attachment instead.`,\n );\n }\n }\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 if (options.acceptTransports && options.acceptTransports.length > 0) {\n // Advertise which transports this customer can RECEIVE output on. Public, signed tag; the\n // provider reads it to decide which transports to seed. Skip if no known kind survives.\n const acceptTag = buildAcceptTransportsTag(options.acceptTransports);\n if (acceptTag.length > 1) {\n tags.push(acceptTag);\n }\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 let decoded;\n try {\n decoded = decodeJobPayload(content);\n } catch {\n // Malformed/unknown-version envelope - skip like an undecryptable result\n // rather than crashing the subscription.\n return;\n }\n resultDelivered = true;\n try {\n // For a file result, surface the text note (or '') plus the attachment\n // descriptor(s); the file(s) are fetched separately, never inlined here.\n // 3rd arg stays the single attachment (= attachments[0]) for back-compat;\n // 4th arg is the full list for multi-file results.\n cb.onResult?.(decoded.text ?? '', ev.id, decoded.attachment, attachmentsOf(decoded));\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 // For targeted jobs (`provPk` set) an `error` feedback from\n // THE provider is terminal: surface the message via `onError`\n // and close the subscription so the customer doesn't sit\n // waiting until the global timeout. Broadcast jobs (no\n // `provPk`) intentionally keep the subscription open - a\n // single provider's rejection should not silence the others.\n if (provPk && statusTag[1] === 'error' && !resolved) {\n const errorMessage = ev.content?.trim() || 'Provider returned an error';\n done();\n try {\n cb.onError?.(errorMessage);\n } catch {\n /* caller error - don't crash subscription */\n }\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 // Prefer the structured `onTimeout` signal; fall back to the\n // legacy `onError` string so callers that predate `onTimeout`\n // (and the external agent `hire.ts` scripts) keep working.\n if (cb.onTimeout) {\n cb.onTimeout(timeoutMs);\n } else {\n cb.onError?.(`Timed out waiting for response (${timeoutMs / 1000}s).`);\n }\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 attachments?: FileAttachment[],\n ): Promise<string> {\n const hasAttachment = attachments !== undefined && attachments.length > 0;\n if (!content && !hasAttachment) {\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 // A file result wraps the (optional) text + attachment in an envelope so the\n // recovery/empty-content path always has non-empty content to deliver.\n const payload = hasAttachment\n ? encodeJobPayload({ text: content || undefined, attachments })\n : content;\n // NIP-44 backstop (same as submitJobRequest): the post-envelope payload must\n // fit the 65_535-byte cap. A large text result should have been spilled to a\n // text/plain attachment by the provider, leaving only the small ticket here.\n if (shouldEncrypt) {\n const payloadBytes = utf8ByteLength(payload);\n if (payloadBytes > LIMITS.NIP44_MAX_PLAINTEXT_BYTES) {\n throw new Error(\n `Encrypted job result too large: ${payloadBytes} bytes (max ${LIMITS.NIP44_MAX_PLAINTEXT_BYTES}). Deliver large results as a file/iroh attachment instead.`,\n );\n }\n }\n const resultContent = shouldEncrypt\n ? nip44Encrypt(payload, identity.secretKey, requestEvent.pubkey)\n : payload;\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 attachments?: FileAttachment[],\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, attachments);\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 let asset: PaymentAssetRef | 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 + payment asset (encoded inside the\n // payment-required feedback's amount tag as `[amount, raw, requestJson, chain]`).\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] && !txHash) {\n txHash = txTag[1];\n }\n if (!asset) {\n const amtTag = fb.tags.find((t) => t[0] === 'amount');\n const requestJson = amtTag?.[2];\n if (requestJson) {\n const parsed = parsePaymentRequest(requestJson);\n if (parsed.ok && parsed.data.asset) {\n asset = parsed.data.asset;\n }\n }\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 asset,\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","import { type Event, type Filter, finalizeEvent, nip19, verifyEvent } from 'nostr-tools';\nimport {\n KIND_LONG_FORM_ARTICLE,\n LIMITS,\n POLICY_D_TAG_PREFIX,\n POLICY_T_TAG,\n POLICY_TYPE_REGEX,\n} from '../constants';\nimport type { ElisymIdentity } from '../primitives/identity';\nimport type { NostrPool } from '../transport/pool';\nimport type { AgentPolicy, PolicyInput } from '../types';\n\nfunction dTagFor(type: string): string {\n return `${POLICY_D_TAG_PREFIX}${type}`;\n}\n\nfunction validatePolicyInput(input: PolicyInput): void {\n if (!POLICY_TYPE_REGEX.test(input.type)) {\n throw new Error(\n `Invalid policy type \"${input.type}\". Must be lowercase ASCII + hyphen, 1-${LIMITS.MAX_POLICY_TYPE_LENGTH} chars, no leading/trailing hyphen.`,\n );\n }\n if (input.version.length === 0 || input.version.length > LIMITS.MAX_POLICY_VERSION_LENGTH) {\n throw new Error(\n `Policy version must be 1-${LIMITS.MAX_POLICY_VERSION_LENGTH} chars (got ${input.version.length}).`,\n );\n }\n if (input.title.length === 0 || input.title.length > LIMITS.MAX_POLICY_TITLE_LENGTH) {\n throw new Error(\n `Policy title must be 1-${LIMITS.MAX_POLICY_TITLE_LENGTH} chars (got ${input.title.length}).`,\n );\n }\n if (input.summary !== undefined && input.summary.length > LIMITS.MAX_POLICY_SUMMARY_LENGTH) {\n throw new Error(\n `Policy summary too long: ${input.summary.length} chars (max ${LIMITS.MAX_POLICY_SUMMARY_LENGTH}).`,\n );\n }\n if (input.content.length === 0) {\n throw new Error('Policy content cannot be empty.');\n }\n if (input.content.length > LIMITS.MAX_POLICY_CONTENT_LENGTH) {\n throw new Error(\n `Policy content too long: ${input.content.length} chars (max ${LIMITS.MAX_POLICY_CONTENT_LENGTH}).`,\n );\n }\n}\n\nfunction parsePolicyEvent(event: Event): AgentPolicy | null {\n if (!verifyEvent(event)) {\n return null;\n }\n if (event.kind !== KIND_LONG_FORM_ARTICLE) {\n return null;\n }\n if (!event.content || event.content.length > LIMITS.MAX_POLICY_CONTENT_LENGTH) {\n return null;\n }\n\n const dTag = event.tags.find((tag) => tag[0] === 'd')?.[1];\n if (!dTag || !dTag.startsWith(POLICY_D_TAG_PREFIX)) {\n return null;\n }\n\n const type = event.tags.find((tag) => tag[0] === 'policy_type')?.[1];\n if (!type || !POLICY_TYPE_REGEX.test(type)) {\n return null;\n }\n\n const version = event.tags.find((tag) => tag[0] === 'policy_version')?.[1];\n if (!version || version.length > LIMITS.MAX_POLICY_VERSION_LENGTH) {\n return null;\n }\n\n const title = event.tags.find((tag) => tag[0] === 'title')?.[1];\n if (!title || title.length > LIMITS.MAX_POLICY_TITLE_LENGTH) {\n return null;\n }\n\n const summaryTag = event.tags.find((tag) => tag[0] === 'summary')?.[1];\n const summary =\n summaryTag !== undefined && summaryTag.length <= LIMITS.MAX_POLICY_SUMMARY_LENGTH\n ? summaryTag\n : undefined;\n\n const naddr = nip19.naddrEncode({\n kind: KIND_LONG_FORM_ARTICLE,\n pubkey: event.pubkey,\n identifier: dTag,\n relays: [],\n });\n\n return {\n type,\n version,\n title,\n summary,\n content: event.content,\n naddr,\n dTag,\n publishedAt: event.created_at,\n eventId: event.id,\n authorPubkey: event.pubkey,\n };\n}\n\nexport class PoliciesService {\n constructor(private pool: NostrPool) {}\n\n /**\n * Fetch all elisym policies published by `pubkey`. Verifies signatures,\n * dedupes by d-tag (latest `created_at` wins), and returns sorted by `type`\n * for deterministic UI rendering.\n *\n * Returns `[]` on empty result. Network errors propagate to the caller.\n */\n async fetchPolicies(pubkey: string): Promise<AgentPolicy[]> {\n const filter: Filter = {\n kinds: [KIND_LONG_FORM_ARTICLE],\n authors: [pubkey],\n '#t': [POLICY_T_TAG],\n };\n const events = await this.pool.querySync(filter);\n\n const latestByDTag = new Map<string, Event>();\n for (const event of events) {\n const dTag = event.tags.find((tag) => tag[0] === 'd')?.[1] ?? '';\n const prev = latestByDTag.get(dTag);\n if (!prev || event.created_at > prev.created_at) {\n latestByDTag.set(dTag, event);\n }\n }\n\n const policies: AgentPolicy[] = [];\n for (const event of latestByDTag.values()) {\n const parsed = parsePolicyEvent(event);\n if (parsed) {\n policies.push(parsed);\n }\n }\n policies.sort((a, b) => a.type.localeCompare(b.type));\n return policies;\n }\n\n /**\n * Publish a policy as a NIP-23 long-form article (kind 30023). Replaces any\n * existing policy of the same `type` for this pubkey via the addressable\n * `(kind, pubkey, d-tag)` slot.\n */\n async publishPolicy(\n identity: ElisymIdentity,\n input: PolicyInput,\n ): Promise<{ eventId: string; naddr: string }> {\n validatePolicyInput(input);\n\n const dTag = dTagFor(input.type);\n const tags: string[][] = [\n ['d', dTag],\n ['t', POLICY_T_TAG],\n ['title', input.title],\n ['policy_type', input.type],\n ['policy_version', input.version],\n ];\n if (input.summary) {\n tags.push(['summary', input.summary]);\n }\n\n const event = finalizeEvent(\n {\n kind: KIND_LONG_FORM_ARTICLE,\n created_at: Math.floor(Date.now() / 1000),\n tags,\n content: input.content,\n },\n identity.secretKey,\n );\n\n await this.pool.publishAll(event);\n\n const naddr = nip19.naddrEncode({\n kind: KIND_LONG_FORM_ARTICLE,\n pubkey: event.pubkey,\n identifier: dTag,\n relays: [],\n });\n\n return { eventId: event.id, naddr };\n }\n\n /**\n * Tombstone a policy by publishing an empty replacement under the same\n * `(kind, pubkey, d-tag)` slot. Readers skip events with empty content.\n */\n async deletePolicy(identity: ElisymIdentity, type: string): Promise<string> {\n if (!POLICY_TYPE_REGEX.test(type)) {\n throw new Error(`Invalid policy type \"${type}\".`);\n }\n const dTag = dTagFor(type);\n const event = finalizeEvent(\n {\n kind: KIND_LONG_FORM_ARTICLE,\n created_at: Math.floor(Date.now() / 1000),\n tags: [\n ['d', dTag],\n ['t', POLICY_T_TAG],\n ['policy_type', type],\n ],\n content: '',\n },\n identity.secretKey,\n );\n await this.pool.publishAll(event);\n return event.id;\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(\n filter: Filter,\n onEvent: (event: Event) => void,\n opts?: { oneose?: () => void },\n ): SubCloser {\n const rawSub = this.pool.subscribeMany(this.relays, filter, {\n onevent: onEvent,\n oneose: opts?.oneose,\n });\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 { BlossomService } from './services/blossom';\nimport { DiscoveryService } from './services/discovery';\nimport { MarketplaceService } from './services/marketplace';\nimport { MediaService } from './services/media';\nimport { PingService } from './services/ping';\nimport { PoliciesService } from './services/policies';\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 /** Custom Blossom server base URL for blob uploads (defaults to files.elisym.network). */\n blossomUrl?: 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 blossom: BlossomService;\n readonly policies: PoliciesService;\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.blossom = new BlossomService(config.blossomUrl, (identity, file) =>\n this.media.upload(identity, file),\n );\n this.policies = new PoliciesService(this.pool);\n this.payment = config.payment ?? new SolanaPaymentStrategy();\n }\n\n close(): void {\n this.pool.close();\n }\n}\n","/**\n * Hybrid file encryption for the Blossom transport (browser-safe).\n *\n * NIP-44 is text-only and capped at ~64 KB, so it cannot encrypt a file directly. Instead this uses\n * the standard hybrid scheme: a fresh random AES-256-GCM content key encrypts the file bytes, and that\n * small key is NIP-44-wrapped to the recipient's pubkey. The recipient unwraps the key (with their\n * secret key + the sender's pubkey) and decrypts the bytes.\n *\n * WebCrypto only (`crypto.subtle` + `crypto.getRandomValues`) - NO `node:crypto`, NO `Buffer` - so it\n * runs in the browser. The IV is non-secret and travels in the transport descriptor (`enc.iv`).\n */\nimport { nip44Decrypt, nip44Encrypt } from './crypto';\n\nconst KEY_BYTES = 32; // AES-256\nconst IV_BYTES = 12; // GCM standard nonce length\n\n// base64 helpers (browser-safe via btoa/atob). Only ever applied to the tiny content key (32 B) and\n// IV (12 B) - never to the file bytes, which are uploaded raw - so the per-char loop cost is trivial.\nfunction bytesToBase64(bytes: Uint8Array): string {\n let bin = '';\n for (const b of bytes) {\n bin += String.fromCharCode(b);\n }\n return btoa(bin);\n}\n\nfunction base64ToBytes(b64: string): Uint8Array {\n const bin = atob(b64);\n const out = new Uint8Array(bin.length);\n for (let i = 0; i < bin.length; i += 1) {\n out[i] = bin.charCodeAt(i);\n }\n return out;\n}\n\nexport interface EncryptedBytes {\n /** AES-256-GCM ciphertext with the 16-byte auth tag appended (WebCrypto layout). */\n ciphertext: Uint8Array;\n /** NIP-44-wrapped content key (sender secret key -> recipient pubkey). */\n wrappedKey: string;\n /** base64 GCM IV (non-secret). */\n iv: string;\n}\n\n/** Encrypt `bytes` so that only `recipientPubkey` (with the sender's pubkey) can decrypt. */\nexport async function encryptBytesForRecipient(\n bytes: Uint8Array,\n senderSk: Uint8Array,\n recipientPubkey: string,\n): Promise<EncryptedBytes> {\n const rawKey = crypto.getRandomValues(new Uint8Array(KEY_BYTES));\n const iv = crypto.getRandomValues(new Uint8Array(IV_BYTES));\n const key = await crypto.subtle.importKey('raw', rawKey, 'AES-GCM', false, ['encrypt']);\n const ct = await crypto.subtle.encrypt({ name: 'AES-GCM', iv, tagLength: 128 }, key, bytes);\n const wrappedKey = nip44Encrypt(bytesToBase64(rawKey), senderSk, recipientPubkey);\n return { ciphertext: new Uint8Array(ct), wrappedKey, iv: bytesToBase64(iv) };\n}\n\n/**\n * Decrypt bytes produced by `encryptBytesForRecipient`. Throws on any tamper (GCM auth tag), a\n * corrupted/forged wrapped key (NIP-44 MAC), or the wrong receiver/sender key pair.\n */\nexport async function decryptBytesFromSender(\n ciphertext: Uint8Array,\n wrappedKey: string,\n iv: string,\n receiverSk: Uint8Array,\n senderPubkey: string,\n): Promise<Uint8Array> {\n const rawKey = base64ToBytes(nip44Decrypt(wrappedKey, receiverSk, senderPubkey));\n const key = await crypto.subtle.importKey('raw', rawKey, 'AES-GCM', false, ['decrypt']);\n const pt = await crypto.subtle.decrypt(\n { name: 'AES-GCM', iv: base64ToBytes(iv), tagLength: 128 },\n key,\n ciphertext,\n );\n return new Uint8Array(pt);\n}\n","/**\n * Encrypted Blossom blob transport - the browser-safe peer to the (Node-only) iroh transport.\n *\n * Seeds a file by encrypting it to a recipient (hybrid AES-256-GCM + NIP-44 key-wrap) and uploading\n * the ciphertext to a Blossom relay; fetches by downloading the ciphertext (bounded + sha256-verified)\n * and decrypting it. The local party's `identity` is both the BUD-11 upload signer AND the\n * encryption sender/receiver; the counterparty pubkey is passed per call.\n */\nimport { LIMITS } from '../constants';\nimport { decryptBytesFromSender, encryptBytesForRecipient } from '../primitives/file-crypto';\nimport type { ElisymIdentity } from '../primitives/identity';\nimport type { BlossomService } from '../services/blossom';\nimport type { FileTransport } from './attachment';\n\ntype BlossomTransport = Extract<FileTransport, { kind: 'blossom' }>;\n\n// AES-256-GCM appends a 16-byte auth tag, so the uploaded ciphertext is exactly 16 bytes larger than\n// the plaintext. The size caps are expressed in PLAINTEXT bytes (the seed side gates on plaintext\n// length), so the ciphertext-download bound is widened by the tag - otherwise a file at exactly the\n// cap seeds fine but its (cap + 16) ciphertext trips the streamed-bytes guard and can't be fetched.\nconst AES_GCM_TAG_BYTES = 16;\n\nexport interface BlossomBlobTransport {\n /** Encrypt `bytes` to `recipientPubkey`, upload the ciphertext, return a `blossom` transport member. */\n seedBytes(args: { bytes: Uint8Array; recipientPubkey: string }): Promise<BlossomTransport>;\n /** Download the ciphertext (bounded + sha256-verified) and decrypt it (sent by `senderPubkey`). */\n fetchToBytes(args: {\n transport: BlossomTransport;\n senderPubkey: string;\n maxBytes?: number;\n }): Promise<Uint8Array>;\n}\n\nexport function createBlossomTransport(opts: {\n blossom: BlossomService;\n identity: ElisymIdentity;\n}): BlossomBlobTransport {\n const { blossom, identity } = opts;\n return {\n async seedBytes({ bytes, recipientPubkey }) {\n if (bytes.byteLength > LIMITS.MAX_BLOSSOM_ENCRYPTED_BYTES) {\n throw new Error(\n `File too large for encrypted Blossom: ${bytes.byteLength} bytes exceeds ${LIMITS.MAX_BLOSSOM_ENCRYPTED_BYTES}.`,\n );\n }\n const { ciphertext, wrappedKey, iv } = await encryptBytesForRecipient(\n bytes,\n identity.secretKey,\n recipientPubkey,\n );\n // Upload the ciphertext as opaque octet-stream - the plaintext mime never reaches the relay.\n const blob = new Blob([ciphertext], { type: 'application/octet-stream' });\n const descriptor = await blossom.upload(identity, blob);\n if (descriptor.provider !== 'blossom') {\n // Fell back to nostr.build: its URL is not content-addressed by our ciphertext sha256, so the\n // fetch-time integrity check would fail. Refuse so the caller emits an iroh-only attachment.\n throw new Error('Blossom upload fell back to a non-content-addressed provider.');\n }\n return {\n kind: 'blossom',\n url: descriptor.url,\n sha256: descriptor.sha256,\n enc: { alg: 'AES-256-GCM', iv, key: wrappedKey },\n };\n },\n\n async fetchToBytes({ transport, senderPubkey, maxBytes }) {\n const plaintextCap = maxBytes ?? LIMITS.MAX_BLOSSOM_ENCRYPTED_BYTES;\n const ciphertext = await blossom.download(transport.url, {\n maxBytes: plaintextCap + AES_GCM_TAG_BYTES,\n expectedSha256: transport.sha256,\n });\n return decryptBytesFromSender(\n ciphertext,\n transport.enc.key,\n transport.enc.iv,\n identity.secretKey,\n senderPubkey,\n );\n },\n };\n}\n","/**\n * Customer-side helpers to send/receive ENCRYPTED file jobs over Blossom with no iroh/Node dependency\n * (browser-safe). These are the seams a web app calls.\n *\n * Encrypted-Blossom needs a recipient pubkey, so a file INPUT is only meaningful on a TARGETED job (a\n * chosen provider) - hence `buildEncryptedFileInput` requires `providerPubkey`. Broadcast file inputs\n * are not supported here (no recipient to encrypt to); those stay on iroh.\n */\nimport { LIMITS } from '../constants';\nimport { encryptBytesForRecipient } from '../primitives/file-crypto';\nimport type { ElisymIdentity } from '../primitives/identity';\nimport type { BlossomService } from '../services/blossom';\nimport type { FileAttachment, FileTransport } from './attachment';\nimport { createBlossomTransport } from './blossom-transport';\n\n/** Hex SHA-256 of bytes (WebCrypto; matches what the Blossom server computes). */\nasync function sha256Hex(bytes: Uint8Array): Promise<string> {\n const digest = await crypto.subtle.digest('SHA-256', bytes);\n return [...new Uint8Array(digest)].map((b) => b.toString(16).padStart(2, '0')).join('');\n}\n\n// Best-effort, UX-only refusal of obviously-executable inputs. NOT a security control - once the bytes\n// are ciphertext the relay cannot enforce anything; this just helps users avoid an obvious mistake.\nconst EXECUTABLE_EXTENSIONS = new Set([\n '.exe',\n '.dll',\n '.bat',\n '.cmd',\n '.com',\n '.msi',\n '.sh',\n '.app',\n '.scr',\n '.ps1',\n]);\nconst EXECUTABLE_MIMES = new Set([\n 'application/x-msdownload',\n 'application/x-msdos-program',\n 'application/x-sh',\n 'application/x-executable',\n 'application/vnd.microsoft.portable-executable',\n 'application/x-mach-binary',\n]);\n\nfunction looksExecutable(name: string, type: string): boolean {\n const dot = name.lastIndexOf('.');\n const ext = dot >= 0 ? name.slice(dot).toLowerCase() : '';\n return EXECUTABLE_EXTENSIONS.has(ext) || EXECUTABLE_MIMES.has(type);\n}\n\n/**\n * Encrypt `file` to `providerPubkey` and build a complete `FileAttachment` WITHOUT uploading the bytes\n * yet. Because Blossom is content-addressed, the blob URL is derivable from the ciphertext sha256, so the\n * caller can submit the job request with this descriptor and DEFER the byte upload (via the returned\n * `upload()`) until the customer commits - e.g. after the provider quotes a price, so an unresponsive\n * provider never costs a wasted upload. TARGETED jobs only (a recipient pubkey is required to encrypt).\n *\n * `upload()` PUTs the ciphertext and verifies the server returns the precomputed url/sha256 (the request\n * already carries them, so a mismatch must fail loudly - pre-commit - rather than 404 the provider).\n */\nexport async function prepareEncryptedFileInput(args: {\n file: Blob & { name?: string };\n providerPubkey: string;\n identity: ElisymIdentity;\n blossom: BlossomService;\n}): Promise<{ attachment: FileAttachment; upload: () => Promise<void> }> {\n const { file, providerPubkey, identity, blossom } = args;\n const name = file.name ?? 'upload';\n if (looksExecutable(name, file.type)) {\n throw new Error('Refusing to upload an executable file.');\n }\n const bytes = new Uint8Array(await file.arrayBuffer());\n if (bytes.byteLength > LIMITS.MAX_BLOSSOM_ENCRYPTED_BYTES) {\n throw new Error(\n `File too large for the encrypted-Blossom transport: ${bytes.byteLength} bytes ` +\n `(max ${LIMITS.MAX_BLOSSOM_ENCRYPTED_BYTES}).`,\n );\n }\n const { ciphertext, wrappedKey, iv } = await encryptBytesForRecipient(\n bytes,\n identity.secretKey,\n providerPubkey,\n );\n const sha256 = await sha256Hex(ciphertext);\n const member: Extract<FileTransport, { kind: 'blossom' }> = {\n kind: 'blossom',\n url: blossom.contentUrl(sha256),\n sha256,\n enc: { alg: 'AES-256-GCM', iv, key: wrappedKey },\n };\n const attachment: FileAttachment = {\n name,\n size: bytes.byteLength,\n mime: file.type || 'application/octet-stream',\n transports: [member],\n };\n const upload = async (): Promise<void> => {\n const descriptor = await blossom.upload(\n identity,\n new Blob([ciphertext], { type: 'application/octet-stream' }),\n );\n if (descriptor.provider !== 'blossom') {\n throw new Error('Blossom upload fell back to a non-content-addressed provider.');\n }\n if (descriptor.sha256 !== sha256 || descriptor.url !== member.url) {\n throw new Error(\n `Blossom upload descriptor mismatch (expected ${member.url} / ${sha256}, ` +\n `got ${descriptor.url} / ${descriptor.sha256}).`,\n );\n }\n };\n return { attachment, upload };\n}\n\n/**\n * Encrypt `file` to `providerPubkey` AND upload it immediately, returning the `FileAttachment`\n * (prepare + upload in one step). Use `prepareEncryptedFileInput` when you want to defer the upload.\n */\nexport async function buildEncryptedFileInput(args: {\n file: Blob & { name?: string };\n providerPubkey: string;\n identity: ElisymIdentity;\n blossom: BlossomService;\n}): Promise<FileAttachment> {\n const prepared = await prepareEncryptedFileInput(args);\n await prepared.upload();\n return prepared.attachment;\n}\n\n/**\n * Download + decrypt a `blossom` file output from an attachment (sent by `providerPubkey`). Returns the\n * plaintext bytes plus the envelope-carried name/mime. Throws if there is no blossom transport.\n */\nexport async function fetchEncryptedFileOutput(args: {\n attachment: FileAttachment;\n providerPubkey: string;\n identity: ElisymIdentity;\n blossom: BlossomService;\n maxBytes?: number;\n}): Promise<{ bytes: Uint8Array; name: string; mime: string }> {\n const { attachment, providerPubkey, identity, blossom, maxBytes } = args;\n const member = attachment.transports.find(\n (t): t is Extract<FileTransport, { kind: 'blossom' }> => t.kind === 'blossom',\n );\n if (member === undefined) {\n throw new Error('Attachment has no blossom transport.');\n }\n const transport = createBlossomTransport({ blossom, identity });\n const bytes = await transport.fetchToBytes({\n transport: member,\n senderPubkey: providerPubkey,\n maxBytes,\n });\n return { bytes, name: attachment.name, mime: attachment.mime };\n}\n","/**\n * Customer-facing error feedback that arrives via `subscribeToJobUpdates`'s\n * `onError` callback can come from many places:\n *\n * - The runtime's stable `Agent temporarily unavailable` string when the\n * LLM health gate refuses a job (preflight) or an in-flight skill\n * surfaced a billing/invalid signal.\n * - The runtime's `Internal processing error` sanitization mask for any\n * \"<Provider> API error: ...\" string that leaks out of an LLM call.\n * - Raw script-skill failures the runtime forwards as-is when the\n * message does not contain \"API\" - e.g. shell scripts that reach\n * Anthropic's `count_tokens` endpoint and exit 1 with the body in\n * stderr instead of using the canonical exit-42 contract.\n * - Generic transport errors (timeouts, \"Provider returned an error\",\n * rate-limit refusals, payment errors).\n *\n * Customers don't care which path produced the error - they care whether\n * the agent is down (try later, payment recoverable) or something else\n * went wrong (their input, their wallet, etc). This classifier collapses\n * the first three categories into a single `agent-unavailable` kind so\n * the UI can render one stable message regardless of how the underlying\n * provider chose to surface the failure.\n *\n * Markers are kept as a permissive superset of every billing/auth phrase\n * the CLI and skill scripts are known to emit. Adding a new marker is\n * always safe; removing one risks classifying a real outage as `unknown`.\n */\n\nconst AGENT_UNAVAILABLE_MARKERS = [\n 'agent temporarily unavailable',\n 'internal processing error',\n 'invalid x-api-key',\n 'invalid api key',\n 'invalid_api_key',\n 'x-api-key',\n 'credit balance',\n 'billing',\n 'insufficient',\n 'insufficient_quota',\n 'authentication_error',\n 'unauthorized',\n 'unauthenticated',\n];\n\nexport type JobErrorKind = 'agent-unavailable' | 'unknown';\n\n/**\n * Classify a customer-facing error string surfaced via\n * `JobUpdateCallbacks.onError` into a stable kind the UI can branch on.\n *\n * Match is case-insensitive against the message text. Returns\n * `agent-unavailable` for any known billing/auth/invalid-key signal;\n * `unknown` for everything else (timeouts, validation errors, transport).\n */\nexport function classifyJobError(message: string): JobErrorKind {\n const lower = message.toLowerCase();\n for (const marker of AGENT_UNAVAILABLE_MARKERS) {\n if (lower.includes(marker)) {\n return 'agent-unavailable';\n }\n }\n return 'unknown';\n}\n\n/**\n * Signalled via `JobUpdateCallbacks.onTimeout` (and thrown by helpers that\n * await a result) when the wait window expires without a result. This is a\n * distinct, structured signal from a genuine provider/transport error, so\n * callers can branch on the type instead of substring-matching \"timed out\"\n * on a free-form error message (which masks real errors that happen to\n * mention a timeout).\n */\nexport class JobWaitTimeoutError extends Error {\n constructor(timeoutMs?: number) {\n super(\n timeoutMs === undefined\n ? 'Timed out waiting for job result'\n : `Timed out waiting for job result (${Math.round(timeoutMs / 1000)}s)`,\n );\n this.name = 'JobWaitTimeoutError';\n }\n}\n","/**\n * SOL-denominated fee estimator for payment requests.\n *\n * For a USDC payment the user still spends SOL to cover the base signature fee,\n * the priority fee, and (for first-time recipients) the ATA rent-exemption\n * deposit. Before calling `send_payment` the customer wants to know whether\n * their SOL balance is sufficient - that's what this helper answers.\n *\n * Browser-safe: no Node-specific imports. The web dashboard will use the same\n * function.\n */\n\nimport { TOKEN_PROGRAM_ADDRESS, findAssociatedTokenPda } from '@solana-program/token';\nimport { type Address, type Rpc, type SolanaRpcApi, address } from '@solana/kit';\nimport type { PaymentRequestData } from '../types';\nimport { resolveAssetFromPaymentRequest } from './assets';\nimport { estimatePriorityFeeMicroLamports } from './priorityFee';\n\n/**\n * Default compute-unit limit attached to payment transactions.\n *\n * Kept in sync with `DEFAULT_COMPUTE_UNIT_LIMIT` in solana.ts. Duplicating the\n * constant keeps the estimator browser-safe without pulling the build path.\n */\nconst DEFAULT_COMPUTE_UNIT_LIMIT = 200_000;\nconst DEFAULT_PRIORITY_FEE_PERCENTILE = 75;\n\n/** Base fee per signature (lamports). See `SystemProgram::get_fee_payer`. */\nconst BASE_FEE_LAMPORTS_PER_SIGNATURE = 5_000n;\n\n/**\n * Rent-exemption minimum for a 165-byte SPL Token account, as of Solana 1.18+.\n *\n * Used as a fallback when `getMinimumBalanceForRentExemption` is unavailable.\n * The real on-chain value is ~2039280 lamports (= 0.00203928 SOL).\n */\nconst FALLBACK_ATA_RENT_LAMPORTS = 2_039_280n;\n\n/** SPL Token account size in bytes. */\nconst SPL_TOKEN_ACCOUNT_SIZE = 165;\n\nexport interface SolFeeEstimate {\n /** Base per-signature fee. Currently 5000 lamports * 1 signature. */\n baseFeeLamports: bigint;\n /**\n * Priority fee in lamports: `ceil(priorityFeeMicroLamports * computeUnitLimit\n * / 1_000_000)`. Rounded up so we don't underestimate.\n */\n priorityFeeLamports: bigint;\n /**\n * Rent-exemption deposit for ATAs that the tx creates.\n *\n * 0 for native SOL. For SPL, `rentPerAta * (# of missing ATAs)`: recipient\n * ATA is missing iff the recipient has never received this token; treasury\n * ATA is missing only on the first-ever protocol fee into this mint.\n */\n rentLamports: bigint;\n /** `baseFeeLamports + priorityFeeLamports + rentLamports`. */\n totalLamports: bigint;\n breakdown: {\n numSignatures: number;\n priorityFeeMicroLamports: bigint;\n computeUnitLimit: number;\n rentPerAtaLamports: bigint;\n missingAtaCount: number;\n };\n}\n\nexport interface EstimateSolFeeOptions {\n /** Override the compute-unit limit used by `buildTransaction`. */\n computeUnitLimit?: number;\n /** Override the priority fee directly (skips RPC). */\n priorityFeeMicroLamports?: bigint;\n /**\n * Percentile of the recent priority-fee distribution to charge when\n * `priorityFeeMicroLamports` is not supplied. Defaults to 75.\n */\n priorityFeePercentile?: number;\n /** Override the number of signatures. Defaults to 1. */\n numSignatures?: number;\n}\n\n/**\n * Estimate the SOL cost (in lamports) to submit the transaction that would pay\n * this payment request from `payerAddress`.\n *\n * Returns a breakdown and a total. Does not submit anything on-chain.\n */\nexport async function estimateSolFeeLamports(\n rpc: Rpc<SolanaRpcApi>,\n paymentRequest: PaymentRequestData,\n _payerAddress: string,\n options?: EstimateSolFeeOptions,\n): Promise<SolFeeEstimate> {\n const numSignatures = options?.numSignatures ?? 1;\n const computeUnitLimit = options?.computeUnitLimit ?? DEFAULT_COMPUTE_UNIT_LIMIT;\n const priorityFeeMicroLamports =\n options?.priorityFeeMicroLamports ??\n (await estimatePriorityFeeMicroLamports(rpc, {\n percentile: options?.priorityFeePercentile ?? DEFAULT_PRIORITY_FEE_PERCENTILE,\n }));\n\n const baseFeeLamports = BASE_FEE_LAMPORTS_PER_SIGNATURE * BigInt(numSignatures);\n const priorityFeeLamports = ceilDiv(\n priorityFeeMicroLamports * BigInt(computeUnitLimit),\n 1_000_000n,\n );\n\n const asset = resolveAssetFromPaymentRequest(paymentRequest);\n let rentLamports = 0n;\n let rentPerAtaLamports = 0n;\n let missingAtaCount = 0;\n\n if (asset.mint) {\n rentPerAtaLamports = await fetchAtaRent(rpc);\n const mint = address(asset.mint);\n\n const ataAccountsToCheck: Address[] = [];\n const [recipientAta] = await findAssociatedTokenPda({\n owner: address(paymentRequest.recipient),\n tokenProgram: TOKEN_PROGRAM_ADDRESS,\n mint,\n });\n ataAccountsToCheck.push(recipientAta);\n\n const feeAmount = paymentRequest.fee_amount ?? 0;\n if (paymentRequest.fee_address && feeAmount > 0) {\n const [treasuryAta] = await findAssociatedTokenPda({\n owner: address(paymentRequest.fee_address),\n tokenProgram: TOKEN_PROGRAM_ADDRESS,\n mint,\n });\n ataAccountsToCheck.push(treasuryAta);\n }\n\n missingAtaCount = await countMissingAccounts(rpc, ataAccountsToCheck);\n rentLamports = rentPerAtaLamports * BigInt(missingAtaCount);\n }\n\n const totalLamports = baseFeeLamports + priorityFeeLamports + rentLamports;\n return {\n baseFeeLamports,\n priorityFeeLamports,\n rentLamports,\n totalLamports,\n breakdown: {\n numSignatures,\n priorityFeeMicroLamports,\n computeUnitLimit,\n rentPerAtaLamports,\n missingAtaCount,\n },\n };\n}\n\nasync function fetchAtaRent(rpc: Rpc<SolanaRpcApi>): Promise<bigint> {\n try {\n const lamports = await rpc\n .getMinimumBalanceForRentExemption(BigInt(SPL_TOKEN_ACCOUNT_SIZE))\n .send();\n if (typeof lamports === 'bigint') {\n return lamports;\n }\n if (typeof lamports === 'number' && Number.isFinite(lamports) && lamports > 0) {\n return BigInt(lamports);\n }\n return FALLBACK_ATA_RENT_LAMPORTS;\n } catch {\n return FALLBACK_ATA_RENT_LAMPORTS;\n }\n}\n\nasync function countMissingAccounts(rpc: Rpc<SolanaRpcApi>, accounts: Address[]): Promise<number> {\n if (accounts.length === 0) {\n return 0;\n }\n let missing = 0;\n for (const acct of accounts) {\n try {\n const res = await rpc.getAccountInfo(acct, { encoding: 'base64' }).send();\n if (!res || !res.value) {\n missing++;\n }\n } catch {\n // If we can't tell, assume the ATA must be created - safer to\n // overestimate the cost than to surprise the payer.\n missing++;\n }\n }\n return missing;\n}\n\nfunction ceilDiv(num: bigint, denom: bigint): bigint {\n if (denom === 0n) {\n throw new Error('division by zero in ceilDiv');\n }\n const q = num / denom;\n const r = num % denom;\n return r === 0n ? q : q + 1n;\n}\n\n/**\n * Multi-line human-readable breakdown. Used by the MCP `estimate_payment_cost`\n * tool and (in a future PR) by the web dashboard's pre-payment panel.\n *\n * We render lamports as raw integers and also show a SOL decimal with 9 places.\n * The `@elisym/sdk` `formatAssetAmount` helper lives in assets.ts, but the\n * formatter does not need to be identical; this stays dependency-free.\n */\nexport function formatFeeBreakdown(estimate: SolFeeEstimate): string {\n const line = (label: string, lamports: bigint): string => {\n const label16 = label.padEnd(14);\n return ` ${label16}${lamports.toString()} lamports (${lamportsToSol(lamports)} SOL)`;\n };\n const lines = [\n 'Estimated SOL cost for this transaction:',\n line('Base fee:', estimate.baseFeeLamports),\n line('Priority fee:', estimate.priorityFeeLamports),\n ];\n if (estimate.rentLamports > 0n) {\n lines.push(line('ATA rent:', estimate.rentLamports));\n }\n lines.push(line('Total:', estimate.totalLamports));\n return lines.join('\\n');\n}\n\nfunction lamportsToSol(lamports: bigint): string {\n const LAMPORTS_PER_SOL = 1_000_000_000n;\n const whole = lamports / LAMPORTS_PER_SOL;\n const frac = lamports % LAMPORTS_PER_SOL;\n return `${whole}.${frac.toString().padStart(9, '0')}`;\n}\n\nexport interface NetworkBaselineEstimate {\n baseFeeLamports: bigint;\n priorityFeeMicroLamports: bigint;\n computeUnitLimit: number;\n priorityFeeLamports: bigint;\n /** Present only when `includeAtaRent: true`. */\n ataRentLamports?: bigint;\n /** baseFeeLamports + priorityFeeLamports + (ataRentLamports ?? 0n). */\n totalLamports: bigint;\n}\n\nexport interface NetworkBaselineOptions {\n /** Add one ATA rent-exemption deposit to the total (USDC first-time payer). */\n includeAtaRent?: boolean;\n /** Override the priority-fee percentile (default 75). */\n priorityFeePercentile?: number;\n /** Override the compute-unit limit (default 200_000). */\n computeUnitLimit?: number;\n /** Override priority fee directly, skipping the RPC call. */\n priorityFeeMicroLamports?: bigint;\n}\n\n/**\n * Estimate the SOL cost of a typical payment transaction on the current\n * cluster, without needing a concrete `payment_request`. Used by MCP\n * confirmation messages (e.g. `buy_capability` price gate) to surface\n * gas before the provider has issued a payment-required feedback.\n *\n * Reuses the priority-fee cache in `estimatePriorityFeeMicroLamports`\n * (TTL 10s) so consecutive confirmations don't double-hit the RPC.\n */\nexport async function estimateNetworkBaseline(\n rpc: Rpc<SolanaRpcApi>,\n options?: NetworkBaselineOptions,\n): Promise<NetworkBaselineEstimate> {\n const computeUnitLimit = options?.computeUnitLimit ?? DEFAULT_COMPUTE_UNIT_LIMIT;\n const priorityFeeMicroLamports =\n options?.priorityFeeMicroLamports ??\n (await estimatePriorityFeeMicroLamports(rpc, {\n percentile: options?.priorityFeePercentile ?? DEFAULT_PRIORITY_FEE_PERCENTILE,\n }));\n const baseFeeLamports = BASE_FEE_LAMPORTS_PER_SIGNATURE;\n const priorityFeeLamports = ceilDiv(\n priorityFeeMicroLamports * BigInt(computeUnitLimit),\n 1_000_000n,\n );\n const ataRentLamports = options?.includeAtaRent ? await fetchAtaRent(rpc) : undefined;\n const totalLamports = baseFeeLamports + priorityFeeLamports + (ataRentLamports ?? 0n);\n return {\n baseFeeLamports,\n priorityFeeMicroLamports,\n computeUnitLimit,\n priorityFeeLamports,\n ataRentLamports,\n totalLamports,\n };\n}\n\n/**\n * Single-line summary of a network baseline estimate, suitable for embedding\n * inside MCP confirmation strings.\n */\nexport function formatNetworkBaseline(estimate: NetworkBaselineEstimate): string {\n const total = lamportsToSol(estimate.totalLamports);\n const base = lamportsToSol(estimate.baseFeeLamports);\n const priority = lamportsToSol(estimate.priorityFeeLamports);\n const parts = [`base ${base}`, `priority ${priority}`];\n if (estimate.ataRentLamports !== undefined) {\n parts.push(`ATA rent ${lamportsToSol(estimate.ataRentLamports)}`);\n }\n return `Estimated network gas: ${total} SOL (${parts.join(' + ')}).`;\n}\n","import { type Address, type Rpc, type Signature, type SolanaRpcApi, isAddress } from '@solana/kit';\n\n/**\n * Lightweight payment verifier used by discovery ranking.\n *\n * Unlike `SolanaPaymentStrategy.verifyPayment`, this is a single-shot check\n * with no retries: discovery cannot afford the 30-second confirmation budget\n * the customer-side verifier uses. If the RPC has not seen the transaction\n * yet, we treat the agent as \"no verified paid job\" rather than blocking.\n *\n * Positive results are cached forever (Solana txs are immutable once\n * confirmed). Negative results expire after `NEGATIVE_CACHE_TTL_MS` so a\n * just-confirmed tx will be picked up on the next discovery refresh.\n */\n\nexport type QuickVerifyReason =\n | 'not_found'\n | 'tx_failed'\n | 'recipient_mismatch'\n | 'rpc_error'\n | 'invalid_input';\n\nexport interface QuickVerifyResult {\n /**\n * True when the recipient address received funds in this transaction.\n *\n * NOTE: this is NOT proof of a valid elisym job payment. It does not check\n * the payment `reference` key or that the amount matches the job price - it\n * is a best-effort signal for the fast discovery-ranking path, where the\n * original payment request is unavailable. For an authoritative check\n * (amount + reference) use `SolanaPaymentStrategy.verifyPayment`.\n */\n receivedFunds: boolean;\n txSignature: string;\n reason?: QuickVerifyReason;\n}\n\ninterface VerifyCacheEntry {\n result: QuickVerifyResult;\n cachedAt: number;\n}\n\nconst NEGATIVE_CACHE_TTL_MS = 60_000;\n// Cap so a long-running process cannot grow the cache without bound (#44).\nconst MAX_CACHE_ENTRIES = 5_000;\n\nconst verifyCache = new Map<string, VerifyCacheEntry>();\n\nexport function clearQuickVerifyCache(): void {\n verifyCache.clear();\n}\n\nexport async function verifyJobPaymentQuick(\n rpc: Rpc<SolanaRpcApi>,\n txSignature: string,\n expectedRecipient: Address,\n): Promise<QuickVerifyResult> {\n if (!txSignature) {\n return { receivedFunds: false, txSignature: '', reason: 'invalid_input' };\n }\n if (!expectedRecipient || !isAddress(expectedRecipient as string)) {\n return { receivedFunds: false, txSignature, reason: 'invalid_input' };\n }\n\n const cacheKey = `${txSignature}:${expectedRecipient}`;\n const cached = verifyCache.get(cacheKey);\n if (cached) {\n if (cached.result.receivedFunds) {\n return cached.result;\n }\n if (Date.now() - cached.cachedAt < NEGATIVE_CACHE_TTL_MS) {\n return cached.result;\n }\n // Expired negative result - drop it so re-verification can refresh.\n verifyCache.delete(cacheKey);\n }\n\n const result = await doVerifyOnce(rpc, txSignature as Signature, expectedRecipient);\n // Map preserves insertion order, so evicting the first key is LRU-ish.\n if (verifyCache.size >= MAX_CACHE_ENTRIES) {\n const oldest = verifyCache.keys().next().value;\n if (oldest !== undefined) {\n verifyCache.delete(oldest);\n }\n }\n verifyCache.set(cacheKey, { result, cachedAt: Date.now() });\n return result;\n}\n\ninterface TokenBalanceEntry {\n accountIndex: number;\n mint: string;\n owner?: string;\n uiTokenAmount: { amount: string };\n}\n\nasync function doVerifyOnce(\n rpc: Rpc<SolanaRpcApi>,\n txSignature: Signature,\n expectedRecipient: Address,\n): Promise<QuickVerifyResult> {\n const sigStr = txSignature as string;\n\n if (!rpc || typeof (rpc as { getTransaction?: unknown }).getTransaction !== 'function') {\n return { receivedFunds: false, txSignature: sigStr, reason: 'rpc_error' };\n }\n\n let tx: Awaited<ReturnType<ReturnType<Rpc<SolanaRpcApi>['getTransaction']>['send']>>;\n try {\n tx = await rpc\n .getTransaction(txSignature, {\n commitment: 'confirmed',\n encoding: 'json',\n maxSupportedTransactionVersion: 0,\n })\n .send();\n } catch {\n return { receivedFunds: false, txSignature: sigStr, reason: 'rpc_error' };\n }\n\n if (!tx) {\n return { receivedFunds: false, txSignature: sigStr, reason: 'not_found' };\n }\n if (!tx.meta || tx.meta.err) {\n return { receivedFunds: false, txSignature: sigStr, reason: 'tx_failed' };\n }\n\n const accountKeys = tx.transaction.message.accountKeys as readonly string[];\n const recipientStr = expectedRecipient as string;\n\n const recipientIdx = accountKeys.indexOf(recipientStr);\n if (recipientIdx !== -1) {\n const preBalances = tx.meta.preBalances as readonly bigint[] | undefined;\n const postBalances = tx.meta.postBalances as readonly bigint[] | undefined;\n if (preBalances && postBalances) {\n const pre = preBalances[recipientIdx];\n const post = postBalances[recipientIdx];\n if (pre !== undefined && post !== undefined) {\n const delta = BigInt(post) - BigInt(pre);\n if (delta > 0n) {\n return { receivedFunds: true, txSignature: sigStr };\n }\n }\n }\n }\n\n const postTokenBalances = tx.meta.postTokenBalances as readonly TokenBalanceEntry[] | undefined;\n const preTokenBalances = tx.meta.preTokenBalances as readonly TokenBalanceEntry[] | undefined;\n if (postTokenBalances) {\n for (const post of postTokenBalances) {\n if (post.owner !== recipientStr) {\n continue;\n }\n const pre = preTokenBalances?.find(\n (entry) => entry.owner === recipientStr && entry.mint === post.mint,\n );\n const preAmount = pre ? BigInt(pre.uiTokenAmount.amount) : 0n;\n const postAmount = BigInt(post.uiTokenAmount.amount);\n if (postAmount > preAmount) {\n return { receivedFunds: true, txSignature: sigStr };\n }\n }\n }\n\n return { receivedFunds: false, txSignature: sigStr, reason: 'recipient_mismatch' };\n}\n","import { deriveNetworkStatsAddress, fetchMaybeNetworkStats } from '@elisym/config-client';\nimport type { Address, Rpc, Signature, SolanaRpcApi } from '@solana/kit';\nimport { address } from '@solana/kit';\nimport { DEFAULTS, ELISYM_PROTOCOL_TAG } from '../constants';\n\n/**\n * Aggregated on-chain stats across the entire elisym network. Volume is\n * keyed by `'native'` for SOL or by SPL mint address; values are subunits\n * (lamports for native, raw token units for SPL).\n */\nexport interface NetworkStatsResult {\n jobCount: number;\n volumeByAsset: Record<string, bigint>;\n /** Most-recent signature returned by the RPC (use as cursor for forward sync). */\n latestSignature?: string;\n /** Oldest signature scanned in this batch (use as `before` for next page). */\n oldestSignature?: string;\n}\n\nexport interface AggregateNetworkStatsOptions {\n /** Cap on signatures fetched in one call. Defaults to 1000 (RPC max). */\n limit?: number;\n /** Page backwards from this signature for historical scans. */\n before?: Signature;\n /** Parallel `getTransaction` calls. Defaults to `DEFAULTS.QUERY_MAX_CONCURRENCY`. */\n concurrency?: number;\n}\n\nconst DEFAULT_LIMIT = 1000;\nconst NATIVE_KEY = 'native';\n\ninterface TokenBalanceEntry {\n accountIndex: number;\n mint: string;\n owner?: string;\n uiTokenAmount: { amount: string };\n}\n\n/**\n * Enumerate every elisym payment transaction reachable from the protocol tag\n * pubkey and aggregate gross volume + count.\n *\n * Implementation detail: for SPL txs we sum positive token-balance deltas per\n * mint (ignores ATA rent that would inflate native lamport deltas in the same\n * tx). For native SOL txs we sum positive lamport deltas across all non-payer\n * accounts - elisym native txs only emit provider + optional fee transfers,\n * so this equals gross volume. The `tx_fee` paid by the fee-payer never shows\n * up as a positive delta, so it is naturally excluded.\n */\nexport async function aggregateNetworkStats(\n rpc: Rpc<SolanaRpcApi>,\n options?: AggregateNetworkStatsOptions,\n): Promise<NetworkStatsResult> {\n const limit = options?.limit ?? DEFAULT_LIMIT;\n const concurrency = options?.concurrency ?? DEFAULTS.QUERY_MAX_CONCURRENCY;\n const tag = address(ELISYM_PROTOCOL_TAG);\n\n const signatures = await rpc\n .getSignaturesForAddress(tag, { limit, before: options?.before })\n .send();\n const validSigs = signatures.filter((entry) => entry.err === null);\n\n if (validSigs.length === 0) {\n return { jobCount: 0, volumeByAsset: {} };\n }\n\n const volumeByAsset: Record<string, bigint> = {};\n let jobCount = 0;\n\n for (let start = 0; start < validSigs.length; start += concurrency) {\n const batch = validSigs.slice(start, start + concurrency);\n const txResults = await Promise.all(\n batch.map((entry) =>\n rpc\n .getTransaction(entry.signature, {\n commitment: 'confirmed',\n encoding: 'json',\n maxSupportedTransactionVersion: 0,\n })\n .send()\n .catch(() => null),\n ),\n );\n\n for (const tx of txResults) {\n if (!tx?.meta || tx.meta.err) {\n continue;\n }\n jobCount += 1;\n accumulateTransfers(tx, volumeByAsset);\n }\n }\n\n const latest = validSigs[0]?.signature;\n const oldest = validSigs.at(-1)?.signature;\n\n return {\n jobCount,\n volumeByAsset,\n latestSignature: latest as string | undefined,\n oldestSignature: oldest as string | undefined,\n };\n}\n\ninterface RawTransaction {\n meta: {\n err: unknown;\n preBalances: readonly bigint[];\n postBalances: readonly bigint[];\n preTokenBalances?: readonly TokenBalanceEntry[];\n postTokenBalances?: readonly TokenBalanceEntry[];\n } | null;\n transaction: {\n message: {\n accountKeys: readonly string[];\n };\n };\n}\n\nfunction accumulateTransfers(tx: unknown, volumeByAsset: Record<string, bigint>): void {\n const raw = tx as RawTransaction;\n const meta = raw.meta;\n if (!meta) {\n return;\n }\n\n const preTokens = meta.preTokenBalances ?? [];\n const postTokens = meta.postTokenBalances ?? [];\n const isSpl = postTokens.length > 0 || preTokens.length > 0;\n\n if (isSpl) {\n accumulateSplDeltas(preTokens, postTokens, volumeByAsset);\n return;\n }\n\n accumulateNativeDeltas(meta.preBalances, meta.postBalances, volumeByAsset);\n}\n\nfunction accumulateSplDeltas(\n pre: readonly TokenBalanceEntry[],\n post: readonly TokenBalanceEntry[],\n volumeByAsset: Record<string, bigint>,\n): void {\n for (const postEntry of post) {\n const preEntry = pre.find((entry) => entry.accountIndex === postEntry.accountIndex);\n const preAmount = preEntry ? BigInt(preEntry.uiTokenAmount.amount) : 0n;\n const postAmount = BigInt(postEntry.uiTokenAmount.amount);\n const delta = postAmount - preAmount;\n if (delta > 0n) {\n volumeByAsset[postEntry.mint] = (volumeByAsset[postEntry.mint] ?? 0n) + delta;\n }\n }\n}\n\nfunction accumulateNativeDeltas(\n pre: readonly bigint[],\n post: readonly bigint[],\n volumeByAsset: Record<string, bigint>,\n): void {\n // accountKeys[0] is the fee payer; its negative delta covers gross + tx_fee.\n // Skip it and sum positive deltas of every other account - equals gross.\n for (let i = 1; i < post.length; i++) {\n const preValue = pre[i] ?? 0n;\n const postValue = post[i] ?? 0n;\n const delta = BigInt(postValue) - BigInt(preValue);\n if (delta > 0n) {\n volumeByAsset[NATIVE_KEY] = (volumeByAsset[NATIVE_KEY] ?? 0n) + delta;\n }\n }\n}\n\n/**\n * Best-effort network stats read from the on-chain `NetworkStats` PDA\n * maintained by the elisym-config program. One `getAccountInfo` call - no\n * signature scans, no per-tx aggregation.\n *\n * The PDA is incremented by the client SDK alongside each payment and is not\n * yet bound to a verified transfer, so totals can be inflated cheaply by a\n * malicious caller. Authoritative tracking will land with the escrow rewrite.\n *\n * Returns `null` when the PDA has not been initialized yet (admin must call\n * `initialize_stats` once after program upgrade).\n */\n/**\n * Best-effort network counters read from the on-chain PDA. These are NOT bound\n * to verified transfers and can be inflated by a malicious caller, so present\n * them as approximate/unverified, never as authoritative proof of activity. For\n * a transfer-derived figure use `aggregateNetworkStats`.\n */\nexport interface OnchainNetworkStats {\n jobCount: number;\n volumeNative: bigint;\n volumeUsdc: bigint;\n}\n\nexport async function getNetworkStats(\n rpc: Rpc<SolanaRpcApi>,\n programId: Address,\n): Promise<OnchainNetworkStats | null> {\n const statsPda = await deriveNetworkStatsAddress(programId);\n const account = await fetchMaybeNetworkStats(rpc, statsPda);\n if (!account.exists) {\n return null;\n }\n return {\n jobCount: Number(account.data.jobCount),\n volumeNative: account.data.volumeNative,\n volumeUsdc: account.data.volumeUsdc,\n };\n}\n","/**\n * Zod schemas and types for `~/.elisym/config.yaml`.\n *\n * Split from `./global` so the schemas can be re-exported from the\n * browser-safe `@elisym/sdk` entry point without dragging in `node:fs/promises`\n * (which the loader/writer in `./global` needs).\n */\n\nimport { z } from 'zod';\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 // Stored as a string to preserve the operator's exact decimal text (avoids\n // Number round-tripping to scientific notation). Legacy configs persisted a\n // number; accept both and normalize to a positive-decimal string.\n amount: z\n .union([z.string(), z.number()])\n .transform((value) => (typeof value === 'number' ? String(value) : value.trim()))\n .refine((value) => /^\\d+(?:\\.\\d+)?$/.test(value) && /[1-9]/.test(value), {\n message: 'amount must be a positive decimal (e.g. \"0.5\", \"1\")',\n }),\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","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_keys` is a Record<provider-id, key> after the registry\n // refactor; the wildcard variants cover any nested provider id.\n 'nostr_secret_key',\n 'solana_secret_key',\n 'llm_api_keys',\n '*.nostr_secret_key',\n '*.solana_secret_key',\n '*.llm_api_keys',\n 'llm_api_keys.*',\n '*.llm_api_keys.*',\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"]}