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

ValueMeaning
mesh consensus timethe node's current PTP² mesh estimate
canonical transaction timestamptimestamp assigned to a transaction
transaction watermarkhighest canonical timestamp processed by chain state
block nanosecond timestamptemporal 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

MethodUse
`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

See `examples/temporal-rpc`:

  • 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.