@otskit/client 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts DELETED
@@ -1,361 +0,0 @@
1
- import { Timestamp, BlockHeader, Attestation } from '@otskit/core';
2
- export { Attestation, BitcoinAttestation, DetachedTimestampFile, PendingAttestation, Timestamp, verifyAgainstBlockheader } from '@otskit/core';
3
-
4
- /**
5
- * Type definitions for the OpenTimestamps Client SDK
6
- */
7
- /** Logger interface for observability */
8
- interface Logger {
9
- debug(message: string, ...args: unknown[]): void;
10
- info(message: string, ...args: unknown[]): void;
11
- warn(message: string, ...args: unknown[]): void;
12
- error(message: string, ...args: unknown[]): void;
13
- }
14
- /** Backoff strategy for retries */
15
- type BackoffStrategy = 'exponential' | 'linear' | 'constant';
16
- /** Jitter type for randomizing backoff delays */
17
- type JitterType = 'none' | 'full' | 'equal';
18
- /** Retry configuration */
19
- interface RetryOptions {
20
- enabled: boolean;
21
- maxAttempts: number;
22
- backoff: {
23
- strategy: BackoffStrategy;
24
- initialDelayMs: number;
25
- maxDelayMs?: number;
26
- jitter: JitterType;
27
- };
28
- }
29
- /** Circuit breaker configuration */
30
- interface CircuitBreakerOptions {
31
- enabled: boolean;
32
- failureThreshold: number;
33
- recoveryTimeoutMs: number;
34
- halfOpenMaxAttempts?: number;
35
- }
36
- /** Network resilience configuration */
37
- interface ResilienceOptions {
38
- totalTimeoutMs: number;
39
- connectTimeoutMs: number;
40
- retries: RetryOptions;
41
- circuitBreaker: CircuitBreakerOptions;
42
- }
43
- /** Client configuration options */
44
- interface ClientOptions {
45
- /** List of OpenTimestamps calendar URLs */
46
- calendars?: string[];
47
- /** Network resilience configuration */
48
- resilience?: Partial<ResilienceOptions>;
49
- /** Optional logger for observability */
50
- logger?: Logger;
51
- /** Optional AbortSignal to cancel all operations */
52
- signal?: AbortSignal;
53
- /** Minimum successful calendar submissions required (default: 2) */
54
- minimumSuccessfulSubmissions?: number;
55
- }
56
- /** Operation-specific options */
57
- interface OperationOptions {
58
- signal?: AbortSignal;
59
- }
60
- /** Verification result */
61
- interface VerificationResult {
62
- valid: boolean;
63
- blockHeight?: number;
64
- blockHash?: string;
65
- timestamp?: number;
66
- error?: string;
67
- }
68
- /** Default calendar servers */
69
- declare const DEFAULT_CALENDARS: string[];
70
- /** Default resilience configuration */
71
- declare const DEFAULT_RESILIENCE: ResilienceOptions;
72
-
73
- /**
74
- * Main OpenTimestamps Client SDK
75
- */
76
-
77
- /**
78
- * OpenTimestamps Client SDK
79
- *
80
- * Provides a high-level interface for interacting with OpenTimestamps calendars
81
- * with built-in resilience patterns (timeout, retry, circuit breaker)
82
- *
83
- * @example
84
- * ```typescript
85
- * const client = new OpenTimestampsClient({
86
- * calendars: ['https://alice.btc.calendar.opentimestamps.org']
87
- * })
88
- *
89
- * // Create timestamp
90
- * const fileHash = Buffer.from('a'.repeat(64), 'hex')
91
- * const otsProof = await client.stamp(fileHash)
92
- *
93
- * // Later, upgrade to get Bitcoin confirmation
94
- * const upgradedProof = await client.upgrade(otsProof)
95
- *
96
- * // Verify the timestamp
97
- * const result = await client.verify(upgradedProof, fileHash)
98
- * console.log(`Confirmed in block ${result.blockHeight}`)
99
- * ```
100
- */
101
- declare class OpenTimestampsClient {
102
- private calendars;
103
- private networkLayer;
104
- private logger?;
105
- private globalSignal?;
106
- private minimumSuccessfulSubmissions;
107
- /**
108
- * Create a new OpenTimestamps client
109
- *
110
- * @param options Client configuration options
111
- */
112
- constructor(options?: ClientOptions);
113
- /**
114
- * Create a timestamp by submitting a hash to calendar servers
115
- *
116
- * @param hash SHA-256 hash of the data to timestamp (as Buffer or hex string)
117
- * @param options Operation-specific options
118
- * @returns Initial .ots proof with pending attestations
119
- *
120
- * @throws {ValidationError} If the hash is invalid
121
- * @throws {StampError} If submission fails to all calendars
122
- * @throws {NetworkError} If network errors occur
123
- *
124
- * @example
125
- * ```typescript
126
- * const hash = crypto.createHash('sha256').update('my data').digest()
127
- * const otsProof = await client.stamp(hash)
128
- * // Save otsProof to database as Buffer
129
- * ```
130
- */
131
- stamp(hash: Buffer | string, options?: OperationOptions): Promise<Buffer>;
132
- /**
133
- * Upgrade an incomplete timestamp proof by querying calendars for Bitcoin confirmation
134
- *
135
- * @param incompleteProof The initial .ots proof returned by stamp()
136
- * @param options Operation-specific options
137
- * @returns Upgraded .ots proof with Bitcoin attestation (if available)
138
- *
139
- * @throws {ValidationError} If the proof format is invalid
140
- * @throws {UpgradeError} If no calendar has confirmed the timestamp yet
141
- * @throws {NetworkError} If network errors occur
142
- *
143
- * @example
144
- * ```typescript
145
- * // Proof already has pending attestations from stamp()
146
- * const upgradedProof = await client.upgrade(incompleteProof)
147
- *
148
- * // If upgrade throws UpgradeError, Bitcoin hasn't confirmed yet
149
- * // Retry later (typically 10-60 minutes after stamp)
150
- * ```
151
- */
152
- upgrade(incompleteProof: Buffer, options?: OperationOptions): Promise<Buffer>;
153
- /**
154
- * Verify a complete timestamp proof against the Bitcoin blockchain
155
- *
156
- * @param proof The complete .ots proof with Bitcoin attestation
157
- * @param originalDataHash Optional: the original data hash to verify against
158
- * @returns Verification result with block details
159
- *
160
- * @example
161
- * ```typescript
162
- * const result = await client.verify(completeProof, originalHash)
163
- *
164
- * if (result.valid) {
165
- * console.log(`Timestamp confirmed in Bitcoin block ${result.blockHeight}`)
166
- * console.log(`Block timestamp: ${new Date(result.timestamp! * 1000)}`)
167
- * } else {
168
- * console.error(`Verification failed: ${result.error}`)
169
- * }
170
- * ```
171
- */
172
- verify(proof: Buffer, originalDataHash?: Buffer | string): Promise<VerificationResult>;
173
- /**
174
- * Get the current state of the circuit breaker for a calendar
175
- * Useful for monitoring and debugging
176
- *
177
- * @param calendarUrl The calendar URL to check
178
- * @returns Circuit state: 'CLOSED', 'OPEN', or 'HALF_OPEN' (undefined if not yet initialized)
179
- */
180
- getCircuitState(calendarUrl: string): 'CLOSED' | 'OPEN' | 'HALF_OPEN' | undefined;
181
- /**
182
- * Reset the circuit breaker for a specific calendar
183
- * Use this to manually recover a calendar that has been marked as failing
184
- *
185
- * @param calendarUrl The calendar URL to reset
186
- */
187
- resetCircuit(calendarUrl: string): void;
188
- /**
189
- * Reset all circuit breakers
190
- * Use this to clear all failure states
191
- */
192
- resetAllCircuits(): void;
193
- }
194
-
195
- /**
196
- * Custom error classes for the OpenTimestamps Client SDK
197
- */
198
- /** Base class for all SDK-specific errors */
199
- declare class OpenTimestampsClientError extends Error {
200
- readonly cause?: Error;
201
- constructor(message: string, options?: {
202
- cause?: Error;
203
- });
204
- }
205
- /** Error during input validation */
206
- declare class ValidationError extends OpenTimestampsClientError {
207
- }
208
- /** Error during stamp operation */
209
- declare class StampError extends OpenTimestampsClientError {
210
- readonly successfulSubmissions: Array<{
211
- calendar: string;
212
- proof?: Buffer;
213
- }>;
214
- readonly failedSubmissions: Array<{
215
- calendar: string;
216
- error: Error;
217
- }>;
218
- constructor(message: string, successful: Array<{
219
- calendar: string;
220
- proof?: Buffer;
221
- }>, failed: Array<{
222
- calendar: string;
223
- error: Error;
224
- }>, options?: {
225
- cause?: Error;
226
- });
227
- }
228
- /** Error during upgrade operation */
229
- declare class UpgradeError extends OpenTimestampsClientError {
230
- }
231
- /** Network-related error (timeout, all retries failed, etc.) */
232
- declare class NetworkError extends OpenTimestampsClientError {
233
- /** HTTP status code, cuando el fallo viene de una respuesta HTTP. */
234
- readonly status?: number;
235
- constructor(message: string, options?: {
236
- cause?: Error;
237
- status?: number;
238
- });
239
- }
240
- /** Circuit breaker is open, request rejected */
241
- declare class CircuitBreakerError extends NetworkError {
242
- constructor(calendar: string);
243
- }
244
- /** El calendario no conoce (todavía) el commitment consultado (HTTP 404). */
245
- declare class CommitmentNotFoundError extends NetworkError {
246
- }
247
- /** La respuesta del calendario supera el límite de tamaño permitido (defensa DoS). */
248
- declare class CalendarResponseTooLargeError extends NetworkError {
249
- }
250
- /** Respuesta del explorador Esplora inválida: vacía, no-JSON, malformada o demasiado grande (defensa DoS). */
251
- declare class EsploraResponseError extends NetworkError {
252
- }
253
-
254
- /**
255
- * Circuit Breaker implementation for protecting against cascading failures
256
- */
257
-
258
- declare enum CircuitState {
259
- CLOSED = "CLOSED",
260
- OPEN = "OPEN",
261
- HALF_OPEN = "HALF_OPEN"
262
- }
263
-
264
- /**
265
- * Universal fetch adapter for multi-runtime compatibility
266
- * Works in Node.js 18+, browsers, and edge runtimes
267
- */
268
- interface FetchRequest {
269
- url: string;
270
- method: 'GET' | 'POST';
271
- body?: Uint8Array;
272
- headers?: Record<string, string>;
273
- signal?: AbortSignal;
274
- }
275
- interface FetchResponse {
276
- ok: boolean;
277
- status: number;
278
- statusText: string;
279
- data: Uint8Array;
280
- }
281
-
282
- declare class ResilientNetworkLayer {
283
- private options;
284
- private logger?;
285
- private circuitBreaker;
286
- constructor(options: ResilienceOptions, logger?: Logger | undefined);
287
- /**
288
- * Execute a request with full resilience pipeline
289
- */
290
- request(calendarUrl: string, request: Omit<FetchRequest, 'signal'>, parentSignal?: AbortSignal): Promise<FetchResponse>;
291
- /** Get circuit breaker state for a calendar */
292
- getCircuitState(calendarUrl: string): CircuitState | undefined;
293
- /** Reset circuit breaker for a calendar */
294
- resetCircuit(calendarUrl: string): void;
295
- /** Reset all circuit breakers */
296
- resetAllCircuits(): void;
297
- }
298
-
299
- /**
300
- * Cliente de un calendario remoto OpenTimestamps (protocolo OTS real).
301
- */
302
-
303
- /** Límite de tamaño de la respuesta de un calendario (defensa DoS). */
304
- declare const MAX_CALENDAR_RESPONSE_SIZE = 10000;
305
- /** Interfaz con un servidor de calendario remoto. */
306
- declare class CalendarClient {
307
- #private;
308
- private readonly url;
309
- private readonly networkLayer;
310
- private readonly logger?;
311
- constructor(url: string, networkLayer: ResilientNetworkLayer, logger?: Logger | undefined);
312
- /** Envía un digest al calendario y devuelve el Timestamp que lo commit-ea. */
313
- submit(digest: Uint8Array, signal?: AbortSignal): Promise<Timestamp>;
314
- /** Pregunta al calendario si tiene un Timestamp más completo para `commitment` (upgrade). */
315
- getTimestamp(commitment: Uint8Array, signal?: AbortSignal): Promise<Timestamp>;
316
- }
317
- /** Lista blanca de URLs de calendario de confianza. */
318
- declare class UrlWhitelist {
319
- #private;
320
- constructor(urls?: readonly string[]);
321
- /** Añade un patrón; si no trae esquema, se añaden las variantes http y https. */
322
- add(url: string): void;
323
- /** Verdadero si `url` casa con algún patrón de la whitelist. */
324
- contains(url: string): boolean;
325
- toString(): string;
326
- }
327
- /** Calendarios de confianza por defecto para verificación/upgrade. */
328
- declare const DEFAULT_CALENDAR_WHITELIST: UrlWhitelist;
329
- /** Agregadores por defecto a los que enviar digests al sellar. */
330
- declare const DEFAULT_AGGREGATORS: readonly string[];
331
-
332
- /** Explorador Esplora público por defecto (Bitcoin mainnet). */
333
- declare const PUBLIC_ESPLORA_URL = "https://blockstream.info/api";
334
- /** Límite de tamaño de una respuesta de Esplora (defensa DoS). Una cabecera JSON ronda los cientos de bytes. */
335
- declare const MAX_ESPLORA_RESPONSE_SIZE = 100000;
336
- interface EsploraClientOptions {
337
- /** URL base del explorador (por defecto Blockstream). Útil para apuntar a un Esplora de Litecoin. */
338
- url?: string;
339
- logger?: Logger;
340
- }
341
- /** Cliente de un explorador Esplora remoto. */
342
- declare class EsploraClient {
343
- #private;
344
- constructor(networkLayer: ResilientNetworkLayer, options?: EsploraClientOptions);
345
- /** Devuelve el hash (hex 64, minúsculas) del bloque a la altura dada. */
346
- blockHash(height: number, signal?: AbortSignal): Promise<string>;
347
- /** Devuelve la cabecera del bloque (merkleroot + time) dado su hash. */
348
- block(hash: string, signal?: AbortSignal): Promise<BlockHeader>;
349
- }
350
- /**
351
- * Verifica una atestación Bitcoin/Litecoin contra la cabecera del bloque correspondiente.
352
- *
353
- * `digest` es el commitment final del árbol del timestamp en el punto de la atestación
354
- * (32 bytes, debe ser el merkleroot del bloque). `explorer` debe apuntar a la cadena de la
355
- * atestación (Blockstream para Bitcoin; un Esplora de Litecoin para Litecoin). Devuelve el
356
- * tiempo del bloque (epoch s) en éxito; lanza `VerificationError` si no coincide o si la
357
- * atestación no es verificable en cadena (`pending`/`unknown`). Fail-closed.
358
- */
359
- declare function verifyTimestampAttestation(digest: Uint8Array, attestation: Attestation, explorer: EsploraClient, signal?: AbortSignal): Promise<number>;
360
-
361
- 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, StampError, UpgradeError, UrlWhitelist, ValidationError, type VerificationResult, verifyTimestampAttestation };