A Next.js 16 game demonstrating advanced BSV blockchain integration with server-controlled minting, overlay network broadcasting, and on-chain provable item crafting.
This project showcases production-ready BSV blockchain integration for gaming:
- Server-Side Minting: Secure, fraud-proof item creation
- OrdinalP2PKH Tokens: BSV-20/BSV-21 compliant token implementation
- Overlay Network: Custom overlay for game transactions
- Material Tokens: Quantity-based tokens with smart updates
- Hybrid Crafting: Client material consumption with server-minted output
- Auth Outputs: On-chain provable links between transactions
- OrderLock Integration: P2P marketplace for trading items (coming soon)
๐ Read More: Why BSV & Transaction Flow Pattern
All game items are minted server-side for security and validation:
Client Request โ Server Validates โ Server Mints โ Server Transfers โ Database Update
Why Server-Side?
- โ Single source of truth (server wallet)
- โ Prevents fraudulent items
- โ Validates user ownership before minting
- โ Handles complex SIGHASH scenarios
- โ All mints provably originate from server
Two-Transaction Flow:
Mint TX: Server โ Server (1 sat, OrdinalP2PKH)
Transfer TX: Server โ User (1 sat, OrdinalP2PKH)
API: POST /api/items/mint-and-transfer
Tracking:
NFTLoot.mintOutpoint- Server mint proof (txid.vout)UserInventory.tokenId- User's current outpoint (txid.vout)
Quantity-Based Tokens:
Each material = 1 token with quantity field
Updates reuse same token (no duplication)
Smart Update System:
- Checks for existing token via
/api/materials/check-token - If exists: Updates quantity on existing token
- If new: Mints new token with initial quantity
API: POST /api/materials/mint-and-transfer
Tracking:
MaterialToken.mintOutpoint- Server mint proofMaterialToken.tokenId- Current outpointMaterialToken.quantity- Current material count
Most Complex: Client controls material consumption, server controls item minting.
Client Transaction:
// useCraftItemNFT.ts
Inputs: Material tokens (user unlocks)
Outputs: Material change (if excess) + Auth output (locked to server)Server Transactions:
// /api/crafting/mint-and-transfer
Mint TX: Auth input โ Crafted item (server mints)
Transfer TX: Crafted item โ UserAuth Output:
- Uses
OrdinalP2PKH(overlay requirement) - Locked to server public key
- Proves on-chain link: materials โ crafted item
- Server validation: "If server can unlock it, it's valid"
API: POST /api/crafting/mint-and-transfer
Tracking:
craftingProof.consumptionTxId- Client material consumption txcraftingProof.authOutpoint- Auth output linking transactionscraftingProof.recipeId- Recipe used for crafting
All game tokens use OrdinalP2PKH for BSV-20/BSV-21 compliance:
import { OrdinalsP2PKH } from '@/utils/ordinalP2PKH';
const ordinalP2PKH = new OrdinalsP2PKH();
// Minting (deploy+mint)
const mintLockingScript = ordinalP2PKH.lock(
publicKey,
'', // Empty assetId for new mint
metadata, // Token metadata
'deploy+mint'
);
// Transferring
const transferLockingScript = ordinalP2PKH.lock(
userPublicKey,
assetId, // mintOutpoint with '.' replaced by '_'
metadata,
'transfer'
);
// Unlocking
const unlockTemplate = ordinalP2PKH.unlock(wallet, "single");
const unlockingScript = await unlockTemplate.sign(transaction, outputIndex);Key Features:
- OP_FALSE OP_RETURN prefix with JSON metadata
- P2PKH locking for ownership
- Asset ID format:
${mintTxId}_${vout}(BSV-21 standard) - SIGHASH_SINGLE for multi-output transactions
Custom overlay for broadcasting and querying game transactions:
// src/utils/overlayFunctions.ts
import { LookupResolver, TopicBroadcaster } from "@bsv/sdk";
const overlay = new LookupResolver({
slapTrackers: ['https://overlay-us-1.bsvb.tech'],
hostOverrides: {
'ls_monsterbattle': ['https://overlay-us-1.bsvb.tech']
}
});
// Broadcasting
export const broadcastTX = async (tx: Transaction) => {
const tb = new TopicBroadcaster(['tm_monsterbattle'], {
resolver: overlay,
});
return await tx.broadcast(tb);
}
// Querying
export async function getTransactionByTxID(txid: string) {
return await overlay.query({
service: 'ls_monsterbattle',
query: { txid: txid }
}, 10000);
}Overlay Requirements:
- All outputs must be
OrdinalP2PKHorOrderLock - Regular P2PKH outputs are rejected
- Includes "helper" outputs like auth tokens
All blockchain operations in this application follow a standardized 3-step pattern for transaction creation and signing:
๐ Read Full Documentation: Transaction Flow Pattern
Quick Summary:
1. createAction โ Prepare transaction with estimated script lengths
2. Sign โ Generate actual unlocking scripts using SDK
3. signAction โ Finalize transaction with actual scripts
This pattern provides:
- โ Consistency: Same flow across all 5 backend routes
- โ BSV-20/21 Support: Handles fungible (materials) and non-fungible (items) tokens
- โ On-Chain Credibility: Full provenance for every game item and operation
- โ Server Control: Prevents fraudulent minting and ensures game rule enforcement
- โ Scalability: Handles single and multiple input transactions seamlessly
Every item minted, crafted, transferred, or updated has a verifiable on-chain record, demonstrating a production-ready blockchain-based game economy.
Example Routes Using This Pattern:
src/app/api/items/mint-and-transfer/route.ts- Item NFT mintingsrc/app/api/materials/mint-and-transfer/route.ts- Material token mintingsrc/app/api/crafting/mint-and-transfer/route.ts- Crafting with material consumptionsrc/app/api/equipment/update/route.ts- Equipment inscription updatessrc/app/api/materials/add-and-merge/route.ts- Material token merging
Critical: Always store full outpoints (txid.vout), never just txid.
Why?
โ WRONG: transactionId: "abc123..."
Problem: Which output? Could be vout 0, 1, 2...
โ
CORRECT: tokenId: "abc123...def.0"
Clear: Exact UTXO location (output 0 of tx abc123...def)
Benefits:
- Exact UTXO location tracking
- No ambiguity in multi-output transactions
- Correct material token linking
- Easier debugging (paste outpoint in explorer)
Format: ${txid}.${vout}
Examples:
mintOutpoint: "abc123...def.0" // Mint transaction output 0
tokenId: "ghi789...jkl.0" // Transfer transaction output 0
authOutpoint: "mno012...pqr.2" // Consumption transaction output 2OrderLock enables trustless P2P trading using BSV smart contracts:
Seller โ Creates Order (locks item + price) โ Order available on marketplace
Buyer โ Fulfills Order (sends BSV) โ Atomic swap (itemโBSV)
Order Creation (to be implemented):
// Future: useCreateOrder.ts
const orderLock = new OrderLock();
const orderScript = orderLock.lock(
itemOutpoint, // Item being sold
priceInSatoshis, // Asking price
sellerPublicKey, // Seller's public key
payoutPublicKey // Where seller receives payment
);Order Fulfillment (to be implemented):
// Future: useFulfillOrder.ts
const unlockScript = orderLock.unlock(
buyerWallet,
itemLockingScript,
priceInSatoshis
);
// Atomic swap: Buyer gets item, seller gets payment- List minted items for sale (OrderLock)
- Browse available orders (filter by type/rarity)
- Purchase items with BSV wallet
- Cancel orders (seller reclaims item)
- Order history and trade analytics
- Escrow-free atomic swaps
- On-chain price discovery
Route Structure (planned):
POST /api/marketplace/create-order - Create OrderLock
POST /api/marketplace/fulfill-order - Buy item
POST /api/marketplace/cancel-order - Cancel listing
GET /api/marketplace/list-orders - Browse marketplace
Database (planned):
interface MarketplaceOrder {
_id: ObjectId;
itemOutpoint: string; // Item being sold
sellerUserId: string; // Seller's userId
priceInSatoshis: number; // Asking price
orderLockOutpoint: string; // OrderLock UTXO
status: 'active' | 'fulfilled' | 'cancelled';
createdAt: Date;
fulfilledAt?: Date;
fulfilledBy?: string; // Buyer's userId
}References:
src/utils/orderLock.ts- OrderLock implementation_tests/orderLock.test.ts- Comprehensive test suite
- Next.js 16 - App Router, Server Components
- React 19 - Latest features
- TypeScript - Strict mode
- TailwindCSS v4 - Styling
- BSV SDK - Wallet integration (@bsv/sdk)
- Next.js API Routes - Server-side logic
- MongoDB - Database (via native driver)
- JWT - Authentication (jose library)
- BSV Wallet - Server wallet for minting
- BSV Blockchain - Layer 1
- OrdinalP2PKH - Token standard (BSV-20/BSV-21)
- Overlay Network - Custom transaction routing
- OrderLock - P2P trading smart contracts (coming soon)
See .env.example for environment variables.
# MongoDB
MONGODB_URI=mongodb+srv://...
# Authentication
JWT_SECRET=your-secret-key-minimum-32-chars
# Server Wallet (for minting)
SERVER_WALLET_PRIVATE_KEY=your-server-wallet-private-key-hex
SERVER_WALLET_STORAGE_URL=your-wallet-storage-url
SERVER_WALLET_CHAIN=main-or-test
# Node Environment
NODE_ENV=development# Install dependencies
npm install
# Run development server
npm run dev
# Build for production
npm run build
# Start production server
npm start
# Run tests
npm test
# Type checking
npx tsc --noEmit
# Linting
npm run lintsrc/
โโโ app/
โ โโโ api/ # API Routes
โ โ โโโ items/mint-and-transfer/ # Regular item minting
โ โ โโโ materials/mint-and-transfer/ # Material token minting
โ โ โโโ crafting/mint-and-transfer/ # Crafted item minting
โ โ โโโ materials/check-token/ # Material token smart updates
โ โโโ battle/ # Battle page
โ โโโ inventory/ # Inventory page
โ โโโ crafting/ # Crafting page
โโโ components/ # React components
โโโ contexts/ # React Context (Player, Equipment, etc.)
โโโ hooks/ # Custom React hooks
โ โโโ useMintItemNFT.ts # Regular item minting hook
โ โโโ useMintMaterialTokens.ts # Material minting hook
โ โโโ useCraftItemNFT.ts # Hybrid crafting hook
โโโ lib/
โ โโโ mongodb.ts # MongoDB connection
โ โโโ serverWallet.ts # Server wallet utilities
โ โโโ types.ts # TypeScript interfaces
โ โโโ loot-table.ts # Item definitions
โโโ utils/
โ โโโ ordinalP2PKH.ts # OrdinalP2PKH implementation
โ โโโ overlayFunctions.ts # Overlay broadcast/query
โ โโโ orderLock.ts # OrderLock smart contract
โ โโโ jwt.ts # JWT utilities
โโโ _tests/ # Unit tests
โโโ ordinalP2PKH.test.ts # Token script tests
โโโ orderLock.test.ts # Marketplace tests
docs/ # Documentation
โโโ SERVER_SIDE_MINTING.md # Minting architecture
โโโ [other docs]
npm run testOrdinalP2PKH Token Scripts (_tests/ordinalP2PKH.test.ts):
- โ Mint transaction creation
- โ Transfer transaction creation
- โ Script structure validation
- โ Metadata encoding/decoding
- โ Asset ID format (BSV-21)
OrderLock Smart Contracts (_tests/orderLock.test.ts):
- โ Order creation and locking
- โ Order fulfillment (atomic swap)
- โ Order cancellation
- โ Multi-signature scenarios
- โ Edge cases and failure modes
Regular Items:
- Mint weapon/armor/artifact
- Verify
mintOutpointin database - Verify
tokenIdin UserInventory - Check transaction on overlay
Material Tokens:
- Mint new material (e.g., 10 iron)
- Mint same material again (should update quantity)
- Verify
mintOutpointdoesn't change - Verify
tokenIdupdates to new outpoint - Verify quantity = 20
Crafted Items:
- Craft item with exact materials (no change)
- Craft item with excess materials (check change outputs)
- Verify auth output on-chain
- Verify crafting proof in database
- Verify material quantities updated
A click-based monster battler where:
- Fight monsters across 5 biomes (Forest โ Desert โ Ocean โ Volcano โ Castle)
- Defeat monsters to earn loot (materials, equipment, consumables)
- Craft powerful items using materials
- Equip gear for stat bonuses (damage, crit, defense, HP)
- Level up and progress through tiers (1-5)
Blockchain Integration:
- All items/materials are BSV blockchain tokens
- Crafting creates provable on-chain links
- Future: Trade items on P2P marketplace (OrderLock)
- User ownership verified before minting
- JWT authentication on all API routes
- MongoDB queries filtered by userId
- Server-side time tracking (database timestamps)
- Click rate validation (max 15 clicks/sec)
- HP verification (did player survive monster damage?)
- Server wallet private key secured in environment
- All mints provably from server wallet (mintOutpoint)
- Auth outputs prove material consumption for crafting
- Outpoint tracking prevents UTXO confusion
- Create feature branch:
git checkout -b feature/my-feature - Make changes (ensure TypeScript compiles:
npx tsc --noEmit) - Run tests:
npm run test - Commit with clear message
- Push and create PR
MIT
Built with BSV Blockchain and Next.js