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 payloadconst payload = {market_id: 0, // RLM-PERPside: 0, // BUYtype: 0, // LIMITprice: 10000000000, // 100.00000000 (8 decimals)size: 100000000, // 1.00000000 (8 decimals)time_in_force: 0, // GTCtimestamp: Date.now() * 1_000_000, // Nanosecondsnonce: accountNonce + 1, // Monotonic};// 2. Serialize to protobuf bytesconst payloadBytes = PlaceOrderRequest.encode(payload).finish();// 3. Sign with Dilithium-3const signature = await wallet.sign(payloadBytes);// 4. Attach to requestconst request = {public_key: wallet.publicKey, // 1952 bytessignature: 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 signingawait client.connect(wallet);// All subsequent requests are automatically signedconst 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 GetAccountSummaryconst 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 sizesconst PUBLIC_KEY_SIZE = 1952; // bytesconst SECRET_KEY_SIZE = 4032; // bytesconst SIGNATURE_SIZE = 3309; // bytes// Address derivationconst address = blake3(publicKey); // 32 bytes hex// The SDK uses @noble/post-quantum for Dilithiumimport { 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);
| Property | Value |
|---|---|
| Algorithm | ML-DSA-65 (Dilithium-3) |
| Security Level | NIST Level 3 (AES-192 equivalent) |
| Public Key | 1,952 bytes |
| Secret Key | 4,032 bytes |
| Signature | 3,309 bytes |
| Hash Function | SHAKE-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:
PingGetChainInfoGetMarketsGetOrderbookGetTradesGetFundingRateGetMarkPrice
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.