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, image: 'https://example.com/logo.png' });
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)

// Pool queries
await rc.dex.getPools();
await rc.dex.getPool('XRGE-MTK');
await rc.dex.getPriceHistory('XRGE-MTK');  // PriceSnapshot[] — for building charts
await rc.dex.getPoolStats('XRGE-MTK');     // volume, swap counts (total + 24h)
await rc.dex.getPoolEvents('XRGE-MTK');    // swap/add/remove event history

// Quote & swap
await rc.dex.quote({ poolId: 'XRGE-MTK', tokenIn: 'XRGE', tokenOut: 'MTK', amountIn: 100 });
await rc.dex.swap(wallet, { tokenIn: 'XRGE', tokenOut: 'MTK', amountIn: 100, minAmountOut: 95 });

// Liquidity
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();

Mail Name Registry (rc.mail)

Register human-readable names and resolve recipients before sending encrypted mail. Third-party apps must call these for cross-app mail to work.

All write operations require a wallet parameter for ML-DSA-65 signed requests via /api/v2/ endpoints with anti-replay nonce protection.

// Register wallet on the node first (signed request)
await rc.messenger.registerWallet(wallet, {
  id: wallet.publicKey,
  displayName: "Alice",
  signingPublicKey: wallet.publicKey,
  encryptionPublicKey: encPubKey,
});

// Register a mail name (signed request)
await rc.mail.registerName(wallet, "alice", wallet.publicKey);

// Resolve a name → wallet info (public, no signing needed)
const resolved = await rc.mail.resolveName("bob");
// { entry: { name, wallet_id }, wallet: { id, encryption_public_key, ... } }

// Reverse lookup: wallet ID → name (public, no signing needed)
const name = await rc.mail.reverseLookup(wallet.publicKey); // "alice"

// Release a name (signed request)
await rc.mail.releaseName(wallet, "alice");

// Send mail (signed request, multi-recipient CEK encryption)
await rc.mail.send(wallet, { from, to, subject, body, encrypted_subject, encrypted_body });

// Read inbox / sent (signed requests)
const inbox = await rc.mail.getInbox(wallet);
const sent = await rc.mail.getSent(wallet);

// Manage mail (signed requests)
await rc.mail.markRead(wallet, messageId);
await rc.mail.move(wallet, messageId, "trash");
await rc.mail.delete(wallet, messageId);

Messenger (rc.messenger)

All operations use ML-DSA-65 signed requests with nonce-based anti-replay protection.

await rc.messenger.getWallets();
await rc.messenger.registerWallet(wallet, { id, displayName, signingPublicKey, encryptionPublicKey });
await rc.messenger.getConversations(wallet);
await rc.messenger.createConversation(wallet, [pubKeyA, pubKeyB]);
await rc.messenger.getMessages(wallet, conversationId);
await rc.messenger.sendMessage(wallet, conversationId, encryptedContent, { selfDestruct: true, destructAfterSeconds: 30 });
await rc.messenger.deleteMessage(wallet, messageId, conversationId);
await rc.messenger.deleteConversation(wallet, conversationId);

Push Notifications

// Register for push notifications (PQC-signed)
await rc.registerPushToken(publicKey, privateKey, 'ExponentPushToken[xxx]');

// Unregister
await rc.unregisterPushToken(publicKey, privateKey);

Address Resolution

// Resolve rouge1… address to public key, or vice versa
const result = await rc.resolveAddress('rouge1q8f3x...');
// → { address, publicKey, balance }

Account Nonce

const nonce = await rc.getNonce(publicKey);
// → { nonce, next_nonce }

Token Allowances

// ERC-20 style approve/transferFrom
await rc.approveAllowance(wallet, { spender, token, amount });
await rc.transferFrom(wallet, { owner, to, token, amount });
await rc.freezeToken(wallet, { token, frozen: true });

Multi-Sig Wallets

// Create a 2-of-3 multi-sig wallet
await rc.sendTransaction(wallet, {
  txType: 'multisig_create',
  payload: {
    multisig_signers: [keyA, keyB, keyC],
    multisig_threshold: 2,
    multisig_label: 'Team Treasury',
  },
});

// Submit a transfer proposal
await rc.sendTransaction(wallet, {
  txType: 'multisig_submit',
  payload: {
    multisig_wallet_id: 'ms-abc123...',
    multisig_proposal_tx_type: 'transfer',
    multisig_proposal_payload: { to_pub_key_hex: recipient, amount: 1000 },
  },
});

// Co-signer approves
await rc.sendTransaction(coSignerWallet, {
  txType: 'multisig_approve',
  payload: { multisig_proposal_id: 'mp-def456...' },
});

// Query wallets + proposals
const wallets = await rc.get('/multisig/wallets');
const myWallets = await rc.get(`/multisig/wallets/${myPubKey}`);
const proposals = await rc.get(`/multisig/wallet/${walletId}/proposals`);

Smart Contracts (rc.shielded)

Contract helpers are accessed via the rc.shielded sub-client:

// Deploy WASM contract
const deploy = await rc.shielded.deployContract({
  wasm: base64WasmBytes,
  deployer: wallet.publicKey,
});

// Call contract method
const result = await rc.shielded.callContract({
  contractAddr: deploy.address,
  method: 'increment',
  caller: wallet.publicKey,
  args: { key: 'value' },
  gasLimit: 10_000_000,
});

// Query contract
const meta = await rc.shielded.getContract(deploy.address);
const state = await rc.shielded.getContractState(deploy.address);
const events = await rc.shielded.getContractEvents(deploy.address);

EIP-1559 Fee Info

const feeInfo = await rc.getFeeInfo();
// → { base_fee, total_fee_suggestion, total_fees_burned, block_height }

Environment Support

EnvironmentRequirements
BrowserAny bundler (Vite, webpack)
Node.js 18+Works out of the box
Node.js < 18Provide node-fetch polyfill
React NativeInstall react-native-get-random-values

TypeScript

Full type declarations are included:

import type {
  Block, Transaction, Validator, LiquidityPool, NftCollection,
  NameEntry, ResolvedName, MailMessage, SendMailParams,
  PriceSnapshot, PoolStats, SwapQuote,
} 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
  • All mail, messenger, and name registry operations use ML-DSA-65 signed requests with timestamp validation and nonce-based anti-replay protection
  • Mail uses a CEK pattern for efficient multi-recipient encryption via ML-KEM-768
  • TOFU key fingerprint tracking for contact key-change detection

Source

The SDK source code is in the sdk/ directory of the quantum-vault repository.