Implementation
Build the game with Shreds integration and transaction pooling
Game Implementation
Now let's build the core game component with Shreds integration for blockchain-backed precision.
The complete implementation can be found in the GitHub repository. We'll highlight only the key sections here.
Key Concepts
Transaction Pool Pattern:
- Pre-sign 10 transactions at initialization
- Each click retrieves a pre-signed transaction from the pool
- Background refilling at 50% capacity ensures the pool never depletes
- Zero signing latency during gameplay
Game State Machine:
- IDLE → WAITING → READY → FINISHED
- Random delay (1-5s) between WAITING and READY
- Measure reaction time with
performance.now() - Record transaction confirmation time separately
Shreds Integration:
- Use
eth_sendRawTransactionSyncfor synchronous confirmations - Returns when transaction is finalized (3ms), not just submitted
- Critical for accurate timing measurements
Core Implementation Highlights
// Transaction pool for pre-signed transactions
const preSignedPool: {
transactions: `0x${string}`[];
currentIndex: number;
baseNonce: number;
} = {
transactions: [],
currentIndex: 0,
baseNonce: 0,
};
// Pre-sign batch of transactions
const preSignBatch = async (startNonce: number, batchSize: number) => {
const signingPromises = Array.from({ length: batchSize }, async (_, i) => {
const txData = {
to: account.address,
value: 0n,
data: `0x${(i + 1).toString(16).padStart(2, "0")}` as `0x${string}`,
nonce: startNonce + i,
gasPrice: gasPrice,
gas: gasLimit,
type: "legacy" as const,
};
return await client.signTransaction(txData);
});
return await Promise.all(signingPromises);
};
// Send transaction synchronously
const handleClick = async () => {
const signedTx = getNextTransaction();
const txStart = performance.now();
await client.request({
method: 'eth_sendRawTransactionSync',
params: [signedTx]
});
const txTime = Math.round(performance.now() - txStart);
// Record result with reaction time + TX time
};Complete Source Code
For the full game implementation including:
- Complete game state management
- Landing page with animated background
- Results table and statistics
- Play again functionality
Visit: https://github.com/awesamarth/reaction-time
Running the Game
Fund Your Burner Wallet
Before playing, you need testnet ETH. Visit the RISE Faucet and request funds for your burner wallet address (check the navbar after starting the app).
Start Development Server
npm run devyarn devpnpm devbun run devOpen your browser and navigate to http://localhost:3000.
Playing the Game
Start the Game
Click the "START GAME" button on the landing page. Wait for "INITIALIZING..." to change to "CLICK TO START".
Round 1
Click the purple box to start. It will turn red with "WAIT..." - don't click yet!
After 1-5 seconds, it turns green with "CLICK NOW!" - click as fast as you can!
Transaction Recording
The box turns yellow with "RECORDING..." while your click is being recorded on the blockchain. This takes only ~3ms!
View Results
After each round, your results appear in the table below:
- Reaction Time: Your raw reflexes
- TX Time: How long RISE took to confirm
- Total Time: Combined time
Complete 5 Rounds
Repeat for rounds 2-5. After the final round, view your FINAL STATS showing averages and blockchain overhead percentage.
The game in action should look like this:

Pro Tip
The average human reaction time is 200-300ms. If your TX time is only 3ms, RISE adds less than 2% overhead to your total response time!
Understanding the Code
Transaction Pool Pattern
Why this works:
- Signing is slow (~50ms) - doing it during gameplay adds latency
- Pre-signing is instant - transaction is ready to send immediately
- Background refilling - pool never runs out during a 5-round game
- Synchronous confirmation -
eth_sendRawTransactionSyncwaits for finality
Timing Precision
The game uses performance.now() for microsecond precision:
// When box turns green
greenTimeRef.current = performance.now();
// When user clicks
clickTimeRef.current = performance.now();
// Calculate reaction time
const reactionTime = Math.round(clickTimeRef.current - greenTimeRef.current) - ADJUSTMENT;The 100ms adjustment accounts for:
- Browser rendering delays
- Monitor refresh rate (~16ms at 60Hz)
- Event propagation time
Performance Insights
What the Game Proves
This game demonstrates three critical points:
- Blockchain Can Be Fast: 3ms confirmations are comparable to database writes
- Pre-signing Works: Zero-latency gameplay with background pool management
- RISE Enables New Use Cases: Gaming, high-frequency trading, realtime auctions
Advanced Optimizations
Background Refilling Strategy
The pool refills at 50% capacity to ensure transactions are always ready:
if (preSignedPool.currentIndex % 5 === 0 && !preSignedPool.hasTriggeredRefill) {
preSignedPool.hasTriggeredRefill = true;
const nextNonce = preSignedPool.baseNonce + preSignedPool.transactions.length;
preSignBatch(nextNonce, 10).then(() => {
preSignedPool.hasTriggeredRefill = false; // Ready for next refill
});
}Why 50% threshold?
- Signing 10 transactions takes ~500ms
- Typical game round takes 2-6 seconds
- Pool will never deplete during gameplay
Security Considerations
Burner Wallet Best Practices
Production Warning
This tutorial uses an exposed private key for simplicity. In production:
- Use server-side signing with API routes
- Implement rate limiting to prevent abuse
- Never expose private keys in client code
- Consider using threshold signatures or MPC
Next Steps
Congratulations! You've built a realtime blockchain game with 3ms confirmations. Here are some ideas to extend your game:
- Multiplayer Mode: Add realtime leaderboards using Shreds events
- NFT Rewards: Mint achievement NFTs for top scores
- Smart Contract Integration: Record high scores on-chain
- Advanced Analytics: Track improvement over time
- Tournament Mode: Compete against other players
Related Tutorials
- Shred Ninja - Realtime event monitoring
- RISEx Trading Bot - Build a Telegram perp trading bot
- Deploy Your First Contract - Smart contract deployment
Resources
- GitHub Repository - Complete source code
- Shreds Documentation - Complete Shreds API reference
- RISE Testnet Details - Network information
- Viem Documentation - Ethereum client library
- RISE Faucet - Get testnet ETH