SDK
02
@otskit/client
SDK TypeScript para sellar hashes, actualizar pruebas pendientes y verificar attestations Bitcoin. Usa @otskit/core por debajo y añade calendarios, red, resiliencia y helpers para producción.
Cuándo usarlo
Cuándo usarlo
Si eres developer y quieres usar OTSkit en una aplicación real, empieza aquí.
El ciclo
El ciclo completo
- hashFile()
- SHA-256 en streaming, localmente. El archivo no sale de tu máquina.
- stamp()
- Envía el hash a los calendarios. Devuelve una prueba pending en milisegundos.
- .ots pending
- Estado normal. Bitcoin aún no ha incluido el hash en un bloque.
- upgrade()
- Consulta los calendarios más tarde. Fusiona la attestation Bitcoin en la prueba.
- .ots confirmed
- La prueba es completa. Tiene una attestation Bitcoin verificable offline.
- verify()
- Comprueba la prueba contra Bitcoin. Devuelve { valid, blockHeight, timestamp }.
Instalación
Instalación
Incluye @otskit/core automáticamente.
Quick start
Quick start
Flujo completo: stamp → upgrade → verify
El flujo habitual en producción. hashFile calcula el SHA-256 localmente, stamp sella contra calendarios, upgrade recoge la confirmación Bitcoin y verify comprueba la prueba.
import { OpenTimestampsClient, hashFile } from '@otskit/client'
import { writeFileSync } from 'fs'
const client = new OpenTimestampsClient()
const hash = await hashFile('contract.pdf') // streaming SHA-256
const pending = await client.stamp(hash) // milisegundos
writeFileSync('contract.pdf.ots', pending)
const upgraded = await client.upgrade(pending) // ~60 min después
writeFileSync('contract.pdf.ots', upgraded)
const result = await client.verify(upgraded, hash)
if (result.valid) {
console.log('Block:', result.blockHeight)
console.log('Time: ', new Date(result.timestamp! * 1000).toISOString())
}Manejo de errores tipado
Cada tipo de fallo tiene su clase. verify() nunca lanza por una prueba inválida — devuelve {valid: false}.
import { StampError, ValidationError, CircuitBreakerError } from '@otskit/client'
try {
await client.stamp(hash)
} catch (err) {
if (err instanceof ValidationError) { /* hash inválido */ }
if (err instanceof StampError) { console.log(err.successfulSubmissions) }
if (err instanceof CircuitBreakerError) { /* calendario aislado */ }
}Pending no es error
Pending no es error
import { DetachedTimestampFile } from '@otskit/core'
const proof = new Uint8Array(readFileSync('contract.pdf.ots'))
const dtf = DetachedTimestampFile.deserialize(proof)
if (!dtf.timestamp.isTimestampComplete()) {
console.log('Pendiente — reintenta upgrade() en ~60 min')
} else {
console.log('Confirmado en Bitcoin')
}Resiliencia
Resiliencia
El diferencial de client sobre core: red con comportamiento de producción. Cada operación puede sobrevivir a fallos de calendarios individuales sin afectar al resultado.
Circuit breaker por calendario
Un calendario roto se aísla automáticamente. No afecta a los demás ni bloquea la operación.
Retry con backoff
Reintentos con backoff exponencial, linear o constante. Jitter configurable para evitar tormentas.
Threshold submissions
stamp() puede exigir N de M calendarios exitosos. Tú decides cuánta redundancia necesitas.
Dual timeouts
Timeout total para la operación completa y timeout por intento de red. Ambos configurables.
Fail-fast 4xx
Los errores de cliente (400, 401, 404…) no se reintentan. Solo fallan los 5xx y errores de red.
AbortController
Cualquier operación en curso se puede cancelar limpiamente pasando tu propio signal.
Seguridad
Seguridad
Client no custodia nada ni requiere cuenta. El diseño de seguridad es el mismo que el del protocolo: sin servidores de confianza propios.
El archivo no se sube
hashFile() lee el archivo localmente y calcula SHA-256 en streaming. Solo el hash sale de tu máquina.
stamp() recibe hash
Envía el hash (Uint8Array o hex) a los calendarios, nunca el archivo original.
Calendarios con whitelist
upgrade() solo consulta los calendarios ya presentes en la prueba y valida las URLs contra una whitelist.
verify() sin red propietaria
Valida la prueba contra Esplora / Bitcoin directamente. Sin pasar por servidores de OTSkit.
Config avanzada
Configuración avanzada
Todos los parámetros son opcionales. Los valores por defecto funcionan para producción con los cuatro calendarios públicos.
const client = new OpenTimestampsClient({
minimumSuccessfulSubmissions: 2, // 2 de 4 calendarios
resilience: {
retries: {
maxAttempts: 3,
backoff: { type: 'exponential', jitter: 'full', baseMs: 1000, maxMs: 30000 }
},
circuitBreaker: {
failureThreshold: 5,
recoveryTimeoutMs: 30000,
halfOpenMaxCalls: 2
},
timeout: { totalTimeoutMs: 30000, connectTimeoutMs: 10000 }
},
logger: console, // cualquier objeto { info, warn, error }
signal: abortController.signal,
})Errores tipados
Errores tipados
verify() no lanza por una prueba inválida — devuelve {valid: false, error}. Los throws son para fallos inesperados de red o input malformado.
ValidationError
Hash malformado, prueba corrupta u otro input inválido. No tiene sentido reintentar.
StampError
stamp() no alcanzó el mínimo de calendarios exitosos. Incluye successfulSubmissions.
UpgradeError
No se pudo consultar ningún calendario durante el upgrade. Puede reintentarse más tarde.
NetworkError
Fallo de red no recuperable después de agotar los reintentos configurados.
CircuitBreakerError
El calendario está aislado por su circuit breaker. Se recupera solo tras recoveryTimeoutMs.
verify() no lanza
Una prueba inválida devuelve { valid: false, error }. Los throws son para fallos de red o input malformado.
API surface
API surface
OpenTimestampsClient
new OpenTimestampsClient(config?)Crea el cliente con configuración opcional.stamp(hash)Envía hash a calendarios, devuelve prueba pending (Uint8Array).upgrade(proof)Actualiza prueba pendiente con attestation Bitcoin.verify(proof, originalHash?)Verifica la prueba. Devuelve { valid, blockHeight, timestamp }.getCircuitState(url)Estado del circuit breaker para un calendario.resetCircuit(url)Resetea manualmente el circuit breaker de un calendarioHelpers
hashFile(path)SHA-256 en streaming de un archivo localhashBuffer(data)SHA-256 de un Uint8Array o Buffer ya en memoriaAvanzado
CalendarClientCliente de bajo nivel para un calendario concretoEsploraClientCliente para consultar Bitcoin via API EsploraResilientNetworkLayerCapa de red con retry, circuit breaker y timeoutsSiguiente paso
¿Quieres usarlo desde Claude, Codex u otro agente AI? Sigue con @otskit/mcp.
@otskit/mcp — Servidor MCP para agentes AI →