Contractless/docs/DEV_CLIENTS.md

3.1 KiB

Developer Client Notes

This file contains low-level notes for building external clients or debugging the Contractless RPC client flow. It is not required for normal node setup.

RPC Clients

RPC clients are not treated the same as mining nodes. A client must follow the handshake format exactly, or the server may classify it as a node/miner instead of a client. When that happens, client tools can hang, be rejected or behave unexpectedly.

Required Client Handshake Rules

  1. Use a valid wallet address and signature in the handshake.
  • The client must load a real wallet locally.
  • The wallet encryption key is used only locally to open the wallet and sign the handshake.
  • The wallet encryption key is not sent over the stream.
  • The wallet address is sent as part of the handshake identity.
  1. The opening handshake message must be aced.
  • The client signs the hash of aced.
  • The server verifies that signature against the wallet address supplied in the handshake.
  1. A client must advertise its IP with port 0.
  • Example: 127.0.0.1:0
  • This is the rule that tells the server the connection is a client-style RPC connection rather than a mining node connection.
  • The server checks whether the submitted ip:port is externally reachable.
  • If the submitted port is open, the connection is treated as a miner/node.
  • If the submitted port is 0 or not reachable, the connection is treated as a client.
  1. The client timestamp must be within 1 second of the server timestamp.
  • If the timestamp is too far off, the handshake is rejected.
  1. The submitted IP must match the caller IP seen by the server.
  • The server compares the claimed IP in the handshake against the actual remote peer IP.

Handshake Byte Layout

The client sends:

  • 2 bytes: message (aced)
  • 65 bytes: recoverable signature
  • 21 bytes: wallet address
  • 4 bytes: timestamp
  • 18 bytes: ip:port

Total client handshake size:

  • 110 bytes

The server returns:

  • 2 bytes: message
  • 65 bytes: recoverable signature
  • 21 bytes: wallet address

Total server handshake size:

  • 88 bytes

Server Return Messages

After the client handshake is accepted:

  • miner/node connections receive face
  • client connections receive ecaf

RPC clients should expect ecaf.

If you do not follow the client rules above, especially the ip:0 rule, the server can classify your connection as a mining/node connection instead of a client connection. That will cause errors for standalone RPC tools.

RPC Request Format After Handshake

After the handshake succeeds, the client sends:

  • 1 byte: command
  • 3 bytes: request uid
  • command-specific payload bytes if required

Normal RPC replies are returned as:

  • 1 byte: reply command (111)
  • 3 bytes: request uid
  • 2 bytes: payload length
  • payload bytes

Practical Note For Standalone Tools

Standalone tools in src/bin should behave like clients, not mining nodes. Their handshake should therefore:

  • use a real wallet
  • send aced
  • sign it correctly
  • advertise your_ip:0

If a standalone tool advertises a real RPC/mining port instead of 0, the server may treat it as a node connection and the tool can fail in confusing ways.