@oredata/sdk
v0.16.3
Published
TypeScript client for the oredata.supply API.
Maintainers
Readme
@oredata/sdk
Real-time SDK for ORE v3 — Build games, bots, and dashboards on top of Solana's most active on-chain RNG.
npm install @oredata/sdkNew here? Visit oredata.supply for interactive docs, a live playground, and guided onboarding.
What is ORE?
ORE is a proof-of-work token on Solana where miners compete in timed rounds by placing bids on a 5×5 grid. One tile wins each round — winners split the pot. This SDK provides the data and transaction infrastructure to build on top of it.
Learn more about ORE at ore.supply.
✨ Features
| | |
|---|---|
| 🎮 Live Game State | Round data, pot size, per-tile bets — updated every second |
| 🏆 Winner Events | Know who won instantly, not when the next round starts |
| 💰 Wallet Tracking | SOL balance, claimable rewards, ORE tokens |
| 💵 Token Prices | Real-time SOL & ORE in USD |
| 📊 Token Data | ORE supply, market cap, emission stats |
| ⏱️ Countdown Timers | Accurate countdowns using actual Solana slot times |
| 🔧 Transaction Builders | Place bids & claim rewards — no RPC setup needed |
| 💬 Community Chat | Send & receive ore.supply chat (unified ecosystem) |
| 🤖 Bot Self-Service | Register, manage keys, projects, T&C — all via wallet |
| ⚛️ React Hooks | Provider, hooks, auto-updates |
| 🖥️ Server Multiplexer | One API connection → 1000+ browser clients |
| 📝 Full TypeScript | Zero any, complete types |
🚀 Quick Start
1. Connect
import { OredataClient } from '@oredata/sdk';
const client = new OredataClient({
apiKey: process.env.OREDATA_API_KEY, // Get yours at oredata.supply/register
});
client.start();2. Get Game State
const store = client.getStore();
// Current round data
const round = store.getCurrentRound();
console.log(`Round ${round.roundId}: ${round.totals.deployedSol} SOL in pot`);
// Previous round winner
const prev = store.getPreviousRound();
if (prev?.winner) {
console.log(`Last winner: Tile ${prev.winner.tile + 1}`);
}3. Listen for Events
// New round started
store.on('roundStarted', ({ roundId }) => {
console.log(`🎲 Round ${roundId} - betting open!`);
});
// Winner announced
store.on('roundCompleted', ({ roundId, winner }) => {
console.log(`🎉 Round ${roundId} winner: Tile ${winner.tile + 1}`);
});
// Pot updated
store.on('roundDataUpdated', ({ data }) => {
console.log(`💰 Pot: ${data.totals.deployedSol} SOL`);
});Consent (new)
import { ConsentClient, buildConsentMessage } from '@oredata/sdk';
const http = new OredataClient({ apiKey: process.env.OREDATA_API_KEY });
const consent = new ConsentClient({ http });
const terms = await consent.getTerms();
const status = await consent.getStatus(walletAddress);
if (status.status !== 'accepted') {
const msg = buildConsentMessage({
projectName: terms.project?.name,
projectDomainOrSlug: terms.project?.domain ?? terms.project?.slug,
walletAddress,
version: terms.version,
});
const signature = await signMessage(new TextEncoder().encode(msg.message));
await consent.accept({ walletAddress, signature: bs58.encode(signature), termsVersion: terms.version });
}📦 What's Included
@oredata/sdk → Core client, events, wallet tracking
@oredata/sdk/react → React hooks & provider
@oredata/sdk/server → Server-side multiplexer for SSE🎯 Common Patterns
Get Current Pot Size
const round = store.getCurrentRound();
const pot = round?.totals.deployedSol ?? 0;Check If Round Is Active
const round = store.getCurrentRound();
const isActive = round?.mining.status === 'active';Get Token Prices
const solPrice = store.getSolPriceUsd(); // e.g., 242.50
const orePrice = store.getOrePriceUsd(); // e.g., 2.15Detect Winner
store.on('roundCompleted', ({ winner, isHistorical }) => {
if (isHistorical) return; // Skip page-load replays
showWinner(winner.tile + 1); // 0-indexed → display
});Handle Tab Visibility (Pause/Resume)
document.addEventListener('visibilitychange', () => {
if (document.hidden) {
client.pause(); // Saves battery, reduces API calls
} else {
client.resume(); // Immediately fetches fresh data
}
});Track Connection Health
// Check if polling is healthy
if (!client.isPollingHealthy()) {
showStaleDataWarning();
}
// Or listen for recovery
store.on('connectionChange', ({ status, previousStatus, downtimeMs }) => {
if (status === 'connected' && previousStatus === 'unreachable') {
console.log(`Reconnected after ${downtimeMs}ms`);
refreshUI();
}
});Place a Bid
const { transaction } = await client.buildBidTransaction({
authority: wallet.publicKey.toString(),
tiles: [0, 4, 11], // 0-indexed
amountSol: 0.025,
});
const tx = Transaction.from(Buffer.from(transaction, 'base64'));
await wallet.signAndSendTransaction(tx);Claim Rewards
Two types of rewards can be claimed:
| Reward Type | SDK Method | What It Claims |
|-------------|------------|----------------|
| SOL | buildClaimTransaction() or buildClaimSolTransaction() | SOL winnings from the pot |
| ORE | buildClaimOreTransaction() | ORE token rewards (10% tax on unrefined) |
// Check claimable amounts (via MinerClient)
const status = miner.getStatus();
console.log(`Claimable SOL: ${status.claimableSol}`);
console.log(`Claimable ORE: ${status.totalClaimableOre}`);
// Claim SOL rewards
const { transaction } = await client.buildClaimSolTransaction({
authority: wallet.publicKey.toString(),
});
// Claim ORE tokens
const { transaction: oreTx } = await client.buildClaimOreTransaction({
authority: wallet.publicKey.toString(),
});Track Wallet Balance
import { MinerClient } from '@oredata/sdk';
const miner = new MinerClient({
apiBaseUrl: 'https://api.oredata.supply',
authority: wallet.publicKey.toString(),
});
miner.on('update', (status) => {
console.log(`SOL: ${status.authoritySol}`);
console.log(`Claimable: ${status.claimableSol}`);
console.log(`ORE: ${status.unrefinedOre}`);
});
miner.start();Get Token Data
import { TokenClient } from '@oredata/sdk';
const token = new TokenClient();
// Current supply & price
const info = await token.getInfo();
console.log(`Supply: ${Number(info.totalSupply).toLocaleString()} ORE`);
console.log(`Price: $${info.priceUsd}`);
console.log(`Market Cap: $${info.marketCapUsd}`);
// Emission statistics
const emissions = await token.getEmissions();
console.log(`${emissions.dailyEmissionOre} ORE/day`);
console.log(`Round ${emissions.currentRound}`);
console.log(`${emissions.daysSinceLaunch} days since V3 launch`);Send & Receive Chat
import { ChatClient } from '@oredata/sdk';
const chat = new ChatClient();
// 1. Fetch history on startup (no more empty chat!)
const { messages, hasMore } = await chat.fetchHistory({ limit: 50 });
messages.forEach(msg => console.log(`${msg.username}: ${msg.text}`));
// 2. Connect to live stream
chat.on('message', (msg) => {
console.log(`${msg.username}: ${msg.text}`);
});
chat.connect();
// 3. Send a message (unified ore.supply ecosystem!)
const result = await chat.send('Hello from my app!', wallet);
if (result.success) {
console.log('Message sent to ore.supply chat!');
}Features:
- Permanent history — Messages stored in database, fetch on page load
- Pagination —
before/afterparams for infinite scroll - Session caching — Sign once per 24 hours, even across refreshes
⚛️ React
import { OredataProvider, useStore } from '@oredata/sdk/react';
function App() {
return (
<OredataProvider config={{ baseUrls: ['https://api.oredata.supply'] }}>
<Game />
</OredataProvider>
);
}
function Game() {
const { currentRound, isReady } = useStore();
if (!isReady) return <div>Connecting...</div>;
return <div>Pot: {currentRound?.totals.deployedSol} SOL</div>;
}Available Hooks
| Hook | Purpose |
|------|---------|
| useStore() | Round data, winners, connection status |
| usePresenter() | UI timing (phase transitions, animations) |
| useRoundTiming() | Countdown timer with progress |
| useMinerAccount(pubkey) | Wallet balance & rewards |
| useBidTracker() | Track bids placed this session |
🤖 Bot Self-Service
Bots can register and manage API keys programmatically via wallet signature — no web dashboard needed.
import { SelfServiceClient } from '@oredata/sdk';
const client = new SelfServiceClient();
// Register with wallet signature
const { nonce } = await client.auth.getNonce();
const message = client.auth.buildSignInMessage(walletAddress, nonce);
const signature = await signMessage(message);
await client.auth.register({ wallet: walletAddress, message, signature });
// Create and manage API keys
const newKey = await client.keys.create({ label: 'Production' });Full capabilities: key management, project creation, Terms of Service setup, consent tracking.
→ Bot Builder Guide | API Reference
📚 Documentation
Prefer the web? oredata.supply/docs has the same content with interactive examples and better navigation.
Start Here:
- Getting Started — Two paths: developers or bots
- Core Concepts — Layer 1 vs Layer 2, isHistorical flag
Reference (complete API docs):
| Client | Description | |--------|-------------| | OredataClient | Main client: state, transactions, polling | | OredataStore | Layer 1: immediate data events | | OredataState | Layer 2: UI timing events | | MinerClient | Wallet balance & rewards | | TokenClient | ORE token data | | ChatClient | ore.supply community chat | | SelfServiceClient | Bot registration, keys, T&C | | Transactions | Building bids & claims | | Errors | Error types & handling |
Integrations:
| Framework | Docs | |-----------|------| | React | Hooks & provider | | Server | Multiplexer for 1000+ users |
More:
- API Reference — REST/SSE endpoints
- Architecture — Deep dive
- Troubleshooting — Common issues
Guides & Examples: oredata.supply/examples
🔑 API Keys & Pricing
Free tier — 2 requests/second, no credit card required. Perfect for prototyping.
Paid plans ($9–$29/mo) — Higher rate limits, faster winner detection, and fee discounts up to 90%. Set a fee wallet to capture savings as revenue from your users' transactions.
Get your API key:
- Web: oredata.supply/register
- Programmatic: Use
SelfServiceClientfor bots (docs)
→ View full pricing & fee economics
💬 Support
- 🌐 oredata.supply — Get API key
- 🐛 GitHub Issues — Report bugs
- 💬 ORE Discord — Community
📄 License
MIT © oredata.supply
