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
| 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,
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.