Message Format
The Nitro RPC protocol uses a compact, efficient message format for all communication between clients and a clearnode.
General Structure
Every Nitro RPC message consists of a compact JSON array format:
[requestId, method, params, timestamp]
This array-based format reduces message overhead by approximately 30% compared to traditional JSON-RPC, making it ideal for high-frequency state channel operations.
Components
| Component | Type | Description |
|---|---|---|
| requestId | uint64 | Unique identifier for the request, used to correlate responses |
| method | string | Remote method name to be invoked |
| params | object | Method-specific parameters as a JSON object |
| timestamp | uint64 | Server-provided timestamp in milliseconds |
requestId
- Purpose: Correlate requests with their responses
- Type: Unsigned 64-bit integer
- Generation: Client-generated, must be unique per connection
- Range: 0 to 2^64-1
- Example:
1,42,9876543210
method
- Purpose: Specify which RPC method to invoke
- Type: String
- Format: snake_case (e.g.,
create_channel, notcreateChannel) - Examples:
auth_request,transfer,create_app_session
params
- Purpose: Provide method-specific parameters
- Type: JSON object
- Content: Varies by method
- Example:
{"chain_id": 137, "token": "0x...", "amount": "100000000"} - Reference: See Authentication, Channel Methods, Transfers, App Sessions, and Queries for parameter specifications
timestamp
- Purpose: Request ordering and replay attack prevention
- Type: Unsigned 64-bit integer (Unix milliseconds)
- Generation: Client-provided on requests; server-provided on responses
- Example:
1699123456789(November 5, 2023, 01:57:36 UTC)
Request Message
A complete request message wraps the payload array and includes signatures.
Structure
{
"req": [requestId, method, params, timestamp],
"sig": [signature1, signature2, ...]
}
Fields
req
The request payload as a 4-element array containing:
- Request ID
- Method name
- Parameters object
- Timestamp
sig
Array of ECDSA signatures, one or more depending on the operation:
- Single signature: Most operations (signed by client's session key)
- Multiple signatures: Multi-party operations (e.g., app session creation)
Signature Format
Each signature is:
- Format: 0x-prefixed hex string
- Length: 65 bytes (130 hex characters + "0x" prefix)
- Components: r (32 bytes) + s (32 bytes) + v (1 byte)
- Algorithm: ECDSA over secp256k1 curve
- Hash: keccak256 of the exact
reqarray bytes
Example Signature:
0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef01
This signature format (ECDSA over secp256k1 with keccak256 hashing) is specific to EVM-compatible chains. If the protocol extends to support non-EVM chains in the future, signature formats may need to be adapted to match those chains' native cryptographic primitives.
Signatures are computed over the keccak256 hash of the JSON-encoded req array. The JSON encoding MUST be consistent (same key ordering, no extra whitespace) to ensure signature validity.
Complete Example
{
"req": [
1,
"auth_request",
{
"address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
"session_key": "0x9876543210fedcba9876543210fedcba98765432",
"application": "trading-dex",
"allowances": [
{"asset": "usdc", "amount": "1000.0"},
{"asset": "eth", "amount": "0.5"}
],
"scope": "transfer,app.create",
"expires_at": 1762417328123
},
1699123456789
],
"sig": [
"0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef01"
]
}
Response Message
The clearnode sends response messages with the same structure, replacing params with result.
Structure
{
"res": [requestId, method, result, timestamp],
"sig": [signature1, ...]
}
Fields
res
The response payload as a 4-element array:
- Same requestId (to correlate with request)
- method (response method name)
- Usually matches the request method
- Exception:
auth_request→ response hasauth_challengemethod - Exception: Errors → response has
errormethod
- result (method-specific response data, replaces params)
- timestamp (server response time)
sig
The clearnode's signature(s) over the response:
- Proves response authenticity
- Verifies response hasn't been tampered with
- Enables non-repudiation
Complete Example
{
"res": [
1,
"auth_challenge",
{
"challenge_message": "550e8400-e29b-41d4-a716-446655440000"
},
1699123457000
],
"sig": [
"0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890ab"
]
}
Error Response
When an error occurs, the clearnode sends an error response with method set to "error".
Structure
{
"res": [
requestId,
"error",
{
"error": "Error description message"
},
timestamp
],
"sig": ["0xServerSignature..."]
}
The result object at position 2 contains a single "error" field with a descriptive error message string.
Error Examples
Authentication Required:
{
"res": [
5,
"error",
{
"error": "Authentication required: session not established"
},
1699123456789
],
"sig": ["0xServerSignature..."]
}
Insufficient Balance:
{
"res": [
12,
"error",
{
"error": "Insufficient balance: required 100 USDC, available 75 USDC"
},
1699123456790
],
"sig": ["0xServerSignature..."]
}
Method Not Found:
{
"res": [
8,
"error",
{
"error": "Method not found: 'invalid_method'"
},
1699123456791
],
"sig": ["0xServerSignature..."]
}
Check the response method field (position 1 in res array). If it equals "error", extract the error message from the result object's error field. The error message provides human-readable context about what went wrong.
Payload Hash Computation
Every RPC message (request or response) is signed over the exact serialized req or res array bytes.
What is Signed
- Requests: The
reqarray[requestId, method, params, timestamp]exactly as sent - Responses: The
resarray[requestId, method, result, timestamp]exactly as received
Hash Formula
payloadHash = keccak256(<exact JSON bytes of req or res>)
Use the same bytes you transmit (or receive) when computing/verifying the hash; do not re-serialize with different spacing or key ordering.
Example
Request Payload:
[42,"create_app_session",{"definition":{...},"allocations":[...]},1699123456789]
Hash that exact byte string, then sign it (client for requests, clearnode for responses).
Message Flow Diagram
The following diagram illustrates the complete request-response cycle:
Signature Verification Process
Both clients and a clearnode MUST verify signatures on all messages.
Client Verifying a Clearnode Response
- Extract Response: Get
resarray from response - Compute Hash:
hash = keccak256(<exact res bytes>) - Recover Address: Use
sigto recover signer address - Verify: Confirm recovered address matches the clearnode's known address
A Clearnode Verifying Client Request
- Extract Request: Get
reqarray from request - Compute Hash:
hash = keccak256(<exact req bytes>) - Recover Address: Use
sigto recover signer address - Verify: Confirm recovered address matches authenticated user or registered session key
Most messages MUST be cryptographically signed and verified. All state-changing operations (channel creation/closure, transfers, app sessions) and authenticated methods require valid signatures. However, some query methods (such as get_config) may be accessed without signatures. Refer to individual method specifications for signature requirements.
JSON Encoding Consistency
To ensure signature validity, JSON encoding MUST be consistent across all implementations.
Requirements
- Key Ordering: Object keys MUST be in a deterministic order
- No Whitespace: Remove all unnecessary whitespace
- No Trailing Commas: Standard JSON (no trailing commas)
- UTF-8 Encoding: Use UTF-8 character encoding
- Number Format: Numbers as strings for large integers (avoid precision loss)
Canonical Example
Consistent (valid for signing):
[1,"transfer",{"amount":"100","asset":"usdc","destination":"0x..."},1699123456]
Inconsistent (would produce different hash):
[ 1, "transfer", { "destination": "0x...", "amount": "100", "asset": "usdc" }, 1699123456 ]
Use a JSON library that supports canonical JSON serialization, or implement strict key ordering and whitespace removal before computing hashes.
Next Steps
Now that you understand the message format, explore how it's used in practice:
- Authentication - Learn the 3-step authentication flow
- Channel Methods - See request/response examples for channel operations
- Transfers - Understand transfer message structure
- App Sessions - Explore multi-signature app session messages
For a high-level overview, return to Off-Chain RPC Overview.