Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 116 additions & 0 deletions docs/api.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8" />
<title>json-trail - API</title>
<link rel="stylesheet" href="style.css" />
</head>

<body>
<main>

<h1>API Reference</h1>

<p>
json-trail exposes a minimal API for creating hash-linked blocks and
verifying their integrity. All operations use deterministic SHA-256 hashing and return plain data structures
containing Uint8Array fields.
</p>

<h2>createBlock(payload, prevBlock)</h2>

<p>
Creates a new hash-linked block. The payload must be a Uint8Array. If a
previous block is provided, its <code>blockHash</code> becomes the
<code>prevHash</code> of the new block.
</p>

<h3>Import</h3>
<pre><code>import { createBlock } from "json-trail";
</code></pre>

<h3>Usage</h3>
<pre><code>const enc = new TextEncoder();
const payload = enc.encode("hello");

const block = await createBlock(payload);
</code></pre>

<h3>Returns</h3>
<pre><code>{
index: number,
timestamp: number,
payload: Uint8Array,
payloadHash: Uint8Array,
prevHash: Uint8Array | null,
blockHash: Uint8Array
}
</code></pre>

<p>
Note: modifying a block or its payload after creation will invalidate its
hashes.
</p>

<hr />

<h2>verifyBlock(block)</h2>

<p>
Verifies the integrity of a single block. Returns <code>true</code> if
the <code>payloadHash</code> and <code>blockHash</code> match the block
contents.
</p>

<h3>Import</h3>
<pre><code>import { verifyBlock } from "json-trail";
</code></pre>

<h3>Usage</h3>
<pre><code>const ok = await verifyBlock(block);
</code></pre>

<h3>Returns</h3>
<pre><code>boolean
</code></pre>

<hr />

<h2>verifyChain(blocks)</h2>

<p>
Verifies the integrity of a sequence of blocks. Ensures each block is
valid and that each <code>prevHash</code> matches the previous
<code>blockHash</code>.
</p>

<h3>Import</h3>
<pre><code>import { verifyChain } from "json-trail";
</code></pre>

<h3>Usage</h3>
<pre><code>const ok = await verifyChain([block0, block1, block2]);
</code></pre>

<h3>Returns</h3>
<pre><code>boolean
</code></pre>

<nav>
<a href="index.html">Overview</a>
<a href="api.html">API</a>
<a href="examples.html">Examples</a>
<a href="integrity-model.html">Integrity Model</a>
<a href="seal-and-trail.html">Using json-seal with json-trail</a>
</nav>

<p class="external-links">
<a href="https://github.com/cmyers/json-trail">GitHub</a> ·
<a href="https://www.npmjs.com/package/json-trail">npm</a>
</p>

</main>
</body>

</html>
54 changes: 54 additions & 0 deletions docs/examples.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8" />
<title>json-trail - Examples</title>
<link rel="stylesheet" href="style.css" />
</head>

<body>
<main>

<h1>Examples</h1>

<h2>Basic usage</h2>

<pre><code>import { createBlock, verifyBlock, verifyChain } from "json-trail";

const enc = new TextEncoder();
const payload = enc.encode("hello world");

const block0 = await createBlock(payload);
const block1 = await createBlock(payload, block0);

console.log(await verifyBlock(block0));
console.log(await verifyBlock(block1));
console.log(await verifyChain([block0, block1]));
</code></pre>

<h2>Tampering detection</h2>

<pre><code>block1.payload[0] ^= 1;

console.log(await verifyBlock(block1)); // false
console.log(await verifyChain([block0, block1])); // false
</code></pre>

<nav>
<a href="index.html">Overview</a>
<a href="api.html">API</a>
<a href="examples.html">Examples</a>
<a href="integrity-model.html">Integrity Model</a>
<a href="seal-and-trail.html">Using json-seal with json-trail</a>
</nav>

<p class="external-links">
<a href="https://github.com/cmyers/json-trail">GitHub</a> ·
<a href="https://www.npmjs.com/package/json-trail">npm</a>
</p>

</main>
</body>

</html>
58 changes: 58 additions & 0 deletions docs/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8" />
<title>json-trail</title>
<link rel="stylesheet" href="style.css" />
</head>

<body>
<main>

<h1>json-trail</h1>
<p class="subtitle">
Tamper-evident, hash-linked blocks for apps. Zero dependencies.
</p>

