Content Paths
Oak Chain uses wallet-based namespacing with deterministic ownership and routing. The path is itself a contract: it encodes who can write where, how content shards across nodes, and how the indexer organizes retrieval. Get the path structure wrong and you get unpredictable ownership semantics and brittle queries; get it right and ownership is wallet-cryptographic, sharding falls out for free, and AEM-style sub-paths (/content, /conf, /apps) work normally inside each wallet's scope.
Map one real wallet and organization structure to the template below before implementing write flows.
Path Structure
/oak-chain/{L1}/{L2}/{L3}/0x{wallet}/{organization}/content/...
{L1}/{L2}/{L3}74/2d/350x{wallet}0x742d35cc...{organization}PixelPiratescontent/Example
For wallet 0x742d35cc6634c0532925a3b844bc454e4438f44e:
/oak-chain/74/2d/35/0x742d35cc6634c0532925a3b844bc454e4438f44e/
├── PixelPirates/
│ ├── content/ ← Gaming brand content
│ │ └── games/
│ └── conf/ ← Gaming brand config
├── CryptoKitchenware/
│ ├── content/ ← eCommerce content
│ │ └── products/
│ └── conf/
└── PersonalBlog/
└── content/ ← Personal content
└── posts/
The write API creates each item directly under {organization}/content/, or under content/ when no organization is given. Deeper folders such as games/ and the conf/ scope, here and below, are a layout convention. The API does not create them today.
Why This Structure?
1. Wallet = Namespace
Your Ethereum wallet owns your namespace. The validator builds the path from the signing wallet, so in sepolia mode only a valid signature from that wallet can write to it. Mock mode, the default, does not verify signatures.
Only 0x742d35cc... can write to:
/oak-chain/74/2d/35/0x742d35cc.../...
2. Sharding for Scale
The {L1}/{L2}/{L3} prefix enables:
- 256³ = 16.7M shards
- Deterministic routing by wallet-derived path prefix
- Fault isolation: Issues contained to shard
- Parallel processing: Shards processed independently
Clusters can own explicit ranges of the first level ({L1}). With -Doak.sharding.enabled=true, a validator redirects writes for a wallet owned by another cluster (307, wrong_shard) and refuses prefixes no cluster claims (503). Sharding is off by default, so a single cluster accepts every wallet. Remote clusters may mount a namespace read-only. Cross-cluster deployments are not yet validated.
3. Organization Scope
One wallet can own multiple brands:
# Gaming brand
/oak-chain/74/2d/35/0xWALLET/PixelPirates/content/games/nft-drop
# eCommerce brand
/oak-chain/74/2d/35/0xWALLET/CryptoKitchenware/content/products/spatula
# Personal
/oak-chain/74/2d/35/0xWALLET/PersonalBlog/content/posts/hello-world
4. AEM Compatibility
Within each scope, standard AEM paths work:
{scope}/content/... ← Content
{scope}/conf/... ← Configuration
{scope}/apps/... ← Components (future)
Path Validation
// WalletPathUtil.java (simplified)
public static String getContentPath(String wallet, String org) {
String shardRoot = getShardRoot(wallet); // /oak-chain/{L1}/{L2}/{L3}/0x{lowercase wallet}
if (org == null || org.isEmpty()) {
return shardRoot + "/content";
}
return shardRoot + "/" + org + "/content";
}
Rules
0x742d35cc...742d35Cc...My-Brand_123My/Brand/content/page/../secretWrite Example
curl -X POST http://localhost:8090/v1/propose-write \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "proposalId=0x1111111111111111111111111111111111111111111111111111111111111111" \
-d "walletAddress=0x742d35cc6634c0532925a3b844bc454e4438f44e" \
-d "organization=PixelPirates" \
--data-urlencode "message={\"title\":\"New NFT Drop!\",\"date\":\"2026-01-10\"}" \
-d "contentType=page" \
-d "ethereumTxHash=<tx hash; in mock mode, reuse the proposalId>" \
-d "signature=<personal_sign of the exact message>"
See Authentication for how to sign the message.
The validator constructs the full path and returns it as storagePath in the 202 response. The item name is {contentType}-{milliseconds}-{first 8 hex characters of proposalId}:
/oak-chain/74/2d/35/0x742d35cc.../PixelPirates/content/page-1767225600000-11111111
Cross-Organization References
Content can reference other organizations (read-only):
{
"title": "Partnership Announcement",
"partner": {
"ref": "/oak-chain/ab/cd/ef/0xPARTNER.../TheirBrand/content/about"
}
}
Content Structure Within Namespaces
Each wallet/brand namespace should maintain consistent content structure for indexing and querying to work efficiently.
Key point: Oak Chain doesn't enforce content structure at the consensus layer, but brand maintainers should enforce consistency within their namespace for queries to work.
Operational Model
- Intra-cluster consensus: the authoritative cluster owns writes for the namespace and replicates them via local Aeron/Raft.
- Cross-cluster reads: other clusters can expose the namespace through lazy read-only mounts.
- Discovery (not built yet): cluster announcements or registries belong to a separate control plane and should not be confused with consensus.
Next Steps
- API Reference - Endpoints and route taxonomy
- Architecture - Full system design
- Smart Contract - Prices and payment contract