@metanodejs/file-module 1.0.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.
@@ -0,0 +1,1276 @@
1
+ import z$1, { z } from 'zod';
2
+ import { MtnContract } from '@metanodejs/mtn-contract';
3
+ import { MarkOptional } from 'ts-essentials';
4
+ import { EventLog, DecodeAbi } from '@metanodejs/event-log';
5
+ import { Emitter, EventHandlerMap } from 'mitt';
6
+
7
+ declare const appConfig: {
8
+ file: string;
9
+ };
10
+
11
+ /**
12
+ * Interface for logging functionality, providing methods for different log levels.
13
+ */
14
+ interface LoggerPort {
15
+ /**
16
+ * Logs a message at the log level.
17
+ * @param message - The message to log.
18
+ * @param meta - Additional metadata to include in the log.
19
+ */
20
+ log(message: string, ...meta: unknown[]): void;
21
+ /**
22
+ * Logs a message at the error level.
23
+ * @param message - The error message to log.
24
+ * @param trace - Optional stack trace or additional error details.
25
+ * @param meta - Additional metadata to include in the log.
26
+ */
27
+ error(message: string, trace?: unknown, ...meta: unknown[]): void;
28
+ /**
29
+ * Logs a message at the warn level.
30
+ * @param message - The warning message to log.
31
+ * @param meta - Additional metadata to include in the log.
32
+ */
33
+ warn(message: string, ...meta: unknown[]): void;
34
+ /**
35
+ * Logs a message at the debug level.
36
+ * @param message - The debug message to log.
37
+ * @param meta - Additional metadata to include in the log.
38
+ */
39
+ debug(message: string, ...meta: unknown[]): void;
40
+ /**
41
+ * Logs a message at the info level.
42
+ * @param message - The info message to log.
43
+ * @param meta - Additional metadata to include in the log.
44
+ */
45
+ info(message: string, ...meta: unknown[]): void;
46
+ }
47
+
48
+ declare class Logger implements LoggerPort {
49
+ private readonly isDev;
50
+ private readonly prefix;
51
+ constructor(prefix?: string);
52
+ private formatMessage;
53
+ debug(...args: any[]): void;
54
+ info(...args: any[]): void;
55
+ warn(...args: any[]): void;
56
+ error(...args: any[]): void;
57
+ log(...args: any[]): void;
58
+ }
59
+ declare const logger: Logger;
60
+
61
+ type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'log';
62
+
63
+ interface IAbiItemBase {
64
+ internalType: string;
65
+ name: string;
66
+ type: string;
67
+ indexed: boolean;
68
+ [key: string]: any;
69
+ }
70
+ interface IAbiBase {
71
+ inputs: IAbiItemBase[];
72
+ name: string;
73
+ stateMutability?: string;
74
+ type: string;
75
+ [key: string]: any;
76
+ }
77
+ interface AbiData {
78
+ functionName: string;
79
+ outputs: IAbiBase['outputs'];
80
+ }
81
+ declare class DecodeAbiService {
82
+ #private;
83
+ constructor(abis: IAbiBase[]);
84
+ get abiArray(): [string, AbiData][];
85
+ getAbiData(raw: string): AbiData | undefined;
86
+ handleDecodeAbi(topic: string, raw: string): Promise<{
87
+ decodedData: unknown;
88
+ event: string;
89
+ } | undefined>;
90
+ }
91
+ declare const decodeAbiService: DecodeAbiService;
92
+
93
+ /**
94
+ * Giao diện định nghĩa các phương thức chung để xử lý các hoạt động blockchain,
95
+ * bao gồm xác thực dữ liệu và thực thi giao dịch với hợp đồng thông minh.
96
+ *
97
+ * @interface BlockchainRepositoryPort
98
+ */
99
+ interface BlockchainRepositoryPort {
100
+ /**
101
+ * Xác thực dữ liệu yêu cầu bằng schema Zod.
102
+ *
103
+ * @param schema - Schema Zod để xác thực dữ liệu.
104
+ * @param data - Dữ liệu cần xác thực.
105
+ * @returns Dữ liệu đã được xác thực.
106
+ * @throws {ArgumentNotProvidedException} Nếu dữ liệu là null, undefined hoặc đối tượng rỗng.
107
+ * @throws {ArgumentInvalidException} Nếu dữ liệu không thỏa mãn schema.
108
+ */
109
+ validateRequest<T>(schema: z.ZodSchema<T>, data: unknown): T;
110
+ /**
111
+ * Thực thi giao dịch blockchain với cơ chế retry.
112
+ *
113
+ * @param params - Tham số giao dịch bao gồm địa chỉ, dữ liệu đầu vào, tên hàm, ABI và số lần thử lại.
114
+ * @returns Kết quả giao dịch.
115
+ * @throws {InternalServerErrorException} Nếu giao dịch thất bại sau số lần thử lại.
116
+ */
117
+ executeTransaction<T>(params: {
118
+ to: string;
119
+ from: string;
120
+ inputData: unknown;
121
+ functionName: string;
122
+ feeType: string;
123
+ abiData: unknown;
124
+ retries?: number;
125
+ }): Promise<T>;
126
+ }
127
+
128
+ /**
129
+ * Schema để xác thực một chuỗi hex 32 bytes (bytes32 trong Solidity).
130
+ * Chuỗi phải chứa chính xác 64 ký tự hex (0-9, a-f, A-F), có thể có hoặc không có tiền tố "0x".
131
+ *
132
+ * @example
133
+ * "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef" // Hợp lệ
134
+ * "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef" // Hợp lệ
135
+ * "0x123" // Không hợp lệ (quá ngắn)
136
+ * "0xGHI" // Không hợp lệ (không phải hex)
137
+ */
138
+ declare const Bytes32Schema: z.ZodString;
139
+ type Bytes32DTO = z.infer<typeof Bytes32Schema>;
140
+ /**
141
+ * Schema để xác thực địa chỉ Ethereum (40 ký tự hex, tùy chọn "0x").
142
+ * Hỗ trợ kiểm tra checksum EIP-55 nếu cần.
143
+ *
144
+ * @example
145
+ * "0x1234567890abcdef1234567890abcdef12345678" // Hợp lệ
146
+ * "1234567890abcdef1234567890abcdef12345678" // Hợp lệ
147
+ * "0x123" // Không hợp lệ (quá ngắn)
148
+ * "0xGHI" // Không hợp lệ (không phải hex)
149
+ */
150
+ declare const AddressSchema: z.ZodString;
151
+ type AddressDTO = z.infer<typeof AddressSchema>;
152
+ /**
153
+ * Schema để xác thực khóa công khai không nén (128 ký tự hex, tương ứng 64 bytes).
154
+ *
155
+ * @example
156
+ * "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef" // Hợp lệ
157
+ * "0x123" // Không hợp lệ (quá ngắn)
158
+ * "0xGHI" // Không hợp lệ (không phải hex)
159
+ */
160
+ declare const PublicKeySchema: z.ZodString;
161
+ type PublicKeyDTO = z.infer<typeof PublicKeySchema>;
162
+ /**
163
+ * Schema để xác thực và chuyển đổi timestamp từ chuỗi thành số nguyên không âm.
164
+ * Dùng để xử lý các giá trị timestamp trả về từ hợp đồng thông minh (ví dụ: "1698765432").
165
+ *
166
+ * @example
167
+ * ```typescript
168
+ * TimestampSchema.parse("1698765432") // Kết quả: 1698765432
169
+ * TimestampSchema.parse("abc") // Lỗi: "Timestamp phải là chuỗi số nguyên không âm"
170
+ * ```
171
+ */
172
+ declare const TimestampSchema: z.ZodPipe<z.ZodString, z.ZodTransform<number, string>>;
173
+ type TimestampDTO = z.infer<typeof TimestampSchema>;
174
+ /**
175
+ * Schema cơ bản cho các yêu cầu blockchain, chứa địa chỉ người gửi và hợp đồng đích (tùy chọn).
176
+ *
177
+ * @example
178
+ * ```typescript
179
+ * {
180
+ * from: "0x1234567890abcdef1234567890abcdef12345678",
181
+ * to: "0xabcdef1234567890abcdef1234567890abcdef12" // Tùy chọn
182
+ * }
183
+ * ```
184
+ */
185
+ declare const BaseRequestSchema: z.ZodObject<{
186
+ from: z.ZodString;
187
+ to: z.ZodOptional<z.ZodString>;
188
+ }, z.core.$strip>;
189
+ type BaseRequestDTO = z.infer<typeof BaseRequestSchema>;
190
+
191
+ /**
192
+ * Lớp cơ sở trừu tượng để xử lý các hoạt động blockchain, cung cấp các phương thức chung để xác thực,
193
+ * thực thi giao dịch và ghi log. Các lớp con như FileBlockchainRepository
194
+ * có thể kế thừa để triển khai các tác vụ cụ thể như upload file hoặc download file.
195
+ *
196
+ * @class BlockchainRepositoryBase
197
+ * @extends {MtnContract}
198
+ * @implements {BlockchainRepositoryPort}
199
+ */
200
+ declare abstract class BlockchainRepositoryBase extends MtnContract implements BlockchainRepositoryPort {
201
+ protected readonly logger: LoggerPort;
202
+ /**
203
+ * Khởi tạo BlockchainRepositoryBase với địa chỉ hợp đồng và logger.
204
+ *
205
+ * @param to - Địa chỉ hợp đồng blockchain.
206
+ * @param logger - Đối tượng logger để ghi log các sự kiện và lỗi.
207
+ * @throws {ArgumentInvalidException} Nếu địa chỉ hợp đồng không hợp lệ.
208
+ */
209
+ protected constructor(to: AddressDTO, logger: LoggerPort);
210
+ /**
211
+ * Xác thực dữ liệu yêu cầu bằng schema Zod.
212
+ *
213
+ * @param schema - Schema Zod để xác thực dữ liệu.
214
+ * @param data - Dữ liệu cần xác thực.
215
+ * @returns Dữ liệu đã được xác thực.
216
+ * @throws {ArgumentNotProvidedException} Nếu dữ liệu là null, undefined hoặc đối tượng rỗng.
217
+ * @throws {ArgumentInvalidException} Nếu dữ liệu không thỏa mãn schema.
218
+ */
219
+ validateRequest<T>(schema: z$1.ZodSchema<T>, data: unknown): T;
220
+ /**
221
+ * Thực thi giao dịch blockchain với cơ chế retry.
222
+ *
223
+ * @param params - Tham số giao dịch bao gồm địa chỉ, dữ liệu đầu vào, tên hàm, ABI và số lần thử lại.
224
+ * @returns Kết quả giao dịch.
225
+ * @throws {InternalServerErrorException} Nếu giao dịch thất bại sau số lần thử lại.
226
+ */
227
+ executeTransaction<T>(params: {
228
+ to?: string;
229
+ from: string;
230
+ inputData?: unknown;
231
+ functionName: string;
232
+ feeType: string;
233
+ abiData: unknown;
234
+ value?: string | bigint;
235
+ }): Promise<T>;
236
+ }
237
+
238
+ declare const CalculatePriceRequestSchema: z$1.ZodObject<{
239
+ from: z$1.ZodString;
240
+ to: z$1.ZodOptional<z$1.ZodString>;
241
+ numChunks: z$1.ZodNumber;
242
+ }, z$1.core.$strip>;
243
+ type CalculatePriceRequestDTO = z$1.infer<typeof CalculatePriceRequestSchema>;
244
+ declare const CalculatePriceResponseSchema: z$1.ZodString;
245
+ type CalculatePriceResponseDTO = z$1.infer<typeof CalculatePriceResponseSchema>;
246
+
247
+ declare const PushFileInfoRequestSchema: z$1.ZodObject<{
248
+ from: z$1.ZodString;
249
+ to: z$1.ZodOptional<z$1.ZodString>;
250
+ info: z$1.ZodObject<{
251
+ owner: z$1.ZodString;
252
+ merkleRoot: z$1.ZodString;
253
+ contentLen: z$1.ZodNumber;
254
+ totalChunks: z$1.ZodNumber;
255
+ expireTime: z$1.ZodNumber;
256
+ name: z$1.ZodString;
257
+ ext: z$1.ZodString;
258
+ contentDisposition: z$1.ZodString;
259
+ contentID: z$1.ZodString;
260
+ status: z$1.ZodNumber;
261
+ }, z$1.core.$strip>;
262
+ value: z$1.ZodString;
263
+ }, z$1.core.$strip>;
264
+ type PushFileInfoRequestDTO = z$1.infer<typeof PushFileInfoRequestSchema>;
265
+ declare const PushFileInfoResponseSchema: z$1.ZodObject<{
266
+ fileKey: z$1.ZodString;
267
+ }, z$1.core.$strip>;
268
+ type PushFileInfoResponseDTO = z$1.infer<typeof PushFileInfoResponseSchema>;
269
+
270
+ declare const UploadChunkRequestSchema: z$1.ZodObject<{
271
+ from: z$1.ZodString;
272
+ to: z$1.ZodOptional<z$1.ZodString>;
273
+ fileKey: z$1.ZodString;
274
+ chunkData: z$1.ZodString;
275
+ chunkIndex: z$1.ZodNumber;
276
+ merkleProof: z$1.ZodArray<z$1.ZodString>;
277
+ }, z$1.core.$strip>;
278
+ type UploadChunkRequestDTO = z$1.infer<typeof UploadChunkRequestSchema>;
279
+ type UploadChunkResponseDTO = void;
280
+
281
+ declare const GetFileInfoRequestSchema: z$1.ZodObject<{
282
+ from: z$1.ZodString;
283
+ to: z$1.ZodOptional<z$1.ZodString>;
284
+ fileKey: z$1.ZodString;
285
+ }, z$1.core.$strip>;
286
+ type GetFileInfoRequestDTO = z$1.infer<typeof GetFileInfoRequestSchema>;
287
+ declare const GetFileInfoResponseSchema: z$1.ZodObject<{
288
+ owner: z$1.ZodString;
289
+ merkleRoot: z$1.ZodString;
290
+ contentLen: z$1.ZodNumber;
291
+ totalChunks: z$1.ZodNumber;
292
+ expireTime: z$1.ZodNumber;
293
+ name: z$1.ZodString;
294
+ ext: z$1.ZodString;
295
+ contentDisposition: z$1.ZodString;
296
+ contentID: z$1.ZodString;
297
+ status: z$1.ZodNumber;
298
+ }, z$1.core.$strip>;
299
+ type GetFileInfoResponseDTO = z$1.infer<typeof GetFileInfoResponseSchema>;
300
+
301
+ declare const PayForDownloadRequestSchema: z$1.ZodObject<{
302
+ from: z$1.ZodString;
303
+ to: z$1.ZodOptional<z$1.ZodString>;
304
+ fileKey: z$1.ZodString;
305
+ downloadTimes: z$1.ZodNumber;
306
+ value: z$1.ZodString;
307
+ }, z$1.core.$strip>;
308
+ type PayForDownloadRequestDTO = z$1.infer<typeof PayForDownloadRequestSchema>;
309
+ declare const PayForDownloadResponseSchema: z$1.ZodObject<{
310
+ transactionHash: z$1.ZodOptional<z$1.ZodString>;
311
+ }, z$1.core.$strip>;
312
+ type PayForDownloadResponseDTO = z$1.infer<typeof PayForDownloadResponseSchema>;
313
+
314
+ declare const ConfirmServerDownloadRequestSchema: z$1.ZodObject<{
315
+ from: z$1.ZodString;
316
+ to: z$1.ZodOptional<z$1.ZodString>;
317
+ downloadKey: z$1.ZodString;
318
+ }, z$1.core.$strip>;
319
+ type ConfirmServerDownloadRequestDTO = z$1.infer<typeof ConfirmServerDownloadRequestSchema>;
320
+ declare const ConfirmServerDownloadResponseSchema: z$1.ZodString;
321
+ type ConfirmServerDownloadResponseDTO = z$1.infer<typeof ConfirmServerDownloadResponseSchema>;
322
+
323
+ declare const GetRustServerAddressesRequestSchema: z$1.ZodObject<{
324
+ from: z$1.ZodString;
325
+ to: z$1.ZodOptional<z$1.ZodString>;
326
+ }, z$1.core.$strip>;
327
+ type GetRustServerAddressesRequestDTO = z$1.infer<typeof GetRustServerAddressesRequestSchema>;
328
+ declare const GetRustServerAddressesResponseSchema: z$1.ZodArray<z$1.ZodString>;
329
+ type GetRustServerAddressesResponseDTO = z$1.infer<typeof GetRustServerAddressesResponseSchema>;
330
+
331
+ declare const SetPublicStatusRequestSchema: z.ZodObject<{
332
+ from: z.ZodString;
333
+ to: z.ZodOptional<z.ZodString>;
334
+ fileKey: z.ZodString;
335
+ status: z.ZodBoolean;
336
+ }, z.core.$strip>;
337
+ type SetPublicStatusRequestDTO = z.infer<typeof SetPublicStatusRequestSchema>;
338
+ type SetPublicStatusResponseDTO = void;
339
+
340
+ declare const AddWhitelistRequestSchema: z.ZodObject<{
341
+ from: z.ZodString;
342
+ to: z.ZodOptional<z.ZodString>;
343
+ fileKey: z.ZodString;
344
+ users: z.ZodArray<z.ZodString>;
345
+ }, z.core.$strip>;
346
+ type AddWhitelistRequestDTO = z.infer<typeof AddWhitelistRequestSchema>;
347
+ type AddWhitelistResponseDTO = void;
348
+
349
+ declare const GetWhitelistRequestSchema: z.ZodObject<{
350
+ from: z.ZodString;
351
+ to: z.ZodOptional<z.ZodString>;
352
+ fileKey: z.ZodString;
353
+ }, z.core.$strip>;
354
+ type GetWhitelistRequestDTO = z.infer<typeof GetWhitelistRequestSchema>;
355
+ type GetWhitelistResponseDTO = string[];
356
+
357
+ declare const IsPublicFileRequestSchema: z.ZodObject<{
358
+ from: z.ZodString;
359
+ to: z.ZodOptional<z.ZodString>;
360
+ fileKey: z.ZodString;
361
+ }, z.core.$strip>;
362
+ type IsPublicFileRequestDTO = z.infer<typeof IsPublicFileRequestSchema>;
363
+ type IsPublicFileResponseDTO = boolean;
364
+
365
+ interface FileBlockchainRepositoryPort {
366
+ calculatePrice(request: CalculatePriceRequestDTO): Promise<CalculatePriceResponseDTO>;
367
+ pushFileInfo(request: PushFileInfoRequestDTO): Promise<PushFileInfoResponseDTO>;
368
+ uploadChunk(request: UploadChunkRequestDTO): Promise<UploadChunkResponseDTO>;
369
+ getFileInfo(request: GetFileInfoRequestDTO): Promise<GetFileInfoResponseDTO>;
370
+ payForDownload(request: PayForDownloadRequestDTO): Promise<PayForDownloadResponseDTO>;
371
+ confirmServerDownload(request: ConfirmServerDownloadRequestDTO): Promise<ConfirmServerDownloadResponseDTO>;
372
+ getRustServerAddresses(request: GetRustServerAddressesRequestDTO): Promise<GetRustServerAddressesResponseDTO>;
373
+ setPublicStatus(request: SetPublicStatusRequestDTO): Promise<SetPublicStatusResponseDTO>;
374
+ addWhitelist(request: AddWhitelistRequestDTO): Promise<AddWhitelistResponseDTO>;
375
+ getWhitelist(request: GetWhitelistRequestDTO): Promise<GetWhitelistResponseDTO>;
376
+ isPublicFile(request: IsPublicFileRequestDTO): Promise<IsPublicFileResponseDTO>;
377
+ }
378
+
379
+ declare class FileBlockchainRepository extends BlockchainRepositoryBase implements FileBlockchainRepositoryPort {
380
+ constructor();
381
+ calculatePrice(request: CalculatePriceRequestDTO): Promise<CalculatePriceResponseDTO>;
382
+ pushFileInfo(request: PushFileInfoRequestDTO): Promise<PushFileInfoResponseDTO>;
383
+ uploadChunk(request: UploadChunkRequestDTO): Promise<UploadChunkResponseDTO>;
384
+ getFileInfo(request: GetFileInfoRequestDTO): Promise<GetFileInfoResponseDTO>;
385
+ payForDownload(request: PayForDownloadRequestDTO): Promise<PayForDownloadResponseDTO>;
386
+ confirmServerDownload(request: ConfirmServerDownloadRequestDTO): Promise<ConfirmServerDownloadResponseDTO>;
387
+ getRustServerAddresses(request: GetRustServerAddressesRequestDTO): Promise<GetRustServerAddressesResponseDTO>;
388
+ setPublicStatus(request: SetPublicStatusRequestDTO): Promise<SetPublicStatusResponseDTO>;
389
+ addWhitelist(request: AddWhitelistRequestDTO): Promise<AddWhitelistResponseDTO>;
390
+ getWhitelist(request: GetWhitelistRequestDTO): Promise<GetWhitelistResponseDTO>;
391
+ isPublicFile(request: IsPublicFileRequestDTO): Promise<IsPublicFileResponseDTO>;
392
+ }
393
+ declare const fileBlockchainRepository: FileBlockchainRepository;
394
+
395
+ declare const calculatePriceAbi: {
396
+ inputs: {
397
+ internalType: string;
398
+ name: string;
399
+ type: string;
400
+ }[];
401
+ name: string;
402
+ outputs: {
403
+ internalType: string;
404
+ name: string;
405
+ type: string;
406
+ }[];
407
+ stateMutability: string;
408
+ type: string;
409
+ }[];
410
+
411
+ declare const confirmServerDownloadAbi: {
412
+ inputs: {
413
+ internalType: string;
414
+ name: string;
415
+ type: string;
416
+ }[];
417
+ name: string;
418
+ outputs: never[];
419
+ stateMutability: string;
420
+ type: string;
421
+ }[];
422
+
423
+ declare const getFileInfoAbi: {
424
+ inputs: {
425
+ internalType: string;
426
+ name: string;
427
+ type: string;
428
+ }[];
429
+ name: string;
430
+ outputs: {
431
+ components: {
432
+ internalType: string;
433
+ name: string;
434
+ type: string;
435
+ }[];
436
+ internalType: string;
437
+ name: string;
438
+ type: string;
439
+ }[];
440
+ stateMutability: string;
441
+ type: string;
442
+ }[];
443
+
444
+ declare const GetRustServerAddressesAbi: {
445
+ inputs: never[];
446
+ name: string;
447
+ outputs: {
448
+ internalType: string;
449
+ name: string;
450
+ type: string;
451
+ }[];
452
+ stateMutability: string;
453
+ type: string;
454
+ }[];
455
+
456
+ declare const payForDownloadAbi: {
457
+ inputs: {
458
+ internalType: string;
459
+ name: string;
460
+ type: string;
461
+ }[];
462
+ name: string;
463
+ outputs: never[];
464
+ stateMutability: string;
465
+ type: string;
466
+ }[];
467
+
468
+ declare const pushFileInfoAbi: {
469
+ inputs: {
470
+ components: {
471
+ internalType: string;
472
+ name: string;
473
+ type: string;
474
+ }[];
475
+ internalType: string;
476
+ name: string;
477
+ type: string;
478
+ }[];
479
+ name: string;
480
+ outputs: {
481
+ internalType: string;
482
+ name: string;
483
+ type: string;
484
+ }[];
485
+ stateMutability: string;
486
+ type: string;
487
+ }[];
488
+
489
+ declare const uploadChunkAbi: {
490
+ inputs: {
491
+ internalType: string;
492
+ name: string;
493
+ type: string;
494
+ }[];
495
+ name: string;
496
+ outputs: never[];
497
+ stateMutability: string;
498
+ type: string;
499
+ }[];
500
+
501
+ declare const setPublicStatusAbi: {
502
+ inputs: {
503
+ internalType: string;
504
+ name: string;
505
+ type: string;
506
+ }[];
507
+ name: string;
508
+ outputs: never[];
509
+ stateMutability: string;
510
+ type: string;
511
+ }[];
512
+
513
+ declare const addWhitelistAbi: {
514
+ inputs: {
515
+ internalType: string;
516
+ name: string;
517
+ type: string;
518
+ }[];
519
+ name: string;
520
+ outputs: never[];
521
+ stateMutability: string;
522
+ type: string;
523
+ }[];
524
+
525
+ declare const getWhitelistAbi: {
526
+ inputs: {
527
+ internalType: string;
528
+ name: string;
529
+ type: string;
530
+ }[];
531
+ name: string;
532
+ outputs: {
533
+ internalType: string;
534
+ name: string;
535
+ type: string;
536
+ }[];
537
+ stateMutability: string;
538
+ type: string;
539
+ }[];
540
+
541
+ declare const isPublicFileAbi: {
542
+ inputs: {
543
+ internalType: string;
544
+ name: string;
545
+ type: string;
546
+ }[];
547
+ name: string;
548
+ outputs: {
549
+ internalType: string;
550
+ name: string;
551
+ type: string;
552
+ }[];
553
+ stateMutability: string;
554
+ type: string;
555
+ }[];
556
+
557
+ type EntityId = string | number
558
+ type StringEnum<T> = T | (string & Record<never, never>)
559
+
560
+ declare module '@metanodejs/event-log' {
561
+ export class DecodeAbi {
562
+ registerAbi(abi: any): Promise<void>
563
+ }
564
+ export class EventLog<T> {
565
+ constructor(decodeAbi: DecodeAbi)
566
+ registerEvent(from: string, to: string[]): Promise<void>
567
+ onEventLog(callback: (event: any) => void): () => void
568
+ }
569
+ }
570
+
571
+ declare class UniqueEntityID {
572
+ protected readonly id: EntityId;
573
+ constructor(_id?: EntityId);
574
+ equals(_id?: UniqueEntityID): boolean;
575
+ toString(): string;
576
+ toValue(): EntityId;
577
+ }
578
+
579
+ interface BaseEntityProps {
580
+ id: UniqueEntityID;
581
+ createdAt: Date;
582
+ updatedAt: Date;
583
+ }
584
+ interface CreateEntityProps<T> extends MarkOptional<BaseEntityProps, 'createdAt' | 'updatedAt'> {
585
+ props: T;
586
+ }
587
+ declare abstract class Entity<Props> {
588
+ #private;
589
+ constructor({ id, props, createdAt, updatedAt }: CreateEntityProps<Props>);
590
+ static isEntity(entity: unknown): entity is Entity<unknown>;
591
+ get id(): UniqueEntityID;
592
+ get createdAt(): Date;
593
+ get updatedAt(): Date;
594
+ getProps(): Props & BaseEntityProps;
595
+ protected getMutableProps(): Props;
596
+ /**
597
+ * Convert an Entity and all sub-entities/Value Objects it
598
+ * contains to a plain object with primitive types. Can be
599
+ * useful when logging an entity during testing/debugging
600
+ */
601
+ toObject(): any;
602
+ /**
603
+ * Each entity must have some validate/business rules
604
+ * This method is called every time before save this entity to the database
605
+ */
606
+ abstract validate(): void;
607
+ }
608
+
609
+ interface Mapper<DomainEntity extends Entity<unknown>, DbRecord, Response = unknown> {
610
+ toPersistence(entity: DomainEntity): DbRecord;
611
+ toDomain(record: DbRecord): DomainEntity;
612
+ toResponse(entity: DomainEntity): Response;
613
+ }
614
+
615
+ type NumericValue = number | string | bigint;
616
+ type EventMap = {
617
+ DownloadKeyGenerated: {
618
+ downloadKey: string;
619
+ fileKey: string;
620
+ user: string;
621
+ amount: NumericValue;
622
+ };
623
+ FileActivated: {
624
+ user: string;
625
+ fileKey: string;
626
+ };
627
+ };
628
+
629
+ declare class EventLogs {
630
+ private static instance;
631
+ private readonly _decodeAbi;
632
+ private readonly _eventLog;
633
+ private _abiRegistrationPromise;
634
+ private _registeredEvents;
635
+ private constructor();
636
+ static getInstance(): EventLogs;
637
+ get eventLog(): EventLog<EventMap>;
638
+ get decodeAbi(): DecodeAbi;
639
+ registerAbi(): Promise<void>;
640
+ registerEvent(userAddress: string, contractAddress: string): Promise<void>;
641
+ }
642
+ declare const eventLogs: EventLogs;
643
+
644
+ interface UseCase<Request, Response> {
645
+ execute(request?: Request): Promise<Response> | Response;
646
+ }
647
+
648
+ interface EventLogData {
649
+ type: string;
650
+ payload: any;
651
+ }
652
+ interface IEventLogRepository {
653
+ registerEvent(from: string, to: string | string[]): Promise<void>;
654
+ onEventLog(callback: (data: EventLogData) => void): () => void;
655
+ }
656
+
657
+ interface DecodedAbiResult {
658
+ decodedData: Record<string, unknown>;
659
+ event: string;
660
+ }
661
+ interface IDecodeAbiRepository {
662
+ decodeAbi(hash: string, raw: string): Promise<DecodedAbiResult>;
663
+ registerAbi?(abiEvents: any[]): Promise<void>;
664
+ }
665
+
666
+ type DomainEventMetadata = {
667
+ /** Timestamp when this domain event occurred */
668
+ readonly timestamp: number;
669
+ /** ID for correlation purposes (for Integration Events,logs correlation, etc).
670
+ */
671
+ readonly correlationId?: string | undefined;
672
+ /**
673
+ * Causation id used to reconstruct execution order if needed
674
+ */
675
+ readonly causationId?: string | undefined;
676
+ };
677
+ type IDomainEvent<T> = Omit<T, 'id' | '_metadata' | 'eventName'> & {
678
+ _metadata: DomainEventMetadata;
679
+ aggregateId: UniqueEntityID;
680
+ };
681
+ declare abstract class DomainEvent {
682
+ readonly id: UniqueEntityID;
683
+ readonly aggregateId: UniqueEntityID;
684
+ readonly _metadata: DomainEventMetadata;
685
+ abstract eventName: string;
686
+ constructor(domainEvent: IDomainEvent<unknown>);
687
+ }
688
+
689
+ type EmitDomainEvents = any;
690
+
691
+ interface AsyncEventBus extends Emitter<EmitDomainEvents> {
692
+ emitAsync<Key extends keyof EmitDomainEvents>(type: Key, event: EmitDomainEvents[Key]): Promise<void>;
693
+ }
694
+ declare function createMittAsync(all?: EventHandlerMap<EmitDomainEvents>): AsyncEventBus;
695
+ declare const emitter: AsyncEventBus;
696
+
697
+ declare abstract class AggregateRoot<Props> extends Entity<Props> {
698
+ #private;
699
+ get domainEvents(): readonly DomainEvent[];
700
+ protected addEvent(event: DomainEvent | DomainEvent[]): void;
701
+ clearEvents(): void;
702
+ /**
703
+ * Publish tất cả domain events qua AsyncEventBus
704
+ * - Logger để debug
705
+ * - await cho từng handler async
706
+ */
707
+ publishEvents(logger: LoggerPort, emitter: AsyncEventBus): Promise<void>;
708
+ }
709
+
710
+ /**
711
+ * Domain Primitive is an object that contains only a single value
712
+ */
713
+ type Primitives = string | number | boolean;
714
+ interface DomainPrimitive<T extends Primitives | Date> {
715
+ value: T;
716
+ }
717
+ type ValueObjectProps<T> = T extends Primitives | Date ? DomainPrimitive<T> : T;
718
+ declare abstract class ValueObject<Props> {
719
+ #private;
720
+ protected readonly props: ValueObjectProps<Props>;
721
+ constructor(props: ValueObjectProps<Props>);
722
+ protected abstract validate(props: ValueObjectProps<Props>): void;
723
+ static isValueObject(obj: unknown): obj is ValueObject<unknown>;
724
+ equals(vo?: ValueObject<Props>): boolean;
725
+ /**
726
+ * Convert value obj to get raw properties
727
+ */
728
+ raw(): any;
729
+ }
730
+
731
+ interface RepositoryPorts<Entity> {
732
+ save(entity: Entity): Promise<void>;
733
+ update(id: string, entity: Partial<Entity>): Promise<void>;
734
+ delete(id: string): Promise<void>;
735
+ findById(id: string): Promise<Entity | null>;
736
+ findAll(): Promise<Entity[]>;
737
+ clear(): Promise<void>;
738
+ findByField<K extends keyof Entity>(field: K, entity: Entity): Promise<Entity[]>;
739
+ }
740
+
741
+ interface NormalizedException {
742
+ message: string;
743
+ code: string;
744
+ correlationId: string;
745
+ stack?: string | undefined;
746
+ cause?: string | undefined;
747
+ /**
748
+ * ^ Consider adding optional `metadata` object to
749
+ * exceptions (if language doesn't support anything
750
+ * similar by default) and pass some useful technical
751
+ * information about the exception when throwing.
752
+ * This will make debugging easier.
753
+ */
754
+ metadata?: Record<string, unknown> | undefined;
755
+ }
756
+ declare abstract class ExceptionBase extends Error {
757
+ readonly message: string;
758
+ readonly metadata?: Record<string, unknown> | undefined;
759
+ abstract code: string;
760
+ readonly correlationId: string;
761
+ /**
762
+ * @param {string} message
763
+ * @param {ObjectLiteral} [metadata={}]
764
+ * **BE CAREFUL** not to include sensitive info in 'metadata'
765
+ * to prevent leaks since all exception's data will end up
766
+ * in application's log files. Only include non-sensitive
767
+ * info that may help with debugging.
768
+ */
769
+ constructor(message: string, metadata?: Record<string, unknown> | undefined);
770
+ toJSON(): NormalizedException;
771
+ }
772
+
773
+ /**
774
+ * Adding a `code` string with a custom status code for every
775
+ * exception is a good practice.
776
+ *
777
+ * Since when that exception is transferred to another process `instanceof`
778
+ * check cannot be performed anymore so a `code` string is used instead.
779
+ *
780
+ * Code constants can be stored in a separate file so they
781
+ * can be shared and reused on a receiving side (code sharing is
782
+ * useful when developing fullstack apps or microservices)
783
+ */
784
+ declare const ARGUMENT_INVALID = "GENERIC.ARGUMENT_INVALID";
785
+ declare const ARGUMENT_OUT_OF_RANGE = "GENERIC.ARGUMENT_OUT_OF_RANGE";
786
+ declare const ARGUMENT_NOT_PROVIDED = "GENERIC.ARGUMENT_NOT_PROVIDED";
787
+ declare const NOT_FOUND = "GENERIC.NOT_FOUND";
788
+ declare const CONFLICT = "GENERIC.CONFLICT";
789
+ declare const INTERNAL_SERVER_ERROR = "GENERIC.INTERNAL_SERVER_ERROR";
790
+
791
+ /**
792
+ * Used to indicate that an argument was not provided (is empty object/array, null of undefined).
793
+ *
794
+ * @class ArgumentNotProvidedException
795
+ * @extends {ExceptionBase}
796
+ */
797
+ declare class ArgumentNotProvidedException extends ExceptionBase {
798
+ readonly code = "GENERIC.ARGUMENT_NOT_PROVIDED";
799
+ }
800
+ /**
801
+ * Used to indicate that an incorrect argument was provided to a method/function/class constructor
802
+ *
803
+ * @class ArgumentInvalidException
804
+ * @extends {ExceptionBase}
805
+ */
806
+ declare class ArgumentInvalidException extends ExceptionBase {
807
+ readonly code = "GENERIC.ARGUMENT_INVALID";
808
+ }
809
+ /**
810
+ * Used to indicate that an argument is out of allowed range
811
+ * (for example: incorrect string/array length, number not in allowed min/max range etc)
812
+ *
813
+ * @class ArgumentOutOfRangeException
814
+ * @extends {ExceptionBase}
815
+ */
816
+ declare class ArgumentOutOfRangeException extends ExceptionBase {
817
+ readonly code = "GENERIC.ARGUMENT_OUT_OF_RANGE";
818
+ }
819
+ /**
820
+ * Used to indicate conflicting entities (usually in the database)
821
+ *
822
+ * @class ConflictException
823
+ * @extends {ExceptionBase}
824
+ */
825
+ declare class ConflictException extends ExceptionBase {
826
+ readonly code = "GENERIC.CONFLICT";
827
+ }
828
+ /**
829
+ * Used to indicate that entity is not found
830
+ *
831
+ * @class NotFoundException
832
+ * @extends {ExceptionBase}
833
+ */
834
+ declare class NotFoundException extends ExceptionBase {
835
+ readonly code = "GENERIC.NOT_FOUND";
836
+ }
837
+ /**
838
+ * Used to indicate an internal server error that does not fall under all other errors
839
+ *
840
+ * @class InternalServerErrorException
841
+ * @extends {ExceptionBase}
842
+ */
843
+ declare class InternalServerErrorException extends ExceptionBase {
844
+ readonly code = "GENERIC.INTERNAL_SERVER_ERROR";
845
+ }
846
+
847
+ declare function isValidAddress(address: string): boolean;
848
+ declare function isValidPublicKey(publicKey: string): boolean;
849
+
850
+ /**
851
+ * You just increase the length if necessary to improve performance
852
+ * Attention to the security(id is key)
853
+ *
854
+ * Characters Length Total States
855
+ * UUID 16 32 16^32 = 3.4e+38
856
+ * Base58 58 22 58^22 = 6.2e+38
857
+ * ---------------------------------------------------------
858
+ * Length Example Total States
859
+ * nanoid(8) re6ZkUUV 1.3e+14
860
+ * nanoid(12) pfpPYdZGbZvw 1.4e+21
861
+ * nanoid(16) sFDUZScHfZTfkLwk 1.6e+28
862
+ * nanoid(24) u7vzXJL9cGqUeabGPAZ5XUJ6 2.1e+42
863
+ * nanoid(32) qkvPDeH6JyAsRhaZ3X4ZLDPSLFP7MnJz 2.7e+56
864
+ *
865
+ * See @https://unkey.dev/blog/uuid-ux
866
+ */
867
+ declare const generateId: (size?: number) => string;
868
+ declare const DEFAULT_PREFIX_ID_LENGTH = 22;
869
+ declare const ENTITY_ID_LENGTH = 25;
870
+ declare function generatePrefixId(prefix?: string, length?: number): string;
871
+
872
+ /**
873
+ * Converts Entity/Value Objects props to a plain object.
874
+ * Useful for testing and debugging.
875
+ * @param props
876
+ */
877
+ declare function convertPropsToObject(props: any): any;
878
+
879
+ type InvariantMessage = string | (() => string) | Error;
880
+ declare function invariant(condition: any, message?: InvariantMessage): asserts condition;
881
+
882
+ declare function isNotNull<T>(v: T | null): v is Exclude<T, null>;
883
+ declare function isArray<T = unknown>(val: any): val is T[];
884
+ declare function isPrimitive(value: unknown): boolean;
885
+ declare const isDef: <T = any>(val?: T) => val is T;
886
+ declare const isUndef: <T = any>(val?: T) => val is T;
887
+ declare const isBoolean: (val: any) => val is boolean;
888
+ declare const isFunction: (val: any) => boolean;
889
+ declare const isNumber: (val: any) => val is number;
890
+ declare const isString: (val: unknown) => val is string;
891
+ declare const isObject: (val: any) => val is object;
892
+ declare const isMap: (val: unknown) => val is Map<any, any>;
893
+ declare const isSet: (val: unknown) => val is Set<any>;
894
+ declare const isDate: (val: unknown) => val is Date;
895
+ declare const isSymbol: (val: unknown) => val is symbol;
896
+ declare const isPromise: <T = any>(val: unknown) => val is Promise<T>;
897
+ declare const isFalsy: (val: any) => val is false | undefined | null;
898
+ declare const isWindow: (val: any) => boolean;
899
+ declare const isStream: (val: any) => boolean;
900
+ declare const isBrowser: boolean;
901
+ /**
902
+ * Check a value is empty or not
903
+ * Currently not support check WeakMap/WeakSet/WeakRef
904
+ */
905
+ declare function isEmpty<T = unknown>(val: T): val is T;
906
+ declare function isNotEmpty<T = unknown>(val: T): val is T;
907
+ /**
908
+ * Use for case you validate multiple values is not empty
909
+ *
910
+ * @param {any} args any arguments
911
+ * @returns {boolean} will return true if all value is not empty
912
+ */
913
+ declare function isNotEmpties(...args: any[]): boolean;
914
+ /**
915
+ * Use for case you validate multiple values is not empty
916
+ * @param args
917
+ */
918
+ declare function isEmpties(...args: any[]): boolean;
919
+ /**
920
+ * {@link} https://en.wikipedia.org/wiki/Portable_Network_Graphics
921
+ *
922
+ * @param {Buffer | Uint8Array} buffer Input is a buffer
923
+ * @returns {boolean} return true if the input is a PNG Image
924
+ */
925
+ declare function isPngImage(buffer: Buffer | Uint8Array): boolean;
926
+ declare const isAndroid: boolean;
927
+ declare const isMobile: boolean | undefined;
928
+ declare const isCrawler: boolean;
929
+
930
+ declare function delay(ms: number): Promise<void>;
931
+
932
+ declare function humanFileSize(bytes: number, si?: boolean, dp?: number): string;
933
+
934
+ declare function generateRandomHex(length: number): string;
935
+
936
+ declare const fulfilledPromises: <T extends Promise<any>>(promises: T[]) => Promise<Awaited<T>[]>;
937
+ declare function formatSize(bytes: number): string;
938
+
939
+ declare const UploadFileRequestSchema: z$1.ZodObject<{
940
+ file: z$1.ZodCustom<File, File>;
941
+ from: z$1.ZodString;
942
+ chunkSize: z$1.ZodDefault<z$1.ZodOptional<z$1.ZodNumber>>;
943
+ }, z$1.core.$strip>;
944
+ type UploadFileRequestDTO = z$1.infer<typeof UploadFileRequestSchema>;
945
+ declare const UploadFileResponseSchema: z$1.ZodObject<{
946
+ fileKey: z$1.ZodString;
947
+ merkleRoot: z$1.ZodString;
948
+ totalChunks: z$1.ZodNumber;
949
+ }, z$1.core.$strip>;
950
+ type UploadFileResponseDTO = z$1.infer<typeof UploadFileResponseSchema>;
951
+
952
+ declare const DownloadFileRequestSchema: z$1.ZodObject<{
953
+ fileKey: z$1.ZodString;
954
+ from: z$1.ZodString;
955
+ downloadTimes: z$1.ZodDefault<z$1.ZodOptional<z$1.ZodNumber>>;
956
+ }, z$1.core.$strip>;
957
+ type DownloadFileRequestDTO = z$1.infer<typeof DownloadFileRequestSchema>;
958
+ declare const DownloadFileResponseSchema: z$1.ZodObject<{
959
+ fileData: z$1.ZodCustom<Uint8Array<ArrayBuffer>, Uint8Array<ArrayBuffer>>;
960
+ fileName: z$1.ZodString;
961
+ fileExt: z$1.ZodString;
962
+ }, z$1.core.$strip>;
963
+ type DownloadFileResponseDTO = z$1.infer<typeof DownloadFileResponseSchema>;
964
+
965
+ interface SetPublicStatusUseCaseRequestDTO {
966
+ from: string;
967
+ fileKey: string;
968
+ status: boolean;
969
+ }
970
+ type SetPublicStatusUseCaseResponseDTO = void;
971
+ interface AddWhitelistUseCaseRequestDTO {
972
+ from: string;
973
+ fileKey: string;
974
+ users: string[];
975
+ }
976
+ type AddWhitelistUseCaseResponseDTO = void;
977
+ interface GetWhitelistUseCaseRequestDTO {
978
+ from: string;
979
+ fileKey: string;
980
+ }
981
+ type GetWhitelistUseCaseResponseDTO = string[];
982
+ interface IsPublicFileUseCaseRequestDTO {
983
+ from: string;
984
+ fileKey: string;
985
+ }
986
+ type IsPublicFileUseCaseResponseDTO = boolean;
987
+
988
+ /**
989
+ * File Activated Listener Service
990
+ *
991
+ * Service lắng nghe event FileActivated và cung cấp confirmation
992
+ * khi file đã được activate sau khi upload hết chunks
993
+ */
994
+ interface FileActivatedProvider {
995
+ waitForFileActivated(fileKey: string, timeout?: number): Promise<{
996
+ fileKey: string;
997
+ user: string;
998
+ }>;
999
+ }
1000
+ declare class FileActivatedListenerService implements FileActivatedProvider {
1001
+ private activatedFiles;
1002
+ private pendingRequests;
1003
+ private unsubscribe;
1004
+ private isInitialized;
1005
+ constructor();
1006
+ initialize(userAddress: string, contractAddress: string): Promise<void>;
1007
+ /**
1008
+ * Bắt đầu lắng nghe event FileActivated
1009
+ */
1010
+ private startListening;
1011
+ /**
1012
+ * Xử lý event FileActivated
1013
+ */
1014
+ private handleFileActivated;
1015
+ /**
1016
+ * Normalize fileKey để so sánh (remove 0x prefix, lowercase, pad)
1017
+ */
1018
+ private normalizeFileKey;
1019
+ /**
1020
+ * Đợi FileActivated event cho fileKey
1021
+ */
1022
+ waitForFileActivated(fileKey: string, timeout?: number): Promise<{
1023
+ fileKey: string;
1024
+ user: string;
1025
+ }>;
1026
+ /**
1027
+ * Dọn dẹp và dừng lắng nghe
1028
+ */
1029
+ stop(): void;
1030
+ /**
1031
+ * Clear cache (có thể dùng để test hoặc reset)
1032
+ */
1033
+ clearCache(): void;
1034
+ }
1035
+
1036
+ declare class UploadFileUseCase {
1037
+ private readonly fileBlockchainRepository;
1038
+ private readonly fileActivatedProvider?;
1039
+ constructor(fileBlockchainRepository: FileBlockchainRepositoryPort, fileActivatedProvider?: FileActivatedProvider | undefined);
1040
+ execute(request: UploadFileRequestDTO): Promise<UploadFileResponseDTO>;
1041
+ }
1042
+
1043
+ interface DownloadKeyProvider {
1044
+ getDownloadKey(fileKey: string, timeout?: number): Promise<{
1045
+ downloadKey: string;
1046
+ user: string;
1047
+ amount: string;
1048
+ }>;
1049
+ }
1050
+ declare class DownloadFileUseCase {
1051
+ private readonly fileBlockchainRepository;
1052
+ private readonly downloadKeyProvider;
1053
+ constructor(fileBlockchainRepository: FileBlockchainRepositoryPort, downloadKeyProvider: DownloadKeyProvider);
1054
+ execute(request: DownloadFileRequestDTO): Promise<DownloadFileResponseDTO>;
1055
+ }
1056
+
1057
+ declare class SetPublicStatusUseCase {
1058
+ private readonly fileBlockchainRepository;
1059
+ constructor(fileBlockchainRepository: FileBlockchainRepositoryPort);
1060
+ execute(request: SetPublicStatusUseCaseRequestDTO): Promise<SetPublicStatusUseCaseResponseDTO>;
1061
+ }
1062
+
1063
+ declare class AddWhitelistUseCase {
1064
+ private readonly fileBlockchainRepository;
1065
+ constructor(fileBlockchainRepository: FileBlockchainRepositoryPort);
1066
+ execute(request: AddWhitelistUseCaseRequestDTO): Promise<AddWhitelistUseCaseResponseDTO>;
1067
+ }
1068
+
1069
+ declare class GetWhitelistUseCase {
1070
+ private readonly fileBlockchainRepository;
1071
+ constructor(fileBlockchainRepository: FileBlockchainRepositoryPort);
1072
+ execute(request: GetWhitelistUseCaseRequestDTO): Promise<GetWhitelistUseCaseResponseDTO>;
1073
+ }
1074
+
1075
+ declare class IsPublicFileUseCase {
1076
+ private readonly fileBlockchainRepository;
1077
+ constructor(fileBlockchainRepository: FileBlockchainRepositoryPort);
1078
+ execute(request: IsPublicFileUseCaseRequestDTO): Promise<IsPublicFileUseCaseResponseDTO>;
1079
+ }
1080
+
1081
+ /**
1082
+ * File Repository Port
1083
+ * Interface cho file operations
1084
+ */
1085
+ interface IFileRepository extends FileBlockchainRepositoryPort {
1086
+ }
1087
+
1088
+ /**
1089
+ * Rust Server Client
1090
+ *
1091
+ * Kết nối và request chunks từ Rust Servers sử dụng Native QUIC Connection
1092
+ *
1093
+ * Implementation sử dụng native functions:
1094
+ * - connectQuicServer: Connect đến Rust server
1095
+ * - sendQuicMessage: Gửi message và nhận response
1096
+ * - disconnectQuicServer: Disconnect khi không dùng nữa
1097
+ * - Load Balancing: Chunk chẵn từ Server 1, chunk lẻ từ Server 2
1098
+ * - Retry logic khi request fail (max 3 lần)
1099
+ * - Không retry nếu lỗi chứa "to store chunk on disk" (đã thành công)
1100
+ */
1101
+ interface DownloadChunkPayload {
1102
+ file_key: string;
1103
+ download_key: string;
1104
+ chunk_index: number;
1105
+ signature: string;
1106
+ }
1107
+ interface DownloadChunkRequest {
1108
+ command: string;
1109
+ requestId?: string;
1110
+ chunkIndex?: number;
1111
+ totalChunks?: number;
1112
+ payload: DownloadChunkPayload;
1113
+ }
1114
+ interface DownloadResponse {
1115
+ status: string;
1116
+ message: string;
1117
+ chunk_data_base64?: string;
1118
+ chunkIndex?: number;
1119
+ requestId?: string;
1120
+ }
1121
+ declare class NativeQuicError extends Error {
1122
+ code: string;
1123
+ retryable: boolean;
1124
+ retryAfterMs?: number | undefined;
1125
+ constructor(code: string, retryable: boolean, retryAfterMs?: number | undefined, message?: string);
1126
+ }
1127
+ /**
1128
+ * Request chunk với automatic server selection và retry logic
1129
+ */
1130
+ declare function requestChunk(fileKey: string, downloadKey: string, chunkIndex: number, totalChunks: number, signature: string, serverAddresses: string[]): Promise<{
1131
+ chunkIndex: number;
1132
+ data: Uint8Array;
1133
+ }>;
1134
+ /**
1135
+ * Download all chunks using a worker pool concurrency model
1136
+ *
1137
+ * Chia chunks thành 2 nhóm (chẵn/lẻ) và download song song
1138
+ * - Chunks chẵn (0, 2, 4...) → Server 1
1139
+ * - Chunks lẻ (1, 3, 5...) → Server 2
1140
+ * - Tương tự Go code với Goroutines
1141
+ *
1142
+ * @param fileKey - File key
1143
+ * @param downloadKey - Download key from event
1144
+ * @param totalChunks - Total number of chunks
1145
+ * @param signature - Signature for authentication
1146
+ * @param onProgress - Callback for progress updates
1147
+ * @returns Array of chunks in correct order
1148
+ */
1149
+ declare function downloadAllChunks(fileKey: string, downloadKey: string, totalChunks: number, signature: string, from: string, onProgress?: (downloaded: number, total: number) => void): Promise<Uint8Array[]>;
1150
+ /**
1151
+ * Download all chunks and merge into single file
1152
+ *
1153
+ * @param fileKey - File key
1154
+ * @param downloadKey - Download key from event
1155
+ * @param totalChunks - Total number of chunks
1156
+ * @param signature - Signature for authentication
1157
+ * @param onProgress - Callback for progress updates
1158
+ * @returns Merged file as Uint8Array
1159
+ */
1160
+ declare function downloadAndMergeFile(fileKey: string, downloadKey: string, totalChunks: number, signature: string, from: string, onProgress?: (downloaded: number, total: number) => void): Promise<Uint8Array>;
1161
+
1162
+ /**
1163
+ * Download Key Listener Service
1164
+ *
1165
+ * Service lắng nghe event DownloadKeyGenerated và cung cấp downloadKey
1166
+ * khi được yêu cầu
1167
+ */
1168
+
1169
+ declare class DownloadKeyListenerService implements DownloadKeyProvider {
1170
+ private downloadKeys;
1171
+ private pendingRequests;
1172
+ private unsubscribe;
1173
+ private isInitialized;
1174
+ constructor();
1175
+ initialize(userAddress: string, contractAddress: string): Promise<void>;
1176
+ /**
1177
+ * Bắt đầu lắng nghe event DownloadKeyGenerated
1178
+ */
1179
+ private startListening;
1180
+ /**
1181
+ * Xử lý event DownloadKeyGenerated
1182
+ */
1183
+ private handleDownloadKeyGenerated;
1184
+ /**
1185
+ * Normalize fileKey để so sánh (remove 0x prefix, lowercase, pad)
1186
+ */
1187
+ private normalizeFileKey;
1188
+ /**
1189
+ * Lấy downloadKey cho fileKey
1190
+ */
1191
+ getDownloadKey(fileKey: string, timeout?: number): Promise<{
1192
+ downloadKey: string;
1193
+ user: string;
1194
+ amount: string;
1195
+ }>;
1196
+ /**
1197
+ * Dọn dẹp và dừng lắng nghe
1198
+ */
1199
+ stop(): void;
1200
+ /**
1201
+ * Clear cache (có thể dùng để test hoặc reset)
1202
+ */
1203
+ clearCache(): void;
1204
+ }
1205
+
1206
+ /**
1207
+ * File Module Container
1208
+ * Dependency injection container cho file module
1209
+ */
1210
+ declare class FileModuleContainer {
1211
+ private uploadFileUseCase;
1212
+ private downloadFileUseCase;
1213
+ private downloadKeyListenerService;
1214
+ private fileActivatedListenerService;
1215
+ private setPublicStatusUseCase;
1216
+ private addWhitelistUseCase;
1217
+ private getWhitelistUseCase;
1218
+ private isPublicFileUseCase;
1219
+ private initPromise;
1220
+ constructor(downloadKeyProvider?: DownloadKeyProvider, options?: {
1221
+ userAddress?: string;
1222
+ contractAddress?: string;
1223
+ });
1224
+ /**
1225
+ * Tạo DownloadKeyProvider mặc định sử dụng EventLog
1226
+ */
1227
+ private createDefaultDownloadKeyProvider;
1228
+ /**
1229
+ * Tạo FileActivatedProvider mặc định sử dụng EventLog
1230
+ */
1231
+ private createDefaultFileActivatedProvider;
1232
+ getUploadFileUseCase(): UploadFileUseCase;
1233
+ getDownloadFileUseCase(): DownloadFileUseCase;
1234
+ getSetPublicStatusUseCase(): SetPublicStatusUseCase;
1235
+ getAddWhitelistUseCase(): AddWhitelistUseCase;
1236
+ getGetWhitelistUseCase(): GetWhitelistUseCase;
1237
+ getIsPublicFileUseCase(): IsPublicFileUseCase;
1238
+ /**
1239
+ * Khởi tạo và đăng ký event với native
1240
+ * Cần gọi method này trước khi sử dụng download/upload để native biết gửi event về
1241
+ * @param userAddress Địa chỉ ví của user
1242
+ * @param contractAddress Địa chỉ contract file
1243
+ */
1244
+ initialize(userAddress: string, contractAddress: string): Promise<void>;
1245
+ /**
1246
+ * Dọn dẹp resources
1247
+ */
1248
+ cleanup(): void;
1249
+ }
1250
+ /**
1251
+ * Factory function để tạo file module container
1252
+ * Nếu không truyền downloadKeyProvider, sẽ tự động tạo DownloadKeyListenerService
1253
+ * @param downloadKeyProvider Optional custom provider
1254
+ * @param options Optional configuration: userAddress để tự động đăng ký events, contractAddress
1255
+ */
1256
+ declare function createFileModule(downloadKeyProvider?: DownloadKeyProvider, options?: {
1257
+ userAddress?: string;
1258
+ contractAddress?: string;
1259
+ }): FileModuleContainer;
1260
+
1261
+ declare const buildMerkleTreePadded: (chunks: Uint8Array[]) => Promise<[string[], string, string[][]]>;
1262
+ /**
1263
+ * Get Merkle proof sử dụng cached tree levels (không rebuild tree)
1264
+ * @param levels Các levels của Merkle tree đã được build (từ buildMerkleTreePadded)
1265
+ * @param index Index của leaf cần lấy proof
1266
+ */
1267
+ declare const getMerkleProofPadded: (levels: string[][], index: number) => Promise<string[]>;
1268
+ declare const verifyMerkleProof: (leafHash: string, proof: string[], root: string, index: number) => Promise<boolean>;
1269
+
1270
+ /**
1271
+ * Generate signature for downloadKey
1272
+ * Logic matches Go code: hash = Keccak256Hash("0x00" + downloadKey bytes)
1273
+ */
1274
+ declare function generateSignature(downloadKey: string, privateKey: string): Promise<string>;
1275
+
1276
+ export { ARGUMENT_INVALID, ARGUMENT_NOT_PROVIDED, ARGUMENT_OUT_OF_RANGE, type AddWhitelistRequestDTO, AddWhitelistRequestSchema, type AddWhitelistResponseDTO, AddWhitelistUseCase, type AddWhitelistUseCaseRequestDTO, type AddWhitelistUseCaseResponseDTO, type AddressDTO, AddressSchema, AggregateRoot, ArgumentInvalidException, ArgumentNotProvidedException, ArgumentOutOfRangeException, type AsyncEventBus, type BaseEntityProps, type BaseRequestDTO, BaseRequestSchema, BlockchainRepositoryBase, type BlockchainRepositoryPort, type Bytes32DTO, Bytes32Schema, CONFLICT, type CalculatePriceRequestDTO, CalculatePriceRequestSchema, type CalculatePriceResponseDTO, CalculatePriceResponseSchema, type ConfirmServerDownloadRequestDTO, ConfirmServerDownloadRequestSchema, type ConfirmServerDownloadResponseDTO, ConfirmServerDownloadResponseSchema, ConflictException, type CreateEntityProps, DEFAULT_PREFIX_ID_LENGTH, DecodeAbiService, type DecodedAbiResult, DomainEvent, type DomainPrimitive, type DownloadChunkPayload, type DownloadChunkRequest, type DownloadFileRequestDTO, DownloadFileRequestSchema, type DownloadFileResponseDTO, DownloadFileResponseSchema, DownloadFileUseCase, DownloadKeyListenerService, type DownloadKeyProvider, type DownloadResponse, ENTITY_ID_LENGTH, type EmitDomainEvents, Entity, type EntityId, type EventLogData, type EventMap, ExceptionBase, FileActivatedListenerService, type FileActivatedProvider, FileBlockchainRepository, type FileBlockchainRepositoryPort, FileModuleContainer, type GetFileInfoRequestDTO, GetFileInfoRequestSchema, type GetFileInfoResponseDTO, GetFileInfoResponseSchema, GetRustServerAddressesAbi, type GetRustServerAddressesRequestDTO, GetRustServerAddressesRequestSchema, type GetRustServerAddressesResponseDTO, GetRustServerAddressesResponseSchema, type GetWhitelistRequestDTO, GetWhitelistRequestSchema, type GetWhitelistResponseDTO, GetWhitelistUseCase, type GetWhitelistUseCaseRequestDTO, type GetWhitelistUseCaseResponseDTO, type IDecodeAbiRepository, type IDomainEvent, type IEventLogRepository, type IFileRepository, INTERNAL_SERVER_ERROR, InternalServerErrorException, type IsPublicFileRequestDTO, IsPublicFileRequestSchema, type IsPublicFileResponseDTO, IsPublicFileUseCase, type IsPublicFileUseCaseRequestDTO, type IsPublicFileUseCaseResponseDTO, type LogLevel, Logger, type LoggerPort, type Mapper, NOT_FOUND, NativeQuicError, type NormalizedException, NotFoundException, type PayForDownloadRequestDTO, PayForDownloadRequestSchema, type PayForDownloadResponseDTO, PayForDownloadResponseSchema, type Primitives, type PublicKeyDTO, PublicKeySchema, type PushFileInfoRequestDTO, PushFileInfoRequestSchema, type PushFileInfoResponseDTO, PushFileInfoResponseSchema, type RepositoryPorts, type SetPublicStatusRequestDTO, SetPublicStatusRequestSchema, type SetPublicStatusResponseDTO, SetPublicStatusUseCase, type SetPublicStatusUseCaseRequestDTO, type SetPublicStatusUseCaseResponseDTO, type StringEnum, type TimestampDTO, TimestampSchema, UniqueEntityID, type UploadChunkRequestDTO, UploadChunkRequestSchema, type UploadChunkResponseDTO, type UploadFileRequestDTO, UploadFileRequestSchema, type UploadFileResponseDTO, UploadFileResponseSchema, UploadFileUseCase, type UseCase, ValueObject, addWhitelistAbi, appConfig, buildMerkleTreePadded, calculatePriceAbi, confirmServerDownloadAbi, convertPropsToObject, createFileModule, createMittAsync, decodeAbiService, delay, downloadAllChunks, downloadAndMergeFile, emitter, eventLogs, fileBlockchainRepository, formatSize, fulfilledPromises, generateId, generatePrefixId, generateRandomHex, generateSignature, getFileInfoAbi, getMerkleProofPadded, getWhitelistAbi, humanFileSize, invariant, isAndroid, isArray, isBoolean, isBrowser, isCrawler, isDate, isDef, isEmpties, isEmpty, isFalsy, isFunction, isMap, isMobile, isNotEmpties, isNotEmpty, isNotNull, isNumber, isObject, isPngImage, isPrimitive, isPromise, isPublicFileAbi, isSet, isStream, isString, isSymbol, isUndef, isValidAddress, isValidPublicKey, isWindow, logger, payForDownloadAbi, pushFileInfoAbi, requestChunk, setPublicStatusAbi, uploadChunkAbi, verifyMerkleProof };