Foundation
01
@otskit/core
La implementación TypeScript pura del protocolo OpenTimestamps. Sin dependencias externas, validación estricta y control total sobre pruebas .ots, operaciones criptográficas, attestations y Merkle trees.
Qué es Core
Qué es Core
Core es la capa de bajo nivel. Te da las piezas del protocolo: DetachedTimestampFile, Timestamp, operaciones hash, attestations, serialización binaria y verificación contra block headers.
.ots. No es el SDK de red para hablar con calendarios. Para stamp → upgrade → verify en producción, usa @otskit/client.Cuándo usarlo
Cuándo usarlo
Usa Core si…
- Quieres manipular .ots directamente
- Quieres construir Merkle trees
- Quieres verificar contra block headers
- Quieres integrar el protocolo en otra herramienta
Usa Client si…
- Quieres sellar archivos contra calendarios
- Quieres retries, circuit breaker y upgrade automático
- Quieres una API stamp / upgrade / verify lista para producción
- Quieres empezar rápido
Mapa del protocolo
Mapa del protocolo
- bytes / hash
- El contenido del archivo o un digest ya calculado.
- DetachedTimestampFile
- Envoltorio del .ots: liga el digest con su árbol de prueba.
- Timestamp
- El árbol de prueba. Cada nodo es un mensaje intermedio.
- Ops
- Las operaciones que transforman un nodo en el siguiente.
- Attestations
- Hojas del árbol: pending, Bitcoin o Litecoin.
- .ots bytes
- El árbol serializado al formato binario OTS.
Primitivas
Primitivas del protocolo
DetachedTimestampFile
El envoltorio del .ots. Liga el digest del archivo con su árbol de prueba y se encarga de serializar y deserializar.
Timestamp
Un nodo del árbol de prueba. Se construye aplicando operaciones y se fusiona con merge() para unir ramas y attestations.
Ops
Las operaciones del protocolo: SHA-256, SHA-1, RIPEMD-160 y append / prepend / reverse / hexlify.
Attestations
Las hojas del árbol: pending (referencia a un calendario), Bitcoin, Litecoin y unknown para tipos futuros.
Merkle
Construye un solo árbol Merkle a partir de muchos documentos para sellar miles de pruebas con una única ancla.
Serialization
Lee y escribe el formato binario OTS. Estricta con Uint8Array, sin coerciones silenciosas.
Instalación
Instalación
Ejemplos
Ejemplos
Crear una prueba .ots local
Construye el árbol desde los bytes del archivo y le añade una attestation pending — una referencia al calendario, todavía sin confirmar en Bitcoin.
import { DetachedTimestampFile, OpSHA256, makePending } from '@otskit/core'
import { readFileSync, writeFileSync } from 'node:fs'
const content = new Uint8Array(readFileSync('document.pdf'))
const dtf = DetachedTimestampFile.fromBytes(new OpSHA256(), content)
dtf.timestamp.attestations.push(
makePending('https://alice.btc.calendar.opentimestamps.org')
)
writeFileSync('document.pdf.ots', dtf.serializeToBytes())Leer un .ots
Deserializa una prueba existente e inspecciona su digest y si ya está completa.
import { DetachedTimestampFile } from '@otskit/core'
const otsBytes = new Uint8Array(readFileSync('document.pdf.ots'))
const dtf = DetachedTimestampFile.deserialize(otsBytes)
console.log('Hash op: ', dtf.fileHashOp.tagName)
console.log('Digest: ', Buffer.from(dtf.fileDigest()).toString('hex'))
console.log('Complete: ', dtf.timestamp.isTimestampComplete())Verificar contra un block header
Recorre las attestations Bitcoin del árbol y comprueba el digest contra el Merkle root del bloque.
import { DetachedTimestampFile, verifyAgainstBlockheader } from '@otskit/core'
const dtf = DetachedTimestampFile.deserialize(new Uint8Array(readFileSync('document.pdf.ots')))
for (const { msg, attestation } of dtf.timestamp.allAttestations()) {
if (attestation.tagName === 'bitcoin') {
const ok = verifyAgainstBlockheader(msg, blockHeader)
console.log('Bloque', attestation.height, ok ? '✓ verificado' : '✗ fallo')
}
}Crear un Merkle tree
Une muchos documentos en un solo árbol — una única ancla para miles de pruebas.
import { makeMerkleTree, makePending, DetachedTimestampFile, OpSHA256 } from '@otskit/core'
const files = ['a.pdf', 'b.pdf', 'c.pdf']
const dtfs = files.map(f =>
DetachedTimestampFile.fromBytes(new OpSHA256(), new Uint8Array(readFileSync(f)))
)
// Un solo árbol Merkle — una sola ancla para todos
const root = makeMerkleTree(dtfs.map(d => d.timestamp))
root.attestations.push(makePending('https://alice.btc.calendar.opentimestamps.org'))
files.forEach((f, i) => writeFileSync(`${f}.ots`, dtfs[i].serializeToBytes()))Fail-closed por diseño
Fail-closed por diseño
Una attestation pending no es una confirmación Bitcoin: es una referencia a un calendario. La prueba se vuelve completa cuando aparece una attestation Bitcoin o Litecoin. Core nunca finge que una prueba está completa cuando no lo está.
Rechaza entradas malformadas
Cada frontera valida antes de seguir. Un .ots corrupto falla en la deserialización, no más tarde.
Uint8Array estricto
No acepta strings ni Buffers ambiguos donde espera bytes. El tipo es el contrato.
Sin coerciones silenciosas
Nunca adivina ni rellena valores por ti. Si algo no encaja, lo dice.
Errores tipados
Errores distintos para deserialización, operaciones, verificación y Merkle. Puedes ramificar con instanceof.
API surface
API surface
DetachedTimestampFile
DetachedTimestampFile.fromBytes(op, content)Crea desde bytes de archivoDetachedTimestampFile.fromHash(op, digest)Crea desde digest pre-computado.deserialize(bytes: Uint8Array)Parsea archivo .ots — solo Uint8Array, fail-closed.serializeToBytes()Serializa a bytes .ots.fileDigest()Retorna el digest del archivo.timestampNodo raíz del árbol de pruebaTimestamp
new Timestamp(msg)Crea nodo hoja.add(op)Aplica operación, retorna sub-timestamp.merge(other)Fusiona attestations y ramas.isTimestampComplete()true si existe attestation Bitcoin o Litecoin.allAttestations()Todos los pares {msg, attestation} en el árbolOperaciones criptográficas
OpSHA256SHA-256 (tag 0x08)OpSHA1SHA-1 (tag 0x02)OpRIPEMD160RIPEMD-160 (tag 0x03)OpAppend(suffix)Concatena sufijo (tag 0xf0)OpPrepend(prefix)Prepend prefijo (tag 0xf1)Attestations y Merkle
makePending(uri)Attestation pendiente de calendariomakeBitcoin(height)Attestation de blockchain BitcoinmakeLitecoin(height)Attestation de blockchain LitecoinmakeMerkleTree(timestamps)Construye Merkle-Mountain-RangeverifyAgainstBlockheader(digest, header)Verifica digest contra Merkle root de bloqueSiguiente paso
Si quieres usar esto en producción contra calendarios OpenTimestamps, sigue con @otskit/client.
@otskit/client — SDK de producción →