@elisym/sdk 0.23.0 → 0.24.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -1,8 +1,8 @@
1
1
  import { Address, TransactionSigner, Rpc, SolanaRpcApi, Signature } from '@solana/kit';
2
+ import { z } from 'zod';
2
3
  import { Filter, Event } from 'nostr-tools';
3
4
  import { A as Asset } from './assets-C-nzSYD4.cjs';
4
5
  export { C as Chain, K as KNOWN_ASSETS, N as NATIVE_SOL, U as USDC_SOLANA_DEVNET, a as assetByKey, b as assetKey, f as formatAssetAmount, p as parseAssetAmount, r as resolveAssetFromPaymentRequest, c as resolveKnownAsset } from './assets-C-nzSYD4.cjs';
5
- import { z } from 'zod';
6
6
  export { G as GlobalConfig, a as GlobalConfigSchema, S as SessionSpendLimitEntry, b as SessionSpendLimitEntrySchema } from './global-schema-BsVFDtkt.cjs';
7
7
  export { R as RateLimitDecision, S as SlidingWindowLimiter, a as SlidingWindowLimiterOptions, c as createSlidingWindowLimiter } from './rateLimiter-CoEmZkSX.cjs';
8
8
 
@@ -23,6 +23,170 @@ declare class ElisymIdentity {
23
23
  static fromHex(hex: string): ElisymIdentity;
24
24
  }
25
25
 
26
+ /**
27
+ * Job file-attachment descriptor and the job-payload envelope (browser-safe).
28
+ *
29
+ * A file job carries its file out-of-band (P2P via iroh); the Nostr event's
30
+ * (NIP-44-encrypted) `content` carries only a small JSON envelope describing the
31
+ * file and how to fetch it. This module owns the envelope shape, its encode, and
32
+ * its strict decode. It deliberately does NOT construct an iroh `BlobTicket` - the
33
+ * `ticket` is validated only as a bounded opaque string so that decoding an
34
+ * untrusted, possibly pre-payment request never pulls in the native iroh addon.
35
+ *
36
+ * The transport is a discriminated union keyed on `kind`; Phase 1 ships only
37
+ * `iroh`. A future HTTP/Blossom transport is added as another union member without
38
+ * changing this contract.
39
+ */
40
+
41
+ /** Current envelope version. Bumped only on a breaking envelope-shape change. */
42
+ declare const ENVELOPE_VERSION = "elisym-job/1";
43
+ declare const FileTransportSchema: z.ZodDiscriminatedUnion<"kind", [z.ZodObject<{
44
+ kind: z.ZodLiteral<"iroh">;
45
+ /** Opaque iroh `BlobTicket` string. Parsed into a real ticket only at fetch time. */
46
+ ticket: z.ZodString;
47
+ }, "strip", z.ZodTypeAny, {
48
+ kind: "iroh";
49
+ ticket: string;
50
+ }, {
51
+ kind: "iroh";
52
+ ticket: string;
53
+ }>]>;
54
+ declare const FileAttachmentSchema: z.ZodObject<{
55
+ /** Display name only. Never used to derive a filesystem path (callers sanitize). */
56
+ name: z.ZodString;
57
+ /** Declared size in bytes (display/hint only; enforcement is on actual streamed bytes). */
58
+ size: z.ZodNumber;
59
+ mime: z.ZodString;
60
+ /** Ordered by sender preference; at least one. */
61
+ transports: z.ZodArray<z.ZodDiscriminatedUnion<"kind", [z.ZodObject<{
62
+ kind: z.ZodLiteral<"iroh">;
63
+ /** Opaque iroh `BlobTicket` string. Parsed into a real ticket only at fetch time. */
64
+ ticket: z.ZodString;
65
+ }, "strip", z.ZodTypeAny, {
66
+ kind: "iroh";
67
+ ticket: string;
68
+ }, {
69
+ kind: "iroh";
70
+ ticket: string;
71
+ }>]>, "many">;
72
+ /** Optional provider hint (unix seconds) for when seeding may stop. */
73
+ seedingExpiresAt: z.ZodOptional<z.ZodNumber>;
74
+ }, "strip", z.ZodTypeAny, {
75
+ name: string;
76
+ size: number;
77
+ mime: string;
78
+ transports: {
79
+ kind: "iroh";
80
+ ticket: string;
81
+ }[];
82
+ seedingExpiresAt?: number | undefined;
83
+ }, {
84
+ name: string;
85
+ size: number;
86
+ mime: string;
87
+ transports: {
88
+ kind: "iroh";
89
+ ticket: string;
90
+ }[];
91
+ seedingExpiresAt?: number | undefined;
92
+ }>;
93
+ declare const JobPayloadEnvelopeSchema: z.ZodObject<{
94
+ v: z.ZodLiteral<"elisym-job/1">;
95
+ text: z.ZodOptional<z.ZodString>;
96
+ attachment: z.ZodOptional<z.ZodObject<{
97
+ /** Display name only. Never used to derive a filesystem path (callers sanitize). */
98
+ name: z.ZodString;
99
+ /** Declared size in bytes (display/hint only; enforcement is on actual streamed bytes). */
100
+ size: z.ZodNumber;
101
+ mime: z.ZodString;
102
+ /** Ordered by sender preference; at least one. */
103
+ transports: z.ZodArray<z.ZodDiscriminatedUnion<"kind", [z.ZodObject<{
104
+ kind: z.ZodLiteral<"iroh">;
105
+ /** Opaque iroh `BlobTicket` string. Parsed into a real ticket only at fetch time. */
106
+ ticket: z.ZodString;
107
+ }, "strip", z.ZodTypeAny, {
108
+ kind: "iroh";
109
+ ticket: string;
110
+ }, {
111
+ kind: "iroh";
112
+ ticket: string;
113
+ }>]>, "many">;
114
+ /** Optional provider hint (unix seconds) for when seeding may stop. */
115
+ seedingExpiresAt: z.ZodOptional<z.ZodNumber>;
116
+ }, "strip", z.ZodTypeAny, {
117
+ name: string;
118
+ size: number;
119
+ mime: string;
120
+ transports: {
121
+ kind: "iroh";
122
+ ticket: string;
123
+ }[];
124
+ seedingExpiresAt?: number | undefined;
125
+ }, {
126
+ name: string;
127
+ size: number;
128
+ mime: string;
129
+ transports: {
130
+ kind: "iroh";
131
+ ticket: string;
132
+ }[];
133
+ seedingExpiresAt?: number | undefined;
134
+ }>>;
135
+ }, "strip", z.ZodTypeAny, {
136
+ v: "elisym-job/1";
137
+ text?: string | undefined;
138
+ attachment?: {
139
+ name: string;
140
+ size: number;
141
+ mime: string;
142
+ transports: {
143
+ kind: "iroh";
144
+ ticket: string;
145
+ }[];
146
+ seedingExpiresAt?: number | undefined;
147
+ } | undefined;
148
+ }, {
149
+ v: "elisym-job/1";
150
+ text?: string | undefined;
151
+ attachment?: {
152
+ name: string;
153
+ size: number;
154
+ mime: string;
155
+ transports: {
156
+ kind: "iroh";
157
+ ticket: string;
158
+ }[];
159
+ seedingExpiresAt?: number | undefined;
160
+ } | undefined;
161
+ }>;
162
+ type FileTransport = z.infer<typeof FileTransportSchema>;
163
+ type FileAttachment = z.infer<typeof FileAttachmentSchema>;
164
+ type JobPayloadEnvelope = z.infer<typeof JobPayloadEnvelopeSchema>;
165
+ /** Decoded job payload: a free-text note and/or a file attachment. */
166
+ interface DecodedJobPayload {
167
+ text?: string;
168
+ attachment?: FileAttachment;
169
+ }
170
+ /**
171
+ * Serialize a job payload into the envelope string that goes (encrypted) into a
172
+ * Nostr event's `content`. Used only when an attachment is present; plain-text
173
+ * jobs send their text directly and are never wrapped.
174
+ */
175
+ declare function encodeJobPayload(payload: DecodedJobPayload): string;
176
+ /**
177
+ * Decode decrypted `content` into a job payload.
178
+ *
179
+ * - Content longer than `MAX_INPUT_LENGTH` is treated as raw text without parsing
180
+ * (a valid envelope is small and a valid text job is capped at submit time), so
181
+ * untrusted, possibly-huge intake content is never `JSON.parse`d unbounded.
182
+ * - Non-JSON, non-object JSON, or a JSON object that does not carry our
183
+ * `elisym-job/` version marker is returned as raw text.
184
+ * - A value that DOES carry an `elisym-job/` marker is validated strictly: an
185
+ * unknown version or a malformed envelope throws (callers skip/surface it)
186
+ * rather than being silently mistreated as text.
187
+ */
188
+ declare function decodeJobPayload(content: string): DecodedJobPayload;
189
+
26
190
  interface SubCloser {
27
191
  close: (reason?: string) => void;
28
192
  }
