Authentication

Realm uses Dilithium-3 (ML-DSA-65) post-quantum signatures for authentication. No API keys — every request is signed with your private key.

SDK Handles This

If you're using the TypeScript SDK, authentication is handled automatically after calling client.connect(wallet). This page is for understanding the protocol or implementing custom clients.

Overview

Every authenticated request includes:

  • public_key — Your Dilithium-3 public key (1952 bytes)
  • signature — Signature of the request payload (3309 bytes)
  • timestamp — Unix timestamp in nanoseconds
  • nonce — Monotonically increasing counter

Signature Flow

typescript
// 1. Build the request payload
const payload = {
market_id: 0, // RLM-PERP
side: 0, // BUY
type: 0, // LIMIT
price: 10000000000, // 100.00000000 (8 decimals)
size: 100000000, // 1.00000000 (8 decimals)
time_in_force: 0, // GTC
timestamp: Date.now() * 1_000_000, // Nanoseconds
nonce: accountNonce + 1, // Monotonic
};
// 2. Serialize to protobuf bytes
const payloadBytes = PlaceOrderRequest.encode(payload).finish();
// 3. Sign with Dilithium-3
const signature = await wallet.sign(payloadBytes);
// 4. Attach to request
const request = {
public_key: wallet.publicKey, // 1952 bytes
signature: signature, // 3309 bytes
...payload,
};

Using the SDK

The SDK handles all signing automatically:

typescript
import { RealmClient, RealmWallet } from '@empyrealm/sdk';
const client = new RealmClient('https://api.realm.software');
const wallet = await RealmWallet.generate();
// Connect automatically handles all signing
await client.connect(wallet);
// All subsequent requests are automatically signed
const balance = await client.getBalance();
const order = await client.placeOrder({ ... });

Nonce Management

Nonces prevent replay attacks. Each nonce must be strictly greater than the previous one used by your account.

typescript
// Nonces must be strictly increasing
// The SDK handles this automatically, but if implementing manually:
let currentNonce = 0;
async function signRequest(payload) {
currentNonce += 1;
const request = {
...payload,
nonce: currentNonce,
timestamp: Date.now() * 1_000_000,
};
// Sign and send...
}
// If you receive INVALID_NONCE, fetch current nonce from GetAccountSummary
const summary = await client.getAccountSummary();
currentNonce = summary.nonce;

Nonce Ordering

If you submit requests in parallel, ensure each has a unique, increasing nonce. The SDK uses a mutex internally to guarantee ordering.

Timestamp Validation

Timestamps must be within ±60 seconds of server time. This prevents replay attacks with old requests. Use nanosecond precision:

typescript
const timestamp = BigInt(Date.now()) * 1_000_000n; // Nanoseconds

Dilithium-3 (ML-DSA-65)

Realm uses NIST's standardized post-quantum signature algorithm:

typescript
// Dilithium-3 (ML-DSA-65) key sizes
const PUBLIC_KEY_SIZE = 1952; // bytes
const SECRET_KEY_SIZE = 4032; // bytes
const SIGNATURE_SIZE = 3309; // bytes
// Address derivation
const address = blake3(publicKey); // 32 bytes hex
// The SDK uses @noble/post-quantum for Dilithium
import { ml_dsa65 } from '@noble/post-quantum/ml-dsa';
const keys = ml_dsa65.keygen();
const signature = ml_dsa65.sign(keys.secretKey, message);
const valid = ml_dsa65.verify(keys.publicKey, message, signature);
PropertyValue
AlgorithmML-DSA-65 (Dilithium-3)
Security LevelNIST Level 3 (AES-192 equivalent)
Public Key1,952 bytes
Secret Key4,032 bytes
Signature3,309 bytes
Hash FunctionSHAKE-256

Address Derivation

Your address is the BLAKE3 hash of your public key:

text
address = blake3(publicKey) // 32 bytes, displayed as 64 hex chars

Public Endpoints

These endpoints don't require authentication:

  • Ping
  • GetChainInfo
  • GetMarkets
  • GetOrderbook
  • GetTrades
  • GetFundingRate
  • GetMarkPrice

Security Considerations

  • Never expose your secret key — The 4032-byte secret key must remain private. Use hardware security modules in production.
  • Use fresh nonces — Never reuse nonces. The blockchain rejects duplicate nonces.
  • Verify signatures — When receiving data from the API, verify any included signatures.
  • Quantum-safe — Dilithium-3 is secure against both classical and quantum computers.