H3 Hexagonal Grid System
How Opacus divides the Earth into hexagonal cells — and uses them for agent routing, land ownership, and geospatial identity.
What is H3?
H3 is Uber's open-source hierarchical geospatial indexing system. It divides the Earth into hexagonal cells arranged in 16 resolution levels (0–15). Each resolution level subdivides every hexagon into approximately 7 child cells.
Opacus uses the h3-js library (Uber's official JavaScript port) to compute cell IDs, distances, and neighborhoods. Every agent, Nitro node, and land title is indexed to an H3 cell.
Resolution Levels
The table below shows all H3 resolution levels with approximate cell counts and areas. Each level has ~7× more cells than the previous.
| Resolution | Cell Count (approx.) | Area / Cell | Scale | Opacus Use |
|---|---|---|---|---|
0 | 122 | ~4,357,449 km² | Continent | — |
1 | 842 | ~609,788 km² | Sub-continent | — |
2 | 5,882 | ~86,745 km² | Large country | — |
3 | 41,162 | ~12,393 km² | Region / State | — |
4 | 288,122 | ~1,770 km² | Large metro | — |
5 | 2,016,842 | ~252 km² | City / Metro | Routing V1 Nitro node anchors, spam filter, market infra anchors |
6 | 14,117,882 | ~36 km² | District | — |
7 | 98,825,162 | ~5.2 km² | Neighborhood | — |
8 | 691,776,122 | ~0.74 km² | Neighborhood (~860m) | SDK default latLngToH3Cell() default, H3 Beacon Globe |
9 | 4,842,432,842 | ~0.1 km² | Block (~300m) | Agent Registry h3-registry.ts, ERC-7751 agent registration, discovery |
10 | 33,897,029,882 | ~0.015 km² | Building | — |
11 | 237,279,209,162 | ~2,150 m² | Large room | — |
12 | 1,660,954,464,122 | ~307 m² | Room (~17m) | WorldEvent agent-kernel WorldEvent spatial index, IoT precision |
13 | 11,626,681,248,842 | ~44 m² | Person-scale | — |
14 | 81,386,768,741,882 | ~6.3 m² | Desk-scale | — |
15 | 569,707,381,193,162 | ~0.9 m² | Object-scale | — |
Hexagonal Grid Visualization
Each parent hexagon contains exactly 1 center cell + 6 neighbors at the next resolution level. The diagram below shows res 5 cells (blue = city anchors, green = agent zone, purple = agent registered, orange = Nitro node).
How H3 Works in Opacus
Opacus uses H3 at three distinct layers, each at a different resolution:
2,016,842 cells
691M–4.8B cells
1.6T cells
Request Flow: GPS → H3 Cell → Nitro Node
lat/lon
ToCell(lat,lon,5)
85283473fffffffNitro node
established
IP geo
(lat,lon,9)
did:opacus:v1:h3:...registry
identity
Nitro Nodes & H3 Anchors
Each Opacus Nitro node is assigned to an H3 resolution 5 cell representing its geographic region. The routing engine uses great-circle distance between cell centers to select the nearest healthy node.
CitadelDID: H3 + Wallet Identity
A CitadelDID encodes both the agent's geospatial position (H3 cell) and its wallet address into a single on-chain identity string:
// Format
did:opacus:v1:h3:{h3CellIndex}:{walletAddress}
// Example (res 9, Istanbul)
did:opacus:v1:h3:891e353c0affff:0x1a2b3c4d...
// Core DID (no geo — always free, assigned to all agents)
did:opacus:v1:{agentId}
The CitadelDID is stored in the ERC-7751 registry contract on 0G Network. Any agent can query it to discover nearby agents by capability and proximity.
lon: 28.9784
891e353c0affffdid:opacus:v1:h3:
891e353c0affff:0x1a2b...
on-chain
SDK Usage
import { latLngToH3Cell, H3RoutingClient, citadelDID } from 'opacus-sdk/h3';
import { ethers } from 'ethers';
// 1. Convert GPS → H3 cell (res 9, ~0.1 km² block scale)
const h3Index = latLngToH3Cell(41.0082, 28.9784, 9); // Istanbul
// → '891e353c0affff'
// 2. Build a CitadelDID
const did = citadelDID(h3Index, wallet.address);
// → 'did:opacus:v1:h3:891e353c0affff:0xabc...'
// 3. Register on ERC-7751 (0G Network)
const h3Client = new H3RoutingClient(signer, process.env.ERC7751_CONTRACT);
await h3Client.register({
h3Index: ethers.id(h3Index),
quicEndpoint: 'quic://my-agent.example.com:4433',
capabilities: [
ethers.id('exec.evm.public_tx'),
ethers.id('data.oracle.price'),
],
kineticScore: 75,
value: ethers.parseEther('0.001') // registration bond
});
// 4. Discover nearby agents by capability (within ~5 km at res 9)
const nearby = await h3Client.findAgents({
h3Index: ethers.id(h3Index),
radiusCells: 2, // H3 grid steps
capability: ethers.id('exec.evm.public_tx')
});
// → [{ wallet, h3Index, quicEndpoint, kineticScore }, ...]
// 5. Resolve nearest Nitro node for this H3 cell
const node = await opacus.nitro.resolve({ h3Index });
// → { endpoint: 'quic://us-iad-1.0g.network:4433', latencyMs: 12 }
H3 API Reference
GET /v1/routing/anchors
Returns the H3 cell and nearest Nitro nodes for a GPS coordinate.
| Param | Type | Description |
|---|---|---|
lat | float | Latitude (-90 to 90) |
lon | float | Longitude (-180 to 180) |
resolution | int | H3 resolution 0–12 (default: 8) |
curl "https://opacus.xyz/api/v1/routing/anchors?lat=41.0082&lon=28.9784&resolution=9" \
-H "Authorization: Bearer obr_agent_..."
// Response
{
"ok": true,
"cellId": "891e353c0affff",
"resolution": 9,
"area_km2": 0.1,
"center": { "lat": 41.0097, "lng": 28.9801 },
"anchors": [
{ "endpoint": "quic://de-fra-1.0g.network:4433", "region": "eu-central",
"distanceKm": 2174, "latencyMs": 9 }
],
"nitroNode": {
"id": "de-fra-1", "label": "Frankfurt",
"endpoint": "quic://de-fra-1.0g.network:4433", "latencyMs": 9
}
}
GET /v1/land/:h3Index
Query iNFT land ownership for a specific H3 cell.
curl "https://opacus.xyz/api/v1/land/891e353c0affff" \
-H "Authorization: Bearer obr_agent_..."
// Response — unowned cell
{ "ok": true, "h3Index": "891e353c0affff", "owned": false }
// Response — owned cell
{
"ok": true,
"h3Index": "891e353c0affff",
"owned": true,
"owner": "0x1a2b3c4d...",
"inft_token_id": "0x0000...0042",
"chain": "0g",
"micro_fee_bps": 25
}
POST /v1/land/register
Register an iNFT land title for an H3 cell. Requires pay.gas_subsidy scope token.
curl -X POST "https://opacus.xyz/api/v1/land/register" \
-H "Authorization: Bearer obr_pay_..." \
-H "Content-Type: application/json" \
-d '{
"h3_index": "891e353c0affff",
"inft_token_id": "0x0000...0042"
}'
GET /api/v1/agents/h3
List all agents registered to H3 cells. Filter by proximity.
curl "https://opacus.xyz/api/v1/agents/h3?h3Index=891e353c0affff&radius=3" \
-H "Authorization: Bearer obr_agent_..."
iNFT Land Registry
Every H3 cell can be claimed as a land title — represented as an iNFT on 0G Chain. When an agent executes a transaction inside a claimed cell, a 0.25% micro-fee is automatically routed to the land owner.
Zone Revenue Distribution
Transaction
Agent executes in an H3 cell
(swap/bridge/task)
Zone Revenue Pool
0.25% micro-fee collected
per transaction
Distribution (daily epoch)
20% Protocol treasury
56% Land owner (70% of 80%)
24% Node sponsor (30% of 80%)
How to Claim a Cell
- Mint an iNFT on 0G Chain representing the H3 cell index.
- Call
POST /v1/land/registerwith theh3_indexandinft_token_id. - All transactions in that cell automatically trigger micro-fee routing.
- Claim earnings each daily epoch via the land registry contract.
- Micro-fee:
_INFT_LAND_MICRO_FEE_BPS = 25→ 0.25% per transaction - Protocol cut:
20%of zone revenue - Land owner share:
70%of zone royalty pool - Node sponsor share:
30%of zone royalty pool - Epoch duration:
24 hours(UTC 00:00 – 23:59)
Spam Filter & H3 Reputation
Each agent × H3 cell pair has an independent rate-limit bucket. Exceeding 100 submissions per 100ms window counts as a violation. 5 violations triggers a slash (agent removed from discovery).
| Parameter | Value | Notes |
|---|---|---|
| Window size | 100ms | Sliding window per agent × cell pair |
| Max burst | 100 submissions | Per window |
| Violations → slash | 5 | Agent removed from H3 discovery index |
| Reputation score | max(0, 100 − violations × 10) | Decays with violations |