Part 1: Open Concept
Hash any agreement data, anchor the hash to any blockchain, reference applicable terms. No vendor dependency.
Part 1 is the simplest possible integration. It requires no vendor dependency, no SDK, no API key. Any developer can implement this independently using only open standards.
The Concept
Three steps:
- Hash your terms document (SHA-256)
- Anchor the hash to any blockchain or timestamping service
- Reference the hash in your transactions
That is it. You now have provable evidence that specific terms existed at a specific time, and that specific transactions referenced those terms.
Step 1: Hash
Compute the SHA-256 hash of your terms document. The input MUST be the exact bytes of the document -- not a URL, not a summary, the raw content.
import { createHash } from "crypto";
import { readFileSync } from "fs";
const document = readFileSync("terms-of-service.html");
const hash = createHash("sha256").update(document).digest("hex");
const contentHash = `0x${hash}`;
console.log(contentHash);
// 0x7f83b1657ff1fc53b92dc18148a1d65dfc2d4b1fa3d677284addd200126d9069The resulting contentHash is a 0x-prefixed, 64-character hexadecimal string (66 characters total). This is the canonical format used throughout the protocol.
Step 2: Anchor
Record the hash on any blockchain or timestamping service. This proves the document existed at or before the timestamp of the anchoring transaction.
Option A: Any EVM chain
// Minimal existence proof -- just emit an event
event DocumentAnchored(bytes32 indexed contentHash, uint256 timestamp);
function anchor(bytes32 contentHash) external {
emit DocumentAnchored(contentHash, block.timestamp);
}Option B: Bitcoin (via OP_RETURN)
The contentHash (32 bytes) fits in a standard OP_RETURN output.
Option C: Timestamping service
Use any RFC 3161 timestamping service, OpenTimestamps, or similar. The hash format is compatible with all of them.
Step 3: Reference
Include the contentHash in your transaction metadata. The specific location depends on your payment protocol:
- TIP-20 transfers: The 32-byte
memofield - ERC-20 transfers: As calldata or an emitted event
- HTTP payments: As a response header or metadata field
- Invoices: As a reference field
At this point, you have:
- A document with a unique content hash
- Proof that the document existed at a specific time
- A link between payments and the terms that governed them
What You Get at Part 1
| Capability | Status |
|---|---|
| Document integrity | Yes -- SHA-256 hash proves content has not changed |
| Timestamp proof | Yes -- on-chain anchor proves existence before a time |
| Terms-to-payment binding | Yes -- hash in payment memo/metadata |
| Machine-discoverable terms | No -- requires Part 2 |
| Verification API | No -- requires Part 2 |
| Per-protocol integration | No -- requires Part 3 |
| Dispute resolution | No -- requires Part 4 |
Limitations
Part 1 is powerful but limited. You have proof, but no discovery mechanism. An agent cannot find your terms unless you tell it where to look out-of-band. There is no API for verification, acceptance, or dispute resolution.
Part 2 addresses these limitations by adding the legal-context.json discovery standard and the API gateway.