@agirails/sdk 2.0.4 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/README.md +536 -87
  2. package/dist/adapters/BasicAdapter.d.ts.map +1 -1
  3. package/dist/adapters/BasicAdapter.js +8 -0
  4. package/dist/adapters/BasicAdapter.js.map +1 -1
  5. package/dist/adapters/StandardAdapter.d.ts +10 -5
  6. package/dist/adapters/StandardAdapter.d.ts.map +1 -1
  7. package/dist/adapters/StandardAdapter.js +19 -6
  8. package/dist/adapters/StandardAdapter.js.map +1 -1
  9. package/dist/config/networks.d.ts +9 -0
  10. package/dist/config/networks.d.ts.map +1 -1
  11. package/dist/config/networks.js +25 -10
  12. package/dist/config/networks.js.map +1 -1
  13. package/dist/index.d.ts +6 -1
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +31 -1
  16. package/dist/index.js.map +1 -1
  17. package/dist/level0/provide.d.ts.map +1 -1
  18. package/dist/level0/provide.js +2 -1
  19. package/dist/level0/provide.js.map +1 -1
  20. package/dist/level1/Agent.d.ts.map +1 -1
  21. package/dist/level1/Agent.js +11 -3
  22. package/dist/level1/Agent.js.map +1 -1
  23. package/dist/protocol/ACTPKernel.d.ts.map +1 -1
  24. package/dist/protocol/ACTPKernel.js +7 -5
  25. package/dist/protocol/ACTPKernel.js.map +1 -1
  26. package/dist/protocol/DIDResolver.js +1 -1
  27. package/dist/protocol/DIDResolver.js.map +1 -1
  28. package/dist/protocol/EASHelper.d.ts.map +1 -1
  29. package/dist/protocol/EASHelper.js +2 -3
  30. package/dist/protocol/EASHelper.js.map +1 -1
  31. package/dist/protocol/MessageSigner.d.ts.map +1 -1
  32. package/dist/protocol/MessageSigner.js +8 -8
  33. package/dist/protocol/MessageSigner.js.map +1 -1
  34. package/dist/runtime/BlockchainRuntime.d.ts +7 -0
  35. package/dist/runtime/BlockchainRuntime.d.ts.map +1 -1
  36. package/dist/runtime/BlockchainRuntime.js +38 -22
  37. package/dist/runtime/BlockchainRuntime.js.map +1 -1
  38. package/dist/runtime/IACTPRuntime.d.ts +15 -0
  39. package/dist/runtime/IACTPRuntime.d.ts.map +1 -1
  40. package/dist/runtime/MockRuntime.d.ts +7 -0
  41. package/dist/runtime/MockRuntime.d.ts.map +1 -1
  42. package/dist/runtime/MockRuntime.js +15 -4
  43. package/dist/runtime/MockRuntime.js.map +1 -1
  44. package/dist/runtime/types/MockState.d.ts +5 -2
  45. package/dist/runtime/types/MockState.d.ts.map +1 -1
  46. package/dist/runtime/types/MockState.js.map +1 -1
  47. package/dist/storage/ArchiveBundleBuilder.d.ts +150 -0
  48. package/dist/storage/ArchiveBundleBuilder.d.ts.map +1 -0
  49. package/dist/storage/ArchiveBundleBuilder.js +468 -0
  50. package/dist/storage/ArchiveBundleBuilder.js.map +1 -0
  51. package/dist/storage/ArweaveClient.d.ts +271 -0
  52. package/dist/storage/ArweaveClient.d.ts.map +1 -0
  53. package/dist/storage/ArweaveClient.js +761 -0
  54. package/dist/storage/ArweaveClient.js.map +1 -0
  55. package/dist/storage/FilebaseClient.d.ts +193 -0
  56. package/dist/storage/FilebaseClient.d.ts.map +1 -0
  57. package/dist/storage/FilebaseClient.js +643 -0
  58. package/dist/storage/FilebaseClient.js.map +1 -0
  59. package/dist/storage/index.d.ts +47 -0
  60. package/dist/storage/index.d.ts.map +1 -0
  61. package/dist/storage/index.js +64 -0
  62. package/dist/storage/index.js.map +1 -0
  63. package/dist/storage/types.d.ts +291 -0
  64. package/dist/storage/types.d.ts.map +1 -0
  65. package/dist/storage/types.js +18 -0
  66. package/dist/storage/types.js.map +1 -0
  67. package/dist/types/state.d.ts +5 -4
  68. package/dist/types/state.d.ts.map +1 -1
  69. package/dist/types/state.js +10 -9
  70. package/dist/types/state.js.map +1 -1
  71. package/dist/utils/IPFSClient.d.ts.map +1 -1
  72. package/dist/utils/IPFSClient.js +5 -2
  73. package/dist/utils/IPFSClient.js.map +1 -1
  74. package/dist/utils/NonceManager.d.ts.map +1 -1
  75. package/dist/utils/NonceManager.js +3 -2
  76. package/dist/utils/NonceManager.js.map +1 -1
  77. package/dist/utils/UsedAttestationTracker.d.ts.map +1 -1
  78. package/dist/utils/UsedAttestationTracker.js +3 -3
  79. package/dist/utils/UsedAttestationTracker.js.map +1 -1
  80. package/dist/utils/circuitBreaker.d.ts +136 -0
  81. package/dist/utils/circuitBreaker.d.ts.map +1 -0
  82. package/dist/utils/circuitBreaker.js +253 -0
  83. package/dist/utils/circuitBreaker.js.map +1 -0
  84. package/dist/utils/retry.d.ts +120 -0
  85. package/dist/utils/retry.d.ts.map +1 -0
  86. package/dist/utils/retry.js +260 -0
  87. package/dist/utils/retry.js.map +1 -0
  88. package/dist/utils/validation.d.ts +100 -0
  89. package/dist/utils/validation.d.ts.map +1 -1
  90. package/dist/utils/validation.js +248 -1
  91. package/dist/utils/validation.js.map +1 -1
  92. package/package.json +14 -2
  93. package/src/adapters/BasicAdapter.ts +11 -0
  94. package/src/adapters/StandardAdapter.ts +26 -6
  95. package/src/config/networks.ts +34 -10
  96. package/src/index.ts +54 -0
  97. package/src/level0/provide.ts +2 -1
  98. package/src/level1/Agent.ts +13 -3
  99. package/src/protocol/ACTPKernel.ts +7 -5
  100. package/src/protocol/DIDResolver.ts +1 -1
  101. package/src/protocol/EASHelper.ts +2 -5
  102. package/src/protocol/MessageSigner.ts +8 -14
  103. package/src/runtime/BlockchainRuntime.ts +39 -45
  104. package/src/runtime/IACTPRuntime.ts +16 -0
  105. package/src/runtime/MockRuntime.ts +16 -4
  106. package/src/runtime/types/MockState.ts +5 -2
  107. package/src/storage/ArchiveBundleBuilder.ts +563 -0
  108. package/src/storage/ArweaveClient.ts +945 -0
  109. package/src/storage/FilebaseClient.ts +790 -0
  110. package/src/storage/index.ts +96 -0
  111. package/src/storage/types.ts +348 -0
  112. package/src/types/state.ts +10 -9
  113. package/src/utils/IPFSClient.ts +5 -4
  114. package/src/utils/NonceManager.ts +3 -2
  115. package/src/utils/UsedAttestationTracker.ts +3 -5
  116. package/src/utils/circuitBreaker.ts +324 -0
  117. package/src/utils/fsSafe.ts +5 -0
  118. package/src/utils/retry.ts +365 -0
  119. package/src/utils/validation.ts +295 -1
