@otskit/client 0.1.3 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +50 -13
- package/dist/index.cjs +328 -84
- package/dist/index.d.cts +84 -16
- package/dist/index.d.ts +84 -16
- package/dist/index.js +323 -84
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -39,6 +39,8 @@ interface ResilienceOptions {
|
|
|
39
39
|
connectTimeoutMs: number;
|
|
40
40
|
retries: RetryOptions;
|
|
41
41
|
circuitBreaker: CircuitBreakerOptions;
|
|
42
|
+
/** Límite de bytes para el body de la respuesta. Default 100 KB. */
|
|
43
|
+
maxResponseBytes?: number;
|
|
42
44
|
}
|
|
43
45
|
/** Client configuration options */
|
|
44
46
|
interface ClientOptions {
|
|
@@ -52,19 +54,51 @@ interface ClientOptions {
|
|
|
52
54
|
signal?: AbortSignal;
|
|
53
55
|
/** Minimum successful calendar submissions required (default: 2) */
|
|
54
56
|
minimumSuccessfulSubmissions?: number;
|
|
57
|
+
/**
|
|
58
|
+
* Permite URLs de calendario que resuelven a IPs privadas/reservadas.
|
|
59
|
+
*
|
|
60
|
+
* **No activar en producción.** Útil para testing local o redes corporativas.
|
|
61
|
+
*
|
|
62
|
+
* Incluso con `false`, la protección es best-effort contra DNS rebinding (TOCTOU).
|
|
63
|
+
* Para alta seguridad, complementar con egress filtering a nivel de red.
|
|
64
|
+
*
|
|
65
|
+
* @default false
|
|
66
|
+
*/
|
|
67
|
+
allowPrivateCalendars?: boolean;
|
|
55
68
|
}
|
|
56
69
|
/** Operation-specific options */
|
|
57
70
|
interface OperationOptions {
|
|
58
71
|
signal?: AbortSignal;
|
|
59
72
|
}
|
|
60
|
-
/**
|
|
61
|
-
interface
|
|
62
|
-
|
|
63
|
-
blockHeight
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
73
|
+
/** Verificación exitosa: prueba criptográficamente válida y confirmada en Bitcoin. */
|
|
74
|
+
interface VerificationSuccess {
|
|
75
|
+
readonly status: 'verified';
|
|
76
|
+
readonly blockHeight: number;
|
|
77
|
+
readonly blockTime: number;
|
|
78
|
+
readonly blockHash?: string;
|
|
79
|
+
}
|
|
80
|
+
/** El timestamp es parseable pero aún no tiene confirmación Bitcoin. Estado normal. */
|
|
81
|
+
interface VerificationPending {
|
|
82
|
+
readonly status: 'pending';
|
|
83
|
+
readonly reason: string;
|
|
67
84
|
}
|
|
85
|
+
/**
|
|
86
|
+
* La verificación criptográfica falló: el digest no coincide con el merkleroot.
|
|
87
|
+
* Indica posible manipulación del archivo o de la prueba.
|
|
88
|
+
*/
|
|
89
|
+
interface VerificationInvalid {
|
|
90
|
+
readonly status: 'invalid';
|
|
91
|
+
readonly reason: string;
|
|
92
|
+
}
|
|
93
|
+
/** Error de infraestructura: Esplora no disponible. El estado del timestamp es desconocido. */
|
|
94
|
+
interface VerificationNetworkError {
|
|
95
|
+
readonly status: 'network_error';
|
|
96
|
+
readonly reason: string;
|
|
97
|
+
}
|
|
98
|
+
/** Resultado de verify(). Usar switch(result.status) para narrowing exhaustivo. */
|
|
99
|
+
type VerificationResult = VerificationSuccess | VerificationPending | VerificationInvalid | VerificationNetworkError;
|
|
100
|
+
/** Type guard — verdadero si la verificación fue exitosa. */
|
|
101
|
+
declare const isVerified: (r: VerificationResult) => r is VerificationSuccess;
|
|
68
102
|
/** Default calendar servers */
|
|
69
103
|
declare const DEFAULT_CALENDARS: string[];
|
|
70
104
|
/** Default resilience configuration */
|
|
@@ -104,6 +138,7 @@ declare class OpenTimestampsClient {
|
|
|
104
138
|
private logger?;
|
|
105
139
|
private globalSignal?;
|
|
106
140
|
private minimumSuccessfulSubmissions;
|
|
141
|
+
private allowPrivateCalendars;
|
|
107
142
|
/**
|
|
108
143
|
* Create a new OpenTimestamps client
|
|
109
144
|
*
|
|
@@ -250,6 +285,15 @@ declare class CalendarResponseTooLargeError extends NetworkError {
|
|
|
250
285
|
/** Respuesta del explorador Esplora inválida: vacía, no-JSON, malformada o demasiado grande (defensa DoS). */
|
|
251
286
|
declare class EsploraResponseError extends NetworkError {
|
|
252
287
|
}
|
|
288
|
+
/** La respuesta supera el límite de bytes permitido (defensa DoS). */
|
|
289
|
+
declare class SizeLimitExceededError extends NetworkError {
|
|
290
|
+
readonly maxBytes: number;
|
|
291
|
+
readonly actualBytes?: number;
|
|
292
|
+
constructor(maxBytes: number, actualBytes?: number, options?: {
|
|
293
|
+
cause?: Error;
|
|
294
|
+
status?: number;
|
|
295
|
+
});
|
|
296
|
+
}
|
|
253
297
|
|
|
254
298
|
/**
|
|
255
299
|
* Circuit Breaker implementation for protecting against cascading failures
|
|
@@ -262,8 +306,8 @@ declare enum CircuitState {
|
|
|
262
306
|
}
|
|
263
307
|
|
|
264
308
|
/**
|
|
265
|
-
* Universal fetch adapter
|
|
266
|
-
*
|
|
309
|
+
* Universal fetch adapter para compatibilidad multi-runtime.
|
|
310
|
+
* Funciona en Node.js 18+, browsers y edge runtimes.
|
|
267
311
|
*/
|
|
268
312
|
interface FetchRequest {
|
|
269
313
|
url: string;
|
|
@@ -300,7 +344,7 @@ declare class ResilientNetworkLayer {
|
|
|
300
344
|
* Cliente de un calendario remoto OpenTimestamps (protocolo OTS real).
|
|
301
345
|
*/
|
|
302
346
|
|
|
303
|
-
/**
|
|
347
|
+
/** Limite de tamano de la respuesta de un calendario (defensa DoS). */
|
|
304
348
|
declare const MAX_CALENDAR_RESPONSE_SIZE = 10000;
|
|
305
349
|
/** Interfaz con un servidor de calendario remoto. */
|
|
306
350
|
declare class CalendarClient {
|
|
@@ -309,22 +353,22 @@ declare class CalendarClient {
|
|
|
309
353
|
private readonly networkLayer;
|
|
310
354
|
private readonly logger?;
|
|
311
355
|
constructor(url: string, networkLayer: ResilientNetworkLayer, logger?: Logger | undefined);
|
|
312
|
-
/**
|
|
356
|
+
/** Envia un digest al calendario y devuelve el Timestamp que lo commit-ea. */
|
|
313
357
|
submit(digest: Uint8Array, signal?: AbortSignal): Promise<Timestamp>;
|
|
314
|
-
/** Pregunta al calendario si tiene un Timestamp
|
|
358
|
+
/** Pregunta al calendario si tiene un Timestamp mas completo para `commitment` (upgrade). */
|
|
315
359
|
getTimestamp(commitment: Uint8Array, signal?: AbortSignal): Promise<Timestamp>;
|
|
316
360
|
}
|
|
317
361
|
/** Lista blanca de URLs de calendario de confianza. */
|
|
318
362
|
declare class UrlWhitelist {
|
|
319
363
|
#private;
|
|
320
364
|
constructor(urls?: readonly string[]);
|
|
321
|
-
/**
|
|
365
|
+
/** Anade un patron; si no trae esquema, se anaden las variantes http y https. */
|
|
322
366
|
add(url: string): void;
|
|
323
|
-
/** Verdadero si `url` casa con
|
|
367
|
+
/** Verdadero si `url` casa con algun patron de la whitelist. */
|
|
324
368
|
contains(url: string): boolean;
|
|
325
369
|
toString(): string;
|
|
326
370
|
}
|
|
327
|
-
/** Calendarios de confianza por defecto para
|
|
371
|
+
/** Calendarios de confianza por defecto para verificacion/upgrade. */
|
|
328
372
|
declare const DEFAULT_CALENDAR_WHITELIST: UrlWhitelist;
|
|
329
373
|
/** Agregadores por defecto a los que enviar digests al sellar. */
|
|
330
374
|
declare const DEFAULT_AGGREGATORS: readonly string[];
|
|
@@ -358,4 +402,28 @@ declare class EsploraClient {
|
|
|
358
402
|
*/
|
|
359
403
|
declare function verifyTimestampAttestation(digest: Uint8Array, attestation: Attestation, explorer: EsploraClient, signal?: AbortSignal): Promise<number>;
|
|
360
404
|
|
|
361
|
-
|
|
405
|
+
declare function hashBuffer(data: Buffer | Uint8Array): Buffer;
|
|
406
|
+
declare function hashFile(path: string): Promise<Buffer>;
|
|
407
|
+
|
|
408
|
+
/**
|
|
409
|
+
* SSRF protection para calendarios configurables por el usuario.
|
|
410
|
+
*
|
|
411
|
+
* LIMITACIONES (documentadas intencionalmente):
|
|
412
|
+
* - TOCTOU/DNS rebinding: la validación DNS ocurre ANTES de la conexión.
|
|
413
|
+
* Un servidor con TTL=0 puede cambiar la IP entre la validación y el fetch.
|
|
414
|
+
* Mitigación real requiere egress filtering a nivel de red.
|
|
415
|
+
* - IPv4-mapped IPv6 (::ffff:x.x.x.x): se bloquea el prefijo ::ffff:
|
|
416
|
+
* pero la validación del componente IPv4 depende del formato que devuelva Node.js.
|
|
417
|
+
*/
|
|
418
|
+
/**
|
|
419
|
+
* Valida que una URL de calendario es segura para hacer outbound HTTP.
|
|
420
|
+
* Bloquea IPs privadas/reservadas por defecto.
|
|
421
|
+
*
|
|
422
|
+
* @param allowPrivate Si true, omite la comprobación de rangos IP.
|
|
423
|
+
* Útil para testing local o redes corporativas internas.
|
|
424
|
+
*/
|
|
425
|
+
declare function assertSafeCalendarUrl(url: string, options: {
|
|
426
|
+
allowPrivate: boolean;
|
|
427
|
+
}): Promise<void>;
|
|
428
|
+
|
|
429
|
+
export { type BackoffStrategy, CalendarClient, CalendarResponseTooLargeError, CircuitBreakerError, type CircuitBreakerOptions, CircuitState, type ClientOptions, CommitmentNotFoundError, DEFAULT_AGGREGATORS, DEFAULT_CALENDARS, DEFAULT_CALENDAR_WHITELIST, DEFAULT_RESILIENCE, EsploraClient, type EsploraClientOptions, EsploraResponseError, type JitterType, type Logger, MAX_CALENDAR_RESPONSE_SIZE, MAX_ESPLORA_RESPONSE_SIZE, NetworkError, OpenTimestampsClient, OpenTimestampsClientError, type OperationOptions, PUBLIC_ESPLORA_URL, type ResilienceOptions, ResilientNetworkLayer, type RetryOptions, SizeLimitExceededError, StampError, UpgradeError, UrlWhitelist, ValidationError, type VerificationInvalid, type VerificationNetworkError, type VerificationPending, type VerificationResult, type VerificationSuccess, assertSafeCalendarUrl, hashBuffer, hashFile, isVerified, verifyTimestampAttestation };
|
package/dist/index.d.ts
CHANGED
|
@@ -39,6 +39,8 @@ interface ResilienceOptions {
|
|
|
39
39
|
connectTimeoutMs: number;
|
|
40
40
|
retries: RetryOptions;
|
|
41
41
|
circuitBreaker: CircuitBreakerOptions;
|
|
42
|
+
/** Límite de bytes para el body de la respuesta. Default 100 KB. */
|
|
43
|
+
maxResponseBytes?: number;
|
|
42
44
|
}
|
|
43
45
|
/** Client configuration options */
|
|
44
46
|
interface ClientOptions {
|
|
@@ -52,19 +54,51 @@ interface ClientOptions {
|
|
|
52
54
|
signal?: AbortSignal;
|
|
53
55
|
/** Minimum successful calendar submissions required (default: 2) */
|
|
54
56
|
minimumSuccessfulSubmissions?: number;
|
|
57
|
+
/**
|
|
58
|
+
* Permite URLs de calendario que resuelven a IPs privadas/reservadas.
|
|
59
|
+
*
|
|
60
|
+
* **No activar en producción.** Útil para testing local o redes corporativas.
|
|
61
|
+
*
|
|
62
|
+
* Incluso con `false`, la protección es best-effort contra DNS rebinding (TOCTOU).
|
|
63
|
+
* Para alta seguridad, complementar con egress filtering a nivel de red.
|
|
64
|
+
*
|
|
65
|
+
* @default false
|
|
66
|
+
*/
|
|
67
|
+
allowPrivateCalendars?: boolean;
|
|
55
68
|
}
|
|
56
69
|
/** Operation-specific options */
|
|
57
70
|
interface OperationOptions {
|
|
58
71
|
signal?: AbortSignal;
|
|
59
72
|
}
|
|
60
|
-
/**
|
|
61
|
-
interface
|
|
62
|
-
|
|
63
|
-
blockHeight
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
73
|
+
/** Verificación exitosa: prueba criptográficamente válida y confirmada en Bitcoin. */
|
|
74
|
+
interface VerificationSuccess {
|
|
75
|
+
readonly status: 'verified';
|
|
76
|
+
readonly blockHeight: number;
|
|
77
|
+
readonly blockTime: number;
|
|
78
|
+
readonly blockHash?: string;
|
|
79
|
+
}
|
|
80
|
+
/** El timestamp es parseable pero aún no tiene confirmación Bitcoin. Estado normal. */
|
|
81
|
+
interface VerificationPending {
|
|
82
|
+
readonly status: 'pending';
|
|
83
|
+
readonly reason: string;
|
|
67
84
|
}
|
|
85
|
+
/**
|
|
86
|
+
* La verificación criptográfica falló: el digest no coincide con el merkleroot.
|
|
87
|
+
* Indica posible manipulación del archivo o de la prueba.
|
|
88
|
+
*/
|
|
89
|
+
interface VerificationInvalid {
|
|
90
|
+
readonly status: 'invalid';
|
|
91
|
+
readonly reason: string;
|
|
92
|
+
}
|
|
93
|
+
/** Error de infraestructura: Esplora no disponible. El estado del timestamp es desconocido. */
|
|
94
|
+
interface VerificationNetworkError {
|
|
95
|
+
readonly status: 'network_error';
|
|
96
|
+
readonly reason: string;
|
|
97
|
+
}
|
|
98
|
+
/** Resultado de verify(). Usar switch(result.status) para narrowing exhaustivo. */
|
|
99
|
+
type VerificationResult = VerificationSuccess | VerificationPending | VerificationInvalid | VerificationNetworkError;
|
|
100
|
+
/** Type guard — verdadero si la verificación fue exitosa. */
|
|
101
|
+
declare const isVerified: (r: VerificationResult) => r is VerificationSuccess;
|
|
68
102
|
/** Default calendar servers */
|
|
69
103
|
declare const DEFAULT_CALENDARS: string[];
|
|
70
104
|
/** Default resilience configuration */
|
|
@@ -104,6 +138,7 @@ declare class OpenTimestampsClient {
|
|
|
104
138
|
private logger?;
|
|
105
139
|
private globalSignal?;
|
|
106
140
|
private minimumSuccessfulSubmissions;
|
|
141
|
+
private allowPrivateCalendars;
|
|
107
142
|
/**
|
|
108
143
|
* Create a new OpenTimestamps client
|
|
109
144
|
*
|
|
@@ -250,6 +285,15 @@ declare class CalendarResponseTooLargeError extends NetworkError {
|
|
|
250
285
|
/** Respuesta del explorador Esplora inválida: vacía, no-JSON, malformada o demasiado grande (defensa DoS). */
|
|
251
286
|
declare class EsploraResponseError extends NetworkError {
|
|
252
287
|
}
|
|
288
|
+
/** La respuesta supera el límite de bytes permitido (defensa DoS). */
|
|
289
|
+
declare class SizeLimitExceededError extends NetworkError {
|
|
290
|
+
readonly maxBytes: number;
|
|
291
|
+
readonly actualBytes?: number;
|
|
292
|
+
constructor(maxBytes: number, actualBytes?: number, options?: {
|
|
293
|
+
cause?: Error;
|
|
294
|
+
status?: number;
|
|
295
|
+
});
|
|
296
|
+
}
|
|
253
297
|
|
|
254
298
|
/**
|
|
255
299
|
* Circuit Breaker implementation for protecting against cascading failures
|
|
@@ -262,8 +306,8 @@ declare enum CircuitState {
|
|
|
262
306
|
}
|
|
263
307
|
|
|
264
308
|
/**
|
|
265
|
-
* Universal fetch adapter
|
|
266
|
-
*
|
|
309
|
+
* Universal fetch adapter para compatibilidad multi-runtime.
|
|
310
|
+
* Funciona en Node.js 18+, browsers y edge runtimes.
|
|
267
311
|
*/
|
|
268
312
|
interface FetchRequest {
|
|
269
313
|
url: string;
|
|
@@ -300,7 +344,7 @@ declare class ResilientNetworkLayer {
|
|
|
300
344
|
* Cliente de un calendario remoto OpenTimestamps (protocolo OTS real).
|
|
301
345
|
*/
|
|
302
346
|
|
|
303
|
-
/**
|
|
347
|
+
/** Limite de tamano de la respuesta de un calendario (defensa DoS). */
|
|
304
348
|
declare const MAX_CALENDAR_RESPONSE_SIZE = 10000;
|
|
305
349
|
/** Interfaz con un servidor de calendario remoto. */
|
|
306
350
|
declare class CalendarClient {
|
|
@@ -309,22 +353,22 @@ declare class CalendarClient {
|
|
|
309
353
|
private readonly networkLayer;
|
|
310
354
|
private readonly logger?;
|
|
311
355
|
constructor(url: string, networkLayer: ResilientNetworkLayer, logger?: Logger | undefined);
|
|
312
|
-
/**
|
|
356
|
+
/** Envia un digest al calendario y devuelve el Timestamp que lo commit-ea. */
|
|
313
357
|
submit(digest: Uint8Array, signal?: AbortSignal): Promise<Timestamp>;
|
|
314
|
-
/** Pregunta al calendario si tiene un Timestamp
|
|
358
|
+
/** Pregunta al calendario si tiene un Timestamp mas completo para `commitment` (upgrade). */
|
|
315
359
|
getTimestamp(commitment: Uint8Array, signal?: AbortSignal): Promise<Timestamp>;
|
|
316
360
|
}
|
|
317
361
|
/** Lista blanca de URLs de calendario de confianza. */
|
|
318
362
|
declare class UrlWhitelist {
|
|
319
363
|
#private;
|
|
320
364
|
constructor(urls?: readonly string[]);
|
|
321
|
-
/**
|
|
365
|
+
/** Anade un patron; si no trae esquema, se anaden las variantes http y https. */
|
|
322
366
|
add(url: string): void;
|
|
323
|
-
/** Verdadero si `url` casa con
|
|
367
|
+
/** Verdadero si `url` casa con algun patron de la whitelist. */
|
|
324
368
|
contains(url: string): boolean;
|
|
325
369
|
toString(): string;
|
|
326
370
|
}
|
|
327
|
-
/** Calendarios de confianza por defecto para
|
|
371
|
+
/** Calendarios de confianza por defecto para verificacion/upgrade. */
|
|
328
372
|
declare const DEFAULT_CALENDAR_WHITELIST: UrlWhitelist;
|
|
329
373
|
/** Agregadores por defecto a los que enviar digests al sellar. */
|
|
330
374
|
declare const DEFAULT_AGGREGATORS: readonly string[];
|
|
@@ -358,4 +402,28 @@ declare class EsploraClient {
|
|
|
358
402
|
*/
|
|
359
403
|
declare function verifyTimestampAttestation(digest: Uint8Array, attestation: Attestation, explorer: EsploraClient, signal?: AbortSignal): Promise<number>;
|
|
360
404
|
|
|
361
|
-
|
|
405
|
+
declare function hashBuffer(data: Buffer | Uint8Array): Buffer;
|
|
406
|
+
declare function hashFile(path: string): Promise<Buffer>;
|
|
407
|
+
|
|
408
|
+
/**
|
|
409
|
+
* SSRF protection para calendarios configurables por el usuario.
|
|
410
|
+
*
|
|
411
|
+
* LIMITACIONES (documentadas intencionalmente):
|
|
412
|
+
* - TOCTOU/DNS rebinding: la validación DNS ocurre ANTES de la conexión.
|
|
413
|
+
* Un servidor con TTL=0 puede cambiar la IP entre la validación y el fetch.
|
|
414
|
+
* Mitigación real requiere egress filtering a nivel de red.
|
|
415
|
+
* - IPv4-mapped IPv6 (::ffff:x.x.x.x): se bloquea el prefijo ::ffff:
|
|
416
|
+
* pero la validación del componente IPv4 depende del formato que devuelva Node.js.
|
|
417
|
+
*/
|
|
418
|
+
/**
|
|
419
|
+
* Valida que una URL de calendario es segura para hacer outbound HTTP.
|
|
420
|
+
* Bloquea IPs privadas/reservadas por defecto.
|
|
421
|
+
*
|
|
422
|
+
* @param allowPrivate Si true, omite la comprobación de rangos IP.
|
|
423
|
+
* Útil para testing local o redes corporativas internas.
|
|
424
|
+
*/
|
|
425
|
+
declare function assertSafeCalendarUrl(url: string, options: {
|
|
426
|
+
allowPrivate: boolean;
|
|
427
|
+
}): Promise<void>;
|
|
428
|
+
|
|
429
|
+
export { type BackoffStrategy, CalendarClient, CalendarResponseTooLargeError, CircuitBreakerError, type CircuitBreakerOptions, CircuitState, type ClientOptions, CommitmentNotFoundError, DEFAULT_AGGREGATORS, DEFAULT_CALENDARS, DEFAULT_CALENDAR_WHITELIST, DEFAULT_RESILIENCE, EsploraClient, type EsploraClientOptions, EsploraResponseError, type JitterType, type Logger, MAX_CALENDAR_RESPONSE_SIZE, MAX_ESPLORA_RESPONSE_SIZE, NetworkError, OpenTimestampsClient, OpenTimestampsClientError, type OperationOptions, PUBLIC_ESPLORA_URL, type ResilienceOptions, ResilientNetworkLayer, type RetryOptions, SizeLimitExceededError, StampError, UpgradeError, UrlWhitelist, ValidationError, type VerificationInvalid, type VerificationNetworkError, type VerificationPending, type VerificationResult, type VerificationSuccess, assertSafeCalendarUrl, hashBuffer, hashFile, isVerified, verifyTimestampAttestation };
|