Skip to content

Blocks

A block represents a single unit of agent activity — a message, a decision, a tool call, a commitment.

import synpareia
profile = synpareia.generate()
# Simple text content
block = synpareia.create_block(profile, "message", "Hello, world!")
# With metadata
block = synpareia.create_block(
profile, "message", "Analysis complete",
metadata={"model": "claude-opus-4-6", "tokens": 1523}
)
# Custom block types
block = synpareia.create_block(profile, "tool_call", '{"name": "search", "args": {"q": "trust"}}')

Every block contains:

FieldDescription
idUnique identifier (blk_ prefix + UUID hex)
typeWhat kind of activity (message, thought, commitment, anchor, etc.)
author_idDID of the creating agent
content_hashSHA-256 of the content — always present
contentThe actual content — present in full mode, absent in hash_only mode
created_atUTC timestamp
signatureEd25519 signature over the block’s canonical representation
metadataOptional key-value pairs

Blocks support three content modes for privacy control:

Both content and its hash are present. Anyone with the block can read the content.

block = synpareia.create_block(profile, "message", "visible content")
assert block.content is not None
assert block.content_hash is not None

Only the content hash is stored. The content existed when the hash was computed, but isn’t included. Useful for privacy-preserving chains where you want to prove structure without revealing content.

from synpareia.types import ContentMode
block = synpareia.create_block(
profile, "message", "private content",
content_mode=ContentMode.HASH_ONLY,
)
assert block.content is None
assert block.content_hash is not None # hash is still there

A hash-only block that has been revealed — content filled back in and verified against the original hash.

revealed = synpareia.reveal_block(hash_only_block, "private content")
# Raises ValueError if content doesn't match the hash

Blocks are signed over their canonical representation — not just the content, but the full identity of the block:

sign({id, type, author_id, content_hash, created_at})

This prevents metadata substitution: you can’t take a valid signature and attach it to a block with a different type, author, or timestamp.

# Verify a block's signature
valid = synpareia.verify_block(block)
TypePurpose
messageA message sent by the agent
thoughtInternal reasoning (chain-of-thought)
reactionResponse to another block
commitmentHash commitment for commit-reveal schemes
anchorCross-chain reference
sealWitness service timestamp
systemSystem-generated events
join / leaveParticipation signals

Custom types are also supported — pass any string as the type.

Built by Sam Hyland · Canberra, Australia