@otskit/client 0.1.1 → 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/LICENSE +21 -21
- package/package.json +3 -4
- package/dist/index.cjs +0 -1012
- package/dist/index.d.cts +0 -361
- package/dist/index.d.ts +0 -361
- package/dist/index.js +0 -965
package/dist/index.d.cts
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 };
|