<p>
json-trail is a tiny library for creating hash-linked blocks that detect
any modification to payloads or history. It provides chronological
integrity without keys, signatures, or complex state.
</p>

<h2>Why json-trail exists</h2>

<p>
Local-first apps store data on the device and sync when possible. Without
a server acting as the source of truth, you still need a way to know
whether your local history has been tampered with. json-trail provides a
minimal, deterministic, tamper-evident structure for that purpose.
</p>

<h2>Features</h2>
<ul>
<li>Deterministic SHA-256 hashing</li>
<li>Hash-linked blocks with prevHash</li>
<li>Pure JSON block format</li>
<li>Browser and Node support</li>
<li>Zero dependencies</li>
</ul>

<nav>
<a href="index.html">Overview</a>
<a href="api.html">API</a>
<a href="examples.html">Examples</a>
<a href="integrity-model.html">Integrity Model</a>
<a href="seal-and-trail.html">Using json-seal with json-trail</a>
</nav>

<p class="external-links">
<a href="https://github.com/cmyers/json-trail">GitHub</a> ·
<a href="https://www.npmjs.com/package/json-trail">npm</a>
</p>

</main>
</body>

</html>
55 changes: 55 additions & 0 deletions docs/integrity-model.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8" />
<title>json-trail - Integrity Model</title>
<link rel="stylesheet" href="style.css" />
</head>

<body>
<main>

<h1>Integrity Model</h1>

<p>
json-trail uses a simple hashing model to detect tampering.
</p>

<h2>Block structure</h2>
<ul>
<li>payloadHash = SHA-256(payload)</li>
<li>prevHash = previous block's blockHash (or null for the first block)</li>
<li>blockHash = SHA-256(index + timestamp + payloadHash + prevHash)</li>
</ul>

<h2>Block validity</h2>
<ul>
<li>payloadHash must match the payload</li>
<li>blockHash must match the block contents</li>
</ul>

<h2>Chain validity</h2>
<ul>
<li>every block must be valid</li>
<li>prevHash must match the previous blockHash</li>
<li>indexes must increase by 1</li>
</ul>

<nav>
<a href="index.html">Overview</a>
<a href="api.html">API</a>
<a href="examples.html">Examples</a>
<a href="integrity-model.html">Integrity Model</a>
<a href="seal-and-trail.html">Using json-seal with json-trail</a>
</nav>

<p class="external-links">
<a href="https://github.com/cmyers/json-trail">GitHub</a> ·
<a href="https://www.npmjs.com/package/json-trail">npm</a>
</p>

</main>
</body>

</html>
63 changes: 63 additions & 0 deletions docs/seal-and-trail.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8" />
<title>json-seal + json-trail</title>
<link rel="stylesheet" href="style.css" />
</head>

<body>
<main>

<h1>json-seal + json-trail</h1>

<p>
json-seal provides authenticity. json-trail provides chronological integrity.
Together, they form a signed, tamper-evident, hash-linked log entry.
</p>

<p>
npm: <a href="https://www.npmjs.com/package/json-seal">json-seal</a>
</p>

<h2>Example</h2>

<pre><code>import { generateKeyPair, signPayload, canonicalize } from "json-seal";
import { createBlock } from "json-trail";

const { privateKey, publicKey } = await generateKeyPair();

const sealed = await signPayload({ foo: 123 }, privateKey, publicKey);

// canonical, deterministic bytes for the block
const canonical = canonicalize(sealed);
const block = await createBlock(new TextEncoder().encode(canonical));
</code></pre>

<p>
Using <code>canonicalize</code> ensures that the bytes passed into
<code>createBlock</code> are deterministic. json-seal produces a stable,
canonical representation of the sealed envelope, so hashing it with
json-trail yields consistent results across platforms and runtimes.
</p>

<h2>Verification flow</h2>
<ul>
<li><code>verifyBackup(sealed)</code> checks authenticity</li>
<li><code>verifyBlock(block)</code> checks integrity</li>
<li><code>verifyChain([...])</code> checks ordering</li>
</ul>

<nav>
<a href="index.html">Overview</a>
<a href="api.html">API</a>
<a href="examples.html">Examples</a>
<a href="integrity-model.html">Integrity Model</a>
<a href="seal-and-trail.html">Using json-seal with json-trail</a>
</nav>

</main>
</body>

</html>
Loading