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:
- subscribe to or poll finalized heads;
- resolve the finalized block number/hash;
- call
temporal_getBlockTransactionTimestamps; - correlate
substrateHashorethHash; - store
timestampNsas 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
nullmeans “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.