@@ -0,0 +1,643 @@
1
+ "use strict";
2
+ /**
3
+ * FilebaseClient - IPFS Storage via Filebase S3 API (AIP-7 §4.2)
4
+ *
5
+ * Provides S3-compatible IPFS pinning via Filebase.
6
+ * Used for hot storage of request metadata and delivery proofs.
7
+ *
8
+ * Security Features (Post-Audit):
9
+ * - Gateway URL whitelist (SSRF protection)
10
+ * - Download size limits (DoS protection)
11
+ * - Credential sanitization in errors
12
+ * - Retry with exponential backoff
13
+ * - Circuit breaker for gateway health tracking
14
+ *
15
+ * @module storage/FilebaseClient
16
+ */
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.FilebaseClient = void 0;
19
+ const client_s3_1 = require("@aws-sdk/client-s3");
20
+ const errors_1 = require("../errors");
21
+ const validation_1 = require("../utils/validation");
22
+ const retry_1 = require("../utils/retry");
23
+ const circuitBreaker_1 = require("../utils/circuitBreaker");
24
+ // ============================================================================
25
+ // Constants
26
+ // ============================================================================
27
+ const DEFAULT_ENDPOINT = 'https://s3.filebase.com';
28
+ const DEFAULT_GATEWAY = 'https://ipfs.filebase.io/ipfs/';
29
+ const DEFAULT_BUCKET = 'agirails-storage';
30
+ const DEFAULT_TIMEOUT = 30000; // 30 seconds
31
+ const DEFAULT_MAX_FILE_SIZE = 100 * 1024 * 1024; // 100MB
32
+ const DEFAULT_MAX_DOWNLOAD_SIZE = 50 * 1024 * 1024; // 50MB (P1-1: DoS protection)
33
+ const DEFAULT_REGION = 'us-east-1';
34
+ // ============================================================================
35
+ // FilebaseClient Class
36
+ // ============================================================================
37
+ /**
38
+ * FilebaseClient - IPFS storage via Filebase S3 API
39
+ *
40
+ * Provides hot storage for:
41
+ * - AIP-1 request metadata
42
+ * - AIP-4 delivery proofs
43
+ * - Service descriptors
44
+ *
45
+ * @example
46
+ * ```typescript
47
+ * const client = new FilebaseClient({
48
+ * accessKey: process.env.FILEBASE_ACCESS_KEY!,
49
+ * secretKey: process.env.FILEBASE_SECRET_KEY!,
50
+ * bucket: 'my-agirails-bucket'
51
+ * });
52
+ *
53
+ * // Upload JSON
54
+ * const result = await client.uploadJSON({ message: 'Hello IPFS!' });
55
+ * console.log('CID:', result.cid);
56
+ *
57
+ * // Download JSON
58
+ * const data = await client.downloadJSON(result.cid);
59
+ * ```
60
+ */
61
+ class FilebaseClient {
62
+ /**
63
+ * Create a new FilebaseClient
64
+ *
65
+ * @param config - Filebase configuration
66
+ * @throws {ValidationError} If required config is missing or gateway URL not whitelisted
67
+ */
68
+ constructor(config) {
69
+ // Validate required config
70
+ if (!config.accessKey) {
71
+ throw new errors_1.ValidationError('accessKey', 'Filebase access key is required');
72
+ }
73
+ if (!config.secretKey) {
74
+ throw new errors_1.ValidationError('secretKey', 'Filebase secret key is required');
75
+ }
76
+ // P0-1: Validate gateway URL against whitelist (SSRF protection)
77
+ const gatewayUrl = config.gatewayUrl || DEFAULT_GATEWAY;
78
+ (0, validation_1.validateGatewayURL)(gatewayUrl, validation_1.ALLOWED_IPFS_GATEWAYS, 'gatewayUrl');
79
+ // Initialize S3 client
80
+ this.s3 = new client_s3_1.S3Client({
81
+ endpoint: config.endpoint || DEFAULT_ENDPOINT,
82
+ region: DEFAULT_REGION,
83
+ credentials: {
84
+ accessKeyId: config.accessKey,
85
+ secretAccessKey: config.secretKey
86
+ },
87
+ forcePathStyle: true // Required for S3-compatible services
88
+ });
89
+ this.bucket = config.bucket || DEFAULT_BUCKET;
90
+ this.gatewayUrl = gatewayUrl;
91
+ this.timeout = config.timeout || DEFAULT_TIMEOUT;
92
+ this.maxFileSize = config.maxFileSize || DEFAULT_MAX_FILE_SIZE;
93
+ this.maxDownloadSize = config.maxDownloadSize || DEFAULT_MAX_DOWNLOAD_SIZE;
94
+ // P1-2: Default retry options
95
+ this.retryOptions = {
96
+ maxAttempts: 3,
97
+ initialDelayMs: 1000,
98
+ maxDelayMs: 10000,
99
+ backoffMultiplier: 2
100
+ };
101
+ // Circuit breaker for gateway health tracking
102
+ this.circuitBreakerEnabled = config.circuitBreaker?.enabled !== false;
103
+ if (this.circuitBreakerEnabled) {
104
+ this.circuitBreaker = new circuitBreaker_1.GatewayCircuitBreaker({
105
+ failureThreshold: config.circuitBreaker?.failureThreshold,
106
+ resetTimeoutMs: config.circuitBreaker?.resetTimeoutMs,
107
+ failureWindowMs: config.circuitBreaker?.failureWindowMs,
108
+ successThreshold: config.circuitBreaker?.successThreshold
109
+ });
110
+ }
111
+ else {
112
+ this.circuitBreaker = null;
113
+ }
114
+ }
115
+ // ==========================================================================
116
+ // Public Methods
117
+ // ==========================================================================
118
+ /**
119
+ * Upload JSON to IPFS via Filebase (automatic pinning)
120
+ *
121
+ * @param data - JSON-serializable data to upload
122
+ * @param options - Upload options
123
+ * @returns Upload result with CID
124
+ * @throws {FileSizeLimitExceededError} If data exceeds max size
125
+ * @throws {StorageAuthenticationError} If credentials are invalid
126
+ * @throws {UploadTimeoutError} If upload times out
127
+ * @throws {StorageError} If upload fails
128
+ *
129
+ * @example
130
+ * ```typescript
131
+ * const result = await client.uploadJSON({
132
+ * version: '1.0.0',
133
+ * serviceType: 'text-generation',
134
+ * inputData: { prompt: 'Hello!' }
135
+ * });
136
+ * console.log('Uploaded to IPFS:', result.cid);
137
+ * ```
138
+ */
139
+ async uploadJSON(data, options) {
140
+ // Serialize to JSON
141
+ const jsonString = JSON.stringify(data);
142
+ const buffer = Buffer.from(jsonString, 'utf-8');
143
+ // Check file size
144
+ if (buffer.length > this.maxFileSize) {
145
+ throw new errors_1.FileSizeLimitExceededError(buffer.length, this.maxFileSize);
146
+ }
147
+ // Generate unique key if not provided
148
+ const key = options?.key || this.generateKey('.json');
149
+ try {
150
+ // Upload to Filebase (auto-pins to IPFS)
151
+ const command = new client_s3_1.PutObjectCommand({
152
+ Bucket: this.bucket,
153
+ Key: key,
154
+ Body: buffer,
155
+ ContentType: 'application/json',
156
+ Metadata: options?.metadata
157
+ });
158
+ const response = await this.withTimeout(this.s3.send(command), this.timeout, 'upload');
159
+ // Extract CID from response headers
160
+ // Filebase returns CID in x-amz-meta-cid header
161
+ const cid = response.$metadata?.httpStatusCode === 200
162
+ ? await this.getCIDFromKey(key)
163
+ : undefined;
164
+ if (!cid) {
165
+ throw new errors_1.StorageError('upload', 'Failed to retrieve CID after upload');
166
+ }
167
+ return {
168
+ cid,
169
+ size: buffer.length,
170
+ uploadedAt: new Date()
171
+ };
172
+ }
173
+ catch (error) {
174
+ // Handle specific errors
175
+ if (error instanceof errors_1.FileSizeLimitExceededError)
176
+ throw error;
177
+ if (error instanceof errors_1.UploadTimeoutError)
178
+ throw error;
179
+ if (error.name === 'CredentialsProviderError' || error.Code === 'InvalidAccessKeyId') {
180
+ throw new errors_1.StorageAuthenticationError('Filebase');
181
+ }
182
+ if (error.Code === 'SlowDown' || error.statusCode === 429) {
183
+ const retryAfter = error.$metadata?.httpHeaders?.['retry-after'];
184
+ throw new errors_1.StorageRateLimitError(retryAfter ? parseInt(retryAfter, 10) : undefined);
185
+ }
186
+ // P0-2: Sanitize error message (may contain AWS credentials)
187
+ throw new errors_1.StorageError('upload', (0, validation_1.sanitizeErrorMessage)(error), {
188
+ originalError: error.name,
189
+ key
190
+ });
191
+ }
192
+ }
193
+ /**
194
+ * Download JSON from IPFS via gateway
195
+ *
196
+ * Security Features:
197
+ * - Size limit enforcement (P1-1: DoS protection)
198
+ * - Retry with exponential backoff (P1-2)
199
+ * - Centralized CID validation (P1-3)
200
+ * - Credential sanitization in errors (P0-2)
201
+ *
202
+ * @param cid - IPFS CID to download
203
+ * @returns Downloaded and parsed JSON data
204
+ * @throws {InvalidCIDError} If CID format is invalid
205
+ * @throws {ContentNotFoundError} If content not found
206
+ * @throws {FileSizeLimitExceededError} If content exceeds size limit
207
+ * @throws {DownloadTimeoutError} If download times out
208
+ * @throws {StorageError} If download fails
209
+ *
210
+ * @example
211
+ * ```typescript
212
+ * const data = await client.downloadJSON('bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi');
213
+ * console.log('Downloaded:', data);
214
+ * ```
215
+ */
216
+ async downloadJSON(cid) {
217
+ // P1-3: Use centralized CID validation
218
+ (0, validation_1.validateCID)(cid);
219
+ const url = `${this.gatewayUrl}${cid}`;
220
+ // Circuit breaker: check gateway health before attempting download
221
+ if (this.circuitBreaker && !this.circuitBreaker.isHealthy(this.gatewayUrl)) {
222
+ const state = this.circuitBreaker.getState(this.gatewayUrl);
223
+ const failures = this.circuitBreaker.getFailureCount(this.gatewayUrl);
224
+ throw new errors_1.StorageError('download', `Gateway circuit breaker OPEN for ${this.gatewayUrl}. ` +
225
+ `State: ${state}, Failures: ${failures}. ` +
226
+ `Please wait for cooldown period before retrying.`, { cid, circuitState: state });
227
+ }
228
+ // P1-2: Wrap in retry logic
229
+ return (0, retry_1.withRetry)(async () => {
230
+ const controller = new AbortController();
231
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
232
+ try {
233
+ const response = await fetch(url, {
234
+ signal: controller.signal,
235
+ headers: {
236
+ 'Accept': 'application/json'
237
+ }
238
+ });
239
+ clearTimeout(timeoutId);
240
+ if (!response.ok) {
241
+ if (response.status === 404) {
242
+ throw new errors_1.ContentNotFoundError(cid);
243
+ }
244
+ throw new errors_1.StorageError('download', `HTTP ${response.status}: ${response.statusText}`, { cid });
245
+ }
246
+ // P1-1: Check Content-Length header before downloading
247
+ const contentLength = response.headers.get('content-length');
248
+ if (contentLength && parseInt(contentLength, 10) > this.maxDownloadSize) {
249
+ throw new errors_1.FileSizeLimitExceededError(parseInt(contentLength, 10), this.maxDownloadSize);
250
+ }
251
+ // P1-1: Stream response with size limit enforcement
252
+ const reader = response.body?.getReader();
253
+ if (!reader) {
254
+ throw new errors_1.StorageError('download', 'No response body', { cid });
255
+ }
256
+ const chunks = [];
257
+ let totalSize = 0;
258
+ while (true) {
259
+ const { done, value } = await reader.read();
260
+ if (done)
261
+ break;
262
+ totalSize += value.length;
263
+ // P1-1: Enforce size limit during streaming
264
+ if (totalSize > this.maxDownloadSize) {
265
+ reader.cancel();
266
+ throw new errors_1.FileSizeLimitExceededError(totalSize, this.maxDownloadSize);
267
+ }
268
+ chunks.push(value);
269
+ }
270
+ // Combine chunks into text
271
+ const decoder = new TextDecoder();
272
+ const text = chunks.map(chunk => decoder.decode(chunk, { stream: true })).join('') +
273
+ decoder.decode();
274
+ const data = JSON.parse(text);
275
+ // Circuit breaker: record success
276
+ if (this.circuitBreaker) {
277
+ this.circuitBreaker.recordSuccess(this.gatewayUrl);
278
+ }
279
+ return {
280
+ data,
281
+ size: totalSize,
282
+ downloadedAt: new Date()
283
+ };
284
+ }
285
+ catch (error) {
286
+ clearTimeout(timeoutId);
287
+ // Circuit breaker: record failure for retryable errors
288
+ // (non-retryable errors like 404 shouldn't count as gateway failures)
289
+ if (this.circuitBreaker && this.isGatewayFailure(error)) {
290
+ this.circuitBreaker.recordFailure(this.gatewayUrl);
291
+ }
292
+ if (error instanceof errors_1.ContentNotFoundError)
293
+ throw error;
294
+ if (error instanceof errors_1.FileSizeLimitExceededError)
295
+ throw error;
296
+ if (error.name === 'AbortError') {
297
+ throw new errors_1.DownloadTimeoutError(cid, this.timeout);
298
+ }
299
+ if (error instanceof SyntaxError) {
300
+ throw new errors_1.StorageError('download', `Invalid JSON content for CID: ${cid}`, { cid });
301
+ }
302
+ // P0-2: Sanitize error message
303
+ throw new errors_1.StorageError('download', (0, validation_1.sanitizeErrorMessage)(error), {
304
+ cid,
305
+ originalError: error.name
306
+ });
307
+ }
308
+ }, this.retryOptions);
309
+ }
310
+ /**
311
+ * Upload binary data to IPFS
312
+ *
313
+ * @param data - Binary data to upload
314
+ * @param contentType - MIME type of the content
315
+ * @param options - Upload options
316
+ * @returns Upload result with CID
317
+ */
318
+ async uploadBinary(data, contentType, options) {
319
+ const buffer = Buffer.from(data);
320
+ // Check file size
321
+ if (buffer.length > this.maxFileSize) {
322
+ throw new errors_1.FileSizeLimitExceededError(buffer.length, this.maxFileSize);
323
+ }
324
+ // Generate key with appropriate extension
325
+ const extension = this.getExtensionFromContentType(contentType);
326
+ const key = options?.key || this.generateKey(extension);
327
+ try {
328
+ const command = new client_s3_1.PutObjectCommand({
329
+ Bucket: this.bucket,
330
+ Key: key,
331
+ Body: buffer,
332
+ ContentType: contentType,
333
+ Metadata: options?.metadata
334
+ });
335
+ await this.withTimeout(this.s3.send(command), this.timeout, 'upload');
336
+ const cid = await this.getCIDFromKey(key);
337
+ if (!cid) {
338
+ throw new errors_1.StorageError('upload', 'Failed to retrieve CID after upload');
339
+ }
340
+ return {
341
+ cid,
342
+ size: buffer.length,
343
+ uploadedAt: new Date()
344
+ };
345
+ }
346
+ catch (error) {
347
+ if (error instanceof errors_1.FileSizeLimitExceededError)
348
+ throw error;
349
+ if (error instanceof errors_1.UploadTimeoutError)
350
+ throw error;
351
+ if (error instanceof errors_1.StorageError)
352
+ throw error;
353
+ // P0-2: Sanitize error message (may contain AWS credentials)
354
+ throw new errors_1.StorageError('upload', (0, validation_1.sanitizeErrorMessage)(error), {
355
+ originalError: error.name,
356
+ key
357
+ });
358
+ }
359
+ }
360
+ /**
361
+ * Download binary data from IPFS
362
+ *
363
+ * Security Features:
364
+ * - Size limit enforcement (P1-1: DoS protection)
365
+ * - Retry with exponential backoff (P1-2)
366
+ * - Centralized CID validation (P1-3)
367
+ *
368
+ * @param cid - IPFS CID to download
369
+ * @returns Downloaded binary data
370
+ */
371
+ async downloadBinary(cid) {
372
+ // P1-3: Use centralized CID validation
373
+ (0, validation_1.validateCID)(cid);
374
+ const url = `${this.gatewayUrl}${cid}`;
375
+ // Circuit breaker: check gateway health before attempting download
376
+ if (this.circuitBreaker && !this.circuitBreaker.isHealthy(this.gatewayUrl)) {
377
+ const state = this.circuitBreaker.getState(this.gatewayUrl);
378
+ const failures = this.circuitBreaker.getFailureCount(this.gatewayUrl);
379
+ throw new errors_1.StorageError('download', `Gateway circuit breaker OPEN for ${this.gatewayUrl}. ` +
380
+ `State: ${state}, Failures: ${failures}. ` +
381
+ `Please wait for cooldown period before retrying.`, { cid, circuitState: state });
382
+ }
383
+ // P1-2: Wrap in retry logic
384
+ return (0, retry_1.withRetry)(async () => {
385
+ const controller = new AbortController();
386
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
387
+ try {
388
+ const response = await fetch(url, { signal: controller.signal });
389
+ clearTimeout(timeoutId);
390
+ if (!response.ok) {
391
+ if (response.status === 404) {
392
+ throw new errors_1.ContentNotFoundError(cid);
393
+ }
394
+ throw new errors_1.StorageError('download', `HTTP ${response.status}: ${response.statusText}`, { cid });
395
+ }
396
+ // P1-1: Check Content-Length header before downloading
397
+ const contentLength = response.headers.get('content-length');
398
+ if (contentLength && parseInt(contentLength, 10) > this.maxDownloadSize) {
399
+ throw new errors_1.FileSizeLimitExceededError(parseInt(contentLength, 10), this.maxDownloadSize);
400
+ }
401
+ // P1-1: Stream response with size limit enforcement
402
+ const reader = response.body?.getReader();
403
+ if (!reader) {
404
+ throw new errors_1.StorageError('download', 'No response body', { cid });
405
+ }
406
+ const chunks = [];
407
+ let totalSize = 0;
408
+ while (true) {
409
+ const { done, value } = await reader.read();
410
+ if (done)
411
+ break;
412
+ totalSize += value.length;
413
+ // P1-1: Enforce size limit during streaming
414
+ if (totalSize > this.maxDownloadSize) {
415
+ reader.cancel();
416
+ throw new errors_1.FileSizeLimitExceededError(totalSize, this.maxDownloadSize);
417
+ }
418
+ chunks.push(value);
419
+ }
420
+ // Combine chunks into Buffer
421
+ const buffer = Buffer.concat(chunks);
422
+ // Circuit breaker: record success
423
+ if (this.circuitBreaker) {
424
+ this.circuitBreaker.recordSuccess(this.gatewayUrl);
425
+ }
426
+ return {
427
+ data: buffer,
428
+ size: buffer.length,
429
+ downloadedAt: new Date()
430
+ };
431
+ }
432
+ catch (error) {
433
+ clearTimeout(timeoutId);
434
+ // Circuit breaker: record failure for retryable errors
435
+ if (this.circuitBreaker && this.isGatewayFailure(error)) {
436
+ this.circuitBreaker.recordFailure(this.gatewayUrl);
437
+ }
438
+ if (error instanceof errors_1.ContentNotFoundError)
439
+ throw error;
440
+ if (error instanceof errors_1.FileSizeLimitExceededError)
441
+ throw error;
442
+ if (error.name === 'AbortError') {
443
+ throw new errors_1.DownloadTimeoutError(cid, this.timeout);
444
+ }
445
+ // P0-2: Sanitize error message
446
+ throw new errors_1.StorageError('download', (0, validation_1.sanitizeErrorMessage)(error), {
447
+ cid,
448
+ originalError: error.name
449
+ });
450
+ }
451
+ }, this.retryOptions);
452
+ }
453
+ /**
454
+ * Check if content exists on IPFS
455
+ *
456
+ * @param cid - IPFS CID to check
457
+ * @returns True if content exists
458
+ */
459
+ async exists(cid) {
460
+ // P1-3: Use centralized CID validation
461
+ (0, validation_1.validateCID)(cid);
462
+ const url = `${this.gatewayUrl}${cid}`;
463
+ try {
464
+ const controller = new AbortController();
465
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
466
+ const response = await fetch(url, {
467
+ method: 'HEAD',
468
+ signal: controller.signal
469
+ });
470
+ clearTimeout(timeoutId);
471
+ return response.ok;
472
+ }
473
+ catch {
474
+ return false;
475
+ }
476
+ }
477
+ /**
478
+ * Get the bucket name
479
+ */
480
+ getBucket() {
481
+ return this.bucket;
482
+ }
483
+ /**
484
+ * Get the gateway URL
485
+ */
486
+ getGatewayUrl() {
487
+ return this.gatewayUrl;
488
+ }
489
+ // ==========================================================================
490
+ // Private Methods
491
+ // ==========================================================================
492
+ /**
493
+ * Generate unique key for S3 object
494
+ */
495
+ generateKey(extension) {
496
+ const timestamp = Date.now();
497
+ const random = Math.random().toString(36).substring(2, 10);
498
+ return `${timestamp}-${random}${extension}`;
499
+ }
500
+ /**
501
+ * Get CID from uploaded object via HeadObject
502
+ * Filebase returns CID in x-amz-meta-cid header
503
+ */
504
+ async getCIDFromKey(key) {
505
+ try {
506
+ const command = new client_s3_1.HeadObjectCommand({
507
+ Bucket: this.bucket,
508
+ Key: key
509
+ });
510
+ const response = await this.s3.send(command);
511
+ // Filebase stores CID in metadata
512
+ return response.Metadata?.cid;
513
+ }
514
+ catch {
515
+ return undefined;
516
+ }
517
+ }
518
+ /**
519
+ * Get file extension from content type
520
+ */
521
+ getExtensionFromContentType(contentType) {
522
+ const types = {
523
+ 'application/json': '.json',
524
+ 'text/plain': '.txt',
525
+ 'image/png': '.png',
526
+ 'image/jpeg': '.jpg',
527
+ 'application/pdf': '.pdf',
528
+ 'application/octet-stream': '.bin'
529
+ };
530
+ return types[contentType] || '.bin';
531
+ }
532
+ /**
533
+ * Wrap promise with timeout
534
+ */
535
+ async withTimeout(promise, timeoutMs, operation) {
536
+ let timeoutId;
537
+ const timeoutPromise = new Promise((_, reject) => {
538
+ timeoutId = setTimeout(() => {
539
+ if (operation === 'upload') {
540
+ reject(new errors_1.UploadTimeoutError(timeoutMs));
541
+ }
542
+ else {
543
+ reject(new errors_1.DownloadTimeoutError('unknown', timeoutMs));
544
+ }
545
+ }, timeoutMs);
546
+ });
547
+ try {
548
+ return await Promise.race([promise, timeoutPromise]);
549
+ }
550
+ finally {
551
+ clearTimeout(timeoutId);
552
+ }
553
+ }
554
+ /**
555
+ * Determine if an error represents a gateway failure
556
+ * (should be counted by circuit breaker)
557
+ *
558
+ * Gateway failures are network/server errors that indicate
559
+ * the gateway is unhealthy. Content-specific errors (404, invalid JSON)
560
+ * are NOT gateway failures.
561
+ *
562
+ * @param error - Error to check
563
+ * @returns true if error is a gateway failure
564
+ */
565
+ isGatewayFailure(error) {
566
+ if (!error)
567
+ return false;
568
+ const e = error;
569
+ // 404 Not Found - content doesn't exist, not a gateway failure
570
+ if (error instanceof errors_1.ContentNotFoundError)
571
+ return false;
572
+ // File size exceeded - content too large, not a gateway failure
573
+ if (error instanceof errors_1.FileSizeLimitExceededError)
574
+ return false;
575
+ // Invalid JSON - content is corrupted, not a gateway failure
576
+ if (error instanceof SyntaxError)
577
+ return false;
578
+ // Timeout - gateway is slow/unresponsive, IS a failure
579
+ if (e.name === 'AbortError' || e.name === 'TimeoutError')
580
+ return true;
581
+ // 5xx server errors - gateway issue
582
+ if (e.status >= 500 && e.status < 600)
583
+ return true;
584
+ if (e.statusCode >= 500 && e.statusCode < 600)
585
+ return true;
586
+ // Network errors - gateway unreachable
587
+ const networkErrors = ['ECONNRESET', 'ECONNREFUSED', 'ETIMEDOUT', 'ENOTFOUND'];
588
+ if (e.code && networkErrors.includes(e.code))
589
+ return true;
590
+ // Rate limiting - gateway overloaded
591
+ if (e.status === 429 || e.statusCode === 429)
592
+ return true;
593
+ // Generic StorageError from network issues or HTTP errors
594
+ if (error instanceof errors_1.StorageError) {
595
+ const message = e.message?.toLowerCase() || '';
596
+ // Network-related errors
597
+ if (message.includes('timeout') ||
598
+ message.includes('network') ||
599
+ message.includes('connection')) {
600
+ return true;
601
+ }
602
+ // HTTP 5xx errors in message (e.g., "HTTP 500: Internal Server Error")
603
+ if (/http 5\d{2}/.test(message)) {
604
+ return true;
605
+ }
606
+ // HTTP 429 rate limiting in message
607
+ if (/http 429/.test(message)) {
608
+ return true;
609
+ }
610
+ }
611
+ return false;
612
+ }
613
+ // ==========================================================================
614
+ // Circuit Breaker Status (Public API)
615
+ // ==========================================================================
616
+ /**
617
+ * Get circuit breaker status for the gateway
618
+ *
619
+ * @returns Circuit breaker status or null if disabled
620
+ */
621
+ getCircuitBreakerStatus() {
622
+ if (!this.circuitBreaker) {
623
+ return null;
624
+ }
625
+ return {
626
+ enabled: true,
627
+ state: this.circuitBreaker.getState(this.gatewayUrl),
628
+ failures: this.circuitBreaker.getFailureCount(this.gatewayUrl),
629
+ isHealthy: this.circuitBreaker.isHealthy(this.gatewayUrl)
630
+ };
631
+ }
632
+ /**
633
+ * Reset circuit breaker for the gateway
634
+ * Use this to manually reset after a known temporary outage
635
+ */
636
+ resetCircuitBreaker() {
637
+ if (this.circuitBreaker) {
638
+ this.circuitBreaker.reset(this.gatewayUrl);
639
+ }
640
+ }
641
+ }
642
+ exports.FilebaseClient = FilebaseClient;
643
+ //# sourceMappingURL=FilebaseClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FilebaseClient.js","sourceRoot":"","sources":["../../src/storage/FilebaseClient.ts"],"names":[],"mappings":"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"}