@@ -34,6 +198,16 @@ interface CapabilityCard {
34
198
  payment?: PaymentInfo;
35
199
  image?: string;
36
200
  static?: boolean;
201
+ /**
202
+ * MIME the capability expects as a file input (from a dynamic-script skill's
203
+ * `input_mime`). Discovery hint only; the provider still content-sniffs the
204
+ * actual file. Its presence means the capability needs a file input - which
205
+ * the web app cannot send (no iroh transport), so the web app blocks the Buy
206
+ * button. `*` = any file, `image/*` = any image, `image/png` = exact.
207
+ */
208
+ inputMime?: string;
209
+ /** MIME of a file result the capability produces (from `output_mime`). */
210
+ outputMime?: string;
37
211
  }
38
212
  /** Payment info embedded in capability card (legacy format for on-network events). */
39
213
  interface PaymentInfo {
@@ -139,17 +313,32 @@ interface Job {
139
313
  asset?: PaymentAssetRef;
140
314
  }
141
315
  interface SubmitJobOptions {
142
- /** Job input text. Sent unencrypted if providerPubkey is not set. */
316
+ /**
317
+ * Job input text. Sent unencrypted if providerPubkey is not set. May be empty
318
+ * when `attachment` is set (a file-only job carries no text note).
319
+ */
143
320
  input: string;
144
321
  capability: string;
145
322
  /** Target provider pubkey. If omitted, job is broadcast unencrypted and visible to all relays. */
146
323
  providerPubkey?: string;
147
324
  /** Kind offset (default 100 - kind 5100). */
148
325
  kindOffset?: number;
326
+ /**
327
+ * Optional file attachment. When set, `input` (as the text note) and the
328
+ * attachment are wrapped in a job-payload envelope before encryption. The file
329
+ * itself travels out-of-band (P2P via iroh), not in the Nostr event.
330
+ */
331
+ attachment?: FileAttachment;
149
332
  }
150
333
  interface JobUpdateCallbacks {
151
334
  onFeedback?: (status: string, amount?: number, paymentRequest?: string, senderPubkey?: string) => void;
152
- onResult?: (content: string, eventId: string) => void;
335
+ /**
336
+ * Fired on a job result. `content` is the result text (for a file result, the
337
+ * envelope's text note, or `''`); `attachment` is the file descriptor when the
338
+ * result carries a file. The file is fetched separately (P2P via iroh), never
339
+ * inlined here.
340
+ */
341
+ onResult?: (content: string, eventId: string, attachment?: FileAttachment) => void;
153
342
  onError?: (error: string) => void;
154
343
  /**
155
344
  * Fired when the result wait window expires without a result - a distinct,
@@ -536,14 +725,14 @@ declare class MarketplaceService {
536
725
  */
537
726
  subscribeToJobRequests(identity: ElisymIdentity, kinds: number[], onRequest: (event: Event) => void): SubCloser;
538
727
  /** Submit a job result with NIP-44 encrypted content. Result kind is derived from the request kind. */
539
- submitJobResult(identity: ElisymIdentity, requestEvent: Event, content: string, amount?: number): Promise<string>;
728
+ submitJobResult(identity: ElisymIdentity, requestEvent: Event, content: string, amount?: number, attachment?: FileAttachment): Promise<string>;
540
729
  /**
541
730
  * Submit a job result with retry and exponential backoff.
542
731
  * Retries on publish failures (e.g. relay disconnects).
543
732
  * With maxAttempts=3: try, ~1s, try, ~2s, try, throw.
544
733
  * Jitter: 0.5x-1.0x of calculated delay.
545
734
  */
546
- submitJobResultWithRetry(identity: ElisymIdentity, requestEvent: Event, content: string, amount?: number, maxAttempts?: number, baseDelayMs?: number): Promise<string>;
735
+ submitJobResultWithRetry(identity: ElisymIdentity, requestEvent: Event, content: string, amount?: number, maxAttempts?: number, baseDelayMs?: number, attachment?: FileAttachment): Promise<string>;
547
736
  /** Submit payment-required feedback with a payment request. */
548
737
  submitPaymentRequiredFeedback(identity: ElisymIdentity, requestEvent: Event, amount: number, paymentRequestJson: string): Promise<void>;
549
738
  /** Submit processing feedback to notify customer that work has started. */
@@ -1288,10 +1477,15 @@ declare const DEFAULTS: {
1288
1477
  readonly RESULT_RETRY_BASE_MS: 1000;
1289
1478
  readonly QUERY_MAX_CONCURRENCY: 6;
1290
1479
  readonly VERIFY_SIGNATURE_LIMIT: 25;
1480
+ readonly IROH_FETCH_TIMEOUT_MS: 300000;
1291
1481
  };
1292
1482
  /** Protocol limits for input validation. */
1293
1483
  declare const LIMITS: {
1294
1484
  readonly MAX_INPUT_LENGTH: 100000;
1485
+ readonly NIP44_MAX_PLAINTEXT_BYTES: 65535;
1486
+ readonly MAX_ENCRYPTED_INLINE_BYTES: 60000;
1487
+ readonly MAX_REINLINE_TEXT_BYTES: 4194304;
1488
+ readonly MAX_FILE_SIZE: 1073741824;
1295
1489
  readonly MAX_TIMEOUT_SECS: 600;
1296
1490
  readonly MAX_EXECUTION_SECS: 2147483;
1297
1491
  readonly MAX_CAPABILITIES: 20;
@@ -1305,5 +1499,11 @@ declare const LIMITS: {
1305
1499
  readonly MAX_POLICY_SUMMARY_LENGTH: 280;
1306
1500
  readonly MAX_POLICY_VERSION_LENGTH: 32;
1307
1501
  };
1502
+ /**
1503
+ * UTF-8 byte length of a string. All size guards on encrypted content measure
1504
+ * BYTES, not `String.length` (UTF-16 code units): NIP-44's plaintext cap is a
1505
+ * byte cap, so a multibyte string under the char cap can still exceed it.
1506
+ */
1507
+ declare function utf8ByteLength(value: string): number;
1308
1508
 
1309
- export { type Agent, type AgentPolicy, type AggregateNetworkStatsOptions, Asset, BoundedSet, type BuildTransactionOptions, type CapabilityCard, DEFAULTS, DEFAULT_KIND_OFFSET, DEFAULT_REDACT_PATHS, DiscoveryService, ELISYM_PROTOCOL_TAG, ElisymClient, type ElisymClientConfig, type ElisymClientFullConfig, ElisymIdentity, type EstimatePriorityFeeOptions, type EstimateSolFeeOptions, type GetProtocolConfigOptions, INPUT_REDACT_PATHS, type Job, type JobErrorKind, type JobStatus, type JobSubscriptionOptions, type JobUpdateCallbacks, JobWaitTimeoutError, KIND_APP_HANDLER, KIND_JOB_FEEDBACK, KIND_JOB_REQUEST, KIND_JOB_REQUEST_BASE, KIND_JOB_RESULT, KIND_JOB_RESULT_BASE, KIND_LONG_FORM_ARTICLE, KIND_PING, KIND_PONG, LAMPORTS_PER_SOL, LIMITS, MarketplaceService, MediaService, type Network, type NetworkBaselineEstimate, type NetworkBaselineOptions, type NetworkStats, type NetworkStatsResult, NostrPool, type OnchainNetworkStats, POLICY_D_TAG_PREFIX, POLICY_TYPE_REGEX, POLICY_T_TAG, PROTOCOL_PROGRAM_ID_DEVNET, type ParseOptions, type ParseResult, type ParsedPaymentRequest, type PaymentAssetRef, type PaymentInfo, type PaymentRequestData, PaymentRequestSchema, type PaymentStrategy, type PaymentValidationCode, type PaymentValidationError, type PingResult, PingService, PoliciesService, type PolicyInput, type ProtocolCluster, type ProtocolConfig, type ProtocolConfigInput, type QuickVerifyReason, type QuickVerifyResult, RELAYS, type RankKey, SECRET_REDACT_PATHS, type Signer, type SolFeeEstimate, SolanaPaymentStrategy, type SubCloser, type SubmitJobOptions, type VerifyOptions, type VerifyResult, aggregateNetworkStats, assertExpiry, assertLamports, buildPaymentInstructions, calculateProtocolFee, classifyJobError, clearPriorityFeeCache, clearProtocolConfigCache, clearQuickVerifyCache, compareAgentsByRank, computeRankKey, createPaymentRequestWithOnchainConfig, estimateNetworkBaseline, estimatePriorityFeeMicroLamports, estimateSolFeeLamports, formatFeeBreakdown, formatNetworkBaseline, formatSol, getNetworkStats, getProtocolConfig, getProtocolProgramId, jobRequestKind, jobResultKind, makeCensor, nip44Decrypt, nip44Encrypt, parsePaymentRequest, pickPercentileFee, timeAgo, toDTag, truncateKey, validateAgentName, validateExpiry, verifyJobPaymentQuick };
1509
+ export { type Agent, type AgentPolicy, type AggregateNetworkStatsOptions, Asset, BoundedSet, type BuildTransactionOptions, type CapabilityCard, DEFAULTS, DEFAULT_KIND_OFFSET, DEFAULT_REDACT_PATHS, type DecodedJobPayload, DiscoveryService, ELISYM_PROTOCOL_TAG, ENVELOPE_VERSION, ElisymClient, type ElisymClientConfig, type ElisymClientFullConfig, ElisymIdentity, type EstimatePriorityFeeOptions, type EstimateSolFeeOptions, type FileAttachment, type FileTransport, type GetProtocolConfigOptions, INPUT_REDACT_PATHS, type Job, type JobErrorKind, type JobPayloadEnvelope, type JobStatus, type JobSubscriptionOptions, type JobUpdateCallbacks, JobWaitTimeoutError, KIND_APP_HANDLER, KIND_JOB_FEEDBACK, KIND_JOB_REQUEST, KIND_JOB_REQUEST_BASE, KIND_JOB_RESULT, KIND_JOB_RESULT_BASE, KIND_LONG_FORM_ARTICLE, KIND_PING, KIND_PONG, LAMPORTS_PER_SOL, LIMITS, MarketplaceService, MediaService, type Network, type NetworkBaselineEstimate, type NetworkBaselineOptions, type NetworkStats, type NetworkStatsResult, NostrPool, type OnchainNetworkStats, POLICY_D_TAG_PREFIX, POLICY_TYPE_REGEX, POLICY_T_TAG, PROTOCOL_PROGRAM_ID_DEVNET, type ParseOptions, type ParseResult, type ParsedPaymentRequest, type PaymentAssetRef, type PaymentInfo, type PaymentRequestData, PaymentRequestSchema, type PaymentStrategy, type PaymentValidationCode, type PaymentValidationError, type PingResult, PingService, PoliciesService, type PolicyInput, type ProtocolCluster, type ProtocolConfig, type ProtocolConfigInput, type QuickVerifyReason, type QuickVerifyResult, RELAYS, type RankKey, SECRET_REDACT_PATHS, type Signer, type SolFeeEstimate, SolanaPaymentStrategy, type SubCloser, type SubmitJobOptions, type VerifyOptions, type VerifyResult, aggregateNetworkStats, assertExpiry, assertLamports, buildPaymentInstructions, calculateProtocolFee, classifyJobError, clearPriorityFeeCache, clearProtocolConfigCache, clearQuickVerifyCache, compareAgentsByRank, computeRankKey, createPaymentRequestWithOnchainConfig, decodeJobPayload, encodeJobPayload, estimateNetworkBaseline, estimatePriorityFeeMicroLamports, estimateSolFeeLamports, formatFeeBreakdown, formatNetworkBaseline, formatSol, getNetworkStats, getProtocolConfig, getProtocolProgramId, jobRequestKind, jobResultKind, makeCensor, nip44Decrypt, nip44Encrypt, parsePaymentRequest, pickPercentileFee, timeAgo, toDTag, truncateKey, utf8ByteLength, validateAgentName, validateExpiry, verifyJobPaymentQuick };
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import { Address, TransactionSigner, Rpc, SolanaRpcApi, Signature } from '@solana/kit';
2
+ import { z } from 'zod';
2
3
  import { Filter, Event } from 'nostr-tools';
3
4
  import { A as Asset } from './assets-C-nzSYD4.js';
4
5
  export { C as Chain, K as KNOWN_ASSETS, N as NATIVE_SOL, U as USDC_SOLANA_DEVNET, a as assetByKey, b as assetKey, f as formatAssetAmount, p as parseAssetAmount, r as resolveAssetFromPaymentRequest, c as resolveKnownAsset } from './assets-C-nzSYD4.js';
5
- import { z } from 'zod';
6
6
  export { G as GlobalConfig, a as GlobalConfigSchema, S as SessionSpendLimitEntry, b as SessionSpendLimitEntrySchema } from './global-schema-BsVFDtkt.js';
7
7
  export { R as RateLimitDecision, S as SlidingWindowLimiter, a as SlidingWindowLimiterOptions, c as createSlidingWindowLimiter } from './rateLimiter-CoEmZkSX.js';
8
8
 
@@ -23,6 +23,170 @@ declare class ElisymIdentity {
23
23
  static fromHex(hex: string): ElisymIdentity;
24
24
  }
25
25
 
26
+ /**
27
+ * Job file-attachment descriptor and the job-payload envelope (browser-safe).
28
+ *
29
+ * A file job carries its file out-of-band (P2P via iroh); the Nostr event's
30
+ * (NIP-44-encrypted) `content` carries only a small JSON envelope describing the
31
+ * file and how to fetch it. This module owns the envelope shape, its encode, and
32
+ * its strict decode. It deliberately does NOT construct an iroh `BlobTicket` - the
33
+ * `ticket` is validated only as a bounded opaque string so that decoding an
34
+ * untrusted, possibly pre-payment request never pulls in the native iroh addon.
35
+ *
36
+ * The transport is a discriminated union keyed on `kind`; Phase 1 ships only
37
+ * `iroh`. A future HTTP/Blossom transport is added as another union member without
38
+ * changing this contract.
39
+ */
40
+
41
+ /** Current envelope version. Bumped only on a breaking envelope-shape change. */
42
+ declare const ENVELOPE_VERSION = "elisym-job/1";
43
+ declare const FileTransportSchema: z.ZodDiscriminatedUnion<"kind", [z.ZodObject<{
44
+ kind: z.ZodLiteral<"iroh">;
45
+ /** Opaque iroh `BlobTicket` string. Parsed into a real ticket only at fetch time. */
46
+ ticket: z.ZodString;
47
+ }, "strip", z.ZodTypeAny, {
48
+ kind: "iroh";
49
+ ticket: string;
50
+ }, {
51
+ kind: "iroh";
52
+ ticket: string;
53
+ }>]>;
54
+ declare const FileAttachmentSchema: z.ZodObject<{
55
+ /** Display name only. Never used to derive a filesystem path (callers sanitize). */
56
+ name: z.ZodString;
57
+ /** Declared size in bytes (display/hint only; enforcement is on actual streamed bytes). */
58
+ size: z.ZodNumber;
59
+ mime: z.ZodString;
60
+ /** Ordered by sender preference; at least one. */
61
+ transports: z.ZodArray<z.ZodDiscriminatedUnion<"kind", [z.ZodObject<{
62
+ kind: z.ZodLiteral<"iroh">;
63
+ /** Opaque iroh `BlobTicket` string. Parsed into a real ticket only at fetch time. */
64
+ ticket: z.ZodString;
65
+ }, "strip", z.ZodTypeAny, {
66
+ kind: "iroh";
67
+ ticket: string;
68
+ }, {
69
+ kind: "iroh";
70
+ ticket: string;
71
+ }>]>, "many">;
72
+ /** Optional provider hint (unix seconds) for when seeding may stop. */
73
+ seedingExpiresAt: z.ZodOptional<z.ZodNumber>;
74
+ }, "strip", z.ZodTypeAny, {
75
+ name: string;
76
+ size: number;
77
+ mime: string;
78
+ transports: {
79
+ kind: "iroh";
80
+ ticket: string;
81
+ }[];
82
+ seedingExpiresAt?: number | undefined;
83
+ }, {
84
+ name: string;
85
+ size: number;
86
+ mime: string;
87
+ transports: {
88
+ kind: "iroh";
89
+ ticket: string;
90
+ }[];
91
+ seedingExpiresAt?: number | undefined;
92
+ }>;
93
+ declare const JobPayloadEnvelopeSchema: z.ZodObject<{
94
+ v: z.ZodLiteral<"elisym-job/1">;
95
+ text: z.ZodOptional<z.ZodString>;
96
+ attachment: z.ZodOptional<z.ZodObject<{
97
+ /** Display name only. Never used to derive a filesystem path (callers sanitize). */
98
+ name: z.ZodString;
99
+ /** Declared size in bytes (display/hint only; enforcement is on actual streamed bytes). */
100
+ size: z.ZodNumber;
101
+ mime: z.ZodString;
102
+ /** Ordered by sender preference; at least one. */
103
+ transports: z.ZodArray<z.ZodDiscriminatedUnion<"kind", [z.ZodObject<{
104
+ kind: z.ZodLiteral<"iroh">;
105
+ /** Opaque iroh `BlobTicket` string. Parsed into a real ticket only at fetch time. */
106
+ ticket: z.ZodString;
107
+ }, "strip", z.ZodTypeAny, {
108
+ kind: "iroh";
109
+ ticket: string;
110
+ }, {
111
+ kind: "iroh";
112
+ ticket: string;
113
+ }>]>, "many">;
114
+ /** Optional provider hint (unix seconds) for when seeding may stop. */
115
+ seedingExpiresAt: z.ZodOptional<z.ZodNumber>;
116
+ }, "strip", z.ZodTypeAny, {
117
+ name: string;
118
+ size: number;
119
+ mime: string;
120
+ transports: {
121
+ kind: "iroh";
122
+ ticket: string;
123
+ }[];
124
+ seedingExpiresAt?: number | undefined;
125
+ }, {
126
+ name: string;
127
+ size: number;
128
+ mime: string;
129
+ transports: {
130
+ kind: "iroh";
131
+ ticket: string;
132
+ }[];
133
+ seedingExpiresAt?: number | undefined;
134
+ }>>;
135
+ }, "strip", z.ZodTypeAny, {
136
+ v: "elisym-job/1";
137
+ text?: string | undefined;
138
+ attachment?: {
139
+ name: string;
140
+ size: number;
141
+ mime: string;
142
+ transports: {
143
+ kind: "iroh";
144
+ ticket: string;
145
+ }[];
146
+ seedingExpiresAt?: number | undefined;
147
+ } | undefined;
148
+ }, {
149
+ v: "elisym-job/1";
150
+ text?: string | undefined;
151
+ attachment?: {
152
+ name: string;
153
+ size: number;
154
+ mime: string;
155
+ transports: {
156
+ kind: "iroh";
157
+ ticket: string;
158
+ }[];
159
+ seedingExpiresAt?: number | undefined;
160
+ } | undefined;
161
+ }>;
162
+ type FileTransport = z.infer<typeof FileTransportSchema>;
163
+ type FileAttachment = z.infer<typeof FileAttachmentSchema>;
164
+ type JobPayloadEnvelope = z.infer<typeof JobPayloadEnvelopeSchema>;
165
+ /** Decoded job payload: a free-text note and/or a file attachment. */
166
+ interface DecodedJobPayload {
167
+ text?: string;
168
+ attachment?: FileAttachment;
169
+ }
170
+ /**
171
+ * Serialize a job payload into the envelope string that goes (encrypted) into a
172
+ * Nostr event's `content`. Used only when an attachment is present; plain-text
173
+ * jobs send their text directly and are never wrapped.
174
+ */
175
+ declare function encodeJobPayload(payload: DecodedJobPayload): string;
176
+ /**
177
+ * Decode decrypted `content` into a job payload.
178
+ *
179
+ * - Content longer than `MAX_INPUT_LENGTH` is treated as raw text without parsing
180
+ * (a valid envelope is small and a valid text job is capped at submit time), so
181
+ * untrusted, possibly-huge intake content is never `JSON.parse`d unbounded.
182
+ * - Non-JSON, non-object JSON, or a JSON object that does not carry our
183
+ * `elisym-job/` version marker is returned as raw text.
184
+ * - A value that DOES carry an `elisym-job/` marker is validated strictly: an
185
+ * unknown version or a malformed envelope throws (callers skip/surface it)
186
+ * rather than being silently mistreated as text.
187
+ */
188
+ declare function decodeJobPayload(content: string): DecodedJobPayload;
189
+
26
190
  interface SubCloser {
27
191
  close: (reason?: string) => void;
28
192
  }
@@ -34,6 +198,16 @@ interface CapabilityCard {
34
198
  payment?: PaymentInfo;
35
199
  image?: string;
36
200
  static?: boolean;
201
+ /**
202
+ * MIME the capability expects as a file input (from a dynamic-script skill's
203
+ * `input_mime`). Discovery hint only; the provider still content-sniffs the
204
+ * actual file. Its presence means the capability needs a file input - which
205
+ * the web app cannot send (no iroh transport), so the web app blocks the Buy
206
+ * button. `*` = any file, `image/*` = any image, `image/png` = exact.
207
+ */
208
+ inputMime?: string;
209
+ /** MIME of a file result the capability produces (from `output_mime`). */
210
+ outputMime?: string;
37
211
  }
38
212
  /** Payment info embedded in capability card (legacy format for on-network events). */
39
213
  interface PaymentInfo {
@@ -139,17 +313,32 @@ interface Job {
139
313
  asset?: PaymentAssetRef;
140
314
  }
141
315
  interface SubmitJobOptions {
142
- /** Job input text. Sent unencrypted if providerPubkey is not set. */
316
+ /**
317
+ * Job input text. Sent unencrypted if providerPubkey is not set. May be empty
318
+ * when `attachment` is set (a file-only job carries no text note).
319
+ */
143
320
  input: string;
144
321
  capability: string;
145
322
  /** Target provider pubkey. If omitted, job is broadcast unencrypted and visible to all relays. */
146
323
  providerPubkey?: string;
147
324
  /** Kind offset (default 100 - kind 5100). */
148
325
  kindOffset?: number;
326
+ /**
327
+ * Optional file attachment. When set, `input` (as the text note) and the
328
+ * attachment are wrapped in a job-payload envelope before encryption. The file
329
+ * itself travels out-of-band (P2P via iroh), not in the Nostr event.
330
+ */
331
+ attachment?: FileAttachment;
149
332
  }
150
333
  interface JobUpdateCallbacks {
151
334
  onFeedback?: (status: string, amount?: number, paymentRequest?: string, senderPubkey?: string) => void;
152
- onResult?: (content: string, eventId: string) => void;
335
+ /**
336
+ * Fired on a job result. `content` is the result text (for a file result, the
337
+ * envelope's text note, or `''`); `attachment` is the file descriptor when the
338
+ * result carries a file. The file is fetched separately (P2P via iroh), never
339
+ * inlined here.
340
+ */
341
+ onResult?: (content: string, eventId: string, attachment?: FileAttachment) => void;
153
342
  onError?: (error: string) => void;
154
343
  /**
155
344
  * Fired when the result wait window expires without a result - a distinct,
@@ -536,14 +725,14 @@ declare class MarketplaceService {
536
725
  */
537
726
  subscribeToJobRequests(identity: ElisymIdentity, kinds: number[], onRequest: (event: Event) => void): SubCloser;
538
727
  /** Submit a job result with NIP-44 encrypted content. Result kind is derived from the request kind. */
539
- submitJobResult(identity: ElisymIdentity, requestEvent: Event, content: string, amount?: number): Promise<string>;
728
+ submitJobResult(identity: ElisymIdentity, requestEvent: Event, content: string, amount?: number, attachment?: FileAttachment): Promise<string>;
540
729
  /**
541
730
  * Submit a job result with retry and exponential backoff.
542
731
  * Retries on publish failures (e.g. relay disconnects).
543
732
  * With maxAttempts=3: try, ~1s, try, ~2s, try, throw.
544
733
  * Jitter: 0.5x-1.0x of calculated delay.
545
734
  */
546
- submitJobResultWithRetry(identity: ElisymIdentity, requestEvent: Event, content: string, amount?: number, maxAttempts?: number, baseDelayMs?: number): Promise<string>;
735
+ submitJobResultWithRetry(identity: ElisymIdentity, requestEvent: Event, content: string, amount?: number, maxAttempts?: number, baseDelayMs?: number, attachment?: FileAttachment): Promise<string>;
547
736
  /** Submit payment-required feedback with a payment request. */
548
737
  submitPaymentRequiredFeedback(identity: ElisymIdentity, requestEvent: Event, amount: number, paymentRequestJson: string): Promise<void>;
549
738
  /** Submit processing feedback to notify customer that work has started. */
@@ -1288,10 +1477,15 @@ declare const DEFAULTS: {
1288
1477
  readonly RESULT_RETRY_BASE_MS: 1000;
1289
1478
  readonly QUERY_MAX_CONCURRENCY: 6;
1290
1479
  readonly VERIFY_SIGNATURE_LIMIT: 25;
1480
+ readonly IROH_FETCH_TIMEOUT_MS: 300000;
1291
1481
  };
1292
1482
  /** Protocol limits for input validation. */
1293
1483
  declare const LIMITS: {
1294
1484
  readonly MAX_INPUT_LENGTH: 100000;
1485
+ readonly NIP44_MAX_PLAINTEXT_BYTES: 65535;
1486
+ readonly MAX_ENCRYPTED_INLINE_BYTES: 60000;
1487
+ readonly MAX_REINLINE_TEXT_BYTES: 4194304;
1488
+ readonly MAX_FILE_SIZE: 1073741824;
1295
1489
  readonly MAX_TIMEOUT_SECS: 600;
1296
1490
  readonly MAX_EXECUTION_SECS: 2147483;
1297
1491
  readonly MAX_CAPABILITIES: 20;
@@ -1305,5 +1499,11 @@ declare const LIMITS: {
1305
1499
  readonly MAX_POLICY_SUMMARY_LENGTH: 280;
1306
1500
  readonly MAX_POLICY_VERSION_LENGTH: 32;
1307
1501
  };
1502
+ /**
1503
+ * UTF-8 byte length of a string. All size guards on encrypted content measure
1504
+ * BYTES, not `String.length` (UTF-16 code units): NIP-44's plaintext cap is a
1505
+ * byte cap, so a multibyte string under the char cap can still exceed it.
1506
+ */
1507
+ declare function utf8ByteLength(value: string): number;
1308
1508
 
1309
- export { type Agent, type AgentPolicy, type AggregateNetworkStatsOptions, Asset, BoundedSet, type BuildTransactionOptions, type CapabilityCard, DEFAULTS, DEFAULT_KIND_OFFSET, DEFAULT_REDACT_PATHS, DiscoveryService, ELISYM_PROTOCOL_TAG, ElisymClient, type ElisymClientConfig, type ElisymClientFullConfig, ElisymIdentity, type EstimatePriorityFeeOptions, type EstimateSolFeeOptions, type GetProtocolConfigOptions, INPUT_REDACT_PATHS, type Job, type JobErrorKind, type JobStatus, type JobSubscriptionOptions, type JobUpdateCallbacks, JobWaitTimeoutError, KIND_APP_HANDLER, KIND_JOB_FEEDBACK, KIND_JOB_REQUEST, KIND_JOB_REQUEST_BASE, KIND_JOB_RESULT, KIND_JOB_RESULT_BASE, KIND_LONG_FORM_ARTICLE, KIND_PING, KIND_PONG, LAMPORTS_PER_SOL, LIMITS, MarketplaceService, MediaService, type Network, type NetworkBaselineEstimate, type NetworkBaselineOptions, type NetworkStats, type NetworkStatsResult, NostrPool, type OnchainNetworkStats, POLICY_D_TAG_PREFIX, POLICY_TYPE_REGEX, POLICY_T_TAG, PROTOCOL_PROGRAM_ID_DEVNET, type ParseOptions, type ParseResult, type ParsedPaymentRequest, type PaymentAssetRef, type PaymentInfo, type PaymentRequestData, PaymentRequestSchema, type PaymentStrategy, type PaymentValidationCode, type PaymentValidationError, type PingResult, PingService, PoliciesService, type PolicyInput, type ProtocolCluster, type ProtocolConfig, type ProtocolConfigInput, type QuickVerifyReason, type QuickVerifyResult, RELAYS, type RankKey, SECRET_REDACT_PATHS, type Signer, type SolFeeEstimate, SolanaPaymentStrategy, type SubCloser, type SubmitJobOptions, type VerifyOptions, type VerifyResult, aggregateNetworkStats, assertExpiry, assertLamports, buildPaymentInstructions, calculateProtocolFee, classifyJobError, clearPriorityFeeCache, clearProtocolConfigCache, clearQuickVerifyCache, compareAgentsByRank, computeRankKey, createPaymentRequestWithOnchainConfig, estimateNetworkBaseline, estimatePriorityFeeMicroLamports, estimateSolFeeLamports, formatFeeBreakdown, formatNetworkBaseline, formatSol, getNetworkStats, getProtocolConfig, getProtocolProgramId, jobRequestKind, jobResultKind, makeCensor, nip44Decrypt, nip44Encrypt, parsePaymentRequest, pickPercentileFee, timeAgo, toDTag, truncateKey, validateAgentName, validateExpiry, verifyJobPaymentQuick };
1509
+ export { type Agent, type AgentPolicy, type AggregateNetworkStatsOptions, Asset, BoundedSet, type BuildTransactionOptions, type CapabilityCard, DEFAULTS, DEFAULT_KIND_OFFSET, DEFAULT_REDACT_PATHS, type DecodedJobPayload, DiscoveryService, ELISYM_PROTOCOL_TAG, ENVELOPE_VERSION, ElisymClient, type ElisymClientConfig, type ElisymClientFullConfig, ElisymIdentity, type EstimatePriorityFeeOptions, type EstimateSolFeeOptions, type FileAttachment, type FileTransport, type GetProtocolConfigOptions, INPUT_REDACT_PATHS, type Job, type JobErrorKind, type JobPayloadEnvelope, type JobStatus, type JobSubscriptionOptions, type JobUpdateCallbacks, JobWaitTimeoutError, KIND_APP_HANDLER, KIND_JOB_FEEDBACK, KIND_JOB_REQUEST, KIND_JOB_REQUEST_BASE, KIND_JOB_RESULT, KIND_JOB_RESULT_BASE, KIND_LONG_FORM_ARTICLE, KIND_PING, KIND_PONG, LAMPORTS_PER_SOL, LIMITS, MarketplaceService, MediaService, type Network, type NetworkBaselineEstimate, type NetworkBaselineOptions, type NetworkStats, type NetworkStatsResult, NostrPool, type OnchainNetworkStats, POLICY_D_TAG_PREFIX, POLICY_TYPE_REGEX, POLICY_T_TAG, PROTOCOL_PROGRAM_ID_DEVNET, type ParseOptions, type ParseResult, type ParsedPaymentRequest, type PaymentAssetRef, type PaymentInfo, type PaymentRequestData, PaymentRequestSchema, type PaymentStrategy, type PaymentValidationCode, type PaymentValidationError, type PingResult, PingService, PoliciesService, type PolicyInput, type ProtocolCluster, type ProtocolConfig, type ProtocolConfigInput, type QuickVerifyReason, type QuickVerifyResult, RELAYS, type RankKey, SECRET_REDACT_PATHS, type Signer, type SolFeeEstimate, SolanaPaymentStrategy, type SubCloser, type SubmitJobOptions, type VerifyOptions, type VerifyResult, aggregateNetworkStats, assertExpiry, assertLamports, buildPaymentInstructions, calculateProtocolFee, classifyJobError, clearPriorityFeeCache, clearProtocolConfigCache, clearQuickVerifyCache, compareAgentsByRank, computeRankKey, createPaymentRequestWithOnchainConfig, decodeJobPayload, encodeJobPayload, estimateNetworkBaseline, estimatePriorityFeeMicroLamports, estimateSolFeeLamports, formatFeeBreakdown, formatNetworkBaseline, formatSol, getNetworkStats, getProtocolConfig, getProtocolProgramId, jobRequestKind, jobResultKind, makeCensor, nip44Decrypt, nip44Encrypt, parsePaymentRequest, pickPercentileFee, timeAgo, toDTag, truncateKey, utf8ByteLength, validateAgentName, validateExpiry, verifyJobPaymentQuick };