Temporal RPC Quickstart
Query finalized temporal data without losing nanosecond precision.
Build with ROKO nanosecond time
ROKO timestamps ordinary EVM and Substrate transactions automatically. A user does not submit a special “timed transaction” envelope.
Know which time you are reading
| Value | Meaning |
|---|---|
| mesh consensus time | the node's current PTP² mesh estimate |
| canonical transaction timestamp | timestamp assigned to a transaction |
| transaction watermark | highest canonical timestamp processed by chain state |
| block nanosecond timestamp | temporal metadata attached to a block |
| EVM `block.timestamp` | conventional EVM seconds, not ROKO nanoseconds |
Nanosecond representation does not promise nanosecond wall-clock accuracy. Inspect convergence, peer count, time quality, source distance, and application latency.
Query mesh time
curl --fail --silent --show-error https://rpc.roko.network \
-H 'content-type: application/json' \
--data '{"jsonrpc":"2.0","id":1,"method":"temporal_getConsensusTime","params":[]}'
Current shape:
{
"consensusTimeNs": "1785196016508998403",
"timeQuality": 7697,
"convergenceState": "Converged",
"peerCount": 5,
"consensusOffsetNs": "-1062154"
}
Treat the value as authoritative for your use only when `convergenceState == "Converged"` and your policy accepts the quality and peer count. `timeQuality` uses 0..10,000, where 10,000 is 100%.
Query a transaction
Both a Substrate extrinsic hash and an Ethereum transaction hash are accepted:
curl --fail --silent --show-error https://rpc.roko.network \
-H 'content-type: application/json' \
--data '{
"jsonrpc":"2.0",
"id":1,
"method":"temporal_getTransactionTimestamp",
"params":["<32_BYTE_TRANSACTION_HASH>"]
}'
The result is a decimal nanosecond string or `null` when unknown.
For finality-aware processing:
1. subscribe to or poll finalized heads; 2. resolve the finalized block number/hash; 3. call `temporal_getBlockTransactionTimestamps`; 4. correlate `substrateHash` or `ethHash`; 5. store `timestampNs` as a decimal string or arbitrary-precision integer.
Precision rules
Unix nanoseconds are already larger than JavaScript's `Number.MAX_SAFE_INTEGER`.
const ns = BigInt(response.result.consensusTimeNs);
const seconds = ns / 1_000_000_000n;
const subsecondNs = ns % 1_000_000_000n;
Never call `Number()` on a full nanosecond value. Convert only a bounded display unit after checking its range. `JSON.stringify` also rejects `BigInt`, so serialize nanoseconds back to decimal strings.
Python's `int` preserves these values:
ns = int(result["consensusTimeNs"])
seconds, subsecond_ns = divmod(ns, 1_000_000_000)
Current wire-format caveat
Most current temporal RPC nanosecond fields are quoted decimal strings. The legacy `temporal_getWatermarkInfo` and `temporal_getBlockMetadata` responses can still contain unquoted JSON integers larger than JavaScript's safe range. Native `JSON.parse()` can round those values before application code sees them. Until those RPCs emit strings consistently, use a lossless/BigInt JSON parser or query them from a language such as Python with arbitrary-precision JSON integers.
Useful methods
| Method | Use |
|---|---|
| `temporal_getConsensusTime` | current mesh estimate and quality |
| `temporal_getMeshState` | convergence and per-peer measurement summary |
| `temporal_getWatermarkInfo` | current transaction watermark |
| `temporal_getTransactionTimestamp` | canonical timestamp by transaction hash |
| `temporal_getBlockMetadata` | temporal metadata for a block number |
| `temporal_getBlockTransactionTimestamps` | hashes and timestamps by extrinsic index |
| `temporal_getQueueStats` | local fee-priority queue statistics |
| `temporal_getTransactionWaitTime` | local queue timing for one transaction |
| `temporal_getRecentWaitTimes` | recent local wait-time samples |
Queue statistics are node-local and can reset on restart. Historical data may require an archive node.
Examples
- Node.js reads string-encoded nanoseconds as `BigInt`;
- Python preserves all JSON integer precision and polls finalized temporal
block metadata.
Failure handling
- `null` means “not available/known,” not timestamp zero.
- Reject malformed or non-32-byte transaction hashes.
- Apply an HTTP timeout and exponential backoff.
- Use finalized heads when reorganization would be harmful.
- Degrade gracefully when the mesh is initializing, converging, degraded, or
below your minimum peer/quality policy.
- Verify chain genesis and EVM chain ID before trusting an endpoint.