RougeChain Documentation
Welcome to RougeChain — a post-quantum secure Layer 1 blockchain built with real NIST-approved cryptography.
What is RougeChain?
RougeChain is the first blockchain designed from the ground up to be resistant to quantum computer attacks. It uses:
- ML-DSA-65 (CRYSTALS-Dilithium) for digital signatures
- ML-KEM-768 (CRYSTALS-Kyber) for key encapsulation
- SHA-256 for hashing
All cryptographic primitives are NIST FIPS 204/203 compliant.
Key Features
| Feature | Description |
|---|---|
| Post-Quantum Security | Protected against both classical and quantum attacks |
| Client-Side Signing | Private keys never leave your browser |
| AMM/DEX | Uniswap V2-style liquidity pools and token swaps |
| Token Burning | Official burn address with on-chain tracking |
| Proof of Stake | Energy-efficient consensus with validator staking |
| P2P Network | Decentralized peer-to-peer block and transaction propagation |
| qETH Bridge | Bridge ETH from Base Sepolia to qETH on RougeChain |
| Custom Tokens | Create your own tokens on the network |
| RC-721 NFTs | NFT collections with royalties, batch minting, and freezing |
| Encrypted Messenger | E2E encrypted messaging with PQC, media support, self-destruct |
| PQC Mail | Encrypted email with @rouge.quant addresses and threading |
| Browser Extensions | Chrome/Firefox wallet extensions with vault lock |
| PWA Support | Installable progressive web app for mobile and desktop |
| SDK | @rougechain/sdk npm package for building dApps |
| Open Source | Fully open source Rust backend and React frontend |
Quick Links
- Getting Started
- Running a Node
- API Reference
- P2P Networking
- Staking & Validators
- Browser Extensions
- SDK
- Architecture
Network Info
| Network | API Endpoint |
|---|---|
| Testnet | https://testnet.rougechain.io/api |
| Devnet (local) | http://127.0.0.1:5100/api |
Tokens
XRGE
The native token of RougeChain is XRGE (pronounced "rouge").
qETH
qETH is a bridged representation of ETH on RougeChain. It uses 6 decimal places and can be bridged in from Base Sepolia or withdrawn back.
| Property | Value |
|---|---|
| Decimals | 6 |
| Bridge Source | Base Sepolia |
| Bridge Contract | Configured per-node via --bridge-custody-address |
Fees
| Action | Fee |
|---|---|
| Transfer | 0.1 XRGE |
| Token Creation | 100 XRGE |
| Pool Creation | 10 XRGE |
| Swap | 0.3% (to LPs) |
| Minimum Stake | 1,000 XRGE |
Burn Address
Tokens can be permanently burned by sending to the official burn address:
XRGE_BURN_0x000000000000000000000000000000000000000000000000000000000000DEAD
Burned tokens are tracked on-chain and can be queried via the /api/burned endpoint.
Security
Client-Side Signing
RougeChain uses a secure v2 API where all transactions are signed client-side:
- Your wallet creates a transaction payload
- The payload is signed locally using ML-DSA-65
- Only the signature and public key are sent to the server
- Your private key never leaves your browser
This ensures maximum security even when interacting with untrusted nodes.
Getting Started
This guide will help you get up and running with RougeChain in minutes.
Prerequisites
- A modern web browser (Chrome, Firefox, Edge, Safari)
- For running a node: Rust toolchain (1.70+)
Quickest Path
- Visit rougechain.io
- Click "Wallet" in the sidebar
- Your wallet is automatically created and stored locally
- Use the faucet to get free testnet XRGE
That's it! You now have a quantum-secure wallet.
What's Next?
- Quick Start Guide - Detailed walkthrough
- Create a Wallet - Understanding your keys
- Get Test Tokens - Using the faucet
- Running a Node - Participate in the network
Quick Start
Get started with RougeChain in 5 minutes.
Step 1: Access the Web App
Visit rougechain.io or run locally:
git clone https://github.com/cyberdreadx/quantum-vault
cd quantum-vault
npm install
npm run dev
Open http://localhost:5173 in your browser.
Step 2: Create Your Wallet
Your wallet is created automatically when you first visit. It includes:
- Public Key (ML-DSA-65) - Your address, share freely
- Private Key (ML-DSA-65) - Never share this!
- Encryption Key (ML-KEM-768) - For secure messaging
Keys are stored locally in your browser.
Step 3: Get Test Tokens
- Click Wallet in the sidebar
- Click Request from Faucet
- Receive 1,000 XRGE instantly
Step 4: Send Your First Transaction
- Click Send
- Enter recipient address
- Enter amount
- Click Send XRGE
Transaction is signed with your ML-DSA-65 key and broadcast to the network.
Step 5: View on Blockchain
- Click Blockchain in sidebar
- See your transaction in the latest block
- Verify the PQC signature
What's Next?
- Run your own node
- Stake and become a validator
- Create custom tokens
- Use encrypted messenger
- Send encrypted mail
- Install the browser extension
- Use the SDK
Troubleshooting
"Failed to fetch" Error
- Check if you're connected to the right network (Testnet vs Devnet)
- Ensure the node is running if using local devnet
"Insufficient balance"
- Transaction requires amount + 0.1 XRGE fee
- Use faucet to get more tokens
Wallet not loading
- Clear browser cache
- Check browser console for errors
Create a Wallet
Your RougeChain wallet is automatically created when you first visit the app. Here's what you need to know about it.
Wallet Components
| Component | Algorithm | Purpose |
|---|---|---|
| Signing Key | ML-DSA-65 | Sign transactions, prove ownership |
| Encryption Key | ML-KEM-768 | Encrypt/decrypt messages |
Your Public Key = Your Address
Your public key (signing key) is your address on RougeChain. It's safe to share.
Example address:
9c88d3ec652bb98aea33e601c351e3c597661b1a...
Addresses are ~2,600 characters (base64 encoded ML-DSA-65 public key).
Backup Your Wallet
CRITICAL: Your private key is only stored in your browser. If you clear browser data, you lose access to your funds.
Export Backup
- Go to Wallet page
- Click Backup or the key icon
- Save the backup file securely
Restore from Backup
- Go to Wallet page
- Click Restore
- Upload your backup file
Security Best Practices
- Never share your private key
- Backup your wallet immediately
- Use a password manager to store your backup
- Don't screenshot your keys
- Verify addresses before sending
Technical Details
Key Generation
// Signing keypair (ML-DSA-65)
const signingSeed = crypto.getRandomValues(new Uint8Array(32));
const signingKeypair = ml_dsa65.keygen(signingSeed);
// Encryption keypair (ML-KEM-768)
const encryptionSeed = crypto.getRandomValues(new Uint8Array(32));
const encryptionKeypair = ml_kem768.keygen(encryptionSeed);
Storage
Keys are stored in browser localStorage:
localStorage.getItem('pqc-wallet-keys')
For production, consider:
- IndexedDB with encryption
- Hardware wallet integration
- Server-side encrypted backup
Get Test Tokens
The faucet distributes free XRGE tokens for testing on testnet.
Using the Web UI
- Go to the Wallet page
- Click Request from Faucet
- Receive 1,000 XRGE instantly
Using the API
curl -X POST https://testnet.rougechain.io/api/faucet \
-H "Content-Type: application/json" \
-d '{"publicKey": "your-public-key-here"}'
Response:
{
"success": true,
"amount": 1000,
"txId": "abc123..."
}
Rate Limits
| Condition | Limit |
|---|---|
| Per address | 1 request / hour |
| Per IP | 10 requests / hour |
| Whitelisted | Unlimited |
Whitelisting
For development or testing, addresses can be whitelisted:
# Start node with whitelist
./quantum-vault-daemon --mine \
--faucet-whitelist "pubkey1,pubkey2,pubkey3"
# Or via environment variable
export QV_FAUCET_WHITELIST="pubkey1,pubkey2"
./quantum-vault-daemon --mine
Troubleshooting
"Rate limited"
Wait an hour or use a different address.
"Faucet disabled"
The node may not have faucet enabled. Check node configuration.
Transaction not appearing
- Check the block explorer for your tx
- Verify you're on the correct network
- Wait for the next block (1-2 seconds)
Running a Node
Run your own RougeChain node to participate in the network, validate transactions, and earn rewards.
Node Types
| Type | Description | Requires |
|---|---|---|
| Full Node | Syncs and validates all blocks | --peers |
| Mining Node | Produces new blocks | --mine |
| Public Node | Accepts external connections | --host 0.0.0.0 |
Quick Start
# Build the daemon
cd core
cargo build --release -p quantum-vault-daemon
# Run a syncing node
./target/release/quantum-vault-daemon \
--api-port 5100 \
--peers "https://testnet.rougechain.io"
# Run a mining node
./target/release/quantum-vault-daemon \
--mine \
--api-port 5100 \
--peers "https://testnet.rougechain.io"
Verify It's Working
curl http://127.0.0.1:5100/api/health
Expected response:
{
"status": "ok",
"chain_id": "rougechain-devnet-1",
"height": 123
}
Next Steps
- Installation - Detailed setup instructions
- Configuration - All CLI options
- Mining - Block production
Installation
Build and run a RougeChain node from source.
Prerequisites
Linux / macOS
# Install Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source ~/.cargo/env
# Install build dependencies (Ubuntu/Debian)
sudo apt update && sudo apt install -y build-essential pkg-config libssl-dev
# Install build dependencies (macOS)
xcode-select --install
Windows
- Install Rust
- Install Visual Studio Build Tools
- Ensure
cargois in your PATH
Build from Source
# Clone the repository
git clone https://github.com/cyberdreadx/quantum-vault
cd quantum-vault/core
# Build release binary
cargo build --release -p quantum-vault-daemon
# Binary location
./target/release/quantum-vault-daemon --help
Verify Installation
./target/release/quantum-vault-daemon --version
Expected output:
quantum-vault-daemon 0.1.0
First Run
Option A: Connect to Testnet
./target/release/quantum-vault-daemon \
--api-port 5100 \
--peers "https://testnet.rougechain.io"
Option B: Start Local Devnet
./target/release/quantum-vault-daemon --mine --api-port 5100
Verify Node is Running
curl http://127.0.0.1:5100/api/health
Expected response:
{"status":"ok","chain_id":"rougechain-devnet-1","height":0}
Directory Structure
After first run, data is stored at:
| OS | Default Location |
|---|---|
| Linux/macOS | ~/.quantum-vault/core-node/ |
| Windows | C:\Users\<you>\.quantum-vault\core-node\ |
Updating
cd quantum-vault
git pull
cd core
cargo build --release -p quantum-vault-daemon
# Restart the node
Troubleshooting
"cargo not found"
source ~/.cargo/env
# or restart your terminal
"OpenSSL not found"
# Ubuntu/Debian
sudo apt install libssl-dev pkg-config
# Fedora/RHEL
sudo dnf install openssl-devel
# macOS
brew install openssl
"Address already in use"
Another process is using port 5100:
# Find and kill it
lsof -i :5100
kill -9 <PID>
# Or use a different port
./quantum-vault-daemon --api-port 5101
Build fails on Windows
Ensure you have Visual Studio Build Tools with C++ workload installed.
Configuration
All node configuration is done via command-line flags or environment variables.
CLI Options
| Flag | Env Variable | Default | Description |
|---|---|---|---|
--host | - | 127.0.0.1 | Bind address for API/gRPC |
--port | - | 4100 | gRPC port |
--api-port | - | 5100 | HTTP API port |
--chain-id | - | rougechain-devnet-1 | Chain identifier |
--block-time-ms | - | 1000 | Block production interval (ms) |
--mine | - | false | Enable block production |
--data-dir | - | ~/.quantum-vault/core-node | Data storage directory |
--peers | QV_PEERS | - | Comma-separated peer URLs |
--public-url | QV_PUBLIC_URL | - | This node's public URL for discovery |
--api-keys | QV_API_KEYS | - | Comma-separated API keys |
--rate-limit-per-minute | - | 120 | Rate limit for API requests |
Examples
Local Development Node
./quantum-vault-daemon --mine --api-port 5100
Syncing Node (No Mining)
./quantum-vault-daemon \
--api-port 5100 \
--peers "https://testnet.rougechain.io"
Public Mining Node
./quantum-vault-daemon \
--mine \
--host 0.0.0.0 \
--api-port 5100 \
--peers "https://testnet.rougechain.io" \
--public-url "https://mynode.example.com"
Multiple Peers
./quantum-vault-daemon \
--api-port 5100 \
--peers "https://node1.example.com,https://node2.example.com,https://node3.example.com"
Custom Data Directory
./quantum-vault-daemon \
--mine \
--api-port 5100 \
--data-dir "/var/lib/rougechain"
Environment Variables
You can also use environment variables:
export QV_PEERS="https://testnet.rougechain.io"
export QV_PUBLIC_URL="https://mynode.example.com"
export QV_API_KEYS="key1,key2,key3"
./quantum-vault-daemon --mine --api-port 5100
Data Directory Structure
~/.quantum-vault/core-node/
├── chain.jsonl # Block data (append-only)
├── tip.json # Current chain tip
├── validators-db/ # Validator state (RocksDB)
└── messenger-db/ # Messenger data (RocksDB)
Running with Systemd (Linux)
Create /etc/systemd/system/rougechain.service:
[Unit]
Description=RougeChain Node
After=network.target
[Service]
Type=simple
User=rougechain
ExecStart=/opt/rougechain/quantum-vault-daemon --mine --host 0.0.0.0 --api-port 5100 --peers "https://testnet.rougechain.io"
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
Enable and start:
sudo systemctl enable rougechain
sudo systemctl start rougechain
sudo journalctl -u rougechain -f # View logs
Mining (Block Production)
RougeChain uses Proof of Stake, so "mining" refers to block production by validators rather than proof-of-work mining.
Enable Mining
Start your node with the --mine flag:
./quantum-vault-daemon --mine --api-port 5100
This tells the node to produce blocks at the configured interval (default: 1000ms).
Requirements
| Requirement | Value |
|---|---|
| Staked XRGE | Minimum 1,000 XRGE |
| Node uptime | Must be online to produce blocks |
| Network sync | Node must be synced to chain tip |
How Block Production Works
- Validator selection — Each block slot, the network selects a proposer based on stake weight and quantum entropy
- Block assembly — The selected validator collects pending transactions from the mempool
- Signing — The block is signed with the validator's ML-DSA-65 key
- Propagation — The signed block is broadcast to all peers via
POST /api/blocks/import - Verification — Receiving nodes verify the signature and block validity before accepting
Block Timing
| Parameter | Default | Flag |
|---|---|---|
| Block time | 1000ms | --block-time-ms |
# Slower blocks (5 seconds)
./quantum-vault-daemon --mine --block-time-ms 5000
# Faster blocks (500ms, for local dev)
./quantum-vault-daemon --mine --block-time-ms 500
Mining with Peers
To mine as part of the network (not solo):
./quantum-vault-daemon \
--mine \
--api-port 5100 \
--peers "https://testnet.rougechain.io" \
--public-url "https://mynode.example.com"
The --public-url flag is important — it lets other nodes discover and sync from you.
Monitoring
Check your validator status:
curl https://testnet.rougechain.io/api/validators
Check blocks produced:
curl https://testnet.rougechain.io/api/blocks?limit=10
Rewards
Validators earn transaction fees from blocks they produce. Fees are credited immediately when a block is finalized. See Staking Rewards for details.
Troubleshooting
Node not producing blocks
- Ensure
--mineflag is set - Verify you have enough XRGE staked (min 1,000)
- Check that your node is synced:
curl http://127.0.0.1:5100/api/health
Blocks not propagating
- Ensure
--public-urlis set and accessible from the internet - Check firewall rules for your API port
- Verify peer connections:
curl http://127.0.0.1:5100/api/peers
Producing blocks but no rewards
- Confirm your staking transaction was included in a block
- Check validator status via the API
P2P Networking
RougeChain uses a peer-to-peer network for block propagation, transaction broadcasting, and peer discovery.
How It Works
┌─────────────┐ blocks/txs ┌─────────────┐
│ Node A │ ◄─────────────────► │ Node B │
│ (mining) │ │ (syncing) │
└─────────────┘ └─────────────┘
▲ ▲
│ peer discovery │
└───────────────┬───────────────────┘
│
▼
┌─────────────┐
│ Node C │
│ (new peer) │
└─────────────┘
Features
| Feature | Description |
|---|---|
| Block Sync | Nodes download and verify blocks from peers |
| Transaction Broadcast | Submitted txs propagate to all peers |
| Peer Discovery | Nodes share their peer lists with each other |
| Genesis Reset | New nodes automatically adopt the network's chain |
Connecting to the Network
As a Syncing Node
./quantum-vault-daemon \
--api-port 5100 \
--peers "https://testnet.rougechain.io"
As a Mining Node
./quantum-vault-daemon \
--mine \
--api-port 5100 \
--peers "https://testnet.rougechain.io"
Peer Discovery
Nodes automatically discover new peers every 30 seconds by:
- Querying known peers via
GET /api/peers - Adding any new peers to their list
- Optionally registering themselves via
POST /api/peers/register
Enable Self-Registration
./quantum-vault-daemon \
--api-port 5100 \
--peers "https://testnet.rougechain.io" \
--public-url "https://mynode.example.com"
This tells other nodes how to reach you.
API Endpoints
| Endpoint | Method | Description |
|---|---|---|
/api/peers | GET | List known peers |
/api/peers/register | POST | Register as a peer |
/api/blocks/import | POST | Import a block (peer-to-peer) |
/api/tx/broadcast | POST | Receive a broadcasted transaction |
Next Steps
Connecting to Peers
Connect your RougeChain node to the network to sync blocks and broadcast transactions.
Connect to Testnet
The simplest way to join the network:
./quantum-vault-daemon \
--api-port 5100 \
--peers "https://testnet.rougechain.io"
Your node will:
- Download all blocks from the peer
- Verify each block's PQC signatures
- Build the local chain state
- Start receiving new blocks in real-time
Connect to Multiple Peers
For better reliability, connect to multiple peers:
./quantum-vault-daemon \
--api-port 5100 \
--peers "https://testnet.rougechain.io,https://node2.example.com,https://node3.example.com"
Or via environment variable:
export QV_PEERS="https://testnet.rougechain.io,https://node2.example.com"
./quantum-vault-daemon --api-port 5100
Verify Connection
Check that your node has peers:
curl http://127.0.0.1:5100/api/peers
Expected response:
{
"peers": [
"https://testnet.rougechain.io/api"
],
"count": 1
}
Sync Status
Check if your node is synced:
curl http://127.0.0.1:5100/api/health
{
"status": "ok",
"chain_id": "rougechain-devnet-1",
"height": 12345
}
Compare the height with the testnet to confirm you're in sync:
curl https://testnet.rougechain.io/api/health
Connection Flow
Your Node Peer Node
│ │
│── GET /api/health ──────────────►│
│◄─── { height: 12345 } ──────────│
│ │
│── GET /api/blocks?from=0 ───────►│
│◄─── [ block0, block1, ... ] ────│
│ │
│ (verify signatures, apply) │
│ │
│── GET /api/peers ───────────────►│
│◄─── { peers: [...] } ───────────│
│ │
│ (discover new peers) │
Firewall Configuration
If running behind a firewall, ensure the API port is accessible:
| Port | Protocol | Purpose |
|---|---|---|
| 5100 (default) | TCP/HTTP | REST API and P2P |
# Linux (ufw)
sudo ufw allow 5100/tcp
# Linux (firewalld)
sudo firewall-cmd --add-port=5100/tcp --permanent
sudo firewall-cmd --reload
Troubleshooting
"Connection refused"
- Check that the peer URL is correct and reachable
- Verify the peer node is running
- Check for firewall restrictions
Node stuck syncing
- The initial sync may take time on long chains
- Monitor progress by watching the
heightincrease via/api/health - Try connecting to a different peer
"Chain ID mismatch"
- Ensure your
--chain-idmatches the network you're connecting to - Testnet uses
rougechain-devnet-1
Peer Discovery
RougeChain nodes automatically discover other nodes on the network through a gossip-based peer exchange protocol.
How Discovery Works
1. Node A starts with seed peer(s) via --peers
2. Node A queries GET /api/peers on each known peer
3. Each peer returns its own list of known peers
4. Node A adds any new peers to its local list
5. If --public-url is set, Node A registers itself on peers
6. Repeat every 30 seconds
Over time, all nodes in the network discover each other, forming a mesh.
Discovery Interval
Peer discovery runs automatically every 30 seconds. No configuration is needed.
Seed Peers
The first peer(s) you connect to act as seeds for discovery. From them, your node learns about the rest of the network.
# Single seed
./quantum-vault-daemon --peers "https://testnet.rougechain.io"
# Multiple seeds for redundancy
./quantum-vault-daemon --peers "https://testnet.rougechain.io,https://backup.example.com"
Self-Registration
To make your node discoverable by others, set --public-url:
./quantum-vault-daemon \
--api-port 5100 \
--peers "https://testnet.rougechain.io" \
--public-url "https://mynode.example.com"
Your node will call POST /api/peers/register on all known peers, announcing its presence. Other nodes will then include your URL in their peer lists.
Discovery API
Get Known Peers
curl http://127.0.0.1:5100/api/peers
{
"peers": [
"https://testnet.rougechain.io/api",
"https://node2.example.com/api",
"https://node3.example.com/api"
],
"count": 3
}
Register as a Peer
curl -X POST https://testnet.rougechain.io/api/peers/register \
-H "Content-Type: application/json" \
-d '{"peerUrl": "https://mynode.example.com"}'
Discovery Diagram
Seed Node
┌─────────┐
│ Node A │ ◄── your --peers target
└────┬────┘
│
GET /api/peers
│
┌────────┼────────┐
▼ ▼ ▼
┌───────┐┌───────┐┌───────┐
│Node B ││Node C ││Node D │ ◄── discovered automatically
└───────┘└───────┘└───────┘
│ │ │
└─────────┼────────┘
│
More peers discovered
from B, C, D...
Privacy Considerations
- Your node's IP/URL is shared with all peers when using
--public-url - Without
--public-url, your node connects outward but is not discoverable by others - Consider using a reverse proxy or domain name instead of exposing raw IP addresses
Running a Public Node
Run a RougeChain node that is publicly accessible and participates fully in the network.
Requirements
| Requirement | Details |
|---|---|
| Server | VPS or dedicated server with a public IP |
| Domain (recommended) | Point a domain to your server |
| SSL certificate | Required for HTTPS (use Let's Encrypt) |
| Open port | API port accessible from the internet |
Setup
1. Build and Install
git clone https://github.com/cyberdreadx/quantum-vault
cd quantum-vault/core
cargo build --release -p quantum-vault-daemon
sudo cp target/release/quantum-vault-daemon /usr/local/bin/
2. Configure Reverse Proxy (nginx)
server {
listen 443 ssl;
server_name mynode.rougechain.example.com;
ssl_certificate /etc/letsencrypt/live/mynode.rougechain.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mynode.rougechain.example.com/privkey.pem;
client_max_body_size 50M;
location / {
proxy_pass http://127.0.0.1:5100;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Set client_max_body_size to at least 50M to support messenger media uploads.
3. Start the Node
./quantum-vault-daemon \
--mine \
--host 127.0.0.1 \
--api-port 5100 \
--peers "https://testnet.rougechain.io" \
--public-url "https://mynode.rougechain.example.com"
4. Run as a Service
Create /etc/systemd/system/rougechain.service:
[Unit]
Description=RougeChain Node
After=network.target
[Service]
Type=simple
User=rougechain
ExecStart=/usr/local/bin/quantum-vault-daemon --mine --host 127.0.0.1 --api-port 5100 --peers "https://testnet.rougechain.io" --public-url "https://mynode.rougechain.example.com"
Restart=always
RestartSec=5
LimitNOFILE=65535
[Install]
WantedBy=multi-user.target
sudo useradd -r -s /bin/false rougechain
sudo systemctl enable rougechain
sudo systemctl start rougechain
Verify Your Node
Health Check
curl https://mynode.rougechain.example.com/api/health
Check Peers Can See You
curl https://testnet.rougechain.io/api/peers
# Your node's URL should appear in the list
Security Hardening
API Keys
Restrict write access with API keys:
./quantum-vault-daemon \
--mine \
--api-port 5100 \
--api-keys "secret-key-1,secret-key-2"
Rate Limiting
The node has built-in rate limiting (default: 120 requests/minute). Adjust as needed:
./quantum-vault-daemon --rate-limit-per-minute 60
Firewall
Only expose the necessary port:
sudo ufw default deny incoming
sudo ufw allow ssh
sudo ufw allow 443/tcp
sudo ufw enable
Monitoring
Check Logs
sudo journalctl -u rougechain -f
Health Endpoint
Set up a monitoring tool (e.g., UptimeRobot) to poll:
https://mynode.rougechain.example.com/api/health
Metrics to Watch
| Metric | How to Check |
|---|---|
| Block height | GET /api/health — compare with testnet |
| Peer count | GET /api/peers — should be > 0 |
| Validator status | GET /api/validators — check your stake |
Staking & Validators
RougeChain uses Proof of Stake (PoS) for consensus. Validators stake XRGE tokens to participate in block production and earn rewards.
How It Works
- Stake tokens - Lock XRGE to become a validator
- Propose blocks - Selected validators propose new blocks
- Earn rewards - Collect transaction fees from blocks you produce
- Unstake - Wait for unbonding period to withdraw
Requirements
| Requirement | Value |
|---|---|
| Minimum stake | 1,000 XRGE |
| Unbonding period | ~7 days |
| Slashing | Not implemented (testnet) |
Become a Validator
Via Web UI
- Go to the Validators page
- Click Stake
- Enter amount (min 1,000 XRGE)
- Confirm transaction
Via API
curl -X POST https://testnet.rougechain.io/api/stake/submit \
-H "Content-Type: application/json" \
-d '{
"fromPrivateKey": "your-private-key",
"fromPublicKey": "your-public-key",
"amount": 1000
}'
Check Your Stake
curl "https://testnet.rougechain.io/api/validators?publicKey=your-public-key"
Response:
{
"validators": [
{
"publicKey": "your-public-key",
"stake": 1000.0,
"status": "active",
"blocksProposed": 42
}
]
}
Unstake
Via API
curl -X POST https://testnet.rougechain.io/api/unstake/submit \
-H "Content-Type: application/json" \
-d '{
"fromPrivateKey": "your-private-key",
"fromPublicKey": "your-public-key",
"amount": 500
}'
Validator Selection
Block proposers are selected using:
- Stake weight - Higher stake = higher probability
- Quantum entropy - Unpredictable randomness
- Round-robin fallback - Ensures all validators participate
Rewards
Validators earn:
- Transaction fees from blocks they produce
- Base block reward (if configured)
Fees are credited immediately when a block is finalized.
PQC Security
All validator operations use ML-DSA-65 signatures:
- Block proposals are signed
- Stake/unstake transactions are signed
- Signatures are verified by all nodes
This ensures quantum-resistant security for the entire consensus process.
Becoming a Validator
Validators produce blocks and earn transaction fees on RougeChain. This guide walks you through the full process.
Prerequisites
| Requirement | Details |
|---|---|
| XRGE balance | At least 1,000 XRGE (+ fees) |
| Wallet | A RougeChain wallet with signing keys |
| Node (optional) | Running a node earns you more blocks |
Step 1: Get XRGE
If you're on testnet, use the faucet:
- Visit rougechain.io
- Go to Wallet and click Request from Faucet
- Repeat until you have at least 1,000 XRGE
Step 2: Stake Tokens
Via Web UI
- Navigate to the Validators page
- Click Stake
- Enter your stake amount (minimum 1,000 XRGE)
- Confirm the transaction
- Your wallet signs the stake transaction with ML-DSA-65
Via v2 API (Client-Side Signing)
curl -X POST https://testnet.rougechain.io/api/v2/stake \
-H "Content-Type: application/json" \
-d '{
"publicKey": "your-public-key-hex",
"amount": 1000,
"nonce": 1706745600000,
"signature": "your-ml-dsa65-signature-hex"
}'
Step 3: Verify Your Validator Status
curl "https://testnet.rougechain.io/api/validators"
Look for your public key in the response:
{
"validators": [
{
"publicKey": "your-public-key",
"stake": 1000.0,
"status": "active",
"blocksProposed": 0
}
]
}
Step 4: Run a Mining Node (Recommended)
While staking alone makes you a validator, running a node ensures you're online to produce blocks when selected:
./quantum-vault-daemon \
--mine \
--api-port 5100 \
--peers "https://testnet.rougechain.io" \
--public-url "https://mynode.example.com"
Increasing Your Stake
You can add more XRGE to increase your block proposal probability:
# Stake additional 500 XRGE
curl -X POST https://testnet.rougechain.io/api/v2/stake \
-H "Content-Type: application/json" \
-d '{
"publicKey": "your-public-key-hex",
"amount": 500,
"nonce": 1706745600001,
"signature": "your-signature-hex"
}'
Your total stake accumulates.
Validator Selection Algorithm
Proposer selection uses three factors:
- Stake weight — Higher stake gives proportionally higher probability
- Quantum entropy — Ensures unpredictable selection
- Round-robin fallback — Guarantees all validators eventually participate
This means even validators with the minimum stake will produce blocks, just less frequently.
Leaving the Validator Set
See Unstaking — after unstaking below the minimum, you're removed from the active validator set.
Staking Rewards
Validators earn rewards for producing blocks on RougeChain.
Reward Sources
| Source | Description |
|---|---|
| Transaction fees | All fees from transactions in your block |
| Base block reward | Fixed reward per block (if configured) |
How Rewards Work
- A validator is selected to propose a block
- The validator assembles pending transactions
- All transaction fees in that block go to the proposer
- Rewards are credited immediately upon block finalization
Fee Structure
| Transaction Type | Fee |
|---|---|
| Transfer | 0.1 XRGE |
| Token creation | 100 XRGE |
| Pool creation | 10 XRGE |
| Swap | 0.3% (to LPs, not validators) |
| Stake/Unstake | 0.1 XRGE |
Validators earn the flat fees (transfer, token creation, pool creation, stake/unstake). Swap fees go to liquidity providers.
Estimated Returns
Rewards depend on:
- Your stake relative to total staked — determines how often you're selected
- Network activity — more transactions = more fees per block
- Number of validators — fewer validators means more blocks per validator
Example
| Scenario | Value |
|---|---|
| Your stake | 10,000 XRGE |
| Total staked | 100,000 XRGE |
| Your share | 10% |
| Blocks per day | ~86,400 (1s block time) |
| Your blocks per day | ~8,640 |
| Avg fee per block | 0.5 XRGE |
| Daily earnings | ~4,320 XRGE |
These are approximate — actual returns vary with network conditions.
Compounding
Rewards are added to your balance, not your stake. To compound:
- Periodically stake your accumulated rewards
- This increases your proposer probability
- Leading to more blocks and more rewards
Checking Rewards
Via Web UI
Go to the Validators page to see your validator stats including blocks proposed.
Via API
# Check your balance (includes accumulated rewards)
curl "https://testnet.rougechain.io/api/balance/your-public-key"
# Check blocks proposed
curl "https://testnet.rougechain.io/api/validators"
Tax Considerations
Staking rewards may be taxable income in your jurisdiction. Keep records of:
- Amount staked
- Rewards received (block by block)
- Token price at time of receipt
- Unstaking transactions
RougeChain does not provide tax advice. Consult a tax professional.
Bridge
RougeChain supports bridging assets between Base Sepolia (EVM) and the RougeChain L1 network. The bridge uses a lock-and-mint / burn-and-release model with a dedicated smart contract.
Supported Assets
| EVM Asset | RougeChain Asset | Decimals | Direction |
|---|---|---|---|
| ETH | qETH | 6 (L1 units) | Both ways |
| USDC | qUSDC | 6 | Both ways |
| XRGE | XRGE | 18 (EVM) / whole units (L1) | Both ways |
How It Works
Deposit (EVM → RougeChain)
- User deposits ETH, USDC, or XRGE into the RougeBridge smart contract on Base Sepolia
- User calls the claim endpoint on RougeChain with the EVM transaction hash
- The node verifies the deposit on-chain and mints the wrapped token (qETH, qUSDC, or XRGE) on L1
Withdrawal (RougeChain → EVM)
- User submits a signed bridge_withdraw transaction on RougeChain, burning the wrapped token
- The withdrawal is recorded in the pending withdrawals store
- The bridge relayer polls for pending withdrawals and releases the corresponding asset from the contract on EVM
Security
- Client-side signing — Private keys never leave the browser. Withdraw transactions are signed locally using ML-DSA-65
- RougeBridge contract — Pausable, with guardian role for emergencies, timelock on large withdrawals
- Relayer authentication — The relayer uses a
BRIDGE_RELAYER_SECRETfor API authentication - Replay protection — Claimed transaction hashes are persisted to prevent double-claims
- EVM signature verification — ETH claims require an EVM
personal_signto prove deposit ownership
Architecture
Base Sepolia (EVM) RougeChain L1
┌──────────────────┐ ┌──────────────────┐
│ RougeBridge.sol │ │ Node Daemon │
│ - depositETH() │──relayer──│ - /bridge/claim │
│ - depositERC20()│ │ - /bridge/withdraw│
│ - releaseETH() │◀─relayer──│ - withdraw store │
│ - releaseERC20()│ │ │
│ BridgeVault.sol │ │ │
│ - deposit() │──relayer──│ - /bridge/xrge/* │
│ - release() │◀─relayer──│ │
└──────────────────┘ └──────────────────┘
ETH Bridge (qETH)
Bridge ETH from Base Sepolia to RougeChain as qETH, and back.
Deposit (ETH → qETH)
Step 1: Send ETH to the Bridge
Connect your MetaMask (or other EVM wallet) to Base Sepolia and send ETH to the custody/bridge contract address shown on the Bridge page.
Step 2: Claim qETH
- Go to the Bridge page and select the Bridge In tab
- Paste the EVM transaction hash
- Sign the claim message with your EVM wallet (proves you made the deposit)
- Click Claim
The node verifies:
- The transaction exists on Base Sepolia
- It was sent to the correct custody address
- The EVM signature matches the sender
- The transaction has sufficient confirmations
- It hasn't been claimed before
On success, qETH is minted to your RougeChain wallet.
Conversion Rate
1 ETH = 1,000,000 qETH units (6 decimal precision)
For example, depositing 0.01 ETH gives you 10,000 qETH units.
Withdraw (qETH → ETH)
- Go to the Bridge page and select the Bridge Out tab
- Select ETH as the token
- Enter the amount of qETH to bridge out
- Enter the Base Sepolia address to receive ETH
- Click Bridge Out
The transaction is signed client-side (your private key never leaves the browser), then:
- qETH is burned on RougeChain
- A pending withdrawal is created
- The bridge relayer picks it up and sends ETH to your EVM address
A 0.1 XRGE fee is charged for the withdrawal transaction.
Fees
| Operation | Fee |
|---|---|
| Deposit (ETH → qETH) | Gas on Base Sepolia only |
| Withdraw (qETH → ETH) | 0.1 XRGE |
USDC Bridge (qUSDC)
Bridge USDC from Base Sepolia to RougeChain as qUSDC, and back.
Overview
qUSDC is a wrapped representation of USDC on RougeChain. It maintains a 1:1 peg with USDC locked in the RougeBridge contract on Base Sepolia.
USDC Contract on Base Sepolia: 0x036CbD53842c5426634e7929541eC2318f3dCF7e
Deposit (USDC → qUSDC)
- Approve the RougeBridge contract to spend your USDC
- Call
depositERC20(usdc_address, amount, rougechainPubkey)on the contract - Go to the Bridge page, select USDC as the token, switch to Bridge In
- Paste the EVM transaction hash and claim
The node parses the ERC-20 Transfer event from the transaction receipt to determine the amount. USDC uses 6 decimals, and qUSDC uses the same 6-decimal precision.
Withdraw (qUSDC → USDC)
- Go to Bridge page, select USDC, switch to Bridge Out
- Enter amount and destination EVM address
- Click Bridge Out qUSDC
The relayer calls releaseERC20() on the RougeBridge contract to send USDC back to your EVM address.
Fees
| Operation | Fee |
|---|---|
| Deposit | Gas on Base Sepolia |
| Withdraw | 0.1 XRGE |
XRGE Bridge
Bridge XRGE tokens between Base (EVM) and RougeChain L1 using the BridgeVault contract.
Overview
Unlike qETH/qUSDC (which are wrapped assets), XRGE is the native token of RougeChain. The XRGE bridge allows moving XRGE between its ERC-20 representation on Base and the L1 network.
XRGE Token on Base: 0x147120faEC9277ec02d957584CFCD92B56A24317
Deposit (Base XRGE → L1 XRGE)
- Approve the BridgeVault contract to spend your XRGE
- Call
deposit(amount, rougechainPubkey)on the BridgeVault - The vault locks your XRGE and emits a
BridgeDepositevent - Call the
/api/bridge/xrge/claimendpoint with the transaction hash - The node verifies the receipt and credits XRGE on L1
Withdraw (L1 XRGE → Base XRGE)
- Go to the Bridge page and use the XRGE Bridge Out tab
- Enter the amount and your Base EVM address
- Submit the signed withdrawal
- The relayer calls
release()on the BridgeVault to unlock your XRGE on Base
BridgeVault Contract
The BridgeVault is a lock-and-release contract:
deposit(amount, rougechainPubkey)— Lock XRGE, emit event for relayerrelease(to, amount, l1TxId)— Owner (relayer) releases XRGE back to uservaultBalance()— View how much XRGE the vault holdsemergencyWithdraw(token)— Admin-only emergency recovery
Liquidity in the vault = total XRGE locked by depositors minus released amounts.
RougeBridge Contract
The RougeBridge.sol contract is a multi-asset bridge contract deployed on Base Sepolia that handles ETH and ERC-20 deposits/releases with enhanced security features.
Features
- Multi-token support — ETH and any ERC-20 token (USDC, etc.)
- Pausable — Guardian can pause all operations in emergencies
- Timelock — Large withdrawals require a delay period before execution
- Guardian role — Separate from owner; can pause but cannot withdraw
- Replay protection — Processed L1 transaction IDs are tracked to prevent double-releases
- Owner = multisig — Deploy with a Gnosis Safe as owner for production
Key Functions
Deposits
function depositETH(string calldata rougechainPubkey) external payable;
function depositERC20(address token, uint256 amount, string calldata rougechainPubkey) external;
Users call these to lock assets in the contract. Events are emitted for the relayer to pick up.
Releases (Owner Only)
function releaseETH(address to, uint256 amount, bytes32 l1TxId) external;
function releaseERC20(address token, address to, uint256 amount, bytes32 l1TxId) external;
The relayer (owner) calls these to release assets when a user burns their wrapped tokens on L1. If the amount exceeds largeWithdrawalThreshold, a timelock is queued instead.
Timelock
function executeTimelock(uint256 requestId) external; // Owner, after delay
function cancelTimelock(uint256 requestId) external; // Guardian
Large releases are queued with a configurable delay (default 24 hours). The guardian can cancel suspicious requests during the delay window.
Admin
function pause() external; // Guardian or Owner
function unpause() external; // Owner only
function setGuardian(address newGuardian) external; // Owner
function setSupportedToken(address token, bool) external;// Owner
function setLargeWithdrawalThreshold(uint256) external; // Owner
Events
| Event | Description |
|---|---|
BridgeDepositETH | ETH deposited for bridging |
BridgeDepositERC20 | ERC-20 deposited for bridging |
BridgeReleaseETH | ETH released to user |
BridgeReleaseERC20 | ERC-20 released to user |
TimelockQueued | Large release queued with delay |
TimelockExecuted | Queued release executed |
TimelockCancelled | Queued release cancelled by guardian |
Deployment
The contract is deployed on Base Sepolia (chain ID 84532). For mainnet, deploy with a Gnosis Safe multisig as the owner.
Bridge Relayer
The bridge relayer is an off-chain process that monitors pending withdrawals on RougeChain and executes the corresponding releases on Base Sepolia.
How It Works
- Polls the RougeChain node for pending ETH and XRGE withdrawals
- For each pending withdrawal, sends the corresponding asset on Base Sepolia
- Marks the withdrawal as fulfilled on the node
Running the Relayer
# Required environment variables
export CORE_API_URL="http://localhost:5101"
export BRIDGE_CUSTODY_PRIVATE_KEY="0x..." # EVM private key for the bridge wallet
export BRIDGE_RELAYER_SECRET="your-secret" # Shared secret for API authentication
export BASE_SEPOLIA_RPC="https://sepolia.base.org"
# Optional
export XRGE_BRIDGE_VAULT="0x..." # BridgeVault contract address
export ROUGE_BRIDGE_ADDRESS="0x..." # RougeBridge contract address
export USDC_ADDRESS="0x036CbD53842c5426634e7929541eC2318f3dCF7e"
export POLL_INTERVAL_MS="5000"
# Run
npx tsx scripts/bridge-relayer.ts
Authentication
The relayer authenticates with the node using the BRIDGE_RELAYER_SECRET environment variable. This is sent as the x-bridge-relayer-secret HTTP header when marking withdrawals as fulfilled.
Set the same secret on both the relayer and the node:
# On the node
export BRIDGE_RELAYER_SECRET="your-secret"
# On the relayer
export BRIDGE_RELAYER_SECRET="your-secret"
Contract Mode vs Legacy Mode
- With
ROUGE_BRIDGE_ADDRESS— The relayer callsreleaseETH()/releaseERC20()on the RougeBridge contract - Without it — Falls back to raw ETH transfers from the custody wallet (legacy mode)
- With
XRGE_BRIDGE_VAULT— Enables XRGE bridge support via the BridgeVault contract
Security Considerations
- The relayer's EVM private key should be stored securely (not in code)
- Use a dedicated wallet with limited funds for the relayer
- For production, the RougeBridge contract owner should be a multisig
- The
BRIDGE_RELAYER_SECRETshould be a strong random string
DEX & AMM
RougeChain includes a built-in decentralized exchange (DEX) powered by an Automated Market Maker (AMM) using the constant product formula (x * y = k).
Overview
- Create pools for any token pair
- Swap between tokens with slippage protection
- Provide liquidity and earn fees from trades
- Multi-hop routing for tokens without direct pools
All operations are signed client-side with ML-DSA-65 — your private key never leaves the browser.
Fee Structure
| Operation | Fee |
|---|---|
| Create Pool | 100 XRGE |
| Swap | 0.3% of input + 1 XRGE tx fee |
| Add Liquidity | 1 XRGE |
| Remove Liquidity | 1 XRGE |
The 0.3% swap fee is distributed to liquidity providers proportional to their share of the pool.
Pool Mechanics
Pools use the Constant Product Market Maker model:
reserve_a × reserve_b = k (constant)
When a user swaps token A for token B:
- Token A is added to the pool
- Token B is removed, maintaining the constant product
- 0.3% fee is taken from the input amount
- Price impact increases with larger trades relative to pool size
LP Tokens
When you provide liquidity, you receive LP tokens representing your share of the pool. When you remove liquidity, you burn LP tokens and receive your proportional share of both tokens in the pool.
Liquidity Pools
Creating a Pool
To create a new trading pool:
- Go to the Swap page
- Click Create Pool
- Select two tokens (e.g., XRGE / qETH)
- Enter the initial amounts for each token
- Click Create Pool
The initial token ratio sets the starting price. A 100 XRGE fee is charged for pool creation.
Adding Liquidity
- Go to the pool page
- Click Add Liquidity
- Enter the amount of one token — the other amount auto-calculates based on the current ratio
- Confirm the transaction
You receive LP tokens proportional to your contribution.
Removing Liquidity
- Go to the pool page
- Click Remove Liquidity
- Enter the LP token amount to withdraw
- You receive your proportional share of both tokens
Impermanent Loss
If the price ratio changes significantly from when you deposited, you may experience impermanent loss compared to simply holding the tokens. This is standard AMM behavior.
Pool Stats
Each pool shows:
- Current reserves for both tokens
- Total LP tokens issued
- Your LP share percentage
- 24h volume and fees earned
- Price history chart
Swaps
Making a Swap
- Go to the Swap page
- Select the input token and output token
- Enter the amount to swap
- Review the quote (output amount, price impact, minimum received)
- Click Swap
Slippage Protection
Set your maximum slippage tolerance to protect against price movements during your transaction. If the actual output would be less than your minimum, the transaction is rejected.
Default slippage: 0.5%
Price Impact
Price impact shows how much your trade will move the pool price. Large trades relative to pool size have higher price impact.
| Price Impact | Severity |
|---|---|
| < 1% | Low |
| 1-5% | Medium |
| > 5% | High (warning shown) |
Multi-Hop Routing
If no direct pool exists between your tokens, the router automatically finds a path through XRGE:
TOKEN_A → XRGE → TOKEN_B
This uses two swaps internally but is handled in a single transaction.
Fees
- 0.3% of the input amount goes to liquidity providers
- 1 XRGE base transaction fee
Token Creation
Create custom tokens on RougeChain. Tokens can be traded on the built-in AMM/DEX.
Overview
| Property | Value |
|---|---|
| Creation fee | 100 XRGE |
| Max supply | Set at creation (immutable) |
| Decimals | Configurable |
| Trading | Via AMM liquidity pools |
Create a Token
Via Web UI
- Navigate to the Token Explorer page
- Click Create Token
- Fill in token details:
- Name — Full name (e.g., "My Token")
- Symbol — Ticker symbol (e.g., "MTK")
- Total Supply — Maximum supply
- Decimals — Decimal places (typically 8)
- Confirm and sign the transaction
Via v2 API
curl -X POST https://testnet.rougechain.io/api/v2/token/create \
-H "Content-Type: application/json" \
-d '{
"publicKey": "your-public-key-hex",
"payload": {
"name": "My Token",
"symbol": "MTK",
"totalSupply": 1000000,
"decimals": 8
},
"nonce": 1706745600000,
"signature": "your-ml-dsa65-signature-hex"
}'
Response
{
"success": true,
"txId": "abc123...",
"token": {
"symbol": "MTK",
"name": "My Token",
"totalSupply": 1000000,
"decimals": 8,
"creator": "your-public-key"
}
}
After Creation
Once created, the entire supply is credited to the creator's wallet. You can then:
- Transfer tokens to other wallets
- Create a liquidity pool to enable trading
- Burn tokens by sending to the burn address
Creating a Liquidity Pool
To make your token tradeable on the DEX:
curl -X POST https://testnet.rougechain.io/api/v2/pool/create \
-H "Content-Type: application/json" \
-d '{
"publicKey": "your-public-key-hex",
"payload": {
"tokenA": "XRGE",
"tokenB": "MTK",
"amountA": 1000,
"amountB": 10000
},
"nonce": 1706745600001,
"signature": "your-signature-hex"
}'
This creates an XRGE/MTK pool with an initial price of 0.1 XRGE per MTK.
Pool creation costs 10 XRGE.
Token Burning
Send tokens to the burn address to permanently remove them from circulation:
XRGE_BURN_0x000000000000000000000000000000000000000000000000000000000000DEAD
Burned amounts are tracked on-chain and queryable via GET /api/burned.
Listing on the DEX
Tokens are automatically listed on the DEX once a liquidity pool is created. Users can then:
- Swap between your token and XRGE
- Add/remove liquidity
- View price charts and pool stats
Token Standards
RougeChain tokens are native protocol-level assets (not smart contract tokens). This means:
- No ERC-20 compatibility (different chain architecture)
- Transfers are first-class transactions
- All token operations are signed with ML-DSA-65
- Quantum-resistant by default
NFTs
RougeChain supports on-chain NFTs with collections, minting, transfers, and marketplace features — all secured by post-quantum cryptography.
Features
- Collections — Create NFT collections with configurable max supply, royalties, and metadata
- Minting — Mint single or batch NFTs with metadata URIs and custom attributes
- Transfers — Send NFTs to any RougeChain address with optional sale price tracking
- Burning — Permanently destroy NFTs
- Locking — Lock individual NFTs to prevent transfers
- Freezing — Freeze entire collections to prevent further minting
Fee Structure
| Operation | Fee (XRGE) |
|---|---|
| Create Collection | 50 |
| Mint NFT | 5 |
| Batch Mint | 5 per NFT |
| Transfer | 1 |
| Burn | 0.1 |
| Lock/Unlock | 0.1 |
| Freeze Collection | 0.1 |
Security
All NFT operations use the v2 signed transaction API — transactions are signed client-side with ML-DSA-65 and verified on-chain. Only collection creators can mint, and only token owners can transfer or burn.
NFT Collections
Creating a Collection
- Go to the NFT Explorer page
- Click Create Collection
- Fill in:
- Symbol — Short identifier (e.g., "ROGUE")
- Name — Full collection name
- Max Supply — Maximum number of NFTs (optional, 0 = unlimited)
- Royalty — Royalty percentage in basis points (e.g., 500 = 5%)
- Image — Collection cover image URL
- Description — Collection description
- Click Create
The collection ID is generated from creator_pubkey:SYMBOL.
Collection Properties
| Property | Description |
|---|---|
id | Unique identifier (creator:symbol) |
symbol | Short token symbol |
name | Full collection name |
creator | Creator's public key |
max_supply | Max tokens (0 = unlimited) |
royalty_bps | Royalty in basis points |
frozen | Whether minting is frozen |
total_minted | Number of tokens minted |
Freezing a Collection
Collection creators can freeze their collections to permanently prevent further minting. This is irreversible and signals to holders that the supply is final.
Browsing Collections
The NFT Explorer page shows all collections with their stats, floor price, and total items. Click any collection to view its individual tokens.
Minting & Trading NFTs
Minting
Single Mint
- Open a collection page
- Click Mint NFT
- Enter the token name and optional metadata URI / attributes
- Click Mint
Only the collection creator can mint new tokens.
Batch Mint
Mint multiple NFTs at once:
- Open a collection page
- Click Batch Mint
- Provide a list of names (and optional URIs/attributes for each)
- Click Mint All
Fee is 5 XRGE per NFT in the batch.
Token Properties
Each NFT has:
| Property | Description |
|---|---|
token_id | Sequential ID within the collection |
name | Token name |
owner | Current owner's public key |
creator | Original minter |
metadata_uri | Link to off-chain metadata (IPFS, HTTP) |
attributes | On-chain key-value attributes |
locked | Whether the token is locked (non-transferable) |
created_at | Timestamp of minting |
Transferring
- Open the NFT detail page
- Click Transfer
- Enter the recipient's RougeChain public key
- Optionally set a sale price (for marketplace tracking)
- Confirm
Locked NFTs cannot be transferred until unlocked by the owner.
Burning
Permanently destroy an NFT:
- Open the NFT detail page
- Click Burn
- Confirm
Only the current owner can burn. This action is irreversible.
Locking
Lock an NFT to prevent it from being transferred:
- Open the NFT detail page
- Toggle Lock
Only the owner can lock/unlock their NFTs.
Block Explorer
RougeChain includes a built-in block explorer at rougechain.io for browsing blocks, transactions, addresses, tokens, and NFTs.
Features
- Block details — View block height, hash, timestamp, proposer, and all transactions
- Transaction details — View transaction type, sender, recipient, amount, fee, and status
- Address pages — View any address's balances, token holdings, and transaction history
- Token list — Browse all tokens created on RougeChain
- NFT Explorer — Browse NFT collections and individual tokens
- Global search — Search by address, transaction hash, or block height
Navigation
The explorer is integrated into the main RougeChain web app:
| Page | URL | Description |
|---|---|---|
| Blockchain | /blockchain | Block list with live updates |
| Block Detail | /block/:height | Individual block |
| Transaction | /tx/:hash | Individual transaction |
| Address | /address/:pubkey | Address details |
| Transactions | /transactions | All transactions list |
| NFT Explorer | /nft-explorer | NFT collections browser |
| Tokens | /tokens | All tokens list |
Block Explorer — Blocks
Block List
The Blockchain page shows all blocks in reverse chronological order with:
- Block height (index)
- Block hash (truncated)
- Timestamp
- Number of transactions
- Proposer address
Click any block to view its full details.
Block Detail Page
URL: /block/:height
Shows:
| Field | Description |
|---|---|
| Height | Block number in the chain |
| Hash | SHA-256 hash of the block |
| Previous Hash | Hash of the parent block |
| Timestamp | When the block was created |
| Proposer | Public key of the block proposer |
| Transaction Count | Number of transactions in the block |
Below the header, all transactions in the block are listed with their type, sender, recipient, amount, and fee.
API
GET /api/blocks — List all blocks (paginated)
GET /api/block/:height — Get a specific block by height
GET /api/blocks/summary — Block summary for charts
Block Explorer — Transactions
Transaction List
The Transactions page shows all transactions across the network with:
- Transaction hash
- Type (transfer, swap, stake, bridge, NFT, etc.)
- Sender and recipient
- Amount
- Block number
- Timestamp
Transaction Detail Page
URL: /tx/:hash
Shows the full transaction details:
| Field | Description |
|---|---|
| Hash | Transaction hash (SHA-256) |
| Type | Transaction type |
| From | Sender public key |
| To | Recipient public key |
| Amount | Transaction amount |
| Fee | Transaction fee (XRGE) |
| Token | Token symbol (if applicable) |
| Block | Block height containing this tx |
| Timestamp | When the transaction was processed |
| Signature | PQC signature (ML-DSA-65) |
Transaction Types
| Type | Description |
|---|---|
transfer | Token transfer between addresses |
create_token | New token creation |
stake | Staking tokens |
unstake | Unstaking tokens |
create_pool | Creating a liquidity pool |
add_liquidity | Adding liquidity to a pool |
remove_liquidity | Removing liquidity from a pool |
swap | Token swap via AMM |
bridge_mint | Minting bridged tokens (qETH, qUSDC) |
bridge_withdraw | Burning bridged tokens for withdrawal |
nft_create_collection | Creating an NFT collection |
nft_mint | Minting an NFT |
nft_transfer | Transferring an NFT |
nft_burn | Burning an NFT |
API
GET /api/txs — List recent transactions
GET /api/tx/:hash — Get transaction by hash
GET /api/address/:public_key/transactions — Get transactions for an address
Block Explorer — Addresses
Address Detail Page
URL: /address/:pubkey
Shows comprehensive information for any RougeChain address:
Balances
- XRGE balance
- All token balances (qETH, qUSDC, custom tokens)
- Staked amount (if any)
Transaction History
Paginated list of all transactions where this address is the sender or recipient, including:
- Transfers
- Swaps
- Staking operations
- Bridge operations
- NFT operations
NFTs Owned
List of all NFTs currently owned by this address, grouped by collection.
API
GET /api/balance/:public_key — XRGE balance
GET /api/balance/:public_key/:token_symbol — Token balance
GET /api/address/:public_key/transactions — Transaction history (paginated)
GET /api/nft/owner/:pubkey — NFTs owned
API Reference
The RougeChain node exposes a REST API on the configured --api-port (default: 5100).
Base URL
http://127.0.0.1:5100/api
For the public testnet:
https://testnet.rougechain.io/api
Endpoints Overview
System
| Endpoint | Method | Description |
|---|---|---|
/api/health | GET | Node health check |
/api/stats | GET | Network statistics |
Blockchain
| Endpoint | Method | Description |
|---|---|---|
/api/blocks | GET | Get all blocks |
/api/blocks/summary | GET | Block summary for charts |
/api/txs | GET | Get transactions |
Wallet
| Endpoint | Method | Description |
|---|---|---|
/api/wallet/create | POST | Create new wallet |
/api/balance/:publicKey | GET | Get balance |
/api/faucet | POST | Request testnet tokens |
/api/tx/submit | POST | Submit transaction |
Staking
| Endpoint | Method | Description |
|---|---|---|
/api/validators | GET | List validators |
/api/stake/submit | POST | Stake tokens |
/api/unstake/submit | POST | Unstake tokens |
Tokens
| Endpoint | Method | Description |
|---|---|---|
/api/token/create | POST | Create custom token |
/api/burn-address | GET | Get official burn address |
/api/burned | GET | Get burned token stats |
AMM/DEX
| Endpoint | Method | Description |
|---|---|---|
/api/pools | GET | List liquidity pools |
/api/pool/:pool_id | GET | Get pool details |
/api/pool/:pool_id/prices | GET | Get price history |
/api/pool/:pool_id/events | GET | Get pool events |
/api/pool/:pool_id/stats | GET | Get pool statistics |
/api/pool/create | POST | Create liquidity pool |
/api/pool/add-liquidity | POST | Add liquidity |
/api/pool/remove-liquidity | POST | Remove liquidity |
/api/swap/quote | POST | Get swap quote |
/api/swap/execute | POST | Execute swap |
Secure v2 API (Client-Side Signing)
All v2 endpoints accept pre-signed transactions. Private keys never leave the client.
| Endpoint | Method | Description |
|---|---|---|
/api/v2/transfer | POST | Transfer tokens |
/api/v2/token/create | POST | Create token |
/api/v2/pool/create | POST | Create pool |
/api/v2/pool/add-liquidity | POST | Add liquidity |
/api/v2/pool/remove-liquidity | POST | Remove liquidity |
/api/v2/swap/execute | POST | Execute swap |
/api/v2/stake | POST | Stake tokens |
/api/v2/unstake | POST | Unstake tokens |
/api/v2/faucet | POST | Request faucet |
P2P
| Endpoint | Method | Description |
|---|---|---|
/api/peers | GET | List known peers |
/api/peers/register | POST | Register as peer |
/api/blocks/import | POST | Import block from peer |
/api/tx/broadcast | POST | Receive broadcasted tx |
Messenger
| Endpoint | Method | Description |
|---|---|---|
/api/messenger/wallets | GET | List messenger wallets |
/api/messenger/wallets/register | POST | Register wallet |
/api/messenger/conversations | GET/POST | Conversations |
/api/messenger/messages | GET/POST | Messages |
/api/messenger/messages/read | POST | Mark message as read (self-destruct) |
| Endpoint | Method | Description |
|---|---|---|
/api/names/register | POST | Register a mail name |
/api/names/lookup | GET | Look up a name's public keys |
/api/names/reverse | GET | Reverse lookup (public key → name) |
/api/mail/send | POST | Send encrypted mail |
/api/mail/inbox | GET | Get inbox |
/api/mail/sent | GET | Get sent mail |
/api/mail/trash | GET | Get trashed mail |
/api/mail/message/:id | GET | Get single mail item |
/api/mail/read | POST | Mark mail as read |
/api/mail/move | POST | Move mail to folder |
/api/mail/:id | DELETE | Delete mail permanently |
Authentication
Some endpoints require an API key (if configured on the node):
curl -H "X-API-Key: your-api-key" https://testnet.rougechain.io/api/stats
Rate Limiting
Default limits:
- Read endpoints: 120 requests/minute
- Write endpoints: 30 requests/minute
Rate limit headers are included in responses:
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 115
Health & Stats API
System endpoints for monitoring node status and network statistics.
Health Check
GET /api/health
Returns the node's current status.
Response
{
"status": "ok",
"chain_id": "rougechain-devnet-1",
"height": 12345
}
| Field | Type | Description |
|---|---|---|
status | string | "ok" if the node is healthy |
chain_id | string | The chain identifier |
height | number | Current block height |
Use Cases
- Monitoring node uptime
- Checking sync status (compare height with peers)
- Load balancer health checks
Network Statistics
GET /api/stats
Returns network-wide statistics.
Response
{
"blockHeight": 12345,
"totalTransactions": 98765,
"totalWallets": 432,
"totalValidators": 15,
"totalStaked": 150000.0,
"totalBurned": 5000.0,
"totalPools": 8,
"chainId": "rougechain-devnet-1"
}
| Field | Type | Description |
|---|---|---|
blockHeight | number | Current block height |
totalTransactions | number | Total transactions processed |
totalWallets | number | Unique wallets on the network |
totalValidators | number | Active validators |
totalStaked | number | Total XRGE staked |
totalBurned | number | Total XRGE burned |
totalPools | number | Number of AMM liquidity pools |
chainId | string | Chain identifier |
Burn Stats
GET /api/burned
Get burned token statistics.
Response
{
"totalBurned": 5000.0,
"burnAddress": "XRGE_BURN_0x000000000000000000000000000000000000000000000000000000000000DEAD"
}
Examples
Monitoring Script
#!/bin/bash
while true; do
HEIGHT=$(curl -s http://127.0.0.1:5100/api/health | jq '.height')
echo "$(date): Block height = $HEIGHT"
sleep 10
done
Compare with Testnet
LOCAL=$(curl -s http://127.0.0.1:5100/api/health | jq '.height')
TESTNET=$(curl -s https://testnet.rougechain.io/api/health | jq '.height')
echo "Local: $LOCAL, Testnet: $TESTNET, Behind: $((TESTNET - LOCAL))"
Blocks API
Endpoints for querying block data on RougeChain.
Get Blocks
GET /api/blocks?limit=50&offset=0
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
limit | number | 50 | Maximum blocks to return |
offset | number | 0 | Pagination offset |
Response
{
"blocks": [
{
"version": 1,
"header": {
"version": 1,
"chainId": "rougechain-devnet-1",
"height": 42,
"time": 1706745600000,
"prevHash": "abc123...",
"txHash": "def456...",
"proposerPubKey": "ghi789..."
},
"txs": [...],
"proposerSig": "...",
"hash": "xyz..."
}
],
"total": 12345
}
Block Fields
| Field | Type | Description |
|---|---|---|
version | number | Block format version |
header.height | number | Block number |
header.time | number | Timestamp (ms since epoch) |
header.prevHash | string | Hash of previous block |
header.txHash | string | Merkle root of transactions |
header.proposerPubKey | string | Validator who proposed this block |
txs | array | Transactions included in this block |
proposerSig | string | ML-DSA-65 signature by the proposer |
hash | string | SHA-256 hash of this block |
Block Summary
GET /api/blocks/summary
Returns a lightweight summary of recent blocks, suitable for charts and dashboards.
Response
{
"blocks": [
{
"height": 42,
"time": 1706745600000,
"txCount": 5,
"proposer": "abc123..."
}
]
}
Import Block (P2P)
Used by peer nodes to propagate blocks.
POST /api/blocks/import
Content-Type: application/json
See Peers API for details.
Block Verification
Every block is verified by receiving nodes:
- Hash check — Recompute the block hash and compare
- Signature check — Verify ML-DSA-65 signature against the proposer's public key
- Height check — Must extend the current chain tip by exactly 1
- Previous hash — Must reference the current tip's hash
- Transaction validity — All transactions must have valid signatures and sufficient balances
Transactions API
Submit Transaction
Send XRGE tokens to another address.
POST /api/tx/submit
Content-Type: application/json
Request Body
{
"fromPrivateKey": "your-private-key-hex",
"fromPublicKey": "your-public-key-hex",
"toPublicKey": "recipient-public-key-hex",
"amount": 100.0,
"fee": 0.1
}
| Field | Type | Required | Description |
|---|---|---|---|
fromPrivateKey | string | Yes | Sender's ML-DSA-65 private key (hex) |
fromPublicKey | string | Yes | Sender's ML-DSA-65 public key (hex) |
toPublicKey | string | Yes | Recipient's public key (hex) |
amount | number | Yes | Amount of XRGE to send |
fee | number | No | Transaction fee (default: 0.1) |
Response
{
"success": true,
"txId": "abc123...",
"tx": {
"version": 1,
"txType": "transfer",
"fromPubKey": "...",
"nonce": 1234567890,
"payload": {
"toPubKeyHex": "...",
"amount": 100
},
"fee": 0.1,
"sig": "..."
}
}
Error Response
{
"success": false,
"error": "insufficient balance: have 50.0000 XRGE, need 100.1000 XRGE"
}
Get Transactions
Retrieve recent transactions.
GET /api/txs?limit=50&offset=0
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
limit | number | 50 | Max transactions to return |
offset | number | 0 | Pagination offset |
Response
{
"txs": [
{
"version": 1,
"txType": "transfer",
"fromPubKey": "abc...",
"nonce": 1234567890,
"payload": {
"toPubKeyHex": "def...",
"amount": 100
},
"fee": 0.1,
"sig": "ghi...",
"blockHeight": 42,
"blockTime": 1706745600000
}
],
"total": 150
}
Request Faucet (Testnet)
Get free testnet XRGE tokens.
POST /api/faucet
Content-Type: application/json
Request Body
{
"publicKey": "your-public-key-hex"
}
Response
{
"success": true,
"amount": 1000,
"txId": "abc123..."
}
Rate Limit
The faucet has additional rate limiting:
- 1 request per address per hour
- Whitelisted addresses bypass rate limits
Transaction Types
| Type | Description |
|---|---|
transfer | Standard XRGE transfer |
faucet | Faucet distribution |
stake | Stake tokens to become validator |
unstake | Unstake tokens |
create_token | Create custom token |
Wallet API
Endpoints for wallet creation, balance queries, and token management.
Get Balance
GET /api/balance/:publicKey
Path Parameters
| Parameter | Type | Description |
|---|---|---|
publicKey | string | The wallet's ML-DSA-65 public key (hex) |
Response
{
"balance": 1500.5,
"publicKey": "abc123...",
"tokens": {
"XRGE": 1500.5,
"qETH": 0.5
}
}
Create Wallet
POST /api/wallet/create
Creates a new wallet on the server. In practice, wallets are created client-side and only need to interact with the chain when transacting.
Response
{
"success": true,
"publicKey": "abc123...",
"privateKey": "def456..."
}
Note: The v2 API uses client-side key generation. Private keys never leave the browser. This endpoint exists for legacy compatibility.
Request Faucet
POST /api/faucet
Content-Type: application/json
Request Body
{
"publicKey": "your-public-key-hex"
}
Response
{
"success": true,
"amount": 1000,
"txId": "abc123..."
}
See Get Test Tokens for details on rate limits.
Submit Transaction (Legacy)
POST /api/tx/submit
Content-Type: application/json
See Transactions API for full details.
v2 Transfer (Client-Side Signing)
POST /api/v2/transfer
Content-Type: application/json
Request Body
{
"publicKey": "sender-public-key-hex",
"payload": {
"toPubKeyHex": "recipient-public-key-hex",
"amount": 100,
"fee": 0.1,
"token": "XRGE"
},
"nonce": 1706745600000,
"signature": "ml-dsa65-signature-hex"
}
The transaction is signed client-side using ML-DSA-65. The server verifies the signature before processing.
Response
{
"success": true,
"txId": "abc123..."
}
v2 Faucet
POST /api/v2/faucet
Content-Type: application/json
Request Body
{
"publicKey": "your-public-key-hex",
"nonce": 1706745600000,
"signature": "your-signature-hex"
}
Response
{
"success": true,
"amount": 1000,
"txId": "abc123..."
}
Burn Address
GET /api/burn-address
Response
{
"burnAddress": "XRGE_BURN_0x000000000000000000000000000000000000000000000000000000000000DEAD"
}
Send tokens to this address to permanently burn them. Burned amounts are tracked on-chain.
Staking API
Endpoints for validator staking operations.
List Validators
GET /api/validators
Query Parameters
| Parameter | Type | Description |
|---|---|---|
publicKey | string | (Optional) Filter by specific validator |
Response
{
"validators": [
{
"publicKey": "abc123...",
"stake": 10000.0,
"status": "active",
"blocksProposed": 142
},
{
"publicKey": "def456...",
"stake": 5000.0,
"status": "active",
"blocksProposed": 71
}
],
"totalStaked": 15000.0
}
Validator Fields
| Field | Type | Description |
|---|---|---|
publicKey | string | Validator's ML-DSA-65 public key |
stake | number | Amount of XRGE staked |
status | string | active or unbonding |
blocksProposed | number | Total blocks produced |
Stake Tokens
Legacy API
POST /api/stake/submit
Content-Type: application/json
{
"fromPrivateKey": "your-private-key-hex",
"fromPublicKey": "your-public-key-hex",
"amount": 1000
}
v2 API (Client-Side Signing)
POST /api/v2/stake
Content-Type: application/json
{
"publicKey": "your-public-key-hex",
"payload": {
"amount": 1000
},
"nonce": 1706745600000,
"signature": "your-ml-dsa65-signature-hex"
}
Response
{
"success": true,
"txId": "abc123...",
"stake": 1000.0,
"status": "active"
}
Requirements
| Requirement | Value |
|---|---|
| Minimum stake | 1,000 XRGE |
| Fee | 0.1 XRGE |
Unstake Tokens
Legacy API
POST /api/unstake/submit
Content-Type: application/json
{
"fromPrivateKey": "your-private-key-hex",
"fromPublicKey": "your-public-key-hex",
"amount": 500
}
v2 API (Client-Side Signing)
POST /api/v2/unstake
Content-Type: application/json
{
"publicKey": "your-public-key-hex",
"payload": {
"amount": 500
},
"nonce": 1706745600000,
"signature": "your-ml-dsa65-signature-hex"
}
Response
{
"success": true,
"txId": "abc123...",
"remainingStake": 500.0
}
Unbonding
After unstaking, tokens enter an unbonding period (~7 days on testnet) before they become available in your balance.
Error Responses
| Error | Cause |
|---|---|
"insufficient balance" | Not enough XRGE to stake |
"below minimum stake" | Amount is less than 1,000 XRGE |
"validator not found" | Trying to unstake but not a validator |
"invalid signature" | ML-DSA-65 signature verification failed |
Peers API
Endpoints for P2P peer management and discovery.
List Peers
Get all known peers.
GET /api/peers
Response
{
"peers": [
"https://testnet.rougechain.io/api",
"https://node2.example.com/api"
],
"count": 2
}
Register Peer
Register this node with another peer (enables discovery).
POST /api/peers/register
Content-Type: application/json
Request Body
{
"peerUrl": "https://mynode.example.com"
}
Response
{
"success": true,
"message": "Peer registered"
}
If the peer is already known:
{
"success": true,
"message": "Peer already known"
}
Import Block (P2P)
Receive a block from a peer (used for block propagation).
POST /api/blocks/import
Content-Type: application/json
Request Body
The full block object:
{
"version": 1,
"header": {
"version": 1,
"chainId": "rougechain-devnet-1",
"height": 42,
"time": 1706745600000,
"prevHash": "abc123...",
"txHash": "def456...",
"proposerPubKey": "..."
},
"txs": [...],
"proposerSig": "...",
"hash": "..."
}
Response
{
"success": true
}
Error Response
{
"success": false,
"error": "Block height 42 doesn't extend tip height 40"
}
Broadcast Transaction (P2P)
Receive a transaction broadcast from a peer.
POST /api/tx/broadcast
Content-Type: application/json
Request Body
The full transaction object.
Response
{
"success": true
}
Peer Discovery Flow
1. Node A starts with --peers "https://seed.example.com"
2. Node A calls GET /api/peers on seed node
→ Receives list of other peers
3. Node A adds new peers to its list
4. If Node A has --public-url, it calls POST /api/peers/register
on all known peers to announce itself
5. Every 30 seconds, repeat steps 2-4
This creates a mesh network where all nodes eventually discover each other.
Messenger API
Endpoints for the end-to-end encrypted PQC messenger.
All messages are encrypted client-side using ML-KEM-768 key encapsulation and AES-GCM. The server only stores encrypted blobs — it cannot read message contents.
Register Messenger Wallet
POST /api/messenger/wallets/register
Content-Type: application/json
Register your wallet's encryption public key so others can send you messages.
Request Body
{
"publicKey": "signing-public-key-hex",
"encPublicKey": "ml-kem768-public-key-hex",
"displayName": "Alice"
}
Response
{
"success": true
}
List Messenger Wallets
GET /api/messenger/wallets
Returns all registered messenger wallets.
Response
{
"wallets": [
{
"publicKey": "abc123...",
"encPublicKey": "def456...",
"displayName": "Alice"
}
]
}
Send Message
POST /api/messenger/messages
Content-Type: application/json
Request Body
{
"conversationId": "conv-uuid",
"senderPublicKey": "sender-pub-hex",
"recipientPublicKey": "recipient-pub-hex",
"senderEncrypted": "base64-encrypted-for-sender",
"recipientEncrypted": "base64-encrypted-for-recipient",
"senderDisplayName": "Alice",
"recipientDisplayName": "Bob",
"selfDestruct": false,
"destructSeconds": 0
}
Messages are encrypted twice — once for the sender (so they can read their sent messages) and once for the recipient. The server stores both ciphertexts.
Self-Destruct Messages
Set selfDestruct: true and destructSeconds to a value. After the recipient reads the message, it is marked as read and hidden from the UI.
Response
{
"success": true,
"messageId": "msg-uuid"
}
Get Messages
GET /api/messenger/messages?conversationId=conv-uuid&publicKey=your-pub-hex
Query Parameters
| Parameter | Type | Description |
|---|---|---|
conversationId | string | The conversation ID |
publicKey | string | Your public key (to get your encrypted copy) |
Response
{
"messages": [
{
"id": "msg-uuid",
"conversationId": "conv-uuid",
"senderPublicKey": "abc...",
"senderDisplayName": "Alice",
"encrypted": "base64-ciphertext",
"timestamp": 1706745600000,
"selfDestruct": false,
"mediaType": null
}
]
}
Mark Message as Read
POST /api/messenger/messages/read
Content-Type: application/json
Used for self-destruct messages.
{
"messageId": "msg-uuid"
}
Get Conversations
GET /api/messenger/conversations?publicKey=your-pub-hex
Returns all conversations for a wallet.
Response
{
"conversations": [
{
"conversationId": "conv-uuid",
"participants": [
{
"publicKey": "abc...",
"displayName": "Alice"
},
{
"publicKey": "def...",
"displayName": "Bob"
}
],
"lastMessage": "2024-01-31T12:00:00Z",
"unreadCount": 2
}
]
}
Media Messages
The messenger supports image and video attachments. Media is encrypted and sent as base64 within the message payload.
| Limit | Value |
|---|---|
| Max upload size | 50 MB (before compression) |
| Compressed target | ~1.5 MB |
| Image format | Converted to WebP client-side |
| Video format | Converted to WebM (VP9) client-side |
The client automatically compresses large media before encryption and sending.
Encryption Flow
Sender Recipient
│ │
│ 1. Generate shared secret via ML-KEM-768 │
│ 2. Derive AES-256 key via HKDF │
│ 3. Encrypt message with AES-GCM │
│ 4. Encrypt for self (sender copy) │
│ 5. Encrypt for recipient │
│ │
│── POST /messages (both ciphertexts) ────►│
│ │
│ 6. Decapsulate shared secret
│ 7. Derive same AES key
│ 8. Decrypt message
Wallet Blocking
Users can block wallets client-side. Blocked wallets are filtered from conversations and contacts. The block list is stored in browser localStorage under pqc_blocked_wallets.
This is a client-side feature — the server is not involved. Blocked users can still send messages, but they won't appear in the blocking user's UI.
Mail API
Endpoints for the PQC-encrypted mail system. Mail uses the same ML-KEM-768 encryption as the messenger but adds subject lines, folders, threading, and a name registry.
Name Registry
Register a Name
POST /api/names/register
Content-Type: application/json
Register a human-readable email address (e.g., alice@rouge.quant).
{
"name": "alice",
"publicKey": "your-signing-public-key-hex",
"encPublicKey": "your-ml-kem768-public-key-hex"
}
Response
{
"success": true,
"address": "alice@rouge.quant"
}
Error
{
"success": false,
"error": "Name already taken"
}
Lookup a Name
GET /api/names/lookup?name=alice
Response
{
"name": "alice",
"publicKey": "abc123...",
"encPublicKey": "def456..."
}
Reverse Lookup (Public Key to Name)
GET /api/names/reverse?publicKey=abc123...
Response
{
"name": "alice",
"publicKey": "abc123..."
}
Send Mail
POST /api/mail/send
Content-Type: application/json
Request Body
{
"from": "alice",
"fromPublicKey": "sender-pub-hex",
"to": "bob",
"toPublicKey": "recipient-pub-hex",
"senderEncrypted": "base64-encrypted-for-sender",
"recipientEncrypted": "base64-encrypted-for-recipient",
"replyToId": null
}
The senderEncrypted and recipientEncrypted fields contain the encrypted subject and body. Both sender and recipient get their own copy, just like the messenger.
Set replyToId to the ID of the mail being replied to, enabling threading.
Response
{
"success": true,
"id": "mail-uuid"
}
Get Inbox
GET /api/mail/inbox?publicKey=your-pub-hex
Response
{
"mail": [
{
"id": "mail-uuid",
"from": "alice",
"fromPublicKey": "abc...",
"to": "bob",
"toPublicKey": "def...",
"encrypted": "base64-ciphertext",
"timestamp": 1706745600000,
"read": false,
"replyToId": null
}
]
}
Get Sent Mail
GET /api/mail/sent?publicKey=your-pub-hex
Same response format as inbox, but returns mail you sent.
Get Single Mail
GET /api/mail/message/:id?publicKey=your-pub-hex
Mark as Read
POST /api/mail/read
Content-Type: application/json
{
"id": "mail-uuid"
}
Move to Trash
POST /api/mail/move
Content-Type: application/json
{
"id": "mail-uuid",
"folder": "trash"
}
Get Trash
GET /api/mail/trash?publicKey=your-pub-hex
Delete Mail
DELETE /api/mail/:id
Permanently deletes a mail item.
Email Domains
| Domain | Platform |
|---|---|
@rouge.quant | Website and browser extensions |
@qwalla.mail | QWalla mobile app (future) |
Threading
Mail threading is handled client-side by following the replyToId chain. When viewing a mail, the client:
- Fetches both inbox and sent mail
- Walks the
replyToIdchain to build the thread - Displays messages in chronological order
- Collapses older messages, expands the latest two
Encryption
Mail uses the same encryption as the messenger:
- Look up recipient's ML-KEM-768 public key via Name Registry
- Encapsulate a shared secret
- Derive AES-256 key via HKDF
- Encrypt subject + body with AES-GCM
- Create separate ciphertext for sender and recipient
- Server stores both encrypted copies
API Reference — Bridge
ETH/USDC Bridge
Get Bridge Config
GET /api/bridge/config
Returns bridge status, custody address, chain ID, and supported tokens.
Response:
{
"enabled": true,
"custodyAddress": "0x...",
"chainId": 84532,
"supportedTokens": ["ETH", "USDC"]
}
Claim Bridge Deposit
POST /api/bridge/claim
Claim wrapped tokens (qETH or qUSDC) after depositing on Base Sepolia.
Body:
{
"evmTxHash": "0x...",
"evmAddress": "0x...",
"evmSignature": "0x...",
"recipientRougechainPubkey": "abc123...",
"token": "ETH"
}
The token field can be "ETH" (default) or "USDC". The node verifies the EVM transaction, checks the signature, and mints the corresponding wrapped token.
Bridge Withdraw
POST /api/bridge/withdraw
Burn wrapped tokens and create a pending withdrawal for the relayer.
Body (signed):
{
"fromPublicKey": "abc123...",
"amountUnits": 10000,
"evmAddress": "0x...",
"signature": "...",
"payload": { "type": "bridge_withdraw", "..." }
}
List Pending Withdrawals
GET /api/bridge/withdrawals
Returns all pending ETH/USDC withdrawals waiting for the relayer.
Fulfill Withdrawal
DELETE /api/bridge/withdrawals/:txId
Mark a withdrawal as fulfilled. Requires x-bridge-relayer-secret header or a PQC-signed body.
XRGE Bridge
Get XRGE Bridge Config
GET /api/bridge/xrge/config
Response:
{
"enabled": true,
"vaultAddress": "0x...",
"tokenAddress": "0x147120faEC9277ec02d957584CFCD92B56A24317",
"chainId": 84532
}
Claim XRGE Deposit
POST /api/bridge/xrge/claim
Body:
{
"evmTxHash": "0x...",
"evmAddress": "0x...",
"amount": "1000000000000000000",
"recipientRougechainPubkey": "abc123..."
}
XRGE Withdraw
POST /api/bridge/xrge/withdraw
Body (signed):
{
"fromPublicKey": "abc123...",
"amount": 100,
"evmAddress": "0x...",
"signature": "...",
"payload": { "..." }
}
List XRGE Withdrawals
GET /api/bridge/xrge/withdrawals
Fulfill XRGE Withdrawal
DELETE /api/bridge/xrge/withdrawals/:txId
API Reference — NFTs
All write operations use the v2 signed transaction API (client-side signing).
Read Endpoints
List Collections
GET /api/nft/collections
Get Collection
GET /api/nft/collection/:id
Get Collection Tokens
GET /api/nft/collection/:id/tokens
Get Token
GET /api/nft/token/:collection_id/:token_id
Get NFTs by Owner
GET /api/nft/owner/:pubkey
Write Endpoints (v2 Signed)
All write endpoints accept a signed transaction body:
{
"payload": { "type": "nft_mint", "..." },
"signature": "...",
"public_key": "..."
}
Create Collection
POST /api/v2/nft/collection/create
Payload fields: symbol, name, maxSupply, royaltyBps, image, description
Fee: 50 XRGE
Mint NFT
POST /api/v2/nft/mint
Payload fields: collectionId, name, metadataUri, attributes
Fee: 5 XRGE
Batch Mint
POST /api/v2/nft/batch-mint
Payload fields: collectionId, names, uris, batchAttributes
Fee: 5 XRGE per NFT
Transfer NFT
POST /api/v2/nft/transfer
Payload fields: collectionId, tokenId, to, salePrice
Fee: 1 XRGE
Burn NFT
POST /api/v2/nft/burn
Payload fields: collectionId, tokenId
Fee: 0.1 XRGE
Lock/Unlock NFT
POST /api/v2/nft/lock
Payload fields: collectionId, tokenId, locked
Fee: 0.1 XRGE
Freeze Collection
POST /api/v2/nft/freeze-collection
Payload fields: collectionId, frozen
Fee: 0.1 XRGE
API Reference — DEX / AMM
Read Endpoints
List Pools
GET /api/pools
Returns all liquidity pools with reserves, LP supply, and token info.
Get Pool
GET /api/pool/:pool_id
Pool ID format: TOKEN_A-TOKEN_B (alphabetically sorted).
Get Pool Events
GET /api/pool/:pool_id/events
Returns swap, add_liquidity, and remove_liquidity events for a pool.
Get Pool Price History
GET /api/pool/:pool_id/prices
Get Pool Stats
GET /api/pool/:pool_id/stats
Get Swap Quote
POST /api/swap/quote
Body:
{
"tokenIn": "XRGE",
"tokenOut": "qETH",
"amountIn": 1000
}
Response:
{
"amountOut": 95,
"priceImpact": 0.5,
"fee": 3,
"route": ["XRGE", "qETH"]
}
Get All Events
GET /api/events
Returns all DEX events across all pools.
Write Endpoints (v2 Signed)
Create Pool
POST /api/v2/pool/create
Payload fields: token_a, token_b, amount_a, amount_b
Fee: 100 XRGE
Add Liquidity
POST /api/v2/pool/add-liquidity
Payload fields: pool_id, amount_a, amount_b
Fee: 1 XRGE
Remove Liquidity
POST /api/v2/pool/remove-liquidity
Payload fields: pool_id, lp_amount
Fee: 1 XRGE
Execute Swap
POST /api/v2/swap/execute
Payload fields: token_in, token_out, amount_in, min_amount_out
Fee: 0.3% of input + 1 XRGE
Architecture
An overview of RougeChain's system architecture.
High-Level Architecture
┌───────────────────────────────────────────────────────────┐
│ Clients │
│ │
│ ┌──────────┐ ┌──────────────────┐ ┌────────────────┐ │
│ │ Website │ │ Browser Extension│ │ @rougechain/sdk│ │
│ │ React │ │ Chrome / Firefox │ │ npm package │ │
│ └────┬─────┘ └────────┬─────────┘ └───────┬────────┘ │
│ │ │ │ │
│ │ Client-side ML-DSA-65 signing │ │
│ │ Client-side ML-KEM-768 encryption │ │
│ └────────────┬────┴─────────────────────┘ │
└────────────────────┼──────────────────────────────────────┘
│ HTTPS REST API
▼
┌───────────────────────────────────────────────────────────┐
│ Core Node (Rust) │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ REST API │ │Blockchain│ │Validator │ │Messenger │ │
│ │ (Actix) │ │ Engine │ │ / PoS │ │ Server │ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
│ │ │ │ │ │
│ ┌────┴──────────────┴──────────────┴──────────────┴────┐ │
│ │ Storage Layer │ │
│ │ chain.jsonl │ validators-db (RocksDB) │ messenger-db│ │
│ └──────────────────────────────────────────────────────┘ │
└────────────────────┬──────────────────────────────────────┘
│ P2P (HTTP)
▼
┌───────────────────────────────────────────────────────────┐
│ Peer Nodes │
│ Block sync │ TX broadcast │ Peer discovery │
└───────────────────────────────────────────────────────────┘
Components
Core Node (Rust)
The backend is a single Rust binary (quantum-vault-daemon) that includes:
| Module | Responsibility |
|---|---|
| REST API | HTTP endpoints via Actix-web |
| Blockchain Engine | Block production, transaction processing, state management |
| Validator / PoS | Stake tracking, proposer selection, rewards |
| Messenger Server | Stores encrypted messages and wallet registrations |
| Mail Server | Stores encrypted mail, name registry |
| P2P Layer | Peer discovery, block/tx propagation |
| AMM/DEX | Liquidity pools, swap execution, price calculation |
| Bridge | qETH bridge from Base Sepolia |
Frontend (React + TypeScript)
The website at rougechain.io is a single-page application built with:
| Technology | Purpose |
|---|---|
| React 18 | UI framework |
| TypeScript | Type safety |
| Vite | Build tool |
| Tailwind CSS | Styling |
| shadcn/ui | Component library |
@noble/post-quantum | PQC cryptography (ML-DSA-65, ML-KEM-768) |
The frontend is a PWA (Progressive Web App) and can be installed on mobile and desktop.
Browser Extensions
Two Chrome extensions provide wallet functionality:
| Extension | Description |
|---|---|
| RougeChain Wallet | Primary browser extension |
| rougechain-wallet | Secondary extension |
Both inject a window.rougechain provider (similar to MetaMask's window.ethereum) for dApp integration.
SDK (@rougechain/sdk)
The npm package @rougechain/sdk provides a programmatic interface for interacting with RougeChain from Node.js or browser applications.
Cryptography Stack
┌─────────────────────────────────────────┐
│ Application Layer │
│ Transactions │ Messages │ Mail │ Auth │
└─────────────┬───────────────────────────┘
│
┌─────────────▼───────────────────────────┐
│ Cryptographic Primitives │
│ │
│ ML-DSA-65 (FIPS 204) │
│ └─ Signing: txs, blocks, stakes │
│ │
│ ML-KEM-768 (FIPS 203) │
│ └─ Key encapsulation: messenger, mail │
│ │
│ AES-256-GCM │
│ └─ Symmetric encryption of content │
│ │
│ HKDF (SHA-256) │
│ └─ Key derivation from shared secrets │
│ │
│ SHA-256 │
│ └─ Block hashes, tx hashes, Merkle │
└─────────────────────────────────────────┘
Data Flow
Transaction Flow
1. User creates transaction in browser
2. Transaction payload is constructed
3. ML-DSA-65 signs the payload client-side
4. Signed transaction is sent to node via REST API
5. Node verifies signature
6. Transaction enters mempool
7. Validator includes it in next block
8. Block is signed and propagated to peers
Message Flow
1. Sender looks up recipient's ML-KEM-768 public key
2. ML-KEM-768 encapsulation generates shared secret
3. HKDF derives AES-256 key from shared secret
4. Message is encrypted with AES-GCM (for both sender and recipient)
5. Encrypted blobs are sent to server
6. Recipient fetches encrypted blob
7. ML-KEM-768 decapsulation recovers shared secret
8. Message is decrypted client-side
Mail Flow
1. User registers a name (e.g., alice@rouge.quant) via Name Registry
2. Sender composes email, encrypts subject + body with PQC
3. Encrypted mail is stored on the server
4. Recipient fetches and decrypts client-side
5. Thread history is reconstructed via replyToId chain
Storage
Node Storage
| Store | Format | Content |
|---|---|---|
chain.jsonl | Append-only JSON lines | Block data |
tip.json | JSON | Current chain tip reference |
validators-db/ | RocksDB | Validator stakes and state |
messenger-db/ | RocksDB | Encrypted messages and wallets |
Client Storage
| Store | Location | Content |
|---|---|---|
| Wallet keys | localStorage | Encrypted ML-DSA-65 and ML-KEM-768 keys |
| Block list | localStorage | Blocked wallet addresses |
| Mail settings | localStorage | Email signature preferences |
| Display name | localStorage | User's messenger display name |
Security Model
| Principle | Implementation |
|---|---|
| Keys never leave client | All signing/encryption happens in-browser |
| Server is untrusted | Server only stores encrypted data |
| Quantum-resistant | NIST-approved PQC algorithms throughout |
| No seed phrases | Keys are stored directly (backup via file export) |
| Dual encryption | Messages encrypted for both sender and recipient |
Post-Quantum Cryptography
RougeChain uses NIST-approved post-quantum cryptographic algorithms to protect against both classical and quantum computer attacks.
Why Post-Quantum?
Quantum computers threaten current cryptography:
| Algorithm | Quantum Threat |
|---|---|
| RSA | Broken by Shor's algorithm |
| ECDSA | Broken by Shor's algorithm |
| SHA-256 | Weakened (Grover's algorithm) |
| ML-DSA | Secure |
| ML-KEM | Secure |
Algorithms Used
ML-DSA-65 (Digital Signatures)
Formerly: CRYSTALS-Dilithium
Standard: FIPS 204
Security Level: NIST Level 3 (192-bit classical equivalent)
Used for:
- Transaction signatures
- Block proposal signatures
- Validator attestations
Key sizes:
| Component | Size |
|---|---|
| Public key | ~1,952 bytes |
| Private key | ~4,032 bytes |
| Signature | ~3,309 bytes |
ML-KEM-768 (Key Encapsulation)
Formerly: CRYSTALS-Kyber
Standard: FIPS 203
Security Level: NIST Level 3
Used for:
- Messenger encryption
- PQC Mail encryption
- Future: Encrypted transactions
Key sizes:
| Component | Size |
|---|---|
| Public key | ~1,184 bytes |
| Private key | ~2,400 bytes |
| Ciphertext | ~1,088 bytes |
SHA-256 (Hashing)
Used for:
- Block hashes
- Transaction hashes
- Merkle trees
While Grover's algorithm reduces SHA-256 security to ~128-bit equivalent against quantum computers, this is still considered secure.
Implementation
RougeChain uses the following libraries:
| Component | Library |
|---|---|
| Backend (Rust) | pqcrypto crate |
| Frontend (JS) | @noble/post-quantum |
All cryptographic operations happen locally - private keys never leave your device.
Key Generation
#![allow(unused)] fn main() { // Rust example use pqcrypto_dilithium::dilithium3::*; let (pk, sk) = keypair(); let signature = sign(message, &sk); let valid = verify(message, &signature, &pk); }
// TypeScript example
import { ml_dsa65 } from '@noble/post-quantum/ml-dsa';
const { publicKey, secretKey } = ml_dsa65.keygen();
const signature = ml_dsa65.sign(message, secretKey);
const valid = ml_dsa65.verify(signature, message, publicKey);
Security Considerations
- Key storage - Private keys are stored in browser localStorage (encrypted in production)
- Entropy - Keys use cryptographically secure random number generators
- Side channels - Library implementations are designed to be constant-time
- Hybrid approach - Consider adding classical signatures for defense-in-depth
Future Roadmap
- SLH-DSA (SPHINCS+) as alternative signature scheme
- Hybrid classical+PQC mode
- Hardware wallet support
- Threshold signatures for multi-sig
Browser Extensions
RougeChain provides browser extensions that serve as quantum-safe wallets, similar to how MetaMask works for Ethereum — but using post-quantum cryptography.
Available Extensions
| Extension | Description | Store |
|---|---|---|
| RougeChain Wallet | Primary browser extension | Chrome Web Store |
| rougechain-wallet | Secondary extension | Chrome Web Store |
Features
- Wallet — View balances, send/receive XRGE, claim faucet, custom token support
- Encrypted Messenger — E2E encrypted chat using ML-KEM-768 + ML-DSA-65
- PQC Mail — Encrypted email with
@rouge.quantaddresses - Vault Lock — AES-256-GCM encryption with PBKDF2 key derivation and auto-lock timer
- Cross-browser — Chrome, Edge, Brave, Opera, Arc, Firefox (Manifest V3)
Installation
From Chrome Web Store
- Visit the extension page on the Chrome Web Store
- Click Add to Chrome
- The extension icon appears in your toolbar
From Source
cd browser-extension
npm install
npm run build
- Open
chrome://extensions(oredge://extensions,brave://extensions) - Enable Developer mode
- Click Load unpacked
- Select the
browser-extension/distfolder
Firefox
cd browser-extension
npm install
npm run build
- Open
about:debugging#/runtime/this-firefox - Click Load Temporary Add-on
- Select
browser-extension/dist/manifest.json
DApp Integration
The extension injects a window.rougechain provider object, similar to MetaMask's window.ethereum. DApps can use this to interact with the user's wallet.
Detecting the Extension
if (window.rougechain) {
console.log('RougeChain wallet detected');
const address = await window.rougechain.getAddress();
}
Provider API
| Method | Description |
|---|---|
getAddress() | Get the user's public key |
signTransaction(tx) | Sign a transaction with ML-DSA-65 |
getBalance() | Get the wallet's balance |
getNetwork() | Get the current network (testnet/devnet) |
Security
| Feature | Implementation |
|---|---|
| Vault encryption | AES-256-GCM with PBKDF2-derived key |
| Auto-lock | Configurable timer via background service worker |
| Key storage | chrome.storage.local (encrypted) |
| Signing | ML-DSA-65 (FIPS 204) — quantum-resistant |
| Encryption | ML-KEM-768 (FIPS 203) — quantum-resistant |
Permissions
The extensions request minimal permissions:
| Permission | Purpose |
|---|---|
storage | Store encrypted wallet data |
alarms | Auto-lock timer |
notifications | Transaction alerts |
| Host permissions | Connect to RougeChain nodes (rougechain.io, testnet.rougechain.io, localhost) |
Why Not MetaMask?
MetaMask and all EVM wallets use secp256k1 / ECDSA cryptography. RougeChain uses ML-DSA-65 / ML-KEM-768 (post-quantum). The key formats, signature schemes, and transaction structures are fundamentally incompatible. RougeChain's extensions are purpose-built for quantum-safe operations.
See PQC Cryptography for details on the algorithms used.
SDK (@rougechain/sdk)
The official JavaScript/TypeScript SDK for building on RougeChain.
Installation
npm install @rougechain/sdk
Quick Start
import { RougeChain, Wallet } from '@rougechain/sdk';
const rc = new RougeChain('https://testnet.rougechain.io/api');
// Generate a new post-quantum wallet
const wallet = Wallet.generate();
console.log('Public key:', wallet.publicKey);
// Request testnet tokens
await rc.faucet(wallet);
// Check balance
const balance = await rc.getBalance(wallet.publicKey);
console.log('Balance:', balance);
// Transfer tokens
await rc.transfer(wallet, { to: recipientPubKey, amount: 100 });
Wallet
All signing happens client-side. Private keys never leave your application.
import { Wallet } from '@rougechain/sdk';
// Generate new keypair
const wallet = Wallet.generate();
// Restore from saved keys
const restored = Wallet.fromKeys(publicKey, privateKey);
// Export for storage
const keys = wallet.toJSON(); // { publicKey, privateKey }
// Verify keypair integrity
const valid = wallet.verify(); // true
Client
import { RougeChain } from '@rougechain/sdk';
// Basic connection
const rc = new RougeChain('https://testnet.rougechain.io/api');
// With API key
const rc = new RougeChain('https://testnet.rougechain.io/api', {
apiKey: 'your-api-key',
});
Available Methods
Queries
await rc.getHealth();
await rc.getStats();
await rc.getBlocks({ limit: 10 });
await rc.getBalance(publicKey);
await rc.getValidators();
await rc.getTokens();
await rc.getBurnedTokens();
Transactions
await rc.transfer(wallet, { to: recipient, amount: 100 });
await rc.transfer(wallet, { to: recipient, amount: 50, token: 'MYTOKEN' });
await rc.createToken(wallet, { name: 'My Token', symbol: 'MTK', totalSupply: 1_000_000 });
await rc.burn(wallet, 500, 1, 'XRGE');
await rc.faucet(wallet);
Staking
await rc.stake(wallet, { amount: 1000 });
await rc.unstake(wallet, { amount: 500 });
DEX (rc.dex)
await rc.dex.getPools();
await rc.dex.getPool('XRGE-MTK');
await rc.dex.quote({ poolId: 'XRGE-MTK', tokenIn: 'XRGE', amountIn: 100 });
await rc.dex.swap(wallet, { tokenIn: 'XRGE', tokenOut: 'MTK', amountIn: 100, minAmountOut: 95 });
await rc.dex.createPool(wallet, { tokenA: 'XRGE', tokenB: 'MTK', amountA: 10000, amountB: 5000 });
await rc.dex.addLiquidity(wallet, { poolId: 'XRGE-MTK', amountA: 1000, amountB: 500 });
await rc.dex.removeLiquidity(wallet, { poolId: 'XRGE-MTK', lpAmount: 100 });
NFTs (rc.nft)
await rc.nft.createCollection(wallet, { symbol: 'ART', name: 'My Art', royaltyBps: 500, maxSupply: 10000 });
await rc.nft.mint(wallet, { collectionId: 'abc123', name: 'Piece #1', metadataUri: '...' });
await rc.nft.batchMint(wallet, { collectionId: 'abc123', names: ['#1', '#2'], uris: ['...', '...'] });
await rc.nft.transfer(wallet, { collectionId: 'abc123', tokenId: 1, to: buyerPubKey, salePrice: 100 });
await rc.nft.getCollections();
await rc.nft.getByOwner(wallet.publicKey);
Bridge (rc.bridge)
await rc.bridge.getConfig();
await rc.bridge.withdraw(wallet, { amount: 500000, evmAddress: '0x...' });
await rc.bridge.claim({ evmTxHash: '0x...', evmAddress: '0x...', evmSignature: '0x...', recipientPubkey: wallet.publicKey });
await rc.bridge.getWithdrawals();
Environment Support
| Environment | Requirements |
|---|---|
| Browser | Any bundler (Vite, webpack) |
| Node.js 18+ | Works out of the box |
| Node.js < 18 | Provide node-fetch polyfill |
| React Native | Install react-native-get-random-values |
TypeScript
Full type declarations are included:
import type { Block, Transaction, Validator, LiquidityPool, NftCollection } from '@rougechain/sdk';
Security
- All signatures use ML-DSA-65 (FIPS 204), resistant to quantum attacks
- Private keys never leave your application
- The SDK does not store keys — persistence is your responsibility
Source
The SDK source code is in the sdk/ directory of the quantum-vault repository.